<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="utils"/>
<classpathentry kind="src" path="test"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/activation.jar"/>
<classpathentry kind="lib" path="lib/axis.jar" sourcepath="D:/axis-1_2RC2-src/axis-1_2RC2"/>
<classpathentry kind="lib" path="lib/commons-discovery.jar"/>
<classpathentry kind="lib" path="lib/jaxrpc.jar"/>
<classpathentry kind="lib" path="lib/jhall.jar"/>
- <classpathentry kind="lib" path="lib/log4j-1.2.8.jar"/>
<classpathentry kind="lib" path="lib/mail.jar"/>
<classpathentry kind="lib" path="lib/regex.jar"/>
<classpathentry kind="lib" path="lib/saaj.jar"/>
<classpathentry kind="lib" path="lib/wsdl4j.jar"/>
<classpathentry kind="lib" path="lib/xercesImpl.jar"/>
- <classpathentry kind="lib" path="lib/xml-apis.jar"/>
<classpathentry kind="lib" path="lib/castor-1.1-cycle-xml.jar" sourcepath="C:/Documents and Settings/JimP/workspace-3.3/castor/src/main/java"/>
<classpathentry kind="lib" path="lib/JGoogleAnalytics_0.3.jar" sourcepath="/JGoogleAnalytics/src/main/java"/>
<classpathentry kind="lib" path="lib/vamsas-client.jar"/>
<classpathentry kind="lib" path="lib/spring-web-3.0.5.RELEASE.jar"/>
<classpathentry kind="lib" path="lib/groovy-all-1.8.2.jar"/>
<classpathentry kind="lib" path="lib/min-jabaws-client-2.1.0.jar" sourcepath="/clustengine"/>
- <classpathentry kind="lib" path="lib/VARNAv3-9.jar" sourcepath="/Users/jimp/Documents/Jalview/VARNA/VARNAv3-9-src.jar"/>
<classpathentry kind="lib" path="lib/json_simple-1.1.jar" sourcepath="/Users/jimp/Downloads/json_simple-1.1-all.zip"/>
+ <classpathentry kind="lib" path="lib/slf4j-api-1.7.7.jar"/>
+ <classpathentry kind="lib" path="lib/jsoup-1.8.1.jar"/>
+ <classpathentry kind="lib" path="lib/log4j-to-slf4j-2.0-rc2.jar"/>
+ <classpathentry kind="lib" path="lib/slf4j-log4j12-1.7.7.jar"/>
+ <classpathentry kind="lib" path="lib/VARNAv3-91.jar"/>
+ <classpathentry kind="lib" path="lib/jfreesvg-2.1.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.jar"/>
+ <classpathentry kind="lib" path="lib/xml-apis.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin17"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="classes"/>
</classpath>
--- /dev/null
+# force text file line endings to LF (Unix style) on commit
+# see https://help.github.com/articles/dealing-with-line-endings/#per-repository-settings
+* text=auto
+
+# see also http://git-scm.com/book/en/Customizing-Git-Git-Configuration#Formatting-and-Whitespace
+# Users should set a git/config entry of
+# core.autocrlf = true # for Windows
+# core.autocrlf = input # for Mac
\ No newline at end of file
/classes
.externalToolBuilders/Jalview Release indices [Builder].launch
/.DS_Store
+.DS_Store
/.com.apple.timemachine.supported
+.gitattributes
+
+
--- /dev/null
+eclipse.preferences.version=1
+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=16
+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=1
+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=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+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=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+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=4
+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=false
+org.eclipse.jdt.core.formatter.indentation.size=8
+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_after_type_annotation=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=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=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_lambda_arrow=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_lambda_arrow=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=true
+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=76
+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=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=2
+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=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
--- /dev/null
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Jalview
+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=false
+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_functional_interfaces=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=true
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.make_local_variable_final=true
+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=false
+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=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=true
+sp_cleanup.remove_trailing_whitespaces=false
+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=false
+sp_cleanup.remove_unused_imports=true
+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_anonymous_class_creation=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=true
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_type_arguments=false
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--JBuilder XML Project-->\r
-<project>\r
- <property category="debug.0" name="SmartStepRedefineClasses" value="0"/>\r
- <property category="debug.0" name="SmartStepSkipStaticInitializers" value="0"/>\r
- <property category="debug.0" name="SmartStepSkipSynthetics" value="0"/>\r
- <property category="editor.general" name="line_ending.style" value="2"/>\r
- <property category="generalFormatting" name="lineEndingStyle" value="2"/>\r
- <property category="generalFormatting2" name="lineEndingStyle" value="2"/>\r
- <property category="generalFormatting2" name="overrideBasicFormatting" value="1"/>\r
- <property category="javaFormatting" name="classBraceNextLine" value="1"/>\r
- <property category="javaFormatting" name="methodBraceNextLine" value="1"/>\r
- <property category="javaFormatting" name="otherBraceNextLine" value="1"/>\r
- <property category="javaFormatting" name="packagePrefixGroups" value="java;javax;BLANK_LINE;java.awt;javax.swing;BLANK_LINE;org;(*)"/>\r
- <property category="javaFormatting" name="throwsOnNewLine" value="1"/>\r
- <property category="javadoc" name="custom.tags.1" value="todo;a;To Do:"/>\r
- <property category="runtime" name="DefaultConfiguration" value="-1"/>\r
- <property category="runtime.0" name="BuildTargetOnRun" value="com.borland.jbuilder.build.ProjectBuilder$ProjectBuildAction;make"/>\r
- <property category="runtime.0" name="ConfigurationName" value="Applet"/>\r
- <property category="runtime.0" name="RunnableType" value="com.borland.jbuilder.runtime.AppletRunner"/>\r
- <property category="runtime.0" name="applet.appletviewer" value="1"/>\r
- <property category="runtime.0" name="applet.class" value="jalview.bin.JalviewLite"/>\r
- <property category="runtime.0" name="applet.html" value="classes/applet.html"/>\r
- <property category="serverservices" name="single.server.name" value="Tomcat 4.0"/>\r
- <property category="sys" name="AuthorLabel" value="@author"/>\r
- <property category="sys" name="BackupPath" value="bak"/>\r
- <property category="sys" name="CheckStable" value="1"/>\r
- <property category="sys" name="Company" value=""/>\r
- <property category="sys" name="CompanyLabel" value="Company:"/>\r
- <property category="sys" name="Copyright" value="Copyright (c) 2004"/>\r
- <property category="sys" name="CopyrightLabel" value="Copyright:"/>\r
- <property category="sys" name="DefaultPath" value="src"/>\r
- <property category="sys" name="Description" value=""/>\r
- <property category="sys" name="DescriptionLabel" value="Description:"/>\r
- <property category="sys" name="DocPath" value="doc"/>\r
- <property category="sys" name="ExcludeClassEnabled" value="0"/>\r
- <property category="sys" name="IncludeTestPath" value="1"/>\r
- <property category="sys" name="InstanceVisibility" value="2"/>\r
- <property category="sys" name="JDK" value="java version 1.1.8_010"/>\r
- <property category="sys" name="LastTag" value="0"/>\r
- <property category="sys" name="Libraries" value=""/>\r
- <property category="sys" name="MakeStable" value="0"/>\r
- <property category="sys" name="OutPath" value="classes"/>\r
- <property category="sys" name="SourcePath" value="src;test"/>\r
- <property category="sys" name="TestPath" value="src"/>\r
- <property category="sys" name="Title" value=""/>\r
- <property category="sys" name="TitleLabel" value="Title:"/>\r
- <property category="sys" name="Version" value="1.0"/>\r
- <property category="sys" name="VersionLabel" value="@version"/>\r
- <property category="sys" name="WorkingDirectory" value="."/>\r
- <property category="sys" name="enable.auto.packages" value="false"/>\r
- <node name="jalview.appletgui" type="Package"/>\r
- <node name="jalview.datamodel" type="Package"/>\r
- <node name="jalview.jbappletgui" type="Package"/>\r
- <node name="jalview.math" type="Package"/>\r
- <node name="jalview.schemes" type="Package"/>\r
- <file path="src/jalview/analysis/AAFrequency.java"/>\r
- <file path="src/jalview/io/AlignFile.java"/>\r
- <file path="src/jalview/analysis/AlignmentSorter.java"/>\r
- <file path="src/jalview/analysis/AlignSeq.java"/>\r
- <file path="src/jalview/io/BLCFile.java"/>\r
- <file path="src/jalview/io/ClustalFile.java"/>\r
- <file path="src/jalview/analysis/Conservation.java"/>\r
- <file path="src/jalview/io/FastaFile.java"/>\r
- <file path="src/jalview/io/FileParse.java"/>\r
- <file path="src/jalview/io/FormatAdapter.java"/>\r
- <file path="src/jalview/io/IdentifyFile.java"/>\r
- <file path="src/jalview/bin/JalviewLite.java"/>\r
- <file path="src/jalview/io/MSFfile.java"/>\r
- <file path="src/jalview/io/NewickFile.java"/>\r
- <file path="src/jalview/analysis/NJTree.java"/>\r
- <file path="src/jalview/analysis/PCA.java"/>\r
- <file path="src/jalview/io/PfamFile.java"/>\r
- <file path="src/jalview/io/PIRFile.java"/>\r
-</project>\r
+<?xml version="1.0" encoding="UTF-8"?>
+<!--JBuilder XML Project-->
+<project>
+ <property category="debug.0" name="SmartStepRedefineClasses" value="0"/>
+ <property category="debug.0" name="SmartStepSkipStaticInitializers" value="0"/>
+ <property category="debug.0" name="SmartStepSkipSynthetics" value="0"/>
+ <property category="editor.general" name="line_ending.style" value="2"/>
+ <property category="generalFormatting" name="lineEndingStyle" value="2"/>
+ <property category="generalFormatting2" name="lineEndingStyle" value="2"/>
+ <property category="generalFormatting2" name="overrideBasicFormatting" value="1"/>
+ <property category="javaFormatting" name="classBraceNextLine" value="1"/>
+ <property category="javaFormatting" name="methodBraceNextLine" value="1"/>
+ <property category="javaFormatting" name="otherBraceNextLine" value="1"/>
+ <property category="javaFormatting" name="packagePrefixGroups" value="java;javax;BLANK_LINE;java.awt;javax.swing;BLANK_LINE;org;(*)"/>
+ <property category="javaFormatting" name="throwsOnNewLine" value="1"/>
+ <property category="javadoc" name="custom.tags.1" value="todo;a;To Do:"/>
+ <property category="runtime" name="DefaultConfiguration" value="-1"/>
+ <property category="runtime.0" name="BuildTargetOnRun" value="com.borland.jbuilder.build.ProjectBuilder$ProjectBuildAction;make"/>
+ <property category="runtime.0" name="ConfigurationName" value="Applet"/>
+ <property category="runtime.0" name="RunnableType" value="com.borland.jbuilder.runtime.AppletRunner"/>
+ <property category="runtime.0" name="applet.appletviewer" value="1"/>
+ <property category="runtime.0" name="applet.class" value="jalview.bin.JalviewLite"/>
+ <property category="runtime.0" name="applet.html" value="classes/applet.html"/>
+ <property category="serverservices" name="single.server.name" value="Tomcat 4.0"/>
+ <property category="sys" name="AuthorLabel" value="@author"/>
+ <property category="sys" name="BackupPath" value="bak"/>
+ <property category="sys" name="CheckStable" value="1"/>
+ <property category="sys" name="Company" value=""/>
+ <property category="sys" name="CompanyLabel" value="Company:"/>
+ <property category="sys" name="Copyright" value="Copyright (c) 2004"/>
+ <property category="sys" name="CopyrightLabel" value="Copyright:"/>
+ <property category="sys" name="DefaultPath" value="src"/>
+ <property category="sys" name="Description" value=""/>
+ <property category="sys" name="DescriptionLabel" value="Description:"/>
+ <property category="sys" name="DocPath" value="doc"/>
+ <property category="sys" name="ExcludeClassEnabled" value="0"/>
+ <property category="sys" name="IncludeTestPath" value="1"/>
+ <property category="sys" name="InstanceVisibility" value="2"/>
+ <property category="sys" name="JDK" value="java version 1.1.8_010"/>
+ <property category="sys" name="LastTag" value="0"/>
+ <property category="sys" name="Libraries" value=""/>
+ <property category="sys" name="MakeStable" value="0"/>
+ <property category="sys" name="OutPath" value="classes"/>
+ <property category="sys" name="SourcePath" value="src;test"/>
+ <property category="sys" name="TestPath" value="src"/>
+ <property category="sys" name="Title" value=""/>
+ <property category="sys" name="TitleLabel" value="Title:"/>
+ <property category="sys" name="Version" value="1.0"/>
+ <property category="sys" name="VersionLabel" value="@version"/>
+ <property category="sys" name="WorkingDirectory" value="."/>
+ <property category="sys" name="enable.auto.packages" value="false"/>
+ <node name="jalview.appletgui" type="Package"/>
+ <node name="jalview.datamodel" type="Package"/>
+ <node name="jalview.jbappletgui" type="Package"/>
+ <node name="jalview.math" type="Package"/>
+ <node name="jalview.schemes" type="Package"/>
+ <file path="src/jalview/analysis/AAFrequency.java"/>
+ <file path="src/jalview/io/AlignFile.java"/>
+ <file path="src/jalview/analysis/AlignmentSorter.java"/>
+ <file path="src/jalview/analysis/AlignSeq.java"/>
+ <file path="src/jalview/io/BLCFile.java"/>
+ <file path="src/jalview/io/ClustalFile.java"/>
+ <file path="src/jalview/analysis/Conservation.java"/>
+ <file path="src/jalview/io/FastaFile.java"/>
+ <file path="src/jalview/io/FileParse.java"/>
+ <file path="src/jalview/io/FormatAdapter.java"/>
+ <file path="src/jalview/io/IdentifyFile.java"/>
+ <file path="src/jalview/bin/JalviewLite.java"/>
+ <file path="src/jalview/io/MSFfile.java"/>
+ <file path="src/jalview/io/NewickFile.java"/>
+ <file path="src/jalview/analysis/NJTree.java"/>
+ <file path="src/jalview/analysis/PCA.java"/>
+ <file path="src/jalview/io/PfamFile.java"/>
+ <file path="src/jalview/io/PIRFile.java"/>
+</project>
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--JBuilder XML Project-->\r
-<project>\r
- <property category="debug.0" name="SmartStepRedefineClasses" value="0"/>\r
- <property category="debug.0" name="SmartStepSkipStaticInitializers" value="0"/>\r
- <property category="debug.0" name="SmartStepSkipSynthetics" value="0"/>\r
- <property category="generalFormatting2" name="overrideBasicFormatting" value="1"/>\r
- <property category="javaFormatting" name="EventStyle" value="0"/>\r
- <property category="javaFormatting" name="classBraceNextLine" value="1"/>\r
- <property category="javaFormatting" name="methodBraceNextLine" value="1"/>\r
- <property category="javaFormatting" name="otherBraceNextLine" value="1"/>\r
- <property category="javaFormatting" name="packagePrefixGroups" value="java;javax;BLANK_LINE;java.awt;javax.swing;BLANK_LINE;org;(*)"/>\r
- <property category="javaFormatting" name="throwsOnNewLine" value="1"/>\r
- <property category="optimize.0" name="OptimizableType" value="com.borland.jbuilder.optimize.IntroOptimizeitProfiler"/>\r
- <property category="runtime.0" name="BuildTargetOnRun" value="com.borland.jbuilder.build.ProjectBuilder$ProjectBuildAction;make"/>\r
- <property category="runtime.0" name="ConfigurationName" value="JalviewX"/>\r
- <property category="runtime.0" name="RunnableType" value="com.borland.jbuilder.runtime.ApplicationRunner"/>\r
- <property category="runtime.0" name="application.class" value="jalview.bin.Jalview"/>\r
- <property category="serverservices" name="single.server.name" value="Tomcat 4.0"/>\r
- <property category="sys" name="AuthorLabel" value="@author"/>\r
- <property category="sys" name="BackupPath" value="bak"/>\r
- <property category="sys" name="Company" value="Dundee University"/>\r
- <property category="sys" name="CompanyLabel" value="Company:"/>\r
- <property category="sys" name="Copyright" value="Copyright (c) 2004"/>\r
- <property category="sys" name="CopyrightLabel" value="Copyright:"/>\r
- <property category="sys" name="DefaultPath" value="src"/>\r
- <property category="sys" name="Description" value=""/>\r
- <property category="sys" name="DescriptionLabel" value="Description:"/>\r
- <property category="sys" name="DocPath" value="doc"/>\r
- <property category="sys" name="ExcludeClassEnabled" value="0"/>\r
- <property category="sys" name="IncludeTestPath" value="1"/>\r
- <property category="sys" name="JDK" value="java version 1.4.2_04-b05"/>\r
- <property category="sys" name="JvmVersion" value="1.4"/>\r
- <property category="sys" name="Libraries" value="all"/>\r
- <property category="sys" name="OutPath" value="classes"/>\r
- <property category="sys" name="SourcePath" value="src;test"/>\r
- <property category="sys" name="SourceVersion" value="1.4"/>\r
- <property category="sys" name="TestPath" value="test"/>\r
- <property category="sys" name="Title" value=""/>\r
- <property category="sys" name="TitleLabel" value="Title:"/>\r
- <property category="sys" name="Version" value="1.0"/>\r
- <property category="sys" name="VersionLabel" value="@version"/>\r
- <property category="sys" name="WorkingDirectory" value="."/>\r
- <property category="sys" name="uidesign.size.jalview.jbgui.GPreferences" value="453,333"/>\r
- <property category="sys" name="uidesign.size.jalview.jbgui.GSequenceLink" value="400,112"/>\r
- <file path="build.xml"/>\r
-</project>\r
+<?xml version="1.0" encoding="UTF-8"?>
+<!--JBuilder XML Project-->
+<project>
+ <property category="debug.0" name="SmartStepRedefineClasses" value="0"/>
+ <property category="debug.0" name="SmartStepSkipStaticInitializers" value="0"/>
+ <property category="debug.0" name="SmartStepSkipSynthetics" value="0"/>
+ <property category="generalFormatting2" name="overrideBasicFormatting" value="1"/>
+ <property category="javaFormatting" name="EventStyle" value="0"/>
+ <property category="javaFormatting" name="classBraceNextLine" value="1"/>
+ <property category="javaFormatting" name="methodBraceNextLine" value="1"/>
+ <property category="javaFormatting" name="otherBraceNextLine" value="1"/>
+ <property category="javaFormatting" name="packagePrefixGroups" value="java;javax;BLANK_LINE;java.awt;javax.swing;BLANK_LINE;org;(*)"/>
+ <property category="javaFormatting" name="throwsOnNewLine" value="1"/>
+ <property category="optimize.0" name="OptimizableType" value="com.borland.jbuilder.optimize.IntroOptimizeitProfiler"/>
+ <property category="runtime.0" name="BuildTargetOnRun" value="com.borland.jbuilder.build.ProjectBuilder$ProjectBuildAction;make"/>
+ <property category="runtime.0" name="ConfigurationName" value="JalviewX"/>
+ <property category="runtime.0" name="RunnableType" value="com.borland.jbuilder.runtime.ApplicationRunner"/>
+ <property category="runtime.0" name="application.class" value="jalview.bin.Jalview"/>
+ <property category="serverservices" name="single.server.name" value="Tomcat 4.0"/>
+ <property category="sys" name="AuthorLabel" value="@author"/>
+ <property category="sys" name="BackupPath" value="bak"/>
+ <property category="sys" name="Company" value="Dundee University"/>
+ <property category="sys" name="CompanyLabel" value="Company:"/>
+ <property category="sys" name="Copyright" value="Copyright (c) 2004"/>
+ <property category="sys" name="CopyrightLabel" value="Copyright:"/>
+ <property category="sys" name="DefaultPath" value="src"/>
+ <property category="sys" name="Description" value=""/>
+ <property category="sys" name="DescriptionLabel" value="Description:"/>
+ <property category="sys" name="DocPath" value="doc"/>
+ <property category="sys" name="ExcludeClassEnabled" value="0"/>
+ <property category="sys" name="IncludeTestPath" value="1"/>
+ <property category="sys" name="JDK" value="java version 1.4.2_04-b05"/>
+ <property category="sys" name="JvmVersion" value="1.4"/>
+ <property category="sys" name="Libraries" value="all"/>
+ <property category="sys" name="OutPath" value="classes"/>
+ <property category="sys" name="SourcePath" value="src;test"/>
+ <property category="sys" name="SourceVersion" value="1.4"/>
+ <property category="sys" name="TestPath" value="test"/>
+ <property category="sys" name="Title" value=""/>
+ <property category="sys" name="TitleLabel" value="Title:"/>
+ <property category="sys" name="Version" value="1.0"/>
+ <property category="sys" name="VersionLabel" value="@version"/>
+ <property category="sys" name="WorkingDirectory" value="."/>
+ <property category="sys" name="uidesign.size.jalview.jbgui.GPreferences" value="453,333"/>
+ <property category="sys" name="uidesign.size.jalview.jbgui.GSequenceLink" value="400,112"/>
+ <file path="build.xml"/>
+</project>
-jalview.release=Release_2_8_2_Branch\r
-jalview.version=2.8.2\r
+jalview.release=Release_2_8_2_Branch
+jalview.version=2.8.2
These can be found in the lib directory, with additional compile
time dependencies in the utils directory.
+A number of sources have also been adapted for incorporation into Jalview's source tree
+
+ext.edu.ucsf.rbvi.strucviz2 includes sources originally developed by Scooter Morris and Nadezhda Doncheva for the Cytoscape StructureViz2 plugin. It is released under the Berkley license and we hereby acknowledge its original copyright is held by the UCSF Computer Graphics Laboratory
+ and the software was developed with support by the NIH National Center for Research Resources, grant P41-RR01081.
+
Licencing information for each library is given below:
JGoogleAnalytics_0.3.jar APL 2.0 License - http://code.google.com/p/jgoogleanalytics/
xercesImpl.jar
xml-apis.jar
json_simple-1.1.jar : Apache 2.0 license : downloaded from https://code.google.com/p/json-simple/downloads/list (will move to 1.1.1 version when jalview is mavenised and osgi-ised)
+
Additional dependencies
examples/javascript/deployJava.js : http://java.com/js/deployJava.js
<property name="outputJar" value="jalview.jar" />
<!-- Jalview Applet JMol Jar Dependency -->
<property name="jmolJar" value="JmolApplet-12.2.4.jar" />
- <property name="varnaJar" value="VARNAv3-9.jar" />
+ <property name="varnaJar" value="VARNAv3-91.jar" />
<property name="jalviewLiteJar" value="jalviewApplet.jar" />
<!-- switch to indicate if we should obfuscate jalviewLite -->
<!-- <property name="donotobfuscate" value="true"/> -->
<!-- switch to exclude associations from generated jnlp files -->
<!-- <property name="nojnlpfileassocs" value="true"/> -->
- <!-- Jalview Web Service Clients - see the comments in 'buildextclients' for details -->
+ <!-- Jalview Web Service Clients - see the comments in 'buildextexcclients' for details -->
<property name="wsdl.File" value="http://www.compbio.dundee.ac.uk/JalviewWS/services/jpred?wsdl" />
<property name="wsdl.Files" value="http://www.compbio.dundee.ac.uk/JalviewWS/services/vamsas?wsdlFiles" />
<property name="wsdl.MsaWS" value="http://www.compbio.dundee.ac.uk/JalviewWS/services/MuscleWS?wsdl" />
<mkdir dir="${outputDir}" />
<javac source="1.5" target="1.5" srcdir="${sourceDir}" destdir="${outputDir}" debug="${javac.debug}"
classpathref="jalviewlite.deps" includes="jalview/appletgui/**"
- excludes="ext/**,MCview/**,org/**,vamsas/**,jalview/ext/paradise/**" />
+ excludes="ext/**,MCview/**,org/**,vamsas/**,jalview/io/**,jalview/ext/paradise/**" />
</target>
<target name="packageApplet" depends="compileApplet, buildPropertiesFile">
-<!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
-<!--\r
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)\r
- * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle\r
- * \r
- * This file is part of Jalview.\r
- * \r
- * Jalview is free software: you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License \r
- * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\r
- * \r
- * Jalview is distributed in the hope that it will be useful, but \r
- * WITHOUT ANY WARRANTY; without even the implied warranty \r
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
- * PURPOSE. See the GNU General Public License for more details.\r
- * \r
- * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.\r
--->\r
-<html xmlns="http://www.w3.org/1999/xhtml">\r
- <head>Jalview i18n</head>\r
- <body>\r
-<h1>Best practices</h1>\r
-<ol>\r
-<li>Follow the standards described in this guide</li>\r
-<li>Always use properties files for user interface text; never include displayable text in code</li>\r
-<li>Use properties files only for user interface text (Messages_xx.properties) and config files for configuration settings (jalview.properties).</li>\r
-<li>Use a proper naming schema for keys in your resource bundles. The name of the keys should provide some information about the context of the displayed text. This helps the translators during the translation process.</li>\r
-<li>Group keys by view, ie. edit.title, edit.instructions, list.title, list.instructions, create.title, etc</li>\r
-<li>Never use displayable text when executing comparisons within the logic of the tool (separate codified values from displayable text)</li>\r
-<li>Always use the MessageManager class for retrieving properties values, and invoke MessageManager methods dynamically, to accommodate dynamic user preferences (see MessageManager below).</li>\r
-<li>All numbers and dates should be formatted specific to the user's locale (e.g. java.text.NumberFormat and java.text.DateFormat)</li>\r
-<li>Test code in more than one language</li>\r
-</ol>\r
-<h1>MessageManager</h1>\r
-<p>The jalview.util.MessageManager class is a wrapper class for the ResourceBundle class. It provides dynamic language/locale support for individual users, and is recommended for all Jalview code.</p>\r
-<p>To use it within your code, you only have to invoke MessageManager with the text key in Messages_xx.properties:</p>\r
-<p>JButton ok = new JButton(MessageManager.getString("button.ok"));</p>\r
-<p>This will set JButton text to the one included at button.ok key. In English JButton text will be OK, while in Spanish will be Aceptar. This is the big thing of i18n. :)</p>\r
-<h1>Don't rely comparisons on labels</h1>\r
-<p>Don't use this type of coding:\r
- threshold.addItem("No Threshold");<br>\r
- threshold.addItem("Above Threshold");<br>\r
- threshold.addItem("Below Threshold");<br>\r
- [...]<br>\r
- if (threshold.getSelectedItem().equals("Above Threshold"))<br>\r
- {</br>\r
- aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;<br>\r
- }<br>\r
- else if (threshold.getSelectedItem().equals("Below Threshold"))<br>\r
- {<br>\r
- aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;<br>\r
- }<br>\r
-</p>\r
-<p>Once text has been translated, these equals will fail as the label won't be the English ones. It should be used getSelectedIndex() instead of getSelectedItem(). If you do the proper way, the code will look like this:<br>\r
- threshold.addItem(MessageManager.getString("label.threshold_feature_no_thereshold"));<br>\r
- threshold.addItem(MessageManager.getString("label.threshold_feature_above_thereshold"));<br>\r
- threshold.addItem(MessageManager.getString("label.threshold_feature_below_thereshold"));<br>\r
- [...]<br>\r
- if (threshold.getSelectedIndex()==1)<br>\r
- {<br>\r
- aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;<br>\r
- }<br>\r
- else if (threshold.getSelectedIndex()==2)<br>\r
- {<br>\r
- aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;<br>\r
- }<br> \r
-</p>\r
-<h1>How to translate Jalview</h1>\r
-<p>Anyone interested in localizing/translating Jalview is strongly encouraged to join the <a href="mailto:jalview-dev@jalview.org">Jalview Development List</a> list. We would recommend that you read this entire page before proceeding.</p>\r
-<p>If you are planning on working on a Jalview translation, please send us an email (<a href="mailto:jalview-dev@jalview.org">Jalview Development List</a>). There may be someone else already working on translating Jalview to your target language.</p>\r
-<p>Once you have downloaded the source code (available at <a href="http://www.jalview.org/download">http://www.jalview.org/download</a>), you must edit {jalview.home}/resources/lang/Messages_xx.properties, where xx refers to your language country code. If it doesn't exits, rename Messages.properties to Messages_xx.properties.</p>\r
-<p>Next step...start transtalation!</p>\r
-<p>Once you have it translated, we would appreciate if you contribute it forwarding the file to <a href="mailto:jalview-dev@jalview.org">Jalview Development List</a>. We will commit it to the code base as soon as possible. Thanks so much for this in advance!</p>\r
-</body>\r
-</html>\r
-\r
+<!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
+ * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview 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.
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>Jalview i18n</head>
+ <body>
+<h1>Best practices</h1>
+<ol>
+<li>Follow the standards described in this guide</li>
+<li>Always use properties files for user interface text; never include displayable text in code</li>
+<li>Use properties files only for user interface text (Messages_xx.properties) and config files for configuration settings (jalview.properties).</li>
+<li>Use a proper naming schema for keys in your resource bundles. The name of the keys should provide some information about the context of the displayed text. This helps the translators during the translation process.</li>
+<li>Group keys by view, ie. edit.title, edit.instructions, list.title, list.instructions, create.title, etc</li>
+<li>Never use displayable text when executing comparisons within the logic of the tool (separate codified values from displayable text)</li>
+<li>Always use the MessageManager class for retrieving properties values, and invoke MessageManager methods dynamically, to accommodate dynamic user preferences (see MessageManager below).</li>
+<li>All numbers and dates should be formatted specific to the user's locale (e.g. java.text.NumberFormat and java.text.DateFormat)</li>
+<li>Test code in more than one language</li>
+</ol>
+<h1>MessageManager</h1>
+<p>The jalview.util.MessageManager class is a wrapper class for the ResourceBundle class. It provides dynamic language/locale support for individual users, and is recommended for all Jalview code.</p>
+<p>To use it within your code, you only have to invoke MessageManager with the text key in Messages_xx.properties:</p>
+<p>JButton ok = new JButton(MessageManager.getString("button.ok"));</p>
+<p>This will set JButton text to the one included at button.ok key. In English JButton text will be OK, while in Spanish will be Aceptar. This is the big thing of i18n. :)</p>
+<h1>Don't rely comparisons on labels</h1>
+<p>Don't use this type of coding:
+ threshold.addItem("No Threshold");<br>
+ threshold.addItem("Above Threshold");<br>
+ threshold.addItem("Below Threshold");<br>
+ [...]<br>
+ if (threshold.getSelectedItem().equals("Above Threshold"))<br>
+ {</br>
+ aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;<br>
+ }<br>
+ else if (threshold.getSelectedItem().equals("Below Threshold"))<br>
+ {<br>
+ aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;<br>
+ }<br>
+</p>
+<p>Once text has been translated, these equals will fail as the label won't be the English ones. It should be used getSelectedIndex() instead of getSelectedItem(). If you do the proper way, the code will look like this:<br>
+ threshold.addItem(MessageManager.getString("label.threshold_feature_no_thereshold"));<br>
+ threshold.addItem(MessageManager.getString("label.threshold_feature_above_thereshold"));<br>
+ threshold.addItem(MessageManager.getString("label.threshold_feature_below_thereshold"));<br>
+ [...]<br>
+ if (threshold.getSelectedIndex()==1)<br>
+ {<br>
+ aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;<br>
+ }<br>
+ else if (threshold.getSelectedIndex()==2)<br>
+ {<br>
+ aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;<br>
+ }<br>
+</p>
+<h1>How to translate Jalview</h1>
+<p>Anyone interested in localizing/translating Jalview is strongly encouraged to join the <a href="mailto:jalview-dev@jalview.org">Jalview Development List</a> list. We would recommend that you read this entire page before proceeding.</p>
+<p>If you are planning on working on a Jalview translation, please send us an email (<a href="mailto:jalview-dev@jalview.org">Jalview Development List</a>). There may be someone else already working on translating Jalview to your target language.</p>
+<p>Once you have downloaded the source code (available at <a href="http://www.jalview.org/download">http://www.jalview.org/download</a>), you must edit {jalview.home}/resources/lang/Messages_xx.properties, where xx refers to your language country code. If it doesn't exits, rename Messages.properties to Messages_xx.properties.</p>
+<p>Next step...start transtalation!</p>
+<p>Once you have it translated, we would appreciate if you contribute it forwarding the file to <a href="mailto:jalview-dev@jalview.org">Jalview Development List</a>. We will commit it to the code base as soon as possible. Thanks so much for this in advance!</p>
+</body>
+</html>
+
-HEADER OXIDOREDUCTASE/ELECTRON TRANSPORT 08-MAY-00 1GAQ \r
-ATOM 2 CA GLU A 19 20.491 30.713 36.290 1.00 74.29 C \r
-ATOM 11 CA SER A 20 24.056 29.774 37.264 1.00 72.09 C \r
-ATOM 17 CA LYS A 21 27.517 31.289 37.563 1.00 70.09 C \r
-ATOM 26 CA LYS A 22 28.794 27.865 36.481 1.00 68.64 C \r
-ATOM 35 CA GLN A 23 29.484 26.806 32.884 1.00 70.46 C \r
-ATOM 44 CA GLU A 24 26.420 25.175 31.360 1.00 72.08 C \r
-ATOM 53 CA GLU A 25 26.736 26.049 27.683 1.00 70.43 C \r
-ATOM 62 CA GLY A 26 28.299 22.912 26.233 1.00 63.14 C \r
-ATOM 66 CA VAL A 27 26.863 20.704 28.982 1.00 54.50 C \r
-ATOM 73 CA VAL A 28 25.030 17.390 28.655 1.00 48.32 C \r
-ATOM 80 CA THR A 29 23.728 14.677 30.991 1.00 44.86 C \r
-ATOM 87 CA ASN A 30 22.327 11.164 30.703 1.00 45.42 C \r
-ATOM 95 CA LEU A 31 23.332 10.459 27.102 1.00 45.42 C \r
-ATOM 103 CA TYR A 32 23.549 6.898 28.380 1.00 45.88 C \r
-ATOM 115 CA LYS A 33 21.656 5.321 31.262 1.00 47.27 C \r
-ATOM 124 CA PRO A 34 21.991 2.046 33.248 1.00 48.99 C \r
-ATOM 131 CA LYS A 35 19.339 0.560 30.970 1.00 52.75 C \r
-ATOM 140 CA GLU A 36 21.580 0.855 27.886 1.00 53.33 C \r
-ATOM 149 CA PRO A 37 25.154 2.015 28.678 1.00 47.54 C \r
-ATOM 156 CA TYR A 38 27.929 2.872 26.249 1.00 41.98 C \r
-ATOM 168 CA VAL A 39 30.355 -0.017 25.909 1.00 41.48 C \r
-ATOM 175 CA GLY A 40 33.823 1.485 25.966 1.00 37.59 C \r
-ATOM 179 CA ARG A 41 37.165 -0.277 26.122 1.00 39.77 C \r
-ATOM 190 CA CYS A 42 40.148 -0.029 28.442 1.00 36.51 C \r
-ATOM 196 CA LEU A 43 43.095 1.441 26.554 1.00 36.13 C \r
-ATOM 204 CA LEU A 44 45.231 2.023 29.649 1.00 33.55 C \r
-ATOM 212 CA ASN A 45 45.140 1.026 33.307 1.00 27.79 C \r
-ATOM 220 CA THR A 46 48.056 1.800 35.617 1.00 28.75 C \r
-ATOM 227 CA LYS A 47 48.542 1.776 39.388 1.00 30.31 C \r
-ATOM 236 CA ILE A 48 49.564 5.317 40.376 1.00 31.32 C \r
-ATOM 244 CA THR A 49 50.339 4.682 44.059 1.00 37.62 C \r
-ATOM 251 CA GLY A 50 53.585 3.317 45.460 1.00 44.49 C \r
-ATOM 255 CA ASP A 51 53.706 -0.448 46.087 1.00 52.89 C \r
-ATOM 263 CA ASP A 52 53.910 0.545 49.751 1.00 55.23 C \r
-ATOM 271 CA ALA A 53 50.816 2.767 50.056 1.00 53.34 C \r
-ATOM 276 CA PRO A 54 47.904 1.940 52.405 1.00 50.60 C \r
-ATOM 283 CA GLY A 55 45.420 1.579 49.561 1.00 50.35 C \r
-ATOM 287 CA GLU A 56 46.098 1.286 45.836 1.00 42.53 C \r
-ATOM 296 CA THR A 57 44.534 3.816 43.480 1.00 41.14 C \r
-ATOM 303 CA TRP A 58 44.540 3.423 39.708 1.00 35.60 C \r
-ATOM 317 CA HIS A 59 44.468 5.853 36.796 1.00 31.89 C \r
-ATOM 327 CA MET A 60 42.658 4.227 33.866 1.00 31.65 C \r
-ATOM 335 CA VAL A 61 41.716 5.345 30.350 1.00 30.43 C \r
-ATOM 342 CA PHE A 62 38.669 4.172 28.360 1.00 34.36 C \r
-ATOM 353 CA SER A 63 37.657 4.908 24.772 1.00 34.69 C \r
-ATOM 359 CA THR A 64 34.448 6.828 23.951 1.00 36.96 C \r
-ATOM 366 CA GLU A 65 34.691 7.644 20.254 1.00 40.08 C \r
-ATOM 375 CA GLY A 66 33.742 11.183 21.285 1.00 40.22 C \r
-ATOM 379 CA LYS A 67 30.272 9.763 22.003 1.00 41.93 C \r
-ATOM 388 CA ILE A 68 30.279 11.116 25.577 1.00 41.52 C \r
-ATOM 396 CA PRO A 69 30.791 14.926 25.537 1.00 42.35 C \r
-ATOM 403 CA TYR A 70 31.228 15.232 29.299 1.00 39.84 C \r
-ATOM 415 CA ARG A 71 32.639 18.451 30.768 1.00 44.14 C \r
-ATOM 426 CA GLU A 72 35.122 19.278 33.515 1.00 43.82 C \r
-ATOM 435 CA GLY A 73 33.472 18.458 36.835 1.00 41.97 C \r
-ATOM 439 CA GLN A 74 30.929 15.874 35.657 1.00 37.19 C \r
-ATOM 448 CA SER A 75 31.285 12.124 36.138 1.00 38.28 C \r
-ATOM 454 CA ILE A 76 30.458 8.792 34.539 1.00 36.84 C \r
-ATOM 462 CA GLY A 77 28.983 5.620 35.918 1.00 35.39 C \r
-ATOM 466 CA VAL A 78 30.311 2.108 35.530 1.00 32.05 C \r
-ATOM 473 CA ILE A 79 28.458 -1.201 35.591 1.00 32.67 C \r
-ATOM 481 CA ALA A 80 30.745 -4.018 36.644 1.00 35.36 C \r
-ATOM 486 CA ASP A 81 30.359 -7.373 34.872 1.00 38.72 C \r
-ATOM 494 CA GLY A 82 28.308 -10.332 36.110 1.00 45.79 C \r
-ATOM 498 CA VAL A 83 25.820 -10.242 39.001 1.00 52.24 C \r
-ATOM 505 CA ASP A 84 25.838 -10.250 42.834 1.00 60.54 C \r
-ATOM 513 CA LYS A 85 25.014 -13.158 45.196 1.00 66.72 C \r
-ATOM 522 CA ASN A 86 21.414 -13.062 43.904 1.00 67.37 C \r
-ATOM 530 CA GLY A 87 21.724 -13.423 40.136 1.00 64.74 C \r
-ATOM 534 CA LYS A 88 20.971 -9.733 39.570 1.00 61.12 C \r
-ATOM 543 CA PRO A 89 23.054 -7.201 37.561 1.00 54.68 C \r
-ATOM 550 CA HIS A 90 25.224 -4.957 39.755 1.00 44.44 C \r
-ATOM 560 CA LYS A 91 23.940 -1.433 40.260 1.00 40.48 C \r
-ATOM 569 CA VAL A 92 25.803 1.546 38.843 1.00 38.45 C \r
-ATOM 576 CA ARG A 93 28.709 2.986 40.828 1.00 38.93 C \r
-ATOM 587 CA LEU A 94 29.778 6.584 40.096 1.00 34.37 C \r
-ATOM 595 CA TYR A 95 33.309 7.878 39.513 1.00 30.27 C \r
-ATOM 607 CA SER A 96 34.425 11.475 39.057 1.00 29.44 C \r
-ATOM 613 CA ILE A 97 36.029 12.090 35.662 1.00 27.61 C \r
-ATOM 621 CA ALA A 98 39.769 12.693 36.069 1.00 31.12 C \r
-ATOM 626 CA SER A 99 40.393 13.712 32.475 1.00 32.42 C \r
-ATOM 632 CA SER A 100 39.566 17.142 31.059 1.00 36.14 C \r
-ATOM 638 CA ALA A 101 37.097 17.367 28.154 1.00 41.07 C \r
-ATOM 643 CA ILE A 102 39.764 16.549 25.527 1.00 47.65 C \r
-ATOM 651 CA GLY A 103 41.172 13.692 27.599 1.00 46.77 C \r
-ATOM 655 CA ASP A 104 44.730 12.612 28.289 1.00 43.82 C \r
-ATOM 663 CA PHE A 105 45.115 12.065 24.522 1.00 41.52 C \r
-ATOM 674 CA GLY A 106 43.862 15.455 23.328 1.00 41.66 C \r
-ATOM 678 CA ASP A 107 41.355 13.883 20.926 1.00 40.90 C \r
-ATOM 686 CA SER A 108 38.132 14.250 22.954 1.00 42.95 C \r
-ATOM 692 CA LYS A 109 37.967 10.535 22.224 1.00 44.74 C \r
-ATOM 701 CA THR A 110 38.731 9.184 25.704 1.00 41.09 C \r
-ATOM 708 CA VAL A 111 37.728 9.519 29.374 1.00 39.03 C \r
-ATOM 715 CA SER A 112 39.912 8.705 32.399 1.00 37.17 C \r
-ATOM 721 CA LEU A 113 39.098 7.476 35.935 1.00 32.10 C \r
-ATOM 729 CA CYS A 114 40.964 7.578 39.261 1.00 30.65 C \r
-ATOM 735 CA VAL A 115 39.724 4.459 41.060 1.00 33.45 C \r
-ATOM 742 CA LYS A 116 40.668 3.524 44.628 1.00 34.75 C \r
-ATOM 751 CA ARG A 117 40.376 -0.250 45.123 1.00 32.85 C \r
-ATOM 762 CA LEU A 118 38.137 -1.094 48.077 1.00 30.50 C \r
-ATOM 770 CA ILE A 119 39.376 -3.752 50.459 1.00 34.34 C \r
-ATOM 778 CA TYR A 120 38.699 -4.266 54.125 1.00 31.39 C \r
-ATOM 790 CA THR A 121 38.264 -7.086 56.567 1.00 28.83 C \r
-ATOM 797 CA ASN A 122 34.792 -7.477 58.109 1.00 26.51 C \r
-ATOM 805 CA ASP A 123 33.626 -8.382 61.634 1.00 31.58 C \r
-ATOM 813 CA ALA A 124 34.191 -12.077 60.901 1.00 27.84 C \r
-ATOM 818 CA GLY A 125 37.759 -11.844 59.728 1.00 32.39 C \r
-ATOM 822 CA GLU A 126 36.809 -12.146 56.073 1.00 35.82 C \r
-ATOM 831 CA ILE A 127 38.655 -9.932 53.598 1.00 38.42 C \r
-ATOM 839 CA VAL A 128 36.025 -8.261 51.421 1.00 33.73 C \r
-ATOM 846 CA LYS A 129 36.482 -6.484 48.090 1.00 31.87 C \r
-ATOM 855 CA GLY A 130 34.363 -3.680 46.686 1.00 26.91 C \r
-ATOM 859 CA VAL A 131 32.680 -5.051 43.569 1.00 27.89 C \r
-ATOM 866 CA CYS A 132 33.074 -2.246 41.018 1.00 28.46 C \r
-ATOM 872 CA SER A 133 36.266 -0.553 42.213 1.00 31.33 C \r
-ATOM 878 CA ASN A 134 37.861 -3.983 41.984 1.00 30.29 C \r
-ATOM 886 CA PHE A 135 36.318 -4.795 38.623 1.00 31.48 C \r
-ATOM 897 CA LEU A 136 37.926 -1.553 37.520 1.00 27.81 C \r
-ATOM 905 CA CYS A 137 41.417 -1.976 38.955 1.00 25.91 C \r
-ATOM 911 CA ASP A 138 41.605 -5.419 37.338 1.00 30.22 C \r
-ATOM 919 CA LEU A 139 40.462 -4.306 33.874 1.00 32.69 C \r
-ATOM 927 CA GLN A 140 42.851 -5.511 31.186 1.00 36.80 C \r
-ATOM 936 CA PRO A 141 43.380 -3.220 28.170 1.00 36.16 C \r
-ATOM 943 CA GLY A 142 40.864 -4.420 25.586 1.00 31.10 C \r
-ATOM 947 CA ASP A 143 38.129 -5.298 28.055 1.00 30.62 C \r
-ATOM 955 CA ASN A 144 34.690 -3.847 27.645 1.00 33.52 C \r
-ATOM 963 CA VAL A 145 33.430 -1.522 30.361 1.00 37.08 C \r
-ATOM 970 CA GLN A 146 29.817 -0.374 30.523 1.00 37.65 C \r
-ATOM 979 CA ILE A 147 29.547 3.413 31.045 1.00 30.95 C \r
-ATOM 987 CA THR A 148 26.637 5.791 31.832 1.00 29.95 C \r
-ATOM 994 CA GLY A 149 26.297 9.581 31.843 1.00 32.81 C \r
-ATOM 998 CA PRO A 150 27.785 12.148 31.800 1.00 34.98 C \r
-ATOM 1005 CA VAL A 151 26.376 12.668 35.275 1.00 36.53 C \r
-ATOM 1012 CA GLY A 152 26.196 15.756 37.474 1.00 43.09 C \r
-ATOM 1016 CA LYS A 153 26.048 19.528 37.068 1.00 48.37 C \r
-ATOM 1025 CA GLU A 154 26.921 20.540 40.633 1.00 49.70 C \r
-ATOM 1034 CA MET A 155 30.710 20.266 40.235 1.00 47.30 C \r
-ATOM 1042 CA LEU A 156 30.882 22.020 36.869 1.00 50.36 C \r
-ATOM 1050 CA MET A 157 33.362 24.883 36.404 1.00 55.29 C \r
-ATOM 1058 CA PRO A 158 32.521 28.612 36.605 1.00 54.88 C \r
-ATOM 1065 CA LYS A 159 32.291 30.776 33.464 1.00 54.92 C \r
-ATOM 1074 CA ASP A 160 34.497 33.503 34.939 1.00 57.22 C \r
-ATOM 1082 CA PRO A 161 38.055 32.687 33.759 1.00 58.62 C \r
-ATOM 1089 CA ASN A 162 39.524 35.240 36.163 1.00 60.44 C \r
-ATOM 1097 CA ALA A 163 37.814 33.910 39.279 1.00 55.80 C \r
-ATOM 1102 CA THR A 164 39.596 32.487 42.316 1.00 51.04 C \r
-ATOM 1109 CA ILE A 165 38.966 28.771 42.756 1.00 50.26 C \r
-ATOM 1117 CA ILE A 166 39.774 26.773 45.885 1.00 47.54 C \r
-ATOM 1125 CA MET A 167 39.883 23.014 45.324 1.00 46.38 C \r
-ATOM 1133 CA LEU A 168 39.700 20.963 48.522 1.00 42.18 C \r
-ATOM 1141 CA ALA A 169 40.377 17.316 47.770 1.00 36.41 C \r
-ATOM 1146 CA THR A 170 41.005 14.086 49.622 1.00 32.98 C \r
-ATOM 1153 CA GLY A 171 42.027 10.802 48.014 1.00 31.36 C \r
-ATOM 1157 CA THR A 172 40.386 10.037 44.680 1.00 30.48 C \r
-ATOM 1164 CA GLY A 173 38.640 13.335 45.359 1.00 33.99 C \r
-ATOM 1168 CA ILE A 174 41.418 15.036 43.394 1.00 35.66 C \r
-ATOM 1176 CA ALA A 175 39.758 13.585 40.300 1.00 36.00 C \r
-ATOM 1181 CA PRO A 176 37.445 16.385 39.155 1.00 39.41 C \r
-ATOM 1188 CA PHE A 177 40.109 18.971 39.976 1.00 43.21 C \r
-ATOM 1199 CA ARG A 178 42.726 17.119 37.955 1.00 41.09 C \r
-ATOM 1210 CA SER A 179 40.235 17.536 35.124 1.00 39.92 C \r
-ATOM 1216 CA PHE A 180 39.808 21.204 36.009 1.00 39.23 C \r
-ATOM 1227 CA LEU A 181 43.528 21.949 35.995 1.00 39.50 C \r
-ATOM 1235 CA TRP A 182 44.305 20.081 32.770 1.00 41.47 C \r
-ATOM 1249 CA LYS A 183 42.141 22.654 30.972 1.00 48.08 C \r
-ATOM 1258 CA MET A 184 43.477 25.547 33.062 1.00 52.79 C \r
-ATOM 1266 CA PHE A 185 47.102 25.043 32.014 1.00 57.35 C \r
-ATOM 1277 CA PHE A 186 48.075 21.921 30.051 1.00 55.98 C \r
-ATOM 1288 CA GLU A 187 45.758 23.173 27.297 1.00 54.44 C \r
-ATOM 1297 CA LYS A 188 44.908 26.236 25.196 1.00 51.29 C \r
-ATOM 1306 CA HIS A 189 41.395 27.080 24.003 1.00 51.35 C \r
-ATOM 1316 CA ASP A 190 40.108 29.972 21.873 1.00 54.30 C \r
-ATOM 1324 CA ASP A 191 37.199 30.481 24.249 1.00 53.95 C \r
-ATOM 1332 CA TYR A 192 38.816 29.937 27.634 1.00 50.68 C \r
-ATOM 1344 CA LYS A 193 41.916 31.388 29.230 1.00 51.00 C \r
-ATOM 1353 CA PHE A 194 42.322 30.967 32.956 1.00 52.09 C \r
-ATOM 1364 CA ASN A 195 43.672 34.234 34.312 1.00 56.46 C \r
-ATOM 1372 CA GLY A 196 42.616 34.078 37.969 1.00 57.17 C \r
-ATOM 1376 CA LEU A 197 43.874 31.920 40.843 1.00 57.92 C \r
-ATOM 1384 CA GLY A 198 43.549 28.151 41.086 1.00 56.67 C \r
-ATOM 1388 CA TRP A 199 44.258 26.886 44.592 1.00 51.55 C \r
-ATOM 1402 CA LEU A 200 44.411 23.170 45.379 1.00 49.17 C \r
-ATOM 1410 CA PHE A 201 44.558 21.335 48.709 1.00 48.60 C \r
-ATOM 1421 CA LEU A 202 45.122 17.570 48.598 1.00 45.34 C \r
-ATOM 1429 CA GLY A 203 44.885 15.480 51.742 1.00 48.55 C \r
-ATOM 1433 CA VAL A 204 46.225 11.936 51.755 1.00 50.23 C \r
-ATOM 1440 CA PRO A 205 47.942 9.740 54.365 1.00 51.51 C \r
-ATOM 1447 CA THR A 206 51.284 9.148 52.648 1.00 50.21 C \r
-ATOM 1454 CA SER A 207 53.551 10.483 49.894 1.00 49.38 C \r
-ATOM 1460 CA SER A 208 53.267 7.061 48.259 1.00 43.49 C \r
-ATOM 1466 CA SER A 209 49.588 8.049 48.093 1.00 42.57 C \r
-ATOM 1472 CA LEU A 210 49.990 11.424 46.364 1.00 42.65 C \r
-ATOM 1480 CA LEU A 211 48.121 11.446 43.035 1.00 39.33 C \r
-ATOM 1488 CA TYR A 212 49.516 13.214 39.935 1.00 40.89 C \r
-ATOM 1500 CA LYS A 213 52.128 15.234 41.873 1.00 45.88 C \r
-ATOM 1509 CA GLU A 214 54.518 15.406 38.899 1.00 53.22 C \r
-ATOM 1518 CA GLU A 215 51.680 16.911 36.889 1.00 55.16 C \r
-ATOM 1527 CA PHE A 216 50.757 19.475 39.514 1.00 60.55 C \r
-ATOM 1538 CA GLY A 217 54.488 20.153 39.524 1.00 66.64 C \r
-ATOM 1542 CA LYS A 218 54.575 21.110 35.850 1.00 68.86 C \r
-ATOM 1551 CA MET A 219 51.398 23.159 36.265 1.00 66.97 C \r
-ATOM 1559 CA LYS A 220 53.138 25.090 39.061 1.00 65.97 C \r
-ATOM 1568 CA GLU A 221 55.654 26.250 36.459 1.00 70.02 C \r
-ATOM 1577 CA ARG A 222 53.584 26.507 33.294 1.00 73.48 C \r
-ATOM 1588 CA ALA A 223 52.005 29.449 35.175 1.00 76.21 C \r
-ATOM 1593 CA PRO A 224 53.272 29.877 38.804 1.00 79.25 C \r
-ATOM 1600 CA GLU A 225 51.296 33.124 39.020 1.00 81.84 C \r
-ATOM 1609 CA ASN A 226 47.873 31.528 38.622 1.00 78.84 C \r
-ATOM 1617 CA PHE A 227 48.418 28.176 40.350 1.00 75.28 C \r
-ATOM 1628 CA ARG A 228 49.090 27.305 43.996 1.00 72.05 C \r
-ATOM 1639 CA VAL A 229 49.165 23.724 45.323 1.00 68.82 C \r
-ATOM 1646 CA ASP A 230 49.258 22.581 48.958 1.00 66.54 C \r
-ATOM 1654 CA TYR A 231 49.605 18.943 49.968 1.00 60.31 C \r
-ATOM 1666 CA ALA A 232 48.551 17.560 53.332 1.00 57.39 C \r
-ATOM 1671 CA VAL A 233 50.260 14.228 53.945 1.00 57.14 C \r
-ATOM 1678 CA SER A 234 48.465 13.579 57.244 1.00 60.81 C \r
-ATOM 1684 CA ARG A 235 50.959 11.010 58.514 1.00 60.74 C \r
-ATOM 1695 CA GLU A 236 54.268 12.594 57.481 1.00 59.17 C \r
-ATOM 1704 CA GLN A 237 53.494 16.197 58.450 1.00 59.62 C \r
-ATOM 1713 CA THR A 238 52.590 18.236 61.521 1.00 63.18 C \r
-ATOM 1720 CA ASN A 239 52.019 21.937 62.188 1.00 66.71 C \r
-ATOM 1728 CA ALA A 240 52.096 23.767 65.537 1.00 70.06 C \r
-ATOM 1733 CA ALA A 241 51.302 21.400 68.410 1.00 72.44 C \r
-ATOM 1738 CA GLY A 242 52.383 18.324 66.438 1.00 72.38 C \r
-ATOM 1742 CA GLU A 243 48.826 18.169 65.110 1.00 69.71 C \r
-ATOM 1751 CA ARG A 244 48.674 15.776 62.148 1.00 67.21 C \r
-ATOM 1762 CA MET A 245 48.712 17.796 58.933 1.00 64.20 C \r
-ATOM 1770 CA TYR A 246 45.246 17.082 57.556 1.00 60.65 C \r
-ATOM 1782 CA ILE A 247 43.617 18.437 54.409 1.00 62.98 C \r
-ATOM 1790 CA GLN A 248 42.035 21.001 56.761 1.00 64.64 C \r
-ATOM 1799 CA THR A 249 45.057 21.461 59.009 1.00 63.37 C \r
-ATOM 1806 CA ARG A 250 46.891 22.664 55.903 1.00 62.47 C \r
-ATOM 1817 CA MET A 251 44.123 25.201 55.251 1.00 63.35 C \r
-ATOM 1825 CA ALA A 252 44.571 26.305 58.854 1.00 65.73 C \r
-ATOM 1830 CA GLU A 253 47.973 27.809 58.076 1.00 65.97 C \r
-ATOM 1839 CA TYR A 254 46.267 30.063 55.517 1.00 65.83 C \r
-ATOM 1851 CA LYS A 255 42.991 30.559 57.379 1.00 70.30 C \r
-ATOM 1860 CA GLU A 256 43.578 34.326 57.320 1.00 73.73 C \r
-ATOM 1869 CA GLU A 257 44.189 34.738 53.593 1.00 71.52 C \r
-ATOM 1878 CA LEU A 258 41.459 32.202 52.893 1.00 73.38 C \r
-ATOM 1886 CA TRP A 259 38.790 34.074 54.853 1.00 76.72 C \r
-ATOM 1900 CA GLU A 260 39.721 37.275 53.006 1.00 78.61 C \r
-ATOM 1909 CA LEU A 261 38.580 35.553 49.815 1.00 75.71 C \r
-ATOM 1917 CA LEU A 262 35.391 33.881 51.047 1.00 73.74 C \r
-ATOM 1925 CA LYS A 263 33.562 37.165 50.535 1.00 73.64 C \r
-ATOM 1934 CA LYS A 264 34.299 38.143 46.954 1.00 72.48 C \r
-ATOM 1943 CA ASP A 265 31.954 37.554 43.993 1.00 69.65 C \r
-ATOM 1951 CA ASN A 266 34.660 35.649 42.106 1.00 65.06 C \r
-ATOM 1959 CA THR A 267 35.835 33.117 44.683 1.00 58.24 C \r
-ATOM 1966 CA TYR A 268 34.459 29.646 43.909 1.00 51.04 C \r
-ATOM 1978 CA VAL A 269 35.192 26.827 46.382 1.00 44.95 C \r
-ATOM 1985 CA TYR A 270 35.012 23.150 45.368 1.00 44.96 C \r
-ATOM 1997 CA MET A 271 35.162 20.122 47.656 1.00 41.72 C \r
-ATOM 2005 CA CYS A 272 35.314 16.468 46.632 1.00 37.19 C \r
-ATOM 2011 CA GLY A 273 36.343 13.080 47.951 1.00 37.65 C \r
-ATOM 2015 CA LEU A 274 36.040 10.886 51.020 1.00 39.39 C \r
-ATOM 2023 CA LYS A 275 33.076 12.283 52.955 1.00 44.86 C \r
-ATOM 2032 CA GLY A 276 34.322 13.183 56.400 1.00 49.16 C \r
-ATOM 2036 CA MET A 277 36.932 15.608 55.168 1.00 53.30 C \r
-ATOM 2044 CA GLU A 278 33.917 17.921 55.165 1.00 56.74 C \r
-ATOM 2053 CA LYS A 279 33.531 18.089 58.947 1.00 59.30 C \r
-ATOM 2062 CA GLY A 280 36.982 19.413 59.776 1.00 58.94 C \r
-ATOM 2066 CA ILE A 281 36.705 22.048 57.063 1.00 61.43 C \r
-ATOM 2074 CA ASP A 282 33.453 23.402 58.515 1.00 67.06 C \r
-ATOM 2082 CA ASP A 283 35.050 23.189 61.972 1.00 74.12 C \r
-ATOM 2090 CA ILE A 284 37.991 25.422 61.040 1.00 78.49 C \r
-ATOM 2098 CA MET A 285 35.456 27.566 59.201 1.00 82.25 C \r
-ATOM 2106 CA VAL A 286 32.941 27.959 62.027 1.00 83.44 C \r
-ATOM 2113 CA SER A 287 35.610 29.113 64.469 1.00 83.43 C \r
-ATOM 2119 CA LEU A 288 36.927 31.601 61.887 1.00 85.53 C \r
-ATOM 2127 CA ALA A 289 33.506 33.025 60.970 1.00 86.85 C \r
-ATOM 2132 CA GLU A 290 31.841 32.696 64.387 1.00 89.26 C \r
-ATOM 2141 CA LYS A 291 34.438 35.312 65.347 1.00 88.73 C \r
-ATOM 2150 CA ASP A 292 33.635 37.891 62.652 1.00 88.03 C \r
-ATOM 2158 CA GLY A 293 30.219 37.450 61.081 1.00 87.88 C \r
-ATOM 2162 CA ILE A 294 27.319 35.051 61.511 1.00 84.61 C \r
-ATOM 2170 CA ASP A 295 27.665 31.329 62.188 1.00 82.45 C \r
-ATOM 2178 CA TRP A 296 29.539 29.627 59.355 1.00 80.12 C \r
-ATOM 2192 CA PHE A 297 26.527 27.452 58.512 1.00 78.99 C \r
-ATOM 2203 CA ASP A 298 24.167 30.241 57.486 1.00 76.37 C \r
-ATOM 2211 CA TYR A 299 27.074 31.748 55.561 1.00 74.07 C \r
-ATOM 2223 CA LYS A 300 27.679 28.620 53.473 1.00 74.31 C \r
-ATOM 2232 CA LYS A 301 24.059 29.146 52.464 1.00 75.97 C \r
-ATOM 2241 CA GLN A 302 24.921 32.563 51.018 1.00 75.38 C \r
-ATOM 2250 CA LEU A 303 27.896 31.099 49.155 1.00 72.10 C \r
-ATOM 2258 CA LYS A 304 25.917 28.207 47.690 1.00 72.08 C \r
-ATOM 2267 CA ARG A 305 23.595 31.021 46.594 1.00 74.82 C \r
-ATOM 2278 CA GLY A 306 26.071 32.136 43.958 1.00 71.84 C \r
-ATOM 2282 CA ASP A 307 27.505 28.682 43.220 1.00 67.23 C \r
-ATOM 2290 CA GLN A 308 30.620 29.291 45.346 1.00 60.18 C \r
-ATOM 2299 CA TRP A 309 30.585 26.177 47.537 1.00 52.25 C \r
-ATOM 2313 CA ASN A 310 29.894 22.997 45.597 1.00 45.03 C \r
-ATOM 2321 CA VAL A 311 30.327 19.716 47.403 1.00 39.13 C \r
-ATOM 2328 CA GLU A 312 30.507 16.190 46.110 1.00 35.17 C \r
-ATOM 2337 CA VAL A 313 31.761 13.957 48.861 1.00 30.12 C \r
-ATOM 2344 CA TYR A 314 31.112 10.230 49.021 1.00 28.23 C \r
-ATOM 2358 CA ALA B 1 2.311 24.702 44.475 1.00 74.17 C \r
-ATOM 2363 CA THR B 2 3.590 24.207 48.055 1.00 74.76 C \r
-ATOM 2370 CA TYR B 3 3.069 20.876 49.837 1.00 73.52 C \r
-ATOM 2382 CA ASN B 4 3.748 19.874 53.435 1.00 75.75 C \r
-ATOM 2390 CA VAL B 5 6.618 17.399 53.868 1.00 75.95 C \r
-ATOM 2397 CA LYS B 6 7.769 15.523 56.983 1.00 77.70 C \r
-ATOM 2406 CA LEU B 7 11.351 14.325 57.458 1.00 78.91 C \r
-ATOM 2414 CA ILE B 8 11.807 11.511 59.985 1.00 81.00 C \r
-ATOM 2422 CA THR B 9 15.560 12.046 60.247 1.00 87.49 C \r
-ATOM 2429 CA PRO B 10 17.662 9.793 62.539 1.00 92.94 C \r
-ATOM 2436 CA GLU B 11 18.161 13.147 64.282 1.00 96.61 C \r
-ATOM 2445 CA GLY B 12 14.579 14.154 65.041 1.00 97.52 C \r
-ATOM 2449 CA GLU B 13 11.602 14.823 62.748 1.00 96.90 C \r
-ATOM 2458 CA VAL B 14 11.547 17.892 60.480 1.00 96.63 C \r
-ATOM 2465 CA GLU B 15 8.340 19.701 59.440 1.00 94.86 C \r
-ATOM 2474 CA LEU B 16 9.471 21.479 56.254 1.00 91.55 C \r
-ATOM 2482 CA GLN B 17 7.281 23.141 53.598 1.00 89.75 C \r
-ATOM 2491 CA VAL B 18 8.485 22.069 50.145 1.00 87.92 C \r
-ATOM 2498 CA PRO B 19 6.906 23.558 46.964 1.00 86.35 C \r
-ATOM 2505 CA ASP B 20 5.990 21.744 43.717 1.00 86.29 C \r
-ATOM 2513 CA ASP B 21 8.578 22.751 41.083 1.00 83.78 C \r
-ATOM 2521 CA VAL B 22 11.385 22.401 43.639 1.00 80.98 C \r
-ATOM 2528 CA TYR B 23 13.439 19.280 44.481 1.00 77.04 C \r
-ATOM 2540 CA ILE B 24 13.212 18.196 48.120 1.00 76.45 C \r
-ATOM 2548 CA LEU B 25 16.959 18.133 48.851 1.00 75.15 C \r
-ATOM 2556 CA ASP B 26 17.154 21.745 47.689 1.00 75.80 C \r
-ATOM 2564 CA GLN B 27 14.616 22.906 50.280 1.00 76.31 C \r
-ATOM 2573 CA ALA B 28 16.562 20.957 52.914 1.00 78.86 C \r
-ATOM 2578 CA GLU B 29 19.698 23.011 52.198 1.00 81.51 C \r
-ATOM 2587 CA GLU B 30 17.491 26.106 52.510 1.00 83.25 C \r
-ATOM 2596 CA ASP B 31 15.857 25.933 55.935 1.00 81.92 C \r
-ATOM 2604 CA GLY B 32 19.280 24.859 57.151 1.00 79.08 C \r
-ATOM 2608 CA ILE B 33 18.621 21.130 57.157 1.00 76.93 C \r
-ATOM 2616 CA ASP B 34 21.528 18.731 56.618 1.00 73.53 C \r
-ATOM 2624 CA LEU B 35 20.738 15.738 54.421 1.00 67.74 C \r
-ATOM 2632 CA PRO B 36 23.138 13.391 52.547 1.00 65.90 C \r
-ATOM 2639 CA TYR B 37 23.916 14.226 48.912 1.00 64.85 C \r
-ATOM 2651 CA SER B 38 26.659 13.373 46.412 1.00 62.58 C \r
-ATOM 2657 CA CYS B 39 26.193 13.603 42.652 1.00 60.99 C \r
-ATOM 2663 CA ARG B 40 22.908 15.441 43.251 1.00 58.35 C \r
-ATOM 2674 CA ALA B 41 21.699 14.108 39.886 1.00 56.38 C \r
-ATOM 2679 CA GLY B 42 19.886 10.955 40.991 1.00 56.66 C \r
-ATOM 2683 CA SER B 43 22.465 8.336 40.010 1.00 58.55 C \r
-ATOM 2689 CA CYS B 44 23.548 7.052 43.447 1.00 56.27 C \r
-ATOM 2695 CA SER B 45 22.057 5.987 46.791 1.00 58.20 C \r
-ATOM 2701 CA SER B 46 23.574 8.773 48.890 1.00 59.13 C \r
-ATOM 2707 CA CYS B 47 20.220 10.475 49.517 1.00 65.64 C \r
-ATOM 2713 CA ALA B 48 17.911 7.436 49.610 1.00 69.71 C \r
-ATOM 2718 CA GLY B 49 14.733 7.635 51.681 1.00 73.09 C \r
-ATOM 2722 CA LYS B 50 11.712 5.340 52.183 1.00 73.77 C \r
-ATOM 2731 CA VAL B 51 8.551 7.412 51.568 1.00 76.51 C \r
-ATOM 2738 CA VAL B 52 5.237 7.081 53.429 1.00 78.85 C \r
-ATOM 2745 CA SER B 53 2.180 9.376 53.647 1.00 79.57 C \r
-ATOM 2751 CA GLY B 54 2.118 10.991 50.218 1.00 76.32 C \r
-ATOM 2755 CA SER B 55 3.577 10.944 46.726 1.00 76.31 C \r
-ATOM 2761 CA VAL B 56 6.436 12.592 44.828 1.00 77.50 C \r
-ATOM 2768 CA ASP B 57 7.691 12.960 41.243 1.00 76.83 C \r
-ATOM 2776 CA GLN B 58 11.150 11.483 40.555 1.00 76.66 C \r
-ATOM 2785 CA SER B 59 10.976 10.827 36.792 1.00 80.19 C \r
-ATOM 2791 CA ASP B 60 14.688 11.644 36.510 1.00 83.51 C \r
-ATOM 2799 CA GLN B 61 15.175 8.137 37.916 1.00 85.74 C \r
-ATOM 2808 CA SER B 62 18.644 7.080 36.699 1.00 85.85 C \r
-ATOM 2814 CA TYR B 63 19.324 5.049 39.852 1.00 84.49 C \r
-ATOM 2826 CA LEU B 64 15.683 4.296 40.629 1.00 89.06 C \r
-ATOM 2834 CA ASP B 65 15.356 0.604 39.742 1.00 92.21 C \r
-ATOM 2842 CA ASP B 66 12.421 -1.791 39.331 1.00 92.35 C \r
-ATOM 2850 CA GLY B 67 10.747 -2.542 42.659 1.00 89.07 C \r
-ATOM 2854 CA GLN B 68 12.336 0.632 44.010 1.00 88.41 C \r
-ATOM 2863 CA ILE B 69 9.483 2.828 42.742 1.00 86.11 C \r
-ATOM 2871 CA ALA B 70 7.060 0.441 44.446 1.00 81.10 C \r
-ATOM 2876 CA ASP B 71 8.985 -0.310 47.648 1.00 76.82 C \r
-ATOM 2884 CA GLY B 72 8.653 3.423 48.186 1.00 73.00 C \r
-ATOM 2888 CA TRP B 73 12.342 4.386 48.095 1.00 67.93 C \r
-ATOM 2902 CA VAL B 74 13.052 8.007 47.136 1.00 63.84 C \r
-ATOM 2909 CA LEU B 75 16.093 9.940 45.892 1.00 58.37 C \r
-ATOM 2917 CA THR B 76 15.524 13.198 47.826 1.00 55.82 C \r
-ATOM 2924 CA CYS B 77 17.941 15.109 45.556 1.00 58.23 C \r
-ATOM 2930 CA HIS B 78 15.777 14.389 42.513 1.00 64.55 C \r
-ATOM 2940 CA ALA B 79 12.108 14.429 43.512 1.00 68.40 C \r
-ATOM 2945 CA TYR B 80 9.442 17.152 43.581 1.00 69.69 C \r
-ATOM 2957 CA PRO B 81 6.414 16.584 45.842 1.00 71.39 C \r
-ATOM 2964 CA THR B 82 3.015 16.014 44.179 1.00 73.67 C \r
-ATOM 2971 CA SER B 83 1.278 15.771 47.557 1.00 76.90 C \r
-ATOM 2977 CA ASP B 84 1.940 16.119 51.289 1.00 75.20 C \r
-ATOM 2985 CA VAL B 85 4.840 13.765 52.050 1.00 71.37 C \r
-ATOM 2992 CA VAL B 86 6.363 11.824 54.956 1.00 70.12 C \r
-ATOM 2999 CA ILE B 87 9.770 10.300 54.188 1.00 74.18 C \r
-ATOM 3007 CA GLU B 88 12.211 8.403 56.410 1.00 78.53 C \r
-ATOM 3012 CA THR B 89 15.541 9.964 55.407 1.00 79.79 C \r
-ATOM 3019 CA HIS B 90 19.062 8.538 55.881 1.00 79.40 C \r
-ATOM 3029 CA LYS B 91 17.584 5.099 55.099 1.00 84.52 C \r
-ATOM 3038 CA GLU B 92 20.016 2.596 53.549 1.00 91.64 C \r
-ATOM 3047 CA GLU B 93 20.192 -0.858 51.981 1.00 98.97 C \r
-ATOM 3056 CA GLU B 94 23.321 -2.924 51.298 1.00106.32 C \r
-ATOM 3065 CA LEU B 95 22.104 -6.552 51.453 1.00111.32 C \r
-ATOM 3073 CA THR B 96 18.778 -8.417 51.866 1.00116.01 C \r
-ATOM 3080 CA GLY B 97 18.877 -11.302 49.394 1.00116.63 C \r
-ATOM 3084 CA ALA B 98 22.056 -9.833 47.910 1.00116.02 C \r
-ATOM 3091 CA GLU C 19 26.080 -2.480 15.294 1.00 73.96 C \r
-ATOM 3100 CA SER C 20 23.405 0.198 14.956 1.00 67.27 C \r
-ATOM 3106 CA LYS C 21 22.937 3.927 15.380 1.00 59.27 C \r
-ATOM 3115 CA LYS C 22 19.198 3.481 15.874 1.00 58.42 C \r
-ATOM 3124 CA GLN C 23 17.251 3.141 19.137 1.00 59.89 C \r
-ATOM 3133 CA GLU C 24 17.931 -0.276 20.610 1.00 62.66 C \r
-ATOM 3142 CA GLU C 25 16.850 -0.453 24.226 1.00 64.27 C \r
-ATOM 3151 CA GLY C 26 13.211 -0.817 25.116 1.00 61.78 C \r
-ATOM 3155 CA VAL C 27 12.703 -2.073 21.582 1.00 58.37 C \r
-ATOM 3162 CA VAL C 28 10.779 -5.347 21.485 1.00 54.17 C \r
-ATOM 3169 CA THR C 29 9.481 -7.339 18.549 1.00 52.79 C \r
-ATOM 3176 CA ASN C 30 6.670 -9.775 17.786 1.00 51.30 C \r
-ATOM 3184 CA LEU C 31 4.863 -9.997 21.112 1.00 51.05 C \r
-ATOM 3192 CA TYR C 32 1.766 -11.297 19.327 1.00 50.51 C \r
-ATOM 3204 CA LYS C 33 1.373 -13.532 16.266 1.00 49.49 C \r
-ATOM 3213 CA PRO C 34 -1.609 -14.150 13.925 1.00 50.98 C \r
-ATOM 3220 CA LYS C 35 -2.450 -17.248 16.011 1.00 55.46 C \r
-ATOM 3229 CA GLU C 36 -2.977 -15.400 19.288 1.00 53.79 C \r
-ATOM 3238 CA PRO C 37 -3.251 -11.638 18.607 1.00 49.32 C \r
-ATOM 3245 CA TYR C 38 -3.674 -9.050 21.318 1.00 46.76 C \r
-ATOM 3257 CA VAL C 39 -7.276 -7.947 21.418 1.00 43.68 C \r
-ATOM 3264 CA GLY C 40 -7.415 -4.194 21.922 1.00 41.62 C \r
-ATOM 3268 CA ARG C 41 -10.273 -1.719 21.954 1.00 40.07 C \r
-ATOM 3279 CA CYS C 42 -11.026 1.064 19.477 1.00 36.37 C \r
-ATOM 3285 CA LEU C 43 -11.330 4.206 21.583 1.00 31.09 C \r
-ATOM 3293 CA LEU C 44 -11.337 6.671 18.673 1.00 28.46 C \r
-ATOM 3301 CA ASN C 45 -11.792 6.653 14.923 1.00 26.74 C \r
-ATOM 3309 CA THR C 46 -11.954 9.920 13.013 1.00 25.29 C \r
-ATOM 3316 CA LYS C 47 -11.667 10.775 9.352 1.00 21.50 C \r
-ATOM 3325 CA ILE C 48 -8.895 13.355 9.121 1.00 19.33 C \r
-ATOM 3333 CA THR C 49 -9.125 14.281 5.442 1.00 20.38 C \r
-ATOM 3340 CA GLY C 50 -11.630 16.676 3.855 1.00 20.12 C \r
-ATOM 3344 CA ASP C 51 -14.895 15.345 2.412 1.00 21.75 C \r
-ATOM 3352 CA ASP C 52 -13.889 16.693 -0.999 1.00 21.19 C \r
-ATOM 3360 CA ALA C 53 -10.651 14.683 -0.749 1.00 21.06 C \r
-ATOM 3365 CA PRO C 54 -10.036 11.974 -3.413 1.00 21.39 C \r
-ATOM 3372 CA GLY C 55 -9.982 9.067 -0.977 1.00 24.42 C \r
-ATOM 3376 CA GLU C 56 -10.374 9.298 2.857 1.00 22.08 C \r
-ATOM 3385 CA THR C 57 -7.723 8.611 5.517 1.00 20.31 C \r
-ATOM 3392 CA TRP C 58 -8.541 7.849 9.162 1.00 19.33 C \r
-ATOM 3406 CA HIS C 59 -6.758 8.520 12.438 1.00 22.68 C \r
-ATOM 3416 CA MET C 60 -7.645 5.951 15.108 1.00 27.16 C \r
-ATOM 3424 CA VAL C 61 -6.672 5.224 18.723 1.00 29.32 C \r
-ATOM 3431 CA PHE C 62 -6.669 1.704 20.220 1.00 34.23 C \r
-ATOM 3442 CA SER C 63 -6.102 0.643 23.847 1.00 37.05 C \r
-ATOM 3448 CA THR C 64 -3.096 -1.517 24.798 1.00 41.86 C \r
-ATOM 3455 CA GLU C 65 -3.169 -1.652 28.621 1.00 48.33 C \r
-ATOM 3464 CA GLY C 66 0.537 -0.885 28.318 1.00 52.45 C \r
-ATOM 3468 CA LYS C 67 0.955 -4.385 26.891 1.00 54.14 C \r
-ATOM 3477 CA ILE C 68 2.429 -3.211 23.570 1.00 51.52 C \r
-ATOM 3485 CA PRO C 69 5.602 -1.279 24.487 1.00 49.85 C \r
-ATOM 3492 CA TYR C 70 6.523 -0.180 20.967 1.00 44.48 C \r
-ATOM 3504 CA ARG C 71 9.185 2.353 19.993 1.00 40.96 C \r
-ATOM 3515 CA GLU C 72 8.727 5.317 17.688 1.00 33.49 C \r
-ATOM 3524 CA GLY C 73 8.913 3.876 14.164 1.00 30.16 C \r
-ATOM 3528 CA GLN C 74 7.423 0.399 14.427 1.00 31.26 C \r
-ATOM 3537 CA SER C 75 4.187 -0.913 12.966 1.00 33.65 C \r
-ATOM 3543 CA ILE C 76 1.454 -3.212 14.278 1.00 33.75 C \r
-ATOM 3551 CA GLY C 77 -0.295 -5.923 12.356 1.00 34.32 C \r
-ATOM 3555 CA VAL C 78 -4.060 -6.111 12.164 1.00 36.67 C \r
-ATOM 3562 CA ILE C 79 -6.137 -9.230 11.507 1.00 41.91 C \r
-ATOM 3570 CA ALA C 80 -9.427 -8.086 10.024 1.00 44.06 C \r
-ATOM 3575 CA ASP C 81 -12.530 -9.927 11.224 1.00 47.03 C \r
-ATOM 3583 CA GLY C 82 -13.972 -12.487 8.829 1.00 53.52 C \r
-ATOM 3587 CA VAL C 83 -12.521 -14.951 6.324 1.00 62.57 C \r
-ATOM 3594 CA ASP C 84 -11.856 -14.200 2.630 1.00 71.97 C \r
-ATOM 3602 CA LYS C 85 -12.935 -17.403 0.861 1.00 76.86 C \r
-ATOM 3611 CA ASN C 86 -13.690 -18.960 4.253 1.00 76.52 C \r
-ATOM 3619 CA GLY C 87 -10.006 -19.837 4.066 1.00 76.22 C \r
-ATOM 3623 CA LYS C 88 -8.802 -19.138 7.616 1.00 71.60 C \r
-ATOM 3632 CA PRO C 89 -8.651 -15.577 8.944 1.00 64.14 C \r
-ATOM 3639 CA HIS C 90 -7.547 -12.649 6.805 1.00 52.35 C \r
-ATOM 3649 CA LYS C 91 -3.753 -12.529 6.474 1.00 46.81 C \r
-ATOM 3658 CA VAL C 92 -2.180 -9.868 8.686 1.00 43.48 C \r
-ATOM 3665 CA ARG C 93 -1.491 -6.414 7.232 1.00 36.99 C \r
-ATOM 3676 CA LEU C 94 0.983 -3.882 8.601 1.00 32.95 C \r
-ATOM 3684 CA TYR C 95 0.340 -0.239 9.510 1.00 24.84 C \r
-ATOM 3696 CA SER C 96 3.003 2.101 10.803 1.00 23.32 C \r
-ATOM 3702 CA ILE C 97 2.244 3.502 14.236 1.00 24.12 C \r
-ATOM 3710 CA ALA C 98 1.243 7.179 13.932 1.00 22.32 C \r
-ATOM 3715 CA SER C 99 1.572 7.636 17.676 1.00 25.69 C \r
-ATOM 3721 CA SER C 100 4.752 7.924 19.726 1.00 28.83 C \r
-ATOM 3727 CA ALA C 101 5.741 5.521 22.508 1.00 35.61 C \r
-ATOM 3732 CA ILE C 102 3.906 7.635 25.079 1.00 38.39 C \r
-ATOM 3740 CA GLY C 103 0.899 7.826 22.742 1.00 31.93 C \r
-ATOM 3744 CA ASP C 104 -1.803 10.384 21.986 1.00 28.77 C \r
-ATOM 3752 CA PHE C 105 -3.050 10.293 25.607 1.00 37.05 C \r
-ATOM 3763 CA GLY C 106 0.503 10.389 26.967 1.00 39.36 C \r
-ATOM 3767 CA ASP C 107 -0.221 7.437 29.266 1.00 41.44 C \r
-ATOM 3775 CA SER C 108 1.566 4.766 27.217 1.00 42.18 C \r
-ATOM 3781 CA LYS C 109 -1.747 2.877 27.156 1.00 42.45 C \r
-ATOM 3790 CA THR C 110 -2.698 3.586 23.515 1.00 38.10 C \r
-ATOM 3797 CA VAL C 111 -1.603 2.971 19.906 1.00 32.79 C \r
-ATOM 3804 CA SER C 112 -2.671 5.020 16.872 1.00 29.60 C \r
-ATOM 3810 CA LEU C 113 -2.713 4.324 13.126 1.00 25.68 C \r
-ATOM 3818 CA CYS C 114 -3.142 6.498 9.999 1.00 24.23 C \r
-ATOM 3824 CA VAL C 115 -5.345 4.496 7.641 1.00 22.80 C \r
-ATOM 3831 CA LYS C 116 -6.221 5.196 4.015 1.00 22.11 C \r
-ATOM 3840 CA ARG C 117 -9.458 3.521 2.955 1.00 25.68 C \r
-ATOM 3851 CA LEU C 118 -8.447 1.440 -0.100 1.00 28.80 C \r
-ATOM 3859 CA ILE C 119 -11.140 1.661 -2.792 1.00 31.75 C \r
-ATOM 3867 CA TYR C 120 -10.086 0.716 -6.312 1.00 32.93 C \r
-ATOM 3879 CA THR C 121 -11.388 -0.733 -9.598 1.00 36.84 C \r
-ATOM 3886 CA ASN C 122 -10.258 -4.257 -10.546 1.00 36.90 C \r
-ATOM 3894 CA ASP C 123 -9.574 -5.562 -14.056 1.00 45.45 C \r
-ATOM 3902 CA ALA C 124 -13.196 -6.758 -14.269 1.00 44.66 C \r
-ATOM 3907 CA GLY C 125 -14.207 -3.102 -14.023 1.00 45.49 C \r
-ATOM 3911 CA GLU C 126 -16.059 -3.511 -10.722 1.00 45.54 C \r
-ATOM 3920 CA ILE C 127 -15.507 -1.321 -7.638 1.00 39.70 C \r
-ATOM 3928 CA VAL C 128 -13.846 -3.171 -4.762 1.00 38.09 C \r
-ATOM 3935 CA LYS C 129 -12.759 -2.512 -1.198 1.00 33.77 C \r
-ATOM 3944 CA GLY C 130 -9.566 -3.363 0.599 1.00 31.98 C \r
-ATOM 3948 CA VAL C 131 -10.443 -5.797 3.385 1.00 33.16 C \r
-ATOM 3955 CA CYS C 132 -8.241 -4.645 6.257 1.00 29.97 C \r
-ATOM 3961 CA SER C 133 -8.238 -0.898 5.607 1.00 30.67 C \r
-ATOM 3967 CA ASN C 134 -12.022 -0.902 5.268 1.00 30.35 C \r
-ATOM 3975 CA PHE C 135 -12.375 -2.946 8.424 1.00 29.86 C \r
-ATOM 3986 CA LEU C 136 -10.223 -0.334 10.195 1.00 29.42 C \r
-ATOM 3994 CA CYS C 137 -11.779 2.834 8.813 1.00 32.27 C \r
-ATOM 4000 CA ASP C 138 -15.116 1.280 9.724 1.00 34.29 C \r
-ATOM 4008 CA LEU C 139 -14.287 0.699 13.399 1.00 37.51 C \r
-ATOM 4016 CA GLN C 140 -16.635 2.170 16.028 1.00 43.76 C \r
-ATOM 4025 CA PRO C 141 -15.630 3.032 19.581 1.00 42.77 C \r
-ATOM 4032 CA GLY C 142 -16.082 -0.210 21.478 1.00 42.83 C \r
-ATOM 4036 CA ASP C 143 -15.117 -2.625 18.696 1.00 40.91 C \r
-ATOM 4044 CA ASN C 144 -12.182 -4.947 19.288 1.00 45.66 C \r
-ATOM 4052 CA VAL C 145 -9.056 -5.146 17.145 1.00 46.95 C \r
-ATOM 4059 CA GLN C 146 -6.707 -8.107 16.606 1.00 48.69 C \r
-ATOM 4068 CA ILE C 147 -3.249 -6.538 17.123 1.00 46.84 C \r
-ATOM 4076 CA THR C 148 -0.010 -8.392 16.264 1.00 46.26 C \r
-ATOM 4083 CA GLY C 149 3.543 -7.117 16.634 1.00 45.60 C \r
-ATOM 4087 CA PRO C 150 5.248 -4.818 17.394 1.00 44.97 C \r
-ATOM 4094 CA VAL C 151 7.423 -5.293 14.321 1.00 44.50 C \r
-ATOM 4101 CA GLY C 152 10.289 -3.716 12.438 1.00 45.33 C \r
-ATOM 4105 CA LYS C 153 13.599 -2.161 13.435 1.00 48.64 C \r
-ATOM 4114 CA GLU C 154 14.166 -0.437 10.074 1.00 48.20 C \r
-ATOM 4123 CA MET C 155 12.437 2.888 10.737 1.00 41.77 C \r
-ATOM 4131 CA LEU C 156 13.839 3.081 14.267 1.00 38.27 C \r
-ATOM 4139 CA MET C 157 15.076 6.540 15.308 1.00 34.29 C \r
-ATOM 4147 CA PRO C 158 18.782 7.419 15.339 1.00 34.05 C \r
-ATOM 4154 CA LYS C 159 20.262 7.521 18.845 1.00 35.82 C \r
-ATOM 4163 CA ASP C 160 22.076 10.792 18.273 1.00 35.95 C \r
-ATOM 4171 CA PRO C 161 19.683 13.401 19.809 1.00 35.63 C \r
-ATOM 4178 CA ASN C 162 21.563 15.948 17.758 1.00 33.92 C \r
-ATOM 4186 CA ALA C 163 21.028 14.172 14.487 1.00 30.82 C \r
-ATOM 4191 CA THR C 164 19.693 15.722 11.305 1.00 25.18 C \r
-ATOM 4198 CA ILE C 165 16.617 13.601 10.636 1.00 19.91 C \r
-ATOM 4206 CA ILE C 166 15.351 13.978 7.060 1.00 13.76 C \r
-ATOM 4214 CA MET C 167 11.843 12.550 6.703 1.00 14.98 C \r
-ATOM 4222 CA LEU C 168 10.385 11.831 3.251 1.00 16.64 C \r
-ATOM 4230 CA ALA C 169 6.747 10.808 3.007 1.00 15.85 C \r
-ATOM 4235 CA THR C 170 3.765 10.346 0.737 1.00 14.23 C \r
-ATOM 4242 CA GLY C 171 0.255 9.724 2.035 1.00 13.78 C \r
-ATOM 4246 CA THR C 172 -0.103 7.560 5.139 1.00 17.62 C \r
-ATOM 4253 CA GLY C 173 3.646 7.343 4.821 1.00 17.20 C \r
-ATOM 4257 CA ILE C 174 3.469 10.213 7.270 1.00 15.91 C \r
-ATOM 4265 CA ALA C 175 2.586 7.783 10.110 1.00 15.63 C \r
-ATOM 4270 CA PRO C 176 6.023 6.933 11.582 1.00 17.04 C \r
-ATOM 4277 CA PHE C 177 7.215 10.514 11.327 1.00 18.21 C \r
-ATOM 4288 CA ARG C 178 4.268 11.745 13.359 1.00 22.35 C \r
-ATOM 4299 CA SER C 179 5.563 9.289 15.983 1.00 25.22 C \r
-ATOM 4305 CA PHE C 180 9.139 10.593 15.614 1.00 25.98 C \r
-ATOM 4316 CA LEU C 181 7.925 14.180 15.767 1.00 29.12 C \r
-ATOM 4324 CA TRP C 182 5.625 13.641 18.714 1.00 31.35 C \r
-ATOM 4338 CA LYS C 183 8.488 12.385 20.871 1.00 30.92 C \r
-ATOM 4347 CA MET C 184 10.841 15.050 19.503 1.00 24.85 C \r
-ATOM 4355 CA PHE C 185 8.741 18.202 20.114 1.00 22.97 C \r
-ATOM 4366 CA PHE C 186 5.604 17.337 22.076 1.00 27.77 C \r
-ATOM 4377 CA GLU C 187 7.117 15.432 25.009 1.00 37.71 C \r
-ATOM 4386 CA LYS C 188 9.542 15.977 27.878 1.00 53.59 C \r
-ATOM 4395 CA HIS C 189 12.355 13.416 28.180 1.00 63.67 C \r
-ATOM 4405 CA ASP C 190 15.318 13.181 30.569 1.00 66.93 C \r
-ATOM 4413 CA ASP C 191 17.480 11.106 28.238 1.00 59.79 C \r
-ATOM 4421 CA TYR C 192 16.190 12.725 25.047 1.00 51.96 C \r
-ATOM 4433 CA LYS C 193 16.700 16.406 24.324 1.00 47.01 C \r
-ATOM 4442 CA PHE C 194 16.580 16.471 20.530 1.00 39.85 C \r
-ATOM 4453 CA ASN C 195 18.572 19.494 19.409 1.00 37.52 C \r
-ATOM 4461 CA GLY C 196 19.361 18.548 15.845 1.00 32.08 C \r
-ATOM 4465 CA LEU C 197 17.310 19.266 12.766 1.00 28.26 C \r
-ATOM 4473 CA GLY C 198 14.051 17.526 11.928 1.00 25.05 C \r
-ATOM 4477 CA TRP C 199 13.211 18.137 8.269 1.00 19.81 C \r
-ATOM 4491 CA LEU C 200 9.908 16.742 7.059 1.00 13.86 C \r
-ATOM 4499 CA PHE C 201 8.855 16.521 3.429 1.00 14.83 C \r
-ATOM 4510 CA LEU C 202 5.288 15.361 2.717 1.00 16.12 C \r
-ATOM 4518 CA GLY C 203 3.701 14.731 -0.681 1.00 13.79 C \r
-ATOM 4522 CA VAL C 204 -0.051 14.414 -1.182 1.00 11.75 C \r
-ATOM 4529 CA PRO C 205 -2.113 15.264 -4.308 1.00 14.66 C \r
-ATOM 4536 CA THR C 206 -4.553 17.737 -2.778 1.00 16.37 C \r
-ATOM 4543 CA SER C 207 -4.756 20.169 0.120 1.00 18.01 C \r
-ATOM 4549 CA SER C 208 -7.780 18.225 1.280 1.00 17.59 C \r
-ATOM 4555 CA SER C 209 -5.452 15.198 1.550 1.00 16.19 C \r
-ATOM 4561 CA LEU C 210 -2.972 16.940 3.860 1.00 14.22 C \r
-ATOM 4569 CA LEU C 211 -2.255 14.980 7.059 1.00 14.43 C \r
-ATOM 4577 CA TYR C 212 -1.624 16.449 10.549 1.00 18.94 C \r
-ATOM 4589 CA LYS C 213 -0.818 19.896 9.150 1.00 22.61 C \r
-ATOM 4598 CA GLU C 214 -2.039 21.572 12.352 1.00 25.73 C \r
-ATOM 4607 CA GLU C 215 0.152 19.413 14.514 1.00 19.23 C \r
-ATOM 4616 CA PHE C 216 3.216 20.178 12.439 1.00 17.80 C \r
-ATOM 4627 CA GLY C 217 2.478 23.890 12.512 1.00 19.90 C \r
-ATOM 4631 CA LYS C 218 2.578 24.001 16.294 1.00 25.54 C \r
-ATOM 4640 CA MET C 219 5.810 22.021 16.188 1.00 26.79 C \r
-ATOM 4648 CA LYS C 220 7.224 24.606 13.819 1.00 31.85 C \r
-ATOM 4657 CA GLU C 221 6.071 27.341 16.219 1.00 38.62 C \r
-ATOM 4666 CA ARG C 222 7.760 25.760 19.233 1.00 39.10 C \r
-ATOM 4677 CA ALA C 223 11.124 24.971 17.668 1.00 35.43 C \r
-ATOM 4682 CA PRO C 224 11.696 27.100 14.528 1.00 32.99 C \r
-ATOM 4689 CA GLU C 225 15.425 26.331 14.360 1.00 33.87 C \r
-ATOM 4698 CA ASN C 226 15.038 22.591 14.986 1.00 30.46 C \r
-ATOM 4706 CA PHE C 227 12.088 21.755 12.732 1.00 24.98 C \r
-ATOM 4717 CA ARG C 228 11.351 22.384 9.075 1.00 19.87 C \r
-ATOM 4728 CA VAL C 229 8.435 21.010 7.118 1.00 14.21 C \r
-ATOM 4735 CA ASP C 230 7.739 21.452 3.398 1.00 12.26 C \r
-ATOM 4743 CA TYR C 231 4.627 20.147 1.722 1.00 14.42 C \r
-ATOM 4755 CA ALA C 232 4.334 19.003 -1.872 1.00 9.99 C \r
-ATOM 4760 CA VAL C 233 0.778 19.232 -3.168 1.00 10.49 C \r
-ATOM 4767 CA SER C 234 1.043 17.769 -6.694 1.00 19.00 C \r
-ATOM 4773 CA ARG C 235 -2.240 19.042 -8.206 1.00 23.13 C \r
-ATOM 4784 CA GLU C 236 -2.069 22.459 -6.578 1.00 17.58 C \r
-ATOM 4793 CA GLN C 237 1.546 23.511 -6.623 1.00 15.89 C \r
-ATOM 4802 CA THR C 238 4.202 24.018 -9.275 1.00 17.86 C \r
-ATOM 4809 CA ASN C 239 7.922 24.800 -9.182 1.00 15.15 C \r
-ATOM 4817 CA ALA C 240 9.558 27.791 -10.892 1.00 21.51 C \r
-ATOM 4822 CA ALA C 241 9.475 25.887 -14.174 1.00 24.05 C \r
-ATOM 4827 CA GLY C 242 5.741 25.110 -13.938 1.00 26.25 C \r
-ATOM 4831 CA GLU C 243 5.999 21.359 -13.153 1.00 25.92 C \r
-ATOM 4840 CA ARG C 244 3.679 19.536 -10.704 1.00 24.04 C \r
-ATOM 4851 CA MET C 245 5.076 19.643 -7.174 1.00 18.58 C \r
-ATOM 4859 CA TYR C 246 5.784 16.047 -6.100 1.00 14.16 C \r
-ATOM 4871 CA ILE C 247 7.910 15.343 -3.034 1.00 16.78 C \r
-ATOM 4879 CA GLN C 248 11.089 15.070 -5.120 1.00 18.72 C \r
-ATOM 4888 CA THR C 249 10.168 18.255 -6.921 1.00 20.93 C \r
-ATOM 4895 CA ARG C 250 9.962 20.031 -3.567 1.00 19.25 C \r
-ATOM 4906 CA MET C 251 13.275 18.471 -2.561 1.00 19.40 C \r
-ATOM 4914 CA ALA C 252 14.910 19.812 -5.760 1.00 20.48 C \r
-ATOM 4919 CA GLU C 253 14.456 23.418 -4.569 1.00 18.19 C \r
-ATOM 4928 CA TYR C 254 16.804 22.515 -1.673 1.00 17.80 C \r
-ATOM 4940 CA LYS C 255 19.038 20.415 -3.902 1.00 20.66 C \r
-ATOM 4949 CA GLU C 256 22.452 21.603 -2.682 1.00 16.05 C \r
-ATOM 4958 CA GLU C 257 21.544 21.914 0.993 1.00 15.89 C \r
-ATOM 4967 CA LEU C 258 20.377 18.297 0.919 1.00 20.74 C \r
-ATOM 4975 CA TRP C 259 23.388 16.939 -0.965 1.00 23.45 C \r
-ATOM 4989 CA GLU C 260 25.645 18.669 1.563 1.00 24.08 C \r
-ATOM 4998 CA LEU C 261 23.573 17.378 4.477 1.00 24.74 C \r
-ATOM 5006 CA LEU C 262 24.020 13.928 2.938 1.00 26.14 C \r
-ATOM 5014 CA LYS C 263 27.792 14.091 3.402 1.00 25.40 C \r
-ATOM 5023 CA LYS C 264 27.457 14.521 7.176 1.00 31.47 C \r
-ATOM 5032 CA ASP C 265 27.877 11.474 9.425 1.00 35.31 C \r
-ATOM 5040 CA ASN C 266 24.934 12.482 11.620 1.00 29.63 C \r
-ATOM 5048 CA THR C 267 22.321 12.795 8.832 1.00 28.00 C \r
-ATOM 5055 CA TYR C 268 19.556 10.160 8.808 1.00 27.00 C \r
-ATOM 5067 CA VAL C 269 17.143 9.903 5.884 1.00 24.65 C \r
-ATOM 5074 CA TYR C 270 13.890 8.016 6.276 1.00 23.37 C \r
-ATOM 5086 CA MET C 271 11.373 7.327 3.518 1.00 18.93 C \r
-ATOM 5094 CA CYS C 272 7.834 6.074 4.043 1.00 18.24 C \r
-ATOM 5100 CA GLY C 273 4.784 5.874 1.826 1.00 22.39 C \r
-ATOM 5104 CA LEU C 274 3.837 4.483 -1.568 1.00 26.95 C \r
-ATOM 5112 CA LYS C 275 6.305 2.384 -3.532 1.00 32.36 C \r
-ATOM 5121 CA GLY C 276 7.741 4.199 -6.514 1.00 37.46 C \r
-ATOM 5125 CA MET C 277 7.714 7.455 -4.608 1.00 28.76 C \r
-ATOM 5133 CA GLU C 278 11.430 6.639 -4.425 1.00 32.22 C \r
-ATOM 5142 CA LYS C 279 12.017 6.321 -8.153 1.00 29.94 C \r
-ATOM 5151 CA GLY C 280 11.317 10.057 -8.293 1.00 24.18 C \r
-ATOM 5155 CA ILE C 281 13.766 10.673 -5.460 1.00 23.68 C \r
-ATOM 5163 CA ASP C 282 16.431 8.365 -6.934 1.00 26.58 C \r
-ATOM 5171 CA ASP C 283 16.211 10.530 -10.054 1.00 28.70 C \r
-ATOM 5179 CA ILE C 284 17.089 13.937 -8.538 1.00 27.28 C \r
-ATOM 5187 CA MET C 285 19.706 12.222 -6.388 1.00 27.45 C \r
-ATOM 5195 CA VAL C 286 21.377 10.712 -9.470 1.00 30.74 C \r
-ATOM 5202 CA SER C 287 21.619 14.159 -11.061 1.00 32.14 C \r
-ATOM 5208 CA LEU C 288 23.240 15.463 -7.873 1.00 34.20 C \r
-ATOM 5216 CA ALA C 289 25.801 12.653 -7.874 1.00 40.16 C \r
-ATOM 5221 CA GLU C 290 26.837 12.825 -11.536 1.00 41.84 C \r
-ATOM 5230 CA LYS C 291 27.855 16.387 -10.793 1.00 43.17 C \r
-ATOM 5239 CA ASP C 292 30.299 15.115 -8.139 1.00 41.84 C \r
-ATOM 5247 CA GLY C 293 31.237 12.232 -10.420 1.00 46.12 C \r
-ATOM 5251 CA ILE C 294 30.053 9.669 -7.864 1.00 45.54 C \r
-ATOM 5259 CA ASP C 295 27.399 6.998 -8.480 1.00 41.14 C \r
-ATOM 5267 CA TRP C 296 24.222 7.605 -6.479 1.00 30.67 C \r
-ATOM 5281 CA PHE C 297 23.381 3.910 -6.151 1.00 31.97 C \r
-ATOM 5292 CA ASP C 298 26.856 2.916 -4.907 1.00 38.12 C \r
-ATOM 5300 CA TYR C 299 26.671 5.875 -2.540 1.00 39.05 C \r
-ATOM 5312 CA LYS C 300 23.196 4.971 -1.294 1.00 41.63 C \r
-ATOM 5321 CA LYS C 301 24.542 1.489 -0.577 1.00 43.40 C \r
-ATOM 5330 CA GLN C 302 27.207 3.064 1.608 1.00 43.79 C \r
-ATOM 5339 CA LEU C 303 24.476 5.181 3.238 1.00 41.51 C \r
-ATOM 5347 CA LYS C 304 22.138 2.343 4.264 1.00 45.18 C \r
-ATOM 5356 CA ARG C 305 25.322 0.535 5.256 1.00 46.65 C \r
-ATOM 5367 CA GLY C 306 25.613 3.181 7.945 1.00 40.29 C \r
-ATOM 5371 CA ASP C 307 21.954 3.487 8.940 1.00 41.21 C \r
-ATOM 5379 CA GLN C 308 21.463 6.730 7.023 1.00 35.55 C \r
-ATOM 5388 CA TRP C 309 18.961 5.674 4.361 1.00 31.22 C \r
-ATOM 5402 CA ASN C 310 16.018 3.728 5.752 1.00 31.61 C \r
-ATOM 5410 CA VAL C 311 13.120 2.841 3.452 1.00 32.13 C \r
-ATOM 5417 CA GLU C 312 9.705 1.332 4.261 1.00 31.51 C \r
-ATOM 5426 CA VAL C 313 7.466 1.606 1.209 1.00 26.39 C \r
-ATOM 5433 CA TYR C 314 4.403 -0.343 0.111 1.00 25.42 C \r
+HEADER OXIDOREDUCTASE/ELECTRON TRANSPORT 08-MAY-00 1GAQ
+ATOM 2 CA GLU A 19 20.491 30.713 36.290 1.00 74.29 C
+ATOM 11 CA SER A 20 24.056 29.774 37.264 1.00 72.09 C
+ATOM 17 CA LYS A 21 27.517 31.289 37.563 1.00 70.09 C
+ATOM 26 CA LYS A 22 28.794 27.865 36.481 1.00 68.64 C
+ATOM 35 CA GLN A 23 29.484 26.806 32.884 1.00 70.46 C
+ATOM 44 CA GLU A 24 26.420 25.175 31.360 1.00 72.08 C
+ATOM 53 CA GLU A 25 26.736 26.049 27.683 1.00 70.43 C
+ATOM 62 CA GLY A 26 28.299 22.912 26.233 1.00 63.14 C
+ATOM 66 CA VAL A 27 26.863 20.704 28.982 1.00 54.50 C
+ATOM 73 CA VAL A 28 25.030 17.390 28.655 1.00 48.32 C
+ATOM 80 CA THR A 29 23.728 14.677 30.991 1.00 44.86 C
+ATOM 87 CA ASN A 30 22.327 11.164 30.703 1.00 45.42 C
+ATOM 95 CA LEU A 31 23.332 10.459 27.102 1.00 45.42 C
+ATOM 103 CA TYR A 32 23.549 6.898 28.380 1.00 45.88 C
+ATOM 115 CA LYS A 33 21.656 5.321 31.262 1.00 47.27 C
+ATOM 124 CA PRO A 34 21.991 2.046 33.248 1.00 48.99 C
+ATOM 131 CA LYS A 35 19.339 0.560 30.970 1.00 52.75 C
+ATOM 140 CA GLU A 36 21.580 0.855 27.886 1.00 53.33 C
+ATOM 149 CA PRO A 37 25.154 2.015 28.678 1.00 47.54 C
+ATOM 156 CA TYR A 38 27.929 2.872 26.249 1.00 41.98 C
+ATOM 168 CA VAL A 39 30.355 -0.017 25.909 1.00 41.48 C
+ATOM 175 CA GLY A 40 33.823 1.485 25.966 1.00 37.59 C
+ATOM 179 CA ARG A 41 37.165 -0.277 26.122 1.00 39.77 C
+ATOM 190 CA CYS A 42 40.148 -0.029 28.442 1.00 36.51 C
+ATOM 196 CA LEU A 43 43.095 1.441 26.554 1.00 36.13 C
+ATOM 204 CA LEU A 44 45.231 2.023 29.649 1.00 33.55 C
+ATOM 212 CA ASN A 45 45.140 1.026 33.307 1.00 27.79 C
+ATOM 220 CA THR A 46 48.056 1.800 35.617 1.00 28.75 C
+ATOM 227 CA LYS A 47 48.542 1.776 39.388 1.00 30.31 C
+ATOM 236 CA ILE A 48 49.564 5.317 40.376 1.00 31.32 C
+ATOM 244 CA THR A 49 50.339 4.682 44.059 1.00 37.62 C
+ATOM 251 CA GLY A 50 53.585 3.317 45.460 1.00 44.49 C
+ATOM 255 CA ASP A 51 53.706 -0.448 46.087 1.00 52.89 C
+ATOM 263 CA ASP A 52 53.910 0.545 49.751 1.00 55.23 C
+ATOM 271 CA ALA A 53 50.816 2.767 50.056 1.00 53.34 C
+ATOM 276 CA PRO A 54 47.904 1.940 52.405 1.00 50.60 C
+ATOM 283 CA GLY A 55 45.420 1.579 49.561 1.00 50.35 C
+ATOM 287 CA GLU A 56 46.098 1.286 45.836 1.00 42.53 C
+ATOM 296 CA THR A 57 44.534 3.816 43.480 1.00 41.14 C
+ATOM 303 CA TRP A 58 44.540 3.423 39.708 1.00 35.60 C
+ATOM 317 CA HIS A 59 44.468 5.853 36.796 1.00 31.89 C
+ATOM 327 CA MET A 60 42.658 4.227 33.866 1.00 31.65 C
+ATOM 335 CA VAL A 61 41.716 5.345 30.350 1.00 30.43 C
+ATOM 342 CA PHE A 62 38.669 4.172 28.360 1.00 34.36 C
+ATOM 353 CA SER A 63 37.657 4.908 24.772 1.00 34.69 C
+ATOM 359 CA THR A 64 34.448 6.828 23.951 1.00 36.96 C
+ATOM 366 CA GLU A 65 34.691 7.644 20.254 1.00 40.08 C
+ATOM 375 CA GLY A 66 33.742 11.183 21.285 1.00 40.22 C
+ATOM 379 CA LYS A 67 30.272 9.763 22.003 1.00 41.93 C
+ATOM 388 CA ILE A 68 30.279 11.116 25.577 1.00 41.52 C
+ATOM 396 CA PRO A 69 30.791 14.926 25.537 1.00 42.35 C
+ATOM 403 CA TYR A 70 31.228 15.232 29.299 1.00 39.84 C
+ATOM 415 CA ARG A 71 32.639 18.451 30.768 1.00 44.14 C
+ATOM 426 CA GLU A 72 35.122 19.278 33.515 1.00 43.82 C
+ATOM 435 CA GLY A 73 33.472 18.458 36.835 1.00 41.97 C
+ATOM 439 CA GLN A 74 30.929 15.874 35.657 1.00 37.19 C
+ATOM 448 CA SER A 75 31.285 12.124 36.138 1.00 38.28 C
+ATOM 454 CA ILE A 76 30.458 8.792 34.539 1.00 36.84 C
+ATOM 462 CA GLY A 77 28.983 5.620 35.918 1.00 35.39 C
+ATOM 466 CA VAL A 78 30.311 2.108 35.530 1.00 32.05 C
+ATOM 473 CA ILE A 79 28.458 -1.201 35.591 1.00 32.67 C
+ATOM 481 CA ALA A 80 30.745 -4.018 36.644 1.00 35.36 C
+ATOM 486 CA ASP A 81 30.359 -7.373 34.872 1.00 38.72 C
+ATOM 494 CA GLY A 82 28.308 -10.332 36.110 1.00 45.79 C
+ATOM 498 CA VAL A 83 25.820 -10.242 39.001 1.00 52.24 C
+ATOM 505 CA ASP A 84 25.838 -10.250 42.834 1.00 60.54 C
+ATOM 513 CA LYS A 85 25.014 -13.158 45.196 1.00 66.72 C
+ATOM 522 CA ASN A 86 21.414 -13.062 43.904 1.00 67.37 C
+ATOM 530 CA GLY A 87 21.724 -13.423 40.136 1.00 64.74 C
+ATOM 534 CA LYS A 88 20.971 -9.733 39.570 1.00 61.12 C
+ATOM 543 CA PRO A 89 23.054 -7.201 37.561 1.00 54.68 C
+ATOM 550 CA HIS A 90 25.224 -4.957 39.755 1.00 44.44 C
+ATOM 560 CA LYS A 91 23.940 -1.433 40.260 1.00 40.48 C
+ATOM 569 CA VAL A 92 25.803 1.546 38.843 1.00 38.45 C
+ATOM 576 CA ARG A 93 28.709 2.986 40.828 1.00 38.93 C
+ATOM 587 CA LEU A 94 29.778 6.584 40.096 1.00 34.37 C
+ATOM 595 CA TYR A 95 33.309 7.878 39.513 1.00 30.27 C
+ATOM 607 CA SER A 96 34.425 11.475 39.057 1.00 29.44 C
+ATOM 613 CA ILE A 97 36.029 12.090 35.662 1.00 27.61 C
+ATOM 621 CA ALA A 98 39.769 12.693 36.069 1.00 31.12 C
+ATOM 626 CA SER A 99 40.393 13.712 32.475 1.00 32.42 C
+ATOM 632 CA SER A 100 39.566 17.142 31.059 1.00 36.14 C
+ATOM 638 CA ALA A 101 37.097 17.367 28.154 1.00 41.07 C
+ATOM 643 CA ILE A 102 39.764 16.549 25.527 1.00 47.65 C
+ATOM 651 CA GLY A 103 41.172 13.692 27.599 1.00 46.77 C
+ATOM 655 CA ASP A 104 44.730 12.612 28.289 1.00 43.82 C
+ATOM 663 CA PHE A 105 45.115 12.065 24.522 1.00 41.52 C
+ATOM 674 CA GLY A 106 43.862 15.455 23.328 1.00 41.66 C
+ATOM 678 CA ASP A 107 41.355 13.883 20.926 1.00 40.90 C
+ATOM 686 CA SER A 108 38.132 14.250 22.954 1.00 42.95 C
+ATOM 692 CA LYS A 109 37.967 10.535 22.224 1.00 44.74 C
+ATOM 701 CA THR A 110 38.731 9.184 25.704 1.00 41.09 C
+ATOM 708 CA VAL A 111 37.728 9.519 29.374 1.00 39.03 C
+ATOM 715 CA SER A 112 39.912 8.705 32.399 1.00 37.17 C
+ATOM 721 CA LEU A 113 39.098 7.476 35.935 1.00 32.10 C
+ATOM 729 CA CYS A 114 40.964 7.578 39.261 1.00 30.65 C
+ATOM 735 CA VAL A 115 39.724 4.459 41.060 1.00 33.45 C
+ATOM 742 CA LYS A 116 40.668 3.524 44.628 1.00 34.75 C
+ATOM 751 CA ARG A 117 40.376 -0.250 45.123 1.00 32.85 C
+ATOM 762 CA LEU A 118 38.137 -1.094 48.077 1.00 30.50 C
+ATOM 770 CA ILE A 119 39.376 -3.752 50.459 1.00 34.34 C
+ATOM 778 CA TYR A 120 38.699 -4.266 54.125 1.00 31.39 C
+ATOM 790 CA THR A 121 38.264 -7.086 56.567 1.00 28.83 C
+ATOM 797 CA ASN A 122 34.792 -7.477 58.109 1.00 26.51 C
+ATOM 805 CA ASP A 123 33.626 -8.382 61.634 1.00 31.58 C
+ATOM 813 CA ALA A 124 34.191 -12.077 60.901 1.00 27.84 C
+ATOM 818 CA GLY A 125 37.759 -11.844 59.728 1.00 32.39 C
+ATOM 822 CA GLU A 126 36.809 -12.146 56.073 1.00 35.82 C
+ATOM 831 CA ILE A 127 38.655 -9.932 53.598 1.00 38.42 C
+ATOM 839 CA VAL A 128 36.025 -8.261 51.421 1.00 33.73 C
+ATOM 846 CA LYS A 129 36.482 -6.484 48.090 1.00 31.87 C
+ATOM 855 CA GLY A 130 34.363 -3.680 46.686 1.00 26.91 C
+ATOM 859 CA VAL A 131 32.680 -5.051 43.569 1.00 27.89 C
+ATOM 866 CA CYS A 132 33.074 -2.246 41.018 1.00 28.46 C
+ATOM 872 CA SER A 133 36.266 -0.553 42.213 1.00 31.33 C
+ATOM 878 CA ASN A 134 37.861 -3.983 41.984 1.00 30.29 C
+ATOM 886 CA PHE A 135 36.318 -4.795 38.623 1.00 31.48 C
+ATOM 897 CA LEU A 136 37.926 -1.553 37.520 1.00 27.81 C
+ATOM 905 CA CYS A 137 41.417 -1.976 38.955 1.00 25.91 C
+ATOM 911 CA ASP A 138 41.605 -5.419 37.338 1.00 30.22 C
+ATOM 919 CA LEU A 139 40.462 -4.306 33.874 1.00 32.69 C
+ATOM 927 CA GLN A 140 42.851 -5.511 31.186 1.00 36.80 C
+ATOM 936 CA PRO A 141 43.380 -3.220 28.170 1.00 36.16 C
+ATOM 943 CA GLY A 142 40.864 -4.420 25.586 1.00 31.10 C
+ATOM 947 CA ASP A 143 38.129 -5.298 28.055 1.00 30.62 C
+ATOM 955 CA ASN A 144 34.690 -3.847 27.645 1.00 33.52 C
+ATOM 963 CA VAL A 145 33.430 -1.522 30.361 1.00 37.08 C
+ATOM 970 CA GLN A 146 29.817 -0.374 30.523 1.00 37.65 C
+ATOM 979 CA ILE A 147 29.547 3.413 31.045 1.00 30.95 C
+ATOM 987 CA THR A 148 26.637 5.791 31.832 1.00 29.95 C
+ATOM 994 CA GLY A 149 26.297 9.581 31.843 1.00 32.81 C
+ATOM 998 CA PRO A 150 27.785 12.148 31.800 1.00 34.98 C
+ATOM 1005 CA VAL A 151 26.376 12.668 35.275 1.00 36.53 C
+ATOM 1012 CA GLY A 152 26.196 15.756 37.474 1.00 43.09 C
+ATOM 1016 CA LYS A 153 26.048 19.528 37.068 1.00 48.37 C
+ATOM 1025 CA GLU A 154 26.921 20.540 40.633 1.00 49.70 C
+ATOM 1034 CA MET A 155 30.710 20.266 40.235 1.00 47.30 C
+ATOM 1042 CA LEU A 156 30.882 22.020 36.869 1.00 50.36 C
+ATOM 1050 CA MET A 157 33.362 24.883 36.404 1.00 55.29 C
+ATOM 1058 CA PRO A 158 32.521 28.612 36.605 1.00 54.88 C
+ATOM 1065 CA LYS A 159 32.291 30.776 33.464 1.00 54.92 C
+ATOM 1074 CA ASP A 160 34.497 33.503 34.939 1.00 57.22 C
+ATOM 1082 CA PRO A 161 38.055 32.687 33.759 1.00 58.62 C
+ATOM 1089 CA ASN A 162 39.524 35.240 36.163 1.00 60.44 C
+ATOM 1097 CA ALA A 163 37.814 33.910 39.279 1.00 55.80 C
+ATOM 1102 CA THR A 164 39.596 32.487 42.316 1.00 51.04 C
+ATOM 1109 CA ILE A 165 38.966 28.771 42.756 1.00 50.26 C
+ATOM 1117 CA ILE A 166 39.774 26.773 45.885 1.00 47.54 C
+ATOM 1125 CA MET A 167 39.883 23.014 45.324 1.00 46.38 C
+ATOM 1133 CA LEU A 168 39.700 20.963 48.522 1.00 42.18 C
+ATOM 1141 CA ALA A 169 40.377 17.316 47.770 1.00 36.41 C
+ATOM 1146 CA THR A 170 41.005 14.086 49.622 1.00 32.98 C
+ATOM 1153 CA GLY A 171 42.027 10.802 48.014 1.00 31.36 C
+ATOM 1157 CA THR A 172 40.386 10.037 44.680 1.00 30.48 C
+ATOM 1164 CA GLY A 173 38.640 13.335 45.359 1.00 33.99 C
+ATOM 1168 CA ILE A 174 41.418 15.036 43.394 1.00 35.66 C
+ATOM 1176 CA ALA A 175 39.758 13.585 40.300 1.00 36.00 C
+ATOM 1181 CA PRO A 176 37.445 16.385 39.155 1.00 39.41 C
+ATOM 1188 CA PHE A 177 40.109 18.971 39.976 1.00 43.21 C
+ATOM 1199 CA ARG A 178 42.726 17.119 37.955 1.00 41.09 C
+ATOM 1210 CA SER A 179 40.235 17.536 35.124 1.00 39.92 C
+ATOM 1216 CA PHE A 180 39.808 21.204 36.009 1.00 39.23 C
+ATOM 1227 CA LEU A 181 43.528 21.949 35.995 1.00 39.50 C
+ATOM 1235 CA TRP A 182 44.305 20.081 32.770 1.00 41.47 C
+ATOM 1249 CA LYS A 183 42.141 22.654 30.972 1.00 48.08 C
+ATOM 1258 CA MET A 184 43.477 25.547 33.062 1.00 52.79 C
+ATOM 1266 CA PHE A 185 47.102 25.043 32.014 1.00 57.35 C
+ATOM 1277 CA PHE A 186 48.075 21.921 30.051 1.00 55.98 C
+ATOM 1288 CA GLU A 187 45.758 23.173 27.297 1.00 54.44 C
+ATOM 1297 CA LYS A 188 44.908 26.236 25.196 1.00 51.29 C
+ATOM 1306 CA HIS A 189 41.395 27.080 24.003 1.00 51.35 C
+ATOM 1316 CA ASP A 190 40.108 29.972 21.873 1.00 54.30 C
+ATOM 1324 CA ASP A 191 37.199 30.481 24.249 1.00 53.95 C
+ATOM 1332 CA TYR A 192 38.816 29.937 27.634 1.00 50.68 C
+ATOM 1344 CA LYS A 193 41.916 31.388 29.230 1.00 51.00 C
+ATOM 1353 CA PHE A 194 42.322 30.967 32.956 1.00 52.09 C
+ATOM 1364 CA ASN A 195 43.672 34.234 34.312 1.00 56.46 C
+ATOM 1372 CA GLY A 196 42.616 34.078 37.969 1.00 57.17 C
+ATOM 1376 CA LEU A 197 43.874 31.920 40.843 1.00 57.92 C
+ATOM 1384 CA GLY A 198 43.549 28.151 41.086 1.00 56.67 C
+ATOM 1388 CA TRP A 199 44.258 26.886 44.592 1.00 51.55 C
+ATOM 1402 CA LEU A 200 44.411 23.170 45.379 1.00 49.17 C
+ATOM 1410 CA PHE A 201 44.558 21.335 48.709 1.00 48.60 C
+ATOM 1421 CA LEU A 202 45.122 17.570 48.598 1.00 45.34 C
+ATOM 1429 CA GLY A 203 44.885 15.480 51.742 1.00 48.55 C
+ATOM 1433 CA VAL A 204 46.225 11.936 51.755 1.00 50.23 C
+ATOM 1440 CA PRO A 205 47.942 9.740 54.365 1.00 51.51 C
+ATOM 1447 CA THR A 206 51.284 9.148 52.648 1.00 50.21 C
+ATOM 1454 CA SER A 207 53.551 10.483 49.894 1.00 49.38 C
+ATOM 1460 CA SER A 208 53.267 7.061 48.259 1.00 43.49 C
+ATOM 1466 CA SER A 209 49.588 8.049 48.093 1.00 42.57 C
+ATOM 1472 CA LEU A 210 49.990 11.424 46.364 1.00 42.65 C
+ATOM 1480 CA LEU A 211 48.121 11.446 43.035 1.00 39.33 C
+ATOM 1488 CA TYR A 212 49.516 13.214 39.935 1.00 40.89 C
+ATOM 1500 CA LYS A 213 52.128 15.234 41.873 1.00 45.88 C
+ATOM 1509 CA GLU A 214 54.518 15.406 38.899 1.00 53.22 C
+ATOM 1518 CA GLU A 215 51.680 16.911 36.889 1.00 55.16 C
+ATOM 1527 CA PHE A 216 50.757 19.475 39.514 1.00 60.55 C
+ATOM 1538 CA GLY A 217 54.488 20.153 39.524 1.00 66.64 C
+ATOM 1542 CA LYS A 218 54.575 21.110 35.850 1.00 68.86 C
+ATOM 1551 CA MET A 219 51.398 23.159 36.265 1.00 66.97 C
+ATOM 1559 CA LYS A 220 53.138 25.090 39.061 1.00 65.97 C
+ATOM 1568 CA GLU A 221 55.654 26.250 36.459 1.00 70.02 C
+ATOM 1577 CA ARG A 222 53.584 26.507 33.294 1.00 73.48 C
+ATOM 1588 CA ALA A 223 52.005 29.449 35.175 1.00 76.21 C
+ATOM 1593 CA PRO A 224 53.272 29.877 38.804 1.00 79.25 C
+ATOM 1600 CA GLU A 225 51.296 33.124 39.020 1.00 81.84 C
+ATOM 1609 CA ASN A 226 47.873 31.528 38.622 1.00 78.84 C
+ATOM 1617 CA PHE A 227 48.418 28.176 40.350 1.00 75.28 C
+ATOM 1628 CA ARG A 228 49.090 27.305 43.996 1.00 72.05 C
+ATOM 1639 CA VAL A 229 49.165 23.724 45.323 1.00 68.82 C
+ATOM 1646 CA ASP A 230 49.258 22.581 48.958 1.00 66.54 C
+ATOM 1654 CA TYR A 231 49.605 18.943 49.968 1.00 60.31 C
+ATOM 1666 CA ALA A 232 48.551 17.560 53.332 1.00 57.39 C
+ATOM 1671 CA VAL A 233 50.260 14.228 53.945 1.00 57.14 C
+ATOM 1678 CA SER A 234 48.465 13.579 57.244 1.00 60.81 C
+ATOM 1684 CA ARG A 235 50.959 11.010 58.514 1.00 60.74 C
+ATOM 1695 CA GLU A 236 54.268 12.594 57.481 1.00 59.17 C
+ATOM 1704 CA GLN A 237 53.494 16.197 58.450 1.00 59.62 C
+ATOM 1713 CA THR A 238 52.590 18.236 61.521 1.00 63.18 C
+ATOM 1720 CA ASN A 239 52.019 21.937 62.188 1.00 66.71 C
+ATOM 1728 CA ALA A 240 52.096 23.767 65.537 1.00 70.06 C
+ATOM 1733 CA ALA A 241 51.302 21.400 68.410 1.00 72.44 C
+ATOM 1738 CA GLY A 242 52.383 18.324 66.438 1.00 72.38 C
+ATOM 1742 CA GLU A 243 48.826 18.169 65.110 1.00 69.71 C
+ATOM 1751 CA ARG A 244 48.674 15.776 62.148 1.00 67.21 C
+ATOM 1762 CA MET A 245 48.712 17.796 58.933 1.00 64.20 C
+ATOM 1770 CA TYR A 246 45.246 17.082 57.556 1.00 60.65 C
+ATOM 1782 CA ILE A 247 43.617 18.437 54.409 1.00 62.98 C
+ATOM 1790 CA GLN A 248 42.035 21.001 56.761 1.00 64.64 C
+ATOM 1799 CA THR A 249 45.057 21.461 59.009 1.00 63.37 C
+ATOM 1806 CA ARG A 250 46.891 22.664 55.903 1.00 62.47 C
+ATOM 1817 CA MET A 251 44.123 25.201 55.251 1.00 63.35 C
+ATOM 1825 CA ALA A 252 44.571 26.305 58.854 1.00 65.73 C
+ATOM 1830 CA GLU A 253 47.973 27.809 58.076 1.00 65.97 C
+ATOM 1839 CA TYR A 254 46.267 30.063 55.517 1.00 65.83 C
+ATOM 1851 CA LYS A 255 42.991 30.559 57.379 1.00 70.30 C
+ATOM 1860 CA GLU A 256 43.578 34.326 57.320 1.00 73.73 C
+ATOM 1869 CA GLU A 257 44.189 34.738 53.593 1.00 71.52 C
+ATOM 1878 CA LEU A 258 41.459 32.202 52.893 1.00 73.38 C
+ATOM 1886 CA TRP A 259 38.790 34.074 54.853 1.00 76.72 C
+ATOM 1900 CA GLU A 260 39.721 37.275 53.006 1.00 78.61 C
+ATOM 1909 CA LEU A 261 38.580 35.553 49.815 1.00 75.71 C
+ATOM 1917 CA LEU A 262 35.391 33.881 51.047 1.00 73.74 C
+ATOM 1925 CA LYS A 263 33.562 37.165 50.535 1.00 73.64 C
+ATOM 1934 CA LYS A 264 34.299 38.143 46.954 1.00 72.48 C
+ATOM 1943 CA ASP A 265 31.954 37.554 43.993 1.00 69.65 C
+ATOM 1951 CA ASN A 266 34.660 35.649 42.106 1.00 65.06 C
+ATOM 1959 CA THR A 267 35.835 33.117 44.683 1.00 58.24 C
+ATOM 1966 CA TYR A 268 34.459 29.646 43.909 1.00 51.04 C
+ATOM 1978 CA VAL A 269 35.192 26.827 46.382 1.00 44.95 C
+ATOM 1985 CA TYR A 270 35.012 23.150 45.368 1.00 44.96 C
+ATOM 1997 CA MET A 271 35.162 20.122 47.656 1.00 41.72 C
+ATOM 2005 CA CYS A 272 35.314 16.468 46.632 1.00 37.19 C
+ATOM 2011 CA GLY A 273 36.343 13.080 47.951 1.00 37.65 C
+ATOM 2015 CA LEU A 274 36.040 10.886 51.020 1.00 39.39 C
+ATOM 2023 CA LYS A 275 33.076 12.283 52.955 1.00 44.86 C
+ATOM 2032 CA GLY A 276 34.322 13.183 56.400 1.00 49.16 C
+ATOM 2036 CA MET A 277 36.932 15.608 55.168 1.00 53.30 C
+ATOM 2044 CA GLU A 278 33.917 17.921 55.165 1.00 56.74 C
+ATOM 2053 CA LYS A 279 33.531 18.089 58.947 1.00 59.30 C
+ATOM 2062 CA GLY A 280 36.982 19.413 59.776 1.00 58.94 C
+ATOM 2066 CA ILE A 281 36.705 22.048 57.063 1.00 61.43 C
+ATOM 2074 CA ASP A 282 33.453 23.402 58.515 1.00 67.06 C
+ATOM 2082 CA ASP A 283 35.050 23.189 61.972 1.00 74.12 C
+ATOM 2090 CA ILE A 284 37.991 25.422 61.040 1.00 78.49 C
+ATOM 2098 CA MET A 285 35.456 27.566 59.201 1.00 82.25 C
+ATOM 2106 CA VAL A 286 32.941 27.959 62.027 1.00 83.44 C
+ATOM 2113 CA SER A 287 35.610 29.113 64.469 1.00 83.43 C
+ATOM 2119 CA LEU A 288 36.927 31.601 61.887 1.00 85.53 C
+ATOM 2127 CA ALA A 289 33.506 33.025 60.970 1.00 86.85 C
+ATOM 2132 CA GLU A 290 31.841 32.696 64.387 1.00 89.26 C
+ATOM 2141 CA LYS A 291 34.438 35.312 65.347 1.00 88.73 C
+ATOM 2150 CA ASP A 292 33.635 37.891 62.652 1.00 88.03 C
+ATOM 2158 CA GLY A 293 30.219 37.450 61.081 1.00 87.88 C
+ATOM 2162 CA ILE A 294 27.319 35.051 61.511 1.00 84.61 C
+ATOM 2170 CA ASP A 295 27.665 31.329 62.188 1.00 82.45 C
+ATOM 2178 CA TRP A 296 29.539 29.627 59.355 1.00 80.12 C
+ATOM 2192 CA PHE A 297 26.527 27.452 58.512 1.00 78.99 C
+ATOM 2203 CA ASP A 298 24.167 30.241 57.486 1.00 76.37 C
+ATOM 2211 CA TYR A 299 27.074 31.748 55.561 1.00 74.07 C
+ATOM 2223 CA LYS A 300 27.679 28.620 53.473 1.00 74.31 C
+ATOM 2232 CA LYS A 301 24.059 29.146 52.464 1.00 75.97 C
+ATOM 2241 CA GLN A 302 24.921 32.563 51.018 1.00 75.38 C
+ATOM 2250 CA LEU A 303 27.896 31.099 49.155 1.00 72.10 C
+ATOM 2258 CA LYS A 304 25.917 28.207 47.690 1.00 72.08 C
+ATOM 2267 CA ARG A 305 23.595 31.021 46.594 1.00 74.82 C
+ATOM 2278 CA GLY A 306 26.071 32.136 43.958 1.00 71.84 C
+ATOM 2282 CA ASP A 307 27.505 28.682 43.220 1.00 67.23 C
+ATOM 2290 CA GLN A 308 30.620 29.291 45.346 1.00 60.18 C
+ATOM 2299 CA TRP A 309 30.585 26.177 47.537 1.00 52.25 C
+ATOM 2313 CA ASN A 310 29.894 22.997 45.597 1.00 45.03 C
+ATOM 2321 CA VAL A 311 30.327 19.716 47.403 1.00 39.13 C
+ATOM 2328 CA GLU A 312 30.507 16.190 46.110 1.00 35.17 C
+ATOM 2337 CA VAL A 313 31.761 13.957 48.861 1.00 30.12 C
+ATOM 2344 CA TYR A 314 31.112 10.230 49.021 1.00 28.23 C
+ATOM 2358 CA ALA B 1 2.311 24.702 44.475 1.00 74.17 C
+ATOM 2363 CA THR B 2 3.590 24.207 48.055 1.00 74.76 C
+ATOM 2370 CA TYR B 3 3.069 20.876 49.837 1.00 73.52 C
+ATOM 2382 CA ASN B 4 3.748 19.874 53.435 1.00 75.75 C
+ATOM 2390 CA VAL B 5 6.618 17.399 53.868 1.00 75.95 C
+ATOM 2397 CA LYS B 6 7.769 15.523 56.983 1.00 77.70 C
+ATOM 2406 CA LEU B 7 11.351 14.325 57.458 1.00 78.91 C
+ATOM 2414 CA ILE B 8 11.807 11.511 59.985 1.00 81.00 C
+ATOM 2422 CA THR B 9 15.560 12.046 60.247 1.00 87.49 C
+ATOM 2429 CA PRO B 10 17.662 9.793 62.539 1.00 92.94 C
+ATOM 2436 CA GLU B 11 18.161 13.147 64.282 1.00 96.61 C
+ATOM 2445 CA GLY B 12 14.579 14.154 65.041 1.00 97.52 C
+ATOM 2449 CA GLU B 13 11.602 14.823 62.748 1.00 96.90 C
+ATOM 2458 CA VAL B 14 11.547 17.892 60.480 1.00 96.63 C
+ATOM 2465 CA GLU B 15 8.340 19.701 59.440 1.00 94.86 C
+ATOM 2474 CA LEU B 16 9.471 21.479 56.254 1.00 91.55 C
+ATOM 2482 CA GLN B 17 7.281 23.141 53.598 1.00 89.75 C
+ATOM 2491 CA VAL B 18 8.485 22.069 50.145 1.00 87.92 C
+ATOM 2498 CA PRO B 19 6.906 23.558 46.964 1.00 86.35 C
+ATOM 2505 CA ASP B 20 5.990 21.744 43.717 1.00 86.29 C
+ATOM 2513 CA ASP B 21 8.578 22.751 41.083 1.00 83.78 C
+ATOM 2521 CA VAL B 22 11.385 22.401 43.639 1.00 80.98 C
+ATOM 2528 CA TYR B 23 13.439 19.280 44.481 1.00 77.04 C
+ATOM 2540 CA ILE B 24 13.212 18.196 48.120 1.00 76.45 C
+ATOM 2548 CA LEU B 25 16.959 18.133 48.851 1.00 75.15 C
+ATOM 2556 CA ASP B 26 17.154 21.745 47.689 1.00 75.80 C
+ATOM 2564 CA GLN B 27 14.616 22.906 50.280 1.00 76.31 C
+ATOM 2573 CA ALA B 28 16.562 20.957 52.914 1.00 78.86 C
+ATOM 2578 CA GLU B 29 19.698 23.011 52.198 1.00 81.51 C
+ATOM 2587 CA GLU B 30 17.491 26.106 52.510 1.00 83.25 C
+ATOM 2596 CA ASP B 31 15.857 25.933 55.935 1.00 81.92 C
+ATOM 2604 CA GLY B 32 19.280 24.859 57.151 1.00 79.08 C
+ATOM 2608 CA ILE B 33 18.621 21.130 57.157 1.00 76.93 C
+ATOM 2616 CA ASP B 34 21.528 18.731 56.618 1.00 73.53 C
+ATOM 2624 CA LEU B 35 20.738 15.738 54.421 1.00 67.74 C
+ATOM 2632 CA PRO B 36 23.138 13.391 52.547 1.00 65.90 C
+ATOM 2639 CA TYR B 37 23.916 14.226 48.912 1.00 64.85 C
+ATOM 2651 CA SER B 38 26.659 13.373 46.412 1.00 62.58 C
+ATOM 2657 CA CYS B 39 26.193 13.603 42.652 1.00 60.99 C
+ATOM 2663 CA ARG B 40 22.908 15.441 43.251 1.00 58.35 C
+ATOM 2674 CA ALA B 41 21.699 14.108 39.886 1.00 56.38 C
+ATOM 2679 CA GLY B 42 19.886 10.955 40.991 1.00 56.66 C
+ATOM 2683 CA SER B 43 22.465 8.336 40.010 1.00 58.55 C
+ATOM 2689 CA CYS B 44 23.548 7.052 43.447 1.00 56.27 C
+ATOM 2695 CA SER B 45 22.057 5.987 46.791 1.00 58.20 C
+ATOM 2701 CA SER B 46 23.574 8.773 48.890 1.00 59.13 C
+ATOM 2707 CA CYS B 47 20.220 10.475 49.517 1.00 65.64 C
+ATOM 2713 CA ALA B 48 17.911 7.436 49.610 1.00 69.71 C
+ATOM 2718 CA GLY B 49 14.733 7.635 51.681 1.00 73.09 C
+ATOM 2722 CA LYS B 50 11.712 5.340 52.183 1.00 73.77 C
+ATOM 2731 CA VAL B 51 8.551 7.412 51.568 1.00 76.51 C
+ATOM 2738 CA VAL B 52 5.237 7.081 53.429 1.00 78.85 C
+ATOM 2745 CA SER B 53 2.180 9.376 53.647 1.00 79.57 C
+ATOM 2751 CA GLY B 54 2.118 10.991 50.218 1.00 76.32 C
+ATOM 2755 CA SER B 55 3.577 10.944 46.726 1.00 76.31 C
+ATOM 2761 CA VAL B 56 6.436 12.592 44.828 1.00 77.50 C
+ATOM 2768 CA ASP B 57 7.691 12.960 41.243 1.00 76.83 C
+ATOM 2776 CA GLN B 58 11.150 11.483 40.555 1.00 76.66 C
+ATOM 2785 CA SER B 59 10.976 10.827 36.792 1.00 80.19 C
+ATOM 2791 CA ASP B 60 14.688 11.644 36.510 1.00 83.51 C
+ATOM 2799 CA GLN B 61 15.175 8.137 37.916 1.00 85.74 C
+ATOM 2808 CA SER B 62 18.644 7.080 36.699 1.00 85.85 C
+ATOM 2814 CA TYR B 63 19.324 5.049 39.852 1.00 84.49 C
+ATOM 2826 CA LEU B 64 15.683 4.296 40.629 1.00 89.06 C
+ATOM 2834 CA ASP B 65 15.356 0.604 39.742 1.00 92.21 C
+ATOM 2842 CA ASP B 66 12.421 -1.791 39.331 1.00 92.35 C
+ATOM 2850 CA GLY B 67 10.747 -2.542 42.659 1.00 89.07 C
+ATOM 2854 CA GLN B 68 12.336 0.632 44.010 1.00 88.41 C
+ATOM 2863 CA ILE B 69 9.483 2.828 42.742 1.00 86.11 C
+ATOM 2871 CA ALA B 70 7.060 0.441 44.446 1.00 81.10 C
+ATOM 2876 CA ASP B 71 8.985 -0.310 47.648 1.00 76.82 C
+ATOM 2884 CA GLY B 72 8.653 3.423 48.186 1.00 73.00 C
+ATOM 2888 CA TRP B 73 12.342 4.386 48.095 1.00 67.93 C
+ATOM 2902 CA VAL B 74 13.052 8.007 47.136 1.00 63.84 C
+ATOM 2909 CA LEU B 75 16.093 9.940 45.892 1.00 58.37 C
+ATOM 2917 CA THR B 76 15.524 13.198 47.826 1.00 55.82 C
+ATOM 2924 CA CYS B 77 17.941 15.109 45.556 1.00 58.23 C
+ATOM 2930 CA HIS B 78 15.777 14.389 42.513 1.00 64.55 C
+ATOM 2940 CA ALA B 79 12.108 14.429 43.512 1.00 68.40 C
+ATOM 2945 CA TYR B 80 9.442 17.152 43.581 1.00 69.69 C
+ATOM 2957 CA PRO B 81 6.414 16.584 45.842 1.00 71.39 C
+ATOM 2964 CA THR B 82 3.015 16.014 44.179 1.00 73.67 C
+ATOM 2971 CA SER B 83 1.278 15.771 47.557 1.00 76.90 C
+ATOM 2977 CA ASP B 84 1.940 16.119 51.289 1.00 75.20 C
+ATOM 2985 CA VAL B 85 4.840 13.765 52.050 1.00 71.37 C
+ATOM 2992 CA VAL B 86 6.363 11.824 54.956 1.00 70.12 C
+ATOM 2999 CA ILE B 87 9.770 10.300 54.188 1.00 74.18 C
+ATOM 3007 CA GLU B 88 12.211 8.403 56.410 1.00 78.53 C
+ATOM 3012 CA THR B 89 15.541 9.964 55.407 1.00 79.79 C
+ATOM 3019 CA HIS B 90 19.062 8.538 55.881 1.00 79.40 C
+ATOM 3029 CA LYS B 91 17.584 5.099 55.099 1.00 84.52 C
+ATOM 3038 CA GLU B 92 20.016 2.596 53.549 1.00 91.64 C
+ATOM 3047 CA GLU B 93 20.192 -0.858 51.981 1.00 98.97 C
+ATOM 3056 CA GLU B 94 23.321 -2.924 51.298 1.00106.32 C
+ATOM 3065 CA LEU B 95 22.104 -6.552 51.453 1.00111.32 C
+ATOM 3073 CA THR B 96 18.778 -8.417 51.866 1.00116.01 C
+ATOM 3080 CA GLY B 97 18.877 -11.302 49.394 1.00116.63 C
+ATOM 3084 CA ALA B 98 22.056 -9.833 47.910 1.00116.02 C
+ATOM 3091 CA GLU C 19 26.080 -2.480 15.294 1.00 73.96 C
+ATOM 3100 CA SER C 20 23.405 0.198 14.956 1.00 67.27 C
+ATOM 3106 CA LYS C 21 22.937 3.927 15.380 1.00 59.27 C
+ATOM 3115 CA LYS C 22 19.198 3.481 15.874 1.00 58.42 C
+ATOM 3124 CA GLN C 23 17.251 3.141 19.137 1.00 59.89 C
+ATOM 3133 CA GLU C 24 17.931 -0.276 20.610 1.00 62.66 C
+ATOM 3142 CA GLU C 25 16.850 -0.453 24.226 1.00 64.27 C
+ATOM 3151 CA GLY C 26 13.211 -0.817 25.116 1.00 61.78 C
+ATOM 3155 CA VAL C 27 12.703 -2.073 21.582 1.00 58.37 C
+ATOM 3162 CA VAL C 28 10.779 -5.347 21.485 1.00 54.17 C
+ATOM 3169 CA THR C 29 9.481 -7.339 18.549 1.00 52.79 C
+ATOM 3176 CA ASN C 30 6.670 -9.775 17.786 1.00 51.30 C
+ATOM 3184 CA LEU C 31 4.863 -9.997 21.112 1.00 51.05 C
+ATOM 3192 CA TYR C 32 1.766 -11.297 19.327 1.00 50.51 C
+ATOM 3204 CA LYS C 33 1.373 -13.532 16.266 1.00 49.49 C
+ATOM 3213 CA PRO C 34 -1.609 -14.150 13.925 1.00 50.98 C
+ATOM 3220 CA LYS C 35 -2.450 -17.248 16.011 1.00 55.46 C
+ATOM 3229 CA GLU C 36 -2.977 -15.400 19.288 1.00 53.79 C
+ATOM 3238 CA PRO C 37 -3.251 -11.638 18.607 1.00 49.32 C
+ATOM 3245 CA TYR C 38 -3.674 -9.050 21.318 1.00 46.76 C
+ATOM 3257 CA VAL C 39 -7.276 -7.947 21.418 1.00 43.68 C
+ATOM 3264 CA GLY C 40 -7.415 -4.194 21.922 1.00 41.62 C
+ATOM 3268 CA ARG C 41 -10.273 -1.719 21.954 1.00 40.07 C
+ATOM 3279 CA CYS C 42 -11.026 1.064 19.477 1.00 36.37 C
+ATOM 3285 CA LEU C 43 -11.330 4.206 21.583 1.00 31.09 C
+ATOM 3293 CA LEU C 44 -11.337 6.671 18.673 1.00 28.46 C
+ATOM 3301 CA ASN C 45 -11.792 6.653 14.923 1.00 26.74 C
+ATOM 3309 CA THR C 46 -11.954 9.920 13.013 1.00 25.29 C
+ATOM 3316 CA LYS C 47 -11.667 10.775 9.352 1.00 21.50 C
+ATOM 3325 CA ILE C 48 -8.895 13.355 9.121 1.00 19.33 C
+ATOM 3333 CA THR C 49 -9.125 14.281 5.442 1.00 20.38 C
+ATOM 3340 CA GLY C 50 -11.630 16.676 3.855 1.00 20.12 C
+ATOM 3344 CA ASP C 51 -14.895 15.345 2.412 1.00 21.75 C
+ATOM 3352 CA ASP C 52 -13.889 16.693 -0.999 1.00 21.19 C
+ATOM 3360 CA ALA C 53 -10.651 14.683 -0.749 1.00 21.06 C
+ATOM 3365 CA PRO C 54 -10.036 11.974 -3.413 1.00 21.39 C
+ATOM 3372 CA GLY C 55 -9.982 9.067 -0.977 1.00 24.42 C
+ATOM 3376 CA GLU C 56 -10.374 9.298 2.857 1.00 22.08 C
+ATOM 3385 CA THR C 57 -7.723 8.611 5.517 1.00 20.31 C
+ATOM 3392 CA TRP C 58 -8.541 7.849 9.162 1.00 19.33 C
+ATOM 3406 CA HIS C 59 -6.758 8.520 12.438 1.00 22.68 C
+ATOM 3416 CA MET C 60 -7.645 5.951 15.108 1.00 27.16 C
+ATOM 3424 CA VAL C 61 -6.672 5.224 18.723 1.00 29.32 C
+ATOM 3431 CA PHE C 62 -6.669 1.704 20.220 1.00 34.23 C
+ATOM 3442 CA SER C 63 -6.102 0.643 23.847 1.00 37.05 C
+ATOM 3448 CA THR C 64 -3.096 -1.517 24.798 1.00 41.86 C
+ATOM 3455 CA GLU C 65 -3.169 -1.652 28.621 1.00 48.33 C
+ATOM 3464 CA GLY C 66 0.537 -0.885 28.318 1.00 52.45 C
+ATOM 3468 CA LYS C 67 0.955 -4.385 26.891 1.00 54.14 C
+ATOM 3477 CA ILE C 68 2.429 -3.211 23.570 1.00 51.52 C
+ATOM 3485 CA PRO C 69 5.602 -1.279 24.487 1.00 49.85 C
+ATOM 3492 CA TYR C 70 6.523 -0.180 20.967 1.00 44.48 C
+ATOM 3504 CA ARG C 71 9.185 2.353 19.993 1.00 40.96 C
+ATOM 3515 CA GLU C 72 8.727 5.317 17.688 1.00 33.49 C
+ATOM 3524 CA GLY C 73 8.913 3.876 14.164 1.00 30.16 C
+ATOM 3528 CA GLN C 74 7.423 0.399 14.427 1.00 31.26 C
+ATOM 3537 CA SER C 75 4.187 -0.913 12.966 1.00 33.65 C
+ATOM 3543 CA ILE C 76 1.454 -3.212 14.278 1.00 33.75 C
+ATOM 3551 CA GLY C 77 -0.295 -5.923 12.356 1.00 34.32 C
+ATOM 3555 CA VAL C 78 -4.060 -6.111 12.164 1.00 36.67 C
+ATOM 3562 CA ILE C 79 -6.137 -9.230 11.507 1.00 41.91 C
+ATOM 3570 CA ALA C 80 -9.427 -8.086 10.024 1.00 44.06 C
+ATOM 3575 CA ASP C 81 -12.530 -9.927 11.224 1.00 47.03 C
+ATOM 3583 CA GLY C 82 -13.972 -12.487 8.829 1.00 53.52 C
+ATOM 3587 CA VAL C 83 -12.521 -14.951 6.324 1.00 62.57 C
+ATOM 3594 CA ASP C 84 -11.856 -14.200 2.630 1.00 71.97 C
+ATOM 3602 CA LYS C 85 -12.935 -17.403 0.861 1.00 76.86 C
+ATOM 3611 CA ASN C 86 -13.690 -18.960 4.253 1.00 76.52 C
+ATOM 3619 CA GLY C 87 -10.006 -19.837 4.066 1.00 76.22 C
+ATOM 3623 CA LYS C 88 -8.802 -19.138 7.616 1.00 71.60 C
+ATOM 3632 CA PRO C 89 -8.651 -15.577 8.944 1.00 64.14 C
+ATOM 3639 CA HIS C 90 -7.547 -12.649 6.805 1.00 52.35 C
+ATOM 3649 CA LYS C 91 -3.753 -12.529 6.474 1.00 46.81 C
+ATOM 3658 CA VAL C 92 -2.180 -9.868 8.686 1.00 43.48 C
+ATOM 3665 CA ARG C 93 -1.491 -6.414 7.232 1.00 36.99 C
+ATOM 3676 CA LEU C 94 0.983 -3.882 8.601 1.00 32.95 C
+ATOM 3684 CA TYR C 95 0.340 -0.239 9.510 1.00 24.84 C
+ATOM 3696 CA SER C 96 3.003 2.101 10.803 1.00 23.32 C
+ATOM 3702 CA ILE C 97 2.244 3.502 14.236 1.00 24.12 C
+ATOM 3710 CA ALA C 98 1.243 7.179 13.932 1.00 22.32 C
+ATOM 3715 CA SER C 99 1.572 7.636 17.676 1.00 25.69 C
+ATOM 3721 CA SER C 100 4.752 7.924 19.726 1.00 28.83 C
+ATOM 3727 CA ALA C 101 5.741 5.521 22.508 1.00 35.61 C
+ATOM 3732 CA ILE C 102 3.906 7.635 25.079 1.00 38.39 C
+ATOM 3740 CA GLY C 103 0.899 7.826 22.742 1.00 31.93 C
+ATOM 3744 CA ASP C 104 -1.803 10.384 21.986 1.00 28.77 C
+ATOM 3752 CA PHE C 105 -3.050 10.293 25.607 1.00 37.05 C
+ATOM 3763 CA GLY C 106 0.503 10.389 26.967 1.00 39.36 C
+ATOM 3767 CA ASP C 107 -0.221 7.437 29.266 1.00 41.44 C
+ATOM 3775 CA SER C 108 1.566 4.766 27.217 1.00 42.18 C
+ATOM 3781 CA LYS C 109 -1.747 2.877 27.156 1.00 42.45 C
+ATOM 3790 CA THR C 110 -2.698 3.586 23.515 1.00 38.10 C
+ATOM 3797 CA VAL C 111 -1.603 2.971 19.906 1.00 32.79 C
+ATOM 3804 CA SER C 112 -2.671 5.020 16.872 1.00 29.60 C
+ATOM 3810 CA LEU C 113 -2.713 4.324 13.126 1.00 25.68 C
+ATOM 3818 CA CYS C 114 -3.142 6.498 9.999 1.00 24.23 C
+ATOM 3824 CA VAL C 115 -5.345 4.496 7.641 1.00 22.80 C
+ATOM 3831 CA LYS C 116 -6.221 5.196 4.015 1.00 22.11 C
+ATOM 3840 CA ARG C 117 -9.458 3.521 2.955 1.00 25.68 C
+ATOM 3851 CA LEU C 118 -8.447 1.440 -0.100 1.00 28.80 C
+ATOM 3859 CA ILE C 119 -11.140 1.661 -2.792 1.00 31.75 C
+ATOM 3867 CA TYR C 120 -10.086 0.716 -6.312 1.00 32.93 C
+ATOM 3879 CA THR C 121 -11.388 -0.733 -9.598 1.00 36.84 C
+ATOM 3886 CA ASN C 122 -10.258 -4.257 -10.546 1.00 36.90 C
+ATOM 3894 CA ASP C 123 -9.574 -5.562 -14.056 1.00 45.45 C
+ATOM 3902 CA ALA C 124 -13.196 -6.758 -14.269 1.00 44.66 C
+ATOM 3907 CA GLY C 125 -14.207 -3.102 -14.023 1.00 45.49 C
+ATOM 3911 CA GLU C 126 -16.059 -3.511 -10.722 1.00 45.54 C
+ATOM 3920 CA ILE C 127 -15.507 -1.321 -7.638 1.00 39.70 C
+ATOM 3928 CA VAL C 128 -13.846 -3.171 -4.762 1.00 38.09 C
+ATOM 3935 CA LYS C 129 -12.759 -2.512 -1.198 1.00 33.77 C
+ATOM 3944 CA GLY C 130 -9.566 -3.363 0.599 1.00 31.98 C
+ATOM 3948 CA VAL C 131 -10.443 -5.797 3.385 1.00 33.16 C
+ATOM 3955 CA CYS C 132 -8.241 -4.645 6.257 1.00 29.97 C
+ATOM 3961 CA SER C 133 -8.238 -0.898 5.607 1.00 30.67 C
+ATOM 3967 CA ASN C 134 -12.022 -0.902 5.268 1.00 30.35 C
+ATOM 3975 CA PHE C 135 -12.375 -2.946 8.424 1.00 29.86 C
+ATOM 3986 CA LEU C 136 -10.223 -0.334 10.195 1.00 29.42 C
+ATOM 3994 CA CYS C 137 -11.779 2.834 8.813 1.00 32.27 C
+ATOM 4000 CA ASP C 138 -15.116 1.280 9.724 1.00 34.29 C
+ATOM 4008 CA LEU C 139 -14.287 0.699 13.399 1.00 37.51 C
+ATOM 4016 CA GLN C 140 -16.635 2.170 16.028 1.00 43.76 C
+ATOM 4025 CA PRO C 141 -15.630 3.032 19.581 1.00 42.77 C
+ATOM 4032 CA GLY C 142 -16.082 -0.210 21.478 1.00 42.83 C
+ATOM 4036 CA ASP C 143 -15.117 -2.625 18.696 1.00 40.91 C
+ATOM 4044 CA ASN C 144 -12.182 -4.947 19.288 1.00 45.66 C
+ATOM 4052 CA VAL C 145 -9.056 -5.146 17.145 1.00 46.95 C
+ATOM 4059 CA GLN C 146 -6.707 -8.107 16.606 1.00 48.69 C
+ATOM 4068 CA ILE C 147 -3.249 -6.538 17.123 1.00 46.84 C
+ATOM 4076 CA THR C 148 -0.010 -8.392 16.264 1.00 46.26 C
+ATOM 4083 CA GLY C 149 3.543 -7.117 16.634 1.00 45.60 C
+ATOM 4087 CA PRO C 150 5.248 -4.818 17.394 1.00 44.97 C
+ATOM 4094 CA VAL C 151 7.423 -5.293 14.321 1.00 44.50 C
+ATOM 4101 CA GLY C 152 10.289 -3.716 12.438 1.00 45.33 C
+ATOM 4105 CA LYS C 153 13.599 -2.161 13.435 1.00 48.64 C
+ATOM 4114 CA GLU C 154 14.166 -0.437 10.074 1.00 48.20 C
+ATOM 4123 CA MET C 155 12.437 2.888 10.737 1.00 41.77 C
+ATOM 4131 CA LEU C 156 13.839 3.081 14.267 1.00 38.27 C
+ATOM 4139 CA MET C 157 15.076 6.540 15.308 1.00 34.29 C
+ATOM 4147 CA PRO C 158 18.782 7.419 15.339 1.00 34.05 C
+ATOM 4154 CA LYS C 159 20.262 7.521 18.845 1.00 35.82 C
+ATOM 4163 CA ASP C 160 22.076 10.792 18.273 1.00 35.95 C
+ATOM 4171 CA PRO C 161 19.683 13.401 19.809 1.00 35.63 C
+ATOM 4178 CA ASN C 162 21.563 15.948 17.758 1.00 33.92 C
+ATOM 4186 CA ALA C 163 21.028 14.172 14.487 1.00 30.82 C
+ATOM 4191 CA THR C 164 19.693 15.722 11.305 1.00 25.18 C
+ATOM 4198 CA ILE C 165 16.617 13.601 10.636 1.00 19.91 C
+ATOM 4206 CA ILE C 166 15.351 13.978 7.060 1.00 13.76 C
+ATOM 4214 CA MET C 167 11.843 12.550 6.703 1.00 14.98 C
+ATOM 4222 CA LEU C 168 10.385 11.831 3.251 1.00 16.64 C
+ATOM 4230 CA ALA C 169 6.747 10.808 3.007 1.00 15.85 C
+ATOM 4235 CA THR C 170 3.765 10.346 0.737 1.00 14.23 C
+ATOM 4242 CA GLY C 171 0.255 9.724 2.035 1.00 13.78 C
+ATOM 4246 CA THR C 172 -0.103 7.560 5.139 1.00 17.62 C
+ATOM 4253 CA GLY C 173 3.646 7.343 4.821 1.00 17.20 C
+ATOM 4257 CA ILE C 174 3.469 10.213 7.270 1.00 15.91 C
+ATOM 4265 CA ALA C 175 2.586 7.783 10.110 1.00 15.63 C
+ATOM 4270 CA PRO C 176 6.023 6.933 11.582 1.00 17.04 C
+ATOM 4277 CA PHE C 177 7.215 10.514 11.327 1.00 18.21 C
+ATOM 4288 CA ARG C 178 4.268 11.745 13.359 1.00 22.35 C
+ATOM 4299 CA SER C 179 5.563 9.289 15.983 1.00 25.22 C
+ATOM 4305 CA PHE C 180 9.139 10.593 15.614 1.00 25.98 C
+ATOM 4316 CA LEU C 181 7.925 14.180 15.767 1.00 29.12 C
+ATOM 4324 CA TRP C 182 5.625 13.641 18.714 1.00 31.35 C
+ATOM 4338 CA LYS C 183 8.488 12.385 20.871 1.00 30.92 C
+ATOM 4347 CA MET C 184 10.841 15.050 19.503 1.00 24.85 C
+ATOM 4355 CA PHE C 185 8.741 18.202 20.114 1.00 22.97 C
+ATOM 4366 CA PHE C 186 5.604 17.337 22.076 1.00 27.77 C
+ATOM 4377 CA GLU C 187 7.117 15.432 25.009 1.00 37.71 C
+ATOM 4386 CA LYS C 188 9.542 15.977 27.878 1.00 53.59 C
+ATOM 4395 CA HIS C 189 12.355 13.416 28.180 1.00 63.67 C
+ATOM 4405 CA ASP C 190 15.318 13.181 30.569 1.00 66.93 C
+ATOM 4413 CA ASP C 191 17.480 11.106 28.238 1.00 59.79 C
+ATOM 4421 CA TYR C 192 16.190 12.725 25.047 1.00 51.96 C
+ATOM 4433 CA LYS C 193 16.700 16.406 24.324 1.00 47.01 C
+ATOM 4442 CA PHE C 194 16.580 16.471 20.530 1.00 39.85 C
+ATOM 4453 CA ASN C 195 18.572 19.494 19.409 1.00 37.52 C
+ATOM 4461 CA GLY C 196 19.361 18.548 15.845 1.00 32.08 C
+ATOM 4465 CA LEU C 197 17.310 19.266 12.766 1.00 28.26 C
+ATOM 4473 CA GLY C 198 14.051 17.526 11.928 1.00 25.05 C
+ATOM 4477 CA TRP C 199 13.211 18.137 8.269 1.00 19.81 C
+ATOM 4491 CA LEU C 200 9.908 16.742 7.059 1.00 13.86 C
+ATOM 4499 CA PHE C 201 8.855 16.521 3.429 1.00 14.83 C
+ATOM 4510 CA LEU C 202 5.288 15.361 2.717 1.00 16.12 C
+ATOM 4518 CA GLY C 203 3.701 14.731 -0.681 1.00 13.79 C
+ATOM 4522 CA VAL C 204 -0.051 14.414 -1.182 1.00 11.75 C
+ATOM 4529 CA PRO C 205 -2.113 15.264 -4.308 1.00 14.66 C
+ATOM 4536 CA THR C 206 -4.553 17.737 -2.778 1.00 16.37 C
+ATOM 4543 CA SER C 207 -4.756 20.169 0.120 1.00 18.01 C
+ATOM 4549 CA SER C 208 -7.780 18.225 1.280 1.00 17.59 C
+ATOM 4555 CA SER C 209 -5.452 15.198 1.550 1.00 16.19 C
+ATOM 4561 CA LEU C 210 -2.972 16.940 3.860 1.00 14.22 C
+ATOM 4569 CA LEU C 211 -2.255 14.980 7.059 1.00 14.43 C
+ATOM 4577 CA TYR C 212 -1.624 16.449 10.549 1.00 18.94 C
+ATOM 4589 CA LYS C 213 -0.818 19.896 9.150 1.00 22.61 C
+ATOM 4598 CA GLU C 214 -2.039 21.572 12.352 1.00 25.73 C
+ATOM 4607 CA GLU C 215 0.152 19.413 14.514 1.00 19.23 C
+ATOM 4616 CA PHE C 216 3.216 20.178 12.439 1.00 17.80 C
+ATOM 4627 CA GLY C 217 2.478 23.890 12.512 1.00 19.90 C
+ATOM 4631 CA LYS C 218 2.578 24.001 16.294 1.00 25.54 C
+ATOM 4640 CA MET C 219 5.810 22.021 16.188 1.00 26.79 C
+ATOM 4648 CA LYS C 220 7.224 24.606 13.819 1.00 31.85 C
+ATOM 4657 CA GLU C 221 6.071 27.341 16.219 1.00 38.62 C
+ATOM 4666 CA ARG C 222 7.760 25.760 19.233 1.00 39.10 C
+ATOM 4677 CA ALA C 223 11.124 24.971 17.668 1.00 35.43 C
+ATOM 4682 CA PRO C 224 11.696 27.100 14.528 1.00 32.99 C
+ATOM 4689 CA GLU C 225 15.425 26.331 14.360 1.00 33.87 C
+ATOM 4698 CA ASN C 226 15.038 22.591 14.986 1.00 30.46 C
+ATOM 4706 CA PHE C 227 12.088 21.755 12.732 1.00 24.98 C
+ATOM 4717 CA ARG C 228 11.351 22.384 9.075 1.00 19.87 C
+ATOM 4728 CA VAL C 229 8.435 21.010 7.118 1.00 14.21 C
+ATOM 4735 CA ASP C 230 7.739 21.452 3.398 1.00 12.26 C
+ATOM 4743 CA TYR C 231 4.627 20.147 1.722 1.00 14.42 C
+ATOM 4755 CA ALA C 232 4.334 19.003 -1.872 1.00 9.99 C
+ATOM 4760 CA VAL C 233 0.778 19.232 -3.168 1.00 10.49 C
+ATOM 4767 CA SER C 234 1.043 17.769 -6.694 1.00 19.00 C
+ATOM 4773 CA ARG C 235 -2.240 19.042 -8.206 1.00 23.13 C
+ATOM 4784 CA GLU C 236 -2.069 22.459 -6.578 1.00 17.58 C
+ATOM 4793 CA GLN C 237 1.546 23.511 -6.623 1.00 15.89 C
+ATOM 4802 CA THR C 238 4.202 24.018 -9.275 1.00 17.86 C
+ATOM 4809 CA ASN C 239 7.922 24.800 -9.182 1.00 15.15 C
+ATOM 4817 CA ALA C 240 9.558 27.791 -10.892 1.00 21.51 C
+ATOM 4822 CA ALA C 241 9.475 25.887 -14.174 1.00 24.05 C
+ATOM 4827 CA GLY C 242 5.741 25.110 -13.938 1.00 26.25 C
+ATOM 4831 CA GLU C 243 5.999 21.359 -13.153 1.00 25.92 C
+ATOM 4840 CA ARG C 244 3.679 19.536 -10.704 1.00 24.04 C
+ATOM 4851 CA MET C 245 5.076 19.643 -7.174 1.00 18.58 C
+ATOM 4859 CA TYR C 246 5.784 16.047 -6.100 1.00 14.16 C
+ATOM 4871 CA ILE C 247 7.910 15.343 -3.034 1.00 16.78 C
+ATOM 4879 CA GLN C 248 11.089 15.070 -5.120 1.00 18.72 C
+ATOM 4888 CA THR C 249 10.168 18.255 -6.921 1.00 20.93 C
+ATOM 4895 CA ARG C 250 9.962 20.031 -3.567 1.00 19.25 C
+ATOM 4906 CA MET C 251 13.275 18.471 -2.561 1.00 19.40 C
+ATOM 4914 CA ALA C 252 14.910 19.812 -5.760 1.00 20.48 C
+ATOM 4919 CA GLU C 253 14.456 23.418 -4.569 1.00 18.19 C
+ATOM 4928 CA TYR C 254 16.804 22.515 -1.673 1.00 17.80 C
+ATOM 4940 CA LYS C 255 19.038 20.415 -3.902 1.00 20.66 C
+ATOM 4949 CA GLU C 256 22.452 21.603 -2.682 1.00 16.05 C
+ATOM 4958 CA GLU C 257 21.544 21.914 0.993 1.00 15.89 C
+ATOM 4967 CA LEU C 258 20.377 18.297 0.919 1.00 20.74 C
+ATOM 4975 CA TRP C 259 23.388 16.939 -0.965 1.00 23.45 C
+ATOM 4989 CA GLU C 260 25.645 18.669 1.563 1.00 24.08 C
+ATOM 4998 CA LEU C 261 23.573 17.378 4.477 1.00 24.74 C
+ATOM 5006 CA LEU C 262 24.020 13.928 2.938 1.00 26.14 C
+ATOM 5014 CA LYS C 263 27.792 14.091 3.402 1.00 25.40 C
+ATOM 5023 CA LYS C 264 27.457 14.521 7.176 1.00 31.47 C
+ATOM 5032 CA ASP C 265 27.877 11.474 9.425 1.00 35.31 C
+ATOM 5040 CA ASN C 266 24.934 12.482 11.620 1.00 29.63 C
+ATOM 5048 CA THR C 267 22.321 12.795 8.832 1.00 28.00 C
+ATOM 5055 CA TYR C 268 19.556 10.160 8.808 1.00 27.00 C
+ATOM 5067 CA VAL C 269 17.143 9.903 5.884 1.00 24.65 C
+ATOM 5074 CA TYR C 270 13.890 8.016 6.276 1.00 23.37 C
+ATOM 5086 CA MET C 271 11.373 7.327 3.518 1.00 18.93 C
+ATOM 5094 CA CYS C 272 7.834 6.074 4.043 1.00 18.24 C
+ATOM 5100 CA GLY C 273 4.784 5.874 1.826 1.00 22.39 C
+ATOM 5104 CA LEU C 274 3.837 4.483 -1.568 1.00 26.95 C
+ATOM 5112 CA LYS C 275 6.305 2.384 -3.532 1.00 32.36 C
+ATOM 5121 CA GLY C 276 7.741 4.199 -6.514 1.00 37.46 C
+ATOM 5125 CA MET C 277 7.714 7.455 -4.608 1.00 28.76 C
+ATOM 5133 CA GLU C 278 11.430 6.639 -4.425 1.00 32.22 C
+ATOM 5142 CA LYS C 279 12.017 6.321 -8.153 1.00 29.94 C
+ATOM 5151 CA GLY C 280 11.317 10.057 -8.293 1.00 24.18 C
+ATOM 5155 CA ILE C 281 13.766 10.673 -5.460 1.00 23.68 C
+ATOM 5163 CA ASP C 282 16.431 8.365 -6.934 1.00 26.58 C
+ATOM 5171 CA ASP C 283 16.211 10.530 -10.054 1.00 28.70 C
+ATOM 5179 CA ILE C 284 17.089 13.937 -8.538 1.00 27.28 C
+ATOM 5187 CA MET C 285 19.706 12.222 -6.388 1.00 27.45 C
+ATOM 5195 CA VAL C 286 21.377 10.712 -9.470 1.00 30.74 C
+ATOM 5202 CA SER C 287 21.619 14.159 -11.061 1.00 32.14 C
+ATOM 5208 CA LEU C 288 23.240 15.463 -7.873 1.00 34.20 C
+ATOM 5216 CA ALA C 289 25.801 12.653 -7.874 1.00 40.16 C
+ATOM 5221 CA GLU C 290 26.837 12.825 -11.536 1.00 41.84 C
+ATOM 5230 CA LYS C 291 27.855 16.387 -10.793 1.00 43.17 C
+ATOM 5239 CA ASP C 292 30.299 15.115 -8.139 1.00 41.84 C
+ATOM 5247 CA GLY C 293 31.237 12.232 -10.420 1.00 46.12 C
+ATOM 5251 CA ILE C 294 30.053 9.669 -7.864 1.00 45.54 C
+ATOM 5259 CA ASP C 295 27.399 6.998 -8.480 1.00 41.14 C
+ATOM 5267 CA TRP C 296 24.222 7.605 -6.479 1.00 30.67 C
+ATOM 5281 CA PHE C 297 23.381 3.910 -6.151 1.00 31.97 C
+ATOM 5292 CA ASP C 298 26.856 2.916 -4.907 1.00 38.12 C
+ATOM 5300 CA TYR C 299 26.671 5.875 -2.540 1.00 39.05 C
+ATOM 5312 CA LYS C 300 23.196 4.971 -1.294 1.00 41.63 C
+ATOM 5321 CA LYS C 301 24.542 1.489 -0.577 1.00 43.40 C
+ATOM 5330 CA GLN C 302 27.207 3.064 1.608 1.00 43.79 C
+ATOM 5339 CA LEU C 303 24.476 5.181 3.238 1.00 41.51 C
+ATOM 5347 CA LYS C 304 22.138 2.343 4.264 1.00 45.18 C
+ATOM 5356 CA ARG C 305 25.322 0.535 5.256 1.00 46.65 C
+ATOM 5367 CA GLY C 306 25.613 3.181 7.945 1.00 40.29 C
+ATOM 5371 CA ASP C 307 21.954 3.487 8.940 1.00 41.21 C
+ATOM 5379 CA GLN C 308 21.463 6.730 7.023 1.00 35.55 C
+ATOM 5388 CA TRP C 309 18.961 5.674 4.361 1.00 31.22 C
+ATOM 5402 CA ASN C 310 16.018 3.728 5.752 1.00 31.61 C
+ATOM 5410 CA VAL C 311 13.120 2.841 3.452 1.00 32.13 C
+ATOM 5417 CA GLU C 312 9.705 1.332 4.261 1.00 31.51 C
+ATOM 5426 CA VAL C 313 7.466 1.606 1.209 1.00 26.39 C
+ATOM 5433 CA TYR C 314 4.403 -0.343 0.111 1.00 25.42 C
-(((FER_BRANA:128.0,FER3_RAPSA:128.0):50.75,FER_CAPAA:178.75):121.94443,(Q93Z60_ARATH:271.45456,((O80429_MAIZE:183.0,FER1_MAIZE:183.0):30.5,((Q7XA98_TRIPR:90.0,FER1_PEA:90.0):83.32143,(((FER2_ARATH:64.0,FER1_ARATH:64.0):94.375,(FER1_SPIOL:124.5,FER1_MESCR:124.5):33.875):6.4166718,((Q93XJ9_SOLTU:33.5,FER1_SOLLC:33.5):49.0,FER_CAPAN:82.5):82.29167):8.529755):40.178574):57.95456):29.239868);\r
+(((FER_BRANA:128.0,FER3_RAPSA:128.0):50.75,FER_CAPAA:178.75):121.94443,(Q93Z60_ARATH:271.45456,((O80429_MAIZE:183.0,FER1_MAIZE:183.0):30.5,((Q7XA98_TRIPR:90.0,FER1_PEA:90.0):83.32143,(((FER2_ARATH:64.0,FER1_ARATH:64.0):94.375,(FER1_SPIOL:124.5,FER1_MESCR:124.5):33.875):6.4166718,((Q93XJ9_SOLTU:33.5,FER1_SOLLC:33.5):49.0,FER_CAPAN:82.5):82.29167):8.529755):40.178574):57.95456):29.239868);
-/**\r
- * Copyright 2010 Tim Down.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
+/**
+ * Copyright 2010 Tim Down.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
var Hashtable=(function(){var p="function";var n=(typeof Array.prototype.splice==p)?function(s,r){s.splice(r,1)}:function(u,t){var s,v,r;if(t===u.length-1){u.length=t}else{s=u.slice(t+1);u.length=t;for(v=0,r=s.length;v<r;++v){u[t+v]=s[v]}}};function a(t){var r;if(typeof t=="string"){return t}else{if(typeof t.hashCode==p){r=t.hashCode();return(typeof r=="string")?r:a(r)}else{if(typeof t.toString==p){return t.toString()}else{try{return String(t)}catch(s){return Object.prototype.toString.call(t)}}}}}function g(r,s){return r.equals(s)}function e(r,s){return(typeof s.equals==p)?s.equals(r):(r===s)}function c(r){return function(s){if(s===null){throw new Error("null is not a valid "+r)}else{if(typeof s=="undefined"){throw new Error(r+" must not be undefined")}}}}var q=c("key"),l=c("value");function d(u,s,t,r){this[0]=u;this.entries=[];this.addEntry(s,t);if(r!==null){this.getEqualityFunction=function(){return r}}}var h=0,j=1,f=2;function o(r){return function(t){var s=this.entries.length,v,u=this.getEqualityFunction(t);while(s--){v=this.entries[s];if(u(t,v[0])){switch(r){case h:return true;case j:return v;case f:return[s,v[1]]}}}return false}}function k(r){return function(u){var v=u.length;for(var t=0,s=this.entries.length;t<s;++t){u[v+t]=this.entries[t][r]}}}d.prototype={getEqualityFunction:function(r){return(typeof r.equals==p)?g:e},getEntryForKey:o(j),getEntryAndIndexForKey:o(f),removeEntryForKey:function(s){var r=this.getEntryAndIndexForKey(s);if(r){n(this.entries,r[0]);return r[1]}return null},addEntry:function(r,s){this.entries[this.entries.length]=[r,s]},keys:k(0),values:k(1),getEntries:function(s){var u=s.length;for(var t=0,r=this.entries.length;t<r;++t){s[u+t]=this.entries[t].slice(0)}},containsKey:o(h),containsValue:function(s){var r=this.entries.length;while(r--){if(s===this.entries[r][1]){return true}}return false}};function m(s,t){var r=s.length,u;while(r--){u=s[r];if(t===u[0]){return r}}return null}function i(r,s){var t=r[s];return(t&&(t instanceof d))?t:null}function b(t,r){var w=this;var v=[];var u={};var x=(typeof t==p)?t:a;var s=(typeof r==p)?r:null;this.put=function(B,C){q(B);l(C);var D=x(B),E,A,z=null;E=i(u,D);if(E){A=E.getEntryForKey(B);if(A){z=A[1];A[1]=C}else{E.addEntry(B,C)}}else{E=new d(D,B,C,s);v[v.length]=E;u[D]=E}return z};this.get=function(A){q(A);var B=x(A);var C=i(u,B);if(C){var z=C.getEntryForKey(A);if(z){return z[1]}}return null};this.containsKey=function(A){q(A);var z=x(A);var B=i(u,z);return B?B.containsKey(A):false};this.containsValue=function(A){l(A);var z=v.length;while(z--){if(v[z].containsValue(A)){return true}}return false};this.clear=function(){v.length=0;u={}};this.isEmpty=function(){return !v.length};var y=function(z){return function(){var A=[],B=v.length;while(B--){v[B][z](A)}return A}};this.keys=y("keys");this.values=y("values");this.entries=y("getEntries");this.remove=function(B){q(B);var C=x(B),z,A=null;var D=i(u,C);if(D){A=D.removeEntryForKey(B);if(A!==null){if(!D.entries.length){z=m(v,C);n(v,z);delete u[C]}}}return A};this.size=function(){var A=0,z=v.length;while(z--){A+=v[z].entries.length}return A};this.each=function(C){var z=w.entries(),A=z.length,B;while(A--){B=z[A];C(B[0],B[1])}};this.putAll=function(H,C){var B=H.entries();var E,F,D,z,A=B.length;var G=(typeof C==p);while(A--){E=B[A];F=E[0];D=E[1];if(G&&(z=w.get(F))){D=C(F,z,D)}w.put(F,D)}};this.clone=function(){var z=new b(t,r);z.putAll(w);return z}}return b})();
\ No newline at end of file
-/* Jmol 12.0 script library Jmol.js 9:48 PM 1/31/2011 Bob Hanson\r
-\r
- checkbox heirarchy -- see http://chemapps.stolaf.edu/jmol/docs/examples-11/check.htm\r
-\r
- based on:\r
- *\r
- * Copyright (C) 2004-2005 Miguel, Jmol Development, www.jmol.org\r
- *\r
- * Contact: hansonr@stolaf.edu\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\r
- * 02111-1307 USA.\r
- */\r
-\r
-// for documentation see www.jmol.org/jslibrary\r
-\r
-try{if(typeof(_jmol)!="undefined")exit()\r
-\r
-// place "?NOAPPLET" on your command line to check applet control action with a textarea\r
-// place "?JMOLJAR=xxxxx" to use a specific jar file\r
-\r
-// bob hanson -- jmolResize(w,h) -- resizes absolutely or by percent (w or h 0.5 means 50%)\r
-// angel herraez -- update of jmolResize(w,h,targetSuffix) so it is not tied to first applet\r
-// bob hanson -- jmolEvaluate -- evaluates molecular math 8:37 AM 2/23/2007\r
-// bob hanson -- jmolScriptMessage -- returns all "scriptStatus" messages 8:37 AM 2/23/2007\r
-// bob hanson -- jmolScriptEcho -- returns all "scriptEcho" messages 8:37 AM 2/23/2007\r
-// bob hanson -- jmolScriptWait -- 11:31 AM 5/2/2006\r
-// bob hanson -- remove trailing separatorHTML in radio groups -- 12:18 PM 5/6/2006\r
-// bob hanson -- adds support for dynamic DOM script nodes 7:04 AM 5/19/2006\r
-// bob hanson -- adds try/catch for wiki - multiple code passes 7:05 AM 5/19/2006\r
-// bob hanson -- auto-initiates to defaultdir/defaultjar -- change as desired.\r
-// bob hanson -- adding save/restore orientation w/ and w/o delay 11:49 AM 5/25/2006\r
-// bob hanson -- adding AjaxJS service 11:16 AM 6/3/2006\r
-// bob hanson -- fix for iframes not available for finding applet\r
-// bob hanson -- added applet fake ?NOAPPLET URL flag\r
-// bob hanson -- added jmolSetCallback(calbackName, funcName) 3:32 PM 6/13/2006\r
-// used PRIOR to jmolApplet() or jmolAppletInline()\r
-// added 4th array element in jmolRadioGroup -- title\r
-// added <span> and id around link, checkbox, radio, menu\r
-// fixing AJAX loads for MSIE/Opera-Mozilla incompatibility\r
-// -- renamed Jmol-11.js from Jmol-new.js; JmolApplet.jar from JmolAppletProto.jar\r
-// renamed Jmol.js for Jmol 11 distribution\r
-// -- modified jmolRestoreOrientation() to be immediate, no 1-second delay\r
-// bob hanson -- jmolScriptWait always returns a string -- 11:23 AM 9/16/2006\r
-// bh -- jmolCommandInput()\r
-// bh -- jmolSetTranslation(TF) -- forces translation even if there might be message callback issues\r
-// bh -- minor fixes suggested by Angel\r
-// bh -- adds jmolSetSyncId() and jmolGetSyncId()\r
-// bh 3/2008 -- adds jmolAppendInlineScript() and jmolAppendInlineArray()\r
-// bh 3/2008 -- fixes IE7 bug in relation to jmolLoadInlineArray()\r
-// bh 6/2008 -- adds jmolSetAppletWindow()\r
-// Angel H. 6/2008 -- added html <label> tags to checkboxes and radio buttons [in jmolCheckbox() and _jmolRadio() functions]\r
-// bh 7/2008 -- code fix "for(i..." not "for(var i..."\r
-// bh 12/2008 -- jmolLoadInline, jmolLoadInlineArray, jmolLoadInlineScript, jmolAppendInlineScript, jmolAppendInlineArray all return error message or null (Jmol 11.7.16)\r
-// bh 12/2008 -- jmolScriptWaitOutput() -- waits for script to complete and delivers output normally sent to console\r
-\r
-// bh 5/2009 -- Support for XHTML using jmolSetXHTML(id)\r
-// ah & bh 6/2009 -- New jmolResizeApplet() more flexible, similar to jmolApplet() size syntax\r
-// bh 11/2009 -- care in accessing top.document\r
-// bh 12/2009 -- added jmolSetParameter(name, value)\r
-// bh 12/2009 -- added PARAMS=name:value;name:value;name:value... for command line\r
-// bh 12/2009 -- overhaul of target checking\r
-// bh 1/2010 -- all _xxxx() methods ALWAYS have complete argument list\r
-// bh 1/2010 -- adds option to run a JavaScript function from any Jmol control. \r
-// This is accomplished by passing an array rather than a script:\r
-// jmolHref([myfunc,"my param 1", "my param 2"], "testing")\r
-// function myfunc(jmolControlObject, [myfunc,"my param 1", "my param 2"], target){...}\r
-// and allows much more flexibility with responding to controls\r
-// bh 4/2010 -- added jmolSetMemoryMb(nMb)\r
-// ah 1/2011 -- wider detection of browsers; more browsers now use the object tag instead of the applet tag; \r
-// fix of object tag (removed classid) accounts for change of behavior in Chrome\r
-// bh 3/2011 -- added jmolLoadAjax_STOLAF_NIH\r
-\r
-var defaultdir = "."\r
-var defaultjar = "JmolApplet.jar"\r
-\r
-\r
-// Note added 12:41 PM 9/21/2008 by Bob Hanson, hansonr@stolaf.edu:\r
-\r
-// JMOLJAR=xxxxx.jar on the URL for this page will override\r
-// the JAR file specified in the jmolInitialize() call.\r
-\r
-// The idea is that it can be very useful to test a web page with different JAR files\r
-// Or for an expert user to substitute a signed applet for an unsigned one\r
-// so as to use a broader range of models or to create JPEG files, for example.\r
-\r
-// If the JAR file is not in the current directory (has any sort of "/" in its name)\r
-// then the user is presented with a warning and asked whether it is OK to change Jar files.\r
-// The default action, if the user just presses "OK" is to NOT allow the change. \r
-// The user must type the word "yes" in the prompt box for the change to be approved.\r
-\r
-// If you don't want people to be able to switch in their own JAR file on your page,\r
-// simply set this next line to read "var allowJMOLJAR = false".\r
-\r
-\r
-var undefined; // for IE 5 ... wherein undefined is undefined\r
-\r
-////////////////////////////////////////////////////////////////\r
-// Basic Scripting infrastruture\r
-////////////////////////////////////////////////////////////////\r
-\r
-function jmolInitialize(codebaseDirectory, fileNameOrUseSignedApplet) {\r
- if (_jmol.initialized)\r
- return;\r
- _jmol.initialized = true;\r
- if(_jmol.jmoljar) {\r
- var f = _jmol.jmoljar;\r
- if (f.indexOf("/") >= 0) {\r
- alert ("This web page URL is requesting that the applet used be " + f + ". This is a possible security risk, particularly if the applet is signed, because signed applets can read and write files on your local machine or network.")\r
- var ok = prompt("Do you want to use applet " + f + "? ","yes or no")\r
- if (ok == "yes") {\r
- codebaseDirectory = f.substring(0, f.lastIndexOf("/"));\r
- fileNameOrUseSignedApplet = f.substring(f.lastIndexOf("/") + 1);\r
- } else {\r
- _jmolGetJarFilename(fileNameOrUseSignedApplet);\r
- alert("The web page URL was ignored. Continuing using " + _jmol.archivePath + ' in directory "' + codebaseDirectory + '"');\r
- }\r
- } else {\r
- fileNameOrUseSignedApplet = f;\r
- }\r
- }\r
- _jmolSetCodebase(codebaseDirectory);\r
- _jmolGetJarFilename(fileNameOrUseSignedApplet);\r
- _jmolOnloadResetForms();\r
-}\r
-\r
-function jmolSetTranslation(TF) {\r
- _jmol.params.doTranslate = ''+TF;\r
-}\r
-\r
-function _jmolGetJarFilename(fileNameOrFlag) {\r
- _jmol.archivePath =\r
- (typeof(fileNameOrFlag) == "string" ? fileNameOrFlag : (fileNameOrFlag ? "JmolAppletSigned" : "JmolApplet") + "0.jar");\r
-}\r
-\r
-function jmolSetDocument(doc) {\r
- _jmol.currentDocument = doc;\r
-}\r
-\r
-function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) {\r
- _jmolInitCheck();\r
- _jmol.params.boxbgcolor = boxbgcolor;\r
- if (boxfgcolor)\r
- _jmol.params.boxfgcolor = boxfgcolor\r
- else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF")\r
- _jmol.params.boxfgcolor = "black";\r
- else\r
- _jmol.params.boxfgcolor = "white";\r
- if (progresscolor)\r
- _jmol.params.progresscolor = progresscolor;\r
- if (_jmol.debugAlert)\r
- alert(" boxbgcolor=" + _jmol.params.boxbgcolor +\r
- " boxfgcolor=" + _jmol.params.boxfgcolor +\r
- " progresscolor=" + _jmol.params.progresscolor);\r
-}\r
-\r
-function jmolSetAppletWindow(w) {\r
- _jmol.appletWindow = w;\r
-}\r
-\r
-function jmolApplet(size, script, nameSuffix) {\r
- _jmolInitCheck();\r
- return _jmolApplet(size, null, script, nameSuffix);\r
-}\r
-\r
-////////////////////////////////////////////////////////////////\r
-// Basic controls\r
-////////////////////////////////////////////////////////////////\r
-\r
-// undefined means it wasn't there; null means it was explicitly listed as null (so as to skip it)\r
-\r
-function jmolButton(script, label, id, title) {\r
- _jmolInitCheck();\r
- id != undefined && id != null || (id = "jmolButton" + _jmol.buttonCount);\r
- label != undefined && label != null || (label = script.substring(0, 32));\r
- ++_jmol.buttonCount;\r
- var scriptIndex = _jmolAddScript(script);\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='button' name='" + id + "' id='" + id +\r
- "' value='" + label +\r
- "' onclick='_jmolClick(this," + scriptIndex + _jmol.targetText +\r
- ")' onmouseover='_jmolMouseOver(" + scriptIndex +\r
- ");return true' onmouseout='_jmolMouseOut()' " +\r
- _jmol.buttonCssText + " /></span>";\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked,\r
- labelHtml, isChecked, id, title) {\r
- _jmolInitCheck();\r
- id != undefined && id != null || (id = "jmolCheckbox" + _jmol.checkboxCount);\r
- ++_jmol.checkboxCount;\r
- if (scriptWhenChecked == undefined || scriptWhenChecked == null ||\r
- scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) {\r
- alert("jmolCheckbox requires two scripts");\r
- return;\r
- }\r
- if (labelHtml == undefined || labelHtml == null) {\r
- alert("jmolCheckbox requires a label");\r
- return;\r
- }\r
- var indexChecked = _jmolAddScript(scriptWhenChecked);\r
- var indexUnchecked = _jmolAddScript(scriptWhenUnchecked);\r
- var eospan = "</span>"\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='checkbox' name='" + id + "' id='" + id +\r
- "' onclick='_jmolCbClick(this," +\r
- indexChecked + "," + indexUnchecked + _jmol.targetText +\r
- ")' onmouseover='_jmolCbOver(this," + indexChecked + "," +\r
- indexUnchecked +\r
- ");return true' onmouseout='_jmolMouseOut()' " +\r
- (isChecked ? "checked='true' " : "")+ _jmol.checkboxCssText + " />" \r
- if (labelHtml.toLowerCase().indexOf("<td>")>=0) {\r
- t += eospan\r
- eospan = "";\r
- }\r
- t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan;\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-function jmolStartNewRadioGroup() {\r
- ++_jmol.radioGroupCount;\r
-}\r
-\r
-function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName, id, title) {\r
- /*\r
-\r
- array: [radio1,radio2,radio3...]\r
- where radioN = ["script","label",isSelected,"id","title"]\r
-\r
- */\r
-\r
- _jmolInitCheck();\r
- var type = typeof arrayOfRadioButtons;\r
- if (type != "object" || type == null || ! arrayOfRadioButtons.length) {\r
- alert("invalid arrayOfRadioButtons");\r
- return;\r
- }\r
- separatorHtml != undefined && separatorHtml != null || (separatorHtml = " ");\r
- var len = arrayOfRadioButtons.length;\r
- jmolStartNewRadioGroup();\r
- groupName || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));\r
- var t = "<span id='"+(id ? id : groupName)+"'>";\r
- for (var i = 0; i < len; ++i) {\r
- if (i == len - 1)\r
- separatorHtml = "";\r
- var radio = arrayOfRadioButtons[i];\r
- type = typeof radio;\r
- if (type == "object") {\r
- t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName, (radio.length > 3 ? radio[3]: (id ? id : groupName)+"_"+i), (radio.length > 4 ? radio[4] : 0), title);\r
- } else {\r
- t += _jmolRadio(radio, null, null, separatorHtml, groupName, (id ? id : groupName)+"_"+i, title);\r
- }\r
- }\r
- t+="</span>"\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-\r
-function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {\r
- _jmolInitCheck();\r
- if (_jmol.radioGroupCount == 0)\r
- ++_jmol.radioGroupCount;\r
- var t = _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, (id ? id : groupName + "_" + _jmol.radioCount), title ? title : 0);\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-function jmolLink(script, label, id, title) {\r
- _jmolInitCheck();\r
- id != undefined && id != null || (id = "jmolLink" + _jmol.linkCount);\r
- label != undefined && label != null || (label = script.substring(0, 32));\r
- ++_jmol.linkCount;\r
- var scriptIndex = _jmolAddScript(script);\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><a name='" + id + "' id='" + id + \r
- "' href='javascript:_jmolClick(this," + scriptIndex + _jmol.targetText + ");' onmouseover='_jmolMouseOver(" + scriptIndex +\r
- ");return true;' onmouseout='_jmolMouseOut()' " +\r
- _jmol.linkCssText + ">" + label + "</a></span>";\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-function jmolCommandInput(label, size, id, title) {\r
- _jmolInitCheck();\r
- id != undefined && id != null || (id = "jmolCmd" + _jmol.cmdCount);\r
- label != undefined && label != null || (label = "Execute");\r
- size != undefined && !isNaN(size) || (size = 60);\r
- ++_jmol.cmdCount;\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='" + id + "' id='" + id + \r
- "' size='"+size+"' onkeypress='_jmolCommandKeyPress(event,\""+id+"\"" + _jmol.targetText + ")'><input type=button value = '"+label+"' onclick='jmolScript(document.getElementById(\""+id+"\").value" + _jmol.targetText + ")' /></span>";\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-function _jmolCommandKeyPress(e, id, target) {\r
- var keycode = (window.event ? window.event.keyCode : e ? e.which : 0);\r
- if (keycode == 13) {\r
- var inputBox = document.getElementById(id)\r
- _jmolScriptExecute(inputBox, inputBox.value, target)\r
- }\r
-}\r
-\r
-function _jmolScriptExecute(element,script,target) {\r
- if (typeof(script) == "object")\r
- script[0](element, script, target)\r
- else\r
- jmolScript(script, target) \r
-}\r
-\r
-function jmolMenu(arrayOfMenuItems, size, id, title) {\r
- _jmolInitCheck();\r
- id != undefined && id != null || (id = "jmolMenu" + _jmol.menuCount);\r
- ++_jmol.menuCount;\r
- var type = typeof arrayOfMenuItems;\r
- if (type != null && type == "object" && arrayOfMenuItems.length) {\r
- var len = arrayOfMenuItems.length;\r
- if (typeof size != "number" || size == 1)\r
- size = null;\r
- else if (size < 0)\r
- size = len;\r
- var sizeText = size ? " size='" + size + "' " : "";\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><select name='" + id + "' id='" + id +\r
- "' onChange='_jmolMenuSelected(this" + _jmol.targetText + ")'" +\r
- sizeText + _jmol.menuCssText + ">";\r
- for (var i = 0; i < len; ++i) {\r
- var menuItem = arrayOfMenuItems[i];\r
- type = typeof menuItem;\r
- var script, text;\r
- var isSelected = undefined;\r
- if (type == "object" && menuItem != null) {\r
- script = menuItem[0];\r
- text = menuItem[1];\r
- isSelected = menuItem[2];\r
- } else {\r
- script = text = menuItem;\r
- }\r
- text != undefined && text != null || (text = script); \r
- if (script=="#optgroup") {\r
- t += "<optgroup label='" + text + "'>"; \r
- } else if (script=="#optgroupEnd") {\r
- t += "</optgroup>"; \r
- } else { \r
- var scriptIndex = _jmolAddScript(script);\r
- var selectedText = isSelected ? "' selected='true'>" : "'>";\r
- t += "<option value='" + scriptIndex + selectedText + text + "</option>";\r
- }\r
- }\r
- t += "</select></span>";\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
- }\r
-}\r
-\r
-function jmolHtml(html) {\r
- return _jmolDocumentWrite(html);\r
-}\r
-\r
-function jmolBr() {\r
- return _jmolDocumentWrite("<br />");\r
-}\r
-\r
-////////////////////////////////////////////////////////////////\r
-// advanced scripting functions\r
-////////////////////////////////////////////////////////////////\r
-\r
-function jmolDebugAlert(enableAlerts) {\r
- _jmol.debugAlert = (enableAlerts == undefined || enableAlerts)\r
-}\r
-\r
-function jmolAppletInline(size, inlineModel, script, nameSuffix) {\r
- _jmolInitCheck();\r
- return _jmolApplet(size, _jmolSterilizeInline(inlineModel),\r
- script, nameSuffix);\r
-}\r
-\r
-function jmolSetTarget(targetSuffix) {\r
- _jmol.targetSuffix = targetSuffix;\r
- _jmol.targetText = targetSuffix ? ",\"" + targetSuffix + "\"" : ",0";\r
-}\r
-\r
-function jmolScript(script, targetSuffix) {\r
- if (script) {\r
- _jmolCheckBrowser();\r
- if (targetSuffix == "all") {\r
- with (_jmol) {\r
- for (var i = 0; i < appletSuffixes.length; ++i) {\r
- var applet = _jmolGetApplet(appletSuffixes[i]);\r
- if (applet) applet.script(script);\r
- }\r
- }\r
- } else {\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (applet) applet.script(script);\r
- }\r
- }\r
-}\r
-\r
-function jmolLoadInline(model, targetSuffix) {\r
- if (!model)return "ERROR: NO MODEL"\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (!applet)return "ERROR: NO APPLET"\r
- if (typeof(model) == "string")\r
- return applet.loadInlineString(model, "", false);\r
- else\r
- return applet.loadInlineArray(model, "", false);\r
-}\r
-\r
-\r
-function jmolLoadInlineScript(model, script, targetSuffix) {\r
- if (!model)return "ERROR: NO MODEL"\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (!applet)return "ERROR: NO APPLET"\r
- return applet.loadInlineString(model, script, false);\r
-}\r
-\r
-\r
-function jmolLoadInlineArray(ModelArray, script, targetSuffix) {\r
- if (!model)return "ERROR: NO MODEL"\r
- script || (script="")\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (!applet)return "ERROR: NO APPLET"\r
- try {\r
- return applet.loadInlineArray(ModelArray, script, false);\r
- } catch (err) {\r
- //IE 7 bug\r
- return applet.loadInlineString(ModelArray.join("\n"), script, false);\r
- }\r
-}\r
-\r
-function jmolAppendInlineArray(ModelArray, script, targetSuffix) {\r
- if (!model)return "ERROR: NO MODEL"\r
- script || (script="")\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (!applet)return "ERROR: NO APPLET"\r
- try {\r
- return applet.loadInlineArray(ModelArray, script, true);\r
- } catch (err) {\r
- //IE 7 bug\r
- return applet.loadInlineString(ModelArray.join("\n"), script, true);\r
- }\r
-}\r
-\r
-function jmolAppendInlineScript(model, script, targetSuffix) {\r
- if (!model)return "ERROR: NO MODEL"\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (!applet)return "ERROR: NO APPLET"\r
- return applet.loadInlineString(model, script, true);\r
-}\r
-\r
-function jmolCheckBrowser(action, urlOrMessage, nowOrLater) {\r
- if (typeof action == "string") {\r
- action = action.toLowerCase();\r
- action == "alert" || action == "redirect" || action == "popup" || (action = null);\r
- }\r
- if (typeof action != "string")\r
- alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +\r
- "action must be 'alert', 'redirect', or 'popup'");\r
- else {\r
- if (typeof urlOrMessage != "string")\r
- alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +\r
- "urlOrMessage must be a string");\r
- else {\r
- _jmol.checkBrowserAction = action;\r
- _jmol.checkBrowserUrlOrMessage = urlOrMessage;\r
- }\r
- }\r
- if (typeof nowOrLater == "string" && nowOrLater.toLowerCase() == "now")\r
- _jmolCheckBrowser();\r
-}\r
-\r
-////////////////////////////////////////////////////////////////\r
-// Cascading Style Sheet Class support\r
-////////////////////////////////////////////////////////////////\r
-\r
-function jmolSetAppletCssClass(appletCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.appletCssClass = appletCssClass;\r
- _jmol.appletCssText = appletCssClass ? "class='" + appletCssClass + "' " : "";\r
- }\r
-}\r
-\r
-function jmolSetButtonCssClass(buttonCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.buttonCssClass = buttonCssClass;\r
- _jmol.buttonCssText = buttonCssClass ? "class='" + buttonCssClass + "' " : "";\r
- }\r
-}\r
-\r
-function jmolSetCheckboxCssClass(checkboxCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.checkboxCssClass = checkboxCssClass;\r
- _jmol.checkboxCssText = checkboxCssClass ? "class='" + checkboxCssClass + "' " : "";\r
- }\r
-}\r
-\r
-function jmolSetRadioCssClass(radioCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.radioCssClass = radioCssClass;\r
- _jmol.radioCssText = radioCssClass ? "class='" + radioCssClass + "' " : "";\r
- }\r
-}\r
-\r
-function jmolSetLinkCssClass(linkCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.linkCssClass = linkCssClass;\r
- _jmol.linkCssText = linkCssClass ? "class='" + linkCssClass + "' " : "";\r
- }\r
-}\r
-\r
-function jmolSetMenuCssClass(menuCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.menuCssClass = menuCssClass;\r
- _jmol.menuCssText = menuCssClass ? "class='" + menuCssClass + "' " : "";\r
- }\r
-}\r
-\r
-////////////////////////////////////////////////////////////////\r
-// functions for INTERNAL USE ONLY which are subject to change\r
-// use at your own risk ... you have been WARNED!\r
-////////////////////////////////////////////////////////////////\r
-var _jmol = {\r
- currentDocument: document,\r
-\r
- debugAlert: false,\r
- \r
- codebase: "",\r
- modelbase: ".",\r
- \r
- appletCount: 0,\r
- appletSuffixes: [],\r
- appletWindow: null,\r
- allowedJmolSize: [25, 2048, 300], // min, max, default (pixels)\r
- /* By setting the _jmol.allowedJmolSize[] variable in the webpage \r
- before calling jmolApplet(), limits for applet size can be overriden.\r
- 2048 standard for GeoWall (http://geowall.geo.lsa.umich.edu/home.html)\r
- */ \r
- buttonCount: 0,\r
- checkboxCount: 0,\r
- linkCount: 0,\r
- cmdCount: 0,\r
- menuCount: 0,\r
- radioCount: 0,\r
- radioGroupCount: 0,\r
- \r
- appletCssClass: null,\r
- appletCssText: "",\r
- buttonCssClass: null,\r
- buttonCssText: "",\r
- checkboxCssClass: null,\r
- checkboxCssText: "",\r
- java_arguments: "-Xmx512m",\r
- radioCssClass: null,\r
- radioCssText: "",\r
- linkCssClass: null,\r
- linkCssText: "",\r
- menuCssClass: null,\r
- menuCssText: "",\r
- \r
- targetSuffix: 0,\r
- targetText: ",0",\r
- scripts: [""],\r
- params: {\r
- syncId: ("" + Math.random()).substring(3),\r
- progressbar: "true",\r
- progresscolor: "blue",\r
- boxbgcolor: "black",\r
- boxfgcolor: "white",\r
- boxmessage: "Downloading JmolApplet ..."\r
- },\r
- ua: navigator.userAgent.toLowerCase(),\r
- // uaVersion: parseFloat(navigator.appVersion), // not used\r
- \r
- os: "unknown",\r
- browser: "unknown",\r
- browserVersion: 0,\r
- hasGetElementById: !!document.getElementById,\r
- isJavaEnabled: navigator.javaEnabled(),\r
- // isNetscape47Win: false, // not used, N4.7 is no longer supported even for detection\r
- useIEObject: false,\r
- useHtml4Object: false,\r
- \r
- windowsClassId: "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93",\r
- windowsCabUrl:\r
- "http://java.sun.com/update/1.6.0/jinstall-6u22-windows-i586.cab",\r
-\r
- isBrowserCompliant: false,\r
- isJavaCompliant: false,\r
- isFullyCompliant: false,\r
-\r
- initialized: false,\r
- initChecked: false,\r
- \r
- browserChecked: false,\r
- checkBrowserAction: "alert",\r
- checkBrowserUrlOrMessage: null,\r
-\r
- archivePath: null, // JmolApplet0.jar OR JmolAppletSigned0.jar\r
-\r
- previousOnloadHandler: null,\r
-\r
- jmoljar: null, \r
- useNoApplet: false,\r
-\r
- ready: {}\r
-}\r
-\r
-with (_jmol) {\r
- function _jmolTestUA(candidate) {\r
- var ua = _jmol.ua;\r
- var index = ua.indexOf(candidate);\r
- if (index < 0)\r
- return false;\r
- _jmol.browser = candidate;\r
- _jmol.browserVersion = parseFloat(ua.substring(index+candidate.length+1));\r
- return true;\r
- }\r
- \r
- function _jmolTestOS(candidate) {\r
- if (_jmol.ua.indexOf(candidate) < 0)\r
- return false;\r
- _jmol.os = candidate;\r
- return true;\r
- }\r
- \r
- _jmolTestUA("konqueror") ||\r
- _jmolTestUA("webkit") ||\r
- _jmolTestUA("omniweb") ||\r
- _jmolTestUA("opera") ||\r
- _jmolTestUA("webtv") ||\r
- _jmolTestUA("icab") ||\r
- _jmolTestUA("msie") ||\r
- (_jmol.ua.indexOf("compatible") < 0 && _jmolTestUA("mozilla")); //Netscape, Mozilla, Seamonkey, Firefox and anything assimilated\r
- \r
- _jmolTestOS("linux") ||\r
- _jmolTestOS("unix") ||\r
- _jmolTestOS("mac") ||\r
- _jmolTestOS("win");\r
-\r
- /* not used:\r
- isNetscape47Win = (os == "win" && browser == "mozilla" &&\r
- browserVersion >= 4.78 && browserVersion <= 4.8);\r
- */\r
-\r
- if (os == "win") {\r
- isBrowserCompliant = hasGetElementById;\r
- } else if (os == "mac") { // mac is the problem child :-(\r
- if (browser == "mozilla" && browserVersion >= 5) {\r
- // miguel 2004 11 17\r
- // checking the plugins array does not work because\r
- // Netscape 7.2 OS X still has Java 1.3.1 listed even though\r
- // javaplugin.sf.net is installed to upgrade to 1.4.2\r
- eval("try {var v = java.lang.System.getProperty('java.version');" +\r
- " _jmol.isBrowserCompliant = v >= '1.4.2';" +\r
- " } catch (e) { }");\r
- } else if (browser == "opera" && browserVersion <= 7.54) {\r
- isBrowserCompliant = false;\r
- } else {\r
- isBrowserCompliant = hasGetElementById &&\r
- !((browser == "msie") ||\r
- (browser == "webkit" && browserVersion < 125.12));\r
- }\r
- } else if (os == "linux" || os == "unix") {\r
- if (browser == "konqueror" && browserVersion <= 3.3)\r
- isBrowserCompliant = false;\r
- else\r
- isBrowserCompliant = hasGetElementById;\r
- } else { // other OS\r
- isBrowserCompliant = hasGetElementById;\r
- }\r
-\r
- // possibly more checks in the future for this\r
- isJavaCompliant = isJavaEnabled;\r
-\r
- isFullyCompliant = isBrowserCompliant && isJavaCompliant;\r
-\r
- useIEObject = (os == "win" && browser == "msie" && browserVersion >= 5.5);\r
- useHtml4Object =\r
- (browser == "mozilla" && browserVersion >= 5) ||\r
- (browser == "opera" && browserVersion >= 8) ||\r
- (browser == "webkit" && browserVersion >= 412.2);\r
- try {\r
- if (top.location.search.indexOf("JMOLJAR=")>=0)\r
- jmoljar = top.location.search.split("JMOLJAR=")[1].split("&")[0];\r
- } catch(e) {\r
- // can't access top.location\r
- }\r
- try {\r
- useNoApplet = (top.location.search.indexOf("NOAPPLET")>=0);\r
- } catch(e) {\r
- // can't access top.document\r
- }\r
-}\r
-\r
-function jmolSetMemoryMb(nMb) {\r
- _jmol.java_arguments = "-Xmx" + Math.round(nMb) + "m"\r
-}\r
-\r
-function jmolSetParameter(name,value) {\r
- _jmol.params[name] = value\r
-}\r
-\r
-function jmolSetCallback(callbackName,funcName) {\r
- _jmol.params[callbackName] = funcName\r
-}\r
-\r
- try {\r
-// note this is done FIRST, so it cannot override a setting done by the developer\r
- if (top.location.search.indexOf("PARAMS=")>=0) {\r
- var pars = unescape(top.location.search.split("PARAMS=")[1].split("&")[0]).split(";");\r
- for (var i = 0; i < pars.length; i++) {\r
- var p = pars[i].split(":");\r
- jmolSetParameter(p[0],p[1]);\r
- }\r
- }\r
- } catch(e) {\r
- // can't access top.location\r
- }\r
-\r
-function jmolSetSyncId(n) {\r
- return _jmol.params["syncId"] = n\r
-}\r
-\r
-function jmolGetSyncId() {\r
- return _jmol.params["syncId"]\r
-}\r
-\r
-function jmolSetLogLevel(n) {\r
- _jmol.params.logLevel = ''+n;\r
-}\r
-\r
- /* AngelH, mar2007:\r
- By (re)setting these variables in the webpage before calling jmolApplet(), \r
- a custom message can be provided (e.g. localized for user's language) when no Java is installed.\r
- */\r
-if (noJavaMsg==undefined) var noJavaMsg = \r
- "You do not have Java applets enabled in your web browser, or your browser is blocking this applet.<br />\n" +\r
- "Check the warning message from your browser and/or enable Java applets in<br />\n" +\r
- "your web browser preferences, or install the Java Runtime Environment from <a href='http://www.java.com'>www.java.com</a><br />";\r
-if (noJavaMsg2==undefined) var noJavaMsg2 = \r
- "You do not have the<br />\n" +\r
- "Java Runtime Environment<br />\n" +\r
- "installed for applet support.<br />\n" +\r
- "Visit <a href='http://www.java.com'>www.java.com</a>";\r
-function _jmolApplet(size, inlineModel, script, nameSuffix) {\r
- /* AngelH, mar2007\r
- Fixed percent / pixel business, to avoid browser errors:\r
- put "px" where needed, avoid where not.\r
-\r
- Bob Hanson, 1/2010\r
- Fixed inline escape changing returns to | \r
- */\r
- with (_jmol) {\r
- nameSuffix == undefined && (nameSuffix = appletCount);\r
- appletSuffixes.push(nameSuffix);\r
- ++appletCount;\r
- script || (script = "select *");\r
- var sz = _jmolGetAppletSize(size);\r
- var widthAndHeight = " width='" + sz[0] + "' height='" + sz[1] + "' ";\r
- var tHeader, tFooter;\r
- codebase || jmolInitialize(".");\r
- if (useIEObject || useHtml4Object) {\r
- params.archive = archivePath;\r
- params.mayscript = 'true';\r
- params.codebase = codebase;\r
- params.code = 'JmolApplet';\r
- tHeader = \r
- "<object name='jmolApplet" + nameSuffix +\r
- "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +\r
- widthAndHeight + "\n";\r
- tFooter = "</object>";\r
- }\r
- if (java_arguments)\r
- params.java_arguments = java_arguments;\r
- if (useIEObject) { // use MSFT IE6 object tag with .cab file reference\r
- tHeader += " classid='" + windowsClassId + "'\n" +\r
- (windowsCabUrl ? " codebase='" + windowsCabUrl + "'\n" : "") + ">\n";\r
- } else if (useHtml4Object) { // use HTML4 object tag\r
- tHeader += " type='application/x-java-applet'\n>\n";\r
- /* " classid='java:JmolApplet'\n" + AH removed this\r
- Chromium Issue 62076: Java Applets using an <object> with a classid paramater don't load.\r
- http://code.google.com/p/chromium/issues/detail?id=62076\r
- They say this is the correct behavior according to the spec, and there's no indication at this point \r
- that WebKit will be changing the handling, so eventually Safari will acquire this behavior too.\r
- Removing the classid parameter seems to be well tolerated by all browsers (even IE!).\r
- */\r
- } else { // use applet tag\r
- tHeader = \r
- "<applet name='jmolApplet" + nameSuffix +\r
- "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +\r
- widthAndHeight + "\n" +\r
- " code='JmolApplet'" +\r
- " archive='" + archivePath + "' codebase='" + codebase + "'\n" +\r
- " mayscript='true'>\n";\r
- tFooter = "</applet>";\r
- }\r
- var visitJava;\r
- if (useIEObject || useHtml4Object) {\r
- var szX = "width:" + sz[0]\r
- if ( szX.indexOf("%")==-1 ) szX+="px" \r
- var szY = "height:" + sz[1]\r
- if ( szY.indexOf("%")==-1 ) szY+="px" \r
- visitJava =\r
- "<p style='background-color:yellow; color:black; " +\r
- szX + ";" + szY + ";" +\r
- // why doesn't this vertical-align work?\r
- "text-align:center;vertical-align:middle;'>\n" +\r
- noJavaMsg +\r
- "</p>";\r
- } else {\r
- visitJava =\r
- "<table bgcolor='yellow'><tr>" +\r
- "<td align='center' valign='middle' " + widthAndHeight + "><font color='black'>\n" +\r
- noJavaMsg2 +\r
- "</font></td></tr></table>";\r
- }\r
- params.loadInline = (inlineModel ? inlineModel : "");\r
- params.script = (script ? _jmolSterilizeScript(script) : "");\r
- var t = tHeader + _jmolParams() + visitJava + tFooter;\r
- jmolSetTarget(nameSuffix);\r
- ready["jmolApplet" + nameSuffix] = false;\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
- }\r
-}\r
-\r
-function _jmolParams() {\r
- var t = "";\r
- for (var i in _jmol.params)\r
- if(_jmol.params[i]!="")\r
- t+=" <param name='"+i+"' value='"+_jmol.params[i]+"' />\n";\r
- return t\r
-}\r
-\r
-function _jmolInitCheck() {\r
- if (_jmol.initChecked)\r
- return;\r
- _jmol.initChecked = true;\r
- jmolInitialize(defaultdir, defaultjar)\r
-}\r
-\r
-function _jmolCheckBrowser() {\r
- with (_jmol) {\r
- if (browserChecked)\r
- return;\r
- browserChecked = true;\r
- \r
- if (isFullyCompliant)\r
- return true;\r
-\r
- if (checkBrowserAction == "redirect")\r
- location.href = checkBrowserUrlOrMessage;\r
- else if (checkBrowserAction == "popup")\r
- _jmolPopup(checkBrowserUrlOrMessage);\r
- else {\r
- var msg = checkBrowserUrlOrMessage;\r
- if (msg == null)\r
- msg = "Your web browser is not fully compatible with Jmol\n\n" +\r
- "browser: " + browser +\r
- " version: " + browserVersion +\r
- " os: " + os +\r
- " isBrowserCompliant: " + isBrowserCompliant +\r
- " isJavaCompliant: " + isJavaCompliant +\r
- "\n\n" + ua;\r
- alert(msg);\r
- }\r
- }\r
- return false;\r
-}\r
-\r
-function jmolSetXHTML(id) {\r
- _jmol.isXHTML = true\r
- _jmol.XhtmlElement = null\r
- _jmol.XhtmlAppendChild = false\r
- if (id){\r
- _jmol.XhtmlElement = document.getElementById(id)\r
- _jmol.XhtmlAppendChild = true\r
- }\r
-}\r
-\r
-function _jmolDocumentWrite(text) {\r
- if (_jmol.currentDocument) {\r
- if (_jmol.isXHTML && !_jmol.XhtmlElement) {\r
- var s = document.getElementsByTagName("script")\r
- _jmol.XhtmlElement = s.item(s.length - 1)\r
- _jmol.XhtmlAppendChild = false\r
- }\r
- if (_jmol.XhtmlElement) {\r
- _jmolDomDocumentWrite(text)\r
- } else {\r
- _jmol.currentDocument.write(text);\r
- }\r
- }\r
- return text;\r
-}\r
-\r
-function _jmolDomDocumentWrite(data) {\r
- var pt = 0\r
- var Ptr = []\r
- Ptr[0] = 0\r
- while (Ptr[0] < data.length) {\r
- var child = _jmolGetDomElement(data, Ptr)\r
- if (!child)break\r
- if (_jmol.XhtmlAppendChild)\r
- _jmol.XhtmlElement.appendChild(child)\r
- else\r
- _jmol.XhtmlElement.parentNode.insertBefore(child, _jmol.XhtmlElement); \r
- }\r
-}\r
-function _jmolGetDomElement(data, Ptr, closetag, lvel) {\r
- var e = document.createElement("span")\r
- e.innerHTML = data\r
- Ptr[0] = data.length\r
- return e\r
-\r
-//unnecessary?\r
-\r
- closetag || (closetag = "")\r
- lvel || (lvel = 0)\r
- var pt0 = Ptr[0]\r
- var pt = pt0\r
- while (pt < data.length && data.charAt(pt) != "<") pt++\r
- if (pt != pt0) {\r
- var text = data.substring(pt0, pt)\r
- Ptr[0] = pt\r
- return document.createTextNode(text)\r
- } \r
- pt0 = ++pt\r
- var ch\r
- while (pt < data.length && "\n\r\t >".indexOf(ch = data.charAt(pt)) < 0) pt++\r
- var tagname = data.substring(pt0, pt)\r
- var e = (tagname == closetag || tagname == "/" ? "" \r
- : document.createElementNS ? document.createElementNS('http://www.w3.org/1999/xhtml', tagname)\r
- : document.createElement(tagname));\r
- if (ch == ">") {\r
- Ptr[0] = ++pt\r
- return e\r
- }\r
- while (pt < data.length && (ch = data.charAt(pt)) != ">") {\r
- while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++\r
- pt0 = pt\r
- while (pt < data.length && "\n\r\t =/>".indexOf(ch = data.charAt(pt)) < 0) pt++\r
- var attrname = data.substring(pt0, pt).toLowerCase()\r
- if (attrname && ch != "=") \r
- e.setAttribute(attrname, "true")\r
- while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++\r
- if (ch == "/") {\r
- Ptr[0] = pt + 2\r
- return e\r
- } else if (ch == "=") {\r
- var quote = data.charAt(++pt)\r
- pt0 = ++pt\r
- while (pt < data.length && (ch = data.charAt(pt)) != quote) pt++\r
- var attrvalue = data.substring(pt0, pt)\r
- e.setAttribute(attrname, attrvalue)\r
- pt++\r
- }\r
- }\r
- Ptr[0] = ++pt\r
- while (Ptr[0] < data.length) {\r
- var child = _jmolGetDomElement(data, Ptr, "/" + tagname, lvel+1)\r
- if (!child)break\r
- e.appendChild(child)\r
- }\r
- return e\r
-}\r
-\r
-function _jmolPopup(url) {\r
- var popup = window.open(url, "JmolPopup",\r
- "left=150,top=150,height=400,width=600," +\r
- "directories=yes,location=yes,menubar=yes," +\r
- "toolbar=yes," +\r
- "resizable=yes,scrollbars=yes,status=yes");\r
- if (popup.focus)\r
- poup.focus();\r
-}\r
-\r
-function _jmolReadyCallback(name) {\r
- if (_jmol.debugAlert)\r
- alert(name + " is ready");\r
- _jmol.ready["" + name] = true;\r
-}\r
-\r
-function _jmolSterilizeScript(script) {\r
- script = script.replace(/'/g, "'");\r
- if (_jmol.debugAlert)\r
- alert("script:\n" + script);\r
- return script;\r
-}\r
-\r
-function _jmolSterilizeInline(model) {\r
- model = model.replace(/\r|\n|\r\n/g, (model.indexOf("|") >= 0 ? "\\/n" : "|")).replace(/'/g, "'");\r
- if (_jmol.debugAlert)\r
- alert("inline model:\n" + model);\r
- return model;\r
-}\r
-\r
-function _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {\r
- ++_jmol.radioCount;\r
- groupName != undefined && groupName != null || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));\r
- if (!script)\r
- return "";\r
- labelHtml != undefined && labelHtml != null || (labelHtml = script.substring(0, 32));\r
- separatorHtml || (separatorHtml = "")\r
- var scriptIndex = _jmolAddScript(script);\r
- var eospan = "</span>"\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='" \r
- + groupName + "' id='"+id+"' type='radio' onclick='_jmolClick(this," +\r
- scriptIndex + _jmol.targetText + ");return true;' onmouseover='_jmolMouseOver(" +\r
- scriptIndex + ");return true;' onmouseout='_jmolMouseOut()' " +\r
- (isChecked ? "checked='true' " : "") + _jmol.radioCssText + " />"\r
- if (labelHtml.toLowerCase().indexOf("<td>")>=0) {\r
- t += eospan\r
- eospan = "";\r
- }\r
- t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan + separatorHtml;\r
-\r
- return t;\r
-}\r
-\r
-function _jmolFindApplet(target) {\r
- // first look for the target in the current window\r
- var applet = _jmolFindAppletInWindow(_jmol.appletWindow != null ? _jmol.appletWindow : window, target);\r
- // THEN look for the target in child frames\r
- if (applet == undefined)\r
- applet = _jmolSearchFrames(window, target);\r
- // FINALLY look for the target in sibling frames\r
- if (applet == undefined)\r
- applet = _jmolSearchFrames(top, target); // look starting in top frame\r
- return applet;\r
-}\r
-\r
-function _jmolGetApplet(targetSuffix){\r
- var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");\r
- var applet = _jmolFindApplet(target);\r
- if (applet) return applet\r
- _jmol.alerted || alert("could not find applet " + target);\r
- _jmol.alerted = true;\r
- return null\r
-}\r
-\r
-function _jmolSearchFrames(win, target) {\r
- var applet;\r
- var frames = win.frames;\r
- if (frames && frames.length) { // look in all the frames below this window\r
- try{\r
- for (var i = 0; i < frames.length; ++i) {\r
- applet = _jmolSearchFrames(frames[i], target);\r
- if (applet)\r
- return applet;\r
- }\r
- }catch(e) {\r
- if (_jmol.debugAlert)\r
- alert("Jmol.js _jmolSearchFrames cannot access " + win.name + ".frame[" + i + "] consider using jmolSetAppletWindow()") \r
- }\r
- }\r
- return applet = _jmolFindAppletInWindow(win, target)\r
-}\r
-\r
-function _jmolFindAppletInWindow(win, target) {\r
- var doc = win.document;\r
- if (doc.getElementById(target))\r
- return doc.getElementById(target);\r
- else if (doc.applets)\r
- return doc.applets[target];\r
- else\r
- return doc[target]; \r
-}\r
-\r
-function _jmolAddScript(script) {\r
- if (!script)\r
- return 0;\r
- var index = _jmol.scripts.length;\r
- _jmol.scripts[index] = script;\r
- return index;\r
-}\r
-\r
-function _jmolClick(elementClicked, scriptIndex, targetSuffix) {\r
- _jmol.element = elementClicked;\r
- _jmolScriptExecute(elementClicked, _jmol.scripts[scriptIndex], targetSuffix);\r
-}\r
-\r
-function _jmolMenuSelected(menuObject, targetSuffix) {\r
- var scriptIndex = menuObject.value;\r
- if (scriptIndex != undefined) {\r
- _jmolScriptExecute(menuObject, _jmol.scripts[scriptIndex], targetSuffix);\r
- return;\r
- }\r
- var len = menuObject.length;\r
- if (typeof len == "number") {\r
- for (var i = 0; i < len; ++i) {\r
- if (menuObject[i].selected) {\r
- _jmolClick(menuObject[i], menuObject[i].value, targetSuffix);\r
- return;\r
- }\r
- }\r
- }\r
- alert("?Que? menu selected bug #8734");\r
-}\r
-\r
-\r
-_jmol.checkboxMasters = {};\r
-_jmol.checkboxItems = {};\r
-\r
-function jmolSetCheckboxGroup(chkMaster,chkBox) {\r
- var id = chkMaster;\r
- if(typeof(id)=="number")id = "jmolCheckbox" + id;\r
- chkMaster = document.getElementById(id);\r
- if (!chkMaster)alert("jmolSetCheckboxGroup: master checkbox not found: " + id);\r
- var m = _jmol.checkboxMasters[id] = {};\r
- m.chkMaster = chkMaster;\r
- m.chkGroup = {};\r
- for (var i = 1; i < arguments.length; i++){\r
- var id = arguments[i];\r
- if(typeof(id)=="number")id = "jmolCheckbox" + id;\r
- checkboxItem = document.getElementById(id);\r
- if (!checkboxItem)alert("jmolSetCheckboxGroup: group checkbox not found: " + id);\r
- m.chkGroup[id] = checkboxItem;\r
- _jmol.checkboxItems[id] = m;\r
- }\r
-}\r
-\r
-function _jmolNotifyMaster(m){\r
- //called when a group item is checked\r
- var allOn = true;\r
- var allOff = true;\r
- for (var chkBox in m.chkGroup){\r
- if(m.chkGroup[chkBox].checked)\r
- allOff = false;\r
- else\r
- allOn = false;\r
- }\r
- if (allOn)m.chkMaster.checked = true; \r
- if (allOff)m.chkMaster.checked = false;\r
- if ((allOn || allOff) && _jmol.checkboxItems[m.chkMaster.id])\r
- _jmolNotifyMaster(_jmol.checkboxItems[m.chkMaster.id])\r
-}\r
-\r
-function _jmolNotifyGroup(m, isOn){\r
- //called when a master item is checked\r
- for (var chkBox in m.chkGroup){\r
- var item = m.chkGroup[chkBox]\r
- item.checked = isOn;\r
- if (_jmol.checkboxMasters[item.id])\r
- _jmolNotifyGroup(_jmol.checkboxMasters[item.id], isOn)\r
- }\r
-}\r
-\r
-function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) {\r
- _jmol.control = ckbox\r
- _jmolClick(ckbox, ckbox.checked ? whenChecked : whenUnchecked, targetSuffix);\r
- if(_jmol.checkboxMasters[ckbox.id])\r
- _jmolNotifyGroup(_jmol.checkboxMasters[ckbox.id], ckbox.checked)\r
- if(_jmol.checkboxItems[ckbox.id])\r
- _jmolNotifyMaster(_jmol.checkboxItems[ckbox.id])\r
-}\r
-\r
-function _jmolCbOver(ckbox, whenChecked, whenUnchecked) {\r
- window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked];\r
-}\r
-\r
-function _jmolMouseOver(scriptIndex) {\r
- window.status = _jmol.scripts[scriptIndex];\r
-}\r
-\r
-function _jmolMouseOut() {\r
- window.status = " ";\r
- return true;\r
-}\r
-\r
-function _jmolSetCodebase(codebase) {\r
- _jmol.codebase = codebase ? codebase : ".";\r
- if (_jmol.debugAlert)\r
- alert("jmolCodebase=" + _jmol.codebase);\r
-}\r
-\r
-function _jmolOnloadResetForms() {\r
- // must be evaluated ONLY once\r
- _jmol.previousOnloadHandler = window.onload;\r
- window.onload =\r
- function() {\r
- with (_jmol) {\r
- if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) {\r
- var forms = document.forms;\r
- for (var i = forms.length; --i >= 0; )\r
- forms[i].reset();\r
- }\r
- if (previousOnloadHandler)\r
- previousOnloadHandler();\r
- }\r
- }\r
-}\r
-\r
-////////////////////////////////////\r
-/////extensions for getProperty/////\r
-////////////////////////////////////\r
-\r
-\r
-function _jmolEvalJSON(s,key){\r
- s=s+""\r
- if(!s)return []\r
- if(s.charAt(0)!="{"){\r
- if(s.indexOf(" | ")>=0)s=s.replace(/\ \|\ /g, "\n")\r
- return s\r
- }\r
- var A = eval("("+s+")")\r
- if(!A)return\r
- if(key && A[key])A=A[key]\r
- return A\r
-}\r
-\r
-function _jmolEnumerateObject(A,key){\r
- var sout=""\r
- if(typeof(A) == "string" && A!="null"){\r
- sout+="\n"+key+"=\""+A+"\""\r
- }else if(!isNaN(A)||A==null){\r
- sout+="\n"+key+"="+(A+""==""?"null":A)\r
- }else if(A.length){\r
- sout+=key+"=[]"\r
- for(var i=0;i<A.length;i++){\r
- sout+="\n"\r
- if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){\r
- sout+=_jmolEnumerateObject(A[i],key+"["+i+"]")\r
- }else{\r
- sout+=key+"["+i+"]="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])\r
- }\r
- }\r
- }else{\r
- if(key != ""){\r
- sout+=key+"={}"\r
- key+="."\r
- }\r
- \r
- for(var i in A){\r
- sout+="\n"\r
- if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){\r
- sout+=_jmolEnumerateObject(A[i],key+i)\r
- }else{\r
- sout+=key+i+"="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])\r
- }\r
- }\r
- } \r
- return sout\r
-}\r
-\r
-\r
-function _jmolSortKey0(a,b){\r
- return (a[0]<b[0]?1:a[0]>b[0]?-1:0)\r
-}\r
-\r
-function _jmolSortMessages(A){\r
- if(!A || typeof(A)!="object")return []\r
- var B = []\r
- for(var i=A.length-1;i>=0;i--)for(var j=0;j<A[i].length;j++)B[B.length]=A[i][j]\r
- if(B.length == 0) return\r
- B=B.sort(_jmolSortKey0)\r
- return B\r
-}\r
-\r
-/////////additional extensions //////////\r
-\r
-\r
-function _jmolDomScriptLoad(URL){\r
- //open(URL) //to debug\r
- _jmol.servercall=URL\r
- var node = document.getElementById("_jmolScriptNode")\r
- if (node && _jmol.browser!="msie"){\r
- document.getElementsByTagName("HEAD")[0].removeChild(node)\r
- node=null\r
- }\r
- if (node) {\r
- node.setAttribute("src",URL)\r
- } else {\r
- node=document.createElement("script")\r
- node.setAttribute("id","_jmolScriptNode")\r
- node.setAttribute("type","text/javascript")\r
- node.setAttribute("src",URL)\r
- document.getElementsByTagName("HEAD")[0].appendChild(node)\r
- }\r
-}\r
-\r
-\r
-function _jmolExtractPostData(url){\r
- S=url.split("&POST:")\r
- var s=""\r
- for(var i=1;i<S.length;i++){\r
- KV=S[i].split("=")\r
- s+="&POSTKEY"+i+"="+KV[0]\r
- s+="&POSTVALUE"+i+"="+KV[1]\r
- }\r
- return "&url="+escape(S[0])+s\r
-}\r
-\r
-function _jmolLoadModel(targetSuffix,remoteURL,array,isError,errorMessage){\r
- //called by server, but in client\r
- //overload this function to customize return\r
- _jmol.remoteURL=remoteURL\r
- isError && alert(errorMessage)\r
- jmolLoadInlineScript(array.join("\n"),_jmol.optionalscript,targetSuffix)\r
-}\r
-\r
-//////////user property/status functions/////////\r
-\r
-function jmolGetStatus(strStatus,targetSuffix){\r
- return _jmolSortMessages(jmolGetPropertyAsArray("jmolStatus",strStatus,targetSuffix))\r
-}\r
-\r
-function jmolGetPropertyAsArray(sKey,sValue,targetSuffix) {\r
- return _jmolEvalJSON(jmolGetPropertyAsJSON(sKey,sValue,targetSuffix),sKey)\r
-}\r
-\r
-function jmolGetPropertyAsString(sKey,sValue,targetSuffix) {\r
- var applet = _jmolGetApplet(targetSuffix);\r
- sValue == undefined && (sValue="");\r
- return (applet ? applet.getPropertyAsString(sKey,sValue) + "" : "")\r
-}\r
-\r
-function jmolGetPropertyAsJSON(sKey,sValue,targetSuffix) {\r
- sValue == undefined && (sValue = "")\r
- var applet = _jmolGetApplet(targetSuffix);\r
- try {\r
- return (applet ? applet.getPropertyAsJSON(sKey,sValue) + "" : "")\r
- } catch(e) {\r
- return ""\r
- }\r
-}\r
-\r
-function jmolGetPropertyAsJavaObject(sKey,sValue,targetSuffix) {\r
- sValue == undefined && (sValue = "")\r
- var applet = _jmolGetApplet(targetSuffix);\r
- return (applet ? applet.getProperty(sKey,sValue) : null)\r
-}\r
-\r
-\r
-function jmolDecodeJSON(s) {\r
- return _jmolEnumerateObject(_jmolEvalJSON(s),"")\r
-}\r
-\r
-\r
-///////// synchronous scripting ////////\r
-\r
-function jmolScriptWait(script, targetSuffix) {\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var Ret=jmolScriptWaitAsArray(script, targetSuffix)\r
- var s = ""\r
- for(var i=Ret.length;--i>=0;)\r
- for(var j=0;j< Ret[i].length;j++)\r
- s+=Ret[i][j]+"\n"\r
- return s\r
-}\r
-\r
-function jmolScriptWaitOutput(script, targetSuffix) {\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var ret = ""\r
- try{\r
- if (script) {\r
- _jmolCheckBrowser();\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (applet) ret += applet.scriptWaitOutput(script);\r
- }\r
- }catch(e){\r
- }\r
- return ret;\r
-}\r
-\r
-function jmolEvaluate(molecularMath, targetSuffix) {\r
-\r
- //carries out molecular math on a model\r
-\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var result = "" + jmolGetPropertyAsJavaObject("evaluate", molecularMath, targetSuffix);\r
- var s = result.replace(/\-*\d+/,"")\r
- if (s == "" && !isNaN(parseInt(result)))return parseInt(result);\r
- var s = result.replace(/\-*\d*\.\d*/,"")\r
- if (s == "" && !isNaN(parseFloat(result)))return parseFloat(result);\r
- return result;\r
-}\r
-\r
-function jmolScriptEcho(script, targetSuffix) {\r
- // returns a newline-separated list of all echos from a script\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var Ret=jmolScriptWaitAsArray(script, targetSuffix)\r
- var s = ""\r
- for(var i=Ret.length;--i>=0;)\r
- for(var j=Ret[i].length;--j>=0;)\r
- if (Ret[i][j][1] == "scriptEcho")s+=Ret[i][j][3]+"\n"\r
- return s.replace(/ \| /g, "\n")\r
-}\r
-\r
-\r
-function jmolScriptMessage(script, targetSuffix) {\r
- // returns a newline-separated list of all messages from a script, ending with "script completed\n"\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var Ret=jmolScriptWaitAsArray(script, targetSuffix)\r
- var s = ""\r
- for(var i=Ret.length;--i>=0;)\r
- for(var j=Ret[i].length;--j>=0;)\r
- if (Ret[i][j][1] == "scriptStatus")s+=Ret[i][j][3]+"\n"\r
- return s.replace(/ \| /g, "\n")\r
-}\r
-\r
-\r
-function jmolScriptWaitAsArray(script, targetSuffix) {\r
- var ret = ""\r
- try{\r
- jmolGetStatus("scriptEcho,scriptMessage,scriptStatus,scriptError",targetSuffix)\r
- if (script) {\r
- _jmolCheckBrowser();\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (applet) ret += applet.scriptWait(script);\r
- ret = _jmolEvalJSON(ret,"jmolStatus")\r
- if(typeof ret == "object")\r
- return ret\r
- }\r
- }catch(e){\r
- }\r
- return [[ret]]\r
-}\r
-\r
-\r
-\r
-//////////// save/restore orientation /////////////\r
-\r
-function jmolSaveOrientation(id, targetSuffix) { \r
- targetSuffix == undefined && (targetSuffix="0")\r
- return _jmol["savedOrientation"+id] = jmolGetPropertyAsArray("orientationInfo","info",targetSuffix).moveTo\r
-}\r
-\r
-function jmolRestoreOrientation(id, targetSuffix) {\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var s=_jmol["savedOrientation"+id]\r
- if (!s || s == "")return\r
- s=s.replace(/1\.0/,"0")\r
- return jmolScriptWait(s,targetSuffix)\r
-}\r
-\r
-function jmolRestoreOrientationDelayed(id, delay, targetSuffix) {\r
- arguments.length < 2 && (delay=1)\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var s=_jmol["savedOrientation"+id]\r
- if (!s || s == "")return\r
- s=s.replace(/1\.0/,delay)\r
- return jmolScriptWait(s,targetSuffix)\r
-}\r
-\r
-//////////// add parameter /////////////\r
-/*\r
- * for adding callbacks or other parameters. Use:\r
-\r
- jmolSetDocument(0)\r
- var s= jmolApplet(....)\r
- s = jmolAppletAddParam(s,"messageCallback", "myFunctionName")\r
- document.write(s)\r
- jmolSetDocument(document) // if you want to then write buttons and such normally\r
- \r
- */\r
-\r
-function jmolAppletAddParam(appletCode,name,value){\r
- return (value == "" ? appletCode : appletCode.replace(/\<param/,"\n<param name='"+name+"' value='"+value+"' />\n<param"))\r
-}\r
-\r
-///////////////auto load Research Consortium for Structural Biology (RCSB) data ///////////\r
-\r
-function jmolLoadAjax_STOLAF_RCSB(fileformat,pdbid,optionalscript,targetSuffix){\r
-\r
- _jmol.thismodel || (_jmol.thismodel = "1crn")\r
- _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")\r
- _jmol.RCSBserver || (_jmol.RCSBserver="http://www.rcsb.org")\r
- _jmol.defaultURL_RCSB || (_jmol.defaultURL_RCSB=_jmol.RCSBserver+"/pdb/files/1CRN.CIF")\r
- fileformat || (fileformat="PDB")\r
- pdbid || (pdbid=prompt("Enter a 4-digit PDB ID:",_jmol.thismodel))\r
- if(!pdbid || pdbid.length != 4)return ""\r
- targetSuffix || (targetSuffix="0")\r
- optionalscript || (optionalscript="")\r
- var url=_jmol.defaultURL_RCSB.replace(/1CRN/g,pdbid.toUpperCase())\r
- fileformat=="CIF" || (url=url.replace(/CIF/,fileformat))\r
- _jmol.optionalscript=optionalscript\r
- _jmol.thismodel=pdbid\r
- _jmol.thistargetsuffix=targetSuffix\r
- _jmol.thisurl=url\r
- _jmol.modelArray = []\r
- url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)\r
- _jmolDomScriptLoad(url)\r
- return url\r
-}\r
-\r
-\r
-///////////////auto load NIH CACTVS data -- compound name or SMILES ///////////\r
-\r
-function jmolLoadAjax_STOLAF_NIH(compoundid,optionalscript,targetSuffix){\r
- _jmol.thismodel || (_jmol.thismodel = "aspirin")\r
- _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")\r
- _jmol.defaultURL_NIH || (_jmol.defaultURL_NIH="http://cactus.nci.nih.gov/chemical/structure/FILE/file?format=sdf&get3d=True")\r
- compoundid || (compoundid=prompt("Enter a compound name or a SMILES string:",_jmol.thismodel))\r
- if(!compoundid)return ""\r
- targetSuffix || (targetSuffix="0")\r
- optionalscript || (optionalscript="")\r
- var url=_jmol.defaultURL_NIH.replace(/FILE/g,compoundid)\r
- _jmol.optionalscript=optionalscript\r
- _jmol.thismodel=compoundid\r
- _jmol.thistargetsuffix=targetSuffix\r
- _jmol.thisurl=url\r
- _jmol.modelArray = []\r
- url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)\r
- _jmolDomScriptLoad(url)\r
- return url\r
-}\r
-\r
-\r
-/////////////// St. Olaf College AJAX server -- ANY URL ///////////\r
-\r
-function jmolLoadAjax_STOLAF_ANY(url, userid, optionalscript,targetSuffix){\r
- _jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm"\r
- _jmol.thisurlANY || (_jmol.thisurlANY = "http://www.stolaf.edu/depts/chemistry/mo/struc/data/ycp3-1.mol")\r
- url || (url=prompt("Enter any (uncompressed file) URL:", _jmol.thisurlANY))\r
- userid || (userid="0")\r
- targetSuffix || (targetSuffix="0")\r
- optionalscript || (optionalscript="")\r
- _jmol.optionalscript=optionalscript\r
- _jmol.thistargetsuffix=targetSuffix\r
- _jmol.modelArray = []\r
- _jmol.thisurl = url\r
- url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)\r
- _jmolDomScriptLoad(url)\r
-}\r
-\r
-\r
-/////////////// Mineralogical Society of America (MSA) data /////////\r
-\r
-function jmolLoadAjax_MSA(key,value,optionalscript,targetSuffix){\r
-\r
- _jmol.thiskeyMSA || (_jmol.thiskeyMSA = "mineral")\r
- _jmol.thismodelMSA || (_jmol.thismodelMSA = "quartz")\r
- _jmol.ajaxURL_MSA || (_jmol.ajaxURL_MSA="http://rruff.geo.arizona.edu/AMS/result.php?mineral=quartz&viewing=ajaxjs")\r
- key || (key=prompt("Enter a field:", _jmol.thiskeyMSA))\r
- if(!key)return ""\r
- value || (value=prompt("Enter a "+key+":", _jmol.thismodelMSA))\r
- if(!value)return ""\r
- targetSuffix || (targetSuffix="0")\r
- optionalscript || (optionalscript="")\r
- optionalscript == 1 && (optionalscript='load "" {1 1 1}')\r
- var url=_jmol.ajaxURL_MSA.replace(/mineral/g,key).replace(/quartz/g,value)\r
- _jmol.optionalscript=optionalscript\r
- _jmol.thiskeyMSA=key\r
- _jmol.thismodelMSA=value\r
- _jmol.thistargetsuffix=targetSuffix\r
- _jmol.thisurl=url\r
- _jmol.modelArray = []\r
- loadModel=_jmolLoadModel\r
- _jmolDomScriptLoad(url)\r
- return url\r
-}\r
-\r
-\r
-\r
-function jmolLoadAjaxJS(url, userid, optionalscript,targetSuffix){\r
- userid || (userid="0")\r
- targetSuffix || (targetSuffix="0")\r
- optionalscript || (optionalscript="")\r
- _jmol.optionalscript=optionalscript\r
- _jmol.thismodel=userid\r
- _jmol.thistargetsuffix=targetSuffix\r
- _jmol.modelArray = []\r
- _jmol.thisurl = url\r
- url+="&returnFunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix\r
- _jmolDomScriptLoad(url)\r
-}\r
-\r
-\r
-//// in case Jmol library has already been loaded:\r
-\r
-}catch(e){}\r
-\r
-///////////////moving atoms //////////////\r
-\r
-// HIGHLY experimental!!\r
-\r
-function jmolSetAtomCoord(i,x,y,z,targetSuffix){\r
- _jmolCheckBrowser();\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (applet) applet.getProperty('jmolViewer').setAtomCoord(i,x,y,z)\r
-}\r
-\r
-function jmolSetAtomCoordRelative(i,x,y,z,targetSuffix){\r
- _jmolCheckBrowser();\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (applet) applet.getProperty('jmolViewer').setAtomCoordRelative(i,x,y,z)\r
-}\r
-\r
-\r
-///////////////applet fake for testing buttons/////////////\r
-\r
-\r
-if(_jmol.useNoApplet){\r
- jmolApplet = function(w){\r
- var s="<table style='background-color:black' width="+w+"><tr height="+w+">"\r
- +"<td align=center valign=center style='background-color:white'>"\r
- +"Applet would be here"\r
- +"<p><textarea id=fakeApplet rows=5 cols=50></textarea>"\r
- +"</td></tr></table>"\r
- return _jmolDocumentWrite(s)\r
- }\r
-\r
- _jmolFindApplet = function(){return jmolApplet0}\r
-\r
- jmolApplet0 = {\r
- script: function(script){document.getElementById("fakeApplet").value="\njmolScript:\n"+script}\r
- ,scriptWait: function(script){document.getElementById("fakeApplet").value="\njmolScriptWait:\n"+script} \r
- ,loadInline: function(data,script){document.getElementById("fakeApplet").value="\njmolLoadInline data:\n"+data+"\n\nscript:\n"+script}\r
- }\r
-}\r
-\r
-\r
-///////////////////////////////////////////\r
-\r
- // This should no longer be needed, jmolResizeApplet() is better; kept for backwards compatibility\r
- /*\r
- Resizes absolutely (pixels) or by percent of window (w or h 0.5 means 50%).\r
- targetSuffix is optional and defaults to zero (first applet in page).\r
- Both w and h are optional, but needed if you want to use targetSuffix.\r
- h defaults to w\r
- w defaults to 100% of window\r
- If either w or h is between 0 and 1, then it is taken as percent/100.\r
- If either w or h is greater than 1, then it is taken as a size (pixels). \r
- */\r
-function jmolResize(w,h,targetSuffix) {\r
- _jmol.alerted = true;\r
- var percentW = (!w ? 100 : w <= 1 && w > 0 ? w * 100 : 0);\r
- var percentH = (!h ? percentW : h <= 1 && h > 0 ? h * 100 : 0);\r
- if (_jmol.browser=="msie") {\r
- var width=document.body.clientWidth;\r
- var height=document.body.clientHeight;\r
- } else {\r
- var netscapeScrollWidth=15;\r
- var width=window.innerWidth - netscapeScrollWidth;\r
- var height=window.innerHeight-netscapeScrollWidth;\r
- }\r
- var applet = _jmolGetApplet(targetSuffix);\r
- if(!applet)return;\r
- applet.style.width = (percentW ? width * percentW/100 : w)+"px";\r
- applet.style.height = (percentH ? height * percentH/100 : (h ? h : w))+"px";\r
- //title=width + " " + height + " " + (new Date());\r
-}\r
-\r
-// 13 Jun 09 -- makes jmolResize() obsolete (kept for backwards compatibility)\r
-function jmolResizeApplet(size,targetSuffix) {\r
- // See _jmolGetAppletSize() for the formats accepted as size [same used by jmolApplet()]\r
- // Special case: an empty value for width or height is accepted, meaning no change in that dimension.\r
- _jmol.alerted = true;\r
- var applet = _jmolGetApplet(targetSuffix);\r
- if(!applet)return;\r
- var sz = _jmolGetAppletSize(size, "px");\r
- sz[0] && (applet.style.width = sz[0]);\r
- sz[1] && (applet.style.height = sz[1]);\r
-}\r
-\r
-function _jmolGetAppletSize(size, units) {\r
- /* Accepts single number or 2-value array, each one can be one of:\r
- percent (text string ending %), decimal 0 to 1 (percent/100), number, or text string (interpreted as nr.)\r
- [width, height] array of strings is returned, with units added if specified.\r
- Percent is relative to container div or element (which should have explicitly set size).\r
- */\r
- var width, height;\r
- if ( (typeof size) == "object" && size != null ) {\r
- width = size[0]; height = size[1];\r
- } else {\r
- width = height = size;\r
- }\r
- return [_jmolFixDim(width, units), _jmolFixDim(height, units)];\r
-}\r
-\r
-function _jmolFixDim(x, units) {\r
- var sx = "" + x;\r
- return (sx.length == 0 ? (units ? "" : _jmol.allowedJmolSize[2])\r
- : sx.indexOf("%") == sx.length-1 ? sx \r
- : (x = parseFloat(x)) <= 1 && x > 0 ? x * 100 + "%"\r
- : (isNaN(x = Math.floor(x)) ? _jmol.allowedJmolSize[2]\r
- : x < _jmol.allowedJmolSize[0] ? _jmol.allowedJmolSize[0]\r
- : x > _jmol.allowedJmolSize[1] ? _jmol.allowedJmolSize[1] \r
- : x) + (units ? units : ""));\r
-}\r
-\r
-\r
-\r
-\r
+/* Jmol 12.0 script library Jmol.js 9:48 PM 1/31/2011 Bob Hanson
+
+ checkbox heirarchy -- see http://chemapps.stolaf.edu/jmol/docs/examples-11/check.htm
+
+ based on:
+ *
+ * Copyright (C) 2004-2005 Miguel, Jmol Development, www.jmol.org
+ *
+ * Contact: hansonr@stolaf.edu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ */
+
+// for documentation see www.jmol.org/jslibrary
+
+try{if(typeof(_jmol)!="undefined")exit()
+
+// place "?NOAPPLET" on your command line to check applet control action with a textarea
+// place "?JMOLJAR=xxxxx" to use a specific jar file
+
+// bob hanson -- jmolResize(w,h) -- resizes absolutely or by percent (w or h 0.5 means 50%)
+// angel herraez -- update of jmolResize(w,h,targetSuffix) so it is not tied to first applet
+// bob hanson -- jmolEvaluate -- evaluates molecular math 8:37 AM 2/23/2007
+// bob hanson -- jmolScriptMessage -- returns all "scriptStatus" messages 8:37 AM 2/23/2007
+// bob hanson -- jmolScriptEcho -- returns all "scriptEcho" messages 8:37 AM 2/23/2007
+// bob hanson -- jmolScriptWait -- 11:31 AM 5/2/2006
+// bob hanson -- remove trailing separatorHTML in radio groups -- 12:18 PM 5/6/2006
+// bob hanson -- adds support for dynamic DOM script nodes 7:04 AM 5/19/2006
+// bob hanson -- adds try/catch for wiki - multiple code passes 7:05 AM 5/19/2006
+// bob hanson -- auto-initiates to defaultdir/defaultjar -- change as desired.
+// bob hanson -- adding save/restore orientation w/ and w/o delay 11:49 AM 5/25/2006
+// bob hanson -- adding AjaxJS service 11:16 AM 6/3/2006
+// bob hanson -- fix for iframes not available for finding applet
+// bob hanson -- added applet fake ?NOAPPLET URL flag
+// bob hanson -- added jmolSetCallback(calbackName, funcName) 3:32 PM 6/13/2006
+// used PRIOR to jmolApplet() or jmolAppletInline()
+// added 4th array element in jmolRadioGroup -- title
+// added <span> and id around link, checkbox, radio, menu
+// fixing AJAX loads for MSIE/Opera-Mozilla incompatibility
+// -- renamed Jmol-11.js from Jmol-new.js; JmolApplet.jar from JmolAppletProto.jar
+// renamed Jmol.js for Jmol 11 distribution
+// -- modified jmolRestoreOrientation() to be immediate, no 1-second delay
+// bob hanson -- jmolScriptWait always returns a string -- 11:23 AM 9/16/2006
+// bh -- jmolCommandInput()
+// bh -- jmolSetTranslation(TF) -- forces translation even if there might be message callback issues
+// bh -- minor fixes suggested by Angel
+// bh -- adds jmolSetSyncId() and jmolGetSyncId()
+// bh 3/2008 -- adds jmolAppendInlineScript() and jmolAppendInlineArray()
+// bh 3/2008 -- fixes IE7 bug in relation to jmolLoadInlineArray()
+// bh 6/2008 -- adds jmolSetAppletWindow()
+// Angel H. 6/2008 -- added html <label> tags to checkboxes and radio buttons [in jmolCheckbox() and _jmolRadio() functions]
+// bh 7/2008 -- code fix "for(i..." not "for(var i..."
+// bh 12/2008 -- jmolLoadInline, jmolLoadInlineArray, jmolLoadInlineScript, jmolAppendInlineScript, jmolAppendInlineArray all return error message or null (Jmol 11.7.16)
+// bh 12/2008 -- jmolScriptWaitOutput() -- waits for script to complete and delivers output normally sent to console
+
+// bh 5/2009 -- Support for XHTML using jmolSetXHTML(id)
+// ah & bh 6/2009 -- New jmolResizeApplet() more flexible, similar to jmolApplet() size syntax
+// bh 11/2009 -- care in accessing top.document
+// bh 12/2009 -- added jmolSetParameter(name, value)
+// bh 12/2009 -- added PARAMS=name:value;name:value;name:value... for command line
+// bh 12/2009 -- overhaul of target checking
+// bh 1/2010 -- all _xxxx() methods ALWAYS have complete argument list
+// bh 1/2010 -- adds option to run a JavaScript function from any Jmol control.
+// This is accomplished by passing an array rather than a script:
+// jmolHref([myfunc,"my param 1", "my param 2"], "testing")
+// function myfunc(jmolControlObject, [myfunc,"my param 1", "my param 2"], target){...}
+// and allows much more flexibility with responding to controls
+// bh 4/2010 -- added jmolSetMemoryMb(nMb)
+// ah 1/2011 -- wider detection of browsers; more browsers now use the object tag instead of the applet tag;
+// fix of object tag (removed classid) accounts for change of behavior in Chrome
+// bh 3/2011 -- added jmolLoadAjax_STOLAF_NIH
+
+var defaultdir = "."
+var defaultjar = "JmolApplet.jar"
+
+
+// Note added 12:41 PM 9/21/2008 by Bob Hanson, hansonr@stolaf.edu:
+
+// JMOLJAR=xxxxx.jar on the URL for this page will override
+// the JAR file specified in the jmolInitialize() call.
+
+// The idea is that it can be very useful to test a web page with different JAR files
+// Or for an expert user to substitute a signed applet for an unsigned one
+// so as to use a broader range of models or to create JPEG files, for example.
+
+// If the JAR file is not in the current directory (has any sort of "/" in its name)
+// then the user is presented with a warning and asked whether it is OK to change Jar files.
+// The default action, if the user just presses "OK" is to NOT allow the change.
+// The user must type the word "yes" in the prompt box for the change to be approved.
+
+// If you don't want people to be able to switch in their own JAR file on your page,
+// simply set this next line to read "var allowJMOLJAR = false".
+
+
+var undefined; // for IE 5 ... wherein undefined is undefined
+
+////////////////////////////////////////////////////////////////
+// Basic Scripting infrastruture
+////////////////////////////////////////////////////////////////
+
+function jmolInitialize(codebaseDirectory, fileNameOrUseSignedApplet) {
+ if (_jmol.initialized)
+ return;
+ _jmol.initialized = true;
+ if(_jmol.jmoljar) {
+ var f = _jmol.jmoljar;
+ if (f.indexOf("/") >= 0) {
+ alert ("This web page URL is requesting that the applet used be " + f + ". This is a possible security risk, particularly if the applet is signed, because signed applets can read and write files on your local machine or network.")
+ var ok = prompt("Do you want to use applet " + f + "? ","yes or no")
+ if (ok == "yes") {
+ codebaseDirectory = f.substring(0, f.lastIndexOf("/"));
+ fileNameOrUseSignedApplet = f.substring(f.lastIndexOf("/") + 1);
+ } else {
+ _jmolGetJarFilename(fileNameOrUseSignedApplet);
+ alert("The web page URL was ignored. Continuing using " + _jmol.archivePath + ' in directory "' + codebaseDirectory + '"');
+ }
+ } else {
+ fileNameOrUseSignedApplet = f;
+ }
+ }
+ _jmolSetCodebase(codebaseDirectory);
+ _jmolGetJarFilename(fileNameOrUseSignedApplet);
+ _jmolOnloadResetForms();
+}
+
+function jmolSetTranslation(TF) {
+ _jmol.params.doTranslate = ''+TF;
+}
+
+function _jmolGetJarFilename(fileNameOrFlag) {
+ _jmol.archivePath =
+ (typeof(fileNameOrFlag) == "string" ? fileNameOrFlag : (fileNameOrFlag ? "JmolAppletSigned" : "JmolApplet") + "0.jar");
+}
+
+function jmolSetDocument(doc) {
+ _jmol.currentDocument = doc;
+}
+
+function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) {
+ _jmolInitCheck();
+ _jmol.params.boxbgcolor = boxbgcolor;
+ if (boxfgcolor)
+ _jmol.params.boxfgcolor = boxfgcolor
+ else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF")
+ _jmol.params.boxfgcolor = "black";
+ else
+ _jmol.params.boxfgcolor = "white";
+ if (progresscolor)
+ _jmol.params.progresscolor = progresscolor;
+ if (_jmol.debugAlert)
+ alert(" boxbgcolor=" + _jmol.params.boxbgcolor +
+ " boxfgcolor=" + _jmol.params.boxfgcolor +
+ " progresscolor=" + _jmol.params.progresscolor);
+}
+
+function jmolSetAppletWindow(w) {
+ _jmol.appletWindow = w;
+}
+
+function jmolApplet(size, script, nameSuffix) {
+ _jmolInitCheck();
+ return _jmolApplet(size, null, script, nameSuffix);
+}
+
+////////////////////////////////////////////////////////////////
+// Basic controls
+////////////////////////////////////////////////////////////////
+
+// undefined means it wasn't there; null means it was explicitly listed as null (so as to skip it)
+
+function jmolButton(script, label, id, title) {
+ _jmolInitCheck();
+ id != undefined && id != null || (id = "jmolButton" + _jmol.buttonCount);
+ label != undefined && label != null || (label = script.substring(0, 32));
+ ++_jmol.buttonCount;
+ var scriptIndex = _jmolAddScript(script);
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='button' name='" + id + "' id='" + id +
+ "' value='" + label +
+ "' onclick='_jmolClick(this," + scriptIndex + _jmol.targetText +
+ ")' onmouseover='_jmolMouseOver(" + scriptIndex +
+ ");return true' onmouseout='_jmolMouseOut()' " +
+ _jmol.buttonCssText + " /></span>";
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked,
+ labelHtml, isChecked, id, title) {
+ _jmolInitCheck();
+ id != undefined && id != null || (id = "jmolCheckbox" + _jmol.checkboxCount);
+ ++_jmol.checkboxCount;
+ if (scriptWhenChecked == undefined || scriptWhenChecked == null ||
+ scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) {
+ alert("jmolCheckbox requires two scripts");
+ return;
+ }
+ if (labelHtml == undefined || labelHtml == null) {
+ alert("jmolCheckbox requires a label");
+ return;
+ }
+ var indexChecked = _jmolAddScript(scriptWhenChecked);
+ var indexUnchecked = _jmolAddScript(scriptWhenUnchecked);
+ var eospan = "</span>"
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='checkbox' name='" + id + "' id='" + id +
+ "' onclick='_jmolCbClick(this," +
+ indexChecked + "," + indexUnchecked + _jmol.targetText +
+ ")' onmouseover='_jmolCbOver(this," + indexChecked + "," +
+ indexUnchecked +
+ ");return true' onmouseout='_jmolMouseOut()' " +
+ (isChecked ? "checked='true' " : "")+ _jmol.checkboxCssText + " />"
+ if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
+ t += eospan
+ eospan = "";
+ }
+ t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan;
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+function jmolStartNewRadioGroup() {
+ ++_jmol.radioGroupCount;
+}
+
+function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName, id, title) {
+ /*
+
+ array: [radio1,radio2,radio3...]
+ where radioN = ["script","label",isSelected,"id","title"]
+
+ */
+
+ _jmolInitCheck();
+ var type = typeof arrayOfRadioButtons;
+ if (type != "object" || type == null || ! arrayOfRadioButtons.length) {
+ alert("invalid arrayOfRadioButtons");
+ return;
+ }
+ separatorHtml != undefined && separatorHtml != null || (separatorHtml = " ");
+ var len = arrayOfRadioButtons.length;
+ jmolStartNewRadioGroup();
+ groupName || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));
+ var t = "<span id='"+(id ? id : groupName)+"'>";
+ for (var i = 0; i < len; ++i) {
+ if (i == len - 1)
+ separatorHtml = "";
+ var radio = arrayOfRadioButtons[i];
+ type = typeof radio;
+ if (type == "object") {
+ t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName, (radio.length > 3 ? radio[3]: (id ? id : groupName)+"_"+i), (radio.length > 4 ? radio[4] : 0), title);
+ } else {
+ t += _jmolRadio(radio, null, null, separatorHtml, groupName, (id ? id : groupName)+"_"+i, title);
+ }
+ }
+ t+="</span>"
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+
+function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
+ _jmolInitCheck();
+ if (_jmol.radioGroupCount == 0)
+ ++_jmol.radioGroupCount;
+ var t = _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, (id ? id : groupName + "_" + _jmol.radioCount), title ? title : 0);
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+function jmolLink(script, label, id, title) {
+ _jmolInitCheck();
+ id != undefined && id != null || (id = "jmolLink" + _jmol.linkCount);
+ label != undefined && label != null || (label = script.substring(0, 32));
+ ++_jmol.linkCount;
+ var scriptIndex = _jmolAddScript(script);
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><a name='" + id + "' id='" + id +
+ "' href='javascript:_jmolClick(this," + scriptIndex + _jmol.targetText + ");' onmouseover='_jmolMouseOver(" + scriptIndex +
+ ");return true;' onmouseout='_jmolMouseOut()' " +
+ _jmol.linkCssText + ">" + label + "</a></span>";
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+function jmolCommandInput(label, size, id, title) {
+ _jmolInitCheck();
+ id != undefined && id != null || (id = "jmolCmd" + _jmol.cmdCount);
+ label != undefined && label != null || (label = "Execute");
+ size != undefined && !isNaN(size) || (size = 60);
+ ++_jmol.cmdCount;
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='" + id + "' id='" + id +
+ "' size='"+size+"' onkeypress='_jmolCommandKeyPress(event,\""+id+"\"" + _jmol.targetText + ")'><input type=button value = '"+label+"' onclick='jmolScript(document.getElementById(\""+id+"\").value" + _jmol.targetText + ")' /></span>";
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+function _jmolCommandKeyPress(e, id, target) {
+ var keycode = (window.event ? window.event.keyCode : e ? e.which : 0);
+ if (keycode == 13) {
+ var inputBox = document.getElementById(id)
+ _jmolScriptExecute(inputBox, inputBox.value, target)
+ }
+}
+
+function _jmolScriptExecute(element,script,target) {
+ if (typeof(script) == "object")
+ script[0](element, script, target)
+ else
+ jmolScript(script, target)
+}
+
+function jmolMenu(arrayOfMenuItems, size, id, title) {
+ _jmolInitCheck();
+ id != undefined && id != null || (id = "jmolMenu" + _jmol.menuCount);
+ ++_jmol.menuCount;
+ var type = typeof arrayOfMenuItems;
+ if (type != null && type == "object" && arrayOfMenuItems.length) {
+ var len = arrayOfMenuItems.length;
+ if (typeof size != "number" || size == 1)
+ size = null;
+ else if (size < 0)
+ size = len;
+ var sizeText = size ? " size='" + size + "' " : "";
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><select name='" + id + "' id='" + id +
+ "' onChange='_jmolMenuSelected(this" + _jmol.targetText + ")'" +
+ sizeText + _jmol.menuCssText + ">";
+ for (var i = 0; i < len; ++i) {
+ var menuItem = arrayOfMenuItems[i];
+ type = typeof menuItem;
+ var script, text;
+ var isSelected = undefined;
+ if (type == "object" && menuItem != null) {
+ script = menuItem[0];
+ text = menuItem[1];
+ isSelected = menuItem[2];
+ } else {
+ script = text = menuItem;
+ }
+ text != undefined && text != null || (text = script);
+ if (script=="#optgroup") {
+ t += "<optgroup label='" + text + "'>";
+ } else if (script=="#optgroupEnd") {
+ t += "</optgroup>";
+ } else {
+ var scriptIndex = _jmolAddScript(script);
+ var selectedText = isSelected ? "' selected='true'>" : "'>";
+ t += "<option value='" + scriptIndex + selectedText + text + "</option>";
+ }
+ }
+ t += "</select></span>";
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+ }
+}
+
+function jmolHtml(html) {
+ return _jmolDocumentWrite(html);
+}
+
+function jmolBr() {
+ return _jmolDocumentWrite("<br />");
+}
+
+////////////////////////////////////////////////////////////////
+// advanced scripting functions
+////////////////////////////////////////////////////////////////
+
+function jmolDebugAlert(enableAlerts) {
+ _jmol.debugAlert = (enableAlerts == undefined || enableAlerts)
+}
+
+function jmolAppletInline(size, inlineModel, script, nameSuffix) {
+ _jmolInitCheck();
+ return _jmolApplet(size, _jmolSterilizeInline(inlineModel),
+ script, nameSuffix);
+}
+
+function jmolSetTarget(targetSuffix) {
+ _jmol.targetSuffix = targetSuffix;
+ _jmol.targetText = targetSuffix ? ",\"" + targetSuffix + "\"" : ",0";
+}
+
+function jmolScript(script, targetSuffix) {
+ if (script) {
+ _jmolCheckBrowser();
+ if (targetSuffix == "all") {
+ with (_jmol) {
+ for (var i = 0; i < appletSuffixes.length; ++i) {
+ var applet = _jmolGetApplet(appletSuffixes[i]);
+ if (applet) applet.script(script);
+ }
+ }
+ } else {
+ var applet=_jmolGetApplet(targetSuffix);
+ if (applet) applet.script(script);
+ }
+ }
+}
+
+function jmolLoadInline(model, targetSuffix) {
+ if (!model)return "ERROR: NO MODEL"
+ var applet=_jmolGetApplet(targetSuffix);
+ if (!applet)return "ERROR: NO APPLET"
+ if (typeof(model) == "string")
+ return applet.loadInlineString(model, "", false);
+ else
+ return applet.loadInlineArray(model, "", false);
+}
+
+
+function jmolLoadInlineScript(model, script, targetSuffix) {
+ if (!model)return "ERROR: NO MODEL"
+ var applet=_jmolGetApplet(targetSuffix);
+ if (!applet)return "ERROR: NO APPLET"
+ return applet.loadInlineString(model, script, false);
+}
+
+
+function jmolLoadInlineArray(ModelArray, script, targetSuffix) {
+ if (!model)return "ERROR: NO MODEL"
+ script || (script="")
+ var applet=_jmolGetApplet(targetSuffix);
+ if (!applet)return "ERROR: NO APPLET"
+ try {
+ return applet.loadInlineArray(ModelArray, script, false);
+ } catch (err) {
+ //IE 7 bug
+ return applet.loadInlineString(ModelArray.join("\n"), script, false);
+ }
+}
+
+function jmolAppendInlineArray(ModelArray, script, targetSuffix) {
+ if (!model)return "ERROR: NO MODEL"
+ script || (script="")
+ var applet=_jmolGetApplet(targetSuffix);
+ if (!applet)return "ERROR: NO APPLET"
+ try {
+ return applet.loadInlineArray(ModelArray, script, true);
+ } catch (err) {
+ //IE 7 bug
+ return applet.loadInlineString(ModelArray.join("\n"), script, true);
+ }
+}
+
+function jmolAppendInlineScript(model, script, targetSuffix) {
+ if (!model)return "ERROR: NO MODEL"
+ var applet=_jmolGetApplet(targetSuffix);
+ if (!applet)return "ERROR: NO APPLET"
+ return applet.loadInlineString(model, script, true);
+}
+
+function jmolCheckBrowser(action, urlOrMessage, nowOrLater) {
+ if (typeof action == "string") {
+ action = action.toLowerCase();
+ action == "alert" || action == "redirect" || action == "popup" || (action = null);
+ }
+ if (typeof action != "string")
+ alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
+ "action must be 'alert', 'redirect', or 'popup'");
+ else {
+ if (typeof urlOrMessage != "string")
+ alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
+ "urlOrMessage must be a string");
+ else {
+ _jmol.checkBrowserAction = action;
+ _jmol.checkBrowserUrlOrMessage = urlOrMessage;
+ }
+ }
+ if (typeof nowOrLater == "string" && nowOrLater.toLowerCase() == "now")
+ _jmolCheckBrowser();
+}
+
+////////////////////////////////////////////////////////////////
+// Cascading Style Sheet Class support
+////////////////////////////////////////////////////////////////
+
+function jmolSetAppletCssClass(appletCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.appletCssClass = appletCssClass;
+ _jmol.appletCssText = appletCssClass ? "class='" + appletCssClass + "' " : "";
+ }
+}
+
+function jmolSetButtonCssClass(buttonCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.buttonCssClass = buttonCssClass;
+ _jmol.buttonCssText = buttonCssClass ? "class='" + buttonCssClass + "' " : "";
+ }
+}
+
+function jmolSetCheckboxCssClass(checkboxCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.checkboxCssClass = checkboxCssClass;
+ _jmol.checkboxCssText = checkboxCssClass ? "class='" + checkboxCssClass + "' " : "";
+ }
+}
+
+function jmolSetRadioCssClass(radioCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.radioCssClass = radioCssClass;
+ _jmol.radioCssText = radioCssClass ? "class='" + radioCssClass + "' " : "";
+ }
+}
+
+function jmolSetLinkCssClass(linkCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.linkCssClass = linkCssClass;
+ _jmol.linkCssText = linkCssClass ? "class='" + linkCssClass + "' " : "";
+ }
+}
+
+function jmolSetMenuCssClass(menuCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.menuCssClass = menuCssClass;
+ _jmol.menuCssText = menuCssClass ? "class='" + menuCssClass + "' " : "";
+ }
+}
+
+////////////////////////////////////////////////////////////////
+// functions for INTERNAL USE ONLY which are subject to change
+// use at your own risk ... you have been WARNED!
+////////////////////////////////////////////////////////////////
+var _jmol = {
+ currentDocument: document,
+
+ debugAlert: false,
+
+ codebase: "",
+ modelbase: ".",
+
+ appletCount: 0,
+ appletSuffixes: [],
+ appletWindow: null,
+ allowedJmolSize: [25, 2048, 300], // min, max, default (pixels)
+ /* By setting the _jmol.allowedJmolSize[] variable in the webpage
+ before calling jmolApplet(), limits for applet size can be overriden.
+ 2048 standard for GeoWall (http://geowall.geo.lsa.umich.edu/home.html)
+ */
+ buttonCount: 0,
+ checkboxCount: 0,
+ linkCount: 0,
+ cmdCount: 0,
+ menuCount: 0,
+ radioCount: 0,
+ radioGroupCount: 0,
+
+ appletCssClass: null,
+ appletCssText: "",
+ buttonCssClass: null,
+ buttonCssText: "",
+ checkboxCssClass: null,
+ checkboxCssText: "",
+ java_arguments: "-Xmx512m",
+ radioCssClass: null,
+ radioCssText: "",
+ linkCssClass: null,
+ linkCssText: "",
+ menuCssClass: null,
+ menuCssText: "",
+
+ targetSuffix: 0,
+ targetText: ",0",
+ scripts: [""],
+ params: {
+ syncId: ("" + Math.random()).substring(3),
+ progressbar: "true",
+ progresscolor: "blue",
+ boxbgcolor: "black",
+ boxfgcolor: "white",
+ boxmessage: "Downloading JmolApplet ..."
+ },
+ ua: navigator.userAgent.toLowerCase(),
+ // uaVersion: parseFloat(navigator.appVersion), // not used
+
+ os: "unknown",
+ browser: "unknown",
+ browserVersion: 0,
+ hasGetElementById: !!document.getElementById,
+ isJavaEnabled: navigator.javaEnabled(),
+ // isNetscape47Win: false, // not used, N4.7 is no longer supported even for detection
+ useIEObject: false,
+ useHtml4Object: false,
+
+ windowsClassId: "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93",
+ windowsCabUrl:
+ "http://java.sun.com/update/1.6.0/jinstall-6u22-windows-i586.cab",
+
+ isBrowserCompliant: false,
+ isJavaCompliant: false,
+ isFullyCompliant: false,
+
+ initialized: false,
+ initChecked: false,
+
+ browserChecked: false,
+ checkBrowserAction: "alert",
+ checkBrowserUrlOrMessage: null,
+
+ archivePath: null, // JmolApplet0.jar OR JmolAppletSigned0.jar
+
+ previousOnloadHandler: null,
+
+ jmoljar: null,
+ useNoApplet: false,
+
+ ready: {}
+}
+
+with (_jmol) {
+ function _jmolTestUA(candidate) {
+ var ua = _jmol.ua;
+ var index = ua.indexOf(candidate);
+ if (index < 0)
+ return false;
+ _jmol.browser = candidate;
+ _jmol.browserVersion = parseFloat(ua.substring(index+candidate.length+1));
+ return true;
+ }
+
+ function _jmolTestOS(candidate) {
+ if (_jmol.ua.indexOf(candidate) < 0)
+ return false;
+ _jmol.os = candidate;
+ return true;
+ }
+
+ _jmolTestUA("konqueror") ||
+ _jmolTestUA("webkit") ||
+ _jmolTestUA("omniweb") ||
+ _jmolTestUA("opera") ||
+ _jmolTestUA("webtv") ||
+ _jmolTestUA("icab") ||
+ _jmolTestUA("msie") ||
+ (_jmol.ua.indexOf("compatible") < 0 && _jmolTestUA("mozilla")); //Netscape, Mozilla, Seamonkey, Firefox and anything assimilated
+
+ _jmolTestOS("linux") ||
+ _jmolTestOS("unix") ||
+ _jmolTestOS("mac") ||
+ _jmolTestOS("win");
+
+ /* not used:
+ isNetscape47Win = (os == "win" && browser == "mozilla" &&
+ browserVersion >= 4.78 && browserVersion <= 4.8);
+ */
+
+ if (os == "win") {
+ isBrowserCompliant = hasGetElementById;
+ } else if (os == "mac") { // mac is the problem child :-(
+ if (browser == "mozilla" && browserVersion >= 5) {
+ // miguel 2004 11 17
+ // checking the plugins array does not work because
+ // Netscape 7.2 OS X still has Java 1.3.1 listed even though
+ // javaplugin.sf.net is installed to upgrade to 1.4.2
+ eval("try {var v = java.lang.System.getProperty('java.version');" +
+ " _jmol.isBrowserCompliant = v >= '1.4.2';" +
+ " } catch (e) { }");
+ } else if (browser == "opera" && browserVersion <= 7.54) {
+ isBrowserCompliant = false;
+ } else {
+ isBrowserCompliant = hasGetElementById &&
+ !((browser == "msie") ||
+ (browser == "webkit" && browserVersion < 125.12));
+ }
+ } else if (os == "linux" || os == "unix") {
+ if (browser == "konqueror" && browserVersion <= 3.3)
+ isBrowserCompliant = false;
+ else
+ isBrowserCompliant = hasGetElementById;
+ } else { // other OS
+ isBrowserCompliant = hasGetElementById;
+ }
+
+ // possibly more checks in the future for this
+ isJavaCompliant = isJavaEnabled;
+
+ isFullyCompliant = isBrowserCompliant && isJavaCompliant;
+
+ useIEObject = (os == "win" && browser == "msie" && browserVersion >= 5.5);
+ useHtml4Object =
+ (browser == "mozilla" && browserVersion >= 5) ||
+ (browser == "opera" && browserVersion >= 8) ||
+ (browser == "webkit" && browserVersion >= 412.2);
+ try {
+ if (top.location.search.indexOf("JMOLJAR=")>=0)
+ jmoljar = top.location.search.split("JMOLJAR=")[1].split("&")[0];
+ } catch(e) {
+ // can't access top.location
+ }
+ try {
+ useNoApplet = (top.location.search.indexOf("NOAPPLET")>=0);
+ } catch(e) {
+ // can't access top.document
+ }
+}
+
+function jmolSetMemoryMb(nMb) {
+ _jmol.java_arguments = "-Xmx" + Math.round(nMb) + "m"
+}
+
+function jmolSetParameter(name,value) {
+ _jmol.params[name] = value
+}
+
+function jmolSetCallback(callbackName,funcName) {
+ _jmol.params[callbackName] = funcName
+}
+
+ try {
+// note this is done FIRST, so it cannot override a setting done by the developer
+ if (top.location.search.indexOf("PARAMS=")>=0) {
+ var pars = unescape(top.location.search.split("PARAMS=")[1].split("&")[0]).split(";");
+ for (var i = 0; i < pars.length; i++) {
+ var p = pars[i].split(":");
+ jmolSetParameter(p[0],p[1]);
+ }
+ }
+ } catch(e) {
+ // can't access top.location
+ }
+
+function jmolSetSyncId(n) {
+ return _jmol.params["syncId"] = n
+}
+
+function jmolGetSyncId() {
+ return _jmol.params["syncId"]
+}
+
+function jmolSetLogLevel(n) {
+ _jmol.params.logLevel = ''+n;
+}
+
+ /* AngelH, mar2007:
+ By (re)setting these variables in the webpage before calling jmolApplet(),
+ a custom message can be provided (e.g. localized for user's language) when no Java is installed.
+ */
+if (noJavaMsg==undefined) var noJavaMsg =
+ "You do not have Java applets enabled in your web browser, or your browser is blocking this applet.<br />\n" +
+ "Check the warning message from your browser and/or enable Java applets in<br />\n" +
+ "your web browser preferences, or install the Java Runtime Environment from <a href='http://www.java.com'>www.java.com</a><br />";
+if (noJavaMsg2==undefined) var noJavaMsg2 =
+ "You do not have the<br />\n" +
+ "Java Runtime Environment<br />\n" +
+ "installed for applet support.<br />\n" +
+ "Visit <a href='http://www.java.com'>www.java.com</a>";
+function _jmolApplet(size, inlineModel, script, nameSuffix) {
+ /* AngelH, mar2007
+ Fixed percent / pixel business, to avoid browser errors:
+ put "px" where needed, avoid where not.
+
+ Bob Hanson, 1/2010
+ Fixed inline escape changing returns to |
+ */
+ with (_jmol) {
+ nameSuffix == undefined && (nameSuffix = appletCount);
+ appletSuffixes.push(nameSuffix);
+ ++appletCount;
+ script || (script = "select *");
+ var sz = _jmolGetAppletSize(size);
+ var widthAndHeight = " width='" + sz[0] + "' height='" + sz[1] + "' ";
+ var tHeader, tFooter;
+ codebase || jmolInitialize(".");
+ if (useIEObject || useHtml4Object) {
+ params.archive = archivePath;
+ params.mayscript = 'true';
+ params.codebase = codebase;
+ params.code = 'JmolApplet';
+ tHeader =
+ "<object name='jmolApplet" + nameSuffix +
+ "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
+ widthAndHeight + "\n";
+ tFooter = "</object>";
+ }
+ if (java_arguments)
+ params.java_arguments = java_arguments;
+ if (useIEObject) { // use MSFT IE6 object tag with .cab file reference
+ tHeader += " classid='" + windowsClassId + "'\n" +
+ (windowsCabUrl ? " codebase='" + windowsCabUrl + "'\n" : "") + ">\n";
+ } else if (useHtml4Object) { // use HTML4 object tag
+ tHeader += " type='application/x-java-applet'\n>\n";
+ /* " classid='java:JmolApplet'\n" + AH removed this
+ Chromium Issue 62076: Java Applets using an <object> with a classid paramater don't load.
+ http://code.google.com/p/chromium/issues/detail?id=62076
+ They say this is the correct behavior according to the spec, and there's no indication at this point
+ that WebKit will be changing the handling, so eventually Safari will acquire this behavior too.
+ Removing the classid parameter seems to be well tolerated by all browsers (even IE!).
+ */
+ } else { // use applet tag
+ tHeader =
+ "<applet name='jmolApplet" + nameSuffix +
+ "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
+ widthAndHeight + "\n" +
+ " code='JmolApplet'" +
+ " archive='" + archivePath + "' codebase='" + codebase + "'\n" +
+ " mayscript='true'>\n";
+ tFooter = "</applet>";
+ }
+ var visitJava;
+ if (useIEObject || useHtml4Object) {
+ var szX = "width:" + sz[0]
+ if ( szX.indexOf("%")==-1 ) szX+="px"
+ var szY = "height:" + sz[1]
+ if ( szY.indexOf("%")==-1 ) szY+="px"
+ visitJava =
+ "<p style='background-color:yellow; color:black; " +
+ szX + ";" + szY + ";" +
+ // why doesn't this vertical-align work?
+ "text-align:center;vertical-align:middle;'>\n" +
+ noJavaMsg +
+ "</p>";
+ } else {
+ visitJava =
+ "<table bgcolor='yellow'><tr>" +
+ "<td align='center' valign='middle' " + widthAndHeight + "><font color='black'>\n" +
+ noJavaMsg2 +
+ "</font></td></tr></table>";
+ }
+ params.loadInline = (inlineModel ? inlineModel : "");
+ params.script = (script ? _jmolSterilizeScript(script) : "");
+ var t = tHeader + _jmolParams() + visitJava + tFooter;
+ jmolSetTarget(nameSuffix);
+ ready["jmolApplet" + nameSuffix] = false;
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+ }
+}
+
+function _jmolParams() {
+ var t = "";
+ for (var i in _jmol.params)
+ if(_jmol.params[i]!="")
+ t+=" <param name='"+i+"' value='"+_jmol.params[i]+"' />\n";
+ return t
+}
+
+function _jmolInitCheck() {
+ if (_jmol.initChecked)
+ return;
+ _jmol.initChecked = true;
+ jmolInitialize(defaultdir, defaultjar)
+}
+
+function _jmolCheckBrowser() {
+ with (_jmol) {
+ if (browserChecked)
+ return;
+ browserChecked = true;
+
+ if (isFullyCompliant)
+ return true;
+
+ if (checkBrowserAction == "redirect")
+ location.href = checkBrowserUrlOrMessage;
+ else if (checkBrowserAction == "popup")
+ _jmolPopup(checkBrowserUrlOrMessage);
+ else {
+ var msg = checkBrowserUrlOrMessage;
+ if (msg == null)
+ msg = "Your web browser is not fully compatible with Jmol\n\n" +
+ "browser: " + browser +
+ " version: " + browserVersion +
+ " os: " + os +
+ " isBrowserCompliant: " + isBrowserCompliant +
+ " isJavaCompliant: " + isJavaCompliant +
+ "\n\n" + ua;
+ alert(msg);
+ }
+ }
+ return false;
+}
+
+function jmolSetXHTML(id) {
+ _jmol.isXHTML = true
+ _jmol.XhtmlElement = null
+ _jmol.XhtmlAppendChild = false
+ if (id){
+ _jmol.XhtmlElement = document.getElementById(id)
+ _jmol.XhtmlAppendChild = true
+ }
+}
+
+function _jmolDocumentWrite(text) {
+ if (_jmol.currentDocument) {
+ if (_jmol.isXHTML && !_jmol.XhtmlElement) {
+ var s = document.getElementsByTagName("script")
+ _jmol.XhtmlElement = s.item(s.length - 1)
+ _jmol.XhtmlAppendChild = false
+ }
+ if (_jmol.XhtmlElement) {
+ _jmolDomDocumentWrite(text)
+ } else {
+ _jmol.currentDocument.write(text);
+ }
+ }
+ return text;
+}
+
+function _jmolDomDocumentWrite(data) {
+ var pt = 0
+ var Ptr = []
+ Ptr[0] = 0
+ while (Ptr[0] < data.length) {
+ var child = _jmolGetDomElement(data, Ptr)
+ if (!child)break
+ if (_jmol.XhtmlAppendChild)
+ _jmol.XhtmlElement.appendChild(child)
+ else
+ _jmol.XhtmlElement.parentNode.insertBefore(child, _jmol.XhtmlElement);
+ }
+}
+function _jmolGetDomElement(data, Ptr, closetag, lvel) {
+ var e = document.createElement("span")
+ e.innerHTML = data
+ Ptr[0] = data.length
+ return e
+
+//unnecessary?
+
+ closetag || (closetag = "")
+ lvel || (lvel = 0)
+ var pt0 = Ptr[0]
+ var pt = pt0
+ while (pt < data.length && data.charAt(pt) != "<") pt++
+ if (pt != pt0) {
+ var text = data.substring(pt0, pt)
+ Ptr[0] = pt
+ return document.createTextNode(text)
+ }
+ pt0 = ++pt
+ var ch
+ while (pt < data.length && "\n\r\t >".indexOf(ch = data.charAt(pt)) < 0) pt++
+ var tagname = data.substring(pt0, pt)
+ var e = (tagname == closetag || tagname == "/" ? ""
+ : document.createElementNS ? document.createElementNS('http://www.w3.org/1999/xhtml', tagname)
+ : document.createElement(tagname));
+ if (ch == ">") {
+ Ptr[0] = ++pt
+ return e
+ }
+ while (pt < data.length && (ch = data.charAt(pt)) != ">") {
+ while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++
+ pt0 = pt
+ while (pt < data.length && "\n\r\t =/>".indexOf(ch = data.charAt(pt)) < 0) pt++
+ var attrname = data.substring(pt0, pt).toLowerCase()
+ if (attrname && ch != "=")
+ e.setAttribute(attrname, "true")
+ while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++
+ if (ch == "/") {
+ Ptr[0] = pt + 2
+ return e
+ } else if (ch == "=") {
+ var quote = data.charAt(++pt)
+ pt0 = ++pt
+ while (pt < data.length && (ch = data.charAt(pt)) != quote) pt++
+ var attrvalue = data.substring(pt0, pt)
+ e.setAttribute(attrname, attrvalue)
+ pt++
+ }
+ }
+ Ptr[0] = ++pt
+ while (Ptr[0] < data.length) {
+ var child = _jmolGetDomElement(data, Ptr, "/" + tagname, lvel+1)
+ if (!child)break
+ e.appendChild(child)
+ }
+ return e
+}
+
+function _jmolPopup(url) {
+ var popup = window.open(url, "JmolPopup",
+ "left=150,top=150,height=400,width=600," +
+ "directories=yes,location=yes,menubar=yes," +
+ "toolbar=yes," +
+ "resizable=yes,scrollbars=yes,status=yes");
+ if (popup.focus)
+ poup.focus();
+}
+
+function _jmolReadyCallback(name) {
+ if (_jmol.debugAlert)
+ alert(name + " is ready");
+ _jmol.ready["" + name] = true;
+}
+
+function _jmolSterilizeScript(script) {
+ script = script.replace(/'/g, "'");
+ if (_jmol.debugAlert)
+ alert("script:\n" + script);
+ return script;
+}
+
+function _jmolSterilizeInline(model) {
+ model = model.replace(/\r|\n|\r\n/g, (model.indexOf("|") >= 0 ? "\\/n" : "|")).replace(/'/g, "'");
+ if (_jmol.debugAlert)
+ alert("inline model:\n" + model);
+ return model;
+}
+
+function _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
+ ++_jmol.radioCount;
+ groupName != undefined && groupName != null || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));
+ if (!script)
+ return "";
+ labelHtml != undefined && labelHtml != null || (labelHtml = script.substring(0, 32));
+ separatorHtml || (separatorHtml = "")
+ var scriptIndex = _jmolAddScript(script);
+ var eospan = "</span>"
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='"
+ + groupName + "' id='"+id+"' type='radio' onclick='_jmolClick(this," +
+ scriptIndex + _jmol.targetText + ");return true;' onmouseover='_jmolMouseOver(" +
+ scriptIndex + ");return true;' onmouseout='_jmolMouseOut()' " +
+ (isChecked ? "checked='true' " : "") + _jmol.radioCssText + " />"
+ if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
+ t += eospan
+ eospan = "";
+ }
+ t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan + separatorHtml;
+
+ return t;
+}
+
+function _jmolFindApplet(target) {
+ // first look for the target in the current window
+ var applet = _jmolFindAppletInWindow(_jmol.appletWindow != null ? _jmol.appletWindow : window, target);
+ // THEN look for the target in child frames
+ if (applet == undefined)
+ applet = _jmolSearchFrames(window, target);
+ // FINALLY look for the target in sibling frames
+ if (applet == undefined)
+ applet = _jmolSearchFrames(top, target); // look starting in top frame
+ return applet;
+}
+
+function _jmolGetApplet(targetSuffix){
+ var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");
+ var applet = _jmolFindApplet(target);
+ if (applet) return applet
+ _jmol.alerted || alert("could not find applet " + target);
+ _jmol.alerted = true;
+ return null
+}
+
+function _jmolSearchFrames(win, target) {
+ var applet;
+ var frames = win.frames;
+ if (frames && frames.length) { // look in all the frames below this window
+ try{
+ for (var i = 0; i < frames.length; ++i) {
+ applet = _jmolSearchFrames(frames[i], target);
+ if (applet)
+ return applet;
+ }
+ }catch(e) {
+ if (_jmol.debugAlert)
+ alert("Jmol.js _jmolSearchFrames cannot access " + win.name + ".frame[" + i + "] consider using jmolSetAppletWindow()")
+ }
+ }
+ return applet = _jmolFindAppletInWindow(win, target)
+}
+
+function _jmolFindAppletInWindow(win, target) {
+ var doc = win.document;
+ if (doc.getElementById(target))
+ return doc.getElementById(target);
+ else if (doc.applets)
+ return doc.applets[target];
+ else
+ return doc[target];
+}
+
+function _jmolAddScript(script) {
+ if (!script)
+ return 0;
+ var index = _jmol.scripts.length;
+ _jmol.scripts[index] = script;
+ return index;
+}
+
+function _jmolClick(elementClicked, scriptIndex, targetSuffix) {
+ _jmol.element = elementClicked;
+ _jmolScriptExecute(elementClicked, _jmol.scripts[scriptIndex], targetSuffix);
+}
+
+function _jmolMenuSelected(menuObject, targetSuffix) {
+ var scriptIndex = menuObject.value;
+ if (scriptIndex != undefined) {
+ _jmolScriptExecute(menuObject, _jmol.scripts[scriptIndex], targetSuffix);
+ return;
+ }
+ var len = menuObject.length;
+ if (typeof len == "number") {
+ for (var i = 0; i < len; ++i) {
+ if (menuObject[i].selected) {
+ _jmolClick(menuObject[i], menuObject[i].value, targetSuffix);
+ return;
+ }
+ }
+ }
+ alert("?Que? menu selected bug #8734");
+}
+
+
+_jmol.checkboxMasters = {};
+_jmol.checkboxItems = {};
+
+function jmolSetCheckboxGroup(chkMaster,chkBox) {
+ var id = chkMaster;
+ if(typeof(id)=="number")id = "jmolCheckbox" + id;
+ chkMaster = document.getElementById(id);
+ if (!chkMaster)alert("jmolSetCheckboxGroup: master checkbox not found: " + id);
+ var m = _jmol.checkboxMasters[id] = {};
+ m.chkMaster = chkMaster;
+ m.chkGroup = {};
+ for (var i = 1; i < arguments.length; i++){
+ var id = arguments[i];
+ if(typeof(id)=="number")id = "jmolCheckbox" + id;
+ checkboxItem = document.getElementById(id);
+ if (!checkboxItem)alert("jmolSetCheckboxGroup: group checkbox not found: " + id);
+ m.chkGroup[id] = checkboxItem;
+ _jmol.checkboxItems[id] = m;
+ }
+}
+
+function _jmolNotifyMaster(m){
+ //called when a group item is checked
+ var allOn = true;
+ var allOff = true;
+ for (var chkBox in m.chkGroup){
+ if(m.chkGroup[chkBox].checked)
+ allOff = false;
+ else
+ allOn = false;
+ }
+ if (allOn)m.chkMaster.checked = true;
+ if (allOff)m.chkMaster.checked = false;
+ if ((allOn || allOff) && _jmol.checkboxItems[m.chkMaster.id])
+ _jmolNotifyMaster(_jmol.checkboxItems[m.chkMaster.id])
+}
+
+function _jmolNotifyGroup(m, isOn){
+ //called when a master item is checked
+ for (var chkBox in m.chkGroup){
+ var item = m.chkGroup[chkBox]
+ item.checked = isOn;
+ if (_jmol.checkboxMasters[item.id])
+ _jmolNotifyGroup(_jmol.checkboxMasters[item.id], isOn)
+ }
+}
+
+function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) {
+ _jmol.control = ckbox
+ _jmolClick(ckbox, ckbox.checked ? whenChecked : whenUnchecked, targetSuffix);
+ if(_jmol.checkboxMasters[ckbox.id])
+ _jmolNotifyGroup(_jmol.checkboxMasters[ckbox.id], ckbox.checked)
+ if(_jmol.checkboxItems[ckbox.id])
+ _jmolNotifyMaster(_jmol.checkboxItems[ckbox.id])
+}
+
+function _jmolCbOver(ckbox, whenChecked, whenUnchecked) {
+ window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked];
+}
+
+function _jmolMouseOver(scriptIndex) {
+ window.status = _jmol.scripts[scriptIndex];
+}
+
+function _jmolMouseOut() {
+ window.status = " ";
+ return true;
+}
+
+function _jmolSetCodebase(codebase) {
+ _jmol.codebase = codebase ? codebase : ".";
+ if (_jmol.debugAlert)
+ alert("jmolCodebase=" + _jmol.codebase);
+}
+
+function _jmolOnloadResetForms() {
+ // must be evaluated ONLY once
+ _jmol.previousOnloadHandler = window.onload;
+ window.onload =
+ function() {
+ with (_jmol) {
+ if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) {
+ var forms = document.forms;
+ for (var i = forms.length; --i >= 0; )
+ forms[i].reset();
+ }
+ if (previousOnloadHandler)
+ previousOnloadHandler();
+ }
+ }
+}
+
+////////////////////////////////////
+/////extensions for getProperty/////
+////////////////////////////////////
+
+
+function _jmolEvalJSON(s,key){
+ s=s+""
+ if(!s)return []
+ if(s.charAt(0)!="{"){
+ if(s.indexOf(" | ")>=0)s=s.replace(/\ \|\ /g, "\n")
+ return s
+ }
+ var A = eval("("+s+")")
+ if(!A)return
+ if(key && A[key])A=A[key]
+ return A
+}
+
+function _jmolEnumerateObject(A,key){
+ var sout=""
+ if(typeof(A) == "string" && A!="null"){
+ sout+="\n"+key+"=\""+A+"\""
+ }else if(!isNaN(A)||A==null){
+ sout+="\n"+key+"="+(A+""==""?"null":A)
+ }else if(A.length){
+ sout+=key+"=[]"
+ for(var i=0;i<A.length;i++){
+ sout+="\n"
+ if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
+ sout+=_jmolEnumerateObject(A[i],key+"["+i+"]")
+ }else{
+ sout+=key+"["+i+"]="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
+ }
+ }
+ }else{
+ if(key != ""){
+ sout+=key+"={}"
+ key+="."
+ }
+
+ for(var i in A){
+ sout+="\n"
+ if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
+ sout+=_jmolEnumerateObject(A[i],key+i)
+ }else{
+ sout+=key+i+"="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
+ }
+ }
+ }
+ return sout
+}
+
+
+function _jmolSortKey0(a,b){
+ return (a[0]<b[0]?1:a[0]>b[0]?-1:0)
+}
+
+function _jmolSortMessages(A){
+ if(!A || typeof(A)!="object")return []
+ var B = []
+ for(var i=A.length-1;i>=0;i--)for(var j=0;j<A[i].length;j++)B[B.length]=A[i][j]
+ if(B.length == 0) return
+ B=B.sort(_jmolSortKey0)
+ return B
+}
+
+/////////additional extensions //////////
+
+
+function _jmolDomScriptLoad(URL){
+ //open(URL) //to debug
+ _jmol.servercall=URL
+ var node = document.getElementById("_jmolScriptNode")
+ if (node && _jmol.browser!="msie"){
+ document.getElementsByTagName("HEAD")[0].removeChild(node)
+ node=null
+ }
+ if (node) {
+ node.setAttribute("src",URL)
+ } else {
+ node=document.createElement("script")
+ node.setAttribute("id","_jmolScriptNode")
+ node.setAttribute("type","text/javascript")
+ node.setAttribute("src",URL)
+ document.getElementsByTagName("HEAD")[0].appendChild(node)
+ }
+}
+
+
+function _jmolExtractPostData(url){
+ S=url.split("&POST:")
+ var s=""
+ for(var i=1;i<S.length;i++){
+ KV=S[i].split("=")
+ s+="&POSTKEY"+i+"="+KV[0]
+ s+="&POSTVALUE"+i+"="+KV[1]
+ }
+ return "&url="+escape(S[0])+s
+}
+
+function _jmolLoadModel(targetSuffix,remoteURL,array,isError,errorMessage){
+ //called by server, but in client
+ //overload this function to customize return
+ _jmol.remoteURL=remoteURL
+ isError && alert(errorMessage)
+ jmolLoadInlineScript(array.join("\n"),_jmol.optionalscript,targetSuffix)
+}
+
+//////////user property/status functions/////////
+
+function jmolGetStatus(strStatus,targetSuffix){
+ return _jmolSortMessages(jmolGetPropertyAsArray("jmolStatus",strStatus,targetSuffix))
+}
+
+function jmolGetPropertyAsArray(sKey,sValue,targetSuffix) {
+ return _jmolEvalJSON(jmolGetPropertyAsJSON(sKey,sValue,targetSuffix),sKey)
+}
+
+function jmolGetPropertyAsString(sKey,sValue,targetSuffix) {
+ var applet = _jmolGetApplet(targetSuffix);
+ sValue == undefined && (sValue="");
+ return (applet ? applet.getPropertyAsString(sKey,sValue) + "" : "")
+}
+
+function jmolGetPropertyAsJSON(sKey,sValue,targetSuffix) {
+ sValue == undefined && (sValue = "")
+ var applet = _jmolGetApplet(targetSuffix);
+ try {
+ return (applet ? applet.getPropertyAsJSON(sKey,sValue) + "" : "")
+ } catch(e) {
+ return ""
+ }
+}
+
+function jmolGetPropertyAsJavaObject(sKey,sValue,targetSuffix) {
+ sValue == undefined && (sValue = "")
+ var applet = _jmolGetApplet(targetSuffix);
+ return (applet ? applet.getProperty(sKey,sValue) : null)
+}
+
+
+function jmolDecodeJSON(s) {
+ return _jmolEnumerateObject(_jmolEvalJSON(s),"")
+}
+
+
+///////// synchronous scripting ////////
+
+function jmolScriptWait(script, targetSuffix) {
+ targetSuffix == undefined && (targetSuffix="0")
+ var Ret=jmolScriptWaitAsArray(script, targetSuffix)
+ var s = ""
+ for(var i=Ret.length;--i>=0;)
+ for(var j=0;j< Ret[i].length;j++)
+ s+=Ret[i][j]+"\n"
+ return s
+}
+
+function jmolScriptWaitOutput(script, targetSuffix) {
+ targetSuffix == undefined && (targetSuffix="0")
+ var ret = ""
+ try{
+ if (script) {
+ _jmolCheckBrowser();
+ var applet=_jmolGetApplet(targetSuffix);
+ if (applet) ret += applet.scriptWaitOutput(script);
+ }
+ }catch(e){
+ }
+ return ret;
+}
+
+function jmolEvaluate(molecularMath, targetSuffix) {
+
+ //carries out molecular math on a model
+
+ targetSuffix == undefined && (targetSuffix="0")
+ var result = "" + jmolGetPropertyAsJavaObject("evaluate", molecularMath, targetSuffix);
+ var s = result.replace(/\-*\d+/,"")
+ if (s == "" && !isNaN(parseInt(result)))return parseInt(result);
+ var s = result.replace(/\-*\d*\.\d*/,"")
+ if (s == "" && !isNaN(parseFloat(result)))return parseFloat(result);
+ return result;
+}
+
+function jmolScriptEcho(script, targetSuffix) {
+ // returns a newline-separated list of all echos from a script
+ targetSuffix == undefined && (targetSuffix="0")
+ var Ret=jmolScriptWaitAsArray(script, targetSuffix)
+ var s = ""
+ for(var i=Ret.length;--i>=0;)
+ for(var j=Ret[i].length;--j>=0;)
+ if (Ret[i][j][1] == "scriptEcho")s+=Ret[i][j][3]+"\n"
+ return s.replace(/ \| /g, "\n")
+}
+
+
+function jmolScriptMessage(script, targetSuffix) {
+ // returns a newline-separated list of all messages from a script, ending with "script completed\n"
+ targetSuffix == undefined && (targetSuffix="0")
+ var Ret=jmolScriptWaitAsArray(script, targetSuffix)
+ var s = ""
+ for(var i=Ret.length;--i>=0;)
+ for(var j=Ret[i].length;--j>=0;)
+ if (Ret[i][j][1] == "scriptStatus")s+=Ret[i][j][3]+"\n"
+ return s.replace(/ \| /g, "\n")
+}
+
+
+function jmolScriptWaitAsArray(script, targetSuffix) {
+ var ret = ""
+ try{
+ jmolGetStatus("scriptEcho,scriptMessage,scriptStatus,scriptError",targetSuffix)
+ if (script) {
+ _jmolCheckBrowser();
+ var applet=_jmolGetApplet(targetSuffix);
+ if (applet) ret += applet.scriptWait(script);
+ ret = _jmolEvalJSON(ret,"jmolStatus")
+ if(typeof ret == "object")
+ return ret
+ }
+ }catch(e){
+ }
+ return [[ret]]
+}
+
+
+
+//////////// save/restore orientation /////////////
+
+function jmolSaveOrientation(id, targetSuffix) {
+ targetSuffix == undefined && (targetSuffix="0")
+ return _jmol["savedOrientation"+id] = jmolGetPropertyAsArray("orientationInfo","info",targetSuffix).moveTo
+}
+
+function jmolRestoreOrientation(id, targetSuffix) {
+ targetSuffix == undefined && (targetSuffix="0")
+ var s=_jmol["savedOrientation"+id]
+ if (!s || s == "")return
+ s=s.replace(/1\.0/,"0")
+ return jmolScriptWait(s,targetSuffix)
+}
+
+function jmolRestoreOrientationDelayed(id, delay, targetSuffix) {
+ arguments.length < 2 && (delay=1)
+ targetSuffix == undefined && (targetSuffix="0")
+ var s=_jmol["savedOrientation"+id]
+ if (!s || s == "")return
+ s=s.replace(/1\.0/,delay)
+ return jmolScriptWait(s,targetSuffix)
+}
+
+//////////// add parameter /////////////
+/*
+ * for adding callbacks or other parameters. Use:
+
+ jmolSetDocument(0)
+ var s= jmolApplet(....)
+ s = jmolAppletAddParam(s,"messageCallback", "myFunctionName")
+ document.write(s)
+ jmolSetDocument(document) // if you want to then write buttons and such normally
+
+ */
+
+function jmolAppletAddParam(appletCode,name,value){
+ return (value == "" ? appletCode : appletCode.replace(/\<param/,"\n<param name='"+name+"' value='"+value+"' />\n<param"))
+}
+
+///////////////auto load Research Consortium for Structural Biology (RCSB) data ///////////
+
+function jmolLoadAjax_STOLAF_RCSB(fileformat,pdbid,optionalscript,targetSuffix){
+
+ _jmol.thismodel || (_jmol.thismodel = "1crn")
+ _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")
+ _jmol.RCSBserver || (_jmol.RCSBserver="http://www.rcsb.org")
+ _jmol.defaultURL_RCSB || (_jmol.defaultURL_RCSB=_jmol.RCSBserver+"/pdb/files/1CRN.CIF")
+ fileformat || (fileformat="PDB")
+ pdbid || (pdbid=prompt("Enter a 4-digit PDB ID:",_jmol.thismodel))
+ if(!pdbid || pdbid.length != 4)return ""
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ var url=_jmol.defaultURL_RCSB.replace(/1CRN/g,pdbid.toUpperCase())
+ fileformat=="CIF" || (url=url.replace(/CIF/,fileformat))
+ _jmol.optionalscript=optionalscript
+ _jmol.thismodel=pdbid
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.thisurl=url
+ _jmol.modelArray = []
+ url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
+ _jmolDomScriptLoad(url)
+ return url
+}
+
+
+///////////////auto load NIH CACTVS data -- compound name or SMILES ///////////
+
+function jmolLoadAjax_STOLAF_NIH(compoundid,optionalscript,targetSuffix){
+ _jmol.thismodel || (_jmol.thismodel = "aspirin")
+ _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")
+ _jmol.defaultURL_NIH || (_jmol.defaultURL_NIH="http://cactus.nci.nih.gov/chemical/structure/FILE/file?format=sdf&get3d=True")
+ compoundid || (compoundid=prompt("Enter a compound name or a SMILES string:",_jmol.thismodel))
+ if(!compoundid)return ""
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ var url=_jmol.defaultURL_NIH.replace(/FILE/g,compoundid)
+ _jmol.optionalscript=optionalscript
+ _jmol.thismodel=compoundid
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.thisurl=url
+ _jmol.modelArray = []
+ url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
+ _jmolDomScriptLoad(url)
+ return url
+}
+
+
+/////////////// St. Olaf College AJAX server -- ANY URL ///////////
+
+function jmolLoadAjax_STOLAF_ANY(url, userid, optionalscript,targetSuffix){
+ _jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm"
+ _jmol.thisurlANY || (_jmol.thisurlANY = "http://www.stolaf.edu/depts/chemistry/mo/struc/data/ycp3-1.mol")
+ url || (url=prompt("Enter any (uncompressed file) URL:", _jmol.thisurlANY))
+ userid || (userid="0")
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ _jmol.optionalscript=optionalscript
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.modelArray = []
+ _jmol.thisurl = url
+ url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
+ _jmolDomScriptLoad(url)
+}
+
+
+/////////////// Mineralogical Society of America (MSA) data /////////
+
+function jmolLoadAjax_MSA(key,value,optionalscript,targetSuffix){
+
+ _jmol.thiskeyMSA || (_jmol.thiskeyMSA = "mineral")
+ _jmol.thismodelMSA || (_jmol.thismodelMSA = "quartz")
+ _jmol.ajaxURL_MSA || (_jmol.ajaxURL_MSA="http://rruff.geo.arizona.edu/AMS/result.php?mineral=quartz&viewing=ajaxjs")
+ key || (key=prompt("Enter a field:", _jmol.thiskeyMSA))
+ if(!key)return ""
+ value || (value=prompt("Enter a "+key+":", _jmol.thismodelMSA))
+ if(!value)return ""
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ optionalscript == 1 && (optionalscript='load "" {1 1 1}')
+ var url=_jmol.ajaxURL_MSA.replace(/mineral/g,key).replace(/quartz/g,value)
+ _jmol.optionalscript=optionalscript
+ _jmol.thiskeyMSA=key
+ _jmol.thismodelMSA=value
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.thisurl=url
+ _jmol.modelArray = []
+ loadModel=_jmolLoadModel
+ _jmolDomScriptLoad(url)
+ return url
+}
+
+
+
+function jmolLoadAjaxJS(url, userid, optionalscript,targetSuffix){
+ userid || (userid="0")
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ _jmol.optionalscript=optionalscript
+ _jmol.thismodel=userid
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.modelArray = []
+ _jmol.thisurl = url
+ url+="&returnFunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix
+ _jmolDomScriptLoad(url)
+}
+
+
+//// in case Jmol library has already been loaded:
+
+}catch(e){}
+
+///////////////moving atoms //////////////
+
+// HIGHLY experimental!!
+
+function jmolSetAtomCoord(i,x,y,z,targetSuffix){
+ _jmolCheckBrowser();
+ var applet=_jmolGetApplet(targetSuffix);
+ if (applet) applet.getProperty('jmolViewer').setAtomCoord(i,x,y,z)
+}
+
+function jmolSetAtomCoordRelative(i,x,y,z,targetSuffix){
+ _jmolCheckBrowser();
+ var applet=_jmolGetApplet(targetSuffix);
+ if (applet) applet.getProperty('jmolViewer').setAtomCoordRelative(i,x,y,z)
+}
+
+
+///////////////applet fake for testing buttons/////////////
+
+
+if(_jmol.useNoApplet){
+ jmolApplet = function(w){
+ var s="<table style='background-color:black' width="+w+"><tr height="+w+">"
+ +"<td align=center valign=center style='background-color:white'>"
+ +"Applet would be here"
+ +"<p><textarea id=fakeApplet rows=5 cols=50></textarea>"
+ +"</td></tr></table>"
+ return _jmolDocumentWrite(s)
+ }
+
+ _jmolFindApplet = function(){return jmolApplet0}
+
+ jmolApplet0 = {
+ script: function(script){document.getElementById("fakeApplet").value="\njmolScript:\n"+script}
+ ,scriptWait: function(script){document.getElementById("fakeApplet").value="\njmolScriptWait:\n"+script}
+ ,loadInline: function(data,script){document.getElementById("fakeApplet").value="\njmolLoadInline data:\n"+data+"\n\nscript:\n"+script}
+ }
+}
+
+
+///////////////////////////////////////////
+
+ // This should no longer be needed, jmolResizeApplet() is better; kept for backwards compatibility
+ /*
+ Resizes absolutely (pixels) or by percent of window (w or h 0.5 means 50%).
+ targetSuffix is optional and defaults to zero (first applet in page).
+ Both w and h are optional, but needed if you want to use targetSuffix.
+ h defaults to w
+ w defaults to 100% of window
+ If either w or h is between 0 and 1, then it is taken as percent/100.
+ If either w or h is greater than 1, then it is taken as a size (pixels).
+ */
+function jmolResize(w,h,targetSuffix) {
+ _jmol.alerted = true;
+ var percentW = (!w ? 100 : w <= 1 && w > 0 ? w * 100 : 0);
+ var percentH = (!h ? percentW : h <= 1 && h > 0 ? h * 100 : 0);
+ if (_jmol.browser=="msie") {
+ var width=document.body.clientWidth;
+ var height=document.body.clientHeight;
+ } else {
+ var netscapeScrollWidth=15;
+ var width=window.innerWidth - netscapeScrollWidth;
+ var height=window.innerHeight-netscapeScrollWidth;
+ }
+ var applet = _jmolGetApplet(targetSuffix);
+ if(!applet)return;
+ applet.style.width = (percentW ? width * percentW/100 : w)+"px";
+ applet.style.height = (percentH ? height * percentH/100 : (h ? h : w))+"px";
+ //title=width + " " + height + " " + (new Date());
+}
+
+// 13 Jun 09 -- makes jmolResize() obsolete (kept for backwards compatibility)
+function jmolResizeApplet(size,targetSuffix) {
+ // See _jmolGetAppletSize() for the formats accepted as size [same used by jmolApplet()]
+ // Special case: an empty value for width or height is accepted, meaning no change in that dimension.
+ _jmol.alerted = true;
+ var applet = _jmolGetApplet(targetSuffix);
+ if(!applet)return;
+ var sz = _jmolGetAppletSize(size, "px");
+ sz[0] && (applet.style.width = sz[0]);
+ sz[1] && (applet.style.height = sz[1]);
+}
+
+function _jmolGetAppletSize(size, units) {
+ /* Accepts single number or 2-value array, each one can be one of:
+ percent (text string ending %), decimal 0 to 1 (percent/100), number, or text string (interpreted as nr.)
+ [width, height] array of strings is returned, with units added if specified.
+ Percent is relative to container div or element (which should have explicitly set size).
+ */
+ var width, height;
+ if ( (typeof size) == "object" && size != null ) {
+ width = size[0]; height = size[1];
+ } else {
+ width = height = size;
+ }
+ return [_jmolFixDim(width, units), _jmolFixDim(height, units)];
+}
+
+function _jmolFixDim(x, units) {
+ var sx = "" + x;
+ return (sx.length == 0 ? (units ? "" : _jmol.allowedJmolSize[2])
+ : sx.indexOf("%") == sx.length-1 ? sx
+ : (x = parseFloat(x)) <= 1 && x > 0 ? x * 100 + "%"
+ : (isNaN(x = Math.floor(x)) ? _jmol.allowedJmolSize[2]
+ : x < _jmol.allowedJmolSize[0] ? _jmol.allowedJmolSize[0]
+ : x > _jmol.allowedJmolSize[1] ? _jmol.allowedJmolSize[1]
+ : x) + (units ? units : ""));
+}
+
+
+
+
->FER_CAPAA Ferredoxin\r
------------------------------------------------------------ASYKVKLITPDGP\r
-IEFDCPDDVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDV\r
-TIETHKEAELVG-\r
->FER_CAPAN Ferredoxin, chloroplast precursor\r
-MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMASYKVKLITPDGP\r
-IEFDCPDNVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDV\r
-TIETHKEAELVG-\r
->FER1_SOLLC Ferredoxin-1, chloroplast precursor\r
-MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPEGP\r
-IEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGSVDQSDGNFLDEDQEAAGFVLTCVAYPKGDV\r
-TIETHKEEELTA-\r
->Q93XJ9_SOLTU Ferredoxin I precursor\r
-MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPDGP\r
-IEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGTVDQSDGKFLDDDQEAAGFVLTCVAYPKCDV\r
-TIETHKEEELTA-\r
->FER1_PEA Ferredoxin-1, chloroplast precursor\r
-MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMASYKVKLVTPDGT\r
-QEFECPSDVYILDHAEEVGIDLPYSCRAGSCSSCAGKVVGGEVDQSDGSFLDDEQIEAGFVLTCVAYPTSDV\r
-VIETHKEEDLTA-\r
->Q7XA98_TRIPR Ferredoxin I\r
-MATT---PALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGFGLKSVSTKRGDLAVAMATYKVKLITPEGP\r
-QEFDCPDDVYILDHAEEVGIELPYSCRAGSCSSCAGKVVNGNVNQEDGSFLDDEQIEGGWVLTCVAFPTSDV\r
-TIETHKEEELTA-\r
->FER1_MESCR Ferredoxin-1, chloroplast precursor\r
-MAAT--TAALSGATMSTAFAPK--TPPMTAALPTNVGR--ALFGLKS-SASR-GRVTAMAAYKVTLVTPEGK\r
-QELECPDDVYILDAAEEAGIDLPYSCRAGSCSSCAGKVTSGSVNQDDGSFLDDDQIKEGWVLTCVAYPTGDV\r
-TIETHKEEELTA-\r
->FER1_SPIOL Ferredoxin-1, chloroplast precursor\r
-MAAT--TTTMMG--MATTFVPKPQAPPMMAALPSNTGR--SLFGLKT-GSR--GGRMTMAAYKVTLVTPTGN\r
-VEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDDDQIDEGWVLTCAAYPVSDV\r
-TIETHKEEELTA-\r
->FER3_RAPSA Ferredoxin, leaf L-A\r
------------------------------------------------------------ATYKVKFITPEGE\r
-QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDV\r
-TIETHREEDMV--\r
->FER1_ARATH Ferredoxin-1, chloroplast precursor\r
-MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGE\r
-LEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDV\r
-TIETHKEEDIV--\r
->FER_BRANA Ferredoxin\r
------------------------------------------------------------ATYKVKFITPEGE\r
-QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDV\r
-TIETHKEEELV--\r
->FER2_ARATH Ferredoxin-2, chloroplast precursor\r
-MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE\r
-QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV\r
-VIETHKEEAIM--\r
->Q93Z60_ARATH At1g10960/T19D16_12\r
-MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE\r
-QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD-------------------\r
--------------\r
->FER1_MAIZE Ferredoxin-1, chloroplast precursor\r
-MATVLGSPRAPAFFFSSSSLRAAPAPTAV--ALPAAKV--GIMGRSA-SSRR--RLRAQATYNVKLITPEGE\r
-VELQVPDDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDV\r
-VIETHKEEELTGA\r
->O80429_MAIZE Ferredoxin\r
-MAAT---------ALSMSILR---APPPCFSSPLRLRV--AVAKPLA-APMRRQLLRAQATYNVKLITPEGE\r
-VELQVPDDVYILDFAEEEGIDLPFSCRAGSCSSCAGKVVSGSVDQSDQSFLNDNQVADGWVLTCAAYPTSDV\r
-VIETHKEDDLL--\r
+>FER_CAPAA Ferredoxin
+-----------------------------------------------------------ASYKVKLITPDGP
+IEFDCPDDVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDV
+TIETHKEAELVG-
+>FER_CAPAN Ferredoxin, chloroplast precursor
+MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMASYKVKLITPDGP
+IEFDCPDNVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDV
+TIETHKEAELVG-
+>FER1_SOLLC Ferredoxin-1, chloroplast precursor
+MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPEGP
+IEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGSVDQSDGNFLDEDQEAAGFVLTCVAYPKGDV
+TIETHKEEELTA-
+>Q93XJ9_SOLTU Ferredoxin I precursor
+MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPDGP
+IEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGTVDQSDGKFLDDDQEAAGFVLTCVAYPKCDV
+TIETHKEEELTA-
+>FER1_PEA Ferredoxin-1, chloroplast precursor
+MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMASYKVKLVTPDGT
+QEFECPSDVYILDHAEEVGIDLPYSCRAGSCSSCAGKVVGGEVDQSDGSFLDDEQIEAGFVLTCVAYPTSDV
+VIETHKEEDLTA-
+>Q7XA98_TRIPR Ferredoxin I
+MATT---PALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGFGLKSVSTKRGDLAVAMATYKVKLITPEGP
+QEFDCPDDVYILDHAEEVGIELPYSCRAGSCSSCAGKVVNGNVNQEDGSFLDDEQIEGGWVLTCVAFPTSDV
+TIETHKEEELTA-
+>FER1_MESCR Ferredoxin-1, chloroplast precursor
+MAAT--TAALSGATMSTAFAPK--TPPMTAALPTNVGR--ALFGLKS-SASR-GRVTAMAAYKVTLVTPEGK
+QELECPDDVYILDAAEEAGIDLPYSCRAGSCSSCAGKVTSGSVNQDDGSFLDDDQIKEGWVLTCVAYPTGDV
+TIETHKEEELTA-
+>FER1_SPIOL Ferredoxin-1, chloroplast precursor
+MAAT--TTTMMG--MATTFVPKPQAPPMMAALPSNTGR--SLFGLKT-GSR--GGRMTMAAYKVTLVTPTGN
+VEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDDDQIDEGWVLTCAAYPVSDV
+TIETHKEEELTA-
+>FER3_RAPSA Ferredoxin, leaf L-A
+-----------------------------------------------------------ATYKVKFITPEGE
+QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDV
+TIETHREEDMV--
+>FER1_ARATH Ferredoxin-1, chloroplast precursor
+MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGE
+LEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDV
+TIETHKEEDIV--
+>FER_BRANA Ferredoxin
+-----------------------------------------------------------ATYKVKFITPEGE
+QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDV
+TIETHKEEELV--
+>FER2_ARATH Ferredoxin-2, chloroplast precursor
+MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
+QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV
+VIETHKEEAIM--
+>Q93Z60_ARATH At1g10960/T19D16_12
+MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
+QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD-------------------
+-------------
+>FER1_MAIZE Ferredoxin-1, chloroplast precursor
+MATVLGSPRAPAFFFSSSSLRAAPAPTAV--ALPAAKV--GIMGRSA-SSRR--RLRAQATYNVKLITPEGE
+VELQVPDDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDV
+VIETHKEEELTGA
+>O80429_MAIZE Ferredoxin
+MAAT---------ALSMSILR---APPPCFSSPLRLRV--AVAKPLA-APMRRQLLRAQATYNVKLITPEGE
+VELQVPDDVYILDFAEEEGIDLPFSCRAGSCSSCAGKVVSGSVDQSDQSFLNDNQVADGWVLTCAAYPTSDV
+VIETHKEDDLL--
-HEADER OXIDOREDUCTASE/ELECTRON TRANSPORT 08-MAY-00 1GAQ \r
-ATOM 2 CA GLU A 19 20.491 30.713 36.290 1.00 74.29 C \r
-ATOM 11 CA SER A 20 24.056 29.774 37.264 1.00 72.09 C \r
-ATOM 17 CA LYS A 21 27.517 31.289 37.563 1.00 70.09 C \r
-ATOM 26 CA LYS A 22 28.794 27.865 36.481 1.00 68.64 C \r
-ATOM 35 CA GLN A 23 29.484 26.806 32.884 1.00 70.46 C \r
-ATOM 44 CA GLU A 24 26.420 25.175 31.360 1.00 72.08 C \r
-ATOM 53 CA GLU A 25 26.736 26.049 27.683 1.00 70.43 C \r
-ATOM 62 CA GLY A 26 28.299 22.912 26.233 1.00 63.14 C \r
-ATOM 66 CA VAL A 27 26.863 20.704 28.982 1.00 54.50 C \r
-ATOM 73 CA VAL A 28 25.030 17.390 28.655 1.00 48.32 C \r
-ATOM 80 CA THR A 29 23.728 14.677 30.991 1.00 44.86 C \r
-ATOM 87 CA ASN A 30 22.327 11.164 30.703 1.00 45.42 C \r
-ATOM 95 CA LEU A 31 23.332 10.459 27.102 1.00 45.42 C \r
-ATOM 103 CA TYR A 32 23.549 6.898 28.380 1.00 45.88 C \r
-ATOM 115 CA LYS A 33 21.656 5.321 31.262 1.00 47.27 C \r
-ATOM 124 CA PRO A 34 21.991 2.046 33.248 1.00 48.99 C \r
-ATOM 131 CA LYS A 35 19.339 0.560 30.970 1.00 52.75 C \r
-ATOM 140 CA GLU A 36 21.580 0.855 27.886 1.00 53.33 C \r
-ATOM 149 CA PRO A 37 25.154 2.015 28.678 1.00 47.54 C \r
-ATOM 156 CA TYR A 38 27.929 2.872 26.249 1.00 41.98 C \r
-ATOM 168 CA VAL A 39 30.355 -0.017 25.909 1.00 41.48 C \r
-ATOM 175 CA GLY A 40 33.823 1.485 25.966 1.00 37.59 C \r
-ATOM 179 CA ARG A 41 37.165 -0.277 26.122 1.00 39.77 C \r
-ATOM 190 CA CYS A 42 40.148 -0.029 28.442 1.00 36.51 C \r
-ATOM 196 CA LEU A 43 43.095 1.441 26.554 1.00 36.13 C \r
-ATOM 204 CA LEU A 44 45.231 2.023 29.649 1.00 33.55 C \r
-ATOM 212 CA ASN A 45 45.140 1.026 33.307 1.00 27.79 C \r
-ATOM 220 CA THR A 46 48.056 1.800 35.617 1.00 28.75 C \r
-ATOM 227 CA LYS A 47 48.542 1.776 39.388 1.00 30.31 C \r
-ATOM 236 CA ILE A 48 49.564 5.317 40.376 1.00 31.32 C \r
-ATOM 244 CA THR A 49 50.339 4.682 44.059 1.00 37.62 C \r
-ATOM 251 CA GLY A 50 53.585 3.317 45.460 1.00 44.49 C \r
-ATOM 255 CA ASP A 51 53.706 -0.448 46.087 1.00 52.89 C \r
-ATOM 263 CA ASP A 52 53.910 0.545 49.751 1.00 55.23 C \r
-ATOM 271 CA ALA A 53 50.816 2.767 50.056 1.00 53.34 C \r
-ATOM 276 CA PRO A 54 47.904 1.940 52.405 1.00 50.60 C \r
-ATOM 283 CA GLY A 55 45.420 1.579 49.561 1.00 50.35 C \r
-ATOM 287 CA GLU A 56 46.098 1.286 45.836 1.00 42.53 C \r
-ATOM 296 CA THR A 57 44.534 3.816 43.480 1.00 41.14 C \r
-ATOM 303 CA TRP A 58 44.540 3.423 39.708 1.00 35.60 C \r
-ATOM 317 CA HIS A 59 44.468 5.853 36.796 1.00 31.89 C \r
-ATOM 327 CA MET A 60 42.658 4.227 33.866 1.00 31.65 C \r
-ATOM 335 CA VAL A 61 41.716 5.345 30.350 1.00 30.43 C \r
-ATOM 342 CA PHE A 62 38.669 4.172 28.360 1.00 34.36 C \r
-ATOM 353 CA SER A 63 37.657 4.908 24.772 1.00 34.69 C \r
-ATOM 359 CA THR A 64 34.448 6.828 23.951 1.00 36.96 C \r
-ATOM 366 CA GLU A 65 34.691 7.644 20.254 1.00 40.08 C \r
-ATOM 375 CA GLY A 66 33.742 11.183 21.285 1.00 40.22 C \r
-ATOM 379 CA LYS A 67 30.272 9.763 22.003 1.00 41.93 C \r
-ATOM 388 CA ILE A 68 30.279 11.116 25.577 1.00 41.52 C \r
-ATOM 396 CA PRO A 69 30.791 14.926 25.537 1.00 42.35 C \r
-ATOM 403 CA TYR A 70 31.228 15.232 29.299 1.00 39.84 C \r
-ATOM 415 CA ARG A 71 32.639 18.451 30.768 1.00 44.14 C \r
-ATOM 426 CA GLU A 72 35.122 19.278 33.515 1.00 43.82 C \r
-ATOM 435 CA GLY A 73 33.472 18.458 36.835 1.00 41.97 C \r
-ATOM 439 CA GLN A 74 30.929 15.874 35.657 1.00 37.19 C \r
-ATOM 448 CA SER A 75 31.285 12.124 36.138 1.00 38.28 C \r
-ATOM 454 CA ILE A 76 30.458 8.792 34.539 1.00 36.84 C \r
-ATOM 462 CA GLY A 77 28.983 5.620 35.918 1.00 35.39 C \r
-ATOM 466 CA VAL A 78 30.311 2.108 35.530 1.00 32.05 C \r
-ATOM 473 CA ILE A 79 28.458 -1.201 35.591 1.00 32.67 C \r
-ATOM 481 CA ALA A 80 30.745 -4.018 36.644 1.00 35.36 C \r
-ATOM 486 CA ASP A 81 30.359 -7.373 34.872 1.00 38.72 C \r
-ATOM 494 CA GLY A 82 28.308 -10.332 36.110 1.00 45.79 C \r
-ATOM 498 CA VAL A 83 25.820 -10.242 39.001 1.00 52.24 C \r
-ATOM 505 CA ASP A 84 25.838 -10.250 42.834 1.00 60.54 C \r
-ATOM 513 CA LYS A 85 25.014 -13.158 45.196 1.00 66.72 C \r
-ATOM 522 CA ASN A 86 21.414 -13.062 43.904 1.00 67.37 C \r
-ATOM 530 CA GLY A 87 21.724 -13.423 40.136 1.00 64.74 C \r
-ATOM 534 CA LYS A 88 20.971 -9.733 39.570 1.00 61.12 C \r
-ATOM 543 CA PRO A 89 23.054 -7.201 37.561 1.00 54.68 C \r
-ATOM 550 CA HIS A 90 25.224 -4.957 39.755 1.00 44.44 C \r
-ATOM 560 CA LYS A 91 23.940 -1.433 40.260 1.00 40.48 C \r
-ATOM 569 CA VAL A 92 25.803 1.546 38.843 1.00 38.45 C \r
-ATOM 576 CA ARG A 93 28.709 2.986 40.828 1.00 38.93 C \r
-ATOM 587 CA LEU A 94 29.778 6.584 40.096 1.00 34.37 C \r
-ATOM 595 CA TYR A 95 33.309 7.878 39.513 1.00 30.27 C \r
-ATOM 607 CA SER A 96 34.425 11.475 39.057 1.00 29.44 C \r
-ATOM 613 CA ILE A 97 36.029 12.090 35.662 1.00 27.61 C \r
-ATOM 621 CA ALA A 98 39.769 12.693 36.069 1.00 31.12 C \r
-ATOM 626 CA SER A 99 40.393 13.712 32.475 1.00 32.42 C \r
-ATOM 632 CA SER A 100 39.566 17.142 31.059 1.00 36.14 C \r
-ATOM 638 CA ALA A 101 37.097 17.367 28.154 1.00 41.07 C \r
-ATOM 643 CA ILE A 102 39.764 16.549 25.527 1.00 47.65 C \r
-ATOM 651 CA GLY A 103 41.172 13.692 27.599 1.00 46.77 C \r
-ATOM 655 CA ASP A 104 44.730 12.612 28.289 1.00 43.82 C \r
-ATOM 663 CA PHE A 105 45.115 12.065 24.522 1.00 41.52 C \r
-ATOM 674 CA GLY A 106 43.862 15.455 23.328 1.00 41.66 C \r
-ATOM 678 CA ASP A 107 41.355 13.883 20.926 1.00 40.90 C \r
-ATOM 686 CA SER A 108 38.132 14.250 22.954 1.00 42.95 C \r
-ATOM 692 CA LYS A 109 37.967 10.535 22.224 1.00 44.74 C \r
-ATOM 701 CA THR A 110 38.731 9.184 25.704 1.00 41.09 C \r
-ATOM 708 CA VAL A 111 37.728 9.519 29.374 1.00 39.03 C \r
-ATOM 715 CA SER A 112 39.912 8.705 32.399 1.00 37.17 C \r
-ATOM 721 CA LEU A 113 39.098 7.476 35.935 1.00 32.10 C \r
-ATOM 729 CA CYS A 114 40.964 7.578 39.261 1.00 30.65 C \r
-ATOM 735 CA VAL A 115 39.724 4.459 41.060 1.00 33.45 C \r
-ATOM 742 CA LYS A 116 40.668 3.524 44.628 1.00 34.75 C \r
-ATOM 751 CA ARG A 117 40.376 -0.250 45.123 1.00 32.85 C \r
-ATOM 762 CA LEU A 118 38.137 -1.094 48.077 1.00 30.50 C \r
-ATOM 770 CA ILE A 119 39.376 -3.752 50.459 1.00 34.34 C \r
-ATOM 778 CA TYR A 120 38.699 -4.266 54.125 1.00 31.39 C \r
-ATOM 790 CA THR A 121 38.264 -7.086 56.567 1.00 28.83 C \r
-ATOM 797 CA ASN A 122 34.792 -7.477 58.109 1.00 26.51 C \r
-ATOM 805 CA ASP A 123 33.626 -8.382 61.634 1.00 31.58 C \r
-ATOM 813 CA ALA A 124 34.191 -12.077 60.901 1.00 27.84 C \r
-ATOM 818 CA GLY A 125 37.759 -11.844 59.728 1.00 32.39 C \r
-ATOM 822 CA GLU A 126 36.809 -12.146 56.073 1.00 35.82 C \r
-ATOM 831 CA ILE A 127 38.655 -9.932 53.598 1.00 38.42 C \r
-ATOM 839 CA VAL A 128 36.025 -8.261 51.421 1.00 33.73 C \r
-ATOM 846 CA LYS A 129 36.482 -6.484 48.090 1.00 31.87 C \r
-ATOM 855 CA GLY A 130 34.363 -3.680 46.686 1.00 26.91 C \r
-ATOM 859 CA VAL A 131 32.680 -5.051 43.569 1.00 27.89 C \r
-ATOM 866 CA CYS A 132 33.074 -2.246 41.018 1.00 28.46 C \r
-ATOM 872 CA SER A 133 36.266 -0.553 42.213 1.00 31.33 C \r
-ATOM 878 CA ASN A 134 37.861 -3.983 41.984 1.00 30.29 C \r
-ATOM 886 CA PHE A 135 36.318 -4.795 38.623 1.00 31.48 C \r
-ATOM 897 CA LEU A 136 37.926 -1.553 37.520 1.00 27.81 C \r
-ATOM 905 CA CYS A 137 41.417 -1.976 38.955 1.00 25.91 C \r
-ATOM 911 CA ASP A 138 41.605 -5.419 37.338 1.00 30.22 C \r
-ATOM 919 CA LEU A 139 40.462 -4.306 33.874 1.00 32.69 C \r
-ATOM 927 CA GLN A 140 42.851 -5.511 31.186 1.00 36.80 C \r
-ATOM 936 CA PRO A 141 43.380 -3.220 28.170 1.00 36.16 C \r
-ATOM 943 CA GLY A 142 40.864 -4.420 25.586 1.00 31.10 C \r
-ATOM 947 CA ASP A 143 38.129 -5.298 28.055 1.00 30.62 C \r
-ATOM 955 CA ASN A 144 34.690 -3.847 27.645 1.00 33.52 C \r
-ATOM 963 CA VAL A 145 33.430 -1.522 30.361 1.00 37.08 C \r
-ATOM 970 CA GLN A 146 29.817 -0.374 30.523 1.00 37.65 C \r
-ATOM 979 CA ILE A 147 29.547 3.413 31.045 1.00 30.95 C \r
-ATOM 987 CA THR A 148 26.637 5.791 31.832 1.00 29.95 C \r
-ATOM 994 CA GLY A 149 26.297 9.581 31.843 1.00 32.81 C \r
-ATOM 998 CA PRO A 150 27.785 12.148 31.800 1.00 34.98 C \r
-ATOM 1005 CA VAL A 151 26.376 12.668 35.275 1.00 36.53 C \r
-ATOM 1012 CA GLY A 152 26.196 15.756 37.474 1.00 43.09 C \r
-ATOM 1016 CA LYS A 153 26.048 19.528 37.068 1.00 48.37 C \r
-ATOM 1025 CA GLU A 154 26.921 20.540 40.633 1.00 49.70 C \r
-ATOM 1034 CA MET A 155 30.710 20.266 40.235 1.00 47.30 C \r
-ATOM 1042 CA LEU A 156 30.882 22.020 36.869 1.00 50.36 C \r
-ATOM 1050 CA MET A 157 33.362 24.883 36.404 1.00 55.29 C \r
-ATOM 1058 CA PRO A 158 32.521 28.612 36.605 1.00 54.88 C \r
-ATOM 1065 CA LYS A 159 32.291 30.776 33.464 1.00 54.92 C \r
-ATOM 1074 CA ASP A 160 34.497 33.503 34.939 1.00 57.22 C \r
-ATOM 1082 CA PRO A 161 38.055 32.687 33.759 1.00 58.62 C \r
-ATOM 1089 CA ASN A 162 39.524 35.240 36.163 1.00 60.44 C \r
-ATOM 1097 CA ALA A 163 37.814 33.910 39.279 1.00 55.80 C \r
-ATOM 1102 CA THR A 164 39.596 32.487 42.316 1.00 51.04 C \r
-ATOM 1109 CA ILE A 165 38.966 28.771 42.756 1.00 50.26 C \r
-ATOM 1117 CA ILE A 166 39.774 26.773 45.885 1.00 47.54 C \r
-ATOM 1125 CA MET A 167 39.883 23.014 45.324 1.00 46.38 C \r
-ATOM 1133 CA LEU A 168 39.700 20.963 48.522 1.00 42.18 C \r
-ATOM 1141 CA ALA A 169 40.377 17.316 47.770 1.00 36.41 C \r
-ATOM 1146 CA THR A 170 41.005 14.086 49.622 1.00 32.98 C \r
-ATOM 1153 CA GLY A 171 42.027 10.802 48.014 1.00 31.36 C \r
-ATOM 1157 CA THR A 172 40.386 10.037 44.680 1.00 30.48 C \r
-ATOM 1164 CA GLY A 173 38.640 13.335 45.359 1.00 33.99 C \r
-ATOM 1168 CA ILE A 174 41.418 15.036 43.394 1.00 35.66 C \r
-ATOM 1176 CA ALA A 175 39.758 13.585 40.300 1.00 36.00 C \r
-ATOM 1181 CA PRO A 176 37.445 16.385 39.155 1.00 39.41 C \r
-ATOM 1188 CA PHE A 177 40.109 18.971 39.976 1.00 43.21 C \r
-ATOM 1199 CA ARG A 178 42.726 17.119 37.955 1.00 41.09 C \r
-ATOM 1210 CA SER A 179 40.235 17.536 35.124 1.00 39.92 C \r
-ATOM 1216 CA PHE A 180 39.808 21.204 36.009 1.00 39.23 C \r
-ATOM 1227 CA LEU A 181 43.528 21.949 35.995 1.00 39.50 C \r
-ATOM 1235 CA TRP A 182 44.305 20.081 32.770 1.00 41.47 C \r
-ATOM 1249 CA LYS A 183 42.141 22.654 30.972 1.00 48.08 C \r
-ATOM 1258 CA MET A 184 43.477 25.547 33.062 1.00 52.79 C \r
-ATOM 1266 CA PHE A 185 47.102 25.043 32.014 1.00 57.35 C \r
-ATOM 1277 CA PHE A 186 48.075 21.921 30.051 1.00 55.98 C \r
-ATOM 1288 CA GLU A 187 45.758 23.173 27.297 1.00 54.44 C \r
-ATOM 1297 CA LYS A 188 44.908 26.236 25.196 1.00 51.29 C \r
-ATOM 1306 CA HIS A 189 41.395 27.080 24.003 1.00 51.35 C \r
-ATOM 1316 CA ASP A 190 40.108 29.972 21.873 1.00 54.30 C \r
-ATOM 1324 CA ASP A 191 37.199 30.481 24.249 1.00 53.95 C \r
-ATOM 1332 CA TYR A 192 38.816 29.937 27.634 1.00 50.68 C \r
-ATOM 1344 CA LYS A 193 41.916 31.388 29.230 1.00 51.00 C \r
-ATOM 1353 CA PHE A 194 42.322 30.967 32.956 1.00 52.09 C \r
-ATOM 1364 CA ASN A 195 43.672 34.234 34.312 1.00 56.46 C \r
-ATOM 1372 CA GLY A 196 42.616 34.078 37.969 1.00 57.17 C \r
-ATOM 1376 CA LEU A 197 43.874 31.920 40.843 1.00 57.92 C \r
-ATOM 1384 CA GLY A 198 43.549 28.151 41.086 1.00 56.67 C \r
-ATOM 1388 CA TRP A 199 44.258 26.886 44.592 1.00 51.55 C \r
-ATOM 1402 CA LEU A 200 44.411 23.170 45.379 1.00 49.17 C \r
-ATOM 1410 CA PHE A 201 44.558 21.335 48.709 1.00 48.60 C \r
-ATOM 1421 CA LEU A 202 45.122 17.570 48.598 1.00 45.34 C \r
-ATOM 1429 CA GLY A 203 44.885 15.480 51.742 1.00 48.55 C \r
-ATOM 1433 CA VAL A 204 46.225 11.936 51.755 1.00 50.23 C \r
-ATOM 1440 CA PRO A 205 47.942 9.740 54.365 1.00 51.51 C \r
-ATOM 1447 CA THR A 206 51.284 9.148 52.648 1.00 50.21 C \r
-ATOM 1454 CA SER A 207 53.551 10.483 49.894 1.00 49.38 C \r
-ATOM 1460 CA SER A 208 53.267 7.061 48.259 1.00 43.49 C \r
-ATOM 1466 CA SER A 209 49.588 8.049 48.093 1.00 42.57 C \r
-ATOM 1472 CA LEU A 210 49.990 11.424 46.364 1.00 42.65 C \r
-ATOM 1480 CA LEU A 211 48.121 11.446 43.035 1.00 39.33 C \r
-ATOM 1488 CA TYR A 212 49.516 13.214 39.935 1.00 40.89 C \r
-ATOM 1500 CA LYS A 213 52.128 15.234 41.873 1.00 45.88 C \r
-ATOM 1509 CA GLU A 214 54.518 15.406 38.899 1.00 53.22 C \r
-ATOM 1518 CA GLU A 215 51.680 16.911 36.889 1.00 55.16 C \r
-ATOM 1527 CA PHE A 216 50.757 19.475 39.514 1.00 60.55 C \r
-ATOM 1538 CA GLY A 217 54.488 20.153 39.524 1.00 66.64 C \r
-ATOM 1542 CA LYS A 218 54.575 21.110 35.850 1.00 68.86 C \r
-ATOM 1551 CA MET A 219 51.398 23.159 36.265 1.00 66.97 C \r
-ATOM 1559 CA LYS A 220 53.138 25.090 39.061 1.00 65.97 C \r
-ATOM 1568 CA GLU A 221 55.654 26.250 36.459 1.00 70.02 C \r
-ATOM 1577 CA ARG A 222 53.584 26.507 33.294 1.00 73.48 C \r
-ATOM 1588 CA ALA A 223 52.005 29.449 35.175 1.00 76.21 C \r
-ATOM 1593 CA PRO A 224 53.272 29.877 38.804 1.00 79.25 C \r
-ATOM 1600 CA GLU A 225 51.296 33.124 39.020 1.00 81.84 C \r
-ATOM 1609 CA ASN A 226 47.873 31.528 38.622 1.00 78.84 C \r
-ATOM 1617 CA PHE A 227 48.418 28.176 40.350 1.00 75.28 C \r
-ATOM 1628 CA ARG A 228 49.090 27.305 43.996 1.00 72.05 C \r
-ATOM 1639 CA VAL A 229 49.165 23.724 45.323 1.00 68.82 C \r
-ATOM 1646 CA ASP A 230 49.258 22.581 48.958 1.00 66.54 C \r
-ATOM 1654 CA TYR A 231 49.605 18.943 49.968 1.00 60.31 C \r
-ATOM 1666 CA ALA A 232 48.551 17.560 53.332 1.00 57.39 C \r
-ATOM 1671 CA VAL A 233 50.260 14.228 53.945 1.00 57.14 C \r
-ATOM 1678 CA SER A 234 48.465 13.579 57.244 1.00 60.81 C \r
-ATOM 1684 CA ARG A 235 50.959 11.010 58.514 1.00 60.74 C \r
-ATOM 1695 CA GLU A 236 54.268 12.594 57.481 1.00 59.17 C \r
-ATOM 1704 CA GLN A 237 53.494 16.197 58.450 1.00 59.62 C \r
-ATOM 1713 CA THR A 238 52.590 18.236 61.521 1.00 63.18 C \r
-ATOM 1720 CA ASN A 239 52.019 21.937 62.188 1.00 66.71 C \r
-ATOM 1728 CA ALA A 240 52.096 23.767 65.537 1.00 70.06 C \r
-ATOM 1733 CA ALA A 241 51.302 21.400 68.410 1.00 72.44 C \r
-ATOM 1738 CA GLY A 242 52.383 18.324 66.438 1.00 72.38 C \r
-ATOM 1742 CA GLU A 243 48.826 18.169 65.110 1.00 69.71 C \r
-ATOM 1751 CA ARG A 244 48.674 15.776 62.148 1.00 67.21 C \r
-ATOM 1762 CA MET A 245 48.712 17.796 58.933 1.00 64.20 C \r
-ATOM 1770 CA TYR A 246 45.246 17.082 57.556 1.00 60.65 C \r
-ATOM 1782 CA ILE A 247 43.617 18.437 54.409 1.00 62.98 C \r
-ATOM 1790 CA GLN A 248 42.035 21.001 56.761 1.00 64.64 C \r
-ATOM 1799 CA THR A 249 45.057 21.461 59.009 1.00 63.37 C \r
-ATOM 1806 CA ARG A 250 46.891 22.664 55.903 1.00 62.47 C \r
-ATOM 1817 CA MET A 251 44.123 25.201 55.251 1.00 63.35 C \r
-ATOM 1825 CA ALA A 252 44.571 26.305 58.854 1.00 65.73 C \r
-ATOM 1830 CA GLU A 253 47.973 27.809 58.076 1.00 65.97 C \r
-ATOM 1839 CA TYR A 254 46.267 30.063 55.517 1.00 65.83 C \r
-ATOM 1851 CA LYS A 255 42.991 30.559 57.379 1.00 70.30 C \r
-ATOM 1860 CA GLU A 256 43.578 34.326 57.320 1.00 73.73 C \r
-ATOM 1869 CA GLU A 257 44.189 34.738 53.593 1.00 71.52 C \r
-ATOM 1878 CA LEU A 258 41.459 32.202 52.893 1.00 73.38 C \r
-ATOM 1886 CA TRP A 259 38.790 34.074 54.853 1.00 76.72 C \r
-ATOM 1900 CA GLU A 260 39.721 37.275 53.006 1.00 78.61 C \r
-ATOM 1909 CA LEU A 261 38.580 35.553 49.815 1.00 75.71 C \r
-ATOM 1917 CA LEU A 262 35.391 33.881 51.047 1.00 73.74 C \r
-ATOM 1925 CA LYS A 263 33.562 37.165 50.535 1.00 73.64 C \r
-ATOM 1934 CA LYS A 264 34.299 38.143 46.954 1.00 72.48 C \r
-ATOM 1943 CA ASP A 265 31.954 37.554 43.993 1.00 69.65 C \r
-ATOM 1951 CA ASN A 266 34.660 35.649 42.106 1.00 65.06 C \r
-ATOM 1959 CA THR A 267 35.835 33.117 44.683 1.00 58.24 C \r
-ATOM 1966 CA TYR A 268 34.459 29.646 43.909 1.00 51.04 C \r
-ATOM 1978 CA VAL A 269 35.192 26.827 46.382 1.00 44.95 C \r
-ATOM 1985 CA TYR A 270 35.012 23.150 45.368 1.00 44.96 C \r
-ATOM 1997 CA MET A 271 35.162 20.122 47.656 1.00 41.72 C \r
-ATOM 2005 CA CYS A 272 35.314 16.468 46.632 1.00 37.19 C \r
-ATOM 2011 CA GLY A 273 36.343 13.080 47.951 1.00 37.65 C \r
-ATOM 2015 CA LEU A 274 36.040 10.886 51.020 1.00 39.39 C \r
-ATOM 2023 CA LYS A 275 33.076 12.283 52.955 1.00 44.86 C \r
-ATOM 2032 CA GLY A 276 34.322 13.183 56.400 1.00 49.16 C \r
-ATOM 2036 CA MET A 277 36.932 15.608 55.168 1.00 53.30 C \r
-ATOM 2044 CA GLU A 278 33.917 17.921 55.165 1.00 56.74 C \r
-ATOM 2053 CA LYS A 279 33.531 18.089 58.947 1.00 59.30 C \r
-ATOM 2062 CA GLY A 280 36.982 19.413 59.776 1.00 58.94 C \r
-ATOM 2066 CA ILE A 281 36.705 22.048 57.063 1.00 61.43 C \r
-ATOM 2074 CA ASP A 282 33.453 23.402 58.515 1.00 67.06 C \r
-ATOM 2082 CA ASP A 283 35.050 23.189 61.972 1.00 74.12 C \r
-ATOM 2090 CA ILE A 284 37.991 25.422 61.040 1.00 78.49 C \r
-ATOM 2098 CA MET A 285 35.456 27.566 59.201 1.00 82.25 C \r
-ATOM 2106 CA VAL A 286 32.941 27.959 62.027 1.00 83.44 C \r
-ATOM 2113 CA SER A 287 35.610 29.113 64.469 1.00 83.43 C \r
-ATOM 2119 CA LEU A 288 36.927 31.601 61.887 1.00 85.53 C \r
-ATOM 2127 CA ALA A 289 33.506 33.025 60.970 1.00 86.85 C \r
-ATOM 2132 CA GLU A 290 31.841 32.696 64.387 1.00 89.26 C \r
-ATOM 2141 CA LYS A 291 34.438 35.312 65.347 1.00 88.73 C \r
-ATOM 2150 CA ASP A 292 33.635 37.891 62.652 1.00 88.03 C \r
-ATOM 2158 CA GLY A 293 30.219 37.450 61.081 1.00 87.88 C \r
-ATOM 2162 CA ILE A 294 27.319 35.051 61.511 1.00 84.61 C \r
-ATOM 2170 CA ASP A 295 27.665 31.329 62.188 1.00 82.45 C \r
-ATOM 2178 CA TRP A 296 29.539 29.627 59.355 1.00 80.12 C \r
-ATOM 2192 CA PHE A 297 26.527 27.452 58.512 1.00 78.99 C \r
-ATOM 2203 CA ASP A 298 24.167 30.241 57.486 1.00 76.37 C \r
-ATOM 2211 CA TYR A 299 27.074 31.748 55.561 1.00 74.07 C \r
-ATOM 2223 CA LYS A 300 27.679 28.620 53.473 1.00 74.31 C \r
-ATOM 2232 CA LYS A 301 24.059 29.146 52.464 1.00 75.97 C \r
-ATOM 2241 CA GLN A 302 24.921 32.563 51.018 1.00 75.38 C \r
-ATOM 2250 CA LEU A 303 27.896 31.099 49.155 1.00 72.10 C \r
-ATOM 2258 CA LYS A 304 25.917 28.207 47.690 1.00 72.08 C \r
-ATOM 2267 CA ARG A 305 23.595 31.021 46.594 1.00 74.82 C \r
-ATOM 2278 CA GLY A 306 26.071 32.136 43.958 1.00 71.84 C \r
-ATOM 2282 CA ASP A 307 27.505 28.682 43.220 1.00 67.23 C \r
-ATOM 2290 CA GLN A 308 30.620 29.291 45.346 1.00 60.18 C \r
-ATOM 2299 CA TRP A 309 30.585 26.177 47.537 1.00 52.25 C \r
-ATOM 2313 CA ASN A 310 29.894 22.997 45.597 1.00 45.03 C \r
-ATOM 2321 CA VAL A 311 30.327 19.716 47.403 1.00 39.13 C \r
-ATOM 2328 CA GLU A 312 30.507 16.190 46.110 1.00 35.17 C \r
-ATOM 2337 CA VAL A 313 31.761 13.957 48.861 1.00 30.12 C \r
-ATOM 2344 CA TYR A 314 31.112 10.230 49.021 1.00 28.23 C \r
-ATOM 2358 CA ALA B 1 2.311 24.702 44.475 1.00 74.17 C \r
-ATOM 2363 CA THR B 2 3.590 24.207 48.055 1.00 74.76 C \r
-ATOM 2370 CA TYR B 3 3.069 20.876 49.837 1.00 73.52 C \r
-ATOM 2382 CA ASN B 4 3.748 19.874 53.435 1.00 75.75 C \r
-ATOM 2390 CA VAL B 5 6.618 17.399 53.868 1.00 75.95 C \r
-ATOM 2397 CA LYS B 6 7.769 15.523 56.983 1.00 77.70 C \r
-ATOM 2406 CA LEU B 7 11.351 14.325 57.458 1.00 78.91 C \r
-ATOM 2414 CA ILE B 8 11.807 11.511 59.985 1.00 81.00 C \r
-ATOM 2422 CA THR B 9 15.560 12.046 60.247 1.00 87.49 C \r
-ATOM 2429 CA PRO B 10 17.662 9.793 62.539 1.00 92.94 C \r
-ATOM 2436 CA GLU B 11 18.161 13.147 64.282 1.00 96.61 C \r
-ATOM 2445 CA GLY B 12 14.579 14.154 65.041 1.00 97.52 C \r
-ATOM 2449 CA GLU B 13 11.602 14.823 62.748 1.00 96.90 C \r
-ATOM 2458 CA VAL B 14 11.547 17.892 60.480 1.00 96.63 C \r
-ATOM 2465 CA GLU B 15 8.340 19.701 59.440 1.00 94.86 C \r
-ATOM 2474 CA LEU B 16 9.471 21.479 56.254 1.00 91.55 C \r
-ATOM 2482 CA GLN B 17 7.281 23.141 53.598 1.00 89.75 C \r
-ATOM 2491 CA VAL B 18 8.485 22.069 50.145 1.00 87.92 C \r
-ATOM 2498 CA PRO B 19 6.906 23.558 46.964 1.00 86.35 C \r
-ATOM 2505 CA ASP B 20 5.990 21.744 43.717 1.00 86.29 C \r
-ATOM 2513 CA ASP B 21 8.578 22.751 41.083 1.00 83.78 C \r
-ATOM 2521 CA VAL B 22 11.385 22.401 43.639 1.00 80.98 C \r
-ATOM 2528 CA TYR B 23 13.439 19.280 44.481 1.00 77.04 C \r
-ATOM 2540 CA ILE B 24 13.212 18.196 48.120 1.00 76.45 C \r
-ATOM 2548 CA LEU B 25 16.959 18.133 48.851 1.00 75.15 C \r
-ATOM 2556 CA ASP B 26 17.154 21.745 47.689 1.00 75.80 C \r
-ATOM 2564 CA GLN B 27 14.616 22.906 50.280 1.00 76.31 C \r
-ATOM 2573 CA ALA B 28 16.562 20.957 52.914 1.00 78.86 C \r
-ATOM 2578 CA GLU B 29 19.698 23.011 52.198 1.00 81.51 C \r
-ATOM 2587 CA GLU B 30 17.491 26.106 52.510 1.00 83.25 C \r
-ATOM 2596 CA ASP B 31 15.857 25.933 55.935 1.00 81.92 C \r
-ATOM 2604 CA GLY B 32 19.280 24.859 57.151 1.00 79.08 C \r
-ATOM 2608 CA ILE B 33 18.621 21.130 57.157 1.00 76.93 C \r
-ATOM 2616 CA ASP B 34 21.528 18.731 56.618 1.00 73.53 C \r
-ATOM 2624 CA LEU B 35 20.738 15.738 54.421 1.00 67.74 C \r
-ATOM 2632 CA PRO B 36 23.138 13.391 52.547 1.00 65.90 C \r
-ATOM 2639 CA TYR B 37 23.916 14.226 48.912 1.00 64.85 C \r
-ATOM 2651 CA SER B 38 26.659 13.373 46.412 1.00 62.58 C \r
-ATOM 2657 CA CYS B 39 26.193 13.603 42.652 1.00 60.99 C \r
-ATOM 2663 CA ARG B 40 22.908 15.441 43.251 1.00 58.35 C \r
-ATOM 2674 CA ALA B 41 21.699 14.108 39.886 1.00 56.38 C \r
-ATOM 2679 CA GLY B 42 19.886 10.955 40.991 1.00 56.66 C \r
-ATOM 2683 CA SER B 43 22.465 8.336 40.010 1.00 58.55 C \r
-ATOM 2689 CA CYS B 44 23.548 7.052 43.447 1.00 56.27 C \r
-ATOM 2695 CA SER B 45 22.057 5.987 46.791 1.00 58.20 C \r
-ATOM 2701 CA SER B 46 23.574 8.773 48.890 1.00 59.13 C \r
-ATOM 2707 CA CYS B 47 20.220 10.475 49.517 1.00 65.64 C \r
-ATOM 2713 CA ALA B 48 17.911 7.436 49.610 1.00 69.71 C \r
-ATOM 2718 CA GLY B 49 14.733 7.635 51.681 1.00 73.09 C \r
-ATOM 2722 CA LYS B 50 11.712 5.340 52.183 1.00 73.77 C \r
-ATOM 2731 CA VAL B 51 8.551 7.412 51.568 1.00 76.51 C \r
-ATOM 2738 CA VAL B 52 5.237 7.081 53.429 1.00 78.85 C \r
-ATOM 2745 CA SER B 53 2.180 9.376 53.647 1.00 79.57 C \r
-ATOM 2751 CA GLY B 54 2.118 10.991 50.218 1.00 76.32 C \r
-ATOM 2755 CA SER B 55 3.577 10.944 46.726 1.00 76.31 C \r
-ATOM 2761 CA VAL B 56 6.436 12.592 44.828 1.00 77.50 C \r
-ATOM 2768 CA ASP B 57 7.691 12.960 41.243 1.00 76.83 C \r
-ATOM 2776 CA GLN B 58 11.150 11.483 40.555 1.00 76.66 C \r
-ATOM 2785 CA SER B 59 10.976 10.827 36.792 1.00 80.19 C \r
-ATOM 2791 CA ASP B 60 14.688 11.644 36.510 1.00 83.51 C \r
-ATOM 2799 CA GLN B 61 15.175 8.137 37.916 1.00 85.74 C \r
-ATOM 2808 CA SER B 62 18.644 7.080 36.699 1.00 85.85 C \r
-ATOM 2814 CA TYR B 63 19.324 5.049 39.852 1.00 84.49 C \r
-ATOM 2826 CA LEU B 64 15.683 4.296 40.629 1.00 89.06 C \r
-ATOM 2834 CA ASP B 65 15.356 0.604 39.742 1.00 92.21 C \r
-ATOM 2842 CA ASP B 66 12.421 -1.791 39.331 1.00 92.35 C \r
-ATOM 2850 CA GLY B 67 10.747 -2.542 42.659 1.00 89.07 C \r
-ATOM 2854 CA GLN B 68 12.336 0.632 44.010 1.00 88.41 C \r
-ATOM 2863 CA ILE B 69 9.483 2.828 42.742 1.00 86.11 C \r
-ATOM 2871 CA ALA B 70 7.060 0.441 44.446 1.00 81.10 C \r
-ATOM 2876 CA ASP B 71 8.985 -0.310 47.648 1.00 76.82 C \r
-ATOM 2884 CA GLY B 72 8.653 3.423 48.186 1.00 73.00 C \r
-ATOM 2888 CA TRP B 73 12.342 4.386 48.095 1.00 67.93 C \r
-ATOM 2902 CA VAL B 74 13.052 8.007 47.136 1.00 63.84 C \r
-ATOM 2909 CA LEU B 75 16.093 9.940 45.892 1.00 58.37 C \r
-ATOM 2917 CA THR B 76 15.524 13.198 47.826 1.00 55.82 C \r
-ATOM 2924 CA CYS B 77 17.941 15.109 45.556 1.00 58.23 C \r
-ATOM 2930 CA HIS B 78 15.777 14.389 42.513 1.00 64.55 C \r
-ATOM 2940 CA ALA B 79 12.108 14.429 43.512 1.00 68.40 C \r
-ATOM 2945 CA TYR B 80 9.442 17.152 43.581 1.00 69.69 C \r
-ATOM 2957 CA PRO B 81 6.414 16.584 45.842 1.00 71.39 C \r
-ATOM 2964 CA THR B 82 3.015 16.014 44.179 1.00 73.67 C \r
-ATOM 2971 CA SER B 83 1.278 15.771 47.557 1.00 76.90 C \r
-ATOM 2977 CA ASP B 84 1.940 16.119 51.289 1.00 75.20 C \r
-ATOM 2985 CA VAL B 85 4.840 13.765 52.050 1.00 71.37 C \r
-ATOM 2992 CA VAL B 86 6.363 11.824 54.956 1.00 70.12 C \r
-ATOM 2999 CA ILE B 87 9.770 10.300 54.188 1.00 74.18 C \r
-ATOM 3007 CA GLU B 88 12.211 8.403 56.410 1.00 78.53 C \r
-ATOM 3012 CA THR B 89 15.541 9.964 55.407 1.00 79.79 C \r
-ATOM 3019 CA HIS B 90 19.062 8.538 55.881 1.00 79.40 C \r
-ATOM 3029 CA LYS B 91 17.584 5.099 55.099 1.00 84.52 C \r
-ATOM 3038 CA GLU B 92 20.016 2.596 53.549 1.00 91.64 C \r
-ATOM 3047 CA GLU B 93 20.192 -0.858 51.981 1.00 98.97 C \r
-ATOM 3056 CA GLU B 94 23.321 -2.924 51.298 1.00106.32 C \r
-ATOM 3065 CA LEU B 95 22.104 -6.552 51.453 1.00111.32 C \r
-ATOM 3073 CA THR B 96 18.778 -8.417 51.866 1.00116.01 C \r
-ATOM 3080 CA GLY B 97 18.877 -11.302 49.394 1.00116.63 C \r
-ATOM 3084 CA ALA B 98 22.056 -9.833 47.910 1.00116.02 C \r
-ATOM 3091 CA GLU C 19 26.080 -2.480 15.294 1.00 73.96 C \r
-ATOM 3100 CA SER C 20 23.405 0.198 14.956 1.00 67.27 C \r
-ATOM 3106 CA LYS C 21 22.937 3.927 15.380 1.00 59.27 C \r
-ATOM 3115 CA LYS C 22 19.198 3.481 15.874 1.00 58.42 C \r
-ATOM 3124 CA GLN C 23 17.251 3.141 19.137 1.00 59.89 C \r
-ATOM 3133 CA GLU C 24 17.931 -0.276 20.610 1.00 62.66 C \r
-ATOM 3142 CA GLU C 25 16.850 -0.453 24.226 1.00 64.27 C \r
-ATOM 3151 CA GLY C 26 13.211 -0.817 25.116 1.00 61.78 C \r
-ATOM 3155 CA VAL C 27 12.703 -2.073 21.582 1.00 58.37 C \r
-ATOM 3162 CA VAL C 28 10.779 -5.347 21.485 1.00 54.17 C \r
-ATOM 3169 CA THR C 29 9.481 -7.339 18.549 1.00 52.79 C \r
-ATOM 3176 CA ASN C 30 6.670 -9.775 17.786 1.00 51.30 C \r
-ATOM 3184 CA LEU C 31 4.863 -9.997 21.112 1.00 51.05 C \r
-ATOM 3192 CA TYR C 32 1.766 -11.297 19.327 1.00 50.51 C \r
-ATOM 3204 CA LYS C 33 1.373 -13.532 16.266 1.00 49.49 C \r
-ATOM 3213 CA PRO C 34 -1.609 -14.150 13.925 1.00 50.98 C \r
-ATOM 3220 CA LYS C 35 -2.450 -17.248 16.011 1.00 55.46 C \r
-ATOM 3229 CA GLU C 36 -2.977 -15.400 19.288 1.00 53.79 C \r
-ATOM 3238 CA PRO C 37 -3.251 -11.638 18.607 1.00 49.32 C \r
-ATOM 3245 CA TYR C 38 -3.674 -9.050 21.318 1.00 46.76 C \r
-ATOM 3257 CA VAL C 39 -7.276 -7.947 21.418 1.00 43.68 C \r
-ATOM 3264 CA GLY C 40 -7.415 -4.194 21.922 1.00 41.62 C \r
-ATOM 3268 CA ARG C 41 -10.273 -1.719 21.954 1.00 40.07 C \r
-ATOM 3279 CA CYS C 42 -11.026 1.064 19.477 1.00 36.37 C \r
-ATOM 3285 CA LEU C 43 -11.330 4.206 21.583 1.00 31.09 C \r
-ATOM 3293 CA LEU C 44 -11.337 6.671 18.673 1.00 28.46 C \r
-ATOM 3301 CA ASN C 45 -11.792 6.653 14.923 1.00 26.74 C \r
-ATOM 3309 CA THR C 46 -11.954 9.920 13.013 1.00 25.29 C \r
-ATOM 3316 CA LYS C 47 -11.667 10.775 9.352 1.00 21.50 C \r
-ATOM 3325 CA ILE C 48 -8.895 13.355 9.121 1.00 19.33 C \r
-ATOM 3333 CA THR C 49 -9.125 14.281 5.442 1.00 20.38 C \r
-ATOM 3340 CA GLY C 50 -11.630 16.676 3.855 1.00 20.12 C \r
-ATOM 3344 CA ASP C 51 -14.895 15.345 2.412 1.00 21.75 C \r
-ATOM 3352 CA ASP C 52 -13.889 16.693 -0.999 1.00 21.19 C \r
-ATOM 3360 CA ALA C 53 -10.651 14.683 -0.749 1.00 21.06 C \r
-ATOM 3365 CA PRO C 54 -10.036 11.974 -3.413 1.00 21.39 C \r
-ATOM 3372 CA GLY C 55 -9.982 9.067 -0.977 1.00 24.42 C \r
-ATOM 3376 CA GLU C 56 -10.374 9.298 2.857 1.00 22.08 C \r
-ATOM 3385 CA THR C 57 -7.723 8.611 5.517 1.00 20.31 C \r
-ATOM 3392 CA TRP C 58 -8.541 7.849 9.162 1.00 19.33 C \r
-ATOM 3406 CA HIS C 59 -6.758 8.520 12.438 1.00 22.68 C \r
-ATOM 3416 CA MET C 60 -7.645 5.951 15.108 1.00 27.16 C \r
-ATOM 3424 CA VAL C 61 -6.672 5.224 18.723 1.00 29.32 C \r
-ATOM 3431 CA PHE C 62 -6.669 1.704 20.220 1.00 34.23 C \r
-ATOM 3442 CA SER C 63 -6.102 0.643 23.847 1.00 37.05 C \r
-ATOM 3448 CA THR C 64 -3.096 -1.517 24.798 1.00 41.86 C \r
-ATOM 3455 CA GLU C 65 -3.169 -1.652 28.621 1.00 48.33 C \r
-ATOM 3464 CA GLY C 66 0.537 -0.885 28.318 1.00 52.45 C \r
-ATOM 3468 CA LYS C 67 0.955 -4.385 26.891 1.00 54.14 C \r
-ATOM 3477 CA ILE C 68 2.429 -3.211 23.570 1.00 51.52 C \r
-ATOM 3485 CA PRO C 69 5.602 -1.279 24.487 1.00 49.85 C \r
-ATOM 3492 CA TYR C 70 6.523 -0.180 20.967 1.00 44.48 C \r
-ATOM 3504 CA ARG C 71 9.185 2.353 19.993 1.00 40.96 C \r
-ATOM 3515 CA GLU C 72 8.727 5.317 17.688 1.00 33.49 C \r
-ATOM 3524 CA GLY C 73 8.913 3.876 14.164 1.00 30.16 C \r
-ATOM 3528 CA GLN C 74 7.423 0.399 14.427 1.00 31.26 C \r
-ATOM 3537 CA SER C 75 4.187 -0.913 12.966 1.00 33.65 C \r
-ATOM 3543 CA ILE C 76 1.454 -3.212 14.278 1.00 33.75 C \r
-ATOM 3551 CA GLY C 77 -0.295 -5.923 12.356 1.00 34.32 C \r
-ATOM 3555 CA VAL C 78 -4.060 -6.111 12.164 1.00 36.67 C \r
-ATOM 3562 CA ILE C 79 -6.137 -9.230 11.507 1.00 41.91 C \r
-ATOM 3570 CA ALA C 80 -9.427 -8.086 10.024 1.00 44.06 C \r
-ATOM 3575 CA ASP C 81 -12.530 -9.927 11.224 1.00 47.03 C \r
-ATOM 3583 CA GLY C 82 -13.972 -12.487 8.829 1.00 53.52 C \r
-ATOM 3587 CA VAL C 83 -12.521 -14.951 6.324 1.00 62.57 C \r
-ATOM 3594 CA ASP C 84 -11.856 -14.200 2.630 1.00 71.97 C \r
-ATOM 3602 CA LYS C 85 -12.935 -17.403 0.861 1.00 76.86 C \r
-ATOM 3611 CA ASN C 86 -13.690 -18.960 4.253 1.00 76.52 C \r
-ATOM 3619 CA GLY C 87 -10.006 -19.837 4.066 1.00 76.22 C \r
-ATOM 3623 CA LYS C 88 -8.802 -19.138 7.616 1.00 71.60 C \r
-ATOM 3632 CA PRO C 89 -8.651 -15.577 8.944 1.00 64.14 C \r
-ATOM 3639 CA HIS C 90 -7.547 -12.649 6.805 1.00 52.35 C \r
-ATOM 3649 CA LYS C 91 -3.753 -12.529 6.474 1.00 46.81 C \r
-ATOM 3658 CA VAL C 92 -2.180 -9.868 8.686 1.00 43.48 C \r
-ATOM 3665 CA ARG C 93 -1.491 -6.414 7.232 1.00 36.99 C \r
-ATOM 3676 CA LEU C 94 0.983 -3.882 8.601 1.00 32.95 C \r
-ATOM 3684 CA TYR C 95 0.340 -0.239 9.510 1.00 24.84 C \r
-ATOM 3696 CA SER C 96 3.003 2.101 10.803 1.00 23.32 C \r
-ATOM 3702 CA ILE C 97 2.244 3.502 14.236 1.00 24.12 C \r
-ATOM 3710 CA ALA C 98 1.243 7.179 13.932 1.00 22.32 C \r
-ATOM 3715 CA SER C 99 1.572 7.636 17.676 1.00 25.69 C \r
-ATOM 3721 CA SER C 100 4.752 7.924 19.726 1.00 28.83 C \r
-ATOM 3727 CA ALA C 101 5.741 5.521 22.508 1.00 35.61 C \r
-ATOM 3732 CA ILE C 102 3.906 7.635 25.079 1.00 38.39 C \r
-ATOM 3740 CA GLY C 103 0.899 7.826 22.742 1.00 31.93 C \r
-ATOM 3744 CA ASP C 104 -1.803 10.384 21.986 1.00 28.77 C \r
-ATOM 3752 CA PHE C 105 -3.050 10.293 25.607 1.00 37.05 C \r
-ATOM 3763 CA GLY C 106 0.503 10.389 26.967 1.00 39.36 C \r
-ATOM 3767 CA ASP C 107 -0.221 7.437 29.266 1.00 41.44 C \r
-ATOM 3775 CA SER C 108 1.566 4.766 27.217 1.00 42.18 C \r
-ATOM 3781 CA LYS C 109 -1.747 2.877 27.156 1.00 42.45 C \r
-ATOM 3790 CA THR C 110 -2.698 3.586 23.515 1.00 38.10 C \r
-ATOM 3797 CA VAL C 111 -1.603 2.971 19.906 1.00 32.79 C \r
-ATOM 3804 CA SER C 112 -2.671 5.020 16.872 1.00 29.60 C \r
-ATOM 3810 CA LEU C 113 -2.713 4.324 13.126 1.00 25.68 C \r
-ATOM 3818 CA CYS C 114 -3.142 6.498 9.999 1.00 24.23 C \r
-ATOM 3824 CA VAL C 115 -5.345 4.496 7.641 1.00 22.80 C \r
-ATOM 3831 CA LYS C 116 -6.221 5.196 4.015 1.00 22.11 C \r
-ATOM 3840 CA ARG C 117 -9.458 3.521 2.955 1.00 25.68 C \r
-ATOM 3851 CA LEU C 118 -8.447 1.440 -0.100 1.00 28.80 C \r
-ATOM 3859 CA ILE C 119 -11.140 1.661 -2.792 1.00 31.75 C \r
-ATOM 3867 CA TYR C 120 -10.086 0.716 -6.312 1.00 32.93 C \r
-ATOM 3879 CA THR C 121 -11.388 -0.733 -9.598 1.00 36.84 C \r
-ATOM 3886 CA ASN C 122 -10.258 -4.257 -10.546 1.00 36.90 C \r
-ATOM 3894 CA ASP C 123 -9.574 -5.562 -14.056 1.00 45.45 C \r
-ATOM 3902 CA ALA C 124 -13.196 -6.758 -14.269 1.00 44.66 C \r
-ATOM 3907 CA GLY C 125 -14.207 -3.102 -14.023 1.00 45.49 C \r
-ATOM 3911 CA GLU C 126 -16.059 -3.511 -10.722 1.00 45.54 C \r
-ATOM 3920 CA ILE C 127 -15.507 -1.321 -7.638 1.00 39.70 C \r
-ATOM 3928 CA VAL C 128 -13.846 -3.171 -4.762 1.00 38.09 C \r
-ATOM 3935 CA LYS C 129 -12.759 -2.512 -1.198 1.00 33.77 C \r
-ATOM 3944 CA GLY C 130 -9.566 -3.363 0.599 1.00 31.98 C \r
-ATOM 3948 CA VAL C 131 -10.443 -5.797 3.385 1.00 33.16 C \r
-ATOM 3955 CA CYS C 132 -8.241 -4.645 6.257 1.00 29.97 C \r
-ATOM 3961 CA SER C 133 -8.238 -0.898 5.607 1.00 30.67 C \r
-ATOM 3967 CA ASN C 134 -12.022 -0.902 5.268 1.00 30.35 C \r
-ATOM 3975 CA PHE C 135 -12.375 -2.946 8.424 1.00 29.86 C \r
-ATOM 3986 CA LEU C 136 -10.223 -0.334 10.195 1.00 29.42 C \r
-ATOM 3994 CA CYS C 137 -11.779 2.834 8.813 1.00 32.27 C \r
-ATOM 4000 CA ASP C 138 -15.116 1.280 9.724 1.00 34.29 C \r
-ATOM 4008 CA LEU C 139 -14.287 0.699 13.399 1.00 37.51 C \r
-ATOM 4016 CA GLN C 140 -16.635 2.170 16.028 1.00 43.76 C \r
-ATOM 4025 CA PRO C 141 -15.630 3.032 19.581 1.00 42.77 C \r
-ATOM 4032 CA GLY C 142 -16.082 -0.210 21.478 1.00 42.83 C \r
-ATOM 4036 CA ASP C 143 -15.117 -2.625 18.696 1.00 40.91 C \r
-ATOM 4044 CA ASN C 144 -12.182 -4.947 19.288 1.00 45.66 C \r
-ATOM 4052 CA VAL C 145 -9.056 -5.146 17.145 1.00 46.95 C \r
-ATOM 4059 CA GLN C 146 -6.707 -8.107 16.606 1.00 48.69 C \r
-ATOM 4068 CA ILE C 147 -3.249 -6.538 17.123 1.00 46.84 C \r
-ATOM 4076 CA THR C 148 -0.010 -8.392 16.264 1.00 46.26 C \r
-ATOM 4083 CA GLY C 149 3.543 -7.117 16.634 1.00 45.60 C \r
-ATOM 4087 CA PRO C 150 5.248 -4.818 17.394 1.00 44.97 C \r
-ATOM 4094 CA VAL C 151 7.423 -5.293 14.321 1.00 44.50 C \r
-ATOM 4101 CA GLY C 152 10.289 -3.716 12.438 1.00 45.33 C \r
-ATOM 4105 CA LYS C 153 13.599 -2.161 13.435 1.00 48.64 C \r
-ATOM 4114 CA GLU C 154 14.166 -0.437 10.074 1.00 48.20 C \r
-ATOM 4123 CA MET C 155 12.437 2.888 10.737 1.00 41.77 C \r
-ATOM 4131 CA LEU C 156 13.839 3.081 14.267 1.00 38.27 C \r
-ATOM 4139 CA MET C 157 15.076 6.540 15.308 1.00 34.29 C \r
-ATOM 4147 CA PRO C 158 18.782 7.419 15.339 1.00 34.05 C \r
-ATOM 4154 CA LYS C 159 20.262 7.521 18.845 1.00 35.82 C \r
-ATOM 4163 CA ASP C 160 22.076 10.792 18.273 1.00 35.95 C \r
-ATOM 4171 CA PRO C 161 19.683 13.401 19.809 1.00 35.63 C \r
-ATOM 4178 CA ASN C 162 21.563 15.948 17.758 1.00 33.92 C \r
-ATOM 4186 CA ALA C 163 21.028 14.172 14.487 1.00 30.82 C \r
-ATOM 4191 CA THR C 164 19.693 15.722 11.305 1.00 25.18 C \r
-ATOM 4198 CA ILE C 165 16.617 13.601 10.636 1.00 19.91 C \r
-ATOM 4206 CA ILE C 166 15.351 13.978 7.060 1.00 13.76 C \r
-ATOM 4214 CA MET C 167 11.843 12.550 6.703 1.00 14.98 C \r
-ATOM 4222 CA LEU C 168 10.385 11.831 3.251 1.00 16.64 C \r
-ATOM 4230 CA ALA C 169 6.747 10.808 3.007 1.00 15.85 C \r
-ATOM 4235 CA THR C 170 3.765 10.346 0.737 1.00 14.23 C \r
-ATOM 4242 CA GLY C 171 0.255 9.724 2.035 1.00 13.78 C \r
-ATOM 4246 CA THR C 172 -0.103 7.560 5.139 1.00 17.62 C \r
-ATOM 4253 CA GLY C 173 3.646 7.343 4.821 1.00 17.20 C \r
-ATOM 4257 CA ILE C 174 3.469 10.213 7.270 1.00 15.91 C \r
-ATOM 4265 CA ALA C 175 2.586 7.783 10.110 1.00 15.63 C \r
-ATOM 4270 CA PRO C 176 6.023 6.933 11.582 1.00 17.04 C \r
-ATOM 4277 CA PHE C 177 7.215 10.514 11.327 1.00 18.21 C \r
-ATOM 4288 CA ARG C 178 4.268 11.745 13.359 1.00 22.35 C \r
-ATOM 4299 CA SER C 179 5.563 9.289 15.983 1.00 25.22 C \r
-ATOM 4305 CA PHE C 180 9.139 10.593 15.614 1.00 25.98 C \r
-ATOM 4316 CA LEU C 181 7.925 14.180 15.767 1.00 29.12 C \r
-ATOM 4324 CA TRP C 182 5.625 13.641 18.714 1.00 31.35 C \r
-ATOM 4338 CA LYS C 183 8.488 12.385 20.871 1.00 30.92 C \r
-ATOM 4347 CA MET C 184 10.841 15.050 19.503 1.00 24.85 C \r
-ATOM 4355 CA PHE C 185 8.741 18.202 20.114 1.00 22.97 C \r
-ATOM 4366 CA PHE C 186 5.604 17.337 22.076 1.00 27.77 C \r
-ATOM 4377 CA GLU C 187 7.117 15.432 25.009 1.00 37.71 C \r
-ATOM 4386 CA LYS C 188 9.542 15.977 27.878 1.00 53.59 C \r
-ATOM 4395 CA HIS C 189 12.355 13.416 28.180 1.00 63.67 C \r
-ATOM 4405 CA ASP C 190 15.318 13.181 30.569 1.00 66.93 C \r
-ATOM 4413 CA ASP C 191 17.480 11.106 28.238 1.00 59.79 C \r
-ATOM 4421 CA TYR C 192 16.190 12.725 25.047 1.00 51.96 C \r
-ATOM 4433 CA LYS C 193 16.700 16.406 24.324 1.00 47.01 C \r
-ATOM 4442 CA PHE C 194 16.580 16.471 20.530 1.00 39.85 C \r
-ATOM 4453 CA ASN C 195 18.572 19.494 19.409 1.00 37.52 C \r
-ATOM 4461 CA GLY C 196 19.361 18.548 15.845 1.00 32.08 C \r
-ATOM 4465 CA LEU C 197 17.310 19.266 12.766 1.00 28.26 C \r
-ATOM 4473 CA GLY C 198 14.051 17.526 11.928 1.00 25.05 C \r
-ATOM 4477 CA TRP C 199 13.211 18.137 8.269 1.00 19.81 C \r
-ATOM 4491 CA LEU C 200 9.908 16.742 7.059 1.00 13.86 C \r
-ATOM 4499 CA PHE C 201 8.855 16.521 3.429 1.00 14.83 C \r
-ATOM 4510 CA LEU C 202 5.288 15.361 2.717 1.00 16.12 C \r
-ATOM 4518 CA GLY C 203 3.701 14.731 -0.681 1.00 13.79 C \r
-ATOM 4522 CA VAL C 204 -0.051 14.414 -1.182 1.00 11.75 C \r
-ATOM 4529 CA PRO C 205 -2.113 15.264 -4.308 1.00 14.66 C \r
-ATOM 4536 CA THR C 206 -4.553 17.737 -2.778 1.00 16.37 C \r
-ATOM 4543 CA SER C 207 -4.756 20.169 0.120 1.00 18.01 C \r
-ATOM 4549 CA SER C 208 -7.780 18.225 1.280 1.00 17.59 C \r
-ATOM 4555 CA SER C 209 -5.452 15.198 1.550 1.00 16.19 C \r
-ATOM 4561 CA LEU C 210 -2.972 16.940 3.860 1.00 14.22 C \r
-ATOM 4569 CA LEU C 211 -2.255 14.980 7.059 1.00 14.43 C \r
-ATOM 4577 CA TYR C 212 -1.624 16.449 10.549 1.00 18.94 C \r
-ATOM 4589 CA LYS C 213 -0.818 19.896 9.150 1.00 22.61 C \r
-ATOM 4598 CA GLU C 214 -2.039 21.572 12.352 1.00 25.73 C \r
-ATOM 4607 CA GLU C 215 0.152 19.413 14.514 1.00 19.23 C \r
-ATOM 4616 CA PHE C 216 3.216 20.178 12.439 1.00 17.80 C \r
-ATOM 4627 CA GLY C 217 2.478 23.890 12.512 1.00 19.90 C \r
-ATOM 4631 CA LYS C 218 2.578 24.001 16.294 1.00 25.54 C \r
-ATOM 4640 CA MET C 219 5.810 22.021 16.188 1.00 26.79 C \r
-ATOM 4648 CA LYS C 220 7.224 24.606 13.819 1.00 31.85 C \r
-ATOM 4657 CA GLU C 221 6.071 27.341 16.219 1.00 38.62 C \r
-ATOM 4666 CA ARG C 222 7.760 25.760 19.233 1.00 39.10 C \r
-ATOM 4677 CA ALA C 223 11.124 24.971 17.668 1.00 35.43 C \r
-ATOM 4682 CA PRO C 224 11.696 27.100 14.528 1.00 32.99 C \r
-ATOM 4689 CA GLU C 225 15.425 26.331 14.360 1.00 33.87 C \r
-ATOM 4698 CA ASN C 226 15.038 22.591 14.986 1.00 30.46 C \r
-ATOM 4706 CA PHE C 227 12.088 21.755 12.732 1.00 24.98 C \r
-ATOM 4717 CA ARG C 228 11.351 22.384 9.075 1.00 19.87 C \r
-ATOM 4728 CA VAL C 229 8.435 21.010 7.118 1.00 14.21 C \r
-ATOM 4735 CA ASP C 230 7.739 21.452 3.398 1.00 12.26 C \r
-ATOM 4743 CA TYR C 231 4.627 20.147 1.722 1.00 14.42 C \r
-ATOM 4755 CA ALA C 232 4.334 19.003 -1.872 1.00 9.99 C \r
-ATOM 4760 CA VAL C 233 0.778 19.232 -3.168 1.00 10.49 C \r
-ATOM 4767 CA SER C 234 1.043 17.769 -6.694 1.00 19.00 C \r
-ATOM 4773 CA ARG C 235 -2.240 19.042 -8.206 1.00 23.13 C \r
-ATOM 4784 CA GLU C 236 -2.069 22.459 -6.578 1.00 17.58 C \r
-ATOM 4793 CA GLN C 237 1.546 23.511 -6.623 1.00 15.89 C \r
-ATOM 4802 CA THR C 238 4.202 24.018 -9.275 1.00 17.86 C \r
-ATOM 4809 CA ASN C 239 7.922 24.800 -9.182 1.00 15.15 C \r
-ATOM 4817 CA ALA C 240 9.558 27.791 -10.892 1.00 21.51 C \r
-ATOM 4822 CA ALA C 241 9.475 25.887 -14.174 1.00 24.05 C \r
-ATOM 4827 CA GLY C 242 5.741 25.110 -13.938 1.00 26.25 C \r
-ATOM 4831 CA GLU C 243 5.999 21.359 -13.153 1.00 25.92 C \r
-ATOM 4840 CA ARG C 244 3.679 19.536 -10.704 1.00 24.04 C \r
-ATOM 4851 CA MET C 245 5.076 19.643 -7.174 1.00 18.58 C \r
-ATOM 4859 CA TYR C 246 5.784 16.047 -6.100 1.00 14.16 C \r
-ATOM 4871 CA ILE C 247 7.910 15.343 -3.034 1.00 16.78 C \r
-ATOM 4879 CA GLN C 248 11.089 15.070 -5.120 1.00 18.72 C \r
-ATOM 4888 CA THR C 249 10.168 18.255 -6.921 1.00 20.93 C \r
-ATOM 4895 CA ARG C 250 9.962 20.031 -3.567 1.00 19.25 C \r
-ATOM 4906 CA MET C 251 13.275 18.471 -2.561 1.00 19.40 C \r
-ATOM 4914 CA ALA C 252 14.910 19.812 -5.760 1.00 20.48 C \r
-ATOM 4919 CA GLU C 253 14.456 23.418 -4.569 1.00 18.19 C \r
-ATOM 4928 CA TYR C 254 16.804 22.515 -1.673 1.00 17.80 C \r
-ATOM 4940 CA LYS C 255 19.038 20.415 -3.902 1.00 20.66 C \r
-ATOM 4949 CA GLU C 256 22.452 21.603 -2.682 1.00 16.05 C \r
-ATOM 4958 CA GLU C 257 21.544 21.914 0.993 1.00 15.89 C \r
-ATOM 4967 CA LEU C 258 20.377 18.297 0.919 1.00 20.74 C \r
-ATOM 4975 CA TRP C 259 23.388 16.939 -0.965 1.00 23.45 C \r
-ATOM 4989 CA GLU C 260 25.645 18.669 1.563 1.00 24.08 C \r
-ATOM 4998 CA LEU C 261 23.573 17.378 4.477 1.00 24.74 C \r
-ATOM 5006 CA LEU C 262 24.020 13.928 2.938 1.00 26.14 C \r
-ATOM 5014 CA LYS C 263 27.792 14.091 3.402 1.00 25.40 C \r
-ATOM 5023 CA LYS C 264 27.457 14.521 7.176 1.00 31.47 C \r
-ATOM 5032 CA ASP C 265 27.877 11.474 9.425 1.00 35.31 C \r
-ATOM 5040 CA ASN C 266 24.934 12.482 11.620 1.00 29.63 C \r
-ATOM 5048 CA THR C 267 22.321 12.795 8.832 1.00 28.00 C \r
-ATOM 5055 CA TYR C 268 19.556 10.160 8.808 1.00 27.00 C \r
-ATOM 5067 CA VAL C 269 17.143 9.903 5.884 1.00 24.65 C \r
-ATOM 5074 CA TYR C 270 13.890 8.016 6.276 1.00 23.37 C \r
-ATOM 5086 CA MET C 271 11.373 7.327 3.518 1.00 18.93 C \r
-ATOM 5094 CA CYS C 272 7.834 6.074 4.043 1.00 18.24 C \r
-ATOM 5100 CA GLY C 273 4.784 5.874 1.826 1.00 22.39 C \r
-ATOM 5104 CA LEU C 274 3.837 4.483 -1.568 1.00 26.95 C \r
-ATOM 5112 CA LYS C 275 6.305 2.384 -3.532 1.00 32.36 C \r
-ATOM 5121 CA GLY C 276 7.741 4.199 -6.514 1.00 37.46 C \r
-ATOM 5125 CA MET C 277 7.714 7.455 -4.608 1.00 28.76 C \r
-ATOM 5133 CA GLU C 278 11.430 6.639 -4.425 1.00 32.22 C \r
-ATOM 5142 CA LYS C 279 12.017 6.321 -8.153 1.00 29.94 C \r
-ATOM 5151 CA GLY C 280 11.317 10.057 -8.293 1.00 24.18 C \r
-ATOM 5155 CA ILE C 281 13.766 10.673 -5.460 1.00 23.68 C \r
-ATOM 5163 CA ASP C 282 16.431 8.365 -6.934 1.00 26.58 C \r
-ATOM 5171 CA ASP C 283 16.211 10.530 -10.054 1.00 28.70 C \r
-ATOM 5179 CA ILE C 284 17.089 13.937 -8.538 1.00 27.28 C \r
-ATOM 5187 CA MET C 285 19.706 12.222 -6.388 1.00 27.45 C \r
-ATOM 5195 CA VAL C 286 21.377 10.712 -9.470 1.00 30.74 C \r
-ATOM 5202 CA SER C 287 21.619 14.159 -11.061 1.00 32.14 C \r
-ATOM 5208 CA LEU C 288 23.240 15.463 -7.873 1.00 34.20 C \r
-ATOM 5216 CA ALA C 289 25.801 12.653 -7.874 1.00 40.16 C \r
-ATOM 5221 CA GLU C 290 26.837 12.825 -11.536 1.00 41.84 C \r
-ATOM 5230 CA LYS C 291 27.855 16.387 -10.793 1.00 43.17 C \r
-ATOM 5239 CA ASP C 292 30.299 15.115 -8.139 1.00 41.84 C \r
-ATOM 5247 CA GLY C 293 31.237 12.232 -10.420 1.00 46.12 C \r
-ATOM 5251 CA ILE C 294 30.053 9.669 -7.864 1.00 45.54 C \r
-ATOM 5259 CA ASP C 295 27.399 6.998 -8.480 1.00 41.14 C \r
-ATOM 5267 CA TRP C 296 24.222 7.605 -6.479 1.00 30.67 C \r
-ATOM 5281 CA PHE C 297 23.381 3.910 -6.151 1.00 31.97 C \r
-ATOM 5292 CA ASP C 298 26.856 2.916 -4.907 1.00 38.12 C \r
-ATOM 5300 CA TYR C 299 26.671 5.875 -2.540 1.00 39.05 C \r
-ATOM 5312 CA LYS C 300 23.196 4.971 -1.294 1.00 41.63 C \r
-ATOM 5321 CA LYS C 301 24.542 1.489 -0.577 1.00 43.40 C \r
-ATOM 5330 CA GLN C 302 27.207 3.064 1.608 1.00 43.79 C \r
-ATOM 5339 CA LEU C 303 24.476 5.181 3.238 1.00 41.51 C \r
-ATOM 5347 CA LYS C 304 22.138 2.343 4.264 1.00 45.18 C \r
-ATOM 5356 CA ARG C 305 25.322 0.535 5.256 1.00 46.65 C \r
-ATOM 5367 CA GLY C 306 25.613 3.181 7.945 1.00 40.29 C \r
-ATOM 5371 CA ASP C 307 21.954 3.487 8.940 1.00 41.21 C \r
-ATOM 5379 CA GLN C 308 21.463 6.730 7.023 1.00 35.55 C \r
-ATOM 5388 CA TRP C 309 18.961 5.674 4.361 1.00 31.22 C \r
-ATOM 5402 CA ASN C 310 16.018 3.728 5.752 1.00 31.61 C \r
-ATOM 5410 CA VAL C 311 13.120 2.841 3.452 1.00 32.13 C \r
-ATOM 5417 CA GLU C 312 9.705 1.332 4.261 1.00 31.51 C \r
-ATOM 5426 CA VAL C 313 7.466 1.606 1.209 1.00 26.39 C \r
-ATOM 5433 CA TYR C 314 4.403 -0.343 0.111 1.00 25.42 C \r
+HEADER OXIDOREDUCTASE/ELECTRON TRANSPORT 08-MAY-00 1GAQ
+ATOM 2 CA GLU A 19 20.491 30.713 36.290 1.00 74.29 C
+ATOM 11 CA SER A 20 24.056 29.774 37.264 1.00 72.09 C
+ATOM 17 CA LYS A 21 27.517 31.289 37.563 1.00 70.09 C
+ATOM 26 CA LYS A 22 28.794 27.865 36.481 1.00 68.64 C
+ATOM 35 CA GLN A 23 29.484 26.806 32.884 1.00 70.46 C
+ATOM 44 CA GLU A 24 26.420 25.175 31.360 1.00 72.08 C
+ATOM 53 CA GLU A 25 26.736 26.049 27.683 1.00 70.43 C
+ATOM 62 CA GLY A 26 28.299 22.912 26.233 1.00 63.14 C
+ATOM 66 CA VAL A 27 26.863 20.704 28.982 1.00 54.50 C
+ATOM 73 CA VAL A 28 25.030 17.390 28.655 1.00 48.32 C
+ATOM 80 CA THR A 29 23.728 14.677 30.991 1.00 44.86 C
+ATOM 87 CA ASN A 30 22.327 11.164 30.703 1.00 45.42 C
+ATOM 95 CA LEU A 31 23.332 10.459 27.102 1.00 45.42 C
+ATOM 103 CA TYR A 32 23.549 6.898 28.380 1.00 45.88 C
+ATOM 115 CA LYS A 33 21.656 5.321 31.262 1.00 47.27 C
+ATOM 124 CA PRO A 34 21.991 2.046 33.248 1.00 48.99 C
+ATOM 131 CA LYS A 35 19.339 0.560 30.970 1.00 52.75 C
+ATOM 140 CA GLU A 36 21.580 0.855 27.886 1.00 53.33 C
+ATOM 149 CA PRO A 37 25.154 2.015 28.678 1.00 47.54 C
+ATOM 156 CA TYR A 38 27.929 2.872 26.249 1.00 41.98 C
+ATOM 168 CA VAL A 39 30.355 -0.017 25.909 1.00 41.48 C
+ATOM 175 CA GLY A 40 33.823 1.485 25.966 1.00 37.59 C
+ATOM 179 CA ARG A 41 37.165 -0.277 26.122 1.00 39.77 C
+ATOM 190 CA CYS A 42 40.148 -0.029 28.442 1.00 36.51 C
+ATOM 196 CA LEU A 43 43.095 1.441 26.554 1.00 36.13 C
+ATOM 204 CA LEU A 44 45.231 2.023 29.649 1.00 33.55 C
+ATOM 212 CA ASN A 45 45.140 1.026 33.307 1.00 27.79 C
+ATOM 220 CA THR A 46 48.056 1.800 35.617 1.00 28.75 C
+ATOM 227 CA LYS A 47 48.542 1.776 39.388 1.00 30.31 C
+ATOM 236 CA ILE A 48 49.564 5.317 40.376 1.00 31.32 C
+ATOM 244 CA THR A 49 50.339 4.682 44.059 1.00 37.62 C
+ATOM 251 CA GLY A 50 53.585 3.317 45.460 1.00 44.49 C
+ATOM 255 CA ASP A 51 53.706 -0.448 46.087 1.00 52.89 C
+ATOM 263 CA ASP A 52 53.910 0.545 49.751 1.00 55.23 C
+ATOM 271 CA ALA A 53 50.816 2.767 50.056 1.00 53.34 C
+ATOM 276 CA PRO A 54 47.904 1.940 52.405 1.00 50.60 C
+ATOM 283 CA GLY A 55 45.420 1.579 49.561 1.00 50.35 C
+ATOM 287 CA GLU A 56 46.098 1.286 45.836 1.00 42.53 C
+ATOM 296 CA THR A 57 44.534 3.816 43.480 1.00 41.14 C
+ATOM 303 CA TRP A 58 44.540 3.423 39.708 1.00 35.60 C
+ATOM 317 CA HIS A 59 44.468 5.853 36.796 1.00 31.89 C
+ATOM 327 CA MET A 60 42.658 4.227 33.866 1.00 31.65 C
+ATOM 335 CA VAL A 61 41.716 5.345 30.350 1.00 30.43 C
+ATOM 342 CA PHE A 62 38.669 4.172 28.360 1.00 34.36 C
+ATOM 353 CA SER A 63 37.657 4.908 24.772 1.00 34.69 C
+ATOM 359 CA THR A 64 34.448 6.828 23.951 1.00 36.96 C
+ATOM 366 CA GLU A 65 34.691 7.644 20.254 1.00 40.08 C
+ATOM 375 CA GLY A 66 33.742 11.183 21.285 1.00 40.22 C
+ATOM 379 CA LYS A 67 30.272 9.763 22.003 1.00 41.93 C
+ATOM 388 CA ILE A 68 30.279 11.116 25.577 1.00 41.52 C
+ATOM 396 CA PRO A 69 30.791 14.926 25.537 1.00 42.35 C
+ATOM 403 CA TYR A 70 31.228 15.232 29.299 1.00 39.84 C
+ATOM 415 CA ARG A 71 32.639 18.451 30.768 1.00 44.14 C
+ATOM 426 CA GLU A 72 35.122 19.278 33.515 1.00 43.82 C
+ATOM 435 CA GLY A 73 33.472 18.458 36.835 1.00 41.97 C
+ATOM 439 CA GLN A 74 30.929 15.874 35.657 1.00 37.19 C
+ATOM 448 CA SER A 75 31.285 12.124 36.138 1.00 38.28 C
+ATOM 454 CA ILE A 76 30.458 8.792 34.539 1.00 36.84 C
+ATOM 462 CA GLY A 77 28.983 5.620 35.918 1.00 35.39 C
+ATOM 466 CA VAL A 78 30.311 2.108 35.530 1.00 32.05 C
+ATOM 473 CA ILE A 79 28.458 -1.201 35.591 1.00 32.67 C
+ATOM 481 CA ALA A 80 30.745 -4.018 36.644 1.00 35.36 C
+ATOM 486 CA ASP A 81 30.359 -7.373 34.872 1.00 38.72 C
+ATOM 494 CA GLY A 82 28.308 -10.332 36.110 1.00 45.79 C
+ATOM 498 CA VAL A 83 25.820 -10.242 39.001 1.00 52.24 C
+ATOM 505 CA ASP A 84 25.838 -10.250 42.834 1.00 60.54 C
+ATOM 513 CA LYS A 85 25.014 -13.158 45.196 1.00 66.72 C
+ATOM 522 CA ASN A 86 21.414 -13.062 43.904 1.00 67.37 C
+ATOM 530 CA GLY A 87 21.724 -13.423 40.136 1.00 64.74 C
+ATOM 534 CA LYS A 88 20.971 -9.733 39.570 1.00 61.12 C
+ATOM 543 CA PRO A 89 23.054 -7.201 37.561 1.00 54.68 C
+ATOM 550 CA HIS A 90 25.224 -4.957 39.755 1.00 44.44 C
+ATOM 560 CA LYS A 91 23.940 -1.433 40.260 1.00 40.48 C
+ATOM 569 CA VAL A 92 25.803 1.546 38.843 1.00 38.45 C
+ATOM 576 CA ARG A 93 28.709 2.986 40.828 1.00 38.93 C
+ATOM 587 CA LEU A 94 29.778 6.584 40.096 1.00 34.37 C
+ATOM 595 CA TYR A 95 33.309 7.878 39.513 1.00 30.27 C
+ATOM 607 CA SER A 96 34.425 11.475 39.057 1.00 29.44 C
+ATOM 613 CA ILE A 97 36.029 12.090 35.662 1.00 27.61 C
+ATOM 621 CA ALA A 98 39.769 12.693 36.069 1.00 31.12 C
+ATOM 626 CA SER A 99 40.393 13.712 32.475 1.00 32.42 C
+ATOM 632 CA SER A 100 39.566 17.142 31.059 1.00 36.14 C
+ATOM 638 CA ALA A 101 37.097 17.367 28.154 1.00 41.07 C
+ATOM 643 CA ILE A 102 39.764 16.549 25.527 1.00 47.65 C
+ATOM 651 CA GLY A 103 41.172 13.692 27.599 1.00 46.77 C
+ATOM 655 CA ASP A 104 44.730 12.612 28.289 1.00 43.82 C
+ATOM 663 CA PHE A 105 45.115 12.065 24.522 1.00 41.52 C
+ATOM 674 CA GLY A 106 43.862 15.455 23.328 1.00 41.66 C
+ATOM 678 CA ASP A 107 41.355 13.883 20.926 1.00 40.90 C
+ATOM 686 CA SER A 108 38.132 14.250 22.954 1.00 42.95 C
+ATOM 692 CA LYS A 109 37.967 10.535 22.224 1.00 44.74 C
+ATOM 701 CA THR A 110 38.731 9.184 25.704 1.00 41.09 C
+ATOM 708 CA VAL A 111 37.728 9.519 29.374 1.00 39.03 C
+ATOM 715 CA SER A 112 39.912 8.705 32.399 1.00 37.17 C
+ATOM 721 CA LEU A 113 39.098 7.476 35.935 1.00 32.10 C
+ATOM 729 CA CYS A 114 40.964 7.578 39.261 1.00 30.65 C
+ATOM 735 CA VAL A 115 39.724 4.459 41.060 1.00 33.45 C
+ATOM 742 CA LYS A 116 40.668 3.524 44.628 1.00 34.75 C
+ATOM 751 CA ARG A 117 40.376 -0.250 45.123 1.00 32.85 C
+ATOM 762 CA LEU A 118 38.137 -1.094 48.077 1.00 30.50 C
+ATOM 770 CA ILE A 119 39.376 -3.752 50.459 1.00 34.34 C
+ATOM 778 CA TYR A 120 38.699 -4.266 54.125 1.00 31.39 C
+ATOM 790 CA THR A 121 38.264 -7.086 56.567 1.00 28.83 C
+ATOM 797 CA ASN A 122 34.792 -7.477 58.109 1.00 26.51 C
+ATOM 805 CA ASP A 123 33.626 -8.382 61.634 1.00 31.58 C
+ATOM 813 CA ALA A 124 34.191 -12.077 60.901 1.00 27.84 C
+ATOM 818 CA GLY A 125 37.759 -11.844 59.728 1.00 32.39 C
+ATOM 822 CA GLU A 126 36.809 -12.146 56.073 1.00 35.82 C
+ATOM 831 CA ILE A 127 38.655 -9.932 53.598 1.00 38.42 C
+ATOM 839 CA VAL A 128 36.025 -8.261 51.421 1.00 33.73 C
+ATOM 846 CA LYS A 129 36.482 -6.484 48.090 1.00 31.87 C
+ATOM 855 CA GLY A 130 34.363 -3.680 46.686 1.00 26.91 C
+ATOM 859 CA VAL A 131 32.680 -5.051 43.569 1.00 27.89 C
+ATOM 866 CA CYS A 132 33.074 -2.246 41.018 1.00 28.46 C
+ATOM 872 CA SER A 133 36.266 -0.553 42.213 1.00 31.33 C
+ATOM 878 CA ASN A 134 37.861 -3.983 41.984 1.00 30.29 C
+ATOM 886 CA PHE A 135 36.318 -4.795 38.623 1.00 31.48 C
+ATOM 897 CA LEU A 136 37.926 -1.553 37.520 1.00 27.81 C
+ATOM 905 CA CYS A 137 41.417 -1.976 38.955 1.00 25.91 C
+ATOM 911 CA ASP A 138 41.605 -5.419 37.338 1.00 30.22 C
+ATOM 919 CA LEU A 139 40.462 -4.306 33.874 1.00 32.69 C
+ATOM 927 CA GLN A 140 42.851 -5.511 31.186 1.00 36.80 C
+ATOM 936 CA PRO A 141 43.380 -3.220 28.170 1.00 36.16 C
+ATOM 943 CA GLY A 142 40.864 -4.420 25.586 1.00 31.10 C
+ATOM 947 CA ASP A 143 38.129 -5.298 28.055 1.00 30.62 C
+ATOM 955 CA ASN A 144 34.690 -3.847 27.645 1.00 33.52 C
+ATOM 963 CA VAL A 145 33.430 -1.522 30.361 1.00 37.08 C
+ATOM 970 CA GLN A 146 29.817 -0.374 30.523 1.00 37.65 C
+ATOM 979 CA ILE A 147 29.547 3.413 31.045 1.00 30.95 C
+ATOM 987 CA THR A 148 26.637 5.791 31.832 1.00 29.95 C
+ATOM 994 CA GLY A 149 26.297 9.581 31.843 1.00 32.81 C
+ATOM 998 CA PRO A 150 27.785 12.148 31.800 1.00 34.98 C
+ATOM 1005 CA VAL A 151 26.376 12.668 35.275 1.00 36.53 C
+ATOM 1012 CA GLY A 152 26.196 15.756 37.474 1.00 43.09 C
+ATOM 1016 CA LYS A 153 26.048 19.528 37.068 1.00 48.37 C
+ATOM 1025 CA GLU A 154 26.921 20.540 40.633 1.00 49.70 C
+ATOM 1034 CA MET A 155 30.710 20.266 40.235 1.00 47.30 C
+ATOM 1042 CA LEU A 156 30.882 22.020 36.869 1.00 50.36 C
+ATOM 1050 CA MET A 157 33.362 24.883 36.404 1.00 55.29 C
+ATOM 1058 CA PRO A 158 32.521 28.612 36.605 1.00 54.88 C
+ATOM 1065 CA LYS A 159 32.291 30.776 33.464 1.00 54.92 C
+ATOM 1074 CA ASP A 160 34.497 33.503 34.939 1.00 57.22 C
+ATOM 1082 CA PRO A 161 38.055 32.687 33.759 1.00 58.62 C
+ATOM 1089 CA ASN A 162 39.524 35.240 36.163 1.00 60.44 C
+ATOM 1097 CA ALA A 163 37.814 33.910 39.279 1.00 55.80 C
+ATOM 1102 CA THR A 164 39.596 32.487 42.316 1.00 51.04 C
+ATOM 1109 CA ILE A 165 38.966 28.771 42.756 1.00 50.26 C
+ATOM 1117 CA ILE A 166 39.774 26.773 45.885 1.00 47.54 C
+ATOM 1125 CA MET A 167 39.883 23.014 45.324 1.00 46.38 C
+ATOM 1133 CA LEU A 168 39.700 20.963 48.522 1.00 42.18 C
+ATOM 1141 CA ALA A 169 40.377 17.316 47.770 1.00 36.41 C
+ATOM 1146 CA THR A 170 41.005 14.086 49.622 1.00 32.98 C
+ATOM 1153 CA GLY A 171 42.027 10.802 48.014 1.00 31.36 C
+ATOM 1157 CA THR A 172 40.386 10.037 44.680 1.00 30.48 C
+ATOM 1164 CA GLY A 173 38.640 13.335 45.359 1.00 33.99 C
+ATOM 1168 CA ILE A 174 41.418 15.036 43.394 1.00 35.66 C
+ATOM 1176 CA ALA A 175 39.758 13.585 40.300 1.00 36.00 C
+ATOM 1181 CA PRO A 176 37.445 16.385 39.155 1.00 39.41 C
+ATOM 1188 CA PHE A 177 40.109 18.971 39.976 1.00 43.21 C
+ATOM 1199 CA ARG A 178 42.726 17.119 37.955 1.00 41.09 C
+ATOM 1210 CA SER A 179 40.235 17.536 35.124 1.00 39.92 C
+ATOM 1216 CA PHE A 180 39.808 21.204 36.009 1.00 39.23 C
+ATOM 1227 CA LEU A 181 43.528 21.949 35.995 1.00 39.50 C
+ATOM 1235 CA TRP A 182 44.305 20.081 32.770 1.00 41.47 C
+ATOM 1249 CA LYS A 183 42.141 22.654 30.972 1.00 48.08 C
+ATOM 1258 CA MET A 184 43.477 25.547 33.062 1.00 52.79 C
+ATOM 1266 CA PHE A 185 47.102 25.043 32.014 1.00 57.35 C
+ATOM 1277 CA PHE A 186 48.075 21.921 30.051 1.00 55.98 C
+ATOM 1288 CA GLU A 187 45.758 23.173 27.297 1.00 54.44 C
+ATOM 1297 CA LYS A 188 44.908 26.236 25.196 1.00 51.29 C
+ATOM 1306 CA HIS A 189 41.395 27.080 24.003 1.00 51.35 C
+ATOM 1316 CA ASP A 190 40.108 29.972 21.873 1.00 54.30 C
+ATOM 1324 CA ASP A 191 37.199 30.481 24.249 1.00 53.95 C
+ATOM 1332 CA TYR A 192 38.816 29.937 27.634 1.00 50.68 C
+ATOM 1344 CA LYS A 193 41.916 31.388 29.230 1.00 51.00 C
+ATOM 1353 CA PHE A 194 42.322 30.967 32.956 1.00 52.09 C
+ATOM 1364 CA ASN A 195 43.672 34.234 34.312 1.00 56.46 C
+ATOM 1372 CA GLY A 196 42.616 34.078 37.969 1.00 57.17 C
+ATOM 1376 CA LEU A 197 43.874 31.920 40.843 1.00 57.92 C
+ATOM 1384 CA GLY A 198 43.549 28.151 41.086 1.00 56.67 C
+ATOM 1388 CA TRP A 199 44.258 26.886 44.592 1.00 51.55 C
+ATOM 1402 CA LEU A 200 44.411 23.170 45.379 1.00 49.17 C
+ATOM 1410 CA PHE A 201 44.558 21.335 48.709 1.00 48.60 C
+ATOM 1421 CA LEU A 202 45.122 17.570 48.598 1.00 45.34 C
+ATOM 1429 CA GLY A 203 44.885 15.480 51.742 1.00 48.55 C
+ATOM 1433 CA VAL A 204 46.225 11.936 51.755 1.00 50.23 C
+ATOM 1440 CA PRO A 205 47.942 9.740 54.365 1.00 51.51 C
+ATOM 1447 CA THR A 206 51.284 9.148 52.648 1.00 50.21 C
+ATOM 1454 CA SER A 207 53.551 10.483 49.894 1.00 49.38 C
+ATOM 1460 CA SER A 208 53.267 7.061 48.259 1.00 43.49 C
+ATOM 1466 CA SER A 209 49.588 8.049 48.093 1.00 42.57 C
+ATOM 1472 CA LEU A 210 49.990 11.424 46.364 1.00 42.65 C
+ATOM 1480 CA LEU A 211 48.121 11.446 43.035 1.00 39.33 C
+ATOM 1488 CA TYR A 212 49.516 13.214 39.935 1.00 40.89 C
+ATOM 1500 CA LYS A 213 52.128 15.234 41.873 1.00 45.88 C
+ATOM 1509 CA GLU A 214 54.518 15.406 38.899 1.00 53.22 C
+ATOM 1518 CA GLU A 215 51.680 16.911 36.889 1.00 55.16 C
+ATOM 1527 CA PHE A 216 50.757 19.475 39.514 1.00 60.55 C
+ATOM 1538 CA GLY A 217 54.488 20.153 39.524 1.00 66.64 C
+ATOM 1542 CA LYS A 218 54.575 21.110 35.850 1.00 68.86 C
+ATOM 1551 CA MET A 219 51.398 23.159 36.265 1.00 66.97 C
+ATOM 1559 CA LYS A 220 53.138 25.090 39.061 1.00 65.97 C
+ATOM 1568 CA GLU A 221 55.654 26.250 36.459 1.00 70.02 C
+ATOM 1577 CA ARG A 222 53.584 26.507 33.294 1.00 73.48 C
+ATOM 1588 CA ALA A 223 52.005 29.449 35.175 1.00 76.21 C
+ATOM 1593 CA PRO A 224 53.272 29.877 38.804 1.00 79.25 C
+ATOM 1600 CA GLU A 225 51.296 33.124 39.020 1.00 81.84 C
+ATOM 1609 CA ASN A 226 47.873 31.528 38.622 1.00 78.84 C
+ATOM 1617 CA PHE A 227 48.418 28.176 40.350 1.00 75.28 C
+ATOM 1628 CA ARG A 228 49.090 27.305 43.996 1.00 72.05 C
+ATOM 1639 CA VAL A 229 49.165 23.724 45.323 1.00 68.82 C
+ATOM 1646 CA ASP A 230 49.258 22.581 48.958 1.00 66.54 C
+ATOM 1654 CA TYR A 231 49.605 18.943 49.968 1.00 60.31 C
+ATOM 1666 CA ALA A 232 48.551 17.560 53.332 1.00 57.39 C
+ATOM 1671 CA VAL A 233 50.260 14.228 53.945 1.00 57.14 C
+ATOM 1678 CA SER A 234 48.465 13.579 57.244 1.00 60.81 C
+ATOM 1684 CA ARG A 235 50.959 11.010 58.514 1.00 60.74 C
+ATOM 1695 CA GLU A 236 54.268 12.594 57.481 1.00 59.17 C
+ATOM 1704 CA GLN A 237 53.494 16.197 58.450 1.00 59.62 C
+ATOM 1713 CA THR A 238 52.590 18.236 61.521 1.00 63.18 C
+ATOM 1720 CA ASN A 239 52.019 21.937 62.188 1.00 66.71 C
+ATOM 1728 CA ALA A 240 52.096 23.767 65.537 1.00 70.06 C
+ATOM 1733 CA ALA A 241 51.302 21.400 68.410 1.00 72.44 C
+ATOM 1738 CA GLY A 242 52.383 18.324 66.438 1.00 72.38 C
+ATOM 1742 CA GLU A 243 48.826 18.169 65.110 1.00 69.71 C
+ATOM 1751 CA ARG A 244 48.674 15.776 62.148 1.00 67.21 C
+ATOM 1762 CA MET A 245 48.712 17.796 58.933 1.00 64.20 C
+ATOM 1770 CA TYR A 246 45.246 17.082 57.556 1.00 60.65 C
+ATOM 1782 CA ILE A 247 43.617 18.437 54.409 1.00 62.98 C
+ATOM 1790 CA GLN A 248 42.035 21.001 56.761 1.00 64.64 C
+ATOM 1799 CA THR A 249 45.057 21.461 59.009 1.00 63.37 C
+ATOM 1806 CA ARG A 250 46.891 22.664 55.903 1.00 62.47 C
+ATOM 1817 CA MET A 251 44.123 25.201 55.251 1.00 63.35 C
+ATOM 1825 CA ALA A 252 44.571 26.305 58.854 1.00 65.73 C
+ATOM 1830 CA GLU A 253 47.973 27.809 58.076 1.00 65.97 C
+ATOM 1839 CA TYR A 254 46.267 30.063 55.517 1.00 65.83 C
+ATOM 1851 CA LYS A 255 42.991 30.559 57.379 1.00 70.30 C
+ATOM 1860 CA GLU A 256 43.578 34.326 57.320 1.00 73.73 C
+ATOM 1869 CA GLU A 257 44.189 34.738 53.593 1.00 71.52 C
+ATOM 1878 CA LEU A 258 41.459 32.202 52.893 1.00 73.38 C
+ATOM 1886 CA TRP A 259 38.790 34.074 54.853 1.00 76.72 C
+ATOM 1900 CA GLU A 260 39.721 37.275 53.006 1.00 78.61 C
+ATOM 1909 CA LEU A 261 38.580 35.553 49.815 1.00 75.71 C
+ATOM 1917 CA LEU A 262 35.391 33.881 51.047 1.00 73.74 C
+ATOM 1925 CA LYS A 263 33.562 37.165 50.535 1.00 73.64 C
+ATOM 1934 CA LYS A 264 34.299 38.143 46.954 1.00 72.48 C
+ATOM 1943 CA ASP A 265 31.954 37.554 43.993 1.00 69.65 C
+ATOM 1951 CA ASN A 266 34.660 35.649 42.106 1.00 65.06 C
+ATOM 1959 CA THR A 267 35.835 33.117 44.683 1.00 58.24 C
+ATOM 1966 CA TYR A 268 34.459 29.646 43.909 1.00 51.04 C
+ATOM 1978 CA VAL A 269 35.192 26.827 46.382 1.00 44.95 C
+ATOM 1985 CA TYR A 270 35.012 23.150 45.368 1.00 44.96 C
+ATOM 1997 CA MET A 271 35.162 20.122 47.656 1.00 41.72 C
+ATOM 2005 CA CYS A 272 35.314 16.468 46.632 1.00 37.19 C
+ATOM 2011 CA GLY A 273 36.343 13.080 47.951 1.00 37.65 C
+ATOM 2015 CA LEU A 274 36.040 10.886 51.020 1.00 39.39 C
+ATOM 2023 CA LYS A 275 33.076 12.283 52.955 1.00 44.86 C
+ATOM 2032 CA GLY A 276 34.322 13.183 56.400 1.00 49.16 C
+ATOM 2036 CA MET A 277 36.932 15.608 55.168 1.00 53.30 C
+ATOM 2044 CA GLU A 278 33.917 17.921 55.165 1.00 56.74 C
+ATOM 2053 CA LYS A 279 33.531 18.089 58.947 1.00 59.30 C
+ATOM 2062 CA GLY A 280 36.982 19.413 59.776 1.00 58.94 C
+ATOM 2066 CA ILE A 281 36.705 22.048 57.063 1.00 61.43 C
+ATOM 2074 CA ASP A 282 33.453 23.402 58.515 1.00 67.06 C
+ATOM 2082 CA ASP A 283 35.050 23.189 61.972 1.00 74.12 C
+ATOM 2090 CA ILE A 284 37.991 25.422 61.040 1.00 78.49 C
+ATOM 2098 CA MET A 285 35.456 27.566 59.201 1.00 82.25 C
+ATOM 2106 CA VAL A 286 32.941 27.959 62.027 1.00 83.44 C
+ATOM 2113 CA SER A 287 35.610 29.113 64.469 1.00 83.43 C
+ATOM 2119 CA LEU A 288 36.927 31.601 61.887 1.00 85.53 C
+ATOM 2127 CA ALA A 289 33.506 33.025 60.970 1.00 86.85 C
+ATOM 2132 CA GLU A 290 31.841 32.696 64.387 1.00 89.26 C
+ATOM 2141 CA LYS A 291 34.438 35.312 65.347 1.00 88.73 C
+ATOM 2150 CA ASP A 292 33.635 37.891 62.652 1.00 88.03 C
+ATOM 2158 CA GLY A 293 30.219 37.450 61.081 1.00 87.88 C
+ATOM 2162 CA ILE A 294 27.319 35.051 61.511 1.00 84.61 C
+ATOM 2170 CA ASP A 295 27.665 31.329 62.188 1.00 82.45 C
+ATOM 2178 CA TRP A 296 29.539 29.627 59.355 1.00 80.12 C
+ATOM 2192 CA PHE A 297 26.527 27.452 58.512 1.00 78.99 C
+ATOM 2203 CA ASP A 298 24.167 30.241 57.486 1.00 76.37 C
+ATOM 2211 CA TYR A 299 27.074 31.748 55.561 1.00 74.07 C
+ATOM 2223 CA LYS A 300 27.679 28.620 53.473 1.00 74.31 C
+ATOM 2232 CA LYS A 301 24.059 29.146 52.464 1.00 75.97 C
+ATOM 2241 CA GLN A 302 24.921 32.563 51.018 1.00 75.38 C
+ATOM 2250 CA LEU A 303 27.896 31.099 49.155 1.00 72.10 C
+ATOM 2258 CA LYS A 304 25.917 28.207 47.690 1.00 72.08 C
+ATOM 2267 CA ARG A 305 23.595 31.021 46.594 1.00 74.82 C
+ATOM 2278 CA GLY A 306 26.071 32.136 43.958 1.00 71.84 C
+ATOM 2282 CA ASP A 307 27.505 28.682 43.220 1.00 67.23 C
+ATOM 2290 CA GLN A 308 30.620 29.291 45.346 1.00 60.18 C
+ATOM 2299 CA TRP A 309 30.585 26.177 47.537 1.00 52.25 C
+ATOM 2313 CA ASN A 310 29.894 22.997 45.597 1.00 45.03 C
+ATOM 2321 CA VAL A 311 30.327 19.716 47.403 1.00 39.13 C
+ATOM 2328 CA GLU A 312 30.507 16.190 46.110 1.00 35.17 C
+ATOM 2337 CA VAL A 313 31.761 13.957 48.861 1.00 30.12 C
+ATOM 2344 CA TYR A 314 31.112 10.230 49.021 1.00 28.23 C
+ATOM 2358 CA ALA B 1 2.311 24.702 44.475 1.00 74.17 C
+ATOM 2363 CA THR B 2 3.590 24.207 48.055 1.00 74.76 C
+ATOM 2370 CA TYR B 3 3.069 20.876 49.837 1.00 73.52 C
+ATOM 2382 CA ASN B 4 3.748 19.874 53.435 1.00 75.75 C
+ATOM 2390 CA VAL B 5 6.618 17.399 53.868 1.00 75.95 C
+ATOM 2397 CA LYS B 6 7.769 15.523 56.983 1.00 77.70 C
+ATOM 2406 CA LEU B 7 11.351 14.325 57.458 1.00 78.91 C
+ATOM 2414 CA ILE B 8 11.807 11.511 59.985 1.00 81.00 C
+ATOM 2422 CA THR B 9 15.560 12.046 60.247 1.00 87.49 C
+ATOM 2429 CA PRO B 10 17.662 9.793 62.539 1.00 92.94 C
+ATOM 2436 CA GLU B 11 18.161 13.147 64.282 1.00 96.61 C
+ATOM 2445 CA GLY B 12 14.579 14.154 65.041 1.00 97.52 C
+ATOM 2449 CA GLU B 13 11.602 14.823 62.748 1.00 96.90 C
+ATOM 2458 CA VAL B 14 11.547 17.892 60.480 1.00 96.63 C
+ATOM 2465 CA GLU B 15 8.340 19.701 59.440 1.00 94.86 C
+ATOM 2474 CA LEU B 16 9.471 21.479 56.254 1.00 91.55 C
+ATOM 2482 CA GLN B 17 7.281 23.141 53.598 1.00 89.75 C
+ATOM 2491 CA VAL B 18 8.485 22.069 50.145 1.00 87.92 C
+ATOM 2498 CA PRO B 19 6.906 23.558 46.964 1.00 86.35 C
+ATOM 2505 CA ASP B 20 5.990 21.744 43.717 1.00 86.29 C
+ATOM 2513 CA ASP B 21 8.578 22.751 41.083 1.00 83.78 C
+ATOM 2521 CA VAL B 22 11.385 22.401 43.639 1.00 80.98 C
+ATOM 2528 CA TYR B 23 13.439 19.280 44.481 1.00 77.04 C
+ATOM 2540 CA ILE B 24 13.212 18.196 48.120 1.00 76.45 C
+ATOM 2548 CA LEU B 25 16.959 18.133 48.851 1.00 75.15 C
+ATOM 2556 CA ASP B 26 17.154 21.745 47.689 1.00 75.80 C
+ATOM 2564 CA GLN B 27 14.616 22.906 50.280 1.00 76.31 C
+ATOM 2573 CA ALA B 28 16.562 20.957 52.914 1.00 78.86 C
+ATOM 2578 CA GLU B 29 19.698 23.011 52.198 1.00 81.51 C
+ATOM 2587 CA GLU B 30 17.491 26.106 52.510 1.00 83.25 C
+ATOM 2596 CA ASP B 31 15.857 25.933 55.935 1.00 81.92 C
+ATOM 2604 CA GLY B 32 19.280 24.859 57.151 1.00 79.08 C
+ATOM 2608 CA ILE B 33 18.621 21.130 57.157 1.00 76.93 C
+ATOM 2616 CA ASP B 34 21.528 18.731 56.618 1.00 73.53 C
+ATOM 2624 CA LEU B 35 20.738 15.738 54.421 1.00 67.74 C
+ATOM 2632 CA PRO B 36 23.138 13.391 52.547 1.00 65.90 C
+ATOM 2639 CA TYR B 37 23.916 14.226 48.912 1.00 64.85 C
+ATOM 2651 CA SER B 38 26.659 13.373 46.412 1.00 62.58 C
+ATOM 2657 CA CYS B 39 26.193 13.603 42.652 1.00 60.99 C
+ATOM 2663 CA ARG B 40 22.908 15.441 43.251 1.00 58.35 C
+ATOM 2674 CA ALA B 41 21.699 14.108 39.886 1.00 56.38 C
+ATOM 2679 CA GLY B 42 19.886 10.955 40.991 1.00 56.66 C
+ATOM 2683 CA SER B 43 22.465 8.336 40.010 1.00 58.55 C
+ATOM 2689 CA CYS B 44 23.548 7.052 43.447 1.00 56.27 C
+ATOM 2695 CA SER B 45 22.057 5.987 46.791 1.00 58.20 C
+ATOM 2701 CA SER B 46 23.574 8.773 48.890 1.00 59.13 C
+ATOM 2707 CA CYS B 47 20.220 10.475 49.517 1.00 65.64 C
+ATOM 2713 CA ALA B 48 17.911 7.436 49.610 1.00 69.71 C
+ATOM 2718 CA GLY B 49 14.733 7.635 51.681 1.00 73.09 C
+ATOM 2722 CA LYS B 50 11.712 5.340 52.183 1.00 73.77 C
+ATOM 2731 CA VAL B 51 8.551 7.412 51.568 1.00 76.51 C
+ATOM 2738 CA VAL B 52 5.237 7.081 53.429 1.00 78.85 C
+ATOM 2745 CA SER B 53 2.180 9.376 53.647 1.00 79.57 C
+ATOM 2751 CA GLY B 54 2.118 10.991 50.218 1.00 76.32 C
+ATOM 2755 CA SER B 55 3.577 10.944 46.726 1.00 76.31 C
+ATOM 2761 CA VAL B 56 6.436 12.592 44.828 1.00 77.50 C
+ATOM 2768 CA ASP B 57 7.691 12.960 41.243 1.00 76.83 C
+ATOM 2776 CA GLN B 58 11.150 11.483 40.555 1.00 76.66 C
+ATOM 2785 CA SER B 59 10.976 10.827 36.792 1.00 80.19 C
+ATOM 2791 CA ASP B 60 14.688 11.644 36.510 1.00 83.51 C
+ATOM 2799 CA GLN B 61 15.175 8.137 37.916 1.00 85.74 C
+ATOM 2808 CA SER B 62 18.644 7.080 36.699 1.00 85.85 C
+ATOM 2814 CA TYR B 63 19.324 5.049 39.852 1.00 84.49 C
+ATOM 2826 CA LEU B 64 15.683 4.296 40.629 1.00 89.06 C
+ATOM 2834 CA ASP B 65 15.356 0.604 39.742 1.00 92.21 C
+ATOM 2842 CA ASP B 66 12.421 -1.791 39.331 1.00 92.35 C
+ATOM 2850 CA GLY B 67 10.747 -2.542 42.659 1.00 89.07 C
+ATOM 2854 CA GLN B 68 12.336 0.632 44.010 1.00 88.41 C
+ATOM 2863 CA ILE B 69 9.483 2.828 42.742 1.00 86.11 C
+ATOM 2871 CA ALA B 70 7.060 0.441 44.446 1.00 81.10 C
+ATOM 2876 CA ASP B 71 8.985 -0.310 47.648 1.00 76.82 C
+ATOM 2884 CA GLY B 72 8.653 3.423 48.186 1.00 73.00 C
+ATOM 2888 CA TRP B 73 12.342 4.386 48.095 1.00 67.93 C
+ATOM 2902 CA VAL B 74 13.052 8.007 47.136 1.00 63.84 C
+ATOM 2909 CA LEU B 75 16.093 9.940 45.892 1.00 58.37 C
+ATOM 2917 CA THR B 76 15.524 13.198 47.826 1.00 55.82 C
+ATOM 2924 CA CYS B 77 17.941 15.109 45.556 1.00 58.23 C
+ATOM 2930 CA HIS B 78 15.777 14.389 42.513 1.00 64.55 C
+ATOM 2940 CA ALA B 79 12.108 14.429 43.512 1.00 68.40 C
+ATOM 2945 CA TYR B 80 9.442 17.152 43.581 1.00 69.69 C
+ATOM 2957 CA PRO B 81 6.414 16.584 45.842 1.00 71.39 C
+ATOM 2964 CA THR B 82 3.015 16.014 44.179 1.00 73.67 C
+ATOM 2971 CA SER B 83 1.278 15.771 47.557 1.00 76.90 C
+ATOM 2977 CA ASP B 84 1.940 16.119 51.289 1.00 75.20 C
+ATOM 2985 CA VAL B 85 4.840 13.765 52.050 1.00 71.37 C
+ATOM 2992 CA VAL B 86 6.363 11.824 54.956 1.00 70.12 C
+ATOM 2999 CA ILE B 87 9.770 10.300 54.188 1.00 74.18 C
+ATOM 3007 CA GLU B 88 12.211 8.403 56.410 1.00 78.53 C
+ATOM 3012 CA THR B 89 15.541 9.964 55.407 1.00 79.79 C
+ATOM 3019 CA HIS B 90 19.062 8.538 55.881 1.00 79.40 C
+ATOM 3029 CA LYS B 91 17.584 5.099 55.099 1.00 84.52 C
+ATOM 3038 CA GLU B 92 20.016 2.596 53.549 1.00 91.64 C
+ATOM 3047 CA GLU B 93 20.192 -0.858 51.981 1.00 98.97 C
+ATOM 3056 CA GLU B 94 23.321 -2.924 51.298 1.00106.32 C
+ATOM 3065 CA LEU B 95 22.104 -6.552 51.453 1.00111.32 C
+ATOM 3073 CA THR B 96 18.778 -8.417 51.866 1.00116.01 C
+ATOM 3080 CA GLY B 97 18.877 -11.302 49.394 1.00116.63 C
+ATOM 3084 CA ALA B 98 22.056 -9.833 47.910 1.00116.02 C
+ATOM 3091 CA GLU C 19 26.080 -2.480 15.294 1.00 73.96 C
+ATOM 3100 CA SER C 20 23.405 0.198 14.956 1.00 67.27 C
+ATOM 3106 CA LYS C 21 22.937 3.927 15.380 1.00 59.27 C
+ATOM 3115 CA LYS C 22 19.198 3.481 15.874 1.00 58.42 C
+ATOM 3124 CA GLN C 23 17.251 3.141 19.137 1.00 59.89 C
+ATOM 3133 CA GLU C 24 17.931 -0.276 20.610 1.00 62.66 C
+ATOM 3142 CA GLU C 25 16.850 -0.453 24.226 1.00 64.27 C
+ATOM 3151 CA GLY C 26 13.211 -0.817 25.116 1.00 61.78 C
+ATOM 3155 CA VAL C 27 12.703 -2.073 21.582 1.00 58.37 C
+ATOM 3162 CA VAL C 28 10.779 -5.347 21.485 1.00 54.17 C
+ATOM 3169 CA THR C 29 9.481 -7.339 18.549 1.00 52.79 C
+ATOM 3176 CA ASN C 30 6.670 -9.775 17.786 1.00 51.30 C
+ATOM 3184 CA LEU C 31 4.863 -9.997 21.112 1.00 51.05 C
+ATOM 3192 CA TYR C 32 1.766 -11.297 19.327 1.00 50.51 C
+ATOM 3204 CA LYS C 33 1.373 -13.532 16.266 1.00 49.49 C
+ATOM 3213 CA PRO C 34 -1.609 -14.150 13.925 1.00 50.98 C
+ATOM 3220 CA LYS C 35 -2.450 -17.248 16.011 1.00 55.46 C
+ATOM 3229 CA GLU C 36 -2.977 -15.400 19.288 1.00 53.79 C
+ATOM 3238 CA PRO C 37 -3.251 -11.638 18.607 1.00 49.32 C
+ATOM 3245 CA TYR C 38 -3.674 -9.050 21.318 1.00 46.76 C
+ATOM 3257 CA VAL C 39 -7.276 -7.947 21.418 1.00 43.68 C
+ATOM 3264 CA GLY C 40 -7.415 -4.194 21.922 1.00 41.62 C
+ATOM 3268 CA ARG C 41 -10.273 -1.719 21.954 1.00 40.07 C
+ATOM 3279 CA CYS C 42 -11.026 1.064 19.477 1.00 36.37 C
+ATOM 3285 CA LEU C 43 -11.330 4.206 21.583 1.00 31.09 C
+ATOM 3293 CA LEU C 44 -11.337 6.671 18.673 1.00 28.46 C
+ATOM 3301 CA ASN C 45 -11.792 6.653 14.923 1.00 26.74 C
+ATOM 3309 CA THR C 46 -11.954 9.920 13.013 1.00 25.29 C
+ATOM 3316 CA LYS C 47 -11.667 10.775 9.352 1.00 21.50 C
+ATOM 3325 CA ILE C 48 -8.895 13.355 9.121 1.00 19.33 C
+ATOM 3333 CA THR C 49 -9.125 14.281 5.442 1.00 20.38 C
+ATOM 3340 CA GLY C 50 -11.630 16.676 3.855 1.00 20.12 C
+ATOM 3344 CA ASP C 51 -14.895 15.345 2.412 1.00 21.75 C
+ATOM 3352 CA ASP C 52 -13.889 16.693 -0.999 1.00 21.19 C
+ATOM 3360 CA ALA C 53 -10.651 14.683 -0.749 1.00 21.06 C
+ATOM 3365 CA PRO C 54 -10.036 11.974 -3.413 1.00 21.39 C
+ATOM 3372 CA GLY C 55 -9.982 9.067 -0.977 1.00 24.42 C
+ATOM 3376 CA GLU C 56 -10.374 9.298 2.857 1.00 22.08 C
+ATOM 3385 CA THR C 57 -7.723 8.611 5.517 1.00 20.31 C
+ATOM 3392 CA TRP C 58 -8.541 7.849 9.162 1.00 19.33 C
+ATOM 3406 CA HIS C 59 -6.758 8.520 12.438 1.00 22.68 C
+ATOM 3416 CA MET C 60 -7.645 5.951 15.108 1.00 27.16 C
+ATOM 3424 CA VAL C 61 -6.672 5.224 18.723 1.00 29.32 C
+ATOM 3431 CA PHE C 62 -6.669 1.704 20.220 1.00 34.23 C
+ATOM 3442 CA SER C 63 -6.102 0.643 23.847 1.00 37.05 C
+ATOM 3448 CA THR C 64 -3.096 -1.517 24.798 1.00 41.86 C
+ATOM 3455 CA GLU C 65 -3.169 -1.652 28.621 1.00 48.33 C
+ATOM 3464 CA GLY C 66 0.537 -0.885 28.318 1.00 52.45 C
+ATOM 3468 CA LYS C 67 0.955 -4.385 26.891 1.00 54.14 C
+ATOM 3477 CA ILE C 68 2.429 -3.211 23.570 1.00 51.52 C
+ATOM 3485 CA PRO C 69 5.602 -1.279 24.487 1.00 49.85 C
+ATOM 3492 CA TYR C 70 6.523 -0.180 20.967 1.00 44.48 C
+ATOM 3504 CA ARG C 71 9.185 2.353 19.993 1.00 40.96 C
+ATOM 3515 CA GLU C 72 8.727 5.317 17.688 1.00 33.49 C
+ATOM 3524 CA GLY C 73 8.913 3.876 14.164 1.00 30.16 C
+ATOM 3528 CA GLN C 74 7.423 0.399 14.427 1.00 31.26 C
+ATOM 3537 CA SER C 75 4.187 -0.913 12.966 1.00 33.65 C
+ATOM 3543 CA ILE C 76 1.454 -3.212 14.278 1.00 33.75 C
+ATOM 3551 CA GLY C 77 -0.295 -5.923 12.356 1.00 34.32 C
+ATOM 3555 CA VAL C 78 -4.060 -6.111 12.164 1.00 36.67 C
+ATOM 3562 CA ILE C 79 -6.137 -9.230 11.507 1.00 41.91 C
+ATOM 3570 CA ALA C 80 -9.427 -8.086 10.024 1.00 44.06 C
+ATOM 3575 CA ASP C 81 -12.530 -9.927 11.224 1.00 47.03 C
+ATOM 3583 CA GLY C 82 -13.972 -12.487 8.829 1.00 53.52 C
+ATOM 3587 CA VAL C 83 -12.521 -14.951 6.324 1.00 62.57 C
+ATOM 3594 CA ASP C 84 -11.856 -14.200 2.630 1.00 71.97 C
+ATOM 3602 CA LYS C 85 -12.935 -17.403 0.861 1.00 76.86 C
+ATOM 3611 CA ASN C 86 -13.690 -18.960 4.253 1.00 76.52 C
+ATOM 3619 CA GLY C 87 -10.006 -19.837 4.066 1.00 76.22 C
+ATOM 3623 CA LYS C 88 -8.802 -19.138 7.616 1.00 71.60 C
+ATOM 3632 CA PRO C 89 -8.651 -15.577 8.944 1.00 64.14 C
+ATOM 3639 CA HIS C 90 -7.547 -12.649 6.805 1.00 52.35 C
+ATOM 3649 CA LYS C 91 -3.753 -12.529 6.474 1.00 46.81 C
+ATOM 3658 CA VAL C 92 -2.180 -9.868 8.686 1.00 43.48 C
+ATOM 3665 CA ARG C 93 -1.491 -6.414 7.232 1.00 36.99 C
+ATOM 3676 CA LEU C 94 0.983 -3.882 8.601 1.00 32.95 C
+ATOM 3684 CA TYR C 95 0.340 -0.239 9.510 1.00 24.84 C
+ATOM 3696 CA SER C 96 3.003 2.101 10.803 1.00 23.32 C
+ATOM 3702 CA ILE C 97 2.244 3.502 14.236 1.00 24.12 C
+ATOM 3710 CA ALA C 98 1.243 7.179 13.932 1.00 22.32 C
+ATOM 3715 CA SER C 99 1.572 7.636 17.676 1.00 25.69 C
+ATOM 3721 CA SER C 100 4.752 7.924 19.726 1.00 28.83 C
+ATOM 3727 CA ALA C 101 5.741 5.521 22.508 1.00 35.61 C
+ATOM 3732 CA ILE C 102 3.906 7.635 25.079 1.00 38.39 C
+ATOM 3740 CA GLY C 103 0.899 7.826 22.742 1.00 31.93 C
+ATOM 3744 CA ASP C 104 -1.803 10.384 21.986 1.00 28.77 C
+ATOM 3752 CA PHE C 105 -3.050 10.293 25.607 1.00 37.05 C
+ATOM 3763 CA GLY C 106 0.503 10.389 26.967 1.00 39.36 C
+ATOM 3767 CA ASP C 107 -0.221 7.437 29.266 1.00 41.44 C
+ATOM 3775 CA SER C 108 1.566 4.766 27.217 1.00 42.18 C
+ATOM 3781 CA LYS C 109 -1.747 2.877 27.156 1.00 42.45 C
+ATOM 3790 CA THR C 110 -2.698 3.586 23.515 1.00 38.10 C
+ATOM 3797 CA VAL C 111 -1.603 2.971 19.906 1.00 32.79 C
+ATOM 3804 CA SER C 112 -2.671 5.020 16.872 1.00 29.60 C
+ATOM 3810 CA LEU C 113 -2.713 4.324 13.126 1.00 25.68 C
+ATOM 3818 CA CYS C 114 -3.142 6.498 9.999 1.00 24.23 C
+ATOM 3824 CA VAL C 115 -5.345 4.496 7.641 1.00 22.80 C
+ATOM 3831 CA LYS C 116 -6.221 5.196 4.015 1.00 22.11 C
+ATOM 3840 CA ARG C 117 -9.458 3.521 2.955 1.00 25.68 C
+ATOM 3851 CA LEU C 118 -8.447 1.440 -0.100 1.00 28.80 C
+ATOM 3859 CA ILE C 119 -11.140 1.661 -2.792 1.00 31.75 C
+ATOM 3867 CA TYR C 120 -10.086 0.716 -6.312 1.00 32.93 C
+ATOM 3879 CA THR C 121 -11.388 -0.733 -9.598 1.00 36.84 C
+ATOM 3886 CA ASN C 122 -10.258 -4.257 -10.546 1.00 36.90 C
+ATOM 3894 CA ASP C 123 -9.574 -5.562 -14.056 1.00 45.45 C
+ATOM 3902 CA ALA C 124 -13.196 -6.758 -14.269 1.00 44.66 C
+ATOM 3907 CA GLY C 125 -14.207 -3.102 -14.023 1.00 45.49 C
+ATOM 3911 CA GLU C 126 -16.059 -3.511 -10.722 1.00 45.54 C
+ATOM 3920 CA ILE C 127 -15.507 -1.321 -7.638 1.00 39.70 C
+ATOM 3928 CA VAL C 128 -13.846 -3.171 -4.762 1.00 38.09 C
+ATOM 3935 CA LYS C 129 -12.759 -2.512 -1.198 1.00 33.77 C
+ATOM 3944 CA GLY C 130 -9.566 -3.363 0.599 1.00 31.98 C
+ATOM 3948 CA VAL C 131 -10.443 -5.797 3.385 1.00 33.16 C
+ATOM 3955 CA CYS C 132 -8.241 -4.645 6.257 1.00 29.97 C
+ATOM 3961 CA SER C 133 -8.238 -0.898 5.607 1.00 30.67 C
+ATOM 3967 CA ASN C 134 -12.022 -0.902 5.268 1.00 30.35 C
+ATOM 3975 CA PHE C 135 -12.375 -2.946 8.424 1.00 29.86 C
+ATOM 3986 CA LEU C 136 -10.223 -0.334 10.195 1.00 29.42 C
+ATOM 3994 CA CYS C 137 -11.779 2.834 8.813 1.00 32.27 C
+ATOM 4000 CA ASP C 138 -15.116 1.280 9.724 1.00 34.29 C
+ATOM 4008 CA LEU C 139 -14.287 0.699 13.399 1.00 37.51 C
+ATOM 4016 CA GLN C 140 -16.635 2.170 16.028 1.00 43.76 C
+ATOM 4025 CA PRO C 141 -15.630 3.032 19.581 1.00 42.77 C
+ATOM 4032 CA GLY C 142 -16.082 -0.210 21.478 1.00 42.83 C
+ATOM 4036 CA ASP C 143 -15.117 -2.625 18.696 1.00 40.91 C
+ATOM 4044 CA ASN C 144 -12.182 -4.947 19.288 1.00 45.66 C
+ATOM 4052 CA VAL C 145 -9.056 -5.146 17.145 1.00 46.95 C
+ATOM 4059 CA GLN C 146 -6.707 -8.107 16.606 1.00 48.69 C
+ATOM 4068 CA ILE C 147 -3.249 -6.538 17.123 1.00 46.84 C
+ATOM 4076 CA THR C 148 -0.010 -8.392 16.264 1.00 46.26 C
+ATOM 4083 CA GLY C 149 3.543 -7.117 16.634 1.00 45.60 C
+ATOM 4087 CA PRO C 150 5.248 -4.818 17.394 1.00 44.97 C
+ATOM 4094 CA VAL C 151 7.423 -5.293 14.321 1.00 44.50 C
+ATOM 4101 CA GLY C 152 10.289 -3.716 12.438 1.00 45.33 C
+ATOM 4105 CA LYS C 153 13.599 -2.161 13.435 1.00 48.64 C
+ATOM 4114 CA GLU C 154 14.166 -0.437 10.074 1.00 48.20 C
+ATOM 4123 CA MET C 155 12.437 2.888 10.737 1.00 41.77 C
+ATOM 4131 CA LEU C 156 13.839 3.081 14.267 1.00 38.27 C
+ATOM 4139 CA MET C 157 15.076 6.540 15.308 1.00 34.29 C
+ATOM 4147 CA PRO C 158 18.782 7.419 15.339 1.00 34.05 C
+ATOM 4154 CA LYS C 159 20.262 7.521 18.845 1.00 35.82 C
+ATOM 4163 CA ASP C 160 22.076 10.792 18.273 1.00 35.95 C
+ATOM 4171 CA PRO C 161 19.683 13.401 19.809 1.00 35.63 C
+ATOM 4178 CA ASN C 162 21.563 15.948 17.758 1.00 33.92 C
+ATOM 4186 CA ALA C 163 21.028 14.172 14.487 1.00 30.82 C
+ATOM 4191 CA THR C 164 19.693 15.722 11.305 1.00 25.18 C
+ATOM 4198 CA ILE C 165 16.617 13.601 10.636 1.00 19.91 C
+ATOM 4206 CA ILE C 166 15.351 13.978 7.060 1.00 13.76 C
+ATOM 4214 CA MET C 167 11.843 12.550 6.703 1.00 14.98 C
+ATOM 4222 CA LEU C 168 10.385 11.831 3.251 1.00 16.64 C
+ATOM 4230 CA ALA C 169 6.747 10.808 3.007 1.00 15.85 C
+ATOM 4235 CA THR C 170 3.765 10.346 0.737 1.00 14.23 C
+ATOM 4242 CA GLY C 171 0.255 9.724 2.035 1.00 13.78 C
+ATOM 4246 CA THR C 172 -0.103 7.560 5.139 1.00 17.62 C
+ATOM 4253 CA GLY C 173 3.646 7.343 4.821 1.00 17.20 C
+ATOM 4257 CA ILE C 174 3.469 10.213 7.270 1.00 15.91 C
+ATOM 4265 CA ALA C 175 2.586 7.783 10.110 1.00 15.63 C
+ATOM 4270 CA PRO C 176 6.023 6.933 11.582 1.00 17.04 C
+ATOM 4277 CA PHE C 177 7.215 10.514 11.327 1.00 18.21 C
+ATOM 4288 CA ARG C 178 4.268 11.745 13.359 1.00 22.35 C
+ATOM 4299 CA SER C 179 5.563 9.289 15.983 1.00 25.22 C
+ATOM 4305 CA PHE C 180 9.139 10.593 15.614 1.00 25.98 C
+ATOM 4316 CA LEU C 181 7.925 14.180 15.767 1.00 29.12 C
+ATOM 4324 CA TRP C 182 5.625 13.641 18.714 1.00 31.35 C
+ATOM 4338 CA LYS C 183 8.488 12.385 20.871 1.00 30.92 C
+ATOM 4347 CA MET C 184 10.841 15.050 19.503 1.00 24.85 C
+ATOM 4355 CA PHE C 185 8.741 18.202 20.114 1.00 22.97 C
+ATOM 4366 CA PHE C 186 5.604 17.337 22.076 1.00 27.77 C
+ATOM 4377 CA GLU C 187 7.117 15.432 25.009 1.00 37.71 C
+ATOM 4386 CA LYS C 188 9.542 15.977 27.878 1.00 53.59 C
+ATOM 4395 CA HIS C 189 12.355 13.416 28.180 1.00 63.67 C
+ATOM 4405 CA ASP C 190 15.318 13.181 30.569 1.00 66.93 C
+ATOM 4413 CA ASP C 191 17.480 11.106 28.238 1.00 59.79 C
+ATOM 4421 CA TYR C 192 16.190 12.725 25.047 1.00 51.96 C
+ATOM 4433 CA LYS C 193 16.700 16.406 24.324 1.00 47.01 C
+ATOM 4442 CA PHE C 194 16.580 16.471 20.530 1.00 39.85 C
+ATOM 4453 CA ASN C 195 18.572 19.494 19.409 1.00 37.52 C
+ATOM 4461 CA GLY C 196 19.361 18.548 15.845 1.00 32.08 C
+ATOM 4465 CA LEU C 197 17.310 19.266 12.766 1.00 28.26 C
+ATOM 4473 CA GLY C 198 14.051 17.526 11.928 1.00 25.05 C
+ATOM 4477 CA TRP C 199 13.211 18.137 8.269 1.00 19.81 C
+ATOM 4491 CA LEU C 200 9.908 16.742 7.059 1.00 13.86 C
+ATOM 4499 CA PHE C 201 8.855 16.521 3.429 1.00 14.83 C
+ATOM 4510 CA LEU C 202 5.288 15.361 2.717 1.00 16.12 C
+ATOM 4518 CA GLY C 203 3.701 14.731 -0.681 1.00 13.79 C
+ATOM 4522 CA VAL C 204 -0.051 14.414 -1.182 1.00 11.75 C
+ATOM 4529 CA PRO C 205 -2.113 15.264 -4.308 1.00 14.66 C
+ATOM 4536 CA THR C 206 -4.553 17.737 -2.778 1.00 16.37 C
+ATOM 4543 CA SER C 207 -4.756 20.169 0.120 1.00 18.01 C
+ATOM 4549 CA SER C 208 -7.780 18.225 1.280 1.00 17.59 C
+ATOM 4555 CA SER C 209 -5.452 15.198 1.550 1.00 16.19 C
+ATOM 4561 CA LEU C 210 -2.972 16.940 3.860 1.00 14.22 C
+ATOM 4569 CA LEU C 211 -2.255 14.980 7.059 1.00 14.43 C
+ATOM 4577 CA TYR C 212 -1.624 16.449 10.549 1.00 18.94 C
+ATOM 4589 CA LYS C 213 -0.818 19.896 9.150 1.00 22.61 C
+ATOM 4598 CA GLU C 214 -2.039 21.572 12.352 1.00 25.73 C
+ATOM 4607 CA GLU C 215 0.152 19.413 14.514 1.00 19.23 C
+ATOM 4616 CA PHE C 216 3.216 20.178 12.439 1.00 17.80 C
+ATOM 4627 CA GLY C 217 2.478 23.890 12.512 1.00 19.90 C
+ATOM 4631 CA LYS C 218 2.578 24.001 16.294 1.00 25.54 C
+ATOM 4640 CA MET C 219 5.810 22.021 16.188 1.00 26.79 C
+ATOM 4648 CA LYS C 220 7.224 24.606 13.819 1.00 31.85 C
+ATOM 4657 CA GLU C 221 6.071 27.341 16.219 1.00 38.62 C
+ATOM 4666 CA ARG C 222 7.760 25.760 19.233 1.00 39.10 C
+ATOM 4677 CA ALA C 223 11.124 24.971 17.668 1.00 35.43 C
+ATOM 4682 CA PRO C 224 11.696 27.100 14.528 1.00 32.99 C
+ATOM 4689 CA GLU C 225 15.425 26.331 14.360 1.00 33.87 C
+ATOM 4698 CA ASN C 226 15.038 22.591 14.986 1.00 30.46 C
+ATOM 4706 CA PHE C 227 12.088 21.755 12.732 1.00 24.98 C
+ATOM 4717 CA ARG C 228 11.351 22.384 9.075 1.00 19.87 C
+ATOM 4728 CA VAL C 229 8.435 21.010 7.118 1.00 14.21 C
+ATOM 4735 CA ASP C 230 7.739 21.452 3.398 1.00 12.26 C
+ATOM 4743 CA TYR C 231 4.627 20.147 1.722 1.00 14.42 C
+ATOM 4755 CA ALA C 232 4.334 19.003 -1.872 1.00 9.99 C
+ATOM 4760 CA VAL C 233 0.778 19.232 -3.168 1.00 10.49 C
+ATOM 4767 CA SER C 234 1.043 17.769 -6.694 1.00 19.00 C
+ATOM 4773 CA ARG C 235 -2.240 19.042 -8.206 1.00 23.13 C
+ATOM 4784 CA GLU C 236 -2.069 22.459 -6.578 1.00 17.58 C
+ATOM 4793 CA GLN C 237 1.546 23.511 -6.623 1.00 15.89 C
+ATOM 4802 CA THR C 238 4.202 24.018 -9.275 1.00 17.86 C
+ATOM 4809 CA ASN C 239 7.922 24.800 -9.182 1.00 15.15 C
+ATOM 4817 CA ALA C 240 9.558 27.791 -10.892 1.00 21.51 C
+ATOM 4822 CA ALA C 241 9.475 25.887 -14.174 1.00 24.05 C
+ATOM 4827 CA GLY C 242 5.741 25.110 -13.938 1.00 26.25 C
+ATOM 4831 CA GLU C 243 5.999 21.359 -13.153 1.00 25.92 C
+ATOM 4840 CA ARG C 244 3.679 19.536 -10.704 1.00 24.04 C
+ATOM 4851 CA MET C 245 5.076 19.643 -7.174 1.00 18.58 C
+ATOM 4859 CA TYR C 246 5.784 16.047 -6.100 1.00 14.16 C
+ATOM 4871 CA ILE C 247 7.910 15.343 -3.034 1.00 16.78 C
+ATOM 4879 CA GLN C 248 11.089 15.070 -5.120 1.00 18.72 C
+ATOM 4888 CA THR C 249 10.168 18.255 -6.921 1.00 20.93 C
+ATOM 4895 CA ARG C 250 9.962 20.031 -3.567 1.00 19.25 C
+ATOM 4906 CA MET C 251 13.275 18.471 -2.561 1.00 19.40 C
+ATOM 4914 CA ALA C 252 14.910 19.812 -5.760 1.00 20.48 C
+ATOM 4919 CA GLU C 253 14.456 23.418 -4.569 1.00 18.19 C
+ATOM 4928 CA TYR C 254 16.804 22.515 -1.673 1.00 17.80 C
+ATOM 4940 CA LYS C 255 19.038 20.415 -3.902 1.00 20.66 C
+ATOM 4949 CA GLU C 256 22.452 21.603 -2.682 1.00 16.05 C
+ATOM 4958 CA GLU C 257 21.544 21.914 0.993 1.00 15.89 C
+ATOM 4967 CA LEU C 258 20.377 18.297 0.919 1.00 20.74 C
+ATOM 4975 CA TRP C 259 23.388 16.939 -0.965 1.00 23.45 C
+ATOM 4989 CA GLU C 260 25.645 18.669 1.563 1.00 24.08 C
+ATOM 4998 CA LEU C 261 23.573 17.378 4.477 1.00 24.74 C
+ATOM 5006 CA LEU C 262 24.020 13.928 2.938 1.00 26.14 C
+ATOM 5014 CA LYS C 263 27.792 14.091 3.402 1.00 25.40 C
+ATOM 5023 CA LYS C 264 27.457 14.521 7.176 1.00 31.47 C
+ATOM 5032 CA ASP C 265 27.877 11.474 9.425 1.00 35.31 C
+ATOM 5040 CA ASN C 266 24.934 12.482 11.620 1.00 29.63 C
+ATOM 5048 CA THR C 267 22.321 12.795 8.832 1.00 28.00 C
+ATOM 5055 CA TYR C 268 19.556 10.160 8.808 1.00 27.00 C
+ATOM 5067 CA VAL C 269 17.143 9.903 5.884 1.00 24.65 C
+ATOM 5074 CA TYR C 270 13.890 8.016 6.276 1.00 23.37 C
+ATOM 5086 CA MET C 271 11.373 7.327 3.518 1.00 18.93 C
+ATOM 5094 CA CYS C 272 7.834 6.074 4.043 1.00 18.24 C
+ATOM 5100 CA GLY C 273 4.784 5.874 1.826 1.00 22.39 C
+ATOM 5104 CA LEU C 274 3.837 4.483 -1.568 1.00 26.95 C
+ATOM 5112 CA LYS C 275 6.305 2.384 -3.532 1.00 32.36 C
+ATOM 5121 CA GLY C 276 7.741 4.199 -6.514 1.00 37.46 C
+ATOM 5125 CA MET C 277 7.714 7.455 -4.608 1.00 28.76 C
+ATOM 5133 CA GLU C 278 11.430 6.639 -4.425 1.00 32.22 C
+ATOM 5142 CA LYS C 279 12.017 6.321 -8.153 1.00 29.94 C
+ATOM 5151 CA GLY C 280 11.317 10.057 -8.293 1.00 24.18 C
+ATOM 5155 CA ILE C 281 13.766 10.673 -5.460 1.00 23.68 C
+ATOM 5163 CA ASP C 282 16.431 8.365 -6.934 1.00 26.58 C
+ATOM 5171 CA ASP C 283 16.211 10.530 -10.054 1.00 28.70 C
+ATOM 5179 CA ILE C 284 17.089 13.937 -8.538 1.00 27.28 C
+ATOM 5187 CA MET C 285 19.706 12.222 -6.388 1.00 27.45 C
+ATOM 5195 CA VAL C 286 21.377 10.712 -9.470 1.00 30.74 C
+ATOM 5202 CA SER C 287 21.619 14.159 -11.061 1.00 32.14 C
+ATOM 5208 CA LEU C 288 23.240 15.463 -7.873 1.00 34.20 C
+ATOM 5216 CA ALA C 289 25.801 12.653 -7.874 1.00 40.16 C
+ATOM 5221 CA GLU C 290 26.837 12.825 -11.536 1.00 41.84 C
+ATOM 5230 CA LYS C 291 27.855 16.387 -10.793 1.00 43.17 C
+ATOM 5239 CA ASP C 292 30.299 15.115 -8.139 1.00 41.84 C
+ATOM 5247 CA GLY C 293 31.237 12.232 -10.420 1.00 46.12 C
+ATOM 5251 CA ILE C 294 30.053 9.669 -7.864 1.00 45.54 C
+ATOM 5259 CA ASP C 295 27.399 6.998 -8.480 1.00 41.14 C
+ATOM 5267 CA TRP C 296 24.222 7.605 -6.479 1.00 30.67 C
+ATOM 5281 CA PHE C 297 23.381 3.910 -6.151 1.00 31.97 C
+ATOM 5292 CA ASP C 298 26.856 2.916 -4.907 1.00 38.12 C
+ATOM 5300 CA TYR C 299 26.671 5.875 -2.540 1.00 39.05 C
+ATOM 5312 CA LYS C 300 23.196 4.971 -1.294 1.00 41.63 C
+ATOM 5321 CA LYS C 301 24.542 1.489 -0.577 1.00 43.40 C
+ATOM 5330 CA GLN C 302 27.207 3.064 1.608 1.00 43.79 C
+ATOM 5339 CA LEU C 303 24.476 5.181 3.238 1.00 41.51 C
+ATOM 5347 CA LYS C 304 22.138 2.343 4.264 1.00 45.18 C
+ATOM 5356 CA ARG C 305 25.322 0.535 5.256 1.00 46.65 C
+ATOM 5367 CA GLY C 306 25.613 3.181 7.945 1.00 40.29 C
+ATOM 5371 CA ASP C 307 21.954 3.487 8.940 1.00 41.21 C
+ATOM 5379 CA GLN C 308 21.463 6.730 7.023 1.00 35.55 C
+ATOM 5388 CA TRP C 309 18.961 5.674 4.361 1.00 31.22 C
+ATOM 5402 CA ASN C 310 16.018 3.728 5.752 1.00 31.61 C
+ATOM 5410 CA VAL C 311 13.120 2.841 3.452 1.00 32.13 C
+ATOM 5417 CA GLU C 312 9.705 1.332 4.261 1.00 31.51 C
+ATOM 5426 CA VAL C 313 7.466 1.606 1.209 1.00 26.39 C
+ATOM 5433 CA TYR C 314 4.403 -0.343 0.111 1.00 25.42 C
--- /dev/null
+HEADER ELECTRON TRANSPORT 06-FEB-13 3W5V
+TITLE CROSS-LINKED COMPLEX BETWEEN FERREDOXIN AND FERREDOXIN-NADP+ REDUCTASE
+COMPND MOL_ID: 1;
+COMPND 2 MOLECULE: FERREDOXIN;
+COMPND 3 CHAIN: A, C;
+COMPND 4 FRAGMENT: UNP RESIDUES 42-355;
+COMPND 5 SYNONYM: FERREDOXIN--NADP REDUCTASE, LEAF ISOZYME,
+COMPND 6 FERREDOXINFERREDOXIN--NADP REDUCTASE, LEAF ISOZYME, UNCHARACTERIZED
+COMPND 7 PROTEIN;
+COMPND 8 ENGINEERED: YES;
+COMPND 9 MUTATION: YES;
+COMPND 10 MOL_ID: 2;
+COMPND 11 MOLECULE: FERREDOXIN-1, CHLOROPLASTIC;
+COMPND 12 CHAIN: B, D;
+COMPND 13 FRAGMENT: UNP RESIDUES 53-150;
+COMPND 14 SYNONYM: FERREDOXIN I, FD I;
+COMPND 15 ENGINEERED: YES;
+COMPND 16 MUTATION: YES
+SOURCE MOL_ID: 1;
+SOURCE 2 ORGANISM_SCIENTIFIC: ZEA MAYS;
+SOURCE 3 ORGANISM_COMMON: MAIZE;
+SOURCE 4 ORGANISM_TAXID: 4577;
+SOURCE 5 GENE: L-FNRI, ZEAMMB73_343560;
+SOURCE 6 EXPRESSION_SYSTEM: ESCHERICHIA COLI;
+SOURCE 7 EXPRESSION_SYSTEM_TAXID: 562;
+SOURCE 8 EXPRESSION_SYSTEM_VECTOR_TYPE: PLASMID;
+SOURCE 9 MOL_ID: 2;
+SOURCE 10 ORGANISM_SCIENTIFIC: ZEA MAYS;
+SOURCE 11 ORGANISM_COMMON: MAIZE;
+SOURCE 12 ORGANISM_TAXID: 4577;
+SOURCE 13 GENE: FDX1, PFD1;
+SOURCE 14 EXPRESSION_SYSTEM: ESCHERICHIA COLI;
+SOURCE 15 EXPRESSION_SYSTEM_TAXID: 562;
+SOURCE 16 EXPRESSION_SYSTEM_VECTOR_TYPE: PLASMID
+KEYWDS ELECTRON TRANSFER COMPLEX, ELECTRON TRANSPORT
+EXPDTA X-RAY DIFFRACTION
+AUTHOR Y.KIMATA-ARIGA,H.KUBOTA-KAWAI,N.MURAKI,T.HASE,G.KURISU
+REVDAT 1 19-JUN-13 3W5V 0
+JRNL AUTH Y.KIMATA-ARIGA,H.KUBOTA-KAWAI,Y.-H.LEE,N.MURAKI,T.IKEGAMI,
+JRNL AUTH 2 G.KURISU,T.HASE
+JRNL TITL CONCENTRATION-DEPENDENT OLIGOMERIZATION OF CROSS-LINKED
+JRNL TITL 2 COMPLEXES BETWEEN FERREDOXIN AND FERREDOXIN-NADP(+)
+JRNL TITL 3 REDUCTASE
+JRNL REF BIOCHEM.BIOPHYS.RES.COMMUN. V. 434 867 2013
+JRNL REFN ISSN 0006-291X
+JRNL PMID 23618857
+JRNL DOI 10.1016/J.BBRC.2013.04.033
+REMARK 2
+REMARK 2 RESOLUTION. 3.81 ANGSTROMS.
+REMARK 3
+REMARK 3 REFINEMENT.
+REMARK 3 PROGRAM : REFMAC 5.6.0117
+REMARK 3 AUTHORS : MURSHUDOV,VAGIN,DODSON
+REMARK 3
+REMARK 3 REFINEMENT TARGET : MAXIMUM LIKELIHOOD
+REMARK 3
+REMARK 3 DATA USED IN REFINEMENT.
+REMARK 3 RESOLUTION RANGE HIGH (ANGSTROMS) : 3.81
+REMARK 3 RESOLUTION RANGE LOW (ANGSTROMS) : 35.67
+REMARK 3 DATA CUTOFF (SIGMA(F)) : NULL
+REMARK 3 COMPLETENESS FOR RANGE (%) : 98.3
+REMARK 3 NUMBER OF REFLECTIONS : 13076
+REMARK 3
+REMARK 3 FIT TO DATA USED IN REFINEMENT.
+REMARK 3 CROSS-VALIDATION METHOD : THROUGHOUT
+REMARK 3 FREE R VALUE TEST SET SELECTION : RANDOM
+REMARK 3 R VALUE (WORKING + TEST SET) : 0.279
+REMARK 3 R VALUE (WORKING SET) : 0.277
+REMARK 3 FREE R VALUE : 0.306
+REMARK 3 FREE R VALUE TEST SET SIZE (%) : 5.000
+REMARK 3 FREE R VALUE TEST SET COUNT : 683
+REMARK 3
+REMARK 3 FIT IN THE HIGHEST RESOLUTION BIN.
+REMARK 3 TOTAL NUMBER OF BINS USED : 20
+REMARK 3 BIN RESOLUTION RANGE HIGH (A) : 3.81
+REMARK 3 BIN RESOLUTION RANGE LOW (A) : 3.90
+REMARK 3 REFLECTION IN BIN (WORKING SET) : 878
+REMARK 3 BIN COMPLETENESS (WORKING+TEST) (%) : 93.74
+REMARK 3 BIN R VALUE (WORKING SET) : 0.5870
+REMARK 3 BIN FREE R VALUE SET COUNT : 51
+REMARK 3 BIN FREE R VALUE : 0.6500
+REMARK 3
+REMARK 3 NUMBER OF NON-HYDROGEN ATOMS USED IN REFINEMENT.
+REMARK 3 PROTEIN ATOMS : 6176
+REMARK 3 NUCLEIC ACID ATOMS : 0
+REMARK 3 HETEROGEN ATOMS : 114
+REMARK 3 SOLVENT ATOMS : 0
+REMARK 3
+REMARK 3 B VALUES.
+REMARK 3 FROM WILSON PLOT (A**2) : NULL
+REMARK 3 MEAN B VALUE (OVERALL, A**2) : 39.99
+REMARK 3 OVERALL ANISOTROPIC B VALUE.
+REMARK 3 B11 (A**2) : -0.01000
+REMARK 3 B22 (A**2) : 0.12000
+REMARK 3 B33 (A**2) : -0.07000
+REMARK 3 B12 (A**2) : -0.00000
+REMARK 3 B13 (A**2) : 0.07000
+REMARK 3 B23 (A**2) : -0.00000
+REMARK 3
+REMARK 3 ESTIMATED OVERALL COORDINATE ERROR.
+REMARK 3 ESU BASED ON R VALUE (A): NULL
+REMARK 3 ESU BASED ON FREE R VALUE (A): 0.827
+REMARK 3 ESU BASED ON MAXIMUM LIKELIHOOD (A): 0.920
+REMARK 3 ESU FOR B VALUES BASED ON MAXIMUM LIKELIHOOD (A**2): 73.326
+REMARK 3
+REMARK 3 CORRELATION COEFFICIENTS.
+REMARK 3 CORRELATION COEFFICIENT FO-FC : 0.949
+REMARK 3 CORRELATION COEFFICIENT FO-FC FREE : 0.942
+REMARK 3
+REMARK 3 RMS DEVIATIONS FROM IDEAL VALUES COUNT RMS WEIGHT
+REMARK 3 BOND LENGTHS REFINED ATOMS (A): 6430 ; 0.010 ; 0.020
+REMARK 3 BOND LENGTHS OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 BOND ANGLES REFINED ATOMS (DEGREES): 8708 ; 1.361 ; 1.989
+REMARK 3 BOND ANGLES OTHERS (DEGREES): NULL ; NULL ; NULL
+REMARK 3 TORSION ANGLES, PERIOD 1 (DEGREES): 782 ; 6.280 ; 5.000
+REMARK 3 TORSION ANGLES, PERIOD 2 (DEGREES): 286 ;37.739 ;25.315
+REMARK 3 TORSION ANGLES, PERIOD 3 (DEGREES): 1124 ;17.100 ;15.000
+REMARK 3 TORSION ANGLES, PERIOD 4 (DEGREES): 24 ;13.428 ;15.000
+REMARK 3 CHIRAL-CENTER RESTRAINTS (A**3): 932 ; 0.084 ; 0.200
+REMARK 3 GENERAL PLANES REFINED ATOMS (A): 4820 ; 0.005 ; 0.021
+REMARK 3 GENERAL PLANES OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 NON-BONDED CONTACTS REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 NON-BONDED CONTACTS OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 NON-BONDED TORSION REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 NON-BONDED TORSION OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 H-BOND (X...Y) REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 H-BOND (X...Y) OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 POTENTIAL METAL-ION REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 POTENTIAL METAL-ION OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY VDW REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY VDW OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY H-BOND REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY H-BOND OTHERS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY METAL-ION REFINED ATOMS (A): NULL ; NULL ; NULL
+REMARK 3 SYMMETRY METAL-ION OTHERS (A): NULL ; NULL ; NULL
+REMARK 3
+REMARK 3 ISOTROPIC THERMAL FACTOR RESTRAINTS. COUNT RMS WEIGHT
+REMARK 3 MAIN-CHAIN BOND REFINED ATOMS (A**2): NULL ; NULL ; NULL
+REMARK 3 MAIN-CHAIN BOND OTHER ATOMS (A**2): NULL ; NULL ; NULL
+REMARK 3 MAIN-CHAIN ANGLE REFINED ATOMS (A**2): NULL ; NULL ; NULL
+REMARK 3 SIDE-CHAIN BOND REFINED ATOMS (A**2): NULL ; NULL ; NULL
+REMARK 3 SIDE-CHAIN ANGLE REFINED ATOMS (A**2): NULL ; NULL ; NULL
+REMARK 3
+REMARK 3 ANISOTROPIC THERMAL FACTOR RESTRAINTS. COUNT RMS WEIGHT
+REMARK 3 RIGID-BOND RESTRAINTS (A**2): NULL ; NULL ; NULL
+REMARK 3 SPHERICITY; FREE ATOMS (A**2): NULL ; NULL ; NULL
+REMARK 3 SPHERICITY; BONDED ATOMS (A**2): NULL ; NULL ; NULL
+REMARK 3
+REMARK 3 NCS RESTRAINTS STATISTICS
+REMARK 3 NUMBER OF DIFFERENT NCS GROUPS : NULL
+REMARK 3
+REMARK 3 TLS DETAILS
+REMARK 3 NUMBER OF TLS GROUPS : NULL
+REMARK 3
+REMARK 3 BULK SOLVENT MODELLING.
+REMARK 3 METHOD USED : MASK
+REMARK 3 PARAMETERS FOR MASK CALCULATION
+REMARK 3 VDW PROBE RADIUS : 1.20
+REMARK 3 ION PROBE RADIUS : 0.80
+REMARK 3 SHRINKAGE RADIUS : 0.80
+REMARK 3
+REMARK 3 OTHER REFINEMENT REMARKS: HYDROGENS HAVE BEEN USED IF PRESENT IN
+REMARK 3 THE INPUT
+REMARK 4
+REMARK 4 3W5V COMPLIES WITH FORMAT V. 3.30, 13-JUL-11
+REMARK 100
+REMARK 100 THIS ENTRY HAS BEEN PROCESSED BY PDBJ ON 15-FEB-13.
+REMARK 100 THE RCSB ID CODE IS RCSB095924.
+REMARK 200
+REMARK 200 EXPERIMENTAL DETAILS
+REMARK 200 EXPERIMENT TYPE : X-RAY DIFFRACTION
+REMARK 200 DATE OF DATA COLLECTION : 24-JUL-11
+REMARK 200 TEMPERATURE (KELVIN) : 100
+REMARK 200 PH : 7.5
+REMARK 200 NUMBER OF CRYSTALS USED : 1
+REMARK 200
+REMARK 200 SYNCHROTRON (Y/N) : Y
+REMARK 200 RADIATION SOURCE : SPRING-8
+REMARK 200 BEAMLINE : BL44XU
+REMARK 200 X-RAY GENERATOR MODEL : NULL
+REMARK 200 MONOCHROMATIC OR LAUE (M/L) : M
+REMARK 200 WAVELENGTH OR RANGE (A) : 0.90000
+REMARK 200 MONOCHROMATOR : NULL
+REMARK 200 OPTICS : NULL
+REMARK 200
+REMARK 200 DETECTOR TYPE : CCD
+REMARK 200 DETECTOR MANUFACTURER : RAYONIX MX225HE
+REMARK 200 INTENSITY-INTEGRATION SOFTWARE : HKL-2000
+REMARK 200 DATA SCALING SOFTWARE : HKL-2000
+REMARK 200
+REMARK 200 NUMBER OF UNIQUE REFLECTIONS : 13803
+REMARK 200 RESOLUTION RANGE HIGH (A) : 3.800
+REMARK 200 RESOLUTION RANGE LOW (A) : 50.000
+REMARK 200 REJECTION CRITERIA (SIGMA(I)) : NULL
+REMARK 200
+REMARK 200 OVERALL.
+REMARK 200 COMPLETENESS FOR RANGE (%) : NULL
+REMARK 200 DATA REDUNDANCY : NULL
+REMARK 200 R MERGE (I) : NULL
+REMARK 200 R SYM (I) : NULL
+REMARK 200 <I/SIGMA(I)> FOR THE DATA SET : NULL
+REMARK 200
+REMARK 200 IN THE HIGHEST RESOLUTION SHELL.
+REMARK 200 HIGHEST RESOLUTION SHELL, RANGE HIGH (A) : NULL
+REMARK 200 HIGHEST RESOLUTION SHELL, RANGE LOW (A) : NULL
+REMARK 200 COMPLETENESS FOR SHELL (%) : NULL
+REMARK 200 DATA REDUNDANCY IN SHELL : NULL
+REMARK 200 R MERGE FOR SHELL (I) : NULL
+REMARK 200 R SYM FOR SHELL (I) : NULL
+REMARK 200 <I/SIGMA(I)> FOR SHELL : NULL
+REMARK 200
+REMARK 200 DIFFRACTION PROTOCOL: SINGLE WAVELENGTH
+REMARK 200 METHOD USED TO DETERMINE THE STRUCTURE: MOLECULAR REPLACEMENT
+REMARK 200 SOFTWARE USED: PHASER
+REMARK 200 STARTING MODEL: 1GAW, 3B2F
+REMARK 200
+REMARK 200 REMARK: NULL
+REMARK 280
+REMARK 280 CRYSTAL
+REMARK 280 SOLVENT CONTENT, VS (%): 68.66
+REMARK 280 MATTHEWS COEFFICIENT, VM (ANGSTROMS**3/DA): 3.92
+REMARK 280
+REMARK 280 CRYSTALLIZATION CONDITIONS: 8% PEG 8000, 20% ETHYLENE GLYCOL,
+REMARK 280 100MM BIS-TRIS, PH 7.5, VAPOR DIFFUSION, HANGING DROP,
+REMARK 280 TEMPERATURE 277K
+REMARK 290
+REMARK 290 CRYSTALLOGRAPHIC SYMMETRY
+REMARK 290 SYMMETRY OPERATORS FOR SPACE GROUP: P 1 21 1
+REMARK 290
+REMARK 290 SYMOP SYMMETRY
+REMARK 290 NNNMMM OPERATOR
+REMARK 290 1555 X,Y,Z
+REMARK 290 2555 -X,Y+1/2,-Z
+REMARK 290
+REMARK 290 WHERE NNN -> OPERATOR NUMBER
+REMARK 290 MMM -> TRANSLATION VECTOR
+REMARK 290
+REMARK 290 CRYSTALLOGRAPHIC SYMMETRY TRANSFORMATIONS
+REMARK 290 THE FOLLOWING TRANSFORMATIONS OPERATE ON THE ATOM/HETATM
+REMARK 290 RECORDS IN THIS ENTRY TO PRODUCE CRYSTALLOGRAPHICALLY
+REMARK 290 RELATED MOLECULES.
+REMARK 290 SMTRY1 1 1.000000 0.000000 0.000000 0.00000
+REMARK 290 SMTRY2 1 0.000000 1.000000 0.000000 0.00000
+REMARK 290 SMTRY3 1 0.000000 0.000000 1.000000 0.00000
+REMARK 290 SMTRY1 2 -1.000000 0.000000 0.000000 0.00000
+REMARK 290 SMTRY2 2 0.000000 1.000000 0.000000 60.17250
+REMARK 290 SMTRY3 2 0.000000 0.000000 -1.000000 0.00000
+REMARK 290
+REMARK 290 REMARK: NULL
+REMARK 300
+REMARK 300 BIOMOLECULE: 1, 2
+REMARK 300 SEE REMARK 350 FOR THE AUTHOR PROVIDED AND/OR PROGRAM
+REMARK 300 GENERATED ASSEMBLY INFORMATION FOR THE STRUCTURE IN
+REMARK 300 THIS ENTRY. THE REMARK MAY ALSO PROVIDE INFORMATION ON
+REMARK 300 BURIED SURFACE AREA.
+REMARK 350
+REMARK 350 COORDINATES FOR A COMPLETE MULTIMER REPRESENTING THE KNOWN
+REMARK 350 BIOLOGICALLY SIGNIFICANT OLIGOMERIZATION STATE OF THE
+REMARK 350 MOLECULE CAN BE GENERATED BY APPLYING BIOMT TRANSFORMATIONS
+REMARK 350 GIVEN BELOW. BOTH NON-CRYSTALLOGRAPHIC AND
+REMARK 350 CRYSTALLOGRAPHIC OPERATIONS ARE GIVEN.
+REMARK 350
+REMARK 350 BIOMOLECULE: 1
+REMARK 350 AUTHOR DETERMINED BIOLOGICAL UNIT: DIMERIC
+REMARK 350 SOFTWARE DETERMINED QUATERNARY STRUCTURE: DIMERIC
+REMARK 350 SOFTWARE USED: PISA
+REMARK 350 TOTAL BURIED SURFACE AREA: 1370 ANGSTROM**2
+REMARK 350 SURFACE AREA OF THE COMPLEX: 19220 ANGSTROM**2
+REMARK 350 CHANGE IN SOLVENT FREE ENERGY: -28.0 KCAL/MOL
+REMARK 350 APPLY THE FOLLOWING TO CHAINS: A, D
+REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.00000
+REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.00000
+REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.00000
+REMARK 350
+REMARK 350 BIOMOLECULE: 2
+REMARK 350 AUTHOR DETERMINED BIOLOGICAL UNIT: DIMERIC
+REMARK 350 SOFTWARE DETERMINED QUATERNARY STRUCTURE: DIMERIC
+REMARK 350 SOFTWARE USED: PISA
+REMARK 350 TOTAL BURIED SURFACE AREA: 1640 ANGSTROM**2
+REMARK 350 SURFACE AREA OF THE COMPLEX: 18950 ANGSTROM**2
+REMARK 350 CHANGE IN SOLVENT FREE ENERGY: -28.0 KCAL/MOL
+REMARK 350 APPLY THE FOLLOWING TO CHAINS: C, B
+REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.00000
+REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.00000
+REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.00000
+REMARK 465
+REMARK 465 MISSING RESIDUES
+REMARK 465 THE FOLLOWING RESIDUES WERE NOT LOCATED IN THE
+REMARK 465 EXPERIMENT. (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN
+REMARK 465 IDENTIFIER; SSSEQ=SEQUENCE NUMBER; I=INSERTION CODE.)
+REMARK 465
+REMARK 465 M RES C SSSEQI
+REMARK 465 ILE A 1
+REMARK 465 ARG A 2
+REMARK 465 ALA A 3
+REMARK 465 GLN A 4
+REMARK 465 ALA A 5
+REMARK 465 SER A 6
+REMARK 465 ALA A 7
+REMARK 465 VAL A 8
+REMARK 465 GLU A 9
+REMARK 465 ALA A 10
+REMARK 465 PRO A 11
+REMARK 465 ALA A 12
+REMARK 465 THR A 13
+REMARK 465 ALA A 14
+REMARK 465 LYS A 15
+REMARK 465 ALA A 16
+REMARK 465 LYS A 17
+REMARK 465 GLY B 97
+REMARK 465 ALA B 98
+REMARK 465 ILE C 1
+REMARK 465 ARG C 2
+REMARK 465 ALA C 3
+REMARK 465 GLN C 4
+REMARK 465 ALA C 5
+REMARK 465 SER C 6
+REMARK 465 ALA C 7
+REMARK 465 VAL C 8
+REMARK 465 GLU C 9
+REMARK 465 ALA C 10
+REMARK 465 PRO C 11
+REMARK 465 ALA C 12
+REMARK 465 THR C 13
+REMARK 465 ALA C 14
+REMARK 465 LYS C 15
+REMARK 465 ALA C 16
+REMARK 465 LYS C 17
+REMARK 465 GLY D 97
+REMARK 465 ALA D 98
+REMARK 500
+REMARK 500 GEOMETRY AND STEREOCHEMISTRY
+REMARK 500 SUBTOPIC: CLOSE CONTACTS IN SAME ASYMMETRIC UNIT
+REMARK 500
+REMARK 500 THE FOLLOWING ATOMS ARE IN CLOSE CONTACT.
+REMARK 500
+REMARK 500 ATM1 RES C SSEQI ATM2 RES C SSEQI DISTANCE
+REMARK 500 SG CYS B 47 FE1 FES B 101 1.79
+REMARK 500 SG CYS B 44 FE2 FES B 101 1.83
+REMARK 500 O LEU C 94 C9A FAD C 401 2.17
+REMARK 500
+REMARK 500 REMARK: NULL
+REMARK 500
+REMARK 500 GEOMETRY AND STEREOCHEMISTRY
+REMARK 500 SUBTOPIC: COVALENT BOND ANGLES
+REMARK 500
+REMARK 500 THE STEREOCHEMICAL PARAMETERS OF THE FOLLOWING RESIDUES
+REMARK 500 HAVE VALUES WHICH DEVIATE FROM EXPECTED VALUES BY MORE
+REMARK 500 THAN 6*RMSD (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN
+REMARK 500 IDENTIFIER; SSEQ=SEQUENCE NUMBER; I=INSERTION CODE).
+REMARK 500
+REMARK 500 STANDARD TABLE:
+REMARK 500 FORMAT: (10X,I3,1X,A3,1X,A1,I4,A1,3(1X,A4,2X),12X,F5.1)
+REMARK 500
+REMARK 500 EXPECTED VALUES PROTEIN: ENGH AND HUBER, 1999
+REMARK 500 EXPECTED VALUES NUCLEIC ACID: CLOWNEY ET AL 1996
+REMARK 500
+REMARK 500 M RES CSSEQI ATM1 ATM2 ATM3
+REMARK 500 CYS C 19 CA - CB - SG ANGL. DEV. = 8.7 DEGREES
+REMARK 500
+REMARK 500 REMARK: NULL
+REMARK 500
+REMARK 500 GEOMETRY AND STEREOCHEMISTRY
+REMARK 500 SUBTOPIC: TORSION ANGLES
+REMARK 500
+REMARK 500 TORSION ANGLES OUTSIDE THE EXPECTED RAMACHANDRAN REGIONS:
+REMARK 500 (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN IDENTIFIER;
+REMARK 500 SSEQ=SEQUENCE NUMBER; I=INSERTION CODE).
+REMARK 500
+REMARK 500 STANDARD TABLE:
+REMARK 500 FORMAT:(10X,I3,1X,A3,1X,A1,I4,A1,4X,F7.2,3X,F7.2)
+REMARK 500
+REMARK 500 EXPECTED VALUES: GJ KLEYWEGT AND TA JONES (1996). PHI/PSI-
+REMARK 500 CHOLOGY: RAMACHANDRAN REVISITED. STRUCTURE 4, 1395 - 1400
+REMARK 500
+REMARK 500 M RES CSSEQI PSI PHI
+REMARK 500 GLN A 23 109.52 -58.82
+REMARK 500 ASN A 45 92.65 172.03
+REMARK 500 GLU A 56 115.31 72.23
+REMARK 500 PRO A 69 74.20 -68.96
+REMARK 500 GLU A 72 109.91 -44.80
+REMARK 500 THR A 172 20.52 -73.87
+REMARK 500 ASN A 195 42.91 -167.55
+REMARK 500 TYR A 212 12.59 54.24
+REMARK 500 GLU A 236 5.02 -155.90
+REMARK 500 LYS A 255 -16.18 -46.64
+REMARK 500 GLU A 256 -80.11 -72.63
+REMARK 500 LYS A 300 -71.41 -59.56
+REMARK 500 LYS A 301 -58.26 -27.03
+REMARK 500 ASP A 307 19.54 53.46
+REMARK 500 ILE B 8 79.93 -101.73
+REMARK 500 ASP B 20 4.98 -66.21
+REMARK 500 SER B 38 -78.01 -148.14
+REMARK 500 ALA B 41 19.26 -151.32
+REMARK 500 ASP B 60 15.91 96.95
+REMARK 500 SER B 62 -6.27 -143.09
+REMARK 500 GLN C 23 105.40 -59.16
+REMARK 500 ASN C 45 93.14 173.52
+REMARK 500 GLU C 56 118.79 69.25
+REMARK 500 GLN C 74 -173.82 -67.66
+REMARK 500 ILE C 127 102.10 -59.16
+REMARK 500 VAL C 131 -72.25 -48.59
+REMARK 500 ASN C 195 41.36 -161.84
+REMARK 500 TYR C 212 11.89 53.93
+REMARK 500 GLU C 236 1.48 -151.37
+REMARK 500 LYS C 255 -11.94 -45.29
+REMARK 500 GLU C 256 -78.15 -77.12
+REMARK 500 LYS C 301 -58.19 -29.78
+REMARK 500 ASP C 307 17.60 52.66
+REMARK 500 LEU D 16 162.38 179.37
+REMARK 500 ASP D 20 3.82 -67.10
+REMARK 500 SER D 38 -81.95 -149.47
+REMARK 500 ALA D 41 17.72 -150.42
+REMARK 500 ASP D 60 12.76 97.38
+REMARK 500 SER D 62 -9.08 -144.78
+REMARK 500
+REMARK 500 REMARK: NULL
+REMARK 620
+REMARK 620 METAL COORDINATION
+REMARK 620 (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN IDENTIFIER;
+REMARK 620 SSEQ=SEQUENCE NUMBER; I=INSERTION CODE):
+REMARK 620
+REMARK 620 COORDINATION ANGLES FOR: M RES CSSEQI METAL
+REMARK 620 FES D 101 FE2
+REMARK 620 N RES CSSEQI ATOM
+REMARK 620 1 CYS D 44 SG
+REMARK 620 2 FES D 101 S1 125.9
+REMARK 620 3 FES D 101 S2 95.5 93.6
+REMARK 620 4 CYS D 39 SG 140.2 77.5 116.4
+REMARK 620 N 1 2 3
+REMARK 620
+REMARK 620 COORDINATION ANGLES FOR: M RES CSSEQI METAL
+REMARK 620 FES D 101 FE1
+REMARK 620 N RES CSSEQI ATOM
+REMARK 620 1 CYS D 47 SG
+REMARK 620 2 FES D 101 S1 126.0
+REMARK 620 3 FES D 101 S2 106.4 93.2
+REMARK 620 4 CYS D 77 SG 126.8 80.4 118.3
+REMARK 620 N 1 2 3
+REMARK 620
+REMARK 620 COORDINATION ANGLES FOR: M RES CSSEQI METAL
+REMARK 620 FES B 101 FE2
+REMARK 620 N RES CSSEQI ATOM
+REMARK 620 1 CYS B 39 SG
+REMARK 620 2 FES B 101 S1 86.8
+REMARK 620 3 FES B 101 S2 116.1 91.6
+REMARK 620 N 1 2
+REMARK 620
+REMARK 620 COORDINATION ANGLES FOR: M RES CSSEQI METAL
+REMARK 620 FES B 101 FE1
+REMARK 620 N RES CSSEQI ATOM
+REMARK 620 1 CYS B 77 SG
+REMARK 620 2 FES B 101 S1 88.1
+REMARK 620 3 FES B 101 S2 109.5 92.2
+REMARK 620 N 1 2
+REMARK 800
+REMARK 800 SITE
+REMARK 800 SITE_IDENTIFIER: AC1
+REMARK 800 EVIDENCE_CODE: SOFTWARE
+REMARK 800 SITE_DESCRIPTION: BINDING SITE FOR RESIDUE FAD A 401
+REMARK 800
+REMARK 800 SITE_IDENTIFIER: AC2
+REMARK 800 EVIDENCE_CODE: SOFTWARE
+REMARK 800 SITE_DESCRIPTION: BINDING SITE FOR RESIDUE FES B 101
+REMARK 800
+REMARK 800 SITE_IDENTIFIER: AC3
+REMARK 800 EVIDENCE_CODE: SOFTWARE
+REMARK 800 SITE_DESCRIPTION: BINDING SITE FOR RESIDUE FAD C 401
+REMARK 800
+REMARK 800 SITE_IDENTIFIER: AC4
+REMARK 800 EVIDENCE_CODE: SOFTWARE
+REMARK 800 SITE_DESCRIPTION: BINDING SITE FOR RESIDUE FES D 101
+REMARK 900
+REMARK 900 RELATED ENTRIES
+REMARK 900 RELATED ID: 3W5U RELATED DB: PDB
+REMARK 900 SIMILAR COMPLEX WITH A DISTINCT CROSS-LINKAGE
+REMARK 900 RELATED ID: 1GAW RELATED DB: PDB
+REMARK 900 FERREDOXIN-NADP+ REDUCTASE
+REMARK 900 RELATED ID: 3B2F RELATED DB: PDB
+REMARK 900 FERREDOXIN
+DBREF 3W5V A 1 314 UNP Q9SLP6 Q9SLP6_MAIZE 42 355
+DBREF 3W5V B 1 98 UNP P27787 FER1_MAIZE 53 150
+DBREF 3W5V C 1 314 UNP Q9SLP6 Q9SLP6_MAIZE 42 355
+DBREF 3W5V D 1 98 UNP P27787 FER1_MAIZE 53 150
+SEQADV 3W5V CYS A 19 UNP Q9SLP6 GLU 60 ENGINEERED MUTATION
+SEQADV 3W5V CYS B 70 UNP P27787 ALA 122 ENGINEERED MUTATION
+SEQADV 3W5V CYS C 19 UNP Q9SLP6 GLU 60 ENGINEERED MUTATION
+SEQADV 3W5V CYS D 70 UNP P27787 ALA 122 ENGINEERED MUTATION
+SEQRES 1 A 314 ILE ARG ALA GLN ALA SER ALA VAL GLU ALA PRO ALA THR
+SEQRES 2 A 314 ALA LYS ALA LYS LYS CYS SER LYS LYS GLN GLU GLU GLY
+SEQRES 3 A 314 VAL VAL THR ASN LEU TYR LYS PRO LYS GLU PRO TYR VAL
+SEQRES 4 A 314 GLY ARG CYS LEU LEU ASN THR LYS ILE THR GLY ASP ASP
+SEQRES 5 A 314 ALA PRO GLY GLU THR TRP HIS MET VAL PHE SER THR GLU
+SEQRES 6 A 314 GLY LYS ILE PRO TYR ARG GLU GLY GLN SER ILE GLY VAL
+SEQRES 7 A 314 ILE ALA ASP GLY VAL ASP LYS ASN GLY LYS PRO HIS LYS
+SEQRES 8 A 314 VAL ARG LEU TYR SER ILE ALA SER SER ALA ILE GLY ASP
+SEQRES 9 A 314 PHE GLY ASP SER LYS THR VAL SER LEU CYS VAL LYS ARG
+SEQRES 10 A 314 LEU ILE TYR THR ASN ASP ALA GLY GLU ILE VAL LYS GLY
+SEQRES 11 A 314 VAL CYS SER ASN PHE LEU CYS ASP LEU GLN PRO GLY ASP
+SEQRES 12 A 314 ASN VAL GLN ILE THR GLY PRO VAL GLY LYS GLU MET LEU
+SEQRES 13 A 314 MET PRO LYS ASP PRO ASN ALA THR ILE ILE MET LEU ALA
+SEQRES 14 A 314 THR GLY THR GLY ILE ALA PRO PHE ARG SER PHE LEU TRP
+SEQRES 15 A 314 LYS MET PHE PHE GLU LYS HIS ASP ASP TYR LYS PHE ASN
+SEQRES 16 A 314 GLY LEU GLY TRP LEU PHE LEU GLY VAL PRO THR SER SER
+SEQRES 17 A 314 SER LEU LEU TYR LYS GLU GLU PHE GLY LYS MET LYS GLU
+SEQRES 18 A 314 ARG ALA PRO GLU ASN PHE ARG VAL ASP TYR ALA VAL SER
+SEQRES 19 A 314 ARG GLU GLN THR ASN ALA ALA GLY GLU ARG MET TYR ILE
+SEQRES 20 A 314 GLN THR ARG MET ALA GLU TYR LYS GLU GLU LEU TRP GLU
+SEQRES 21 A 314 LEU LEU LYS LYS ASP ASN THR TYR VAL TYR MET CYS GLY
+SEQRES 22 A 314 LEU LYS GLY MET GLU LYS GLY ILE ASP ASP ILE MET VAL
+SEQRES 23 A 314 SER LEU ALA GLU LYS ASP GLY ILE ASP TRP PHE ASP TYR
+SEQRES 24 A 314 LYS LYS GLN LEU LYS ARG GLY ASP GLN TRP ASN VAL GLU
+SEQRES 25 A 314 VAL TYR
+SEQRES 1 B 98 ALA THR TYR ASN VAL LYS LEU ILE THR PRO GLU GLY GLU
+SEQRES 2 B 98 VAL GLU LEU GLN VAL PRO ASP ASP VAL TYR ILE LEU ASP
+SEQRES 3 B 98 GLN ALA GLU GLU ASP GLY ILE ASP LEU PRO TYR SER CYS
+SEQRES 4 B 98 ARG ALA GLY SER CYS SER SER CYS ALA GLY LYS VAL VAL
+SEQRES 5 B 98 SER GLY SER VAL ASP GLN SER ASP GLN SER TYR LEU ASP
+SEQRES 6 B 98 ASP GLY GLN ILE CYS ASP GLY TRP VAL LEU THR CYS HIS
+SEQRES 7 B 98 ALA TYR PRO THR SER ASP VAL VAL ILE GLU THR HIS LYS
+SEQRES 8 B 98 GLU GLU GLU LEU THR GLY ALA
+SEQRES 1 C 314 ILE ARG ALA GLN ALA SER ALA VAL GLU ALA PRO ALA THR
+SEQRES 2 C 314 ALA LYS ALA LYS LYS CYS SER LYS LYS GLN GLU GLU GLY
+SEQRES 3 C 314 VAL VAL THR ASN LEU TYR LYS PRO LYS GLU PRO TYR VAL
+SEQRES 4 C 314 GLY ARG CYS LEU LEU ASN THR LYS ILE THR GLY ASP ASP
+SEQRES 5 C 314 ALA PRO GLY GLU THR TRP HIS MET VAL PHE SER THR GLU
+SEQRES 6 C 314 GLY LYS ILE PRO TYR ARG GLU GLY GLN SER ILE GLY VAL
+SEQRES 7 C 314 ILE ALA ASP GLY VAL ASP LYS ASN GLY LYS PRO HIS LYS
+SEQRES 8 C 314 VAL ARG LEU TYR SER ILE ALA SER SER ALA ILE GLY ASP
+SEQRES 9 C 314 PHE GLY ASP SER LYS THR VAL SER LEU CYS VAL LYS ARG
+SEQRES 10 C 314 LEU ILE TYR THR ASN ASP ALA GLY GLU ILE VAL LYS GLY
+SEQRES 11 C 314 VAL CYS SER ASN PHE LEU CYS ASP LEU GLN PRO GLY ASP
+SEQRES 12 C 314 ASN VAL GLN ILE THR GLY PRO VAL GLY LYS GLU MET LEU
+SEQRES 13 C 314 MET PRO LYS ASP PRO ASN ALA THR ILE ILE MET LEU ALA
+SEQRES 14 C 314 THR GLY THR GLY ILE ALA PRO PHE ARG SER PHE LEU TRP
+SEQRES 15 C 314 LYS MET PHE PHE GLU LYS HIS ASP ASP TYR LYS PHE ASN
+SEQRES 16 C 314 GLY LEU GLY TRP LEU PHE LEU GLY VAL PRO THR SER SER
+SEQRES 17 C 314 SER LEU LEU TYR LYS GLU GLU PHE GLY LYS MET LYS GLU
+SEQRES 18 C 314 ARG ALA PRO GLU ASN PHE ARG VAL ASP TYR ALA VAL SER
+SEQRES 19 C 314 ARG GLU GLN THR ASN ALA ALA GLY GLU ARG MET TYR ILE
+SEQRES 20 C 314 GLN THR ARG MET ALA GLU TYR LYS GLU GLU LEU TRP GLU
+SEQRES 21 C 314 LEU LEU LYS LYS ASP ASN THR TYR VAL TYR MET CYS GLY
+SEQRES 22 C 314 LEU LYS GLY MET GLU LYS GLY ILE ASP ASP ILE MET VAL
+SEQRES 23 C 314 SER LEU ALA GLU LYS ASP GLY ILE ASP TRP PHE ASP TYR
+SEQRES 24 C 314 LYS LYS GLN LEU LYS ARG GLY ASP GLN TRP ASN VAL GLU
+SEQRES 25 C 314 VAL TYR
+SEQRES 1 D 98 ALA THR TYR ASN VAL LYS LEU ILE THR PRO GLU GLY GLU
+SEQRES 2 D 98 VAL GLU LEU GLN VAL PRO ASP ASP VAL TYR ILE LEU ASP
+SEQRES 3 D 98 GLN ALA GLU GLU ASP GLY ILE ASP LEU PRO TYR SER CYS
+SEQRES 4 D 98 ARG ALA GLY SER CYS SER SER CYS ALA GLY LYS VAL VAL
+SEQRES 5 D 98 SER GLY SER VAL ASP GLN SER ASP GLN SER TYR LEU ASP
+SEQRES 6 D 98 ASP GLY GLN ILE CYS ASP GLY TRP VAL LEU THR CYS HIS
+SEQRES 7 D 98 ALA TYR PRO THR SER ASP VAL VAL ILE GLU THR HIS LYS
+SEQRES 8 D 98 GLU GLU GLU LEU THR GLY ALA
+HET FAD A 401 53
+HET FES B 101 4
+HET FAD C 401 53
+HET FES D 101 4
+HETNAM FAD FLAVIN-ADENINE DINUCLEOTIDE
+HETNAM FES FE2/S2 (INORGANIC) CLUSTER
+FORMUL 5 FAD 2(C27 H33 N9 O15 P2)
+FORMUL 6 FES 2(FE2 S2)
+HELIX 1 1 GLY A 130 ASP A 138 1 9
+HELIX 2 2 ILE A 174 PHE A 186 1 13
+HELIX 3 3 TYR A 212 ALA A 223 1 12
+HELIX 4 4 TYR A 246 GLU A 253 1 8
+HELIX 5 5 TYR A 254 LEU A 262 1 9
+HELIX 6 6 GLY A 276 GLU A 290 1 15
+HELIX 7 7 ASP A 295 GLY A 306 1 12
+HELIX 8 8 TYR B 23 ASP B 31 1 9
+HELIX 9 9 ASP B 65 CYS B 70 1 6
+HELIX 10 10 CYS B 77 ALA B 79 5 3
+HELIX 11 11 LYS B 91 THR B 96 1 6
+HELIX 12 12 GLY C 130 ASP C 138 1 9
+HELIX 13 13 ILE C 174 PHE C 186 1 13
+HELIX 14 14 TYR C 212 ALA C 223 1 12
+HELIX 15 15 TYR C 246 GLU C 253 1 8
+HELIX 16 16 TYR C 254 LEU C 262 1 9
+HELIX 17 17 GLY C 276 GLU C 290 1 15
+HELIX 18 18 ASP C 295 GLY C 306 1 12
+HELIX 19 19 TYR D 23 ASP D 31 1 9
+HELIX 20 20 ASP D 65 ASP D 71 1 7
+HELIX 21 21 CYS D 77 ALA D 79 5 3
+HELIX 22 22 LYS D 91 THR D 96 1 6
+SHEET 1 A 6 THR A 46 LYS A 47 0
+SHEET 2 A 6 THR A 57 SER A 63 -1 O HIS A 59 N THR A 46
+SHEET 3 A 6 TYR A 38 CYS A 42 -1 N ARG A 41 O SER A 63
+SHEET 4 A 6 ASN A 144 VAL A 151 -1 O ILE A 147 N TYR A 38
+SHEET 5 A 6 SER A 75 ILE A 79 -1 N GLY A 77 O THR A 148
+SHEET 6 A 6 ARG A 93 SER A 96 -1 O TYR A 95 N ILE A 76
+SHEET 1 B 3 THR A 46 LYS A 47 0
+SHEET 2 B 3 THR A 57 SER A 63 -1 O HIS A 59 N THR A 46
+SHEET 3 B 3 THR A 110 LYS A 116 -1 O LEU A 113 N MET A 60
+SHEET 1 C 2 ILE A 119 THR A 121 0
+SHEET 2 C 2 ILE A 127 LYS A 129 -1 O VAL A 128 N TYR A 120
+SHEET 1 D 5 PHE A 227 VAL A 233 0
+SHEET 2 D 5 LEU A 197 VAL A 204 1 N GLY A 198 O ARG A 228
+SHEET 3 D 5 THR A 164 THR A 170 1 N MET A 167 O PHE A 201
+SHEET 4 D 5 THR A 267 LEU A 274 1 O TYR A 270 N ILE A 166
+SHEET 5 D 5 TRP A 309 TYR A 314 1 O ASN A 310 N MET A 271
+SHEET 1 E 5 GLY B 12 PRO B 19 0
+SHEET 2 E 5 THR B 2 THR B 9 -1 N LEU B 7 O VAL B 14
+SHEET 3 E 5 VAL B 85 GLU B 88 1 O ILE B 87 N ILE B 8
+SHEET 4 E 5 ALA B 48 SER B 53 -1 N VAL B 52 O VAL B 86
+SHEET 5 E 5 TRP B 73 LEU B 75 -1 O VAL B 74 N GLY B 49
+SHEET 1 F 2 VAL B 56 ASP B 57 0
+SHEET 2 F 2 TYR B 80 PRO B 81 -1 O TYR B 80 N ASP B 57
+SHEET 1 G 6 THR C 46 LYS C 47 0
+SHEET 2 G 6 THR C 57 SER C 63 -1 O HIS C 59 N THR C 46
+SHEET 3 G 6 TYR C 38 CYS C 42 -1 N ARG C 41 O SER C 63
+SHEET 4 G 6 ASN C 144 VAL C 151 -1 O VAL C 145 N GLY C 40
+SHEET 5 G 6 SER C 75 ILE C 79 -1 N GLY C 77 O THR C 148
+SHEET 6 G 6 ARG C 93 SER C 96 -1 O TYR C 95 N ILE C 76
+SHEET 1 H 3 THR C 46 LYS C 47 0
+SHEET 2 H 3 THR C 57 SER C 63 -1 O HIS C 59 N THR C 46
+SHEET 3 H 3 THR C 110 LYS C 116 -1 O VAL C 111 N PHE C 62
+SHEET 1 I 2 ILE C 119 THR C 121 0
+SHEET 2 I 2 ILE C 127 LYS C 129 -1 O VAL C 128 N TYR C 120
+SHEET 1 J 5 PHE C 227 VAL C 233 0
+SHEET 2 J 5 LEU C 197 VAL C 204 1 N GLY C 198 O ARG C 228
+SHEET 3 J 5 THR C 164 THR C 170 1 N MET C 167 O PHE C 201
+SHEET 4 J 5 THR C 267 LEU C 274 1 O TYR C 268 N THR C 164
+SHEET 5 J 5 TRP C 309 TYR C 314 1 O ASN C 310 N MET C 271
+SHEET 1 K 5 GLY D 12 PRO D 19 0
+SHEET 2 K 5 THR D 2 THR D 9 -1 N LEU D 7 O VAL D 14
+SHEET 3 K 5 VAL D 85 THR D 89 1 O ILE D 87 N ILE D 8
+SHEET 4 K 5 ALA D 48 SER D 53 -1 N VAL D 52 O VAL D 86
+SHEET 5 K 5 TRP D 73 LEU D 75 -1 O VAL D 74 N GLY D 49
+SHEET 1 L 2 VAL D 56 ASP D 57 0
+SHEET 2 L 2 TYR D 80 PRO D 81 -1 O TYR D 80 N ASP D 57
+SSBOND 1 CYS A 19 CYS D 70 1555 1555 2.02
+SSBOND 2 CYS B 70 CYS C 19 1555 1555 2.03
+LINK SG CYS D 44 FE2 FES D 101 1555 1555 1.91
+LINK SG CYS D 47 FE1 FES D 101 1555 1555 1.95
+LINK SG CYS B 39 FE2 FES B 101 1555 1555 1.96
+LINK SG CYS D 39 FE2 FES D 101 1555 1555 2.15
+LINK SG CYS B 77 FE1 FES B 101 1555 1555 2.35
+LINK SG CYS D 77 FE1 FES D 101 1555 1555 2.61
+CISPEP 1 GLY A 149 PRO A 150 0 -1.95
+CISPEP 2 GLY C 149 PRO C 150 0 -1.62
+SITE 1 AC1 15 ARG A 93 LEU A 94 TYR A 95 SER A 96
+SITE 2 AC1 15 CYS A 114 LYS A 116 LEU A 118 TYR A 120
+SITE 3 AC1 15 GLY A 130 VAL A 131 CYS A 132 SER A 133
+SITE 4 AC1 15 THR A 172 TYR A 314 SER B 38
+SITE 1 AC2 9 SER B 38 CYS B 39 ARG B 40 GLY B 42
+SITE 2 AC2 9 SER B 43 CYS B 44 CYS B 47 LEU B 75
+SITE 3 AC2 9 CYS B 77
+SITE 1 AC3 17 GLY A 242 ARG A 244 ARG C 93 LEU C 94
+SITE 2 AC3 17 TYR C 95 SER C 96 CYS C 114 VAL C 115
+SITE 3 AC3 17 LYS C 116 LEU C 118 TYR C 120 GLY C 130
+SITE 4 AC3 17 VAL C 131 CYS C 132 SER C 133 THR C 172
+SITE 5 AC3 17 TYR C 314
+SITE 1 AC4 9 SER D 38 CYS D 39 ARG D 40 GLY D 42
+SITE 2 AC4 9 SER D 43 CYS D 44 CYS D 47 LEU D 75
+SITE 3 AC4 9 CYS D 77
+CRYST1 75.170 120.345 84.577 90.00 109.70 90.00 P 1 21 1 4
+ORIGX1 1.000000 0.000000 0.000000 0.00000
+ORIGX2 0.000000 1.000000 0.000000 0.00000
+ORIGX3 0.000000 0.000000 1.000000 0.00000
+SCALE1 0.013303 0.000000 0.004764 0.00000
+SCALE2 0.000000 0.008309 0.000000 0.00000
+SCALE3 0.000000 0.000000 0.012559 0.00000
+MTRIX1 1 1.000000 0.000000 0.000000 0.00000 1
+MTRIX2 1 0.000000 1.000000 0.000000 0.00000 1
+MTRIX3 1 0.000000 0.000000 1.000000 0.00000 1
+MTRIX1 2 -0.900585 -0.360692 0.242586 -93.40076 1
+MTRIX2 2 -0.323557 0.183576 -0.928230 33.09570 1
+MTRIX3 2 0.290273 -0.914440 -0.282030 74.35553 1
+ATOM 1 N LYS A 18 -28.790 -18.357 17.844 1.00 40.00 N
+ATOM 2 CA LYS A 18 -27.990 -18.527 19.103 1.00 40.00 C
+ATOM 3 C LYS A 18 -28.888 -18.264 20.328 1.00 40.00 C
+ATOM 4 O LYS A 18 -29.482 -17.177 20.452 1.00 40.00 O
+ATOM 5 CB LYS A 18 -26.767 -17.582 19.138 1.00 40.00 C
+ATOM 6 CG LYS A 18 -26.359 -16.919 17.814 1.00 40.00 C
+ATOM 7 CD LYS A 18 -27.280 -15.776 17.366 1.00 40.00 C
+ATOM 8 CE LYS A 18 -27.659 -14.804 18.485 1.00 40.00 C
+ATOM 9 NZ LYS A 18 -26.567 -13.860 18.840 1.00 40.00 N
+ATOM 10 N CYS A 19 -29.018 -19.251 21.219 1.00 40.00 N
+ATOM 11 CA CYS A 19 -29.736 -19.000 22.469 1.00 40.00 C
+ATOM 12 C CYS A 19 -28.765 -18.475 23.517 1.00 40.00 C
+ATOM 13 O CYS A 19 -27.614 -18.928 23.642 1.00 40.00 O
+ATOM 14 CB CYS A 19 -30.569 -20.193 22.949 1.00 40.00 C
+ATOM 15 SG CYS A 19 -29.784 -21.807 22.816 1.00 40.00 S
+ATOM 16 N SER A 20 -29.241 -17.468 24.227 1.00 40.00 N
+ATOM 17 CA SER A 20 -28.405 -16.691 25.110 1.00 40.00 C
+ATOM 18 C SER A 20 -28.651 -17.107 26.557 1.00 40.00 C
+ATOM 19 O SER A 20 -29.707 -17.666 26.874 1.00 40.00 O
+ATOM 20 CB SER A 20 -28.692 -15.201 24.887 1.00 40.00 C
+ATOM 21 OG SER A 20 -28.226 -14.386 25.948 1.00 40.00 O
+ATOM 22 N LYS A 21 -27.671 -16.835 27.422 1.00 40.00 N
+ATOM 23 CA LYS A 21 -27.776 -17.131 28.847 1.00 40.00 C
+ATOM 24 C LYS A 21 -28.469 -16.016 29.608 1.00 40.00 C
+ATOM 25 O LYS A 21 -28.576 -16.083 30.831 1.00 40.00 O
+ATOM 26 CB LYS A 21 -26.396 -17.388 29.438 1.00 40.00 C
+ATOM 27 CG LYS A 21 -25.693 -18.583 28.818 1.00 40.00 C
+ATOM 28 CD LYS A 21 -24.275 -18.744 29.338 1.00 40.00 C
+ATOM 29 CE LYS A 21 -23.428 -19.521 28.345 1.00 40.00 C
+ATOM 30 NZ LYS A 21 -22.039 -19.714 28.839 1.00 40.00 N
+ATOM 31 N LYS A 22 -28.949 -15.011 28.867 1.00 40.00 N
+ATOM 32 CA LYS A 22 -29.640 -13.820 29.400 1.00 40.00 C
+ATOM 33 C LYS A 22 -31.095 -13.782 28.970 1.00 40.00 C
+ATOM 34 O LYS A 22 -31.378 -13.969 27.792 1.00 40.00 O
+ATOM 35 CB LYS A 22 -28.976 -12.554 28.871 1.00 40.00 C
+ATOM 36 CG LYS A 22 -27.457 -12.569 28.929 1.00 40.00 C
+ATOM 37 CD LYS A 22 -26.889 -11.294 28.334 1.00 40.00 C
+ATOM 38 CE LYS A 22 -25.393 -11.184 28.564 1.00 40.00 C
+ATOM 39 NZ LYS A 22 -24.847 -9.966 27.905 1.00 40.00 N
+ATOM 40 N GLN A 23 -32.010 -13.517 29.901 1.00 40.00 N
+ATOM 41 CA GLN A 23 -33.443 -13.632 29.609 1.00 40.00 C
+ATOM 42 C GLN A 23 -33.847 -12.730 28.472 1.00 40.00 C
+ATOM 43 O GLN A 23 -33.873 -11.517 28.638 1.00 40.00 O
+ATOM 44 CB GLN A 23 -34.285 -13.288 30.821 1.00 40.00 C
+ATOM 45 CG GLN A 23 -34.161 -14.283 31.949 1.00 40.00 C
+ATOM 46 CD GLN A 23 -34.707 -13.739 33.250 1.00 40.00 C
+ATOM 47 OE1 GLN A 23 -35.821 -13.197 33.293 1.00 40.00 O
+ATOM 48 NE2 GLN A 23 -33.926 -13.876 34.327 1.00 40.00 N
+ATOM 49 N GLU A 24 -34.168 -13.327 27.322 1.00 40.00 N
+ATOM 50 CA GLU A 24 -34.463 -12.550 26.110 1.00 40.00 C
+ATOM 51 C GLU A 24 -35.961 -12.512 25.779 1.00 40.00 C
+ATOM 52 O GLU A 24 -36.399 -11.866 24.824 1.00 40.00 O
+ATOM 53 CB GLU A 24 -33.599 -13.030 24.929 1.00 40.00 C
+ATOM 54 CG GLU A 24 -32.098 -12.852 25.188 1.00 40.00 C
+ATOM 55 CD GLU A 24 -31.292 -12.380 23.983 1.00 40.00 C
+ATOM 56 OE1 GLU A 24 -31.884 -11.756 23.060 1.00 40.00 O
+ATOM 57 OE2 GLU A 24 -30.056 -12.619 23.976 1.00 40.00 O
+ATOM 58 N GLU A 25 -36.735 -13.170 26.630 1.00 40.00 N
+ATOM 59 CA GLU A 25 -38.162 -13.331 26.437 1.00 40.00 C
+ATOM 60 C GLU A 25 -38.996 -12.123 26.887 1.00 40.00 C
+ATOM 61 O GLU A 25 -39.035 -11.786 28.066 1.00 40.00 O
+ATOM 62 CB GLU A 25 -38.616 -14.588 27.179 1.00 40.00 C
+ATOM 63 CG GLU A 25 -40.121 -14.836 27.137 1.00 40.00 C
+ATOM 64 CD GLU A 25 -40.633 -15.707 28.283 1.00 40.00 C
+ATOM 65 OE1 GLU A 25 -41.875 -15.854 28.414 1.00 40.00 O
+ATOM 66 OE2 GLU A 25 -39.806 -16.243 29.060 1.00 40.00 O
+ATOM 67 N GLY A 26 -39.692 -11.503 25.943 1.00 40.00 N
+ATOM 68 CA GLY A 26 -40.566 -10.364 26.242 1.00 40.00 C
+ATOM 69 C GLY A 26 -39.886 -9.008 26.056 1.00 40.00 C
+ATOM 70 O GLY A 26 -40.544 -7.959 25.948 1.00 40.00 O
+ATOM 71 N VAL A 27 -38.559 -9.036 26.018 1.00 40.00 N
+ATOM 72 CA VAL A 27 -37.749 -7.848 25.849 1.00 40.00 C
+ATOM 73 C VAL A 27 -38.078 -7.122 24.552 1.00 40.00 C
+ATOM 74 O VAL A 27 -37.933 -7.683 23.480 1.00 40.00 O
+ATOM 75 CB VAL A 27 -36.277 -8.254 25.799 1.00 40.00 C
+ATOM 76 CG1 VAL A 27 -35.391 -7.024 25.762 1.00 40.00 C
+ATOM 77 CG2 VAL A 27 -35.947 -9.134 26.990 1.00 40.00 C
+ATOM 78 N VAL A 28 -38.508 -5.874 24.640 1.00 40.00 N
+ATOM 79 CA VAL A 28 -38.799 -5.109 23.432 1.00 40.00 C
+ATOM 80 C VAL A 28 -37.718 -4.048 23.188 1.00 40.00 C
+ATOM 81 O VAL A 28 -37.091 -3.598 24.138 1.00 40.00 O
+ATOM 82 CB VAL A 28 -40.218 -4.495 23.498 1.00 40.00 C
+ATOM 83 CG1 VAL A 28 -41.217 -5.521 24.018 1.00 40.00 C
+ATOM 84 CG2 VAL A 28 -40.254 -3.255 24.379 1.00 40.00 C
+ATOM 85 N THR A 29 -37.477 -3.665 21.934 1.00 40.00 N
+ATOM 86 CA THR A 29 -36.574 -2.537 21.657 1.00 40.00 C
+ATOM 87 C THR A 29 -37.134 -1.489 20.708 1.00 40.00 C
+ATOM 88 O THR A 29 -38.044 -1.749 19.930 1.00 40.00 O
+ATOM 89 CB THR A 29 -35.197 -2.967 21.126 1.00 40.00 C
+ATOM 90 OG1 THR A 29 -35.354 -4.108 20.293 1.00 40.00 O
+ATOM 91 CG2 THR A 29 -34.287 -3.330 22.251 1.00 40.00 C
+ATOM 92 N ASN A 30 -36.557 -0.296 20.803 1.00 40.00 N
+ATOM 93 CA ASN A 30 -36.905 0.869 19.986 1.00 40.00 C
+ATOM 94 C ASN A 30 -38.395 1.116 19.727 1.00 40.00 C
+ATOM 95 O ASN A 30 -38.775 1.572 18.647 1.00 40.00 O
+ATOM 96 CB ASN A 30 -36.064 0.893 18.710 1.00 40.00 C
+ATOM 97 CG ASN A 30 -34.598 1.154 19.000 1.00 40.00 C
+ATOM 98 OD1 ASN A 30 -34.152 2.307 19.007 1.00 40.00 O
+ATOM 99 ND2 ASN A 30 -33.841 0.081 19.259 1.00 40.00 N
+ATOM 100 N LEU A 31 -39.213 0.838 20.749 1.00 40.00 N
+ATOM 101 CA LEU A 31 -40.649 1.101 20.729 1.00 40.00 C
+ATOM 102 C LEU A 31 -40.994 2.576 20.443 1.00 40.00 C
+ATOM 103 O LEU A 31 -41.929 2.844 19.702 1.00 40.00 O
+ATOM 104 CB LEU A 31 -41.297 0.630 22.027 1.00 40.00 C
+ATOM 105 CG LEU A 31 -42.459 -0.352 21.899 1.00 40.00 C
+ATOM 106 CD1 LEU A 31 -43.174 -0.478 23.228 1.00 40.00 C
+ATOM 107 CD2 LEU A 31 -43.458 0.073 20.839 1.00 40.00 C
+ATOM 108 N TYR A 32 -40.253 3.522 21.021 1.00 40.00 N
+ATOM 109 CA TYR A 32 -40.294 4.924 20.569 1.00 40.00 C
+ATOM 110 C TYR A 32 -38.899 5.382 20.108 1.00 40.00 C
+ATOM 111 O TYR A 32 -37.879 5.020 20.708 1.00 40.00 O
+ATOM 112 CB TYR A 32 -40.812 5.870 21.655 1.00 40.00 C
+ATOM 113 CG TYR A 32 -42.199 5.587 22.193 1.00 40.00 C
+ATOM 114 CD1 TYR A 32 -42.442 4.480 23.014 1.00 40.00 C
+ATOM 115 CD2 TYR A 32 -43.259 6.450 21.924 1.00 40.00 C
+ATOM 116 CE1 TYR A 32 -43.703 4.225 23.533 1.00 40.00 C
+ATOM 117 CE2 TYR A 32 -44.528 6.205 22.437 1.00 40.00 C
+ATOM 118 CZ TYR A 32 -44.743 5.091 23.246 1.00 40.00 C
+ATOM 119 OH TYR A 32 -45.992 4.821 23.773 1.00 40.00 O
+ATOM 120 N LYS A 33 -38.867 6.178 19.039 1.00 40.00 N
+ATOM 121 CA LYS A 33 -37.616 6.691 18.445 1.00 40.00 C
+ATOM 122 C LYS A 33 -37.626 8.235 18.464 1.00 40.00 C
+ATOM 123 O LYS A 33 -38.688 8.830 18.665 1.00 40.00 O
+ATOM 124 CB LYS A 33 -37.440 6.174 16.999 1.00 40.00 C
+ATOM 125 CG LYS A 33 -37.289 4.652 16.831 1.00 40.00 C
+ATOM 126 CD LYS A 33 -37.474 4.221 15.363 1.00 40.00 C
+ATOM 127 CE LYS A 33 -37.663 2.713 15.168 1.00 40.00 C
+ATOM 128 NZ LYS A 33 -39.025 2.239 15.551 1.00 40.00 N
+ATOM 129 N PRO A 34 -36.447 8.887 18.267 1.00 40.00 N
+ATOM 130 CA PRO A 34 -36.280 10.366 18.253 1.00 40.00 C
+ATOM 131 C PRO A 34 -37.264 11.186 17.397 1.00 40.00 C
+ATOM 132 O PRO A 34 -37.515 12.357 17.704 1.00 40.00 O
+ATOM 133 CB PRO A 34 -34.857 10.543 17.725 1.00 40.00 C
+ATOM 134 CG PRO A 34 -34.140 9.335 18.228 1.00 40.00 C
+ATOM 135 CD PRO A 34 -35.135 8.203 18.237 1.00 40.00 C
+ATOM 136 N LYS A 35 -37.800 10.578 16.340 1.00 40.00 N
+ATOM 137 CA LYS A 35 -38.849 11.199 15.530 1.00 40.00 C
+ATOM 138 C LYS A 35 -40.211 11.280 16.256 1.00 40.00 C
+ATOM 139 O LYS A 35 -40.899 12.304 16.167 1.00 40.00 O
+ATOM 140 CB LYS A 35 -39.004 10.472 14.188 1.00 40.00 C
+ATOM 141 CG LYS A 35 -39.985 9.302 14.206 1.00 40.00 C
+ATOM 142 CD LYS A 35 -39.803 8.387 13.013 1.00 40.00 C
+ATOM 143 CE LYS A 35 -38.570 7.518 13.187 1.00 40.00 C
+ATOM 144 NZ LYS A 35 -38.127 6.952 11.883 1.00 40.00 N
+ATOM 145 N GLU A 36 -40.605 10.205 16.950 1.00 40.00 N
+ATOM 146 CA GLU A 36 -41.873 10.179 17.706 1.00 40.00 C
+ATOM 147 C GLU A 36 -41.734 9.676 19.153 1.00 40.00 C
+ATOM 148 O GLU A 36 -42.177 8.560 19.475 1.00 40.00 O
+ATOM 149 CB GLU A 36 -42.958 9.405 16.952 1.00 40.00 C
+ATOM 150 CG GLU A 36 -43.620 10.221 15.850 1.00 40.00 C
+ATOM 151 CD GLU A 36 -44.885 9.573 15.306 1.00 40.00 C
+ATOM 152 OE1 GLU A 36 -44.957 9.388 14.068 1.00 40.00 O
+ATOM 153 OE2 GLU A 36 -45.805 9.247 16.103 1.00 40.00 O
+ATOM 154 N PRO A 37 -41.128 10.514 20.032 1.00 40.00 N
+ATOM 155 CA PRO A 37 -40.925 10.163 21.443 1.00 40.00 C
+ATOM 156 C PRO A 37 -42.210 10.182 22.254 1.00 40.00 C
+ATOM 157 O PRO A 37 -43.074 11.034 22.044 1.00 40.00 O
+ATOM 158 CB PRO A 37 -39.998 11.277 21.952 1.00 40.00 C
+ATOM 159 CG PRO A 37 -40.282 12.447 21.069 1.00 40.00 C
+ATOM 160 CD PRO A 37 -40.593 11.860 19.720 1.00 40.00 C
+ATOM 161 N TYR A 38 -42.330 9.250 23.186 1.00 40.00 N
+ATOM 162 CA TYR A 38 -43.392 9.337 24.168 1.00 40.00 C
+ATOM 163 C TYR A 38 -43.159 10.548 25.084 1.00 40.00 C
+ATOM 164 O TYR A 38 -42.049 10.781 25.576 1.00 40.00 O
+ATOM 165 CB TYR A 38 -43.482 8.045 24.982 1.00 40.00 C
+ATOM 166 CG TYR A 38 -44.433 8.147 26.140 1.00 40.00 C
+ATOM 167 CD1 TYR A 38 -45.807 7.979 25.963 1.00 40.00 C
+ATOM 168 CD2 TYR A 38 -43.956 8.434 27.413 1.00 40.00 C
+ATOM 169 CE1 TYR A 38 -46.677 8.086 27.029 1.00 40.00 C
+ATOM 170 CE2 TYR A 38 -44.811 8.535 28.486 1.00 40.00 C
+ATOM 171 CZ TYR A 38 -46.164 8.366 28.293 1.00 40.00 C
+ATOM 172 OH TYR A 38 -46.982 8.477 29.393 1.00 40.00 O
+ATOM 173 N VAL A 39 -44.201 11.331 25.306 1.00 40.00 N
+ATOM 174 CA VAL A 39 -44.064 12.412 26.249 1.00 40.00 C
+ATOM 175 C VAL A 39 -44.601 11.918 27.577 1.00 40.00 C
+ATOM 176 O VAL A 39 -45.771 11.562 27.697 1.00 40.00 O
+ATOM 177 CB VAL A 39 -44.717 13.720 25.754 1.00 40.00 C
+ATOM 178 CG1 VAL A 39 -44.727 14.770 26.847 1.00 40.00 C
+ATOM 179 CG2 VAL A 39 -43.955 14.261 24.551 1.00 40.00 C
+ATOM 180 N GLY A 40 -43.702 11.848 28.551 1.00 40.00 N
+ATOM 181 CA GLY A 40 -44.030 11.417 29.907 1.00 40.00 C
+ATOM 182 C GLY A 40 -44.064 12.579 30.875 1.00 40.00 C
+ATOM 183 O GLY A 40 -44.082 13.734 30.467 1.00 40.00 O
+ATOM 184 N ARG A 41 -44.072 12.288 32.167 1.00 40.00 N
+ATOM 185 CA ARG A 41 -44.154 13.375 33.120 1.00 40.00 C
+ATOM 186 C ARG A 41 -43.387 13.136 34.402 1.00 40.00 C
+ATOM 187 O ARG A 41 -43.339 12.001 34.897 1.00 40.00 O
+ATOM 188 CB ARG A 41 -45.603 13.674 33.447 1.00 40.00 C
+ATOM 189 CG ARG A 41 -45.807 15.073 33.989 1.00 40.00 C
+ATOM 190 CD ARG A 41 -47.283 15.412 34.094 1.00 40.00 C
+ATOM 191 NE ARG A 41 -47.922 15.509 32.782 1.00 40.00 N
+ATOM 192 CZ ARG A 41 -48.022 16.630 32.072 1.00 40.00 C
+ATOM 193 NH1 ARG A 41 -47.520 17.772 32.542 1.00 40.00 N
+ATOM 194 NH2 ARG A 41 -48.619 16.605 30.883 1.00 40.00 N
+ATOM 195 N CYS A 42 -42.816 14.228 34.934 1.00 40.00 N
+ATOM 196 CA CYS A 42 -41.958 14.215 36.133 1.00 40.00 C
+ATOM 197 C CYS A 42 -42.762 14.117 37.430 1.00 40.00 C
+ATOM 198 O CYS A 42 -43.594 14.964 37.730 1.00 40.00 O
+ATOM 199 CB CYS A 42 -41.034 15.446 36.156 1.00 40.00 C
+ATOM 200 SG CYS A 42 -39.841 15.488 37.524 1.00 40.00 S
+ATOM 201 N LEU A 43 -42.502 13.070 38.196 1.00 40.00 N
+ATOM 202 CA LEU A 43 -43.235 12.832 39.417 1.00 40.00 C
+ATOM 203 C LEU A 43 -42.380 13.251 40.604 1.00 40.00 C
+ATOM 204 O LEU A 43 -42.809 14.064 41.421 1.00 40.00 O
+ATOM 205 CB LEU A 43 -43.630 11.351 39.513 1.00 40.00 C
+ATOM 206 CG LEU A 43 -44.789 10.752 38.693 1.00 40.00 C
+ATOM 207 CD1 LEU A 43 -45.023 11.410 37.337 1.00 40.00 C
+ATOM 208 CD2 LEU A 43 -44.591 9.248 38.532 1.00 40.00 C
+ATOM 209 N LEU A 44 -41.174 12.687 40.682 1.00 40.00 N
+ATOM 210 CA LEU A 44 -40.198 13.000 41.731 1.00 40.00 C
+ATOM 211 C LEU A 44 -38.964 13.607 41.105 1.00 40.00 C
+ATOM 212 O LEU A 44 -38.890 13.762 39.886 1.00 40.00 O
+ATOM 213 CB LEU A 44 -39.783 11.741 42.516 1.00 40.00 C
+ATOM 214 CG LEU A 44 -40.797 11.112 43.474 1.00 40.00 C
+ATOM 215 CD1 LEU A 44 -40.100 10.077 44.349 1.00 40.00 C
+ATOM 216 CD2 LEU A 44 -41.502 12.174 44.316 1.00 40.00 C
+ATOM 217 N ASN A 45 -38.003 13.943 41.960 1.00 40.00 N
+ATOM 218 CA ASN A 45 -36.712 14.492 41.563 1.00 40.00 C
+ATOM 219 C ASN A 45 -36.006 14.916 42.840 1.00 40.00 C
+ATOM 220 O ASN A 45 -36.197 16.022 43.330 1.00 40.00 O
+ATOM 221 CB ASN A 45 -36.854 15.678 40.576 1.00 40.00 C
+ATOM 222 CG ASN A 45 -35.547 16.018 39.854 1.00 40.00 C
+ATOM 223 OD1 ASN A 45 -34.512 15.390 40.083 1.00 40.00 O
+ATOM 224 ND2 ASN A 45 -35.596 17.017 38.969 1.00 40.00 N
+ATOM 225 N THR A 46 -35.206 14.016 43.389 1.00 40.00 N
+ATOM 226 CA THR A 46 -34.545 14.249 44.664 1.00 40.00 C
+ATOM 227 C THR A 46 -33.023 14.198 44.497 1.00 40.00 C
+ATOM 228 O THR A 46 -32.503 13.253 43.909 1.00 40.00 O
+ATOM 229 CB THR A 46 -34.994 13.176 45.676 1.00 40.00 C
+ATOM 230 OG1 THR A 46 -36.415 13.026 45.596 1.00 40.00 O
+ATOM 231 CG2 THR A 46 -34.581 13.531 47.102 1.00 40.00 C
+ATOM 232 N LYS A 47 -32.302 15.202 44.993 1.00 40.00 N
+ATOM 233 CA LYS A 47 -30.850 15.085 45.060 1.00 40.00 C
+ATOM 234 C LYS A 47 -30.584 13.942 46.019 1.00 40.00 C
+ATOM 235 O LYS A 47 -31.277 13.796 47.022 1.00 40.00 O
+ATOM 236 CB LYS A 47 -30.183 16.378 45.549 1.00 40.00 C
+ATOM 237 CG LYS A 47 -28.695 16.463 45.219 1.00 40.00 C
+ATOM 238 CD LYS A 47 -28.118 17.866 45.326 1.00 40.00 C
+ATOM 239 CE LYS A 47 -27.205 17.999 46.525 1.00 40.00 C
+ATOM 240 NZ LYS A 47 -26.233 19.097 46.295 1.00 40.00 N
+ATOM 241 N ILE A 48 -29.610 13.108 45.687 1.00 40.00 N
+ATOM 242 CA ILE A 48 -29.268 11.956 46.527 1.00 40.00 C
+ATOM 243 C ILE A 48 -27.803 11.960 47.021 1.00 40.00 C
+ATOM 244 O ILE A 48 -27.420 11.140 47.860 1.00 40.00 O
+ATOM 245 CB ILE A 48 -29.630 10.625 45.839 1.00 40.00 C
+ATOM 246 CG1 ILE A 48 -29.110 10.621 44.405 1.00 40.00 C
+ATOM 247 CG2 ILE A 48 -31.138 10.426 45.842 1.00 40.00 C
+ATOM 248 CD1 ILE A 48 -28.765 9.252 43.880 1.00 40.00 C
+ATOM 249 N THR A 49 -26.995 12.881 46.488 1.00 40.00 N
+ATOM 250 CA THR A 49 -25.672 13.207 47.045 1.00 40.00 C
+ATOM 251 C THR A 49 -25.827 14.275 48.159 1.00 40.00 C
+ATOM 252 O THR A 49 -26.760 15.104 48.119 1.00 40.00 O
+ATOM 253 CB THR A 49 -24.658 13.706 45.963 1.00 40.00 C
+ATOM 254 OG1 THR A 49 -25.212 14.791 45.208 1.00 40.00 O
+ATOM 255 CG2 THR A 49 -24.258 12.608 45.001 1.00 40.00 C
+ATOM 256 N GLY A 50 -24.925 14.246 49.150 1.00 40.00 N
+ATOM 257 CA GLY A 50 -24.826 15.302 50.191 1.00 40.00 C
+ATOM 258 C GLY A 50 -24.474 16.671 49.608 1.00 40.00 C
+ATOM 259 O GLY A 50 -24.331 16.813 48.387 1.00 40.00 O
+ATOM 260 N ASP A 51 -24.336 17.692 50.450 1.00 40.00 N
+ATOM 261 CA ASP A 51 -24.119 19.048 49.917 1.00 40.00 C
+ATOM 262 C ASP A 51 -22.654 19.324 49.611 1.00 40.00 C
+ATOM 263 O ASP A 51 -22.311 20.122 48.725 1.00 40.00 O
+ATOM 264 CB ASP A 51 -24.703 20.088 50.863 1.00 40.00 C
+ATOM 265 CG ASP A 51 -26.211 20.175 50.759 1.00 40.00 C
+ATOM 266 OD1 ASP A 51 -26.905 19.754 51.714 1.00 40.00 O
+ATOM 267 OD2 ASP A 51 -26.699 20.651 49.706 1.00 40.00 O
+ATOM 268 N ASP A 52 -21.808 18.624 50.357 1.00 40.00 N
+ATOM 269 CA ASP A 52 -20.368 18.673 50.201 1.00 40.00 C
+ATOM 270 C ASP A 52 -19.892 17.891 48.971 1.00 40.00 C
+ATOM 271 O ASP A 52 -18.757 18.073 48.514 1.00 40.00 O
+ATOM 272 CB ASP A 52 -19.698 18.150 51.478 1.00 40.00 C
+ATOM 273 CG ASP A 52 -20.384 16.909 52.048 1.00 40.00 C
+ATOM 274 OD1 ASP A 52 -21.637 16.813 52.034 1.00 40.00 O
+ATOM 275 OD2 ASP A 52 -19.648 16.030 52.535 1.00 40.00 O
+ATOM 276 N ALA A 53 -20.771 17.037 48.439 1.00 40.00 N
+ATOM 277 CA ALA A 53 -20.493 16.213 47.250 1.00 40.00 C
+ATOM 278 C ALA A 53 -19.982 16.975 46.023 1.00 40.00 C
+ATOM 279 O ALA A 53 -20.568 17.984 45.608 1.00 40.00 O
+ATOM 280 CB ALA A 53 -21.718 15.397 46.877 1.00 40.00 C
+ATOM 281 N PRO A 54 -18.885 16.478 45.434 1.00 40.00 N
+ATOM 282 CA PRO A 54 -18.259 17.121 44.284 1.00 40.00 C
+ATOM 283 C PRO A 54 -19.181 17.402 43.079 1.00 40.00 C
+ATOM 284 O PRO A 54 -19.044 18.441 42.428 1.00 40.00 O
+ATOM 285 CB PRO A 54 -17.130 16.140 43.902 1.00 40.00 C
+ATOM 286 CG PRO A 54 -17.359 14.899 44.711 1.00 40.00 C
+ATOM 287 CD PRO A 54 -18.076 15.354 45.938 1.00 40.00 C
+ATOM 288 N GLY A 55 -20.116 16.500 42.796 1.00 40.00 N
+ATOM 289 CA GLY A 55 -20.763 16.496 41.487 1.00 40.00 C
+ATOM 290 C GLY A 55 -22.252 16.748 41.411 1.00 40.00 C
+ATOM 291 O GLY A 55 -22.731 17.305 40.418 1.00 40.00 O
+ATOM 292 N GLU A 56 -22.985 16.328 42.443 1.00 40.00 N
+ATOM 293 CA GLU A 56 -24.454 16.432 42.468 1.00 40.00 C
+ATOM 294 C GLU A 56 -25.172 15.432 41.517 1.00 40.00 C
+ATOM 295 O GLU A 56 -25.052 15.505 40.284 1.00 40.00 O
+ATOM 296 CB GLU A 56 -24.912 17.888 42.236 1.00 40.00 C
+ATOM 297 CG GLU A 56 -26.414 18.093 42.298 1.00 40.00 C
+ATOM 298 CD GLU A 56 -26.820 19.539 42.179 1.00 40.00 C
+ATOM 299 OE1 GLU A 56 -26.457 20.334 43.065 1.00 40.00 O
+ATOM 300 OE2 GLU A 56 -27.520 19.867 41.207 1.00 40.00 O
+ATOM 301 N THR A 57 -25.931 14.515 42.119 1.00 40.00 N
+ATOM 302 CA THR A 57 -26.616 13.446 41.399 1.00 40.00 C
+ATOM 303 C THR A 57 -28.043 13.255 41.921 1.00 40.00 C
+ATOM 304 O THR A 57 -28.260 13.062 43.114 1.00 40.00 O
+ATOM 305 CB THR A 57 -25.803 12.142 41.502 1.00 40.00 C
+ATOM 306 OG1 THR A 57 -24.613 12.272 40.718 1.00 40.00 O
+ATOM 307 CG2 THR A 57 -26.590 10.956 41.008 1.00 40.00 C
+ATOM 308 N TRP A 58 -29.004 13.307 41.004 1.00 40.00 N
+ATOM 309 CA TRP A 58 -30.434 13.245 41.326 1.00 40.00 C
+ATOM 310 C TRP A 58 -31.092 11.933 40.947 1.00 40.00 C
+ATOM 311 O TRP A 58 -30.743 11.335 39.923 1.00 40.00 O
+ATOM 312 CB TRP A 58 -31.155 14.372 40.595 1.00 40.00 C
+ATOM 313 CG TRP A 58 -30.775 15.755 41.046 1.00 40.00 C
+ATOM 314 CD1 TRP A 58 -29.567 16.415 40.844 1.00 40.00 C
+ATOM 315 CD2 TRP A 58 -31.608 16.703 41.794 1.00 40.00 C
+ATOM 316 NE1 TRP A 58 -29.598 17.670 41.396 1.00 40.00 N
+ATOM 317 CE2 TRP A 58 -30.791 17.903 41.983 1.00 40.00 C
+ATOM 318 CE3 TRP A 58 -32.898 16.677 42.304 1.00 40.00 C
+ATOM 319 CZ2 TRP A 58 -31.266 19.011 42.654 1.00 40.00 C
+ATOM 320 CZ3 TRP A 58 -33.366 17.799 42.984 1.00 40.00 C
+ATOM 321 CH2 TRP A 58 -32.571 18.939 43.153 1.00 40.00 C
+ATOM 322 N HIS A 59 -32.068 11.481 41.743 1.00 40.00 N
+ATOM 323 CA HIS A 59 -32.878 10.310 41.378 1.00 40.00 C
+ATOM 324 C HIS A 59 -34.281 10.627 40.983 1.00 40.00 C
+ATOM 325 O HIS A 59 -35.088 11.090 41.798 1.00 40.00 O
+ATOM 326 CB HIS A 59 -32.942 9.314 42.493 1.00 40.00 C
+ATOM 327 CG HIS A 59 -33.793 8.133 42.160 1.00 40.00 C
+ATOM 328 ND1 HIS A 59 -33.340 7.113 41.424 1.00 40.00 N
+ATOM 329 CD2 HIS A 59 -35.113 7.849 42.457 1.00 40.00 C
+ATOM 330 CE1 HIS A 59 -34.306 6.200 41.283 1.00 40.00 C
+ATOM 331 NE2 HIS A 59 -35.393 6.652 41.913 1.00 40.00 N
+ATOM 332 N MET A 60 -34.603 10.320 39.737 1.00 40.00 N
+ATOM 333 CA MET A 60 -35.849 10.782 39.170 1.00 40.00 C
+ATOM 334 C MET A 60 -36.703 9.667 38.610 1.00 40.00 C
+ATOM 335 O MET A 60 -36.186 8.702 38.054 1.00 40.00 O
+ATOM 336 CB MET A 60 -35.592 11.852 38.110 1.00 40.00 C
+ATOM 337 CG MET A 60 -34.631 11.461 37.002 1.00 40.00 C
+ATOM 338 SD MET A 60 -34.024 12.965 36.220 1.00 40.00 S
+ATOM 339 CE MET A 60 -32.764 13.417 37.401 1.00 40.00 C
+ATOM 340 N VAL A 61 -38.018 9.838 38.761 1.00 40.00 N
+ATOM 341 CA VAL A 61 -39.025 8.875 38.324 1.00 40.00 C
+ATOM 342 C VAL A 61 -40.008 9.534 37.337 1.00 40.00 C
+ATOM 343 O VAL A 61 -40.361 10.707 37.491 1.00 40.00 O
+ATOM 344 CB VAL A 61 -39.796 8.278 39.531 1.00 40.00 C
+ATOM 345 CG1 VAL A 61 -40.247 6.862 39.218 1.00 40.00 C
+ATOM 346 CG2 VAL A 61 -38.928 8.259 40.786 1.00 40.00 C
+ATOM 347 N PHE A 62 -40.438 8.783 36.322 1.00 40.00 N
+ATOM 348 CA PHE A 62 -41.399 9.295 35.336 1.00 40.00 C
+ATOM 349 C PHE A 62 -42.632 8.416 35.114 1.00 40.00 C
+ATOM 350 O PHE A 62 -42.584 7.179 35.279 1.00 40.00 O
+ATOM 351 CB PHE A 62 -40.738 9.530 33.976 1.00 40.00 C
+ATOM 352 CG PHE A 62 -39.466 10.322 34.031 1.00 40.00 C
+ATOM 353 CD1 PHE A 62 -39.434 11.591 34.586 1.00 40.00 C
+ATOM 354 CD2 PHE A 62 -38.298 9.804 33.482 1.00 40.00 C
+ATOM 355 CE1 PHE A 62 -38.251 12.320 34.613 1.00 40.00 C
+ATOM 356 CE2 PHE A 62 -37.111 10.527 33.504 1.00 40.00 C
+ATOM 357 CZ PHE A 62 -37.087 11.788 34.071 1.00 40.00 C
+ATOM 358 N SER A 63 -43.720 9.080 34.713 1.00 40.00 N
+ATOM 359 CA SER A 63 -44.963 8.426 34.328 1.00 40.00 C
+ATOM 360 C SER A 63 -44.881 7.967 32.874 1.00 40.00 C
+ATOM 361 O SER A 63 -44.475 8.728 31.981 1.00 40.00 O
+ATOM 362 CB SER A 63 -46.127 9.389 34.494 1.00 40.00 C
+ATOM 363 OG SER A 63 -45.875 10.568 33.749 1.00 40.00 O
+ATOM 364 N THR A 64 -45.292 6.714 32.667 1.00 40.00 N
+ATOM 365 CA THR A 64 -45.090 5.974 31.416 1.00 40.00 C
+ATOM 366 C THR A 64 -46.394 5.421 30.855 1.00 40.00 C
+ATOM 367 O THR A 64 -46.471 5.081 29.676 1.00 40.00 O
+ATOM 368 CB THR A 64 -44.178 4.749 31.645 1.00 40.00 C
+ATOM 369 OG1 THR A 64 -44.864 3.776 32.443 1.00 40.00 O
+ATOM 370 CG2 THR A 64 -42.914 5.139 32.379 1.00 40.00 C
+ATOM 371 N GLU A 65 -47.399 5.326 31.730 1.00 40.00 N
+ATOM 372 CA GLU A 65 -48.696 4.680 31.462 1.00 40.00 C
+ATOM 373 C GLU A 65 -48.599 3.163 31.192 1.00 40.00 C
+ATOM 374 O GLU A 65 -49.466 2.597 30.527 1.00 40.00 O
+ATOM 375 CB GLU A 65 -49.451 5.382 30.329 1.00 40.00 C
+ATOM 376 CG GLU A 65 -49.692 6.869 30.531 1.00 40.00 C
+ATOM 377 CD GLU A 65 -50.340 7.504 29.309 1.00 40.00 C
+ATOM 378 OE1 GLU A 65 -51.537 7.226 29.062 1.00 40.00 O
+ATOM 379 OE2 GLU A 65 -49.658 8.276 28.588 1.00 40.00 O
+ATOM 380 N GLY A 66 -47.560 2.510 31.719 1.00 40.00 N
+ATOM 381 CA GLY A 66 -47.309 1.087 31.443 1.00 40.00 C
+ATOM 382 C GLY A 66 -46.930 0.849 29.990 1.00 40.00 C
+ATOM 383 O GLY A 66 -46.709 -0.298 29.569 1.00 40.00 O
+ATOM 384 N LYS A 67 -46.842 1.958 29.244 1.00 40.00 N
+ATOM 385 CA LYS A 67 -46.648 1.973 27.779 1.00 40.00 C
+ATOM 386 C LYS A 67 -45.213 1.614 27.318 1.00 40.00 C
+ATOM 387 O LYS A 67 -44.925 1.554 26.100 1.00 40.00 O
+ATOM 388 CB LYS A 67 -47.116 3.324 27.173 1.00 40.00 C
+ATOM 389 CG LYS A 67 -48.639 3.472 27.026 1.00 40.00 C
+ATOM 390 CD LYS A 67 -49.052 4.687 26.184 1.00 40.00 C
+ATOM 391 CE LYS A 67 -50.562 4.731 25.952 1.00 40.00 C
+ATOM 392 NZ LYS A 67 -50.995 5.959 25.222 1.00 40.00 N
+ATOM 393 N ILE A 68 -44.325 1.383 28.289 1.00 40.00 N
+ATOM 394 CA ILE A 68 -42.946 1.039 27.993 1.00 40.00 C
+ATOM 395 C ILE A 68 -42.532 -0.130 28.856 1.00 40.00 C
+ATOM 396 O ILE A 68 -41.862 0.072 29.858 1.00 40.00 O
+ATOM 397 CB ILE A 68 -41.987 2.225 28.214 1.00 40.00 C
+ATOM 398 CG1 ILE A 68 -42.425 3.445 27.375 1.00 40.00 C
+ATOM 399 CG2 ILE A 68 -40.573 1.789 27.864 1.00 40.00 C
+ATOM 400 CD1 ILE A 68 -41.767 4.769 27.724 1.00 40.00 C
+ATOM 401 N PRO A 69 -42.935 -1.360 28.467 1.00 40.00 N
+ATOM 402 CA PRO A 69 -42.637 -2.574 29.235 1.00 40.00 C
+ATOM 403 C PRO A 69 -41.153 -2.886 29.178 1.00 40.00 C
+ATOM 404 O PRO A 69 -40.732 -3.803 28.469 1.00 40.00 O
+ATOM 405 CB PRO A 69 -43.440 -3.661 28.513 1.00 40.00 C
+ATOM 406 CG PRO A 69 -43.521 -3.179 27.109 1.00 40.00 C
+ATOM 407 CD PRO A 69 -43.632 -1.679 27.205 1.00 40.00 C
+ATOM 408 N TYR A 70 -40.374 -2.099 29.916 1.00 40.00 N
+ATOM 409 CA TYR A 70 -38.932 -2.248 29.950 1.00 40.00 C
+ATOM 410 C TYR A 70 -38.521 -3.405 30.817 1.00 40.00 C
+ATOM 411 O TYR A 70 -39.291 -3.900 31.639 1.00 40.00 O
+ATOM 412 CB TYR A 70 -38.248 -0.961 30.424 1.00 40.00 C
+ATOM 413 CG TYR A 70 -38.543 -0.511 31.851 1.00 40.00 C
+ATOM 414 CD1 TYR A 70 -37.698 -0.855 32.907 1.00 40.00 C
+ATOM 415 CD2 TYR A 70 -39.644 0.302 32.135 1.00 40.00 C
+ATOM 416 CE1 TYR A 70 -37.958 -0.421 34.204 1.00 40.00 C
+ATOM 417 CE2 TYR A 70 -39.911 0.739 33.428 1.00 40.00 C
+ATOM 418 CZ TYR A 70 -39.067 0.380 34.456 1.00 40.00 C
+ATOM 419 OH TYR A 70 -39.345 0.822 35.732 1.00 40.00 O
+ATOM 420 N ARG A 71 -37.290 -3.834 30.622 1.00 40.00 N
+ATOM 421 CA ARG A 71 -36.788 -4.906 31.416 1.00 40.00 C
+ATOM 422 C ARG A 71 -35.400 -4.586 31.972 1.00 40.00 C
+ATOM 423 O ARG A 71 -34.612 -3.855 31.350 1.00 40.00 O
+ATOM 424 CB ARG A 71 -36.835 -6.212 30.626 1.00 40.00 C
+ATOM 425 CG ARG A 71 -37.151 -7.440 31.477 1.00 40.00 C
+ATOM 426 CD ARG A 71 -38.593 -7.499 31.989 1.00 40.00 C
+ATOM 427 NE ARG A 71 -39.564 -7.907 30.961 1.00 40.00 N
+ATOM 428 CZ ARG A 71 -39.833 -9.170 30.595 1.00 40.00 C
+ATOM 429 NH1 ARG A 71 -39.198 -10.204 31.151 1.00 40.00 N
+ATOM 430 NH2 ARG A 71 -40.742 -9.409 29.646 1.00 40.00 N
+ATOM 431 N GLU A 72 -35.148 -5.133 33.167 1.00 40.00 N
+ATOM 432 CA GLU A 72 -33.984 -4.850 34.010 1.00 40.00 C
+ATOM 433 C GLU A 72 -32.664 -4.822 33.253 1.00 40.00 C
+ATOM 434 O GLU A 72 -32.184 -5.860 32.796 1.00 40.00 O
+ATOM 435 CB GLU A 72 -33.909 -5.874 35.151 1.00 40.00 C
+ATOM 436 CG GLU A 72 -34.974 -5.723 36.237 1.00 40.00 C
+ATOM 437 CD GLU A 72 -36.307 -6.390 35.907 1.00 40.00 C
+ATOM 438 OE1 GLU A 72 -36.381 -7.150 34.918 1.00 40.00 O
+ATOM 439 OE2 GLU A 72 -37.294 -6.163 36.649 1.00 40.00 O
+ATOM 440 N GLY A 73 -32.090 -3.628 33.120 1.00 40.00 N
+ATOM 441 CA GLY A 73 -30.760 -3.483 32.542 1.00 40.00 C
+ATOM 442 C GLY A 73 -30.753 -2.563 31.359 1.00 40.00 C
+ATOM 443 O GLY A 73 -29.710 -2.106 30.888 1.00 40.00 O
+ATOM 444 N GLN A 74 -31.942 -2.286 30.878 1.00 40.00 N
+ATOM 445 CA GLN A 74 -32.066 -1.431 29.740 1.00 40.00 C
+ATOM 446 C GLN A 74 -31.752 0.006 30.134 1.00 40.00 C
+ATOM 447 O GLN A 74 -31.291 0.275 31.245 1.00 40.00 O
+ATOM 448 CB GLN A 74 -33.454 -1.578 29.124 1.00 40.00 C
+ATOM 449 CG GLN A 74 -33.702 -2.957 28.517 1.00 40.00 C
+ATOM 450 CD GLN A 74 -35.029 -3.062 27.790 1.00 40.00 C
+ATOM 451 OE1 GLN A 74 -36.094 -3.173 28.407 1.00 40.00 O
+ATOM 452 NE2 GLN A 74 -34.968 -3.039 26.464 1.00 40.00 N
+ATOM 453 N SER A 75 -31.998 0.921 29.208 1.00 40.00 N
+ATOM 454 CA SER A 75 -31.564 2.287 29.334 1.00 40.00 C
+ATOM 455 C SER A 75 -32.503 3.069 28.459 1.00 40.00 C
+ATOM 456 O SER A 75 -33.016 2.531 27.491 1.00 40.00 O
+ATOM 457 CB SER A 75 -30.145 2.404 28.774 1.00 40.00 C
+ATOM 458 OG SER A 75 -29.446 1.152 28.823 1.00 40.00 O
+ATOM 459 N ILE A 76 -32.737 4.333 28.764 1.00 40.00 N
+ATOM 460 CA ILE A 76 -33.582 5.116 27.866 1.00 40.00 C
+ATOM 461 C ILE A 76 -32.987 6.420 27.366 1.00 40.00 C
+ATOM 462 O ILE A 76 -31.976 6.922 27.874 1.00 40.00 O
+ATOM 463 CB ILE A 76 -34.985 5.384 28.439 1.00 40.00 C
+ATOM 464 CG1 ILE A 76 -34.904 6.188 29.731 1.00 40.00 C
+ATOM 465 CG2 ILE A 76 -35.734 4.084 28.648 1.00 40.00 C
+ATOM 466 CD1 ILE A 76 -36.182 6.935 30.059 1.00 40.00 C
+ATOM 467 N GLY A 77 -33.654 6.959 26.356 1.00 40.00 N
+ATOM 468 CA GLY A 77 -33.234 8.179 25.712 1.00 40.00 C
+ATOM 469 C GLY A 77 -34.017 9.371 26.197 1.00 40.00 C
+ATOM 470 O GLY A 77 -35.193 9.273 26.550 1.00 40.00 O
+ATOM 471 N VAL A 78 -33.335 10.505 26.214 1.00 40.00 N
+ATOM 472 CA VAL A 78 -33.906 11.744 26.675 1.00 40.00 C
+ATOM 473 C VAL A 78 -33.591 12.832 25.662 1.00 40.00 C
+ATOM 474 O VAL A 78 -32.420 13.150 25.391 1.00 40.00 O
+ATOM 475 CB VAL A 78 -33.358 12.145 28.065 1.00 40.00 C
+ATOM 476 CG1 VAL A 78 -33.909 13.507 28.478 1.00 40.00 C
+ATOM 477 CG2 VAL A 78 -33.709 11.096 29.116 1.00 40.00 C
+ATOM 478 N ILE A 79 -34.661 13.376 25.091 1.00 40.00 N
+ATOM 479 CA ILE A 79 -34.580 14.580 24.271 1.00 40.00 C
+ATOM 480 C ILE A 79 -34.788 15.791 25.173 1.00 40.00 C
+ATOM 481 O ILE A 79 -35.906 16.045 25.671 1.00 40.00 O
+ATOM 482 CB ILE A 79 -35.621 14.597 23.124 1.00 40.00 C
+ATOM 483 CG1 ILE A 79 -35.448 13.361 22.215 1.00 40.00 C
+ATOM 484 CG2 ILE A 79 -35.524 15.914 22.347 1.00 40.00 C
+ATOM 485 CD1 ILE A 79 -36.684 12.946 21.435 1.00 40.00 C
+ATOM 486 N ALA A 80 -33.687 16.513 25.384 1.00 40.00 N
+ATOM 487 CA ALA A 80 -33.678 17.749 26.175 1.00 40.00 C
+ATOM 488 C ALA A 80 -34.479 18.867 25.493 1.00 40.00 C
+ATOM 489 O ALA A 80 -34.510 18.977 24.250 1.00 40.00 O
+ATOM 490 CB ALA A 80 -32.243 18.203 26.469 1.00 40.00 C
+ATOM 491 N ASP A 81 -35.138 19.677 26.321 1.00 40.00 N
+ATOM 492 CA ASP A 81 -35.970 20.754 25.819 1.00 40.00 C
+ATOM 493 C ASP A 81 -35.108 21.891 25.296 1.00 40.00 C
+ATOM 494 O ASP A 81 -34.049 22.214 25.866 1.00 40.00 O
+ATOM 495 CB ASP A 81 -36.970 21.232 26.880 1.00 40.00 C
+ATOM 496 CG ASP A 81 -38.255 20.401 26.888 1.00 40.00 C
+ATOM 497 OD1 ASP A 81 -38.262 19.276 26.330 1.00 40.00 O
+ATOM 498 OD2 ASP A 81 -39.267 20.875 27.451 1.00 40.00 O
+ATOM 499 N GLY A 82 -35.569 22.472 24.190 1.00 40.00 N
+ATOM 500 CA GLY A 82 -34.833 23.508 23.487 1.00 40.00 C
+ATOM 501 C GLY A 82 -34.290 22.996 22.171 1.00 40.00 C
+ATOM 502 O GLY A 82 -34.594 21.870 21.739 1.00 40.00 O
+ATOM 503 N VAL A 83 -33.485 23.839 21.535 1.00 40.00 N
+ATOM 504 CA VAL A 83 -32.905 23.536 20.227 1.00 40.00 C
+ATOM 505 C VAL A 83 -31.386 23.798 20.223 1.00 40.00 C
+ATOM 506 O VAL A 83 -30.876 24.560 21.064 1.00 40.00 O
+ATOM 507 CB VAL A 83 -33.655 24.261 19.053 1.00 40.00 C
+ATOM 508 CG1 VAL A 83 -35.043 23.648 18.824 1.00 40.00 C
+ATOM 509 CG2 VAL A 83 -33.746 25.777 19.262 1.00 40.00 C
+ATOM 510 N ASP A 84 -30.668 23.138 19.307 1.00 40.00 N
+ATOM 511 CA ASP A 84 -29.243 23.408 19.089 1.00 40.00 C
+ATOM 512 C ASP A 84 -29.095 24.738 18.338 1.00 40.00 C
+ATOM 513 O ASP A 84 -30.096 25.440 18.107 1.00 40.00 O
+ATOM 514 CB ASP A 84 -28.555 22.244 18.344 1.00 40.00 C
+ATOM 515 CG ASP A 84 -29.096 22.025 16.935 1.00 40.00 C
+ATOM 516 OD1 ASP A 84 -28.631 21.099 16.258 1.00 40.00 O
+ATOM 517 OD2 ASP A 84 -29.980 22.766 16.487 1.00 40.00 O
+ATOM 518 N LYS A 85 -27.864 25.084 17.957 1.00 40.00 N
+ATOM 519 CA LYS A 85 -27.621 26.282 17.146 1.00 40.00 C
+ATOM 520 C LYS A 85 -28.473 26.388 15.855 1.00 40.00 C
+ATOM 521 O LYS A 85 -28.785 27.511 15.407 1.00 40.00 O
+ATOM 522 CB LYS A 85 -26.147 26.380 16.790 1.00 40.00 C
+ATOM 523 CG LYS A 85 -25.591 25.135 16.115 1.00 40.00 C
+ATOM 524 CD LYS A 85 -24.194 25.391 15.588 1.00 40.00 C
+ATOM 525 CE LYS A 85 -23.360 26.152 16.612 1.00 40.00 C
+ATOM 526 NZ LYS A 85 -23.672 25.752 18.019 1.00 40.00 N
+ATOM 527 N ASN A 86 -28.851 25.228 15.287 1.00 40.00 N
+ATOM 528 CA ASN A 86 -29.528 25.119 13.963 1.00 40.00 C
+ATOM 529 C ASN A 86 -31.074 25.049 13.961 1.00 40.00 C
+ATOM 530 O ASN A 86 -31.683 24.652 12.947 1.00 40.00 O
+ATOM 531 CB ASN A 86 -28.973 23.914 13.184 1.00 40.00 C
+ATOM 532 CG ASN A 86 -27.496 24.057 12.830 1.00 40.00 C
+ATOM 533 OD1 ASN A 86 -26.940 23.182 12.170 1.00 40.00 O
+ATOM 534 ND2 ASN A 86 -26.856 25.147 13.257 1.00 40.00 N
+ATOM 535 N GLY A 87 -31.690 25.441 15.086 1.00 40.00 N
+ATOM 536 CA GLY A 87 -33.138 25.295 15.311 1.00 40.00 C
+ATOM 537 C GLY A 87 -33.572 23.838 15.505 1.00 40.00 C
+ATOM 538 O GLY A 87 -34.777 23.552 15.696 1.00 40.00 O
+ATOM 539 N LYS A 88 -32.582 22.927 15.467 1.00 40.00 N
+ATOM 540 CA LYS A 88 -32.770 21.461 15.542 1.00 40.00 C
+ATOM 541 C LYS A 88 -32.750 20.935 16.979 1.00 40.00 C
+ATOM 542 O LYS A 88 -32.002 21.463 17.816 1.00 40.00 O
+ATOM 543 CB LYS A 88 -31.682 20.740 14.738 1.00 40.00 C
+ATOM 544 CG LYS A 88 -31.854 20.847 13.238 1.00 40.00 C
+ATOM 545 CD LYS A 88 -30.580 20.423 12.547 1.00 40.00 C
+ATOM 546 CE LYS A 88 -30.614 20.780 11.076 1.00 40.00 C
+ATOM 547 NZ LYS A 88 -29.401 20.226 10.412 1.00 40.00 N
+ATOM 548 N PRO A 89 -33.551 19.873 17.265 1.00 40.00 N
+ATOM 549 CA PRO A 89 -33.560 19.337 18.638 1.00 40.00 C
+ATOM 550 C PRO A 89 -32.130 19.033 19.111 1.00 40.00 C
+ATOM 551 O PRO A 89 -31.192 18.976 18.297 1.00 40.00 O
+ATOM 552 CB PRO A 89 -34.381 18.036 18.523 1.00 40.00 C
+ATOM 553 CG PRO A 89 -35.116 18.116 17.223 1.00 40.00 C
+ATOM 554 CD PRO A 89 -34.361 19.059 16.327 1.00 40.00 C
+ATOM 555 N HIS A 90 -31.957 18.865 20.417 1.00 40.00 N
+ATOM 556 CA HIS A 90 -30.689 18.342 20.936 1.00 40.00 C
+ATOM 557 C HIS A 90 -30.642 16.854 20.637 1.00 40.00 C
+ATOM 558 O HIS A 90 -31.658 16.255 20.244 1.00 40.00 O
+ATOM 559 CB HIS A 90 -30.518 18.644 22.437 1.00 40.00 C
+ATOM 560 CG HIS A 90 -30.581 20.127 22.779 1.00 40.00 C
+ATOM 561 ND1 HIS A 90 -29.625 21.003 22.399 1.00 40.00 N
+ATOM 562 CD2 HIS A 90 -31.538 20.873 23.483 1.00 40.00 C
+ATOM 563 CE1 HIS A 90 -29.949 22.245 22.831 1.00 40.00 C
+ATOM 564 NE2 HIS A 90 -31.120 22.165 23.493 1.00 40.00 N
+ATOM 565 N LYS A 91 -29.473 16.234 20.796 1.00 40.00 N
+ATOM 566 CA LYS A 91 -29.331 14.806 20.482 1.00 40.00 C
+ATOM 567 C LYS A 91 -29.667 13.918 21.692 1.00 40.00 C
+ATOM 568 O LYS A 91 -29.379 14.267 22.838 1.00 40.00 O
+ATOM 569 CB LYS A 91 -27.929 14.515 19.914 1.00 40.00 C
+ATOM 570 CG LYS A 91 -27.882 13.452 18.813 1.00 40.00 C
+ATOM 571 CD LYS A 91 -28.185 13.974 17.411 1.00 40.00 C
+ATOM 572 CE LYS A 91 -26.907 14.289 16.635 1.00 40.00 C
+ATOM 573 NZ LYS A 91 -27.166 15.339 15.604 1.00 40.00 N
+ATOM 574 N VAL A 92 -30.307 12.786 21.416 1.00 40.00 N
+ATOM 575 CA VAL A 92 -30.689 11.803 22.429 1.00 40.00 C
+ATOM 576 C VAL A 92 -29.541 11.474 23.366 1.00 40.00 C
+ATOM 577 O VAL A 92 -28.484 11.042 22.928 1.00 40.00 O
+ATOM 578 CB VAL A 92 -31.156 10.494 21.760 1.00 40.00 C
+ATOM 579 CG1 VAL A 92 -31.308 9.366 22.770 1.00 40.00 C
+ATOM 580 CG2 VAL A 92 -32.464 10.722 21.036 1.00 40.00 C
+ATOM 581 N ARG A 93 -29.736 11.689 24.656 1.00 40.00 N
+ATOM 582 CA ARG A 93 -28.787 11.168 25.618 1.00 40.00 C
+ATOM 583 C ARG A 93 -29.381 9.936 26.265 1.00 40.00 C
+ATOM 584 O ARG A 93 -30.591 9.826 26.421 1.00 40.00 O
+ATOM 585 CB ARG A 93 -28.426 12.213 26.668 1.00 40.00 C
+ATOM 586 CG ARG A 93 -27.177 13.021 26.352 1.00 40.00 C
+ATOM 587 CD ARG A 93 -27.400 13.906 25.150 1.00 40.00 C
+ATOM 588 NE ARG A 93 -26.626 15.133 25.226 1.00 40.00 N
+ATOM 589 CZ ARG A 93 -26.703 16.119 24.338 1.00 40.00 C
+ATOM 590 NH1 ARG A 93 -27.517 16.021 23.289 1.00 40.00 N
+ATOM 591 NH2 ARG A 93 -25.963 17.211 24.499 1.00 40.00 N
+ATOM 592 N LEU A 94 -28.529 9.001 26.643 1.00 40.00 N
+ATOM 593 CA LEU A 94 -29.027 7.768 27.204 1.00 40.00 C
+ATOM 594 C LEU A 94 -28.708 7.629 28.673 1.00 40.00 C
+ATOM 595 O LEU A 94 -27.617 7.998 29.129 1.00 40.00 O
+ATOM 596 CB LEU A 94 -28.463 6.587 26.439 1.00 40.00 C
+ATOM 597 CG LEU A 94 -28.893 6.493 24.976 1.00 40.00 C
+ATOM 598 CD1 LEU A 94 -28.234 5.277 24.332 1.00 40.00 C
+ATOM 599 CD2 LEU A 94 -30.406 6.428 24.827 1.00 40.00 C
+ATOM 600 N TYR A 95 -29.680 7.099 29.409 1.00 40.00 N
+ATOM 601 CA TYR A 95 -29.533 6.926 30.843 1.00 40.00 C
+ATOM 602 C TYR A 95 -30.029 5.551 31.267 1.00 40.00 C
+ATOM 603 O TYR A 95 -31.121 5.129 30.892 1.00 40.00 O
+ATOM 604 CB TYR A 95 -30.274 8.062 31.574 1.00 40.00 C
+ATOM 605 CG TYR A 95 -29.678 9.428 31.276 1.00 40.00 C
+ATOM 606 CD1 TYR A 95 -28.523 9.869 31.947 1.00 40.00 C
+ATOM 607 CD2 TYR A 95 -30.238 10.261 30.301 1.00 40.00 C
+ATOM 608 CE1 TYR A 95 -27.957 11.108 31.666 1.00 40.00 C
+ATOM 609 CE2 TYR A 95 -29.678 11.501 30.017 1.00 40.00 C
+ATOM 610 CZ TYR A 95 -28.536 11.915 30.700 1.00 40.00 C
+ATOM 611 OH TYR A 95 -27.951 13.132 30.436 1.00 40.00 O
+ATOM 612 N SER A 96 -29.188 4.852 32.030 1.00 40.00 N
+ATOM 613 CA SER A 96 -29.441 3.478 32.434 1.00 40.00 C
+ATOM 614 C SER A 96 -30.620 3.475 33.347 1.00 40.00 C
+ATOM 615 O SER A 96 -30.680 4.268 34.269 1.00 40.00 O
+ATOM 616 CB SER A 96 -28.242 2.913 33.186 1.00 40.00 C
+ATOM 617 OG SER A 96 -27.015 3.360 32.632 1.00 40.00 O
+ATOM 618 N ILE A 97 -31.561 2.578 33.097 1.00 40.00 N
+ATOM 619 CA ILE A 97 -32.782 2.575 33.869 1.00 40.00 C
+ATOM 620 C ILE A 97 -32.546 2.089 35.280 1.00 40.00 C
+ATOM 621 O ILE A 97 -32.032 0.990 35.500 1.00 40.00 O
+ATOM 622 CB ILE A 97 -33.883 1.756 33.198 1.00 40.00 C
+ATOM 623 CG1 ILE A 97 -34.219 2.376 31.841 1.00 40.00 C
+ATOM 624 CG2 ILE A 97 -35.114 1.715 34.091 1.00 40.00 C
+ATOM 625 CD1 ILE A 97 -34.996 1.463 30.933 1.00 40.00 C
+ATOM 626 N ALA A 98 -32.951 2.928 36.224 1.00 40.00 N
+ATOM 627 CA ALA A 98 -32.674 2.712 37.625 1.00 40.00 C
+ATOM 628 C ALA A 98 -33.733 1.884 38.321 1.00 40.00 C
+ATOM 629 O ALA A 98 -33.386 1.093 39.192 1.00 40.00 O
+ATOM 630 CB ALA A 98 -32.493 4.042 38.330 1.00 40.00 C
+ATOM 631 N SER A 99 -35.009 2.059 37.957 1.00 40.00 N
+ATOM 632 CA SER A 99 -36.078 1.250 38.572 1.00 40.00 C
+ATOM 633 C SER A 99 -36.173 -0.154 37.983 1.00 40.00 C
+ATOM 634 O SER A 99 -35.708 -0.389 36.876 1.00 40.00 O
+ATOM 635 CB SER A 99 -37.439 1.950 38.506 1.00 40.00 C
+ATOM 636 OG SER A 99 -37.670 2.505 37.233 1.00 40.00 O
+ATOM 637 N SER A 100 -36.767 -1.084 38.728 1.00 40.00 N
+ATOM 638 CA SER A 100 -37.017 -2.428 38.218 1.00 40.00 C
+ATOM 639 C SER A 100 -38.166 -2.382 37.222 1.00 40.00 C
+ATOM 640 O SER A 100 -38.791 -1.351 37.052 1.00 40.00 O
+ATOM 641 CB SER A 100 -37.387 -3.366 39.357 1.00 40.00 C
+ATOM 642 OG SER A 100 -38.731 -3.151 39.748 1.00 40.00 O
+ATOM 643 N ALA A 101 -38.464 -3.506 36.587 1.00 40.00 N
+ATOM 644 CA ALA A 101 -39.560 -3.574 35.631 1.00 40.00 C
+ATOM 645 C ALA A 101 -40.817 -2.937 36.207 1.00 40.00 C
+ATOM 646 O ALA A 101 -41.525 -2.174 35.545 1.00 40.00 O
+ATOM 647 CB ALA A 101 -39.829 -5.026 35.256 1.00 40.00 C
+ATOM 648 N ILE A 102 -41.054 -3.239 37.472 1.00 40.00 N
+ATOM 649 CA ILE A 102 -42.299 -2.917 38.129 1.00 40.00 C
+ATOM 650 C ILE A 102 -42.355 -1.438 38.499 1.00 40.00 C
+ATOM 651 O ILE A 102 -43.403 -0.918 38.896 1.00 40.00 O
+ATOM 652 CB ILE A 102 -42.472 -3.800 39.381 1.00 40.00 C
+ATOM 653 CG1 ILE A 102 -41.786 -5.167 39.177 1.00 40.00 C
+ATOM 654 CG2 ILE A 102 -43.949 -3.957 39.721 1.00 40.00 C
+ATOM 655 CD1 ILE A 102 -42.319 -6.004 38.026 1.00 40.00 C
+ATOM 656 N GLY A 103 -41.219 -0.764 38.345 1.00 40.00 N
+ATOM 657 CA GLY A 103 -41.067 0.630 38.746 1.00 40.00 C
+ATOM 658 C GLY A 103 -40.758 0.734 40.222 1.00 40.00 C
+ATOM 659 O GLY A 103 -40.701 -0.274 40.947 1.00 40.00 O
+ATOM 660 N ASP A 104 -40.554 1.962 40.672 1.00 40.00 N
+ATOM 661 CA ASP A 104 -40.362 2.218 42.095 1.00 40.00 C
+ATOM 662 C ASP A 104 -41.646 2.044 42.909 1.00 40.00 C
+ATOM 663 O ASP A 104 -41.615 1.767 44.112 1.00 40.00 O
+ATOM 664 CB ASP A 104 -39.807 3.623 42.301 1.00 40.00 C
+ATOM 665 CG ASP A 104 -38.379 3.741 41.857 1.00 40.00 C
+ATOM 666 OD1 ASP A 104 -37.629 2.735 41.974 1.00 40.00 O
+ATOM 667 OD2 ASP A 104 -38.015 4.846 41.398 1.00 40.00 O
+ATOM 668 N PHE A 105 -42.782 2.210 42.251 1.00 40.00 N
+ATOM 669 CA PHE A 105 -44.036 2.109 42.953 1.00 40.00 C
+ATOM 670 C PHE A 105 -44.558 0.697 42.851 1.00 40.00 C
+ATOM 671 O PHE A 105 -45.513 0.355 43.526 1.00 40.00 O
+ATOM 672 CB PHE A 105 -45.046 3.121 42.414 1.00 40.00 C
+ATOM 673 CG PHE A 105 -44.503 4.518 42.311 1.00 40.00 C
+ATOM 674 CD1 PHE A 105 -43.559 4.986 43.233 1.00 40.00 C
+ATOM 675 CD2 PHE A 105 -44.938 5.379 41.303 1.00 40.00 C
+ATOM 676 CE1 PHE A 105 -43.049 6.280 43.137 1.00 40.00 C
+ATOM 677 CE2 PHE A 105 -44.437 6.676 41.201 1.00 40.00 C
+ATOM 678 CZ PHE A 105 -43.492 7.130 42.118 1.00 40.00 C
+ATOM 679 N GLY A 106 -43.925 -0.126 42.018 1.00 40.00 N
+ATOM 680 CA GLY A 106 -44.315 -1.525 41.884 1.00 40.00 C
+ATOM 681 C GLY A 106 -45.626 -1.729 41.145 1.00 40.00 C
+ATOM 682 O GLY A 106 -46.351 -2.689 41.409 1.00 40.00 O
+ATOM 683 N ASP A 107 -45.917 -0.836 40.205 1.00 40.00 N
+ATOM 684 CA ASP A 107 -47.158 -0.895 39.444 1.00 40.00 C
+ATOM 685 C ASP A 107 -46.914 -0.878 37.932 1.00 40.00 C
+ATOM 686 O ASP A 107 -47.855 -0.914 37.157 1.00 40.00 O
+ATOM 687 CB ASP A 107 -48.078 0.264 39.848 1.00 40.00 C
+ATOM 688 CG ASP A 107 -47.636 1.607 39.256 1.00 40.00 C
+ATOM 689 OD1 ASP A 107 -46.415 1.871 39.206 1.00 40.00 O
+ATOM 690 OD2 ASP A 107 -48.511 2.401 38.839 1.00 40.00 O
+ATOM 691 N SER A 108 -45.649 -0.801 37.530 1.00 40.00 N
+ATOM 692 CA SER A 108 -45.237 -0.830 36.119 1.00 40.00 C
+ATOM 693 C SER A 108 -45.753 0.328 35.243 1.00 40.00 C
+ATOM 694 O SER A 108 -45.887 0.174 34.033 1.00 40.00 O
+ATOM 695 CB SER A 108 -45.573 -2.184 35.491 1.00 40.00 C
+ATOM 696 OG SER A 108 -44.964 -3.235 36.213 1.00 40.00 O
+ATOM 697 N LYS A 109 -46.022 1.480 35.858 1.00 40.00 N
+ATOM 698 CA LYS A 109 -46.450 2.704 35.149 1.00 40.00 C
+ATOM 699 C LYS A 109 -45.403 3.816 35.304 1.00 40.00 C
+ATOM 700 O LYS A 109 -45.703 5.018 35.218 1.00 40.00 O
+ATOM 701 CB LYS A 109 -47.790 3.192 35.709 1.00 40.00 C
+ATOM 702 CG LYS A 109 -48.906 2.154 35.719 1.00 40.00 C
+ATOM 703 CD LYS A 109 -49.242 1.651 34.318 1.00 40.00 C
+ATOM 704 CE LYS A 109 -50.562 0.893 34.262 1.00 40.00 C
+ATOM 705 NZ LYS A 109 -51.743 1.801 34.275 1.00 40.00 N
+ATOM 706 N THR A 110 -44.164 3.378 35.520 1.00 40.00 N
+ATOM 707 CA THR A 110 -43.132 4.200 36.133 1.00 40.00 C
+ATOM 708 C THR A 110 -41.740 3.770 35.740 1.00 40.00 C
+ATOM 709 O THR A 110 -41.391 2.581 35.825 1.00 40.00 O
+ATOM 710 CB THR A 110 -43.176 4.086 37.673 1.00 40.00 C
+ATOM 711 OG1 THR A 110 -42.773 2.762 38.086 1.00 40.00 O
+ATOM 712 CG2 THR A 110 -44.582 4.402 38.198 1.00 40.00 C
+ATOM 713 N VAL A 111 -40.942 4.758 35.352 1.00 40.00 N
+ATOM 714 CA VAL A 111 -39.539 4.547 35.046 1.00 40.00 C
+ATOM 715 C VAL A 111 -38.681 5.464 35.922 1.00 40.00 C
+ATOM 716 O VAL A 111 -39.092 6.584 36.201 1.00 40.00 O
+ATOM 717 CB VAL A 111 -39.270 4.819 33.558 1.00 40.00 C
+ATOM 718 CG1 VAL A 111 -39.332 6.304 33.259 1.00 40.00 C
+ATOM 719 CG2 VAL A 111 -37.935 4.229 33.131 1.00 40.00 C
+ATOM 720 N SER A 112 -37.500 4.993 36.344 1.00 40.00 N
+ATOM 721 CA SER A 112 -36.612 5.768 37.210 1.00 40.00 C
+ATOM 722 C SER A 112 -35.195 5.904 36.669 1.00 40.00 C
+ATOM 723 O SER A 112 -34.578 4.915 36.265 1.00 40.00 O
+ATOM 724 CB SER A 112 -36.581 5.142 38.589 1.00 40.00 C
+ATOM 725 OG SER A 112 -37.902 4.802 38.978 1.00 40.00 O
+ATOM 726 N LEU A 113 -34.700 7.146 36.678 1.00 40.00 N
+ATOM 727 CA LEU A 113 -33.350 7.495 36.226 1.00 40.00 C
+ATOM 728 C LEU A 113 -32.426 7.979 37.334 1.00 40.00 C
+ATOM 729 O LEU A 113 -32.875 8.519 38.340 1.00 40.00 O
+ATOM 730 CB LEU A 113 -33.423 8.601 35.188 1.00 40.00 C
+ATOM 731 CG LEU A 113 -33.742 8.182 33.763 1.00 40.00 C
+ATOM 732 CD1 LEU A 113 -33.598 9.386 32.853 1.00 40.00 C
+ATOM 733 CD2 LEU A 113 -32.802 7.078 33.325 1.00 40.00 C
+ATOM 734 N CYS A 114 -31.127 7.812 37.125 1.00 40.00 N
+ATOM 735 CA CYS A 114 -30.134 8.284 38.069 1.00 40.00 C
+ATOM 736 C CYS A 114 -29.172 9.188 37.325 1.00 40.00 C
+ATOM 737 O CYS A 114 -28.409 8.728 36.475 1.00 40.00 O
+ATOM 738 CB CYS A 114 -29.409 7.100 38.680 1.00 40.00 C
+ATOM 739 SG CYS A 114 -28.053 7.523 39.784 1.00 40.00 S
+ATOM 740 N VAL A 115 -29.225 10.479 37.626 1.00 40.00 N
+ATOM 741 CA VAL A 115 -28.500 11.460 36.823 1.00 40.00 C
+ATOM 742 C VAL A 115 -27.558 12.344 37.630 1.00 40.00 C
+ATOM 743 O VAL A 115 -27.969 13.010 38.587 1.00 40.00 O
+ATOM 744 CB VAL A 115 -29.450 12.373 36.020 1.00 40.00 C
+ATOM 745 CG1 VAL A 115 -28.696 13.063 34.888 1.00 40.00 C
+ATOM 746 CG2 VAL A 115 -30.614 11.582 35.463 1.00 40.00 C
+ATOM 747 N LYS A 116 -26.291 12.354 37.219 1.00 40.00 N
+ATOM 748 CA LYS A 116 -25.312 13.297 37.734 1.00 40.00 C
+ATOM 749 C LYS A 116 -25.303 14.521 36.826 1.00 40.00 C
+ATOM 750 O LYS A 116 -25.272 14.409 35.591 1.00 40.00 O
+ATOM 751 CB LYS A 116 -23.925 12.667 37.794 1.00 40.00 C
+ATOM 752 CG LYS A 116 -22.913 13.470 38.580 1.00 40.00 C
+ATOM 753 CD LYS A 116 -21.544 13.277 37.972 1.00 40.00 C
+ATOM 754 CE LYS A 116 -20.591 14.385 38.372 1.00 40.00 C
+ATOM 755 NZ LYS A 116 -19.921 14.036 39.646 1.00 40.00 N
+ATOM 756 N ARG A 117 -25.360 15.685 37.466 1.00 40.00 N
+ATOM 757 CA ARG A 117 -25.310 16.981 36.805 1.00 40.00 C
+ATOM 758 C ARG A 117 -23.893 17.241 36.254 1.00 40.00 C
+ATOM 759 O ARG A 117 -22.926 17.397 37.016 1.00 40.00 O
+ATOM 760 CB ARG A 117 -25.724 18.062 37.817 1.00 40.00 C
+ATOM 761 CG ARG A 117 -26.222 19.356 37.206 1.00 40.00 C
+ATOM 762 CD ARG A 117 -26.411 20.435 38.260 1.00 40.00 C
+ATOM 763 NE ARG A 117 -27.721 20.374 38.908 1.00 40.00 N
+ATOM 764 CZ ARG A 117 -28.829 20.947 38.438 1.00 40.00 C
+ATOM 765 NH1 ARG A 117 -28.806 21.629 37.299 1.00 40.00 N
+ATOM 766 NH2 ARG A 117 -29.968 20.835 39.110 1.00 40.00 N
+ATOM 767 N LEU A 118 -23.767 17.254 34.928 1.00 40.00 N
+ATOM 768 CA LEU A 118 -22.479 17.524 34.289 1.00 40.00 C
+ATOM 769 C LEU A 118 -22.130 19.002 34.438 1.00 40.00 C
+ATOM 770 O LEU A 118 -22.697 19.844 33.730 1.00 40.00 O
+ATOM 771 CB LEU A 118 -22.512 17.118 32.798 1.00 40.00 C
+ATOM 772 CG LEU A 118 -21.355 17.468 31.845 1.00 40.00 C
+ATOM 773 CD1 LEU A 118 -20.050 16.822 32.286 1.00 40.00 C
+ATOM 774 CD2 LEU A 118 -21.666 17.083 30.406 1.00 40.00 C
+ATOM 775 N ILE A 119 -21.237 19.320 35.381 1.00 40.00 N
+ATOM 776 CA ILE A 119 -20.637 20.668 35.454 1.00 40.00 C
+ATOM 777 C ILE A 119 -19.129 20.613 35.733 1.00 40.00 C
+ATOM 778 O ILE A 119 -18.690 20.060 36.746 1.00 40.00 O
+ATOM 779 CB ILE A 119 -21.336 21.634 36.455 1.00 40.00 C
+ATOM 780 CG1 ILE A 119 -22.827 21.824 36.124 1.00 40.00 C
+ATOM 781 CG2 ILE A 119 -20.641 22.992 36.423 1.00 40.00 C
+ATOM 782 CD1 ILE A 119 -23.622 22.615 37.146 1.00 40.00 C
+ATOM 783 N TYR A 120 -18.358 21.178 34.803 1.00 40.00 N
+ATOM 784 CA TYR A 120 -16.898 21.312 34.919 1.00 40.00 C
+ATOM 785 C TYR A 120 -16.486 22.749 34.631 1.00 40.00 C
+ATOM 786 O TYR A 120 -17.273 23.525 34.095 1.00 40.00 O
+ATOM 787 CB TYR A 120 -16.127 20.328 33.992 1.00 40.00 C
+ATOM 788 CG TYR A 120 -16.482 20.331 32.489 1.00 40.00 C
+ATOM 789 CD1 TYR A 120 -17.665 19.724 32.018 1.00 40.00 C
+ATOM 790 CD2 TYR A 120 -15.617 20.891 31.532 1.00 40.00 C
+ATOM 791 CE1 TYR A 120 -17.991 19.699 30.659 1.00 40.00 C
+ATOM 792 CE2 TYR A 120 -15.940 20.867 30.164 1.00 40.00 C
+ATOM 793 CZ TYR A 120 -17.128 20.265 29.732 1.00 40.00 C
+ATOM 794 OH TYR A 120 -17.481 20.224 28.390 1.00 40.00 O
+ATOM 795 N THR A 121 -15.264 23.097 35.025 1.00 40.00 N
+ATOM 796 CA THR A 121 -14.608 24.343 34.610 1.00 40.00 C
+ATOM 797 C THR A 121 -13.546 23.922 33.568 1.00 40.00 C
+ATOM 798 O THR A 121 -12.801 22.960 33.812 1.00 40.00 O
+ATOM 799 CB THR A 121 -14.024 25.127 35.848 1.00 40.00 C
+ATOM 800 OG1 THR A 121 -15.065 25.870 36.507 1.00 40.00 O
+ATOM 801 CG2 THR A 121 -12.909 26.121 35.477 1.00 40.00 C
+ATOM 802 N ASN A 122 -13.515 24.577 32.397 1.00 40.00 N
+ATOM 803 CA ASN A 122 -12.383 24.390 31.444 1.00 40.00 C
+ATOM 804 C ASN A 122 -11.133 25.248 31.785 1.00 40.00 C
+ATOM 805 O ASN A 122 -11.107 25.916 32.834 1.00 40.00 O
+ATOM 806 CB ASN A 122 -12.798 24.456 29.939 1.00 40.00 C
+ATOM 807 CG ASN A 122 -13.401 25.803 29.513 1.00 40.00 C
+ATOM 808 OD1 ASN A 122 -12.796 26.869 29.669 1.00 40.00 O
+ATOM 809 ND2 ASN A 122 -14.586 25.741 28.912 1.00 40.00 N
+ATOM 810 N ASP A 123 -10.105 25.215 30.925 1.00 40.00 N
+ATOM 811 CA ASP A 123 -8.842 25.962 31.178 1.00 40.00 C
+ATOM 812 C ASP A 123 -8.906 27.528 31.050 1.00 40.00 C
+ATOM 813 O ASP A 123 -7.963 28.247 31.453 1.00 40.00 O
+ATOM 814 CB ASP A 123 -7.632 25.339 30.423 1.00 40.00 C
+ATOM 815 CG ASP A 123 -7.922 25.017 28.942 1.00 40.00 C
+ATOM 816 OD1 ASP A 123 -8.986 25.411 28.394 1.00 40.00 O
+ATOM 817 OD2 ASP A 123 -7.046 24.360 28.326 1.00 40.00 O
+ATOM 818 N ALA A 124 -10.021 28.041 30.517 1.00 40.00 N
+ATOM 819 CA ALA A 124 -10.295 29.487 30.481 1.00 40.00 C
+ATOM 820 C ALA A 124 -11.108 30.011 31.708 1.00 40.00 C
+ATOM 821 O ALA A 124 -11.480 31.195 31.749 1.00 40.00 O
+ATOM 822 CB ALA A 124 -10.959 29.865 29.155 1.00 40.00 C
+ATOM 823 N GLY A 125 -11.349 29.135 32.700 1.00 40.00 N
+ATOM 824 CA GLY A 125 -12.114 29.457 33.926 1.00 40.00 C
+ATOM 825 C GLY A 125 -13.628 29.297 33.788 1.00 40.00 C
+ATOM 826 O GLY A 125 -14.375 29.486 34.768 1.00 40.00 O
+ATOM 827 N GLU A 126 -14.052 28.912 32.574 1.00 40.00 N
+ATOM 828 CA GLU A 126 -15.458 28.920 32.097 1.00 40.00 C
+ATOM 829 C GLU A 126 -16.289 27.700 32.509 1.00 40.00 C
+ATOM 830 O GLU A 126 -16.063 26.596 32.002 1.00 40.00 O
+ATOM 831 CB GLU A 126 -15.495 29.041 30.559 1.00 40.00 C
+ATOM 832 CG GLU A 126 -14.751 30.247 29.999 1.00 40.00 C
+ATOM 833 CD GLU A 126 -14.203 30.032 28.593 1.00 40.00 C
+ATOM 834 OE1 GLU A 126 -13.985 28.867 28.172 1.00 40.00 O
+ATOM 835 OE2 GLU A 126 -13.960 31.055 27.912 1.00 40.00 O
+ATOM 836 N ILE A 127 -17.258 27.922 33.406 1.00 40.00 N
+ATOM 837 CA ILE A 127 -18.194 26.882 33.880 1.00 40.00 C
+ATOM 838 C ILE A 127 -19.071 26.318 32.736 1.00 40.00 C
+ATOM 839 O ILE A 127 -19.987 26.998 32.234 1.00 40.00 O
+ATOM 840 CB ILE A 127 -19.036 27.368 35.107 1.00 40.00 C
+ATOM 841 CG1 ILE A 127 -18.186 27.333 36.389 1.00 40.00 C
+ATOM 842 CG2 ILE A 127 -20.310 26.546 35.298 1.00 40.00 C
+ATOM 843 CD1 ILE A 127 -18.945 27.614 37.674 1.00 40.00 C
+ATOM 844 N VAL A 128 -18.751 25.079 32.330 1.00 40.00 N
+ATOM 845 CA VAL A 128 -19.491 24.319 31.302 1.00 40.00 C
+ATOM 846 C VAL A 128 -20.505 23.383 31.972 1.00 40.00 C
+ATOM 847 O VAL A 128 -20.198 22.706 32.961 1.00 40.00 O
+ATOM 848 CB VAL A 128 -18.553 23.472 30.397 1.00 40.00 C
+ATOM 849 CG1 VAL A 128 -19.304 22.932 29.185 1.00 40.00 C
+ATOM 850 CG2 VAL A 128 -17.339 24.274 29.947 1.00 40.00 C
+ATOM 851 N LYS A 129 -21.714 23.361 31.421 1.00 40.00 N
+ATOM 852 CA LYS A 129 -22.788 22.508 31.928 1.00 40.00 C
+ATOM 853 C LYS A 129 -23.339 21.556 30.837 1.00 40.00 C
+ATOM 854 O LYS A 129 -23.557 21.965 29.685 1.00 40.00 O
+ATOM 855 CB LYS A 129 -23.926 23.366 32.503 1.00 40.00 C
+ATOM 856 CG LYS A 129 -23.519 24.435 33.513 1.00 40.00 C
+ATOM 857 CD LYS A 129 -24.732 25.009 34.254 1.00 40.00 C
+ATOM 858 CE LYS A 129 -25.698 25.765 33.340 1.00 40.00 C
+ATOM 859 NZ LYS A 129 -26.987 26.080 34.018 1.00 40.00 N
+ATOM 860 N GLY A 130 -23.569 20.295 31.204 1.00 40.00 N
+ATOM 861 CA GLY A 130 -24.160 19.319 30.286 1.00 40.00 C
+ATOM 862 C GLY A 130 -25.624 19.575 29.974 1.00 40.00 C
+ATOM 863 O GLY A 130 -26.442 19.695 30.883 1.00 40.00 O
+ATOM 864 N VAL A 131 -25.944 19.649 28.682 1.00 40.00 N
+ATOM 865 CA VAL A 131 -27.308 19.894 28.208 1.00 40.00 C
+ATOM 866 C VAL A 131 -28.322 18.985 28.914 1.00 40.00 C
+ATOM 867 O VAL A 131 -29.124 19.445 29.733 1.00 40.00 O
+ATOM 868 CB VAL A 131 -27.416 19.720 26.667 1.00 40.00 C
+ATOM 869 CG1 VAL A 131 -28.848 19.929 26.179 1.00 40.00 C
+ATOM 870 CG2 VAL A 131 -26.471 20.671 25.946 1.00 40.00 C
+ATOM 871 N CYS A 132 -28.266 17.694 28.612 1.00 40.00 N
+ATOM 872 CA CYS A 132 -29.274 16.755 29.085 1.00 40.00 C
+ATOM 873 C CYS A 132 -29.195 16.559 30.596 1.00 40.00 C
+ATOM 874 O CYS A 132 -30.220 16.564 31.274 1.00 40.00 O
+ATOM 875 CB CYS A 132 -29.141 15.419 28.356 1.00 40.00 C
+ATOM 876 SG CYS A 132 -30.708 14.639 27.945 1.00 40.00 S
+ATOM 877 N SER A 133 -27.976 16.420 31.119 1.00 40.00 N
+ATOM 878 CA SER A 133 -27.757 16.172 32.546 1.00 40.00 C
+ATOM 879 C SER A 133 -28.342 17.269 33.407 1.00 40.00 C
+ATOM 880 O SER A 133 -28.935 17.008 34.455 1.00 40.00 O
+ATOM 881 CB SER A 133 -26.268 16.081 32.842 1.00 40.00 C
+ATOM 882 OG SER A 133 -25.647 17.327 32.581 1.00 40.00 O
+ATOM 883 N ASN A 134 -28.145 18.502 32.956 1.00 40.00 N
+ATOM 884 CA ASN A 134 -28.660 19.668 33.663 1.00 40.00 C
+ATOM 885 C ASN A 134 -30.156 19.861 33.442 1.00 40.00 C
+ATOM 886 O ASN A 134 -30.871 20.219 34.376 1.00 40.00 O
+ATOM 887 CB ASN A 134 -27.860 20.932 33.315 1.00 40.00 C
+ATOM 888 CG ASN A 134 -26.510 20.972 34.019 1.00 40.00 C
+ATOM 889 OD1 ASN A 134 -26.403 21.436 35.159 1.00 40.00 O
+ATOM 890 ND2 ASN A 134 -25.473 20.477 33.345 1.00 40.00 N
+ATOM 891 N PHE A 135 -30.627 19.601 32.223 1.00 40.00 N
+ATOM 892 CA PHE A 135 -32.054 19.635 31.944 1.00 40.00 C
+ATOM 893 C PHE A 135 -32.812 18.734 32.932 1.00 40.00 C
+ATOM 894 O PHE A 135 -33.855 19.124 33.475 1.00 40.00 O
+ATOM 895 CB PHE A 135 -32.319 19.235 30.486 1.00 40.00 C
+ATOM 896 CG PHE A 135 -33.754 18.869 30.201 1.00 40.00 C
+ATOM 897 CD1 PHE A 135 -34.766 19.830 30.267 1.00 40.00 C
+ATOM 898 CD2 PHE A 135 -34.099 17.554 29.860 1.00 40.00 C
+ATOM 899 CE1 PHE A 135 -36.087 19.483 30.009 1.00 40.00 C
+ATOM 900 CE2 PHE A 135 -35.420 17.203 29.596 1.00 40.00 C
+ATOM 901 CZ PHE A 135 -36.415 18.171 29.669 1.00 40.00 C
+ATOM 902 N LEU A 136 -32.253 17.554 33.193 1.00 40.00 N
+ATOM 903 CA LEU A 136 -32.944 16.525 33.959 1.00 40.00 C
+ATOM 904 C LEU A 136 -32.970 16.775 35.450 1.00 40.00 C
+ATOM 905 O LEU A 136 -34.036 16.712 36.064 1.00 40.00 O
+ATOM 906 CB LEU A 136 -32.378 15.140 33.650 1.00 40.00 C
+ATOM 907 CG LEU A 136 -32.822 14.638 32.268 1.00 40.00 C
+ATOM 908 CD1 LEU A 136 -31.982 13.460 31.773 1.00 40.00 C
+ATOM 909 CD2 LEU A 136 -34.317 14.322 32.236 1.00 40.00 C
+ATOM 910 N CYS A 137 -31.809 17.073 36.032 1.00 40.00 N
+ATOM 911 CA CYS A 137 -31.756 17.422 37.449 1.00 40.00 C
+ATOM 912 C CYS A 137 -32.649 18.637 37.738 1.00 40.00 C
+ATOM 913 O CYS A 137 -33.182 18.764 38.846 1.00 40.00 O
+ATOM 914 CB CYS A 137 -30.318 17.712 37.879 1.00 40.00 C
+ATOM 915 SG CYS A 137 -29.191 16.300 37.890 1.00 40.00 S
+ATOM 916 N ASP A 138 -32.810 19.499 36.720 1.00 40.00 N
+ATOM 917 CA ASP A 138 -33.585 20.761 36.787 1.00 40.00 C
+ATOM 918 C ASP A 138 -35.098 20.568 36.736 1.00 40.00 C
+ATOM 919 O ASP A 138 -35.859 21.534 36.878 1.00 40.00 O
+ATOM 920 CB ASP A 138 -33.183 21.726 35.649 1.00 40.00 C
+ATOM 921 CG ASP A 138 -31.939 22.562 35.977 1.00 40.00 C
+ATOM 922 OD1 ASP A 138 -31.361 22.413 37.082 1.00 40.00 O
+ATOM 923 OD2 ASP A 138 -31.532 23.376 35.113 1.00 40.00 O
+ATOM 924 N LEU A 139 -35.535 19.333 36.528 1.00 40.00 N
+ATOM 925 CA LEU A 139 -36.950 19.092 36.343 1.00 40.00 C
+ATOM 926 C LEU A 139 -37.750 19.113 37.634 1.00 40.00 C
+ATOM 927 O LEU A 139 -37.335 18.564 38.659 1.00 40.00 O
+ATOM 928 CB LEU A 139 -37.195 17.809 35.564 1.00 40.00 C
+ATOM 929 CG LEU A 139 -36.862 17.934 34.072 1.00 40.00 C
+ATOM 930 CD1 LEU A 139 -37.016 16.572 33.412 1.00 40.00 C
+ATOM 931 CD2 LEU A 139 -37.685 18.996 33.341 1.00 40.00 C
+ATOM 932 N GLN A 140 -38.901 19.776 37.556 1.00 40.00 N
+ATOM 933 CA GLN A 140 -39.833 19.898 38.671 1.00 40.00 C
+ATOM 934 C GLN A 140 -40.996 18.939 38.501 1.00 40.00 C
+ATOM 935 O GLN A 140 -41.377 18.616 37.362 1.00 40.00 O
+ATOM 936 CB GLN A 140 -40.372 21.334 38.787 1.00 40.00 C
+ATOM 937 CG GLN A 140 -39.315 22.396 39.072 1.00 40.00 C
+ATOM 938 CD GLN A 140 -38.353 22.014 40.195 1.00 40.00 C
+ATOM 939 OE1 GLN A 140 -37.207 22.469 40.215 1.00 40.00 O
+ATOM 940 NE2 GLN A 140 -38.813 21.174 41.132 1.00 40.00 N
+ATOM 941 N PRO A 141 -41.569 18.478 39.630 1.00 40.00 N
+ATOM 942 CA PRO A 141 -42.819 17.730 39.510 1.00 40.00 C
+ATOM 943 C PRO A 141 -43.761 18.392 38.480 1.00 40.00 C
+ATOM 944 O PRO A 141 -44.050 19.592 38.570 1.00 40.00 O
+ATOM 945 CB PRO A 141 -43.397 17.789 40.934 1.00 40.00 C
+ATOM 946 CG PRO A 141 -42.201 17.931 41.827 1.00 40.00 C
+ATOM 947 CD PRO A 141 -41.064 18.512 41.020 1.00 40.00 C
+ATOM 948 N GLY A 142 -44.179 17.627 37.477 1.00 40.00 N
+ATOM 949 CA GLY A 142 -45.208 18.090 36.557 1.00 40.00 C
+ATOM 950 C GLY A 142 -44.722 18.481 35.192 1.00 40.00 C
+ATOM 951 O GLY A 142 -45.525 18.641 34.262 1.00 40.00 O
+ATOM 952 N ASP A 143 -43.407 18.641 35.072 1.00 40.00 N
+ATOM 953 CA ASP A 143 -42.783 18.922 33.783 1.00 40.00 C
+ATOM 954 C ASP A 143 -42.959 17.749 32.808 1.00 40.00 C
+ATOM 955 O ASP A 143 -43.105 16.583 33.218 1.00 40.00 O
+ATOM 956 CB ASP A 143 -41.302 19.261 33.969 1.00 40.00 C
+ATOM 957 CG ASP A 143 -41.083 20.453 34.884 1.00 40.00 C
+ATOM 958 OD1 ASP A 143 -41.995 20.805 35.670 1.00 40.00 O
+ATOM 959 OD2 ASP A 143 -39.979 21.032 34.816 1.00 40.00 O
+ATOM 960 N ASN A 144 -42.968 18.072 31.519 1.00 40.00 N
+ATOM 961 CA ASN A 144 -42.992 17.047 30.502 1.00 40.00 C
+ATOM 962 C ASN A 144 -41.600 16.581 30.099 1.00 40.00 C
+ATOM 963 O ASN A 144 -40.657 17.385 30.092 1.00 40.00 O
+ATOM 964 CB ASN A 144 -43.770 17.526 29.292 1.00 40.00 C
+ATOM 965 CG ASN A 144 -45.229 17.149 29.371 1.00 40.00 C
+ATOM 966 OD1 ASN A 144 -46.048 17.607 28.575 1.00 40.00 O
+ATOM 967 ND2 ASN A 144 -45.564 16.290 30.331 1.00 40.00 N
+ATOM 968 N VAL A 145 -41.487 15.275 29.795 1.00 40.00 N
+ATOM 969 CA VAL A 145 -40.241 14.627 29.301 1.00 40.00 C
+ATOM 970 C VAL A 145 -40.498 13.830 28.001 1.00 40.00 C
+ATOM 971 O VAL A 145 -41.399 12.974 27.938 1.00 40.00 O
+ATOM 972 CB VAL A 145 -39.573 13.668 30.343 1.00 40.00 C
+ATOM 973 CG1 VAL A 145 -38.104 13.472 30.015 1.00 40.00 C
+ATOM 974 CG2 VAL A 145 -39.690 14.179 31.771 1.00 40.00 C
+ATOM 975 N GLN A 146 -39.703 14.116 26.970 1.00 40.00 N
+ATOM 976 CA GLN A 146 -39.768 13.348 25.725 1.00 40.00 C
+ATOM 977 C GLN A 146 -38.863 12.123 25.831 1.00 40.00 C
+ATOM 978 O GLN A 146 -37.657 12.249 26.089 1.00 40.00 O
+ATOM 979 CB GLN A 146 -39.365 14.214 24.536 1.00 40.00 C
+ATOM 980 CG GLN A 146 -40.338 15.340 24.214 1.00 40.00 C
+ATOM 981 CD GLN A 146 -39.825 16.229 23.096 1.00 40.00 C
+ATOM 982 OE1 GLN A 146 -38.720 16.781 23.178 1.00 40.00 O
+ATOM 983 NE2 GLN A 146 -40.625 16.374 22.040 1.00 40.00 N
+ATOM 984 N ILE A 147 -39.448 10.942 25.624 1.00 40.00 N
+ATOM 985 CA ILE A 147 -38.804 9.665 25.987 1.00 40.00 C
+ATOM 986 C ILE A 147 -38.645 8.662 24.828 1.00 40.00 C
+ATOM 987 O ILE A 147 -39.631 8.250 24.203 1.00 40.00 O
+ATOM 988 CB ILE A 147 -39.548 9.004 27.177 1.00 40.00 C
+ATOM 989 CG1 ILE A 147 -39.446 9.898 28.412 1.00 40.00 C
+ATOM 990 CG2 ILE A 147 -38.992 7.619 27.480 1.00 40.00 C
+ATOM 991 CD1 ILE A 147 -40.486 9.620 29.468 1.00 40.00 C
+ATOM 992 N THR A 148 -37.393 8.276 24.564 1.00 40.00 N
+ATOM 993 CA THR A 148 -37.063 7.238 23.575 1.00 40.00 C
+ATOM 994 C THR A 148 -36.675 5.904 24.234 1.00 40.00 C
+ATOM 995 O THR A 148 -36.190 5.870 25.367 1.00 40.00 O
+ATOM 996 CB THR A 148 -35.922 7.680 22.625 1.00 40.00 C
+ATOM 997 OG1 THR A 148 -34.740 7.978 23.376 1.00 40.00 O
+ATOM 998 CG2 THR A 148 -36.321 8.908 21.832 1.00 40.00 C
+ATOM 999 N GLY A 149 -36.882 4.803 23.525 1.00 40.00 N
+ATOM 1000 CA GLY A 149 -36.491 3.508 24.057 1.00 40.00 C
+ATOM 1001 C GLY A 149 -37.626 2.503 24.097 1.00 40.00 C
+ATOM 1002 O GLY A 149 -38.636 2.684 23.402 1.00 40.00 O
+ATOM 1003 N PRO A 150 -37.462 1.418 24.884 1.00 40.00 N
+ATOM 1004 CA PRO A 150 -36.271 1.117 25.663 1.00 40.00 C
+ATOM 1005 C PRO A 150 -35.124 0.669 24.768 1.00 40.00 C
+ATOM 1006 O PRO A 150 -35.361 0.262 23.629 1.00 40.00 O
+ATOM 1007 CB PRO A 150 -36.723 -0.025 26.572 1.00 40.00 C
+ATOM 1008 CG PRO A 150 -37.820 -0.691 25.850 1.00 40.00 C
+ATOM 1009 CD PRO A 150 -38.472 0.349 24.987 1.00 40.00 C
+ATOM 1010 N VAL A 151 -33.896 0.753 25.273 1.00 40.00 N
+ATOM 1011 CA VAL A 151 -32.719 0.495 24.458 1.00 40.00 C
+ATOM 1012 C VAL A 151 -31.702 -0.353 25.218 1.00 40.00 C
+ATOM 1013 O VAL A 151 -31.580 -0.231 26.434 1.00 40.00 O
+ATOM 1014 CB VAL A 151 -32.095 1.825 23.975 1.00 40.00 C
+ATOM 1015 CG1 VAL A 151 -30.744 1.599 23.326 1.00 40.00 C
+ATOM 1016 CG2 VAL A 151 -33.011 2.522 22.981 1.00 40.00 C
+ATOM 1017 N GLY A 152 -30.991 -1.217 24.491 1.00 40.00 N
+ATOM 1018 CA GLY A 152 -29.925 -2.036 25.060 1.00 40.00 C
+ATOM 1019 C GLY A 152 -30.393 -3.446 25.327 1.00 40.00 C
+ATOM 1020 O GLY A 152 -31.478 -3.664 25.858 1.00 40.00 O
+ATOM 1021 N LYS A 153 -29.577 -4.408 24.934 1.00 40.00 N
+ATOM 1022 CA LYS A 153 -29.853 -5.785 25.250 1.00 40.00 C
+ATOM 1023 C LYS A 153 -28.638 -6.265 25.976 1.00 40.00 C
+ATOM 1024 O LYS A 153 -28.606 -7.381 26.486 1.00 40.00 O
+ATOM 1025 CB LYS A 153 -30.011 -6.611 23.978 1.00 40.00 C
+ATOM 1026 CG LYS A 153 -31.176 -6.229 23.063 1.00 40.00 C
+ATOM 1027 CD LYS A 153 -32.425 -7.104 23.259 1.00 40.00 C
+ATOM 1028 CE LYS A 153 -32.369 -8.463 22.555 1.00 40.00 C
+ATOM 1029 NZ LYS A 153 -32.662 -8.406 21.096 1.00 40.00 N
+ATOM 1030 N GLU A 154 -27.627 -5.406 26.011 1.00 40.00 N
+ATOM 1031 CA GLU A 154 -26.322 -5.791 26.493 1.00 40.00 C
+ATOM 1032 C GLU A 154 -26.320 -6.129 27.976 1.00 40.00 C
+ATOM 1033 O GLU A 154 -25.576 -6.999 28.422 1.00 40.00 O
+ATOM 1034 CB GLU A 154 -25.314 -4.692 26.182 1.00 40.00 C
+ATOM 1035 CG GLU A 154 -23.885 -5.029 26.586 1.00 40.00 C
+ATOM 1036 CD GLU A 154 -23.215 -6.101 25.726 1.00 40.00 C
+ATOM 1037 OE1 GLU A 154 -23.919 -6.833 24.987 1.00 40.00 O
+ATOM 1038 OE2 GLU A 154 -21.964 -6.212 25.791 1.00 40.00 O
+ATOM 1039 N MET A 155 -27.176 -5.468 28.735 1.00 40.00 N
+ATOM 1040 CA MET A 155 -27.100 -5.586 30.173 1.00 40.00 C
+ATOM 1041 C MET A 155 -28.265 -6.311 30.831 1.00 40.00 C
+ATOM 1042 O MET A 155 -28.585 -6.055 31.983 1.00 40.00 O
+ATOM 1043 CB MET A 155 -26.916 -4.199 30.767 1.00 40.00 C
+ATOM 1044 CG MET A 155 -25.592 -3.569 30.387 1.00 40.00 C
+ATOM 1045 SD MET A 155 -24.208 -4.601 30.890 1.00 40.00 S
+ATOM 1046 CE MET A 155 -23.855 -3.957 32.519 1.00 40.00 C
+ATOM 1047 N LEU A 156 -28.885 -7.236 30.114 1.00 40.00 N
+ATOM 1048 CA LEU A 156 -30.019 -7.981 30.657 1.00 40.00 C
+ATOM 1049 C LEU A 156 -29.555 -9.015 31.666 1.00 40.00 C
+ATOM 1050 O LEU A 156 -28.435 -9.513 31.581 1.00 40.00 O
+ATOM 1051 CB LEU A 156 -30.803 -8.666 29.535 1.00 40.00 C
+ATOM 1052 CG LEU A 156 -31.392 -7.809 28.402 1.00 40.00 C
+ATOM 1053 CD1 LEU A 156 -31.667 -8.655 27.163 1.00 40.00 C
+ATOM 1054 CD2 LEU A 156 -32.645 -7.064 28.852 1.00 40.00 C
+ATOM 1055 N MET A 157 -30.430 -9.342 32.614 1.00 40.00 N
+ATOM 1056 CA MET A 157 -30.103 -10.273 33.701 1.00 40.00 C
+ATOM 1057 C MET A 157 -29.798 -11.657 33.171 1.00 40.00 C
+ATOM 1058 O MET A 157 -30.134 -11.954 32.028 1.00 40.00 O
+ATOM 1059 CB MET A 157 -31.268 -10.385 34.683 1.00 40.00 C
+ATOM 1060 CG MET A 157 -31.984 -9.081 34.977 1.00 40.00 C
+ATOM 1061 SD MET A 157 -32.949 -9.217 36.492 1.00 40.00 S
+ATOM 1062 CE MET A 157 -31.623 -9.401 37.693 1.00 40.00 C
+ATOM 1063 N PRO A 158 -29.171 -12.517 33.992 1.00 40.00 N
+ATOM 1064 CA PRO A 158 -29.047 -13.891 33.544 1.00 40.00 C
+ATOM 1065 C PRO A 158 -30.374 -14.620 33.665 1.00 40.00 C
+ATOM 1066 O PRO A 158 -31.252 -14.187 34.424 1.00 40.00 O
+ATOM 1067 CB PRO A 158 -28.024 -14.492 34.514 1.00 40.00 C
+ATOM 1068 CG PRO A 158 -27.307 -13.324 35.072 1.00 40.00 C
+ATOM 1069 CD PRO A 158 -28.378 -12.286 35.202 1.00 40.00 C
+ATOM 1070 N LYS A 159 -30.509 -15.703 32.900 1.00 40.00 N
+ATOM 1071 CA LYS A 159 -31.654 -16.586 33.000 1.00 40.00 C
+ATOM 1072 C LYS A 159 -31.562 -17.326 34.319 1.00 40.00 C
+ATOM 1073 O LYS A 159 -32.563 -17.456 35.026 1.00 40.00 O
+ATOM 1074 CB LYS A 159 -31.701 -17.558 31.811 1.00 40.00 C
+ATOM 1075 CG LYS A 159 -32.395 -16.993 30.569 1.00 40.00 C
+ATOM 1076 CD LYS A 159 -32.161 -17.807 29.290 1.00 40.00 C
+ATOM 1077 CE LYS A 159 -32.824 -17.144 28.076 1.00 40.00 C
+ATOM 1078 NZ LYS A 159 -32.295 -17.566 26.743 1.00 40.00 N
+ATOM 1079 N ASP A 160 -30.342 -17.763 34.647 1.00 40.00 N
+ATOM 1080 CA ASP A 160 -30.024 -18.511 35.873 1.00 40.00 C
+ATOM 1081 C ASP A 160 -30.443 -17.784 37.170 1.00 40.00 C
+ATOM 1082 O ASP A 160 -29.834 -16.772 37.527 1.00 40.00 O
+ATOM 1083 CB ASP A 160 -28.512 -18.812 35.898 1.00 40.00 C
+ATOM 1084 CG ASP A 160 -28.103 -19.795 37.012 1.00 40.00 C
+ATOM 1085 OD1 ASP A 160 -28.936 -20.156 37.876 1.00 40.00 O
+ATOM 1086 OD2 ASP A 160 -26.923 -20.214 37.018 1.00 40.00 O
+ATOM 1087 N PRO A 161 -31.470 -18.301 37.894 1.00 40.00 N
+ATOM 1088 CA PRO A 161 -31.816 -17.616 39.142 1.00 40.00 C
+ATOM 1089 C PRO A 161 -30.994 -18.138 40.329 1.00 40.00 C
+ATOM 1090 O PRO A 161 -31.324 -17.842 41.479 1.00 40.00 O
+ATOM 1091 CB PRO A 161 -33.316 -17.925 39.314 1.00 40.00 C
+ATOM 1092 CG PRO A 161 -33.562 -19.173 38.515 1.00 40.00 C
+ATOM 1093 CD PRO A 161 -32.334 -19.480 37.678 1.00 40.00 C
+ATOM 1094 N ASN A 162 -29.946 -18.916 40.039 1.00 40.00 N
+ATOM 1095 CA ASN A 162 -28.958 -19.364 41.037 1.00 40.00 C
+ATOM 1096 C ASN A 162 -27.577 -18.861 40.649 1.00 40.00 C
+ATOM 1097 O ASN A 162 -26.542 -19.424 41.035 1.00 40.00 O
+ATOM 1098 CB ASN A 162 -28.957 -20.894 41.175 1.00 40.00 C
+ATOM 1099 CG ASN A 162 -30.085 -21.402 42.057 1.00 40.00 C
+ATOM 1100 OD1 ASN A 162 -30.552 -22.526 41.897 1.00 40.00 O
+ATOM 1101 ND2 ASN A 162 -30.530 -20.573 42.990 1.00 40.00 N
+ATOM 1102 N ALA A 163 -27.593 -17.778 39.882 1.00 40.00 N
+ATOM 1103 CA ALA A 163 -26.399 -17.218 39.296 1.00 40.00 C
+ATOM 1104 C ALA A 163 -25.562 -16.502 40.331 1.00 40.00 C
+ATOM 1105 O ALA A 163 -26.089 -15.955 41.293 1.00 40.00 O
+ATOM 1106 CB ALA A 163 -26.782 -16.256 38.186 1.00 40.00 C
+ATOM 1107 N THR A 164 -24.252 -16.536 40.128 1.00 40.00 N
+ATOM 1108 CA THR A 164 -23.336 -15.630 40.792 1.00 40.00 C
+ATOM 1109 C THR A 164 -23.306 -14.371 39.923 1.00 40.00 C
+ATOM 1110 O THR A 164 -22.897 -14.440 38.765 1.00 40.00 O
+ATOM 1111 CB THR A 164 -21.917 -16.230 40.866 1.00 40.00 C
+ATOM 1112 OG1 THR A 164 -21.967 -17.553 41.413 1.00 40.00 O
+ATOM 1113 CG2 THR A 164 -21.015 -15.375 41.723 1.00 40.00 C
+ATOM 1114 N ILE A 165 -23.755 -13.234 40.458 1.00 40.00 N
+ATOM 1115 CA ILE A 165 -23.834 -12.001 39.653 1.00 40.00 C
+ATOM 1116 C ILE A 165 -22.952 -10.868 40.148 1.00 40.00 C
+ATOM 1117 O ILE A 165 -23.278 -10.153 41.097 1.00 40.00 O
+ATOM 1118 CB ILE A 165 -25.264 -11.490 39.519 1.00 40.00 C
+ATOM 1119 CG1 ILE A 165 -26.149 -12.615 39.020 1.00 40.00 C
+ATOM 1120 CG2 ILE A 165 -25.302 -10.323 38.548 1.00 40.00 C
+ATOM 1121 CD1 ILE A 165 -27.609 -12.407 39.330 1.00 40.00 C
+ATOM 1122 N ILE A 166 -21.843 -10.686 39.461 1.00 40.00 N
+ATOM 1123 CA ILE A 166 -20.872 -9.724 39.883 1.00 40.00 C
+ATOM 1124 C ILE A 166 -21.085 -8.444 39.139 1.00 40.00 C
+ATOM 1125 O ILE A 166 -21.057 -8.407 37.915 1.00 40.00 O
+ATOM 1126 CB ILE A 166 -19.470 -10.250 39.643 1.00 40.00 C
+ATOM 1127 CG1 ILE A 166 -19.293 -11.513 40.474 1.00 40.00 C
+ATOM 1128 CG2 ILE A 166 -18.435 -9.195 40.002 1.00 40.00 C
+ATOM 1129 CD1 ILE A 166 -18.232 -12.451 39.951 1.00 40.00 C
+ATOM 1130 N MET A 167 -21.278 -7.393 39.915 1.00 40.00 N
+ATOM 1131 CA MET A 167 -21.655 -6.109 39.399 1.00 40.00 C
+ATOM 1132 C MET A 167 -20.611 -5.075 39.777 1.00 40.00 C
+ATOM 1133 O MET A 167 -20.463 -4.734 40.949 1.00 40.00 O
+ATOM 1134 CB MET A 167 -22.996 -5.741 39.998 1.00 40.00 C
+ATOM 1135 CG MET A 167 -24.031 -6.839 39.870 1.00 40.00 C
+ATOM 1136 SD MET A 167 -25.494 -6.488 40.852 1.00 40.00 S
+ATOM 1137 CE MET A 167 -25.129 -7.461 42.309 1.00 40.00 C
+ATOM 1138 N LEU A 168 -19.872 -4.592 38.788 1.00 40.00 N
+ATOM 1139 CA LEU A 168 -18.912 -3.532 39.030 1.00 40.00 C
+ATOM 1140 C LEU A 168 -19.503 -2.220 38.588 1.00 40.00 C
+ATOM 1141 O LEU A 168 -19.976 -2.106 37.463 1.00 40.00 O
+ATOM 1142 CB LEU A 168 -17.610 -3.782 38.279 1.00 40.00 C
+ATOM 1143 CG LEU A 168 -16.800 -5.023 38.621 1.00 40.00 C
+ATOM 1144 CD1 LEU A 168 -17.060 -5.544 40.029 1.00 40.00 C
+ATOM 1145 CD2 LEU A 168 -17.153 -6.076 37.604 1.00 40.00 C
+ATOM 1146 N ALA A 169 -19.472 -1.228 39.472 1.00 40.00 N
+ATOM 1147 CA ALA A 169 -20.097 0.055 39.185 1.00 40.00 C
+ATOM 1148 C ALA A 169 -19.341 1.233 39.745 1.00 40.00 C
+ATOM 1149 O ALA A 169 -18.823 1.186 40.846 1.00 40.00 O
+ATOM 1150 CB ALA A 169 -21.526 0.070 39.696 1.00 40.00 C
+ATOM 1151 N THR A 170 -19.307 2.306 38.977 1.00 40.00 N
+ATOM 1152 CA THR A 170 -18.687 3.535 39.415 1.00 40.00 C
+ATOM 1153 C THR A 170 -19.607 4.684 39.100 1.00 40.00 C
+ATOM 1154 O THR A 170 -19.853 4.979 37.941 1.00 40.00 O
+ATOM 1155 CB THR A 170 -17.395 3.797 38.648 1.00 40.00 C
+ATOM 1156 OG1 THR A 170 -17.645 3.597 37.251 1.00 40.00 O
+ATOM 1157 CG2 THR A 170 -16.275 2.866 39.120 1.00 40.00 C
+ATOM 1158 N GLY A 171 -20.112 5.340 40.128 1.00 40.00 N
+ATOM 1159 CA GLY A 171 -20.984 6.480 39.922 1.00 40.00 C
+ATOM 1160 C GLY A 171 -22.345 6.077 39.397 1.00 40.00 C
+ATOM 1161 O GLY A 171 -22.928 5.114 39.882 1.00 40.00 O
+ATOM 1162 N THR A 172 -22.840 6.807 38.394 1.00 40.00 N
+ATOM 1163 CA THR A 172 -24.168 6.566 37.829 1.00 40.00 C
+ATOM 1164 C THR A 172 -24.191 5.311 36.969 1.00 40.00 C
+ATOM 1165 O THR A 172 -25.068 5.140 36.114 1.00 40.00 O
+ATOM 1166 CB THR A 172 -24.680 7.759 37.003 1.00 40.00 C
+ATOM 1167 OG1 THR A 172 -23.932 7.871 35.791 1.00 40.00 O
+ATOM 1168 CG2 THR A 172 -24.555 9.031 37.770 1.00 40.00 C
+ATOM 1169 N GLY A 173 -23.205 4.441 37.203 1.00 40.00 N
+ATOM 1170 CA GLY A 173 -23.184 3.107 36.618 1.00 40.00 C
+ATOM 1171 C GLY A 173 -23.761 2.079 37.575 1.00 40.00 C
+ATOM 1172 O GLY A 173 -23.717 0.878 37.317 1.00 40.00 O
+ATOM 1173 N ILE A 174 -24.298 2.558 38.689 1.00 40.00 N
+ATOM 1174 CA ILE A 174 -24.989 1.708 39.623 1.00 40.00 C
+ATOM 1175 C ILE A 174 -26.422 1.505 39.155 1.00 40.00 C
+ATOM 1176 O ILE A 174 -27.036 0.492 39.469 1.00 40.00 O
+ATOM 1177 CB ILE A 174 -25.006 2.340 41.012 1.00 40.00 C
+ATOM 1178 CG1 ILE A 174 -25.696 1.427 42.023 1.00 40.00 C
+ATOM 1179 CG2 ILE A 174 -25.708 3.687 40.968 1.00 40.00 C
+ATOM 1180 CD1 ILE A 174 -24.779 0.452 42.722 1.00 40.00 C
+ATOM 1181 N ALA A 175 -26.942 2.467 38.393 1.00 40.00 N
+ATOM 1182 CA ALA A 175 -28.350 2.472 37.936 1.00 40.00 C
+ATOM 1183 C ALA A 175 -28.978 1.118 37.523 1.00 40.00 C
+ATOM 1184 O ALA A 175 -29.980 0.692 38.113 1.00 40.00 O
+ATOM 1185 CB ALA A 175 -28.541 3.508 36.834 1.00 40.00 C
+ATOM 1186 N PRO A 176 -28.405 0.446 36.506 1.00 40.00 N
+ATOM 1187 CA PRO A 176 -28.979 -0.821 36.128 1.00 40.00 C
+ATOM 1188 C PRO A 176 -29.001 -1.785 37.302 1.00 40.00 C
+ATOM 1189 O PRO A 176 -29.996 -2.462 37.517 1.00 40.00 O
+ATOM 1190 CB PRO A 176 -28.018 -1.318 35.053 1.00 40.00 C
+ATOM 1191 CG PRO A 176 -26.742 -0.599 35.287 1.00 40.00 C
+ATOM 1192 CD PRO A 176 -27.202 0.746 35.710 1.00 40.00 C
+ATOM 1193 N PHE A 177 -27.917 -1.824 38.068 1.00 40.00 N
+ATOM 1194 CA PHE A 177 -27.815 -2.737 39.188 1.00 40.00 C
+ATOM 1195 C PHE A 177 -28.808 -2.421 40.279 1.00 40.00 C
+ATOM 1196 O PHE A 177 -29.149 -3.290 41.066 1.00 40.00 O
+ATOM 1197 CB PHE A 177 -26.427 -2.711 39.774 1.00 40.00 C
+ATOM 1198 CG PHE A 177 -25.363 -3.037 38.795 1.00 40.00 C
+ATOM 1199 CD1 PHE A 177 -25.354 -4.253 38.159 1.00 40.00 C
+ATOM 1200 CD2 PHE A 177 -24.355 -2.125 38.514 1.00 40.00 C
+ATOM 1201 CE1 PHE A 177 -24.357 -4.565 37.253 1.00 40.00 C
+ATOM 1202 CE2 PHE A 177 -23.349 -2.428 37.609 1.00 40.00 C
+ATOM 1203 CZ PHE A 177 -23.349 -3.655 36.975 1.00 40.00 C
+ATOM 1204 N ARG A 178 -29.264 -1.177 40.347 1.00 40.00 N
+ATOM 1205 CA ARG A 178 -30.387 -0.878 41.213 1.00 40.00 C
+ATOM 1206 C ARG A 178 -31.491 -1.749 40.691 1.00 40.00 C
+ATOM 1207 O ARG A 178 -32.012 -2.615 41.393 1.00 40.00 O
+ATOM 1208 CB ARG A 178 -30.816 0.584 41.112 1.00 40.00 C
+ATOM 1209 CG ARG A 178 -32.073 0.903 41.917 1.00 40.00 C
+ATOM 1210 CD ARG A 178 -32.270 2.396 42.117 1.00 40.00 C
+ATOM 1211 NE ARG A 178 -33.134 2.685 43.252 1.00 40.00 N
+ATOM 1212 CZ ARG A 178 -34.451 2.752 43.177 1.00 40.00 C
+ATOM 1213 NH1 ARG A 178 -35.055 2.562 42.031 1.00 40.00 N
+ATOM 1214 NH2 ARG A 178 -35.159 3.014 44.244 1.00 40.00 N
+ATOM 1215 N SER A 179 -31.796 -1.527 39.418 1.00 40.00 N
+ATOM 1216 CA SER A 179 -32.868 -2.202 38.734 1.00 40.00 C
+ATOM 1217 C SER A 179 -32.804 -3.698 38.985 1.00 40.00 C
+ATOM 1218 O SER A 179 -33.817 -4.321 39.261 1.00 40.00 O
+ATOM 1219 CB SER A 179 -32.779 -1.893 37.249 1.00 40.00 C
+ATOM 1220 OG SER A 179 -34.041 -2.036 36.652 1.00 40.00 O
+ATOM 1221 N PHE A 180 -31.600 -4.253 38.919 1.00 40.00 N
+ATOM 1222 CA PHE A 180 -31.374 -5.661 39.180 1.00 40.00 C
+ATOM 1223 C PHE A 180 -31.828 -6.057 40.556 1.00 40.00 C
+ATOM 1224 O PHE A 180 -32.624 -6.960 40.717 1.00 40.00 O
+ATOM 1225 CB PHE A 180 -29.891 -5.973 39.116 1.00 40.00 C
+ATOM 1226 CG PHE A 180 -29.360 -6.178 37.735 1.00 40.00 C
+ATOM 1227 CD1 PHE A 180 -29.923 -5.529 36.644 1.00 40.00 C
+ATOM 1228 CD2 PHE A 180 -28.253 -7.000 37.532 1.00 40.00 C
+ATOM 1229 CE1 PHE A 180 -29.410 -5.719 35.370 1.00 40.00 C
+ATOM 1230 CE2 PHE A 180 -27.726 -7.189 36.265 1.00 40.00 C
+ATOM 1231 CZ PHE A 180 -28.308 -6.546 35.182 1.00 40.00 C
+ATOM 1232 N LEU A 181 -31.294 -5.391 41.562 1.00 40.00 N
+ATOM 1233 CA LEU A 181 -31.458 -5.874 42.922 1.00 40.00 C
+ATOM 1234 C LEU A 181 -32.908 -5.764 43.372 1.00 40.00 C
+ATOM 1235 O LEU A 181 -33.454 -6.696 43.972 1.00 40.00 O
+ATOM 1236 CB LEU A 181 -30.486 -5.162 43.868 1.00 40.00 C
+ATOM 1237 CG LEU A 181 -29.032 -5.571 43.605 1.00 40.00 C
+ATOM 1238 CD1 LEU A 181 -28.107 -4.381 43.767 1.00 40.00 C
+ATOM 1239 CD2 LEU A 181 -28.590 -6.735 44.482 1.00 40.00 C
+ATOM 1240 N TRP A 182 -33.536 -4.639 43.041 1.00 40.00 N
+ATOM 1241 CA TRP A 182 -34.936 -4.420 43.360 1.00 40.00 C
+ATOM 1242 C TRP A 182 -35.714 -5.656 43.072 1.00 40.00 C
+ATOM 1243 O TRP A 182 -36.352 -6.212 43.961 1.00 40.00 O
+ATOM 1244 CB TRP A 182 -35.484 -3.251 42.553 1.00 40.00 C
+ATOM 1245 CG TRP A 182 -35.496 -1.952 43.315 1.00 40.00 C
+ATOM 1246 CD1 TRP A 182 -34.406 -1.225 43.766 1.00 40.00 C
+ATOM 1247 CD2 TRP A 182 -36.668 -1.171 43.732 1.00 40.00 C
+ATOM 1248 NE1 TRP A 182 -34.811 -0.085 44.416 1.00 40.00 N
+ATOM 1249 CE2 TRP A 182 -36.150 0.007 44.432 1.00 40.00 C
+ATOM 1250 CE3 TRP A 182 -38.040 -1.323 43.597 1.00 40.00 C
+ATOM 1251 CZ2 TRP A 182 -36.983 0.964 44.976 1.00 40.00 C
+ATOM 1252 CZ3 TRP A 182 -38.873 -0.346 44.147 1.00 40.00 C
+ATOM 1253 CH2 TRP A 182 -38.354 0.768 44.821 1.00 40.00 C
+ATOM 1254 N LYS A 183 -35.635 -6.108 41.823 1.00 40.00 N
+ATOM 1255 CA LYS A 183 -36.297 -7.331 41.379 1.00 40.00 C
+ATOM 1256 C LYS A 183 -35.870 -8.531 42.241 1.00 40.00 C
+ATOM 1257 O LYS A 183 -36.711 -9.311 42.690 1.00 40.00 O
+ATOM 1258 CB LYS A 183 -35.992 -7.581 39.890 1.00 40.00 C
+ATOM 1259 CG LYS A 183 -37.109 -8.256 39.101 1.00 40.00 C
+ATOM 1260 CD LYS A 183 -36.589 -9.063 37.907 1.00 40.00 C
+ATOM 1261 CE LYS A 183 -37.747 -9.737 37.168 1.00 40.00 C
+ATOM 1262 NZ LYS A 183 -37.304 -10.815 36.228 1.00 40.00 N
+ATOM 1263 N MET A 184 -34.569 -8.643 42.497 1.00 40.00 N
+ATOM 1264 CA MET A 184 -34.015 -9.798 43.171 1.00 40.00 C
+ATOM 1265 C MET A 184 -34.423 -9.892 44.607 1.00 40.00 C
+ATOM 1266 O MET A 184 -34.765 -10.964 45.071 1.00 40.00 O
+ATOM 1267 CB MET A 184 -32.510 -9.758 43.129 1.00 40.00 C
+ATOM 1268 CG MET A 184 -31.963 -9.985 41.749 1.00 40.00 C
+ATOM 1269 SD MET A 184 -30.327 -9.277 41.642 1.00 40.00 S
+ATOM 1270 CE MET A 184 -29.404 -10.476 42.602 1.00 40.00 C
+ATOM 1271 N PHE A 185 -34.379 -8.780 45.318 1.00 40.00 N
+ATOM 1272 CA PHE A 185 -34.528 -8.853 46.753 1.00 40.00 C
+ATOM 1273 C PHE A 185 -35.754 -8.174 47.294 1.00 40.00 C
+ATOM 1274 O PHE A 185 -36.326 -8.600 48.295 1.00 40.00 O
+ATOM 1275 CB PHE A 185 -33.291 -8.308 47.422 1.00 40.00 C
+ATOM 1276 CG PHE A 185 -32.094 -9.156 47.209 1.00 40.00 C
+ATOM 1277 CD1 PHE A 185 -32.001 -10.402 47.808 1.00 40.00 C
+ATOM 1278 CD2 PHE A 185 -31.062 -8.722 46.401 1.00 40.00 C
+ATOM 1279 CE1 PHE A 185 -30.887 -11.204 47.619 1.00 40.00 C
+ATOM 1280 CE2 PHE A 185 -29.943 -9.516 46.204 1.00 40.00 C
+ATOM 1281 CZ PHE A 185 -29.851 -10.761 46.816 1.00 40.00 C
+ATOM 1282 N PHE A 186 -36.165 -7.107 46.642 1.00 40.00 N
+ATOM 1283 CA PHE A 186 -37.333 -6.423 47.127 1.00 40.00 C
+ATOM 1284 C PHE A 186 -38.630 -7.064 46.639 1.00 40.00 C
+ATOM 1285 O PHE A 186 -39.640 -7.017 47.338 1.00 40.00 O
+ATOM 1286 CB PHE A 186 -37.274 -4.937 46.782 1.00 40.00 C
+ATOM 1287 CG PHE A 186 -36.399 -4.133 47.708 1.00 40.00 C
+ATOM 1288 CD1 PHE A 186 -35.872 -4.705 48.872 1.00 40.00 C
+ATOM 1289 CD2 PHE A 186 -36.134 -2.790 47.433 1.00 40.00 C
+ATOM 1290 CE1 PHE A 186 -35.077 -3.959 49.721 1.00 40.00 C
+ATOM 1291 CE2 PHE A 186 -35.348 -2.035 48.284 1.00 40.00 C
+ATOM 1292 CZ PHE A 186 -34.818 -2.621 49.427 1.00 40.00 C
+ATOM 1293 N GLU A 187 -38.596 -7.695 45.465 1.00 40.00 N
+ATOM 1294 CA GLU A 187 -39.835 -8.139 44.812 1.00 40.00 C
+ATOM 1295 C GLU A 187 -40.097 -9.663 44.850 1.00 40.00 C
+ATOM 1296 O GLU A 187 -39.163 -10.483 44.870 1.00 40.00 O
+ATOM 1297 CB GLU A 187 -39.912 -7.568 43.386 1.00 40.00 C
+ATOM 1298 CG GLU A 187 -39.751 -6.050 43.341 1.00 40.00 C
+ATOM 1299 CD GLU A 187 -39.603 -5.467 41.937 1.00 40.00 C
+ATOM 1300 OE1 GLU A 187 -39.112 -6.152 41.010 1.00 40.00 O
+ATOM 1301 OE2 GLU A 187 -39.976 -4.287 41.758 1.00 40.00 O
+ATOM 1302 N LYS A 188 -41.384 -10.015 44.892 1.00 40.00 N
+ATOM 1303 CA LYS A 188 -41.835 -11.410 44.841 1.00 40.00 C
+ATOM 1304 C LYS A 188 -42.450 -11.734 43.488 1.00 40.00 C
+ATOM 1305 O LYS A 188 -43.497 -11.191 43.111 1.00 40.00 O
+ATOM 1306 CB LYS A 188 -42.854 -11.706 45.944 1.00 40.00 C
+ATOM 1307 CG LYS A 188 -42.292 -11.621 47.350 1.00 40.00 C
+ATOM 1308 CD LYS A 188 -41.264 -12.715 47.616 1.00 40.00 C
+ATOM 1309 CE LYS A 188 -40.557 -12.486 48.939 1.00 40.00 C
+ATOM 1310 NZ LYS A 188 -41.537 -12.398 50.057 1.00 40.00 N
+ATOM 1311 N HIS A 189 -41.783 -12.615 42.756 1.00 40.00 N
+ATOM 1312 CA HIS A 189 -42.287 -13.057 41.473 1.00 40.00 C
+ATOM 1313 C HIS A 189 -42.439 -14.536 41.503 1.00 40.00 C
+ATOM 1314 O HIS A 189 -41.630 -15.261 42.110 1.00 40.00 O
+ATOM 1315 CB HIS A 189 -41.360 -12.634 40.347 1.00 40.00 C
+ATOM 1316 CG HIS A 189 -41.238 -11.139 40.200 1.00 40.00 C
+ATOM 1317 ND1 HIS A 189 -41.884 -10.451 39.237 1.00 40.00 N
+ATOM 1318 CD2 HIS A 189 -40.527 -10.197 40.954 1.00 40.00 C
+ATOM 1319 CE1 HIS A 189 -41.594 -9.135 39.356 1.00 40.00 C
+ATOM 1320 NE2 HIS A 189 -40.765 -8.981 40.410 1.00 40.00 N
+ATOM 1321 N ASP A 190 -43.504 -14.989 40.854 1.00 40.00 N
+ATOM 1322 CA ASP A 190 -43.826 -16.400 40.798 1.00 40.00 C
+ATOM 1323 C ASP A 190 -42.862 -17.081 39.840 1.00 40.00 C
+ATOM 1324 O ASP A 190 -42.321 -18.151 40.136 1.00 40.00 O
+ATOM 1325 CB ASP A 190 -45.288 -16.569 40.382 1.00 40.00 C
+ATOM 1326 CG ASP A 190 -46.225 -15.766 41.267 1.00 40.00 C
+ATOM 1327 OD1 ASP A 190 -46.339 -16.128 42.461 1.00 40.00 O
+ATOM 1328 OD2 ASP A 190 -46.816 -14.762 40.788 1.00 40.00 O
+ATOM 1329 N ASP A 191 -42.616 -16.423 38.711 1.00 40.00 N
+ATOM 1330 CA ASP A 191 -41.725 -16.951 37.689 1.00 40.00 C
+ATOM 1331 C ASP A 191 -40.269 -16.761 38.047 1.00 40.00 C
+ATOM 1332 O ASP A 191 -39.390 -17.377 37.451 1.00 40.00 O
+ATOM 1333 CB ASP A 191 -42.020 -16.300 36.337 1.00 40.00 C
+ATOM 1334 CG ASP A 191 -42.157 -14.789 36.423 1.00 40.00 C
+ATOM 1335 OD1 ASP A 191 -42.994 -14.294 37.216 1.00 40.00 O
+ATOM 1336 OD2 ASP A 191 -41.441 -14.097 35.670 1.00 40.00 O
+ATOM 1337 N TYR A 192 -40.013 -15.905 39.025 1.00 40.00 N
+ATOM 1338 CA TYR A 192 -38.642 -15.551 39.353 1.00 40.00 C
+ATOM 1339 C TYR A 192 -38.371 -15.389 40.841 1.00 40.00 C
+ATOM 1340 O TYR A 192 -38.819 -14.429 41.479 1.00 40.00 O
+ATOM 1341 CB TYR A 192 -38.207 -14.292 38.595 1.00 40.00 C
+ATOM 1342 CG TYR A 192 -36.711 -14.097 38.595 1.00 40.00 C
+ATOM 1343 CD1 TYR A 192 -35.879 -14.961 37.880 1.00 40.00 C
+ATOM 1344 CD2 TYR A 192 -36.126 -13.065 39.314 1.00 40.00 C
+ATOM 1345 CE1 TYR A 192 -34.505 -14.793 37.878 1.00 40.00 C
+ATOM 1346 CE2 TYR A 192 -34.753 -12.886 39.315 1.00 40.00 C
+ATOM 1347 CZ TYR A 192 -33.944 -13.753 38.597 1.00 40.00 C
+ATOM 1348 OH TYR A 192 -32.572 -13.589 38.590 1.00 40.00 O
+ATOM 1349 N LYS A 193 -37.632 -16.351 41.382 1.00 40.00 N
+ATOM 1350 CA LYS A 193 -37.067 -16.235 42.716 1.00 40.00 C
+ATOM 1351 C LYS A 193 -35.578 -16.517 42.586 1.00 40.00 C
+ATOM 1352 O LYS A 193 -35.160 -17.556 42.064 1.00 40.00 O
+ATOM 1353 CB LYS A 193 -37.739 -17.189 43.706 1.00 40.00 C
+ATOM 1354 CG LYS A 193 -39.248 -17.018 43.822 1.00 40.00 C
+ATOM 1355 CD LYS A 193 -39.896 -18.271 44.398 1.00 40.00 C
+ATOM 1356 CE LYS A 193 -39.597 -19.530 43.581 1.00 40.00 C
+ATOM 1357 NZ LYS A 193 -40.161 -19.482 42.194 1.00 40.00 N
+ATOM 1358 N PHE A 194 -34.786 -15.550 43.027 1.00 40.00 N
+ATOM 1359 CA PHE A 194 -33.336 -15.647 43.003 1.00 40.00 C
+ATOM 1360 C PHE A 194 -32.839 -16.492 44.187 1.00 40.00 C
+ATOM 1361 O PHE A 194 -33.509 -16.589 45.216 1.00 40.00 O
+ATOM 1362 CB PHE A 194 -32.735 -14.234 43.027 1.00 40.00 C
+ATOM 1363 CG PHE A 194 -31.242 -14.211 42.988 1.00 40.00 C
+ATOM 1364 CD1 PHE A 194 -30.561 -14.520 41.815 1.00 40.00 C
+ATOM 1365 CD2 PHE A 194 -30.515 -13.886 44.127 1.00 40.00 C
+ATOM 1366 CE1 PHE A 194 -29.178 -14.510 41.782 1.00 40.00 C
+ATOM 1367 CE2 PHE A 194 -29.131 -13.866 44.103 1.00 40.00 C
+ATOM 1368 CZ PHE A 194 -28.461 -14.176 42.926 1.00 40.00 C
+ATOM 1369 N ASN A 195 -31.678 -17.121 44.035 1.00 40.00 N
+ATOM 1370 CA ASN A 195 -31.084 -17.861 45.126 1.00 40.00 C
+ATOM 1371 C ASN A 195 -29.640 -18.233 44.826 1.00 40.00 C
+ATOM 1372 O ASN A 195 -29.204 -19.354 45.068 1.00 40.00 O
+ATOM 1373 CB ASN A 195 -31.923 -19.099 45.442 1.00 40.00 C
+ATOM 1374 CG ASN A 195 -31.707 -19.606 46.855 1.00 40.00 C
+ATOM 1375 OD1 ASN A 195 -31.873 -20.802 47.144 1.00 40.00 O
+ATOM 1376 ND2 ASN A 195 -31.330 -18.697 47.749 1.00 40.00 N
+ATOM 1377 N GLY A 196 -28.901 -17.285 44.273 1.00 40.00 N
+ATOM 1378 CA GLY A 196 -27.467 -17.455 44.073 1.00 40.00 C
+ATOM 1379 C GLY A 196 -26.718 -16.521 45.006 1.00 40.00 C
+ATOM 1380 O GLY A 196 -27.026 -16.439 46.205 1.00 40.00 O
+ATOM 1381 N LEU A 197 -25.741 -15.803 44.454 1.00 40.00 N
+ATOM 1382 CA LEU A 197 -25.001 -14.805 45.216 1.00 40.00 C
+ATOM 1383 C LEU A 197 -24.844 -13.486 44.470 1.00 40.00 C
+ATOM 1384 O LEU A 197 -24.182 -13.425 43.430 1.00 40.00 O
+ATOM 1385 CB LEU A 197 -23.627 -15.340 45.582 1.00 40.00 C
+ATOM 1386 CG LEU A 197 -22.745 -14.288 46.248 1.00 40.00 C
+ATOM 1387 CD1 LEU A 197 -23.057 -14.173 47.735 1.00 40.00 C
+ATOM 1388 CD2 LEU A 197 -21.284 -14.619 46.015 1.00 40.00 C
+ATOM 1389 N GLY A 198 -25.440 -12.432 45.018 1.00 40.00 N
+ATOM 1390 CA GLY A 198 -25.305 -11.104 44.440 1.00 40.00 C
+ATOM 1391 C GLY A 198 -24.190 -10.298 45.084 1.00 40.00 C
+ATOM 1392 O GLY A 198 -24.344 -9.800 46.200 1.00 40.00 O
+ATOM 1393 N TRP A 199 -23.064 -10.169 44.385 1.00 40.00 N
+ATOM 1394 CA TRP A 199 -21.941 -9.382 44.886 1.00 40.00 C
+ATOM 1395 C TRP A 199 -21.843 -8.076 44.161 1.00 40.00 C
+ATOM 1396 O TRP A 199 -21.849 -8.043 42.925 1.00 40.00 O
+ATOM 1397 CB TRP A 199 -20.639 -10.146 44.725 1.00 40.00 C
+ATOM 1398 CG TRP A 199 -19.601 -9.819 45.772 1.00 40.00 C
+ATOM 1399 CD1 TRP A 199 -19.549 -8.704 46.601 1.00 40.00 C
+ATOM 1400 CD2 TRP A 199 -18.403 -10.606 46.118 1.00 40.00 C
+ATOM 1401 NE1 TRP A 199 -18.453 -8.756 47.421 1.00 40.00 N
+ATOM 1402 CE2 TRP A 199 -17.724 -9.869 47.178 1.00 40.00 C
+ATOM 1403 CE3 TRP A 199 -17.853 -11.811 45.675 1.00 40.00 C
+ATOM 1404 CZ2 TRP A 199 -16.549 -10.333 47.755 1.00 40.00 C
+ATOM 1405 CZ3 TRP A 199 -16.668 -12.271 46.267 1.00 40.00 C
+ATOM 1406 CH2 TRP A 199 -16.033 -11.549 47.282 1.00 40.00 C
+ATOM 1407 N LEU A 200 -21.745 -6.989 44.922 1.00 40.00 N
+ATOM 1408 CA LEU A 200 -21.708 -5.662 44.342 1.00 40.00 C
+ATOM 1409 C LEU A 200 -20.494 -4.892 44.774 1.00 40.00 C
+ATOM 1410 O LEU A 200 -20.218 -4.785 45.961 1.00 40.00 O
+ATOM 1411 CB LEU A 200 -22.951 -4.868 44.729 1.00 40.00 C
+ATOM 1412 CG LEU A 200 -22.899 -3.357 44.467 1.00 40.00 C
+ATOM 1413 CD1 LEU A 200 -22.604 -3.017 43.015 1.00 40.00 C
+ATOM 1414 CD2 LEU A 200 -24.198 -2.711 44.901 1.00 40.00 C
+ATOM 1415 N PHE A 201 -19.795 -4.330 43.796 1.00 40.00 N
+ATOM 1416 CA PHE A 201 -18.699 -3.401 44.043 1.00 40.00 C
+ATOM 1417 C PHE A 201 -19.060 -2.019 43.493 1.00 40.00 C
+ATOM 1418 O PHE A 201 -19.343 -1.874 42.302 1.00 40.00 O
+ATOM 1419 CB PHE A 201 -17.404 -3.936 43.412 1.00 40.00 C
+ATOM 1420 CG PHE A 201 -16.817 -5.124 44.137 1.00 40.00 C
+ATOM 1421 CD1 PHE A 201 -17.472 -6.354 44.161 1.00 40.00 C
+ATOM 1422 CD2 PHE A 201 -15.600 -5.011 44.804 1.00 40.00 C
+ATOM 1423 CE1 PHE A 201 -16.926 -7.439 44.837 1.00 40.00 C
+ATOM 1424 CE2 PHE A 201 -15.049 -6.094 45.481 1.00 40.00 C
+ATOM 1425 CZ PHE A 201 -15.712 -7.308 45.495 1.00 40.00 C
+ATOM 1426 N LEU A 202 -19.081 -1.012 44.362 1.00 40.00 N
+ATOM 1427 CA LEU A 202 -19.356 0.348 43.915 1.00 40.00 C
+ATOM 1428 C LEU A 202 -18.323 1.363 44.359 1.00 40.00 C
+ATOM 1429 O LEU A 202 -18.145 1.606 45.548 1.00 40.00 O
+ATOM 1430 CB LEU A 202 -20.732 0.818 44.351 1.00 40.00 C
+ATOM 1431 CG LEU A 202 -20.907 2.333 44.162 1.00 40.00 C
+ATOM 1432 CD1 LEU A 202 -21.056 2.749 42.701 1.00 40.00 C
+ATOM 1433 CD2 LEU A 202 -22.085 2.826 44.977 1.00 40.00 C
+ATOM 1434 N GLY A 203 -17.688 1.989 43.377 1.00 40.00 N
+ATOM 1435 CA GLY A 203 -16.596 2.912 43.622 1.00 40.00 C
+ATOM 1436 C GLY A 203 -17.015 4.335 43.367 1.00 40.00 C
+ATOM 1437 O GLY A 203 -17.647 4.631 42.347 1.00 40.00 O
+ATOM 1438 N VAL A 204 -16.654 5.207 44.308 1.00 40.00 N
+ATOM 1439 CA VAL A 204 -16.982 6.638 44.261 1.00 40.00 C
+ATOM 1440 C VAL A 204 -15.888 7.537 44.858 1.00 40.00 C
+ATOM 1441 O VAL A 204 -14.970 7.041 45.526 1.00 40.00 O
+ATOM 1442 CB VAL A 204 -18.310 6.950 44.998 1.00 40.00 C
+ATOM 1443 CG1 VAL A 204 -19.514 6.676 44.101 1.00 40.00 C
+ATOM 1444 CG2 VAL A 204 -18.390 6.202 46.325 1.00 40.00 C
+ATOM 1445 N PRO A 205 -15.989 8.866 44.613 1.00 40.00 N
+ATOM 1446 CA PRO A 205 -15.120 9.837 45.278 1.00 40.00 C
+ATOM 1447 C PRO A 205 -15.268 9.916 46.814 1.00 40.00 C
+ATOM 1448 O PRO A 205 -14.289 9.735 47.535 1.00 40.00 O
+ATOM 1449 CB PRO A 205 -15.518 11.179 44.617 1.00 40.00 C
+ATOM 1450 CG PRO A 205 -16.813 10.933 43.903 1.00 40.00 C
+ATOM 1451 CD PRO A 205 -16.745 9.493 43.503 1.00 40.00 C
+ATOM 1452 N THR A 206 -16.478 10.178 47.297 1.00 40.00 N
+ATOM 1453 CA THR A 206 -16.685 10.568 48.689 1.00 40.00 C
+ATOM 1454 C THR A 206 -17.681 9.641 49.358 1.00 40.00 C
+ATOM 1455 O THR A 206 -18.304 8.828 48.696 1.00 40.00 O
+ATOM 1456 CB THR A 206 -17.222 12.022 48.791 1.00 40.00 C
+ATOM 1457 OG1 THR A 206 -18.350 12.190 47.921 1.00 40.00 O
+ATOM 1458 CG2 THR A 206 -16.152 13.053 48.412 1.00 40.00 C
+ATOM 1459 N SER A 207 -17.823 9.758 50.674 1.00 40.00 N
+ATOM 1460 CA SER A 207 -18.925 9.108 51.374 1.00 40.00 C
+ATOM 1461 C SER A 207 -20.210 9.890 51.163 1.00 40.00 C
+ATOM 1462 O SER A 207 -21.279 9.429 51.552 1.00 40.00 O
+ATOM 1463 CB SER A 207 -18.637 8.974 52.868 1.00 40.00 C
+ATOM 1464 OG SER A 207 -17.909 7.786 53.146 1.00 40.00 O
+ATOM 1465 N SER A 208 -20.089 11.073 50.556 1.00 40.00 N
+ATOM 1466 CA SER A 208 -21.235 11.913 50.171 1.00 40.00 C
+ATOM 1467 C SER A 208 -21.745 11.619 48.749 1.00 40.00 C
+ATOM 1468 O SER A 208 -22.867 12.000 48.396 1.00 40.00 O
+ATOM 1469 CB SER A 208 -20.900 13.405 50.313 1.00 40.00 C
+ATOM 1470 OG SER A 208 -19.921 13.819 49.373 1.00 40.00 O
+ATOM 1471 N SER A 209 -20.916 10.955 47.939 1.00 40.00 N
+ATOM 1472 CA SER A 209 -21.310 10.485 46.595 1.00 40.00 C
+ATOM 1473 C SER A 209 -21.835 9.021 46.607 1.00 40.00 C
+ATOM 1474 O SER A 209 -22.129 8.444 45.554 1.00 40.00 O
+ATOM 1475 CB SER A 209 -20.139 10.620 45.597 1.00 40.00 C
+ATOM 1476 OG SER A 209 -19.661 11.949 45.489 1.00 40.00 O
+ATOM 1477 N LEU A 210 -21.965 8.438 47.797 1.00 40.00 N
+ATOM 1478 CA LEU A 210 -22.286 7.027 47.947 1.00 40.00 C
+ATOM 1479 C LEU A 210 -23.788 6.758 47.786 1.00 40.00 C
+ATOM 1480 O LEU A 210 -24.528 6.776 48.772 1.00 40.00 O
+ATOM 1481 CB LEU A 210 -21.807 6.579 49.321 1.00 40.00 C
+ATOM 1482 CG LEU A 210 -21.345 5.146 49.534 1.00 40.00 C
+ATOM 1483 CD1 LEU A 210 -20.037 4.862 48.806 1.00 40.00 C
+ATOM 1484 CD2 LEU A 210 -21.198 4.942 51.035 1.00 40.00 C
+ATOM 1485 N LEU A 211 -24.227 6.483 46.555 1.00 40.00 N
+ATOM 1486 CA LEU A 211 -25.658 6.410 46.215 1.00 40.00 C
+ATOM 1487 C LEU A 211 -26.446 5.237 46.859 1.00 40.00 C
+ATOM 1488 O LEU A 211 -25.908 4.160 47.082 1.00 40.00 O
+ATOM 1489 CB LEU A 211 -25.823 6.424 44.690 1.00 40.00 C
+ATOM 1490 CG LEU A 211 -24.971 7.372 43.831 1.00 40.00 C
+ATOM 1491 CD1 LEU A 211 -25.086 6.992 42.370 1.00 40.00 C
+ATOM 1492 CD2 LEU A 211 -25.331 8.838 43.997 1.00 40.00 C
+ATOM 1493 N TYR A 212 -27.709 5.486 47.194 1.00 40.00 N
+ATOM 1494 CA TYR A 212 -28.674 4.449 47.591 1.00 40.00 C
+ATOM 1495 C TYR A 212 -28.276 3.519 48.735 1.00 40.00 C
+ATOM 1496 O TYR A 212 -28.945 2.514 48.956 1.00 40.00 O
+ATOM 1497 CB TYR A 212 -29.064 3.587 46.378 1.00 40.00 C
+ATOM 1498 CG TYR A 212 -29.405 4.350 45.104 1.00 40.00 C
+ATOM 1499 CD1 TYR A 212 -30.723 4.713 44.807 1.00 40.00 C
+ATOM 1500 CD2 TYR A 212 -28.413 4.678 44.180 1.00 40.00 C
+ATOM 1501 CE1 TYR A 212 -31.031 5.401 43.643 1.00 40.00 C
+ATOM 1502 CE2 TYR A 212 -28.708 5.367 43.015 1.00 40.00 C
+ATOM 1503 CZ TYR A 212 -30.013 5.726 42.749 1.00 40.00 C
+ATOM 1504 OH TYR A 212 -30.284 6.412 41.582 1.00 40.00 O
+ATOM 1505 N LYS A 213 -27.215 3.856 49.463 1.00 40.00 N
+ATOM 1506 CA LYS A 213 -26.605 2.952 50.469 1.00 40.00 C
+ATOM 1507 C LYS A 213 -27.572 2.268 51.483 1.00 40.00 C
+ATOM 1508 O LYS A 213 -27.448 1.060 51.756 1.00 40.00 O
+ATOM 1509 CB LYS A 213 -25.441 3.669 51.184 1.00 40.00 C
+ATOM 1510 CG LYS A 213 -24.832 2.963 52.398 1.00 40.00 C
+ATOM 1511 CD LYS A 213 -24.096 3.974 53.280 1.00 40.00 C
+ATOM 1512 CE LYS A 213 -23.843 3.473 54.696 1.00 40.00 C
+ATOM 1513 NZ LYS A 213 -22.624 2.627 54.814 1.00 40.00 N
+ATOM 1514 N GLU A 214 -28.522 3.039 52.022 1.00 40.00 N
+ATOM 1515 CA GLU A 214 -29.479 2.553 53.036 1.00 40.00 C
+ATOM 1516 C GLU A 214 -30.404 1.516 52.429 1.00 40.00 C
+ATOM 1517 O GLU A 214 -30.997 0.713 53.140 1.00 40.00 O
+ATOM 1518 CB GLU A 214 -30.344 3.682 53.632 1.00 40.00 C
+ATOM 1519 CG GLU A 214 -29.854 5.109 53.424 1.00 40.00 C
+ATOM 1520 CD GLU A 214 -29.645 5.459 51.958 1.00 40.00 C
+ATOM 1521 OE1 GLU A 214 -30.340 4.896 51.077 1.00 40.00 O
+ATOM 1522 OE2 GLU A 214 -28.759 6.292 51.684 1.00 40.00 O
+ATOM 1523 N GLU A 215 -30.550 1.559 51.111 1.00 40.00 N
+ATOM 1524 CA GLU A 215 -31.352 0.576 50.425 1.00 40.00 C
+ATOM 1525 C GLU A 215 -30.596 -0.732 50.453 1.00 40.00 C
+ATOM 1526 O GLU A 215 -31.072 -1.713 51.022 1.00 40.00 O
+ATOM 1527 CB GLU A 215 -31.652 1.023 49.002 1.00 40.00 C
+ATOM 1528 CG GLU A 215 -32.550 2.247 48.954 1.00 40.00 C
+ATOM 1529 CD GLU A 215 -32.960 2.613 47.550 1.00 40.00 C
+ATOM 1530 OE1 GLU A 215 -32.902 1.742 46.661 1.00 40.00 O
+ATOM 1531 OE2 GLU A 215 -33.349 3.779 47.339 1.00 40.00 O
+ATOM 1532 N PHE A 216 -29.393 -0.727 49.887 1.00 40.00 N
+ATOM 1533 CA PHE A 216 -28.559 -1.920 49.871 1.00 40.00 C
+ATOM 1534 C PHE A 216 -28.381 -2.455 51.277 1.00 40.00 C
+ATOM 1535 O PHE A 216 -28.292 -3.665 51.485 1.00 40.00 O
+ATOM 1536 CB PHE A 216 -27.200 -1.626 49.257 1.00 40.00 C
+ATOM 1537 CG PHE A 216 -27.274 -0.936 47.931 1.00 40.00 C
+ATOM 1538 CD1 PHE A 216 -27.761 -1.595 46.814 1.00 40.00 C
+ATOM 1539 CD2 PHE A 216 -26.845 0.376 47.794 1.00 40.00 C
+ATOM 1540 CE1 PHE A 216 -27.825 -0.955 45.585 1.00 40.00 C
+ATOM 1541 CE2 PHE A 216 -26.900 1.019 46.569 1.00 40.00 C
+ATOM 1542 CZ PHE A 216 -27.391 0.354 45.461 1.00 40.00 C
+ATOM 1543 N GLY A 217 -28.331 -1.544 52.239 1.00 40.00 N
+ATOM 1544 CA GLY A 217 -28.376 -1.933 53.630 1.00 40.00 C
+ATOM 1545 C GLY A 217 -29.563 -2.849 53.858 1.00 40.00 C
+ATOM 1546 O GLY A 217 -29.391 -4.018 54.214 1.00 40.00 O
+ATOM 1547 N LYS A 218 -30.765 -2.325 53.612 1.00 40.00 N
+ATOM 1548 CA LYS A 218 -32.014 -3.035 53.899 1.00 40.00 C
+ATOM 1549 C LYS A 218 -32.033 -4.391 53.233 1.00 40.00 C
+ATOM 1550 O LYS A 218 -32.654 -5.320 53.730 1.00 40.00 O
+ATOM 1551 CB LYS A 218 -33.234 -2.204 53.484 1.00 40.00 C
+ATOM 1552 CG LYS A 218 -33.508 -1.019 54.412 1.00 40.00 C
+ATOM 1553 CD LYS A 218 -34.755 -0.213 54.053 1.00 40.00 C
+ATOM 1554 CE LYS A 218 -34.466 0.952 53.109 1.00 40.00 C
+ATOM 1555 NZ LYS A 218 -35.689 1.772 52.869 1.00 40.00 N
+ATOM 1556 N MET A 219 -31.313 -4.501 52.123 1.00 40.00 N
+ATOM 1557 CA MET A 219 -31.187 -5.759 51.394 1.00 40.00 C
+ATOM 1558 C MET A 219 -30.257 -6.715 52.110 1.00 40.00 C
+ATOM 1559 O MET A 219 -30.664 -7.813 52.486 1.00 40.00 O
+ATOM 1560 CB MET A 219 -30.666 -5.503 49.986 1.00 40.00 C
+ATOM 1561 CG MET A 219 -31.499 -4.500 49.219 1.00 40.00 C
+ATOM 1562 SD MET A 219 -31.269 -4.665 47.449 1.00 40.00 S
+ATOM 1563 CE MET A 219 -32.434 -3.439 46.849 1.00 40.00 C
+ATOM 1564 N LYS A 220 -29.009 -6.278 52.285 1.00 40.00 N
+ATOM 1565 CA LYS A 220 -28.010 -7.009 53.056 1.00 40.00 C
+ATOM 1566 C LYS A 220 -28.624 -7.451 54.365 1.00 40.00 C
+ATOM 1567 O LYS A 220 -28.229 -8.468 54.931 1.00 40.00 O
+ATOM 1568 CB LYS A 220 -26.777 -6.133 53.334 1.00 40.00 C
+ATOM 1569 CG LYS A 220 -25.688 -6.776 54.193 1.00 40.00 C
+ATOM 1570 CD LYS A 220 -25.117 -8.007 53.517 1.00 40.00 C
+ATOM 1571 CE LYS A 220 -24.068 -8.675 54.376 1.00 40.00 C
+ATOM 1572 NZ LYS A 220 -23.592 -9.900 53.678 1.00 40.00 N
+ATOM 1573 N GLU A 221 -29.603 -6.686 54.831 1.00 40.00 N
+ATOM 1574 CA GLU A 221 -30.260 -6.993 56.077 1.00 40.00 C
+ATOM 1575 C GLU A 221 -31.314 -8.096 55.940 1.00 40.00 C
+ATOM 1576 O GLU A 221 -31.514 -8.889 56.875 1.00 40.00 O
+ATOM 1577 CB GLU A 221 -30.867 -5.738 56.666 1.00 40.00 C
+ATOM 1578 CG GLU A 221 -31.057 -5.839 58.160 1.00 40.00 C
+ATOM 1579 CD GLU A 221 -32.118 -4.892 58.654 1.00 40.00 C
+ATOM 1580 OE1 GLU A 221 -32.139 -3.737 58.177 1.00 40.00 O
+ATOM 1581 OE2 GLU A 221 -32.930 -5.301 59.513 1.00 40.00 O
+ATOM 1582 N ARG A 222 -31.983 -8.164 54.791 1.00 40.00 N
+ATOM 1583 CA ARG A 222 -32.971 -9.222 54.591 1.00 40.00 C
+ATOM 1584 C ARG A 222 -32.480 -10.386 53.733 1.00 40.00 C
+ATOM 1585 O ARG A 222 -33.196 -11.366 53.568 1.00 40.00 O
+ATOM 1586 CB ARG A 222 -34.301 -8.669 54.090 1.00 40.00 C
+ATOM 1587 CG ARG A 222 -34.164 -7.635 53.000 1.00 40.00 C
+ATOM 1588 CD ARG A 222 -35.456 -6.860 52.895 1.00 40.00 C
+ATOM 1589 NE ARG A 222 -36.524 -7.716 52.387 1.00 40.00 N
+ATOM 1590 CZ ARG A 222 -37.757 -7.302 52.097 1.00 40.00 C
+ATOM 1591 NH1 ARG A 222 -38.101 -6.025 52.277 1.00 40.00 N
+ATOM 1592 NH2 ARG A 222 -38.652 -8.171 51.625 1.00 40.00 N
+ATOM 1593 N ALA A 223 -31.262 -10.290 53.204 1.00 40.00 N
+ATOM 1594 CA ALA A 223 -30.637 -11.435 52.533 1.00 40.00 C
+ATOM 1595 C ALA A 223 -29.128 -11.479 52.745 1.00 40.00 C
+ATOM 1596 O ALA A 223 -28.356 -11.283 51.805 1.00 40.00 O
+ATOM 1597 CB ALA A 223 -30.966 -11.437 51.056 1.00 40.00 C
+ATOM 1598 N PRO A 224 -28.707 -11.758 53.986 1.00 40.00 N
+ATOM 1599 CA PRO A 224 -27.305 -11.668 54.373 1.00 40.00 C
+ATOM 1600 C PRO A 224 -26.340 -12.503 53.515 1.00 40.00 C
+ATOM 1601 O PRO A 224 -25.296 -11.985 53.109 1.00 40.00 O
+ATOM 1602 CB PRO A 224 -27.306 -12.142 55.836 1.00 40.00 C
+ATOM 1603 CG PRO A 224 -28.593 -12.858 56.024 1.00 40.00 C
+ATOM 1604 CD PRO A 224 -29.559 -12.193 55.105 1.00 40.00 C
+ATOM 1605 N GLU A 225 -26.681 -13.764 53.235 1.00 40.00 N
+ATOM 1606 CA GLU A 225 -25.782 -14.660 52.480 1.00 40.00 C
+ATOM 1607 C GLU A 225 -25.941 -14.552 50.960 1.00 40.00 C
+ATOM 1608 O GLU A 225 -25.012 -14.894 50.215 1.00 40.00 O
+ATOM 1609 CB GLU A 225 -25.928 -16.120 52.927 1.00 40.00 C
+ATOM 1610 CG GLU A 225 -27.322 -16.710 52.744 1.00 40.00 C
+ATOM 1611 CD GLU A 225 -28.098 -16.815 54.046 1.00 40.00 C
+ATOM 1612 OE1 GLU A 225 -28.088 -15.849 54.845 1.00 40.00 O
+ATOM 1613 OE2 GLU A 225 -28.725 -17.876 54.269 1.00 40.00 O
+ATOM 1614 N ASN A 226 -27.114 -14.073 50.521 1.00 40.00 N
+ATOM 1615 CA ASN A 226 -27.470 -13.925 49.090 1.00 40.00 C
+ATOM 1616 C ASN A 226 -27.034 -12.602 48.471 1.00 40.00 C
+ATOM 1617 O ASN A 226 -27.124 -12.393 47.255 1.00 40.00 O
+ATOM 1618 CB ASN A 226 -28.975 -14.084 48.921 1.00 40.00 C
+ATOM 1619 CG ASN A 226 -29.481 -15.365 49.527 1.00 40.00 C
+ATOM 1620 OD1 ASN A 226 -29.251 -16.453 48.987 1.00 40.00 O
+ATOM 1621 ND2 ASN A 226 -30.154 -15.250 50.671 1.00 40.00 N
+ATOM 1622 N PHE A 227 -26.562 -11.719 49.340 1.00 40.00 N
+ATOM 1623 CA PHE A 227 -26.097 -10.412 48.955 1.00 40.00 C
+ATOM 1624 C PHE A 227 -24.800 -10.078 49.674 1.00 40.00 C
+ATOM 1625 O PHE A 227 -24.652 -10.328 50.879 1.00 40.00 O
+ATOM 1626 CB PHE A 227 -27.157 -9.375 49.295 1.00 40.00 C
+ATOM 1627 CG PHE A 227 -26.880 -8.011 48.735 1.00 40.00 C
+ATOM 1628 CD1 PHE A 227 -26.245 -7.858 47.498 1.00 40.00 C
+ATOM 1629 CD2 PHE A 227 -27.293 -6.875 49.425 1.00 40.00 C
+ATOM 1630 CE1 PHE A 227 -26.000 -6.600 46.977 1.00 40.00 C
+ATOM 1631 CE2 PHE A 227 -27.062 -5.611 48.905 1.00 40.00 C
+ATOM 1632 CZ PHE A 227 -26.413 -5.472 47.680 1.00 40.00 C
+ATOM 1633 N ARG A 228 -23.864 -9.522 48.909 1.00 40.00 N
+ATOM 1634 CA ARG A 228 -22.584 -9.059 49.423 1.00 40.00 C
+ATOM 1635 C ARG A 228 -22.272 -7.732 48.757 1.00 40.00 C
+ATOM 1636 O ARG A 228 -22.294 -7.626 47.537 1.00 40.00 O
+ATOM 1637 CB ARG A 228 -21.477 -10.086 49.144 1.00 40.00 C
+ATOM 1638 CG ARG A 228 -21.620 -11.404 49.909 1.00 40.00 C
+ATOM 1639 CD ARG A 228 -20.396 -12.290 49.734 1.00 40.00 C
+ATOM 1640 NE ARG A 228 -19.180 -11.627 50.216 1.00 40.00 N
+ATOM 1641 CZ ARG A 228 -17.948 -12.142 50.157 1.00 40.00 C
+ATOM 1642 NH1 ARG A 228 -17.728 -13.352 49.626 1.00 40.00 N
+ATOM 1643 NH2 ARG A 228 -16.925 -11.436 50.633 1.00 40.00 N
+ATOM 1644 N VAL A 229 -22.021 -6.708 49.557 1.00 40.00 N
+ATOM 1645 CA VAL A 229 -21.687 -5.419 48.996 1.00 40.00 C
+ATOM 1646 C VAL A 229 -20.295 -5.054 49.403 1.00 40.00 C
+ATOM 1647 O VAL A 229 -19.782 -5.530 50.416 1.00 40.00 O
+ATOM 1648 CB VAL A 229 -22.580 -4.289 49.509 1.00 40.00 C
+ATOM 1649 CG1 VAL A 229 -22.712 -3.220 48.439 1.00 40.00 C
+ATOM 1650 CG2 VAL A 229 -23.938 -4.815 49.931 1.00 40.00 C
+ATOM 1651 N ASP A 230 -19.700 -4.188 48.601 1.00 40.00 N
+ATOM 1652 CA ASP A 230 -18.407 -3.619 48.879 1.00 40.00 C
+ATOM 1653 C ASP A 230 -18.415 -2.248 48.233 1.00 40.00 C
+ATOM 1654 O ASP A 230 -18.835 -2.102 47.085 1.00 40.00 O
+ATOM 1655 CB ASP A 230 -17.298 -4.490 48.279 1.00 40.00 C
+ATOM 1656 CG ASP A 230 -16.973 -5.704 49.136 1.00 40.00 C
+ATOM 1657 OD1 ASP A 230 -16.034 -5.598 49.948 1.00 40.00 O
+ATOM 1658 OD2 ASP A 230 -17.648 -6.752 49.015 1.00 40.00 O
+ATOM 1659 N TYR A 231 -17.982 -1.234 48.966 1.00 40.00 N
+ATOM 1660 CA TYR A 231 -17.850 0.083 48.370 1.00 40.00 C
+ATOM 1661 C TYR A 231 -16.393 0.463 48.281 1.00 40.00 C
+ATOM 1662 O TYR A 231 -15.554 -0.159 48.918 1.00 40.00 O
+ATOM 1663 CB TYR A 231 -18.571 1.102 49.200 1.00 40.00 C
+ATOM 1664 CG TYR A 231 -19.999 0.764 49.485 1.00 40.00 C
+ATOM 1665 CD1 TYR A 231 -20.342 -0.075 50.543 1.00 40.00 C
+ATOM 1666 CD2 TYR A 231 -21.017 1.318 48.725 1.00 40.00 C
+ATOM 1667 CE1 TYR A 231 -21.667 -0.360 50.825 1.00 40.00 C
+ATOM 1668 CE2 TYR A 231 -22.346 1.044 49.000 1.00 40.00 C
+ATOM 1669 CZ TYR A 231 -22.666 0.205 50.050 1.00 40.00 C
+ATOM 1670 OH TYR A 231 -23.986 -0.065 50.331 1.00 40.00 O
+ATOM 1671 N ALA A 232 -16.088 1.480 47.485 1.00 40.00 N
+ATOM 1672 CA ALA A 232 -14.719 1.959 47.359 1.00 40.00 C
+ATOM 1673 C ALA A 232 -14.712 3.481 47.249 1.00 40.00 C
+ATOM 1674 O ALA A 232 -14.956 4.045 46.177 1.00 40.00 O
+ATOM 1675 CB ALA A 232 -14.020 1.311 46.171 1.00 40.00 C
+ATOM 1676 N VAL A 233 -14.452 4.139 48.375 1.00 40.00 N
+ATOM 1677 CA VAL A 233 -14.387 5.593 48.420 1.00 40.00 C
+ATOM 1678 C VAL A 233 -12.940 6.018 48.170 1.00 40.00 C
+ATOM 1679 O VAL A 233 -12.092 5.940 49.065 1.00 40.00 O
+ATOM 1680 CB VAL A 233 -14.890 6.143 49.768 1.00 40.00 C
+ATOM 1681 CG1 VAL A 233 -15.344 7.574 49.603 1.00 40.00 C
+ATOM 1682 CG2 VAL A 233 -16.033 5.301 50.309 1.00 40.00 C
+ATOM 1683 N SER A 234 -12.660 6.453 46.944 1.00 40.00 N
+ATOM 1684 CA SER A 234 -11.289 6.780 46.530 1.00 40.00 C
+ATOM 1685 C SER A 234 -10.607 7.838 47.424 1.00 40.00 C
+ATOM 1686 O SER A 234 -9.396 7.754 47.685 1.00 40.00 O
+ATOM 1687 CB SER A 234 -11.255 7.177 45.046 1.00 40.00 C
+ATOM 1688 OG SER A 234 -11.900 8.418 44.799 1.00 40.00 O
+ATOM 1689 N ARG A 235 -11.404 8.794 47.917 1.00 40.00 N
+ATOM 1690 CA ARG A 235 -10.918 9.949 48.687 1.00 40.00 C
+ATOM 1691 C ARG A 235 -11.096 9.871 50.200 1.00 40.00 C
+ATOM 1692 O ARG A 235 -11.116 10.918 50.862 1.00 40.00 O
+ATOM 1693 CB ARG A 235 -11.632 11.209 48.232 1.00 40.00 C
+ATOM 1694 CG ARG A 235 -11.318 11.648 46.835 1.00 40.00 C
+ATOM 1695 CD ARG A 235 -11.957 12.997 46.690 1.00 40.00 C
+ATOM 1696 NE ARG A 235 -11.945 13.453 45.316 1.00 40.00 N
+ATOM 1697 CZ ARG A 235 -12.796 14.350 44.829 1.00 40.00 C
+ATOM 1698 NH1 ARG A 235 -13.742 14.873 45.610 1.00 40.00 N
+ATOM 1699 NH2 ARG A 235 -12.710 14.718 43.556 1.00 40.00 N
+ATOM 1700 N GLU A 236 -11.238 8.660 50.746 1.00 40.00 N
+ATOM 1701 CA GLU A 236 -11.512 8.488 52.176 1.00 40.00 C
+ATOM 1702 C GLU A 236 -11.080 7.147 52.705 1.00 40.00 C
+ATOM 1703 O GLU A 236 -11.354 6.799 53.852 1.00 40.00 O
+ATOM 1704 CB GLU A 236 -12.993 8.654 52.465 1.00 40.00 C
+ATOM 1705 CG GLU A 236 -13.464 10.092 52.463 1.00 40.00 C
+ATOM 1706 CD GLU A 236 -14.932 10.191 52.757 1.00 40.00 C
+ATOM 1707 OE1 GLU A 236 -15.373 9.527 53.725 1.00 40.00 O
+ATOM 1708 OE2 GLU A 236 -15.633 10.922 52.020 1.00 40.00 O
+ATOM 1709 N GLN A 237 -10.435 6.375 51.849 1.00 40.00 N
+ATOM 1710 CA GLN A 237 -9.888 5.092 52.244 1.00 40.00 C
+ATOM 1711 C GLN A 237 -8.631 4.851 51.429 1.00 40.00 C
+ATOM 1712 O GLN A 237 -8.480 5.381 50.319 1.00 40.00 O
+ATOM 1713 CB GLN A 237 -10.882 3.950 51.988 1.00 40.00 C
+ATOM 1714 CG GLN A 237 -12.212 4.036 52.720 1.00 40.00 C
+ATOM 1715 CD GLN A 237 -13.285 3.197 52.056 1.00 40.00 C
+ATOM 1716 OE1 GLN A 237 -13.250 2.955 50.849 1.00 40.00 O
+ATOM 1717 NE2 GLN A 237 -14.249 2.751 52.843 1.00 40.00 N
+ATOM 1718 N THR A 238 -7.720 4.075 52.005 1.00 40.00 N
+ATOM 1719 CA THR A 238 -6.615 3.488 51.262 1.00 40.00 C
+ATOM 1720 C THR A 238 -6.430 2.047 51.743 1.00 40.00 C
+ATOM 1721 O THR A 238 -7.001 1.637 52.766 1.00 40.00 O
+ATOM 1722 CB THR A 238 -5.293 4.290 51.380 1.00 40.00 C
+ATOM 1723 OG1 THR A 238 -4.833 4.265 52.730 1.00 40.00 O
+ATOM 1724 CG2 THR A 238 -5.450 5.752 50.914 1.00 40.00 C
+ATOM 1725 N ASN A 239 -5.656 1.277 50.983 1.00 40.00 N
+ATOM 1726 CA ASN A 239 -5.400 -0.120 51.313 1.00 40.00 C
+ATOM 1727 C ASN A 239 -4.243 -0.263 52.295 1.00 40.00 C
+ATOM 1728 O ASN A 239 -3.701 0.753 52.772 1.00 40.00 O
+ATOM 1729 CB ASN A 239 -5.166 -0.965 50.041 1.00 40.00 C
+ATOM 1730 CG ASN A 239 -4.091 -0.390 49.119 1.00 40.00 C
+ATOM 1731 OD1 ASN A 239 -3.859 0.815 49.079 1.00 40.00 O
+ATOM 1732 ND2 ASN A 239 -3.445 -1.266 48.355 1.00 40.00 N
+ATOM 1733 N ALA A 240 -3.885 -1.519 52.600 1.00 40.00 N
+ATOM 1734 CA ALA A 240 -2.667 -1.830 53.349 1.00 40.00 C
+ATOM 1735 C ALA A 240 -1.430 -1.258 52.637 1.00 40.00 C
+ATOM 1736 O ALA A 240 -0.485 -0.809 53.291 1.00 40.00 O
+ATOM 1737 CB ALA A 240 -2.531 -3.324 53.563 1.00 40.00 C
+ATOM 1738 N ALA A 241 -1.459 -1.237 51.306 1.00 40.00 N
+ATOM 1739 CA ALA A 241 -0.391 -0.616 50.521 1.00 40.00 C
+ATOM 1740 C ALA A 241 -0.400 0.954 50.457 1.00 40.00 C
+ATOM 1741 O ALA A 241 0.414 1.565 49.752 1.00 40.00 O
+ATOM 1742 CB ALA A 241 -0.351 -1.244 49.137 1.00 40.00 C
+ATOM 1743 N GLY A 242 -1.297 1.597 51.206 1.00 40.00 N
+ATOM 1744 CA GLY A 242 -1.349 3.070 51.279 1.00 40.00 C
+ATOM 1745 C GLY A 242 -1.703 3.838 49.998 1.00 40.00 C
+ATOM 1746 O GLY A 242 -1.227 4.970 49.782 1.00 40.00 O
+ATOM 1747 N GLU A 243 -2.551 3.229 49.161 1.00 40.00 N
+ATOM 1748 CA GLU A 243 -2.998 3.815 47.882 1.00 40.00 C
+ATOM 1749 C GLU A 243 -4.501 4.007 47.915 1.00 40.00 C
+ATOM 1750 O GLU A 243 -5.203 3.246 48.595 1.00 40.00 O
+ATOM 1751 CB GLU A 243 -2.682 2.876 46.718 1.00 40.00 C
+ATOM 1752 CG GLU A 243 -1.593 1.855 47.014 1.00 40.00 C
+ATOM 1753 CD GLU A 243 -1.617 0.674 46.063 1.00 40.00 C
+ATOM 1754 OE1 GLU A 243 -1.472 0.898 44.843 1.00 40.00 O
+ATOM 1755 OE2 GLU A 243 -1.763 -0.479 46.531 1.00 40.00 O
+ATOM 1756 N ARG A 244 -4.988 5.000 47.162 1.00 40.00 N
+ATOM 1757 CA ARG A 244 -6.425 5.328 47.105 1.00 40.00 C
+ATOM 1758 C ARG A 244 -7.339 4.144 46.701 1.00 40.00 C
+ATOM 1759 O ARG A 244 -7.059 3.420 45.729 1.00 40.00 O
+ATOM 1760 CB ARG A 244 -6.657 6.517 46.186 1.00 40.00 C
+ATOM 1761 CG ARG A 244 -6.320 7.850 46.813 1.00 40.00 C
+ATOM 1762 CD ARG A 244 -6.601 8.952 45.797 1.00 40.00 C
+ATOM 1763 NE ARG A 244 -6.305 10.309 46.284 1.00 40.00 N
+ATOM 1764 CZ ARG A 244 -6.022 11.360 45.506 1.00 40.00 C
+ATOM 1765 NH1 ARG A 244 -5.966 11.247 44.176 1.00 40.00 N
+ATOM 1766 NH2 ARG A 244 -5.768 12.532 46.074 1.00 40.00 N
+ATOM 1767 N MET A 245 -8.423 3.953 47.458 1.00 40.00 N
+ATOM 1768 CA MET A 245 -9.300 2.807 47.257 1.00 40.00 C
+ATOM 1769 C MET A 245 -10.158 2.997 46.025 1.00 40.00 C
+ATOM 1770 O MET A 245 -11.228 3.604 46.072 1.00 40.00 O
+ATOM 1771 CB MET A 245 -10.171 2.550 48.484 1.00 40.00 C
+ATOM 1772 CG MET A 245 -10.926 1.225 48.435 1.00 40.00 C
+ATOM 1773 SD MET A 245 -9.869 -0.242 48.406 1.00 40.00 S
+ATOM 1774 CE MET A 245 -9.239 -0.262 50.089 1.00 40.00 C
+ATOM 1775 N TYR A 246 -9.662 2.489 44.909 1.00 40.00 N
+ATOM 1776 CA TYR A 246 -10.440 2.475 43.689 1.00 40.00 C
+ATOM 1777 C TYR A 246 -11.153 1.148 43.600 1.00 40.00 C
+ATOM 1778 O TYR A 246 -10.849 0.221 44.368 1.00 40.00 O
+ATOM 1779 CB TYR A 246 -9.548 2.732 42.479 1.00 40.00 C
+ATOM 1780 CG TYR A 246 -8.975 4.122 42.523 1.00 40.00 C
+ATOM 1781 CD1 TYR A 246 -9.821 5.240 42.564 1.00 40.00 C
+ATOM 1782 CD2 TYR A 246 -7.592 4.333 42.563 1.00 40.00 C
+ATOM 1783 CE1 TYR A 246 -9.310 6.528 42.625 1.00 40.00 C
+ATOM 1784 CE2 TYR A 246 -7.071 5.626 42.630 1.00 40.00 C
+ATOM 1785 CZ TYR A 246 -7.936 6.720 42.659 1.00 40.00 C
+ATOM 1786 OH TYR A 246 -7.435 8.007 42.715 1.00 40.00 O
+ATOM 1787 N ILE A 247 -12.121 1.060 42.688 1.00 40.00 N
+ATOM 1788 CA ILE A 247 -12.915 -0.157 42.544 1.00 40.00 C
+ATOM 1789 C ILE A 247 -11.998 -1.369 42.495 1.00 40.00 C
+ATOM 1790 O ILE A 247 -12.138 -2.305 43.288 1.00 40.00 O
+ATOM 1791 CB ILE A 247 -13.869 -0.105 41.332 1.00 40.00 C
+ATOM 1792 CG1 ILE A 247 -14.676 -1.397 41.278 1.00 40.00 C
+ATOM 1793 CG2 ILE A 247 -13.127 0.175 40.027 1.00 40.00 C
+ATOM 1794 CD1 ILE A 247 -16.070 -1.219 40.729 1.00 40.00 C
+ATOM 1795 N GLN A 248 -11.026 -1.297 41.592 1.00 40.00 N
+ATOM 1796 CA GLN A 248 -10.024 -2.336 41.429 1.00 40.00 C
+ATOM 1797 C GLN A 248 -9.315 -2.681 42.736 1.00 40.00 C
+ATOM 1798 O GLN A 248 -9.077 -3.859 43.012 1.00 40.00 O
+ATOM 1799 CB GLN A 248 -9.009 -1.953 40.339 1.00 40.00 C
+ATOM 1800 CG GLN A 248 -8.233 -0.661 40.564 1.00 40.00 C
+ATOM 1801 CD GLN A 248 -8.895 0.546 39.935 1.00 40.00 C
+ATOM 1802 OE1 GLN A 248 -10.113 0.687 39.968 1.00 40.00 O
+ATOM 1803 NE2 GLN A 248 -8.088 1.429 39.361 1.00 40.00 N
+ATOM 1804 N THR A 249 -9.002 -1.650 43.528 1.00 40.00 N
+ATOM 1805 CA THR A 249 -8.272 -1.790 44.790 1.00 40.00 C
+ATOM 1806 C THR A 249 -9.101 -2.584 45.799 1.00 40.00 C
+ATOM 1807 O THR A 249 -8.594 -3.504 46.443 1.00 40.00 O
+ATOM 1808 CB THR A 249 -7.877 -0.416 45.391 1.00 40.00 C
+ATOM 1809 OG1 THR A 249 -7.721 0.559 44.350 1.00 40.00 O
+ATOM 1810 CG2 THR A 249 -6.580 -0.521 46.181 1.00 40.00 C
+ATOM 1811 N ARG A 250 -10.379 -2.241 45.919 1.00 40.00 N
+ATOM 1812 CA ARG A 250 -11.274 -2.991 46.784 1.00 40.00 C
+ATOM 1813 C ARG A 250 -11.442 -4.433 46.302 1.00 40.00 C
+ATOM 1814 O ARG A 250 -11.462 -5.370 47.114 1.00 40.00 O
+ATOM 1815 CB ARG A 250 -12.637 -2.309 46.868 1.00 40.00 C
+ATOM 1816 CG ARG A 250 -13.690 -3.110 47.640 1.00 40.00 C
+ATOM 1817 CD ARG A 250 -13.400 -3.138 49.131 1.00 40.00 C
+ATOM 1818 NE ARG A 250 -13.244 -1.771 49.632 1.00 40.00 N
+ATOM 1819 CZ ARG A 250 -12.578 -1.426 50.734 1.00 40.00 C
+ATOM 1820 NH1 ARG A 250 -11.990 -2.350 51.478 1.00 40.00 N
+ATOM 1821 NH2 ARG A 250 -12.495 -0.147 51.096 1.00 40.00 N
+ATOM 1822 N MET A 251 -11.581 -4.591 44.982 1.00 40.00 N
+ATOM 1823 CA MET A 251 -11.716 -5.901 44.350 1.00 40.00 C
+ATOM 1824 C MET A 251 -10.500 -6.738 44.665 1.00 40.00 C
+ATOM 1825 O MET A 251 -10.630 -7.863 45.142 1.00 40.00 O
+ATOM 1826 CB MET A 251 -11.836 -5.759 42.844 1.00 40.00 C
+ATOM 1827 CG MET A 251 -13.208 -5.348 42.370 1.00 40.00 C
+ATOM 1828 SD MET A 251 -13.105 -4.663 40.713 1.00 40.00 S
+ATOM 1829 CE MET A 251 -12.752 -6.110 39.727 1.00 40.00 C
+ATOM 1830 N ALA A 252 -9.322 -6.165 44.410 1.00 40.00 N
+ATOM 1831 CA ALA A 252 -8.037 -6.812 44.677 1.00 40.00 C
+ATOM 1832 C ALA A 252 -8.004 -7.464 46.059 1.00 40.00 C
+ATOM 1833 O ALA A 252 -7.259 -8.424 46.283 1.00 40.00 O
+ATOM 1834 CB ALA A 252 -6.892 -5.818 44.521 1.00 40.00 C
+ATOM 1835 N GLU A 253 -8.829 -6.949 46.971 1.00 40.00 N
+ATOM 1836 CA GLU A 253 -8.964 -7.513 48.315 1.00 40.00 C
+ATOM 1837 C GLU A 253 -9.618 -8.899 48.324 1.00 40.00 C
+ATOM 1838 O GLU A 253 -9.644 -9.574 49.354 1.00 40.00 O
+ATOM 1839 CB GLU A 253 -9.750 -6.566 49.219 1.00 40.00 C
+ATOM 1840 CG GLU A 253 -9.057 -5.250 49.498 1.00 40.00 C
+ATOM 1841 CD GLU A 253 -9.732 -4.479 50.608 1.00 40.00 C
+ATOM 1842 OE1 GLU A 253 -9.069 -3.587 51.176 1.00 40.00 O
+ATOM 1843 OE2 GLU A 253 -10.913 -4.765 50.917 1.00 40.00 O
+ATOM 1844 N TYR A 254 -10.143 -9.320 47.182 1.00 40.00 N
+ATOM 1845 CA TYR A 254 -10.752 -10.626 47.082 1.00 40.00 C
+ATOM 1846 C TYR A 254 -10.238 -11.339 45.856 1.00 40.00 C
+ATOM 1847 O TYR A 254 -10.873 -12.280 45.382 1.00 40.00 O
+ATOM 1848 CB TYR A 254 -12.256 -10.492 46.941 1.00 40.00 C
+ATOM 1849 CG TYR A 254 -12.975 -9.750 48.035 1.00 40.00 C
+ATOM 1850 CD1 TYR A 254 -13.483 -10.434 49.136 1.00 40.00 C
+ATOM 1851 CD2 TYR A 254 -13.205 -8.364 47.942 1.00 40.00 C
+ATOM 1852 CE1 TYR A 254 -14.183 -9.770 50.131 1.00 40.00 C
+ATOM 1853 CE2 TYR A 254 -13.905 -7.684 48.936 1.00 40.00 C
+ATOM 1854 CZ TYR A 254 -14.395 -8.397 50.030 1.00 40.00 C
+ATOM 1855 OH TYR A 254 -15.099 -7.767 51.034 1.00 40.00 O
+ATOM 1856 N LYS A 255 -9.098 -10.893 45.337 1.00 40.00 N
+ATOM 1857 CA LYS A 255 -8.579 -11.415 44.072 1.00 40.00 C
+ATOM 1858 C LYS A 255 -8.622 -12.944 44.015 1.00 40.00 C
+ATOM 1859 O LYS A 255 -8.538 -13.537 42.939 1.00 40.00 O
+ATOM 1860 CB LYS A 255 -7.174 -10.866 43.782 1.00 40.00 C
+ATOM 1861 CG LYS A 255 -6.121 -11.123 44.859 1.00 40.00 C
+ATOM 1862 CD LYS A 255 -4.916 -10.193 44.690 1.00 40.00 C
+ATOM 1863 CE LYS A 255 -3.747 -10.562 45.606 1.00 40.00 C
+ATOM 1864 NZ LYS A 255 -2.946 -11.712 45.095 1.00 40.00 N
+ATOM 1865 N GLU A 256 -8.787 -13.554 45.194 1.00 40.00 N
+ATOM 1866 CA GLU A 256 -8.911 -15.009 45.376 1.00 40.00 C
+ATOM 1867 C GLU A 256 -10.266 -15.532 44.890 1.00 40.00 C
+ATOM 1868 O GLU A 256 -10.347 -16.062 43.771 1.00 40.00 O
+ATOM 1869 CB GLU A 256 -8.694 -15.414 46.852 1.00 40.00 C
+ATOM 1870 CG GLU A 256 -7.734 -14.537 47.657 1.00 40.00 C
+ATOM 1871 CD GLU A 256 -6.288 -14.625 47.185 1.00 40.00 C
+ATOM 1872 OE1 GLU A 256 -5.925 -15.636 46.534 1.00 40.00 O
+ATOM 1873 OE2 GLU A 256 -5.514 -13.676 47.473 1.00 40.00 O
+ATOM 1874 N GLU A 257 -11.317 -15.377 45.719 1.00 40.00 N
+ATOM 1875 CA GLU A 257 -12.663 -15.916 45.405 1.00 40.00 C
+ATOM 1876 C GLU A 257 -13.055 -15.502 44.012 1.00 40.00 C
+ATOM 1877 O GLU A 257 -13.594 -16.294 43.245 1.00 40.00 O
+ATOM 1878 CB GLU A 257 -13.785 -15.444 46.349 1.00 40.00 C
+ATOM 1879 CG GLU A 257 -13.543 -15.588 47.828 1.00 40.00 C
+ATOM 1880 CD GLU A 257 -12.964 -14.318 48.403 1.00 40.00 C
+ATOM 1881 OE1 GLU A 257 -11.737 -14.089 48.225 1.00 40.00 O
+ATOM 1882 OE2 GLU A 257 -13.746 -13.549 49.018 1.00 40.00 O
+ATOM 1883 N LEU A 258 -12.781 -14.241 43.703 1.00 40.00 N
+ATOM 1884 CA LEU A 258 -13.121 -13.680 42.415 1.00 40.00 C
+ATOM 1885 C LEU A 258 -12.502 -14.525 41.308 1.00 40.00 C
+ATOM 1886 O LEU A 258 -13.221 -15.147 40.528 1.00 40.00 O
+ATOM 1887 CB LEU A 258 -12.701 -12.204 42.338 1.00 40.00 C
+ATOM 1888 CG LEU A 258 -13.248 -11.262 43.435 1.00 40.00 C
+ATOM 1889 CD1 LEU A 258 -12.801 -9.832 43.172 1.00 40.00 C
+ATOM 1890 CD2 LEU A 258 -14.767 -11.313 43.604 1.00 40.00 C
+ATOM 1891 N TRP A 259 -11.178 -14.597 41.274 1.00 40.00 N
+ATOM 1892 CA TRP A 259 -10.516 -15.402 40.268 1.00 40.00 C
+ATOM 1893 C TRP A 259 -11.031 -16.805 40.217 1.00 40.00 C
+ATOM 1894 O TRP A 259 -11.203 -17.390 39.143 1.00 40.00 O
+ATOM 1895 CB TRP A 259 -9.031 -15.432 40.503 1.00 40.00 C
+ATOM 1896 CG TRP A 259 -8.376 -16.315 39.492 1.00 40.00 C
+ATOM 1897 CD1 TRP A 259 -7.599 -17.441 39.725 1.00 40.00 C
+ATOM 1898 CD2 TRP A 259 -8.479 -16.208 38.024 1.00 40.00 C
+ATOM 1899 NE1 TRP A 259 -7.192 -18.002 38.540 1.00 40.00 N
+ATOM 1900 CE2 TRP A 259 -7.690 -17.314 37.478 1.00 40.00 C
+ATOM 1901 CE3 TRP A 259 -9.110 -15.325 37.139 1.00 40.00 C
+ATOM 1902 CZ2 TRP A 259 -7.554 -17.516 36.100 1.00 40.00 C
+ATOM 1903 CZ3 TRP A 259 -8.967 -15.537 35.758 1.00 40.00 C
+ATOM 1904 CH2 TRP A 259 -8.207 -16.605 35.252 1.00 40.00 C
+ATOM 1905 N GLU A 260 -11.264 -17.352 41.399 1.00 40.00 N
+ATOM 1906 CA GLU A 260 -11.913 -18.634 41.538 1.00 40.00 C
+ATOM 1907 C GLU A 260 -13.270 -18.638 40.847 1.00 40.00 C
+ATOM 1908 O GLU A 260 -13.471 -19.364 39.865 1.00 40.00 O
+ATOM 1909 CB GLU A 260 -12.072 -18.983 43.018 1.00 40.00 C
+ATOM 1910 CG GLU A 260 -10.772 -19.396 43.679 1.00 40.00 C
+ATOM 1911 CD GLU A 260 -10.094 -20.535 42.938 1.00 40.00 C
+ATOM 1912 OE1 GLU A 260 -8.957 -20.310 42.443 1.00 40.00 O
+ATOM 1913 OE2 GLU A 260 -10.711 -21.636 42.832 1.00 40.00 O
+ATOM 1914 N LEU A 261 -14.183 -17.811 41.360 1.00 40.00 N
+ATOM 1915 CA LEU A 261 -15.549 -17.695 40.834 1.00 40.00 C
+ATOM 1916 C LEU A 261 -15.559 -17.431 39.325 1.00 40.00 C
+ATOM 1917 O LEU A 261 -16.569 -17.639 38.647 1.00 40.00 O
+ATOM 1918 CB LEU A 261 -16.319 -16.599 41.581 1.00 40.00 C
+ATOM 1919 CG LEU A 261 -16.818 -16.923 42.989 1.00 40.00 C
+ATOM 1920 CD1 LEU A 261 -16.672 -15.716 43.908 1.00 40.00 C
+ATOM 1921 CD2 LEU A 261 -18.251 -17.440 42.951 1.00 40.00 C
+ATOM 1922 N LEU A 262 -14.412 -17.000 38.811 1.00 40.00 N
+ATOM 1923 CA LEU A 262 -14.270 -16.685 37.403 1.00 40.00 C
+ATOM 1924 C LEU A 262 -14.189 -17.905 36.531 1.00 40.00 C
+ATOM 1925 O LEU A 262 -14.233 -17.802 35.303 1.00 40.00 O
+ATOM 1926 CB LEU A 262 -13.038 -15.823 37.160 1.00 40.00 C
+ATOM 1927 CG LEU A 262 -13.352 -14.325 37.180 1.00 40.00 C
+ATOM 1928 CD1 LEU A 262 -12.166 -13.531 36.670 1.00 40.00 C
+ATOM 1929 CD2 LEU A 262 -14.587 -13.993 36.351 1.00 40.00 C
+ATOM 1930 N LYS A 263 -14.059 -19.064 37.157 1.00 40.00 N
+ATOM 1931 CA LYS A 263 -13.965 -20.294 36.389 1.00 40.00 C
+ATOM 1932 C LYS A 263 -15.279 -21.094 36.432 1.00 40.00 C
+ATOM 1933 O LYS A 263 -15.423 -22.083 35.717 1.00 40.00 O
+ATOM 1934 CB LYS A 263 -12.705 -21.079 36.792 1.00 40.00 C
+ATOM 1935 CG LYS A 263 -11.428 -20.242 36.621 1.00 40.00 C
+ATOM 1936 CD LYS A 263 -10.148 -20.962 37.024 1.00 40.00 C
+ATOM 1937 CE LYS A 263 -9.915 -20.920 38.534 1.00 40.00 C
+ATOM 1938 NZ LYS A 263 -8.674 -21.639 38.953 1.00 40.00 N
+ATOM 1939 N LYS A 264 -16.243 -20.627 37.232 1.00 40.00 N
+ATOM 1940 CA LYS A 264 -17.583 -21.228 37.295 1.00 40.00 C
+ATOM 1941 C LYS A 264 -18.421 -20.900 36.064 1.00 40.00 C
+ATOM 1942 O LYS A 264 -18.123 -19.967 35.316 1.00 40.00 O
+ATOM 1943 CB LYS A 264 -18.328 -20.819 38.573 1.00 40.00 C
+ATOM 1944 CG LYS A 264 -17.896 -21.589 39.813 1.00 40.00 C
+ATOM 1945 CD LYS A 264 -18.712 -21.197 41.037 1.00 40.00 C
+ATOM 1946 CE LYS A 264 -18.562 -22.206 42.175 1.00 40.00 C
+ATOM 1947 NZ LYS A 264 -17.171 -22.350 42.699 1.00 40.00 N
+ATOM 1948 N ASP A 265 -19.468 -21.692 35.871 1.00 40.00 N
+ATOM 1949 CA ASP A 265 -20.310 -21.614 34.686 1.00 40.00 C
+ATOM 1950 C ASP A 265 -21.506 -20.747 34.935 1.00 40.00 C
+ATOM 1951 O ASP A 265 -22.216 -20.366 34.006 1.00 40.00 O
+ATOM 1952 CB ASP A 265 -20.819 -23.001 34.298 1.00 40.00 C
+ATOM 1953 CG ASP A 265 -19.878 -23.728 33.354 1.00 40.00 C
+ATOM 1954 OD1 ASP A 265 -19.949 -24.981 33.312 1.00 40.00 O
+ATOM 1955 OD2 ASP A 265 -19.075 -23.052 32.654 1.00 40.00 O
+ATOM 1956 N ASN A 266 -21.741 -20.454 36.201 1.00 40.00 N
+ATOM 1957 CA ASN A 266 -22.913 -19.694 36.580 1.00 40.00 C
+ATOM 1958 C ASN A 266 -22.515 -18.385 37.265 1.00 40.00 C
+ATOM 1959 O ASN A 266 -23.265 -17.830 38.077 1.00 40.00 O
+ATOM 1960 CB ASN A 266 -23.782 -20.546 37.489 1.00 40.00 C
+ATOM 1961 CG ASN A 266 -23.079 -20.908 38.782 1.00 40.00 C
+ATOM 1962 OD1 ASN A 266 -21.837 -20.970 38.849 1.00 40.00 O
+ATOM 1963 ND2 ASN A 266 -23.870 -21.139 39.824 1.00 40.00 N
+ATOM 1964 N THR A 267 -21.319 -17.908 36.933 1.00 40.00 N
+ATOM 1965 CA THR A 267 -20.837 -16.625 37.409 1.00 40.00 C
+ATOM 1966 C THR A 267 -20.857 -15.624 36.240 1.00 40.00 C
+ATOM 1967 O THR A 267 -20.141 -15.803 35.259 1.00 40.00 O
+ATOM 1968 CB THR A 267 -19.432 -16.772 38.031 1.00 40.00 C
+ATOM 1969 OG1 THR A 267 -19.489 -17.674 39.147 1.00 40.00 O
+ATOM 1970 CG2 THR A 267 -18.919 -15.445 38.514 1.00 40.00 C
+ATOM 1971 N TYR A 268 -21.697 -14.591 36.338 1.00 40.00 N
+ATOM 1972 CA TYR A 268 -21.846 -13.602 35.259 1.00 40.00 C
+ATOM 1973 C TYR A 268 -21.443 -12.208 35.721 1.00 40.00 C
+ATOM 1974 O TYR A 268 -21.956 -11.691 36.713 1.00 40.00 O
+ATOM 1975 CB TYR A 268 -23.285 -13.578 34.721 1.00 40.00 C
+ATOM 1976 CG TYR A 268 -23.874 -14.943 34.418 1.00 40.00 C
+ATOM 1977 CD1 TYR A 268 -24.509 -15.681 35.413 1.00 40.00 C
+ATOM 1978 CD2 TYR A 268 -23.801 -15.496 33.136 1.00 40.00 C
+ATOM 1979 CE1 TYR A 268 -25.050 -16.931 35.149 1.00 40.00 C
+ATOM 1980 CE2 TYR A 268 -24.342 -16.752 32.864 1.00 40.00 C
+ATOM 1981 CZ TYR A 268 -24.969 -17.461 33.879 1.00 40.00 C
+ATOM 1982 OH TYR A 268 -25.521 -18.700 33.652 1.00 40.00 O
+ATOM 1983 N VAL A 269 -20.528 -11.597 34.989 1.00 40.00 N
+ATOM 1984 CA VAL A 269 -19.997 -10.311 35.387 1.00 40.00 C
+ATOM 1985 C VAL A 269 -20.635 -9.174 34.620 1.00 40.00 C
+ATOM 1986 O VAL A 269 -20.812 -9.251 33.404 1.00 40.00 O
+ATOM 1987 CB VAL A 269 -18.490 -10.248 35.150 1.00 40.00 C
+ATOM 1988 CG1 VAL A 269 -18.001 -8.821 35.268 1.00 40.00 C
+ATOM 1989 CG2 VAL A 269 -17.771 -11.126 36.148 1.00 40.00 C
+ATOM 1990 N TYR A 270 -20.950 -8.106 35.339 1.00 40.00 N
+ATOM 1991 CA TYR A 270 -21.510 -6.931 34.724 1.00 40.00 C
+ATOM 1992 C TYR A 270 -20.739 -5.711 35.194 1.00 40.00 C
+ATOM 1993 O TYR A 270 -20.550 -5.508 36.386 1.00 40.00 O
+ATOM 1994 CB TYR A 270 -22.992 -6.798 35.083 1.00 40.00 C
+ATOM 1995 CG TYR A 270 -23.941 -7.857 34.507 1.00 40.00 C
+ATOM 1996 CD1 TYR A 270 -24.091 -9.107 35.114 1.00 40.00 C
+ATOM 1997 CD2 TYR A 270 -24.726 -7.584 33.383 1.00 40.00 C
+ATOM 1998 CE1 TYR A 270 -24.967 -10.059 34.602 1.00 40.00 C
+ATOM 1999 CE2 TYR A 270 -25.605 -8.530 32.865 1.00 40.00 C
+ATOM 2000 CZ TYR A 270 -25.725 -9.769 33.475 1.00 40.00 C
+ATOM 2001 OH TYR A 270 -26.603 -10.714 32.966 1.00 40.00 O
+ATOM 2002 N MET A 271 -20.289 -4.908 34.242 1.00 40.00 N
+ATOM 2003 CA MET A 271 -19.529 -3.706 34.528 1.00 40.00 C
+ATOM 2004 C MET A 271 -20.259 -2.507 33.939 1.00 40.00 C
+ATOM 2005 O MET A 271 -20.636 -2.524 32.762 1.00 40.00 O
+ATOM 2006 CB MET A 271 -18.133 -3.825 33.920 1.00 40.00 C
+ATOM 2007 CG MET A 271 -17.120 -2.855 34.488 1.00 40.00 C
+ATOM 2008 SD MET A 271 -15.619 -2.784 33.511 1.00 40.00 S
+ATOM 2009 CE MET A 271 -14.777 -4.264 34.022 1.00 40.00 C
+ATOM 2010 N CYS A 272 -20.459 -1.475 34.756 1.00 40.00 N
+ATOM 2011 CA CYS A 272 -21.139 -0.257 34.306 1.00 40.00 C
+ATOM 2012 C CYS A 272 -20.628 1.035 34.944 1.00 40.00 C
+ATOM 2013 O CYS A 272 -20.347 1.079 36.137 1.00 40.00 O
+ATOM 2014 CB CYS A 272 -22.635 -0.376 34.547 1.00 40.00 C
+ATOM 2015 SG CYS A 272 -23.569 0.962 33.788 1.00 40.00 S
+ATOM 2016 N GLY A 273 -20.520 2.088 34.140 1.00 40.00 N
+ATOM 2017 CA GLY A 273 -20.152 3.397 34.654 1.00 40.00 C
+ATOM 2018 C GLY A 273 -19.260 4.248 33.775 1.00 40.00 C
+ATOM 2019 O GLY A 273 -19.592 4.570 32.634 1.00 40.00 O
+ATOM 2020 N LEU A 274 -18.115 4.613 34.328 1.00 40.00 N
+ATOM 2021 CA LEU A 274 -17.276 5.636 33.744 1.00 40.00 C
+ATOM 2022 C LEU A 274 -16.165 5.022 32.930 1.00 40.00 C
+ATOM 2023 O LEU A 274 -15.307 4.310 33.460 1.00 40.00 O
+ATOM 2024 CB LEU A 274 -16.690 6.527 34.846 1.00 40.00 C
+ATOM 2025 CG LEU A 274 -17.668 7.296 35.753 1.00 40.00 C
+ATOM 2026 CD1 LEU A 274 -17.084 7.563 37.144 1.00 40.00 C
+ATOM 2027 CD2 LEU A 274 -18.161 8.582 35.075 1.00 40.00 C
+ATOM 2028 N LYS A 275 -16.182 5.308 31.635 1.00 40.00 N
+ATOM 2029 CA LYS A 275 -15.110 4.893 30.758 1.00 40.00 C
+ATOM 2030 C LYS A 275 -13.784 5.099 31.464 1.00 40.00 C
+ATOM 2031 O LYS A 275 -13.462 6.203 31.882 1.00 40.00 O
+ATOM 2032 CB LYS A 275 -15.141 5.716 29.481 1.00 40.00 C
+ATOM 2033 CG LYS A 275 -14.125 5.272 28.446 1.00 40.00 C
+ATOM 2034 CD LYS A 275 -14.314 6.044 27.151 1.00 40.00 C
+ATOM 2035 CE LYS A 275 -13.537 5.406 26.012 1.00 40.00 C
+ATOM 2036 NZ LYS A 275 -14.084 5.851 24.697 1.00 40.00 N
+ATOM 2037 N GLY A 276 -13.027 4.028 31.623 1.00 40.00 N
+ATOM 2038 CA GLY A 276 -11.723 4.140 32.245 1.00 40.00 C
+ATOM 2039 C GLY A 276 -11.553 3.188 33.402 1.00 40.00 C
+ATOM 2040 O GLY A 276 -10.442 2.704 33.659 1.00 40.00 O
+ATOM 2041 N MET A 277 -12.651 2.912 34.095 1.00 40.00 N
+ATOM 2042 CA MET A 277 -12.606 2.010 35.231 1.00 40.00 C
+ATOM 2043 C MET A 277 -11.976 0.674 34.851 1.00 40.00 C
+ATOM 2044 O MET A 277 -11.239 0.079 35.648 1.00 40.00 O
+ATOM 2045 CB MET A 277 -14.001 1.804 35.806 1.00 40.00 C
+ATOM 2046 CG MET A 277 -15.014 1.300 34.800 1.00 40.00 C
+ATOM 2047 SD MET A 277 -16.700 1.372 35.412 1.00 40.00 S
+ATOM 2048 CE MET A 277 -16.685 0.097 36.673 1.00 40.00 C
+ATOM 2049 N GLU A 278 -12.244 0.227 33.622 1.00 40.00 N
+ATOM 2050 CA GLU A 278 -11.842 -1.117 33.188 1.00 40.00 C
+ATOM 2051 C GLU A 278 -10.357 -1.269 32.888 1.00 40.00 C
+ATOM 2052 O GLU A 278 -9.843 -2.390 32.941 1.00 40.00 O
+ATOM 2053 CB GLU A 278 -12.694 -1.658 32.018 1.00 40.00 C
+ATOM 2054 CG GLU A 278 -12.296 -1.187 30.627 1.00 40.00 C
+ATOM 2055 CD GLU A 278 -12.872 0.175 30.297 1.00 40.00 C
+ATOM 2056 OE1 GLU A 278 -12.496 1.172 30.967 1.00 40.00 O
+ATOM 2057 OE2 GLU A 278 -13.706 0.238 29.366 1.00 40.00 O
+ATOM 2058 N LYS A 279 -9.660 -0.177 32.569 1.00 40.00 N
+ATOM 2059 CA LYS A 279 -8.212 -0.286 32.558 1.00 40.00 C
+ATOM 2060 C LYS A 279 -7.795 -0.758 33.957 1.00 40.00 C
+ATOM 2061 O LYS A 279 -7.112 -1.784 34.103 1.00 40.00 O
+ATOM 2062 CB LYS A 279 -7.505 1.016 32.187 1.00 40.00 C
+ATOM 2063 CG LYS A 279 -6.016 0.777 31.946 1.00 40.00 C
+ATOM 2064 CD LYS A 279 -5.170 2.013 32.187 1.00 40.00 C
+ATOM 2065 CE LYS A 279 -3.696 1.641 32.262 1.00 40.00 C
+ATOM 2066 NZ LYS A 279 -2.802 2.831 32.123 1.00 40.00 N
+ATOM 2067 N GLY A 280 -8.255 -0.027 34.977 1.00 40.00 N
+ATOM 2068 CA GLY A 280 -8.025 -0.384 36.381 1.00 40.00 C
+ATOM 2069 C GLY A 280 -8.230 -1.862 36.659 1.00 40.00 C
+ATOM 2070 O GLY A 280 -7.353 -2.528 37.224 1.00 40.00 O
+ATOM 2071 N ILE A 281 -9.378 -2.375 36.228 1.00 40.00 N
+ATOM 2072 CA ILE A 281 -9.752 -3.760 36.472 1.00 40.00 C
+ATOM 2073 C ILE A 281 -8.942 -4.768 35.671 1.00 40.00 C
+ATOM 2074 O ILE A 281 -8.450 -5.746 36.224 1.00 40.00 O
+ATOM 2075 CB ILE A 281 -11.248 -3.961 36.232 1.00 40.00 C
+ATOM 2076 CG1 ILE A 281 -12.034 -3.295 37.373 1.00 40.00 C
+ATOM 2077 CG2 ILE A 281 -11.554 -5.443 36.100 1.00 40.00 C
+ATOM 2078 CD1 ILE A 281 -13.545 -3.366 37.257 1.00 40.00 C
+ATOM 2079 N ASP A 282 -8.808 -4.524 34.373 1.00 40.00 N
+ATOM 2080 CA ASP A 282 -8.007 -5.375 33.507 1.00 40.00 C
+ATOM 2081 C ASP A 282 -6.603 -5.585 34.080 1.00 40.00 C
+ATOM 2082 O ASP A 282 -6.097 -6.705 34.113 1.00 40.00 O
+ATOM 2083 CB ASP A 282 -7.920 -4.789 32.087 1.00 40.00 C
+ATOM 2084 CG ASP A 282 -9.233 -4.907 31.303 1.00 40.00 C
+ATOM 2085 OD1 ASP A 282 -10.134 -5.677 31.712 1.00 40.00 O
+ATOM 2086 OD2 ASP A 282 -9.360 -4.225 30.260 1.00 40.00 O
+ATOM 2087 N ASP A 283 -5.992 -4.499 34.547 1.00 40.00 N
+ATOM 2088 CA ASP A 283 -4.645 -4.522 35.128 1.00 40.00 C
+ATOM 2089 C ASP A 283 -4.515 -5.520 36.289 1.00 40.00 C
+ATOM 2090 O ASP A 283 -3.503 -6.219 36.422 1.00 40.00 O
+ATOM 2091 CB ASP A 283 -4.257 -3.103 35.585 1.00 40.00 C
+ATOM 2092 CG ASP A 283 -4.122 -2.106 34.412 1.00 40.00 C
+ATOM 2093 OD1 ASP A 283 -3.766 -2.519 33.286 1.00 40.00 O
+ATOM 2094 OD2 ASP A 283 -4.365 -0.895 34.618 1.00 40.00 O
+ATOM 2095 N ILE A 284 -5.563 -5.575 37.108 1.00 40.00 N
+ATOM 2096 CA ILE A 284 -5.652 -6.488 38.241 1.00 40.00 C
+ATOM 2097 C ILE A 284 -5.841 -7.940 37.786 1.00 40.00 C
+ATOM 2098 O ILE A 284 -5.338 -8.881 38.424 1.00 40.00 O
+ATOM 2099 CB ILE A 284 -6.804 -6.068 39.192 1.00 40.00 C
+ATOM 2100 CG1 ILE A 284 -6.615 -4.616 39.679 1.00 40.00 C
+ATOM 2101 CG2 ILE A 284 -6.982 -7.056 40.351 1.00 40.00 C
+ATOM 2102 CD1 ILE A 284 -5.211 -4.234 40.122 1.00 40.00 C
+ATOM 2103 N MET A 285 -6.565 -8.110 36.680 1.00 40.00 N
+ATOM 2104 CA MET A 285 -6.879 -9.438 36.145 1.00 40.00 C
+ATOM 2105 C MET A 285 -5.707 -10.059 35.414 1.00 40.00 C
+ATOM 2106 O MET A 285 -5.577 -11.284 35.359 1.00 40.00 O
+ATOM 2107 CB MET A 285 -8.084 -9.361 35.213 1.00 40.00 C
+ATOM 2108 CG MET A 285 -9.386 -9.147 35.960 1.00 40.00 C
+ATOM 2109 SD MET A 285 -9.690 -10.513 37.113 1.00 40.00 S
+ATOM 2110 CE MET A 285 -10.320 -9.624 38.535 1.00 40.00 C
+ATOM 2111 N VAL A 286 -4.871 -9.188 34.855 1.00 40.00 N
+ATOM 2112 CA VAL A 286 -3.674 -9.576 34.127 1.00 40.00 C
+ATOM 2113 C VAL A 286 -2.762 -10.434 35.006 1.00 40.00 C
+ATOM 2114 O VAL A 286 -2.376 -11.540 34.608 1.00 40.00 O
+ATOM 2115 CB VAL A 286 -2.942 -8.318 33.586 1.00 40.00 C
+ATOM 2116 CG1 VAL A 286 -1.493 -8.624 33.224 1.00 40.00 C
+ATOM 2117 CG2 VAL A 286 -3.685 -7.751 32.382 1.00 40.00 C
+ATOM 2118 N SER A 287 -2.455 -9.927 36.203 1.00 40.00 N
+ATOM 2119 CA SER A 287 -1.558 -10.603 37.144 1.00 40.00 C
+ATOM 2120 C SER A 287 -2.140 -11.898 37.733 1.00 40.00 C
+ATOM 2121 O SER A 287 -1.383 -12.821 38.055 1.00 40.00 O
+ATOM 2122 CB SER A 287 -1.099 -9.636 38.247 1.00 40.00 C
+ATOM 2123 OG SER A 287 -2.195 -9.006 38.890 1.00 40.00 O
+ATOM 2124 N LEU A 288 -3.473 -11.953 37.854 1.00 40.00 N
+ATOM 2125 CA LEU A 288 -4.223 -13.151 38.296 1.00 40.00 C
+ATOM 2126 C LEU A 288 -4.275 -14.282 37.253 1.00 40.00 C
+ATOM 2127 O LEU A 288 -4.320 -15.474 37.594 1.00 40.00 O
+ATOM 2128 CB LEU A 288 -5.659 -12.768 38.688 1.00 40.00 C
+ATOM 2129 CG LEU A 288 -5.948 -12.379 40.139 1.00 40.00 C
+ATOM 2130 CD1 LEU A 288 -7.365 -11.839 40.269 1.00 40.00 C
+ATOM 2131 CD2 LEU A 288 -5.730 -13.572 41.064 1.00 40.00 C
+ATOM 2132 N ALA A 289 -4.287 -13.878 35.985 1.00 40.00 N
+ATOM 2133 CA ALA A 289 -4.353 -14.795 34.847 1.00 40.00 C
+ATOM 2134 C ALA A 289 -3.032 -15.533 34.634 1.00 40.00 C
+ATOM 2135 O ALA A 289 -3.012 -16.760 34.670 1.00 40.00 O
+ATOM 2136 CB ALA A 289 -4.777 -14.053 33.578 1.00 40.00 C
+ATOM 2137 N GLU A 290 -1.946 -14.781 34.422 1.00 40.00 N
+ATOM 2138 CA GLU A 290 -0.595 -15.328 34.234 1.00 40.00 C
+ATOM 2139 C GLU A 290 -0.115 -16.168 35.429 1.00 40.00 C
+ATOM 2140 O GLU A 290 0.921 -16.827 35.337 1.00 40.00 O
+ATOM 2141 CB GLU A 290 0.394 -14.194 33.952 1.00 40.00 C
+ATOM 2142 CG GLU A 290 0.355 -13.097 35.020 1.00 40.00 C
+ATOM 2143 CD GLU A 290 1.393 -12.002 34.827 1.00 40.00 C
+ATOM 2144 OE1 GLU A 290 2.601 -12.325 34.822 1.00 40.00 O
+ATOM 2145 OE2 GLU A 290 1.008 -10.814 34.709 1.00 40.00 O
+ATOM 2146 N LYS A 291 -0.859 -16.123 36.542 1.00 40.00 N
+ATOM 2147 CA LYS A 291 -0.677 -17.060 37.665 1.00 40.00 C
+ATOM 2148 C LYS A 291 -0.925 -18.505 37.250 1.00 40.00 C
+ATOM 2149 O LYS A 291 -0.148 -19.394 37.604 1.00 40.00 O
+ATOM 2150 CB LYS A 291 -1.628 -16.755 38.827 1.00 40.00 C
+ATOM 2151 CG LYS A 291 -1.201 -15.620 39.723 1.00 40.00 C
+ATOM 2152 CD LYS A 291 0.220 -15.786 40.223 1.00 40.00 C
+ATOM 2153 CE LYS A 291 0.657 -14.493 40.875 1.00 40.00 C
+ATOM 2154 NZ LYS A 291 -0.456 -13.928 41.697 1.00 40.00 N
+ATOM 2155 N ASP A 292 -2.029 -18.726 36.527 1.00 40.00 N
+ATOM 2156 CA ASP A 292 -2.407 -20.051 35.993 1.00 40.00 C
+ATOM 2157 C ASP A 292 -1.778 -20.331 34.627 1.00 40.00 C
+ATOM 2158 O ASP A 292 -2.083 -21.354 33.996 1.00 40.00 O
+ATOM 2159 CB ASP A 292 -3.931 -20.169 35.863 1.00 40.00 C
+ATOM 2160 CG ASP A 292 -4.652 -19.995 37.185 1.00 40.00 C
+ATOM 2161 OD1 ASP A 292 -4.061 -19.435 38.144 1.00 40.00 O
+ATOM 2162 OD2 ASP A 292 -5.829 -20.419 37.257 1.00 40.00 O
+ATOM 2163 N GLY A 293 -0.909 -19.416 34.185 1.00 40.00 N
+ATOM 2164 CA GLY A 293 -0.314 -19.435 32.837 1.00 40.00 C
+ATOM 2165 C GLY A 293 -1.218 -18.920 31.714 1.00 40.00 C
+ATOM 2166 O GLY A 293 -0.947 -19.171 30.527 1.00 40.00 O
+ATOM 2167 N ILE A 294 -2.272 -18.186 32.096 1.00 40.00 N
+ATOM 2168 CA ILE A 294 -3.351 -17.744 31.188 1.00 40.00 C
+ATOM 2169 C ILE A 294 -3.151 -16.293 30.669 1.00 40.00 C
+ATOM 2170 O ILE A 294 -2.731 -15.398 31.425 1.00 40.00 O
+ATOM 2171 CB ILE A 294 -4.756 -17.942 31.856 1.00 40.00 C
+ATOM 2172 CG1 ILE A 294 -5.002 -19.429 32.192 1.00 40.00 C
+ATOM 2173 CG2 ILE A 294 -5.884 -17.397 30.981 1.00 40.00 C
+ATOM 2174 CD1 ILE A 294 -6.184 -19.697 33.107 1.00 40.00 C
+ATOM 2175 N ASP A 295 -3.411 -16.083 29.373 1.00 40.00 N
+ATOM 2176 CA ASP A 295 -3.548 -14.731 28.830 1.00 40.00 C
+ATOM 2177 C ASP A 295 -4.981 -14.224 28.989 1.00 40.00 C
+ATOM 2178 O ASP A 295 -5.954 -14.825 28.500 1.00 40.00 O
+ATOM 2179 CB ASP A 295 -3.102 -14.615 27.370 1.00 40.00 C
+ATOM 2180 CG ASP A 295 -3.338 -13.206 26.794 1.00 40.00 C
+ATOM 2181 OD1 ASP A 295 -3.307 -13.036 25.556 1.00 40.00 O
+ATOM 2182 OD2 ASP A 295 -3.563 -12.257 27.574 1.00 40.00 O
+ATOM 2183 N TRP A 296 -5.066 -13.080 29.659 1.00 40.00 N
+ATOM 2184 CA TRP A 296 -6.314 -12.498 30.133 1.00 40.00 C
+ATOM 2185 C TRP A 296 -7.316 -12.203 29.050 1.00 40.00 C
+ATOM 2186 O TRP A 296 -8.456 -12.674 29.108 1.00 40.00 O
+ATOM 2187 CB TRP A 296 -6.003 -11.250 30.969 1.00 40.00 C
+ATOM 2188 CG TRP A 296 -7.190 -10.364 31.254 1.00 40.00 C
+ATOM 2189 CD1 TRP A 296 -7.320 -9.012 30.967 1.00 40.00 C
+ATOM 2190 CD2 TRP A 296 -8.467 -10.740 31.884 1.00 40.00 C
+ATOM 2191 NE1 TRP A 296 -8.546 -8.541 31.365 1.00 40.00 N
+ATOM 2192 CE2 TRP A 296 -9.281 -9.522 31.922 1.00 40.00 C
+ATOM 2193 CE3 TRP A 296 -8.994 -11.916 32.396 1.00 40.00 C
+ATOM 2194 CZ2 TRP A 296 -10.558 -9.505 32.459 1.00 40.00 C
+ATOM 2195 CZ3 TRP A 296 -10.286 -11.887 32.932 1.00 40.00 C
+ATOM 2196 CH2 TRP A 296 -11.045 -10.708 32.965 1.00 40.00 C
+ATOM 2197 N PHE A 297 -6.896 -11.441 28.045 1.00 40.00 N
+ATOM 2198 CA PHE A 297 -7.820 -10.958 27.031 1.00 40.00 C
+ATOM 2199 C PHE A 297 -8.493 -12.110 26.298 1.00 40.00 C
+ATOM 2200 O PHE A 297 -9.658 -12.006 25.930 1.00 40.00 O
+ATOM 2201 CB PHE A 297 -7.132 -9.947 26.112 1.00 40.00 C
+ATOM 2202 CG PHE A 297 -6.670 -8.710 26.844 1.00 40.00 C
+ATOM 2203 CD1 PHE A 297 -5.410 -8.668 27.455 1.00 40.00 C
+ATOM 2204 CD2 PHE A 297 -7.506 -7.596 26.972 1.00 40.00 C
+ATOM 2205 CE1 PHE A 297 -4.987 -7.534 28.152 1.00 40.00 C
+ATOM 2206 CE2 PHE A 297 -7.085 -6.458 27.667 1.00 40.00 C
+ATOM 2207 CZ PHE A 297 -5.824 -6.425 28.256 1.00 40.00 C
+ATOM 2208 N ASP A 298 -7.783 -13.229 26.167 1.00 40.00 N
+ATOM 2209 CA ASP A 298 -8.319 -14.437 25.529 1.00 40.00 C
+ATOM 2210 C ASP A 298 -9.290 -15.176 26.406 1.00 40.00 C
+ATOM 2211 O ASP A 298 -10.206 -15.832 25.919 1.00 40.00 O
+ATOM 2212 CB ASP A 298 -7.189 -15.366 25.159 1.00 40.00 C
+ATOM 2213 CG ASP A 298 -6.196 -14.707 24.252 1.00 40.00 C
+ATOM 2214 OD1 ASP A 298 -5.434 -15.452 23.612 1.00 40.00 O
+ATOM 2215 OD2 ASP A 298 -6.175 -13.449 24.170 1.00 40.00 O
+ATOM 2216 N TYR A 299 -9.069 -15.079 27.707 1.00 40.00 N
+ATOM 2217 CA TYR A 299 -10.021 -15.585 28.667 1.00 40.00 C
+ATOM 2218 C TYR A 299 -11.202 -14.625 28.747 1.00 40.00 C
+ATOM 2219 O TYR A 299 -12.342 -15.051 28.940 1.00 40.00 O
+ATOM 2220 CB TYR A 299 -9.351 -15.732 30.026 1.00 40.00 C
+ATOM 2221 CG TYR A 299 -10.108 -16.593 31.022 1.00 40.00 C
+ATOM 2222 CD1 TYR A 299 -10.252 -17.974 30.834 1.00 40.00 C
+ATOM 2223 CD2 TYR A 299 -10.653 -16.032 32.180 1.00 40.00 C
+ATOM 2224 CE1 TYR A 299 -10.930 -18.761 31.765 1.00 40.00 C
+ATOM 2225 CE2 TYR A 299 -11.332 -16.813 33.117 1.00 40.00 C
+ATOM 2226 CZ TYR A 299 -11.470 -18.173 32.905 1.00 40.00 C
+ATOM 2227 OH TYR A 299 -12.141 -18.936 33.832 1.00 40.00 O
+ATOM 2228 N LYS A 300 -10.915 -13.333 28.578 1.00 40.00 N
+ATOM 2229 CA LYS A 300 -11.937 -12.285 28.554 1.00 40.00 C
+ATOM 2230 C LYS A 300 -12.916 -12.553 27.430 1.00 40.00 C
+ATOM 2231 O LYS A 300 -14.065 -12.931 27.672 1.00 40.00 O
+ATOM 2232 CB LYS A 300 -11.297 -10.898 28.377 1.00 40.00 C
+ATOM 2233 CG LYS A 300 -12.301 -9.742 28.322 1.00 40.00 C
+ATOM 2234 CD LYS A 300 -11.662 -8.388 27.996 1.00 40.00 C
+ATOM 2235 CE LYS A 300 -11.327 -7.569 29.245 1.00 40.00 C
+ATOM 2236 NZ LYS A 300 -10.991 -6.153 28.917 1.00 40.00 N
+ATOM 2237 N LYS A 301 -12.438 -12.354 26.205 1.00 40.00 N
+ATOM 2238 CA LYS A 301 -13.154 -12.733 25.006 1.00 40.00 C
+ATOM 2239 C LYS A 301 -14.095 -13.901 25.279 1.00 40.00 C
+ATOM 2240 O LYS A 301 -15.305 -13.796 25.083 1.00 40.00 O
+ATOM 2241 CB LYS A 301 -12.149 -13.165 23.950 1.00 40.00 C
+ATOM 2242 CG LYS A 301 -11.372 -12.036 23.309 1.00 40.00 C
+ATOM 2243 CD LYS A 301 -10.036 -12.541 22.773 1.00 40.00 C
+ATOM 2244 CE LYS A 301 -9.474 -11.659 21.667 1.00 40.00 C
+ATOM 2245 NZ LYS A 301 -9.623 -10.192 21.906 1.00 40.00 N
+ATOM 2246 N GLN A 302 -13.520 -15.006 25.748 1.00 40.00 N
+ATOM 2247 CA GLN A 302 -14.242 -16.259 25.962 1.00 40.00 C
+ATOM 2248 C GLN A 302 -15.452 -16.119 26.882 1.00 40.00 C
+ATOM 2249 O GLN A 302 -16.534 -16.633 26.591 1.00 40.00 O
+ATOM 2250 CB GLN A 302 -13.280 -17.305 26.515 1.00 40.00 C
+ATOM 2251 CG GLN A 302 -13.917 -18.647 26.825 1.00 40.00 C
+ATOM 2252 CD GLN A 302 -13.017 -19.509 27.674 1.00 40.00 C
+ATOM 2253 OE1 GLN A 302 -13.421 -19.966 28.745 1.00 40.00 O
+ATOM 2254 NE2 GLN A 302 -11.780 -19.722 27.213 1.00 40.00 N
+ATOM 2255 N LEU A 303 -15.262 -15.427 27.996 1.00 40.00 N
+ATOM 2256 CA LEU A 303 -16.354 -15.194 28.913 1.00 40.00 C
+ATOM 2257 C LEU A 303 -17.409 -14.397 28.201 1.00 40.00 C
+ATOM 2258 O LEU A 303 -18.594 -14.648 28.369 1.00 40.00 O
+ATOM 2259 CB LEU A 303 -15.872 -14.425 30.129 1.00 40.00 C
+ATOM 2260 CG LEU A 303 -14.750 -15.113 30.898 1.00 40.00 C
+ATOM 2261 CD1 LEU A 303 -13.966 -14.082 31.692 1.00 40.00 C
+ATOM 2262 CD2 LEU A 303 -15.284 -16.233 31.787 1.00 40.00 C
+ATOM 2263 N LYS A 304 -16.962 -13.439 27.393 1.00 40.00 N
+ATOM 2264 CA LYS A 304 -17.874 -12.588 26.639 1.00 40.00 C
+ATOM 2265 C LYS A 304 -18.707 -13.447 25.712 1.00 40.00 C
+ATOM 2266 O LYS A 304 -19.932 -13.366 25.752 1.00 40.00 O
+ATOM 2267 CB LYS A 304 -17.133 -11.497 25.861 1.00 40.00 C
+ATOM 2268 CG LYS A 304 -16.518 -10.423 26.738 1.00 40.00 C
+ATOM 2269 CD LYS A 304 -15.816 -9.347 25.930 1.00 40.00 C
+ATOM 2270 CE LYS A 304 -16.647 -8.076 25.838 1.00 40.00 C
+ATOM 2271 NZ LYS A 304 -15.861 -6.953 25.250 1.00 40.00 N
+ATOM 2272 N ARG A 305 -18.052 -14.284 24.903 1.00 40.00 N
+ATOM 2273 CA ARG A 305 -18.775 -15.237 24.062 1.00 40.00 C
+ATOM 2274 C ARG A 305 -19.781 -15.994 24.912 1.00 40.00 C
+ATOM 2275 O ARG A 305 -20.893 -16.262 24.467 1.00 40.00 O
+ATOM 2276 CB ARG A 305 -17.836 -16.218 23.361 1.00 40.00 C
+ATOM 2277 CG ARG A 305 -17.602 -15.931 21.881 1.00 40.00 C
+ATOM 2278 CD ARG A 305 -16.864 -17.080 21.181 1.00 40.00 C
+ATOM 2279 NE ARG A 305 -15.444 -17.174 21.566 1.00 40.00 N
+ATOM 2280 CZ ARG A 305 -14.917 -18.103 22.373 1.00 40.00 C
+ATOM 2281 NH1 ARG A 305 -15.684 -19.064 22.893 1.00 40.00 N
+ATOM 2282 NH2 ARG A 305 -13.610 -18.072 22.660 1.00 40.00 N
+ATOM 2283 N GLY A 306 -19.403 -16.312 26.147 1.00 40.00 N
+ATOM 2284 CA GLY A 306 -20.336 -16.937 27.074 1.00 40.00 C
+ATOM 2285 C GLY A 306 -21.323 -15.966 27.709 1.00 40.00 C
+ATOM 2286 O GLY A 306 -22.011 -16.332 28.665 1.00 40.00 O
+ATOM 2287 N ASP A 307 -21.400 -14.736 27.194 1.00 40.00 N
+ATOM 2288 CA ASP A 307 -22.252 -13.696 27.777 1.00 40.00 C
+ATOM 2289 C ASP A 307 -21.947 -13.530 29.255 1.00 40.00 C
+ATOM 2290 O ASP A 307 -22.772 -13.011 30.004 1.00 40.00 O
+ATOM 2291 CB ASP A 307 -23.736 -14.043 27.621 1.00 40.00 C
+ATOM 2292 CG ASP A 307 -24.146 -14.239 26.187 1.00 40.00 C
+ATOM 2293 OD1 ASP A 307 -23.858 -13.364 25.341 1.00 40.00 O
+ATOM 2294 OD2 ASP A 307 -24.781 -15.272 25.913 1.00 40.00 O
+ATOM 2295 N GLN A 308 -20.772 -13.995 29.675 1.00 40.00 N
+ATOM 2296 CA GLN A 308 -20.417 -14.016 31.090 1.00 40.00 C
+ATOM 2297 C GLN A 308 -19.707 -12.733 31.512 1.00 40.00 C
+ATOM 2298 O GLN A 308 -19.525 -12.476 32.703 1.00 40.00 O
+ATOM 2299 CB GLN A 308 -19.618 -15.288 31.445 1.00 40.00 C
+ATOM 2300 CG GLN A 308 -20.503 -16.538 31.592 1.00 40.00 C
+ATOM 2301 CD GLN A 308 -19.745 -17.843 31.852 1.00 40.00 C
+ATOM 2302 OE1 GLN A 308 -19.205 -18.069 32.936 1.00 40.00 O
+ATOM 2303 NE2 GLN A 308 -19.741 -18.725 30.863 1.00 40.00 N
+ATOM 2304 N TRP A 309 -19.348 -11.914 30.525 1.00 40.00 N
+ATOM 2305 CA TRP A 309 -18.743 -10.606 30.762 1.00 40.00 C
+ATOM 2306 C TRP A 309 -19.429 -9.588 29.935 1.00 40.00 C
+ATOM 2307 O TRP A 309 -19.490 -9.721 28.708 1.00 40.00 O
+ATOM 2308 CB TRP A 309 -17.304 -10.628 30.340 1.00 40.00 C
+ATOM 2309 CG TRP A 309 -16.536 -9.401 30.745 1.00 40.00 C
+ATOM 2310 CD1 TRP A 309 -16.325 -8.230 30.014 1.00 40.00 C
+ATOM 2311 CD2 TRP A 309 -15.808 -9.206 31.991 1.00 40.00 C
+ATOM 2312 NE1 TRP A 309 -15.533 -7.348 30.712 1.00 40.00 N
+ATOM 2313 CE2 TRP A 309 -15.189 -7.870 31.906 1.00 40.00 C
+ATOM 2314 CE3 TRP A 309 -15.602 -9.983 33.132 1.00 40.00 C
+ATOM 2315 CZ2 TRP A 309 -14.410 -7.356 32.928 1.00 40.00 C
+ATOM 2316 CZ3 TRP A 309 -14.819 -9.453 34.162 1.00 40.00 C
+ATOM 2317 CH2 TRP A 309 -14.239 -8.169 34.061 1.00 40.00 C
+ATOM 2318 N ASN A 310 -19.928 -8.545 30.598 1.00 40.00 N
+ATOM 2319 CA ASN A 310 -20.834 -7.571 29.971 1.00 40.00 C
+ATOM 2320 C ASN A 310 -20.569 -6.108 30.408 1.00 40.00 C
+ATOM 2321 O ASN A 310 -20.638 -5.790 31.596 1.00 40.00 O
+ATOM 2322 CB ASN A 310 -22.298 -7.989 30.218 1.00 40.00 C
+ATOM 2323 CG ASN A 310 -22.550 -9.477 29.950 1.00 40.00 C
+ATOM 2324 OD1 ASN A 310 -22.310 -9.986 28.847 1.00 40.00 O
+ATOM 2325 ND2 ASN A 310 -23.048 -10.178 30.963 1.00 40.00 N
+ATOM 2326 N VAL A 311 -20.276 -5.232 29.441 1.00 40.00 N
+ATOM 2327 CA VAL A 311 -19.674 -3.910 29.698 1.00 40.00 C
+ATOM 2328 C VAL A 311 -20.449 -2.734 29.105 1.00 40.00 C
+ATOM 2329 O VAL A 311 -20.713 -2.683 27.917 1.00 40.00 O
+ATOM 2330 CB VAL A 311 -18.239 -3.851 29.132 1.00 40.00 C
+ATOM 2331 CG1 VAL A 311 -17.594 -2.513 29.430 1.00 40.00 C
+ATOM 2332 CG2 VAL A 311 -17.387 -4.978 29.689 1.00 40.00 C
+ATOM 2333 N GLU A 312 -20.760 -1.757 29.932 1.00 40.00 N
+ATOM 2334 CA GLU A 312 -21.562 -0.642 29.506 1.00 40.00 C
+ATOM 2335 C GLU A 312 -20.966 0.609 30.137 1.00 40.00 C
+ATOM 2336 O GLU A 312 -21.380 0.997 31.224 1.00 40.00 O
+ATOM 2337 CB GLU A 312 -22.976 -0.879 30.028 1.00 40.00 C
+ATOM 2338 CG GLU A 312 -24.017 0.174 29.690 1.00 40.00 C
+ATOM 2339 CD GLU A 312 -25.082 -0.356 28.756 1.00 40.00 C
+ATOM 2340 OE1 GLU A 312 -24.693 -0.818 27.662 1.00 40.00 O
+ATOM 2341 OE2 GLU A 312 -26.294 -0.316 29.114 1.00 40.00 O
+ATOM 2342 N VAL A 313 -19.977 1.231 29.498 1.00 40.00 N
+ATOM 2343 CA VAL A 313 -19.362 2.434 30.091 1.00 40.00 C
+ATOM 2344 C VAL A 313 -19.471 3.659 29.212 1.00 40.00 C
+ATOM 2345 O VAL A 313 -19.553 3.532 28.011 1.00 40.00 O
+ATOM 2346 CB VAL A 313 -17.887 2.230 30.497 1.00 40.00 C
+ATOM 2347 CG1 VAL A 313 -17.780 1.254 31.663 1.00 40.00 C
+ATOM 2348 CG2 VAL A 313 -17.043 1.778 29.318 1.00 40.00 C
+ATOM 2349 N TYR A 314 -19.471 4.843 29.820 1.00 40.00 N
+ATOM 2350 CA TYR A 314 -19.621 6.099 29.083 1.00 40.00 C
+ATOM 2351 C TYR A 314 -18.769 7.202 29.668 1.00 40.00 C
+ATOM 2352 O TYR A 314 -18.195 7.056 30.748 1.00 40.00 O
+ATOM 2353 CB TYR A 314 -21.079 6.553 29.038 1.00 40.00 C
+ATOM 2354 CG TYR A 314 -21.819 6.413 30.341 1.00 40.00 C
+ATOM 2355 CD1 TYR A 314 -21.944 7.475 31.212 1.00 40.00 C
+ATOM 2356 CD2 TYR A 314 -22.406 5.212 30.698 1.00 40.00 C
+ATOM 2357 CE1 TYR A 314 -22.631 7.340 32.413 1.00 40.00 C
+ATOM 2358 CE2 TYR A 314 -23.089 5.064 31.897 1.00 40.00 C
+ATOM 2359 CZ TYR A 314 -23.206 6.127 32.753 1.00 40.00 C
+ATOM 2360 OH TYR A 314 -23.903 5.960 33.936 1.00 40.00 O
+ATOM 2361 OXT TYR A 314 -18.642 8.263 29.059 1.00 40.00 O
+TER 2362 TYR A 314
+ATOM 2363 N ALA B 1 -53.291 -14.159 81.934 1.00 40.00 N
+ATOM 2364 CA ALA B 1 -52.106 -13.577 81.238 1.00 40.00 C
+ATOM 2365 C ALA B 1 -51.069 -13.092 82.240 1.00 40.00 C
+ATOM 2366 O ALA B 1 -51.414 -12.674 83.342 1.00 40.00 O
+ATOM 2367 CB ALA B 1 -52.535 -12.439 80.327 1.00 40.00 C
+ATOM 2368 N THR B 2 -49.799 -13.152 81.850 1.00 40.00 N
+ATOM 2369 CA THR B 2 -48.690 -12.696 82.696 1.00 40.00 C
+ATOM 2370 C THR B 2 -47.816 -11.746 81.869 1.00 40.00 C
+ATOM 2371 O THR B 2 -47.528 -12.035 80.713 1.00 40.00 O
+ATOM 2372 CB THR B 2 -47.873 -13.900 83.257 1.00 40.00 C
+ATOM 2373 OG1 THR B 2 -48.706 -14.689 84.122 1.00 40.00 O
+ATOM 2374 CG2 THR B 2 -46.631 -13.451 84.045 1.00 40.00 C
+ATOM 2375 N TYR B 3 -47.415 -10.615 82.456 1.00 40.00 N
+ATOM 2376 CA TYR B 3 -46.621 -9.595 81.748 1.00 40.00 C
+ATOM 2377 C TYR B 3 -45.389 -9.150 82.549 1.00 40.00 C
+ATOM 2378 O TYR B 3 -45.362 -9.266 83.784 1.00 40.00 O
+ATOM 2379 CB TYR B 3 -47.468 -8.354 81.437 1.00 40.00 C
+ATOM 2380 CG TYR B 3 -48.872 -8.592 80.913 1.00 40.00 C
+ATOM 2381 CD1 TYR B 3 -49.920 -8.921 81.780 1.00 40.00 C
+ATOM 2382 CD2 TYR B 3 -49.165 -8.435 79.564 1.00 40.00 C
+ATOM 2383 CE1 TYR B 3 -51.207 -9.116 81.313 1.00 40.00 C
+ATOM 2384 CE2 TYR B 3 -50.454 -8.627 79.090 1.00 40.00 C
+ATOM 2385 CZ TYR B 3 -51.469 -8.966 79.974 1.00 40.00 C
+ATOM 2386 OH TYR B 3 -52.758 -9.163 79.537 1.00 40.00 O
+ATOM 2387 N ASN B 4 -44.382 -8.625 81.843 1.00 40.00 N
+ATOM 2388 CA ASN B 4 -43.164 -8.113 82.484 1.00 40.00 C
+ATOM 2389 C ASN B 4 -43.332 -6.746 83.138 1.00 40.00 C
+ATOM 2390 O ASN B 4 -43.884 -5.810 82.547 1.00 40.00 O
+ATOM 2391 CB ASN B 4 -41.967 -8.071 81.519 1.00 40.00 C
+ATOM 2392 CG ASN B 4 -40.730 -7.419 82.145 1.00 40.00 C
+ATOM 2393 OD1 ASN B 4 -40.209 -7.886 83.170 1.00 40.00 O
+ATOM 2394 ND2 ASN B 4 -40.260 -6.329 81.534 1.00 40.00 N
+ATOM 2395 N VAL B 5 -42.831 -6.649 84.367 1.00 40.00 N
+ATOM 2396 CA VAL B 5 -42.800 -5.390 85.098 1.00 40.00 C
+ATOM 2397 C VAL B 5 -41.394 -5.073 85.574 1.00 40.00 C
+ATOM 2398 O VAL B 5 -40.709 -5.913 86.165 1.00 40.00 O
+ATOM 2399 CB VAL B 5 -43.747 -5.378 86.310 1.00 40.00 C
+ATOM 2400 CG1 VAL B 5 -43.828 -3.968 86.876 1.00 40.00 C
+ATOM 2401 CG2 VAL B 5 -45.135 -5.889 85.927 1.00 40.00 C
+ATOM 2402 N LYS B 6 -40.995 -3.839 85.305 1.00 40.00 N
+ATOM 2403 CA LYS B 6 -39.669 -3.343 85.612 1.00 40.00 C
+ATOM 2404 C LYS B 6 -39.817 -2.233 86.647 1.00 40.00 C
+ATOM 2405 O LYS B 6 -40.451 -1.210 86.383 1.00 40.00 O
+ATOM 2406 CB LYS B 6 -39.025 -2.818 84.324 1.00 40.00 C
+ATOM 2407 CG LYS B 6 -37.626 -2.237 84.463 1.00 40.00 C
+ATOM 2408 CD LYS B 6 -37.094 -1.703 83.132 1.00 40.00 C
+ATOM 2409 CE LYS B 6 -36.805 -2.811 82.123 1.00 40.00 C
+ATOM 2410 NZ LYS B 6 -35.913 -2.359 81.016 1.00 40.00 N
+ATOM 2411 N LEU B 7 -39.244 -2.441 87.827 1.00 40.00 N
+ATOM 2412 CA LEU B 7 -39.395 -1.482 88.903 1.00 40.00 C
+ATOM 2413 C LEU B 7 -38.138 -0.714 89.101 1.00 40.00 C
+ATOM 2414 O LEU B 7 -37.073 -1.294 89.283 1.00 40.00 O
+ATOM 2415 CB LEU B 7 -39.777 -2.172 90.199 1.00 40.00 C
+ATOM 2416 CG LEU B 7 -41.164 -2.805 90.153 1.00 40.00 C
+ATOM 2417 CD1 LEU B 7 -41.447 -3.576 91.437 1.00 40.00 C
+ATOM 2418 CD2 LEU B 7 -42.225 -1.744 89.896 1.00 40.00 C
+ATOM 2419 N ILE B 8 -38.280 0.604 89.057 1.00 40.00 N
+ATOM 2420 CA ILE B 8 -37.173 1.519 89.306 1.00 40.00 C
+ATOM 2421 C ILE B 8 -37.271 2.090 90.730 1.00 40.00 C
+ATOM 2422 O ILE B 8 -37.755 3.216 90.945 1.00 40.00 O
+ATOM 2423 CB ILE B 8 -37.091 2.621 88.231 1.00 40.00 C
+ATOM 2424 CG1 ILE B 8 -37.457 2.024 86.867 1.00 40.00 C
+ATOM 2425 CG2 ILE B 8 -35.693 3.229 88.217 1.00 40.00 C
+ATOM 2426 CD1 ILE B 8 -38.366 2.888 86.025 1.00 40.00 C
+ATOM 2427 N THR B 9 -36.822 1.271 91.691 1.00 40.00 N
+ATOM 2428 CA THR B 9 -36.771 1.620 93.114 1.00 40.00 C
+ATOM 2429 C THR B 9 -35.679 2.687 93.308 1.00 40.00 C
+ATOM 2430 O THR B 9 -34.882 2.915 92.387 1.00 40.00 O
+ATOM 2431 CB THR B 9 -36.547 0.359 94.011 1.00 40.00 C
+ATOM 2432 OG1 THR B 9 -35.149 0.079 94.170 1.00 40.00 O
+ATOM 2433 CG2 THR B 9 -37.244 -0.870 93.421 1.00 40.00 C
+ATOM 2434 N PRO B 10 -35.640 3.359 94.482 1.00 40.00 N
+ATOM 2435 CA PRO B 10 -34.550 4.320 94.721 1.00 40.00 C
+ATOM 2436 C PRO B 10 -33.225 3.583 94.929 1.00 40.00 C
+ATOM 2437 O PRO B 10 -32.163 4.199 95.046 1.00 40.00 O
+ATOM 2438 CB PRO B 10 -34.974 5.029 96.015 1.00 40.00 C
+ATOM 2439 CG PRO B 10 -36.379 4.606 96.270 1.00 40.00 C
+ATOM 2440 CD PRO B 10 -36.520 3.254 95.654 1.00 40.00 C
+ATOM 2441 N GLU B 11 -33.316 2.258 94.969 1.00 40.00 N
+ATOM 2442 CA GLU B 11 -32.167 1.388 95.091 1.00 40.00 C
+ATOM 2443 C GLU B 11 -32.037 0.467 93.870 1.00 40.00 C
+ATOM 2444 O GLU B 11 -31.719 -0.727 93.991 1.00 40.00 O
+ATOM 2445 CB GLU B 11 -32.288 0.579 96.370 1.00 40.00 C
+ATOM 2446 CG GLU B 11 -32.489 1.441 97.598 1.00 40.00 C
+ATOM 2447 CD GLU B 11 -32.233 0.668 98.867 1.00 40.00 C
+ATOM 2448 OE1 GLU B 11 -32.989 -0.288 99.140 1.00 40.00 O
+ATOM 2449 OE2 GLU B 11 -31.270 1.010 99.586 1.00 40.00 O
+ATOM 2450 N GLY B 12 -32.297 1.037 92.694 1.00 40.00 N
+ATOM 2451 CA GLY B 12 -32.036 0.361 91.432 1.00 40.00 C
+ATOM 2452 C GLY B 12 -33.216 -0.383 90.858 1.00 40.00 C
+ATOM 2453 O GLY B 12 -34.280 -0.484 91.484 1.00 40.00 O
+ATOM 2454 N GLU B 13 -32.990 -0.919 89.662 1.00 40.00 N
+ATOM 2455 CA GLU B 13 -34.008 -1.581 88.856 1.00 40.00 C
+ATOM 2456 C GLU B 13 -34.140 -3.063 89.241 1.00 40.00 C
+ATOM 2457 O GLU B 13 -33.197 -3.658 89.771 1.00 40.00 O
+ATOM 2458 CB GLU B 13 -33.635 -1.411 87.379 1.00 40.00 C
+ATOM 2459 CG GLU B 13 -34.758 -1.590 86.382 1.00 40.00 C
+ATOM 2460 CD GLU B 13 -34.220 -1.770 84.979 1.00 40.00 C
+ATOM 2461 OE1 GLU B 13 -34.314 -2.901 84.452 1.00 40.00 O
+ATOM 2462 OE2 GLU B 13 -33.683 -0.790 84.418 1.00 40.00 O
+ATOM 2463 N VAL B 14 -35.323 -3.631 89.004 1.00 40.00 N
+ATOM 2464 CA VAL B 14 -35.569 -5.071 89.164 1.00 40.00 C
+ATOM 2465 C VAL B 14 -36.873 -5.478 88.460 1.00 40.00 C
+ATOM 2466 O VAL B 14 -37.894 -4.806 88.585 1.00 40.00 O
+ATOM 2467 CB VAL B 14 -35.527 -5.534 90.653 1.00 40.00 C
+ATOM 2468 CG1 VAL B 14 -36.541 -4.785 91.514 1.00 40.00 C
+ATOM 2469 CG2 VAL B 14 -35.688 -7.049 90.771 1.00 40.00 C
+ATOM 2470 N GLU B 15 -36.821 -6.570 87.703 1.00 40.00 N
+ATOM 2471 CA GLU B 15 -37.971 -7.037 86.922 1.00 40.00 C
+ATOM 2472 C GLU B 15 -38.583 -8.301 87.511 1.00 40.00 C
+ATOM 2473 O GLU B 15 -37.996 -8.937 88.391 1.00 40.00 O
+ATOM 2474 CB GLU B 15 -37.589 -7.256 85.454 1.00 40.00 C
+ATOM 2475 CG GLU B 15 -37.021 -6.013 84.780 1.00 40.00 C
+ATOM 2476 CD GLU B 15 -36.490 -6.278 83.382 1.00 40.00 C
+ATOM 2477 OE1 GLU B 15 -35.323 -5.908 83.105 1.00 40.00 O
+ATOM 2478 OE2 GLU B 15 -37.239 -6.858 82.563 1.00 40.00 O
+ATOM 2479 N LEU B 16 -39.773 -8.645 87.025 1.00 40.00 N
+ATOM 2480 CA LEU B 16 -40.571 -9.736 87.586 1.00 40.00 C
+ATOM 2481 C LEU B 16 -41.869 -9.946 86.818 1.00 40.00 C
+ATOM 2482 O LEU B 16 -42.302 -9.087 86.054 1.00 40.00 O
+ATOM 2483 CB LEU B 16 -40.907 -9.475 89.050 1.00 40.00 C
+ATOM 2484 CG LEU B 16 -41.741 -8.218 89.287 1.00 40.00 C
+ATOM 2485 CD1 LEU B 16 -42.715 -8.439 90.428 1.00 40.00 C
+ATOM 2486 CD2 LEU B 16 -40.852 -7.006 89.547 1.00 40.00 C
+ATOM 2487 N GLN B 17 -42.500 -11.089 87.060 1.00 40.00 N
+ATOM 2488 CA GLN B 17 -43.656 -11.522 86.279 1.00 40.00 C
+ATOM 2489 C GLN B 17 -44.938 -11.455 87.089 1.00 40.00 C
+ATOM 2490 O GLN B 17 -45.044 -12.076 88.148 1.00 40.00 O
+ATOM 2491 CB GLN B 17 -43.439 -12.948 85.745 1.00 40.00 C
+ATOM 2492 CG GLN B 17 -42.303 -13.069 84.733 1.00 40.00 C
+ATOM 2493 CD GLN B 17 -42.375 -12.015 83.633 1.00 40.00 C
+ATOM 2494 OE1 GLN B 17 -41.444 -11.226 83.450 1.00 40.00 O
+ATOM 2495 NE2 GLN B 17 -43.490 -11.993 82.901 1.00 40.00 N
+ATOM 2496 N VAL B 18 -45.914 -10.707 86.585 1.00 40.00 N
+ATOM 2497 CA VAL B 18 -47.151 -10.507 87.333 1.00 40.00 C
+ATOM 2498 C VAL B 18 -48.420 -10.876 86.580 1.00 40.00 C
+ATOM 2499 O VAL B 18 -48.741 -10.271 85.549 1.00 40.00 O
+ATOM 2500 CB VAL B 18 -47.303 -9.065 87.838 1.00 40.00 C
+ATOM 2501 CG1 VAL B 18 -48.354 -9.017 88.947 1.00 40.00 C
+ATOM 2502 CG2 VAL B 18 -45.963 -8.520 88.318 1.00 40.00 C
+ATOM 2503 N PRO B 19 -49.154 -11.867 87.111 1.00 40.00 N
+ATOM 2504 CA PRO B 19 -50.457 -12.258 86.585 1.00 40.00 C
+ATOM 2505 C PRO B 19 -51.437 -11.091 86.617 1.00 40.00 C
+ATOM 2506 O PRO B 19 -51.528 -10.413 87.639 1.00 40.00 O
+ATOM 2507 CB PRO B 19 -50.897 -13.364 87.551 1.00 40.00 C
+ATOM 2508 CG PRO B 19 -49.618 -13.959 88.038 1.00 40.00 C
+ATOM 2509 CD PRO B 19 -48.689 -12.788 88.168 1.00 40.00 C
+ATOM 2510 N ASP B 20 -52.153 -10.875 85.506 1.00 40.00 N
+ATOM 2511 CA ASP B 20 -53.104 -9.750 85.347 1.00 40.00 C
+ATOM 2512 C ASP B 20 -54.350 -9.792 86.256 1.00 40.00 C
+ATOM 2513 O ASP B 20 -55.247 -8.947 86.131 1.00 40.00 O
+ATOM 2514 CB ASP B 20 -53.492 -9.524 83.859 1.00 40.00 C
+ATOM 2515 CG ASP B 20 -54.532 -10.535 83.323 1.00 40.00 C
+ATOM 2516 OD1 ASP B 20 -54.851 -10.458 82.106 1.00 40.00 O
+ATOM 2517 OD2 ASP B 20 -55.033 -11.391 84.093 1.00 40.00 O
+ATOM 2518 N ASP B 21 -54.386 -10.777 87.156 1.00 40.00 N
+ATOM 2519 CA ASP B 21 -55.429 -10.904 88.175 1.00 40.00 C
+ATOM 2520 C ASP B 21 -54.848 -10.740 89.583 1.00 40.00 C
+ATOM 2521 O ASP B 21 -55.563 -10.873 90.583 1.00 40.00 O
+ATOM 2522 CB ASP B 21 -56.128 -12.257 88.055 1.00 40.00 C
+ATOM 2523 CG ASP B 21 -55.154 -13.404 87.801 1.00 40.00 C
+ATOM 2524 OD1 ASP B 21 -53.933 -13.251 88.036 1.00 40.00 O
+ATOM 2525 OD2 ASP B 21 -55.615 -14.472 87.352 1.00 40.00 O
+ATOM 2526 N VAL B 22 -53.548 -10.449 89.643 1.00 40.00 N
+ATOM 2527 CA VAL B 22 -52.842 -10.206 90.900 1.00 40.00 C
+ATOM 2528 C VAL B 22 -52.370 -8.749 90.938 1.00 40.00 C
+ATOM 2529 O VAL B 22 -51.800 -8.251 89.961 1.00 40.00 O
+ATOM 2530 CB VAL B 22 -51.640 -11.179 91.062 1.00 40.00 C
+ATOM 2531 CG1 VAL B 22 -50.811 -10.856 92.306 1.00 40.00 C
+ATOM 2532 CG2 VAL B 22 -52.118 -12.627 91.103 1.00 40.00 C
+ATOM 2533 N TYR B 23 -52.630 -8.073 92.059 1.00 40.00 N
+ATOM 2534 CA TYR B 23 -52.105 -6.731 92.301 1.00 40.00 C
+ATOM 2535 C TYR B 23 -50.579 -6.719 92.270 1.00 40.00 C
+ATOM 2536 O TYR B 23 -49.926 -7.702 92.647 1.00 40.00 O
+ATOM 2537 CB TYR B 23 -52.572 -6.210 93.649 1.00 40.00 C
+ATOM 2538 CG TYR B 23 -54.047 -5.929 93.750 1.00 40.00 C
+ATOM 2539 CD1 TYR B 23 -54.864 -6.674 94.605 1.00 40.00 C
+ATOM 2540 CD2 TYR B 23 -54.631 -4.906 93.011 1.00 40.00 C
+ATOM 2541 CE1 TYR B 23 -56.224 -6.404 94.718 1.00 40.00 C
+ATOM 2542 CE2 TYR B 23 -55.990 -4.632 93.110 1.00 40.00 C
+ATOM 2543 CZ TYR B 23 -56.784 -5.378 93.966 1.00 40.00 C
+ATOM 2544 OH TYR B 23 -58.133 -5.095 94.060 1.00 40.00 O
+ATOM 2545 N ILE B 24 -50.015 -5.593 91.839 1.00 40.00 N
+ATOM 2546 CA ILE B 24 -48.579 -5.498 91.589 1.00 40.00 C
+ATOM 2547 C ILE B 24 -47.747 -5.671 92.847 1.00 40.00 C
+ATOM 2548 O ILE B 24 -46.802 -6.457 92.871 1.00 40.00 O
+ATOM 2549 CB ILE B 24 -48.221 -4.176 90.903 1.00 40.00 C
+ATOM 2550 CG1 ILE B 24 -48.733 -4.196 89.477 1.00 40.00 C
+ATOM 2551 CG2 ILE B 24 -46.720 -3.994 90.855 1.00 40.00 C
+ATOM 2552 CD1 ILE B 24 -48.951 -2.828 88.881 1.00 40.00 C
+ATOM 2553 N LEU B 25 -48.117 -4.932 93.886 1.00 40.00 N
+ATOM 2554 CA LEU B 25 -47.412 -4.939 95.166 1.00 40.00 C
+ATOM 2555 C LEU B 25 -47.416 -6.321 95.823 1.00 40.00 C
+ATOM 2556 O LEU B 25 -46.398 -6.747 96.385 1.00 40.00 O
+ATOM 2557 CB LEU B 25 -48.027 -3.896 96.104 1.00 40.00 C
+ATOM 2558 CG LEU B 25 -47.376 -3.610 97.455 1.00 40.00 C
+ATOM 2559 CD1 LEU B 25 -46.174 -2.689 97.310 1.00 40.00 C
+ATOM 2560 CD2 LEU B 25 -48.415 -2.996 98.378 1.00 40.00 C
+ATOM 2561 N ASP B 26 -48.557 -7.008 95.745 1.00 40.00 N
+ATOM 2562 CA ASP B 26 -48.681 -8.387 96.208 1.00 40.00 C
+ATOM 2563 C ASP B 26 -47.572 -9.258 95.659 1.00 40.00 C
+ATOM 2564 O ASP B 26 -46.868 -9.932 96.417 1.00 40.00 O
+ATOM 2565 CB ASP B 26 -50.022 -8.953 95.790 1.00 40.00 C
+ATOM 2566 CG ASP B 26 -51.158 -8.223 96.424 1.00 40.00 C
+ATOM 2567 OD1 ASP B 26 -50.891 -7.377 97.298 1.00 40.00 O
+ATOM 2568 OD2 ASP B 26 -52.311 -8.486 96.047 1.00 40.00 O
+ATOM 2569 N GLN B 27 -47.415 -9.224 94.339 1.00 40.00 N
+ATOM 2570 CA GLN B 27 -46.324 -9.919 93.677 1.00 40.00 C
+ATOM 2571 C GLN B 27 -44.939 -9.535 94.252 1.00 40.00 C
+ATOM 2572 O GLN B 27 -44.220 -10.401 94.777 1.00 40.00 O
+ATOM 2573 CB GLN B 27 -46.396 -9.683 92.162 1.00 40.00 C
+ATOM 2574 CG GLN B 27 -45.584 -10.675 91.344 1.00 40.00 C
+ATOM 2575 CD GLN B 27 -46.015 -12.104 91.588 1.00 40.00 C
+ATOM 2576 OE1 GLN B 27 -47.193 -12.437 91.453 1.00 40.00 O
+ATOM 2577 NE2 GLN B 27 -45.066 -12.957 91.960 1.00 40.00 N
+ATOM 2578 N ALA B 28 -44.597 -8.241 94.176 1.00 40.00 N
+ATOM 2579 CA ALA B 28 -43.285 -7.715 94.595 1.00 40.00 C
+ATOM 2580 C ALA B 28 -42.860 -8.244 95.952 1.00 40.00 C
+ATOM 2581 O ALA B 28 -41.702 -8.605 96.161 1.00 40.00 O
+ATOM 2582 CB ALA B 28 -43.304 -6.200 94.614 1.00 40.00 C
+ATOM 2583 N GLU B 29 -43.828 -8.302 96.857 1.00 40.00 N
+ATOM 2584 CA GLU B 29 -43.632 -8.814 98.204 1.00 40.00 C
+ATOM 2585 C GLU B 29 -43.206 -10.302 98.235 1.00 40.00 C
+ATOM 2586 O GLU B 29 -42.186 -10.626 98.849 1.00 40.00 O
+ATOM 2587 CB GLU B 29 -44.906 -8.571 99.011 1.00 40.00 C
+ATOM 2588 CG GLU B 29 -44.782 -8.712 100.514 1.00 40.00 C
+ATOM 2589 CD GLU B 29 -46.145 -8.837 101.155 1.00 40.00 C
+ATOM 2590 OE1 GLU B 29 -47.150 -8.623 100.449 1.00 40.00 O
+ATOM 2591 OE2 GLU B 29 -46.219 -9.153 102.356 1.00 40.00 O
+ATOM 2592 N GLU B 30 -43.964 -11.189 97.576 1.00 40.00 N
+ATOM 2593 CA GLU B 30 -43.621 -12.625 97.537 1.00 40.00 C
+ATOM 2594 C GLU B 30 -42.341 -12.829 96.794 1.00 40.00 C
+ATOM 2595 O GLU B 30 -41.678 -13.853 96.954 1.00 40.00 O
+ATOM 2596 CB GLU B 30 -44.655 -13.445 96.800 1.00 40.00 C
+ATOM 2597 CG GLU B 30 -45.945 -13.677 97.541 1.00 40.00 C
+ATOM 2598 CD GLU B 30 -47.013 -14.147 96.584 1.00 40.00 C
+ATOM 2599 OE1 GLU B 30 -46.699 -15.067 95.788 1.00 40.00 O
+ATOM 2600 OE2 GLU B 30 -48.141 -13.589 96.611 1.00 40.00 O
+ATOM 2601 N ASP B 31 -42.030 -11.861 95.944 1.00 40.00 N
+ATOM 2602 CA ASP B 31 -40.783 -11.861 95.221 1.00 40.00 C
+ATOM 2603 C ASP B 31 -39.734 -11.101 96.003 1.00 40.00 C
+ATOM 2604 O ASP B 31 -38.678 -10.767 95.476 1.00 40.00 O
+ATOM 2605 CB ASP B 31 -40.975 -11.298 93.816 1.00 40.00 C
+ATOM 2606 CG ASP B 31 -41.769 -12.247 92.912 1.00 40.00 C
+ATOM 2607 OD1 ASP B 31 -42.290 -13.277 93.423 1.00 40.00 O
+ATOM 2608 OD2 ASP B 31 -41.872 -11.964 91.690 1.00 40.00 O
+ATOM 2609 N GLY B 32 -40.042 -10.838 97.269 1.00 40.00 N
+ATOM 2610 CA GLY B 32 -39.059 -10.364 98.233 1.00 40.00 C
+ATOM 2611 C GLY B 32 -38.613 -8.932 98.066 1.00 40.00 C
+ATOM 2612 O GLY B 32 -37.513 -8.572 98.493 1.00 40.00 O
+ATOM 2613 N ILE B 33 -39.466 -8.115 97.452 1.00 40.00 N
+ATOM 2614 CA ILE B 33 -39.151 -6.708 97.222 1.00 40.00 C
+ATOM 2615 C ILE B 33 -39.905 -5.807 98.195 1.00 40.00 C
+ATOM 2616 O ILE B 33 -41.122 -5.951 98.391 1.00 40.00 O
+ATOM 2617 CB ILE B 33 -39.420 -6.274 95.768 1.00 40.00 C
+ATOM 2618 CG1 ILE B 33 -38.961 -7.357 94.789 1.00 40.00 C
+ATOM 2619 CG2 ILE B 33 -38.694 -4.968 95.473 1.00 40.00 C
+ATOM 2620 CD1 ILE B 33 -39.755 -7.404 93.498 1.00 40.00 C
+ATOM 2621 N ASP B 34 -39.150 -4.888 98.797 1.00 40.00 N
+ATOM 2622 CA ASP B 34 -39.662 -3.966 99.801 1.00 40.00 C
+ATOM 2623 C ASP B 34 -40.100 -2.634 99.160 1.00 40.00 C
+ATOM 2624 O ASP B 34 -39.283 -1.744 98.864 1.00 40.00 O
+ATOM 2625 CB ASP B 34 -38.617 -3.770 100.921 1.00 40.00 C
+ATOM 2626 CG ASP B 34 -39.196 -3.111 102.192 1.00 40.00 C
+ATOM 2627 OD1 ASP B 34 -40.444 -3.043 102.348 1.00 40.00 O
+ATOM 2628 OD2 ASP B 34 -38.385 -2.663 103.046 1.00 40.00 O
+ATOM 2629 N LEU B 35 -41.410 -2.530 98.942 1.00 40.00 N
+ATOM 2630 CA LEU B 35 -42.039 -1.341 98.380 1.00 40.00 C
+ATOM 2631 C LEU B 35 -42.942 -0.709 99.418 1.00 40.00 C
+ATOM 2632 O LEU B 35 -43.597 -1.427 100.179 1.00 40.00 O
+ATOM 2633 CB LEU B 35 -42.890 -1.709 97.172 1.00 40.00 C
+ATOM 2634 CG LEU B 35 -42.232 -2.483 96.042 1.00 40.00 C
+ATOM 2635 CD1 LEU B 35 -43.293 -2.924 95.052 1.00 40.00 C
+ATOM 2636 CD2 LEU B 35 -41.174 -1.617 95.377 1.00 40.00 C
+ATOM 2637 N PRO B 36 -43.009 0.635 99.438 1.00 40.00 N
+ATOM 2638 CA PRO B 36 -43.776 1.316 100.485 1.00 40.00 C
+ATOM 2639 C PRO B 36 -45.285 1.047 100.366 1.00 40.00 C
+ATOM 2640 O PRO B 36 -45.777 0.865 99.251 1.00 40.00 O
+ATOM 2641 CB PRO B 36 -43.454 2.798 100.242 1.00 40.00 C
+ATOM 2642 CG PRO B 36 -43.158 2.881 98.782 1.00 40.00 C
+ATOM 2643 CD PRO B 36 -42.488 1.580 98.430 1.00 40.00 C
+ATOM 2644 N TYR B 37 -45.982 0.998 101.512 1.00 40.00 N
+ATOM 2645 CA TYR B 37 -47.441 0.776 101.588 1.00 40.00 C
+ATOM 2646 C TYR B 37 -48.046 1.211 102.913 1.00 40.00 C
+ATOM 2647 O TYR B 37 -47.326 1.506 103.845 1.00 40.00 O
+ATOM 2648 CB TYR B 37 -47.817 -0.689 101.297 1.00 40.00 C
+ATOM 2649 CG TYR B 37 -47.342 -1.774 102.272 1.00 40.00 C
+ATOM 2650 CD1 TYR B 37 -46.012 -2.208 102.285 1.00 40.00 C
+ATOM 2651 CD2 TYR B 37 -48.243 -2.419 103.120 1.00 40.00 C
+ATOM 2652 CE1 TYR B 37 -45.597 -3.216 103.140 1.00 40.00 C
+ATOM 2653 CE2 TYR B 37 -47.834 -3.429 103.971 1.00 40.00 C
+ATOM 2654 CZ TYR B 37 -46.515 -3.817 103.973 1.00 40.00 C
+ATOM 2655 OH TYR B 37 -46.110 -4.806 104.819 1.00 40.00 O
+ATOM 2656 N SER B 38 -49.372 1.265 102.979 1.00 40.00 N
+ATOM 2657 CA SER B 38 -50.075 1.532 104.225 1.00 40.00 C
+ATOM 2658 C SER B 38 -51.425 0.825 104.285 1.00 40.00 C
+ATOM 2659 O SER B 38 -51.560 -0.212 104.937 1.00 40.00 O
+ATOM 2660 CB SER B 38 -50.269 3.028 104.435 1.00 40.00 C
+ATOM 2661 OG SER B 38 -50.794 3.262 105.728 1.00 40.00 O
+ATOM 2662 N CYS B 39 -52.413 1.393 103.593 1.00 40.00 N
+ATOM 2663 CA CYS B 39 -53.800 0.917 103.621 1.00 40.00 C
+ATOM 2664 C CYS B 39 -53.963 -0.458 102.981 1.00 40.00 C
+ATOM 2665 O CYS B 39 -54.596 -1.359 103.552 1.00 40.00 O
+ATOM 2666 CB CYS B 39 -54.707 1.920 102.899 1.00 40.00 C
+ATOM 2667 SG CYS B 39 -54.499 1.939 101.101 1.00 40.00 S
+ATOM 2668 N ARG B 40 -53.382 -0.592 101.788 1.00 40.00 N
+ATOM 2669 CA ARG B 40 -53.546 -1.759 100.921 1.00 40.00 C
+ATOM 2670 C ARG B 40 -55.000 -1.941 100.498 1.00 40.00 C
+ATOM 2671 O ARG B 40 -55.512 -3.053 100.410 1.00 40.00 O
+ATOM 2672 CB ARG B 40 -52.964 -3.008 101.573 1.00 40.00 C
+ATOM 2673 CG ARG B 40 -51.452 -2.942 101.679 1.00 40.00 C
+ATOM 2674 CD ARG B 40 -50.910 -4.052 102.552 1.00 40.00 C
+ATOM 2675 NE ARG B 40 -51.013 -5.348 101.896 1.00 40.00 N
+ATOM 2676 CZ ARG B 40 -50.055 -5.890 101.150 1.00 40.00 C
+ATOM 2677 NH1 ARG B 40 -48.909 -5.250 100.962 1.00 40.00 N
+ATOM 2678 NH2 ARG B 40 -50.243 -7.077 100.593 1.00 40.00 N
+ATOM 2679 N ALA B 41 -55.654 -0.817 100.242 1.00 40.00 N
+ATOM 2680 CA ALA B 41 -57.024 -0.806 99.756 1.00 40.00 C
+ATOM 2681 C ALA B 41 -57.257 0.442 98.916 1.00 40.00 C
+ATOM 2682 O ALA B 41 -58.393 0.873 98.692 1.00 40.00 O
+ATOM 2683 CB ALA B 41 -58.013 -0.902 100.902 1.00 40.00 C
+ATOM 2684 N GLY B 42 -56.150 1.021 98.465 1.00 40.00 N
+ATOM 2685 CA GLY B 42 -56.171 1.959 97.355 1.00 40.00 C
+ATOM 2686 C GLY B 42 -56.852 3.277 97.621 1.00 40.00 C
+ATOM 2687 O GLY B 42 -57.432 3.875 96.719 1.00 40.00 O
+ATOM 2688 N SER B 43 -56.792 3.734 98.861 1.00 40.00 N
+ATOM 2689 CA SER B 43 -57.242 5.077 99.158 1.00 40.00 C
+ATOM 2690 C SER B 43 -56.235 5.797 100.032 1.00 40.00 C
+ATOM 2691 O SER B 43 -56.621 6.514 100.939 1.00 40.00 O
+ATOM 2692 CB SER B 43 -58.644 5.070 99.788 1.00 40.00 C
+ATOM 2693 OG SER B 43 -58.642 4.519 101.092 1.00 40.00 O
+ATOM 2694 N CYS B 44 -54.948 5.591 99.763 1.00 40.00 N
+ATOM 2695 CA CYS B 44 -53.889 6.330 100.446 1.00 40.00 C
+ATOM 2696 C CYS B 44 -52.771 6.656 99.469 1.00 40.00 C
+ATOM 2697 O CYS B 44 -52.956 6.518 98.273 1.00 40.00 O
+ATOM 2698 CB CYS B 44 -53.371 5.569 101.663 1.00 40.00 C
+ATOM 2699 SG CYS B 44 -51.997 4.467 101.318 1.00 40.00 S
+ATOM 2700 N SER B 45 -51.617 7.080 99.970 1.00 40.00 N
+ATOM 2701 CA SER B 45 -50.556 7.583 99.102 1.00 40.00 C
+ATOM 2702 C SER B 45 -49.225 6.835 99.209 1.00 40.00 C
+ATOM 2703 O SER B 45 -48.283 7.137 98.469 1.00 40.00 O
+ATOM 2704 CB SER B 45 -50.326 9.063 99.389 1.00 40.00 C
+ATOM 2705 OG SER B 45 -49.974 9.247 100.749 1.00 40.00 O
+ATOM 2706 N SER B 46 -49.149 5.863 100.116 1.00 40.00 N
+ATOM 2707 CA SER B 46 -47.866 5.238 100.490 1.00 40.00 C
+ATOM 2708 C SER B 46 -47.192 4.505 99.341 1.00 40.00 C
+ATOM 2709 O SER B 46 -45.993 4.674 99.089 1.00 40.00 O
+ATOM 2710 CB SER B 46 -48.044 4.290 101.681 1.00 40.00 C
+ATOM 2711 OG SER B 46 -48.247 5.008 102.885 1.00 40.00 O
+ATOM 2712 N CYS B 47 -47.992 3.717 98.636 1.00 40.00 N
+ATOM 2713 CA CYS B 47 -47.511 2.845 97.579 1.00 40.00 C
+ATOM 2714 C CYS B 47 -47.249 3.577 96.267 1.00 40.00 C
+ATOM 2715 O CYS B 47 -46.905 2.962 95.257 1.00 40.00 O
+ATOM 2716 CB CYS B 47 -48.520 1.725 97.372 1.00 40.00 C
+ATOM 2717 SG CYS B 47 -50.226 2.302 97.364 1.00 40.00 S
+ATOM 2718 N ALA B 48 -47.386 4.895 96.305 1.00 40.00 N
+ATOM 2719 CA ALA B 48 -47.285 5.729 95.124 1.00 40.00 C
+ATOM 2720 C ALA B 48 -46.130 5.394 94.200 1.00 40.00 C
+ATOM 2721 O ALA B 48 -45.009 5.074 94.628 1.00 40.00 O
+ATOM 2722 CB ALA B 48 -47.223 7.190 95.518 1.00 40.00 C
+ATOM 2723 N GLY B 49 -46.444 5.497 92.918 1.00 40.00 N
+ATOM 2724 CA GLY B 49 -45.484 5.319 91.860 1.00 40.00 C
+ATOM 2725 C GLY B 49 -45.930 5.983 90.574 1.00 40.00 C
+ATOM 2726 O GLY B 49 -47.069 6.446 90.453 1.00 40.00 O
+ATOM 2727 N LYS B 50 -45.023 6.011 89.605 1.00 40.00 N
+ATOM 2728 CA LYS B 50 -45.265 6.687 88.348 1.00 40.00 C
+ATOM 2729 C LYS B 50 -45.053 5.756 87.174 1.00 40.00 C
+ATOM 2730 O LYS B 50 -44.003 5.118 87.063 1.00 40.00 O
+ATOM 2731 CB LYS B 50 -44.340 7.894 88.207 1.00 40.00 C
+ATOM 2732 CG LYS B 50 -44.715 9.077 89.083 1.00 40.00 C
+ATOM 2733 CD LYS B 50 -44.402 10.393 88.395 1.00 40.00 C
+ATOM 2734 CE LYS B 50 -45.443 10.704 87.343 1.00 40.00 C
+ATOM 2735 NZ LYS B 50 -44.982 11.862 86.547 1.00 40.00 N
+ATOM 2736 N VAL B 51 -46.048 5.701 86.293 1.00 40.00 N
+ATOM 2737 CA VAL B 51 -45.951 4.910 85.078 1.00 40.00 C
+ATOM 2738 C VAL B 51 -45.055 5.596 84.078 1.00 40.00 C
+ATOM 2739 O VAL B 51 -45.300 6.734 83.686 1.00 40.00 O
+ATOM 2740 CB VAL B 51 -47.317 4.677 84.426 1.00 40.00 C
+ATOM 2741 CG1 VAL B 51 -47.169 3.906 83.118 1.00 40.00 C
+ATOM 2742 CG2 VAL B 51 -48.209 3.907 85.375 1.00 40.00 C
+ATOM 2743 N VAL B 52 -44.014 4.876 83.678 1.00 40.00 N
+ATOM 2744 CA VAL B 52 -43.097 5.312 82.635 1.00 40.00 C
+ATOM 2745 C VAL B 52 -43.600 4.842 81.260 1.00 40.00 C
+ATOM 2746 O VAL B 52 -43.571 5.601 80.283 1.00 40.00 O
+ATOM 2747 CB VAL B 52 -41.673 4.776 82.898 1.00 40.00 C
+ATOM 2748 CG1 VAL B 52 -40.694 5.304 81.856 1.00 40.00 C
+ATOM 2749 CG2 VAL B 52 -41.214 5.144 84.302 1.00 40.00 C
+ATOM 2750 N SER B 53 -44.065 3.593 81.202 1.00 40.00 N
+ATOM 2751 CA SER B 53 -44.579 2.986 79.974 1.00 40.00 C
+ATOM 2752 C SER B 53 -45.525 1.850 80.337 1.00 40.00 C
+ATOM 2753 O SER B 53 -45.565 1.422 81.490 1.00 40.00 O
+ATOM 2754 CB SER B 53 -43.425 2.431 79.150 1.00 40.00 C
+ATOM 2755 OG SER B 53 -42.770 1.398 79.868 1.00 40.00 O
+ATOM 2756 N GLY B 54 -46.275 1.359 79.357 1.00 40.00 N
+ATOM 2757 CA GLY B 54 -47.226 0.286 79.599 1.00 40.00 C
+ATOM 2758 C GLY B 54 -48.460 0.783 80.323 1.00 40.00 C
+ATOM 2759 O GLY B 54 -48.523 1.934 80.766 1.00 40.00 O
+ATOM 2760 N SER B 55 -49.441 -0.101 80.446 1.00 40.00 N
+ATOM 2761 CA SER B 55 -50.738 0.250 81.011 1.00 40.00 C
+ATOM 2762 C SER B 55 -51.091 -0.587 82.242 1.00 40.00 C
+ATOM 2763 O SER B 55 -50.592 -1.702 82.404 1.00 40.00 O
+ATOM 2764 CB SER B 55 -51.824 0.089 79.943 1.00 40.00 C
+ATOM 2765 OG SER B 55 -51.783 -1.199 79.348 1.00 40.00 O
+ATOM 2766 N VAL B 56 -51.943 -0.042 83.113 1.00 40.00 N
+ATOM 2767 CA VAL B 56 -52.496 -0.808 84.248 1.00 40.00 C
+ATOM 2768 C VAL B 56 -54.006 -0.595 84.445 1.00 40.00 C
+ATOM 2769 O VAL B 56 -54.576 0.406 83.989 1.00 40.00 O
+ATOM 2770 CB VAL B 56 -51.773 -0.538 85.591 1.00 40.00 C
+ATOM 2771 CG1 VAL B 56 -50.260 -0.576 85.436 1.00 40.00 C
+ATOM 2772 CG2 VAL B 56 -52.237 0.769 86.203 1.00 40.00 C
+ATOM 2773 N ASP B 57 -54.644 -1.550 85.121 1.00 40.00 N
+ATOM 2774 CA ASP B 57 -56.062 -1.456 85.458 1.00 40.00 C
+ATOM 2775 C ASP B 57 -56.161 -1.222 86.943 1.00 40.00 C
+ATOM 2776 O ASP B 57 -56.246 -2.163 87.742 1.00 40.00 O
+ATOM 2777 CB ASP B 57 -56.836 -2.724 85.045 1.00 40.00 C
+ATOM 2778 CG ASP B 57 -58.263 -2.785 85.630 1.00 40.00 C
+ATOM 2779 OD1 ASP B 57 -58.805 -3.908 85.746 1.00 40.00 O
+ATOM 2780 OD2 ASP B 57 -58.842 -1.729 85.972 1.00 40.00 O
+ATOM 2781 N GLN B 58 -56.140 0.048 87.312 1.00 40.00 N
+ATOM 2782 CA GLN B 58 -56.276 0.405 88.707 1.00 40.00 C
+ATOM 2783 C GLN B 58 -57.672 0.898 89.019 1.00 40.00 C
+ATOM 2784 O GLN B 58 -57.853 1.781 89.854 1.00 40.00 O
+ATOM 2785 CB GLN B 58 -55.238 1.434 89.094 1.00 40.00 C
+ATOM 2786 CG GLN B 58 -55.110 2.549 88.089 1.00 40.00 C
+ATOM 2787 CD GLN B 58 -54.138 3.605 88.550 1.00 40.00 C
+ATOM 2788 OE1 GLN B 58 -53.820 4.544 87.808 1.00 40.00 O
+ATOM 2789 NE2 GLN B 58 -53.651 3.462 89.787 1.00 40.00 N
+ATOM 2790 N SER B 59 -58.661 0.326 88.335 1.00 40.00 N
+ATOM 2791 CA SER B 59 -60.042 0.553 88.715 1.00 40.00 C
+ATOM 2792 C SER B 59 -60.224 -0.127 90.066 1.00 40.00 C
+ATOM 2793 O SER B 59 -59.732 -1.243 90.307 1.00 40.00 O
+ATOM 2794 CB SER B 59 -61.035 0.044 87.660 1.00 40.00 C
+ATOM 2795 OG SER B 59 -60.987 -1.366 87.537 1.00 40.00 O
+ATOM 2796 N ASP B 60 -60.885 0.601 90.953 1.00 40.00 N
+ATOM 2797 CA ASP B 60 -61.073 0.197 92.333 1.00 40.00 C
+ATOM 2798 C ASP B 60 -60.060 0.813 93.298 1.00 40.00 C
+ATOM 2799 O ASP B 60 -59.903 0.344 94.426 1.00 40.00 O
+ATOM 2800 CB ASP B 60 -61.084 -1.318 92.474 1.00 40.00 C
+ATOM 2801 CG ASP B 60 -61.974 -1.771 93.586 1.00 40.00 C
+ATOM 2802 OD1 ASP B 60 -62.636 -0.922 94.229 1.00 40.00 O
+ATOM 2803 OD2 ASP B 60 -62.016 -2.987 93.816 1.00 40.00 O
+ATOM 2804 N GLN B 61 -59.372 1.858 92.843 1.00 40.00 N
+ATOM 2805 CA GLN B 61 -58.739 2.803 93.757 1.00 40.00 C
+ATOM 2806 C GLN B 61 -59.721 3.951 93.954 1.00 40.00 C
+ATOM 2807 O GLN B 61 -60.731 4.033 93.253 1.00 40.00 O
+ATOM 2808 CB GLN B 61 -57.377 3.298 93.231 1.00 40.00 C
+ATOM 2809 CG GLN B 61 -57.399 4.229 92.015 1.00 40.00 C
+ATOM 2810 CD GLN B 61 -57.531 5.715 92.352 1.00 40.00 C
+ATOM 2811 OE1 GLN B 61 -57.046 6.194 93.382 1.00 40.00 O
+ATOM 2812 NE2 GLN B 61 -58.183 6.454 91.463 1.00 40.00 N
+ATOM 2813 N SER B 62 -59.431 4.829 94.908 1.00 40.00 N
+ATOM 2814 CA SER B 62 -60.283 5.991 95.144 1.00 40.00 C
+ATOM 2815 C SER B 62 -59.534 7.281 95.529 1.00 40.00 C
+ATOM 2816 O SER B 62 -60.147 8.345 95.598 1.00 40.00 O
+ATOM 2817 CB SER B 62 -61.415 5.660 96.142 1.00 40.00 C
+ATOM 2818 OG SER B 62 -61.075 4.598 97.021 1.00 40.00 O
+ATOM 2819 N TYR B 63 -58.219 7.195 95.736 1.00 40.00 N
+ATOM 2820 CA TYR B 63 -57.419 8.334 96.241 1.00 40.00 C
+ATOM 2821 C TYR B 63 -57.030 9.406 95.199 1.00 40.00 C
+ATOM 2822 O TYR B 63 -57.100 10.615 95.473 1.00 40.00 O
+ATOM 2823 CB TYR B 63 -56.161 7.820 96.961 1.00 40.00 C
+ATOM 2824 CG TYR B 63 -55.351 8.887 97.685 1.00 40.00 C
+ATOM 2825 CD1 TYR B 63 -54.398 9.660 97.010 1.00 40.00 C
+ATOM 2826 CD2 TYR B 63 -55.524 9.105 99.046 1.00 40.00 C
+ATOM 2827 CE1 TYR B 63 -53.657 10.623 97.676 1.00 40.00 C
+ATOM 2828 CE2 TYR B 63 -54.784 10.060 99.719 1.00 40.00 C
+ATOM 2829 CZ TYR B 63 -53.858 10.815 99.036 1.00 40.00 C
+ATOM 2830 OH TYR B 63 -53.151 11.762 99.735 1.00 40.00 O
+ATOM 2831 N LEU B 64 -56.589 8.971 94.025 1.00 40.00 N
+ATOM 2832 CA LEU B 64 -56.165 9.908 92.998 1.00 40.00 C
+ATOM 2833 C LEU B 64 -57.362 10.478 92.268 1.00 40.00 C
+ATOM 2834 O LEU B 64 -58.344 9.770 92.025 1.00 40.00 O
+ATOM 2835 CB LEU B 64 -55.273 9.216 91.977 1.00 40.00 C
+ATOM 2836 CG LEU B 64 -53.982 8.569 92.452 1.00 40.00 C
+ATOM 2837 CD1 LEU B 64 -53.414 7.717 91.333 1.00 40.00 C
+ATOM 2838 CD2 LEU B 64 -52.975 9.616 92.886 1.00 40.00 C
+ATOM 2839 N ASP B 65 -57.279 11.758 91.912 1.00 40.00 N
+ATOM 2840 CA ASP B 65 -58.207 12.327 90.935 1.00 40.00 C
+ATOM 2841 C ASP B 65 -57.750 11.942 89.529 1.00 40.00 C
+ATOM 2842 O ASP B 65 -56.681 11.346 89.358 1.00 40.00 O
+ATOM 2843 CB ASP B 65 -58.299 13.847 91.079 1.00 40.00 C
+ATOM 2844 CG ASP B 65 -56.953 14.542 90.909 1.00 40.00 C
+ATOM 2845 OD1 ASP B 65 -56.245 14.293 89.902 1.00 40.00 O
+ATOM 2846 OD2 ASP B 65 -56.613 15.359 91.789 1.00 40.00 O
+ATOM 2847 N ASP B 66 -58.541 12.298 88.524 1.00 40.00 N
+ATOM 2848 CA ASP B 66 -58.230 11.914 87.156 1.00 40.00 C
+ATOM 2849 C ASP B 66 -56.964 12.516 86.562 1.00 40.00 C
+ATOM 2850 O ASP B 66 -56.278 11.862 85.774 1.00 40.00 O
+ATOM 2851 CB ASP B 66 -59.426 12.198 86.281 1.00 40.00 C
+ATOM 2852 CG ASP B 66 -60.537 11.229 86.533 1.00 40.00 C
+ATOM 2853 OD1 ASP B 66 -60.244 10.020 86.681 1.00 40.00 O
+ATOM 2854 OD2 ASP B 66 -61.697 11.672 86.597 1.00 40.00 O
+ATOM 2855 N GLY B 67 -56.669 13.756 86.954 1.00 40.00 N
+ATOM 2856 CA GLY B 67 -55.488 14.493 86.482 1.00 40.00 C
+ATOM 2857 C GLY B 67 -54.181 13.907 86.984 1.00 40.00 C
+ATOM 2858 O GLY B 67 -53.109 14.125 86.397 1.00 40.00 O
+ATOM 2859 N GLN B 68 -54.290 13.175 88.089 1.00 40.00 N
+ATOM 2860 CA GLN B 68 -53.198 12.381 88.620 1.00 40.00 C
+ATOM 2861 C GLN B 68 -53.087 11.050 87.825 1.00 40.00 C
+ATOM 2862 O GLN B 68 -51.976 10.603 87.508 1.00 40.00 O
+ATOM 2863 CB GLN B 68 -53.372 12.194 90.149 1.00 40.00 C
+ATOM 2864 CG GLN B 68 -53.129 13.483 90.962 1.00 40.00 C
+ATOM 2865 CD GLN B 68 -53.590 13.441 92.429 1.00 40.00 C
+ATOM 2866 OE1 GLN B 68 -54.676 12.939 92.756 1.00 40.00 O
+ATOM 2867 NE2 GLN B 68 -52.769 14.008 93.318 1.00 40.00 N
+ATOM 2868 N ILE B 69 -54.234 10.454 87.471 1.00 40.00 N
+ATOM 2869 CA ILE B 69 -54.281 9.256 86.609 1.00 40.00 C
+ATOM 2870 C ILE B 69 -53.802 9.627 85.218 1.00 40.00 C
+ATOM 2871 O ILE B 69 -53.069 8.872 84.570 1.00 40.00 O
+ATOM 2872 CB ILE B 69 -55.706 8.649 86.519 1.00 40.00 C
+ATOM 2873 CG1 ILE B 69 -56.088 7.980 87.841 1.00 40.00 C
+ATOM 2874 CG2 ILE B 69 -55.800 7.632 85.388 1.00 40.00 C
+ATOM 2875 CD1 ILE B 69 -57.575 7.899 88.092 1.00 40.00 C
+ATOM 2876 N CYS B 70 -54.237 10.804 84.779 1.00 40.00 N
+ATOM 2877 CA CYS B 70 -53.785 11.408 83.543 1.00 40.00 C
+ATOM 2878 C CYS B 70 -52.291 11.666 83.548 1.00 40.00 C
+ATOM 2879 O CYS B 70 -51.654 11.644 82.503 1.00 40.00 O
+ATOM 2880 CB CYS B 70 -54.520 12.722 83.331 1.00 20.00 C
+ATOM 2881 SG CYS B 70 -55.578 12.751 81.867 1.00 20.00 S
+ATOM 2882 N ASP B 71 -51.737 11.908 84.728 1.00 40.00 N
+ATOM 2883 CA ASP B 71 -50.317 12.197 84.857 1.00 40.00 C
+ATOM 2884 C ASP B 71 -49.482 10.930 85.132 1.00 40.00 C
+ATOM 2885 O ASP B 71 -48.294 11.013 85.464 1.00 40.00 O
+ATOM 2886 CB ASP B 71 -50.108 13.265 85.942 1.00 40.00 C
+ATOM 2887 CG ASP B 71 -49.042 14.308 85.567 1.00 40.00 C
+ATOM 2888 OD1 ASP B 71 -48.813 14.563 84.353 1.00 40.00 O
+ATOM 2889 OD2 ASP B 71 -48.438 14.886 86.507 1.00 40.00 O
+ATOM 2890 N GLY B 72 -50.111 9.763 84.994 1.00 40.00 N
+ATOM 2891 CA GLY B 72 -49.407 8.475 85.083 1.00 40.00 C
+ATOM 2892 C GLY B 72 -49.042 8.010 86.484 1.00 40.00 C
+ATOM 2893 O GLY B 72 -48.242 7.087 86.672 1.00 40.00 O
+ATOM 2894 N TRP B 73 -49.628 8.657 87.476 1.00 40.00 N
+ATOM 2895 CA TRP B 73 -49.456 8.244 88.846 1.00 40.00 C
+ATOM 2896 C TRP B 73 -50.145 6.952 89.065 1.00 40.00 C
+ATOM 2897 O TRP B 73 -51.158 6.677 88.426 1.00 40.00 O
+ATOM 2898 CB TRP B 73 -50.064 9.283 89.751 1.00 40.00 C
+ATOM 2899 CG TRP B 73 -49.131 10.425 89.984 1.00 40.00 C
+ATOM 2900 CD1 TRP B 73 -49.193 11.708 89.444 1.00 40.00 C
+ATOM 2901 CD2 TRP B 73 -47.934 10.412 90.827 1.00 40.00 C
+ATOM 2902 NE1 TRP B 73 -48.150 12.475 89.894 1.00 40.00 N
+ATOM 2903 CE2 TRP B 73 -47.352 11.755 90.730 1.00 40.00 C
+ATOM 2904 CE3 TRP B 73 -47.313 9.457 91.641 1.00 40.00 C
+ATOM 2905 CZ2 TRP B 73 -46.195 12.106 91.426 1.00 40.00 C
+ATOM 2906 CZ3 TRP B 73 -46.152 9.822 92.339 1.00 40.00 C
+ATOM 2907 CH2 TRP B 73 -45.606 11.113 92.233 1.00 40.00 C
+ATOM 2908 N VAL B 74 -49.612 6.148 89.980 1.00 40.00 N
+ATOM 2909 CA VAL B 74 -50.226 4.865 90.299 1.00 40.00 C
+ATOM 2910 C VAL B 74 -50.107 4.412 91.742 1.00 40.00 C
+ATOM 2911 O VAL B 74 -49.065 4.565 92.385 1.00 40.00 O
+ATOM 2912 CB VAL B 74 -49.679 3.736 89.414 1.00 40.00 C
+ATOM 2913 CG1 VAL B 74 -48.164 3.659 89.517 1.00 40.00 C
+ATOM 2914 CG2 VAL B 74 -50.328 2.400 89.772 1.00 40.00 C
+ATOM 2915 N LEU B 75 -51.204 3.836 92.221 1.00 40.00 N
+ATOM 2916 CA LEU B 75 -51.234 3.157 93.496 1.00 40.00 C
+ATOM 2917 C LEU B 75 -50.967 1.692 93.263 1.00 40.00 C
+ATOM 2918 O LEU B 75 -51.782 0.978 92.669 1.00 40.00 O
+ATOM 2919 CB LEU B 75 -52.572 3.359 94.214 1.00 40.00 C
+ATOM 2920 CG LEU B 75 -52.784 4.744 94.839 1.00 40.00 C
+ATOM 2921 CD1 LEU B 75 -54.017 4.758 95.737 1.00 40.00 C
+ATOM 2922 CD2 LEU B 75 -51.543 5.191 95.605 1.00 40.00 C
+ATOM 2923 N THR B 76 -49.804 1.267 93.740 1.00 40.00 N
+ATOM 2924 CA THR B 76 -49.308 -0.081 93.537 1.00 40.00 C
+ATOM 2925 C THR B 76 -50.151 -1.165 94.245 1.00 40.00 C
+ATOM 2926 O THR B 76 -50.355 -2.255 93.695 1.00 40.00 O
+ATOM 2927 CB THR B 76 -47.816 -0.170 93.905 1.00 40.00 C
+ATOM 2928 OG1 THR B 76 -47.580 0.574 95.097 1.00 40.00 O
+ATOM 2929 CG2 THR B 76 -46.984 0.449 92.822 1.00 40.00 C
+ATOM 2930 N CYS B 77 -50.674 -0.859 95.430 1.00 40.00 N
+ATOM 2931 CA CYS B 77 -51.440 -1.847 96.189 1.00 40.00 C
+ATOM 2932 C CYS B 77 -52.763 -2.189 95.539 1.00 40.00 C
+ATOM 2933 O CYS B 77 -53.406 -3.150 95.926 1.00 40.00 O
+ATOM 2934 CB CYS B 77 -51.647 -1.410 97.646 1.00 40.00 C
+ATOM 2935 SG CYS B 77 -52.996 -0.254 98.003 1.00 40.00 S
+ATOM 2936 N HIS B 78 -53.165 -1.397 94.555 1.00 40.00 N
+ATOM 2937 CA HIS B 78 -54.412 -1.637 93.838 1.00 40.00 C
+ATOM 2938 C HIS B 78 -54.288 -1.498 92.345 1.00 40.00 C
+ATOM 2939 O HIS B 78 -55.223 -1.052 91.675 1.00 40.00 O
+ATOM 2940 CB HIS B 78 -55.541 -0.763 94.383 1.00 40.00 C
+ATOM 2941 CG HIS B 78 -56.486 -1.489 95.323 1.00 40.00 C
+ATOM 2942 ND1 HIS B 78 -56.058 -2.158 96.412 1.00 40.00 N
+ATOM 2943 CD2 HIS B 78 -57.874 -1.612 95.307 1.00 40.00 C
+ATOM 2944 CE1 HIS B 78 -57.114 -2.689 97.054 1.00 40.00 C
+ATOM 2945 NE2 HIS B 78 -58.225 -2.350 96.379 1.00 40.00 N
+ATOM 2946 N ALA B 79 -53.137 -1.892 91.805 1.00 40.00 N
+ATOM 2947 CA ALA B 79 -52.937 -1.891 90.359 1.00 40.00 C
+ATOM 2948 C ALA B 79 -52.617 -3.296 89.838 1.00 40.00 C
+ATOM 2949 O ALA B 79 -51.672 -3.933 90.322 1.00 40.00 O
+ATOM 2950 CB ALA B 79 -51.850 -0.898 89.967 1.00 40.00 C
+ATOM 2951 N TYR B 80 -53.448 -3.780 88.901 1.00 40.00 N
+ATOM 2952 CA TYR B 80 -53.161 -4.957 88.068 1.00 40.00 C
+ATOM 2953 C TYR B 80 -52.502 -4.454 86.791 1.00 40.00 C
+ATOM 2954 O TYR B 80 -52.779 -3.333 86.363 1.00 40.00 O
+ATOM 2955 CB TYR B 80 -54.442 -5.667 87.636 1.00 40.00 C
+ATOM 2956 CG TYR B 80 -55.349 -6.145 88.726 1.00 40.00 C
+ATOM 2957 CD1 TYR B 80 -56.584 -5.546 88.940 1.00 40.00 C
+ATOM 2958 CD2 TYR B 80 -54.992 -7.219 89.519 1.00 40.00 C
+ATOM 2959 CE1 TYR B 80 -57.433 -5.995 89.928 1.00 40.00 C
+ATOM 2960 CE2 TYR B 80 -55.829 -7.675 90.512 1.00 40.00 C
+ATOM 2961 CZ TYR B 80 -57.045 -7.063 90.708 1.00 40.00 C
+ATOM 2962 OH TYR B 80 -57.857 -7.538 91.703 1.00 40.00 O
+ATOM 2963 N PRO B 81 -51.640 -5.272 86.162 1.00 40.00 N
+ATOM 2964 CA PRO B 81 -51.158 -4.848 84.842 1.00 40.00 C
+ATOM 2965 C PRO B 81 -52.077 -5.311 83.703 1.00 40.00 C
+ATOM 2966 O PRO B 81 -52.777 -6.332 83.835 1.00 40.00 O
+ATOM 2967 CB PRO B 81 -49.786 -5.512 84.739 1.00 40.00 C
+ATOM 2968 CG PRO B 81 -49.877 -6.723 85.618 1.00 40.00 C
+ATOM 2969 CD PRO B 81 -50.941 -6.474 86.657 1.00 40.00 C
+ATOM 2970 N THR B 82 -52.097 -4.546 82.612 1.00 40.00 N
+ATOM 2971 CA THR B 82 -52.779 -4.970 81.388 1.00 40.00 C
+ATOM 2972 C THR B 82 -51.783 -5.006 80.242 1.00 40.00 C
+ATOM 2973 O THR B 82 -52.154 -5.251 79.096 1.00 40.00 O
+ATOM 2974 CB THR B 82 -53.996 -4.084 81.009 1.00 40.00 C
+ATOM 2975 OG1 THR B 82 -53.606 -2.704 80.957 1.00 40.00 O
+ATOM 2976 CG2 THR B 82 -55.162 -4.282 81.992 1.00 40.00 C
+ATOM 2977 N SER B 83 -50.518 -4.756 80.562 1.00 40.00 N
+ATOM 2978 CA SER B 83 -49.452 -4.819 79.581 1.00 40.00 C
+ATOM 2979 C SER B 83 -48.129 -4.899 80.301 1.00 40.00 C
+ATOM 2980 O SER B 83 -48.077 -4.766 81.521 1.00 40.00 O
+ATOM 2981 CB SER B 83 -49.483 -3.593 78.660 1.00 40.00 C
+ATOM 2982 OG SER B 83 -48.931 -2.447 79.279 1.00 40.00 O
+ATOM 2983 N ASP B 84 -47.068 -5.142 79.536 1.00 40.00 N
+ATOM 2984 CA ASP B 84 -45.703 -4.980 80.018 1.00 40.00 C
+ATOM 2985 C ASP B 84 -45.536 -3.536 80.460 1.00 40.00 C
+ATOM 2986 O ASP B 84 -45.883 -2.609 79.728 1.00 40.00 O
+ATOM 2987 CB ASP B 84 -44.694 -5.322 78.916 1.00 40.00 C
+ATOM 2988 CG ASP B 84 -44.421 -6.826 78.795 1.00 40.00 C
+ATOM 2989 OD1 ASP B 84 -43.315 -7.172 78.325 1.00 40.00 O
+ATOM 2990 OD2 ASP B 84 -45.285 -7.660 79.163 1.00 40.00 O
+ATOM 2991 N VAL B 85 -45.022 -3.344 81.667 1.00 40.00 N
+ATOM 2992 CA VAL B 85 -45.050 -2.015 82.277 1.00 40.00 C
+ATOM 2993 C VAL B 85 -43.782 -1.670 83.080 1.00 40.00 C
+ATOM 2994 O VAL B 85 -43.272 -2.502 83.838 1.00 40.00 O
+ATOM 2995 CB VAL B 85 -46.379 -1.788 83.074 1.00 40.00 C
+ATOM 2996 CG1 VAL B 85 -46.649 -2.907 84.077 1.00 40.00 C
+ATOM 2997 CG2 VAL B 85 -46.431 -0.413 83.734 1.00 40.00 C
+ATOM 2998 N VAL B 86 -43.270 -0.452 82.864 1.00 40.00 N
+ATOM 2999 CA VAL B 86 -42.123 0.087 83.605 1.00 40.00 C
+ATOM 3000 C VAL B 86 -42.621 1.117 84.624 1.00 40.00 C
+ATOM 3001 O VAL B 86 -43.398 2.012 84.259 1.00 40.00 O
+ATOM 3002 CB VAL B 86 -41.093 0.764 82.672 1.00 40.00 C
+ATOM 3003 CG1 VAL B 86 -39.861 1.197 83.454 1.00 40.00 C
+ATOM 3004 CG2 VAL B 86 -40.692 -0.169 81.543 1.00 40.00 C
+ATOM 3005 N ILE B 87 -42.168 0.985 85.884 1.00 40.00 N
+ATOM 3006 CA ILE B 87 -42.645 1.810 87.037 1.00 40.00 C
+ATOM 3007 C ILE B 87 -41.541 2.222 88.056 1.00 40.00 C
+ATOM 3008 O ILE B 87 -40.732 1.386 88.491 1.00 40.00 O
+ATOM 3009 CB ILE B 87 -43.849 1.135 87.783 1.00 40.00 C
+ATOM 3010 CG1 ILE B 87 -45.124 1.190 86.936 1.00 40.00 C
+ATOM 3011 CG2 ILE B 87 -44.147 1.820 89.107 1.00 40.00 C
+ATOM 3012 CD1 ILE B 87 -46.294 0.426 87.514 1.00 40.00 C
+ATOM 3013 N GLU B 88 -41.526 3.515 88.417 1.00 40.00 N
+ATOM 3014 CA GLU B 88 -40.719 4.039 89.535 1.00 40.00 C
+ATOM 3015 C GLU B 88 -41.498 3.906 90.829 1.00 40.00 C
+ATOM 3016 O GLU B 88 -42.676 4.247 90.874 1.00 40.00 O
+ATOM 3017 CB GLU B 88 -40.431 5.523 89.345 1.00 40.00 C
+ATOM 3018 CG GLU B 88 -39.597 5.883 88.136 1.00 40.00 C
+ATOM 3019 CD GLU B 88 -39.866 7.299 87.679 1.00 40.00 C
+ATOM 3020 OE1 GLU B 88 -41.040 7.724 87.714 1.00 40.00 O
+ATOM 3021 OE2 GLU B 88 -38.906 7.988 87.279 1.00 40.00 O
+ATOM 3022 N THR B 89 -40.843 3.455 91.888 1.00 40.00 N
+ATOM 3023 CA THR B 89 -41.513 3.322 93.174 1.00 40.00 C
+ATOM 3024 C THR B 89 -41.008 4.387 94.145 1.00 40.00 C
+ATOM 3025 O THR B 89 -40.146 5.187 93.777 1.00 40.00 O
+ATOM 3026 CB THR B 89 -41.315 1.908 93.747 1.00 40.00 C
+ATOM 3027 OG1 THR B 89 -39.932 1.689 94.035 1.00 40.00 O
+ATOM 3028 CG2 THR B 89 -41.749 0.886 92.737 1.00 40.00 C
+ATOM 3029 N HIS B 90 -41.546 4.400 95.370 1.00 40.00 N
+ATOM 3030 CA HIS B 90 -41.099 5.306 96.448 1.00 40.00 C
+ATOM 3031 C HIS B 90 -41.301 6.726 96.016 1.00 40.00 C
+ATOM 3032 O HIS B 90 -40.430 7.584 96.180 1.00 40.00 O
+ATOM 3033 CB HIS B 90 -39.628 5.065 96.849 1.00 40.00 C
+ATOM 3034 CG HIS B 90 -39.315 3.651 97.354 1.00 40.00 C
+ATOM 3035 ND1 HIS B 90 -39.489 2.545 96.596 1.00 40.00 N
+ATOM 3036 CD2 HIS B 90 -38.756 3.209 98.560 1.00 40.00 C
+ATOM 3037 CE1 HIS B 90 -39.104 1.451 97.292 1.00 40.00 C
+ATOM 3038 NE2 HIS B 90 -38.653 1.857 98.490 1.00 40.00 N
+ATOM 3039 N LYS B 91 -42.468 6.975 95.445 1.00 40.00 N
+ATOM 3040 CA LYS B 91 -42.743 8.249 94.819 1.00 40.00 C
+ATOM 3041 C LYS B 91 -43.735 9.073 95.599 1.00 40.00 C
+ATOM 3042 O LYS B 91 -44.197 10.119 95.118 1.00 40.00 O
+ATOM 3043 CB LYS B 91 -43.286 8.017 93.421 1.00 40.00 C
+ATOM 3044 CG LYS B 91 -42.256 7.497 92.443 1.00 40.00 C
+ATOM 3045 CD LYS B 91 -41.324 8.600 91.962 1.00 40.00 C
+ATOM 3046 CE LYS B 91 -40.129 8.783 92.880 1.00 40.00 C
+ATOM 3047 NZ LYS B 91 -39.048 9.476 92.134 1.00 40.00 N
+ATOM 3048 N GLU B 92 -44.073 8.601 96.799 1.00 40.00 N
+ATOM 3049 CA GLU B 92 -45.069 9.292 97.611 1.00 40.00 C
+ATOM 3050 C GLU B 92 -44.666 10.748 97.807 1.00 40.00 C
+ATOM 3051 O GLU B 92 -45.444 11.653 97.494 1.00 40.00 O
+ATOM 3052 CB GLU B 92 -45.310 8.603 98.958 1.00 40.00 C
+ATOM 3053 CG GLU B 92 -46.388 9.303 99.780 1.00 40.00 C
+ATOM 3054 CD GLU B 92 -46.585 8.715 101.164 1.00 40.00 C
+ATOM 3055 OE1 GLU B 92 -45.715 7.950 101.636 1.00 40.00 O
+ATOM 3056 OE2 GLU B 92 -47.617 9.027 101.792 1.00 40.00 O
+ATOM 3057 N GLU B 93 -43.442 10.957 98.292 1.00 40.00 N
+ATOM 3058 CA GLU B 93 -42.939 12.296 98.561 1.00 40.00 C
+ATOM 3059 C GLU B 93 -43.052 13.207 97.342 1.00 40.00 C
+ATOM 3060 O GLU B 93 -43.366 14.400 97.471 1.00 40.00 O
+ATOM 3061 CB GLU B 93 -41.495 12.244 99.043 1.00 40.00 C
+ATOM 3062 CG GLU B 93 -40.877 13.628 99.151 1.00 40.00 C
+ATOM 3063 CD GLU B 93 -39.546 13.630 99.873 1.00 40.00 C
+ATOM 3064 OE1 GLU B 93 -38.557 13.093 99.313 1.00 40.00 O
+ATOM 3065 OE2 GLU B 93 -39.493 14.188 100.998 1.00 40.00 O
+ATOM 3066 N GLU B 94 -42.791 12.641 96.165 1.00 40.00 N
+ATOM 3067 CA GLU B 94 -42.983 13.381 94.934 1.00 40.00 C
+ATOM 3068 C GLU B 94 -44.452 13.784 94.755 1.00 40.00 C
+ATOM 3069 O GLU B 94 -44.734 14.907 94.319 1.00 40.00 O
+ATOM 3070 CB GLU B 94 -42.458 12.621 93.714 1.00 40.00 C
+ATOM 3071 CG GLU B 94 -42.543 13.458 92.442 1.00 40.00 C
+ATOM 3072 CD GLU B 94 -41.943 12.792 91.229 1.00 40.00 C
+ATOM 3073 OE1 GLU B 94 -40.910 12.104 91.369 1.00 40.00 O
+ATOM 3074 OE2 GLU B 94 -42.505 12.978 90.128 1.00 40.00 O
+ATOM 3075 N LEU B 95 -45.374 12.879 95.102 1.00 40.00 N
+ATOM 3076 CA LEU B 95 -46.808 13.186 95.075 1.00 40.00 C
+ATOM 3077 C LEU B 95 -47.161 14.216 96.151 1.00 40.00 C
+ATOM 3078 O LEU B 95 -47.834 15.220 95.891 1.00 40.00 O
+ATOM 3079 CB LEU B 95 -47.625 11.912 95.263 1.00 40.00 C
+ATOM 3080 CG LEU B 95 -49.144 12.067 95.202 1.00 40.00 C
+ATOM 3081 CD1 LEU B 95 -49.617 12.716 93.898 1.00 40.00 C
+ATOM 3082 CD2 LEU B 95 -49.786 10.705 95.409 1.00 40.00 C
+ATOM 3083 N THR B 96 -46.701 13.929 97.363 1.00 40.00 N
+ATOM 3084 CA THR B 96 -46.629 14.885 98.462 1.00 40.00 C
+ATOM 3085 C THR B 96 -45.690 16.047 98.102 1.00 40.00 C
+ATOM 3086 O THR B 96 -45.914 17.200 98.478 1.00 40.00 O
+ATOM 3087 CB THR B 96 -46.142 14.144 99.734 1.00 40.00 C
+ATOM 3088 OG1 THR B 96 -47.275 13.674 100.467 1.00 40.00 O
+ATOM 3089 CG2 THR B 96 -45.272 15.017 100.646 1.00 40.00 C
+TER 3090 THR B 96
+ATOM 3091 N LYS C 18 -58.009 18.926 79.425 1.00 40.00 N
+ATOM 3092 CA LYS C 18 -58.319 17.450 79.423 1.00 40.00 C
+ATOM 3093 C LYS C 18 -57.250 16.682 78.632 1.00 40.00 C
+ATOM 3094 O LYS C 18 -56.972 16.993 77.455 1.00 40.00 O
+ATOM 3095 CB LYS C 18 -59.725 17.138 78.849 1.00 40.00 C
+ATOM 3096 CG LYS C 18 -60.691 18.323 78.676 1.00 40.00 C
+ATOM 3097 CD LYS C 18 -60.325 19.296 77.533 1.00 40.00 C
+ATOM 3098 CE LYS C 18 -59.955 18.619 76.204 1.00 40.00 C
+ATOM 3099 NZ LYS C 18 -61.102 17.999 75.476 1.00 40.00 N
+ATOM 3100 N CYS C 19 -56.645 15.691 79.284 1.00 40.00 N
+ATOM 3101 CA CYS C 19 -55.661 14.858 78.611 1.00 40.00 C
+ATOM 3102 C CYS C 19 -56.375 13.639 77.986 1.00 40.00 C
+ATOM 3103 O CYS C 19 -57.234 12.985 78.612 1.00 40.00 O
+ATOM 3104 CB CYS C 19 -54.438 14.589 79.533 1.00 40.00 C
+ATOM 3105 SG CYS C 19 -54.191 13.011 80.414 1.00 40.00 S
+ATOM 3106 N SER C 20 -56.061 13.414 76.714 1.00 40.00 N
+ATOM 3107 CA SER C 20 -56.756 12.448 75.898 1.00 40.00 C
+ATOM 3108 C SER C 20 -55.937 11.176 75.749 1.00 40.00 C
+ATOM 3109 O SER C 20 -54.711 11.211 75.766 1.00 40.00 O
+ATOM 3110 CB SER C 20 -57.028 13.058 74.531 1.00 40.00 C
+ATOM 3111 OG SER C 20 -57.317 12.055 73.580 1.00 40.00 O
+ATOM 3112 N LYS C 21 -56.629 10.052 75.588 1.00 40.00 N
+ATOM 3113 CA LYS C 21 -55.976 8.749 75.425 1.00 40.00 C
+ATOM 3114 C LYS C 21 -55.500 8.538 73.990 1.00 40.00 C
+ATOM 3115 O LYS C 21 -55.014 7.452 73.650 1.00 40.00 O
+ATOM 3116 CB LYS C 21 -56.914 7.609 75.857 1.00 40.00 C
+ATOM 3117 CG LYS C 21 -57.380 7.714 77.304 1.00 40.00 C
+ATOM 3118 CD LYS C 21 -58.500 6.742 77.617 1.00 40.00 C
+ATOM 3119 CE LYS C 21 -59.278 7.220 78.833 1.00 40.00 C
+ATOM 3120 NZ LYS C 21 -60.349 6.258 79.206 1.00 40.00 N
+ATOM 3121 N LYS C 22 -55.640 9.581 73.166 1.00 40.00 N
+ATOM 3122 CA LYS C 22 -55.257 9.546 71.759 1.00 40.00 C
+ATOM 3123 C LYS C 22 -54.057 10.458 71.563 1.00 40.00 C
+ATOM 3124 O LYS C 22 -54.044 11.564 72.090 1.00 40.00 O
+ATOM 3125 CB LYS C 22 -56.417 10.015 70.878 1.00 40.00 C
+ATOM 3126 CG LYS C 22 -57.774 9.413 71.218 1.00 40.00 C
+ATOM 3127 CD LYS C 22 -58.858 9.982 70.324 1.00 40.00 C
+ATOM 3128 CE LYS C 22 -60.177 9.278 70.544 1.00 40.00 C
+ATOM 3129 NZ LYS C 22 -61.203 9.839 69.630 1.00 40.00 N
+ATOM 3130 N GLN C 23 -53.055 9.992 70.815 1.00 40.00 N
+ATOM 3131 CA GLN C 23 -51.804 10.744 70.620 1.00 40.00 C
+ATOM 3132 C GLN C 23 -52.053 12.095 69.994 1.00 40.00 C
+ATOM 3133 O GLN C 23 -52.320 12.192 68.792 1.00 40.00 O
+ATOM 3134 CB GLN C 23 -50.827 9.987 69.733 1.00 40.00 C
+ATOM 3135 CG GLN C 23 -50.282 8.713 70.339 1.00 40.00 C
+ATOM 3136 CD GLN C 23 -49.611 7.827 69.305 1.00 40.00 C
+ATOM 3137 OE1 GLN C 23 -48.764 8.283 68.523 1.00 40.00 O
+ATOM 3138 NE2 GLN C 23 -49.983 6.549 69.295 1.00 40.00 N
+ATOM 3139 N GLU C 24 -51.955 13.143 70.802 1.00 40.00 N
+ATOM 3140 CA GLU C 24 -52.297 14.462 70.309 1.00 40.00 C
+ATOM 3141 C GLU C 24 -51.056 15.283 69.983 1.00 40.00 C
+ATOM 3142 O GLU C 24 -51.152 16.425 69.542 1.00 40.00 O
+ATOM 3143 CB GLU C 24 -53.274 15.166 71.263 1.00 40.00 C
+ATOM 3144 CG GLU C 24 -54.615 14.429 71.362 1.00 40.00 C
+ATOM 3145 CD GLU C 24 -55.843 15.342 71.429 1.00 40.00 C
+ATOM 3146 OE1 GLU C 24 -55.779 16.502 70.941 1.00 40.00 O
+ATOM 3147 OE2 GLU C 24 -56.892 14.881 71.955 1.00 40.00 O
+ATOM 3148 N GLU C 25 -49.895 14.663 70.135 1.00 40.00 N
+ATOM 3149 CA GLU C 25 -48.629 15.360 69.990 1.00 40.00 C
+ATOM 3150 C GLU C 25 -48.146 15.495 68.541 1.00 40.00 C
+ATOM 3151 O GLU C 25 -47.923 14.494 67.866 1.00 40.00 O
+ATOM 3152 CB GLU C 25 -47.580 14.640 70.832 1.00 40.00 C
+ATOM 3153 CG GLU C 25 -46.161 15.200 70.732 1.00 40.00 C
+ATOM 3154 CD GLU C 25 -45.081 14.190 71.139 1.00 40.00 C
+ATOM 3155 OE1 GLU C 25 -43.878 14.513 71.001 1.00 40.00 O
+ATOM 3156 OE2 GLU C 25 -45.418 13.068 71.591 1.00 40.00 O
+ATOM 3157 N GLY C 26 -47.959 16.735 68.090 1.00 40.00 N
+ATOM 3158 CA GLY C 26 -47.467 17.018 66.743 1.00 40.00 C
+ATOM 3159 C GLY C 26 -48.567 17.152 65.703 1.00 40.00 C
+ATOM 3160 O GLY C 26 -48.339 17.646 64.600 1.00 40.00 O
+ATOM 3161 N VAL C 27 -49.762 16.702 66.059 1.00 40.00 N
+ATOM 3162 CA VAL C 27 -50.917 16.705 65.172 1.00 40.00 C
+ATOM 3163 C VAL C 27 -51.241 18.137 64.758 1.00 40.00 C
+ATOM 3164 O VAL C 27 -51.474 18.974 65.625 1.00 40.00 O
+ATOM 3165 CB VAL C 27 -52.140 16.099 65.903 1.00 40.00 C
+ATOM 3166 CG1 VAL C 27 -53.366 16.071 65.004 1.00 40.00 C
+ATOM 3167 CG2 VAL C 27 -51.836 14.701 66.423 1.00 40.00 C
+ATOM 3168 N VAL C 28 -51.252 18.427 63.456 1.00 40.00 N
+ATOM 3169 CA VAL C 28 -51.605 19.779 62.973 1.00 40.00 C
+ATOM 3170 C VAL C 28 -52.984 19.809 62.296 1.00 40.00 C
+ATOM 3171 O VAL C 28 -53.421 18.810 61.748 1.00 40.00 O
+ATOM 3172 CB VAL C 28 -50.510 20.378 62.046 1.00 40.00 C
+ATOM 3173 CG1 VAL C 28 -49.114 20.079 62.575 1.00 40.00 C
+ATOM 3174 CG2 VAL C 28 -50.633 19.864 60.623 1.00 40.00 C
+ATOM 3175 N THR C 29 -53.681 20.937 62.347 1.00 40.00 N
+ATOM 3176 CA THR C 29 -54.941 21.038 61.611 1.00 40.00 C
+ATOM 3177 C THR C 29 -55.071 22.296 60.777 1.00 40.00 C
+ATOM 3178 O THR C 29 -54.453 23.330 61.067 1.00 40.00 O
+ATOM 3179 CB THR C 29 -56.185 20.910 62.509 1.00 40.00 C
+ATOM 3180 OG1 THR C 29 -55.939 21.548 63.766 1.00 40.00 O
+ATOM 3181 CG2 THR C 29 -56.533 19.456 62.738 1.00 40.00 C
+ATOM 3182 N ASN C 30 -55.889 22.165 59.735 1.00 40.00 N
+ATOM 3183 CA ASN C 30 -56.228 23.234 58.807 1.00 40.00 C
+ATOM 3184 C ASN C 30 -55.059 24.055 58.276 1.00 40.00 C
+ATOM 3185 O ASN C 30 -55.192 25.262 58.029 1.00 40.00 O
+ATOM 3186 CB ASN C 30 -57.311 24.109 59.417 1.00 40.00 C
+ATOM 3187 CG ASN C 30 -58.629 23.387 59.497 1.00 40.00 C
+ATOM 3188 OD1 ASN C 30 -59.401 23.385 58.538 1.00 40.00 O
+ATOM 3189 ND2 ASN C 30 -58.887 22.746 60.633 1.00 40.00 N
+ATOM 3190 N LEU C 31 -53.924 23.383 58.080 1.00 40.00 N
+ATOM 3191 CA LEU C 31 -52.718 24.011 57.540 1.00 40.00 C
+ATOM 3192 C LEU C 31 -52.982 24.730 56.207 1.00 40.00 C
+ATOM 3193 O LEU C 31 -52.474 25.829 55.970 1.00 40.00 O
+ATOM 3194 CB LEU C 31 -51.596 22.987 57.401 1.00 40.00 C
+ATOM 3195 CG LEU C 31 -50.291 23.335 58.116 1.00 40.00 C
+ATOM 3196 CD1 LEU C 31 -49.233 22.305 57.768 1.00 40.00 C
+ATOM 3197 CD2 LEU C 31 -49.800 24.741 57.787 1.00 40.00 C
+ATOM 3198 N TYR C 32 -53.788 24.111 55.351 1.00 40.00 N
+ATOM 3199 CA TYR C 32 -54.310 24.788 54.177 1.00 40.00 C
+ATOM 3200 C TYR C 32 -55.843 24.795 54.232 1.00 40.00 C
+ATOM 3201 O TYR C 32 -56.464 23.794 54.615 1.00 40.00 O
+ATOM 3202 CB TYR C 32 -53.822 24.115 52.889 1.00 40.00 C
+ATOM 3203 CG TYR C 32 -52.311 24.098 52.648 1.00 40.00 C
+ATOM 3204 CD1 TYR C 32 -51.480 23.229 53.360 1.00 40.00 C
+ATOM 3205 CD2 TYR C 32 -51.719 24.922 51.675 1.00 40.00 C
+ATOM 3206 CE1 TYR C 32 -50.111 23.190 53.130 1.00 40.00 C
+ATOM 3207 CE2 TYR C 32 -50.346 24.884 51.437 1.00 40.00 C
+ATOM 3208 CZ TYR C 32 -49.549 24.011 52.170 1.00 40.00 C
+ATOM 3209 OH TYR C 32 -48.191 23.953 51.963 1.00 40.00 O
+ATOM 3210 N LYS C 33 -56.431 25.936 53.857 1.00 40.00 N
+ATOM 3211 CA LYS C 33 -57.901 26.153 53.823 1.00 40.00 C
+ATOM 3212 C LYS C 33 -58.391 26.383 52.371 1.00 40.00 C
+ATOM 3213 O LYS C 33 -57.575 26.701 51.501 1.00 40.00 O
+ATOM 3214 CB LYS C 33 -58.294 27.357 54.709 1.00 40.00 C
+ATOM 3215 CG LYS C 33 -57.982 27.224 56.203 1.00 40.00 C
+ATOM 3216 CD LYS C 33 -58.128 28.566 56.930 1.00 40.00 C
+ATOM 3217 CE LYS C 33 -57.539 28.556 58.340 1.00 40.00 C
+ATOM 3218 NZ LYS C 33 -56.047 28.576 58.334 1.00 40.00 N
+ATOM 3219 N PRO C 34 -59.713 26.220 52.100 1.00 40.00 N
+ATOM 3220 CA PRO C 34 -60.316 26.436 50.759 1.00 40.00 C
+ATOM 3221 C PRO C 34 -59.958 27.747 49.999 1.00 40.00 C
+ATOM 3222 O PRO C 34 -59.988 27.760 48.753 1.00 40.00 O
+ATOM 3223 CB PRO C 34 -61.817 26.365 51.049 1.00 40.00 C
+ATOM 3224 CG PRO C 34 -61.908 25.404 52.178 1.00 40.00 C
+ATOM 3225 CD PRO C 34 -60.690 25.619 53.031 1.00 40.00 C
+ATOM 3226 N LYS C 35 -59.637 28.822 50.735 1.00 40.00 N
+ATOM 3227 CA LYS C 35 -59.136 30.083 50.147 1.00 40.00 C
+ATOM 3228 C LYS C 35 -57.726 29.944 49.520 1.00 40.00 C
+ATOM 3229 O LYS C 35 -57.483 30.459 48.414 1.00 40.00 O
+ATOM 3230 CB LYS C 35 -59.146 31.223 51.184 1.00 40.00 C
+ATOM 3231 CG LYS C 35 -57.854 31.369 51.995 1.00 40.00 C
+ATOM 3232 CD LYS C 35 -58.042 32.238 53.226 1.00 40.00 C
+ATOM 3233 CE LYS C 35 -58.807 31.494 54.323 1.00 40.00 C
+ATOM 3234 NZ LYS C 35 -59.389 32.434 55.331 1.00 40.00 N
+ATOM 3235 N GLU C 36 -56.812 29.265 50.234 1.00 40.00 N
+ATOM 3236 CA GLU C 36 -55.432 29.011 49.755 1.00 40.00 C
+ATOM 3237 C GLU C 36 -54.972 27.531 49.834 1.00 40.00 C
+ATOM 3238 O GLU C 36 -54.097 27.199 50.674 1.00 40.00 O
+ATOM 3239 CB GLU C 36 -54.430 29.949 50.446 1.00 40.00 C
+ATOM 3240 CG GLU C 36 -54.447 31.352 49.858 1.00 40.00 C
+ATOM 3241 CD GLU C 36 -53.270 32.193 50.299 1.00 40.00 C
+ATOM 3242 OE1 GLU C 36 -53.513 33.280 50.859 1.00 40.00 O
+ATOM 3243 OE2 GLU C 36 -52.107 31.776 50.091 1.00 40.00 O
+ATOM 3244 N PRO C 37 -55.548 26.653 48.947 1.00 40.00 N
+ATOM 3245 CA PRO C 37 -55.224 25.226 48.901 1.00 40.00 C
+ATOM 3246 C PRO C 37 -53.844 24.952 48.327 1.00 40.00 C
+ATOM 3247 O PRO C 37 -53.431 25.593 47.353 1.00 40.00 O
+ATOM 3248 CB PRO C 37 -56.285 24.656 47.956 1.00 40.00 C
+ATOM 3249 CG PRO C 37 -56.615 25.776 47.049 1.00 40.00 C
+ATOM 3250 CD PRO C 37 -56.566 26.992 47.926 1.00 40.00 C
+ATOM 3251 N TYR C 38 -53.137 24.004 48.933 1.00 40.00 N
+ATOM 3252 CA TYR C 38 -51.904 23.513 48.355 1.00 40.00 C
+ATOM 3253 C TYR C 38 -52.241 22.809 47.042 1.00 40.00 C
+ATOM 3254 O TYR C 38 -53.164 21.981 46.990 1.00 40.00 O
+ATOM 3255 CB TYR C 38 -51.203 22.553 49.311 1.00 40.00 C
+ATOM 3256 CG TYR C 38 -50.038 21.856 48.679 1.00 40.00 C
+ATOM 3257 CD1 TYR C 38 -48.798 22.492 48.545 1.00 40.00 C
+ATOM 3258 CD2 TYR C 38 -50.181 20.562 48.186 1.00 40.00 C
+ATOM 3259 CE1 TYR C 38 -47.730 21.838 47.948 1.00 40.00 C
+ATOM 3260 CE2 TYR C 38 -49.126 19.900 47.591 1.00 40.00 C
+ATOM 3261 CZ TYR C 38 -47.910 20.534 47.473 1.00 40.00 C
+ATOM 3262 OH TYR C 38 -46.890 19.834 46.880 1.00 40.00 O
+ATOM 3263 N VAL C 39 -51.518 23.153 45.981 1.00 40.00 N
+ATOM 3264 CA VAL C 39 -51.703 22.445 44.727 1.00 40.00 C
+ATOM 3265 C VAL C 39 -50.671 21.317 44.676 1.00 40.00 C
+ATOM 3266 O VAL C 39 -49.466 21.579 44.682 1.00 40.00 O
+ATOM 3267 CB VAL C 39 -51.642 23.387 43.507 1.00 40.00 C
+ATOM 3268 CG1 VAL C 39 -51.728 22.588 42.217 1.00 40.00 C
+ATOM 3269 CG2 VAL C 39 -52.789 24.387 43.566 1.00 40.00 C
+ATOM 3270 N GLY C 40 -51.158 20.072 44.676 1.00 40.00 N
+ATOM 3271 CA GLY C 40 -50.309 18.876 44.669 1.00 40.00 C
+ATOM 3272 C GLY C 40 -50.352 18.208 43.322 1.00 40.00 C
+ATOM 3273 O GLY C 40 -50.801 18.814 42.354 1.00 40.00 O
+ATOM 3274 N ARG C 41 -49.896 16.960 43.246 1.00 40.00 N
+ATOM 3275 CA ARG C 41 -49.868 16.271 41.959 1.00 40.00 C
+ATOM 3276 C ARG C 41 -50.191 14.784 42.022 1.00 40.00 C
+ATOM 3277 O ARG C 41 -49.794 14.104 42.959 1.00 40.00 O
+ATOM 3278 CB ARG C 41 -48.532 16.494 41.263 1.00 40.00 C
+ATOM 3279 CG ARG C 41 -48.652 16.407 39.755 1.00 40.00 C
+ATOM 3280 CD ARG C 41 -47.429 16.973 39.051 1.00 40.00 C
+ATOM 3281 NE ARG C 41 -47.310 18.440 39.146 1.00 40.00 N
+ATOM 3282 CZ ARG C 41 -47.772 19.321 38.248 1.00 40.00 C
+ATOM 3283 NH1 ARG C 41 -48.427 18.913 37.150 1.00 40.00 N
+ATOM 3284 NH2 ARG C 41 -47.580 20.626 38.460 1.00 40.00 N
+ATOM 3285 N CYS C 42 -50.914 14.299 41.009 1.00 40.00 N
+ATOM 3286 CA CYS C 42 -51.350 12.902 40.924 1.00 40.00 C
+ATOM 3287 C CYS C 42 -50.240 12.006 40.423 1.00 40.00 C
+ATOM 3288 O CYS C 42 -49.746 12.182 39.315 1.00 40.00 O
+ATOM 3289 CB CYS C 42 -52.570 12.755 40.005 1.00 40.00 C
+ATOM 3290 SG CYS C 42 -53.073 11.032 39.708 1.00 40.00 S
+ATOM 3291 N LEU C 43 -49.873 11.033 41.247 1.00 40.00 N
+ATOM 3292 CA LEU C 43 -48.792 10.095 40.936 1.00 40.00 C
+ATOM 3293 C LEU C 43 -49.354 8.759 40.439 1.00 40.00 C
+ATOM 3294 O LEU C 43 -49.005 8.280 39.358 1.00 40.00 O
+ATOM 3295 CB LEU C 43 -47.910 9.874 42.175 1.00 40.00 C
+ATOM 3296 CG LEU C 43 -46.896 10.914 42.686 1.00 40.00 C
+ATOM 3297 CD1 LEU C 43 -47.278 12.360 42.380 1.00 40.00 C
+ATOM 3298 CD2 LEU C 43 -46.657 10.743 44.181 1.00 40.00 C
+ATOM 3299 N LEU C 44 -50.224 8.165 41.248 1.00 40.00 N
+ATOM 3300 CA LEU C 44 -50.913 6.941 40.886 1.00 40.00 C
+ATOM 3301 C LEU C 44 -52.397 7.185 40.790 1.00 40.00 C
+ATOM 3302 O LEU C 44 -52.868 8.298 41.039 1.00 40.00 O
+ATOM 3303 CB LEU C 44 -50.658 5.850 41.916 1.00 40.00 C
+ATOM 3304 CG LEU C 44 -49.261 5.247 41.897 1.00 40.00 C
+ATOM 3305 CD1 LEU C 44 -49.255 3.977 42.730 1.00 40.00 C
+ATOM 3306 CD2 LEU C 44 -48.778 4.963 40.477 1.00 40.00 C
+ATOM 3307 N ASN C 45 -53.124 6.132 40.422 1.00 40.00 N
+ATOM 3308 CA ASN C 45 -54.578 6.148 40.358 1.00 40.00 C
+ATOM 3309 C ASN C 45 -55.012 4.834 39.750 1.00 40.00 C
+ATOM 3310 O ASN C 45 -55.078 4.690 38.538 1.00 40.00 O
+ATOM 3311 CB ASN C 45 -55.104 7.336 39.533 1.00 40.00 C
+ATOM 3312 CG ASN C 45 -56.578 7.615 39.779 1.00 40.00 C
+ATOM 3313 OD1 ASN C 45 -57.219 6.952 40.592 1.00 40.00 O
+ATOM 3314 ND2 ASN C 45 -57.123 8.600 39.073 1.00 40.00 N
+ATOM 3315 N THR C 46 -55.294 3.864 40.601 1.00 40.00 N
+ATOM 3316 CA THR C 46 -55.593 2.515 40.144 1.00 40.00 C
+ATOM 3317 C THR C 46 -56.983 2.131 40.626 1.00 40.00 C
+ATOM 3318 O THR C 46 -57.333 2.381 41.780 1.00 40.00 O
+ATOM 3319 CB THR C 46 -54.528 1.527 40.669 1.00 40.00 C
+ATOM 3320 OG1 THR C 46 -53.223 2.059 40.388 1.00 40.00 O
+ATOM 3321 CG2 THR C 46 -54.675 0.119 40.056 1.00 40.00 C
+ATOM 3322 N LYS C 47 -57.795 1.564 39.737 1.00 40.00 N
+ATOM 3323 CA LYS C 47 -59.039 0.956 40.177 1.00 40.00 C
+ATOM 3324 C LYS C 47 -58.617 -0.238 41.015 1.00 40.00 C
+ATOM 3325 O LYS C 47 -57.631 -0.918 40.696 1.00 40.00 O
+ATOM 3326 CB LYS C 47 -59.940 0.530 39.007 1.00 40.00 C
+ATOM 3327 CG LYS C 47 -61.374 0.227 39.436 1.00 40.00 C
+ATOM 3328 CD LYS C 47 -62.341 0.149 38.271 1.00 40.00 C
+ATOM 3329 CE LYS C 47 -62.826 -1.264 38.039 1.00 40.00 C
+ATOM 3330 NZ LYS C 47 -64.128 -1.269 37.325 1.00 40.00 N
+ATOM 3331 N ILE C 48 -59.338 -0.460 42.108 1.00 40.00 N
+ATOM 3332 CA ILE C 48 -59.023 -1.561 43.020 1.00 40.00 C
+ATOM 3333 C ILE C 48 -60.203 -2.518 43.215 1.00 40.00 C
+ATOM 3334 O ILE C 48 -60.050 -3.601 43.803 1.00 40.00 O
+ATOM 3335 CB ILE C 48 -58.502 -1.044 44.370 1.00 40.00 C
+ATOM 3336 CG1 ILE C 48 -59.407 0.069 44.891 1.00 40.00 C
+ATOM 3337 CG2 ILE C 48 -57.076 -0.532 44.219 1.00 40.00 C
+ATOM 3338 CD1 ILE C 48 -59.380 0.222 46.389 1.00 40.00 C
+ATOM 3339 N THR C 49 -61.371 -2.098 42.721 1.00 40.00 N
+ATOM 3340 CA THR C 49 -62.527 -2.976 42.558 1.00 40.00 C
+ATOM 3341 C THR C 49 -62.402 -3.763 41.235 1.00 40.00 C
+ATOM 3342 O THR C 49 -61.833 -3.247 40.257 1.00 40.00 O
+ATOM 3343 CB THR C 49 -63.866 -2.182 42.573 1.00 40.00 C
+ATOM 3344 OG1 THR C 49 -63.812 -1.096 41.640 1.00 40.00 O
+ATOM 3345 CG2 THR C 49 -64.174 -1.638 43.948 1.00 40.00 C
+ATOM 3346 N GLY C 50 -62.919 -5.003 41.216 1.00 40.00 N
+ATOM 3347 CA GLY C 50 -63.077 -5.809 39.977 1.00 40.00 C
+ATOM 3348 C GLY C 50 -63.970 -5.142 38.920 1.00 40.00 C
+ATOM 3349 O GLY C 50 -64.459 -4.019 39.126 1.00 40.00 O
+ATOM 3350 N ASP C 51 -64.192 -5.803 37.782 1.00 40.00 N
+ATOM 3351 CA ASP C 51 -64.990 -5.176 36.707 1.00 40.00 C
+ATOM 3352 C ASP C 51 -66.493 -5.389 36.854 1.00 40.00 C
+ATOM 3353 O ASP C 51 -67.312 -4.576 36.396 1.00 40.00 O
+ATOM 3354 CB ASP C 51 -64.514 -5.649 35.347 1.00 40.00 C
+ATOM 3355 CG ASP C 51 -63.217 -5.007 34.953 1.00 40.00 C
+ATOM 3356 OD1 ASP C 51 -62.207 -5.738 34.834 1.00 40.00 O
+ATOM 3357 OD2 ASP C 51 -63.207 -3.767 34.794 1.00 40.00 O
+ATOM 3358 N ASP C 52 -66.822 -6.505 37.498 1.00 40.00 N
+ATOM 3359 CA ASP C 52 -68.181 -6.864 37.878 1.00 40.00 C
+ATOM 3360 C ASP C 52 -68.681 -6.034 39.079 1.00 40.00 C
+ATOM 3361 O ASP C 52 -69.885 -5.939 39.315 1.00 40.00 O
+ATOM 3362 CB ASP C 52 -68.256 -8.376 38.168 1.00 40.00 C
+ATOM 3363 CG ASP C 52 -67.097 -8.880 39.031 1.00 40.00 C
+ATOM 3364 OD1 ASP C 52 -65.933 -8.456 38.837 1.00 40.00 O
+ATOM 3365 OD2 ASP C 52 -67.356 -9.724 39.903 1.00 40.00 O
+ATOM 3366 N ALA C 53 -67.753 -5.421 39.816 1.00 40.00 N
+ATOM 3367 CA ALA C 53 -68.073 -4.624 41.002 1.00 40.00 C
+ATOM 3368 C ALA C 53 -69.131 -3.569 40.735 1.00 40.00 C
+ATOM 3369 O ALA C 53 -69.051 -2.865 39.731 1.00 40.00 O
+ATOM 3370 CB ALA C 53 -66.820 -3.966 41.551 1.00 40.00 C
+ATOM 3371 N PRO C 54 -70.120 -3.458 41.643 1.00 40.00 N
+ATOM 3372 CA PRO C 54 -71.227 -2.494 41.565 1.00 40.00 C
+ATOM 3373 C PRO C 54 -70.863 -0.994 41.458 1.00 40.00 C
+ATOM 3374 O PRO C 54 -71.552 -0.237 40.772 1.00 40.00 O
+ATOM 3375 CB PRO C 54 -72.017 -2.754 42.867 1.00 40.00 C
+ATOM 3376 CG PRO C 54 -71.120 -3.569 43.734 1.00 40.00 C
+ATOM 3377 CD PRO C 54 -70.301 -4.382 42.777 1.00 40.00 C
+ATOM 3378 N GLY C 55 -69.806 -0.558 42.122 1.00 40.00 N
+ATOM 3379 CA GLY C 55 -69.601 0.876 42.267 1.00 40.00 C
+ATOM 3380 C GLY C 55 -68.351 1.481 41.663 1.00 40.00 C
+ATOM 3381 O GLY C 55 -68.365 2.660 41.300 1.00 40.00 O
+ATOM 3382 N GLU C 56 -67.278 0.686 41.571 1.00 40.00 N
+ATOM 3383 CA GLU C 56 -65.955 1.160 41.138 1.00 40.00 C
+ATOM 3384 C GLU C 56 -65.262 2.108 42.165 1.00 40.00 C
+ATOM 3385 O GLU C 56 -65.774 3.196 42.494 1.00 40.00 O
+ATOM 3386 CB GLU C 56 -66.038 1.778 39.738 1.00 40.00 C
+ATOM 3387 CG GLU C 56 -64.734 2.341 39.221 1.00 40.00 C
+ATOM 3388 CD GLU C 56 -64.866 2.912 37.832 1.00 40.00 C
+ATOM 3389 OE1 GLU C 56 -65.247 2.158 36.920 1.00 40.00 O
+ATOM 3390 OE2 GLU C 56 -64.581 4.108 37.647 1.00 40.00 O
+ATOM 3391 N THR C 57 -64.094 1.674 42.658 1.00 40.00 N
+ATOM 3392 CA THR C 57 -63.320 2.411 43.667 1.00 40.00 C
+ATOM 3393 C THR C 57 -61.814 2.373 43.371 1.00 40.00 C
+ATOM 3394 O THR C 57 -61.236 1.300 43.158 1.00 40.00 O
+ATOM 3395 CB THR C 57 -63.618 1.863 45.070 1.00 40.00 C
+ATOM 3396 OG1 THR C 57 -64.954 2.224 45.433 1.00 40.00 O
+ATOM 3397 CG2 THR C 57 -62.652 2.415 46.100 1.00 40.00 C
+ATOM 3398 N TRP C 58 -61.198 3.558 43.371 1.00 40.00 N
+ATOM 3399 CA TRP C 58 -59.799 3.748 42.956 1.00 40.00 C
+ATOM 3400 C TRP C 58 -58.870 4.143 44.073 1.00 40.00 C
+ATOM 3401 O TRP C 58 -59.270 4.879 44.979 1.00 40.00 O
+ATOM 3402 CB TRP C 58 -59.730 4.848 41.914 1.00 40.00 C
+ATOM 3403 CG TRP C 58 -60.412 4.540 40.613 1.00 40.00 C
+ATOM 3404 CD1 TRP C 58 -61.772 4.392 40.375 1.00 40.00 C
+ATOM 3405 CD2 TRP C 58 -59.776 4.366 39.311 1.00 40.00 C
+ATOM 3406 NE1 TRP C 58 -62.006 4.137 39.054 1.00 40.00 N
+ATOM 3407 CE2 TRP C 58 -60.852 4.107 38.362 1.00 40.00 C
+ATOM 3408 CE3 TRP C 58 -58.469 4.400 38.854 1.00 40.00 C
+ATOM 3409 CZ2 TRP C 58 -60.605 3.887 37.019 1.00 40.00 C
+ATOM 3410 CZ3 TRP C 58 -58.230 4.172 37.499 1.00 40.00 C
+ATOM 3411 CH2 TRP C 58 -59.273 3.924 36.605 1.00 40.00 C
+ATOM 3412 N HIS C 59 -57.613 3.699 44.002 1.00 40.00 N
+ATOM 3413 CA HIS C 59 -56.595 4.095 44.987 1.00 40.00 C
+ATOM 3414 C HIS C 59 -55.609 5.053 44.395 1.00 40.00 C
+ATOM 3415 O HIS C 59 -54.871 4.695 43.484 1.00 40.00 O
+ATOM 3416 CB HIS C 59 -55.866 2.879 45.546 1.00 40.00 C
+ATOM 3417 CG HIS C 59 -54.840 3.214 46.605 1.00 40.00 C
+ATOM 3418 ND1 HIS C 59 -55.172 3.478 47.882 1.00 40.00 N
+ATOM 3419 CD2 HIS C 59 -53.455 3.315 46.534 1.00 40.00 C
+ATOM 3420 CE1 HIS C 59 -54.057 3.736 48.594 1.00 40.00 C
+ATOM 3421 NE2 HIS C 59 -53.007 3.636 47.769 1.00 40.00 N
+ATOM 3422 N MET C 60 -55.572 6.280 44.913 1.00 40.00 N
+ATOM 3423 CA MET C 60 -54.713 7.318 44.342 1.00 40.00 C
+ATOM 3424 C MET C 60 -53.772 7.939 45.354 1.00 40.00 C
+ATOM 3425 O MET C 60 -54.111 8.080 46.532 1.00 40.00 O
+ATOM 3426 CB MET C 60 -55.554 8.405 43.717 1.00 40.00 C
+ATOM 3427 CG MET C 60 -56.531 8.993 44.697 1.00 40.00 C
+ATOM 3428 SD MET C 60 -57.842 9.607 43.678 1.00 40.00 S
+ATOM 3429 CE MET C 60 -58.815 8.132 43.402 1.00 40.00 C
+ATOM 3430 N VAL C 61 -52.595 8.321 44.864 1.00 40.00 N
+ATOM 3431 CA VAL C 61 -51.534 8.888 45.687 1.00 40.00 C
+ATOM 3432 C VAL C 61 -51.145 10.281 45.154 1.00 40.00 C
+ATOM 3433 O VAL C 61 -51.163 10.504 43.941 1.00 40.00 O
+ATOM 3434 CB VAL C 61 -50.304 7.956 45.714 1.00 40.00 C
+ATOM 3435 CG1 VAL C 61 -49.547 8.119 47.015 1.00 40.00 C
+ATOM 3436 CG2 VAL C 61 -50.715 6.501 45.572 1.00 40.00 C
+ATOM 3437 N PHE C 62 -50.816 11.216 46.056 1.00 40.00 N
+ATOM 3438 CA PHE C 62 -50.438 12.591 45.672 1.00 40.00 C
+ATOM 3439 C PHE C 62 -49.126 13.094 46.276 1.00 40.00 C
+ATOM 3440 O PHE C 62 -48.780 12.771 47.410 1.00 40.00 O
+ATOM 3441 CB PHE C 62 -51.535 13.599 46.026 1.00 40.00 C
+ATOM 3442 CG PHE C 62 -52.921 13.194 45.602 1.00 40.00 C
+ATOM 3443 CD1 PHE C 62 -53.204 12.859 44.283 1.00 40.00 C
+ATOM 3444 CD2 PHE C 62 -53.964 13.194 46.525 1.00 40.00 C
+ATOM 3445 CE1 PHE C 62 -54.491 12.497 43.906 1.00 40.00 C
+ATOM 3446 CE2 PHE C 62 -55.254 12.843 46.151 1.00 40.00 C
+ATOM 3447 CZ PHE C 62 -55.518 12.494 44.839 1.00 40.00 C
+ATOM 3448 N SER C 63 -48.419 13.917 45.504 1.00 40.00 N
+ATOM 3449 CA SER C 63 -47.179 14.549 45.947 1.00 40.00 C
+ATOM 3450 C SER C 63 -47.503 15.738 46.828 1.00 40.00 C
+ATOM 3451 O SER C 63 -48.339 16.579 46.477 1.00 40.00 O
+ATOM 3452 CB SER C 63 -46.331 15.000 44.756 1.00 40.00 C
+ATOM 3453 OG SER C 63 -47.059 15.878 43.916 1.00 40.00 O
+ATOM 3454 N THR C 64 -46.819 15.805 47.965 1.00 40.00 N
+ATOM 3455 CA THR C 64 -47.136 16.761 49.014 1.00 40.00 C
+ATOM 3456 C THR C 64 -45.948 17.648 49.338 1.00 40.00 C
+ATOM 3457 O THR C 64 -46.102 18.696 49.950 1.00 40.00 O
+ATOM 3458 CB THR C 64 -47.523 16.027 50.307 1.00 40.00 C
+ATOM 3459 OG1 THR C 64 -46.363 15.396 50.854 1.00 40.00 O
+ATOM 3460 CG2 THR C 64 -48.559 14.966 50.029 1.00 40.00 C
+ATOM 3461 N GLU C 65 -44.761 17.207 48.933 1.00 40.00 N
+ATOM 3462 CA GLU C 65 -43.499 17.854 49.303 1.00 40.00 C
+ATOM 3463 C GLU C 65 -43.231 17.805 50.818 1.00 40.00 C
+ATOM 3464 O GLU C 65 -42.460 18.612 51.354 1.00 40.00 O
+ATOM 3465 CB GLU C 65 -43.449 19.306 48.814 1.00 40.00 C
+ATOM 3466 CG GLU C 65 -43.635 19.518 47.320 1.00 40.00 C
+ATOM 3467 CD GLU C 65 -43.610 20.998 46.938 1.00 40.00 C
+ATOM 3468 OE1 GLU C 65 -42.513 21.599 46.914 1.00 40.00 O
+ATOM 3469 OE2 GLU C 65 -44.687 21.571 46.660 1.00 40.00 O
+ATOM 3470 N GLY C 66 -43.861 16.850 51.503 1.00 40.00 N
+ATOM 3471 CA GLY C 66 -43.715 16.711 52.951 1.00 40.00 C
+ATOM 3472 C GLY C 66 -44.311 17.906 53.655 1.00 40.00 C
+ATOM 3473 O GLY C 66 -44.203 18.040 54.877 1.00 40.00 O
+ATOM 3474 N LYS C 67 -44.951 18.768 52.864 1.00 40.00 N
+ATOM 3475 CA LYS C 67 -45.543 20.032 53.337 1.00 40.00 C
+ATOM 3476 C LYS C 67 -46.858 19.856 54.118 1.00 40.00 C
+ATOM 3477 O LYS C 67 -47.478 20.842 54.532 1.00 40.00 O
+ATOM 3478 CB LYS C 67 -45.752 21.023 52.167 1.00 40.00 C
+ATOM 3479 CG LYS C 67 -44.493 21.752 51.715 1.00 40.00 C
+ATOM 3480 CD LYS C 67 -44.784 22.851 50.705 1.00 40.00 C
+ATOM 3481 CE LYS C 67 -43.497 23.583 50.353 1.00 40.00 C
+ATOM 3482 NZ LYS C 67 -43.700 24.661 49.351 1.00 40.00 N
+ATOM 3483 N ILE C 68 -47.281 18.608 54.305 1.00 40.00 N
+ATOM 3484 CA ILE C 68 -48.496 18.318 55.042 1.00 40.00 C
+ATOM 3485 C ILE C 68 -48.251 17.161 56.003 1.00 40.00 C
+ATOM 3486 O ILE C 68 -48.615 16.029 55.700 1.00 40.00 O
+ATOM 3487 CB ILE C 68 -49.655 18.004 54.089 1.00 40.00 C
+ATOM 3488 CG1 ILE C 68 -49.877 19.194 53.156 1.00 40.00 C
+ATOM 3489 CG2 ILE C 68 -50.904 17.700 54.890 1.00 40.00 C
+ATOM 3490 CD1 ILE C 68 -50.796 18.942 51.986 1.00 40.00 C
+ATOM 3491 N PRO C 69 -47.626 17.443 57.168 1.00 40.00 N
+ATOM 3492 CA PRO C 69 -47.273 16.400 58.136 1.00 40.00 C
+ATOM 3493 C PRO C 69 -48.516 15.832 58.800 1.00 40.00 C
+ATOM 3494 O PRO C 69 -48.785 16.111 59.972 1.00 40.00 O
+ATOM 3495 CB PRO C 69 -46.394 17.138 59.157 1.00 40.00 C
+ATOM 3496 CG PRO C 69 -46.870 18.544 59.101 1.00 40.00 C
+ATOM 3497 CD PRO C 69 -47.282 18.788 57.669 1.00 40.00 C
+ATOM 3498 N TYR C 70 -49.266 15.044 58.034 1.00 40.00 N
+ATOM 3499 CA TYR C 70 -50.494 14.444 58.528 1.00 40.00 C
+ATOM 3500 C TYR C 70 -50.218 13.312 59.482 1.00 40.00 C
+ATOM 3501 O TYR C 70 -49.094 12.825 59.593 1.00 40.00 O
+ATOM 3502 CB TYR C 70 -51.425 13.985 57.390 1.00 40.00 C
+ATOM 3503 CG TYR C 70 -50.918 12.876 56.477 1.00 40.00 C
+ATOM 3504 CD1 TYR C 70 -51.317 11.556 56.657 1.00 40.00 C
+ATOM 3505 CD2 TYR C 70 -50.083 13.162 55.396 1.00 40.00 C
+ATOM 3506 CE1 TYR C 70 -50.873 10.550 55.809 1.00 40.00 C
+ATOM 3507 CE2 TYR C 70 -49.636 12.163 54.543 1.00 40.00 C
+ATOM 3508 CZ TYR C 70 -50.038 10.865 54.755 1.00 40.00 C
+ATOM 3509 OH TYR C 70 -49.591 9.887 53.909 1.00 40.00 O
+ATOM 3510 N ARG C 71 -51.261 12.908 60.181 1.00 40.00 N
+ATOM 3511 CA ARG C 71 -51.132 11.818 61.096 1.00 40.00 C
+ATOM 3512 C ARG C 71 -52.317 10.864 60.965 1.00 40.00 C
+ATOM 3513 O ARG C 71 -53.437 11.260 60.625 1.00 40.00 O
+ATOM 3514 CB ARG C 71 -50.921 12.342 62.520 1.00 40.00 C
+ATOM 3515 CG ARG C 71 -49.958 11.516 63.371 1.00 40.00 C
+ATOM 3516 CD ARG C 71 -48.494 11.578 62.915 1.00 40.00 C
+ATOM 3517 NE ARG C 71 -47.780 12.796 63.329 1.00 40.00 N
+ATOM 3518 CZ ARG C 71 -47.215 13.002 64.528 1.00 40.00 C
+ATOM 3519 NH1 ARG C 71 -47.280 12.081 65.489 1.00 40.00 N
+ATOM 3520 NH2 ARG C 71 -46.588 14.152 64.782 1.00 40.00 N
+ATOM 3521 N GLU C 72 -52.018 9.597 61.223 1.00 40.00 N
+ATOM 3522 CA GLU C 72 -52.904 8.477 60.988 1.00 40.00 C
+ATOM 3523 C GLU C 72 -54.313 8.727 61.481 1.00 40.00 C
+ATOM 3524 O GLU C 72 -54.547 8.848 62.683 1.00 40.00 O
+ATOM 3525 CB GLU C 72 -52.336 7.229 61.662 1.00 40.00 C
+ATOM 3526 CG GLU C 72 -51.081 6.668 61.002 1.00 40.00 C
+ATOM 3527 CD GLU C 72 -49.790 7.381 61.402 1.00 40.00 C
+ATOM 3528 OE1 GLU C 72 -49.816 8.160 62.383 1.00 40.00 O
+ATOM 3529 OE2 GLU C 72 -48.737 7.150 60.744 1.00 40.00 O
+ATOM 3530 N GLY C 73 -55.247 8.810 60.540 1.00 40.00 N
+ATOM 3531 CA GLY C 73 -56.665 8.884 60.870 1.00 40.00 C
+ATOM 3532 C GLY C 73 -57.318 10.129 60.329 1.00 40.00 C
+ATOM 3533 O GLY C 73 -58.551 10.237 60.251 1.00 40.00 O
+ATOM 3534 N GLN C 74 -56.483 11.078 59.948 1.00 40.00 N
+ATOM 3535 CA GLN C 74 -56.991 12.319 59.419 1.00 40.00 C
+ATOM 3536 C GLN C 74 -57.663 12.097 58.074 1.00 40.00 C
+ATOM 3537 O GLN C 74 -57.856 10.964 57.632 1.00 40.00 O
+ATOM 3538 CB GLN C 74 -55.884 13.362 59.355 1.00 40.00 C
+ATOM 3539 CG GLN C 74 -55.479 13.831 60.738 1.00 40.00 C
+ATOM 3540 CD GLN C 74 -54.476 14.950 60.695 1.00 40.00 C
+ATOM 3541 OE1 GLN C 74 -53.327 14.750 60.299 1.00 40.00 O
+ATOM 3542 NE2 GLN C 74 -54.897 16.139 61.118 1.00 40.00 N
+ATOM 3543 N SER C 75 -58.048 13.193 57.449 1.00 40.00 N
+ATOM 3544 CA SER C 75 -58.818 13.155 56.237 1.00 40.00 C
+ATOM 3545 C SER C 75 -58.419 14.432 55.534 1.00 40.00 C
+ATOM 3546 O SER C 75 -57.978 15.372 56.194 1.00 40.00 O
+ATOM 3547 CB SER C 75 -60.306 13.178 56.585 1.00 40.00 C
+ATOM 3548 OG SER C 75 -60.566 12.573 57.851 1.00 40.00 O
+ATOM 3549 N ILE C 76 -58.530 14.490 54.210 1.00 40.00 N
+ATOM 3550 CA ILE C 76 -58.253 15.771 53.533 1.00 40.00 C
+ATOM 3551 C ILE C 76 -59.353 16.315 52.630 1.00 40.00 C
+ATOM 3552 O ILE C 76 -60.336 15.631 52.310 1.00 40.00 O
+ATOM 3553 CB ILE C 76 -56.908 15.813 52.770 1.00 40.00 C
+ATOM 3554 CG1 ILE C 76 -56.843 14.726 51.688 1.00 40.00 C
+ATOM 3555 CG2 ILE C 76 -55.745 15.729 53.741 1.00 40.00 C
+ATOM 3556 CD1 ILE C 76 -55.962 15.094 50.504 1.00 40.00 C
+ATOM 3557 N GLY C 77 -59.153 17.562 52.224 1.00 40.00 N
+ATOM 3558 CA GLY C 77 -60.093 18.231 51.372 1.00 40.00 C
+ATOM 3559 C GLY C 77 -59.632 18.239 49.935 1.00 40.00 C
+ATOM 3560 O GLY C 77 -58.426 18.292 49.641 1.00 40.00 O
+ATOM 3561 N VAL C 78 -60.621 18.173 49.045 1.00 40.00 N
+ATOM 3562 CA VAL C 78 -60.398 18.236 47.615 1.00 40.00 C
+ATOM 3563 C VAL C 78 -61.353 19.244 46.996 1.00 40.00 C
+ATOM 3564 O VAL C 78 -62.579 19.092 47.053 1.00 40.00 O
+ATOM 3565 CB VAL C 78 -60.586 16.858 46.951 1.00 40.00 C
+ATOM 3566 CG1 VAL C 78 -60.445 16.967 45.443 1.00 40.00 C
+ATOM 3567 CG2 VAL C 78 -59.570 15.861 47.484 1.00 40.00 C
+ATOM 3568 N ILE C 79 -60.766 20.288 46.428 1.00 40.00 N
+ATOM 3569 CA ILE C 79 -61.492 21.203 45.568 1.00 40.00 C
+ATOM 3570 C ILE C 79 -61.450 20.629 44.140 1.00 40.00 C
+ATOM 3571 O ILE C 79 -60.380 20.617 43.487 1.00 40.00 O
+ATOM 3572 CB ILE C 79 -60.910 22.641 45.631 1.00 40.00 C
+ATOM 3573 CG1 ILE C 79 -60.945 23.163 47.083 1.00 40.00 C
+ATOM 3574 CG2 ILE C 79 -61.654 23.580 44.671 1.00 40.00 C
+ATOM 3575 CD1 ILE C 79 -59.961 24.277 47.402 1.00 40.00 C
+ATOM 3576 N ALA C 80 -62.615 20.126 43.691 1.00 40.00 N
+ATOM 3577 CA ALA C 80 -62.832 19.603 42.320 1.00 40.00 C
+ATOM 3578 C ALA C 80 -62.685 20.693 41.249 1.00 40.00 C
+ATOM 3579 O ALA C 80 -63.093 21.850 41.454 1.00 40.00 O
+ATOM 3580 CB ALA C 80 -64.200 18.933 42.211 1.00 40.00 C
+ATOM 3581 N ASP C 81 -62.102 20.329 40.108 1.00 40.00 N
+ATOM 3582 CA ASP C 81 -61.849 21.309 39.051 1.00 40.00 C
+ATOM 3583 C ASP C 81 -63.120 21.725 38.320 1.00 40.00 C
+ATOM 3584 O ASP C 81 -64.010 20.902 38.088 1.00 40.00 O
+ATOM 3585 CB ASP C 81 -60.772 20.818 38.084 1.00 40.00 C
+ATOM 3586 CG ASP C 81 -59.353 21.053 38.614 1.00 40.00 C
+ATOM 3587 OD1 ASP C 81 -59.174 21.320 39.834 1.00 40.00 O
+ATOM 3588 OD2 ASP C 81 -58.406 20.971 37.799 1.00 40.00 O
+ATOM 3589 N GLY C 82 -63.194 23.012 37.981 1.00 40.00 N
+ATOM 3590 CA GLY C 82 -64.398 23.599 37.405 1.00 40.00 C
+ATOM 3591 C GLY C 82 -65.100 24.521 38.387 1.00 40.00 C
+ATOM 3592 O GLY C 82 -64.574 24.795 39.482 1.00 40.00 O
+ATOM 3593 N VAL C 83 -66.285 25.001 37.990 1.00 40.00 N
+ATOM 3594 CA VAL C 83 -67.094 25.921 38.813 1.00 40.00 C
+ATOM 3595 C VAL C 83 -68.561 25.462 38.916 1.00 40.00 C
+ATOM 3596 O VAL C 83 -69.039 24.665 38.088 1.00 40.00 O
+ATOM 3597 CB VAL C 83 -66.981 27.400 38.333 1.00 40.00 C
+ATOM 3598 CG1 VAL C 83 -65.600 27.987 38.654 1.00 40.00 C
+ATOM 3599 CG2 VAL C 83 -67.299 27.525 36.846 1.00 40.00 C
+ATOM 3600 N ASP C 84 -69.255 25.933 39.952 1.00 40.00 N
+ATOM 3601 CA ASP C 84 -70.674 25.645 40.106 1.00 40.00 C
+ATOM 3602 C ASP C 84 -71.456 26.538 39.138 1.00 40.00 C
+ATOM 3603 O ASP C 84 -70.844 27.245 38.329 1.00 40.00 O
+ATOM 3604 CB ASP C 84 -71.117 25.852 41.564 1.00 40.00 C
+ATOM 3605 CG ASP C 84 -70.956 27.295 42.043 1.00 40.00 C
+ATOM 3606 OD1 ASP C 84 -71.272 27.574 43.216 1.00 40.00 O
+ATOM 3607 OD2 ASP C 84 -70.523 28.158 41.257 1.00 40.00 O
+ATOM 3608 N LYS C 85 -72.789 26.517 39.221 1.00 40.00 N
+ATOM 3609 CA LYS C 85 -73.635 27.398 38.400 1.00 40.00 C
+ATOM 3610 C LYS C 85 -73.283 28.893 38.501 1.00 40.00 C
+ATOM 3611 O LYS C 85 -73.508 29.639 37.544 1.00 40.00 O
+ATOM 3612 CB LYS C 85 -75.116 27.213 38.735 1.00 40.00 C
+ATOM 3613 CG LYS C 85 -75.462 27.436 40.204 1.00 40.00 C
+ATOM 3614 CD LYS C 85 -76.963 27.503 40.431 1.00 40.00 C
+ATOM 3615 CE LYS C 85 -77.680 26.403 39.669 1.00 40.00 C
+ATOM 3616 NZ LYS C 85 -76.907 25.123 39.643 1.00 40.00 N
+ATOM 3617 N ASN C 86 -72.738 29.321 39.648 1.00 40.00 N
+ATOM 3618 CA ASN C 86 -72.501 30.752 39.942 1.00 40.00 C
+ATOM 3619 C ASN C 86 -71.091 31.275 39.634 1.00 40.00 C
+ATOM 3620 O ASN C 86 -70.720 32.356 40.114 1.00 40.00 O
+ATOM 3621 CB ASN C 86 -72.836 31.067 41.413 1.00 40.00 C
+ATOM 3622 CG ASN C 86 -74.321 30.932 41.738 1.00 40.00 C
+ATOM 3623 OD1 ASN C 86 -74.751 31.265 42.844 1.00 40.00 O
+ATOM 3624 ND2 ASN C 86 -75.109 30.444 40.788 1.00 40.00 N
+ATOM 3625 N GLY C 87 -70.318 30.519 38.845 1.00 40.00 N
+ATOM 3626 CA GLY C 87 -68.917 30.852 38.543 1.00 40.00 C
+ATOM 3627 C GLY C 87 -67.984 30.576 39.714 1.00 40.00 C
+ATOM 3628 O GLY C 87 -66.763 30.802 39.620 1.00 40.00 O
+ATOM 3629 N LYS C 88 -68.571 30.078 40.811 1.00 40.00 N
+ATOM 3630 CA LYS C 88 -67.872 29.807 42.082 1.00 40.00 C
+ATOM 3631 C LYS C 88 -67.287 28.396 42.136 1.00 40.00 C
+ATOM 3632 O LYS C 88 -67.866 27.460 41.548 1.00 40.00 O
+ATOM 3633 CB LYS C 88 -68.820 29.989 43.273 1.00 40.00 C
+ATOM 3634 CG LYS C 88 -69.113 31.431 43.605 1.00 40.00 C
+ATOM 3635 CD LYS C 88 -70.344 31.516 44.478 1.00 40.00 C
+ATOM 3636 CE LYS C 88 -70.882 32.939 44.517 1.00 40.00 C
+ATOM 3637 NZ LYS C 88 -72.018 33.029 45.479 1.00 40.00 N
+ATOM 3638 N PRO C 89 -66.157 28.230 42.872 1.00 40.00 N
+ATOM 3639 CA PRO C 89 -65.567 26.886 43.012 1.00 40.00 C
+ATOM 3640 C PRO C 89 -66.623 25.859 43.460 1.00 40.00 C
+ATOM 3641 O PRO C 89 -67.716 26.242 43.902 1.00 40.00 O
+ATOM 3642 CB PRO C 89 -64.494 27.069 44.109 1.00 40.00 C
+ATOM 3643 CG PRO C 89 -64.242 28.541 44.206 1.00 40.00 C
+ATOM 3644 CD PRO C 89 -65.473 29.246 43.709 1.00 40.00 C
+ATOM 3645 N HIS C 90 -66.319 24.569 43.332 1.00 40.00 N
+ATOM 3646 CA HIS C 90 -67.167 23.541 43.954 1.00 40.00 C
+ATOM 3647 C HIS C 90 -66.859 23.514 45.433 1.00 40.00 C
+ATOM 3648 O HIS C 90 -65.870 24.140 45.869 1.00 40.00 O
+ATOM 3649 CB HIS C 90 -66.963 22.167 43.298 1.00 40.00 C
+ATOM 3650 CG HIS C 90 -67.302 22.136 41.812 1.00 40.00 C
+ATOM 3651 ND1 HIS C 90 -68.560 22.339 41.341 1.00 40.00 N
+ATOM 3652 CD2 HIS C 90 -66.492 21.917 40.685 1.00 40.00 C
+ATOM 3653 CE1 HIS C 90 -68.556 22.259 39.985 1.00 40.00 C
+ATOM 3654 NE2 HIS C 90 -67.291 22.001 39.585 1.00 40.00 N
+ATOM 3655 N LYS C 91 -67.691 22.823 46.225 1.00 40.00 N
+ATOM 3656 CA LYS C 91 -67.492 22.772 47.687 1.00 40.00 C
+ATOM 3657 C LYS C 91 -66.598 21.591 48.136 1.00 40.00 C
+ATOM 3658 O LYS C 91 -66.630 20.505 47.534 1.00 40.00 O
+ATOM 3659 CB LYS C 91 -68.835 22.802 48.440 1.00 40.00 C
+ATOM 3660 CG LYS C 91 -68.801 23.579 49.757 1.00 40.00 C
+ATOM 3661 CD LYS C 91 -69.083 25.064 49.582 1.00 40.00 C
+ATOM 3662 CE LYS C 91 -70.561 25.357 49.794 1.00 40.00 C
+ATOM 3663 NZ LYS C 91 -70.916 26.599 49.069 1.00 40.00 N
+ATOM 3664 N VAL C 92 -65.792 21.842 49.175 1.00 40.00 N
+ATOM 3665 CA VAL C 92 -64.818 20.885 49.728 1.00 40.00 C
+ATOM 3666 C VAL C 92 -65.476 19.538 50.079 1.00 40.00 C
+ATOM 3667 O VAL C 92 -66.387 19.487 50.905 1.00 40.00 O
+ATOM 3668 CB VAL C 92 -64.083 21.500 50.962 1.00 40.00 C
+ATOM 3669 CG1 VAL C 92 -63.308 20.452 51.751 1.00 40.00 C
+ATOM 3670 CG2 VAL C 92 -63.150 22.630 50.535 1.00 40.00 C
+ATOM 3671 N ARG C 93 -65.039 18.461 49.420 1.00 40.00 N
+ATOM 3672 CA ARG C 93 -65.430 17.104 49.822 1.00 40.00 C
+ATOM 3673 C ARG C 93 -64.326 16.477 50.632 1.00 40.00 C
+ATOM 3674 O ARG C 93 -63.135 16.742 50.392 1.00 40.00 O
+ATOM 3675 CB ARG C 93 -65.727 16.205 48.626 1.00 40.00 C
+ATOM 3676 CG ARG C 93 -67.182 16.165 48.220 1.00 40.00 C
+ATOM 3677 CD ARG C 93 -67.582 17.501 47.644 1.00 40.00 C
+ATOM 3678 NE ARG C 93 -68.656 17.371 46.685 1.00 40.00 N
+ATOM 3679 CZ ARG C 93 -69.167 18.391 46.025 1.00 40.00 C
+ATOM 3680 NH1 ARG C 93 -68.691 19.612 46.226 1.00 40.00 N
+ATOM 3681 NH2 ARG C 93 -70.150 18.187 45.168 1.00 40.00 N
+ATOM 3682 N LEU C 94 -64.722 15.628 51.578 1.00 40.00 N
+ATOM 3683 CA LEU C 94 -63.765 15.059 52.502 1.00 40.00 C
+ATOM 3684 C LEU C 94 -63.605 13.577 52.319 1.00 40.00 C
+ATOM 3685 O LEU C 94 -64.557 12.851 52.075 1.00 40.00 O
+ATOM 3686 CB LEU C 94 -64.139 15.378 53.941 1.00 40.00 C
+ATOM 3687 CG LEU C 94 -64.083 16.863 54.308 1.00 40.00 C
+ATOM 3688 CD1 LEU C 94 -64.493 17.025 55.762 1.00 40.00 C
+ATOM 3689 CD2 LEU C 94 -62.714 17.491 54.044 1.00 40.00 C
+ATOM 3690 N TYR C 95 -62.361 13.146 52.421 1.00 40.00 N
+ATOM 3691 CA TYR C 95 -62.038 11.759 52.260 1.00 40.00 C
+ATOM 3692 C TYR C 95 -60.956 11.412 53.240 1.00 40.00 C
+ATOM 3693 O TYR C 95 -59.986 12.149 53.419 1.00 40.00 O
+ATOM 3694 CB TYR C 95 -61.586 11.488 50.831 1.00 40.00 C
+ATOM 3695 CG TYR C 95 -62.625 11.881 49.811 1.00 40.00 C
+ATOM 3696 CD1 TYR C 95 -63.527 10.944 49.333 1.00 40.00 C
+ATOM 3697 CD2 TYR C 95 -62.715 13.198 49.337 1.00 40.00 C
+ATOM 3698 CE1 TYR C 95 -64.477 11.291 48.397 1.00 40.00 C
+ATOM 3699 CE2 TYR C 95 -63.672 13.558 48.410 1.00 40.00 C
+ATOM 3700 CZ TYR C 95 -64.556 12.601 47.953 1.00 40.00 C
+ATOM 3701 OH TYR C 95 -65.507 12.953 47.029 1.00 40.00 O
+ATOM 3702 N SER C 96 -61.153 10.275 53.883 1.00 40.00 N
+ATOM 3703 CA SER C 96 -60.253 9.802 54.908 1.00 40.00 C
+ATOM 3704 C SER C 96 -58.941 9.395 54.280 1.00 40.00 C
+ATOM 3705 O SER C 96 -58.935 8.747 53.235 1.00 40.00 O
+ATOM 3706 CB SER C 96 -60.878 8.598 55.574 1.00 40.00 C
+ATOM 3707 OG SER C 96 -62.283 8.745 55.574 1.00 40.00 O
+ATOM 3708 N ILE C 97 -57.829 9.775 54.914 1.00 40.00 N
+ATOM 3709 CA ILE C 97 -56.496 9.520 54.351 1.00 40.00 C
+ATOM 3710 C ILE C 97 -56.134 8.053 54.457 1.00 40.00 C
+ATOM 3711 O ILE C 97 -56.182 7.454 55.530 1.00 40.00 O
+ATOM 3712 CB ILE C 97 -55.386 10.380 54.989 1.00 40.00 C
+ATOM 3713 CG1 ILE C 97 -55.650 11.866 54.750 1.00 40.00 C
+ATOM 3714 CG2 ILE C 97 -54.026 10.008 54.413 1.00 40.00 C
+ATOM 3715 CD1 ILE C 97 -54.966 12.771 55.754 1.00 40.00 C
+ATOM 3716 N ALA C 98 -55.765 7.496 53.314 1.00 40.00 N
+ATOM 3717 CA ALA C 98 -55.528 6.077 53.180 1.00 40.00 C
+ATOM 3718 C ALA C 98 -54.106 5.704 53.512 1.00 40.00 C
+ATOM 3719 O ALA C 98 -53.882 4.598 53.990 1.00 40.00 O
+ATOM 3720 CB ALA C 98 -55.872 5.614 51.778 1.00 40.00 C
+ATOM 3721 N SER C 99 -53.149 6.605 53.256 1.00 40.00 N
+ATOM 3722 CA SER C 99 -51.732 6.324 53.557 1.00 40.00 C
+ATOM 3723 C SER C 99 -51.344 6.638 54.991 1.00 40.00 C
+ATOM 3724 O SER C 99 -51.957 7.481 55.631 1.00 40.00 O
+ATOM 3725 CB SER C 99 -50.784 7.054 52.601 1.00 40.00 C
+ATOM 3726 OG SER C 99 -51.127 8.418 52.466 1.00 40.00 O
+ATOM 3727 N SER C 100 -50.318 5.948 55.483 1.00 40.00 N
+ATOM 3728 CA SER C 100 -49.759 6.222 56.800 1.00 40.00 C
+ATOM 3729 C SER C 100 -49.026 7.559 56.769 1.00 40.00 C
+ATOM 3730 O SER C 100 -48.942 8.187 55.722 1.00 40.00 O
+ATOM 3731 CB SER C 100 -48.801 5.110 57.231 1.00 40.00 C
+ATOM 3732 OG SER C 100 -47.504 5.324 56.695 1.00 40.00 O
+ATOM 3733 N ALA C 101 -48.488 7.979 57.913 1.00 40.00 N
+ATOM 3734 CA ALA C 101 -47.779 9.251 58.020 1.00 40.00 C
+ATOM 3735 C ALA C 101 -46.694 9.323 56.963 1.00 40.00 C
+ATOM 3736 O ALA C 101 -46.478 10.346 56.295 1.00 40.00 O
+ATOM 3737 CB ALA C 101 -47.171 9.392 59.409 1.00 40.00 C
+ATOM 3738 N ILE C 102 -46.042 8.188 56.798 1.00 40.00 N
+ATOM 3739 CA ILE C 102 -44.836 8.110 56.035 1.00 40.00 C
+ATOM 3740 C ILE C 102 -45.143 8.036 54.563 1.00 40.00 C
+ATOM 3741 O ILE C 102 -44.246 8.141 53.736 1.00 40.00 O
+ATOM 3742 CB ILE C 102 -44.042 6.882 56.452 1.00 40.00 C
+ATOM 3743 CG1 ILE C 102 -44.290 6.571 57.938 1.00 40.00 C
+ATOM 3744 CG2 ILE C 102 -42.571 7.103 56.158 1.00 40.00 C
+ATOM 3745 CD1 ILE C 102 -43.875 7.669 58.909 1.00 40.00 C
+ATOM 3746 N GLY C 103 -46.422 7.868 54.245 1.00 40.00 N
+ATOM 3747 CA GLY C 103 -46.882 7.718 52.859 1.00 40.00 C
+ATOM 3748 C GLY C 103 -46.785 6.282 52.373 1.00 40.00 C
+ATOM 3749 O GLY C 103 -46.257 5.407 53.071 1.00 40.00 O
+ATOM 3750 N ASP C 104 -47.297 6.039 51.172 1.00 40.00 N
+ATOM 3751 CA ASP C 104 -47.193 4.718 50.567 1.00 40.00 C
+ATOM 3752 C ASP C 104 -45.744 4.399 50.178 1.00 40.00 C
+ATOM 3753 O ASP C 104 -45.348 3.231 50.083 1.00 40.00 O
+ATOM 3754 CB ASP C 104 -48.112 4.619 49.341 1.00 40.00 C
+ATOM 3755 CG ASP C 104 -49.583 4.416 49.712 1.00 40.00 C
+ATOM 3756 OD1 ASP C 104 -49.867 3.911 50.824 1.00 40.00 O
+ATOM 3757 OD2 ASP C 104 -50.453 4.747 48.873 1.00 40.00 O
+ATOM 3758 N PHE C 105 -44.954 5.439 49.953 1.00 40.00 N
+ATOM 3759 CA PHE C 105 -43.575 5.224 49.577 1.00 40.00 C
+ATOM 3760 C PHE C 105 -42.676 5.273 50.789 1.00 40.00 C
+ATOM 3761 O PHE C 105 -41.497 4.974 50.686 1.00 40.00 O
+ATOM 3762 CB PHE C 105 -43.137 6.230 48.523 1.00 40.00 C
+ATOM 3763 CG PHE C 105 -44.126 6.389 47.420 1.00 40.00 C
+ATOM 3764 CD1 PHE C 105 -44.842 5.291 46.960 1.00 40.00 C
+ATOM 3765 CD2 PHE C 105 -44.347 7.632 46.840 1.00 40.00 C
+ATOM 3766 CE1 PHE C 105 -45.771 5.429 45.950 1.00 40.00 C
+ATOM 3767 CE2 PHE C 105 -45.274 7.783 45.824 1.00 40.00 C
+ATOM 3768 CZ PHE C 105 -45.986 6.677 45.378 1.00 40.00 C
+ATOM 3769 N GLY C 106 -43.237 5.635 51.938 1.00 40.00 N
+ATOM 3770 CA GLY C 106 -42.481 5.658 53.181 1.00 40.00 C
+ATOM 3771 C GLY C 106 -41.452 6.768 53.249 1.00 40.00 C
+ATOM 3772 O GLY C 106 -40.399 6.608 53.852 1.00 40.00 O
+ATOM 3773 N ASP C 107 -41.757 7.904 52.640 1.00 40.00 N
+ATOM 3774 CA ASP C 107 -40.829 9.024 52.630 1.00 40.00 C
+ATOM 3775 C ASP C 107 -41.482 10.356 53.058 1.00 40.00 C
+ATOM 3776 O ASP C 107 -40.839 11.405 53.023 1.00 40.00 O
+ATOM 3777 CB ASP C 107 -40.213 9.151 51.244 1.00 40.00 C
+ATOM 3778 CG ASP C 107 -41.191 9.674 50.233 1.00 40.00 C
+ATOM 3779 OD1 ASP C 107 -42.376 9.274 50.268 1.00 40.00 O
+ATOM 3780 OD2 ASP C 107 -40.773 10.501 49.407 1.00 40.00 O
+ATOM 3781 N SER C 108 -42.759 10.298 53.444 1.00 40.00 N
+ATOM 3782 CA SER C 108 -43.532 11.439 53.977 1.00 40.00 C
+ATOM 3783 C SER C 108 -43.690 12.642 53.045 1.00 40.00 C
+ATOM 3784 O SER C 108 -43.845 13.766 53.504 1.00 40.00 O
+ATOM 3785 CB SER C 108 -42.980 11.883 55.332 1.00 40.00 C
+ATOM 3786 OG SER C 108 -43.020 10.817 56.257 1.00 40.00 O
+ATOM 3787 N LYS C 109 -43.662 12.392 51.741 1.00 40.00 N
+ATOM 3788 CA LYS C 109 -43.883 13.425 50.728 1.00 40.00 C
+ATOM 3789 C LYS C 109 -45.135 13.069 49.935 1.00 40.00 C
+ATOM 3790 O LYS C 109 -45.340 13.527 48.800 1.00 40.00 O
+ATOM 3791 CB LYS C 109 -42.681 13.506 49.784 1.00 40.00 C
+ATOM 3792 CG LYS C 109 -41.320 13.620 50.467 1.00 40.00 C
+ATOM 3793 CD LYS C 109 -41.206 14.897 51.286 1.00 40.00 C
+ATOM 3794 CE LYS C 109 -39.765 15.283 51.606 1.00 40.00 C
+ATOM 3795 NZ LYS C 109 -39.043 15.920 50.463 1.00 40.00 N
+ATOM 3796 N THR C 110 -45.974 12.253 50.569 1.00 40.00 N
+ATOM 3797 CA THR C 110 -47.022 11.510 49.884 1.00 40.00 C
+ATOM 3798 C THR C 110 -48.230 11.251 50.766 1.00 40.00 C
+ATOM 3799 O THR C 110 -48.094 10.810 51.911 1.00 40.00 O
+ATOM 3800 CB THR C 110 -46.525 10.123 49.445 1.00 40.00 C
+ATOM 3801 OG1 THR C 110 -46.372 9.284 50.597 1.00 40.00 O
+ATOM 3802 CG2 THR C 110 -45.210 10.232 48.691 1.00 40.00 C
+ATOM 3803 N VAL C 111 -49.406 11.501 50.195 1.00 40.00 N
+ATOM 3804 CA VAL C 111 -50.676 11.213 50.834 1.00 40.00 C
+ATOM 3805 C VAL C 111 -51.491 10.294 49.945 1.00 40.00 C
+ATOM 3806 O VAL C 111 -51.388 10.370 48.723 1.00 40.00 O
+ATOM 3807 CB VAL C 111 -51.476 12.494 51.033 1.00 40.00 C
+ATOM 3808 CG1 VAL C 111 -51.933 13.046 49.688 1.00 40.00 C
+ATOM 3809 CG2 VAL C 111 -52.661 12.227 51.943 1.00 40.00 C
+ATOM 3810 N SER C 112 -52.319 9.451 50.551 1.00 40.00 N
+ATOM 3811 CA SER C 112 -53.117 8.502 49.786 1.00 40.00 C
+ATOM 3812 C SER C 112 -54.588 8.528 50.161 1.00 40.00 C
+ATOM 3813 O SER C 112 -54.921 8.607 51.333 1.00 40.00 O
+ATOM 3814 CB SER C 112 -52.547 7.105 49.950 1.00 40.00 C
+ATOM 3815 OG SER C 112 -51.143 7.136 49.734 1.00 40.00 O
+ATOM 3816 N LEU C 113 -55.454 8.460 49.149 1.00 40.00 N
+ATOM 3817 CA LEU C 113 -56.898 8.522 49.338 1.00 40.00 C
+ATOM 3818 C LEU C 113 -57.582 7.298 48.807 1.00 40.00 C
+ATOM 3819 O LEU C 113 -57.065 6.627 47.919 1.00 40.00 O
+ATOM 3820 CB LEU C 113 -57.465 9.700 48.579 1.00 40.00 C
+ATOM 3821 CG LEU C 113 -57.290 11.028 49.267 1.00 40.00 C
+ATOM 3822 CD1 LEU C 113 -57.924 12.110 48.408 1.00 40.00 C
+ATOM 3823 CD2 LEU C 113 -57.958 10.912 50.619 1.00 40.00 C
+ATOM 3824 N CYS C 114 -58.768 7.030 49.332 1.00 40.00 N
+ATOM 3825 CA CYS C 114 -59.589 5.950 48.817 1.00 40.00 C
+ATOM 3826 C CYS C 114 -60.936 6.513 48.395 1.00 40.00 C
+ATOM 3827 O CYS C 114 -61.679 7.053 49.220 1.00 40.00 O
+ATOM 3828 CB CYS C 114 -59.755 4.849 49.857 1.00 40.00 C
+ATOM 3829 SG CYS C 114 -60.695 3.413 49.274 1.00 40.00 S
+ATOM 3830 N VAL C 115 -61.231 6.401 47.100 1.00 40.00 N
+ATOM 3831 CA VAL C 115 -62.420 7.031 46.518 1.00 40.00 C
+ATOM 3832 C VAL C 115 -63.275 6.105 45.652 1.00 40.00 C
+ATOM 3833 O VAL C 115 -62.808 5.511 44.665 1.00 40.00 O
+ATOM 3834 CB VAL C 115 -62.072 8.279 45.680 1.00 40.00 C
+ATOM 3835 CG1 VAL C 115 -63.307 9.157 45.504 1.00 40.00 C
+ATOM 3836 CG2 VAL C 115 -60.947 9.066 46.333 1.00 40.00 C
+ATOM 3837 N LYS C 116 -64.545 6.012 46.038 1.00 40.00 N
+ATOM 3838 CA LYS C 116 -65.562 5.345 45.242 1.00 40.00 C
+ATOM 3839 C LYS C 116 -66.220 6.392 44.345 1.00 40.00 C
+ATOM 3840 O LYS C 116 -66.573 7.493 44.792 1.00 40.00 O
+ATOM 3841 CB LYS C 116 -66.598 4.672 46.145 1.00 40.00 C
+ATOM 3842 CG LYS C 116 -67.550 3.739 45.423 1.00 40.00 C
+ATOM 3843 CD LYS C 116 -68.898 3.755 46.123 1.00 40.00 C
+ATOM 3844 CE LYS C 116 -70.031 3.252 45.235 1.00 40.00 C
+ATOM 3845 NZ LYS C 116 -70.175 1.775 45.339 1.00 40.00 N
+ATOM 3846 N ARG C 117 -66.352 6.034 43.074 1.00 40.00 N
+ATOM 3847 CA ARG C 117 -67.003 6.863 42.080 1.00 40.00 C
+ATOM 3848 C ARG C 117 -68.522 6.864 42.333 1.00 40.00 C
+ATOM 3849 O ARG C 117 -69.210 5.845 42.142 1.00 40.00 O
+ATOM 3850 CB ARG C 117 -66.668 6.312 40.692 1.00 40.00 C
+ATOM 3851 CG ARG C 117 -66.724 7.322 39.568 1.00 40.00 C
+ATOM 3852 CD ARG C 117 -66.647 6.638 38.212 1.00 40.00 C
+ATOM 3853 NE ARG C 117 -65.278 6.494 37.728 1.00 40.00 N
+ATOM 3854 CZ ARG C 117 -64.612 7.434 37.066 1.00 40.00 C
+ATOM 3855 NH1 ARG C 117 -65.181 8.599 36.819 1.00 40.00 N
+ATOM 3856 NH2 ARG C 117 -63.371 7.213 36.656 1.00 40.00 N
+ATOM 3857 N LEU C 118 -69.033 8.002 42.798 1.00 40.00 N
+ATOM 3858 CA LEU C 118 -70.469 8.166 42.994 1.00 40.00 C
+ATOM 3859 C LEU C 118 -71.159 8.194 41.627 1.00 40.00 C
+ATOM 3860 O LEU C 118 -71.077 9.202 40.910 1.00 40.00 O
+ATOM 3861 CB LEU C 118 -70.771 9.448 43.799 1.00 40.00 C
+ATOM 3862 CG LEU C 118 -72.212 9.949 43.968 1.00 40.00 C
+ATOM 3863 CD1 LEU C 118 -73.056 8.959 44.749 1.00 40.00 C
+ATOM 3864 CD2 LEU C 118 -72.247 11.301 44.646 1.00 40.00 C
+ATOM 3865 N ILE C 119 -71.778 7.068 41.247 1.00 40.00 N
+ATOM 3866 CA ILE C 119 -72.764 7.035 40.128 1.00 40.00 C
+ATOM 3867 C ILE C 119 -74.029 6.213 40.487 1.00 40.00 C
+ATOM 3868 O ILE C 119 -73.936 5.009 40.798 1.00 40.00 O
+ATOM 3869 CB ILE C 119 -72.181 6.584 38.748 1.00 40.00 C
+ATOM 3870 CG1 ILE C 119 -71.024 7.482 38.303 1.00 40.00 C
+ATOM 3871 CG2 ILE C 119 -73.256 6.641 37.665 1.00 40.00 C
+ATOM 3872 CD1 ILE C 119 -70.299 6.984 37.072 1.00 40.00 C
+ATOM 3873 N TYR C 120 -75.187 6.891 40.455 1.00 40.00 N
+ATOM 3874 CA TYR C 120 -76.525 6.289 40.653 1.00 40.00 C
+ATOM 3875 C TYR C 120 -77.437 6.617 39.455 1.00 40.00 C
+ATOM 3876 O TYR C 120 -77.104 7.493 38.644 1.00 40.00 O
+ATOM 3877 CB TYR C 120 -77.170 6.721 42.008 1.00 40.00 C
+ATOM 3878 CG TYR C 120 -77.278 8.235 42.308 1.00 40.00 C
+ATOM 3879 CD1 TYR C 120 -76.156 8.983 42.708 1.00 40.00 C
+ATOM 3880 CD2 TYR C 120 -78.515 8.909 42.241 1.00 40.00 C
+ATOM 3881 CE1 TYR C 120 -76.251 10.353 42.993 1.00 40.00 C
+ATOM 3882 CE2 TYR C 120 -78.617 10.282 42.526 1.00 40.00 C
+ATOM 3883 CZ TYR C 120 -77.486 10.999 42.906 1.00 40.00 C
+ATOM 3884 OH TYR C 120 -77.567 12.350 43.192 1.00 40.00 O
+ATOM 3885 N THR C 121 -78.551 5.883 39.324 1.00 40.00 N
+ATOM 3886 CA THR C 121 -79.678 6.254 38.419 1.00 40.00 C
+ATOM 3887 C THR C 121 -80.856 6.724 39.307 1.00 40.00 C
+ATOM 3888 O THR C 121 -81.221 6.002 40.241 1.00 40.00 O
+ATOM 3889 CB THR C 121 -80.086 5.077 37.459 1.00 40.00 C
+ATOM 3890 OG1 THR C 121 -79.204 5.042 36.321 1.00 40.00 O
+ATOM 3891 CG2 THR C 121 -81.548 5.189 36.956 1.00 40.00 C
+ATOM 3892 N ASN C 122 -81.409 7.925 39.061 1.00 40.00 N
+ATOM 3893 CA ASN C 122 -82.621 8.363 39.800 1.00 40.00 C
+ATOM 3894 C ASN C 122 -83.918 7.760 39.217 1.00 40.00 C
+ATOM 3895 O ASN C 122 -83.847 6.913 38.300 1.00 40.00 O
+ATOM 3896 CB ASN C 122 -82.687 9.902 40.100 1.00 40.00 C
+ATOM 3897 CG ASN C 122 -82.666 10.784 38.845 1.00 40.00 C
+ATOM 3898 OD1 ASN C 122 -83.512 10.662 37.948 1.00 40.00 O
+ATOM 3899 ND2 ASN C 122 -81.719 11.719 38.808 1.00 40.00 N
+ATOM 3900 N ASP C 123 -85.078 8.160 39.767 1.00 40.00 N
+ATOM 3901 CA ASP C 123 -86.413 7.640 39.324 1.00 40.00 C
+ATOM 3902 C ASP C 123 -86.874 8.015 37.882 1.00 40.00 C
+ATOM 3903 O ASP C 123 -87.813 7.394 37.330 1.00 40.00 O
+ATOM 3904 CB ASP C 123 -87.547 7.863 40.380 1.00 40.00 C
+ATOM 3905 CG ASP C 123 -87.508 9.260 41.090 1.00 40.00 C
+ATOM 3906 OD1 ASP C 123 -86.823 10.227 40.649 1.00 40.00 O
+ATOM 3907 OD2 ASP C 123 -88.212 9.376 42.124 1.00 40.00 O
+ATOM 3908 N ALA C 124 -86.193 9.014 37.297 1.00 40.00 N
+ATOM 3909 CA ALA C 124 -86.385 9.443 35.903 1.00 40.00 C
+ATOM 3910 C ALA C 124 -85.479 8.684 34.866 1.00 40.00 C
+ATOM 3911 O ALA C 124 -85.502 9.001 33.663 1.00 40.00 O
+ATOM 3912 CB ALA C 124 -86.250 10.974 35.797 1.00 40.00 C
+ATOM 3913 N GLY C 125 -84.725 7.671 35.333 1.00 40.00 N
+ATOM 3914 CA GLY C 125 -83.774 6.892 34.501 1.00 40.00 C
+ATOM 3915 C GLY C 125 -82.401 7.545 34.308 1.00 40.00 C
+ATOM 3916 O GLY C 125 -81.506 6.949 33.672 1.00 40.00 O
+ATOM 3917 N GLU C 126 -82.251 8.752 34.894 1.00 40.00 N
+ATOM 3918 CA GLU C 126 -81.133 9.722 34.678 1.00 40.00 C
+ATOM 3919 C GLU C 126 -79.853 9.451 35.499 1.00 40.00 C
+ATOM 3920 O GLU C 126 -79.839 9.675 36.728 1.00 40.00 O
+ATOM 3921 CB GLU C 126 -81.599 11.172 34.972 1.00 40.00 C
+ATOM 3922 CG GLU C 126 -82.812 11.647 34.180 1.00 40.00 C
+ATOM 3923 CD GLU C 126 -83.642 12.715 34.896 1.00 40.00 C
+ATOM 3924 OE1 GLU C 126 -83.587 12.829 36.151 1.00 40.00 O
+ATOM 3925 OE2 GLU C 126 -84.389 13.431 34.188 1.00 40.00 O
+ATOM 3926 N ILE C 127 -78.791 9.006 34.804 1.00 40.00 N
+ATOM 3927 CA ILE C 127 -77.448 8.757 35.390 1.00 40.00 C
+ATOM 3928 C ILE C 127 -76.807 10.024 36.047 1.00 40.00 C
+ATOM 3929 O ILE C 127 -76.304 10.928 35.349 1.00 40.00 O
+ATOM 3930 CB ILE C 127 -76.507 8.029 34.372 1.00 40.00 C
+ATOM 3931 CG1 ILE C 127 -76.911 6.557 34.254 1.00 40.00 C
+ATOM 3932 CG2 ILE C 127 -75.034 8.138 34.764 1.00 40.00 C
+ATOM 3933 CD1 ILE C 127 -75.960 5.718 33.435 1.00 40.00 C
+ATOM 3934 N VAL C 128 -76.867 10.078 37.391 1.00 40.00 N
+ATOM 3935 CA VAL C 128 -76.253 11.147 38.221 1.00 40.00 C
+ATOM 3936 C VAL C 128 -74.812 10.752 38.597 1.00 40.00 C
+ATOM 3937 O VAL C 128 -74.545 9.598 38.952 1.00 40.00 O
+ATOM 3938 CB VAL C 128 -77.075 11.458 39.518 1.00 40.00 C
+ATOM 3939 CG1 VAL C 128 -76.561 12.719 40.212 1.00 40.00 C
+ATOM 3940 CG2 VAL C 128 -78.568 11.588 39.227 1.00 40.00 C
+ATOM 3941 N LYS C 129 -73.891 11.708 38.497 1.00 40.00 N
+ATOM 3942 CA LYS C 129 -72.495 11.474 38.860 1.00 40.00 C
+ATOM 3943 C LYS C 129 -71.995 12.498 39.893 1.00 40.00 C
+ATOM 3944 O LYS C 129 -72.264 13.702 39.784 1.00 40.00 O
+ATOM 3945 CB LYS C 129 -71.605 11.485 37.614 1.00 40.00 C
+ATOM 3946 CG LYS C 129 -72.046 10.553 36.487 1.00 40.00 C
+ATOM 3947 CD LYS C 129 -70.960 10.413 35.417 1.00 40.00 C
+ATOM 3948 CE LYS C 129 -70.569 11.756 34.794 1.00 40.00 C
+ATOM 3949 NZ LYS C 129 -69.312 11.712 33.986 1.00 40.00 N
+ATOM 3950 N GLY C 130 -71.281 12.006 40.900 1.00 40.00 N
+ATOM 3951 CA GLY C 130 -70.667 12.871 41.891 1.00 40.00 C
+ATOM 3952 C GLY C 130 -69.561 13.735 41.305 1.00 40.00 C
+ATOM 3953 O GLY C 130 -68.653 13.238 40.637 1.00 40.00 O
+ATOM 3954 N VAL C 131 -69.649 15.037 41.563 1.00 40.00 N
+ATOM 3955 CA VAL C 131 -68.611 16.003 41.182 1.00 40.00 C
+ATOM 3956 C VAL C 131 -67.209 15.515 41.602 1.00 40.00 C
+ATOM 3957 O VAL C 131 -66.409 15.090 40.755 1.00 40.00 O
+ATOM 3958 CB VAL C 131 -68.905 17.421 41.770 1.00 40.00 C
+ATOM 3959 CG1 VAL C 131 -67.826 18.433 41.381 1.00 40.00 C
+ATOM 3960 CG2 VAL C 131 -70.282 17.914 41.340 1.00 40.00 C
+ATOM 3961 N CYS C 132 -66.942 15.551 42.911 1.00 40.00 N
+ATOM 3962 CA CYS C 132 -65.605 15.325 43.441 1.00 40.00 C
+ATOM 3963 C CYS C 132 -65.135 13.894 43.233 1.00 40.00 C
+ATOM 3964 O CYS C 132 -64.005 13.690 42.794 1.00 40.00 O
+ATOM 3965 CB CYS C 132 -65.533 15.717 44.913 1.00 40.00 C
+ATOM 3966 SG CYS C 132 -63.970 16.504 45.332 1.00 40.00 S
+ATOM 3967 N SER C 133 -66.009 12.920 43.525 1.00 40.00 N
+ATOM 3968 CA SER C 133 -65.695 11.481 43.398 1.00 40.00 C
+ATOM 3969 C SER C 133 -65.317 11.080 41.970 1.00 40.00 C
+ATOM 3970 O SER C 133 -64.406 10.264 41.768 1.00 40.00 O
+ATOM 3971 CB SER C 133 -66.865 10.609 43.872 1.00 40.00 C
+ATOM 3972 OG SER C 133 -67.963 10.715 42.979 1.00 40.00 O
+ATOM 3973 N ASN C 134 -66.022 11.653 40.991 1.00 40.00 N
+ATOM 3974 CA ASN C 134 -65.744 11.394 39.578 1.00 40.00 C
+ATOM 3975 C ASN C 134 -64.542 12.151 39.080 1.00 40.00 C
+ATOM 3976 O ASN C 134 -63.747 11.606 38.320 1.00 40.00 O
+ATOM 3977 CB ASN C 134 -66.963 11.695 38.720 1.00 40.00 C
+ATOM 3978 CG ASN C 134 -67.988 10.583 38.788 1.00 40.00 C
+ATOM 3979 OD1 ASN C 134 -67.844 9.561 38.118 1.00 40.00 O
+ATOM 3980 ND2 ASN C 134 -69.019 10.764 39.612 1.00 40.00 N
+ATOM 3981 N PHE C 135 -64.414 13.405 39.524 1.00 40.00 N
+ATOM 3982 CA PHE C 135 -63.202 14.193 39.292 1.00 40.00 C
+ATOM 3983 C PHE C 135 -61.964 13.366 39.658 1.00 40.00 C
+ATOM 3984 O PHE C 135 -61.018 13.252 38.863 1.00 40.00 O
+ATOM 3985 CB PHE C 135 -63.243 15.525 40.081 1.00 40.00 C
+ATOM 3986 CG PHE C 135 -61.912 16.241 40.156 1.00 40.00 C
+ATOM 3987 CD1 PHE C 135 -61.267 16.680 38.996 1.00 40.00 C
+ATOM 3988 CD2 PHE C 135 -61.302 16.480 41.385 1.00 40.00 C
+ATOM 3989 CE1 PHE C 135 -60.043 17.331 39.063 1.00 40.00 C
+ATOM 3990 CE2 PHE C 135 -60.079 17.136 41.455 1.00 40.00 C
+ATOM 3991 CZ PHE C 135 -59.451 17.563 40.295 1.00 40.00 C
+ATOM 3992 N LEU C 136 -62.016 12.762 40.847 1.00 40.00 N
+ATOM 3993 CA LEU C 136 -60.871 12.093 41.445 1.00 40.00 C
+ATOM 3994 C LEU C 136 -60.518 10.763 40.786 1.00 40.00 C
+ATOM 3995 O LEU C 136 -59.353 10.529 40.443 1.00 40.00 O
+ATOM 3996 CB LEU C 136 -61.054 11.954 42.960 1.00 40.00 C
+ATOM 3997 CG LEU C 136 -60.809 13.274 43.718 1.00 40.00 C
+ATOM 3998 CD1 LEU C 136 -61.321 13.203 45.153 1.00 40.00 C
+ATOM 3999 CD2 LEU C 136 -59.344 13.717 43.691 1.00 40.00 C
+ATOM 4000 N CYS C 137 -61.504 9.901 40.582 1.00 40.00 N
+ATOM 4001 CA CYS C 137 -61.246 8.657 39.873 1.00 40.00 C
+ATOM 4002 C CYS C 137 -60.762 8.918 38.445 1.00 40.00 C
+ATOM 4003 O CYS C 137 -60.040 8.098 37.869 1.00 40.00 O
+ATOM 4004 CB CYS C 137 -62.494 7.792 39.879 1.00 40.00 C
+ATOM 4005 SG CYS C 137 -62.975 7.260 41.545 1.00 40.00 S
+ATOM 4006 N ASP C 138 -61.144 10.085 37.908 1.00 40.00 N
+ATOM 4007 CA ASP C 138 -60.800 10.525 36.540 1.00 40.00 C
+ATOM 4008 C ASP C 138 -59.381 11.067 36.354 1.00 40.00 C
+ATOM 4009 O ASP C 138 -58.959 11.340 35.220 1.00 40.00 O
+ATOM 4010 CB ASP C 138 -61.795 11.586 36.041 1.00 40.00 C
+ATOM 4011 CG ASP C 138 -63.053 10.983 35.441 1.00 40.00 C
+ATOM 4012 OD1 ASP C 138 -63.167 9.730 35.360 1.00 40.00 O
+ATOM 4013 OD2 ASP C 138 -63.933 11.781 35.052 1.00 40.00 O
+ATOM 4014 N LEU C 139 -58.647 11.232 37.451 1.00 40.00 N
+ATOM 4015 CA LEU C 139 -57.332 11.860 37.369 1.00 40.00 C
+ATOM 4016 C LEU C 139 -56.265 10.961 36.761 1.00 40.00 C
+ATOM 4017 O LEU C 139 -56.208 9.756 37.019 1.00 40.00 O
+ATOM 4018 CB LEU C 139 -56.888 12.434 38.720 1.00 40.00 C
+ATOM 4019 CG LEU C 139 -57.626 13.708 39.150 1.00 40.00 C
+ATOM 4020 CD1 LEU C 139 -57.174 14.094 40.544 1.00 40.00 C
+ATOM 4021 CD2 LEU C 139 -57.459 14.875 38.179 1.00 40.00 C
+ATOM 4022 N GLN C 140 -55.442 11.576 35.924 1.00 40.00 N
+ATOM 4023 CA GLN C 140 -54.323 10.903 35.302 1.00 40.00 C
+ATOM 4024 C GLN C 140 -53.016 11.281 36.021 1.00 40.00 C
+ATOM 4025 O GLN C 140 -52.923 12.390 36.571 1.00 40.00 O
+ATOM 4026 CB GLN C 140 -54.266 11.281 33.814 1.00 40.00 C
+ATOM 4027 CG GLN C 140 -55.489 10.873 33.008 1.00 40.00 C
+ATOM 4028 CD GLN C 140 -55.935 9.443 33.285 1.00 40.00 C
+ATOM 4029 OE1 GLN C 140 -57.104 9.120 33.125 1.00 40.00 O
+ATOM 4030 NE2 GLN C 140 -55.009 8.585 33.708 1.00 40.00 N
+ATOM 4031 N PRO C 141 -52.011 10.364 36.045 1.00 40.00 N
+ATOM 4032 CA PRO C 141 -50.678 10.782 36.470 1.00 40.00 C
+ATOM 4033 C PRO C 141 -50.308 12.166 35.888 1.00 40.00 C
+ATOM 4034 O PRO C 141 -50.358 12.358 34.672 1.00 40.00 O
+ATOM 4035 CB PRO C 141 -49.776 9.694 35.880 1.00 40.00 C
+ATOM 4036 CG PRO C 141 -50.625 8.477 35.814 1.00 40.00 C
+ATOM 4037 CD PRO C 141 -52.066 8.910 35.787 1.00 40.00 C
+ATOM 4038 N GLY C 142 -49.985 13.135 36.740 1.00 40.00 N
+ATOM 4039 CA GLY C 142 -49.518 14.447 36.259 1.00 40.00 C
+ATOM 4040 C GLY C 142 -50.501 15.598 36.379 1.00 40.00 C
+ATOM 4041 O GLY C 142 -50.123 16.776 36.253 1.00 40.00 O
+ATOM 4042 N ASP C 143 -51.765 15.245 36.615 1.00 40.00 N
+ATOM 4043 CA ASP C 143 -52.829 16.213 36.871 1.00 40.00 C
+ATOM 4044 C ASP C 143 -52.573 16.949 38.189 1.00 40.00 C
+ATOM 4045 O ASP C 143 -52.031 16.380 39.132 1.00 40.00 O
+ATOM 4046 CB ASP C 143 -54.201 15.508 36.916 1.00 40.00 C
+ATOM 4047 CG ASP C 143 -54.563 14.802 35.604 1.00 40.00 C
+ATOM 4048 OD1 ASP C 143 -53.655 14.490 34.809 1.00 40.00 O
+ATOM 4049 OD2 ASP C 143 -55.764 14.546 35.374 1.00 40.00 O
+ATOM 4050 N ASN C 144 -52.954 18.217 38.244 1.00 40.00 N
+ATOM 4051 CA ASN C 144 -52.895 18.961 39.496 1.00 40.00 C
+ATOM 4052 C ASN C 144 -54.107 18.687 40.383 1.00 40.00 C
+ATOM 4053 O ASN C 144 -55.196 18.427 39.865 1.00 40.00 O
+ATOM 4054 CB ASN C 144 -52.764 20.467 39.230 1.00 40.00 C
+ATOM 4055 CG ASN C 144 -51.319 20.941 39.238 1.00 40.00 C
+ATOM 4056 OD1 ASN C 144 -51.016 22.064 38.818 1.00 40.00 O
+ATOM 4057 ND2 ASN C 144 -50.419 20.094 39.732 1.00 40.00 N
+ATOM 4058 N VAL C 145 -53.904 18.726 41.710 1.00 40.00 N
+ATOM 4059 CA VAL C 145 -54.997 18.631 42.730 1.00 40.00 C
+ATOM 4060 C VAL C 145 -54.888 19.780 43.765 1.00 40.00 C
+ATOM 4061 O VAL C 145 -53.794 20.059 44.295 1.00 40.00 O
+ATOM 4062 CB VAL C 145 -55.055 17.252 43.490 1.00 40.00 C
+ATOM 4063 CG1 VAL C 145 -56.415 17.036 44.156 1.00 40.00 C
+ATOM 4064 CG2 VAL C 145 -54.744 16.071 42.574 1.00 40.00 C
+ATOM 4065 N GLN C 146 -56.022 20.439 44.038 1.00 40.00 N
+ATOM 4066 CA GLN C 146 -56.102 21.455 45.094 1.00 40.00 C
+ATOM 4067 C GLN C 146 -56.493 20.775 46.410 1.00 40.00 C
+ATOM 4068 O GLN C 146 -57.515 20.071 46.496 1.00 40.00 O
+ATOM 4069 CB GLN C 146 -57.098 22.566 44.724 1.00 40.00 C
+ATOM 4070 CG GLN C 146 -56.642 23.480 43.586 1.00 40.00 C
+ATOM 4071 CD GLN C 146 -57.707 24.482 43.134 1.00 40.00 C
+ATOM 4072 OE1 GLN C 146 -58.872 24.123 42.879 1.00 40.00 O
+ATOM 4073 NE2 GLN C 146 -57.302 25.748 43.010 1.00 40.00 N
+ATOM 4074 N ILE C 147 -55.668 20.986 47.431 1.00 40.00 N
+ATOM 4075 CA ILE C 147 -55.758 20.188 48.649 1.00 40.00 C
+ATOM 4076 C ILE C 147 -55.829 21.012 49.931 1.00 40.00 C
+ATOM 4077 O ILE C 147 -54.932 21.827 50.210 1.00 40.00 O
+ATOM 4078 CB ILE C 147 -54.587 19.182 48.739 1.00 40.00 C
+ATOM 4079 CG1 ILE C 147 -54.693 18.146 47.617 1.00 40.00 C
+ATOM 4080 CG2 ILE C 147 -54.589 18.455 50.077 1.00 40.00 C
+ATOM 4081 CD1 ILE C 147 -53.386 17.454 47.293 1.00 40.00 C
+ATOM 4082 N THR C 148 -56.899 20.770 50.700 1.00 40.00 N
+ATOM 4083 CA THR C 148 -57.126 21.395 52.014 1.00 40.00 C
+ATOM 4084 C THR C 148 -56.839 20.421 53.158 1.00 40.00 C
+ATOM 4085 O THR C 148 -56.967 19.200 53.000 1.00 40.00 O
+ATOM 4086 CB THR C 148 -58.576 21.931 52.171 1.00 40.00 C
+ATOM 4087 OG1 THR C 148 -59.511 20.862 52.015 1.00 40.00 O
+ATOM 4088 CG2 THR C 148 -58.899 23.004 51.135 1.00 40.00 C
+ATOM 4089 N GLY C 149 -56.458 20.970 54.308 1.00 40.00 N
+ATOM 4090 CA GLY C 149 -56.265 20.159 55.504 1.00 40.00 C
+ATOM 4091 C GLY C 149 -54.965 20.452 56.233 1.00 40.00 C
+ATOM 4092 O GLY C 149 -54.358 21.502 56.007 1.00 40.00 O
+ATOM 4093 N PRO C 150 -54.527 19.526 57.116 1.00 40.00 N
+ATOM 4094 CA PRO C 150 -55.248 18.294 57.424 1.00 40.00 C
+ATOM 4095 C PRO C 150 -56.356 18.570 58.408 1.00 40.00 C
+ATOM 4096 O PRO C 150 -56.344 19.599 59.082 1.00 40.00 O
+ATOM 4097 CB PRO C 150 -54.185 17.414 58.074 1.00 40.00 C
+ATOM 4098 CG PRO C 150 -53.224 18.370 58.682 1.00 40.00 C
+ATOM 4099 CD PRO C 150 -53.254 19.628 57.859 1.00 40.00 C
+ATOM 4100 N VAL C 151 -57.303 17.646 58.493 1.00 40.00 N
+ATOM 4101 CA VAL C 151 -58.528 17.873 59.246 1.00 40.00 C
+ATOM 4102 C VAL C 151 -59.002 16.620 59.999 1.00 40.00 C
+ATOM 4103 O VAL C 151 -58.809 15.478 59.536 1.00 40.00 O
+ATOM 4104 CB VAL C 151 -59.637 18.352 58.296 1.00 40.00 C
+ATOM 4105 CG1 VAL C 151 -60.973 18.404 59.002 1.00 40.00 C
+ATOM 4106 CG2 VAL C 151 -59.301 19.719 57.737 1.00 40.00 C
+ATOM 4107 N GLY C 152 -59.634 16.843 61.153 1.00 40.00 N
+ATOM 4108 CA GLY C 152 -60.164 15.753 61.977 1.00 40.00 C
+ATOM 4109 C GLY C 152 -59.190 15.399 63.082 1.00 40.00 C
+ATOM 4110 O GLY C 152 -57.983 15.275 62.859 1.00 40.00 O
+ATOM 4111 N LYS C 153 -59.707 15.269 64.291 1.00 40.00 N
+ATOM 4112 CA LYS C 153 -58.886 14.832 65.399 1.00 40.00 C
+ATOM 4113 C LYS C 153 -59.606 13.624 65.934 1.00 40.00 C
+ATOM 4114 O LYS C 153 -59.112 12.932 66.823 1.00 40.00 O
+ATOM 4115 CB LYS C 153 -58.796 15.914 66.478 1.00 40.00 C
+ATOM 4116 CG LYS C 153 -58.182 17.237 66.036 1.00 40.00 C
+ATOM 4117 CD LYS C 153 -56.728 17.366 66.453 1.00 40.00 C
+ATOM 4118 CE LYS C 153 -56.571 17.714 67.929 1.00 40.00 C
+ATOM 4119 NZ LYS C 153 -56.830 19.145 68.228 1.00 40.00 N
+ATOM 4120 N GLU C 154 -60.786 13.380 65.369 1.00 40.00 N
+ATOM 4121 CA GLU C 154 -61.705 12.393 65.906 1.00 40.00 C
+ATOM 4122 C GLU C 154 -61.164 10.975 65.797 1.00 40.00 C
+ATOM 4123 O GLU C 154 -61.406 10.133 66.668 1.00 40.00 O
+ATOM 4124 CB GLU C 154 -63.064 12.504 65.208 1.00 40.00 C
+ATOM 4125 CG GLU C 154 -64.143 11.554 65.742 1.00 40.00 C
+ATOM 4126 CD GLU C 154 -64.703 11.955 67.104 1.00 40.00 C
+ATOM 4127 OE1 GLU C 154 -64.068 12.786 67.796 1.00 40.00 O
+ATOM 4128 OE2 GLU C 154 -65.787 11.438 67.479 1.00 40.00 O
+ATOM 4129 N MET C 155 -60.412 10.714 64.743 1.00 40.00 N
+ATOM 4130 CA MET C 155 -60.042 9.355 64.479 1.00 40.00 C
+ATOM 4131 C MET C 155 -58.580 9.044 64.700 1.00 40.00 C
+ATOM 4132 O MET C 155 -58.056 8.114 64.118 1.00 40.00 O
+ATOM 4133 CB MET C 155 -60.478 9.001 63.077 1.00 40.00 C
+ATOM 4134 CG MET C 155 -61.982 8.961 62.964 1.00 40.00 C
+ATOM 4135 SD MET C 155 -62.656 7.770 64.134 1.00 40.00 S
+ATOM 4136 CE MET C 155 -62.756 6.298 63.115 1.00 40.00 C
+ATOM 4137 N LEU C 156 -57.922 9.805 65.562 1.00 40.00 N
+ATOM 4138 CA LEU C 156 -56.511 9.564 65.843 1.00 40.00 C
+ATOM 4139 C LEU C 156 -56.340 8.255 66.610 1.00 40.00 C
+ATOM 4140 O LEU C 156 -57.227 7.845 67.353 1.00 40.00 O
+ATOM 4141 CB LEU C 156 -55.895 10.739 66.616 1.00 40.00 C
+ATOM 4142 CG LEU C 156 -55.910 12.149 65.997 1.00 40.00 C
+ATOM 4143 CD1 LEU C 156 -55.752 13.239 67.047 1.00 40.00 C
+ATOM 4144 CD2 LEU C 156 -54.834 12.297 64.941 1.00 40.00 C
+ATOM 4145 N MET C 157 -55.198 7.601 66.409 1.00 40.00 N
+ATOM 4146 CA MET C 157 -54.900 6.320 67.044 1.00 40.00 C
+ATOM 4147 C MET C 157 -54.801 6.505 68.544 1.00 40.00 C
+ATOM 4148 O MET C 157 -54.660 7.629 69.018 1.00 40.00 O
+ATOM 4149 CB MET C 157 -53.565 5.788 66.546 1.00 40.00 C
+ATOM 4150 CG MET C 157 -53.320 5.997 65.069 1.00 40.00 C
+ATOM 4151 SD MET C 157 -51.987 4.945 64.499 1.00 40.00 S
+ATOM 4152 CE MET C 157 -52.750 3.337 64.635 1.00 40.00 C
+ATOM 4153 N PRO C 158 -54.868 5.409 69.306 1.00 40.00 N
+ATOM 4154 CA PRO C 158 -54.652 5.558 70.744 1.00 40.00 C
+ATOM 4155 C PRO C 158 -53.182 5.838 71.088 1.00 40.00 C
+ATOM 4156 O PRO C 158 -52.315 5.674 70.244 1.00 40.00 O
+ATOM 4157 CB PRO C 158 -55.102 4.200 71.307 1.00 40.00 C
+ATOM 4158 CG PRO C 158 -55.970 3.608 70.245 1.00 40.00 C
+ATOM 4159 CD PRO C 158 -55.341 4.060 68.964 1.00 40.00 C
+ATOM 4160 N LYS C 159 -52.918 6.285 72.308 1.00 40.00 N
+ATOM 4161 CA LYS C 159 -51.555 6.442 72.779 1.00 40.00 C
+ATOM 4162 C LYS C 159 -50.982 5.090 73.147 1.00 40.00 C
+ATOM 4163 O LYS C 159 -49.818 4.811 72.866 1.00 40.00 O
+ATOM 4164 CB LYS C 159 -51.506 7.373 73.982 1.00 40.00 C
+ATOM 4165 CG LYS C 159 -51.429 8.837 73.597 1.00 40.00 C
+ATOM 4166 CD LYS C 159 -51.852 9.766 74.728 1.00 40.00 C
+ATOM 4167 CE LYS C 159 -51.754 11.215 74.241 1.00 40.00 C
+ATOM 4168 NZ LYS C 159 -52.514 12.204 75.069 1.00 40.00 N
+ATOM 4169 N ASP C 160 -51.819 4.257 73.766 1.00 40.00 N
+ATOM 4170 CA ASP C 160 -51.473 2.894 74.211 1.00 40.00 C
+ATOM 4171 C ASP C 160 -50.944 1.990 73.071 1.00 40.00 C
+ATOM 4172 O ASP C 160 -51.698 1.648 72.162 1.00 40.00 O
+ATOM 4173 CB ASP C 160 -52.722 2.267 74.871 1.00 40.00 C
+ATOM 4174 CG ASP C 160 -52.460 0.894 75.515 1.00 40.00 C
+ATOM 4175 OD1 ASP C 160 -51.365 0.303 75.334 1.00 40.00 O
+ATOM 4176 OD2 ASP C 160 -53.386 0.407 76.213 1.00 40.00 O
+ATOM 4177 N PRO C 161 -49.653 1.592 73.112 1.00 40.00 N
+ATOM 4178 CA PRO C 161 -49.205 0.704 72.057 1.00 40.00 C
+ATOM 4179 C PRO C 161 -49.447 -0.776 72.400 1.00 40.00 C
+ATOM 4180 O PRO C 161 -48.912 -1.660 71.721 1.00 40.00 O
+ATOM 4181 CB PRO C 161 -47.715 1.036 71.925 1.00 40.00 C
+ATOM 4182 CG PRO C 161 -47.333 1.664 73.215 1.00 40.00 C
+ATOM 4183 CD PRO C 161 -48.564 1.887 74.048 1.00 40.00 C
+ATOM 4184 N ASN C 162 -50.260 -1.030 73.429 1.00 40.00 N
+ATOM 4185 CA ASN C 162 -50.733 -2.377 73.756 1.00 40.00 C
+ATOM 4186 C ASN C 162 -52.243 -2.444 73.743 1.00 40.00 C
+ATOM 4187 O ASN C 162 -52.862 -3.273 74.409 1.00 40.00 O
+ATOM 4188 CB ASN C 162 -50.210 -2.811 75.119 1.00 40.00 C
+ATOM 4189 CG ASN C 162 -48.769 -3.290 75.066 1.00 40.00 C
+ATOM 4190 OD1 ASN C 162 -48.045 -3.217 76.062 1.00 40.00 O
+ATOM 4191 ND2 ASN C 162 -48.342 -3.785 73.902 1.00 40.00 N
+ATOM 4192 N ALA C 163 -52.819 -1.556 72.952 1.00 40.00 N
+ATOM 4193 CA ALA C 163 -54.251 -1.372 72.879 1.00 40.00 C
+ATOM 4194 C ALA C 163 -54.943 -2.458 72.094 1.00 40.00 C
+ATOM 4195 O ALA C 163 -54.380 -3.016 71.155 1.00 40.00 O
+ATOM 4196 CB ALA C 163 -54.554 -0.035 72.238 1.00 40.00 C
+ATOM 4197 N THR C 164 -56.178 -2.740 72.489 1.00 40.00 N
+ATOM 4198 CA THR C 164 -57.083 -3.532 71.687 1.00 40.00 C
+ATOM 4199 C THR C 164 -57.756 -2.531 70.766 1.00 40.00 C
+ATOM 4200 O THR C 164 -58.417 -1.613 71.244 1.00 40.00 O
+ATOM 4201 CB THR C 164 -58.140 -4.225 72.568 1.00 40.00 C
+ATOM 4202 OG1 THR C 164 -57.493 -4.960 73.611 1.00 40.00 O
+ATOM 4203 CG2 THR C 164 -58.985 -5.182 71.755 1.00 40.00 C
+ATOM 4204 N ILE C 165 -57.573 -2.688 69.454 1.00 40.00 N
+ATOM 4205 CA ILE C 165 -58.113 -1.721 68.494 1.00 40.00 C
+ATOM 4206 C ILE C 165 -59.139 -2.270 67.522 1.00 40.00 C
+ATOM 4207 O ILE C 165 -58.809 -2.866 66.497 1.00 40.00 O
+ATOM 4208 CB ILE C 165 -57.015 -1.050 67.687 1.00 40.00 C
+ATOM 4209 CG1 ILE C 165 -56.022 -0.417 68.641 1.00 40.00 C
+ATOM 4210 CG2 ILE C 165 -57.622 0.009 66.785 1.00 40.00 C
+ATOM 4211 CD1 ILE C 165 -54.711 -0.064 67.987 1.00 40.00 C
+ATOM 4212 N ILE C 166 -60.396 -2.011 67.833 1.00 40.00 N
+ATOM 4213 CA ILE C 166 -61.471 -2.568 67.064 1.00 40.00 C
+ATOM 4214 C ILE C 166 -61.914 -1.604 66.009 1.00 40.00 C
+ATOM 4215 O ILE C 166 -62.306 -0.474 66.299 1.00 40.00 O
+ATOM 4216 CB ILE C 166 -62.639 -2.936 67.959 1.00 40.00 C
+ATOM 4217 CG1 ILE C 166 -62.154 -3.987 68.949 1.00 40.00 C
+ATOM 4218 CG2 ILE C 166 -63.784 -3.478 67.119 1.00 40.00 C
+ATOM 4219 CD1 ILE C 166 -62.985 -4.107 70.203 1.00 40.00 C
+ATOM 4220 N MET C 167 -61.866 -2.090 64.779 1.00 40.00 N
+ATOM 4221 CA MET C 167 -62.083 -1.272 63.613 1.00 40.00 C
+ATOM 4222 C MET C 167 -63.248 -1.784 62.776 1.00 40.00 C
+ATOM 4223 O MET C 167 -63.170 -2.835 62.139 1.00 40.00 O
+ATOM 4224 CB MET C 167 -60.797 -1.248 62.809 1.00 40.00 C
+ATOM 4225 CG MET C 167 -59.596 -0.847 63.652 1.00 40.00 C
+ATOM 4226 SD MET C 167 -58.020 -1.016 62.796 1.00 40.00 S
+ATOM 4227 CE MET C 167 -57.561 -2.673 63.303 1.00 40.00 C
+ATOM 4228 N LEU C 168 -64.339 -1.034 62.795 1.00 40.00 N
+ATOM 4229 CA LEU C 168 -65.488 -1.399 62.003 1.00 40.00 C
+ATOM 4230 C LEU C 168 -65.540 -0.534 60.778 1.00 40.00 C
+ATOM 4231 O LEU C 168 -65.555 0.689 60.881 1.00 40.00 O
+ATOM 4232 CB LEU C 168 -66.775 -1.223 62.793 1.00 40.00 C
+ATOM 4233 CG LEU C 168 -66.972 -2.032 64.068 1.00 40.00 C
+ATOM 4234 CD1 LEU C 168 -66.153 -3.320 64.072 1.00 40.00 C
+ATOM 4235 CD2 LEU C 168 -66.580 -1.141 65.224 1.00 40.00 C
+ATOM 4236 N ALA C 169 -65.591 -1.174 59.617 1.00 40.00 N
+ATOM 4237 CA ALA C 169 -65.541 -0.442 58.366 1.00 40.00 C
+ATOM 4238 C ALA C 169 -66.437 -0.998 57.281 1.00 40.00 C
+ATOM 4239 O ALA C 169 -66.541 -2.203 57.107 1.00 40.00 O
+ATOM 4240 CB ALA C 169 -64.113 -0.373 57.866 1.00 40.00 C
+ATOM 4241 N THR C 170 -67.063 -0.095 56.541 1.00 40.00 N
+ATOM 4242 CA THR C 170 -67.895 -0.448 55.413 1.00 40.00 C
+ATOM 4243 C THR C 170 -67.483 0.396 54.237 1.00 40.00 C
+ATOM 4244 O THR C 170 -67.626 1.626 54.267 1.00 40.00 O
+ATOM 4245 CB THR C 170 -69.366 -0.120 55.683 1.00 40.00 C
+ATOM 4246 OG1 THR C 170 -69.468 1.213 56.211 1.00 40.00 O
+ATOM 4247 CG2 THR C 170 -69.964 -1.111 56.661 1.00 40.00 C
+ATOM 4248 N GLY C 171 -66.979 -0.258 53.197 1.00 40.00 N
+ATOM 4249 CA GLY C 171 -66.609 0.436 51.966 1.00 40.00 C
+ATOM 4250 C GLY C 171 -65.386 1.305 52.153 1.00 40.00 C
+ATOM 4251 O GLY C 171 -64.430 0.892 52.805 1.00 40.00 O
+ATOM 4252 N THR C 172 -65.429 2.517 51.601 1.00 40.00 N
+ATOM 4253 CA THR C 172 -64.300 3.440 51.682 1.00 40.00 C
+ATOM 4254 C THR C 172 -64.118 4.004 53.099 1.00 40.00 C
+ATOM 4255 O THR C 172 -63.422 5.004 53.303 1.00 40.00 O
+ATOM 4256 CB THR C 172 -64.415 4.588 50.653 1.00 40.00 C
+ATOM 4257 OG1 THR C 172 -65.483 5.468 51.027 1.00 40.00 O
+ATOM 4258 CG2 THR C 172 -64.679 4.042 49.262 1.00 40.00 C
+ATOM 4259 N GLY C 173 -64.750 3.360 54.074 1.00 40.00 N
+ATOM 4260 CA GLY C 173 -64.515 3.676 55.475 1.00 40.00 C
+ATOM 4261 C GLY C 173 -63.331 2.904 56.024 1.00 40.00 C
+ATOM 4262 O GLY C 173 -63.022 2.986 57.207 1.00 40.00 O
+ATOM 4263 N ILE C 174 -62.674 2.143 55.162 1.00 40.00 N
+ATOM 4264 CA ILE C 174 -61.505 1.385 55.556 1.00 40.00 C
+ATOM 4265 C ILE C 174 -60.304 2.302 55.531 1.00 40.00 C
+ATOM 4266 O ILE C 174 -59.328 2.074 56.239 1.00 40.00 O
+ATOM 4267 CB ILE C 174 -61.257 0.210 54.596 1.00 40.00 C
+ATOM 4268 CG1 ILE C 174 -60.001 -0.582 54.986 1.00 40.00 C
+ATOM 4269 CG2 ILE C 174 -61.100 0.717 53.173 1.00 40.00 C
+ATOM 4270 CD1 ILE C 174 -60.245 -1.716 55.956 1.00 40.00 C
+ATOM 4271 N ALA C 175 -60.396 3.346 54.715 1.00 40.00 N
+ATOM 4272 CA ALA C 175 -59.280 4.256 54.458 1.00 40.00 C
+ATOM 4273 C ALA C 175 -58.406 4.602 55.673 1.00 40.00 C
+ATOM 4274 O ALA C 175 -57.191 4.385 55.622 1.00 40.00 O
+ATOM 4275 CB ALA C 175 -59.773 5.521 53.777 1.00 40.00 C
+ATOM 4276 N PRO C 176 -59.011 5.133 56.763 1.00 40.00 N
+ATOM 4277 CA PRO C 176 -58.199 5.459 57.921 1.00 40.00 C
+ATOM 4278 C PRO C 176 -57.533 4.226 58.483 1.00 40.00 C
+ATOM 4279 O PRO C 176 -56.384 4.291 58.885 1.00 40.00 O
+ATOM 4280 CB PRO C 176 -59.218 5.987 58.923 1.00 40.00 C
+ATOM 4281 CG PRO C 176 -60.515 5.396 58.511 1.00 40.00 C
+ATOM 4282 CD PRO C 176 -60.437 5.406 57.021 1.00 40.00 C
+ATOM 4283 N PHE C 177 -58.243 3.108 58.490 1.00 40.00 N
+ATOM 4284 CA PHE C 177 -57.706 1.897 59.057 1.00 40.00 C
+ATOM 4285 C PHE C 177 -56.567 1.324 58.259 1.00 40.00 C
+ATOM 4286 O PHE C 177 -55.684 0.688 58.818 1.00 40.00 O
+ATOM 4287 CB PHE C 177 -58.795 0.884 59.185 1.00 40.00 C
+ATOM 4288 CG PHE C 177 -59.916 1.344 60.031 1.00 40.00 C
+ATOM 4289 CD1 PHE C 177 -59.698 1.693 61.348 1.00 40.00 C
+ATOM 4290 CD2 PHE C 177 -61.191 1.431 59.515 1.00 40.00 C
+ATOM 4291 CE1 PHE C 177 -60.742 2.111 62.148 1.00 40.00 C
+ATOM 4292 CE2 PHE C 177 -62.247 1.844 60.307 1.00 40.00 C
+ATOM 4293 CZ PHE C 177 -62.021 2.183 61.630 1.00 40.00 C
+ATOM 4294 N ARG C 178 -56.583 1.540 56.953 1.00 40.00 N
+ATOM 4295 CA ARG C 178 -55.411 1.242 56.165 1.00 40.00 C
+ATOM 4296 C ARG C 178 -54.284 1.953 56.888 1.00 40.00 C
+ATOM 4297 O ARG C 178 -53.361 1.322 57.427 1.00 40.00 O
+ATOM 4298 CB ARG C 178 -55.551 1.770 54.735 1.00 40.00 C
+ATOM 4299 CG ARG C 178 -54.305 1.541 53.901 1.00 40.00 C
+ATOM 4300 CD ARG C 178 -54.555 1.687 52.415 1.00 40.00 C
+ATOM 4301 NE ARG C 178 -53.512 1.009 51.641 1.00 40.00 N
+ATOM 4302 CZ ARG C 178 -52.405 1.593 51.188 1.00 40.00 C
+ATOM 4303 NH1 ARG C 178 -52.182 2.882 51.407 1.00 40.00 N
+ATOM 4304 NH2 ARG C 178 -51.524 0.884 50.506 1.00 40.00 N
+ATOM 4305 N SER C 179 -54.424 3.278 56.938 1.00 40.00 N
+ATOM 4306 CA SER C 179 -53.438 4.187 57.510 1.00 40.00 C
+ATOM 4307 C SER C 179 -52.934 3.685 58.854 1.00 40.00 C
+ATOM 4308 O SER C 179 -51.735 3.711 59.107 1.00 40.00 O
+ATOM 4309 CB SER C 179 -54.028 5.594 57.637 1.00 40.00 C
+ATOM 4310 OG SER C 179 -53.012 6.567 57.623 1.00 40.00 O
+ATOM 4311 N PHE C 180 -53.853 3.201 59.687 1.00 40.00 N
+ATOM 4312 CA PHE C 180 -53.521 2.638 60.995 1.00 40.00 C
+ATOM 4313 C PHE C 180 -52.612 1.446 60.856 1.00 40.00 C
+ATOM 4314 O PHE C 180 -51.552 1.365 61.474 1.00 40.00 O
+ATOM 4315 CB PHE C 180 -54.778 2.146 61.700 1.00 40.00 C
+ATOM 4316 CG PHE C 180 -55.498 3.198 62.478 1.00 40.00 C
+ATOM 4317 CD1 PHE C 180 -55.465 4.527 62.086 1.00 40.00 C
+ATOM 4318 CD2 PHE C 180 -56.249 2.845 63.588 1.00 40.00 C
+ATOM 4319 CE1 PHE C 180 -56.149 5.485 62.805 1.00 40.00 C
+ATOM 4320 CE2 PHE C 180 -56.940 3.795 64.313 1.00 40.00 C
+ATOM 4321 CZ PHE C 180 -56.888 5.117 63.921 1.00 40.00 C
+ATOM 4322 N LEU C 181 -53.043 0.502 60.046 1.00 40.00 N
+ATOM 4323 CA LEU C 181 -52.366 -0.760 60.044 1.00 40.00 C
+ATOM 4324 C LEU C 181 -50.962 -0.606 59.480 1.00 40.00 C
+ATOM 4325 O LEU C 181 -49.994 -1.086 60.078 1.00 40.00 O
+ATOM 4326 CB LEU C 181 -53.210 -1.820 59.340 1.00 40.00 C
+ATOM 4327 CG LEU C 181 -54.447 -2.163 60.175 1.00 40.00 C
+ATOM 4328 CD1 LEU C 181 -55.630 -2.475 59.294 1.00 40.00 C
+ATOM 4329 CD2 LEU C 181 -54.180 -3.323 61.104 1.00 40.00 C
+ATOM 4330 N TRP C 182 -50.839 0.113 58.371 1.00 40.00 N
+ATOM 4331 CA TRP C 182 -49.532 0.324 57.789 1.00 40.00 C
+ATOM 4332 C TRP C 182 -48.517 0.699 58.823 1.00 40.00 C
+ATOM 4333 O TRP C 182 -47.458 0.093 58.897 1.00 40.00 O
+ATOM 4334 CB TRP C 182 -49.596 1.378 56.719 1.00 40.00 C
+ATOM 4335 CG TRP C 182 -49.746 0.810 55.336 1.00 40.00 C
+ATOM 4336 CD1 TRP C 182 -50.799 0.060 54.830 1.00 40.00 C
+ATOM 4337 CD2 TRP C 182 -48.816 0.956 54.218 1.00 40.00 C
+ATOM 4338 NE1 TRP C 182 -50.586 -0.258 53.513 1.00 40.00 N
+ATOM 4339 CE2 TRP C 182 -49.417 0.248 53.086 1.00 40.00 C
+ATOM 4340 CE3 TRP C 182 -47.596 1.583 54.046 1.00 40.00 C
+ATOM 4341 CZ2 TRP C 182 -48.801 0.183 51.851 1.00 40.00 C
+ATOM 4342 CZ3 TRP C 182 -46.985 1.512 52.791 1.00 40.00 C
+ATOM 4343 CH2 TRP C 182 -47.574 0.827 51.721 1.00 40.00 C
+ATOM 4344 N LYS C 183 -48.836 1.688 59.649 1.00 40.00 N
+ATOM 4345 CA LYS C 183 -47.924 2.131 60.692 1.00 40.00 C
+ATOM 4346 C LYS C 183 -47.662 0.996 61.661 1.00 40.00 C
+ATOM 4347 O LYS C 183 -46.523 0.733 62.024 1.00 40.00 O
+ATOM 4348 CB LYS C 183 -48.497 3.346 61.436 1.00 40.00 C
+ATOM 4349 CG LYS C 183 -47.454 4.318 62.006 1.00 40.00 C
+ATOM 4350 CD LYS C 183 -47.932 5.102 63.245 1.00 40.00 C
+ATOM 4351 CE LYS C 183 -46.844 6.029 63.813 1.00 40.00 C
+ATOM 4352 NZ LYS C 183 -47.163 6.581 65.163 1.00 40.00 N
+ATOM 4353 N MET C 184 -48.727 0.312 62.051 1.00 40.00 N
+ATOM 4354 CA MET C 184 -48.638 -0.717 63.067 1.00 40.00 C
+ATOM 4355 C MET C 184 -47.807 -1.900 62.646 1.00 40.00 C
+ATOM 4356 O MET C 184 -47.003 -2.410 63.423 1.00 40.00 O
+ATOM 4357 CB MET C 184 -50.016 -1.227 63.407 1.00 40.00 C
+ATOM 4358 CG MET C 184 -50.865 -0.195 64.084 1.00 40.00 C
+ATOM 4359 SD MET C 184 -52.568 -0.614 63.780 1.00 40.00 S
+ATOM 4360 CE MET C 184 -52.758 -2.005 64.901 1.00 40.00 C
+ATOM 4361 N PHE C 185 -48.009 -2.346 61.416 1.00 40.00 N
+ATOM 4362 CA PHE C 185 -47.455 -3.609 61.020 1.00 40.00 C
+ATOM 4363 C PHE C 185 -46.429 -3.531 59.916 1.00 40.00 C
+ATOM 4364 O PHE C 185 -45.461 -4.277 59.921 1.00 40.00 O
+ATOM 4365 CB PHE C 185 -48.572 -4.548 60.636 1.00 40.00 C
+ATOM 4366 CG PHE C 185 -49.431 -4.957 61.787 1.00 40.00 C
+ATOM 4367 CD1 PHE C 185 -48.937 -5.796 62.780 1.00 40.00 C
+ATOM 4368 CD2 PHE C 185 -50.741 -4.518 61.874 1.00 40.00 C
+ATOM 4369 CE1 PHE C 185 -49.740 -6.185 63.841 1.00 40.00 C
+ATOM 4370 CE2 PHE C 185 -51.548 -4.903 62.931 1.00 40.00 C
+ATOM 4371 CZ PHE C 185 -51.050 -5.738 63.915 1.00 40.00 C
+ATOM 4372 N PHE C 186 -46.620 -2.641 58.962 1.00 40.00 N
+ATOM 4373 CA PHE C 186 -45.622 -2.531 57.911 1.00 40.00 C
+ATOM 4374 C PHE C 186 -44.371 -1.774 58.349 1.00 40.00 C
+ATOM 4375 O PHE C 186 -43.282 -2.055 57.862 1.00 40.00 O
+ATOM 4376 CB PHE C 186 -46.216 -1.923 56.633 1.00 40.00 C
+ATOM 4377 CG PHE C 186 -47.055 -2.890 55.818 1.00 40.00 C
+ATOM 4378 CD1 PHE C 186 -47.053 -4.260 56.109 1.00 40.00 C
+ATOM 4379 CD2 PHE C 186 -47.825 -2.431 54.737 1.00 40.00 C
+ATOM 4380 CE1 PHE C 186 -47.816 -5.143 55.363 1.00 40.00 C
+ATOM 4381 CE2 PHE C 186 -48.583 -3.314 53.990 1.00 40.00 C
+ATOM 4382 CZ PHE C 186 -48.577 -4.670 54.302 1.00 40.00 C
+ATOM 4383 N GLU C 187 -44.525 -0.847 59.295 1.00 40.00 N
+ATOM 4384 CA GLU C 187 -43.475 0.135 59.625 1.00 40.00 C
+ATOM 4385 C GLU C 187 -42.762 -0.051 60.983 1.00 40.00 C
+ATOM 4386 O GLU C 187 -43.348 -0.539 61.963 1.00 40.00 O
+ATOM 4387 CB GLU C 187 -44.027 1.563 59.470 1.00 40.00 C
+ATOM 4388 CG GLU C 187 -44.621 1.816 58.089 1.00 40.00 C
+ATOM 4389 CD GLU C 187 -45.361 3.129 57.965 1.00 40.00 C
+ATOM 4390 OE1 GLU C 187 -45.828 3.687 58.975 1.00 40.00 O
+ATOM 4391 OE2 GLU C 187 -45.487 3.605 56.829 1.00 40.00 O
+ATOM 4392 N LYS C 188 -41.480 0.328 61.002 1.00 40.00 N
+ATOM 4393 CA LYS C 188 -40.634 0.277 62.202 1.00 40.00 C
+ATOM 4394 C LYS C 188 -40.372 1.675 62.713 1.00 40.00 C
+ATOM 4395 O LYS C 188 -39.677 2.468 62.080 1.00 40.00 O
+ATOM 4396 CB LYS C 188 -39.287 -0.423 61.943 1.00 40.00 C
+ATOM 4397 CG LYS C 188 -39.384 -1.907 61.604 1.00 40.00 C
+ATOM 4398 CD LYS C 188 -39.918 -2.763 62.755 1.00 40.00 C
+ATOM 4399 CE LYS C 188 -40.284 -4.179 62.305 1.00 40.00 C
+ATOM 4400 NZ LYS C 188 -39.143 -4.922 61.687 1.00 40.00 N
+ATOM 4401 N HIS C 189 -40.941 1.965 63.870 1.00 40.00 N
+ATOM 4402 CA HIS C 189 -40.704 3.228 64.521 1.00 40.00 C
+ATOM 4403 C HIS C 189 -40.034 2.983 65.820 1.00 40.00 C
+ATOM 4404 O HIS C 189 -40.355 2.010 66.518 1.00 40.00 O
+ATOM 4405 CB HIS C 189 -42.012 3.953 64.726 1.00 40.00 C
+ATOM 4406 CG HIS C 189 -42.684 4.312 63.446 1.00 40.00 C
+ATOM 4407 ND1 HIS C 189 -42.669 5.560 62.949 1.00 40.00 N
+ATOM 4408 CD2 HIS C 189 -43.367 3.526 62.530 1.00 40.00 C
+ATOM 4409 CE1 HIS C 189 -43.331 5.581 61.784 1.00 40.00 C
+ATOM 4410 NE2 HIS C 189 -43.754 4.332 61.525 1.00 40.00 N
+ATOM 4411 N ASP C 190 -39.086 3.856 66.148 1.00 40.00 N
+ATOM 4412 CA ASP C 190 -38.360 3.770 67.404 1.00 40.00 C
+ATOM 4413 C ASP C 190 -39.260 4.189 68.550 1.00 40.00 C
+ATOM 4414 O ASP C 190 -39.270 3.551 69.592 1.00 40.00 O
+ATOM 4415 CB ASP C 190 -37.103 4.624 67.332 1.00 40.00 C
+ATOM 4416 CG ASP C 190 -36.256 4.279 66.128 1.00 40.00 C
+ATOM 4417 OD1 ASP C 190 -35.773 3.127 66.055 1.00 40.00 O
+ATOM 4418 OD2 ASP C 190 -36.097 5.148 65.247 1.00 40.00 O
+ATOM 4419 N ASP C 191 -40.044 5.240 68.328 1.00 40.00 N
+ATOM 4420 CA ASP C 191 -41.009 5.723 69.317 1.00 40.00 C
+ATOM 4421 C ASP C 191 -42.292 4.905 69.364 1.00 40.00 C
+ATOM 4422 O ASP C 191 -43.088 5.023 70.286 1.00 40.00 O
+ATOM 4423 CB ASP C 191 -41.349 7.201 69.069 1.00 40.00 C
+ATOM 4424 CG ASP C 191 -41.728 7.487 67.634 1.00 40.00 C
+ATOM 4425 OD1 ASP C 191 -40.908 7.202 66.736 1.00 40.00 O
+ATOM 4426 OD2 ASP C 191 -42.834 8.019 67.410 1.00 40.00 O
+ATOM 4427 N TYR C 192 -42.495 4.071 68.363 1.00 40.00 N
+ATOM 4428 CA TYR C 192 -43.752 3.370 68.254 1.00 40.00 C
+ATOM 4429 C TYR C 192 -43.630 1.923 67.750 1.00 40.00 C
+ATOM 4430 O TYR C 192 -43.355 1.657 66.571 1.00 40.00 O
+ATOM 4431 CB TYR C 192 -44.743 4.185 67.408 1.00 40.00 C
+ATOM 4432 CG TYR C 192 -46.143 3.679 67.564 1.00 40.00 C
+ATOM 4433 CD1 TYR C 192 -46.815 3.823 68.770 1.00 40.00 C
+ATOM 4434 CD2 TYR C 192 -46.783 3.011 66.527 1.00 40.00 C
+ATOM 4435 CE1 TYR C 192 -48.097 3.331 68.935 1.00 40.00 C
+ATOM 4436 CE2 TYR C 192 -48.066 2.519 66.681 1.00 40.00 C
+ATOM 4437 CZ TYR C 192 -48.714 2.684 67.886 1.00 40.00 C
+ATOM 4438 OH TYR C 192 -49.979 2.196 68.060 1.00 40.00 O
+ATOM 4439 N LYS C 193 -43.821 0.989 68.670 1.00 40.00 N
+ATOM 4440 CA LYS C 193 -43.969 -0.402 68.306 1.00 40.00 C
+ATOM 4441 C LYS C 193 -45.244 -0.899 68.964 1.00 40.00 C
+ATOM 4442 O LYS C 193 -45.420 -0.786 70.181 1.00 40.00 O
+ATOM 4443 CB LYS C 193 -42.761 -1.223 68.750 1.00 40.00 C
+ATOM 4444 CG LYS C 193 -41.426 -0.735 68.204 1.00 40.00 C
+ATOM 4445 CD LYS C 193 -40.254 -1.252 69.035 1.00 40.00 C
+ATOM 4446 CE LYS C 193 -40.320 -0.835 70.507 1.00 40.00 C
+ATOM 4447 NZ LYS C 193 -40.254 0.640 70.725 1.00 40.00 N
+ATOM 4448 N PHE C 194 -46.147 -1.413 68.138 1.00 40.00 N
+ATOM 4449 CA PHE C 194 -47.423 -1.924 68.600 1.00 40.00 C
+ATOM 4450 C PHE C 194 -47.244 -3.324 69.159 1.00 40.00 C
+ATOM 4451 O PHE C 194 -46.361 -4.058 68.731 1.00 40.00 O
+ATOM 4452 CB PHE C 194 -48.425 -1.921 67.445 1.00 40.00 C
+ATOM 4453 CG PHE C 194 -49.781 -2.420 67.822 1.00 40.00 C
+ATOM 4454 CD1 PHE C 194 -50.628 -1.651 68.593 1.00 40.00 C
+ATOM 4455 CD2 PHE C 194 -50.210 -3.667 67.412 1.00 40.00 C
+ATOM 4456 CE1 PHE C 194 -51.880 -2.121 68.954 1.00 40.00 C
+ATOM 4457 CE2 PHE C 194 -51.467 -4.143 67.762 1.00 40.00 C
+ATOM 4458 CZ PHE C 194 -52.306 -3.365 68.534 1.00 40.00 C
+ATOM 4459 N ASN C 195 -48.072 -3.682 70.131 1.00 40.00 N
+ATOM 4460 CA ASN C 195 -48.074 -5.034 70.676 1.00 40.00 C
+ATOM 4461 C ASN C 195 -49.366 -5.358 71.447 1.00 40.00 C
+ATOM 4462 O ASN C 195 -49.339 -5.976 72.515 1.00 40.00 O
+ATOM 4463 CB ASN C 195 -46.815 -5.280 71.528 1.00 40.00 C
+ATOM 4464 CG ASN C 195 -46.470 -6.763 71.670 1.00 40.00 C
+ATOM 4465 OD1 ASN C 195 -45.833 -7.164 72.651 1.00 40.00 O
+ATOM 4466 ND2 ASN C 195 -46.883 -7.585 70.692 1.00 40.00 N
+ATOM 4467 N GLY C 196 -50.496 -4.925 70.895 1.00 40.00 N
+ATOM 4468 CA GLY C 196 -51.811 -5.301 71.416 1.00 40.00 C
+ATOM 4469 C GLY C 196 -52.510 -6.241 70.440 1.00 40.00 C
+ATOM 4470 O GLY C 196 -51.905 -7.213 69.952 1.00 40.00 O
+ATOM 4471 N LEU C 197 -53.777 -5.945 70.148 1.00 40.00 N
+ATOM 4472 CA LEU C 197 -54.571 -6.751 69.229 1.00 40.00 C
+ATOM 4473 C LEU C 197 -55.365 -5.882 68.280 1.00 40.00 C
+ATOM 4474 O LEU C 197 -56.271 -5.170 68.698 1.00 40.00 O
+ATOM 4475 CB LEU C 197 -55.527 -7.657 69.999 1.00 40.00 C
+ATOM 4476 CG LEU C 197 -56.495 -8.415 69.099 1.00 40.00 C
+ATOM 4477 CD1 LEU C 197 -55.826 -9.634 68.460 1.00 40.00 C
+ATOM 4478 CD2 LEU C 197 -57.733 -8.796 69.899 1.00 40.00 C
+ATOM 4479 N GLY C 198 -55.027 -5.954 67.000 1.00 40.00 N
+ATOM 4480 CA GLY C 198 -55.754 -5.215 65.977 1.00 40.00 C
+ATOM 4481 C GLY C 198 -56.840 -6.053 65.329 1.00 40.00 C
+ATOM 4482 O GLY C 198 -56.545 -6.917 64.508 1.00 40.00 O
+ATOM 4483 N TRP C 199 -58.097 -5.804 65.695 1.00 40.00 N
+ATOM 4484 CA TRP C 199 -59.223 -6.533 65.113 1.00 40.00 C
+ATOM 4485 C TRP C 199 -59.964 -5.665 64.162 1.00 40.00 C
+ATOM 4486 O TRP C 199 -60.401 -4.573 64.527 1.00 40.00 O
+ATOM 4487 CB TRP C 199 -60.186 -7.035 66.182 1.00 40.00 C
+ATOM 4488 CG TRP C 199 -60.897 -8.337 65.837 1.00 40.00 C
+ATOM 4489 CD1 TRP C 199 -61.046 -8.919 64.582 1.00 40.00 C
+ATOM 4490 CD2 TRP C 199 -61.603 -9.256 66.761 1.00 40.00 C
+ATOM 4491 NE1 TRP C 199 -61.753 -10.092 64.662 1.00 40.00 N
+ATOM 4492 CE2 TRP C 199 -62.120 -10.351 65.934 1.00 40.00 C
+ATOM 4493 CE3 TRP C 199 -61.844 -9.279 68.138 1.00 40.00 C
+ATOM 4494 CZ2 TRP C 199 -62.847 -11.405 66.479 1.00 40.00 C
+ATOM 4495 CZ3 TRP C 199 -62.571 -10.353 68.678 1.00 40.00 C
+ATOM 4496 CH2 TRP C 199 -63.060 -11.389 67.867 1.00 40.00 C
+ATOM 4497 N LEU C 200 -60.122 -6.165 62.936 1.00 40.00 N
+ATOM 4498 CA LEU C 200 -60.765 -5.430 61.846 1.00 40.00 C
+ATOM 4499 C LEU C 200 -61.991 -6.107 61.241 1.00 40.00 C
+ATOM 4500 O LEU C 200 -61.940 -7.261 60.787 1.00 40.00 O
+ATOM 4501 CB LEU C 200 -59.769 -5.151 60.731 1.00 40.00 C
+ATOM 4502 CG LEU C 200 -60.379 -4.613 59.440 1.00 40.00 C
+ATOM 4503 CD1 LEU C 200 -61.115 -3.295 59.646 1.00 40.00 C
+ATOM 4504 CD2 LEU C 200 -59.280 -4.468 58.408 1.00 40.00 C
+ATOM 4505 N PHE C 201 -63.078 -5.346 61.207 1.00 40.00 N
+ATOM 4506 CA PHE C 201 -64.310 -5.777 60.591 1.00 40.00 C
+ATOM 4507 C PHE C 201 -64.603 -4.868 59.399 1.00 40.00 C
+ATOM 4508 O PHE C 201 -64.741 -3.652 59.554 1.00 40.00 O
+ATOM 4509 CB PHE C 201 -65.450 -5.734 61.616 1.00 40.00 C
+ATOM 4510 CG PHE C 201 -65.383 -6.827 62.665 1.00 40.00 C
+ATOM 4511 CD1 PHE C 201 -64.445 -6.783 63.693 1.00 40.00 C
+ATOM 4512 CD2 PHE C 201 -66.279 -7.898 62.638 1.00 40.00 C
+ATOM 4513 CE1 PHE C 201 -64.395 -7.790 64.656 1.00 40.00 C
+ATOM 4514 CE2 PHE C 201 -66.237 -8.905 63.604 1.00 40.00 C
+ATOM 4515 CZ PHE C 201 -65.294 -8.852 64.613 1.00 40.00 C
+ATOM 4516 N LEU C 202 -64.667 -5.471 58.210 1.00 40.00 N
+ATOM 4517 CA LEU C 202 -64.990 -4.753 56.978 1.00 40.00 C
+ATOM 4518 C LEU C 202 -66.097 -5.377 56.150 1.00 40.00 C
+ATOM 4519 O LEU C 202 -65.958 -6.489 55.628 1.00 40.00 O
+ATOM 4520 CB LEU C 202 -63.774 -4.604 56.087 1.00 40.00 C
+ATOM 4521 CG LEU C 202 -64.180 -4.177 54.673 1.00 40.00 C
+ATOM 4522 CD1 LEU C 202 -64.604 -2.702 54.588 1.00 40.00 C
+ATOM 4523 CD2 LEU C 202 -63.042 -4.509 53.724 1.00 40.00 C
+ATOM 4524 N GLY C 203 -67.170 -4.613 55.988 1.00 40.00 N
+ATOM 4525 CA GLY C 203 -68.365 -5.072 55.299 1.00 40.00 C
+ATOM 4526 C GLY C 203 -68.535 -4.415 53.949 1.00 40.00 C
+ATOM 4527 O GLY C 203 -68.418 -3.194 53.817 1.00 40.00 O
+ATOM 4528 N VAL C 204 -68.815 -5.243 52.947 1.00 40.00 N
+ATOM 4529 CA VAL C 204 -68.987 -4.796 51.564 1.00 40.00 C
+ATOM 4530 C VAL C 204 -70.073 -5.591 50.847 1.00 40.00 C
+ATOM 4531 O VAL C 204 -70.547 -6.610 51.364 1.00 40.00 O
+ATOM 4532 CB VAL C 204 -67.695 -4.947 50.719 1.00 40.00 C
+ATOM 4533 CG1 VAL C 204 -66.785 -3.744 50.890 1.00 40.00 C
+ATOM 4534 CG2 VAL C 204 -66.980 -6.266 51.010 1.00 40.00 C
+ATOM 4535 N PRO C 205 -70.467 -5.126 49.645 1.00 40.00 N
+ATOM 4536 CA PRO C 205 -71.365 -5.875 48.748 1.00 40.00 C
+ATOM 4537 C PRO C 205 -70.840 -7.231 48.188 1.00 40.00 C
+ATOM 4538 O PRO C 205 -71.480 -8.271 48.365 1.00 40.00 O
+ATOM 4539 CB PRO C 205 -71.610 -4.877 47.598 1.00 40.00 C
+ATOM 4540 CG PRO C 205 -70.552 -3.821 47.725 1.00 40.00 C
+ATOM 4541 CD PRO C 205 -70.286 -3.728 49.194 1.00 40.00 C
+ATOM 4542 N THR C 206 -69.696 -7.201 47.513 1.00 40.00 N
+ATOM 4543 CA THR C 206 -69.220 -8.336 46.735 1.00 40.00 C
+ATOM 4544 C THR C 206 -67.819 -8.752 47.137 1.00 40.00 C
+ATOM 4545 O THR C 206 -67.154 -8.047 47.879 1.00 40.00 O
+ATOM 4546 CB THR C 206 -69.162 -7.971 45.249 1.00 40.00 C
+ATOM 4547 OG1 THR C 206 -68.452 -6.733 45.087 1.00 40.00 O
+ATOM 4548 CG2 THR C 206 -70.554 -7.832 44.690 1.00 40.00 C
+ATOM 4549 N SER C 207 -67.373 -9.902 46.644 1.00 40.00 N
+ATOM 4550 CA SER C 207 -65.972 -10.295 46.763 1.00 40.00 C
+ATOM 4551 C SER C 207 -65.131 -9.472 45.809 1.00 40.00 C
+ATOM 4552 O SER C 207 -63.908 -9.533 45.842 1.00 40.00 O
+ATOM 4553 CB SER C 207 -65.786 -11.782 46.463 1.00 40.00 C
+ATOM 4554 OG SER C 207 -66.038 -12.575 47.610 1.00 40.00 O
+ATOM 4555 N SER C 208 -65.810 -8.710 44.957 1.00 40.00 N
+ATOM 4556 CA SER C 208 -65.165 -7.803 44.014 1.00 40.00 C
+ATOM 4557 C SER C 208 -65.034 -6.405 44.594 1.00 40.00 C
+ATOM 4558 O SER C 208 -64.231 -5.613 44.107 1.00 40.00 O
+ATOM 4559 CB SER C 208 -65.924 -7.741 42.679 1.00 40.00 C
+ATOM 4560 OG SER C 208 -67.178 -7.087 42.817 1.00 40.00 O
+ATOM 4561 N SER C 209 -65.828 -6.104 45.620 1.00 40.00 N
+ATOM 4562 CA SER C 209 -65.718 -4.826 46.333 1.00 40.00 C
+ATOM 4563 C SER C 209 -64.754 -4.892 47.547 1.00 40.00 C
+ATOM 4564 O SER C 209 -64.613 -3.928 48.305 1.00 40.00 O
+ATOM 4565 CB SER C 209 -67.105 -4.326 46.761 1.00 40.00 C
+ATOM 4566 OG SER C 209 -67.974 -4.181 45.653 1.00 40.00 O
+ATOM 4567 N LEU C 210 -64.074 -6.024 47.702 1.00 40.00 N
+ATOM 4568 CA LEU C 210 -63.244 -6.305 48.877 1.00 40.00 C
+ATOM 4569 C LEU C 210 -61.841 -5.649 48.800 1.00 40.00 C
+ATOM 4570 O LEU C 210 -60.876 -6.252 48.316 1.00 40.00 O
+ATOM 4571 CB LEU C 210 -63.147 -7.830 49.052 1.00 40.00 C
+ATOM 4572 CG LEU C 210 -63.103 -8.506 50.424 1.00 40.00 C
+ATOM 4573 CD1 LEU C 210 -64.430 -8.400 51.156 1.00 40.00 C
+ATOM 4574 CD2 LEU C 210 -62.713 -9.963 50.255 1.00 40.00 C
+ATOM 4575 N LEU C 211 -61.736 -4.422 49.306 1.00 40.00 N
+ATOM 4576 CA LEU C 211 -60.522 -3.603 49.166 1.00 40.00 C
+ATOM 4577 C LEU C 211 -59.254 -4.123 49.895 1.00 40.00 C
+ATOM 4578 O LEU C 211 -59.331 -4.705 50.969 1.00 40.00 O
+ATOM 4579 CB LEU C 211 -60.833 -2.146 49.564 1.00 40.00 C
+ATOM 4580 CG LEU C 211 -62.145 -1.471 49.125 1.00 40.00 C
+ATOM 4581 CD1 LEU C 211 -62.313 -0.115 49.786 1.00 40.00 C
+ATOM 4582 CD2 LEU C 211 -62.231 -1.312 47.621 1.00 40.00 C
+ATOM 4583 N TYR C 212 -58.097 -3.928 49.267 1.00 40.00 N
+ATOM 4584 CA TYR C 212 -56.783 -4.133 49.887 1.00 40.00 C
+ATOM 4585 C TYR C 212 -56.508 -5.496 50.536 1.00 40.00 C
+ATOM 4586 O TYR C 212 -55.508 -5.646 51.236 1.00 40.00 O
+ATOM 4587 CB TYR C 212 -56.511 -3.036 50.920 1.00 40.00 C
+ATOM 4588 CG TYR C 212 -56.798 -1.621 50.472 1.00 40.00 C
+ATOM 4589 CD1 TYR C 212 -55.823 -0.856 49.840 1.00 40.00 C
+ATOM 4590 CD2 TYR C 212 -58.026 -1.036 50.719 1.00 40.00 C
+ATOM 4591 CE1 TYR C 212 -56.077 0.441 49.441 1.00 40.00 C
+ATOM 4592 CE2 TYR C 212 -58.293 0.256 50.321 1.00 40.00 C
+ATOM 4593 CZ TYR C 212 -57.315 0.990 49.686 1.00 40.00 C
+ATOM 4594 OH TYR C 212 -57.583 2.281 49.295 1.00 40.00 O
+ATOM 4595 N LYS C 213 -57.371 -6.481 50.289 1.00 40.00 N
+ATOM 4596 CA LYS C 213 -57.327 -7.806 50.959 1.00 40.00 C
+ATOM 4597 C LYS C 213 -55.953 -8.504 51.050 1.00 40.00 C
+ATOM 4598 O LYS C 213 -55.599 -9.012 52.117 1.00 40.00 O
+ATOM 4599 CB LYS C 213 -58.376 -8.747 50.343 1.00 40.00 C
+ATOM 4600 CG LYS C 213 -58.310 -10.212 50.773 1.00 40.00 C
+ATOM 4601 CD LYS C 213 -59.049 -11.103 49.775 1.00 40.00 C
+ATOM 4602 CE LYS C 213 -58.738 -12.585 49.945 1.00 40.00 C
+ATOM 4603 NZ LYS C 213 -59.547 -13.251 51.004 1.00 40.00 N
+ATOM 4604 N GLU C 214 -55.203 -8.533 49.942 1.00 40.00 N
+ATOM 4605 CA GLU C 214 -53.857 -9.168 49.882 1.00 40.00 C
+ATOM 4606 C GLU C 214 -52.842 -8.451 50.784 1.00 40.00 C
+ATOM 4607 O GLU C 214 -51.827 -9.034 51.176 1.00 40.00 O
+ATOM 4608 CB GLU C 214 -53.275 -9.237 48.446 1.00 40.00 C
+ATOM 4609 CG GLU C 214 -54.242 -8.988 47.297 1.00 40.00 C
+ATOM 4610 CD GLU C 214 -54.952 -7.636 47.401 1.00 40.00 C
+ATOM 4611 OE1 GLU C 214 -54.374 -6.660 47.959 1.00 40.00 O
+ATOM 4612 OE2 GLU C 214 -56.113 -7.556 46.938 1.00 40.00 O
+ATOM 4613 N GLU C 215 -53.107 -7.185 51.091 1.00 40.00 N
+ATOM 4614 CA GLU C 215 -52.263 -6.443 51.995 1.00 40.00 C
+ATOM 4615 C GLU C 215 -52.486 -6.969 53.390 1.00 40.00 C
+ATOM 4616 O GLU C 215 -51.577 -7.487 54.013 1.00 40.00 O
+ATOM 4617 CB GLU C 215 -52.587 -4.959 51.921 1.00 40.00 C
+ATOM 4618 CG GLU C 215 -52.154 -4.306 50.619 1.00 40.00 C
+ATOM 4619 CD GLU C 215 -52.280 -2.791 50.646 1.00 40.00 C
+ATOM 4620 OE1 GLU C 215 -52.327 -2.185 51.739 1.00 40.00 O
+ATOM 4621 OE2 GLU C 215 -52.331 -2.194 49.556 1.00 40.00 O
+ATOM 4622 N PHE C 216 -53.718 -6.857 53.862 1.00 40.00 N
+ATOM 4623 CA PHE C 216 -54.071 -7.365 55.173 1.00 40.00 C
+ATOM 4624 C PHE C 216 -53.679 -8.823 55.299 1.00 40.00 C
+ATOM 4625 O PHE C 216 -53.290 -9.276 56.372 1.00 40.00 O
+ATOM 4626 CB PHE C 216 -55.568 -7.237 55.405 1.00 40.00 C
+ATOM 4627 CG PHE C 216 -56.116 -5.880 55.091 1.00 40.00 C
+ATOM 4628 CD1 PHE C 216 -55.735 -4.778 55.837 1.00 40.00 C
+ATOM 4629 CD2 PHE C 216 -57.029 -5.705 54.056 1.00 40.00 C
+ATOM 4630 CE1 PHE C 216 -56.243 -3.519 55.553 1.00 40.00 C
+ATOM 4631 CE2 PHE C 216 -57.543 -4.449 53.771 1.00 40.00 C
+ATOM 4632 CZ PHE C 216 -57.147 -3.352 54.521 1.00 40.00 C
+ATOM 4633 N GLY C 217 -53.814 -9.558 54.198 1.00 40.00 N
+ATOM 4634 CA GLY C 217 -53.293 -10.912 54.114 1.00 40.00 C
+ATOM 4635 C GLY C 217 -51.851 -10.910 54.586 1.00 40.00 C
+ATOM 4636 O GLY C 217 -51.530 -11.515 55.616 1.00 40.00 O
+ATOM 4637 N LYS C 218 -50.996 -10.185 53.858 1.00 40.00 N
+ATOM 4638 CA LYS C 218 -49.560 -10.100 54.169 1.00 40.00 C
+ATOM 4639 C LYS C 218 -49.304 -9.705 55.630 1.00 40.00 C
+ATOM 4640 O LYS C 218 -48.277 -10.071 56.218 1.00 40.00 O
+ATOM 4641 CB LYS C 218 -48.847 -9.133 53.210 1.00 40.00 C
+ATOM 4642 CG LYS C 218 -48.689 -9.661 51.785 1.00 40.00 C
+ATOM 4643 CD LYS C 218 -47.932 -8.694 50.872 1.00 40.00 C
+ATOM 4644 CE LYS C 218 -48.839 -7.669 50.191 1.00 40.00 C
+ATOM 4645 NZ LYS C 218 -48.065 -6.833 49.228 1.00 40.00 N
+ATOM 4646 N MET C 219 -50.257 -8.972 56.202 1.00 40.00 N
+ATOM 4647 CA MET C 219 -50.195 -8.552 57.590 1.00 40.00 C
+ATOM 4648 C MET C 219 -50.487 -9.728 58.501 1.00 40.00 C
+ATOM 4649 O MET C 219 -49.641 -10.120 59.305 1.00 40.00 O
+ATOM 4650 CB MET C 219 -51.199 -7.434 57.841 1.00 40.00 C
+ATOM 4651 CG MET C 219 -51.043 -6.257 56.896 1.00 40.00 C
+ATOM 4652 SD MET C 219 -51.644 -4.733 57.631 1.00 40.00 S
+ATOM 4653 CE MET C 219 -51.254 -3.579 56.313 1.00 40.00 C
+ATOM 4654 N LYS C 220 -51.685 -10.290 58.356 1.00 40.00 N
+ATOM 4655 CA LYS C 220 -52.101 -11.473 59.101 1.00 40.00 C
+ATOM 4656 C LYS C 220 -51.044 -12.559 59.011 1.00 40.00 C
+ATOM 4657 O LYS C 220 -50.943 -13.419 59.886 1.00 40.00 O
+ATOM 4658 CB LYS C 220 -53.432 -11.990 58.552 1.00 40.00 C
+ATOM 4659 CG LYS C 220 -53.931 -13.274 59.194 1.00 40.00 C
+ATOM 4660 CD LYS C 220 -54.262 -13.065 60.658 1.00 40.00 C
+ATOM 4661 CE LYS C 220 -54.685 -14.368 61.303 1.00 40.00 C
+ATOM 4662 NZ LYS C 220 -54.931 -14.153 62.749 1.00 40.00 N
+ATOM 4663 N GLU C 221 -50.254 -12.498 57.944 1.00 40.00 N
+ATOM 4664 CA GLU C 221 -49.194 -13.465 57.715 1.00 40.00 C
+ATOM 4665 C GLU C 221 -47.900 -13.138 58.483 1.00 40.00 C
+ATOM 4666 O GLU C 221 -47.156 -14.053 58.859 1.00 40.00 O
+ATOM 4667 CB GLU C 221 -48.917 -13.626 56.220 1.00 40.00 C
+ATOM 4668 CG GLU C 221 -48.288 -14.962 55.855 1.00 40.00 C
+ATOM 4669 CD GLU C 221 -47.477 -14.880 54.589 1.00 40.00 C
+ATOM 4670 OE1 GLU C 221 -47.949 -14.239 53.626 1.00 40.00 O
+ATOM 4671 OE2 GLU C 221 -46.368 -15.450 54.565 1.00 40.00 O
+ATOM 4672 N ARG C 222 -47.617 -11.860 58.722 1.00 40.00 N
+ATOM 4673 CA ARG C 222 -46.439 -11.528 59.519 1.00 40.00 C
+ATOM 4674 C ARG C 222 -46.753 -11.171 60.969 1.00 40.00 C
+ATOM 4675 O ARG C 222 -45.840 -10.987 61.756 1.00 40.00 O
+ATOM 4676 CB ARG C 222 -45.563 -10.473 58.841 1.00 40.00 C
+ATOM 4677 CG ARG C 222 -46.318 -9.305 58.244 1.00 40.00 C
+ATOM 4678 CD ARG C 222 -45.437 -8.605 57.233 1.00 40.00 C
+ATOM 4679 NE ARG C 222 -44.316 -7.933 57.887 1.00 40.00 N
+ATOM 4680 CZ ARG C 222 -43.426 -7.158 57.268 1.00 40.00 C
+ATOM 4681 NH1 ARG C 222 -43.499 -6.939 55.958 1.00 40.00 N
+ATOM 4682 NH2 ARG C 222 -42.451 -6.592 57.963 1.00 40.00 N
+ATOM 4683 N ALA C 223 -48.033 -11.101 61.325 1.00 40.00 N
+ATOM 4684 CA ALA C 223 -48.428 -10.907 62.725 1.00 40.00 C
+ATOM 4685 C ALA C 223 -49.727 -11.634 63.084 1.00 40.00 C
+ATOM 4686 O ALA C 223 -50.747 -11.005 63.361 1.00 40.00 O
+ATOM 4687 CB ALA C 223 -48.525 -9.429 63.056 1.00 40.00 C
+ATOM 4688 N PRO C 224 -49.683 -12.972 63.103 1.00 40.00 N
+ATOM 4689 CA PRO C 224 -50.866 -13.826 63.235 1.00 40.00 C
+ATOM 4690 C PRO C 224 -51.702 -13.582 64.485 1.00 40.00 C
+ATOM 4691 O PRO C 224 -52.929 -13.594 64.401 1.00 40.00 O
+ATOM 4692 CB PRO C 224 -50.282 -15.241 63.270 1.00 40.00 C
+ATOM 4693 CG PRO C 224 -48.845 -15.070 63.626 1.00 40.00 C
+ATOM 4694 CD PRO C 224 -48.441 -13.759 63.037 1.00 40.00 C
+ATOM 4695 N GLU C 225 -51.047 -13.372 65.627 1.00 40.00 N
+ATOM 4696 CA GLU C 225 -51.765 -13.157 66.898 1.00 40.00 C
+ATOM 4697 C GLU C 225 -52.083 -11.685 67.181 1.00 40.00 C
+ATOM 4698 O GLU C 225 -53.025 -11.382 67.928 1.00 40.00 O
+ATOM 4699 CB GLU C 225 -51.025 -13.776 68.096 1.00 40.00 C
+ATOM 4700 CG GLU C 225 -49.642 -13.211 68.345 1.00 40.00 C
+ATOM 4701 CD GLU C 225 -48.554 -14.141 67.861 1.00 40.00 C
+ATOM 4702 OE1 GLU C 225 -48.673 -14.689 66.746 1.00 40.00 O
+ATOM 4703 OE2 GLU C 225 -47.577 -14.328 68.610 1.00 40.00 O
+ATOM 4704 N ASN C 226 -51.297 -10.788 66.583 1.00 40.00 N
+ATOM 4705 CA ASN C 226 -51.452 -9.341 66.775 1.00 40.00 C
+ATOM 4706 C ASN C 226 -52.446 -8.710 65.798 1.00 40.00 C
+ATOM 4707 O ASN C 226 -52.762 -7.512 65.894 1.00 40.00 O
+ATOM 4708 CB ASN C 226 -50.095 -8.646 66.674 1.00 40.00 C
+ATOM 4709 CG ASN C 226 -49.067 -9.252 67.604 1.00 40.00 C
+ATOM 4710 OD1 ASN C 226 -49.105 -9.044 68.820 1.00 40.00 O
+ATOM 4711 ND2 ASN C 226 -48.145 -10.018 67.035 1.00 40.00 N
+ATOM 4712 N PHE C 227 -52.934 -9.532 64.870 1.00 40.00 N
+ATOM 4713 CA PHE C 227 -53.906 -9.115 63.869 1.00 40.00 C
+ATOM 4714 C PHE C 227 -54.972 -10.183 63.683 1.00 40.00 C
+ATOM 4715 O PHE C 227 -54.682 -11.378 63.644 1.00 40.00 O
+ATOM 4716 CB PHE C 227 -53.201 -8.822 62.542 1.00 40.00 C
+ATOM 4717 CG PHE C 227 -54.075 -8.163 61.500 1.00 40.00 C
+ATOM 4718 CD1 PHE C 227 -55.058 -7.238 61.852 1.00 40.00 C
+ATOM 4719 CD2 PHE C 227 -53.872 -8.433 60.147 1.00 40.00 C
+ATOM 4720 CE1 PHE C 227 -55.841 -6.631 60.880 1.00 40.00 C
+ATOM 4721 CE2 PHE C 227 -54.643 -7.816 59.169 1.00 40.00 C
+ATOM 4722 CZ PHE C 227 -55.631 -6.916 59.537 1.00 40.00 C
+ATOM 4723 N ARG C 228 -56.211 -9.728 63.589 1.00 40.00 N
+ATOM 4724 CA ARG C 228 -57.340 -10.587 63.332 1.00 40.00 C
+ATOM 4725 C ARG C 228 -58.215 -9.853 62.328 1.00 40.00 C
+ATOM 4726 O ARG C 228 -58.568 -8.698 62.552 1.00 40.00 O
+ATOM 4727 CB ARG C 228 -58.094 -10.864 64.636 1.00 40.00 C
+ATOM 4728 CG ARG C 228 -57.324 -11.720 65.638 1.00 40.00 C
+ATOM 4729 CD ARG C 228 -58.196 -12.158 66.810 1.00 40.00 C
+ATOM 4730 NE ARG C 228 -59.360 -12.940 66.378 1.00 40.00 N
+ATOM 4731 CZ ARG C 228 -60.306 -13.437 67.181 1.00 40.00 C
+ATOM 4732 NH1 ARG C 228 -60.265 -13.246 68.497 1.00 40.00 N
+ATOM 4733 NH2 ARG C 228 -61.315 -14.131 66.658 1.00 40.00 N
+ATOM 4734 N VAL C 229 -58.532 -10.494 61.205 1.00 40.00 N
+ATOM 4735 CA VAL C 229 -59.426 -9.886 60.220 1.00 40.00 C
+ATOM 4736 C VAL C 229 -60.704 -10.675 60.083 1.00 40.00 C
+ATOM 4737 O VAL C 229 -60.744 -11.867 60.360 1.00 40.00 O
+ATOM 4738 CB VAL C 229 -58.805 -9.828 58.828 1.00 40.00 C
+ATOM 4739 CG1 VAL C 229 -59.325 -8.610 58.084 1.00 40.00 C
+ATOM 4740 CG2 VAL C 229 -57.295 -9.812 58.929 1.00 40.00 C
+ATOM 4741 N ASP C 230 -61.750 -9.993 59.645 1.00 40.00 N
+ATOM 4742 CA ASP C 230 -63.021 -10.624 59.382 1.00 40.00 C
+ATOM 4743 C ASP C 230 -63.693 -9.797 58.322 1.00 40.00 C
+ATOM 4744 O ASP C 230 -63.754 -8.573 58.457 1.00 40.00 O
+ATOM 4745 CB ASP C 230 -63.878 -10.630 60.644 1.00 40.00 C
+ATOM 4746 CG ASP C 230 -63.542 -11.780 61.566 1.00 40.00 C
+ATOM 4747 OD1 ASP C 230 -64.153 -12.855 61.407 1.00 40.00 O
+ATOM 4748 OD2 ASP C 230 -62.674 -11.612 62.449 1.00 40.00 O
+ATOM 4749 N TYR C 231 -64.182 -10.449 57.266 1.00 40.00 N
+ATOM 4750 CA TYR C 231 -64.920 -9.750 56.226 1.00 40.00 C
+ATOM 4751 C TYR C 231 -66.376 -10.139 56.282 1.00 40.00 C
+ATOM 4752 O TYR C 231 -66.725 -11.166 56.859 1.00 40.00 O
+ATOM 4753 CB TYR C 231 -64.356 -10.066 54.860 1.00 40.00 C
+ATOM 4754 CG TYR C 231 -62.884 -9.803 54.746 1.00 40.00 C
+ATOM 4755 CD1 TYR C 231 -61.955 -10.748 55.175 1.00 40.00 C
+ATOM 4756 CD2 TYR C 231 -62.408 -8.611 54.199 1.00 40.00 C
+ATOM 4757 CE1 TYR C 231 -60.587 -10.513 55.061 1.00 40.00 C
+ATOM 4758 CE2 TYR C 231 -61.039 -8.368 54.076 1.00 40.00 C
+ATOM 4759 CZ TYR C 231 -60.131 -9.321 54.506 1.00 40.00 C
+ATOM 4760 OH TYR C 231 -58.780 -9.088 54.379 1.00 40.00 O
+ATOM 4761 N ALA C 232 -67.222 -9.298 55.697 1.00 40.00 N
+ATOM 4762 CA ALA C 232 -68.665 -9.534 55.656 1.00 40.00 C
+ATOM 4763 C ALA C 232 -69.214 -9.140 54.291 1.00 40.00 C
+ATOM 4764 O ALA C 232 -69.485 -7.964 54.023 1.00 40.00 O
+ATOM 4765 CB ALA C 232 -69.377 -8.772 56.772 1.00 40.00 C
+ATOM 4766 N VAL C 233 -69.349 -10.136 53.422 1.00 40.00 N
+ATOM 4767 CA VAL C 233 -69.861 -9.918 52.080 1.00 40.00 C
+ATOM 4768 C VAL C 233 -71.377 -10.126 52.108 1.00 40.00 C
+ATOM 4769 O VAL C 233 -71.866 -11.257 52.197 1.00 40.00 O
+ATOM 4770 CB VAL C 233 -69.169 -10.832 51.041 1.00 40.00 C
+ATOM 4771 CG1 VAL C 233 -69.240 -10.199 49.661 1.00 40.00 C
+ATOM 4772 CG2 VAL C 233 -67.712 -11.093 51.416 1.00 40.00 C
+ATOM 4773 N SER C 234 -72.107 -9.013 52.054 1.00 40.00 N
+ATOM 4774 CA SER C 234 -73.566 -9.013 52.182 1.00 40.00 C
+ATOM 4775 C SER C 234 -74.268 -9.823 51.087 1.00 40.00 C
+ATOM 4776 O SER C 234 -75.294 -10.460 51.339 1.00 40.00 O
+ATOM 4777 CB SER C 234 -74.124 -7.578 52.256 1.00 40.00 C
+ATOM 4778 OG SER C 234 -74.119 -6.898 51.005 1.00 40.00 O
+ATOM 4779 N ARG C 235 -73.700 -9.816 49.883 1.00 40.00 N
+ATOM 4780 CA ARG C 235 -74.303 -10.505 48.741 1.00 40.00 C
+ATOM 4781 C ARG C 235 -73.664 -11.842 48.361 1.00 40.00 C
+ATOM 4782 O ARG C 235 -73.834 -12.267 47.224 1.00 40.00 O
+ATOM 4783 CB ARG C 235 -74.244 -9.616 47.511 1.00 40.00 C
+ATOM 4784 CG ARG C 235 -75.199 -8.458 47.535 1.00 40.00 C
+ATOM 4785 CD ARG C 235 -75.135 -7.813 46.175 1.00 40.00 C
+ATOM 4786 NE ARG C 235 -75.651 -6.450 46.194 1.00 40.00 N
+ATOM 4787 CZ ARG C 235 -75.338 -5.515 45.298 1.00 40.00 C
+ATOM 4788 NH1 ARG C 235 -74.496 -5.789 44.303 1.00 40.00 N
+ATOM 4789 NH2 ARG C 235 -75.861 -4.298 45.401 1.00 40.00 N
+ATOM 4790 N GLU C 236 -72.931 -12.492 49.274 1.00 40.00 N
+ATOM 4791 CA GLU C 236 -72.218 -13.755 48.969 1.00 40.00 C
+ATOM 4792 C GLU C 236 -72.051 -14.651 50.177 1.00 40.00 C
+ATOM 4793 O GLU C 236 -71.422 -15.706 50.096 1.00 40.00 O
+ATOM 4794 CB GLU C 236 -70.828 -13.484 48.390 1.00 40.00 C
+ATOM 4795 CG GLU C 236 -70.812 -13.070 46.927 1.00 40.00 C
+ATOM 4796 CD GLU C 236 -69.415 -12.796 46.410 1.00 40.00 C
+ATOM 4797 OE1 GLU C 236 -68.525 -13.663 46.595 1.00 40.00 O
+ATOM 4798 OE2 GLU C 236 -69.219 -11.713 45.813 1.00 40.00 O
+ATOM 4799 N GLN C 237 -72.581 -14.204 51.304 1.00 40.00 N
+ATOM 4800 CA GLN C 237 -72.544 -14.981 52.524 1.00 40.00 C
+ATOM 4801 C GLN C 237 -73.824 -14.731 53.293 1.00 40.00 C
+ATOM 4802 O GLN C 237 -74.415 -13.644 53.222 1.00 40.00 O
+ATOM 4803 CB GLN C 237 -71.361 -14.578 53.412 1.00 40.00 C
+ATOM 4804 CG GLN C 237 -69.967 -14.751 52.819 1.00 40.00 C
+ATOM 4805 CD GLN C 237 -68.910 -13.929 53.552 1.00 40.00 C
+ATOM 4806 OE1 GLN C 237 -69.207 -12.893 54.153 1.00 40.00 O
+ATOM 4807 NE2 GLN C 237 -67.667 -14.389 53.499 1.00 40.00 N
+ATOM 4808 N THR C 238 -74.249 -15.765 54.013 1.00 40.00 N
+ATOM 4809 CA THR C 238 -75.267 -15.645 55.056 1.00 40.00 C
+ATOM 4810 C THR C 238 -74.799 -16.417 56.309 1.00 40.00 C
+ATOM 4811 O THR C 238 -73.823 -17.201 56.266 1.00 40.00 O
+ATOM 4812 CB THR C 238 -76.690 -16.103 54.601 1.00 40.00 C
+ATOM 4813 OG1 THR C 238 -76.712 -17.514 54.343 1.00 40.00 O
+ATOM 4814 CG2 THR C 238 -77.168 -15.337 53.352 1.00 40.00 C
+ATOM 4815 N ASN C 239 -75.482 -16.168 57.425 1.00 40.00 N
+ATOM 4816 CA ASN C 239 -75.183 -16.843 58.689 1.00 40.00 C
+ATOM 4817 C ASN C 239 -75.899 -18.197 58.816 1.00 40.00 C
+ATOM 4818 O ASN C 239 -76.573 -18.657 57.876 1.00 40.00 O
+ATOM 4819 CB ASN C 239 -75.468 -15.913 59.906 1.00 40.00 C
+ATOM 4820 CG ASN C 239 -76.900 -15.354 59.931 1.00 40.00 C
+ATOM 4821 OD1 ASN C 239 -77.554 -15.216 58.895 1.00 40.00 O
+ATOM 4822 ND2 ASN C 239 -77.378 -15.016 61.128 1.00 40.00 N
+ATOM 4823 N ALA C 240 -75.730 -18.835 59.974 1.00 40.00 N
+ATOM 4824 CA ALA C 240 -76.516 -20.008 60.327 1.00 40.00 C
+ATOM 4825 C ALA C 240 -78.010 -19.677 60.212 1.00 40.00 C
+ATOM 4826 O ALA C 240 -78.797 -20.492 59.713 1.00 40.00 O
+ATOM 4827 CB ALA C 240 -76.163 -20.486 61.731 1.00 40.00 C
+ATOM 4828 N ALA C 241 -78.383 -18.468 60.635 1.00 40.00 N
+ATOM 4829 CA ALA C 241 -79.770 -18.005 60.556 1.00 40.00 C
+ATOM 4830 C ALA C 241 -80.267 -17.639 59.129 1.00 40.00 C
+ATOM 4831 O ALA C 241 -81.400 -17.154 58.979 1.00 40.00 O
+ATOM 4832 CB ALA C 241 -80.000 -16.859 61.537 1.00 40.00 C
+ATOM 4833 N GLY C 242 -79.439 -17.878 58.101 1.00 40.00 N
+ATOM 4834 CA GLY C 242 -79.812 -17.649 56.685 1.00 40.00 C
+ATOM 4835 C GLY C 242 -80.131 -16.217 56.243 1.00 40.00 C
+ATOM 4836 O GLY C 242 -80.959 -16.008 55.340 1.00 40.00 O
+ATOM 4837 N GLU C 243 -79.471 -15.240 56.879 1.00 40.00 N
+ATOM 4838 CA GLU C 243 -79.617 -13.797 56.563 1.00 40.00 C
+ATOM 4839 C GLU C 243 -78.301 -13.226 56.023 1.00 40.00 C
+ATOM 4840 O GLU C 243 -77.219 -13.757 56.308 1.00 40.00 O
+ATOM 4841 CB GLU C 243 -80.033 -12.986 57.793 1.00 40.00 C
+ATOM 4842 CG GLU C 243 -80.657 -13.808 58.904 1.00 40.00 C
+ATOM 4843 CD GLU C 243 -80.512 -13.141 60.249 1.00 40.00 C
+ATOM 4844 OE1 GLU C 243 -81.036 -12.011 60.386 1.00 40.00 O
+ATOM 4845 OE2 GLU C 243 -79.878 -13.742 61.157 1.00 40.00 O
+ATOM 4846 N ARG C 244 -78.403 -12.131 55.267 1.00 40.00 N
+ATOM 4847 CA ARG C 244 -77.258 -11.546 54.561 1.00 40.00 C
+ATOM 4848 C ARG C 244 -76.153 -11.059 55.502 1.00 40.00 C
+ATOM 4849 O ARG C 244 -76.437 -10.346 56.470 1.00 40.00 O
+ATOM 4850 CB ARG C 244 -77.736 -10.398 53.676 1.00 40.00 C
+ATOM 4851 CG ARG C 244 -78.369 -10.838 52.370 1.00 40.00 C
+ATOM 4852 CD ARG C 244 -78.677 -9.617 51.524 1.00 40.00 C
+ATOM 4853 NE ARG C 244 -79.229 -9.964 50.220 1.00 40.00 N
+ATOM 4854 CZ ARG C 244 -80.074 -9.195 49.534 1.00 40.00 C
+ATOM 4855 NH1 ARG C 244 -80.482 -8.032 50.029 1.00 40.00 N
+ATOM 4856 NH2 ARG C 244 -80.527 -9.592 48.354 1.00 40.00 N
+ATOM 4857 N MET C 245 -74.904 -11.433 55.207 1.00 40.00 N
+ATOM 4858 CA MET C 245 -73.764 -11.100 56.083 1.00 40.00 C
+ATOM 4859 C MET C 245 -73.396 -9.623 56.060 1.00 40.00 C
+ATOM 4860 O MET C 245 -72.573 -9.167 55.260 1.00 40.00 O
+ATOM 4861 CB MET C 245 -72.530 -11.962 55.780 1.00 40.00 C
+ATOM 4862 CG MET C 245 -71.451 -11.903 56.855 1.00 40.00 C
+ATOM 4863 SD MET C 245 -72.010 -12.534 58.449 1.00 40.00 S
+ATOM 4864 CE MET C 245 -72.063 -14.302 58.147 1.00 40.00 C
+ATOM 4865 N TYR C 246 -74.033 -8.885 56.956 1.00 40.00 N
+ATOM 4866 CA TYR C 246 -73.697 -7.499 57.179 1.00 40.00 C
+ATOM 4867 C TYR C 246 -72.656 -7.425 58.272 1.00 40.00 C
+ATOM 4868 O TYR C 246 -72.459 -8.384 59.030 1.00 40.00 O
+ATOM 4869 CB TYR C 246 -74.949 -6.698 57.521 1.00 40.00 C
+ATOM 4870 CG TYR C 246 -75.907 -6.704 56.373 1.00 40.00 C
+ATOM 4871 CD1 TYR C 246 -75.485 -6.291 55.116 1.00 40.00 C
+ATOM 4872 CD2 TYR C 246 -77.216 -7.157 56.523 1.00 40.00 C
+ATOM 4873 CE1 TYR C 246 -76.340 -6.308 54.032 1.00 40.00 C
+ATOM 4874 CE2 TYR C 246 -78.090 -7.177 55.445 1.00 40.00 C
+ATOM 4875 CZ TYR C 246 -77.645 -6.750 54.198 1.00 40.00 C
+ATOM 4876 OH TYR C 246 -78.487 -6.750 53.101 1.00 40.00 O
+ATOM 4877 N ILE C 247 -71.963 -6.296 58.329 1.00 40.00 N
+ATOM 4878 CA ILE C 247 -70.920 -6.117 59.318 1.00 40.00 C
+ATOM 4879 C ILE C 247 -71.410 -6.649 60.670 1.00 40.00 C
+ATOM 4880 O ILE C 247 -70.770 -7.529 61.253 1.00 40.00 O
+ATOM 4881 CB ILE C 247 -70.411 -4.646 59.365 1.00 40.00 C
+ATOM 4882 CG1 ILE C 247 -69.286 -4.499 60.396 1.00 40.00 C
+ATOM 4883 CG2 ILE C 247 -71.546 -3.644 59.597 1.00 40.00 C
+ATOM 4884 CD1 ILE C 247 -68.284 -3.408 60.075 1.00 40.00 C
+ATOM 4885 N GLN C 248 -72.579 -6.161 61.103 1.00 40.00 N
+ATOM 4886 CA GLN C 248 -73.181 -6.511 62.389 1.00 40.00 C
+ATOM 4887 C GLN C 248 -73.349 -8.007 62.527 1.00 40.00 C
+ATOM 4888 O GLN C 248 -73.117 -8.567 63.600 1.00 40.00 O
+ATOM 4889 CB GLN C 248 -74.529 -5.800 62.598 1.00 40.00 C
+ATOM 4890 CG GLN C 248 -75.606 -6.096 61.562 1.00 40.00 C
+ATOM 4891 CD GLN C 248 -75.602 -5.108 60.414 1.00 40.00 C
+ATOM 4892 OE1 GLN C 248 -74.550 -4.721 59.911 1.00 40.00 O
+ATOM 4893 NE2 GLN C 248 -76.784 -4.697 59.991 1.00 40.00 N
+ATOM 4894 N THR C 249 -73.732 -8.648 61.429 1.00 40.00 N
+ATOM 4895 CA THR C 249 -73.978 -10.080 61.420 1.00 40.00 C
+ATOM 4896 C THR C 249 -72.677 -10.827 61.692 1.00 40.00 C
+ATOM 4897 O THR C 249 -72.639 -11.738 62.522 1.00 40.00 O
+ATOM 4898 CB THR C 249 -74.587 -10.526 60.084 1.00 40.00 C
+ATOM 4899 OG1 THR C 249 -75.322 -9.437 59.516 1.00 40.00 O
+ATOM 4900 CG2 THR C 249 -75.509 -11.715 60.287 1.00 40.00 C
+ATOM 4901 N ARG C 250 -71.613 -10.414 61.009 1.00 40.00 N
+ATOM 4902 CA ARG C 250 -70.298 -11.004 61.200 1.00 40.00 C
+ATOM 4903 C ARG C 250 -69.831 -10.786 62.629 1.00 40.00 C
+ATOM 4904 O ARG C 250 -69.279 -11.685 63.262 1.00 40.00 O
+ATOM 4905 CB ARG C 250 -69.298 -10.399 60.208 1.00 40.00 C
+ATOM 4906 CG ARG C 250 -67.853 -10.861 60.383 1.00 40.00 C
+ATOM 4907 CD ARG C 250 -67.659 -12.323 60.023 1.00 40.00 C
+ATOM 4908 NE ARG C 250 -68.078 -12.570 58.647 1.00 40.00 N
+ATOM 4909 CZ ARG C 250 -68.486 -13.746 58.175 1.00 40.00 C
+ATOM 4910 NH1 ARG C 250 -68.535 -14.819 58.969 1.00 40.00 N
+ATOM 4911 NH2 ARG C 250 -68.853 -13.847 56.900 1.00 40.00 N
+ATOM 4912 N MET C 251 -70.055 -9.574 63.119 1.00 40.00 N
+ATOM 4913 CA MET C 251 -69.680 -9.200 64.469 1.00 40.00 C
+ATOM 4914 C MET C 251 -70.420 -10.084 65.440 1.00 40.00 C
+ATOM 4915 O MET C 251 -69.808 -10.665 66.335 1.00 40.00 O
+ATOM 4916 CB MET C 251 -70.052 -7.749 64.744 1.00 40.00 C
+ATOM 4917 CG MET C 251 -69.102 -6.714 64.165 1.00 40.00 C
+ATOM 4918 SD MET C 251 -69.870 -5.081 64.056 1.00 40.00 S
+ATOM 4919 CE MET C 251 -70.085 -4.652 65.778 1.00 40.00 C
+ATOM 4920 N ALA C 252 -71.736 -10.183 65.245 1.00 40.00 N
+ATOM 4921 CA ALA C 252 -72.607 -10.985 66.101 1.00 40.00 C
+ATOM 4922 C ALA C 252 -72.040 -12.390 66.336 1.00 40.00 C
+ATOM 4923 O ALA C 252 -72.352 -13.036 67.343 1.00 40.00 O
+ATOM 4924 CB ALA C 252 -74.008 -11.060 65.515 1.00 40.00 C
+ATOM 4925 N GLU C 253 -71.191 -12.843 65.411 1.00 40.00 N
+ATOM 4926 CA GLU C 253 -70.503 -14.130 65.534 1.00 40.00 C
+ATOM 4927 C GLU C 253 -69.422 -14.153 66.620 1.00 40.00 C
+ATOM 4928 O GLU C 253 -68.841 -15.204 66.905 1.00 40.00 O
+ATOM 4929 CB GLU C 253 -69.887 -14.532 64.201 1.00 40.00 C
+ATOM 4930 CG GLU C 253 -70.899 -14.829 63.112 1.00 40.00 C
+ATOM 4931 CD GLU C 253 -70.248 -15.405 61.869 1.00 40.00 C
+ATOM 4932 OE1 GLU C 253 -70.990 -15.925 61.005 1.00 40.00 O
+ATOM 4933 OE2 GLU C 253 -68.998 -15.340 61.757 1.00 40.00 O
+ATOM 4934 N TYR C 254 -69.142 -13.000 67.217 1.00 40.00 N
+ATOM 4935 CA TYR C 254 -68.202 -12.938 68.311 1.00 40.00 C
+ATOM 4936 C TYR C 254 -68.798 -12.153 69.444 1.00 40.00 C
+ATOM 4937 O TYR C 254 -68.072 -11.712 70.320 1.00 40.00 O
+ATOM 4938 CB TYR C 254 -66.930 -12.235 67.879 1.00 40.00 C
+ATOM 4939 CG TYR C 254 -66.204 -12.838 66.712 1.00 40.00 C
+ATOM 4940 CD1 TYR C 254 -65.220 -13.798 66.914 1.00 40.00 C
+ATOM 4941 CD2 TYR C 254 -66.466 -12.415 65.407 1.00 40.00 C
+ATOM 4942 CE1 TYR C 254 -64.524 -14.337 65.854 1.00 40.00 C
+ATOM 4943 CE2 TYR C 254 -65.779 -12.952 64.336 1.00 40.00 C
+ATOM 4944 CZ TYR C 254 -64.807 -13.910 64.571 1.00 40.00 C
+ATOM 4945 OH TYR C 254 -64.106 -14.455 63.529 1.00 40.00 O
+ATOM 4946 N LYS C 255 -70.115 -11.972 69.430 1.00 40.00 N
+ATOM 4947 CA LYS C 255 -70.788 -11.115 70.409 1.00 40.00 C
+ATOM 4948 C LYS C 255 -70.300 -11.356 71.831 1.00 40.00 C
+ATOM 4949 O LYS C 255 -70.573 -10.577 72.735 1.00 40.00 O
+ATOM 4950 CB LYS C 255 -72.310 -11.256 70.314 1.00 40.00 C
+ATOM 4951 CG LYS C 255 -72.856 -12.648 70.563 1.00 40.00 C
+ATOM 4952 CD LYS C 255 -74.246 -12.784 69.964 1.00 40.00 C
+ATOM 4953 CE LYS C 255 -74.884 -14.108 70.343 1.00 40.00 C
+ATOM 4954 NZ LYS C 255 -75.336 -14.081 71.759 1.00 40.00 N
+ATOM 4955 N GLU C 256 -69.553 -12.441 71.994 1.00 40.00 N
+ATOM 4956 CA GLU C 256 -68.949 -12.833 73.264 1.00 40.00 C
+ATOM 4957 C GLU C 256 -67.706 -12.000 73.590 1.00 40.00 C
+ATOM 4958 O GLU C 256 -67.784 -11.085 74.410 1.00 40.00 O
+ATOM 4959 CB GLU C 256 -68.578 -14.330 73.248 1.00 40.00 C
+ATOM 4960 CG GLU C 256 -69.500 -15.242 72.439 1.00 40.00 C
+ATOM 4961 CD GLU C 256 -70.910 -15.357 73.007 1.00 40.00 C
+ATOM 4962 OE1 GLU C 256 -71.097 -15.145 74.230 1.00 40.00 O
+ATOM 4963 OE2 GLU C 256 -71.839 -15.668 72.221 1.00 40.00 O
+ATOM 4964 N GLU C 257 -66.570 -12.320 72.954 1.00 40.00 N
+ATOM 4965 CA GLU C 257 -65.281 -11.644 73.230 1.00 40.00 C
+ATOM 4966 C GLU C 257 -65.433 -10.138 73.151 1.00 40.00 C
+ATOM 4967 O GLU C 257 -64.926 -9.407 73.998 1.00 40.00 O
+ATOM 4968 CB GLU C 257 -64.157 -12.042 72.250 1.00 40.00 C
+ATOM 4969 CG GLU C 257 -63.930 -13.521 72.006 1.00 40.00 C
+ATOM 4970 CD GLU C 257 -64.649 -13.986 70.763 1.00 40.00 C
+ATOM 4971 OE1 GLU C 257 -65.892 -14.168 70.834 1.00 40.00 O
+ATOM 4972 OE2 GLU C 257 -63.967 -14.149 69.724 1.00 40.00 O
+ATOM 4973 N LEU C 258 -66.123 -9.689 72.109 1.00 40.00 N
+ATOM 4974 CA LEU C 258 -66.345 -8.280 71.891 1.00 40.00 C
+ATOM 4975 C LEU C 258 -66.957 -7.670 73.137 1.00 40.00 C
+ATOM 4976 O LEU C 258 -66.327 -6.826 73.771 1.00 40.00 O
+ATOM 4977 CB LEU C 258 -67.211 -8.056 70.655 1.00 40.00 C
+ATOM 4978 CG LEU C 258 -66.662 -8.675 69.358 1.00 40.00 C
+ATOM 4979 CD1 LEU C 258 -67.614 -8.424 68.195 1.00 40.00 C
+ATOM 4980 CD2 LEU C 258 -65.256 -8.191 69.013 1.00 40.00 C
+ATOM 4981 N TRP C 259 -68.144 -8.131 73.527 1.00 40.00 N
+ATOM 4982 CA TRP C 259 -68.791 -7.617 74.740 1.00 40.00 C
+ATOM 4983 C TRP C 259 -67.885 -7.646 75.946 1.00 40.00 C
+ATOM 4984 O TRP C 259 -67.882 -6.728 76.768 1.00 40.00 O
+ATOM 4985 CB TRP C 259 -70.092 -8.354 75.033 1.00 40.00 C
+ATOM 4986 CG TRP C 259 -70.756 -7.831 76.282 1.00 40.00 C
+ATOM 4987 CD1 TRP C 259 -71.069 -8.540 77.442 1.00 40.00 C
+ATOM 4988 CD2 TRP C 259 -71.168 -6.437 76.563 1.00 40.00 C
+ATOM 4989 NE1 TRP C 259 -71.650 -7.715 78.381 1.00 40.00 N
+ATOM 4990 CE2 TRP C 259 -71.737 -6.440 77.918 1.00 40.00 C
+ATOM 4991 CE3 TRP C 259 -71.144 -5.245 75.848 1.00 40.00 C
+ATOM 4992 CZ2 TRP C 259 -72.245 -5.282 78.507 1.00 40.00 C
+ATOM 4993 CZ3 TRP C 259 -71.660 -4.090 76.452 1.00 40.00 C
+ATOM 4994 CH2 TRP C 259 -72.196 -4.110 77.748 1.00 40.00 C
+ATOM 4995 N GLU C 260 -67.108 -8.719 76.048 1.00 40.00 N
+ATOM 4996 CA GLU C 260 -66.101 -8.868 77.082 1.00 40.00 C
+ATOM 4997 C GLU C 260 -65.066 -7.762 76.954 1.00 40.00 C
+ATOM 4998 O GLU C 260 -64.902 -6.958 77.868 1.00 40.00 O
+ATOM 4999 CB GLU C 260 -65.425 -10.247 76.972 1.00 40.00 C
+ATOM 5000 CG GLU C 260 -66.263 -11.421 77.469 1.00 40.00 C
+ATOM 5001 CD GLU C 260 -66.689 -11.263 78.921 1.00 40.00 C
+ATOM 5002 OE1 GLU C 260 -67.908 -11.300 79.186 1.00 40.00 O
+ATOM 5003 OE2 GLU C 260 -65.813 -11.084 79.798 1.00 40.00 O
+ATOM 5004 N LEU C 261 -64.396 -7.725 75.803 1.00 40.00 N
+ATOM 5005 CA LEU C 261 -63.350 -6.743 75.500 1.00 40.00 C
+ATOM 5006 C LEU C 261 -63.837 -5.310 75.662 1.00 40.00 C
+ATOM 5007 O LEU C 261 -63.047 -4.383 75.793 1.00 40.00 O
+ATOM 5008 CB LEU C 261 -62.815 -6.960 74.077 1.00 40.00 C
+ATOM 5009 CG LEU C 261 -61.874 -8.157 73.840 1.00 40.00 C
+ATOM 5010 CD1 LEU C 261 -62.098 -8.829 72.494 1.00 40.00 C
+ATOM 5011 CD2 LEU C 261 -60.417 -7.747 73.975 1.00 40.00 C
+ATOM 5012 N LEU C 262 -65.152 -5.149 75.668 1.00 40.00 N
+ATOM 5013 CA LEU C 262 -65.777 -3.847 75.823 1.00 40.00 C
+ATOM 5014 C LEU C 262 -65.723 -3.293 77.235 1.00 40.00 C
+ATOM 5015 O LEU C 262 -66.098 -2.142 77.486 1.00 40.00 O
+ATOM 5016 CB LEU C 262 -67.232 -3.923 75.389 1.00 40.00 C
+ATOM 5017 CG LEU C 262 -67.471 -3.515 73.940 1.00 40.00 C
+ATOM 5018 CD1 LEU C 262 -68.959 -3.316 73.688 1.00 40.00 C
+ATOM 5019 CD2 LEU C 262 -66.724 -2.227 73.634 1.00 40.00 C
+ATOM 5020 N LYS C 263 -65.277 -4.119 78.166 1.00 40.00 N
+ATOM 5021 CA LYS C 263 -65.229 -3.696 79.548 1.00 40.00 C
+ATOM 5022 C LYS C 263 -63.778 -3.426 79.960 1.00 40.00 C
+ATOM 5023 O LYS C 263 -63.521 -2.919 81.046 1.00 40.00 O
+ATOM 5024 CB LYS C 263 -65.961 -4.715 80.440 1.00 40.00 C
+ATOM 5025 CG LYS C 263 -67.431 -4.911 80.044 1.00 40.00 C
+ATOM 5026 CD LYS C 263 -68.199 -5.887 80.929 1.00 40.00 C
+ATOM 5027 CE LYS C 263 -67.948 -7.340 80.548 1.00 40.00 C
+ATOM 5028 NZ LYS C 263 -68.742 -8.257 81.414 1.00 40.00 N
+ATOM 5029 N LYS C 264 -62.841 -3.735 79.065 1.00 40.00 N
+ATOM 5030 CA LYS C 264 -61.432 -3.430 79.278 1.00 40.00 C
+ATOM 5031 C LYS C 264 -61.139 -1.944 79.082 1.00 40.00 C
+ATOM 5032 O LYS C 264 -61.908 -1.229 78.457 1.00 40.00 O
+ATOM 5033 CB LYS C 264 -60.556 -4.269 78.353 1.00 40.00 C
+ATOM 5034 CG LYS C 264 -60.323 -5.693 78.837 1.00 40.00 C
+ATOM 5035 CD LYS C 264 -59.338 -6.437 77.938 1.00 40.00 C
+ATOM 5036 CE LYS C 264 -58.817 -7.711 78.587 1.00 40.00 C
+ATOM 5037 NZ LYS C 264 -59.893 -8.704 78.862 1.00 40.00 N
+ATOM 5038 N ASP C 265 -60.012 -1.495 79.627 1.00 40.00 N
+ATOM 5039 CA ASP C 265 -59.617 -0.071 79.660 1.00 40.00 C
+ATOM 5040 C ASP C 265 -58.748 0.315 78.484 1.00 40.00 C
+ATOM 5041 O ASP C 265 -58.461 1.488 78.261 1.00 40.00 O
+ATOM 5042 CB ASP C 265 -58.804 0.230 80.937 1.00 40.00 C
+ATOM 5043 CG ASP C 265 -59.675 0.548 82.149 1.00 40.00 C
+ATOM 5044 OD1 ASP C 265 -59.187 0.363 83.297 1.00 40.00 O
+ATOM 5045 OD2 ASP C 265 -60.833 0.992 81.955 1.00 40.00 O
+ATOM 5046 N ASN C 266 -58.288 -0.687 77.763 1.00 40.00 N
+ATOM 5047 CA ASN C 266 -57.352 -0.463 76.701 1.00 40.00 C
+ATOM 5048 C ASN C 266 -57.930 -1.027 75.410 1.00 40.00 C
+ATOM 5049 O ASN C 266 -57.208 -1.374 74.474 1.00 40.00 O
+ATOM 5050 CB ASN C 266 -56.019 -1.109 77.053 1.00 40.00 C
+ATOM 5051 CG ASN C 266 -56.129 -2.615 77.214 1.00 40.00 C
+ATOM 5052 OD1 ASN C 266 -57.210 -3.149 77.510 1.00 40.00 O
+ATOM 5053 ND2 ASN C 266 -55.009 -3.314 77.010 1.00 40.00 N
+ATOM 5054 N THR C 267 -59.252 -1.126 75.376 1.00 40.00 N
+ATOM 5055 CA THR C 267 -59.960 -1.496 74.164 1.00 40.00 C
+ATOM 5056 C THR C 267 -60.576 -0.225 73.574 1.00 40.00 C
+ATOM 5057 O THR C 267 -61.405 0.407 74.204 1.00 40.00 O
+ATOM 5058 CB THR C 267 -61.032 -2.566 74.465 1.00 40.00 C
+ATOM 5059 OG1 THR C 267 -60.407 -3.733 75.007 1.00 40.00 O
+ATOM 5060 CG2 THR C 267 -61.753 -2.971 73.223 1.00 40.00 C
+ATOM 5061 N TYR C 268 -60.151 0.169 72.380 1.00 40.00 N
+ATOM 5062 CA TYR C 268 -60.680 1.383 71.758 1.00 40.00 C
+ATOM 5063 C TYR C 268 -61.353 1.068 70.421 1.00 40.00 C
+ATOM 5064 O TYR C 268 -60.772 0.382 69.568 1.00 40.00 O
+ATOM 5065 CB TYR C 268 -59.577 2.413 71.553 1.00 40.00 C
+ATOM 5066 CG TYR C 268 -58.700 2.617 72.752 1.00 40.00 C
+ATOM 5067 CD1 TYR C 268 -57.652 1.750 73.016 1.00 40.00 C
+ATOM 5068 CD2 TYR C 268 -58.907 3.681 73.624 1.00 40.00 C
+ATOM 5069 CE1 TYR C 268 -56.830 1.927 74.118 1.00 40.00 C
+ATOM 5070 CE2 TYR C 268 -58.086 3.870 74.734 1.00 40.00 C
+ATOM 5071 CZ TYR C 268 -57.043 2.983 74.974 1.00 40.00 C
+ATOM 5072 OH TYR C 268 -56.202 3.119 76.059 1.00 40.00 O
+ATOM 5073 N VAL C 269 -62.575 1.575 70.241 1.00 40.00 N
+ATOM 5074 CA VAL C 269 -63.386 1.268 69.058 1.00 40.00 C
+ATOM 5075 C VAL C 269 -63.399 2.422 68.089 1.00 40.00 C
+ATOM 5076 O VAL C 269 -63.566 3.575 68.468 1.00 40.00 O
+ATOM 5077 CB VAL C 269 -64.839 0.919 69.425 1.00 40.00 C
+ATOM 5078 CG1 VAL C 269 -65.718 0.899 68.197 1.00 40.00 C
+ATOM 5079 CG2 VAL C 269 -64.888 -0.439 70.078 1.00 40.00 C
+ATOM 5080 N TYR C 270 -63.226 2.094 66.824 1.00 40.00 N
+ATOM 5081 CA TYR C 270 -63.311 3.089 65.794 1.00 40.00 C
+ATOM 5082 C TYR C 270 -64.279 2.611 64.720 1.00 40.00 C
+ATOM 5083 O TYR C 270 -64.194 1.459 64.260 1.00 40.00 O
+ATOM 5084 CB TYR C 270 -61.941 3.313 65.190 1.00 40.00 C
+ATOM 5085 CG TYR C 270 -60.904 3.965 66.086 1.00 40.00 C
+ATOM 5086 CD1 TYR C 270 -60.209 3.231 67.038 1.00 40.00 C
+ATOM 5087 CD2 TYR C 270 -60.569 5.312 65.925 1.00 40.00 C
+ATOM 5088 CE1 TYR C 270 -59.238 3.829 67.826 1.00 40.00 C
+ATOM 5089 CE2 TYR C 270 -59.597 5.915 66.705 1.00 40.00 C
+ATOM 5090 CZ TYR C 270 -58.935 5.169 67.651 1.00 40.00 C
+ATOM 5091 OH TYR C 270 -57.970 5.761 68.425 1.00 40.00 O
+ATOM 5092 N MET C 271 -65.200 3.496 64.333 1.00 40.00 N
+ATOM 5093 CA MET C 271 -66.225 3.183 63.337 1.00 40.00 C
+ATOM 5094 C MET C 271 -66.148 4.179 62.206 1.00 40.00 C
+ATOM 5095 O MET C 271 -66.098 5.380 62.452 1.00 40.00 O
+ATOM 5096 CB MET C 271 -67.621 3.254 63.954 1.00 40.00 C
+ATOM 5097 CG MET C 271 -68.709 2.570 63.131 1.00 40.00 C
+ATOM 5098 SD MET C 271 -70.407 2.855 63.711 1.00 40.00 S
+ATOM 5099 CE MET C 271 -70.577 1.683 65.062 1.00 40.00 C
+ATOM 5100 N CYS C 272 -66.150 3.681 60.972 1.00 40.00 N
+ATOM 5101 CA CYS C 272 -66.031 4.546 59.805 1.00 40.00 C
+ATOM 5102 C CYS C 272 -66.695 3.956 58.577 1.00 40.00 C
+ATOM 5103 O CYS C 272 -66.631 2.753 58.341 1.00 40.00 O
+ATOM 5104 CB CYS C 272 -64.557 4.842 59.502 1.00 40.00 C
+ATOM 5105 SG CYS C 272 -64.262 6.245 58.397 1.00 40.00 S
+ATOM 5106 N GLY C 273 -67.335 4.820 57.799 1.00 40.00 N
+ATOM 5107 CA GLY C 273 -67.863 4.432 56.504 1.00 40.00 C
+ATOM 5108 C GLY C 273 -69.174 5.084 56.140 1.00 40.00 C
+ATOM 5109 O GLY C 273 -69.292 6.313 56.082 1.00 40.00 O
+ATOM 5110 N LEU C 274 -70.166 4.234 55.904 1.00 40.00 N
+ATOM 5111 CA LEU C 274 -71.442 4.646 55.327 1.00 40.00 C
+ATOM 5112 C LEU C 274 -72.503 4.885 56.383 1.00 40.00 C
+ATOM 5113 O LEU C 274 -72.908 3.951 57.091 1.00 40.00 O
+ATOM 5114 CB LEU C 274 -71.938 3.572 54.357 1.00 40.00 C
+ATOM 5115 CG LEU C 274 -71.016 3.238 53.181 1.00 40.00 C
+ATOM 5116 CD1 LEU C 274 -71.247 1.810 52.683 1.00 40.00 C
+ATOM 5117 CD2 LEU C 274 -71.184 4.287 52.076 1.00 40.00 C
+ATOM 5118 N LYS C 275 -72.959 6.130 56.480 1.00 40.00 N
+ATOM 5119 CA LYS C 275 -74.051 6.452 57.379 1.00 40.00 C
+ATOM 5120 C LYS C 275 -75.092 5.330 57.302 1.00 40.00 C
+ATOM 5121 O LYS C 275 -75.577 5.003 56.220 1.00 40.00 O
+ATOM 5122 CB LYS C 275 -74.665 7.797 56.997 1.00 40.00 C
+ATOM 5123 CG LYS C 275 -75.699 8.305 57.986 1.00 40.00 C
+ATOM 5124 CD LYS C 275 -76.164 9.710 57.637 1.00 40.00 C
+ATOM 5125 CE LYS C 275 -76.995 10.311 58.767 1.00 40.00 C
+ATOM 5126 NZ LYS C 275 -77.027 11.808 58.755 1.00 40.00 N
+ATOM 5127 N GLY C 276 -75.395 4.710 58.437 1.00 40.00 N
+ATOM 5128 CA GLY C 276 -76.421 3.678 58.470 1.00 40.00 C
+ATOM 5129 C GLY C 276 -75.954 2.367 59.049 1.00 40.00 C
+ATOM 5130 O GLY C 276 -76.736 1.635 59.659 1.00 40.00 O
+ATOM 5131 N MET C 277 -74.677 2.064 58.858 1.00 40.00 N
+ATOM 5132 CA MET C 277 -74.087 0.872 59.453 1.00 40.00 C
+ATOM 5133 C MET C 277 -74.378 0.757 60.964 1.00 40.00 C
+ATOM 5134 O MET C 277 -74.733 -0.332 61.434 1.00 40.00 O
+ATOM 5135 CB MET C 277 -72.578 0.793 59.149 1.00 40.00 C
+ATOM 5136 CG MET C 277 -71.732 1.975 59.628 1.00 40.00 C
+ATOM 5137 SD MET C 277 -70.032 2.043 58.995 1.00 40.00 S
+ATOM 5138 CE MET C 277 -69.241 0.709 59.891 1.00 40.00 C
+ATOM 5139 N GLU C 278 -74.277 1.881 61.696 1.00 40.00 N
+ATOM 5140 CA GLU C 278 -74.348 1.895 63.182 1.00 40.00 C
+ATOM 5141 C GLU C 278 -75.716 1.588 63.795 1.00 40.00 C
+ATOM 5142 O GLU C 278 -75.778 1.136 64.942 1.00 40.00 O
+ATOM 5143 CB GLU C 278 -73.757 3.181 63.809 1.00 40.00 C
+ATOM 5144 CG GLU C 278 -74.690 4.377 63.889 1.00 40.00 C
+ATOM 5145 CD GLU C 278 -74.710 5.158 62.599 1.00 40.00 C
+ATOM 5146 OE1 GLU C 278 -75.211 4.634 61.571 1.00 40.00 O
+ATOM 5147 OE2 GLU C 278 -74.207 6.301 62.621 1.00 40.00 O
+ATOM 5148 N LYS C 279 -76.803 1.827 63.061 1.00 40.00 N
+ATOM 5149 CA LYS C 279 -78.079 1.304 63.519 1.00 40.00 C
+ATOM 5150 C LYS C 279 -77.883 -0.192 63.633 1.00 40.00 C
+ATOM 5151 O LYS C 279 -78.078 -0.752 64.706 1.00 40.00 O
+ATOM 5152 CB LYS C 279 -79.242 1.611 62.580 1.00 40.00 C
+ATOM 5153 CG LYS C 279 -80.577 1.245 63.219 1.00 40.00 C
+ATOM 5154 CD LYS C 279 -81.681 0.972 62.205 1.00 40.00 C
+ATOM 5155 CE LYS C 279 -82.875 0.318 62.892 1.00 40.00 C
+ATOM 5156 NZ LYS C 279 -84.124 0.391 62.089 1.00 40.00 N
+ATOM 5157 N GLY C 280 -77.449 -0.814 62.535 1.00 40.00 N
+ATOM 5158 CA GLY C 280 -77.128 -2.238 62.504 1.00 40.00 C
+ATOM 5159 C GLY C 280 -76.375 -2.681 63.740 1.00 40.00 C
+ATOM 5160 O GLY C 280 -76.785 -3.629 64.408 1.00 40.00 O
+ATOM 5161 N ILE C 281 -75.295 -1.965 64.053 1.00 40.00 N
+ATOM 5162 CA ILE C 281 -74.420 -2.273 65.185 1.00 40.00 C
+ATOM 5163 C ILE C 281 -75.094 -2.034 66.531 1.00 40.00 C
+ATOM 5164 O ILE C 281 -75.137 -2.926 67.381 1.00 40.00 O
+ATOM 5165 CB ILE C 281 -73.087 -1.500 65.080 1.00 40.00 C
+ATOM 5166 CG1 ILE C 281 -72.192 -2.178 64.041 1.00 40.00 C
+ATOM 5167 CG2 ILE C 281 -72.371 -1.439 66.417 1.00 40.00 C
+ATOM 5168 CD1 ILE C 281 -70.836 -1.532 63.840 1.00 40.00 C
+ATOM 5169 N ASP C 282 -75.629 -0.836 66.718 1.00 40.00 N
+ATOM 5170 CA ASP C 282 -76.312 -0.510 67.953 1.00 40.00 C
+ATOM 5171 C ASP C 282 -77.331 -1.581 68.305 1.00 40.00 C
+ATOM 5172 O ASP C 282 -77.402 -2.005 69.453 1.00 40.00 O
+ATOM 5173 CB ASP C 282 -76.964 0.869 67.862 1.00 40.00 C
+ATOM 5174 CG ASP C 282 -75.938 2.005 67.871 1.00 40.00 C
+ATOM 5175 OD1 ASP C 282 -74.758 1.763 68.210 1.00 40.00 O
+ATOM 5176 OD2 ASP C 282 -76.305 3.150 67.537 1.00 40.00 O
+ATOM 5177 N ASP C 283 -78.078 -2.041 67.298 1.00 40.00 N
+ATOM 5178 CA ASP C 283 -79.117 -3.084 67.451 1.00 40.00 C
+ATOM 5179 C ASP C 283 -78.584 -4.368 68.073 1.00 40.00 C
+ATOM 5180 O ASP C 283 -79.273 -5.014 68.875 1.00 40.00 O
+ATOM 5181 CB ASP C 283 -79.784 -3.413 66.100 1.00 40.00 C
+ATOM 5182 CG ASP C 283 -80.613 -2.247 65.544 1.00 40.00 C
+ATOM 5183 OD1 ASP C 283 -81.178 -1.462 66.342 1.00 40.00 O
+ATOM 5184 OD2 ASP C 283 -80.704 -2.116 64.300 1.00 40.00 O
+ATOM 5185 N ILE C 284 -77.355 -4.718 67.692 1.00 40.00 N
+ATOM 5186 CA ILE C 284 -76.654 -5.892 68.212 1.00 40.00 C
+ATOM 5187 C ILE C 284 -76.160 -5.655 69.640 1.00 40.00 C
+ATOM 5188 O ILE C 284 -76.125 -6.581 70.462 1.00 40.00 O
+ATOM 5189 CB ILE C 284 -75.477 -6.289 67.287 1.00 40.00 C
+ATOM 5190 CG1 ILE C 284 -75.974 -6.535 65.854 1.00 40.00 C
+ATOM 5191 CG2 ILE C 284 -74.717 -7.501 67.818 1.00 40.00 C
+ATOM 5192 CD1 ILE C 284 -77.242 -7.360 65.741 1.00 40.00 C
+ATOM 5193 N MET C 285 -75.802 -4.406 69.932 1.00 40.00 N
+ATOM 5194 CA MET C 285 -75.251 -4.036 71.237 1.00 40.00 C
+ATOM 5195 C MET C 285 -76.310 -3.925 72.311 1.00 40.00 C
+ATOM 5196 O MET C 285 -76.042 -4.148 73.489 1.00 40.00 O
+ATOM 5197 CB MET C 285 -74.489 -2.722 71.129 1.00 40.00 C
+ATOM 5198 CG MET C 285 -73.222 -2.842 70.296 1.00 40.00 C
+ATOM 5199 SD MET C 285 -71.950 -3.864 71.075 1.00 40.00 S
+ATOM 5200 CE MET C 285 -71.399 -4.868 69.698 1.00 40.00 C
+ATOM 5201 N VAL C 286 -77.511 -3.570 71.879 1.00 40.00 N
+ATOM 5202 CA VAL C 286 -78.649 -3.421 72.761 1.00 40.00 C
+ATOM 5203 C VAL C 286 -78.923 -4.727 73.499 1.00 40.00 C
+ATOM 5204 O VAL C 286 -78.986 -4.734 74.735 1.00 40.00 O
+ATOM 5205 CB VAL C 286 -79.885 -2.929 71.973 1.00 40.00 C
+ATOM 5206 CG1 VAL C 286 -81.182 -3.218 72.721 1.00 40.00 C
+ATOM 5207 CG2 VAL C 286 -79.749 -1.438 71.674 1.00 40.00 C
+ATOM 5208 N SER C 287 -79.045 -5.823 72.744 1.00 40.00 N
+ATOM 5209 CA SER C 287 -79.365 -7.132 73.330 1.00 40.00 C
+ATOM 5210 C SER C 287 -78.245 -7.659 74.229 1.00 40.00 C
+ATOM 5211 O SER C 287 -78.520 -8.373 75.197 1.00 40.00 O
+ATOM 5212 CB SER C 287 -79.798 -8.173 72.271 1.00 40.00 C
+ATOM 5213 OG SER C 287 -78.784 -8.436 71.319 1.00 40.00 O
+ATOM 5214 N LEU C 288 -77.002 -7.281 73.918 1.00 40.00 N
+ATOM 5215 CA LEU C 288 -75.836 -7.654 74.729 1.00 40.00 C
+ATOM 5216 C LEU C 288 -75.752 -6.872 76.035 1.00 40.00 C
+ATOM 5217 O LEU C 288 -75.257 -7.395 77.041 1.00 40.00 O
+ATOM 5218 CB LEU C 288 -74.532 -7.464 73.946 1.00 40.00 C
+ATOM 5219 CG LEU C 288 -73.944 -8.643 73.165 1.00 40.00 C
+ATOM 5220 CD1 LEU C 288 -72.822 -8.153 72.265 1.00 40.00 C
+ATOM 5221 CD2 LEU C 288 -73.454 -9.764 74.079 1.00 40.00 C
+ATOM 5222 N ALA C 289 -76.221 -5.619 75.999 1.00 40.00 N
+ATOM 5223 CA ALA C 289 -76.168 -4.707 77.148 1.00 40.00 C
+ATOM 5224 C ALA C 289 -77.197 -5.087 78.212 1.00 40.00 C
+ATOM 5225 O ALA C 289 -76.830 -5.290 79.368 1.00 40.00 O
+ATOM 5226 CB ALA C 289 -76.346 -3.258 76.709 1.00 40.00 C
+ATOM 5227 N GLU C 290 -78.470 -5.199 77.819 1.00 40.00 N
+ATOM 5228 CA GLU C 290 -79.556 -5.609 78.725 1.00 40.00 C
+ATOM 5229 C GLU C 290 -79.351 -7.011 79.316 1.00 40.00 C
+ATOM 5230 O GLU C 290 -80.066 -7.389 80.243 1.00 40.00 O
+ATOM 5231 CB GLU C 290 -80.901 -5.530 78.002 1.00 40.00 C
+ATOM 5232 CG GLU C 290 -80.917 -6.309 76.686 1.00 40.00 C
+ATOM 5233 CD GLU C 290 -82.271 -6.330 75.987 1.00 40.00 C
+ATOM 5234 OE1 GLU C 290 -83.248 -6.824 76.590 1.00 40.00 O
+ATOM 5235 OE2 GLU C 290 -82.362 -5.880 74.819 1.00 40.00 O
+ATOM 5236 N LYS C 291 -78.394 -7.767 78.758 1.00 40.00 N
+ATOM 5237 CA LYS C 291 -77.908 -9.033 79.336 1.00 40.00 C
+ATOM 5238 C LYS C 291 -77.322 -8.849 80.720 1.00 40.00 C
+ATOM 5239 O LYS C 291 -77.598 -9.645 81.616 1.00 40.00 O
+ATOM 5240 CB LYS C 291 -76.820 -9.675 78.478 1.00 40.00 C
+ATOM 5241 CG LYS C 291 -77.331 -10.428 77.280 1.00 40.00 C
+ATOM 5242 CD LYS C 291 -78.345 -11.490 77.665 1.00 40.00 C
+ATOM 5243 CE LYS C 291 -78.957 -12.084 76.409 1.00 40.00 C
+ATOM 5244 NZ LYS C 291 -77.906 -12.452 75.414 1.00 40.00 N
+ATOM 5245 N ASP C 292 -76.482 -7.824 80.874 1.00 40.00 N
+ATOM 5246 CA ASP C 292 -75.886 -7.460 82.172 1.00 40.00 C
+ATOM 5247 C ASP C 292 -76.790 -6.492 82.982 1.00 40.00 C
+ATOM 5248 O ASP C 292 -76.403 -6.014 84.067 1.00 40.00 O
+ATOM 5249 CB ASP C 292 -74.483 -6.855 81.971 1.00 40.00 C
+ATOM 5250 CG ASP C 292 -73.524 -7.787 81.224 1.00 40.00 C
+ATOM 5251 OD1 ASP C 292 -73.969 -8.743 80.533 1.00 40.00 O
+ATOM 5252 OD2 ASP C 292 -72.300 -7.544 81.325 1.00 40.00 O
+ATOM 5253 N GLY C 293 -77.993 -6.234 82.448 1.00 40.00 N
+ATOM 5254 CA GLY C 293 -78.933 -5.240 82.980 1.00 40.00 C
+ATOM 5255 C GLY C 293 -78.596 -3.797 82.611 1.00 40.00 C
+ATOM 5256 O GLY C 293 -79.139 -2.867 83.212 1.00 40.00 O
+ATOM 5257 N ILE C 294 -77.715 -3.614 81.619 1.00 40.00 N
+ATOM 5258 CA ILE C 294 -77.146 -2.300 81.244 1.00 40.00 C
+ATOM 5259 C ILE C 294 -77.907 -1.643 80.081 1.00 40.00 C
+ATOM 5260 O ILE C 294 -78.306 -2.329 79.118 1.00 40.00 O
+ATOM 5261 CB ILE C 294 -75.635 -2.417 80.886 1.00 40.00 C
+ATOM 5262 CG1 ILE C 294 -74.832 -2.920 82.095 1.00 40.00 C
+ATOM 5263 CG2 ILE C 294 -75.072 -1.085 80.393 1.00 40.00 C
+ATOM 5264 CD1 ILE C 294 -73.423 -3.387 81.781 1.00 40.00 C
+ATOM 5265 N ASP C 295 -78.125 -0.325 80.184 1.00 40.00 N
+ATOM 5266 CA ASP C 295 -78.639 0.445 79.044 1.00 40.00 C
+ATOM 5267 C ASP C 295 -77.494 0.912 78.160 1.00 40.00 C
+ATOM 5268 O ASP C 295 -76.577 1.613 78.614 1.00 40.00 O
+ATOM 5269 CB ASP C 295 -79.511 1.633 79.446 1.00 40.00 C
+ATOM 5270 CG ASP C 295 -79.899 2.501 78.244 1.00 40.00 C
+ATOM 5271 OD1 ASP C 295 -80.288 3.665 78.437 1.00 40.00 O
+ATOM 5272 OD2 ASP C 295 -79.808 2.034 77.092 1.00 40.00 O
+ATOM 5273 N TRP C 296 -77.600 0.534 76.885 1.00 40.00 N
+ATOM 5274 CA TRP C 296 -76.529 0.648 75.898 1.00 40.00 C
+ATOM 5275 C TRP C 296 -76.038 2.056 75.666 1.00 40.00 C
+ATOM 5276 O TRP C 296 -74.839 2.331 75.760 1.00 40.00 O
+ATOM 5277 CB TRP C 296 -76.950 -0.047 74.595 1.00 40.00 C
+ATOM 5278 CG TRP C 296 -76.084 0.291 73.410 1.00 40.00 C
+ATOM 5279 CD1 TRP C 296 -76.497 0.815 72.192 1.00 40.00 C
+ATOM 5280 CD2 TRP C 296 -74.615 0.162 73.290 1.00 40.00 C
+ATOM 5281 NE1 TRP C 296 -75.424 1.004 71.347 1.00 40.00 N
+ATOM 5282 CE2 TRP C 296 -74.270 0.640 71.941 1.00 40.00 C
+ATOM 5283 CE3 TRP C 296 -73.598 -0.285 74.126 1.00 40.00 C
+ATOM 5284 CZ2 TRP C 296 -72.963 0.660 71.475 1.00 40.00 C
+ATOM 5285 CZ3 TRP C 296 -72.284 -0.258 73.646 1.00 40.00 C
+ATOM 5286 CH2 TRP C 296 -71.977 0.204 72.352 1.00 40.00 C
+ATOM 5287 N PHE C 297 -76.956 2.968 75.389 1.00 40.00 N
+ATOM 5288 CA PHE C 297 -76.564 4.311 74.989 1.00 40.00 C
+ATOM 5289 C PHE C 297 -75.797 5.018 76.101 1.00 40.00 C
+ATOM 5290 O PHE C 297 -74.883 5.790 75.832 1.00 40.00 O
+ATOM 5291 CB PHE C 297 -77.775 5.096 74.459 1.00 40.00 C
+ATOM 5292 CG PHE C 297 -78.383 4.482 73.216 1.00 40.00 C
+ATOM 5293 CD1 PHE C 297 -79.366 3.481 73.317 1.00 40.00 C
+ATOM 5294 CD2 PHE C 297 -77.945 4.862 71.947 1.00 40.00 C
+ATOM 5295 CE1 PHE C 297 -79.909 2.892 72.182 1.00 40.00 C
+ATOM 5296 CE2 PHE C 297 -78.488 4.275 70.812 1.00 40.00 C
+ATOM 5297 CZ PHE C 297 -79.470 3.291 70.929 1.00 40.00 C
+ATOM 5298 N ASP C 298 -76.121 4.692 77.345 1.00 40.00 N
+ATOM 5299 CA ASP C 298 -75.425 5.275 78.487 1.00 40.00 C
+ATOM 5300 C ASP C 298 -74.037 4.700 78.667 1.00 40.00 C
+ATOM 5301 O ASP C 298 -73.134 5.366 79.176 1.00 40.00 O
+ATOM 5302 CB ASP C 298 -76.243 5.069 79.750 1.00 40.00 C
+ATOM 5303 CG ASP C 298 -77.633 5.645 79.630 1.00 40.00 C
+ATOM 5304 OD1 ASP C 298 -78.258 5.871 80.683 1.00 40.00 O
+ATOM 5305 OD2 ASP C 298 -78.098 5.878 78.487 1.00 40.00 O
+ATOM 5306 N TYR C 299 -73.887 3.449 78.252 1.00 40.00 N
+ATOM 5307 CA TYR C 299 -72.596 2.796 78.245 1.00 40.00 C
+ATOM 5308 C TYR C 299 -71.802 3.322 77.057 1.00 40.00 C
+ATOM 5309 O TYR C 299 -70.592 3.506 77.144 1.00 40.00 O
+ATOM 5310 CB TYR C 299 -72.767 1.267 78.196 1.00 40.00 C
+ATOM 5311 CG TYR C 299 -71.513 0.469 78.519 1.00 40.00 C
+ATOM 5312 CD1 TYR C 299 -70.975 0.447 79.816 1.00 40.00 C
+ATOM 5313 CD2 TYR C 299 -70.870 -0.282 77.536 1.00 40.00 C
+ATOM 5314 CE1 TYR C 299 -69.820 -0.285 80.112 1.00 40.00 C
+ATOM 5315 CE2 TYR C 299 -69.720 -1.019 77.822 1.00 40.00 C
+ATOM 5316 CZ TYR C 299 -69.193 -1.022 79.106 1.00 40.00 C
+ATOM 5317 OH TYR C 299 -68.049 -1.754 79.383 1.00 40.00 O
+ATOM 5318 N LYS C 300 -72.504 3.588 75.958 1.00 40.00 N
+ATOM 5319 CA LYS C 300 -71.893 4.160 74.763 1.00 40.00 C
+ATOM 5320 C LYS C 300 -71.293 5.514 75.120 1.00 40.00 C
+ATOM 5321 O LYS C 300 -70.075 5.682 75.112 1.00 40.00 O
+ATOM 5322 CB LYS C 300 -72.929 4.300 73.638 1.00 40.00 C
+ATOM 5323 CG LYS C 300 -72.372 4.849 72.327 1.00 40.00 C
+ATOM 5324 CD LYS C 300 -73.469 5.273 71.355 1.00 40.00 C
+ATOM 5325 CE LYS C 300 -73.722 4.232 70.277 1.00 40.00 C
+ATOM 5326 NZ LYS C 300 -74.698 4.706 69.248 1.00 40.00 N
+ATOM 5327 N LYS C 301 -72.162 6.463 75.449 1.00 40.00 N
+ATOM 5328 CA LYS C 301 -71.758 7.758 75.951 1.00 40.00 C
+ATOM 5329 C LYS C 301 -70.460 7.633 76.698 1.00 40.00 C
+ATOM 5330 O LYS C 301 -69.474 8.258 76.345 1.00 40.00 O
+ATOM 5331 CB LYS C 301 -72.812 8.268 76.913 1.00 40.00 C
+ATOM 5332 CG LYS C 301 -74.047 8.816 76.234 1.00 40.00 C
+ATOM 5333 CD LYS C 301 -75.269 8.728 77.144 1.00 40.00 C
+ATOM 5334 CE LYS C 301 -76.391 9.685 76.736 1.00 40.00 C
+ATOM 5335 NZ LYS C 301 -76.720 9.751 75.272 1.00 40.00 N
+ATOM 5336 N GLN C 302 -70.479 6.789 77.723 1.00 40.00 N
+ATOM 5337 CA GLN C 302 -69.367 6.618 78.656 1.00 40.00 C
+ATOM 5338 C GLN C 302 -68.060 6.243 77.971 1.00 40.00 C
+ATOM 5339 O GLN C 302 -67.000 6.800 78.267 1.00 40.00 O
+ATOM 5340 CB GLN C 302 -69.739 5.568 79.703 1.00 40.00 C
+ATOM 5341 CG GLN C 302 -68.645 5.240 80.708 1.00 40.00 C
+ATOM 5342 CD GLN C 302 -68.967 3.996 81.524 1.00 40.00 C
+ATOM 5343 OE1 GLN C 302 -68.173 3.045 81.582 1.00 40.00 O
+ATOM 5344 NE2 GLN C 302 -70.143 3.987 82.151 1.00 40.00 N
+ATOM 5345 N LEU C 303 -68.138 5.293 77.055 1.00 40.00 N
+ATOM 5346 CA LEU C 303 -66.959 4.894 76.319 1.00 40.00 C
+ATOM 5347 C LEU C 303 -66.486 6.087 75.538 1.00 40.00 C
+ATOM 5348 O LEU C 303 -65.291 6.361 75.485 1.00 40.00 O
+ATOM 5349 CB LEU C 303 -67.268 3.735 75.378 1.00 40.00 C
+ATOM 5350 CG LEU C 303 -67.821 2.483 76.057 1.00 40.00 C
+ATOM 5351 CD1 LEU C 303 -68.639 1.688 75.062 1.00 40.00 C
+ATOM 5352 CD2 LEU C 303 -66.725 1.625 76.675 1.00 40.00 C
+ATOM 5353 N LYS C 304 -67.438 6.811 74.952 1.00 40.00 N
+ATOM 5354 CA LYS C 304 -67.100 7.991 74.175 1.00 40.00 C
+ATOM 5355 C LYS C 304 -66.335 8.961 75.050 1.00 40.00 C
+ATOM 5356 O LYS C 304 -65.245 9.385 74.673 1.00 40.00 O
+ATOM 5357 CB LYS C 304 -68.334 8.649 73.560 1.00 40.00 C
+ATOM 5358 CG LYS C 304 -68.934 7.832 72.431 1.00 40.00 C
+ATOM 5359 CD LYS C 304 -70.144 8.504 71.800 1.00 40.00 C
+ATOM 5360 CE LYS C 304 -69.834 9.105 70.436 1.00 40.00 C
+ATOM 5361 NZ LYS C 304 -71.088 9.574 69.780 1.00 40.00 N
+ATOM 5362 N ARG C 305 -66.876 9.281 76.228 1.00 40.00 N
+ATOM 5363 CA ARG C 305 -66.153 10.131 77.177 1.00 40.00 C
+ATOM 5364 C ARG C 305 -64.757 9.579 77.397 1.00 40.00 C
+ATOM 5365 O ARG C 305 -63.800 10.333 77.500 1.00 40.00 O
+ATOM 5366 CB ARG C 305 -66.892 10.287 78.508 1.00 40.00 C
+ATOM 5367 CG ARG C 305 -67.678 11.593 78.647 1.00 40.00 C
+ATOM 5368 CD ARG C 305 -68.207 11.813 80.063 1.00 40.00 C
+ATOM 5369 NE ARG C 305 -69.324 10.919 80.409 1.00 40.00 N
+ATOM 5370 CZ ARG C 305 -69.232 9.807 81.154 1.00 40.00 C
+ATOM 5371 NH1 ARG C 305 -68.062 9.412 81.663 1.00 40.00 N
+ATOM 5372 NH2 ARG C 305 -70.323 9.077 81.394 1.00 40.00 N
+ATOM 5373 N GLY C 306 -64.637 8.258 77.425 1.00 40.00 N
+ATOM 5374 CA GLY C 306 -63.328 7.640 77.506 1.00 40.00 C
+ATOM 5375 C GLY C 306 -62.574 7.621 76.184 1.00 40.00 C
+ATOM 5376 O GLY C 306 -61.561 6.929 76.059 1.00 40.00 O
+ATOM 5377 N ASP C 307 -63.056 8.372 75.195 1.00 40.00 N
+ATOM 5378 CA ASP C 307 -62.476 8.369 73.851 1.00 40.00 C
+ATOM 5379 C ASP C 307 -62.372 6.957 73.317 1.00 40.00 C
+ATOM 5380 O ASP C 307 -61.621 6.712 72.383 1.00 40.00 O
+ATOM 5381 CB ASP C 307 -61.082 9.005 73.845 1.00 40.00 C
+ATOM 5382 CG ASP C 307 -61.084 10.448 74.330 1.00 40.00 C
+ATOM 5383 OD1 ASP C 307 -61.835 11.291 73.785 1.00 40.00 O
+ATOM 5384 OD2 ASP C 307 -60.306 10.754 75.254 1.00 40.00 O
+ATOM 5385 N GLN C 308 -63.114 6.034 73.930 1.00 40.00 N
+ATOM 5386 CA GLN C 308 -63.027 4.601 73.617 1.00 40.00 C
+ATOM 5387 C GLN C 308 -63.980 4.208 72.484 1.00 40.00 C
+ATOM 5388 O GLN C 308 -63.879 3.113 71.940 1.00 40.00 O
+ATOM 5389 CB GLN C 308 -63.216 3.734 74.885 1.00 40.00 C
+ATOM 5390 CG GLN C 308 -61.956 3.664 75.762 1.00 40.00 C
+ATOM 5391 CD GLN C 308 -62.126 2.913 77.081 1.00 40.00 C
+ATOM 5392 OE1 GLN C 308 -62.191 1.691 77.121 1.00 40.00 O
+ATOM 5393 NE2 GLN C 308 -62.144 3.652 78.171 1.00 40.00 N
+ATOM 5394 N TRP C 309 -64.867 5.132 72.111 1.00 40.00 N
+ATOM 5395 CA TRP C 309 -65.828 4.942 71.016 1.00 40.00 C
+ATOM 5396 C TRP C 309 -65.759 6.118 70.100 1.00 40.00 C
+ATOM 5397 O TRP C 309 -65.982 7.262 70.524 1.00 40.00 O
+ATOM 5398 CB TRP C 309 -67.226 4.833 71.584 1.00 40.00 C
+ATOM 5399 CG TRP C 309 -68.287 4.382 70.620 1.00 40.00 C
+ATOM 5400 CD1 TRP C 309 -69.164 5.170 69.891 1.00 40.00 C
+ATOM 5401 CD2 TRP C 309 -68.651 3.005 70.297 1.00 40.00 C
+ATOM 5402 NE1 TRP C 309 -70.015 4.396 69.152 1.00 40.00 N
+ATOM 5403 CE2 TRP C 309 -69.759 3.085 69.350 1.00 40.00 C
+ATOM 5404 CE3 TRP C 309 -68.179 1.759 70.680 1.00 40.00 C
+ATOM 5405 CZ2 TRP C 309 -70.355 1.948 68.815 1.00 40.00 C
+ATOM 5406 CZ3 TRP C 309 -68.785 0.624 70.137 1.00 40.00 C
+ATOM 5407 CH2 TRP C 309 -69.846 0.716 69.226 1.00 40.00 C
+ATOM 5408 N ASN C 310 -65.440 5.846 68.835 1.00 40.00 N
+ATOM 5409 CA ASN C 310 -65.100 6.901 67.875 1.00 40.00 C
+ATOM 5410 C ASN C 310 -65.665 6.677 66.461 1.00 40.00 C
+ATOM 5411 O ASN C 310 -65.361 5.679 65.803 1.00 40.00 O
+ATOM 5412 CB ASN C 310 -63.578 7.129 67.843 1.00 40.00 C
+ATOM 5413 CG ASN C 310 -62.955 7.228 69.243 1.00 40.00 C
+ATOM 5414 OD1 ASN C 310 -63.358 8.044 70.084 1.00 40.00 O
+ATOM 5415 ND2 ASN C 310 -61.954 6.394 69.488 1.00 40.00 N
+ATOM 5416 N VAL C 311 -66.472 7.636 66.003 1.00 40.00 N
+ATOM 5417 CA VAL C 311 -67.351 7.446 64.851 1.00 40.00 C
+ATOM 5418 C VAL C 311 -67.171 8.507 63.762 1.00 40.00 C
+ATOM 5419 O VAL C 311 -67.185 9.709 64.034 1.00 40.00 O
+ATOM 5420 CB VAL C 311 -68.831 7.421 65.286 1.00 40.00 C
+ATOM 5421 CG1 VAL C 311 -69.731 7.059 64.118 1.00 40.00 C
+ATOM 5422 CG2 VAL C 311 -69.048 6.432 66.421 1.00 40.00 C
+ATOM 5423 N GLU C 312 -67.039 8.031 62.525 1.00 40.00 N
+ATOM 5424 CA GLU C 312 -66.745 8.851 61.356 1.00 40.00 C
+ATOM 5425 C GLU C 312 -67.498 8.262 60.178 1.00 40.00 C
+ATOM 5426 O GLU C 312 -66.919 7.510 59.399 1.00 40.00 O
+ATOM 5427 CB GLU C 312 -65.249 8.760 61.058 1.00 40.00 C
+ATOM 5428 CG GLU C 312 -64.717 9.626 59.923 1.00 40.00 C
+ATOM 5429 CD GLU C 312 -63.878 10.797 60.420 1.00 40.00 C
+ATOM 5430 OE1 GLU C 312 -64.374 11.541 61.312 1.00 40.00 O
+ATOM 5431 OE2 GLU C 312 -62.729 10.975 59.919 1.00 40.00 O
+ATOM 5432 N VAL C 313 -68.783 8.591 60.044 1.00 40.00 N
+ATOM 5433 CA VAL C 313 -69.602 8.065 58.928 1.00 40.00 C
+ATOM 5434 C VAL C 313 -70.199 9.157 58.029 1.00 40.00 C
+ATOM 5435 O VAL C 313 -70.390 10.299 58.468 1.00 40.00 O
+ATOM 5436 CB VAL C 313 -70.717 7.106 59.401 1.00 40.00 C
+ATOM 5437 CG1 VAL C 313 -70.114 5.853 60.013 1.00 40.00 C
+ATOM 5438 CG2 VAL C 313 -71.653 7.795 60.381 1.00 40.00 C
+ATOM 5439 N TYR C 314 -70.487 8.803 56.774 1.00 40.00 N
+ATOM 5440 CA TYR C 314 -70.949 9.777 55.778 1.00 40.00 C
+ATOM 5441 C TYR C 314 -71.875 9.124 54.771 1.00 40.00 C
+ATOM 5442 O TYR C 314 -71.981 7.896 54.713 1.00 40.00 O
+ATOM 5443 CB TYR C 314 -69.760 10.453 55.053 1.00 40.00 C
+ATOM 5444 CG TYR C 314 -68.662 9.485 54.630 1.00 40.00 C
+ATOM 5445 CD1 TYR C 314 -68.664 8.888 53.360 1.00 40.00 C
+ATOM 5446 CD2 TYR C 314 -67.617 9.165 55.504 1.00 40.00 C
+ATOM 5447 CE1 TYR C 314 -67.660 7.993 52.983 1.00 40.00 C
+ATOM 5448 CE2 TYR C 314 -66.615 8.267 55.141 1.00 40.00 C
+ATOM 5449 CZ TYR C 314 -66.630 7.681 53.884 1.00 40.00 C
+ATOM 5450 OH TYR C 314 -65.621 6.791 53.546 1.00 40.00 O
+ATOM 5451 OXT TYR C 314 -72.521 9.829 53.997 1.00 40.00 O
+TER 5452 TYR C 314
+ATOM 5453 N ALA D 1 -35.462 -28.005 -0.988 1.00 40.00 N
+ATOM 5454 CA ALA D 1 -33.990 -27.743 -0.945 1.00 40.00 C
+ATOM 5455 C ALA D 1 -33.218 -28.950 -0.428 1.00 40.00 C
+ATOM 5456 O ALA D 1 -33.724 -29.706 0.392 1.00 40.00 O
+ATOM 5457 CB ALA D 1 -33.694 -26.520 -0.090 1.00 40.00 C
+ATOM 5458 N THR D 2 -31.994 -29.120 -0.922 1.00 40.00 N
+ATOM 5459 CA THR D 2 -31.100 -30.212 -0.507 1.00 40.00 C
+ATOM 5460 C THR D 2 -29.765 -29.585 -0.074 1.00 40.00 C
+ATOM 5461 O THR D 2 -29.266 -28.676 -0.736 1.00 40.00 O
+ATOM 5462 CB THR D 2 -30.903 -31.259 -1.646 1.00 40.00 C
+ATOM 5463 OG1 THR D 2 -32.164 -31.853 -1.982 1.00 40.00 O
+ATOM 5464 CG2 THR D 2 -29.919 -32.368 -1.256 1.00 40.00 C
+ATOM 5465 N TYR D 3 -29.203 -30.050 1.043 1.00 40.00 N
+ATOM 5466 CA TYR D 3 -27.958 -29.483 1.598 1.00 40.00 C
+ATOM 5467 C TYR D 3 -26.955 -30.580 1.968 1.00 40.00 C
+ATOM 5468 O TYR D 3 -27.344 -31.720 2.244 1.00 40.00 O
+ATOM 5469 CB TYR D 3 -28.236 -28.636 2.848 1.00 40.00 C
+ATOM 5470 CG TYR D 3 -29.403 -27.660 2.765 1.00 40.00 C
+ATOM 5471 CD1 TYR D 3 -30.726 -28.102 2.902 1.00 40.00 C
+ATOM 5472 CD2 TYR D 3 -29.188 -26.294 2.602 1.00 40.00 C
+ATOM 5473 CE1 TYR D 3 -31.792 -27.219 2.856 1.00 40.00 C
+ATOM 5474 CE2 TYR D 3 -30.253 -25.404 2.556 1.00 40.00 C
+ATOM 5475 CZ TYR D 3 -31.551 -25.875 2.683 1.00 40.00 C
+ATOM 5476 OH TYR D 3 -32.616 -25.006 2.639 1.00 40.00 O
+ATOM 5477 N ASN D 4 -25.668 -30.227 1.985 1.00 40.00 N
+ATOM 5478 CA ASN D 4 -24.608 -31.176 2.363 1.00 40.00 C
+ATOM 5479 C ASN D 4 -24.573 -31.469 3.866 1.00 40.00 C
+ATOM 5480 O ASN D 4 -24.685 -30.559 4.709 1.00 40.00 O
+ATOM 5481 CB ASN D 4 -23.215 -30.727 1.859 1.00 40.00 C
+ATOM 5482 CG ASN D 4 -22.081 -31.649 2.329 1.00 40.00 C
+ATOM 5483 OD1 ASN D 4 -22.086 -32.860 2.063 1.00 40.00 O
+ATOM 5484 ND2 ASN D 4 -21.100 -31.071 3.031 1.00 40.00 N
+ATOM 5485 N VAL D 5 -24.434 -32.758 4.177 1.00 40.00 N
+ATOM 5486 CA VAL D 5 -24.203 -33.210 5.547 1.00 40.00 C
+ATOM 5487 C VAL D 5 -22.988 -34.128 5.629 1.00 40.00 C
+ATOM 5488 O VAL D 5 -22.810 -35.045 4.822 1.00 40.00 O
+ATOM 5489 CB VAL D 5 -25.432 -33.895 6.181 1.00 40.00 C
+ATOM 5490 CG1 VAL D 5 -25.227 -34.060 7.688 1.00 40.00 C
+ATOM 5491 CG2 VAL D 5 -26.706 -33.103 5.892 1.00 40.00 C
+ATOM 5492 N LYS D 6 -22.165 -33.849 6.629 1.00 40.00 N
+ATOM 5493 CA LYS D 6 -20.899 -34.513 6.844 1.00 40.00 C
+ATOM 5494 C LYS D 6 -21.017 -35.171 8.196 1.00 40.00 C
+ATOM 5495 O LYS D 6 -21.233 -34.507 9.212 1.00 40.00 O
+ATOM 5496 CB LYS D 6 -19.775 -33.465 6.832 1.00 40.00 C
+ATOM 5497 CG LYS D 6 -18.365 -33.958 7.139 1.00 40.00 C
+ATOM 5498 CD LYS D 6 -17.336 -32.820 7.112 1.00 40.00 C
+ATOM 5499 CE LYS D 6 -17.121 -32.260 5.703 1.00 40.00 C
+ATOM 5500 NZ LYS D 6 -15.848 -31.501 5.550 1.00 40.00 N
+ATOM 5501 N LEU D 7 -20.901 -36.487 8.205 1.00 40.00 N
+ATOM 5502 CA LEU D 7 -21.063 -37.224 9.444 1.00 40.00 C
+ATOM 5503 C LEU D 7 -19.755 -37.759 9.957 1.00 40.00 C
+ATOM 5504 O LEU D 7 -19.040 -38.472 9.254 1.00 40.00 O
+ATOM 5505 CB LEU D 7 -22.052 -38.371 9.280 1.00 40.00 C
+ATOM 5506 CG LEU D 7 -23.491 -37.929 9.037 1.00 40.00 C
+ATOM 5507 CD1 LEU D 7 -24.351 -39.145 8.751 1.00 40.00 C
+ATOM 5508 CD2 LEU D 7 -24.030 -37.156 10.231 1.00 40.00 C
+ATOM 5509 N ILE D 8 -19.455 -37.414 11.199 1.00 40.00 N
+ATOM 5510 CA ILE D 8 -18.237 -37.878 11.822 1.00 40.00 C
+ATOM 5511 C ILE D 8 -18.625 -39.018 12.753 1.00 40.00 C
+ATOM 5512 O ILE D 8 -18.820 -38.842 13.968 1.00 40.00 O
+ATOM 5513 CB ILE D 8 -17.461 -36.737 12.528 1.00 40.00 C
+ATOM 5514 CG1 ILE D 8 -17.575 -35.431 11.720 1.00 40.00 C
+ATOM 5515 CG2 ILE D 8 -15.993 -37.127 12.709 1.00 40.00 C
+ATOM 5516 CD1 ILE D 8 -17.774 -34.185 12.566 1.00 40.00 C
+ATOM 5517 N THR D 9 -18.764 -40.190 12.141 1.00 40.00 N
+ATOM 5518 CA THR D 9 -19.029 -41.428 12.864 1.00 40.00 C
+ATOM 5519 C THR D 9 -17.766 -41.815 13.684 1.00 40.00 C
+ATOM 5520 O THR D 9 -16.693 -41.221 13.476 1.00 40.00 O
+ATOM 5521 CB THR D 9 -19.509 -42.548 11.894 1.00 40.00 C
+ATOM 5522 OG1 THR D 9 -18.392 -43.275 11.365 1.00 40.00 O
+ATOM 5523 CG2 THR D 9 -20.334 -41.954 10.733 1.00 40.00 C
+ATOM 5524 N PRO D 10 -17.882 -42.780 14.634 1.00 40.00 N
+ATOM 5525 CA PRO D 10 -16.682 -43.237 15.361 1.00 40.00 C
+ATOM 5526 C PRO D 10 -15.761 -44.047 14.445 1.00 40.00 C
+ATOM 5527 O PRO D 10 -14.647 -44.427 14.832 1.00 40.00 O
+ATOM 5528 CB PRO D 10 -17.253 -44.146 16.463 1.00 40.00 C
+ATOM 5529 CG PRO D 10 -18.717 -43.874 16.494 1.00 40.00 C
+ATOM 5530 CD PRO D 10 -19.081 -43.501 15.091 1.00 40.00 C
+ATOM 5531 N GLU D 11 -16.250 -44.302 13.233 1.00 40.00 N
+ATOM 5532 CA GLU D 11 -15.498 -44.999 12.201 1.00 40.00 C
+ATOM 5533 C GLU D 11 -15.266 -44.098 10.987 1.00 40.00 C
+ATOM 5534 O GLU D 11 -15.336 -44.546 9.835 1.00 40.00 O
+ATOM 5535 CB GLU D 11 -16.239 -46.263 11.803 1.00 40.00 C
+ATOM 5536 CG GLU D 11 -16.520 -47.176 12.981 1.00 40.00 C
+ATOM 5537 CD GLU D 11 -16.924 -48.562 12.534 1.00 40.00 C
+ATOM 5538 OE1 GLU D 11 -17.983 -48.686 11.877 1.00 40.00 O
+ATOM 5539 OE2 GLU D 11 -16.178 -49.523 12.834 1.00 40.00 O
+ATOM 5540 N GLY D 12 -14.997 -42.822 11.268 1.00 40.00 N
+ATOM 5541 CA GLY D 12 -14.643 -41.853 10.246 1.00 40.00 C
+ATOM 5542 C GLY D 12 -15.780 -41.038 9.661 1.00 40.00 C
+ATOM 5543 O GLY D 12 -16.967 -41.191 10.004 1.00 40.00 O
+ATOM 5544 N GLU D 13 -15.380 -40.174 8.741 1.00 40.00 N
+ATOM 5545 CA GLU D 13 -16.259 -39.198 8.137 1.00 40.00 C
+ATOM 5546 C GLU D 13 -16.964 -39.785 6.905 1.00 40.00 C
+ATOM 5547 O GLU D 13 -16.455 -40.721 6.284 1.00 40.00 O
+ATOM 5548 CB GLU D 13 -15.419 -37.966 7.776 1.00 40.00 C
+ATOM 5549 CG GLU D 13 -16.187 -36.661 7.613 1.00 40.00 C
+ATOM 5550 CD GLU D 13 -15.354 -35.597 6.916 1.00 40.00 C
+ATOM 5551 OE1 GLU D 13 -15.670 -35.274 5.740 1.00 40.00 O
+ATOM 5552 OE2 GLU D 13 -14.380 -35.101 7.539 1.00 40.00 O
+ATOM 5553 N VAL D 14 -18.144 -39.247 6.584 1.00 40.00 N
+ATOM 5554 CA VAL D 14 -18.858 -39.553 5.335 1.00 40.00 C
+ATOM 5555 C VAL D 14 -19.938 -38.494 5.058 1.00 40.00 C
+ATOM 5556 O VAL D 14 -20.680 -38.083 5.959 1.00 40.00 O
+ATOM 5557 CB VAL D 14 -19.414 -41.005 5.304 1.00 40.00 C
+ATOM 5558 CG1 VAL D 14 -20.356 -41.269 6.477 1.00 40.00 C
+ATOM 5559 CG2 VAL D 14 -20.061 -41.319 3.958 1.00 40.00 C
+ATOM 5560 N GLU D 15 -20.000 -38.040 3.811 1.00 40.00 N
+ATOM 5561 CA GLU D 15 -20.914 -36.962 3.443 1.00 40.00 C
+ATOM 5562 C GLU D 15 -22.038 -37.474 2.566 1.00 40.00 C
+ATOM 5563 O GLU D 15 -21.991 -38.614 2.106 1.00 40.00 O
+ATOM 5564 CB GLU D 15 -20.168 -35.817 2.749 1.00 40.00 C
+ATOM 5565 CG GLU D 15 -19.062 -35.181 3.588 1.00 40.00 C
+ATOM 5566 CD GLU D 15 -18.267 -34.130 2.824 1.00 40.00 C
+ATOM 5567 OE1 GLU D 15 -17.016 -34.205 2.846 1.00 40.00 O
+ATOM 5568 OE2 GLU D 15 -18.888 -33.231 2.199 1.00 40.00 O
+ATOM 5569 N LEU D 16 -23.041 -36.623 2.347 1.00 40.00 N
+ATOM 5570 CA LEU D 16 -24.273 -37.025 1.671 1.00 40.00 C
+ATOM 5571 C LEU D 16 -25.290 -35.900 1.540 1.00 40.00 C
+ATOM 5572 O LEU D 16 -25.238 -34.910 2.271 1.00 40.00 O
+ATOM 5573 CB LEU D 16 -24.935 -38.168 2.431 1.00 40.00 C
+ATOM 5574 CG LEU D 16 -25.333 -37.858 3.880 1.00 40.00 C
+ATOM 5575 CD1 LEU D 16 -26.649 -38.555 4.225 1.00 40.00 C
+ATOM 5576 CD2 LEU D 16 -24.214 -38.227 4.860 1.00 40.00 C
+ATOM 5577 N GLN D 17 -26.244 -36.099 0.636 1.00 40.00 N
+ATOM 5578 CA GLN D 17 -27.202 -35.062 0.273 1.00 40.00 C
+ATOM 5579 C GLN D 17 -28.566 -35.289 0.897 1.00 40.00 C
+ATOM 5580 O GLN D 17 -29.179 -36.339 0.686 1.00 40.00 O
+ATOM 5581 CB GLN D 17 -27.326 -34.976 -1.255 1.00 40.00 C
+ATOM 5582 CG GLN D 17 -26.062 -34.470 -1.927 1.00 40.00 C
+ATOM 5583 CD GLN D 17 -25.494 -33.236 -1.232 1.00 40.00 C
+ATOM 5584 OE1 GLN D 17 -24.355 -33.250 -0.750 1.00 40.00 O
+ATOM 5585 NE2 GLN D 17 -26.296 -32.167 -1.158 1.00 40.00 N
+ATOM 5586 N VAL D 18 -29.044 -34.304 1.657 1.00 40.00 N
+ATOM 5587 CA VAL D 18 -30.330 -34.447 2.344 1.00 40.00 C
+ATOM 5588 C VAL D 18 -31.340 -33.338 2.054 1.00 40.00 C
+ATOM 5589 O VAL D 18 -31.102 -32.168 2.394 1.00 40.00 O
+ATOM 5590 CB VAL D 18 -30.170 -34.558 3.869 1.00 40.00 C
+ATOM 5591 CG1 VAL D 18 -31.451 -35.132 4.485 1.00 40.00 C
+ATOM 5592 CG2 VAL D 18 -28.945 -35.400 4.213 1.00 40.00 C
+ATOM 5593 N PRO D 19 -32.482 -33.710 1.437 1.00 40.00 N
+ATOM 5594 CA PRO D 19 -33.627 -32.795 1.249 1.00 40.00 C
+ATOM 5595 C PRO D 19 -34.182 -32.276 2.586 1.00 40.00 C
+ATOM 5596 O PRO D 19 -34.333 -33.067 3.528 1.00 40.00 O
+ATOM 5597 CB PRO D 19 -34.660 -33.672 0.522 1.00 40.00 C
+ATOM 5598 CG PRO D 19 -33.839 -34.715 -0.182 1.00 40.00 C
+ATOM 5599 CD PRO D 19 -32.672 -34.994 0.725 1.00 40.00 C
+ATOM 5600 N ASP D 20 -34.474 -30.971 2.655 1.00 40.00 N
+ATOM 5601 CA ASP D 20 -34.919 -30.295 3.906 1.00 40.00 C
+ATOM 5602 C ASP D 20 -36.309 -30.697 4.472 1.00 40.00 C
+ATOM 5603 O ASP D 20 -36.773 -30.117 5.478 1.00 40.00 O
+ATOM 5604 CB ASP D 20 -34.789 -28.749 3.795 1.00 40.00 C
+ATOM 5605 CG ASP D 20 -35.867 -28.085 2.879 1.00 40.00 C
+ATOM 5606 OD1 ASP D 20 -35.752 -26.857 2.662 1.00 40.00 O
+ATOM 5607 OD2 ASP D 20 -36.816 -28.743 2.377 1.00 40.00 O
+ATOM 5608 N ASP D 21 -36.944 -31.680 3.816 1.00 40.00 N
+ATOM 5609 CA ASP D 21 -38.240 -32.261 4.221 1.00 40.00 C
+ATOM 5610 C ASP D 21 -38.120 -33.722 4.685 1.00 40.00 C
+ATOM 5611 O ASP D 21 -39.118 -34.329 5.081 1.00 40.00 O
+ATOM 5612 CB ASP D 21 -39.281 -32.134 3.091 1.00 40.00 C
+ATOM 5613 CG ASP D 21 -38.698 -32.407 1.695 1.00 40.00 C
+ATOM 5614 OD1 ASP D 21 -37.603 -33.002 1.570 1.00 40.00 O
+ATOM 5615 OD2 ASP D 21 -39.348 -32.021 0.704 1.00 40.00 O
+ATOM 5616 N VAL D 22 -36.895 -34.260 4.640 1.00 40.00 N
+ATOM 5617 CA VAL D 22 -36.580 -35.625 5.062 1.00 40.00 C
+ATOM 5618 C VAL D 22 -35.696 -35.571 6.301 1.00 40.00 C
+ATOM 5619 O VAL D 22 -34.720 -34.827 6.346 1.00 40.00 O
+ATOM 5620 CB VAL D 22 -35.870 -36.428 3.935 1.00 40.00 C
+ATOM 5621 CG1 VAL D 22 -35.412 -37.798 4.430 1.00 40.00 C
+ATOM 5622 CG2 VAL D 22 -36.787 -36.592 2.725 1.00 40.00 C
+ATOM 5623 N TYR D 23 -36.055 -36.356 7.310 1.00 40.00 N
+ATOM 5624 CA TYR D 23 -35.212 -36.522 8.483 1.00 40.00 C
+ATOM 5625 C TYR D 23 -33.854 -37.067 8.097 1.00 40.00 C
+ATOM 5626 O TYR D 23 -33.723 -37.835 7.146 1.00 40.00 O
+ATOM 5627 CB TYR D 23 -35.854 -37.467 9.490 1.00 40.00 C
+ATOM 5628 CG TYR D 23 -37.118 -36.945 10.121 1.00 40.00 C
+ATOM 5629 CD1 TYR D 23 -38.349 -37.544 9.864 1.00 40.00 C
+ATOM 5630 CD2 TYR D 23 -37.087 -35.858 10.981 1.00 40.00 C
+ATOM 5631 CE1 TYR D 23 -39.510 -37.070 10.452 1.00 40.00 C
+ATOM 5632 CE2 TYR D 23 -38.240 -35.374 11.569 1.00 40.00 C
+ATOM 5633 CZ TYR D 23 -39.445 -35.980 11.305 1.00 40.00 C
+ATOM 5634 OH TYR D 23 -40.575 -35.478 11.901 1.00 40.00 O
+ATOM 5635 N ILE D 24 -32.849 -36.675 8.865 1.00 40.00 N
+ATOM 5636 CA ILE D 24 -31.455 -36.971 8.543 1.00 40.00 C
+ATOM 5637 C ILE D 24 -31.105 -38.467 8.576 1.00 40.00 C
+ATOM 5638 O ILE D 24 -30.468 -38.978 7.649 1.00 40.00 O
+ATOM 5639 CB ILE D 24 -30.484 -36.168 9.451 1.00 40.00 C
+ATOM 5640 CG1 ILE D 24 -30.558 -34.661 9.128 1.00 40.00 C
+ATOM 5641 CG2 ILE D 24 -29.050 -36.693 9.311 1.00 40.00 C
+ATOM 5642 CD1 ILE D 24 -30.128 -33.749 10.260 1.00 40.00 C
+ATOM 5643 N LEU D 25 -31.509 -39.151 9.649 1.00 40.00 N
+ATOM 5644 CA LEU D 25 -31.208 -40.580 9.845 1.00 40.00 C
+ATOM 5645 C LEU D 25 -31.864 -41.426 8.757 1.00 40.00 C
+ATOM 5646 O LEU D 25 -31.263 -42.402 8.290 1.00 40.00 O
+ATOM 5647 CB LEU D 25 -31.664 -41.037 11.237 1.00 40.00 C
+ATOM 5648 CG LEU D 25 -31.419 -42.468 11.725 1.00 40.00 C
+ATOM 5649 CD1 LEU D 25 -30.012 -42.638 12.271 1.00 40.00 C
+ATOM 5650 CD2 LEU D 25 -32.454 -42.809 12.791 1.00 40.00 C
+ATOM 5651 N ASP D 26 -33.089 -41.034 8.371 1.00 40.00 N
+ATOM 5652 CA ASP D 26 -33.819 -41.613 7.241 1.00 40.00 C
+ATOM 5653 C ASP D 26 -32.915 -41.732 6.025 1.00 40.00 C
+ATOM 5654 O ASP D 26 -32.703 -42.837 5.496 1.00 40.00 O
+ATOM 5655 CB ASP D 26 -35.032 -40.746 6.890 1.00 40.00 C
+ATOM 5656 CG ASP D 26 -36.116 -40.819 7.934 1.00 40.00 C
+ATOM 5657 OD1 ASP D 26 -35.968 -41.620 8.888 1.00 40.00 O
+ATOM 5658 OD2 ASP D 26 -37.120 -40.082 7.793 1.00 40.00 O
+ATOM 5659 N GLN D 27 -32.377 -40.586 5.601 1.00 40.00 N
+ATOM 5660 CA GLN D 27 -31.390 -40.520 4.521 1.00 40.00 C
+ATOM 5661 C GLN D 27 -30.182 -41.470 4.732 1.00 40.00 C
+ATOM 5662 O GLN D 27 -29.927 -42.350 3.896 1.00 40.00 O
+ATOM 5663 CB GLN D 27 -30.925 -39.072 4.335 1.00 40.00 C
+ATOM 5664 CG GLN D 27 -30.270 -38.802 2.996 1.00 40.00 C
+ATOM 5665 CD GLN D 27 -31.189 -39.139 1.849 1.00 40.00 C
+ATOM 5666 OE1 GLN D 27 -32.315 -38.633 1.766 1.00 40.00 O
+ATOM 5667 NE2 GLN D 27 -30.722 -40.009 0.960 1.00 40.00 N
+ATOM 5668 N ALA D 28 -29.471 -41.294 5.855 1.00 40.00 N
+ATOM 5669 CA ALA D 28 -28.270 -42.073 6.206 1.00 40.00 C
+ATOM 5670 C ALA D 28 -28.468 -43.556 5.970 1.00 40.00 C
+ATOM 5671 O ALA D 28 -27.605 -44.227 5.421 1.00 40.00 O
+ATOM 5672 CB ALA D 28 -27.885 -41.829 7.658 1.00 40.00 C
+ATOM 5673 N GLU D 29 -29.630 -44.040 6.386 1.00 40.00 N
+ATOM 5674 CA GLU D 29 -30.022 -45.430 6.252 1.00 40.00 C
+ATOM 5675 C GLU D 29 -30.128 -45.910 4.788 1.00 40.00 C
+ATOM 5676 O GLU D 29 -29.498 -46.910 4.438 1.00 40.00 O
+ATOM 5677 CB GLU D 29 -31.340 -45.626 6.992 1.00 40.00 C
+ATOM 5678 CG GLU D 29 -31.734 -47.058 7.294 1.00 40.00 C
+ATOM 5679 CD GLU D 29 -33.203 -47.154 7.665 1.00 40.00 C
+ATOM 5680 OE1 GLU D 29 -33.816 -46.099 7.943 1.00 40.00 O
+ATOM 5681 OE2 GLU D 29 -33.757 -48.276 7.673 1.00 40.00 O
+ATOM 5682 N GLU D 30 -30.908 -45.217 3.943 1.00 40.00 N
+ATOM 5683 CA GLU D 30 -31.027 -45.583 2.505 1.00 40.00 C
+ATOM 5684 C GLU D 30 -29.698 -45.452 1.817 1.00 40.00 C
+ATOM 5685 O GLU D 30 -29.450 -46.112 0.803 1.00 40.00 O
+ATOM 5686 CB GLU D 30 -31.962 -44.666 1.742 1.00 40.00 C
+ATOM 5687 CG GLU D 30 -33.420 -44.830 2.039 1.00 40.00 C
+ATOM 5688 CD GLU D 30 -34.138 -43.576 1.635 1.00 40.00 C
+ATOM 5689 OE1 GLU D 30 -33.848 -43.103 0.510 1.00 40.00 O
+ATOM 5690 OE2 GLU D 30 -34.944 -43.052 2.443 1.00 40.00 O
+ATOM 5691 N ASP D 31 -28.868 -44.559 2.357 1.00 40.00 N
+ATOM 5692 CA ASP D 31 -27.512 -44.354 1.875 1.00 40.00 C
+ATOM 5693 C ASP D 31 -26.550 -45.344 2.526 1.00 40.00 C
+ATOM 5694 O ASP D 31 -25.332 -45.214 2.397 1.00 40.00 O
+ATOM 5695 CB ASP D 31 -27.083 -42.893 2.073 1.00 40.00 C
+ATOM 5696 CG ASP D 31 -27.815 -41.937 1.124 1.00 40.00 C
+ATOM 5697 OD1 ASP D 31 -28.789 -42.368 0.454 1.00 40.00 O
+ATOM 5698 OD2 ASP D 31 -27.422 -40.749 1.045 1.00 40.00 O
+ATOM 5699 N GLY D 32 -27.116 -46.335 3.214 1.00 40.00 N
+ATOM 5700 CA GLY D 32 -26.358 -47.479 3.714 1.00 40.00 C
+ATOM 5701 C GLY D 32 -25.488 -47.263 4.938 1.00 40.00 C
+ATOM 5702 O GLY D 32 -24.548 -48.036 5.180 1.00 40.00 O
+ATOM 5703 N ILE D 33 -25.802 -46.222 5.710 1.00 40.00 N
+ATOM 5704 CA ILE D 33 -25.006 -45.863 6.884 1.00 40.00 C
+ATOM 5705 C ILE D 33 -25.730 -46.315 8.156 1.00 40.00 C
+ATOM 5706 O ILE D 33 -26.948 -46.112 8.314 1.00 40.00 O
+ATOM 5707 CB ILE D 33 -24.643 -44.350 6.925 1.00 40.00 C
+ATOM 5708 CG1 ILE D 33 -24.297 -43.825 5.519 1.00 40.00 C
+ATOM 5709 CG2 ILE D 33 -23.466 -44.112 7.869 1.00 40.00 C
+ATOM 5710 CD1 ILE D 33 -24.632 -42.366 5.278 1.00 40.00 C
+ATOM 5711 N ASP D 34 -24.955 -46.952 9.036 1.00 40.00 N
+ATOM 5712 CA ASP D 34 -25.441 -47.504 10.301 1.00 40.00 C
+ATOM 5713 C ASP D 34 -25.234 -46.517 11.480 1.00 40.00 C
+ATOM 5714 O ASP D 34 -24.148 -46.444 12.076 1.00 40.00 O
+ATOM 5715 CB ASP D 34 -24.769 -48.869 10.563 1.00 40.00 C
+ATOM 5716 CG ASP D 34 -25.460 -49.688 11.665 1.00 40.00 C
+ATOM 5717 OD1 ASP D 34 -26.592 -49.350 12.086 1.00 40.00 O
+ATOM 5718 OD2 ASP D 34 -24.859 -50.691 12.109 1.00 40.00 O
+ATOM 5719 N LEU D 35 -26.290 -45.758 11.790 1.00 40.00 N
+ATOM 5720 CA LEU D 35 -26.304 -44.789 12.895 1.00 40.00 C
+ATOM 5721 C LEU D 35 -27.220 -45.285 13.997 1.00 40.00 C
+ATOM 5722 O LEU D 35 -28.292 -45.810 13.704 1.00 40.00 O
+ATOM 5723 CB LEU D 35 -26.829 -43.439 12.415 1.00 40.00 C
+ATOM 5724 CG LEU D 35 -26.151 -42.793 11.216 1.00 40.00 C
+ATOM 5725 CD1 LEU D 35 -26.983 -41.600 10.799 1.00 40.00 C
+ATOM 5726 CD2 LEU D 35 -24.732 -42.379 11.586 1.00 40.00 C
+ATOM 5727 N PRO D 36 -26.829 -45.086 15.268 1.00 40.00 N
+ATOM 5728 CA PRO D 36 -27.635 -45.625 16.359 1.00 40.00 C
+ATOM 5729 C PRO D 36 -29.022 -44.966 16.408 1.00 40.00 C
+ATOM 5730 O PRO D 36 -29.167 -43.807 15.996 1.00 40.00 O
+ATOM 5731 CB PRO D 36 -26.810 -45.285 17.602 1.00 40.00 C
+ATOM 5732 CG PRO D 36 -26.072 -44.049 17.220 1.00 40.00 C
+ATOM 5733 CD PRO D 36 -25.758 -44.202 15.758 1.00 40.00 C
+ATOM 5734 N TYR D 37 -30.017 -45.732 16.869 1.00 40.00 N
+ATOM 5735 CA TYR D 37 -31.418 -45.289 16.994 1.00 40.00 C
+ATOM 5736 C TYR D 37 -32.237 -46.232 17.871 1.00 40.00 C
+ATOM 5737 O TYR D 37 -31.779 -47.329 18.213 1.00 40.00 O
+ATOM 5738 CB TYR D 37 -32.107 -45.139 15.621 1.00 40.00 C
+ATOM 5739 CG TYR D 37 -32.334 -46.423 14.822 1.00 40.00 C
+ATOM 5740 CD1 TYR D 37 -31.271 -47.064 14.170 1.00 40.00 C
+ATOM 5741 CD2 TYR D 37 -33.614 -46.970 14.682 1.00 40.00 C
+ATOM 5742 CE1 TYR D 37 -31.464 -48.221 13.429 1.00 40.00 C
+ATOM 5743 CE2 TYR D 37 -33.822 -48.123 13.933 1.00 40.00 C
+ATOM 5744 CZ TYR D 37 -32.740 -48.745 13.309 1.00 40.00 C
+ATOM 5745 OH TYR D 37 -32.910 -49.896 12.559 1.00 40.00 O
+ATOM 5746 N SER D 38 -33.449 -45.794 18.221 1.00 40.00 N
+ATOM 5747 CA SER D 38 -34.385 -46.595 19.005 1.00 40.00 C
+ATOM 5748 C SER D 38 -35.825 -46.245 18.635 1.00 40.00 C
+ATOM 5749 O SER D 38 -36.444 -46.934 17.818 1.00 40.00 O
+ATOM 5750 CB SER D 38 -34.140 -46.385 20.506 1.00 40.00 C
+ATOM 5751 OG SER D 38 -34.786 -47.367 21.288 1.00 40.00 O
+ATOM 5752 N CYS D 39 -36.324 -45.158 19.229 1.00 40.00 N
+ATOM 5753 CA CYS D 39 -37.730 -44.741 19.153 1.00 40.00 C
+ATOM 5754 C CYS D 39 -38.129 -44.304 17.760 1.00 40.00 C
+ATOM 5755 O CYS D 39 -39.217 -44.632 17.263 1.00 40.00 O
+ATOM 5756 CB CYS D 39 -37.984 -43.574 20.117 1.00 40.00 C
+ATOM 5757 SG CYS D 39 -37.365 -41.965 19.544 1.00 40.00 S
+ATOM 5758 N ARG D 40 -37.229 -43.540 17.151 1.00 40.00 N
+ATOM 5759 CA ARG D 40 -37.478 -42.902 15.880 1.00 40.00 C
+ATOM 5760 C ARG D 40 -38.738 -42.063 15.967 1.00 40.00 C
+ATOM 5761 O ARG D 40 -39.567 -42.064 15.062 1.00 40.00 O
+ATOM 5762 CB ARG D 40 -37.559 -43.935 14.754 1.00 40.00 C
+ATOM 5763 CG ARG D 40 -36.222 -44.608 14.461 1.00 40.00 C
+ATOM 5764 CD ARG D 40 -36.386 -45.810 13.539 1.00 40.00 C
+ATOM 5765 NE ARG D 40 -36.719 -45.420 12.174 1.00 40.00 N
+ATOM 5766 CZ ARG D 40 -35.824 -45.218 11.217 1.00 40.00 C
+ATOM 5767 NH1 ARG D 40 -34.534 -45.372 11.474 1.00 40.00 N
+ATOM 5768 NH2 ARG D 40 -36.224 -44.857 10.007 1.00 40.00 N
+ATOM 5769 N ALA D 41 -38.879 -41.362 17.083 1.00 40.00 N
+ATOM 5770 CA ALA D 41 -39.955 -40.405 17.250 1.00 40.00 C
+ATOM 5771 C ALA D 41 -39.513 -39.287 18.186 1.00 40.00 C
+ATOM 5772 O ALA D 41 -40.335 -38.544 18.737 1.00 40.00 O
+ATOM 5773 CB ALA D 41 -41.221 -41.088 17.736 1.00 40.00 C
+ATOM 5774 N GLY D 42 -38.198 -39.187 18.357 1.00 40.00 N
+ATOM 5775 CA GLY D 42 -37.581 -38.012 18.949 1.00 40.00 C
+ATOM 5776 C GLY D 42 -37.859 -37.764 20.413 1.00 40.00 C
+ATOM 5777 O GLY D 42 -37.872 -36.624 20.873 1.00 40.00 O
+ATOM 5778 N SER D 43 -38.087 -38.818 21.167 1.00 40.00 N
+ATOM 5779 CA SER D 43 -38.162 -38.622 22.586 1.00 40.00 C
+ATOM 5780 C SER D 43 -37.345 -39.697 23.266 1.00 40.00 C
+ATOM 5781 O SER D 43 -37.779 -40.267 24.261 1.00 40.00 O
+ATOM 5782 CB SER D 43 -39.611 -38.598 23.068 1.00 40.00 C
+ATOM 5783 OG SER D 43 -40.169 -39.883 22.990 1.00 40.00 O
+ATOM 5784 N CYS D 44 -36.165 -39.980 22.711 1.00 40.00 N
+ATOM 5785 CA CYS D 44 -35.177 -40.867 23.360 1.00 40.00 C
+ATOM 5786 C CYS D 44 -33.755 -40.327 23.180 1.00 40.00 C
+ATOM 5787 O CYS D 44 -33.580 -39.162 22.805 1.00 40.00 O
+ATOM 5788 CB CYS D 44 -35.297 -42.320 22.872 1.00 40.00 C
+ATOM 5789 SG CYS D 44 -34.195 -42.765 21.510 1.00 40.00 S
+ATOM 5790 N SER D 45 -32.752 -41.167 23.437 1.00 40.00 N
+ATOM 5791 CA SER D 45 -31.367 -40.714 23.418 1.00 40.00 C
+ATOM 5792 C SER D 45 -30.437 -41.428 22.434 1.00 40.00 C
+ATOM 5793 O SER D 45 -29.278 -41.033 22.294 1.00 40.00 O
+ATOM 5794 CB SER D 45 -30.783 -40.806 24.822 1.00 40.00 C
+ATOM 5795 OG SER D 45 -30.887 -42.124 25.312 1.00 40.00 O
+ATOM 5796 N SER D 46 -30.942 -42.449 21.745 1.00 40.00 N
+ATOM 5797 CA SER D 46 -30.090 -43.369 20.973 1.00 40.00 C
+ATOM 5798 C SER D 46 -29.371 -42.757 19.790 1.00 40.00 C
+ATOM 5799 O SER D 46 -28.178 -43.002 19.594 1.00 40.00 O
+ATOM 5800 CB SER D 46 -30.900 -44.561 20.496 1.00 40.00 C
+ATOM 5801 OG SER D 46 -31.220 -45.408 21.586 1.00 40.00 O
+ATOM 5802 N CYS D 47 -30.109 -41.964 19.015 1.00 40.00 N
+ATOM 5803 CA CYS D 47 -29.601 -41.327 17.791 1.00 40.00 C
+ATOM 5804 C CYS D 47 -28.733 -40.083 18.034 1.00 40.00 C
+ATOM 5805 O CYS D 47 -28.312 -39.413 17.079 1.00 40.00 O
+ATOM 5806 CB CYS D 47 -30.767 -40.990 16.867 1.00 40.00 C
+ATOM 5807 SG CYS D 47 -32.074 -40.088 17.697 1.00 40.00 S
+ATOM 5808 N ALA D 48 -28.455 -39.815 19.313 1.00 40.00 N
+ATOM 5809 CA ALA D 48 -27.720 -38.639 19.769 1.00 40.00 C
+ATOM 5810 C ALA D 48 -26.500 -38.306 18.946 1.00 40.00 C
+ATOM 5811 O ALA D 48 -25.771 -39.174 18.461 1.00 40.00 O
+ATOM 5812 CB ALA D 48 -27.329 -38.777 21.230 1.00 40.00 C
+ATOM 5813 N GLY D 49 -26.302 -37.009 18.809 1.00 40.00 N
+ATOM 5814 CA GLY D 49 -25.183 -36.465 18.081 1.00 40.00 C
+ATOM 5815 C GLY D 49 -24.997 -35.007 18.441 1.00 40.00 C
+ATOM 5816 O GLY D 49 -25.828 -34.415 19.150 1.00 40.00 O
+ATOM 5817 N LYS D 50 -23.907 -34.426 17.940 1.00 40.00 N
+ATOM 5818 CA LYS D 50 -23.546 -33.038 18.254 1.00 40.00 C
+ATOM 5819 C LYS D 50 -23.358 -32.170 16.997 1.00 40.00 C
+ATOM 5820 O LYS D 50 -22.594 -32.544 16.098 1.00 40.00 O
+ATOM 5821 CB LYS D 50 -22.267 -32.997 19.117 1.00 40.00 C
+ATOM 5822 CG LYS D 50 -22.432 -33.498 20.548 1.00 40.00 C
+ATOM 5823 CD LYS D 50 -21.540 -32.723 21.501 1.00 40.00 C
+ATOM 5824 CE LYS D 50 -22.085 -31.326 21.724 1.00 40.00 C
+ATOM 5825 NZ LYS D 50 -21.109 -30.511 22.488 1.00 40.00 N
+ATOM 5826 N VAL D 51 -24.048 -31.023 16.946 1.00 40.00 N
+ATOM 5827 CA VAL D 51 -23.841 -30.035 15.880 1.00 40.00 C
+ATOM 5828 C VAL D 51 -22.471 -29.386 16.034 1.00 40.00 C
+ATOM 5829 O VAL D 51 -22.185 -28.787 17.072 1.00 40.00 O
+ATOM 5830 CB VAL D 51 -24.925 -28.931 15.872 1.00 40.00 C
+ATOM 5831 CG1 VAL D 51 -24.640 -27.886 14.792 1.00 40.00 C
+ATOM 5832 CG2 VAL D 51 -26.294 -29.551 15.662 1.00 40.00 C
+ATOM 5833 N VAL D 52 -21.629 -29.540 15.008 1.00 40.00 N
+ATOM 5834 CA VAL D 52 -20.333 -28.845 14.904 1.00 40.00 C
+ATOM 5835 C VAL D 52 -20.541 -27.494 14.175 1.00 40.00 C
+ATOM 5836 O VAL D 52 -19.970 -26.463 14.566 1.00 40.00 O
+ATOM 5837 CB VAL D 52 -19.254 -29.729 14.200 1.00 40.00 C
+ATOM 5838 CG1 VAL D 52 -17.900 -29.028 14.118 1.00 40.00 C
+ATOM 5839 CG2 VAL D 52 -19.104 -31.068 14.911 1.00 40.00 C
+ATOM 5840 N SER D 53 -21.385 -27.506 13.141 1.00 40.00 N
+ATOM 5841 CA SER D 53 -21.648 -26.329 12.328 1.00 40.00 C
+ATOM 5842 C SER D 53 -22.962 -26.503 11.605 1.00 40.00 C
+ATOM 5843 O SER D 53 -23.525 -27.593 11.585 1.00 40.00 O
+ATOM 5844 CB SER D 53 -20.527 -26.129 11.305 1.00 40.00 C
+ATOM 5845 OG SER D 53 -20.487 -27.198 10.377 1.00 40.00 O
+ATOM 5846 N GLY D 54 -23.440 -25.426 10.998 1.00 40.00 N
+ATOM 5847 CA GLY D 54 -24.700 -25.460 10.292 1.00 40.00 C
+ATOM 5848 C GLY D 54 -25.864 -25.582 11.252 1.00 40.00 C
+ATOM 5849 O GLY D 54 -25.683 -25.795 12.464 1.00 40.00 O
+ATOM 5850 N SER D 55 -27.062 -25.452 10.686 1.00 40.00 N
+ATOM 5851 CA SER D 55 -28.316 -25.423 11.447 1.00 40.00 C
+ATOM 5852 C SER D 55 -29.263 -26.588 11.094 1.00 40.00 C
+ATOM 5853 O SER D 55 -29.151 -27.193 10.010 1.00 40.00 O
+ATOM 5854 CB SER D 55 -29.028 -24.051 11.295 1.00 40.00 C
+ATOM 5855 OG SER D 55 -29.234 -23.669 9.940 1.00 40.00 O
+ATOM 5856 N VAL D 56 -30.166 -26.908 12.032 1.00 40.00 N
+ATOM 5857 CA VAL D 56 -31.234 -27.908 11.829 1.00 40.00 C
+ATOM 5858 C VAL D 56 -32.609 -27.465 12.382 1.00 40.00 C
+ATOM 5859 O VAL D 56 -32.698 -26.626 13.290 1.00 40.00 O
+ATOM 5860 CB VAL D 56 -30.869 -29.333 12.369 1.00 40.00 C
+ATOM 5861 CG1 VAL D 56 -29.465 -29.769 11.936 1.00 40.00 C
+ATOM 5862 CG2 VAL D 56 -31.056 -29.445 13.883 1.00 40.00 C
+ATOM 5863 N ASP D 57 -33.670 -28.033 11.803 1.00 40.00 N
+ATOM 5864 CA ASP D 57 -35.052 -27.858 12.277 1.00 40.00 C
+ATOM 5865 C ASP D 57 -35.521 -29.145 12.975 1.00 40.00 C
+ATOM 5866 O ASP D 57 -36.141 -30.035 12.361 1.00 40.00 O
+ATOM 5867 CB ASP D 57 -35.992 -27.454 11.114 1.00 40.00 C
+ATOM 5868 CG ASP D 57 -37.479 -27.453 11.506 1.00 40.00 C
+ATOM 5869 OD1 ASP D 57 -38.320 -27.548 10.583 1.00 40.00 O
+ATOM 5870 OD2 ASP D 57 -37.808 -27.364 12.717 1.00 40.00 O
+ATOM 5871 N GLN D 58 -35.202 -29.240 14.260 1.00 40.00 N
+ATOM 5872 CA GLN D 58 -35.620 -30.385 15.044 1.00 40.00 C
+ATOM 5873 C GLN D 58 -36.814 -30.027 15.923 1.00 40.00 C
+ATOM 5874 O GLN D 58 -36.955 -30.550 17.029 1.00 40.00 O
+ATOM 5875 CB GLN D 58 -34.453 -30.956 15.860 1.00 40.00 C
+ATOM 5876 CG GLN D 58 -33.647 -29.910 16.614 1.00 40.00 C
+ATOM 5877 CD GLN D 58 -32.558 -30.520 17.471 1.00 40.00 C
+ATOM 5878 OE1 GLN D 58 -31.707 -29.803 18.004 1.00 40.00 O
+ATOM 5879 NE2 GLN D 58 -32.580 -31.848 17.616 1.00 40.00 N
+ATOM 5880 N SER D 59 -37.665 -29.124 15.432 1.00 40.00 N
+ATOM 5881 CA SER D 59 -38.962 -28.897 16.065 1.00 40.00 C
+ATOM 5882 C SER D 59 -39.769 -30.177 15.880 1.00 40.00 C
+ATOM 5883 O SER D 59 -39.781 -30.767 14.782 1.00 40.00 O
+ATOM 5884 CB SER D 59 -39.693 -27.666 15.500 1.00 40.00 C
+ATOM 5885 OG SER D 59 -40.198 -27.888 14.194 1.00 40.00 O
+ATOM 5886 N ASP D 60 -40.389 -30.619 16.975 1.00 40.00 N
+ATOM 5887 CA ASP D 60 -41.091 -31.908 17.041 1.00 40.00 C
+ATOM 5888 C ASP D 60 -40.261 -33.064 17.661 1.00 40.00 C
+ATOM 5889 O ASP D 60 -40.617 -34.245 17.554 1.00 40.00 O
+ATOM 5890 CB ASP D 60 -41.649 -32.305 15.665 1.00 40.00 C
+ATOM 5891 CG ASP D 60 -42.980 -33.028 15.762 1.00 40.00 C
+ATOM 5892 OD1 ASP D 60 -43.526 -33.167 16.889 1.00 40.00 O
+ATOM 5893 OD2 ASP D 60 -43.486 -33.455 14.702 1.00 40.00 O
+ATOM 5894 N GLN D 61 -39.144 -32.722 18.290 1.00 40.00 N
+ATOM 5895 CA GLN D 61 -38.545 -33.624 19.249 1.00 40.00 C
+ATOM 5896 C GLN D 61 -39.126 -33.216 20.599 1.00 40.00 C
+ATOM 5897 O GLN D 61 -39.817 -32.192 20.710 1.00 40.00 O
+ATOM 5898 CB GLN D 61 -37.003 -33.578 19.218 1.00 40.00 C
+ATOM 5899 CG GLN D 61 -36.345 -32.313 19.774 1.00 40.00 C
+ATOM 5900 CD GLN D 61 -36.164 -32.307 21.293 1.00 40.00 C
+ATOM 5901 OE1 GLN D 61 -35.932 -33.350 21.914 1.00 40.00 O
+ATOM 5902 NE2 GLN D 61 -36.259 -31.119 21.896 1.00 40.00 N
+ATOM 5903 N SER D 62 -38.867 -34.023 21.617 1.00 40.00 N
+ATOM 5904 CA SER D 62 -39.357 -33.714 22.942 1.00 40.00 C
+ATOM 5905 C SER D 62 -38.394 -34.127 24.055 1.00 40.00 C
+ATOM 5906 O SER D 62 -38.605 -33.740 25.201 1.00 40.00 O
+ATOM 5907 CB SER D 62 -40.764 -34.299 23.157 1.00 40.00 C
+ATOM 5908 OG SER D 62 -40.920 -35.545 22.494 1.00 40.00 O
+ATOM 5909 N TYR D 63 -37.332 -34.871 23.728 1.00 40.00 N
+ATOM 5910 CA TYR D 63 -36.413 -35.418 24.752 1.00 40.00 C
+ATOM 5911 C TYR D 63 -35.429 -34.428 25.416 1.00 40.00 C
+ATOM 5912 O TYR D 63 -35.204 -34.476 26.635 1.00 40.00 O
+ATOM 5913 CB TYR D 63 -35.634 -36.604 24.182 1.00 40.00 C
+ATOM 5914 CG TYR D 63 -34.821 -37.348 25.219 1.00 40.00 C
+ATOM 5915 CD1 TYR D 63 -33.538 -36.924 25.566 1.00 40.00 C
+ATOM 5916 CD2 TYR D 63 -35.335 -38.478 25.860 1.00 40.00 C
+ATOM 5917 CE1 TYR D 63 -32.793 -37.607 26.522 1.00 40.00 C
+ATOM 5918 CE2 TYR D 63 -34.595 -39.176 26.806 1.00 40.00 C
+ATOM 5919 CZ TYR D 63 -33.329 -38.739 27.135 1.00 40.00 C
+ATOM 5920 OH TYR D 63 -32.610 -39.433 28.077 1.00 40.00 O
+ATOM 5921 N LEU D 64 -34.828 -33.557 24.610 1.00 40.00 N
+ATOM 5922 CA LEU D 64 -33.866 -32.571 25.106 1.00 40.00 C
+ATOM 5923 C LEU D 64 -34.530 -31.326 25.703 1.00 40.00 C
+ATOM 5924 O LEU D 64 -35.555 -30.849 25.199 1.00 40.00 O
+ATOM 5925 CB LEU D 64 -32.945 -32.125 23.970 1.00 40.00 C
+ATOM 5926 CG LEU D 64 -32.161 -33.161 23.166 1.00 40.00 C
+ATOM 5927 CD1 LEU D 64 -31.595 -32.503 21.912 1.00 40.00 C
+ATOM 5928 CD2 LEU D 64 -31.058 -33.779 24.015 1.00 40.00 C
+ATOM 5929 N ASP D 65 -33.937 -30.793 26.769 1.00 40.00 N
+ATOM 5930 CA ASP D 65 -34.296 -29.460 27.256 1.00 40.00 C
+ATOM 5931 C ASP D 65 -33.571 -28.421 26.402 1.00 40.00 C
+ATOM 5932 O ASP D 65 -32.741 -28.783 25.560 1.00 40.00 O
+ATOM 5933 CB ASP D 65 -33.950 -29.300 28.744 1.00 40.00 C
+ATOM 5934 CG ASP D 65 -32.466 -29.573 29.058 1.00 40.00 C
+ATOM 5935 OD1 ASP D 65 -31.571 -28.997 28.395 1.00 40.00 O
+ATOM 5936 OD2 ASP D 65 -32.193 -30.347 30.002 1.00 40.00 O
+ATOM 5937 N ASP D 66 -33.861 -27.140 26.624 1.00 40.00 N
+ATOM 5938 CA ASP D 66 -33.265 -26.064 25.807 1.00 40.00 C
+ATOM 5939 C ASP D 66 -31.749 -25.888 25.905 1.00 40.00 C
+ATOM 5940 O ASP D 66 -31.121 -25.478 24.926 1.00 40.00 O
+ATOM 5941 CB ASP D 66 -33.946 -24.730 26.086 1.00 40.00 C
+ATOM 5942 CG ASP D 66 -35.289 -24.624 25.417 1.00 40.00 C
+ATOM 5943 OD1 ASP D 66 -35.404 -25.086 24.253 1.00 40.00 O
+ATOM 5944 OD2 ASP D 66 -36.222 -24.073 26.052 1.00 40.00 O
+ATOM 5945 N GLY D 67 -31.188 -26.176 27.084 1.00 40.00 N
+ATOM 5946 CA GLY D 67 -29.741 -26.069 27.352 1.00 40.00 C
+ATOM 5947 C GLY D 67 -28.899 -27.117 26.645 1.00 40.00 C
+ATOM 5948 O GLY D 67 -27.695 -26.922 26.427 1.00 40.00 O
+ATOM 5949 N GLN D 68 -29.545 -28.236 26.309 1.00 40.00 N
+ATOM 5950 CA GLN D 68 -28.970 -29.281 25.460 1.00 40.00 C
+ATOM 5951 C GLN D 68 -29.053 -28.885 23.964 1.00 40.00 C
+ATOM 5952 O GLN D 68 -28.115 -29.145 23.201 1.00 40.00 O
+ATOM 5953 CB GLN D 68 -29.632 -30.645 25.756 1.00 40.00 C
+ATOM 5954 CG GLN D 68 -29.261 -31.232 27.128 1.00 40.00 C
+ATOM 5955 CD GLN D 68 -30.143 -32.398 27.609 1.00 40.00 C
+ATOM 5956 OE1 GLN D 68 -31.377 -32.386 27.468 1.00 40.00 O
+ATOM 5957 NE2 GLN D 68 -29.503 -33.401 28.216 1.00 40.00 N
+ATOM 5958 N ILE D 69 -30.163 -28.246 23.566 1.00 40.00 N
+ATOM 5959 CA ILE D 69 -30.319 -27.606 22.231 1.00 40.00 C
+ATOM 5960 C ILE D 69 -29.362 -26.417 22.078 1.00 40.00 C
+ATOM 5961 O ILE D 69 -28.738 -26.220 21.017 1.00 40.00 O
+ATOM 5962 CB ILE D 69 -31.770 -27.096 22.000 1.00 40.00 C
+ATOM 5963 CG1 ILE D 69 -32.725 -28.280 21.796 1.00 40.00 C
+ATOM 5964 CG2 ILE D 69 -31.849 -26.107 20.826 1.00 40.00 C
+ATOM 5965 CD1 ILE D 69 -34.171 -27.979 22.148 1.00 40.00 C
+ATOM 5966 N CYS D 70 -29.283 -25.623 23.148 1.00 40.00 N
+ATOM 5967 CA CYS D 70 -28.295 -24.564 23.286 1.00 40.00 C
+ATOM 5968 C CYS D 70 -26.883 -25.112 23.172 1.00 40.00 C
+ATOM 5969 O CYS D 70 -25.992 -24.451 22.632 1.00 40.00 O
+ATOM 5970 CB CYS D 70 -28.456 -23.862 24.636 1.00 20.00 C
+ATOM 5971 SG CYS D 70 -28.825 -22.076 24.577 1.00 20.00 S
+ATOM 5972 N ASP D 71 -26.691 -26.325 23.679 1.00 40.00 N
+ATOM 5973 CA ASP D 71 -25.388 -26.972 23.630 1.00 40.00 C
+ATOM 5974 C ASP D 71 -25.141 -27.729 22.312 1.00 40.00 C
+ATOM 5975 O ASP D 71 -24.165 -28.479 22.196 1.00 40.00 O
+ATOM 5976 CB ASP D 71 -25.195 -27.887 24.850 1.00 40.00 C
+ATOM 5977 CG ASP D 71 -23.798 -27.766 25.468 1.00 40.00 C
+ATOM 5978 OD1 ASP D 71 -23.116 -26.726 25.251 1.00 40.00 O
+ATOM 5979 OD2 ASP D 71 -23.386 -28.710 26.183 1.00 40.00 O
+ATOM 5980 N GLY D 72 -26.016 -27.523 21.325 1.00 40.00 N
+ATOM 5981 CA GLY D 72 -25.837 -28.095 19.981 1.00 40.00 C
+ATOM 5982 C GLY D 72 -26.086 -29.593 19.873 1.00 40.00 C
+ATOM 5983 O GLY D 72 -25.733 -30.221 18.863 1.00 40.00 O
+ATOM 5984 N TRP D 73 -26.684 -30.165 20.920 1.00 40.00 N
+ATOM 5985 CA TRP D 73 -27.124 -31.549 20.901 1.00 40.00 C
+ATOM 5986 C TRP D 73 -28.241 -31.708 19.918 1.00 40.00 C
+ATOM 5987 O TRP D 73 -29.040 -30.787 19.720 1.00 40.00 O
+ATOM 5988 CB TRP D 73 -27.605 -31.969 22.279 1.00 40.00 C
+ATOM 5989 CG TRP D 73 -26.497 -32.374 23.215 1.00 40.00 C
+ATOM 5990 CD1 TRP D 73 -26.015 -31.669 24.312 1.00 40.00 C
+ATOM 5991 CD2 TRP D 73 -25.691 -33.611 23.169 1.00 40.00 C
+ATOM 5992 NE1 TRP D 73 -24.999 -32.361 24.930 1.00 40.00 N
+ATOM 5993 CE2 TRP D 73 -24.752 -33.529 24.299 1.00 40.00 C
+ATOM 5994 CE3 TRP D 73 -25.656 -34.737 22.338 1.00 40.00 C
+ATOM 5995 CZ2 TRP D 73 -23.827 -34.533 24.564 1.00 40.00 C
+ATOM 5996 CZ3 TRP D 73 -24.719 -35.743 22.617 1.00 40.00 C
+ATOM 5997 CH2 TRP D 73 -23.825 -35.638 23.701 1.00 40.00 C
+ATOM 5998 N VAL D 74 -28.316 -32.882 19.298 1.00 40.00 N
+ATOM 5999 CA VAL D 74 -29.358 -33.146 18.310 1.00 40.00 C
+ATOM 6000 C VAL D 74 -29.842 -34.607 18.281 1.00 40.00 C
+ATOM 6001 O VAL D 74 -29.062 -35.560 18.462 1.00 40.00 O
+ATOM 6002 CB VAL D 74 -28.927 -32.656 16.902 1.00 40.00 C
+ATOM 6003 CG1 VAL D 74 -27.600 -33.284 16.482 1.00 40.00 C
+ATOM 6004 CG2 VAL D 74 -30.024 -32.895 15.868 1.00 40.00 C
+ATOM 6005 N LEU D 75 -31.149 -34.753 18.069 1.00 40.00 N
+ATOM 6006 CA LEU D 75 -31.757 -36.046 17.785 1.00 40.00 C
+ATOM 6007 C LEU D 75 -31.869 -36.253 16.280 1.00 40.00 C
+ATOM 6008 O LEU D 75 -32.652 -35.582 15.583 1.00 40.00 O
+ATOM 6009 CB LEU D 75 -33.117 -36.191 18.482 1.00 40.00 C
+ATOM 6010 CG LEU D 75 -33.048 -36.415 20.006 1.00 40.00 C
+ATOM 6011 CD1 LEU D 75 -34.420 -36.748 20.597 1.00 40.00 C
+ATOM 6012 CD2 LEU D 75 -32.004 -37.471 20.389 1.00 40.00 C
+ATOM 6013 N THR D 76 -31.053 -37.183 15.796 1.00 40.00 N
+ATOM 6014 CA THR D 76 -30.929 -37.444 14.380 1.00 40.00 C
+ATOM 6015 C THR D 76 -32.257 -37.913 13.760 1.00 40.00 C
+ATOM 6016 O THR D 76 -32.620 -37.466 12.668 1.00 40.00 O
+ATOM 6017 CB THR D 76 -29.737 -38.387 14.082 1.00 40.00 C
+ATOM 6018 OG1 THR D 76 -29.666 -39.422 15.066 1.00 40.00 O
+ATOM 6019 CG2 THR D 76 -28.442 -37.621 14.146 1.00 40.00 C
+ATOM 6020 N CYS D 77 -32.995 -38.771 14.476 1.00 40.00 N
+ATOM 6021 CA CYS D 77 -34.259 -39.349 13.972 1.00 40.00 C
+ATOM 6022 C CYS D 77 -35.354 -38.308 13.738 1.00 40.00 C
+ATOM 6023 O CYS D 77 -36.359 -38.581 13.088 1.00 40.00 O
+ATOM 6024 CB CYS D 77 -34.778 -40.446 14.911 1.00 40.00 C
+ATOM 6025 SG CYS D 77 -35.879 -39.875 16.241 1.00 40.00 S
+ATOM 6026 N HIS D 78 -35.151 -37.115 14.277 1.00 40.00 N
+ATOM 6027 CA HIS D 78 -36.119 -36.040 14.136 1.00 40.00 C
+ATOM 6028 C HIS D 78 -35.502 -34.696 13.825 1.00 40.00 C
+ATOM 6029 O HIS D 78 -36.019 -33.643 14.206 1.00 40.00 O
+ATOM 6030 CB HIS D 78 -37.010 -35.974 15.372 1.00 40.00 C
+ATOM 6031 CG HIS D 78 -38.357 -36.621 15.186 1.00 40.00 C
+ATOM 6032 ND1 HIS D 78 -38.500 -37.901 14.800 1.00 40.00 N
+ATOM 6033 CD2 HIS D 78 -39.644 -36.113 15.363 1.00 40.00 C
+ATOM 6034 CE1 HIS D 78 -39.812 -38.197 14.724 1.00 40.00 C
+ATOM 6035 NE2 HIS D 78 -40.510 -37.102 15.075 1.00 40.00 N
+ATOM 6036 N ALA D 79 -34.394 -34.715 13.104 1.00 40.00 N
+ATOM 6037 CA ALA D 79 -33.794 -33.484 12.668 1.00 40.00 C
+ATOM 6038 C ALA D 79 -33.811 -33.391 11.145 1.00 40.00 C
+ATOM 6039 O ALA D 79 -33.263 -34.257 10.464 1.00 40.00 O
+ATOM 6040 CB ALA D 79 -32.382 -33.390 13.201 1.00 40.00 C
+ATOM 6041 N TYR D 80 -34.483 -32.365 10.619 1.00 40.00 N
+ATOM 6042 CA TYR D 80 -34.336 -31.948 9.209 1.00 40.00 C
+ATOM 6043 C TYR D 80 -33.210 -30.908 9.112 1.00 40.00 C
+ATOM 6044 O TYR D 80 -32.987 -30.171 10.080 1.00 40.00 O
+ATOM 6045 CB TYR D 80 -35.583 -31.218 8.703 1.00 40.00 C
+ATOM 6046 CG TYR D 80 -36.879 -31.961 8.766 1.00 40.00 C
+ATOM 6047 CD1 TYR D 80 -37.866 -31.584 9.677 1.00 40.00 C
+ATOM 6048 CD2 TYR D 80 -37.143 -33.014 7.889 1.00 40.00 C
+ATOM 6049 CE1 TYR D 80 -39.076 -32.250 9.728 1.00 40.00 C
+ATOM 6050 CE2 TYR D 80 -38.347 -33.690 7.931 1.00 40.00 C
+ATOM 6051 CZ TYR D 80 -39.310 -33.302 8.848 1.00 40.00 C
+ATOM 6052 OH TYR D 80 -40.506 -33.972 8.886 1.00 40.00 O
+ATOM 6053 N PRO D 81 -32.518 -30.809 7.947 1.00 40.00 N
+ATOM 6054 CA PRO D 81 -31.587 -29.669 7.822 1.00 40.00 C
+ATOM 6055 C PRO D 81 -32.241 -28.359 7.300 1.00 40.00 C
+ATOM 6056 O PRO D 81 -33.255 -28.391 6.575 1.00 40.00 O
+ATOM 6057 CB PRO D 81 -30.502 -30.199 6.867 1.00 40.00 C
+ATOM 6058 CG PRO D 81 -31.194 -31.243 6.042 1.00 40.00 C
+ATOM 6059 CD PRO D 81 -32.370 -31.774 6.834 1.00 40.00 C
+ATOM 6060 N THR D 82 -31.672 -27.225 7.722 1.00 40.00 N
+ATOM 6061 CA THR D 82 -31.993 -25.896 7.157 1.00 40.00 C
+ATOM 6062 C THR D 82 -30.724 -25.242 6.552 1.00 40.00 C
+ATOM 6063 O THR D 82 -30.770 -24.106 6.043 1.00 40.00 O
+ATOM 6064 CB THR D 82 -32.723 -24.944 8.163 1.00 40.00 C
+ATOM 6065 OG1 THR D 82 -31.946 -24.766 9.360 1.00 40.00 O
+ATOM 6066 CG2 THR D 82 -34.118 -25.476 8.521 1.00 40.00 C
+ATOM 6067 N SER D 83 -29.609 -25.980 6.612 1.00 40.00 N
+ATOM 6068 CA SER D 83 -28.335 -25.577 6.021 1.00 40.00 C
+ATOM 6069 C SER D 83 -27.401 -26.779 5.856 1.00 40.00 C
+ATOM 6070 O SER D 83 -27.669 -27.881 6.357 1.00 40.00 O
+ATOM 6071 CB SER D 83 -27.651 -24.493 6.870 1.00 40.00 C
+ATOM 6072 OG SER D 83 -26.960 -25.049 7.981 1.00 40.00 O
+ATOM 6073 N ASP D 84 -26.310 -26.548 5.130 1.00 40.00 N
+ATOM 6074 CA ASP D 84 -25.166 -27.452 5.123 1.00 40.00 C
+ATOM 6075 C ASP D 84 -24.722 -27.634 6.571 1.00 40.00 C
+ATOM 6076 O ASP D 84 -24.533 -26.647 7.311 1.00 40.00 O
+ATOM 6077 CB ASP D 84 -24.010 -26.871 4.285 1.00 40.00 C
+ATOM 6078 CG ASP D 84 -24.183 -27.094 2.775 1.00 40.00 C
+ATOM 6079 OD1 ASP D 84 -23.145 -27.097 2.067 1.00 40.00 O
+ATOM 6080 OD2 ASP D 84 -25.334 -27.267 2.293 1.00 40.00 O
+ATOM 6081 N VAL D 85 -24.568 -28.887 6.985 1.00 40.00 N
+ATOM 6082 CA VAL D 85 -24.343 -29.167 8.403 1.00 40.00 C
+ATOM 6083 C VAL D 85 -23.353 -30.320 8.639 1.00 40.00 C
+ATOM 6084 O VAL D 85 -23.401 -31.343 7.954 1.00 40.00 O
+ATOM 6085 CB VAL D 85 -25.705 -29.308 9.161 1.00 40.00 C
+ATOM 6086 CG1 VAL D 85 -26.622 -30.317 8.476 1.00 40.00 C
+ATOM 6087 CG2 VAL D 85 -25.523 -29.612 10.647 1.00 40.00 C
+ATOM 6088 N VAL D 86 -22.435 -30.115 9.586 1.00 40.00 N
+ATOM 6089 CA VAL D 86 -21.465 -31.137 10.013 1.00 40.00 C
+ATOM 6090 C VAL D 86 -21.920 -31.704 11.365 1.00 40.00 C
+ATOM 6091 O VAL D 86 -22.281 -30.930 12.265 1.00 40.00 O
+ATOM 6092 CB VAL D 86 -20.028 -30.556 10.137 1.00 40.00 C
+ATOM 6093 CG1 VAL D 86 -19.015 -31.653 10.452 1.00 40.00 C
+ATOM 6094 CG2 VAL D 86 -19.623 -29.815 8.866 1.00 40.00 C
+ATOM 6095 N ILE D 87 -21.912 -33.039 11.500 1.00 40.00 N
+ATOM 6096 CA ILE D 87 -22.411 -33.727 12.724 1.00 40.00 C
+ATOM 6097 C ILE D 87 -21.623 -34.986 13.178 1.00 40.00 C
+ATOM 6098 O ILE D 87 -21.318 -35.879 12.378 1.00 40.00 O
+ATOM 6099 CB ILE D 87 -23.937 -34.049 12.631 1.00 40.00 C
+ATOM 6100 CG1 ILE D 87 -24.780 -32.762 12.702 1.00 40.00 C
+ATOM 6101 CG2 ILE D 87 -24.367 -35.022 13.728 1.00 40.00 C
+ATOM 6102 CD1 ILE D 87 -26.237 -32.932 12.330 1.00 40.00 C
+ATOM 6103 N GLU D 88 -21.312 -35.038 14.475 1.00 40.00 N
+ATOM 6104 CA GLU D 88 -20.799 -36.244 15.114 1.00 40.00 C
+ATOM 6105 C GLU D 88 -21.977 -37.122 15.507 1.00 40.00 C
+ATOM 6106 O GLU D 88 -22.962 -36.628 16.057 1.00 40.00 O
+ATOM 6107 CB GLU D 88 -20.024 -35.901 16.387 1.00 40.00 C
+ATOM 6108 CG GLU D 88 -18.735 -35.118 16.194 1.00 40.00 C
+ATOM 6109 CD GLU D 88 -18.331 -34.355 17.454 1.00 40.00 C
+ATOM 6110 OE1 GLU D 88 -19.242 -33.868 18.179 1.00 40.00 O
+ATOM 6111 OE2 GLU D 88 -17.103 -34.232 17.716 1.00 40.00 O
+ATOM 6112 N THR D 89 -21.865 -38.422 15.240 1.00 40.00 N
+ATOM 6113 CA THR D 89 -22.887 -39.386 15.645 1.00 40.00 C
+ATOM 6114 C THR D 89 -22.320 -40.284 16.739 1.00 40.00 C
+ATOM 6115 O THR D 89 -21.147 -40.146 17.112 1.00 40.00 O
+ATOM 6116 CB THR D 89 -23.369 -40.223 14.445 1.00 40.00 C
+ATOM 6117 OG1 THR D 89 -22.307 -41.068 13.987 1.00 40.00 O
+ATOM 6118 CG2 THR D 89 -23.793 -39.311 13.302 1.00 40.00 C
+ATOM 6119 N HIS D 90 -23.151 -41.195 17.248 1.00 40.00 N
+ATOM 6120 CA HIS D 90 -22.769 -42.158 18.316 1.00 40.00 C
+ATOM 6121 C HIS D 90 -22.379 -41.453 19.593 1.00 40.00 C
+ATOM 6122 O HIS D 90 -21.413 -41.830 20.270 1.00 40.00 O
+ATOM 6123 CB HIS D 90 -21.673 -43.132 17.854 1.00 40.00 C
+ATOM 6124 CG HIS D 90 -22.035 -43.941 16.611 1.00 40.00 C
+ATOM 6125 ND1 HIS D 90 -22.296 -43.369 15.408 1.00 40.00 N
+ATOM 6126 CD2 HIS D 90 -22.135 -45.323 16.413 1.00 40.00 C
+ATOM 6127 CE1 HIS D 90 -22.566 -44.331 14.498 1.00 40.00 C
+ATOM 6128 NE2 HIS D 90 -22.471 -45.525 15.113 1.00 40.00 N
+ATOM 6129 N LYS D 91 -23.158 -40.422 19.921 1.00 40.00 N
+ATOM 6130 CA LYS D 91 -22.851 -39.507 21.003 1.00 40.00 C
+ATOM 6131 C LYS D 91 -23.766 -39.686 22.179 1.00 40.00 C
+ATOM 6132 O LYS D 91 -23.773 -38.847 23.072 1.00 40.00 O
+ATOM 6133 CB LYS D 91 -22.972 -38.060 20.525 1.00 40.00 C
+ATOM 6134 CG LYS D 91 -21.911 -37.618 19.526 1.00 40.00 C
+ATOM 6135 CD LYS D 91 -20.540 -37.368 20.153 1.00 40.00 C
+ATOM 6136 CE LYS D 91 -19.681 -38.628 20.211 1.00 40.00 C
+ATOM 6137 NZ LYS D 91 -18.239 -38.312 20.375 1.00 40.00 N
+ATOM 6138 N GLU D 92 -24.546 -40.764 22.183 1.00 40.00 N
+ATOM 6139 CA GLU D 92 -25.457 -41.026 23.302 1.00 40.00 C
+ATOM 6140 C GLU D 92 -24.704 -41.129 24.625 1.00 40.00 C
+ATOM 6141 O GLU D 92 -25.058 -40.437 25.582 1.00 40.00 O
+ATOM 6142 CB GLU D 92 -26.325 -42.282 23.098 1.00 40.00 C
+ATOM 6143 CG GLU D 92 -27.296 -42.532 24.263 1.00 40.00 C
+ATOM 6144 CD GLU D 92 -28.113 -43.813 24.151 1.00 40.00 C
+ATOM 6145 OE1 GLU D 92 -27.791 -44.678 23.316 1.00 40.00 O
+ATOM 6146 OE2 GLU D 92 -29.088 -43.962 24.913 1.00 40.00 O
+ATOM 6147 N GLU D 93 -23.675 -41.981 24.678 1.00 40.00 N
+ATOM 6148 CA GLU D 93 -22.884 -42.156 25.900 1.00 40.00 C
+ATOM 6149 C GLU D 93 -22.327 -40.841 26.453 1.00 40.00 C
+ATOM 6150 O GLU D 93 -22.286 -40.663 27.678 1.00 40.00 O
+ATOM 6151 CB GLU D 93 -21.744 -43.137 25.680 1.00 40.00 C
+ATOM 6152 CG GLU D 93 -20.791 -43.176 26.861 1.00 40.00 C
+ATOM 6153 CD GLU D 93 -19.779 -44.291 26.761 1.00 40.00 C
+ATOM 6154 OE1 GLU D 93 -18.896 -44.231 25.877 1.00 40.00 O
+ATOM 6155 OE2 GLU D 93 -19.864 -45.229 27.579 1.00 40.00 O
+ATOM 6156 N GLU D 94 -21.895 -39.945 25.552 1.00 40.00 N
+ATOM 6157 CA GLU D 94 -21.473 -38.586 25.921 1.00 40.00 C
+ATOM 6158 C GLU D 94 -22.605 -37.756 26.554 1.00 40.00 C
+ATOM 6159 O GLU D 94 -22.384 -37.029 27.520 1.00 40.00 O
+ATOM 6160 CB GLU D 94 -20.859 -37.836 24.732 1.00 40.00 C
+ATOM 6161 CG GLU D 94 -20.342 -36.446 25.119 1.00 40.00 C
+ATOM 6162 CD GLU D 94 -19.657 -35.669 23.990 1.00 40.00 C
+ATOM 6163 OE1 GLU D 94 -18.988 -36.296 23.129 1.00 40.00 O
+ATOM 6164 OE2 GLU D 94 -19.768 -34.413 23.983 1.00 40.00 O
+ATOM 6165 N LEU D 95 -23.809 -37.863 26.007 1.00 40.00 N
+ATOM 6166 CA LEU D 95 -24.982 -37.267 26.632 1.00 40.00 C
+ATOM 6167 C LEU D 95 -25.286 -37.974 27.963 1.00 40.00 C
+ATOM 6168 O LEU D 95 -25.458 -37.327 28.996 1.00 40.00 O
+ATOM 6169 CB LEU D 95 -26.168 -37.352 25.675 1.00 40.00 C
+ATOM 6170 CG LEU D 95 -27.462 -36.667 26.097 1.00 40.00 C
+ATOM 6171 CD1 LEU D 95 -27.250 -35.173 26.345 1.00 40.00 C
+ATOM 6172 CD2 LEU D 95 -28.515 -36.912 25.029 1.00 40.00 C
+ATOM 6173 N THR D 96 -25.356 -39.303 27.904 1.00 40.00 N
+ATOM 6174 CA THR D 96 -25.330 -40.186 29.068 1.00 40.00 C
+ATOM 6175 C THR D 96 -24.003 -40.044 29.811 1.00 40.00 C
+ATOM 6176 O THR D 96 -23.949 -40.140 31.036 1.00 40.00 O
+ATOM 6177 CB THR D 96 -25.549 -41.653 28.624 1.00 40.00 C
+ATOM 6178 OG1 THR D 96 -26.934 -41.981 28.772 1.00 40.00 O
+ATOM 6179 CG2 THR D 96 -24.705 -42.650 29.425 1.00 40.00 C
+TER 6180 THR D 96
+HETATM 6181 PA FAD A 401 -23.428 17.103 27.091 1.00 40.00 P
+HETATM 6182 O1A FAD A 401 -24.306 18.270 26.716 1.00 40.00 O
+HETATM 6183 O2A FAD A 401 -23.559 15.832 26.282 1.00 40.00 O
+HETATM 6184 O5B FAD A 401 -21.890 17.553 27.179 1.00 40.00 O
+HETATM 6185 C5B FAD A 401 -20.853 16.590 27.038 1.00 40.00 C
+HETATM 6186 C4B FAD A 401 -19.842 17.121 26.035 1.00 40.00 C
+HETATM 6187 O4B FAD A 401 -18.794 17.804 26.729 1.00 40.00 O
+HETATM 6188 C3B FAD A 401 -19.217 15.972 25.272 1.00 40.00 C
+HETATM 6189 O3B FAD A 401 -19.255 16.278 23.875 1.00 40.00 O
+HETATM 6190 C2B FAD A 401 -17.792 15.873 25.793 1.00 40.00 C
+HETATM 6191 O2B FAD A 401 -16.826 15.915 24.736 1.00 40.00 O
+HETATM 6192 C1B FAD A 401 -17.592 17.045 26.742 1.00 40.00 C
+HETATM 6193 N9A FAD A 401 -17.401 16.497 28.097 1.00 40.00 N
+HETATM 6194 C8A FAD A 401 -18.201 15.571 28.651 1.00 40.00 C
+HETATM 6195 N7A FAD A 401 -17.783 15.244 29.896 1.00 40.00 N
+HETATM 6196 C5A FAD A 401 -16.679 15.970 30.175 1.00 40.00 C
+HETATM 6197 C6A FAD A 401 -15.733 16.101 31.336 1.00 40.00 C
+HETATM 6198 N6A FAD A 401 -15.890 15.366 32.480 1.00 40.00 N
+HETATM 6199 N1A FAD A 401 -14.702 16.986 31.205 1.00 40.00 N
+HETATM 6200 C2A FAD A 401 -14.533 17.709 30.076 1.00 40.00 C
+HETATM 6201 N3A FAD A 401 -15.352 17.635 28.998 1.00 40.00 N
+HETATM 6202 C4A FAD A 401 -16.431 16.801 28.973 1.00 40.00 C
+HETATM 6203 N1 FAD A 401 -25.090 9.523 32.642 1.00 40.00 N
+HETATM 6204 C2 FAD A 401 -25.557 9.541 33.915 1.00 40.00 C
+HETATM 6205 O2 FAD A 401 -25.483 10.627 34.537 1.00 40.00 O
+HETATM 6206 N3 FAD A 401 -26.098 8.445 34.510 1.00 40.00 N
+HETATM 6207 C4 FAD A 401 -26.237 7.253 33.884 1.00 40.00 C
+HETATM 6208 O4 FAD A 401 -26.778 6.234 34.424 1.00 40.00 O
+HETATM 6209 C4X FAD A 401 -25.739 7.161 32.489 1.00 40.00 C
+HETATM 6210 N5 FAD A 401 -25.863 6.001 31.802 1.00 40.00 N
+HETATM 6211 C5X FAD A 401 -25.398 5.956 30.524 1.00 40.00 C
+HETATM 6212 C6 FAD A 401 -25.490 4.755 29.818 1.00 40.00 C
+HETATM 6213 C7 FAD A 401 -25.017 4.678 28.501 1.00 40.00 C
+HETATM 6214 C7M FAD A 401 -25.148 3.362 27.765 1.00 40.00 C
+HETATM 6215 C8 FAD A 401 -24.383 5.906 27.849 1.00 40.00 C
+HETATM 6216 C8M FAD A 401 -23.851 5.897 26.433 1.00 40.00 C
+HETATM 6217 C9 FAD A 401 -24.283 7.099 28.560 1.00 40.00 C
+HETATM 6218 C9A FAD A 401 -24.746 7.161 29.867 1.00 40.00 C
+HETATM 6219 N10 FAD A 401 -24.654 8.366 30.570 1.00 40.00 N
+HETATM 6220 C10 FAD A 401 -25.146 8.399 31.889 1.00 40.00 C
+HETATM 6221 C1' FAD A 401 -24.095 9.555 29.919 1.00 40.00 C
+HETATM 6222 C2' FAD A 401 -25.245 10.459 29.459 1.00 40.00 C
+HETATM 6223 O2' FAD A 401 -25.841 9.937 28.246 1.00 40.00 O
+HETATM 6224 C3' FAD A 401 -24.785 11.898 29.225 1.00 40.00 C
+HETATM 6225 O3' FAD A 401 -23.775 11.857 28.206 1.00 40.00 O
+HETATM 6226 C4' FAD A 401 -24.249 12.610 30.477 1.00 40.00 C
+HETATM 6227 O4' FAD A 401 -25.197 12.552 31.543 1.00 40.00 O
+HETATM 6228 C5' FAD A 401 -23.945 14.082 30.202 1.00 40.00 C
+HETATM 6229 O5' FAD A 401 -24.838 14.583 29.203 1.00 40.00 O
+HETATM 6230 P FAD A 401 -25.140 16.152 28.992 1.00 40.00 P
+HETATM 6231 O1P FAD A 401 -26.059 16.273 27.791 1.00 40.00 O
+HETATM 6232 O2P FAD A 401 -25.528 16.748 30.312 1.00 40.00 O
+HETATM 6233 O3P FAD A 401 -23.701 16.741 28.620 1.00 40.00 O
+HETATM 6234 FE1 FES B 101 -51.609 1.622 98.269 1.00 40.00 FE
+HETATM 6235 FE2 FES B 101 -52.880 2.980 100.726 1.00 40.00 FE
+HETATM 6236 S1 FES B 101 -53.432 2.833 98.586 1.00 40.00 S
+HETATM 6237 S2 FES B 101 -51.017 1.806 100.389 1.00 40.00 S
+HETATM 6238 PA FAD C 401 -71.512 15.192 45.303 1.00 40.00 P
+HETATM 6239 O1A FAD C 401 -71.196 16.095 44.126 1.00 40.00 O
+HETATM 6240 O2A FAD C 401 -71.257 15.763 46.676 1.00 40.00 O
+HETATM 6241 O5B FAD C 401 -73.004 14.581 45.212 1.00 40.00 O
+HETATM 6242 C5B FAD C 401 -73.681 14.131 46.378 1.00 40.00 C
+HETATM 6243 C4B FAD C 401 -75.069 14.753 46.405 1.00 40.00 C
+HETATM 6244 O4B FAD C 401 -76.017 13.854 45.806 1.00 40.00 O
+HETATM 6245 C3B FAD C 401 -75.475 15.014 47.848 1.00 40.00 C
+HETATM 6246 O3B FAD C 401 -75.908 16.371 48.034 1.00 40.00 O
+HETATM 6247 C2B FAD C 401 -76.572 13.998 48.130 1.00 40.00 C
+HETATM 6248 O2B FAD C 401 -77.747 14.621 48.666 1.00 40.00 O
+HETATM 6249 C1B FAD C 401 -76.849 13.269 46.810 1.00 40.00 C
+HETATM 6250 N9A FAD C 401 -76.460 11.848 46.996 1.00 40.00 N
+HETATM 6251 C8A FAD C 401 -75.293 11.445 47.534 1.00 40.00 C
+HETATM 6252 N7A FAD C 401 -75.211 10.092 47.590 1.00 40.00 N
+HETATM 6253 C5A FAD C 401 -76.353 9.571 47.087 1.00 40.00 C
+HETATM 6254 C6A FAD C 401 -76.920 8.189 46.862 1.00 40.00 C
+HETATM 6255 N6A FAD C 401 -76.254 7.052 47.184 1.00 40.00 N
+HETATM 6256 N1A FAD C 401 -78.147 8.081 46.312 1.00 40.00 N
+HETATM 6257 C2A FAD C 401 -78.810 9.203 45.978 1.00 40.00 C
+HETATM 6258 N3A FAD C 401 -78.385 10.482 46.155 1.00 40.00 N
+HETATM 6259 C4A FAD C 401 -77.171 10.745 46.698 1.00 40.00 C
+HETATM 6260 N1 FAD C 401 -65.661 9.492 50.049 1.00 40.00 N
+HETATM 6261 C2 FAD C 401 -64.871 8.517 49.530 1.00 40.00 C
+HETATM 6262 O2 FAD C 401 -65.158 8.098 48.382 1.00 40.00 O
+HETATM 6263 N3 FAD C 401 -63.801 8.024 50.206 1.00 40.00 N
+HETATM 6264 C4 FAD C 401 -63.462 8.454 51.440 1.00 40.00 C
+HETATM 6265 O4 FAD C 401 -62.478 7.989 52.060 1.00 40.00 O
+HETATM 6266 C4X FAD C 401 -64.274 9.523 52.063 1.00 40.00 C
+HETATM 6267 N5 FAD C 401 -63.998 10.018 53.286 1.00 40.00 N
+HETATM 6268 C5X FAD C 401 -64.775 10.985 53.813 1.00 40.00 C
+HETATM 6269 C6 FAD C 401 -64.501 11.476 55.068 1.00 40.00 C
+HETATM 6270 C7 FAD C 401 -65.298 12.469 55.614 1.00 40.00 C
+HETATM 6271 C7M FAD C 401 -64.967 12.998 56.986 1.00 40.00 C
+HETATM 6272 C8 FAD C 401 -66.454 13.004 54.860 1.00 40.00 C
+HETATM 6273 C8M FAD C 401 -67.330 14.079 55.439 1.00 40.00 C
+HETATM 6274 C9 FAD C 401 -66.736 12.505 53.615 1.00 40.00 C
+HETATM 6275 C9A FAD C 401 -65.945 11.515 53.081 1.00 40.00 C
+HETATM 6276 N10 FAD C 401 -66.230 11.025 51.811 1.00 40.00 N
+HETATM 6277 C10 FAD C 401 -65.420 10.022 51.268 1.00 40.00 C
+HETATM 6278 C1' FAD C 401 -67.368 11.555 51.076 1.00 40.00 C
+HETATM 6279 C2' FAD C 401 -66.800 12.560 50.081 1.00 40.00 C
+HETATM 6280 O2' FAD C 401 -66.365 13.763 50.738 1.00 40.00 O
+HETATM 6281 C3' FAD C 401 -67.851 12.841 49.021 1.00 40.00 C
+HETATM 6282 O3' FAD C 401 -69.000 13.394 49.680 1.00 40.00 O
+HETATM 6283 C4' FAD C 401 -68.281 11.567 48.257 1.00 40.00 C
+HETATM 6284 O4' FAD C 401 -67.170 10.752 47.833 1.00 40.00 O
+HETATM 6285 C5' FAD C 401 -69.122 11.942 47.040 1.00 40.00 C
+HETATM 6286 O5' FAD C 401 -68.816 13.304 46.693 1.00 40.00 O
+HETATM 6287 P FAD C 401 -69.069 13.912 45.222 1.00 40.00 P
+HETATM 6288 O1P FAD C 401 -68.616 15.371 45.244 1.00 40.00 O
+HETATM 6289 O2P FAD C 401 -68.531 12.935 44.203 1.00 40.00 O
+HETATM 6290 O3P FAD C 401 -70.673 13.835 45.140 1.00 40.00 O
+HETATM 6291 FE1 FES D 101 -33.932 -40.658 17.785 1.00 40.00 FE
+HETATM 6292 FE2 FES D 101 -35.294 -42.145 20.075 1.00 40.00 FE
+HETATM 6293 S1 FES D 101 -35.422 -40.052 19.343 1.00 40.00 S
+HETATM 6294 S2 FES D 101 -33.906 -42.776 18.453 1.00 40.00 S
+CONECT 15 5971
+CONECT 2667 6235
+CONECT 2881 3105
+CONECT 2935 6234
+CONECT 3105 2881
+CONECT 5757 6292
+CONECT 5789 6292
+CONECT 5807 6291
+CONECT 5971 15
+CONECT 6025 6291
+CONECT 6181 6182 6183 6184 6233
+CONECT 6182 6181
+CONECT 6183 6181
+CONECT 6184 6181 6185
+CONECT 6185 6184 6186
+CONECT 6186 6185 6187 6188
+CONECT 6187 6186 6192
+CONECT 6188 6186 6189 6190
+CONECT 6189 6188
+CONECT 6190 6188 6191 6192
+CONECT 6191 6190
+CONECT 6192 6187 6190 6193
+CONECT 6193 6192 6194 6202
+CONECT 6194 6193 6195
+CONECT 6195 6194 6196
+CONECT 6196 6195 6197 6202
+CONECT 6197 6196 6198 6199
+CONECT 6198 6197
+CONECT 6199 6197 6200
+CONECT 6200 6199 6201
+CONECT 6201 6200 6202
+CONECT 6202 6193 6196 6201
+CONECT 6203 6204 6220
+CONECT 6204 6203 6205 6206
+CONECT 6205 6204
+CONECT 6206 6204 6207
+CONECT 6207 6206 6208 6209
+CONECT 6208 6207
+CONECT 6209 6207 6210 6220
+CONECT 6210 6209 6211
+CONECT 6211 6210 6212 6218
+CONECT 6212 6211 6213
+CONECT 6213 6212 6214 6215
+CONECT 6214 6213
+CONECT 6215 6213 6216 6217
+CONECT 6216 6215
+CONECT 6217 6215 6218
+CONECT 6218 6211 6217 6219
+CONECT 6219 6218 6220 6221
+CONECT 6220 6203 6209 6219
+CONECT 6221 6219 6222
+CONECT 6222 6221 6223 6224
+CONECT 6223 6222
+CONECT 6224 6222 6225 6226
+CONECT 6225 6224
+CONECT 6226 6224 6227 6228
+CONECT 6227 6226
+CONECT 6228 6226 6229
+CONECT 6229 6228 6230
+CONECT 6230 6229 6231 6232 6233
+CONECT 6231 6230
+CONECT 6232 6230
+CONECT 6233 6181 6230
+CONECT 6234 2935 6236 6237
+CONECT 6235 2667 6236 6237
+CONECT 6236 6234 6235
+CONECT 6237 6234 6235
+CONECT 6238 6239 6240 6241 6290
+CONECT 6239 6238
+CONECT 6240 6238
+CONECT 6241 6238 6242
+CONECT 6242 6241 6243
+CONECT 6243 6242 6244 6245
+CONECT 6244 6243 6249
+CONECT 6245 6243 6246 6247
+CONECT 6246 6245
+CONECT 6247 6245 6248 6249
+CONECT 6248 6247
+CONECT 6249 6244 6247 6250
+CONECT 6250 6249 6251 6259
+CONECT 6251 6250 6252
+CONECT 6252 6251 6253
+CONECT 6253 6252 6254 6259
+CONECT 6254 6253 6255 6256
+CONECT 6255 6254
+CONECT 6256 6254 6257
+CONECT 6257 6256 6258
+CONECT 6258 6257 6259
+CONECT 6259 6250 6253 6258
+CONECT 6260 6261 6277
+CONECT 6261 6260 6262 6263
+CONECT 6262 6261
+CONECT 6263 6261 6264
+CONECT 6264 6263 6265 6266
+CONECT 6265 6264
+CONECT 6266 6264 6267 6277
+CONECT 6267 6266 6268
+CONECT 6268 6267 6269 6275
+CONECT 6269 6268 6270
+CONECT 6270 6269 6271 6272
+CONECT 6271 6270
+CONECT 6272 6270 6273 6274
+CONECT 6273 6272
+CONECT 6274 6272 6275
+CONECT 6275 6268 6274 6276
+CONECT 6276 6275 6277 6278
+CONECT 6277 6260 6266 6276
+CONECT 6278 6276 6279
+CONECT 6279 6278 6280 6281
+CONECT 6280 6279
+CONECT 6281 6279 6282 6283
+CONECT 6282 6281
+CONECT 6283 6281 6284 6285
+CONECT 6284 6283
+CONECT 6285 6283 6286
+CONECT 6286 6285 6287
+CONECT 6287 6286 6288 6289 6290
+CONECT 6288 6287
+CONECT 6289 6287
+CONECT 6290 6238 6287
+CONECT 6291 5807 6025 6293 6294
+CONECT 6292 5757 5789 6293 6294
+CONECT 6293 6291 6292
+CONECT 6294 6291 6292
+MASTER 433 0 4 22 46 0 15 12 6290 4 124 66
+END
--- /dev/null
+10 705
+Cow ATGGCATATCCCATACAACTAGGATTCCAAGATGCAACATCACCAATCATAGAAGAACTA
+Carp ATGGCACACCCAACGCAACTAGGTTTCAAGGACGCGGCCATACCCGTTATAGAGGAACTT
+Chicken ATGGCCAACCACTCCCAACTAGGCTTTCAAGACGCCTCATCCCCCATCATAGAAGAGCTC
+Human ATGGCACATGCAGCGCAAGTAGGTCTACAAGACGCTACTTCCCCTATCATAGAAGAGCTT
+Loach ATGGCACATCCCACACAATTAGGATTCCAAGACGCGGCCTCACCCGTAATAGAAGAACTT
+Mouse ATGGCCTACCCATTCCAACTTGGTCTACAAGACGCCACATCCCCTATTATAGAAGAGCTA
+Rat ATGGCTTACCCATTTCAACTTGGCTTACAAGACGCTACATCACCTATCATAGAAGAACTT
+Seal ATGGCATACCCCCTACAAATAGGCCTACAAGATGCAACCTCTCCCATTATAGAGGAGTTA
+Whale ATGGCATATCCATTCCAACTAGGTTTCCAAGATGCAGCATCACCCATCATAGAAGAGCTC
+Frog ATGGCACACCCATCACAATTAGGTTTTCAAGACGCAGCCTCTCCAATTATAGAAGAATTA
+
+CTTCACTTTCATGACCACACGCTAATAATTGTCTTCTTAATTAGCTCATTAGTACTTTAC
+CTTCACTTCCACGACCACGCATTAATAATTGTGCTCCTAATTAGCACTTTAGTTTTATAT
+GTTGAATTCCACGACCACGCCCTGATAGTCGCACTAGCAATTTGCAGCTTAGTACTCTAC
+ATCACCTTTCATGATCACGCCCTCATAATCATTTTCCTTATCTGCTTCCTAGTCCTGTAT
+CTTCACTTCCATGACCATGCCCTAATAATTGTATTTTTGATTAGCGCCCTAGTACTTTAT
+ATAAATTTCCATGATCACACACTAATAATTGTTTTCCTAATTAGCTCCTTAGTCCTCTAT
+ACAAACTTTCATGACCACACCCTAATAATTGTATTCCTCATCAGCTCCCTAGTACTTTAT
+CTACACTTCCATGACCACACATTAATAATTGTGTTCCTAATTAGCTCATTAGTACTCTAC
+CTACACTTTCACGATCATACACTAATAATCGTTTTTCTAATTAGCTCTTTAGTTCTCTAC
+CTTCACTTCCACGACCATACCCTCATAGCCGTTTTTCTTATTAGTACGCTAGTTCTTTAC
+
+ATTATTTCACTAATACTAACGACAAAGCTGACCCATACAAGCACGATAGATGCACAAGAA
+ATTATTACTGCAATGGTATCAACTAAACTTACTAATAAATATATTCTAGACTCCCAAGAA
+CTTCTAACTCTTATACTTATAGAAAAACTATCA---TCAAACACCGTAGATGCCCAAGAA
+GCCCTTTTCCTAACACTCACAACAAAACTAACTAATACTAACATCTCAGACGCTCAGGAA
+GTTATTATTACAACCGTCTCAACAAAACTCACTAACATATATATTTTGGACTCACAAGAA
+ATCATCTCGCTAATATTAACAACAAAACTAACACATACAAGCACAATAGATGCACAAGAA
+ATTATTTCACTAATACTAACAACAAAACTAACACACACAAGCACAATAGACGCCCAAGAA
+ATTATCTCACTTATACTAACCACGAAACTCACCCACACAAGTACAATAGACGCACAAGAA
+ATTATTACCCTAATGCTTACAACCAAATTAACACATACTAGTACAATAGACGCCCAAGAA
+ATTATTACTATTATAATAACTACTAAACTAACTAATACAAACCTAATGGACGCACAAGAG
+
+GTAGAGACAATCTGAACCATTCTGCCCGCCATCATCTTAATTCTAATTGCTCTTCCTTCT
+ATCGAAATCGTATGAACCATTCTACCAGCCGTCATTTTAGTACTAATCGCCCTGCCCTCC
+GTTGAACTAATCTGAACCATCCTACCCGCTATTGTCCTAGTCCTGCTTGCCCTCCCCTCC
+ATAGAAACCGTCTGAACTATCCTGCCCGCCATCATCCTAGTCCTCATCGCCCTCCCATCC
+ATTGAAATCGTATGAACTGTGCTCCCTGCCCTAATCCTCATTTTAATCGCCCTCCCCTCA
+GTTGAAACCATTTGAACTATTCTACCAGCTGTAATCCTTATCATAATTGCTCTCCCCTCT
+GTAGAAACAATTTGAACAATTCTCCCAGCTGTCATTCTTATTCTAATTGCCCTTCCCTCC
+GTGGAAACGGTGTGAACGATCCTACCCGCTATCATTTTAATTCTCATTGCCCTACCATCA
+GTAGAAACTGTCTGAACTATCCTCCCAGCCATTATCTTAATTTTAATTGCCTTGCCTTCA
+ATCGAAATAGTGTGAACTATTATACCAGCTATTAGCCTCATCATAATTGCCCTTCCATCC
+
+TTACGAATTCTATACATAATAGATGAAATCAATAACCCATCTCTTACAGTAAAAACCATA
+CTACGCATCCTGTACCTTATAGACGAAATTAACGACCCTCACCTGACAATTAAAGCAATA
+CTCCAAATCCTCTACATAATAGACGAAATCGACGAACCTGATCTCACCCTAAAAGCCATC
+CTACGCATCCTTTACATAACAGACGAGGTCAACGATCCCTCCCTTACCATCAAATCAATT
+CTACGAATTCTATATCTTATAGACGAGATTAATGACCCCCACCTAACAATTAAGGCCATG
+CTACGCATTCTATATATAATAGACGAAATCAACAACCCCGTATTAACCGTTAAAACCATA
+CTACGAATTCTATACATAATAGACGAGATTAATAACCCAGTTCTAACAGTAAAAACTATA
+TTACGAATCCTCTACATAATGGACGAGATCAATAACCCTTCCTTGACCGTAAAAACTATA
+TTACGGATCCTTTACATAATAGACGAAGTCAATAACCCCTCCCTCACTGTAAAAACAATA
+CTTCGTATCCTATATTTAATAGATGAAGTTAATGATCCACACTTAACAATTAAAGCAATC
+
+GGACATCAGTGATACTGAAGCTATGAGTATACAGATTATGAGGACTTAAGCTTCGACTCC
+GGACACCAATGATACTGAAGTTACGAGTATACAGACTATGAAAATCTAGGATTCGACTCC
+GGACACCAATGATACTGAACCTATGAATACACAGACTTCAAGGACCTCTCATTTGACTCC
+GGCCACCAATGGTACTGAACCTACGAGTACACCGACTACGGCGGACTAATCTTCAACTCC
+GGGCACCAATGATACTGAAGCTACGAGTATACTGATTATGAAAACTTAAGTTTTGACTCC
+GGGCACCAATGATACTGAAGCTACGAATATACTGACTATGAAGACCTATGCTTTGATTCA
+GGACACCAATGATACTGAAGCTATGAATATACTGACTATGAAGACCTATGCTTTGACTCC
+GGACATCAGTGATACTGAAGCTATGAGTACACAGACTACGAAGACCTGAACTTTGACTCA
+GGTCACCAATGATATTGAAGCTATGAGTATACCGACTACGAAGACCTAAGCTTCGACTCC
+GGCCACCAATGATACTGAAGCTACGAATATACTAACTATGAGGATCTCTCATTTGACTCT
+
+TACATAATTCCAACATCAGAATTAAAGCCAGGGGAGCTACGACTATTAGAAGTCGATAAT
+TATATAGTACCAACCCAAGACCTTGCCCCCGGACAATTCCGACTTCTGGAAACAGACCAC
+TACATAACCCCAACAACAGACCTCCCCCTAGGCCACTTCCGCCTACTAGAAGTCGACCAT
+TACATACTTCCCCCATTATTCCTAGAACCAGGCGACCTGCGACTCCTTGACGTTGACAAT
+TACATAATCCCCACCCAGGACCTAACCCCTGGACAATTCCGGCTACTAGAGACAGACCAC
+TATATAATCCCAACAAACGACCTAAAACCTGGTGAACTACGACTGCTAGAAGTTGATAAC
+TACATAATCCCAACCAATGACCTAAAACCAGGTGAACTTCGTCTATTAGAAGTTGATAAT
+TATATGATCCCCACACAAGAACTAAAGCCCGGAGAACTACGACTGCTAGAAGTAGACAAT
+TATATAATCCCAACATCAGACCTAAAGCCAGGAGAACTACGATTATTAGAAGTAGATAAC
+TATATAATTCCAACTAATGACCTTACCCCTGGACAATTCCGGCTGCTAGAAGTTGATAAT
+
+CGAGTTGTACTACCAATAGAAATAACAATCCGAATGTTAGTCTCCTCTGAAGACGTATTA
+CGAATAGTTGTTCCAATAGAATCCCCAGTCCGTGTCCTAGTATCTGCTGAAGACGTGCTA
+CGCATTGTAATCCCCATAGAATCCCCCATTCGAGTAATCATCACCGCTGATGACGTCCTC
+CGAGTAGTACTCCCGATTGAAGCCCCCATTCGTATAATAATTACATCACAAGACGTCTTG
+CGAATGGTTGTTCCCATAGAATCCCCTATTCGCATTCTTGTTTCCGCCGAAGATGTACTA
+CGAGTCGTTCTGCCAATAGAACTTCCAATCCGTATATTAATTTCATCTGAAGACGTCCTC
+CGGGTAGTCTTACCAATAGAACTTCCAATTCGTATACTAATCTCATCCGAAGACGTCCTG
+CGAGTAGTCCTCCCAATAGAAATAACAATCCGCATACTAATCTCATCAGAAGATGTACTC
+CGAGTTGTCTTACCTATAGAAATAACAATCCGAATATTAGTCTCATCAGAAGACGTACTC
+CGAATAGTAGTCCCAATAGAATCTCCAACCCGACTTTTAGTTACAGCCGAAGACGTCCTC
+
+CACTCATGAGCTGTGCCCTCTCTAGGACTAAAAACAGACGCAATCCCAGGCCGTCTAAAC
+CATTCTTGAGCTGTTCCATCCCTTGGCGTAAAAATGGACGCAGTCCCAGGACGACTAAAT
+CACTCATGAGCCGTACCCGCCCTCGGGGTAAAAACAGACGCAATCCCTGGACGACTAAAT
+CACTCATGAGCTGTCCCCACATTAGGCTTAAAAACAGATGCAATTCCCGGACGTCTAAAC
+CACTCCTGGGCCCTTCCAGCCATGGGGGTAAAGATAGACGCGGTCCCAGGACGCCTTAAC
+CACTCATGAGCAGTCCCCTCCCTAGGACTTAAAACTGATGCCATCCCAGGCCGACTAAAT
+CACTCATGAGCCATCCCTTCACTAGGGTTAAAAACCGACGCAATCCCCGGCCGCCTAAAC
+CACTCATGAGCCGTACCGTCCCTAGGACTAAAAACTGATGCTATCCCAGGACGACTAAAC
+CACTCATGGGCCGTACCCTCCTTGGGCCTAAAAACAGATGCAATCCCAGGACGCCTAAAC
+CACTCGTGAGCTGTACCCTCCTTGGGTGTCAAAACAGATGCAATCCCAGGACGACTTCAT
+
+CAAACAACCCTTATATCGTCCCGTCCAGGCTTATATTACGGTCAATGCTCAGAAATTTGC
+CAAGCCGCCTTTATTGCCTCACGCCCAGGGGTCTTTTACGGACAATGCTCTGAAATTTGT
+CAAACCTCCTTCATCACCACTCGACCAGGAGTGTTTTACGGACAATGCTCAGAAATCTGC
+CAAACCACTTTCACCGCTACACGACCGGGGGTATACTACGGTCAATGCTCTGAAATCTGT
+CAAACCGCCTTTATTGCCTCCCGCCCCGGGGTATTCTATGGGCAATGCTCAGAAATCTGT
+CAAGCAACAGTAACATCAAACCGACCAGGGTTATTCTATGGCCAATGCTCTGAAATTTGT
+CAAGCTACAGTCACATCAAACCGACCAGGTCTATTCTATGGCCAATGCTCTGAAATTTGC
+CAAACAACCCTAATAACCATACGACCAGGACTGTACTACGGTCAATGCTCAGAAATCTGT
+CAAACAACCTTAATATCAACACGACCAGGCCTATTTTATGGACAATGCTCAGAGATCTGC
+CAAACATCATTTATTGCTACTCGTCCGGGAGTATTTTACGGACAATGTTCAGAAATTTGC
+
+GGGTCAAACCACAGTTTCATACCCATTGTCCTTGAGTTAGTCCCACTAAAGTACTTTGAA
+GGAGCTAATCACAGCTTTATACCAATTGTAGTTGAAGCAGTACCTCTCGAACACTTCGAA
+GGAGCTAACCACAGCTACATACCCATTGTAGTAGAGTCTACCCCCCTAAAACACTTTGAA
+GGAGCAAACCACAGTTTCATGCCCATCGTCCTAGAATTAATTCCCCTAAAAATCTTTGAA
+GGAGCAAACCACAGCTTTATACCCATCGTAGTAGAAGCGGTCCCACTATCTCACTTCGAA
+GGATCTAACCATAGCTTTATGCCCATTGTCCTAGAAATGGTTCCACTAAAATATTTCGAA
+GGCTCAAATCACAGCTTCATACCCATTGTACTAGAAATAGTGCCTCTAAAATATTTCGAA
+GGTTCAAACCACAGCTTCATACCTATTGTCCTCGAATTGGTCCCACTATCCCACTTCGAG
+GGCTCAAACCACAGTTTCATACCAATTGTCCTAGAACTAGTACCCCTAGAAGTCTTTGAA
+GGAGCAAACCACAGCTTTATACCAATTGTAGTTGAAGCAGTACCGCTAACCGACTTTGAA
+
+AAATGATCTGCGTCAATATTA---------------------TAA
+AACTGATCCTCATTAATACTAGAAGACGCCTCGCTAGGAAGCTAA
+GCCTGATCCTCACTA------------------CTGTCATCTTAA
+ATA---------------------GGGCCCGTATTTACCCTATAG
+AACTGGTCCACCCTTATACTAAAAGACGCCTCACTAGGAAGCTAA
+AACTGATCTGCTTCAATAATT---------------------TAA
+AACTGATCAGCTTCTATAATT---------------------TAA
+AAATGATCTACCTCAATGCTT---------------------TAA
+AAATGATCTGTATCAATACTA---------------------TAA
+AACTGATCTTCATCAATACTA---GAAGCATCACTA------AGA
--- /dev/null
+10 705
+Cow ATGGCATATCCCATACAACTAGGATTCCAAGATGCAACATCACCAATCATAGAAGAACTACTTCACTTTCATGACCACACGCTAATAATTGTCTTCTTAATTAGCTCATTAGTACTTTACATTATTTCACTAATACTAACGACAAAGCTGACCCATACAAGCACGATAGATGCACAAGAAGTAGAGACAATCTGAACCATTCTGCCCGCCATCATCTTAATTCTAATTGCTCTTCCTTCTTTACGAATTCTATACATAATAGATGAAATCAATAACCCATCTCTTACAGTAAAAACCATAGGACATCAGTGATACTGAAGCTATGAGTATACAGATTATGAGGACTTAAGCTTCGACTCCTACATAATTCCAACATCAGAATTAAAGCCAGGGGAGCTACGACTATTAGAAGTCGATAATCGAGTTGTACTACCAATAGAAATAACAATCCGAATGTTAGTCTCCTCTGAAGACGTATTACACTCATGAGCTGTGCCCTCTCTAGGACTAAAAACAGACGCAATCCCAGGCCGTCTAAACCAAACAACCCTTATATCGTCCCGTCCAGGCTTATATTACGGTCAATGCTCAGAAATTTGCGGGTCAAACCACAGTTTCATACCCATTGTCCTTGAGTTAGTCCCACTAAAGTACTTTGAAAAATGATCTGCGTCAATATTA---------------------TAA
+Carp ATGGCACACCCAACGCAACTAGGTTTCAAGGACGCGGCCATACCCGTTATAGAGGAACTTCTTCACTTCCACGACCACGCATTAATAATTGTGCTCCTAATTAGCACTTTAGTTTTATATATTATTACTGCAATGGTATCAACTAAACTTACTAATAAATATATTCTAGACTCCCAAGAAATCGAAATCGTATGAACCATTCTACCAGCCGTCATTTTAGTACTAATCGCCCTGCCCTCCCTACGCATCCTGTACCTTATAGACGAAATTAACGACCCTCACCTGACAATTAAAGCAATAGGACACCAATGATACTGAAGTTACGAGTATACAGACTATGAAAATCTAGGATTCGACTCCTATATAGTACCAACCCAAGACCTTGCCCCCGGACAATTCCGACTTCTGGAAACAGACCACCGAATAGTTGTTCCAATAGAATCCCCAGTCCGTGTCCTAGTATCTGCTGAAGACGTGCTACATTCTTGAGCTGTTCCATCCCTTGGCGTAAAAATGGACGCAGTCCCAGGACGACTAAATCAAGCCGCCTTTATTGCCTCACGCCCAGGGGTCTTTTACGGACAATGCTCTGAAATTTGTGGAGCTAATCACAGCTTTATACCAATTGTAGTTGAAGCAGTACCTCTCGAACACTTCGAAAACTGATCCTCATTAATACTAGAAGACGCCTCGCTAGGAAGCTAA
+Chicken ATGGCCAACCACTCCCAACTAGGCTTTCAAGACGCCTCATCCCCCATCATAGAAGAGCTCGTTGAATTCCACGACCACGCCCTGATAGTCGCACTAGCAATTTGCAGCTTAGTACTCTACCTTCTAACTCTTATACTTATAGAAAAACTATCA---TCAAACACCGTAGATGCCCAAGAAGTTGAACTAATCTGAACCATCCTACCCGCTATTGTCCTAGTCCTGCTTGCCCTCCCCTCCCTCCAAATCCTCTACATAATAGACGAAATCGACGAACCTGATCTCACCCTAAAAGCCATCGGACACCAATGATACTGAACCTATGAATACACAGACTTCAAGGACCTCTCATTTGACTCCTACATAACCCCAACAACAGACCTCCCCCTAGGCCACTTCCGCCTACTAGAAGTCGACCATCGCATTGTAATCCCCATAGAATCCCCCATTCGAGTAATCATCACCGCTGATGACGTCCTCCACTCATGAGCCGTACCCGCCCTCGGGGTAAAAACAGACGCAATCCCTGGACGACTAAATCAAACCTCCTTCATCACCACTCGACCAGGAGTGTTTTACGGACAATGCTCAGAAATCTGCGGAGCTAACCACAGCTACATACCCATTGTAGTAGAGTCTACCCCCCTAAAACACTTTGAAGCCTGATCCTCACTA------------------CTGTCATCTTAA
+Human ATGGCACATGCAGCGCAAGTAGGTCTACAAGACGCTACTTCCCCTATCATAGAAGAGCTTATCACCTTTCATGATCACGCCCTCATAATCATTTTCCTTATCTGCTTCCTAGTCCTGTATGCCCTTTTCCTAACACTCACAACAAAACTAACTAATACTAACATCTCAGACGCTCAGGAAATAGAAACCGTCTGAACTATCCTGCCCGCCATCATCCTAGTCCTCATCGCCCTCCCATCCCTACGCATCCTTTACATAACAGACGAGGTCAACGATCCCTCCCTTACCATCAAATCAATTGGCCACCAATGGTACTGAACCTACGAGTACACCGACTACGGCGGACTAATCTTCAACTCCTACATACTTCCCCCATTATTCCTAGAACCAGGCGACCTGCGACTCCTTGACGTTGACAATCGAGTAGTACTCCCGATTGAAGCCCCCATTCGTATAATAATTACATCACAAGACGTCTTGCACTCATGAGCTGTCCCCACATTAGGCTTAAAAACAGATGCAATTCCCGGACGTCTAAACCAAACCACTTTCACCGCTACACGACCGGGGGTATACTACGGTCAATGCTCTGAAATCTGTGGAGCAAACCACAGTTTCATGCCCATCGTCCTAGAATTAATTCCCCTAAAAATCTTTGAAATA---------------------GGGCCCGTATTTACCCTATAG
+Loach ATGGCACATCCCACACAATTAGGATTCCAAGACGCGGCCTCACCCGTAATAGAAGAACTTCTTCACTTCCATGACCATGCCCTAATAATTGTATTTTTGATTAGCGCCCTAGTACTTTATGTTATTATTACAACCGTCTCAACAAAACTCACTAACATATATATTTTGGACTCACAAGAAATTGAAATCGTATGAACTGTGCTCCCTGCCCTAATCCTCATTTTAATCGCCCTCCCCTCACTACGAATTCTATATCTTATAGACGAGATTAATGACCCCCACCTAACAATTAAGGCCATGGGGCACCAATGATACTGAAGCTACGAGTATACTGATTATGAAAACTTAAGTTTTGACTCCTACATAATCCCCACCCAGGACCTAACCCCTGGACAATTCCGGCTACTAGAGACAGACCACCGAATGGTTGTTCCCATAGAATCCCCTATTCGCATTCTTGTTTCCGCCGAAGATGTACTACACTCCTGGGCCCTTCCAGCCATGGGGGTAAAGATAGACGCGGTCCCAGGACGCCTTAACCAAACCGCCTTTATTGCCTCCCGCCCCGGGGTATTCTATGGGCAATGCTCAGAAATCTGTGGAGCAAACCACAGCTTTATACCCATCGTAGTAGAAGCGGTCCCACTATCTCACTTCGAAAACTGGTCCACCCTTATACTAAAAGACGCCTCACTAGGAAGCTAA
+Mouse ATGGCCTACCCATTCCAACTTGGTCTACAAGACGCCACATCCCCTATTATAGAAGAGCTAATAAATTTCCATGATCACACACTAATAATTGTTTTCCTAATTAGCTCCTTAGTCCTCTATATCATCTCGCTAATATTAACAACAAAACTAACACATACAAGCACAATAGATGCACAAGAAGTTGAAACCATTTGAACTATTCTACCAGCTGTAATCCTTATCATAATTGCTCTCCCCTCTCTACGCATTCTATATATAATAGACGAAATCAACAACCCCGTATTAACCGTTAAAACCATAGGGCACCAATGATACTGAAGCTACGAATATACTGACTATGAAGACCTATGCTTTGATTCATATATAATCCCAACAAACGACCTAAAACCTGGTGAACTACGACTGCTAGAAGTTGATAACCGAGTCGTTCTGCCAATAGAACTTCCAATCCGTATATTAATTTCATCTGAAGACGTCCTCCACTCATGAGCAGTCCCCTCCCTAGGACTTAAAACTGATGCCATCCCAGGCCGACTAAATCAAGCAACAGTAACATCAAACCGACCAGGGTTATTCTATGGCCAATGCTCTGAAATTTGTGGATCTAACCATAGCTTTATGCCCATTGTCCTAGAAATGGTTCCACTAAAATATTTCGAAAACTGATCTGCTTCAATAATT---------------------TAA
+Rat ATGGCTTACCCATTTCAACTTGGCTTACAAGACGCTACATCACCTATCATAGAAGAACTTACAAACTTTCATGACCACACCCTAATAATTGTATTCCTCATCAGCTCCCTAGTACTTTATATTATTTCACTAATACTAACAACAAAACTAACACACACAAGCACAATAGACGCCCAAGAAGTAGAAACAATTTGAACAATTCTCCCAGCTGTCATTCTTATTCTAATTGCCCTTCCCTCCCTACGAATTCTATACATAATAGACGAGATTAATAACCCAGTTCTAACAGTAAAAACTATAGGACACCAATGATACTGAAGCTATGAATATACTGACTATGAAGACCTATGCTTTGACTCCTACATAATCCCAACCAATGACCTAAAACCAGGTGAACTTCGTCTATTAGAAGTTGATAATCGGGTAGTCTTACCAATAGAACTTCCAATTCGTATACTAATCTCATCCGAAGACGTCCTGCACTCATGAGCCATCCCTTCACTAGGGTTAAAAACCGACGCAATCCCCGGCCGCCTAAACCAAGCTACAGTCACATCAAACCGACCAGGTCTATTCTATGGCCAATGCTCTGAAATTTGCGGCTCAAATCACAGCTTCATACCCATTGTACTAGAAATAGTGCCTCTAAAATATTTCGAAAACTGATCAGCTTCTATAATT---------------------TAA
+Seal ATGGCATACCCCCTACAAATAGGCCTACAAGATGCAACCTCTCCCATTATAGAGGAGTTACTACACTTCCATGACCACACATTAATAATTGTGTTCCTAATTAGCTCATTAGTACTCTACATTATCTCACTTATACTAACCACGAAACTCACCCACACAAGTACAATAGACGCACAAGAAGTGGAAACGGTGTGAACGATCCTACCCGCTATCATTTTAATTCTCATTGCCCTACCATCATTACGAATCCTCTACATAATGGACGAGATCAATAACCCTTCCTTGACCGTAAAAACTATAGGACATCAGTGATACTGAAGCTATGAGTACACAGACTACGAAGACCTGAACTTTGACTCATATATGATCCCCACACAAGAACTAAAGCCCGGAGAACTACGACTGCTAGAAGTAGACAATCGAGTAGTCCTCCCAATAGAAATAACAATCCGCATACTAATCTCATCAGAAGATGTACTCCACTCATGAGCCGTACCGTCCCTAGGACTAAAAACTGATGCTATCCCAGGACGACTAAACCAAACAACCCTAATAACCATACGACCAGGACTGTACTACGGTCAATGCTCAGAAATCTGTGGTTCAAACCACAGCTTCATACCTATTGTCCTCGAATTGGTCCCACTATCCCACTTCGAGAAATGATCTACCTCAATGCTT---------------------TAA
+Whale ATGGCATATCCATTCCAACTAGGTTTCCAAGATGCAGCATCACCCATCATAGAAGAGCTCCTACACTTTCACGATCATACACTAATAATCGTTTTTCTAATTAGCTCTTTAGTTCTCTACATTATTACCCTAATGCTTACAACCAAATTAACACATACTAGTACAATAGACGCCCAAGAAGTAGAAACTGTCTGAACTATCCTCCCAGCCATTATCTTAATTTTAATTGCCTTGCCTTCATTACGGATCCTTTACATAATAGACGAAGTCAATAACCCCTCCCTCACTGTAAAAACAATAGGTCACCAATGATATTGAAGCTATGAGTATACCGACTACGAAGACCTAAGCTTCGACTCCTATATAATCCCAACATCAGACCTAAAGCCAGGAGAACTACGATTATTAGAAGTAGATAACCGAGTTGTCTTACCTATAGAAATAACAATCCGAATATTAGTCTCATCAGAAGACGTACTCCACTCATGGGCCGTACCCTCCTTGGGCCTAAAAACAGATGCAATCCCAGGACGCCTAAACCAAACAACCTTAATATCAACACGACCAGGCCTATTTTATGGACAATGCTCAGAGATCTGCGGCTCAAACCACAGTTTCATACCAATTGTCCTAGAACTAGTACCCCTAGAAGTCTTTGAAAAATGATCTGTATCAATACTA---------------------TAA
+Frog ATGGCACACCCATCACAATTAGGTTTTCAAGACGCAGCCTCTCCAATTATAGAAGAATTACTTCACTTCCACGACCATACCCTCATAGCCGTTTTTCTTATTAGTACGCTAGTTCTTTACATTATTACTATTATAATAACTACTAAACTAACTAATACAAACCTAATGGACGCACAAGAGATCGAAATAGTGTGAACTATTATACCAGCTATTAGCCTCATCATAATTGCCCTTCCATCCCTTCGTATCCTATATTTAATAGATGAAGTTAATGATCCACACTTAACAATTAAAGCAATCGGCCACCAATGATACTGAAGCTACGAATATACTAACTATGAGGATCTCTCATTTGACTCTTATATAATTCCAACTAATGACCTTACCCCTGGACAATTCCGGCTGCTAGAAGTTGATAATCGAATAGTAGTCCCAATAGAATCTCCAACCCGACTTTTAGTTACAGCCGAAGACGTCCTCCACTCGTGAGCTGTACCCTCCTTGGGTGTCAAAACAGATGCAATCCCAGGACGACTTCATCAAACATCATTTATTGCTACTCGTCCGGGAGTATTTTACGGACAATGTTCAGAAATTTGCGGAGCAAACCACAGCTTTATACCAATTGTAGTTGAAGCAGTACCGCTAACCGACTTTGAAAACTGATCTTCATCAATACTA---GAAGCATCACTA------AGA
--- /dev/null
+<html>
+<header><title>BioJS viewer</title></header>
+
+<body>
+
+<!-- include MSA js + css -->
+<!-- <script src="https://s3-eu-west-1.amazonaws.com/biojs/msa/latest/msa.js"></script> -->
+<!-- <link type=text/css rel=stylesheet href=https://s3-eu-west-1.amazonaws.com/biojs/msa/latest/msa.css /> -->
+
+ <img src="file:/Users/tcnofoegbu/Documents/workspace/java/dev/jalview/classes/images/Jalview_Logo.png" alt="Jalview Logo" title="This html page was generated from Jalview, to import the data back to Jalview, please drag the generated html file and drop it unto the Jalview workbench.
+
+ Alternatively, you could copy the url from the address bar and use Jalview's url importer (main menu-> File-> Input Alignment-> from URL) to import back the alignment jalview." >
+
+</br>
+</br>
+
+<button onclick="javascipt:openJalviewUsingCurrentUrl();">Launch in Jalview</button>
+<input type="button" name="divToggleButton" id="divToggleButton" onclick="javascipt:toggleMenuVisibility();" value="Show Menu"></input>
+
+</br>
+</br>
+
+<div id="yourDiv">press "Run with JS"</div>
+<input type='hidden' id='seqData' name='seqData' value='{"globalColorScheme":"zappo","seqs":[{"id":"1","start":1,"name":"FER_CAPAA/1-97","seq":"----------------------------------------------------------ASYKVKLITPDGPIEFDCPDDVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDVTIETHKEAELVG-","features":[],"end":97},{"id":"2","start":1,"name":"FER_CAPAN/1-144","seq":"------MASVSATMISTSFMPRKPAVTSLKPIP-NVG-EALFGLKS---ANGGKVTCMASYKVKLITPDGPIEFDCPDNVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDVTIETHKEAELVG-","features":[{"xEnd":22,"text":"feature_1","fillColor":"#8c25cd","xStart":2}],"end":144},{"id":"3","start":1,"name":"FER1_SOLLC/1-144","seq":"------MASISGTMISTSFLPRKPAVTSLKAIS-NVG-EALFGLKS---GRNGRITCMASYKVKLITPEGPIEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGSVDQSDGNFLDEDQEAAGFVLTCVAYPKGDVTIETHKEEELTA-","features":[],"end":144},{"id":"4","start":1,"name":"Q93XJ9_SOLTU/1-144","seq":"------MASISGTMISTSFLPRKPVVTSLKAIS-NVG-EALFGLKS---GRNGRITCMASYKVKLITPDGPIEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGTVDQSDGKFLDDDQEAAGFVLTCVAYPKCDVTIETHKEEELTA-","features":[],"end":144},{"id":"5","start":1,"name":"FER1_PEA/1-149","seq":"---MATTPALYGTAVSTSFLRTQPMPMSVTTTKAFSN--GFLGLKT-SLKRGDLAVAMASYKVKLVTPDGTQEFECPSDVYILDHAEEVGIDLPYSCRAGSCSSCAGKVVGGEVDQSDGSFLDDEQIEAGFVLTCVAYPTSDVVIETHKEEDLTA-","features":[],"end":149},{"id":"6","start":1,"name":"Q7XA98_TRIPR/1-152","seq":"---MATTPALYGTAVSTSFMRRQPVPMSVATTTTTKAFPSGFGLKSVSTKRGDLAVAMATYKVKLITPEGPQEFDCPDDVYILDHAEEVGIELPYSCRAGSCSSCAGKVVNGNVNQEDGSFLDDEQIEGGWVLTCVAFPTSDVTIETHKEEELTA-","features":[],"end":152},{"id":"7","start":1,"name":"FER1_MESCR/1-148","seq":"--MAATTAALSGATMSTAFAPKT--PPMTAALPTNVG-RALFGLKS--SASRGRVTAMAAYKVTLVTPEGKQELECPDDVYILDAAEEAGIDLPYSCRAGSCSSCAGKVTSGSVNQDDGSFLDDDQIKEGWVLTCVAYPTGDVTIETHKEEELTA-","features":[],"end":148},{"id":"8","start":1,"name":"FER1_SPIOL/1-147","seq":"----MAATTTTMMGMATTFVPKPQAPPMMAALPSNTG-RSLFGLKT--GSRGGRMT-MAAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDDDQIDEGWVLTCAAYPVSDVTIETHKEEELTA-","features":[],"end":147},{"id":"9","start":1,"name":"FER3_RAPSA/1-96","seq":"----------------------------------------------------------ATYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDVTIETHREEDMV--","features":[],"end":96},{"id":"10","start":1,"name":"FER1_ARATH/1-148","seq":"----MASTALSSAIVGTSFIRRSPAPISLRSLPSANT-QSLFGLKS-GTARGGRVTAMATYKVKFITPEGELEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDVTIETHKEEDIV--","features":[],"end":148},{"id":"11","start":1,"name":"FER_BRANA/1-96","seq":"----------------------------------------------------------ATYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDVTIETHKEEELV--","features":[],"end":96},{"id":"12","start":1,"name":"FER2_ARATH/1-148","seq":"----MASTALSSAIVSTSFLRRQQTPISLRSLPFANT-QSLFGLKS-STARGGRVTAMATYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDVVIETHKEEAIM--","features":[],"end":148},{"id":"13","start":1,"name":"Q93Z60_ARATH/1-118","seq":"----MASTALSSAIVSTSFLRRQQTPISLRSLPFANT-QSLFGLKS-STARGGRVTAMATYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD--------------------------------","features":[],"end":118},{"id":"14","start":1,"name":"FER1_MAIZE/1-150","seq":"MATVLGSPRAPAFFFSSSSLRAAPAPTAVALPAAKVG---IMGRSA---SSRRRLRAQATYNVKLITPEGEVELQVPDDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDVVIETHKEEELTGA","features":[],"end":150},{"id":"15","start":1,"name":"O80429_MAIZE/1-140","seq":"---------MAATALSMSILRAPP-PCFSSPLRLRVAVAKPLAAPM----RRQLLRAQATYNVKLITPEGEVELQVPDDVYILDFAEEEGIDLPFSCRAGSCSSCAGKVVSGSVDQSDQSFLNDNQVADGWVLTCAAYPTSDVVIETHKEDDLL--","features":[],"end":140}]}'/>
+
+</body>
+</html>
+
+
+
+<script>
+
+function toggleMenuVisibility(){
+ //alert("toggleMenuVisibility called!");
+
+ var menu = document.getElementsByClassName("biojs_msa_menubar");
+ var divToggleButton = document.getElementById("divToggleButton");
+ if(menu[0].style.display == 'block'){
+ menu[0].style.display = 'none';
+ divToggleButton.value="Show Menu";
+ }else{
+ menu[0].style.display = 'block';
+ divToggleButton.value="Hide Menu";
+ }
+}
+function openJalviewUsingCurrentUrl2(){
+var jnpl = "<!--"+
+"Hi!"+
+"If you have downloaded this file after pressing \"Launch Full Application\" from Jalview on a web page and you don't know what to do with this file, you must install Java from http://www.java.sun.com then try opening this file again."+
+" \n"+
+" JNLP generated by /jalviewServlet/services/launchAppDev"+
+" JNLP generated from http://www.jalview.org/builds/develop/webstart/jalview.jnlp"+
+"Available servlet parameters (please URLEncode):"+
+" open=<alignment file URL>"+
+" jvm-max-heap=heap size in M or G"+
+" features maps to '-features'"+
+" treeFile maps to '-tree'"+
+" tree maps to '-tree'"+
+" annotations maps to '-annotations'"+
+" colour maps to '-colour'"+
+" "+
+"-->"+
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?><jnlp spec=\"1.0+\" codebase=\"http://www.jalview.org/builds/develop/webstart\"> <information> <title>Jalview</title> <vendor>The Barton Group</vendor> <homepage href=\"http://www.jalview.org\"/> <description>Jalview Multiple Alignment Editor</description> <description kind=\"short\">Jalview</description> <icon href=\"JalviewLogo_big.png\"/> <offline-allowed/> </information> <security> <all-permissions/> </security> <resources> <j2se version=\"1.7+\" initial-heap-size=\"10M\" max-heap-size=\"2G\"/> <jar href=\"jalview.jar\"/> <jar href=\"JGoogleAnalytics_0.3.jar\"/> <jar href=\"Jmol-12.2.4.jar\"/> <jar href=\"VARNAv3-91.jar\"/> <jar href=\"activation.jar\"/> <jar href=\"apache-mime4j-0.6.jar\"/> <jar href=\"axis.jar\"/> <jar href=\"castor-1.1-cycle-xml.jar\"/> <jar href=\"commons-codec-1.3.jar\"/> <jar href=\"commons-discovery.jar\"/> <jar href=\"commons-logging-1.1.1.jar\"/> <jar href=\"groovy-all-1.8.2.jar\"/> <jar href=\"httpclient-4.0.3.jar\"/> <jar href=\"httpcore-4.0.1.jar\"/> <jar href=\"httpmime-4.0.3.jar\"/> <jar href=\"jalview_jnlp_vm.jar\"/> <jar href=\"jaxrpc.jar\"/> <jar href=\"jdas-1.0.4.jar\"/> <jar href=\"jhall.jar\"/> <jar href=\"json_simple-1.1.jar\"/> <jar href=\"jsoup-1.8.1.jar\"/> <jar href=\"jswingreader-0.3.jar\"/> <jar href=\"log4j-to-slf4j-2.0-rc2.jar\"/> <jar href=\"mail.jar\"/> <jar href=\"miglayout-4.0-swing.jar\"/> <jar href=\"min-jabaws-client-2.1.0.jar\"/> <jar href=\"regex.jar\"/> <jar href=\"saaj.jar\"/> <jar href=\"slf4j-api-1.7.7.jar\"/> <jar href=\"slf4j-log4j12-1.7.7.jar\"/> <jar href=\"spring-core-3.0.5.RELEASE.jar\"/> <jar href=\"spring-web-3.0.5.RELEASE.jar\"/> <jar href=\"vamsas-client.jar\"/> <jar href=\"wsdl4j.jar\"/> <jar href=\"xercesImpl.jar\"/> <jar href=\"xml-apis.jar\"/> <property name=\"jalview.version\" value=\"Development Branch Build\"/> </resources>"+
+"<application-desc main-class=\"jalview.bin.Jalview\">"+
+"<argument>-open</argument>"+
+"<argument>file:///Users/tcnofoegbu/Documents/workspace/java/dev/jalview/examples/example_biojs.html</argument>"+
+"</application-desc>"+
+" <security>"+
+" <all-permissions/>"+
+" </security>"+
+"</jnlp>"
+
+var encodedUri = encodeURI(jnpl);
+window.open(encodedUri)
+//alert(jnpl)
+}
+
+function openJalviewUsingCurrentUrl(){
+ var url = "http://webservices.compbio.dundee.ac.uk:38080/jalviewServlet/services/launchAppDev";
+ var myForm = document.createElement("form");
+ myForm.action = url;
+
+ var myInput = document.createElement("input") ;
+ myInput.setAttribute("name", "jvm-max-heap") ;
+ myInput.setAttribute("value", "2G");
+ myForm.appendChild(myInput) ;
+
+ var myInput1 = document.createElement("input") ;
+ myInput1.setAttribute("name", "open") ;
+ myInput1.setAttribute("value", document.URL);
+ myForm.appendChild(myInput1) ;
+
+
+ document.body.appendChild(myForm) ;
+ myForm.submit() ;
+ document.body.removeChild(myForm) ;
+}
+
+
+require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+var css = ".biojs_msa_stage {\n cursor: default;\n line-height: normal; }\n\n.biojs_msa_labels {\n color: black;\n display: inline-block;\n white-space: nowrap;\n cursor: pointer;\n vertical-align: top; }\n\n.biojs_msa_seqblock {\n cursor: move; }\n\n.biojs_msa_layer {\n display: block;\n white-space: nowrap; }\n\n.biojs_msa_labelblock::-webkit-scrollbar, .biojs_msa_header::-webkit-scrollbar {\n -webkit-appearance: none;\n width: 7px;\n height: 7px; }\n\n.biojs_msa_labelblock::-webkit-scrollbar-thumb, .biojs_msa_header::-webkit-scrollbar-thumb {\n border-radius: 4px;\n background-color: rgba(0, 0, 0, 0.5);\n box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); }\n\n.biojs_msa_marker {\n color: grey;\n white-space: nowrap;\n cursor: pointer; }\n\n.biojs_msa_marker span {\n text-align: center; }\n\n.biojs_msa_menubar .biojs_msa_menubar_alink {\n background: #3498db;\n background-image: -webkit-linear-gradient(top, #3498db, #2980b9);\n background-image: -moz-linear-gradient(top, #3498db, #2980b9);\n background-image: -ms-linear-gradient(top, #3498db, #2980b9);\n background-image: -o-linear-gradient(top, #3498db, #2980b9);\n background-image: linear-gradient(to bottom, #3498db, #2980b9);\n -webkit-border-radius: 28;\n -moz-border-radius: 28;\n border-radius: 28px;\n font-family: Arial;\n color: #ffffff;\n padding: 3px 10px 3px 10px;\n margin-left: 10px;\n text-decoration: none; }\n\n.biojs_msa_menubar .biojs_msa_menubar_alink:hover {\n cursor: pointer; }\n\n/* jquery dropdown CSS */\n.dropdown {\n position: absolute;\n z-index: 9999999;\n display: none; }\n\n.dropdown .dropdown-menu,\n.dropdown .dropdown-panel {\n min-width: 160px;\n max-width: 360px;\n list-style: none;\n background: #FFF;\n border: solid 1px #DDD;\n border: solid 1px rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n overflow: visible;\n padding: 4px 0;\n margin: 0; }\n\n.dropdown .dropdown-panel {\n padding: 10px; }\n\n.dropdown.dropdown-scroll .dropdown-menu,\n.dropdown.dropdown-scroll .dropdown-panel {\n max-height: 358px;\n overflow: auto; }\n\n.dropdown .dropdown-menu LI {\n list-style: none;\n padding: 0 0;\n margin: 0;\n line-height: 18px; }\n\n.dropdown .dropdown-menu LI,\n.dropdown .dropdown-menu LABEL {\n display: block;\n color: #555;\n text-decoration: none;\n line-height: 18px;\n padding: 3px 15px;\n white-space: nowrap; }\n\n.dropdown .dropdown-menu LI:hover,\n.dropdown .dropdown-menu LABEL:hover {\n background-color: #08C;\n color: #FFF;\n cursor: pointer; }\n\n.dropdown .dropdown-menu .dropdown-divider {\n font-size: 1px;\n border-top: solid 1px #E5E5E5;\n padding: 0;\n margin: 5px 0; }\n"; (require("/home/travis/build/greenify/biojs-vis-msa/node_modules/cssify"))(css); module.exports = css;
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/cssify":48}],2:[function(require,module,exports){
+module.exports = require("./src/index");
+
+},{"./src/index":72}],3:[function(require,module,exports){
+var _ = require('underscore');
+var viewType = require("backbone-viewj");
+var pluginator;
+
+module.exports = pluginator = viewType.extend({
+ renderSubviews: function() {
+ var oldEl = this.el;
+ var el = document.createElement("div");
+ this.setElement(el);
+ var frag = document.createDocumentFragment();
+ if (oldEl.parentNode != null) {
+ oldEl.parentNode.replaceChild(this.el, oldEl);
+ }
+ var views = this._views();
+ var viewsSorted = _.sortBy(views, function(el) {
+ return el.ordering;
+ });
+ var view, node;
+ for (var i = 0; i < viewsSorted.length; i++) {
+ view = viewsSorted[i];
+ view.render();
+ node = view.el;
+ if (node != null) {
+ frag.appendChild(node);
+ }
+ }
+ el.appendChild(frag);
+ return el;
+ },
+ addView: function(key, view) {
+ var views = this._views();
+ if (view == null) {
+ throw "Invalid plugin. ";
+ }
+ if (view.ordering == null) {
+ view.ordering = key;
+ }
+ return views[key] = view;
+ },
+ removeViews: function() {
+ var el, key;
+ var views = this._views();
+ for (key in views) {
+ el = views[key];
+ el.undelegateEvents();
+ el.unbind();
+ if (el.removeViews != null) {
+ el.removeViews();
+ }
+ el.remove();
+ }
+ return this.views = {};
+ },
+ removeView: function(key) {
+ var views = this._views();
+ views[key].remove();
+ return delete views[key];
+ },
+ getView: function(key) {
+ var views = this._views();
+ return views[key];
+ },
+ remove: function() {
+ this.removeViews();
+ return viewType.prototype.remove.apply(this);
+ },
+ _views: function() {
+ if (this.views == null) {
+ this.views = {};
+ }
+ return this.views;
+ }
+});
+
+},{"backbone-viewj":10,"underscore":59}],4:[function(require,module,exports){
+// Backbone.js 1.1.2
+
+// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Backbone may be freely distributed under the MIT license.
+// For all details and documentation:
+// http://backbonejs.org
+
+var Events = require("backbone-events-standalone");
+var extend = require("backbone-extend-standalone");
+var _ = require("underscore");
+var Model = require("./model");
+
+// Create local references to array methods we'll want to use later.
+var array = [];
+var slice = array.slice;
+
+// Backbone.Collection
+// -------------------
+
+// If models tend to represent a single row of data, a Backbone Collection is
+// more analogous to a table full of data ... or a small slice or page of that
+// table, or a collection of rows that belong together for a particular reason
+// -- all of the messages in this particular folder, all of the documents
+// belonging to this particular author, and so on. Collections maintain
+// indexes of their models, both in order, and for lookup by `id`.
+
+// Create a new **Collection**, perhaps to contain a specific type of `model`.
+// If a `comparator` is specified, the Collection will maintain
+// its models in sort order, as they're added and removed.
+var Collection = function(models, options) {
+ options || (options = {});
+ if (options.model) this.model = options.model;
+ if (options.comparator !== void 0) this.comparator = options.comparator;
+ this._reset();
+ this.initialize.apply(this, arguments);
+ if (models) this.reset(models, _.extend({silent: true}, options));
+};
+
+// Default options for `Collection#set`.
+var setOptions = {add: true, remove: true, merge: true};
+var addOptions = {add: true, remove: false};
+
+// Define the Collection's inheritable methods.
+_.extend(Collection.prototype, Events, {
+
+ // The default model for a collection is just a **Backbone.Model**.
+ // This should be overridden in most cases.
+ model: Model,
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // The JSON representation of a Collection is an array of the
+ // models' attributes.
+ toJSON: function(options) {
+ return this.map(function(model){ return model.toJSON(options); });
+ },
+
+ // Proxy `Backbone.sync` by default.
+ sync: function() {
+ return Backbone.sync.apply(this, arguments);
+ },
+
+ // Add a model, or list of models to the set.
+ add: function(models, options) {
+ return this.set(models, _.extend({merge: false}, options, addOptions));
+ },
+
+ // Remove a model, or a list of models from the set.
+ remove: function(models, options) {
+ var singular = !_.isArray(models);
+ models = singular ? [models] : _.clone(models);
+ options || (options = {});
+ for (var i = 0, length = models.length; i < length; i++) {
+ var model = models[i] = this.get(models[i]);
+ if (!model) continue;
+ var id = this.modelId(model.attributes);
+ if (id != null) delete this._byId[id];
+ delete this._byId[model.cid];
+ var index = this.indexOf(model);
+ this.models.splice(index, 1);
+ this.length--;
+ if (!options.silent) {
+ options.index = index;
+ model.trigger('remove', model, this, options);
+ }
+ this._removeReference(model, options);
+ }
+ return singular ? models[0] : models;
+ },
+
+ // Update a collection by `set`-ing a new list of models, adding new ones,
+ // removing models that are no longer present, and merging models that
+ // already exist in the collection, as necessary. Similar to **Model#set**,
+ // the core operation for updating the data contained by the collection.
+ set: function(models, options) {
+ options = _.defaults({}, options, setOptions);
+ if (options.parse) models = this.parse(models, options);
+ var singular = !_.isArray(models);
+ models = singular ? (models ? [models] : []) : models.slice();
+ var id, model, attrs, existing, sort;
+ var at = options.at;
+ var sortable = this.comparator && (at == null) && options.sort !== false;
+ var sortAttr = _.isString(this.comparator) ? this.comparator : null;
+ var toAdd = [], toRemove = [], modelMap = {};
+ var add = options.add, merge = options.merge, remove = options.remove;
+ var order = !sortable && add && remove ? [] : false;
+
+ // Turn bare objects into model references, and prevent invalid models
+ // from being added.
+ for (var i = 0, length = models.length; i < length; i++) {
+ attrs = models[i];
+
+ // If a duplicate is found, prevent it from being added and
+ // optionally merge it into the existing model.
+ if (existing = this.get(attrs)) {
+ if (remove) modelMap[existing.cid] = true;
+ if (merge && attrs !== existing) {
+ attrs = this._isModel(attrs) ? attrs.attributes : attrs;
+ if (options.parse) attrs = existing.parse(attrs, options);
+ existing.set(attrs, options);
+ if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
+ }
+ models[i] = existing;
+
+ // If this is a new, valid model, push it to the `toAdd` list.
+ } else if (add) {
+ model = models[i] = this._prepareModel(attrs, options);
+ if (!model) continue;
+ toAdd.push(model);
+ this._addReference(model, options);
+ }
+
+ // Do not add multiple models with the same `id`.
+ model = existing || model;
+ if (!model) continue;
+ id = this.modelId(model.attributes);
+ if (order && (model.isNew() || !modelMap[id])) order.push(model);
+ modelMap[id] = true;
+ }
+
+ // Remove nonexistent models if appropriate.
+ if (remove) {
+ for (var i = 0, length = this.length; i < length; i++) {
+ if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
+ }
+ if (toRemove.length) this.remove(toRemove, options);
+ }
+
+ // See if sorting is needed, update `length` and splice in new models.
+ if (toAdd.length || (order && order.length)) {
+ if (sortable) sort = true;
+ this.length += toAdd.length;
+ if (at != null) {
+ for (var i = 0, length = toAdd.length; i < length; i++) {
+ this.models.splice(at + i, 0, toAdd[i]);
+ }
+ } else {
+ if (order) this.models.length = 0;
+ var orderedModels = order || toAdd;
+ for (var i = 0, length = orderedModels.length; i < length; i++) {
+ this.models.push(orderedModels[i]);
+ }
+ }
+ }
+
+ // Silently sort the collection if appropriate.
+ if (sort) this.sort({silent: true});
+
+ // Unless silenced, it's time to fire all appropriate add/sort events.
+ if (!options.silent) {
+ var addOpts = at != null ? _.clone(options) : options;
+ for (var i = 0, length = toAdd.length; i < length; i++) {
+ if (at != null) addOpts.index = at + i;
+ (model = toAdd[i]).trigger('add', model, this, addOpts);
+ }
+ if (sort || (order && order.length)) this.trigger('sort', this, options);
+ }
+
+ // Return the added (or merged) model (or models).
+ return singular ? models[0] : models;
+ },
+
+ // When you have more items than you want to add or remove individually,
+ // you can reset the entire set with a new list of models, without firing
+ // any granular `add` or `remove` events. Fires `reset` when finished.
+ // Useful for bulk operations and optimizations.
+ reset: function(models, options) {
+ options || (options = {});
+ for (var i = 0, length = this.models.length; i < length; i++) {
+ this._removeReference(this.models[i], options);
+ }
+ options.previousModels = this.models;
+ this._reset();
+ models = this.add(models, _.extend({silent: true}, options));
+ if (!options.silent) this.trigger('reset', this, options);
+ return models;
+ },
+
+ // Add a model to the end of the collection.
+ push: function(model, options) {
+ return this.add(model, _.extend({at: this.length}, options));
+ },
+
+ // Remove a model from the end of the collection.
+ pop: function(options) {
+ var model = this.at(this.length - 1);
+ this.remove(model, options);
+ return model;
+ },
+
+ // Add a model to the beginning of the collection.
+ unshift: function(model, options) {
+ return this.add(model, _.extend({at: 0}, options));
+ },
+
+ // Remove a model from the beginning of the collection.
+ shift: function(options) {
+ var model = this.at(0);
+ this.remove(model, options);
+ return model;
+ },
+
+ // Slice out a sub-array of models from the collection.
+ slice: function() {
+ return slice.apply(this.models, arguments);
+ },
+
+ // Get a model from the set by id.
+ get: function(obj) {
+ if (obj == null) return void 0;
+ var id = this.modelId(this._isModel(obj) ? obj.attributes : obj);
+ return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
+ },
+
+ // Get the model at the given index.
+ at: function(index) {
+ if (index < 0) index += this.length;
+ return this.models[index];
+ },
+
+ // Return models with matching attributes. Useful for simple cases of
+ // `filter`.
+ where: function(attrs, first) {
+ if (_.isEmpty(attrs)) return first ? void 0 : [];
+ return this[first ? 'find' : 'filter'](function(model) {
+ for (var key in attrs) {
+ if (attrs[key] !== model.get(key)) return false;
+ }
+ return true;
+ });
+ },
+
+ // Return the first model with matching attributes. Useful for simple cases
+ // of `find`.
+ findWhere: function(attrs) {
+ return this.where(attrs, true);
+ },
+
+ // Force the collection to re-sort itself. You don't need to call this under
+ // normal circumstances, as the set will maintain sort order as each item
+ // is added.
+ sort: function(options) {
+ if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
+ options || (options = {});
+
+ // Run sort based on type of `comparator`.
+ if (_.isString(this.comparator) || this.comparator.length === 1) {
+ this.models = this.sortBy(this.comparator, this);
+ } else {
+ this.models.sort(_.bind(this.comparator, this));
+ }
+
+ if (!options.silent) this.trigger('sort', this, options);
+ return this;
+ },
+
+ // Pluck an attribute from each model in the collection.
+ pluck: function(attr) {
+ return _.invoke(this.models, 'get', attr);
+ },
+
+ // Fetch the default set of models for this collection, resetting the
+ // collection when they arrive. If `reset: true` is passed, the response
+ // data will be passed through the `reset` method instead of `set`.
+ fetch: function(options) {
+ options = options ? _.clone(options) : {};
+ if (options.parse === void 0) options.parse = true;
+ var success = options.success;
+ var collection = this;
+ options.success = function(resp) {
+ var method = options.reset ? 'reset' : 'set';
+ collection[method](resp, options);
+ if (success) success(collection, resp, options);
+ collection.trigger('sync', collection, resp, options);
+ };
+ wrapError(this, options);
+ return this.sync('read', this, options);
+ },
+
+ // Create a new instance of a model in this collection. Add the model to the
+ // collection immediately, unless `wait: true` is passed, in which case we
+ // wait for the server to agree.
+ create: function(model, options) {
+ options = options ? _.clone(options) : {};
+ if (!(model = this._prepareModel(model, options))) return false;
+ if (!options.wait) this.add(model, options);
+ var collection = this;
+ var success = options.success;
+ options.success = function(model, resp) {
+ if (options.wait) collection.add(model, options);
+ if (success) success(model, resp, options);
+ };
+ model.save(null, options);
+ return model;
+ },
+
+ // **parse** converts a response into a list of models to be added to the
+ // collection. The default implementation is just to pass it through.
+ parse: function(resp, options) {
+ return resp;
+ },
+
+ // Create a new collection with an identical list of models as this one.
+ clone: function() {
+ return new this.constructor(this.models, {
+ model: this.model,
+ comparator: this.comparator
+ });
+ },
+
+ // Define how to uniquely identify models in the collection.
+ modelId: function (attrs) {
+ return attrs[this.model.prototype.idAttribute || 'id'];
+ },
+
+ // Private method to reset all internal state. Called when the collection
+ // is first initialized or reset.
+ _reset: function() {
+ this.length = 0;
+ this.models = [];
+ this._byId = {};
+ },
+
+ // Prepare a hash of attributes (or other model) to be added to this
+ // collection.
+ _prepareModel: function(attrs, options) {
+ if (this._isModel(attrs)) {
+ if (!attrs.collection) attrs.collection = this;
+ return attrs;
+ }
+ options = options ? _.clone(options) : {};
+ options.collection = this;
+ var model = new this.model(attrs, options);
+ if (!model.validationError) return model;
+ this.trigger('invalid', this, model.validationError, options);
+ return false;
+ },
+
+ // Method for checking whether an object should be considered a model for
+ // the purposes of adding to the collection.
+ _isModel: function (model) {
+ return model instanceof Model;
+ },
+
+ // Internal method to create a model's ties to a collection.
+ _addReference: function(model, options) {
+ this._byId[model.cid] = model;
+ var id = this.modelId(model.attributes);
+ if (id != null) this._byId[id] = model;
+ model.on('all', this._onModelEvent, this);
+ },
+
+ // Internal method to sever a model's ties to a collection.
+ _removeReference: function(model, options) {
+ if (this === model.collection) delete model.collection;
+ model.off('all', this._onModelEvent, this);
+ },
+
+ // Internal method called every time a model in the set fires an event.
+ // Sets need to update their indexes when models change ids. All other
+ // events simply proxy through. "add" and "remove" events that originate
+ // in other collections are ignored.
+ _onModelEvent: function(event, model, collection, options) {
+ if ((event === 'add' || event === 'remove') && collection !== this) return;
+ if (event === 'destroy') this.remove(model, options);
+ if (event === 'change') {
+ var prevId = this.modelId(model.previousAttributes());
+ var id = this.modelId(model.attributes);
+ if (prevId !== id) {
+ if (prevId != null) delete this._byId[prevId];
+ if (id != null) this._byId[id] = model;
+ }
+ }
+ this.trigger.apply(this, arguments);
+ }
+
+});
+
+// Underscore methods that we want to implement on the Collection.
+// 90% of the core usefulness of Backbone Collections is actually implemented
+// right here:
+var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
+ 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
+ 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
+ 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
+ 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
+ 'lastIndexOf', 'isEmpty', 'chain', 'sample', 'partition'];
+
+// Mix in each Underscore method as a proxy to `Collection#models`.
+_.each(methods, function(method) {
+ if (!_[method]) return;
+ Collection.prototype[method] = function() {
+ var args = slice.call(arguments);
+ args.unshift(this.models);
+ return _[method].apply(_, args);
+ };
+});
+
+// Underscore methods that take a property name as an argument.
+var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy'];
+
+// Use attributes instead of properties.
+_.each(attributeMethods, function(method) {
+ if (!_[method]) return;
+ Collection.prototype[method] = function(value, context) {
+ var iterator = _.isFunction(value) ? value : function(model) {
+ return model.get(value);
+ };
+ return _[method](this.models, iterator, context);
+ };
+});
+
+// setup inheritance
+Collection.extend = extend;
+module.exports = Collection;
+
+},{"./model":6,"backbone-events-standalone":8,"backbone-extend-standalone":9,"underscore":59}],5:[function(require,module,exports){
+module.exports.Model = require("./model");
+module.exports.Collection = require("./collection");
+module.exports.Events = require("backbone-events-standalone");
+module.exports.extend = require("backbone-extend-standalone");
+
+},{"./collection":4,"./model":6,"backbone-events-standalone":8,"backbone-extend-standalone":9}],6:[function(require,module,exports){
+// Backbone.js 1.1.2
+
+// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Backbone may be freely distributed under the MIT license.
+// For all details and documentation:
+// http://backbonejs.org
+
+var Events = require("backbone-events-standalone");
+var extend = require("backbone-extend-standalone");
+var _ = require("underscore");
+
+// Backbone.Model
+// --------------
+
+// Backbone **Models** are the basic data object in the framework --
+// frequently representing a row in a table in a database on your server.
+// A discrete chunk of data and a bunch of useful, related methods for
+// performing computations and transformations on that data.
+
+// Create a new model with the specified attributes. A client id (`cid`)
+// is automatically generated and assigned for you.
+var Model = function(attributes, options) {
+ var attrs = attributes || {};
+ options || (options = {});
+ this.cid = _.uniqueId('c');
+ this.attributes = {};
+ if (options.collection) this.collection = options.collection;
+ if (options.parse) attrs = this.parse(attrs, options) || {};
+ attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
+ this.set(attrs, options);
+ this.changed = {};
+ this.initialize.apply(this, arguments);
+};
+
+// Attach all inheritable methods to the Model prototype.
+_.extend(Model.prototype, Events, {
+
+ // A hash of attributes whose current and previous value differ.
+ changed: null,
+
+ // The value returned during the last failed validation.
+ validationError: null,
+
+ // The default name for the JSON `id` attribute is `"id"`. MongoDB and
+ // CouchDB users may want to set this to `"_id"`.
+ idAttribute: 'id',
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // Return a copy of the model's `attributes` object.
+ toJSON: function(options) {
+ return _.clone(this.attributes);
+ },
+
+ // Proxy `Backbone.sync` by default -- but override this if you need
+ // custom syncing semantics for *this* particular model.
+ sync: function() {
+ return Backbone.sync.apply(this, arguments);
+ },
+
+ // Get the value of an attribute.
+ get: function(attr) {
+ return this.attributes[attr];
+ },
+
+ // Get the HTML-escaped value of an attribute.
+ escape: function(attr) {
+ return _.escape(this.get(attr));
+ },
+
+ // Returns `true` if the attribute contains a value that is not null
+ // or undefined.
+ has: function(attr) {
+ return this.get(attr) != null;
+ },
+
+ // Set a hash of model attributes on the object, firing `"change"`. This is
+ // the core primitive operation of a model, updating the data and notifying
+ // anyone who needs to know about the change in state. The heart of the beast.
+ set: function(key, val, options) {
+ var attr, attrs, unset, changes, silent, changing, prev, current;
+ if (key == null) return this;
+
+ // Handle both `"key", value` and `{key: value}` -style arguments.
+ if (typeof key === 'object') {
+ attrs = key;
+ options = val;
+ } else {
+ (attrs = {})[key] = val;
+ }
+
+ options || (options = {});
+
+ // Run validation.
+ if (!this._validate(attrs, options)) return false;
+
+ // Extract attributes and options.
+ unset = options.unset;
+ silent = options.silent;
+ changes = [];
+ changing = this._changing;
+ this._changing = true;
+
+ if (!changing) {
+ this._previousAttributes = _.clone(this.attributes);
+ this.changed = {};
+ }
+ current = this.attributes, prev = this._previousAttributes;
+
+ // Check for changes of `id`.
+ if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
+
+ // For each `set` attribute, update or delete the current value.
+ for (attr in attrs) {
+ val = attrs[attr];
+ if (!_.isEqual(current[attr], val)) changes.push(attr);
+ if (!_.isEqual(prev[attr], val)) {
+ this.changed[attr] = val;
+ } else {
+ delete this.changed[attr];
+ }
+ unset ? delete current[attr] : current[attr] = val;
+ }
+
+ // Trigger all relevant attribute changes.
+ if (!silent) {
+ if (changes.length) this._pending = options;
+ for (var i = 0, length = changes.length; i < length; i++) {
+ this.trigger('change:' + changes[i], this, current[changes[i]], options);
+ }
+ }
+
+ // You might be wondering why there's a `while` loop here. Changes can
+ // be recursively nested within `"change"` events.
+ if (changing) return this;
+ if (!silent) {
+ while (this._pending) {
+ options = this._pending;
+ this._pending = false;
+ this.trigger('change', this, options);
+ }
+ }
+ this._pending = false;
+ this._changing = false;
+ return this;
+ },
+
+ // Remove an attribute from the model, firing `"change"`. `unset` is a noop
+ // if the attribute doesn't exist.
+ unset: function(attr, options) {
+ return this.set(attr, void 0, _.extend({}, options, {unset: true}));
+ },
+
+ // Clear all attributes on the model, firing `"change"`.
+ clear: function(options) {
+ var attrs = {};
+ for (var key in this.attributes) attrs[key] = void 0;
+ return this.set(attrs, _.extend({}, options, {unset: true}));
+ },
+
+ // Determine if the model has changed since the last `"change"` event.
+ // If you specify an attribute name, determine if that attribute has changed.
+ hasChanged: function(attr) {
+ if (attr == null) return !_.isEmpty(this.changed);
+ return _.has(this.changed, attr);
+ },
+
+ // Return an object containing all the attributes that have changed, or
+ // false if there are no changed attributes. Useful for determining what
+ // parts of a view need to be updated and/or what attributes need to be
+ // persisted to the server. Unset attributes will be set to undefined.
+ // You can also pass an attributes object to diff against the model,
+ // determining if there *would be* a change.
+ changedAttributes: function(diff) {
+ if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
+ var val, changed = false;
+ var old = this._changing ? this._previousAttributes : this.attributes;
+ for (var attr in diff) {
+ if (_.isEqual(old[attr], (val = diff[attr]))) continue;
+ (changed || (changed = {}))[attr] = val;
+ }
+ return changed;
+ },
+
+ // Get the previous value of an attribute, recorded at the time the last
+ // `"change"` event was fired.
+ previous: function(attr) {
+ if (attr == null || !this._previousAttributes) return null;
+ return this._previousAttributes[attr];
+ },
+
+ // Get all of the attributes of the model at the time of the previous
+ // `"change"` event.
+ previousAttributes: function() {
+ return _.clone(this._previousAttributes);
+ },
+
+ // Fetch the model from the server. If the server's representation of the
+ // model differs from its current attributes, they will be overridden,
+ // triggering a `"change"` event.
+ fetch: function(options) {
+ options = options ? _.clone(options) : {};
+ if (options.parse === void 0) options.parse = true;
+ var model = this;
+ var success = options.success;
+ options.success = function(resp) {
+ if (!model.set(model.parse(resp, options), options)) return false;
+ if (success) success(model, resp, options);
+ model.trigger('sync', model, resp, options);
+ };
+ wrapError(this, options);
+ return this.sync('read', this, options);
+ },
+
+ // Set a hash of model attributes, and sync the model to the server.
+ // If the server returns an attributes hash that differs, the model's
+ // state will be `set` again.
+ save: function(key, val, options) {
+ var attrs, method, xhr, attributes = this.attributes;
+
+ // Handle both `"key", value` and `{key: value}` -style arguments.
+ if (key == null || typeof key === 'object') {
+ attrs = key;
+ options = val;
+ } else {
+ (attrs = {})[key] = val;
+ }
+
+ options = _.extend({validate: true}, options);
+
+ // If we're not waiting and attributes exist, save acts as
+ // `set(attr).save(null, opts)` with validation. Otherwise, check if
+ // the model will be valid when the attributes, if any, are set.
+ if (attrs && !options.wait) {
+ if (!this.set(attrs, options)) return false;
+ } else {
+ if (!this._validate(attrs, options)) return false;
+ }
+
+ // Set temporary attributes if `{wait: true}`.
+ if (attrs && options.wait) {
+ this.attributes = _.extend({}, attributes, attrs);
+ }
+
+ // After a successful server-side save, the client is (optionally)
+ // updated with the server-side state.
+ if (options.parse === void 0) options.parse = true;
+ var model = this;
+ var success = options.success;
+ options.success = function(resp) {
+ // Ensure attributes are restored during synchronous saves.
+ model.attributes = attributes;
+ var serverAttrs = model.parse(resp, options);
+ if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
+ if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
+ return false;
+ }
+ if (success) success(model, resp, options);
+ model.trigger('sync', model, resp, options);
+ };
+ wrapError(this, options);
+
+ method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
+ if (method === 'patch' && !options.attrs) options.attrs = attrs;
+ xhr = this.sync(method, this, options);
+
+ // Restore attributes.
+ if (attrs && options.wait) this.attributes = attributes;
+
+ return xhr;
+ },
+
+ // Destroy this model on the server if it was already persisted.
+ // Optimistically removes the model from its collection, if it has one.
+ // If `wait: true` is passed, waits for the server to respond before removal.
+ destroy: function(options) {
+ options = options ? _.clone(options) : {};
+ var model = this;
+ var success = options.success;
+
+ var destroy = function() {
+ model.stopListening();
+ model.trigger('destroy', model, model.collection, options);
+ };
+
+ options.success = function(resp) {
+ if (options.wait || model.isNew()) destroy();
+ if (success) success(model, resp, options);
+ if (!model.isNew()) model.trigger('sync', model, resp, options);
+ };
+
+ if (this.isNew()) {
+ options.success();
+ return false;
+ }
+ wrapError(this, options);
+
+ var xhr = this.sync('delete', this, options);
+ if (!options.wait) destroy();
+ return xhr;
+ },
+
+ // Default URL for the model's representation on the server -- if you're
+ // using Backbone's restful methods, override this to change the endpoint
+ // that will be called.
+ url: function() {
+ var base =
+ _.result(this, 'urlRoot') ||
+ _.result(this.collection, 'url') ||
+ urlError();
+ if (this.isNew()) return base;
+ return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id);
+ },
+
+ // **parse** converts a response into the hash of attributes to be `set` on
+ // the model. The default implementation is just to pass the response along.
+ parse: function(resp, options) {
+ return resp;
+ },
+
+ // Create a new model with identical attributes to this one.
+ clone: function() {
+ return new this.constructor(this.attributes);
+ },
+
+ // A model is new if it has never been saved to the server, and lacks an id.
+ isNew: function() {
+ return !this.has(this.idAttribute);
+ },
+
+ // Check if the model is currently in a valid state.
+ isValid: function(options) {
+ return this._validate({}, _.extend(options || {}, { validate: true }));
+ },
+
+ // Run validation against the next complete set of model attributes,
+ // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
+ _validate: function(attrs, options) {
+ if (!options.validate || !this.validate) return true;
+ attrs = _.extend({}, this.attributes, attrs);
+ var error = this.validationError = this.validate(attrs, options) || null;
+ if (!error) return true;
+ this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
+ return false;
+ }
+
+});
+
+// Underscore methods that we want to implement on the Model.
+var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit', 'chain', 'isEmpty'];
+
+// Mix in each Underscore method as a proxy to `Model#attributes`.
+_.each(modelMethods, function(method) {
+ if (!_[method]) return;
+ Model.prototype[method] = function() {
+ var args = slice.call(arguments);
+ args.unshift(this.attributes);
+ return _[method].apply(_, args);
+ };
+});
+
+// setup inheritance
+Model.extend = extend;
+module.exports = Model;
+
+},{"backbone-events-standalone":8,"backbone-extend-standalone":9,"underscore":59}],7:[function(require,module,exports){
+/**
+ * Standalone extraction of Backbone.Events, no external dependency required.
+ * Degrades nicely when Backone/underscore are already available in the current
+ * global context.
+ *
+ * Note that docs suggest to use underscore's `_.extend()` method to add Events
+ * support to some given object. A `mixin()` method has been added to the Events
+ * prototype to avoid using underscore for that sole purpose:
+ *
+ * var myEventEmitter = BackboneEvents.mixin({});
+ *
+ * Or for a function constructor:
+ *
+ * function MyConstructor(){}
+ * MyConstructor.prototype.foo = function(){}
+ * BackboneEvents.mixin(MyConstructor.prototype);
+ *
+ * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
+ * (c) 2013 Nicolas Perriault
+ */
+/* global exports:true, define, module */
+(function() {
+ var root = this,
+ breaker = {},
+ nativeForEach = Array.prototype.forEach,
+ hasOwnProperty = Object.prototype.hasOwnProperty,
+ slice = Array.prototype.slice,
+ idCounter = 0;
+
+ // Returns a partial implementation matching the minimal API subset required
+ // by Backbone.Events
+ function miniscore() {
+ return {
+ keys: Object.keys || function (obj) {
+ if (typeof obj !== "object" && typeof obj !== "function" || obj === null) {
+ throw new TypeError("keys() called on a non-object");
+ }
+ var key, keys = [];
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ keys[keys.length] = key;
+ }
+ }
+ return keys;
+ },
+
+ uniqueId: function(prefix) {
+ var id = ++idCounter + '';
+ return prefix ? prefix + id : id;
+ },
+
+ has: function(obj, key) {
+ return hasOwnProperty.call(obj, key);
+ },
+
+ each: function(obj, iterator, context) {
+ if (obj == null) return;
+ if (nativeForEach && obj.forEach === nativeForEach) {
+ obj.forEach(iterator, context);
+ } else if (obj.length === +obj.length) {
+ for (var i = 0, l = obj.length; i < l; i++) {
+ if (iterator.call(context, obj[i], i, obj) === breaker) return;
+ }
+ } else {
+ for (var key in obj) {
+ if (this.has(obj, key)) {
+ if (iterator.call(context, obj[key], key, obj) === breaker) return;
+ }
+ }
+ }
+ },
+
+ once: function(func) {
+ var ran = false, memo;
+ return function() {
+ if (ran) return memo;
+ ran = true;
+ memo = func.apply(this, arguments);
+ func = null;
+ return memo;
+ };
+ }
+ };
+ }
+
+ var _ = miniscore(), Events;
+
+ // Backbone.Events
+ // ---------------
+
+ // A module that can be mixed in to *any object* in order to provide it with
+ // custom events. You may bind with `on` or remove with `off` callback
+ // functions to an event; `trigger`-ing an event fires all callbacks in
+ // succession.
+ //
+ // var object = {};
+ // _.extend(object, Backbone.Events);
+ // object.on('expand', function(){ alert('expanded'); });
+ // object.trigger('expand');
+ //
+ Events = {
+
+ // Bind an event to a `callback` function. Passing `"all"` will bind
+ // the callback to all events fired.
+ on: function(name, callback, context) {
+ if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
+ this._events || (this._events = {});
+ var events = this._events[name] || (this._events[name] = []);
+ events.push({callback: callback, context: context, ctx: context || this});
+ return this;
+ },
+
+ // Bind an event to only be triggered a single time. After the first time
+ // the callback is invoked, it will be removed.
+ once: function(name, callback, context) {
+ if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
+ var self = this;
+ var once = _.once(function() {
+ self.off(name, once);
+ callback.apply(this, arguments);
+ });
+ once._callback = callback;
+ return this.on(name, once, context);
+ },
+
+ // Remove one or many callbacks. If `context` is null, removes all
+ // callbacks with that function. If `callback` is null, removes all
+ // callbacks for the event. If `name` is null, removes all bound
+ // callbacks for all events.
+ off: function(name, callback, context) {
+ var retain, ev, events, names, i, l, j, k;
+ if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
+ if (!name && !callback && !context) {
+ this._events = {};
+ return this;
+ }
+
+ names = name ? [name] : _.keys(this._events);
+ for (i = 0, l = names.length; i < l; i++) {
+ name = names[i];
+ if (events = this._events[name]) {
+ this._events[name] = retain = [];
+ if (callback || context) {
+ for (j = 0, k = events.length; j < k; j++) {
+ ev = events[j];
+ if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
+ (context && context !== ev.context)) {
+ retain.push(ev);
+ }
+ }
+ }
+ if (!retain.length) delete this._events[name];
+ }
+ }
+
+ return this;
+ },
+
+ // Trigger one or many events, firing all bound callbacks. Callbacks are
+ // passed the same arguments as `trigger` is, apart from the event name
+ // (unless you're listening on `"all"`, which will cause your callback to
+ // receive the true name of the event as the first argument).
+ trigger: function(name) {
+ if (!this._events) return this;
+ var args = slice.call(arguments, 1);
+ if (!eventsApi(this, 'trigger', name, args)) return this;
+ var events = this._events[name];
+ var allEvents = this._events.all;
+ if (events) triggerEvents(events, args);
+ if (allEvents) triggerEvents(allEvents, arguments);
+ return this;
+ },
+
+ // Tell this object to stop listening to either specific events ... or
+ // to every object it's currently listening to.
+ stopListening: function(obj, name, callback) {
+ var listeners = this._listeners;
+ if (!listeners) return this;
+ var deleteListener = !name && !callback;
+ if (typeof name === 'object') callback = this;
+ if (obj) (listeners = {})[obj._listenerId] = obj;
+ for (var id in listeners) {
+ listeners[id].off(name, callback, this);
+ if (deleteListener) delete this._listeners[id];
+ }
+ return this;
+ }
+
+ };
+
+ // Regular expression used to split event strings.
+ var eventSplitter = /\s+/;
+
+ // Implement fancy features of the Events API such as multiple event
+ // names `"change blur"` and jQuery-style event maps `{change: action}`
+ // in terms of the existing API.
+ var eventsApi = function(obj, action, name, rest) {
+ if (!name) return true;
+
+ // Handle event maps.
+ if (typeof name === 'object') {
+ for (var key in name) {
+ obj[action].apply(obj, [key, name[key]].concat(rest));
+ }
+ return false;
+ }
+
+ // Handle space separated event names.
+ if (eventSplitter.test(name)) {
+ var names = name.split(eventSplitter);
+ for (var i = 0, l = names.length; i < l; i++) {
+ obj[action].apply(obj, [names[i]].concat(rest));
+ }
+ return false;
+ }
+
+ return true;
+ };
+
+ // A difficult-to-believe, but optimized internal dispatch function for
+ // triggering events. Tries to keep the usual cases speedy (most internal
+ // Backbone events have 3 arguments).
+ var triggerEvents = function(events, args) {
+ var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
+ switch (args.length) {
+ case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
+ case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
+ case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
+ case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
+ default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
+ }
+ };
+
+ var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
+
+ // Inversion-of-control versions of `on` and `once`. Tell *this* object to
+ // listen to an event in another object ... keeping track of what it's
+ // listening to.
+ _.each(listenMethods, function(implementation, method) {
+ Events[method] = function(obj, name, callback) {
+ var listeners = this._listeners || (this._listeners = {});
+ var id = obj._listenerId || (obj._listenerId = _.uniqueId('l'));
+ listeners[id] = obj;
+ if (typeof name === 'object') callback = this;
+ obj[implementation](name, callback, this);
+ return this;
+ };
+ });
+
+ // Aliases for backwards compatibility.
+ Events.bind = Events.on;
+ Events.unbind = Events.off;
+
+ // Mixin utility
+ Events.mixin = function(proto) {
+ var exports = ['on', 'once', 'off', 'trigger', 'stopListening', 'listenTo',
+ 'listenToOnce', 'bind', 'unbind'];
+ _.each(exports, function(name) {
+ proto[name] = this[name];
+ }, this);
+ return proto;
+ };
+
+ // Export Events as BackboneEvents depending on current context
+ if (typeof define === "function") {
+ define(function() {
+ return Events;
+ });
+ } else if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = Events;
+ }
+ exports.BackboneEvents = Events;
+ } else {
+ root.BackboneEvents = Events;
+ }
+})(this);
+
+},{}],8:[function(require,module,exports){
+module.exports = require('./backbone-events-standalone');
+
+},{"./backbone-events-standalone":7}],9:[function(require,module,exports){
+(function (definition) {
+ if (typeof exports === "object") {
+ module.exports = definition();
+ }
+ else if (typeof define === 'function' && define.amd) {
+ define(definition);
+ }
+ else {
+ window.BackboneExtend = definition();
+ }
+})(function () {
+ "use strict";
+
+ // mini-underscore
+ var _ = {
+ has: function (obj, key) {
+ return Object.prototype.hasOwnProperty.call(obj, key);
+ },
+
+ extend: function(obj) {
+ for (var i=1; i<arguments.length; ++i) {
+ var source = arguments[i];
+ if (source) {
+ for (var prop in source) {
+ obj[prop] = source[prop];
+ }
+ }
+ }
+ return obj;
+ }
+ };
+
+ /// Following code is pasted from Backbone.js ///
+
+ // Helper function to correctly set up the prototype chain, for subclasses.
+ // Similar to `goog.inherits`, but uses a hash of prototype properties and
+ // class properties to be extended.
+ var extend = function(protoProps, staticProps) {
+ var parent = this;
+ var child;
+
+ // The constructor function for the new subclass is either defined by you
+ // (the "constructor" property in your `extend` definition), or defaulted
+ // by us to simply call the parent's constructor.
+ if (protoProps && _.has(protoProps, 'constructor')) {
+ child = protoProps.constructor;
+ } else {
+ child = function(){ return parent.apply(this, arguments); };
+ }
+
+ // Add static properties to the constructor function, if supplied.
+ _.extend(child, parent, staticProps);
+
+ // Set the prototype chain to inherit from `parent`, without calling
+ // `parent`'s constructor function.
+ var Surrogate = function(){ this.constructor = child; };
+ Surrogate.prototype = parent.prototype;
+ child.prototype = new Surrogate();
+
+ // Add prototype properties (instance properties) to the subclass,
+ // if supplied.
+ if (protoProps) _.extend(child.prototype, protoProps);
+
+ // Set a convenience property in case the parent's prototype is needed
+ // later.
+ child.__super__ = parent.prototype;
+
+ return child;
+ };
+
+ // Expose the extend function
+ return extend;
+});
+
+},{}],10:[function(require,module,exports){
+// this is the extracted view model from backbone
+// note that we inject jbone as jquery replacment
+// (and underscore directly)
+//
+// Views are almost more convention than they are actual code.
+// MVC pattern
+// Backbone.View
+// -------------
+
+var _ = require("underscore");
+var Events = require("backbone-events-standalone");
+var extend = require("backbone-extend-standalone");
+var $ = require('jbone');
+
+// Backbone Views are almost more convention than they are actual code. A View
+// is simply a JavaScript object that represents a logical chunk of UI in the
+// DOM. This might be a single item, an entire list, a sidebar or panel, or
+// even the surrounding frame which wraps your whole app. Defining a chunk of
+// UI as a **View** allows you to define your DOM events declaratively, without
+// having to worry about render order ... and makes it easy for the view to
+// react to specific changes in the state of your models.
+
+// Creating a Backbone.View creates its initial element outside of the DOM,
+// if an existing element is not provided...
+var View = function(options) {
+ this.cid = _.uniqueId('view');
+ options || (options = {});
+ _.extend(this, _.pick(options, viewOptions));
+ this._ensureElement();
+ this.initialize.apply(this, arguments);
+};
+
+// Cached regex to split keys for `delegate`.
+var delegateEventSplitter = /^(\S+)\s*(.*)$/;
+
+// List of view options to be merged as properties.
+var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
+
+// Set up all inheritable **Backbone.View** properties and methods.
+_.extend(View.prototype, Events, {
+
+ // The default `tagName` of a View's element is `"div"`.
+ tagName: 'div',
+
+ // jQuery delegate for element lookup, scoped to DOM elements within the
+ // current view. This should be preferred to global lookups where possible.
+ $: function(selector) {
+ return this.$el.find(selector);
+ },
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // **render** is the core function that your view should override, in order
+ // to populate its element (`this.el`), with the appropriate HTML. The
+ // convention is for **render** to always return `this`.
+ render: function() {
+ return this;
+ },
+
+ // Remove this view by taking the element out of the DOM, and removing any
+ // applicable Backbone.Events listeners.
+ remove: function() {
+ this._removeElement();
+ this.stopListening();
+ return this;
+ },
+
+ // Remove this view's element from the document and all event listeners
+ // attached to it. Exposed for subclasses using an alternative DOM
+ // manipulation API.
+ _removeElement: function() {
+ this.$el.remove();
+ },
+
+ // Change the view's element (`this.el` property) and re-delegate the
+ // view's events on the new element.
+ setElement: function(element) {
+ this.undelegateEvents();
+ this._setElement(element);
+ this.delegateEvents();
+ return this;
+ },
+
+ // Creates the `this.el` and `this.$el` references for this view using the
+ // given `el`. `el` can be a CSS selector or an HTML string, a jQuery
+ // context or an element. Subclasses can override this to utilize an
+ // alternative DOM manipulation API and are only required to set the
+ // `this.el` property.
+ _setElement: function(el) {
+ this.$el = el instanceof $ ? el : $(el);
+ this.el = this.$el[0];
+ },
+
+ // Set callbacks, where `this.events` is a hash of
+ //
+ // *{"event selector": "callback"}*
+ //
+ // {
+ // 'mousedown .title': 'edit',
+ // 'click .button': 'save',
+ // 'click .open': function(e) { ... }
+ // }
+ //
+ // pairs. Callbacks will be bound to the view, with `this` set properly.
+ // Uses event delegation for efficiency.
+ // Omitting the selector binds the event to `this.el`.
+ delegateEvents: function(events) {
+ if (!(events || (events = _.result(this, 'events')))) return this;
+ this.undelegateEvents();
+ for (var key in events) {
+ var method = events[key];
+ if (!_.isFunction(method)) method = this[events[key]];
+ if (!method) continue;
+ var match = key.match(delegateEventSplitter);
+ this.delegate(match[1], match[2], _.bind(method, this));
+ }
+ return this;
+ },
+
+ // Add a single event listener to the view's element (or a child element
+ // using `selector`). This only works for delegate-able events: not `focus`,
+ // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.
+ delegate: function(eventName, selector, listener) {
+ this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
+ },
+
+ // Clears all callbacks previously bound to the view by `delegateEvents`.
+ // You usually don't need to use this, but may wish to if you have multiple
+ // Backbone views attached to the same DOM element.
+ undelegateEvents: function() {
+ if (this.$el) this.$el.off('.delegateEvents' + this.cid);
+ return this;
+ },
+
+ // A finer-grained `undelegateEvents` for removing a single delegated event.
+ // `selector` and `listener` are both optional.
+ undelegate: function(eventName, selector, listener) {
+ this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
+ },
+
+ // Produces a DOM element to be assigned to your view. Exposed for
+ // subclasses using an alternative DOM manipulation API.
+ _createElement: function(tagName) {
+ return document.createElement(tagName);
+ },
+
+ // Ensure that the View has a DOM element to render into.
+ // If `this.el` is a string, pass it through `$()`, take the first
+ // matching element, and re-assign it to `el`. Otherwise, create
+ // an element from the `id`, `className` and `tagName` properties.
+ _ensureElement: function() {
+ if (!this.el) {
+ var attrs = _.extend({}, _.result(this, 'attributes'));
+ if (this.id) attrs.id = _.result(this, 'id');
+ if (this.className) attrs['class'] = _.result(this, 'className');
+ this.setElement(this._createElement(_.result(this, 'tagName')));
+ this._setAttributes(attrs);
+ } else {
+ this.setElement(_.result(this, 'el'));
+ }
+ },
+
+ // Set attributes from a hash on this view's element. Exposed for
+ // subclasses using an alternative DOM manipulation API.
+ _setAttributes: function(attributes) {
+ this.$el.attr(attributes);
+ }
+
+});
+
+// setup inheritance
+View.extend = extend;
+module.exports = View;
+
+},{"backbone-events-standalone":12,"backbone-extend-standalone":13,"jbone":50,"underscore":59}],11:[function(require,module,exports){
+module.exports=require(7)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/backbone-thin/node_modules/backbone-events-standalone/backbone-events-standalone.js":7}],12:[function(require,module,exports){
+module.exports=require(8)
+},{"./backbone-events-standalone":11,"/home/travis/build/greenify/biojs-vis-msa/node_modules/backbone-thin/node_modules/backbone-events-standalone/index.js":8}],13:[function(require,module,exports){
+module.exports=require(9)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/backbone-thin/node_modules/backbone-extend-standalone/backbone-extend-standalone.js":9}],14:[function(require,module,exports){
+var events = require("backbone-events-standalone");
+
+events.onAll = function(callback,context){
+ this.on("all", callback,context);
+ return this;
+};
+
+// Mixin utility
+events.oldMixin = events.mixin;
+events.mixin = function(proto) {
+ events.oldMixin(proto);
+ // add custom onAll
+ var exports = ['onAll'];
+ for(var i=0; i < exports.length;i++){
+ var name = exports[i];
+ proto[name] = this[name];
+ }
+ return proto;
+};
+
+module.exports = events;
+
+},{"backbone-events-standalone":16}],15:[function(require,module,exports){
+module.exports=require(7)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/backbone-thin/node_modules/backbone-events-standalone/backbone-events-standalone.js":7}],16:[function(require,module,exports){
+module.exports=require(8)
+},{"./backbone-events-standalone":15,"/home/travis/build/greenify/biojs-vis-msa/node_modules/backbone-thin/node_modules/backbone-events-standalone/index.js":8}],17:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var GenericReader, xhr;
+
+xhr = require('nets');
+
+module.exports = GenericReader = (function() {
+ function GenericReader() {}
+
+ GenericReader.read = function(url, callback) {
+ var onret;
+ onret = (function(_this) {
+ return function(err, response, text) {
+ return _this._onRetrieval(text, callback);
+ };
+ })(this);
+ return xhr(url, onret);
+ };
+
+ GenericReader._onRetrieval = function(text, callback) {
+ var rText;
+ rText = this.parse(text);
+ return callback(rText);
+ };
+
+ return GenericReader;
+
+})();
+
+},{"nets":undefined}],18:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var Seq;
+
+module.exports = Seq = (function() {
+ function Seq(seq, name, id) {
+ var meta;
+ this.seq = seq;
+ this.name = name;
+ this.id = id;
+ meta = {};
+ }
+
+ return Seq;
+
+})();
+
+},{}],19:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var strings;
+
+strings = {
+ contains: function(text, search) {
+ return ''.indexOf.call(text, search, 0) !== -1;
+ }
+};
+
+module.exports = strings;
+
+},{}],20:[function(require,module,exports){
+module.exports=require(17)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/biojs-io-clustal/lib/generic_reader.js":17,"nets":undefined}],21:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var Fasta, GenericReader, Seq, Str,
+ __hasProp = {}.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
+
+Str = require("./strings");
+
+GenericReader = require("./generic_reader");
+
+Seq = require("biojs-model").seq;
+
+module.exports = Fasta = (function(_super) {
+ __extends(Fasta, _super);
+
+ function Fasta() {
+ return Fasta.__super__.constructor.apply(this, arguments);
+ }
+
+ Fasta.parse = function(text) {
+ var currentSeq, database, databaseID, identifiers, k, label, line, seqs, _i, _len;
+ seqs = [];
+ if (Object.prototype.toString.call(text) !== '[object Array]') {
+ text = text.split("\n");
+ }
+ for (_i = 0, _len = text.length; _i < _len; _i++) {
+ line = text[_i];
+ if (line[0] === ">" || line[0] === ";") {
+ label = line.slice(1);
+ currentSeq = new Seq("", label, seqs.length);
+ seqs.push(currentSeq);
+ if (Str.contains("|", line)) {
+ identifiers = label.split("|");
+ k = 1;
+ while (k < identifiers.length) {
+ database = identifiers[k];
+ databaseID = identifiers[k + 1];
+ currentSeq.meta[database] = databaseID;
+ k += 2;
+ }
+ currentSeq.name = identifiers[identifiers.length - 1];
+ }
+ } else {
+ currentSeq.seq += line;
+ }
+ }
+ return seqs;
+ };
+
+ return Fasta;
+
+})(GenericReader);
+
+},{"./generic_reader":20,"./strings":22,"biojs-model":25}],22:[function(require,module,exports){
+module.exports=require(19)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/biojs-io-clustal/lib/strings.js":19}],23:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var Utils;
+
+Utils = {};
+
+Utils.splitNChars = function(txt, num) {
+ var i, result, _i, _ref;
+ result = [];
+ for (i = _i = 0, _ref = txt.length - 1; num > 0 ? _i <= _ref : _i >= _ref; i = _i += num) {
+ result.push(txt.substr(i, num));
+ }
+ return result;
+};
+
+module.exports = Utils;
+
+},{}],24:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var FastaExporter, Utils;
+
+Utils = require("./utils");
+
+module.exports = FastaExporter = (function() {
+ function FastaExporter() {}
+
+ FastaExporter["export"] = function(seqs, access) {
+ var seq, text, _i, _len;
+ text = "";
+ for (_i = 0, _len = seqs.length; _i < _len; _i++) {
+ seq = seqs[_i];
+ if (access != null) {
+ seq = access(seq);
+ }
+ text += ">" + seq.name + "\n";
+ text += (Utils.splitNChars(seq.seq, 80)).join("\n");
+ text += "\n";
+ }
+ return text;
+ };
+
+ return FastaExporter;
+
+})();
+
+},{"./utils":23}],25:[function(require,module,exports){
+module.exports.seq = require("./seq");
+
+},{"./seq":26}],26:[function(require,module,exports){
+module.exports = function(seq, name, id) {
+ this.seq = seq;
+ this.name = name;
+ this.id = id;
+ this.meta = {};
+};
+
+},{}],27:[function(require,module,exports){
+module.exports=require(25)
+},{"./seq":28,"/home/travis/build/greenify/biojs-vis-msa/node_modules/biojs-io-fasta/node_modules/biojs-model/src/index.js":25}],28:[function(require,module,exports){
+module.exports=require(26)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/biojs-io-fasta/node_modules/biojs-model/src/seq.js":26}],29:[function(require,module,exports){
+module.exports = require('./src/index.js')
+
+},{"./src/index.js":36}],30:[function(require,module,exports){
+module.exports = {
+ A: "#00a35c",
+ R: "#00fc03",
+ N: "#00eb14",
+ D: "#00eb14",
+ C: "#0000ff",
+ Q: "#00f10e",
+ E: "#00f10e",
+ G: "#009d62",
+ H: "#00d52a",
+ I: "#0054ab",
+ L: "#007b84",
+ K: "#00ff00",
+ M: "#009768",
+ F: "#008778",
+ P: "#00e01f",
+ S: "#00d52a",
+ T: "#00db24",
+ W: "#00a857",
+ Y: "#00e619",
+ V: "#005fa0",
+ B: "#00eb14",
+ X: "#00b649",
+ Z: "#00f10e"
+};
+
+},{}],31:[function(require,module,exports){
+module.exports = {
+ A: "#BBBBBB",
+ B: "grey",
+ C: "yellow",
+ D: "red",
+ E: "red",
+ F: "magenta",
+ G: "brown",
+ H: "#00FFFF",
+ I: "#BBBBBB",
+ J: "#fff",
+ K: "#00FFFF",
+ L: "#BBBBBB",
+ M: "#BBBBBB",
+ N: "green",
+ O: "#fff",
+ P: "brown",
+ Q: "green",
+ R: "#00FFFF",
+ S: "green",
+ T: "green",
+ U: "#fff",
+ V: "#BBBBBB",
+ W: "magenta",
+ X: "grey",
+ Y: "magenta",
+ Z: "grey",
+ Gap: "grey"
+};
+
+},{}],32:[function(require,module,exports){
+module.exports = {
+ A: "orange",
+ B: "#fff",
+ C: "green",
+ D: "red",
+ E: "red",
+ F: "blue",
+ G: "orange",
+ H: "red",
+ I: "green",
+ J: "#fff",
+ K: "red",
+ L: "green",
+ M: "green",
+ N: "#fff",
+ O: "#fff",
+ P: "orange",
+ Q: "#fff",
+ R: "red",
+ S: "orange",
+ T: "orange",
+ U: "#fff",
+ V: "green",
+ W: "blue",
+ X: "#fff",
+ Y: "blue",
+ Z: "#fff",
+ Gap: "#fff"
+};
+
+},{}],33:[function(require,module,exports){
+module.exports = {
+ A: "#80a0f0",
+ R: "#f01505",
+ N: "#00ff00",
+ D: "#c048c0",
+ C: "#f08080",
+ Q: "#00ff00",
+ E: "#c048c0",
+ G: "#f09048",
+ H: "#15a4a4",
+ I: "#80a0f0",
+ L: "#80a0f0",
+ K: "#f01505",
+ M: "#80a0f0",
+ F: "#80a0f0",
+ P: "#ffff00",
+ S: "#00ff00",
+ T: "#00ff00",
+ W: "#80a0f0",
+ Y: "#15a4a4",
+ V: "#80a0f0",
+ B: "#fff",
+ X: "#fff",
+ Z: "#fff"
+};
+
+},{}],34:[function(require,module,exports){
+module.exports = {
+ A: "#e718e7",
+ R: "#6f906f",
+ N: "#1be41b",
+ D: "#778877",
+ C: "#23dc23",
+ Q: "#926d92",
+ E: "#ff00ff",
+ G: "#00ff00",
+ H: "#758a75",
+ I: "#8a758a",
+ L: "#ae51ae",
+ K: "#a05fa0",
+ M: "#ef10ef",
+ F: "#986798",
+ P: "#00ff00",
+ S: "#36c936",
+ T: "#47b847",
+ W: "#8a758a",
+ Y: "#21de21",
+ V: "#857a85",
+ B: "#49b649",
+ X: "#758a75",
+ Z: "#c936c9"
+};
+
+},{}],35:[function(require,module,exports){
+module.exports = {
+ A: "#ad0052",
+ B: "#0c00f3",
+ C: "#c2003d",
+ D: "#0c00f3",
+ E: "#0c00f3",
+ F: "#cb0034",
+ G: "#6a0095",
+ H: "#1500ea",
+ I: "#ff0000",
+ J: "#fff",
+ K: "#0000ff",
+ L: "#ea0015",
+ M: "#b0004f",
+ N: "#0c00f3",
+ O: "#fff",
+ P: "#4600b9",
+ Q: "#0c00f3",
+ R: "#0000ff",
+ S: "#5e00a1",
+ T: "#61009e",
+ U: "#fff",
+ V: "#f60009",
+ W: "#5b00a4",
+ X: "#680097",
+ Y: "#4f00b0",
+ Z: "#0c00f3"
+};
+
+},{}],36:[function(require,module,exports){
+module.exports.selector = require("./selector");
+
+// basics
+module.exports.taylor = require("./taylor");
+module.exports.zappo= require("./zappo");
+module.exports.hydro= require("./hydrophobicity");
+
+module.exports.clustal = require("./clustal");
+module.exports.clustal2 = require("./clustal2");
+
+module.exports.curied = require("./buried");
+module.exports.cinema = require("./cinema");
+module.exports.nucleotide = require("./nucleotide");
+module.exports.helix = require("./helix");
+module.exports.lesk = require("./lesk");
+module.exports.mae = require("./mae");
+module.exports.purine = require("./purine");
+module.exports.strand = require("./strand");
+module.exports.turn = require("./turn");
+
+},{"./buried":30,"./cinema":31,"./clustal":32,"./clustal2":33,"./helix":34,"./hydrophobicity":35,"./lesk":37,"./mae":38,"./nucleotide":39,"./purine":40,"./selector":41,"./strand":42,"./taylor":43,"./turn":44,"./zappo":45}],37:[function(require,module,exports){
+module.exports = {
+ A: " orange",
+ B: " #fff",
+ C: " green",
+ D: " red",
+ E: " red",
+ F: " green",
+ G: " orange",
+ H: " magenta",
+ I: " green",
+ J: " #fff",
+ K: " red",
+ L: " green",
+ M: " green",
+ N: " magenta",
+ O: " #fff",
+ P: " green",
+ Q: " magenta",
+ R: " red",
+ S: " orange",
+ T: " orange",
+ U: " #fff",
+ V: " green",
+ W: " green",
+ X: " #fff",
+ Y: " green",
+ Z: " #fff",
+ Gap: " #fff"
+};
+
+},{}],38:[function(require,module,exports){
+module.exports = {
+ A: " #77dd88",
+ B: " #fff",
+ C: " #99ee66",
+ D: " #55bb33",
+ E: " #55bb33",
+ F: " #9999ff",
+ G: " #77dd88",
+ H: " #5555ff",
+ I: " #66bbff",
+ J: " #fff",
+ K: " #ffcc77",
+ L: " #66bbff",
+ M: " #66bbff",
+ N: " #55bb33",
+ O: " #fff",
+ P: " #eeaaaa",
+ Q: " #55bb33",
+ R: " #ffcc77",
+ S: " #ff4455",
+ T: " #ff4455",
+ U: " #fff",
+ V: " #66bbff",
+ W: " #9999ff",
+ X: " #fff",
+ Y: " #9999ff",
+ Z: " #fff",
+ Gap: " #fff"
+};
+
+},{}],39:[function(require,module,exports){
+module.exports = {
+ A: " #64F73F",
+ C: " #FFB340",
+ G: " #EB413C",
+ T: " #3C88EE",
+ U: " #3C88EE"
+};
+
+},{}],40:[function(require,module,exports){
+module.exports = {
+ A: " #FF83FA",
+ C: " #40E0D0",
+ G: " #FF83FA",
+ R: " #FF83FA",
+ T: " #40E0D0",
+ U: " #40E0D0",
+ Y: " #40E0D0"
+};
+
+},{}],41:[function(require,module,exports){
+var Buried = require("./buried");
+var Cinema = require("./cinema");
+var Clustal = require("./clustal");
+var Clustal2 = require("./clustal2");
+var Helix = require("./helix");
+var Hydro = require("./hydrophobicity");
+var Lesk = require("./lesk");
+var Mae = require("./mae");
+var Nucleotide = require("./nucleotide");
+var Purine = require("./purine");
+var Strand = require("./strand");
+var Taylor = require("./taylor");
+var Turn = require("./turn");
+var Zappo = require("./zappo");
+
+module.exports = Colors = {
+ mapping: {
+ buried: Buried,
+ buried_index: Buried,
+ cinema: Cinema,
+ clustal2: Clustal2,
+ clustal: Clustal,
+ helix: Helix,
+ helix_propensity: Helix,
+ hydro: Hydro,
+ lesk: Lesk,
+ mae: Mae,
+ nucleotide: Nucleotide,
+ purine: Purine,
+ purine_pyrimidine: Purine,
+ strand: Strand,
+ strand_propensity: Strand,
+ taylor: Taylor,
+ turn: Turn,
+ turn_propensity: Turn,
+ zappo: Zappo,
+ },
+ getColor: function(scheme) {
+ var color = Colors.mapping[scheme];
+ if (color === undefined) {
+ color = {};
+ }
+ return color;
+ }
+};
+
+},{"./buried":30,"./cinema":31,"./clustal":32,"./clustal2":33,"./helix":34,"./hydrophobicity":35,"./lesk":37,"./mae":38,"./nucleotide":39,"./purine":40,"./strand":42,"./taylor":43,"./turn":44,"./zappo":45}],42:[function(require,module,exports){
+module.exports = {
+ A: "#5858a7",
+ R: "#6b6b94",
+ N: "#64649b",
+ D: "#2121de",
+ C: "#9d9d62",
+ Q: "#8c8c73",
+ E: "#0000ff",
+ G: "#4949b6",
+ H: "#60609f",
+ I: "#ecec13",
+ L: "#b2b24d",
+ K: "#4747b8",
+ M: "#82827d",
+ F: "#c2c23d",
+ P: "#2323dc",
+ S: "#4949b6",
+ T: "#9d9d62",
+ W: "#c0c03f",
+ Y: "#d3d32c",
+ V: "#ffff00",
+ B: "#4343bc",
+ X: "#797986",
+ Z: "#4747b8"
+};
+
+},{}],43:[function(require,module,exports){
+module.exports = {
+ A: "#ccff00",
+ R: "#0000ff",
+ N: "#cc00ff",
+ D: "#ff0000",
+ C: "#ffff00",
+ Q: "#ff00cc",
+ E: "#ff0066",
+ G: "#ff9900",
+ H: "#0066ff",
+ I: "#66ff00",
+ L: "#33ff00",
+ K: "#6600ff",
+ M: "#00ff00",
+ F: "#00ff66",
+ P: "#ffcc00",
+ S: "#ff3300",
+ T: "#ff6600",
+ W: "#00ccff",
+ Y: "#00ffcc",
+ V: "#99ff00",
+ B: "#fff",
+ X: "#fff",
+ Z: "#fff"
+};
+
+},{}],44:[function(require,module,exports){
+module.exports = {
+ A: "#2cd3d3",
+ R: "#708f8f",
+ N: "#ff0000",
+ D: "#e81717",
+ C: "#a85757",
+ Q: "#3fc0c0",
+ E: "#778888",
+ G: "#ff0000",
+ H: "#708f8f",
+ I: "#00ffff",
+ L: "#1ce3e3",
+ K: "#7e8181",
+ M: "#1ee1e1",
+ F: "#1ee1e1",
+ P: "#f60909",
+ S: "#e11e1e",
+ T: "#738c8c",
+ W: "#738c8c",
+ Y: "#9d6262",
+ V: "#07f8f8",
+ B: "#f30c0c",
+ X: "#7c8383",
+ Z: "#5ba4a4"
+};
+
+},{}],45:[function(require,module,exports){
+module.exports = {
+ A: "#ffafaf",
+ R: "#6464ff",
+ N: "#00ff00",
+ D: "#ff0000",
+ C: "#ffff00",
+ Q: "#00ff00",
+ E: "#ff0000",
+ G: "#ff00ff",
+ H: "#6464ff",
+ I: "#ffafaf",
+ L: "#ffafaf",
+ K: "#6464ff",
+ M: "#ffafaf",
+ F: "#ffc800",
+ P: "#ff00ff",
+ S: "#00ff00",
+ T: "#00ff00",
+ W: "#ffc800",
+ Y: "#ffc800",
+ V: "#ffafaf",
+ B: "#fff",
+ X: "#fff",
+ Z: "#fff"
+};
+
+},{}],46:[function(require,module,exports){
+/*
+ * JavaScript Canvas to Blob 2.0.5
+ * https://github.com/blueimp/JavaScript-Canvas-to-Blob
+ *
+ * Copyright 2012, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ *
+ * Based on stackoverflow user Stoive's code snippet:
+ * http://stackoverflow.com/q/4998908
+ */
+var CanvasPrototype = window.HTMLCanvasElement &&
+window.HTMLCanvasElement.prototype,
+ hasBlobConstructor = window.Blob && (function () {
+ try {
+ return Boolean(new Blob());
+ } catch (e) {
+ return false;
+ }
+ }()),
+ hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&
+ (function () {
+ try {
+ return new Blob([new Uint8Array(100)]).size === 100;
+ } catch (e) {
+ return false;
+ }
+ }()),
+ BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||
+ window.MozBlobBuilder || window.MSBlobBuilder,
+ dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&
+ window.ArrayBuffer && window.Uint8Array && function (dataURI) {
+ var byteString,
+ arrayBuffer,
+ intArray,
+ i,
+ mimeString,
+ bb;
+ if (dataURI.split(',')[0].indexOf('base64') >= 0) {
+ // Convert base64 to raw binary data held in a string:
+ byteString = atob(dataURI.split(',')[1]);
+ } else {
+ // Convert base64/URLEncoded data component to raw binary data:
+ byteString = decodeURIComponent(dataURI.split(',')[1]);
+ }
+ // Write the bytes of the string to an ArrayBuffer:
+ arrayBuffer = new ArrayBuffer(byteString.length);
+ intArray = new Uint8Array(arrayBuffer);
+ for (i = 0; i < byteString.length; i += 1) {
+ intArray[i] = byteString.charCodeAt(i);
+ }
+ // Separate out the mime component:
+ mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
+ // Write the ArrayBuffer (or ArrayBufferView) to a blob:
+ if (hasBlobConstructor) {
+ return new Blob(
+ [hasArrayBufferViewSupport ? intArray : arrayBuffer],
+ {type: mimeString}
+ );
+ }
+ bb = new BlobBuilder();
+ bb.append(arrayBuffer);
+ return bb.getBlob(mimeString);
+ };
+if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {
+ if (CanvasPrototype.mozGetAsFile) {
+ CanvasPrototype.toBlob = function (callback, type, quality) {
+ if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {
+ callback(dataURLtoBlob(this.toDataURL(type, quality)));
+ } else {
+ callback(this.mozGetAsFile('blob', type));
+ }
+ };
+ } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {
+ CanvasPrototype.toBlob = function (callback, type, quality) {
+ callback(dataURLtoBlob(this.toDataURL(type, quality)));
+ };
+ }
+}
+
+module.exports = dataURLtoBlob;
+
+},{}],47:[function(require,module,exports){
+/* FileSaver.js
+ * A saveAs() FileSaver implementation.
+ * 2014-05-27
+ *
+ * By Eli Grey, http://eligrey.com
+ * License: X11/MIT
+ * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
+ */
+
+/*global self */
+/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
+
+/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
+
+var saveAs = saveAs
+ // IE 10+ (native saveAs)
+ || (typeof navigator !== "undefined" &&
+ navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))
+ // Everyone else
+ || (function(view) {
+ "use strict";
+ // IE <10 is explicitly unsupported
+ if (typeof navigator !== "undefined" &&
+ /MSIE [1-9]\./.test(navigator.userAgent)) {
+ return;
+ }
+ var
+ doc = view.document
+ // only get URL when necessary in case Blob.js hasn't overridden it yet
+ , get_URL = function() {
+ return view.URL || view.webkitURL || view;
+ }
+ , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
+ , can_use_save_link = !view.externalHost && "download" in save_link
+ , click = function(node) {
+ var event = doc.createEvent("MouseEvents");
+ event.initMouseEvent(
+ "click", true, false, view, 0, 0, 0, 0, 0
+ , false, false, false, false, 0, null
+ );
+ node.dispatchEvent(event);
+ }
+ , webkit_req_fs = view.webkitRequestFileSystem
+ , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
+ , throw_outside = function(ex) {
+ (view.setImmediate || view.setTimeout)(function() {
+ throw ex;
+ }, 0);
+ }
+ , force_saveable_type = "application/octet-stream"
+ , fs_min_size = 0
+ , deletion_queue = []
+ , process_deletion_queue = function() {
+ var i = deletion_queue.length;
+ while (i--) {
+ var file = deletion_queue[i];
+ if (typeof file === "string") { // file is an object URL
+ get_URL().revokeObjectURL(file);
+ } else { // file is a File
+ file.remove();
+ }
+ }
+ deletion_queue.length = 0; // clear queue
+ }
+ , dispatch = function(filesaver, event_types, event) {
+ event_types = [].concat(event_types);
+ var i = event_types.length;
+ while (i--) {
+ var listener = filesaver["on" + event_types[i]];
+ if (typeof listener === "function") {
+ try {
+ listener.call(filesaver, event || filesaver);
+ } catch (ex) {
+ throw_outside(ex);
+ }
+ }
+ }
+ }
+ , FileSaver = function(blob, name) {
+ // First try a.download, then web filesystem, then object URLs
+ var
+ filesaver = this
+ , type = blob.type
+ , blob_changed = false
+ , object_url
+ , target_view
+ , get_object_url = function() {
+ var object_url = get_URL().createObjectURL(blob);
+ deletion_queue.push(object_url);
+ return object_url;
+ }
+ , dispatch_all = function() {
+ dispatch(filesaver, "writestart progress write writeend".split(" "));
+ }
+ // on any filesys errors revert to saving with object URLs
+ , fs_error = function() {
+ // don't create more object URLs than needed
+ if (blob_changed || !object_url) {
+ object_url = get_object_url(blob);
+ }
+ if (target_view) {
+ target_view.location.href = object_url;
+ } else {
+ window.open(object_url, "_blank");
+ }
+ filesaver.readyState = filesaver.DONE;
+ dispatch_all();
+ }
+ , abortable = function(func) {
+ return function() {
+ if (filesaver.readyState !== filesaver.DONE) {
+ return func.apply(this, arguments);
+ }
+ };
+ }
+ , create_if_not_found = {create: true, exclusive: false}
+ , slice
+ ;
+ filesaver.readyState = filesaver.INIT;
+ if (!name) {
+ name = "download";
+ }
+ if (can_use_save_link) {
+ object_url = get_object_url(blob);
+ save_link.href = object_url;
+ save_link.download = name;
+ click(save_link);
+ filesaver.readyState = filesaver.DONE;
+ dispatch_all();
+ return;
+ }
+ // Object and web filesystem URLs have a problem saving in Google Chrome when
+ // viewed in a tab, so I force save with application/octet-stream
+ // http://code.google.com/p/chromium/issues/detail?id=91158
+ if (view.chrome && type && type !== force_saveable_type) {
+ slice = blob.slice || blob.webkitSlice;
+ blob = slice.call(blob, 0, blob.size, force_saveable_type);
+ blob_changed = true;
+ }
+ // Since I can't be sure that the guessed media type will trigger a download
+ // in WebKit, I append .download to the filename.
+ // https://bugs.webkit.org/show_bug.cgi?id=65440
+ if (webkit_req_fs && name !== "download") {
+ name += ".download";
+ }
+ if (type === force_saveable_type || webkit_req_fs) {
+ target_view = view;
+ }
+ if (!req_fs) {
+ fs_error();
+ return;
+ }
+ fs_min_size += blob.size;
+ req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
+ fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
+ var save = function() {
+ dir.getFile(name, create_if_not_found, abortable(function(file) {
+ file.createWriter(abortable(function(writer) {
+ writer.onwriteend = function(event) {
+ target_view.location.href = file.toURL();
+ deletion_queue.push(file);
+ filesaver.readyState = filesaver.DONE;
+ dispatch(filesaver, "writeend", event);
+ };
+ writer.onerror = function() {
+ var error = writer.error;
+ if (error.code !== error.ABORT_ERR) {
+ fs_error();
+ }
+ };
+ "writestart progress write abort".split(" ").forEach(function(event) {
+ writer["on" + event] = filesaver["on" + event];
+ });
+ writer.write(blob);
+ filesaver.abort = function() {
+ writer.abort();
+ filesaver.readyState = filesaver.DONE;
+ };
+ filesaver.readyState = filesaver.WRITING;
+ }), fs_error);
+ }), fs_error);
+ };
+ dir.getFile(name, {create: false}, abortable(function(file) {
+ // delete file if it already exists
+ file.remove();
+ save();
+ }), abortable(function(ex) {
+ if (ex.code === ex.NOT_FOUND_ERR) {
+ save();
+ } else {
+ fs_error();
+ }
+ }));
+ }), fs_error);
+ }), fs_error);
+ }
+ , FS_proto = FileSaver.prototype
+ , saveAs = function(blob, name) {
+ return new FileSaver(blob, name);
+ }
+ ;
+ FS_proto.abort = function() {
+ var filesaver = this;
+ filesaver.readyState = filesaver.DONE;
+ dispatch(filesaver, "abort");
+ };
+ FS_proto.readyState = FS_proto.INIT = 0;
+ FS_proto.WRITING = 1;
+ FS_proto.DONE = 2;
+
+ FS_proto.error =
+ FS_proto.onwritestart =
+ FS_proto.onprogress =
+ FS_proto.onwrite =
+ FS_proto.onabort =
+ FS_proto.onerror =
+ FS_proto.onwriteend =
+ null;
+
+ view.addEventListener("unload", process_deletion_queue, false);
+ saveAs.unload = function() {
+ process_deletion_queue();
+ view.removeEventListener("unload", process_deletion_queue, false);
+ };
+ return saveAs;
+}(
+ typeof self !== "undefined" && self
+ || typeof window !== "undefined" && window
+ || this.content
+));
+// `self` is undefined in Firefox for Android content script context
+// while `this` is nsIContentFrameMessageManager
+// with an attribute `content` that corresponds to the window
+
+amdDefine = window.define;
+if( typeof amdDefine === "undefined" && (typeof window.almond !== "undefined"
+ && "define" in window.almond )){
+ amdDefine = window.almond.define;
+}
+
+if (typeof module !== "undefined" && module !== null) {
+ module.exports = saveAs;
+} else if ((typeof amdDefine !== "undefined" && amdDefine !== null) && (amdDefine.amd != null)) {
+ amdDefine("saveAs",[], function() {
+ return saveAs;
+ });
+}
+
+},{}],48:[function(require,module,exports){
+module.exports = function (css, customDocument) {
+ var doc = customDocument || document;
+ if (doc.createStyleSheet) {
+ var sheet = doc.createStyleSheet()
+ sheet.cssText = css;
+ return sheet.ownerNode;
+ } else {
+ var head = doc.getElementsByTagName('head')[0],
+ style = doc.createElement('style');
+
+ style.type = 'text/css';
+
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.appendChild(doc.createTextNode(css));
+ }
+
+ head.appendChild(style);
+ return style;
+ }
+};
+
+module.exports.byUrl = function(url) {
+ if (document.createStyleSheet) {
+ return document.createStyleSheet(url).ownerNode;
+ } else {
+ var head = document.getElementsByTagName('head')[0],
+ link = document.createElement('link');
+
+ link.rel = 'stylesheet';
+ link.href = url;
+
+ head.appendChild(link);
+ return link;
+ }
+};
+
+},{}],49:[function(require,module,exports){
+var Utils = {};
+
+
+/*
+Remove an element and provide a function that inserts it into its original position
+https://developers.google.com/speed/articles/javascript-dom
+@param element {Element} The element to be temporarily removed
+@return {Function} A function that inserts the element into its original position
+ */
+
+Utils.removeToInsertLater = function(element) {
+ var nextSibling, parentNode;
+ parentNode = element.parentNode;
+ nextSibling = element.nextSibling;
+ parentNode.removeChild(element);
+ return function() {
+ if (nextSibling) {
+ parentNode.insertBefore(element, nextSibling);
+ } else {
+ parentNode.appendChild(element);
+ }
+ };
+};
+
+
+/*
+fastest possible way to destroy all sub nodes (aka childs)
+http://jsperf.com/innerhtml-vs-removechild/15
+@param element {Element} The element for which all childs should be removed
+ */
+
+Utils.removeAllChilds = function(element) {
+ var count;
+ count = 0;
+ while (element.firstChild) {
+ count++;
+ element.removeChild(element.firstChild);
+ }
+};
+
+module.exports = Utils;
+
+},{}],50:[function(require,module,exports){
+/*!
+ * jBone v1.0.19 - 2014-10-12 - Library for DOM manipulation
+ *
+ * https://github.com/kupriyanenko/jbone
+ *
+ * Copyright 2014 Alexey Kupriyanenko
+ * Released under the MIT license.
+ */
+
+(function (win) {
+
+var
+// cache previous versions
+_$ = win.$,
+_jBone = win.jBone,
+
+// Quick match a standalone tag
+rquickSingleTag = /^<(\w+)\s*\/?>$/,
+
+// A simple way to check for HTML strings
+// Prioritize #id over <tag> to avoid XSS via location.hash
+rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+// Alias for function
+slice = [].slice,
+splice = [].splice,
+keys = Object.keys,
+
+// Alias for global variables
+doc = document,
+
+isString = function(el) {
+ return typeof el === "string";
+},
+isObject = function(el) {
+ return el instanceof Object;
+},
+isFunction = function(el) {
+ var getType = {};
+ return el && getType.toString.call(el) === "[object Function]";
+},
+isArray = function(el) {
+ return Array.isArray(el);
+},
+jBone = function(element, data) {
+ return new fn.init(element, data);
+},
+fn;
+
+// set previous values and return the instance upon calling the no-conflict mode
+jBone.noConflict = function() {
+ win.$ = _$;
+ win.jBone = _jBone;
+
+ return jBone;
+};
+
+fn = jBone.fn = jBone.prototype = {
+ init: function(element, data) {
+ var elements, tag, wraper, fragment;
+
+ if (!element) {
+ return this;
+ }
+ if (isString(element)) {
+ // Create single DOM element
+ if (tag = rquickSingleTag.exec(element)) {
+ this[0] = doc.createElement(tag[1]);
+ this.length = 1;
+
+ if (isObject(data)) {
+ this.attr(data);
+ }
+
+ return this;
+ }
+ // Create DOM collection
+ if ((tag = rquickExpr.exec(element)) && tag[1]) {
+ fragment = doc.createDocumentFragment();
+ wraper = doc.createElement("div");
+ wraper.innerHTML = element;
+ while (wraper.lastChild) {
+ fragment.appendChild(wraper.firstChild);
+ }
+ elements = slice.call(fragment.childNodes);
+
+ return jBone.merge(this, elements);
+ }
+ // Find DOM elements with querySelectorAll
+ if (jBone.isElement(data)) {
+ return jBone(data).find(element);
+ }
+
+ try {
+ elements = doc.querySelectorAll(element);
+
+ return jBone.merge(this, elements);
+ } catch (e) {
+ return this;
+ }
+ }
+ // Wrap DOMElement
+ if (element.nodeType) {
+ this[0] = element;
+ this.length = 1;
+
+ return this;
+ }
+ // Run function
+ if (isFunction(element)) {
+ return element();
+ }
+ // Return jBone element as is
+ if (element instanceof jBone) {
+ return element;
+ }
+
+ // Return element wrapped by jBone
+ return jBone.makeArray(element, this);
+ },
+
+ pop: [].pop,
+ push: [].push,
+ reverse: [].reverse,
+ shift: [].shift,
+ sort: [].sort,
+ splice: [].splice,
+ slice: [].slice,
+ indexOf: [].indexOf,
+ forEach: [].forEach,
+ unshift: [].unshift,
+ concat: [].concat,
+ join: [].join,
+ every: [].every,
+ some: [].some,
+ filter: [].filter,
+ map: [].map,
+ reduce: [].reduce,
+ reduceRight: [].reduceRight,
+ length: 0
+};
+
+fn.constructor = jBone;
+
+fn.init.prototype = fn;
+
+jBone.setId = function(el) {
+ var jid = el.jid;
+
+ if (el === win) {
+ jid = "window";
+ } else if (el.jid === undefined) {
+ el.jid = jid = ++jBone._cache.jid;
+ }
+
+ if (!jBone._cache.events[jid]) {
+ jBone._cache.events[jid] = {};
+ }
+};
+
+jBone.getData = function(el) {
+ el = el instanceof jBone ? el[0] : el;
+
+ var jid = el === win ? "window" : el.jid;
+
+ return {
+ jid: jid,
+ events: jBone._cache.events[jid]
+ };
+};
+
+jBone.isElement = function(el) {
+ return el && el instanceof jBone || el instanceof HTMLElement || isString(el);
+};
+
+jBone._cache = {
+ events: {},
+ jid: 0
+};
+
+function isArraylike(obj) {
+ var length = obj.length,
+ type = typeof obj;
+
+ if (isFunction(type) || obj === win) {
+ return false;
+ }
+
+ if (obj.nodeType === 1 && length) {
+ return true;
+ }
+
+ return isArray(type) || length === 0 ||
+ typeof length === "number" && length > 0 && (length - 1) in obj;
+}
+
+jBone.merge = function(first, second) {
+ var l = second.length,
+ i = first.length,
+ j = 0;
+
+ while (j < l) {
+ first[i++] = second[j++];
+ }
+
+ first.length = i;
+
+ return first;
+};
+
+jBone.contains = function(container, contained) {
+ var result;
+
+ container.reverse().some(function(el) {
+ if (el.contains(contained)) {
+ return result = el;
+ }
+ });
+
+ return result;
+};
+
+jBone.extend = function(target) {
+ var k, kl, i, tg;
+
+ splice.call(arguments, 1).forEach(function(object) {
+ if (!object) {
+ return;
+ }
+
+ k = keys(object);
+ kl = k.length;
+ i = 0;
+ tg = target; //caching target for perf improvement
+
+ for (; i < kl; i++) {
+ tg[k[i]] = object[k[i]];
+ }
+ });
+
+ return target;
+};
+
+jBone.makeArray = function(arr, results) {
+ var ret = results || [];
+
+ if (arr !== null) {
+ if (isArraylike(arr)) {
+ jBone.merge(ret, isString(arr) ? [arr] : arr);
+ } else {
+ ret.push(arr);
+ }
+ }
+
+ return ret;
+};
+
+function BoneEvent(e, data) {
+ var key, setter;
+
+ this.originalEvent = e;
+
+ setter = function(key, e) {
+ if (key === "preventDefault") {
+ this[key] = function() {
+ this.defaultPrevented = true;
+ return e[key]();
+ };
+ } else if (isFunction(e[key])) {
+ this[key] = function() {
+ return e[key]();
+ };
+ } else {
+ this[key] = e[key];
+ }
+ };
+
+ for (key in e) {
+ if (e[key] || typeof e[key] === "function") {
+ setter.call(this, key, e);
+ }
+ }
+
+ jBone.extend(this, data);
+}
+
+jBone.Event = function(event, data) {
+ var namespace, eventType;
+
+ if (event.type && !data) {
+ data = event;
+ event = event.type;
+ }
+
+ namespace = event.split(".").splice(1).join(".");
+ eventType = event.split(".")[0];
+
+ event = doc.createEvent("Event");
+ event.initEvent(eventType, true, true);
+
+ return jBone.extend(event, {
+ namespace: namespace,
+ isDefaultPrevented: function() {
+ return event.defaultPrevented;
+ }
+ }, data);
+};
+
+fn.on = function(event) {
+ var args = arguments,
+ length = this.length,
+ i = 0,
+ callback, target, namespace, fn, events, eventType, expectedTarget, addListener;
+
+ if (args.length === 2) {
+ callback = args[1];
+ } else {
+ target = args[1];
+ callback = args[2];
+ }
+
+ addListener = function(el) {
+ jBone.setId(el);
+ events = jBone.getData(el).events;
+ event.split(" ").forEach(function(event) {
+ eventType = event.split(".")[0];
+ namespace = event.split(".").splice(1).join(".");
+ events[eventType] = events[eventType] || [];
+
+ fn = function(e) {
+ if (e.namespace && e.namespace !== namespace) {
+ return;
+ }
+
+ expectedTarget = null;
+ if (!target) {
+ callback.call(el, e);
+ } else if (~jBone(el).find(target).indexOf(e.target) || (expectedTarget = jBone.contains(jBone(el).find(target), e.target))) {
+ expectedTarget = expectedTarget || e.target;
+ e = new BoneEvent(e, {
+ currentTarget: expectedTarget
+ });
+
+ callback.call(expectedTarget, e);
+ }
+ };
+
+ events[eventType].push({
+ namespace: namespace,
+ fn: fn,
+ originfn: callback
+ });
+
+ el.addEventListener && el.addEventListener(eventType, fn, false);
+ });
+ };
+
+ for (; i < length; i++) {
+ addListener(this[i]);
+ }
+
+ return this;
+};
+
+fn.one = function(event) {
+ var args = arguments,
+ i = 0,
+ length = this.length,
+ callback, target, addListener;
+
+ if (args.length === 2) {
+ callback = args[1];
+ } else {
+ target = args[1], callback = args[2];
+ }
+
+ addListener = function(el) {
+ event.split(" ").forEach(function(event) {
+ var fn = function(e) {
+ jBone(el).off(event, fn);
+ callback.call(el, e);
+ };
+
+ if (!target) {
+ jBone(el).on(event, fn);
+ } else {
+ jBone(el).on(event, target, fn);
+ }
+ });
+ };
+
+ for (; i < length; i++) {
+ addListener(this[i]);
+ }
+
+ return this;
+};
+
+fn.trigger = function(event) {
+ var events = [],
+ i = 0,
+ length = this.length,
+ dispatchEvents;
+
+ if (!event) {
+ return this;
+ }
+
+ if (isString(event)) {
+ events = event.split(" ").map(function(event) {
+ return jBone.Event(event);
+ });
+ } else {
+ event = event instanceof Event ? event : jBone.Event(event);
+ events = [event];
+ }
+
+ dispatchEvents = function(el) {
+ events.forEach(function(event) {
+ if (!event.type) {
+ return;
+ }
+
+ el.dispatchEvent && el.dispatchEvent(event);
+ });
+ };
+
+ for (; i < length; i++) {
+ dispatchEvents(this[i]);
+ }
+
+ return this;
+};
+
+fn.off = function(event, fn) {
+ var i = 0,
+ length = this.length,
+ removeListener = function(events, eventType, index, el, e) {
+ var callback;
+
+ // get callback
+ if ((fn && e.originfn === fn) || !fn) {
+ callback = e.fn;
+ }
+
+ if (events[eventType][index].fn === callback) {
+ el.removeEventListener(eventType, callback);
+
+ // remove handler from cache
+ jBone._cache.events[jBone.getData(el).jid][eventType].splice(index, 1);
+ }
+ },
+ events, namespace, removeListeners, eventType;
+
+ removeListeners = function(el) {
+ var l, eventsByType, e;
+
+ events = jBone.getData(el).events;
+
+ if (!events) {
+ return;
+ }
+
+ // remove all events
+ if (!event && events) {
+ return keys(events).forEach(function(eventType) {
+ eventsByType = events[eventType];
+ l = eventsByType.length;
+
+ while(l--) {
+ removeListener(events, eventType, l, el, eventsByType[l]);
+ }
+ });
+ }
+
+ event.split(" ").forEach(function(event) {
+ eventType = event.split(".")[0];
+ namespace = event.split(".").splice(1).join(".");
+
+ // remove named events
+ if (events[eventType]) {
+ eventsByType = events[eventType];
+ l = eventsByType.length;
+
+ while(l--) {
+ e = eventsByType[l];
+ if (!namespace || (namespace && e.namespace === namespace)) {
+ removeListener(events, eventType, l, el, e);
+ }
+ }
+ }
+ // remove all namespaced events
+ else if (namespace) {
+ keys(events).forEach(function(eventType) {
+ eventsByType = events[eventType];
+ l = eventsByType.length;
+
+ while(l--) {
+ e = eventsByType[l];
+ if (e.namespace.split(".")[0] === namespace.split(".")[0]) {
+ removeListener(events, eventType, l, el, e);
+ }
+ }
+ });
+ }
+ });
+ };
+
+ for (; i < length; i++) {
+ removeListeners(this[i]);
+ }
+
+ return this;
+};
+
+fn.find = function(selector) {
+ var results = [],
+ i = 0,
+ length = this.length,
+ finder = function(el) {
+ if (isFunction(el.querySelectorAll)) {
+ [].forEach.call(el.querySelectorAll(selector), function(found) {
+ results.push(found);
+ });
+ }
+ };
+
+ for (; i < length; i++) {
+ finder(this[i]);
+ }
+
+ return jBone(results);
+};
+
+fn.get = function(index) {
+ return this[index];
+};
+
+fn.eq = function(index) {
+ return jBone(this[index]);
+};
+
+fn.parent = function() {
+ var results = [],
+ parent,
+ i = 0,
+ length = this.length;
+
+ for (; i < length; i++) {
+ if (!~results.indexOf(parent = this[i].parentElement) && parent) {
+ results.push(parent);
+ }
+ }
+
+ return jBone(results);
+};
+
+fn.toArray = function() {
+ return slice.call(this);
+};
+
+fn.is = function() {
+ var args = arguments;
+
+ return this.some(function(el) {
+ return el.tagName.toLowerCase() === args[0];
+ });
+};
+
+fn.has = function() {
+ var args = arguments;
+
+ return this.some(function(el) {
+ return el.querySelectorAll(args[0]).length;
+ });
+};
+
+fn.attr = function(key, value) {
+ var args = arguments,
+ i = 0,
+ length = this.length,
+ setter;
+
+ if (isString(key) && args.length === 1) {
+ return this[0] && this[0].getAttribute(key);
+ }
+
+ if (args.length === 2) {
+ setter = function(el) {
+ el.setAttribute(key, value);
+ };
+ } else if (isObject(key)) {
+ setter = function(el) {
+ keys(key).forEach(function(name) {
+ el.setAttribute(name, key[name]);
+ });
+ };
+ }
+
+ for (; i < length; i++) {
+ setter(this[i]);
+ }
+
+ return this;
+};
+
+fn.removeAttr = function(key) {
+ var i = 0,
+ length = this.length;
+
+ for (; i < length; i++) {
+ this[i].removeAttribute(key);
+ }
+
+ return this;
+};
+
+fn.val = function(value) {
+ var i = 0,
+ length = this.length;
+
+ if (arguments.length === 0) {
+ return this[0] && this[0].value;
+ }
+
+ for (; i < length; i++) {
+ this[i].value = value;
+ }
+
+ return this;
+};
+
+fn.css = function(key, value) {
+ var args = arguments,
+ i = 0,
+ length = this.length,
+ setter;
+
+ // Get attribute
+ if (isString(key) && args.length === 1) {
+ return this[0] && win.getComputedStyle(this[0])[key];
+ }
+
+ // Set attributes
+ if (args.length === 2) {
+ setter = function(el) {
+ el.style[key] = value;
+ };
+ } else if (isObject(key)) {
+ setter = function(el) {
+ keys(key).forEach(function(name) {
+ el.style[name] = key[name];
+ });
+ };
+ }
+
+ for (; i < length; i++) {
+ setter(this[i]);
+ }
+
+ return this;
+};
+
+fn.data = function(key, value) {
+ var args = arguments, data = {},
+ i = 0,
+ length = this.length,
+ setter,
+ setValue = function(el, key, value) {
+ if (isObject(value)) {
+ el.jdata = el.jdata || {};
+ el.jdata[key] = value;
+ } else {
+ el.dataset[key] = value;
+ }
+ },
+ getValue = function(value) {
+ if (value === "true") {
+ return true;
+ } else if (value === "false") {
+ return false;
+ } else {
+ return value;
+ }
+ };
+
+ // Get all data
+ if (args.length === 0) {
+ this[0].jdata && (data = this[0].jdata);
+
+ keys(this[0].dataset).forEach(function(key) {
+ data[key] = getValue(this[0].dataset[key]);
+ }, this);
+
+ return data;
+ }
+ // Get data by name
+ if (args.length === 1 && isString(key)) {
+ return this[0] && getValue(this[0].dataset[key] || this[0].jdata && this[0].jdata[key]);
+ }
+
+ // Set data
+ if (args.length === 1 && isObject(key)) {
+ setter = function(el) {
+ keys(key).forEach(function(name) {
+ setValue(el, name, key[name]);
+ });
+ };
+ } else if (args.length === 2) {
+ setter = function(el) {
+ setValue(el, key, value);
+ };
+ }
+
+ for (; i < length; i++) {
+ setter(this[i]);
+ }
+
+ return this;
+};
+
+fn.removeData = function(key) {
+ var i = 0,
+ length = this.length,
+ jdata, dataset;
+
+ for (; i < length; i++) {
+ jdata = this[i].jdata;
+ dataset = this[i].dataset;
+
+ if (key) {
+ jdata && jdata[key] && delete jdata[key];
+ delete dataset[key];
+ } else {
+ for (key in jdata) {
+ delete jdata[key];
+ }
+
+ for (key in dataset) {
+ delete dataset[key];
+ }
+ }
+ }
+
+ return this;
+};
+
+fn.html = function(value) {
+ var args = arguments,
+ el;
+
+ // add HTML into elements
+ if (args.length === 1 && value !== undefined) {
+ return this.empty().append(value);
+ }
+ // get HTML from element
+ else if (args.length === 0 && (el = this[0])) {
+ return el.innerHTML;
+ }
+
+ return this;
+};
+
+fn.append = function(appended) {
+ var i = 0,
+ length = this.length,
+ setter;
+
+ // create jBone object and then append
+ if (isString(appended) && rquickExpr.exec(appended)) {
+ appended = jBone(appended);
+ }
+ // create text node for inserting
+ else if (!isObject(appended)) {
+ appended = document.createTextNode(appended);
+ }
+
+ appended = appended instanceof jBone ? appended : jBone(appended);
+
+ setter = function(el, i) {
+ appended.forEach(function(node) {
+ if (i) {
+ el.appendChild(node.cloneNode());
+ } else {
+ el.appendChild(node);
+ }
+ });
+ };
+
+ for (; i < length; i++) {
+ setter(this[i], i);
+ }
+
+ return this;
+};
+
+fn.appendTo = function(to) {
+ jBone(to).append(this);
+
+ return this;
+};
+
+fn.empty = function() {
+ var i = 0,
+ length = this.length,
+ el;
+
+ for (; i < length; i++) {
+ el = this[i];
+
+ while (el.lastChild) {
+ el.removeChild(el.lastChild);
+ }
+ }
+
+ return this;
+};
+
+fn.remove = function() {
+ var i = 0,
+ length = this.length,
+ el;
+
+ // remove all listners
+ this.off();
+
+ for (; i < length; i++) {
+ el = this[i];
+
+ // remove data and nodes
+ delete el.jdata;
+ el.parentNode && el.parentNode.removeChild(el);
+ }
+
+ return this;
+};
+
+if (typeof module === "object" && module && typeof module.exports === "object") {
+ // Expose jBone as module.exports in loaders that implement the Node
+ // module pattern (including browserify). Do not create the global, since
+ // the user will be storing it themselves locally, and globals are frowned
+ // upon in the Node module world.
+ module.exports = jBone;
+}
+// Register as a AMD module
+else if (typeof define === "function" && define.amd) {
+ define(function() {
+ return jBone;
+ });
+
+ win.jBone = win.$ = jBone;
+} else if (typeof win === "object" && typeof win.document === "object") {
+ win.jBone = win.$ = jBone;
+}
+
+}(window));
+
+},{}],51:[function(require,module,exports){
+var Mouse;
+
+module.exports = Mouse = {
+ rel: function(e) {
+ var mouseX, mouseY, rect, target;
+ mouseX = e.offsetX;
+ mouseY = e.offsetY;
+ if (mouseX == null) {
+ rect = target.getBoundingClientRect();
+ target = e.target || e.srcElement;
+ if (mouseX == null) {
+ mouseX = e.clientX - rect.left;
+ mouseY = e.clientY - rect.top;
+ }
+ if (mouseX == null) {
+ mouseX = e.pageX - target.offsetLeft;
+ mouseY = e.pageY - target.offsetTop;
+ }
+ if (mouseX == null) {
+ console.log(e, "no mouse event defined. your browser sucks");
+ return;
+ }
+ }
+ return [mouseX, mouseY];
+ },
+ abs: function(e) {
+ var mouseX, mouseY;
+ mouseX = e.pageX;
+ mouseY = e.pageY;
+ if (mouseX == null) {
+ mouseX = e.layerX;
+ mouseY = e.layerY;
+ }
+ if (mouseX == null) {
+ mouseX = e.clientX;
+ mouseY = e.clientY;
+ }
+ if (mouseX == null) {
+ mouseX = e.x;
+ mouseY = e.y;
+ }
+ return [mouseX, mouseY];
+ },
+ wheelDelta: function(e) {
+ var delta, dir;
+ delta = [e.deltaX, e.deltaY];
+ if (delta[0] == null) {
+ dir = Math.floor(e.detail / 3);
+ delta = [0, e.mozMovementX * dir];
+ }
+ return delta;
+ }
+};
+
+},{}],52:[function(require,module,exports){
+var window = require("global/window")
+var once = require("once")
+var parseHeaders = require('parse-headers')
+
+var messages = {
+ "0": "Internal XMLHttpRequest Error",
+ "4": "4xx Client Error",
+ "5": "5xx Server Error"
+}
+
+var XHR = window.XMLHttpRequest || noop
+var XDR = "withCredentials" in (new XHR()) ? XHR : window.XDomainRequest
+
+module.exports = createXHR
+
+function createXHR(options, callback) {
+ if (typeof options === "string") {
+ options = { uri: options }
+ }
+
+ options = options || {}
+ callback = once(callback)
+
+ var xhr = options.xhr || null
+
+ if (!xhr) {
+ if (options.cors || options.useXDR) {
+ xhr = new XDR()
+ }else{
+ xhr = new XHR()
+ }
+ }
+
+ var uri = xhr.url = options.uri || options.url
+ var method = xhr.method = options.method || "GET"
+ var body = options.body || options.data
+ var headers = xhr.headers = options.headers || {}
+ var sync = !!options.sync
+ var isJson = false
+ var key
+ var load = options.response ? loadResponse : loadXhr
+
+ if ("json" in options) {
+ isJson = true
+ headers["Accept"] = "application/json"
+ if (method !== "GET" && method !== "HEAD") {
+ headers["Content-Type"] = "application/json"
+ body = JSON.stringify(options.json)
+ }
+ }
+
+ xhr.onreadystatechange = readystatechange
+ xhr.onload = load
+ xhr.onerror = error
+ // IE9 must have onprogress be set to a unique function.
+ xhr.onprogress = function () {
+ // IE must die
+ }
+ // hate IE
+ xhr.ontimeout = noop
+ xhr.open(method, uri, !sync)
+ //backward compatibility
+ if (options.withCredentials || (options.cors && options.withCredentials !== false)) {
+ xhr.withCredentials = true
+ }
+
+ // Cannot set timeout with sync request
+ if (!sync) {
+ xhr.timeout = "timeout" in options ? options.timeout : 5000
+ }
+
+ if (xhr.setRequestHeader) {
+ for(key in headers){
+ if(headers.hasOwnProperty(key)){
+ xhr.setRequestHeader(key, headers[key])
+ }
+ }
+ } else if (options.headers) {
+ throw new Error("Headers cannot be set on an XDomainRequest object")
+ }
+
+ if ("responseType" in options) {
+ xhr.responseType = options.responseType
+ }
+
+ if ("beforeSend" in options &&
+ typeof options.beforeSend === "function"
+ ) {
+ options.beforeSend(xhr)
+ }
+
+ xhr.send(body)
+
+ return xhr
+
+ function readystatechange() {
+ if (xhr.readyState === 4) {
+ load()
+ }
+ }
+
+ function getBody() {
+ // Chrome with requestType=blob throws errors arround when even testing access to responseText
+ var body = null
+
+ if (xhr.response) {
+ body = xhr.response
+ } else if (xhr.responseType === 'text' || !xhr.responseType) {
+ body = xhr.responseText || xhr.responseXML
+ }
+
+ if (isJson) {
+ try {
+ body = JSON.parse(body)
+ } catch (e) {}
+ }
+
+ return body
+ }
+
+ function getStatusCode() {
+ return xhr.status === 1223 ? 204 : xhr.status
+ }
+
+ // if we're getting a none-ok statusCode, build & return an error
+ function errorFromStatusCode(status) {
+ var error = null
+ if (status === 0 || (status >= 400 && status < 600)) {
+ var message = (typeof body === "string" ? body : false) ||
+ messages[String(status).charAt(0)]
+ error = new Error(message)
+ error.statusCode = status
+ }
+
+ return error
+ }
+
+ // will load the data & process the response in a special response object
+ function loadResponse() {
+ var status = getStatusCode()
+ var error = errorFromStatusCode(status)
+ var response = {
+ body: getBody(),
+ statusCode: status,
+ statusText: xhr.statusText,
+ raw: xhr
+ }
+ if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
+ response.headers = parseHeaders(xhr.getAllResponseHeaders())
+ } else {
+ response.headers = {}
+ }
+
+ callback(error, response, response.body)
+ }
+
+ // will load the data and add some response properties to the source xhr
+ // and then respond with that
+ function loadXhr() {
+ var status = getStatusCode()
+ var error = errorFromStatusCode(status)
+
+ xhr.status = xhr.statusCode = status
+ xhr.body = getBody()
+ xhr.headers = parseHeaders(xhr.getAllResponseHeaders())
+
+ callback(error, xhr, xhr.body)
+ }
+
+ function error(evt) {
+ callback(evt, xhr)
+ }
+}
+
+
+function noop() {}
+
+},{"global/window":53,"once":54,"parse-headers":58}],53:[function(require,module,exports){
+(function (global){
+if (typeof window !== "undefined") {
+ module.exports = window;
+} else if (typeof global !== "undefined") {
+ module.exports = global;
+} else if (typeof self !== "undefined"){
+ module.exports = self;
+} else {
+ module.exports = {};
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],54:[function(require,module,exports){
+module.exports = once
+
+once.proto = once(function () {
+ Object.defineProperty(Function.prototype, 'once', {
+ value: function () {
+ return once(this)
+ },
+ configurable: true
+ })
+})
+
+function once (fn) {
+ var called = false
+ return function () {
+ if (called) return
+ called = true
+ return fn.apply(this, arguments)
+ }
+}
+
+},{}],55:[function(require,module,exports){
+var isFunction = require('is-function')
+
+module.exports = forEach
+
+var toString = Object.prototype.toString
+var hasOwnProperty = Object.prototype.hasOwnProperty
+
+function forEach(list, iterator, context) {
+ if (!isFunction(iterator)) {
+ throw new TypeError('iterator must be a function')
+ }
+
+ if (arguments.length < 3) {
+ context = this
+ }
+
+ if (toString.call(list) === '[object Array]')
+ forEachArray(list, iterator, context)
+ else if (typeof list === 'string')
+ forEachString(list, iterator, context)
+ else
+ forEachObject(list, iterator, context)
+}
+
+function forEachArray(array, iterator, context) {
+ for (var i = 0, len = array.length; i < len; i++) {
+ if (hasOwnProperty.call(array, i)) {
+ iterator.call(context, array[i], i, array)
+ }
+ }
+}
+
+function forEachString(string, iterator, context) {
+ for (var i = 0, len = string.length; i < len; i++) {
+ // no such thing as a sparse string.
+ iterator.call(context, string.charAt(i), i, string)
+ }
+}
+
+function forEachObject(object, iterator, context) {
+ for (var k in object) {
+ if (hasOwnProperty.call(object, k)) {
+ iterator.call(context, object[k], k, object)
+ }
+ }
+}
+
+},{"is-function":56}],56:[function(require,module,exports){
+module.exports = isFunction
+
+var toString = Object.prototype.toString
+
+function isFunction (fn) {
+ var string = toString.call(fn)
+ return string === '[object Function]' ||
+ (typeof fn === 'function' && string !== '[object RegExp]') ||
+ (typeof window !== 'undefined' &&
+ // IE8 and below
+ (fn === window.setTimeout ||
+ fn === window.alert ||
+ fn === window.confirm ||
+ fn === window.prompt))
+};
+
+},{}],57:[function(require,module,exports){
+
+exports = module.exports = trim;
+
+function trim(str){
+ return str.replace(/^\s*|\s*$/g, '');
+}
+
+exports.left = function(str){
+ return str.replace(/^\s*/, '');
+};
+
+exports.right = function(str){
+ return str.replace(/\s*$/, '');
+};
+
+},{}],58:[function(require,module,exports){
+var trim = require('trim')
+ , forEach = require('for-each')
+ , isArray = function(arg) {
+ return Object.prototype.toString.call(arg) === '[object Array]';
+ }
+
+module.exports = function (headers) {
+ if (!headers)
+ return {}
+
+ var result = {}
+
+ forEach(
+ trim(headers).split('\n')
+ , function (row) {
+ var index = row.indexOf(':')
+ , key = trim(row.slice(0, index)).toLowerCase()
+ , value = trim(row.slice(index + 1))
+
+ if (typeof(result[key]) === 'undefined') {
+ result[key] = value
+ } else if (isArray(result[key])) {
+ result[key].push(value)
+ } else {
+ result[key] = [ result[key], value ]
+ }
+ }
+ )
+
+ return result
+}
+},{"for-each":55,"trim":57}],59:[function(require,module,exports){
+// Underscore.js 1.7.0
+// http://underscorejs.org
+// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Underscore may be freely distributed under the MIT license.
+
+(function() {
+
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `exports` on the server.
+ var root = this;
+
+ // Save the previous value of the `_` variable.
+ var previousUnderscore = root._;
+
+ // Save bytes in the minified (but not gzipped) version:
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+ // Create quick reference variables for speed access to core prototypes.
+ var
+ push = ArrayProto.push,
+ slice = ArrayProto.slice,
+ concat = ArrayProto.concat,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
+
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
+ var
+ nativeIsArray = Array.isArray,
+ nativeKeys = Object.keys,
+ nativeBind = FuncProto.bind;
+
+ // Create a safe reference to the Underscore object for use below.
+ var _ = function(obj) {
+ if (obj instanceof _) return obj;
+ if (!(this instanceof _)) return new _(obj);
+ this._wrapped = obj;
+ };
+
+ // Export the Underscore object for **Node.js**, with
+ // backwards-compatibility for the old `require()` API. If we're in
+ // the browser, add `_` as a global object.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
+ exports._ = _;
+ } else {
+ root._ = _;
+ }
+
+ // Current version.
+ _.VERSION = '1.7.0';
+
+ // Internal function that returns an efficient (for current engines) version
+ // of the passed-in callback, to be repeatedly applied in other Underscore
+ // functions.
+ var createCallback = function(func, context, argCount) {
+ if (context === void 0) return func;
+ switch (argCount == null ? 3 : argCount) {
+ case 1: return function(value) {
+ return func.call(context, value);
+ };
+ case 2: return function(value, other) {
+ return func.call(context, value, other);
+ };
+ case 3: return function(value, index, collection) {
+ return func.call(context, value, index, collection);
+ };
+ case 4: return function(accumulator, value, index, collection) {
+ return func.call(context, accumulator, value, index, collection);
+ };
+ }
+ return function() {
+ return func.apply(context, arguments);
+ };
+ };
+
+ // A mostly-internal function to generate callbacks that can be applied
+ // to each element in a collection, returning the desired result — either
+ // identity, an arbitrary callback, a property matcher, or a property accessor.
+ _.iteratee = function(value, context, argCount) {
+ if (value == null) return _.identity;
+ if (_.isFunction(value)) return createCallback(value, context, argCount);
+ if (_.isObject(value)) return _.matches(value);
+ return _.property(value);
+ };
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles raw objects in addition to array-likes. Treats all
+ // sparse array-likes as if they were dense.
+ _.each = _.forEach = function(obj, iteratee, context) {
+ if (obj == null) return obj;
+ iteratee = createCallback(iteratee, context);
+ var i, length = obj.length;
+ if (length === +length) {
+ for (i = 0; i < length; i++) {
+ iteratee(obj[i], i, obj);
+ }
+ } else {
+ var keys = _.keys(obj);
+ for (i = 0, length = keys.length; i < length; i++) {
+ iteratee(obj[keys[i]], keys[i], obj);
+ }
+ }
+ return obj;
+ };
+
+ // Return the results of applying the iteratee to each element.
+ _.map = _.collect = function(obj, iteratee, context) {
+ if (obj == null) return [];
+ iteratee = _.iteratee(iteratee, context);
+ var keys = obj.length !== +obj.length && _.keys(obj),
+ length = (keys || obj).length,
+ results = Array(length),
+ currentKey;
+ for (var index = 0; index < length; index++) {
+ currentKey = keys ? keys[index] : index;
+ results[index] = iteratee(obj[currentKey], currentKey, obj);
+ }
+ return results;
+ };
+
+ var reduceError = 'Reduce of empty array with no initial value';
+
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`.
+ _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) {
+ if (obj == null) obj = [];
+ iteratee = createCallback(iteratee, context, 4);
+ var keys = obj.length !== +obj.length && _.keys(obj),
+ length = (keys || obj).length,
+ index = 0, currentKey;
+ if (arguments.length < 3) {
+ if (!length) throw new TypeError(reduceError);
+ memo = obj[keys ? keys[index++] : index++];
+ }
+ for (; index < length; index++) {
+ currentKey = keys ? keys[index] : index;
+ memo = iteratee(memo, obj[currentKey], currentKey, obj);
+ }
+ return memo;
+ };
+
+ // The right-associative version of reduce, also known as `foldr`.
+ _.reduceRight = _.foldr = function(obj, iteratee, memo, context) {
+ if (obj == null) obj = [];
+ iteratee = createCallback(iteratee, context, 4);
+ var keys = obj.length !== + obj.length && _.keys(obj),
+ index = (keys || obj).length,
+ currentKey;
+ if (arguments.length < 3) {
+ if (!index) throw new TypeError(reduceError);
+ memo = obj[keys ? keys[--index] : --index];
+ }
+ while (index--) {
+ currentKey = keys ? keys[index] : index;
+ memo = iteratee(memo, obj[currentKey], currentKey, obj);
+ }
+ return memo;
+ };
+
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, predicate, context) {
+ var result;
+ predicate = _.iteratee(predicate, context);
+ _.some(obj, function(value, index, list) {
+ if (predicate(value, index, list)) {
+ result = value;
+ return true;
+ }
+ });
+ return result;
+ };
+
+ // Return all the elements that pass a truth test.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, predicate, context) {
+ var results = [];
+ if (obj == null) return results;
+ predicate = _.iteratee(predicate, context);
+ _.each(obj, function(value, index, list) {
+ if (predicate(value, index, list)) results.push(value);
+ });
+ return results;
+ };
+
+ // Return all the elements for which a truth test fails.
+ _.reject = function(obj, predicate, context) {
+ return _.filter(obj, _.negate(_.iteratee(predicate)), context);
+ };
+
+ // Determine whether all of the elements match a truth test.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, predicate, context) {
+ if (obj == null) return true;
+ predicate = _.iteratee(predicate, context);
+ var keys = obj.length !== +obj.length && _.keys(obj),
+ length = (keys || obj).length,
+ index, currentKey;
+ for (index = 0; index < length; index++) {
+ currentKey = keys ? keys[index] : index;
+ if (!predicate(obj[currentKey], currentKey, obj)) return false;
+ }
+ return true;
+ };
+
+ // Determine if at least one element in the object matches a truth test.
+ // Aliased as `any`.
+ _.some = _.any = function(obj, predicate, context) {
+ if (obj == null) return false;
+ predicate = _.iteratee(predicate, context);
+ var keys = obj.length !== +obj.length && _.keys(obj),
+ length = (keys || obj).length,
+ index, currentKey;
+ for (index = 0; index < length; index++) {
+ currentKey = keys ? keys[index] : index;
+ if (predicate(obj[currentKey], currentKey, obj)) return true;
+ }
+ return false;
+ };
+
+ // Determine if the array or object contains a given value (using `===`).
+ // Aliased as `include`.
+ _.contains = _.include = function(obj, target) {
+ if (obj == null) return false;
+ if (obj.length !== +obj.length) obj = _.values(obj);
+ return _.indexOf(obj, target) >= 0;
+ };
+
+ // Invoke a method (with arguments) on every item in a collection.
+ _.invoke = function(obj, method) {
+ var args = slice.call(arguments, 2);
+ var isFunc = _.isFunction(method);
+ return _.map(obj, function(value) {
+ return (isFunc ? method : value[method]).apply(value, args);
+ });
+ };
+
+ // Convenience version of a common use case of `map`: fetching a property.
+ _.pluck = function(obj, key) {
+ return _.map(obj, _.property(key));
+ };
+
+ // Convenience version of a common use case of `filter`: selecting only objects
+ // containing specific `key:value` pairs.
+ _.where = function(obj, attrs) {
+ return _.filter(obj, _.matches(attrs));
+ };
+
+ // Convenience version of a common use case of `find`: getting the first object
+ // containing specific `key:value` pairs.
+ _.findWhere = function(obj, attrs) {
+ return _.find(obj, _.matches(attrs));
+ };
+
+ // Return the maximum element (or element-based computation).
+ _.max = function(obj, iteratee, context) {
+ var result = -Infinity, lastComputed = -Infinity,
+ value, computed;
+ if (iteratee == null && obj != null) {
+ obj = obj.length === +obj.length ? obj : _.values(obj);
+ for (var i = 0, length = obj.length; i < length; i++) {
+ value = obj[i];
+ if (value > result) {
+ result = value;
+ }
+ }
+ } else {
+ iteratee = _.iteratee(iteratee, context);
+ _.each(obj, function(value, index, list) {
+ computed = iteratee(value, index, list);
+ if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
+ result = value;
+ lastComputed = computed;
+ }
+ });
+ }
+ return result;
+ };
+
+ // Return the minimum element (or element-based computation).
+ _.min = function(obj, iteratee, context) {
+ var result = Infinity, lastComputed = Infinity,
+ value, computed;
+ if (iteratee == null && obj != null) {
+ obj = obj.length === +obj.length ? obj : _.values(obj);
+ for (var i = 0, length = obj.length; i < length; i++) {
+ value = obj[i];
+ if (value < result) {
+ result = value;
+ }
+ }
+ } else {
+ iteratee = _.iteratee(iteratee, context);
+ _.each(obj, function(value, index, list) {
+ computed = iteratee(value, index, list);
+ if (computed < lastComputed || computed === Infinity && result === Infinity) {
+ result = value;
+ lastComputed = computed;
+ }
+ });
+ }
+ return result;
+ };
+
+ // Shuffle a collection, using the modern version of the
+ // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
+ _.shuffle = function(obj) {
+ var set = obj && obj.length === +obj.length ? obj : _.values(obj);
+ var length = set.length;
+ var shuffled = Array(length);
+ for (var index = 0, rand; index < length; index++) {
+ rand = _.random(0, index);
+ if (rand !== index) shuffled[index] = shuffled[rand];
+ shuffled[rand] = set[index];
+ }
+ return shuffled;
+ };
+
+ // Sample **n** random values from a collection.
+ // If **n** is not specified, returns a single random element.
+ // The internal `guard` argument allows it to work with `map`.
+ _.sample = function(obj, n, guard) {
+ if (n == null || guard) {
+ if (obj.length !== +obj.length) obj = _.values(obj);
+ return obj[_.random(obj.length - 1)];
+ }
+ return _.shuffle(obj).slice(0, Math.max(0, n));
+ };
+
+ // Sort the object's values by a criterion produced by an iteratee.
+ _.sortBy = function(obj, iteratee, context) {
+ iteratee = _.iteratee(iteratee, context);
+ return _.pluck(_.map(obj, function(value, index, list) {
+ return {
+ value: value,
+ index: index,
+ criteria: iteratee(value, index, list)
+ };
+ }).sort(function(left, right) {
+ var a = left.criteria;
+ var b = right.criteria;
+ if (a !== b) {
+ if (a > b || a === void 0) return 1;
+ if (a < b || b === void 0) return -1;
+ }
+ return left.index - right.index;
+ }), 'value');
+ };
+
+ // An internal function used for aggregate "group by" operations.
+ var group = function(behavior) {
+ return function(obj, iteratee, context) {
+ var result = {};
+ iteratee = _.iteratee(iteratee, context);
+ _.each(obj, function(value, index) {
+ var key = iteratee(value, index, obj);
+ behavior(result, value, key);
+ });
+ return result;
+ };
+ };
+
+ // Groups the object's values by a criterion. Pass either a string attribute
+ // to group by, or a function that returns the criterion.
+ _.groupBy = group(function(result, value, key) {
+ if (_.has(result, key)) result[key].push(value); else result[key] = [value];
+ });
+
+ // Indexes the object's values by a criterion, similar to `groupBy`, but for
+ // when you know that your index values will be unique.
+ _.indexBy = group(function(result, value, key) {
+ result[key] = value;
+ });
+
+ // Counts instances of an object that group by a certain criterion. Pass
+ // either a string attribute to count by, or a function that returns the
+ // criterion.
+ _.countBy = group(function(result, value, key) {
+ if (_.has(result, key)) result[key]++; else result[key] = 1;
+ });
+
+ // Use a comparator function to figure out the smallest index at which
+ // an object should be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iteratee, context) {
+ iteratee = _.iteratee(iteratee, context, 1);
+ var value = iteratee(obj);
+ var low = 0, high = array.length;
+ while (low < high) {
+ var mid = low + high >>> 1;
+ if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
+ }
+ return low;
+ };
+
+ // Safely create a real, live array from anything iterable.
+ _.toArray = function(obj) {
+ if (!obj) return [];
+ if (_.isArray(obj)) return slice.call(obj);
+ if (obj.length === +obj.length) return _.map(obj, _.identity);
+ return _.values(obj);
+ };
+
+ // Return the number of elements in an object.
+ _.size = function(obj) {
+ if (obj == null) return 0;
+ return obj.length === +obj.length ? obj.length : _.keys(obj).length;
+ };
+
+ // Split a collection into two arrays: one whose elements all satisfy the given
+ // predicate, and one whose elements all do not satisfy the predicate.
+ _.partition = function(obj, predicate, context) {
+ predicate = _.iteratee(predicate, context);
+ var pass = [], fail = [];
+ _.each(obj, function(value, key, obj) {
+ (predicate(value, key, obj) ? pass : fail).push(value);
+ });
+ return [pass, fail];
+ };
+
+ // Array Functions
+ // ---------------
+
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head` and `take`. The **guard** check
+ // allows it to work with `_.map`.
+ _.first = _.head = _.take = function(array, n, guard) {
+ if (array == null) return void 0;
+ if (n == null || guard) return array[0];
+ if (n < 0) return [];
+ return slice.call(array, 0, n);
+ };
+
+ // Returns everything but the last entry of the array. Especially useful on
+ // the arguments object. Passing **n** will return all the values in
+ // the array, excluding the last N. The **guard** check allows it to work with
+ // `_.map`.
+ _.initial = function(array, n, guard) {
+ return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
+ };
+
+ // Get the last element of an array. Passing **n** will return the last N
+ // values in the array. The **guard** check allows it to work with `_.map`.
+ _.last = function(array, n, guard) {
+ if (array == null) return void 0;
+ if (n == null || guard) return array[array.length - 1];
+ return slice.call(array, Math.max(array.length - n, 0));
+ };
+
+ // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
+ // Especially useful on the arguments object. Passing an **n** will return
+ // the rest N values in the array. The **guard**
+ // check allows it to work with `_.map`.
+ _.rest = _.tail = _.drop = function(array, n, guard) {
+ return slice.call(array, n == null || guard ? 1 : n);
+ };
+
+ // Trim out all falsy values from an array.
+ _.compact = function(array) {
+ return _.filter(array, _.identity);
+ };
+
+ // Internal implementation of a recursive `flatten` function.
+ var flatten = function(input, shallow, strict, output) {
+ if (shallow && _.every(input, _.isArray)) {
+ return concat.apply(output, input);
+ }
+ for (var i = 0, length = input.length; i < length; i++) {
+ var value = input[i];
+ if (!_.isArray(value) && !_.isArguments(value)) {
+ if (!strict) output.push(value);
+ } else if (shallow) {
+ push.apply(output, value);
+ } else {
+ flatten(value, shallow, strict, output);
+ }
+ }
+ return output;
+ };
+
+ // Flatten out an array, either recursively (by default), or just one level.
+ _.flatten = function(array, shallow) {
+ return flatten(array, shallow, false, []);
+ };
+
+ // Return a version of the array that does not contain the specified value(s).
+ _.without = function(array) {
+ return _.difference(array, slice.call(arguments, 1));
+ };
+
+ // Produce a duplicate-free version of the array. If the array has already
+ // been sorted, you have the option of using a faster algorithm.
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted, iteratee, context) {
+ if (array == null) return [];
+ if (!_.isBoolean(isSorted)) {
+ context = iteratee;
+ iteratee = isSorted;
+ isSorted = false;
+ }
+ if (iteratee != null) iteratee = _.iteratee(iteratee, context);
+ var result = [];
+ var seen = [];
+ for (var i = 0, length = array.length; i < length; i++) {
+ var value = array[i];
+ if (isSorted) {
+ if (!i || seen !== value) result.push(value);
+ seen = value;
+ } else if (iteratee) {
+ var computed = iteratee(value, i, array);
+ if (_.indexOf(seen, computed) < 0) {
+ seen.push(computed);
+ result.push(value);
+ }
+ } else if (_.indexOf(result, value) < 0) {
+ result.push(value);
+ }
+ }
+ return result;
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(flatten(arguments, true, true, []));
+ };
+
+ // Produce an array that contains every item shared between all the
+ // passed-in arrays.
+ _.intersection = function(array) {
+ if (array == null) return [];
+ var result = [];
+ var argsLength = arguments.length;
+ for (var i = 0, length = array.length; i < length; i++) {
+ var item = array[i];
+ if (_.contains(result, item)) continue;
+ for (var j = 1; j < argsLength; j++) {
+ if (!_.contains(arguments[j], item)) break;
+ }
+ if (j === argsLength) result.push(item);
+ }
+ return result;
+ };
+
+ // Take the difference between one array and a number of other arrays.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array) {
+ var rest = flatten(slice.call(arguments, 1), true, true, []);
+ return _.filter(array, function(value){
+ return !_.contains(rest, value);
+ });
+ };
+
+ // Zip together multiple lists into a single array -- elements that share
+ // an index go together.
+ _.zip = function(array) {
+ if (array == null) return [];
+ var length = _.max(arguments, 'length').length;
+ var results = Array(length);
+ for (var i = 0; i < length; i++) {
+ results[i] = _.pluck(arguments, i);
+ }
+ return results;
+ };
+
+ // Converts lists into objects. Pass either a single array of `[key, value]`
+ // pairs, or two parallel arrays of the same length -- one of keys, and one of
+ // the corresponding values.
+ _.object = function(list, values) {
+ if (list == null) return {};
+ var result = {};
+ for (var i = 0, length = list.length; i < length; i++) {
+ if (values) {
+ result[list[i]] = values[i];
+ } else {
+ result[list[i][0]] = list[i][1];
+ }
+ }
+ return result;
+ };
+
+ // Return the position of the first occurrence of an item in an array,
+ // or -1 if the item is not included in the array.
+ // If the array is large and already in sort order, pass `true`
+ // for **isSorted** to use binary search.
+ _.indexOf = function(array, item, isSorted) {
+ if (array == null) return -1;
+ var i = 0, length = array.length;
+ if (isSorted) {
+ if (typeof isSorted == 'number') {
+ i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
+ } else {
+ i = _.sortedIndex(array, item);
+ return array[i] === item ? i : -1;
+ }
+ }
+ for (; i < length; i++) if (array[i] === item) return i;
+ return -1;
+ };
+
+ _.lastIndexOf = function(array, item, from) {
+ if (array == null) return -1;
+ var idx = array.length;
+ if (typeof from == 'number') {
+ idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
+ }
+ while (--idx >= 0) if (array[idx] === item) return idx;
+ return -1;
+ };
+
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
+ _.range = function(start, stop, step) {
+ if (arguments.length <= 1) {
+ stop = start || 0;
+ start = 0;
+ }
+ step = step || 1;
+
+ var length = Math.max(Math.ceil((stop - start) / step), 0);
+ var range = Array(length);
+
+ for (var idx = 0; idx < length; idx++, start += step) {
+ range[idx] = start;
+ }
+
+ return range;
+ };
+
+ // Function (ahem) Functions
+ // ------------------
+
+ // Reusable constructor function for prototype setting.
+ var Ctor = function(){};
+
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
+ // available.
+ _.bind = function(func, context) {
+ var args, bound;
+ if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
+ args = slice.call(arguments, 2);
+ bound = function() {
+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+ Ctor.prototype = func.prototype;
+ var self = new Ctor;
+ Ctor.prototype = null;
+ var result = func.apply(self, args.concat(slice.call(arguments)));
+ if (_.isObject(result)) return result;
+ return self;
+ };
+ return bound;
+ };
+
+ // Partially apply a function by creating a version that has had some of its
+ // arguments pre-filled, without changing its dynamic `this` context. _ acts
+ // as a placeholder, allowing any combination of arguments to be pre-filled.
+ _.partial = function(func) {
+ var boundArgs = slice.call(arguments, 1);
+ return function() {
+ var position = 0;
+ var args = boundArgs.slice();
+ for (var i = 0, length = args.length; i < length; i++) {
+ if (args[i] === _) args[i] = arguments[position++];
+ }
+ while (position < arguments.length) args.push(arguments[position++]);
+ return func.apply(this, args);
+ };
+ };
+
+ // Bind a number of an object's methods to that object. Remaining arguments
+ // are the method names to be bound. Useful for ensuring that all callbacks
+ // defined on an object belong to it.
+ _.bindAll = function(obj) {
+ var i, length = arguments.length, key;
+ if (length <= 1) throw new Error('bindAll must be passed function names');
+ for (i = 1; i < length; i++) {
+ key = arguments[i];
+ obj[key] = _.bind(obj[key], obj);
+ }
+ return obj;
+ };
+
+ // Memoize an expensive function by storing its results.
+ _.memoize = function(func, hasher) {
+ var memoize = function(key) {
+ var cache = memoize.cache;
+ var address = hasher ? hasher.apply(this, arguments) : key;
+ if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
+ return cache[address];
+ };
+ memoize.cache = {};
+ return memoize;
+ };
+
+ // Delays a function for the given number of milliseconds, and then calls
+ // it with the arguments supplied.
+ _.delay = function(func, wait) {
+ var args = slice.call(arguments, 2);
+ return setTimeout(function(){
+ return func.apply(null, args);
+ }, wait);
+ };
+
+ // Defers a function, scheduling it to run after the current call stack has
+ // cleared.
+ _.defer = function(func) {
+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+ };
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time. Normally, the throttled function will run
+ // as much as it can, without ever going more than once per `wait` duration;
+ // but if you'd like to disable the execution on the leading edge, pass
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
+ _.throttle = function(func, wait, options) {
+ var context, args, result;
+ var timeout = null;
+ var previous = 0;
+ if (!options) options = {};
+ var later = function() {
+ previous = options.leading === false ? 0 : _.now();
+ timeout = null;
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ };
+ return function() {
+ var now = _.now();
+ if (!previous && options.leading === false) previous = now;
+ var remaining = wait - (now - previous);
+ context = this;
+ args = arguments;
+ if (remaining <= 0 || remaining > wait) {
+ clearTimeout(timeout);
+ timeout = null;
+ previous = now;
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ } else if (!timeout && options.trailing !== false) {
+ timeout = setTimeout(later, remaining);
+ }
+ return result;
+ };
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds. If `immediate` is passed, trigger the function on the
+ // leading edge, instead of the trailing.
+ _.debounce = function(func, wait, immediate) {
+ var timeout, args, context, timestamp, result;
+
+ var later = function() {
+ var last = _.now() - timestamp;
+
+ if (last < wait && last > 0) {
+ timeout = setTimeout(later, wait - last);
+ } else {
+ timeout = null;
+ if (!immediate) {
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ }
+ }
+ };
+
+ return function() {
+ context = this;
+ args = arguments;
+ timestamp = _.now();
+ var callNow = immediate && !timeout;
+ if (!timeout) timeout = setTimeout(later, wait);
+ if (callNow) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+
+ return result;
+ };
+ };
+
+ // Returns the first function passed as an argument to the second,
+ // allowing you to adjust arguments, run code before and after, and
+ // conditionally execute the original function.
+ _.wrap = function(func, wrapper) {
+ return _.partial(wrapper, func);
+ };
+
+ // Returns a negated version of the passed-in predicate.
+ _.negate = function(predicate) {
+ return function() {
+ return !predicate.apply(this, arguments);
+ };
+ };
+
+ // Returns a function that is the composition of a list of functions, each
+ // consuming the return value of the function that follows.
+ _.compose = function() {
+ var args = arguments;
+ var start = args.length - 1;
+ return function() {
+ var i = start;
+ var result = args[start].apply(this, arguments);
+ while (i--) result = args[i].call(this, result);
+ return result;
+ };
+ };
+
+ // Returns a function that will only be executed after being called N times.
+ _.after = function(times, func) {
+ return function() {
+ if (--times < 1) {
+ return func.apply(this, arguments);
+ }
+ };
+ };
+
+ // Returns a function that will only be executed before being called N times.
+ _.before = function(times, func) {
+ var memo;
+ return function() {
+ if (--times > 0) {
+ memo = func.apply(this, arguments);
+ } else {
+ func = null;
+ }
+ return memo;
+ };
+ };
+
+ // Returns a function that will be executed at most one time, no matter how
+ // often you call it. Useful for lazy initialization.
+ _.once = _.partial(_.before, 2);
+
+ // Object Functions
+ // ----------------
+
+ // Retrieve the names of an object's properties.
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
+ _.keys = function(obj) {
+ if (!_.isObject(obj)) return [];
+ if (nativeKeys) return nativeKeys(obj);
+ var keys = [];
+ for (var key in obj) if (_.has(obj, key)) keys.push(key);
+ return keys;
+ };
+
+ // Retrieve the values of an object's properties.
+ _.values = function(obj) {
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var values = Array(length);
+ for (var i = 0; i < length; i++) {
+ values[i] = obj[keys[i]];
+ }
+ return values;
+ };
+
+ // Convert an object into a list of `[key, value]` pairs.
+ _.pairs = function(obj) {
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var pairs = Array(length);
+ for (var i = 0; i < length; i++) {
+ pairs[i] = [keys[i], obj[keys[i]]];
+ }
+ return pairs;
+ };
+
+ // Invert the keys and values of an object. The values must be serializable.
+ _.invert = function(obj) {
+ var result = {};
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ result[obj[keys[i]]] = keys[i];
+ }
+ return result;
+ };
+
+ // Return a sorted list of the function names available on the object.
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
+ };
+
+ // Extend a given object with all the properties in passed-in object(s).
+ _.extend = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ var source, prop;
+ for (var i = 1, length = arguments.length; i < length; i++) {
+ source = arguments[i];
+ for (prop in source) {
+ if (hasOwnProperty.call(source, prop)) {
+ obj[prop] = source[prop];
+ }
+ }
+ }
+ return obj;
+ };
+
+ // Return a copy of the object only containing the whitelisted properties.
+ _.pick = function(obj, iteratee, context) {
+ var result = {}, key;
+ if (obj == null) return result;
+ if (_.isFunction(iteratee)) {
+ iteratee = createCallback(iteratee, context);
+ for (key in obj) {
+ var value = obj[key];
+ if (iteratee(value, key, obj)) result[key] = value;
+ }
+ } else {
+ var keys = concat.apply([], slice.call(arguments, 1));
+ obj = new Object(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ key = keys[i];
+ if (key in obj) result[key] = obj[key];
+ }
+ }
+ return result;
+ };
+
+ // Return a copy of the object without the blacklisted properties.
+ _.omit = function(obj, iteratee, context) {
+ if (_.isFunction(iteratee)) {
+ iteratee = _.negate(iteratee);
+ } else {
+ var keys = _.map(concat.apply([], slice.call(arguments, 1)), String);
+ iteratee = function(value, key) {
+ return !_.contains(keys, key);
+ };
+ }
+ return _.pick(obj, iteratee, context);
+ };
+
+ // Fill in a given object with default properties.
+ _.defaults = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ for (var i = 1, length = arguments.length; i < length; i++) {
+ var source = arguments[i];
+ for (var prop in source) {
+ if (obj[prop] === void 0) obj[prop] = source[prop];
+ }
+ }
+ return obj;
+ };
+
+ // Create a (shallow-cloned) duplicate of an object.
+ _.clone = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+ };
+
+ // Invokes interceptor with the obj, and then returns obj.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
+ _.tap = function(obj, interceptor) {
+ interceptor(obj);
+ return obj;
+ };
+
+ // Internal recursive comparison function for `isEqual`.
+ var eq = function(a, b, aStack, bStack) {
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+ if (a === b) return a !== 0 || 1 / a === 1 / b;
+ // A strict comparison is necessary because `null == undefined`.
+ if (a == null || b == null) return a === b;
+ // Unwrap any wrapped objects.
+ if (a instanceof _) a = a._wrapped;
+ if (b instanceof _) b = b._wrapped;
+ // Compare `[[Class]]` names.
+ var className = toString.call(a);
+ if (className !== toString.call(b)) return false;
+ switch (className) {
+ // Strings, numbers, regular expressions, dates, and booleans are compared by value.
+ case '[object RegExp]':
+ // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return '' + a === '' + b;
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive.
+ // Object(NaN) is equivalent to NaN
+ if (+a !== +a) return +b !== +b;
+ // An `egal` comparison is performed for other numeric values.
+ return +a === 0 ? 1 / +a === 1 / b : +a === +b;
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a === +b;
+ }
+ if (typeof a != 'object' || typeof b != 'object') return false;
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+ var length = aStack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (aStack[length] === a) return bStack[length] === b;
+ }
+ // Objects with different constructors are not equivalent, but `Object`s
+ // from different frames are.
+ var aCtor = a.constructor, bCtor = b.constructor;
+ if (
+ aCtor !== bCtor &&
+ // Handle Object.create(x) cases
+ 'constructor' in a && 'constructor' in b &&
+ !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
+ _.isFunction(bCtor) && bCtor instanceof bCtor)
+ ) {
+ return false;
+ }
+ // Add the first object to the stack of traversed objects.
+ aStack.push(a);
+ bStack.push(b);
+ var size, result;
+ // Recursively compare objects and arrays.
+ if (className === '[object Array]') {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ size = a.length;
+ result = size === b.length;
+ if (result) {
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (size--) {
+ if (!(result = eq(a[size], b[size], aStack, bStack))) break;
+ }
+ }
+ } else {
+ // Deep compare objects.
+ var keys = _.keys(a), key;
+ size = keys.length;
+ // Ensure that both objects contain the same number of properties before comparing deep equality.
+ result = _.keys(b).length === size;
+ if (result) {
+ while (size--) {
+ // Deep compare each member
+ key = keys[size];
+ if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
+ }
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ aStack.pop();
+ bStack.pop();
+ return result;
+ };
+
+ // Perform a deep comparison to check if two objects are equal.
+ _.isEqual = function(a, b) {
+ return eq(a, b, [], []);
+ };
+
+ // Is a given array, string, or object empty?
+ // An "empty" object has no enumerable own-properties.
+ _.isEmpty = function(obj) {
+ if (obj == null) return true;
+ if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0;
+ for (var key in obj) if (_.has(obj, key)) return false;
+ return true;
+ };
+
+ // Is a given value a DOM element?
+ _.isElement = function(obj) {
+ return !!(obj && obj.nodeType === 1);
+ };
+
+ // Is a given value an array?
+ // Delegates to ECMA5's native Array.isArray
+ _.isArray = nativeIsArray || function(obj) {
+ return toString.call(obj) === '[object Array]';
+ };
+
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ var type = typeof obj;
+ return type === 'function' || type === 'object' && !!obj;
+ };
+
+ // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
+ _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
+ _['is' + name] = function(obj) {
+ return toString.call(obj) === '[object ' + name + ']';
+ };
+ });
+
+ // Define a fallback version of the method in browsers (ahem, IE), where
+ // there isn't any inspectable "Arguments" type.
+ if (!_.isArguments(arguments)) {
+ _.isArguments = function(obj) {
+ return _.has(obj, 'callee');
+ };
+ }
+
+ // Optimize `isFunction` if appropriate. Work around an IE 11 bug.
+ if (typeof /./ !== 'function') {
+ _.isFunction = function(obj) {
+ return typeof obj == 'function' || false;
+ };
+ }
+
+ // Is a given object a finite number?
+ _.isFinite = function(obj) {
+ return isFinite(obj) && !isNaN(parseFloat(obj));
+ };
+
+ // Is the given value `NaN`? (NaN is the only number which does not equal itself).
+ _.isNaN = function(obj) {
+ return _.isNumber(obj) && obj !== +obj;
+ };
+
+ // Is a given value a boolean?
+ _.isBoolean = function(obj) {
+ return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
+ };
+
+ // Is a given value equal to null?
+ _.isNull = function(obj) {
+ return obj === null;
+ };
+
+ // Is a given variable undefined?
+ _.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ // Shortcut function for checking if an object has a given property directly
+ // on itself (in other words, not on a prototype).
+ _.has = function(obj, key) {
+ return obj != null && hasOwnProperty.call(obj, key);
+ };
+
+ // Utility Functions
+ // -----------------
+
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+ // previous owner. Returns a reference to the Underscore object.
+ _.noConflict = function() {
+ root._ = previousUnderscore;
+ return this;
+ };
+
+ // Keep the identity function around for default iteratees.
+ _.identity = function(value) {
+ return value;
+ };
+
+ _.constant = function(value) {
+ return function() {
+ return value;
+ };
+ };
+
+ _.noop = function(){};
+
+ _.property = function(key) {
+ return function(obj) {
+ return obj[key];
+ };
+ };
+
+ // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
+ _.matches = function(attrs) {
+ var pairs = _.pairs(attrs), length = pairs.length;
+ return function(obj) {
+ if (obj == null) return !length;
+ obj = new Object(obj);
+ for (var i = 0; i < length; i++) {
+ var pair = pairs[i], key = pair[0];
+ if (pair[1] !== obj[key] || !(key in obj)) return false;
+ }
+ return true;
+ };
+ };
+
+ // Run a function **n** times.
+ _.times = function(n, iteratee, context) {
+ var accum = Array(Math.max(0, n));
+ iteratee = createCallback(iteratee, context, 1);
+ for (var i = 0; i < n; i++) accum[i] = iteratee(i);
+ return accum;
+ };
+
+ // Return a random integer between min and max (inclusive).
+ _.random = function(min, max) {
+ if (max == null) {
+ max = min;
+ min = 0;
+ }
+ return min + Math.floor(Math.random() * (max - min + 1));
+ };
+
+ // A (possibly faster) way to get the current timestamp as an integer.
+ _.now = Date.now || function() {
+ return new Date().getTime();
+ };
+
+ // List of HTML entities for escaping.
+ var escapeMap = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": ''',
+ '`': '`'
+ };
+ var unescapeMap = _.invert(escapeMap);
+
+ // Functions for escaping and unescaping strings to/from HTML interpolation.
+ var createEscaper = function(map) {
+ var escaper = function(match) {
+ return map[match];
+ };
+ // Regexes for identifying a key that needs to be escaped
+ var source = '(?:' + _.keys(map).join('|') + ')';
+ var testRegexp = RegExp(source);
+ var replaceRegexp = RegExp(source, 'g');
+ return function(string) {
+ string = string == null ? '' : '' + string;
+ return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
+ };
+ };
+ _.escape = createEscaper(escapeMap);
+ _.unescape = createEscaper(unescapeMap);
+
+ // If the value of the named `property` is a function then invoke it with the
+ // `object` as context; otherwise, return it.
+ _.result = function(object, property) {
+ if (object == null) return void 0;
+ var value = object[property];
+ return _.isFunction(value) ? object[property]() : value;
+ };
+
+ // Generate a unique integer id (unique within the entire client session).
+ // Useful for temporary DOM ids.
+ var idCounter = 0;
+ _.uniqueId = function(prefix) {
+ var id = ++idCounter + '';
+ return prefix ? prefix + id : id;
+ };
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g,
+ escape : /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /(.)^/;
+
+ // Certain characters need to be escaped so that they can be put into a
+ // string literal.
+ var escapes = {
+ "'": "'",
+ '\\': '\\',
+ '\r': 'r',
+ '\n': 'n',
+ '\u2028': 'u2028',
+ '\u2029': 'u2029'
+ };
+
+ var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
+
+ var escapeChar = function(match) {
+ return '\\' + escapes[match];
+ };
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ // NB: `oldSettings` only exists for backwards compatibility.
+ _.template = function(text, settings, oldSettings) {
+ if (!settings && oldSettings) settings = oldSettings;
+ settings = _.defaults({}, settings, _.templateSettings);
+
+ // Combine delimiters into one regular expression via alternation.
+ var matcher = RegExp([
+ (settings.escape || noMatch).source,
+ (settings.interpolate || noMatch).source,
+ (settings.evaluate || noMatch).source
+ ].join('|') + '|$', 'g');
+
+ // Compile the template source, escaping string literals appropriately.
+ var index = 0;
+ var source = "__p+='";
+ text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+ source += text.slice(index, offset).replace(escaper, escapeChar);
+ index = offset + match.length;
+
+ if (escape) {
+ source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
+ } else if (interpolate) {
+ source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
+ } else if (evaluate) {
+ source += "';\n" + evaluate + "\n__p+='";
+ }
+
+ // Adobe VMs need the match returned to produce the correct offest.
+ return match;
+ });
+ source += "';\n";
+
+ // If a variable is not specified, place data values in local scope.
+ if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
+
+ source = "var __t,__p='',__j=Array.prototype.join," +
+ "print=function(){__p+=__j.call(arguments,'');};\n" +
+ source + 'return __p;\n';
+
+ try {
+ var render = new Function(settings.variable || 'obj', '_', source);
+ } catch (e) {
+ e.source = source;
+ throw e;
+ }
+
+ var template = function(data) {
+ return render.call(this, data, _);
+ };
+
+ // Provide the compiled source as a convenience for precompilation.
+ var argument = settings.variable || 'obj';
+ template.source = 'function(' + argument + '){\n' + source + '}';
+
+ return template;
+ };
+
+ // Add a "chain" function. Start chaining a wrapped Underscore object.
+ _.chain = function(obj) {
+ var instance = _(obj);
+ instance._chain = true;
+ return instance;
+ };
+
+ // OOP
+ // ---------------
+ // If Underscore is called as a function, it returns a wrapped object that
+ // can be used OO-style. This wrapper holds altered versions of all the
+ // underscore functions. Wrapped objects may be chained.
+
+ // Helper function to continue chaining intermediate results.
+ var result = function(obj) {
+ return this._chain ? _(obj).chain() : obj;
+ };
+
+ // Add your own custom functions to the Underscore object.
+ _.mixin = function(obj) {
+ _.each(_.functions(obj), function(name) {
+ var func = _[name] = obj[name];
+ _.prototype[name] = function() {
+ var args = [this._wrapped];
+ push.apply(args, arguments);
+ return result.call(this, func.apply(_, args));
+ };
+ });
+ };
+
+ // Add all of the Underscore functions to the wrapper object.
+ _.mixin(_);
+
+ // Add all mutator Array functions to the wrapper.
+ _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ var obj = this._wrapped;
+ method.apply(obj, arguments);
+ if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
+ return result.call(this, obj);
+ };
+ });
+
+ // Add all accessor Array functions to the wrapper.
+ _.each(['concat', 'join', 'slice'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ return result.call(this, method.apply(this._wrapped, arguments));
+ };
+ });
+
+ // Extracts the result from a wrapped and chained object.
+ _.prototype.value = function() {
+ return this._wrapped;
+ };
+
+ // AMD registration happens at the end for compatibility with AMD loaders
+ // that may not enforce next-turn semantics on modules. Even though general
+ // practice for AMD registration is to be anonymous, underscore registers
+ // as a named module because, like jQuery, it is a base library that is
+ // popular enough to be bundled in a third party lib, but not be part of
+ // an AMD load request. Those cases could generate an error when an
+ // anonymous define() is called outside of a loader request.
+ if (typeof define === 'function' && define.amd) {
+ define('underscore', [], function() {
+ return _;
+ });
+ }
+}.call(this));
+
+},{}],60:[function(require,module,exports){
+var _;
+
+_ = require("underscore");
+
+module.exports = function(seqs) {
+ var occs;
+ seqs = seqs.map(function(el) {
+ return el.get("seq");
+ });
+ occs = new Array(seqs.length);
+ _.each(seqs, function(el, i) {
+ return _.each(el, function(char, pos) {
+ if (occs[pos] == null) {
+ occs[pos] = {};
+ }
+ if (occs[pos][char] == null) {
+ occs[pos][char] = 0;
+ }
+ return occs[pos][char]++;
+ });
+ });
+ return _.reduce(occs, function(memo, occ) {
+ var keys;
+ keys = _.keys(occ);
+ return memo += _.max(keys, function(key) {
+ return occ[key];
+ });
+ }, "");
+};
+
+
+
+},{"underscore":59}],61:[function(require,module,exports){
+var identitiyCalc;
+
+module.exports = identitiyCalc = function(seqs, consensus) {
+ if (consensus === void 0) {
+ console.warn("bug on consenus calc");
+ return;
+ }
+ return seqs.each(function(seqObj) {
+ var i, matches, seq, total, _i, _ref;
+ seq = seqObj.get("seq");
+ matches = 0;
+ total = 0;
+ for (i = _i = 0, _ref = seq.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ if (seq[i] !== "-" && consensus[i] !== "-") {
+ total++;
+ if (seq[i] === consensus[i]) {
+ matches++;
+ }
+ }
+ }
+ return seqObj.set("identity", matches / total);
+ });
+};
+
+
+
+},{}],62:[function(require,module,exports){
+module.exports.consensus = require("./ConsensusCalc");
+
+
+
+},{"./ConsensusCalc":60}],63:[function(require,module,exports){
+var Colorator, Model;
+
+Model = require("backbone-thin").Model;
+
+module.exports = Colorator = Model.extend({
+ defaults: {
+ scheme: "taylor",
+ colorBackground: true,
+ showLowerCase: true,
+ opacity: 0.6
+ }
+});
+
+
+
+},{"backbone-thin":5}],64:[function(require,module,exports){
+var Columns, Model, consenus, _;
+
+Model = require("backbone-thin").Model;
+
+consenus = require("../algo/ConsensusCalc");
+
+_ = require("underscore");
+
+module.exports = Columns = Model.extend({
+ defaults: {
+ scaling: "lin"
+ },
+ initialize: function() {
+ if (this.get("hidden") == null) {
+ return this.set("hidden", []);
+ }
+ },
+ calcHiddenColumns: function(n) {
+ var hidden, i, newX, _i, _len;
+ hidden = this.get("hidden");
+ newX = n;
+ for (_i = 0, _len = hidden.length; _i < _len; _i++) {
+ i = hidden[_i];
+ if (i <= newX) {
+ newX++;
+ }
+ }
+ return newX - n;
+ },
+ _calcConservationPre: function(seqs) {
+ var cons, matches, nMax, total;
+ console.log(seqs.length);
+ if (seqs.length > 1000) {
+ return;
+ }
+ cons = consenus(seqs);
+ seqs = seqs.map(function(el) {
+ return el.get("seq");
+ });
+ nMax = (_.max(seqs, function(el) {
+ return el.length;
+ })).length;
+ total = new Array(nMax);
+ matches = new Array(nMax);
+ _.each(seqs, function(el, i) {
+ return _.each(el, function(char, pos) {
+ total[pos] = total[pos] + 1 || 1;
+ if (cons[pos] === char) {
+ return matches[pos] = matches[pos] + 1 || 1;
+ }
+ });
+ });
+ return [matches, total, nMax];
+ },
+ calcConservation: function(seqs) {
+ if (this.attributes.scaling === "exp") {
+ return this.calcConservationExp(seqs);
+ } else if (this.attributes.scaling === "log") {
+ return this.calcConservationLog(seqs);
+ } else if (this.attributes.scaling === "lin") {
+ return this.calcConservationLin(seqs);
+ }
+ },
+ calcConservationLin: function(seqs) {
+ var i, matches, nMax, total, _i, _ref, _ref1;
+ _ref = this._calcConservationPre(seqs), matches = _ref[0], total = _ref[1], nMax = _ref[2];
+ for (i = _i = 0, _ref1 = nMax - 1; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
+ matches[i] = matches[i] / total[i];
+ }
+ this.set("conserv", matches);
+ return matches;
+ },
+ calcConservationLog: function(seqs) {
+ var i, matches, nMax, total, _i, _ref, _ref1;
+ _ref = this._calcConservationPre(seqs), matches = _ref[0], total = _ref[1], nMax = _ref[2];
+ for (i = _i = 0, _ref1 = nMax - 1; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
+ matches[i] = Math.log(matches[i] + 1) / Math.log(total[i] + 1);
+ }
+ this.set("conserv", matches);
+ return matches;
+ },
+ calcConservationExp: function(seqs) {
+ var i, matches, nMax, total, _i, _ref, _ref1;
+ _ref = this._calcConservationPre(seqs), matches = _ref[0], total = _ref[1], nMax = _ref[2];
+ for (i = _i = 0, _ref1 = nMax - 1; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
+ matches[i] = Math.exp(matches[i] + 1) / Math.exp(total[i] + 1);
+ }
+ this.set("conserv", matches);
+ return matches;
+ }
+});
+
+
+
+},{"../algo/ConsensusCalc":60,"backbone-thin":5,"underscore":59}],65:[function(require,module,exports){
+var Config, Model;
+
+Model = require("backbone-thin").Model;
+
+module.exports = Config = Model.extend({
+ defaults: {
+ registerMouseHover: false,
+ registerMouseClicks: true,
+ importProxy: "https://cors-anywhere.herokuapp.com/",
+ eventBus: true
+ }
+});
+
+
+
+},{"backbone-thin":5}],66:[function(require,module,exports){
+var Consenus, Model, consenusCalc;
+
+Model = require("backbone-thin").Model;
+
+consenusCalc = require("../algo/ConsensusCalc");
+
+module.exports = Consenus = Model.extend({
+ defaults: {
+ consenus: ""
+ },
+ getConsensus: function(seqs) {
+ var cons;
+ if (seqs.length > 1000) {
+ return;
+ }
+ cons = consenusCalc(seqs);
+ this.set("consenus", cons);
+ return cons;
+ }
+});
+
+
+
+},{"../algo/ConsensusCalc":60,"backbone-thin":5}],67:[function(require,module,exports){
+var ColumnSelection, Model, PosSelection, RowSelection, Selection, _;
+
+_ = require("underscore");
+
+Model = require("backbone-thin").Model;
+
+Selection = Model.extend({
+ defaults: {
+ type: "super"
+ }
+});
+
+RowSelection = Selection.extend({
+ defaults: _.extend({}, Selection.prototype.defaults, {
+ type: "row",
+ seqId: ""
+ }),
+ inRow: function(seqId) {
+ return seqId === this.get("seqId");
+ },
+ inColumn: function(rowPos) {
+ return true;
+ },
+ getLength: function() {
+ return 1;
+ }
+});
+
+ColumnSelection = Selection.extend({
+ defaults: _.extend({}, Selection.prototype.defaults, {
+ type: "column",
+ xStart: -1,
+ xEnd: -1
+ }),
+ inRow: function() {
+ return true;
+ },
+ inColumn: function(rowPos) {
+ return xStart <= rowPos && rowPos <= xEnd;
+ },
+ getLength: function() {
+ return xEnd - xStart;
+ }
+});
+
+PosSelection = RowSelection.extend(_.extend({}, _.pick(ColumnSelection, "inColumn"), _.pick(ColumnSelection, "getLength"), {
+ defaults: _.extend({}, ColumnSelection.prototype.defaults, RowSelection.prototype.defaults, {
+ type: "pos"
+ })
+}));
+
+module.exports.sel = Selection;
+
+module.exports.possel = PosSelection;
+
+module.exports.rowsel = RowSelection;
+
+module.exports.columnsel = ColumnSelection;
+
+
+
+},{"backbone-thin":5,"underscore":59}],68:[function(require,module,exports){
+var Collection, SelectionManager, sel, _;
+
+sel = require("./Selection");
+
+_ = require("underscore");
+
+Collection = require("backbone-thin").Collection;
+
+module.exports = SelectionManager = Collection.extend({
+ model: sel.sel,
+ initialize: function(data, opts) {
+ this.g = opts.g;
+ this.listenTo(this.g, "residue:click", function(e) {
+ return this._handleE(e.evt, new sel.possel({
+ xStart: e.rowPos,
+ xEnd: e.rowPos,
+ seqId: e.seqId
+ }));
+ });
+ this.listenTo(this.g, "row:click", function(e) {
+ return this._handleE(e.evt, new sel.rowsel({
+ xStart: e.rowPos,
+ xEnd: e.rowPos,
+ seqId: e.seqId
+ }));
+ });
+ return this.listenTo(this.g, "column:click", function(e) {
+ return this._handleE(e.evt, new sel.columnsel({
+ xStart: e.rowPos,
+ xEnd: e.rowPos + e.stepSize - 1
+ }));
+ });
+ },
+ getSelForRow: function(seqId) {
+ return this.filter(function(el) {
+ return el.inRow(seqId);
+ });
+ },
+ getSelForColumns: function(rowPos) {
+ return this.filter(function(el) {
+ return el.inColumn(rowPos);
+ });
+ },
+ getBlocksForRow: function(seqId, maxLen) {
+ var blocks, seli, selis, _i, _j, _k, _len, _ref, _ref1, _results, _results1;
+ selis = this.filter(function(el) {
+ return el.inRow(seqId);
+ });
+ blocks = [];
+ for (_i = 0, _len = selis.length; _i < _len; _i++) {
+ seli = selis[_i];
+ if (seli.attributes.type === "row") {
+ blocks = (function() {
+ _results = [];
+ for (var _j = 0; 0 <= maxLen ? _j <= maxLen : _j >= maxLen; 0 <= maxLen ? _j++ : _j--){ _results.push(_j); }
+ return _results;
+ }).apply(this);
+ break;
+ } else {
+ blocks = blocks.concat((function() {
+ _results1 = [];
+ for (var _k = _ref = seli.attributes.xStart, _ref1 = seli.attributes.xEnd; _ref <= _ref1 ? _k <= _ref1 : _k >= _ref1; _ref <= _ref1 ? _k++ : _k--){ _results1.push(_k); }
+ return _results1;
+ }).apply(this));
+ }
+ }
+ return blocks;
+ },
+ getAllColumnBlocks: function(conf) {
+ var blocks, filtered, maxLen, seli, withPos, _i, _j, _len, _ref, _ref1, _results;
+ maxLen = conf.maxLen;
+ withPos = conf.withPos;
+ blocks = [];
+ if (conf.withPos) {
+ filtered = this.filter(function(el) {
+ return el.get('xStart') != null;
+ });
+ } else {
+ filtered = this.filter(function(el) {
+ return el.get('type') === "column";
+ });
+ }
+ for (_i = 0, _len = filtered.length; _i < _len; _i++) {
+ seli = filtered[_i];
+ blocks = blocks.concat((function() {
+ _results = [];
+ for (var _j = _ref = seli.attributes.xStart, _ref1 = seli.attributes.xEnd; _ref <= _ref1 ? _j <= _ref1 : _j >= _ref1; _ref <= _ref1 ? _j++ : _j--){ _results.push(_j); }
+ return _results;
+ }).apply(this));
+ }
+ blocks = _.uniq(blocks);
+ return blocks;
+ },
+ invertRow: function(rows) {
+ var el, inverted, s, selRows, _i, _len;
+ selRows = this.where({
+ type: "row"
+ });
+ selRows = _.map(selRows, function(el) {
+ return el.attributes.seqId;
+ });
+ inverted = _.filter(rows, function(el) {
+ if (selRows.indexOf(el) >= 0) {
+ return false;
+ }
+ return true;
+ });
+ s = [];
+ for (_i = 0, _len = inverted.length; _i < _len; _i++) {
+ el = inverted[_i];
+ s.push(new sel.rowsel({
+ seqId: el
+ }));
+ }
+ console.log(s);
+ return this.reset(s);
+ },
+ invertCol: function(columns) {
+ var el, inverted, s, selColumns, xEnd, xStart, _i, _len;
+ selColumns = this.where({
+ type: "column"
+ });
+ selColumns = _.reduce(selColumns, function(memo, el) {
+ var _i, _ref, _ref1, _results;
+ return memo.concat((function() {
+ _results = [];
+ for (var _i = _ref = el.attributes.xStart, _ref1 = el.attributes.xEnd; _ref <= _ref1 ? _i <= _ref1 : _i >= _ref1; _ref <= _ref1 ? _i++ : _i--){ _results.push(_i); }
+ return _results;
+ }).apply(this));
+ }, []);
+ inverted = _.filter(columns, function(el) {
+ if (selColumns.indexOf(el) >= 0) {
+ return false;
+ }
+ return true;
+ });
+ if (inverted.length === 0) {
+ return;
+ }
+ s = [];
+ console.log(inverted);
+ xStart = xEnd = inverted[0];
+ for (_i = 0, _len = inverted.length; _i < _len; _i++) {
+ el = inverted[_i];
+ if (xEnd + 1 === el) {
+ xEnd = el;
+ } else {
+ s.push(new sel.columnsel({
+ xStart: xStart,
+ xEnd: xEnd
+ }));
+ xStart = xEnd = el;
+ }
+ }
+ if (xStart !== xEnd) {
+ s.push(new sel.columnsel({
+ xStart: xStart,
+ xEnd: inverted[inverted.length - 1]
+ }));
+ }
+ return this.reset(s);
+ },
+ _handleE: function(e, selection) {
+ if (e.ctrlKey || e.metaKey) {
+ return this.add(selection);
+ } else {
+ return this.reset([selection]);
+ }
+ },
+ _reduceColumns: function() {
+ return this.each(function(el, index, arr) {
+ var cols, left, lefts, right, rights, xEnd, xStart, _i, _j, _len, _len1;
+ cols = _.filter(arr, function(el) {
+ return el.get('type') === 'column';
+ });
+ xStart = el.get('xStart');
+ xEnd = el.get('xEnd');
+ lefts = _.filter(cols, function(el) {
+ return el.get('xEnd') === (xStart - 1);
+ });
+ for (_i = 0, _len = lefts.length; _i < _len; _i++) {
+ left = lefts[_i];
+ left.set('xEnd', xStart);
+ }
+ rights = _.filter(cols, function(el) {
+ return el.get('xStart') === (xEnd + 1);
+ });
+ for (_j = 0, _len1 = rights.length; _j < _len1; _j++) {
+ right = rights[_j];
+ right.set('xStart', xEnd);
+ }
+ if (lefts.length > 0 || rights.length > 0) {
+ console.log("removed el");
+ return el.collection.remove(el);
+ }
+ });
+ }
+});
+
+
+
+},{"./Selection":67,"backbone-thin":5,"underscore":59}],69:[function(require,module,exports){
+var Model, Visibility;
+
+Model = require("backbone-thin").Model;
+
+module.exports = Visibility = Model.extend({
+ defaults: {
+ overviewBox: 30,
+ headerBox: -1,
+ alignmentBody: 0
+ }
+});
+
+
+
+},{"backbone-thin":5}],70:[function(require,module,exports){
+var Model, Visibility;
+
+Model = require("backbone-thin").Model;
+
+module.exports = Visibility = Model.extend({
+ defaults: {
+ sequences: true,
+ markers: true,
+ metacell: false,
+ conserv: true,
+ overviewbox: false,
+ labels: true,
+ labelName: true,
+ labelId: true,
+ labelPartition: false,
+ labelCheckbox: false
+ }
+});
+
+
+
+},{"backbone-thin":5}],71:[function(require,module,exports){
+var Model, Zoomer;
+
+Model = require("backbone-thin").Model;
+
+module.exports = Zoomer = Model.extend({
+ constructor: function(attributes, options) {
+ Model.apply(this, arguments);
+ this.g = options.g;
+ return this;
+ },
+ defaults: {
+ alignmentWidth: "auto",
+ alignmentHeight: 195,
+ columnWidth: 15,
+ rowHeight: 15,
+ labelWidth: 100,
+ metaWidth: 100,
+ textVisible: true,
+ labelIdLength: 30,
+ labelFontsize: "13px",
+ labelLineHeight: "13px",
+ markerFontsize: "10px",
+ stepSize: 1,
+ markerStepSize: 2,
+ residueFont: "13px mono",
+ canvasEventScale: 1,
+ boxRectHeight: 5,
+ boxRectWidth: 5,
+ menuFontsize: "20px",
+ menuItemFontsize: "18px",
+ menuItemLineHeight: "18px",
+ menuMarginLeft: "5px",
+ menuPadding: "3px 5px 3px 5px",
+ _alignmentScrollLeft: 0,
+ _alignmentScrollTop: 0
+ },
+ getAlignmentWidth: function(n) {
+ if (this.get("alignmentWidth") === "auto") {
+ return this.get("columnWidth") * n;
+ } else {
+ return this.get("alignmentWidth");
+ }
+ },
+ setLeftOffset: function(n) {
+ var val;
+ val = (n - 1) * this.get('columnWidth');
+ val = Math.max(0, val);
+ return this.set("_alignmentScrollLeft", val);
+ },
+ setTopOffset: function(n) {
+ var val;
+ val = (n - 1) * this.get('rowHeight');
+ val = Math.max(0, val);
+ return this.set("_alignmentScrollTop", val);
+ },
+ getLabelWidth: function() {
+ var paddingLeft;
+ paddingLeft = 0;
+ if (this.g.vis.get("labels")) {
+ paddingLeft += this.get("labelWidth");
+ }
+ if (this.g.vis.get("metacell")) {
+ paddingLeft += this.get("metaWidth");
+ }
+ return paddingLeft;
+ },
+ _adjustWidth: function(el, model) {
+ var calcWidth, maxWidth, parentWidth, val;
+ if ((el.parentNode != null) && el.parentNode.offsetWidth !== 0) {
+ parentWidth = el.parentNode.offsetWidth;
+ } else {
+ parentWidth = document.body.clientWidth - 35;
+ }
+ maxWidth = parentWidth - this.getLabelWidth();
+ calcWidth = this.getAlignmentWidth(model.getMaxLength() - this.g.columns.get('hidden').length);
+ val = Math.min(maxWidth, calcWidth);
+ val = Math.floor(val / this.get("columnWidth")) * this.get("columnWidth");
+ return this.set("alignmentWidth", val);
+ },
+ _checkScrolling: function(scrollObj, opts) {
+ var xScroll, yScroll;
+ xScroll = scrollObj[0];
+ yScroll = scrollObj[1];
+ this.set("_alignmentScrollLeft", xScroll, opts);
+ return this.set("_alignmentScrollTop", yScroll, opts);
+ }
+});
+
+
+
+},{"backbone-thin":5}],72:[function(require,module,exports){
+module.exports.msa = require("./msa");
+
+module.exports.model = require("./model");
+
+module.exports.algo = require("./algo");
+
+module.exports.menu = require("./menu");
+
+module.exports.utils = require("./utils");
+
+module.exports.selection = require("./g/selection/Selection");
+
+module.exports.view = require("backbone-viewj");
+
+module.exports.boneView = require("backbone-childs");
+
+module.exports._ = require('underscore');
+
+module.exports.$ = require('jbone');
+
+module.exports.version = "0.1.0";
+
+
+
+},{"./algo":62,"./g/selection/Selection":67,"./menu":74,"./model":89,"./msa":90,"./utils":92,"backbone-childs":3,"backbone-viewj":10,"jbone":50,"underscore":59}],73:[function(require,module,exports){
+var ColorMenu, ExportMenu, ExtraMenu, FilterMenu, HelpMenu, ImportMenu, MenuView, OrderingMenu, SelectionMenu, VisMenu, boneView;
+
+boneView = require("backbone-childs");
+
+ImportMenu = require("./views/ImportMenu");
+
+FilterMenu = require("./views/FilterMenu");
+
+SelectionMenu = require("./views/SelectionMenu");
+
+VisMenu = require("./views/VisMenu");
+
+ColorMenu = require("./views/ColorMenu");
+
+OrderingMenu = require("./views/OrderingMenu");
+
+ExtraMenu = require("./views/ExtraMenu");
+
+ExportMenu = require("./views/ExportMenu");
+
+HelpMenu = require("./views/HelpMenu");
+
+module.exports = MenuView = boneView.extend({
+ initialize: function(data) {
+ this.msa = data.msa;
+ this.addView("10_import", new ImportMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("20_filter", new FilterMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("30_selection", new SelectionMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("40_vis", new VisMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("50_color", new ColorMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("60_ordering", new OrderingMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("70_extra", new ExtraMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("80_export", new ExportMenu({
+ model: this.msa.seqs,
+ g: this.msa.g,
+ msa: this.msa
+ }));
+ return this.addView("90_help", new HelpMenu({
+ g: this.msa.g
+ }));
+ },
+ render: function() {
+ this.renderSubviews();
+ this.el.setAttribute("class", "biojs_msa_menubar");
+ return this.el.appendChild(document.createElement("p"));
+ }
+});
+
+
+
+},{"./views/ColorMenu":76,"./views/ExportMenu":77,"./views/ExtraMenu":78,"./views/FilterMenu":79,"./views/HelpMenu":80,"./views/ImportMenu":81,"./views/OrderingMenu":82,"./views/SelectionMenu":83,"./views/VisMenu":84,"backbone-childs":3}],74:[function(require,module,exports){
+module.exports.defaultmenu = require("./defaultmenu");
+
+module.exports.menubuilder = require("./menubuilder");
+
+
+
+},{"./defaultmenu":73,"./menubuilder":75}],75:[function(require,module,exports){
+var BMath, MenuBuilder, jbone, view;
+
+BMath = require("../utils/bmath");
+
+jbone = require("jbone");
+
+view = require("backbone-viewj");
+
+module.exports = MenuBuilder = view.extend({
+ setName: function(name) {
+ this.name = name;
+ return this._nodes = [];
+ },
+ addNode: function(label, callback, data) {
+ var style;
+ if (data != null) {
+ style = data.style;
+ }
+ if (this._nodes == null) {
+ this._nodes = [];
+ }
+ return this._nodes.push({
+ label: label,
+ callback: callback,
+ style: style
+ });
+ },
+ buildDOM: function() {
+ return this._buildM({
+ nodes: this._nodes,
+ name: this.name
+ });
+ },
+ _buildM: function(data) {
+ var displayedButton, frag, key, li, menu, menuUl, name, node, nodes, style, _i, _len, _ref;
+ nodes = data.nodes;
+ name = data.name;
+ menu = document.createElement("div");
+ menu.className = "dropdown dropdown-tip";
+ menu.id = "adrop-" + BMath.uniqueId();
+ menu.style.display = "none";
+ menuUl = document.createElement("ul");
+ menuUl.className = "dropdown-menu";
+ for (_i = 0, _len = nodes.length; _i < _len; _i++) {
+ node = nodes[_i];
+ li = document.createElement("li");
+ li.textContent = node.label;
+ _ref = node.style;
+ for (key in _ref) {
+ style = _ref[key];
+ li.style[key] = style;
+ }
+ li.addEventListener("click", node.callback);
+ if (this.g != null) {
+ li.style.lineHeight = this.g.zoomer.get("menuItemLineHeight");
+ }
+ menuUl.appendChild(li);
+ }
+ menu.appendChild(menuUl);
+ frag = document.createDocumentFragment();
+ displayedButton = document.createElement("a");
+ displayedButton.textContent = name;
+ displayedButton.className = "biojs_msa_menubar_alink";
+ if (this.g != null) {
+ menuUl.style.fontSize = this.g.zoomer.get("menuItemFontsize");
+ displayedButton.style.fontSize = this.g.zoomer.get("menuFontsize");
+ displayedButton.style.marginLeft = this.g.zoomer.get("menuMarginLeft");
+ displayedButton.style.padding = this.g.zoomer.get("menuPadding");
+ }
+ jbone(displayedButton).on("click", (function(_this) {
+ return function(e) {
+ _this._showMenu(e, menu, displayedButton);
+ return window.setTimeout(function() {
+ return jbone(document.body).one("click", function(e) {
+ console.log("next click");
+ return menu.style.display = "none";
+ });
+ }, 5);
+ };
+ })(this));
+ frag.appendChild(menu);
+ frag.appendChild(displayedButton);
+ return frag;
+ },
+ _showMenu: function(e, menu, target) {
+ var rect;
+ menu.style.display = "block";
+ menu.style.position = "absolute";
+ rect = target.getBoundingClientRect();
+ menu.style.left = rect.left + "px";
+ return menu.style.top = (rect.top + target.offsetHeight) + "px";
+ }
+});
+
+
+
+},{"../utils/bmath":91,"backbone-viewj":10,"jbone":50}],76:[function(require,module,exports){
+var ColorMenu, MenuBuilder, dom, _;
+
+MenuBuilder = require("../menubuilder");
+
+_ = require("underscore");
+
+dom = require("dom-helper");
+
+module.exports = ColorMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.el.style.display = "inline-block";
+ return this.listenTo(this.g.colorscheme, "change", function() {
+ return this.render();
+ });
+ },
+ render: function() {
+ var colorschemes, menuColor, scheme, text, _i, _len;
+ menuColor = this.setName("Color scheme");
+ colorschemes = this.getColorschemes();
+ for (_i = 0, _len = colorschemes.length; _i < _len; _i++) {
+ scheme = colorschemes[_i];
+ this.addScheme(menuColor, scheme);
+ }
+ text = "Background";
+ if (this.g.colorscheme.get("colorBackground")) {
+ text = "Hide " + text;
+ } else {
+ text = "Show " + text;
+ }
+ this.addNode(text, (function(_this) {
+ return function() {
+ return _this.g.colorscheme.set("colorBackground", !_this.g.colorscheme.get("colorBackground"));
+ };
+ })(this));
+ this.grey(menuColor);
+ dom.removeAllChilds(this.el);
+ this.el.appendChild(this.buildDOM());
+ return this;
+ },
+ addScheme: function(menuColor, scheme) {
+ var current, style;
+ style = {};
+ current = this.g.colorscheme.get("scheme");
+ if (current === scheme.id) {
+ style.backgroundColor = "#77ED80";
+ }
+ return this.addNode(scheme.name, (function(_this) {
+ return function() {
+ return _this.g.colorscheme.set("scheme", scheme.id);
+ };
+ })(this), {
+ style: style
+ });
+ },
+ getColorschemes: function() {
+ var schemes;
+ schemes = [];
+ schemes.push({
+ name: "Zappo",
+ id: "zappo"
+ });
+ schemes.push({
+ name: "Taylor",
+ id: "taylor"
+ });
+ schemes.push({
+ name: "Hydrophobicity",
+ id: "hydro"
+ });
+ schemes.push({
+ name: "Lesk",
+ id: "lesk"
+ });
+ schemes.push({
+ name: "Cinema",
+ id: "cinema"
+ });
+ schemes.push({
+ name: "MAE",
+ id: "mae"
+ });
+ schemes.push({
+ name: "Clustal",
+ id: "clustal"
+ });
+ schemes.push({
+ name: "Clustal2",
+ id: "clustal2"
+ });
+ schemes.push({
+ name: "Turn",
+ id: "turn"
+ });
+ schemes.push({
+ name: "Strand",
+ id: "strand"
+ });
+ schemes.push({
+ name: "Buried",
+ id: "buried"
+ });
+ schemes.push({
+ name: "Helix",
+ id: "helix"
+ });
+ schemes.push({
+ name: "Nucleotide",
+ id: "nucleotide"
+ });
+ schemes.push({
+ name: "Purine",
+ id: "purine"
+ });
+ schemes.push({
+ name: "PID",
+ id: "pid"
+ });
+ schemes.push({
+ name: "No color",
+ id: "foo"
+ });
+ return schemes;
+ },
+ grey: function(menuColor) {
+ this.addNode("Grey", (function(_this) {
+ return function() {
+ _this.g.colorscheme.set("showLowerCase", false);
+ return _this.model.each(function(seq) {
+ var grey, residues;
+ residues = seq.get("seq");
+ grey = [];
+ _.each(residues, function(el, index) {
+ if (el === el.toLowerCase()) {
+ return grey.push(index);
+ }
+ });
+ return seq.set("grey", grey);
+ });
+ };
+ })(this));
+ this.addNode("Grey by threshold", (function(_this) {
+ return function() {
+ var conserv, grey, i, maxLen, threshold, _i, _ref;
+ threshold = prompt("Enter threshold (in percent)", 20);
+ threshold = threshold / 100;
+ maxLen = _this.model.getMaxLength();
+ conserv = _this.g.columns.get("conserv");
+ grey = [];
+ for (i = _i = 0, _ref = maxLen - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ console.log(conserv[i]);
+ if (conserv[i] < threshold) {
+ grey.push(i);
+ }
+ }
+ return _this.model.each(function(seq) {
+ return seq.set("grey", grey);
+ });
+ };
+ })(this));
+ this.addNode("Grey selection", (function(_this) {
+ return function() {
+ var maxLen;
+ maxLen = _this.model.getMaxLength();
+ return _this.model.each(function(seq) {
+ var blocks;
+ blocks = _this.g.selcol.getBlocksForRow(seq.get("id"), maxLen);
+ return seq.set("grey", blocks);
+ });
+ };
+ })(this));
+ return this.addNode("Reset grey", (function(_this) {
+ return function() {
+ _this.g.colorscheme.set("showLowerCase", true);
+ return _this.model.each(function(seq) {
+ return seq.set("grey", []);
+ });
+ };
+ })(this));
+ }
+});
+
+
+
+},{"../menubuilder":75,"dom-helper":49,"underscore":59}],77:[function(require,module,exports){
+var ExportMenu, FastaExporter, MenuBuilder, blobURL, saveAs, _;
+
+MenuBuilder = require("../menubuilder");
+
+saveAs = require("browser-saveas");
+
+FastaExporter = require("biojs-io-fasta").writer;
+
+_ = require("underscore");
+
+blobURL = require("blueimp_canvastoblob");
+
+module.exports = ExportMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.msa = data.msa;
+ return this.el.style.display = "inline-block";
+ },
+ render: function() {
+ this.setName("Export");
+ this.addNode("Export sequences", (function(_this) {
+ return function() {
+ var blob, text;
+ text = FastaExporter["export"](_this.model.toJSON());
+ blob = new Blob([text], {
+ type: 'text/plain'
+ });
+ return saveAs(blob, "all.fasta");
+ };
+ })(this));
+ this.addNode("Export selection", (function(_this) {
+ return function() {
+ var blob, i, selection, text, _i, _ref;
+ selection = _this.g.selcol.pluck("seqId");
+ if (selection != null) {
+ selection = _this.model.filter(function(el) {
+ return _.contains(selection, el.get("id"));
+ });
+ for (i = _i = 0, _ref = selection.length - 1; _i <= _ref; i = _i += 1) {
+ selection[i] = selection[i].toJSON();
+ }
+ } else {
+ selection = _this.model.toJSON();
+ console.log("no selection found");
+ }
+ text = FastaExporter["export"](selection);
+ blob = new Blob([text], {
+ type: 'text/plain'
+ });
+ return saveAs(blob, "selection.fasta");
+ };
+ })(this));
+ this.addNode("Export image", (function(_this) {
+ return function() {
+ var canvas, url;
+ canvas = _this.msa.getView('stage').getView('body').getView('seqblock').el;
+ if (canvas != null) {
+ url = canvas.toDataURL('image/png');
+ return saveAs(blobURL(url), "biojs-msa.png", "image/png");
+ }
+ };
+ })(this));
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../menubuilder":75,"biojs-io-fasta":undefined,"blueimp_canvastoblob":46,"browser-saveas":47,"underscore":59}],78:[function(require,module,exports){
+var ExtraMenu, MenuBuilder, Seq, consenus;
+
+MenuBuilder = require("../menubuilder");
+
+consenus = require("../../algo/ConsensusCalc");
+
+Seq = require("../../model/Sequence");
+
+module.exports = ExtraMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ return this.el.style.display = "inline-block";
+ },
+ render: function() {
+ this.setName("Extras");
+ this.addNode("Add consensus seq", (function(_this) {
+ return function() {
+ var con, seq;
+ con = consenus(_this.model);
+ console.log(con);
+ seq = new Seq({
+ seq: con,
+ id: "0c",
+ name: "consenus"
+ });
+ _this.model.add(seq);
+ _this.model.comparator = function(seq) {
+ return seq.get("id");
+ };
+ return _this.model.sort();
+ };
+ })(this));
+ this.addNode("Increase font size", (function(_this) {
+ return function() {
+ _this.g.zoomer.set("columnWidth", _this.g.zoomer.get("columnWidth") + 2);
+ _this.g.zoomer.set("labelWidth", _this.g.zoomer.get("columnWidth") + 5);
+ _this.g.zoomer.set("rowHeight", _this.g.zoomer.get("rowHeight") + 2);
+ return _this.g.zoomer.set("labelFontSize", _this.g.zoomer.get("labelFontSize") + 2);
+ };
+ })(this));
+ this.addNode("Decrease font size", (function(_this) {
+ return function() {
+ _this.g.zoomer.set("columnWidth", _this.g.zoomer.get("columnWidth") - 2);
+ _this.g.zoomer.set("rowHeight", _this.g.zoomer.get("rowHeight") - 2);
+ _this.g.zoomer.set("labelFontSize", _this.g.zoomer.get("labelFontSize") - 2);
+ if (_this.g.zoomer.get("columnWidth") < 8) {
+ return _this.g.zoomer.set("textVisible", false);
+ }
+ };
+ })(this));
+ this.addNode("Bar chart exp scaling", (function(_this) {
+ return function() {
+ return _this.g.columns.set("scaling", "exp");
+ };
+ })(this));
+ this.addNode("Bar chart linear scaling", (function(_this) {
+ return function() {
+ return _this.g.columns.set("scaling", "lin");
+ };
+ })(this));
+ this.addNode("Bar chart log scaling", (function(_this) {
+ return function() {
+ return _this.g.columns.set("scaling", "log");
+ };
+ })(this));
+ this.addNode("Minimized width", (function(_this) {
+ return function() {
+ return _this.g.zoomer.set("alignmentWidth", 600);
+ };
+ })(this));
+ this.addNode("Minimized height", (function(_this) {
+ return function() {
+ return _this.g.zoomer.set("alignmentHeight", 120);
+ };
+ })(this));
+ this.addNode("Jump to a column", (function(_this) {
+ return function() {
+ var offset;
+ offset = prompt("Column", "20");
+ if (offset < 0 || offset > _this.model.getMaxLength() || isNaN(offset)) {
+ alert("invalid column");
+ return;
+ }
+ return _this.g.zoomer.setLeftOffset(offset);
+ };
+ })(this));
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../../algo/ConsensusCalc":60,"../../model/Sequence":88,"../menubuilder":75}],79:[function(require,module,exports){
+var FilterMenu, MenuBuilder, _;
+
+MenuBuilder = require("../menubuilder");
+
+_ = require("underscore");
+
+module.exports = FilterMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ return this.el.style.display = "inline-block";
+ },
+ render: function() {
+ this.setName("Filter");
+ this.addNode("Hide columns by threshold", (function(_this) {
+ return function(e) {
+ var conserv, hidden, i, maxLen, threshold, _i, _ref;
+ threshold = prompt("Enter threshold (in percent)", 20);
+ threshold = threshold / 100;
+ maxLen = _this.model.getMaxLength();
+ hidden = [];
+ conserv = _this.g.columns.get("conserv");
+ for (i = _i = 0, _ref = maxLen - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ if (conserv[i] < threshold) {
+ hidden.push(i);
+ }
+ }
+ return _this.g.columns.set("hidden", hidden);
+ };
+ })(this));
+ this.addNode("Hide columns by selection", (function(_this) {
+ return function() {
+ var hidden, hiddenOld;
+ hiddenOld = _this.g.columns.get("hidden");
+ hidden = hiddenOld.concat(_this.g.selcol.getAllColumnBlocks({
+ maxLen: _this.model.getMaxLength(),
+ withPos: true
+ }));
+ _this.g.selcol.reset([]);
+ return _this.g.columns.set("hidden", hidden);
+ };
+ })(this));
+ this.addNode("Hide columns by gaps", (function(_this) {
+ return function() {
+ var gapContent, gaps, hidden, i, maxLen, threshold, total, _i, _ref;
+ threshold = prompt("Enter threshold (in percent)", 20);
+ threshold = threshold / 100;
+ maxLen = _this.model.getMaxLength();
+ hidden = [];
+ for (i = _i = 0, _ref = maxLen - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ gaps = 0;
+ total = 0;
+ _this.model.each(function(el) {
+ if (el.get('seq')[i] === "-") {
+ gaps++;
+ }
+ return total++;
+ });
+ gapContent = gaps / total;
+ if (gapContent > threshold) {
+ hidden.push(i);
+ }
+ }
+ return _this.g.columns.set("hidden", hidden);
+ };
+ })(this));
+ this.addNode("Hide seqs by identity", (function(_this) {
+ return function() {
+ var threshold;
+ threshold = prompt("Enter threshold (in percent)", 20);
+ threshold = threshold / 100;
+ return _this.model.each(function(el) {
+ if (el.get('identity') < threshold) {
+ return el.set('hidden', true);
+ }
+ });
+ };
+ })(this));
+ this.addNode("Hide seqs by selection", (function(_this) {
+ return function() {
+ var hidden, ids;
+ hidden = _this.g.selcol.where({
+ type: "row"
+ });
+ ids = _.map(hidden, function(el) {
+ return el.get('seqId');
+ });
+ _this.g.selcol.reset([]);
+ return _this.model.each(function(el) {
+ if (ids.indexOf(el.get('id')) >= 0) {
+ return el.set('hidden', true);
+ }
+ });
+ };
+ })(this));
+ this.addNode("Hide seqs by gaps", (function(_this) {
+ return function() {
+ var threshold;
+ threshold = prompt("Enter threshold (in percent)", 40);
+ return _this.model.each(function(el, i) {
+ var gaps, seq;
+ seq = el.get('seq');
+ gaps = _.reduce(seq, (function(memo, c) {
+ if (c === '-') {
+ memo++;
+ }
+ return memo;
+ }), 0);
+ console.log(gaps);
+ if (gaps > threshold) {
+ return el.set('hidden', true);
+ }
+ });
+ };
+ })(this));
+ this.addNode("Reset", (function(_this) {
+ return function() {
+ _this.g.columns.set("hidden", []);
+ return _this.model.each(function(el) {
+ if (el.get('hidden')) {
+ return el.set('hidden', false);
+ }
+ });
+ };
+ })(this));
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../menubuilder":75,"underscore":59}],80:[function(require,module,exports){
+var HelpMenu, MenuBuilder;
+
+MenuBuilder = require("../menubuilder");
+
+module.exports = HelpMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ return this.g = data.g;
+ },
+ render: function() {
+ this.setName("Help");
+ this.addNode("About the project", (function(_this) {
+ return function() {
+ return window.open("https://github.com/greenify/biojs-vis-msa");
+ };
+ })(this));
+ this.addNode("Report issues", (function(_this) {
+ return function() {
+ return window.open("https://github.com/greenify/biojs-vis-msa/issues");
+ };
+ })(this));
+ this.addNode("User manual", (function(_this) {
+ return function() {
+ return window.open("https://github.com/greenify/biojs-vis-msa/wiki");
+ };
+ })(this));
+ this.el.style.display = "inline-block";
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../menubuilder":75}],81:[function(require,module,exports){
+var Clustal, FastaReader, ImportMenu, MenuBuilder, corsURL;
+
+Clustal = require("biojs-io-clustal");
+
+FastaReader = require("biojs-io-fasta").parse;
+
+MenuBuilder = require("../menubuilder");
+
+corsURL = require("../../utils/proxy").corsURL;
+
+module.exports = ImportMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ return this.el.style.display = "inline-block";
+ },
+ render: function() {
+ this.setName("Import");
+ this.addNode("FASTA", (function(_this) {
+ return function(e) {
+ var url;
+ url = prompt("URL", "/test/dummy/samples/p53.clustalo.fasta");
+ url = corsURL(url, _this.g);
+ return FastaReader.read(url, function(seqs) {
+ var zoomer;
+ zoomer = _this.g.zoomer.toJSON();
+ zoomer.labelWidth = 200;
+ zoomer.boxRectHeight = 2;
+ zoomer.boxRectWidth = 2;
+ _this.model.reset([]);
+ _this.g.zoomer.set(zoomer);
+ _this.model.reset(seqs);
+ return _this.g.columns.calcConservation(_this.model);
+ });
+ };
+ })(this));
+ this.addNode("CLUSTAL", (function(_this) {
+ return function() {
+ var url;
+ url = prompt("URL", "/test/dummy/samples/p53.clustalo.clustal");
+ url = corsURL(url, _this.g);
+ return Clustal.read(url, function(seqs) {
+ var zoomer;
+ zoomer = _this.g.zoomer.toJSON();
+ zoomer.labelWidth = 200;
+ zoomer.boxRectHeight = 2;
+ zoomer.boxRectWidth = 2;
+ _this.model.reset([]);
+ _this.g.zoomer.set(zoomer);
+ _this.model.reset(seqs);
+ return _this.g.columns.calcConservation(_this.model);
+ });
+ };
+ })(this));
+ this.addNode("add your own Parser", (function(_this) {
+ return function() {
+ return window.open("https://github.com/biojs/biojs2");
+ };
+ })(this));
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../../utils/proxy":93,"../menubuilder":75,"biojs-io-clustal":undefined,"biojs-io-fasta":undefined}],82:[function(require,module,exports){
+var MenuBuilder, OrderingMenu, dom, _;
+
+MenuBuilder = require("../menubuilder");
+
+dom = require("dom-helper");
+
+_ = require('underscore');
+
+module.exports = OrderingMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.order = "ID";
+ return this.el.style.display = "inline-block";
+ },
+ setOrder: function(order) {
+ this.order = order;
+ return this.render();
+ },
+ render: function() {
+ var comps, el, m, _i, _len;
+ this.setName("Ordering");
+ comps = this.getComparators();
+ for (_i = 0, _len = comps.length; _i < _len; _i++) {
+ m = comps[_i];
+ this._addNode(m);
+ }
+ el = this.buildDOM();
+ dom.removeAllChilds(this.el);
+ this.el.appendChild(el);
+ return this;
+ },
+ _addNode: function(m) {
+ var style, text;
+ text = m.text;
+ style = {};
+ if (text === this.order) {
+ style.backgroundColor = "#77ED80";
+ }
+ return this.addNode(text, (function(_this) {
+ return function() {
+ if (m.precode != null) {
+ m.precode();
+ }
+ _this.model.comparator = m.comparator;
+ _this.model.sort();
+ return _this.setOrder(m.text);
+ };
+ })(this), {
+ style: style
+ });
+ },
+ getComparators: function() {
+ var models;
+ models = [];
+ models.push({
+ text: "ID",
+ comparator: "id"
+ });
+ models.push({
+ text: "ID Desc",
+ comparator: function(a, b) {
+ return -a.get("id").localeCompare(b.get("id"));
+ }
+ });
+ models.push({
+ text: "Label",
+ comparator: "name"
+ });
+ models.push({
+ text: "Label Desc",
+ comparator: function(a, b) {
+ return -a.get("name").localeCompare(b.get("name"));
+ }
+ });
+ models.push({
+ text: "Seq",
+ comparator: "seq"
+ });
+ models.push({
+ text: "Seq Desc",
+ comparator: function(a, b) {
+ return -a.get("seq").localeCompare(b.get("seq"));
+ }
+ });
+ models.push({
+ text: "Identity",
+ comparator: "identity"
+ });
+ models.push({
+ text: "Identity Desc",
+ comparator: function(seq) {
+ return -seq.get("identity");
+ }
+ });
+ models.push({
+ text: "Partition codes",
+ comparator: "partition",
+ precode: (function(_this) {
+ return function() {
+ _this.g.vis.set('labelPartition', true);
+ return _this.model.each(function(el) {
+ return el.set('partition', _.random(1, 3));
+ });
+ };
+ })(this)
+ });
+ return models;
+ }
+});
+
+
+
+},{"../menubuilder":75,"dom-helper":49,"underscore":59}],83:[function(require,module,exports){
+var MenuBuilder, SelectionMenu, sel;
+
+sel = require("../../g/selection/Selection");
+
+MenuBuilder = require("../menubuilder");
+
+module.exports = SelectionMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ return this.el.style.display = "inline-block";
+ },
+ render: function() {
+ this.setName("Selection");
+ this.addNode("Find Motif (supports RegEx)", (function(_this) {
+ return function() {
+ var leftestIndex, newSeli, origIndex, search, selcol;
+ search = prompt("your search", "D");
+ search = new RegExp(search, "gi");
+ selcol = _this.g.selcol;
+ newSeli = [];
+ leftestIndex = origIndex = 100042;
+ _this.model.each(function(seq) {
+ var args, index, match, strSeq, _results;
+ strSeq = seq.get("seq");
+ _results = [];
+ while (match = search.exec(strSeq)) {
+ index = match.index;
+ args = {
+ xStart: index,
+ xEnd: index + match[0].length - 1,
+ seqId: seq.get("id")
+ };
+ newSeli.push(new sel.possel(args));
+ _results.push(leftestIndex = Math.min(index, leftestIndex));
+ }
+ return _results;
+ });
+ if (newSeli.length === 0) {
+ alert("no selection found");
+ }
+ selcol.reset(newSeli);
+ if (leftestIndex === origIndex) {
+ leftestIndex = 0;
+ }
+ return _this.g.zoomer.setLeftOffset(leftestIndex);
+ };
+ })(this));
+ this.addNode("Invert columns", (function(_this) {
+ return function() {
+ var _i, _ref, _results;
+ return _this.g.selcol.invertCol((function() {
+ _results = [];
+ for (var _i = 0, _ref = _this.model.getMaxLength(); 0 <= _ref ? _i <= _ref : _i >= _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }
+ return _results;
+ }).apply(this));
+ };
+ })(this));
+ this.addNode("Invert rows", (function(_this) {
+ return function() {
+ return _this.g.selcol.invertRow(_this.model.pluck("id"));
+ };
+ })(this));
+ this.addNode("Reset", (function(_this) {
+ return function() {
+ return _this.g.selcol.reset();
+ };
+ })(this));
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../../g/selection/Selection":67,"../menubuilder":75}],84:[function(require,module,exports){
+var ImportMenu, MenuBuilder, dom;
+
+MenuBuilder = require("../menubuilder");
+
+dom = require("dom-helper");
+
+module.exports = ImportMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.el.style.display = "inline-block";
+ return this.listenTo(this.g.vis, "change", this.render);
+ },
+ render: function() {
+ var visEl, visElements, _i, _len;
+ this.setName("Vis. elements");
+ visElements = this.getVisElements();
+ for (_i = 0, _len = visElements.length; _i < _len; _i++) {
+ visEl = visElements[_i];
+ this._addVisEl(visEl);
+ }
+ this.addNode("Reset", (function(_this) {
+ return function() {
+ _this.g.vis.set("labels", true);
+ _this.g.vis.set("sequences", true);
+ _this.g.vis.set("metacell", true);
+ _this.g.vis.set("conserv", true);
+ _this.g.vis.set("labelId", true);
+ _this.g.vis.set("labelName", true);
+ return _this.g.vis.set("labelCheckbox", false);
+ };
+ })(this));
+ this.addNode("Toggle mouseover events", (function(_this) {
+ return function() {
+ return _this.g.config.set("registerMouseHover", !_this.g.config.get("registerMouseHover"));
+ };
+ })(this));
+ dom.removeAllChilds(this.el);
+ this.el.appendChild(this.buildDOM());
+ return this;
+ },
+ _addVisEl: function(visEl) {
+ var pre, style;
+ style = {};
+ if (this.g.vis.get(visEl.id)) {
+ pre = "Hide ";
+ style.color = "red";
+ } else {
+ pre = "Show ";
+ style.color = "green";
+ }
+ return this.addNode(pre + visEl.name, (function(_this) {
+ return function() {
+ return _this.g.vis.set(visEl.id, !_this.g.vis.get(visEl.id));
+ };
+ })(this), {
+ style: style
+ });
+ },
+ getVisElements: function() {
+ var vis;
+ vis = [];
+ vis.push({
+ name: "Markers",
+ id: "markers"
+ });
+ vis.push({
+ name: "Labels",
+ id: "labels"
+ });
+ vis.push({
+ name: "Sequences",
+ id: "sequences"
+ });
+ vis.push({
+ name: "Meta info",
+ id: "metacell"
+ });
+ vis.push({
+ name: "Overviewbox",
+ id: "overviewbox"
+ });
+ vis.push({
+ name: "conserv",
+ id: "conserv"
+ });
+ vis.push({
+ name: "LabelName",
+ id: "labelName"
+ });
+ vis.push({
+ name: "LabelId",
+ id: "labelId"
+ });
+ vis.push({
+ name: "LabelCheckbox",
+ id: "labelCheckbox"
+ });
+ return vis;
+ }
+});
+
+
+
+},{"../menubuilder":75,"dom-helper":49}],85:[function(require,module,exports){
+var Feature, Model;
+
+Feature = require("./Feature");
+
+Model = require("backbone-thin").Model;
+
+module.exports = Feature = Model.extend({
+ defaults: {
+ xStart: -1,
+ xEnd: -1,
+ height: -1,
+ text: "",
+ fillColor: "red",
+ fillOpacity: 0.5,
+ type: "rectangle",
+ borderSize: 1,
+ borderColor: "black",
+ borderOpacity: 0.5,
+ validate: true
+ },
+ validate: function() {
+ if (isNaN(this.attributes.xStart || isNaN(this.attributes.xEnd))) {
+ return "features need integer start and end.";
+ }
+ },
+ contains: function(index) {
+ return this.attributes.xStart <= index && index <= this.attributes.xEnd;
+ }
+});
+
+
+
+},{"./Feature":85,"backbone-thin":5}],86:[function(require,module,exports){
+var Collection, Feature, FeatureCol, _;
+
+Feature = require("./Feature");
+
+Collection = require("backbone-thin").Collection;
+
+_ = require("underscore");
+
+module.exports = FeatureCol = Collection.extend({
+ model: Feature,
+ constructor: function() {
+ this.startOnCache = [];
+ this.on("all", function() {
+ return this.startOnCache = [];
+ }, this);
+ return Collection.apply(this, arguments);
+ },
+ startOn: function(index) {
+ if (this.startOnCache[index] == null) {
+ this.startOnCache[index] = this.where({
+ xStart: index
+ });
+ }
+ return this.startOnCache[index];
+ },
+ contains: function(index) {
+ return this.reduce(function(el, memo) {
+ return memo || el.contains(index);
+ }, false);
+ },
+ getMinRows: function() {
+ var len, rows, x;
+ len = this.max(function(el) {
+ return el.get("xEnd");
+ });
+ rows = (function() {
+ var _i, _results;
+ _results = [];
+ for (x = _i = 1; 1 <= len ? _i <= len : _i >= len; x = 1 <= len ? ++_i : --_i) {
+ _results.push(0);
+ }
+ return _results;
+ })();
+ this.each(function(el) {
+ var _i, _ref, _ref1, _results;
+ _results = [];
+ for (x = _i = _ref = el.get("xStart"), _ref1 = feature.get("xEnd"); _i <= _ref1; x = _i += 1) {
+ _results.push(rows[x]++);
+ }
+ return _results;
+ });
+ return _.max(rows);
+ }
+});
+
+
+
+},{"./Feature":85,"backbone-thin":5,"underscore":59}],87:[function(require,module,exports){
+var Collection, SeqManager, Sequence;
+
+Sequence = require("./Sequence");
+
+Collection = require("backbone-thin").Collection;
+
+module.exports = SeqManager = Collection.extend({
+ model: Sequence,
+ constructor: function() {
+ Collection.apply(this, arguments);
+ this.on("all", function() {
+ return this.lengthCache = null;
+ }, this);
+ this.lengthCache = null;
+ return this;
+ },
+ getMaxLength: function() {
+ if (this.models.length === 0) {
+ return 0;
+ }
+ if (this.lengthCache === null) {
+ this.lengthCache = this.max(function(seq) {
+ return seq.get("seq").length;
+ }).get("seq").length;
+ }
+ return this.lengthCache;
+ },
+ prev: function(model, endless) {
+ var index;
+ index = this.indexOf(model) - 1;
+ if (index < 0 && endless) {
+ index = this.length - 1;
+ }
+ return this.at(index);
+ },
+ next: function(model, endless) {
+ var index;
+ index = this.indexOf(model) + 1;
+ if (index === this.length && endless) {
+ index = 0;
+ }
+ return this.at(index);
+ },
+ calcHiddenSeqs: function(n) {
+ var i, nNew, _i;
+ nNew = n;
+ for (i = _i = 0; 0 <= nNew ? _i <= nNew : _i >= nNew; i = 0 <= nNew ? ++_i : --_i) {
+ if (this.at(i).get("hidden")) {
+ nNew++;
+ }
+ }
+ return nNew - n;
+ }
+});
+
+
+
+},{"./Sequence":88,"backbone-thin":5}],88:[function(require,module,exports){
+var FeatureCol, Model, Sequence;
+
+Model = require("backbone-thin").Model;
+
+FeatureCol = require("./FeatureCol");
+
+module.exports = Sequence = Model.extend({
+ defaults: {
+ name: "",
+ id: "",
+ seq: ""
+ },
+ initialize: function() {
+ this.set("grey", []);
+ return this.set("features", new FeatureCol());
+ }
+});
+
+
+
+},{"./FeatureCol":86,"backbone-thin":5}],89:[function(require,module,exports){
+module.exports.seq = require("./Sequence");
+
+module.exports.seqcol = require("./SeqCollection");
+
+module.exports.feature = require("./Feature");
+
+module.exports.featurecol = require("./FeatureCol");
+
+
+
+},{"./Feature":85,"./FeatureCol":86,"./SeqCollection":87,"./Sequence":88}],90:[function(require,module,exports){
+var Colorator, Columns, Config, Consensus, Eventhandler, SelCol, SeqCollection, Stage, VisOrdering, Visibility, Zoomer, boneView;
+
+SeqCollection = require("./model/SeqCollection");
+
+Colorator = require("./g/colorator");
+
+Consensus = require("./g/consensus");
+
+Columns = require("./g/columns");
+
+Config = require("./g/config");
+
+SelCol = require("./g/selection/SelectionCol");
+
+Visibility = require("./g/visibility");
+
+VisOrdering = require("./g/visOrdering");
+
+Zoomer = require("./g/zoomer");
+
+boneView = require("backbone-childs");
+
+Eventhandler = require("biojs-events");
+
+Stage = require("./views/Stage");
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ var _ref;
+ if (data.columns == null) {
+ data.columns = {};
+ }
+ if (data.conf == null) {
+ data.conf = {};
+ }
+ if (data.vis == null) {
+ data.vis = {};
+ }
+ if (data.zoomer == null) {
+ if (!((_ref = data.visorder) != null ? _ref : data.zoomer = {})) {
+ data.visorder = {};
+ }
+ }
+ this.g = Eventhandler.mixin({});
+ if (data.seqs === void 0 || data.seqs.length === 0) {
+ console.log("warning. empty seqs.");
+ }
+ this.seqs = new SeqCollection(data.seqs);
+ this.g.config = new Config(data.conf);
+ this.g.consensus = new Consensus();
+ this.g.columns = new Columns(data.columns);
+ this.g.colorscheme = new Colorator();
+ this.g.selcol = new SelCol([], {
+ g: this.g
+ });
+ this.g.vis = new Visibility(data.vis);
+ this.g.visorder = new VisOrdering(data.visorder);
+ this.g.zoomer = new Zoomer(data.zoomer, {
+ g: this.g
+ });
+ this.addView("stage", new Stage({
+ model: this.seqs,
+ g: this.g
+ }));
+ this.el.setAttribute("class", "biojs_msa_div");
+ if (this.g.config.get("eventBus") === true) {
+ return this.startEventBus();
+ }
+ },
+ startEventBus: function() {
+ var busObjs, key, _i, _len, _results;
+ busObjs = ["config", "consensus", "columns", "colorscheme", "selcol", "vis", "visorder", "zoomer"];
+ _results = [];
+ for (_i = 0, _len = busObjs.length; _i < _len; _i++) {
+ key = busObjs[_i];
+ _results.push(this._proxyToG(key));
+ }
+ return _results;
+ },
+ _proxyToG: function(key) {
+ return this.listenTo(this.g[key], "all", function(name, prev, now) {
+ if (name === "change") {
+ return;
+ }
+ return this.g.trigger(key + ":" + name, now);
+ });
+ },
+ render: function() {
+ this.renderSubviews();
+ this.g.vis.set("loaded", true);
+ return this;
+ }
+});
+
+
+
+},{"./g/colorator":63,"./g/columns":64,"./g/config":65,"./g/consensus":66,"./g/selection/SelectionCol":68,"./g/visOrdering":69,"./g/visibility":70,"./g/zoomer":71,"./model/SeqCollection":87,"./views/Stage":100,"backbone-childs":3,"biojs-events":14}],91:[function(require,module,exports){
+var BMath;
+
+module.exports = BMath = (function() {
+ function BMath() {}
+
+ BMath.randomInt = function(lower, upper) {
+ var _ref, _ref1;
+ if (upper == null) {
+ _ref = [0, lower], lower = _ref[0], upper = _ref[1];
+ }
+ if (lower > upper) {
+ _ref1 = [upper, lower], lower = _ref1[0], upper = _ref1[1];
+ }
+ return Math.floor(Math.random() * (upper - lower + 1) + lower);
+ };
+
+ BMath.uniqueId = function(length) {
+ var id;
+ if (length == null) {
+ length = 8;
+ }
+ id = "";
+ while (id.length < length) {
+ id += Math.random().toString(36).substr(2);
+ }
+ return id.substr(0, length);
+ };
+
+ BMath.getRandomInt = function(min, max) {
+ return Math.floor(Math.random() * (max - min + 1)) + min;
+ };
+
+ return BMath;
+
+})();
+
+
+
+},{}],92:[function(require,module,exports){
+module.exports.bmath = require("./bmath");
+
+module.exports.proxy = require("./proxy");
+
+module.exports.seqgen = require("./seqgen");
+
+
+
+},{"./bmath":91,"./proxy":93,"./seqgen":94}],93:[function(require,module,exports){
+var proxy;
+
+module.exports = proxy = {
+ corsURL: (function(_this) {
+ return function(url, g) {
+ _this.g = g;
+ if (document.URL.indexOf('localhost') >= 0 && url[0] === "/") {
+ return url;
+ }
+ url = url.replace("www\.", "");
+ url = url.replace("http://", "");
+ url = _this.g.config.get('importProxy') + url;
+ return url;
+ };
+ })(this)
+};
+
+
+
+},{}],94:[function(require,module,exports){
+var BMath, Sequence, seqgen;
+
+Sequence = require("biojs-model").seq;
+
+BMath = require("./bmath");
+
+seqgen = module.exports = {
+ _generateSequence: function(len) {
+ var i, possible, text, _i, _ref;
+ text = "";
+ possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ for (i = _i = 0, _ref = len - 1; _i <= _ref; i = _i += 1) {
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
+ }
+ return text;
+ },
+ getDummySequences: function(len, seqLen) {
+ var i, seqs, _i;
+ seqs = [];
+ if (len == null) {
+ len = BMath.getRandomInt(3, 5);
+ }
+ if (seqLen == null) {
+ seqLen = BMath.getRandomInt(50, 200);
+ }
+ for (i = _i = 1; _i <= len; i = _i += 1) {
+ seqs.push(new Sequence(seqgen._generateSequence(seqLen), "seq" + i, "r" + i));
+ }
+ return seqs;
+ }
+};
+
+
+
+},{"./bmath":91,"biojs-model":27}],95:[function(require,module,exports){
+var Base, Line, Polygon, Rect, setAttr, svgns;
+
+svgns = "http://www.w3.org/2000/svg";
+
+setAttr = function(obj, opts) {
+ var name, value;
+ for (name in opts) {
+ value = opts[name];
+ obj.setAttributeNS(null, name, value);
+ }
+ return obj;
+};
+
+Base = function(opts) {
+ var svg;
+ svg = document.createElementNS(svgns, 'svg');
+ svg.setAttribute("width", opts.width);
+ svg.setAttribute("height", opts.height);
+ return svg;
+};
+
+Rect = function(opts) {
+ var rect;
+ rect = document.createElementNS(svgns, 'rect');
+ return setAttr(rect, opts);
+};
+
+Line = function(opts) {
+ var line;
+ line = document.createElementNS(svgns, 'line');
+ return setAttr(line, opts);
+};
+
+Polygon = function(opts) {
+ var line;
+ line = document.createElementNS(svgns, 'polygon');
+ return setAttr(line, opts);
+};
+
+module.exports.rect = Rect;
+
+module.exports.line = Line;
+
+module.exports.polygon = Polygon;
+
+module.exports.base = Base;
+
+
+
+},{}],96:[function(require,module,exports){
+var LabelBlock, SeqBlock, boneView;
+
+boneView = require("backbone-childs");
+
+SeqBlock = require("./CanvasSeqBlock");
+
+LabelBlock = require("./labels/LabelBlock");
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ var labelblock, seqblock;
+ this.g = data.g;
+ if (true) {
+ labelblock = new LabelBlock({
+ model: this.model,
+ g: this.g
+ });
+ labelblock.ordering = -1;
+ this.addView("labelblock", labelblock);
+ }
+ if (this.g.vis.get("sequences")) {
+ seqblock = new SeqBlock({
+ model: this.model,
+ g: this.g
+ });
+ seqblock.ordering = 0;
+ this.addView("seqblock", seqblock);
+ }
+ this.listenTo(this.g.zoomer, "change:alignmentHeight", this.adjustHeight);
+ return this.listenTo(this.g.columns, "change:hidden", this.adjustHeight);
+ },
+ render: function() {
+ this.renderSubviews();
+ this.el.className = "biojs_msa_albody";
+ this.el.style.whiteSpace = "nowrap";
+ this.adjustHeight();
+ return this;
+ },
+ adjustHeight: function() {
+ if (this.g.zoomer.get("alignmentHeight") === "auto") {
+ this.el.style.height = (this.g.zoomer.get("rowHeight") * this.model.length) + 5;
+ } else {
+ this.el.style.height = this.g.zoomer.get("alignmentHeight");
+ }
+ return this.el.style.width = this.getWidth() + 15;
+ },
+ getWidth: function() {
+ var width;
+ width = 0;
+ if (this.g.vis.get("labels")) {
+ width += this.g.zoomer.get("labelWidth");
+ }
+ if (this.g.vis.get("metacell")) {
+ width += this.g.zoomer.get("metaWidth");
+ }
+ if (this.g.vis.get("sequences")) {
+ width += this.g.zoomer.get("alignmentWidth");
+ }
+ return width;
+ }
+});
+
+
+
+},{"./CanvasSeqBlock":98,"./labels/LabelBlock":104,"backbone-childs":3}],97:[function(require,module,exports){
+var CanvasCharCache, Events;
+
+Events = require("biojs-events");
+
+module.exports = CanvasCharCache = (function() {
+ function CanvasCharCache(g) {
+ this.g = g;
+ this.cache = {};
+ this.cacheHeight = 0;
+ this.cacheWidth = 0;
+ }
+
+ CanvasCharCache.prototype.getFontTile = function(letter, width, height) {
+ if (width !== this.cacheWidth || height !== this.cacheHeight) {
+ this.cacheHeight = height;
+ this.cacheWidth = width;
+ this.cache = {};
+ }
+ if (this.cache[letter] === void 0) {
+ this.createTile(letter, width, height);
+ }
+ return this.cache[letter];
+ };
+
+ CanvasCharCache.prototype.createTile = function(letter, width, height) {
+ var canvas;
+ canvas = this.cache[letter] = document.createElement("canvas");
+ canvas.width = width;
+ canvas.height = height;
+ this.ctx = canvas.getContext('2d');
+ this.ctx.font = this.g.zoomer.get("residueFont");
+ this.ctx.textBaseline = 'middle';
+ this.ctx.textAlign = "center";
+ return this.ctx.fillText(letter, width / 2, height / 2, width);
+ };
+
+ return CanvasCharCache;
+
+})();
+
+
+
+},{"biojs-events":14}],98:[function(require,module,exports){
+var CharCache, boneView, colorSelector, jbone, mouse, _;
+
+boneView = require("backbone-childs");
+
+mouse = require("mouse-pos");
+
+colorSelector = require("biojs-util-colorschemes").selector;
+
+_ = require("underscore");
+
+jbone = require("jbone");
+
+CharCache = require("./CanvasCharCache");
+
+module.exports = boneView.extend({
+ tagName: "canvas",
+ initialize: function(data) {
+ this.g = data.g;
+ this.listenTo(this.g.zoomer, "change:_alignmentScrollLeft change:_alignmentScrollTop", function(model, value, options) {
+ if (((options != null ? options.origin : void 0) == null) || options.origin !== "canvasseq") {
+ return this.render();
+ }
+ });
+ this.listenTo(this.g.columns, "change:hidden", this.render);
+ this.listenTo(this.g.zoomer, "change:alignmentWidth", this.render);
+ this.listenTo(this.g.colorscheme, "change", this.render);
+ this.listenTo(this.g.selcol, "reset add", this.render);
+ this.el.style.display = "inline-block";
+ this.el.style.overflowX = "hidden";
+ this.el.style.overflowY = "hidden";
+ this.el.className = "biojs_msa_seqblock";
+ this.ctx = this.el.getContext('2d');
+ this.cache = new CharCache(this.g);
+ this.throttleTime = 0;
+ this.throttleCounts = 0;
+ if (document.documentElement.style.webkitAppearance != null) {
+ this.throttledDraw = function() {
+ var start, tTime;
+ start = +new Date();
+ this.draw();
+ this.throttleTime += +new Date() - start;
+ this.throttleCounts++;
+ if (this.throttleCounts > 15) {
+ tTime = Math.ceil(this.throttleTime / this.throttleCounts);
+ console.log("avgDrawTime/WebKit", tTime);
+ return this.throttledDraw = this.draw;
+ }
+ };
+ } else {
+ this.throttledDraw = _.throttle(this.throttledDraw, 30);
+ }
+ return this.manageEvents();
+ },
+ throttledDraw: function() {
+ var start, tTime;
+ start = +new Date();
+ this.draw();
+ this.throttleTime += +new Date() - start;
+ this.throttleCounts++;
+ if (this.throttleCounts > 15) {
+ tTime = Math.ceil(this.throttleTime / this.throttleCounts);
+ console.log("avgDrawTime", tTime);
+ tTime *= 1.2;
+ tTime = Math.max(20, tTime);
+ return this.throttledDraw = _.throttle(this.draw, tTime);
+ }
+ },
+ manageEvents: function() {
+ var events;
+ events = {};
+ events.mousedown = "_onmousedown";
+ events.touchstart = "_ontouchstart";
+ if (this.g.config.get("registerMouseClicks")) {
+ events.dblclick = "_onclick";
+ }
+ if (this.g.config.get("registerMouseHover")) {
+ events.mousein = "_onmousein";
+ events.mouseout = "_onmouseout";
+ }
+ events.mousewheel = "_onmousewheel";
+ events.DOMMouseScroll = "_onmousewheel";
+ this.delegateEvents(events);
+ this.listenTo(this.g.config, "change:registerMouseHover", this.manageEvents);
+ this.listenTo(this.g.config, "change:registerMouseClick", this.manageEvents);
+ return this.dragStart = [];
+ },
+ draw: function() {
+ var rectHeight;
+ this.el.width = this.el.width;
+ rectHeight = this.g.zoomer.get("rowHeight");
+ this.ctx.globalAlpha = this.g.colorscheme.get("opacity");
+ this.drawSeqs(function(data) {
+ return this.drawSeq(data, this._drawRect);
+ });
+ this.ctx.globalAlpha = 1;
+ this.drawSeqs(function(data) {
+ return this.drawSeq(data, this._drawLetter);
+ });
+ return this.drawSeqs(this.drawSeqExtended);
+ },
+ drawSeqs: function(callback) {
+ var hidden, i, rectHeight, start, y, _i, _ref, _results;
+ rectHeight = this.g.zoomer.get("rowHeight");
+ hidden = this.g.columns.get("hidden");
+ start = Math.max(0, Math.abs(Math.ceil(-this.g.zoomer.get('_alignmentScrollTop') / rectHeight)));
+ y = -Math.abs(-this.g.zoomer.get('_alignmentScrollTop') % rectHeight);
+ _results = [];
+ for (i = _i = start, _ref = this.model.length - 1; _i <= _ref; i = _i += 1) {
+ if (this.model.at(i).get('hidden')) {
+ continue;
+ }
+ callback.call(this, {
+ model: this.model.at(i),
+ y: y,
+ hidden: hidden
+ });
+ y = y + rectHeight;
+ if (y > this.el.height) {
+ break;
+ } else {
+ _results.push(void 0);
+ }
+ }
+ return _results;
+ },
+ drawSeq: function(data, callback) {
+ var c, elWidth, j, rectHeight, rectWidth, res, seq, start, x, y, _i, _ref, _results;
+ seq = data.model.get("seq");
+ y = data.y;
+ rectWidth = this.g.zoomer.get("columnWidth");
+ rectHeight = this.g.zoomer.get("rowHeight");
+ start = Math.max(0, Math.abs(Math.ceil(-this.g.zoomer.get('_alignmentScrollLeft') / rectWidth)));
+ x = -Math.abs(-this.g.zoomer.get('_alignmentScrollLeft') % rectWidth);
+ res = {
+ rectWidth: rectWidth,
+ rectHeight: rectHeight,
+ y: y
+ };
+ elWidth = this.el.width;
+ _results = [];
+ for (j = _i = start, _ref = seq.length - 1; _i <= _ref; j = _i += 1) {
+ c = seq[j];
+ c = c.toUpperCase();
+ res.x = x;
+ res.c = c;
+ if (data.hidden.indexOf(j) < 0) {
+ callback(this, res);
+ } else {
+ continue;
+ }
+ x = x + rectWidth;
+ if (x > elWidth) {
+ break;
+ } else {
+ _results.push(void 0);
+ }
+ }
+ return _results;
+ },
+ _drawRect: function(that, data) {
+ var color;
+ color = that.color[data.c];
+ if (color != null) {
+ that.ctx.fillStyle = color;
+ return that.ctx.fillRect(data.x, data.y, data.rectWidth, data.rectHeight);
+ }
+ },
+ _drawLetter: function(that, data) {
+ return that.ctx.drawImage(that.cache.getFontTile(data.c, data.rectWidth, data.rectHeight), data.x, data.y, data.rectWidth, data.rectHeight);
+ },
+ drawSeqExtended: function(data) {
+ var f, features, j, mNextSel, mPrevSel, rectHeight, rectWidth, selection, seq, start, starts, x, xZero, yZero, _i, _j, _len, _ref, _ref1;
+ seq = data.model.get("seq");
+ rectWidth = this.g.zoomer.get("columnWidth");
+ rectHeight = this.g.zoomer.get("rowHeight");
+ start = Math.max(0, Math.abs(Math.ceil(-this.g.zoomer.get('_alignmentScrollLeft') / rectWidth)));
+ x = -Math.abs(-this.g.zoomer.get('_alignmentScrollLeft') % rectWidth);
+ xZero = x - start * rectWidth;
+ selection = this._getSelection(data.model);
+ _ref = this._getPrevNextSelection(data.model), mPrevSel = _ref[0], mNextSel = _ref[1];
+ features = data.model.get("features");
+ yZero = data.y;
+ for (j = _i = start, _ref1 = seq.length - 1; _i <= _ref1; j = _i += 1) {
+ starts = features.startOn(j);
+ if (data.hidden.indexOf(j) >= 0) {
+ continue;
+ }
+ if (starts.length > 0) {
+ for (_j = 0, _len = starts.length; _j < _len; _j++) {
+ f = starts[_j];
+ this.appendFeature({
+ f: f,
+ xZero: x,
+ yZero: yZero
+ });
+ }
+ }
+ x = x + rectWidth;
+ if (x > this.el.width) {
+ break;
+ }
+ }
+ return this._appendSelection({
+ model: data.model,
+ xZero: xZero,
+ yZero: yZero,
+ hidden: data.hidden
+ });
+ },
+ render: function() {
+ this.el.setAttribute('height', this.g.zoomer.get("alignmentHeight"));
+ this.el.setAttribute('width', this.g.zoomer.get("alignmentWidth"));
+ this.g.zoomer._adjustWidth(this.el, this.model);
+ this.g.zoomer._checkScrolling(this._checkScrolling([this.g.zoomer.get('_alignmentScrollLeft'), this.g.zoomer.get('_alignmentScrollTop')]), {
+ header: "canvasseq"
+ });
+ this.color = colorSelector.getColor(this.g.colorscheme.get("scheme"));
+ this.throttledDraw();
+ return this;
+ },
+ _onmousemove: function(e, reversed) {
+ var dragEnd, i, relDist, relEnd, scaleFactor, scrollCorrected, _i, _j, _k;
+ if (this.dragStart.length === 0) {
+ return;
+ }
+ dragEnd = mouse.abs(e);
+ relEnd = [dragEnd[0] - this.dragStart[0], dragEnd[1] - this.dragStart[1]];
+ scaleFactor = this.g.zoomer.get("canvasEventScale");
+ if (reversed) {
+ scaleFactor = 3;
+ }
+ for (i = _i = 0; _i <= 1; i = _i += 1) {
+ relEnd[i] = relEnd[i] * scaleFactor;
+ }
+ relDist = [this.dragStartScroll[0] - relEnd[0], this.dragStartScroll[1] - relEnd[1]];
+ for (i = _j = 0; _j <= 1; i = _j += 1) {
+ relDist[i] = Math.round(relDist[i]);
+ }
+ scrollCorrected = this._checkScrolling(relDist);
+ this.g.zoomer._checkScrolling(scrollCorrected, {
+ origin: "canvasseq"
+ });
+ for (i = _k = 0; _k <= 1; i = _k += 1) {
+ if (scrollCorrected[i] !== relDist[i]) {
+ if (scrollCorrected[i] === 0) {
+ this.dragStart[i] = dragEnd[i];
+ this.dragStartScroll[i] = 0;
+ } else {
+ this.dragStart[i] = dragEnd[i] - scrollCorrected[i];
+ }
+ }
+ }
+ this.throttledDraw();
+ if (e.preventDefault != null) {
+ e.preventDefault();
+ return e.stopPropagation();
+ }
+ },
+ _ontouchmove: function(e) {
+ this._onmousemove(e.changedTouches[0], true);
+ e.preventDefault();
+ return e.stopPropagation();
+ },
+ _onmousedown: function(e) {
+ this.dragStart = mouse.abs(e);
+ this.dragStartScroll = [this.g.zoomer.get('_alignmentScrollLeft'), this.g.zoomer.get('_alignmentScrollTop')];
+ jbone(document.body).on('mousemove.overmove', (function(_this) {
+ return function(e) {
+ return _this._onmousemove(e);
+ };
+ })(this));
+ jbone(document.body).on('mouseup.overup', (function(_this) {
+ return function() {
+ return _this._cleanup();
+ };
+ })(this));
+ return e.preventDefault();
+ },
+ _ontouchstart: function(e) {
+ this.dragStart = mouse.abs(e.changedTouches[0]);
+ this.dragStartScroll = [this.g.zoomer.get('_alignmentScrollLeft'), this.g.zoomer.get('_alignmentScrollTop')];
+ jbone(document.body).on('touchmove.overtmove', (function(_this) {
+ return function(e) {
+ return _this._ontouchmove(e);
+ };
+ })(this));
+ return jbone(document.body).on('touchend.overtend touchleave.overtleave touchcancel.overtcanel', (function(_this) {
+ return function(e) {
+ return _this._touchCleanup(e);
+ };
+ })(this));
+ },
+ _onmousewinout: function(e) {
+ if (e.toElement === document.body.parentNode) {
+ return this._cleanup();
+ }
+ },
+ _cleanup: function() {
+ this.dragStart = [];
+ jbone(document.body).off('.overmove');
+ jbone(document.body).off('.overup');
+ return jbone(document.body).off('.overout');
+ },
+ _touchCleanup: function(e) {
+ if (e.changedTouches.length > 0) {
+ this._onmousemove(e.changedTouches[0], true);
+ }
+ this.dragStart = [];
+ jbone(document.body).off('.overtmove');
+ jbone(document.body).off('.overtend');
+ jbone(document.body).off('.overtleave');
+ return jbone(document.body).off('.overtcancel');
+ },
+ _onmousewheel: function(e) {
+ var delta;
+ delta = mouse.wheelDelta(e);
+ this.g.zoomer.set('_alignmentScrollLeft', this.g.zoomer.get('_alignmentScrollLeft') + delta[0]);
+ this.g.zoomer.set('_alignmentScrollTop', this.g.zoomer.get('_alignmentScrollTop') + delta[1]);
+ return e.preventDefault();
+ },
+ _onclick: function(e) {
+ this.g.trigger("residue:click", this._getClickPos(e));
+ return this.throttledDraw();
+ },
+ _onmousein: function(e) {
+ this.g.trigger("residue:click", this._getClickPos(e));
+ return this.throttledDraw();
+ },
+ _onmouseout: function(e) {
+ this.g.trigger("residue:click", this._getClickPos(e));
+ return this.throttledDraw();
+ },
+ _getClickPos: function(e) {
+ var coords, seqId, x, y;
+ coords = mouse.rel(e);
+ coords[0] += this.g.zoomer.get("_alignmentScrollLeft");
+ coords[1] += this.g.zoomer.get("_alignmentScrollTop");
+ x = Math.floor(coords[0] / this.g.zoomer.get("columnWidth"));
+ y = Math.floor(coords[1] / this.g.zoomer.get("rowHeight"));
+ x += this.g.columns.calcHiddenColumns(x);
+ y += this.model.calcHiddenSeqs(y);
+ x = Math.max(0, x);
+ y = Math.max(0, y);
+ seqId = this.model.at(y).get("id");
+ return {
+ seqId: seqId,
+ rowPos: x,
+ evt: e
+ };
+ },
+ _checkScrolling: function(scrollObj) {
+ var i, max, _i;
+ max = [this.model.getMaxLength() * this.g.zoomer.get("columnWidth") - this.g.zoomer.get('alignmentWidth'), this.model.length * this.g.zoomer.get("rowHeight") - this.g.zoomer.get('alignmentHeight')];
+ for (i = _i = 0; _i <= 1; i = _i += 1) {
+ if (scrollObj[i] > max[i]) {
+ scrollObj[i] = max[i];
+ }
+ if (scrollObj[i] < 0) {
+ scrollObj[i] = 0;
+ }
+ }
+ return scrollObj;
+ },
+ _getSelection: function(model) {
+ var maxLen, n, rows, sel, selection, sels, _i, _j, _k, _len, _ref, _ref1, _ref2;
+ maxLen = model.get("seq").length;
+ selection = [];
+ sels = this.g.selcol.getSelForRow(model.get("id"));
+ rows = _.find(sels, function(el) {
+ return el.get("type") === "row";
+ });
+ if (rows != null) {
+ for (n = _i = 0, _ref = maxLen - 1; _i <= _ref; n = _i += 1) {
+ selection.push(n);
+ }
+ } else if (sels.length > 0) {
+ for (_j = 0, _len = sels.length; _j < _len; _j++) {
+ sel = sels[_j];
+ for (n = _k = _ref1 = sel.get("xStart"), _ref2 = sel.get("xEnd"); _k <= _ref2; n = _k += 1) {
+ selection.push(n);
+ }
+ }
+ }
+ return selection;
+ },
+ appendFeature: function(data) {
+ var beforeStyle, beforeWidth, boxHeight, boxWidth, f, width;
+ f = data.f;
+ boxWidth = this.g.zoomer.get("columnWidth");
+ boxHeight = this.g.zoomer.get("rowHeight");
+ width = (f.get("xEnd") - f.get("xStart")) * boxWidth;
+ beforeWidth = this.ctx.lineWidth;
+ this.ctx.lineWidth = 3;
+ beforeStyle = this.ctx.strokeStyle;
+ this.ctx.strokeStyle = f.get("fillColor");
+ this.ctx.strokeRect(data.xZero, data.yZero, width, boxHeight);
+ this.ctx.strokeStyle = beforeStyle;
+ return this.ctx.lineWidth = beforeWidth;
+ },
+ _appendSelection: function(data) {
+ var boxHeight, boxWidth, hiddenOffset, k, mNextSel, mPrevSel, n, selection, seq, _i, _ref, _ref1, _results;
+ seq = data.model.get("seq");
+ selection = this._getSelection(data.model);
+ _ref = this._getPrevNextSelection(data.model), mPrevSel = _ref[0], mNextSel = _ref[1];
+ boxWidth = this.g.zoomer.get("columnWidth");
+ boxHeight = this.g.zoomer.get("rowHeight");
+ if (selection.length === 0) {
+ return;
+ }
+ hiddenOffset = 0;
+ _results = [];
+ for (n = _i = 0, _ref1 = seq.length - 1; _i <= _ref1; n = _i += 1) {
+ if (data.hidden.indexOf(n) >= 0) {
+ _results.push(hiddenOffset++);
+ } else {
+ k = n - hiddenOffset;
+ if (selection.indexOf(n) >= 0 && (k === 0 || selection.indexOf(n - 1) < 0)) {
+ _results.push(this._renderSelection({
+ n: n,
+ k: k,
+ selection: selection,
+ mPrevSel: mPrevSel,
+ mNextSel: mNextSel,
+ xZero: data.xZero,
+ yZero: data.yZero,
+ model: data.model
+ }));
+ } else {
+ _results.push(void 0);
+ }
+ }
+ }
+ return _results;
+ },
+ _renderSelection: function(data) {
+ var beforeStyle, beforeWidth, boxHeight, boxWidth, hidden, i, k, mNextSel, mPrevSel, n, selection, selectionLength, totalWidth, xPart, xPos, xZero, yZero, _i, _j, _ref, _ref1;
+ xZero = data.xZero;
+ yZero = data.yZero;
+ n = data.n;
+ k = data.k;
+ selection = data.selection;
+ mPrevSel = data.mPrevSel;
+ mNextSel = data.mNextSel;
+ selectionLength = 0;
+ for (i = _i = n, _ref = data.model.get("seq").length - 1; _i <= _ref; i = _i += 1) {
+ if (selection.indexOf(i) >= 0) {
+ selectionLength++;
+ } else {
+ break;
+ }
+ }
+ boxWidth = this.g.zoomer.get("columnWidth");
+ boxHeight = this.g.zoomer.get("rowHeight");
+ totalWidth = (boxWidth * selectionLength) + 1;
+ hidden = this.g.columns.get('hidden');
+ this.ctx.beginPath();
+ beforeWidth = this.ctx.lineWidth;
+ this.ctx.lineWidth = 3;
+ beforeStyle = this.ctx.strokeStyle;
+ this.ctx.strokeStyle = "#FF0000";
+ xZero += k * boxWidth;
+ xPart = 0;
+ for (i = _j = 0, _ref1 = selectionLength - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
+ xPos = n + i;
+ if (hidden.indexOf(xPos) >= 0) {
+ continue;
+ }
+ if (!((mPrevSel != null) && mPrevSel.indexOf(xPos) >= 0)) {
+ this.ctx.moveTo(xZero + xPart, yZero);
+ this.ctx.lineTo(xPart + boxWidth + xZero, yZero);
+ }
+ if (!((mNextSel != null) && mNextSel.indexOf(xPos) >= 0)) {
+ this.ctx.moveTo(xPart + xZero, boxHeight + yZero);
+ this.ctx.lineTo(xPart + boxWidth + xZero, boxHeight + yZero);
+ }
+ xPart += boxWidth;
+ }
+ this.ctx.moveTo(xZero, yZero);
+ this.ctx.lineTo(xZero, boxHeight + yZero);
+ this.ctx.moveTo(xZero + totalWidth, yZero);
+ this.ctx.lineTo(xZero + totalWidth, boxHeight + yZero);
+ this.ctx.stroke();
+ this.ctx.strokeStyle = beforeStyle;
+ return this.ctx.lineWidth = beforeWidth;
+ },
+ _getPrevNextSelection: function(model) {
+ var mNextSel, mPrevSel, modelNext, modelPrev;
+ modelPrev = model.collection.prev(model);
+ modelNext = model.collection.next(model);
+ if (modelPrev != null) {
+ mPrevSel = this._getSelection(modelPrev);
+ }
+ if (modelNext != null) {
+ mNextSel = this._getSelection(modelNext);
+ }
+ return [mPrevSel, mNextSel];
+ }
+});
+
+
+
+},{"./CanvasCharCache":97,"backbone-childs":3,"biojs-util-colorschemes":29,"jbone":50,"mouse-pos":51,"underscore":59}],99:[function(require,module,exports){
+var OverviewBox, colorSelector, jbone, mouse, selection, view, _;
+
+view = require("backbone-viewj");
+
+mouse = require("mouse-pos");
+
+selection = require("../g/selection/Selection");
+
+colorSelector = require("biojs-util-colorschemes").selector;
+
+jbone = require("jbone");
+
+_ = require("underscore");
+
+module.exports = OverviewBox = view.extend({
+ className: "biojs_msa_overviewbox",
+ tagName: "canvas",
+ initialize: function(data) {
+ this.g = data.g;
+ this.listenTo(this.g.zoomer, "change:boxRectWidth change:boxRectHeight", this.render);
+ this.listenTo(this.g.selcol, "add reset change", this.render);
+ this.listenTo(this.g.columns, "change:hidden", this.render);
+ this.listenTo(this.g.colorscheme, "change:showLowerCase", this.render);
+ this.listenTo(this.model, "change", _.debounce(this.render, 5));
+ this.color = colorSelector.getColor(this.g.colorscheme.get("scheme"));
+ this.listenTo(this.g.colorscheme, "change:scheme", function() {
+ this.color = colorSelector.getColor(this.g.colorscheme.get("scheme"));
+ return this.render();
+ });
+ return this.dragStart = [];
+ },
+ events: {
+ click: "_onclick",
+ mousedown: "_onmousedown"
+ },
+ render: function() {
+ var c, color, hidden, i, j, rectHeight, rectWidth, seq, showLowerCase, x, y, _i, _j, _ref, _ref1;
+ this._createCanvas();
+ this.el.textContent = "overview";
+ this.ctx.fillStyle = "#999999";
+ this.ctx.fillRect(0, 0, this.el.width, this.el.height);
+ rectWidth = this.g.zoomer.get("boxRectWidth");
+ rectHeight = this.g.zoomer.get("boxRectHeight");
+ hidden = this.g.columns.get("hidden");
+ showLowerCase = this.g.colorscheme.get("showLowerCase");
+ y = -rectHeight;
+ for (i = _i = 0, _ref = this.model.length - 1; _i <= _ref; i = _i += 1) {
+ seq = this.model.at(i).get("seq");
+ x = 0;
+ y = y + rectHeight;
+ if (this.model.at(i).get("hidden")) {
+ console.log(this.model.at(i).get("hidden"));
+ this.ctx.fillStyle = "grey";
+ this.ctx.fillRect(0, y, seq.length * rectWidth, rectHeight);
+ continue;
+ }
+ for (j = _j = 0, _ref1 = seq.length - 1; _j <= _ref1; j = _j += 1) {
+ c = seq[j];
+ if (showLowerCase) {
+ c = c.toUpperCase();
+ }
+ color = this.color[c];
+ if (hidden.indexOf(j) >= 0) {
+ color = "grey";
+ }
+ if (color != null) {
+ this.ctx.fillStyle = color;
+ this.ctx.fillRect(x, y, rectWidth, rectHeight);
+ }
+ x = x + rectWidth;
+ }
+ }
+ return this._drawSelection();
+ },
+ _drawSelection: function() {
+ var i, maxHeight, pos, rectHeight, rectWidth, sel, seq, _i, _ref;
+ if (this.dragStart.length > 0 && !this.prolongSelection) {
+ return;
+ }
+ rectWidth = this.g.zoomer.get("boxRectWidth");
+ rectHeight = this.g.zoomer.get("boxRectHeight");
+ maxHeight = rectHeight * this.model.length;
+ this.ctx.fillStyle = "#ffff00";
+ this.ctx.globalAlpha = 0.9;
+ for (i = _i = 0, _ref = this.g.selcol.length - 1; _i <= _ref; i = _i += 1) {
+ sel = this.g.selcol.at(i);
+ if (sel.get('type') === 'column') {
+ this.ctx.fillRect(rectWidth * sel.get('xStart'), 0, rectWidth * (sel.get('xEnd') - sel.get('xStart') + 1), maxHeight);
+ } else if (sel.get('type') === 'row') {
+ seq = (this.model.filter(function(el) {
+ return el.get('id') === sel.get('seqId');
+ }))[0];
+ pos = this.model.indexOf(seq);
+ this.ctx.fillRect(0, rectHeight * pos, rectWidth * seq.get('seq').length, rectHeight);
+ } else if (sel.get('type') === 'pos') {
+ seq = (this.model.filter(function(el) {
+ return el.get('id') === sel.get('seqId');
+ }))[0];
+ pos = this.model.indexOf(seq);
+ this.ctx.fillRect(rectWidth * sel.get('xStart'), rectHeight * pos, rectWidth * (sel.get('xEnd') - sel.get('xStart') + 1), rectHeight);
+ }
+ }
+ return this.ctx.globalAlpha = 1;
+ },
+ _onclick: function(evt) {
+ return this.g.trigger("meta:click", {
+ seqId: this.model.get("id", {
+ evt: evt
+ })
+ });
+ },
+ _onmousemove: function(e) {
+ var rect;
+ if (this.dragStart.length === 0) {
+ return;
+ }
+ this.render();
+ this.ctx.fillStyle = "#ffff00";
+ this.ctx.globalAlpha = 0.9;
+ rect = this._calcSelection(mouse.abs(e));
+ this.ctx.fillRect(rect[0][0], rect[1][0], rect[0][1] - rect[0][0], rect[1][1] - rect[1][0]);
+ e.preventDefault();
+ return e.stopPropagation();
+ },
+ _onmousedown: function(e) {
+ this.dragStart = mouse.abs(e);
+ this.dragStartRel = mouse.rel(e);
+ if (e.ctrlKey || e.metaKey) {
+ this.prolongSelection = true;
+ } else {
+ this.prolongSelection = false;
+ }
+ jbone(document.body).on('mousemove.overmove', (function(_this) {
+ return function(e) {
+ return _this._onmousemove(e);
+ };
+ })(this));
+ jbone(document.body).on('mouseup.overup', (function(_this) {
+ return function(e) {
+ return _this._onmouseup(e);
+ };
+ })(this));
+ return this.dragStart;
+ },
+ _calcSelection: function(dragMove) {
+ var dragRel, i, rect, _i, _j;
+ dragRel = [dragMove[0] - this.dragStart[0], dragMove[1] - this.dragStart[1]];
+ for (i = _i = 0; _i <= 1; i = _i += 1) {
+ dragRel[i] = this.dragStartRel[i] + dragRel[i];
+ }
+ rect = [[this.dragStartRel[0], dragRel[0]], [this.dragStartRel[1], dragRel[1]]];
+ for (i = _j = 0; _j <= 1; i = _j += 1) {
+ if (rect[i][1] < rect[i][0]) {
+ rect[i] = [rect[i][1], rect[i][0]];
+ }
+ rect[i][0] = Math.max(rect[i][0], 0);
+ }
+ return rect;
+ },
+ _endSelection: function(dragEnd) {
+ var args, i, j, rect, selis, _i, _j, _k, _ref, _ref1;
+ jbone(document.body).off('.overmove');
+ jbone(document.body).off('.overup');
+ if (this.dragStart.length === 0) {
+ return;
+ }
+ rect = this._calcSelection(dragEnd);
+ for (i = _i = 0; _i <= 1; i = ++_i) {
+ rect[0][i] = Math.floor(rect[0][i] / this.g.zoomer.get("boxRectWidth"));
+ }
+ for (i = _j = 0; _j <= 1; i = ++_j) {
+ rect[1][i] = Math.floor(rect[1][i] / this.g.zoomer.get("boxRectHeight"));
+ }
+ rect[0][1] = Math.min(this.model.getMaxLength() - 1, rect[0][1]);
+ rect[1][1] = Math.min(this.model.length - 1, rect[1][1]);
+ selis = [];
+ for (j = _k = _ref = rect[1][0], _ref1 = rect[1][1]; _k <= _ref1; j = _k += 1) {
+ args = {
+ seqId: this.model.at(j).get('id'),
+ xStart: rect[0][0],
+ xEnd: rect[0][1]
+ };
+ selis.push(new selection.possel(args));
+ }
+ this.dragStart = [];
+ if (this.prolongSelection) {
+ this.g.selcol.add(selis);
+ } else {
+ this.g.selcol.reset(selis);
+ }
+ this.g.zoomer.setLeftOffset(rect[0][0]);
+ return this.g.zoomer.setTopOffset(rect[1][0]);
+ },
+ _onmouseup: function(e) {
+ return this._endSelection(mouse.abs(e));
+ },
+ _onmouseout: function(e) {
+ return this._endSelection(mouse.abs(e));
+ },
+ _createCanvas: function() {
+ var rectHeight, rectWidth;
+ rectWidth = this.g.zoomer.get("boxRectWidth");
+ rectHeight = this.g.zoomer.get("boxRectHeight");
+ this.el.height = this.model.length * rectHeight;
+ this.el.width = this.model.getMaxLength() * rectWidth;
+ this.ctx = this.el.getContext("2d");
+ this.el.style.overflow = "scroll";
+ return this.el.style.cursor = "crosshair";
+ }
+});
+
+
+
+},{"../g/selection/Selection":67,"backbone-viewj":10,"biojs-util-colorschemes":29,"jbone":50,"mouse-pos":51,"underscore":59}],100:[function(require,module,exports){
+var AlignmentBody, HeaderBlock, OverviewBox, boneView, identityCalc, _;
+
+boneView = require("backbone-childs");
+
+AlignmentBody = require("./AlignmentBody");
+
+HeaderBlock = require("./header/HeaderBlock");
+
+OverviewBox = require("./OverviewBox");
+
+identityCalc = require("../algo/identityCalc");
+
+_ = require('underscore');
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.draw();
+ this.listenTo(this.model, "reset", function() {
+ this.isNotDirty = false;
+ return this.rerender();
+ });
+ this.listenTo(this.model, "change:hidden", _.debounce(this.rerender, 10));
+ this.listenTo(this.model, "sort", this.rerender);
+ this.listenTo(this.model, "add", function() {
+ return console.log("seq add");
+ });
+ this.listenTo(this.g.vis, "change:sequences", this.rerender);
+ this.listenTo(this.g.vis, "change:overviewbox", this.rerender);
+ return this.listenTo(this.g.visorder, "change", this.rerender);
+ },
+ draw: function() {
+ var body, consensus, headerblock, overviewbox;
+ this.removeViews();
+ if (!this.isNotDirty) {
+ consensus = this.g.consensus.getConsensus(this.model);
+ identityCalc(this.model, consensus);
+ this.isNotDirty = true;
+ }
+ if (this.g.vis.get("overviewbox")) {
+ overviewbox = new OverviewBox({
+ model: this.model,
+ g: this.g
+ });
+ overviewbox.ordering = this.g.visorder.get('overviewBox');
+ this.addView("overviewbox", overviewbox);
+ }
+ if (true) {
+ headerblock = new HeaderBlock({
+ model: this.model,
+ g: this.g
+ });
+ headerblock.ordering = this.g.visorder.get('headerBox');
+ this.addView("headerblock", headerblock);
+ }
+ body = new AlignmentBody({
+ model: this.model,
+ g: this.g
+ });
+ body.ordering = this.g.visorder.get('alignmentBody');
+ return this.addView("body", body);
+ },
+ render: function() {
+ this.renderSubviews();
+ this.el.className = "biojs_msa_stage";
+ return this;
+ },
+ rerender: function() {
+ this.draw();
+ return this.render();
+ }
+});
+
+
+
+},{"../algo/identityCalc":61,"./AlignmentBody":96,"./OverviewBox":99,"./header/HeaderBlock":102,"backbone-childs":3,"underscore":59}],101:[function(require,module,exports){
+var ConservationView, dom, svg, view;
+
+view = require("backbone-viewj");
+
+dom = require("dom-helper");
+
+svg = require("../../utils/svg");
+
+ConservationView = view.extend({
+ className: "biojs_msa_conserv",
+ initialize: function(data) {
+ this.g = data.g;
+ this.listenTo(this.g.zoomer, "change:stepSize change:labelWidth change:columnWidth", this.render);
+ this.listenTo(this.g.vis, "change:labels change:metacell", this.render);
+ this.listenTo(this.g.columns, "change:scaling", this.render);
+ this.listenTo(this.model, "reset", this.render);
+ return this.manageEvents();
+ },
+ render: function() {
+ var avgHeight, cellWidth, height, hidden, i, maxHeight, n, nMax, rect, s, stepSize, width, x, _i, _ref;
+ this.g.columns.calcConservation(this.model);
+ dom.removeAllChilds(this.el);
+ nMax = this.model.getMaxLength();
+ cellWidth = this.g.zoomer.get("columnWidth");
+ maxHeight = 20;
+ width = cellWidth * (nMax - this.g.columns.get('hidden').length);
+ console.log(this.g.columns.get('hidden'));
+ s = svg.base({
+ height: maxHeight,
+ width: width
+ });
+ s.style.display = "inline-block";
+ s.style.cursor = "pointer";
+ stepSize = this.g.zoomer.get("stepSize");
+ hidden = this.g.columns.get("hidden");
+ x = 0;
+ n = 0;
+ while (n < nMax) {
+ if (hidden.indexOf(n) >= 0) {
+ n += stepSize;
+ continue;
+ }
+ width = cellWidth * stepSize;
+ avgHeight = 0;
+ for (i = _i = 0, _ref = stepSize - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ avgHeight += this.g.columns.get("conserv")[n];
+ }
+ height = maxHeight * (avgHeight / stepSize);
+ rect = svg.rect({
+ x: x,
+ y: maxHeight - height,
+ width: width - cellWidth / 4,
+ height: height,
+ style: "stroke:red;stroke-width:1;"
+ });
+ rect.rowPos = n;
+ s.appendChild(rect);
+ x += width;
+ n += stepSize;
+ }
+ this.el.appendChild(s);
+ return this;
+ },
+ _onclick: function(evt) {
+ var i, rowPos, stepSize, _i, _ref, _results;
+ rowPos = evt.target.rowPos;
+ stepSize = this.g.zoomer.get("stepSize");
+ _results = [];
+ for (i = _i = 0, _ref = stepSize - 1; _i <= _ref; i = _i += 1) {
+ _results.push(this.g.trigger("bar:click", {
+ rowPos: rowPos + i,
+ evt: evt
+ }));
+ }
+ return _results;
+ },
+ manageEvents: function() {
+ var events;
+ events = {};
+ if (this.g.config.get("registerMouseClicks")) {
+ events.click = "_onclick";
+ }
+ if (this.g.config.get("registerMouseHover")) {
+ events.mousein = "_onmousein";
+ events.mouseout = "_onmouseout";
+ }
+ this.delegateEvents(events);
+ this.listenTo(this.g.config, "change:registerMouseHover", this.manageEvents);
+ return this.listenTo(this.g.config, "change:registerMouseClick", this.manageEvents);
+ },
+ _onmousein: function(evt) {
+ var rowPos;
+ rowPos = this.g.zoomer.get("stepSize" * evt.rowPos);
+ return this.g.trigger("bar:mousein", {
+ rowPos: rowPos,
+ evt: evt
+ });
+ },
+ _onmouseout: function(evt) {
+ var rowPos;
+ rowPos = this.g.zoomer.get("stepSize" * evt.rowPos);
+ return this.g.trigger("bar:mouseout", {
+ rowPos: rowPos,
+ evt: evt
+ });
+ }
+});
+
+module.exports = ConservationView;
+
+
+
+},{"../../utils/svg":95,"backbone-viewj":10,"dom-helper":49}],102:[function(require,module,exports){
+var ConservationView, MarkerView, boneView, identityCalc, _;
+
+MarkerView = require("./MarkerView");
+
+ConservationView = require("./ConservationView");
+
+identityCalc = require("../../algo/identityCalc");
+
+boneView = require("backbone-childs");
+
+_ = require('underscore');
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.blockEvents = false;
+ this.listenTo(this.g.vis, "change:markers change:conserv", function() {
+ this.draw();
+ return this.render();
+ });
+ this.listenTo(this.g.vis, "change", this._setSpacer);
+ this.listenTo(this.g.zoomer, "change:alignmentWidth", function() {
+ return this._adjustWidth();
+ });
+ this.listenTo(this.g.zoomer, "change:_alignmentScrollLeft", this._adjustScrollingLeft);
+ this.listenTo(this.g.columns, "change:hidden", function() {
+ this.draw();
+ return this.render();
+ });
+ this.draw();
+ this._onscroll = this._sendScrollEvent;
+ return this.g.vis.once('change:loaded', this._adjustScrollingLeft, this);
+ },
+ events: {
+ "scroll": "_onscroll"
+ },
+ draw: function() {
+ var consensus, conserv, marker;
+ this.removeViews();
+ if (!this.isNotDirty) {
+ consensus = this.g.consensus.getConsensus(this.model);
+ identityCalc(this.model, consensus);
+ this.isNotDirty = true;
+ }
+ if (this.g.vis.get("conserv")) {
+ conserv = new ConservationView({
+ model: this.model,
+ g: this.g
+ });
+ conserv.ordering = -20;
+ this.addView("conserv", conserv);
+ }
+ if (this.g.vis.get("markers")) {
+ marker = new MarkerView({
+ model: this.model,
+ g: this.g
+ });
+ marker.ordering = -10;
+ return this.addView("marker", marker);
+ }
+ },
+ render: function() {
+ this.renderSubviews();
+ this._setSpacer();
+ this.el.className = "biojs_msa_header";
+ this.el.style.overflowX = "auto";
+ this._adjustWidth();
+ this._adjustScrollingLeft();
+ return this;
+ },
+ _sendScrollEvent: function() {
+ if (!this.blockEvents) {
+ this.g.zoomer.set("_alignmentScrollLeft", this.el.scrollLeft, {
+ origin: "header"
+ });
+ }
+ return this.blockEvents = false;
+ },
+ _adjustScrollingLeft: function(model, value, options) {
+ var scrollLeft;
+ if (((options != null ? options.origin : void 0) == null) || options.origin !== "header") {
+ scrollLeft = this.g.zoomer.get("_alignmentScrollLeft");
+ this.blockEvents = true;
+ return this.el.scrollLeft = scrollLeft;
+ }
+ },
+ _setSpacer: function() {
+ return this.el.style.marginLeft = this._getLabelWidth() + "px";
+ },
+ _getLabelWidth: function() {
+ var paddingLeft;
+ paddingLeft = 0;
+ if (this.g.vis.get("labels")) {
+ paddingLeft += this.g.zoomer.get("labelWidth");
+ }
+ if (this.g.vis.get("metacell")) {
+ paddingLeft += this.g.zoomer.get("metaWidth");
+ }
+ return paddingLeft;
+ },
+ _adjustWidth: function() {
+ return this.el.style.width = this.g.zoomer.get("alignmentWidth") + "px";
+ }
+});
+
+
+
+},{"../../algo/identityCalc":61,"./ConservationView":101,"./MarkerView":103,"backbone-childs":3,"underscore":59}],103:[function(require,module,exports){
+var HeaderView, dom, jbone, svg, view;
+
+view = require("backbone-viewj");
+
+dom = require("dom-helper");
+
+svg = require("../../utils/svg");
+
+jbone = require("jbone");
+
+HeaderView = view.extend({
+ className: "biojs_msa_marker",
+ initialize: function(data) {
+ this.g = data.g;
+ this.listenTo(this.g.zoomer, "change:stepSize change:labelWidth change:columnWidth change:markerStepSize change:markerFontsize", this.render);
+ this.listenTo(this.g.vis, "change:labels change:metacell", this.render);
+ return this.manageEvents();
+ },
+ render: function() {
+ var cellWidth, container, hidden, n, nMax, span, stepSize;
+ dom.removeAllChilds(this.el);
+ this.el.style.fontSize = this.g.zoomer.get("markerFontsize");
+ container = document.createElement("span");
+ n = 0;
+ cellWidth = this.g.zoomer.get("columnWidth");
+ nMax = this.model.getMaxLength();
+ stepSize = this.g.zoomer.get("stepSize");
+ hidden = this.g.columns.get("hidden");
+ while (n < nMax) {
+ if (hidden.indexOf(n) >= 0) {
+ this.markerHidden(span, n, stepSize);
+ n += stepSize;
+ continue;
+ }
+ span = document.createElement("span");
+ span.style.width = (cellWidth * stepSize) + "px";
+ span.style.display = "inline-block";
+ if ((n + 1) % this.g.zoomer.get('markerStepSize') === 0) {
+ span.textContent = n + 1;
+ } else {
+ span.textContent = ".";
+ }
+ span.rowPos = n;
+ n += stepSize;
+ container.appendChild(span);
+ }
+ this.el.appendChild(container);
+ return this;
+ },
+ markerHidden: function(span, n, stepSize) {
+ var hidden, index, j, length, min, nMax, prevHidden, s, triangle, _i, _j;
+ hidden = this.g.columns.get("hidden").slice(0);
+ min = Math.max(0, n - stepSize);
+ prevHidden = true;
+ for (j = _i = min; _i <= n; j = _i += 1) {
+ prevHidden &= hidden.indexOf(j) >= 0;
+ }
+ if (prevHidden) {
+ return;
+ }
+ nMax = this.model.getMaxLength();
+ length = 0;
+ index = -1;
+ for (n = _j = n; _j <= nMax; n = _j += 1) {
+ if (!(index >= 0)) {
+ index = hidden.indexOf(n);
+ }
+ if (hidden.indexOf(n) >= 0) {
+ length++;
+ } else {
+ break;
+ }
+ }
+ s = svg.base({
+ height: 10,
+ width: 10
+ });
+ s.style.position = "relative";
+ triangle = svg.polygon({
+ points: "0,0 5,5 10,0",
+ style: "fill:lime;stroke:purple;stroke-width:1"
+ });
+ jbone(triangle).on("click", (function(_this) {
+ return function(evt) {
+ hidden.splice(index, length);
+ return _this.g.columns.set("hidden", hidden);
+ };
+ })(this));
+ s.appendChild(triangle);
+ span.appendChild(s);
+ return s;
+ },
+ manageEvents: function() {
+ var events;
+ events = {};
+ if (this.g.config.get("registerMouseClicks")) {
+ events.click = "_onclick";
+ }
+ if (this.g.config.get("registerMouseHover")) {
+ events.mousein = "_onmousein";
+ events.mouseout = "_onmouseout";
+ }
+ this.delegateEvents(events);
+ this.listenTo(this.g.config, "change:registerMouseHover", this.manageEvents);
+ return this.listenTo(this.g.config, "change:registerMouseClick", this.manageEvents);
+ },
+ _onclick: function(evt) {
+ var rowPos, stepSize;
+ rowPos = evt.target.rowPos;
+ stepSize = this.g.zoomer.get("stepSize");
+ return this.g.trigger("column:click", {
+ rowPos: rowPos,
+ stepSize: stepSize,
+ evt: evt
+ });
+ },
+ _onmousein: function(evt) {
+ var rowPos, stepSize;
+ rowPos = this.g.zoomer.get("stepSize" * evt.rowPos);
+ stepSize = this.g.zoomer.get("stepSize");
+ return this.g.trigger("column:mousein", {
+ rowPos: rowPos,
+ stepSize: stepSize,
+ evt: evt
+ });
+ },
+ _onmouseout: function(evt) {
+ var rowPos, stepSize;
+ rowPos = this.g.zoomer.get("stepSize" * evt.rowPos);
+ stepSize = this.g.zoomer.get("stepSize");
+ return this.g.trigger("column:mouseout", {
+ rowPos: rowPos,
+ stepSize: stepSize,
+ evt: evt
+ });
+ }
+});
+
+module.exports = HeaderView;
+
+
+
+},{"../../utils/svg":95,"backbone-viewj":10,"dom-helper":49,"jbone":50}],104:[function(require,module,exports){
+var LabelRowView, boneView;
+
+LabelRowView = require("./LabelRowView");
+
+boneView = require("backbone-childs");
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.draw();
+ this.listenTo(this.g.zoomer, "change:_alignmentScrollTop", this._adjustScrollingTop);
+ return this.g.vis.once('change:loaded', this._adjustScrollingTop, this);
+ },
+ draw: function() {
+ var i, view, _i, _ref, _results;
+ this.removeViews();
+ _results = [];
+ for (i = _i = 0, _ref = this.model.length - 1; _i <= _ref; i = _i += 1) {
+ if (this.model.at(i).get('hidden')) {
+ continue;
+ }
+ view = new LabelRowView({
+ model: this.model.at(i),
+ g: this.g
+ });
+ view.ordering = i;
+ _results.push(this.addView("row_" + i, view));
+ }
+ return _results;
+ },
+ events: {
+ "scroll": "_sendScrollEvent"
+ },
+ _sendScrollEvent: function() {
+ return this.g.zoomer.set("_alignmentScrollTop", this.el.scrollTop, {
+ origin: "label"
+ });
+ },
+ _adjustScrollingTop: function() {
+ return this.el.scrollTop = this.g.zoomer.get("_alignmentScrollTop");
+ },
+ render: function() {
+ this.renderSubviews();
+ this.el.className = "biojs_msa_labelblock";
+ this.el.style.display = "inline-block";
+ this.el.style.verticalAlign = "top";
+ this.el.style.height = this.g.zoomer.get("alignmentHeight") + "px";
+ this.el.style.overflowY = "auto";
+ this.el.style.overflowX = "hidden";
+ this.el.style.fontSize = "" + (this.g.zoomer.get("labelFontsize"));
+ this.el.style.lineHeight = "" + (this.g.zoomer.get("labelLineHeight"));
+ return this;
+ }
+});
+
+
+
+},{"./LabelRowView":105,"backbone-childs":3}],105:[function(require,module,exports){
+var LabelView, MetaView, boneView;
+
+boneView = require("backbone-childs");
+
+LabelView = require("./LabelView");
+
+MetaView = require("./MetaView");
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.draw();
+ this.listenTo(this.g.vis, "change:labels", this.drawR);
+ return this.listenTo(this.g.vis, "change:metacell", this.drawR);
+ },
+ draw: function() {
+ this.removeViews();
+ if (this.g.vis.get("labels")) {
+ this.addView("labels", new LabelView({
+ model: this.model,
+ g: this.g
+ }));
+ }
+ if (this.g.vis.get("metacell")) {
+ return this.addView("metacell", new MetaView({
+ model: this.model,
+ g: this.g
+ }));
+ }
+ },
+ drawR: function() {
+ this.draw();
+ return this.render();
+ },
+ render: function() {
+ this.renderSubviews();
+ this.el.setAttribute("class", "biojs_msa_labelrow");
+ this.el.style.height = this.g.zoomer.get("rowHeight");
+ return this;
+ }
+});
+
+
+
+},{"./LabelView":106,"./MetaView":107,"backbone-childs":3}],106:[function(require,module,exports){
+var LabelView, dom, view;
+
+view = require("backbone-viewj");
+
+dom = require("dom-helper");
+
+LabelView = view.extend({
+ initialize: function(data) {
+ this.seq = data.seq;
+ this.g = data.g;
+ return this.manageEvents();
+ },
+ manageEvents: function() {
+ var events;
+ events = {};
+ if (this.g.config.get("registerMouseClicks")) {
+ events.click = "_onclick";
+ }
+ if (this.g.config.get("registerMouseHover")) {
+ events.mousein = "_onmousein";
+ events.mouseout = "_onmouseout";
+ }
+ this.delegateEvents(events);
+ this.listenTo(this.g.config, "change:registerMouseHover", this.manageEvents);
+ this.listenTo(this.g.config, "change:registerMouseClick", this.manageEvents);
+ this.listenTo(this.g.vis, "change:labelName", this.render);
+ this.listenTo(this.g.vis, "change:labelId", this.render);
+ this.listenTo(this.g.vis, "change:labelPartition", this.render);
+ return this.listenTo(this.g.vis, "change:labelCheckbox", this.render);
+ },
+ render: function() {
+ var checkBox, id, name, part;
+ dom.removeAllChilds(this.el);
+ this.el.style.width = "" + (this.g.zoomer.get("labelWidth")) + "px";
+ this.el.style.height = "" + (this.g.zoomer.get("rowHeight")) + "px";
+ this.el.setAttribute("class", "biojs_msa_labels");
+ if (this.g.vis.get("labelCheckbox")) {
+ checkBox = document.createElement("input");
+ checkBox.setAttribute("type", "checkbox");
+ checkBox.value = this.model.get('id');
+ checkBox.name = "seq";
+ this.el.appendChild(checkBox);
+ }
+ if (this.g.vis.get("labelId")) {
+ id = document.createElement("span");
+ id.textContent = this.model.get("id");
+ id.style.width = this.g.zoomer.get("labelIdLength");
+ id.style.display = "inline-block";
+ this.el.appendChild(id);
+ }
+ if (this.g.vis.get("labelPartition")) {
+ part = document.createElement("span");
+ part.style.width = 15;
+ part.textContent = this.model.get("partition");
+ part.style.display = "inline-block";
+ this.el.appendChild(id);
+ this.el.appendChild(part);
+ }
+ if (this.g.vis.get("labelName")) {
+ name = document.createElement("span");
+ name.textContent = this.model.get("name");
+ this.el.appendChild(name);
+ }
+ this.el.style.overflow = scroll;
+ return this;
+ },
+ _onclick: function(evt) {
+ var seqId;
+ seqId = this.model.get("id");
+ return this.g.trigger("row:click", {
+ seqId: seqId,
+ evt: evt
+ });
+ },
+ _onmousein: function(evt) {
+ var seqId;
+ seqId = this.model.get("id");
+ return this.g.trigger("row:mouseout", {
+ seqId: seqId,
+ evt: evt
+ });
+ },
+ _onmouseout: function(evt) {
+ var seqId;
+ seqId = this.model.get("id");
+ return this.g.trigger("row:mouseout", {
+ seqId: seqId,
+ evt: evt
+ });
+ }
+});
+
+module.exports = LabelView;
+
+
+
+},{"backbone-viewj":10,"dom-helper":49}],107:[function(require,module,exports){
+var MenuBuilder, MetaView, dom, view, _;
+
+view = require("backbone-viewj");
+
+MenuBuilder = require("../../menu/menubuilder");
+
+_ = require('underscore');
+
+dom = require("dom-helper");
+
+module.exports = MetaView = view.extend({
+ className: "biojs_msa_metaview",
+ initialize: function(data) {
+ return this.g = data.g;
+ },
+ events: {
+ click: "_onclick",
+ mousein: "_onmousein",
+ mouseout: "_onmouseout"
+ },
+ render: function() {
+ var gapSpan, gaps, ident, identSpan, menu, seq, width;
+ dom.removeAllChilds(this.el);
+ this.el.style.display = "inline-block";
+ width = this.g.zoomer.get("metaWidth");
+ this.el.style.width = width - 5;
+ this.el.style.paddingRight = 5;
+ seq = this.model.get('seq');
+ gaps = _.reduce(seq, (function(memo, c) {
+ if (c === '-') {
+ memo++;
+ }
+ return memo;
+ }), 0);
+ gaps = (gaps / seq.length).toFixed(1);
+ gapSpan = document.createElement('span');
+ gapSpan.textContent = gaps;
+ gapSpan.style.display = "inline-block";
+ gapSpan.style.width = 35;
+ this.el.appendChild(gapSpan);
+ ident = this.model.get('identity');
+ identSpan = document.createElement('span');
+ identSpan.textContent = ident.toFixed(2);
+ identSpan.style.display = "inline-block";
+ identSpan.style.width = 40;
+ this.el.appendChild(identSpan);
+ menu = new MenuBuilder("↗");
+ menu.addNode("Uniprot", (function(_this) {
+ return function(e) {
+ return window.open("http://beta.uniprot.org/uniprot/Q7T2N8");
+ };
+ })(this));
+ this.el.appendChild(menu.buildDOM());
+ this.el.width = 10;
+ this.el.style.height = "" + (this.g.zoomer.get("rowHeight")) + "px";
+ return this.el.style.cursor = "pointer";
+ },
+ _onclick: function(evt) {
+ return this.g.trigger("meta:click", {
+ seqId: this.model.get("id", {
+ evt: evt
+ })
+ });
+ },
+ _onmousein: function(evt) {
+ return this.g.trigger("meta:mousein", {
+ seqId: this.model.get("id", {
+ evt: evt
+ })
+ });
+ },
+ _onmouseout: function(evt) {
+ return this.g.trigger("meta:mouseout", {
+ seqId: this.model.get("id", {
+ evt: evt
+ })
+ });
+ }
+});
+
+
+
+},{"../../menu/menubuilder":75,"backbone-viewj":10,"dom-helper":49,"underscore":59}],"biojs-io-clustal":[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var Clustal, GenericReader, Seq, Str,
+ __hasProp = {}.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
+
+Str = require("./strings");
+
+GenericReader = require("./generic_reader");
+
+Seq = require("./seq");
+
+module.exports = Clustal = (function(_super) {
+ __extends(Clustal, _super);
+
+ function Clustal() {
+ return Clustal.__super__.constructor.apply(this, arguments);
+ }
+
+ Clustal.parse = function(text) {
+ var blockstate, k, label, line, lines, match, regex, seqCounter, seqs, sequence;
+ seqs = [];
+ if (Object.prototype.toString.call(text) === '[object Array]') {
+ lines = text;
+ } else {
+ lines = text.split("\n");
+ }
+ if (lines[0].slice(0, 6) === !"CLUSTAL") {
+ throw new Error("Invalid CLUSTAL Header");
+ }
+ k = 0;
+ blockstate = 1;
+ seqCounter = 0;
+ while (k < lines.length) {
+ k++;
+ line = lines[k];
+ if ((line == null) || line.length === 0) {
+ blockstate = 1;
+ continue;
+ }
+ if (line.trim().length === 0) {
+ blockstate = 1;
+ continue;
+ } else {
+ if (Str.contains(line, "*")) {
+ continue;
+ }
+ if (blockstate === 1) {
+ seqCounter = 0;
+ blockstate = 0;
+ }
+ regex = /^(?:\s*)(\S+)(?:\s+)(\S+)(?:\s*)(\d*)(?:\s*|$)/g;
+ match = regex.exec(line);
+ if (match != null) {
+ label = match[1];
+ sequence = match[2];
+ if (seqCounter >= seqs.length) {
+ seqs.push(new Seq(sequence, label, seqCounter));
+ } else {
+ seqs[seqCounter].seq += sequence;
+ }
+ seqCounter++;
+ } else {
+ console.log(line);
+ }
+ }
+ }
+ return seqs;
+ };
+
+ return Clustal;
+
+})(GenericReader);
+
+},{"./generic_reader":17,"./seq":18,"./strings":19}],"biojs-io-fasta":[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+module.exports.parse = require("./parser");
+
+module.exports.writer = require("./writer");
+
+},{"./parser":21,"./writer":24}],"biojs-vis-msa":[function(require,module,exports){
+if (typeof biojs === 'undefined') {
+ biojs = {};
+}
+if (typeof biojs.vis === 'undefined') {
+ biojs.vis = {};
+}
+// use two namespaces
+window.msa = biojs.vis.msa = module.exports = require('./index');
+
+// TODO: how should this be bundled
+
+if (typeof biojs.io === 'undefined') {
+ biojs.io = {};
+}
+// just bundle the two parsers
+window.biojs.io.fasta = require("biojs-io-fasta");
+window.biojs.io.clustal = require("biojs-io-clustal");
+window.biojs.xhr = require("nets");
+
+// simulate standalone flag
+window.biojsVisMsa = window.msa;
+
+require('./build/msa.css');
+
+},{"./build/msa.css":1,"./index":2,"biojs-io-clustal":undefined,"biojs-io-fasta":undefined,"nets":undefined}],"nets":[function(require,module,exports){
+var req = require('request')
+
+module.exports = Nets
+
+function Nets(uri, opts, cb) {
+ req(uri, opts, cb)
+}
+},{"request":52}]},{},["biojs-vis-msa"])
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9idWlsZC9tc2EuY3NzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2EvaW5kZXguanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmFja2JvbmUtY2hpbGRzL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2JhY2tib25lLXRoaW4vY29sbGVjdGlvbi5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iYWNrYm9uZS10aGluL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2JhY2tib25lLXRoaW4vbW9kZWwuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmFja2JvbmUtdGhpbi9ub2RlX21vZHVsZXMvYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUvYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmFja2JvbmUtdGhpbi9ub2RlX21vZHVsZXMvYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUvaW5kZXguanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmFja2JvbmUtdGhpbi9ub2RlX21vZHVsZXMvYmFja2JvbmUtZXh0ZW5kLXN0YW5kYWxvbmUvYmFja2JvbmUtZXh0ZW5kLXN0YW5kYWxvbmUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmFja2JvbmUtdmlld2ovaW5kZXguanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtZXZlbnRzL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWNsdXN0YWwvbGliL2dlbmVyaWNfcmVhZGVyLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWNsdXN0YWwvbGliL3NlcS5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy1pby1jbHVzdGFsL2xpYi9zdHJpbmdzLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL2xpYi9wYXJzZXIuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbGliL3V0aWxzLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL2xpYi93cml0ZXIuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbm9kZV9tb2R1bGVzL2Jpb2pzLW1vZGVsL3NyYy9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy1pby1mYXN0YS9ub2RlX21vZHVsZXMvYmlvanMtbW9kZWwvc3JjL3NlcS5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy11dGlsLWNvbG9yc2NoZW1lcy9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy11dGlsLWNvbG9yc2NoZW1lcy9zcmMvYnVyaWVkLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy9jaW5lbWEuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL2NsdXN0YWwuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL2NsdXN0YWwyLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy9oZWxpeC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy11dGlsLWNvbG9yc2NoZW1lcy9zcmMvaHlkcm9waG9iaWNpdHkuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy9sZXNrLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy9tYWUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL251Y2xlb3RpZGUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL3B1cmluZS5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy11dGlsLWNvbG9yc2NoZW1lcy9zcmMvc2VsZWN0b3IuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL3N0cmFuZC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy11dGlsLWNvbG9yc2NoZW1lcy9zcmMvdGF5bG9yLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy90dXJuLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy96YXBwby5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9ibHVlaW1wX2NhbnZhc3RvYmxvYi9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9icm93c2VyLXNhdmVhcy9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9jc3NpZnkvYnJvd3Nlci5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9kb20taGVscGVyL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2pib25lL2Rpc3QvamJvbmUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvbW91c2UtcG9zL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL25ldHMvbm9kZV9tb2R1bGVzL3hoci9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9uZXRzL25vZGVfbW9kdWxlcy94aHIvbm9kZV9tb2R1bGVzL2dsb2JhbC93aW5kb3cuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvbmV0cy9ub2RlX21vZHVsZXMveGhyL25vZGVfbW9kdWxlcy9vbmNlL29uY2UuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvbmV0cy9ub2RlX21vZHVsZXMveGhyL25vZGVfbW9kdWxlcy9wYXJzZS1oZWFkZXJzL25vZGVfbW9kdWxlcy9mb3ItZWFjaC9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9uZXRzL25vZGVfbW9kdWxlcy94aHIvbm9kZV9tb2R1bGVzL3BhcnNlLWhlYWRlcnMvbm9kZV9tb2R1bGVzL2Zvci1lYWNoL25vZGVfbW9kdWxlcy9pcy1mdW5jdGlvbi9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9uZXRzL25vZGVfbW9kdWxlcy94aHIvbm9kZV9tb2R1bGVzL3BhcnNlLWhlYWRlcnMvbm9kZV9tb2R1bGVzL3RyaW0vaW5kZXguanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvbmV0cy9ub2RlX21vZHVsZXMveGhyL25vZGVfbW9kdWxlcy9wYXJzZS1oZWFkZXJzL3BhcnNlLWhlYWRlcnMuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvdW5kZXJzY29yZS91bmRlcnNjb3JlLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2FsZ28vQ29uc2Vuc3VzQ2FsYy5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvYWxnby9pZGVudGl0eUNhbGMuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2FsZ28vaW5kZXguY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2cvY29sb3JhdG9yLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9nL2NvbHVtbnMuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2cvY29uZmlnLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9nL2NvbnNlbnN1cy5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvZy9zZWxlY3Rpb24vU2VsZWN0aW9uLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9nL3NlbGVjdGlvbi9TZWxlY3Rpb25Db2wuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2cvdmlzT3JkZXJpbmcuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2cvdmlzaWJpbGl0eS5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvZy96b29tZXIuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2luZGV4LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L2RlZmF1bHRtZW51LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L2luZGV4LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L21lbnVidWlsZGVyLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L3ZpZXdzL0NvbG9yTWVudS5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbWVudS92aWV3cy9FeHBvcnRNZW51LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L3ZpZXdzL0V4dHJhTWVudS5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbWVudS92aWV3cy9GaWx0ZXJNZW51LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L3ZpZXdzL0hlbHBNZW51LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L3ZpZXdzL0ltcG9ydE1lbnUuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL21lbnUvdmlld3MvT3JkZXJpbmdNZW51LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L3ZpZXdzL1NlbGVjdGlvbk1lbnUuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL21lbnUvdmlld3MvVmlzTWVudS5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbW9kZWwvRmVhdHVyZS5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbW9kZWwvRmVhdHVyZUNvbC5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbW9kZWwvU2VxQ29sbGVjdGlvbi5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbW9kZWwvU2VxdWVuY2UuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL21vZGVsL2luZGV4LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tc2EuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL3V0aWxzL2JtYXRoLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy91dGlscy9pbmRleC5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdXRpbHMvcHJveHkuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL3V0aWxzL3NlcWdlbi5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdXRpbHMvc3ZnLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy92aWV3cy9BbGlnbm1lbnRCb2R5LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy92aWV3cy9DYW52YXNDaGFyQ2FjaGUuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL3ZpZXdzL0NhbnZhc1NlcUJsb2NrLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy92aWV3cy9PdmVydmlld0JveC5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdmlld3MvU3RhZ2UuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL3ZpZXdzL2hlYWRlci9Db25zZXJ2YXRpb25WaWV3LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy92aWV3cy9oZWFkZXIvSGVhZGVyQmxvY2suY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL3ZpZXdzL2hlYWRlci9NYXJrZXJWaWV3LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy92aWV3cy9sYWJlbHMvTGFiZWxCbG9jay5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdmlld3MvbGFiZWxzL0xhYmVsUm93Vmlldy5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdmlld3MvbGFiZWxzL0xhYmVsVmlldy5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdmlld3MvbGFiZWxzL01ldGFWaWV3LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy1pby1jbHVzdGFsL2xpYi9jbHVzdGFsLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL2xpYi9pbmRleC5qcyIsIi4vYnJvd3NlciIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9uZXRzL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7O0FDQUE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcmJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclJBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUMvS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FDTkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2UEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3gxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2NENBLElBQUEsQ0FBQTs7QUFBQSxDQUFBLEdBQUksT0FBQSxDQUFRLFlBQVIsQ0FBSixDQUFBOztBQUFBLE1BSU0sQ0FBQyxPQUFQLEdBQWlCLFNBQUMsSUFBRCxHQUFBO0FBRWYsTUFBQSxJQUFBO0FBQUEs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Q0FyRFo7QUFBQSxFQXdEQSxXQUFBLEVBQWEsU0FBQyxHQUFELEdBQUE7V0FDWCxJQUFDLENBQUEsQ0FBQyxDQUFDLE9BQUgsQ0FBVyxlQUFYLEVBQTRCO0FBQUEsTUFBQyxLQUFBLEVBQU8sSUFBQyxDQUFBLEtBQUssQ0FBQyxHQUFQLENBQVcsSUFBWCxFQUFpQjtBQUFBLFFBQUEsR0FBQSxFQUFJLEdBQUo7T0FBakIsQ0FBUjtLQUE1QixFQURXO0VBQUEsQ0F4RGI7Q0FGMEIsQ0FMNUIsQ0FBQTs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsInZhciBjc3MgPSBcIi5iaW9qc19tc2Ffc3RhZ2Uge1xcbiAgY3Vyc29yOiBkZWZhdWx0O1xcbiAgbGluZS1oZWlnaHQ6IG5vcm1hbDsgfVxcblxcbi5iaW9qc19tc2FfbGFiZWxzIHtcXG4gIGNvbG9yOiBibGFjaztcXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcXG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XFxuICBjdXJzb3I6IHBvaW50ZXI7XFxuICB2ZXJ0aWNhbC1hbGlnbjogdG9wOyB9XFxuXFxuLmJpb2pzX21zYV9zZXFibG9jayB7XFxuICBjdXJzb3I6IG1vdmU7IH1cXG5cXG4uYmlvanNfbXNhX2xheWVyIHtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDsgfVxcblxcbi5iaW9qc19tc2FfbGFiZWxibG9jazo6LXdlYmtpdC1zY3JvbGxiYXIsIC5iaW9qc19tc2FfaGVhZGVyOjotd2Via2l0LXNjcm9sbGJhciB7XFxuICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XFxuICB3aWR0aDogN3B4O1xcbiAgaGVpZ2h0OiA3cHg7IH1cXG5cXG4uYmlvanNfbXNhX2xhYmVsYmxvY2s6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iLCAuYmlvanNfbXNhX2hlYWRlcjo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWIge1xcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjUpO1xcbiAgYm94LXNoYWRvdzogMCAwIDFweCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNSk7IH1cXG5cXG4uYmlvanNfbXNhX21hcmtlciB7XFxuICBjb2xvcjogZ3JleTtcXG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XFxuICBjdXJzb3I6IHBvaW50ZXI7IH1cXG5cXG4uYmlvanNfbXNhX21hcmtlciBzcGFuIHtcXG4gIHRleHQtYWxpZ246IGNlbnRlcjsgfVxcblxcbi5iaW9qc19tc2FfbWVudWJhciAuYmlvanNfbXNhX21lbnViYXJfYWxpbmsge1xcbiAgYmFja2dyb3VuZDogIzM0OThkYjtcXG4gIGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtbGluZWFyLWdyYWRpZW50KHRvcCwgIzM0OThkYiwgIzI5ODBiOSk7XFxuICBiYWNrZ3JvdW5kLWltYWdlOiAtbW96LWxpbmVhci1ncmFkaWVudCh0b3AsICMzNDk4ZGIsICMyOTgwYjkpO1xcbiAgYmFja2dyb3VuZC1pbWFnZTogLW1zLWxpbmVhci1ncmFkaWVudCh0b3AsICMzNDk4ZGIsICMyOTgwYjkpO1xcbiAgYmFja2dyb3VuZC1pbWFnZTogLW8tbGluZWFyLWdyYWRpZW50KHRvcCwgIzM0OThkYiwgIzI5ODBiOSk7XFxuICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gYm90dG9tLCAjMzQ5OGRiLCAjMjk4MGI5KTtcXG4gIC13ZWJraXQtYm9yZGVyLXJhZGl1czogMjg7XFxuICAtbW96LWJvcmRlci1yYWRpdXM6IDI4O1xcbiAgYm9yZGVyLXJhZGl1czogMjhweDtcXG4gIGZvbnQtZmFtaWx5OiBBcmlhbDtcXG4gIGNvbG9yOiAjZmZmZmZmO1xcbiAgcGFkZGluZzogM3B4IDEwcHggM3B4IDEwcHg7XFxuICBtYXJnaW4tbGVmdDogMTBweDtcXG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTsgfVxcblxcbi5iaW9qc19tc2FfbWVudWJhciAuYmlvanNfbXNhX21lbnViYXJfYWxpbms6aG92ZXIge1xcbiAgY3Vyc29yOiBwb2ludGVyOyB9XFxuXFxuLyoganF1ZXJ5IGRyb3Bkb3duIENTUyAqL1xcbi5kcm9wZG93biB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB6LWluZGV4OiA5OTk5OTk5O1xcbiAgZGlzcGxheTogbm9uZTsgfVxcblxcbi5kcm9wZG93biAuZHJvcGRvd24tbWVudSxcXG4uZHJvcGRvd24gLmRyb3Bkb3duLXBhbmVsIHtcXG4gIG1pbi13aWR0aDogMTYwcHg7XFxuICBtYXgtd2lkdGg6IDM2MHB4O1xcbiAgbGlzdC1zdHlsZTogbm9uZTtcXG4gIGJhY2tncm91bmQ6ICNGRkY7XFxuICBib3JkZXI6IHNvbGlkIDFweCAjREREO1xcbiAgYm9yZGVyOiBzb2xpZCAxcHggcmdiYSgwLCAwLCAwLCAwLjIpO1xcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xcbiAgYm94LXNoYWRvdzogMCA1cHggMTBweCByZ2JhKDAsIDAsIDAsIDAuMik7XFxuICBvdmVyZmxvdzogdmlzaWJsZTtcXG4gIHBhZGRpbmc6IDRweCAwO1xcbiAgbWFyZ2luOiAwOyB9XFxuXFxuLmRyb3Bkb3duIC5kcm9wZG93bi1wYW5lbCB7XFxuICBwYWRkaW5nOiAxMHB4OyB9XFxuXFxuLmRyb3Bkb3duLmRyb3Bkb3duLXNjcm9sbCAuZHJvcGRvd24tbWVudSxcXG4uZHJvcGRvd24uZHJvcGRvd24tc2Nyb2xsIC5kcm9wZG93bi1wYW5lbCB7XFxuICBtYXgtaGVpZ2h0OiAzNThweDtcXG4gIG92ZXJmbG93OiBhdXRvOyB9XFxuXFxuLmRyb3Bkb3duIC5kcm9wZG93bi1tZW51IExJIHtcXG4gIGxpc3Qtc3R5bGU6IG5vbmU7XFxuICBwYWRkaW5nOiAwIDA7XFxuICBtYXJnaW46IDA7XFxuICBsaW5lLWhlaWdodDogMThweDsgfVxcblxcbi5kcm9wZG93biAuZHJvcGRvd24tbWVudSBMSSxcXG4uZHJvcGRvd24gLmRyb3Bkb3duLW1lbnUgTEFCRUwge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICBjb2xvcjogIzU1NTtcXG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcXG4gIGxpbmUtaGVpZ2h0OiAxOHB4O1xcbiAgcGFkZGluZzogM3B4IDE1cHg7XFxuICB3aGl0ZS1zcGFjZTogbm93cmFwOyB9XFxuXFxuLmRyb3Bkb3duIC5kcm9wZG93bi1tZW51IExJOmhvdmVyLFxcbi5kcm9wZG93biAuZHJvcGRvd24tbWVudSBMQUJFTDpob3ZlciB7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDhDO1xcbiAgY29sb3I6ICNGRkY7XFxuICBjdXJzb3I6IHBvaW50ZXI7IH1cXG5cXG4uZHJvcGRvd24gLmRyb3Bkb3duLW1lbnUgLmRyb3Bkb3duLWRpdmlkZXIge1xcbiAgZm9udC1zaXplOiAxcHg7XFxuICBib3JkZXItdG9wOiBzb2xpZCAxcHggI0U1RTVFNTtcXG4gIHBhZGRpbmc6IDA7XFxuICBtYXJnaW46IDVweCAwOyB9XFxuXCI7IChyZXF1aXJlKFwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Nzc2lmeVwiKSkoY3NzKTsgbW9kdWxlLmV4cG9ydHMgPSBjc3M7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9zcmMvaW5kZXhcIik7XG4iLCJ2YXIgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcbnZhciB2aWV3VHlwZSA9IHJlcXVpcmUoXCJiYWNrYm9uZS12aWV3alwiKTtcbnZhciBwbHVnaW5hdG9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHBsdWdpbmF0b3IgPSB2aWV3VHlwZS5leHRlbmQoe1xuICByZW5kZXJTdWJ2aWV3czogZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9sZEVsID0gdGhpcy5lbDtcbiAgICB2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIHRoaXMuc2V0RWxlbWVudChlbCk7XG4gICAgdmFyIGZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgaWYgKG9sZEVsLnBhcmVudE5vZGUgIT0gbnVsbCkge1xuICAgICAgb2xkRWwucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQodGhpcy5lbCwgb2xkRWwpO1xuICAgIH1cbiAgICB2YXIgdmlld3MgPSB0aGlzLl92aWV3cygpO1xuICAgIHZhciB2aWV3c1NvcnRlZCA9IF8uc29ydEJ5KHZpZXdzLCBmdW5jdGlvbihlbCkge1xuICAgICAgcmV0dXJuIGVsLm9yZGVyaW5nO1xuICAgIH0pO1xuICAgIHZhciB2aWV3LCBub2RlO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgIHZpZXdzU29ydGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2aWV3ID0gdmlld3NTb3J0ZWRbaV07XG4gICAgICB2aWV3LnJlbmRlcigpO1xuICAgICAgbm9kZSA9IHZpZXcuZWw7XG4gICAgICBpZiAobm9kZSAhPSBudWxsKSB7XG4gICAgICAgIGZyYWcuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGVsLmFwcGVuZENoaWxkKGZyYWcpO1xuICAgIHJldHVybiBlbDtcbiAgfSxcbiAgYWRkVmlldzogZnVuY3Rpb24oa2V5LCB2aWV3KSB7XG4gICAgdmFyIHZpZXdzID0gdGhpcy5fdmlld3MoKTtcbiAgICBpZiAodmlldyA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBcIkludmFsaWQgcGx1Z2luLiBcIjtcbiAgICB9XG4gICAgaWYgKHZpZXcub3JkZXJpbmcgPT0gbnVsbCkge1xuICAgICAgdmlldy5vcmRlcmluZyA9IGtleTtcbiAgICB9XG4gICAgcmV0dXJuIHZpZXdzW2tleV0gPSB2aWV3O1xuICB9LFxuICByZW1vdmVWaWV3czogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGVsLCBrZXk7XG4gICAgdmFyIHZpZXdzID0gdGhpcy5fdmlld3MoKTtcbiAgICBmb3IgKGtleSBpbiB2aWV3cykge1xuICAgICAgZWwgPSB2aWV3c1trZXldO1xuICAgICAgZWwudW5kZWxlZ2F0ZUV2ZW50cygpO1xuICAgICAgZWwudW5iaW5kKCk7XG4gICAgICBpZiAoZWwucmVtb3ZlVmlld3MgIT0gbnVsbCkge1xuICAgICAgICBlbC5yZW1vdmVWaWV3cygpO1xuICAgICAgfVxuICAgICAgZWwucmVtb3ZlKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnZpZXdzID0ge307XG4gIH0sXG4gIHJlbW92ZVZpZXc6IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciB2aWV3cyA9IHRoaXMuX3ZpZXdzKCk7XG4gICAgdmlld3Nba2V5XS5yZW1vdmUoKTtcbiAgICByZXR1cm4gZGVsZXRlIHZpZXdzW2tleV07XG4gIH0sXG4gIGdldFZpZXc6IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciB2aWV3cyA9IHRoaXMuX3ZpZXdzKCk7XG4gICAgcmV0dXJuIHZpZXdzW2tleV07XG4gIH0sXG4gIHJlbW92ZTogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5yZW1vdmVWaWV3cygpO1xuICAgIHJldHVybiB2aWV3VHlwZS5wcm90b3R5cGUucmVtb3ZlLmFwcGx5KHRoaXMpO1xuICB9LFxuICBfdmlld3M6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLnZpZXdzID09IG51bGwpIHtcbiAgICAgIHRoaXMudmlld3MgPSB7fTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudmlld3M7XG4gIH1cbn0pO1xuIiwiLy8gICAgIEJhY2tib25lLmpzIDEuMS4yXG5cbi8vICAgICAoYykgMjAxMC0yMDE0IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4vLyAgICAgQmFja2JvbmUgbWF5IGJlIGZyZWVseSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXG4vLyAgICAgRm9yIGFsbCBkZXRhaWxzIGFuZCBkb2N1bWVudGF0aW9uOlxuLy8gICAgIGh0dHA6Ly9iYWNrYm9uZWpzLm9yZ1xuXG52YXIgRXZlbnRzID0gcmVxdWlyZShcImJhY2tib25lLWV2ZW50cy1zdGFuZGFsb25lXCIpO1xudmFyIGV4dGVuZCA9IHJlcXVpcmUoXCJiYWNrYm9uZS1leHRlbmQtc3RhbmRhbG9uZVwiKTtcbnZhciBfID0gcmVxdWlyZShcInVuZGVyc2NvcmVcIik7XG52YXIgTW9kZWwgPSByZXF1aXJlKFwiLi9tb2RlbFwiKTtcblxuLy8gQ3JlYXRlIGxvY2FsIHJlZmVyZW5jZXMgdG8gYXJyYXkgbWV0aG9kcyB3ZSdsbCB3YW50IHRvIHVzZSBsYXRlci5cbnZhciBhcnJheSA9IFtdO1xudmFyIHNsaWNlID0gYXJyYXkuc2xpY2U7XG5cbi8vIEJhY2tib25lLkNvbGxlY3Rpb25cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gSWYgbW9kZWxzIHRlbmQgdG8gcmVwcmVzZW50IGEgc2luZ2xlIHJvdyBvZiBkYXRhLCBhIEJhY2tib25lIENvbGxlY3Rpb24gaXNcbi8vIG1vcmUgYW5hbG9nb3VzIHRvIGEgdGFibGUgZnVsbCBvZiBkYXRhIC4uLiBvciBhIHNtYWxsIHNsaWNlIG9yIHBhZ2Ugb2YgdGhhdFxuLy8gdGFibGUsIG9yIGEgY29sbGVjdGlvbiBvZiByb3dzIHRoYXQgYmVsb25nIHRvZ2V0aGVyIGZvciBhIHBhcnRpY3VsYXIgcmVhc29uXG4vLyAtLSBhbGwgb2YgdGhlIG1lc3NhZ2VzIGluIHRoaXMgcGFydGljdWxhciBmb2xkZXIsIGFsbCBvZiB0aGUgZG9jdW1lbnRzXG4vLyBiZWxvbmdpbmcgdG8gdGhpcyBwYXJ0aWN1bGFyIGF1dGhvciwgYW5kIHNvIG9uLiBDb2xsZWN0aW9ucyBtYWludGFpblxuLy8gaW5kZXhlcyBvZiB0aGVpciBtb2RlbHMsIGJvdGggaW4gb3JkZXIsIGFuZCBmb3IgbG9va3VwIGJ5IGBpZGAuXG5cbi8vIENyZWF0ZSBhIG5ldyAqKkNvbGxlY3Rpb24qKiwgcGVyaGFwcyB0byBjb250YWluIGEgc3BlY2lmaWMgdHlwZSBvZiBgbW9kZWxgLlxuLy8gSWYgYSBgY29tcGFyYXRvcmAgaXMgc3BlY2lmaWVkLCB0aGUgQ29sbGVjdGlvbiB3aWxsIG1haW50YWluXG4vLyBpdHMgbW9kZWxzIGluIHNvcnQgb3JkZXIsIGFzIHRoZXkncmUgYWRkZWQgYW5kIHJlbW92ZWQuXG52YXIgQ29sbGVjdGlvbiA9IGZ1bmN0aW9uKG1vZGVscywgb3B0aW9ucykge1xuICBvcHRpb25zIHx8IChvcHRpb25zID0ge30pO1xuICBpZiAob3B0aW9ucy5tb2RlbCkgdGhpcy5tb2RlbCA9IG9wdGlvbnMubW9kZWw7XG4gIGlmIChvcHRpb25zLmNvbXBhcmF0b3IgIT09IHZvaWQgMCkgdGhpcy5jb21wYXJhdG9yID0gb3B0aW9ucy5jb21wYXJhdG9yO1xuICB0aGlzLl9yZXNldCgpO1xuICB0aGlzLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgaWYgKG1vZGVscykgdGhpcy5yZXNldChtb2RlbHMsIF8uZXh0ZW5kKHtzaWxlbnQ6IHRydWV9LCBvcHRpb25zKSk7XG59O1xuXG4vLyBEZWZhdWx0IG9wdGlvbnMgZm9yIGBDb2xsZWN0aW9uI3NldGAuXG52YXIgc2V0T3B0aW9ucyA9IHthZGQ6IHRydWUsIHJlbW92ZTogdHJ1ZSwgbWVyZ2U6IHRydWV9O1xudmFyIGFkZE9wdGlvbnMgPSB7YWRkOiB0cnVlLCByZW1vdmU6IGZhbHNlfTtcblxuLy8gRGVmaW5lIHRoZSBDb2xsZWN0aW9uJ3MgaW5oZXJpdGFibGUgbWV0aG9kcy5cbl8uZXh0ZW5kKENvbGxlY3Rpb24ucHJvdG90eXBlLCBFdmVudHMsIHtcblxuICAvLyBUaGUgZGVmYXVsdCBtb2RlbCBmb3IgYSBjb2xsZWN0aW9uIGlzIGp1c3QgYSAqKkJhY2tib25lLk1vZGVsKiouXG4gIC8vIFRoaXMgc2hvdWxkIGJlIG92ZXJyaWRkZW4gaW4gbW9zdCBjYXNlcy5cbiAgbW9kZWw6IE1vZGVsLFxuXG4gIC8vIEluaXRpYWxpemUgaXMgYW4gZW1wdHkgZnVuY3Rpb24gYnkgZGVmYXVsdC4gT3ZlcnJpZGUgaXQgd2l0aCB5b3VyIG93blxuICAvLyBpbml0aWFsaXphdGlvbiBsb2dpYy5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXt9LFxuXG4gICAgLy8gVGhlIEpTT04gcmVwcmVzZW50YXRpb24gb2YgYSBDb2xsZWN0aW9uIGlzIGFuIGFycmF5IG9mIHRoZVxuICAgIC8vIG1vZGVscycgYXR0cmlidXRlcy5cbiAgdG9KU09OOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKG1vZGVsKXsgcmV0dXJuIG1vZGVsLnRvSlNPTihvcHRpb25zKTsgfSk7XG4gIH0sXG5cbiAgICAvLyBQcm94eSBgQmFja2JvbmUuc3luY2AgYnkgZGVmYXVsdC5cbiAgc3luYzogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIEJhY2tib25lLnN5bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfSxcblxuICAgIC8vIEFkZCBhIG1vZGVsLCBvciBsaXN0IG9mIG1vZGVscyB0byB0aGUgc2V0LlxuICBhZGQ6IGZ1bmN0aW9uKG1vZGVscywgb3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLnNldChtb2RlbHMsIF8uZXh0ZW5kKHttZXJnZTogZmFsc2V9LCBvcHRpb25zLCBhZGRPcHRpb25zKSk7XG4gIH0sXG5cbiAgICAvLyBSZW1vdmUgYSBtb2RlbCwgb3IgYSBsaXN0IG9mIG1vZGVscyBmcm9tIHRoZSBzZXQuXG4gIHJlbW92ZTogZnVuY3Rpb24obW9kZWxzLCBvcHRpb25zKSB7XG4gICAgdmFyIHNpbmd1bGFyID0gIV8uaXNBcnJheShtb2RlbHMpO1xuICAgIG1vZGVscyA9IHNpbmd1bGFyID8gW21vZGVsc10gOiBfLmNsb25lKG1vZGVscyk7XG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gbW9kZWxzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbW9kZWwgPSBtb2RlbHNbaV0gPSB0aGlzLmdldChtb2RlbHNbaV0pO1xuICAgICAgaWYgKCFtb2RlbCkgY29udGludWU7XG4gICAgICB2YXIgaWQgPSB0aGlzLm1vZGVsSWQobW9kZWwuYXR0cmlidXRlcyk7XG4gICAgICBpZiAoaWQgIT0gbnVsbCkgZGVsZXRlIHRoaXMuX2J5SWRbaWRdO1xuICAgICAgZGVsZXRlIHRoaXMuX2J5SWRbbW9kZWwuY2lkXTtcbiAgICAgIHZhciBpbmRleCA9IHRoaXMuaW5kZXhPZihtb2RlbCk7XG4gICAgICB0aGlzLm1vZGVscy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgdGhpcy5sZW5ndGgtLTtcbiAgICAgIGlmICghb3B0aW9ucy5zaWxlbnQpIHtcbiAgICAgICAgb3B0aW9ucy5pbmRleCA9IGluZGV4O1xuICAgICAgICBtb2RlbC50cmlnZ2VyKCdyZW1vdmUnLCBtb2RlbCwgdGhpcywgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICB0aGlzLl9yZW1vdmVSZWZlcmVuY2UobW9kZWwsIG9wdGlvbnMpO1xuICAgIH1cbiAgICByZXR1cm4gc2luZ3VsYXIgPyBtb2RlbHNbMF0gOiBtb2RlbHM7XG4gIH0sXG5cbiAgICAvLyBVcGRhdGUgYSBjb2xsZWN0aW9uIGJ5IGBzZXRgLWluZyBhIG5ldyBsaXN0IG9mIG1vZGVscywgYWRkaW5nIG5ldyBvbmVzLFxuICAgIC8vIHJlbW92aW5nIG1vZGVscyB0aGF0IGFyZSBubyBsb25nZXIgcHJlc2VudCwgYW5kIG1lcmdpbmcgbW9kZWxzIHRoYXRcbiAgICAvLyBhbHJlYWR5IGV4aXN0IGluIHRoZSBjb2xsZWN0aW9uLCBhcyBuZWNlc3NhcnkuIFNpbWlsYXIgdG8gKipNb2RlbCNzZXQqKixcbiAgICAvLyB0aGUgY29yZSBvcGVyYXRpb24gZm9yIHVwZGF0aW5nIHRoZSBkYXRhIGNvbnRhaW5lZCBieSB0aGUgY29sbGVjdGlvbi5cbiAgc2V0OiBmdW5jdGlvbihtb2RlbHMsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gXy5kZWZhdWx0cyh7fSwgb3B0aW9ucywgc2V0T3B0aW9ucyk7XG4gICAgaWYgKG9wdGlvbnMucGFyc2UpIG1vZGVscyA9IHRoaXMucGFyc2UobW9kZWxzLCBvcHRpb25zKTtcbiAgICB2YXIgc2luZ3VsYXIgPSAhXy5pc0FycmF5KG1vZGVscyk7XG4gICAgbW9kZWxzID0gc2luZ3VsYXIgPyAobW9kZWxzID8gW21vZGVsc10gOiBbXSkgOiBtb2RlbHMuc2xpY2UoKTtcbiAgICB2YXIgaWQsIG1vZGVsLCBhdHRycywgZXhpc3RpbmcsIHNvcnQ7XG4gICAgdmFyIGF0ID0gb3B0aW9ucy5hdDtcbiAgICB2YXIgc29ydGFibGUgPSB0aGlzLmNvbXBhcmF0b3IgJiYgKGF0ID09IG51bGwpICYmIG9wdGlvbnMuc29ydCAhPT0gZmFsc2U7XG4gICAgdmFyIHNvcnRBdHRyID0gXy5pc1N0cmluZyh0aGlzLmNvbXBhcmF0b3IpID8gdGhpcy5jb21wYXJhdG9yIDogbnVsbDtcbiAgICB2YXIgdG9BZGQgPSBbXSwgdG9SZW1vdmUgPSBbXSwgbW9kZWxNYXAgPSB7fTtcbiAgICB2YXIgYWRkID0gb3B0aW9ucy5hZGQsIG1lcmdlID0gb3B0aW9ucy5tZXJnZSwgcmVtb3ZlID0gb3B0aW9ucy5yZW1vdmU7XG4gICAgdmFyIG9yZGVyID0gIXNvcnRhYmxlICYmIGFkZCAmJiByZW1vdmUgPyBbXSA6IGZhbHNlO1xuXG4gICAgLy8gVHVybiBiYXJlIG9iamVjdHMgaW50byBtb2RlbCByZWZlcmVuY2VzLCBhbmQgcHJldmVudCBpbnZhbGlkIG1vZGVsc1xuICAgIC8vIGZyb20gYmVpbmcgYWRkZWQuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IG1vZGVscy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgYXR0cnMgPSBtb2RlbHNbaV07XG5cbiAgICAgIC8vIElmIGEgZHVwbGljYXRlIGlzIGZvdW5kLCBwcmV2ZW50IGl0IGZyb20gYmVpbmcgYWRkZWQgYW5kXG4gICAgICAvLyBvcHRpb25hbGx5IG1lcmdlIGl0IGludG8gdGhlIGV4aXN0aW5nIG1vZGVsLlxuICAgICAgaWYgKGV4aXN0aW5nID0gdGhpcy5nZXQoYXR0cnMpKSB7XG4gICAgICAgIGlmIChyZW1vdmUpIG1vZGVsTWFwW2V4aXN0aW5nLmNpZF0gPSB0cnVlO1xuICAgICAgICBpZiAobWVyZ2UgJiYgYXR0cnMgIT09IGV4aXN0aW5nKSB7XG4gICAgICAgICAgYXR0cnMgPSB0aGlzLl9pc01vZGVsKGF0dHJzKSA/IGF0dHJzLmF0dHJpYnV0ZXMgOiBhdHRycztcbiAgICAgICAgICBpZiAob3B0aW9ucy5wYXJzZSkgYXR0cnMgPSBleGlzdGluZy5wYXJzZShhdHRycywgb3B0aW9ucyk7XG4gICAgICAgICAgZXhpc3Rpbmcuc2V0KGF0dHJzLCBvcHRpb25zKTtcbiAgICAgICAgICBpZiAoc29ydGFibGUgJiYgIXNvcnQgJiYgZXhpc3RpbmcuaGFzQ2hhbmdlZChzb3J0QXR0cikpIHNvcnQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIG1vZGVsc1tpXSA9IGV4aXN0aW5nO1xuXG4gICAgICAgIC8vIElmIHRoaXMgaXMgYSBuZXcsIHZhbGlkIG1vZGVsLCBwdXNoIGl0IHRvIHRoZSBgdG9BZGRgIGxpc3QuXG4gICAgICB9IGVsc2UgaWYgKGFkZCkge1xuICAgICAgICBtb2RlbCA9IG1vZGVsc1tpXSA9IHRoaXMuX3ByZXBhcmVNb2RlbChhdHRycywgb3B0aW9ucyk7XG4gICAgICAgIGlmICghbW9kZWwpIGNvbnRpbnVlO1xuICAgICAgICB0b0FkZC5wdXNoKG1vZGVsKTtcbiAgICAgICAgdGhpcy5fYWRkUmVmZXJlbmNlKG1vZGVsLCBvcHRpb25zKTtcbiAgICAgIH1cblxuICAgICAgLy8gRG8gbm90IGFkZCBtdWx0aXBsZSBtb2RlbHMgd2l0aCB0aGUgc2FtZSBgaWRgLlxuICAgICAgbW9kZWwgPSBleGlzdGluZyB8fCBtb2RlbDtcbiAgICAgIGlmICghbW9kZWwpIGNvbnRpbnVlO1xuICAgICAgaWQgPSB0aGlzLm1vZGVsSWQobW9kZWwuYXR0cmlidXRlcyk7XG4gICAgICBpZiAob3JkZXIgJiYgKG1vZGVsLmlzTmV3KCkgfHwgIW1vZGVsTWFwW2lkXSkpIG9yZGVyLnB1c2gobW9kZWwpO1xuICAgICAgbW9kZWxNYXBbaWRdID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgbm9uZXhpc3RlbnQgbW9kZWxzIGlmIGFwcHJvcHJpYXRlLlxuICAgIGlmIChyZW1vdmUpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSB0aGlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICghbW9kZWxNYXBbKG1vZGVsID0gdGhpcy5tb2RlbHNbaV0pLmNpZF0pIHRvUmVtb3ZlLnB1c2gobW9kZWwpO1xuICAgICAgfVxuICAgICAgaWYgKHRvUmVtb3ZlLmxlbmd0aCkgdGhpcy5yZW1vdmUodG9SZW1vdmUsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8vIFNlZSBpZiBzb3J0aW5nIGlzIG5lZWRlZCwgdXBkYXRlIGBsZW5ndGhgIGFuZCBzcGxpY2UgaW4gbmV3IG1vZGVscy5cbiAgICBpZiAodG9BZGQubGVuZ3RoIHx8IChvcmRlciAmJiBvcmRlci5sZW5ndGgpKSB7XG4gICAgICBpZiAoc29ydGFibGUpIHNvcnQgPSB0cnVlO1xuICAgICAgdGhpcy5sZW5ndGggKz0gdG9BZGQubGVuZ3RoO1xuICAgICAgaWYgKGF0ICE9IG51bGwpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IHRvQWRkLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdGhpcy5tb2RlbHMuc3BsaWNlKGF0ICsgaSwgMCwgdG9BZGRbaV0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAob3JkZXIpIHRoaXMubW9kZWxzLmxlbmd0aCA9IDA7XG4gICAgICAgIHZhciBvcmRlcmVkTW9kZWxzID0gb3JkZXIgfHwgdG9BZGQ7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBvcmRlcmVkTW9kZWxzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdGhpcy5tb2RlbHMucHVzaChvcmRlcmVkTW9kZWxzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNpbGVudGx5IHNvcnQgdGhlIGNvbGxlY3Rpb24gaWYgYXBwcm9wcmlhdGUuXG4gICAgaWYgKHNvcnQpIHRoaXMuc29ydCh7c2lsZW50OiB0cnVlfSk7XG5cbiAgICAvLyBVbmxlc3Mgc2lsZW5jZWQsIGl0J3MgdGltZSB0byBmaXJlIGFsbCBhcHByb3ByaWF0ZSBhZGQvc29ydCBldmVudHMuXG4gICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgICAgdmFyIGFkZE9wdHMgPSBhdCAhPSBudWxsID8gXy5jbG9uZShvcHRpb25zKSA6IG9wdGlvbnM7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gdG9BZGQubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGF0ICE9IG51bGwpIGFkZE9wdHMuaW5kZXggPSBhdCArIGk7XG4gICAgICAgIChtb2RlbCA9IHRvQWRkW2ldKS50cmlnZ2VyKCdhZGQnLCBtb2RlbCwgdGhpcywgYWRkT3B0cyk7XG4gICAgICB9XG4gICAgICBpZiAoc29ydCB8fCAob3JkZXIgJiYgb3JkZXIubGVuZ3RoKSkgdGhpcy50cmlnZ2VyKCdzb3J0JywgdGhpcywgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIHRoZSBhZGRlZCAob3IgbWVyZ2VkKSBtb2RlbCAob3IgbW9kZWxzKS5cbiAgICByZXR1cm4gc2luZ3VsYXIgPyBtb2RlbHNbMF0gOiBtb2RlbHM7XG4gIH0sXG5cbiAgICAvLyBXaGVuIHlvdSBoYXZlIG1vcmUgaXRlbXMgdGhhbiB5b3Ugd2FudCB0byBhZGQgb3IgcmVtb3ZlIGluZGl2aWR1YWxseSxcbiAgICAvLyB5b3UgY2FuIHJlc2V0IHRoZSBlbnRpcmUgc2V0IHdpdGggYSBuZXcgbGlzdCBvZiBtb2RlbHMsIHdpdGhvdXQgZmlyaW5nXG4gICAgLy8gYW55IGdyYW51bGFyIGBhZGRgIG9yIGByZW1vdmVgIGV2ZW50cy4gRmlyZXMgYHJlc2V0YCB3aGVuIGZpbmlzaGVkLlxuICAgIC8vIFVzZWZ1bCBmb3IgYnVsayBvcGVyYXRpb25zIGFuZCBvcHRpbWl6YXRpb25zLlxuICByZXNldDogZnVuY3Rpb24obW9kZWxzLCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gdGhpcy5tb2RlbHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuX3JlbW92ZVJlZmVyZW5jZSh0aGlzLm1vZGVsc1tpXSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIG9wdGlvbnMucHJldmlvdXNNb2RlbHMgPSB0aGlzLm1vZGVscztcbiAgICB0aGlzLl9yZXNldCgpO1xuICAgIG1vZGVscyA9IHRoaXMuYWRkKG1vZGVscywgXy5leHRlbmQoe3NpbGVudDogdHJ1ZX0sIG9wdGlvbnMpKTtcbiAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB0aGlzLnRyaWdnZXIoJ3Jlc2V0JywgdGhpcywgb3B0aW9ucyk7XG4gICAgcmV0dXJuIG1vZGVscztcbiAgfSxcblxuICAgIC8vIEFkZCBhIG1vZGVsIHRvIHRoZSBlbmQgb2YgdGhlIGNvbGxlY3Rpb24uXG4gIHB1c2g6IGZ1bmN0aW9uKG1vZGVsLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkKG1vZGVsLCBfLmV4dGVuZCh7YXQ6IHRoaXMubGVuZ3RofSwgb3B0aW9ucykpO1xuICB9LFxuXG4gICAgLy8gUmVtb3ZlIGEgbW9kZWwgZnJvbSB0aGUgZW5kIG9mIHRoZSBjb2xsZWN0aW9uLlxuICBwb3A6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICB2YXIgbW9kZWwgPSB0aGlzLmF0KHRoaXMubGVuZ3RoIC0gMSk7XG4gICAgdGhpcy5yZW1vdmUobW9kZWwsIG9wdGlvbnMpO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfSxcblxuICAgIC8vIEFkZCBhIG1vZGVsIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGNvbGxlY3Rpb24uXG4gIHVuc2hpZnQ6IGZ1bmN0aW9uKG1vZGVsLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkKG1vZGVsLCBfLmV4dGVuZCh7YXQ6IDB9LCBvcHRpb25zKSk7XG4gIH0sXG5cbiAgICAvLyBSZW1vdmUgYSBtb2RlbCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGNvbGxlY3Rpb24uXG4gIHNoaWZ0OiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgdmFyIG1vZGVsID0gdGhpcy5hdCgwKTtcbiAgICB0aGlzLnJlbW92ZShtb2RlbCwgb3B0aW9ucyk7XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9LFxuXG4gICAgLy8gU2xpY2Ugb3V0IGEgc3ViLWFycmF5IG9mIG1vZGVscyBmcm9tIHRoZSBjb2xsZWN0aW9uLlxuICBzbGljZTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNsaWNlLmFwcGx5KHRoaXMubW9kZWxzLCBhcmd1bWVudHMpO1xuICB9LFxuXG4gICAgLy8gR2V0IGEgbW9kZWwgZnJvbSB0aGUgc2V0IGJ5IGlkLlxuICBnZXQ6IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHZvaWQgMDtcbiAgICB2YXIgaWQgPSB0aGlzLm1vZGVsSWQodGhpcy5faXNNb2RlbChvYmopID8gb2JqLmF0dHJpYnV0ZXMgOiBvYmopO1xuICAgIHJldHVybiB0aGlzLl9ieUlkW29ial0gfHwgdGhpcy5fYnlJZFtpZF0gfHwgdGhpcy5fYnlJZFtvYmouY2lkXTtcbiAgfSxcblxuICAgIC8vIEdldCB0aGUgbW9kZWwgYXQgdGhlIGdpdmVuIGluZGV4LlxuICBhdDogZnVuY3Rpb24oaW5kZXgpIHtcbiAgICBpZiAoaW5kZXggPCAwKSBpbmRleCArPSB0aGlzLmxlbmd0aDtcbiAgICByZXR1cm4gdGhpcy5tb2RlbHNbaW5kZXhdO1xuICB9LFxuXG4gICAgLy8gUmV0dXJuIG1vZGVscyB3aXRoIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIFVzZWZ1bCBmb3Igc2ltcGxlIGNhc2VzIG9mXG4gICAgLy8gYGZpbHRlcmAuXG4gIHdoZXJlOiBmdW5jdGlvbihhdHRycywgZmlyc3QpIHtcbiAgICBpZiAoXy5pc0VtcHR5KGF0dHJzKSkgcmV0dXJuIGZpcnN0ID8gdm9pZCAwIDogW107XG4gICAgcmV0dXJuIHRoaXNbZmlyc3QgPyAnZmluZCcgOiAnZmlsdGVyJ10oZnVuY3Rpb24obW9kZWwpIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiBhdHRycykge1xuICAgICAgICBpZiAoYXR0cnNba2V5XSAhPT0gbW9kZWwuZ2V0KGtleSkpIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICB9LFxuXG4gICAgLy8gUmV0dXJuIHRoZSBmaXJzdCBtb2RlbCB3aXRoIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIFVzZWZ1bCBmb3Igc2ltcGxlIGNhc2VzXG4gICAgLy8gb2YgYGZpbmRgLlxuICBmaW5kV2hlcmU6IGZ1bmN0aW9uKGF0dHJzKSB7XG4gICAgcmV0dXJuIHRoaXMud2hlcmUoYXR0cnMsIHRydWUpO1xuICB9LFxuXG4gICAgLy8gRm9yY2UgdGhlIGNvbGxlY3Rpb24gdG8gcmUtc29ydCBpdHNlbGYuIFlvdSBkb24ndCBuZWVkIHRvIGNhbGwgdGhpcyB1bmRlclxuICAgIC8vIG5vcm1hbCBjaXJjdW1zdGFuY2VzLCBhcyB0aGUgc2V0IHdpbGwgbWFpbnRhaW4gc29ydCBvcmRlciBhcyBlYWNoIGl0ZW1cbiAgICAvLyBpcyBhZGRlZC5cbiAgc29ydDogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgIGlmICghdGhpcy5jb21wYXJhdG9yKSB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBzb3J0IGEgc2V0IHdpdGhvdXQgYSBjb21wYXJhdG9yJyk7XG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcblxuICAgIC8vIFJ1biBzb3J0IGJhc2VkIG9uIHR5cGUgb2YgYGNvbXBhcmF0b3JgLlxuICAgIGlmIChfLmlzU3RyaW5nKHRoaXMuY29tcGFyYXRvcikgfHwgdGhpcy5jb21wYXJhdG9yLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdGhpcy5tb2RlbHMgPSB0aGlzLnNvcnRCeSh0aGlzLmNvbXBhcmF0b3IsIHRoaXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1vZGVscy5zb3J0KF8uYmluZCh0aGlzLmNvbXBhcmF0b3IsIHRoaXMpKTtcbiAgICB9XG5cbiAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB0aGlzLnRyaWdnZXIoJ3NvcnQnLCB0aGlzLCBvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICAgIC8vIFBsdWNrIGFuIGF0dHJpYnV0ZSBmcm9tIGVhY2ggbW9kZWwgaW4gdGhlIGNvbGxlY3Rpb24uXG4gIHBsdWNrOiBmdW5jdGlvbihhdHRyKSB7XG4gICAgcmV0dXJuIF8uaW52b2tlKHRoaXMubW9kZWxzLCAnZ2V0JywgYXR0cik7XG4gIH0sXG5cbiAgICAvLyBGZXRjaCB0aGUgZGVmYXVsdCBzZXQgb2YgbW9kZWxzIGZvciB0aGlzIGNvbGxlY3Rpb24sIHJlc2V0dGluZyB0aGVcbiAgICAvLyBjb2xsZWN0aW9uIHdoZW4gdGhleSBhcnJpdmUuIElmIGByZXNldDogdHJ1ZWAgaXMgcGFzc2VkLCB0aGUgcmVzcG9uc2VcbiAgICAvLyBkYXRhIHdpbGwgYmUgcGFzc2VkIHRocm91Z2ggdGhlIGByZXNldGAgbWV0aG9kIGluc3RlYWQgb2YgYHNldGAuXG4gIGZldGNoOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgPyBfLmNsb25lKG9wdGlvbnMpIDoge307XG4gICAgaWYgKG9wdGlvbnMucGFyc2UgPT09IHZvaWQgMCkgb3B0aW9ucy5wYXJzZSA9IHRydWU7XG4gICAgdmFyIHN1Y2Nlc3MgPSBvcHRpb25zLnN1Y2Nlc3M7XG4gICAgdmFyIGNvbGxlY3Rpb24gPSB0aGlzO1xuICAgIG9wdGlvbnMuc3VjY2VzcyA9IGZ1bmN0aW9uKHJlc3ApIHtcbiAgICAgIHZhciBtZXRob2QgPSBvcHRpb25zLnJlc2V0ID8gJ3Jlc2V0JyA6ICdzZXQnO1xuICAgICAgY29sbGVjdGlvblttZXRob2RdKHJlc3AsIG9wdGlvbnMpO1xuICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MoY29sbGVjdGlvbiwgcmVzcCwgb3B0aW9ucyk7XG4gICAgICBjb2xsZWN0aW9uLnRyaWdnZXIoJ3N5bmMnLCBjb2xsZWN0aW9uLCByZXNwLCBvcHRpb25zKTtcbiAgICB9O1xuICAgIHdyYXBFcnJvcih0aGlzLCBvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5zeW5jKCdyZWFkJywgdGhpcywgb3B0aW9ucyk7XG4gIH0sXG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgYSBtb2RlbCBpbiB0aGlzIGNvbGxlY3Rpb24uIEFkZCB0aGUgbW9kZWwgdG8gdGhlXG4gICAgLy8gY29sbGVjdGlvbiBpbW1lZGlhdGVseSwgdW5sZXNzIGB3YWl0OiB0cnVlYCBpcyBwYXNzZWQsIGluIHdoaWNoIGNhc2Ugd2VcbiAgICAvLyB3YWl0IGZvciB0aGUgc2VydmVyIHRvIGFncmVlLlxuICBjcmVhdGU6IGZ1bmN0aW9uKG1vZGVsLCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgPyBfLmNsb25lKG9wdGlvbnMpIDoge307XG4gICAgaWYgKCEobW9kZWwgPSB0aGlzLl9wcmVwYXJlTW9kZWwobW9kZWwsIG9wdGlvbnMpKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghb3B0aW9ucy53YWl0KSB0aGlzLmFkZChtb2RlbCwgb3B0aW9ucyk7XG4gICAgdmFyIGNvbGxlY3Rpb24gPSB0aGlzO1xuICAgIHZhciBzdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzO1xuICAgIG9wdGlvbnMuc3VjY2VzcyA9IGZ1bmN0aW9uKG1vZGVsLCByZXNwKSB7XG4gICAgICBpZiAob3B0aW9ucy53YWl0KSBjb2xsZWN0aW9uLmFkZChtb2RlbCwgb3B0aW9ucyk7XG4gICAgICBpZiAoc3VjY2Vzcykgc3VjY2Vzcyhtb2RlbCwgcmVzcCwgb3B0aW9ucyk7XG4gICAgfTtcbiAgICBtb2RlbC5zYXZlKG51bGwsIG9wdGlvbnMpO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfSxcblxuICAgIC8vICoqcGFyc2UqKiBjb252ZXJ0cyBhIHJlc3BvbnNlIGludG8gYSBsaXN0IG9mIG1vZGVscyB0byBiZSBhZGRlZCB0byB0aGVcbiAgICAvLyBjb2xsZWN0aW9uLiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBqdXN0IHRvIHBhc3MgaXQgdGhyb3VnaC5cbiAgcGFyc2U6IGZ1bmN0aW9uKHJlc3AsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gcmVzcDtcbiAgfSxcblxuICAgIC8vIENyZWF0ZSBhIG5ldyBjb2xsZWN0aW9uIHdpdGggYW4gaWRlbnRpY2FsIGxpc3Qgb2YgbW9kZWxzIGFzIHRoaXMgb25lLlxuICBjbG9uZTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMubW9kZWxzLCB7XG4gICAgICBtb2RlbDogdGhpcy5tb2RlbCxcbiAgICAgIGNvbXBhcmF0b3I6IHRoaXMuY29tcGFyYXRvclxuICAgIH0pO1xuICB9LFxuXG4gICAgLy8gRGVmaW5lIGhvdyB0byB1bmlxdWVseSBpZGVudGlmeSBtb2RlbHMgaW4gdGhlIGNvbGxlY3Rpb24uXG4gIG1vZGVsSWQ6IGZ1bmN0aW9uIChhdHRycykge1xuICAgIHJldHVybiBhdHRyc1t0aGlzLm1vZGVsLnByb3RvdHlwZS5pZEF0dHJpYnV0ZSB8fCAnaWQnXTtcbiAgfSxcblxuICAgIC8vIFByaXZhdGUgbWV0aG9kIHRvIHJlc2V0IGFsbCBpbnRlcm5hbCBzdGF0ZS4gQ2FsbGVkIHdoZW4gdGhlIGNvbGxlY3Rpb25cbiAgICAvLyBpcyBmaXJzdCBpbml0aWFsaXplZCBvciByZXNldC5cbiAgX3Jlc2V0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLmxlbmd0aCA9IDA7XG4gICAgdGhpcy5tb2RlbHMgPSBbXTtcbiAgICB0aGlzLl9ieUlkICA9IHt9O1xuICB9LFxuXG4gICAgLy8gUHJlcGFyZSBhIGhhc2ggb2YgYXR0cmlidXRlcyAob3Igb3RoZXIgbW9kZWwpIHRvIGJlIGFkZGVkIHRvIHRoaXNcbiAgICAvLyBjb2xsZWN0aW9uLlxuICBfcHJlcGFyZU1vZGVsOiBmdW5jdGlvbihhdHRycywgb3B0aW9ucykge1xuICAgIGlmICh0aGlzLl9pc01vZGVsKGF0dHJzKSkge1xuICAgICAgaWYgKCFhdHRycy5jb2xsZWN0aW9uKSBhdHRycy5jb2xsZWN0aW9uID0gdGhpcztcbiAgICAgIHJldHVybiBhdHRycztcbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgPyBfLmNsb25lKG9wdGlvbnMpIDoge307XG4gICAgb3B0aW9ucy5jb2xsZWN0aW9uID0gdGhpcztcbiAgICB2YXIgbW9kZWwgPSBuZXcgdGhpcy5tb2RlbChhdHRycywgb3B0aW9ucyk7XG4gICAgaWYgKCFtb2RlbC52YWxpZGF0aW9uRXJyb3IpIHJldHVybiBtb2RlbDtcbiAgICB0aGlzLnRyaWdnZXIoJ2ludmFsaWQnLCB0aGlzLCBtb2RlbC52YWxpZGF0aW9uRXJyb3IsIG9wdGlvbnMpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcblxuICAgIC8vIE1ldGhvZCBmb3IgY2hlY2tpbmcgd2hldGhlciBhbiBvYmplY3Qgc2hvdWxkIGJlIGNvbnNpZGVyZWQgYSBtb2RlbCBmb3JcbiAgICAvLyB0aGUgcHVycG9zZXMgb2YgYWRkaW5nIHRvIHRoZSBjb2xsZWN0aW9uLlxuICBfaXNNb2RlbDogZnVuY3Rpb24gKG1vZGVsKSB7XG4gICAgcmV0dXJuIG1vZGVsIGluc3RhbmNlb2YgTW9kZWw7XG4gIH0sXG5cbiAgICAvLyBJbnRlcm5hbCBtZXRob2QgdG8gY3JlYXRlIGEgbW9kZWwncyB0aWVzIHRvIGEgY29sbGVjdGlvbi5cbiAgX2FkZFJlZmVyZW5jZTogZnVuY3Rpb24obW9kZWwsIG9wdGlvbnMpIHtcbiAgICB0aGlzLl9ieUlkW21vZGVsLmNpZF0gPSBtb2RlbDtcbiAgICB2YXIgaWQgPSB0aGlzLm1vZGVsSWQobW9kZWwuYXR0cmlidXRlcyk7XG4gICAgaWYgKGlkICE9IG51bGwpIHRoaXMuX2J5SWRbaWRdID0gbW9kZWw7XG4gICAgbW9kZWwub24oJ2FsbCcsIHRoaXMuX29uTW9kZWxFdmVudCwgdGhpcyk7XG4gIH0sXG5cbiAgICAvLyBJbnRlcm5hbCBtZXRob2QgdG8gc2V2ZXIgYSBtb2RlbCdzIHRpZXMgdG8gYSBjb2xsZWN0aW9uLlxuICBfcmVtb3ZlUmVmZXJlbmNlOiBmdW5jdGlvbihtb2RlbCwgb3B0aW9ucykge1xuICAgIGlmICh0aGlzID09PSBtb2RlbC5jb2xsZWN0aW9uKSBkZWxldGUgbW9kZWwuY29sbGVjdGlvbjtcbiAgICBtb2RlbC5vZmYoJ2FsbCcsIHRoaXMuX29uTW9kZWxFdmVudCwgdGhpcyk7XG4gIH0sXG5cbiAgICAvLyBJbnRlcm5hbCBtZXRob2QgY2FsbGVkIGV2ZXJ5IHRpbWUgYSBtb2RlbCBpbiB0aGUgc2V0IGZpcmVzIGFuIGV2ZW50LlxuICAgIC8vIFNldHMgbmVlZCB0byB1cGRhdGUgdGhlaXIgaW5kZXhlcyB3aGVuIG1vZGVscyBjaGFuZ2UgaWRzLiBBbGwgb3RoZXJcbiAgICAvLyBldmVudHMgc2ltcGx5IHByb3h5IHRocm91Z2guIFwiYWRkXCIgYW5kIFwicmVtb3ZlXCIgZXZlbnRzIHRoYXQgb3JpZ2luYXRlXG4gICAgLy8gaW4gb3RoZXIgY29sbGVjdGlvbnMgYXJlIGlnbm9yZWQuXG4gIF9vbk1vZGVsRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50LCBtb2RlbCwgY29sbGVjdGlvbiwgb3B0aW9ucykge1xuICAgIGlmICgoZXZlbnQgPT09ICdhZGQnIHx8IGV2ZW50ID09PSAncmVtb3ZlJykgJiYgY29sbGVjdGlvbiAhPT0gdGhpcykgcmV0dXJuO1xuICAgIGlmIChldmVudCA9PT0gJ2Rlc3Ryb3knKSB0aGlzLnJlbW92ZShtb2RlbCwgb3B0aW9ucyk7XG4gICAgaWYgKGV2ZW50ID09PSAnY2hhbmdlJykge1xuICAgICAgdmFyIHByZXZJZCA9IHRoaXMubW9kZWxJZChtb2RlbC5wcmV2aW91c0F0dHJpYnV0ZXMoKSk7XG4gICAgICB2YXIgaWQgPSB0aGlzLm1vZGVsSWQobW9kZWwuYXR0cmlidXRlcyk7XG4gICAgICBpZiAocHJldklkICE9PSBpZCkge1xuICAgICAgICBpZiAocHJldklkICE9IG51bGwpIGRlbGV0ZSB0aGlzLl9ieUlkW3ByZXZJZF07XG4gICAgICAgIGlmIChpZCAhPSBudWxsKSB0aGlzLl9ieUlkW2lkXSA9IG1vZGVsO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnRyaWdnZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG59KTtcblxuLy8gVW5kZXJzY29yZSBtZXRob2RzIHRoYXQgd2Ugd2FudCB0byBpbXBsZW1lbnQgb24gdGhlIENvbGxlY3Rpb24uXG4vLyA5MCUgb2YgdGhlIGNvcmUgdXNlZnVsbmVzcyBvZiBCYWNrYm9uZSBDb2xsZWN0aW9ucyBpcyBhY3R1YWxseSBpbXBsZW1lbnRlZFxuLy8gcmlnaHQgaGVyZTpcbnZhciBtZXRob2RzID0gWydmb3JFYWNoJywgJ2VhY2gnLCAnbWFwJywgJ2NvbGxlY3QnLCAncmVkdWNlJywgJ2ZvbGRsJyxcbiAgICAnaW5qZWN0JywgJ3JlZHVjZVJpZ2h0JywgJ2ZvbGRyJywgJ2ZpbmQnLCAnZGV0ZWN0JywgJ2ZpbHRlcicsICdzZWxlY3QnLFxuICAgICdyZWplY3QnLCAnZXZlcnknLCAnYWxsJywgJ3NvbWUnLCAnYW55JywgJ2luY2x1ZGUnLCAnY29udGFpbnMnLCAnaW52b2tlJyxcbiAgICAnbWF4JywgJ21pbicsICd0b0FycmF5JywgJ3NpemUnLCAnZmlyc3QnLCAnaGVhZCcsICd0YWtlJywgJ2luaXRpYWwnLCAncmVzdCcsXG4gICAgJ3RhaWwnLCAnZHJvcCcsICdsYXN0JywgJ3dpdGhvdXQnLCAnZGlmZmVyZW5jZScsICdpbmRleE9mJywgJ3NodWZmbGUnLFxuICAgICdsYXN0SW5kZXhPZicsICdpc0VtcHR5JywgJ2NoYWluJywgJ3NhbXBsZScsICdwYXJ0aXRpb24nXTtcblxuLy8gTWl4IGluIGVhY2ggVW5kZXJzY29yZSBtZXRob2QgYXMgYSBwcm94eSB0byBgQ29sbGVjdGlvbiNtb2RlbHNgLlxuXy5lYWNoKG1ldGhvZHMsIGZ1bmN0aW9uKG1ldGhvZCkge1xuICBpZiAoIV9bbWV0aG9kXSkgcmV0dXJuO1xuICBDb2xsZWN0aW9uLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgYXJncy51bnNoaWZ0KHRoaXMubW9kZWxzKTtcbiAgICByZXR1cm4gX1ttZXRob2RdLmFwcGx5KF8sIGFyZ3MpO1xuICB9O1xufSk7XG5cbi8vIFVuZGVyc2NvcmUgbWV0aG9kcyB0aGF0IHRha2UgYSBwcm9wZXJ0eSBuYW1lIGFzIGFuIGFyZ3VtZW50LlxudmFyIGF0dHJpYnV0ZU1ldGhvZHMgPSBbJ2dyb3VwQnknLCAnY291bnRCeScsICdzb3J0QnknLCAnaW5kZXhCeSddO1xuXG4vLyBVc2UgYXR0cmlidXRlcyBpbnN0ZWFkIG9mIHByb3BlcnRpZXMuXG5fLmVhY2goYXR0cmlidXRlTWV0aG9kcywgZnVuY3Rpb24obWV0aG9kKSB7XG4gIGlmICghX1ttZXRob2RdKSByZXR1cm47XG4gIENvbGxlY3Rpb24ucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbih2YWx1ZSwgY29udGV4dCkge1xuICAgIHZhciBpdGVyYXRvciA9IF8uaXNGdW5jdGlvbih2YWx1ZSkgPyB2YWx1ZSA6IGZ1bmN0aW9uKG1vZGVsKSB7XG4gICAgICByZXR1cm4gbW9kZWwuZ2V0KHZhbHVlKTtcbiAgICB9O1xuICAgIHJldHVybiBfW21ldGhvZF0odGhpcy5tb2RlbHMsIGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgfTtcbn0pO1xuXG4vLyBzZXR1cCBpbmhlcml0YW5jZVxuQ29sbGVjdGlvbi5leHRlbmQgPSBleHRlbmQ7XG5tb2R1bGUuZXhwb3J0cyA9IENvbGxlY3Rpb247XG4iLCJtb2R1bGUuZXhwb3J0cy5Nb2RlbCA9IHJlcXVpcmUoXCIuL21vZGVsXCIpO1xubW9kdWxlLmV4cG9ydHMuQ29sbGVjdGlvbiA9IHJlcXVpcmUoXCIuL2NvbGxlY3Rpb25cIik7XG5tb2R1bGUuZXhwb3J0cy5FdmVudHMgPSByZXF1aXJlKFwiYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmVcIik7XG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgPSByZXF1aXJlKFwiYmFja2JvbmUtZXh0ZW5kLXN0YW5kYWxvbmVcIik7XG4iLCIvLyAgICAgQmFja2JvbmUuanMgMS4xLjJcblxuLy8gICAgIChjKSAyMDEwLTIwMTQgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbi8vICAgICBCYWNrYm9uZSBtYXkgYmUgZnJlZWx5IGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbi8vICAgICBGb3IgYWxsIGRldGFpbHMgYW5kIGRvY3VtZW50YXRpb246XG4vLyAgICAgaHR0cDovL2JhY2tib25lanMub3JnXG5cbnZhciBFdmVudHMgPSByZXF1aXJlKFwiYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmVcIik7XG52YXIgZXh0ZW5kID0gcmVxdWlyZShcImJhY2tib25lLWV4dGVuZC1zdGFuZGFsb25lXCIpO1xudmFyIF8gPSByZXF1aXJlKFwidW5kZXJzY29yZVwiKTtcblxuLy8gQmFja2JvbmUuTW9kZWxcbi8vIC0tLS0tLS0tLS0tLS0tXG5cbi8vIEJhY2tib25lICoqTW9kZWxzKiogYXJlIHRoZSBiYXNpYyBkYXRhIG9iamVjdCBpbiB0aGUgZnJhbWV3b3JrIC0tXG4vLyBmcmVxdWVudGx5IHJlcHJlc2VudGluZyBhIHJvdyBpbiBhIHRhYmxlIGluIGEgZGF0YWJhc2Ugb24geW91ciBzZXJ2ZXIuXG4vLyBBIGRpc2NyZXRlIGNodW5rIG9mIGRhdGEgYW5kIGEgYnVuY2ggb2YgdXNlZnVsLCByZWxhdGVkIG1ldGhvZHMgZm9yXG4vLyBwZXJmb3JtaW5nIGNvbXB1dGF0aW9ucyBhbmQgdHJhbnNmb3JtYXRpb25zIG9uIHRoYXQgZGF0YS5cblxuLy8gQ3JlYXRlIGEgbmV3IG1vZGVsIHdpdGggdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGVzLiBBIGNsaWVudCBpZCAoYGNpZGApXG4vLyBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBhbmQgYXNzaWduZWQgZm9yIHlvdS5cbnZhciBNb2RlbCA9IGZ1bmN0aW9uKGF0dHJpYnV0ZXMsIG9wdGlvbnMpIHtcbiAgdmFyIGF0dHJzID0gYXR0cmlidXRlcyB8fCB7fTtcbiAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcbiAgdGhpcy5jaWQgPSBfLnVuaXF1ZUlkKCdjJyk7XG4gIHRoaXMuYXR0cmlidXRlcyA9IHt9O1xuICBpZiAob3B0aW9ucy5jb2xsZWN0aW9uKSB0aGlzLmNvbGxlY3Rpb24gPSBvcHRpb25zLmNvbGxlY3Rpb247XG4gIGlmIChvcHRpb25zLnBhcnNlKSBhdHRycyA9IHRoaXMucGFyc2UoYXR0cnMsIG9wdGlvbnMpIHx8IHt9O1xuICBhdHRycyA9IF8uZGVmYXVsdHMoe30sIGF0dHJzLCBfLnJlc3VsdCh0aGlzLCAnZGVmYXVsdHMnKSk7XG4gIHRoaXMuc2V0KGF0dHJzLCBvcHRpb25zKTtcbiAgdGhpcy5jaGFuZ2VkID0ge307XG4gIHRoaXMuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufTtcblxuLy8gQXR0YWNoIGFsbCBpbmhlcml0YWJsZSBtZXRob2RzIHRvIHRoZSBNb2RlbCBwcm90b3R5cGUuXG5fLmV4dGVuZChNb2RlbC5wcm90b3R5cGUsIEV2ZW50cywge1xuXG4gIC8vIEEgaGFzaCBvZiBhdHRyaWJ1dGVzIHdob3NlIGN1cnJlbnQgYW5kIHByZXZpb3VzIHZhbHVlIGRpZmZlci5cbiAgY2hhbmdlZDogbnVsbCxcblxuICAvLyBUaGUgdmFsdWUgcmV0dXJuZWQgZHVyaW5nIHRoZSBsYXN0IGZhaWxlZCB2YWxpZGF0aW9uLlxuICB2YWxpZGF0aW9uRXJyb3I6IG51bGwsXG5cbiAgICAvLyBUaGUgZGVmYXVsdCBuYW1lIGZvciB0aGUgSlNPTiBgaWRgIGF0dHJpYnV0ZSBpcyBgXCJpZFwiYC4gTW9uZ29EQiBhbmRcbiAgICAvLyBDb3VjaERCIHVzZXJzIG1heSB3YW50IHRvIHNldCB0aGlzIHRvIGBcIl9pZFwiYC5cbiAgaWRBdHRyaWJ1dGU6ICdpZCcsXG5cbiAgICAvLyBJbml0aWFsaXplIGlzIGFuIGVtcHR5IGZ1bmN0aW9uIGJ5IGRlZmF1bHQuIE92ZXJyaWRlIGl0IHdpdGggeW91ciBvd25cbiAgICAvLyBpbml0aWFsaXphdGlvbiBsb2dpYy5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXt9LFxuXG4gICAgLy8gUmV0dXJuIGEgY29weSBvZiB0aGUgbW9kZWwncyBgYXR0cmlidXRlc2Agb2JqZWN0LlxuICB0b0pTT046IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gXy5jbG9uZSh0aGlzLmF0dHJpYnV0ZXMpO1xuICB9LFxuXG4gICAgLy8gUHJveHkgYEJhY2tib25lLnN5bmNgIGJ5IGRlZmF1bHQgLS0gYnV0IG92ZXJyaWRlIHRoaXMgaWYgeW91IG5lZWRcbiAgICAvLyBjdXN0b20gc3luY2luZyBzZW1hbnRpY3MgZm9yICp0aGlzKiBwYXJ0aWN1bGFyIG1vZGVsLlxuICBzeW5jOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gQmFja2JvbmUuc3luYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9LFxuXG4gICAgLy8gR2V0IHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUuXG4gIGdldDogZnVuY3Rpb24oYXR0cikge1xuICAgIHJldHVybiB0aGlzLmF0dHJpYnV0ZXNbYXR0cl07XG4gIH0sXG5cbiAgICAvLyBHZXQgdGhlIEhUTUwtZXNjYXBlZCB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUuXG4gIGVzY2FwZTogZnVuY3Rpb24oYXR0cikge1xuICAgIHJldHVybiBfLmVzY2FwZSh0aGlzLmdldChhdHRyKSk7XG4gIH0sXG5cbiAgICAvLyBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXR0cmlidXRlIGNvbnRhaW5zIGEgdmFsdWUgdGhhdCBpcyBub3QgbnVsbFxuICAgIC8vIG9yIHVuZGVmaW5lZC5cbiAgaGFzOiBmdW5jdGlvbihhdHRyKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGF0dHIpICE9IG51bGw7XG4gIH0sXG5cbiAgICAvLyBTZXQgYSBoYXNoIG9mIG1vZGVsIGF0dHJpYnV0ZXMgb24gdGhlIG9iamVjdCwgZmlyaW5nIGBcImNoYW5nZVwiYC4gVGhpcyBpc1xuICAgIC8vIHRoZSBjb3JlIHByaW1pdGl2ZSBvcGVyYXRpb24gb2YgYSBtb2RlbCwgdXBkYXRpbmcgdGhlIGRhdGEgYW5kIG5vdGlmeWluZ1xuICAgIC8vIGFueW9uZSB3aG8gbmVlZHMgdG8ga25vdyBhYm91dCB0aGUgY2hhbmdlIGluIHN0YXRlLiBUaGUgaGVhcnQgb2YgdGhlIGJlYXN0LlxuICBzZXQ6IGZ1bmN0aW9uKGtleSwgdmFsLCBvcHRpb25zKSB7XG4gICAgdmFyIGF0dHIsIGF0dHJzLCB1bnNldCwgY2hhbmdlcywgc2lsZW50LCBjaGFuZ2luZywgcHJldiwgY3VycmVudDtcbiAgICBpZiAoa2V5ID09IG51bGwpIHJldHVybiB0aGlzO1xuXG4gICAgLy8gSGFuZGxlIGJvdGggYFwia2V5XCIsIHZhbHVlYCBhbmQgYHtrZXk6IHZhbHVlfWAgLXN0eWxlIGFyZ3VtZW50cy5cbiAgICBpZiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGF0dHJzID0ga2V5O1xuICAgICAgb3B0aW9ucyA9IHZhbDtcbiAgICB9IGVsc2Uge1xuICAgICAgKGF0dHJzID0ge30pW2tleV0gPSB2YWw7XG4gICAgfVxuXG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcblxuICAgIC8vIFJ1biB2YWxpZGF0aW9uLlxuICAgIGlmICghdGhpcy5fdmFsaWRhdGUoYXR0cnMsIG9wdGlvbnMpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBFeHRyYWN0IGF0dHJpYnV0ZXMgYW5kIG9wdGlvbnMuXG4gICAgdW5zZXQgICAgICAgICAgID0gb3B0aW9ucy51bnNldDtcbiAgICBzaWxlbnQgICAgICAgICAgPSBvcHRpb25zLnNpbGVudDtcbiAgICBjaGFuZ2VzICAgICAgICAgPSBbXTtcbiAgICBjaGFuZ2luZyAgICAgICAgPSB0aGlzLl9jaGFuZ2luZztcbiAgICB0aGlzLl9jaGFuZ2luZyAgPSB0cnVlO1xuXG4gICAgaWYgKCFjaGFuZ2luZykge1xuICAgICAgdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzID0gXy5jbG9uZSh0aGlzLmF0dHJpYnV0ZXMpO1xuICAgICAgdGhpcy5jaGFuZ2VkID0ge307XG4gICAgfVxuICAgIGN1cnJlbnQgPSB0aGlzLmF0dHJpYnV0ZXMsIHByZXYgPSB0aGlzLl9wcmV2aW91c0F0dHJpYnV0ZXM7XG5cbiAgICAvLyBDaGVjayBmb3IgY2hhbmdlcyBvZiBgaWRgLlxuICAgIGlmICh0aGlzLmlkQXR0cmlidXRlIGluIGF0dHJzKSB0aGlzLmlkID0gYXR0cnNbdGhpcy5pZEF0dHJpYnV0ZV07XG5cbiAgICAvLyBGb3IgZWFjaCBgc2V0YCBhdHRyaWJ1dGUsIHVwZGF0ZSBvciBkZWxldGUgdGhlIGN1cnJlbnQgdmFsdWUuXG4gICAgZm9yIChhdHRyIGluIGF0dHJzKSB7XG4gICAgICB2YWwgPSBhdHRyc1thdHRyXTtcbiAgICAgIGlmICghXy5pc0VxdWFsKGN1cnJlbnRbYXR0cl0sIHZhbCkpIGNoYW5nZXMucHVzaChhdHRyKTtcbiAgICAgIGlmICghXy5pc0VxdWFsKHByZXZbYXR0cl0sIHZhbCkpIHtcbiAgICAgICAgdGhpcy5jaGFuZ2VkW2F0dHJdID0gdmFsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuY2hhbmdlZFthdHRyXTtcbiAgICAgIH1cbiAgICAgIHVuc2V0ID8gZGVsZXRlIGN1cnJlbnRbYXR0cl0gOiBjdXJyZW50W2F0dHJdID0gdmFsO1xuICAgIH1cblxuICAgIC8vIFRyaWdnZXIgYWxsIHJlbGV2YW50IGF0dHJpYnV0ZSBjaGFuZ2VzLlxuICAgIGlmICghc2lsZW50KSB7XG4gICAgICBpZiAoY2hhbmdlcy5sZW5ndGgpIHRoaXMuX3BlbmRpbmcgPSBvcHRpb25zO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGNoYW5nZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy50cmlnZ2VyKCdjaGFuZ2U6JyArIGNoYW5nZXNbaV0sIHRoaXMsIGN1cnJlbnRbY2hhbmdlc1tpXV0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFlvdSBtaWdodCBiZSB3b25kZXJpbmcgd2h5IHRoZXJlJ3MgYSBgd2hpbGVgIGxvb3AgaGVyZS4gQ2hhbmdlcyBjYW5cbiAgICAvLyBiZSByZWN1cnNpdmVseSBuZXN0ZWQgd2l0aGluIGBcImNoYW5nZVwiYCBldmVudHMuXG4gICAgaWYgKGNoYW5naW5nKSByZXR1cm4gdGhpcztcbiAgICBpZiAoIXNpbGVudCkge1xuICAgICAgd2hpbGUgKHRoaXMuX3BlbmRpbmcpIHtcbiAgICAgICAgb3B0aW9ucyA9IHRoaXMuX3BlbmRpbmc7XG4gICAgICAgIHRoaXMuX3BlbmRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50cmlnZ2VyKCdjaGFuZ2UnLCB0aGlzLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5fcGVuZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuX2NoYW5naW5nID0gZmFsc2U7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgICAvLyBSZW1vdmUgYW4gYXR0cmlidXRlIGZyb20gdGhlIG1vZGVsLCBmaXJpbmcgYFwiY2hhbmdlXCJgLiBgdW5zZXRgIGlzIGEgbm9vcFxuICAgIC8vIGlmIHRoZSBhdHRyaWJ1dGUgZG9lc24ndCBleGlzdC5cbiAgdW5zZXQ6IGZ1bmN0aW9uKGF0dHIsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5zZXQoYXR0ciwgdm9pZCAwLCBfLmV4dGVuZCh7fSwgb3B0aW9ucywge3Vuc2V0OiB0cnVlfSkpO1xuICB9LFxuXG4gICAgLy8gQ2xlYXIgYWxsIGF0dHJpYnV0ZXMgb24gdGhlIG1vZGVsLCBmaXJpbmcgYFwiY2hhbmdlXCJgLlxuICBjbGVhcjogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgIHZhciBhdHRycyA9IHt9O1xuICAgIGZvciAodmFyIGtleSBpbiB0aGlzLmF0dHJpYnV0ZXMpIGF0dHJzW2tleV0gPSB2b2lkIDA7XG4gICAgcmV0dXJuIHRoaXMuc2V0KGF0dHJzLCBfLmV4dGVuZCh7fSwgb3B0aW9ucywge3Vuc2V0OiB0cnVlfSkpO1xuICB9LFxuXG4gICAgLy8gRGV0ZXJtaW5lIGlmIHRoZSBtb2RlbCBoYXMgY2hhbmdlZCBzaW5jZSB0aGUgbGFzdCBgXCJjaGFuZ2VcImAgZXZlbnQuXG4gICAgLy8gSWYgeW91IHNwZWNpZnkgYW4gYXR0cmlidXRlIG5hbWUsIGRldGVybWluZSBpZiB0aGF0IGF0dHJpYnV0ZSBoYXMgY2hhbmdlZC5cbiAgaGFzQ2hhbmdlZDogZnVuY3Rpb24oYXR0cikge1xuICAgIGlmIChhdHRyID09IG51bGwpIHJldHVybiAhXy5pc0VtcHR5KHRoaXMuY2hhbmdlZCk7XG4gICAgcmV0dXJuIF8uaGFzKHRoaXMuY2hhbmdlZCwgYXR0cik7XG4gIH0sXG5cbiAgICAvLyBSZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIHRoZSBhdHRyaWJ1dGVzIHRoYXQgaGF2ZSBjaGFuZ2VkLCBvclxuICAgIC8vIGZhbHNlIGlmIHRoZXJlIGFyZSBubyBjaGFuZ2VkIGF0dHJpYnV0ZXMuIFVzZWZ1bCBmb3IgZGV0ZXJtaW5pbmcgd2hhdFxuICAgIC8vIHBhcnRzIG9mIGEgdmlldyBuZWVkIHRvIGJlIHVwZGF0ZWQgYW5kL29yIHdoYXQgYXR0cmlidXRlcyBuZWVkIHRvIGJlXG4gICAgLy8gcGVyc2lzdGVkIHRvIHRoZSBzZXJ2ZXIuIFVuc2V0IGF0dHJpYnV0ZXMgd2lsbCBiZSBzZXQgdG8gdW5kZWZpbmVkLlxuICAgIC8vIFlvdSBjYW4gYWxzbyBwYXNzIGFuIGF0dHJpYnV0ZXMgb2JqZWN0IHRvIGRpZmYgYWdhaW5zdCB0aGUgbW9kZWwsXG4gICAgLy8gZGV0ZXJtaW5pbmcgaWYgdGhlcmUgKndvdWxkIGJlKiBhIGNoYW5nZS5cbiAgY2hhbmdlZEF0dHJpYnV0ZXM6IGZ1bmN0aW9uKGRpZmYpIHtcbiAgICBpZiAoIWRpZmYpIHJldHVybiB0aGlzLmhhc0NoYW5nZWQoKSA/IF8uY2xvbmUodGhpcy5jaGFuZ2VkKSA6IGZhbHNlO1xuICAgIHZhciB2YWwsIGNoYW5nZWQgPSBmYWxzZTtcbiAgICB2YXIgb2xkID0gdGhpcy5fY2hhbmdpbmcgPyB0aGlzLl9wcmV2aW91c0F0dHJpYnV0ZXMgOiB0aGlzLmF0dHJpYnV0ZXM7XG4gICAgZm9yICh2YXIgYXR0ciBpbiBkaWZmKSB7XG4gICAgICBpZiAoXy5pc0VxdWFsKG9sZFthdHRyXSwgKHZhbCA9IGRpZmZbYXR0cl0pKSkgY29udGludWU7XG4gICAgICAoY2hhbmdlZCB8fCAoY2hhbmdlZCA9IHt9KSlbYXR0cl0gPSB2YWw7XG4gICAgfVxuICAgIHJldHVybiBjaGFuZ2VkO1xuICB9LFxuXG4gICAgLy8gR2V0IHRoZSBwcmV2aW91cyB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUsIHJlY29yZGVkIGF0IHRoZSB0aW1lIHRoZSBsYXN0XG4gICAgLy8gYFwiY2hhbmdlXCJgIGV2ZW50IHdhcyBmaXJlZC5cbiAgcHJldmlvdXM6IGZ1bmN0aW9uKGF0dHIpIHtcbiAgICBpZiAoYXR0ciA9PSBudWxsIHx8ICF0aGlzLl9wcmV2aW91c0F0dHJpYnV0ZXMpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB0aGlzLl9wcmV2aW91c0F0dHJpYnV0ZXNbYXR0cl07XG4gIH0sXG5cbiAgICAvLyBHZXQgYWxsIG9mIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBtb2RlbCBhdCB0aGUgdGltZSBvZiB0aGUgcHJldmlvdXNcbiAgICAvLyBgXCJjaGFuZ2VcImAgZXZlbnQuXG4gIHByZXZpb3VzQXR0cmlidXRlczogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIF8uY2xvbmUodGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzKTtcbiAgfSxcblxuICAgIC8vIEZldGNoIHRoZSBtb2RlbCBmcm9tIHRoZSBzZXJ2ZXIuIElmIHRoZSBzZXJ2ZXIncyByZXByZXNlbnRhdGlvbiBvZiB0aGVcbiAgICAvLyBtb2RlbCBkaWZmZXJzIGZyb20gaXRzIGN1cnJlbnQgYXR0cmlidXRlcywgdGhleSB3aWxsIGJlIG92ZXJyaWRkZW4sXG4gICAgLy8gdHJpZ2dlcmluZyBhIGBcImNoYW5nZVwiYCBldmVudC5cbiAgZmV0Y2g6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyA/IF8uY2xvbmUob3B0aW9ucykgOiB7fTtcbiAgICBpZiAob3B0aW9ucy5wYXJzZSA9PT0gdm9pZCAwKSBvcHRpb25zLnBhcnNlID0gdHJ1ZTtcbiAgICB2YXIgbW9kZWwgPSB0aGlzO1xuICAgIHZhciBzdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzO1xuICAgIG9wdGlvbnMuc3VjY2VzcyA9IGZ1bmN0aW9uKHJlc3ApIHtcbiAgICAgIGlmICghbW9kZWwuc2V0KG1vZGVsLnBhcnNlKHJlc3AsIG9wdGlvbnMpLCBvcHRpb25zKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MobW9kZWwsIHJlc3AsIG9wdGlvbnMpO1xuICAgICAgbW9kZWwudHJpZ2dlcignc3luYycsIG1vZGVsLCByZXNwLCBvcHRpb25zKTtcbiAgICB9O1xuICAgIHdyYXBFcnJvcih0aGlzLCBvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5zeW5jKCdyZWFkJywgdGhpcywgb3B0aW9ucyk7XG4gIH0sXG5cbiAgICAvLyBTZXQgYSBoYXNoIG9mIG1vZGVsIGF0dHJpYnV0ZXMsIGFuZCBzeW5jIHRoZSBtb2RlbCB0byB0aGUgc2VydmVyLlxuICAgIC8vIElmIHRoZSBzZXJ2ZXIgcmV0dXJucyBhbiBhdHRyaWJ1dGVzIGhhc2ggdGhhdCBkaWZmZXJzLCB0aGUgbW9kZWwnc1xuICAgIC8vIHN0YXRlIHdpbGwgYmUgYHNldGAgYWdhaW4uXG4gIHNhdmU6IGZ1bmN0aW9uKGtleSwgdmFsLCBvcHRpb25zKSB7XG4gICAgdmFyIGF0dHJzLCBtZXRob2QsIHhociwgYXR0cmlidXRlcyA9IHRoaXMuYXR0cmlidXRlcztcblxuICAgIC8vIEhhbmRsZSBib3RoIGBcImtleVwiLCB2YWx1ZWAgYW5kIGB7a2V5OiB2YWx1ZX1gIC1zdHlsZSBhcmd1bWVudHMuXG4gICAgaWYgKGtleSA9PSBudWxsIHx8IHR5cGVvZiBrZXkgPT09ICdvYmplY3QnKSB7XG4gICAgICBhdHRycyA9IGtleTtcbiAgICAgIG9wdGlvbnMgPSB2YWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIChhdHRycyA9IHt9KVtrZXldID0gdmFsO1xuICAgIH1cblxuICAgIG9wdGlvbnMgPSBfLmV4dGVuZCh7dmFsaWRhdGU6IHRydWV9LCBvcHRpb25zKTtcblxuICAgIC8vIElmIHdlJ3JlIG5vdCB3YWl0aW5nIGFuZCBhdHRyaWJ1dGVzIGV4aXN0LCBzYXZlIGFjdHMgYXNcbiAgICAvLyBgc2V0KGF0dHIpLnNhdmUobnVsbCwgb3B0cylgIHdpdGggdmFsaWRhdGlvbi4gT3RoZXJ3aXNlLCBjaGVjayBpZlxuICAgIC8vIHRoZSBtb2RlbCB3aWxsIGJlIHZhbGlkIHdoZW4gdGhlIGF0dHJpYnV0ZXMsIGlmIGFueSwgYXJlIHNldC5cbiAgICBpZiAoYXR0cnMgJiYgIW9wdGlvbnMud2FpdCkge1xuICAgICAgaWYgKCF0aGlzLnNldChhdHRycywgb3B0aW9ucykpIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF0aGlzLl92YWxpZGF0ZShhdHRycywgb3B0aW9ucykpIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBTZXQgdGVtcG9yYXJ5IGF0dHJpYnV0ZXMgaWYgYHt3YWl0OiB0cnVlfWAuXG4gICAgaWYgKGF0dHJzICYmIG9wdGlvbnMud2FpdCkge1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzID0gXy5leHRlbmQoe30sIGF0dHJpYnV0ZXMsIGF0dHJzKTtcbiAgICB9XG5cbiAgICAvLyBBZnRlciBhIHN1Y2Nlc3NmdWwgc2VydmVyLXNpZGUgc2F2ZSwgdGhlIGNsaWVudCBpcyAob3B0aW9uYWxseSlcbiAgICAvLyB1cGRhdGVkIHdpdGggdGhlIHNlcnZlci1zaWRlIHN0YXRlLlxuICAgIGlmIChvcHRpb25zLnBhcnNlID09PSB2b2lkIDApIG9wdGlvbnMucGFyc2UgPSB0cnVlO1xuICAgIHZhciBtb2RlbCA9IHRoaXM7XG4gICAgdmFyIHN1Y2Nlc3MgPSBvcHRpb25zLnN1Y2Nlc3M7XG4gICAgb3B0aW9ucy5zdWNjZXNzID0gZnVuY3Rpb24ocmVzcCkge1xuICAgICAgLy8gRW5zdXJlIGF0dHJpYnV0ZXMgYXJlIHJlc3RvcmVkIGR1cmluZyBzeW5jaHJvbm91cyBzYXZlcy5cbiAgICAgIG1vZGVsLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzO1xuICAgICAgdmFyIHNlcnZlckF0dHJzID0gbW9kZWwucGFyc2UocmVzcCwgb3B0aW9ucyk7XG4gICAgICBpZiAob3B0aW9ucy53YWl0KSBzZXJ2ZXJBdHRycyA9IF8uZXh0ZW5kKGF0dHJzIHx8IHt9LCBzZXJ2ZXJBdHRycyk7XG4gICAgICBpZiAoXy5pc09iamVjdChzZXJ2ZXJBdHRycykgJiYgIW1vZGVsLnNldChzZXJ2ZXJBdHRycywgb3B0aW9ucykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MobW9kZWwsIHJlc3AsIG9wdGlvbnMpO1xuICAgICAgbW9kZWwudHJpZ2dlcignc3luYycsIG1vZGVsLCByZXNwLCBvcHRpb25zKTtcbiAgICB9O1xuICAgIHdyYXBFcnJvcih0aGlzLCBvcHRpb25zKTtcblxuICAgIG1ldGhvZCA9IHRoaXMuaXNOZXcoKSA/ICdjcmVhdGUnIDogKG9wdGlvbnMucGF0Y2ggPyAncGF0Y2gnIDogJ3VwZGF0ZScpO1xuICAgIGlmIChtZXRob2QgPT09ICdwYXRjaCcgJiYgIW9wdGlvbnMuYXR0cnMpIG9wdGlvbnMuYXR0cnMgPSBhdHRycztcbiAgICB4aHIgPSB0aGlzLnN5bmMobWV0aG9kLCB0aGlzLCBvcHRpb25zKTtcblxuICAgIC8vIFJlc3RvcmUgYXR0cmlidXRlcy5cbiAgICBpZiAoYXR0cnMgJiYgb3B0aW9ucy53YWl0KSB0aGlzLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzO1xuXG4gICAgcmV0dXJuIHhocjtcbiAgfSxcblxuICAgIC8vIERlc3Ryb3kgdGhpcyBtb2RlbCBvbiB0aGUgc2VydmVyIGlmIGl0IHdhcyBhbHJlYWR5IHBlcnNpc3RlZC5cbiAgICAvLyBPcHRpbWlzdGljYWxseSByZW1vdmVzIHRoZSBtb2RlbCBmcm9tIGl0cyBjb2xsZWN0aW9uLCBpZiBpdCBoYXMgb25lLlxuICAgIC8vIElmIGB3YWl0OiB0cnVlYCBpcyBwYXNzZWQsIHdhaXRzIGZvciB0aGUgc2VydmVyIHRvIHJlc3BvbmQgYmVmb3JlIHJlbW92YWwuXG4gIGRlc3Ryb3k6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyA/IF8uY2xvbmUob3B0aW9ucykgOiB7fTtcbiAgICB2YXIgbW9kZWwgPSB0aGlzO1xuICAgIHZhciBzdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzO1xuXG4gICAgdmFyIGRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgICAgIG1vZGVsLnN0b3BMaXN0ZW5pbmcoKTtcbiAgICAgIG1vZGVsLnRyaWdnZXIoJ2Rlc3Ryb3knLCBtb2RlbCwgbW9kZWwuY29sbGVjdGlvbiwgb3B0aW9ucyk7XG4gICAgfTtcblxuICAgIG9wdGlvbnMuc3VjY2VzcyA9IGZ1bmN0aW9uKHJlc3ApIHtcbiAgICAgIGlmIChvcHRpb25zLndhaXQgfHwgbW9kZWwuaXNOZXcoKSkgZGVzdHJveSgpO1xuICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MobW9kZWwsIHJlc3AsIG9wdGlvbnMpO1xuICAgICAgaWYgKCFtb2RlbC5pc05ldygpKSBtb2RlbC50cmlnZ2VyKCdzeW5jJywgbW9kZWwsIHJlc3AsIG9wdGlvbnMpO1xuICAgIH07XG5cbiAgICBpZiAodGhpcy5pc05ldygpKSB7XG4gICAgICBvcHRpb25zLnN1Y2Nlc3MoKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgd3JhcEVycm9yKHRoaXMsIG9wdGlvbnMpO1xuXG4gICAgdmFyIHhociA9IHRoaXMuc3luYygnZGVsZXRlJywgdGhpcywgb3B0aW9ucyk7XG4gICAgaWYgKCFvcHRpb25zLndhaXQpIGRlc3Ryb3koKTtcbiAgICByZXR1cm4geGhyO1xuICB9LFxuXG4gICAgLy8gRGVmYXVsdCBVUkwgZm9yIHRoZSBtb2RlbCdzIHJlcHJlc2VudGF0aW9uIG9uIHRoZSBzZXJ2ZXIgLS0gaWYgeW91J3JlXG4gICAgLy8gdXNpbmcgQmFja2JvbmUncyByZXN0ZnVsIG1ldGhvZHMsIG92ZXJyaWRlIHRoaXMgdG8gY2hhbmdlIHRoZSBlbmRwb2ludFxuICAgIC8vIHRoYXQgd2lsbCBiZSBjYWxsZWQuXG4gIHVybDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJhc2UgPVxuICAgICAgXy5yZXN1bHQodGhpcywgJ3VybFJvb3QnKSB8fFxuICAgICAgXy5yZXN1bHQodGhpcy5jb2xsZWN0aW9uLCAndXJsJykgfHxcbiAgICAgIHVybEVycm9yKCk7XG4gICAgaWYgKHRoaXMuaXNOZXcoKSkgcmV0dXJuIGJhc2U7XG4gICAgcmV0dXJuIGJhc2UucmVwbGFjZSgvKFteXFwvXSkkLywgJyQxLycpICsgZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMuaWQpO1xuICB9LFxuXG4gICAgLy8gKipwYXJzZSoqIGNvbnZlcnRzIGEgcmVzcG9uc2UgaW50byB0aGUgaGFzaCBvZiBhdHRyaWJ1dGVzIHRvIGJlIGBzZXRgIG9uXG4gICAgLy8gdGhlIG1vZGVsLiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBqdXN0IHRvIHBhc3MgdGhlIHJlc3BvbnNlIGFsb25nLlxuICBwYXJzZTogZnVuY3Rpb24ocmVzcCwgb3B0aW9ucykge1xuICAgIHJldHVybiByZXNwO1xuICB9LFxuXG4gICAgLy8gQ3JlYXRlIGEgbmV3IG1vZGVsIHdpdGggaWRlbnRpY2FsIGF0dHJpYnV0ZXMgdG8gdGhpcyBvbmUuXG4gIGNsb25lOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5hdHRyaWJ1dGVzKTtcbiAgfSxcblxuICAgIC8vIEEgbW9kZWwgaXMgbmV3IGlmIGl0IGhhcyBuZXZlciBiZWVuIHNhdmVkIHRvIHRoZSBzZXJ2ZXIsIGFuZCBsYWNrcyBhbiBpZC5cbiAgaXNOZXc6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAhdGhpcy5oYXModGhpcy5pZEF0dHJpYnV0ZSk7XG4gIH0sXG5cbiAgICAvLyBDaGVjayBpZiB0aGUgbW9kZWwgaXMgY3VycmVudGx5IGluIGEgdmFsaWQgc3RhdGUuXG4gIGlzVmFsaWQ6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGUoe30sIF8uZXh0ZW5kKG9wdGlvbnMgfHwge30sIHsgdmFsaWRhdGU6IHRydWUgfSkpO1xuICB9LFxuXG4gICAgLy8gUnVuIHZhbGlkYXRpb24gYWdhaW5zdCB0aGUgbmV4dCBjb21wbGV0ZSBzZXQgb2YgbW9kZWwgYXR0cmlidXRlcyxcbiAgICAvLyByZXR1cm5pbmcgYHRydWVgIGlmIGFsbCBpcyB3ZWxsLiBPdGhlcndpc2UsIGZpcmUgYW4gYFwiaW52YWxpZFwiYCBldmVudC5cbiAgX3ZhbGlkYXRlOiBmdW5jdGlvbihhdHRycywgb3B0aW9ucykge1xuICAgIGlmICghb3B0aW9ucy52YWxpZGF0ZSB8fCAhdGhpcy52YWxpZGF0ZSkgcmV0dXJuIHRydWU7XG4gICAgYXR0cnMgPSBfLmV4dGVuZCh7fSwgdGhpcy5hdHRyaWJ1dGVzLCBhdHRycyk7XG4gICAgdmFyIGVycm9yID0gdGhpcy52YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlKGF0dHJzLCBvcHRpb25zKSB8fCBudWxsO1xuICAgIGlmICghZXJyb3IpIHJldHVybiB0cnVlO1xuICAgIHRoaXMudHJpZ2dlcignaW52YWxpZCcsIHRoaXMsIGVycm9yLCBfLmV4dGVuZChvcHRpb25zLCB7dmFsaWRhdGlvbkVycm9yOiBlcnJvcn0pKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxufSk7XG5cbi8vIFVuZGVyc2NvcmUgbWV0aG9kcyB0aGF0IHdlIHdhbnQgdG8gaW1wbGVtZW50IG9uIHRoZSBNb2RlbC5cbnZhciBtb2RlbE1ldGhvZHMgPSBbJ2tleXMnLCAndmFsdWVzJywgJ3BhaXJzJywgJ2ludmVydCcsICdwaWNrJywgJ29taXQnLCAnY2hhaW4nLCAnaXNFbXB0eSddO1xuXG4vLyBNaXggaW4gZWFjaCBVbmRlcnNjb3JlIG1ldGhvZCBhcyBhIHByb3h5IHRvIGBNb2RlbCNhdHRyaWJ1dGVzYC5cbl8uZWFjaChtb2RlbE1ldGhvZHMsIGZ1bmN0aW9uKG1ldGhvZCkge1xuICBpZiAoIV9bbWV0aG9kXSkgcmV0dXJuO1xuICBNb2RlbC5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzLmF0dHJpYnV0ZXMpO1xuICAgIHJldHVybiBfW21ldGhvZF0uYXBwbHkoXywgYXJncyk7XG4gIH07XG59KTtcblxuLy8gc2V0dXAgaW5oZXJpdGFuY2Vcbk1vZGVsLmV4dGVuZCA9IGV4dGVuZDtcbm1vZHVsZS5leHBvcnRzID0gTW9kZWw7XG4iLCIvKipcbiAqIFN0YW5kYWxvbmUgZXh0cmFjdGlvbiBvZiBCYWNrYm9uZS5FdmVudHMsIG5vIGV4dGVybmFsIGRlcGVuZGVuY3kgcmVxdWlyZWQuXG4gKiBEZWdyYWRlcyBuaWNlbHkgd2hlbiBCYWNrb25lL3VuZGVyc2NvcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50XG4gKiBnbG9iYWwgY29udGV4dC5cbiAqXG4gKiBOb3RlIHRoYXQgZG9jcyBzdWdnZXN0IHRvIHVzZSB1bmRlcnNjb3JlJ3MgYF8uZXh0ZW5kKClgIG1ldGhvZCB0byBhZGQgRXZlbnRzXG4gKiBzdXBwb3J0IHRvIHNvbWUgZ2l2ZW4gb2JqZWN0LiBBIGBtaXhpbigpYCBtZXRob2QgaGFzIGJlZW4gYWRkZWQgdG8gdGhlIEV2ZW50c1xuICogcHJvdG90eXBlIHRvIGF2b2lkIHVzaW5nIHVuZGVyc2NvcmUgZm9yIHRoYXQgc29sZSBwdXJwb3NlOlxuICpcbiAqICAgICB2YXIgbXlFdmVudEVtaXR0ZXIgPSBCYWNrYm9uZUV2ZW50cy5taXhpbih7fSk7XG4gKlxuICogT3IgZm9yIGEgZnVuY3Rpb24gY29uc3RydWN0b3I6XG4gKlxuICogICAgIGZ1bmN0aW9uIE15Q29uc3RydWN0b3IoKXt9XG4gKiAgICAgTXlDb25zdHJ1Y3Rvci5wcm90b3R5cGUuZm9vID0gZnVuY3Rpb24oKXt9XG4gKiAgICAgQmFja2JvbmVFdmVudHMubWl4aW4oTXlDb25zdHJ1Y3Rvci5wcm90b3R5cGUpO1xuICpcbiAqIChjKSAyMDA5LTIwMTMgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIEluYy5cbiAqIChjKSAyMDEzIE5pY29sYXMgUGVycmlhdWx0XG4gKi9cbi8qIGdsb2JhbCBleHBvcnRzOnRydWUsIGRlZmluZSwgbW9kdWxlICovXG4oZnVuY3Rpb24oKSB7XG4gIHZhciByb290ID0gdGhpcyxcbiAgICAgIGJyZWFrZXIgPSB7fSxcbiAgICAgIG5hdGl2ZUZvckVhY2ggPSBBcnJheS5wcm90b3R5cGUuZm9yRWFjaCxcbiAgICAgIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxcbiAgICAgIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLFxuICAgICAgaWRDb3VudGVyID0gMDtcblxuICAvLyBSZXR1cm5zIGEgcGFydGlhbCBpbXBsZW1lbnRhdGlvbiBtYXRjaGluZyB0aGUgbWluaW1hbCBBUEkgc3Vic2V0IHJlcXVpcmVkXG4gIC8vIGJ5IEJhY2tib25lLkV2ZW50c1xuICBmdW5jdGlvbiBtaW5pc2NvcmUoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleXM6IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmogIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iaiAhPT0gXCJmdW5jdGlvblwiIHx8IG9iaiA9PT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXlzKCkgY2FsbGVkIG9uIGEgbm9uLW9iamVjdFwiKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIga2V5LCBrZXlzID0gW107XG4gICAgICAgIGZvciAoa2V5IGluIG9iaikge1xuICAgICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAga2V5c1trZXlzLmxlbmd0aF0gPSBrZXk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrZXlzO1xuICAgICAgfSxcblxuICAgICAgdW5pcXVlSWQ6IGZ1bmN0aW9uKHByZWZpeCkge1xuICAgICAgICB2YXIgaWQgPSArK2lkQ291bnRlciArICcnO1xuICAgICAgICByZXR1cm4gcHJlZml4ID8gcHJlZml4ICsgaWQgOiBpZDtcbiAgICAgIH0sXG5cbiAgICAgIGhhczogZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpO1xuICAgICAgfSxcblxuICAgICAgZWFjaDogZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgICAgICBpZiAob2JqID09IG51bGwpIHJldHVybjtcbiAgICAgICAgaWYgKG5hdGl2ZUZvckVhY2ggJiYgb2JqLmZvckVhY2ggPT09IG5hdGl2ZUZvckVhY2gpIHtcbiAgICAgICAgICBvYmouZm9yRWFjaChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgICAgIH0gZWxzZSBpZiAob2JqLmxlbmd0aCA9PT0gK29iai5sZW5ndGgpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtpXSwgaSwgb2JqKSA9PT0gYnJlYWtlcikgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5oYXMob2JqLCBrZXkpKSB7XG4gICAgICAgICAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXldLCBrZXksIG9iaikgPT09IGJyZWFrZXIpIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIG9uY2U6IGZ1bmN0aW9uKGZ1bmMpIHtcbiAgICAgICAgdmFyIHJhbiA9IGZhbHNlLCBtZW1vO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKHJhbikgcmV0dXJuIG1lbW87XG4gICAgICAgICAgcmFuID0gdHJ1ZTtcbiAgICAgICAgICBtZW1vID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgIGZ1bmMgPSBudWxsO1xuICAgICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICB2YXIgXyA9IG1pbmlzY29yZSgpLCBFdmVudHM7XG5cbiAgLy8gQmFja2JvbmUuRXZlbnRzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLVxuXG4gIC8vIEEgbW9kdWxlIHRoYXQgY2FuIGJlIG1peGVkIGluIHRvICphbnkgb2JqZWN0KiBpbiBvcmRlciB0byBwcm92aWRlIGl0IHdpdGhcbiAgLy8gY3VzdG9tIGV2ZW50cy4gWW91IG1heSBiaW5kIHdpdGggYG9uYCBvciByZW1vdmUgd2l0aCBgb2ZmYCBjYWxsYmFja1xuICAvLyBmdW5jdGlvbnMgdG8gYW4gZXZlbnQ7IGB0cmlnZ2VyYC1pbmcgYW4gZXZlbnQgZmlyZXMgYWxsIGNhbGxiYWNrcyBpblxuICAvLyBzdWNjZXNzaW9uLlxuICAvL1xuICAvLyAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAvLyAgICAgXy5leHRlbmQob2JqZWN0LCBCYWNrYm9uZS5FdmVudHMpO1xuICAvLyAgICAgb2JqZWN0Lm9uKCdleHBhbmQnLCBmdW5jdGlvbigpeyBhbGVydCgnZXhwYW5kZWQnKTsgfSk7XG4gIC8vICAgICBvYmplY3QudHJpZ2dlcignZXhwYW5kJyk7XG4gIC8vXG4gIEV2ZW50cyA9IHtcblxuICAgIC8vIEJpbmQgYW4gZXZlbnQgdG8gYSBgY2FsbGJhY2tgIGZ1bmN0aW9uLiBQYXNzaW5nIGBcImFsbFwiYCB3aWxsIGJpbmRcbiAgICAvLyB0aGUgY2FsbGJhY2sgdG8gYWxsIGV2ZW50cyBmaXJlZC5cbiAgICBvbjogZnVuY3Rpb24obmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICAgIGlmICghZXZlbnRzQXBpKHRoaXMsICdvbicsIG5hbWUsIFtjYWxsYmFjaywgY29udGV4dF0pIHx8ICFjYWxsYmFjaykgcmV0dXJuIHRoaXM7XG4gICAgICB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICAgIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHNbbmFtZV0gfHwgKHRoaXMuX2V2ZW50c1tuYW1lXSA9IFtdKTtcbiAgICAgIGV2ZW50cy5wdXNoKHtjYWxsYmFjazogY2FsbGJhY2ssIGNvbnRleHQ6IGNvbnRleHQsIGN0eDogY29udGV4dCB8fCB0aGlzfSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLy8gQmluZCBhbiBldmVudCB0byBvbmx5IGJlIHRyaWdnZXJlZCBhIHNpbmdsZSB0aW1lLiBBZnRlciB0aGUgZmlyc3QgdGltZVxuICAgIC8vIHRoZSBjYWxsYmFjayBpcyBpbnZva2VkLCBpdCB3aWxsIGJlIHJlbW92ZWQuXG4gICAgb25jZTogZnVuY3Rpb24obmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICAgIGlmICghZXZlbnRzQXBpKHRoaXMsICdvbmNlJywgbmFtZSwgW2NhbGxiYWNrLCBjb250ZXh0XSkgfHwgIWNhbGxiYWNrKSByZXR1cm4gdGhpcztcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIHZhciBvbmNlID0gXy5vbmNlKGZ1bmN0aW9uKCkge1xuICAgICAgICBzZWxmLm9mZihuYW1lLCBvbmNlKTtcbiAgICAgICAgY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH0pO1xuICAgICAgb25jZS5fY2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICAgIHJldHVybiB0aGlzLm9uKG5hbWUsIG9uY2UsIGNvbnRleHQpO1xuICAgIH0sXG5cbiAgICAvLyBSZW1vdmUgb25lIG9yIG1hbnkgY2FsbGJhY2tzLiBJZiBgY29udGV4dGAgaXMgbnVsbCwgcmVtb3ZlcyBhbGxcbiAgICAvLyBjYWxsYmFja3Mgd2l0aCB0aGF0IGZ1bmN0aW9uLiBJZiBgY2FsbGJhY2tgIGlzIG51bGwsIHJlbW92ZXMgYWxsXG4gICAgLy8gY2FsbGJhY2tzIGZvciB0aGUgZXZlbnQuIElmIGBuYW1lYCBpcyBudWxsLCByZW1vdmVzIGFsbCBib3VuZFxuICAgIC8vIGNhbGxiYWNrcyBmb3IgYWxsIGV2ZW50cy5cbiAgICBvZmY6IGZ1bmN0aW9uKG5hbWUsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgICB2YXIgcmV0YWluLCBldiwgZXZlbnRzLCBuYW1lcywgaSwgbCwgaiwgaztcbiAgICAgIGlmICghdGhpcy5fZXZlbnRzIHx8ICFldmVudHNBcGkodGhpcywgJ29mZicsIG5hbWUsIFtjYWxsYmFjaywgY29udGV4dF0pKSByZXR1cm4gdGhpcztcbiAgICAgIGlmICghbmFtZSAmJiAhY2FsbGJhY2sgJiYgIWNvbnRleHQpIHtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICBuYW1lcyA9IG5hbWUgPyBbbmFtZV0gOiBfLmtleXModGhpcy5fZXZlbnRzKTtcbiAgICAgIGZvciAoaSA9IDAsIGwgPSBuYW1lcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgbmFtZSA9IG5hbWVzW2ldO1xuICAgICAgICBpZiAoZXZlbnRzID0gdGhpcy5fZXZlbnRzW25hbWVdKSB7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzW25hbWVdID0gcmV0YWluID0gW107XG4gICAgICAgICAgaWYgKGNhbGxiYWNrIHx8IGNvbnRleHQpIHtcbiAgICAgICAgICAgIGZvciAoaiA9IDAsIGsgPSBldmVudHMubGVuZ3RoOyBqIDwgazsgaisrKSB7XG4gICAgICAgICAgICAgIGV2ID0gZXZlbnRzW2pdO1xuICAgICAgICAgICAgICBpZiAoKGNhbGxiYWNrICYmIGNhbGxiYWNrICE9PSBldi5jYWxsYmFjayAmJiBjYWxsYmFjayAhPT0gZXYuY2FsbGJhY2suX2NhbGxiYWNrKSB8fFxuICAgICAgICAgICAgICAgICAgKGNvbnRleHQgJiYgY29udGV4dCAhPT0gZXYuY29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICByZXRhaW4ucHVzaChldik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFyZXRhaW4ubGVuZ3RoKSBkZWxldGUgdGhpcy5fZXZlbnRzW25hbWVdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvLyBUcmlnZ2VyIG9uZSBvciBtYW55IGV2ZW50cywgZmlyaW5nIGFsbCBib3VuZCBjYWxsYmFja3MuIENhbGxiYWNrcyBhcmVcbiAgICAvLyBwYXNzZWQgdGhlIHNhbWUgYXJndW1lbnRzIGFzIGB0cmlnZ2VyYCBpcywgYXBhcnQgZnJvbSB0aGUgZXZlbnQgbmFtZVxuICAgIC8vICh1bmxlc3MgeW91J3JlIGxpc3RlbmluZyBvbiBgXCJhbGxcImAsIHdoaWNoIHdpbGwgY2F1c2UgeW91ciBjYWxsYmFjayB0b1xuICAgIC8vIHJlY2VpdmUgdGhlIHRydWUgbmFtZSBvZiB0aGUgZXZlbnQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50KS5cbiAgICB0cmlnZ2VyOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgICBpZiAoIXRoaXMuX2V2ZW50cykgcmV0dXJuIHRoaXM7XG4gICAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgIGlmICghZXZlbnRzQXBpKHRoaXMsICd0cmlnZ2VyJywgbmFtZSwgYXJncykpIHJldHVybiB0aGlzO1xuICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50c1tuYW1lXTtcbiAgICAgIHZhciBhbGxFdmVudHMgPSB0aGlzLl9ldmVudHMuYWxsO1xuICAgICAgaWYgKGV2ZW50cykgdHJpZ2dlckV2ZW50cyhldmVudHMsIGFyZ3MpO1xuICAgICAgaWYgKGFsbEV2ZW50cykgdHJpZ2dlckV2ZW50cyhhbGxFdmVudHMsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLy8gVGVsbCB0aGlzIG9iamVjdCB0byBzdG9wIGxpc3RlbmluZyB0byBlaXRoZXIgc3BlY2lmaWMgZXZlbnRzIC4uLiBvclxuICAgIC8vIHRvIGV2ZXJ5IG9iamVjdCBpdCdzIGN1cnJlbnRseSBsaXN0ZW5pbmcgdG8uXG4gICAgc3RvcExpc3RlbmluZzogZnVuY3Rpb24ob2JqLCBuYW1lLCBjYWxsYmFjaykge1xuICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycztcbiAgICAgIGlmICghbGlzdGVuZXJzKSByZXR1cm4gdGhpcztcbiAgICAgIHZhciBkZWxldGVMaXN0ZW5lciA9ICFuYW1lICYmICFjYWxsYmFjaztcbiAgICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ29iamVjdCcpIGNhbGxiYWNrID0gdGhpcztcbiAgICAgIGlmIChvYmopIChsaXN0ZW5lcnMgPSB7fSlbb2JqLl9saXN0ZW5lcklkXSA9IG9iajtcbiAgICAgIGZvciAodmFyIGlkIGluIGxpc3RlbmVycykge1xuICAgICAgICBsaXN0ZW5lcnNbaWRdLm9mZihuYW1lLCBjYWxsYmFjaywgdGhpcyk7XG4gICAgICAgIGlmIChkZWxldGVMaXN0ZW5lcikgZGVsZXRlIHRoaXMuX2xpc3RlbmVyc1tpZF07XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgfTtcblxuICAvLyBSZWd1bGFyIGV4cHJlc3Npb24gdXNlZCB0byBzcGxpdCBldmVudCBzdHJpbmdzLlxuICB2YXIgZXZlbnRTcGxpdHRlciA9IC9cXHMrLztcblxuICAvLyBJbXBsZW1lbnQgZmFuY3kgZmVhdHVyZXMgb2YgdGhlIEV2ZW50cyBBUEkgc3VjaCBhcyBtdWx0aXBsZSBldmVudFxuICAvLyBuYW1lcyBgXCJjaGFuZ2UgYmx1clwiYCBhbmQgalF1ZXJ5LXN0eWxlIGV2ZW50IG1hcHMgYHtjaGFuZ2U6IGFjdGlvbn1gXG4gIC8vIGluIHRlcm1zIG9mIHRoZSBleGlzdGluZyBBUEkuXG4gIHZhciBldmVudHNBcGkgPSBmdW5jdGlvbihvYmosIGFjdGlvbiwgbmFtZSwgcmVzdCkge1xuICAgIGlmICghbmFtZSkgcmV0dXJuIHRydWU7XG5cbiAgICAvLyBIYW5kbGUgZXZlbnQgbWFwcy5cbiAgICBpZiAodHlwZW9mIG5hbWUgPT09ICdvYmplY3QnKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gbmFtZSkge1xuICAgICAgICBvYmpbYWN0aW9uXS5hcHBseShvYmosIFtrZXksIG5hbWVba2V5XV0uY29uY2F0KHJlc3QpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgc3BhY2Ugc2VwYXJhdGVkIGV2ZW50IG5hbWVzLlxuICAgIGlmIChldmVudFNwbGl0dGVyLnRlc3QobmFtZSkpIHtcbiAgICAgIHZhciBuYW1lcyA9IG5hbWUuc3BsaXQoZXZlbnRTcGxpdHRlcik7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG5hbWVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICBvYmpbYWN0aW9uXS5hcHBseShvYmosIFtuYW1lc1tpXV0uY29uY2F0KHJlc3QpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICAvLyBBIGRpZmZpY3VsdC10by1iZWxpZXZlLCBidXQgb3B0aW1pemVkIGludGVybmFsIGRpc3BhdGNoIGZ1bmN0aW9uIGZvclxuICAvLyB0cmlnZ2VyaW5nIGV2ZW50cy4gVHJpZXMgdG8ga2VlcCB0aGUgdXN1YWwgY2FzZXMgc3BlZWR5IChtb3N0IGludGVybmFsXG4gIC8vIEJhY2tib25lIGV2ZW50cyBoYXZlIDMgYXJndW1lbnRzKS5cbiAgdmFyIHRyaWdnZXJFdmVudHMgPSBmdW5jdGlvbihldmVudHMsIGFyZ3MpIHtcbiAgICB2YXIgZXYsIGkgPSAtMSwgbCA9IGV2ZW50cy5sZW5ndGgsIGExID0gYXJnc1swXSwgYTIgPSBhcmdzWzFdLCBhMyA9IGFyZ3NbMl07XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5jYWxsKGV2LmN0eCk7IHJldHVybjtcbiAgICAgIGNhc2UgMTogd2hpbGUgKCsraSA8IGwpIChldiA9IGV2ZW50c1tpXSkuY2FsbGJhY2suY2FsbChldi5jdHgsIGExKTsgcmV0dXJuO1xuICAgICAgY2FzZSAyOiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5jYWxsKGV2LmN0eCwgYTEsIGEyKTsgcmV0dXJuO1xuICAgICAgY2FzZSAzOiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5jYWxsKGV2LmN0eCwgYTEsIGEyLCBhMyk7IHJldHVybjtcbiAgICAgIGRlZmF1bHQ6IHdoaWxlICgrK2kgPCBsKSAoZXYgPSBldmVudHNbaV0pLmNhbGxiYWNrLmFwcGx5KGV2LmN0eCwgYXJncyk7XG4gICAgfVxuICB9O1xuXG4gIHZhciBsaXN0ZW5NZXRob2RzID0ge2xpc3RlblRvOiAnb24nLCBsaXN0ZW5Ub09uY2U6ICdvbmNlJ307XG5cbiAgLy8gSW52ZXJzaW9uLW9mLWNvbnRyb2wgdmVyc2lvbnMgb2YgYG9uYCBhbmQgYG9uY2VgLiBUZWxsICp0aGlzKiBvYmplY3QgdG9cbiAgLy8gbGlzdGVuIHRvIGFuIGV2ZW50IGluIGFub3RoZXIgb2JqZWN0IC4uLiBrZWVwaW5nIHRyYWNrIG9mIHdoYXQgaXQnc1xuICAvLyBsaXN0ZW5pbmcgdG8uXG4gIF8uZWFjaChsaXN0ZW5NZXRob2RzLCBmdW5jdGlvbihpbXBsZW1lbnRhdGlvbiwgbWV0aG9kKSB7XG4gICAgRXZlbnRzW21ldGhvZF0gPSBmdW5jdGlvbihvYmosIG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzIHx8ICh0aGlzLl9saXN0ZW5lcnMgPSB7fSk7XG4gICAgICB2YXIgaWQgPSBvYmouX2xpc3RlbmVySWQgfHwgKG9iai5fbGlzdGVuZXJJZCA9IF8udW5pcXVlSWQoJ2wnKSk7XG4gICAgICBsaXN0ZW5lcnNbaWRdID0gb2JqO1xuICAgICAgaWYgKHR5cGVvZiBuYW1lID09PSAnb2JqZWN0JykgY2FsbGJhY2sgPSB0aGlzO1xuICAgICAgb2JqW2ltcGxlbWVudGF0aW9uXShuYW1lLCBjYWxsYmFjaywgdGhpcyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICB9KTtcblxuICAvLyBBbGlhc2VzIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbiAgRXZlbnRzLmJpbmQgICA9IEV2ZW50cy5vbjtcbiAgRXZlbnRzLnVuYmluZCA9IEV2ZW50cy5vZmY7XG5cbiAgLy8gTWl4aW4gdXRpbGl0eVxuICBFdmVudHMubWl4aW4gPSBmdW5jdGlvbihwcm90bykge1xuICAgIHZhciBleHBvcnRzID0gWydvbicsICdvbmNlJywgJ29mZicsICd0cmlnZ2VyJywgJ3N0b3BMaXN0ZW5pbmcnLCAnbGlzdGVuVG8nLFxuICAgICAgICAgICAgICAgICAgICdsaXN0ZW5Ub09uY2UnLCAnYmluZCcsICd1bmJpbmQnXTtcbiAgICBfLmVhY2goZXhwb3J0cywgZnVuY3Rpb24obmFtZSkge1xuICAgICAgcHJvdG9bbmFtZV0gPSB0aGlzW25hbWVdO1xuICAgIH0sIHRoaXMpO1xuICAgIHJldHVybiBwcm90bztcbiAgfTtcblxuICAvLyBFeHBvcnQgRXZlbnRzIGFzIEJhY2tib25lRXZlbnRzIGRlcGVuZGluZyBvbiBjdXJyZW50IGNvbnRleHRcbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBFdmVudHM7XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBFdmVudHM7XG4gICAgfVxuICAgIGV4cG9ydHMuQmFja2JvbmVFdmVudHMgPSBFdmVudHM7XG4gIH0gZWxzZSB7XG4gICAgcm9vdC5CYWNrYm9uZUV2ZW50cyA9IEV2ZW50cztcbiAgfVxufSkodGhpcyk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUnKTtcbiIsIihmdW5jdGlvbiAoZGVmaW5pdGlvbikge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcbiAgfVxuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICBkZWZpbmUoZGVmaW5pdGlvbik7XG4gIH1cbiAgZWxzZSB7XG4gICAgd2luZG93LkJhY2tib25lRXh0ZW5kID0gZGVmaW5pdGlvbigpO1xuICB9XG59KShmdW5jdGlvbiAoKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuICBcbiAgLy8gbWluaS11bmRlcnNjb3JlXG4gIHZhciBfID0ge1xuICAgIGhhczogZnVuY3Rpb24gKG9iaiwga2V5KSB7XG4gICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTtcbiAgICB9LFxuICBcbiAgICBleHRlbmQ6IGZ1bmN0aW9uKG9iaikge1xuICAgICAgZm9yICh2YXIgaT0xOyBpPGFyZ3VtZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuICAgICAgICBpZiAoc291cmNlKSB7XG4gICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIG9ialtwcm9wXSA9IHNvdXJjZVtwcm9wXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICB9O1xuXG4gIC8vLyBGb2xsb3dpbmcgY29kZSBpcyBwYXN0ZWQgZnJvbSBCYWNrYm9uZS5qcyAvLy9cblxuICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gY29ycmVjdGx5IHNldCB1cCB0aGUgcHJvdG90eXBlIGNoYWluLCBmb3Igc3ViY2xhc3Nlcy5cbiAgLy8gU2ltaWxhciB0byBgZ29vZy5pbmhlcml0c2AsIGJ1dCB1c2VzIGEgaGFzaCBvZiBwcm90b3R5cGUgcHJvcGVydGllcyBhbmRcbiAgLy8gY2xhc3MgcHJvcGVydGllcyB0byBiZSBleHRlbmRlZC5cbiAgdmFyIGV4dGVuZCA9IGZ1bmN0aW9uKHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gICAgdmFyIHBhcmVudCA9IHRoaXM7XG4gICAgdmFyIGNoaWxkO1xuXG4gICAgLy8gVGhlIGNvbnN0cnVjdG9yIGZ1bmN0aW9uIGZvciB0aGUgbmV3IHN1YmNsYXNzIGlzIGVpdGhlciBkZWZpbmVkIGJ5IHlvdVxuICAgIC8vICh0aGUgXCJjb25zdHJ1Y3RvclwiIHByb3BlcnR5IGluIHlvdXIgYGV4dGVuZGAgZGVmaW5pdGlvbiksIG9yIGRlZmF1bHRlZFxuICAgIC8vIGJ5IHVzIHRvIHNpbXBseSBjYWxsIHRoZSBwYXJlbnQncyBjb25zdHJ1Y3Rvci5cbiAgICBpZiAocHJvdG9Qcm9wcyAmJiBfLmhhcyhwcm90b1Byb3BzLCAnY29uc3RydWN0b3InKSkge1xuICAgICAgY2hpbGQgPSBwcm90b1Byb3BzLmNvbnN0cnVjdG9yO1xuICAgIH0gZWxzZSB7XG4gICAgICBjaGlsZCA9IGZ1bmN0aW9uKCl7IHJldHVybiBwYXJlbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICB9XG5cbiAgICAvLyBBZGQgc3RhdGljIHByb3BlcnRpZXMgdG8gdGhlIGNvbnN0cnVjdG9yIGZ1bmN0aW9uLCBpZiBzdXBwbGllZC5cbiAgICBfLmV4dGVuZChjaGlsZCwgcGFyZW50LCBzdGF0aWNQcm9wcyk7XG5cbiAgICAvLyBTZXQgdGhlIHByb3RvdHlwZSBjaGFpbiB0byBpbmhlcml0IGZyb20gYHBhcmVudGAsIHdpdGhvdXQgY2FsbGluZ1xuICAgIC8vIGBwYXJlbnRgJ3MgY29uc3RydWN0b3IgZnVuY3Rpb24uXG4gICAgdmFyIFN1cnJvZ2F0ZSA9IGZ1bmN0aW9uKCl7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfTtcbiAgICBTdXJyb2dhdGUucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTtcbiAgICBjaGlsZC5wcm90b3R5cGUgPSBuZXcgU3Vycm9nYXRlKCk7XG5cbiAgICAvLyBBZGQgcHJvdG90eXBlIHByb3BlcnRpZXMgKGluc3RhbmNlIHByb3BlcnRpZXMpIHRvIHRoZSBzdWJjbGFzcyxcbiAgICAvLyBpZiBzdXBwbGllZC5cbiAgICBpZiAocHJvdG9Qcm9wcykgXy5leHRlbmQoY2hpbGQucHJvdG90eXBlLCBwcm90b1Byb3BzKTtcblxuICAgIC8vIFNldCBhIGNvbnZlbmllbmNlIHByb3BlcnR5IGluIGNhc2UgdGhlIHBhcmVudCdzIHByb3RvdHlwZSBpcyBuZWVkZWRcbiAgICAvLyBsYXRlci5cbiAgICBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlO1xuXG4gICAgcmV0dXJuIGNoaWxkO1xuICB9O1xuXG4gIC8vIEV4cG9zZSB0aGUgZXh0ZW5kIGZ1bmN0aW9uXG4gIHJldHVybiBleHRlbmQ7XG59KTtcbiIsIi8vIHRoaXMgaXMgdGhlIGV4dHJhY3RlZCB2aWV3IG1vZGVsIGZyb20gYmFja2JvbmVcbi8vIG5vdGUgdGhhdCB3ZSBpbmplY3QgamJvbmUgYXMganF1ZXJ5IHJlcGxhY21lbnRcbi8vIChhbmQgdW5kZXJzY29yZSBkaXJlY3RseSlcbi8vXG4vLyBWaWV3cyBhcmUgYWxtb3N0IG1vcmUgY29udmVudGlvbiB0aGFuIHRoZXkgYXJlIGFjdHVhbCBjb2RlLlxuLy8gIE1WQyBwYXR0ZXJuXG4vLyBCYWNrYm9uZS5WaWV3XG4vLyAtLS0tLS0tLS0tLS0tXG5cbnZhciBfID0gcmVxdWlyZShcInVuZGVyc2NvcmVcIik7XG52YXIgRXZlbnRzID0gcmVxdWlyZShcImJhY2tib25lLWV2ZW50cy1zdGFuZGFsb25lXCIpO1xudmFyIGV4dGVuZCA9IHJlcXVpcmUoXCJiYWNrYm9uZS1leHRlbmQtc3RhbmRhbG9uZVwiKTtcbnZhciAkID0gcmVxdWlyZSgnamJvbmUnKTtcblxuLy8gQmFja2JvbmUgVmlld3MgYXJlIGFsbW9zdCBtb3JlIGNvbnZlbnRpb24gdGhhbiB0aGV5IGFyZSBhY3R1YWwgY29kZS4gQSBWaWV3XG4vLyBpcyBzaW1wbHkgYSBKYXZhU2NyaXB0IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYSBsb2dpY2FsIGNodW5rIG9mIFVJIGluIHRoZVxuLy8gRE9NLiBUaGlzIG1pZ2h0IGJlIGEgc2luZ2xlIGl0ZW0sIGFuIGVudGlyZSBsaXN0LCBhIHNpZGViYXIgb3IgcGFuZWwsIG9yXG4vLyBldmVuIHRoZSBzdXJyb3VuZGluZyBmcmFtZSB3aGljaCB3cmFwcyB5b3VyIHdob2xlIGFwcC4gRGVmaW5pbmcgYSBjaHVuayBvZlxuLy8gVUkgYXMgYSAqKlZpZXcqKiBhbGxvd3MgeW91IHRvIGRlZmluZSB5b3VyIERPTSBldmVudHMgZGVjbGFyYXRpdmVseSwgd2l0aG91dFxuLy8gaGF2aW5nIHRvIHdvcnJ5IGFib3V0IHJlbmRlciBvcmRlciAuLi4gYW5kIG1ha2VzIGl0IGVhc3kgZm9yIHRoZSB2aWV3IHRvXG4vLyByZWFjdCB0byBzcGVjaWZpYyBjaGFuZ2VzIGluIHRoZSBzdGF0ZSBvZiB5b3VyIG1vZGVscy5cblxuLy8gQ3JlYXRpbmcgYSBCYWNrYm9uZS5WaWV3IGNyZWF0ZXMgaXRzIGluaXRpYWwgZWxlbWVudCBvdXRzaWRlIG9mIHRoZSBET00sXG4vLyBpZiBhbiBleGlzdGluZyBlbGVtZW50IGlzIG5vdCBwcm92aWRlZC4uLlxudmFyIFZpZXcgPSAgZnVuY3Rpb24ob3B0aW9ucykge1xuICB0aGlzLmNpZCA9IF8udW5pcXVlSWQoJ3ZpZXcnKTtcbiAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcbiAgXy5leHRlbmQodGhpcywgXy5waWNrKG9wdGlvbnMsIHZpZXdPcHRpb25zKSk7XG4gIHRoaXMuX2Vuc3VyZUVsZW1lbnQoKTtcbiAgdGhpcy5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59O1xuXG4vLyBDYWNoZWQgcmVnZXggdG8gc3BsaXQga2V5cyBmb3IgYGRlbGVnYXRlYC5cbnZhciBkZWxlZ2F0ZUV2ZW50U3BsaXR0ZXIgPSAvXihcXFMrKVxccyooLiopJC87XG5cbi8vIExpc3Qgb2YgdmlldyBvcHRpb25zIHRvIGJlIG1lcmdlZCBhcyBwcm9wZXJ0aWVzLlxudmFyIHZpZXdPcHRpb25zID0gWydtb2RlbCcsICdjb2xsZWN0aW9uJywgJ2VsJywgJ2lkJywgJ2F0dHJpYnV0ZXMnLCAnY2xhc3NOYW1lJywgJ3RhZ05hbWUnLCAnZXZlbnRzJ107XG5cbi8vIFNldCB1cCBhbGwgaW5oZXJpdGFibGUgKipCYWNrYm9uZS5WaWV3KiogcHJvcGVydGllcyBhbmQgbWV0aG9kcy5cbl8uZXh0ZW5kKFZpZXcucHJvdG90eXBlLCBFdmVudHMsIHtcblxuICAvLyBUaGUgZGVmYXVsdCBgdGFnTmFtZWAgb2YgYSBWaWV3J3MgZWxlbWVudCBpcyBgXCJkaXZcImAuXG4gIHRhZ05hbWU6ICdkaXYnLFxuXG4gIC8vIGpRdWVyeSBkZWxlZ2F0ZSBmb3IgZWxlbWVudCBsb29rdXAsIHNjb3BlZCB0byBET00gZWxlbWVudHMgd2l0aGluIHRoZVxuICAvLyBjdXJyZW50IHZpZXcuIFRoaXMgc2hvdWxkIGJlIHByZWZlcnJlZCB0byBnbG9iYWwgbG9va3VwcyB3aGVyZSBwb3NzaWJsZS5cbiAgJDogZnVuY3Rpb24oc2VsZWN0b3IpIHtcbiAgICByZXR1cm4gdGhpcy4kZWwuZmluZChzZWxlY3Rvcik7XG4gIH0sXG5cbiAgICAvLyBJbml0aWFsaXplIGlzIGFuIGVtcHR5IGZ1bmN0aW9uIGJ5IGRlZmF1bHQuIE92ZXJyaWRlIGl0IHdpdGggeW91ciBvd25cbiAgICAvLyBpbml0aWFsaXphdGlvbiBsb2dpYy5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXt9LFxuXG4gICAgLy8gKipyZW5kZXIqKiBpcyB0aGUgY29yZSBmdW5jdGlvbiB0aGF0IHlvdXIgdmlldyBzaG91bGQgb3ZlcnJpZGUsIGluIG9yZGVyXG4gICAgLy8gdG8gcG9wdWxhdGUgaXRzIGVsZW1lbnQgKGB0aGlzLmVsYCksIHdpdGggdGhlIGFwcHJvcHJpYXRlIEhUTUwuIFRoZVxuICAgIC8vIGNvbnZlbnRpb24gaXMgZm9yICoqcmVuZGVyKiogdG8gYWx3YXlzIHJldHVybiBgdGhpc2AuXG4gIHJlbmRlcjogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgICAvLyBSZW1vdmUgdGhpcyB2aWV3IGJ5IHRha2luZyB0aGUgZWxlbWVudCBvdXQgb2YgdGhlIERPTSwgYW5kIHJlbW92aW5nIGFueVxuICAgIC8vIGFwcGxpY2FibGUgQmFja2JvbmUuRXZlbnRzIGxpc3RlbmVycy5cbiAgcmVtb3ZlOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9yZW1vdmVFbGVtZW50KCk7XG4gICAgdGhpcy5zdG9wTGlzdGVuaW5nKCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgICAvLyBSZW1vdmUgdGhpcyB2aWV3J3MgZWxlbWVudCBmcm9tIHRoZSBkb2N1bWVudCBhbmQgYWxsIGV2ZW50IGxpc3RlbmVyc1xuICAgIC8vIGF0dGFjaGVkIHRvIGl0LiBFeHBvc2VkIGZvciBzdWJjbGFzc2VzIHVzaW5nIGFuIGFsdGVybmF0aXZlIERPTVxuICAgIC8vIG1hbmlwdWxhdGlvbiBBUEkuXG4gIF9yZW1vdmVFbGVtZW50OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLiRlbC5yZW1vdmUoKTtcbiAgfSxcblxuICAgIC8vIENoYW5nZSB0aGUgdmlldydzIGVsZW1lbnQgKGB0aGlzLmVsYCBwcm9wZXJ0eSkgYW5kIHJlLWRlbGVnYXRlIHRoZVxuICAgIC8vIHZpZXcncyBldmVudHMgb24gdGhlIG5ldyBlbGVtZW50LlxuICBzZXRFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgdGhpcy51bmRlbGVnYXRlRXZlbnRzKCk7XG4gICAgdGhpcy5fc2V0RWxlbWVudChlbGVtZW50KTtcbiAgICB0aGlzLmRlbGVnYXRlRXZlbnRzKCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgICAvLyBDcmVhdGVzIHRoZSBgdGhpcy5lbGAgYW5kIGB0aGlzLiRlbGAgcmVmZXJlbmNlcyBmb3IgdGhpcyB2aWV3IHVzaW5nIHRoZVxuICAgIC8vIGdpdmVuIGBlbGAuIGBlbGAgY2FuIGJlIGEgQ1NTIHNlbGVjdG9yIG9yIGFuIEhUTUwgc3RyaW5nLCBhIGpRdWVyeVxuICAgIC8vIGNvbnRleHQgb3IgYW4gZWxlbWVudC4gU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUgdGhpcyB0byB1dGlsaXplIGFuXG4gICAgLy8gYWx0ZXJuYXRpdmUgRE9NIG1hbmlwdWxhdGlvbiBBUEkgYW5kIGFyZSBvbmx5IHJlcXVpcmVkIHRvIHNldCB0aGVcbiAgICAvLyBgdGhpcy5lbGAgcHJvcGVydHkuXG4gIF9zZXRFbGVtZW50OiBmdW5jdGlvbihlbCkge1xuICAgIHRoaXMuJGVsID0gZWwgaW5zdGFuY2VvZiAkID8gZWwgOiAkKGVsKTtcbiAgICB0aGlzLmVsID0gdGhpcy4kZWxbMF07XG4gIH0sXG5cbiAgICAvLyBTZXQgY2FsbGJhY2tzLCB3aGVyZSBgdGhpcy5ldmVudHNgIGlzIGEgaGFzaCBvZlxuICAgIC8vXG4gICAgLy8gKntcImV2ZW50IHNlbGVjdG9yXCI6IFwiY2FsbGJhY2tcIn0qXG4gICAgLy9cbiAgICAvLyAgICAge1xuICAgIC8vICAgICAgICdtb3VzZWRvd24gLnRpdGxlJzogICdlZGl0JyxcbiAgICAvLyAgICAgICAnY2xpY2sgLmJ1dHRvbic6ICAgICAnc2F2ZScsXG4gICAgLy8gICAgICAgJ2NsaWNrIC5vcGVuJzogICAgICAgZnVuY3Rpb24oZSkgeyAuLi4gfVxuICAgIC8vICAgICB9XG4gICAgLy9cbiAgICAvLyBwYWlycy4gQ2FsbGJhY2tzIHdpbGwgYmUgYm91bmQgdG8gdGhlIHZpZXcsIHdpdGggYHRoaXNgIHNldCBwcm9wZXJseS5cbiAgICAvLyBVc2VzIGV2ZW50IGRlbGVnYXRpb24gZm9yIGVmZmljaWVuY3kuXG4gICAgLy8gT21pdHRpbmcgdGhlIHNlbGVjdG9yIGJpbmRzIHRoZSBldmVudCB0byBgdGhpcy5lbGAuXG4gIGRlbGVnYXRlRXZlbnRzOiBmdW5jdGlvbihldmVudHMpIHtcbiAgICBpZiAoIShldmVudHMgfHwgKGV2ZW50cyA9IF8ucmVzdWx0KHRoaXMsICdldmVudHMnKSkpKSByZXR1cm4gdGhpcztcbiAgICB0aGlzLnVuZGVsZWdhdGVFdmVudHMoKTtcbiAgICBmb3IgKHZhciBrZXkgaW4gZXZlbnRzKSB7XG4gICAgICB2YXIgbWV0aG9kID0gZXZlbnRzW2tleV07XG4gICAgICBpZiAoIV8uaXNGdW5jdGlvbihtZXRob2QpKSBtZXRob2QgPSB0aGlzW2V2ZW50c1trZXldXTtcbiAgICAgIGlmICghbWV0aG9kKSBjb250aW51ZTtcbiAgICAgIHZhciBtYXRjaCA9IGtleS5tYXRjaChkZWxlZ2F0ZUV2ZW50U3BsaXR0ZXIpO1xuICAgICAgdGhpcy5kZWxlZ2F0ZShtYXRjaFsxXSwgbWF0Y2hbMl0sIF8uYmluZChtZXRob2QsIHRoaXMpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgICAvLyBBZGQgYSBzaW5nbGUgZXZlbnQgbGlzdGVuZXIgdG8gdGhlIHZpZXcncyBlbGVtZW50IChvciBhIGNoaWxkIGVsZW1lbnRcbiAgICAvLyB1c2luZyBgc2VsZWN0b3JgKS4gVGhpcyBvbmx5IHdvcmtzIGZvciBkZWxlZ2F0ZS1hYmxlIGV2ZW50czogbm90IGBmb2N1c2AsXG4gICAgLy8gYGJsdXJgLCBhbmQgbm90IGBjaGFuZ2VgLCBgc3VibWl0YCwgYW5kIGByZXNldGAgaW4gSW50ZXJuZXQgRXhwbG9yZXIuXG4gIGRlbGVnYXRlOiBmdW5jdGlvbihldmVudE5hbWUsIHNlbGVjdG9yLCBsaXN0ZW5lcikge1xuICAgIHRoaXMuJGVsLm9uKGV2ZW50TmFtZSArICcuZGVsZWdhdGVFdmVudHMnICsgdGhpcy5jaWQsIHNlbGVjdG9yLCBsaXN0ZW5lcik7XG4gIH0sXG5cbiAgICAvLyBDbGVhcnMgYWxsIGNhbGxiYWNrcyBwcmV2aW91c2x5IGJvdW5kIHRvIHRoZSB2aWV3IGJ5IGBkZWxlZ2F0ZUV2ZW50c2AuXG4gICAgLy8gWW91IHVzdWFsbHkgZG9uJ3QgbmVlZCB0byB1c2UgdGhpcywgYnV0IG1heSB3aXNoIHRvIGlmIHlvdSBoYXZlIG11bHRpcGxlXG4gICAgLy8gQmFja2JvbmUgdmlld3MgYXR0YWNoZWQgdG8gdGhlIHNhbWUgRE9NIGVsZW1lbnQuXG4gIHVuZGVsZWdhdGVFdmVudHM6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLiRlbCkgdGhpcy4kZWwub2ZmKCcuZGVsZWdhdGVFdmVudHMnICsgdGhpcy5jaWQpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gICAgLy8gQSBmaW5lci1ncmFpbmVkIGB1bmRlbGVnYXRlRXZlbnRzYCBmb3IgcmVtb3ZpbmcgYSBzaW5nbGUgZGVsZWdhdGVkIGV2ZW50LlxuICAgIC8vIGBzZWxlY3RvcmAgYW5kIGBsaXN0ZW5lcmAgYXJlIGJvdGggb3B0aW9uYWwuXG4gIHVuZGVsZWdhdGU6IGZ1bmN0aW9uKGV2ZW50TmFtZSwgc2VsZWN0b3IsIGxpc3RlbmVyKSB7XG4gICAgdGhpcy4kZWwub2ZmKGV2ZW50TmFtZSArICcuZGVsZWdhdGVFdmVudHMnICsgdGhpcy5jaWQsIHNlbGVjdG9yLCBsaXN0ZW5lcik7XG4gIH0sXG5cbiAgICAvLyBQcm9kdWNlcyBhIERPTSBlbGVtZW50IHRvIGJlIGFzc2lnbmVkIHRvIHlvdXIgdmlldy4gRXhwb3NlZCBmb3JcbiAgICAvLyBzdWJjbGFzc2VzIHVzaW5nIGFuIGFsdGVybmF0aXZlIERPTSBtYW5pcHVsYXRpb24gQVBJLlxuICBfY3JlYXRlRWxlbWVudDogZnVuY3Rpb24odGFnTmFtZSkge1xuICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpO1xuICB9LFxuXG4gICAgLy8gRW5zdXJlIHRoYXQgdGhlIFZpZXcgaGFzIGEgRE9NIGVsZW1lbnQgdG8gcmVuZGVyIGludG8uXG4gICAgLy8gSWYgYHRoaXMuZWxgIGlzIGEgc3RyaW5nLCBwYXNzIGl0IHRocm91Z2ggYCQoKWAsIHRha2UgdGhlIGZpcnN0XG4gICAgLy8gbWF0Y2hpbmcgZWxlbWVudCwgYW5kIHJlLWFzc2lnbiBpdCB0byBgZWxgLiBPdGhlcndpc2UsIGNyZWF0ZVxuICAgIC8vIGFuIGVsZW1lbnQgZnJvbSB0aGUgYGlkYCwgYGNsYXNzTmFtZWAgYW5kIGB0YWdOYW1lYCBwcm9wZXJ0aWVzLlxuICBfZW5zdXJlRWxlbWVudDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKCF0aGlzLmVsKSB7XG4gICAgICB2YXIgYXR0cnMgPSBfLmV4dGVuZCh7fSwgXy5yZXN1bHQodGhpcywgJ2F0dHJpYnV0ZXMnKSk7XG4gICAgICBpZiAodGhpcy5pZCkgYXR0cnMuaWQgPSBfLnJlc3VsdCh0aGlzLCAnaWQnKTtcbiAgICAgIGlmICh0aGlzLmNsYXNzTmFtZSkgYXR0cnNbJ2NsYXNzJ10gPSBfLnJlc3VsdCh0aGlzLCAnY2xhc3NOYW1lJyk7XG4gICAgICB0aGlzLnNldEVsZW1lbnQodGhpcy5fY3JlYXRlRWxlbWVudChfLnJlc3VsdCh0aGlzLCAndGFnTmFtZScpKSk7XG4gICAgICB0aGlzLl9zZXRBdHRyaWJ1dGVzKGF0dHJzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXRFbGVtZW50KF8ucmVzdWx0KHRoaXMsICdlbCcpKTtcbiAgICB9XG4gIH0sXG5cbiAgICAvLyBTZXQgYXR0cmlidXRlcyBmcm9tIGEgaGFzaCBvbiB0aGlzIHZpZXcncyBlbGVtZW50LiAgRXhwb3NlZCBmb3JcbiAgICAvLyBzdWJjbGFzc2VzIHVzaW5nIGFuIGFsdGVybmF0aXZlIERPTSBtYW5pcHVsYXRpb24gQVBJLlxuICBfc2V0QXR0cmlidXRlczogZnVuY3Rpb24oYXR0cmlidXRlcykge1xuICAgIHRoaXMuJGVsLmF0dHIoYXR0cmlidXRlcyk7XG4gIH1cblxufSk7XG5cbi8vIHNldHVwIGluaGVyaXRhbmNlXG5WaWV3LmV4dGVuZCA9IGV4dGVuZDtcbm1vZHVsZS5leHBvcnRzID0gVmlldztcbiIsInZhciBldmVudHMgPSByZXF1aXJlKFwiYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmVcIik7XG5cbmV2ZW50cy5vbkFsbCA9IGZ1bmN0aW9uKGNhbGxiYWNrLGNvbnRleHQpe1xuICB0aGlzLm9uKFwiYWxsXCIsIGNhbGxiYWNrLGNvbnRleHQpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIE1peGluIHV0aWxpdHlcbmV2ZW50cy5vbGRNaXhpbiA9IGV2ZW50cy5taXhpbjtcbmV2ZW50cy5taXhpbiA9IGZ1bmN0aW9uKHByb3RvKSB7XG4gIGV2ZW50cy5vbGRNaXhpbihwcm90byk7XG4gIC8vIGFkZCBjdXN0b20gb25BbGxcbiAgdmFyIGV4cG9ydHMgPSBbJ29uQWxsJ107XG4gIGZvcih2YXIgaT0wOyBpIDwgZXhwb3J0cy5sZW5ndGg7aSsrKXtcbiAgICB2YXIgbmFtZSA9IGV4cG9ydHNbaV07XG4gICAgcHJvdG9bbmFtZV0gPSB0aGlzW25hbWVdO1xuICB9XG4gIHJldHVybiBwcm90bztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZXZlbnRzO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjguMFxudmFyIEdlbmVyaWNSZWFkZXIsIHhocjtcblxueGhyID0gcmVxdWlyZSgnbmV0cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEdlbmVyaWNSZWFkZXIgPSAoZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIEdlbmVyaWNSZWFkZXIoKSB7fVxuXG4gIEdlbmVyaWNSZWFkZXIucmVhZCA9IGZ1bmN0aW9uKHVybCwgY2FsbGJhY2spIHtcbiAgICB2YXIgb25yZXQ7XG4gICAgb25yZXQgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihlcnIsIHJlc3BvbnNlLCB0ZXh0KSB7XG4gICAgICAgIHJldHVybiBfdGhpcy5fb25SZXRyaWV2YWwodGV4dCwgY2FsbGJhY2spO1xuICAgICAgfTtcbiAgICB9KSh0aGlzKTtcbiAgICByZXR1cm4geGhyKHVybCwgb25yZXQpO1xuICB9O1xuXG4gIEdlbmVyaWNSZWFkZXIuX29uUmV0cmlldmFsID0gZnVuY3Rpb24odGV4dCwgY2FsbGJhY2spIHtcbiAgICB2YXIgclRleHQ7XG4gICAgclRleHQgPSB0aGlzLnBhcnNlKHRleHQpO1xuICAgIHJldHVybiBjYWxsYmFjayhyVGV4dCk7XG4gIH07XG5cbiAgcmV0dXJuIEdlbmVyaWNSZWFkZXI7XG5cbn0pKCk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG52YXIgU2VxO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNlcSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gU2VxKHNlcSwgbmFtZSwgaWQpIHtcbiAgICB2YXIgbWV0YTtcbiAgICB0aGlzLnNlcSA9IHNlcTtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICBtZXRhID0ge307XG4gIH1cblxuICByZXR1cm4gU2VxO1xuXG59KSgpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjguMFxudmFyIHN0cmluZ3M7XG5cbnN0cmluZ3MgPSB7XG4gIGNvbnRhaW5zOiBmdW5jdGlvbih0ZXh0LCBzZWFyY2gpIHtcbiAgICByZXR1cm4gJycuaW5kZXhPZi5jYWxsKHRleHQsIHNlYXJjaCwgMCkgIT09IC0xO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHN0cmluZ3M7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG52YXIgRmFzdGEsIEdlbmVyaWNSZWFkZXIsIFNlcSwgU3RyLFxuICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgX19leHRlbmRzID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChfX2hhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH07XG5cblN0ciA9IHJlcXVpcmUoXCIuL3N0cmluZ3NcIik7XG5cbkdlbmVyaWNSZWFkZXIgPSByZXF1aXJlKFwiLi9nZW5lcmljX3JlYWRlclwiKTtcblxuU2VxID0gcmVxdWlyZShcImJpb2pzLW1vZGVsXCIpLnNlcTtcblxubW9kdWxlLmV4cG9ydHMgPSBGYXN0YSA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgX19leHRlbmRzKEZhc3RhLCBfc3VwZXIpO1xuXG4gIGZ1bmN0aW9uIEZhc3RhKCkge1xuICAgIHJldHVybiBGYXN0YS5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIEZhc3RhLnBhcnNlID0gZnVuY3Rpb24odGV4dCkge1xuICAgIHZhciBjdXJyZW50U2VxLCBkYXRhYmFzZSwgZGF0YWJhc2VJRCwgaWRlbnRpZmllcnMsIGssIGxhYmVsLCBsaW5lLCBzZXFzLCBfaSwgX2xlbjtcbiAgICBzZXFzID0gW107XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0ZXh0KSAhPT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgICAgdGV4dCA9IHRleHQuc3BsaXQoXCJcXG5cIik7XG4gICAgfVxuICAgIGZvciAoX2kgPSAwLCBfbGVuID0gdGV4dC5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgbGluZSA9IHRleHRbX2ldO1xuICAgICAgaWYgKGxpbmVbMF0gPT09IFwiPlwiIHx8IGxpbmVbMF0gPT09IFwiO1wiKSB7XG4gICAgICAgIGxhYmVsID0gbGluZS5zbGljZSgxKTtcbiAgICAgICAgY3VycmVudFNlcSA9IG5ldyBTZXEoXCJcIiwgbGFiZWwsIHNlcXMubGVuZ3RoKTtcbiAgICAgICAgc2Vxcy5wdXNoKGN1cnJlbnRTZXEpO1xuICAgICAgICBpZiAoU3RyLmNvbnRhaW5zKFwifFwiLCBsaW5lKSkge1xuICAgICAgICAgIGlkZW50aWZpZXJzID0gbGFiZWwuc3BsaXQoXCJ8XCIpO1xuICAgICAgICAgIGsgPSAxO1xuICAgICAgICAgIHdoaWxlIChrIDwgaWRlbnRpZmllcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBkYXRhYmFzZSA9IGlkZW50aWZpZXJzW2tdO1xuICAgICAgICAgICAgZGF0YWJhc2VJRCA9IGlkZW50aWZpZXJzW2sgKyAxXTtcbiAgICAgICAgICAgIGN1cnJlbnRTZXEubWV0YVtkYXRhYmFzZV0gPSBkYXRhYmFzZUlEO1xuICAgICAgICAgICAgayArPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJyZW50U2VxLm5hbWUgPSBpZGVudGlmaWVyc1tpZGVudGlmaWVycy5sZW5ndGggLSAxXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VycmVudFNlcS5zZXEgKz0gbGluZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNlcXM7XG4gIH07XG5cbiAgcmV0dXJuIEZhc3RhO1xuXG59KShHZW5lcmljUmVhZGVyKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS44LjBcbnZhciBVdGlscztcblxuVXRpbHMgPSB7fTtcblxuVXRpbHMuc3BsaXROQ2hhcnMgPSBmdW5jdGlvbih0eHQsIG51bSkge1xuICB2YXIgaSwgcmVzdWx0LCBfaSwgX3JlZjtcbiAgcmVzdWx0ID0gW107XG4gIGZvciAoaSA9IF9pID0gMCwgX3JlZiA9IHR4dC5sZW5ndGggLSAxOyBudW0gPiAwID8gX2kgPD0gX3JlZiA6IF9pID49IF9yZWY7IGkgPSBfaSArPSBudW0pIHtcbiAgICByZXN1bHQucHVzaCh0eHQuc3Vic3RyKGksIG51bSkpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFV0aWxzO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjguMFxudmFyIEZhc3RhRXhwb3J0ZXIsIFV0aWxzO1xuXG5VdGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZhc3RhRXhwb3J0ZXIgPSAoZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIEZhc3RhRXhwb3J0ZXIoKSB7fVxuXG4gIEZhc3RhRXhwb3J0ZXJbXCJleHBvcnRcIl0gPSBmdW5jdGlvbihzZXFzLCBhY2Nlc3MpIHtcbiAgICB2YXIgc2VxLCB0ZXh0LCBfaSwgX2xlbjtcbiAgICB0ZXh0ID0gXCJcIjtcbiAgICBmb3IgKF9pID0gMCwgX2xlbiA9IHNlcXMubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgIHNlcSA9IHNlcXNbX2ldO1xuICAgICAgaWYgKGFjY2VzcyAhPSBudWxsKSB7XG4gICAgICAgIHNlcSA9IGFjY2VzcyhzZXEpO1xuICAgICAgfVxuICAgICAgdGV4dCArPSBcIj5cIiArIHNlcS5uYW1lICsgXCJcXG5cIjtcbiAgICAgIHRleHQgKz0gKFV0aWxzLnNwbGl0TkNoYXJzKHNlcS5zZXEsIDgwKSkuam9pbihcIlxcblwiKTtcbiAgICAgIHRleHQgKz0gXCJcXG5cIjtcbiAgICB9XG4gICAgcmV0dXJuIHRleHQ7XG4gIH07XG5cbiAgcmV0dXJuIEZhc3RhRXhwb3J0ZXI7XG5cbn0pKCk7XG4iLCJtb2R1bGUuZXhwb3J0cy5zZXEgPSByZXF1aXJlKFwiLi9zZXFcIik7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHNlcSwgbmFtZSwgaWQpIHtcbiAgICB0aGlzLnNlcSA9IHNlcTtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICB0aGlzLm1ldGEgPSB7fTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vc3JjL2luZGV4LmpzJylcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBBOiBcIiMwMGEzNWNcIixcbiAgUjogXCIjMDBmYzAzXCIsXG4gIE46IFwiIzAwZWIxNFwiLFxuICBEOiBcIiMwMGViMTRcIixcbiAgQzogXCIjMDAwMGZmXCIsXG4gIFE6IFwiIzAwZjEwZVwiLFxuICBFOiBcIiMwMGYxMGVcIixcbiAgRzogXCIjMDA5ZDYyXCIsXG4gIEg6IFwiIzAwZDUyYVwiLFxuICBJOiBcIiMwMDU0YWJcIixcbiAgTDogXCIjMDA3Yjg0XCIsXG4gIEs6IFwiIzAwZmYwMFwiLFxuICBNOiBcIiMwMDk3NjhcIixcbiAgRjogXCIjMDA4Nzc4XCIsXG4gIFA6IFwiIzAwZTAxZlwiLFxuICBTOiBcIiMwMGQ1MmFcIixcbiAgVDogXCIjMDBkYjI0XCIsXG4gIFc6IFwiIzAwYTg1N1wiLFxuICBZOiBcIiMwMGU2MTlcIixcbiAgVjogXCIjMDA1ZmEwXCIsXG4gIEI6IFwiIzAwZWIxNFwiLFxuICBYOiBcIiMwMGI2NDlcIixcbiAgWjogXCIjMDBmMTBlXCJcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgQTogXCIjQkJCQkJCXCIsXG4gIEI6IFwiZ3JleVwiLFxuICBDOiBcInllbGxvd1wiLFxuICBEOiBcInJlZFwiLFxuICBFOiBcInJlZFwiLFxuICBGOiBcIm1hZ2VudGFcIixcbiAgRzogXCJicm93blwiLFxuICBIOiBcIiMwMEZGRkZcIixcbiAgSTogXCIjQkJCQkJCXCIsXG4gIEo6IFwiI2ZmZlwiLFxuICBLOiBcIiMwMEZGRkZcIixcbiAgTDogXCIjQkJCQkJCXCIsXG4gIE06IFwiI0JCQkJCQlwiLFxuICBOOiBcImdyZWVuXCIsXG4gIE86IFwiI2ZmZlwiLFxuICBQOiBcImJyb3duXCIsXG4gIFE6IFwiZ3JlZW5cIixcbiAgUjogXCIjMDBGRkZGXCIsXG4gIFM6IFwiZ3JlZW5cIixcbiAgVDogXCJncmVlblwiLFxuICBVOiBcIiNmZmZcIixcbiAgVjogXCIjQkJCQkJCXCIsXG4gIFc6IFwibWFnZW50YVwiLFxuICBYOiBcImdyZXlcIixcbiAgWTogXCJtYWdlbnRhXCIsXG4gIFo6IFwiZ3JleVwiLFxuICBHYXA6IFwiZ3JleVwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwib3JhbmdlXCIsXG4gIEI6IFwiI2ZmZlwiLFxuICBDOiBcImdyZWVuXCIsXG4gIEQ6IFwicmVkXCIsXG4gIEU6IFwicmVkXCIsXG4gIEY6IFwiYmx1ZVwiLFxuICBHOiBcIm9yYW5nZVwiLFxuICBIOiBcInJlZFwiLFxuICBJOiBcImdyZWVuXCIsXG4gIEo6IFwiI2ZmZlwiLFxuICBLOiBcInJlZFwiLFxuICBMOiBcImdyZWVuXCIsXG4gIE06IFwiZ3JlZW5cIixcbiAgTjogXCIjZmZmXCIsXG4gIE86IFwiI2ZmZlwiLFxuICBQOiBcIm9yYW5nZVwiLFxuICBROiBcIiNmZmZcIixcbiAgUjogXCJyZWRcIixcbiAgUzogXCJvcmFuZ2VcIixcbiAgVDogXCJvcmFuZ2VcIixcbiAgVTogXCIjZmZmXCIsXG4gIFY6IFwiZ3JlZW5cIixcbiAgVzogXCJibHVlXCIsXG4gIFg6IFwiI2ZmZlwiLFxuICBZOiBcImJsdWVcIixcbiAgWjogXCIjZmZmXCIsXG4gIEdhcDogXCIjZmZmXCJcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgQTogXCIjODBhMGYwXCIsXG4gIFI6IFwiI2YwMTUwNVwiLFxuICBOOiBcIiMwMGZmMDBcIixcbiAgRDogXCIjYzA0OGMwXCIsXG4gIEM6IFwiI2YwODA4MFwiLFxuICBROiBcIiMwMGZmMDBcIixcbiAgRTogXCIjYzA0OGMwXCIsXG4gIEc6IFwiI2YwOTA0OFwiLFxuICBIOiBcIiMxNWE0YTRcIixcbiAgSTogXCIjODBhMGYwXCIsXG4gIEw6IFwiIzgwYTBmMFwiLFxuICBLOiBcIiNmMDE1MDVcIixcbiAgTTogXCIjODBhMGYwXCIsXG4gIEY6IFwiIzgwYTBmMFwiLFxuICBQOiBcIiNmZmZmMDBcIixcbiAgUzogXCIjMDBmZjAwXCIsXG4gIFQ6IFwiIzAwZmYwMFwiLFxuICBXOiBcIiM4MGEwZjBcIixcbiAgWTogXCIjMTVhNGE0XCIsXG4gIFY6IFwiIzgwYTBmMFwiLFxuICBCOiBcIiNmZmZcIixcbiAgWDogXCIjZmZmXCIsXG4gIFo6IFwiI2ZmZlwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwiI2U3MThlN1wiLFxuICBSOiBcIiM2ZjkwNmZcIixcbiAgTjogXCIjMWJlNDFiXCIsXG4gIEQ6IFwiIzc3ODg3N1wiLFxuICBDOiBcIiMyM2RjMjNcIixcbiAgUTogXCIjOTI2ZDkyXCIsXG4gIEU6IFwiI2ZmMDBmZlwiLFxuICBHOiBcIiMwMGZmMDBcIixcbiAgSDogXCIjNzU4YTc1XCIsXG4gIEk6IFwiIzhhNzU4YVwiLFxuICBMOiBcIiNhZTUxYWVcIixcbiAgSzogXCIjYTA1ZmEwXCIsXG4gIE06IFwiI2VmMTBlZlwiLFxuICBGOiBcIiM5ODY3OThcIixcbiAgUDogXCIjMDBmZjAwXCIsXG4gIFM6IFwiIzM2YzkzNlwiLFxuICBUOiBcIiM0N2I4NDdcIixcbiAgVzogXCIjOGE3NThhXCIsXG4gIFk6IFwiIzIxZGUyMVwiLFxuICBWOiBcIiM4NTdhODVcIixcbiAgQjogXCIjNDliNjQ5XCIsXG4gIFg6IFwiIzc1OGE3NVwiLFxuICBaOiBcIiNjOTM2YzlcIlxufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBBOiBcIiNhZDAwNTJcIixcbiAgQjogXCIjMGMwMGYzXCIsXG4gIEM6IFwiI2MyMDAzZFwiLFxuICBEOiBcIiMwYzAwZjNcIixcbiAgRTogXCIjMGMwMGYzXCIsXG4gIEY6IFwiI2NiMDAzNFwiLFxuICBHOiBcIiM2YTAwOTVcIixcbiAgSDogXCIjMTUwMGVhXCIsXG4gIEk6IFwiI2ZmMDAwMFwiLFxuICBKOiBcIiNmZmZcIixcbiAgSzogXCIjMDAwMGZmXCIsXG4gIEw6IFwiI2VhMDAxNVwiLFxuICBNOiBcIiNiMDAwNGZcIixcbiAgTjogXCIjMGMwMGYzXCIsXG4gIE86IFwiI2ZmZlwiLFxuICBQOiBcIiM0NjAwYjlcIixcbiAgUTogXCIjMGMwMGYzXCIsXG4gIFI6IFwiIzAwMDBmZlwiLFxuICBTOiBcIiM1ZTAwYTFcIixcbiAgVDogXCIjNjEwMDllXCIsXG4gIFU6IFwiI2ZmZlwiLFxuICBWOiBcIiNmNjAwMDlcIixcbiAgVzogXCIjNWIwMGE0XCIsXG4gIFg6IFwiIzY4MDA5N1wiLFxuICBZOiBcIiM0ZjAwYjBcIixcbiAgWjogXCIjMGMwMGYzXCJcbn07XG4iLCJtb2R1bGUuZXhwb3J0cy5zZWxlY3RvciA9IHJlcXVpcmUoXCIuL3NlbGVjdG9yXCIpO1xuXG4vLyBiYXNpY3Ncbm1vZHVsZS5leHBvcnRzLnRheWxvciA9IHJlcXVpcmUoXCIuL3RheWxvclwiKTtcbm1vZHVsZS5leHBvcnRzLnphcHBvPSByZXF1aXJlKFwiLi96YXBwb1wiKTtcbm1vZHVsZS5leHBvcnRzLmh5ZHJvPSByZXF1aXJlKFwiLi9oeWRyb3Bob2JpY2l0eVwiKTtcblxubW9kdWxlLmV4cG9ydHMuY2x1c3RhbCA9IHJlcXVpcmUoXCIuL2NsdXN0YWxcIik7XG5tb2R1bGUuZXhwb3J0cy5jbHVzdGFsMiA9IHJlcXVpcmUoXCIuL2NsdXN0YWwyXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy5jdXJpZWQgPSByZXF1aXJlKFwiLi9idXJpZWRcIik7XG5tb2R1bGUuZXhwb3J0cy5jaW5lbWEgPSByZXF1aXJlKFwiLi9jaW5lbWFcIik7XG5tb2R1bGUuZXhwb3J0cy5udWNsZW90aWRlICA9IHJlcXVpcmUoXCIuL251Y2xlb3RpZGVcIik7XG5tb2R1bGUuZXhwb3J0cy5oZWxpeCAgPSByZXF1aXJlKFwiLi9oZWxpeFwiKTtcbm1vZHVsZS5leHBvcnRzLmxlc2sgID0gcmVxdWlyZShcIi4vbGVza1wiKTtcbm1vZHVsZS5leHBvcnRzLm1hZSA9IHJlcXVpcmUoXCIuL21hZVwiKTtcbm1vZHVsZS5leHBvcnRzLnB1cmluZSA9IHJlcXVpcmUoXCIuL3B1cmluZVwiKTtcbm1vZHVsZS5leHBvcnRzLnN0cmFuZCA9IHJlcXVpcmUoXCIuL3N0cmFuZFwiKTtcbm1vZHVsZS5leHBvcnRzLnR1cm4gPSByZXF1aXJlKFwiLi90dXJuXCIpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwiIG9yYW5nZVwiLFxuICBCOiBcIiAjZmZmXCIsXG4gIEM6IFwiIGdyZWVuXCIsXG4gIEQ6IFwiIHJlZFwiLFxuICBFOiBcIiByZWRcIixcbiAgRjogXCIgZ3JlZW5cIixcbiAgRzogXCIgb3JhbmdlXCIsXG4gIEg6IFwiIG1hZ2VudGFcIixcbiAgSTogXCIgZ3JlZW5cIixcbiAgSjogXCIgI2ZmZlwiLFxuICBLOiBcIiByZWRcIixcbiAgTDogXCIgZ3JlZW5cIixcbiAgTTogXCIgZ3JlZW5cIixcbiAgTjogXCIgbWFnZW50YVwiLFxuICBPOiBcIiAjZmZmXCIsXG4gIFA6IFwiIGdyZWVuXCIsXG4gIFE6IFwiIG1hZ2VudGFcIixcbiAgUjogXCIgcmVkXCIsXG4gIFM6IFwiIG9yYW5nZVwiLFxuICBUOiBcIiBvcmFuZ2VcIixcbiAgVTogXCIgI2ZmZlwiLFxuICBWOiBcIiBncmVlblwiLFxuICBXOiBcIiBncmVlblwiLFxuICBYOiBcIiAjZmZmXCIsXG4gIFk6IFwiIGdyZWVuXCIsXG4gIFo6IFwiICNmZmZcIixcbiAgR2FwOiBcIiAjZmZmXCJcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgQTogXCIgIzc3ZGQ4OFwiLFxuICBCOiBcIiAjZmZmXCIsXG4gIEM6IFwiICM5OWVlNjZcIixcbiAgRDogXCIgIzU1YmIzM1wiLFxuICBFOiBcIiAjNTViYjMzXCIsXG4gIEY6IFwiICM5OTk5ZmZcIixcbiAgRzogXCIgIzc3ZGQ4OFwiLFxuICBIOiBcIiAjNTU1NWZmXCIsXG4gIEk6IFwiICM2NmJiZmZcIixcbiAgSjogXCIgI2ZmZlwiLFxuICBLOiBcIiAjZmZjYzc3XCIsXG4gIEw6IFwiICM2NmJiZmZcIixcbiAgTTogXCIgIzY2YmJmZlwiLFxuICBOOiBcIiAjNTViYjMzXCIsXG4gIE86IFwiICNmZmZcIixcbiAgUDogXCIgI2VlYWFhYVwiLFxuICBROiBcIiAjNTViYjMzXCIsXG4gIFI6IFwiICNmZmNjNzdcIixcbiAgUzogXCIgI2ZmNDQ1NVwiLFxuICBUOiBcIiAjZmY0NDU1XCIsXG4gIFU6IFwiICNmZmZcIixcbiAgVjogXCIgIzY2YmJmZlwiLFxuICBXOiBcIiAjOTk5OWZmXCIsXG4gIFg6IFwiICNmZmZcIixcbiAgWTogXCIgIzk5OTlmZlwiLFxuICBaOiBcIiAjZmZmXCIsXG4gIEdhcDogXCIgI2ZmZlwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwiICM2NEY3M0ZcIixcbiAgQzogXCIgI0ZGQjM0MFwiLFxuICBHOiBcIiAjRUI0MTNDXCIsXG4gIFQ6IFwiICMzQzg4RUVcIixcbiAgVTogXCIgIzNDODhFRVwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwiICNGRjgzRkFcIixcbiAgQzogXCIgIzQwRTBEMFwiLFxuICBHOiBcIiAjRkY4M0ZBXCIsXG4gIFI6IFwiICNGRjgzRkFcIixcbiAgVDogXCIgIzQwRTBEMFwiLFxuICBVOiBcIiAjNDBFMEQwXCIsXG4gIFk6IFwiICM0MEUwRDBcIlxufTtcbiIsInZhciBCdXJpZWQgPSByZXF1aXJlKFwiLi9idXJpZWRcIik7XG52YXIgQ2luZW1hID0gcmVxdWlyZShcIi4vY2luZW1hXCIpO1xudmFyIENsdXN0YWwgPSByZXF1aXJlKFwiLi9jbHVzdGFsXCIpO1xudmFyIENsdXN0YWwyID0gcmVxdWlyZShcIi4vY2x1c3RhbDJcIik7XG52YXIgSGVsaXggPSByZXF1aXJlKFwiLi9oZWxpeFwiKTtcbnZhciBIeWRybyA9IHJlcXVpcmUoXCIuL2h5ZHJvcGhvYmljaXR5XCIpO1xudmFyIExlc2sgPSByZXF1aXJlKFwiLi9sZXNrXCIpO1xudmFyIE1hZSA9IHJlcXVpcmUoXCIuL21hZVwiKTtcbnZhciBOdWNsZW90aWRlID0gcmVxdWlyZShcIi4vbnVjbGVvdGlkZVwiKTtcbnZhciBQdXJpbmUgPSByZXF1aXJlKFwiLi9wdXJpbmVcIik7XG52YXIgU3RyYW5kID0gcmVxdWlyZShcIi4vc3RyYW5kXCIpO1xudmFyIFRheWxvciA9IHJlcXVpcmUoXCIuL3RheWxvclwiKTtcbnZhciBUdXJuID0gcmVxdWlyZShcIi4vdHVyblwiKTtcbnZhciBaYXBwbyA9IHJlcXVpcmUoXCIuL3phcHBvXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IENvbG9ycyA9IHtcbiAgbWFwcGluZzoge1xuICAgIGJ1cmllZDogQnVyaWVkLFxuICAgIGJ1cmllZF9pbmRleDogQnVyaWVkLFxuICAgIGNpbmVtYTogQ2luZW1hLFxuICAgIGNsdXN0YWwyOiBDbHVzdGFsMixcbiAgICBjbHVzdGFsOiBDbHVzdGFsLFxuICAgIGhlbGl4OiBIZWxpeCxcbiAgICBoZWxpeF9wcm9wZW5zaXR5OiBIZWxpeCxcbiAgICBoeWRybzogSHlkcm8sXG4gICAgbGVzazogTGVzayxcbiAgICBtYWU6IE1hZSxcbiAgICBudWNsZW90aWRlOiBOdWNsZW90aWRlLFxuICAgIHB1cmluZTogUHVyaW5lLFxuICAgIHB1cmluZV9weXJpbWlkaW5lOiBQdXJpbmUsXG4gICAgc3RyYW5kOiBTdHJhbmQsXG4gICAgc3RyYW5kX3Byb3BlbnNpdHk6IFN0cmFuZCxcbiAgICB0YXlsb3I6IFRheWxvcixcbiAgICB0dXJuOiBUdXJuLFxuICAgIHR1cm5fcHJvcGVuc2l0eTogVHVybixcbiAgICB6YXBwbzogWmFwcG8sXG4gIH0sXG4gIGdldENvbG9yOiBmdW5jdGlvbihzY2hlbWUpIHtcbiAgICB2YXIgY29sb3IgPSBDb2xvcnMubWFwcGluZ1tzY2hlbWVdO1xuICAgIGlmIChjb2xvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb2xvciA9IHt9O1xuICAgIH1cbiAgICByZXR1cm4gY29sb3I7XG4gIH1cbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgQTogXCIjNTg1OGE3XCIsXG4gIFI6IFwiIzZiNmI5NFwiLFxuICBOOiBcIiM2NDY0OWJcIixcbiAgRDogXCIjMjEyMWRlXCIsXG4gIEM6IFwiIzlkOWQ2MlwiLFxuICBROiBcIiM4YzhjNzNcIixcbiAgRTogXCIjMDAwMGZmXCIsXG4gIEc6IFwiIzQ5NDliNlwiLFxuICBIOiBcIiM2MDYwOWZcIixcbiAgSTogXCIjZWNlYzEzXCIsXG4gIEw6IFwiI2IyYjI0ZFwiLFxuICBLOiBcIiM0NzQ3YjhcIixcbiAgTTogXCIjODI4MjdkXCIsXG4gIEY6IFwiI2MyYzIzZFwiLFxuICBQOiBcIiMyMzIzZGNcIixcbiAgUzogXCIjNDk0OWI2XCIsXG4gIFQ6IFwiIzlkOWQ2MlwiLFxuICBXOiBcIiNjMGMwM2ZcIixcbiAgWTogXCIjZDNkMzJjXCIsXG4gIFY6IFwiI2ZmZmYwMFwiLFxuICBCOiBcIiM0MzQzYmNcIixcbiAgWDogXCIjNzk3OTg2XCIsXG4gIFo6IFwiIzQ3NDdiOFwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwiI2NjZmYwMFwiLFxuICBSOiBcIiMwMDAwZmZcIixcbiAgTjogXCIjY2MwMGZmXCIsXG4gIEQ6IFwiI2ZmMDAwMFwiLFxuICBDOiBcIiNmZmZmMDBcIixcbiAgUTogXCIjZmYwMGNjXCIsXG4gIEU6IFwiI2ZmMDA2NlwiLFxuICBHOiBcIiNmZjk5MDBcIixcbiAgSDogXCIjMDA2NmZmXCIsXG4gIEk6IFwiIzY2ZmYwMFwiLFxuICBMOiBcIiMzM2ZmMDBcIixcbiAgSzogXCIjNjYwMGZmXCIsXG4gIE06IFwiIzAwZmYwMFwiLFxuICBGOiBcIiMwMGZmNjZcIixcbiAgUDogXCIjZmZjYzAwXCIsXG4gIFM6IFwiI2ZmMzMwMFwiLFxuICBUOiBcIiNmZjY2MDBcIixcbiAgVzogXCIjMDBjY2ZmXCIsXG4gIFk6IFwiIzAwZmZjY1wiLFxuICBWOiBcIiM5OWZmMDBcIixcbiAgQjogXCIjZmZmXCIsXG4gIFg6IFwiI2ZmZlwiLFxuICBaOiBcIiNmZmZcIlxufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBBOiBcIiMyY2QzZDNcIixcbiAgUjogXCIjNzA4ZjhmXCIsXG4gIE46IFwiI2ZmMDAwMFwiLFxuICBEOiBcIiNlODE3MTdcIixcbiAgQzogXCIjYTg1NzU3XCIsXG4gIFE6IFwiIzNmYzBjMFwiLFxuICBFOiBcIiM3Nzg4ODhcIixcbiAgRzogXCIjZmYwMDAwXCIsXG4gIEg6IFwiIzcwOGY4ZlwiLFxuICBJOiBcIiMwMGZmZmZcIixcbiAgTDogXCIjMWNlM2UzXCIsXG4gIEs6IFwiIzdlODE4MVwiLFxuICBNOiBcIiMxZWUxZTFcIixcbiAgRjogXCIjMWVlMWUxXCIsXG4gIFA6IFwiI2Y2MDkwOVwiLFxuICBTOiBcIiNlMTFlMWVcIixcbiAgVDogXCIjNzM4YzhjXCIsXG4gIFc6IFwiIzczOGM4Y1wiLFxuICBZOiBcIiM5ZDYyNjJcIixcbiAgVjogXCIjMDdmOGY4XCIsXG4gIEI6IFwiI2YzMGMwY1wiLFxuICBYOiBcIiM3YzgzODNcIixcbiAgWjogXCIjNWJhNGE0XCJcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgQTogXCIjZmZhZmFmXCIsXG4gIFI6IFwiIzY0NjRmZlwiLFxuICBOOiBcIiMwMGZmMDBcIixcbiAgRDogXCIjZmYwMDAwXCIsXG4gIEM6IFwiI2ZmZmYwMFwiLFxuICBROiBcIiMwMGZmMDBcIixcbiAgRTogXCIjZmYwMDAwXCIsXG4gIEc6IFwiI2ZmMDBmZlwiLFxuICBIOiBcIiM2NDY0ZmZcIixcbiAgSTogXCIjZmZhZmFmXCIsXG4gIEw6IFwiI2ZmYWZhZlwiLFxuICBLOiBcIiM2NDY0ZmZcIixcbiAgTTogXCIjZmZhZmFmXCIsXG4gIEY6IFwiI2ZmYzgwMFwiLFxuICBQOiBcIiNmZjAwZmZcIixcbiAgUzogXCIjMDBmZjAwXCIsXG4gIFQ6IFwiIzAwZmYwMFwiLFxuICBXOiBcIiNmZmM4MDBcIixcbiAgWTogXCIjZmZjODAwXCIsXG4gIFY6IFwiI2ZmYWZhZlwiLFxuICBCOiBcIiNmZmZcIixcbiAgWDogXCIjZmZmXCIsXG4gIFo6IFwiI2ZmZlwiXG59O1xuIiwiLypcbiAqIEphdmFTY3JpcHQgQ2FudmFzIHRvIEJsb2IgMi4wLjVcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9ibHVlaW1wL0phdmFTY3JpcHQtQ2FudmFzLXRvLUJsb2JcbiAqXG4gKiBDb3B5cmlnaHQgMjAxMiwgU2ViYXN0aWFuIFRzY2hhblxuICogaHR0cHM6Ly9ibHVlaW1wLm5ldFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZTpcbiAqIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXG4gKlxuICogQmFzZWQgb24gc3RhY2tvdmVyZmxvdyB1c2VyIFN0b2l2ZSdzIGNvZGUgc25pcHBldDpcbiAqIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xLzQ5OTg5MDhcbiAqL1xudmFyIENhbnZhc1Byb3RvdHlwZSA9IHdpbmRvdy5IVE1MQ2FudmFzRWxlbWVudCAmJlxud2luZG93LkhUTUxDYW52YXNFbGVtZW50LnByb3RvdHlwZSxcbiAgaGFzQmxvYkNvbnN0cnVjdG9yID0gd2luZG93LkJsb2IgJiYgKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEJvb2xlYW4obmV3IEJsb2IoKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSgpKSxcbiAgaGFzQXJyYXlCdWZmZXJWaWV3U3VwcG9ydCA9IGhhc0Jsb2JDb25zdHJ1Y3RvciAmJiB3aW5kb3cuVWludDhBcnJheSAmJlxuICAoZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbmV3IEJsb2IoW25ldyBVaW50OEFycmF5KDEwMCldKS5zaXplID09PSAxMDA7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSgpKSxcbiAgQmxvYkJ1aWxkZXIgPSB3aW5kb3cuQmxvYkJ1aWxkZXIgfHwgd2luZG93LldlYktpdEJsb2JCdWlsZGVyIHx8XG4gIHdpbmRvdy5Nb3pCbG9iQnVpbGRlciB8fCB3aW5kb3cuTVNCbG9iQnVpbGRlcixcbiAgZGF0YVVSTHRvQmxvYiA9IChoYXNCbG9iQ29uc3RydWN0b3IgfHwgQmxvYkJ1aWxkZXIpICYmIHdpbmRvdy5hdG9iICYmXG4gIHdpbmRvdy5BcnJheUJ1ZmZlciAmJiB3aW5kb3cuVWludDhBcnJheSAmJiBmdW5jdGlvbiAoZGF0YVVSSSkge1xuICAgIHZhciBieXRlU3RyaW5nLFxuICAgIGFycmF5QnVmZmVyLFxuICAgIGludEFycmF5LFxuICAgICAgaSxcbiAgICAgIG1pbWVTdHJpbmcsXG4gICAgICAgIGJiO1xuICAgIGlmIChkYXRhVVJJLnNwbGl0KCcsJylbMF0uaW5kZXhPZignYmFzZTY0JykgPj0gMCkge1xuICAgICAgLy8gQ29udmVydCBiYXNlNjQgdG8gcmF3IGJpbmFyeSBkYXRhIGhlbGQgaW4gYSBzdHJpbmc6XG4gICAgICBieXRlU3RyaW5nID0gYXRvYihkYXRhVVJJLnNwbGl0KCcsJylbMV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDb252ZXJ0IGJhc2U2NC9VUkxFbmNvZGVkIGRhdGEgY29tcG9uZW50IHRvIHJhdyBiaW5hcnkgZGF0YTpcbiAgICAgIGJ5dGVTdHJpbmcgPSBkZWNvZGVVUklDb21wb25lbnQoZGF0YVVSSS5zcGxpdCgnLCcpWzFdKTtcbiAgICB9XG4gICAgLy8gV3JpdGUgdGhlIGJ5dGVzIG9mIHRoZSBzdHJpbmcgdG8gYW4gQXJyYXlCdWZmZXI6XG4gICAgYXJyYXlCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoYnl0ZVN0cmluZy5sZW5ndGgpO1xuICAgIGludEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlCdWZmZXIpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBieXRlU3RyaW5nLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBpbnRBcnJheVtpXSA9IGJ5dGVTdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICB9XG4gICAgLy8gU2VwYXJhdGUgb3V0IHRoZSBtaW1lIGNvbXBvbmVudDpcbiAgICBtaW1lU3RyaW5nID0gZGF0YVVSSS5zcGxpdCgnLCcpWzBdLnNwbGl0KCc6JylbMV0uc3BsaXQoJzsnKVswXTtcbiAgICAvLyBXcml0ZSB0aGUgQXJyYXlCdWZmZXIgKG9yIEFycmF5QnVmZmVyVmlldykgdG8gYSBibG9iOlxuICAgIGlmIChoYXNCbG9iQ29uc3RydWN0b3IpIHtcbiAgICAgIHJldHVybiBuZXcgQmxvYihcbiAgICAgICAgICBbaGFzQXJyYXlCdWZmZXJWaWV3U3VwcG9ydCA/IGludEFycmF5IDogYXJyYXlCdWZmZXJdLFxuICAgICAgICAgIHt0eXBlOiBtaW1lU3RyaW5nfVxuICAgICAgICAgICk7XG4gICAgfVxuICAgIGJiID0gbmV3IEJsb2JCdWlsZGVyKCk7XG4gICAgYmIuYXBwZW5kKGFycmF5QnVmZmVyKTtcbiAgICByZXR1cm4gYmIuZ2V0QmxvYihtaW1lU3RyaW5nKTtcbiAgfTtcbmlmICh3aW5kb3cuSFRNTENhbnZhc0VsZW1lbnQgJiYgIUNhbnZhc1Byb3RvdHlwZS50b0Jsb2IpIHtcbiAgaWYgKENhbnZhc1Byb3RvdHlwZS5tb3pHZXRBc0ZpbGUpIHtcbiAgICBDYW52YXNQcm90b3R5cGUudG9CbG9iID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0eXBlLCBxdWFsaXR5KSB7XG4gICAgICBpZiAocXVhbGl0eSAmJiBDYW52YXNQcm90b3R5cGUudG9EYXRhVVJMICYmIGRhdGFVUkx0b0Jsb2IpIHtcbiAgICAgICAgY2FsbGJhY2soZGF0YVVSTHRvQmxvYih0aGlzLnRvRGF0YVVSTCh0eXBlLCBxdWFsaXR5KSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sodGhpcy5tb3pHZXRBc0ZpbGUoJ2Jsb2InLCB0eXBlKSk7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIGlmIChDYW52YXNQcm90b3R5cGUudG9EYXRhVVJMICYmIGRhdGFVUkx0b0Jsb2IpIHtcbiAgICBDYW52YXNQcm90b3R5cGUudG9CbG9iID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0eXBlLCBxdWFsaXR5KSB7XG4gICAgICBjYWxsYmFjayhkYXRhVVJMdG9CbG9iKHRoaXMudG9EYXRhVVJMKHR5cGUsIHF1YWxpdHkpKSk7XG4gICAgfTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRhdGFVUkx0b0Jsb2I7XG4iLCIvKiBGaWxlU2F2ZXIuanNcbiAqICBBIHNhdmVBcygpIEZpbGVTYXZlciBpbXBsZW1lbnRhdGlvbi5cbiAqICAyMDE0LTA1LTI3XG4gKlxuICogIEJ5IEVsaSBHcmV5LCBodHRwOi8vZWxpZ3JleS5jb21cbiAqICBMaWNlbnNlOiBYMTEvTUlUXG4gKiAgICBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2VsaWdyZXkvRmlsZVNhdmVyLmpzL2Jsb2IvbWFzdGVyL0xJQ0VOU0UubWRcbiAqL1xuXG4vKmdsb2JhbCBzZWxmICovXG4vKmpzbGludCBiaXR3aXNlOiB0cnVlLCBpbmRlbnQ6IDQsIGxheGJyZWFrOiB0cnVlLCBsYXhjb21tYTogdHJ1ZSwgc21hcnR0YWJzOiB0cnVlLCBwbHVzcGx1czogdHJ1ZSAqL1xuXG4vKiEgQHNvdXJjZSBodHRwOi8vcHVybC5lbGlncmV5LmNvbS9naXRodWIvRmlsZVNhdmVyLmpzL2Jsb2IvbWFzdGVyL0ZpbGVTYXZlci5qcyAqL1xuXG52YXIgc2F2ZUFzID0gc2F2ZUFzXG4gIC8vIElFIDEwKyAobmF0aXZlIHNhdmVBcylcbiAgfHwgKHR5cGVvZiBuYXZpZ2F0b3IgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgIG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iICYmIG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iLmJpbmQobmF2aWdhdG9yKSlcbiAgLy8gRXZlcnlvbmUgZWxzZVxuICB8fCAoZnVuY3Rpb24odmlldykge1xuXHRcInVzZSBzdHJpY3RcIjtcblx0Ly8gSUUgPDEwIGlzIGV4cGxpY2l0bHkgdW5zdXBwb3J0ZWRcblx0aWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09IFwidW5kZWZpbmVkXCIgJiZcblx0ICAgIC9NU0lFIFsxLTldXFwuLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdHZhclxuXHRcdCAgZG9jID0gdmlldy5kb2N1bWVudFxuXHRcdCAgLy8gb25seSBnZXQgVVJMIHdoZW4gbmVjZXNzYXJ5IGluIGNhc2UgQmxvYi5qcyBoYXNuJ3Qgb3ZlcnJpZGRlbiBpdCB5ZXRcblx0XHQsIGdldF9VUkwgPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB2aWV3LlVSTCB8fCB2aWV3LndlYmtpdFVSTCB8fCB2aWV3O1xuXHRcdH1cblx0XHQsIHNhdmVfbGluayA9IGRvYy5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCIsIFwiYVwiKVxuXHRcdCwgY2FuX3VzZV9zYXZlX2xpbmsgPSAhdmlldy5leHRlcm5hbEhvc3QgJiYgXCJkb3dubG9hZFwiIGluIHNhdmVfbGlua1xuXHRcdCwgY2xpY2sgPSBmdW5jdGlvbihub2RlKSB7XG5cdFx0XHR2YXIgZXZlbnQgPSBkb2MuY3JlYXRlRXZlbnQoXCJNb3VzZUV2ZW50c1wiKTtcblx0XHRcdGV2ZW50LmluaXRNb3VzZUV2ZW50KFxuXHRcdFx0XHRcImNsaWNrXCIsIHRydWUsIGZhbHNlLCB2aWV3LCAwLCAwLCAwLCAwLCAwXG5cdFx0XHRcdCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIDAsIG51bGxcblx0XHRcdCk7XG5cdFx0XHRub2RlLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuXHRcdH1cblx0XHQsIHdlYmtpdF9yZXFfZnMgPSB2aWV3LndlYmtpdFJlcXVlc3RGaWxlU3lzdGVtXG5cdFx0LCByZXFfZnMgPSB2aWV3LnJlcXVlc3RGaWxlU3lzdGVtIHx8IHdlYmtpdF9yZXFfZnMgfHwgdmlldy5tb3pSZXF1ZXN0RmlsZVN5c3RlbVxuXHRcdCwgdGhyb3dfb3V0c2lkZSA9IGZ1bmN0aW9uKGV4KSB7XG5cdFx0XHQodmlldy5zZXRJbW1lZGlhdGUgfHwgdmlldy5zZXRUaW1lb3V0KShmdW5jdGlvbigpIHtcblx0XHRcdFx0dGhyb3cgZXg7XG5cdFx0XHR9LCAwKTtcblx0XHR9XG5cdFx0LCBmb3JjZV9zYXZlYWJsZV90eXBlID0gXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1cIlxuXHRcdCwgZnNfbWluX3NpemUgPSAwXG5cdFx0LCBkZWxldGlvbl9xdWV1ZSA9IFtdXG5cdFx0LCBwcm9jZXNzX2RlbGV0aW9uX3F1ZXVlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgaSA9IGRlbGV0aW9uX3F1ZXVlLmxlbmd0aDtcblx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0dmFyIGZpbGUgPSBkZWxldGlvbl9xdWV1ZVtpXTtcblx0XHRcdFx0aWYgKHR5cGVvZiBmaWxlID09PSBcInN0cmluZ1wiKSB7IC8vIGZpbGUgaXMgYW4gb2JqZWN0IFVSTFxuXHRcdFx0XHRcdGdldF9VUkwoKS5yZXZva2VPYmplY3RVUkwoZmlsZSk7XG5cdFx0XHRcdH0gZWxzZSB7IC8vIGZpbGUgaXMgYSBGaWxlXG5cdFx0XHRcdFx0ZmlsZS5yZW1vdmUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0ZGVsZXRpb25fcXVldWUubGVuZ3RoID0gMDsgLy8gY2xlYXIgcXVldWVcblx0XHR9XG5cdFx0LCBkaXNwYXRjaCA9IGZ1bmN0aW9uKGZpbGVzYXZlciwgZXZlbnRfdHlwZXMsIGV2ZW50KSB7XG5cdFx0XHRldmVudF90eXBlcyA9IFtdLmNvbmNhdChldmVudF90eXBlcyk7XG5cdFx0XHR2YXIgaSA9IGV2ZW50X3R5cGVzLmxlbmd0aDtcblx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0dmFyIGxpc3RlbmVyID0gZmlsZXNhdmVyW1wib25cIiArIGV2ZW50X3R5cGVzW2ldXTtcblx0XHRcdFx0aWYgKHR5cGVvZiBsaXN0ZW5lciA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdGxpc3RlbmVyLmNhbGwoZmlsZXNhdmVyLCBldmVudCB8fCBmaWxlc2F2ZXIpO1xuXHRcdFx0XHRcdH0gY2F0Y2ggKGV4KSB7XG5cdFx0XHRcdFx0XHR0aHJvd19vdXRzaWRlKGV4KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0LCBGaWxlU2F2ZXIgPSBmdW5jdGlvbihibG9iLCBuYW1lKSB7XG5cdFx0XHQvLyBGaXJzdCB0cnkgYS5kb3dubG9hZCwgdGhlbiB3ZWIgZmlsZXN5c3RlbSwgdGhlbiBvYmplY3QgVVJMc1xuXHRcdFx0dmFyXG5cdFx0XHRcdCAgZmlsZXNhdmVyID0gdGhpc1xuXHRcdFx0XHQsIHR5cGUgPSBibG9iLnR5cGVcblx0XHRcdFx0LCBibG9iX2NoYW5nZWQgPSBmYWxzZVxuXHRcdFx0XHQsIG9iamVjdF91cmxcblx0XHRcdFx0LCB0YXJnZXRfdmlld1xuXHRcdFx0XHQsIGdldF9vYmplY3RfdXJsID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0dmFyIG9iamVjdF91cmwgPSBnZXRfVVJMKCkuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuXHRcdFx0XHRcdGRlbGV0aW9uX3F1ZXVlLnB1c2gob2JqZWN0X3VybCk7XG5cdFx0XHRcdFx0cmV0dXJuIG9iamVjdF91cmw7XG5cdFx0XHRcdH1cblx0XHRcdFx0LCBkaXNwYXRjaF9hbGwgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRkaXNwYXRjaChmaWxlc2F2ZXIsIFwid3JpdGVzdGFydCBwcm9ncmVzcyB3cml0ZSB3cml0ZWVuZFwiLnNwbGl0KFwiIFwiKSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly8gb24gYW55IGZpbGVzeXMgZXJyb3JzIHJldmVydCB0byBzYXZpbmcgd2l0aCBvYmplY3QgVVJMc1xuXHRcdFx0XHQsIGZzX2Vycm9yID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0Ly8gZG9uJ3QgY3JlYXRlIG1vcmUgb2JqZWN0IFVSTHMgdGhhbiBuZWVkZWRcblx0XHRcdFx0XHRpZiAoYmxvYl9jaGFuZ2VkIHx8ICFvYmplY3RfdXJsKSB7XG5cdFx0XHRcdFx0XHRvYmplY3RfdXJsID0gZ2V0X29iamVjdF91cmwoYmxvYik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICh0YXJnZXRfdmlldykge1xuXHRcdFx0XHRcdFx0dGFyZ2V0X3ZpZXcubG9jYXRpb24uaHJlZiA9IG9iamVjdF91cmw7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHdpbmRvdy5vcGVuKG9iamVjdF91cmwsIFwiX2JsYW5rXCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FO1xuXHRcdFx0XHRcdGRpc3BhdGNoX2FsbCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCwgYWJvcnRhYmxlID0gZnVuY3Rpb24oZnVuYykge1xuXHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdGlmIChmaWxlc2F2ZXIucmVhZHlTdGF0ZSAhPT0gZmlsZXNhdmVyLkRPTkUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdCwgY3JlYXRlX2lmX25vdF9mb3VuZCA9IHtjcmVhdGU6IHRydWUsIGV4Y2x1c2l2ZTogZmFsc2V9XG5cdFx0XHRcdCwgc2xpY2Vcblx0XHRcdDtcblx0XHRcdGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLklOSVQ7XG5cdFx0XHRpZiAoIW5hbWUpIHtcblx0XHRcdFx0bmFtZSA9IFwiZG93bmxvYWRcIjtcblx0XHRcdH1cblx0XHRcdGlmIChjYW5fdXNlX3NhdmVfbGluaykge1xuXHRcdFx0XHRvYmplY3RfdXJsID0gZ2V0X29iamVjdF91cmwoYmxvYik7XG5cdFx0XHRcdHNhdmVfbGluay5ocmVmID0gb2JqZWN0X3VybDtcblx0XHRcdFx0c2F2ZV9saW5rLmRvd25sb2FkID0gbmFtZTtcblx0XHRcdFx0Y2xpY2soc2F2ZV9saW5rKTtcblx0XHRcdFx0ZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTtcblx0XHRcdFx0ZGlzcGF0Y2hfYWxsKCk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdC8vIE9iamVjdCBhbmQgd2ViIGZpbGVzeXN0ZW0gVVJMcyBoYXZlIGEgcHJvYmxlbSBzYXZpbmcgaW4gR29vZ2xlIENocm9tZSB3aGVuXG5cdFx0XHQvLyB2aWV3ZWQgaW4gYSB0YWIsIHNvIEkgZm9yY2Ugc2F2ZSB3aXRoIGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVxuXHRcdFx0Ly8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9OTExNThcblx0XHRcdGlmICh2aWV3LmNocm9tZSAmJiB0eXBlICYmIHR5cGUgIT09IGZvcmNlX3NhdmVhYmxlX3R5cGUpIHtcblx0XHRcdFx0c2xpY2UgPSBibG9iLnNsaWNlIHx8IGJsb2Iud2Via2l0U2xpY2U7XG5cdFx0XHRcdGJsb2IgPSBzbGljZS5jYWxsKGJsb2IsIDAsIGJsb2Iuc2l6ZSwgZm9yY2Vfc2F2ZWFibGVfdHlwZSk7XG5cdFx0XHRcdGJsb2JfY2hhbmdlZCA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHQvLyBTaW5jZSBJIGNhbid0IGJlIHN1cmUgdGhhdCB0aGUgZ3Vlc3NlZCBtZWRpYSB0eXBlIHdpbGwgdHJpZ2dlciBhIGRvd25sb2FkXG5cdFx0XHQvLyBpbiBXZWJLaXQsIEkgYXBwZW5kIC5kb3dubG9hZCB0byB0aGUgZmlsZW5hbWUuXG5cdFx0XHQvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NjU0NDBcblx0XHRcdGlmICh3ZWJraXRfcmVxX2ZzICYmIG5hbWUgIT09IFwiZG93bmxvYWRcIikge1xuXHRcdFx0XHRuYW1lICs9IFwiLmRvd25sb2FkXCI7XG5cdFx0XHR9XG5cdFx0XHRpZiAodHlwZSA9PT0gZm9yY2Vfc2F2ZWFibGVfdHlwZSB8fCB3ZWJraXRfcmVxX2ZzKSB7XG5cdFx0XHRcdHRhcmdldF92aWV3ID0gdmlldztcblx0XHRcdH1cblx0XHRcdGlmICghcmVxX2ZzKSB7XG5cdFx0XHRcdGZzX2Vycm9yKCk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGZzX21pbl9zaXplICs9IGJsb2Iuc2l6ZTtcblx0XHRcdHJlcV9mcyh2aWV3LlRFTVBPUkFSWSwgZnNfbWluX3NpemUsIGFib3J0YWJsZShmdW5jdGlvbihmcykge1xuXHRcdFx0XHRmcy5yb290LmdldERpcmVjdG9yeShcInNhdmVkXCIsIGNyZWF0ZV9pZl9ub3RfZm91bmQsIGFib3J0YWJsZShmdW5jdGlvbihkaXIpIHtcblx0XHRcdFx0XHR2YXIgc2F2ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0ZGlyLmdldEZpbGUobmFtZSwgY3JlYXRlX2lmX25vdF9mb3VuZCwgYWJvcnRhYmxlKGZ1bmN0aW9uKGZpbGUpIHtcblx0XHRcdFx0XHRcdFx0ZmlsZS5jcmVhdGVXcml0ZXIoYWJvcnRhYmxlKGZ1bmN0aW9uKHdyaXRlcikge1xuXHRcdFx0XHRcdFx0XHRcdHdyaXRlci5vbndyaXRlZW5kID0gZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHRhcmdldF92aWV3LmxvY2F0aW9uLmhyZWYgPSBmaWxlLnRvVVJMKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRkZWxldGlvbl9xdWV1ZS5wdXNoKGZpbGUpO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTtcblx0XHRcdFx0XHRcdFx0XHRcdGRpc3BhdGNoKGZpbGVzYXZlciwgXCJ3cml0ZWVuZFwiLCBldmVudCk7XG5cdFx0XHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdFx0XHR3cml0ZXIub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dmFyIGVycm9yID0gd3JpdGVyLmVycm9yO1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKGVycm9yLmNvZGUgIT09IGVycm9yLkFCT1JUX0VSUikge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRmc19lcnJvcigpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0XHRcdFx0XCJ3cml0ZXN0YXJ0IHByb2dyZXNzIHdyaXRlIGFib3J0XCIuc3BsaXQoXCIgXCIpLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHdyaXRlcltcIm9uXCIgKyBldmVudF0gPSBmaWxlc2F2ZXJbXCJvblwiICsgZXZlbnRdO1xuXHRcdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHRcdHdyaXRlci53cml0ZShibG9iKTtcblx0XHRcdFx0XHRcdFx0XHRmaWxlc2F2ZXIuYWJvcnQgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHdyaXRlci5hYm9ydCgpO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTtcblx0XHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0XHRcdGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLldSSVRJTkc7XG5cdFx0XHRcdFx0XHRcdH0pLCBmc19lcnJvcik7XG5cdFx0XHRcdFx0XHR9KSwgZnNfZXJyb3IpO1xuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0ZGlyLmdldEZpbGUobmFtZSwge2NyZWF0ZTogZmFsc2V9LCBhYm9ydGFibGUoZnVuY3Rpb24oZmlsZSkge1xuXHRcdFx0XHRcdFx0Ly8gZGVsZXRlIGZpbGUgaWYgaXQgYWxyZWFkeSBleGlzdHNcblx0XHRcdFx0XHRcdGZpbGUucmVtb3ZlKCk7XG5cdFx0XHRcdFx0XHRzYXZlKCk7XG5cdFx0XHRcdFx0fSksIGFib3J0YWJsZShmdW5jdGlvbihleCkge1xuXHRcdFx0XHRcdFx0aWYgKGV4LmNvZGUgPT09IGV4Lk5PVF9GT1VORF9FUlIpIHtcblx0XHRcdFx0XHRcdFx0c2F2ZSgpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0ZnNfZXJyb3IoKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSk7XG5cdFx0XHRcdH0pLCBmc19lcnJvcik7XG5cdFx0XHR9KSwgZnNfZXJyb3IpO1xuXHRcdH1cblx0XHQsIEZTX3Byb3RvID0gRmlsZVNhdmVyLnByb3RvdHlwZVxuXHRcdCwgc2F2ZUFzID0gZnVuY3Rpb24oYmxvYiwgbmFtZSkge1xuXHRcdFx0cmV0dXJuIG5ldyBGaWxlU2F2ZXIoYmxvYiwgbmFtZSk7XG5cdFx0fVxuXHQ7XG5cdEZTX3Byb3RvLmFib3J0ID0gZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGZpbGVzYXZlciA9IHRoaXM7XG5cdFx0ZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTtcblx0XHRkaXNwYXRjaChmaWxlc2F2ZXIsIFwiYWJvcnRcIik7XG5cdH07XG5cdEZTX3Byb3RvLnJlYWR5U3RhdGUgPSBGU19wcm90by5JTklUID0gMDtcblx0RlNfcHJvdG8uV1JJVElORyA9IDE7XG5cdEZTX3Byb3RvLkRPTkUgPSAyO1xuXG5cdEZTX3Byb3RvLmVycm9yID1cblx0RlNfcHJvdG8ub253cml0ZXN0YXJ0ID1cblx0RlNfcHJvdG8ub25wcm9ncmVzcyA9XG5cdEZTX3Byb3RvLm9ud3JpdGUgPVxuXHRGU19wcm90by5vbmFib3J0ID1cblx0RlNfcHJvdG8ub25lcnJvciA9XG5cdEZTX3Byb3RvLm9ud3JpdGVlbmQgPVxuXHRcdG51bGw7XG5cblx0dmlldy5hZGRFdmVudExpc3RlbmVyKFwidW5sb2FkXCIsIHByb2Nlc3NfZGVsZXRpb25fcXVldWUsIGZhbHNlKTtcblx0c2F2ZUFzLnVubG9hZCA9IGZ1bmN0aW9uKCkge1xuXHRcdHByb2Nlc3NfZGVsZXRpb25fcXVldWUoKTtcblx0XHR2aWV3LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ1bmxvYWRcIiwgcHJvY2Vzc19kZWxldGlvbl9xdWV1ZSwgZmFsc2UpO1xuXHR9O1xuXHRyZXR1cm4gc2F2ZUFzO1xufShcblx0ICAgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgJiYgc2VsZlxuXHR8fCB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvd1xuXHR8fCB0aGlzLmNvbnRlbnRcbikpO1xuLy8gYHNlbGZgIGlzIHVuZGVmaW5lZCBpbiBGaXJlZm94IGZvciBBbmRyb2lkIGNvbnRlbnQgc2NyaXB0IGNvbnRleHRcbi8vIHdoaWxlIGB0aGlzYCBpcyBuc0lDb250ZW50RnJhbWVNZXNzYWdlTWFuYWdlclxuLy8gd2l0aCBhbiBhdHRyaWJ1dGUgYGNvbnRlbnRgIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHdpbmRvd1xuXG5hbWREZWZpbmUgPSB3aW5kb3cuZGVmaW5lO1xuaWYoIHR5cGVvZiBhbWREZWZpbmUgPT09IFwidW5kZWZpbmVkXCIgJiYgKHR5cGVvZiB3aW5kb3cuYWxtb25kICE9PSBcInVuZGVmaW5lZFwiIFxuICAgICYmIFwiZGVmaW5lXCIgaW4gd2luZG93LmFsbW9uZCApKXtcbiAgYW1kRGVmaW5lID0gd2luZG93LmFsbW9uZC5kZWZpbmU7XG59XG5cbmlmICh0eXBlb2YgbW9kdWxlICE9PSBcInVuZGVmaW5lZFwiICYmIG1vZHVsZSAhPT0gbnVsbCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IHNhdmVBcztcbn0gZWxzZSBpZiAoKHR5cGVvZiBhbWREZWZpbmUgIT09IFwidW5kZWZpbmVkXCIgJiYgYW1kRGVmaW5lICE9PSBudWxsKSAmJiAoYW1kRGVmaW5lLmFtZCAhPSBudWxsKSkge1xuICBhbWREZWZpbmUoXCJzYXZlQXNcIixbXSwgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNhdmVBcztcbiAgfSk7XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjc3MsIGN1c3RvbURvY3VtZW50KSB7XG4gIHZhciBkb2MgPSBjdXN0b21Eb2N1bWVudCB8fCBkb2N1bWVudDtcbiAgaWYgKGRvYy5jcmVhdGVTdHlsZVNoZWV0KSB7XG4gICAgdmFyIHNoZWV0ID0gZG9jLmNyZWF0ZVN0eWxlU2hlZXQoKVxuICAgIHNoZWV0LmNzc1RleHQgPSBjc3M7XG4gICAgcmV0dXJuIHNoZWV0Lm93bmVyTm9kZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaGVhZCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdLFxuICAgICAgICBzdHlsZSA9IGRvYy5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuXG4gICAgc3R5bGUudHlwZSA9ICd0ZXh0L2Nzcyc7XG5cbiAgICBpZiAoc3R5bGUuc3R5bGVTaGVldCkge1xuICAgICAgc3R5bGUuc3R5bGVTaGVldC5jc3NUZXh0ID0gY3NzO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHlsZS5hcHBlbmRDaGlsZChkb2MuY3JlYXRlVGV4dE5vZGUoY3NzKSk7XG4gICAgfVxuXG4gICAgaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG4gICAgcmV0dXJuIHN0eWxlO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5ieVVybCA9IGZ1bmN0aW9uKHVybCkge1xuICBpZiAoZG9jdW1lbnQuY3JlYXRlU3R5bGVTaGVldCkge1xuICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVTdHlsZVNoZWV0KHVybCkub3duZXJOb2RlO1xuICB9IGVsc2Uge1xuICAgIHZhciBoZWFkID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXSxcbiAgICAgICAgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpbmsnKTtcblxuICAgIGxpbmsucmVsID0gJ3N0eWxlc2hlZXQnO1xuICAgIGxpbmsuaHJlZiA9IHVybDtcblxuICAgIGhlYWQuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgcmV0dXJuIGxpbms7XG4gIH1cbn07XG4iLCJ2YXIgVXRpbHMgPSB7fTtcblxuXG4vKlxuUmVtb3ZlIGFuIGVsZW1lbnQgYW5kIHByb3ZpZGUgYSBmdW5jdGlvbiB0aGF0IGluc2VydHMgaXQgaW50byBpdHMgb3JpZ2luYWwgcG9zaXRpb25cbmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3NwZWVkL2FydGljbGVzL2phdmFzY3JpcHQtZG9tXG5AcGFyYW0gZWxlbWVudCB7RWxlbWVudH0gVGhlIGVsZW1lbnQgdG8gYmUgdGVtcG9yYXJpbHkgcmVtb3ZlZFxuQHJldHVybiB7RnVuY3Rpb259IEEgZnVuY3Rpb24gdGhhdCBpbnNlcnRzIHRoZSBlbGVtZW50IGludG8gaXRzIG9yaWdpbmFsIHBvc2l0aW9uXG4gKi9cblxuVXRpbHMucmVtb3ZlVG9JbnNlcnRMYXRlciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgdmFyIG5leHRTaWJsaW5nLCBwYXJlbnROb2RlO1xuICBwYXJlbnROb2RlID0gZWxlbWVudC5wYXJlbnROb2RlO1xuICBuZXh0U2libGluZyA9IGVsZW1lbnQubmV4dFNpYmxpbmc7XG4gIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWxlbWVudCk7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBpZiAobmV4dFNpYmxpbmcpIHtcbiAgICAgIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnQsIG5leHRTaWJsaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICB9XG4gIH07XG59O1xuXG5cbi8qXG5mYXN0ZXN0IHBvc3NpYmxlIHdheSB0byBkZXN0cm95IGFsbCBzdWIgbm9kZXMgKGFrYSBjaGlsZHMpXG5odHRwOi8vanNwZXJmLmNvbS9pbm5lcmh0bWwtdnMtcmVtb3ZlY2hpbGQvMTVcbkBwYXJhbSBlbGVtZW50IHtFbGVtZW50fSBUaGUgZWxlbWVudCBmb3Igd2hpY2ggYWxsIGNoaWxkcyBzaG91bGQgYmUgcmVtb3ZlZFxuICovXG5cblV0aWxzLnJlbW92ZUFsbENoaWxkcyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgdmFyIGNvdW50O1xuICBjb3VudCA9IDA7XG4gIHdoaWxlIChlbGVtZW50LmZpcnN0Q2hpbGQpIHtcbiAgICBjb3VudCsrO1xuICAgIGVsZW1lbnQucmVtb3ZlQ2hpbGQoZWxlbWVudC5maXJzdENoaWxkKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBVdGlscztcbiIsIi8qIVxuICogakJvbmUgdjEuMC4xOSAtIDIwMTQtMTAtMTIgLSBMaWJyYXJ5IGZvciBET00gbWFuaXB1bGF0aW9uXG4gKlxuICogaHR0cHM6Ly9naXRodWIuY29tL2t1cHJpeWFuZW5rby9qYm9uZVxuICpcbiAqIENvcHlyaWdodCAyMDE0IEFsZXhleSBLdXByaXlhbmVua29cbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbiAqL1xuXG4oZnVuY3Rpb24gKHdpbikge1xuXG52YXJcbi8vIGNhY2hlIHByZXZpb3VzIHZlcnNpb25zXG5fJCA9IHdpbi4kLFxuX2pCb25lID0gd2luLmpCb25lLFxuXG4vLyBRdWljayBtYXRjaCBhIHN0YW5kYWxvbmUgdGFnXG5ycXVpY2tTaW5nbGVUYWcgPSAvXjwoXFx3KylcXHMqXFwvPz4kLyxcblxuLy8gQSBzaW1wbGUgd2F5IHRvIGNoZWNrIGZvciBIVE1MIHN0cmluZ3Ncbi8vIFByaW9yaXRpemUgI2lkIG92ZXIgPHRhZz4gdG8gYXZvaWQgWFNTIHZpYSBsb2NhdGlvbi5oYXNoXG5ycXVpY2tFeHByID0gL14oPzpbXiM8XSooPFtcXHdcXFddKz4pW14+XSokfCMoW1xcd1xcLV0qKSQpLyxcblxuLy8gQWxpYXMgZm9yIGZ1bmN0aW9uXG5zbGljZSA9IFtdLnNsaWNlLFxuc3BsaWNlID0gW10uc3BsaWNlLFxua2V5cyA9IE9iamVjdC5rZXlzLFxuXG4vLyBBbGlhcyBmb3IgZ2xvYmFsIHZhcmlhYmxlc1xuZG9jID0gZG9jdW1lbnQsXG5cbmlzU3RyaW5nID0gZnVuY3Rpb24oZWwpIHtcbiAgICByZXR1cm4gdHlwZW9mIGVsID09PSBcInN0cmluZ1wiO1xufSxcbmlzT2JqZWN0ID0gZnVuY3Rpb24oZWwpIHtcbiAgICByZXR1cm4gZWwgaW5zdGFuY2VvZiBPYmplY3Q7XG59LFxuaXNGdW5jdGlvbiA9IGZ1bmN0aW9uKGVsKSB7XG4gICAgdmFyIGdldFR5cGUgPSB7fTtcbiAgICByZXR1cm4gZWwgJiYgZ2V0VHlwZS50b1N0cmluZy5jYWxsKGVsKSA9PT0gXCJbb2JqZWN0IEZ1bmN0aW9uXVwiO1xufSxcbmlzQXJyYXkgPSBmdW5jdGlvbihlbCkge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KGVsKTtcbn0sXG5qQm9uZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIGRhdGEpIHtcbiAgICByZXR1cm4gbmV3IGZuLmluaXQoZWxlbWVudCwgZGF0YSk7XG59LFxuZm47XG5cbi8vIHNldCBwcmV2aW91cyB2YWx1ZXMgYW5kIHJldHVybiB0aGUgaW5zdGFuY2UgdXBvbiBjYWxsaW5nIHRoZSBuby1jb25mbGljdCBtb2RlXG5qQm9uZS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oKSB7XG4gICAgd2luLiQgPSBfJDtcbiAgICB3aW4uakJvbmUgPSBfakJvbmU7XG5cbiAgICByZXR1cm4gakJvbmU7XG59O1xuXG5mbiA9IGpCb25lLmZuID0gakJvbmUucHJvdG90eXBlID0ge1xuICAgIGluaXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGRhdGEpIHtcbiAgICAgICAgdmFyIGVsZW1lbnRzLCB0YWcsIHdyYXBlciwgZnJhZ21lbnQ7XG5cbiAgICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNTdHJpbmcoZWxlbWVudCkpIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSBzaW5nbGUgRE9NIGVsZW1lbnRcbiAgICAgICAgICAgIGlmICh0YWcgPSBycXVpY2tTaW5nbGVUYWcuZXhlYyhlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHRoaXNbMF0gPSBkb2MuY3JlYXRlRWxlbWVudCh0YWdbMV0pO1xuICAgICAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gMTtcblxuICAgICAgICAgICAgICAgIGlmIChpc09iamVjdChkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmF0dHIoZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBDcmVhdGUgRE9NIGNvbGxlY3Rpb25cbiAgICAgICAgICAgIGlmICgodGFnID0gcnF1aWNrRXhwci5leGVjKGVsZW1lbnQpKSAmJiB0YWdbMV0pIHtcbiAgICAgICAgICAgICAgICBmcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgICAgICAgICAgICAgd3JhcGVyID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgICAgICAgICAgd3JhcGVyLmlubmVySFRNTCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHdyYXBlci5sYXN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQod3JhcGVyLmZpcnN0Q2hpbGQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbGVtZW50cyA9IHNsaWNlLmNhbGwoZnJhZ21lbnQuY2hpbGROb2Rlcyk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gakJvbmUubWVyZ2UodGhpcywgZWxlbWVudHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRmluZCBET00gZWxlbWVudHMgd2l0aCBxdWVyeVNlbGVjdG9yQWxsXG4gICAgICAgICAgICBpZiAoakJvbmUuaXNFbGVtZW50KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGpCb25lKGRhdGEpLmZpbmQoZWxlbWVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMgPSBkb2MucXVlcnlTZWxlY3RvckFsbChlbGVtZW50KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBqQm9uZS5tZXJnZSh0aGlzLCBlbGVtZW50cyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gV3JhcCBET01FbGVtZW50XG4gICAgICAgIGlmIChlbGVtZW50Lm5vZGVUeXBlKSB7XG4gICAgICAgICAgICB0aGlzWzBdID0gZWxlbWVudDtcbiAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gMTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUnVuIGZ1bmN0aW9uXG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudCgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJldHVybiBqQm9uZSBlbGVtZW50IGFzIGlzXG4gICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgakJvbmUpIHtcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmV0dXJuIGVsZW1lbnQgd3JhcHBlZCBieSBqQm9uZVxuICAgICAgICByZXR1cm4gakJvbmUubWFrZUFycmF5KGVsZW1lbnQsIHRoaXMpO1xuICAgIH0sXG5cbiAgICBwb3A6IFtdLnBvcCxcbiAgICBwdXNoOiBbXS5wdXNoLFxuICAgIHJldmVyc2U6IFtdLnJldmVyc2UsXG4gICAgc2hpZnQ6IFtdLnNoaWZ0LFxuICAgIHNvcnQ6IFtdLnNvcnQsXG4gICAgc3BsaWNlOiBbXS5zcGxpY2UsXG4gICAgc2xpY2U6IFtdLnNsaWNlLFxuICAgIGluZGV4T2Y6IFtdLmluZGV4T2YsXG4gICAgZm9yRWFjaDogW10uZm9yRWFjaCxcbiAgICB1bnNoaWZ0OiBbXS51bnNoaWZ0LFxuICAgIGNvbmNhdDogW10uY29uY2F0LFxuICAgIGpvaW46IFtdLmpvaW4sXG4gICAgZXZlcnk6IFtdLmV2ZXJ5LFxuICAgIHNvbWU6IFtdLnNvbWUsXG4gICAgZmlsdGVyOiBbXS5maWx0ZXIsXG4gICAgbWFwOiBbXS5tYXAsXG4gICAgcmVkdWNlOiBbXS5yZWR1Y2UsXG4gICAgcmVkdWNlUmlnaHQ6IFtdLnJlZHVjZVJpZ2h0LFxuICAgIGxlbmd0aDogMFxufTtcblxuZm4uY29uc3RydWN0b3IgPSBqQm9uZTtcblxuZm4uaW5pdC5wcm90b3R5cGUgPSBmbjtcblxuakJvbmUuc2V0SWQgPSBmdW5jdGlvbihlbCkge1xuICAgIHZhciBqaWQgPSBlbC5qaWQ7XG5cbiAgICBpZiAoZWwgPT09IHdpbikge1xuICAgICAgICBqaWQgPSBcIndpbmRvd1wiO1xuICAgIH0gZWxzZSBpZiAoZWwuamlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZWwuamlkID0gamlkID0gKytqQm9uZS5fY2FjaGUuamlkO1xuICAgIH1cblxuICAgIGlmICghakJvbmUuX2NhY2hlLmV2ZW50c1tqaWRdKSB7XG4gICAgICAgIGpCb25lLl9jYWNoZS5ldmVudHNbamlkXSA9IHt9O1xuICAgIH1cbn07XG5cbmpCb25lLmdldERhdGEgPSBmdW5jdGlvbihlbCkge1xuICAgIGVsID0gZWwgaW5zdGFuY2VvZiBqQm9uZSA/IGVsWzBdIDogZWw7XG5cbiAgICB2YXIgamlkID0gZWwgPT09IHdpbiA/IFwid2luZG93XCIgOiBlbC5qaWQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBqaWQ6IGppZCxcbiAgICAgICAgZXZlbnRzOiBqQm9uZS5fY2FjaGUuZXZlbnRzW2ppZF1cbiAgICB9O1xufTtcblxuakJvbmUuaXNFbGVtZW50ID0gZnVuY3Rpb24oZWwpIHtcbiAgICByZXR1cm4gZWwgJiYgZWwgaW5zdGFuY2VvZiBqQm9uZSB8fCBlbCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8IGlzU3RyaW5nKGVsKTtcbn07XG5cbmpCb25lLl9jYWNoZSA9IHtcbiAgICBldmVudHM6IHt9LFxuICAgIGppZDogMFxufTtcblxuZnVuY3Rpb24gaXNBcnJheWxpa2Uob2JqKSB7XG4gICAgdmFyIGxlbmd0aCA9IG9iai5sZW5ndGgsXG4gICAgICAgIHR5cGUgPSB0eXBlb2Ygb2JqO1xuXG4gICAgaWYgKGlzRnVuY3Rpb24odHlwZSkgfHwgb2JqID09PSB3aW4pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChvYmoubm9kZVR5cGUgPT09IDEgJiYgbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBpc0FycmF5KHR5cGUpIHx8IGxlbmd0aCA9PT0gMCB8fFxuICAgICAgICB0eXBlb2YgbGVuZ3RoID09PSBcIm51bWJlclwiICYmIGxlbmd0aCA+IDAgJiYgKGxlbmd0aCAtIDEpIGluIG9iajtcbn1cblxuakJvbmUubWVyZ2UgPSBmdW5jdGlvbihmaXJzdCwgc2Vjb25kKSB7XG4gICAgdmFyIGwgPSBzZWNvbmQubGVuZ3RoLFxuICAgICAgICBpID0gZmlyc3QubGVuZ3RoLFxuICAgICAgICBqID0gMDtcblxuICAgIHdoaWxlIChqIDwgbCkge1xuICAgICAgICBmaXJzdFtpKytdID0gc2Vjb25kW2orK107XG4gICAgfVxuXG4gICAgZmlyc3QubGVuZ3RoID0gaTtcblxuICAgIHJldHVybiBmaXJzdDtcbn07XG5cbmpCb25lLmNvbnRhaW5zID0gZnVuY3Rpb24oY29udGFpbmVyLCBjb250YWluZWQpIHtcbiAgICB2YXIgcmVzdWx0O1xuXG4gICAgY29udGFpbmVyLnJldmVyc2UoKS5zb21lKGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgIGlmIChlbC5jb250YWlucyhjb250YWluZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0ID0gZWw7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG5qQm9uZS5leHRlbmQgPSBmdW5jdGlvbih0YXJnZXQpIHtcbiAgICB2YXIgaywga2wsIGksIHRnO1xuXG4gICAgc3BsaWNlLmNhbGwoYXJndW1lbnRzLCAxKS5mb3JFYWNoKGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgayA9IGtleXMob2JqZWN0KTtcbiAgICAgICAga2wgPSBrLmxlbmd0aDtcbiAgICAgICAgaSA9IDA7XG4gICAgICAgIHRnID0gdGFyZ2V0OyAvL2NhY2hpbmcgdGFyZ2V0IGZvciBwZXJmIGltcHJvdmVtZW50XG5cbiAgICAgICAgZm9yICg7IGkgPCBrbDsgaSsrKSB7XG4gICAgICAgICAgICB0Z1trW2ldXSA9IG9iamVjdFtrW2ldXTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRhcmdldDtcbn07XG5cbmpCb25lLm1ha2VBcnJheSA9IGZ1bmN0aW9uKGFyciwgcmVzdWx0cykge1xuICAgIHZhciByZXQgPSByZXN1bHRzIHx8IFtdO1xuXG4gICAgaWYgKGFyciAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoaXNBcnJheWxpa2UoYXJyKSkge1xuICAgICAgICAgICAgakJvbmUubWVyZ2UocmV0LCBpc1N0cmluZyhhcnIpID8gW2Fycl0gOiBhcnIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0LnB1c2goYXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBCb25lRXZlbnQoZSwgZGF0YSkge1xuICAgIHZhciBrZXksIHNldHRlcjtcblxuICAgIHRoaXMub3JpZ2luYWxFdmVudCA9IGU7XG5cbiAgICBzZXR0ZXIgPSBmdW5jdGlvbihrZXksIGUpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gXCJwcmV2ZW50RGVmYXVsdFwiKSB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBlW2tleV0oKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihlW2tleV0pKSB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZVtrZXldKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpc1trZXldID0gZVtrZXldO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGZvciAoa2V5IGluIGUpIHtcbiAgICAgICAgaWYgKGVba2V5XSB8fCB0eXBlb2YgZVtrZXldID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHNldHRlci5jYWxsKHRoaXMsIGtleSwgZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBqQm9uZS5leHRlbmQodGhpcywgZGF0YSk7XG59XG5cbmpCb25lLkV2ZW50ID0gZnVuY3Rpb24oZXZlbnQsIGRhdGEpIHtcbiAgICB2YXIgbmFtZXNwYWNlLCBldmVudFR5cGU7XG5cbiAgICBpZiAoZXZlbnQudHlwZSAmJiAhZGF0YSkge1xuICAgICAgICBkYXRhID0gZXZlbnQ7XG4gICAgICAgIGV2ZW50ID0gZXZlbnQudHlwZTtcbiAgICB9XG5cbiAgICBuYW1lc3BhY2UgPSBldmVudC5zcGxpdChcIi5cIikuc3BsaWNlKDEpLmpvaW4oXCIuXCIpO1xuICAgIGV2ZW50VHlwZSA9IGV2ZW50LnNwbGl0KFwiLlwiKVswXTtcblxuICAgIGV2ZW50ID0gZG9jLmNyZWF0ZUV2ZW50KFwiRXZlbnRcIik7XG4gICAgZXZlbnQuaW5pdEV2ZW50KGV2ZW50VHlwZSwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgICByZXR1cm4gakJvbmUuZXh0ZW5kKGV2ZW50LCB7XG4gICAgICAgIG5hbWVzcGFjZTogbmFtZXNwYWNlLFxuICAgICAgICBpc0RlZmF1bHRQcmV2ZW50ZWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQ7XG4gICAgICAgIH1cbiAgICB9LCBkYXRhKTtcbn07XG5cbmZuLm9uID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIGkgPSAwLFxuICAgICAgICBjYWxsYmFjaywgdGFyZ2V0LCBuYW1lc3BhY2UsIGZuLCBldmVudHMsIGV2ZW50VHlwZSwgZXhwZWN0ZWRUYXJnZXQsIGFkZExpc3RlbmVyO1xuXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIGNhbGxiYWNrID0gYXJnc1sxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0YXJnZXQgPSBhcmdzWzFdO1xuICAgICAgICBjYWxsYmFjayA9IGFyZ3NbMl07XG4gICAgfVxuXG4gICAgYWRkTGlzdGVuZXIgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICBqQm9uZS5zZXRJZChlbCk7XG4gICAgICAgIGV2ZW50cyA9IGpCb25lLmdldERhdGEoZWwpLmV2ZW50cztcbiAgICAgICAgZXZlbnQuc3BsaXQoXCIgXCIpLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGV2ZW50VHlwZSA9IGV2ZW50LnNwbGl0KFwiLlwiKVswXTtcbiAgICAgICAgICAgIG5hbWVzcGFjZSA9IGV2ZW50LnNwbGl0KFwiLlwiKS5zcGxpY2UoMSkuam9pbihcIi5cIik7XG4gICAgICAgICAgICBldmVudHNbZXZlbnRUeXBlXSA9IGV2ZW50c1tldmVudFR5cGVdIHx8IFtdO1xuXG4gICAgICAgICAgICBmbiA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoZS5uYW1lc3BhY2UgJiYgZS5uYW1lc3BhY2UgIT09IG5hbWVzcGFjZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWRUYXJnZXQgPSBudWxsO1xuICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoZWwsIGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAofmpCb25lKGVsKS5maW5kKHRhcmdldCkuaW5kZXhPZihlLnRhcmdldCkgfHwgKGV4cGVjdGVkVGFyZ2V0ID0gakJvbmUuY29udGFpbnMoakJvbmUoZWwpLmZpbmQodGFyZ2V0KSwgZS50YXJnZXQpKSkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZFRhcmdldCA9IGV4cGVjdGVkVGFyZ2V0IHx8IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgICAgICBlID0gbmV3IEJvbmVFdmVudChlLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50VGFyZ2V0OiBleHBlY3RlZFRhcmdldFxuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKGV4cGVjdGVkVGFyZ2V0LCBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBldmVudHNbZXZlbnRUeXBlXS5wdXNoKHtcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IG5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgICBmbjogZm4sXG4gICAgICAgICAgICAgICAgb3JpZ2luZm46IGNhbGxiYWNrXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lciAmJiBlbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgZm4sIGZhbHNlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYWRkTGlzdGVuZXIodGhpc1tpXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mbi5vbmUgPSBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIGNhbGxiYWNrLCB0YXJnZXQsIGFkZExpc3RlbmVyO1xuXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIGNhbGxiYWNrID0gYXJnc1sxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0YXJnZXQgPSBhcmdzWzFdLCBjYWxsYmFjayA9IGFyZ3NbMl07XG4gICAgfVxuXG4gICAgYWRkTGlzdGVuZXIgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICBldmVudC5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgdmFyIGZuID0gZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIGpCb25lKGVsKS5vZmYoZXZlbnQsIGZuKTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKGVsLCBlKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgakJvbmUoZWwpLm9uKGV2ZW50LCBmbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGpCb25lKGVsKS5vbihldmVudCwgdGFyZ2V0LCBmbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGFkZExpc3RlbmVyKHRoaXNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4udHJpZ2dlciA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGV2ZW50cyA9IFtdLFxuICAgICAgICBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIGRpc3BhdGNoRXZlbnRzO1xuXG4gICAgaWYgKCFldmVudCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBpZiAoaXNTdHJpbmcoZXZlbnQpKSB7XG4gICAgICAgIGV2ZW50cyA9IGV2ZW50LnNwbGl0KFwiIFwiKS5tYXAoZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBqQm9uZS5FdmVudChldmVudCk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGV2ZW50ID0gZXZlbnQgaW5zdGFuY2VvZiBFdmVudCA/IGV2ZW50IDogakJvbmUuRXZlbnQoZXZlbnQpO1xuICAgICAgICBldmVudHMgPSBbZXZlbnRdO1xuICAgIH1cblxuICAgIGRpc3BhdGNoRXZlbnRzID0gZnVuY3Rpb24oZWwpIHtcbiAgICAgICAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICghZXZlbnQudHlwZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudCAmJiBlbC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZGlzcGF0Y2hFdmVudHModGhpc1tpXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mbi5vZmYgPSBmdW5jdGlvbihldmVudCwgZm4pIHtcbiAgICB2YXIgaSA9IDAsXG4gICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoLFxuICAgICAgICByZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50cywgZXZlbnRUeXBlLCBpbmRleCwgZWwsIGUpIHtcbiAgICAgICAgICAgIHZhciBjYWxsYmFjaztcblxuICAgICAgICAgICAgLy8gZ2V0IGNhbGxiYWNrXG4gICAgICAgICAgICBpZiAoKGZuICYmIGUub3JpZ2luZm4gPT09IGZuKSB8fCAhZm4pIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGUuZm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChldmVudHNbZXZlbnRUeXBlXVtpbmRleF0uZm4gPT09IGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGNhbGxiYWNrKTtcblxuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBoYW5kbGVyIGZyb20gY2FjaGVcbiAgICAgICAgICAgICAgICBqQm9uZS5fY2FjaGUuZXZlbnRzW2pCb25lLmdldERhdGEoZWwpLmppZF1bZXZlbnRUeXBlXS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBldmVudHMsIG5hbWVzcGFjZSwgcmVtb3ZlTGlzdGVuZXJzLCBldmVudFR5cGU7XG5cbiAgICByZW1vdmVMaXN0ZW5lcnMgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICB2YXIgbCwgZXZlbnRzQnlUeXBlLCBlO1xuXG4gICAgICAgIGV2ZW50cyA9IGpCb25lLmdldERhdGEoZWwpLmV2ZW50cztcblxuICAgICAgICBpZiAoIWV2ZW50cykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBldmVudHNcbiAgICAgICAgaWYgKCFldmVudCAmJiBldmVudHMpIHtcbiAgICAgICAgICAgIHJldHVybiBrZXlzKGV2ZW50cykuZm9yRWFjaChmdW5jdGlvbihldmVudFR5cGUpIHtcbiAgICAgICAgICAgICAgICBldmVudHNCeVR5cGUgPSBldmVudHNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICBsID0gZXZlbnRzQnlUeXBlLmxlbmd0aDtcblxuICAgICAgICAgICAgICAgIHdoaWxlKGwtLSkge1xuICAgICAgICAgICAgICAgICAgICByZW1vdmVMaXN0ZW5lcihldmVudHMsIGV2ZW50VHlwZSwgbCwgZWwsIGV2ZW50c0J5VHlwZVtsXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBldmVudC5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgZXZlbnRUeXBlID0gZXZlbnQuc3BsaXQoXCIuXCIpWzBdO1xuICAgICAgICAgICAgbmFtZXNwYWNlID0gZXZlbnQuc3BsaXQoXCIuXCIpLnNwbGljZSgxKS5qb2luKFwiLlwiKTtcblxuICAgICAgICAgICAgLy8gcmVtb3ZlIG5hbWVkIGV2ZW50c1xuICAgICAgICAgICAgaWYgKGV2ZW50c1tldmVudFR5cGVdKSB7XG4gICAgICAgICAgICAgICAgZXZlbnRzQnlUeXBlID0gZXZlbnRzW2V2ZW50VHlwZV07XG4gICAgICAgICAgICAgICAgbCA9IGV2ZW50c0J5VHlwZS5sZW5ndGg7XG5cbiAgICAgICAgICAgICAgICB3aGlsZShsLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgZSA9IGV2ZW50c0J5VHlwZVtsXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuYW1lc3BhY2UgfHwgKG5hbWVzcGFjZSAmJiBlLm5hbWVzcGFjZSA9PT0gbmFtZXNwYWNlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlTGlzdGVuZXIoZXZlbnRzLCBldmVudFR5cGUsIGwsIGVsLCBlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJlbW92ZSBhbGwgbmFtZXNwYWNlZCBldmVudHNcbiAgICAgICAgICAgIGVsc2UgaWYgKG5hbWVzcGFjZSkge1xuICAgICAgICAgICAgICAgIGtleXMoZXZlbnRzKS5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50VHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBldmVudHNCeVR5cGUgPSBldmVudHNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgbCA9IGV2ZW50c0J5VHlwZS5sZW5ndGg7XG5cbiAgICAgICAgICAgICAgICAgICAgd2hpbGUobC0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlID0gZXZlbnRzQnlUeXBlW2xdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUubmFtZXNwYWNlLnNwbGl0KFwiLlwiKVswXSA9PT0gbmFtZXNwYWNlLnNwbGl0KFwiLlwiKVswXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50cywgZXZlbnRUeXBlLCBsLCBlbCwgZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVtb3ZlTGlzdGVuZXJzKHRoaXNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4uZmluZCA9IGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgdmFyIHJlc3VsdHMgPSBbXSxcbiAgICAgICAgaSA9IDAsXG4gICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoLFxuICAgICAgICBmaW5kZXIgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24oZWwucXVlcnlTZWxlY3RvckFsbCkpIHtcbiAgICAgICAgICAgICAgICBbXS5mb3JFYWNoLmNhbGwoZWwucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvciksIGZ1bmN0aW9uKGZvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChmb3VuZCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZpbmRlcih0aGlzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gakJvbmUocmVzdWx0cyk7XG59O1xuXG5mbi5nZXQgPSBmdW5jdGlvbihpbmRleCkge1xuICAgIHJldHVybiB0aGlzW2luZGV4XTtcbn07XG5cbmZuLmVxID0gZnVuY3Rpb24oaW5kZXgpIHtcbiAgICByZXR1cm4gakJvbmUodGhpc1tpbmRleF0pO1xufTtcblxuZm4ucGFyZW50ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJlc3VsdHMgPSBbXSxcbiAgICAgICAgcGFyZW50LFxuICAgICAgICBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICghfnJlc3VsdHMuaW5kZXhPZihwYXJlbnQgPSB0aGlzW2ldLnBhcmVudEVsZW1lbnQpICYmIHBhcmVudCkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHBhcmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gakJvbmUocmVzdWx0cyk7XG59O1xuXG5mbi50b0FycmF5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNsaWNlLmNhbGwodGhpcyk7XG59O1xuXG5mbi5pcyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuXG4gICAgcmV0dXJuIHRoaXMuc29tZShmdW5jdGlvbihlbCkge1xuICAgICAgICByZXR1cm4gZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSBhcmdzWzBdO1xuICAgIH0pO1xufTtcblxuZm4uaGFzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG5cbiAgICByZXR1cm4gdGhpcy5zb21lKGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgIHJldHVybiBlbC5xdWVyeVNlbGVjdG9yQWxsKGFyZ3NbMF0pLmxlbmd0aDtcbiAgICB9KTtcbn07XG5cbmZuLmF0dHIgPSBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGkgPSAwLFxuICAgICAgICBsZW5ndGggPSB0aGlzLmxlbmd0aCxcbiAgICAgICAgc2V0dGVyO1xuXG4gICAgaWYgKGlzU3RyaW5nKGtleSkgJiYgYXJncy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbMF0gJiYgdGhpc1swXS5nZXRBdHRyaWJ1dGUoa2V5KTtcbiAgICB9XG5cbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgc2V0dGVyID0gZnVuY3Rpb24oZWwpIHtcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShrZXksIHZhbHVlKTtcbiAgICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KGtleSkpIHtcbiAgICAgICAgc2V0dGVyID0gZnVuY3Rpb24oZWwpIHtcbiAgICAgICAgICAgIGtleXMoa2V5KS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUobmFtZSwga2V5W25hbWVdKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgc2V0dGVyKHRoaXNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4ucmVtb3ZlQXR0ciA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXNbaV0ucmVtb3ZlQXR0cmlidXRlKGtleSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mbi52YWwgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpc1swXSAmJiB0aGlzWzBdLnZhbHVlO1xuICAgIH1cblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpc1tpXS52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4uY3NzID0gZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIHNldHRlcjtcblxuICAgIC8vIEdldCBhdHRyaWJ1dGVcbiAgICBpZiAoaXNTdHJpbmcoa2V5KSAmJiBhcmdzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gdGhpc1swXSAmJiB3aW4uZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzWzBdKVtrZXldO1xuICAgIH1cblxuICAgIC8vIFNldCBhdHRyaWJ1dGVzXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIHNldHRlciA9IGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgICAgICBlbC5zdHlsZVtrZXldID0gdmFsdWU7XG4gICAgICAgIH07XG4gICAgfSBlbHNlIGlmIChpc09iamVjdChrZXkpKSB7XG4gICAgICAgIHNldHRlciA9IGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgICAgICBrZXlzKGtleSkuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgICAgICAgICAgZWwuc3R5bGVbbmFtZV0gPSBrZXlbbmFtZV07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHNldHRlcih0aGlzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbmZuLmRhdGEgPSBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsIGRhdGEgPSB7fSxcbiAgICAgICAgaSA9IDAsXG4gICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoLFxuICAgICAgICBzZXR0ZXIsXG4gICAgICAgIHNldFZhbHVlID0gZnVuY3Rpb24oZWwsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBlbC5qZGF0YSA9IGVsLmpkYXRhIHx8IHt9O1xuICAgICAgICAgICAgICAgIGVsLmpkYXRhW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZWwuZGF0YXNldFtrZXldID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGdldFZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gXCJ0cnVlXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09IFwiZmFsc2VcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgLy8gR2V0IGFsbCBkYXRhXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXNbMF0uamRhdGEgJiYgKGRhdGEgPSB0aGlzWzBdLmpkYXRhKTtcblxuICAgICAgICBrZXlzKHRoaXNbMF0uZGF0YXNldCkuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgICAgIGRhdGFba2V5XSA9IGdldFZhbHVlKHRoaXNbMF0uZGF0YXNldFtrZXldKTtcbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIC8vIEdldCBkYXRhIGJ5IG5hbWVcbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgaXNTdHJpbmcoa2V5KSkge1xuICAgICAgICByZXR1cm4gdGhpc1swXSAmJiBnZXRWYWx1ZSh0aGlzWzBdLmRhdGFzZXRba2V5XSB8fCB0aGlzWzBdLmpkYXRhICYmIHRoaXNbMF0uamRhdGFba2V5XSk7XG4gICAgfVxuXG4gICAgLy8gU2V0IGRhdGFcbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgaXNPYmplY3Qoa2V5KSkge1xuICAgICAgICBzZXR0ZXIgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICAgICAga2V5cyhrZXkpLmZvckVhY2goZnVuY3Rpb24obmFtZSkge1xuICAgICAgICAgICAgICAgIHNldFZhbHVlKGVsLCBuYW1lLCBrZXlbbmFtZV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfSBlbHNlIGlmIChhcmdzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICBzZXR0ZXIgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICAgICAgc2V0VmFsdWUoZWwsIGtleSwgdmFsdWUpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgc2V0dGVyKHRoaXNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4ucmVtb3ZlRGF0YSA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIGpkYXRhLCBkYXRhc2V0O1xuXG4gICAgZm9yICg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBqZGF0YSA9IHRoaXNbaV0uamRhdGE7XG4gICAgICAgIGRhdGFzZXQgPSB0aGlzW2ldLmRhdGFzZXQ7XG5cbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgamRhdGEgJiYgamRhdGFba2V5XSAmJiBkZWxldGUgamRhdGFba2V5XTtcbiAgICAgICAgICAgIGRlbGV0ZSBkYXRhc2V0W2tleV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBqZGF0YSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBqZGF0YVtrZXldO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGtleSBpbiBkYXRhc2V0KSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGRhdGFzZXRba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4uaHRtbCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGVsO1xuXG4gICAgLy8gYWRkIEhUTUwgaW50byBlbGVtZW50c1xuICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVtcHR5KCkuYXBwZW5kKHZhbHVlKTtcbiAgICB9XG4gICAgLy8gZ2V0IEhUTUwgZnJvbSBlbGVtZW50XG4gICAgZWxzZSBpZiAoYXJncy5sZW5ndGggPT09IDAgJiYgKGVsID0gdGhpc1swXSkpIHtcbiAgICAgICAgcmV0dXJuIGVsLmlubmVySFRNTDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbmZuLmFwcGVuZCA9IGZ1bmN0aW9uKGFwcGVuZGVkKSB7XG4gICAgdmFyIGkgPSAwLFxuICAgICAgICBsZW5ndGggPSB0aGlzLmxlbmd0aCxcbiAgICAgICAgc2V0dGVyO1xuXG4gICAgLy8gY3JlYXRlIGpCb25lIG9iamVjdCBhbmQgdGhlbiBhcHBlbmRcbiAgICBpZiAoaXNTdHJpbmcoYXBwZW5kZWQpICYmIHJxdWlja0V4cHIuZXhlYyhhcHBlbmRlZCkpIHtcbiAgICAgICAgYXBwZW5kZWQgPSBqQm9uZShhcHBlbmRlZCk7XG4gICAgfVxuICAgIC8vIGNyZWF0ZSB0ZXh0IG5vZGUgZm9yIGluc2VydGluZ1xuICAgIGVsc2UgaWYgKCFpc09iamVjdChhcHBlbmRlZCkpIHtcbiAgICAgICAgYXBwZW5kZWQgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShhcHBlbmRlZCk7XG4gICAgfVxuXG4gICAgYXBwZW5kZWQgPSBhcHBlbmRlZCBpbnN0YW5jZW9mIGpCb25lID8gYXBwZW5kZWQgOiBqQm9uZShhcHBlbmRlZCk7XG5cbiAgICBzZXR0ZXIgPSBmdW5jdGlvbihlbCwgaSkge1xuICAgICAgICBhcHBlbmRlZC5mb3JFYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgICAgIGlmIChpKSB7XG4gICAgICAgICAgICAgICAgZWwuYXBwZW5kQ2hpbGQobm9kZS5jbG9uZU5vZGUoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVsLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgZm9yICg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBzZXR0ZXIodGhpc1tpXSwgaSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mbi5hcHBlbmRUbyA9IGZ1bmN0aW9uKHRvKSB7XG4gICAgakJvbmUodG8pLmFwcGVuZCh0aGlzKTtcblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4uZW1wdHkgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaSA9IDAsXG4gICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoLFxuICAgICAgICBlbDtcblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZWwgPSB0aGlzW2ldO1xuXG4gICAgICAgIHdoaWxlIChlbC5sYXN0Q2hpbGQpIHtcbiAgICAgICAgICAgIGVsLnJlbW92ZUNoaWxkKGVsLmxhc3RDaGlsZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbmZuLnJlbW92ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIGVsO1xuXG4gICAgLy8gcmVtb3ZlIGFsbCBsaXN0bmVyc1xuICAgIHRoaXMub2ZmKCk7XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGVsID0gdGhpc1tpXTtcblxuICAgICAgICAvLyByZW1vdmUgZGF0YSBhbmQgbm9kZXNcbiAgICAgICAgZGVsZXRlIGVsLmpkYXRhO1xuICAgICAgICBlbC5wYXJlbnROb2RlICYmIGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWwpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuaWYgKHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIgJiYgbW9kdWxlICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuICAgIC8vIEV4cG9zZSBqQm9uZSBhcyBtb2R1bGUuZXhwb3J0cyBpbiBsb2FkZXJzIHRoYXQgaW1wbGVtZW50IHRoZSBOb2RlXG4gICAgLy8gbW9kdWxlIHBhdHRlcm4gKGluY2x1ZGluZyBicm93c2VyaWZ5KS4gRG8gbm90IGNyZWF0ZSB0aGUgZ2xvYmFsLCBzaW5jZVxuICAgIC8vIHRoZSB1c2VyIHdpbGwgYmUgc3RvcmluZyBpdCB0aGVtc2VsdmVzIGxvY2FsbHksIGFuZCBnbG9iYWxzIGFyZSBmcm93bmVkXG4gICAgLy8gdXBvbiBpbiB0aGUgTm9kZSBtb2R1bGUgd29ybGQuXG4gICAgbW9kdWxlLmV4cG9ydHMgPSBqQm9uZTtcbn1cbi8vIFJlZ2lzdGVyIGFzIGEgQU1EIG1vZHVsZVxuZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICBkZWZpbmUoZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBqQm9uZTtcbiAgICB9KTtcblxuICAgIHdpbi5qQm9uZSA9IHdpbi4kID0gakJvbmU7XG59IGVsc2UgaWYgKHR5cGVvZiB3aW4gPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHdpbi5kb2N1bWVudCA9PT0gXCJvYmplY3RcIikge1xuICAgIHdpbi5qQm9uZSA9IHdpbi4kID0gakJvbmU7XG59XG5cbn0od2luZG93KSk7XG4iLCJ2YXIgTW91c2U7XG5cbm1vZHVsZS5leHBvcnRzID0gTW91c2UgPSB7XG4gIHJlbDogZnVuY3Rpb24oZSkge1xuICAgIHZhciBtb3VzZVgsIG1vdXNlWSwgcmVjdCwgdGFyZ2V0O1xuICAgIG1vdXNlWCA9IGUub2Zmc2V0WDtcbiAgICBtb3VzZVkgPSBlLm9mZnNldFk7XG4gICAgaWYgKG1vdXNlWCA9PSBudWxsKSB7XG4gICAgICByZWN0ID0gdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgdGFyZ2V0ID0gZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50O1xuICAgICAgaWYgKG1vdXNlWCA9PSBudWxsKSB7XG4gICAgICAgIG1vdXNlWCA9IGUuY2xpZW50WCAtIHJlY3QubGVmdDtcbiAgICAgICAgbW91c2VZID0gZS5jbGllbnRZIC0gcmVjdC50b3A7XG4gICAgICB9XG4gICAgICBpZiAobW91c2VYID09IG51bGwpIHtcbiAgICAgICAgbW91c2VYID0gZS5wYWdlWCAtIHRhcmdldC5vZmZzZXRMZWZ0O1xuICAgICAgICBtb3VzZVkgPSBlLnBhZ2VZIC0gdGFyZ2V0Lm9mZnNldFRvcDtcbiAgICAgIH1cbiAgICAgIGlmIChtb3VzZVggPT0gbnVsbCkge1xuICAgICAgICBjb25zb2xlLmxvZyhlLCBcIm5vIG1vdXNlIGV2ZW50IGRlZmluZWQuIHlvdXIgYnJvd3NlciBzdWNrc1wiKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW21vdXNlWCwgbW91c2VZXTtcbiAgfSxcbiAgYWJzOiBmdW5jdGlvbihlKSB7XG4gICAgdmFyIG1vdXNlWCwgbW91c2VZO1xuICAgIG1vdXNlWCA9IGUucGFnZVg7XG4gICAgbW91c2VZID0gZS5wYWdlWTtcbiAgICBpZiAobW91c2VYID09IG51bGwpIHtcbiAgICAgIG1vdXNlWCA9IGUubGF5ZXJYO1xuICAgICAgbW91c2VZID0gZS5sYXllclk7XG4gICAgfVxuICAgIGlmIChtb3VzZVggPT0gbnVsbCkge1xuICAgICAgbW91c2VYID0gZS5jbGllbnRYO1xuICAgICAgbW91c2VZID0gZS5jbGllbnRZO1xuICAgIH1cbiAgICBpZiAobW91c2VYID09IG51bGwpIHtcbiAgICAgIG1vdXNlWCA9IGUueDtcbiAgICAgIG1vdXNlWSA9IGUueTtcbiAgICB9XG4gICAgcmV0dXJuIFttb3VzZVgsIG1vdXNlWV07XG4gIH0sXG4gIHdoZWVsRGVsdGE6IGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZGVsdGEsIGRpcjtcbiAgICBkZWx0YSA9IFtlLmRlbHRhWCwgZS5kZWx0YVldO1xuICAgIGlmIChkZWx0YVswXSA9PSBudWxsKSB7XG4gICAgICBkaXIgPSBNYXRoLmZsb29yKGUuZGV0YWlsIC8gMyk7XG4gICAgICBkZWx0YSA9IFswLCBlLm1vek1vdmVtZW50WCAqIGRpcl07XG4gICAgfVxuICAgIHJldHVybiBkZWx0YTtcbiAgfVxufTtcbiIsInZhciB3aW5kb3cgPSByZXF1aXJlKFwiZ2xvYmFsL3dpbmRvd1wiKVxudmFyIG9uY2UgPSByZXF1aXJlKFwib25jZVwiKVxudmFyIHBhcnNlSGVhZGVycyA9IHJlcXVpcmUoJ3BhcnNlLWhlYWRlcnMnKVxuXG52YXIgbWVzc2FnZXMgPSB7XG4gICAgXCIwXCI6IFwiSW50ZXJuYWwgWE1MSHR0cFJlcXVlc3QgRXJyb3JcIixcbiAgICBcIjRcIjogXCI0eHggQ2xpZW50IEVycm9yXCIsXG4gICAgXCI1XCI6IFwiNXh4IFNlcnZlciBFcnJvclwiXG59XG5cbnZhciBYSFIgPSB3aW5kb3cuWE1MSHR0cFJlcXVlc3QgfHwgbm9vcFxudmFyIFhEUiA9IFwid2l0aENyZWRlbnRpYWxzXCIgaW4gKG5ldyBYSFIoKSkgPyBYSFIgOiB3aW5kb3cuWERvbWFpblJlcXVlc3RcblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVYSFJcblxuZnVuY3Rpb24gY3JlYXRlWEhSKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIG9wdGlvbnMgPSB7IHVyaTogb3B0aW9ucyB9XG4gICAgfVxuXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgICBjYWxsYmFjayA9IG9uY2UoY2FsbGJhY2spXG5cbiAgICB2YXIgeGhyID0gb3B0aW9ucy54aHIgfHwgbnVsbFxuXG4gICAgaWYgKCF4aHIpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuY29ycyB8fCBvcHRpb25zLnVzZVhEUikge1xuICAgICAgICAgICAgeGhyID0gbmV3IFhEUigpXG4gICAgICAgIH1lbHNle1xuICAgICAgICAgICAgeGhyID0gbmV3IFhIUigpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgdXJpID0geGhyLnVybCA9IG9wdGlvbnMudXJpIHx8IG9wdGlvbnMudXJsXG4gICAgdmFyIG1ldGhvZCA9IHhoci5tZXRob2QgPSBvcHRpb25zLm1ldGhvZCB8fCBcIkdFVFwiXG4gICAgdmFyIGJvZHkgPSBvcHRpb25zLmJvZHkgfHwgb3B0aW9ucy5kYXRhXG4gICAgdmFyIGhlYWRlcnMgPSB4aHIuaGVhZGVycyA9IG9wdGlvbnMuaGVhZGVycyB8fCB7fVxuICAgIHZhciBzeW5jID0gISFvcHRpb25zLnN5bmNcbiAgICB2YXIgaXNKc29uID0gZmFsc2VcbiAgICB2YXIga2V5XG4gICAgdmFyIGxvYWQgPSBvcHRpb25zLnJlc3BvbnNlID8gbG9hZFJlc3BvbnNlIDogbG9hZFhoclxuXG4gICAgaWYgKFwianNvblwiIGluIG9wdGlvbnMpIHtcbiAgICAgICAgaXNKc29uID0gdHJ1ZVxuICAgICAgICBoZWFkZXJzW1wiQWNjZXB0XCJdID0gXCJhcHBsaWNhdGlvbi9qc29uXCJcbiAgICAgICAgaWYgKG1ldGhvZCAhPT0gXCJHRVRcIiAmJiBtZXRob2QgIT09IFwiSEVBRFwiKSB7XG4gICAgICAgICAgICBoZWFkZXJzW1wiQ29udGVudC1UeXBlXCJdID0gXCJhcHBsaWNhdGlvbi9qc29uXCJcbiAgICAgICAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShvcHRpb25zLmpzb24pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gcmVhZHlzdGF0ZWNoYW5nZVxuICAgIHhoci5vbmxvYWQgPSBsb2FkXG4gICAgeGhyLm9uZXJyb3IgPSBlcnJvclxuICAgIC8vIElFOSBtdXN0IGhhdmUgb25wcm9ncmVzcyBiZSBzZXQgdG8gYSB1bmlxdWUgZnVuY3Rpb24uXG4gICAgeGhyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIElFIG11c3QgZGllXG4gICAgfVxuICAgIC8vIGhhdGUgSUVcbiAgICB4aHIub250aW1lb3V0ID0gbm9vcFxuICAgIHhoci5vcGVuKG1ldGhvZCwgdXJpLCAhc3luYylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICAgIGlmIChvcHRpb25zLndpdGhDcmVkZW50aWFscyB8fCAob3B0aW9ucy5jb3JzICYmIG9wdGlvbnMud2l0aENyZWRlbnRpYWxzICE9PSBmYWxzZSkpIHtcbiAgICAgICAgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWVcbiAgICB9XG5cbiAgICAvLyBDYW5ub3Qgc2V0IHRpbWVvdXQgd2l0aCBzeW5jIHJlcXVlc3RcbiAgICBpZiAoIXN5bmMpIHtcbiAgICAgICAgeGhyLnRpbWVvdXQgPSBcInRpbWVvdXRcIiBpbiBvcHRpb25zID8gb3B0aW9ucy50aW1lb3V0IDogNTAwMFxuICAgIH1cblxuICAgIGlmICh4aHIuc2V0UmVxdWVzdEhlYWRlcikge1xuICAgICAgICBmb3Ioa2V5IGluIGhlYWRlcnMpe1xuICAgICAgICAgICAgaWYoaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKXtcbiAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkhlYWRlcnMgY2Fubm90IGJlIHNldCBvbiBhbiBYRG9tYWluUmVxdWVzdCBvYmplY3RcIilcbiAgICB9XG5cbiAgICBpZiAoXCJyZXNwb25zZVR5cGVcIiBpbiBvcHRpb25zKSB7XG4gICAgICAgIHhoci5yZXNwb25zZVR5cGUgPSBvcHRpb25zLnJlc3BvbnNlVHlwZVxuICAgIH1cbiAgICBcbiAgICBpZiAoXCJiZWZvcmVTZW5kXCIgaW4gb3B0aW9ucyAmJiBcbiAgICAgICAgdHlwZW9mIG9wdGlvbnMuYmVmb3JlU2VuZCA9PT0gXCJmdW5jdGlvblwiXG4gICAgKSB7XG4gICAgICAgIG9wdGlvbnMuYmVmb3JlU2VuZCh4aHIpXG4gICAgfVxuXG4gICAgeGhyLnNlbmQoYm9keSlcblxuICAgIHJldHVybiB4aHJcblxuICAgIGZ1bmN0aW9uIHJlYWR5c3RhdGVjaGFuZ2UoKSB7XG4gICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgbG9hZCgpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRCb2R5KCkge1xuICAgICAgICAvLyBDaHJvbWUgd2l0aCByZXF1ZXN0VHlwZT1ibG9iIHRocm93cyBlcnJvcnMgYXJyb3VuZCB3aGVuIGV2ZW4gdGVzdGluZyBhY2Nlc3MgdG8gcmVzcG9uc2VUZXh0XG4gICAgICAgIHZhciBib2R5ID0gbnVsbFxuXG4gICAgICAgIGlmICh4aHIucmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGJvZHkgPSB4aHIucmVzcG9uc2VcbiAgICAgICAgfSBlbHNlIGlmICh4aHIucmVzcG9uc2VUeXBlID09PSAndGV4dCcgfHwgIXhoci5yZXNwb25zZVR5cGUpIHtcbiAgICAgICAgICAgIGJvZHkgPSB4aHIucmVzcG9uc2VUZXh0IHx8IHhoci5yZXNwb25zZVhNTFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzSnNvbikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBib2R5ID0gSlNPTi5wYXJzZShib2R5KVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBib2R5XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U3RhdHVzQ29kZSgpIHtcbiAgICAgICAgcmV0dXJuIHhoci5zdGF0dXMgPT09IDEyMjMgPyAyMDQgOiB4aHIuc3RhdHVzXG4gICAgfVxuXG4gICAgLy8gaWYgd2UncmUgZ2V0dGluZyBhIG5vbmUtb2sgc3RhdHVzQ29kZSwgYnVpbGQgJiByZXR1cm4gYW4gZXJyb3JcbiAgICBmdW5jdGlvbiBlcnJvckZyb21TdGF0dXNDb2RlKHN0YXR1cykge1xuICAgICAgICB2YXIgZXJyb3IgPSBudWxsXG4gICAgICAgIGlmIChzdGF0dXMgPT09IDAgfHwgKHN0YXR1cyA+PSA0MDAgJiYgc3RhdHVzIDwgNjAwKSkge1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSAodHlwZW9mIGJvZHkgPT09IFwic3RyaW5nXCIgPyBib2R5IDogZmFsc2UpIHx8XG4gICAgICAgICAgICAgICAgbWVzc2FnZXNbU3RyaW5nKHN0YXR1cykuY2hhckF0KDApXVxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSlcbiAgICAgICAgICAgIGVycm9yLnN0YXR1c0NvZGUgPSBzdGF0dXNcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvclxuICAgIH1cblxuICAgIC8vIHdpbGwgbG9hZCB0aGUgZGF0YSAmIHByb2Nlc3MgdGhlIHJlc3BvbnNlIGluIGEgc3BlY2lhbCByZXNwb25zZSBvYmplY3RcbiAgICBmdW5jdGlvbiBsb2FkUmVzcG9uc2UoKSB7XG4gICAgICAgIHZhciBzdGF0dXMgPSBnZXRTdGF0dXNDb2RlKClcbiAgICAgICAgdmFyIGVycm9yID0gZXJyb3JGcm9tU3RhdHVzQ29kZShzdGF0dXMpXG4gICAgICAgIHZhciByZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGJvZHk6IGdldEJvZHkoKSxcbiAgICAgICAgICAgIHN0YXR1c0NvZGU6IHN0YXR1cyxcbiAgICAgICAgICAgIHN0YXR1c1RleHQ6IHhoci5zdGF0dXNUZXh0LFxuICAgICAgICAgICAgcmF3OiB4aHJcbiAgICAgICAgfVxuICAgICAgICBpZih4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKXsgLy9yZW1lbWJlciB4aHIgY2FuIGluIGZhY3QgYmUgWERSIGZvciBDT1JTIGluIElFXG4gICAgICAgICAgICByZXNwb25zZS5oZWFkZXJzID0gcGFyc2VIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlLmhlYWRlcnMgPSB7fVxuICAgICAgICB9XG5cbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3BvbnNlLCByZXNwb25zZS5ib2R5KVxuICAgIH1cblxuICAgIC8vIHdpbGwgbG9hZCB0aGUgZGF0YSBhbmQgYWRkIHNvbWUgcmVzcG9uc2UgcHJvcGVydGllcyB0byB0aGUgc291cmNlIHhoclxuICAgIC8vIGFuZCB0aGVuIHJlc3BvbmQgd2l0aCB0aGF0XG4gICAgZnVuY3Rpb24gbG9hZFhocigpIHtcbiAgICAgICAgdmFyIHN0YXR1cyA9IGdldFN0YXR1c0NvZGUoKVxuICAgICAgICB2YXIgZXJyb3IgPSBlcnJvckZyb21TdGF0dXNDb2RlKHN0YXR1cylcblxuICAgICAgICB4aHIuc3RhdHVzID0geGhyLnN0YXR1c0NvZGUgPSBzdGF0dXNcbiAgICAgICAgeGhyLmJvZHkgPSBnZXRCb2R5KClcbiAgICAgICAgeGhyLmhlYWRlcnMgPSBwYXJzZUhlYWRlcnMoeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKVxuXG4gICAgICAgIGNhbGxiYWNrKGVycm9yLCB4aHIsIHhoci5ib2R5KVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGVycm9yKGV2dCkge1xuICAgICAgICBjYWxsYmFjayhldnQsIHhocilcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gbm9vcCgpIHt9XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gd2luZG93O1xufSBlbHNlIGlmICh0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBnbG9iYWw7XG59IGVsc2UgaWYgKHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiKXtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHNlbGY7XG59IGVsc2Uge1xuICAgIG1vZHVsZS5leHBvcnRzID0ge307XG59XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KSIsIm1vZHVsZS5leHBvcnRzID0gb25jZVxuXG5vbmNlLnByb3RvID0gb25jZShmdW5jdGlvbiAoKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGdW5jdGlvbi5wcm90b3R5cGUsICdvbmNlJywge1xuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gb25jZSh0aGlzKVxuICAgIH0sXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pXG59KVxuXG5mdW5jdGlvbiBvbmNlIChmbikge1xuICB2YXIgY2FsbGVkID0gZmFsc2VcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoY2FsbGVkKSByZXR1cm5cbiAgICBjYWxsZWQgPSB0cnVlXG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgfVxufVxuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCdpcy1mdW5jdGlvbicpXG5cbm1vZHVsZS5leHBvcnRzID0gZm9yRWFjaFxuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5XG5cbmZ1bmN0aW9uIGZvckVhY2gobGlzdCwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzRnVuY3Rpb24oaXRlcmF0b3IpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2l0ZXJhdG9yIG11c3QgYmUgYSBmdW5jdGlvbicpXG4gICAgfVxuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSB7XG4gICAgICAgIGNvbnRleHQgPSB0aGlzXG4gICAgfVxuICAgIFxuICAgIGlmICh0b1N0cmluZy5jYWxsKGxpc3QpID09PSAnW29iamVjdCBBcnJheV0nKVxuICAgICAgICBmb3JFYWNoQXJyYXkobGlzdCwgaXRlcmF0b3IsIGNvbnRleHQpXG4gICAgZWxzZSBpZiAodHlwZW9mIGxpc3QgPT09ICdzdHJpbmcnKVxuICAgICAgICBmb3JFYWNoU3RyaW5nKGxpc3QsIGl0ZXJhdG9yLCBjb250ZXh0KVxuICAgIGVsc2VcbiAgICAgICAgZm9yRWFjaE9iamVjdChsaXN0LCBpdGVyYXRvciwgY29udGV4dClcbn1cblxuZnVuY3Rpb24gZm9yRWFjaEFycmF5KGFycmF5LCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhcnJheS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChhcnJheSwgaSkpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgYXJyYXlbaV0sIGksIGFycmF5KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmb3JFYWNoU3RyaW5nKHN0cmluZywgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gc3RyaW5nLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIC8vIG5vIHN1Y2ggdGhpbmcgYXMgYSBzcGFyc2Ugc3RyaW5nLlxuICAgICAgICBpdGVyYXRvci5jYWxsKGNvbnRleHQsIHN0cmluZy5jaGFyQXQoaSksIGksIHN0cmluZylcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGZvckVhY2hPYmplY3Qob2JqZWN0LCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGZvciAodmFyIGsgaW4gb2JqZWN0KSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgaykpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqZWN0W2tdLCBrLCBvYmplY3QpXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGlzRnVuY3Rpb25cblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uIChmbikge1xuICB2YXIgc3RyaW5nID0gdG9TdHJpbmcuY2FsbChmbilcbiAgcmV0dXJuIHN0cmluZyA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJyB8fFxuICAgICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgc3RyaW5nICE9PSAnW29iamVjdCBSZWdFeHBdJykgfHxcbiAgICAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgLy8gSUU4IGFuZCBiZWxvd1xuICAgICAoZm4gPT09IHdpbmRvdy5zZXRUaW1lb3V0IHx8XG4gICAgICBmbiA9PT0gd2luZG93LmFsZXJ0IHx8XG4gICAgICBmbiA9PT0gd2luZG93LmNvbmZpcm0gfHxcbiAgICAgIGZuID09PSB3aW5kb3cucHJvbXB0KSlcbn07XG4iLCJcbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHRyaW07XG5cbmZ1bmN0aW9uIHRyaW0oc3RyKXtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzKnxcXHMqJC9nLCAnJyk7XG59XG5cbmV4cG9ydHMubGVmdCA9IGZ1bmN0aW9uKHN0cil7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyovLCAnJyk7XG59O1xuXG5leHBvcnRzLnJpZ2h0ID0gZnVuY3Rpb24oc3RyKXtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cXHMqJC8sICcnKTtcbn07XG4iLCJ2YXIgdHJpbSA9IHJlcXVpcmUoJ3RyaW0nKVxuICAsIGZvckVhY2ggPSByZXF1aXJlKCdmb3ItZWFjaCcpXG4gICwgaXNBcnJheSA9IGZ1bmN0aW9uKGFyZykge1xuICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaGVhZGVycykge1xuICBpZiAoIWhlYWRlcnMpXG4gICAgcmV0dXJuIHt9XG5cbiAgdmFyIHJlc3VsdCA9IHt9XG5cbiAgZm9yRWFjaChcbiAgICAgIHRyaW0oaGVhZGVycykuc3BsaXQoJ1xcbicpXG4gICAgLCBmdW5jdGlvbiAocm93KSB7XG4gICAgICAgIHZhciBpbmRleCA9IHJvdy5pbmRleE9mKCc6JylcbiAgICAgICAgICAsIGtleSA9IHRyaW0ocm93LnNsaWNlKDAsIGluZGV4KSkudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICwgdmFsdWUgPSB0cmltKHJvdy5zbGljZShpbmRleCArIDEpKVxuXG4gICAgICAgIGlmICh0eXBlb2YocmVzdWx0W2tleV0pID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHJlc3VsdFtrZXldID0gdmFsdWVcbiAgICAgICAgfSBlbHNlIGlmIChpc0FycmF5KHJlc3VsdFtrZXldKSkge1xuICAgICAgICAgIHJlc3VsdFtrZXldLnB1c2godmFsdWUpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0W2tleV0gPSBbIHJlc3VsdFtrZXldLCB2YWx1ZSBdXG4gICAgICAgIH1cbiAgICAgIH1cbiAgKVxuXG4gIHJldHVybiByZXN1bHRcbn0iLCIvLyAgICAgVW5kZXJzY29yZS5qcyAxLjcuMFxuLy8gICAgIGh0dHA6Ly91bmRlcnNjb3JlanMub3JnXG4vLyAgICAgKGMpIDIwMDktMjAxNCBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9yc1xuLy8gICAgIFVuZGVyc2NvcmUgbWF5IGJlIGZyZWVseSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXG5cbihmdW5jdGlvbigpIHtcblxuICAvLyBCYXNlbGluZSBzZXR1cFxuICAvLyAtLS0tLS0tLS0tLS0tLVxuXG4gIC8vIEVzdGFibGlzaCB0aGUgcm9vdCBvYmplY3QsIGB3aW5kb3dgIGluIHRoZSBicm93c2VyLCBvciBgZXhwb3J0c2Agb24gdGhlIHNlcnZlci5cbiAgdmFyIHJvb3QgPSB0aGlzO1xuXG4gIC8vIFNhdmUgdGhlIHByZXZpb3VzIHZhbHVlIG9mIHRoZSBgX2AgdmFyaWFibGUuXG4gIHZhciBwcmV2aW91c1VuZGVyc2NvcmUgPSByb290Ll87XG5cbiAgLy8gU2F2ZSBieXRlcyBpbiB0aGUgbWluaWZpZWQgKGJ1dCBub3QgZ3ppcHBlZCkgdmVyc2lvbjpcbiAgdmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGUsIE9ialByb3RvID0gT2JqZWN0LnByb3RvdHlwZSwgRnVuY1Byb3RvID0gRnVuY3Rpb24ucHJvdG90eXBlO1xuXG4gIC8vIENyZWF0ZSBxdWljayByZWZlcmVuY2UgdmFyaWFibGVzIGZvciBzcGVlZCBhY2Nlc3MgdG8gY29yZSBwcm90b3R5cGVzLlxuICB2YXJcbiAgICBwdXNoICAgICAgICAgICAgID0gQXJyYXlQcm90by5wdXNoLFxuICAgIHNsaWNlICAgICAgICAgICAgPSBBcnJheVByb3RvLnNsaWNlLFxuICAgIGNvbmNhdCAgICAgICAgICAgPSBBcnJheVByb3RvLmNvbmNhdCxcbiAgICB0b1N0cmluZyAgICAgICAgID0gT2JqUHJvdG8udG9TdHJpbmcsXG4gICAgaGFzT3duUHJvcGVydHkgICA9IE9ialByb3RvLmhhc093blByb3BlcnR5O1xuXG4gIC8vIEFsbCAqKkVDTUFTY3JpcHQgNSoqIG5hdGl2ZSBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbnMgdGhhdCB3ZSBob3BlIHRvIHVzZVxuICAvLyBhcmUgZGVjbGFyZWQgaGVyZS5cbiAgdmFyXG4gICAgbmF0aXZlSXNBcnJheSAgICAgID0gQXJyYXkuaXNBcnJheSxcbiAgICBuYXRpdmVLZXlzICAgICAgICAgPSBPYmplY3Qua2V5cyxcbiAgICBuYXRpdmVCaW5kICAgICAgICAgPSBGdW5jUHJvdG8uYmluZDtcblxuICAvLyBDcmVhdGUgYSBzYWZlIHJlZmVyZW5jZSB0byB0aGUgVW5kZXJzY29yZSBvYmplY3QgZm9yIHVzZSBiZWxvdy5cbiAgdmFyIF8gPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAob2JqIGluc3RhbmNlb2YgXykgcmV0dXJuIG9iajtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgXykpIHJldHVybiBuZXcgXyhvYmopO1xuICAgIHRoaXMuX3dyYXBwZWQgPSBvYmo7XG4gIH07XG5cbiAgLy8gRXhwb3J0IHRoZSBVbmRlcnNjb3JlIG9iamVjdCBmb3IgKipOb2RlLmpzKiosIHdpdGhcbiAgLy8gYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgZm9yIHRoZSBvbGQgYHJlcXVpcmUoKWAgQVBJLiBJZiB3ZSdyZSBpblxuICAvLyB0aGUgYnJvd3NlciwgYWRkIGBfYCBhcyBhIGdsb2JhbCBvYmplY3QuXG4gIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAgIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IF87XG4gICAgfVxuICAgIGV4cG9ydHMuXyA9IF87XG4gIH0gZWxzZSB7XG4gICAgcm9vdC5fID0gXztcbiAgfVxuXG4gIC8vIEN1cnJlbnQgdmVyc2lvbi5cbiAgXy5WRVJTSU9OID0gJzEuNy4wJztcblxuICAvLyBJbnRlcm5hbCBmdW5jdGlvbiB0aGF0IHJldHVybnMgYW4gZWZmaWNpZW50IChmb3IgY3VycmVudCBlbmdpbmVzKSB2ZXJzaW9uXG4gIC8vIG9mIHRoZSBwYXNzZWQtaW4gY2FsbGJhY2ssIHRvIGJlIHJlcGVhdGVkbHkgYXBwbGllZCBpbiBvdGhlciBVbmRlcnNjb3JlXG4gIC8vIGZ1bmN0aW9ucy5cbiAgdmFyIGNyZWF0ZUNhbGxiYWNrID0gZnVuY3Rpb24oZnVuYywgY29udGV4dCwgYXJnQ291bnQpIHtcbiAgICBpZiAoY29udGV4dCA9PT0gdm9pZCAwKSByZXR1cm4gZnVuYztcbiAgICBzd2l0Y2ggKGFyZ0NvdW50ID09IG51bGwgPyAzIDogYXJnQ291bnQpIHtcbiAgICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgdmFsdWUpO1xuICAgICAgfTtcbiAgICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgICByZXR1cm4gZnVuYy5jYWxsKGNvbnRleHQsIHZhbHVlLCBvdGhlcik7XG4gICAgICB9O1xuICAgICAgY2FzZSAzOiByZXR1cm4gZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICAgIH07XG4gICAgICBjYXNlIDQ6IHJldHVybiBmdW5jdGlvbihhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZnVuYy5hcHBseShjb250ZXh0LCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH07XG5cbiAgLy8gQSBtb3N0bHktaW50ZXJuYWwgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgY2FsbGJhY2tzIHRoYXQgY2FuIGJlIGFwcGxpZWRcbiAgLy8gdG8gZWFjaCBlbGVtZW50IGluIGEgY29sbGVjdGlvbiwgcmV0dXJuaW5nIHRoZSBkZXNpcmVkIHJlc3VsdCDigJQgZWl0aGVyXG4gIC8vIGlkZW50aXR5LCBhbiBhcmJpdHJhcnkgY2FsbGJhY2ssIGEgcHJvcGVydHkgbWF0Y2hlciwgb3IgYSBwcm9wZXJ0eSBhY2Nlc3Nvci5cbiAgXy5pdGVyYXRlZSA9IGZ1bmN0aW9uKHZhbHVlLCBjb250ZXh0LCBhcmdDb3VudCkge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSByZXR1cm4gXy5pZGVudGl0eTtcbiAgICBpZiAoXy5pc0Z1bmN0aW9uKHZhbHVlKSkgcmV0dXJuIGNyZWF0ZUNhbGxiYWNrKHZhbHVlLCBjb250ZXh0LCBhcmdDb3VudCk7XG4gICAgaWYgKF8uaXNPYmplY3QodmFsdWUpKSByZXR1cm4gXy5tYXRjaGVzKHZhbHVlKTtcbiAgICByZXR1cm4gXy5wcm9wZXJ0eSh2YWx1ZSk7XG4gIH07XG5cbiAgLy8gQ29sbGVjdGlvbiBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBUaGUgY29ybmVyc3RvbmUsIGFuIGBlYWNoYCBpbXBsZW1lbnRhdGlvbiwgYWthIGBmb3JFYWNoYC5cbiAgLy8gSGFuZGxlcyByYXcgb2JqZWN0cyBpbiBhZGRpdGlvbiB0byBhcnJheS1saWtlcy4gVHJlYXRzIGFsbFxuICAvLyBzcGFyc2UgYXJyYXktbGlrZXMgYXMgaWYgdGhleSB3ZXJlIGRlbnNlLlxuICBfLmVhY2ggPSBfLmZvckVhY2ggPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gb2JqO1xuICAgIGl0ZXJhdGVlID0gY3JlYXRlQ2FsbGJhY2soaXRlcmF0ZWUsIGNvbnRleHQpO1xuICAgIHZhciBpLCBsZW5ndGggPSBvYmoubGVuZ3RoO1xuICAgIGlmIChsZW5ndGggPT09ICtsZW5ndGgpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBpdGVyYXRlZShvYmpbaV0sIGksIG9iaik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBrZXlzID0gXy5rZXlzKG9iaik7XG4gICAgICBmb3IgKGkgPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGl0ZXJhdGVlKG9ialtrZXlzW2ldXSwga2V5c1tpXSwgb2JqKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIHJlc3VsdHMgb2YgYXBwbHlpbmcgdGhlIGl0ZXJhdGVlIHRvIGVhY2ggZWxlbWVudC5cbiAgXy5tYXAgPSBfLmNvbGxlY3QgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gW107XG4gICAgaXRlcmF0ZWUgPSBfLml0ZXJhdGVlKGl0ZXJhdGVlLCBjb250ZXh0KTtcbiAgICB2YXIga2V5cyA9IG9iai5sZW5ndGggIT09ICtvYmoubGVuZ3RoICYmIF8ua2V5cyhvYmopLFxuICAgICAgICBsZW5ndGggPSAoa2V5cyB8fCBvYmopLmxlbmd0aCxcbiAgICAgICAgcmVzdWx0cyA9IEFycmF5KGxlbmd0aCksXG4gICAgICAgIGN1cnJlbnRLZXk7XG4gICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgY3VycmVudEtleSA9IGtleXMgPyBrZXlzW2luZGV4XSA6IGluZGV4O1xuICAgICAgcmVzdWx0c1tpbmRleF0gPSBpdGVyYXRlZShvYmpbY3VycmVudEtleV0sIGN1cnJlbnRLZXksIG9iaik7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9O1xuXG4gIHZhciByZWR1Y2VFcnJvciA9ICdSZWR1Y2Ugb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJztcblxuICAvLyAqKlJlZHVjZSoqIGJ1aWxkcyB1cCBhIHNpbmdsZSByZXN1bHQgZnJvbSBhIGxpc3Qgb2YgdmFsdWVzLCBha2EgYGluamVjdGAsXG4gIC8vIG9yIGBmb2xkbGAuXG4gIF8ucmVkdWNlID0gXy5mb2xkbCA9IF8uaW5qZWN0ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgbWVtbywgY29udGV4dCkge1xuICAgIGlmIChvYmogPT0gbnVsbCkgb2JqID0gW107XG4gICAgaXRlcmF0ZWUgPSBjcmVhdGVDYWxsYmFjayhpdGVyYXRlZSwgY29udGV4dCwgNCk7XG4gICAgdmFyIGtleXMgPSBvYmoubGVuZ3RoICE9PSArb2JqLmxlbmd0aCAmJiBfLmtleXMob2JqKSxcbiAgICAgICAgbGVuZ3RoID0gKGtleXMgfHwgb2JqKS5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gMCwgY3VycmVudEtleTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIHtcbiAgICAgIGlmICghbGVuZ3RoKSB0aHJvdyBuZXcgVHlwZUVycm9yKHJlZHVjZUVycm9yKTtcbiAgICAgIG1lbW8gPSBvYmpba2V5cyA/IGtleXNbaW5kZXgrK10gOiBpbmRleCsrXTtcbiAgICB9XG4gICAgZm9yICg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjdXJyZW50S2V5ID0ga2V5cyA/IGtleXNbaW5kZXhdIDogaW5kZXg7XG4gICAgICBtZW1vID0gaXRlcmF0ZWUobWVtbywgb2JqW2N1cnJlbnRLZXldLCBjdXJyZW50S2V5LCBvYmopO1xuICAgIH1cbiAgICByZXR1cm4gbWVtbztcbiAgfTtcblxuICAvLyBUaGUgcmlnaHQtYXNzb2NpYXRpdmUgdmVyc2lvbiBvZiByZWR1Y2UsIGFsc28ga25vd24gYXMgYGZvbGRyYC5cbiAgXy5yZWR1Y2VSaWdodCA9IF8uZm9sZHIgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBtZW1vLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSBvYmogPSBbXTtcbiAgICBpdGVyYXRlZSA9IGNyZWF0ZUNhbGxiYWNrKGl0ZXJhdGVlLCBjb250ZXh0LCA0KTtcbiAgICB2YXIga2V5cyA9IG9iai5sZW5ndGggIT09ICsgb2JqLmxlbmd0aCAmJiBfLmtleXMob2JqKSxcbiAgICAgICAgaW5kZXggPSAoa2V5cyB8fCBvYmopLmxlbmd0aCxcbiAgICAgICAgY3VycmVudEtleTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIHtcbiAgICAgIGlmICghaW5kZXgpIHRocm93IG5ldyBUeXBlRXJyb3IocmVkdWNlRXJyb3IpO1xuICAgICAgbWVtbyA9IG9ialtrZXlzID8ga2V5c1stLWluZGV4XSA6IC0taW5kZXhdO1xuICAgIH1cbiAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgY3VycmVudEtleSA9IGtleXMgPyBrZXlzW2luZGV4XSA6IGluZGV4O1xuICAgICAgbWVtbyA9IGl0ZXJhdGVlKG1lbW8sIG9ialtjdXJyZW50S2V5XSwgY3VycmVudEtleSwgb2JqKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lbW87XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBmaXJzdCB2YWx1ZSB3aGljaCBwYXNzZXMgYSB0cnV0aCB0ZXN0LiBBbGlhc2VkIGFzIGBkZXRlY3RgLlxuICBfLmZpbmQgPSBfLmRldGVjdCA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdDtcbiAgICBwcmVkaWNhdGUgPSBfLml0ZXJhdGVlKHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgXy5zb21lKG9iaiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBsaXN0KSB7XG4gICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgbGlzdCkpIHtcbiAgICAgICAgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gUmV0dXJuIGFsbCB0aGUgZWxlbWVudHMgdGhhdCBwYXNzIGEgdHJ1dGggdGVzdC5cbiAgLy8gQWxpYXNlZCBhcyBgc2VsZWN0YC5cbiAgXy5maWx0ZXIgPSBfLnNlbGVjdCA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiByZXN1bHRzO1xuICAgIHByZWRpY2F0ZSA9IF8uaXRlcmF0ZWUocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICBfLmVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBsaXN0KSkgcmVzdWx0cy5wdXNoKHZhbHVlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICAvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyBmb3Igd2hpY2ggYSB0cnV0aCB0ZXN0IGZhaWxzLlxuICBfLnJlamVjdCA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIF8uZmlsdGVyKG9iaiwgXy5uZWdhdGUoXy5pdGVyYXRlZShwcmVkaWNhdGUpKSwgY29udGV4dCk7XG4gIH07XG5cbiAgLy8gRGV0ZXJtaW5lIHdoZXRoZXIgYWxsIG9mIHRoZSBlbGVtZW50cyBtYXRjaCBhIHRydXRoIHRlc3QuXG4gIC8vIEFsaWFzZWQgYXMgYGFsbGAuXG4gIF8uZXZlcnkgPSBfLmFsbCA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgICBwcmVkaWNhdGUgPSBfLml0ZXJhdGVlKHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgdmFyIGtleXMgPSBvYmoubGVuZ3RoICE9PSArb2JqLmxlbmd0aCAmJiBfLmtleXMob2JqKSxcbiAgICAgICAgbGVuZ3RoID0gKGtleXMgfHwgb2JqKS5sZW5ndGgsXG4gICAgICAgIGluZGV4LCBjdXJyZW50S2V5O1xuICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgY3VycmVudEtleSA9IGtleXMgPyBrZXlzW2luZGV4XSA6IGluZGV4O1xuICAgICAgaWYgKCFwcmVkaWNhdGUob2JqW2N1cnJlbnRLZXldLCBjdXJyZW50S2V5LCBvYmopKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8vIERldGVybWluZSBpZiBhdCBsZWFzdCBvbmUgZWxlbWVudCBpbiB0aGUgb2JqZWN0IG1hdGNoZXMgYSB0cnV0aCB0ZXN0LlxuICAvLyBBbGlhc2VkIGFzIGBhbnlgLlxuICBfLnNvbWUgPSBfLmFueSA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgcHJlZGljYXRlID0gXy5pdGVyYXRlZShwcmVkaWNhdGUsIGNvbnRleHQpO1xuICAgIHZhciBrZXlzID0gb2JqLmxlbmd0aCAhPT0gK29iai5sZW5ndGggJiYgXy5rZXlzKG9iaiksXG4gICAgICAgIGxlbmd0aCA9IChrZXlzIHx8IG9iaikubGVuZ3RoLFxuICAgICAgICBpbmRleCwgY3VycmVudEtleTtcbiAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGN1cnJlbnRLZXkgPSBrZXlzID8ga2V5c1tpbmRleF0gOiBpbmRleDtcbiAgICAgIGlmIChwcmVkaWNhdGUob2JqW2N1cnJlbnRLZXldLCBjdXJyZW50S2V5LCBvYmopKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuXG4gIC8vIERldGVybWluZSBpZiB0aGUgYXJyYXkgb3Igb2JqZWN0IGNvbnRhaW5zIGEgZ2l2ZW4gdmFsdWUgKHVzaW5nIGA9PT1gKS5cbiAgLy8gQWxpYXNlZCBhcyBgaW5jbHVkZWAuXG4gIF8uY29udGFpbnMgPSBfLmluY2x1ZGUgPSBmdW5jdGlvbihvYmosIHRhcmdldCkge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChvYmoubGVuZ3RoICE9PSArb2JqLmxlbmd0aCkgb2JqID0gXy52YWx1ZXMob2JqKTtcbiAgICByZXR1cm4gXy5pbmRleE9mKG9iaiwgdGFyZ2V0KSA+PSAwO1xuICB9O1xuXG4gIC8vIEludm9rZSBhIG1ldGhvZCAod2l0aCBhcmd1bWVudHMpIG9uIGV2ZXJ5IGl0ZW0gaW4gYSBjb2xsZWN0aW9uLlxuICBfLmludm9rZSA9IGZ1bmN0aW9uKG9iaiwgbWV0aG9kKSB7XG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGlzRnVuYyA9IF8uaXNGdW5jdGlvbihtZXRob2QpO1xuICAgIHJldHVybiBfLm1hcChvYmosIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gKGlzRnVuYyA/IG1ldGhvZCA6IHZhbHVlW21ldGhvZF0pLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBDb252ZW5pZW5jZSB2ZXJzaW9uIG9mIGEgY29tbW9uIHVzZSBjYXNlIG9mIGBtYXBgOiBmZXRjaGluZyBhIHByb3BlcnR5LlxuICBfLnBsdWNrID0gZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICByZXR1cm4gXy5tYXAob2JqLCBfLnByb3BlcnR5KGtleSkpO1xuICB9O1xuXG4gIC8vIENvbnZlbmllbmNlIHZlcnNpb24gb2YgYSBjb21tb24gdXNlIGNhc2Ugb2YgYGZpbHRlcmA6IHNlbGVjdGluZyBvbmx5IG9iamVjdHNcbiAgLy8gY29udGFpbmluZyBzcGVjaWZpYyBga2V5OnZhbHVlYCBwYWlycy5cbiAgXy53aGVyZSA9IGZ1bmN0aW9uKG9iaiwgYXR0cnMpIHtcbiAgICByZXR1cm4gXy5maWx0ZXIob2JqLCBfLm1hdGNoZXMoYXR0cnMpKTtcbiAgfTtcblxuICAvLyBDb252ZW5pZW5jZSB2ZXJzaW9uIG9mIGEgY29tbW9uIHVzZSBjYXNlIG9mIGBmaW5kYDogZ2V0dGluZyB0aGUgZmlyc3Qgb2JqZWN0XG4gIC8vIGNvbnRhaW5pbmcgc3BlY2lmaWMgYGtleTp2YWx1ZWAgcGFpcnMuXG4gIF8uZmluZFdoZXJlID0gZnVuY3Rpb24ob2JqLCBhdHRycykge1xuICAgIHJldHVybiBfLmZpbmQob2JqLCBfLm1hdGNoZXMoYXR0cnMpKTtcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIG1heGltdW0gZWxlbWVudCAob3IgZWxlbWVudC1iYXNlZCBjb21wdXRhdGlvbikuXG4gIF8ubWF4ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgIHZhciByZXN1bHQgPSAtSW5maW5pdHksIGxhc3RDb21wdXRlZCA9IC1JbmZpbml0eSxcbiAgICAgICAgdmFsdWUsIGNvbXB1dGVkO1xuICAgIGlmIChpdGVyYXRlZSA9PSBudWxsICYmIG9iaiAhPSBudWxsKSB7XG4gICAgICBvYmogPSBvYmoubGVuZ3RoID09PSArb2JqLmxlbmd0aCA/IG9iaiA6IF8udmFsdWVzKG9iaik7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gb2JqLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhbHVlID0gb2JqW2ldO1xuICAgICAgICBpZiAodmFsdWUgPiByZXN1bHQpIHtcbiAgICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpdGVyYXRlZSA9IF8uaXRlcmF0ZWUoaXRlcmF0ZWUsIGNvbnRleHQpO1xuICAgICAgXy5lYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBsaXN0KSB7XG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUodmFsdWUsIGluZGV4LCBsaXN0KTtcbiAgICAgICAgaWYgKGNvbXB1dGVkID4gbGFzdENvbXB1dGVkIHx8IGNvbXB1dGVkID09PSAtSW5maW5pdHkgJiYgcmVzdWx0ID09PSAtSW5maW5pdHkpIHtcbiAgICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBsYXN0Q29tcHV0ZWQgPSBjb21wdXRlZDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBtaW5pbXVtIGVsZW1lbnQgKG9yIGVsZW1lbnQtYmFzZWQgY29tcHV0YXRpb24pLlxuICBfLm1pbiA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0ID0gSW5maW5pdHksIGxhc3RDb21wdXRlZCA9IEluZmluaXR5LFxuICAgICAgICB2YWx1ZSwgY29tcHV0ZWQ7XG4gICAgaWYgKGl0ZXJhdGVlID09IG51bGwgJiYgb2JqICE9IG51bGwpIHtcbiAgICAgIG9iaiA9IG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoID8gb2JqIDogXy52YWx1ZXMob2JqKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBvYmoubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFsdWUgPSBvYmpbaV07XG4gICAgICAgIGlmICh2YWx1ZSA8IHJlc3VsdCkge1xuICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGl0ZXJhdGVlID0gXy5pdGVyYXRlZShpdGVyYXRlZSwgY29udGV4dCk7XG4gICAgICBfLmVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSh2YWx1ZSwgaW5kZXgsIGxpc3QpO1xuICAgICAgICBpZiAoY29tcHV0ZWQgPCBsYXN0Q29tcHV0ZWQgfHwgY29tcHV0ZWQgPT09IEluZmluaXR5ICYmIHJlc3VsdCA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBsYXN0Q29tcHV0ZWQgPSBjb21wdXRlZDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gU2h1ZmZsZSBhIGNvbGxlY3Rpb24sIHVzaW5nIHRoZSBtb2Rlcm4gdmVyc2lvbiBvZiB0aGVcbiAgLy8gW0Zpc2hlci1ZYXRlcyBzaHVmZmxlXShodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Zpc2hlcuKAk1lhdGVzX3NodWZmbGUpLlxuICBfLnNodWZmbGUgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgc2V0ID0gb2JqICYmIG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoID8gb2JqIDogXy52YWx1ZXMob2JqKTtcbiAgICB2YXIgbGVuZ3RoID0gc2V0Lmxlbmd0aDtcbiAgICB2YXIgc2h1ZmZsZWQgPSBBcnJheShsZW5ndGgpO1xuICAgIGZvciAodmFyIGluZGV4ID0gMCwgcmFuZDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIHJhbmQgPSBfLnJhbmRvbSgwLCBpbmRleCk7XG4gICAgICBpZiAocmFuZCAhPT0gaW5kZXgpIHNodWZmbGVkW2luZGV4XSA9IHNodWZmbGVkW3JhbmRdO1xuICAgICAgc2h1ZmZsZWRbcmFuZF0gPSBzZXRbaW5kZXhdO1xuICAgIH1cbiAgICByZXR1cm4gc2h1ZmZsZWQ7XG4gIH07XG5cbiAgLy8gU2FtcGxlICoqbioqIHJhbmRvbSB2YWx1ZXMgZnJvbSBhIGNvbGxlY3Rpb24uXG4gIC8vIElmICoqbioqIGlzIG5vdCBzcGVjaWZpZWQsIHJldHVybnMgYSBzaW5nbGUgcmFuZG9tIGVsZW1lbnQuXG4gIC8vIFRoZSBpbnRlcm5hbCBgZ3VhcmRgIGFyZ3VtZW50IGFsbG93cyBpdCB0byB3b3JrIHdpdGggYG1hcGAuXG4gIF8uc2FtcGxlID0gZnVuY3Rpb24ob2JqLCBuLCBndWFyZCkge1xuICAgIGlmIChuID09IG51bGwgfHwgZ3VhcmQpIHtcbiAgICAgIGlmIChvYmoubGVuZ3RoICE9PSArb2JqLmxlbmd0aCkgb2JqID0gXy52YWx1ZXMob2JqKTtcbiAgICAgIHJldHVybiBvYmpbXy5yYW5kb20ob2JqLmxlbmd0aCAtIDEpXTtcbiAgICB9XG4gICAgcmV0dXJuIF8uc2h1ZmZsZShvYmopLnNsaWNlKDAsIE1hdGgubWF4KDAsIG4pKTtcbiAgfTtcblxuICAvLyBTb3J0IHRoZSBvYmplY3QncyB2YWx1ZXMgYnkgYSBjcml0ZXJpb24gcHJvZHVjZWQgYnkgYW4gaXRlcmF0ZWUuXG4gIF8uc29ydEJ5ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgIGl0ZXJhdGVlID0gXy5pdGVyYXRlZShpdGVyYXRlZSwgY29udGV4dCk7XG4gICAgcmV0dXJuIF8ucGx1Y2soXy5tYXAob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICBjcml0ZXJpYTogaXRlcmF0ZWUodmFsdWUsIGluZGV4LCBsaXN0KVxuICAgICAgfTtcbiAgICB9KS5zb3J0KGZ1bmN0aW9uKGxlZnQsIHJpZ2h0KSB7XG4gICAgICB2YXIgYSA9IGxlZnQuY3JpdGVyaWE7XG4gICAgICB2YXIgYiA9IHJpZ2h0LmNyaXRlcmlhO1xuICAgICAgaWYgKGEgIT09IGIpIHtcbiAgICAgICAgaWYgKGEgPiBiIHx8IGEgPT09IHZvaWQgMCkgcmV0dXJuIDE7XG4gICAgICAgIGlmIChhIDwgYiB8fCBiID09PSB2b2lkIDApIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBsZWZ0LmluZGV4IC0gcmlnaHQuaW5kZXg7XG4gICAgfSksICd2YWx1ZScpO1xuICB9O1xuXG4gIC8vIEFuIGludGVybmFsIGZ1bmN0aW9uIHVzZWQgZm9yIGFnZ3JlZ2F0ZSBcImdyb3VwIGJ5XCIgb3BlcmF0aW9ucy5cbiAgdmFyIGdyb3VwID0gZnVuY3Rpb24oYmVoYXZpb3IpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgaXRlcmF0ZWUgPSBfLml0ZXJhdGVlKGl0ZXJhdGVlLCBjb250ZXh0KTtcbiAgICAgIF8uZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgICB2YXIga2V5ID0gaXRlcmF0ZWUodmFsdWUsIGluZGV4LCBvYmopO1xuICAgICAgICBiZWhhdmlvcihyZXN1bHQsIHZhbHVlLCBrZXkpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH07XG5cbiAgLy8gR3JvdXBzIHRoZSBvYmplY3QncyB2YWx1ZXMgYnkgYSBjcml0ZXJpb24uIFBhc3MgZWl0aGVyIGEgc3RyaW5nIGF0dHJpYnV0ZVxuICAvLyB0byBncm91cCBieSwgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIGNyaXRlcmlvbi5cbiAgXy5ncm91cEJ5ID0gZ3JvdXAoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgaWYgKF8uaGFzKHJlc3VsdCwga2V5KSkgcmVzdWx0W2tleV0ucHVzaCh2YWx1ZSk7IGVsc2UgcmVzdWx0W2tleV0gPSBbdmFsdWVdO1xuICB9KTtcblxuICAvLyBJbmRleGVzIHRoZSBvYmplY3QncyB2YWx1ZXMgYnkgYSBjcml0ZXJpb24sIHNpbWlsYXIgdG8gYGdyb3VwQnlgLCBidXQgZm9yXG4gIC8vIHdoZW4geW91IGtub3cgdGhhdCB5b3VyIGluZGV4IHZhbHVlcyB3aWxsIGJlIHVuaXF1ZS5cbiAgXy5pbmRleEJ5ID0gZ3JvdXAoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgcmVzdWx0W2tleV0gPSB2YWx1ZTtcbiAgfSk7XG5cbiAgLy8gQ291bnRzIGluc3RhbmNlcyBvZiBhbiBvYmplY3QgdGhhdCBncm91cCBieSBhIGNlcnRhaW4gY3JpdGVyaW9uLiBQYXNzXG4gIC8vIGVpdGhlciBhIHN0cmluZyBhdHRyaWJ1dGUgdG8gY291bnQgYnksIG9yIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZVxuICAvLyBjcml0ZXJpb24uXG4gIF8uY291bnRCeSA9IGdyb3VwKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgIGlmIChfLmhhcyhyZXN1bHQsIGtleSkpIHJlc3VsdFtrZXldKys7IGVsc2UgcmVzdWx0W2tleV0gPSAxO1xuICB9KTtcblxuICAvLyBVc2UgYSBjb21wYXJhdG9yIGZ1bmN0aW9uIHRvIGZpZ3VyZSBvdXQgdGhlIHNtYWxsZXN0IGluZGV4IGF0IHdoaWNoXG4gIC8vIGFuIG9iamVjdCBzaG91bGQgYmUgaW5zZXJ0ZWQgc28gYXMgdG8gbWFpbnRhaW4gb3JkZXIuIFVzZXMgYmluYXJ5IHNlYXJjaC5cbiAgXy5zb3J0ZWRJbmRleCA9IGZ1bmN0aW9uKGFycmF5LCBvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgaXRlcmF0ZWUgPSBfLml0ZXJhdGVlKGl0ZXJhdGVlLCBjb250ZXh0LCAxKTtcbiAgICB2YXIgdmFsdWUgPSBpdGVyYXRlZShvYmopO1xuICAgIHZhciBsb3cgPSAwLCBoaWdoID0gYXJyYXkubGVuZ3RoO1xuICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICB2YXIgbWlkID0gbG93ICsgaGlnaCA+Pj4gMTtcbiAgICAgIGlmIChpdGVyYXRlZShhcnJheVttaWRdKSA8IHZhbHVlKSBsb3cgPSBtaWQgKyAxOyBlbHNlIGhpZ2ggPSBtaWQ7XG4gICAgfVxuICAgIHJldHVybiBsb3c7XG4gIH07XG5cbiAgLy8gU2FmZWx5IGNyZWF0ZSBhIHJlYWwsIGxpdmUgYXJyYXkgZnJvbSBhbnl0aGluZyBpdGVyYWJsZS5cbiAgXy50b0FycmF5ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFvYmopIHJldHVybiBbXTtcbiAgICBpZiAoXy5pc0FycmF5KG9iaikpIHJldHVybiBzbGljZS5jYWxsKG9iaik7XG4gICAgaWYgKG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoKSByZXR1cm4gXy5tYXAob2JqLCBfLmlkZW50aXR5KTtcbiAgICByZXR1cm4gXy52YWx1ZXMob2JqKTtcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBhbiBvYmplY3QuXG4gIF8uc2l6ZSA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIDA7XG4gICAgcmV0dXJuIG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoID8gb2JqLmxlbmd0aCA6IF8ua2V5cyhvYmopLmxlbmd0aDtcbiAgfTtcblxuICAvLyBTcGxpdCBhIGNvbGxlY3Rpb24gaW50byB0d28gYXJyYXlzOiBvbmUgd2hvc2UgZWxlbWVudHMgYWxsIHNhdGlzZnkgdGhlIGdpdmVuXG4gIC8vIHByZWRpY2F0ZSwgYW5kIG9uZSB3aG9zZSBlbGVtZW50cyBhbGwgZG8gbm90IHNhdGlzZnkgdGhlIHByZWRpY2F0ZS5cbiAgXy5wYXJ0aXRpb24gPSBmdW5jdGlvbihvYmosIHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgIHByZWRpY2F0ZSA9IF8uaXRlcmF0ZWUocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICB2YXIgcGFzcyA9IFtdLCBmYWlsID0gW107XG4gICAgXy5lYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGtleSwgb2JqKSB7XG4gICAgICAocHJlZGljYXRlKHZhbHVlLCBrZXksIG9iaikgPyBwYXNzIDogZmFpbCkucHVzaCh2YWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIFtwYXNzLCBmYWlsXTtcbiAgfTtcblxuICAvLyBBcnJheSBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gR2V0IHRoZSBmaXJzdCBlbGVtZW50IG9mIGFuIGFycmF5LiBQYXNzaW5nICoqbioqIHdpbGwgcmV0dXJuIHRoZSBmaXJzdCBOXG4gIC8vIHZhbHVlcyBpbiB0aGUgYXJyYXkuIEFsaWFzZWQgYXMgYGhlYWRgIGFuZCBgdGFrZWAuIFRoZSAqKmd1YXJkKiogY2hlY2tcbiAgLy8gYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgXy5tYXBgLlxuICBfLmZpcnN0ID0gXy5oZWFkID0gXy50YWtlID0gZnVuY3Rpb24oYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiB2b2lkIDA7XG4gICAgaWYgKG4gPT0gbnVsbCB8fCBndWFyZCkgcmV0dXJuIGFycmF5WzBdO1xuICAgIGlmIChuIDwgMCkgcmV0dXJuIFtdO1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCAwLCBuKTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGV2ZXJ5dGhpbmcgYnV0IHRoZSBsYXN0IGVudHJ5IG9mIHRoZSBhcnJheS4gRXNwZWNpYWxseSB1c2VmdWwgb25cbiAgLy8gdGhlIGFyZ3VtZW50cyBvYmplY3QuIFBhc3NpbmcgKipuKiogd2lsbCByZXR1cm4gYWxsIHRoZSB2YWx1ZXMgaW5cbiAgLy8gdGhlIGFycmF5LCBleGNsdWRpbmcgdGhlIGxhc3QgTi4gVGhlICoqZ3VhcmQqKiBjaGVjayBhbGxvd3MgaXQgdG8gd29yayB3aXRoXG4gIC8vIGBfLm1hcGAuXG4gIF8uaW5pdGlhbCA9IGZ1bmN0aW9uKGFycmF5LCBuLCBndWFyZCkge1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCAwLCBNYXRoLm1heCgwLCBhcnJheS5sZW5ndGggLSAobiA9PSBudWxsIHx8IGd1YXJkID8gMSA6IG4pKSk7XG4gIH07XG5cbiAgLy8gR2V0IHRoZSBsYXN0IGVsZW1lbnQgb2YgYW4gYXJyYXkuIFBhc3NpbmcgKipuKiogd2lsbCByZXR1cm4gdGhlIGxhc3QgTlxuICAvLyB2YWx1ZXMgaW4gdGhlIGFycmF5LiBUaGUgKipndWFyZCoqIGNoZWNrIGFsbG93cyBpdCB0byB3b3JrIHdpdGggYF8ubWFwYC5cbiAgXy5sYXN0ID0gZnVuY3Rpb24oYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiB2b2lkIDA7XG4gICAgaWYgKG4gPT0gbnVsbCB8fCBndWFyZCkgcmV0dXJuIGFycmF5W2FycmF5Lmxlbmd0aCAtIDFdO1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCBNYXRoLm1heChhcnJheS5sZW5ndGggLSBuLCAwKSk7XG4gIH07XG5cbiAgLy8gUmV0dXJucyBldmVyeXRoaW5nIGJ1dCB0aGUgZmlyc3QgZW50cnkgb2YgdGhlIGFycmF5LiBBbGlhc2VkIGFzIGB0YWlsYCBhbmQgYGRyb3BgLlxuICAvLyBFc3BlY2lhbGx5IHVzZWZ1bCBvbiB0aGUgYXJndW1lbnRzIG9iamVjdC4gUGFzc2luZyBhbiAqKm4qKiB3aWxsIHJldHVyblxuICAvLyB0aGUgcmVzdCBOIHZhbHVlcyBpbiB0aGUgYXJyYXkuIFRoZSAqKmd1YXJkKipcbiAgLy8gY2hlY2sgYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgXy5tYXBgLlxuICBfLnJlc3QgPSBfLnRhaWwgPSBfLmRyb3AgPSBmdW5jdGlvbihhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICByZXR1cm4gc2xpY2UuY2FsbChhcnJheSwgbiA9PSBudWxsIHx8IGd1YXJkID8gMSA6IG4pO1xuICB9O1xuXG4gIC8vIFRyaW0gb3V0IGFsbCBmYWxzeSB2YWx1ZXMgZnJvbSBhbiBhcnJheS5cbiAgXy5jb21wYWN0ID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICByZXR1cm4gXy5maWx0ZXIoYXJyYXksIF8uaWRlbnRpdHkpO1xuICB9O1xuXG4gIC8vIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIGEgcmVjdXJzaXZlIGBmbGF0dGVuYCBmdW5jdGlvbi5cbiAgdmFyIGZsYXR0ZW4gPSBmdW5jdGlvbihpbnB1dCwgc2hhbGxvdywgc3RyaWN0LCBvdXRwdXQpIHtcbiAgICBpZiAoc2hhbGxvdyAmJiBfLmV2ZXJ5KGlucHV0LCBfLmlzQXJyYXkpKSB7XG4gICAgICByZXR1cm4gY29uY2F0LmFwcGx5KG91dHB1dCwgaW5wdXQpO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gaW5wdXQubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciB2YWx1ZSA9IGlucHV0W2ldO1xuICAgICAgaWYgKCFfLmlzQXJyYXkodmFsdWUpICYmICFfLmlzQXJndW1lbnRzKHZhbHVlKSkge1xuICAgICAgICBpZiAoIXN0cmljdCkgb3V0cHV0LnB1c2godmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChzaGFsbG93KSB7XG4gICAgICAgIHB1c2guYXBwbHkob3V0cHV0LCB2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmbGF0dGVuKHZhbHVlLCBzaGFsbG93LCBzdHJpY3QsIG91dHB1dCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH07XG5cbiAgLy8gRmxhdHRlbiBvdXQgYW4gYXJyYXksIGVpdGhlciByZWN1cnNpdmVseSAoYnkgZGVmYXVsdCksIG9yIGp1c3Qgb25lIGxldmVsLlxuICBfLmZsYXR0ZW4gPSBmdW5jdGlvbihhcnJheSwgc2hhbGxvdykge1xuICAgIHJldHVybiBmbGF0dGVuKGFycmF5LCBzaGFsbG93LCBmYWxzZSwgW10pO1xuICB9O1xuXG4gIC8vIFJldHVybiBhIHZlcnNpb24gb2YgdGhlIGFycmF5IHRoYXQgZG9lcyBub3QgY29udGFpbiB0aGUgc3BlY2lmaWVkIHZhbHVlKHMpLlxuICBfLndpdGhvdXQgPSBmdW5jdGlvbihhcnJheSkge1xuICAgIHJldHVybiBfLmRpZmZlcmVuY2UoYXJyYXksIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XG4gIH07XG5cbiAgLy8gUHJvZHVjZSBhIGR1cGxpY2F0ZS1mcmVlIHZlcnNpb24gb2YgdGhlIGFycmF5LiBJZiB0aGUgYXJyYXkgaGFzIGFscmVhZHlcbiAgLy8gYmVlbiBzb3J0ZWQsIHlvdSBoYXZlIHRoZSBvcHRpb24gb2YgdXNpbmcgYSBmYXN0ZXIgYWxnb3JpdGhtLlxuICAvLyBBbGlhc2VkIGFzIGB1bmlxdWVgLlxuICBfLnVuaXEgPSBfLnVuaXF1ZSA9IGZ1bmN0aW9uKGFycmF5LCBpc1NvcnRlZCwgaXRlcmF0ZWUsIGNvbnRleHQpIHtcbiAgICBpZiAoYXJyYXkgPT0gbnVsbCkgcmV0dXJuIFtdO1xuICAgIGlmICghXy5pc0Jvb2xlYW4oaXNTb3J0ZWQpKSB7XG4gICAgICBjb250ZXh0ID0gaXRlcmF0ZWU7XG4gICAgICBpdGVyYXRlZSA9IGlzU29ydGVkO1xuICAgICAgaXNTb3J0ZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGl0ZXJhdGVlICE9IG51bGwpIGl0ZXJhdGVlID0gXy5pdGVyYXRlZShpdGVyYXRlZSwgY29udGV4dCk7XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIHZhciBzZWVuID0gW107XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcnJheVtpXTtcbiAgICAgIGlmIChpc1NvcnRlZCkge1xuICAgICAgICBpZiAoIWkgfHwgc2VlbiAhPT0gdmFsdWUpIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgc2VlbiA9IHZhbHVlO1xuICAgICAgfSBlbHNlIGlmIChpdGVyYXRlZSkge1xuICAgICAgICB2YXIgY29tcHV0ZWQgPSBpdGVyYXRlZSh2YWx1ZSwgaSwgYXJyYXkpO1xuICAgICAgICBpZiAoXy5pbmRleE9mKHNlZW4sIGNvbXB1dGVkKSA8IDApIHtcbiAgICAgICAgICBzZWVuLnB1c2goY29tcHV0ZWQpO1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChfLmluZGV4T2YocmVzdWx0LCB2YWx1ZSkgPCAwKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBQcm9kdWNlIGFuIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIHVuaW9uOiBlYWNoIGRpc3RpbmN0IGVsZW1lbnQgZnJvbSBhbGwgb2ZcbiAgLy8gdGhlIHBhc3NlZC1pbiBhcnJheXMuXG4gIF8udW5pb24gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXy51bmlxKGZsYXR0ZW4oYXJndW1lbnRzLCB0cnVlLCB0cnVlLCBbXSkpO1xuICB9O1xuXG4gIC8vIFByb2R1Y2UgYW4gYXJyYXkgdGhhdCBjb250YWlucyBldmVyeSBpdGVtIHNoYXJlZCBiZXR3ZWVuIGFsbCB0aGVcbiAgLy8gcGFzc2VkLWluIGFycmF5cy5cbiAgXy5pbnRlcnNlY3Rpb24gPSBmdW5jdGlvbihhcnJheSkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gW107XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIHZhciBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBpdGVtID0gYXJyYXlbaV07XG4gICAgICBpZiAoXy5jb250YWlucyhyZXN1bHQsIGl0ZW0pKSBjb250aW51ZTtcbiAgICAgIGZvciAodmFyIGogPSAxOyBqIDwgYXJnc0xlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmICghXy5jb250YWlucyhhcmd1bWVudHNbal0sIGl0ZW0pKSBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChqID09PSBhcmdzTGVuZ3RoKSByZXN1bHQucHVzaChpdGVtKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBUYWtlIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gb25lIGFycmF5IGFuZCBhIG51bWJlciBvZiBvdGhlciBhcnJheXMuXG4gIC8vIE9ubHkgdGhlIGVsZW1lbnRzIHByZXNlbnQgaW4ganVzdCB0aGUgZmlyc3QgYXJyYXkgd2lsbCByZW1haW4uXG4gIF8uZGlmZmVyZW5jZSA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgdmFyIHJlc3QgPSBmbGF0dGVuKHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSwgdHJ1ZSwgdHJ1ZSwgW10pO1xuICAgIHJldHVybiBfLmZpbHRlcihhcnJheSwgZnVuY3Rpb24odmFsdWUpe1xuICAgICAgcmV0dXJuICFfLmNvbnRhaW5zKHJlc3QsIHZhbHVlKTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBaaXAgdG9nZXRoZXIgbXVsdGlwbGUgbGlzdHMgaW50byBhIHNpbmdsZSBhcnJheSAtLSBlbGVtZW50cyB0aGF0IHNoYXJlXG4gIC8vIGFuIGluZGV4IGdvIHRvZ2V0aGVyLlxuICBfLnppcCA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiBbXTtcbiAgICB2YXIgbGVuZ3RoID0gXy5tYXgoYXJndW1lbnRzLCAnbGVuZ3RoJykubGVuZ3RoO1xuICAgIHZhciByZXN1bHRzID0gQXJyYXkobGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHRzW2ldID0gXy5wbHVjayhhcmd1bWVudHMsIGkpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICAvLyBDb252ZXJ0cyBsaXN0cyBpbnRvIG9iamVjdHMuIFBhc3MgZWl0aGVyIGEgc2luZ2xlIGFycmF5IG9mIGBba2V5LCB2YWx1ZV1gXG4gIC8vIHBhaXJzLCBvciB0d28gcGFyYWxsZWwgYXJyYXlzIG9mIHRoZSBzYW1lIGxlbmd0aCAtLSBvbmUgb2Yga2V5cywgYW5kIG9uZSBvZlxuICAvLyB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gIF8ub2JqZWN0ID0gZnVuY3Rpb24obGlzdCwgdmFsdWVzKSB7XG4gICAgaWYgKGxpc3QgPT0gbnVsbCkgcmV0dXJuIHt9O1xuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gbGlzdC5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHZhbHVlcykge1xuICAgICAgICByZXN1bHRbbGlzdFtpXV0gPSB2YWx1ZXNbaV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRbbGlzdFtpXVswXV0gPSBsaXN0W2ldWzFdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYW4gaXRlbSBpbiBhbiBhcnJheSxcbiAgLy8gb3IgLTEgaWYgdGhlIGl0ZW0gaXMgbm90IGluY2x1ZGVkIGluIHRoZSBhcnJheS5cbiAgLy8gSWYgdGhlIGFycmF5IGlzIGxhcmdlIGFuZCBhbHJlYWR5IGluIHNvcnQgb3JkZXIsIHBhc3MgYHRydWVgXG4gIC8vIGZvciAqKmlzU29ydGVkKiogdG8gdXNlIGJpbmFyeSBzZWFyY2guXG4gIF8uaW5kZXhPZiA9IGZ1bmN0aW9uKGFycmF5LCBpdGVtLCBpc1NvcnRlZCkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gLTE7XG4gICAgdmFyIGkgPSAwLCBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgaWYgKGlzU29ydGVkKSB7XG4gICAgICBpZiAodHlwZW9mIGlzU29ydGVkID09ICdudW1iZXInKSB7XG4gICAgICAgIGkgPSBpc1NvcnRlZCA8IDAgPyBNYXRoLm1heCgwLCBsZW5ndGggKyBpc1NvcnRlZCkgOiBpc1NvcnRlZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGkgPSBfLnNvcnRlZEluZGV4KGFycmF5LCBpdGVtKTtcbiAgICAgICAgcmV0dXJuIGFycmF5W2ldID09PSBpdGVtID8gaSA6IC0xO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSBpZiAoYXJyYXlbaV0gPT09IGl0ZW0pIHJldHVybiBpO1xuICAgIHJldHVybiAtMTtcbiAgfTtcblxuICBfLmxhc3RJbmRleE9mID0gZnVuY3Rpb24oYXJyYXksIGl0ZW0sIGZyb20pIHtcbiAgICBpZiAoYXJyYXkgPT0gbnVsbCkgcmV0dXJuIC0xO1xuICAgIHZhciBpZHggPSBhcnJheS5sZW5ndGg7XG4gICAgaWYgKHR5cGVvZiBmcm9tID09ICdudW1iZXInKSB7XG4gICAgICBpZHggPSBmcm9tIDwgMCA/IGlkeCArIGZyb20gKyAxIDogTWF0aC5taW4oaWR4LCBmcm9tICsgMSk7XG4gICAgfVxuICAgIHdoaWxlICgtLWlkeCA+PSAwKSBpZiAoYXJyYXlbaWR4XSA9PT0gaXRlbSkgcmV0dXJuIGlkeDtcbiAgICByZXR1cm4gLTE7XG4gIH07XG5cbiAgLy8gR2VuZXJhdGUgYW4gaW50ZWdlciBBcnJheSBjb250YWluaW5nIGFuIGFyaXRobWV0aWMgcHJvZ3Jlc3Npb24uIEEgcG9ydCBvZlxuICAvLyB0aGUgbmF0aXZlIFB5dGhvbiBgcmFuZ2UoKWAgZnVuY3Rpb24uIFNlZVxuICAvLyBbdGhlIFB5dGhvbiBkb2N1bWVudGF0aW9uXShodHRwOi8vZG9jcy5weXRob24ub3JnL2xpYnJhcnkvZnVuY3Rpb25zLmh0bWwjcmFuZ2UpLlxuICBfLnJhbmdlID0gZnVuY3Rpb24oc3RhcnQsIHN0b3AsIHN0ZXApIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8PSAxKSB7XG4gICAgICBzdG9wID0gc3RhcnQgfHwgMDtcbiAgICAgIHN0YXJ0ID0gMDtcbiAgICB9XG4gICAgc3RlcCA9IHN0ZXAgfHwgMTtcblxuICAgIHZhciBsZW5ndGggPSBNYXRoLm1heChNYXRoLmNlaWwoKHN0b3AgLSBzdGFydCkgLyBzdGVwKSwgMCk7XG4gICAgdmFyIHJhbmdlID0gQXJyYXkobGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGlkeCA9IDA7IGlkeCA8IGxlbmd0aDsgaWR4KyssIHN0YXJ0ICs9IHN0ZXApIHtcbiAgICAgIHJhbmdlW2lkeF0gPSBzdGFydDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmFuZ2U7XG4gIH07XG5cbiAgLy8gRnVuY3Rpb24gKGFoZW0pIEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBSZXVzYWJsZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBmb3IgcHJvdG90eXBlIHNldHRpbmcuXG4gIHZhciBDdG9yID0gZnVuY3Rpb24oKXt9O1xuXG4gIC8vIENyZWF0ZSBhIGZ1bmN0aW9uIGJvdW5kIHRvIGEgZ2l2ZW4gb2JqZWN0IChhc3NpZ25pbmcgYHRoaXNgLCBhbmQgYXJndW1lbnRzLFxuICAvLyBvcHRpb25hbGx5KS4gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYEZ1bmN0aW9uLmJpbmRgIGlmXG4gIC8vIGF2YWlsYWJsZS5cbiAgXy5iaW5kID0gZnVuY3Rpb24oZnVuYywgY29udGV4dCkge1xuICAgIHZhciBhcmdzLCBib3VuZDtcbiAgICBpZiAobmF0aXZlQmluZCAmJiBmdW5jLmJpbmQgPT09IG5hdGl2ZUJpbmQpIHJldHVybiBuYXRpdmVCaW5kLmFwcGx5KGZ1bmMsIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XG4gICAgaWYgKCFfLmlzRnVuY3Rpb24oZnVuYykpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0JpbmQgbXVzdCBiZSBjYWxsZWQgb24gYSBmdW5jdGlvbicpO1xuICAgIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgYm91bmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBib3VuZCkpIHJldHVybiBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MuY29uY2F0KHNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xuICAgICAgQ3Rvci5wcm90b3R5cGUgPSBmdW5jLnByb3RvdHlwZTtcbiAgICAgIHZhciBzZWxmID0gbmV3IEN0b3I7XG4gICAgICBDdG9yLnByb3RvdHlwZSA9IG51bGw7XG4gICAgICB2YXIgcmVzdWx0ID0gZnVuYy5hcHBseShzZWxmLCBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgIGlmIChfLmlzT2JqZWN0KHJlc3VsdCkpIHJldHVybiByZXN1bHQ7XG4gICAgICByZXR1cm4gc2VsZjtcbiAgICB9O1xuICAgIHJldHVybiBib3VuZDtcbiAgfTtcblxuICAvLyBQYXJ0aWFsbHkgYXBwbHkgYSBmdW5jdGlvbiBieSBjcmVhdGluZyBhIHZlcnNpb24gdGhhdCBoYXMgaGFkIHNvbWUgb2YgaXRzXG4gIC8vIGFyZ3VtZW50cyBwcmUtZmlsbGVkLCB3aXRob3V0IGNoYW5naW5nIGl0cyBkeW5hbWljIGB0aGlzYCBjb250ZXh0LiBfIGFjdHNcbiAgLy8gYXMgYSBwbGFjZWhvbGRlciwgYWxsb3dpbmcgYW55IGNvbWJpbmF0aW9uIG9mIGFyZ3VtZW50cyB0byBiZSBwcmUtZmlsbGVkLlxuICBfLnBhcnRpYWwgPSBmdW5jdGlvbihmdW5jKSB7XG4gICAgdmFyIGJvdW5kQXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcG9zaXRpb24gPSAwO1xuICAgICAgdmFyIGFyZ3MgPSBib3VuZEFyZ3Muc2xpY2UoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBhcmdzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChhcmdzW2ldID09PSBfKSBhcmdzW2ldID0gYXJndW1lbnRzW3Bvc2l0aW9uKytdO1xuICAgICAgfVxuICAgICAgd2hpbGUgKHBvc2l0aW9uIDwgYXJndW1lbnRzLmxlbmd0aCkgYXJncy5wdXNoKGFyZ3VtZW50c1twb3NpdGlvbisrXSk7XG4gICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9O1xuICB9O1xuXG4gIC8vIEJpbmQgYSBudW1iZXIgb2YgYW4gb2JqZWN0J3MgbWV0aG9kcyB0byB0aGF0IG9iamVjdC4gUmVtYWluaW5nIGFyZ3VtZW50c1xuICAvLyBhcmUgdGhlIG1ldGhvZCBuYW1lcyB0byBiZSBib3VuZC4gVXNlZnVsIGZvciBlbnN1cmluZyB0aGF0IGFsbCBjYWxsYmFja3NcbiAgLy8gZGVmaW5lZCBvbiBhbiBvYmplY3QgYmVsb25nIHRvIGl0LlxuICBfLmJpbmRBbGwgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgaSwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCwga2V5O1xuICAgIGlmIChsZW5ndGggPD0gMSkgdGhyb3cgbmV3IEVycm9yKCdiaW5kQWxsIG11c3QgYmUgcGFzc2VkIGZ1bmN0aW9uIG5hbWVzJyk7XG4gICAgZm9yIChpID0gMTsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBrZXkgPSBhcmd1bWVudHNbaV07XG4gICAgICBvYmpba2V5XSA9IF8uYmluZChvYmpba2V5XSwgb2JqKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfTtcblxuICAvLyBNZW1vaXplIGFuIGV4cGVuc2l2ZSBmdW5jdGlvbiBieSBzdG9yaW5nIGl0cyByZXN1bHRzLlxuICBfLm1lbW9pemUgPSBmdW5jdGlvbihmdW5jLCBoYXNoZXIpIHtcbiAgICB2YXIgbWVtb2l6ZSA9IGZ1bmN0aW9uKGtleSkge1xuICAgICAgdmFyIGNhY2hlID0gbWVtb2l6ZS5jYWNoZTtcbiAgICAgIHZhciBhZGRyZXNzID0gaGFzaGVyID8gaGFzaGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiBrZXk7XG4gICAgICBpZiAoIV8uaGFzKGNhY2hlLCBhZGRyZXNzKSkgY2FjaGVbYWRkcmVzc10gPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gY2FjaGVbYWRkcmVzc107XG4gICAgfTtcbiAgICBtZW1vaXplLmNhY2hlID0ge307XG4gICAgcmV0dXJuIG1lbW9pemU7XG4gIH07XG5cbiAgLy8gRGVsYXlzIGEgZnVuY3Rpb24gZm9yIHRoZSBnaXZlbiBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLCBhbmQgdGhlbiBjYWxsc1xuICAvLyBpdCB3aXRoIHRoZSBhcmd1bWVudHMgc3VwcGxpZWQuXG4gIF8uZGVsYXkgPSBmdW5jdGlvbihmdW5jLCB3YWl0KSB7XG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIHJldHVybiBmdW5jLmFwcGx5KG51bGwsIGFyZ3MpO1xuICAgIH0sIHdhaXQpO1xuICB9O1xuXG4gIC8vIERlZmVycyBhIGZ1bmN0aW9uLCBzY2hlZHVsaW5nIGl0IHRvIHJ1biBhZnRlciB0aGUgY3VycmVudCBjYWxsIHN0YWNrIGhhc1xuICAvLyBjbGVhcmVkLlxuICBfLmRlZmVyID0gZnVuY3Rpb24oZnVuYykge1xuICAgIHJldHVybiBfLmRlbGF5LmFwcGx5KF8sIFtmdW5jLCAxXS5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKSk7XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uLCB0aGF0LCB3aGVuIGludm9rZWQsIHdpbGwgb25seSBiZSB0cmlnZ2VyZWQgYXQgbW9zdCBvbmNlXG4gIC8vIGR1cmluZyBhIGdpdmVuIHdpbmRvdyBvZiB0aW1lLiBOb3JtYWxseSwgdGhlIHRocm90dGxlZCBmdW5jdGlvbiB3aWxsIHJ1blxuICAvLyBhcyBtdWNoIGFzIGl0IGNhbiwgd2l0aG91dCBldmVyIGdvaW5nIG1vcmUgdGhhbiBvbmNlIHBlciBgd2FpdGAgZHVyYXRpb247XG4gIC8vIGJ1dCBpZiB5b3UnZCBsaWtlIHRvIGRpc2FibGUgdGhlIGV4ZWN1dGlvbiBvbiB0aGUgbGVhZGluZyBlZGdlLCBwYXNzXG4gIC8vIGB7bGVhZGluZzogZmFsc2V9YC4gVG8gZGlzYWJsZSBleGVjdXRpb24gb24gdGhlIHRyYWlsaW5nIGVkZ2UsIGRpdHRvLlxuICBfLnRocm90dGxlID0gZnVuY3Rpb24oZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICAgIHZhciBjb250ZXh0LCBhcmdzLCByZXN1bHQ7XG4gICAgdmFyIHRpbWVvdXQgPSBudWxsO1xuICAgIHZhciBwcmV2aW91cyA9IDA7XG4gICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgdmFyIGxhdGVyID0gZnVuY3Rpb24oKSB7XG4gICAgICBwcmV2aW91cyA9IG9wdGlvbnMubGVhZGluZyA9PT0gZmFsc2UgPyAwIDogXy5ub3coKTtcbiAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgIGlmICghdGltZW91dCkgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG5vdyA9IF8ubm93KCk7XG4gICAgICBpZiAoIXByZXZpb3VzICYmIG9wdGlvbnMubGVhZGluZyA9PT0gZmFsc2UpIHByZXZpb3VzID0gbm93O1xuICAgICAgdmFyIHJlbWFpbmluZyA9IHdhaXQgLSAobm93IC0gcHJldmlvdXMpO1xuICAgICAgY29udGV4dCA9IHRoaXM7XG4gICAgICBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgaWYgKHJlbWFpbmluZyA8PSAwIHx8IHJlbWFpbmluZyA+IHdhaXQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgcHJldmlvdXMgPSBub3c7XG4gICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgIGlmICghdGltZW91dCkgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgICAgfSBlbHNlIGlmICghdGltZW91dCAmJiBvcHRpb25zLnRyYWlsaW5nICE9PSBmYWxzZSkge1xuICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgcmVtYWluaW5nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24sIHRoYXQsIGFzIGxvbmcgYXMgaXQgY29udGludWVzIHRvIGJlIGludm9rZWQsIHdpbGwgbm90XG4gIC8vIGJlIHRyaWdnZXJlZC4gVGhlIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGl0IHN0b3BzIGJlaW5nIGNhbGxlZCBmb3JcbiAgLy8gTiBtaWxsaXNlY29uZHMuIElmIGBpbW1lZGlhdGVgIGlzIHBhc3NlZCwgdHJpZ2dlciB0aGUgZnVuY3Rpb24gb24gdGhlXG4gIC8vIGxlYWRpbmcgZWRnZSwgaW5zdGVhZCBvZiB0aGUgdHJhaWxpbmcuXG4gIF8uZGVib3VuY2UgPSBmdW5jdGlvbihmdW5jLCB3YWl0LCBpbW1lZGlhdGUpIHtcbiAgICB2YXIgdGltZW91dCwgYXJncywgY29udGV4dCwgdGltZXN0YW1wLCByZXN1bHQ7XG5cbiAgICB2YXIgbGF0ZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBsYXN0ID0gXy5ub3coKSAtIHRpbWVzdGFtcDtcblxuICAgICAgaWYgKGxhc3QgPCB3YWl0ICYmIGxhc3QgPiAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCB3YWl0IC0gbGFzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgaWYgKCFpbW1lZGlhdGUpIHtcbiAgICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgICAgICAgIGlmICghdGltZW91dCkgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnRleHQgPSB0aGlzO1xuICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgIHRpbWVzdGFtcCA9IF8ubm93KCk7XG4gICAgICB2YXIgY2FsbE5vdyA9IGltbWVkaWF0ZSAmJiAhdGltZW91dDtcbiAgICAgIGlmICghdGltZW91dCkgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpO1xuICAgICAgaWYgKGNhbGxOb3cpIHtcbiAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyB0aGUgZmlyc3QgZnVuY3Rpb24gcGFzc2VkIGFzIGFuIGFyZ3VtZW50IHRvIHRoZSBzZWNvbmQsXG4gIC8vIGFsbG93aW5nIHlvdSB0byBhZGp1c3QgYXJndW1lbnRzLCBydW4gY29kZSBiZWZvcmUgYW5kIGFmdGVyLCBhbmRcbiAgLy8gY29uZGl0aW9uYWxseSBleGVjdXRlIHRoZSBvcmlnaW5hbCBmdW5jdGlvbi5cbiAgXy53cmFwID0gZnVuY3Rpb24oZnVuYywgd3JhcHBlcikge1xuICAgIHJldHVybiBfLnBhcnRpYWwod3JhcHBlciwgZnVuYyk7XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIG5lZ2F0ZWQgdmVyc2lvbiBvZiB0aGUgcGFzc2VkLWluIHByZWRpY2F0ZS5cbiAgXy5uZWdhdGUgPSBmdW5jdGlvbihwcmVkaWNhdGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gIXByZWRpY2F0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIGEgbGlzdCBvZiBmdW5jdGlvbnMsIGVhY2hcbiAgLy8gY29uc3VtaW5nIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZ1bmN0aW9uIHRoYXQgZm9sbG93cy5cbiAgXy5jb21wb3NlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgdmFyIHN0YXJ0ID0gYXJncy5sZW5ndGggLSAxO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpID0gc3RhcnQ7XG4gICAgICB2YXIgcmVzdWx0ID0gYXJnc1tzdGFydF0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHdoaWxlIChpLS0pIHJlc3VsdCA9IGFyZ3NbaV0uY2FsbCh0aGlzLCByZXN1bHQpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9O1xuXG4gIC8vIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHdpbGwgb25seSBiZSBleGVjdXRlZCBhZnRlciBiZWluZyBjYWxsZWQgTiB0aW1lcy5cbiAgXy5hZnRlciA9IGZ1bmN0aW9uKHRpbWVzLCBmdW5jKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKC0tdGltZXMgPCAxKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCB3aWxsIG9ubHkgYmUgZXhlY3V0ZWQgYmVmb3JlIGJlaW5nIGNhbGxlZCBOIHRpbWVzLlxuICBfLmJlZm9yZSA9IGZ1bmN0aW9uKHRpbWVzLCBmdW5jKSB7XG4gICAgdmFyIG1lbW87XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKC0tdGltZXMgPiAwKSB7XG4gICAgICAgIG1lbW8gPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmdW5jID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBtZW1vO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBhdCBtb3N0IG9uZSB0aW1lLCBubyBtYXR0ZXIgaG93XG4gIC8vIG9mdGVuIHlvdSBjYWxsIGl0LiBVc2VmdWwgZm9yIGxhenkgaW5pdGlhbGl6YXRpb24uXG4gIF8ub25jZSA9IF8ucGFydGlhbChfLmJlZm9yZSwgMik7XG5cbiAgLy8gT2JqZWN0IEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gUmV0cmlldmUgdGhlIG5hbWVzIG9mIGFuIG9iamVjdCdzIHByb3BlcnRpZXMuXG4gIC8vIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGBPYmplY3Qua2V5c2BcbiAgXy5rZXlzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBbXTtcbiAgICBpZiAobmF0aXZlS2V5cykgcmV0dXJuIG5hdGl2ZUtleXMob2JqKTtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIGlmIChfLmhhcyhvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICAgIHJldHVybiBrZXlzO1xuICB9O1xuXG4gIC8vIFJldHJpZXZlIHRoZSB2YWx1ZXMgb2YgYW4gb2JqZWN0J3MgcHJvcGVydGllcy5cbiAgXy52YWx1ZXMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopO1xuICAgIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgICB2YXIgdmFsdWVzID0gQXJyYXkobGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWx1ZXNbaV0gPSBvYmpba2V5c1tpXV07XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZXM7XG4gIH07XG5cbiAgLy8gQ29udmVydCBhbiBvYmplY3QgaW50byBhIGxpc3Qgb2YgYFtrZXksIHZhbHVlXWAgcGFpcnMuXG4gIF8ucGFpcnMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopO1xuICAgIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgICB2YXIgcGFpcnMgPSBBcnJheShsZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHBhaXJzW2ldID0gW2tleXNbaV0sIG9ialtrZXlzW2ldXV07XG4gICAgfVxuICAgIHJldHVybiBwYWlycztcbiAgfTtcblxuICAvLyBJbnZlcnQgdGhlIGtleXMgYW5kIHZhbHVlcyBvZiBhbiBvYmplY3QuIFRoZSB2YWx1ZXMgbXVzdCBiZSBzZXJpYWxpemFibGUuXG4gIF8uaW52ZXJ0ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIHZhciBrZXlzID0gXy5rZXlzKG9iaik7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGtleXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdFtvYmpba2V5c1tpXV1dID0ga2V5c1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBSZXR1cm4gYSBzb3J0ZWQgbGlzdCBvZiB0aGUgZnVuY3Rpb24gbmFtZXMgYXZhaWxhYmxlIG9uIHRoZSBvYmplY3QuXG4gIC8vIEFsaWFzZWQgYXMgYG1ldGhvZHNgXG4gIF8uZnVuY3Rpb25zID0gXy5tZXRob2RzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIG5hbWVzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgaWYgKF8uaXNGdW5jdGlvbihvYmpba2V5XSkpIG5hbWVzLnB1c2goa2V5KTtcbiAgICB9XG4gICAgcmV0dXJuIG5hbWVzLnNvcnQoKTtcbiAgfTtcblxuICAvLyBFeHRlbmQgYSBnaXZlbiBvYmplY3Qgd2l0aCBhbGwgdGhlIHByb3BlcnRpZXMgaW4gcGFzc2VkLWluIG9iamVjdChzKS5cbiAgXy5leHRlbmQgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAoIV8uaXNPYmplY3Qob2JqKSkgcmV0dXJuIG9iajtcbiAgICB2YXIgc291cmNlLCBwcm9wO1xuICAgIGZvciAodmFyIGkgPSAxLCBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgIGZvciAocHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBwcm9wKSkge1xuICAgICAgICAgICAgb2JqW3Byb3BdID0gc291cmNlW3Byb3BdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmo7XG4gIH07XG5cbiAgLy8gUmV0dXJuIGEgY29weSBvZiB0aGUgb2JqZWN0IG9ubHkgY29udGFpbmluZyB0aGUgd2hpdGVsaXN0ZWQgcHJvcGVydGllcy5cbiAgXy5waWNrID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgIHZhciByZXN1bHQgPSB7fSwga2V5O1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdDtcbiAgICBpZiAoXy5pc0Z1bmN0aW9uKGl0ZXJhdGVlKSkge1xuICAgICAgaXRlcmF0ZWUgPSBjcmVhdGVDYWxsYmFjayhpdGVyYXRlZSwgY29udGV4dCk7XG4gICAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgICAgdmFyIHZhbHVlID0gb2JqW2tleV07XG4gICAgICAgIGlmIChpdGVyYXRlZSh2YWx1ZSwga2V5LCBvYmopKSByZXN1bHRba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIga2V5cyA9IGNvbmNhdC5hcHBseShbXSwgc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgICAgIG9iaiA9IG5ldyBPYmplY3Qob2JqKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgIGlmIChrZXkgaW4gb2JqKSByZXN1bHRba2V5XSA9IG9ialtrZXldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gICAvLyBSZXR1cm4gYSBjb3B5IG9mIHRoZSBvYmplY3Qgd2l0aG91dCB0aGUgYmxhY2tsaXN0ZWQgcHJvcGVydGllcy5cbiAgXy5vbWl0ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgIGlmIChfLmlzRnVuY3Rpb24oaXRlcmF0ZWUpKSB7XG4gICAgICBpdGVyYXRlZSA9IF8ubmVnYXRlKGl0ZXJhdGVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGtleXMgPSBfLm1hcChjb25jYXQuYXBwbHkoW10sIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSksIFN0cmluZyk7XG4gICAgICBpdGVyYXRlZSA9IGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgcmV0dXJuICFfLmNvbnRhaW5zKGtleXMsIGtleSk7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gXy5waWNrKG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpO1xuICB9O1xuXG4gIC8vIEZpbGwgaW4gYSBnaXZlbiBvYmplY3Qgd2l0aCBkZWZhdWx0IHByb3BlcnRpZXMuXG4gIF8uZGVmYXVsdHMgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAoIV8uaXNPYmplY3Qob2JqKSkgcmV0dXJuIG9iajtcbiAgICBmb3IgKHZhciBpID0gMSwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKG9ialtwcm9wXSA9PT0gdm9pZCAwKSBvYmpbcHJvcF0gPSBzb3VyY2VbcHJvcF07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmo7XG4gIH07XG5cbiAgLy8gQ3JlYXRlIGEgKHNoYWxsb3ctY2xvbmVkKSBkdXBsaWNhdGUgb2YgYW4gb2JqZWN0LlxuICBfLmNsb25lID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gICAgcmV0dXJuIF8uaXNBcnJheShvYmopID8gb2JqLnNsaWNlKCkgOiBfLmV4dGVuZCh7fSwgb2JqKTtcbiAgfTtcblxuICAvLyBJbnZva2VzIGludGVyY2VwdG9yIHdpdGggdGhlIG9iaiwgYW5kIHRoZW4gcmV0dXJucyBvYmouXG4gIC8vIFRoZSBwcmltYXJ5IHB1cnBvc2Ugb2YgdGhpcyBtZXRob2QgaXMgdG8gXCJ0YXAgaW50b1wiIGEgbWV0aG9kIGNoYWluLCBpblxuICAvLyBvcmRlciB0byBwZXJmb3JtIG9wZXJhdGlvbnMgb24gaW50ZXJtZWRpYXRlIHJlc3VsdHMgd2l0aGluIHRoZSBjaGFpbi5cbiAgXy50YXAgPSBmdW5jdGlvbihvYmosIGludGVyY2VwdG9yKSB7XG4gICAgaW50ZXJjZXB0b3Iob2JqKTtcbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIEludGVybmFsIHJlY3Vyc2l2ZSBjb21wYXJpc29uIGZ1bmN0aW9uIGZvciBgaXNFcXVhbGAuXG4gIHZhciBlcSA9IGZ1bmN0aW9uKGEsIGIsIGFTdGFjaywgYlN0YWNrKSB7XG4gICAgLy8gSWRlbnRpY2FsIG9iamVjdHMgYXJlIGVxdWFsLiBgMCA9PT0gLTBgLCBidXQgdGhleSBhcmVuJ3QgaWRlbnRpY2FsLlxuICAgIC8vIFNlZSB0aGUgW0hhcm1vbnkgYGVnYWxgIHByb3Bvc2FsXShodHRwOi8vd2lraS5lY21hc2NyaXB0Lm9yZy9kb2t1LnBocD9pZD1oYXJtb255OmVnYWwpLlxuICAgIGlmIChhID09PSBiKSByZXR1cm4gYSAhPT0gMCB8fCAxIC8gYSA9PT0gMSAvIGI7XG4gICAgLy8gQSBzdHJpY3QgY29tcGFyaXNvbiBpcyBuZWNlc3NhcnkgYmVjYXVzZSBgbnVsbCA9PSB1bmRlZmluZWRgLlxuICAgIGlmIChhID09IG51bGwgfHwgYiA9PSBudWxsKSByZXR1cm4gYSA9PT0gYjtcbiAgICAvLyBVbndyYXAgYW55IHdyYXBwZWQgb2JqZWN0cy5cbiAgICBpZiAoYSBpbnN0YW5jZW9mIF8pIGEgPSBhLl93cmFwcGVkO1xuICAgIGlmIChiIGluc3RhbmNlb2YgXykgYiA9IGIuX3dyYXBwZWQ7XG4gICAgLy8gQ29tcGFyZSBgW1tDbGFzc11dYCBuYW1lcy5cbiAgICB2YXIgY2xhc3NOYW1lID0gdG9TdHJpbmcuY2FsbChhKTtcbiAgICBpZiAoY2xhc3NOYW1lICE9PSB0b1N0cmluZy5jYWxsKGIpKSByZXR1cm4gZmFsc2U7XG4gICAgc3dpdGNoIChjbGFzc05hbWUpIHtcbiAgICAgIC8vIFN0cmluZ3MsIG51bWJlcnMsIHJlZ3VsYXIgZXhwcmVzc2lvbnMsIGRhdGVzLCBhbmQgYm9vbGVhbnMgYXJlIGNvbXBhcmVkIGJ5IHZhbHVlLlxuICAgICAgY2FzZSAnW29iamVjdCBSZWdFeHBdJzpcbiAgICAgIC8vIFJlZ0V4cHMgYXJlIGNvZXJjZWQgdG8gc3RyaW5ncyBmb3IgY29tcGFyaXNvbiAoTm90ZTogJycgKyAvYS9pID09PSAnL2EvaScpXG4gICAgICBjYXNlICdbb2JqZWN0IFN0cmluZ10nOlxuICAgICAgICAvLyBQcmltaXRpdmVzIGFuZCB0aGVpciBjb3JyZXNwb25kaW5nIG9iamVjdCB3cmFwcGVycyBhcmUgZXF1aXZhbGVudDsgdGh1cywgYFwiNVwiYCBpc1xuICAgICAgICAvLyBlcXVpdmFsZW50IHRvIGBuZXcgU3RyaW5nKFwiNVwiKWAuXG4gICAgICAgIHJldHVybiAnJyArIGEgPT09ICcnICsgYjtcbiAgICAgIGNhc2UgJ1tvYmplY3QgTnVtYmVyXSc6XG4gICAgICAgIC8vIGBOYU5gcyBhcmUgZXF1aXZhbGVudCwgYnV0IG5vbi1yZWZsZXhpdmUuXG4gICAgICAgIC8vIE9iamVjdChOYU4pIGlzIGVxdWl2YWxlbnQgdG8gTmFOXG4gICAgICAgIGlmICgrYSAhPT0gK2EpIHJldHVybiArYiAhPT0gK2I7XG4gICAgICAgIC8vIEFuIGBlZ2FsYCBjb21wYXJpc29uIGlzIHBlcmZvcm1lZCBmb3Igb3RoZXIgbnVtZXJpYyB2YWx1ZXMuXG4gICAgICAgIHJldHVybiArYSA9PT0gMCA/IDEgLyArYSA9PT0gMSAvIGIgOiArYSA9PT0gK2I7XG4gICAgICBjYXNlICdbb2JqZWN0IERhdGVdJzpcbiAgICAgIGNhc2UgJ1tvYmplY3QgQm9vbGVhbl0nOlxuICAgICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWVyaWMgcHJpbWl0aXZlIHZhbHVlcy4gRGF0ZXMgYXJlIGNvbXBhcmVkIGJ5IHRoZWlyXG4gICAgICAgIC8vIG1pbGxpc2Vjb25kIHJlcHJlc2VudGF0aW9ucy4gTm90ZSB0aGF0IGludmFsaWQgZGF0ZXMgd2l0aCBtaWxsaXNlY29uZCByZXByZXNlbnRhdGlvbnNcbiAgICAgICAgLy8gb2YgYE5hTmAgYXJlIG5vdCBlcXVpdmFsZW50LlxuICAgICAgICByZXR1cm4gK2EgPT09ICtiO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGEgIT0gJ29iamVjdCcgfHwgdHlwZW9mIGIgIT0gJ29iamVjdCcpIHJldHVybiBmYWxzZTtcbiAgICAvLyBBc3N1bWUgZXF1YWxpdHkgZm9yIGN5Y2xpYyBzdHJ1Y3R1cmVzLiBUaGUgYWxnb3JpdGhtIGZvciBkZXRlY3RpbmcgY3ljbGljXG4gICAgLy8gc3RydWN0dXJlcyBpcyBhZGFwdGVkIGZyb20gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMywgYWJzdHJhY3Qgb3BlcmF0aW9uIGBKT2AuXG4gICAgdmFyIGxlbmd0aCA9IGFTdGFjay5sZW5ndGg7XG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAvLyBMaW5lYXIgc2VhcmNoLiBQZXJmb3JtYW5jZSBpcyBpbnZlcnNlbHkgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2ZcbiAgICAgIC8vIHVuaXF1ZSBuZXN0ZWQgc3RydWN0dXJlcy5cbiAgICAgIGlmIChhU3RhY2tbbGVuZ3RoXSA9PT0gYSkgcmV0dXJuIGJTdGFja1tsZW5ndGhdID09PSBiO1xuICAgIH1cbiAgICAvLyBPYmplY3RzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWl2YWxlbnQsIGJ1dCBgT2JqZWN0YHNcbiAgICAvLyBmcm9tIGRpZmZlcmVudCBmcmFtZXMgYXJlLlxuICAgIHZhciBhQ3RvciA9IGEuY29uc3RydWN0b3IsIGJDdG9yID0gYi5jb25zdHJ1Y3RvcjtcbiAgICBpZiAoXG4gICAgICBhQ3RvciAhPT0gYkN0b3IgJiZcbiAgICAgIC8vIEhhbmRsZSBPYmplY3QuY3JlYXRlKHgpIGNhc2VzXG4gICAgICAnY29uc3RydWN0b3InIGluIGEgJiYgJ2NvbnN0cnVjdG9yJyBpbiBiICYmXG4gICAgICAhKF8uaXNGdW5jdGlvbihhQ3RvcikgJiYgYUN0b3IgaW5zdGFuY2VvZiBhQ3RvciAmJlxuICAgICAgICBfLmlzRnVuY3Rpb24oYkN0b3IpICYmIGJDdG9yIGluc3RhbmNlb2YgYkN0b3IpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIEFkZCB0aGUgZmlyc3Qgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICBhU3RhY2sucHVzaChhKTtcbiAgICBiU3RhY2sucHVzaChiKTtcbiAgICB2YXIgc2l6ZSwgcmVzdWx0O1xuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyBhbmQgYXJyYXlzLlxuICAgIGlmIChjbGFzc05hbWUgPT09ICdbb2JqZWN0IEFycmF5XScpIHtcbiAgICAgIC8vIENvbXBhcmUgYXJyYXkgbGVuZ3RocyB0byBkZXRlcm1pbmUgaWYgYSBkZWVwIGNvbXBhcmlzb24gaXMgbmVjZXNzYXJ5LlxuICAgICAgc2l6ZSA9IGEubGVuZ3RoO1xuICAgICAgcmVzdWx0ID0gc2l6ZSA9PT0gYi5sZW5ndGg7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIC8vIERlZXAgY29tcGFyZSB0aGUgY29udGVudHMsIGlnbm9yaW5nIG5vbi1udW1lcmljIHByb3BlcnRpZXMuXG4gICAgICAgIHdoaWxlIChzaXplLS0pIHtcbiAgICAgICAgICBpZiAoIShyZXN1bHQgPSBlcShhW3NpemVdLCBiW3NpemVdLCBhU3RhY2ssIGJTdGFjaykpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWVwIGNvbXBhcmUgb2JqZWN0cy5cbiAgICAgIHZhciBrZXlzID0gXy5rZXlzKGEpLCBrZXk7XG4gICAgICBzaXplID0ga2V5cy5sZW5ndGg7XG4gICAgICAvLyBFbnN1cmUgdGhhdCBib3RoIG9iamVjdHMgY29udGFpbiB0aGUgc2FtZSBudW1iZXIgb2YgcHJvcGVydGllcyBiZWZvcmUgY29tcGFyaW5nIGRlZXAgZXF1YWxpdHkuXG4gICAgICByZXN1bHQgPSBfLmtleXMoYikubGVuZ3RoID09PSBzaXplO1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICB3aGlsZSAoc2l6ZS0tKSB7XG4gICAgICAgICAgLy8gRGVlcCBjb21wYXJlIGVhY2ggbWVtYmVyXG4gICAgICAgICAga2V5ID0ga2V5c1tzaXplXTtcbiAgICAgICAgICBpZiAoIShyZXN1bHQgPSBfLmhhcyhiLCBrZXkpICYmIGVxKGFba2V5XSwgYltrZXldLCBhU3RhY2ssIGJTdGFjaykpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBSZW1vdmUgdGhlIGZpcnN0IG9iamVjdCBmcm9tIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICBhU3RhY2sucG9wKCk7XG4gICAgYlN0YWNrLnBvcCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gUGVyZm9ybSBhIGRlZXAgY29tcGFyaXNvbiB0byBjaGVjayBpZiB0d28gb2JqZWN0cyBhcmUgZXF1YWwuXG4gIF8uaXNFcXVhbCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gZXEoYSwgYiwgW10sIFtdKTtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIGFycmF5LCBzdHJpbmcsIG9yIG9iamVjdCBlbXB0eT9cbiAgLy8gQW4gXCJlbXB0eVwiIG9iamVjdCBoYXMgbm8gZW51bWVyYWJsZSBvd24tcHJvcGVydGllcy5cbiAgXy5pc0VtcHR5ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoXy5pc0FycmF5KG9iaikgfHwgXy5pc1N0cmluZyhvYmopIHx8IF8uaXNBcmd1bWVudHMob2JqKSkgcmV0dXJuIG9iai5sZW5ndGggPT09IDA7XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikgaWYgKF8uaGFzKG9iaiwga2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gdmFsdWUgYSBET00gZWxlbWVudD9cbiAgXy5pc0VsZW1lbnQgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gISEob2JqICYmIG9iai5ub2RlVHlwZSA9PT0gMSk7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YWx1ZSBhbiBhcnJheT9cbiAgLy8gRGVsZWdhdGVzIHRvIEVDTUE1J3MgbmF0aXZlIEFycmF5LmlzQXJyYXlcbiAgXy5pc0FycmF5ID0gbmF0aXZlSXNBcnJheSB8fCBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gdG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBBcnJheV0nO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gdmFyaWFibGUgYW4gb2JqZWN0P1xuICBfLmlzT2JqZWN0ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIHR5cGUgPSB0eXBlb2Ygb2JqO1xuICAgIHJldHVybiB0eXBlID09PSAnZnVuY3Rpb24nIHx8IHR5cGUgPT09ICdvYmplY3QnICYmICEhb2JqO1xuICB9O1xuXG4gIC8vIEFkZCBzb21lIGlzVHlwZSBtZXRob2RzOiBpc0FyZ3VtZW50cywgaXNGdW5jdGlvbiwgaXNTdHJpbmcsIGlzTnVtYmVyLCBpc0RhdGUsIGlzUmVnRXhwLlxuICBfLmVhY2goWydBcmd1bWVudHMnLCAnRnVuY3Rpb24nLCAnU3RyaW5nJywgJ051bWJlcicsICdEYXRlJywgJ1JlZ0V4cCddLCBmdW5jdGlvbihuYW1lKSB7XG4gICAgX1snaXMnICsgbmFtZV0gPSBmdW5jdGlvbihvYmopIHtcbiAgICAgIHJldHVybiB0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0ICcgKyBuYW1lICsgJ10nO1xuICAgIH07XG4gIH0pO1xuXG4gIC8vIERlZmluZSBhIGZhbGxiYWNrIHZlcnNpb24gb2YgdGhlIG1ldGhvZCBpbiBicm93c2VycyAoYWhlbSwgSUUpLCB3aGVyZVxuICAvLyB0aGVyZSBpc24ndCBhbnkgaW5zcGVjdGFibGUgXCJBcmd1bWVudHNcIiB0eXBlLlxuICBpZiAoIV8uaXNBcmd1bWVudHMoYXJndW1lbnRzKSkge1xuICAgIF8uaXNBcmd1bWVudHMgPSBmdW5jdGlvbihvYmopIHtcbiAgICAgIHJldHVybiBfLmhhcyhvYmosICdjYWxsZWUnKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gT3B0aW1pemUgYGlzRnVuY3Rpb25gIGlmIGFwcHJvcHJpYXRlLiBXb3JrIGFyb3VuZCBhbiBJRSAxMSBidWcuXG4gIGlmICh0eXBlb2YgLy4vICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgXy5pc0Z1bmN0aW9uID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PSAnZnVuY3Rpb24nIHx8IGZhbHNlO1xuICAgIH07XG4gIH1cblxuICAvLyBJcyBhIGdpdmVuIG9iamVjdCBhIGZpbml0ZSBudW1iZXI/XG4gIF8uaXNGaW5pdGUgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gaXNGaW5pdGUob2JqKSAmJiAhaXNOYU4ocGFyc2VGbG9hdChvYmopKTtcbiAgfTtcblxuICAvLyBJcyB0aGUgZ2l2ZW4gdmFsdWUgYE5hTmA/IChOYU4gaXMgdGhlIG9ubHkgbnVtYmVyIHdoaWNoIGRvZXMgbm90IGVxdWFsIGl0c2VsZikuXG4gIF8uaXNOYU4gPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gXy5pc051bWJlcihvYmopICYmIG9iaiAhPT0gK29iajtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhbHVlIGEgYm9vbGVhbj9cbiAgXy5pc0Jvb2xlYW4gPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gb2JqID09PSB0cnVlIHx8IG9iaiA9PT0gZmFsc2UgfHwgdG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBCb29sZWFuXSc7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YWx1ZSBlcXVhbCB0byBudWxsP1xuICBfLmlzTnVsbCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBvYmogPT09IG51bGw7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YXJpYWJsZSB1bmRlZmluZWQ/XG4gIF8uaXNVbmRlZmluZWQgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gb2JqID09PSB2b2lkIDA7XG4gIH07XG5cbiAgLy8gU2hvcnRjdXQgZnVuY3Rpb24gZm9yIGNoZWNraW5nIGlmIGFuIG9iamVjdCBoYXMgYSBnaXZlbiBwcm9wZXJ0eSBkaXJlY3RseVxuICAvLyBvbiBpdHNlbGYgKGluIG90aGVyIHdvcmRzLCBub3Qgb24gYSBwcm90b3R5cGUpLlxuICBfLmhhcyA9IGZ1bmN0aW9uKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIG9iaiAhPSBudWxsICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpO1xuICB9O1xuXG4gIC8vIFV0aWxpdHkgRnVuY3Rpb25zXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gUnVuIFVuZGVyc2NvcmUuanMgaW4gKm5vQ29uZmxpY3QqIG1vZGUsIHJldHVybmluZyB0aGUgYF9gIHZhcmlhYmxlIHRvIGl0c1xuICAvLyBwcmV2aW91cyBvd25lci4gUmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgVW5kZXJzY29yZSBvYmplY3QuXG4gIF8ubm9Db25mbGljdCA9IGZ1bmN0aW9uKCkge1xuICAgIHJvb3QuXyA9IHByZXZpb3VzVW5kZXJzY29yZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvLyBLZWVwIHRoZSBpZGVudGl0eSBmdW5jdGlvbiBhcm91bmQgZm9yIGRlZmF1bHQgaXRlcmF0ZWVzLlxuICBfLmlkZW50aXR5ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH07XG5cbiAgXy5jb25zdGFudCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gIH07XG5cbiAgXy5ub29wID0gZnVuY3Rpb24oKXt9O1xuXG4gIF8ucHJvcGVydHkgPSBmdW5jdGlvbihrZXkpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24ob2JqKSB7XG4gICAgICByZXR1cm4gb2JqW2tleV07XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgcHJlZGljYXRlIGZvciBjaGVja2luZyB3aGV0aGVyIGFuIG9iamVjdCBoYXMgYSBnaXZlbiBzZXQgb2YgYGtleTp2YWx1ZWAgcGFpcnMuXG4gIF8ubWF0Y2hlcyA9IGZ1bmN0aW9uKGF0dHJzKSB7XG4gICAgdmFyIHBhaXJzID0gXy5wYWlycyhhdHRycyksIGxlbmd0aCA9IHBhaXJzLmxlbmd0aDtcbiAgICByZXR1cm4gZnVuY3Rpb24ob2JqKSB7XG4gICAgICBpZiAob2JqID09IG51bGwpIHJldHVybiAhbGVuZ3RoO1xuICAgICAgb2JqID0gbmV3IE9iamVjdChvYmopO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgcGFpciA9IHBhaXJzW2ldLCBrZXkgPSBwYWlyWzBdO1xuICAgICAgICBpZiAocGFpclsxXSAhPT0gb2JqW2tleV0gfHwgIShrZXkgaW4gb2JqKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgfTtcblxuICAvLyBSdW4gYSBmdW5jdGlvbiAqKm4qKiB0aW1lcy5cbiAgXy50aW1lcyA9IGZ1bmN0aW9uKG4sIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgdmFyIGFjY3VtID0gQXJyYXkoTWF0aC5tYXgoMCwgbikpO1xuICAgIGl0ZXJhdGVlID0gY3JlYXRlQ2FsbGJhY2soaXRlcmF0ZWUsIGNvbnRleHQsIDEpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSsrKSBhY2N1bVtpXSA9IGl0ZXJhdGVlKGkpO1xuICAgIHJldHVybiBhY2N1bTtcbiAgfTtcblxuICAvLyBSZXR1cm4gYSByYW5kb20gaW50ZWdlciBiZXR3ZWVuIG1pbiBhbmQgbWF4IChpbmNsdXNpdmUpLlxuICBfLnJhbmRvbSA9IGZ1bmN0aW9uKG1pbiwgbWF4KSB7XG4gICAgaWYgKG1heCA9PSBudWxsKSB7XG4gICAgICBtYXggPSBtaW47XG4gICAgICBtaW4gPSAwO1xuICAgIH1cbiAgICByZXR1cm4gbWluICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbiArIDEpKTtcbiAgfTtcblxuICAvLyBBIChwb3NzaWJseSBmYXN0ZXIpIHdheSB0byBnZXQgdGhlIGN1cnJlbnQgdGltZXN0YW1wIGFzIGFuIGludGVnZXIuXG4gIF8ubm93ID0gRGF0ZS5ub3cgfHwgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICB9O1xuXG4gICAvLyBMaXN0IG9mIEhUTUwgZW50aXRpZXMgZm9yIGVzY2FwaW5nLlxuICB2YXIgZXNjYXBlTWFwID0ge1xuICAgICcmJzogJyZhbXA7JyxcbiAgICAnPCc6ICcmbHQ7JyxcbiAgICAnPic6ICcmZ3Q7JyxcbiAgICAnXCInOiAnJnF1b3Q7JyxcbiAgICBcIidcIjogJyYjeDI3OycsXG4gICAgJ2AnOiAnJiN4NjA7J1xuICB9O1xuICB2YXIgdW5lc2NhcGVNYXAgPSBfLmludmVydChlc2NhcGVNYXApO1xuXG4gIC8vIEZ1bmN0aW9ucyBmb3IgZXNjYXBpbmcgYW5kIHVuZXNjYXBpbmcgc3RyaW5ncyB0by9mcm9tIEhUTUwgaW50ZXJwb2xhdGlvbi5cbiAgdmFyIGNyZWF0ZUVzY2FwZXIgPSBmdW5jdGlvbihtYXApIHtcbiAgICB2YXIgZXNjYXBlciA9IGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICByZXR1cm4gbWFwW21hdGNoXTtcbiAgICB9O1xuICAgIC8vIFJlZ2V4ZXMgZm9yIGlkZW50aWZ5aW5nIGEga2V5IHRoYXQgbmVlZHMgdG8gYmUgZXNjYXBlZFxuICAgIHZhciBzb3VyY2UgPSAnKD86JyArIF8ua2V5cyhtYXApLmpvaW4oJ3wnKSArICcpJztcbiAgICB2YXIgdGVzdFJlZ2V4cCA9IFJlZ0V4cChzb3VyY2UpO1xuICAgIHZhciByZXBsYWNlUmVnZXhwID0gUmVnRXhwKHNvdXJjZSwgJ2cnKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICBzdHJpbmcgPSBzdHJpbmcgPT0gbnVsbCA/ICcnIDogJycgKyBzdHJpbmc7XG4gICAgICByZXR1cm4gdGVzdFJlZ2V4cC50ZXN0KHN0cmluZykgPyBzdHJpbmcucmVwbGFjZShyZXBsYWNlUmVnZXhwLCBlc2NhcGVyKSA6IHN0cmluZztcbiAgICB9O1xuICB9O1xuICBfLmVzY2FwZSA9IGNyZWF0ZUVzY2FwZXIoZXNjYXBlTWFwKTtcbiAgXy51bmVzY2FwZSA9IGNyZWF0ZUVzY2FwZXIodW5lc2NhcGVNYXApO1xuXG4gIC8vIElmIHRoZSB2YWx1ZSBvZiB0aGUgbmFtZWQgYHByb3BlcnR5YCBpcyBhIGZ1bmN0aW9uIHRoZW4gaW52b2tlIGl0IHdpdGggdGhlXG4gIC8vIGBvYmplY3RgIGFzIGNvbnRleHQ7IG90aGVyd2lzZSwgcmV0dXJuIGl0LlxuICBfLnJlc3VsdCA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICBpZiAob2JqZWN0ID09IG51bGwpIHJldHVybiB2b2lkIDA7XG4gICAgdmFyIHZhbHVlID0gb2JqZWN0W3Byb3BlcnR5XTtcbiAgICByZXR1cm4gXy5pc0Z1bmN0aW9uKHZhbHVlKSA/IG9iamVjdFtwcm9wZXJ0eV0oKSA6IHZhbHVlO1xuICB9O1xuXG4gIC8vIEdlbmVyYXRlIGEgdW5pcXVlIGludGVnZXIgaWQgKHVuaXF1ZSB3aXRoaW4gdGhlIGVudGlyZSBjbGllbnQgc2Vzc2lvbikuXG4gIC8vIFVzZWZ1bCBmb3IgdGVtcG9yYXJ5IERPTSBpZHMuXG4gIHZhciBpZENvdW50ZXIgPSAwO1xuICBfLnVuaXF1ZUlkID0gZnVuY3Rpb24ocHJlZml4KSB7XG4gICAgdmFyIGlkID0gKytpZENvdW50ZXIgKyAnJztcbiAgICByZXR1cm4gcHJlZml4ID8gcHJlZml4ICsgaWQgOiBpZDtcbiAgfTtcblxuICAvLyBCeSBkZWZhdWx0LCBVbmRlcnNjb3JlIHVzZXMgRVJCLXN0eWxlIHRlbXBsYXRlIGRlbGltaXRlcnMsIGNoYW5nZSB0aGVcbiAgLy8gZm9sbG93aW5nIHRlbXBsYXRlIHNldHRpbmdzIHRvIHVzZSBhbHRlcm5hdGl2ZSBkZWxpbWl0ZXJzLlxuICBfLnRlbXBsYXRlU2V0dGluZ3MgPSB7XG4gICAgZXZhbHVhdGUgICAgOiAvPCUoW1xcc1xcU10rPyklPi9nLFxuICAgIGludGVycG9sYXRlIDogLzwlPShbXFxzXFxTXSs/KSU+L2csXG4gICAgZXNjYXBlICAgICAgOiAvPCUtKFtcXHNcXFNdKz8pJT4vZ1xuICB9O1xuXG4gIC8vIFdoZW4gY3VzdG9taXppbmcgYHRlbXBsYXRlU2V0dGluZ3NgLCBpZiB5b3UgZG9uJ3Qgd2FudCB0byBkZWZpbmUgYW5cbiAgLy8gaW50ZXJwb2xhdGlvbiwgZXZhbHVhdGlvbiBvciBlc2NhcGluZyByZWdleCwgd2UgbmVlZCBvbmUgdGhhdCBpc1xuICAvLyBndWFyYW50ZWVkIG5vdCB0byBtYXRjaC5cbiAgdmFyIG5vTWF0Y2ggPSAvKC4pXi87XG5cbiAgLy8gQ2VydGFpbiBjaGFyYWN0ZXJzIG5lZWQgdG8gYmUgZXNjYXBlZCBzbyB0aGF0IHRoZXkgY2FuIGJlIHB1dCBpbnRvIGFcbiAgLy8gc3RyaW5nIGxpdGVyYWwuXG4gIHZhciBlc2NhcGVzID0ge1xuICAgIFwiJ1wiOiAgICAgIFwiJ1wiLFxuICAgICdcXFxcJzogICAgICdcXFxcJyxcbiAgICAnXFxyJzogICAgICdyJyxcbiAgICAnXFxuJzogICAgICduJyxcbiAgICAnXFx1MjAyOCc6ICd1MjAyOCcsXG4gICAgJ1xcdTIwMjknOiAndTIwMjknXG4gIH07XG5cbiAgdmFyIGVzY2FwZXIgPSAvXFxcXHwnfFxccnxcXG58XFx1MjAyOHxcXHUyMDI5L2c7XG5cbiAgdmFyIGVzY2FwZUNoYXIgPSBmdW5jdGlvbihtYXRjaCkge1xuICAgIHJldHVybiAnXFxcXCcgKyBlc2NhcGVzW21hdGNoXTtcbiAgfTtcblxuICAvLyBKYXZhU2NyaXB0IG1pY3JvLXRlbXBsYXRpbmcsIHNpbWlsYXIgdG8gSm9obiBSZXNpZydzIGltcGxlbWVudGF0aW9uLlxuICAvLyBVbmRlcnNjb3JlIHRlbXBsYXRpbmcgaGFuZGxlcyBhcmJpdHJhcnkgZGVsaW1pdGVycywgcHJlc2VydmVzIHdoaXRlc3BhY2UsXG4gIC8vIGFuZCBjb3JyZWN0bHkgZXNjYXBlcyBxdW90ZXMgd2l0aGluIGludGVycG9sYXRlZCBjb2RlLlxuICAvLyBOQjogYG9sZFNldHRpbmdzYCBvbmx5IGV4aXN0cyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuXG4gIF8udGVtcGxhdGUgPSBmdW5jdGlvbih0ZXh0LCBzZXR0aW5ncywgb2xkU2V0dGluZ3MpIHtcbiAgICBpZiAoIXNldHRpbmdzICYmIG9sZFNldHRpbmdzKSBzZXR0aW5ncyA9IG9sZFNldHRpbmdzO1xuICAgIHNldHRpbmdzID0gXy5kZWZhdWx0cyh7fSwgc2V0dGluZ3MsIF8udGVtcGxhdGVTZXR0aW5ncyk7XG5cbiAgICAvLyBDb21iaW5lIGRlbGltaXRlcnMgaW50byBvbmUgcmVndWxhciBleHByZXNzaW9uIHZpYSBhbHRlcm5hdGlvbi5cbiAgICB2YXIgbWF0Y2hlciA9IFJlZ0V4cChbXG4gICAgICAoc2V0dGluZ3MuZXNjYXBlIHx8IG5vTWF0Y2gpLnNvdXJjZSxcbiAgICAgIChzZXR0aW5ncy5pbnRlcnBvbGF0ZSB8fCBub01hdGNoKS5zb3VyY2UsXG4gICAgICAoc2V0dGluZ3MuZXZhbHVhdGUgfHwgbm9NYXRjaCkuc291cmNlXG4gICAgXS5qb2luKCd8JykgKyAnfCQnLCAnZycpO1xuXG4gICAgLy8gQ29tcGlsZSB0aGUgdGVtcGxhdGUgc291cmNlLCBlc2NhcGluZyBzdHJpbmcgbGl0ZXJhbHMgYXBwcm9wcmlhdGVseS5cbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBzb3VyY2UgPSBcIl9fcCs9J1wiO1xuICAgIHRleHQucmVwbGFjZShtYXRjaGVyLCBmdW5jdGlvbihtYXRjaCwgZXNjYXBlLCBpbnRlcnBvbGF0ZSwgZXZhbHVhdGUsIG9mZnNldCkge1xuICAgICAgc291cmNlICs9IHRleHQuc2xpY2UoaW5kZXgsIG9mZnNldCkucmVwbGFjZShlc2NhcGVyLCBlc2NhcGVDaGFyKTtcbiAgICAgIGluZGV4ID0gb2Zmc2V0ICsgbWF0Y2gubGVuZ3RoO1xuXG4gICAgICBpZiAoZXNjYXBlKSB7XG4gICAgICAgIHNvdXJjZSArPSBcIicrXFxuKChfX3Q9KFwiICsgZXNjYXBlICsgXCIpKT09bnVsbD8nJzpfLmVzY2FwZShfX3QpKStcXG4nXCI7XG4gICAgICB9IGVsc2UgaWYgKGludGVycG9sYXRlKSB7XG4gICAgICAgIHNvdXJjZSArPSBcIicrXFxuKChfX3Q9KFwiICsgaW50ZXJwb2xhdGUgKyBcIikpPT1udWxsPycnOl9fdCkrXFxuJ1wiO1xuICAgICAgfSBlbHNlIGlmIChldmFsdWF0ZSkge1xuICAgICAgICBzb3VyY2UgKz0gXCInO1xcblwiICsgZXZhbHVhdGUgKyBcIlxcbl9fcCs9J1wiO1xuICAgICAgfVxuXG4gICAgICAvLyBBZG9iZSBWTXMgbmVlZCB0aGUgbWF0Y2ggcmV0dXJuZWQgdG8gcHJvZHVjZSB0aGUgY29ycmVjdCBvZmZlc3QuXG4gICAgICByZXR1cm4gbWF0Y2g7XG4gICAgfSk7XG4gICAgc291cmNlICs9IFwiJztcXG5cIjtcblxuICAgIC8vIElmIGEgdmFyaWFibGUgaXMgbm90IHNwZWNpZmllZCwgcGxhY2UgZGF0YSB2YWx1ZXMgaW4gbG9jYWwgc2NvcGUuXG4gICAgaWYgKCFzZXR0aW5ncy52YXJpYWJsZSkgc291cmNlID0gJ3dpdGgob2JqfHx7fSl7XFxuJyArIHNvdXJjZSArICd9XFxuJztcblxuICAgIHNvdXJjZSA9IFwidmFyIF9fdCxfX3A9JycsX19qPUFycmF5LnByb3RvdHlwZS5qb2luLFwiICtcbiAgICAgIFwicHJpbnQ9ZnVuY3Rpb24oKXtfX3ArPV9fai5jYWxsKGFyZ3VtZW50cywnJyk7fTtcXG5cIiArXG4gICAgICBzb3VyY2UgKyAncmV0dXJuIF9fcDtcXG4nO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciByZW5kZXIgPSBuZXcgRnVuY3Rpb24oc2V0dGluZ3MudmFyaWFibGUgfHwgJ29iaicsICdfJywgc291cmNlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBlLnNvdXJjZSA9IHNvdXJjZTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuXG4gICAgdmFyIHRlbXBsYXRlID0gZnVuY3Rpb24oZGF0YSkge1xuICAgICAgcmV0dXJuIHJlbmRlci5jYWxsKHRoaXMsIGRhdGEsIF8pO1xuICAgIH07XG5cbiAgICAvLyBQcm92aWRlIHRoZSBjb21waWxlZCBzb3VyY2UgYXMgYSBjb252ZW5pZW5jZSBmb3IgcHJlY29tcGlsYXRpb24uXG4gICAgdmFyIGFyZ3VtZW50ID0gc2V0dGluZ3MudmFyaWFibGUgfHwgJ29iaic7XG4gICAgdGVtcGxhdGUuc291cmNlID0gJ2Z1bmN0aW9uKCcgKyBhcmd1bWVudCArICcpe1xcbicgKyBzb3VyY2UgKyAnfSc7XG5cbiAgICByZXR1cm4gdGVtcGxhdGU7XG4gIH07XG5cbiAgLy8gQWRkIGEgXCJjaGFpblwiIGZ1bmN0aW9uLiBTdGFydCBjaGFpbmluZyBhIHdyYXBwZWQgVW5kZXJzY29yZSBvYmplY3QuXG4gIF8uY2hhaW4gPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBfKG9iaik7XG4gICAgaW5zdGFuY2UuX2NoYWluID0gdHJ1ZTtcbiAgICByZXR1cm4gaW5zdGFuY2U7XG4gIH07XG5cbiAgLy8gT09QXG4gIC8vIC0tLS0tLS0tLS0tLS0tLVxuICAvLyBJZiBVbmRlcnNjb3JlIGlzIGNhbGxlZCBhcyBhIGZ1bmN0aW9uLCBpdCByZXR1cm5zIGEgd3JhcHBlZCBvYmplY3QgdGhhdFxuICAvLyBjYW4gYmUgdXNlZCBPTy1zdHlsZS4gVGhpcyB3cmFwcGVyIGhvbGRzIGFsdGVyZWQgdmVyc2lvbnMgb2YgYWxsIHRoZVxuICAvLyB1bmRlcnNjb3JlIGZ1bmN0aW9ucy4gV3JhcHBlZCBvYmplY3RzIG1heSBiZSBjaGFpbmVkLlxuXG4gIC8vIEhlbHBlciBmdW5jdGlvbiB0byBjb250aW51ZSBjaGFpbmluZyBpbnRlcm1lZGlhdGUgcmVzdWx0cy5cbiAgdmFyIHJlc3VsdCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiB0aGlzLl9jaGFpbiA/IF8ob2JqKS5jaGFpbigpIDogb2JqO1xuICB9O1xuXG4gIC8vIEFkZCB5b3VyIG93biBjdXN0b20gZnVuY3Rpb25zIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdC5cbiAgXy5taXhpbiA9IGZ1bmN0aW9uKG9iaikge1xuICAgIF8uZWFjaChfLmZ1bmN0aW9ucyhvYmopLCBmdW5jdGlvbihuYW1lKSB7XG4gICAgICB2YXIgZnVuYyA9IF9bbmFtZV0gPSBvYmpbbmFtZV07XG4gICAgICBfLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYXJncyA9IFt0aGlzLl93cmFwcGVkXTtcbiAgICAgICAgcHVzaC5hcHBseShhcmdzLCBhcmd1bWVudHMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgZnVuYy5hcHBseShfLCBhcmdzKSk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIEFkZCBhbGwgb2YgdGhlIFVuZGVyc2NvcmUgZnVuY3Rpb25zIHRvIHRoZSB3cmFwcGVyIG9iamVjdC5cbiAgXy5taXhpbihfKTtcblxuICAvLyBBZGQgYWxsIG11dGF0b3IgQXJyYXkgZnVuY3Rpb25zIHRvIHRoZSB3cmFwcGVyLlxuICBfLmVhY2goWydwb3AnLCAncHVzaCcsICdyZXZlcnNlJywgJ3NoaWZ0JywgJ3NvcnQnLCAnc3BsaWNlJywgJ3Vuc2hpZnQnXSwgZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBtZXRob2QgPSBBcnJheVByb3RvW25hbWVdO1xuICAgIF8ucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgb2JqID0gdGhpcy5fd3JhcHBlZDtcbiAgICAgIG1ldGhvZC5hcHBseShvYmosIGFyZ3VtZW50cyk7XG4gICAgICBpZiAoKG5hbWUgPT09ICdzaGlmdCcgfHwgbmFtZSA9PT0gJ3NwbGljZScpICYmIG9iai5sZW5ndGggPT09IDApIGRlbGV0ZSBvYmpbMF07XG4gICAgICByZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgb2JqKTtcbiAgICB9O1xuICB9KTtcblxuICAvLyBBZGQgYWxsIGFjY2Vzc29yIEFycmF5IGZ1bmN0aW9ucyB0byB0aGUgd3JhcHBlci5cbiAgXy5lYWNoKFsnY29uY2F0JywgJ2pvaW4nLCAnc2xpY2UnXSwgZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBtZXRob2QgPSBBcnJheVByb3RvW25hbWVdO1xuICAgIF8ucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgbWV0aG9kLmFwcGx5KHRoaXMuX3dyYXBwZWQsIGFyZ3VtZW50cykpO1xuICAgIH07XG4gIH0pO1xuXG4gIC8vIEV4dHJhY3RzIHRoZSByZXN1bHQgZnJvbSBhIHdyYXBwZWQgYW5kIGNoYWluZWQgb2JqZWN0LlxuICBfLnByb3RvdHlwZS52YWx1ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl93cmFwcGVkO1xuICB9O1xuXG4gIC8vIEFNRCByZWdpc3RyYXRpb24gaGFwcGVucyBhdCB0aGUgZW5kIGZvciBjb21wYXRpYmlsaXR5IHdpdGggQU1EIGxvYWRlcnNcbiAgLy8gdGhhdCBtYXkgbm90IGVuZm9yY2UgbmV4dC10dXJuIHNlbWFudGljcyBvbiBtb2R1bGVzLiBFdmVuIHRob3VnaCBnZW5lcmFsXG4gIC8vIHByYWN0aWNlIGZvciBBTUQgcmVnaXN0cmF0aW9uIGlzIHRvIGJlIGFub255bW91cywgdW5kZXJzY29yZSByZWdpc3RlcnNcbiAgLy8gYXMgYSBuYW1lZCBtb2R1bGUgYmVjYXVzZSwgbGlrZSBqUXVlcnksIGl0IGlzIGEgYmFzZSBsaWJyYXJ5IHRoYXQgaXNcbiAgLy8gcG9wdWxhciBlbm91Z2ggdG8gYmUgYnVuZGxlZCBpbiBhIHRoaXJkIHBhcnR5IGxpYiwgYnV0IG5vdCBiZSBwYXJ0IG9mXG4gIC8vIGFuIEFNRCBsb2FkIHJlcXVlc3QuIFRob3NlIGNhc2VzIGNvdWxkIGdlbmVyYXRlIGFuIGVycm9yIHdoZW4gYW5cbiAgLy8gYW5vbnltb3VzIGRlZmluZSgpIGlzIGNhbGxlZCBvdXRzaWRlIG9mIGEgbG9hZGVyIHJlcXVlc3QuXG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICBkZWZpbmUoJ3VuZGVyc2NvcmUnLCBbXSwgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gXztcbiAgICB9KTtcbiAgfVxufS5jYWxsKHRoaXMpKTtcbiIsIl8gPSByZXF1aXJlIFwidW5kZXJzY29yZVwiXG5cbiMgY2FsY3VsYXRlIHRoZSBjb25zZW5zdXMgc2VxXG4jIFRPRE86IHZlcnkgbmFpdmUgd2F5XG5tb2R1bGUuZXhwb3J0cyA9IChzZXFzKSAtPlxuXG4gIHNlcXMgPSBzZXFzLm1hcCAoZWwpIC0+IGVsLmdldCBcInNlcVwiXG4gIG9jY3MgPSBuZXcgQXJyYXkgc2Vxcy5sZW5ndGhcblxuICAjIGNvdW50IHRoZSBvY2N1cmVuY2VzIG9mIHRoZSBjaGFycyBvZiBhIHBvc2l0aW9uXG4gIF8uZWFjaCBzZXFzLCAoZWwsaSkgLT5cbiAgICBfLmVhY2ggZWwsIChjaGFyLCBwb3MpIC0+XG4gICAgICBvY2NzW3Bvc10gPSB7fSB1bmxlc3Mgb2Njc1twb3NdP1xuICAgICAgb2Njc1twb3NdW2NoYXJdID0gMCB1bmxlc3Mgb2Njc1twb3NdW2NoYXJdP1xuICAgICAgb2Njc1twb3NdW2NoYXJdKytcblxuICAjIG5vdyBwaWNrIHRoZSBjaGFyIHdpdGggbW9zdCBvY2N1cmVuY2VzXG4gIF8ucmVkdWNlIG9jY3MsIChtZW1vLG9jYykgLT5cbiAgICBrZXlzID0gXy5rZXlzIG9jY1xuICAgIG1lbW8gKz0gIF8ubWF4IGtleXMsIChrZXkpIC0+IG9jY1trZXldXG4gICwgXCJcIlxuIiwiIyBmb3IgZWFjaCBzZXF1ZW5jZVxuIyAqIGNvdW50cyB0aGUgbWF0Y2hlcyB3aXRoIHRoZSBjb25zZW5zdXMgc2VxXG4jICogZXhjbHVkaW5nIGdhcHNcbiMgKiBpZGVudGl0eSA9IG1hdGNoZWRDaGFycyAvIHRvdGFsQ2hhcnMgKGV4Y2x1ZGluZyBnYXBzKVxubW9kdWxlLmV4cG9ydHMgPSBpZGVudGl0aXlDYWxjID0gKHNlcXMsIGNvbnNlbnN1cykgLT5cbiAgIyBkbyBub3RoaW5nIG9uIGludmFsaWQgY29uc2Vuc3VzXG4gIGlmIGNvbnNlbnN1cyBpcyB1bmRlZmluZWRcbiAgICBjb25zb2xlLndhcm4gXCJidWcgb24gY29uc2VudXMgY2FsY1wiXG4gICAgcmV0dXJuXG4gIHNlcXMuZWFjaCAoc2VxT2JqKSAtPlxuICAgIHNlcSA9IHNlcU9iai5nZXQgXCJzZXFcIlxuICAgIG1hdGNoZXMgPSAwXG4gICAgdG90YWwgPSAwXG4gICAgZm9yIGkgaW4gWzAuLnNlcS5sZW5ndGggLSAxXVxuICAgICAgaWYgc2VxW2ldIGlzbnQgXCItXCIgYW5kIGNvbnNlbnN1c1tpXSBpc250IFwiLVwiXG4gICAgICAgIHRvdGFsKytcbiAgICAgICAgbWF0Y2hlcysrIGlmIHNlcVtpXSBpcyBjb25zZW5zdXNbaV1cbiAgICBzZXFPYmouc2V0IFwiaWRlbnRpdHlcIiwgbWF0Y2hlcyAvIHRvdGFsXG4iLCJtb2R1bGUuZXhwb3J0cy5jb25zZW5zdXMgPSByZXF1aXJlIFwiLi9Db25zZW5zdXNDYWxjXCJcbiIsIk1vZGVsID0gcmVxdWlyZShcImJhY2tib25lLXRoaW5cIikuTW9kZWxcblxuIyB0aGlzIGlzIGFuIGV4YW1wbGUgb2YgaG93IG9uZSBjb3VsZCBjb2xvciB0aGUgTVNBXG4jIGZlZWwgZnJlZSB0byBjcmVhdGUgeW91ciBvd24gY29sb3Igc2NoZW1lIGluIHRoZSAvY3NzL3NjaGVtZXMgZm9sZGVyXG5tb2R1bGUuZXhwb3J0cyA9IENvbG9yYXRvciA9IE1vZGVsLmV4dGVuZFxuXG4gIGRlZmF1bHRzOlxuICAgIHNjaGVtZTogXCJ0YXlsb3JcIiAjIG5hbWUgb2YgeW91ciBjb2xvciBzY2hlbWUgKGNzcyBzdWZmaXgpXG4gICAgY29sb3JCYWNrZ3JvdW5kOiB0cnVlICMgb3RoZXJ3aXNlIG9ubHkgdGhlIHRleHQgd2lsbCBiZSBjb2xvcmVkXG4gICAgc2hvd0xvd2VyQ2FzZTogdHJ1ZSAjIHVzZWQgdG8gaGlkZSBhbmQgc2hvdyBsb3dlcmNhc2UgY2hhcnMgaW4gdGhlIG92ZXJ2aWV3Ym94XG4gICAgb3BhY2l0eTogMC42ICMgb3BhY2l0eSBmb3IgdGhlIHJlc2lkdWVzXG4iLCJNb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG5jb25zZW51cyA9IHJlcXVpcmUgXCIuLi9hbGdvL0NvbnNlbnN1c0NhbGNcIlxuXyA9IHJlcXVpcmUgXCJ1bmRlcnNjb3JlXCJcblxuIyBtb2RlbCBmb3IgY29sdW1uIHByb3BlcnRpZXMgKGxpa2UgdGhlaXIgaGlkZGVuIHN0YXRlKVxubW9kdWxlLmV4cG9ydHMgPSBDb2x1bW5zID0gTW9kZWwuZXh0ZW5kXG5cbiAgZGVmYXVsdHM6XG4gICAgc2NhbGluZzogXCJsaW5cIiAjIG9mIHRoZSBjb25zZXJ2YXRpb24gY2hhcnQgZS5nLiBcImxpblwiLCBcImV4cFwiLCBcImxvZ1wiXG5cbiAgaW5pdGlhbGl6ZTogLT5cbiAgICAjIGhpZGRlbiBjb2x1bW5zXG4gICAgQC5zZXQgXCJoaWRkZW5cIiwgW10gdW5sZXNzIEAuZ2V0KFwiaGlkZGVuXCIpP1xuXG4gICMgYXNzdW1lcyBoaWRkZW4gY29sdW1ucyBhcmUgc29ydGVkXG4gICMgQHJldHVybnMgbiBbaW50XSBudW1iZXIgb2YgaGlkZGVuIGNvbHVtbnMgdW50aWwgblxuICBjYWxjSGlkZGVuQ29sdW1uczogKG4pIC0+XG4gICAgaGlkZGVuID0gQGdldCBcImhpZGRlblwiXG4gICAgbmV3WCA9IG5cbiAgICBmb3IgaSBpbiBoaWRkZW5cbiAgICAgIGlmIGkgPD0gbmV3WFxuICAgICAgICBuZXdYKytcbiAgICBuZXdYIC0gblxuXG4gICMgY2FsY3MgY29uc2VydmF0aW9uXG4gIF9jYWxjQ29uc2VydmF0aW9uUHJlOiAoc2VxcykgLT5cblxuICAgICMgZW1lcmdlbmN5IGN1dG9mZlxuICAgIGNvbnNvbGUubG9nIHNlcXMubGVuZ3RoXG4gICAgaWYgc2Vxcy5sZW5ndGggPiAxMDAwXG4gICAgICByZXR1cm5cblxuICAgICMgY2FsYyBjb25zZW5zdXNcbiAgICBjb25zID0gY29uc2VudXMoc2VxcylcbiAgICBzZXFzID0gc2Vxcy5tYXAgKGVsKSAtPiBlbC5nZXQgXCJzZXFcIlxuICAgIG5NYXggPSAoXy5tYXggc2VxcywgKGVsKSAtPiBlbC5sZW5ndGgpLmxlbmd0aFxuXG4gICAgdG90YWwgPSBuZXcgQXJyYXkgbk1heFxuICAgIG1hdGNoZXMgPSBuZXcgQXJyYXkgbk1heFxuICAgICMgY2FsYyBkZXJpdmF0aW9uIGZyb20gY29uc2VudXNcbiAgICBfLmVhY2ggc2VxcywgKGVsLGkpIC0+XG4gICAgICBfLmVhY2ggZWwsIChjaGFyLCBwb3MpIC0+XG4gICAgICAgICNpZiBjb25zW3Bvc10gaXNudCBcIi1cIiBhbmQgbWF0Y2hlc1twb3NdIGlzbnQgZ2FwXG4gICAgICAgIHRvdGFsW3Bvc10gPSB0b3RhbFtwb3NdICsgMSB8fCAxXG4gICAgICAgIG1hdGNoZXNbcG9zXSA9IG1hdGNoZXNbcG9zXSArIDEgfHwgMSBpZiBjb25zW3Bvc10gaXMgY2hhclxuICAgIFttYXRjaGVzLCB0b3RhbCwgbk1heF1cblxuICBjYWxjQ29uc2VydmF0aW9uOiAoc2VxcykgLT5cbiAgICBpZiBAYXR0cmlidXRlcy5zY2FsaW5nIGlzIFwiZXhwXCJcbiAgICAgIHJldHVybiBAY2FsY0NvbnNlcnZhdGlvbkV4cCBzZXFzXG4gICAgZWxzZSBpZiBAYXR0cmlidXRlcy5zY2FsaW5nIGlzIFwibG9nXCJcbiAgICAgIHJldHVybiBAY2FsY0NvbnNlcnZhdGlvbkxvZyBzZXFzXG4gICAgZWxzZSBpZiBAYXR0cmlidXRlcy5zY2FsaW5nIGlzIFwibGluXCJcbiAgICAgIHJldHVybiBAY2FsY0NvbnNlcnZhdGlvbkxpbiBzZXFzXG5cbiAgIyAocGVyY2VudGFnZSBvZiBjaGFycyBvZiB0aGUgY29uc2VudXMgc2VxKVxuICBjYWxjQ29uc2VydmF0aW9uTGluOiAoc2VxcykgLT5cbiAgICBbbWF0Y2hlcyx0b3RhbCwgbk1heF0gPSBAX2NhbGNDb25zZXJ2YXRpb25QcmUgc2Vxc1xuICAgIGZvciBpIGluIFswIC4uIG5NYXggLSAxXVxuICAgICAgbWF0Y2hlc1tpXSA9IG1hdGNoZXNbaV0gLyB0b3RhbFtpXVxuICAgIEAuc2V0IFwiY29uc2VydlwiLCBtYXRjaGVzXG4gICAgbWF0Y2hlc1xuXG4gICMgKHBlcmNlbnRhZ2Ugb2YgY2hhcnMgb2YgdGhlIGNvbnNlbnVzIHNlcSlcbiAgY2FsY0NvbnNlcnZhdGlvbkxvZzogKHNlcXMpIC0+XG4gICAgW21hdGNoZXMsdG90YWwsIG5NYXhdID0gQF9jYWxjQ29uc2VydmF0aW9uUHJlIHNlcXNcbiAgICBmb3IgaSBpbiBbMCAuLiBuTWF4IC0gMV1cbiAgICAgIG1hdGNoZXNbaV0gPSBNYXRoLmxvZyhtYXRjaGVzW2ldICsgMSkgLyBNYXRoLmxvZyh0b3RhbFtpXSArIDEpXG4gICAgQC5zZXQgXCJjb25zZXJ2XCIsIG1hdGNoZXNcbiAgICBtYXRjaGVzXG5cbiAgY2FsY0NvbnNlcnZhdGlvbkV4cDogKHNlcXMpIC0+XG4gICAgW21hdGNoZXMsdG90YWwsIG5NYXhdID0gQF9jYWxjQ29uc2VydmF0aW9uUHJlIHNlcXNcbiAgICBmb3IgaSBpbiBbMCAuLiBuTWF4IC0gMV1cbiAgICAgIG1hdGNoZXNbaV0gPSBNYXRoLmV4cChtYXRjaGVzW2ldICsgMSkgLyBNYXRoLmV4cCh0b3RhbFtpXSArIDEpXG4gICAgQC5zZXQgXCJjb25zZXJ2XCIsIG1hdGNoZXNcbiAgICBtYXRjaGVzXG4iLCJNb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG5cbiMgc2ltcGxlIHVzZXIgY29uZmlnXG5tb2R1bGUuZXhwb3J0cyA9IENvbmZpZyA9IE1vZGVsLmV4dGVuZFxuXG4gIGRlZmF1bHRzOlxuICAgIHJlZ2lzdGVyTW91c2VIb3ZlcjogZmFsc2UsXG4gICAgcmVnaXN0ZXJNb3VzZUNsaWNrczogdHJ1ZSxcbiAgICBpbXBvcnRQcm94eTogXCJodHRwczovL2NvcnMtYW55d2hlcmUuaGVyb2t1YXBwLmNvbS9cIlxuICAgIGV2ZW50QnVzOiB0cnVlXG4iLCJNb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG5jb25zZW51c0NhbGMgPSByZXF1aXJlIFwiLi4vYWxnby9Db25zZW5zdXNDYWxjXCJcblxuIyBzaW1wbHkgc2F2ZSB0aGUgY29uc2VudXMgc2VxdWVuY2VzIGdsb2JhbGx5XG5tb2R1bGUuZXhwb3J0cyA9IENvbnNlbnVzID0gTW9kZWwuZXh0ZW5kXG5cbiAgZGVmYXVsdHM6XG4gICAgY29uc2VudXMgOiBcIlwiXG5cbiAgZ2V0Q29uc2Vuc3VzOiAoc2VxcykgLT5cbiAgICAjIGVtZXJnZW5jeSBjdXRvZmZcbiAgICBpZiBzZXFzLmxlbmd0aCA+IDEwMDBcbiAgICAgIHJldHVyblxuXG4gICAgY29ucyA9IGNvbnNlbnVzQ2FsYyhzZXFzKVxuICAgIEAuc2V0IFwiY29uc2VudXNcIiwgY29uc1xuICAgIGNvbnNcbiIsIl8gPSByZXF1aXJlIFwidW5kZXJzY29yZVwiXG5Nb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG5cbiMgaG9sZHMgdGhlIGN1cnJlbnQgdXNlciBzZWxlY3Rpb25cblNlbGVjdGlvbiA9IE1vZGVsLmV4dGVuZFxuICBkZWZhdWx0czpcbiAgICB0eXBlOiBcInN1cGVyXCJcblxuUm93U2VsZWN0aW9uID0gU2VsZWN0aW9uLmV4dGVuZFxuICBkZWZhdWx0czogXy5leHRlbmQge30sIFNlbGVjdGlvbjo6LmRlZmF1bHRzLFxuICAgIHR5cGU6IFwicm93XCJcbiAgICBzZXFJZDogXCJcIlxuXG4gIGluUm93OiAoc2VxSWQpIC0+XG4gICAgc2VxSWQgaXMgQC5nZXQgXCJzZXFJZFwiXG5cbiAgaW5Db2x1bW46IChyb3dQb3MpIC0+XG4gICAgdHJ1ZVxuXG4gIGdldExlbmd0aDogLT5cbiAgICAxXG5cbkNvbHVtblNlbGVjdGlvbiA9IFNlbGVjdGlvbi5leHRlbmRcbiAgZGVmYXVsdHM6IF8uZXh0ZW5kIHt9LCBTZWxlY3Rpb246Oi5kZWZhdWx0cyxcbiAgICB0eXBlOiBcImNvbHVtblwiXG4gICAgeFN0YXJ0OiAtMVxuICAgIHhFbmQ6IC0xXG5cbiAgaW5Sb3c6ICgpIC0+XG4gICAgdHJ1ZVxuXG4gIGluQ29sdW1uOiAocm93UG9zKSAtPlxuICAgIHhTdGFydCA8PSByb3dQb3MgJiYgcm93UG9zIDw9IHhFbmRcblxuICBnZXRMZW5ndGg6IC0+XG4gICAgeEVuZCAtIHhTdGFydFxuXG4jIHBvcyBpcyBhIG1peGluIG9mIGNvbHVtbiBhbmQgcm93XG4jIHN0YXJ0IHdpdGggUm93IGFuZCBvbmx5IG92ZXJ3cml0ZSBcImluQ29sdW1uXCIgZnJvbSBDb2x1bW5cblBvc1NlbGVjdGlvbiA9IFJvd1NlbGVjdGlvbi5leHRlbmQgXy5leHRlbmQge30sXy5waWNrKENvbHVtblNlbGVjdGlvbixcImluQ29sdW1uXCIpLFxuICBfLnBpY2soQ29sdW1uU2VsZWN0aW9uLFwiZ2V0TGVuZ3RoXCIpXG5cbiAgIyBtZXJnZSBib3RoIGRlZmF1bHRzXG4gIGRlZmF1bHRzOiBfLmV4dGVuZCB7fSwgQ29sdW1uU2VsZWN0aW9uOjouZGVmYXVsdHMsIFJvd1NlbGVjdGlvbjo6LmRlZmF1bHRzLFxuICAgIHR5cGU6IFwicG9zXCJcblxubW9kdWxlLmV4cG9ydHMuc2VsID0gU2VsZWN0aW9uXG5tb2R1bGUuZXhwb3J0cy5wb3NzZWwgPSBQb3NTZWxlY3Rpb25cbm1vZHVsZS5leHBvcnRzLnJvd3NlbCA9IFJvd1NlbGVjdGlvblxubW9kdWxlLmV4cG9ydHMuY29sdW1uc2VsID0gQ29sdW1uU2VsZWN0aW9uXG4iLCJzZWwgPSByZXF1aXJlIFwiLi9TZWxlY3Rpb25cIlxuXyA9IHJlcXVpcmUgXCJ1bmRlcnNjb3JlXCJcbkNvbGxlY3Rpb24gPSByZXF1aXJlKFwiYmFja2JvbmUtdGhpblwiKS5Db2xsZWN0aW9uXG5cbiMgaG9sZHMgdGhlIGN1cnJlbnQgdXNlciBzZWxlY3Rpb25cbm1vZHVsZS5leHBvcnRzID0gU2VsZWN0aW9uTWFuYWdlciA9IENvbGxlY3Rpb24uZXh0ZW5kXG5cbiAgbW9kZWw6IHNlbC5zZWxcblxuICBpbml0aWFsaXplOiAoZGF0YSwgb3B0cykgLT5cbiAgICBAZyA9IG9wdHMuZ1xuXG4gICAgQGxpc3RlblRvIEBnLCBcInJlc2lkdWU6Y2xpY2tcIiwgKGUpIC0+XG4gICAgICBAX2hhbmRsZUUgZS5ldnQsIG5ldyBzZWwucG9zc2VsXG4gICAgICAgIHhTdGFydDogZS5yb3dQb3NcbiAgICAgICAgeEVuZDogZS5yb3dQb3NcbiAgICAgICAgc2VxSWQ6IGUuc2VxSWRcblxuICAgIEBsaXN0ZW5UbyBAZywgXCJyb3c6Y2xpY2tcIiwgKGUpIC0+XG4gICAgICBAX2hhbmRsZUUgZS5ldnQsIG5ldyBzZWwucm93c2VsXG4gICAgICAgIHhTdGFydDogZS5yb3dQb3NcbiAgICAgICAgeEVuZDogZS5yb3dQb3NcbiAgICAgICAgc2VxSWQ6IGUuc2VxSWRcblxuICAgIEBsaXN0ZW5UbyBAZywgXCJjb2x1bW46Y2xpY2tcIiwgKGUpIC0+XG4gICAgICBAX2hhbmRsZUUgZS5ldnQsIG5ldyBzZWwuY29sdW1uc2VsXG4gICAgICAgIHhTdGFydDogZS5yb3dQb3NcbiAgICAgICAgeEVuZDogZS5yb3dQb3MgKyBlLnN0ZXBTaXplIC0gMVxuXG4gICAgI0BsaXN0ZW5UbyBALCBcImFkZCByZXNldFwiLCAoZSkgLT5cbiAgICAgICNAX3JlZHVjZUNvbHVtbnMoKVxuXG4gIGdldFNlbEZvclJvdzogKHNlcUlkKSAtPlxuICAgIEBmaWx0ZXIgKGVsKSAtPiBlbC5pblJvdyBzZXFJZFxuXG4gIGdldFNlbEZvckNvbHVtbnM6IChyb3dQb3MpIC0+XG4gICAgQGZpbHRlciAoZWwpIC0+IGVsLmluQ29sdW1uIHJvd1Bvc1xuXG4gICMgQHJldHVybnMgYXJyYXkgb2YgYWxsIHNlbGVjdGVkIHJlc2lkdWVzIGZvciBhIHJvd1xuICBnZXRCbG9ja3NGb3JSb3c6IChzZXFJZCwgbWF4TGVuKSAtPlxuICAgIHNlbGlzID0gQGZpbHRlciAoZWwpIC0+IGVsLmluUm93IHNlcUlkXG4gICAgYmxvY2tzID0gW11cbiAgICBmb3Igc2VsaSBpbiBzZWxpc1xuICAgICAgaWYgc2VsaS5hdHRyaWJ1dGVzLnR5cGUgaXMgXCJyb3dcIlxuICAgICAgICBibG9ja3MgPSBbMC4ubWF4TGVuXVxuICAgICAgICBicmVha1xuICAgICAgZWxzZVxuICAgICAgICBibG9ja3MgPSBibG9ja3MuY29uY2F0IFtzZWxpLmF0dHJpYnV0ZXMueFN0YXJ0IC4uIHNlbGkuYXR0cmlidXRlcy54RW5kXVxuICAgIGJsb2Nrc1xuXG4gICMgQHJldHVybnMgYXJyYXkgd2l0aCBhbGwgY29sdW1ucyBiZWluZyBzZWxlY3RlZFxuICAjIGV4YW1wbGU6IDAtNC4uLiAxMi0xNCBzZWxlY3RlZCAtPiBbMCwxLDIsMyw0LDEyLDEzLDE0XVxuICBnZXRBbGxDb2x1bW5CbG9ja3M6IChjb25mKSAtPlxuICAgIG1heExlbiA9IGNvbmYubWF4TGVuXG4gICAgd2l0aFBvcyA9IGNvbmYud2l0aFBvc1xuICAgIGJsb2NrcyA9IFtdXG4gICAgaWYgY29uZi53aXRoUG9zXG4gICAgICBmaWx0ZXJlZCA9IChAZmlsdGVyIChlbCkgLT4gZWwuZ2V0KCd4U3RhcnQnKT8gKVxuICAgIGVsc2VcbiAgICAgIGZpbHRlcmVkID0gKEBmaWx0ZXIgKGVsKSAtPiBlbC5nZXQoJ3R5cGUnKSBpcyBcImNvbHVtblwiKVxuICAgIGZvciBzZWxpIGluIGZpbHRlcmVkXG4gICAgICBibG9ja3MgPSBibG9ja3MuY29uY2F0IFtzZWxpLmF0dHJpYnV0ZXMueFN0YXJ0Li5zZWxpLmF0dHJpYnV0ZXMueEVuZF1cbiAgICBibG9ja3MgPSBfLnVuaXEgYmxvY2tzXG4gICAgcmV0dXJuIGJsb2Nrc1xuXG4gICMgaW52ZXJ0cyB0aGUgY3VycmVudCBzZWxlY3Rpb24gZm9yIGNvbHVtbnNcbiAgIyBAcGFyYW0gcm93cyBbQXJyYXldIGFsbCBhdmFpbGFibGUgc2VxSWRcbiAgaW52ZXJ0Um93OiAocm93cykgLT5cbiAgICBzZWxSb3dzID0gQHdoZXJlKHR5cGU6XCJyb3dcIilcbiAgICBzZWxSb3dzID0gXy5tYXAgc2VsUm93cywgKGVsKSAtPiBlbC5hdHRyaWJ1dGVzLnNlcUlkXG4gICAgaW52ZXJ0ZWQgPSBfLmZpbHRlciByb3dzLCAoZWwpIC0+XG4gICAgICByZXR1cm4gZmFsc2UgaWYgc2VsUm93cy5pbmRleE9mKGVsKSA+PSAwICMgZXhpc3Rpbmcgc2VsZWN0aW9uXG4gICAgICB0cnVlXG4gICAgIyBtYXNzIGluc2VydFxuICAgIHMgPSBbXVxuICAgIGZvciBlbCBpbiBpbnZlcnRlZFxuICAgICAgcy5wdXNoIG5ldyBzZWwucm93c2VsKHNlcUlkOmVsKVxuICAgIGNvbnNvbGUubG9nIHNcbiAgICBAcmVzZXQgc1xuXG4gICMgaW52ZXJ0cyB0aGUgY3VycmVudCBzZWxlY3Rpb24gZm9yIHJvd3NcbiAgIyBAcGFyYW0gcm93cyBbQXJyYXldIGFsbCBhdmFpbGFibGUgcm93cyAoMC4ubWF4Lmxlbmd0aClcbiAgaW52ZXJ0Q29sOiAoY29sdW1ucykgLT5cbiAgICBzZWxDb2x1bW5zID0gQHdoZXJlKHR5cGU6XCJjb2x1bW5cIilcbiAgICBzZWxDb2x1bW5zID0gXy5yZWR1Y2Ugc2VsQ29sdW1ucywgKG1lbW8sZWwpIC0+XG4gICAgICBtZW1vLmNvbmNhdCBbZWwuYXR0cmlidXRlcy54U3RhcnQgLi4gZWwuYXR0cmlidXRlcy54RW5kXVxuICAgICwgW11cbiAgICBpbnZlcnRlZCA9IF8uZmlsdGVyIGNvbHVtbnMsIChlbCkgLT5cbiAgICAgIGlmIHNlbENvbHVtbnMuaW5kZXhPZihlbCkgPj0gMFxuICAgICAgICAjIGV4aXN0aW5nIHNlbGVjdGlvblxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIHRydWVcbiAgICAjIG1hc3MgaW5zZXJ0XG4gICAgcmV0dXJuIGlmIGludmVydGVkLmxlbmd0aCA9PSAwXG4gICAgcyA9IFtdXG4gICAgY29uc29sZS5sb2cgaW52ZXJ0ZWRcbiAgICB4U3RhcnQgPSB4RW5kID0gaW52ZXJ0ZWRbMF1cbiAgICBmb3IgZWwgaW4gaW52ZXJ0ZWRcbiAgICAgIGlmIHhFbmQgKyAxIGlzIGVsXG4gICAgICAgICMgY29udGlndW91c1xuICAgICAgICB4RW5kID0gZWxcbiAgICAgIGVsc2VcbiAgICAgICAgIyBnYXAgYmV0d2VlblxuICAgICAgICBzLnB1c2ggbmV3IHNlbC5jb2x1bW5zZWwoeFN0YXJ0OnhTdGFydCwgeEVuZDogeEVuZClcbiAgICAgICAgeFN0YXJ0ID0geEVuZCA9IGVsXG4gICAgIyBjaGVjayBmb3IgbGFzdCBnYXBcbiAgICBzLnB1c2ggbmV3IHNlbC5jb2x1bW5zZWwoeFN0YXJ0OnhTdGFydCwgeEVuZDogaW52ZXJ0ZWRbaW52ZXJ0ZWQubGVuZ3RoIC0gMV0pIGlmIHhTdGFydCBpc250IHhFbmRcbiAgICBAcmVzZXQgc1xuXG4gICMgbWV0aG9kIHRvIGRlY2lkZSB3aGV0aGVyIHRvIHN0YXJ0IGEgbmV3IHNlbGVjdGlvblxuICAjIG9yIGFwcGVuZCB0byB0aGUgb2xkIG9uZSAoZGVwZW5kaW5nIHdoZXRoZXIgQ1RSTCB3YXMgcHJlc3NlZClcbiAgX2hhbmRsZUU6IChlLCBzZWxlY3Rpb24pIC0+XG4gICAgaWYgZS5jdHJsS2V5IG9yIGUubWV0YUtleVxuICAgICAgQGFkZCBzZWxlY3Rpb25cbiAgICBlbHNlXG4gICAgICBAcmVzZXQgW3NlbGVjdGlvbl1cblxuICAjIGV4cGVyaW1lbnRhbCByZWR1Y2UgbWV0aG9kIGZvciBjb2x1bW5zXG4gIF9yZWR1Y2VDb2x1bW5zOiAtPlxuICAgIEBlYWNoIChlbCwgaW5kZXgsIGFycikgLT5cbiAgICAgIGNvbHMgPSBfLmZpbHRlciBhcnIsIChlbCkgLT4gZWwuZ2V0KCd0eXBlJykgaXMgJ2NvbHVtbidcbiAgICAgIHhTdGFydCA9IGVsLmdldCgneFN0YXJ0JylcbiAgICAgIHhFbmQgPSBlbC5nZXQoJ3hFbmQnKVxuXG4gICAgICBsZWZ0cyA9IF8uZmlsdGVyIGNvbHMsIChlbCkgLT4gZWwuZ2V0KCd4RW5kJykgaXMgKHhTdGFydCAtIDEpXG4gICAgICBmb3IgbGVmdCBpbiBsZWZ0c1xuICAgICAgICBsZWZ0LnNldCAneEVuZCcsIHhTdGFydFxuXG4gICAgICByaWdodHMgPSBfLmZpbHRlciBjb2xzLCAoZWwpIC0+IGVsLmdldCgneFN0YXJ0JykgaXMgKHhFbmQgKyAxKVxuICAgICAgZm9yIHJpZ2h0IGluIHJpZ2h0c1xuICAgICAgICByaWdodC5zZXQgJ3hTdGFydCcsIHhFbmRcblxuICAgICAgaWYgbGVmdHMubGVuZ3RoID4gMCBvciByaWdodHMubGVuZ3RoID4gMFxuICAgICAgICBjb25zb2xlLmxvZyBcInJlbW92ZWQgZWxcIlxuICAgICAgICBlbC5jb2xsZWN0aW9uLnJlbW92ZSBlbFxuIiwiTW9kZWwgPSByZXF1aXJlKFwiYmFja2JvbmUtdGhpblwiKS5Nb2RlbFxuXG4jIHZpc2libGUgYXJlYXNcbm1vZHVsZS5leHBvcnRzID0gVmlzaWJpbGl0eSA9IE1vZGVsLmV4dGVuZFxuXG4gIGRlZmF1bHRzOlxuXG4gICAgIyBmb3IgdGhlIFN0YWdlXG4gICAgb3ZlcnZpZXdCb3g6IDMwXG4gICAgaGVhZGVyQm94OiAtMVxuICAgIGFsaWdubWVudEJvZHk6IDBcbiIsIk1vZGVsID0gcmVxdWlyZShcImJhY2tib25lLXRoaW5cIikuTW9kZWxcblxuIyB2aXNpYmxlIGFyZWFzXG5tb2R1bGUuZXhwb3J0cyA9IFZpc2liaWxpdHkgPSBNb2RlbC5leHRlbmRcblxuICBkZWZhdWx0czpcbiAgICBzZXF1ZW5jZXM6IHRydWVcbiAgICBtYXJrZXJzOiB0cnVlXG4gICAgbWV0YWNlbGw6IGZhbHNlXG4gICAgY29uc2VydjogdHJ1ZVxuICAgIG92ZXJ2aWV3Ym94OiBmYWxzZVxuXG4gICAgIyBhYm91dCB0aGUgbGFiZWxzXG4gICAgbGFiZWxzOiB0cnVlXG4gICAgbGFiZWxOYW1lOiB0cnVlXG4gICAgbGFiZWxJZDogdHJ1ZVxuICAgIGxhYmVsUGFydGl0aW9uOiBmYWxzZVxuICAgIGxhYmVsQ2hlY2tib3g6IGZhbHNlXG4iLCJNb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG4jIHBpeGVsIHByb3BlcnRpZXMgZm9yIHNvbWUgY29tcG9uZW50c1xubW9kdWxlLmV4cG9ydHMgPSBab29tZXIgPSBNb2RlbC5leHRlbmRcblxuICBjb25zdHJ1Y3RvcjogKGF0dHJpYnV0ZXMsb3B0aW9ucykgLT5cbiAgICBNb2RlbC5hcHBseSBALCBhcmd1bWVudHNcbiAgICBAZyA9IG9wdGlvbnMuZ1xuICAgIEBcblxuICBkZWZhdWx0czpcblxuICAgICMgZ2VuZXJhbFxuICAgIGFsaWdubWVudFdpZHRoOiBcImF1dG9cIlxuICAgIGFsaWdubWVudEhlaWdodDogMTk1XG4gICAgY29sdW1uV2lkdGg6IDE1XG4gICAgcm93SGVpZ2h0OiAxNVxuXG4gICAgIyBsYWJlbHNcbiAgICBsYWJlbFdpZHRoOiAxMDBcbiAgICBtZXRhV2lkdGg6IDEwMFxuICAgIHRleHRWaXNpYmxlOiB0cnVlXG4gICAgbGFiZWxJZExlbmd0aDogMzBcbiAgICBsYWJlbEZvbnRzaXplOiBcIjEzcHhcIlxuICAgIGxhYmVsTGluZUhlaWdodDogXCIxM3B4XCJcblxuICAgICMgbWFya2VyXG4gICAgbWFya2VyRm9udHNpemU6IFwiMTBweFwiXG4gICAgc3RlcFNpemU6IDFcbiAgICBtYXJrZXJTdGVwU2l6ZTogMlxuXG4gICAgIyBjYW52YXNcbiAgICByZXNpZHVlRm9udDogXCIxM3B4IG1vbm9cIlxuICAgIGNhbnZhc0V2ZW50U2NhbGU6IDFcblxuICAgIGJveFJlY3RIZWlnaHQ6IDVcbiAgICBib3hSZWN0V2lkdGg6IDVcblxuICAgICMgbWVudVxuICAgIG1lbnVGb250c2l6ZTogXCIyMHB4XCJcbiAgICBtZW51SXRlbUZvbnRzaXplOiBcIjE4cHhcIlxuICAgIG1lbnVJdGVtTGluZUhlaWdodDogXCIxOHB4XCJcbiAgICBtZW51TWFyZ2luTGVmdDogXCI1cHhcIlxuICAgIG1lbnVQYWRkaW5nOiBcIjNweCA1cHggM3B4IDVweFwiXG5cbiAgICAjIGludGVybmFsIHByb3BzXG4gICAgX2FsaWdubWVudFNjcm9sbExlZnQ6IDBcbiAgICBfYWxpZ25tZW50U2Nyb2xsVG9wOiAwXG5cbiAgIyBAcGFyYW0gbiBbaW50XSBtYXhMZW5ndGggb2YgYWxsIHNlcXNcbiAgZ2V0QWxpZ25tZW50V2lkdGg6IChuKSAtPlxuICAgIGlmIEBnZXQoXCJhbGlnbm1lbnRXaWR0aFwiKSBpcyBcImF1dG9cIlxuICAgICAgQGdldChcImNvbHVtbldpZHRoXCIpICogblxuICAgIGVsc2VcbiAgICAgIEBnZXQgXCJhbGlnbm1lbnRXaWR0aFwiXG5cbiAgIyBAcGFyYW0gbiBbaW50XSBudW1iZXIgb2YgcmVzaWR1ZXMgdG8gc2Nyb2xsIHRvIHRoZSByaWdodFxuICBzZXRMZWZ0T2Zmc2V0OiAobikgLT5cbiAgICB2YWwgPSAobiAtIDEpICogQGdldCgnY29sdW1uV2lkdGgnKVxuICAgIHZhbCA9IE1hdGgubWF4IDAsIHZhbFxuICAgIEBzZXQgXCJfYWxpZ25tZW50U2Nyb2xsTGVmdFwiLCB2YWxcblxuICAjIEBwYXJhbSBuIFtpbnRdIHJvdyB0aGF0IHNob3VsZCBiZSBvbiB0b3BcbiAgc2V0VG9wT2Zmc2V0OiAobikgLT5cbiAgICB2YWwgPSAobiAtIDEpICogQGdldCgncm93SGVpZ2h0JylcbiAgICB2YWwgPSBNYXRoLm1heCAwLCB2YWxcbiAgICBAc2V0IFwiX2FsaWdubWVudFNjcm9sbFRvcFwiLHZhbFxuXG4gICMgbGVuZ3RoIG9mIGFsbCBlbGVtZW50cyBsZWZ0IHRvIHRoZSBtYWluIHNlcXVlbmNlIGJvZHk6IGxhYmVscywgbWV0YWNlbGwsIC4uXG4gIGdldExhYmVsV2lkdGg6IC0+XG4gICAgIHBhZGRpbmdMZWZ0ID0gMFxuICAgICBwYWRkaW5nTGVmdCArPSBAZ2V0IFwibGFiZWxXaWR0aFwiIGlmIEBnLnZpcy5nZXQgXCJsYWJlbHNcIlxuICAgICBwYWRkaW5nTGVmdCArPSBAZ2V0IFwibWV0YVdpZHRoXCIgaWYgQGcudmlzLmdldCBcIm1ldGFjZWxsXCJcbiAgICAgcmV0dXJuIHBhZGRpbmdMZWZ0XG5cbiAgX2FkanVzdFdpZHRoOiAoZWwsIG1vZGVsKSAtPlxuICAgIGlmIGVsLnBhcmVudE5vZGU/IGFuZCBlbC5wYXJlbnROb2RlLm9mZnNldFdpZHRoIGlzbnQgMFxuICAgICAgcGFyZW50V2lkdGggPSBlbC5wYXJlbnROb2RlLm9mZnNldFdpZHRoXG4gICAgZWxzZVxuICAgICAgcGFyZW50V2lkdGggPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoIC0gMzVcblxuICAgICMgVE9ETzogZGlydHkgaGFja1xuICAgIG1heFdpZHRoID0gcGFyZW50V2lkdGggLSBAZ2V0TGFiZWxXaWR0aCgpXG4gICAgY2FsY1dpZHRoID0gQGdldEFsaWdubWVudFdpZHRoKCBtb2RlbC5nZXRNYXhMZW5ndGgoKSAtIEBnLmNvbHVtbnMuZ2V0KCdoaWRkZW4nKS5sZW5ndGgpXG4gICAgdmFsID0gTWF0aC5taW4obWF4V2lkdGgsY2FsY1dpZHRoKVxuICAgICMgcm91bmQgdG8gYSB2YWxpZCBBQSBib3hcbiAgICB2YWwgPSBNYXRoLmZsb29yKCB2YWwgLyBAZ2V0KFwiY29sdW1uV2lkdGhcIikpICogQGdldChcImNvbHVtbldpZHRoXCIpXG4gICAgQHNldCBcImFsaWdubWVudFdpZHRoXCIsIHZhbFxuICAgICNlbC5zdHlsZS53aWR0aCA9IE1hdGgubWluIGNhbGNXaWR0aCwgbWF4V2lkdGhcblxuICAjIHVwZGF0ZXMgYm90aCBzY3JvbGwgcHJvcGVydGllcyAoaWYgbmVlZGVkKVxuICBfY2hlY2tTY3JvbGxpbmc6IChzY3JvbGxPYmosIG9wdHMpIC0+XG4gICAgeFNjcm9sbCA9IHNjcm9sbE9ialswXVxuICAgIHlTY3JvbGwgPSBzY3JvbGxPYmpbMV1cblxuICAgIEBzZXQgXCJfYWxpZ25tZW50U2Nyb2xsTGVmdFwiLCB4U2Nyb2xsLCBvcHRzXG4gICAgQHNldCBcIl9hbGlnbm1lbnRTY3JvbGxUb3BcIiwgeVNjcm9sbCwgb3B0c1xuIiwibW9kdWxlLmV4cG9ydHMubXNhID0gcmVxdWlyZShcIi4vbXNhXCIpXG5cbiMgbW9kZWxzXG5tb2R1bGUuZXhwb3J0cy5tb2RlbCA9IHJlcXVpcmUoXCIuL21vZGVsXCIpXG5cbiMgZXh0cmEgcGx1Z2lucywgZXh0ZW5zaW9uc1xubW9kdWxlLmV4cG9ydHMuYWxnbyA9IHJlcXVpcmUoXCIuL2FsZ29cIilcbm1vZHVsZS5leHBvcnRzLm1lbnUgPSByZXF1aXJlKFwiLi9tZW51XCIpXG5tb2R1bGUuZXhwb3J0cy51dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpXG5cbiMgcHJvYmFibHkgbmVlZGVkIG1vcmUgb2Z0ZW5cbm1vZHVsZS5leHBvcnRzLnNlbGVjdGlvbiA9IHJlcXVpcmUoXCIuL2cvc2VsZWN0aW9uL1NlbGVjdGlvblwiKVxubW9kdWxlLmV4cG9ydHMudmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS12aWV3alwiKVxubW9kdWxlLmV4cG9ydHMuYm9uZVZpZXcgPSByZXF1aXJlKFwiYmFja2JvbmUtY2hpbGRzXCIpXG5cbiMgY29udmVuaWVuY2Vcbm1vZHVsZS5leHBvcnRzLl8gPSByZXF1aXJlICd1bmRlcnNjb3JlJ1xubW9kdWxlLmV4cG9ydHMuJCA9IHJlcXVpcmUgJ2pib25lJ1xuXG5tb2R1bGUuZXhwb3J0cy52ZXJzaW9uID0gXCIwLjEuMFwiXG4iLCJib25lVmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS1jaGlsZHNcIilcblxuIyBtZW51IHZpZXdzXG5JbXBvcnRNZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvSW1wb3J0TWVudVwiXG5GaWx0ZXJNZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvRmlsdGVyTWVudVwiXG5TZWxlY3Rpb25NZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvU2VsZWN0aW9uTWVudVwiXG5WaXNNZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvVmlzTWVudVwiXG5Db2xvck1lbnUgPSByZXF1aXJlIFwiLi92aWV3cy9Db2xvck1lbnVcIlxuT3JkZXJpbmdNZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvT3JkZXJpbmdNZW51XCJcbkV4dHJhTWVudSA9IHJlcXVpcmUgXCIuL3ZpZXdzL0V4dHJhTWVudVwiXG5FeHBvcnRNZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvRXhwb3J0TWVudVwiXG5IZWxwTWVudSA9IHJlcXVpcmUgXCIuL3ZpZXdzL0hlbHBNZW51XCJcblxuIyB0aGlzIHZlcnkgYmFzaWMgbWVudSBkZW1vbnN0cmF0ZXMgY2FsbHMgdG8gdGhlIE1TQSBjb21wb25lbnRcbm1vZHVsZS5leHBvcnRzID0gTWVudVZpZXcgPSBib25lVmlldy5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAbXNhID0gZGF0YS5tc2FcblxuICAgIEBhZGRWaWV3ICBcIjEwX2ltcG9ydFwiLCBuZXcgSW1wb3J0TWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZ1xuICAgIEBhZGRWaWV3ICBcIjIwX2ZpbHRlclwiLCBuZXcgRmlsdGVyTWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZ1xuICAgIEBhZGRWaWV3ICBcIjMwX3NlbGVjdGlvblwiLCBuZXcgU2VsZWN0aW9uTWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZ1xuICAgIEBhZGRWaWV3ICBcIjQwX3Zpc1wiLCBuZXcgVmlzTWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZ1xuICAgIEBhZGRWaWV3ICBcIjUwX2NvbG9yXCIsIG5ldyBDb2xvck1lbnUgbW9kZWw6IEBtc2Euc2VxcywgZzpAbXNhLmdcbiAgICBAYWRkVmlldyAgXCI2MF9vcmRlcmluZ1wiLCBuZXcgT3JkZXJpbmdNZW51IG1vZGVsOiBAbXNhLnNlcXMsIGc6QG1zYS5nXG4gICAgQGFkZFZpZXcgIFwiNzBfZXh0cmFcIiwgbmV3IEV4dHJhTWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZ1xuICAgIEBhZGRWaWV3ICBcIjgwX2V4cG9ydFwiLCBuZXcgRXhwb3J0TWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZywgbXNhOkBtc2FcbiAgICBAYWRkVmlldyAgXCI5MF9oZWxwXCIsIG5ldyBIZWxwTWVudSAgZzpAbXNhLmdcblxuICByZW5kZXI6IC0+XG4gICAgQHJlbmRlclN1YnZpZXdzKClcbiAgICAjIG90aGVyXG4gICAgQGVsLnNldEF0dHJpYnV0ZSBcImNsYXNzXCIsIFwiYmlvanNfbXNhX21lbnViYXJcIlxuICAgIEBlbC5hcHBlbmRDaGlsZCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwicFwiKVxuIiwibW9kdWxlLmV4cG9ydHMuZGVmYXVsdG1lbnUgPSByZXF1aXJlKFwiLi9kZWZhdWx0bWVudVwiKVxubW9kdWxlLmV4cG9ydHMubWVudWJ1aWxkZXIgPSByZXF1aXJlKFwiLi9tZW51YnVpbGRlclwiKVxuIiwiQk1hdGggPSByZXF1aXJlIFwiLi4vdXRpbHMvYm1hdGhcIlxuamJvbmUgPSByZXF1aXJlIFwiamJvbmVcIlxudmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS12aWV3alwiKVxuXG4jamJvbmUuZm4uYWRkQ2xhc3MgPSAoY2xhc3NOYW1lKSAtPlxuIyAgZm9yIGkgaW4gWzAuLiBALmxlbmd0aCAtIDFdIGJ5IDFcbiMgICAgQFtpXS5jbGFzc0xpc3QuYWRkIGNsYXNzTmFtZVxuIyAgQFxuXG5tb2R1bGUuZXhwb3J0cyA9IE1lbnVCdWlsZGVyID0gdmlldy5leHRlbmRcblxuICAgIHNldE5hbWU6IChAbmFtZSkgLT5cbiAgICAgIEBfbm9kZXMgPSAgW11cblxuICAgIGFkZE5vZGU6IChsYWJlbCwgY2FsbGJhY2ssIGRhdGEpIC0+XG4gICAgICBzdHlsZSA9IGRhdGEuc3R5bGUgaWYgZGF0YT9cbiAgICAgIEBfbm9kZXMgPSBbXSB1bmxlc3MgQF9ub2Rlcz9cbiAgICAgIEBfbm9kZXMucHVzaCB7bGFiZWw6IGxhYmVsLCBjYWxsYmFjazogY2FsbGJhY2ssIHN0eWxlOiBzdHlsZX1cblxuICAgIGJ1aWxkRE9NOiAtPlxuICAgICAgQF9idWlsZE1cbiAgICAgICAgbm9kZXM6IEBfbm9kZXNcbiAgICAgICAgbmFtZTogQG5hbWVcblxuICAgIF9idWlsZE06IChkYXRhKSAtPlxuICAgICAgbm9kZXMgPSBkYXRhLm5vZGVzXG4gICAgICBuYW1lID0gZGF0YS5uYW1lXG5cbiAgICAgIG1lbnUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwiZGl2XCJcbiAgICAgIG1lbnUuY2xhc3NOYW1lID0gXCJkcm9wZG93biBkcm9wZG93bi10aXBcIlxuICAgICAgbWVudS5pZCA9IFwiYWRyb3AtXCIgKyBCTWF0aC51bmlxdWVJZCgpXG4gICAgICBtZW51LnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIlxuXG4gICAgICBtZW51VWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwidWxcIlxuICAgICAgbWVudVVsLmNsYXNzTmFtZSA9IFwiZHJvcGRvd24tbWVudVwiXG5cbiAgICAgICMgZHJvcGRvd24gbWVudVxuICAgICAgZm9yIG5vZGUgaW4gbm9kZXNcbiAgICAgICAgbGkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwibGlcIlxuXG4gICAgICAgIGxpLnRleHRDb250ZW50ID0gbm9kZS5sYWJlbFxuICAgICAgICBmb3Iga2V5LHN0eWxlIG9mIG5vZGUuc3R5bGVcbiAgICAgICAgICBsaS5zdHlsZVtrZXldID0gc3R5bGVcbiAgICAgICAgbGkuYWRkRXZlbnRMaXN0ZW5lciBcImNsaWNrXCIsIG5vZGUuY2FsbGJhY2tcbiAgICAgICAgaWYgQGc/XG4gICAgICAgICAgbGkuc3R5bGUubGluZUhlaWdodCA9IEBnLnpvb21lci5nZXQgXCJtZW51SXRlbUxpbmVIZWlnaHRcIlxuXG4gICAgICAgIG1lbnVVbC5hcHBlbmRDaGlsZCBsaVxuXG4gICAgICBtZW51LmFwcGVuZENoaWxkIG1lbnVVbFxuXG4gICAgICBmcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpXG4gICAgICAjIGRpcGxheSBpdFxuICAgICAgZGlzcGxheWVkQnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcImFcIlxuICAgICAgZGlzcGxheWVkQnV0dG9uLnRleHRDb250ZW50ID0gbmFtZVxuICAgICAgZGlzcGxheWVkQnV0dG9uLmNsYXNzTmFtZSA9IFwiYmlvanNfbXNhX21lbnViYXJfYWxpbmtcIlxuXG4gICAgICAjIHRpbnkgc3R5bGVcbiAgICAgIGlmIEBnP1xuICAgICAgICBtZW51VWwuc3R5bGUuZm9udFNpemUgPSBAZy56b29tZXIuZ2V0IFwibWVudUl0ZW1Gb250c2l6ZVwiXG4gICAgICAgIGRpc3BsYXllZEJ1dHRvbi5zdHlsZS5mb250U2l6ZSA9IEBnLnpvb21lci5nZXQgXCJtZW51Rm9udHNpemVcIlxuICAgICAgICBkaXNwbGF5ZWRCdXR0b24uc3R5bGUubWFyZ2luTGVmdCA9IEBnLnpvb21lci5nZXQgXCJtZW51TWFyZ2luTGVmdFwiXG4gICAgICAgIGRpc3BsYXllZEJ1dHRvbi5zdHlsZS5wYWRkaW5nID0gQGcuem9vbWVyLmdldCBcIm1lbnVQYWRkaW5nXCJcblxuICAgICAgamJvbmUoZGlzcGxheWVkQnV0dG9uKS5vbiBcImNsaWNrXCIsIChlKSA9PlxuICAgICAgICBAX3Nob3dNZW51IGUsbWVudSxkaXNwbGF5ZWRCdXR0b25cblxuICAgICAgICAjIHdhaXQgdW50aWwgZXZlbnQgaXMgYnViYmxlZCB0byB0aGUgdG9wXG4gICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0IC0+XG4gICAgICAgICAgamJvbmUoZG9jdW1lbnQuYm9keSkub25lIFwiY2xpY2tcIiwgKGUpIC0+XG4gICAgICAgICAgICBjb25zb2xlLmxvZyBcIm5leHQgY2xpY2tcIlxuICAgICAgICAgICAgbWVudS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCJcbiAgICAgICAgLCA1XG5cblxuICAgICAgZnJhZy5hcHBlbmRDaGlsZCBtZW51XG4gICAgICBmcmFnLmFwcGVuZENoaWxkIGRpc3BsYXllZEJ1dHRvblxuICAgICAgcmV0dXJuICBmcmFnXG5cbiAgICBfc2hvd01lbnU6IChlLCBtZW51LCB0YXJnZXQpIC0+XG4gICAgICAjamJvbmUobWVudSkuYWRkQ2xhc3MgXCJkcm9wZG93bi1vcGVuXCJcbiAgICAgIG1lbnUuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIlxuICAgICAgbWVudS5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIlxuXG4gICAgICByZWN0ID0gdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICBtZW51LnN0eWxlLmxlZnQgPSByZWN0LmxlZnQgKyBcInB4XCJcbiAgICAgIG1lbnUuc3R5bGUudG9wID0gKHJlY3QudG9wICsgdGFyZ2V0Lm9mZnNldEhlaWdodCkgKyBcInB4XCJcbiIsIk1lbnVCdWlsZGVyID0gcmVxdWlyZSBcIi4uL21lbnVidWlsZGVyXCJcbl8gPSByZXF1aXJlIFwidW5kZXJzY29yZVwiXG5kb20gPSByZXF1aXJlIFwiZG9tLWhlbHBlclwiXG5cbm1vZHVsZS5leHBvcnRzID0gQ29sb3JNZW51ID0gTWVudUJ1aWxkZXIuZXh0ZW5kXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQGcgPSBkYXRhLmdcbiAgICBAZWwuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcbiAgICBAbGlzdGVuVG8gQGcuY29sb3JzY2hlbWUsIFwiY2hhbmdlXCIsIC0+XG4gICAgICBAcmVuZGVyKClcblxuICByZW5kZXI6IC0+XG4gICAgbWVudUNvbG9yID0gQHNldE5hbWUoXCJDb2xvciBzY2hlbWVcIilcblxuICAgIGNvbG9yc2NoZW1lcyA9IEBnZXRDb2xvcnNjaGVtZXMoKVxuICAgIGZvciBzY2hlbWUgaW4gY29sb3JzY2hlbWVzXG4gICAgICBAYWRkU2NoZW1lIG1lbnVDb2xvciwgc2NoZW1lXG5cbiAgICB0ZXh0ID0gXCJCYWNrZ3JvdW5kXCJcbiAgICBpZiBAZy5jb2xvcnNjaGVtZS5nZXQoXCJjb2xvckJhY2tncm91bmRcIilcbiAgICAgIHRleHQgPSBcIkhpZGUgXCIgKyB0ZXh0XG4gICAgZWxzZVxuICAgICAgdGV4dCA9IFwiU2hvdyBcIiArIHRleHRcblxuICAgIEBhZGROb2RlIHRleHQsID0+XG4gICAgICBAZy5jb2xvcnNjaGVtZS5zZXQgXCJjb2xvckJhY2tncm91bmRcIiwgIUBnLmNvbG9yc2NoZW1lLmdldChcImNvbG9yQmFja2dyb3VuZFwiKVxuXG4gICAgQGdyZXkgbWVudUNvbG9yXG5cbiAgICAjIFRPRE86IG1ha2UgbW9yZSBlZmZpY2llbnRcbiAgICBkb20ucmVtb3ZlQWxsQ2hpbGRzIEBlbFxuICAgIEBlbC5hcHBlbmRDaGlsZCBAYnVpbGRET00oKVxuICAgIEBcblxuICBhZGRTY2hlbWU6IChtZW51Q29sb3Isc2NoZW1lKSAtPlxuICAgIHN0eWxlID0ge31cbiAgICBjdXJyZW50ID0gQGcuY29sb3JzY2hlbWUuZ2V0KFwic2NoZW1lXCIpXG4gICAgaWYgY3VycmVudCBpcyBzY2hlbWUuaWRcbiAgICAgIHN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwiIzc3RUQ4MFwiXG5cbiAgICBAYWRkTm9kZSBzY2hlbWUubmFtZSwgPT5cbiAgICAgIEBnLmNvbG9yc2NoZW1lLnNldCBcInNjaGVtZVwiLCBzY2hlbWUuaWRcbiAgICAsXG4gICAgICBzdHlsZTogc3R5bGVcblxuICBnZXRDb2xvcnNjaGVtZXM6IC0+XG4gICAgc2NoZW1lcyAgPSBbXVxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIlphcHBvXCIsIGlkOiBcInphcHBvXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJUYXlsb3JcIiwgaWQ6IFwidGF5bG9yXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJIeWRyb3Bob2JpY2l0eVwiLCBpZDogXCJoeWRyb1wiXG4gICAgc2NoZW1lcy5wdXNoIG5hbWU6IFwiTGVza1wiLCBpZDogXCJsZXNrXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJDaW5lbWFcIiwgaWQ6IFwiY2luZW1hXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJNQUVcIiwgaWQ6IFwibWFlXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJDbHVzdGFsXCIsIGlkOiBcImNsdXN0YWxcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIkNsdXN0YWwyXCIsIGlkOiBcImNsdXN0YWwyXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJUdXJuXCIsIGlkOiBcInR1cm5cIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIlN0cmFuZFwiLCBpZDogXCJzdHJhbmRcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIkJ1cmllZFwiLCBpZDogXCJidXJpZWRcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIkhlbGl4XCIsIGlkOiBcImhlbGl4XCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJOdWNsZW90aWRlXCIsIGlkOiBcIm51Y2xlb3RpZGVcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIlB1cmluZVwiLCBpZDogXCJwdXJpbmVcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIlBJRFwiLCBpZDogXCJwaWRcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIk5vIGNvbG9yXCIsIGlkOiBcImZvb1wiXG4gICAgc2NoZW1lc1xuXG4gIGdyZXk6IChtZW51Q29sb3IpIC0+XG4gICAgIyBncmV5cyBhbGwgbG93ZXJjYXNlIGxldHRlcnNcbiAgICBAYWRkTm9kZSBcIkdyZXlcIiwgPT5cbiAgICAgIEBnLmNvbG9yc2NoZW1lLnNldCBcInNob3dMb3dlckNhc2VcIiwgZmFsc2VcbiAgICAgIEBtb2RlbC5lYWNoIChzZXEpIC0+XG4gICAgICAgIHJlc2lkdWVzID0gc2VxLmdldCBcInNlcVwiXG4gICAgICAgIGdyZXkgPSBbXVxuICAgICAgICBfLmVhY2ggcmVzaWR1ZXMsIChlbCwgaW5kZXgpIC0+XG4gICAgICAgICAgaWYgZWwgaXMgZWwudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgZ3JleS5wdXNoIGluZGV4XG4gICAgICAgIHNlcS5zZXQgXCJncmV5XCIsIGdyZXlcblxuICAgIEBhZGROb2RlIFwiR3JleSBieSB0aHJlc2hvbGRcIiwgPT5cbiAgICAgIHRocmVzaG9sZCA9IHByb21wdCBcIkVudGVyIHRocmVzaG9sZCAoaW4gcGVyY2VudClcIiwgMjBcbiAgICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCAvIDEwMFxuICAgICAgbWF4TGVuID0gQG1vZGVsLmdldE1heExlbmd0aCgpXG4gICAgICBjb25zZXJ2ID0gQGcuY29sdW1ucy5nZXQoXCJjb25zZXJ2XCIpXG4gICAgICBncmV5ID0gW11cbiAgICAgIGZvciBpIGluIFswLi4gbWF4TGVuIC0gMV1cbiAgICAgICAgY29uc29sZS5sb2cgY29uc2VydltpXVxuICAgICAgICBpZiBjb25zZXJ2W2ldIDwgdGhyZXNob2xkXG4gICAgICAgICAgZ3JleS5wdXNoIGlcbiAgICAgIEBtb2RlbC5lYWNoIChzZXEpIC0+XG4gICAgICAgIHNlcS5zZXQgXCJncmV5XCIsIGdyZXlcblxuICAgIEBhZGROb2RlIFwiR3JleSBzZWxlY3Rpb25cIiwgPT5cbiAgICAgIG1heExlbiA9IEBtb2RlbC5nZXRNYXhMZW5ndGgoKVxuICAgICAgQG1vZGVsLmVhY2ggKHNlcSkgPT5cbiAgICAgICAgYmxvY2tzID0gQGcuc2VsY29sLmdldEJsb2Nrc0ZvclJvdyhzZXEuZ2V0KFwiaWRcIiksbWF4TGVuKVxuICAgICAgICBzZXEuc2V0IFwiZ3JleVwiLCBibG9ja3NcblxuICAgIEBhZGROb2RlIFwiUmVzZXQgZ3JleVwiLCA9PlxuICAgICAgQGcuY29sb3JzY2hlbWUuc2V0IFwic2hvd0xvd2VyQ2FzZVwiLCB0cnVlXG4gICAgICBAbW9kZWwuZWFjaCAoc2VxKSAtPlxuICAgICAgICBzZXEuc2V0IFwiZ3JleVwiLCBbXVxuIiwiTWVudUJ1aWxkZXIgPSByZXF1aXJlIFwiLi4vbWVudWJ1aWxkZXJcIlxuc2F2ZUFzID0gcmVxdWlyZSBcImJyb3dzZXItc2F2ZWFzXCJcbkZhc3RhRXhwb3J0ZXIgPSByZXF1aXJlKFwiYmlvanMtaW8tZmFzdGFcIikud3JpdGVyXG5fID0gcmVxdWlyZSBcInVuZGVyc2NvcmVcIlxuYmxvYlVSTCA9IHJlcXVpcmUgXCJibHVlaW1wX2NhbnZhc3RvYmxvYlwiXG5cbm1vZHVsZS5leHBvcnRzID0gRXhwb3J0TWVudSA9IE1lbnVCdWlsZGVyLmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQG1zYSA9IGRhdGEubXNhXG4gICAgQGVsLnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiXG5cbiAgcmVuZGVyOiAtPlxuICAgIEBzZXROYW1lKFwiRXhwb3J0XCIpXG5cbiAgICBAYWRkTm9kZSBcIkV4cG9ydCBzZXF1ZW5jZXNcIiwgPT5cbiAgICAgICMgbGltaXQgYXQgYWJvdXQgMjU2a1xuICAgICAgdGV4dCA9IEZhc3RhRXhwb3J0ZXIuZXhwb3J0IEBtb2RlbC50b0pTT04oKVxuICAgICAgYmxvYiA9IG5ldyBCbG9iKFt0ZXh0XSwge3R5cGUgOiAndGV4dC9wbGFpbid9KVxuICAgICAgc2F2ZUFzIGJsb2IsIFwiYWxsLmZhc3RhXCJcblxuICAgIEBhZGROb2RlIFwiRXhwb3J0IHNlbGVjdGlvblwiLCA9PlxuICAgICAgc2VsZWN0aW9uID0gQGcuc2VsY29sLnBsdWNrIFwic2VxSWRcIlxuICAgICAgaWYgc2VsZWN0aW9uP1xuICAgICAgICAjIGZpbHRlciB0aG9zZSBzZXFpZHNcbiAgICAgICAgc2VsZWN0aW9uID0gQG1vZGVsLmZpbHRlciAoZWwpIC0+XG4gICAgICAgICAgXy5jb250YWlucyBzZWxlY3Rpb24sIGVsLmdldCBcImlkXCJcbiAgICAgICAgZm9yIGkgaW4gWzAuLiBzZWxlY3Rpb24ubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgICAgIHNlbGVjdGlvbltpXSA9IHNlbGVjdGlvbltpXS50b0pTT04oKVxuICAgICAgZWxzZVxuICAgICAgICBzZWxlY3Rpb24gPSBAbW9kZWwudG9KU09OKClcbiAgICAgICAgY29uc29sZS5sb2cgXCJubyBzZWxlY3Rpb24gZm91bmRcIlxuICAgICAgdGV4dCA9IEZhc3RhRXhwb3J0ZXIuZXhwb3J0IHNlbGVjdGlvblxuICAgICAgYmxvYiA9IG5ldyBCbG9iKFt0ZXh0XSwge3R5cGUgOiAndGV4dC9wbGFpbid9KVxuICAgICAgc2F2ZUFzIGJsb2IsIFwic2VsZWN0aW9uLmZhc3RhXCJcblxuICAgICMgVE9ETzogdXNlIGh0dHBzOi8vZ2l0aHViLmNvbS9ibHVlaW1wL0phdmFTY3JpcHQtQ2FudmFzLXRvLUJsb2IvYmxvYi9tYXN0ZXIvanMvY2FudmFzLXRvLWJsb2IuanNcbiAgICBAYWRkTm9kZSBcIkV4cG9ydCBpbWFnZVwiLCA9PlxuICAgICAgIyBUT0RPOiB0aGlzIGlzIHZlcnkgdWdseVxuICAgICAgY2FudmFzID0gQG1zYS5nZXRWaWV3KCdzdGFnZScpLmdldFZpZXcoJ2JvZHknKS5nZXRWaWV3KCdzZXFibG9jaycpLmVsXG4gICAgICBpZiBjYW52YXM/XG4gICAgICAgIHVybCA9IGNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpXG4gICAgICAgIHNhdmVBcyBibG9iVVJMKHVybCksIFwiYmlvanMtbXNhLnBuZ1wiLCBcImltYWdlL3BuZ1wiXG5cbiAgICAgICMgYWRkIG9jdGV0LXN0cmVhbVxuICAgICAgI3VybCA9IHVybC5yZXBsYWNlKCAvLy8gIyBjcyBoZXJlZ2V4ZXNcbiAgICAgICMvXmRhdGFbOl1pbWFnZVxcLyhwbmd8anBnfGpwZWcpWztdL2lcbiAgICAgICMvLy8sIFwiZGF0YTphcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07XCIpXG5cbiAgICBAZWwuYXBwZW5kQ2hpbGQgQGJ1aWxkRE9NKClcbiAgICBAXG4iLCJNZW51QnVpbGRlciA9IHJlcXVpcmUgXCIuLi9tZW51YnVpbGRlclwiXG5jb25zZW51cyA9IHJlcXVpcmUgXCIuLi8uLi9hbGdvL0NvbnNlbnN1c0NhbGNcIlxuU2VxID0gcmVxdWlyZSBcIi4uLy4uL21vZGVsL1NlcXVlbmNlXCJcblxubW9kdWxlLmV4cG9ydHMgPSBFeHRyYU1lbnUgPSBNZW51QnVpbGRlci5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuICAgIEBlbC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuXG4gIHJlbmRlcjogLT5cbiAgICBAc2V0TmFtZShcIkV4dHJhc1wiKVxuICAgIEBhZGROb2RlIFwiQWRkIGNvbnNlbnN1cyBzZXFcIiwgPT5cbiAgICAgIGNvbiA9IGNvbnNlbnVzKEBtb2RlbClcbiAgICAgIGNvbnNvbGUubG9nIGNvblxuICAgICAgc2VxID0gbmV3IFNlcVxuICAgICAgICBzZXE6IGNvblxuICAgICAgICBpZDogXCIwY1wiXG4gICAgICAgIG5hbWU6IFwiY29uc2VudXNcIlxuICAgICAgQG1vZGVsLmFkZCBzZXFcbiAgICAgIEBtb2RlbC5jb21wYXJhdG9yID0gKHNlcSkgLT5cbiAgICAgICAgc2VxLmdldCBcImlkXCJcbiAgICAgIEBtb2RlbC5zb3J0KClcbiAgICBAYWRkTm9kZSBcIkluY3JlYXNlIGZvbnQgc2l6ZVwiLCA9PlxuICAgICAgQGcuem9vbWVyLnNldCBcImNvbHVtbldpZHRoXCIsIEBnLnpvb21lci5nZXQoXCJjb2x1bW5XaWR0aFwiKSArIDJcbiAgICAgIEBnLnpvb21lci5zZXQgXCJsYWJlbFdpZHRoXCIsIEBnLnpvb21lci5nZXQoXCJjb2x1bW5XaWR0aFwiKSArIDVcbiAgICAgIEBnLnpvb21lci5zZXQgXCJyb3dIZWlnaHRcIiwgQGcuem9vbWVyLmdldChcInJvd0hlaWdodFwiKSArIDJcbiAgICAgIEBnLnpvb21lci5zZXQgXCJsYWJlbEZvbnRTaXplXCIsIEBnLnpvb21lci5nZXQoXCJsYWJlbEZvbnRTaXplXCIpICsgMlxuICAgIEBhZGROb2RlIFwiRGVjcmVhc2UgZm9udCBzaXplXCIsID0+XG4gICAgICBAZy56b29tZXIuc2V0IFwiY29sdW1uV2lkdGhcIiwgQGcuem9vbWVyLmdldChcImNvbHVtbldpZHRoXCIpIC0gMlxuICAgICAgQGcuem9vbWVyLnNldCBcInJvd0hlaWdodFwiLCBAZy56b29tZXIuZ2V0KFwicm93SGVpZ2h0XCIpIC0gMlxuICAgICAgQGcuem9vbWVyLnNldCBcImxhYmVsRm9udFNpemVcIiwgQGcuem9vbWVyLmdldChcImxhYmVsRm9udFNpemVcIikgLSAyXG4gICAgICBpZiBAZy56b29tZXIuZ2V0KFwiY29sdW1uV2lkdGhcIikgPCA4XG4gICAgICAgIEBnLnpvb21lci5zZXQgXCJ0ZXh0VmlzaWJsZVwiLCBmYWxzZVxuXG4gICAgQGFkZE5vZGUgXCJCYXIgY2hhcnQgZXhwIHNjYWxpbmdcIiwgPT5cbiAgICAgIEBnLmNvbHVtbnMuc2V0IFwic2NhbGluZ1wiLCBcImV4cFwiXG4gICAgQGFkZE5vZGUgXCJCYXIgY2hhcnQgbGluZWFyIHNjYWxpbmdcIiwgPT5cbiAgICAgIEBnLmNvbHVtbnMuc2V0IFwic2NhbGluZ1wiLCBcImxpblwiXG4gICAgQGFkZE5vZGUgXCJCYXIgY2hhcnQgbG9nIHNjYWxpbmdcIiwgPT5cbiAgICAgIEBnLmNvbHVtbnMuc2V0IFwic2NhbGluZ1wiLCBcImxvZ1wiXG5cbiAgICBAYWRkTm9kZSBcIk1pbmltaXplZCB3aWR0aFwiLCA9PlxuICAgICAgQGcuem9vbWVyLnNldCBcImFsaWdubWVudFdpZHRoXCIsIDYwMFxuICAgIEBhZGROb2RlIFwiTWluaW1pemVkIGhlaWdodFwiLCA9PlxuICAgICAgQGcuem9vbWVyLnNldCBcImFsaWdubWVudEhlaWdodFwiLCAxMjBcblxuICAgIEBhZGROb2RlIFwiSnVtcCB0byBhIGNvbHVtblwiLCA9PlxuICAgICAgb2Zmc2V0ID0gcHJvbXB0IFwiQ29sdW1uXCIsIFwiMjBcIlxuICAgICAgaWYgb2Zmc2V0IDwgMCBvciBvZmZzZXQgPiBAbW9kZWwuZ2V0TWF4TGVuZ3RoKCkgb3IgaXNOYU4ob2Zmc2V0KVxuICAgICAgICBhbGVydCBcImludmFsaWQgY29sdW1uXCJcbiAgICAgICAgcmV0dXJuXG4gICAgICBAZy56b29tZXIuc2V0TGVmdE9mZnNldChvZmZzZXQpXG5cbiAgICBAZWwuYXBwZW5kQ2hpbGQgQGJ1aWxkRE9NKClcbiAgICBAXG4iLCJNZW51QnVpbGRlciA9IHJlcXVpcmUgXCIuLi9tZW51YnVpbGRlclwiXG5fID0gcmVxdWlyZSBcInVuZGVyc2NvcmVcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IEZpbHRlck1lbnUgPSBNZW51QnVpbGRlci5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuICAgIEBlbC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuXG4gIHJlbmRlcjogLT5cbiAgICBAc2V0TmFtZShcIkZpbHRlclwiKVxuICAgIEBhZGROb2RlIFwiSGlkZSBjb2x1bW5zIGJ5IHRocmVzaG9sZFwiLChlKSA9PlxuICAgICAgdGhyZXNob2xkID0gcHJvbXB0IFwiRW50ZXIgdGhyZXNob2xkIChpbiBwZXJjZW50KVwiLCAyMFxuICAgICAgdGhyZXNob2xkID0gdGhyZXNob2xkIC8gMTAwXG4gICAgICBtYXhMZW4gPSBAbW9kZWwuZ2V0TWF4TGVuZ3RoKClcbiAgICAgIGhpZGRlbiA9IFtdXG4gICAgICBjb25zZXJ2ID0gQGcuY29sdW1ucy5nZXQoXCJjb25zZXJ2XCIpXG4gICAgICBmb3IgaSBpbiBbMC4uIG1heExlbiAtIDFdXG4gICAgICAgIGlmIGNvbnNlcnZbaV0gPCB0aHJlc2hvbGRcbiAgICAgICAgICBoaWRkZW4ucHVzaCBpXG4gICAgICBAZy5jb2x1bW5zLnNldCBcImhpZGRlblwiLCBoaWRkZW5cblxuICAgIEBhZGROb2RlIFwiSGlkZSBjb2x1bW5zIGJ5IHNlbGVjdGlvblwiLCA9PlxuICAgICAgaGlkZGVuT2xkID0gQGcuY29sdW1ucy5nZXQgXCJoaWRkZW5cIlxuICAgICAgaGlkZGVuID0gaGlkZGVuT2xkLmNvbmNhdCBAZy5zZWxjb2wuZ2V0QWxsQ29sdW1uQmxvY2tzIG1heExlbjogQG1vZGVsLmdldE1heExlbmd0aCgpLCB3aXRoUG9zOiB0cnVlXG4gICAgICBAZy5zZWxjb2wucmVzZXQgW11cbiAgICAgIEBnLmNvbHVtbnMuc2V0IFwiaGlkZGVuXCIsIGhpZGRlblxuXG4gICAgQGFkZE5vZGUgXCJIaWRlIGNvbHVtbnMgYnkgZ2Fwc1wiLCA9PlxuICAgICAgdGhyZXNob2xkID0gcHJvbXB0IFwiRW50ZXIgdGhyZXNob2xkIChpbiBwZXJjZW50KVwiLCAyMFxuICAgICAgdGhyZXNob2xkID0gdGhyZXNob2xkIC8gMTAwXG4gICAgICBtYXhMZW4gPSBAbW9kZWwuZ2V0TWF4TGVuZ3RoKClcbiAgICAgIGhpZGRlbiA9IFtdXG4gICAgICBmb3IgaSBpbiBbMC4uIG1heExlbiAtIDFdXG4gICAgICAgIGdhcHMgPSAwXG4gICAgICAgIHRvdGFsID0gMFxuICAgICAgICBAbW9kZWwuZWFjaCAoZWwpIC0+XG4gICAgICAgICAgZ2FwcysrIGlmIGVsLmdldCgnc2VxJylbaV0gaXMgXCItXCJcbiAgICAgICAgICB0b3RhbCsrXG4gICAgICAgIGdhcENvbnRlbnQgPSBnYXBzIC8gdG90YWxcbiAgICAgICAgaWYgZ2FwQ29udGVudCA+IHRocmVzaG9sZFxuICAgICAgICAgIGhpZGRlbi5wdXNoIGlcbiAgICAgIEBnLmNvbHVtbnMuc2V0IFwiaGlkZGVuXCIsIGhpZGRlblxuXG4gICAgQGFkZE5vZGUgXCJIaWRlIHNlcXMgYnkgaWRlbnRpdHlcIiwgPT5cbiAgICAgIHRocmVzaG9sZCA9IHByb21wdCBcIkVudGVyIHRocmVzaG9sZCAoaW4gcGVyY2VudClcIiwgMjBcbiAgICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCAvIDEwMFxuICAgICAgQG1vZGVsLmVhY2ggKGVsKSAtPlxuICAgICAgICBpZiBlbC5nZXQoJ2lkZW50aXR5JykgPCB0aHJlc2hvbGRcbiAgICAgICAgICBlbC5zZXQoJ2hpZGRlbicsIHRydWUpXG5cbiAgICBAYWRkTm9kZSBcIkhpZGUgc2VxcyBieSBzZWxlY3Rpb25cIiwgPT5cbiAgICAgIGhpZGRlbiA9IEBnLnNlbGNvbC53aGVyZSB0eXBlOiBcInJvd1wiXG4gICAgICBpZHMgPSBfLm1hcCBoaWRkZW4sIChlbCkgLT4gZWwuZ2V0KCdzZXFJZCcpXG4gICAgICBAZy5zZWxjb2wucmVzZXQgW11cbiAgICAgIEBtb2RlbC5lYWNoIChlbCkgLT5cbiAgICAgICAgaWYgaWRzLmluZGV4T2YoZWwuZ2V0KCdpZCcpKSA+PSAwXG4gICAgICAgICAgZWwuc2V0KCdoaWRkZW4nLCB0cnVlKVxuXG4gICAgQGFkZE5vZGUgXCJIaWRlIHNlcXMgYnkgZ2Fwc1wiLCA9PlxuICAgICAgdGhyZXNob2xkID0gcHJvbXB0IFwiRW50ZXIgdGhyZXNob2xkIChpbiBwZXJjZW50KVwiLCA0MFxuICAgICAgQG1vZGVsLmVhY2ggKGVsLGkpIC0+XG4gICAgICAgIHNlcSA9IGVsLmdldCgnc2VxJylcbiAgICAgICAgZ2FwcyA9IF8ucmVkdWNlIHNlcSwgKChtZW1vLCBjKSAtPiBtZW1vKysgaWYgYyBpcyAnLSc7bWVtbyksMFxuICAgICAgICBjb25zb2xlLmxvZyBnYXBzXG4gICAgICAgIGlmIGdhcHMgPiAgdGhyZXNob2xkXG4gICAgICAgICAgZWwuc2V0KCdoaWRkZW4nLCB0cnVlKVxuXG4gICAgQGFkZE5vZGUgXCJSZXNldFwiLCA9PlxuICAgICAgQGcuY29sdW1ucy5zZXQgXCJoaWRkZW5cIiwgW11cbiAgICAgIEBtb2RlbC5lYWNoIChlbCkgLT5cbiAgICAgICAgaWYgZWwuZ2V0KCdoaWRkZW4nKVxuICAgICAgICAgIGVsLnNldCgnaGlkZGVuJywgZmFsc2UpXG5cbiAgICBAZWwuYXBwZW5kQ2hpbGQgQGJ1aWxkRE9NKClcbiAgICBAXG4iLCJNZW51QnVpbGRlciA9IHJlcXVpcmUgXCIuLi9tZW51YnVpbGRlclwiXG5cbm1vZHVsZS5leHBvcnRzID0gSGVscE1lbnUgPSBNZW51QnVpbGRlci5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuXG4gIHJlbmRlcjogLT5cbiAgICBAc2V0TmFtZShcIkhlbHBcIilcbiAgICBAYWRkTm9kZSBcIkFib3V0IHRoZSBwcm9qZWN0XCIsID0+XG4gICAgICB3aW5kb3cub3BlbiBcImh0dHBzOi8vZ2l0aHViLmNvbS9ncmVlbmlmeS9iaW9qcy12aXMtbXNhXCJcbiAgICBAYWRkTm9kZSBcIlJlcG9ydCBpc3N1ZXNcIiwgPT5cbiAgICAgIHdpbmRvdy5vcGVuIFwiaHR0cHM6Ly9naXRodWIuY29tL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2EvaXNzdWVzXCJcbiAgICBAYWRkTm9kZSBcIlVzZXIgbWFudWFsXCIsID0+XG4gICAgICB3aW5kb3cub3BlbiBcImh0dHBzOi8vZ2l0aHViLmNvbS9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3dpa2lcIlxuICAgIEBlbC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuICAgIEBlbC5hcHBlbmRDaGlsZCBAYnVpbGRET00oKVxuICAgIEBcbiIsIkNsdXN0YWwgPSByZXF1aXJlIFwiYmlvanMtaW8tY2x1c3RhbFwiXG5GYXN0YVJlYWRlciA9IHJlcXVpcmUoXCJiaW9qcy1pby1mYXN0YVwiKS5wYXJzZVxuTWVudUJ1aWxkZXIgPSByZXF1aXJlIFwiLi4vbWVudWJ1aWxkZXJcIlxuY29yc1VSTCA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy9wcm94eVwiKS5jb3JzVVJMXG5cbm1vZHVsZS5leHBvcnRzID0gSW1wb3J0TWVudSA9IE1lbnVCdWlsZGVyLmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQGVsLnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiXG5cbiAgcmVuZGVyOiAtPlxuICAgIEBzZXROYW1lKFwiSW1wb3J0XCIpXG4gICAgQGFkZE5vZGUgXCJGQVNUQVwiLChlKSA9PlxuICAgICAgdXJsID0gcHJvbXB0IFwiVVJMXCIsIFwiL3Rlc3QvZHVtbXkvc2FtcGxlcy9wNTMuY2x1c3RhbG8uZmFzdGFcIlxuICAgICAgdXJsID0gY29yc1VSTCB1cmwsIEBnXG4gICAgICBGYXN0YVJlYWRlci5yZWFkIHVybCwgKHNlcXMpID0+XG4gICAgICAgICMgbWFzcyB1cGRhdGUgb24gem9vbWVyXG4gICAgICAgIHpvb21lciA9IEBnLnpvb21lci50b0pTT04oKVxuICAgICAgICAjem9vbWVyLnRleHRWaXNpYmxlID0gZmFsc2VcbiAgICAgICAgI3pvb21lci5jb2x1bW5XaWR0aCA9IDRcbiAgICAgICAgem9vbWVyLmxhYmVsV2lkdGggPSAyMDBcbiAgICAgICAgem9vbWVyLmJveFJlY3RIZWlnaHQgPSAyXG4gICAgICAgIHpvb21lci5ib3hSZWN0V2lkdGggPSAyXG4gICAgICAgIEBtb2RlbC5yZXNldCBbXVxuICAgICAgICBAZy56b29tZXIuc2V0IHpvb21lclxuICAgICAgICBAbW9kZWwucmVzZXQgc2Vxc1xuICAgICAgICBAZy5jb2x1bW5zLmNhbGNDb25zZXJ2YXRpb24gQG1vZGVsXG5cbiAgICBAYWRkTm9kZSBcIkNMVVNUQUxcIiwgPT5cbiAgICAgIHVybCA9IHByb21wdCBcIlVSTFwiLCBcIi90ZXN0L2R1bW15L3NhbXBsZXMvcDUzLmNsdXN0YWxvLmNsdXN0YWxcIlxuICAgICAgdXJsID0gY29yc1VSTCB1cmwsIEBnXG4gICAgICBDbHVzdGFsLnJlYWQgdXJsLCAoc2VxcykgPT5cbiAgICAgICAgem9vbWVyID0gQGcuem9vbWVyLnRvSlNPTigpXG4gICAgICAgICN6b29tZXIudGV4dFZpc2libGUgPSBmYWxzZVxuICAgICAgICAjem9vbWVyLmNvbHVtbldpZHRoID0gNFxuICAgICAgICB6b29tZXIubGFiZWxXaWR0aCA9IDIwMFxuICAgICAgICB6b29tZXIuYm94UmVjdEhlaWdodCA9IDJcbiAgICAgICAgem9vbWVyLmJveFJlY3RXaWR0aCA9IDJcbiAgICAgICAgQG1vZGVsLnJlc2V0IFtdXG4gICAgICAgIEBnLnpvb21lci5zZXQgem9vbWVyXG4gICAgICAgIEBtb2RlbC5yZXNldCBzZXFzXG4gICAgICAgIEBnLmNvbHVtbnMuY2FsY0NvbnNlcnZhdGlvbiBAbW9kZWxcblxuICAgIEBhZGROb2RlIFwiYWRkIHlvdXIgb3duIFBhcnNlclwiLCA9PlxuICAgICAgd2luZG93Lm9wZW4gXCJodHRwczovL2dpdGh1Yi5jb20vYmlvanMvYmlvanMyXCJcblxuICAgIEBlbC5hcHBlbmRDaGlsZCBAYnVpbGRET00oKVxuICAgIEBcbiIsIk1lbnVCdWlsZGVyID0gcmVxdWlyZSBcIi4uL21lbnVidWlsZGVyXCJcbmRvbSA9IHJlcXVpcmUgXCJkb20taGVscGVyXCJcbl8gPSByZXF1aXJlKCd1bmRlcnNjb3JlJylcblxubW9kdWxlLmV4cG9ydHMgPSBPcmRlcmluZ01lbnUgPSBNZW51QnVpbGRlci5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuICAgIEBvcmRlciA9IFwiSURcIlxuICAgIEBlbC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuXG4gIHNldE9yZGVyOiAob3JkZXIpIC0+XG4gICAgQG9yZGVyID0gb3JkZXJcbiAgICBAcmVuZGVyKClcblxuICAjIFRPRE86IG1ha2UgbW9yZSBnZW5lcmljXG4gIHJlbmRlcjogLT5cbiAgICBAc2V0TmFtZShcIk9yZGVyaW5nXCIpXG5cbiAgICBjb21wcyA9IEBnZXRDb21wYXJhdG9ycygpXG4gICAgZm9yIG0gaW4gY29tcHNcbiAgICAgIEBfYWRkTm9kZSBtXG5cbiAgICBlbCA9IEBidWlsZERPTSgpXG5cbiAgICAjIFRPRE86IG1ha2UgbW9yZSBlZmZpY2llbnRcbiAgICBkb20ucmVtb3ZlQWxsQ2hpbGRzIEBlbFxuICAgIEBlbC5hcHBlbmRDaGlsZCBlbFxuICAgIEBcblxuICBfYWRkTm9kZTogKG0pIC0+XG4gICAgdGV4dCA9IG0udGV4dFxuICAgIHN0eWxlID0ge31cbiAgICBpZiB0ZXh0IGlzIEBvcmRlclxuICAgICAgc3R5bGUuYmFja2dyb3VuZENvbG9yID0gXCIjNzdFRDgwXCJcbiAgICBAYWRkTm9kZSB0ZXh0LCA9PlxuICAgICAgbS5wcmVjb2RlKCkgaWYgbS5wcmVjb2RlP1xuICAgICAgQG1vZGVsLmNvbXBhcmF0b3IgPSBtLmNvbXBhcmF0b3JcbiAgICAgIEBtb2RlbC5zb3J0KClcbiAgICAgIEBzZXRPcmRlciBtLnRleHRcbiAgICAsXG4gICAgICBzdHlsZTogc3R5bGVcblxuICBnZXRDb21wYXJhdG9yczogLT5cbiAgICBtb2RlbHMgPSBbXVxuXG4gICAgbW9kZWxzLnB1c2ggdGV4dDogXCJJRFwiLCBjb21wYXJhdG9yOiBcImlkXCJcblxuICAgIG1vZGVscy5wdXNoIHRleHQ6IFwiSUQgRGVzY1wiLCBjb21wYXJhdG9yOiAoYSwgYikgLT5cbiAgICAgICAgLSBhLmdldChcImlkXCIpLmxvY2FsZUNvbXBhcmUoYi5nZXQoXCJpZFwiKSlcblxuICAgIG1vZGVscy5wdXNoIHRleHQ6IFwiTGFiZWxcIiwgY29tcGFyYXRvcjogXCJuYW1lXCJcblxuICAgIG1vZGVscy5wdXNoIHRleHQ6IFwiTGFiZWwgRGVzY1wiLCBjb21wYXJhdG9yOiAoYSwgYikgLT5cbiAgICAgICAgLSBhLmdldChcIm5hbWVcIikubG9jYWxlQ29tcGFyZShiLmdldChcIm5hbWVcIikpXG5cbiAgICBtb2RlbHMucHVzaCB0ZXh0OiBcIlNlcVwiLCBjb21wYXJhdG9yOiBcInNlcVwiXG5cbiAgICBtb2RlbHMucHVzaCB0ZXh0OiBcIlNlcSBEZXNjXCIsIGNvbXBhcmF0b3I6IChhLGIpIC0+XG4gICAgICAgIC0gYS5nZXQoXCJzZXFcIikubG9jYWxlQ29tcGFyZShiLmdldChcInNlcVwiKSlcblxuICAgIG1vZGVscy5wdXNoIHRleHQ6IFwiSWRlbnRpdHlcIiwgY29tcGFyYXRvcjogXCJpZGVudGl0eVwiXG5cbiAgICBtb2RlbHMucHVzaCB0ZXh0OiBcIklkZW50aXR5IERlc2NcIiwgY29tcGFyYXRvcjogKHNlcSkgLT5cbiAgICAgICAgLSBzZXEuZ2V0IFwiaWRlbnRpdHlcIlxuXG4gICAgbW9kZWxzLnB1c2ggdGV4dDogXCJQYXJ0aXRpb24gY29kZXNcIiwgY29tcGFyYXRvcjogXCJwYXJ0aXRpb25cIiwgcHJlY29kZTogPT5cbiAgICAgICMgc2V0IHBhcnRpdGlvbnMgcmFuZG9tXG4gICAgICBAZy52aXMuc2V0KCdsYWJlbFBhcnRpdGlvbicsIHRydWUpXG4gICAgICBAbW9kZWwuZWFjaCAoZWwpIC0+XG4gICAgICAgIGVsLnNldCgncGFydGl0aW9uJywgXy5yYW5kb20oMSwzKSlcblxuXG4gICAgcmV0dXJuIG1vZGVsc1xuIiwic2VsID0gcmVxdWlyZSBcIi4uLy4uL2cvc2VsZWN0aW9uL1NlbGVjdGlvblwiXG5cbk1lbnVCdWlsZGVyID0gcmVxdWlyZSBcIi4uL21lbnVidWlsZGVyXCJcblxubW9kdWxlLmV4cG9ydHMgPSBTZWxlY3Rpb25NZW51ID0gTWVudUJ1aWxkZXIuZXh0ZW5kXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQGcgPSBkYXRhLmdcbiAgICBAZWwuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcblxuICByZW5kZXI6IC0+XG4gICAgQHNldE5hbWUoXCJTZWxlY3Rpb25cIilcbiAgICBAYWRkTm9kZSBcIkZpbmQgTW90aWYgKHN1cHBvcnRzIFJlZ0V4KVwiLCA9PlxuICAgICAgc2VhcmNoID0gcHJvbXB0IFwieW91ciBzZWFyY2hcIiwgXCJEXCJcbiAgICAgICMgbWFya3MgYWxsIGhpdHNcbiAgICAgIHNlYXJjaCA9IG5ldyBSZWdFeHAgc2VhcmNoLCBcImdpXCJcbiAgICAgIHNlbGNvbCA9IEBnLnNlbGNvbFxuICAgICAgbmV3U2VsaSA9IFtdXG4gICAgICBsZWZ0ZXN0SW5kZXggPSBvcmlnSW5kZXggPSAxMDAwNDJcbiAgICAgIEBtb2RlbC5lYWNoIChzZXEpIC0+XG4gICAgICAgIHN0clNlcSA9IHNlcS5nZXQoXCJzZXFcIilcbiAgICAgICAgd2hpbGUgbWF0Y2ggPSBzZWFyY2guZXhlYyBzdHJTZXFcbiAgICAgICAgICBpbmRleCA9IG1hdGNoLmluZGV4XG4gICAgICAgICAgYXJncyA9IHt4U3RhcnQ6IGluZGV4LCB4RW5kOiBpbmRleCArIG1hdGNoWzBdLmxlbmd0aCAtIDEsIHNlcUlkOlxuICAgICAgICAgICAgc2VxLmdldChcImlkXCIpfVxuICAgICAgICAgIG5ld1NlbGkucHVzaCBuZXcgc2VsLnBvc3NlbChhcmdzKVxuICAgICAgICAgIGxlZnRlc3RJbmRleCA9IE1hdGgubWluIGluZGV4LCBsZWZ0ZXN0SW5kZXhcblxuICAgICAgaWYgbmV3U2VsaS5sZW5ndGggaXMgMFxuICAgICAgICBhbGVydCBcIm5vIHNlbGVjdGlvbiBmb3VuZFwiXG4gICAgICBzZWxjb2wucmVzZXQgbmV3U2VsaVxuXG4gICAgICAjIHNhZmV0eSBjaGVjayArIHVwZGF0ZSBvZmZzZXRcbiAgICAgIGxlZnRlc3RJbmRleCA9IDAgaWYgbGVmdGVzdEluZGV4IGlzIG9yaWdJbmRleFxuICAgICAgQGcuem9vbWVyLnNldExlZnRPZmZzZXQgbGVmdGVzdEluZGV4XG5cbiAgICBAYWRkTm9kZSBcIkludmVydCBjb2x1bW5zXCIsID0+XG4gICAgICBAZy5zZWxjb2wuaW52ZXJ0Q29sIFswLi5AbW9kZWwuZ2V0TWF4TGVuZ3RoKCldXG4gICAgQGFkZE5vZGUgXCJJbnZlcnQgcm93c1wiLCA9PlxuICAgICAgQGcuc2VsY29sLmludmVydFJvdyBAbW9kZWwucGx1Y2sgXCJpZFwiXG4gICAgQGFkZE5vZGUgXCJSZXNldFwiLCA9PlxuICAgICAgQGcuc2VsY29sLnJlc2V0KClcbiAgICBAZWwuYXBwZW5kQ2hpbGQgQGJ1aWxkRE9NKClcbiAgICBAXG4iLCJNZW51QnVpbGRlciA9IHJlcXVpcmUgXCIuLi9tZW51YnVpbGRlclwiXG5kb20gPSByZXF1aXJlIFwiZG9tLWhlbHBlclwiXG5cbm1vZHVsZS5leHBvcnRzID0gSW1wb3J0TWVudSA9IE1lbnVCdWlsZGVyLmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQGVsLnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiXG4gICAgQGxpc3RlblRvIEBnLnZpcywgXCJjaGFuZ2VcIiwgQHJlbmRlclxuXG4gIHJlbmRlcjogLT5cbiAgICBAc2V0TmFtZShcIlZpcy4gZWxlbWVudHNcIilcblxuICAgIHZpc0VsZW1lbnRzID0gQGdldFZpc0VsZW1lbnRzKClcbiAgICBmb3IgdmlzRWwgaW4gdmlzRWxlbWVudHNcbiAgICAgIEBfYWRkVmlzRWwgdmlzRWxcblxuICAgICMgb3RoZXJcbiAgICBAYWRkTm9kZSBcIlJlc2V0XCIsID0+XG4gICAgICBAZy52aXMuc2V0IFwibGFiZWxzXCIsIHRydWVcbiAgICAgIEBnLnZpcy5zZXQgXCJzZXF1ZW5jZXNcIiwgdHJ1ZVxuICAgICAgQGcudmlzLnNldCBcIm1ldGFjZWxsXCIsIHRydWVcbiAgICAgIEBnLnZpcy5zZXQgXCJjb25zZXJ2XCIsIHRydWVcbiAgICAgIEBnLnZpcy5zZXQgXCJsYWJlbElkXCIsIHRydWVcbiAgICAgIEBnLnZpcy5zZXQgXCJsYWJlbE5hbWVcIiwgdHJ1ZVxuICAgICAgQGcudmlzLnNldCBcImxhYmVsQ2hlY2tib3hcIiwgZmFsc2VcblxuICAgIEBhZGROb2RlIFwiVG9nZ2xlIG1vdXNlb3ZlciBldmVudHNcIiwgPT5cbiAgICAgIEBnLmNvbmZpZy5zZXQgXCJyZWdpc3Rlck1vdXNlSG92ZXJcIiwgIUBnLmNvbmZpZy5nZXQgXCJyZWdpc3Rlck1vdXNlSG92ZXJcIlxuXG4gICAgIyBUT0RPOiBtYWtlIG1vcmUgZWZmaWNpZW50XG4gICAgZG9tLnJlbW92ZUFsbENoaWxkcyBAZWxcbiAgICBAZWwuYXBwZW5kQ2hpbGQgQGJ1aWxkRE9NKClcbiAgICBAXG5cbiAgX2FkZFZpc0VsOiAodmlzRWwpIC0+XG4gICAgc3R5bGUgPSB7fVxuXG4gICAgaWYgQGcudmlzLmdldCB2aXNFbC5pZFxuICAgICAgcHJlID0gXCJIaWRlIFwiXG4gICAgICBzdHlsZS5jb2xvciA9IFwicmVkXCJcbiAgICBlbHNlXG4gICAgICBwcmUgPSBcIlNob3cgXCJcbiAgICAgIHN0eWxlLmNvbG9yID0gXCJncmVlblwiXG5cbiAgICBAYWRkTm9kZSAocHJlICsgdmlzRWwubmFtZSksID0+XG4gICAgICBAZy52aXMuc2V0IHZpc0VsLmlkLCAhIEBnLnZpcy5nZXQgdmlzRWwuaWRcbiAgICAsXG4gICAgICBzdHlsZTogc3R5bGVcblxuICBnZXRWaXNFbGVtZW50czogLT5cbiAgICB2aXMgPSBbXVxuICAgIHZpcy5wdXNoIG5hbWU6IFwiTWFya2Vyc1wiLCBpZDogXCJtYXJrZXJzXCJcbiAgICB2aXMucHVzaCBuYW1lOiBcIkxhYmVsc1wiLCBpZDogXCJsYWJlbHNcIlxuICAgIHZpcy5wdXNoIG5hbWU6IFwiU2VxdWVuY2VzXCIsIGlkOiBcInNlcXVlbmNlc1wiXG4gICAgdmlzLnB1c2ggbmFtZTogXCJNZXRhIGluZm9cIiwgaWQ6IFwibWV0YWNlbGxcIlxuICAgIHZpcy5wdXNoIG5hbWU6IFwiT3ZlcnZpZXdib3hcIiwgaWQ6IFwib3ZlcnZpZXdib3hcIlxuICAgIHZpcy5wdXNoIG5hbWU6IFwiY29uc2VydlwiLCBpZDogXCJjb25zZXJ2XCJcbiAgICB2aXMucHVzaCBuYW1lOiBcIkxhYmVsTmFtZVwiLCBpZDogXCJsYWJlbE5hbWVcIlxuICAgIHZpcy5wdXNoIG5hbWU6IFwiTGFiZWxJZFwiLCBpZDogXCJsYWJlbElkXCJcbiAgICB2aXMucHVzaCBuYW1lOiBcIkxhYmVsQ2hlY2tib3hcIiwgaWQ6IFwibGFiZWxDaGVja2JveFwiXG4gICAgcmV0dXJuIHZpc1xuIiwiRmVhdHVyZSA9IHJlcXVpcmUgXCIuL0ZlYXR1cmVcIlxuTW9kZWwgPSByZXF1aXJlKFwiYmFja2JvbmUtdGhpblwiKS5Nb2RlbFxuXG5tb2R1bGUuZXhwb3J0cyA9IEZlYXR1cmUgPSBNb2RlbC5leHRlbmRcblxuICBkZWZhdWx0czpcbiAgICB4U3RhcnQ6IC0xXG4gICAgeEVuZDogLTFcbiAgICBoZWlnaHQ6IC0xXG4gICAgdGV4dDogXCJcIlxuICAgIGZpbGxDb2xvcjogXCJyZWRcIlxuICAgIGZpbGxPcGFjaXR5OiAwLjVcbiAgICB0eXBlOiBcInJlY3RhbmdsZVwiXG4gICAgYm9yZGVyU2l6ZTogMVxuICAgIGJvcmRlckNvbG9yOiBcImJsYWNrXCJcbiAgICBib3JkZXJPcGFjaXR5OiAwLjVcbiAgICB2YWxpZGF0ZTogdHJ1ZVxuXG4gIHZhbGlkYXRlOiAtPlxuICAgIGlmIGlzTmFOIEBhdHRyaWJ1dGVzLnhTdGFydCBvciBpc05hTiBAYXR0cmlidXRlcy54RW5kXG4gICAgICBcImZlYXR1cmVzIG5lZWQgaW50ZWdlciBzdGFydCBhbmQgZW5kLlwiXG5cbiAgY29udGFpbnM6IChpbmRleCkgLT5cbiAgICByZXR1cm4gIEBhdHRyaWJ1dGVzLnhTdGFydCA8PSBpbmRleCAmJiBpbmRleCA8PSBAYXR0cmlidXRlcy54RW5kXG5cbiIsIkZlYXR1cmUgPSByZXF1aXJlIFwiLi9GZWF0dXJlXCJcbkNvbGxlY3Rpb24gPSByZXF1aXJlKFwiYmFja2JvbmUtdGhpblwiKS5Db2xsZWN0aW9uXG5fID0gcmVxdWlyZSBcInVuZGVyc2NvcmVcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IEZlYXR1cmVDb2wgPSBDb2xsZWN0aW9uLmV4dGVuZFxuICBtb2RlbDogRmVhdHVyZVxuXG4gIGNvbnN0cnVjdG9yOiAtPlxuICAgIEBzdGFydE9uQ2FjaGUgPSBbXVxuICAgICMgaW52YWxpZGF0ZSBjYWNoZVxuICAgIEBvbiBcImFsbFwiLCAtPlxuICAgICAgQHN0YXJ0T25DYWNoZSA9IFtdXG4gICAgLCBAXG4gICAgQ29sbGVjdGlvbi5hcHBseSBALCBhcmd1bWVudHNcblxuICAjIHJldHVybnMgYWxsIGZlYXR1cmVzIHN0YXJ0aW5nIG9uIGluZGV4XG4gIHN0YXJ0T246IChpbmRleCkgLT5cbiAgICB1bmxlc3MgQHN0YXJ0T25DYWNoZVtpbmRleF0/XG4gICAgICBAc3RhcnRPbkNhY2hlW2luZGV4XSA9IEB3aGVyZSh7eFN0YXJ0OiBpbmRleH0pXG4gICAgcmV0dXJuIEBzdGFydE9uQ2FjaGVbaW5kZXhdXG5cbiAgY29udGFpbnM6IChpbmRleCkgLT5cbiAgICBAcmVkdWNlIChlbCxtZW1vKSAtPlxuICAgICAgbWVtbyB8fCBlbC5jb250YWlucyBpbmRleFxuICAgICwgZmFsc2VcblxuICAjIGdpdmVzIHRoZSBtaW5pbWFsIG5lZWRlZCBudW1iZXIgb2Ygcm93c1xuICAjIG5vdCBhIHZlcnkgZWZmaWNpZW50IGFsZ29yaXRobVxuICAjICh0aGVyZSBpcyBvbmUgaW4gTyhuKSApXG4gIGdldE1pblJvd3M6IC0+XG5cbiAgICBsZW4gPSBAbWF4IChlbCkgLT4gZWwuZ2V0IFwieEVuZFwiXG4gICAgcm93cyA9ICgwIGZvciB4IGluIFsxLi5sZW5dKVxuXG4gICAgQGVhY2ggKGVsKSAtPlxuICAgICAgZm9yIHggaW4gW2VsLmdldChcInhTdGFydFwiKS4uZmVhdHVyZS5nZXQoXCJ4RW5kXCIpXSBieSAxXG4gICAgICAgIHJvd3NbeF0rK1xuXG4gICAgXy5tYXggcm93c1xuIiwiU2VxdWVuY2UgPSByZXF1aXJlIFwiLi9TZXF1ZW5jZVwiXG5Db2xsZWN0aW9uID0gcmVxdWlyZShcImJhY2tib25lLXRoaW5cIikuQ29sbGVjdGlvblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNlcU1hbmFnZXIgPSBDb2xsZWN0aW9uLmV4dGVuZFxuICBtb2RlbDogU2VxdWVuY2VcblxuICBjb25zdHJ1Y3RvcjogLT5cblxuICAgIENvbGxlY3Rpb24uYXBwbHkgQCwgYXJndW1lbnRzXG5cbiAgICAjIGludmFsaWRhdGUgY2FjaGVcbiAgICBAb24gXCJhbGxcIiwgLT5cbiAgICAgIEBsZW5ndGhDYWNoZSA9IG51bGxcbiAgICAsIEBcbiAgICBAbGVuZ3RoQ2FjaGUgPSBudWxsXG5cbiAgICBAXG5cbiAgIyBnaXZlcyB0aGUgbWF4IGxlbmd0aCBvZiBhbGwgc2VxdWVuY2VzXG4gICMgKGNhY2hlZClcbiAgZ2V0TWF4TGVuZ3RoOiAoKSAtPlxuICAgIHJldHVybiAwIGlmIEBtb2RlbHMubGVuZ3RoIGlzIDBcbiAgICBpZiBAbGVuZ3RoQ2FjaGUgaXMgbnVsbFxuICAgICAgQGxlbmd0aENhY2hlID0gQG1heCgoc2VxKSAtPiBzZXEuZ2V0KFwic2VxXCIpLmxlbmd0aCkuZ2V0KFwic2VxXCIpLmxlbmd0aFxuICAgIHJldHVybiBAbGVuZ3RoQ2FjaGVcblxuICAjIGdldHMgdGhlIHByZXZpb3VzIG1vZGVsXG4gICMgQHBhcmFtIGVuZGxlc3MgW2Jvb2xlYW5dIGZvciB0aGUgZmlyc3QgZWxlbWVudFxuICAjIHRydWU6IHJldHVybnMgdGhlIGxhc3QgZWxlbWVudCwgZmFsc2U6IHJldHVybnMgdW5kZWZpbmVkXG4gIHByZXY6IChtb2RlbCwgZW5kbGVzcykgLT5cbiAgICBpbmRleCA9IEBpbmRleE9mKG1vZGVsKSAtIDFcbiAgICBpbmRleCA9IEAubGVuZ3RoIC0gMSBpZiBpbmRleCA8IDAgYW5kIGVuZGxlc3NcbiAgICBAYXQoaW5kZXgpXG5cbiAgIyBnZXRzIHRoZSBuZXh0IG1vZGVsXG4gICMgQHBhcmFtIGVuZGxlc3MgW2Jvb2xlYW5dIGZvciB0aGUgbGFzdCBlbGVtZW50XG4gICMgdHJ1ZTogcmV0dXJucyB0aGUgZmlyc3QgZWxlbWVudCwgZmFsc2U6IHJldHVybnMgdW5kZWZpbmVkXG4gIG5leHQ6IChtb2RlbCwgZW5kbGVzcykgLT5cbiAgICBpbmRleCA9IEBpbmRleE9mKG1vZGVsKSArIDFcbiAgICBpbmRleCA9IDAgaWYgaW5kZXggPT0gQC5sZW5ndGggYW5kIGVuZGxlc3NcbiAgICBAYXQoaW5kZXgpXG5cbiAgIyBAcmV0dXJucyBuIFtpbnRdIG51bWJlciBvZiBoaWRkZW4gY29sdW1ucyB1bnRpbCBuXG4gIGNhbGNIaWRkZW5TZXFzOiAobikgLT5cbiAgICBuTmV3ID0gblxuICAgIGZvciBpIGluIFswLi5uTmV3XVxuICAgICAgaWYgQGF0KGkpLmdldChcImhpZGRlblwiKVxuICAgICAgICBuTmV3KytcbiAgICBuTmV3IC0gblxuXG4iLCJNb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG5GZWF0dXJlQ29sID0gcmVxdWlyZSBcIi4vRmVhdHVyZUNvbFwiXG5cbm1vZHVsZS5leHBvcnRzID0gU2VxdWVuY2UgPSBNb2RlbC5leHRlbmRcblxuICBkZWZhdWx0czpcbiAgICBuYW1lOiBcIlwiXG4gICAgaWQ6IFwiXCJcbiAgICBzZXE6IFwiXCJcblxuICBpbml0aWFsaXplOiAtPlxuICAgICMgcmVzaWR1ZXMgd2l0aG91dCBjb2xvclxuICAgIEAuc2V0IFwiZ3JleVwiLCBbXVxuICAgIEAuc2V0IFwiZmVhdHVyZXNcIiwgbmV3IEZlYXR1cmVDb2woKVxuIiwibW9kdWxlLmV4cG9ydHMuc2VxID0gcmVxdWlyZSBcIi4vU2VxdWVuY2VcIlxubW9kdWxlLmV4cG9ydHMuc2VxY29sID0gcmVxdWlyZSBcIi4vU2VxQ29sbGVjdGlvblwiXG5tb2R1bGUuZXhwb3J0cy5mZWF0dXJlID0gcmVxdWlyZSBcIi4vRmVhdHVyZVwiXG5tb2R1bGUuZXhwb3J0cy5mZWF0dXJlY29sID0gcmVxdWlyZSBcIi4vRmVhdHVyZUNvbFwiXG4iLCIjIG1vZGVsc1xuU2VxQ29sbGVjdGlvbiA9IHJlcXVpcmUgXCIuL21vZGVsL1NlcUNvbGxlY3Rpb25cIlxuXG4jIGdsb2JhbHNcbkNvbG9yYXRvciA9IHJlcXVpcmUgXCIuL2cvY29sb3JhdG9yXCJcbkNvbnNlbnN1cyA9IHJlcXVpcmUgXCIuL2cvY29uc2Vuc3VzXCJcbkNvbHVtbnMgPSByZXF1aXJlIFwiLi9nL2NvbHVtbnNcIlxuQ29uZmlnID0gcmVxdWlyZSBcIi4vZy9jb25maWdcIlxuU2VsQ29sID0gcmVxdWlyZSBcIi4vZy9zZWxlY3Rpb24vU2VsZWN0aW9uQ29sXCJcblZpc2liaWxpdHkgPSByZXF1aXJlIFwiLi9nL3Zpc2liaWxpdHlcIlxuVmlzT3JkZXJpbmcgPSByZXF1aXJlIFwiLi9nL3Zpc09yZGVyaW5nXCJcblpvb21lciA9IHJlcXVpcmUgXCIuL2cvem9vbWVyXCJcblxuIyBNViBmcm9tIGJhY2tib25lXG5ib25lVmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS1jaGlsZHNcIilcbkV2ZW50aGFuZGxlciA9IHJlcXVpcmUgXCJiaW9qcy1ldmVudHNcIlxuXG4jIE1TQSB2aWV3c1xuU3RhZ2UgPSByZXF1aXJlIFwiLi92aWV3cy9TdGFnZVwiXG5cbiMgb3B0cyBpcyBhIGRpY3Rpb25hcnkgY29uc2lzdGluZyBvZlxuIyBAcGFyYW0gZWwgW1N0cmluZ10gaWQgb3IgcmVmZXJlbmNlIHRvIGEgRE9NIGVsZW1lbnRcbiMgQHBhcmFtIHNlcXMgW1NlcUFycmF5XSBBcnJheSBvZiBzZXF1ZW5jZXMgZm9yIGluaXRsaXphdGlvblxuIyBAcGFyYW0gY29uZiBbRGljdF0gdXNlciBjb25maWdcbiMgQHBhcmFtIHZpcyBbRGljdF0gY29uZmlnIG9mIHZpc2libGUgdmlld3NcbiMgQHBhcmFtIHpvb21lciBbRGljdF0gZGlzcGxheSBzZXR0aW5ncyBsaWtlIGNvbHVtbldpZHRoXG5tb2R1bGUuZXhwb3J0cyA9IGJvbmVWaWV3LmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuXG4gICAgIyBjaGVjayBmb3IgZGVmYXVsdCBhcnJheXNcbiAgICBkYXRhLmNvbHVtbnMgPSB7fSB1bmxlc3MgZGF0YS5jb2x1bW5zP1xuICAgIGRhdGEuY29uZiA9IHt9IHVubGVzcyBkYXRhLmNvbmY/XG4gICAgZGF0YS52aXMgPSB7fSB1bmxlc3MgZGF0YS52aXM/XG4gICAgZGF0YS52aXNvcmRlciA9IHt9IHVubGVzcyBkYXRhLnZpc29yZGVyID9cbiAgICBkYXRhLnpvb21lciA9IHt9IHVubGVzcyBkYXRhLnpvb21lcj9cblxuICAgICMgZyBpcyBvdXIgZ2xvYmFsIE1lZGlhdG9yXG4gICAgQGcgPSBFdmVudGhhbmRsZXIubWl4aW4ge31cblxuICAgIGlmIGRhdGEuc2VxcyBpcyB1bmRlZmluZWQgb3IgZGF0YS5zZXFzLmxlbmd0aCBpcyAwXG4gICAgICBjb25zb2xlLmxvZyBcIndhcm5pbmcuIGVtcHR5IHNlcXMuXCJcblxuICAgICMgbG9hZCBzZXFzIGFuZCBhZGQgc3Vidmlld3NcbiAgICBAc2VxcyA9IG5ldyBTZXFDb2xsZWN0aW9uIGRhdGEuc2Vxc1xuXG4gICAgIyBwb3B1bGF0ZSBpdCBhbmQgaW5pdCB0aGUgZ2xvYmFsIG1vZGVsc1xuICAgIEBnLmNvbmZpZyA9IG5ldyBDb25maWcgZGF0YS5jb25mXG4gICAgQGcuY29uc2Vuc3VzID0gbmV3IENvbnNlbnN1cygpXG4gICAgQGcuY29sdW1ucyA9IG5ldyBDb2x1bW5zIGRhdGEuY29sdW1ucyAgIyBmb3IgYWN0aW9uIG9uIHRoZSBjb2x1bW5zIGxpa2UgaGlkaW5nXG4gICAgQGcuY29sb3JzY2hlbWUgPSBuZXcgQ29sb3JhdG9yKClcbiAgICBAZy5zZWxjb2wgPSBuZXcgU2VsQ29sIFtdLHtnOkBnfVxuICAgIEBnLnZpcyA9IG5ldyBWaXNpYmlsaXR5IGRhdGEudmlzXG4gICAgQGcudmlzb3JkZXIgPSBuZXcgVmlzT3JkZXJpbmcgZGF0YS52aXNvcmRlclxuICAgIEBnLnpvb21lciA9IG5ldyBab29tZXIgZGF0YS56b29tZXIse2c6QGd9XG5cbiAgICBAYWRkVmlldyBcInN0YWdlXCIsbmV3IFN0YWdlIHttb2RlbDogQHNlcXMsIGc6IEBnfVxuICAgIEBlbC5zZXRBdHRyaWJ1dGUgXCJjbGFzc1wiLCBcImJpb2pzX21zYV9kaXZcIlxuXG4gICAgaWYgQGcuY29uZmlnLmdldChcImV2ZW50QnVzXCIpIGlzIHRydWVcbiAgICAgIEBzdGFydEV2ZW50QnVzKClcblxuICBzdGFydEV2ZW50QnVzOiAtPlxuICAgIGJ1c09ianMgPSBbXCJjb25maWdcIiwgXCJjb25zZW5zdXNcIiwgXCJjb2x1bW5zXCIsIFwiY29sb3JzY2hlbWVcIiwgXCJzZWxjb2xcIlxuICAgICxcInZpc1wiLCBcInZpc29yZGVyXCIsIFwiem9vbWVyXCJdXG4gICAgZm9yIGtleSBpbiBidXNPYmpzXG4gICAgICBAX3Byb3h5VG9HIGtleVxuXG4gIF9wcm94eVRvRzogKGtleSkgLT5cbiAgICBAbGlzdGVuVG8gQGdba2V5XSwgXCJhbGxcIiwobmFtZSxwcmV2LG5vdykgLT5cbiAgICAgICMgc3VwcHJlc3MgZHVwbGljYXRlIGV2ZW50c1xuICAgICAgcmV0dXJuIGlmIG5hbWUgaXMgXCJjaGFuZ2VcIlxuICAgICAgIyBiYWNrYm9uZSB1c2VzIHRoZSBzZWNvbmQgYXJndW1lbnQgZm9yIHRoZSBuZXh0IHZhbHVlIC0+IHN3YXBcbiAgICAgIEBnLnRyaWdnZXIoa2V5ICsgXCI6XCIgKyBuYW1lLG5vdylcblxuICByZW5kZXI6IC0+XG4gICAgQHJlbmRlclN1YnZpZXdzKClcbiAgICBAZy52aXMuc2V0IFwibG9hZGVkXCIsIHRydWVcbiAgICBAXG4iLCJtb2R1bGUuZXhwb3J0cyA9XG4gICMgbWF0aCB1dGlsaXRpZXNcbiAgY2xhc3MgQk1hdGhcbiAgICBAcmFuZG9tSW50OiAobG93ZXIsIHVwcGVyKSAtPlxuICAgICAgIyBDYWxsZWQgd2l0aCBvbmUgYXJndW1lbnRcbiAgICAgIFtsb3dlciwgdXBwZXJdID0gWzAsIGxvd2VyXSAgICAgdW5sZXNzIHVwcGVyP1xuICAgICAgIyBMb3dlciBtdXN0IGJlIGxlc3MgdGhlbiB1cHBlclxuICAgICAgW2xvd2VyLCB1cHBlcl0gPSBbdXBwZXIsIGxvd2VyXSBpZiBsb3dlciA+IHVwcGVyXG4gICAgICAjIExhc3Qgc3RhdGVtZW50IGlzIGEgcmV0dXJuIHZhbHVlXG4gICAgICBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAodXBwZXIgLSBsb3dlciArIDEpICsgbG93ZXIpXG5cbiAgICAjIEByZXR1cm4gW0ludGVnZXJdIHJhbmRvbSBpZFxuICAgIEB1bmlxdWVJZDogKGxlbmd0aCA9IDgpIC0+XG4gICAgICBpZCA9IFwiXCJcbiAgICAgIGlkICs9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyKSB3aGlsZSBpZC5sZW5ndGggPCBsZW5ndGhcbiAgICAgIGlkLnN1YnN0ciAwLCBsZW5ndGhcblxuICAgICMgUmV0dXJucyBhIHJhbmRvbSBpbnRlZ2VyIGJldHdlZW4gbWluIChpbmNsdXNpdmUpIGFuZCBtYXggKGluY2x1c2l2ZSlcbiAgICBAZ2V0UmFuZG9tSW50OiAobWluLCBtYXgpIC0+XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbiArIDEpKSArIG1pblxuIiwibW9kdWxlLmV4cG9ydHMuYm1hdGggPSByZXF1aXJlKFwiLi9ibWF0aFwiKVxubW9kdWxlLmV4cG9ydHMucHJveHkgPSByZXF1aXJlKFwiLi9wcm94eVwiKVxubW9kdWxlLmV4cG9ydHMuc2VxZ2VuID0gcmVxdWlyZShcIi4vc2VxZ2VuXCIpXG4iLCJtb2R1bGUuZXhwb3J0cyA9IHByb3h5ID1cblxuICAgIGNvcnNVUkw6ICh1cmwsIEBnKSA9PlxuICAgICAgIyBkbyBub3QgZmlsdGVyIG9uIGxvY2FsaG9zdFxuICAgICAgcmV0dXJuIHVybCBpZiBkb2N1bWVudC5VUkwuaW5kZXhPZignbG9jYWxob3N0JykgPj0gMCBhbmQgdXJsWzBdIGlzIFwiL1wiXG5cbiAgICAgICMgcmVtb3ZlIHd3dyArIGh0dHBcbiAgICAgIHVybCA9IHVybC5yZXBsYWNlIFwid3d3XFwuXCIsIFwiXCJcbiAgICAgIHVybCA9IHVybC5yZXBsYWNlIFwiaHR0cDovL1wiLCBcIlwiXG5cbiAgICAgICMgcHJlcGVuZCBwcm94eVxuICAgICAgdXJsID0gQGcuY29uZmlnLmdldCgnaW1wb3J0UHJveHknKSArIHVybFxuICAgICAgdXJsXG4iLCJTZXF1ZW5jZSA9IHJlcXVpcmUoXCJiaW9qcy1tb2RlbFwiKS5zZXFcbkJNYXRoID0gcmVxdWlyZSBcIi4vYm1hdGhcIlxuXG5zZXFnZW4gPSBtb2R1bGUuZXhwb3J0cyA9XG4gIF9nZW5lcmF0ZVNlcXVlbmNlOiAobGVuKSAtPlxuICAgIHRleHQgPSBcIlwiXG4gICAgcG9zc2libGUgPSBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIlxuXG4gICAgZm9yIGkgaW4gWzAuLmxlbiAtIDFdIGJ5IDFcbiAgICAgIHRleHQgKz0gcG9zc2libGUuY2hhckF0IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHBvc3NpYmxlLmxlbmd0aClcbiAgICByZXR1cm4gdGV4dFxuXG4gICMgZ2VuZXJhdGVzIGEgZHVtbXkgc2VxdWVuY2VzXG4gICMgQHBhcmFtIGxlbiBbaW50XSBudW1iZXIgb2YgZ2VuZXJhdGVkIHNlcXVlbmNlc1xuICAjIEBwYXJhbSBzZXFMZW4gW2ludF0gbGVuZ3RoIG9mIHRoZSBnZW5lcmF0ZWQgc2VxdWVuY2VzXG4gIGdldER1bW15U2VxdWVuY2VzOiAobGVuLCBzZXFMZW4pIC0+XG4gICAgc2VxcyA9IFtdXG4gICAgbGVuID0gQk1hdGguZ2V0UmFuZG9tSW50IDMsNSB1bmxlc3MgbGVuP1xuICAgIHNlcUxlbiA9IEJNYXRoLmdldFJhbmRvbUludCA1MCwyMDAgdW5sZXNzIHNlcUxlbj9cblxuICAgIGZvciBpIGluIFsxLi5sZW5dIGJ5IDFcbiAgICAgIHNlcXMucHVzaCBuZXcgU2VxdWVuY2Uoc2VxZ2VuLl9nZW5lcmF0ZVNlcXVlbmNlKHNlcUxlbiksIFwic2VxXCIgKyBpLFxuICAgICAgXCJyXCIgKyBpKVxuICAgIHJldHVybiBzZXFzXG4iLCIjIG1pbmkgc3ZnIGhlbHBlclxuXG5zdmducyA9IFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuXG5zZXRBdHRyID0gKG9iaixvcHRzKSAtPlxuICBmb3IgbmFtZSwgdmFsdWUgb2Ygb3B0c1xuICAgIG9iai5zZXRBdHRyaWJ1dGVOUyBudWxsLCBuYW1lLCB2YWx1ZVxuICBvYmpcblxuQmFzZSA9IChvcHRzKSAtPlxuICBzdmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMgc3ZnbnMsICdzdmcnXG4gIHN2Zy5zZXRBdHRyaWJ1dGUgXCJ3aWR0aFwiLCBvcHRzLndpZHRoXG4gIHN2Zy5zZXRBdHRyaWJ1dGUgXCJoZWlnaHRcIiwgb3B0cy5oZWlnaHRcbiAgc3ZnXG5cblJlY3QgPSAob3B0cykgLT5cbiAgcmVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyBzdmducywgJ3JlY3QnXG4gIHNldEF0dHIgcmVjdCxvcHRzXG5cbkxpbmUgPSAob3B0cykgLT5cbiAgbGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyBzdmducywgJ2xpbmUnXG4gIHNldEF0dHIgbGluZSxvcHRzXG5cblBvbHlnb24gPSAob3B0cykgLT5cbiAgbGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyBzdmducywgJ3BvbHlnb24nXG4gIHNldEF0dHIgbGluZSxvcHRzXG5cbm1vZHVsZS5leHBvcnRzLnJlY3QgPSBSZWN0XG5tb2R1bGUuZXhwb3J0cy5saW5lID0gTGluZVxubW9kdWxlLmV4cG9ydHMucG9seWdvbiA9IFBvbHlnb25cbm1vZHVsZS5leHBvcnRzLmJhc2UgPSBCYXNlXG4iLCJib25lVmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS1jaGlsZHNcIilcblNlcUJsb2NrID0gcmVxdWlyZSBcIi4vQ2FudmFzU2VxQmxvY2tcIlxuTGFiZWxCbG9jayA9IHJlcXVpcmUgXCIuL2xhYmVscy9MYWJlbEJsb2NrXCJcblxubW9kdWxlLmV4cG9ydHMgPSBib25lVmlldy5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuXG4gICAgaWYgdHJ1ZVxuICAgICAgbGFiZWxibG9jayA9IG5ldyBMYWJlbEJsb2NrIHttb2RlbDogQG1vZGVsLCBnOiBAZ31cbiAgICAgIGxhYmVsYmxvY2sub3JkZXJpbmcgPSAtMVxuICAgICAgQGFkZFZpZXcgXCJsYWJlbGJsb2NrXCIsbGFiZWxibG9ja1xuXG4gICAgaWYgQGcudmlzLmdldCBcInNlcXVlbmNlc1wiXG4gICAgICBzZXFibG9jayA9IG5ldyBTZXFCbG9jayB7bW9kZWw6IEBtb2RlbCwgZzogQGd9XG4gICAgICBzZXFibG9jay5vcmRlcmluZyA9IDBcbiAgICAgIEBhZGRWaWV3IFwic2VxYmxvY2tcIixzZXFibG9ja1xuXG4gICAgQGxpc3RlblRvIEBnLnpvb21lciwgXCJjaGFuZ2U6YWxpZ25tZW50SGVpZ2h0XCIsIEBhZGp1c3RIZWlnaHRcbiAgICBAbGlzdGVuVG8gQGcuY29sdW1ucywgXCJjaGFuZ2U6aGlkZGVuXCIsIEBhZGp1c3RIZWlnaHRcblxuICByZW5kZXI6IC0+XG4gICAgQHJlbmRlclN1YnZpZXdzKClcbiAgICBAZWwuY2xhc3NOYW1lID0gXCJiaW9qc19tc2FfYWxib2R5XCJcbiAgICBAZWwuc3R5bGUud2hpdGVTcGFjZSA9IFwibm93cmFwXCJcbiAgICBAYWRqdXN0SGVpZ2h0KClcbiAgICBAXG5cbiAgYWRqdXN0SGVpZ2h0OiAtPlxuICAgIGlmIEBnLnpvb21lci5nZXQoXCJhbGlnbm1lbnRIZWlnaHRcIikgaXMgXCJhdXRvXCJcbiAgICAgICMgVE9ETzogZml4IHRoZSBtYWdpYyA1XG4gICAgICBAZWwuc3R5bGUuaGVpZ2h0ID0gKEBnLnpvb21lci5nZXQoXCJyb3dIZWlnaHRcIikgKiBAbW9kZWwubGVuZ3RoKSArIDVcbiAgICBlbHNlXG4gICAgICBAZWwuc3R5bGUuaGVpZ2h0ID0gQGcuem9vbWVyLmdldCBcImFsaWdubWVudEhlaWdodFwiXG5cbiAgICAjIFRPRE86IDE1IGlzIHRoZSB3aWR0aCBvZiB0aGUgc2Nyb2xsYmFyXG4gICAgQGVsLnN0eWxlLndpZHRoID0gQGdldFdpZHRoKCkgKyAxNVxuXG4gIGdldFdpZHRoOiAtPlxuICAgIHdpZHRoID0gMFxuICAgIGlmIEBnLnZpcy5nZXQgXCJsYWJlbHNcIlxuICAgICAgd2lkdGggKz0gQGcuem9vbWVyLmdldCBcImxhYmVsV2lkdGhcIlxuICAgIGlmIEBnLnZpcy5nZXQgXCJtZXRhY2VsbFwiXG4gICAgICB3aWR0aCArPSBAZy56b29tZXIuZ2V0IFwibWV0YVdpZHRoXCJcbiAgICBpZiBAZy52aXMuZ2V0IFwic2VxdWVuY2VzXCJcbiAgICAgIHdpZHRoICs9IEBnLnpvb21lci5nZXQgXCJhbGlnbm1lbnRXaWR0aFwiXG4gICAgd2lkdGhcbiIsIkV2ZW50cyA9IHJlcXVpcmUoXCJiaW9qcy1ldmVudHNcIilcblxubW9kdWxlLmV4cG9ydHMgPSBjbGFzcyBDYW52YXNDaGFyQ2FjaGVcblxuICBjb25zdHJ1Y3RvcjogKEBnKSAtPlxuICAgIEBjYWNoZSA9IHt9XG4gICAgQGNhY2hlSGVpZ2h0ID0gMFxuICAgIEBjYWNoZVdpZHRoID0gMFxuXG4gICMgcmV0dXJucyBhIGNhY2hlZCBjYW52YXNcbiAgZ2V0Rm9udFRpbGU6IChsZXR0ZXIsIHdpZHRoLCBoZWlnaHQpIC0+XG4gICAgIyB2YWxpZGF0ZSBjYWNoZVxuICAgIGlmIHdpZHRoIGlzbnQgQGNhY2hlV2lkdGggb3IgaGVpZ2h0IGlzbnQgQGNhY2hlSGVpZ2h0XG4gICAgICBAY2FjaGVIZWlnaHQgPSBoZWlnaHRcbiAgICAgIEBjYWNoZVdpZHRoID0gd2lkdGhcbiAgICAgIEBjYWNoZSA9IHt9XG5cbiAgICBpZiBAY2FjaGVbbGV0dGVyXSBpcyB1bmRlZmluZWRcbiAgICAgIEBjcmVhdGVUaWxlIGxldHRlciwgd2lkdGgsIGhlaWdodFxuXG4gICAgcmV0dXJuIEBjYWNoZVtsZXR0ZXJdXG5cbiAgIyBjcmVhdGVzIGEgY2FudmFzIHdpdGggYSBzaW5nbGUgbGV0dGVyXG4gICMgKGZvciB0aGUgZmFzdCBmb250IGNhY2hlKVxuICBjcmVhdGVUaWxlOiAobGV0dGVyLCB3aWR0aCwgaGVpZ2h0KSAtPlxuXG4gICAgY2FudmFzID0gQGNhY2hlW2xldHRlcl0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwiY2FudmFzXCJcbiAgICBjYW52YXMud2lkdGggPSB3aWR0aFxuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHRcbiAgICBAY3R4ID0gY2FudmFzLmdldENvbnRleHQgJzJkJ1xuICAgIEBjdHguZm9udCA9IEBnLnpvb21lci5nZXQgXCJyZXNpZHVlRm9udFwiXG4gICAgQGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJ1xuICAgIEBjdHgudGV4dEFsaWduID0gXCJjZW50ZXJcIlxuXG4gICAgQGN0eC5maWxsVGV4dCBsZXR0ZXIsd2lkdGggLyAyLGhlaWdodCAvIDIsd2lkdGhcbiIsImJvbmVWaWV3ID0gcmVxdWlyZShcImJhY2tib25lLWNoaWxkc1wiKVxubW91c2UgPSByZXF1aXJlIFwibW91c2UtcG9zXCJcbmNvbG9yU2VsZWN0b3IgPSByZXF1aXJlKFwiYmlvanMtdXRpbC1jb2xvcnNjaGVtZXNcIikuc2VsZWN0b3Jcbl8gPSByZXF1aXJlIFwidW5kZXJzY29yZVwiXG5qYm9uZSA9IHJlcXVpcmUgXCJqYm9uZVwiXG5DaGFyQ2FjaGUgPSByZXF1aXJlIFwiLi9DYW52YXNDaGFyQ2FjaGVcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IGJvbmVWaWV3LmV4dGVuZFxuXG4gIHRhZ05hbWU6IFwiY2FudmFzXCJcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuXG4gICAgQGxpc3RlblRvIEBnLnpvb21lciwgXCJjaGFuZ2U6X2FsaWdubWVudFNjcm9sbExlZnQgY2hhbmdlOl9hbGlnbm1lbnRTY3JvbGxUb3BcIiwgKG1vZGVsLHZhbHVlLCBvcHRpb25zKSAtPlxuICAgICAgaWYgKG5vdCBvcHRpb25zPy5vcmlnaW4/KSBvciBvcHRpb25zLm9yaWdpbiBpc250IFwiY2FudmFzc2VxXCJcbiAgICAgICAgQHJlbmRlcigpXG5cbiAgICBAbGlzdGVuVG8gQGcuY29sdW1ucyxcImNoYW5nZTpoaWRkZW5cIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAZy56b29tZXIsXCJjaGFuZ2U6YWxpZ25tZW50V2lkdGhcIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAZy5jb2xvcnNjaGVtZSwgXCJjaGFuZ2VcIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAZy5zZWxjb2wsIFwicmVzZXQgYWRkXCIsIEByZW5kZXJcblxuICAgICMgZWwgcHJvcHNcbiAgICBAZWwuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcbiAgICBAZWwuc3R5bGUub3ZlcmZsb3dYID0gXCJoaWRkZW5cIlxuICAgIEBlbC5zdHlsZS5vdmVyZmxvd1kgPSBcImhpZGRlblwiXG4gICAgQGVsLmNsYXNzTmFtZSA9IFwiYmlvanNfbXNhX3NlcWJsb2NrXCJcblxuICAgIEBjdHggPSBAZWwuZ2V0Q29udGV4dCAnMmQnXG4gICAgQGNhY2hlID0gbmV3IENoYXJDYWNoZSBAZ1xuXG4gICAgIyB0aHJvdHRsZSB0aGUgZXhwZW5zaXZlIGRyYXcgZnVuY3Rpb25cbiAgICBAdGhyb3R0bGVUaW1lID0gMFxuICAgIEB0aHJvdHRsZUNvdW50cyA9IDBcbiAgICBpZiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUud2Via2l0QXBwZWFyYW5jZT9cbiAgICAgICMgd2Via2l0IGJyb3dzZXIgLSBubyB0aHJvdHRsaW5nIG5lZWRlZFxuICAgICAgQHRocm90dGxlZERyYXcgPSAtPlxuICAgICAgICBzdGFydCA9ICtuZXcgRGF0ZSgpXG4gICAgICAgIEBkcmF3KClcbiAgICAgICAgQHRocm90dGxlVGltZSArPSArbmV3IERhdGUoKSAtIHN0YXJ0XG4gICAgICAgIEB0aHJvdHRsZUNvdW50cysrXG4gICAgICAgIGlmIEB0aHJvdHRsZUNvdW50cyA+IDE1XG4gICAgICAgICAgdFRpbWUgPSBNYXRoLmNlaWwoQHRocm90dGxlVGltZSAvIEB0aHJvdHRsZUNvdW50cylcbiAgICAgICAgICBjb25zb2xlLmxvZyBcImF2Z0RyYXdUaW1lL1dlYktpdFwiLCB0VGltZVxuICAgICAgICAgICMgcmVtb3ZlIHBlcmYgYW5hbHlzZXJcbiAgICAgICAgICBAdGhyb3R0bGVkRHJhdyA9IEBkcmF3XG4gICAgZWxzZVxuICAgICAgIyBzbG93IGJyb3dzZXJzIGxpa2UgR2Vja29cbiAgICAgIEB0aHJvdHRsZWREcmF3ID0gXy50aHJvdHRsZSBAdGhyb3R0bGVkRHJhdywgMzBcblxuICAgIEBtYW5hZ2VFdmVudHMoKVxuXG4gICMgbWVhc3VyZXMgdGhlIHRpbWUgb2YgYSByZWRyYXcgYW5kIHRodXMgc2V0IHRoZSB0aHJvdHRsZSBsaW1pdFxuICB0aHJvdHRsZWREcmF3OiAtPlxuICAgICMgK25ldyBpcyB0aGUgZmFzdGVzdDogaHR0cDovL2pzcGVyZi5jb20vbmV3LWRhdGUtdnMtZGF0ZS1ub3ctdnMtcGVyZm9ybWFuY2Utbm93LzZcbiAgICBzdGFydCA9ICtuZXcgRGF0ZSgpXG4gICAgQGRyYXcoKVxuICAgIEB0aHJvdHRsZVRpbWUgKz0gK25ldyBEYXRlKCkgLSBzdGFydFxuICAgIEB0aHJvdHRsZUNvdW50cysrXG5cbiAgICAjIHJlbW92ZSBpdHNlbGYgYWZ0ZXIgYW5hbHlzaXNcbiAgICBpZiBAdGhyb3R0bGVDb3VudHMgPiAxNVxuICAgICAgdFRpbWUgPSBNYXRoLmNlaWwoQHRocm90dGxlVGltZSAvIEB0aHJvdHRsZUNvdW50cylcbiAgICAgIGNvbnNvbGUubG9nIFwiYXZnRHJhd1RpbWVcIiwgdFRpbWVcbiAgICAgIHRUaW1lICo9ICAxLjIgIyBhZGQgc2FmZXR5IHRpbWVcbiAgICAgIHRUaW1lID0gTWF0aC5tYXggMjAsIHRUaW1lICMgbGltaXQgZm9yIHVsdHJhIGZhc3QgY29tcHV0ZXJzXG4gICAgICBAdGhyb3R0bGVkRHJhdyA9IF8udGhyb3R0bGUgQGRyYXcsIHRUaW1lXG5cbiAgbWFuYWdlRXZlbnRzOiAtPlxuICAgIGV2ZW50cyA9IHt9XG4gICAgZXZlbnRzLm1vdXNlZG93biA9IFwiX29ubW91c2Vkb3duXCJcbiAgICBldmVudHMudG91Y2hzdGFydCA9IFwiX29udG91Y2hzdGFydFwiXG5cbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUNsaWNrc1wiXG4gICAgICBldmVudHMuZGJsY2xpY2sgPSBcIl9vbmNsaWNrXCJcbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUhvdmVyXCJcbiAgICAgIGV2ZW50cy5tb3VzZWluID0gXCJfb25tb3VzZWluXCJcbiAgICAgIGV2ZW50cy5tb3VzZW91dCA9IFwiX29ubW91c2VvdXRcIlxuXG4gICAgZXZlbnRzLm1vdXNld2hlZWwgPSBcIl9vbm1vdXNld2hlZWxcIlxuICAgIGV2ZW50cy5ET01Nb3VzZVNjcm9sbCA9IFwiX29ubW91c2V3aGVlbFwiXG4gICAgQGRlbGVnYXRlRXZlbnRzIGV2ZW50c1xuXG4gICAgIyBsaXN0ZW4gZm9yIGNoYW5nZXNcbiAgICBAbGlzdGVuVG8gQGcuY29uZmlnLCBcImNoYW5nZTpyZWdpc3Rlck1vdXNlSG92ZXJcIiwgQG1hbmFnZUV2ZW50c1xuICAgIEBsaXN0ZW5UbyBAZy5jb25maWcsIFwiY2hhbmdlOnJlZ2lzdGVyTW91c2VDbGlja1wiLCBAbWFuYWdlRXZlbnRzXG4gICAgQGRyYWdTdGFydCA9IFtdXG5cbiAgZHJhdzogLT5cblxuICAgICMgZmFzdGVzdCB3YXkgdG8gY2xlYXIgdGhlIGNhbnZhc1xuICAgICMgaHR0cDovL2pzcGVyZi5jb20vY2FudmFzLWNsZWFyLXNwZWVkLzI1XG4gICAgQGVsLndpZHRoID0gQGVsLndpZHRoXG5cbiAgICByZWN0SGVpZ2h0ID0gQGcuem9vbWVyLmdldCBcInJvd0hlaWdodFwiXG5cbiAgICAjIHJlY3RzXG4gICAgQGN0eC5nbG9iYWxBbHBoYSA9IEBnLmNvbG9yc2NoZW1lLmdldCBcIm9wYWNpdHlcIlxuICAgIEBkcmF3U2VxcyAoZGF0YSkgLT4gQGRyYXdTZXEoZGF0YSwgQF9kcmF3UmVjdClcbiAgICBAY3R4Lmdsb2JhbEFscGhhID0gMVxuXG4gICAgIyBsZXR0ZXJzXG4gICAgQGRyYXdTZXFzIChkYXRhKSAtPiBAZHJhd1NlcShkYXRhLCBAX2RyYXdMZXR0ZXIpXG5cbiAgICAjIGZlYXR1cmVzLCBzZWxlY3Rpb25cbiAgICBAZHJhd1NlcXMgQGRyYXdTZXFFeHRlbmRlZFxuXG4gIGRyYXdTZXFzOiAoY2FsbGJhY2spIC0+XG4gICAgcmVjdEhlaWdodCA9IEBnLnpvb21lci5nZXQgXCJyb3dIZWlnaHRcIlxuICAgIGhpZGRlbiA9IEBnLmNvbHVtbnMuZ2V0IFwiaGlkZGVuXCJcblxuICAgIHN0YXJ0ID0gTWF0aC5tYXggMCwgTWF0aC5hYnMoTWF0aC5jZWlsKCAtIEBnLnpvb21lci5nZXQoJ19hbGlnbm1lbnRTY3JvbGxUb3AnKSAvIHJlY3RIZWlnaHQpKVxuICAgIHkgPSAtIE1hdGguYWJzKCAtIEBnLnpvb21lci5nZXQoJ19hbGlnbm1lbnRTY3JvbGxUb3AnKSAlIHJlY3RIZWlnaHQpXG4gICAgZm9yIGkgaW4gW3N0YXJ0Li4gQG1vZGVsLmxlbmd0aCAtIDFdIGJ5IDFcbiAgICAgIGNvbnRpbnVlIGlmIEBtb2RlbC5hdChpKS5nZXQoJ2hpZGRlbicpXG4gICAgICBjYWxsYmFjay5jYWxsIEAsIHttb2RlbDogQG1vZGVsLmF0KGkpLCB5OiB5LCBoaWRkZW46IGhpZGRlbn1cbiAgICAgIHkgPSB5ICsgcmVjdEhlaWdodFxuICAgICAgIyBvdXQgb2Ygdmlld3BvcnQgLSBzdG9wXG4gICAgICBpZiB5ID4gQGVsLmhlaWdodFxuICAgICAgICBicmVha1xuXG4gICMgVE9ETzogdmVyeSBleHBlbnNpdmUgbWV0aG9kXG4gIGRyYXdTZXE6IChkYXRhLCBjYWxsYmFjaykgLT5cbiAgICBzZXEgPSBkYXRhLm1vZGVsLmdldCBcInNlcVwiXG4gICAgeSA9IGRhdGEueVxuICAgIHJlY3RXaWR0aCA9IEBnLnpvb21lci5nZXQgXCJjb2x1bW5XaWR0aFwiXG4gICAgcmVjdEhlaWdodCA9IEBnLnpvb21lci5nZXQgXCJyb3dIZWlnaHRcIlxuXG4gICAgIyBza2lwIHVubmVlZGVkIGJsb2NrcyBhdCB0aGUgYmVnaW5uaW5nXG4gICAgc3RhcnQgPSBNYXRoLm1heCAwLCBNYXRoLmFicyhNYXRoLmNlaWwoIC0gQGcuem9vbWVyLmdldCgnX2FsaWdubWVudFNjcm9sbExlZnQnKSAvIHJlY3RXaWR0aCkpXG4gICAgeCA9IC0gTWF0aC5hYnMoIC0gQGcuem9vbWVyLmdldCgnX2FsaWdubWVudFNjcm9sbExlZnQnKSAlIHJlY3RXaWR0aClcblxuICAgIHJlcyA9IHtyZWN0V2lkdGg6IHJlY3RXaWR0aCwgcmVjdEhlaWdodDogcmVjdEhlaWdodCwgeTogeX1cbiAgICBlbFdpZHRoID0gQGVsLndpZHRoXG5cbiAgICBmb3IgaiBpbiBbc3RhcnQuLiBzZXEubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgYyA9IHNlcVtqXVxuICAgICAgYyA9IGMudG9VcHBlckNhc2UoKVxuXG4gICAgICAjIGNhbGwgdGhlIGN1c3RvbSBmdW5jdGlvblxuICAgICAgcmVzLnggPSB4XG4gICAgICByZXMuYyA9IGNcblxuICAgICAgIyBsb2NhbCBjYWxsIGlzIGZhc3RlciB0aGFuIGFwcGx5XG4gICAgICAjIGh0dHA6Ly9qc3BlcmYuY29tL2Z1bmN0aW9uLWNhbGxzLWRpcmVjdC12cy1hcHBseS12cy1jYWxsLXZzLWJpbmQvNlxuICAgICAgaWYgZGF0YS5oaWRkZW4uaW5kZXhPZihqKSA8IDBcbiAgICAgICAgY2FsbGJhY2sgQCxyZXNcbiAgICAgIGVsc2VcbiAgICAgICAgY29udGludWVcblxuICAgICAgIyBtb3ZlIHRvIHRoZSByaWdodFxuICAgICAgeCA9IHggKyByZWN0V2lkdGhcblxuICAgICAgIyBvdXQgb2Ygdmlld3BvcnQgLSBzdG9wXG4gICAgICBpZiB4ID4gZWxXaWR0aFxuICAgICAgICBicmVha1xuXG4gIF9kcmF3UmVjdDogKHRoYXQsIGRhdGEpIC0+XG4gICAgY29sb3IgPSB0aGF0LmNvbG9yW2RhdGEuY11cbiAgICBpZiBjb2xvcj9cbiAgICAgIHRoYXQuY3R4LmZpbGxTdHlsZSA9IGNvbG9yXG4gICAgICB0aGF0LmN0eC5maWxsUmVjdCBkYXRhLngsZGF0YS55LGRhdGEucmVjdFdpZHRoLGRhdGEucmVjdEhlaWdodFxuXG4gICMgUkVBTExZIGV4cGVuc2l2ZSBjYWxsIG9uIEZGXG4gICMgUGVyZm9ybWFuY2U6XG4gICMgY2hyb21lOiAyMDAwbXMgZHJhd0xldHRlciAtIDEwMDBtcyBkcmF3UmVjdFxuICAjIEZGOiAxNzAwbXMgZHJhd0xldHRlciAtIDMwMG1zIGRyYXdSZWN0XG4gIF9kcmF3TGV0dGVyOiAodGhhdCxkYXRhKSAtPlxuICAgIHRoYXQuY3R4LmRyYXdJbWFnZSB0aGF0LmNhY2hlLmdldEZvbnRUaWxlKGRhdGEuYywgZGF0YS5yZWN0V2lkdGgsXG4gICAgICBkYXRhLnJlY3RIZWlnaHQpLCBkYXRhLngsIGRhdGEueSxkYXRhLnJlY3RXaWR0aCxkYXRhLnJlY3RIZWlnaHRcblxuICBkcmF3U2VxRXh0ZW5kZWQ6IChkYXRhKSAtPlxuICAgIHNlcSA9IGRhdGEubW9kZWwuZ2V0IFwic2VxXCJcbiAgICByZWN0V2lkdGggPSBAZy56b29tZXIuZ2V0IFwiY29sdW1uV2lkdGhcIlxuICAgIHJlY3RIZWlnaHQgPSBAZy56b29tZXIuZ2V0IFwicm93SGVpZ2h0XCJcblxuICAgIHN0YXJ0ID0gTWF0aC5tYXggMCwgTWF0aC5hYnMoTWF0aC5jZWlsKCAtIEBnLnpvb21lci5nZXQoJ19hbGlnbm1lbnRTY3JvbGxMZWZ0JykgLyByZWN0V2lkdGgpKVxuICAgIHggPSAtIE1hdGguYWJzKCAtIEBnLnpvb21lci5nZXQoJ19hbGlnbm1lbnRTY3JvbGxMZWZ0JykgJSByZWN0V2lkdGgpXG4gICAgeFplcm8gPSB4IC0gc3RhcnQgKiByZWN0V2lkdGhcblxuICAgIHNlbGVjdGlvbiA9IEBfZ2V0U2VsZWN0aW9uIGRhdGEubW9kZWxcbiAgICBbbVByZXZTZWwsbU5leHRTZWxdID0gQF9nZXRQcmV2TmV4dFNlbGVjdGlvbiBkYXRhLm1vZGVsXG4gICAgZmVhdHVyZXMgPSBkYXRhLm1vZGVsLmdldCBcImZlYXR1cmVzXCJcblxuICAgIHlaZXJvID0gZGF0YS55XG5cbiAgICBmb3IgaiBpbiBbc3RhcnQuLiBzZXEubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgc3RhcnRzID0gZmVhdHVyZXMuc3RhcnRPbiBqXG5cbiAgICAgIGlmIGRhdGEuaGlkZGVuLmluZGV4T2YoaikgPj0gMFxuICAgICAgICBjb250aW51ZVxuXG4gICAgICBpZiBzdGFydHMubGVuZ3RoID4gMFxuICAgICAgICBmb3IgZiBpbiBzdGFydHNcbiAgICAgICAgICBAYXBwZW5kRmVhdHVyZSBmOiBmLHhaZXJvOiB4LCB5WmVybzogeVplcm9cblxuICAgICAgeCA9IHggKyByZWN0V2lkdGhcbiAgICAgICMgb3V0IG9mIHZpZXdwb3J0IC0gc3RvcFxuICAgICAgaWYgeCA+IEBlbC53aWR0aFxuICAgICAgICBicmVha1xuXG4gICAgQF9hcHBlbmRTZWxlY3Rpb24gbW9kZWw6IGRhdGEubW9kZWwsIHhaZXJvOiB4WmVybywgeVplcm86IHlaZXJvLCBoaWRkZW46XG4gICAgICBkYXRhLmhpZGRlblxuXG4gIHJlbmRlcjogLT5cblxuICAgIEBlbC5zZXRBdHRyaWJ1dGUgJ2hlaWdodCcsIEBnLnpvb21lci5nZXQgXCJhbGlnbm1lbnRIZWlnaHRcIlxuICAgIEBlbC5zZXRBdHRyaWJ1dGUgJ3dpZHRoJywgQGcuem9vbWVyLmdldCBcImFsaWdubWVudFdpZHRoXCJcblxuICAgIEBnLnpvb21lci5fYWRqdXN0V2lkdGggQGVsLCBAbW9kZWxcbiAgICBAZy56b29tZXIuX2NoZWNrU2Nyb2xsaW5nKCBAX2NoZWNrU2Nyb2xsaW5nKFtAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsTGVmdCcpLFxuICAgIEBnLnpvb21lci5nZXQoJ19hbGlnbm1lbnRTY3JvbGxUb3AnKV0gKSx7aGVhZGVyOiBcImNhbnZhc3NlcVwifSlcblxuICAgIEBjb2xvciA9IGNvbG9yU2VsZWN0b3IuZ2V0Q29sb3IgQGcuY29sb3JzY2hlbWUuZ2V0KFwic2NoZW1lXCIpXG5cbiAgICBAdGhyb3R0bGVkRHJhdygpXG4gICAgQFxuXG4gIF9vbm1vdXNlbW92ZTogKGUsIHJldmVyc2VkKSAtPlxuICAgIHJldHVybiBpZiBAZHJhZ1N0YXJ0Lmxlbmd0aCBpcyAwXG5cbiAgICBkcmFnRW5kID0gbW91c2UuYWJzIGVcbiAgICAjIHJlbGF0aXZlIHRvIGZpcnN0IGNsaWNrXG4gICAgcmVsRW5kID0gW2RyYWdFbmRbMF0gLSBAZHJhZ1N0YXJ0WzBdLCBkcmFnRW5kWzFdIC0gQGRyYWdTdGFydFsxXV1cbiAgICAjIHJlbGF0aXZlIHRvIGluaXRpYWwgc2Nyb2xsIHN0YXR1c1xuXG4gICAgIyBzY2FsZSBldmVudHNcbiAgICBzY2FsZUZhY3RvciA9IEBnLnpvb21lci5nZXQgXCJjYW52YXNFdmVudFNjYWxlXCJcbiAgICBpZiByZXZlcnNlZFxuICAgICAgc2NhbGVGYWN0b3IgPSAzXG4gICAgZm9yIGkgaW4gWzAuLjFdIGJ5IDFcbiAgICAgIHJlbEVuZFtpXSA9IHJlbEVuZFtpXSAqIHNjYWxlRmFjdG9yXG5cbiAgICAjIGNhbGN1bGF0ZSBuZXcgc2Nyb2xsaW5nIHZhbHNcbiAgICByZWxEaXN0ID0gW0BkcmFnU3RhcnRTY3JvbGxbMF0gLSByZWxFbmRbMF0sIEBkcmFnU3RhcnRTY3JvbGxbMV0gLSByZWxFbmRbMV1dXG5cbiAgICAjIHJvdW5kIHZhbHVlc1xuICAgIGZvciBpIGluIFswLi4xXSBieSAxXG4gICAgICByZWxEaXN0W2ldID0gTWF0aC5yb3VuZCByZWxEaXN0W2ldXG5cbiAgICAjIHVwZGF0ZSBzY3JvbGxiYXJcbiAgICBzY3JvbGxDb3JyZWN0ZWQgPSBAX2NoZWNrU2Nyb2xsaW5nKCByZWxEaXN0KVxuICAgIEBnLnpvb21lci5fY2hlY2tTY3JvbGxpbmcgc2Nyb2xsQ29ycmVjdGVkLCB7b3JpZ2luOiBcImNhbnZhc3NlcVwifVxuXG4gICAgIyByZXNldCBzdGFydCBpZiB1c2Ugc2Nyb2xscyBvdXQgb2YgYm91bmRzXG4gICAgZm9yIGkgaW4gWzAuLjFdIGJ5IDFcbiAgICAgIGlmIHNjcm9sbENvcnJlY3RlZFtpXSBpc250IHJlbERpc3RbaV1cbiAgICAgICAgaWYgc2Nyb2xsQ29ycmVjdGVkW2ldIGlzIDBcbiAgICAgICAgICAjIHJlc2V0IG9mIGxlZnQsIHRvcFxuICAgICAgICAgIEBkcmFnU3RhcnRbaV0gPSBkcmFnRW5kW2ldXG4gICAgICAgICAgQGRyYWdTdGFydFNjcm9sbFtpXSA9IDBcbiAgICAgICAgZWxzZVxuICAgICAgICAgICMgcmVjYWxpYnJhdGUgb24gcmlnaHQsIGJvdHRvbVxuICAgICAgICAgIEBkcmFnU3RhcnRbaV0gPSBkcmFnRW5kW2ldIC0gc2Nyb2xsQ29ycmVjdGVkW2ldXG5cbiAgICBAdGhyb3R0bGVkRHJhdygpXG5cbiAgICAjIGFib3J0IHNlbGVjdGlvbiBldmVudHMgb2YgdGhlIGJyb3dzZXIgKG1vdXNlIG9ubHkpXG4gICAgaWYgZS5wcmV2ZW50RGVmYXVsdD9cbiAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICMgY29udmVydHMgdG91Y2hlcyBpbnRvIG9sZCBtb3VzZSBldmVudFxuICBfb250b3VjaG1vdmU6IChlKSAtPlxuICAgIEBfb25tb3VzZW1vdmUgZS5jaGFuZ2VkVG91Y2hlc1swXSwgdHJ1ZVxuICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcblxuICAjIHN0YXJ0IHRoZSBkcmFnZ2luZyBtb2RlXG4gIF9vbm1vdXNlZG93bjogKGUpIC0+XG4gICAgQGRyYWdTdGFydCA9IG1vdXNlLmFicyBlXG4gICAgQGRyYWdTdGFydFNjcm9sbCA9IFtAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsTGVmdCcpLCBAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsVG9wJyldXG4gICAgamJvbmUoZG9jdW1lbnQuYm9keSkub24gJ21vdXNlbW92ZS5vdmVybW92ZScsIChlKSA9PiBAX29ubW91c2Vtb3ZlKGUpXG4gICAgamJvbmUoZG9jdW1lbnQuYm9keSkub24gJ21vdXNldXAub3ZlcnVwJywgPT4gQF9jbGVhbnVwKClcbiAgICAjamJvbmUoZG9jdW1lbnQuYm9keSkub24gJ21vdXNlb3V0Lm92ZXJvdXQnLCAoZSkgPT4gQF9vbm1vdXNld2lub3V0KGUpXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG5cbiAgIyBzdGFydHMgdGhlIHRvdWNoIG1vZGVcbiAgX29udG91Y2hzdGFydDogKGUpIC0+XG4gICAgQGRyYWdTdGFydCA9IG1vdXNlLmFicyBlLmNoYW5nZWRUb3VjaGVzWzBdXG4gICAgQGRyYWdTdGFydFNjcm9sbCA9IFtAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsTGVmdCcpLCBAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsVG9wJyldXG4gICAgamJvbmUoZG9jdW1lbnQuYm9keSkub24gJ3RvdWNobW92ZS5vdmVydG1vdmUnLCAoZSkgPT4gQF9vbnRvdWNobW92ZShlKVxuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9uICd0b3VjaGVuZC5vdmVydGVuZCB0b3VjaGxlYXZlLm92ZXJ0bGVhdmVcbiAgICB0b3VjaGNhbmNlbC5vdmVydGNhbmVsJywgKGUpID0+IEBfdG91Y2hDbGVhbnVwKGUpXG5cbiAgIyBjaGVja3Mgd2hldGhlciBtb3VzZSBtb3ZlZCBvdXQgb2YgdGhlIHdpbmRvd1xuICAjIC0+IHRlcm1pbmF0ZSBkcmFnZ2luZ1xuICBfb25tb3VzZXdpbm91dDogKGUpIC0+XG4gICAgaWYgZS50b0VsZW1lbnQgaXMgZG9jdW1lbnQuYm9keS5wYXJlbnROb2RlXG4gICAgICBAX2NsZWFudXAoKVxuXG4gICMgdGVybWluYXRlcyBkcmFnZ2luZ1xuICBfY2xlYW51cDogLT5cbiAgICBAZHJhZ1N0YXJ0ID0gW11cbiAgICAjIHJlbW92ZSBhbGwgbGlzdGVuZXJzXG4gICAgamJvbmUoZG9jdW1lbnQuYm9keSkub2ZmKCcub3Zlcm1vdmUnKVxuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9mZignLm92ZXJ1cCcpXG4gICAgamJvbmUoZG9jdW1lbnQuYm9keSkub2ZmKCcub3Zlcm91dCcpXG5cbiAgIyB0ZXJtaW5hdGVzIHRvdWNoaW5nXG4gIF90b3VjaENsZWFudXA6IChlKSAtPlxuICAgIGlmIGUuY2hhbmdlZFRvdWNoZXMubGVuZ3RoID4gMFxuICAgICAgIyBtYXliZSB3ZSBjYW4gc2VuZCBhIGZpbmFsIGV2ZW50XG4gICAgICBAX29ubW91c2Vtb3ZlIGUuY2hhbmdlZFRvdWNoZXNbMF0sIHRydWVcblxuICAgIEBkcmFnU3RhcnQgPSBbXVxuICAgICMgcmVtb3ZlIGFsbCBsaXN0ZW5lcnNcbiAgICBqYm9uZShkb2N1bWVudC5ib2R5KS5vZmYoJy5vdmVydG1vdmUnKVxuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9mZignLm92ZXJ0ZW5kJylcbiAgICBqYm9uZShkb2N1bWVudC5ib2R5KS5vZmYoJy5vdmVydGxlYXZlJylcbiAgICBqYm9uZShkb2N1bWVudC5ib2R5KS5vZmYoJy5vdmVydGNhbmNlbCcpXG5cbiAgIyBtaWdodCBiZSBpbmNvbXBhdGlibGUgd2l0aCBzb21lIGJyb3dzZXJzXG4gIF9vbm1vdXNld2hlZWw6IChlKSAtPlxuICAgIGRlbHRhID0gbW91c2Uud2hlZWxEZWx0YSBlXG4gICAgQGcuem9vbWVyLnNldCAnX2FsaWdubWVudFNjcm9sbExlZnQnLCBAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsTGVmdCcpICsgZGVsdGFbMF1cbiAgICBAZy56b29tZXIuc2V0ICdfYWxpZ25tZW50U2Nyb2xsVG9wJywgQGcuem9vbWVyLmdldCgnX2FsaWdubWVudFNjcm9sbFRvcCcpICsgZGVsdGFbMV1cbiAgICBlLnByZXZlbnREZWZhdWx0KClcblxuICBfb25jbGljazogKGUpIC0+XG4gICAgQGcudHJpZ2dlciBcInJlc2lkdWU6Y2xpY2tcIiwgQF9nZXRDbGlja1BvcyhlKVxuICAgIEB0aHJvdHRsZWREcmF3KClcblxuICBfb25tb3VzZWluOiAoZSkgLT5cbiAgICBAZy50cmlnZ2VyIFwicmVzaWR1ZTpjbGlja1wiLCBAX2dldENsaWNrUG9zKGUpXG4gICAgQHRocm90dGxlZERyYXcoKVxuXG4gIF9vbm1vdXNlb3V0OiAoZSkgLT5cbiAgICBAZy50cmlnZ2VyIFwicmVzaWR1ZTpjbGlja1wiLCBAX2dldENsaWNrUG9zKGUpXG4gICAgQHRocm90dGxlZERyYXcoKVxuXG4gIF9nZXRDbGlja1BvczogKGUpIC0+XG4gICAgY29vcmRzID0gbW91c2UucmVsIGVcbiAgICBjb29yZHNbMF0gKz0gQGcuem9vbWVyLmdldChcIl9hbGlnbm1lbnRTY3JvbGxMZWZ0XCIpXG4gICAgY29vcmRzWzFdICs9IEBnLnpvb21lci5nZXQoXCJfYWxpZ25tZW50U2Nyb2xsVG9wXCIpXG4gICAgeCA9IE1hdGguZmxvb3IoY29vcmRzWzBdIC8gQGcuem9vbWVyLmdldChcImNvbHVtbldpZHRoXCIpIClcbiAgICB5ID0gTWF0aC5mbG9vcihjb29yZHNbMV0gLyBAZy56b29tZXIuZ2V0KFwicm93SGVpZ2h0XCIpKVxuXG4gICAgIyBhZGQgaGlkZGVuIGNvbHVtbnNcbiAgICB4ICs9IEBnLmNvbHVtbnMuY2FsY0hpZGRlbkNvbHVtbnMgeFxuICAgICMgYWRkIGhpZGRlbiBzZXFzXG4gICAgeSArPSBAbW9kZWwuY2FsY0hpZGRlblNlcXMgeVxuXG4gICAgeCA9IE1hdGgubWF4IDAseFxuICAgIHkgPSBNYXRoLm1heCAwLHlcbiAgICBzZXFJZCA9IEBtb2RlbC5hdCh5KS5nZXQgXCJpZFwiXG4gICAgcmV0dXJuIHtzZXFJZDpzZXFJZCwgcm93UG9zOiB4LCBldnQ6ZX1cblxuICAjIGNoZWNrcyB3aGV0aGVyIHRoZSBzY3JvbGxpbmcgY29vcmRpbmF0ZXMgYXJlIHZhbGlkXG4gICMgQHJldHVybnM6IFt4U2Nyb2xsLHlTY3JvbGxdIHZhbGlkIGNvb3JkaW5hdGVzXG4gIF9jaGVja1Njcm9sbGluZzogKHNjcm9sbE9iaikgLT5cblxuICAgICMgMDogbWF4TGVmdCwgMTogbWF4VG9wXG4gICAgbWF4ID0gW0Btb2RlbC5nZXRNYXhMZW5ndGgoKSAqIEBnLnpvb21lci5nZXQoXCJjb2x1bW5XaWR0aFwiKSAtIEBnLnpvb21lci5nZXQoJ2FsaWdubWVudFdpZHRoJyksXG4gICAgQG1vZGVsLmxlbmd0aCAgKiBAZy56b29tZXIuZ2V0KFwicm93SGVpZ2h0XCIpIC0gQGcuem9vbWVyLmdldCgnYWxpZ25tZW50SGVpZ2h0JyldXG5cbiAgICBmb3IgaSBpbiBbMC4uMV0gYnkgMVxuICAgICAgaWYgc2Nyb2xsT2JqW2ldID4gbWF4W2ldXG4gICAgICAgIHNjcm9sbE9ialtpXSA9IG1heFtpXVxuXG4gICAgICBpZiBzY3JvbGxPYmpbaV0gPCAwXG4gICAgICAgIHNjcm9sbE9ialtpXSA9IDBcblxuICAgIHJldHVybiBzY3JvbGxPYmpcblxuICAjIFRPRE86IHNob3VsZCBJIGJlIG1vdmVkIHRvIHRoZSBzZWxlY3Rpb24gbWFuYWdlcj9cbiAgIyByZXR1cm5zIGFuIGFycmF5IHdpdGggdGhlIGN1cnJlbnRseSBzZWxlY3RlZCByZXNpZHVlc1xuICAjIGUuZy4gWzAsM10gPSBwb3MgMCBhbmQgMyBhcmUgc2VsZWN0ZWRcbiAgX2dldFNlbGVjdGlvbjogKG1vZGVsKSAtPlxuICAgIG1heExlbiA9IG1vZGVsLmdldChcInNlcVwiKS5sZW5ndGhcbiAgICBzZWxlY3Rpb24gPSBbXVxuICAgIHNlbHMgPSBAZy5zZWxjb2wuZ2V0U2VsRm9yUm93IG1vZGVsLmdldCBcImlkXCJcbiAgICByb3dzID0gXy5maW5kIHNlbHMsIChlbCkgLT4gZWwuZ2V0KFwidHlwZVwiKSBpcyBcInJvd1wiXG4gICAgaWYgcm93cz9cbiAgICAgICMgZnVsbCBtYXRjaFxuICAgICAgZm9yIG4gaW4gWzAuLm1heExlbiAtIDFdIGJ5IDFcbiAgICAgICAgc2VsZWN0aW9uLnB1c2ggblxuICAgIGVsc2UgaWYgc2Vscy5sZW5ndGggPiAwXG4gICAgICBmb3Igc2VsIGluIHNlbHNcbiAgICAgICAgZm9yIG4gaW4gW3NlbC5nZXQoXCJ4U3RhcnRcIikuLnNlbC5nZXQoXCJ4RW5kXCIpXSBieSAxXG4gICAgICAgICAgc2VsZWN0aW9uLnB1c2ggblxuXG4gICAgcmV0dXJuIHNlbGVjdGlvblxuXG4gICMgZHJhd3MgZmVhdHVyZXNcbiAgYXBwZW5kRmVhdHVyZTogKGRhdGEpIC0+XG4gICAgZiA9IGRhdGEuZlxuICAgICMgVE9ETzogdGhpcyBpcyBhIHZlcnkgbmFpdmUgd2F5XG4gICAgYm94V2lkdGggPSBAZy56b29tZXIuZ2V0KFwiY29sdW1uV2lkdGhcIilcbiAgICBib3hIZWlnaHQgPSBAZy56b29tZXIuZ2V0KFwicm93SGVpZ2h0XCIpXG4gICAgd2lkdGggPSAoZi5nZXQoXCJ4RW5kXCIpIC0gZi5nZXQoXCJ4U3RhcnRcIikpICogYm94V2lkdGhcblxuICAgIGJlZm9yZVdpZHRoID0gQGN0eC5saW5lV2lkdGhcbiAgICBAY3R4LmxpbmVXaWR0aCA9IDNcbiAgICBiZWZvcmVTdHlsZSA9IEBjdHguc3Ryb2tlU3R5bGVcbiAgICBAY3R4LnN0cm9rZVN0eWxlID0gZi5nZXQgXCJmaWxsQ29sb3JcIlxuXG4gICAgQGN0eC5zdHJva2VSZWN0IGRhdGEueFplcm8sIGRhdGEueVplcm8sIHdpZHRoLGJveEhlaWdodFxuICAgIEBjdHguc3Ryb2tlU3R5bGUgPSBiZWZvcmVTdHlsZVxuICAgIEBjdHgubGluZVdpZHRoID0gYmVmb3JlV2lkdGhcblxuXG4gICMgbG9vcHMgb3ZlciBhbGwgc2VsZWN0aW9uIGFuZCBjYWxscyB0aGUgcmVuZGVyIG1ldGhvZFxuICBfYXBwZW5kU2VsZWN0aW9uOiAoZGF0YSkgLT5cbiAgICBzZXEgPSBkYXRhLm1vZGVsLmdldChcInNlcVwiKVxuICAgIHNlbGVjdGlvbiA9IEBfZ2V0U2VsZWN0aW9uIGRhdGEubW9kZWxcbiAgICAjIGdldCB0aGUgc3RhdHVzIG9mIHRoZSB1cHBlciBhbmQgbG93ZXIgcm93XG4gICAgW21QcmV2U2VsLG1OZXh0U2VsXSA9IEBfZ2V0UHJldk5leHRTZWxlY3Rpb24gZGF0YS5tb2RlbFxuXG4gICAgYm94V2lkdGggPSBAZy56b29tZXIuZ2V0KFwiY29sdW1uV2lkdGhcIilcbiAgICBib3hIZWlnaHQgPSBAZy56b29tZXIuZ2V0KFwicm93SGVpZ2h0XCIpXG5cbiAgICAjIGF2b2lkIHVubmVjZXNzYXJ5IGxvb3BzXG4gICAgcmV0dXJuIGlmIHNlbGVjdGlvbi5sZW5ndGggaXMgMFxuXG4gICAgaGlkZGVuT2Zmc2V0ID0gMFxuICAgIGZvciBuIGluIFswLi5zZXEubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgaWYgZGF0YS5oaWRkZW4uaW5kZXhPZihuKSA+PSAwXG4gICAgICAgIGhpZGRlbk9mZnNldCsrXG4gICAgICBlbHNlXG4gICAgICAgIGsgPSBuIC0gaGlkZGVuT2Zmc2V0XG4gICAgICAgICMgb25seSBpZiBpdHMgYSBuZXcgc2VsZWN0aW9uXG4gICAgICAgIGlmIHNlbGVjdGlvbi5pbmRleE9mKG4pID49IDAgYW5kIChrIGlzIDAgb3Igc2VsZWN0aW9uLmluZGV4T2YobiAtIDEpIDwgMCApXG4gICAgICAgICAgQF9yZW5kZXJTZWxlY3Rpb24gbjpuLGs6ayxzZWxlY3Rpb246IHNlbGVjdGlvbixtUHJldlNlbDogbVByZXZTZWwsbU5leHRTZWw6bU5leHRTZWwsIHhaZXJvOiBkYXRhLnhaZXJvLCB5WmVybzogZGF0YS55WmVybywgbW9kZWw6IGRhdGEubW9kZWxcblxuICAjIGRyYXdzIGEgc2luZ2xlIHVzZXIgc2VsZWN0aW9uXG4gIF9yZW5kZXJTZWxlY3Rpb246IChkYXRhKSAtPlxuXG4gICAgeFplcm8gPSBkYXRhLnhaZXJvXG4gICAgeVplcm8gPSBkYXRhLnlaZXJvXG4gICAgbiA9IGRhdGEublxuICAgIGsgPSBkYXRhLmtcbiAgICBzZWxlY3Rpb24gPSBkYXRhLnNlbGVjdGlvblxuICAgICMgYW5kIGNoZWNrcyB0aGUgcHJldiBhbmQgbmV4dCByb3cgZm9yIHNlbGVjdGlvbiAgLT4gbm8gYm9yZGVycyBpbiBhIHNlbGVjdGlvblxuICAgIG1QcmV2U2VsPSBkYXRhLm1QcmV2U2VsXG4gICAgbU5leHRTZWwgPSBkYXRhLm1OZXh0U2VsXG5cbiAgICAjIGdldCB0aGUgbGVuZ3RoIG9mIHRoaXMgc2VsZWN0aW9uXG4gICAgc2VsZWN0aW9uTGVuZ3RoID0gMFxuICAgIGZvciBpIGluIFtuLi4gZGF0YS5tb2RlbC5nZXQoXCJzZXFcIikubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgaWYgc2VsZWN0aW9uLmluZGV4T2YoaSkgPj0gMFxuICAgICAgICBzZWxlY3Rpb25MZW5ndGgrK1xuICAgICAgZWxzZVxuICAgICAgICBicmVha1xuXG4gICAgIyBUT0RPOiB1Z2x5IVxuICAgIGJveFdpZHRoID0gQGcuem9vbWVyLmdldChcImNvbHVtbldpZHRoXCIpXG4gICAgYm94SGVpZ2h0ID0gQGcuem9vbWVyLmdldChcInJvd0hlaWdodFwiKVxuICAgIHRvdGFsV2lkdGggPSAoYm94V2lkdGggKiBzZWxlY3Rpb25MZW5ndGgpICsgMVxuXG4gICAgaGlkZGVuID0gQGcuY29sdW1ucy5nZXQoJ2hpZGRlbicpXG5cbiAgICBAY3R4LmJlZ2luUGF0aCgpXG4gICAgYmVmb3JlV2lkdGggPSBAY3R4LmxpbmVXaWR0aFxuICAgIEBjdHgubGluZVdpZHRoID0gM1xuICAgIGJlZm9yZVN0eWxlID0gQGN0eC5zdHJva2VTdHlsZVxuICAgIEBjdHguc3Ryb2tlU3R5bGUgPSBcIiNGRjAwMDBcIlxuXG4gICAgeFplcm8gKz0gayAqIGJveFdpZHRoXG5cbiAgICAjIHNwbGl0IHVwIHRoZSBzZWxlY3Rpb24gaW50byBzaW5nbGUgY2VsbHNcbiAgICB4UGFydCA9IDBcbiAgICBmb3IgaSBpbiBbMC4uIHNlbGVjdGlvbkxlbmd0aCAtIDFdXG4gICAgICB4UG9zID0gbiArIGlcbiAgICAgIGlmIGhpZGRlbi5pbmRleE9mKHhQb3MpID49IDBcbiAgICAgICAgY29udGludWVcbiAgICAgICMgdXBwZXIgbGluZVxuICAgICAgdW5sZXNzIG1QcmV2U2VsPyBhbmQgbVByZXZTZWwuaW5kZXhPZih4UG9zKSA+PSAwXG4gICAgICAgIEBjdHgubW92ZVRvIHhaZXJvICsgeFBhcnQsIHlaZXJvXG4gICAgICAgIEBjdHgubGluZVRvIHhQYXJ0ICsgYm94V2lkdGggKyB4WmVybywgeVplcm9cbiAgICAgICMgbG93ZXIgbGluZVxuICAgICAgdW5sZXNzIG1OZXh0U2VsPyBhbmQgbU5leHRTZWwuaW5kZXhPZih4UG9zKSA+PSAwXG4gICAgICAgIEBjdHgubW92ZVRvIHhQYXJ0ICsgeFplcm8sIGJveEhlaWdodCArIHlaZXJvXG4gICAgICAgIEBjdHgubGluZVRvIHhQYXJ0ICsgYm94V2lkdGggKyB4WmVybywgYm94SGVpZ2h0ICsgeVplcm9cblxuICAgICAgeFBhcnQgKz0gYm94V2lkdGhcblxuICAgICMgbGVmdFxuICAgIEBjdHgubW92ZVRvIHhaZXJvLHlaZXJvXG4gICAgQGN0eC5saW5lVG8geFplcm8sIGJveEhlaWdodCArIHlaZXJvXG5cbiAgICAjIHJpZ2h0XG4gICAgQGN0eC5tb3ZlVG8geFplcm8gKyB0b3RhbFdpZHRoLHlaZXJvXG4gICAgQGN0eC5saW5lVG8geFplcm8gKyB0b3RhbFdpZHRoLCBib3hIZWlnaHQgKyB5WmVyb1xuXG4gICAgQGN0eC5zdHJva2UoKVxuICAgIEBjdHguc3Ryb2tlU3R5bGUgPSBiZWZvcmVTdHlsZVxuICAgIEBjdHgubGluZVdpZHRoID0gYmVmb3JlV2lkdGhcblxuICAjIGxvb2tzIGF0IHRoZSBzZWxlY3Rpb24gb2YgdGhlIHByZXYgYW5kIG5leHQgZWxcbiAgIyBUT0RPOiB0aGlzIGlzIHZlcnkgbmFpdmUsIGFzIHRoZXJlIG1pZ2h0IGJlIGdhcHMgYWJvdmUgb3IgYmVsb3dcbiAgX2dldFByZXZOZXh0U2VsZWN0aW9uOiAobW9kZWwpIC0+XG5cbiAgICBtb2RlbFByZXYgPSBtb2RlbC5jb2xsZWN0aW9uLnByZXYgbW9kZWxcbiAgICBtb2RlbE5leHQgPSBtb2RlbC5jb2xsZWN0aW9uLm5leHQgbW9kZWxcbiAgICBtUHJldlNlbCA9IEBfZ2V0U2VsZWN0aW9uIG1vZGVsUHJldiBpZiBtb2RlbFByZXY/XG4gICAgbU5leHRTZWwgPSBAX2dldFNlbGVjdGlvbiBtb2RlbE5leHQgaWYgbW9kZWxOZXh0P1xuICAgIFttUHJldlNlbCxtTmV4dFNlbF1cbiIsInZpZXcgPSByZXF1aXJlKFwiYmFja2JvbmUtdmlld2pcIilcbm1vdXNlID0gcmVxdWlyZSBcIm1vdXNlLXBvc1wiXG5zZWxlY3Rpb24gPSByZXF1aXJlIFwiLi4vZy9zZWxlY3Rpb24vU2VsZWN0aW9uXCJcbmNvbG9yU2VsZWN0b3IgPSByZXF1aXJlKFwiYmlvanMtdXRpbC1jb2xvcnNjaGVtZXNcIikuc2VsZWN0b3Jcbmpib25lID0gcmVxdWlyZSBcImpib25lXCJcbl8gPSByZXF1aXJlIFwidW5kZXJzY29yZVwiXG5cbm1vZHVsZS5leHBvcnRzID0gT3ZlcnZpZXdCb3ggPSB2aWV3LmV4dGVuZFxuXG4gIGNsYXNzTmFtZTogXCJiaW9qc19tc2Ffb3ZlcnZpZXdib3hcIlxuICB0YWdOYW1lOiBcImNhbnZhc1wiXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQGcgPSBkYXRhLmdcbiAgICBAbGlzdGVuVG8gQGcuem9vbWVyLFwiY2hhbmdlOmJveFJlY3RXaWR0aCBjaGFuZ2U6Ym94UmVjdEhlaWdodFwiLCBAcmVuZGVyXG4gICAgQGxpc3RlblRvIEBnLnNlbGNvbCwgXCJhZGQgcmVzZXQgY2hhbmdlXCIsIEByZW5kZXJcbiAgICBAbGlzdGVuVG8gQGcuY29sdW1ucywgXCJjaGFuZ2U6aGlkZGVuXCIsIEByZW5kZXJcbiAgICBAbGlzdGVuVG8gQGcuY29sb3JzY2hlbWUsIFwiY2hhbmdlOnNob3dMb3dlckNhc2VcIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAbW9kZWwsIFwiY2hhbmdlXCIsIF8uZGVib3VuY2UgQHJlbmRlciwgNVxuXG4gICAgIyBjb2xvclxuICAgIEBjb2xvciA9IGNvbG9yU2VsZWN0b3IuZ2V0Q29sb3IgQGcuY29sb3JzY2hlbWUuZ2V0KFwic2NoZW1lXCIpXG4gICAgQGxpc3RlblRvIEBnLmNvbG9yc2NoZW1lLCBcImNoYW5nZTpzY2hlbWVcIiwgLT5cbiAgICAgIEBjb2xvciA9IGNvbG9yU2VsZWN0b3IuZ2V0Q29sb3IgQGcuY29sb3JzY2hlbWUuZ2V0KFwic2NoZW1lXCIpXG4gICAgICBAcmVuZGVyKClcbiAgICBAZHJhZ1N0YXJ0ID0gW11cblxuICBldmVudHM6XG4gICAgY2xpY2s6IFwiX29uY2xpY2tcIlxuICAgIG1vdXNlZG93bjogXCJfb25tb3VzZWRvd25cIlxuXG4gIHJlbmRlcjogLT5cbiAgICBAX2NyZWF0ZUNhbnZhcygpXG4gICAgQGVsLnRleHRDb250ZW50ID0gXCJvdmVydmlld1wiXG5cbiAgICAjIGJhY2tncm91bmQgYmcgZm9yIG5vbi1kcmF3ZWQgYXJlYVxuICAgIEBjdHguZmlsbFN0eWxlID0gXCIjOTk5OTk5XCJcbiAgICBAY3R4LmZpbGxSZWN0IDAsMCxAZWwud2lkdGgsQGVsLmhlaWdodFxuXG4gICAgcmVjdFdpZHRoID0gQGcuem9vbWVyLmdldCBcImJveFJlY3RXaWR0aFwiXG4gICAgcmVjdEhlaWdodCA9IEBnLnpvb21lci5nZXQgXCJib3hSZWN0SGVpZ2h0XCJcbiAgICBoaWRkZW4gPSBAZy5jb2x1bW5zLmdldCBcImhpZGRlblwiXG4gICAgc2hvd0xvd2VyQ2FzZSA9IEBnLmNvbG9yc2NoZW1lLmdldCBcInNob3dMb3dlckNhc2VcIlxuXG4gICAgeSA9IC1yZWN0SGVpZ2h0XG4gICAgZm9yIGkgaW4gWzAuLiBAbW9kZWwubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgc2VxID0gQG1vZGVsLmF0KGkpLmdldCBcInNlcVwiXG4gICAgICB4ID0gMFxuICAgICAgeSA9IHkgKyByZWN0SGVpZ2h0XG5cblxuICAgICAgaWYgQG1vZGVsLmF0KGkpLmdldCBcImhpZGRlblwiXG4gICAgICAgICMgaGlkZGVuIHNlcVxuICAgICAgICBjb25zb2xlLmxvZyBAbW9kZWwuYXQoaSkuZ2V0IFwiaGlkZGVuXCJcbiAgICAgICAgQGN0eC5maWxsU3R5bGUgPSBcImdyZXlcIlxuICAgICAgICBAY3R4LmZpbGxSZWN0IDAseSxzZXEubGVuZ3RoICogcmVjdFdpZHRoLHJlY3RIZWlnaHRcbiAgICAgICAgY29udGludWVcblxuICAgICAgZm9yIGogaW4gWzAuLiBzZXEubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgICBjID0gc2VxW2pdXG4gICAgICAgICMgdG9kbzogb3B0aW9uYWwgdXBwZXJjYXNpbmdcbiAgICAgICAgYyA9IGMudG9VcHBlckNhc2UoKSBpZiBzaG93TG93ZXJDYXNlXG4gICAgICAgIGNvbG9yID0gQGNvbG9yW2NdXG5cbiAgICAgICAgaWYgaGlkZGVuLmluZGV4T2YoaikgPj0gMFxuICAgICAgICAgIGNvbG9yID0gXCJncmV5XCJcblxuICAgICAgICBpZiBjb2xvcj9cbiAgICAgICAgICBAY3R4LmZpbGxTdHlsZSA9IGNvbG9yXG4gICAgICAgICAgQGN0eC5maWxsUmVjdCB4LHkscmVjdFdpZHRoLHJlY3RIZWlnaHRcblxuICAgICAgICB4ID0geCArIHJlY3RXaWR0aFxuXG4gICAgQF9kcmF3U2VsZWN0aW9uKClcblxuICBfZHJhd1NlbGVjdGlvbjogLT5cbiAgICAjIGhpZGUgZHVyaW5nIHNlbGVjdGlvblxuICAgIHJldHVybiBpZiBAZHJhZ1N0YXJ0Lmxlbmd0aCA+IDAgYW5kIG5vdCBAcHJvbG9uZ1NlbGVjdGlvblxuXG4gICAgcmVjdFdpZHRoID0gQGcuem9vbWVyLmdldCBcImJveFJlY3RXaWR0aFwiXG4gICAgcmVjdEhlaWdodCA9IEBnLnpvb21lci5nZXQgXCJib3hSZWN0SGVpZ2h0XCJcbiAgICBtYXhIZWlnaHQgPSByZWN0SGVpZ2h0ICogQG1vZGVsLmxlbmd0aFxuICAgIEBjdHguZmlsbFN0eWxlID0gXCIjZmZmZjAwXCJcbiAgICBAY3R4Lmdsb2JhbEFscGhhID0gMC45XG4gICAgZm9yIGkgaW4gWzAuLiBAZy5zZWxjb2wubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgc2VsID0gQGcuc2VsY29sLmF0KGkpXG4gICAgICBpZiBzZWwuZ2V0KCd0eXBlJykgaXMgJ2NvbHVtbidcbiAgICAgICAgQGN0eC5maWxsUmVjdCByZWN0V2lkdGggKiBzZWwuZ2V0KCd4U3RhcnQnKSwwLHJlY3RXaWR0aCAqXG4gICAgICAgIChzZWwuZ2V0KCd4RW5kJykgLSBzZWwuZ2V0KCd4U3RhcnQnKSArIDEpLG1heEhlaWdodFxuICAgICAgZWxzZSBpZiBzZWwuZ2V0KCd0eXBlJykgaXMgJ3JvdydcbiAgICAgICAgc2VxID0gKEBtb2RlbC5maWx0ZXIgKGVsKSAtPiBlbC5nZXQoJ2lkJykgaXMgc2VsLmdldCgnc2VxSWQnKSlbMF1cbiAgICAgICAgcG9zID0gQG1vZGVsLmluZGV4T2Yoc2VxKVxuICAgICAgICBAY3R4LmZpbGxSZWN0IDAscmVjdEhlaWdodCAqIHBvcywgcmVjdFdpZHRoICogc2VxLmdldCgnc2VxJykubGVuZ3RoLCByZWN0SGVpZ2h0XG4gICAgICBlbHNlIGlmIHNlbC5nZXQoJ3R5cGUnKSBpcyAncG9zJ1xuICAgICAgICBzZXEgPSAoQG1vZGVsLmZpbHRlciAoZWwpIC0+IGVsLmdldCgnaWQnKSBpcyBzZWwuZ2V0KCdzZXFJZCcpKVswXVxuICAgICAgICBwb3MgPSBAbW9kZWwuaW5kZXhPZihzZXEpXG4gICAgICAgIEBjdHguZmlsbFJlY3QgcmVjdFdpZHRoICogc2VsLmdldCgneFN0YXJ0JykscmVjdEhlaWdodCAqIHBvcywgcmVjdFdpZHRoICogKHNlbC5nZXQoJ3hFbmQnKSAtIHNlbC5nZXQoJ3hTdGFydCcpICsgMSksIHJlY3RIZWlnaHRcblxuICAgIEBjdHguZ2xvYmFsQWxwaGEgPSAxXG5cbiAgX29uY2xpY2s6IChldnQpIC0+XG4gICAgQGcudHJpZ2dlciBcIm1ldGE6Y2xpY2tcIiwge3NlcUlkOiBAbW9kZWwuZ2V0IFwiaWRcIiwgZXZ0OmV2dH1cblxuICBfb25tb3VzZW1vdmU6IChlKSAtPlxuICAgICMgZHVwbGljYXRlIGV2ZW50c1xuICAgIHJldHVybiBpZiBAZHJhZ1N0YXJ0Lmxlbmd0aCBpcyAwXG5cbiAgICBAcmVuZGVyKClcbiAgICBAY3R4LmZpbGxTdHlsZSA9IFwiI2ZmZmYwMFwiXG4gICAgQGN0eC5nbG9iYWxBbHBoYSA9IDAuOVxuXG4gICAgcmVjdCA9IEBfY2FsY1NlbGVjdGlvbiggbW91c2UuYWJzIGUgKVxuICAgIEBjdHguZmlsbFJlY3QgcmVjdFswXVswXSxyZWN0WzFdWzBdLHJlY3RbMF1bMV0gLSByZWN0WzBdWzBdLCByZWN0WzFdWzFdIC0gcmVjdFsxXVswXVxuXG4gICAgIyBhYm9ydCBzZWxlY3Rpb24gZXZlbnRzIG9mIHRoZSBicm93c2VyXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICMgc3RhcnQgdGhlIHNlbGVjdGlvbiBtb2RlXG4gIF9vbm1vdXNlZG93bjogKGUpIC0+XG4gICAgQGRyYWdTdGFydCA9IG1vdXNlLmFicyBlXG4gICAgQGRyYWdTdGFydFJlbCA9IG1vdXNlLnJlbCBlXG5cbiAgICBpZiBlLmN0cmxLZXkgb3IgZS5tZXRhS2V5XG4gICAgICBAcHJvbG9uZ1NlbGVjdGlvbiA9IHRydWVcbiAgICBlbHNlXG4gICAgICBAcHJvbG9uZ1NlbGVjdGlvbiA9IGZhbHNlXG4gICAgIyBlbmFibGUgZ2xvYmFsIGxpc3RlbmVyc1xuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9uICdtb3VzZW1vdmUub3Zlcm1vdmUnLCAoZSkgPT4gQF9vbm1vdXNlbW92ZShlKVxuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9uICdtb3VzZXVwLm92ZXJ1cCcsIChlKSA9PiBAX29ubW91c2V1cChlKVxuICAgIHJldHVybiBAZHJhZ1N0YXJ0XG5cbiAgIyBjYWxjdWxhdGVzIHRoZSBjdXJyZW50IHNlbGVjdGlvblxuICBfY2FsY1NlbGVjdGlvbjogKGRyYWdNb3ZlKSAtPlxuICAgICMgcmVsYXRpdmUgdG8gZmlyc3QgY2xpY2tcbiAgICBkcmFnUmVsID0gW2RyYWdNb3ZlWzBdIC0gQGRyYWdTdGFydFswXSwgZHJhZ01vdmVbMV0gLSBAZHJhZ1N0YXJ0WzFdXVxuXG4gICAgIyByZWxhdGl2ZSB0byB0YXJnZXRcbiAgICBmb3IgaSBpbiBbMC4uMV0gYnkgMVxuICAgICAgZHJhZ1JlbFtpXSA9IEBkcmFnU3RhcnRSZWxbaV0gKyBkcmFnUmVsW2ldXG5cbiAgICAjIDA6eCwgMTogeVxuICAgIHJlY3QgPSBbW0BkcmFnU3RhcnRSZWxbMF0sIGRyYWdSZWxbMF1dLCBbQGRyYWdTdGFydFJlbFsxXSwgZHJhZ1JlbFsxXV1dXG5cbiAgICAjIHN3YXAgdGhlIGNvb3JkaW5hdGVzIGlmIG5lZWRlZFxuICAgIGZvciBpIGluIFswLi4xXSBieSAxXG4gICAgICBpZiByZWN0W2ldWzFdIDwgcmVjdFtpXVswXVxuICAgICAgICByZWN0W2ldID0gW3JlY3RbaV1bMV0sIHJlY3RbaV1bMF1dXG5cbiAgICAgICMgbG93ZXIgbGltaXRcbiAgICAgIHJlY3RbaV1bMF0gPSBNYXRoLm1heCByZWN0W2ldWzBdLCAwXG5cbiAgICByZXR1cm4gcmVjdFxuXG4gIF9lbmRTZWxlY3Rpb246IChkcmFnRW5kKSAtPlxuICAgICMgcmVtb3ZlIGxpc3RlbmVyc1xuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9mZignLm92ZXJtb3ZlJylcbiAgICBqYm9uZShkb2N1bWVudC5ib2R5KS5vZmYoJy5vdmVydXAnKVxuXG4gICAgIyBkdXBsaWNhdGUgZXZlbnRzXG4gICAgcmV0dXJuIGlmIEBkcmFnU3RhcnQubGVuZ3RoIGlzIDBcblxuICAgIHJlY3QgPSBAX2NhbGNTZWxlY3Rpb24gZHJhZ0VuZFxuXG4gICAgIyB4XG4gICAgZm9yIGkgaW4gWzAuLjFdXG4gICAgICByZWN0WzBdW2ldID0gTWF0aC5mbG9vciggcmVjdFswXVtpXSAvIEBnLnpvb21lci5nZXQoXCJib3hSZWN0V2lkdGhcIikpXG5cbiAgICAjIHlcbiAgICBmb3IgaSBpbiBbMC4uMV1cbiAgICAgIHJlY3RbMV1baV0gPSBNYXRoLmZsb29yKCByZWN0WzFdW2ldIC8gQGcuem9vbWVyLmdldChcImJveFJlY3RIZWlnaHRcIikgKVxuXG4gICAgIyB1cHBlciBsaW1pdFxuICAgIHJlY3RbMF1bMV0gPSBNYXRoLm1pbihAbW9kZWwuZ2V0TWF4TGVuZ3RoKCkgLSAxLCByZWN0WzBdWzFdKVxuICAgIHJlY3RbMV1bMV0gPSBNYXRoLm1pbihAbW9kZWwubGVuZ3RoIC0gMSwgcmVjdFsxXVsxXSlcblxuICAgICMgc2VsZWN0XG4gICAgc2VsaXMgPSBbXVxuICAgIGZvciBqIGluIFtyZWN0WzFdWzBdLi5yZWN0WzFdWzFdXSBieSAxXG4gICAgICBhcmdzID0gc2VxSWQ6IEBtb2RlbC5hdChqKS5nZXQoJ2lkJyksIHhTdGFydDogcmVjdFswXVswXSwgeEVuZDogcmVjdFswXVsxXVxuICAgICAgc2VsaXMucHVzaCBuZXcgc2VsZWN0aW9uLnBvc3NlbCBhcmdzXG5cbiAgICAjIHJlc2V0XG4gICAgQGRyYWdTdGFydCA9IFtdXG4gICAgIyBsb29rIGZvciBjdHJsIGtleVxuICAgIGlmIEBwcm9sb25nU2VsZWN0aW9uXG4gICAgICBAZy5zZWxjb2wuYWRkIHNlbGlzXG4gICAgZWxzZVxuICAgICAgQGcuc2VsY29sLnJlc2V0IHNlbGlzXG5cbiAgICAjIHNhZmV0eSBjaGVjayArIHVwZGF0ZSBvZmZzZXRcbiAgICBAZy56b29tZXIuc2V0TGVmdE9mZnNldCByZWN0WzBdWzBdXG4gICAgQGcuem9vbWVyLnNldFRvcE9mZnNldCByZWN0WzFdWzBdXG5cbiAgIyBlbmRzIHRoZSBzZWxlY3Rpb24gbW9kZVxuICBfb25tb3VzZXVwOiAoZSkgLT5cbiAgICBAX2VuZFNlbGVjdGlvbiBtb3VzZS5hYnMgZVxuXG4gIF9vbm1vdXNlb3V0OiAoZSkgLT5cbiAgICBAX2VuZFNlbGVjdGlvbiBtb3VzZS5hYnMgZVxuXG4gIyBpbml0IHRoZSBjYW52YXNcbiAgX2NyZWF0ZUNhbnZhczogLT5cbiAgICByZWN0V2lkdGggPSBAZy56b29tZXIuZ2V0IFwiYm94UmVjdFdpZHRoXCJcbiAgICByZWN0SGVpZ2h0ID0gQGcuem9vbWVyLmdldCBcImJveFJlY3RIZWlnaHRcIlxuXG4gICAgQGVsLmhlaWdodCA9IEBtb2RlbC5sZW5ndGggKiByZWN0SGVpZ2h0XG4gICAgQGVsLndpZHRoID0gQG1vZGVsLmdldE1heExlbmd0aCgpICogcmVjdFdpZHRoXG4gICAgQGN0eCA9IEBlbC5nZXRDb250ZXh0IFwiMmRcIlxuICAgIEBlbC5zdHlsZS5vdmVyZmxvdyA9IFwic2Nyb2xsXCJcbiAgICBAZWwuc3R5bGUuY3Vyc29yID0gXCJjcm9zc2hhaXJcIlxuIiwiYm9uZVZpZXcgPSByZXF1aXJlKFwiYmFja2JvbmUtY2hpbGRzXCIpXG5BbGlnbm1lbnRCb2R5ID0gcmVxdWlyZSBcIi4vQWxpZ25tZW50Qm9keVwiXG5IZWFkZXJCbG9jayA9IHJlcXVpcmUgXCIuL2hlYWRlci9IZWFkZXJCbG9ja1wiXG5PdmVydmlld0JveCA9IHJlcXVpcmUgXCIuL092ZXJ2aWV3Qm94XCJcbmlkZW50aXR5Q2FsYyA9IHJlcXVpcmUgXCIuLi9hbGdvL2lkZW50aXR5Q2FsY1wiXG5fID0gcmVxdWlyZSAndW5kZXJzY29yZSdcblxuIyBhIG5lYXQgY29sbGVjdGlvbiB2aWV3XG5tb2R1bGUuZXhwb3J0cyA9IGJvbmVWaWV3LmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG5cbiAgICBAZHJhdygpXG4gICAgQGxpc3RlblRvIEBtb2RlbCxcInJlc2V0XCIsIC0+XG4gICAgICBAaXNOb3REaXJ0eSA9IGZhbHNlXG4gICAgICBAcmVyZW5kZXIoKVxuXG4gICAgIyBkZWJvdW5jZSBhIGJ1bGsgb3BlcmF0aW9uXG4gICAgQGxpc3RlblRvIEBtb2RlbCxcImNoYW5nZTpoaWRkZW5cIiwgXy5kZWJvdW5jZSBAcmVyZW5kZXIsIDEwXG5cbiAgICBAbGlzdGVuVG8gQG1vZGVsLFwic29ydFwiLCBAcmVyZW5kZXJcbiAgICBAbGlzdGVuVG8gQG1vZGVsLFwiYWRkXCIsIC0+XG4gICAgICBjb25zb2xlLmxvZyBcInNlcSBhZGRcIlxuXG4gICAgQGxpc3RlblRvIEBnLnZpcyxcImNoYW5nZTpzZXF1ZW5jZXNcIiwgQHJlcmVuZGVyXG4gICAgQGxpc3RlblRvIEBnLnZpcyxcImNoYW5nZTpvdmVydmlld2JveFwiLCBAcmVyZW5kZXJcbiAgICBAbGlzdGVuVG8gQGcudmlzb3JkZXIsXCJjaGFuZ2VcIiwgQHJlcmVuZGVyXG5cbiAgZHJhdzogLT5cbiAgICBAcmVtb3ZlVmlld3MoKVxuXG4gICAgdW5sZXNzIEBpc05vdERpcnR5XG4gICAgICAjIG9ubHkgZXhlY3V0ZWQgd2hlbiBuZXcgc2VxdWVuY2VzIGFyZSBhZGRlZCBvciBvbiBzdGFydFxuICAgICAgY29uc2Vuc3VzID0gQGcuY29uc2Vuc3VzLmdldENvbnNlbnN1cyBAbW9kZWxcbiAgICAgIGlkZW50aXR5Q2FsYyBAbW9kZWwsIGNvbnNlbnN1c1xuICAgICAgQGlzTm90RGlydHkgPSB0cnVlXG5cbiAgICBpZiBAZy52aXMuZ2V0IFwib3ZlcnZpZXdib3hcIlxuICAgICAgb3ZlcnZpZXdib3ggPSBuZXcgT3ZlcnZpZXdCb3gge21vZGVsOiBAbW9kZWwsIGc6IEBnfVxuICAgICAgb3ZlcnZpZXdib3gub3JkZXJpbmcgPSBAZy52aXNvcmRlci5nZXQgJ292ZXJ2aWV3Qm94J1xuICAgICAgQGFkZFZpZXcgXCJvdmVydmlld2JveFwiLG92ZXJ2aWV3Ym94XG5cbiAgICBpZiB0cnVlXG4gICAgICBoZWFkZXJibG9jayA9IG5ldyBIZWFkZXJCbG9jayB7bW9kZWw6IEBtb2RlbCwgZzogQGd9XG4gICAgICBoZWFkZXJibG9jay5vcmRlcmluZyA9IEBnLnZpc29yZGVyLmdldCAnaGVhZGVyQm94J1xuICAgICAgQGFkZFZpZXcgXCJoZWFkZXJibG9ja1wiLGhlYWRlcmJsb2NrXG5cbiAgICBib2R5ID0gbmV3IEFsaWdubWVudEJvZHkge21vZGVsOiBAbW9kZWwsIGc6IEBnfVxuICAgIGJvZHkub3JkZXJpbmcgPSBAZy52aXNvcmRlci5nZXQgJ2FsaWdubWVudEJvZHknXG4gICAgQGFkZFZpZXcgXCJib2R5XCIsYm9keVxuXG4gIHJlbmRlcjogLT5cbiAgICBAcmVuZGVyU3Vidmlld3MoKVxuICAgIEBlbC5jbGFzc05hbWUgPSBcImJpb2pzX21zYV9zdGFnZVwiXG4gICAgQFxuXG4gIHJlcmVuZGVyOiAtPlxuICAgIEBkcmF3KClcbiAgICBAcmVuZGVyKClcbiIsInZpZXcgPSByZXF1aXJlKFwiYmFja2JvbmUtdmlld2pcIilcbmRvbSA9IHJlcXVpcmUoXCJkb20taGVscGVyXCIpXG5zdmcgPSByZXF1aXJlKFwiLi4vLi4vdXRpbHMvc3ZnXCIpXG5cbkNvbnNlcnZhdGlvblZpZXcgPSB2aWV3LmV4dGVuZFxuXG4gIGNsYXNzTmFtZTogXCJiaW9qc19tc2FfY29uc2VydlwiXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQGcgPSBkYXRhLmdcbiAgICBAbGlzdGVuVG8gQGcuem9vbWVyLFwiY2hhbmdlOnN0ZXBTaXplIGNoYW5nZTpsYWJlbFdpZHRoIGNoYW5nZTpjb2x1bW5XaWR0aFwiLCBAcmVuZGVyXG4gICAgQGxpc3RlblRvIEBnLnZpcyxcImNoYW5nZTpsYWJlbHMgY2hhbmdlOm1ldGFjZWxsXCIsIEByZW5kZXJcbiAgICBAbGlzdGVuVG8gQGcuY29sdW1ucywgXCJjaGFuZ2U6c2NhbGluZ1wiLCBAcmVuZGVyXG4gICAgQGxpc3RlblRvIEBtb2RlbCwgXCJyZXNldFwiLEByZW5kZXJcbiAgICBAbWFuYWdlRXZlbnRzKClcblxuICByZW5kZXI6IC0+XG4gICAgQGcuY29sdW1ucy5jYWxjQ29uc2VydmF0aW9uIEBtb2RlbFxuXG4gICAgZG9tLnJlbW92ZUFsbENoaWxkcyBAZWxcblxuICAgIG5NYXggPSBAbW9kZWwuZ2V0TWF4TGVuZ3RoKClcbiAgICBjZWxsV2lkdGggPSBAZy56b29tZXIuZ2V0IFwiY29sdW1uV2lkdGhcIlxuICAgIG1heEhlaWdodCA9IDIwXG4gICAgd2lkdGggPSBjZWxsV2lkdGggKiAobk1heCAtIEBnLmNvbHVtbnMuZ2V0KCdoaWRkZW4nKS5sZW5ndGgpXG4gICAgY29uc29sZS5sb2cgQGcuY29sdW1ucy5nZXQoJ2hpZGRlbicpXG5cbiAgICBzID0gc3ZnLmJhc2UgaGVpZ2h0OiBtYXhIZWlnaHQsIHdpZHRoOiB3aWR0aFxuICAgIHMuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcbiAgICBzLnN0eWxlLmN1cnNvciA9IFwicG9pbnRlclwiXG5cbiAgICBzdGVwU2l6ZSA9IEBnLnpvb21lci5nZXQgXCJzdGVwU2l6ZVwiXG4gICAgaGlkZGVuID0gQGcuY29sdW1ucy5nZXQgXCJoaWRkZW5cIlxuICAgIHggPSAwXG4gICAgbiA9IDBcbiAgICB3aGlsZSBuIDwgbk1heFxuICAgICAgaWYgaGlkZGVuLmluZGV4T2YobikgPj0gMFxuICAgICAgICBuICs9IHN0ZXBTaXplXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB3aWR0aCA9IGNlbGxXaWR0aCAqIHN0ZXBTaXplXG4gICAgICBhdmdIZWlnaHQgPSAwXG4gICAgICBmb3IgaSBpbiBbMCAuLiBzdGVwU2l6ZSAtIDFdXG4gICAgICAgIGF2Z0hlaWdodCArPSBAZy5jb2x1bW5zLmdldChcImNvbnNlcnZcIilbbl1cbiAgICAgIGhlaWdodCA9IG1heEhlaWdodCAqICAoYXZnSGVpZ2h0IC8gc3RlcFNpemUpXG5cbiAgICAgIHJlY3QgPSAgc3ZnLnJlY3QgeDp4LHk6IG1heEhlaWdodCAtIGhlaWdodCx3aWR0aDp3aWR0aCAtIGNlbGxXaWR0aCAvIDQsaGVpZ2h0OmhlaWdodCxzdHlsZTpcbiAgICAgICAgXCJzdHJva2U6cmVkO3N0cm9rZS13aWR0aDoxO1wiXG4gICAgICByZWN0LnJvd1BvcyA9IG5cbiAgICAgIHMuYXBwZW5kQ2hpbGQgcmVjdFxuICAgICAgeCArPSB3aWR0aFxuICAgICAgbiArPSBzdGVwU2l6ZVxuXG4gICAgQGVsLmFwcGVuZENoaWxkIHNcbiAgICBAXG5cbiAgI1RPRE86IG1ha2UgbW9yZSBnZW5lcmFsIHdpdGggSGVhZGVyVmlld1xuICBfb25jbGljazogKGV2dCkgLT5cbiAgICByb3dQb3MgPSBldnQudGFyZ2V0LnJvd1Bvc1xuICAgIHN0ZXBTaXplID0gQGcuem9vbWVyLmdldChcInN0ZXBTaXplXCIpXG4gICAgIyBzaW11bGF0ZSBoaWRkZW4gY29sdW1uc1xuICAgIGZvciBpIGluIFswLi5zdGVwU2l6ZSAtIDFdIGJ5IDFcbiAgICAgIEBnLnRyaWdnZXIgXCJiYXI6Y2xpY2tcIiwge3Jvd1Bvczogcm93UG9zICsgaSwgZXZ0OmV2dH1cblxuICBtYW5hZ2VFdmVudHM6IC0+XG4gICAgZXZlbnRzID0ge31cbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUNsaWNrc1wiXG4gICAgICBldmVudHMuY2xpY2sgPSBcIl9vbmNsaWNrXCJcbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUhvdmVyXCJcbiAgICAgIGV2ZW50cy5tb3VzZWluID0gXCJfb25tb3VzZWluXCJcbiAgICAgIGV2ZW50cy5tb3VzZW91dCA9IFwiX29ubW91c2VvdXRcIlxuICAgIEBkZWxlZ2F0ZUV2ZW50cyBldmVudHNcbiAgICBAbGlzdGVuVG8gQGcuY29uZmlnLCBcImNoYW5nZTpyZWdpc3Rlck1vdXNlSG92ZXJcIiwgQG1hbmFnZUV2ZW50c1xuICAgIEBsaXN0ZW5UbyBAZy5jb25maWcsIFwiY2hhbmdlOnJlZ2lzdGVyTW91c2VDbGlja1wiLCBAbWFuYWdlRXZlbnRzXG5cbiAgX29ubW91c2VpbjogKGV2dCkgLT5cbiAgICByb3dQb3MgPSBAZy56b29tZXIuZ2V0IFwic3RlcFNpemVcIiAqIGV2dC5yb3dQb3NcbiAgICBAZy50cmlnZ2VyIFwiYmFyOm1vdXNlaW5cIiwge3Jvd1Bvczogcm93UG9zLCBldnQ6ZXZ0fVxuXG4gIF9vbm1vdXNlb3V0OiAoZXZ0KSAtPlxuICAgIHJvd1BvcyA9IEBnLnpvb21lci5nZXQgXCJzdGVwU2l6ZVwiICogZXZ0LnJvd1Bvc1xuICAgIEBnLnRyaWdnZXIgXCJiYXI6bW91c2VvdXRcIiwge3Jvd1Bvczogcm93UG9zLCBldnQ6ZXZ0fVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbnNlcnZhdGlvblZpZXdcbiIsIk1hcmtlclZpZXcgPSByZXF1aXJlIFwiLi9NYXJrZXJWaWV3XCJcbkNvbnNlcnZhdGlvblZpZXcgPSByZXF1aXJlIFwiLi9Db25zZXJ2YXRpb25WaWV3XCJcbmlkZW50aXR5Q2FsYyA9IHJlcXVpcmUgXCIuLi8uLi9hbGdvL2lkZW50aXR5Q2FsY1wiXG5ib25lVmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS1jaGlsZHNcIilcbl8gPSByZXF1aXJlICd1bmRlcnNjb3JlJ1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJvbmVWaWV3LmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQGJsb2NrRXZlbnRzID0gZmFsc2VcblxuICAgIEBsaXN0ZW5UbyBAZy52aXMsXCJjaGFuZ2U6bWFya2VycyBjaGFuZ2U6Y29uc2VydlwiLCAtPlxuICAgICAgQGRyYXcoKVxuICAgICAgQHJlbmRlcigpXG4gICAgQGxpc3RlblRvIEBnLnZpcyxcImNoYW5nZVwiLCBAX3NldFNwYWNlclxuICAgIEBsaXN0ZW5UbyBAZy56b29tZXIsXCJjaGFuZ2U6YWxpZ25tZW50V2lkdGhcIiwgLT5cbiAgICAgIEBfYWRqdXN0V2lkdGgoKVxuICAgIEBsaXN0ZW5UbyBAZy56b29tZXIsIFwiY2hhbmdlOl9hbGlnbm1lbnRTY3JvbGxMZWZ0XCIsIEBfYWRqdXN0U2Nyb2xsaW5nTGVmdFxuXG4gICAgIyBUT0RPOiBkdXBsaWNhdGUgcmVuZGVyaW5nXG4gICAgQGxpc3RlblRvIEBnLmNvbHVtbnMsIFwiY2hhbmdlOmhpZGRlblwiLCAtPlxuICAgICAgQGRyYXcoKVxuICAgICAgQHJlbmRlcigpXG5cbiAgICBAZHJhdygpXG4gICAgQF9vbnNjcm9sbCA9IEBfc2VuZFNjcm9sbEV2ZW50XG5cbiAgICBAZy52aXMub25jZSAnY2hhbmdlOmxvYWRlZCcsIEBfYWRqdXN0U2Nyb2xsaW5nTGVmdCwgQFxuXG4gIGV2ZW50czpcbiAgICBcInNjcm9sbFwiOiBcIl9vbnNjcm9sbFwiXG5cbiAgZHJhdzogLT5cbiAgICBAcmVtb3ZlVmlld3MoKVxuXG4gICAgdW5sZXNzIEBpc05vdERpcnR5XG4gICAgICAjIG9ubHkgZXhlY3V0ZWQgd2hlbiBuZXcgc2VxdWVuY2VzIGFyZSBhZGRlZCBvciBvbiBzdGFydFxuICAgICAgY29uc2Vuc3VzID0gQGcuY29uc2Vuc3VzLmdldENvbnNlbnN1cyBAbW9kZWxcbiAgICAgIGlkZW50aXR5Q2FsYyBAbW9kZWwsIGNvbnNlbnN1c1xuICAgICAgQGlzTm90RGlydHkgPSB0cnVlXG5cbiAgICBpZiBAZy52aXMuZ2V0IFwiY29uc2VydlwiXG4gICAgICBjb25zZXJ2ID0gbmV3IENvbnNlcnZhdGlvblZpZXcge21vZGVsOiBAbW9kZWwsIGc6IEBnfVxuICAgICAgY29uc2Vydi5vcmRlcmluZyA9IC0yMFxuICAgICAgQGFkZFZpZXcgXCJjb25zZXJ2XCIsY29uc2VydlxuXG4gICAgaWYgQGcudmlzLmdldCBcIm1hcmtlcnNcIlxuICAgICAgbWFya2VyID0gbmV3IE1hcmtlclZpZXcge21vZGVsOiBAbW9kZWwsIGc6IEBnfVxuICAgICAgbWFya2VyLm9yZGVyaW5nID0gLTEwXG4gICAgICBAYWRkVmlldyBcIm1hcmtlclwiLG1hcmtlclxuXG4gIHJlbmRlcjogLT5cbiAgICBAcmVuZGVyU3Vidmlld3MoKVxuXG4gICAgQF9zZXRTcGFjZXIoKVxuXG4gICAgQGVsLmNsYXNzTmFtZSA9IFwiYmlvanNfbXNhX2hlYWRlclwiXG4gICAgQGVsLnN0eWxlLm92ZXJmbG93WCA9IFwiYXV0b1wiXG4gICAgQF9hZGp1c3RXaWR0aCgpXG4gICAgQF9hZGp1c3RTY3JvbGxpbmdMZWZ0KClcbiAgICBAXG5cbiAgIyBzY3JvbGxMZWZ0IHRyaWdnZXJzIGEgcmVmbG93IG9mIHRoZSB3aG9sZSBhcmVhIChldmVuIG9ubHkgZ2V0KVxuICBfc2VuZFNjcm9sbEV2ZW50OiAtPlxuICAgIHVubGVzcyBAYmxvY2tFdmVudHNcbiAgICAgIEBnLnpvb21lci5zZXQgXCJfYWxpZ25tZW50U2Nyb2xsTGVmdFwiLCBAZWwuc2Nyb2xsTGVmdCwge29yaWdpbjogXCJoZWFkZXJcIn1cbiAgICBAYmxvY2tFdmVudHMgPSBmYWxzZVxuXG4gIF9hZGp1c3RTY3JvbGxpbmdMZWZ0OiAobW9kZWwsdmFsdWUsb3B0aW9ucykgLT5cbiAgICBpZiAobm90IG9wdGlvbnM/Lm9yaWdpbj8pIG9yIG9wdGlvbnMub3JpZ2luIGlzbnQgXCJoZWFkZXJcIlxuICAgICAgc2Nyb2xsTGVmdCA9IEBnLnpvb21lci5nZXQgXCJfYWxpZ25tZW50U2Nyb2xsTGVmdFwiXG4gICAgICBAYmxvY2tFdmVudHMgPSB0cnVlXG4gICAgICBAZWwuc2Nyb2xsTGVmdCA9IHNjcm9sbExlZnRcblxuICBfc2V0U3BhY2VyOiAtPlxuICAgICMgc3BhY2VyIC8gcGFkZGluZyBlbGVtZW50XG4gICAgQGVsLnN0eWxlLm1hcmdpbkxlZnQgPSBAX2dldExhYmVsV2lkdGgoKSArIFwicHhcIlxuXG4gIF9nZXRMYWJlbFdpZHRoOiAtPlxuICAgIHBhZGRpbmdMZWZ0ID0gMFxuICAgIHBhZGRpbmdMZWZ0ICs9IEBnLnpvb21lci5nZXQgXCJsYWJlbFdpZHRoXCIgaWYgQGcudmlzLmdldCBcImxhYmVsc1wiXG4gICAgcGFkZGluZ0xlZnQgKz0gQGcuem9vbWVyLmdldCBcIm1ldGFXaWR0aFwiIGlmIEBnLnZpcy5nZXQgXCJtZXRhY2VsbFwiXG4gICAgcmV0dXJuIHBhZGRpbmdMZWZ0XG5cbiAgX2FkanVzdFdpZHRoOiAtPlxuICAgIEBlbC5zdHlsZS53aWR0aCA9IEBnLnpvb21lci5nZXQoXCJhbGlnbm1lbnRXaWR0aFwiKSArIFwicHhcIlxuIiwidmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS12aWV3alwiKVxuZG9tID0gcmVxdWlyZShcImRvbS1oZWxwZXJcIilcbnN2ZyA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy9zdmdcIilcbmpib25lID0gcmVxdWlyZSBcImpib25lXCJcblxuSGVhZGVyVmlldyA9IHZpZXcuZXh0ZW5kXG5cbiAgY2xhc3NOYW1lOiBcImJpb2pzX21zYV9tYXJrZXJcIlxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQGxpc3RlblRvIEBnLnpvb21lcixcImNoYW5nZTpzdGVwU2l6ZSBjaGFuZ2U6bGFiZWxXaWR0aCBjaGFuZ2U6Y29sdW1uV2lkdGggY2hhbmdlOm1hcmtlclN0ZXBTaXplIGNoYW5nZTptYXJrZXJGb250c2l6ZVwiLCBAcmVuZGVyXG4gICAgQGxpc3RlblRvIEBnLnZpcyxcImNoYW5nZTpsYWJlbHMgY2hhbmdlOm1ldGFjZWxsXCIsIEByZW5kZXJcbiAgICBAbWFuYWdlRXZlbnRzKClcblxuICByZW5kZXI6IC0+XG4gICAgZG9tLnJlbW92ZUFsbENoaWxkcyBAZWxcblxuICAgIEBlbC5zdHlsZS5mb250U2l6ZSA9IEBnLnpvb21lci5nZXQgXCJtYXJrZXJGb250c2l6ZVwiXG5cbiAgICBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwic3BhblwiXG4gICAgbiA9IDBcbiAgICBjZWxsV2lkdGggPSBAZy56b29tZXIuZ2V0IFwiY29sdW1uV2lkdGhcIlxuXG4gICAgbk1heCA9IEBtb2RlbC5nZXRNYXhMZW5ndGgoKVxuICAgIHN0ZXBTaXplID0gQGcuem9vbWVyLmdldChcInN0ZXBTaXplXCIpXG4gICAgaGlkZGVuID0gQGcuY29sdW1ucy5nZXQgXCJoaWRkZW5cIlxuXG4gICAgd2hpbGUgbiA8IG5NYXhcbiAgICAgIGlmIGhpZGRlbi5pbmRleE9mKG4pID49IDBcbiAgICAgICAgQG1hcmtlckhpZGRlbihzcGFuLG4sIHN0ZXBTaXplKVxuICAgICAgICBuICs9IHN0ZXBTaXplXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICBzcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcInNwYW5cIlxuICAgICAgc3Bhbi5zdHlsZS53aWR0aCA9IChjZWxsV2lkdGggKiBzdGVwU2l6ZSkgKyBcInB4XCJcbiAgICAgIHNwYW4uc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcbiAgICAgICMgVE9ETzogdGhpcyBkb2Vzbid0IHdvcmsgZm9yIGEgbGFyZ2VyIHN0ZXBTaXplXG4gICAgICBpZiAobiArIDEpICUgQGcuem9vbWVyLmdldCgnbWFya2VyU3RlcFNpemUnKSBpcyAwXG4gICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSAobiArIDEpXG4gICAgICBlbHNlXG4gICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSBcIi5cIlxuICAgICAgc3Bhbi5yb3dQb3MgPSBuXG5cbiAgICAgIG4gKz0gc3RlcFNpemVcbiAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCBzcGFuXG5cbiAgICBAZWwuYXBwZW5kQ2hpbGQgY29udGFpbmVyXG4gICAgQFxuXG4gIG1hcmtlckhpZGRlbjogKHNwYW4sbixzdGVwU2l6ZSkgLT5cbiAgICBoaWRkZW4gPSBAZy5jb2x1bW5zLmdldChcImhpZGRlblwiKS5zbGljZSAwXG5cbiAgICBtaW4gPSBNYXRoLm1heCAwLCBuIC0gc3RlcFNpemVcbiAgICBwcmV2SGlkZGVuID0gdHJ1ZVxuICAgIGZvciBqIGluICBbbWluIC4uIG5dIGJ5IDFcbiAgICAgIHByZXZIaWRkZW4gJj0gaGlkZGVuLmluZGV4T2YoaikgPj0gMFxuXG4gICAgIyBmaWx0ZXIgZHVwbGljYXRlc1xuICAgIHJldHVybiBpZiBwcmV2SGlkZGVuXG5cbiAgICBuTWF4ID0gQG1vZGVsLmdldE1heExlbmd0aCgpXG5cbiAgICBsZW5ndGggPSAwXG4gICAgaW5kZXggPSAtMVxuICAgICMgYWNjdW1sYXRlIG11bHRpcGxlIHJvd3NcbiAgICBmb3IgbiBpbiBbbi4ubk1heF0gYnkgMVxuICAgICAgaW5kZXggPSBoaWRkZW4uaW5kZXhPZihuKSB1bmxlc3MgaW5kZXggPj0gMCMgc2V0cyB0aGUgZmlyc3QgaW5kZXhcbiAgICAgIGlmIGhpZGRlbi5pbmRleE9mKG4pID49IDBcbiAgICAgICAgbGVuZ3RoKytcbiAgICAgIGVsc2VcbiAgICAgICAgYnJlYWtcblxuICAgIHMgPSBzdmcuYmFzZSBoZWlnaHQ6IDEwLCB3aWR0aDogMTBcbiAgICBzLnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiXG4gICAgdHJpYW5nbGUgPSBzdmcucG9seWdvbiBwb2ludHM6IFwiMCwwIDUsNSAxMCwwXCIsIHN0eWxlOlxuICAgICAgXCJmaWxsOmxpbWU7c3Ryb2tlOnB1cnBsZTtzdHJva2Utd2lkdGg6MVwiXG4gICAgamJvbmUodHJpYW5nbGUpLm9uIFwiY2xpY2tcIiwgKGV2dCkgPT5cbiAgICAgIGhpZGRlbi5zcGxpY2UgaW5kZXgsIGxlbmd0aFxuICAgICAgQGcuY29sdW1ucy5zZXQgXCJoaWRkZW5cIiwgaGlkZGVuXG5cbiAgICBzLmFwcGVuZENoaWxkIHRyaWFuZ2xlXG4gICAgc3Bhbi5hcHBlbmRDaGlsZCBzXG4gICAgcmV0dXJuIHNcblxuICBtYW5hZ2VFdmVudHM6IC0+XG4gICAgZXZlbnRzID0ge31cbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUNsaWNrc1wiXG4gICAgICBldmVudHMuY2xpY2sgPSBcIl9vbmNsaWNrXCJcbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUhvdmVyXCJcbiAgICAgIGV2ZW50cy5tb3VzZWluID0gXCJfb25tb3VzZWluXCJcbiAgICAgIGV2ZW50cy5tb3VzZW91dCA9IFwiX29ubW91c2VvdXRcIlxuICAgIEBkZWxlZ2F0ZUV2ZW50cyBldmVudHNcbiAgICBAbGlzdGVuVG8gQGcuY29uZmlnLCBcImNoYW5nZTpyZWdpc3Rlck1vdXNlSG92ZXJcIiwgQG1hbmFnZUV2ZW50c1xuICAgIEBsaXN0ZW5UbyBAZy5jb25maWcsIFwiY2hhbmdlOnJlZ2lzdGVyTW91c2VDbGlja1wiLCBAbWFuYWdlRXZlbnRzXG5cbiAgX29uY2xpY2s6IChldnQpIC0+XG4gICAgcm93UG9zID0gZXZ0LnRhcmdldC5yb3dQb3NcbiAgICBzdGVwU2l6ZSA9IEBnLnpvb21lci5nZXQoXCJzdGVwU2l6ZVwiKVxuICAgIEBnLnRyaWdnZXIgXCJjb2x1bW46Y2xpY2tcIiwge3Jvd1Bvczogcm93UG9zLHN0ZXBTaXplOiBzdGVwU2l6ZSwgZXZ0OmV2dH1cblxuICBfb25tb3VzZWluOiAoZXZ0KSAtPlxuICAgIHJvd1BvcyA9IEBnLnpvb21lci5nZXQgXCJzdGVwU2l6ZVwiICogZXZ0LnJvd1Bvc1xuICAgIHN0ZXBTaXplID0gQGcuem9vbWVyLmdldChcInN0ZXBTaXplXCIpXG4gICAgQGcudHJpZ2dlciBcImNvbHVtbjptb3VzZWluXCIsIHtyb3dQb3M6IHJvd1BvcyxzdGVwU2l6ZTogc3RlcFNpemUsIGV2dDpldnR9XG5cbiAgX29ubW91c2VvdXQ6IChldnQpIC0+XG4gICAgcm93UG9zID0gQGcuem9vbWVyLmdldCBcInN0ZXBTaXplXCIgKiBldnQucm93UG9zXG4gICAgc3RlcFNpemUgPSBAZy56b29tZXIuZ2V0KFwic3RlcFNpemVcIilcbiAgICBAZy50cmlnZ2VyIFwiY29sdW1uOm1vdXNlb3V0XCIsIHtyb3dQb3M6IHJvd1BvcyxzdGVwU2l6ZTogc3RlcFNpemUsIGV2dDpldnR9XG5cbm1vZHVsZS5leHBvcnRzID0gSGVhZGVyVmlld1xuIiwiTGFiZWxSb3dWaWV3ID0gcmVxdWlyZSBcIi4vTGFiZWxSb3dWaWV3XCJcbmJvbmVWaWV3ID0gcmVxdWlyZShcImJhY2tib25lLWNoaWxkc1wiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJvbmVWaWV3LmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQGRyYXcoKVxuICAgIEBsaXN0ZW5UbyBAZy56b29tZXIsIFwiY2hhbmdlOl9hbGlnbm1lbnRTY3JvbGxUb3BcIiwgQF9hZGp1c3RTY3JvbGxpbmdUb3BcbiAgICBAZy52aXMub25jZSAnY2hhbmdlOmxvYWRlZCcsIEBfYWRqdXN0U2Nyb2xsaW5nVG9wICwgQFxuXG4gIGRyYXc6IC0+XG4gICAgQHJlbW92ZVZpZXdzKClcbiAgICBmb3IgaSBpbiBbMC4uIEBtb2RlbC5sZW5ndGggLSAxXSBieSAxXG4gICAgICBjb250aW51ZSBpZiBAbW9kZWwuYXQoaSkuZ2V0KCdoaWRkZW4nKVxuICAgICAgdmlldyA9IG5ldyBMYWJlbFJvd1ZpZXcge21vZGVsOiBAbW9kZWwuYXQoaSksIGc6IEBnfVxuICAgICAgdmlldy5vcmRlcmluZyA9IGlcbiAgICAgIEBhZGRWaWV3IFwicm93XyN7aX1cIiwgdmlld1xuXG4gIGV2ZW50czpcbiAgICBcInNjcm9sbFwiOiBcIl9zZW5kU2Nyb2xsRXZlbnRcIlxuXG4gICMgYnJvYWRjYXN0IHRoZSBzY3JvbGxpbmcgZXZlbnQgKGJ5IHRoZSBzY3JvbGxiYXIpXG4gIF9zZW5kU2Nyb2xsRXZlbnQ6IC0+XG4gICAgQGcuem9vbWVyLnNldCBcIl9hbGlnbm1lbnRTY3JvbGxUb3BcIiwgQGVsLnNjcm9sbFRvcCwge29yaWdpbjogXCJsYWJlbFwifVxuXG4gICMgc2V0cyB0aGUgc2Nyb2xsaW5nIHByb3BlcnR5IChmcm9tIGFub3RoZXIgZXZlbnQgZS5nLiBkcmFnZ2luZylcbiAgX2FkanVzdFNjcm9sbGluZ1RvcDogLT5cbiAgICBAZWwuc2Nyb2xsVG9wID0gIEBnLnpvb21lci5nZXQgXCJfYWxpZ25tZW50U2Nyb2xsVG9wXCJcblxuICByZW5kZXI6IC0+XG4gICAgQHJlbmRlclN1YnZpZXdzKClcbiAgICBAZWwuY2xhc3NOYW1lID0gXCJiaW9qc19tc2FfbGFiZWxibG9ja1wiXG4gICAgQGVsLnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiXG4gICAgQGVsLnN0eWxlLnZlcnRpY2FsQWxpZ24gPSBcInRvcFwiXG4gICAgQGVsLnN0eWxlLmhlaWdodCA9ICBAZy56b29tZXIuZ2V0KFwiYWxpZ25tZW50SGVpZ2h0XCIpICsgXCJweFwiXG4gICAgQGVsLnN0eWxlLm92ZXJmbG93WSA9IFwiYXV0b1wiXG4gICAgQGVsLnN0eWxlLm92ZXJmbG93WCA9IFwiaGlkZGVuXCJcbiAgICBAZWwuc3R5bGUuZm9udFNpemUgPSBcIiN7QGcuem9vbWVyLmdldCBcImxhYmVsRm9udHNpemVcIn1cIlxuICAgIEBlbC5zdHlsZS5saW5lSGVpZ2h0ID0gXCIje0BnLnpvb21lci5nZXQgXCJsYWJlbExpbmVIZWlnaHRcIn1cIlxuICAgIEBcbiIsImJvbmVWaWV3ID0gcmVxdWlyZShcImJhY2tib25lLWNoaWxkc1wiKVxuTGFiZWxWaWV3ID0gcmVxdWlyZShcIi4vTGFiZWxWaWV3XCIpXG5NZXRhVmlldyA9IHJlcXVpcmUoXCIuL01ldGFWaWV3XCIpXG5cbm1vZHVsZS5leHBvcnRzID0gYm9uZVZpZXcuZXh0ZW5kXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQGcgPSBkYXRhLmdcbiAgICBAZHJhdygpXG5cbiAgICBAbGlzdGVuVG8gQGcudmlzLFwiY2hhbmdlOmxhYmVsc1wiLCBAZHJhd1JcbiAgICBAbGlzdGVuVG8gQGcudmlzLFwiY2hhbmdlOm1ldGFjZWxsXCIsIEBkcmF3UlxuXG4gIGRyYXc6IC0+XG4gICAgQHJlbW92ZVZpZXdzKClcbiAgICBpZiBAZy52aXMuZ2V0IFwibGFiZWxzXCJcbiAgICAgIEBhZGRWaWV3IFwibGFiZWxzXCIsIG5ldyBMYWJlbFZpZXcge21vZGVsOiBAbW9kZWwsIGc6QGd9XG4gICAgaWYgQGcudmlzLmdldCBcIm1ldGFjZWxsXCJcbiAgICAgIEBhZGRWaWV3IFwibWV0YWNlbGxcIiwgbmV3IE1ldGFWaWV3IHttb2RlbDogQG1vZGVsLCBnOkBnfVxuXG4gIGRyYXdSOiAtPlxuICAgIEBkcmF3KClcbiAgICBAcmVuZGVyKClcblxuICByZW5kZXI6IC0+XG4gICAgQHJlbmRlclN1YnZpZXdzKClcbiAgICBAZWwuc2V0QXR0cmlidXRlIFwiY2xhc3NcIiwgXCJiaW9qc19tc2FfbGFiZWxyb3dcIlxuICAgIEBlbC5zdHlsZS5oZWlnaHQgPSBAZy56b29tZXIuZ2V0IFwicm93SGVpZ2h0XCJcbiAgICBAXG4iLCJ2aWV3ID0gcmVxdWlyZShcImJhY2tib25lLXZpZXdqXCIpXG5kb20gPSByZXF1aXJlIFwiZG9tLWhlbHBlclwiXG5cbkxhYmVsVmlldyA9IHZpZXcuZXh0ZW5kXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQHNlcSA9IGRhdGEuc2VxXG4gICAgQGcgPSBkYXRhLmdcblxuICAgIEBtYW5hZ2VFdmVudHMoKVxuXG4gIG1hbmFnZUV2ZW50czogLT5cbiAgICBldmVudHMgPSB7fVxuICAgIGlmIEBnLmNvbmZpZy5nZXQgXCJyZWdpc3Rlck1vdXNlQ2xpY2tzXCJcbiAgICAgIGV2ZW50cy5jbGljayA9IFwiX29uY2xpY2tcIlxuICAgIGlmIEBnLmNvbmZpZy5nZXQgXCJyZWdpc3Rlck1vdXNlSG92ZXJcIlxuICAgICAgZXZlbnRzLm1vdXNlaW4gPSBcIl9vbm1vdXNlaW5cIlxuICAgICAgZXZlbnRzLm1vdXNlb3V0ID0gXCJfb25tb3VzZW91dFwiXG4gICAgQGRlbGVnYXRlRXZlbnRzIGV2ZW50c1xuICAgIEBsaXN0ZW5UbyBAZy5jb25maWcsIFwiY2hhbmdlOnJlZ2lzdGVyTW91c2VIb3ZlclwiLCBAbWFuYWdlRXZlbnRzXG4gICAgQGxpc3RlblRvIEBnLmNvbmZpZywgXCJjaGFuZ2U6cmVnaXN0ZXJNb3VzZUNsaWNrXCIsIEBtYW5hZ2VFdmVudHNcbiAgICBAbGlzdGVuVG8gQGcudmlzLCBcImNoYW5nZTpsYWJlbE5hbWVcIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAZy52aXMsIFwiY2hhbmdlOmxhYmVsSWRcIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAZy52aXMsIFwiY2hhbmdlOmxhYmVsUGFydGl0aW9uXCIsIEByZW5kZXJcbiAgICBAbGlzdGVuVG8gQGcudmlzLCBcImNoYW5nZTpsYWJlbENoZWNrYm94XCIsIEByZW5kZXJcblxuICByZW5kZXI6IC0+XG4gICAgZG9tLnJlbW92ZUFsbENoaWxkcyBAZWxcblxuICAgIEBlbC5zdHlsZS53aWR0aCA9IFwiI3tAZy56b29tZXIuZ2V0IFwibGFiZWxXaWR0aFwifXB4XCJcbiAgICBAZWwuc3R5bGUuaGVpZ2h0ID0gXCIje0BnLnpvb21lci5nZXQgXCJyb3dIZWlnaHRcIn1weFwiXG4gICAgQGVsLnNldEF0dHJpYnV0ZSBcImNsYXNzXCIsIFwiYmlvanNfbXNhX2xhYmVsc1wiXG5cbiAgICBpZiBALmcudmlzLmdldCBcImxhYmVsQ2hlY2tib3hcIlxuICAgICAgY2hlY2tCb3ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwiaW5wdXRcIlxuICAgICAgY2hlY2tCb3guc2V0QXR0cmlidXRlIFwidHlwZVwiLCBcImNoZWNrYm94XCJcbiAgICAgIGNoZWNrQm94LnZhbHVlID0gQG1vZGVsLmdldCgnaWQnKVxuICAgICAgY2hlY2tCb3gubmFtZSA9IFwic2VxXCJcbiAgICAgIEBlbC5hcHBlbmRDaGlsZCBjaGVja0JveFxuXG4gICAgaWYgQC5nLnZpcy5nZXQgXCJsYWJlbElkXCJcbiAgICAgIGlkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcInNwYW5cIlxuICAgICAgaWQudGV4dENvbnRlbnQgPSBAbW9kZWwuZ2V0IFwiaWRcIlxuICAgICAgaWQuc3R5bGUud2lkdGggPSBAZy56b29tZXIuZ2V0IFwibGFiZWxJZExlbmd0aFwiXG4gICAgICBpZC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuICAgICAgQGVsLmFwcGVuZENoaWxkIGlkXG5cbiAgICBpZiBALmcudmlzLmdldCBcImxhYmVsUGFydGl0aW9uXCJcbiAgICAgIHBhcnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwic3BhblwiXG4gICAgICBwYXJ0LnN0eWxlLndpZHRoID0gMTVcbiAgICAgIHBhcnQudGV4dENvbnRlbnQgPSBAbW9kZWwuZ2V0KFwicGFydGl0aW9uXCIpXG4gICAgICBwYXJ0LnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiXG4gICAgICBAZWwuYXBwZW5kQ2hpbGQgaWRcbiAgICAgIEBlbC5hcHBlbmRDaGlsZCBwYXJ0XG5cbiAgICBpZiBALmcudmlzLmdldCBcImxhYmVsTmFtZVwiXG4gICAgICBuYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcInNwYW5cIlxuICAgICAgbmFtZS50ZXh0Q29udGVudCA9IEBtb2RlbC5nZXQoXCJuYW1lXCIpXG4gICAgICBAZWwuYXBwZW5kQ2hpbGQgbmFtZVxuXG5cbiAgICBAZWwuc3R5bGUub3ZlcmZsb3cgPSBzY3JvbGxcbiAgICBAXG5cbiAgX29uY2xpY2s6IChldnQpIC0+XG4gICAgc2VxSWQgPSBAbW9kZWwuZ2V0IFwiaWRcIlxuICAgIEBnLnRyaWdnZXIgXCJyb3c6Y2xpY2tcIiwge3NlcUlkOnNlcUlkLCBldnQ6ZXZ0fVxuXG4gIF9vbm1vdXNlaW46IChldnQpIC0+XG4gICAgc2VxSWQgPSBAbW9kZWwuZ2V0IFwiaWRcIlxuICAgIEBnLnRyaWdnZXIgXCJyb3c6bW91c2VvdXRcIiwge3NlcUlkOnNlcUlkLCBldnQ6ZXZ0fVxuXG4gIF9vbm1vdXNlb3V0OiAoZXZ0KSAtPlxuICAgIHNlcUlkID0gQG1vZGVsLmdldCBcImlkXCJcbiAgICBAZy50cmlnZ2VyIFwicm93Om1vdXNlb3V0XCIsIHtzZXFJZDpzZXFJZCwgZXZ0OmV2dH1cblxubW9kdWxlLmV4cG9ydHMgPSBMYWJlbFZpZXdcbiIsInZpZXcgPSByZXF1aXJlKFwiYmFja2JvbmUtdmlld2pcIilcbk1lbnVCdWlsZGVyID0gcmVxdWlyZSBcIi4uLy4uL21lbnUvbWVudWJ1aWxkZXJcIlxuXyA9IHJlcXVpcmUgJ3VuZGVyc2NvcmUnXG5kb20gPSByZXF1aXJlIFwiZG9tLWhlbHBlclwiXG5cbm1vZHVsZS5leHBvcnRzID0gTWV0YVZpZXcgPSB2aWV3LmV4dGVuZFxuXG4gIGNsYXNzTmFtZTogXCJiaW9qc19tc2FfbWV0YXZpZXdcIlxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG5cbiAgZXZlbnRzOlxuICAgIGNsaWNrOiBcIl9vbmNsaWNrXCJcbiAgICBtb3VzZWluOiBcIl9vbm1vdXNlaW5cIlxuICAgIG1vdXNlb3V0OiBcIl9vbm1vdXNlb3V0XCJcblxuICByZW5kZXI6IC0+XG4gICAgZG9tLnJlbW92ZUFsbENoaWxkcyBAZWxcblxuICAgIEBlbC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuXG4gICAgd2lkdGggPSBAZy56b29tZXIuZ2V0IFwibWV0YVdpZHRoXCJcbiAgICBAZWwuc3R5bGUud2lkdGggPSB3aWR0aCAtIDVcbiAgICBAZWwuc3R5bGUucGFkZGluZ1JpZ2h0ID0gNVxuXG4gICAgIyBhZGRzIGdhcHNcbiAgICBzZXEgPSBAbW9kZWwuZ2V0KCdzZXEnKVxuICAgIGdhcHMgPSBfLnJlZHVjZSBzZXEsICgobWVtbywgYykgLT4gbWVtbysrIGlmIGMgaXMgJy0nO21lbW8pLDBcbiAgICBnYXBzID0gKGdhcHMgLyBzZXEubGVuZ3RoKS50b0ZpeGVkKDEpXG5cbiAgICAjIGFwcGVuZCBnYXAgY291bnRcbiAgICBnYXBTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCAnc3BhbidcbiAgICBnYXBTcGFuLnRleHRDb250ZW50ID0gZ2Fwc1xuICAgIGdhcFNwYW4uc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcbiAgICBnYXBTcGFuLnN0eWxlLndpZHRoID0gMzVcbiAgICBAZWwuYXBwZW5kQ2hpbGQgZ2FwU3BhblxuXG4gICAgIyBpZGVudGl0eVxuICAgIGlkZW50ID0gQG1vZGVsLmdldCgnaWRlbnRpdHknKVxuICAgIGlkZW50U3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgJ3NwYW4nXG4gICAgaWRlbnRTcGFuLnRleHRDb250ZW50ID0gaWRlbnQudG9GaXhlZCgyKVxuICAgIGlkZW50U3Bhbi5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuICAgIGlkZW50U3Bhbi5zdHlsZS53aWR0aCA9IDQwXG4gICAgQGVsLmFwcGVuZENoaWxkIGlkZW50U3BhblxuXG4gICAgIyBUT0RPOiB0aGlzIG1lbnUgYnVpbGRlciBpcyBqdXN0IGFuIGV4YW1wbGUgaG93IG9uZSBjb3VsZCBjdXN0b21pemUgdGhpc1xuICAgICMgdmlld1xuICAgIG1lbnUgPSBuZXcgTWVudUJ1aWxkZXIoXCLihpdcIilcbiAgICBtZW51LmFkZE5vZGUgXCJVbmlwcm90XCIsKGUpID0+XG4gICAgICB3aW5kb3cub3BlbiBcImh0dHA6Ly9iZXRhLnVuaXByb3Qub3JnL3VuaXByb3QvUTdUMk44XCJcbiAgICBAZWwuYXBwZW5kQ2hpbGQgbWVudS5idWlsZERPTSgpXG4gICAgQGVsLndpZHRoID0gMTBcblxuICAgIEBlbC5zdHlsZS5oZWlnaHQgPSBcIiN7QGcuem9vbWVyLmdldCBcInJvd0hlaWdodFwifXB4XCJcbiAgICBAZWwuc3R5bGUuY3Vyc29yID0gXCJwb2ludGVyXCJcblxuICBfb25jbGljazogKGV2dCkgLT5cbiAgICBAZy50cmlnZ2VyIFwibWV0YTpjbGlja1wiLCB7c2VxSWQ6IEBtb2RlbC5nZXQgXCJpZFwiLCBldnQ6ZXZ0fVxuXG4gIF9vbm1vdXNlaW46IChldnQpIC0+XG4gICAgQGcudHJpZ2dlciBcIm1ldGE6bW91c2VpblwiLCB7c2VxSWQ6IEBtb2RlbC5nZXQgXCJpZFwiLCBldnQ6ZXZ0fVxuXG4gIF9vbm1vdXNlb3V0OiAoZXZ0KSAtPlxuICAgIEBnLnRyaWdnZXIgXCJtZXRhOm1vdXNlb3V0XCIsIHtzZXFJZDogQG1vZGVsLmdldCBcImlkXCIsIGV2dDpldnR9XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG52YXIgQ2x1c3RhbCwgR2VuZXJpY1JlYWRlciwgU2VxLCBTdHIsXG4gIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuU3RyID0gcmVxdWlyZShcIi4vc3RyaW5nc1wiKTtcblxuR2VuZXJpY1JlYWRlciA9IHJlcXVpcmUoXCIuL2dlbmVyaWNfcmVhZGVyXCIpO1xuXG5TZXEgPSByZXF1aXJlKFwiLi9zZXFcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gQ2x1c3RhbCA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgX19leHRlbmRzKENsdXN0YWwsIF9zdXBlcik7XG5cbiAgZnVuY3Rpb24gQ2x1c3RhbCgpIHtcbiAgICByZXR1cm4gQ2x1c3RhbC5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIENsdXN0YWwucGFyc2UgPSBmdW5jdGlvbih0ZXh0KSB7XG4gICAgdmFyIGJsb2Nrc3RhdGUsIGssIGxhYmVsLCBsaW5lLCBsaW5lcywgbWF0Y2gsIHJlZ2V4LCBzZXFDb3VudGVyLCBzZXFzLCBzZXF1ZW5jZTtcbiAgICBzZXFzID0gW107XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0ZXh0KSA9PT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgICAgbGluZXMgPSB0ZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICBsaW5lcyA9IHRleHQuc3BsaXQoXCJcXG5cIik7XG4gICAgfVxuICAgIGlmIChsaW5lc1swXS5zbGljZSgwLCA2KSA9PT0gIVwiQ0xVU1RBTFwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIENMVVNUQUwgSGVhZGVyXCIpO1xuICAgIH1cbiAgICBrID0gMDtcbiAgICBibG9ja3N0YXRlID0gMTtcbiAgICBzZXFDb3VudGVyID0gMDtcbiAgICB3aGlsZSAoayA8IGxpbmVzLmxlbmd0aCkge1xuICAgICAgaysrO1xuICAgICAgbGluZSA9IGxpbmVzW2tdO1xuICAgICAgaWYgKChsaW5lID09IG51bGwpIHx8IGxpbmUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGJsb2Nrc3RhdGUgPSAxO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChsaW5lLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgYmxvY2tzdGF0ZSA9IDE7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKFN0ci5jb250YWlucyhsaW5lLCBcIipcIikpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYmxvY2tzdGF0ZSA9PT0gMSkge1xuICAgICAgICAgIHNlcUNvdW50ZXIgPSAwO1xuICAgICAgICAgIGJsb2Nrc3RhdGUgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHJlZ2V4ID0gL14oPzpcXHMqKShcXFMrKSg/OlxccyspKFxcUyspKD86XFxzKikoXFxkKikoPzpcXHMqfCQpL2c7XG4gICAgICAgIG1hdGNoID0gcmVnZXguZXhlYyhsaW5lKTtcbiAgICAgICAgaWYgKG1hdGNoICE9IG51bGwpIHtcbiAgICAgICAgICBsYWJlbCA9IG1hdGNoWzFdO1xuICAgICAgICAgIHNlcXVlbmNlID0gbWF0Y2hbMl07XG4gICAgICAgICAgaWYgKHNlcUNvdW50ZXIgPj0gc2Vxcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHNlcXMucHVzaChuZXcgU2VxKHNlcXVlbmNlLCBsYWJlbCwgc2VxQ291bnRlcikpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXFzW3NlcUNvdW50ZXJdLnNlcSArPSBzZXF1ZW5jZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VxQ291bnRlcisrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGxpbmUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzZXFzO1xuICB9O1xuXG4gIHJldHVybiBDbHVzdGFsO1xuXG59KShHZW5lcmljUmVhZGVyKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS44LjBcbm1vZHVsZS5leHBvcnRzLnBhcnNlID0gcmVxdWlyZShcIi4vcGFyc2VyXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy53cml0ZXIgPSByZXF1aXJlKFwiLi93cml0ZXJcIik7XG4iLCJpZiAodHlwZW9mIGJpb2pzID09PSAndW5kZWZpbmVkJykge1xuICBiaW9qcyA9IHt9O1xufVxuaWYgKHR5cGVvZiBiaW9qcy52aXMgPT09ICd1bmRlZmluZWQnKSB7XG4gIGJpb2pzLnZpcyA9IHt9O1xufVxuLy8gdXNlIHR3byBuYW1lc3BhY2VzXG53aW5kb3cubXNhID0gYmlvanMudmlzLm1zYSA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9pbmRleCcpO1xuXG4vLyBUT0RPOiBob3cgc2hvdWxkIHRoaXMgYmUgYnVuZGxlZFxuXG5pZiAodHlwZW9mIGJpb2pzLmlvID09PSAndW5kZWZpbmVkJykge1xuICBiaW9qcy5pbyA9IHt9O1xufVxuLy8ganVzdCBidW5kbGUgdGhlIHR3byBwYXJzZXJzXG53aW5kb3cuYmlvanMuaW8uZmFzdGEgPSByZXF1aXJlKFwiYmlvanMtaW8tZmFzdGFcIik7XG53aW5kb3cuYmlvanMuaW8uY2x1c3RhbCA9IHJlcXVpcmUoXCJiaW9qcy1pby1jbHVzdGFsXCIpO1xud2luZG93LmJpb2pzLnhociA9IHJlcXVpcmUoXCJuZXRzXCIpO1xuXG4vLyBzaW11bGF0ZSBzdGFuZGFsb25lIGZsYWdcbndpbmRvdy5iaW9qc1Zpc01zYSA9IHdpbmRvdy5tc2E7XG5cbnJlcXVpcmUoJy4vYnVpbGQvbXNhLmNzcycpO1xuIiwidmFyIHJlcSA9IHJlcXVpcmUoJ3JlcXVlc3QnKVxuXG5tb2R1bGUuZXhwb3J0cyA9IE5ldHNcblxuZnVuY3Rpb24gTmV0cyh1cmksIG9wdHMsIGNiKSB7XG4gIHJlcSh1cmksIG9wdHMsIGNiKVxufSJdfQ==
+
+
+
+// this is a way how you use a bundled file parser
+biojs.io.clustal.read("#", function(seqs){
+var opts = {};
+
+// set your custom properties
+// @see: https://github.com/greenify/biojs-vis-msa/tree/master/src/g
+
+var jalviewData = JSON.parse(document.getElementById("seqData").value);
+opts.seqs = jalviewData['seqs'];
+
+opts.el = document.getElementById("yourDiv");
+opts.vis = {conserv: false, overviewbox: false, labelId: false};
+opts.zoomer = {alignmentHeight: 225, labelWidth: 130,labelFontsize: "13px",labelIdLength: 20, menuFontsize: "12px",menuMarginLeft: "3px", menuPadding: "3px 4px 3px 4px", menuItemFontsize: "14px", menuItemLineHeight: "14px"};
+
+
+
+// init msa
+var m = new msa.msa(opts);
+
+m.g.colorscheme.set("scheme", jalviewData['globalColorScheme']);
+
+var x = 0;
+jalviewData.seqs.forEach( function (seq)
+{
+m.seqs.at(x++).set("features", new msa.model.featurecol(seq.features));
+});
+
+// the menu is independent to the MSA container
+var menuOpts = {};
+menuOpts.el = document.getElementById('div');
+menuOpts.msa = m;
+var defMenu = new msa.menu.defaultmenu(menuOpts);
+m.addView("menu", defMenu);
+
+// call render at the end to display the whole MSA
+m.render();
+
+toggleMenuVisibility();
+toggleMenuVisibility();
+});
+</script>
-(((FER_BRANA:128.0,FER3_RAPSA:128.0):50.75,FER_CAPAA:178.75):121.94443,(Q93Z60_ARATH:271.45456,((O80429_MAIZE:183.0,FER1_MAIZE:183.0):30.5,((Q7XA98_TRIPR:90.0,FER1_PEA:90.0):83.32143,(((FER2_ARATH:64.0,FER1_ARATH:64.0):94.375,(FER1_SPIOL:124.5,FER1_MESCR:124.5):33.875):6.4166718,((Q93XJ9_SOLTU:33.5,FER1_SOLLC:33.5):49.0,FER_CAPAN:82.5):82.29167):8.529755):40.178574):57.95456):29.239868);\r
+(((FER_BRANA:128.0,FER3_RAPSA:128.0):50.75,FER_CAPAA:178.75):121.94443,(Q93Z60_ARATH:271.45456,((O80429_MAIZE:183.0,FER1_MAIZE:183.0):30.5,((Q7XA98_TRIPR:90.0,FER1_PEA:90.0):83.32143,(((FER2_ARATH:64.0,FER1_ARATH:64.0):94.375,(FER1_SPIOL:124.5,FER1_MESCR:124.5):33.875):6.4166718,((Q93XJ9_SOLTU:33.5,FER1_SOLLC:33.5):49.0,FER_CAPAN:82.5):82.29167):8.529755):40.178574):57.95456):29.239868);
-// You need to add the groovy directory to the class path from the script window\r
-// or add the groovy directory to the java classpath when running Jalview\r
-\r
-jvtst = new JvLoadTester().newJvLoadTest('D:\\fooTest.jar');\r
-try { jvtst.TestForAll('D:\\e6-workspace\\Jalview RNA\\examples\\rna\\rfamSml') } \r
-catch (OutOfMemoryError e) { \r
-// inspect jvtst to find out what file + file index it was on\r
-}\r
-// Terminate Jalview - useful if running from command line\r
-if (Jalview.isInBatchMode()) {\r
- Jalview.quit() \r
+// You need to add the groovy directory to the class path from the script window
+// or add the groovy directory to the java classpath when running Jalview
+
+jvtst = new JvLoadTester().newJvLoadTest('D:\\fooTest.jar');
+try { jvtst.TestForAll('D:\\e6-workspace\\Jalview RNA\\examples\\rna\\rfamSml') }
+catch (OutOfMemoryError e) {
+// inspect jvtst to find out what file + file index it was on
+}
+// Terminate Jalview - useful if running from command line
+if (Jalview.isInBatchMode()) {
+ Jalview.quit()
}
\ No newline at end of file
-import jalview.gui.*;\r
-import jalview.io.*;\r
-\r
-def class JvLoadTest {\r
- FileLoader fl = null;\r
- def String safename = null;\r
- JvLoadTest(String sname) { \r
- if (!new File(sname).exists() || new File(sname).canWrite())\r
- {\r
- safename = sname;\r
- } else {\r
- System.err.println("Warning : "+sname+" isn't being used to store temporary files.");\r
- } \r
- }\r
- def public boolean doTest (file) {\r
- fl = new FileLoader(false);\r
- System.gc();\r
- AlignFrame af = fl.LoadFileWaitTillLoaded(file\r
- ,FormatAdapter.FILE);\r
- return doTest(af);\r
- }\r
- def public boolean doSequentialReadTest (file) {\r
- return doSequentialReadTest(file, 0);\r
- }\r
- // Return true if there is more data to read.\r
- def public boolean peekFp(FileParse fp) {\r
- try { fp.mark(); } catch (Exception ex) { System.err.println("FAILED mark."+ex); return false; };\r
- try {\r
- def String nl;\r
- for (i in 1..3) { \r
- nl = fp.nextLine();\r
- if (nl==null) { return false; }\r
- System.out.println(nl +"\\n");\r
- }\r
- } catch (Exception e) { // end of file.\r
- return false; };\r
- try { fp.reset(); } catch (Exception ex) { System.err.println("FAILED rewind."+ex); return false; };\r
- return true;\r
- }\r
- /*\r
- Halt after loading the mx'th entry in the filestream\r
- */\r
- def public boolean doSequentialReadTest (file, int mx) {\r
- // first properly open the file\r
- // if (!doTest(file)) { return };\r
- def FileParse fp = null;\r
- try {\r
- fp = new FileParse(file, AppletFormatAdapter.FILE);\r
- } catch (Exception e) { System.err.println("Couldn't open "+file+"\\n"); e.printStackTrace(); return false;};\r
- Desktop.instance.closeAll_actionPerformed(null)\r
- System.gc();\r
- while (fp!=null && fp.isValid() && (mx==0 || mx!=fp.index)) {\r
- if (!peekFp(fp)) return false;\r
- fl = new FileLoader(false);\r
- AlignFrame af = fl.LoadFileWaitTillLoaded(fp, null);\r
- System.out.println("FileParse index: "+fp.index); \r
- if (af!=null && (mx==0 || mx!=fp.index))\r
- { def boolean res = doTest(af);\r
- if (!res)\r
- {\r
- // return false;\r
- }\r
- } else {\r
- // return false;\r
- }\r
- }\r
- return true;\r
- }\r
- def public void waitTillSettled(AlignFrame af)\r
- {\r
- if (af==null) { return; }\r
- Thread.sleep(10);\r
- while (af.getViewport().updatingConsensus || af.getViewport().updatingConservation) {\r
- Thread.sleep(150); // wait until things settle down\r
- }\r
- }\r
- def public boolean doTest(AlignFrame af) {\r
- Object pr = af.getViewport().getAlignment().getProperty("AC");\r
- if (pr!=null) { System.out.println("Accession = "+(String) pr); }\r
- af.selectAllSequenceMenuItem_actionPerformed(null)\r
- def boolean done = false;\r
- // Just try to save - don\'t mess around with clipboard\r
- /*while (!done) {\r
- try {\r
- af.copy_actionPerformed(null)\r
- done = true;\r
- } catch (Exception e) {\r
- Thread.sleep(100); // wait until clipboard might be available again\r
- }\r
- }*/\r
- if (af==null) { return false; }\r
- waitTillSettled(af);\r
- // Try and save as a jalview project and reload\r
- try {\r
- // af.saveAlignment(safename, "Jalview")\r
- new Jalview2XML().SaveState(new java.io.File(safename));\r
- Thread.sleep(100);\r
- } catch (Exception ex) { \r
- System.out.println("Couldn\'t save.");\r
- ex.printStackTrace(System.err);\r
- return false;\r
- }\r
- waitTillSettled(af);\r
- try {\r
- Desktop.instance.closeAll_actionPerformed(null);\r
- } catch (Exception ex) {}\r
- System.gc();\r
- try {\r
- af = new FileLoader(false).LoadFileWaitTillLoaded(safename, FormatAdapter.FILE); \r
- } \r
- catch (Exception ex) {\r
- System.out.println("Couldn't reload saved file.");\r
- System.gc();\r
- return false;\r
- }\r
- waitTillSettled(af);\r
-\r
- Desktop.instance.closeAll_actionPerformed(null);\r
-\r
- // af.paste(true)\r
- // af.newView_actionPerformed(null)\r
- // af.newView_actionPerformed(null)\r
-\r
- return true;\r
- }\r
- def public boolean TestForAll(String dir) {\r
- println "For directory or file : "+dir;\r
- File fd = new File(dir);\r
- if (!fd.isDirectory()) { return doSequentialReadTest(dir); }\r
- fd.eachFile() { file -> TestForAll(file.getAbsolutePath()) };\r
- }\r
-}\r
-def JvLoadTest newJvLoadTest(String tempFile) {\r
- jalview.gui.Desktop.instance.closeAll_actionPerformed(null);\r
- System.gc();\r
- jalview.gui.Desktop.instance.desktop.showMemoryUsage(true);\r
- return new JvLoadTest(tempFile)\r
+import jalview.gui.*;
+import jalview.io.*;
+
+def class JvLoadTest {
+ FileLoader fl = null;
+ def String safename = null;
+ JvLoadTest(String sname) {
+ if (!new File(sname).exists() || new File(sname).canWrite())
+ {
+ safename = sname;
+ } else {
+ System.err.println("Warning : "+sname+" isn't being used to store temporary files.");
+ }
+ }
+ def public boolean doTest (file) {
+ fl = new FileLoader(false);
+ System.gc();
+ AlignFrame af = fl.LoadFileWaitTillLoaded(file
+ ,FormatAdapter.FILE);
+ return doTest(af);
+ }
+ def public boolean doSequentialReadTest (file) {
+ return doSequentialReadTest(file, 0);
+ }
+ // Return true if there is more data to read.
+ def public boolean peekFp(FileParse fp) {
+ try { fp.mark(); } catch (Exception ex) { System.err.println("FAILED mark."+ex); return false; };
+ try {
+ def String nl;
+ for (i in 1..3) {
+ nl = fp.nextLine();
+ if (nl==null) { return false; }
+ System.out.println(nl +"\\n");
+ }
+ } catch (Exception e) { // end of file.
+ return false; };
+ try { fp.reset(); } catch (Exception ex) { System.err.println("FAILED rewind."+ex); return false; };
+ return true;
+ }
+ /*
+ Halt after loading the mx'th entry in the filestream
+ */
+ def public boolean doSequentialReadTest (file, int mx) {
+ // first properly open the file
+ // if (!doTest(file)) { return };
+ def FileParse fp = null;
+ try {
+ fp = new FileParse(file, AppletFormatAdapter.FILE);
+ } catch (Exception e) { System.err.println("Couldn't open "+file+"\\n"); e.printStackTrace(); return false;};
+ Desktop.instance.closeAll_actionPerformed(null)
+ System.gc();
+ while (fp!=null && fp.isValid() && (mx==0 || mx!=fp.index)) {
+ if (!peekFp(fp)) return false;
+ fl = new FileLoader(false);
+ AlignFrame af = fl.LoadFileWaitTillLoaded(fp, null);
+ System.out.println("FileParse index: "+fp.index);
+ if (af!=null && (mx==0 || mx!=fp.index))
+ { def boolean res = doTest(af);
+ if (!res)
+ {
+ // return false;
+ }
+ } else {
+ // return false;
+ }
+ }
+ return true;
+ }
+ def public void waitTillSettled(AlignFrame af)
+ {
+ if (af==null) { return; }
+ Thread.sleep(10);
+ while (af.getViewport().updatingConsensus || af.getViewport().updatingConservation) {
+ Thread.sleep(150); // wait until things settle down
+ }
+ }
+ def public boolean doTest(AlignFrame af) {
+ Object pr = af.getViewport().getAlignment().getProperty("AC");
+ if (pr!=null) { System.out.println("Accession = "+(String) pr); }
+ af.selectAllSequenceMenuItem_actionPerformed(null)
+ def boolean done = false;
+ // Just try to save - don\'t mess around with clipboard
+ /*while (!done) {
+ try {
+ af.copy_actionPerformed(null)
+ done = true;
+ } catch (Exception e) {
+ Thread.sleep(100); // wait until clipboard might be available again
+ }
+ }*/
+ if (af==null) { return false; }
+ waitTillSettled(af);
+ // Try and save as a jalview project and reload
+ try {
+ // af.saveAlignment(safename, "Jalview")
+ new Jalview2XML().SaveState(new java.io.File(safename));
+ Thread.sleep(100);
+ } catch (Exception ex) {
+ System.out.println("Couldn\'t save.");
+ ex.printStackTrace(System.err);
+ return false;
+ }
+ waitTillSettled(af);
+ try {
+ Desktop.instance.closeAll_actionPerformed(null);
+ } catch (Exception ex) {}
+ System.gc();
+ try {
+ af = new FileLoader(false).LoadFileWaitTillLoaded(safename, FormatAdapter.FILE);
+ }
+ catch (Exception ex) {
+ System.out.println("Couldn't reload saved file.");
+ System.gc();
+ return false;
+ }
+ waitTillSettled(af);
+
+ Desktop.instance.closeAll_actionPerformed(null);
+
+ // af.paste(true)
+ // af.newView_actionPerformed(null)
+ // af.newView_actionPerformed(null)
+
+ return true;
+ }
+ def public boolean TestForAll(String dir) {
+ println "For directory or file : "+dir;
+ File fd = new File(dir);
+ if (!fd.isDirectory()) { return doSequentialReadTest(dir); }
+ fd.eachFile() { file -> TestForAll(file.getAbsolutePath()) };
+ }
+}
+def JvLoadTest newJvLoadTest(String tempFile) {
+ jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+ System.gc();
+ jalview.gui.Desktop.instance.desktop.showMemoryUsage(true);
+ return new JvLoadTest(tempFile)
}
\ No newline at end of file
--- /dev/null
+// Requested by David M Garcia (v3)
+// very messy script to output the scores in annotation rows
+// for the first sequence in a selection on the topmost alignment
+
+// thanks to this thread for cut'n'paste code
+// http://comments.gmane.org/gmane.comp.lang.groovy.user/53010
+
+// Jalview issue at http://issues.jalview.org/browse/JAL-1516
+
+import java.awt.datatransfer.StringSelection
+import static java.awt.Toolkit.*
+
+
+def curviewport = Jalview.getAlignframes()[Jalview.getAlignframes().length-1].getViewport();
+
+// TSV output by default.
+// change "\t" to "," to output CSV file
+def sep = "\t";
+
+if (curviewport.getSelectionGroup()) {
+ // gets selection for topmost alignment
+ def selreg = curviewport.getSelectionGroup();
+ // get aligned positions of first sequence selected
+ def gaps = selreg.getSequenceAt(0).gapMap();
+ String csvfile="";
+ String sseq=""
+
+ curviewport.getAlignment().getAlignmentAnnotation().eachWithIndex{ aa, apos ->
+ def count=1
+ String csv=""
+ gaps.eachWithIndex{col,spos -> if (col>=selreg.getStartRes() && col<=selreg.getEndRes()) {
+ // add sequence for debugging
+ if (count>sseq.length()) {
+ sseq+=sep+selreg.getSequenceAt(0).getCharAt(col); count=sseq.length()+1;
+ };
+ // output height of histogram
+ csv+=sep;
+ def annot = aa.annotations[col];
+ if (annot != null) {
+ csv+=aa.annotations[col].value;
+ }
+ // Uncomment to output string shown in tooltip
+ // csv+=sep+aa.annotations[col].description;
+ }}
+ if (csv.length()>0) {
+ csvfile+=aa.label+csv+"\n"
+ }
+ }
+ defaultToolkit.systemClipboard.setContents(new StringSelection(selreg.getSequenceAt(0).getName()+sseq+"\n"+csvfile), null)
+ print "Sequence"+sseq+"\n";
+ print csvfile;
+ print "\nAlignment Annotation for first selected sequence copied to the clipboard.\n"
+} else {
+ "Select a region in the alignment window.";
+}
-// do something groovy in jalview\r
-print "Hello World.\n";\r
-def alf = Jalview.getAlignframes();\r
-for (ala in alf)\r
-{\r
- // ala is an jalview.gui.AlignFrame object \r
- print ala.getTitle()+"\n";\r
- // get the parent jalview.datamodel.Alignment from the alignment viewport\r
- def alignment = ala.viewport.alignment;\r
- // get the first sequence from the jalview.datamodel.Alignment object\r
- def seq = alignment.getSequenceAt(0); \r
-}\r
+// do something groovy in jalview
+print "Hello World.\n";
+def alf = Jalview.getAlignframes();
+for (ala in alf)
+{
+ // ala is an jalview.gui.AlignFrame object
+ print ala.getTitle()+"\n";
+ // get the parent jalview.datamodel.Alignment from the alignment viewport
+ def alignment = ala.viewport.alignment;
+ // get the first sequence from the jalview.datamodel.Alignment object
+ def seq = alignment.getSequenceAt(0);
+}
--- /dev/null
+// Requested by Hari Jayaram
+// script to output residue positions and values for selected region
+
+// thanks to this thread for cut'n'paste code
+// http://comments.gmane.org/gmane.comp.lang.groovy.user/53010
+
+// Jalview issue at http://issues.jalview.org/browse/JAL-1542
+
+import java.awt.datatransfer.StringSelection
+import static java.awt.Toolkit.*
+
+def curviewport = Jalview.getAlignframes()[Jalview.getAlignframes().length-1].getViewport()
+
+def debug = false
+
+// TSV output by default.
+// change "\t" to "," to output CSV file
+def sep = "\t"
+def gapChar = "-"
+
+if (curviewport.getSelectionGroup()) {
+ // gets selection for topmost alignment
+ def selreg = curviewport.getSelectionGroup()
+ def groupStartCol = selreg.getStartRes()
+ def groupEndCol = selreg.getEndRes()
+
+ if (debug) {println "groupStartCol: " + groupStartCol + ", groupEndCol: " + groupEndCol}
+
+ def csv=new StringBuilder(512)
+
+ // for each sequence in the current selection
+ selreg.getSequences().eachWithIndex{ seq, seqNo ->
+ csv.append(seq.getDisplayId(false).padRight(20,' '))
+ // get map of sequence sites to alignment positions
+ def gaps = seq.gapMap()
+ if (debug) {println "gaps: " + gaps}
+
+ // initialise loop variable to 'not quite shown first column'
+ def lastColShown = groupStartCol-1
+
+ for (mapPos=0 ; ; mapPos++) {
+ def nextResiduePos = gaps[mapPos]
+ // skip over sites that precede selected columns
+ if (nextResiduePos < groupStartCol) {
+ continue;
+ }
+
+ if (debug) {println "mapPos: " + mapPos + ", lastColShown: " + lastColShown + ", nextResiduePos: " + nextResiduePos + ", csv: " + csv}
+
+ // fill in any gaps
+ while (lastColShown < groupEndCol && lastColShown+1 < nextResiduePos) {
+ csv.append(sep+gapChar)
+ lastColShown++
+ }
+ if (lastColShown >= groupEndCol) {
+ break
+ }
+ lastColShown = nextResiduePos
+ def residue = seq.getDatasetSequence().getCharAt(mapPos)
+ csv.append(sep+(mapPos+1) + " (" + residue + ")") // user output is base 1
+ }
+ csv.append("\n")
+ }
+ def result = csv.toString()
+ defaultToolkit.systemClipboard.setContents(new StringSelection(result), null)
+ print result
+ println "Sites for selected region copied to the clipboard"
+} else {
+ "Select a region in the alignment window."
+}
-/**\r
- * Copyright 2010 Tim Down.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
+/**
+ * Copyright 2010 Tim Down.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
var Hashtable=(function(){var p="function";var n=(typeof Array.prototype.splice==p)?function(s,r){s.splice(r,1)}:function(u,t){var s,v,r;if(t===u.length-1){u.length=t}else{s=u.slice(t+1);u.length=t;for(v=0,r=s.length;v<r;++v){u[t+v]=s[v]}}};function a(t){var r;if(typeof t=="string"){return t}else{if(typeof t.hashCode==p){r=t.hashCode();return(typeof r=="string")?r:a(r)}else{if(typeof t.toString==p){return t.toString()}else{try{return String(t)}catch(s){return Object.prototype.toString.call(t)}}}}}function g(r,s){return r.equals(s)}function e(r,s){return(typeof s.equals==p)?s.equals(r):(r===s)}function c(r){return function(s){if(s===null){throw new Error("null is not a valid "+r)}else{if(typeof s=="undefined"){throw new Error(r+" must not be undefined")}}}}var q=c("key"),l=c("value");function d(u,s,t,r){this[0]=u;this.entries=[];this.addEntry(s,t);if(r!==null){this.getEqualityFunction=function(){return r}}}var h=0,j=1,f=2;function o(r){return function(t){var s=this.entries.length,v,u=this.getEqualityFunction(t);while(s--){v=this.entries[s];if(u(t,v[0])){switch(r){case h:return true;case j:return v;case f:return[s,v[1]]}}}return false}}function k(r){return function(u){var v=u.length;for(var t=0,s=this.entries.length;t<s;++t){u[v+t]=this.entries[t][r]}}}d.prototype={getEqualityFunction:function(r){return(typeof r.equals==p)?g:e},getEntryForKey:o(j),getEntryAndIndexForKey:o(f),removeEntryForKey:function(s){var r=this.getEntryAndIndexForKey(s);if(r){n(this.entries,r[0]);return r[1]}return null},addEntry:function(r,s){this.entries[this.entries.length]=[r,s]},keys:k(0),values:k(1),getEntries:function(s){var u=s.length;for(var t=0,r=this.entries.length;t<r;++t){s[u+t]=this.entries[t].slice(0)}},containsKey:o(h),containsValue:function(s){var r=this.entries.length;while(r--){if(s===this.entries[r][1]){return true}}return false}};function m(s,t){var r=s.length,u;while(r--){u=s[r];if(t===u[0]){return r}}return null}function i(r,s){var t=r[s];return(t&&(t instanceof d))?t:null}function b(t,r){var w=this;var v=[];var u={};var x=(typeof t==p)?t:a;var s=(typeof r==p)?r:null;this.put=function(B,C){q(B);l(C);var D=x(B),E,A,z=null;E=i(u,D);if(E){A=E.getEntryForKey(B);if(A){z=A[1];A[1]=C}else{E.addEntry(B,C)}}else{E=new d(D,B,C,s);v[v.length]=E;u[D]=E}return z};this.get=function(A){q(A);var B=x(A);var C=i(u,B);if(C){var z=C.getEntryForKey(A);if(z){return z[1]}}return null};this.containsKey=function(A){q(A);var z=x(A);var B=i(u,z);return B?B.containsKey(A):false};this.containsValue=function(A){l(A);var z=v.length;while(z--){if(v[z].containsValue(A)){return true}}return false};this.clear=function(){v.length=0;u={}};this.isEmpty=function(){return !v.length};var y=function(z){return function(){var A=[],B=v.length;while(B--){v[B][z](A)}return A}};this.keys=y("keys");this.values=y("values");this.entries=y("getEntries");this.remove=function(B){q(B);var C=x(B),z,A=null;var D=i(u,C);if(D){A=D.removeEntryForKey(B);if(A!==null){if(!D.entries.length){z=m(v,C);n(v,z);delete u[C]}}}return A};this.size=function(){var A=0,z=v.length;while(z--){A+=v[z].entries.length}return A};this.each=function(C){var z=w.entries(),A=z.length,B;while(A--){B=z[A];C(B[0],B[1])}};this.putAll=function(H,C){var B=H.entries();var E,F,D,z,A=B.length;var G=(typeof C==p);while(A--){E=B[A];F=E[0];D=E[1];if(G&&(z=w.get(F))){D=C(F,z,D)}w.put(F,D)}};this.clone=function(){var z=new b(t,r);z.putAll(w);return z}}return b})();
\ No newline at end of file
-/* Jmol 12.0 script library Jmol.js 9:48 PM 1/31/2011 Bob Hanson\r
-\r
- checkbox heirarchy -- see http://chemapps.stolaf.edu/jmol/docs/examples-11/check.htm\r
-\r
- based on:\r
- *\r
- * Copyright (C) 2004-2005 Miguel, Jmol Development, www.jmol.org\r
- *\r
- * Contact: hansonr@stolaf.edu\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\r
- * 02111-1307 USA.\r
- */\r
-\r
-// for documentation see www.jmol.org/jslibrary\r
-\r
-try{if(typeof(_jmol)!="undefined")exit()\r
-\r
-// place "?NOAPPLET" on your command line to check applet control action with a textarea\r
-// place "?JMOLJAR=xxxxx" to use a specific jar file\r
-\r
-// bob hanson -- jmolResize(w,h) -- resizes absolutely or by percent (w or h 0.5 means 50%)\r
-// angel herraez -- update of jmolResize(w,h,targetSuffix) so it is not tied to first applet\r
-// bob hanson -- jmolEvaluate -- evaluates molecular math 8:37 AM 2/23/2007\r
-// bob hanson -- jmolScriptMessage -- returns all "scriptStatus" messages 8:37 AM 2/23/2007\r
-// bob hanson -- jmolScriptEcho -- returns all "scriptEcho" messages 8:37 AM 2/23/2007\r
-// bob hanson -- jmolScriptWait -- 11:31 AM 5/2/2006\r
-// bob hanson -- remove trailing separatorHTML in radio groups -- 12:18 PM 5/6/2006\r
-// bob hanson -- adds support for dynamic DOM script nodes 7:04 AM 5/19/2006\r
-// bob hanson -- adds try/catch for wiki - multiple code passes 7:05 AM 5/19/2006\r
-// bob hanson -- auto-initiates to defaultdir/defaultjar -- change as desired.\r
-// bob hanson -- adding save/restore orientation w/ and w/o delay 11:49 AM 5/25/2006\r
-// bob hanson -- adding AjaxJS service 11:16 AM 6/3/2006\r
-// bob hanson -- fix for iframes not available for finding applet\r
-// bob hanson -- added applet fake ?NOAPPLET URL flag\r
-// bob hanson -- added jmolSetCallback(calbackName, funcName) 3:32 PM 6/13/2006\r
-// used PRIOR to jmolApplet() or jmolAppletInline()\r
-// added 4th array element in jmolRadioGroup -- title\r
-// added <span> and id around link, checkbox, radio, menu\r
-// fixing AJAX loads for MSIE/Opera-Mozilla incompatibility\r
-// -- renamed Jmol-11.js from Jmol-new.js; JmolApplet.jar from JmolAppletProto.jar\r
-// renamed Jmol.js for Jmol 11 distribution\r
-// -- modified jmolRestoreOrientation() to be immediate, no 1-second delay\r
-// bob hanson -- jmolScriptWait always returns a string -- 11:23 AM 9/16/2006\r
-// bh -- jmolCommandInput()\r
-// bh -- jmolSetTranslation(TF) -- forces translation even if there might be message callback issues\r
-// bh -- minor fixes suggested by Angel\r
-// bh -- adds jmolSetSyncId() and jmolGetSyncId()\r
-// bh 3/2008 -- adds jmolAppendInlineScript() and jmolAppendInlineArray()\r
-// bh 3/2008 -- fixes IE7 bug in relation to jmolLoadInlineArray()\r
-// bh 6/2008 -- adds jmolSetAppletWindow()\r
-// Angel H. 6/2008 -- added html <label> tags to checkboxes and radio buttons [in jmolCheckbox() and _jmolRadio() functions]\r
-// bh 7/2008 -- code fix "for(i..." not "for(var i..."\r
-// bh 12/2008 -- jmolLoadInline, jmolLoadInlineArray, jmolLoadInlineScript, jmolAppendInlineScript, jmolAppendInlineArray all return error message or null (Jmol 11.7.16)\r
-// bh 12/2008 -- jmolScriptWaitOutput() -- waits for script to complete and delivers output normally sent to console\r
-\r
-// bh 5/2009 -- Support for XHTML using jmolSetXHTML(id)\r
-// ah & bh 6/2009 -- New jmolResizeApplet() more flexible, similar to jmolApplet() size syntax\r
-// bh 11/2009 -- care in accessing top.document\r
-// bh 12/2009 -- added jmolSetParameter(name, value)\r
-// bh 12/2009 -- added PARAMS=name:value;name:value;name:value... for command line\r
-// bh 12/2009 -- overhaul of target checking\r
-// bh 1/2010 -- all _xxxx() methods ALWAYS have complete argument list\r
-// bh 1/2010 -- adds option to run a JavaScript function from any Jmol control. \r
-// This is accomplished by passing an array rather than a script:\r
-// jmolHref([myfunc,"my param 1", "my param 2"], "testing")\r
-// function myfunc(jmolControlObject, [myfunc,"my param 1", "my param 2"], target){...}\r
-// and allows much more flexibility with responding to controls\r
-// bh 4/2010 -- added jmolSetMemoryMb(nMb)\r
-// ah 1/2011 -- wider detection of browsers; more browsers now use the object tag instead of the applet tag; \r
-// fix of object tag (removed classid) accounts for change of behavior in Chrome\r
-// bh 3/2011 -- added jmolLoadAjax_STOLAF_NIH\r
-\r
-var defaultdir = "."\r
-var defaultjar = "JmolApplet.jar"\r
-\r
-\r
-// Note added 12:41 PM 9/21/2008 by Bob Hanson, hansonr@stolaf.edu:\r
-\r
-// JMOLJAR=xxxxx.jar on the URL for this page will override\r
-// the JAR file specified in the jmolInitialize() call.\r
-\r
-// The idea is that it can be very useful to test a web page with different JAR files\r
-// Or for an expert user to substitute a signed applet for an unsigned one\r
-// so as to use a broader range of models or to create JPEG files, for example.\r
-\r
-// If the JAR file is not in the current directory (has any sort of "/" in its name)\r
-// then the user is presented with a warning and asked whether it is OK to change Jar files.\r
-// The default action, if the user just presses "OK" is to NOT allow the change. \r
-// The user must type the word "yes" in the prompt box for the change to be approved.\r
-\r
-// If you don't want people to be able to switch in their own JAR file on your page,\r
-// simply set this next line to read "var allowJMOLJAR = false".\r
-\r
-\r
-var undefined; // for IE 5 ... wherein undefined is undefined\r
-\r
-////////////////////////////////////////////////////////////////\r
-// Basic Scripting infrastruture\r
-////////////////////////////////////////////////////////////////\r
-\r
-function jmolInitialize(codebaseDirectory, fileNameOrUseSignedApplet) {\r
- if (_jmol.initialized)\r
- return;\r
- _jmol.initialized = true;\r
- if(_jmol.jmoljar) {\r
- var f = _jmol.jmoljar;\r
- if (f.indexOf("/") >= 0) {\r
- alert ("This web page URL is requesting that the applet used be " + f + ". This is a possible security risk, particularly if the applet is signed, because signed applets can read and write files on your local machine or network.")\r
- var ok = prompt("Do you want to use applet " + f + "? ","yes or no")\r
- if (ok == "yes") {\r
- codebaseDirectory = f.substring(0, f.lastIndexOf("/"));\r
- fileNameOrUseSignedApplet = f.substring(f.lastIndexOf("/") + 1);\r
- } else {\r
- _jmolGetJarFilename(fileNameOrUseSignedApplet);\r
- alert("The web page URL was ignored. Continuing using " + _jmol.archivePath + ' in directory "' + codebaseDirectory + '"');\r
- }\r
- } else {\r
- fileNameOrUseSignedApplet = f;\r
- }\r
- }\r
- _jmolSetCodebase(codebaseDirectory);\r
- _jmolGetJarFilename(fileNameOrUseSignedApplet);\r
- _jmolOnloadResetForms();\r
-}\r
-\r
-function jmolSetTranslation(TF) {\r
- _jmol.params.doTranslate = ''+TF;\r
-}\r
-\r
-function _jmolGetJarFilename(fileNameOrFlag) {\r
- _jmol.archivePath =\r
- (typeof(fileNameOrFlag) == "string" ? fileNameOrFlag : (fileNameOrFlag ? "JmolAppletSigned" : "JmolApplet") + "0.jar");\r
-}\r
-\r
-function jmolSetDocument(doc) {\r
- _jmol.currentDocument = doc;\r
-}\r
-\r
-function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) {\r
- _jmolInitCheck();\r
- _jmol.params.boxbgcolor = boxbgcolor;\r
- if (boxfgcolor)\r
- _jmol.params.boxfgcolor = boxfgcolor\r
- else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF")\r
- _jmol.params.boxfgcolor = "black";\r
- else\r
- _jmol.params.boxfgcolor = "white";\r
- if (progresscolor)\r
- _jmol.params.progresscolor = progresscolor;\r
- if (_jmol.debugAlert)\r
- alert(" boxbgcolor=" + _jmol.params.boxbgcolor +\r
- " boxfgcolor=" + _jmol.params.boxfgcolor +\r
- " progresscolor=" + _jmol.params.progresscolor);\r
-}\r
-\r
-function jmolSetAppletWindow(w) {\r
- _jmol.appletWindow = w;\r
-}\r
-\r
-function jmolApplet(size, script, nameSuffix) {\r
- _jmolInitCheck();\r
- return _jmolApplet(size, null, script, nameSuffix);\r
-}\r
-\r
-////////////////////////////////////////////////////////////////\r
-// Basic controls\r
-////////////////////////////////////////////////////////////////\r
-\r
-// undefined means it wasn't there; null means it was explicitly listed as null (so as to skip it)\r
-\r
-function jmolButton(script, label, id, title) {\r
- _jmolInitCheck();\r
- id != undefined && id != null || (id = "jmolButton" + _jmol.buttonCount);\r
- label != undefined && label != null || (label = script.substring(0, 32));\r
- ++_jmol.buttonCount;\r
- var scriptIndex = _jmolAddScript(script);\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='button' name='" + id + "' id='" + id +\r
- "' value='" + label +\r
- "' onclick='_jmolClick(this," + scriptIndex + _jmol.targetText +\r
- ")' onmouseover='_jmolMouseOver(" + scriptIndex +\r
- ");return true' onmouseout='_jmolMouseOut()' " +\r
- _jmol.buttonCssText + " /></span>";\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked,\r
- labelHtml, isChecked, id, title) {\r
- _jmolInitCheck();\r
- id != undefined && id != null || (id = "jmolCheckbox" + _jmol.checkboxCount);\r
- ++_jmol.checkboxCount;\r
- if (scriptWhenChecked == undefined || scriptWhenChecked == null ||\r
- scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) {\r
- alert("jmolCheckbox requires two scripts");\r
- return;\r
- }\r
- if (labelHtml == undefined || labelHtml == null) {\r
- alert("jmolCheckbox requires a label");\r
- return;\r
- }\r
- var indexChecked = _jmolAddScript(scriptWhenChecked);\r
- var indexUnchecked = _jmolAddScript(scriptWhenUnchecked);\r
- var eospan = "</span>"\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='checkbox' name='" + id + "' id='" + id +\r
- "' onclick='_jmolCbClick(this," +\r
- indexChecked + "," + indexUnchecked + _jmol.targetText +\r
- ")' onmouseover='_jmolCbOver(this," + indexChecked + "," +\r
- indexUnchecked +\r
- ");return true' onmouseout='_jmolMouseOut()' " +\r
- (isChecked ? "checked='true' " : "")+ _jmol.checkboxCssText + " />" \r
- if (labelHtml.toLowerCase().indexOf("<td>")>=0) {\r
- t += eospan\r
- eospan = "";\r
- }\r
- t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan;\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-function jmolStartNewRadioGroup() {\r
- ++_jmol.radioGroupCount;\r
-}\r
-\r
-function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName, id, title) {\r
- /*\r
-\r
- array: [radio1,radio2,radio3...]\r
- where radioN = ["script","label",isSelected,"id","title"]\r
-\r
- */\r
-\r
- _jmolInitCheck();\r
- var type = typeof arrayOfRadioButtons;\r
- if (type != "object" || type == null || ! arrayOfRadioButtons.length) {\r
- alert("invalid arrayOfRadioButtons");\r
- return;\r
- }\r
- separatorHtml != undefined && separatorHtml != null || (separatorHtml = " ");\r
- var len = arrayOfRadioButtons.length;\r
- jmolStartNewRadioGroup();\r
- groupName || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));\r
- var t = "<span id='"+(id ? id : groupName)+"'>";\r
- for (var i = 0; i < len; ++i) {\r
- if (i == len - 1)\r
- separatorHtml = "";\r
- var radio = arrayOfRadioButtons[i];\r
- type = typeof radio;\r
- if (type == "object") {\r
- t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName, (radio.length > 3 ? radio[3]: (id ? id : groupName)+"_"+i), (radio.length > 4 ? radio[4] : 0), title);\r
- } else {\r
- t += _jmolRadio(radio, null, null, separatorHtml, groupName, (id ? id : groupName)+"_"+i, title);\r
- }\r
- }\r
- t+="</span>"\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-\r
-function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {\r
- _jmolInitCheck();\r
- if (_jmol.radioGroupCount == 0)\r
- ++_jmol.radioGroupCount;\r
- var t = _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, (id ? id : groupName + "_" + _jmol.radioCount), title ? title : 0);\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-function jmolLink(script, label, id, title) {\r
- _jmolInitCheck();\r
- id != undefined && id != null || (id = "jmolLink" + _jmol.linkCount);\r
- label != undefined && label != null || (label = script.substring(0, 32));\r
- ++_jmol.linkCount;\r
- var scriptIndex = _jmolAddScript(script);\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><a name='" + id + "' id='" + id + \r
- "' href='javascript:_jmolClick(this," + scriptIndex + _jmol.targetText + ");' onmouseover='_jmolMouseOver(" + scriptIndex +\r
- ");return true;' onmouseout='_jmolMouseOut()' " +\r
- _jmol.linkCssText + ">" + label + "</a></span>";\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-function jmolCommandInput(label, size, id, title) {\r
- _jmolInitCheck();\r
- id != undefined && id != null || (id = "jmolCmd" + _jmol.cmdCount);\r
- label != undefined && label != null || (label = "Execute");\r
- size != undefined && !isNaN(size) || (size = 60);\r
- ++_jmol.cmdCount;\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='" + id + "' id='" + id + \r
- "' size='"+size+"' onkeypress='_jmolCommandKeyPress(event,\""+id+"\"" + _jmol.targetText + ")'><input type=button value = '"+label+"' onclick='jmolScript(document.getElementById(\""+id+"\").value" + _jmol.targetText + ")' /></span>";\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
-}\r
-\r
-function _jmolCommandKeyPress(e, id, target) {\r
- var keycode = (window.event ? window.event.keyCode : e ? e.which : 0);\r
- if (keycode == 13) {\r
- var inputBox = document.getElementById(id)\r
- _jmolScriptExecute(inputBox, inputBox.value, target)\r
- }\r
-}\r
-\r
-function _jmolScriptExecute(element,script,target) {\r
- if (typeof(script) == "object")\r
- script[0](element, script, target)\r
- else\r
- jmolScript(script, target) \r
-}\r
-\r
-function jmolMenu(arrayOfMenuItems, size, id, title) {\r
- _jmolInitCheck();\r
- id != undefined && id != null || (id = "jmolMenu" + _jmol.menuCount);\r
- ++_jmol.menuCount;\r
- var type = typeof arrayOfMenuItems;\r
- if (type != null && type == "object" && arrayOfMenuItems.length) {\r
- var len = arrayOfMenuItems.length;\r
- if (typeof size != "number" || size == 1)\r
- size = null;\r
- else if (size < 0)\r
- size = len;\r
- var sizeText = size ? " size='" + size + "' " : "";\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><select name='" + id + "' id='" + id +\r
- "' onChange='_jmolMenuSelected(this" + _jmol.targetText + ")'" +\r
- sizeText + _jmol.menuCssText + ">";\r
- for (var i = 0; i < len; ++i) {\r
- var menuItem = arrayOfMenuItems[i];\r
- type = typeof menuItem;\r
- var script, text;\r
- var isSelected = undefined;\r
- if (type == "object" && menuItem != null) {\r
- script = menuItem[0];\r
- text = menuItem[1];\r
- isSelected = menuItem[2];\r
- } else {\r
- script = text = menuItem;\r
- }\r
- text != undefined && text != null || (text = script); \r
- if (script=="#optgroup") {\r
- t += "<optgroup label='" + text + "'>"; \r
- } else if (script=="#optgroupEnd") {\r
- t += "</optgroup>"; \r
- } else { \r
- var scriptIndex = _jmolAddScript(script);\r
- var selectedText = isSelected ? "' selected='true'>" : "'>";\r
- t += "<option value='" + scriptIndex + selectedText + text + "</option>";\r
- }\r
- }\r
- t += "</select></span>";\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
- }\r
-}\r
-\r
-function jmolHtml(html) {\r
- return _jmolDocumentWrite(html);\r
-}\r
-\r
-function jmolBr() {\r
- return _jmolDocumentWrite("<br />");\r
-}\r
-\r
-////////////////////////////////////////////////////////////////\r
-// advanced scripting functions\r
-////////////////////////////////////////////////////////////////\r
-\r
-function jmolDebugAlert(enableAlerts) {\r
- _jmol.debugAlert = (enableAlerts == undefined || enableAlerts)\r
-}\r
-\r
-function jmolAppletInline(size, inlineModel, script, nameSuffix) {\r
- _jmolInitCheck();\r
- return _jmolApplet(size, _jmolSterilizeInline(inlineModel),\r
- script, nameSuffix);\r
-}\r
-\r
-function jmolSetTarget(targetSuffix) {\r
- _jmol.targetSuffix = targetSuffix;\r
- _jmol.targetText = targetSuffix ? ",\"" + targetSuffix + "\"" : ",0";\r
-}\r
-\r
-function jmolScript(script, targetSuffix) {\r
- if (script) {\r
- _jmolCheckBrowser();\r
- if (targetSuffix == "all") {\r
- with (_jmol) {\r
- for (var i = 0; i < appletSuffixes.length; ++i) {\r
- var applet = _jmolGetApplet(appletSuffixes[i]);\r
- if (applet) applet.script(script);\r
- }\r
- }\r
- } else {\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (applet) applet.script(script);\r
- }\r
- }\r
-}\r
-\r
-function jmolLoadInline(model, targetSuffix) {\r
- if (!model)return "ERROR: NO MODEL"\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (!applet)return "ERROR: NO APPLET"\r
- if (typeof(model) == "string")\r
- return applet.loadInlineString(model, "", false);\r
- else\r
- return applet.loadInlineArray(model, "", false);\r
-}\r
-\r
-\r
-function jmolLoadInlineScript(model, script, targetSuffix) {\r
- if (!model)return "ERROR: NO MODEL"\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (!applet)return "ERROR: NO APPLET"\r
- return applet.loadInlineString(model, script, false);\r
-}\r
-\r
-\r
-function jmolLoadInlineArray(ModelArray, script, targetSuffix) {\r
- if (!model)return "ERROR: NO MODEL"\r
- script || (script="")\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (!applet)return "ERROR: NO APPLET"\r
- try {\r
- return applet.loadInlineArray(ModelArray, script, false);\r
- } catch (err) {\r
- //IE 7 bug\r
- return applet.loadInlineString(ModelArray.join("\n"), script, false);\r
- }\r
-}\r
-\r
-function jmolAppendInlineArray(ModelArray, script, targetSuffix) {\r
- if (!model)return "ERROR: NO MODEL"\r
- script || (script="")\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (!applet)return "ERROR: NO APPLET"\r
- try {\r
- return applet.loadInlineArray(ModelArray, script, true);\r
- } catch (err) {\r
- //IE 7 bug\r
- return applet.loadInlineString(ModelArray.join("\n"), script, true);\r
- }\r
-}\r
-\r
-function jmolAppendInlineScript(model, script, targetSuffix) {\r
- if (!model)return "ERROR: NO MODEL"\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (!applet)return "ERROR: NO APPLET"\r
- return applet.loadInlineString(model, script, true);\r
-}\r
-\r
-function jmolCheckBrowser(action, urlOrMessage, nowOrLater) {\r
- if (typeof action == "string") {\r
- action = action.toLowerCase();\r
- action == "alert" || action == "redirect" || action == "popup" || (action = null);\r
- }\r
- if (typeof action != "string")\r
- alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +\r
- "action must be 'alert', 'redirect', or 'popup'");\r
- else {\r
- if (typeof urlOrMessage != "string")\r
- alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +\r
- "urlOrMessage must be a string");\r
- else {\r
- _jmol.checkBrowserAction = action;\r
- _jmol.checkBrowserUrlOrMessage = urlOrMessage;\r
- }\r
- }\r
- if (typeof nowOrLater == "string" && nowOrLater.toLowerCase() == "now")\r
- _jmolCheckBrowser();\r
-}\r
-\r
-////////////////////////////////////////////////////////////////\r
-// Cascading Style Sheet Class support\r
-////////////////////////////////////////////////////////////////\r
-\r
-function jmolSetAppletCssClass(appletCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.appletCssClass = appletCssClass;\r
- _jmol.appletCssText = appletCssClass ? "class='" + appletCssClass + "' " : "";\r
- }\r
-}\r
-\r
-function jmolSetButtonCssClass(buttonCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.buttonCssClass = buttonCssClass;\r
- _jmol.buttonCssText = buttonCssClass ? "class='" + buttonCssClass + "' " : "";\r
- }\r
-}\r
-\r
-function jmolSetCheckboxCssClass(checkboxCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.checkboxCssClass = checkboxCssClass;\r
- _jmol.checkboxCssText = checkboxCssClass ? "class='" + checkboxCssClass + "' " : "";\r
- }\r
-}\r
-\r
-function jmolSetRadioCssClass(radioCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.radioCssClass = radioCssClass;\r
- _jmol.radioCssText = radioCssClass ? "class='" + radioCssClass + "' " : "";\r
- }\r
-}\r
-\r
-function jmolSetLinkCssClass(linkCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.linkCssClass = linkCssClass;\r
- _jmol.linkCssText = linkCssClass ? "class='" + linkCssClass + "' " : "";\r
- }\r
-}\r
-\r
-function jmolSetMenuCssClass(menuCssClass) {\r
- if (_jmol.hasGetElementById) {\r
- _jmol.menuCssClass = menuCssClass;\r
- _jmol.menuCssText = menuCssClass ? "class='" + menuCssClass + "' " : "";\r
- }\r
-}\r
-\r
-////////////////////////////////////////////////////////////////\r
-// functions for INTERNAL USE ONLY which are subject to change\r
-// use at your own risk ... you have been WARNED!\r
-////////////////////////////////////////////////////////////////\r
-var _jmol = {\r
- currentDocument: document,\r
-\r
- debugAlert: false,\r
- \r
- codebase: "",\r
- modelbase: ".",\r
- \r
- appletCount: 0,\r
- appletSuffixes: [],\r
- appletWindow: null,\r
- allowedJmolSize: [25, 2048, 300], // min, max, default (pixels)\r
- /* By setting the _jmol.allowedJmolSize[] variable in the webpage \r
- before calling jmolApplet(), limits for applet size can be overriden.\r
- 2048 standard for GeoWall (http://geowall.geo.lsa.umich.edu/home.html)\r
- */ \r
- buttonCount: 0,\r
- checkboxCount: 0,\r
- linkCount: 0,\r
- cmdCount: 0,\r
- menuCount: 0,\r
- radioCount: 0,\r
- radioGroupCount: 0,\r
- \r
- appletCssClass: null,\r
- appletCssText: "",\r
- buttonCssClass: null,\r
- buttonCssText: "",\r
- checkboxCssClass: null,\r
- checkboxCssText: "",\r
- java_arguments: "-Xmx512m",\r
- radioCssClass: null,\r
- radioCssText: "",\r
- linkCssClass: null,\r
- linkCssText: "",\r
- menuCssClass: null,\r
- menuCssText: "",\r
- \r
- targetSuffix: 0,\r
- targetText: ",0",\r
- scripts: [""],\r
- params: {\r
- syncId: ("" + Math.random()).substring(3),\r
- progressbar: "true",\r
- progresscolor: "blue",\r
- boxbgcolor: "black",\r
- boxfgcolor: "white",\r
- boxmessage: "Downloading JmolApplet ..."\r
- },\r
- ua: navigator.userAgent.toLowerCase(),\r
- // uaVersion: parseFloat(navigator.appVersion), // not used\r
- \r
- os: "unknown",\r
- browser: "unknown",\r
- browserVersion: 0,\r
- hasGetElementById: !!document.getElementById,\r
- isJavaEnabled: navigator.javaEnabled(),\r
- // isNetscape47Win: false, // not used, N4.7 is no longer supported even for detection\r
- useIEObject: false,\r
- useHtml4Object: false,\r
- \r
- windowsClassId: "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93",\r
- windowsCabUrl:\r
- "http://java.sun.com/update/1.6.0/jinstall-6u22-windows-i586.cab",\r
-\r
- isBrowserCompliant: false,\r
- isJavaCompliant: false,\r
- isFullyCompliant: false,\r
-\r
- initialized: false,\r
- initChecked: false,\r
- \r
- browserChecked: false,\r
- checkBrowserAction: "alert",\r
- checkBrowserUrlOrMessage: null,\r
-\r
- archivePath: null, // JmolApplet0.jar OR JmolAppletSigned0.jar\r
-\r
- previousOnloadHandler: null,\r
-\r
- jmoljar: null, \r
- useNoApplet: false,\r
-\r
- ready: {}\r
-}\r
-\r
-with (_jmol) {\r
- function _jmolTestUA(candidate) {\r
- var ua = _jmol.ua;\r
- var index = ua.indexOf(candidate);\r
- if (index < 0)\r
- return false;\r
- _jmol.browser = candidate;\r
- _jmol.browserVersion = parseFloat(ua.substring(index+candidate.length+1));\r
- return true;\r
- }\r
- \r
- function _jmolTestOS(candidate) {\r
- if (_jmol.ua.indexOf(candidate) < 0)\r
- return false;\r
- _jmol.os = candidate;\r
- return true;\r
- }\r
- \r
- _jmolTestUA("konqueror") ||\r
- _jmolTestUA("webkit") ||\r
- _jmolTestUA("omniweb") ||\r
- _jmolTestUA("opera") ||\r
- _jmolTestUA("webtv") ||\r
- _jmolTestUA("icab") ||\r
- _jmolTestUA("msie") ||\r
- (_jmol.ua.indexOf("compatible") < 0 && _jmolTestUA("mozilla")); //Netscape, Mozilla, Seamonkey, Firefox and anything assimilated\r
- \r
- _jmolTestOS("linux") ||\r
- _jmolTestOS("unix") ||\r
- _jmolTestOS("mac") ||\r
- _jmolTestOS("win");\r
-\r
- /* not used:\r
- isNetscape47Win = (os == "win" && browser == "mozilla" &&\r
- browserVersion >= 4.78 && browserVersion <= 4.8);\r
- */\r
-\r
- if (os == "win") {\r
- isBrowserCompliant = hasGetElementById;\r
- } else if (os == "mac") { // mac is the problem child :-(\r
- if (browser == "mozilla" && browserVersion >= 5) {\r
- // miguel 2004 11 17\r
- // checking the plugins array does not work because\r
- // Netscape 7.2 OS X still has Java 1.3.1 listed even though\r
- // javaplugin.sf.net is installed to upgrade to 1.4.2\r
- eval("try {var v = java.lang.System.getProperty('java.version');" +\r
- " _jmol.isBrowserCompliant = v >= '1.4.2';" +\r
- " } catch (e) { }");\r
- } else if (browser == "opera" && browserVersion <= 7.54) {\r
- isBrowserCompliant = false;\r
- } else {\r
- isBrowserCompliant = hasGetElementById &&\r
- !((browser == "msie") ||\r
- (browser == "webkit" && browserVersion < 125.12));\r
- }\r
- } else if (os == "linux" || os == "unix") {\r
- if (browser == "konqueror" && browserVersion <= 3.3)\r
- isBrowserCompliant = false;\r
- else\r
- isBrowserCompliant = hasGetElementById;\r
- } else { // other OS\r
- isBrowserCompliant = hasGetElementById;\r
- }\r
-\r
- // possibly more checks in the future for this\r
- isJavaCompliant = isJavaEnabled;\r
-\r
- isFullyCompliant = isBrowserCompliant && isJavaCompliant;\r
-\r
- useIEObject = (os == "win" && browser == "msie" && browserVersion >= 5.5);\r
- useHtml4Object =\r
- (browser == "mozilla" && browserVersion >= 5) ||\r
- (browser == "opera" && browserVersion >= 8) ||\r
- (browser == "webkit" && browserVersion >= 412.2);\r
- try {\r
- if (top.location.search.indexOf("JMOLJAR=")>=0)\r
- jmoljar = top.location.search.split("JMOLJAR=")[1].split("&")[0];\r
- } catch(e) {\r
- // can't access top.location\r
- }\r
- try {\r
- useNoApplet = (top.location.search.indexOf("NOAPPLET")>=0);\r
- } catch(e) {\r
- // can't access top.document\r
- }\r
-}\r
-\r
-function jmolSetMemoryMb(nMb) {\r
- _jmol.java_arguments = "-Xmx" + Math.round(nMb) + "m"\r
-}\r
-\r
-function jmolSetParameter(name,value) {\r
- _jmol.params[name] = value\r
-}\r
-\r
-function jmolSetCallback(callbackName,funcName) {\r
- _jmol.params[callbackName] = funcName\r
-}\r
-\r
- try {\r
-// note this is done FIRST, so it cannot override a setting done by the developer\r
- if (top.location.search.indexOf("PARAMS=")>=0) {\r
- var pars = unescape(top.location.search.split("PARAMS=")[1].split("&")[0]).split(";");\r
- for (var i = 0; i < pars.length; i++) {\r
- var p = pars[i].split(":");\r
- jmolSetParameter(p[0],p[1]);\r
- }\r
- }\r
- } catch(e) {\r
- // can't access top.location\r
- }\r
-\r
-function jmolSetSyncId(n) {\r
- return _jmol.params["syncId"] = n\r
-}\r
-\r
-function jmolGetSyncId() {\r
- return _jmol.params["syncId"]\r
-}\r
-\r
-function jmolSetLogLevel(n) {\r
- _jmol.params.logLevel = ''+n;\r
-}\r
-\r
- /* AngelH, mar2007:\r
- By (re)setting these variables in the webpage before calling jmolApplet(), \r
- a custom message can be provided (e.g. localized for user's language) when no Java is installed.\r
- */\r
-if (noJavaMsg==undefined) var noJavaMsg = \r
- "You do not have Java applets enabled in your web browser, or your browser is blocking this applet.<br />\n" +\r
- "Check the warning message from your browser and/or enable Java applets in<br />\n" +\r
- "your web browser preferences, or install the Java Runtime Environment from <a href='http://www.java.com'>www.java.com</a><br />";\r
-if (noJavaMsg2==undefined) var noJavaMsg2 = \r
- "You do not have the<br />\n" +\r
- "Java Runtime Environment<br />\n" +\r
- "installed for applet support.<br />\n" +\r
- "Visit <a href='http://www.java.com'>www.java.com</a>";\r
-function _jmolApplet(size, inlineModel, script, nameSuffix) {\r
- /* AngelH, mar2007\r
- Fixed percent / pixel business, to avoid browser errors:\r
- put "px" where needed, avoid where not.\r
-\r
- Bob Hanson, 1/2010\r
- Fixed inline escape changing returns to | \r
- */\r
- with (_jmol) {\r
- nameSuffix == undefined && (nameSuffix = appletCount);\r
- appletSuffixes.push(nameSuffix);\r
- ++appletCount;\r
- script || (script = "select *");\r
- var sz = _jmolGetAppletSize(size);\r
- var widthAndHeight = " width='" + sz[0] + "' height='" + sz[1] + "' ";\r
- var tHeader, tFooter;\r
- codebase || jmolInitialize(".");\r
- if (useIEObject || useHtml4Object) {\r
- params.archive = archivePath;\r
- params.mayscript = 'true';\r
- params.codebase = codebase;\r
- params.code = 'JmolApplet';\r
- tHeader = \r
- "<object name='jmolApplet" + nameSuffix +\r
- "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +\r
- widthAndHeight + "\n";\r
- tFooter = "</object>";\r
- }\r
- if (java_arguments)\r
- params.java_arguments = java_arguments;\r
- if (useIEObject) { // use MSFT IE6 object tag with .cab file reference\r
- tHeader += " classid='" + windowsClassId + "'\n" +\r
- (windowsCabUrl ? " codebase='" + windowsCabUrl + "'\n" : "") + ">\n";\r
- } else if (useHtml4Object) { // use HTML4 object tag\r
- tHeader += " type='application/x-java-applet'\n>\n";\r
- /* " classid='java:JmolApplet'\n" + AH removed this\r
- Chromium Issue 62076: Java Applets using an <object> with a classid paramater don't load.\r
- http://code.google.com/p/chromium/issues/detail?id=62076\r
- They say this is the correct behavior according to the spec, and there's no indication at this point \r
- that WebKit will be changing the handling, so eventually Safari will acquire this behavior too.\r
- Removing the classid parameter seems to be well tolerated by all browsers (even IE!).\r
- */\r
- } else { // use applet tag\r
- tHeader = \r
- "<applet name='jmolApplet" + nameSuffix +\r
- "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +\r
- widthAndHeight + "\n" +\r
- " code='JmolApplet'" +\r
- " archive='" + archivePath + "' codebase='" + codebase + "'\n" +\r
- " mayscript='true'>\n";\r
- tFooter = "</applet>";\r
- }\r
- var visitJava;\r
- if (useIEObject || useHtml4Object) {\r
- var szX = "width:" + sz[0]\r
- if ( szX.indexOf("%")==-1 ) szX+="px" \r
- var szY = "height:" + sz[1]\r
- if ( szY.indexOf("%")==-1 ) szY+="px" \r
- visitJava =\r
- "<p style='background-color:yellow; color:black; " +\r
- szX + ";" + szY + ";" +\r
- // why doesn't this vertical-align work?\r
- "text-align:center;vertical-align:middle;'>\n" +\r
- noJavaMsg +\r
- "</p>";\r
- } else {\r
- visitJava =\r
- "<table bgcolor='yellow'><tr>" +\r
- "<td align='center' valign='middle' " + widthAndHeight + "><font color='black'>\n" +\r
- noJavaMsg2 +\r
- "</font></td></tr></table>";\r
- }\r
- params.loadInline = (inlineModel ? inlineModel : "");\r
- params.script = (script ? _jmolSterilizeScript(script) : "");\r
- var t = tHeader + _jmolParams() + visitJava + tFooter;\r
- jmolSetTarget(nameSuffix);\r
- ready["jmolApplet" + nameSuffix] = false;\r
- if (_jmol.debugAlert)\r
- alert(t);\r
- return _jmolDocumentWrite(t);\r
- }\r
-}\r
-\r
-function _jmolParams() {\r
- var t = "";\r
- for (var i in _jmol.params)\r
- if(_jmol.params[i]!="")\r
- t+=" <param name='"+i+"' value='"+_jmol.params[i]+"' />\n";\r
- return t\r
-}\r
-\r
-function _jmolInitCheck() {\r
- if (_jmol.initChecked)\r
- return;\r
- _jmol.initChecked = true;\r
- jmolInitialize(defaultdir, defaultjar)\r
-}\r
-\r
-function _jmolCheckBrowser() {\r
- with (_jmol) {\r
- if (browserChecked)\r
- return;\r
- browserChecked = true;\r
- \r
- if (isFullyCompliant)\r
- return true;\r
-\r
- if (checkBrowserAction == "redirect")\r
- location.href = checkBrowserUrlOrMessage;\r
- else if (checkBrowserAction == "popup")\r
- _jmolPopup(checkBrowserUrlOrMessage);\r
- else {\r
- var msg = checkBrowserUrlOrMessage;\r
- if (msg == null)\r
- msg = "Your web browser is not fully compatible with Jmol\n\n" +\r
- "browser: " + browser +\r
- " version: " + browserVersion +\r
- " os: " + os +\r
- " isBrowserCompliant: " + isBrowserCompliant +\r
- " isJavaCompliant: " + isJavaCompliant +\r
- "\n\n" + ua;\r
- alert(msg);\r
- }\r
- }\r
- return false;\r
-}\r
-\r
-function jmolSetXHTML(id) {\r
- _jmol.isXHTML = true\r
- _jmol.XhtmlElement = null\r
- _jmol.XhtmlAppendChild = false\r
- if (id){\r
- _jmol.XhtmlElement = document.getElementById(id)\r
- _jmol.XhtmlAppendChild = true\r
- }\r
-}\r
-\r
-function _jmolDocumentWrite(text) {\r
- if (_jmol.currentDocument) {\r
- if (_jmol.isXHTML && !_jmol.XhtmlElement) {\r
- var s = document.getElementsByTagName("script")\r
- _jmol.XhtmlElement = s.item(s.length - 1)\r
- _jmol.XhtmlAppendChild = false\r
- }\r
- if (_jmol.XhtmlElement) {\r
- _jmolDomDocumentWrite(text)\r
- } else {\r
- _jmol.currentDocument.write(text);\r
- }\r
- }\r
- return text;\r
-}\r
-\r
-function _jmolDomDocumentWrite(data) {\r
- var pt = 0\r
- var Ptr = []\r
- Ptr[0] = 0\r
- while (Ptr[0] < data.length) {\r
- var child = _jmolGetDomElement(data, Ptr)\r
- if (!child)break\r
- if (_jmol.XhtmlAppendChild)\r
- _jmol.XhtmlElement.appendChild(child)\r
- else\r
- _jmol.XhtmlElement.parentNode.insertBefore(child, _jmol.XhtmlElement); \r
- }\r
-}\r
-function _jmolGetDomElement(data, Ptr, closetag, lvel) {\r
- var e = document.createElement("span")\r
- e.innerHTML = data\r
- Ptr[0] = data.length\r
- return e\r
-\r
-//unnecessary?\r
-\r
- closetag || (closetag = "")\r
- lvel || (lvel = 0)\r
- var pt0 = Ptr[0]\r
- var pt = pt0\r
- while (pt < data.length && data.charAt(pt) != "<") pt++\r
- if (pt != pt0) {\r
- var text = data.substring(pt0, pt)\r
- Ptr[0] = pt\r
- return document.createTextNode(text)\r
- } \r
- pt0 = ++pt\r
- var ch\r
- while (pt < data.length && "\n\r\t >".indexOf(ch = data.charAt(pt)) < 0) pt++\r
- var tagname = data.substring(pt0, pt)\r
- var e = (tagname == closetag || tagname == "/" ? "" \r
- : document.createElementNS ? document.createElementNS('http://www.w3.org/1999/xhtml', tagname)\r
- : document.createElement(tagname));\r
- if (ch == ">") {\r
- Ptr[0] = ++pt\r
- return e\r
- }\r
- while (pt < data.length && (ch = data.charAt(pt)) != ">") {\r
- while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++\r
- pt0 = pt\r
- while (pt < data.length && "\n\r\t =/>".indexOf(ch = data.charAt(pt)) < 0) pt++\r
- var attrname = data.substring(pt0, pt).toLowerCase()\r
- if (attrname && ch != "=") \r
- e.setAttribute(attrname, "true")\r
- while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++\r
- if (ch == "/") {\r
- Ptr[0] = pt + 2\r
- return e\r
- } else if (ch == "=") {\r
- var quote = data.charAt(++pt)\r
- pt0 = ++pt\r
- while (pt < data.length && (ch = data.charAt(pt)) != quote) pt++\r
- var attrvalue = data.substring(pt0, pt)\r
- e.setAttribute(attrname, attrvalue)\r
- pt++\r
- }\r
- }\r
- Ptr[0] = ++pt\r
- while (Ptr[0] < data.length) {\r
- var child = _jmolGetDomElement(data, Ptr, "/" + tagname, lvel+1)\r
- if (!child)break\r
- e.appendChild(child)\r
- }\r
- return e\r
-}\r
-\r
-function _jmolPopup(url) {\r
- var popup = window.open(url, "JmolPopup",\r
- "left=150,top=150,height=400,width=600," +\r
- "directories=yes,location=yes,menubar=yes," +\r
- "toolbar=yes," +\r
- "resizable=yes,scrollbars=yes,status=yes");\r
- if (popup.focus)\r
- poup.focus();\r
-}\r
-\r
-function _jmolReadyCallback(name) {\r
- if (_jmol.debugAlert)\r
- alert(name + " is ready");\r
- _jmol.ready["" + name] = true;\r
-}\r
-\r
-function _jmolSterilizeScript(script) {\r
- script = script.replace(/'/g, "'");\r
- if (_jmol.debugAlert)\r
- alert("script:\n" + script);\r
- return script;\r
-}\r
-\r
-function _jmolSterilizeInline(model) {\r
- model = model.replace(/\r|\n|\r\n/g, (model.indexOf("|") >= 0 ? "\\/n" : "|")).replace(/'/g, "'");\r
- if (_jmol.debugAlert)\r
- alert("inline model:\n" + model);\r
- return model;\r
-}\r
-\r
-function _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {\r
- ++_jmol.radioCount;\r
- groupName != undefined && groupName != null || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));\r
- if (!script)\r
- return "";\r
- labelHtml != undefined && labelHtml != null || (labelHtml = script.substring(0, 32));\r
- separatorHtml || (separatorHtml = "")\r
- var scriptIndex = _jmolAddScript(script);\r
- var eospan = "</span>"\r
- var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='" \r
- + groupName + "' id='"+id+"' type='radio' onclick='_jmolClick(this," +\r
- scriptIndex + _jmol.targetText + ");return true;' onmouseover='_jmolMouseOver(" +\r
- scriptIndex + ");return true;' onmouseout='_jmolMouseOut()' " +\r
- (isChecked ? "checked='true' " : "") + _jmol.radioCssText + " />"\r
- if (labelHtml.toLowerCase().indexOf("<td>")>=0) {\r
- t += eospan\r
- eospan = "";\r
- }\r
- t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan + separatorHtml;\r
-\r
- return t;\r
-}\r
-\r
-function _jmolFindApplet(target) {\r
- // first look for the target in the current window\r
- var applet = _jmolFindAppletInWindow(_jmol.appletWindow != null ? _jmol.appletWindow : window, target);\r
- // THEN look for the target in child frames\r
- if (applet == undefined)\r
- applet = _jmolSearchFrames(window, target);\r
- // FINALLY look for the target in sibling frames\r
- if (applet == undefined)\r
- applet = _jmolSearchFrames(top, target); // look starting in top frame\r
- return applet;\r
-}\r
-\r
-function _jmolGetApplet(targetSuffix){\r
- var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");\r
- var applet = _jmolFindApplet(target);\r
- if (applet) return applet\r
- _jmol.alerted || alert("could not find applet " + target);\r
- _jmol.alerted = true;\r
- return null\r
-}\r
-\r
-function _jmolSearchFrames(win, target) {\r
- var applet;\r
- var frames = win.frames;\r
- if (frames && frames.length) { // look in all the frames below this window\r
- try{\r
- for (var i = 0; i < frames.length; ++i) {\r
- applet = _jmolSearchFrames(frames[i], target);\r
- if (applet)\r
- return applet;\r
- }\r
- }catch(e) {\r
- if (_jmol.debugAlert)\r
- alert("Jmol.js _jmolSearchFrames cannot access " + win.name + ".frame[" + i + "] consider using jmolSetAppletWindow()") \r
- }\r
- }\r
- return applet = _jmolFindAppletInWindow(win, target)\r
-}\r
-\r
-function _jmolFindAppletInWindow(win, target) {\r
- var doc = win.document;\r
- if (doc.getElementById(target))\r
- return doc.getElementById(target);\r
- else if (doc.applets)\r
- return doc.applets[target];\r
- else\r
- return doc[target]; \r
-}\r
-\r
-function _jmolAddScript(script) {\r
- if (!script)\r
- return 0;\r
- var index = _jmol.scripts.length;\r
- _jmol.scripts[index] = script;\r
- return index;\r
-}\r
-\r
-function _jmolClick(elementClicked, scriptIndex, targetSuffix) {\r
- _jmol.element = elementClicked;\r
- _jmolScriptExecute(elementClicked, _jmol.scripts[scriptIndex], targetSuffix);\r
-}\r
-\r
-function _jmolMenuSelected(menuObject, targetSuffix) {\r
- var scriptIndex = menuObject.value;\r
- if (scriptIndex != undefined) {\r
- _jmolScriptExecute(menuObject, _jmol.scripts[scriptIndex], targetSuffix);\r
- return;\r
- }\r
- var len = menuObject.length;\r
- if (typeof len == "number") {\r
- for (var i = 0; i < len; ++i) {\r
- if (menuObject[i].selected) {\r
- _jmolClick(menuObject[i], menuObject[i].value, targetSuffix);\r
- return;\r
- }\r
- }\r
- }\r
- alert("?Que? menu selected bug #8734");\r
-}\r
-\r
-\r
-_jmol.checkboxMasters = {};\r
-_jmol.checkboxItems = {};\r
-\r
-function jmolSetCheckboxGroup(chkMaster,chkBox) {\r
- var id = chkMaster;\r
- if(typeof(id)=="number")id = "jmolCheckbox" + id;\r
- chkMaster = document.getElementById(id);\r
- if (!chkMaster)alert("jmolSetCheckboxGroup: master checkbox not found: " + id);\r
- var m = _jmol.checkboxMasters[id] = {};\r
- m.chkMaster = chkMaster;\r
- m.chkGroup = {};\r
- for (var i = 1; i < arguments.length; i++){\r
- var id = arguments[i];\r
- if(typeof(id)=="number")id = "jmolCheckbox" + id;\r
- checkboxItem = document.getElementById(id);\r
- if (!checkboxItem)alert("jmolSetCheckboxGroup: group checkbox not found: " + id);\r
- m.chkGroup[id] = checkboxItem;\r
- _jmol.checkboxItems[id] = m;\r
- }\r
-}\r
-\r
-function _jmolNotifyMaster(m){\r
- //called when a group item is checked\r
- var allOn = true;\r
- var allOff = true;\r
- for (var chkBox in m.chkGroup){\r
- if(m.chkGroup[chkBox].checked)\r
- allOff = false;\r
- else\r
- allOn = false;\r
- }\r
- if (allOn)m.chkMaster.checked = true; \r
- if (allOff)m.chkMaster.checked = false;\r
- if ((allOn || allOff) && _jmol.checkboxItems[m.chkMaster.id])\r
- _jmolNotifyMaster(_jmol.checkboxItems[m.chkMaster.id])\r
-}\r
-\r
-function _jmolNotifyGroup(m, isOn){\r
- //called when a master item is checked\r
- for (var chkBox in m.chkGroup){\r
- var item = m.chkGroup[chkBox]\r
- item.checked = isOn;\r
- if (_jmol.checkboxMasters[item.id])\r
- _jmolNotifyGroup(_jmol.checkboxMasters[item.id], isOn)\r
- }\r
-}\r
-\r
-function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) {\r
- _jmol.control = ckbox\r
- _jmolClick(ckbox, ckbox.checked ? whenChecked : whenUnchecked, targetSuffix);\r
- if(_jmol.checkboxMasters[ckbox.id])\r
- _jmolNotifyGroup(_jmol.checkboxMasters[ckbox.id], ckbox.checked)\r
- if(_jmol.checkboxItems[ckbox.id])\r
- _jmolNotifyMaster(_jmol.checkboxItems[ckbox.id])\r
-}\r
-\r
-function _jmolCbOver(ckbox, whenChecked, whenUnchecked) {\r
- window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked];\r
-}\r
-\r
-function _jmolMouseOver(scriptIndex) {\r
- window.status = _jmol.scripts[scriptIndex];\r
-}\r
-\r
-function _jmolMouseOut() {\r
- window.status = " ";\r
- return true;\r
-}\r
-\r
-function _jmolSetCodebase(codebase) {\r
- _jmol.codebase = codebase ? codebase : ".";\r
- if (_jmol.debugAlert)\r
- alert("jmolCodebase=" + _jmol.codebase);\r
-}\r
-\r
-function _jmolOnloadResetForms() {\r
- // must be evaluated ONLY once\r
- _jmol.previousOnloadHandler = window.onload;\r
- window.onload =\r
- function() {\r
- with (_jmol) {\r
- if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) {\r
- var forms = document.forms;\r
- for (var i = forms.length; --i >= 0; )\r
- forms[i].reset();\r
- }\r
- if (previousOnloadHandler)\r
- previousOnloadHandler();\r
- }\r
- }\r
-}\r
-\r
-////////////////////////////////////\r
-/////extensions for getProperty/////\r
-////////////////////////////////////\r
-\r
-\r
-function _jmolEvalJSON(s,key){\r
- s=s+""\r
- if(!s)return []\r
- if(s.charAt(0)!="{"){\r
- if(s.indexOf(" | ")>=0)s=s.replace(/\ \|\ /g, "\n")\r
- return s\r
- }\r
- var A = eval("("+s+")")\r
- if(!A)return\r
- if(key && A[key])A=A[key]\r
- return A\r
-}\r
-\r
-function _jmolEnumerateObject(A,key){\r
- var sout=""\r
- if(typeof(A) == "string" && A!="null"){\r
- sout+="\n"+key+"=\""+A+"\""\r
- }else if(!isNaN(A)||A==null){\r
- sout+="\n"+key+"="+(A+""==""?"null":A)\r
- }else if(A.length){\r
- sout+=key+"=[]"\r
- for(var i=0;i<A.length;i++){\r
- sout+="\n"\r
- if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){\r
- sout+=_jmolEnumerateObject(A[i],key+"["+i+"]")\r
- }else{\r
- sout+=key+"["+i+"]="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])\r
- }\r
- }\r
- }else{\r
- if(key != ""){\r
- sout+=key+"={}"\r
- key+="."\r
- }\r
- \r
- for(var i in A){\r
- sout+="\n"\r
- if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){\r
- sout+=_jmolEnumerateObject(A[i],key+i)\r
- }else{\r
- sout+=key+i+"="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])\r
- }\r
- }\r
- } \r
- return sout\r
-}\r
-\r
-\r
-function _jmolSortKey0(a,b){\r
- return (a[0]<b[0]?1:a[0]>b[0]?-1:0)\r
-}\r
-\r
-function _jmolSortMessages(A){\r
- if(!A || typeof(A)!="object")return []\r
- var B = []\r
- for(var i=A.length-1;i>=0;i--)for(var j=0;j<A[i].length;j++)B[B.length]=A[i][j]\r
- if(B.length == 0) return\r
- B=B.sort(_jmolSortKey0)\r
- return B\r
-}\r
-\r
-/////////additional extensions //////////\r
-\r
-\r
-function _jmolDomScriptLoad(URL){\r
- //open(URL) //to debug\r
- _jmol.servercall=URL\r
- var node = document.getElementById("_jmolScriptNode")\r
- if (node && _jmol.browser!="msie"){\r
- document.getElementsByTagName("HEAD")[0].removeChild(node)\r
- node=null\r
- }\r
- if (node) {\r
- node.setAttribute("src",URL)\r
- } else {\r
- node=document.createElement("script")\r
- node.setAttribute("id","_jmolScriptNode")\r
- node.setAttribute("type","text/javascript")\r
- node.setAttribute("src",URL)\r
- document.getElementsByTagName("HEAD")[0].appendChild(node)\r
- }\r
-}\r
-\r
-\r
-function _jmolExtractPostData(url){\r
- S=url.split("&POST:")\r
- var s=""\r
- for(var i=1;i<S.length;i++){\r
- KV=S[i].split("=")\r
- s+="&POSTKEY"+i+"="+KV[0]\r
- s+="&POSTVALUE"+i+"="+KV[1]\r
- }\r
- return "&url="+escape(S[0])+s\r
-}\r
-\r
-function _jmolLoadModel(targetSuffix,remoteURL,array,isError,errorMessage){\r
- //called by server, but in client\r
- //overload this function to customize return\r
- _jmol.remoteURL=remoteURL\r
- isError && alert(errorMessage)\r
- jmolLoadInlineScript(array.join("\n"),_jmol.optionalscript,targetSuffix)\r
-}\r
-\r
-//////////user property/status functions/////////\r
-\r
-function jmolGetStatus(strStatus,targetSuffix){\r
- return _jmolSortMessages(jmolGetPropertyAsArray("jmolStatus",strStatus,targetSuffix))\r
-}\r
-\r
-function jmolGetPropertyAsArray(sKey,sValue,targetSuffix) {\r
- return _jmolEvalJSON(jmolGetPropertyAsJSON(sKey,sValue,targetSuffix),sKey)\r
-}\r
-\r
-function jmolGetPropertyAsString(sKey,sValue,targetSuffix) {\r
- var applet = _jmolGetApplet(targetSuffix);\r
- sValue == undefined && (sValue="");\r
- return (applet ? applet.getPropertyAsString(sKey,sValue) + "" : "")\r
-}\r
-\r
-function jmolGetPropertyAsJSON(sKey,sValue,targetSuffix) {\r
- sValue == undefined && (sValue = "")\r
- var applet = _jmolGetApplet(targetSuffix);\r
- try {\r
- return (applet ? applet.getPropertyAsJSON(sKey,sValue) + "" : "")\r
- } catch(e) {\r
- return ""\r
- }\r
-}\r
-\r
-function jmolGetPropertyAsJavaObject(sKey,sValue,targetSuffix) {\r
- sValue == undefined && (sValue = "")\r
- var applet = _jmolGetApplet(targetSuffix);\r
- return (applet ? applet.getProperty(sKey,sValue) : null)\r
-}\r
-\r
-\r
-function jmolDecodeJSON(s) {\r
- return _jmolEnumerateObject(_jmolEvalJSON(s),"")\r
-}\r
-\r
-\r
-///////// synchronous scripting ////////\r
-\r
-function jmolScriptWait(script, targetSuffix) {\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var Ret=jmolScriptWaitAsArray(script, targetSuffix)\r
- var s = ""\r
- for(var i=Ret.length;--i>=0;)\r
- for(var j=0;j< Ret[i].length;j++)\r
- s+=Ret[i][j]+"\n"\r
- return s\r
-}\r
-\r
-function jmolScriptWaitOutput(script, targetSuffix) {\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var ret = ""\r
- try{\r
- if (script) {\r
- _jmolCheckBrowser();\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (applet) ret += applet.scriptWaitOutput(script);\r
- }\r
- }catch(e){\r
- }\r
- return ret;\r
-}\r
-\r
-function jmolEvaluate(molecularMath, targetSuffix) {\r
-\r
- //carries out molecular math on a model\r
-\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var result = "" + jmolGetPropertyAsJavaObject("evaluate", molecularMath, targetSuffix);\r
- var s = result.replace(/\-*\d+/,"")\r
- if (s == "" && !isNaN(parseInt(result)))return parseInt(result);\r
- var s = result.replace(/\-*\d*\.\d*/,"")\r
- if (s == "" && !isNaN(parseFloat(result)))return parseFloat(result);\r
- return result;\r
-}\r
-\r
-function jmolScriptEcho(script, targetSuffix) {\r
- // returns a newline-separated list of all echos from a script\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var Ret=jmolScriptWaitAsArray(script, targetSuffix)\r
- var s = ""\r
- for(var i=Ret.length;--i>=0;)\r
- for(var j=Ret[i].length;--j>=0;)\r
- if (Ret[i][j][1] == "scriptEcho")s+=Ret[i][j][3]+"\n"\r
- return s.replace(/ \| /g, "\n")\r
-}\r
-\r
-\r
-function jmolScriptMessage(script, targetSuffix) {\r
- // returns a newline-separated list of all messages from a script, ending with "script completed\n"\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var Ret=jmolScriptWaitAsArray(script, targetSuffix)\r
- var s = ""\r
- for(var i=Ret.length;--i>=0;)\r
- for(var j=Ret[i].length;--j>=0;)\r
- if (Ret[i][j][1] == "scriptStatus")s+=Ret[i][j][3]+"\n"\r
- return s.replace(/ \| /g, "\n")\r
-}\r
-\r
-\r
-function jmolScriptWaitAsArray(script, targetSuffix) {\r
- var ret = ""\r
- try{\r
- jmolGetStatus("scriptEcho,scriptMessage,scriptStatus,scriptError",targetSuffix)\r
- if (script) {\r
- _jmolCheckBrowser();\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (applet) ret += applet.scriptWait(script);\r
- ret = _jmolEvalJSON(ret,"jmolStatus")\r
- if(typeof ret == "object")\r
- return ret\r
- }\r
- }catch(e){\r
- }\r
- return [[ret]]\r
-}\r
-\r
-\r
-\r
-//////////// save/restore orientation /////////////\r
-\r
-function jmolSaveOrientation(id, targetSuffix) { \r
- targetSuffix == undefined && (targetSuffix="0")\r
- return _jmol["savedOrientation"+id] = jmolGetPropertyAsArray("orientationInfo","info",targetSuffix).moveTo\r
-}\r
-\r
-function jmolRestoreOrientation(id, targetSuffix) {\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var s=_jmol["savedOrientation"+id]\r
- if (!s || s == "")return\r
- s=s.replace(/1\.0/,"0")\r
- return jmolScriptWait(s,targetSuffix)\r
-}\r
-\r
-function jmolRestoreOrientationDelayed(id, delay, targetSuffix) {\r
- arguments.length < 2 && (delay=1)\r
- targetSuffix == undefined && (targetSuffix="0")\r
- var s=_jmol["savedOrientation"+id]\r
- if (!s || s == "")return\r
- s=s.replace(/1\.0/,delay)\r
- return jmolScriptWait(s,targetSuffix)\r
-}\r
-\r
-//////////// add parameter /////////////\r
-/*\r
- * for adding callbacks or other parameters. Use:\r
-\r
- jmolSetDocument(0)\r
- var s= jmolApplet(....)\r
- s = jmolAppletAddParam(s,"messageCallback", "myFunctionName")\r
- document.write(s)\r
- jmolSetDocument(document) // if you want to then write buttons and such normally\r
- \r
- */\r
-\r
-function jmolAppletAddParam(appletCode,name,value){\r
- return (value == "" ? appletCode : appletCode.replace(/\<param/,"\n<param name='"+name+"' value='"+value+"' />\n<param"))\r
-}\r
-\r
-///////////////auto load Research Consortium for Structural Biology (RCSB) data ///////////\r
-\r
-function jmolLoadAjax_STOLAF_RCSB(fileformat,pdbid,optionalscript,targetSuffix){\r
-\r
- _jmol.thismodel || (_jmol.thismodel = "1crn")\r
- _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")\r
- _jmol.RCSBserver || (_jmol.RCSBserver="http://www.rcsb.org")\r
- _jmol.defaultURL_RCSB || (_jmol.defaultURL_RCSB=_jmol.RCSBserver+"/pdb/files/1CRN.CIF")\r
- fileformat || (fileformat="PDB")\r
- pdbid || (pdbid=prompt("Enter a 4-digit PDB ID:",_jmol.thismodel))\r
- if(!pdbid || pdbid.length != 4)return ""\r
- targetSuffix || (targetSuffix="0")\r
- optionalscript || (optionalscript="")\r
- var url=_jmol.defaultURL_RCSB.replace(/1CRN/g,pdbid.toUpperCase())\r
- fileformat=="CIF" || (url=url.replace(/CIF/,fileformat))\r
- _jmol.optionalscript=optionalscript\r
- _jmol.thismodel=pdbid\r
- _jmol.thistargetsuffix=targetSuffix\r
- _jmol.thisurl=url\r
- _jmol.modelArray = []\r
- url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)\r
- _jmolDomScriptLoad(url)\r
- return url\r
-}\r
-\r
-\r
-///////////////auto load NIH CACTVS data -- compound name or SMILES ///////////\r
-\r
-function jmolLoadAjax_STOLAF_NIH(compoundid,optionalscript,targetSuffix){\r
- _jmol.thismodel || (_jmol.thismodel = "aspirin")\r
- _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")\r
- _jmol.defaultURL_NIH || (_jmol.defaultURL_NIH="http://cactus.nci.nih.gov/chemical/structure/FILE/file?format=sdf&get3d=True")\r
- compoundid || (compoundid=prompt("Enter a compound name or a SMILES string:",_jmol.thismodel))\r
- if(!compoundid)return ""\r
- targetSuffix || (targetSuffix="0")\r
- optionalscript || (optionalscript="")\r
- var url=_jmol.defaultURL_NIH.replace(/FILE/g,compoundid)\r
- _jmol.optionalscript=optionalscript\r
- _jmol.thismodel=compoundid\r
- _jmol.thistargetsuffix=targetSuffix\r
- _jmol.thisurl=url\r
- _jmol.modelArray = []\r
- url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)\r
- _jmolDomScriptLoad(url)\r
- return url\r
-}\r
-\r
-\r
-/////////////// St. Olaf College AJAX server -- ANY URL ///////////\r
-\r
-function jmolLoadAjax_STOLAF_ANY(url, userid, optionalscript,targetSuffix){\r
- _jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm"\r
- _jmol.thisurlANY || (_jmol.thisurlANY = "http://www.stolaf.edu/depts/chemistry/mo/struc/data/ycp3-1.mol")\r
- url || (url=prompt("Enter any (uncompressed file) URL:", _jmol.thisurlANY))\r
- userid || (userid="0")\r
- targetSuffix || (targetSuffix="0")\r
- optionalscript || (optionalscript="")\r
- _jmol.optionalscript=optionalscript\r
- _jmol.thistargetsuffix=targetSuffix\r
- _jmol.modelArray = []\r
- _jmol.thisurl = url\r
- url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)\r
- _jmolDomScriptLoad(url)\r
-}\r
-\r
-\r
-/////////////// Mineralogical Society of America (MSA) data /////////\r
-\r
-function jmolLoadAjax_MSA(key,value,optionalscript,targetSuffix){\r
-\r
- _jmol.thiskeyMSA || (_jmol.thiskeyMSA = "mineral")\r
- _jmol.thismodelMSA || (_jmol.thismodelMSA = "quartz")\r
- _jmol.ajaxURL_MSA || (_jmol.ajaxURL_MSA="http://rruff.geo.arizona.edu/AMS/result.php?mineral=quartz&viewing=ajaxjs")\r
- key || (key=prompt("Enter a field:", _jmol.thiskeyMSA))\r
- if(!key)return ""\r
- value || (value=prompt("Enter a "+key+":", _jmol.thismodelMSA))\r
- if(!value)return ""\r
- targetSuffix || (targetSuffix="0")\r
- optionalscript || (optionalscript="")\r
- optionalscript == 1 && (optionalscript='load "" {1 1 1}')\r
- var url=_jmol.ajaxURL_MSA.replace(/mineral/g,key).replace(/quartz/g,value)\r
- _jmol.optionalscript=optionalscript\r
- _jmol.thiskeyMSA=key\r
- _jmol.thismodelMSA=value\r
- _jmol.thistargetsuffix=targetSuffix\r
- _jmol.thisurl=url\r
- _jmol.modelArray = []\r
- loadModel=_jmolLoadModel\r
- _jmolDomScriptLoad(url)\r
- return url\r
-}\r
-\r
-\r
-\r
-function jmolLoadAjaxJS(url, userid, optionalscript,targetSuffix){\r
- userid || (userid="0")\r
- targetSuffix || (targetSuffix="0")\r
- optionalscript || (optionalscript="")\r
- _jmol.optionalscript=optionalscript\r
- _jmol.thismodel=userid\r
- _jmol.thistargetsuffix=targetSuffix\r
- _jmol.modelArray = []\r
- _jmol.thisurl = url\r
- url+="&returnFunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix\r
- _jmolDomScriptLoad(url)\r
-}\r
-\r
-\r
-//// in case Jmol library has already been loaded:\r
-\r
-}catch(e){}\r
-\r
-///////////////moving atoms //////////////\r
-\r
-// HIGHLY experimental!!\r
-\r
-function jmolSetAtomCoord(i,x,y,z,targetSuffix){\r
- _jmolCheckBrowser();\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (applet) applet.getProperty('jmolViewer').setAtomCoord(i,x,y,z)\r
-}\r
-\r
-function jmolSetAtomCoordRelative(i,x,y,z,targetSuffix){\r
- _jmolCheckBrowser();\r
- var applet=_jmolGetApplet(targetSuffix);\r
- if (applet) applet.getProperty('jmolViewer').setAtomCoordRelative(i,x,y,z)\r
-}\r
-\r
-\r
-///////////////applet fake for testing buttons/////////////\r
-\r
-\r
-if(_jmol.useNoApplet){\r
- jmolApplet = function(w){\r
- var s="<table style='background-color:black' width="+w+"><tr height="+w+">"\r
- +"<td align=center valign=center style='background-color:white'>"\r
- +"Applet would be here"\r
- +"<p><textarea id=fakeApplet rows=5 cols=50></textarea>"\r
- +"</td></tr></table>"\r
- return _jmolDocumentWrite(s)\r
- }\r
-\r
- _jmolFindApplet = function(){return jmolApplet0}\r
-\r
- jmolApplet0 = {\r
- script: function(script){document.getElementById("fakeApplet").value="\njmolScript:\n"+script}\r
- ,scriptWait: function(script){document.getElementById("fakeApplet").value="\njmolScriptWait:\n"+script} \r
- ,loadInline: function(data,script){document.getElementById("fakeApplet").value="\njmolLoadInline data:\n"+data+"\n\nscript:\n"+script}\r
- }\r
-}\r
-\r
-\r
-///////////////////////////////////////////\r
-\r
- // This should no longer be needed, jmolResizeApplet() is better; kept for backwards compatibility\r
- /*\r
- Resizes absolutely (pixels) or by percent of window (w or h 0.5 means 50%).\r
- targetSuffix is optional and defaults to zero (first applet in page).\r
- Both w and h are optional, but needed if you want to use targetSuffix.\r
- h defaults to w\r
- w defaults to 100% of window\r
- If either w or h is between 0 and 1, then it is taken as percent/100.\r
- If either w or h is greater than 1, then it is taken as a size (pixels). \r
- */\r
-function jmolResize(w,h,targetSuffix) {\r
- _jmol.alerted = true;\r
- var percentW = (!w ? 100 : w <= 1 && w > 0 ? w * 100 : 0);\r
- var percentH = (!h ? percentW : h <= 1 && h > 0 ? h * 100 : 0);\r
- if (_jmol.browser=="msie") {\r
- var width=document.body.clientWidth;\r
- var height=document.body.clientHeight;\r
- } else {\r
- var netscapeScrollWidth=15;\r
- var width=window.innerWidth - netscapeScrollWidth;\r
- var height=window.innerHeight-netscapeScrollWidth;\r
- }\r
- var applet = _jmolGetApplet(targetSuffix);\r
- if(!applet)return;\r
- applet.style.width = (percentW ? width * percentW/100 : w)+"px";\r
- applet.style.height = (percentH ? height * percentH/100 : (h ? h : w))+"px";\r
- //title=width + " " + height + " " + (new Date());\r
-}\r
-\r
-// 13 Jun 09 -- makes jmolResize() obsolete (kept for backwards compatibility)\r
-function jmolResizeApplet(size,targetSuffix) {\r
- // See _jmolGetAppletSize() for the formats accepted as size [same used by jmolApplet()]\r
- // Special case: an empty value for width or height is accepted, meaning no change in that dimension.\r
- _jmol.alerted = true;\r
- var applet = _jmolGetApplet(targetSuffix);\r
- if(!applet)return;\r
- var sz = _jmolGetAppletSize(size, "px");\r
- sz[0] && (applet.style.width = sz[0]);\r
- sz[1] && (applet.style.height = sz[1]);\r
-}\r
-\r
-function _jmolGetAppletSize(size, units) {\r
- /* Accepts single number or 2-value array, each one can be one of:\r
- percent (text string ending %), decimal 0 to 1 (percent/100), number, or text string (interpreted as nr.)\r
- [width, height] array of strings is returned, with units added if specified.\r
- Percent is relative to container div or element (which should have explicitly set size).\r
- */\r
- var width, height;\r
- if ( (typeof size) == "object" && size != null ) {\r
- width = size[0]; height = size[1];\r
- } else {\r
- width = height = size;\r
- }\r
- return [_jmolFixDim(width, units), _jmolFixDim(height, units)];\r
-}\r
-\r
-function _jmolFixDim(x, units) {\r
- var sx = "" + x;\r
- return (sx.length == 0 ? (units ? "" : _jmol.allowedJmolSize[2])\r
- : sx.indexOf("%") == sx.length-1 ? sx \r
- : (x = parseFloat(x)) <= 1 && x > 0 ? x * 100 + "%"\r
- : (isNaN(x = Math.floor(x)) ? _jmol.allowedJmolSize[2]\r
- : x < _jmol.allowedJmolSize[0] ? _jmol.allowedJmolSize[0]\r
- : x > _jmol.allowedJmolSize[1] ? _jmol.allowedJmolSize[1] \r
- : x) + (units ? units : ""));\r
-}\r
-\r
-\r
-\r
-\r
+/* Jmol 12.0 script library Jmol.js 9:48 PM 1/31/2011 Bob Hanson
+
+ checkbox heirarchy -- see http://chemapps.stolaf.edu/jmol/docs/examples-11/check.htm
+
+ based on:
+ *
+ * Copyright (C) 2004-2005 Miguel, Jmol Development, www.jmol.org
+ *
+ * Contact: hansonr@stolaf.edu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ */
+
+// for documentation see www.jmol.org/jslibrary
+
+try{if(typeof(_jmol)!="undefined")exit()
+
+// place "?NOAPPLET" on your command line to check applet control action with a textarea
+// place "?JMOLJAR=xxxxx" to use a specific jar file
+
+// bob hanson -- jmolResize(w,h) -- resizes absolutely or by percent (w or h 0.5 means 50%)
+// angel herraez -- update of jmolResize(w,h,targetSuffix) so it is not tied to first applet
+// bob hanson -- jmolEvaluate -- evaluates molecular math 8:37 AM 2/23/2007
+// bob hanson -- jmolScriptMessage -- returns all "scriptStatus" messages 8:37 AM 2/23/2007
+// bob hanson -- jmolScriptEcho -- returns all "scriptEcho" messages 8:37 AM 2/23/2007
+// bob hanson -- jmolScriptWait -- 11:31 AM 5/2/2006
+// bob hanson -- remove trailing separatorHTML in radio groups -- 12:18 PM 5/6/2006
+// bob hanson -- adds support for dynamic DOM script nodes 7:04 AM 5/19/2006
+// bob hanson -- adds try/catch for wiki - multiple code passes 7:05 AM 5/19/2006
+// bob hanson -- auto-initiates to defaultdir/defaultjar -- change as desired.
+// bob hanson -- adding save/restore orientation w/ and w/o delay 11:49 AM 5/25/2006
+// bob hanson -- adding AjaxJS service 11:16 AM 6/3/2006
+// bob hanson -- fix for iframes not available for finding applet
+// bob hanson -- added applet fake ?NOAPPLET URL flag
+// bob hanson -- added jmolSetCallback(calbackName, funcName) 3:32 PM 6/13/2006
+// used PRIOR to jmolApplet() or jmolAppletInline()
+// added 4th array element in jmolRadioGroup -- title
+// added <span> and id around link, checkbox, radio, menu
+// fixing AJAX loads for MSIE/Opera-Mozilla incompatibility
+// -- renamed Jmol-11.js from Jmol-new.js; JmolApplet.jar from JmolAppletProto.jar
+// renamed Jmol.js for Jmol 11 distribution
+// -- modified jmolRestoreOrientation() to be immediate, no 1-second delay
+// bob hanson -- jmolScriptWait always returns a string -- 11:23 AM 9/16/2006
+// bh -- jmolCommandInput()
+// bh -- jmolSetTranslation(TF) -- forces translation even if there might be message callback issues
+// bh -- minor fixes suggested by Angel
+// bh -- adds jmolSetSyncId() and jmolGetSyncId()
+// bh 3/2008 -- adds jmolAppendInlineScript() and jmolAppendInlineArray()
+// bh 3/2008 -- fixes IE7 bug in relation to jmolLoadInlineArray()
+// bh 6/2008 -- adds jmolSetAppletWindow()
+// Angel H. 6/2008 -- added html <label> tags to checkboxes and radio buttons [in jmolCheckbox() and _jmolRadio() functions]
+// bh 7/2008 -- code fix "for(i..." not "for(var i..."
+// bh 12/2008 -- jmolLoadInline, jmolLoadInlineArray, jmolLoadInlineScript, jmolAppendInlineScript, jmolAppendInlineArray all return error message or null (Jmol 11.7.16)
+// bh 12/2008 -- jmolScriptWaitOutput() -- waits for script to complete and delivers output normally sent to console
+
+// bh 5/2009 -- Support for XHTML using jmolSetXHTML(id)
+// ah & bh 6/2009 -- New jmolResizeApplet() more flexible, similar to jmolApplet() size syntax
+// bh 11/2009 -- care in accessing top.document
+// bh 12/2009 -- added jmolSetParameter(name, value)
+// bh 12/2009 -- added PARAMS=name:value;name:value;name:value... for command line
+// bh 12/2009 -- overhaul of target checking
+// bh 1/2010 -- all _xxxx() methods ALWAYS have complete argument list
+// bh 1/2010 -- adds option to run a JavaScript function from any Jmol control.
+// This is accomplished by passing an array rather than a script:
+// jmolHref([myfunc,"my param 1", "my param 2"], "testing")
+// function myfunc(jmolControlObject, [myfunc,"my param 1", "my param 2"], target){...}
+// and allows much more flexibility with responding to controls
+// bh 4/2010 -- added jmolSetMemoryMb(nMb)
+// ah 1/2011 -- wider detection of browsers; more browsers now use the object tag instead of the applet tag;
+// fix of object tag (removed classid) accounts for change of behavior in Chrome
+// bh 3/2011 -- added jmolLoadAjax_STOLAF_NIH
+
+var defaultdir = "."
+var defaultjar = "JmolApplet.jar"
+
+
+// Note added 12:41 PM 9/21/2008 by Bob Hanson, hansonr@stolaf.edu:
+
+// JMOLJAR=xxxxx.jar on the URL for this page will override
+// the JAR file specified in the jmolInitialize() call.
+
+// The idea is that it can be very useful to test a web page with different JAR files
+// Or for an expert user to substitute a signed applet for an unsigned one
+// so as to use a broader range of models or to create JPEG files, for example.
+
+// If the JAR file is not in the current directory (has any sort of "/" in its name)
+// then the user is presented with a warning and asked whether it is OK to change Jar files.
+// The default action, if the user just presses "OK" is to NOT allow the change.
+// The user must type the word "yes" in the prompt box for the change to be approved.
+
+// If you don't want people to be able to switch in their own JAR file on your page,
+// simply set this next line to read "var allowJMOLJAR = false".
+
+
+var undefined; // for IE 5 ... wherein undefined is undefined
+
+////////////////////////////////////////////////////////////////
+// Basic Scripting infrastruture
+////////////////////////////////////////////////////////////////
+
+function jmolInitialize(codebaseDirectory, fileNameOrUseSignedApplet) {
+ if (_jmol.initialized)
+ return;
+ _jmol.initialized = true;
+ if(_jmol.jmoljar) {
+ var f = _jmol.jmoljar;
+ if (f.indexOf("/") >= 0) {
+ alert ("This web page URL is requesting that the applet used be " + f + ". This is a possible security risk, particularly if the applet is signed, because signed applets can read and write files on your local machine or network.")
+ var ok = prompt("Do you want to use applet " + f + "? ","yes or no")
+ if (ok == "yes") {
+ codebaseDirectory = f.substring(0, f.lastIndexOf("/"));
+ fileNameOrUseSignedApplet = f.substring(f.lastIndexOf("/") + 1);
+ } else {
+ _jmolGetJarFilename(fileNameOrUseSignedApplet);
+ alert("The web page URL was ignored. Continuing using " + _jmol.archivePath + ' in directory "' + codebaseDirectory + '"');
+ }
+ } else {
+ fileNameOrUseSignedApplet = f;
+ }
+ }
+ _jmolSetCodebase(codebaseDirectory);
+ _jmolGetJarFilename(fileNameOrUseSignedApplet);
+ _jmolOnloadResetForms();
+}
+
+function jmolSetTranslation(TF) {
+ _jmol.params.doTranslate = ''+TF;
+}
+
+function _jmolGetJarFilename(fileNameOrFlag) {
+ _jmol.archivePath =
+ (typeof(fileNameOrFlag) == "string" ? fileNameOrFlag : (fileNameOrFlag ? "JmolAppletSigned" : "JmolApplet") + "0.jar");
+}
+
+function jmolSetDocument(doc) {
+ _jmol.currentDocument = doc;
+}
+
+function jmolSetAppletColor(boxbgcolor, boxfgcolor, progresscolor) {
+ _jmolInitCheck();
+ _jmol.params.boxbgcolor = boxbgcolor;
+ if (boxfgcolor)
+ _jmol.params.boxfgcolor = boxfgcolor
+ else if (boxbgcolor == "white" || boxbgcolor == "#FFFFFF")
+ _jmol.params.boxfgcolor = "black";
+ else
+ _jmol.params.boxfgcolor = "white";
+ if (progresscolor)
+ _jmol.params.progresscolor = progresscolor;
+ if (_jmol.debugAlert)
+ alert(" boxbgcolor=" + _jmol.params.boxbgcolor +
+ " boxfgcolor=" + _jmol.params.boxfgcolor +
+ " progresscolor=" + _jmol.params.progresscolor);
+}
+
+function jmolSetAppletWindow(w) {
+ _jmol.appletWindow = w;
+}
+
+function jmolApplet(size, script, nameSuffix) {
+ _jmolInitCheck();
+ return _jmolApplet(size, null, script, nameSuffix);
+}
+
+////////////////////////////////////////////////////////////////
+// Basic controls
+////////////////////////////////////////////////////////////////
+
+// undefined means it wasn't there; null means it was explicitly listed as null (so as to skip it)
+
+function jmolButton(script, label, id, title) {
+ _jmolInitCheck();
+ id != undefined && id != null || (id = "jmolButton" + _jmol.buttonCount);
+ label != undefined && label != null || (label = script.substring(0, 32));
+ ++_jmol.buttonCount;
+ var scriptIndex = _jmolAddScript(script);
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='button' name='" + id + "' id='" + id +
+ "' value='" + label +
+ "' onclick='_jmolClick(this," + scriptIndex + _jmol.targetText +
+ ")' onmouseover='_jmolMouseOver(" + scriptIndex +
+ ");return true' onmouseout='_jmolMouseOut()' " +
+ _jmol.buttonCssText + " /></span>";
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+function jmolCheckbox(scriptWhenChecked, scriptWhenUnchecked,
+ labelHtml, isChecked, id, title) {
+ _jmolInitCheck();
+ id != undefined && id != null || (id = "jmolCheckbox" + _jmol.checkboxCount);
+ ++_jmol.checkboxCount;
+ if (scriptWhenChecked == undefined || scriptWhenChecked == null ||
+ scriptWhenUnchecked == undefined || scriptWhenUnchecked == null) {
+ alert("jmolCheckbox requires two scripts");
+ return;
+ }
+ if (labelHtml == undefined || labelHtml == null) {
+ alert("jmolCheckbox requires a label");
+ return;
+ }
+ var indexChecked = _jmolAddScript(scriptWhenChecked);
+ var indexUnchecked = _jmolAddScript(scriptWhenUnchecked);
+ var eospan = "</span>"
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input type='checkbox' name='" + id + "' id='" + id +
+ "' onclick='_jmolCbClick(this," +
+ indexChecked + "," + indexUnchecked + _jmol.targetText +
+ ")' onmouseover='_jmolCbOver(this," + indexChecked + "," +
+ indexUnchecked +
+ ");return true' onmouseout='_jmolMouseOut()' " +
+ (isChecked ? "checked='true' " : "")+ _jmol.checkboxCssText + " />"
+ if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
+ t += eospan
+ eospan = "";
+ }
+ t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan;
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+function jmolStartNewRadioGroup() {
+ ++_jmol.radioGroupCount;
+}
+
+function jmolRadioGroup(arrayOfRadioButtons, separatorHtml, groupName, id, title) {
+ /*
+
+ array: [radio1,radio2,radio3...]
+ where radioN = ["script","label",isSelected,"id","title"]
+
+ */
+
+ _jmolInitCheck();
+ var type = typeof arrayOfRadioButtons;
+ if (type != "object" || type == null || ! arrayOfRadioButtons.length) {
+ alert("invalid arrayOfRadioButtons");
+ return;
+ }
+ separatorHtml != undefined && separatorHtml != null || (separatorHtml = " ");
+ var len = arrayOfRadioButtons.length;
+ jmolStartNewRadioGroup();
+ groupName || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));
+ var t = "<span id='"+(id ? id : groupName)+"'>";
+ for (var i = 0; i < len; ++i) {
+ if (i == len - 1)
+ separatorHtml = "";
+ var radio = arrayOfRadioButtons[i];
+ type = typeof radio;
+ if (type == "object") {
+ t += _jmolRadio(radio[0], radio[1], radio[2], separatorHtml, groupName, (radio.length > 3 ? radio[3]: (id ? id : groupName)+"_"+i), (radio.length > 4 ? radio[4] : 0), title);
+ } else {
+ t += _jmolRadio(radio, null, null, separatorHtml, groupName, (id ? id : groupName)+"_"+i, title);
+ }
+ }
+ t+="</span>"
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+
+function jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
+ _jmolInitCheck();
+ if (_jmol.radioGroupCount == 0)
+ ++_jmol.radioGroupCount;
+ var t = _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, (id ? id : groupName + "_" + _jmol.radioCount), title ? title : 0);
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+function jmolLink(script, label, id, title) {
+ _jmolInitCheck();
+ id != undefined && id != null || (id = "jmolLink" + _jmol.linkCount);
+ label != undefined && label != null || (label = script.substring(0, 32));
+ ++_jmol.linkCount;
+ var scriptIndex = _jmolAddScript(script);
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><a name='" + id + "' id='" + id +
+ "' href='javascript:_jmolClick(this," + scriptIndex + _jmol.targetText + ");' onmouseover='_jmolMouseOver(" + scriptIndex +
+ ");return true;' onmouseout='_jmolMouseOut()' " +
+ _jmol.linkCssText + ">" + label + "</a></span>";
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+function jmolCommandInput(label, size, id, title) {
+ _jmolInitCheck();
+ id != undefined && id != null || (id = "jmolCmd" + _jmol.cmdCount);
+ label != undefined && label != null || (label = "Execute");
+ size != undefined && !isNaN(size) || (size = 60);
+ ++_jmol.cmdCount;
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='" + id + "' id='" + id +
+ "' size='"+size+"' onkeypress='_jmolCommandKeyPress(event,\""+id+"\"" + _jmol.targetText + ")'><input type=button value = '"+label+"' onclick='jmolScript(document.getElementById(\""+id+"\").value" + _jmol.targetText + ")' /></span>";
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+}
+
+function _jmolCommandKeyPress(e, id, target) {
+ var keycode = (window.event ? window.event.keyCode : e ? e.which : 0);
+ if (keycode == 13) {
+ var inputBox = document.getElementById(id)
+ _jmolScriptExecute(inputBox, inputBox.value, target)
+ }
+}
+
+function _jmolScriptExecute(element,script,target) {
+ if (typeof(script) == "object")
+ script[0](element, script, target)
+ else
+ jmolScript(script, target)
+}
+
+function jmolMenu(arrayOfMenuItems, size, id, title) {
+ _jmolInitCheck();
+ id != undefined && id != null || (id = "jmolMenu" + _jmol.menuCount);
+ ++_jmol.menuCount;
+ var type = typeof arrayOfMenuItems;
+ if (type != null && type == "object" && arrayOfMenuItems.length) {
+ var len = arrayOfMenuItems.length;
+ if (typeof size != "number" || size == 1)
+ size = null;
+ else if (size < 0)
+ size = len;
+ var sizeText = size ? " size='" + size + "' " : "";
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><select name='" + id + "' id='" + id +
+ "' onChange='_jmolMenuSelected(this" + _jmol.targetText + ")'" +
+ sizeText + _jmol.menuCssText + ">";
+ for (var i = 0; i < len; ++i) {
+ var menuItem = arrayOfMenuItems[i];
+ type = typeof menuItem;
+ var script, text;
+ var isSelected = undefined;
+ if (type == "object" && menuItem != null) {
+ script = menuItem[0];
+ text = menuItem[1];
+ isSelected = menuItem[2];
+ } else {
+ script = text = menuItem;
+ }
+ text != undefined && text != null || (text = script);
+ if (script=="#optgroup") {
+ t += "<optgroup label='" + text + "'>";
+ } else if (script=="#optgroupEnd") {
+ t += "</optgroup>";
+ } else {
+ var scriptIndex = _jmolAddScript(script);
+ var selectedText = isSelected ? "' selected='true'>" : "'>";
+ t += "<option value='" + scriptIndex + selectedText + text + "</option>";
+ }
+ }
+ t += "</select></span>";
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+ }
+}
+
+function jmolHtml(html) {
+ return _jmolDocumentWrite(html);
+}
+
+function jmolBr() {
+ return _jmolDocumentWrite("<br />");
+}
+
+////////////////////////////////////////////////////////////////
+// advanced scripting functions
+////////////////////////////////////////////////////////////////
+
+function jmolDebugAlert(enableAlerts) {
+ _jmol.debugAlert = (enableAlerts == undefined || enableAlerts)
+}
+
+function jmolAppletInline(size, inlineModel, script, nameSuffix) {
+ _jmolInitCheck();
+ return _jmolApplet(size, _jmolSterilizeInline(inlineModel),
+ script, nameSuffix);
+}
+
+function jmolSetTarget(targetSuffix) {
+ _jmol.targetSuffix = targetSuffix;
+ _jmol.targetText = targetSuffix ? ",\"" + targetSuffix + "\"" : ",0";
+}
+
+function jmolScript(script, targetSuffix) {
+ if (script) {
+ _jmolCheckBrowser();
+ if (targetSuffix == "all") {
+ with (_jmol) {
+ for (var i = 0; i < appletSuffixes.length; ++i) {
+ var applet = _jmolGetApplet(appletSuffixes[i]);
+ if (applet) applet.script(script);
+ }
+ }
+ } else {
+ var applet=_jmolGetApplet(targetSuffix);
+ if (applet) applet.script(script);
+ }
+ }
+}
+
+function jmolLoadInline(model, targetSuffix) {
+ if (!model)return "ERROR: NO MODEL"
+ var applet=_jmolGetApplet(targetSuffix);
+ if (!applet)return "ERROR: NO APPLET"
+ if (typeof(model) == "string")
+ return applet.loadInlineString(model, "", false);
+ else
+ return applet.loadInlineArray(model, "", false);
+}
+
+
+function jmolLoadInlineScript(model, script, targetSuffix) {
+ if (!model)return "ERROR: NO MODEL"
+ var applet=_jmolGetApplet(targetSuffix);
+ if (!applet)return "ERROR: NO APPLET"
+ return applet.loadInlineString(model, script, false);
+}
+
+
+function jmolLoadInlineArray(ModelArray, script, targetSuffix) {
+ if (!model)return "ERROR: NO MODEL"
+ script || (script="")
+ var applet=_jmolGetApplet(targetSuffix);
+ if (!applet)return "ERROR: NO APPLET"
+ try {
+ return applet.loadInlineArray(ModelArray, script, false);
+ } catch (err) {
+ //IE 7 bug
+ return applet.loadInlineString(ModelArray.join("\n"), script, false);
+ }
+}
+
+function jmolAppendInlineArray(ModelArray, script, targetSuffix) {
+ if (!model)return "ERROR: NO MODEL"
+ script || (script="")
+ var applet=_jmolGetApplet(targetSuffix);
+ if (!applet)return "ERROR: NO APPLET"
+ try {
+ return applet.loadInlineArray(ModelArray, script, true);
+ } catch (err) {
+ //IE 7 bug
+ return applet.loadInlineString(ModelArray.join("\n"), script, true);
+ }
+}
+
+function jmolAppendInlineScript(model, script, targetSuffix) {
+ if (!model)return "ERROR: NO MODEL"
+ var applet=_jmolGetApplet(targetSuffix);
+ if (!applet)return "ERROR: NO APPLET"
+ return applet.loadInlineString(model, script, true);
+}
+
+function jmolCheckBrowser(action, urlOrMessage, nowOrLater) {
+ if (typeof action == "string") {
+ action = action.toLowerCase();
+ action == "alert" || action == "redirect" || action == "popup" || (action = null);
+ }
+ if (typeof action != "string")
+ alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
+ "action must be 'alert', 'redirect', or 'popup'");
+ else {
+ if (typeof urlOrMessage != "string")
+ alert("jmolCheckBrowser(action, urlOrMessage, nowOrLater)\n\n" +
+ "urlOrMessage must be a string");
+ else {
+ _jmol.checkBrowserAction = action;
+ _jmol.checkBrowserUrlOrMessage = urlOrMessage;
+ }
+ }
+ if (typeof nowOrLater == "string" && nowOrLater.toLowerCase() == "now")
+ _jmolCheckBrowser();
+}
+
+////////////////////////////////////////////////////////////////
+// Cascading Style Sheet Class support
+////////////////////////////////////////////////////////////////
+
+function jmolSetAppletCssClass(appletCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.appletCssClass = appletCssClass;
+ _jmol.appletCssText = appletCssClass ? "class='" + appletCssClass + "' " : "";
+ }
+}
+
+function jmolSetButtonCssClass(buttonCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.buttonCssClass = buttonCssClass;
+ _jmol.buttonCssText = buttonCssClass ? "class='" + buttonCssClass + "' " : "";
+ }
+}
+
+function jmolSetCheckboxCssClass(checkboxCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.checkboxCssClass = checkboxCssClass;
+ _jmol.checkboxCssText = checkboxCssClass ? "class='" + checkboxCssClass + "' " : "";
+ }
+}
+
+function jmolSetRadioCssClass(radioCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.radioCssClass = radioCssClass;
+ _jmol.radioCssText = radioCssClass ? "class='" + radioCssClass + "' " : "";
+ }
+}
+
+function jmolSetLinkCssClass(linkCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.linkCssClass = linkCssClass;
+ _jmol.linkCssText = linkCssClass ? "class='" + linkCssClass + "' " : "";
+ }
+}
+
+function jmolSetMenuCssClass(menuCssClass) {
+ if (_jmol.hasGetElementById) {
+ _jmol.menuCssClass = menuCssClass;
+ _jmol.menuCssText = menuCssClass ? "class='" + menuCssClass + "' " : "";
+ }
+}
+
+////////////////////////////////////////////////////////////////
+// functions for INTERNAL USE ONLY which are subject to change
+// use at your own risk ... you have been WARNED!
+////////////////////////////////////////////////////////////////
+var _jmol = {
+ currentDocument: document,
+
+ debugAlert: false,
+
+ codebase: "",
+ modelbase: ".",
+
+ appletCount: 0,
+ appletSuffixes: [],
+ appletWindow: null,
+ allowedJmolSize: [25, 2048, 300], // min, max, default (pixels)
+ /* By setting the _jmol.allowedJmolSize[] variable in the webpage
+ before calling jmolApplet(), limits for applet size can be overriden.
+ 2048 standard for GeoWall (http://geowall.geo.lsa.umich.edu/home.html)
+ */
+ buttonCount: 0,
+ checkboxCount: 0,
+ linkCount: 0,
+ cmdCount: 0,
+ menuCount: 0,
+ radioCount: 0,
+ radioGroupCount: 0,
+
+ appletCssClass: null,
+ appletCssText: "",
+ buttonCssClass: null,
+ buttonCssText: "",
+ checkboxCssClass: null,
+ checkboxCssText: "",
+ java_arguments: "-Xmx512m",
+ radioCssClass: null,
+ radioCssText: "",
+ linkCssClass: null,
+ linkCssText: "",
+ menuCssClass: null,
+ menuCssText: "",
+
+ targetSuffix: 0,
+ targetText: ",0",
+ scripts: [""],
+ params: {
+ syncId: ("" + Math.random()).substring(3),
+ progressbar: "true",
+ progresscolor: "blue",
+ boxbgcolor: "black",
+ boxfgcolor: "white",
+ boxmessage: "Downloading JmolApplet ..."
+ },
+ ua: navigator.userAgent.toLowerCase(),
+ // uaVersion: parseFloat(navigator.appVersion), // not used
+
+ os: "unknown",
+ browser: "unknown",
+ browserVersion: 0,
+ hasGetElementById: !!document.getElementById,
+ isJavaEnabled: navigator.javaEnabled(),
+ // isNetscape47Win: false, // not used, N4.7 is no longer supported even for detection
+ useIEObject: false,
+ useHtml4Object: false,
+
+ windowsClassId: "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93",
+ windowsCabUrl:
+ "http://java.sun.com/update/1.6.0/jinstall-6u22-windows-i586.cab",
+
+ isBrowserCompliant: false,
+ isJavaCompliant: false,
+ isFullyCompliant: false,
+
+ initialized: false,
+ initChecked: false,
+
+ browserChecked: false,
+ checkBrowserAction: "alert",
+ checkBrowserUrlOrMessage: null,
+
+ archivePath: null, // JmolApplet0.jar OR JmolAppletSigned0.jar
+
+ previousOnloadHandler: null,
+
+ jmoljar: null,
+ useNoApplet: false,
+
+ ready: {}
+}
+
+with (_jmol) {
+ function _jmolTestUA(candidate) {
+ var ua = _jmol.ua;
+ var index = ua.indexOf(candidate);
+ if (index < 0)
+ return false;
+ _jmol.browser = candidate;
+ _jmol.browserVersion = parseFloat(ua.substring(index+candidate.length+1));
+ return true;
+ }
+
+ function _jmolTestOS(candidate) {
+ if (_jmol.ua.indexOf(candidate) < 0)
+ return false;
+ _jmol.os = candidate;
+ return true;
+ }
+
+ _jmolTestUA("konqueror") ||
+ _jmolTestUA("webkit") ||
+ _jmolTestUA("omniweb") ||
+ _jmolTestUA("opera") ||
+ _jmolTestUA("webtv") ||
+ _jmolTestUA("icab") ||
+ _jmolTestUA("msie") ||
+ (_jmol.ua.indexOf("compatible") < 0 && _jmolTestUA("mozilla")); //Netscape, Mozilla, Seamonkey, Firefox and anything assimilated
+
+ _jmolTestOS("linux") ||
+ _jmolTestOS("unix") ||
+ _jmolTestOS("mac") ||
+ _jmolTestOS("win");
+
+ /* not used:
+ isNetscape47Win = (os == "win" && browser == "mozilla" &&
+ browserVersion >= 4.78 && browserVersion <= 4.8);
+ */
+
+ if (os == "win") {
+ isBrowserCompliant = hasGetElementById;
+ } else if (os == "mac") { // mac is the problem child :-(
+ if (browser == "mozilla" && browserVersion >= 5) {
+ // miguel 2004 11 17
+ // checking the plugins array does not work because
+ // Netscape 7.2 OS X still has Java 1.3.1 listed even though
+ // javaplugin.sf.net is installed to upgrade to 1.4.2
+ eval("try {var v = java.lang.System.getProperty('java.version');" +
+ " _jmol.isBrowserCompliant = v >= '1.4.2';" +
+ " } catch (e) { }");
+ } else if (browser == "opera" && browserVersion <= 7.54) {
+ isBrowserCompliant = false;
+ } else {
+ isBrowserCompliant = hasGetElementById &&
+ !((browser == "msie") ||
+ (browser == "webkit" && browserVersion < 125.12));
+ }
+ } else if (os == "linux" || os == "unix") {
+ if (browser == "konqueror" && browserVersion <= 3.3)
+ isBrowserCompliant = false;
+ else
+ isBrowserCompliant = hasGetElementById;
+ } else { // other OS
+ isBrowserCompliant = hasGetElementById;
+ }
+
+ // possibly more checks in the future for this
+ isJavaCompliant = isJavaEnabled;
+
+ isFullyCompliant = isBrowserCompliant && isJavaCompliant;
+
+ useIEObject = (os == "win" && browser == "msie" && browserVersion >= 5.5);
+ useHtml4Object =
+ (browser == "mozilla" && browserVersion >= 5) ||
+ (browser == "opera" && browserVersion >= 8) ||
+ (browser == "webkit" && browserVersion >= 412.2);
+ try {
+ if (top.location.search.indexOf("JMOLJAR=")>=0)
+ jmoljar = top.location.search.split("JMOLJAR=")[1].split("&")[0];
+ } catch(e) {
+ // can't access top.location
+ }
+ try {
+ useNoApplet = (top.location.search.indexOf("NOAPPLET")>=0);
+ } catch(e) {
+ // can't access top.document
+ }
+}
+
+function jmolSetMemoryMb(nMb) {
+ _jmol.java_arguments = "-Xmx" + Math.round(nMb) + "m"
+}
+
+function jmolSetParameter(name,value) {
+ _jmol.params[name] = value
+}
+
+function jmolSetCallback(callbackName,funcName) {
+ _jmol.params[callbackName] = funcName
+}
+
+ try {
+// note this is done FIRST, so it cannot override a setting done by the developer
+ if (top.location.search.indexOf("PARAMS=")>=0) {
+ var pars = unescape(top.location.search.split("PARAMS=")[1].split("&")[0]).split(";");
+ for (var i = 0; i < pars.length; i++) {
+ var p = pars[i].split(":");
+ jmolSetParameter(p[0],p[1]);
+ }
+ }
+ } catch(e) {
+ // can't access top.location
+ }
+
+function jmolSetSyncId(n) {
+ return _jmol.params["syncId"] = n
+}
+
+function jmolGetSyncId() {
+ return _jmol.params["syncId"]
+}
+
+function jmolSetLogLevel(n) {
+ _jmol.params.logLevel = ''+n;
+}
+
+ /* AngelH, mar2007:
+ By (re)setting these variables in the webpage before calling jmolApplet(),
+ a custom message can be provided (e.g. localized for user's language) when no Java is installed.
+ */
+if (noJavaMsg==undefined) var noJavaMsg =
+ "You do not have Java applets enabled in your web browser, or your browser is blocking this applet.<br />\n" +
+ "Check the warning message from your browser and/or enable Java applets in<br />\n" +
+ "your web browser preferences, or install the Java Runtime Environment from <a href='http://www.java.com'>www.java.com</a><br />";
+if (noJavaMsg2==undefined) var noJavaMsg2 =
+ "You do not have the<br />\n" +
+ "Java Runtime Environment<br />\n" +
+ "installed for applet support.<br />\n" +
+ "Visit <a href='http://www.java.com'>www.java.com</a>";
+function _jmolApplet(size, inlineModel, script, nameSuffix) {
+ /* AngelH, mar2007
+ Fixed percent / pixel business, to avoid browser errors:
+ put "px" where needed, avoid where not.
+
+ Bob Hanson, 1/2010
+ Fixed inline escape changing returns to |
+ */
+ with (_jmol) {
+ nameSuffix == undefined && (nameSuffix = appletCount);
+ appletSuffixes.push(nameSuffix);
+ ++appletCount;
+ script || (script = "select *");
+ var sz = _jmolGetAppletSize(size);
+ var widthAndHeight = " width='" + sz[0] + "' height='" + sz[1] + "' ";
+ var tHeader, tFooter;
+ codebase || jmolInitialize(".");
+ if (useIEObject || useHtml4Object) {
+ params.archive = archivePath;
+ params.mayscript = 'true';
+ params.codebase = codebase;
+ params.code = 'JmolApplet';
+ tHeader =
+ "<object name='jmolApplet" + nameSuffix +
+ "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
+ widthAndHeight + "\n";
+ tFooter = "</object>";
+ }
+ if (java_arguments)
+ params.java_arguments = java_arguments;
+ if (useIEObject) { // use MSFT IE6 object tag with .cab file reference
+ tHeader += " classid='" + windowsClassId + "'\n" +
+ (windowsCabUrl ? " codebase='" + windowsCabUrl + "'\n" : "") + ">\n";
+ } else if (useHtml4Object) { // use HTML4 object tag
+ tHeader += " type='application/x-java-applet'\n>\n";
+ /* " classid='java:JmolApplet'\n" + AH removed this
+ Chromium Issue 62076: Java Applets using an <object> with a classid paramater don't load.
+ http://code.google.com/p/chromium/issues/detail?id=62076
+ They say this is the correct behavior according to the spec, and there's no indication at this point
+ that WebKit will be changing the handling, so eventually Safari will acquire this behavior too.
+ Removing the classid parameter seems to be well tolerated by all browsers (even IE!).
+ */
+ } else { // use applet tag
+ tHeader =
+ "<applet name='jmolApplet" + nameSuffix +
+ "' id='jmolApplet" + nameSuffix + "' " + appletCssText + "\n" +
+ widthAndHeight + "\n" +
+ " code='JmolApplet'" +
+ " archive='" + archivePath + "' codebase='" + codebase + "'\n" +
+ " mayscript='true'>\n";
+ tFooter = "</applet>";
+ }
+ var visitJava;
+ if (useIEObject || useHtml4Object) {
+ var szX = "width:" + sz[0]
+ if ( szX.indexOf("%")==-1 ) szX+="px"
+ var szY = "height:" + sz[1]
+ if ( szY.indexOf("%")==-1 ) szY+="px"
+ visitJava =
+ "<p style='background-color:yellow; color:black; " +
+ szX + ";" + szY + ";" +
+ // why doesn't this vertical-align work?
+ "text-align:center;vertical-align:middle;'>\n" +
+ noJavaMsg +
+ "</p>";
+ } else {
+ visitJava =
+ "<table bgcolor='yellow'><tr>" +
+ "<td align='center' valign='middle' " + widthAndHeight + "><font color='black'>\n" +
+ noJavaMsg2 +
+ "</font></td></tr></table>";
+ }
+ params.loadInline = (inlineModel ? inlineModel : "");
+ params.script = (script ? _jmolSterilizeScript(script) : "");
+ var t = tHeader + _jmolParams() + visitJava + tFooter;
+ jmolSetTarget(nameSuffix);
+ ready["jmolApplet" + nameSuffix] = false;
+ if (_jmol.debugAlert)
+ alert(t);
+ return _jmolDocumentWrite(t);
+ }
+}
+
+function _jmolParams() {
+ var t = "";
+ for (var i in _jmol.params)
+ if(_jmol.params[i]!="")
+ t+=" <param name='"+i+"' value='"+_jmol.params[i]+"' />\n";
+ return t
+}
+
+function _jmolInitCheck() {
+ if (_jmol.initChecked)
+ return;
+ _jmol.initChecked = true;
+ jmolInitialize(defaultdir, defaultjar)
+}
+
+function _jmolCheckBrowser() {
+ with (_jmol) {
+ if (browserChecked)
+ return;
+ browserChecked = true;
+
+ if (isFullyCompliant)
+ return true;
+
+ if (checkBrowserAction == "redirect")
+ location.href = checkBrowserUrlOrMessage;
+ else if (checkBrowserAction == "popup")
+ _jmolPopup(checkBrowserUrlOrMessage);
+ else {
+ var msg = checkBrowserUrlOrMessage;
+ if (msg == null)
+ msg = "Your web browser is not fully compatible with Jmol\n\n" +
+ "browser: " + browser +
+ " version: " + browserVersion +
+ " os: " + os +
+ " isBrowserCompliant: " + isBrowserCompliant +
+ " isJavaCompliant: " + isJavaCompliant +
+ "\n\n" + ua;
+ alert(msg);
+ }
+ }
+ return false;
+}
+
+function jmolSetXHTML(id) {
+ _jmol.isXHTML = true
+ _jmol.XhtmlElement = null
+ _jmol.XhtmlAppendChild = false
+ if (id){
+ _jmol.XhtmlElement = document.getElementById(id)
+ _jmol.XhtmlAppendChild = true
+ }
+}
+
+function _jmolDocumentWrite(text) {
+ if (_jmol.currentDocument) {
+ if (_jmol.isXHTML && !_jmol.XhtmlElement) {
+ var s = document.getElementsByTagName("script")
+ _jmol.XhtmlElement = s.item(s.length - 1)
+ _jmol.XhtmlAppendChild = false
+ }
+ if (_jmol.XhtmlElement) {
+ _jmolDomDocumentWrite(text)
+ } else {
+ _jmol.currentDocument.write(text);
+ }
+ }
+ return text;
+}
+
+function _jmolDomDocumentWrite(data) {
+ var pt = 0
+ var Ptr = []
+ Ptr[0] = 0
+ while (Ptr[0] < data.length) {
+ var child = _jmolGetDomElement(data, Ptr)
+ if (!child)break
+ if (_jmol.XhtmlAppendChild)
+ _jmol.XhtmlElement.appendChild(child)
+ else
+ _jmol.XhtmlElement.parentNode.insertBefore(child, _jmol.XhtmlElement);
+ }
+}
+function _jmolGetDomElement(data, Ptr, closetag, lvel) {
+ var e = document.createElement("span")
+ e.innerHTML = data
+ Ptr[0] = data.length
+ return e
+
+//unnecessary?
+
+ closetag || (closetag = "")
+ lvel || (lvel = 0)
+ var pt0 = Ptr[0]
+ var pt = pt0
+ while (pt < data.length && data.charAt(pt) != "<") pt++
+ if (pt != pt0) {
+ var text = data.substring(pt0, pt)
+ Ptr[0] = pt
+ return document.createTextNode(text)
+ }
+ pt0 = ++pt
+ var ch
+ while (pt < data.length && "\n\r\t >".indexOf(ch = data.charAt(pt)) < 0) pt++
+ var tagname = data.substring(pt0, pt)
+ var e = (tagname == closetag || tagname == "/" ? ""
+ : document.createElementNS ? document.createElementNS('http://www.w3.org/1999/xhtml', tagname)
+ : document.createElement(tagname));
+ if (ch == ">") {
+ Ptr[0] = ++pt
+ return e
+ }
+ while (pt < data.length && (ch = data.charAt(pt)) != ">") {
+ while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++
+ pt0 = pt
+ while (pt < data.length && "\n\r\t =/>".indexOf(ch = data.charAt(pt)) < 0) pt++
+ var attrname = data.substring(pt0, pt).toLowerCase()
+ if (attrname && ch != "=")
+ e.setAttribute(attrname, "true")
+ while (pt < data.length && "\n\r\t ".indexOf(ch = data.charAt(pt)) >= 0) pt++
+ if (ch == "/") {
+ Ptr[0] = pt + 2
+ return e
+ } else if (ch == "=") {
+ var quote = data.charAt(++pt)
+ pt0 = ++pt
+ while (pt < data.length && (ch = data.charAt(pt)) != quote) pt++
+ var attrvalue = data.substring(pt0, pt)
+ e.setAttribute(attrname, attrvalue)
+ pt++
+ }
+ }
+ Ptr[0] = ++pt
+ while (Ptr[0] < data.length) {
+ var child = _jmolGetDomElement(data, Ptr, "/" + tagname, lvel+1)
+ if (!child)break
+ e.appendChild(child)
+ }
+ return e
+}
+
+function _jmolPopup(url) {
+ var popup = window.open(url, "JmolPopup",
+ "left=150,top=150,height=400,width=600," +
+ "directories=yes,location=yes,menubar=yes," +
+ "toolbar=yes," +
+ "resizable=yes,scrollbars=yes,status=yes");
+ if (popup.focus)
+ poup.focus();
+}
+
+function _jmolReadyCallback(name) {
+ if (_jmol.debugAlert)
+ alert(name + " is ready");
+ _jmol.ready["" + name] = true;
+}
+
+function _jmolSterilizeScript(script) {
+ script = script.replace(/'/g, "'");
+ if (_jmol.debugAlert)
+ alert("script:\n" + script);
+ return script;
+}
+
+function _jmolSterilizeInline(model) {
+ model = model.replace(/\r|\n|\r\n/g, (model.indexOf("|") >= 0 ? "\\/n" : "|")).replace(/'/g, "'");
+ if (_jmol.debugAlert)
+ alert("inline model:\n" + model);
+ return model;
+}
+
+function _jmolRadio(script, labelHtml, isChecked, separatorHtml, groupName, id, title) {
+ ++_jmol.radioCount;
+ groupName != undefined && groupName != null || (groupName = "jmolRadioGroup" + (_jmol.radioGroupCount - 1));
+ if (!script)
+ return "";
+ labelHtml != undefined && labelHtml != null || (labelHtml = script.substring(0, 32));
+ separatorHtml || (separatorHtml = "")
+ var scriptIndex = _jmolAddScript(script);
+ var eospan = "</span>"
+ var t = "<span id=\"span_"+id+"\""+(title ? " title=\"" + title + "\"":"")+"><input name='"
+ + groupName + "' id='"+id+"' type='radio' onclick='_jmolClick(this," +
+ scriptIndex + _jmol.targetText + ");return true;' onmouseover='_jmolMouseOver(" +
+ scriptIndex + ");return true;' onmouseout='_jmolMouseOut()' " +
+ (isChecked ? "checked='true' " : "") + _jmol.radioCssText + " />"
+ if (labelHtml.toLowerCase().indexOf("<td>")>=0) {
+ t += eospan
+ eospan = "";
+ }
+ t += "<label for=\"" + id + "\">" + labelHtml + "</label>" +eospan + separatorHtml;
+
+ return t;
+}
+
+function _jmolFindApplet(target) {
+ // first look for the target in the current window
+ var applet = _jmolFindAppletInWindow(_jmol.appletWindow != null ? _jmol.appletWindow : window, target);
+ // THEN look for the target in child frames
+ if (applet == undefined)
+ applet = _jmolSearchFrames(window, target);
+ // FINALLY look for the target in sibling frames
+ if (applet == undefined)
+ applet = _jmolSearchFrames(top, target); // look starting in top frame
+ return applet;
+}
+
+function _jmolGetApplet(targetSuffix){
+ var target = "jmolApplet" + (targetSuffix ? targetSuffix : "0");
+ var applet = _jmolFindApplet(target);
+ if (applet) return applet
+ _jmol.alerted || alert("could not find applet " + target);
+ _jmol.alerted = true;
+ return null
+}
+
+function _jmolSearchFrames(win, target) {
+ var applet;
+ var frames = win.frames;
+ if (frames && frames.length) { // look in all the frames below this window
+ try{
+ for (var i = 0; i < frames.length; ++i) {
+ applet = _jmolSearchFrames(frames[i], target);
+ if (applet)
+ return applet;
+ }
+ }catch(e) {
+ if (_jmol.debugAlert)
+ alert("Jmol.js _jmolSearchFrames cannot access " + win.name + ".frame[" + i + "] consider using jmolSetAppletWindow()")
+ }
+ }
+ return applet = _jmolFindAppletInWindow(win, target)
+}
+
+function _jmolFindAppletInWindow(win, target) {
+ var doc = win.document;
+ if (doc.getElementById(target))
+ return doc.getElementById(target);
+ else if (doc.applets)
+ return doc.applets[target];
+ else
+ return doc[target];
+}
+
+function _jmolAddScript(script) {
+ if (!script)
+ return 0;
+ var index = _jmol.scripts.length;
+ _jmol.scripts[index] = script;
+ return index;
+}
+
+function _jmolClick(elementClicked, scriptIndex, targetSuffix) {
+ _jmol.element = elementClicked;
+ _jmolScriptExecute(elementClicked, _jmol.scripts[scriptIndex], targetSuffix);
+}
+
+function _jmolMenuSelected(menuObject, targetSuffix) {
+ var scriptIndex = menuObject.value;
+ if (scriptIndex != undefined) {
+ _jmolScriptExecute(menuObject, _jmol.scripts[scriptIndex], targetSuffix);
+ return;
+ }
+ var len = menuObject.length;
+ if (typeof len == "number") {
+ for (var i = 0; i < len; ++i) {
+ if (menuObject[i].selected) {
+ _jmolClick(menuObject[i], menuObject[i].value, targetSuffix);
+ return;
+ }
+ }
+ }
+ alert("?Que? menu selected bug #8734");
+}
+
+
+_jmol.checkboxMasters = {};
+_jmol.checkboxItems = {};
+
+function jmolSetCheckboxGroup(chkMaster,chkBox) {
+ var id = chkMaster;
+ if(typeof(id)=="number")id = "jmolCheckbox" + id;
+ chkMaster = document.getElementById(id);
+ if (!chkMaster)alert("jmolSetCheckboxGroup: master checkbox not found: " + id);
+ var m = _jmol.checkboxMasters[id] = {};
+ m.chkMaster = chkMaster;
+ m.chkGroup = {};
+ for (var i = 1; i < arguments.length; i++){
+ var id = arguments[i];
+ if(typeof(id)=="number")id = "jmolCheckbox" + id;
+ checkboxItem = document.getElementById(id);
+ if (!checkboxItem)alert("jmolSetCheckboxGroup: group checkbox not found: " + id);
+ m.chkGroup[id] = checkboxItem;
+ _jmol.checkboxItems[id] = m;
+ }
+}
+
+function _jmolNotifyMaster(m){
+ //called when a group item is checked
+ var allOn = true;
+ var allOff = true;
+ for (var chkBox in m.chkGroup){
+ if(m.chkGroup[chkBox].checked)
+ allOff = false;
+ else
+ allOn = false;
+ }
+ if (allOn)m.chkMaster.checked = true;
+ if (allOff)m.chkMaster.checked = false;
+ if ((allOn || allOff) && _jmol.checkboxItems[m.chkMaster.id])
+ _jmolNotifyMaster(_jmol.checkboxItems[m.chkMaster.id])
+}
+
+function _jmolNotifyGroup(m, isOn){
+ //called when a master item is checked
+ for (var chkBox in m.chkGroup){
+ var item = m.chkGroup[chkBox]
+ item.checked = isOn;
+ if (_jmol.checkboxMasters[item.id])
+ _jmolNotifyGroup(_jmol.checkboxMasters[item.id], isOn)
+ }
+}
+
+function _jmolCbClick(ckbox, whenChecked, whenUnchecked, targetSuffix) {
+ _jmol.control = ckbox
+ _jmolClick(ckbox, ckbox.checked ? whenChecked : whenUnchecked, targetSuffix);
+ if(_jmol.checkboxMasters[ckbox.id])
+ _jmolNotifyGroup(_jmol.checkboxMasters[ckbox.id], ckbox.checked)
+ if(_jmol.checkboxItems[ckbox.id])
+ _jmolNotifyMaster(_jmol.checkboxItems[ckbox.id])
+}
+
+function _jmolCbOver(ckbox, whenChecked, whenUnchecked) {
+ window.status = _jmol.scripts[ckbox.checked ? whenUnchecked : whenChecked];
+}
+
+function _jmolMouseOver(scriptIndex) {
+ window.status = _jmol.scripts[scriptIndex];
+}
+
+function _jmolMouseOut() {
+ window.status = " ";
+ return true;
+}
+
+function _jmolSetCodebase(codebase) {
+ _jmol.codebase = codebase ? codebase : ".";
+ if (_jmol.debugAlert)
+ alert("jmolCodebase=" + _jmol.codebase);
+}
+
+function _jmolOnloadResetForms() {
+ // must be evaluated ONLY once
+ _jmol.previousOnloadHandler = window.onload;
+ window.onload =
+ function() {
+ with (_jmol) {
+ if (buttonCount+checkboxCount+menuCount+radioCount+radioGroupCount > 0) {
+ var forms = document.forms;
+ for (var i = forms.length; --i >= 0; )
+ forms[i].reset();
+ }
+ if (previousOnloadHandler)
+ previousOnloadHandler();
+ }
+ }
+}
+
+////////////////////////////////////
+/////extensions for getProperty/////
+////////////////////////////////////
+
+
+function _jmolEvalJSON(s,key){
+ s=s+""
+ if(!s)return []
+ if(s.charAt(0)!="{"){
+ if(s.indexOf(" | ")>=0)s=s.replace(/\ \|\ /g, "\n")
+ return s
+ }
+ var A = eval("("+s+")")
+ if(!A)return
+ if(key && A[key])A=A[key]
+ return A
+}
+
+function _jmolEnumerateObject(A,key){
+ var sout=""
+ if(typeof(A) == "string" && A!="null"){
+ sout+="\n"+key+"=\""+A+"\""
+ }else if(!isNaN(A)||A==null){
+ sout+="\n"+key+"="+(A+""==""?"null":A)
+ }else if(A.length){
+ sout+=key+"=[]"
+ for(var i=0;i<A.length;i++){
+ sout+="\n"
+ if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
+ sout+=_jmolEnumerateObject(A[i],key+"["+i+"]")
+ }else{
+ sout+=key+"["+i+"]="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
+ }
+ }
+ }else{
+ if(key != ""){
+ sout+=key+"={}"
+ key+="."
+ }
+
+ for(var i in A){
+ sout+="\n"
+ if(typeof(A[i]) == "object"||typeof(A[i]) == "array"){
+ sout+=_jmolEnumerateObject(A[i],key+i)
+ }else{
+ sout+=key+i+"="+(typeof(A[i]) == "string" && A[i]!="null"?"\""+A[i].replace(/\"/g,"\\\"")+"\"":A[i])
+ }
+ }
+ }
+ return sout
+}
+
+
+function _jmolSortKey0(a,b){
+ return (a[0]<b[0]?1:a[0]>b[0]?-1:0)
+}
+
+function _jmolSortMessages(A){
+ if(!A || typeof(A)!="object")return []
+ var B = []
+ for(var i=A.length-1;i>=0;i--)for(var j=0;j<A[i].length;j++)B[B.length]=A[i][j]
+ if(B.length == 0) return
+ B=B.sort(_jmolSortKey0)
+ return B
+}
+
+/////////additional extensions //////////
+
+
+function _jmolDomScriptLoad(URL){
+ //open(URL) //to debug
+ _jmol.servercall=URL
+ var node = document.getElementById("_jmolScriptNode")
+ if (node && _jmol.browser!="msie"){
+ document.getElementsByTagName("HEAD")[0].removeChild(node)
+ node=null
+ }
+ if (node) {
+ node.setAttribute("src",URL)
+ } else {
+ node=document.createElement("script")
+ node.setAttribute("id","_jmolScriptNode")
+ node.setAttribute("type","text/javascript")
+ node.setAttribute("src",URL)
+ document.getElementsByTagName("HEAD")[0].appendChild(node)
+ }
+}
+
+
+function _jmolExtractPostData(url){
+ S=url.split("&POST:")
+ var s=""
+ for(var i=1;i<S.length;i++){
+ KV=S[i].split("=")
+ s+="&POSTKEY"+i+"="+KV[0]
+ s+="&POSTVALUE"+i+"="+KV[1]
+ }
+ return "&url="+escape(S[0])+s
+}
+
+function _jmolLoadModel(targetSuffix,remoteURL,array,isError,errorMessage){
+ //called by server, but in client
+ //overload this function to customize return
+ _jmol.remoteURL=remoteURL
+ isError && alert(errorMessage)
+ jmolLoadInlineScript(array.join("\n"),_jmol.optionalscript,targetSuffix)
+}
+
+//////////user property/status functions/////////
+
+function jmolGetStatus(strStatus,targetSuffix){
+ return _jmolSortMessages(jmolGetPropertyAsArray("jmolStatus",strStatus,targetSuffix))
+}
+
+function jmolGetPropertyAsArray(sKey,sValue,targetSuffix) {
+ return _jmolEvalJSON(jmolGetPropertyAsJSON(sKey,sValue,targetSuffix),sKey)
+}
+
+function jmolGetPropertyAsString(sKey,sValue,targetSuffix) {
+ var applet = _jmolGetApplet(targetSuffix);
+ sValue == undefined && (sValue="");
+ return (applet ? applet.getPropertyAsString(sKey,sValue) + "" : "")
+}
+
+function jmolGetPropertyAsJSON(sKey,sValue,targetSuffix) {
+ sValue == undefined && (sValue = "")
+ var applet = _jmolGetApplet(targetSuffix);
+ try {
+ return (applet ? applet.getPropertyAsJSON(sKey,sValue) + "" : "")
+ } catch(e) {
+ return ""
+ }
+}
+
+function jmolGetPropertyAsJavaObject(sKey,sValue,targetSuffix) {
+ sValue == undefined && (sValue = "")
+ var applet = _jmolGetApplet(targetSuffix);
+ return (applet ? applet.getProperty(sKey,sValue) : null)
+}
+
+
+function jmolDecodeJSON(s) {
+ return _jmolEnumerateObject(_jmolEvalJSON(s),"")
+}
+
+
+///////// synchronous scripting ////////
+
+function jmolScriptWait(script, targetSuffix) {
+ targetSuffix == undefined && (targetSuffix="0")
+ var Ret=jmolScriptWaitAsArray(script, targetSuffix)
+ var s = ""
+ for(var i=Ret.length;--i>=0;)
+ for(var j=0;j< Ret[i].length;j++)
+ s+=Ret[i][j]+"\n"
+ return s
+}
+
+function jmolScriptWaitOutput(script, targetSuffix) {
+ targetSuffix == undefined && (targetSuffix="0")
+ var ret = ""
+ try{
+ if (script) {
+ _jmolCheckBrowser();
+ var applet=_jmolGetApplet(targetSuffix);
+ if (applet) ret += applet.scriptWaitOutput(script);
+ }
+ }catch(e){
+ }
+ return ret;
+}
+
+function jmolEvaluate(molecularMath, targetSuffix) {
+
+ //carries out molecular math on a model
+
+ targetSuffix == undefined && (targetSuffix="0")
+ var result = "" + jmolGetPropertyAsJavaObject("evaluate", molecularMath, targetSuffix);
+ var s = result.replace(/\-*\d+/,"")
+ if (s == "" && !isNaN(parseInt(result)))return parseInt(result);
+ var s = result.replace(/\-*\d*\.\d*/,"")
+ if (s == "" && !isNaN(parseFloat(result)))return parseFloat(result);
+ return result;
+}
+
+function jmolScriptEcho(script, targetSuffix) {
+ // returns a newline-separated list of all echos from a script
+ targetSuffix == undefined && (targetSuffix="0")
+ var Ret=jmolScriptWaitAsArray(script, targetSuffix)
+ var s = ""
+ for(var i=Ret.length;--i>=0;)
+ for(var j=Ret[i].length;--j>=0;)
+ if (Ret[i][j][1] == "scriptEcho")s+=Ret[i][j][3]+"\n"
+ return s.replace(/ \| /g, "\n")
+}
+
+
+function jmolScriptMessage(script, targetSuffix) {
+ // returns a newline-separated list of all messages from a script, ending with "script completed\n"
+ targetSuffix == undefined && (targetSuffix="0")
+ var Ret=jmolScriptWaitAsArray(script, targetSuffix)
+ var s = ""
+ for(var i=Ret.length;--i>=0;)
+ for(var j=Ret[i].length;--j>=0;)
+ if (Ret[i][j][1] == "scriptStatus")s+=Ret[i][j][3]+"\n"
+ return s.replace(/ \| /g, "\n")
+}
+
+
+function jmolScriptWaitAsArray(script, targetSuffix) {
+ var ret = ""
+ try{
+ jmolGetStatus("scriptEcho,scriptMessage,scriptStatus,scriptError",targetSuffix)
+ if (script) {
+ _jmolCheckBrowser();
+ var applet=_jmolGetApplet(targetSuffix);
+ if (applet) ret += applet.scriptWait(script);
+ ret = _jmolEvalJSON(ret,"jmolStatus")
+ if(typeof ret == "object")
+ return ret
+ }
+ }catch(e){
+ }
+ return [[ret]]
+}
+
+
+
+//////////// save/restore orientation /////////////
+
+function jmolSaveOrientation(id, targetSuffix) {
+ targetSuffix == undefined && (targetSuffix="0")
+ return _jmol["savedOrientation"+id] = jmolGetPropertyAsArray("orientationInfo","info",targetSuffix).moveTo
+}
+
+function jmolRestoreOrientation(id, targetSuffix) {
+ targetSuffix == undefined && (targetSuffix="0")
+ var s=_jmol["savedOrientation"+id]
+ if (!s || s == "")return
+ s=s.replace(/1\.0/,"0")
+ return jmolScriptWait(s,targetSuffix)
+}
+
+function jmolRestoreOrientationDelayed(id, delay, targetSuffix) {
+ arguments.length < 2 && (delay=1)
+ targetSuffix == undefined && (targetSuffix="0")
+ var s=_jmol["savedOrientation"+id]
+ if (!s || s == "")return
+ s=s.replace(/1\.0/,delay)
+ return jmolScriptWait(s,targetSuffix)
+}
+
+//////////// add parameter /////////////
+/*
+ * for adding callbacks or other parameters. Use:
+
+ jmolSetDocument(0)
+ var s= jmolApplet(....)
+ s = jmolAppletAddParam(s,"messageCallback", "myFunctionName")
+ document.write(s)
+ jmolSetDocument(document) // if you want to then write buttons and such normally
+
+ */
+
+function jmolAppletAddParam(appletCode,name,value){
+ return (value == "" ? appletCode : appletCode.replace(/\<param/,"\n<param name='"+name+"' value='"+value+"' />\n<param"))
+}
+
+///////////////auto load Research Consortium for Structural Biology (RCSB) data ///////////
+
+function jmolLoadAjax_STOLAF_RCSB(fileformat,pdbid,optionalscript,targetSuffix){
+
+ _jmol.thismodel || (_jmol.thismodel = "1crn")
+ _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")
+ _jmol.RCSBserver || (_jmol.RCSBserver="http://www.rcsb.org")
+ _jmol.defaultURL_RCSB || (_jmol.defaultURL_RCSB=_jmol.RCSBserver+"/pdb/files/1CRN.CIF")
+ fileformat || (fileformat="PDB")
+ pdbid || (pdbid=prompt("Enter a 4-digit PDB ID:",_jmol.thismodel))
+ if(!pdbid || pdbid.length != 4)return ""
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ var url=_jmol.defaultURL_RCSB.replace(/1CRN/g,pdbid.toUpperCase())
+ fileformat=="CIF" || (url=url.replace(/CIF/,fileformat))
+ _jmol.optionalscript=optionalscript
+ _jmol.thismodel=pdbid
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.thisurl=url
+ _jmol.modelArray = []
+ url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
+ _jmolDomScriptLoad(url)
+ return url
+}
+
+
+///////////////auto load NIH CACTVS data -- compound name or SMILES ///////////
+
+function jmolLoadAjax_STOLAF_NIH(compoundid,optionalscript,targetSuffix){
+ _jmol.thismodel || (_jmol.thismodel = "aspirin")
+ _jmol.serverURL || (_jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm")
+ _jmol.defaultURL_NIH || (_jmol.defaultURL_NIH="http://cactus.nci.nih.gov/chemical/structure/FILE/file?format=sdf&get3d=True")
+ compoundid || (compoundid=prompt("Enter a compound name or a SMILES string:",_jmol.thismodel))
+ if(!compoundid)return ""
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ var url=_jmol.defaultURL_NIH.replace(/FILE/g,compoundid)
+ _jmol.optionalscript=optionalscript
+ _jmol.thismodel=compoundid
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.thisurl=url
+ _jmol.modelArray = []
+ url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
+ _jmolDomScriptLoad(url)
+ return url
+}
+
+
+/////////////// St. Olaf College AJAX server -- ANY URL ///////////
+
+function jmolLoadAjax_STOLAF_ANY(url, userid, optionalscript,targetSuffix){
+ _jmol.serverURL="http://fusion.stolaf.edu/chemistry/jmol/getajaxjs.cfm"
+ _jmol.thisurlANY || (_jmol.thisurlANY = "http://www.stolaf.edu/depts/chemistry/mo/struc/data/ycp3-1.mol")
+ url || (url=prompt("Enter any (uncompressed file) URL:", _jmol.thisurlANY))
+ userid || (userid="0")
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ _jmol.optionalscript=optionalscript
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.modelArray = []
+ _jmol.thisurl = url
+ url=_jmol.serverURL+"?returnfunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix+_jmolExtractPostData(url)
+ _jmolDomScriptLoad(url)
+}
+
+
+/////////////// Mineralogical Society of America (MSA) data /////////
+
+function jmolLoadAjax_MSA(key,value,optionalscript,targetSuffix){
+
+ _jmol.thiskeyMSA || (_jmol.thiskeyMSA = "mineral")
+ _jmol.thismodelMSA || (_jmol.thismodelMSA = "quartz")
+ _jmol.ajaxURL_MSA || (_jmol.ajaxURL_MSA="http://rruff.geo.arizona.edu/AMS/result.php?mineral=quartz&viewing=ajaxjs")
+ key || (key=prompt("Enter a field:", _jmol.thiskeyMSA))
+ if(!key)return ""
+ value || (value=prompt("Enter a "+key+":", _jmol.thismodelMSA))
+ if(!value)return ""
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ optionalscript == 1 && (optionalscript='load "" {1 1 1}')
+ var url=_jmol.ajaxURL_MSA.replace(/mineral/g,key).replace(/quartz/g,value)
+ _jmol.optionalscript=optionalscript
+ _jmol.thiskeyMSA=key
+ _jmol.thismodelMSA=value
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.thisurl=url
+ _jmol.modelArray = []
+ loadModel=_jmolLoadModel
+ _jmolDomScriptLoad(url)
+ return url
+}
+
+
+
+function jmolLoadAjaxJS(url, userid, optionalscript,targetSuffix){
+ userid || (userid="0")
+ targetSuffix || (targetSuffix="0")
+ optionalscript || (optionalscript="")
+ _jmol.optionalscript=optionalscript
+ _jmol.thismodel=userid
+ _jmol.thistargetsuffix=targetSuffix
+ _jmol.modelArray = []
+ _jmol.thisurl = url
+ url+="&returnFunction=_jmolLoadModel&returnArray=_jmol.modelArray&id="+targetSuffix
+ _jmolDomScriptLoad(url)
+}
+
+
+//// in case Jmol library has already been loaded:
+
+}catch(e){}
+
+///////////////moving atoms //////////////
+
+// HIGHLY experimental!!
+
+function jmolSetAtomCoord(i,x,y,z,targetSuffix){
+ _jmolCheckBrowser();
+ var applet=_jmolGetApplet(targetSuffix);
+ if (applet) applet.getProperty('jmolViewer').setAtomCoord(i,x,y,z)
+}
+
+function jmolSetAtomCoordRelative(i,x,y,z,targetSuffix){
+ _jmolCheckBrowser();
+ var applet=_jmolGetApplet(targetSuffix);
+ if (applet) applet.getProperty('jmolViewer').setAtomCoordRelative(i,x,y,z)
+}
+
+
+///////////////applet fake for testing buttons/////////////
+
+
+if(_jmol.useNoApplet){
+ jmolApplet = function(w){
+ var s="<table style='background-color:black' width="+w+"><tr height="+w+">"
+ +"<td align=center valign=center style='background-color:white'>"
+ +"Applet would be here"
+ +"<p><textarea id=fakeApplet rows=5 cols=50></textarea>"
+ +"</td></tr></table>"
+ return _jmolDocumentWrite(s)
+ }
+
+ _jmolFindApplet = function(){return jmolApplet0}
+
+ jmolApplet0 = {
+ script: function(script){document.getElementById("fakeApplet").value="\njmolScript:\n"+script}
+ ,scriptWait: function(script){document.getElementById("fakeApplet").value="\njmolScriptWait:\n"+script}
+ ,loadInline: function(data,script){document.getElementById("fakeApplet").value="\njmolLoadInline data:\n"+data+"\n\nscript:\n"+script}
+ }
+}
+
+
+///////////////////////////////////////////
+
+ // This should no longer be needed, jmolResizeApplet() is better; kept for backwards compatibility
+ /*
+ Resizes absolutely (pixels) or by percent of window (w or h 0.5 means 50%).
+ targetSuffix is optional and defaults to zero (first applet in page).
+ Both w and h are optional, but needed if you want to use targetSuffix.
+ h defaults to w
+ w defaults to 100% of window
+ If either w or h is between 0 and 1, then it is taken as percent/100.
+ If either w or h is greater than 1, then it is taken as a size (pixels).
+ */
+function jmolResize(w,h,targetSuffix) {
+ _jmol.alerted = true;
+ var percentW = (!w ? 100 : w <= 1 && w > 0 ? w * 100 : 0);
+ var percentH = (!h ? percentW : h <= 1 && h > 0 ? h * 100 : 0);
+ if (_jmol.browser=="msie") {
+ var width=document.body.clientWidth;
+ var height=document.body.clientHeight;
+ } else {
+ var netscapeScrollWidth=15;
+ var width=window.innerWidth - netscapeScrollWidth;
+ var height=window.innerHeight-netscapeScrollWidth;
+ }
+ var applet = _jmolGetApplet(targetSuffix);
+ if(!applet)return;
+ applet.style.width = (percentW ? width * percentW/100 : w)+"px";
+ applet.style.height = (percentH ? height * percentH/100 : (h ? h : w))+"px";
+ //title=width + " " + height + " " + (new Date());
+}
+
+// 13 Jun 09 -- makes jmolResize() obsolete (kept for backwards compatibility)
+function jmolResizeApplet(size,targetSuffix) {
+ // See _jmolGetAppletSize() for the formats accepted as size [same used by jmolApplet()]
+ // Special case: an empty value for width or height is accepted, meaning no change in that dimension.
+ _jmol.alerted = true;
+ var applet = _jmolGetApplet(targetSuffix);
+ if(!applet)return;
+ var sz = _jmolGetAppletSize(size, "px");
+ sz[0] && (applet.style.width = sz[0]);
+ sz[1] && (applet.style.height = sz[1]);
+}
+
+function _jmolGetAppletSize(size, units) {
+ /* Accepts single number or 2-value array, each one can be one of:
+ percent (text string ending %), decimal 0 to 1 (percent/100), number, or text string (interpreted as nr.)
+ [width, height] array of strings is returned, with units added if specified.
+ Percent is relative to container div or element (which should have explicitly set size).
+ */
+ var width, height;
+ if ( (typeof size) == "object" && size != null ) {
+ width = size[0]; height = size[1];
+ } else {
+ width = height = size;
+ }
+ return [_jmolFixDim(width, units), _jmolFixDim(height, units)];
+}
+
+function _jmolFixDim(x, units) {
+ var sx = "" + x;
+ return (sx.length == 0 ? (units ? "" : _jmol.allowedJmolSize[2])
+ : sx.indexOf("%") == sx.length-1 ? sx
+ : (x = parseFloat(x)) <= 1 && x > 0 ? x * 100 + "%"
+ : (isNaN(x = Math.floor(x)) ? _jmol.allowedJmolSize[2]
+ : x < _jmol.allowedJmolSize[0] ? _jmol.allowedJmolSize[0]
+ : x > _jmol.allowedJmolSize[1] ? _jmol.allowedJmolSize[1]
+ : x) + (units ? units : ""));
+}
+
+
+
+
->FER_CAPAA Ferredoxin\r
------------------------------------------------------------ASYKVKLITPDGP\r
-IEFDCPDDVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDV\r
-TIETHKEAELVG-\r
->FER_CAPAN Ferredoxin, chloroplast precursor\r
-MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMASYKVKLITPDGP\r
-IEFDCPDNVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDV\r
-TIETHKEAELVG-\r
->FER1_SOLLC Ferredoxin-1, chloroplast precursor\r
-MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPEGP\r
-IEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGSVDQSDGNFLDEDQEAAGFVLTCVAYPKGDV\r
-TIETHKEEELTA-\r
->Q93XJ9_SOLTU Ferredoxin I precursor\r
-MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPDGP\r
-IEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGTVDQSDGKFLDDDQEAAGFVLTCVAYPKCDV\r
-TIETHKEEELTA-\r
->FER1_PEA Ferredoxin-1, chloroplast precursor\r
-MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMASYKVKLVTPDGT\r
-QEFECPSDVYILDHAEEVGIDLPYSCRAGSCSSCAGKVVGGEVDQSDGSFLDDEQIEAGFVLTCVAYPTSDV\r
-VIETHKEEDLTA-\r
->Q7XA98_TRIPR Ferredoxin I\r
-MATT---PALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGFGLKSVSTKRGDLAVAMATYKVKLITPEGP\r
-QEFDCPDDVYILDHAEEVGIELPYSCRAGSCSSCAGKVVNGNVNQEDGSFLDDEQIEGGWVLTCVAFPTSDV\r
-TIETHKEEELTA-\r
->FER1_MESCR Ferredoxin-1, chloroplast precursor\r
-MAAT--TAALSGATMSTAFAPK--TPPMTAALPTNVGR--ALFGLKS-SASR-GRVTAMAAYKVTLVTPEGK\r
-QELECPDDVYILDAAEEAGIDLPYSCRAGSCSSCAGKVTSGSVNQDDGSFLDDDQIKEGWVLTCVAYPTGDV\r
-TIETHKEEELTA-\r
->FER1_SPIOL Ferredoxin-1, chloroplast precursor\r
-MAAT--TTTMMG--MATTFVPKPQAPPMMAALPSNTGR--SLFGLKT-GSR--GGRMTMAAYKVTLVTPTGN\r
-VEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDDDQIDEGWVLTCAAYPVSDV\r
-TIETHKEEELTA-\r
->FER3_RAPSA Ferredoxin, leaf L-A\r
------------------------------------------------------------ATYKVKFITPEGE\r
-QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDV\r
-TIETHREEDMV--\r
->FER1_ARATH Ferredoxin-1, chloroplast precursor\r
-MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGE\r
-LEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDV\r
-TIETHKEEDIV--\r
->FER_BRANA Ferredoxin\r
------------------------------------------------------------ATYKVKFITPEGE\r
-QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDV\r
-TIETHKEEELV--\r
->FER2_ARATH Ferredoxin-2, chloroplast precursor\r
-MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE\r
-QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV\r
-VIETHKEEAIM--\r
->Q93Z60_ARATH At1g10960/T19D16_12\r
-MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE\r
-QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD-------------------\r
--------------\r
->FER1_MAIZE Ferredoxin-1, chloroplast precursor\r
-MATVLGSPRAPAFFFSSSSLRAAPAPTAV--ALPAAKV--GIMGRSA-SSRR--RLRAQATYNVKLITPEGE\r
-VELQVPDDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDV\r
-VIETHKEEELTGA\r
->O80429_MAIZE Ferredoxin\r
-MAAT---------ALSMSILR---APPPCFSSPLRLRV--AVAKPLA-APMRRQLLRAQATYNVKLITPEGE\r
-VELQVPDDVYILDFAEEEGIDLPFSCRAGSCSSCAGKVVSGSVDQSDQSFLNDNQVADGWVLTCAAYPTSDV\r
-VIETHKEDDLL--\r
+>FER_CAPAA Ferredoxin
+-----------------------------------------------------------ASYKVKLITPDGP
+IEFDCPDDVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDV
+TIETHKEAELVG-
+>FER_CAPAN Ferredoxin, chloroplast precursor
+MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMASYKVKLITPDGP
+IEFDCPDNVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDGNFLDDDQLEEGWVLTCVAYPQSDV
+TIETHKEAELVG-
+>FER1_SOLLC Ferredoxin-1, chloroplast precursor
+MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPEGP
+IEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGSVDQSDGNFLDEDQEAAGFVLTCVAYPKGDV
+TIETHKEEELTA-
+>Q93XJ9_SOLTU Ferredoxin I precursor
+MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMASYKVKLITPDGP
+IEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGTVDQSDGKFLDDDQEAAGFVLTCVAYPKCDV
+TIETHKEEELTA-
+>FER1_PEA Ferredoxin-1, chloroplast precursor
+MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMASYKVKLVTPDGT
+QEFECPSDVYILDHAEEVGIDLPYSCRAGSCSSCAGKVVGGEVDQSDGSFLDDEQIEAGFVLTCVAYPTSDV
+VIETHKEEDLTA-
+>Q7XA98_TRIPR Ferredoxin I
+MATT---PALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGFGLKSVSTKRGDLAVAMATYKVKLITPEGP
+QEFDCPDDVYILDHAEEVGIELPYSCRAGSCSSCAGKVVNGNVNQEDGSFLDDEQIEGGWVLTCVAFPTSDV
+TIETHKEEELTA-
+>FER1_MESCR Ferredoxin-1, chloroplast precursor
+MAAT--TAALSGATMSTAFAPK--TPPMTAALPTNVGR--ALFGLKS-SASR-GRVTAMAAYKVTLVTPEGK
+QELECPDDVYILDAAEEAGIDLPYSCRAGSCSSCAGKVTSGSVNQDDGSFLDDDQIKEGWVLTCVAYPTGDV
+TIETHKEEELTA-
+>FER1_SPIOL Ferredoxin-1, chloroplast precursor
+MAAT--TTTMMG--MATTFVPKPQAPPMMAALPSNTGR--SLFGLKT-GSR--GGRMTMAAYKVTLVTPTGN
+VEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLDDDQIDEGWVLTCAAYPVSDV
+TIETHKEEELTA-
+>FER3_RAPSA Ferredoxin, leaf L-A
+-----------------------------------------------------------ATYKVKFITPEGE
+QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDV
+TIETHREEDMV--
+>FER1_ARATH Ferredoxin-1, chloroplast precursor
+MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGE
+LEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDV
+TIETHKEEDIV--
+>FER_BRANA Ferredoxin
+-----------------------------------------------------------ATYKVKFITPEGE
+QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDV
+TIETHKEEELV--
+>FER2_ARATH Ferredoxin-2, chloroplast precursor
+MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
+QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV
+VIETHKEEAIM--
+>Q93Z60_ARATH At1g10960/T19D16_12
+MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
+QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD-------------------
+-------------
+>FER1_MAIZE Ferredoxin-1, chloroplast precursor
+MATVLGSPRAPAFFFSSSSLRAAPAPTAV--ALPAAKV--GIMGRSA-SSRR--RLRAQATYNVKLITPEGE
+VELQVPDDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDV
+VIETHKEEELTGA
+>O80429_MAIZE Ferredoxin
+MAAT---------ALSMSILR---APPPCFSSPLRLRV--AVAKPLA-APMRRQLLRAQATYNVKLITPEGE
+VELQVPDDVYILDFAEEEGIDLPFSCRAGSCSSCAGKVVSGSVDQSDQSFLNDNQVADGWVLTCAAYPTSDV
+VIETHKEDDLL--
-<?xml version="1.0" encoding="ISO-8859-1" ?>\r
-<!--\r
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)\r
- * Copyright (C) 2014 The Jalview Authors\r
- * \r
- * This file is part of Jalview.\r
- * \r
- * Jalview is free software: you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License \r
- * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\r
- * \r
- * Jalview is distributed in the hope that it will be useful, but \r
- * WITHOUT ANY WARRANTY; without even the implied warranty \r
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
- * PURPOSE. See the GNU General Public License for more details.\r
- * \r
- * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.\r
- * The Jalview Authors are detailed in the 'AUTHORS' file.\r
--->\r
-<!DOCTYPE helpset PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 1.0//EN" "http://java.sun.com/products/javahelp/helpset_1_0.dtd">\r
-<helpset version="1.0">\r
- <!-- title -->\r
- <title>Jalview Documentation</title>\r
- <!-- maps -->\r
- <maps>\r
- <homeID>home</homeID>\r
- <mapref location="help.jhm" />\r
- </maps>\r
- <!-- views -->\r
- <view>\r
- <name>TOC</name>\r
- <label>Table Of Contents</label>\r
- <type>javax.help.TOCView</type>\r
- <data>helpTOC.xml</data>\r
- </view>\r
- <view>\r
- <name>Search</name>\r
- <label>Search</label>\r
- <type>javax.help.SearchView</type>\r
- <data engine="com.sun.java.help.search.DefaultSearchEngine">\r
- JavaHelpSearch\r
- </data>\r
- </view>\r
-<presentation default="true" displayviews="true" displayviewimages="false">\r
- <name>TOPALi</name>\r
- <size width="800" height="700" />\r
- <location x="200" y="50" />\r
- <title>Jalview Documentation</title>\r
- <image>helpIcon</image>\r
- <toolbar>\r
- <helpaction image="backIcon">javax.help.BackAction</helpaction>\r
- <helpaction image="forwardIcon">javax.help.ForwardAction</helpaction>\r
- <helpaction image="homeIcon">javax.help.HomeAction</helpaction>\r
- <helpaction>javax.help.SeparatorAction</helpaction>\r
- <!--<helpaction image="reloadIcon">javax.help.ReloadAction</helpaction>-->\r
- <!--<helpaction image="addBookmarkIcon">javax.help.FavoritesAction</helpaction>-->\r
- <helpaction image="printIcon">javax.help.PrintAction</helpaction>\r
- <helpaction image="printSetupIcon">javax.help.PrintSetupAction</helpaction>\r
- </toolbar>\r
- </presentation>\r
-</helpset>\r
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview 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.
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+-->
+<!DOCTYPE helpset PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp HelpSet Version 1.0//EN" "http://java.sun.com/products/javahelp/helpset_1_0.dtd">
+<helpset version="1.0">
+ <!-- title -->
+ <title>Jalview Documentation</title>
+ <!-- maps -->
+ <maps>
+ <homeID>home</homeID>
+ <mapref location="help.jhm" />
+ </maps>
+ <!-- views -->
+ <view>
+ <name>TOC</name>
+ <label>Table Of Contents</label>
+ <type>javax.help.TOCView</type>
+ <data>helpTOC.xml</data>
+ </view>
+ <view>
+ <name>Search</name>
+ <label>Search</label>
+ <type>javax.help.SearchView</type>
+ <data engine="com.sun.java.help.search.DefaultSearchEngine">
+ JavaHelpSearch
+ </data>
+ </view>
+<presentation default="true" displayviews="true" displayviewimages="false">
+ <name>TOPALi</name>
+ <size width="800" height="700" />
+ <location x="200" y="50" />
+ <title>Jalview Documentation</title>
+ <image>helpIcon</image>
+ <toolbar>
+ <helpaction image="backIcon">javax.help.BackAction</helpaction>
+ <helpaction image="forwardIcon">javax.help.ForwardAction</helpaction>
+ <helpaction image="homeIcon">javax.help.HomeAction</helpaction>
+ <helpaction>javax.help.SeparatorAction</helpaction>
+ <!--<helpaction image="reloadIcon">javax.help.ReloadAction</helpaction>-->
+ <!--<helpaction image="addBookmarkIcon">javax.help.FavoritesAction</helpaction>-->
+ <helpaction image="printIcon">javax.help.PrintAction</helpaction>
+ <helpaction image="printSetupIcon">javax.help.PrintSetupAction</helpaction>
+ </toolbar>
+ </presentation>
+</helpset>
<mapID target="alwEdit" url="html/menus/alwedit.html"/>
<mapID target="alwSelect" url="html/menus/alwselect.html"/>
<mapID target="alwView" url="html/menus/alwview.html"/>
+ <mapID target="alwAnnotations" url="html/menus/alwannotation.html"/>
<mapID target="alwFormat" url="html/menus/alwformat.html"/>
<mapID target="alwColour" url="html/menus/alwcolour.html"/>
<mapID target="alwCalc" url="html/menus/alwcalculate.html"/>
<mapID target="wsMenu" url="html/menus/wsmenu.html"/>
<mapID target="popMenu" url="html/menus/popupMenu.html"/>
- <mapID target="annotMenus" url="html/menus/alwannotations.html"/>
+ <mapID target="annotPanelMenu" url="html/menus/alwannotationpanel.html"/>
<mapID target="memory" url="html/memory.html" />
<mapID target="jalviewjnlp" url="html/jalviewjnlp.html" />
<tocitem text="Window Menus" target="menus" expand="false">
<tocitem text="Desktop Window" target="desktopMenu"/>
<tocitem text="Alignment Window" target="alMenu">
- <tocitem text="File Menu" target="alwFile"/>
- <tocitem text="Edit Menu" target="alwEdit"/>
- <tocitem text="Select Menu" target="alwSelect"/>
- <tocitem text="View Menu" target="alwView"/>
- <tocitem text="Format Menu" target="alwFormat"/>
- <tocitem text="Colour Menu" target="alwColour"/>
- <tocitem text="Calculation Menu" target="alwCalc"/>
- <tocitem text="Web Service Menu" target="wsMenu"/>
- <tocitem text="Annotation Menus" target="annotMenus"/>
- <tocitem text="Popup Menu" target="popMenu"/>
- </tocitem>
+ <tocitem text="File Menu" target="alwFile"/>
+ <tocitem text="Edit Menu" target="alwEdit"/>
+ <tocitem text="Select Menu" target="alwSelect"/>
+ <tocitem text="View Menu" target="alwView"/>
+ <tocitem text="Annotations Menu" target="alwAnnotations"/>
+ <tocitem text="Format Menu" target="alwFormat"/>
+ <tocitem text="Colour Menu" target="alwColour"/>
+ <tocitem text="Calculation Menu" target="alwCalc"/>
+ <tocitem text="Web Service Menu" target="wsMenu"/>
+ <tocitem text="Annotation Panel Menu" target="annotPanelMenu"/>
+ <tocitem text="Popup Menu" target="popMenu"/>
+ </tocitem>
</tocitem>
<tocitem text="Preferences" target="preferences"/>
<tocitem text="Memory Settings" target="memory" expand="false">
<p><strong>Sequence logo</strong></p>
By clicking on the label you can also activate the sequence logo. It
indicates the relative amount of residues per column which can be
- estimated by it's size in the logo. The tooltip of a column gives the
+ estimated by its size in the logo. The tooltip of a column gives the
exact numbers for all occuring residues.
<br />If columns of the alignment are very diverse, then it can
sometimes be difficult to see the sequence logo - in this case, right
are two residues per column, the actual column and the interacting
base. The opening bracket is always the one on the left side.<br>
Like sequence logos the relative amount of a specific base pair can be
-estimated by it's size in the logo. The tool tip of a column gives the
+estimated by its size in the logo. The tool tip of a column gives the
exact numbers for all occurring valid base pairs.
</p>
</body>
</head>
<body>
-<p> <em>Colouring above a percentage identity threshold</em></p>
+<p> <strong>Colouring above a percentage identity threshold</strong></p>
<p> Selecting this option causes the colour scheme to be applied to only those
residues that occur in that column more than a certain percentage of the time.
For instance selecting the threshold to be 100 will only colour those columns
<body>
-<p><em>Blosum62</a></em> </p>
+<p><strong>Blosum62</a></strong> </p>
<p>Gaps are coloured white. If a residue matches the consensus sequence residue
at that position it is coloured dark blue. If it does not match the consensus
residue but the 2 residues have a positive Blosum62 score, it is coloured light
</head>
<body>
-<p><em>Buried index</em></p>
+<p><strong>Buried index</strong></p>
<div align="center">
<table width="400" border="1">
<tr>
</head>
<body>
-<p><em>Clustal X Colour Scheme</em></p>
+<p><strong>Clustal X Colour Scheme</strong></p>
<p>This is an emulation of the default colourscheme used for alignments in
Clustal X, a graphical interface for the ClustalW multiple sequence alignment
program. Each residue in the alignment is assigned a colour if the
-->
<head><title>Colouring by Conservation</title></head>
<body>
-<p><em>Colouring by Conservation</em></p>
+<p><strong>Colouring by Conservation</strong></p>
<p>This is an approach to alignment colouring which highlights
regions of an alignment where physicochemical properties are
conserved. It is based on the one used in
</head>
<body>
-<p><em>Helix Propensity</em> </p>
+<p><strong>Helix Propensity</strong> </p>
<div align="center">
<table width="400" border="1">
<tr>
</head>
<body>
-<p><em>Hydrophobicity</em></p>
+<p><strong>Hydrophobicity</strong></p>
<p>According to the hydrophobicity table of Kyte, J., and Doolittle, R.F., J.
Mol. Biol. 1157, 105-132, 1982. The most hydrophobic residues according to this
table are coloured red and the most hydrophilic ones are coloured blue.</p>
</head>
<body>
-<p><em>Nucleotide Colours</em></p>
+<p><strong>Nucleotide Colours</strong></p>
<div align="center">
<table width="200" border="1">
<tr>
</head>
<body>
-<p><em>PID Colours</em><br>
+<p><strong>PID Colours</strong><br>
<br>
The PID option colours the residues (boxes and/or text) according to the percentage
of the residues in each column that agree with the consensus sequence. Only
</head>
<body>
-<p><em>Purine/Pyrimidine Colours</em></p>
+<p><strong>Purine/Pyrimidine Colours</strong></p>
<div align="center">
<table width="200" border="1">
<tr>
</head>
<body>
-<p><em>Strand propensity</em></p>
+<p><strong>Strand propensity</strong></p>
<div align="center">
<table width="400" border="1">
<tr>
</head>
<body>
-<p><em><a name="taylor">Taylor</a></em></p>
+<p><strong><a name="taylor">Taylor</a></strong></p>
<p>These colours were invented by Willie Taylor and an entertaining description
of their birth can be found in Protein Engineering, Vol 10 , 743-746 (1997)</p>
<div align="center">
</head>
<body>
-<p><em>Turn propensity</em></p>
+<p><strong>Turn propensity</strong></p>
<div align="center">
<table width="400" border="1">
<tr>
-->
<head><title>User Defined Colours</title></head>
<body>
-<p><em>User Defined Colours</em></p>
-<p><img src="userDefined.gif" width="719" height="368"> </p>
+<p><strong>User Defined Colours</strong></p>
+<p><img src="userDefined_java6.gif" width="815" height="402"> </p>
<p>You may define any number of new colour schemes, each with a unique name. <br>
<br>
- Each of the residues in a new colour scheme may be assigned a new user defined
- colour. <br>
- <br>
- Click "Apply" or "OK" to set your new colours on the active
- alignment window. </p>
-<p>Click "Cancel" to undo your changes if you pressed the "Apply"
- button. <br>
- <br>
- If you save your colour scheme with a unique name the colour scheme name will
- be added to the "Colour" menu on each new alignment window.<br>
+ Each of the residues in a colour scheme may be assigned any chosen colour. <br>
+ Select one or more residues, then select the desired colour.<br/>
+ Use Ctrl-click to select multiple residues, or click then Shift-click to select a block.<br/>
+ Note that the currently selected buttons are highlighted by a lighter text colour.
+ <p>
+ The <strong>Case Sensitive</strong> option allows you to choose distinct colours for upper and
+ lower case residue codes.
+ <p>
+ Click <strong>Apply</strong> or <strong>OK</strong> to set your new colours on the active
+ alignment window.<br/>
+ Click <strong>Cancel</strong> to undo your changes if you pressed the <strong>Apply</strong>
+ button.
+ </p>
+ If you save your colour scheme with a unique name, the colour scheme name will
+ be added to the <strong>Colour</strong> menu on each new alignment window.<br>
<br>
Any saved colour schemes will be automatically loaded the next time you use
- Jalview.</p>
+ Jalview.
+ <br><br>
+ <em>Note: the screenshot shows the appearance when running Java version 6. For Java 7 (from Jalview 2.8.2) only the Swatches colour chooser is
+ currently supported (for reasons of available screen space).</em>
+ <p/>
</body>
</html>
</head>
<body>
-<p><em>Zappo Colours</em><br>
+<p><strong>Zappo Colours</strong><br>
<br>
The residues are coloured according to their physicochemical properties as
follows: </p>
area (below the sequence ID area).
</p>
<ul>
- <li>Add New Row<br>
+ <li><strong>Add New Row</strong><br>
<em>Adds a new, named annotation row (a dialog box will pop up for you to
enter the label for the new row). </em> </li>
- <li>Hide Row<br>
+ <li><strong>Edit Label/Description</strong><br>
+ <em>This opens a dialog where you can change the name (displayed label), or the description
+ (as shown on the label tooltip) of the clicked annotation. </em> </li>
+ <li><strong>Hide This Row</strong><br>
<em>Hides the annotation row whose label was clicked in order to bring up
the menu.</em> </li>
- <li>Delete Row<br>
+ <li><strong>Hide All <em><label></em></strong><br>
+ <em>Hides all annotation rows whose label matches the one clicked.
+ (This option is only shown for annotations that relate to individual sequences,
+ not for whole alignment annotations. Since Jalview 2.8.2.)</em> </li>
+ <li><strong>Delete This Row</strong><br>
<em>Deletes the annotation row whose label was clicked in order to bring up
the menu.</em> </li>
- <li>Show All Hidden Rows<br>
+ <li><strong>Show All Hidden Rows</strong><br>
<em>Shows all hidden annotation rows.</em> </li>
<li><strong>Export Annotation</strong> <em>(Application only)</em><br>
<em>Annotations can be saved to file or output to a text window in either the
BAR_GRAPH	Bar Graph 1	<html>an <em>html tooltip</em> for Bar graph 1.</html>	||-100,-|-200,-|-300,-|-400,-|200,+|300,+|150,+
LINE_GRAPH	Green Values	1.1|2.2|1.3|3.4|0.7|1.4|3.3|2.2|2.1|-1.1|3.2
LINE_GRAPH	Red Values	2.1|3.2|1.3|-1.4|5.5|1.4|1.3|4.2|-1.1|1.1|3.2
-BAR_GRAPH	Bar Graph	2 1,.|2,*|3,:|4,.|5,*|4,:|3,.|2|1|1|2|3|4|5|4
+BAR_GRAPH	Bar Graph 2	1,.|2,*|3,:|4,.|5,*|4,:|3,.|2|1|1|2|3|4|5|4
NO_GRAPH	Icons 	||||E,Sheet1|E|E||||H,Sheet 2|H|H|H||||||
NO_GRAPH	Purple Letters	m|y|p|r|o|t|e|i|n
COLOUR	Bar Graph 2	blue
The jars are obtained from the <em>embedded</em> directory within the
<a href="http://dist.codehaus.org/groovy/distributions">groovy
distribution</a>. The easiest way of adding them to the Jalview classpath
- is to download and build jalview from it's source distribution, and
+ is to download and build jalview from its source distribution, and
then add the groovy-all-*.jar to the lib directory whose path is given
in the java.ext.dirs property.
</p>
<body>
<p><strong>Preferences</strong></p>
<p>The preferences panel is opened from the Jalview Desktop’s <strong><em>Tools</em></strong> menu.</p>
-<p>There are six tabs in the Preferences dialog box:
+<p>There are eight tabs in the Preferences dialog box:
<ul>
<li>The <a href="#visual"><strong>"Visual"</strong>
Preferences</a> tab allows you to configure the default display for a new
<li>The <a href="#colours"><strong>"Colours"</strong>
Preferences</a> tab allows you to configure default colourschemes for a new
alignment window.</li>
+ <li>The <a href="#structure"><strong>"Structure"</strong>
+ Preferences</a> tab allows you to configure options for obtaining and displaying structure information.</li>
<li>The <a href="#connections"><strong>"Connections"</strong>
Preferences</a> tab allows you to change the links made from Jalview to
your default web browser.</li>
<p><em>Sequence ID Tooltip</em>: Control the display of Database
References and Non-positional annotation in the tooltip displayed when
the mouse is over a sequence's ID.</p>
+<p><em>Show Unconserved</em> - When this is selected, all consensus sequence
+symbols will be rendered as a '.', highlighting mutations in highly conserved alignments.</p>
<p><em>Sequence Name Italics</em> - select to apply the italicised
-vbersion of the font to sequence labels.</p>
+version of the font to sequence labels.</p>
<p><em>Smooth Font</em> - Toggles anti-aliasing on / off for faster
rendering of the alignment.</p>
-<p><em>Wrap Alignment</em> - Select whether to open new alignment
-windows in wrapped mode or not.</p>
<p><em>Gap Symbol</em> - The default gap symbol may be set to either
"-" or "."</p>
-<p><em>Sort by</em> - When the alignment is loaded in, it will can
-be sorted by Id or pairwise identity.</p>
+<p><em>Wrap Alignment</em> - Select whether to open new alignment
+windows in wrapped mode or not.</p>
+<p><em>Sort alignment by</em> - When the alignment is loaded in, it can
+be ordered as read (No sort), or sorted by Id or pairwise identity.</p>
+<p><em>Sort annotations by</em> - Annotations can be unsorted, sorted by the order of the related sequences in
+the alignment, or by label. Autocalculated annotations (e.g. Consensus) can be shown either last (below sequence
+annotations) or first (above sequence annotations). <em>Since Jalview 2.8.2.</em></p>
<p><em>Open file</em> - If this is selected then the default
alignment file will be opened when Jalview is started. You can change
the default file by clicking on file name and either typing in the file
<em>Annotation Shading Default</em> - set the default minimum
and maximum colours used when <a
href="../colourSchemes/annotationColouring.html">Colour by
- Annotation ..</a> is selected from the alignment window's colours menu.
- </p>
- <br>
+ Annotation...</a> is selected from the alignment window's colours menu.
</p>
+<p><a name="structure"><strong>"Structure"
+Preferences tab</strong></a><em> added in Jalview 2.8.2</em></p>
+<p><em>Process secondary structure from PDB</em> - if selected, then structure information
+read from PDB will be processed to derive secondary structure annotation.
+<p><em>Use RNAView for secondary structure</em> - if selected, the RNAView service will be
+automatically called to derive secondary structure information.
+<p><em>Add secondary structure annotation to alignment</em> - if selected, PDB secondary structure
+annotation will be shown on the alignment when available.
+<p><em>Add Temperature Factor annotation to alignment</em> - if selected, PDB Temperature Factor
+annotation will be shown on the alignment when available.
+<p><em>Default structure viewer</em> - choose JMOL or CHIMERA for viewing 3D structures.
+
<p><a name="connections"><strong>"Connections"
Preferences tab</strong></a></p>
<p><em>URL Link From Sequence ID</em><br>
This is a selection box which allows the user to set a default rendering
style for EPS export:
<ul>
+ <li>"Prompt each time"<br>
+ Choose this to be asked select between Lineart and Text each time you
+ make an EPS file.</li>
<li>"Lineart"<br>
EPS files will accurately reproduce the alignment view in Jalview and
all characters will be converted into line art. Files generated in this
files that can be edited easily in programs like Microsoft Word and
Adobe Illustrator, but can be problematic if the fonts available to
jalview are not accessible by the program reading the EPS file.
- <li>"Prompt each time"<br>
- Choose this to be asked select between Lineart and Text each time you
- make an EPS file.</li>
</ul>
-</p>
<p><em>Automatically set ID width</em><br>
When enabled, the column containing sequence and annotation labels at the left hand side of an exported figure will be made large enough to display each sequence ID and annotation label in its own line. Enable this if you have particularly long sequence IDs and need to generate EPS or PNG figures or web pages.</p>
<p><em>Figure ID column width</em><br>
</pre>
<p>If the boxes are left unchecked for a particular format, the
sequence limits will not be appended to the sequence id.</p>
-</p>
<p><em>Use Modeller Output</em></p>
<p>This option only applies to PIR format output. Jalview
automatically reads PIR files with sequence descriptions compatible with
write Modeller style PIR files</a> with correct start/end numbering and PDB
file association (if available). The Jalview id/start-end option is
ignored if Modeller output is selected.
+
<p><a name="editing"><strong>Editing Preferences tab</strong></a></p>
-<p>There are currently 2 options available which can be selected /
+<p>There are currently three options available which can be selected /
deselected.</p>
<p><em>AutoCalculate Consensus</em> - For large alignments it can be
useful to deselect "Autocalculate Consensus" when editing.
This prevents lengthy calculations which are performed after each
sequence edit. New alignment windows will have their "Autocalculate
Consensus" option set according to this setting.</p>
-<p><em>Pad gaps when editing</em> - New alignment windows will
+<p><em>Pad Gaps when Editing</em> - New alignment windows will
"Pad Gaps" according to this setting.</p>
+<p><em>Sort with New Tree</em> - When selected, any trees calculated or loaded onto the alignment will automatically sort the alignment.</p>
<p> </p>
<p> </p>
</body>
<tr>
<td width="17%">FASTA</td>
<td width="60%">>SequenceName<br>
-THISISASEQENCE<br></td>
+THISISASEQUENCE<br></td>
<td width="23%">.fa, .fasta</td>
</tr><tr><td width="17%">MSF</td>
<td width="60%">!! AA_MULTIPLE_ALIGNMENT 1.0<br>
>Seq2</td>
<td width="23%">.blc</td>
</tr><tr><td width="17%">PFAM</td>
-<td width="60%">SequenceName THISISASEQENCE</td>
+<td width="60%">SequenceName THISISASEQUENCE</td>
<td width="23%">.pfam</td>
</tr><tr>
<td width="17%">Stockholm</td>
</li>
<li><strong>Load Associated Tree<br> </strong><em>Jalview
can <a href="../calculations/treeviewer.html">view trees</a>
- stored in the Newick file format, and associate them with the
+ stored in the Newick file format, and associate them with the
alignment. Note: the ids of the tree file and your alignment MUST
be the same.</em></li>
<li><strong>Load Features / Annotations<br> </strong><em>Load
selected, the view will automatically scroll to display the
highlighted sequence position corresponding to the position under
the mouse pointer in a linked alignment or structure view.</em></li>
- <li><strong>Show Annotations<br> </strong><em>If this
- is selected the "Annotation Panel" will be displayed
- below the alignment. The default setting is to display the
- conservation calculation, quality calculation and consensus values
- as bar charts. </em>
- </li>
- <li><strong>Autocalculated Annotation<br> </strong><em>Settings
- for the display of autocalculated annotation.</em>
- <ul>
- <li><strong>Apply to all groups<br> </strong><em> When
- ticked, any modification to the current settings will be applied
- to all autocalculated annotation.</em></li>
- <li><strong>Show Consensus Histogram<br> </strong><em>
- Enable or disable the display of the histogram above the
- consensus sequence.</em></li>
- <li><strong>Show Consensus Logo<br> </strong><em> Enable
- or disable the display of the Consensus Logo above the consensus
- sequence.</em></li>
- <li><strong>Normalise Consensus Logo<br>
- </strong><em>When enabled, scales all logo stacks to the same height,
- making it easier to compare symbol diversity in highly variable
- regions.</em></li>
- <li><strong>Group Conservation<br> </strong><em> When
- ticked, display a conservation row for all groups (only available
- for protein alignments).</em></li>
- <li><strong>Apply to all groups<br> </strong><em> When
- ticked, display a consensus row for all groups.</em></li>
- </ul></li>
<li><strong>Show Sequence Features</strong><br> <em>Show
or hide sequence features on this alignment.</em>
</li>
- <li><strong><a href="../features/featuresettings.html">Seqence
+ <li><strong><a href="../features/featuresettings.html">Sequence
Feature Settings...</a> </strong><em><br> <em>Opens the
Sequence Feature Settings dialog box to control the colour and
display of sequence features on the alignment, and configure and
using the mouse. </em>
</li>
</ul></li>
+ <li><strong>Annotations</strong><em> (Since Jalview 2.8.2)</em>
+ <ul>
+ <li><strong>Show Annotations<br> </strong><em>If this
+ is selected the "Annotation Panel" will be displayed
+ below the alignment. The default setting is to display the
+ conservation calculation, quality calculation and consensus values
+ as bar charts. </em>
+ </li>
+ <li><strong>Show Alignment Related</strong><em><br>
+ Show all annotations that are for the alignment as a whole (for example, Consensus,
+ or secondary structure prediction from alignment).</em></li>
+ <li><strong>Hide Alignment Related</strong><em><br>
+ Hide all annotations that are for the alignment as a whole.</em></li>
+ <li><strong>Show Sequence Related</strong><em><br>
+ Show all annotations that are for individual sequences.</em></li>
+ <li><strong>Hide Sequence Related</strong><em><br>
+ Hide all annotations that are for individual sequences.</em></li>
+ <li><em>You can also selectively show or hide annotations from the <a href="./popupMenu.html">Popup</a>
+ or <a href="../features/annotation.html">Annotation</a> menus.</em></li>
+ <li><strong>Sort by Sequence</strong><em><br>Sort sequence-specific annotations by sequence order in the alignment
+ (and within that, by label).</em></li>
+ <li><strong>Sort by Label</strong><em><br>Sort sequence-specific annotations by label
+ (and within that, by sequence order). If neither sort order is selected, no sorting is applied,
+ allowing you to make a manual ordering of the annotations.</em></li>
+ <li><strong>Autocalculated Annotation<br> </strong><em>Settings
+ for the display of autocalculated annotation.</em>
+ <ul>
+ <li><strong>Show first<br></strong><em>
+ Show autocalculated annotations above sequence-specific annotations.
+ Note this also applies to other annotations for the alignment, for example secondary
+ structure prediction from alignment.</em></li>
+ <li><strong>Show last<br></strong><em>
+ Show autocalculated / alignment annotations below sequence-specific annotations.</em></li>
+ <li><strong>Apply to all groups<br> </strong><em> When
+ ticked, any modification to the current settings will be applied
+ to all autocalculated annotation.</em></li>
+ <li><strong>Show Consensus Histogram<br> </strong><em>
+ Enable or disable the display of the histogram above the
+ consensus sequence.</em></li>
+ <li><strong>Show Consensus Logo<br> </strong><em> Enable
+ or disable the display of the Consensus Logo above the consensus
+ sequence.</em></li>
+ <li><strong>Normalise Consensus Logo<br>
+ </strong><em>When enabled, scales all logo stacks to the same height,
+ making it easier to compare symbol diversity in highly variable
+ regions.</em></li>
+ <li><strong>Group Conservation<br> </strong><em> When
+ ticked, display a conservation row for all groups (only available
+ for protein alignments).</em></li>
+ <li><strong>Group Consensus<br> </strong><em> When
+ ticked, display a consensus row for all groups.</em></li>
+ </ul>
+ </li>
+ </ul>
+ </li>
<li><strong>Alignment Window Format Menu</strong>
<ul>
<li><strong>Font...<br> </strong><em>Opens the
--- /dev/null
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview 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.
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ -->
+<head>
+<title>Alignment Window Menus</title>
+</head>
+
+<body>
+<p><strong>Alignment Window Annotations Menu</strong> (Since Jalview 2.8.2)</p>
+<ul>
+ <li><strong>Show Alignment Related</strong><em><br>
+ Show all annotations that are for the alignment as a whole (for example, Consensus,
+ or secondary structure prediction from alignment)).</em></li>
+ <li><strong>Hide Alignment Related</strong><em><br>
+ Hide all annotations that are for the alignment as a whole.</em></li>
+ <li><strong>Show Sequence Related</strong><em><br>
+ Show all annotations that are for individual sequences.</em></li>
+ <li><strong>Hide Sequence Related</strong><em><br>
+ Hide all annotations that are for individual sequences.</em></li>
+ <li><strong>Show Alignment Related</strong><em><br>
+ Show all annotations that are for the alignment as a whole (for example, Consensus).</em></li>
+ <li><em>You can also selectively show or hide annotations from the <a href="./popupMenu.html">Popup</a>
+ or <a href="../features/annotation.html">Annotation</a> menus.</em></li>
+ <li><strong>Sort by Sequence</strong><em><br>Sort sequence-specific annotations by sequence order in the alignment
+ (and within that, by label).</em></li>
+ <li><strong>Sort by Label</strong><em><br>Sort sequence-specific annotations by label
+ (and within that, by sequence order). If neither sort order is selected, no sorting is applied,
+ allowing you to make a manual ordering of the annotations.</em></li>
+ <li><strong>Autocalculated Annotation<br> </strong><em>Settings
+ for the display of autocalculated annotation.</em>
+ <ul>
+ <li><strong>Show first<br></strong><em>
+ Show autocalculated annotations above sequence-specific annotations.
+ Note this also applies to other annotations for the alignment, for example secondary
+ structure prediction from alignment.</em></li>
+ <li><strong>Show last<br></strong><em>
+ Show autocalculated / alignment annotations below sequence-specific annotations.</em></li>
+ <li><strong>Apply to all groups<br> </strong><em> When
+ ticked, any modification to the current settings will be applied
+ to all autocalculated annotation.</em></li>
+ <li><strong>Show Consensus Histogram<br> </strong><em>
+ Enable or disable the display of the histogram above the
+ consensus sequence.</em></li>
+ <li><strong>Show Consensus Logo<br> </strong><em> Enable
+ or disable the display of the Consensus Logo above the consensus
+ sequence.</em></li>
+ <li><strong>Normalise Consensus Logo<br>
+ </strong><em>When enabled, scales all logo stacks to the same height,
+ making it easier to compare symbol diversity in highly variable
+ regions.</em></li>
+ <li><strong>Group Conservation<br> </strong><em> When
+ ticked, display a conservation row for all groups (only available
+ for protein alignments).</em></li>
+ <li><strong>Group Consensus<br> </strong><em> When
+ ticked, display a consensus row for all groups.</em></li>
+ </ul>
+ </li>
+</ul>
+<p> </p>
+</body>
+</html>
<li><strong> Add New Row</strong><br>
<em>Adds a new, named annotation row (a dialog box will pop up for you
to enter the label for the new row). </em> </li>
- <li><strong>Hide Row</strong><br>
- <em>Hides the annotation row whose label was clicked in order to bring
- up the menu.</em> </li>
+ <li><strong>Edit Label/Description</strong><br>
+ <em>This opens a dialog where you can change the name (displayed label), or the description
+ (as shown on the label tooltip) of the clicked annotation. </em> </li>
+ <li><strong>Hide This Row</strong><br>
+ <em>Hides the annotation row whose label was clicked in order to bring up
+ the menu.</em> </li>
+ <li><strong>Hide All <em><label></em></strong><br>
+ <em>Hides all annotation rows whose label matches the one clicked.
+ (This option is only shown for annotations that relate to individual sequences,
+ not for whole alignment annotations. Since Jalview 2.8.2.)</em> </li>
<li><strong>Delete Row</strong><br>
<em>Deletes the annotation row whose label was clicked in order to bring
up the menu.</em> </li>
All hidden Columns / Sequences / Sequences and Columns will be revealed. </em></li>
<li><strong>Hide→(all Columns / Sequences / Selected Region / All but Selected Region)</strong><em><br>
Hides the currently selected Columns / Sequences / Region or everything but the selected Region.</em></li>
- <li><strong>Show Annotations<br>
- </strong><em>If this is selected the "Annotation Panel" will be
- displayed below the alignment. The default setting is to display the conservation
- calculation, quality calculation and consensus values as bar charts. </em></li>
- <li><strong>Autocalculated Annotation<br></strong>Settings for the display of autocalculated annotation.
- <ul><li>
- <strong>Apply to all groups<br></strong>
- When ticked, any modification to the current settings will be applied to all autocalculated annotation.
- </li>
- <li>
- <strong>Show Consensus Histogram<br></strong>
- Enable or disable the display of the histogram above the consensus sequence.
- </li>
- <li>
- <strong>Show Consensus Logo<br></strong>
- Enable or disable the display of the sequence logo above the consensus sequence.
- </li>
- <li><strong>Normalise Consensus Logo<br>
- </strong><em>When enabled, scales all logo stacks to the same height,
- making it easier to compare symbol diversity in highly variable
- regions.</em></li>
-
- <li>
- <strong>Group Conservation<br></strong>
- When ticked, display a conservation row for all groups (only available for protein alignments).
- </li>
- <li>
- <strong>Apply to all groups<br></strong>
- When ticked, display a consensus row for all groups.
- </li>
- </ul>
- </li>
<li><strong>Automatic Scrolling<br>
</strong><em>When selected, the view will automatically scroll to display the
highlighted sequence position corresponding to the position under the mouse
</li>
<li><strong>Show Sequence Features</strong><br>
<em>Show or hide sequence features on this alignment.</em></li>
- <li><strong><a href="../features/featuresettings.html">Seqence Feature Settings...</a></strong><em><br>
+ <li><strong><a href="../features/featuresettings.html">Sequence Feature Settings...</a></strong><em><br>
Opens the Sequence Feature Settings dialog box to control the colour and display
of sequence features on the alignment, and configure and retrieve features
from DAS annotation servers.</em></li>
<p>The <a href="popupMenu.html">Popup Menus</a> are opened by
clicking with the right mouse button in the alignment display area or on
a sequence label in the alignment window.</p>
-<p>The <a href="alwannotations.html">Annotations Menu</a> is opened
+<p>The <a href="alwannotationpanel.html">Annotations Menu</a> is opened
by right-clicking on an annotation row label or in an annotation row.</p>
</body>
<ul>
<li><strong>Selection</strong>
<ul>
- <li><a name="sqreport"><strong>Sequence Details ...<br>
+ <li><a name="sqreport"><strong>Sequence Details...<br>
</strong></a><em>(Since Jalview 2.8)<br>Open an <a href="../io/exportseqreport.html">HTML report containing the annotation
- and database cross references</a> normally shown in the sequence's
+ and database cross references</a> normally shown in the sequence's
tooltip.</em></li>
+ <li><strong>Show Annotations...<br>
+ </strong><em>Choose to show (unhide) either All or
+ a selected type of annotation for the selected sequences. (Since Jalview 2.8.2)</em></li>
+ <li><strong>Hide Annotations...<br>
+ </strong><em>Choose to hide either All or
+ a selected type of annotation for the selected sequences. (Since Jalview 2.8.2)</em></li>
+ <li><strong>Add Reference Annotations...<br>
+ </strong><em>Add to the alignment window any annotations on the selected sequences
+ which have been read from reference sources or calculated (for example,
+ secondary structure derived from 3D structure). (Since Jalview 2.8.2)</em></li>
<li><strong>Edit </strong>
<ul>
<li><strong>Copy</strong><br>
- <em>Copys the selected region. In the applet version, the copied sequences
+ <em>Copies the selected region. In the applet version, the copied sequences
are not available to the system clipboard.</em></li>
<li><strong>Cut<br>
</strong><em>Cuts the selected region from the alignment. In the applet
(The View representative structures option was introduced in
Jalview 2.8.1)</em></li>
</ul>
- <br> <li>
-
- </li>
+ <br>
</ul>
</li>
<li><strong>Hide Sequences</strong><br>
then tries to query a subset of all the databases it can access in order to match
the alignment sequence to any records retrieved from the database. If a
match is found, then the sequence is annotated with that database's
-reference, and any cross-references that it's records contain.</p>
+reference, and any cross-references that its records contain.</p>
<p><strong>The Sequence Identification Process</strong><br>
The method of accession id discovery is derived from the method which
earlier Jalview versions used for Uniprot sequence feature retrieval,
-action.refresh_services = Refresh Services\r
-action.reset_services = Reset Services\r
-action.merge_results = Merge Results\r
-action.load_scheme = Load scheme\r
-action.save_scheme = Save scheme\r
-action.save_image = Save Image\r
-action.paste = Paste\r
-action.show_html_source = Show HTML Source\r
-action.print = Print\r
-action.web_service = Web Service\r
-action.cancel_job = Cancel Job\r
-action.start_job = Start Job\r
-action.revert = Revert\r
-action.move_down = Move Down\r
-action.move_up = Move Up\r
-action.remove_return_datatype = Remove return datatype\r
-action.add_return_datatype = Add return datatype\r
-action.remove_input_parameter = Remove selected input parameter\r
-action.add_input_parameter = Add input parameter\r
-action.edit = Edit\r
-action.new = New\r
-action.open_file = Open file\r
-action.show_unconserved = Show Unconserved\r
-action.open_new_aligmnent = Open new alignment\r
-action.raise_associated_windows = Raise Associated Windows\r
-action.minimize_associated_windows = Minimize Associated Windows\r
-action.close_all = Close all\r
-action.load_project = Load Project\r
-action.save_project = Save Project\r
-action.quit = Quit\r
-action.expand_views = Expand Views\r
-action.gather_views = Gather Views\r
-action.page_setup = Page Setup\r
-action.reload = Reload\r
-action.load = Load\r
-action.open = Open\r
-action.cancel = Cancel\r
-action.create = Create\r
-action.update = Update\r
-action.delete = Delete\r
-action.snapshot = Snapshot\r
-action.clear = Clear\r
-action.accept = Accept\r
-action.select_ddbb = --- Select Database ---\r
-action.undo = Undo\r
-action.redo = Redo\r
-action.reset = Reset\r
-action.remove_left = Remove left\r
-action.remove_right = Remove right\r
-action.remove_empty_columns = Remove Empty Columns\r
-action.remove_all_gaps = Remove All Gaps\r
-action.left_justify_alignment = Left Justify Alignment\r
-action.right_justify_alignment = Right Justify Alignment\r
-action.boxes = Boxes\r
-action.text = Text\r
-action.by_pairwise_id = by Pairwise Identity\r
-action.by_id = by Id\r
-action.by_length = by Length\r
-action.by_group = by Group\r
-action.remove = Remove\r
-action.remove_redundancy = Remove Redundancy...\r
-action.pairwise_alignment = Pairwise Alignments...\r
-action.by_rna_helixes = by RNA Helices\r
-action.user_defined = User Defined...\r
-action.by_conservation = By Conservation\r
-action.wrap = Wrap\r
-action.show_gaps = Show Gaps\r
-action.show_hidden_markers = Show Hidden Markers\r
-action.find = Find\r
-action.undefine_groups = Undefine Groups\r
-action.create_groups = Create Groups\r
-action.make_groups_selection = Make Groups For Selection\r
-action.copy = Copy\r
-action.cut = Cut\r
-action.font = Font...\r
-action.scale_above = Scale Above\r
-action.scale_left = Scale Left\r
-action.scale_right = Scale Right\r
-action.by_tree_order = By Tree Order\r
-action.sort = Sort\r
-action.calculate_tree = Calculate Tree\r
-action.help = Help\r
-action.by_annotation = by Annotation...\r
-action.invert_sequence_selection = Invert Sequence Selection\r
-action.invert_column_selection = Invert Column Selection\r
-action.show = Show\r
-action.hide = Hide\r
-action.ok = OK\r
-action.set_defaults = Defaults\r
-action.create_group = Create Group\r
-action.remove_group = Remove Group\r
-action.edit_group = Edit Group\r
-action.border_colour = Border colour\r
-action.edit_new_group = Edit New Group\r
-action.hide_sequences = Hide Sequences\r
-action.sequences = Sequences\r
-action.ids = IDS\r
-action.ids_sequences = IDS and sequences\r
-action.reveal_all = Reveal All\r
-action.reveal_sequences = Reveal Sequences\r
-action.find_all = Find all\r
-action.find_next = Find next\r
-action.file = File\r
-action.view = View\r
-action.change_params = Change Parameters\r
-action.apply = Apply\r
-action.apply_threshold_all_groups = Apply threshold to all groups\r
-action.apply_all_groups = Apply to all Groups\r
-action.by_chain = By chain\r
-action.by_sequence = By Sequence\r
-action.paste_annotations = Paste Annotations\r
-action.format = Format\r
-action.select = Select\r
-action.new_view = New View\r
-action.close = Close\r
-action.add = Add\r
-action.save_as_default = Save as default\r
-action.save_as = Save as\r
-action.save = Save\r
-action.cancel_fetch = Cancel Fetch\r
-action.save_omit_hidden_columns = Save / Omit Hidden Columns\r
-action.change_font = Change Font\r
-action.change_font_tree_panel = Change Font (Tree Panel)\r
-action.colour = Colour\r
-action.calculate = Calculate\r
-action.select_all = Select all\r
-action.deselect_all = Deselect all\r
-action.invert_selection = Invert selection\r
-action.using_jmol = Using Jmol\r
-action.link = Link\r
-action.group_link = Group Links\r
-action.show_chain = Show Chain\r
-action.show_group = Show Group\r
-action.fetch_db_references = Fetch DB References\r
-action.edit = Edit\r
-action.view_flanking_regions = Show flanking regions\r
-label.view_flanking_regions = Show sequence data either side of the subsequences involved in this alignment\r
-label.str = Str:\r
-label.seq = Seq:\r
-label.structures_manager = Structures Manager\r
-label.nickname = Nickname:\r
-label.url = URL:\r
-label.input_file_url = Enter URL or Input File\r
-label.select_feature = Select feature:\r
-label.name = Name\r
-label.name_param = Name: {0}\r
-label.group = Group\r
-label.group_name = Group Name\r
-label.group_description = Group Description\r
-label.edit_group_name_description = Edit Group Name/Description\r
-label.colour = Colour:\r
-label.description = Description:\r
-label.start = Start:\r
-label.end = End:\r
-label.current_parameter_set_name = Current parameter set name:\r
-label.service_action = Service Action:\r
-label.post_url = POST URL:\r
-label.url_suffix = URL Suffix\r
-label.sequence_source = Sequence Source\r
-label.per_seq = per Sequence\r
-label.result_vertically_separable = Results are vertically separable\r
-label.amend = Amend\r
-label.undo_command = Undo {0}\r
-label.redo_command = Redo {0}\r
-label.principal_component_analysis = Principal Component Analysis\r
-label.average_distance_identity = Average Distance Using % Identity\r
-label.neighbour_joining_identity = Neighbour Joining Using % Identity\r
-label.treecalc_title = {0} Using {1}\r
-label.tree_calc_av = Average Distance\r
-label.tree_calc_nj = Neighbour Joining\r
-label.select_score_model = Select score model\r
-label.score_model_pid = % Identity\r
-label.score_model_blosum62 = BLOSUM62\r
-label.score_model_pam250 = PAM 250\r
-label.score_model_conservation = Physicochemical property conservation\r
-label.score_model_enhconservation = Physicochemical property conservation\r
-label.status_bar = Status bar\r
-label.out_to_textbox = Output to Textbox\r
-label.clustalx = Clustalx\r
-label.clustal = Clustal\r
-label.zappo = Zappo\r
-label.taylor = Taylor\r
-label.blc = BLC\r
-label.fasta = Fasta\r
-label.msf = MSF\r
-label.pfam = PFAM\r
-label.pileup = Pileup\r
-label.pir = PIR\r
-label.hydrophobicity = Hydrophobicity\r
-label.helix_propensity = Helix Propensity\r
-label.strand_propensity = Strand Propensity\r
-label.turn_propensity = Turn Propensity\r
-label.buried_index = Buried Index\r
-label.purine_pyrimidine = Purine/Pyrimidine\r
-label.percentage_identity = Percentage Identity\r
-label.blosum62 = BLOSUM62\r
-label.blosum62_score = BLOSUM62 Score\r
-label.tcoffee_scores = T-Coffee Scores\r
-label.average_distance_bloslum62 = Average Distance Using BLOSUM62\r
-label.neighbour_blosum62 = Neighbour Joining Using BLOSUM62\r
-label.show_annotations = Show annotations\r
-label.colour_text = Colour Text\r
-label.show_non_conversed = Show nonconserved\r
-label.overview_window = Overview Window\r
-label.none = None\r
-label.above_identity_threshold = Above Identity Threshold\r
-label.show_sequence_features = Show Sequence Features\r
-label.nucleotide = Nucleotide\r
-label.to_new_alignment = To New Alignment\r
-label.to_this_alignment = Add To This Alignment\r
-label.apply_colour_to_all_groups = Apply Colour To All Groups\r
-label.modify_identity_thereshold = Modify Identity Threshold...\r
-label.modify_conservation_thereshold = Modify Conservation Threshold...\r
-label.input_from_textbox = Input from textbox\r
-label.centre_column_labels = Centre column labels\r
-label.automatic_scrolling = Automatic Scrolling\r
-label.documentation = Documentation\r
-label.about = About...\r
-label.show_sequence_limits = Show Sequence Limits\r
-label.feature_settings = Feature Settings...\r
-label.sequence_features = Sequence Features\r
-label.all_columns = All Columns\r
-label.all_sequences = All Sequences\r
-label.selected_columns = Selected Columns \r
-label.selected_sequences = Selected Sequences\r
-label.all_but_selected_region = All but Selected Region (Shift+Ctrl+H)\r
-label.selected_region = Selected Region\r
-label.all_sequences_columns = All Sequences and Columns\r
-label.group_consensus = Group Consensus\r
-label.group_conservation = Group Conservation\r
-label.show_consensus_histogram = Show Consensus Histogram\r
-label.show_consensus_logo = Show Consensus Logo\r
-label.norm_consensus_logo = Normalise Consensus Logo\r
-label.apply_all_groups = Apply to all groups\r
-label.autocalculated_annotation = Autocalculated Annotation\r
-label.min_colour = Minimum Colour\r
-label.max_colour = Maximum Colour\r
-label.use_original_colours = Use Original Colours\r
-label.threshold_minmax = Threshold is min/max\r
-label.represent_group_with = Represent Group with {0}\r
-label.selection = Selection\r
-label.group_colour = Group Colour\r
-label.sequence = Sequence\r
-label.view_pdb_structure = View PDB Structure\r
-label.min = Min:\r
-label.max = Max:\r
-label.colour_by_label = Colour by label\r
-label.new_feature = New Feature\r
-label.match_case = Match Case\r
-label.view_alignment_editor = View in alignment editor\r
-label.labels = Labels\r
-label.output_values = Output Values...\r
-label.output_points = Output points...\r
-label.output_transformed_points = Output transformed points\r
-label.input_data = Input Data...\r
-label.nucleotide_matrix = Nucleotide matrix\r
-label.protein_matrix = Protein matrix\r
-label.show_bootstrap_values = Show Bootstrap Values\r
-label.show_distances = Show distances\r
-label.mark_unassociated_leaves = Mark Unassociated Leaves\r
-label.fit_to_window = Fit To Window\r
-label.newick_format = Newick Format\r
-label.select_newick_like_tree_file = Select a newick-like tree file\r
-label.colours = Colours\r
-label.view_mapping = View Mapping\r
-label.wireframe = Wireframe\r
-label.depthcue = Depthcue\r
-label.z_buffering = Z Buffering\r
-label.charge_cysteine = Charge & Cysteine\r
-label.all_chains_visible = All Chains Visible\r
-label.successfully_added_features_alignment = Successfully added features to alignment\r
-label.keyboard_editing_mode = Keyboard editing mode is {0}\r
-label.paste_features_annotations_Tcoffee_here = Paste your features / annotations / T-coffee score file here.\r
-label.removed_columns = Removed {0} columns.\r
-label.removed_empty_columns = Removed {0} empty columns.\r
-label.paste_newick_tree_file = Paste your Newick tree file here.\r
-label.order_by_params = Order by {0}\r
-label.html_content = <html>{0}</html>\r
-label.paste_pdb_file= Paste your PDB file here.\r
-label.paste_pdb_file_for_sequence = Paste PDB file for sequence {0}\r
-label.could_not_parse_newick_file = Could not parse Newick file\!\n {0}\r
-label.successfully_pasted_tcoffee_scores_to_alignment= Successfully pasted T-Coffee scores to alignment.\r
-label.failed_add_tcoffee_scores = Failed to add T-Coffee scores: \r
-label.successfully_pasted_annotation_to_alignment= Successfully pasted annotation to alignment.\r
-label.couldnt_parse_pasted_text_as_valid_annotation_feature_GFF_tcoffee_file = Couldn't parse pasted text as a valid annotation, feature, GFF, or T-Coffee score file\r
-label.successfully_pasted_alignment_file = Successfully pasted alignment file\r
-label.paste_your_alignment_file = Paste your alignment file here\r
-label.paste_your = Paste your\r
-label.finished_searching = Finished searching\r
-label.search_results= Search results {0} : {1}\r
-label.found_match_for = Found match for {0}\r
-label.font = Font:\r
-label.size = Size:\r
-label.style = Style:\r
-label.enter_redundancy_threshold = Enter the redundancy threshold\r
-label.calculating = Calculating....\r
-label.modify_conservation_visibility = Modify conservation visibility\r
-label.colour_residues_above_occurence = Colour residues above % occurence\r
-label.set_this_label_text = set this label text\r
-label.sequences_from = Sequences from {0}\r
-label.successfully_loaded_file = Successfully loaded file {0}\r
-label.successfully_saved_to_file_in_format = Successfully saved to file: {0} in {1} format.\r
-label.copied_sequences_to_clipboard = Copied {0} sequences to clipboard.\r
-label.check_file_matches_sequence_ids_alignment = Check that the file matches sequence IDs in the alignment.\r
-label.problem_reading_tcoffee_score_file = Problem reading T-COFFEE score file\r
-label.source_to_target = {0} ... {1}\r
-label.per_sequence_only= Per-sequence only\r
-label.to_file = to File\r
-label.to_textbox = to Textbox\r
-label.jalview = Jalview\r
-label.csv_spreadsheet = CSV (Spreadsheet)\r
-label.status = [Status]\r
-label.channels = Channels\r
-label.channel_title_item_count = {0} ({1})\r
-label.blog_item_published_on_date = {0} {1} \r
-label.select_das_service_from_table = Select a DAS service from the table to read a full description here.</font></html>\r
-label.session_update = Session Update\r
-label.new_vamsas_session = New Vamsas Session\r
-label.load_vamsas_session = Load Vamsas Session\r
-label.save_vamsas_session = Save Vamsas Session\r
-label.select_vamsas_session_opened_as_new_vamsas_session= Select a vamsas session to be opened as a new vamsas session.\r
-label.open_saved_vamsas_session = Open a saved VAMSAS session\r
-label.groovy_console = Groovy Console...\r
-label.lineart = Lineart\r
-label.dont_ask_me_again = Don't ask me again\r
-label.select_eps_character_rendering_style = Select EPS character rendering style\r
-label.invert_selection = Invert Selection\r
-label.optimise_order = Optimise Order\r
-label.seq_sort_by_score = Seq sort by Score\r
-label.load_colours = Load Colours\r
-label.save_colours = Save Colours\r
-label.fetch_das_features = Fetch DAS Features\r
-label.selected_database_to_fetch_from = Selected {0} database {1} to fetch from {2} \r
-label.database_param = Database: {0}\r
-label.example = Example\r
-label.example_param = Example: {0}\r
-label.select_file_format_before_saving = You must select a file format before saving!\r
-label.file_format_not_specified = File format not specified\r
-label.alignment_contains_hidden_columns = The Alignment contains hidden columns.\nDo you want to save only the visible alignment?\r
-label.couldnt_save_file = Couldn't save file: {0}\r
-label.error_saving_file = Error Saving File\r
-label.remove_from_default_list = Remove from default list?\r
-label.remove_user_defined_colour = Remove user defined colour\r
-label.you_must_select_least_two_sequences = You must select at least 2 sequences.\r
-label.invalid_selection = Invalid Selection\r
-label.principal_component_analysis_must_take_least_four_input_sequences = Principal component analysis must take\nat least 4 input sequences.\r
-label.sequence_selection_insufficient = Sequence selection insufficient\r
-label.you_need_more_two_sequences_selected_build_tree = You need to have more than two sequences selected to build a tree!\r
-label.not_enough_sequences = Not enough sequences\r
-label.selected_region_to_tree_may_only_contain_residues_or_gaps = The selected region to create a tree may\nonly contain residues or gaps.\nTry using the Pad function in the edit menu,\nor one of the multiple sequence alignment web services.\r
-label.sequences_selection_not_aligned = Sequences in selection are not aligned\r
-label.sequences_must_be_aligned_before_creating_tree = The sequences must be aligned before creating a tree.\nTry using the Pad function in the edit menu,\n or one of the multiple sequence alignment web services.\r
-label.sequences_not_aligned = Sequences not aligned\r
-label.problem_reading_tree_file = Problem reading tree file\r
-label.possible_problem_with_tree_file = Possible problem with tree file\r
-label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation = Please select at least three bases in at least one sequence in order to perform a cDNA translation.\r
-label.translation_failed = Translation Failed\r
-label.error_when_translating_sequences_submit_bug_report = Unfortunately, something went wrong when translating your sequences.\nPlease take a look in the Jalview java console\nand submit a bug report including the stacktrace.\r
-label.implementation_error = Implementation error:\r
-label.automatically_associate_pdb_files_with_sequences_same_name = Do you want to automatically associate the {0} PDB files with sequences in the alignment that have the same name?\r
-label.automatically_associate_pdb_files_by_name = Automatically Associate PDB files by name\r
-label.ignore_unmatched_dropped_files_info = <html>Do you want to <em>ignore</em> the {0} files whose names did not match any sequence IDs ?</html>\r
-label.ignore_unmatched_dropped_files = Ignore unmatched dropped files?\r
-label.enter_view_name = Enter View Name\r
-label.enter_label = Enter label\r
-label.enter_label_for_the_structure = Enter a label for the structure?\r
-label.pdb_entry_is_already_displayed = {0} is already displayed.\nDo you want to re-use this viewer ?\r
-label.map_sequences_to_visible_window = Map Sequences to Visible Window: {0}\r
-label.add_pdbentry_to_view = Do you want to add {0} to the view called\n'{1}'\n\r
-label.align_to_existing_structure_view = Align to existing structure view\r
-label.pdb_entries_couldnt_be_retrieved = The following pdb entries could not be retrieved from the PDB\:\n{0}\nPlease try downloading them manually.\r
-label.couldnt_load_file = Couldn't load file\r
-label.couldnt_find_pdb_id_in_file = Couldn't find a PDB id in the file supplied. Please enter an Id to identify this structure.\r
-label.no_pdb_id_in_file = No PDB Id in File\r
-label.couldnt_read_pasted_text = Couldn't read the pasted text {0}\r
-label.error_parsing_text = Error parsing text\r
-label.enter_local_das_source = Enter Nickname & URL of Local DAS Source\r
-label.you_can_only_edit_or_remove_local_das_sources = You can only edit or remove local DAS Sources!\r
-label.public_das_source = Public DAS source - not editable\r
-label.input_alignment_from_url = Input Alignment From URL\r
-label.input_alignment = Input Alignment\r
-label.couldnt_import_as_vamsas_session = Couldn't import '{0}' as a new vamsas session.\r
-label.vamsas_document_import_failed = Vamsas Document Import Failed\r
-label.couldnt_locate = Couldn't locate {0}\r
-label.url_not_found = URL not found\r
-label.no_link_selected = No link selected\r
-label.new_sequence_url_link = New sequence URL link\r
-label.cannot_edit_annotations_in_wrapped_view = Cannot edit annotations in wrapped view\r
-label.wrapped_view_no_edit = Wrapped view - no edit\r
-label.error_retrieving_data = Error Retrieving Data\r
-label.user_colour_scheme_must_have_name = User colour scheme must have a name\r
-label.no_name_colour_scheme = No name for colour scheme\r
-label.invalid_url = Invalid URL !\r
-label.error_loading_file = Error loading file\r
-label.problems_opening_file = Encountered problems opening {0}!!\r
-label.file_open_error = File open error\r
-label.no_das_sources_selected_warn = No das sources were selected.\nPlease select some sources and\ntry again.\r
-label.no_das_sources_selected_title = No DAS Sources Selected\r
-label.colour_scheme_exists_overwrite = Colour scheme {0} exists.\nContinue saving colour scheme as {1}?"\r
-label.duplicate_scheme_name = Duplicate scheme name\r
-label.jalview_new_questionnaire = There is a new Questionnaire available. Would you like to complete it now ?\n\r
-label.jalview_user_survey = Jalview User Survey\r
-label.alignment_properties = Alignment Properties: {0}\r
-label.alignment_props = Alignment Properties\r
-label.input_cut_paste = Cut & Paste Input\r
-label.input_cut_paste_params = Cut & Paste Input - {0}\r
-label.alignment_output_command = Alignment output - {0}\r
-label.annotations = Annotations\r
-label.features = Features\r
-label.overview_params = Overview {0}\r
-label.paste_newick_file = Paste Newick file\r
-label.load_tree_from_file = From File - \r
-label.colour_by_annotation = Colour by Annotation\r
-label.selection_output_command = Selection output - {0}\r
-label.annotation_for_displayid = <p><h2>Annotation for {0} </h2></p><p>\r
-label.pdb_sequence_mapping = PDB - Sequence Mapping\r
-label.pca_details = PCA details\r
-label.redundancy_threshold_selection = Redundancy threshold selection\r
-label.user_defined_colours = User defined colours\r
-label.jalviewLite_release = JalviewLite - Release {0}\r
-label.jaview_build_date = Build date: {0}\r
-label.jalview_authors_1 = Authors: : Jim Procter, Andrew Waterhouse, Lauren Lui, Jan Engelhardt, Natasha Sherstnev,\r
-label.jalview_authors_2 = Daniel Barton, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton.\r
-label.jalview_dev_managers = Development managed by The Barton Group, University of Dundee, Scotland, UK.\r
-label.jalview_distribution_lists = For help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list\r
-label.jalview_please_cite = If you use Jalview, please cite:\r
-label.jalview_cite_1_authors = Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)\r
-label.jalview_cite_1_title = Jalview Version 2 - a multiple sequence alignment editor and analysis workbench\r
-label.jalview_cite_1_ref = Bioinformatics doi: 10.1093/bioinformatics/btp033\r
-label.right_click = Right click\r
-label.to_add_annotation = to add annotation\r
-label.alignment_has_no_annotations = Alignment has no annotations\r
-label.retrieving_pdb_data = Retrieving PDB data...\r
-label.label = Label\r
-label.no_features_added_to_this_alignment = No Features added to this alignment!!\r
-label.features_can_be_added_from_searches_1 = (Features can be added from searches or\r
-label.features_can_be_added_from_searches_2 = from Jalview / GFF features files)\r
-label.calculating_pca= Calculating PCA\r
-label.reveal_columns = Reveal Columns\r
-label.jalview_cannot_open_file = Jalview can't open file\r
-label.jalview_applet = Jalview applet\r
-label.loading_data = Loading data\r
-label.memory_stats = Total Free Memory: {0} MB; Max Memory: {1} MB; {2} %\r
-label.calculating_tree = Calculating tree\r
-label.state_queueing = queuing\r
-label.state_running = running\r
-label.state_complete = complete\r
-label.state_completed = finished\r
-label.state_job_cancelled = job cancelled!!\r
-label.state_job_error = job error!\r
-label.server_error_try_later = Server Error! (try later)\r
-label.error_loading_pdb_data = Error loading PDB data!!\r
-label.fetching_pdb_data = Fetching PDB data...\r
-label.structure_type = Structure type\r
-label.settings_for_type = Settings for {0}\r
-label.view_full_application = View in Full Application\r
-label.load_associated_tree = Load Associated Tree ...\r
-label.load_features_annotations = Load Features/Annotations ...\r
-label.export_features = Export Features ...\r
-label.export_annotations = Export Annotations ...\r
-label.jalview_copy = Copy (Jalview Only)\r
-label.jalview_cut = Cut (Jalview Only)\r
-label.to_upper_case = To Upper Case\r
-label.to_lower_case = To Lower Case\r
-label.toggle_case = Toggle Case\r
-label.edit_name_description = Edit Name/Description ...\r
-label.create_sequence_feature = Create Sequence Feature ...\r
-label.edit_sequence = Edit Sequence\r
-label.edit_sequences = Edit Sequences\r
-label.sequence_details = Sequence Details\r
-label.jmol_help = Jmol Help\r
-label.all = All\r
-label.sort_by = Sort by\r
-label.sort_by_score = Sort by Score\r
-label.sort_by_density = Sort by Density\r
-label.sequence_sort_by_density = Sequence sort by Density\r
-label.reveal = Reveal\r
-label.hide_columns = Hide Columns\r
-label.load_jalview_annotations = Load Jalview Annotations or Features File\r
-label.load_tree_file = Load a tree file\r
-label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences = Retrieve and parse sequence database records for the alignment or the currently selected sequences\r
-label.standard_databases = Standard Databases\r
-label.fetch_embl_uniprot = Fetch from EMBL/EMBLCDS or Uniprot/PDB and any selected DAS sources\r
-label.reset_min_max_colours_to_defaults = Reset min and max colours to defaults from user preferences.\r
-label.align_structures_using_linked_alignment_views = Align structures using {0} linked alignment views\r
-label.connect_to_session = Connect to session {0}\r
-label.threshold_feature_display_by_score = Threshold the feature display by score.\r
-label.threshold_feature_no_thereshold = No Threshold\r
-label.threshold_feature_above_thereshold = Above Threshold\r
-label.threshold_feature_below_thereshold = Below Threshold\r
-label.adjust_thereshold = Adjust threshold\r
-label.toggle_absolute_relative_display_threshold = Toggle between absolute and relative display threshold.\r
-label.display_features_same_type_different_label_using_different_colour = Display features of the same type with a different label using a different colour. (e.g. domain features)\r
-label.select_colour_minimum_value = Select Colour for Minimum Value\r
-label.select_colour_maximum_value = Select Colour for Maximum Value\r
-label.open_new_jmol_view_with_all_structures_associated_current_selection_superimpose_using_alignment = Open a new Jmol view with all structures associated with the current selection and superimpose them using the alignment.\r
-label.open_url_param = Open URL {0}\r
-label.open_url_seqs_param = Open URL ({0}..) ({1} seqs)\r
-label.load_pdb_file_associate_with_sequence = Load a PDB file and associate it with sequence '{0}'\r
-label.reveal_hidden_columns = Reveal Hidden Columns with Right Mouse Button\r
-label.dark_colour = Dark Colour\r
-label.light_colour = Light Colour\r
-label.highlightnode = Left click to select leaves.<br>Double-click to invert leaves.<br>Right click to change colour.\r
-label.load_colour_scheme = Load colour scheme\r
-label.toggle_enabled_views = When enabled, allows many views to be selected.\r
-label.edit_notes_parameter_set = Click to edit the notes for this parameter set.\r
-label.open_local_file = Open local file\r
-label.enable_automatically_sort_alignment_when_open_new_tree = Enable this to automatically sort<br>the alignment when you open<br> a new tree.\r
-label.listen_for_selections = Listen for selections\r
-label.selections_mirror_selections_made_same_sequences_other_views = When selected, selections in this view will mirror<br>selections made on the same sequences in other views.\r
-label.toggle_sequence_visibility = Shift+H toggles sequence visiblity\r
-label.toggle_columns_visibility = Ctrl+H toggles column visiblity.\r
-label.toggles_visibility_hidden_selected_regions = H toggles visibility of hidden or selected regions\r
-label.rename_tab_eXpand_reGroup= Right-click to rename tab <br> Press X to eXpand tabs, G to reGroup.\r
-label.right_align_sequence_id = Right Align Sequence Id\r
-label.sequence_id_tooltip = Sequence ID Tooltip\r
-label.no_services = <No Services>\r
-label.select_copy_raw_html = Select this if you want to copy raw html\r
-label.share_data_vamsas_applications = Share data with other vamsas applications\r
-label.connect_to = Connect to\r
-label.join_existing_vamsas_session = Join an existing vamsas session\r
-label.from_url = from URL\r
-label.any_trees_calculated_or_loaded_alignment_automatically_sort = When selected, any trees calculated or loaded onto the alignment will automatically sort the alignment\r
-label.sort_with_new_tree = Sort With New Tree\r
-label.from_textbox = from Textbox\r
-label.window = Window\r
-label.preferences = Preferences\r
-label.tools = Tools\r
-label.fetch_sequences = Fetch Sequence(s)\r
-label.stop_vamsas_session = Stop Vamsas Session\r
-label.collect_garbage = Collect Garbage\r
-label.show_memory_usage = Show Memory Usage\r
-label.show_java_console = Show Java Console\r
-label.show_jalview_news = Show Jalview News\r
-label.monospaced_fonts_faster_to_render = Monospaced fonts are faster to render\r
-label.anti_alias_fonts = Anti-alias Fonts (Slower to render)\r
-label.monospaced_font= Monospaced\r
-label.quality = Quality\r
-label.maximize_window = Maximize Window\r
-label.conservation = Conservation\r
-label.consensus = Consensus\r
-label.histogram = Histogram\r
-label.logo = Logo\r
-label.non_positional_features = Non-positional Features\r
-label.database_references = Database References\r
-label.share_selection_across_views = Share selection across views\r
-label.scroll_highlighted_regions = Scroll to highlighted regions\r
-label.gap_symbol = Gap Symbol\r
-label.alignment_colour = Alignment Colour\r
-label.address = Address\r
-label.port = Port\r
-label.default_browser_unix = Default Browser (Unix)\r
-label.send_usage_statistics = Send usage statistics\r
-label.check_for_questionnaires = Check for questionnaires\r
-label.check_for_latest_version = Check for latest version\r
-label.url_linkfrom_sequence_id = URL link from Sequence ID\r
-label.use_proxy_server = Use a proxy server\r
-label.eps_rendering_style = EPS rendering style\r
-label.append_start_end = Append /start-end (/15-380)\r
-label.full_sequence_id = Full Sequence Id\r
-label.smooth_font = Smooth Font\r
-label.autocalculate_consensus = AutoCalculate Consensus\r
-label.pad_gaps = Pad Gaps\r
-label.pad_gaps_when_editing = Pad Gaps When Editing\r
-label.automatically_set_id_width = Automatically set ID width\r
-label.figure_id_column_width = Figure ID column width\r
-label.use_modeller_output = Use Modeller Output\r
-label.wrap_alignment = Wrap Alignment\r
-label.right_align_ids = Right Align Ids\r
-label.sequence_name_italics = Sequence Name Italics\r
-label.open_overview = Open Overview\r
-label.default_colour_scheme_for_alignment = Default Colour Scheme for alignment\r
-label.annotation_shading_default = Annotation Shading Default\r
-label.default_minimum_colour_annotation_shading = Default Minimum Colour for annotation shading\r
-label.default_maximum_colour_annotation_shading = Default Maximum Colour for annotation shading\r
-label.visual = Visual\r
-label.connections = Connections\r
-label.output = Output\r
-label.editing = Editing\r
-label.das_settings = DAS Settings\r
-label.web_services = Web Services\r
-label.right_click_to_edit_currently_selected_parameter = Right click to edit currently selected parameter.\r
-label.let_jmol_manage_structure_colours = Let Jmol manage structure colours\r
-label.marks_leaves_tree_not_associated_with_sequence = Marks leaves of tree not associated with a sequence\r
-label.index_web_services_menu_by_host_site = Index web services in menu by the host site\r
-label.option_want_informed_web_service_URL_cannot_be_accessed_jalview_when_starts_up = Check this option if you want to be informed<br>when a web service URL cannot be accessed by Jalview<br>when it starts up\r
-label.new_service_url = New Service URL\r
-label.edit_service_url = Edit Service URL\r
-label.delete_service_url = Delete Service URL\r
-label.details = Details\r
-label.options = Options\r
-label.parameters = Parameters\r
-label.available_das_sources = Available DAS Sources\r
-label.full_details = Full Details\r
-label.authority = Authority\r
-label.type = Type\r
-label.proxy_server = Proxy Server\r
-label.file_output = File Output\r
-label.select_input_type = Select input type\r
-label.set_options_for_type = Set options for type\r
-label.data_input_parameters = Data input parameters\r
-label.data_returned_by_service = Data returned by service\r
-label.rsbs_encoded_service = RSBS Encoded Service\r
-label.parsing_errors = Parsing errors\r
-label.simple_bioinformatics_rest_services = Simple Bioinformatics Rest Services\r
-label.web_service_discovery_urls = Web Service Discovery URLS\r
-label.input_parameter_name = Input Parameter name\r
-label.short_descriptive_name_for_service = Short descriptive name for service\r
-label.function_service_performs = What kind of function the service performs (e.g. alignment, analysis, search, etc).\r
-label.brief_description_service = Brief description of service\r
-label.url_post_data_service = URL to post data to service. Include any special parameters needed here\r
-label.optional_suffix = Optional suffix added to URL when retrieving results from service\r
-label.preferred_gap_character = Which gap character does this service prefer?\r
-label.gap_character = Gap character\r
-label.move_return_type_up_order= Move return type up order\r
-label.move_return_type_down_order= Move return type down order\r
-label.update_user_parameter_set = Update this existing user parameter set\r
-label.delete_user_parameter_set = Delete the currently selected user parameter set\r
-label.create_user_parameter_set = Create a new parameter set with the current settings.\r
-label.revert_changes_user_parameter_set = Undo all changes to the current parameter set\r
-label.start_job_current_settings = Start Job with current settings\r
-label.cancel_job_close_dialog = Close this dialog and cancel job\r
-label.input_output = Input/Output\r
-label.cut_paste = Cut'n'Paste\r
-label.adjusting_parameters_for_calculation = Adjusting parameters for existing Calculation\r
-label.2d_rna_structure_line = 2D RNA {0}\r
-label.2d_rna_sequence_name = 2D RNA - {0}\r
-label.edit_name_and_description_current_group = Edit name and description of current group.\r
-label.view_structure_for = View structure for {0}\r
-label.view_all_structures = View all {0} structures.\r
-label.view_all_representative_structures = View all {0} representative structures.\r
-label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment = Opens a new Jmol view with all representative structures\nassociated with the current selection\nsuperimposed with the current alignment.\r
-label.associate_structure_with_sequence = Associate Structure with Sequence\r
-label.from_file = from file\r
-label.enter_pdb_id = Enter PDB Id\r
-label.discover_pdb_ids = Discover PDB ids\r
-label.text_colour = Text Colour\r
-label.structure = Structure\r
-label.view_structure = View Structure\r
-label.clustalx_colours = Clustalx colours\r
-label.above_identity_percentage = Above % Identity\r
-label.create_sequence_details_report_annotation_for = Annotation for {0}\r
-label.sequece_details_for = Sequece Details for {0}\r
-label.sequence_name = Sequence Name\r
-label.sequence_description = Sequence Description\r
-label.edit_sequence_name_description = Edit Sequence Name/Description\r
-label.spaces_converted_to_backslashes = Spaces have been converted to _\r
-label.no_spaces_allowed_sequence_name = No spaces allowed in Sequence Name\r
-label.select_outline_colour = Select Outline Colour\r
-label.web_browser_not_found_unix = Unixers\: Couldn't find default web browser.\nAdd the full path to your browser in Preferences."\r
-label.web_browser_not_found = Web browser not found\r
-label.select_pdb_file_for = Select a PDB file for {0}\r
-label.html = HTML\r
-label.wrap = Wrap\r
-label.show_database_refs = Show Database Refs\r
-label.show_non_positional_features = Show Non-Positional Features\r
-label.save_png_image = Save As PNG Image\r
-label.load_tree_for_sequence_set = Load a tree for this sequence set\r
-label.export_image = Export Image\r
-label.vamsas_store = VAMSAS store\r
-label.translate_cDNA = Translate cDNA\r
-label.extract_scores = Extract Scores\r
-label.get_cross_refs = Get Cross References\r
-label.sort_alignment_new_tree = Sort Alignment With New Tree\r
-label.add_sequences = Add Sequences\r
-label.new_window = New Window\r
-label.refresh_available_sources = Refresh Available Sources\r
-label.use_registry = Use Registry\r
-label.add_local_source = Add Local Source\r
-label.set_as_default = Set as Default\r
-label.show_labels = Show labels\r
-label.background_colour = Background Colour\r
-label.associate_nodes_with = Associate Nodes With\r
-label.jalview_pca_calculation = Jalview PCA Calculation\r
-label.link_name = Link Name\r
-label.pdb_file = PDB file\r
-label.colour_with_jmol = Colour with Jmol\r
-label.align_structures = Align structures\r
-label.jmol = Jmol\r
-label.sort_alignment_by_tree = Sort Alignment By Tree\r
-label.mark_unlinked_leaves = Mark Unlinked Leaves\r
-label.associate_leaves_with = Associate Leaves With\r
-label.save_colour_scheme_with_unique_name_added_to_colour_menu = Save your colour scheme with a unique name and it will be added to the Colour menu\r
-label.case_sensitive = Case Sensitive\r
-label.lower_case_colour = Lower Case Colour\r
-label.index_by_host = Index by host\r
-label.index_by_type = Index by type\r
-label.enable_jabaws_services = Enable JABAWS Services\r
-label.display_warnings = Display warnings\r
-label.move_url_up = Move URL up\r
-label.move_url_down = Move URL down\r
-label.add_sbrs_definition = Add a SBRS definition\r
-label.edit_sbrs_definition = Edit SBRS definition\r
-label.delete_sbrs_definition = Delete SBRS definition\r
-label.your_sequences_have_been_verified = Your sequences have been verified against known sequence databases. Some of the ids have been\n altered, most likely the start/end residue will have been updated.\n Save your alignment to maintain the updated id.\n\n\r
-label.sequence_names_updated = Sequence names updated\r
-label.dbref_search_completed = DBRef search completed\r
-label.show_all_chains = Show all chains\r
-label.fetch_all_param = Fetch all {0}\r
-label.paste_new_window = Paste To New Window\r
-label.settings_for_param = Settings for {0}\r
-label.view_params = View {0}\r
-label.select_all_views = Select all views\r
-label.align_sequences_to_existing_alignment = Align sequences to an existing alignment\r
-label.realign_with_params = Realign with {0}\r
-label.calcname_with_default_settings = {0} with Defaults\r
-label.action_with_default_settings = {0} with default settings\r
-label.edit_settings_and_run = Edit settings and run...\r
-label.view_and_change_parameters_before_alignment = View and change the parameters before alignment\r
-label.run_with_preset_params = Run {0} with preset\r
-label.view_and_change_parameters_before_running_calculation = View and change parameters before running calculation\r
-label.view_documentation = View documentation\r
-label.select_return_type = Select return type\r
-label.translation_of_params = Translation of {0}\r
-label.features_for_params = Features for - {0}\r
-label.annotations_for_params = Annotations for - {0}\r
-label.generating_features_for_params = Generating features for - {0}\r
-label.generating_annotations_for_params = Generating annotations for - {0}\r
-label.varna_params = VARNA - {0}\r
-label.sequence_feature_settings = Sequence Feature Settings\r
-label.pairwise_aligned_sequences = Pairwise Aligned Sequences\r
-label.original_data_for_params = Original Data for {0}\r
-label.points_for_params = Points for {0}\r
-label.transformed_points_for_params = Transformed points for {0}\r
-label.graduated_color_for_params = Graduated Feature Colour for {0}\r
-label.select_backgroud_colour = Select Background Colour\r
-label.invalid_font = Invalid Font\r
-label.separate_multiple_accession_ids = Separate multiple accession ids with semi colon ";"\r
-label.replace_commas_semicolons = Replace commas with semi-colons\r
-label.parsing_failed_syntax_errors_shown_below_param = Parsing failed. Syntax errors shown below {0}\r
-label.parsing_failed_unrecoverable_exception_thrown_param = \nParsing failed. An unrecoverable exception was thrown:\n {0}\r
-label.example_query_param = Example query: {0}\r
-label.enter_value_increase_conservation_visibility = Enter value to increase conservation visibility\r
-label.enter_percentage_identity_above_which_colour_residues = Enter % identity above which to colour residues\r
-label.wswublast_client_credits = To display sequence features an exact Uniprot id with 100% sequence identity match must be entered.\nIn order to display these features, try changing the names of your sequences to the ids suggested below.\n\nRunning WSWUBlast at EBI.\nPlease quote Pillai S., Silventoinen V., Kallio K., Senger M., Sobhany S., Tate J., Velankar S., Golovin A., Henrick K., Rice P., Stoehr P., Lopez R.\nSOAP-based services provided by the European Bioinformatics Institute.\nNucleic Acids Res. 33(1):W25-W28 (2005));\r
+action.refresh_services = Refresh Services
+action.reset_services = Reset Services
+action.merge_results = Merge Results
+action.load_scheme = Load scheme
+action.save_scheme = Save scheme
+action.save_image = Save Image
+action.paste = Paste
+action.show_html_source = Show HTML Source
+action.print = Print
+action.web_service = Web Service
+action.cancel_job = Cancel Job
+action.start_job = Start Job
+action.revert = Revert
+action.move_down = Move Down
+action.move_up = Move Up
+action.remove_return_datatype = Remove return datatype
+action.add_return_datatype = Add return datatype
+action.remove_input_parameter = Remove selected input parameter
+action.add_input_parameter = Add input parameter
+action.edit = Edit
+action.new = New
+action.open_file = Open file
+action.show_unconserved = Show Unconserved
+action.open_new_alignment = Open new alignment
+action.raise_associated_windows = Raise Associated Windows
+action.minimize_associated_windows = Minimize Associated Windows
+action.close_all = Close all
+action.load_project = Load Project
+action.save_project = Save Project
+action.quit = Quit
+action.expand_views = Expand Views
+action.gather_views = Gather Views
+action.page_setup = Page Setup
+action.reload = Reload
+action.load = Load
+action.open = Open
+action.cancel = Cancel
+action.create = Create
+action.update = Update
+action.delete = Delete
+action.snapshot = Snapshot
+action.clear = Clear
+action.accept = Accept
+action.select_ddbb = --- Select Database ---
+action.undo = Undo
+action.redo = Redo
+action.reset = Reset
+action.remove_left = Remove left
+action.remove_right = Remove right
+action.remove_empty_columns = Remove Empty Columns
+action.remove_all_gaps = Remove All Gaps
+action.left_justify_alignment = Left Justify Alignment
+action.right_justify_alignment = Right Justify Alignment
+action.boxes = Boxes
+action.text = Text
+action.by_pairwise_id = by Pairwise Identity
+action.by_id = by Id
+action.by_length = by Length
+action.by_group = by Group
+action.remove = Remove
+action.remove_redundancy = Remove Redundancy
+action.pairwise_alignment = Pairwise Alignments...
+action.by_rna_helixes = by RNA Helices
+action.user_defined = User Defined...
+action.by_conservation = By Conservation
+action.wrap = Wrap
+action.show_gaps = Show Gaps
+action.show_hidden_markers = Show Hidden Markers
+action.find = Find
+action.undefine_groups = Undefine Groups
+action.create_groups = Create Groups
+action.make_groups_selection = Make Groups For Selection
+action.copy = Copy
+action.cut = Cut
+action.font = Font...
+action.scale_above = Scale Above
+action.scale_left = Scale Left
+action.scale_right = Scale Right
+action.by_tree_order = By Tree Order
+action.sort = Sort
+action.calculate_tree = Calculate Tree
+action.help = Help
+action.by_annotation = by Annotation...
+action.invert_sequence_selection = Invert Sequence Selection
+action.invert_column_selection = Invert Column Selection
+action.show = Show
+action.hide = Hide
+action.ok = OK
+action.set_defaults = Defaults
+action.create_group = Create Group
+action.remove_group = Remove Group
+action.edit_group = Edit Group
+action.border_colour = Border colour
+action.edit_new_group = Edit New Group
+action.hide_sequences = Hide Sequences
+action.sequences = Sequences
+action.ids = IDS
+action.ids_sequences = IDS and sequences
+action.reveal_all = Reveal All
+action.reveal_sequences = Reveal Sequences
+action.find_all = Find all
+action.find_next = Find next
+action.file = File
+action.view = View
+action.annotations = Annotations
+action.change_params = Change Parameters
+action.apply = Apply
+action.apply_threshold_all_groups = Apply threshold to all groups
+action.apply_all_groups = Apply to all Groups
+action.by_chain = By chain
+action.by_sequence = By Sequence
+action.paste_annotations = Paste Annotations
+action.format = Format
+action.select = Select
+action.new_view = New View
+action.close = Close
+action.add = Add
+action.save_as_default = Save as default
+action.save_as = Save as
+action.save = Save
+action.cancel_fetch = Cancel Fetch
+action.save_omit_hidden_columns = Save / Omit Hidden Columns
+action.change_font = Change Font
+action.change_font_tree_panel = Change Font (Tree Panel)
+action.colour = Colour
+action.calculate = Calculate
+action.select_all = Select all
+action.deselect_all = Deselect all
+action.invert_selection = Invert selection
+action.using_jmol = Using Jmol
+action.link = Link
+action.group_link = Group Link
+action.show_chain = Show Chain
+action.show_group = Show Group
+action.fetch_db_references = Fetch DB References
+action.view_flanking_regions = Show flanking regions
+label.view_flanking_regions = Show sequence data either side of the subsequences involved in this alignment
+label.str = Str:
+label.seq = Seq:
+label.structures_manager = Structures Manager
+label.nickname = Nickname:
+label.url = URL:
+label.input_file_url = Enter URL or Input File
+label.select_feature = Select feature:
+label.name = Name
+label.name_param = Name: {0}
+label.group = Group
+label.group_name = Group Name
+label.group_description = Group Description
+label.edit_group_name_description = Edit Group Name/Description
+label.colour = Colour:
+label.description = Description:
+label.start = Start:
+label.end = End:
+label.current_parameter_set_name = Current parameter set name:
+label.service_action = Service Action:
+label.post_url = POST URL:
+label.url_suffix = URL Suffix
+label.sequence_source = Sequence Source
+label.per_seq = per Sequence
+label.result_vertically_separable = Results are vertically separable
+label.amend = Amend
+label.undo_command = Undo {0}
+label.redo_command = Redo {0}
+label.principal_component_analysis = Principal Component Analysis
+label.average_distance_identity = Average Distance Using % Identity
+label.neighbour_joining_identity = Neighbour Joining Using % Identity
+label.treecalc_title = {0} Using {1}
+label.tree_calc_av = Average Distance
+label.tree_calc_nj = Neighbour Joining
+label.select_score_model = Select score model
+label.score_model_pid = % Identity
+label.score_model_blosum62 = BLOSUM62
+label.score_model_pam250 = PAM 250
+label.score_model_conservation = Physicochemical property conservation
+label.score_model_enhconservation = Physicochemical property conservation
+label.status_bar = Status bar
+label.out_to_textbox = Output to Textbox
+label.clustalx = Clustalx
+label.clustal = Clustal
+label.zappo = Zappo
+label.taylor = Taylor
+label.blc = BLC
+label.fasta = Fasta
+label.msf = MSF
+label.pfam = PFAM
+label.pileup = Pileup
+label.pir = PIR
+label.hydrophobicity = Hydrophobicity
+label.helix_propensity = Helix Propensity
+label.strand_propensity = Strand Propensity
+label.turn_propensity = Turn Propensity
+label.buried_index = Buried Index
+label.purine_pyrimidine = Purine/Pyrimidine
+label.percentage_identity = Percentage Identity
+label.blosum62 = BLOSUM62
+label.blosum62_score = BLOSUM62 Score
+label.tcoffee_scores = T-Coffee Scores
+label.average_distance_bloslum62 = Average Distance Using BLOSUM62
+label.neighbour_blosum62 = Neighbour Joining Using BLOSUM62
+label.show_annotations = Show annotations
+label.hide_annotations = Hide annotations
+label.show_all_seq_annotations = Show sequence related
+label.hide_all_seq_annotations = Hide sequence related
+label.show_all_al_annotations = Show alignment related
+label.hide_all_al_annotations = Hide alignment related
+label.hide_all = Hide all
+label.add_reference_annotations = Add reference annotations
+label.find_tip = Search alignment, selection or sequence ids for a subsequence (ignoring gaps).<br>Accepts regular expressions - search Help for 'regex' for details.
+label.colour_text = Colour Text
+label.show_non_conversed = Show nonconserved
+label.overview_window = Overview Window
+label.none = None
+label.above_identity_threshold = Above Identity Threshold
+label.show_sequence_features = Show Sequence Features
+label.nucleotide = Nucleotide
+label.to_new_alignment = To New Alignment
+label.to_this_alignment = Add To This Alignment
+label.apply_colour_to_all_groups = Apply Colour To All Groups
+label.modify_identity_thereshold = Modify Identity Threshold...
+label.modify_conservation_thereshold = Modify Conservation Threshold...
+label.input_from_textbox = Input from textbox
+label.centre_column_labels = Centre column labels
+label.automatic_scrolling = Automatic Scrolling
+label.documentation = Documentation
+label.about = About...
+label.show_sequence_limits = Show Sequence Limits
+label.feature_settings = Feature Settings...
+label.sequence_features = Sequence Features
+label.all_columns = All Columns
+label.all_sequences = All Sequences
+label.selected_columns = Selected Columns
+label.selected_sequences = Selected Sequences
+label.all_but_selected_region = All but Selected Region (Shift+Ctrl+H)
+label.selected_region = Selected Region
+label.all_sequences_columns = All Sequences and Columns
+label.group_consensus = Group Consensus
+label.group_conservation = Group Conservation
+label.show_consensus_histogram = Show Consensus Histogram
+label.show_consensus_logo = Show Consensus Logo
+label.norm_consensus_logo = Normalise Consensus Logo
+label.apply_all_groups = Apply to all groups
+label.autocalculated_annotation = Autocalculated Annotation
+label.show_first = Show first
+label.show_last = Show last
+label.struct_from_pdb = Process secondary structure from PDB
+label.use_rnaview = Use RNAView for secondary structure
+label.autoadd_secstr = Add secondary structure annotation to alignment
+label.autoadd_temp = Add Temperature Factor annotation to alignment
+label.structure_viewer = Default structure viewer
+label.chimera_path = Path to Chimera program
+label.chimera_path_tip = Jalview will try standard locations, plus any path entered here.
+label.invalid_path = File not found or not executable
+label.min_colour = Minimum Colour
+label.max_colour = Maximum Colour
+label.use_original_colours = Use Original Colours
+label.threshold_minmax = Threshold is min/max
+label.represent_group_with = Represent Group with {0}
+label.selection = Selection
+label.group_colour = Group Colour
+label.sequence = Sequence
+label.view_pdb_structure = View PDB Structure
+label.min = Min:
+label.max = Max:
+label.colour_by_label = Colour by label
+label.new_feature = New Feature
+label.match_case = Match Case
+label.view_alignment_editor = View in alignment editor
+label.labels = Labels
+label.output_values = Output Values...
+label.output_points = Output points...
+label.output_transformed_points = Output transformed points
+label.input_data = Input Data...
+label.nucleotide_matrix = Nucleotide matrix
+label.protein_matrix = Protein matrix
+label.show_bootstrap_values = Show Bootstrap Values
+label.show_distances = Show distances
+label.mark_unassociated_leaves = Mark Unassociated Leaves
+label.fit_to_window = Fit To Window
+label.newick_format = Newick Format
+label.select_newick_like_tree_file = Select a newick-like tree file
+label.colours = Colours
+label.view_mapping = View Mapping
+label.wireframe = Wireframe
+label.depthcue = Depthcue
+label.z_buffering = Z Buffering
+label.charge_cysteine = Charge & Cysteine
+label.all_chains_visible = All Chains Visible
+label.successfully_added_features_alignment = Successfully added features to alignment
+label.keyboard_editing_mode = Keyboard editing mode is {0}
+label.paste_features_annotations_Tcoffee_here = Paste your features / annotations / T-coffee score file here.
+label.removed_columns = Removed {0} columns.
+label.removed_empty_columns = Removed {0} empty columns.
+label.paste_newick_tree_file = Paste your Newick tree file here.
+label.order_by_params = Order by {0}
+label.html_content = <html>{0}</html>
+label.paste_pdb_file= Paste your PDB file here.
+label.paste_pdb_file_for_sequence = Paste PDB file for sequence {0}
+label.could_not_parse_newick_file = Could not parse Newick file\!\n {0}
+label.successfully_pasted_tcoffee_scores_to_alignment= Successfully pasted T-Coffee scores to alignment.
+label.failed_add_tcoffee_scores = Failed to add T-Coffee scores:
+label.successfully_pasted_annotation_to_alignment= Successfully pasted annotation to alignment.
+label.couldnt_parse_pasted_text_as_valid_annotation_feature_GFF_tcoffee_file = Couldn't parse pasted text as a valid annotation, feature, GFF, or T-Coffee score file
+label.successfully_pasted_alignment_file = Successfully pasted alignment file
+label.paste_your_alignment_file = Paste your alignment file here
+label.paste_your = Paste your
+label.finished_searching = Finished searching
+label.search_results= Search results {0} : {1}
+label.found_match_for = Found match for {0}
+label.font = Font:
+label.size = Size:
+label.style = Style:
+label.enter_redundancy_threshold = Enter the redundancy threshold
+label.calculating = Calculating....
+label.modify_conservation_visibility = Modify conservation visibility
+label.colour_residues_above_occurence = Colour residues above % occurence
+label.set_this_label_text = set this label text
+label.sequences_from = Sequences from {0}
+label.successfully_loaded_file = Successfully loaded file {0}
+label.successfully_saved_to_file_in_format = Successfully saved to file: {0} in {1} format.
+label.copied_sequences_to_clipboard = Copied {0} sequences to clipboard.
+label.check_file_matches_sequence_ids_alignment = Check that the file matches sequence IDs in the alignment.
+label.problem_reading_tcoffee_score_file = Problem reading T-COFFEE score file
+label.source_to_target = {0} ... {1}
+label.per_sequence_only= Per-sequence only
+label.to_file = to File
+label.to_textbox = to Textbox
+label.jalview = Jalview
+label.csv_spreadsheet = CSV (Spreadsheet)
+label.status = Status
+label.channels = Channels
+label.channel_title_item_count = {0} ({1})
+label.blog_item_published_on_date = {0} {1}
+label.select_das_service_from_table = Select a DAS service from the table to read a full description here.</font></html>
+label.session_update = Session Update
+label.new_vamsas_session = New Vamsas Session
+label.load_vamsas_session = Load Vamsas Session
+label.save_vamsas_session = Save Vamsas Session
+label.select_vamsas_session_opened_as_new_vamsas_session= Select a vamsas session to be opened as a new vamsas session.
+label.open_saved_vamsas_session = Open a saved VAMSAS session
+label.groovy_console = Groovy Console...
+label.lineart = Lineart
+label.dont_ask_me_again = Don't ask me again
+label.select_eps_character_rendering_style = Select EPS character rendering style
+label.invert_selection = Invert Selection
+label.optimise_order = Optimise Order
+label.seq_sort_by_score = Seq sort by Score
+label.load_colours = Load Colours
+label.save_colours = Save Colours
+label.fetch_das_features = Fetch DAS Features
+label.selected_database_to_fetch_from = Selected {0} database {1} to fetch from {2}
+label.database_param = Database: {0}
+label.example = Example
+label.example_param = Example: {0}
+label.select_file_format_before_saving = You must select a file format before saving!
+label.file_format_not_specified = File format not specified
+label.alignment_contains_hidden_columns = The Alignment contains hidden columns.\nDo you want to save only the visible alignment?
+label.couldnt_save_file = Couldn't save file: {0}
+label.error_saving_file = Error Saving File
+label.remove_from_default_list = Remove from default list?
+label.remove_user_defined_colour = Remove user defined colour
+label.you_must_select_least_two_sequences = You must select at least 2 sequences.
+label.invalid_selection = Invalid Selection
+label.principal_component_analysis_must_take_least_four_input_sequences = Principal component analysis must take\nat least 4 input sequences.
+label.sequence_selection_insufficient = Sequence selection insufficient
+label.you_need_more_two_sequences_selected_build_tree = You need to have more than two sequences selected to build a tree!
+label.not_enough_sequences = Not enough sequences
+label.selected_region_to_tree_may_only_contain_residues_or_gaps = The selected region to create a tree may\nonly contain residues or gaps.\nTry using the Pad function in the edit menu,\nor one of the multiple sequence alignment web services.
+label.sequences_selection_not_aligned = Sequences in selection are not aligned
+label.sequences_must_be_aligned_before_creating_tree = The sequences must be aligned before creating a tree.\nTry using the Pad function in the edit menu,\n or one of the multiple sequence alignment web services.
+label.sequences_not_aligned = Sequences not aligned
+label.problem_reading_tree_file = Problem reading tree file
+label.possible_problem_with_tree_file = Possible problem with tree file
+label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation = Please select at least three bases in at least one sequence in order to perform a cDNA translation.
+label.translation_failed = Translation Failed
+label.error_when_translating_sequences_submit_bug_report = Unfortunately, something went wrong when translating your sequences.\nPlease take a look in the Jalview java console\nand submit a bug report including the stacktrace.
+label.implementation_error = Implementation error:
+label.automatically_associate_pdb_files_with_sequences_same_name = Do you want to automatically associate the {0} PDB files with sequences in the alignment that have the same name?
+label.automatically_associate_pdb_files_by_name = Automatically Associate PDB files by name
+label.ignore_unmatched_dropped_files_info = <html>Do you want to <em>ignore</em> the {0} files whose names did not match any sequence IDs ?</html>
+label.ignore_unmatched_dropped_files = Ignore unmatched dropped files?
+label.enter_view_name = Enter View Name
+label.enter_label = Enter label
+label.enter_label_for_the_structure = Enter a label for the structure?
+label.pdb_entry_is_already_displayed = {0} is already displayed.\nDo you want to re-use this viewer ?
+label.map_sequences_to_visible_window = Map Sequences to Visible Window: {0}
+label.add_pdbentry_to_view = Do you want to add {0} to the view called\n{1}\n
+label.align_to_existing_structure_view = Align to existing structure view
+label.pdb_entries_couldnt_be_retrieved = The following pdb entries could not be retrieved from the PDB\:\n{0}\nPlease retry, or try downloading them manually.
+label.couldnt_load_file = Couldn't load file
+label.couldnt_find_pdb_id_in_file = Couldn't find a PDB id in the file supplied. Please enter an Id to identify this structure.
+label.no_pdb_id_in_file = No PDB Id in File
+label.couldnt_read_pasted_text = Couldn't read the pasted text {0}
+label.error_parsing_text = Error parsing text
+label.enter_local_das_source = Enter Nickname & URL of Local DAS Source
+label.you_can_only_edit_or_remove_local_das_sources = You can only edit or remove local DAS Sources!
+label.public_das_source = Public DAS source - not editable
+label.input_alignment_from_url = Input Alignment From URL
+label.input_alignment = Input Alignment
+label.couldnt_import_as_vamsas_session = Couldn't import {0} as a new vamsas session.
+label.vamsas_document_import_failed = Vamsas Document Import Failed
+label.couldnt_locate = Couldn't locate {0}
+label.url_not_found = URL not found
+label.no_link_selected = No link selected
+label.new_sequence_url_link = New sequence URL link
+label.cannot_edit_annotations_in_wrapped_view = Cannot edit annotations in wrapped view
+label.wrapped_view_no_edit = Wrapped view - no edit
+label.error_retrieving_data = Error Retrieving Data
+label.user_colour_scheme_must_have_name = User colour scheme must have a name
+label.no_name_colour_scheme = No name for colour scheme
+label.invalid_url = Invalid URL !
+label.error_loading_file = Error loading file
+label.problems_opening_file = Encountered problems opening {0}!!
+label.file_open_error = File open error
+label.no_das_sources_selected_warn = No das sources were selected.\nPlease select some sources and\ntry again.
+label.no_das_sources_selected_title = No DAS Sources Selected
+label.colour_scheme_exists_overwrite = Colour scheme {0} exists.\nContinue saving colour scheme as {1}?"
+label.duplicate_scheme_name = Duplicate scheme name
+label.jalview_new_questionnaire = There is a new Questionnaire available. Would you like to complete it now ?\n
+label.jalview_user_survey = Jalview User Survey
+label.alignment_properties = Alignment Properties: {0}
+label.alignment_props = Alignment Properties
+label.input_cut_paste = Cut & Paste Input
+label.input_cut_paste_params = Cut & Paste Input - {0}
+label.alignment_output_command = Alignment output - {0}
+label.annotations = Annotations
+label.structure_options = Structure Options
+label.features = Features
+label.overview_params = Overview {0}
+label.paste_newick_file = Paste Newick file
+label.load_tree_from_file = From File -
+label.colour_by_annotation = Colour by Annotation
+label.selection_output_command = Selection output - {0}
+label.annotation_for_displayid = <p><h2>Annotation for {0} </h2></p><p>
+label.pdb_sequence_mapping = PDB - Sequence Mapping
+label.pca_details = PCA details
+label.redundancy_threshold_selection = Redundancy threshold selection
+label.user_defined_colours = User defined colours
+label.jalviewLite_release = JalviewLite - Release {0}
+label.jaview_build_date = Build date: {0}
+label.jalview_authors_1 = Authors: : Jim Procter, Andrew Waterhouse, Lauren Lui, Jan Engelhardt, Natasha Sherstnev,
+label.jalview_authors_2 = Daniel Barton, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton.
+label.jalview_dev_managers = Development managed by The Barton Group, University of Dundee, Scotland, UK.
+label.jalview_distribution_lists = For help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list
+label.jalview_please_cite = If you use Jalview, please cite:
+label.jalview_cite_1_authors = Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)
+label.jalview_cite_1_title = Jalview Version 2 - a multiple sequence alignment editor and analysis workbench
+label.jalview_cite_1_ref = Bioinformatics doi: 10.1093/bioinformatics/btp033
+label.right_click = Right click
+label.to_add_annotation = to add annotation
+label.alignment_has_no_annotations = Alignment has no annotations
+label.retrieving_pdb_data = Retrieving PDB data...
+label.label = Label
+label.no_features_added_to_this_alignment = No Features added to this alignment!!
+label.features_can_be_added_from_searches_1 = (Features can be added from searches or
+label.features_can_be_added_from_searches_2 = from Jalview / GFF features files)
+label.calculating_pca= Calculating PCA
+label.reveal_columns = Reveal Columns
+label.jalview_cannot_open_file = Jalview can't open file
+label.jalview_applet = Jalview applet
+label.loading_data = Loading data
+label.memory_stats = Total Free Memory: {0} MB; Max Memory: {1} MB; {2} %
+label.calculating_tree = Calculating tree
+label.state_queueing = queuing
+label.state_running = running
+label.state_complete = complete
+label.state_completed = finished
+label.state_job_cancelled = job cancelled!!
+label.state_job_error = job error!
+label.server_error_try_later = Server Error! (try later)
+label.error_loading_pdb_data = Error loading PDB data!!
+label.fetching_pdb_data = Fetching PDB data...
+label.structure_type = Structure type
+label.settings_for_type = Settings for {0}
+label.view_full_application = View in Full Application
+label.load_associated_tree = Load Associated Tree ...
+label.load_features_annotations = Load Features/Annotations ...
+label.export_features = Export Features
+label.export_annotations = Export Annotations
+label.jalview_copy = Copy (Jalview Only)
+label.jalview_cut = Cut (Jalview Only)
+label.to_upper_case = To Upper Case
+label.to_lower_case = To Lower Case
+label.toggle_case = Toggle Case
+label.edit_name_description = Edit Name/Description ...
+label.create_sequence_feature = Create Sequence Feature ...
+label.edit_sequence = Edit Sequence
+label.edit_sequences = Edit Sequences
+label.sequence_details = Sequence Details
+label.jmol_help = Jmol Help
+label.chimera_help = Chimera Help
+label.close_viewer = Close Viewer
+label.confirm_close_chimera = This will close Jalview''s connection to {0}.<br>Do you want to close the Chimera window as well?
+label.chimera_help = Chimera Help
+label.all = All
+label.sort_by = Sort alignment by
+label.sort_by_score = Sort by Score
+label.sort_by_density = Sort by Density
+label.sequence_sort_by_density = Sequence sort by Density
+label.sort_ann_by = Sort annotations by
+label.sort_annotations_by_sequence = Sort by sequence
+label.sort_annotations_by_label = Sort by label
+label.reveal = Reveal
+label.hide_columns = Hide Columns
+label.load_jalview_annotations = Load Jalview Annotations or Features File
+label.load_tree_file = Load a tree file
+label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences = Retrieve and parse sequence database records for the alignment or the currently selected sequences
+label.standard_databases = Standard Databases
+label.fetch_embl_uniprot = Fetch from EMBL/EMBLCDS or Uniprot/PDB and any selected DAS sources
+label.reset_min_max_colours_to_defaults = Reset min and max colours to defaults from user preferences.
+label.align_structures_using_linked_alignment_views = Align structures using {0} linked alignment views
+label.connect_to_session = Connect to session {0}
+label.threshold_feature_display_by_score = Threshold the feature display by score.
+label.threshold_feature_no_thereshold = No Threshold
+label.threshold_feature_above_thereshold = Above Threshold
+label.threshold_feature_below_thereshold = Below Threshold
+label.adjust_thereshold = Adjust threshold
+label.toggle_absolute_relative_display_threshold = Toggle between absolute and relative display threshold.
+label.display_features_same_type_different_label_using_different_colour = Display features of the same type with a different label using a different colour. (e.g. domain features)
+label.select_colour_minimum_value = Select Colour for Minimum Value
+label.select_colour_maximum_value = Select Colour for Maximum Value
+label.open_new_jmol_view_with_all_structures_associated_current_selection_superimpose_using_alignment = Open a new structure viewer with all structures associated with the current selection and superimpose them using the alignment.
+label.open_url_param = Open URL {0}
+label.open_url_seqs_param = Open URL ({0}..) ({1} seqs)
+label.load_pdb_file_associate_with_sequence = Load a PDB file and associate it with sequence {0}
+label.reveal_hidden_columns = Reveal Hidden Columns with Right Mouse Button
+label.dark_colour = Dark Colour
+label.light_colour = Light Colour
+label.highlightnode = Left click to select leaves.<br>Double-click to invert leaves.<br>Right click to change colour.
+label.load_colour_scheme = Load colour scheme
+label.toggle_enabled_views = When enabled, allows many views to be selected.
+label.edit_notes_parameter_set = Click to edit the notes for this parameter set.
+label.open_local_file = Open local file
+label.enable_automatically_sort_alignment_when_open_new_tree = Enable this to automatically sort<br>the alignment when you open<br> a new tree.
+label.listen_for_selections = Listen for selections
+label.selections_mirror_selections_made_same_sequences_other_views = When selected, selections in this view will mirror<br>selections made on the same sequences in other views.
+label.toggle_sequence_visibility = Shift+H toggles sequence visiblity
+label.toggle_columns_visibility = Ctrl+H toggles column visiblity.
+label.toggles_visibility_hidden_selected_regions = H toggles visibility of hidden or selected regions
+label.rename_tab_eXpand_reGroup= Right-click to rename tab <br> Press X to eXpand tabs, G to reGroup.
+label.right_align_sequence_id = Right Align Sequence Id
+label.sequence_id_tooltip = Sequence ID Tooltip
+label.no_services = <No Services>
+label.select_copy_raw_html = Select this if you want to copy raw html
+label.share_data_vamsas_applications = Share data with other vamsas applications
+label.connect_to = Connect to
+label.join_existing_vamsas_session = Join an existing vamsas session
+label.from_url = from URL
+label.any_trees_calculated_or_loaded_alignment_automatically_sort = When selected, any trees calculated or loaded onto the alignment will automatically sort the alignment
+label.sort_with_new_tree = Sort With New Tree
+label.from_textbox = from Textbox
+label.window = Window
+label.preferences = Preferences
+label.tools = Tools
+label.fetch_sequences = Fetch Sequence(s)
+label.stop_vamsas_session = Stop Vamsas Session
+label.collect_garbage = Collect Garbage
+label.show_memory_usage = Show Memory Usage
+label.show_java_console = Show Java Console
+label.show_jalview_news = Show Jalview News
+label.take_snapshot = Take snapshot
+label.monospaced_fonts_faster_to_render = Monospaced fonts are faster to render
+label.anti_alias_fonts = Anti-alias Fonts (Slower to render)
+label.monospaced_font= Monospaced
+label.quality = Quality
+label.maximize_window = Maximize Window
+label.conservation = Conservation
+label.consensus = Consensus
+label.histogram = Histogram
+label.logo = Logo
+label.non_positional_features = Non-positional Features
+label.database_references = Database References
+label.share_selection_across_views = Share selection across views
+label.scroll_highlighted_regions = Scroll to highlighted regions
+label.gap_symbol = Gap Symbol
+label.alignment_colour = Alignment Colour
+label.address = Address
+label.port = Port
+label.default_browser_unix = Default Browser (Unix)
+label.send_usage_statistics = Send usage statistics
+label.check_for_questionnaires = Check for questionnaires
+label.check_for_latest_version = Check for latest version
+label.url_linkfrom_sequence_id = URL link from Sequence ID
+label.use_proxy_server = Use a proxy server
+label.eps_rendering_style = EPS rendering style
+label.append_start_end = Append /start-end (/15-380)
+label.full_sequence_id = Full Sequence Id
+label.smooth_font = Smooth Font
+label.autocalculate_consensus = AutoCalculate Consensus
+label.pad_gaps = Pad Gaps
+label.pad_gaps_when_editing = Pad Gaps When Editing
+label.automatically_set_id_width = Automatically set ID width
+label.figure_id_column_width = Figure ID column width
+label.use_modeller_output = Use Modeller Output
+label.wrap_alignment = Wrap Alignment
+label.right_align_ids = Right Align Ids
+label.sequence_name_italics = Seq Name Italics
+label.open_overview = Open Overview
+label.default_colour_scheme_for_alignment = Default Colour Scheme for alignment
+label.annotation_shading_default = Annotation Shading Default
+label.default_minimum_colour_annotation_shading = Default Minimum Colour for annotation shading
+label.default_maximum_colour_annotation_shading = Default Maximum Colour for annotation shading
+label.visual = Visual
+label.connections = Connections
+label.output = Output
+label.editing = Editing
+label.das_settings = DAS Settings
+label.web_services = Web Services
+label.right_click_to_edit_currently_selected_parameter = Right click to edit currently selected parameter.
+label.let_jmol_manage_structure_colours = Let Jmol manage structure colours
+label.let_chimera_manage_structure_colours = Let Chimera manage structure colours
+label.marks_leaves_tree_not_associated_with_sequence = Marks leaves of tree not associated with a sequence
+label.index_web_services_menu_by_host_site = Index web services in menu by the host site
+label.option_want_informed_web_service_URL_cannot_be_accessed_jalview_when_starts_up = Check this option if you want to be informed<br>when a web service URL cannot be accessed by Jalview<br>when it starts up
+label.new_service_url = New Service URL
+label.edit_service_url = Edit Service URL
+label.delete_service_url = Delete Service URL
+label.details = Details
+label.options = Options
+label.parameters = Parameters
+label.available_das_sources = Available DAS Sources
+label.full_details = Full Details
+label.authority = Authority
+label.type = Type
+label.proxy_server = Proxy Server
+label.file_output = File Output
+label.select_input_type = Select input type
+label.set_options_for_type = Set options for type
+label.data_input_parameters = Data input parameters
+label.data_returned_by_service = Data returned by service
+label.rsbs_encoded_service = RSBS Encoded Service
+label.parsing_errors = Parsing errors
+label.simple_bioinformatics_rest_services = Simple Bioinformatics Rest Services
+label.web_service_discovery_urls = Web Service Discovery URLS
+label.input_parameter_name = Input Parameter name
+label.short_descriptive_name_for_service = Short descriptive name for service
+label.function_service_performs = What kind of function the service performs (e.g. alignment, analysis, search, etc).
+label.brief_description_service = Brief description of service
+label.url_post_data_service = URL to post data to service. Include any special parameters needed here
+label.optional_suffix = Optional suffix added to URL when retrieving results from service
+label.preferred_gap_character = Which gap character does this service prefer?
+label.gap_character = Gap character
+label.move_return_type_up_order= Move return type up order
+label.move_return_type_down_order= Move return type down order
+label.update_user_parameter_set = Update this existing user parameter set
+label.delete_user_parameter_set = Delete the currently selected user parameter set
+label.create_user_parameter_set = Create a new parameter set with the current settings.
+label.revert_changes_user_parameter_set = Undo all changes to the current parameter set
+label.start_job_current_settings = Start Job with current settings
+label.cancel_job_close_dialog = Close this dialog and cancel job
+label.input_output = Input/Output
+label.cut_paste = Cut'n'Paste
+label.adjusting_parameters_for_calculation = Adjusting parameters for existing Calculation
+label.2d_rna_structure_line = 2D RNA {0}
+label.2d_rna_sequence_name = 2D RNA - {0}
+label.edit_name_and_description_current_group = Edit name and description of current group.
+label.view_structure_for = View structure for {0}
+label.view_all_structures = View all {0} structures.
+label.view_all_representative_structures = View all {0} representative structures.
+label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment = Opens a new structure viewer with all representative structures\nassociated with the current selection\nsuperimposed with the current alignment.
+label.associate_structure_with_sequence = Associate Structure with Sequence
+label.from_file = from file
+label.enter_pdb_id = Enter PDB Id
+label.discover_pdb_ids = Discover PDB ids
+label.text_colour = Text Colour
+label.structure = Structure
+label.view_structure = View Structure
+label.clustalx_colours = Clustalx colours
+label.above_identity_percentage = Above % Identity
+label.create_sequence_details_report_annotation_for = Annotation for {0}
+label.sequece_details_for = Sequece Details for {0}
+label.sequence_name = Sequence Name
+label.sequence_description = Sequence Description
+label.edit_sequence_name_description = Edit Sequence Name/Description
+label.spaces_converted_to_backslashes = Spaces have been converted to _
+label.no_spaces_allowed_sequence_name = No spaces allowed in Sequence Name
+label.select_outline_colour = Select Outline Colour
+label.web_browser_not_found_unix = Unixers\: Couldn't find default web browser.\nAdd the full path to your browser in Preferences."
+label.web_browser_not_found = Web browser not found
+label.select_pdb_file_for = Select a PDB file for {0}
+label.html = HTML
+label.wrap = Wrap
+label.show_database_refs = Show Database Refs
+label.show_non_positional_features = Show Non-Positional Features
+label.save_png_image = Save As PNG Image
+label.load_tree_for_sequence_set = Load a tree for this sequence set
+label.export_image = Export Image
+label.vamsas_store = VAMSAS store
+label.translate_cDNA = Translate cDNA
+label.extract_scores = Extract Scores
+label.get_cross_refs = Get Cross References
+label.sort_alignment_new_tree = Sort Alignment With New Tree
+label.add_sequences = Add Sequences
+label.new_window = New Window
+label.refresh_available_sources = Refresh Available Sources
+label.use_registry = Use Registry
+label.add_local_source = Add Local Source
+label.set_as_default = Set as Default
+label.show_labels = Show labels
+label.background_colour = Background Colour
+label.associate_nodes_with = Associate Nodes With
+label.jalview_pca_calculation = Jalview PCA Calculation
+label.link_name = Link Name
+label.pdb_file = PDB file
+label.colour_with_jmol = Colour with Jmol
+label.colour_with_chimera = Colour with Chimera
+label.align_structures = Align structures
+label.jmol = Jmol
+label.chimera = Chimera
+label.sort_alignment_by_tree = Sort Alignment By Tree
+label.mark_unlinked_leaves = Mark Unlinked Leaves
+label.associate_leaves_with = Associate Leaves With
+label.save_colour_scheme_with_unique_name_added_to_colour_menu = Save your colour scheme with a unique name and it will be added to the Colour menu
+label.case_sensitive = Case Sensitive
+label.lower_case_colour = Lower Case Colour
+label.index_by_host = Index by host
+label.index_by_type = Index by type
+label.enable_jabaws_services = Enable JABAWS Services
+label.display_warnings = Display warnings
+label.move_url_up = Move URL up
+label.move_url_down = Move URL down
+label.add_sbrs_definition = Add a SBRS definition
+label.edit_sbrs_definition = Edit SBRS definition
+label.delete_sbrs_definition = Delete SBRS definition
+label.your_sequences_have_been_verified = Your sequences have been verified against known sequence databases. Some of the ids have been\n altered, most likely the start/end residue will have been updated.\n Save your alignment to maintain the updated id.\n\n
+label.sequence_names_updated = Sequence names updated
+label.dbref_search_completed = DBRef search completed
+label.show_all_chains = Show all chains
+label.fetch_all_param = Fetch all {0}
+label.paste_new_window = Paste To New Window
+label.settings_for_param = Settings for {0}
+label.view_params = View {0}
+label.select_all_views = Select all views
+label.align_sequences_to_existing_alignment = Align sequences to an existing alignment
+label.realign_with_params = Realign with {0}
+label.calcname_with_default_settings = {0} with Defaults
+label.action_with_default_settings = {0} with default settings
+label.edit_settings_and_run = Edit settings and run...
+label.view_and_change_parameters_before_alignment = View and change the parameters before alignment
+label.run_with_preset_params = Run {0} with preset
+label.view_and_change_parameters_before_running_calculation = View and change parameters before running calculation
+label.view_documentation = View documentation
+label.select_return_type = Select return type
+label.translation_of_params = Translation of {0}
+label.features_for_params = Features for - {0}
+label.annotations_for_params = Annotations for - {0}
+label.generating_features_for_params = Generating features for - {0}
+label.generating_annotations_for_params = Generating annotations for - {0}
+label.varna_params = VARNA - {0}
+label.sequence_feature_settings = Sequence Feature Settings
+label.pairwise_aligned_sequences = Pairwise Aligned Sequences
+label.original_data_for_params = Original Data for {0}
+label.points_for_params = Points for {0}
+label.transformed_points_for_params = Transformed points for {0}
+label.graduated_color_for_params = Graduated Feature Colour for {0}
+label.select_backgroud_colour = Select Background Colour
+label.invalid_font = Invalid Font
+label.separate_multiple_accession_ids = Separate multiple accession ids with semi colon ";"
+label.replace_commas_semicolons = Replace commas with semi-colons
+label.parsing_failed_syntax_errors_shown_below_param = Parsing failed. Syntax errors shown below {0}
+label.parsing_failed_unrecoverable_exception_thrown_param = \nParsing failed. An unrecoverable exception was thrown\:\n {0}
+label.example_query_param = Example query: {0}
+label.enter_value_increase_conservation_visibility = Enter value to increase conservation visibility
+label.enter_percentage_identity_above_which_colour_residues = Enter % identity above which to colour residues
+label.wswublast_client_credits = To display sequence features an exact Uniprot id with 100% sequence identity match must be entered.\nIn order to display these features, try changing the names of your sequences to the ids suggested below.\n\nRunning WSWUBlast at EBI.\nPlease quote Pillai S., Silventoinen V., Kallio K., Senger M., Sobhany S., Tate J., Velankar S., Golovin A., Henrick K., Rice P., Stoehr P., Lopez R.\nSOAP-based services provided by the European Bioinformatics Institute.\nNucleic Acids Res. 33(1)\:W25-W28 (2005));
label.blasting_for_unidentified_sequence = BLASTing for unidentified sequences
-label.select_columns_containing = Select columns containing\r
-label.select_columns_not_containing = Select columns that do not contain\r
-option.trim_retrieved_seqs = Trim retrieved sequences\r
-label.trim_retrieved_sequences = When the reference sequence is longer than the sequence that you are working with, only keep the relevant subsequences.\r
+label.select_columns_containing = Select columns containing
+label.select_columns_not_containing = Select columns that do not contain
+option.trim_retrieved_seqs = Trim retrieved sequences
+label.trim_retrieved_sequences = When the reference sequence is longer than the sequence that you are working with, only keep the relevant subsequences.
+label.use_sequence_id_1 = Use $SEQUENCE_ID$ or $SEQUENCE_ID=/<regex>/=$
+label.use_sequence_id_2 = \nto embed sequence id in URL
+label.ws_parameters_for = Parameters for {0}
+label.switch_server = Switch server
+label.open_jabaws_web_page = Opens the JABAWS server's homepage in web browser
+label.choose_jabaws_server = Choose a server for running this service
+label.services_at = Services at {0}
+label.rest_client_submit = {0} using {1}
+label.fetch_retrieve_from =Retrieve from {0}</html>
+label.fetch_retrieve_from_all_sources = Retrieve from all {0} sources in {1}<br>First is :{2}<html>
+label.feature_settings_click_drag = <html>Click/drag feature types up or down to change render order.<br/>Double click to select columns containing feature in alignment/current selection<br/>Pressing Alt will select columns outside features rather than inside<br/>Pressing Shift to modify current selection (rather than clear current selection)<br/>Press CTRL or Command/Meta to toggle columns in/outside features<br/></html>
+label.opt_and_params_further_details = see further details by right-clicking
+label.opt_and_params_show_brief_desc_image_link = <html>Click to show brief description<br><img src="{0}"/> Right click for further information.</html>
+label.opt_and_params_show_brief_desc = <html>Click to show brief description<br></html>
+label.adjusts_width_generated_eps_png = <html>Adjusts the width of the generated EPS or PNG file to ensure even the longest sequence ID or annotation label is displayed</html>
+label.manually_specify_width_left_column = <html>Manually specify the width of the left hand column where sequence IDs and annotation labels will be rendered in exported alignment figures. This setting will be ignored if 'Automatically set ID width' is set</html>
+label.job_created_when_checked = <html>When checked, a job is created for every sequence in the current selection.</html>
+label.when_checked_job_visible_region_and_results = <html>When checked, a single job is created for the visible region and results mapped back onto their location in the alignment. Otherwise, a job would be created for every contiguous region visible in the alignment or current selection (e.g. a multiple alignment).</html>
+label.flat_file_representation = <html>Flat file representation of this rest service using the Really Simple Bioinformatics Service formalism</html>
+label.result_of_parsing_rsbs = <html>Results of parsing the RSBS representation</html>
+label.user_preset = User Preset
+label.service_preset = Service Preset
+label.run_with_preset = Run {0} with preset
+label.view_service_doc_url = <html>View <a href="{0}">{1}</a></html>
+label.submit_sequence = <html>Submit {0} {1} {2} {3} to<br/>{4}</html>
+action.by_title_param = by {0}
+label.alignment = Alignment
+label.secondary_structure_prediction = Secondary Structure Prediction
+label.sequence_database_search = Sequence Database Search
+label.analysis = Analysis
+label.protein_disorder = Protein Disorder
+label.source_from_db_source = Sources from {0}
+label.from_msname = from {0}
+label.superpose_with = Superpose with ...
+action.do = Do
+label.scale_label_to_column = Scale Label to Column
+label.add_new_row = Add New Row
+label.edit_label_description = Edit Label/Description
+label.hide_row = Hide This Row
+label.delete_row = Delete This Row
+label.show_all_hidden_rows = Show All Hidden Rows
+label.export_annotation = Export Annotation
+label.copy_consensus_sequence = Copy Consensus Sequence
+label.helix = Helix
+label.sheet = Sheet
+label.rna_helix = RNA Helix
+label.remove_annotation = Remove Annotation
+label.colour_by = Colour by...
+label.muscle_multiple_protein_sequence_alignment = Muscle Multiple Protein Sequence Alignment
+label.mafft_multiple_sequence_alignment = MAFFT Multiple Sequence Alignment
+label.clustalw_multiple_sequence_alignment = ClustalW Multiple Sequence Alignment
+label.jnet_secondary_structure_prediction = JNet Secondary Structure Prediction
+label.multiharmony = Multi-Harmony
+label.unable_start_web_service_analysis = Unable to start web service analysis
+label.job_couldnt_be_started_check_input = The Job couldn't be started. Please check your input, and the Jalview console for any warning messages.
+label.prompt_each_time = Prompt each time
+label.use_source = Use Source
+label.couldnt_save_project = Couldn't save project
+label.error_whilst_saving_current_state_to = Error whilst saving current state to {0}
+label.error_whilst_loading_project_from = Error whilst loading project from {0}
+label.couldnt_load_project = Couldn't load project
+label.pca_sequences_not_aligned = The sequences must be aligned before calculating PCA.\nTry using the Pad function in the edit menu,\nor one of the multiple sequence alignment web services.
+label.invalid_name_preset_exists = Invalid name - preset already exists.
+label.invalid_name = Invalid name
+label.set_proxy_settings = Please set up your proxy settings in the 'Connections' tab of the Preferences window
+label.proxy_authorization_failed = Proxy Authorization Failed
+label.internal_jalview_error = Internal Jalview Error
+label.secondary_structure_prediction_service_couldnt_be_located = The Secondary Structure Prediction Service named {0} at {1} couldn't be located.
+label.service_called_is_not_msa_service = The Service called \n{0}\nis not a \nMultiple Sequence Alignment Service\!
+label.msa_service_is_unknown = The Multiple Sequence Alignment Service named {0} is unknown
+label.service_called_is_not_seq_search_service = The Service called \n{0}\nis not a \nSequence Search Service\!
+label.seq_search_service_is_unknown = The Sequence Search Service named {0} is unknown
+label.feature_type = Feature Type
+label.display = Display
+label.service_url = Service URL
+label.copied_sequences = Copied sequences
+label.cut_sequences = Cut Sequences
+label.conservation_colour_increment = Conservation Colour Increment ({0})
+label.percentage_identity_thereshold = Percentage Identity Threshold ({0})
+label.error_unsupported_owwner_user_colour_scheme = Unsupported owner for User Colour scheme dialog
+label.save_alignment_to_file = Save Alignment to file
+label.save_features_to_file = Save Features to File
+label.save_annotation_to_file = Save Annotation to File
+label.no_features_on_alignment = No features found on alignment
+label.save_pdb_file = Save PDB File
+label.save_text_to_file = Save Text to File
+label.save_state = Save State
+label.restore_state = Restore State
+label.saving_jalview_project = Saving jalview project {0}
+label.loading_jalview_project = Loading jalview project {0}
+label.save_vamsas_document_archive = Save Vamsas Document Archive
+label.saving_vamsas_doc = Saving VAMSAS Document to {0}
+label.load_feature_colours = Load Feature Colours
+label.save_feature_colours = Save Feature Colour Scheme
+label.dataset_for = {0} Dataset for {1}
+label.select_startup_file = Select startup file
+label.select_default_browser = Select default web browser
+label.save_tree_as_newick = Save tree as newick file
+label.create_eps_from_tree = Create EPS file from tree
+label.create_png_from_tree = Create PNG image from tree
+label.save_colour_scheme = Save colour scheme
+label.edit_params_for = Edit parameters for {0}
+label.choose_filename_for_param_file = Choose a filename for this parameter file
+label.save_as_html = Save as HTML
+label.recently_opened = Recently Opened
+label.blasting_for_unidentified_sequence_jobs_running = BLASTing for unidentified sequences - {0} jobs running.
+label.tree_from = Tree from {0}
+label.webservice_job_title = {0} using {1}
+label.select_visible_region_of = selected {0} region of {1}
+label.visible = Visible
+label.select_unselect_visible_regions_from = select and unselected {0} regions from {1}
+label.visible_region_of = visible region of
+label.webservice_job_title_on = {0} using {1} on {2}
+label.updating_vamsas_session = Updating vamsas session
+label.loading_file = Loading File: {0}
+label.edit_params = Edit {0}
+error.not_implemented = Not implemented
+error.no_such_method_as_clone1_for = No such method as clone1 for {0}
+error.null_from_clone1 = Null from clone1!
+error.implementation_error_sortbyfeature = Implementation Error - sortByFeature method must be one of FEATURE_SCORE, FEATURE_LABEL or FEATURE_DENSITY.
+error.not_yet_implemented = Not yet implemented
+error.unknown_type_dna_or_pep = Unknown Type {0} - dna or pep are the only allowed values.
+error.implementation_error_dont_know_thereshold_annotationcolourgradient = Implementation error: don't know about threshold setting for current AnnotationColourGradient.
+error.implementation_error_embeddedpopup_not_null = Implementation error - embeddedPopup must be non-null
+error.invalid_colour_for_mycheckbox = Invalid color for MyCheckBox
+error.implementation_error_unrecognised_render_object_for_features_type = Implementation Error: Unrecognised render object {0} for features of type {1}
+error.implementation_error_unsupported_feature_colour_object = Implementation error: Unsupported feature colour object.
+error.invalid_separator_parameter = Invalid separator parameter - must be non-zero length
+error.alignment_cigararray_not_implemented = Alignment(CigarArray) not yet implemented
+error.weak_sequencei_equivalence_not_yet_implemented = Weak sequenceI equivalence not yet implemented.
+error.implementation_error_can_only_make_alignmnet_from_cigararray = Implementation Error - can only make an alignment view from a CigarArray of sequences.
+error.empty_view_cannot_be_updated = empty view cannot be updated.
+error.mismatch_between_number_of_sequences_in_block = Mismatch between number of sequences in block {0} ({1}) and the original view ({2})
+error.padding_not_yet_implemented = Padding not yet implemented
+error.mismatch_between_visible_blocks_to_update_and_number_of_contigs_in_view = Mismatch between visible blocks to update and number of contigs in view (contigs=0,blocks={0})
+error.unknown_seq_cigar_operation = Unknown SeqCigar operation {0}
+error.implementation_bug_parse_cigar_string = Implementation bug in parseCigarString
+error.implementation_error_invalid_operation_string = Implementation error. Invalid operation string.
+error.invalid_range_string = Invalid range string (must be zero or positive number)
+error.implementation_error_delete_range_out_of_bounds = Implementation Error: deleteRange out of bounds: start must be non-negative and less than end.
+error.implementation_error = Implementation error
+error.implementation_error_unknown_operation = Implementation Error! Unknown operation {0}
+error.implementation_error_unexpected_null_from_get_sequence_and_deletions = Implementation Error - unexpected null from getSequenceAndDeletions
+error.implementation_error_set_seq_null = Implementation Error - _setSeq(null,...)
+error.implementation_error_s = Implementation Error: _s= {0}
+error.implementation_error_seqcigar_possible = SeqCigar: Possible implementation error: sequence is longer than dataset sequence
+error.implmentation_bug_seq_null = Implementation Bug. Null seq
+error.implementation_bug_cigar_operation_list_range_list = Implementation Bug. Cigar Operation list!= range list
+error.not_yet_implemented_cigar_object_from_cigar_string = NOT YET Implemented: Constructing a Cigar object from a cigar string and a gapped sequence.
+error.implementation_bug_cigar_operation = Implementation Bug. Cigar Operation {0} {1} not one of {2}, {3}, or {4}.
+error.implementation_error_for_new_cigar = Implementation error for new Cigar(SequenceI)
+error.implementation_error_cigar_seq_no_operations = Implementation error: {0}th sequence Cigar has no operations.
+error.implementation_error_jmol_getting_data = Implementation error - Jmol seems to be still working on getting its data - report at http://issues.jalview.org/browse/JAL-1016
+error.implementation_error_no_pdbentry_from_index = Implementation error - no corresponding pdbentry (for index {0}) to add sequences mappings to
+error.jmol_version_not_compatible_with_jalview_version = Jmol version {0} is not compatible with this version of Jalview. Report this problem at issues.jalview.org
+error.not_implemented_remove = Remove: Not implemented
+error.not_implemented_clone = Clone: Not implemented
+error.implementation_error_chimera_getting_data = Implementation error - Chimera seems to be still working on getting its data - report at http://issues.jalview.org/browse/JAL-1016
+error.call_setprogressbar_before_registering_handler = call setProgressBar before registering the progress bar's handler.
+label.cancelled_params = Cancelled {0}
+error.implementation_error_cannot_show_view_alignment_frame = Implementation error: cannot show a view from another alignment in an AlignFrame.
+error.implementation_error_dont_know_about_thereshold_setting = Implementation error: don't know about threshold setting for current AnnotationColourGradient.
+error.eps_generation_not_implemented = EPS Generation not yet implemented
+error.png_generation_not_implemented = PNG Generation not yet implemented
+error.try_join_vamsas_session_another = Trying to join a vamsas session when another is already connected
+error.invalid_vamsas_session_id = Invalid vamsas session id
+error.implementation_error_cannot_create_groovyshell = Implementation Error. Cannot create groovyShell without Groovy on the classpath!
+label.groovy_support_failed = Jalview Groovy Support Failed
+label.couldnt_create_groovy_shell = Couldn't create the groovy Shell. Check the error log for the details of what went wrong.
+error.unsupported_version_calcIdparam = Unsupported Version for calcIdparam {0}
+error.implementation_error_cant_reorder_tree = Implementation Error: Can't reorder this tree. Not DefaultMutableTreeNode.
+error.invalid_value_for_option = Invalid value {0} for option {1}
+error.implementation_error_cannot_import_vamsas_doc = Implementation Error - cannot import existing vamsas document into an existing session, Yet!
+label.vamsas_doc_couldnt_be_opened_as_new_session = VAMSAS Document could not be opened as a new session - please choose another
+error.implementation_error_vamsas_operation_not_init = Impementation error! Vamsas Operations when client not initialised and connected
+error.jalview_no_connected_vamsas_session = Jalview not connected to Vamsas session
+error.implementation_error_cannot_recover_vamsas_object_mappings = IMPLEMENTATION ERROR: Cannot recover vamsas object mappings - no backup was made
+error.setstatus_called_non_existent_job_pane = setStatus called for non-existent job pane {0}
+error.implementation_error_cannot_find_marshaller_for_param_set =Implementation error: Can't find a marshaller for the parameter set
+error.implementation_error_old_jalview_object_not_bound =IMPLEMENTATION ERROR: old jalview object is not bound ! ({0})
+error.implementation_error_vamsas_doc_class_should_bind_to_type = Implementation Error: Vamsas Document Class {0} should bind to a {1} (found a {2})
+error.implementation_error_jalview_class_should_bind_to_type = Implementation Error: Jalview Class {0} should bind to a {1} (found a {2})
+error.invalid_vamsas_rangetype_cannot_resolve_lists = Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!
+error.implementation_error_maplist_is_null = Implementation error. MapList is null for initMapType.
+error.implementation_error_cannot_have_null_alignment = Implementation error: Cannot have null alignment property key
+error.implementation_error_null_fileparse = Implementation error. Null FileParse in copy constructor
+error.implementation_error_cannot_map_alignment_sequences = IMPLEMENTATION ERROR: Cannot map an alignment of sequences from different datasets into a single alignment in the vamsas document.
+error.implementation_error_cannot_duplicate_colour_scheme = Serious implementation error: cannot duplicate colourscheme {0}
+error.implementation_error_structure_selection_manager_null = Implementation error. Structure selection manager's context is 'null'
+exception.ssm_context_is_null = SSM context is null
+error.idstring_seqstrings_only_one_per_sequence = idstrings and seqstrings contain one string each per sequence
+error.cannot_have_mixed_length_replacement_vectors = Cannot have mixed length replacement vectors. Replacement vector for {0} is {1} strings long, and have already seen a {2} length vector.
+error.cannot_have_zero_length_vector_replacement_strings = Cannot have zero length vector of replacement strings - either 1 value or n values.
+error.implementation_error_multiple_single_sequence_prediction_jobs_not_supported = Implementation Error! Multiple single sequence prediction jobs are not yet supported
+error.implementation_error_invalid_msa_index_for_job =Implementation Error! Invalid msaIndex for JPredJob on parent MSA input object!
+error.implementation_error_startjob_called = Implementation error - StartJob(JpredJob) called on {0}
+error.multiple_jnet_subjob_merge_not_implemented = Multiple JNet subjob merging not yet implemented
+label.job_never_ran = Job never ran - input returned to user.
+error.implementation_error_minlen_must_be_greater_zero = Implementation error: minlen must be zero or more
+error.implementation_error_msawbjob_called = Implementation error - StartJob(MsaWSJob) called on a WSJobInstance {0}
+error.implementation_error_cannot_attach_ws_menu_entry = IMPLEMENTATION ERROR: cannot attach WS Menu Entry without service handle reference!
+error.parameter_migration_not_implemented_yet = Parameter migration not implemented yet
+error.implementation_error_cannot_set_jaba_option = Implementation error: cannot set Jaba Option to a value outside its allowed value range!
+error.implementation_error_valuetype_doesnt_support_jabaws_type = IMPLEMENTATION ERROR: jalview.ws.params.ValueConstrainI.ValueType does not support the JABAWS type : {0}
+error.cannot_create_jabaws_param_set = Cannot create a JabaWSParamSet from non-JabaWS parameters
+error.cannot_set_arguments_to_jabaws_param_set = Cannot set arguments to a JabaWSParamSet that are not JabaWS arguments
+error.implementation_error_runner_config_not_available = Implementation Error: Runner Config not available for a JABAWS service of type {0} ({1})
+error.implementation_error_cannot_handle_jaba_param = Implementation Error: Cannot handle Jaba parameter object {0}
+error.implementation_error_attempt_to_delete_service_preset = Implementation error: Attempt to delete a service preset!
+error.implementation_error_cannot_locate_oldname_presetname = Implementation error: Can't locate either oldname ({0}) or presetName ({1}in the datastore!"
+error.implementation_error_jabaws_param_set_only_handled_by = Implementation error: JabaWsParamSets can only be handled by JabaParamStore
+error.cannot_set_source_file_for = Cannot set source file for {0}
+error.mismatch_service_instance_preset = Probable mismatch between service instance and preset!
+error.cannot_set_params_for_ws_preset = Cannot set Parameters for a Jaba Web service's preset
+error.implementation_error_can_only_instantiate_jaba_param_sets = Implementation error: Can only instantiate Jaba parameter sets
+error.no_aacon_service_found = No AACon service found
+error.implementation_error_couldnt_copy_value_constraint = Implementation error: could not copy ValueConstrain!
+error.couldnt_encode_as_utf8 = Couldn't encode {0} as UTF-8.
+error.tree_inputtype_not_yet_implemented = Tree InputType not yet implemented
+error.implementation_error_need_to_have_httpresponse = Implementation Error: need to have an HttpResponse to process
+error.dbrefsource_implementation_exception =DBRefSource Implementation Exception
+error.implementation_error_dbinstance_must_implement_interface = Implmentation Error - getDbInstances must be given a class that implements jalview.ws.seqfetcher.DbSourceProxy (was given{0})
+error.implementation_error_must_init_dbsources =Implementation error. Must initialise dbSources
+label.view_controller_toggled_marked = {0} {1} columns {2} containing features of type {3} across {4} sequence(s)
+label.toggled = Toggled
+label.marked = Marked
+label.not = not
+label.no_feature_of_type_found = No features of type {0} found.
+label.submission_params = Submission {0}
+label.empty_alignment_job = Empty Alignment Job
+label.add_new_sbrs_service = Add a new Simple Bioinformatics Rest Service
+label.edit_sbrs_entry = Edit Simple Bioinformatics Rest Service entry
+label.pca_recalculating = Recalculating PCA
+label.pca_calculating = Calculating PCA
+label.select_foreground_colour = Choose foreground colour
+label.select_colour_for_text = Select Colour for Text
+label.adjunst_foreground_text_colour_thereshold = Adjust Foreground Text Colour Threshold
+label.select_subtree_colour = Select Sub-Tree Colour
+label.create_new_sequence_features = Create New Sequence Feature(s)
+label.amend_delete_features = Amend/Delete Features for {0}
+exception.out_of_bounds_for_file = Out of bounds for file: i={0}, Final Buffer: i0={1} iend={2}
+exception.null_string_given_to_regex_search = Null String Given to Regex.search
+exception.null_string_like_given_to_regex_search = Null StringLike Given to Regex.search
+exception.null_string_given_to_regex_reverse_search = Null String Given to Regex.reverseSearch
+exception.null_string_like_given_to_regex_reverse_search = Null StringLike Given to Regex.reverseSearch
+exception.null_string_like_given_to_regex_search_from = Null String Given to Regex.searchFrom
+exception.null_string_like_given_to_regex_search_region = Null String Given to Regex.searchRegion
+exception.replace_null_regex_pointer = Replacer has null Regex pointer
+exception.bad_pattern_to_regex_perl_code = bad pattern to Regex.perlCode: {0}
+exception.no_stub_implementation_for_interface = There is no stub implementation for the interface: {0}
+exception.cannot_set_endpoint_address_unknown_port = Cannot set Endpoint Address for Unknown Port {0}
+exception.querying_matching_opening_parenthesis_for_non_closing_parenthesis = Querying matching opening parenthesis for non-closing parenthesis character {0}
+exception.mismatched_unseen_closing_char = Mismatched (unseen) closing character {0}
+exception.mismatched_closing_char = Mismatched closing character {0}
+exception.mismatched_opening_char = Mismatched opening character {0} at {1}
+exception.invalid_datasource_couldnt_obtain_reader = Invalid datasource. Could not obtain Reader
+exception.index_value_not_in_range = {0}: Index value {1} not in range [0..{2}]
+exception.unterminated_cigar_string = Unterminated cigar string
+exception.unexpected_operation_cigar_string_pos = Unexpected operation {0} in cigar string (position {1} in {2}
+exception.couldnt_parse_responde_from_annotated3d_server = Couldn't parse response from Annotate3d server
+exception.application_test_npe = Application test: throwing an NullPointerException It should arrive at the console
+exception.overwriting_vamsas_id_binding = Overwriting vamsas id binding
+exception.overwriting_jalview_id_binding = Overwriting jalview id binding
+error.implementation_error_unknown_file_format_string = Implementation error: Unknown file format string
+exception.failed_to_resolve_gzip_stream = Failed to resolve GZIP stream
+exception.problem_opening_file_also_tried = Problem opening {0} (also tried {1}) : {2}
+exception.problem_opening_file = Problem opening {0} : {1}
+exception.failed_to_read_data_from_source = Failed to read data from source: {0}
+exception.no_init_source_stream = Unitialised Source Stream
+exception.invalid_source_stream = Invalid Source Stream: {0}
+error.implementation_error_reset_called_for_invalid_source = Implementation Error: Reset called for invalid source.
+exception.number_of_residues_in_query_sequence_differ_from_prediction = Number of residues in {0} supposed query sequence ({1}\n{2})\ndiffer from number of prediction sites in prediction ({3})
+label.mapped = mapped
+exception.jpredconcide_entry_has_unexpected_number_of_columns = JPredConcise: Entry ({0}) has an unexpected number of columns
+exception.couldnt_parse_concise_annotation_for_prediction = Couldn't parse concise annotation for prediction profile.\n{0}
+exception.newfile = NewickFile\: {0}\n
+label.no_tree_read_in = No Tree read in
+exception.rnaml_couldnt_access_datasource = Couldn't access datasource ({0})
+exception.ranml_couldnt_process_data = Couldn't process data as RNAML file ({0})
+exception.ranml_invalid_file = Invalid RNAML file ({0})
+exception.ranml_problem_parsing_data = Problem parsing data as RNAML ({0})
+exception.pfam_no_sequences_found = No sequences found (PFAM input)
+exception.stockholm_invalid_format = This file is not in valid STOCKHOLM format: First line does not contain '# STOCKHOLM'
+exception.couldnt_parse_sequence_line = Could not parse sequence line: {0}
+exception.error_parsing_line = Error parsing {0}
+exception.unknown_annotation_detected = Unknown annotation detected: {0} {1}
+exception.couldnt_store_sequence_mappings = Couldn't store sequence mappings for {0}
+exception.matrix_too_many_iteration = Too many iterations in {0} (max is {1})
+exception.browser_not_found = Exception in finding browser: {0}
+exception.browser_unable_to_locate = Unable to locate browser: {0}
+exception.invocation_target_exception_creating_aedesc = InvocationTargetException while creating AEDesc: {0}
+exception.illegal_access_building_apple_evt= IllegalAccessException while building AppleEvent: {0}
+exception.instantiation_creating_aedesc = InstantiationException while creating AEDesc: {0}
+exception.unable_to_launch_url = Unable to launch URL: {0}
+exception.unable_to_create_internet_config = Unable to create an Internet Config instance: {0}
+exception.invocation_target_calling_url = InvocationTargetException while calling openURL: {0}
+exception.illegal_access_calling_url = IllegalAccessException while calling openURL: {0}
+exception.interrupted_launching_browser = InterruptedException while launching browser: {0}
+exception.das_source_doesnt_support_sequence_command = Source {0} does not support the sequence command.
+exception.invalid_das_source = Invalid das source: {0}
+exception.ebiembl_retrieval_failed_on = EBI EMBL XML retrieval failed on {0}:{1}
+label.no_embl_record_found = # No EMBL record retrieved for {0}:{1}
+label.embl_successfully_parsed = # Successfully parsed the {0} queries into an Alignment
+exception.no_pdb_records_for_chain = No PDB Records for {0} chain {1}
+exception.unexpected_handling_rnaml_translation_for_pdb = Unexpected exception when handling RNAML translation of PDB data
+exception.couldnt_recover_sequence_properties_for_alignment = Couldn't recover sequence properties for alignment
+exception.unknown_format_for_file = Unknown format {0} for file \: \n{1}
+label.remove_gaps = Remove Gaps
+exception.couldnt_recover_sequence_props_for_jnet_query = Couldn't recover sequence properties for JNet Query sequence!
+exception.server_timeout_try_later = Server timed out - try again later\n
+exception.web_service_returned_null_try_later= Server at {0} returned null object, it probably cannot be contacted. Try again later.
+exception.cannot_contact_service_endpoint_at = Cannot contact service endpoint at {0}
+error.implementation_error_cannot_find_service_url_in_given_set = Implementation error: Cannot find service url in the given url set!
+error.implementation_error_cannot_find_service_url_in_given_set_param_store = Implementation error: Cannot find service url in the given url set for this service parameter store ({0}}
+exception.jobsubmission_invalid_params_set = Invalid parameter set. Check Jalview implementation
+exception.notvaliddata_group_contains_less_than_min_seqs = Group contains less than {0} sequences.
+exception.outofmemory_loading_pdb_file = Out of memory loading PDB File
+exception.eps_coudnt_write_output_file = Could not write to the output file: {0}
+exception.eps_method_not_supported = Method not currently supported by EpsGraphics2D version {0}
+exception.eps_unable_to_get_inverse_matrix = Unable to get inverse of matrix: {0}
+warn.job_cannot_be_cancelled_close_window = This job cannot be cancelled.\nJust close the window.
+warn.service_not_supported = Service not supported!
+warn.input_is_too_big = Input is too big!
+warn.invalid_job_param_set = Invalid job parameter set!
+info.job_couldnt_be_run_server_doesnt_support_program = Job could not be run because the server doesn't support this program.\n{0}
+info.job_couldnt_be_run_exceeded_hard_limit = Job could not be run because it exceeded a hard limit on the server.\n{0}
+info.job_couldnt_be_run_incorrect_param_setting = Job could not be run because some of the parameter settings are not supported by the server.\n{0}\nPlease check to make sure you have used the correct parameter set for this service\!\n
+info.no_jobs_ran = No jobs ran
+info.failed_to_submit_prediction = Failed to submit the prediction\:\n{0} {1}
+info.invalid_jnet_job_result_data ={0}\n{1}\nInvalid JNet job result data\!\n{2}
+info.failed_to_submit_sequences_for_alignment = Failed to submit sequences for alignment.\nIt is most likely that there is a problem with the server.\nJust close the window\n
+info.alignment_object_method_notes = \nAlignment Object Method Notes\n
+info.server_exception = \n{0} Server exception\!\n{1}
+status.processing_commandline_args = Processing commandline arguments...
+status.das_features_being_retrived = DAS features being retrieved...
+status.searching_for_sequences_from = Searching for sequences from {0}
+status.finished_searching_for_sequences_from = Finished searching for sequences from {0}
+label.eps_file = EPS file
+label.png_image = PNG image
+status.saving_file = Saving {0}
+status.export_complete = Export complete.
+status.fetching_pdb = Fetching PDB {0}
+status.refreshing_news = Refreshing news
+status.importing_vamsas_session_from = Importing VAMSAS session from {0}
+status.opening_params = Opening {0}
+status.waiting_sequence_database_fetchers_init = Waiting for Sequence Database Fetchers to initialise
+status.init_sequence_database_fetchers = Initialising Sequence Database Fetchers
+status.fetching_sequence_queries_from = Fetching {0} sequence queries from {1}
+status.finshed_querying = Finished querying
+status.parsing_results = Parsing results.
+status.processing = Processing...
+status.refreshing_web_service_menus = Refreshing Web Service Menus
+status.collecting_job_results = Collecting job results.
+status.fetching_das_sequence_features = Fetching DAS Sequence Features
+status.no_das_sources_active = No DAS Sources Active
+status.das_feature_fetching_cancelled = DAS Feature Fetching Cancelled
+status.das_feature_fetching_complete = DAS Feature Fetching Complete
+status.fetching_db_refs = Fetching db refs
+label.font_doesnt_have_letters_defined = Font doesn't have letters defined\nso cannot be used\nwith alignment data
+label.error_loading_file_params = Error loading file {0}
+label.error_loading_jalview_file = Error loading Jalview file
+warn.out_of_memory_when_action = Out of memory when {0}\!\!\nSee help files for increasing Java Virtual Machine memory.
+warn.out_of_memory_loading_file = Out of memory loading file {0}\!\!\nSee help files for increasing Java Virtual Machine memory.
+label.out_of_memory = Out of memory
+label.invalid_id_column_width = Invalid ID Column width
+warn.user_defined_width_requirements = The user defined width for the\nannotation and sequence ID columns\nin exported figures must be\nat least 12 pixels wide.
+label.couldnt_create_sequence_fetcher = Couldn't create SequenceFetcher
+warn.couldnt_create_sequence_fetcher_client = Could not create the sequence fetcher client. Check error logs for details.
+warn.server_didnt_pass_validation = Service did not pass validation.\nCheck the Jalview Console for more details.
+warn.url_must_contain = Sequence URL must contain $SEQUENCE_ID$ or a regex $SEQUENCE_ID=/<regex>/=$
+info.validate_jabaws_server = Validate JabaWS Server ?\n(Look in console output for results)
+label.test_server = Test Server?
+info.you_want_jalview_to_find_uniprot_accessions = Do you want Jalview to find\nUniprot Accession ids for given sequence names?
+label.find_uniprot_accession_ids = Find Uniprot Accession Ids
+label.new_sequence_fetcher = New Sequence Fetcher
+label.additional_sequence_fetcher = Additional Sequence Fetcher
+label.select_database_retrieval_source = Select Database Retrieval Source
+label.overwrite_existing_file = Overwrite existing file?
+label.file_already_exists = File exists
+label.edit_jabaws_url = Edit JABAWS URL
+label.add_jabaws_url = Add new JABAWS URL
+label.news_from_jalview = News from http://www.jalview.org
+label.cut_paste_alignmen_file = Cut & Paste Alignment File
+label.enter_redundancy_thereshold = Enter the redundancy threshold
+label.select_dark_light_set_thereshold = <html><i>Select a dark and light text colour, then set the threshold to<br>switch between colours, based on background colour</i></html>
+label.select_feature_colour = Select Feature Colour
+label.delete_all = Delete all sequences
+warn.delete_all = <html>Deleting all sequences will close the alignment window.<br>Confirm deletion or Cancel.
+label.add_annotations_for = Add annotations for
+label.choose_annotations = Choose annotations
+label.find = Find
+label.invalid_search = Search string invalid
+error.invalid_regex = Invalid regular expression
+label.ignore_gaps_consensus = Ignore Gaps In Consensus
+label.show_group_histogram = Show Group Histogram
+label.show_group_logo = Show Group Logo
+label.normalise_group_logo = Normalise Group Logo
+label.show_histogram = Show Histogram
+label.show_logo = Show Logo
+label.normalise_logo = Normalise Logo
+label.no_colour_selection_in_scheme = Please, make a colour selection before to apply colour scheme
+label.no_colour_selection_warn = Error saving colour scheme
-action.cancel = Cancelar\r
-action.create = Crear\r
-action.update = Actualizar\r
-action.delete = Borrar\r
-action.snapshot = Captura\r
-action.clear = Limpiar\r
-action.accept = Aceptar\r
+action.refresh_services = Refrescar servicios
+action.reset_services = Reiniciar servicios
+action.merge_results = Unificar resultados
+action.load_scheme = Cargar esquema
+action.save_scheme = Guardar esquema
+action.save_image = Guardar imagen
+action.paste = Pegar
+action.show_html_source = Mostrar código HTML
+action.print = Imprimir
+action.web_service = Servicio web
+action.cancel_job = Cancelar trabajo
+action.start_job = Arrancar trabajo
+action.revert = Deshacer
+action.move_down = Mover hacia abajo
+action.move_up = Mover hacia arriba
+action.remove_return_datatype = Borrar tipo de datos de retorno
+action.add_return_datatype = Añadir tipo de datos de retorno
+action.remove_input_parameter = Borrar el parámetro de entrada seleccionado
+action.add_input_parameter = Añadir parámetro de entrada seleccionado
+action.edit = Editar
+action.new = Nuevo
+action.open_file = Abrir fichero
+action.show_unconserved = Mostrar regiones no conservadas
+action.open_new_alignment = Abrir nuevo alineamiento
+action.raise_associated_windows = Destacar ventanas asociadas
+action.minimize_associated_windows = Minimizar ventanas asociadas
+action.close_all = Cerrar todo
+action.load_project = Cargar proyecto
+action.save_project = Guardar proyecto
+action.quit = Salir
+action.expand_views = Expandir vistas
+action.gather_views = Capturar vistas
+action.page_setup = Configuración de la página
+action.reload = Recargar
+action.load = Cargar
+action.open = Abrir
+action.cancel = Cancelar
+action.create = Crear
+action.update = Actualizar
+action.delete = Borrar
+action.snapshot = Imagen
+action.clear = Limpiar
+action.accept = Aceptar
+action.select_ddbb = --- Seleccionar base de datos ---
+action.undo = Deshacer
+action.redo = Rehacer
+action.reset = Reiniciar
+action.remove_left = Eliminar parte izquierda
+action.remove_right = Eliminar parte derecha
+action.remove_empty_columns = Eliminar las columnas vacías
+action.remove_all_gaps = Eliminar todos los huecos
+action.left_justify_alignment = Ajustar el alineamiento a la izquierda
+action.right_justify_alignment = Ajustar el alineamiento a la derecha
+action.boxes = Casillas
+action.text = Texto
+action.by_pairwise_id = Identificar por parejas
+action.by_id = Por identificador
+action.by_length = Por longitud
+action.by_group = Por grupo
+action.remove = Eliminar
+action.remove_redundancy = Eliminar redundancia...
+action.pairwise_alignment = Alineamiento de pares...
+action.by_rna_helixes = Por hélices de RNA
+action.user_defined = Definido por el usuario...
+action.by_conservation = Por conservación
+action.wrap = Envolver
+action.show_gaps = Mostrar huecos
+action.show_hidden_markers = Mostrar marcadores ocultos
+action.find = Buscar
+action.undefine_groups = Grupos sin definir
+action.create_groups = Crear grupos
+action.make_groups_selection = Hacer grupos para seleccionar
+action.copy = Copiar
+action.cut = Cortar
+action.font = Fuente...
+action.scale_above = Escala superior
+action.scale_left = Escala izquierda
+action.scale_right = Escala derecha
+action.by_tree_order = Por orden del árbol
+action.sort = Ordenar
+action.calculate_tree = Calcular árbol
+action.help = Ayuda
+action.by_annotation = Por anotación...
+action.invert_sequence_selection = Invertir selección de secuencias
+action.invert_column_selection = Invertir selección de columnas
+action.show = Mostrar
+action.hide = Ocultar
+action.ok = OK
+action.set_defaults = Defecto
+action.create_group = Crear grupo
+action.remove_group = Eliminar grupo
+action.edit_group = Editar grupo
+action.border_colour = Color del borde
+action.edit_new_group = Editar nuevo grupo
+action.hide_sequences = Ocultar secuencias
+action.sequences = Secuencias
+action.ids = IDS
+action.ids_sequences = IDS y secuencias
+action.reveal_all = Revelar todo
+action.reveal_sequences = Revelar secuencias
+action.find_all = Buscar todo
+action.find_next = Buscar siguiente
+action.file = Archivo
+action.view = Ver
+action.change_params = Cambiar parámetros
+action.apply = Aplicar
+action.apply_threshold_all_groups = Aplicar umbral a todos los grupos
+action.apply_all_groups = Aplicar a todos los grupos
+action.by_chain = Por cadena
+action.by_sequence = Por secuencia
+action.paste_annotations = Pegar anotaciones
+action.format = Formato
+action.select = Seleccionar
+action.new_view = Nueva vista
+action.close = Cerrar
+action.add = Añadir
+action.save_as_default = Guardar como por defecto
+action.save_as = Guardar como
+action.save = Guardar
+action.cancel_fetch = Cancelar búsqueda
+action.save_omit_hidden_columns = Guardar / Omitir las columnas ocultas
+action.change_font = Cambiar Fuente
+action.change_font_tree_panel = Cambiar fuente (panel del árbol)
+action.colour = Color
+action.calculate = Calcular
+action.select_all = Seleccionar Todo
+action.deselect_all = Deseleccionar Todo
+action.invert_selection = Invertir selección
+action.using_jmol = Usar Jmol
+action.link = Enlazar
+action.group_link = Enlazar grupo
+action.show_chain = Mostrar cadena
+action.show_group = Mostrar grupo
+action.fetch_db_references = Recuperar referencias a base de datos
+action.view_flanking_regions = Mostrar flancos
+label.view_flanking_regions = Mostrar los datos de la secuencia a ambos lados de las subsecuencias implicadas en este alineamiento
+label.str = Str:
+label.seq = Seq:
+label.structures_manager = Administrar estructuras
+label.nickname = Sobrenombre:
+label.url = URL:
+label.input_file_url = Introducir URL en el fichero de entrada
+label.select_feature = Seleccionar función:
+label.name = Nombre:
+label.name_param = Nombre: {0}
+label.group = Grupo:
+label.group_name = Nombre del grupo
+label.group_description = Descripción del grupo
+label.edit_group_name_description = Editar nombre/descripción del grupo
+label.colour = Color:
+label.description = Descripción:
+label.start = Comenzar:
+label.end = Terminar:
+label.current_parameter_set_name = Nombre actual del conjunto de parámetros:
+label.service_action = Acción de servicio:
+label.post_url = POST URL:
+label.url_suffix = URL Sufijo
+label.sequence_source = Fuente de la secuencia
+label.per_seq = por secuencia
+label.result_vertically_separable = Los resultados son separables verticalmente
+label.amend = Modificar
+label.undo_command = Deshacer {0}
+label.redo_command = Rehacer {0}
+label.principal_component_analysis = Análisis del Componente Principal
+label.average_distance_identity = Distancia Media Usando % de Identidad
+label.neighbour_joining_identity = Unir vecinos utilizando % de Identidad
+label.treecalc_title = {0} utilizando {1}
+label.tree_calc_av = Distancia media
+label.tree_calc_nj = Unir vecinos
+label.select_score_model = Selecciones modelo de puntuación
+label.score_model_pid = % Identidad
+label.score_model_blosum62 = BLOSUM62
+label.score_model_pam250 = PAM 250
+label.score_model_conservation = Conservación de las propiedades físico-químicas
+label.score_model_enhconservation = Conservación de las propiedades físico-químicas
+label.status_bar = Barra de estado
+label.out_to_textbox = Generar cuadro de texto
+label.clustalx = Clustalx
+label.clustal = Clustal
+label.zappo = Zappo
+label.taylor = Taylor
+label.blc = BLC
+label.fasta = Fasta
+label.msf = MSF
+label.pfam = PFAM
+label.pileup = Pileup
+label.pir = PIR
+label.hydrophobicity = Hidrofobicidad
+label.helix_propensity = Tendencia de la hélice
+label.strand_propensity = Tendencia de la hebra
+label.turn_propensity = Tendencia de giro
+label.buried_index = Índice de encubrimiento
+label.purine_pyrimidine = Purina/Pirimidina
+label.percentage_identity = Porcentaje de identidad
+label.blosum62 = BLOSUM62
+label.blosum62_score = Puntuación del BLOSUM62
+label.tcoffee_scores = Puntuación del T-Coffee
+label.average_distance_bloslum62 = Distancia Media Usando BLOSUM62
+label.neighbour_blosum62 = Neighbour Joining usando BLOSUM62
+label.show_annotations = Mostrar anotaciones
+label.colour_text = Color del texto
+label.show_non_conversed = Mostrar no conservadas
+label.overview_window = Ventana resumen
+label.none = Ninguno
+label.above_identity_threshold = Por encima del umbral de identidad
+label.show_sequence_features = Mostrar las características de las secuencias
+label.nucleotide = Nucleótido
+label.to_new_alignment = A nuevo alineamiento
+label.to_this_alignment = Añadir a este alineamiento
+label.apply_colour_to_all_groups = Aplicar color a todos los grupos
+label.modify_identity_thereshold = Modificar el umbral de identidad...
+label.modify_conservation_thereshold = Modificar el umbral de conservación...
+label.input_from_textbox = Introducir desde el cuadro de texto
+label.centre_column_labels = Centrar las etiquetas de las columnas
+label.automatic_scrolling = Desplazamiento automático
+label.documentation = Documentación
+label.about = Acerca de...
+label.show_sequence_limits = Mostrar los límites de la secuencia
+label.feature_settings = Ajustar funciones...
+label.sequence_features = Funciones de la secuencia
+label.all_columns = Todas las columnas
+label.all_sequences = Todas las secuencias
+label.selected_columns = Columnas seleccionadas
+label.selected_sequences = Secuencias seleccionadas
+label.all_but_selected_region = Todo menos la región seleccionada (Shift+Ctrl+H)
+label.selected_region = Región seleccionada
+label.all_sequences_columns = Todas las secuencias y columnas
+label.group_consensus = Consenso de grupo
+label.group_conservation = Conservación de grupo
+label.show_consensus_histogram = Mostrar el histograma de consenso
+label.show_consensus_logo = Mostrar el logo de consenso
+label.norm_consensus_logo = Normalizar el logo de consenso
+label.apply_all_groups = Aplicar a todos los grupos
+label.autocalculated_annotation = Anotación autocalculada
+label.min_colour = Color mínimo
+label.max_colour = Color máximo
+label.use_original_colours = Usar colores originales
+label.threshold_minmax = El umbral es mín/máx
+label.represent_group_with = Representar al grupo con
+label.selection = Seleccionar
+label.group_colour = Color del grupo
+label.sequence = Secuencia
+label.view_pdb_structure = Ver estructura PDB
+label.min = Mín:
+label.max = Máx:
+label.colour_by_label = Color por etiquetas
+label.new_feature = Nueva función
+label.match_case = Hacer corresponder mayúsculas y minúsculas
+label.view_alignment_editor = Ver en el editor de alineamientos
+label.labels = Etiquetas
+label.output_values = Valores de salida...
+label.output_points = Puntos de salida...
+label.output_transformed_points = Puntos de salida transformados
+label.input_data = Datos de entrada...
+label.nucleotide_matrix = Matriz nucleotídica
+label.protein_matrix = Matriz proteica
+label.show_bootstrap_values = Mostrar valores de Bootstrap
+label.show_distances = Mostrar distancias
+label.mark_unassociated_leaves = Marcar hojas no asociadas
+label.fit_to_window = Ajustar a la ventana
+label.newick_format = Formato Newick
+label.select_newick_like_tree_file = Seleccione un fichero de árbol tipo Newick
+label.colours = Colores
+label.view_mapping = Ver mapeado
+label.wireframe = Estructura metálica
+label.depthcue = Clave de profundidad
+label.z_buffering = Tamponamiento Z
+label.charge_cysteine = Carga & Cisteína
+label.all_chains_visible = Todas las cadenas visibles
+label.successfully_added_features_alignment = Funciones añadidas exitosamente al alineamiento
+label.keyboard_editing_mode = El modo de editar teclado es {0}
+label.paste_features_annotations_Tcoffee_here = Pegar tus funciones / anotaciones / puntuación del fichero T-coffee aquí.
+label.removed_columns = {0} columnas eliminadas.
+label.removed_empty_columns = {0} columnas vacías eliminadas.
+label.paste_newick_tree_file = Pegar su fichero árbol Newick aquí.
+label.order_by_params = Ordenar por {0}
+label.html_content = <html>{0}</html>
+label.paste_pdb_file= Pegar tu fichero PDB aquí.
+label.paste_pdb_file_for_sequence = Pegar fichero PDB para la secuencia {0}
+label.could_not_parse_newick_file = No se pudo analizar el fichero Newick\\\!\\n {0}
+label.successfully_pasted_tcoffee_scores_to_alignment= Pegada exitosamente la puntuación T-Coffee al alineamiento.
+label.failed_add_tcoffee_scores = Fallo al añadir las puntuaciones T-Coffee:
+label.successfully_pasted_annotation_to_alignment = Anotación pegada exitosamente al alineamiento.
+label.couldnt_parse_pasted_text_as_valid_annotation_feature_GFF_tcoffee_file = No es posible parsear el texto pegado como una anotación características, GFF, o fichero T-Coffee válidos
+label.successfully_pasted_alignment_file = Fichero de alineamiento pegado exitosamente
+label.paste_your_alignment_file = Pegar su fichero de alineamiento aquí
+label.paste_your = Pegar su
+label.finished_searching = Búsqueda finalizada
+label.search_results= Buscar Resultados {0} : {1}
+label.found_match_for = Buscar coincidencia para {0}
+label.font = Fuente:
+label.size = Talla:
+label.style = Estilo:
+label.enter_redundancy_threshold = Introducir el umbral de redundancia
+label.calculating = Calculando....
+label.modify_conservation_visibility = Modificar la visibilidad de conservación
+label.colour_residues_above_occurence = Residuos de color por encima del % de aparición
+label.set_this_label_text = fijar como etiqueta
+label.sequences_from = Secuencias de {0}
+label.successfully_loaded_file = Fichero cargado exitosamente {0}
+label.successfully_saved_to_file_in_format = Guardado exitosamente en el fichero: {0} en formato {1}.
+label.copied_sequences_to_clipboard = Copiadas {0} secuencias en el portapapeles.
+label.check_file_matches_sequence_ids_alignment = Comprobar que el fichero coincide con el ID de la secuencia en el alineamiento.
+label.problem_reading_tcoffee_score_file = Problema de lectura del fichero de puntuaciones T-COFFEE
+label.source_to_target = {0} a {1}
+label.per_sequence_only= Sólo por secuencia
+label.to_file = a fichero
+label.to_textbox = a cuadro de texto
+label.jalview = Jalview
+label.csv_spreadsheet = CSV (Hoja de cálculo)
+label.status = [Estado]
+label.channels = Canales
+label.channel_title_item_count = {0} ({1})
+label.blog_item_published_on_date = {0} {1}
+label.select_das_service_from_table = Seleccionar servicio DAS de la tabla para leer una descripción completa aquí.
+label.session_update = Actualizar sesión
+label.new_vamsas_session = Nueva sesión Vamsas
+label.load_vamsas_session = Cargar sesión Vamsas
+label.save_vamsas_session = Guardar sesión Vamsas
+label.select_vamsas_session_opened_as_new_vamsas_session= Selecciones una sesión vamsas para abrirla como una nueva sesión.
+label.open_saved_vamsas_session = Abrir una sesión VAMSAS guardada
+label.groovy_console = Consola Groovy
+label.lineart = lineart
+label.dont_ask_me_again = No volver a preguntar
+label.select_eps_character_rendering_style = Seleccionar el carácter EPS como estilo de visualización
+label.invert_selection = Invertir selección
+label.optimise_order = Optimizar orden
+label.seq_sort_by_score = Ordenar las secuencias por puntuación
+label.load_colours = Cargar colores
+label.save_colours = Guardar colores
+label.fetch_das_features = Recuperar funciones DAS
+label.selected_database_to_fetch_from = Seleccionada {0} Base de datos {1} para buscar de {2}
+label.database_param = Base de datos: {0}
+label.example = Ejemplo
+label.example_param = Ejemplo: {0}
+label.select_file_format_before_saving = Debe seleccionar un formato de fichero antes de guardar!
+label.file_format_not_specified = Formato de fichero no especificado
+label.alignment_contains_hidden_columns = El alineamiento contiene columnas ocultas.\\nQuieres guardar s\u00F3lo el alineamiento visible?
+label.couldnt_save_file = No se pudo guardar el fichero: {0}
+label.error_saving_file = Error guardando el fichero
+label.remove_from_default_list = eliminar de la lista de defectuosos?
+label.remove_user_defined_colour = Eliminar el color definido por el usuario
+label.you_must_select_least_two_sequences = Debes seleccionar al menos 2 secuencias.
+label.invalid_selection = Selección inválida
+label.principal_component_analysis_must_take_least_four_input_sequences = El an\u00E1lisis de la componente principal debe tomar\\nal menos 4 secuencias de entrada.
+label.sequence_selection_insufficient = Selección de secuencias insuficiente
+label.you_need_more_two_sequences_selected_build_tree = necesitas seleccionar más de dos secuencias para construir un árbol!
+label.not_enough_sequences = No suficientes secuencias
+label.selected_region_to_tree_may_only_contain_residues_or_gaps = La regi\u00F3n seleccionada para construir un \u00E1rbol puede\\ncontener s\u00F3lo residuos o espacios.\\nPrueba usando la funci\u00F3n Pad en el men\u00FA de edici\u00F3n,\\n o uno de los m\u00FAltiples servicios web de alineamiento de secuencias.
+label.sequences_selection_not_aligned = Las secuencias seleccionadas no están alineadas
+label.sequences_must_be_aligned_before_creating_tree = Las secuencias deben estar alineadas antes de crear el \u00E1rbol.\\nPrueba usando la funci\u00F3n Pad en el men\u00FA de editar,\\n o uno de los m\u00FAltiples servicios web de alineamiento de secuencias.
+label.sequences_not_aligned = Secuencias no alineadas
+label.problem_reading_tree_file = Problema al leer el fichero del árbol
+label.possible_problem_with_tree_file = Posible problema con el fichero del árbol
+label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation = Por favor seleccionar al menos tres bases de al menos una secuencia para poder realizar la traducción de cDNA.
+label.translation_failed = Translation Failed
+label.error_when_translating_sequences_submit_bug_report = Desafortunadamente, algo fue mal a la hora de traducir tus secuencias.\\nPor favor, revisa la consola Jalview java \\ny presenta un informe de error que incluya el seguimiento.
+label.implementation_error = Error de implementación:
+label.automatically_associate_pdb_files_with_sequences_same_name = Quieres asociar automáticamente los {0} ficheros PDB con las secuencias del alineamiento que tengan el mismo nombre?
+label.automatically_associate_pdb_files_by_name = Asociar los ficheros PDB por nombre automáticamente
+label.ignore_unmatched_dropped_files_info = Quieres <em>ignorar</em> los {0} ficheros cuyos nombres no coincidan con ningún IDs de las secuencias ?
+label.ignore_unmatched_dropped_files = Ignorar los ficheros sin coincidencias?
+label.enter_view_name = Introducir nombre visible (¿?)
+label.enter_label = Introducir etiqueta
+label.enter_label_for_the_structure = Introducir una etiqueta para la estructura?
+label.pdb_entry_is_already_displayed = {0} Ya est\u00E1 mostrado.\\nQuieres volver a usar este visor?
+label.map_sequences_to_visible_window = Mapa de secuencias en ventana visible: {0}
+label.add_pdbentry_to_view = Quieres a\u00F1adir {0} a la vista llamada\\n{1}\\n
+label.align_to_existing_structure_view = Alinear a una estructura ya existente
+label.pdb_entries_couldnt_be_retrieved = Las siguientes entradas pdb no pueden ser extra\u00EDdas del PDB\\\:\\n{0}\\nPor favor, prueba descarg\u00E1ndolas manualmente.
+label.couldnt_load_file = No se pudo cargar el fichero
+label.couldnt_find_pdb_id_in_file = No se pudo encontrar un Id PDB en el fichero suministrado. Por favor, introduzca un Id para identificar esta estructura.
+label.no_pdb_id_in_file = No hay un Id PDB en el fichero
+label.couldnt_read_pasted_text = No se pudo leer el texto pegado {0}
+label.error_parsing_text = Error analizando el texto
+label.enter_local_das_source = Intruduzca el Nickname & URL de la fuente DAS local
+label.you_can_only_edit_or_remove_local_das_sources = Sólo puedes editar o eliminar fuentes DAS locales!
+label.public_das_source = Fuente pública DAS - no editable
+label.input_alignment_from_url = Alineamiento de entrada desde URL
+label.input_alignment = Alineamiento de entrada
+label.couldnt_import_as_vamsas_session = No se pudo importar {0} como una nueva sesión Vamsas.
+label.vamsas_document_import_failed = Fallo en la importación del documento Vamsas
+label.couldnt_locate = No se pudo localizar {0}
+label.url_not_found = URL no encontrada
+label.no_link_selected = Enlace no seleccionado
+label.new_sequence_url_link = Enlace a una nueva secuencia URL
+label.cannot_edit_annotations_in_wrapped_view = No se pueden editar anotaciones en vista envolvente
+label.wrapped_view_no_edit = Vista envolvente - no editar
+label.error_retrieving_data = Error en la recuperación de datos
+label.user_colour_scheme_must_have_name = El esquema de colores del usuario debe tener un nombre
+label.no_name_colour_scheme = No hay nombre para el esquema de colores
+label.invalid_url = URL Invalido!
+label.error_loading_file = Error al cargar el fichero
+label.problems_opening_file = Encontrados problemas al abrir el fichero {0}!!
+label.file_open_error = Error al abrir el fichero
+label.no_das_sources_selected_warn = No han sido seleccionadas fuentes DAS.\\nPor favor, seleccione algunas fuentes y\\npruebe de nuevo.
+label.no_das_sources_selected_title = No han sido seleccionadas fuentes DAS
+label.colour_scheme_exists_overwrite = El esquema de colores {0} ya existe.\\nContinuar guardando el esquema de colores como {1}?
+label.duplicate_scheme_name = Duplicar nombre de esquema
+label.jalview_new_questionnaire = Hay un nuevo cuestionario disponible. Querr\u00EDa completarlo ahora ?\\n
+label.jalview_user_survey = Encuesta de usuario Jalview
+label.alignment_properties = Propiedades del alineamiento: {0}
+label.alignment_props = Propiedades del alineamiento
+label.input_cut_paste = Cortar y pegar la entrada
+label.input_cut_paste_params = Cortar y pegar la entrada - {0}
+label.alignment_output_command = Alineamiento de salida - {0}
+label.annotations = Anotaciones
+label.features = Funciones
+label.overview_params = Visión general {0}
+label.paste_newick_file = Pegar nuevo fichero Newick
+label.load_tree_from_file = desde fichero -
+label.colour_by_annotation = Color por anotación
+label.selection_output_command = Seleccionar salida - {0}
+label.annotation_for_displayid = <p><h2>Anotación para {0} </h2></p><p>
+label.pdb_sequence_mapping = PDB - Mapeado de secuencia
+label.pca_details = detalles de la PCA
+label.redundancy_threshold_selection = Selección del umbral de redundancia
+label.user_defined_colours = Colores definidos del usuario
+label.jalviewLite_release = JalviewLite - versión {0}
+label.jaview_build_date = Fecha de creación: {0}
+label.jalview_authors_1 = Authors: Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui,
+label.jalview_authors_2 = Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton.
+label.jalview_dev_managers = Desarrollo gestionado por The Barton Group, University of Dundee, Scotland, UK.
+label.jalview_distribution_lists = Para ayuda, ver el FAQ at www.jalview.org y/o adjuntar la lista de envío jalview-discuss@jalview.org
+label.jalview_please_cite = Si usa Jalview incluya la siguiente cita, por favor:
+label.jalview_cite_1_authors = Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)
+label.jalview_cite_1_title = Jalview Version 2 - un editor de alineamiento múltiple de secuencias y banco de trabajo de análisis
+label.jalview_cite_1_ref = Bioinformaticos doi: 10.1093/bioinformatics/btp033
+label.right_click = clic en el botón derecho
+label.to_add_annotation = para añadir anotación
+label.alignment_has_no_annotations = El alineamiento no tiene anotaciones
+label.retrieving_pdb_data = Recuperación de datos PDB...
+label.label = Etiqueta
+label.no_features_added_to_this_alignment = No hay funciones asociadas a este alineamiento!!
+label.features_can_be_added_from_searches_1 = (Las funciones pueden ser añadidas de búsquedas o
+label.features_can_be_added_from_searches_2 = de ficheros de funciones Jalview / GFF)
+label.calculating_pca= Calculando PCA
+label.reveal_columns = Mostrar Columnas
+label.jalview_cannot_open_file = Jalview no puede abrir el fichero
+label.jalview_applet = Aplicación Jalview
+label.loading_data = Cargando datos
+label.memory_stats = Memoria libre total: {0} MB; Memoria máxima: {1} MB; {2} %
+label.calculating_tree = Calculando árbol
+label.state_queueing = En cola
+label.state_running = Procesando
+label.state_complete = Completar
+label.state_completed = Finalizado
+label.state_job_cancelled = ¡Trabajo cancelado!
+label.state_job_error = Error del trabajo!
+label.server_error_try_later = ¡Error del servidor! (Intentar más tarde)
+label.error_loading_pdb_data = ¡Error cargando los datos PDB!
+label.fetching_pdb_data = Buscando los datos PDB...
+label.structure_type = Estructura_tipo
+label.settings_for_type = Ajustes para {0}
+label.view_full_application = Ver en la aplicación completa
+label.load_associated_tree = Cargar árbol asociado ...
+label.load_features_annotations = Cargar características/anotaciones ...
+label.export_features = Exportar características...
+label.export_annotations = Exportar anotaciones ...
+label.jalview_copy = Copiar (sólo Jalview)
+label.jalview_cut = Cortar (sólo Jalview)
+label.to_upper_case = Pasar a mayúsculas
+label.to_lower_case = Pasar a minúsculas
+label.toggle_case = Alternar mayúsculas y minúsculas
+label.edit_name_description = Editar nombre/descripción
+label.create_sequence_feature = Crear función de secuencia
+label.edit_sequence = Editar secuencia
+label.edit_sequences = Editar secuencias
+label.sequence_details = Detalles de la secuencia
+label.jmol_help = Ayuda de Jmol
+label.all = Todo
+label.sort_by = Ordenar por
+label.sort_by_score = Ordenar por puntuación
+label.sort_by_density = Ordenar por densidad
+label.sequence_sort_by_density = Ordenar las secuencias por densidad
+label.reveal = Revelar
+label.hide_columns = Ocultar columnas
+label.load_jalview_annotations = Cargar un fichero de anotación de Jalivew o un fichero de características
+label.load_tree_file = Cargar un fichero de árbol
+label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences = Recuperar y parsear un registro de secuencia de base de datos para el alineamiento o secuencias actualmente seleccionados
+label.standard_databases = Bases de datos estándar
+label.fetch_embl_uniprot = Recuperar de EMBL/EMBLCDS o Uniprot/PDB y de cualquier fuente DAS seleccionada
+label.reset_min_max_colours_to_defaults = Reiniciar los colores min y max colours a los valores por defecto establecidos en las preferencias de usuario
+label.align_structures_using_linked_alignment_views = Alinear las estructuras utlizando las {0} vistas de alineamiento enlazadas
+label.connect_to_session = Conectar a la sesión {0}
+label.threshold_feature_display_by_score = Filtrar la característica mostrada por puntuación.
+label.threshold_feature_no_thereshold = Sin umbral
+label.threshold_feature_above_thereshold = Por encima del umbral
+label.threshold_feature_below_thereshold = Por debajo del umbral
+label.adjust_thereshold = Ajustar umbral
+label.toggle_absolute_relative_display_threshold = Cambiar entre mostrar el umbral absoluto y el relativo.
+label.display_features_same_type_different_label_using_different_colour = Mostrar las características del mismo tipo con una etiqueta diferente y empleando un color distinto (p.e. características del dominio)
+label.select_colour_minimum_value = Seleccionar el color para el valor mínimo
+label.select_colour_maximum_value = Seleccionar el color para el valor máximo
+label.open_new_jmol_view_with_all_structures_associated_current_selection_superimpose_using_alignment = Abrir una nueva vista Jmol con todas las estructuras asociadas con la selección acxtual y superponer las utilizando el alineamiento.
+label.open_url_param = Abrir URL {0}
+label.open_url_seqs_param = Abrir URL ({0}..) ({1} secuencias)
+label.load_pdb_file_associate_with_sequence = Cargar un fichero PDB y asociarlo con la secuencia {0}
+label.reveal_hidden_columns = Revelar las columnas ocultas con el botón derecho del ratón
+label.dark_colour = Oscurecer color
+label.light_colour = Aclarar color
+label.highlightnode = Pulse el botón izquierdo para seleccionar las hojas.<br>Haga doble clic para invertir las hojas.<br>Pulse el botón derecho para cambiar el color.
+label.load_colour_scheme = Cargar esquema cromático
+label.toggle_enabled_views = Cuando está habilitado, permite que se seleccionen varias vistas.
+label.edit_notes_parameter_set = Haga clic para editar las notas de este conjunto de parámetros.
+label.open_local_file = Abrir fichero local
+label.enable_automatically_sort_alignment_when_open_new_tree = Habilite esta opción para ordenar automáticamente<br>el alineamiento cuando abra<br> un nuevo árbol.
+label.listen_for_selections = Atención a las selecciones
+label.selections_mirror_selections_made_same_sequences_other_views = Cuando está habilitado, las selecciones de esta vista serán un reflejo<br>de las selecciones realizadas en las mismas secuencias de otras vistas.
+label.toggle_sequence_visibility = Shift+H cambia la visibilidad de la secuencia
+label.toggle_columns_visibility = Ctrl+H cambia la visibilidad de la columna
+label.toggles_visibility_hidden_selected_regions = H cambiar la visibilidad de las regiones ocultas o seleccionadas
+label.rename_tab_eXpand_reGroup= Haga clic en el botón derecho para renombrar la pestaña<br>Presione X para expandir las tablas y G para reagrupar.
+label.right_align_sequence_id = Alinear a la derecha el ID de la secuencia
+label.sequence_id_tooltip = Ayuda del ID de la secuencia
+label.no_services = <Sin Servicios>
+label.select_copy_raw_html = Seleccione esta opción si desea copiar el html en bruto
+label.share_data_vamsas_applications = Compartir datos con otras aplicaciones vamsas
+label.connect_to = Conectar a
+label.join_existing_vamsas_session = Unirse a una sesión vamsas existente
+label.from_url = desde una URL
+label.any_trees_calculated_or_loaded_alignment_automatically_sort = Cuando está habilitado, cualquier árbol calculado o cargado en el alineamiento lo ordenará
+label.sort_with_new_tree = Ordenar con el nuevo árbol
+label.from_textbox = desde un área de texto
+label.window = Ventana
+label.preferences = Preferencias
+label.tools = Herramientas
+label.fetch_sequences = Recuperar secuencia(s)
+label.stop_vamsas_session = Parar sesión vamsas
+label.collect_garbage = Recolector de basura
+label.show_memory_usage = Mostrar uso de memoria
+label.show_java_console = Mostrar consola de Java
+label.show_jalview_news = Mostrar las noticias de Jalview
+label.take_snapshot = Tomar captura
+label.monospaced_fonts_faster_to_render = Las fuentes monoespaciadas son más rápidas de pintar
+label.anti_alias_fonts = Fuentes anti-alias (más lentas de pintar)
+label.monospaced_font= Monoespaciadas
+label.quality = Calidad
+label.maximize_window = Maximizar ventana
+label.conservation = Conservación
+label.consensus = Consenso
+label.histogram = Histograma
+label.logo = Logo
+label.non_positional_features = Características no posicionales
+label.database_references = Referencias a base de datos
+label.share_selection_across_views = Compartir la selección en todas las vistas
+label.scroll_highlighted_regions = Desplazarse hasta las regiones resaltadas
+label.gap_symbol = Símbolo del hueco
+label.alignment_colour = Color del alineamiento
+label.address = Dirección
+label.port = Puerto
+label.default_browser_unix = Navegador por defecto (Unix)
+label.send_usage_statistics = Enviar estadísticas de uso
+label.check_for_questionnaires = Comprobar los cuestionarios
+label.check_for_latest_version = Comprobar la última versión
+label.url_linkfrom_sequence_id = URL del enlace del ID de la secuencia
+label.use_proxy_server = Utilizar un servidor proxy
+label.eps_rendering_style = Estilo de visualización EPS
+label.append_start_end = Añadir /inicio-fin (/15-380)
+label.full_sequence_id = ID de la secuencia completo
+label.smooth_font = Fuente alargada
+label.autocalculate_consensus = Autocalcular consenso
+label.pad_gaps = Rellenar huecos
+label.pad_gaps_when_editing = Rellenar huecos al editar
+label.automatically_set_id_width = Establecer automáticamente al anchura del ID
+label.figure_id_column_width = Anchura de la columna del ID de la Figura
+label.use_modeller_output = Utilizar la salidad del Modeller
+label.wrap_alignment = Envolver alineamiento
+label.right_align_ids = Alinear IDs a la derecha
+label.sequence_name_italics = Nombre de la secuencia en cursiva
+label.open_overview = Abrir resumen
+label.default_colour_scheme_for_alignment = Esquema cromático por defecto para el alineamiento
+label.annotation_shading_default = Sombreado por defecto de la anotación
+label.default_minimum_colour_annotation_shading = Por mínimo por defecto para el sombreado de la anotación
+label.default_maximum_colour_annotation_shading = Por máximo por defecto para el sombreado de la anotación
+label.visual = Visual
+label.connections = Conexiones
+label.output = Salida
+label.editing = Edición
+label.das_settings = Configuración DAS
+label.web_services = Servicios web
+label.right_click_to_edit_currently_selected_parameter = Haga clic en el botón derecho para editar el parámetro seleccionado actualmente.
+label.let_jmol_manage_structure_colours = Permitir que Jmol gestione la estructuras cromáticas
+label.marks_leaves_tree_not_associated_with_sequence = Marcar las hojas del árbol que no están asociadas a una secuencia
+label.index_web_services_menu_by_host_site = Indizar los servicios web en el menú por el host que los aloja
+label.option_want_informed_web_service_URL_cannot_be_accessed_jalview_when_starts_up = Marque esta opción si desea ser informado<br>cuando no se pueda acceder a la URL de un servicio web<br>al arrancar Jalview.
+label.new_service_url = Nueva URL del servicio
+label.edit_service_url = Editar la URL del servicio
+label.delete_service_url = Borrar la URL del servicio
+label.details = Detalles
+label.options = Opciones
+label.parameters = Paramétros
+label.available_das_sources = Fuentes DAS disponibles
+label.full_details = Detalles completos
+label.authority = Autoridad
+label.type = Tipo
+label.proxy_server = Servidor proxy
+label.file_output = Fichero de salida
+label.select_input_type = Seleccionar el tipo de entrada
+label.set_options_for_type = Establecer opciones para el tipo
+label.data_input_parameters = Datos de los parámetros de entrada
+label.data_returned_by_service = Datos devueltos por el servicio
+label.rsbs_encoded_service = Servicio RSBS codificado
+label.parsing_errors = Errores de parseo
+label.simple_bioinformatics_rest_services = Simple Bioinformatics Rest Services
+label.web_service_discovery_urls = URL de descubrimiento de servicios web
+label.input_parameter_name = Nombre del parámetro de entrada
+label.short_descriptive_name_for_service = Nombre corto descriptivo del servicio
+label.function_service_performs = Tipo de función que realiza el servicio (p.e. alineamiento, análisis, búsqueda, etc).
+label.brief_description_service = Descripción breve del servicio
+label.url_post_data_service = URL a la que enviar los datos del servicio. Incluya cualquier parámetro especial que se necesite aquí
+label.optional_suffix = Sufijo opcional añadido a la URL al recuperar los resultados del servicio
+label.preferred_gap_character = ¿Qué caracter para el hueco prefiere el servicio?
+label.gap_character = Carácter para hueco
+label.move_return_type_up_order= Mover el tipo de returno hacia arriba en el orden
+label.move_return_type_down_order= Mover el tipo de returno hacia abajo en el orden
+label.update_user_parameter_set = Actualizar el conjunto de parámetros de usuario existente
+label.delete_user_parameter_set = Borrar el conjunto de parámetros de usuario existente
+label.create_user_parameter_set = Crear un nuevo conjunto de parámetro con la configuración actual.
+label.revert_changes_user_parameter_set = Deshacer todos los cambios en el conjunto de parámetros actual
+label.start_job_current_settings = Arrancar trabajo con la configuración actual
+label.cancel_job_close_dialog = Cerrar este diálogo y cancelar el trabajo
+label.input_output = Entrada/Salida
+label.cut_paste = Cortar y pegar
+label.adjusting_parameters_for_calculation = Ajustar los parámetros para el cálculo existente
+label.2d_rna_structure_line = 2D RNA {0}
+label.2d_rna_sequence_name = 2D RNA - {0}
+label.edit_name_and_description_current_group = Editar el nombre y la descripción del grupo actual.
+label.view_structure_for = Visualizar la estructura para {0}
+label.view_all_structures = Visualizar todas las {0} estructuras.
+label.view_all_representative_structures = Visualizar todas las {0} estructuras representativas.
+label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment = Abrir una nueva vista de Jmol con todas las estructuras representativas\nasociadas con la selecci\u00F3n actual\nsuperpuesta con el alineamiento actual.
+label.associate_structure_with_sequence = Asociar estructura con la secuencia
+label.from_file = desde fichero
+label.enter_pdb_id = Introducir PDB Id
+label.discover_pdb_ids = Buscar PDB ids
+label.text_colour = Color del texto
+label.structure = Estructura
+label.view_structure = Visualizar estructura
+label.clustalx_colours = Colores de Clustalx
+label.above_identity_percentage = Sobre % identidad
+label.create_sequence_details_report_annotation_for = Anotación para {0}
+label.sequece_details_for = Detalles de la secuencia para {0}
+label.sequence_name = Nombre de la secuencia
+label.sequence_description = Descripción de la secuencia
+label.edit_sequence_name_description = Editar el nombre/descripción de la secuencia
+label.spaces_converted_to_backslashes = Los espacios se han convertido en _
+label.no_spaces_allowed_sequence_name = No se permiten espacios en el nombre de la secuencia
+label.select_outline_colour = Seleccionar el color del límite
+label.web_browser_not_found_unix = Unixers\: No es posible encontrar el navegador web por defecto.\nA\u00F1ada la ruta completa de su navegador en la pesta\u00F1a de Preferencias.
+label.web_browser_not_found = No se encuentra el navegador web
+label.select_pdb_file_for = Seleccione un fichero PDB para {0}
+label.html = HTML
+label.wrap = Envolver
+label.show_database_refs = Mostrar las referencias en base de datos
+label.show_non_positional_features = Mostrar las características no posicionales
+label.save_png_image = Guardar como imagen PNG
+label.load_tree_for_sequence_set = Cargar un árbol para este conjunto de secuencias
+label.export_image = Exportar imagen
+label.vamsas_store = Almacén VAMSAS
+label.translate_cDNA = Traducir cDNA
+label.extract_scores = Extraer puntuaciones
+label.get_cross_refs = Obtener referencias cruzadas
+label.sort_alignment_new_tree = Alinear el alineamiento con el nuevo árbol
+label.add_sequences = Añadir secuencias
+label.new_window = Nueva ventana
+label.refresh_available_sources = Refrescar las fuentes disponibles
+label.use_registry = Utilizar el registro
+label.add_local_source = Añadir fuente local
+label.set_as_default = Establecer por defecto
+label.show_labels = Mostrar etiquetas
+label.background_colour = Color de fondo
+label.associate_nodes_with = Asociar nodos con
+label.jalview_pca_calculation = Cálculo del PCA por Jalview
+label.link_name = Nombre del enalce
+label.pdb_file = Fichero PDB
+label.colour_with_jmol = Colorear con Jmol
+label.align_structures = Alinear estructuras
+label.jmol = Jmol
+label.sort_alignment_by_tree = Ordenar alineamiento por árbol
+label.mark_unlinked_leaves = Marcar las hojas como no enlazadas
+label.associate_leaves_with = Asociar hojas con
+label.save_colour_scheme_with_unique_name_added_to_colour_menu = Guarde el esquema cromáticos con un nombre único y se añadirá al menú de colores
+label.case_sensitive = Sensible a mayúsculas
+label.lower_case_colour = Color para las minúsculas
+label.index_by_host = Indizar por host
+label.index_by_type = Indizar por tipo
+label.enable_jabaws_services = Habilitar servicios JABAWS
+label.display_warnings = Mostrar advertencias
+label.move_url_up = Mover la URL hacia arriba
+label.move_url_down = Mover la URL hacia abajo
+label.add_sbrs_definition = Añadir una definición SBRS
+label.edit_sbrs_definition = Editar una definición SBRS
+label.delete_sbrs_definition = Borrar una definición SBRS
+label.your_sequences_have_been_verified = Sus secuencias has sido verificadas en una base de datos de secuencias conocidas. Algunos de sus ID se han alterado y\n, probablemente, el residuo de inicio/fin se haya actualizado.\nGuarde su alineamiento para mantener el ID actualizado.\n\n
+label.sequence_names_updated = Nombres de secuencia actualizados
+label.dbref_search_completed = Búsqueda de DBRef terminada
+label.show_all_chains = Mostrar todas las cadenas
+label.fetch_all_param = Recuperar todas {0}
+label.paste_new_window = Pegar en una nueva ventana
+label.settings_for_param = Configuración para {0}
+label.view_params = Visualizar {0}
+label.select_all_views = Seleccionar todas las vistas
+label.align_sequences_to_existing_alignment = Alinear las secuencias con el alineamiento existente
+label.realign_with_params = Realinear con {0}
+label.calcname_with_default_settings = {0} por defecto
+label.action_with_default_settings = {0} con la configuración por defecto
+label.edit_settings_and_run = Editar la configuración y ejecutar...
+label.view_and_change_parameters_before_alignment = Ver y cambiar los parámetros antes del alineamiento
+label.run_with_preset_params = Ejecutar {0} con preconfiguración
+label.view_and_change_parameters_before_running_calculation = Ver y cambiar los parámetros antes de lanzar el cálculo
+label.view_documentation = Ver documentación
+label.select_return_type = Seleccionar el tipo de retorno
+label.translation_of_params = Traducción de {0}
+label.features_for_params = Características de - {0}
+label.annotations_for_params = Anotaciones de - {0}
+label.generating_features_for_params = Generando características de - {0}
+label.generating_annotations_for_params = Generando anotaciones de - {0}
+label.varna_params = VARNA - {0}
+label.sequence_feature_settings = Configuración de las características de la secuencia
+label.pairwise_aligned_sequences = Secuencias alineadas a pares
+label.original_data_for_params = Datos originales de {0}
+label.points_for_params = Puntos de {0}
+label.transformed_points_for_params = Puntos transformados de {0}
+label.graduated_color_for_params = Color graduado para la característica de {0}
+label.select_backgroud_colour = Seleccionar color de fondo
+label.invalid_font = Fuente no válida
+label.separate_multiple_accession_ids = Separar los accession id con un punto y coma ";"
+label.replace_commas_semicolons = Cambiar comas por puntos y comas
+label.parsing_failed_syntax_errors_shown_below_param = Parseo erróneo. A continuación, se muestras los errores de sintaxis {0}
+label.parsing_failed_unrecoverable_exception_thrown_param = \nParseo err\u00F3neo. Se ha lanzado una excepci\u00F3n fatal\:\n {0}
+label.example_query_param = Consulta de ejemplo: {0}
+label.enter_value_increase_conservation_visibility = Introduzca un valor para incrementar la visibilidad de la conservación
+label.enter_percentage_identity_above_which_colour_residues = Introduza un % de identidad por encima del cual se colorearán los residuos
+label.wswublast_client_credits = Para mostrar las caracter\u00EDsticas de una secuencia, debe indicarse un id de Uniprot cuya secuencia se corresponda al 100 % con la introducida.\nPara mostrar estas caracter\u00EDsticas, prueba a cambar los nombre de sus secuencia con los ID que se sugieren a continuaci\u00F3n.\n\nRunning WSWUBlast at EBI.\nPlease quote Pillai S., Silventoinen V., Kallio K., Senger M., Sobhany S., Tate J., Velankar S., Golovin A., Henrick K., Rice P., Stoehr P., Lopez R.\nSOAP-based services provided by the European Bioinformatics Institute.\nNucleic Acids Res. 33(1)\:W25-W28 (2005));
+label.blasting_for_unidentified_sequence = Ejecutar BLAST para la secuencias sin identificar
+label.select_columns_containing = Seleccione las columnas que contengan
+label.select_columns_not_containing = Seleccione las columnas que no contengan
+option.trim_retrieved_seqs = Ajustar las secuencias recuperadas
+label.trim_retrieved_sequences = Cuando la secuencia de referencia es más larga que la secuencia con la que está trabajando, sólo se mantienen las subsecuencias relevantes.
+label.use_sequence_id_1 = Utilice $SEQUENCE_ID$ o $SEQUENCE_ID=/<regex>/=$
+label.use_sequence_id_2 = \nto para embeber el id de la secuencia en una URL
+label.ws_parameters_for = Parámetros para {0}
+label.switch_server = Cambiar servidor
+label.open_jabaws_web_page = Abra el página principal del servidor JABAWS en un navegador web
+label.choose_jabaws_server = Escoja un servidor para ejecutar este servicio
+label.services_at = Servicios en {0}
+label.rest_client_submit = {0} utilizando {1}
+label.fetch_retrieve_from =Recuperar de {0}
+label.fetch_retrieve_from_all_sources = Recuperar de todas las fuentes {0} en {1}<br>La primera es :{2}
+label.feature_settings_click_drag = Haga clic o arrastre los tipos de las características hacia arriba o hacia abajo para cambiar el orden de visualización.<br/>Haga doble clic para seleccionar las columnas que contienen las características del alineamiento/selección actual.<br/>Presionando Alt seleccionará las columnas exteriores a las características en lugar de las interiores<br/>Presione Shift para modificar la selección actual (en lugar de borrarla)<br/>Presione CTRL o Command/Meta para cambiar las columans externas o internas a las características<br/>
+label.opt_and_params_further_details = ver los detalles adicionales haciendo clic en el botón derecho
+label.opt_and_params_show_brief_desc_image_link = Haga clic para ver una descripción breve<br><img src="{0}"/>Haga clic en el botón derecho para obtener información adicional.
+label.opt_and_params_show_brief_desc = Haga clic para ver una descripción breve<br>
+label.adjusts_width_generated_eps_png = Ajusta la anchura del fichero EPS o PNG generado para asegurar incluso que el ID de la secuencia más larga o las etiquetas de anotación se muestran
+label.manually_specify_width_left_column = Especificar manualmente la anchura de la columna izquierda en las etiquetas de los ID de la secuencia y las anotaciones se mostrar en las figuras del alineamiento exportado.Esta configuraicón se ignorará si está marcada la opción 'Establecer automáticamente al anchura del ID'
+label.job_created_when_checked = Cuando está habilitado, se crea un trabajo para cada secuencia de la selección actual
+label.when_checked_job_visible_region_and_results = Cuando está habilitado, se crea un único trabajo para la región visible y los resultados de mapean en su ubicación dentro del alineamiento. En caso contrario, se creará un trabajo para cada región visible y contigua en el alineamiento o selección actual (p.e. un alineamiento múlitple).</html>
+label.flat_file_representation = La representación del fichero plano de este servicio utilizando el formalismo Really Simple Bioinformatics Service</html>
+label.result_of_parsing_rsbs = Resultados de parsear la representación RSBS</html>
+label.user_preset = Preselección de usuario
+label.service_preset = Preselección del servicio
+label.run_with_preset = Ejecutar {0} con preselección
+label.view_service_doc_url = Visualizar <a href="{0}">{1}</a></html>
+label.submit_sequence = Enviar {0} {1} {2} {3} a<br/>{4}</html>
+action.by_title_param = por {0}
+label.alignment = Alineamiento
+label.secondary_structure_prediction = Predicción de la estructura secundaria
+label.sequence_database_search = Búsqueda en base de datos de secuencias
+label.analysis = Análisis
+label.protein_disorder = Desorden en la proteína
+label.source_from_db_source = Fuentes de {0}
+label.from_msname = de {0}
+label.superpose_with = Superponer con...
+action.do = Hacer
+label.scale_label_to_column = Ajustar la etiqueta a la columna
+label.add_new_row = Añadir nuevo fila
+label.edit_label_description = Editar etiqueta/descripción
+label.hide_row = Ocultar esta fila
+label.delete_row = Borrar esta fila
+label.show_all_hidden_rows = Mostrar todas las filas ocultas
+label.export_annotation = Exportar anotación
+label.copy_consensus_sequence = Copiar secuencia de consenso
+label.helix = Hélice
+label.sheet = Hoja
+label.rna_helix = Hélice de ARN
+label.remove_annotation = Borrar anotación
+label.colour_by = Colorear por...
+label.muscle_multiple_protein_sequence_alignment = Alineamiento múltiple de secuencias de proteínas con Muscle
+label.mafft_multiple_sequence_alignment = Alineamiento múltiple de secuencias con MAFFT
+label.clustalw_multiple_sequence_alignment = Alineamiento múltiple de secuencias con ClustalW
+label.jnet_secondary_structure_prediction = Predicción de la estructura secundaria con JNet
+label.multiharmony = Multi-Harmony
+label.unable_start_web_service_analysis = No es posible iniciar el servicio web de análisis
+label.job_couldnt_be_started_check_input = El trabajo no puede arrancarse. Por favor, compruebe los parámetros de entrada y los mensajes de advertencia de la consola de Jalview.
+label.prompt_each_time = Preguntar siempre
+label.use_source = Fuente
+label.couldnt_save_project = No es posible guardar el proyecto
+label.error_whilst_saving_current_state_to = Error mientras se guardaba el estado a {0}
+label.error_whilst_loading_project_from = Error cargando el proyecto desde {0}
+label.couldnt_load_project = No es posible cargar el proyecto
+label.pca_sequences_not_aligned = Las secuencias deben estar alineadas antes de calcular el PCA.\nPruebe a utilizar la funci\u00F3n de rellenar huecos en el men\u00FA Editar,\no cualquiera de los servicios web de alineamiento m\u00FAltiple.
+label.invalid_name_preset_exists = Nombre no válido - esta preconfiguración ya existe.
+label.invalid_name = Nombre no válido
+label.set_proxy_settings = Por favor, configure su proxy en la pestaña 'Conexiones' de la ventana de Preferencia
+label.proxy_authorization_failed = Autorización del proxy fallida
+label.internal_jalview_error = Error interno de Jalview
+label.secondary_structure_prediction_service_couldnt_be_located = No se ha podido encontrar el Servicio de Predicciónd de la Estructura Secudaria {0} en {1}.
+label.service_called_is_not_msa_service = El Servicio llamado \n{0}\nno es un \nServicio de Alineamiento M\u00FAltiple de Secuencias\!
+label.msa_service_is_unknown = El Servicio de Alineamiento Múltiple llamado {0} es desconocido
+label.service_called_is_not_seq_search_service = El Servicio llamando \n{0}\nno es un \nServicio de B\u00FAsqueda de Secuencias\!
+label.seq_search_service_is_unknown = El Servicio de Búsqueda de Sencuencias llamado {0} es desconocido
+label.feature_type = Tipo de característisca
+label.display = Representación
+label.service_url = URL del servicio
+label.copied_sequences = Secuencias copiadas
+label.cut_sequences = Cortar secuencias
+label.conservation_colour_increment = Incremento de Conservación del Color ({0})
+label.percentage_identity_thereshold = Umbral del Porcentaje de Identidad ({0})
+label.error_unsupported_owwner_user_colour_scheme = Propietario no soportado para el diálogo del Esquema Cromático del Usuario
+label.save_alignment_to_file = Guardar Alineamiento en fichero
+label.save_features_to_file = Guardar Características en un fichero
+label.save_annotation_to_file = Guardar Anotación en un fichero
+label.no_features_on_alignment = No se han encontrado características en el alineamiento
+label.save_pdb_file = Guardar fichero PDB
+label.save_text_to_file = Guardar Texto en un fichero
+label.save_state = Guardar estado
+label.restore_state = Restaurar estado
+label.saving_jalview_project = Guardando el proyecto de Jalview {0}
+label.loading_jalview_project = Cargando el proyecto de Jalview {0}
+label.save_vamsas_document_archive = Guardar el archivo de documento Vamsas
+label.saving_vamsas_doc = Guardando el documento VAMSAS en {0}
+label.load_feature_colours = Cargar colores de características
+label.save_feature_colours = Guardar esquema cromático de características
+label.dataset_for = {0} conjunto de datos para {1}
+label.select_startup_file = Seleccionar fichero de arranque
+label.select_default_browser = Seleccionar navegador web por defecto
+label.save_tree_as_newick = Guardar árbol como fichero newick
+label.create_eps_from_tree = Crear un fichero EPS a partir de un árbol
+label.create_png_from_tree = Crear una imagen PNG a partir de un árbol
+label.save_colour_scheme = Guardar esquema cromático
+label.edit_params_for = Editar los parámetros de {0}
+label.choose_filename_for_param_file = Escoja un nombre de fichero para este fichero de parámetros
+label.save_as_html = Guardar como HTML
+label.recently_opened = Abiertos recientemente
+label.blasting_for_unidentified_sequence_jobs_running = Ejecutando BLAST de las secuencias no indentificadas - {0} trabajos en marcha.
+label.tree_from = Árbol de {0}
+label.webservice_job_title = {0} usando {1}
+label.select_visible_region_of = seleccionada {0} región de {1}
+label.visible = Visible
+label.select_unselect_visible_regions_from = seleccionada y deseleccionadas {0} regiones de {1}
+label.visible_region_of = región visible de
+label.webservice_job_title_on = {0} usando {1} de {2}
+label.updating_vamsas_session = Actualizando sesión VAMSAS
+label.loading_file = Cargando fichero: {0}
+label.edit_params = Editar {0}
+error.not_implemented = No implementado
+error.no_such_method_as_clone1_for = No existe ese método como un clone1 de {0}
+error.null_from_clone1 = Nulo de clone1!
+error.implementation_error_sortbyfeature = Error de implementación - sortByFeature debe ser uno de FEATURE_SCORE, FEATURE_LABEL o FEATURE_DENSITY.
+error.not_yet_implemented = No se ha implementado todavía
+error.unknown_type_dna_or_pep = Tipo desconocido {0} - dna o pep son los únicos valores permitidos
+error.implementation_error_dont_know_thereshold_annotationcolourgradient = Error de implementación: no se conoce el valor umbral para el AnnotationColourGradient actual.
+error.implementation_error_embeddedpopup_not_null = Error de implementación - embeddedPopup debe ser no nulo.
+error.invalid_colour_for_mycheckbox = Color no válido para MyCheckBox
+error.implementation_error_unrecognised_render_object_for_features_type = Error de implementación: no se reconoce el objeto de representación {0} para las características de tipo {1}
+error.implementation_error_unsupported_feature_colour_object = Error de implementación: objeto de color de características no soportado.
+error.invalid_separator_parameter = Separador de parámetros no válido - debe tener longitud mayor que cero
+error.alignment_cigararray_not_implemented = Alignment(CigarArray) no se ha implementado todavía
+error.weak_sequencei_equivalence_not_yet_implemented = Equivalencia débil sequenceI no se ha implementado todavía.
+error.implementation_error_can_only_make_alignmnet_from_cigararray = Error de implementación - sólo se puede construir un vista de alineamiento a partir de una CigarArray de secuencias.
+error.empty_view_cannot_be_updated = una vista vacía no se puede actualizar.
+error.mismatch_between_number_of_sequences_in_block = No hay coincidencia entre el número de secuencias en el bloque {0} ({1}) y la vista original ({2})
+error.padding_not_yet_implemented = El relleno no se ha implementado todavía
+error.mismatch_between_visible_blocks_to_update_and_number_of_contigs_in_view = No hay coincidencia entre los bloques visibles para actualizar y el número de contigs en la vista (contigs=0,blocks={0})
+error.unknown_seq_cigar_operation = Operación SeqCigar {0} desconocida
+error.implementation_bug_parse_cigar_string = Bug de implementación en parseCigarString
+error.implementation_error_invalid_operation_string = Error de implementación. Cadena de operación no válida.
+error.invalid_range_string = Rango de la cadena no válido (debe ser cero o un número positivo)
+error.implementation_error_delete_range_out_of_bounds = Error de implementación: deleteRange fuera de rango: el comienzo debe ser cero o positivo y menor que el final.
+error.implementation_error = Error de implementación
+error.implementation_error_unknown_operation = ¡Error de implementación! Operación desconocida {0}
+error.implementation_error_unexpected_null_from_get_sequence_and_deletions = Error de implementación - valor nulo no esperado en getSequenceAndDeletions
+error.implementation_error_set_seq_null = Error de implementación - _setSeq(null,...)
+error.implementation_error_s = Error de implementación: _s= {0}
+error.implementation_error_seqcigar_possible = SeqCigar: posible error de implementación: la secuencia es más larga de el conjunto de datos de la secuencia
+error.implmentation_bug_seq_null = Bug de implementación. Seq nula
+error.implementation_bug_cigar_operation_list_range_list = Bug de implementación: Cigar Operation list!= range list
+error.not_yet_implemented_cigar_object_from_cigar_string = No implementado todavía: construcción de un objeto Cigar desde una cadena y una secuencia con huecos.
+error.implementation_bug_cigar_operation = Bug de implementación. La operación Cigar {0} {1} no es ni {2}, ni {3} ni {4}.
+error.implementation_error_for_new_cigar = Error de implementación en new Cigar(SequenceI)
+error.implementation_error_cigar_seq_no_operations = Error de implementación: la {0}a secuencia Cigar no tiene operaciones.
+error.implementation_error_jmol_getting_data = Error de implementación - Jmol parece estar todavía intentando recuperar sus datos - informe de ello en http://issues.jalview.org/browse/JAL-1016
+error.implementation_error_no_pdbentry_from_index = Error de implementación - no existe la correspondiente entrada pdb (para el índice {0}) para añadir el mapeo de secuencias a
+error.jmol_version_not_compatible_with_jalview_version = La versión {0} de Jmol no es compatible con esta versión de Jalview. Informe de este problema en http://issues.jalview.org
+error.not_implemented_remove = Borrar: no implementado
+error.not_implemented_clone = Clonar: no implementado
+error.implementation_error_chimera_getting_data = Error de implementación - Chimera parece estar todavía intentando recuperar sus datos - informe de ello en http://issues.jalview.org/browse/JAL-1016
+error.call_setprogressbar_before_registering_handler = llamada a setProgressBar antes de registrar el manejador de la barra de estado
+label.cancelled_params = {0} cancelado
+error.implementation_error_cannot_show_view_alignment_frame = Error de implementación: no es posible mostrar una vista de otro alineamiento en un AlignFrame.
+error.implementation_error_dont_know_about_thereshold_setting = Error de implementación: no se conoce la configuración del umbral para el AnnotationColourGradient actual.
+error.eps_generation_not_implemented = La generación de EPS no se ha implementado todavía
+error.png_generation_not_implemented = La generación de PNG no se ha implementado todavía
+error.try_join_vamsas_session_another = Tratando de establecer una sesión VAMSAS cuando ya había otra conectada
+error.invalid_vamsas_session_id = Identificador de sesión VAMSAS no válido
+error.implementation_error_cannot_create_groovyshell = Error de implementación:no se puede crear groovyShell sin Groovy en el classpath
+label.groovy_support_failed = El soporte Groovy de Jalview ha fallado
+label.couldnt_create_groovy_shell = No es posible crear el shell de Groovy. Compruebe el fichero de log para conocer los detalles.
+error.unsupported_version_calcIdparam = Versión no soportada de {0}
+error.implementation_error_cant_reorder_tree = Error de implementación: no es posible reordenar este árbol. No DefaultMutableTreeNode.
+error.invalid_value_for_option = Valor no válido de {0} para la opción {1}
+error.implementation_error_cannot_import_vamsas_doc = Error de implementación - todavía no es posible importar el documento VAMSAS existente en una sesión existente.
+label.vamsas_doc_couldnt_be_opened_as_new_session = El documento VAMSAS no ha podido abrirse como una nueva sesión. Por favor, escoja otra.
+error.implementation_error_vamsas_operation_not_init = ¡Error de implementación! Operaciones VAMSAS cuando el cliente no estaba inicializado ni conectado
+error.jalview_no_connected_vamsas_session = Jalview está conectado a una sesión VAMSAS
+error.implementation_error_cannot_recover_vamsas_object_mappings = Error de implementación: no es posible recuperar los mapeos del objeto VAMSAS - no se ha hecho ningún backup
+error.setstatus_called_non_existent_job_pane = se lllamado a setStatus para el panel de trabajo {0} no existente
+error.implementation_error_cannot_find_marshaller_for_param_set =Error de implementación: no puede encontrar un marshaller para el conjunto de parámetros
+error.implementation_error_old_jalview_object_not_bound =Error de implementación: ¡el objeto Jalview antiguo no está enlazado! ({0})
+error.implementation_error_vamsas_doc_class_should_bind_to_type = Error de implementación: la clase de documento VAMSAS {0} debe enlazar a {1} (pero se ha encontrado que lo está a {2})
+error.implementation_error_jalview_class_should_bind_to_type = Error de implementación: la clase Jalview {0} debe enlazar a {1} (pero se ha encontrado que lo está a {2})
+error.invalid_vamsas_rangetype_cannot_resolve_lists = RangeType VAMSAS no válido - ¡no es posible resolver ambas listas de Pos y Seg con los valores elegidos!
+error.implementation_error_maplist_is_null = Error de implementación. MapList es nulo en initMapType.
+error.implementation_error_cannot_have_null_alignment = Error de implementación: no es posible tener una clave nula en el alineamiento
+error.implementation_error_null_fileparse = Error de implementación. FileParse nulo en el construictor de copia
+error.implementation_error_cannot_map_alignment_sequences = Error de implementación: no es posible maper un alineamiento de secuencias desde distintos conjuntos de datos en un único alineamiento en el documento VAMSAS.
+error.implementation_error_cannot_duplicate_colour_scheme = Error grave de implementación: no es posible duplicar el esquema cromático {0}
+error.implementation_error_structure_selection_manager_null = Error de implementación. El contexto structure selection manager's es nulo
+exception.ssm_context_is_null = El contexto SSM es nulo
+error.idstring_seqstrings_only_one_per_sequence = idstrings y seqstrings contienen una cadena por cada secuencia
+error.cannot_have_mixed_length_replacement_vectors = No es posible tener vectores de reemplazo de distinta longitud. El vector de reemplazo para {0} es de {1} cadenas de largo, pero se ha considerado ya como un vector de longitud {2}.
+error.cannot_have_zero_length_vector_replacement_strings = No es posible tener un vector de cadenas de reemplazo de longitud cero - debe ser uno o n.
+error.implementation_error_multiple_single_sequence_prediction_jobs_not_supported = ¡Error de implementación! Todavía no se soportan varios trabajos de predicción asociados a una única secuencia.
+error.implementation_error_invalid_msa_index_for_job = ¡Error de implementación! Valor msaIndex no válido para JPredJob en el objeto de entrada MSA padre!
+error.implementation_error_startjob_called = Error de implementación - StartJob(JpredJob) invocado en {0}
+error.multiple_jnet_subjob_merge_not_implemented = Todavía no se han implementado varios subtrabajos JNet conjuntos.
+label.job_never_ran = El trabajo nunca se ejecutó - entrada devuelta al usuario.
+error.implementation_error_minlen_must_be_greater_zero = Error de implementación: minlen debe ser cero o más
+error.implementation_error_msawbjob_called = Error de implementación - StartJob(MsaWSJob) invocado en un WSJobInstance {0}
+error.implementation_error_cannot_attach_ws_menu_entry = Error de implementación: ¡no es posible adjunto una WS Menu Entry sin una referencia a un manejador del servicio!
+error.parameter_migration_not_implemented_yet = La migración de parámetros no se ha implementado todavía
+error.implementation_error_cannot_set_jaba_option = Error de implementación: no es posible establecer el valor de Jaba Option a un valor fuera de su rango permitido
+error.implementation_error_valuetype_doesnt_support_jabaws_type = Error de implementación: jalview.ws.params.ValueConstrainI.ValueType no soporta el tipo JABAWS: {0}
+error.cannot_create_jabaws_param_set = No es posible crear un JabaWSParamSet con parámetros no JabaWS
+error.cannot_set_arguments_to_jabaws_param_set = No es posible establecer argumentos en JabaWSParamSet que no sean argumentos JabaWS
+error.implementation_error_runner_config_not_available = Error de implementación: Runner Config no está disponible para un servicio JABAWS de tipo {0} ({1})
+error.implementation_error_cannot_handle_jaba_param = Error de implementación: no es posible manejar el objeto del parámetro Jaba {0}
+error.implementation_error_attempt_to_delete_service_preset = Error de implementación: intento de borrar un servicio preestablecido
+error.implementation_error_cannot_locate_oldname_presetname = Error de implementación: no es posible localizar ni el nombre antiguo ({0}) ni el presetName ({1} en el almacén de datos.
+error.implementation_error_jabaws_param_set_only_handled_by = Error de implementación: JabaWsParamSets sólo puede ser manejado por JabaParamStore
+error.cannot_set_source_file_for = No es posible establecer el fichero fuente para {0}
+error.mismatch_service_instance_preset = Posible desajuste entre la instancia del servicio y la prestablecida
+error.cannot_set_params_for_ws_preset = No es posible establecer los parámetros para el servicio web JABA presestablecido
+error.implementation_error_can_only_instantiate_jaba_param_sets = Error de implementación: sólo se puede instanciar conjuntos de parámetros Jaba
+error.no_aacon_service_found = No se ha encontrado ningún servicio AACon
+error.implementation_error_couldnt_copy_value_constraint = Error de implementación: ¡no se puede copiar ValueConstrain!
+error.couldnt_encode_as_utf8 = No se ha podido codificar {0} como UTF-8.
+error.tree_inputtype_not_yet_implemented = No se ha implementado todavía el árbol como InputType
+error.implementation_error_need_to_have_httpresponse = Error de implementación: se necesita tener un HttpResponse que procesar
+error.dbrefsource_implementation_exception = Excepción de implementación DBRefSource
+error.implementation_error_dbinstance_must_implement_interface = Error de Implementación- getDbInstances debe recibir una clase que implemente jalview.ws.seqfetcher.DbSourceProxy (recibió {0})
+error.implementation_error_must_init_dbsources =Error de implementación. Debe inicializar dbSources
+label.view_controller_toggled_marked = {0} {1} columnas {2} conteniendo características del tipo {3} en {4} secuencia(s)
+label.toggled = Invertida
+label.marked = Marcada
+label.not = no
+label.no_feature_of_type_found = No se han encontrado características del tipo {0}.
+label.submission_params = Envío {0}
+label.empty_alignment_job = Trabajo de alineamiento vacío
+label.add_new_sbrs_service = Añadir un nuevo SBRS
+label.edit_sbrs_entry = Editar entrada SBRS
+label.pca_recalculating = Recalculando PCA
+label.pca_calculating = Calculando PCA
+label.select_foreground_colour = Escoger color del primer plano
+label.select_colour_for_text = Seleccione el color del texto
+label.adjunst_foreground_text_colour_thereshold = Ajustar el umbral del color del texto en primer plano
+label.select_subtree_colour = Seleccioanr el color del sub-árbol
+label.create_new_sequence_features = Crear nueva(s) característica(s) de secuencia
+label.amend_delete_features = Arrelgar/Borrar características de {0}
+exception.out_of_bounds_for_file = Fuera de rango para el fichero: i={0}, Buffer final: i0={1} iend={2}
+exception.null_string_given_to_regex_search = Cadena nula enviada a Regex.search
+exception.null_string_like_given_to_regex_search = StringLike nula enviada a Regex.search
+exception.null_string_given_to_regex_reverse_search = Cadena nula enviada a Regex.reverseSearch
+exception.null_string_like_given_to_regex_reverse_search = StringLike nula enviada a Regex.reverseSearch
+exception.null_string_like_given_to_regex_search_from = Cadena nula enviada a Regex.searchFrom
+exception.null_string_like_given_to_regex_search_region = Cadena nula enviada a Regex.searchRegion
+exception.replace_null_regex_pointer = Reemplazador tiene un puntero Regex nulo
+exception.bad_pattern_to_regex_perl_code = patrón erróneo en Regex.perlCode: {0}
+exception.no_stub_implementation_for_interface = No existe una implementación del stub para la interfaz: {0}
+exception.cannot_set_endpoint_address_unknown_port = No es posible estabelcer la dirección de punto final para el puerto desconocido {0}
+exception.querying_matching_opening_parenthesis_for_non_closing_parenthesis = Consultando la coincidencia de apertura de paréntesis para paréntesis sin cerrar (?)
+exception.mismatched_unseen_closing_char = Discordancia (no vista) en el carácter de cierre {0}
+exception.mismatched_closing_char = Carácter de cierre discordante {0}
+exception.mismatched_opening_char = Carácter de apertura discordante {0} en {1}
+exception.invalid_datasource_couldnt_obtain_reader = Fuente de datos no válida. No es posible obtener el Reader
+exception.index_value_not_in_range = {0}: el valor del índice {1} en se encuentra en el rango [0..{2}]
+exception.unterminated_cigar_string = Cadena cigar sin terminar
+exception.unexpected_operation_cigar_string_pos = Operación no esperada {0} en una cadena cigar (posición {1} en {2})
+exception.couldnt_parse_responde_from_annotated3d_server = No es posible parsear la respuesta procedente del servidor Annotate3d
+exception.application_test_npe = Prueba de aplicación: lanzando un NullPointerException que debe aparecer en la consola
+exception.overwriting_vamsas_id_binding = Sobreescribiendo la asociación al VAMSAS id
+exception.overwriting_jalview_id_binding = Sobreescribiendo la asociación al Jalview id
+error.implementation_error_unknown_file_format_string = Error de implementación: cadena de formato de fichero desconocido
+exception.failed_to_resolve_gzip_stream = Fallo al resolver el flujo GZIP
+exception.problem_opening_file_also_tried = Problema abriendo {0} (también se intentó {1}) : {2}
+exception.problem_opening_file = Problema abriendo {0} : {1}
+exception.failed_to_read_data_from_source = Error al leer datos de la fuente: {0}
+exception.no_init_source_stream = Flujo de fuente sin inicializar
+exception.invalid_source_stream = Flujo de fuente no válida: {0}
+error.implementation_error_reset_called_for_invalid_source = Error de implementación: se ha invocado un Reset en una fuente no válida.
+exception.number_of_residues_in_query_sequence_differ_from_prediction = El n\u00FAmero de residuos en la supuesta secuencia consultada {0} ({1}\n{2})\ndifiere del n\u00FAmero de sitios de predicci\u00F3n en la predicci\u00F3n ({3})
+label.mapped = mapeado
+exception.jpredconcide_entry_has_unexpected_number_of_columns = JPredConcise: La entrada ({0}) tiene un número inesperado de columnas
+exception.couldnt_parse_concise_annotation_for_prediction = No es posible parsear la anotaci\u00F3n concisa para el perfil de predicci\u00F3n.\n{0}
+exception.newfile = Fichero Newick\: {0}\n
+label.no_tree_read_in = No hay lectura de árbol en
+exception.rnaml_couldnt_access_datasource = No ha sido posible acceder la fuente de datos ({0})
+exception.ranml_couldnt_process_data = No ha sido posible procesar los datos como un fichero RNAML ({0})
+exception.ranml_invalid_file = Fichero RNAML no válido ({0})
+exception.ranml_problem_parsing_data = Problema parseando los datos como RNAML ({0})
+exception.pfam_no_sequences_found = No se han encontrado secuencias (entrada PFAM)
+exception.stockholm_invalid_format = Este fichero no es tiene un formato STOCKHOLM válido: la primera línea no contiene '# STOCKHOLM'
+exception.couldnt_parse_sequence_line = No es posible parse la línea de secuencia: {0}
+exception.error_parsing_line = Error parseando {0}
+exception.unknown_annotation_detected = Anotación desconocida detectada: {0} {1}
+exception.couldnt_store_sequence_mappings = No es posible almacenar los mapeos de secuencia para {0}
+exception.matrix_too_many_iteration = Demasiadas iteraciones en {0} (el máximo es {1})
+exception.browser_not_found = Excepción al buscar el navegador: {0}
+exception.browser_unable_to_locate = Imposible encontrar el navegador: {0}
+exception.invocation_target_exception_creating_aedesc = InvocationTargetException mientras se creaba AEDesc: {0}
+exception.illegal_access_building_apple_evt= IllegalAccessException mientras se construía AppleEvent: {0}
+exception.instantiation_creating_aedesc = InstantiationException mientras se creaba AEDesc: {0}
+exception.unable_to_launch_url = Imposible lanzar la URL: {0}
+exception.unable_to_create_internet_config = Imposible crear una instancia de configuración de Internet: {0}
+exception.invocation_target_calling_url = InvocationTargetException mientras se invocaba openURL: {0}
+exception.illegal_access_calling_url = IllegalAccessException mientras se invocaba openURL: {0}
+exception.interrupted_launching_browser = InterruptedException mientras se lanzaba el navegador: {0}
+exception.das_source_doesnt_support_sequence_command = La fuente {0} no soporta el comando sequence.
+exception.invalid_das_source = Fuente DAS no válida: {0}
+exception.ebiembl_retrieval_failed_on = La recuperación de datos EBI EMBL XML ha fallado en {0}:{1}
+label.no_embl_record_found = # No se ha recuperado ningún registro EMBL de {0}:{1}
+label.embl_successfully_parsed = # Se han parseado con éxito las consultas {0} en un alineamiento
+exception.no_pdb_records_for_chain = No se han encontrado registros {0} para la cadena {1}
+exception.unexpected_handling_rnaml_translation_for_pdb = Excepcion inesperada cuando se traducían a RNAML los datos PDB
+exception.couldnt_recover_sequence_properties_for_alignment = No es posible recuperar las propiedades de la secuencia para el alineamiento
+exception.unknown_format_for_file = Formato desconocido {0} para el fichero \: \n{1}
+label.remove_gaps = Eliminar huecos
+exception.couldnt_recover_sequence_props_for_jnet_query = No ha sido posible recuperar las propiedades de la secuencia para la secuencia JNet Query!
+exception.server_timeout_try_later = Tiempo de conexi\u00F3n ha expirado - int\u00E9ntelo de nuevo m\u00E1s tarde\n
+exception.web_service_returned_null_try_later= El servidor {0} ha devuelto un objeto nulo, por lo que probablemente no se haya podido contactar con él. Inténtelo de nuevo más tarde.
+exception.cannot_contact_service_endpoint_at = No es posible contactar por el punto de acceso al servicio en {0}
+error.implementation_error_cannot_find_service_url_in_given_set = Error de implementación: no es posible encontrar la URL del servicio en el conjunto de URL proporcionado
+error.implementation_error_cannot_find_service_url_in_given_set_param_store = Error de implementación: la URL del servicio en el conjunto de URL para este almacén de parámetros del servicio({0})
+exception.jobsubmission_invalid_params_set = Conjunto de parámetros no válido. Comprueba la implementación de Jalview
+exception.notvaliddata_group_contains_less_than_min_seqs = El grupo contiene menos de {0} secuencias.
+exception.outofmemory_loading_pdb_file = Sin menoria al cargar el fichero PDB
+exception.eps_coudnt_write_output_file = No es posible escribir el fichero de salida: {0}
+exception.eps_method_not_supported = Método actualmente no suportado por la versión {0} de EpsGraphics2D
+exception.eps_unable_to_get_inverse_matrix = Imposible obtener la inversa de la matrix: {0}
+warn.job_cannot_be_cancelled_close_window = Este trabajo no se puede cancelar.\nSimplemente, cierre la ventana.
+warn.service_not_supported = ¡Servicio no soportado!
+warn.input_is_too_big = ¡El tamaño de la entrada es demasiado grande!
+warn.invalid_job_param_set = ¡Conjunto de parámetros del trabajo no válido!
+info.job_couldnt_be_run_server_doesnt_support_program = No es posible ejecutar el trabajo porque el servidor no soporta este programa.\n{0}
+info.job_couldnt_be_run_exceeded_hard_limit = No es posible ejecutar el trabajo porque excede los l\u00EDmites del servidor.\n{0}
+info.job_couldnt_be_run_incorrect_param_setting = No es posible ejecutar el trabjao porque el servidor no soporta algunos de los par\u00E1metros.\n{0}\nPor favor, aseg\u00FArese de que ha usado los par\u00E1metros adecuados para este servicio\n
+info.no_jobs_ran = No se ha ejecutado ningún trabajo
+info.failed_to_submit_prediction = Error al enviar la predicci\u00F3n\:\n{0} {1}
+info.invalid_jnet_job_result_data ={0}\n{1}\nResultados del trabajo JNet no v\u00E1lidos\!\n{2}
+info.failed_to_submit_sequences_for_alignment = Error al enviar la secuencias para el alineamiento.\nLo m\u00E1s probable es que haya un problema en el servidor.\nSimplemente, cierre la ventana\n
+info.alignment_object_method_notes = \nNotas sobre los m\u00E9todos del objeto alineamiento\n
+info.server_exception = \n{0} Excepci\u00F3n del servidor\!\n{1}
+status.processing_commandline_args = Procesando los argumentos de la línea de comandos...
+status.das_features_being_retrived = Recuperando características DAS...
+status.searching_for_sequences_from = Buscando secuencias en {0}
+status.finished_searching_for_sequences_from = Finalizada la búsqueda de secuencias en {0}
+label.eps_file = Fichero EPS
+label.png_image = Imagen PNG
+status.saving_file = Guardando {0}
+status.export_complete = Exportación completada.
+status.fetching_pdb = Recuperando PDB {0}
+status.refreshing_news = Refrescando noticias
+status.importing_vamsas_session_from = Importando sesión VAMSAS de {0}
+status.opening_params = Abriendo {0}
+status.waiting_sequence_database_fetchers_init = Esperando la inicialización de los recuperadores de bases de datos de secuencias
+status.init_sequence_database_fetchers = Inicializando recuperadores de bases de datos de secuencias
+status.fetching_sequence_queries_from = Recuperando {0} consultas de secuencias de {1}
+status.finshed_querying = Consulta finalizada
+status.parsing_results = Parseando resultados.
+status.processing = Procesando...
+status.refreshing_web_service_menus = Refrescando los menús de servicios web
+status.collecting_job_results = Recolectando los resultados de los trabajos.
+status.fetching_das_sequence_features = Recuperando las características DAS de las secuencias
+status.no_das_sources_active = No existe ninguna fuente DAS activa
+status.das_feature_fetching_cancelled = Recuperación de características DAS cancelada
+status.das_feature_fetching_complete = Recuperación de características DAS completada
+status.fetching_db_refs = Recuperando db refs
+label.font_doesnt_have_letters_defined = La fuente no tiene letras definidas\npor lo que no puede emplease\ncon datos de alineamientos
+label.error_loading_file_params = Error cargando el fichero {0}
+label.error_loading_jalview_file = Error cargando el fichero Jalview
+warn.out_of_memory_when_action = Sin memoria al {0}\!\!\nConsulte los ficheros de ayuda para ajustar la memoria de la m\u00E1quina virtual de Java.
+warn.out_of_memory_loading_file = Sin memoria al cargar el fichero {0}\!\!\nConsulte los ficheros de ayuda para ajustar la memoria de la m\u00E1quina virtual de Java.
+label.out_of_memory = Sin memoria
+label.invalid_id_column_width = Identificador de anchura de columna no válido
+warn.user_defined_width_requirements = La anchura definida por el usuario para la \nlas columnas de anotaci\u00F3n e identificador de secuencias\nen figuras exportadas debe ser\na, al menos, de 12 p\u00EDxels
+label.couldnt_create_sequence_fetcher = No es posible crear SequenceFetcher
+warn.couldnt_create_sequence_fetcher_client = No es posible crear el cliente de recuperador de secuencias. Comprueba el fichero de log para más detalles.
+warn.server_didnt_pass_validation = El servicio no ha pasado la validaci\u00F3n.\nCompruebe la consola de Jalview para m\u00E1s detalles.
+warn.url_must_contain = La URL de la secuencia debe contener $SEQUENCE_ID$ o un regex $SEQUENCE_ID=/<regex>/=$
+info.validate_jabaws_server = \u00BFValidar el servidor JabaWS?\n(Consulte la consola de salida para obtener los resultados)
+label.test_server = ¿Probar servidor?
+info.you_want_jalview_to_find_uniprot_accessions = \u00BFDesea que Jalview encuentre\nUniprot Accession ids para los nombres de secuencias dados?
+label.find_uniprot_accession_ids = Buscar Uniprot Accession Ids
+label.new_sequence_fetcher = Añadir recuperador de secuencias
+label.additional_sequence_fetcher = Recuperador de secuencia adicional
+label.select_database_retrieval_source = Seleccionar fuente de recuperación de bases de datos
+label.overwrite_existing_file = ¿Sobreescribir el fichero existente?
+label.file_already_exists = El fichero existe
+label.edit_jabaws_url = Editar JABAWS URL
+label.add_jabaws_url = Añadir nueva JABAWS URL
+label.news_from_jalview = Noticias de http://www.jalview.org
+label.cut_paste_alignmen_file = Cortar & Pegar fichero de alineamiento
+label.enter_redundancy_thereshold = Introducir el umbral de redundancia
+label.select_dark_light_set_thereshold = <i>Seleccionar un color oscuro y un color claro para el texto y establecer el umbral en que<br>cambiar entre colores, basándose en el color de fondo</i>
+label.select_feature_colour = Seleccionar color de las características
+label.ignore_gaps_consensus = Ignorar huecos en el consenso
+label.show_group_histogram = Mostrar histograma de grupo
+label.show_group_logo = Mostrar logo de grupo
+label.normalise_group_logo = Normalizar el logo de grupo
+label.show_histogram = Mostrar histograma
+label.show_logo = Mostrar logo
+label.normalise_logo = Normalizar logo
+label.no_colour_selection_in_scheme = Por favor, seleccione un color antes de aplicar el esquema cromático
+label.no_colour_selection_warn = Error guardando el esquema cromático
\ No newline at end of file
--- /dev/null
+<html>
+<header><title>BioJS viewer</title></header>
+
+<body>
+
+<!-- include MSA js + css -->
+<!-- <script src="https://s3-eu-west-1.amazonaws.com/biojs/msa/latest/msa.js"></script> -->
+<!-- <link type=text/css rel=stylesheet href=https://s3-eu-west-1.amazonaws.com/biojs/msa/latest/msa.css /> -->
+
+ <img src="#jalview_logo#" alt="Jalview Logo" title="This html page was generated from Jalview, to import the data back to Jalview, please drag the generated html file and drop it unto the Jalview workbench.
+
+ Alternatively, you could copy the url from the address bar and use Jalview's url importer (main menu-> File-> Input Alignment-> from URL) to import back the alignment jalview." >
+
+</br>
+</br>
+
+<button onclick="javascipt:openJalviewUsingCurrentUrl();">Launch in Jalview</button>
+<input type="button" name="divToggleButton" id="divToggleButton" onclick="javascipt:toggleMenuVisibility();" value="Show Menu"></input>
+
+</br>
+</br>
+
+<div id="yourDiv">press "Run with JS"</div>
+<input type='hidden' id='seqData' name='seqData' value='#sequenceData#'/>
+
+</body>
+</html>
+
+
+
+<script>
+
+function toggleMenuVisibility(){
+ //alert("toggleMenuVisibility called!");
+
+ var menu = document.getElementsByClassName("biojs_msa_menubar");
+ var divToggleButton = document.getElementById("divToggleButton");
+ if(menu[0].style.display == 'block'){
+ menu[0].style.display = 'none';
+ divToggleButton.value="Show Menu";
+ }else{
+ menu[0].style.display = 'block';
+ divToggleButton.value="Hide Menu";
+ }
+}
+function openJalviewUsingCurrentUrl2(){
+var jnpl = "<!--"+
+"Hi!"+
+"If you have downloaded this file after pressing \"Launch Full Application\" from Jalview on a web page and you don't know what to do with this file, you must install Java from http://www.java.sun.com then try opening this file again."+
+" \n"+
+" JNLP generated by /jalviewServlet/services/launchAppDev"+
+" JNLP generated from http://www.jalview.org/builds/develop/webstart/jalview.jnlp"+
+"Available servlet parameters (please URLEncode):"+
+" open=<alignment file URL>"+
+" jvm-max-heap=heap size in M or G"+
+" features maps to '-features'"+
+" treeFile maps to '-tree'"+
+" tree maps to '-tree'"+
+" annotations maps to '-annotations'"+
+" colour maps to '-colour'"+
+" "+
+"-->"+
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?><jnlp spec=\"1.0+\" codebase=\"http://www.jalview.org/builds/develop/webstart\"> <information> <title>Jalview</title> <vendor>The Barton Group</vendor> <homepage href=\"http://www.jalview.org\"/> <description>Jalview Multiple Alignment Editor</description> <description kind=\"short\">Jalview</description> <icon href=\"JalviewLogo_big.png\"/> <offline-allowed/> </information> <security> <all-permissions/> </security> <resources> <j2se version=\"1.7+\" initial-heap-size=\"10M\" max-heap-size=\"2G\"/> <jar href=\"jalview.jar\"/> <jar href=\"JGoogleAnalytics_0.3.jar\"/> <jar href=\"Jmol-12.2.4.jar\"/> <jar href=\"VARNAv3-91.jar\"/> <jar href=\"activation.jar\"/> <jar href=\"apache-mime4j-0.6.jar\"/> <jar href=\"axis.jar\"/> <jar href=\"castor-1.1-cycle-xml.jar\"/> <jar href=\"commons-codec-1.3.jar\"/> <jar href=\"commons-discovery.jar\"/> <jar href=\"commons-logging-1.1.1.jar\"/> <jar href=\"groovy-all-1.8.2.jar\"/> <jar href=\"httpclient-4.0.3.jar\"/> <jar href=\"httpcore-4.0.1.jar\"/> <jar href=\"httpmime-4.0.3.jar\"/> <jar href=\"jalview_jnlp_vm.jar\"/> <jar href=\"jaxrpc.jar\"/> <jar href=\"jdas-1.0.4.jar\"/> <jar href=\"jhall.jar\"/> <jar href=\"json_simple-1.1.jar\"/> <jar href=\"jsoup-1.8.1.jar\"/> <jar href=\"jswingreader-0.3.jar\"/> <jar href=\"log4j-to-slf4j-2.0-rc2.jar\"/> <jar href=\"mail.jar\"/> <jar href=\"miglayout-4.0-swing.jar\"/> <jar href=\"min-jabaws-client-2.1.0.jar\"/> <jar href=\"regex.jar\"/> <jar href=\"saaj.jar\"/> <jar href=\"slf4j-api-1.7.7.jar\"/> <jar href=\"slf4j-log4j12-1.7.7.jar\"/> <jar href=\"spring-core-3.0.5.RELEASE.jar\"/> <jar href=\"spring-web-3.0.5.RELEASE.jar\"/> <jar href=\"vamsas-client.jar\"/> <jar href=\"wsdl4j.jar\"/> <jar href=\"xercesImpl.jar\"/> <jar href=\"xml-apis.jar\"/> <property name=\"jalview.version\" value=\"Development Branch Build\"/> </resources>"+
+"<application-desc main-class=\"jalview.bin.Jalview\">"+
+"<argument>-open</argument>"+
+"<argument>file:///Users/tcnofoegbu/Documents/workspace/java/dev/jalview/examples/example_biojs.html</argument>"+
+"</application-desc>"+
+" <security>"+
+" <all-permissions/>"+
+" </security>"+
+"</jnlp>"
+
+var encodedUri = encodeURI(jnpl);
+window.open(encodedUri)
+//alert(jnpl)
+}
+
+function openJalviewUsingCurrentUrl(){
+ var url = "http://webservices.compbio.dundee.ac.uk:38080/jalviewServlet/services/launchAppDev";
+ var myForm = document.createElement("form");
+ myForm.action = url;
+
+ var myInput = document.createElement("input") ;
+ myInput.setAttribute("name", "jvm-max-heap") ;
+ myInput.setAttribute("value", "2G");
+ myForm.appendChild(myInput) ;
+
+ var myInput1 = document.createElement("input") ;
+ myInput1.setAttribute("name", "open") ;
+ myInput1.setAttribute("value", document.URL);
+ myForm.appendChild(myInput1) ;
+
+
+ document.body.appendChild(myForm) ;
+ myForm.submit() ;
+ document.body.removeChild(myForm) ;
+}
+
+
+require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+var css = ".biojs_msa_stage {\n cursor: default;\n line-height: normal; }\n\n.biojs_msa_labels {\n color: black;\n display: inline-block;\n white-space: nowrap;\n cursor: pointer;\n vertical-align: top; }\n\n.biojs_msa_seqblock {\n cursor: move; }\n\n.biojs_msa_layer {\n display: block;\n white-space: nowrap; }\n\n.biojs_msa_labelblock::-webkit-scrollbar, .biojs_msa_header::-webkit-scrollbar {\n -webkit-appearance: none;\n width: 7px;\n height: 7px; }\n\n.biojs_msa_labelblock::-webkit-scrollbar-thumb, .biojs_msa_header::-webkit-scrollbar-thumb {\n border-radius: 4px;\n background-color: rgba(0, 0, 0, 0.5);\n box-shadow: 0 0 1px rgba(255, 255, 255, 0.5); }\n\n.biojs_msa_marker {\n color: grey;\n white-space: nowrap;\n cursor: pointer; }\n\n.biojs_msa_marker span {\n text-align: center; }\n\n.biojs_msa_menubar .biojs_msa_menubar_alink {\n background: #3498db;\n background-image: -webkit-linear-gradient(top, #3498db, #2980b9);\n background-image: -moz-linear-gradient(top, #3498db, #2980b9);\n background-image: -ms-linear-gradient(top, #3498db, #2980b9);\n background-image: -o-linear-gradient(top, #3498db, #2980b9);\n background-image: linear-gradient(to bottom, #3498db, #2980b9);\n -webkit-border-radius: 28;\n -moz-border-radius: 28;\n border-radius: 28px;\n font-family: Arial;\n color: #ffffff;\n padding: 3px 10px 3px 10px;\n margin-left: 10px;\n text-decoration: none; }\n\n.biojs_msa_menubar .biojs_msa_menubar_alink:hover {\n cursor: pointer; }\n\n/* jquery dropdown CSS */\n.dropdown {\n position: absolute;\n z-index: 9999999;\n display: none; }\n\n.dropdown .dropdown-menu,\n.dropdown .dropdown-panel {\n min-width: 160px;\n max-width: 360px;\n list-style: none;\n background: #FFF;\n border: solid 1px #DDD;\n border: solid 1px rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n overflow: visible;\n padding: 4px 0;\n margin: 0; }\n\n.dropdown .dropdown-panel {\n padding: 10px; }\n\n.dropdown.dropdown-scroll .dropdown-menu,\n.dropdown.dropdown-scroll .dropdown-panel {\n max-height: 358px;\n overflow: auto; }\n\n.dropdown .dropdown-menu LI {\n list-style: none;\n padding: 0 0;\n margin: 0;\n line-height: 18px; }\n\n.dropdown .dropdown-menu LI,\n.dropdown .dropdown-menu LABEL {\n display: block;\n color: #555;\n text-decoration: none;\n line-height: 18px;\n padding: 3px 15px;\n white-space: nowrap; }\n\n.dropdown .dropdown-menu LI:hover,\n.dropdown .dropdown-menu LABEL:hover {\n background-color: #08C;\n color: #FFF;\n cursor: pointer; }\n\n.dropdown .dropdown-menu .dropdown-divider {\n font-size: 1px;\n border-top: solid 1px #E5E5E5;\n padding: 0;\n margin: 5px 0; }\n"; (require("/home/travis/build/greenify/biojs-vis-msa/node_modules/cssify"))(css); module.exports = css;
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/cssify":48}],2:[function(require,module,exports){
+module.exports = require("./src/index");
+
+},{"./src/index":72}],3:[function(require,module,exports){
+var _ = require('underscore');
+var viewType = require("backbone-viewj");
+var pluginator;
+
+module.exports = pluginator = viewType.extend({
+ renderSubviews: function() {
+ var oldEl = this.el;
+ var el = document.createElement("div");
+ this.setElement(el);
+ var frag = document.createDocumentFragment();
+ if (oldEl.parentNode != null) {
+ oldEl.parentNode.replaceChild(this.el, oldEl);
+ }
+ var views = this._views();
+ var viewsSorted = _.sortBy(views, function(el) {
+ return el.ordering;
+ });
+ var view, node;
+ for (var i = 0; i < viewsSorted.length; i++) {
+ view = viewsSorted[i];
+ view.render();
+ node = view.el;
+ if (node != null) {
+ frag.appendChild(node);
+ }
+ }
+ el.appendChild(frag);
+ return el;
+ },
+ addView: function(key, view) {
+ var views = this._views();
+ if (view == null) {
+ throw "Invalid plugin. ";
+ }
+ if (view.ordering == null) {
+ view.ordering = key;
+ }
+ return views[key] = view;
+ },
+ removeViews: function() {
+ var el, key;
+ var views = this._views();
+ for (key in views) {
+ el = views[key];
+ el.undelegateEvents();
+ el.unbind();
+ if (el.removeViews != null) {
+ el.removeViews();
+ }
+ el.remove();
+ }
+ return this.views = {};
+ },
+ removeView: function(key) {
+ var views = this._views();
+ views[key].remove();
+ return delete views[key];
+ },
+ getView: function(key) {
+ var views = this._views();
+ return views[key];
+ },
+ remove: function() {
+ this.removeViews();
+ return viewType.prototype.remove.apply(this);
+ },
+ _views: function() {
+ if (this.views == null) {
+ this.views = {};
+ }
+ return this.views;
+ }
+});
+
+},{"backbone-viewj":10,"underscore":59}],4:[function(require,module,exports){
+// Backbone.js 1.1.2
+
+// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Backbone may be freely distributed under the MIT license.
+// For all details and documentation:
+// http://backbonejs.org
+
+var Events = require("backbone-events-standalone");
+var extend = require("backbone-extend-standalone");
+var _ = require("underscore");
+var Model = require("./model");
+
+// Create local references to array methods we'll want to use later.
+var array = [];
+var slice = array.slice;
+
+// Backbone.Collection
+// -------------------
+
+// If models tend to represent a single row of data, a Backbone Collection is
+// more analogous to a table full of data ... or a small slice or page of that
+// table, or a collection of rows that belong together for a particular reason
+// -- all of the messages in this particular folder, all of the documents
+// belonging to this particular author, and so on. Collections maintain
+// indexes of their models, both in order, and for lookup by `id`.
+
+// Create a new **Collection**, perhaps to contain a specific type of `model`.
+// If a `comparator` is specified, the Collection will maintain
+// its models in sort order, as they're added and removed.
+var Collection = function(models, options) {
+ options || (options = {});
+ if (options.model) this.model = options.model;
+ if (options.comparator !== void 0) this.comparator = options.comparator;
+ this._reset();
+ this.initialize.apply(this, arguments);
+ if (models) this.reset(models, _.extend({silent: true}, options));
+};
+
+// Default options for `Collection#set`.
+var setOptions = {add: true, remove: true, merge: true};
+var addOptions = {add: true, remove: false};
+
+// Define the Collection's inheritable methods.
+_.extend(Collection.prototype, Events, {
+
+ // The default model for a collection is just a **Backbone.Model**.
+ // This should be overridden in most cases.
+ model: Model,
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // The JSON representation of a Collection is an array of the
+ // models' attributes.
+ toJSON: function(options) {
+ return this.map(function(model){ return model.toJSON(options); });
+ },
+
+ // Proxy `Backbone.sync` by default.
+ sync: function() {
+ return Backbone.sync.apply(this, arguments);
+ },
+
+ // Add a model, or list of models to the set.
+ add: function(models, options) {
+ return this.set(models, _.extend({merge: false}, options, addOptions));
+ },
+
+ // Remove a model, or a list of models from the set.
+ remove: function(models, options) {
+ var singular = !_.isArray(models);
+ models = singular ? [models] : _.clone(models);
+ options || (options = {});
+ for (var i = 0, length = models.length; i < length; i++) {
+ var model = models[i] = this.get(models[i]);
+ if (!model) continue;
+ var id = this.modelId(model.attributes);
+ if (id != null) delete this._byId[id];
+ delete this._byId[model.cid];
+ var index = this.indexOf(model);
+ this.models.splice(index, 1);
+ this.length--;
+ if (!options.silent) {
+ options.index = index;
+ model.trigger('remove', model, this, options);
+ }
+ this._removeReference(model, options);
+ }
+ return singular ? models[0] : models;
+ },
+
+ // Update a collection by `set`-ing a new list of models, adding new ones,
+ // removing models that are no longer present, and merging models that
+ // already exist in the collection, as necessary. Similar to **Model#set**,
+ // the core operation for updating the data contained by the collection.
+ set: function(models, options) {
+ options = _.defaults({}, options, setOptions);
+ if (options.parse) models = this.parse(models, options);
+ var singular = !_.isArray(models);
+ models = singular ? (models ? [models] : []) : models.slice();
+ var id, model, attrs, existing, sort;
+ var at = options.at;
+ var sortable = this.comparator && (at == null) && options.sort !== false;
+ var sortAttr = _.isString(this.comparator) ? this.comparator : null;
+ var toAdd = [], toRemove = [], modelMap = {};
+ var add = options.add, merge = options.merge, remove = options.remove;
+ var order = !sortable && add && remove ? [] : false;
+
+ // Turn bare objects into model references, and prevent invalid models
+ // from being added.
+ for (var i = 0, length = models.length; i < length; i++) {
+ attrs = models[i];
+
+ // If a duplicate is found, prevent it from being added and
+ // optionally merge it into the existing model.
+ if (existing = this.get(attrs)) {
+ if (remove) modelMap[existing.cid] = true;
+ if (merge && attrs !== existing) {
+ attrs = this._isModel(attrs) ? attrs.attributes : attrs;
+ if (options.parse) attrs = existing.parse(attrs, options);
+ existing.set(attrs, options);
+ if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
+ }
+ models[i] = existing;
+
+ // If this is a new, valid model, push it to the `toAdd` list.
+ } else if (add) {
+ model = models[i] = this._prepareModel(attrs, options);
+ if (!model) continue;
+ toAdd.push(model);
+ this._addReference(model, options);
+ }
+
+ // Do not add multiple models with the same `id`.
+ model = existing || model;
+ if (!model) continue;
+ id = this.modelId(model.attributes);
+ if (order && (model.isNew() || !modelMap[id])) order.push(model);
+ modelMap[id] = true;
+ }
+
+ // Remove nonexistent models if appropriate.
+ if (remove) {
+ for (var i = 0, length = this.length; i < length; i++) {
+ if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
+ }
+ if (toRemove.length) this.remove(toRemove, options);
+ }
+
+ // See if sorting is needed, update `length` and splice in new models.
+ if (toAdd.length || (order && order.length)) {
+ if (sortable) sort = true;
+ this.length += toAdd.length;
+ if (at != null) {
+ for (var i = 0, length = toAdd.length; i < length; i++) {
+ this.models.splice(at + i, 0, toAdd[i]);
+ }
+ } else {
+ if (order) this.models.length = 0;
+ var orderedModels = order || toAdd;
+ for (var i = 0, length = orderedModels.length; i < length; i++) {
+ this.models.push(orderedModels[i]);
+ }
+ }
+ }
+
+ // Silently sort the collection if appropriate.
+ if (sort) this.sort({silent: true});
+
+ // Unless silenced, it's time to fire all appropriate add/sort events.
+ if (!options.silent) {
+ var addOpts = at != null ? _.clone(options) : options;
+ for (var i = 0, length = toAdd.length; i < length; i++) {
+ if (at != null) addOpts.index = at + i;
+ (model = toAdd[i]).trigger('add', model, this, addOpts);
+ }
+ if (sort || (order && order.length)) this.trigger('sort', this, options);
+ }
+
+ // Return the added (or merged) model (or models).
+ return singular ? models[0] : models;
+ },
+
+ // When you have more items than you want to add or remove individually,
+ // you can reset the entire set with a new list of models, without firing
+ // any granular `add` or `remove` events. Fires `reset` when finished.
+ // Useful for bulk operations and optimizations.
+ reset: function(models, options) {
+ options || (options = {});
+ for (var i = 0, length = this.models.length; i < length; i++) {
+ this._removeReference(this.models[i], options);
+ }
+ options.previousModels = this.models;
+ this._reset();
+ models = this.add(models, _.extend({silent: true}, options));
+ if (!options.silent) this.trigger('reset', this, options);
+ return models;
+ },
+
+ // Add a model to the end of the collection.
+ push: function(model, options) {
+ return this.add(model, _.extend({at: this.length}, options));
+ },
+
+ // Remove a model from the end of the collection.
+ pop: function(options) {
+ var model = this.at(this.length - 1);
+ this.remove(model, options);
+ return model;
+ },
+
+ // Add a model to the beginning of the collection.
+ unshift: function(model, options) {
+ return this.add(model, _.extend({at: 0}, options));
+ },
+
+ // Remove a model from the beginning of the collection.
+ shift: function(options) {
+ var model = this.at(0);
+ this.remove(model, options);
+ return model;
+ },
+
+ // Slice out a sub-array of models from the collection.
+ slice: function() {
+ return slice.apply(this.models, arguments);
+ },
+
+ // Get a model from the set by id.
+ get: function(obj) {
+ if (obj == null) return void 0;
+ var id = this.modelId(this._isModel(obj) ? obj.attributes : obj);
+ return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
+ },
+
+ // Get the model at the given index.
+ at: function(index) {
+ if (index < 0) index += this.length;
+ return this.models[index];
+ },
+
+ // Return models with matching attributes. Useful for simple cases of
+ // `filter`.
+ where: function(attrs, first) {
+ if (_.isEmpty(attrs)) return first ? void 0 : [];
+ return this[first ? 'find' : 'filter'](function(model) {
+ for (var key in attrs) {
+ if (attrs[key] !== model.get(key)) return false;
+ }
+ return true;
+ });
+ },
+
+ // Return the first model with matching attributes. Useful for simple cases
+ // of `find`.
+ findWhere: function(attrs) {
+ return this.where(attrs, true);
+ },
+
+ // Force the collection to re-sort itself. You don't need to call this under
+ // normal circumstances, as the set will maintain sort order as each item
+ // is added.
+ sort: function(options) {
+ if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
+ options || (options = {});
+
+ // Run sort based on type of `comparator`.
+ if (_.isString(this.comparator) || this.comparator.length === 1) {
+ this.models = this.sortBy(this.comparator, this);
+ } else {
+ this.models.sort(_.bind(this.comparator, this));
+ }
+
+ if (!options.silent) this.trigger('sort', this, options);
+ return this;
+ },
+
+ // Pluck an attribute from each model in the collection.
+ pluck: function(attr) {
+ return _.invoke(this.models, 'get', attr);
+ },
+
+ // Fetch the default set of models for this collection, resetting the
+ // collection when they arrive. If `reset: true` is passed, the response
+ // data will be passed through the `reset` method instead of `set`.
+ fetch: function(options) {
+ options = options ? _.clone(options) : {};
+ if (options.parse === void 0) options.parse = true;
+ var success = options.success;
+ var collection = this;
+ options.success = function(resp) {
+ var method = options.reset ? 'reset' : 'set';
+ collection[method](resp, options);
+ if (success) success(collection, resp, options);
+ collection.trigger('sync', collection, resp, options);
+ };
+ wrapError(this, options);
+ return this.sync('read', this, options);
+ },
+
+ // Create a new instance of a model in this collection. Add the model to the
+ // collection immediately, unless `wait: true` is passed, in which case we
+ // wait for the server to agree.
+ create: function(model, options) {
+ options = options ? _.clone(options) : {};
+ if (!(model = this._prepareModel(model, options))) return false;
+ if (!options.wait) this.add(model, options);
+ var collection = this;
+ var success = options.success;
+ options.success = function(model, resp) {
+ if (options.wait) collection.add(model, options);
+ if (success) success(model, resp, options);
+ };
+ model.save(null, options);
+ return model;
+ },
+
+ // **parse** converts a response into a list of models to be added to the
+ // collection. The default implementation is just to pass it through.
+ parse: function(resp, options) {
+ return resp;
+ },
+
+ // Create a new collection with an identical list of models as this one.
+ clone: function() {
+ return new this.constructor(this.models, {
+ model: this.model,
+ comparator: this.comparator
+ });
+ },
+
+ // Define how to uniquely identify models in the collection.
+ modelId: function (attrs) {
+ return attrs[this.model.prototype.idAttribute || 'id'];
+ },
+
+ // Private method to reset all internal state. Called when the collection
+ // is first initialized or reset.
+ _reset: function() {
+ this.length = 0;
+ this.models = [];
+ this._byId = {};
+ },
+
+ // Prepare a hash of attributes (or other model) to be added to this
+ // collection.
+ _prepareModel: function(attrs, options) {
+ if (this._isModel(attrs)) {
+ if (!attrs.collection) attrs.collection = this;
+ return attrs;
+ }
+ options = options ? _.clone(options) : {};
+ options.collection = this;
+ var model = new this.model(attrs, options);
+ if (!model.validationError) return model;
+ this.trigger('invalid', this, model.validationError, options);
+ return false;
+ },
+
+ // Method for checking whether an object should be considered a model for
+ // the purposes of adding to the collection.
+ _isModel: function (model) {
+ return model instanceof Model;
+ },
+
+ // Internal method to create a model's ties to a collection.
+ _addReference: function(model, options) {
+ this._byId[model.cid] = model;
+ var id = this.modelId(model.attributes);
+ if (id != null) this._byId[id] = model;
+ model.on('all', this._onModelEvent, this);
+ },
+
+ // Internal method to sever a model's ties to a collection.
+ _removeReference: function(model, options) {
+ if (this === model.collection) delete model.collection;
+ model.off('all', this._onModelEvent, this);
+ },
+
+ // Internal method called every time a model in the set fires an event.
+ // Sets need to update their indexes when models change ids. All other
+ // events simply proxy through. "add" and "remove" events that originate
+ // in other collections are ignored.
+ _onModelEvent: function(event, model, collection, options) {
+ if ((event === 'add' || event === 'remove') && collection !== this) return;
+ if (event === 'destroy') this.remove(model, options);
+ if (event === 'change') {
+ var prevId = this.modelId(model.previousAttributes());
+ var id = this.modelId(model.attributes);
+ if (prevId !== id) {
+ if (prevId != null) delete this._byId[prevId];
+ if (id != null) this._byId[id] = model;
+ }
+ }
+ this.trigger.apply(this, arguments);
+ }
+
+});
+
+// Underscore methods that we want to implement on the Collection.
+// 90% of the core usefulness of Backbone Collections is actually implemented
+// right here:
+var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
+ 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
+ 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
+ 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
+ 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
+ 'lastIndexOf', 'isEmpty', 'chain', 'sample', 'partition'];
+
+// Mix in each Underscore method as a proxy to `Collection#models`.
+_.each(methods, function(method) {
+ if (!_[method]) return;
+ Collection.prototype[method] = function() {
+ var args = slice.call(arguments);
+ args.unshift(this.models);
+ return _[method].apply(_, args);
+ };
+});
+
+// Underscore methods that take a property name as an argument.
+var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy'];
+
+// Use attributes instead of properties.
+_.each(attributeMethods, function(method) {
+ if (!_[method]) return;
+ Collection.prototype[method] = function(value, context) {
+ var iterator = _.isFunction(value) ? value : function(model) {
+ return model.get(value);
+ };
+ return _[method](this.models, iterator, context);
+ };
+});
+
+// setup inheritance
+Collection.extend = extend;
+module.exports = Collection;
+
+},{"./model":6,"backbone-events-standalone":8,"backbone-extend-standalone":9,"underscore":59}],5:[function(require,module,exports){
+module.exports.Model = require("./model");
+module.exports.Collection = require("./collection");
+module.exports.Events = require("backbone-events-standalone");
+module.exports.extend = require("backbone-extend-standalone");
+
+},{"./collection":4,"./model":6,"backbone-events-standalone":8,"backbone-extend-standalone":9}],6:[function(require,module,exports){
+// Backbone.js 1.1.2
+
+// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Backbone may be freely distributed under the MIT license.
+// For all details and documentation:
+// http://backbonejs.org
+
+var Events = require("backbone-events-standalone");
+var extend = require("backbone-extend-standalone");
+var _ = require("underscore");
+
+// Backbone.Model
+// --------------
+
+// Backbone **Models** are the basic data object in the framework --
+// frequently representing a row in a table in a database on your server.
+// A discrete chunk of data and a bunch of useful, related methods for
+// performing computations and transformations on that data.
+
+// Create a new model with the specified attributes. A client id (`cid`)
+// is automatically generated and assigned for you.
+var Model = function(attributes, options) {
+ var attrs = attributes || {};
+ options || (options = {});
+ this.cid = _.uniqueId('c');
+ this.attributes = {};
+ if (options.collection) this.collection = options.collection;
+ if (options.parse) attrs = this.parse(attrs, options) || {};
+ attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
+ this.set(attrs, options);
+ this.changed = {};
+ this.initialize.apply(this, arguments);
+};
+
+// Attach all inheritable methods to the Model prototype.
+_.extend(Model.prototype, Events, {
+
+ // A hash of attributes whose current and previous value differ.
+ changed: null,
+
+ // The value returned during the last failed validation.
+ validationError: null,
+
+ // The default name for the JSON `id` attribute is `"id"`. MongoDB and
+ // CouchDB users may want to set this to `"_id"`.
+ idAttribute: 'id',
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // Return a copy of the model's `attributes` object.
+ toJSON: function(options) {
+ return _.clone(this.attributes);
+ },
+
+ // Proxy `Backbone.sync` by default -- but override this if you need
+ // custom syncing semantics for *this* particular model.
+ sync: function() {
+ return Backbone.sync.apply(this, arguments);
+ },
+
+ // Get the value of an attribute.
+ get: function(attr) {
+ return this.attributes[attr];
+ },
+
+ // Get the HTML-escaped value of an attribute.
+ escape: function(attr) {
+ return _.escape(this.get(attr));
+ },
+
+ // Returns `true` if the attribute contains a value that is not null
+ // or undefined.
+ has: function(attr) {
+ return this.get(attr) != null;
+ },
+
+ // Set a hash of model attributes on the object, firing `"change"`. This is
+ // the core primitive operation of a model, updating the data and notifying
+ // anyone who needs to know about the change in state. The heart of the beast.
+ set: function(key, val, options) {
+ var attr, attrs, unset, changes, silent, changing, prev, current;
+ if (key == null) return this;
+
+ // Handle both `"key", value` and `{key: value}` -style arguments.
+ if (typeof key === 'object') {
+ attrs = key;
+ options = val;
+ } else {
+ (attrs = {})[key] = val;
+ }
+
+ options || (options = {});
+
+ // Run validation.
+ if (!this._validate(attrs, options)) return false;
+
+ // Extract attributes and options.
+ unset = options.unset;
+ silent = options.silent;
+ changes = [];
+ changing = this._changing;
+ this._changing = true;
+
+ if (!changing) {
+ this._previousAttributes = _.clone(this.attributes);
+ this.changed = {};
+ }
+ current = this.attributes, prev = this._previousAttributes;
+
+ // Check for changes of `id`.
+ if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
+
+ // For each `set` attribute, update or delete the current value.
+ for (attr in attrs) {
+ val = attrs[attr];
+ if (!_.isEqual(current[attr], val)) changes.push(attr);
+ if (!_.isEqual(prev[attr], val)) {
+ this.changed[attr] = val;
+ } else {
+ delete this.changed[attr];
+ }
+ unset ? delete current[attr] : current[attr] = val;
+ }
+
+ // Trigger all relevant attribute changes.
+ if (!silent) {
+ if (changes.length) this._pending = options;
+ for (var i = 0, length = changes.length; i < length; i++) {
+ this.trigger('change:' + changes[i], this, current[changes[i]], options);
+ }
+ }
+
+ // You might be wondering why there's a `while` loop here. Changes can
+ // be recursively nested within `"change"` events.
+ if (changing) return this;
+ if (!silent) {
+ while (this._pending) {
+ options = this._pending;
+ this._pending = false;
+ this.trigger('change', this, options);
+ }
+ }
+ this._pending = false;
+ this._changing = false;
+ return this;
+ },
+
+ // Remove an attribute from the model, firing `"change"`. `unset` is a noop
+ // if the attribute doesn't exist.
+ unset: function(attr, options) {
+ return this.set(attr, void 0, _.extend({}, options, {unset: true}));
+ },
+
+ // Clear all attributes on the model, firing `"change"`.
+ clear: function(options) {
+ var attrs = {};
+ for (var key in this.attributes) attrs[key] = void 0;
+ return this.set(attrs, _.extend({}, options, {unset: true}));
+ },
+
+ // Determine if the model has changed since the last `"change"` event.
+ // If you specify an attribute name, determine if that attribute has changed.
+ hasChanged: function(attr) {
+ if (attr == null) return !_.isEmpty(this.changed);
+ return _.has(this.changed, attr);
+ },
+
+ // Return an object containing all the attributes that have changed, or
+ // false if there are no changed attributes. Useful for determining what
+ // parts of a view need to be updated and/or what attributes need to be
+ // persisted to the server. Unset attributes will be set to undefined.
+ // You can also pass an attributes object to diff against the model,
+ // determining if there *would be* a change.
+ changedAttributes: function(diff) {
+ if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
+ var val, changed = false;
+ var old = this._changing ? this._previousAttributes : this.attributes;
+ for (var attr in diff) {
+ if (_.isEqual(old[attr], (val = diff[attr]))) continue;
+ (changed || (changed = {}))[attr] = val;
+ }
+ return changed;
+ },
+
+ // Get the previous value of an attribute, recorded at the time the last
+ // `"change"` event was fired.
+ previous: function(attr) {
+ if (attr == null || !this._previousAttributes) return null;
+ return this._previousAttributes[attr];
+ },
+
+ // Get all of the attributes of the model at the time of the previous
+ // `"change"` event.
+ previousAttributes: function() {
+ return _.clone(this._previousAttributes);
+ },
+
+ // Fetch the model from the server. If the server's representation of the
+ // model differs from its current attributes, they will be overridden,
+ // triggering a `"change"` event.
+ fetch: function(options) {
+ options = options ? _.clone(options) : {};
+ if (options.parse === void 0) options.parse = true;
+ var model = this;
+ var success = options.success;
+ options.success = function(resp) {
+ if (!model.set(model.parse(resp, options), options)) return false;
+ if (success) success(model, resp, options);
+ model.trigger('sync', model, resp, options);
+ };
+ wrapError(this, options);
+ return this.sync('read', this, options);
+ },
+
+ // Set a hash of model attributes, and sync the model to the server.
+ // If the server returns an attributes hash that differs, the model's
+ // state will be `set` again.
+ save: function(key, val, options) {
+ var attrs, method, xhr, attributes = this.attributes;
+
+ // Handle both `"key", value` and `{key: value}` -style arguments.
+ if (key == null || typeof key === 'object') {
+ attrs = key;
+ options = val;
+ } else {
+ (attrs = {})[key] = val;
+ }
+
+ options = _.extend({validate: true}, options);
+
+ // If we're not waiting and attributes exist, save acts as
+ // `set(attr).save(null, opts)` with validation. Otherwise, check if
+ // the model will be valid when the attributes, if any, are set.
+ if (attrs && !options.wait) {
+ if (!this.set(attrs, options)) return false;
+ } else {
+ if (!this._validate(attrs, options)) return false;
+ }
+
+ // Set temporary attributes if `{wait: true}`.
+ if (attrs && options.wait) {
+ this.attributes = _.extend({}, attributes, attrs);
+ }
+
+ // After a successful server-side save, the client is (optionally)
+ // updated with the server-side state.
+ if (options.parse === void 0) options.parse = true;
+ var model = this;
+ var success = options.success;
+ options.success = function(resp) {
+ // Ensure attributes are restored during synchronous saves.
+ model.attributes = attributes;
+ var serverAttrs = model.parse(resp, options);
+ if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
+ if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
+ return false;
+ }
+ if (success) success(model, resp, options);
+ model.trigger('sync', model, resp, options);
+ };
+ wrapError(this, options);
+
+ method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
+ if (method === 'patch' && !options.attrs) options.attrs = attrs;
+ xhr = this.sync(method, this, options);
+
+ // Restore attributes.
+ if (attrs && options.wait) this.attributes = attributes;
+
+ return xhr;
+ },
+
+ // Destroy this model on the server if it was already persisted.
+ // Optimistically removes the model from its collection, if it has one.
+ // If `wait: true` is passed, waits for the server to respond before removal.
+ destroy: function(options) {
+ options = options ? _.clone(options) : {};
+ var model = this;
+ var success = options.success;
+
+ var destroy = function() {
+ model.stopListening();
+ model.trigger('destroy', model, model.collection, options);
+ };
+
+ options.success = function(resp) {
+ if (options.wait || model.isNew()) destroy();
+ if (success) success(model, resp, options);
+ if (!model.isNew()) model.trigger('sync', model, resp, options);
+ };
+
+ if (this.isNew()) {
+ options.success();
+ return false;
+ }
+ wrapError(this, options);
+
+ var xhr = this.sync('delete', this, options);
+ if (!options.wait) destroy();
+ return xhr;
+ },
+
+ // Default URL for the model's representation on the server -- if you're
+ // using Backbone's restful methods, override this to change the endpoint
+ // that will be called.
+ url: function() {
+ var base =
+ _.result(this, 'urlRoot') ||
+ _.result(this.collection, 'url') ||
+ urlError();
+ if (this.isNew()) return base;
+ return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id);
+ },
+
+ // **parse** converts a response into the hash of attributes to be `set` on
+ // the model. The default implementation is just to pass the response along.
+ parse: function(resp, options) {
+ return resp;
+ },
+
+ // Create a new model with identical attributes to this one.
+ clone: function() {
+ return new this.constructor(this.attributes);
+ },
+
+ // A model is new if it has never been saved to the server, and lacks an id.
+ isNew: function() {
+ return !this.has(this.idAttribute);
+ },
+
+ // Check if the model is currently in a valid state.
+ isValid: function(options) {
+ return this._validate({}, _.extend(options || {}, { validate: true }));
+ },
+
+ // Run validation against the next complete set of model attributes,
+ // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
+ _validate: function(attrs, options) {
+ if (!options.validate || !this.validate) return true;
+ attrs = _.extend({}, this.attributes, attrs);
+ var error = this.validationError = this.validate(attrs, options) || null;
+ if (!error) return true;
+ this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
+ return false;
+ }
+
+});
+
+// Underscore methods that we want to implement on the Model.
+var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit', 'chain', 'isEmpty'];
+
+// Mix in each Underscore method as a proxy to `Model#attributes`.
+_.each(modelMethods, function(method) {
+ if (!_[method]) return;
+ Model.prototype[method] = function() {
+ var args = slice.call(arguments);
+ args.unshift(this.attributes);
+ return _[method].apply(_, args);
+ };
+});
+
+// setup inheritance
+Model.extend = extend;
+module.exports = Model;
+
+},{"backbone-events-standalone":8,"backbone-extend-standalone":9,"underscore":59}],7:[function(require,module,exports){
+/**
+ * Standalone extraction of Backbone.Events, no external dependency required.
+ * Degrades nicely when Backone/underscore are already available in the current
+ * global context.
+ *
+ * Note that docs suggest to use underscore's `_.extend()` method to add Events
+ * support to some given object. A `mixin()` method has been added to the Events
+ * prototype to avoid using underscore for that sole purpose:
+ *
+ * var myEventEmitter = BackboneEvents.mixin({});
+ *
+ * Or for a function constructor:
+ *
+ * function MyConstructor(){}
+ * MyConstructor.prototype.foo = function(){}
+ * BackboneEvents.mixin(MyConstructor.prototype);
+ *
+ * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
+ * (c) 2013 Nicolas Perriault
+ */
+/* global exports:true, define, module */
+(function() {
+ var root = this,
+ breaker = {},
+ nativeForEach = Array.prototype.forEach,
+ hasOwnProperty = Object.prototype.hasOwnProperty,
+ slice = Array.prototype.slice,
+ idCounter = 0;
+
+ // Returns a partial implementation matching the minimal API subset required
+ // by Backbone.Events
+ function miniscore() {
+ return {
+ keys: Object.keys || function (obj) {
+ if (typeof obj !== "object" && typeof obj !== "function" || obj === null) {
+ throw new TypeError("keys() called on a non-object");
+ }
+ var key, keys = [];
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ keys[keys.length] = key;
+ }
+ }
+ return keys;
+ },
+
+ uniqueId: function(prefix) {
+ var id = ++idCounter + '';
+ return prefix ? prefix + id : id;
+ },
+
+ has: function(obj, key) {
+ return hasOwnProperty.call(obj, key);
+ },
+
+ each: function(obj, iterator, context) {
+ if (obj == null) return;
+ if (nativeForEach && obj.forEach === nativeForEach) {
+ obj.forEach(iterator, context);
+ } else if (obj.length === +obj.length) {
+ for (var i = 0, l = obj.length; i < l; i++) {
+ if (iterator.call(context, obj[i], i, obj) === breaker) return;
+ }
+ } else {
+ for (var key in obj) {
+ if (this.has(obj, key)) {
+ if (iterator.call(context, obj[key], key, obj) === breaker) return;
+ }
+ }
+ }
+ },
+
+ once: function(func) {
+ var ran = false, memo;
+ return function() {
+ if (ran) return memo;
+ ran = true;
+ memo = func.apply(this, arguments);
+ func = null;
+ return memo;
+ };
+ }
+ };
+ }
+
+ var _ = miniscore(), Events;
+
+ // Backbone.Events
+ // ---------------
+
+ // A module that can be mixed in to *any object* in order to provide it with
+ // custom events. You may bind with `on` or remove with `off` callback
+ // functions to an event; `trigger`-ing an event fires all callbacks in
+ // succession.
+ //
+ // var object = {};
+ // _.extend(object, Backbone.Events);
+ // object.on('expand', function(){ alert('expanded'); });
+ // object.trigger('expand');
+ //
+ Events = {
+
+ // Bind an event to a `callback` function. Passing `"all"` will bind
+ // the callback to all events fired.
+ on: function(name, callback, context) {
+ if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
+ this._events || (this._events = {});
+ var events = this._events[name] || (this._events[name] = []);
+ events.push({callback: callback, context: context, ctx: context || this});
+ return this;
+ },
+
+ // Bind an event to only be triggered a single time. After the first time
+ // the callback is invoked, it will be removed.
+ once: function(name, callback, context) {
+ if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
+ var self = this;
+ var once = _.once(function() {
+ self.off(name, once);
+ callback.apply(this, arguments);
+ });
+ once._callback = callback;
+ return this.on(name, once, context);
+ },
+
+ // Remove one or many callbacks. If `context` is null, removes all
+ // callbacks with that function. If `callback` is null, removes all
+ // callbacks for the event. If `name` is null, removes all bound
+ // callbacks for all events.
+ off: function(name, callback, context) {
+ var retain, ev, events, names, i, l, j, k;
+ if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
+ if (!name && !callback && !context) {
+ this._events = {};
+ return this;
+ }
+
+ names = name ? [name] : _.keys(this._events);
+ for (i = 0, l = names.length; i < l; i++) {
+ name = names[i];
+ if (events = this._events[name]) {
+ this._events[name] = retain = [];
+ if (callback || context) {
+ for (j = 0, k = events.length; j < k; j++) {
+ ev = events[j];
+ if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
+ (context && context !== ev.context)) {
+ retain.push(ev);
+ }
+ }
+ }
+ if (!retain.length) delete this._events[name];
+ }
+ }
+
+ return this;
+ },
+
+ // Trigger one or many events, firing all bound callbacks. Callbacks are
+ // passed the same arguments as `trigger` is, apart from the event name
+ // (unless you're listening on `"all"`, which will cause your callback to
+ // receive the true name of the event as the first argument).
+ trigger: function(name) {
+ if (!this._events) return this;
+ var args = slice.call(arguments, 1);
+ if (!eventsApi(this, 'trigger', name, args)) return this;
+ var events = this._events[name];
+ var allEvents = this._events.all;
+ if (events) triggerEvents(events, args);
+ if (allEvents) triggerEvents(allEvents, arguments);
+ return this;
+ },
+
+ // Tell this object to stop listening to either specific events ... or
+ // to every object it's currently listening to.
+ stopListening: function(obj, name, callback) {
+ var listeners = this._listeners;
+ if (!listeners) return this;
+ var deleteListener = !name && !callback;
+ if (typeof name === 'object') callback = this;
+ if (obj) (listeners = {})[obj._listenerId] = obj;
+ for (var id in listeners) {
+ listeners[id].off(name, callback, this);
+ if (deleteListener) delete this._listeners[id];
+ }
+ return this;
+ }
+
+ };
+
+ // Regular expression used to split event strings.
+ var eventSplitter = /\s+/;
+
+ // Implement fancy features of the Events API such as multiple event
+ // names `"change blur"` and jQuery-style event maps `{change: action}`
+ // in terms of the existing API.
+ var eventsApi = function(obj, action, name, rest) {
+ if (!name) return true;
+
+ // Handle event maps.
+ if (typeof name === 'object') {
+ for (var key in name) {
+ obj[action].apply(obj, [key, name[key]].concat(rest));
+ }
+ return false;
+ }
+
+ // Handle space separated event names.
+ if (eventSplitter.test(name)) {
+ var names = name.split(eventSplitter);
+ for (var i = 0, l = names.length; i < l; i++) {
+ obj[action].apply(obj, [names[i]].concat(rest));
+ }
+ return false;
+ }
+
+ return true;
+ };
+
+ // A difficult-to-believe, but optimized internal dispatch function for
+ // triggering events. Tries to keep the usual cases speedy (most internal
+ // Backbone events have 3 arguments).
+ var triggerEvents = function(events, args) {
+ var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
+ switch (args.length) {
+ case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
+ case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
+ case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
+ case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
+ default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
+ }
+ };
+
+ var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
+
+ // Inversion-of-control versions of `on` and `once`. Tell *this* object to
+ // listen to an event in another object ... keeping track of what it's
+ // listening to.
+ _.each(listenMethods, function(implementation, method) {
+ Events[method] = function(obj, name, callback) {
+ var listeners = this._listeners || (this._listeners = {});
+ var id = obj._listenerId || (obj._listenerId = _.uniqueId('l'));
+ listeners[id] = obj;
+ if (typeof name === 'object') callback = this;
+ obj[implementation](name, callback, this);
+ return this;
+ };
+ });
+
+ // Aliases for backwards compatibility.
+ Events.bind = Events.on;
+ Events.unbind = Events.off;
+
+ // Mixin utility
+ Events.mixin = function(proto) {
+ var exports = ['on', 'once', 'off', 'trigger', 'stopListening', 'listenTo',
+ 'listenToOnce', 'bind', 'unbind'];
+ _.each(exports, function(name) {
+ proto[name] = this[name];
+ }, this);
+ return proto;
+ };
+
+ // Export Events as BackboneEvents depending on current context
+ if (typeof define === "function") {
+ define(function() {
+ return Events;
+ });
+ } else if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = Events;
+ }
+ exports.BackboneEvents = Events;
+ } else {
+ root.BackboneEvents = Events;
+ }
+})(this);
+
+},{}],8:[function(require,module,exports){
+module.exports = require('./backbone-events-standalone');
+
+},{"./backbone-events-standalone":7}],9:[function(require,module,exports){
+(function (definition) {
+ if (typeof exports === "object") {
+ module.exports = definition();
+ }
+ else if (typeof define === 'function' && define.amd) {
+ define(definition);
+ }
+ else {
+ window.BackboneExtend = definition();
+ }
+})(function () {
+ "use strict";
+
+ // mini-underscore
+ var _ = {
+ has: function (obj, key) {
+ return Object.prototype.hasOwnProperty.call(obj, key);
+ },
+
+ extend: function(obj) {
+ for (var i=1; i<arguments.length; ++i) {
+ var source = arguments[i];
+ if (source) {
+ for (var prop in source) {
+ obj[prop] = source[prop];
+ }
+ }
+ }
+ return obj;
+ }
+ };
+
+ /// Following code is pasted from Backbone.js ///
+
+ // Helper function to correctly set up the prototype chain, for subclasses.
+ // Similar to `goog.inherits`, but uses a hash of prototype properties and
+ // class properties to be extended.
+ var extend = function(protoProps, staticProps) {
+ var parent = this;
+ var child;
+
+ // The constructor function for the new subclass is either defined by you
+ // (the "constructor" property in your `extend` definition), or defaulted
+ // by us to simply call the parent's constructor.
+ if (protoProps && _.has(protoProps, 'constructor')) {
+ child = protoProps.constructor;
+ } else {
+ child = function(){ return parent.apply(this, arguments); };
+ }
+
+ // Add static properties to the constructor function, if supplied.
+ _.extend(child, parent, staticProps);
+
+ // Set the prototype chain to inherit from `parent`, without calling
+ // `parent`'s constructor function.
+ var Surrogate = function(){ this.constructor = child; };
+ Surrogate.prototype = parent.prototype;
+ child.prototype = new Surrogate();
+
+ // Add prototype properties (instance properties) to the subclass,
+ // if supplied.
+ if (protoProps) _.extend(child.prototype, protoProps);
+
+ // Set a convenience property in case the parent's prototype is needed
+ // later.
+ child.__super__ = parent.prototype;
+
+ return child;
+ };
+
+ // Expose the extend function
+ return extend;
+});
+
+},{}],10:[function(require,module,exports){
+// this is the extracted view model from backbone
+// note that we inject jbone as jquery replacment
+// (and underscore directly)
+//
+// Views are almost more convention than they are actual code.
+// MVC pattern
+// Backbone.View
+// -------------
+
+var _ = require("underscore");
+var Events = require("backbone-events-standalone");
+var extend = require("backbone-extend-standalone");
+var $ = require('jbone');
+
+// Backbone Views are almost more convention than they are actual code. A View
+// is simply a JavaScript object that represents a logical chunk of UI in the
+// DOM. This might be a single item, an entire list, a sidebar or panel, or
+// even the surrounding frame which wraps your whole app. Defining a chunk of
+// UI as a **View** allows you to define your DOM events declaratively, without
+// having to worry about render order ... and makes it easy for the view to
+// react to specific changes in the state of your models.
+
+// Creating a Backbone.View creates its initial element outside of the DOM,
+// if an existing element is not provided...
+var View = function(options) {
+ this.cid = _.uniqueId('view');
+ options || (options = {});
+ _.extend(this, _.pick(options, viewOptions));
+ this._ensureElement();
+ this.initialize.apply(this, arguments);
+};
+
+// Cached regex to split keys for `delegate`.
+var delegateEventSplitter = /^(\S+)\s*(.*)$/;
+
+// List of view options to be merged as properties.
+var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
+
+// Set up all inheritable **Backbone.View** properties and methods.
+_.extend(View.prototype, Events, {
+
+ // The default `tagName` of a View's element is `"div"`.
+ tagName: 'div',
+
+ // jQuery delegate for element lookup, scoped to DOM elements within the
+ // current view. This should be preferred to global lookups where possible.
+ $: function(selector) {
+ return this.$el.find(selector);
+ },
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // **render** is the core function that your view should override, in order
+ // to populate its element (`this.el`), with the appropriate HTML. The
+ // convention is for **render** to always return `this`.
+ render: function() {
+ return this;
+ },
+
+ // Remove this view by taking the element out of the DOM, and removing any
+ // applicable Backbone.Events listeners.
+ remove: function() {
+ this._removeElement();
+ this.stopListening();
+ return this;
+ },
+
+ // Remove this view's element from the document and all event listeners
+ // attached to it. Exposed for subclasses using an alternative DOM
+ // manipulation API.
+ _removeElement: function() {
+ this.$el.remove();
+ },
+
+ // Change the view's element (`this.el` property) and re-delegate the
+ // view's events on the new element.
+ setElement: function(element) {
+ this.undelegateEvents();
+ this._setElement(element);
+ this.delegateEvents();
+ return this;
+ },
+
+ // Creates the `this.el` and `this.$el` references for this view using the
+ // given `el`. `el` can be a CSS selector or an HTML string, a jQuery
+ // context or an element. Subclasses can override this to utilize an
+ // alternative DOM manipulation API and are only required to set the
+ // `this.el` property.
+ _setElement: function(el) {
+ this.$el = el instanceof $ ? el : $(el);
+ this.el = this.$el[0];
+ },
+
+ // Set callbacks, where `this.events` is a hash of
+ //
+ // *{"event selector": "callback"}*
+ //
+ // {
+ // 'mousedown .title': 'edit',
+ // 'click .button': 'save',
+ // 'click .open': function(e) { ... }
+ // }
+ //
+ // pairs. Callbacks will be bound to the view, with `this` set properly.
+ // Uses event delegation for efficiency.
+ // Omitting the selector binds the event to `this.el`.
+ delegateEvents: function(events) {
+ if (!(events || (events = _.result(this, 'events')))) return this;
+ this.undelegateEvents();
+ for (var key in events) {
+ var method = events[key];
+ if (!_.isFunction(method)) method = this[events[key]];
+ if (!method) continue;
+ var match = key.match(delegateEventSplitter);
+ this.delegate(match[1], match[2], _.bind(method, this));
+ }
+ return this;
+ },
+
+ // Add a single event listener to the view's element (or a child element
+ // using `selector`). This only works for delegate-able events: not `focus`,
+ // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.
+ delegate: function(eventName, selector, listener) {
+ this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
+ },
+
+ // Clears all callbacks previously bound to the view by `delegateEvents`.
+ // You usually don't need to use this, but may wish to if you have multiple
+ // Backbone views attached to the same DOM element.
+ undelegateEvents: function() {
+ if (this.$el) this.$el.off('.delegateEvents' + this.cid);
+ return this;
+ },
+
+ // A finer-grained `undelegateEvents` for removing a single delegated event.
+ // `selector` and `listener` are both optional.
+ undelegate: function(eventName, selector, listener) {
+ this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
+ },
+
+ // Produces a DOM element to be assigned to your view. Exposed for
+ // subclasses using an alternative DOM manipulation API.
+ _createElement: function(tagName) {
+ return document.createElement(tagName);
+ },
+
+ // Ensure that the View has a DOM element to render into.
+ // If `this.el` is a string, pass it through `$()`, take the first
+ // matching element, and re-assign it to `el`. Otherwise, create
+ // an element from the `id`, `className` and `tagName` properties.
+ _ensureElement: function() {
+ if (!this.el) {
+ var attrs = _.extend({}, _.result(this, 'attributes'));
+ if (this.id) attrs.id = _.result(this, 'id');
+ if (this.className) attrs['class'] = _.result(this, 'className');
+ this.setElement(this._createElement(_.result(this, 'tagName')));
+ this._setAttributes(attrs);
+ } else {
+ this.setElement(_.result(this, 'el'));
+ }
+ },
+
+ // Set attributes from a hash on this view's element. Exposed for
+ // subclasses using an alternative DOM manipulation API.
+ _setAttributes: function(attributes) {
+ this.$el.attr(attributes);
+ }
+
+});
+
+// setup inheritance
+View.extend = extend;
+module.exports = View;
+
+},{"backbone-events-standalone":12,"backbone-extend-standalone":13,"jbone":50,"underscore":59}],11:[function(require,module,exports){
+module.exports=require(7)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/backbone-thin/node_modules/backbone-events-standalone/backbone-events-standalone.js":7}],12:[function(require,module,exports){
+module.exports=require(8)
+},{"./backbone-events-standalone":11,"/home/travis/build/greenify/biojs-vis-msa/node_modules/backbone-thin/node_modules/backbone-events-standalone/index.js":8}],13:[function(require,module,exports){
+module.exports=require(9)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/backbone-thin/node_modules/backbone-extend-standalone/backbone-extend-standalone.js":9}],14:[function(require,module,exports){
+var events = require("backbone-events-standalone");
+
+events.onAll = function(callback,context){
+ this.on("all", callback,context);
+ return this;
+};
+
+// Mixin utility
+events.oldMixin = events.mixin;
+events.mixin = function(proto) {
+ events.oldMixin(proto);
+ // add custom onAll
+ var exports = ['onAll'];
+ for(var i=0; i < exports.length;i++){
+ var name = exports[i];
+ proto[name] = this[name];
+ }
+ return proto;
+};
+
+module.exports = events;
+
+},{"backbone-events-standalone":16}],15:[function(require,module,exports){
+module.exports=require(7)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/backbone-thin/node_modules/backbone-events-standalone/backbone-events-standalone.js":7}],16:[function(require,module,exports){
+module.exports=require(8)
+},{"./backbone-events-standalone":15,"/home/travis/build/greenify/biojs-vis-msa/node_modules/backbone-thin/node_modules/backbone-events-standalone/index.js":8}],17:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var GenericReader, xhr;
+
+xhr = require('nets');
+
+module.exports = GenericReader = (function() {
+ function GenericReader() {}
+
+ GenericReader.read = function(url, callback) {
+ var onret;
+ onret = (function(_this) {
+ return function(err, response, text) {
+ return _this._onRetrieval(text, callback);
+ };
+ })(this);
+ return xhr(url, onret);
+ };
+
+ GenericReader._onRetrieval = function(text, callback) {
+ var rText;
+ rText = this.parse(text);
+ return callback(rText);
+ };
+
+ return GenericReader;
+
+})();
+
+},{"nets":undefined}],18:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var Seq;
+
+module.exports = Seq = (function() {
+ function Seq(seq, name, id) {
+ var meta;
+ this.seq = seq;
+ this.name = name;
+ this.id = id;
+ meta = {};
+ }
+
+ return Seq;
+
+})();
+
+},{}],19:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var strings;
+
+strings = {
+ contains: function(text, search) {
+ return ''.indexOf.call(text, search, 0) !== -1;
+ }
+};
+
+module.exports = strings;
+
+},{}],20:[function(require,module,exports){
+module.exports=require(17)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/biojs-io-clustal/lib/generic_reader.js":17,"nets":undefined}],21:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var Fasta, GenericReader, Seq, Str,
+ __hasProp = {}.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
+
+Str = require("./strings");
+
+GenericReader = require("./generic_reader");
+
+Seq = require("biojs-model").seq;
+
+module.exports = Fasta = (function(_super) {
+ __extends(Fasta, _super);
+
+ function Fasta() {
+ return Fasta.__super__.constructor.apply(this, arguments);
+ }
+
+ Fasta.parse = function(text) {
+ var currentSeq, database, databaseID, identifiers, k, label, line, seqs, _i, _len;
+ seqs = [];
+ if (Object.prototype.toString.call(text) !== '[object Array]') {
+ text = text.split("\n");
+ }
+ for (_i = 0, _len = text.length; _i < _len; _i++) {
+ line = text[_i];
+ if (line[0] === ">" || line[0] === ";") {
+ label = line.slice(1);
+ currentSeq = new Seq("", label, seqs.length);
+ seqs.push(currentSeq);
+ if (Str.contains("|", line)) {
+ identifiers = label.split("|");
+ k = 1;
+ while (k < identifiers.length) {
+ database = identifiers[k];
+ databaseID = identifiers[k + 1];
+ currentSeq.meta[database] = databaseID;
+ k += 2;
+ }
+ currentSeq.name = identifiers[identifiers.length - 1];
+ }
+ } else {
+ currentSeq.seq += line;
+ }
+ }
+ return seqs;
+ };
+
+ return Fasta;
+
+})(GenericReader);
+
+},{"./generic_reader":20,"./strings":22,"biojs-model":25}],22:[function(require,module,exports){
+module.exports=require(19)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/biojs-io-clustal/lib/strings.js":19}],23:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var Utils;
+
+Utils = {};
+
+Utils.splitNChars = function(txt, num) {
+ var i, result, _i, _ref;
+ result = [];
+ for (i = _i = 0, _ref = txt.length - 1; num > 0 ? _i <= _ref : _i >= _ref; i = _i += num) {
+ result.push(txt.substr(i, num));
+ }
+ return result;
+};
+
+module.exports = Utils;
+
+},{}],24:[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var FastaExporter, Utils;
+
+Utils = require("./utils");
+
+module.exports = FastaExporter = (function() {
+ function FastaExporter() {}
+
+ FastaExporter["export"] = function(seqs, access) {
+ var seq, text, _i, _len;
+ text = "";
+ for (_i = 0, _len = seqs.length; _i < _len; _i++) {
+ seq = seqs[_i];
+ if (access != null) {
+ seq = access(seq);
+ }
+ text += ">" + seq.name + "\n";
+ text += (Utils.splitNChars(seq.seq, 80)).join("\n");
+ text += "\n";
+ }
+ return text;
+ };
+
+ return FastaExporter;
+
+})();
+
+},{"./utils":23}],25:[function(require,module,exports){
+module.exports.seq = require("./seq");
+
+},{"./seq":26}],26:[function(require,module,exports){
+module.exports = function(seq, name, id) {
+ this.seq = seq;
+ this.name = name;
+ this.id = id;
+ this.meta = {};
+};
+
+},{}],27:[function(require,module,exports){
+module.exports=require(25)
+},{"./seq":28,"/home/travis/build/greenify/biojs-vis-msa/node_modules/biojs-io-fasta/node_modules/biojs-model/src/index.js":25}],28:[function(require,module,exports){
+module.exports=require(26)
+},{"/home/travis/build/greenify/biojs-vis-msa/node_modules/biojs-io-fasta/node_modules/biojs-model/src/seq.js":26}],29:[function(require,module,exports){
+module.exports = require('./src/index.js')
+
+},{"./src/index.js":36}],30:[function(require,module,exports){
+module.exports = {
+ A: "#00a35c",
+ R: "#00fc03",
+ N: "#00eb14",
+ D: "#00eb14",
+ C: "#0000ff",
+ Q: "#00f10e",
+ E: "#00f10e",
+ G: "#009d62",
+ H: "#00d52a",
+ I: "#0054ab",
+ L: "#007b84",
+ K: "#00ff00",
+ M: "#009768",
+ F: "#008778",
+ P: "#00e01f",
+ S: "#00d52a",
+ T: "#00db24",
+ W: "#00a857",
+ Y: "#00e619",
+ V: "#005fa0",
+ B: "#00eb14",
+ X: "#00b649",
+ Z: "#00f10e"
+};
+
+},{}],31:[function(require,module,exports){
+module.exports = {
+ A: "#BBBBBB",
+ B: "grey",
+ C: "yellow",
+ D: "red",
+ E: "red",
+ F: "magenta",
+ G: "brown",
+ H: "#00FFFF",
+ I: "#BBBBBB",
+ J: "#fff",
+ K: "#00FFFF",
+ L: "#BBBBBB",
+ M: "#BBBBBB",
+ N: "green",
+ O: "#fff",
+ P: "brown",
+ Q: "green",
+ R: "#00FFFF",
+ S: "green",
+ T: "green",
+ U: "#fff",
+ V: "#BBBBBB",
+ W: "magenta",
+ X: "grey",
+ Y: "magenta",
+ Z: "grey",
+ Gap: "grey"
+};
+
+},{}],32:[function(require,module,exports){
+module.exports = {
+ A: "orange",
+ B: "#fff",
+ C: "green",
+ D: "red",
+ E: "red",
+ F: "blue",
+ G: "orange",
+ H: "red",
+ I: "green",
+ J: "#fff",
+ K: "red",
+ L: "green",
+ M: "green",
+ N: "#fff",
+ O: "#fff",
+ P: "orange",
+ Q: "#fff",
+ R: "red",
+ S: "orange",
+ T: "orange",
+ U: "#fff",
+ V: "green",
+ W: "blue",
+ X: "#fff",
+ Y: "blue",
+ Z: "#fff",
+ Gap: "#fff"
+};
+
+},{}],33:[function(require,module,exports){
+module.exports = {
+ A: "#80a0f0",
+ R: "#f01505",
+ N: "#00ff00",
+ D: "#c048c0",
+ C: "#f08080",
+ Q: "#00ff00",
+ E: "#c048c0",
+ G: "#f09048",
+ H: "#15a4a4",
+ I: "#80a0f0",
+ L: "#80a0f0",
+ K: "#f01505",
+ M: "#80a0f0",
+ F: "#80a0f0",
+ P: "#ffff00",
+ S: "#00ff00",
+ T: "#00ff00",
+ W: "#80a0f0",
+ Y: "#15a4a4",
+ V: "#80a0f0",
+ B: "#fff",
+ X: "#fff",
+ Z: "#fff"
+};
+
+},{}],34:[function(require,module,exports){
+module.exports = {
+ A: "#e718e7",
+ R: "#6f906f",
+ N: "#1be41b",
+ D: "#778877",
+ C: "#23dc23",
+ Q: "#926d92",
+ E: "#ff00ff",
+ G: "#00ff00",
+ H: "#758a75",
+ I: "#8a758a",
+ L: "#ae51ae",
+ K: "#a05fa0",
+ M: "#ef10ef",
+ F: "#986798",
+ P: "#00ff00",
+ S: "#36c936",
+ T: "#47b847",
+ W: "#8a758a",
+ Y: "#21de21",
+ V: "#857a85",
+ B: "#49b649",
+ X: "#758a75",
+ Z: "#c936c9"
+};
+
+},{}],35:[function(require,module,exports){
+module.exports = {
+ A: "#ad0052",
+ B: "#0c00f3",
+ C: "#c2003d",
+ D: "#0c00f3",
+ E: "#0c00f3",
+ F: "#cb0034",
+ G: "#6a0095",
+ H: "#1500ea",
+ I: "#ff0000",
+ J: "#fff",
+ K: "#0000ff",
+ L: "#ea0015",
+ M: "#b0004f",
+ N: "#0c00f3",
+ O: "#fff",
+ P: "#4600b9",
+ Q: "#0c00f3",
+ R: "#0000ff",
+ S: "#5e00a1",
+ T: "#61009e",
+ U: "#fff",
+ V: "#f60009",
+ W: "#5b00a4",
+ X: "#680097",
+ Y: "#4f00b0",
+ Z: "#0c00f3"
+};
+
+},{}],36:[function(require,module,exports){
+module.exports.selector = require("./selector");
+
+// basics
+module.exports.taylor = require("./taylor");
+module.exports.zappo= require("./zappo");
+module.exports.hydro= require("./hydrophobicity");
+
+module.exports.clustal = require("./clustal");
+module.exports.clustal2 = require("./clustal2");
+
+module.exports.curied = require("./buried");
+module.exports.cinema = require("./cinema");
+module.exports.nucleotide = require("./nucleotide");
+module.exports.helix = require("./helix");
+module.exports.lesk = require("./lesk");
+module.exports.mae = require("./mae");
+module.exports.purine = require("./purine");
+module.exports.strand = require("./strand");
+module.exports.turn = require("./turn");
+
+},{"./buried":30,"./cinema":31,"./clustal":32,"./clustal2":33,"./helix":34,"./hydrophobicity":35,"./lesk":37,"./mae":38,"./nucleotide":39,"./purine":40,"./selector":41,"./strand":42,"./taylor":43,"./turn":44,"./zappo":45}],37:[function(require,module,exports){
+module.exports = {
+ A: " orange",
+ B: " #fff",
+ C: " green",
+ D: " red",
+ E: " red",
+ F: " green",
+ G: " orange",
+ H: " magenta",
+ I: " green",
+ J: " #fff",
+ K: " red",
+ L: " green",
+ M: " green",
+ N: " magenta",
+ O: " #fff",
+ P: " green",
+ Q: " magenta",
+ R: " red",
+ S: " orange",
+ T: " orange",
+ U: " #fff",
+ V: " green",
+ W: " green",
+ X: " #fff",
+ Y: " green",
+ Z: " #fff",
+ Gap: " #fff"
+};
+
+},{}],38:[function(require,module,exports){
+module.exports = {
+ A: " #77dd88",
+ B: " #fff",
+ C: " #99ee66",
+ D: " #55bb33",
+ E: " #55bb33",
+ F: " #9999ff",
+ G: " #77dd88",
+ H: " #5555ff",
+ I: " #66bbff",
+ J: " #fff",
+ K: " #ffcc77",
+ L: " #66bbff",
+ M: " #66bbff",
+ N: " #55bb33",
+ O: " #fff",
+ P: " #eeaaaa",
+ Q: " #55bb33",
+ R: " #ffcc77",
+ S: " #ff4455",
+ T: " #ff4455",
+ U: " #fff",
+ V: " #66bbff",
+ W: " #9999ff",
+ X: " #fff",
+ Y: " #9999ff",
+ Z: " #fff",
+ Gap: " #fff"
+};
+
+},{}],39:[function(require,module,exports){
+module.exports = {
+ A: " #64F73F",
+ C: " #FFB340",
+ G: " #EB413C",
+ T: " #3C88EE",
+ U: " #3C88EE"
+};
+
+},{}],40:[function(require,module,exports){
+module.exports = {
+ A: " #FF83FA",
+ C: " #40E0D0",
+ G: " #FF83FA",
+ R: " #FF83FA",
+ T: " #40E0D0",
+ U: " #40E0D0",
+ Y: " #40E0D0"
+};
+
+},{}],41:[function(require,module,exports){
+var Buried = require("./buried");
+var Cinema = require("./cinema");
+var Clustal = require("./clustal");
+var Clustal2 = require("./clustal2");
+var Helix = require("./helix");
+var Hydro = require("./hydrophobicity");
+var Lesk = require("./lesk");
+var Mae = require("./mae");
+var Nucleotide = require("./nucleotide");
+var Purine = require("./purine");
+var Strand = require("./strand");
+var Taylor = require("./taylor");
+var Turn = require("./turn");
+var Zappo = require("./zappo");
+
+module.exports = Colors = {
+ mapping: {
+ buried: Buried,
+ buried_index: Buried,
+ cinema: Cinema,
+ clustal2: Clustal2,
+ clustal: Clustal,
+ helix: Helix,
+ helix_propensity: Helix,
+ hydro: Hydro,
+ lesk: Lesk,
+ mae: Mae,
+ nucleotide: Nucleotide,
+ purine: Purine,
+ purine_pyrimidine: Purine,
+ strand: Strand,
+ strand_propensity: Strand,
+ taylor: Taylor,
+ turn: Turn,
+ turn_propensity: Turn,
+ zappo: Zappo,
+ },
+ getColor: function(scheme) {
+ var color = Colors.mapping[scheme];
+ if (color === undefined) {
+ color = {};
+ }
+ return color;
+ }
+};
+
+},{"./buried":30,"./cinema":31,"./clustal":32,"./clustal2":33,"./helix":34,"./hydrophobicity":35,"./lesk":37,"./mae":38,"./nucleotide":39,"./purine":40,"./strand":42,"./taylor":43,"./turn":44,"./zappo":45}],42:[function(require,module,exports){
+module.exports = {
+ A: "#5858a7",
+ R: "#6b6b94",
+ N: "#64649b",
+ D: "#2121de",
+ C: "#9d9d62",
+ Q: "#8c8c73",
+ E: "#0000ff",
+ G: "#4949b6",
+ H: "#60609f",
+ I: "#ecec13",
+ L: "#b2b24d",
+ K: "#4747b8",
+ M: "#82827d",
+ F: "#c2c23d",
+ P: "#2323dc",
+ S: "#4949b6",
+ T: "#9d9d62",
+ W: "#c0c03f",
+ Y: "#d3d32c",
+ V: "#ffff00",
+ B: "#4343bc",
+ X: "#797986",
+ Z: "#4747b8"
+};
+
+},{}],43:[function(require,module,exports){
+module.exports = {
+ A: "#ccff00",
+ R: "#0000ff",
+ N: "#cc00ff",
+ D: "#ff0000",
+ C: "#ffff00",
+ Q: "#ff00cc",
+ E: "#ff0066",
+ G: "#ff9900",
+ H: "#0066ff",
+ I: "#66ff00",
+ L: "#33ff00",
+ K: "#6600ff",
+ M: "#00ff00",
+ F: "#00ff66",
+ P: "#ffcc00",
+ S: "#ff3300",
+ T: "#ff6600",
+ W: "#00ccff",
+ Y: "#00ffcc",
+ V: "#99ff00",
+ B: "#fff",
+ X: "#fff",
+ Z: "#fff"
+};
+
+},{}],44:[function(require,module,exports){
+module.exports = {
+ A: "#2cd3d3",
+ R: "#708f8f",
+ N: "#ff0000",
+ D: "#e81717",
+ C: "#a85757",
+ Q: "#3fc0c0",
+ E: "#778888",
+ G: "#ff0000",
+ H: "#708f8f",
+ I: "#00ffff",
+ L: "#1ce3e3",
+ K: "#7e8181",
+ M: "#1ee1e1",
+ F: "#1ee1e1",
+ P: "#f60909",
+ S: "#e11e1e",
+ T: "#738c8c",
+ W: "#738c8c",
+ Y: "#9d6262",
+ V: "#07f8f8",
+ B: "#f30c0c",
+ X: "#7c8383",
+ Z: "#5ba4a4"
+};
+
+},{}],45:[function(require,module,exports){
+module.exports = {
+ A: "#ffafaf",
+ R: "#6464ff",
+ N: "#00ff00",
+ D: "#ff0000",
+ C: "#ffff00",
+ Q: "#00ff00",
+ E: "#ff0000",
+ G: "#ff00ff",
+ H: "#6464ff",
+ I: "#ffafaf",
+ L: "#ffafaf",
+ K: "#6464ff",
+ M: "#ffafaf",
+ F: "#ffc800",
+ P: "#ff00ff",
+ S: "#00ff00",
+ T: "#00ff00",
+ W: "#ffc800",
+ Y: "#ffc800",
+ V: "#ffafaf",
+ B: "#fff",
+ X: "#fff",
+ Z: "#fff"
+};
+
+},{}],46:[function(require,module,exports){
+/*
+ * JavaScript Canvas to Blob 2.0.5
+ * https://github.com/blueimp/JavaScript-Canvas-to-Blob
+ *
+ * Copyright 2012, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ *
+ * Based on stackoverflow user Stoive's code snippet:
+ * http://stackoverflow.com/q/4998908
+ */
+var CanvasPrototype = window.HTMLCanvasElement &&
+window.HTMLCanvasElement.prototype,
+ hasBlobConstructor = window.Blob && (function () {
+ try {
+ return Boolean(new Blob());
+ } catch (e) {
+ return false;
+ }
+ }()),
+ hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&
+ (function () {
+ try {
+ return new Blob([new Uint8Array(100)]).size === 100;
+ } catch (e) {
+ return false;
+ }
+ }()),
+ BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||
+ window.MozBlobBuilder || window.MSBlobBuilder,
+ dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&
+ window.ArrayBuffer && window.Uint8Array && function (dataURI) {
+ var byteString,
+ arrayBuffer,
+ intArray,
+ i,
+ mimeString,
+ bb;
+ if (dataURI.split(',')[0].indexOf('base64') >= 0) {
+ // Convert base64 to raw binary data held in a string:
+ byteString = atob(dataURI.split(',')[1]);
+ } else {
+ // Convert base64/URLEncoded data component to raw binary data:
+ byteString = decodeURIComponent(dataURI.split(',')[1]);
+ }
+ // Write the bytes of the string to an ArrayBuffer:
+ arrayBuffer = new ArrayBuffer(byteString.length);
+ intArray = new Uint8Array(arrayBuffer);
+ for (i = 0; i < byteString.length; i += 1) {
+ intArray[i] = byteString.charCodeAt(i);
+ }
+ // Separate out the mime component:
+ mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
+ // Write the ArrayBuffer (or ArrayBufferView) to a blob:
+ if (hasBlobConstructor) {
+ return new Blob(
+ [hasArrayBufferViewSupport ? intArray : arrayBuffer],
+ {type: mimeString}
+ );
+ }
+ bb = new BlobBuilder();
+ bb.append(arrayBuffer);
+ return bb.getBlob(mimeString);
+ };
+if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {
+ if (CanvasPrototype.mozGetAsFile) {
+ CanvasPrototype.toBlob = function (callback, type, quality) {
+ if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {
+ callback(dataURLtoBlob(this.toDataURL(type, quality)));
+ } else {
+ callback(this.mozGetAsFile('blob', type));
+ }
+ };
+ } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {
+ CanvasPrototype.toBlob = function (callback, type, quality) {
+ callback(dataURLtoBlob(this.toDataURL(type, quality)));
+ };
+ }
+}
+
+module.exports = dataURLtoBlob;
+
+},{}],47:[function(require,module,exports){
+/* FileSaver.js
+ * A saveAs() FileSaver implementation.
+ * 2014-05-27
+ *
+ * By Eli Grey, http://eligrey.com
+ * License: X11/MIT
+ * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
+ */
+
+/*global self */
+/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
+
+/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
+
+var saveAs = saveAs
+ // IE 10+ (native saveAs)
+ || (typeof navigator !== "undefined" &&
+ navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))
+ // Everyone else
+ || (function(view) {
+ "use strict";
+ // IE <10 is explicitly unsupported
+ if (typeof navigator !== "undefined" &&
+ /MSIE [1-9]\./.test(navigator.userAgent)) {
+ return;
+ }
+ var
+ doc = view.document
+ // only get URL when necessary in case Blob.js hasn't overridden it yet
+ , get_URL = function() {
+ return view.URL || view.webkitURL || view;
+ }
+ , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
+ , can_use_save_link = !view.externalHost && "download" in save_link
+ , click = function(node) {
+ var event = doc.createEvent("MouseEvents");
+ event.initMouseEvent(
+ "click", true, false, view, 0, 0, 0, 0, 0
+ , false, false, false, false, 0, null
+ );
+ node.dispatchEvent(event);
+ }
+ , webkit_req_fs = view.webkitRequestFileSystem
+ , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
+ , throw_outside = function(ex) {
+ (view.setImmediate || view.setTimeout)(function() {
+ throw ex;
+ }, 0);
+ }
+ , force_saveable_type = "application/octet-stream"
+ , fs_min_size = 0
+ , deletion_queue = []
+ , process_deletion_queue = function() {
+ var i = deletion_queue.length;
+ while (i--) {
+ var file = deletion_queue[i];
+ if (typeof file === "string") { // file is an object URL
+ get_URL().revokeObjectURL(file);
+ } else { // file is a File
+ file.remove();
+ }
+ }
+ deletion_queue.length = 0; // clear queue
+ }
+ , dispatch = function(filesaver, event_types, event) {
+ event_types = [].concat(event_types);
+ var i = event_types.length;
+ while (i--) {
+ var listener = filesaver["on" + event_types[i]];
+ if (typeof listener === "function") {
+ try {
+ listener.call(filesaver, event || filesaver);
+ } catch (ex) {
+ throw_outside(ex);
+ }
+ }
+ }
+ }
+ , FileSaver = function(blob, name) {
+ // First try a.download, then web filesystem, then object URLs
+ var
+ filesaver = this
+ , type = blob.type
+ , blob_changed = false
+ , object_url
+ , target_view
+ , get_object_url = function() {
+ var object_url = get_URL().createObjectURL(blob);
+ deletion_queue.push(object_url);
+ return object_url;
+ }
+ , dispatch_all = function() {
+ dispatch(filesaver, "writestart progress write writeend".split(" "));
+ }
+ // on any filesys errors revert to saving with object URLs
+ , fs_error = function() {
+ // don't create more object URLs than needed
+ if (blob_changed || !object_url) {
+ object_url = get_object_url(blob);
+ }
+ if (target_view) {
+ target_view.location.href = object_url;
+ } else {
+ window.open(object_url, "_blank");
+ }
+ filesaver.readyState = filesaver.DONE;
+ dispatch_all();
+ }
+ , abortable = function(func) {
+ return function() {
+ if (filesaver.readyState !== filesaver.DONE) {
+ return func.apply(this, arguments);
+ }
+ };
+ }
+ , create_if_not_found = {create: true, exclusive: false}
+ , slice
+ ;
+ filesaver.readyState = filesaver.INIT;
+ if (!name) {
+ name = "download";
+ }
+ if (can_use_save_link) {
+ object_url = get_object_url(blob);
+ save_link.href = object_url;
+ save_link.download = name;
+ click(save_link);
+ filesaver.readyState = filesaver.DONE;
+ dispatch_all();
+ return;
+ }
+ // Object and web filesystem URLs have a problem saving in Google Chrome when
+ // viewed in a tab, so I force save with application/octet-stream
+ // http://code.google.com/p/chromium/issues/detail?id=91158
+ if (view.chrome && type && type !== force_saveable_type) {
+ slice = blob.slice || blob.webkitSlice;
+ blob = slice.call(blob, 0, blob.size, force_saveable_type);
+ blob_changed = true;
+ }
+ // Since I can't be sure that the guessed media type will trigger a download
+ // in WebKit, I append .download to the filename.
+ // https://bugs.webkit.org/show_bug.cgi?id=65440
+ if (webkit_req_fs && name !== "download") {
+ name += ".download";
+ }
+ if (type === force_saveable_type || webkit_req_fs) {
+ target_view = view;
+ }
+ if (!req_fs) {
+ fs_error();
+ return;
+ }
+ fs_min_size += blob.size;
+ req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
+ fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
+ var save = function() {
+ dir.getFile(name, create_if_not_found, abortable(function(file) {
+ file.createWriter(abortable(function(writer) {
+ writer.onwriteend = function(event) {
+ target_view.location.href = file.toURL();
+ deletion_queue.push(file);
+ filesaver.readyState = filesaver.DONE;
+ dispatch(filesaver, "writeend", event);
+ };
+ writer.onerror = function() {
+ var error = writer.error;
+ if (error.code !== error.ABORT_ERR) {
+ fs_error();
+ }
+ };
+ "writestart progress write abort".split(" ").forEach(function(event) {
+ writer["on" + event] = filesaver["on" + event];
+ });
+ writer.write(blob);
+ filesaver.abort = function() {
+ writer.abort();
+ filesaver.readyState = filesaver.DONE;
+ };
+ filesaver.readyState = filesaver.WRITING;
+ }), fs_error);
+ }), fs_error);
+ };
+ dir.getFile(name, {create: false}, abortable(function(file) {
+ // delete file if it already exists
+ file.remove();
+ save();
+ }), abortable(function(ex) {
+ if (ex.code === ex.NOT_FOUND_ERR) {
+ save();
+ } else {
+ fs_error();
+ }
+ }));
+ }), fs_error);
+ }), fs_error);
+ }
+ , FS_proto = FileSaver.prototype
+ , saveAs = function(blob, name) {
+ return new FileSaver(blob, name);
+ }
+ ;
+ FS_proto.abort = function() {
+ var filesaver = this;
+ filesaver.readyState = filesaver.DONE;
+ dispatch(filesaver, "abort");
+ };
+ FS_proto.readyState = FS_proto.INIT = 0;
+ FS_proto.WRITING = 1;
+ FS_proto.DONE = 2;
+
+ FS_proto.error =
+ FS_proto.onwritestart =
+ FS_proto.onprogress =
+ FS_proto.onwrite =
+ FS_proto.onabort =
+ FS_proto.onerror =
+ FS_proto.onwriteend =
+ null;
+
+ view.addEventListener("unload", process_deletion_queue, false);
+ saveAs.unload = function() {
+ process_deletion_queue();
+ view.removeEventListener("unload", process_deletion_queue, false);
+ };
+ return saveAs;
+}(
+ typeof self !== "undefined" && self
+ || typeof window !== "undefined" && window
+ || this.content
+));
+// `self` is undefined in Firefox for Android content script context
+// while `this` is nsIContentFrameMessageManager
+// with an attribute `content` that corresponds to the window
+
+amdDefine = window.define;
+if( typeof amdDefine === "undefined" && (typeof window.almond !== "undefined"
+ && "define" in window.almond )){
+ amdDefine = window.almond.define;
+}
+
+if (typeof module !== "undefined" && module !== null) {
+ module.exports = saveAs;
+} else if ((typeof amdDefine !== "undefined" && amdDefine !== null) && (amdDefine.amd != null)) {
+ amdDefine("saveAs",[], function() {
+ return saveAs;
+ });
+}
+
+},{}],48:[function(require,module,exports){
+module.exports = function (css, customDocument) {
+ var doc = customDocument || document;
+ if (doc.createStyleSheet) {
+ var sheet = doc.createStyleSheet()
+ sheet.cssText = css;
+ return sheet.ownerNode;
+ } else {
+ var head = doc.getElementsByTagName('head')[0],
+ style = doc.createElement('style');
+
+ style.type = 'text/css';
+
+ if (style.styleSheet) {
+ style.styleSheet.cssText = css;
+ } else {
+ style.appendChild(doc.createTextNode(css));
+ }
+
+ head.appendChild(style);
+ return style;
+ }
+};
+
+module.exports.byUrl = function(url) {
+ if (document.createStyleSheet) {
+ return document.createStyleSheet(url).ownerNode;
+ } else {
+ var head = document.getElementsByTagName('head')[0],
+ link = document.createElement('link');
+
+ link.rel = 'stylesheet';
+ link.href = url;
+
+ head.appendChild(link);
+ return link;
+ }
+};
+
+},{}],49:[function(require,module,exports){
+var Utils = {};
+
+
+/*
+Remove an element and provide a function that inserts it into its original position
+https://developers.google.com/speed/articles/javascript-dom
+@param element {Element} The element to be temporarily removed
+@return {Function} A function that inserts the element into its original position
+ */
+
+Utils.removeToInsertLater = function(element) {
+ var nextSibling, parentNode;
+ parentNode = element.parentNode;
+ nextSibling = element.nextSibling;
+ parentNode.removeChild(element);
+ return function() {
+ if (nextSibling) {
+ parentNode.insertBefore(element, nextSibling);
+ } else {
+ parentNode.appendChild(element);
+ }
+ };
+};
+
+
+/*
+fastest possible way to destroy all sub nodes (aka childs)
+http://jsperf.com/innerhtml-vs-removechild/15
+@param element {Element} The element for which all childs should be removed
+ */
+
+Utils.removeAllChilds = function(element) {
+ var count;
+ count = 0;
+ while (element.firstChild) {
+ count++;
+ element.removeChild(element.firstChild);
+ }
+};
+
+module.exports = Utils;
+
+},{}],50:[function(require,module,exports){
+/*!
+ * jBone v1.0.19 - 2014-10-12 - Library for DOM manipulation
+ *
+ * https://github.com/kupriyanenko/jbone
+ *
+ * Copyright 2014 Alexey Kupriyanenko
+ * Released under the MIT license.
+ */
+
+(function (win) {
+
+var
+// cache previous versions
+_$ = win.$,
+_jBone = win.jBone,
+
+// Quick match a standalone tag
+rquickSingleTag = /^<(\w+)\s*\/?>$/,
+
+// A simple way to check for HTML strings
+// Prioritize #id over <tag> to avoid XSS via location.hash
+rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+// Alias for function
+slice = [].slice,
+splice = [].splice,
+keys = Object.keys,
+
+// Alias for global variables
+doc = document,
+
+isString = function(el) {
+ return typeof el === "string";
+},
+isObject = function(el) {
+ return el instanceof Object;
+},
+isFunction = function(el) {
+ var getType = {};
+ return el && getType.toString.call(el) === "[object Function]";
+},
+isArray = function(el) {
+ return Array.isArray(el);
+},
+jBone = function(element, data) {
+ return new fn.init(element, data);
+},
+fn;
+
+// set previous values and return the instance upon calling the no-conflict mode
+jBone.noConflict = function() {
+ win.$ = _$;
+ win.jBone = _jBone;
+
+ return jBone;
+};
+
+fn = jBone.fn = jBone.prototype = {
+ init: function(element, data) {
+ var elements, tag, wraper, fragment;
+
+ if (!element) {
+ return this;
+ }
+ if (isString(element)) {
+ // Create single DOM element
+ if (tag = rquickSingleTag.exec(element)) {
+ this[0] = doc.createElement(tag[1]);
+ this.length = 1;
+
+ if (isObject(data)) {
+ this.attr(data);
+ }
+
+ return this;
+ }
+ // Create DOM collection
+ if ((tag = rquickExpr.exec(element)) && tag[1]) {
+ fragment = doc.createDocumentFragment();
+ wraper = doc.createElement("div");
+ wraper.innerHTML = element;
+ while (wraper.lastChild) {
+ fragment.appendChild(wraper.firstChild);
+ }
+ elements = slice.call(fragment.childNodes);
+
+ return jBone.merge(this, elements);
+ }
+ // Find DOM elements with querySelectorAll
+ if (jBone.isElement(data)) {
+ return jBone(data).find(element);
+ }
+
+ try {
+ elements = doc.querySelectorAll(element);
+
+ return jBone.merge(this, elements);
+ } catch (e) {
+ return this;
+ }
+ }
+ // Wrap DOMElement
+ if (element.nodeType) {
+ this[0] = element;
+ this.length = 1;
+
+ return this;
+ }
+ // Run function
+ if (isFunction(element)) {
+ return element();
+ }
+ // Return jBone element as is
+ if (element instanceof jBone) {
+ return element;
+ }
+
+ // Return element wrapped by jBone
+ return jBone.makeArray(element, this);
+ },
+
+ pop: [].pop,
+ push: [].push,
+ reverse: [].reverse,
+ shift: [].shift,
+ sort: [].sort,
+ splice: [].splice,
+ slice: [].slice,
+ indexOf: [].indexOf,
+ forEach: [].forEach,
+ unshift: [].unshift,
+ concat: [].concat,
+ join: [].join,
+ every: [].every,
+ some: [].some,
+ filter: [].filter,
+ map: [].map,
+ reduce: [].reduce,
+ reduceRight: [].reduceRight,
+ length: 0
+};
+
+fn.constructor = jBone;
+
+fn.init.prototype = fn;
+
+jBone.setId = function(el) {
+ var jid = el.jid;
+
+ if (el === win) {
+ jid = "window";
+ } else if (el.jid === undefined) {
+ el.jid = jid = ++jBone._cache.jid;
+ }
+
+ if (!jBone._cache.events[jid]) {
+ jBone._cache.events[jid] = {};
+ }
+};
+
+jBone.getData = function(el) {
+ el = el instanceof jBone ? el[0] : el;
+
+ var jid = el === win ? "window" : el.jid;
+
+ return {
+ jid: jid,
+ events: jBone._cache.events[jid]
+ };
+};
+
+jBone.isElement = function(el) {
+ return el && el instanceof jBone || el instanceof HTMLElement || isString(el);
+};
+
+jBone._cache = {
+ events: {},
+ jid: 0
+};
+
+function isArraylike(obj) {
+ var length = obj.length,
+ type = typeof obj;
+
+ if (isFunction(type) || obj === win) {
+ return false;
+ }
+
+ if (obj.nodeType === 1 && length) {
+ return true;
+ }
+
+ return isArray(type) || length === 0 ||
+ typeof length === "number" && length > 0 && (length - 1) in obj;
+}
+
+jBone.merge = function(first, second) {
+ var l = second.length,
+ i = first.length,
+ j = 0;
+
+ while (j < l) {
+ first[i++] = second[j++];
+ }
+
+ first.length = i;
+
+ return first;
+};
+
+jBone.contains = function(container, contained) {
+ var result;
+
+ container.reverse().some(function(el) {
+ if (el.contains(contained)) {
+ return result = el;
+ }
+ });
+
+ return result;
+};
+
+jBone.extend = function(target) {
+ var k, kl, i, tg;
+
+ splice.call(arguments, 1).forEach(function(object) {
+ if (!object) {
+ return;
+ }
+
+ k = keys(object);
+ kl = k.length;
+ i = 0;
+ tg = target; //caching target for perf improvement
+
+ for (; i < kl; i++) {
+ tg[k[i]] = object[k[i]];
+ }
+ });
+
+ return target;
+};
+
+jBone.makeArray = function(arr, results) {
+ var ret = results || [];
+
+ if (arr !== null) {
+ if (isArraylike(arr)) {
+ jBone.merge(ret, isString(arr) ? [arr] : arr);
+ } else {
+ ret.push(arr);
+ }
+ }
+
+ return ret;
+};
+
+function BoneEvent(e, data) {
+ var key, setter;
+
+ this.originalEvent = e;
+
+ setter = function(key, e) {
+ if (key === "preventDefault") {
+ this[key] = function() {
+ this.defaultPrevented = true;
+ return e[key]();
+ };
+ } else if (isFunction(e[key])) {
+ this[key] = function() {
+ return e[key]();
+ };
+ } else {
+ this[key] = e[key];
+ }
+ };
+
+ for (key in e) {
+ if (e[key] || typeof e[key] === "function") {
+ setter.call(this, key, e);
+ }
+ }
+
+ jBone.extend(this, data);
+}
+
+jBone.Event = function(event, data) {
+ var namespace, eventType;
+
+ if (event.type && !data) {
+ data = event;
+ event = event.type;
+ }
+
+ namespace = event.split(".").splice(1).join(".");
+ eventType = event.split(".")[0];
+
+ event = doc.createEvent("Event");
+ event.initEvent(eventType, true, true);
+
+ return jBone.extend(event, {
+ namespace: namespace,
+ isDefaultPrevented: function() {
+ return event.defaultPrevented;
+ }
+ }, data);
+};
+
+fn.on = function(event) {
+ var args = arguments,
+ length = this.length,
+ i = 0,
+ callback, target, namespace, fn, events, eventType, expectedTarget, addListener;
+
+ if (args.length === 2) {
+ callback = args[1];
+ } else {
+ target = args[1];
+ callback = args[2];
+ }
+
+ addListener = function(el) {
+ jBone.setId(el);
+ events = jBone.getData(el).events;
+ event.split(" ").forEach(function(event) {
+ eventType = event.split(".")[0];
+ namespace = event.split(".").splice(1).join(".");
+ events[eventType] = events[eventType] || [];
+
+ fn = function(e) {
+ if (e.namespace && e.namespace !== namespace) {
+ return;
+ }
+
+ expectedTarget = null;
+ if (!target) {
+ callback.call(el, e);
+ } else if (~jBone(el).find(target).indexOf(e.target) || (expectedTarget = jBone.contains(jBone(el).find(target), e.target))) {
+ expectedTarget = expectedTarget || e.target;
+ e = new BoneEvent(e, {
+ currentTarget: expectedTarget
+ });
+
+ callback.call(expectedTarget, e);
+ }
+ };
+
+ events[eventType].push({
+ namespace: namespace,
+ fn: fn,
+ originfn: callback
+ });
+
+ el.addEventListener && el.addEventListener(eventType, fn, false);
+ });
+ };
+
+ for (; i < length; i++) {
+ addListener(this[i]);
+ }
+
+ return this;
+};
+
+fn.one = function(event) {
+ var args = arguments,
+ i = 0,
+ length = this.length,
+ callback, target, addListener;
+
+ if (args.length === 2) {
+ callback = args[1];
+ } else {
+ target = args[1], callback = args[2];
+ }
+
+ addListener = function(el) {
+ event.split(" ").forEach(function(event) {
+ var fn = function(e) {
+ jBone(el).off(event, fn);
+ callback.call(el, e);
+ };
+
+ if (!target) {
+ jBone(el).on(event, fn);
+ } else {
+ jBone(el).on(event, target, fn);
+ }
+ });
+ };
+
+ for (; i < length; i++) {
+ addListener(this[i]);
+ }
+
+ return this;
+};
+
+fn.trigger = function(event) {
+ var events = [],
+ i = 0,
+ length = this.length,
+ dispatchEvents;
+
+ if (!event) {
+ return this;
+ }
+
+ if (isString(event)) {
+ events = event.split(" ").map(function(event) {
+ return jBone.Event(event);
+ });
+ } else {
+ event = event instanceof Event ? event : jBone.Event(event);
+ events = [event];
+ }
+
+ dispatchEvents = function(el) {
+ events.forEach(function(event) {
+ if (!event.type) {
+ return;
+ }
+
+ el.dispatchEvent && el.dispatchEvent(event);
+ });
+ };
+
+ for (; i < length; i++) {
+ dispatchEvents(this[i]);
+ }
+
+ return this;
+};
+
+fn.off = function(event, fn) {
+ var i = 0,
+ length = this.length,
+ removeListener = function(events, eventType, index, el, e) {
+ var callback;
+
+ // get callback
+ if ((fn && e.originfn === fn) || !fn) {
+ callback = e.fn;
+ }
+
+ if (events[eventType][index].fn === callback) {
+ el.removeEventListener(eventType, callback);
+
+ // remove handler from cache
+ jBone._cache.events[jBone.getData(el).jid][eventType].splice(index, 1);
+ }
+ },
+ events, namespace, removeListeners, eventType;
+
+ removeListeners = function(el) {
+ var l, eventsByType, e;
+
+ events = jBone.getData(el).events;
+
+ if (!events) {
+ return;
+ }
+
+ // remove all events
+ if (!event && events) {
+ return keys(events).forEach(function(eventType) {
+ eventsByType = events[eventType];
+ l = eventsByType.length;
+
+ while(l--) {
+ removeListener(events, eventType, l, el, eventsByType[l]);
+ }
+ });
+ }
+
+ event.split(" ").forEach(function(event) {
+ eventType = event.split(".")[0];
+ namespace = event.split(".").splice(1).join(".");
+
+ // remove named events
+ if (events[eventType]) {
+ eventsByType = events[eventType];
+ l = eventsByType.length;
+
+ while(l--) {
+ e = eventsByType[l];
+ if (!namespace || (namespace && e.namespace === namespace)) {
+ removeListener(events, eventType, l, el, e);
+ }
+ }
+ }
+ // remove all namespaced events
+ else if (namespace) {
+ keys(events).forEach(function(eventType) {
+ eventsByType = events[eventType];
+ l = eventsByType.length;
+
+ while(l--) {
+ e = eventsByType[l];
+ if (e.namespace.split(".")[0] === namespace.split(".")[0]) {
+ removeListener(events, eventType, l, el, e);
+ }
+ }
+ });
+ }
+ });
+ };
+
+ for (; i < length; i++) {
+ removeListeners(this[i]);
+ }
+
+ return this;
+};
+
+fn.find = function(selector) {
+ var results = [],
+ i = 0,
+ length = this.length,
+ finder = function(el) {
+ if (isFunction(el.querySelectorAll)) {
+ [].forEach.call(el.querySelectorAll(selector), function(found) {
+ results.push(found);
+ });
+ }
+ };
+
+ for (; i < length; i++) {
+ finder(this[i]);
+ }
+
+ return jBone(results);
+};
+
+fn.get = function(index) {
+ return this[index];
+};
+
+fn.eq = function(index) {
+ return jBone(this[index]);
+};
+
+fn.parent = function() {
+ var results = [],
+ parent,
+ i = 0,
+ length = this.length;
+
+ for (; i < length; i++) {
+ if (!~results.indexOf(parent = this[i].parentElement) && parent) {
+ results.push(parent);
+ }
+ }
+
+ return jBone(results);
+};
+
+fn.toArray = function() {
+ return slice.call(this);
+};
+
+fn.is = function() {
+ var args = arguments;
+
+ return this.some(function(el) {
+ return el.tagName.toLowerCase() === args[0];
+ });
+};
+
+fn.has = function() {
+ var args = arguments;
+
+ return this.some(function(el) {
+ return el.querySelectorAll(args[0]).length;
+ });
+};
+
+fn.attr = function(key, value) {
+ var args = arguments,
+ i = 0,
+ length = this.length,
+ setter;
+
+ if (isString(key) && args.length === 1) {
+ return this[0] && this[0].getAttribute(key);
+ }
+
+ if (args.length === 2) {
+ setter = function(el) {
+ el.setAttribute(key, value);
+ };
+ } else if (isObject(key)) {
+ setter = function(el) {
+ keys(key).forEach(function(name) {
+ el.setAttribute(name, key[name]);
+ });
+ };
+ }
+
+ for (; i < length; i++) {
+ setter(this[i]);
+ }
+
+ return this;
+};
+
+fn.removeAttr = function(key) {
+ var i = 0,
+ length = this.length;
+
+ for (; i < length; i++) {
+ this[i].removeAttribute(key);
+ }
+
+ return this;
+};
+
+fn.val = function(value) {
+ var i = 0,
+ length = this.length;
+
+ if (arguments.length === 0) {
+ return this[0] && this[0].value;
+ }
+
+ for (; i < length; i++) {
+ this[i].value = value;
+ }
+
+ return this;
+};
+
+fn.css = function(key, value) {
+ var args = arguments,
+ i = 0,
+ length = this.length,
+ setter;
+
+ // Get attribute
+ if (isString(key) && args.length === 1) {
+ return this[0] && win.getComputedStyle(this[0])[key];
+ }
+
+ // Set attributes
+ if (args.length === 2) {
+ setter = function(el) {
+ el.style[key] = value;
+ };
+ } else if (isObject(key)) {
+ setter = function(el) {
+ keys(key).forEach(function(name) {
+ el.style[name] = key[name];
+ });
+ };
+ }
+
+ for (; i < length; i++) {
+ setter(this[i]);
+ }
+
+ return this;
+};
+
+fn.data = function(key, value) {
+ var args = arguments, data = {},
+ i = 0,
+ length = this.length,
+ setter,
+ setValue = function(el, key, value) {
+ if (isObject(value)) {
+ el.jdata = el.jdata || {};
+ el.jdata[key] = value;
+ } else {
+ el.dataset[key] = value;
+ }
+ },
+ getValue = function(value) {
+ if (value === "true") {
+ return true;
+ } else if (value === "false") {
+ return false;
+ } else {
+ return value;
+ }
+ };
+
+ // Get all data
+ if (args.length === 0) {
+ this[0].jdata && (data = this[0].jdata);
+
+ keys(this[0].dataset).forEach(function(key) {
+ data[key] = getValue(this[0].dataset[key]);
+ }, this);
+
+ return data;
+ }
+ // Get data by name
+ if (args.length === 1 && isString(key)) {
+ return this[0] && getValue(this[0].dataset[key] || this[0].jdata && this[0].jdata[key]);
+ }
+
+ // Set data
+ if (args.length === 1 && isObject(key)) {
+ setter = function(el) {
+ keys(key).forEach(function(name) {
+ setValue(el, name, key[name]);
+ });
+ };
+ } else if (args.length === 2) {
+ setter = function(el) {
+ setValue(el, key, value);
+ };
+ }
+
+ for (; i < length; i++) {
+ setter(this[i]);
+ }
+
+ return this;
+};
+
+fn.removeData = function(key) {
+ var i = 0,
+ length = this.length,
+ jdata, dataset;
+
+ for (; i < length; i++) {
+ jdata = this[i].jdata;
+ dataset = this[i].dataset;
+
+ if (key) {
+ jdata && jdata[key] && delete jdata[key];
+ delete dataset[key];
+ } else {
+ for (key in jdata) {
+ delete jdata[key];
+ }
+
+ for (key in dataset) {
+ delete dataset[key];
+ }
+ }
+ }
+
+ return this;
+};
+
+fn.html = function(value) {
+ var args = arguments,
+ el;
+
+ // add HTML into elements
+ if (args.length === 1 && value !== undefined) {
+ return this.empty().append(value);
+ }
+ // get HTML from element
+ else if (args.length === 0 && (el = this[0])) {
+ return el.innerHTML;
+ }
+
+ return this;
+};
+
+fn.append = function(appended) {
+ var i = 0,
+ length = this.length,
+ setter;
+
+ // create jBone object and then append
+ if (isString(appended) && rquickExpr.exec(appended)) {
+ appended = jBone(appended);
+ }
+ // create text node for inserting
+ else if (!isObject(appended)) {
+ appended = document.createTextNode(appended);
+ }
+
+ appended = appended instanceof jBone ? appended : jBone(appended);
+
+ setter = function(el, i) {
+ appended.forEach(function(node) {
+ if (i) {
+ el.appendChild(node.cloneNode());
+ } else {
+ el.appendChild(node);
+ }
+ });
+ };
+
+ for (; i < length; i++) {
+ setter(this[i], i);
+ }
+
+ return this;
+};
+
+fn.appendTo = function(to) {
+ jBone(to).append(this);
+
+ return this;
+};
+
+fn.empty = function() {
+ var i = 0,
+ length = this.length,
+ el;
+
+ for (; i < length; i++) {
+ el = this[i];
+
+ while (el.lastChild) {
+ el.removeChild(el.lastChild);
+ }
+ }
+
+ return this;
+};
+
+fn.remove = function() {
+ var i = 0,
+ length = this.length,
+ el;
+
+ // remove all listners
+ this.off();
+
+ for (; i < length; i++) {
+ el = this[i];
+
+ // remove data and nodes
+ delete el.jdata;
+ el.parentNode && el.parentNode.removeChild(el);
+ }
+
+ return this;
+};
+
+if (typeof module === "object" && module && typeof module.exports === "object") {
+ // Expose jBone as module.exports in loaders that implement the Node
+ // module pattern (including browserify). Do not create the global, since
+ // the user will be storing it themselves locally, and globals are frowned
+ // upon in the Node module world.
+ module.exports = jBone;
+}
+// Register as a AMD module
+else if (typeof define === "function" && define.amd) {
+ define(function() {
+ return jBone;
+ });
+
+ win.jBone = win.$ = jBone;
+} else if (typeof win === "object" && typeof win.document === "object") {
+ win.jBone = win.$ = jBone;
+}
+
+}(window));
+
+},{}],51:[function(require,module,exports){
+var Mouse;
+
+module.exports = Mouse = {
+ rel: function(e) {
+ var mouseX, mouseY, rect, target;
+ mouseX = e.offsetX;
+ mouseY = e.offsetY;
+ if (mouseX == null) {
+ rect = target.getBoundingClientRect();
+ target = e.target || e.srcElement;
+ if (mouseX == null) {
+ mouseX = e.clientX - rect.left;
+ mouseY = e.clientY - rect.top;
+ }
+ if (mouseX == null) {
+ mouseX = e.pageX - target.offsetLeft;
+ mouseY = e.pageY - target.offsetTop;
+ }
+ if (mouseX == null) {
+ console.log(e, "no mouse event defined. your browser sucks");
+ return;
+ }
+ }
+ return [mouseX, mouseY];
+ },
+ abs: function(e) {
+ var mouseX, mouseY;
+ mouseX = e.pageX;
+ mouseY = e.pageY;
+ if (mouseX == null) {
+ mouseX = e.layerX;
+ mouseY = e.layerY;
+ }
+ if (mouseX == null) {
+ mouseX = e.clientX;
+ mouseY = e.clientY;
+ }
+ if (mouseX == null) {
+ mouseX = e.x;
+ mouseY = e.y;
+ }
+ return [mouseX, mouseY];
+ },
+ wheelDelta: function(e) {
+ var delta, dir;
+ delta = [e.deltaX, e.deltaY];
+ if (delta[0] == null) {
+ dir = Math.floor(e.detail / 3);
+ delta = [0, e.mozMovementX * dir];
+ }
+ return delta;
+ }
+};
+
+},{}],52:[function(require,module,exports){
+var window = require("global/window")
+var once = require("once")
+var parseHeaders = require('parse-headers')
+
+var messages = {
+ "0": "Internal XMLHttpRequest Error",
+ "4": "4xx Client Error",
+ "5": "5xx Server Error"
+}
+
+var XHR = window.XMLHttpRequest || noop
+var XDR = "withCredentials" in (new XHR()) ? XHR : window.XDomainRequest
+
+module.exports = createXHR
+
+function createXHR(options, callback) {
+ if (typeof options === "string") {
+ options = { uri: options }
+ }
+
+ options = options || {}
+ callback = once(callback)
+
+ var xhr = options.xhr || null
+
+ if (!xhr) {
+ if (options.cors || options.useXDR) {
+ xhr = new XDR()
+ }else{
+ xhr = new XHR()
+ }
+ }
+
+ var uri = xhr.url = options.uri || options.url
+ var method = xhr.method = options.method || "GET"
+ var body = options.body || options.data
+ var headers = xhr.headers = options.headers || {}
+ var sync = !!options.sync
+ var isJson = false
+ var key
+ var load = options.response ? loadResponse : loadXhr
+
+ if ("json" in options) {
+ isJson = true
+ headers["Accept"] = "application/json"
+ if (method !== "GET" && method !== "HEAD") {
+ headers["Content-Type"] = "application/json"
+ body = JSON.stringify(options.json)
+ }
+ }
+
+ xhr.onreadystatechange = readystatechange
+ xhr.onload = load
+ xhr.onerror = error
+ // IE9 must have onprogress be set to a unique function.
+ xhr.onprogress = function () {
+ // IE must die
+ }
+ // hate IE
+ xhr.ontimeout = noop
+ xhr.open(method, uri, !sync)
+ //backward compatibility
+ if (options.withCredentials || (options.cors && options.withCredentials !== false)) {
+ xhr.withCredentials = true
+ }
+
+ // Cannot set timeout with sync request
+ if (!sync) {
+ xhr.timeout = "timeout" in options ? options.timeout : 5000
+ }
+
+ if (xhr.setRequestHeader) {
+ for(key in headers){
+ if(headers.hasOwnProperty(key)){
+ xhr.setRequestHeader(key, headers[key])
+ }
+ }
+ } else if (options.headers) {
+ throw new Error("Headers cannot be set on an XDomainRequest object")
+ }
+
+ if ("responseType" in options) {
+ xhr.responseType = options.responseType
+ }
+
+ if ("beforeSend" in options &&
+ typeof options.beforeSend === "function"
+ ) {
+ options.beforeSend(xhr)
+ }
+
+ xhr.send(body)
+
+ return xhr
+
+ function readystatechange() {
+ if (xhr.readyState === 4) {
+ load()
+ }
+ }
+
+ function getBody() {
+ // Chrome with requestType=blob throws errors arround when even testing access to responseText
+ var body = null
+
+ if (xhr.response) {
+ body = xhr.response
+ } else if (xhr.responseType === 'text' || !xhr.responseType) {
+ body = xhr.responseText || xhr.responseXML
+ }
+
+ if (isJson) {
+ try {
+ body = JSON.parse(body)
+ } catch (e) {}
+ }
+
+ return body
+ }
+
+ function getStatusCode() {
+ return xhr.status === 1223 ? 204 : xhr.status
+ }
+
+ // if we're getting a none-ok statusCode, build & return an error
+ function errorFromStatusCode(status) {
+ var error = null
+ if (status === 0 || (status >= 400 && status < 600)) {
+ var message = (typeof body === "string" ? body : false) ||
+ messages[String(status).charAt(0)]
+ error = new Error(message)
+ error.statusCode = status
+ }
+
+ return error
+ }
+
+ // will load the data & process the response in a special response object
+ function loadResponse() {
+ var status = getStatusCode()
+ var error = errorFromStatusCode(status)
+ var response = {
+ body: getBody(),
+ statusCode: status,
+ statusText: xhr.statusText,
+ raw: xhr
+ }
+ if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
+ response.headers = parseHeaders(xhr.getAllResponseHeaders())
+ } else {
+ response.headers = {}
+ }
+
+ callback(error, response, response.body)
+ }
+
+ // will load the data and add some response properties to the source xhr
+ // and then respond with that
+ function loadXhr() {
+ var status = getStatusCode()
+ var error = errorFromStatusCode(status)
+
+ xhr.status = xhr.statusCode = status
+ xhr.body = getBody()
+ xhr.headers = parseHeaders(xhr.getAllResponseHeaders())
+
+ callback(error, xhr, xhr.body)
+ }
+
+ function error(evt) {
+ callback(evt, xhr)
+ }
+}
+
+
+function noop() {}
+
+},{"global/window":53,"once":54,"parse-headers":58}],53:[function(require,module,exports){
+(function (global){
+if (typeof window !== "undefined") {
+ module.exports = window;
+} else if (typeof global !== "undefined") {
+ module.exports = global;
+} else if (typeof self !== "undefined"){
+ module.exports = self;
+} else {
+ module.exports = {};
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],54:[function(require,module,exports){
+module.exports = once
+
+once.proto = once(function () {
+ Object.defineProperty(Function.prototype, 'once', {
+ value: function () {
+ return once(this)
+ },
+ configurable: true
+ })
+})
+
+function once (fn) {
+ var called = false
+ return function () {
+ if (called) return
+ called = true
+ return fn.apply(this, arguments)
+ }
+}
+
+},{}],55:[function(require,module,exports){
+var isFunction = require('is-function')
+
+module.exports = forEach
+
+var toString = Object.prototype.toString
+var hasOwnProperty = Object.prototype.hasOwnProperty
+
+function forEach(list, iterator, context) {
+ if (!isFunction(iterator)) {
+ throw new TypeError('iterator must be a function')
+ }
+
+ if (arguments.length < 3) {
+ context = this
+ }
+
+ if (toString.call(list) === '[object Array]')
+ forEachArray(list, iterator, context)
+ else if (typeof list === 'string')
+ forEachString(list, iterator, context)
+ else
+ forEachObject(list, iterator, context)
+}
+
+function forEachArray(array, iterator, context) {
+ for (var i = 0, len = array.length; i < len; i++) {
+ if (hasOwnProperty.call(array, i)) {
+ iterator.call(context, array[i], i, array)
+ }
+ }
+}
+
+function forEachString(string, iterator, context) {
+ for (var i = 0, len = string.length; i < len; i++) {
+ // no such thing as a sparse string.
+ iterator.call(context, string.charAt(i), i, string)
+ }
+}
+
+function forEachObject(object, iterator, context) {
+ for (var k in object) {
+ if (hasOwnProperty.call(object, k)) {
+ iterator.call(context, object[k], k, object)
+ }
+ }
+}
+
+},{"is-function":56}],56:[function(require,module,exports){
+module.exports = isFunction
+
+var toString = Object.prototype.toString
+
+function isFunction (fn) {
+ var string = toString.call(fn)
+ return string === '[object Function]' ||
+ (typeof fn === 'function' && string !== '[object RegExp]') ||
+ (typeof window !== 'undefined' &&
+ // IE8 and below
+ (fn === window.setTimeout ||
+ fn === window.alert ||
+ fn === window.confirm ||
+ fn === window.prompt))
+};
+
+},{}],57:[function(require,module,exports){
+
+exports = module.exports = trim;
+
+function trim(str){
+ return str.replace(/^\s*|\s*$/g, '');
+}
+
+exports.left = function(str){
+ return str.replace(/^\s*/, '');
+};
+
+exports.right = function(str){
+ return str.replace(/\s*$/, '');
+};
+
+},{}],58:[function(require,module,exports){
+var trim = require('trim')
+ , forEach = require('for-each')
+ , isArray = function(arg) {
+ return Object.prototype.toString.call(arg) === '[object Array]';
+ }
+
+module.exports = function (headers) {
+ if (!headers)
+ return {}
+
+ var result = {}
+
+ forEach(
+ trim(headers).split('\n')
+ , function (row) {
+ var index = row.indexOf(':')
+ , key = trim(row.slice(0, index)).toLowerCase()
+ , value = trim(row.slice(index + 1))
+
+ if (typeof(result[key]) === 'undefined') {
+ result[key] = value
+ } else if (isArray(result[key])) {
+ result[key].push(value)
+ } else {
+ result[key] = [ result[key], value ]
+ }
+ }
+ )
+
+ return result
+}
+},{"for-each":55,"trim":57}],59:[function(require,module,exports){
+// Underscore.js 1.7.0
+// http://underscorejs.org
+// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Underscore may be freely distributed under the MIT license.
+
+(function() {
+
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `exports` on the server.
+ var root = this;
+
+ // Save the previous value of the `_` variable.
+ var previousUnderscore = root._;
+
+ // Save bytes in the minified (but not gzipped) version:
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
+
+ // Create quick reference variables for speed access to core prototypes.
+ var
+ push = ArrayProto.push,
+ slice = ArrayProto.slice,
+ concat = ArrayProto.concat,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
+
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
+ var
+ nativeIsArray = Array.isArray,
+ nativeKeys = Object.keys,
+ nativeBind = FuncProto.bind;
+
+ // Create a safe reference to the Underscore object for use below.
+ var _ = function(obj) {
+ if (obj instanceof _) return obj;
+ if (!(this instanceof _)) return new _(obj);
+ this._wrapped = obj;
+ };
+
+ // Export the Underscore object for **Node.js**, with
+ // backwards-compatibility for the old `require()` API. If we're in
+ // the browser, add `_` as a global object.
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = _;
+ }
+ exports._ = _;
+ } else {
+ root._ = _;
+ }
+
+ // Current version.
+ _.VERSION = '1.7.0';
+
+ // Internal function that returns an efficient (for current engines) version
+ // of the passed-in callback, to be repeatedly applied in other Underscore
+ // functions.
+ var createCallback = function(func, context, argCount) {
+ if (context === void 0) return func;
+ switch (argCount == null ? 3 : argCount) {
+ case 1: return function(value) {
+ return func.call(context, value);
+ };
+ case 2: return function(value, other) {
+ return func.call(context, value, other);
+ };
+ case 3: return function(value, index, collection) {
+ return func.call(context, value, index, collection);
+ };
+ case 4: return function(accumulator, value, index, collection) {
+ return func.call(context, accumulator, value, index, collection);
+ };
+ }
+ return function() {
+ return func.apply(context, arguments);
+ };
+ };
+
+ // A mostly-internal function to generate callbacks that can be applied
+ // to each element in a collection, returning the desired result — either
+ // identity, an arbitrary callback, a property matcher, or a property accessor.
+ _.iteratee = function(value, context, argCount) {
+ if (value == null) return _.identity;
+ if (_.isFunction(value)) return createCallback(value, context, argCount);
+ if (_.isObject(value)) return _.matches(value);
+ return _.property(value);
+ };
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles raw objects in addition to array-likes. Treats all
+ // sparse array-likes as if they were dense.
+ _.each = _.forEach = function(obj, iteratee, context) {
+ if (obj == null) return obj;
+ iteratee = createCallback(iteratee, context);
+ var i, length = obj.length;
+ if (length === +length) {
+ for (i = 0; i < length; i++) {
+ iteratee(obj[i], i, obj);
+ }
+ } else {
+ var keys = _.keys(obj);
+ for (i = 0, length = keys.length; i < length; i++) {
+ iteratee(obj[keys[i]], keys[i], obj);
+ }
+ }
+ return obj;
+ };
+
+ // Return the results of applying the iteratee to each element.
+ _.map = _.collect = function(obj, iteratee, context) {
+ if (obj == null) return [];
+ iteratee = _.iteratee(iteratee, context);
+ var keys = obj.length !== +obj.length && _.keys(obj),
+ length = (keys || obj).length,
+ results = Array(length),
+ currentKey;
+ for (var index = 0; index < length; index++) {
+ currentKey = keys ? keys[index] : index;
+ results[index] = iteratee(obj[currentKey], currentKey, obj);
+ }
+ return results;
+ };
+
+ var reduceError = 'Reduce of empty array with no initial value';
+
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`.
+ _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) {
+ if (obj == null) obj = [];
+ iteratee = createCallback(iteratee, context, 4);
+ var keys = obj.length !== +obj.length && _.keys(obj),
+ length = (keys || obj).length,
+ index = 0, currentKey;
+ if (arguments.length < 3) {
+ if (!length) throw new TypeError(reduceError);
+ memo = obj[keys ? keys[index++] : index++];
+ }
+ for (; index < length; index++) {
+ currentKey = keys ? keys[index] : index;
+ memo = iteratee(memo, obj[currentKey], currentKey, obj);
+ }
+ return memo;
+ };
+
+ // The right-associative version of reduce, also known as `foldr`.
+ _.reduceRight = _.foldr = function(obj, iteratee, memo, context) {
+ if (obj == null) obj = [];
+ iteratee = createCallback(iteratee, context, 4);
+ var keys = obj.length !== + obj.length && _.keys(obj),
+ index = (keys || obj).length,
+ currentKey;
+ if (arguments.length < 3) {
+ if (!index) throw new TypeError(reduceError);
+ memo = obj[keys ? keys[--index] : --index];
+ }
+ while (index--) {
+ currentKey = keys ? keys[index] : index;
+ memo = iteratee(memo, obj[currentKey], currentKey, obj);
+ }
+ return memo;
+ };
+
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, predicate, context) {
+ var result;
+ predicate = _.iteratee(predicate, context);
+ _.some(obj, function(value, index, list) {
+ if (predicate(value, index, list)) {
+ result = value;
+ return true;
+ }
+ });
+ return result;
+ };
+
+ // Return all the elements that pass a truth test.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, predicate, context) {
+ var results = [];
+ if (obj == null) return results;
+ predicate = _.iteratee(predicate, context);
+ _.each(obj, function(value, index, list) {
+ if (predicate(value, index, list)) results.push(value);
+ });
+ return results;
+ };
+
+ // Return all the elements for which a truth test fails.
+ _.reject = function(obj, predicate, context) {
+ return _.filter(obj, _.negate(_.iteratee(predicate)), context);
+ };
+
+ // Determine whether all of the elements match a truth test.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, predicate, context) {
+ if (obj == null) return true;
+ predicate = _.iteratee(predicate, context);
+ var keys = obj.length !== +obj.length && _.keys(obj),
+ length = (keys || obj).length,
+ index, currentKey;
+ for (index = 0; index < length; index++) {
+ currentKey = keys ? keys[index] : index;
+ if (!predicate(obj[currentKey], currentKey, obj)) return false;
+ }
+ return true;
+ };
+
+ // Determine if at least one element in the object matches a truth test.
+ // Aliased as `any`.
+ _.some = _.any = function(obj, predicate, context) {
+ if (obj == null) return false;
+ predicate = _.iteratee(predicate, context);
+ var keys = obj.length !== +obj.length && _.keys(obj),
+ length = (keys || obj).length,
+ index, currentKey;
+ for (index = 0; index < length; index++) {
+ currentKey = keys ? keys[index] : index;
+ if (predicate(obj[currentKey], currentKey, obj)) return true;
+ }
+ return false;
+ };
+
+ // Determine if the array or object contains a given value (using `===`).
+ // Aliased as `include`.
+ _.contains = _.include = function(obj, target) {
+ if (obj == null) return false;
+ if (obj.length !== +obj.length) obj = _.values(obj);
+ return _.indexOf(obj, target) >= 0;
+ };
+
+ // Invoke a method (with arguments) on every item in a collection.
+ _.invoke = function(obj, method) {
+ var args = slice.call(arguments, 2);
+ var isFunc = _.isFunction(method);
+ return _.map(obj, function(value) {
+ return (isFunc ? method : value[method]).apply(value, args);
+ });
+ };
+
+ // Convenience version of a common use case of `map`: fetching a property.
+ _.pluck = function(obj, key) {
+ return _.map(obj, _.property(key));
+ };
+
+ // Convenience version of a common use case of `filter`: selecting only objects
+ // containing specific `key:value` pairs.
+ _.where = function(obj, attrs) {
+ return _.filter(obj, _.matches(attrs));
+ };
+
+ // Convenience version of a common use case of `find`: getting the first object
+ // containing specific `key:value` pairs.
+ _.findWhere = function(obj, attrs) {
+ return _.find(obj, _.matches(attrs));
+ };
+
+ // Return the maximum element (or element-based computation).
+ _.max = function(obj, iteratee, context) {
+ var result = -Infinity, lastComputed = -Infinity,
+ value, computed;
+ if (iteratee == null && obj != null) {
+ obj = obj.length === +obj.length ? obj : _.values(obj);
+ for (var i = 0, length = obj.length; i < length; i++) {
+ value = obj[i];
+ if (value > result) {
+ result = value;
+ }
+ }
+ } else {
+ iteratee = _.iteratee(iteratee, context);
+ _.each(obj, function(value, index, list) {
+ computed = iteratee(value, index, list);
+ if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
+ result = value;
+ lastComputed = computed;
+ }
+ });
+ }
+ return result;
+ };
+
+ // Return the minimum element (or element-based computation).
+ _.min = function(obj, iteratee, context) {
+ var result = Infinity, lastComputed = Infinity,
+ value, computed;
+ if (iteratee == null && obj != null) {
+ obj = obj.length === +obj.length ? obj : _.values(obj);
+ for (var i = 0, length = obj.length; i < length; i++) {
+ value = obj[i];
+ if (value < result) {
+ result = value;
+ }
+ }
+ } else {
+ iteratee = _.iteratee(iteratee, context);
+ _.each(obj, function(value, index, list) {
+ computed = iteratee(value, index, list);
+ if (computed < lastComputed || computed === Infinity && result === Infinity) {
+ result = value;
+ lastComputed = computed;
+ }
+ });
+ }
+ return result;
+ };
+
+ // Shuffle a collection, using the modern version of the
+ // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
+ _.shuffle = function(obj) {
+ var set = obj && obj.length === +obj.length ? obj : _.values(obj);
+ var length = set.length;
+ var shuffled = Array(length);
+ for (var index = 0, rand; index < length; index++) {
+ rand = _.random(0, index);
+ if (rand !== index) shuffled[index] = shuffled[rand];
+ shuffled[rand] = set[index];
+ }
+ return shuffled;
+ };
+
+ // Sample **n** random values from a collection.
+ // If **n** is not specified, returns a single random element.
+ // The internal `guard` argument allows it to work with `map`.
+ _.sample = function(obj, n, guard) {
+ if (n == null || guard) {
+ if (obj.length !== +obj.length) obj = _.values(obj);
+ return obj[_.random(obj.length - 1)];
+ }
+ return _.shuffle(obj).slice(0, Math.max(0, n));
+ };
+
+ // Sort the object's values by a criterion produced by an iteratee.
+ _.sortBy = function(obj, iteratee, context) {
+ iteratee = _.iteratee(iteratee, context);
+ return _.pluck(_.map(obj, function(value, index, list) {
+ return {
+ value: value,
+ index: index,
+ criteria: iteratee(value, index, list)
+ };
+ }).sort(function(left, right) {
+ var a = left.criteria;
+ var b = right.criteria;
+ if (a !== b) {
+ if (a > b || a === void 0) return 1;
+ if (a < b || b === void 0) return -1;
+ }
+ return left.index - right.index;
+ }), 'value');
+ };
+
+ // An internal function used for aggregate "group by" operations.
+ var group = function(behavior) {
+ return function(obj, iteratee, context) {
+ var result = {};
+ iteratee = _.iteratee(iteratee, context);
+ _.each(obj, function(value, index) {
+ var key = iteratee(value, index, obj);
+ behavior(result, value, key);
+ });
+ return result;
+ };
+ };
+
+ // Groups the object's values by a criterion. Pass either a string attribute
+ // to group by, or a function that returns the criterion.
+ _.groupBy = group(function(result, value, key) {
+ if (_.has(result, key)) result[key].push(value); else result[key] = [value];
+ });
+
+ // Indexes the object's values by a criterion, similar to `groupBy`, but for
+ // when you know that your index values will be unique.
+ _.indexBy = group(function(result, value, key) {
+ result[key] = value;
+ });
+
+ // Counts instances of an object that group by a certain criterion. Pass
+ // either a string attribute to count by, or a function that returns the
+ // criterion.
+ _.countBy = group(function(result, value, key) {
+ if (_.has(result, key)) result[key]++; else result[key] = 1;
+ });
+
+ // Use a comparator function to figure out the smallest index at which
+ // an object should be inserted so as to maintain order. Uses binary search.
+ _.sortedIndex = function(array, obj, iteratee, context) {
+ iteratee = _.iteratee(iteratee, context, 1);
+ var value = iteratee(obj);
+ var low = 0, high = array.length;
+ while (low < high) {
+ var mid = low + high >>> 1;
+ if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
+ }
+ return low;
+ };
+
+ // Safely create a real, live array from anything iterable.
+ _.toArray = function(obj) {
+ if (!obj) return [];
+ if (_.isArray(obj)) return slice.call(obj);
+ if (obj.length === +obj.length) return _.map(obj, _.identity);
+ return _.values(obj);
+ };
+
+ // Return the number of elements in an object.
+ _.size = function(obj) {
+ if (obj == null) return 0;
+ return obj.length === +obj.length ? obj.length : _.keys(obj).length;
+ };
+
+ // Split a collection into two arrays: one whose elements all satisfy the given
+ // predicate, and one whose elements all do not satisfy the predicate.
+ _.partition = function(obj, predicate, context) {
+ predicate = _.iteratee(predicate, context);
+ var pass = [], fail = [];
+ _.each(obj, function(value, key, obj) {
+ (predicate(value, key, obj) ? pass : fail).push(value);
+ });
+ return [pass, fail];
+ };
+
+ // Array Functions
+ // ---------------
+
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head` and `take`. The **guard** check
+ // allows it to work with `_.map`.
+ _.first = _.head = _.take = function(array, n, guard) {
+ if (array == null) return void 0;
+ if (n == null || guard) return array[0];
+ if (n < 0) return [];
+ return slice.call(array, 0, n);
+ };
+
+ // Returns everything but the last entry of the array. Especially useful on
+ // the arguments object. Passing **n** will return all the values in
+ // the array, excluding the last N. The **guard** check allows it to work with
+ // `_.map`.
+ _.initial = function(array, n, guard) {
+ return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
+ };
+
+ // Get the last element of an array. Passing **n** will return the last N
+ // values in the array. The **guard** check allows it to work with `_.map`.
+ _.last = function(array, n, guard) {
+ if (array == null) return void 0;
+ if (n == null || guard) return array[array.length - 1];
+ return slice.call(array, Math.max(array.length - n, 0));
+ };
+
+ // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
+ // Especially useful on the arguments object. Passing an **n** will return
+ // the rest N values in the array. The **guard**
+ // check allows it to work with `_.map`.
+ _.rest = _.tail = _.drop = function(array, n, guard) {
+ return slice.call(array, n == null || guard ? 1 : n);
+ };
+
+ // Trim out all falsy values from an array.
+ _.compact = function(array) {
+ return _.filter(array, _.identity);
+ };
+
+ // Internal implementation of a recursive `flatten` function.
+ var flatten = function(input, shallow, strict, output) {
+ if (shallow && _.every(input, _.isArray)) {
+ return concat.apply(output, input);
+ }
+ for (var i = 0, length = input.length; i < length; i++) {
+ var value = input[i];
+ if (!_.isArray(value) && !_.isArguments(value)) {
+ if (!strict) output.push(value);
+ } else if (shallow) {
+ push.apply(output, value);
+ } else {
+ flatten(value, shallow, strict, output);
+ }
+ }
+ return output;
+ };
+
+ // Flatten out an array, either recursively (by default), or just one level.
+ _.flatten = function(array, shallow) {
+ return flatten(array, shallow, false, []);
+ };
+
+ // Return a version of the array that does not contain the specified value(s).
+ _.without = function(array) {
+ return _.difference(array, slice.call(arguments, 1));
+ };
+
+ // Produce a duplicate-free version of the array. If the array has already
+ // been sorted, you have the option of using a faster algorithm.
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted, iteratee, context) {
+ if (array == null) return [];
+ if (!_.isBoolean(isSorted)) {
+ context = iteratee;
+ iteratee = isSorted;
+ isSorted = false;
+ }
+ if (iteratee != null) iteratee = _.iteratee(iteratee, context);
+ var result = [];
+ var seen = [];
+ for (var i = 0, length = array.length; i < length; i++) {
+ var value = array[i];
+ if (isSorted) {
+ if (!i || seen !== value) result.push(value);
+ seen = value;
+ } else if (iteratee) {
+ var computed = iteratee(value, i, array);
+ if (_.indexOf(seen, computed) < 0) {
+ seen.push(computed);
+ result.push(value);
+ }
+ } else if (_.indexOf(result, value) < 0) {
+ result.push(value);
+ }
+ }
+ return result;
+ };
+
+ // Produce an array that contains the union: each distinct element from all of
+ // the passed-in arrays.
+ _.union = function() {
+ return _.uniq(flatten(arguments, true, true, []));
+ };
+
+ // Produce an array that contains every item shared between all the
+ // passed-in arrays.
+ _.intersection = function(array) {
+ if (array == null) return [];
+ var result = [];
+ var argsLength = arguments.length;
+ for (var i = 0, length = array.length; i < length; i++) {
+ var item = array[i];
+ if (_.contains(result, item)) continue;
+ for (var j = 1; j < argsLength; j++) {
+ if (!_.contains(arguments[j], item)) break;
+ }
+ if (j === argsLength) result.push(item);
+ }
+ return result;
+ };
+
+ // Take the difference between one array and a number of other arrays.
+ // Only the elements present in just the first array will remain.
+ _.difference = function(array) {
+ var rest = flatten(slice.call(arguments, 1), true, true, []);
+ return _.filter(array, function(value){
+ return !_.contains(rest, value);
+ });
+ };
+
+ // Zip together multiple lists into a single array -- elements that share
+ // an index go together.
+ _.zip = function(array) {
+ if (array == null) return [];
+ var length = _.max(arguments, 'length').length;
+ var results = Array(length);
+ for (var i = 0; i < length; i++) {
+ results[i] = _.pluck(arguments, i);
+ }
+ return results;
+ };
+
+ // Converts lists into objects. Pass either a single array of `[key, value]`
+ // pairs, or two parallel arrays of the same length -- one of keys, and one of
+ // the corresponding values.
+ _.object = function(list, values) {
+ if (list == null) return {};
+ var result = {};
+ for (var i = 0, length = list.length; i < length; i++) {
+ if (values) {
+ result[list[i]] = values[i];
+ } else {
+ result[list[i][0]] = list[i][1];
+ }
+ }
+ return result;
+ };
+
+ // Return the position of the first occurrence of an item in an array,
+ // or -1 if the item is not included in the array.
+ // If the array is large and already in sort order, pass `true`
+ // for **isSorted** to use binary search.
+ _.indexOf = function(array, item, isSorted) {
+ if (array == null) return -1;
+ var i = 0, length = array.length;
+ if (isSorted) {
+ if (typeof isSorted == 'number') {
+ i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
+ } else {
+ i = _.sortedIndex(array, item);
+ return array[i] === item ? i : -1;
+ }
+ }
+ for (; i < length; i++) if (array[i] === item) return i;
+ return -1;
+ };
+
+ _.lastIndexOf = function(array, item, from) {
+ if (array == null) return -1;
+ var idx = array.length;
+ if (typeof from == 'number') {
+ idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
+ }
+ while (--idx >= 0) if (array[idx] === item) return idx;
+ return -1;
+ };
+
+ // Generate an integer Array containing an arithmetic progression. A port of
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
+ _.range = function(start, stop, step) {
+ if (arguments.length <= 1) {
+ stop = start || 0;
+ start = 0;
+ }
+ step = step || 1;
+
+ var length = Math.max(Math.ceil((stop - start) / step), 0);
+ var range = Array(length);
+
+ for (var idx = 0; idx < length; idx++, start += step) {
+ range[idx] = start;
+ }
+
+ return range;
+ };
+
+ // Function (ahem) Functions
+ // ------------------
+
+ // Reusable constructor function for prototype setting.
+ var Ctor = function(){};
+
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
+ // available.
+ _.bind = function(func, context) {
+ var args, bound;
+ if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
+ args = slice.call(arguments, 2);
+ bound = function() {
+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+ Ctor.prototype = func.prototype;
+ var self = new Ctor;
+ Ctor.prototype = null;
+ var result = func.apply(self, args.concat(slice.call(arguments)));
+ if (_.isObject(result)) return result;
+ return self;
+ };
+ return bound;
+ };
+
+ // Partially apply a function by creating a version that has had some of its
+ // arguments pre-filled, without changing its dynamic `this` context. _ acts
+ // as a placeholder, allowing any combination of arguments to be pre-filled.
+ _.partial = function(func) {
+ var boundArgs = slice.call(arguments, 1);
+ return function() {
+ var position = 0;
+ var args = boundArgs.slice();
+ for (var i = 0, length = args.length; i < length; i++) {
+ if (args[i] === _) args[i] = arguments[position++];
+ }
+ while (position < arguments.length) args.push(arguments[position++]);
+ return func.apply(this, args);
+ };
+ };
+
+ // Bind a number of an object's methods to that object. Remaining arguments
+ // are the method names to be bound. Useful for ensuring that all callbacks
+ // defined on an object belong to it.
+ _.bindAll = function(obj) {
+ var i, length = arguments.length, key;
+ if (length <= 1) throw new Error('bindAll must be passed function names');
+ for (i = 1; i < length; i++) {
+ key = arguments[i];
+ obj[key] = _.bind(obj[key], obj);
+ }
+ return obj;
+ };
+
+ // Memoize an expensive function by storing its results.
+ _.memoize = function(func, hasher) {
+ var memoize = function(key) {
+ var cache = memoize.cache;
+ var address = hasher ? hasher.apply(this, arguments) : key;
+ if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
+ return cache[address];
+ };
+ memoize.cache = {};
+ return memoize;
+ };
+
+ // Delays a function for the given number of milliseconds, and then calls
+ // it with the arguments supplied.
+ _.delay = function(func, wait) {
+ var args = slice.call(arguments, 2);
+ return setTimeout(function(){
+ return func.apply(null, args);
+ }, wait);
+ };
+
+ // Defers a function, scheduling it to run after the current call stack has
+ // cleared.
+ _.defer = function(func) {
+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+ };
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time. Normally, the throttled function will run
+ // as much as it can, without ever going more than once per `wait` duration;
+ // but if you'd like to disable the execution on the leading edge, pass
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
+ _.throttle = function(func, wait, options) {
+ var context, args, result;
+ var timeout = null;
+ var previous = 0;
+ if (!options) options = {};
+ var later = function() {
+ previous = options.leading === false ? 0 : _.now();
+ timeout = null;
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ };
+ return function() {
+ var now = _.now();
+ if (!previous && options.leading === false) previous = now;
+ var remaining = wait - (now - previous);
+ context = this;
+ args = arguments;
+ if (remaining <= 0 || remaining > wait) {
+ clearTimeout(timeout);
+ timeout = null;
+ previous = now;
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ } else if (!timeout && options.trailing !== false) {
+ timeout = setTimeout(later, remaining);
+ }
+ return result;
+ };
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds. If `immediate` is passed, trigger the function on the
+ // leading edge, instead of the trailing.
+ _.debounce = function(func, wait, immediate) {
+ var timeout, args, context, timestamp, result;
+
+ var later = function() {
+ var last = _.now() - timestamp;
+
+ if (last < wait && last > 0) {
+ timeout = setTimeout(later, wait - last);
+ } else {
+ timeout = null;
+ if (!immediate) {
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ }
+ }
+ };
+
+ return function() {
+ context = this;
+ args = arguments;
+ timestamp = _.now();
+ var callNow = immediate && !timeout;
+ if (!timeout) timeout = setTimeout(later, wait);
+ if (callNow) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+
+ return result;
+ };
+ };
+
+ // Returns the first function passed as an argument to the second,
+ // allowing you to adjust arguments, run code before and after, and
+ // conditionally execute the original function.
+ _.wrap = function(func, wrapper) {
+ return _.partial(wrapper, func);
+ };
+
+ // Returns a negated version of the passed-in predicate.
+ _.negate = function(predicate) {
+ return function() {
+ return !predicate.apply(this, arguments);
+ };
+ };
+
+ // Returns a function that is the composition of a list of functions, each
+ // consuming the return value of the function that follows.
+ _.compose = function() {
+ var args = arguments;
+ var start = args.length - 1;
+ return function() {
+ var i = start;
+ var result = args[start].apply(this, arguments);
+ while (i--) result = args[i].call(this, result);
+ return result;
+ };
+ };
+
+ // Returns a function that will only be executed after being called N times.
+ _.after = function(times, func) {
+ return function() {
+ if (--times < 1) {
+ return func.apply(this, arguments);
+ }
+ };
+ };
+
+ // Returns a function that will only be executed before being called N times.
+ _.before = function(times, func) {
+ var memo;
+ return function() {
+ if (--times > 0) {
+ memo = func.apply(this, arguments);
+ } else {
+ func = null;
+ }
+ return memo;
+ };
+ };
+
+ // Returns a function that will be executed at most one time, no matter how
+ // often you call it. Useful for lazy initialization.
+ _.once = _.partial(_.before, 2);
+
+ // Object Functions
+ // ----------------
+
+ // Retrieve the names of an object's properties.
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
+ _.keys = function(obj) {
+ if (!_.isObject(obj)) return [];
+ if (nativeKeys) return nativeKeys(obj);
+ var keys = [];
+ for (var key in obj) if (_.has(obj, key)) keys.push(key);
+ return keys;
+ };
+
+ // Retrieve the values of an object's properties.
+ _.values = function(obj) {
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var values = Array(length);
+ for (var i = 0; i < length; i++) {
+ values[i] = obj[keys[i]];
+ }
+ return values;
+ };
+
+ // Convert an object into a list of `[key, value]` pairs.
+ _.pairs = function(obj) {
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var pairs = Array(length);
+ for (var i = 0; i < length; i++) {
+ pairs[i] = [keys[i], obj[keys[i]]];
+ }
+ return pairs;
+ };
+
+ // Invert the keys and values of an object. The values must be serializable.
+ _.invert = function(obj) {
+ var result = {};
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ result[obj[keys[i]]] = keys[i];
+ }
+ return result;
+ };
+
+ // Return a sorted list of the function names available on the object.
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
+ var names = [];
+ for (var key in obj) {
+ if (_.isFunction(obj[key])) names.push(key);
+ }
+ return names.sort();
+ };
+
+ // Extend a given object with all the properties in passed-in object(s).
+ _.extend = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ var source, prop;
+ for (var i = 1, length = arguments.length; i < length; i++) {
+ source = arguments[i];
+ for (prop in source) {
+ if (hasOwnProperty.call(source, prop)) {
+ obj[prop] = source[prop];
+ }
+ }
+ }
+ return obj;
+ };
+
+ // Return a copy of the object only containing the whitelisted properties.
+ _.pick = function(obj, iteratee, context) {
+ var result = {}, key;
+ if (obj == null) return result;
+ if (_.isFunction(iteratee)) {
+ iteratee = createCallback(iteratee, context);
+ for (key in obj) {
+ var value = obj[key];
+ if (iteratee(value, key, obj)) result[key] = value;
+ }
+ } else {
+ var keys = concat.apply([], slice.call(arguments, 1));
+ obj = new Object(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ key = keys[i];
+ if (key in obj) result[key] = obj[key];
+ }
+ }
+ return result;
+ };
+
+ // Return a copy of the object without the blacklisted properties.
+ _.omit = function(obj, iteratee, context) {
+ if (_.isFunction(iteratee)) {
+ iteratee = _.negate(iteratee);
+ } else {
+ var keys = _.map(concat.apply([], slice.call(arguments, 1)), String);
+ iteratee = function(value, key) {
+ return !_.contains(keys, key);
+ };
+ }
+ return _.pick(obj, iteratee, context);
+ };
+
+ // Fill in a given object with default properties.
+ _.defaults = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ for (var i = 1, length = arguments.length; i < length; i++) {
+ var source = arguments[i];
+ for (var prop in source) {
+ if (obj[prop] === void 0) obj[prop] = source[prop];
+ }
+ }
+ return obj;
+ };
+
+ // Create a (shallow-cloned) duplicate of an object.
+ _.clone = function(obj) {
+ if (!_.isObject(obj)) return obj;
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+ };
+
+ // Invokes interceptor with the obj, and then returns obj.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
+ _.tap = function(obj, interceptor) {
+ interceptor(obj);
+ return obj;
+ };
+
+ // Internal recursive comparison function for `isEqual`.
+ var eq = function(a, b, aStack, bStack) {
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+ if (a === b) return a !== 0 || 1 / a === 1 / b;
+ // A strict comparison is necessary because `null == undefined`.
+ if (a == null || b == null) return a === b;
+ // Unwrap any wrapped objects.
+ if (a instanceof _) a = a._wrapped;
+ if (b instanceof _) b = b._wrapped;
+ // Compare `[[Class]]` names.
+ var className = toString.call(a);
+ if (className !== toString.call(b)) return false;
+ switch (className) {
+ // Strings, numbers, regular expressions, dates, and booleans are compared by value.
+ case '[object RegExp]':
+ // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ return '' + a === '' + b;
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive.
+ // Object(NaN) is equivalent to NaN
+ if (+a !== +a) return +b !== +b;
+ // An `egal` comparison is performed for other numeric values.
+ return +a === 0 ? 1 / +a === 1 / b : +a === +b;
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ return +a === +b;
+ }
+ if (typeof a != 'object' || typeof b != 'object') return false;
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+ var length = aStack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (aStack[length] === a) return bStack[length] === b;
+ }
+ // Objects with different constructors are not equivalent, but `Object`s
+ // from different frames are.
+ var aCtor = a.constructor, bCtor = b.constructor;
+ if (
+ aCtor !== bCtor &&
+ // Handle Object.create(x) cases
+ 'constructor' in a && 'constructor' in b &&
+ !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
+ _.isFunction(bCtor) && bCtor instanceof bCtor)
+ ) {
+ return false;
+ }
+ // Add the first object to the stack of traversed objects.
+ aStack.push(a);
+ bStack.push(b);
+ var size, result;
+ // Recursively compare objects and arrays.
+ if (className === '[object Array]') {
+ // Compare array lengths to determine if a deep comparison is necessary.
+ size = a.length;
+ result = size === b.length;
+ if (result) {
+ // Deep compare the contents, ignoring non-numeric properties.
+ while (size--) {
+ if (!(result = eq(a[size], b[size], aStack, bStack))) break;
+ }
+ }
+ } else {
+ // Deep compare objects.
+ var keys = _.keys(a), key;
+ size = keys.length;
+ // Ensure that both objects contain the same number of properties before comparing deep equality.
+ result = _.keys(b).length === size;
+ if (result) {
+ while (size--) {
+ // Deep compare each member
+ key = keys[size];
+ if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
+ }
+ }
+ }
+ // Remove the first object from the stack of traversed objects.
+ aStack.pop();
+ bStack.pop();
+ return result;
+ };
+
+ // Perform a deep comparison to check if two objects are equal.
+ _.isEqual = function(a, b) {
+ return eq(a, b, [], []);
+ };
+
+ // Is a given array, string, or object empty?
+ // An "empty" object has no enumerable own-properties.
+ _.isEmpty = function(obj) {
+ if (obj == null) return true;
+ if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0;
+ for (var key in obj) if (_.has(obj, key)) return false;
+ return true;
+ };
+
+ // Is a given value a DOM element?
+ _.isElement = function(obj) {
+ return !!(obj && obj.nodeType === 1);
+ };
+
+ // Is a given value an array?
+ // Delegates to ECMA5's native Array.isArray
+ _.isArray = nativeIsArray || function(obj) {
+ return toString.call(obj) === '[object Array]';
+ };
+
+ // Is a given variable an object?
+ _.isObject = function(obj) {
+ var type = typeof obj;
+ return type === 'function' || type === 'object' && !!obj;
+ };
+
+ // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
+ _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
+ _['is' + name] = function(obj) {
+ return toString.call(obj) === '[object ' + name + ']';
+ };
+ });
+
+ // Define a fallback version of the method in browsers (ahem, IE), where
+ // there isn't any inspectable "Arguments" type.
+ if (!_.isArguments(arguments)) {
+ _.isArguments = function(obj) {
+ return _.has(obj, 'callee');
+ };
+ }
+
+ // Optimize `isFunction` if appropriate. Work around an IE 11 bug.
+ if (typeof /./ !== 'function') {
+ _.isFunction = function(obj) {
+ return typeof obj == 'function' || false;
+ };
+ }
+
+ // Is a given object a finite number?
+ _.isFinite = function(obj) {
+ return isFinite(obj) && !isNaN(parseFloat(obj));
+ };
+
+ // Is the given value `NaN`? (NaN is the only number which does not equal itself).
+ _.isNaN = function(obj) {
+ return _.isNumber(obj) && obj !== +obj;
+ };
+
+ // Is a given value a boolean?
+ _.isBoolean = function(obj) {
+ return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
+ };
+
+ // Is a given value equal to null?
+ _.isNull = function(obj) {
+ return obj === null;
+ };
+
+ // Is a given variable undefined?
+ _.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ // Shortcut function for checking if an object has a given property directly
+ // on itself (in other words, not on a prototype).
+ _.has = function(obj, key) {
+ return obj != null && hasOwnProperty.call(obj, key);
+ };
+
+ // Utility Functions
+ // -----------------
+
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+ // previous owner. Returns a reference to the Underscore object.
+ _.noConflict = function() {
+ root._ = previousUnderscore;
+ return this;
+ };
+
+ // Keep the identity function around for default iteratees.
+ _.identity = function(value) {
+ return value;
+ };
+
+ _.constant = function(value) {
+ return function() {
+ return value;
+ };
+ };
+
+ _.noop = function(){};
+
+ _.property = function(key) {
+ return function(obj) {
+ return obj[key];
+ };
+ };
+
+ // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
+ _.matches = function(attrs) {
+ var pairs = _.pairs(attrs), length = pairs.length;
+ return function(obj) {
+ if (obj == null) return !length;
+ obj = new Object(obj);
+ for (var i = 0; i < length; i++) {
+ var pair = pairs[i], key = pair[0];
+ if (pair[1] !== obj[key] || !(key in obj)) return false;
+ }
+ return true;
+ };
+ };
+
+ // Run a function **n** times.
+ _.times = function(n, iteratee, context) {
+ var accum = Array(Math.max(0, n));
+ iteratee = createCallback(iteratee, context, 1);
+ for (var i = 0; i < n; i++) accum[i] = iteratee(i);
+ return accum;
+ };
+
+ // Return a random integer between min and max (inclusive).
+ _.random = function(min, max) {
+ if (max == null) {
+ max = min;
+ min = 0;
+ }
+ return min + Math.floor(Math.random() * (max - min + 1));
+ };
+
+ // A (possibly faster) way to get the current timestamp as an integer.
+ _.now = Date.now || function() {
+ return new Date().getTime();
+ };
+
+ // List of HTML entities for escaping.
+ var escapeMap = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": ''',
+ '`': '`'
+ };
+ var unescapeMap = _.invert(escapeMap);
+
+ // Functions for escaping and unescaping strings to/from HTML interpolation.
+ var createEscaper = function(map) {
+ var escaper = function(match) {
+ return map[match];
+ };
+ // Regexes for identifying a key that needs to be escaped
+ var source = '(?:' + _.keys(map).join('|') + ')';
+ var testRegexp = RegExp(source);
+ var replaceRegexp = RegExp(source, 'g');
+ return function(string) {
+ string = string == null ? '' : '' + string;
+ return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
+ };
+ };
+ _.escape = createEscaper(escapeMap);
+ _.unescape = createEscaper(unescapeMap);
+
+ // If the value of the named `property` is a function then invoke it with the
+ // `object` as context; otherwise, return it.
+ _.result = function(object, property) {
+ if (object == null) return void 0;
+ var value = object[property];
+ return _.isFunction(value) ? object[property]() : value;
+ };
+
+ // Generate a unique integer id (unique within the entire client session).
+ // Useful for temporary DOM ids.
+ var idCounter = 0;
+ _.uniqueId = function(prefix) {
+ var id = ++idCounter + '';
+ return prefix ? prefix + id : id;
+ };
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g,
+ escape : /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /(.)^/;
+
+ // Certain characters need to be escaped so that they can be put into a
+ // string literal.
+ var escapes = {
+ "'": "'",
+ '\\': '\\',
+ '\r': 'r',
+ '\n': 'n',
+ '\u2028': 'u2028',
+ '\u2029': 'u2029'
+ };
+
+ var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
+
+ var escapeChar = function(match) {
+ return '\\' + escapes[match];
+ };
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ // NB: `oldSettings` only exists for backwards compatibility.
+ _.template = function(text, settings, oldSettings) {
+ if (!settings && oldSettings) settings = oldSettings;
+ settings = _.defaults({}, settings, _.templateSettings);
+
+ // Combine delimiters into one regular expression via alternation.
+ var matcher = RegExp([
+ (settings.escape || noMatch).source,
+ (settings.interpolate || noMatch).source,
+ (settings.evaluate || noMatch).source
+ ].join('|') + '|$', 'g');
+
+ // Compile the template source, escaping string literals appropriately.
+ var index = 0;
+ var source = "__p+='";
+ text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+ source += text.slice(index, offset).replace(escaper, escapeChar);
+ index = offset + match.length;
+
+ if (escape) {
+ source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
+ } else if (interpolate) {
+ source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
+ } else if (evaluate) {
+ source += "';\n" + evaluate + "\n__p+='";
+ }
+
+ // Adobe VMs need the match returned to produce the correct offest.
+ return match;
+ });
+ source += "';\n";
+
+ // If a variable is not specified, place data values in local scope.
+ if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
+
+ source = "var __t,__p='',__j=Array.prototype.join," +
+ "print=function(){__p+=__j.call(arguments,'');};\n" +
+ source + 'return __p;\n';
+
+ try {
+ var render = new Function(settings.variable || 'obj', '_', source);
+ } catch (e) {
+ e.source = source;
+ throw e;
+ }
+
+ var template = function(data) {
+ return render.call(this, data, _);
+ };
+
+ // Provide the compiled source as a convenience for precompilation.
+ var argument = settings.variable || 'obj';
+ template.source = 'function(' + argument + '){\n' + source + '}';
+
+ return template;
+ };
+
+ // Add a "chain" function. Start chaining a wrapped Underscore object.
+ _.chain = function(obj) {
+ var instance = _(obj);
+ instance._chain = true;
+ return instance;
+ };
+
+ // OOP
+ // ---------------
+ // If Underscore is called as a function, it returns a wrapped object that
+ // can be used OO-style. This wrapper holds altered versions of all the
+ // underscore functions. Wrapped objects may be chained.
+
+ // Helper function to continue chaining intermediate results.
+ var result = function(obj) {
+ return this._chain ? _(obj).chain() : obj;
+ };
+
+ // Add your own custom functions to the Underscore object.
+ _.mixin = function(obj) {
+ _.each(_.functions(obj), function(name) {
+ var func = _[name] = obj[name];
+ _.prototype[name] = function() {
+ var args = [this._wrapped];
+ push.apply(args, arguments);
+ return result.call(this, func.apply(_, args));
+ };
+ });
+ };
+
+ // Add all of the Underscore functions to the wrapper object.
+ _.mixin(_);
+
+ // Add all mutator Array functions to the wrapper.
+ _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ var obj = this._wrapped;
+ method.apply(obj, arguments);
+ if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
+ return result.call(this, obj);
+ };
+ });
+
+ // Add all accessor Array functions to the wrapper.
+ _.each(['concat', 'join', 'slice'], function(name) {
+ var method = ArrayProto[name];
+ _.prototype[name] = function() {
+ return result.call(this, method.apply(this._wrapped, arguments));
+ };
+ });
+
+ // Extracts the result from a wrapped and chained object.
+ _.prototype.value = function() {
+ return this._wrapped;
+ };
+
+ // AMD registration happens at the end for compatibility with AMD loaders
+ // that may not enforce next-turn semantics on modules. Even though general
+ // practice for AMD registration is to be anonymous, underscore registers
+ // as a named module because, like jQuery, it is a base library that is
+ // popular enough to be bundled in a third party lib, but not be part of
+ // an AMD load request. Those cases could generate an error when an
+ // anonymous define() is called outside of a loader request.
+ if (typeof define === 'function' && define.amd) {
+ define('underscore', [], function() {
+ return _;
+ });
+ }
+}.call(this));
+
+},{}],60:[function(require,module,exports){
+var _;
+
+_ = require("underscore");
+
+module.exports = function(seqs) {
+ var occs;
+ seqs = seqs.map(function(el) {
+ return el.get("seq");
+ });
+ occs = new Array(seqs.length);
+ _.each(seqs, function(el, i) {
+ return _.each(el, function(char, pos) {
+ if (occs[pos] == null) {
+ occs[pos] = {};
+ }
+ if (occs[pos][char] == null) {
+ occs[pos][char] = 0;
+ }
+ return occs[pos][char]++;
+ });
+ });
+ return _.reduce(occs, function(memo, occ) {
+ var keys;
+ keys = _.keys(occ);
+ return memo += _.max(keys, function(key) {
+ return occ[key];
+ });
+ }, "");
+};
+
+
+
+},{"underscore":59}],61:[function(require,module,exports){
+var identitiyCalc;
+
+module.exports = identitiyCalc = function(seqs, consensus) {
+ if (consensus === void 0) {
+ console.warn("bug on consenus calc");
+ return;
+ }
+ return seqs.each(function(seqObj) {
+ var i, matches, seq, total, _i, _ref;
+ seq = seqObj.get("seq");
+ matches = 0;
+ total = 0;
+ for (i = _i = 0, _ref = seq.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ if (seq[i] !== "-" && consensus[i] !== "-") {
+ total++;
+ if (seq[i] === consensus[i]) {
+ matches++;
+ }
+ }
+ }
+ return seqObj.set("identity", matches / total);
+ });
+};
+
+
+
+},{}],62:[function(require,module,exports){
+module.exports.consensus = require("./ConsensusCalc");
+
+
+
+},{"./ConsensusCalc":60}],63:[function(require,module,exports){
+var Colorator, Model;
+
+Model = require("backbone-thin").Model;
+
+module.exports = Colorator = Model.extend({
+ defaults: {
+ scheme: "taylor",
+ colorBackground: true,
+ showLowerCase: true,
+ opacity: 0.6
+ }
+});
+
+
+
+},{"backbone-thin":5}],64:[function(require,module,exports){
+var Columns, Model, consenus, _;
+
+Model = require("backbone-thin").Model;
+
+consenus = require("../algo/ConsensusCalc");
+
+_ = require("underscore");
+
+module.exports = Columns = Model.extend({
+ defaults: {
+ scaling: "lin"
+ },
+ initialize: function() {
+ if (this.get("hidden") == null) {
+ return this.set("hidden", []);
+ }
+ },
+ calcHiddenColumns: function(n) {
+ var hidden, i, newX, _i, _len;
+ hidden = this.get("hidden");
+ newX = n;
+ for (_i = 0, _len = hidden.length; _i < _len; _i++) {
+ i = hidden[_i];
+ if (i <= newX) {
+ newX++;
+ }
+ }
+ return newX - n;
+ },
+ _calcConservationPre: function(seqs) {
+ var cons, matches, nMax, total;
+ console.log(seqs.length);
+ if (seqs.length > 1000) {
+ return;
+ }
+ cons = consenus(seqs);
+ seqs = seqs.map(function(el) {
+ return el.get("seq");
+ });
+ nMax = (_.max(seqs, function(el) {
+ return el.length;
+ })).length;
+ total = new Array(nMax);
+ matches = new Array(nMax);
+ _.each(seqs, function(el, i) {
+ return _.each(el, function(char, pos) {
+ total[pos] = total[pos] + 1 || 1;
+ if (cons[pos] === char) {
+ return matches[pos] = matches[pos] + 1 || 1;
+ }
+ });
+ });
+ return [matches, total, nMax];
+ },
+ calcConservation: function(seqs) {
+ if (this.attributes.scaling === "exp") {
+ return this.calcConservationExp(seqs);
+ } else if (this.attributes.scaling === "log") {
+ return this.calcConservationLog(seqs);
+ } else if (this.attributes.scaling === "lin") {
+ return this.calcConservationLin(seqs);
+ }
+ },
+ calcConservationLin: function(seqs) {
+ var i, matches, nMax, total, _i, _ref, _ref1;
+ _ref = this._calcConservationPre(seqs), matches = _ref[0], total = _ref[1], nMax = _ref[2];
+ for (i = _i = 0, _ref1 = nMax - 1; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
+ matches[i] = matches[i] / total[i];
+ }
+ this.set("conserv", matches);
+ return matches;
+ },
+ calcConservationLog: function(seqs) {
+ var i, matches, nMax, total, _i, _ref, _ref1;
+ _ref = this._calcConservationPre(seqs), matches = _ref[0], total = _ref[1], nMax = _ref[2];
+ for (i = _i = 0, _ref1 = nMax - 1; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
+ matches[i] = Math.log(matches[i] + 1) / Math.log(total[i] + 1);
+ }
+ this.set("conserv", matches);
+ return matches;
+ },
+ calcConservationExp: function(seqs) {
+ var i, matches, nMax, total, _i, _ref, _ref1;
+ _ref = this._calcConservationPre(seqs), matches = _ref[0], total = _ref[1], nMax = _ref[2];
+ for (i = _i = 0, _ref1 = nMax - 1; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
+ matches[i] = Math.exp(matches[i] + 1) / Math.exp(total[i] + 1);
+ }
+ this.set("conserv", matches);
+ return matches;
+ }
+});
+
+
+
+},{"../algo/ConsensusCalc":60,"backbone-thin":5,"underscore":59}],65:[function(require,module,exports){
+var Config, Model;
+
+Model = require("backbone-thin").Model;
+
+module.exports = Config = Model.extend({
+ defaults: {
+ registerMouseHover: false,
+ registerMouseClicks: true,
+ importProxy: "https://cors-anywhere.herokuapp.com/",
+ eventBus: true
+ }
+});
+
+
+
+},{"backbone-thin":5}],66:[function(require,module,exports){
+var Consenus, Model, consenusCalc;
+
+Model = require("backbone-thin").Model;
+
+consenusCalc = require("../algo/ConsensusCalc");
+
+module.exports = Consenus = Model.extend({
+ defaults: {
+ consenus: ""
+ },
+ getConsensus: function(seqs) {
+ var cons;
+ if (seqs.length > 1000) {
+ return;
+ }
+ cons = consenusCalc(seqs);
+ this.set("consenus", cons);
+ return cons;
+ }
+});
+
+
+
+},{"../algo/ConsensusCalc":60,"backbone-thin":5}],67:[function(require,module,exports){
+var ColumnSelection, Model, PosSelection, RowSelection, Selection, _;
+
+_ = require("underscore");
+
+Model = require("backbone-thin").Model;
+
+Selection = Model.extend({
+ defaults: {
+ type: "super"
+ }
+});
+
+RowSelection = Selection.extend({
+ defaults: _.extend({}, Selection.prototype.defaults, {
+ type: "row",
+ seqId: ""
+ }),
+ inRow: function(seqId) {
+ return seqId === this.get("seqId");
+ },
+ inColumn: function(rowPos) {
+ return true;
+ },
+ getLength: function() {
+ return 1;
+ }
+});
+
+ColumnSelection = Selection.extend({
+ defaults: _.extend({}, Selection.prototype.defaults, {
+ type: "column",
+ xStart: -1,
+ xEnd: -1
+ }),
+ inRow: function() {
+ return true;
+ },
+ inColumn: function(rowPos) {
+ return xStart <= rowPos && rowPos <= xEnd;
+ },
+ getLength: function() {
+ return xEnd - xStart;
+ }
+});
+
+PosSelection = RowSelection.extend(_.extend({}, _.pick(ColumnSelection, "inColumn"), _.pick(ColumnSelection, "getLength"), {
+ defaults: _.extend({}, ColumnSelection.prototype.defaults, RowSelection.prototype.defaults, {
+ type: "pos"
+ })
+}));
+
+module.exports.sel = Selection;
+
+module.exports.possel = PosSelection;
+
+module.exports.rowsel = RowSelection;
+
+module.exports.columnsel = ColumnSelection;
+
+
+
+},{"backbone-thin":5,"underscore":59}],68:[function(require,module,exports){
+var Collection, SelectionManager, sel, _;
+
+sel = require("./Selection");
+
+_ = require("underscore");
+
+Collection = require("backbone-thin").Collection;
+
+module.exports = SelectionManager = Collection.extend({
+ model: sel.sel,
+ initialize: function(data, opts) {
+ this.g = opts.g;
+ this.listenTo(this.g, "residue:click", function(e) {
+ return this._handleE(e.evt, new sel.possel({
+ xStart: e.rowPos,
+ xEnd: e.rowPos,
+ seqId: e.seqId
+ }));
+ });
+ this.listenTo(this.g, "row:click", function(e) {
+ return this._handleE(e.evt, new sel.rowsel({
+ xStart: e.rowPos,
+ xEnd: e.rowPos,
+ seqId: e.seqId
+ }));
+ });
+ return this.listenTo(this.g, "column:click", function(e) {
+ return this._handleE(e.evt, new sel.columnsel({
+ xStart: e.rowPos,
+ xEnd: e.rowPos + e.stepSize - 1
+ }));
+ });
+ },
+ getSelForRow: function(seqId) {
+ return this.filter(function(el) {
+ return el.inRow(seqId);
+ });
+ },
+ getSelForColumns: function(rowPos) {
+ return this.filter(function(el) {
+ return el.inColumn(rowPos);
+ });
+ },
+ getBlocksForRow: function(seqId, maxLen) {
+ var blocks, seli, selis, _i, _j, _k, _len, _ref, _ref1, _results, _results1;
+ selis = this.filter(function(el) {
+ return el.inRow(seqId);
+ });
+ blocks = [];
+ for (_i = 0, _len = selis.length; _i < _len; _i++) {
+ seli = selis[_i];
+ if (seli.attributes.type === "row") {
+ blocks = (function() {
+ _results = [];
+ for (var _j = 0; 0 <= maxLen ? _j <= maxLen : _j >= maxLen; 0 <= maxLen ? _j++ : _j--){ _results.push(_j); }
+ return _results;
+ }).apply(this);
+ break;
+ } else {
+ blocks = blocks.concat((function() {
+ _results1 = [];
+ for (var _k = _ref = seli.attributes.xStart, _ref1 = seli.attributes.xEnd; _ref <= _ref1 ? _k <= _ref1 : _k >= _ref1; _ref <= _ref1 ? _k++ : _k--){ _results1.push(_k); }
+ return _results1;
+ }).apply(this));
+ }
+ }
+ return blocks;
+ },
+ getAllColumnBlocks: function(conf) {
+ var blocks, filtered, maxLen, seli, withPos, _i, _j, _len, _ref, _ref1, _results;
+ maxLen = conf.maxLen;
+ withPos = conf.withPos;
+ blocks = [];
+ if (conf.withPos) {
+ filtered = this.filter(function(el) {
+ return el.get('xStart') != null;
+ });
+ } else {
+ filtered = this.filter(function(el) {
+ return el.get('type') === "column";
+ });
+ }
+ for (_i = 0, _len = filtered.length; _i < _len; _i++) {
+ seli = filtered[_i];
+ blocks = blocks.concat((function() {
+ _results = [];
+ for (var _j = _ref = seli.attributes.xStart, _ref1 = seli.attributes.xEnd; _ref <= _ref1 ? _j <= _ref1 : _j >= _ref1; _ref <= _ref1 ? _j++ : _j--){ _results.push(_j); }
+ return _results;
+ }).apply(this));
+ }
+ blocks = _.uniq(blocks);
+ return blocks;
+ },
+ invertRow: function(rows) {
+ var el, inverted, s, selRows, _i, _len;
+ selRows = this.where({
+ type: "row"
+ });
+ selRows = _.map(selRows, function(el) {
+ return el.attributes.seqId;
+ });
+ inverted = _.filter(rows, function(el) {
+ if (selRows.indexOf(el) >= 0) {
+ return false;
+ }
+ return true;
+ });
+ s = [];
+ for (_i = 0, _len = inverted.length; _i < _len; _i++) {
+ el = inverted[_i];
+ s.push(new sel.rowsel({
+ seqId: el
+ }));
+ }
+ console.log(s);
+ return this.reset(s);
+ },
+ invertCol: function(columns) {
+ var el, inverted, s, selColumns, xEnd, xStart, _i, _len;
+ selColumns = this.where({
+ type: "column"
+ });
+ selColumns = _.reduce(selColumns, function(memo, el) {
+ var _i, _ref, _ref1, _results;
+ return memo.concat((function() {
+ _results = [];
+ for (var _i = _ref = el.attributes.xStart, _ref1 = el.attributes.xEnd; _ref <= _ref1 ? _i <= _ref1 : _i >= _ref1; _ref <= _ref1 ? _i++ : _i--){ _results.push(_i); }
+ return _results;
+ }).apply(this));
+ }, []);
+ inverted = _.filter(columns, function(el) {
+ if (selColumns.indexOf(el) >= 0) {
+ return false;
+ }
+ return true;
+ });
+ if (inverted.length === 0) {
+ return;
+ }
+ s = [];
+ console.log(inverted);
+ xStart = xEnd = inverted[0];
+ for (_i = 0, _len = inverted.length; _i < _len; _i++) {
+ el = inverted[_i];
+ if (xEnd + 1 === el) {
+ xEnd = el;
+ } else {
+ s.push(new sel.columnsel({
+ xStart: xStart,
+ xEnd: xEnd
+ }));
+ xStart = xEnd = el;
+ }
+ }
+ if (xStart !== xEnd) {
+ s.push(new sel.columnsel({
+ xStart: xStart,
+ xEnd: inverted[inverted.length - 1]
+ }));
+ }
+ return this.reset(s);
+ },
+ _handleE: function(e, selection) {
+ if (e.ctrlKey || e.metaKey) {
+ return this.add(selection);
+ } else {
+ return this.reset([selection]);
+ }
+ },
+ _reduceColumns: function() {
+ return this.each(function(el, index, arr) {
+ var cols, left, lefts, right, rights, xEnd, xStart, _i, _j, _len, _len1;
+ cols = _.filter(arr, function(el) {
+ return el.get('type') === 'column';
+ });
+ xStart = el.get('xStart');
+ xEnd = el.get('xEnd');
+ lefts = _.filter(cols, function(el) {
+ return el.get('xEnd') === (xStart - 1);
+ });
+ for (_i = 0, _len = lefts.length; _i < _len; _i++) {
+ left = lefts[_i];
+ left.set('xEnd', xStart);
+ }
+ rights = _.filter(cols, function(el) {
+ return el.get('xStart') === (xEnd + 1);
+ });
+ for (_j = 0, _len1 = rights.length; _j < _len1; _j++) {
+ right = rights[_j];
+ right.set('xStart', xEnd);
+ }
+ if (lefts.length > 0 || rights.length > 0) {
+ console.log("removed el");
+ return el.collection.remove(el);
+ }
+ });
+ }
+});
+
+
+
+},{"./Selection":67,"backbone-thin":5,"underscore":59}],69:[function(require,module,exports){
+var Model, Visibility;
+
+Model = require("backbone-thin").Model;
+
+module.exports = Visibility = Model.extend({
+ defaults: {
+ overviewBox: 30,
+ headerBox: -1,
+ alignmentBody: 0
+ }
+});
+
+
+
+},{"backbone-thin":5}],70:[function(require,module,exports){
+var Model, Visibility;
+
+Model = require("backbone-thin").Model;
+
+module.exports = Visibility = Model.extend({
+ defaults: {
+ sequences: true,
+ markers: true,
+ metacell: false,
+ conserv: true,
+ overviewbox: false,
+ labels: true,
+ labelName: true,
+ labelId: true,
+ labelPartition: false,
+ labelCheckbox: false
+ }
+});
+
+
+
+},{"backbone-thin":5}],71:[function(require,module,exports){
+var Model, Zoomer;
+
+Model = require("backbone-thin").Model;
+
+module.exports = Zoomer = Model.extend({
+ constructor: function(attributes, options) {
+ Model.apply(this, arguments);
+ this.g = options.g;
+ return this;
+ },
+ defaults: {
+ alignmentWidth: "auto",
+ alignmentHeight: 195,
+ columnWidth: 15,
+ rowHeight: 15,
+ labelWidth: 100,
+ metaWidth: 100,
+ textVisible: true,
+ labelIdLength: 30,
+ labelFontsize: "13px",
+ labelLineHeight: "13px",
+ markerFontsize: "10px",
+ stepSize: 1,
+ markerStepSize: 2,
+ residueFont: "13px mono",
+ canvasEventScale: 1,
+ boxRectHeight: 5,
+ boxRectWidth: 5,
+ menuFontsize: "20px",
+ menuItemFontsize: "18px",
+ menuItemLineHeight: "18px",
+ menuMarginLeft: "5px",
+ menuPadding: "3px 5px 3px 5px",
+ _alignmentScrollLeft: 0,
+ _alignmentScrollTop: 0
+ },
+ getAlignmentWidth: function(n) {
+ if (this.get("alignmentWidth") === "auto") {
+ return this.get("columnWidth") * n;
+ } else {
+ return this.get("alignmentWidth");
+ }
+ },
+ setLeftOffset: function(n) {
+ var val;
+ val = (n - 1) * this.get('columnWidth');
+ val = Math.max(0, val);
+ return this.set("_alignmentScrollLeft", val);
+ },
+ setTopOffset: function(n) {
+ var val;
+ val = (n - 1) * this.get('rowHeight');
+ val = Math.max(0, val);
+ return this.set("_alignmentScrollTop", val);
+ },
+ getLabelWidth: function() {
+ var paddingLeft;
+ paddingLeft = 0;
+ if (this.g.vis.get("labels")) {
+ paddingLeft += this.get("labelWidth");
+ }
+ if (this.g.vis.get("metacell")) {
+ paddingLeft += this.get("metaWidth");
+ }
+ return paddingLeft;
+ },
+ _adjustWidth: function(el, model) {
+ var calcWidth, maxWidth, parentWidth, val;
+ if ((el.parentNode != null) && el.parentNode.offsetWidth !== 0) {
+ parentWidth = el.parentNode.offsetWidth;
+ } else {
+ parentWidth = document.body.clientWidth - 35;
+ }
+ maxWidth = parentWidth - this.getLabelWidth();
+ calcWidth = this.getAlignmentWidth(model.getMaxLength() - this.g.columns.get('hidden').length);
+ val = Math.min(maxWidth, calcWidth);
+ val = Math.floor(val / this.get("columnWidth")) * this.get("columnWidth");
+ return this.set("alignmentWidth", val);
+ },
+ _checkScrolling: function(scrollObj, opts) {
+ var xScroll, yScroll;
+ xScroll = scrollObj[0];
+ yScroll = scrollObj[1];
+ this.set("_alignmentScrollLeft", xScroll, opts);
+ return this.set("_alignmentScrollTop", yScroll, opts);
+ }
+});
+
+
+
+},{"backbone-thin":5}],72:[function(require,module,exports){
+module.exports.msa = require("./msa");
+
+module.exports.model = require("./model");
+
+module.exports.algo = require("./algo");
+
+module.exports.menu = require("./menu");
+
+module.exports.utils = require("./utils");
+
+module.exports.selection = require("./g/selection/Selection");
+
+module.exports.view = require("backbone-viewj");
+
+module.exports.boneView = require("backbone-childs");
+
+module.exports._ = require('underscore');
+
+module.exports.$ = require('jbone');
+
+module.exports.version = "0.1.0";
+
+
+
+},{"./algo":62,"./g/selection/Selection":67,"./menu":74,"./model":89,"./msa":90,"./utils":92,"backbone-childs":3,"backbone-viewj":10,"jbone":50,"underscore":59}],73:[function(require,module,exports){
+var ColorMenu, ExportMenu, ExtraMenu, FilterMenu, HelpMenu, ImportMenu, MenuView, OrderingMenu, SelectionMenu, VisMenu, boneView;
+
+boneView = require("backbone-childs");
+
+ImportMenu = require("./views/ImportMenu");
+
+FilterMenu = require("./views/FilterMenu");
+
+SelectionMenu = require("./views/SelectionMenu");
+
+VisMenu = require("./views/VisMenu");
+
+ColorMenu = require("./views/ColorMenu");
+
+OrderingMenu = require("./views/OrderingMenu");
+
+ExtraMenu = require("./views/ExtraMenu");
+
+ExportMenu = require("./views/ExportMenu");
+
+HelpMenu = require("./views/HelpMenu");
+
+module.exports = MenuView = boneView.extend({
+ initialize: function(data) {
+ this.msa = data.msa;
+ this.addView("10_import", new ImportMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("20_filter", new FilterMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("30_selection", new SelectionMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("40_vis", new VisMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("50_color", new ColorMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("60_ordering", new OrderingMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("70_extra", new ExtraMenu({
+ model: this.msa.seqs,
+ g: this.msa.g
+ }));
+ this.addView("80_export", new ExportMenu({
+ model: this.msa.seqs,
+ g: this.msa.g,
+ msa: this.msa
+ }));
+ return this.addView("90_help", new HelpMenu({
+ g: this.msa.g
+ }));
+ },
+ render: function() {
+ this.renderSubviews();
+ this.el.setAttribute("class", "biojs_msa_menubar");
+ return this.el.appendChild(document.createElement("p"));
+ }
+});
+
+
+
+},{"./views/ColorMenu":76,"./views/ExportMenu":77,"./views/ExtraMenu":78,"./views/FilterMenu":79,"./views/HelpMenu":80,"./views/ImportMenu":81,"./views/OrderingMenu":82,"./views/SelectionMenu":83,"./views/VisMenu":84,"backbone-childs":3}],74:[function(require,module,exports){
+module.exports.defaultmenu = require("./defaultmenu");
+
+module.exports.menubuilder = require("./menubuilder");
+
+
+
+},{"./defaultmenu":73,"./menubuilder":75}],75:[function(require,module,exports){
+var BMath, MenuBuilder, jbone, view;
+
+BMath = require("../utils/bmath");
+
+jbone = require("jbone");
+
+view = require("backbone-viewj");
+
+module.exports = MenuBuilder = view.extend({
+ setName: function(name) {
+ this.name = name;
+ return this._nodes = [];
+ },
+ addNode: function(label, callback, data) {
+ var style;
+ if (data != null) {
+ style = data.style;
+ }
+ if (this._nodes == null) {
+ this._nodes = [];
+ }
+ return this._nodes.push({
+ label: label,
+ callback: callback,
+ style: style
+ });
+ },
+ buildDOM: function() {
+ return this._buildM({
+ nodes: this._nodes,
+ name: this.name
+ });
+ },
+ _buildM: function(data) {
+ var displayedButton, frag, key, li, menu, menuUl, name, node, nodes, style, _i, _len, _ref;
+ nodes = data.nodes;
+ name = data.name;
+ menu = document.createElement("div");
+ menu.className = "dropdown dropdown-tip";
+ menu.id = "adrop-" + BMath.uniqueId();
+ menu.style.display = "none";
+ menuUl = document.createElement("ul");
+ menuUl.className = "dropdown-menu";
+ for (_i = 0, _len = nodes.length; _i < _len; _i++) {
+ node = nodes[_i];
+ li = document.createElement("li");
+ li.textContent = node.label;
+ _ref = node.style;
+ for (key in _ref) {
+ style = _ref[key];
+ li.style[key] = style;
+ }
+ li.addEventListener("click", node.callback);
+ if (this.g != null) {
+ li.style.lineHeight = this.g.zoomer.get("menuItemLineHeight");
+ }
+ menuUl.appendChild(li);
+ }
+ menu.appendChild(menuUl);
+ frag = document.createDocumentFragment();
+ displayedButton = document.createElement("a");
+ displayedButton.textContent = name;
+ displayedButton.className = "biojs_msa_menubar_alink";
+ if (this.g != null) {
+ menuUl.style.fontSize = this.g.zoomer.get("menuItemFontsize");
+ displayedButton.style.fontSize = this.g.zoomer.get("menuFontsize");
+ displayedButton.style.marginLeft = this.g.zoomer.get("menuMarginLeft");
+ displayedButton.style.padding = this.g.zoomer.get("menuPadding");
+ }
+ jbone(displayedButton).on("click", (function(_this) {
+ return function(e) {
+ _this._showMenu(e, menu, displayedButton);
+ return window.setTimeout(function() {
+ return jbone(document.body).one("click", function(e) {
+ console.log("next click");
+ return menu.style.display = "none";
+ });
+ }, 5);
+ };
+ })(this));
+ frag.appendChild(menu);
+ frag.appendChild(displayedButton);
+ return frag;
+ },
+ _showMenu: function(e, menu, target) {
+ var rect;
+ menu.style.display = "block";
+ menu.style.position = "absolute";
+ rect = target.getBoundingClientRect();
+ menu.style.left = rect.left + "px";
+ return menu.style.top = (rect.top + target.offsetHeight) + "px";
+ }
+});
+
+
+
+},{"../utils/bmath":91,"backbone-viewj":10,"jbone":50}],76:[function(require,module,exports){
+var ColorMenu, MenuBuilder, dom, _;
+
+MenuBuilder = require("../menubuilder");
+
+_ = require("underscore");
+
+dom = require("dom-helper");
+
+module.exports = ColorMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.el.style.display = "inline-block";
+ return this.listenTo(this.g.colorscheme, "change", function() {
+ return this.render();
+ });
+ },
+ render: function() {
+ var colorschemes, menuColor, scheme, text, _i, _len;
+ menuColor = this.setName("Color scheme");
+ colorschemes = this.getColorschemes();
+ for (_i = 0, _len = colorschemes.length; _i < _len; _i++) {
+ scheme = colorschemes[_i];
+ this.addScheme(menuColor, scheme);
+ }
+ text = "Background";
+ if (this.g.colorscheme.get("colorBackground")) {
+ text = "Hide " + text;
+ } else {
+ text = "Show " + text;
+ }
+ this.addNode(text, (function(_this) {
+ return function() {
+ return _this.g.colorscheme.set("colorBackground", !_this.g.colorscheme.get("colorBackground"));
+ };
+ })(this));
+ this.grey(menuColor);
+ dom.removeAllChilds(this.el);
+ this.el.appendChild(this.buildDOM());
+ return this;
+ },
+ addScheme: function(menuColor, scheme) {
+ var current, style;
+ style = {};
+ current = this.g.colorscheme.get("scheme");
+ if (current === scheme.id) {
+ style.backgroundColor = "#77ED80";
+ }
+ return this.addNode(scheme.name, (function(_this) {
+ return function() {
+ return _this.g.colorscheme.set("scheme", scheme.id);
+ };
+ })(this), {
+ style: style
+ });
+ },
+ getColorschemes: function() {
+ var schemes;
+ schemes = [];
+ schemes.push({
+ name: "Zappo",
+ id: "zappo"
+ });
+ schemes.push({
+ name: "Taylor",
+ id: "taylor"
+ });
+ schemes.push({
+ name: "Hydrophobicity",
+ id: "hydro"
+ });
+ schemes.push({
+ name: "Lesk",
+ id: "lesk"
+ });
+ schemes.push({
+ name: "Cinema",
+ id: "cinema"
+ });
+ schemes.push({
+ name: "MAE",
+ id: "mae"
+ });
+ schemes.push({
+ name: "Clustal",
+ id: "clustal"
+ });
+ schemes.push({
+ name: "Clustal2",
+ id: "clustal2"
+ });
+ schemes.push({
+ name: "Turn",
+ id: "turn"
+ });
+ schemes.push({
+ name: "Strand",
+ id: "strand"
+ });
+ schemes.push({
+ name: "Buried",
+ id: "buried"
+ });
+ schemes.push({
+ name: "Helix",
+ id: "helix"
+ });
+ schemes.push({
+ name: "Nucleotide",
+ id: "nucleotide"
+ });
+ schemes.push({
+ name: "Purine",
+ id: "purine"
+ });
+ schemes.push({
+ name: "PID",
+ id: "pid"
+ });
+ schemes.push({
+ name: "No color",
+ id: "foo"
+ });
+ return schemes;
+ },
+ grey: function(menuColor) {
+ this.addNode("Grey", (function(_this) {
+ return function() {
+ _this.g.colorscheme.set("showLowerCase", false);
+ return _this.model.each(function(seq) {
+ var grey, residues;
+ residues = seq.get("seq");
+ grey = [];
+ _.each(residues, function(el, index) {
+ if (el === el.toLowerCase()) {
+ return grey.push(index);
+ }
+ });
+ return seq.set("grey", grey);
+ });
+ };
+ })(this));
+ this.addNode("Grey by threshold", (function(_this) {
+ return function() {
+ var conserv, grey, i, maxLen, threshold, _i, _ref;
+ threshold = prompt("Enter threshold (in percent)", 20);
+ threshold = threshold / 100;
+ maxLen = _this.model.getMaxLength();
+ conserv = _this.g.columns.get("conserv");
+ grey = [];
+ for (i = _i = 0, _ref = maxLen - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ console.log(conserv[i]);
+ if (conserv[i] < threshold) {
+ grey.push(i);
+ }
+ }
+ return _this.model.each(function(seq) {
+ return seq.set("grey", grey);
+ });
+ };
+ })(this));
+ this.addNode("Grey selection", (function(_this) {
+ return function() {
+ var maxLen;
+ maxLen = _this.model.getMaxLength();
+ return _this.model.each(function(seq) {
+ var blocks;
+ blocks = _this.g.selcol.getBlocksForRow(seq.get("id"), maxLen);
+ return seq.set("grey", blocks);
+ });
+ };
+ })(this));
+ return this.addNode("Reset grey", (function(_this) {
+ return function() {
+ _this.g.colorscheme.set("showLowerCase", true);
+ return _this.model.each(function(seq) {
+ return seq.set("grey", []);
+ });
+ };
+ })(this));
+ }
+});
+
+
+
+},{"../menubuilder":75,"dom-helper":49,"underscore":59}],77:[function(require,module,exports){
+var ExportMenu, FastaExporter, MenuBuilder, blobURL, saveAs, _;
+
+MenuBuilder = require("../menubuilder");
+
+saveAs = require("browser-saveas");
+
+FastaExporter = require("biojs-io-fasta").writer;
+
+_ = require("underscore");
+
+blobURL = require("blueimp_canvastoblob");
+
+module.exports = ExportMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.msa = data.msa;
+ return this.el.style.display = "inline-block";
+ },
+ render: function() {
+ this.setName("Export");
+ this.addNode("Export sequences", (function(_this) {
+ return function() {
+ var blob, text;
+ text = FastaExporter["export"](_this.model.toJSON());
+ blob = new Blob([text], {
+ type: 'text/plain'
+ });
+ return saveAs(blob, "all.fasta");
+ };
+ })(this));
+ this.addNode("Export selection", (function(_this) {
+ return function() {
+ var blob, i, selection, text, _i, _ref;
+ selection = _this.g.selcol.pluck("seqId");
+ if (selection != null) {
+ selection = _this.model.filter(function(el) {
+ return _.contains(selection, el.get("id"));
+ });
+ for (i = _i = 0, _ref = selection.length - 1; _i <= _ref; i = _i += 1) {
+ selection[i] = selection[i].toJSON();
+ }
+ } else {
+ selection = _this.model.toJSON();
+ console.log("no selection found");
+ }
+ text = FastaExporter["export"](selection);
+ blob = new Blob([text], {
+ type: 'text/plain'
+ });
+ return saveAs(blob, "selection.fasta");
+ };
+ })(this));
+ this.addNode("Export image", (function(_this) {
+ return function() {
+ var canvas, url;
+ canvas = _this.msa.getView('stage').getView('body').getView('seqblock').el;
+ if (canvas != null) {
+ url = canvas.toDataURL('image/png');
+ return saveAs(blobURL(url), "biojs-msa.png", "image/png");
+ }
+ };
+ })(this));
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../menubuilder":75,"biojs-io-fasta":undefined,"blueimp_canvastoblob":46,"browser-saveas":47,"underscore":59}],78:[function(require,module,exports){
+var ExtraMenu, MenuBuilder, Seq, consenus;
+
+MenuBuilder = require("../menubuilder");
+
+consenus = require("../../algo/ConsensusCalc");
+
+Seq = require("../../model/Sequence");
+
+module.exports = ExtraMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ return this.el.style.display = "inline-block";
+ },
+ render: function() {
+ this.setName("Extras");
+ this.addNode("Add consensus seq", (function(_this) {
+ return function() {
+ var con, seq;
+ con = consenus(_this.model);
+ console.log(con);
+ seq = new Seq({
+ seq: con,
+ id: "0c",
+ name: "consenus"
+ });
+ _this.model.add(seq);
+ _this.model.comparator = function(seq) {
+ return seq.get("id");
+ };
+ return _this.model.sort();
+ };
+ })(this));
+ this.addNode("Increase font size", (function(_this) {
+ return function() {
+ _this.g.zoomer.set("columnWidth", _this.g.zoomer.get("columnWidth") + 2);
+ _this.g.zoomer.set("labelWidth", _this.g.zoomer.get("columnWidth") + 5);
+ _this.g.zoomer.set("rowHeight", _this.g.zoomer.get("rowHeight") + 2);
+ return _this.g.zoomer.set("labelFontSize", _this.g.zoomer.get("labelFontSize") + 2);
+ };
+ })(this));
+ this.addNode("Decrease font size", (function(_this) {
+ return function() {
+ _this.g.zoomer.set("columnWidth", _this.g.zoomer.get("columnWidth") - 2);
+ _this.g.zoomer.set("rowHeight", _this.g.zoomer.get("rowHeight") - 2);
+ _this.g.zoomer.set("labelFontSize", _this.g.zoomer.get("labelFontSize") - 2);
+ if (_this.g.zoomer.get("columnWidth") < 8) {
+ return _this.g.zoomer.set("textVisible", false);
+ }
+ };
+ })(this));
+ this.addNode("Bar chart exp scaling", (function(_this) {
+ return function() {
+ return _this.g.columns.set("scaling", "exp");
+ };
+ })(this));
+ this.addNode("Bar chart linear scaling", (function(_this) {
+ return function() {
+ return _this.g.columns.set("scaling", "lin");
+ };
+ })(this));
+ this.addNode("Bar chart log scaling", (function(_this) {
+ return function() {
+ return _this.g.columns.set("scaling", "log");
+ };
+ })(this));
+ this.addNode("Minimized width", (function(_this) {
+ return function() {
+ return _this.g.zoomer.set("alignmentWidth", 600);
+ };
+ })(this));
+ this.addNode("Minimized height", (function(_this) {
+ return function() {
+ return _this.g.zoomer.set("alignmentHeight", 120);
+ };
+ })(this));
+ this.addNode("Jump to a column", (function(_this) {
+ return function() {
+ var offset;
+ offset = prompt("Column", "20");
+ if (offset < 0 || offset > _this.model.getMaxLength() || isNaN(offset)) {
+ alert("invalid column");
+ return;
+ }
+ return _this.g.zoomer.setLeftOffset(offset);
+ };
+ })(this));
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../../algo/ConsensusCalc":60,"../../model/Sequence":88,"../menubuilder":75}],79:[function(require,module,exports){
+var FilterMenu, MenuBuilder, _;
+
+MenuBuilder = require("../menubuilder");
+
+_ = require("underscore");
+
+module.exports = FilterMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ return this.el.style.display = "inline-block";
+ },
+ render: function() {
+ this.setName("Filter");
+ this.addNode("Hide columns by threshold", (function(_this) {
+ return function(e) {
+ var conserv, hidden, i, maxLen, threshold, _i, _ref;
+ threshold = prompt("Enter threshold (in percent)", 20);
+ threshold = threshold / 100;
+ maxLen = _this.model.getMaxLength();
+ hidden = [];
+ conserv = _this.g.columns.get("conserv");
+ for (i = _i = 0, _ref = maxLen - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ if (conserv[i] < threshold) {
+ hidden.push(i);
+ }
+ }
+ return _this.g.columns.set("hidden", hidden);
+ };
+ })(this));
+ this.addNode("Hide columns by selection", (function(_this) {
+ return function() {
+ var hidden, hiddenOld;
+ hiddenOld = _this.g.columns.get("hidden");
+ hidden = hiddenOld.concat(_this.g.selcol.getAllColumnBlocks({
+ maxLen: _this.model.getMaxLength(),
+ withPos: true
+ }));
+ _this.g.selcol.reset([]);
+ return _this.g.columns.set("hidden", hidden);
+ };
+ })(this));
+ this.addNode("Hide columns by gaps", (function(_this) {
+ return function() {
+ var gapContent, gaps, hidden, i, maxLen, threshold, total, _i, _ref;
+ threshold = prompt("Enter threshold (in percent)", 20);
+ threshold = threshold / 100;
+ maxLen = _this.model.getMaxLength();
+ hidden = [];
+ for (i = _i = 0, _ref = maxLen - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ gaps = 0;
+ total = 0;
+ _this.model.each(function(el) {
+ if (el.get('seq')[i] === "-") {
+ gaps++;
+ }
+ return total++;
+ });
+ gapContent = gaps / total;
+ if (gapContent > threshold) {
+ hidden.push(i);
+ }
+ }
+ return _this.g.columns.set("hidden", hidden);
+ };
+ })(this));
+ this.addNode("Hide seqs by identity", (function(_this) {
+ return function() {
+ var threshold;
+ threshold = prompt("Enter threshold (in percent)", 20);
+ threshold = threshold / 100;
+ return _this.model.each(function(el) {
+ if (el.get('identity') < threshold) {
+ return el.set('hidden', true);
+ }
+ });
+ };
+ })(this));
+ this.addNode("Hide seqs by selection", (function(_this) {
+ return function() {
+ var hidden, ids;
+ hidden = _this.g.selcol.where({
+ type: "row"
+ });
+ ids = _.map(hidden, function(el) {
+ return el.get('seqId');
+ });
+ _this.g.selcol.reset([]);
+ return _this.model.each(function(el) {
+ if (ids.indexOf(el.get('id')) >= 0) {
+ return el.set('hidden', true);
+ }
+ });
+ };
+ })(this));
+ this.addNode("Hide seqs by gaps", (function(_this) {
+ return function() {
+ var threshold;
+ threshold = prompt("Enter threshold (in percent)", 40);
+ return _this.model.each(function(el, i) {
+ var gaps, seq;
+ seq = el.get('seq');
+ gaps = _.reduce(seq, (function(memo, c) {
+ if (c === '-') {
+ memo++;
+ }
+ return memo;
+ }), 0);
+ console.log(gaps);
+ if (gaps > threshold) {
+ return el.set('hidden', true);
+ }
+ });
+ };
+ })(this));
+ this.addNode("Reset", (function(_this) {
+ return function() {
+ _this.g.columns.set("hidden", []);
+ return _this.model.each(function(el) {
+ if (el.get('hidden')) {
+ return el.set('hidden', false);
+ }
+ });
+ };
+ })(this));
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../menubuilder":75,"underscore":59}],80:[function(require,module,exports){
+var HelpMenu, MenuBuilder;
+
+MenuBuilder = require("../menubuilder");
+
+module.exports = HelpMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ return this.g = data.g;
+ },
+ render: function() {
+ this.setName("Help");
+ this.addNode("About the project", (function(_this) {
+ return function() {
+ return window.open("https://github.com/greenify/biojs-vis-msa");
+ };
+ })(this));
+ this.addNode("Report issues", (function(_this) {
+ return function() {
+ return window.open("https://github.com/greenify/biojs-vis-msa/issues");
+ };
+ })(this));
+ this.addNode("User manual", (function(_this) {
+ return function() {
+ return window.open("https://github.com/greenify/biojs-vis-msa/wiki");
+ };
+ })(this));
+ this.el.style.display = "inline-block";
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../menubuilder":75}],81:[function(require,module,exports){
+var Clustal, FastaReader, ImportMenu, MenuBuilder, corsURL;
+
+Clustal = require("biojs-io-clustal");
+
+FastaReader = require("biojs-io-fasta").parse;
+
+MenuBuilder = require("../menubuilder");
+
+corsURL = require("../../utils/proxy").corsURL;
+
+module.exports = ImportMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ return this.el.style.display = "inline-block";
+ },
+ render: function() {
+ this.setName("Import");
+ this.addNode("FASTA", (function(_this) {
+ return function(e) {
+ var url;
+ url = prompt("URL", "/test/dummy/samples/p53.clustalo.fasta");
+ url = corsURL(url, _this.g);
+ return FastaReader.read(url, function(seqs) {
+ var zoomer;
+ zoomer = _this.g.zoomer.toJSON();
+ zoomer.labelWidth = 200;
+ zoomer.boxRectHeight = 2;
+ zoomer.boxRectWidth = 2;
+ _this.model.reset([]);
+ _this.g.zoomer.set(zoomer);
+ _this.model.reset(seqs);
+ return _this.g.columns.calcConservation(_this.model);
+ });
+ };
+ })(this));
+ this.addNode("CLUSTAL", (function(_this) {
+ return function() {
+ var url;
+ url = prompt("URL", "/test/dummy/samples/p53.clustalo.clustal");
+ url = corsURL(url, _this.g);
+ return Clustal.read(url, function(seqs) {
+ var zoomer;
+ zoomer = _this.g.zoomer.toJSON();
+ zoomer.labelWidth = 200;
+ zoomer.boxRectHeight = 2;
+ zoomer.boxRectWidth = 2;
+ _this.model.reset([]);
+ _this.g.zoomer.set(zoomer);
+ _this.model.reset(seqs);
+ return _this.g.columns.calcConservation(_this.model);
+ });
+ };
+ })(this));
+ this.addNode("add your own Parser", (function(_this) {
+ return function() {
+ return window.open("https://github.com/biojs/biojs2");
+ };
+ })(this));
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../../utils/proxy":93,"../menubuilder":75,"biojs-io-clustal":undefined,"biojs-io-fasta":undefined}],82:[function(require,module,exports){
+var MenuBuilder, OrderingMenu, dom, _;
+
+MenuBuilder = require("../menubuilder");
+
+dom = require("dom-helper");
+
+_ = require('underscore');
+
+module.exports = OrderingMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.order = "ID";
+ return this.el.style.display = "inline-block";
+ },
+ setOrder: function(order) {
+ this.order = order;
+ return this.render();
+ },
+ render: function() {
+ var comps, el, m, _i, _len;
+ this.setName("Ordering");
+ comps = this.getComparators();
+ for (_i = 0, _len = comps.length; _i < _len; _i++) {
+ m = comps[_i];
+ this._addNode(m);
+ }
+ el = this.buildDOM();
+ dom.removeAllChilds(this.el);
+ this.el.appendChild(el);
+ return this;
+ },
+ _addNode: function(m) {
+ var style, text;
+ text = m.text;
+ style = {};
+ if (text === this.order) {
+ style.backgroundColor = "#77ED80";
+ }
+ return this.addNode(text, (function(_this) {
+ return function() {
+ if (m.precode != null) {
+ m.precode();
+ }
+ _this.model.comparator = m.comparator;
+ _this.model.sort();
+ return _this.setOrder(m.text);
+ };
+ })(this), {
+ style: style
+ });
+ },
+ getComparators: function() {
+ var models;
+ models = [];
+ models.push({
+ text: "ID",
+ comparator: "id"
+ });
+ models.push({
+ text: "ID Desc",
+ comparator: function(a, b) {
+ return -a.get("id").localeCompare(b.get("id"));
+ }
+ });
+ models.push({
+ text: "Label",
+ comparator: "name"
+ });
+ models.push({
+ text: "Label Desc",
+ comparator: function(a, b) {
+ return -a.get("name").localeCompare(b.get("name"));
+ }
+ });
+ models.push({
+ text: "Seq",
+ comparator: "seq"
+ });
+ models.push({
+ text: "Seq Desc",
+ comparator: function(a, b) {
+ return -a.get("seq").localeCompare(b.get("seq"));
+ }
+ });
+ models.push({
+ text: "Identity",
+ comparator: "identity"
+ });
+ models.push({
+ text: "Identity Desc",
+ comparator: function(seq) {
+ return -seq.get("identity");
+ }
+ });
+ models.push({
+ text: "Partition codes",
+ comparator: "partition",
+ precode: (function(_this) {
+ return function() {
+ _this.g.vis.set('labelPartition', true);
+ return _this.model.each(function(el) {
+ return el.set('partition', _.random(1, 3));
+ });
+ };
+ })(this)
+ });
+ return models;
+ }
+});
+
+
+
+},{"../menubuilder":75,"dom-helper":49,"underscore":59}],83:[function(require,module,exports){
+var MenuBuilder, SelectionMenu, sel;
+
+sel = require("../../g/selection/Selection");
+
+MenuBuilder = require("../menubuilder");
+
+module.exports = SelectionMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ return this.el.style.display = "inline-block";
+ },
+ render: function() {
+ this.setName("Selection");
+ this.addNode("Find Motif (supports RegEx)", (function(_this) {
+ return function() {
+ var leftestIndex, newSeli, origIndex, search, selcol;
+ search = prompt("your search", "D");
+ search = new RegExp(search, "gi");
+ selcol = _this.g.selcol;
+ newSeli = [];
+ leftestIndex = origIndex = 100042;
+ _this.model.each(function(seq) {
+ var args, index, match, strSeq, _results;
+ strSeq = seq.get("seq");
+ _results = [];
+ while (match = search.exec(strSeq)) {
+ index = match.index;
+ args = {
+ xStart: index,
+ xEnd: index + match[0].length - 1,
+ seqId: seq.get("id")
+ };
+ newSeli.push(new sel.possel(args));
+ _results.push(leftestIndex = Math.min(index, leftestIndex));
+ }
+ return _results;
+ });
+ if (newSeli.length === 0) {
+ alert("no selection found");
+ }
+ selcol.reset(newSeli);
+ if (leftestIndex === origIndex) {
+ leftestIndex = 0;
+ }
+ return _this.g.zoomer.setLeftOffset(leftestIndex);
+ };
+ })(this));
+ this.addNode("Invert columns", (function(_this) {
+ return function() {
+ var _i, _ref, _results;
+ return _this.g.selcol.invertCol((function() {
+ _results = [];
+ for (var _i = 0, _ref = _this.model.getMaxLength(); 0 <= _ref ? _i <= _ref : _i >= _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }
+ return _results;
+ }).apply(this));
+ };
+ })(this));
+ this.addNode("Invert rows", (function(_this) {
+ return function() {
+ return _this.g.selcol.invertRow(_this.model.pluck("id"));
+ };
+ })(this));
+ this.addNode("Reset", (function(_this) {
+ return function() {
+ return _this.g.selcol.reset();
+ };
+ })(this));
+ this.el.appendChild(this.buildDOM());
+ return this;
+ }
+});
+
+
+
+},{"../../g/selection/Selection":67,"../menubuilder":75}],84:[function(require,module,exports){
+var ImportMenu, MenuBuilder, dom;
+
+MenuBuilder = require("../menubuilder");
+
+dom = require("dom-helper");
+
+module.exports = ImportMenu = MenuBuilder.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.el.style.display = "inline-block";
+ return this.listenTo(this.g.vis, "change", this.render);
+ },
+ render: function() {
+ var visEl, visElements, _i, _len;
+ this.setName("Vis. elements");
+ visElements = this.getVisElements();
+ for (_i = 0, _len = visElements.length; _i < _len; _i++) {
+ visEl = visElements[_i];
+ this._addVisEl(visEl);
+ }
+ this.addNode("Reset", (function(_this) {
+ return function() {
+ _this.g.vis.set("labels", true);
+ _this.g.vis.set("sequences", true);
+ _this.g.vis.set("metacell", true);
+ _this.g.vis.set("conserv", true);
+ _this.g.vis.set("labelId", true);
+ _this.g.vis.set("labelName", true);
+ return _this.g.vis.set("labelCheckbox", false);
+ };
+ })(this));
+ this.addNode("Toggle mouseover events", (function(_this) {
+ return function() {
+ return _this.g.config.set("registerMouseHover", !_this.g.config.get("registerMouseHover"));
+ };
+ })(this));
+ dom.removeAllChilds(this.el);
+ this.el.appendChild(this.buildDOM());
+ return this;
+ },
+ _addVisEl: function(visEl) {
+ var pre, style;
+ style = {};
+ if (this.g.vis.get(visEl.id)) {
+ pre = "Hide ";
+ style.color = "red";
+ } else {
+ pre = "Show ";
+ style.color = "green";
+ }
+ return this.addNode(pre + visEl.name, (function(_this) {
+ return function() {
+ return _this.g.vis.set(visEl.id, !_this.g.vis.get(visEl.id));
+ };
+ })(this), {
+ style: style
+ });
+ },
+ getVisElements: function() {
+ var vis;
+ vis = [];
+ vis.push({
+ name: "Markers",
+ id: "markers"
+ });
+ vis.push({
+ name: "Labels",
+ id: "labels"
+ });
+ vis.push({
+ name: "Sequences",
+ id: "sequences"
+ });
+ vis.push({
+ name: "Meta info",
+ id: "metacell"
+ });
+ vis.push({
+ name: "Overviewbox",
+ id: "overviewbox"
+ });
+ vis.push({
+ name: "conserv",
+ id: "conserv"
+ });
+ vis.push({
+ name: "LabelName",
+ id: "labelName"
+ });
+ vis.push({
+ name: "LabelId",
+ id: "labelId"
+ });
+ vis.push({
+ name: "LabelCheckbox",
+ id: "labelCheckbox"
+ });
+ return vis;
+ }
+});
+
+
+
+},{"../menubuilder":75,"dom-helper":49}],85:[function(require,module,exports){
+var Feature, Model;
+
+Feature = require("./Feature");
+
+Model = require("backbone-thin").Model;
+
+module.exports = Feature = Model.extend({
+ defaults: {
+ xStart: -1,
+ xEnd: -1,
+ height: -1,
+ text: "",
+ fillColor: "red",
+ fillOpacity: 0.5,
+ type: "rectangle",
+ borderSize: 1,
+ borderColor: "black",
+ borderOpacity: 0.5,
+ validate: true
+ },
+ validate: function() {
+ if (isNaN(this.attributes.xStart || isNaN(this.attributes.xEnd))) {
+ return "features need integer start and end.";
+ }
+ },
+ contains: function(index) {
+ return this.attributes.xStart <= index && index <= this.attributes.xEnd;
+ }
+});
+
+
+
+},{"./Feature":85,"backbone-thin":5}],86:[function(require,module,exports){
+var Collection, Feature, FeatureCol, _;
+
+Feature = require("./Feature");
+
+Collection = require("backbone-thin").Collection;
+
+_ = require("underscore");
+
+module.exports = FeatureCol = Collection.extend({
+ model: Feature,
+ constructor: function() {
+ this.startOnCache = [];
+ this.on("all", function() {
+ return this.startOnCache = [];
+ }, this);
+ return Collection.apply(this, arguments);
+ },
+ startOn: function(index) {
+ if (this.startOnCache[index] == null) {
+ this.startOnCache[index] = this.where({
+ xStart: index
+ });
+ }
+ return this.startOnCache[index];
+ },
+ contains: function(index) {
+ return this.reduce(function(el, memo) {
+ return memo || el.contains(index);
+ }, false);
+ },
+ getMinRows: function() {
+ var len, rows, x;
+ len = this.max(function(el) {
+ return el.get("xEnd");
+ });
+ rows = (function() {
+ var _i, _results;
+ _results = [];
+ for (x = _i = 1; 1 <= len ? _i <= len : _i >= len; x = 1 <= len ? ++_i : --_i) {
+ _results.push(0);
+ }
+ return _results;
+ })();
+ this.each(function(el) {
+ var _i, _ref, _ref1, _results;
+ _results = [];
+ for (x = _i = _ref = el.get("xStart"), _ref1 = feature.get("xEnd"); _i <= _ref1; x = _i += 1) {
+ _results.push(rows[x]++);
+ }
+ return _results;
+ });
+ return _.max(rows);
+ }
+});
+
+
+
+},{"./Feature":85,"backbone-thin":5,"underscore":59}],87:[function(require,module,exports){
+var Collection, SeqManager, Sequence;
+
+Sequence = require("./Sequence");
+
+Collection = require("backbone-thin").Collection;
+
+module.exports = SeqManager = Collection.extend({
+ model: Sequence,
+ constructor: function() {
+ Collection.apply(this, arguments);
+ this.on("all", function() {
+ return this.lengthCache = null;
+ }, this);
+ this.lengthCache = null;
+ return this;
+ },
+ getMaxLength: function() {
+ if (this.models.length === 0) {
+ return 0;
+ }
+ if (this.lengthCache === null) {
+ this.lengthCache = this.max(function(seq) {
+ return seq.get("seq").length;
+ }).get("seq").length;
+ }
+ return this.lengthCache;
+ },
+ prev: function(model, endless) {
+ var index;
+ index = this.indexOf(model) - 1;
+ if (index < 0 && endless) {
+ index = this.length - 1;
+ }
+ return this.at(index);
+ },
+ next: function(model, endless) {
+ var index;
+ index = this.indexOf(model) + 1;
+ if (index === this.length && endless) {
+ index = 0;
+ }
+ return this.at(index);
+ },
+ calcHiddenSeqs: function(n) {
+ var i, nNew, _i;
+ nNew = n;
+ for (i = _i = 0; 0 <= nNew ? _i <= nNew : _i >= nNew; i = 0 <= nNew ? ++_i : --_i) {
+ if (this.at(i).get("hidden")) {
+ nNew++;
+ }
+ }
+ return nNew - n;
+ }
+});
+
+
+
+},{"./Sequence":88,"backbone-thin":5}],88:[function(require,module,exports){
+var FeatureCol, Model, Sequence;
+
+Model = require("backbone-thin").Model;
+
+FeatureCol = require("./FeatureCol");
+
+module.exports = Sequence = Model.extend({
+ defaults: {
+ name: "",
+ id: "",
+ seq: ""
+ },
+ initialize: function() {
+ this.set("grey", []);
+ return this.set("features", new FeatureCol());
+ }
+});
+
+
+
+},{"./FeatureCol":86,"backbone-thin":5}],89:[function(require,module,exports){
+module.exports.seq = require("./Sequence");
+
+module.exports.seqcol = require("./SeqCollection");
+
+module.exports.feature = require("./Feature");
+
+module.exports.featurecol = require("./FeatureCol");
+
+
+
+},{"./Feature":85,"./FeatureCol":86,"./SeqCollection":87,"./Sequence":88}],90:[function(require,module,exports){
+var Colorator, Columns, Config, Consensus, Eventhandler, SelCol, SeqCollection, Stage, VisOrdering, Visibility, Zoomer, boneView;
+
+SeqCollection = require("./model/SeqCollection");
+
+Colorator = require("./g/colorator");
+
+Consensus = require("./g/consensus");
+
+Columns = require("./g/columns");
+
+Config = require("./g/config");
+
+SelCol = require("./g/selection/SelectionCol");
+
+Visibility = require("./g/visibility");
+
+VisOrdering = require("./g/visOrdering");
+
+Zoomer = require("./g/zoomer");
+
+boneView = require("backbone-childs");
+
+Eventhandler = require("biojs-events");
+
+Stage = require("./views/Stage");
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ var _ref;
+ if (data.columns == null) {
+ data.columns = {};
+ }
+ if (data.conf == null) {
+ data.conf = {};
+ }
+ if (data.vis == null) {
+ data.vis = {};
+ }
+ if (data.zoomer == null) {
+ if (!((_ref = data.visorder) != null ? _ref : data.zoomer = {})) {
+ data.visorder = {};
+ }
+ }
+ this.g = Eventhandler.mixin({});
+ if (data.seqs === void 0 || data.seqs.length === 0) {
+ console.log("warning. empty seqs.");
+ }
+ this.seqs = new SeqCollection(data.seqs);
+ this.g.config = new Config(data.conf);
+ this.g.consensus = new Consensus();
+ this.g.columns = new Columns(data.columns);
+ this.g.colorscheme = new Colorator();
+ this.g.selcol = new SelCol([], {
+ g: this.g
+ });
+ this.g.vis = new Visibility(data.vis);
+ this.g.visorder = new VisOrdering(data.visorder);
+ this.g.zoomer = new Zoomer(data.zoomer, {
+ g: this.g
+ });
+ this.addView("stage", new Stage({
+ model: this.seqs,
+ g: this.g
+ }));
+ this.el.setAttribute("class", "biojs_msa_div");
+ if (this.g.config.get("eventBus") === true) {
+ return this.startEventBus();
+ }
+ },
+ startEventBus: function() {
+ var busObjs, key, _i, _len, _results;
+ busObjs = ["config", "consensus", "columns", "colorscheme", "selcol", "vis", "visorder", "zoomer"];
+ _results = [];
+ for (_i = 0, _len = busObjs.length; _i < _len; _i++) {
+ key = busObjs[_i];
+ _results.push(this._proxyToG(key));
+ }
+ return _results;
+ },
+ _proxyToG: function(key) {
+ return this.listenTo(this.g[key], "all", function(name, prev, now) {
+ if (name === "change") {
+ return;
+ }
+ return this.g.trigger(key + ":" + name, now);
+ });
+ },
+ render: function() {
+ this.renderSubviews();
+ this.g.vis.set("loaded", true);
+ return this;
+ }
+});
+
+
+
+},{"./g/colorator":63,"./g/columns":64,"./g/config":65,"./g/consensus":66,"./g/selection/SelectionCol":68,"./g/visOrdering":69,"./g/visibility":70,"./g/zoomer":71,"./model/SeqCollection":87,"./views/Stage":100,"backbone-childs":3,"biojs-events":14}],91:[function(require,module,exports){
+var BMath;
+
+module.exports = BMath = (function() {
+ function BMath() {}
+
+ BMath.randomInt = function(lower, upper) {
+ var _ref, _ref1;
+ if (upper == null) {
+ _ref = [0, lower], lower = _ref[0], upper = _ref[1];
+ }
+ if (lower > upper) {
+ _ref1 = [upper, lower], lower = _ref1[0], upper = _ref1[1];
+ }
+ return Math.floor(Math.random() * (upper - lower + 1) + lower);
+ };
+
+ BMath.uniqueId = function(length) {
+ var id;
+ if (length == null) {
+ length = 8;
+ }
+ id = "";
+ while (id.length < length) {
+ id += Math.random().toString(36).substr(2);
+ }
+ return id.substr(0, length);
+ };
+
+ BMath.getRandomInt = function(min, max) {
+ return Math.floor(Math.random() * (max - min + 1)) + min;
+ };
+
+ return BMath;
+
+})();
+
+
+
+},{}],92:[function(require,module,exports){
+module.exports.bmath = require("./bmath");
+
+module.exports.proxy = require("./proxy");
+
+module.exports.seqgen = require("./seqgen");
+
+
+
+},{"./bmath":91,"./proxy":93,"./seqgen":94}],93:[function(require,module,exports){
+var proxy;
+
+module.exports = proxy = {
+ corsURL: (function(_this) {
+ return function(url, g) {
+ _this.g = g;
+ if (document.URL.indexOf('localhost') >= 0 && url[0] === "/") {
+ return url;
+ }
+ url = url.replace("www\.", "");
+ url = url.replace("http://", "");
+ url = _this.g.config.get('importProxy') + url;
+ return url;
+ };
+ })(this)
+};
+
+
+
+},{}],94:[function(require,module,exports){
+var BMath, Sequence, seqgen;
+
+Sequence = require("biojs-model").seq;
+
+BMath = require("./bmath");
+
+seqgen = module.exports = {
+ _generateSequence: function(len) {
+ var i, possible, text, _i, _ref;
+ text = "";
+ possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ for (i = _i = 0, _ref = len - 1; _i <= _ref; i = _i += 1) {
+ text += possible.charAt(Math.floor(Math.random() * possible.length));
+ }
+ return text;
+ },
+ getDummySequences: function(len, seqLen) {
+ var i, seqs, _i;
+ seqs = [];
+ if (len == null) {
+ len = BMath.getRandomInt(3, 5);
+ }
+ if (seqLen == null) {
+ seqLen = BMath.getRandomInt(50, 200);
+ }
+ for (i = _i = 1; _i <= len; i = _i += 1) {
+ seqs.push(new Sequence(seqgen._generateSequence(seqLen), "seq" + i, "r" + i));
+ }
+ return seqs;
+ }
+};
+
+
+
+},{"./bmath":91,"biojs-model":27}],95:[function(require,module,exports){
+var Base, Line, Polygon, Rect, setAttr, svgns;
+
+svgns = "http://www.w3.org/2000/svg";
+
+setAttr = function(obj, opts) {
+ var name, value;
+ for (name in opts) {
+ value = opts[name];
+ obj.setAttributeNS(null, name, value);
+ }
+ return obj;
+};
+
+Base = function(opts) {
+ var svg;
+ svg = document.createElementNS(svgns, 'svg');
+ svg.setAttribute("width", opts.width);
+ svg.setAttribute("height", opts.height);
+ return svg;
+};
+
+Rect = function(opts) {
+ var rect;
+ rect = document.createElementNS(svgns, 'rect');
+ return setAttr(rect, opts);
+};
+
+Line = function(opts) {
+ var line;
+ line = document.createElementNS(svgns, 'line');
+ return setAttr(line, opts);
+};
+
+Polygon = function(opts) {
+ var line;
+ line = document.createElementNS(svgns, 'polygon');
+ return setAttr(line, opts);
+};
+
+module.exports.rect = Rect;
+
+module.exports.line = Line;
+
+module.exports.polygon = Polygon;
+
+module.exports.base = Base;
+
+
+
+},{}],96:[function(require,module,exports){
+var LabelBlock, SeqBlock, boneView;
+
+boneView = require("backbone-childs");
+
+SeqBlock = require("./CanvasSeqBlock");
+
+LabelBlock = require("./labels/LabelBlock");
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ var labelblock, seqblock;
+ this.g = data.g;
+ if (true) {
+ labelblock = new LabelBlock({
+ model: this.model,
+ g: this.g
+ });
+ labelblock.ordering = -1;
+ this.addView("labelblock", labelblock);
+ }
+ if (this.g.vis.get("sequences")) {
+ seqblock = new SeqBlock({
+ model: this.model,
+ g: this.g
+ });
+ seqblock.ordering = 0;
+ this.addView("seqblock", seqblock);
+ }
+ this.listenTo(this.g.zoomer, "change:alignmentHeight", this.adjustHeight);
+ return this.listenTo(this.g.columns, "change:hidden", this.adjustHeight);
+ },
+ render: function() {
+ this.renderSubviews();
+ this.el.className = "biojs_msa_albody";
+ this.el.style.whiteSpace = "nowrap";
+ this.adjustHeight();
+ return this;
+ },
+ adjustHeight: function() {
+ if (this.g.zoomer.get("alignmentHeight") === "auto") {
+ this.el.style.height = (this.g.zoomer.get("rowHeight") * this.model.length) + 5;
+ } else {
+ this.el.style.height = this.g.zoomer.get("alignmentHeight");
+ }
+ return this.el.style.width = this.getWidth() + 15;
+ },
+ getWidth: function() {
+ var width;
+ width = 0;
+ if (this.g.vis.get("labels")) {
+ width += this.g.zoomer.get("labelWidth");
+ }
+ if (this.g.vis.get("metacell")) {
+ width += this.g.zoomer.get("metaWidth");
+ }
+ if (this.g.vis.get("sequences")) {
+ width += this.g.zoomer.get("alignmentWidth");
+ }
+ return width;
+ }
+});
+
+
+
+},{"./CanvasSeqBlock":98,"./labels/LabelBlock":104,"backbone-childs":3}],97:[function(require,module,exports){
+var CanvasCharCache, Events;
+
+Events = require("biojs-events");
+
+module.exports = CanvasCharCache = (function() {
+ function CanvasCharCache(g) {
+ this.g = g;
+ this.cache = {};
+ this.cacheHeight = 0;
+ this.cacheWidth = 0;
+ }
+
+ CanvasCharCache.prototype.getFontTile = function(letter, width, height) {
+ if (width !== this.cacheWidth || height !== this.cacheHeight) {
+ this.cacheHeight = height;
+ this.cacheWidth = width;
+ this.cache = {};
+ }
+ if (this.cache[letter] === void 0) {
+ this.createTile(letter, width, height);
+ }
+ return this.cache[letter];
+ };
+
+ CanvasCharCache.prototype.createTile = function(letter, width, height) {
+ var canvas;
+ canvas = this.cache[letter] = document.createElement("canvas");
+ canvas.width = width;
+ canvas.height = height;
+ this.ctx = canvas.getContext('2d');
+ this.ctx.font = this.g.zoomer.get("residueFont");
+ this.ctx.textBaseline = 'middle';
+ this.ctx.textAlign = "center";
+ return this.ctx.fillText(letter, width / 2, height / 2, width);
+ };
+
+ return CanvasCharCache;
+
+})();
+
+
+
+},{"biojs-events":14}],98:[function(require,module,exports){
+var CharCache, boneView, colorSelector, jbone, mouse, _;
+
+boneView = require("backbone-childs");
+
+mouse = require("mouse-pos");
+
+colorSelector = require("biojs-util-colorschemes").selector;
+
+_ = require("underscore");
+
+jbone = require("jbone");
+
+CharCache = require("./CanvasCharCache");
+
+module.exports = boneView.extend({
+ tagName: "canvas",
+ initialize: function(data) {
+ this.g = data.g;
+ this.listenTo(this.g.zoomer, "change:_alignmentScrollLeft change:_alignmentScrollTop", function(model, value, options) {
+ if (((options != null ? options.origin : void 0) == null) || options.origin !== "canvasseq") {
+ return this.render();
+ }
+ });
+ this.listenTo(this.g.columns, "change:hidden", this.render);
+ this.listenTo(this.g.zoomer, "change:alignmentWidth", this.render);
+ this.listenTo(this.g.colorscheme, "change", this.render);
+ this.listenTo(this.g.selcol, "reset add", this.render);
+ this.el.style.display = "inline-block";
+ this.el.style.overflowX = "hidden";
+ this.el.style.overflowY = "hidden";
+ this.el.className = "biojs_msa_seqblock";
+ this.ctx = this.el.getContext('2d');
+ this.cache = new CharCache(this.g);
+ this.throttleTime = 0;
+ this.throttleCounts = 0;
+ if (document.documentElement.style.webkitAppearance != null) {
+ this.throttledDraw = function() {
+ var start, tTime;
+ start = +new Date();
+ this.draw();
+ this.throttleTime += +new Date() - start;
+ this.throttleCounts++;
+ if (this.throttleCounts > 15) {
+ tTime = Math.ceil(this.throttleTime / this.throttleCounts);
+ console.log("avgDrawTime/WebKit", tTime);
+ return this.throttledDraw = this.draw;
+ }
+ };
+ } else {
+ this.throttledDraw = _.throttle(this.throttledDraw, 30);
+ }
+ return this.manageEvents();
+ },
+ throttledDraw: function() {
+ var start, tTime;
+ start = +new Date();
+ this.draw();
+ this.throttleTime += +new Date() - start;
+ this.throttleCounts++;
+ if (this.throttleCounts > 15) {
+ tTime = Math.ceil(this.throttleTime / this.throttleCounts);
+ console.log("avgDrawTime", tTime);
+ tTime *= 1.2;
+ tTime = Math.max(20, tTime);
+ return this.throttledDraw = _.throttle(this.draw, tTime);
+ }
+ },
+ manageEvents: function() {
+ var events;
+ events = {};
+ events.mousedown = "_onmousedown";
+ events.touchstart = "_ontouchstart";
+ if (this.g.config.get("registerMouseClicks")) {
+ events.dblclick = "_onclick";
+ }
+ if (this.g.config.get("registerMouseHover")) {
+ events.mousein = "_onmousein";
+ events.mouseout = "_onmouseout";
+ }
+ events.mousewheel = "_onmousewheel";
+ events.DOMMouseScroll = "_onmousewheel";
+ this.delegateEvents(events);
+ this.listenTo(this.g.config, "change:registerMouseHover", this.manageEvents);
+ this.listenTo(this.g.config, "change:registerMouseClick", this.manageEvents);
+ return this.dragStart = [];
+ },
+ draw: function() {
+ var rectHeight;
+ this.el.width = this.el.width;
+ rectHeight = this.g.zoomer.get("rowHeight");
+ this.ctx.globalAlpha = this.g.colorscheme.get("opacity");
+ this.drawSeqs(function(data) {
+ return this.drawSeq(data, this._drawRect);
+ });
+ this.ctx.globalAlpha = 1;
+ this.drawSeqs(function(data) {
+ return this.drawSeq(data, this._drawLetter);
+ });
+ return this.drawSeqs(this.drawSeqExtended);
+ },
+ drawSeqs: function(callback) {
+ var hidden, i, rectHeight, start, y, _i, _ref, _results;
+ rectHeight = this.g.zoomer.get("rowHeight");
+ hidden = this.g.columns.get("hidden");
+ start = Math.max(0, Math.abs(Math.ceil(-this.g.zoomer.get('_alignmentScrollTop') / rectHeight)));
+ y = -Math.abs(-this.g.zoomer.get('_alignmentScrollTop') % rectHeight);
+ _results = [];
+ for (i = _i = start, _ref = this.model.length - 1; _i <= _ref; i = _i += 1) {
+ if (this.model.at(i).get('hidden')) {
+ continue;
+ }
+ callback.call(this, {
+ model: this.model.at(i),
+ y: y,
+ hidden: hidden
+ });
+ y = y + rectHeight;
+ if (y > this.el.height) {
+ break;
+ } else {
+ _results.push(void 0);
+ }
+ }
+ return _results;
+ },
+ drawSeq: function(data, callback) {
+ var c, elWidth, j, rectHeight, rectWidth, res, seq, start, x, y, _i, _ref, _results;
+ seq = data.model.get("seq");
+ y = data.y;
+ rectWidth = this.g.zoomer.get("columnWidth");
+ rectHeight = this.g.zoomer.get("rowHeight");
+ start = Math.max(0, Math.abs(Math.ceil(-this.g.zoomer.get('_alignmentScrollLeft') / rectWidth)));
+ x = -Math.abs(-this.g.zoomer.get('_alignmentScrollLeft') % rectWidth);
+ res = {
+ rectWidth: rectWidth,
+ rectHeight: rectHeight,
+ y: y
+ };
+ elWidth = this.el.width;
+ _results = [];
+ for (j = _i = start, _ref = seq.length - 1; _i <= _ref; j = _i += 1) {
+ c = seq[j];
+ c = c.toUpperCase();
+ res.x = x;
+ res.c = c;
+ if (data.hidden.indexOf(j) < 0) {
+ callback(this, res);
+ } else {
+ continue;
+ }
+ x = x + rectWidth;
+ if (x > elWidth) {
+ break;
+ } else {
+ _results.push(void 0);
+ }
+ }
+ return _results;
+ },
+ _drawRect: function(that, data) {
+ var color;
+ color = that.color[data.c];
+ if (color != null) {
+ that.ctx.fillStyle = color;
+ return that.ctx.fillRect(data.x, data.y, data.rectWidth, data.rectHeight);
+ }
+ },
+ _drawLetter: function(that, data) {
+ return that.ctx.drawImage(that.cache.getFontTile(data.c, data.rectWidth, data.rectHeight), data.x, data.y, data.rectWidth, data.rectHeight);
+ },
+ drawSeqExtended: function(data) {
+ var f, features, j, mNextSel, mPrevSel, rectHeight, rectWidth, selection, seq, start, starts, x, xZero, yZero, _i, _j, _len, _ref, _ref1;
+ seq = data.model.get("seq");
+ rectWidth = this.g.zoomer.get("columnWidth");
+ rectHeight = this.g.zoomer.get("rowHeight");
+ start = Math.max(0, Math.abs(Math.ceil(-this.g.zoomer.get('_alignmentScrollLeft') / rectWidth)));
+ x = -Math.abs(-this.g.zoomer.get('_alignmentScrollLeft') % rectWidth);
+ xZero = x - start * rectWidth;
+ selection = this._getSelection(data.model);
+ _ref = this._getPrevNextSelection(data.model), mPrevSel = _ref[0], mNextSel = _ref[1];
+ features = data.model.get("features");
+ yZero = data.y;
+ for (j = _i = start, _ref1 = seq.length - 1; _i <= _ref1; j = _i += 1) {
+ starts = features.startOn(j);
+ if (data.hidden.indexOf(j) >= 0) {
+ continue;
+ }
+ if (starts.length > 0) {
+ for (_j = 0, _len = starts.length; _j < _len; _j++) {
+ f = starts[_j];
+ this.appendFeature({
+ f: f,
+ xZero: x,
+ yZero: yZero
+ });
+ }
+ }
+ x = x + rectWidth;
+ if (x > this.el.width) {
+ break;
+ }
+ }
+ return this._appendSelection({
+ model: data.model,
+ xZero: xZero,
+ yZero: yZero,
+ hidden: data.hidden
+ });
+ },
+ render: function() {
+ this.el.setAttribute('height', this.g.zoomer.get("alignmentHeight"));
+ this.el.setAttribute('width', this.g.zoomer.get("alignmentWidth"));
+ this.g.zoomer._adjustWidth(this.el, this.model);
+ this.g.zoomer._checkScrolling(this._checkScrolling([this.g.zoomer.get('_alignmentScrollLeft'), this.g.zoomer.get('_alignmentScrollTop')]), {
+ header: "canvasseq"
+ });
+ this.color = colorSelector.getColor(this.g.colorscheme.get("scheme"));
+ this.throttledDraw();
+ return this;
+ },
+ _onmousemove: function(e, reversed) {
+ var dragEnd, i, relDist, relEnd, scaleFactor, scrollCorrected, _i, _j, _k;
+ if (this.dragStart.length === 0) {
+ return;
+ }
+ dragEnd = mouse.abs(e);
+ relEnd = [dragEnd[0] - this.dragStart[0], dragEnd[1] - this.dragStart[1]];
+ scaleFactor = this.g.zoomer.get("canvasEventScale");
+ if (reversed) {
+ scaleFactor = 3;
+ }
+ for (i = _i = 0; _i <= 1; i = _i += 1) {
+ relEnd[i] = relEnd[i] * scaleFactor;
+ }
+ relDist = [this.dragStartScroll[0] - relEnd[0], this.dragStartScroll[1] - relEnd[1]];
+ for (i = _j = 0; _j <= 1; i = _j += 1) {
+ relDist[i] = Math.round(relDist[i]);
+ }
+ scrollCorrected = this._checkScrolling(relDist);
+ this.g.zoomer._checkScrolling(scrollCorrected, {
+ origin: "canvasseq"
+ });
+ for (i = _k = 0; _k <= 1; i = _k += 1) {
+ if (scrollCorrected[i] !== relDist[i]) {
+ if (scrollCorrected[i] === 0) {
+ this.dragStart[i] = dragEnd[i];
+ this.dragStartScroll[i] = 0;
+ } else {
+ this.dragStart[i] = dragEnd[i] - scrollCorrected[i];
+ }
+ }
+ }
+ this.throttledDraw();
+ if (e.preventDefault != null) {
+ e.preventDefault();
+ return e.stopPropagation();
+ }
+ },
+ _ontouchmove: function(e) {
+ this._onmousemove(e.changedTouches[0], true);
+ e.preventDefault();
+ return e.stopPropagation();
+ },
+ _onmousedown: function(e) {
+ this.dragStart = mouse.abs(e);
+ this.dragStartScroll = [this.g.zoomer.get('_alignmentScrollLeft'), this.g.zoomer.get('_alignmentScrollTop')];
+ jbone(document.body).on('mousemove.overmove', (function(_this) {
+ return function(e) {
+ return _this._onmousemove(e);
+ };
+ })(this));
+ jbone(document.body).on('mouseup.overup', (function(_this) {
+ return function() {
+ return _this._cleanup();
+ };
+ })(this));
+ return e.preventDefault();
+ },
+ _ontouchstart: function(e) {
+ this.dragStart = mouse.abs(e.changedTouches[0]);
+ this.dragStartScroll = [this.g.zoomer.get('_alignmentScrollLeft'), this.g.zoomer.get('_alignmentScrollTop')];
+ jbone(document.body).on('touchmove.overtmove', (function(_this) {
+ return function(e) {
+ return _this._ontouchmove(e);
+ };
+ })(this));
+ return jbone(document.body).on('touchend.overtend touchleave.overtleave touchcancel.overtcanel', (function(_this) {
+ return function(e) {
+ return _this._touchCleanup(e);
+ };
+ })(this));
+ },
+ _onmousewinout: function(e) {
+ if (e.toElement === document.body.parentNode) {
+ return this._cleanup();
+ }
+ },
+ _cleanup: function() {
+ this.dragStart = [];
+ jbone(document.body).off('.overmove');
+ jbone(document.body).off('.overup');
+ return jbone(document.body).off('.overout');
+ },
+ _touchCleanup: function(e) {
+ if (e.changedTouches.length > 0) {
+ this._onmousemove(e.changedTouches[0], true);
+ }
+ this.dragStart = [];
+ jbone(document.body).off('.overtmove');
+ jbone(document.body).off('.overtend');
+ jbone(document.body).off('.overtleave');
+ return jbone(document.body).off('.overtcancel');
+ },
+ _onmousewheel: function(e) {
+ var delta;
+ delta = mouse.wheelDelta(e);
+ this.g.zoomer.set('_alignmentScrollLeft', this.g.zoomer.get('_alignmentScrollLeft') + delta[0]);
+ this.g.zoomer.set('_alignmentScrollTop', this.g.zoomer.get('_alignmentScrollTop') + delta[1]);
+ return e.preventDefault();
+ },
+ _onclick: function(e) {
+ this.g.trigger("residue:click", this._getClickPos(e));
+ return this.throttledDraw();
+ },
+ _onmousein: function(e) {
+ this.g.trigger("residue:click", this._getClickPos(e));
+ return this.throttledDraw();
+ },
+ _onmouseout: function(e) {
+ this.g.trigger("residue:click", this._getClickPos(e));
+ return this.throttledDraw();
+ },
+ _getClickPos: function(e) {
+ var coords, seqId, x, y;
+ coords = mouse.rel(e);
+ coords[0] += this.g.zoomer.get("_alignmentScrollLeft");
+ coords[1] += this.g.zoomer.get("_alignmentScrollTop");
+ x = Math.floor(coords[0] / this.g.zoomer.get("columnWidth"));
+ y = Math.floor(coords[1] / this.g.zoomer.get("rowHeight"));
+ x += this.g.columns.calcHiddenColumns(x);
+ y += this.model.calcHiddenSeqs(y);
+ x = Math.max(0, x);
+ y = Math.max(0, y);
+ seqId = this.model.at(y).get("id");
+ return {
+ seqId: seqId,
+ rowPos: x,
+ evt: e
+ };
+ },
+ _checkScrolling: function(scrollObj) {
+ var i, max, _i;
+ max = [this.model.getMaxLength() * this.g.zoomer.get("columnWidth") - this.g.zoomer.get('alignmentWidth'), this.model.length * this.g.zoomer.get("rowHeight") - this.g.zoomer.get('alignmentHeight')];
+ for (i = _i = 0; _i <= 1; i = _i += 1) {
+ if (scrollObj[i] > max[i]) {
+ scrollObj[i] = max[i];
+ }
+ if (scrollObj[i] < 0) {
+ scrollObj[i] = 0;
+ }
+ }
+ return scrollObj;
+ },
+ _getSelection: function(model) {
+ var maxLen, n, rows, sel, selection, sels, _i, _j, _k, _len, _ref, _ref1, _ref2;
+ maxLen = model.get("seq").length;
+ selection = [];
+ sels = this.g.selcol.getSelForRow(model.get("id"));
+ rows = _.find(sels, function(el) {
+ return el.get("type") === "row";
+ });
+ if (rows != null) {
+ for (n = _i = 0, _ref = maxLen - 1; _i <= _ref; n = _i += 1) {
+ selection.push(n);
+ }
+ } else if (sels.length > 0) {
+ for (_j = 0, _len = sels.length; _j < _len; _j++) {
+ sel = sels[_j];
+ for (n = _k = _ref1 = sel.get("xStart"), _ref2 = sel.get("xEnd"); _k <= _ref2; n = _k += 1) {
+ selection.push(n);
+ }
+ }
+ }
+ return selection;
+ },
+ appendFeature: function(data) {
+ var beforeStyle, beforeWidth, boxHeight, boxWidth, f, width;
+ f = data.f;
+ boxWidth = this.g.zoomer.get("columnWidth");
+ boxHeight = this.g.zoomer.get("rowHeight");
+ width = (f.get("xEnd") - f.get("xStart")) * boxWidth;
+ beforeWidth = this.ctx.lineWidth;
+ this.ctx.lineWidth = 3;
+ beforeStyle = this.ctx.strokeStyle;
+ this.ctx.strokeStyle = f.get("fillColor");
+ this.ctx.strokeRect(data.xZero, data.yZero, width, boxHeight);
+ this.ctx.strokeStyle = beforeStyle;
+ return this.ctx.lineWidth = beforeWidth;
+ },
+ _appendSelection: function(data) {
+ var boxHeight, boxWidth, hiddenOffset, k, mNextSel, mPrevSel, n, selection, seq, _i, _ref, _ref1, _results;
+ seq = data.model.get("seq");
+ selection = this._getSelection(data.model);
+ _ref = this._getPrevNextSelection(data.model), mPrevSel = _ref[0], mNextSel = _ref[1];
+ boxWidth = this.g.zoomer.get("columnWidth");
+ boxHeight = this.g.zoomer.get("rowHeight");
+ if (selection.length === 0) {
+ return;
+ }
+ hiddenOffset = 0;
+ _results = [];
+ for (n = _i = 0, _ref1 = seq.length - 1; _i <= _ref1; n = _i += 1) {
+ if (data.hidden.indexOf(n) >= 0) {
+ _results.push(hiddenOffset++);
+ } else {
+ k = n - hiddenOffset;
+ if (selection.indexOf(n) >= 0 && (k === 0 || selection.indexOf(n - 1) < 0)) {
+ _results.push(this._renderSelection({
+ n: n,
+ k: k,
+ selection: selection,
+ mPrevSel: mPrevSel,
+ mNextSel: mNextSel,
+ xZero: data.xZero,
+ yZero: data.yZero,
+ model: data.model
+ }));
+ } else {
+ _results.push(void 0);
+ }
+ }
+ }
+ return _results;
+ },
+ _renderSelection: function(data) {
+ var beforeStyle, beforeWidth, boxHeight, boxWidth, hidden, i, k, mNextSel, mPrevSel, n, selection, selectionLength, totalWidth, xPart, xPos, xZero, yZero, _i, _j, _ref, _ref1;
+ xZero = data.xZero;
+ yZero = data.yZero;
+ n = data.n;
+ k = data.k;
+ selection = data.selection;
+ mPrevSel = data.mPrevSel;
+ mNextSel = data.mNextSel;
+ selectionLength = 0;
+ for (i = _i = n, _ref = data.model.get("seq").length - 1; _i <= _ref; i = _i += 1) {
+ if (selection.indexOf(i) >= 0) {
+ selectionLength++;
+ } else {
+ break;
+ }
+ }
+ boxWidth = this.g.zoomer.get("columnWidth");
+ boxHeight = this.g.zoomer.get("rowHeight");
+ totalWidth = (boxWidth * selectionLength) + 1;
+ hidden = this.g.columns.get('hidden');
+ this.ctx.beginPath();
+ beforeWidth = this.ctx.lineWidth;
+ this.ctx.lineWidth = 3;
+ beforeStyle = this.ctx.strokeStyle;
+ this.ctx.strokeStyle = "#FF0000";
+ xZero += k * boxWidth;
+ xPart = 0;
+ for (i = _j = 0, _ref1 = selectionLength - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
+ xPos = n + i;
+ if (hidden.indexOf(xPos) >= 0) {
+ continue;
+ }
+ if (!((mPrevSel != null) && mPrevSel.indexOf(xPos) >= 0)) {
+ this.ctx.moveTo(xZero + xPart, yZero);
+ this.ctx.lineTo(xPart + boxWidth + xZero, yZero);
+ }
+ if (!((mNextSel != null) && mNextSel.indexOf(xPos) >= 0)) {
+ this.ctx.moveTo(xPart + xZero, boxHeight + yZero);
+ this.ctx.lineTo(xPart + boxWidth + xZero, boxHeight + yZero);
+ }
+ xPart += boxWidth;
+ }
+ this.ctx.moveTo(xZero, yZero);
+ this.ctx.lineTo(xZero, boxHeight + yZero);
+ this.ctx.moveTo(xZero + totalWidth, yZero);
+ this.ctx.lineTo(xZero + totalWidth, boxHeight + yZero);
+ this.ctx.stroke();
+ this.ctx.strokeStyle = beforeStyle;
+ return this.ctx.lineWidth = beforeWidth;
+ },
+ _getPrevNextSelection: function(model) {
+ var mNextSel, mPrevSel, modelNext, modelPrev;
+ modelPrev = model.collection.prev(model);
+ modelNext = model.collection.next(model);
+ if (modelPrev != null) {
+ mPrevSel = this._getSelection(modelPrev);
+ }
+ if (modelNext != null) {
+ mNextSel = this._getSelection(modelNext);
+ }
+ return [mPrevSel, mNextSel];
+ }
+});
+
+
+
+},{"./CanvasCharCache":97,"backbone-childs":3,"biojs-util-colorschemes":29,"jbone":50,"mouse-pos":51,"underscore":59}],99:[function(require,module,exports){
+var OverviewBox, colorSelector, jbone, mouse, selection, view, _;
+
+view = require("backbone-viewj");
+
+mouse = require("mouse-pos");
+
+selection = require("../g/selection/Selection");
+
+colorSelector = require("biojs-util-colorschemes").selector;
+
+jbone = require("jbone");
+
+_ = require("underscore");
+
+module.exports = OverviewBox = view.extend({
+ className: "biojs_msa_overviewbox",
+ tagName: "canvas",
+ initialize: function(data) {
+ this.g = data.g;
+ this.listenTo(this.g.zoomer, "change:boxRectWidth change:boxRectHeight", this.render);
+ this.listenTo(this.g.selcol, "add reset change", this.render);
+ this.listenTo(this.g.columns, "change:hidden", this.render);
+ this.listenTo(this.g.colorscheme, "change:showLowerCase", this.render);
+ this.listenTo(this.model, "change", _.debounce(this.render, 5));
+ this.color = colorSelector.getColor(this.g.colorscheme.get("scheme"));
+ this.listenTo(this.g.colorscheme, "change:scheme", function() {
+ this.color = colorSelector.getColor(this.g.colorscheme.get("scheme"));
+ return this.render();
+ });
+ return this.dragStart = [];
+ },
+ events: {
+ click: "_onclick",
+ mousedown: "_onmousedown"
+ },
+ render: function() {
+ var c, color, hidden, i, j, rectHeight, rectWidth, seq, showLowerCase, x, y, _i, _j, _ref, _ref1;
+ this._createCanvas();
+ this.el.textContent = "overview";
+ this.ctx.fillStyle = "#999999";
+ this.ctx.fillRect(0, 0, this.el.width, this.el.height);
+ rectWidth = this.g.zoomer.get("boxRectWidth");
+ rectHeight = this.g.zoomer.get("boxRectHeight");
+ hidden = this.g.columns.get("hidden");
+ showLowerCase = this.g.colorscheme.get("showLowerCase");
+ y = -rectHeight;
+ for (i = _i = 0, _ref = this.model.length - 1; _i <= _ref; i = _i += 1) {
+ seq = this.model.at(i).get("seq");
+ x = 0;
+ y = y + rectHeight;
+ if (this.model.at(i).get("hidden")) {
+ console.log(this.model.at(i).get("hidden"));
+ this.ctx.fillStyle = "grey";
+ this.ctx.fillRect(0, y, seq.length * rectWidth, rectHeight);
+ continue;
+ }
+ for (j = _j = 0, _ref1 = seq.length - 1; _j <= _ref1; j = _j += 1) {
+ c = seq[j];
+ if (showLowerCase) {
+ c = c.toUpperCase();
+ }
+ color = this.color[c];
+ if (hidden.indexOf(j) >= 0) {
+ color = "grey";
+ }
+ if (color != null) {
+ this.ctx.fillStyle = color;
+ this.ctx.fillRect(x, y, rectWidth, rectHeight);
+ }
+ x = x + rectWidth;
+ }
+ }
+ return this._drawSelection();
+ },
+ _drawSelection: function() {
+ var i, maxHeight, pos, rectHeight, rectWidth, sel, seq, _i, _ref;
+ if (this.dragStart.length > 0 && !this.prolongSelection) {
+ return;
+ }
+ rectWidth = this.g.zoomer.get("boxRectWidth");
+ rectHeight = this.g.zoomer.get("boxRectHeight");
+ maxHeight = rectHeight * this.model.length;
+ this.ctx.fillStyle = "#ffff00";
+ this.ctx.globalAlpha = 0.9;
+ for (i = _i = 0, _ref = this.g.selcol.length - 1; _i <= _ref; i = _i += 1) {
+ sel = this.g.selcol.at(i);
+ if (sel.get('type') === 'column') {
+ this.ctx.fillRect(rectWidth * sel.get('xStart'), 0, rectWidth * (sel.get('xEnd') - sel.get('xStart') + 1), maxHeight);
+ } else if (sel.get('type') === 'row') {
+ seq = (this.model.filter(function(el) {
+ return el.get('id') === sel.get('seqId');
+ }))[0];
+ pos = this.model.indexOf(seq);
+ this.ctx.fillRect(0, rectHeight * pos, rectWidth * seq.get('seq').length, rectHeight);
+ } else if (sel.get('type') === 'pos') {
+ seq = (this.model.filter(function(el) {
+ return el.get('id') === sel.get('seqId');
+ }))[0];
+ pos = this.model.indexOf(seq);
+ this.ctx.fillRect(rectWidth * sel.get('xStart'), rectHeight * pos, rectWidth * (sel.get('xEnd') - sel.get('xStart') + 1), rectHeight);
+ }
+ }
+ return this.ctx.globalAlpha = 1;
+ },
+ _onclick: function(evt) {
+ return this.g.trigger("meta:click", {
+ seqId: this.model.get("id", {
+ evt: evt
+ })
+ });
+ },
+ _onmousemove: function(e) {
+ var rect;
+ if (this.dragStart.length === 0) {
+ return;
+ }
+ this.render();
+ this.ctx.fillStyle = "#ffff00";
+ this.ctx.globalAlpha = 0.9;
+ rect = this._calcSelection(mouse.abs(e));
+ this.ctx.fillRect(rect[0][0], rect[1][0], rect[0][1] - rect[0][0], rect[1][1] - rect[1][0]);
+ e.preventDefault();
+ return e.stopPropagation();
+ },
+ _onmousedown: function(e) {
+ this.dragStart = mouse.abs(e);
+ this.dragStartRel = mouse.rel(e);
+ if (e.ctrlKey || e.metaKey) {
+ this.prolongSelection = true;
+ } else {
+ this.prolongSelection = false;
+ }
+ jbone(document.body).on('mousemove.overmove', (function(_this) {
+ return function(e) {
+ return _this._onmousemove(e);
+ };
+ })(this));
+ jbone(document.body).on('mouseup.overup', (function(_this) {
+ return function(e) {
+ return _this._onmouseup(e);
+ };
+ })(this));
+ return this.dragStart;
+ },
+ _calcSelection: function(dragMove) {
+ var dragRel, i, rect, _i, _j;
+ dragRel = [dragMove[0] - this.dragStart[0], dragMove[1] - this.dragStart[1]];
+ for (i = _i = 0; _i <= 1; i = _i += 1) {
+ dragRel[i] = this.dragStartRel[i] + dragRel[i];
+ }
+ rect = [[this.dragStartRel[0], dragRel[0]], [this.dragStartRel[1], dragRel[1]]];
+ for (i = _j = 0; _j <= 1; i = _j += 1) {
+ if (rect[i][1] < rect[i][0]) {
+ rect[i] = [rect[i][1], rect[i][0]];
+ }
+ rect[i][0] = Math.max(rect[i][0], 0);
+ }
+ return rect;
+ },
+ _endSelection: function(dragEnd) {
+ var args, i, j, rect, selis, _i, _j, _k, _ref, _ref1;
+ jbone(document.body).off('.overmove');
+ jbone(document.body).off('.overup');
+ if (this.dragStart.length === 0) {
+ return;
+ }
+ rect = this._calcSelection(dragEnd);
+ for (i = _i = 0; _i <= 1; i = ++_i) {
+ rect[0][i] = Math.floor(rect[0][i] / this.g.zoomer.get("boxRectWidth"));
+ }
+ for (i = _j = 0; _j <= 1; i = ++_j) {
+ rect[1][i] = Math.floor(rect[1][i] / this.g.zoomer.get("boxRectHeight"));
+ }
+ rect[0][1] = Math.min(this.model.getMaxLength() - 1, rect[0][1]);
+ rect[1][1] = Math.min(this.model.length - 1, rect[1][1]);
+ selis = [];
+ for (j = _k = _ref = rect[1][0], _ref1 = rect[1][1]; _k <= _ref1; j = _k += 1) {
+ args = {
+ seqId: this.model.at(j).get('id'),
+ xStart: rect[0][0],
+ xEnd: rect[0][1]
+ };
+ selis.push(new selection.possel(args));
+ }
+ this.dragStart = [];
+ if (this.prolongSelection) {
+ this.g.selcol.add(selis);
+ } else {
+ this.g.selcol.reset(selis);
+ }
+ this.g.zoomer.setLeftOffset(rect[0][0]);
+ return this.g.zoomer.setTopOffset(rect[1][0]);
+ },
+ _onmouseup: function(e) {
+ return this._endSelection(mouse.abs(e));
+ },
+ _onmouseout: function(e) {
+ return this._endSelection(mouse.abs(e));
+ },
+ _createCanvas: function() {
+ var rectHeight, rectWidth;
+ rectWidth = this.g.zoomer.get("boxRectWidth");
+ rectHeight = this.g.zoomer.get("boxRectHeight");
+ this.el.height = this.model.length * rectHeight;
+ this.el.width = this.model.getMaxLength() * rectWidth;
+ this.ctx = this.el.getContext("2d");
+ this.el.style.overflow = "scroll";
+ return this.el.style.cursor = "crosshair";
+ }
+});
+
+
+
+},{"../g/selection/Selection":67,"backbone-viewj":10,"biojs-util-colorschemes":29,"jbone":50,"mouse-pos":51,"underscore":59}],100:[function(require,module,exports){
+var AlignmentBody, HeaderBlock, OverviewBox, boneView, identityCalc, _;
+
+boneView = require("backbone-childs");
+
+AlignmentBody = require("./AlignmentBody");
+
+HeaderBlock = require("./header/HeaderBlock");
+
+OverviewBox = require("./OverviewBox");
+
+identityCalc = require("../algo/identityCalc");
+
+_ = require('underscore');
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.draw();
+ this.listenTo(this.model, "reset", function() {
+ this.isNotDirty = false;
+ return this.rerender();
+ });
+ this.listenTo(this.model, "change:hidden", _.debounce(this.rerender, 10));
+ this.listenTo(this.model, "sort", this.rerender);
+ this.listenTo(this.model, "add", function() {
+ return console.log("seq add");
+ });
+ this.listenTo(this.g.vis, "change:sequences", this.rerender);
+ this.listenTo(this.g.vis, "change:overviewbox", this.rerender);
+ return this.listenTo(this.g.visorder, "change", this.rerender);
+ },
+ draw: function() {
+ var body, consensus, headerblock, overviewbox;
+ this.removeViews();
+ if (!this.isNotDirty) {
+ consensus = this.g.consensus.getConsensus(this.model);
+ identityCalc(this.model, consensus);
+ this.isNotDirty = true;
+ }
+ if (this.g.vis.get("overviewbox")) {
+ overviewbox = new OverviewBox({
+ model: this.model,
+ g: this.g
+ });
+ overviewbox.ordering = this.g.visorder.get('overviewBox');
+ this.addView("overviewbox", overviewbox);
+ }
+ if (true) {
+ headerblock = new HeaderBlock({
+ model: this.model,
+ g: this.g
+ });
+ headerblock.ordering = this.g.visorder.get('headerBox');
+ this.addView("headerblock", headerblock);
+ }
+ body = new AlignmentBody({
+ model: this.model,
+ g: this.g
+ });
+ body.ordering = this.g.visorder.get('alignmentBody');
+ return this.addView("body", body);
+ },
+ render: function() {
+ this.renderSubviews();
+ this.el.className = "biojs_msa_stage";
+ return this;
+ },
+ rerender: function() {
+ this.draw();
+ return this.render();
+ }
+});
+
+
+
+},{"../algo/identityCalc":61,"./AlignmentBody":96,"./OverviewBox":99,"./header/HeaderBlock":102,"backbone-childs":3,"underscore":59}],101:[function(require,module,exports){
+var ConservationView, dom, svg, view;
+
+view = require("backbone-viewj");
+
+dom = require("dom-helper");
+
+svg = require("../../utils/svg");
+
+ConservationView = view.extend({
+ className: "biojs_msa_conserv",
+ initialize: function(data) {
+ this.g = data.g;
+ this.listenTo(this.g.zoomer, "change:stepSize change:labelWidth change:columnWidth", this.render);
+ this.listenTo(this.g.vis, "change:labels change:metacell", this.render);
+ this.listenTo(this.g.columns, "change:scaling", this.render);
+ this.listenTo(this.model, "reset", this.render);
+ return this.manageEvents();
+ },
+ render: function() {
+ var avgHeight, cellWidth, height, hidden, i, maxHeight, n, nMax, rect, s, stepSize, width, x, _i, _ref;
+ this.g.columns.calcConservation(this.model);
+ dom.removeAllChilds(this.el);
+ nMax = this.model.getMaxLength();
+ cellWidth = this.g.zoomer.get("columnWidth");
+ maxHeight = 20;
+ width = cellWidth * (nMax - this.g.columns.get('hidden').length);
+ console.log(this.g.columns.get('hidden'));
+ s = svg.base({
+ height: maxHeight,
+ width: width
+ });
+ s.style.display = "inline-block";
+ s.style.cursor = "pointer";
+ stepSize = this.g.zoomer.get("stepSize");
+ hidden = this.g.columns.get("hidden");
+ x = 0;
+ n = 0;
+ while (n < nMax) {
+ if (hidden.indexOf(n) >= 0) {
+ n += stepSize;
+ continue;
+ }
+ width = cellWidth * stepSize;
+ avgHeight = 0;
+ for (i = _i = 0, _ref = stepSize - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
+ avgHeight += this.g.columns.get("conserv")[n];
+ }
+ height = maxHeight * (avgHeight / stepSize);
+ rect = svg.rect({
+ x: x,
+ y: maxHeight - height,
+ width: width - cellWidth / 4,
+ height: height,
+ style: "stroke:red;stroke-width:1;"
+ });
+ rect.rowPos = n;
+ s.appendChild(rect);
+ x += width;
+ n += stepSize;
+ }
+ this.el.appendChild(s);
+ return this;
+ },
+ _onclick: function(evt) {
+ var i, rowPos, stepSize, _i, _ref, _results;
+ rowPos = evt.target.rowPos;
+ stepSize = this.g.zoomer.get("stepSize");
+ _results = [];
+ for (i = _i = 0, _ref = stepSize - 1; _i <= _ref; i = _i += 1) {
+ _results.push(this.g.trigger("bar:click", {
+ rowPos: rowPos + i,
+ evt: evt
+ }));
+ }
+ return _results;
+ },
+ manageEvents: function() {
+ var events;
+ events = {};
+ if (this.g.config.get("registerMouseClicks")) {
+ events.click = "_onclick";
+ }
+ if (this.g.config.get("registerMouseHover")) {
+ events.mousein = "_onmousein";
+ events.mouseout = "_onmouseout";
+ }
+ this.delegateEvents(events);
+ this.listenTo(this.g.config, "change:registerMouseHover", this.manageEvents);
+ return this.listenTo(this.g.config, "change:registerMouseClick", this.manageEvents);
+ },
+ _onmousein: function(evt) {
+ var rowPos;
+ rowPos = this.g.zoomer.get("stepSize" * evt.rowPos);
+ return this.g.trigger("bar:mousein", {
+ rowPos: rowPos,
+ evt: evt
+ });
+ },
+ _onmouseout: function(evt) {
+ var rowPos;
+ rowPos = this.g.zoomer.get("stepSize" * evt.rowPos);
+ return this.g.trigger("bar:mouseout", {
+ rowPos: rowPos,
+ evt: evt
+ });
+ }
+});
+
+module.exports = ConservationView;
+
+
+
+},{"../../utils/svg":95,"backbone-viewj":10,"dom-helper":49}],102:[function(require,module,exports){
+var ConservationView, MarkerView, boneView, identityCalc, _;
+
+MarkerView = require("./MarkerView");
+
+ConservationView = require("./ConservationView");
+
+identityCalc = require("../../algo/identityCalc");
+
+boneView = require("backbone-childs");
+
+_ = require('underscore');
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.blockEvents = false;
+ this.listenTo(this.g.vis, "change:markers change:conserv", function() {
+ this.draw();
+ return this.render();
+ });
+ this.listenTo(this.g.vis, "change", this._setSpacer);
+ this.listenTo(this.g.zoomer, "change:alignmentWidth", function() {
+ return this._adjustWidth();
+ });
+ this.listenTo(this.g.zoomer, "change:_alignmentScrollLeft", this._adjustScrollingLeft);
+ this.listenTo(this.g.columns, "change:hidden", function() {
+ this.draw();
+ return this.render();
+ });
+ this.draw();
+ this._onscroll = this._sendScrollEvent;
+ return this.g.vis.once('change:loaded', this._adjustScrollingLeft, this);
+ },
+ events: {
+ "scroll": "_onscroll"
+ },
+ draw: function() {
+ var consensus, conserv, marker;
+ this.removeViews();
+ if (!this.isNotDirty) {
+ consensus = this.g.consensus.getConsensus(this.model);
+ identityCalc(this.model, consensus);
+ this.isNotDirty = true;
+ }
+ if (this.g.vis.get("conserv")) {
+ conserv = new ConservationView({
+ model: this.model,
+ g: this.g
+ });
+ conserv.ordering = -20;
+ this.addView("conserv", conserv);
+ }
+ if (this.g.vis.get("markers")) {
+ marker = new MarkerView({
+ model: this.model,
+ g: this.g
+ });
+ marker.ordering = -10;
+ return this.addView("marker", marker);
+ }
+ },
+ render: function() {
+ this.renderSubviews();
+ this._setSpacer();
+ this.el.className = "biojs_msa_header";
+ this.el.style.overflowX = "auto";
+ this._adjustWidth();
+ this._adjustScrollingLeft();
+ return this;
+ },
+ _sendScrollEvent: function() {
+ if (!this.blockEvents) {
+ this.g.zoomer.set("_alignmentScrollLeft", this.el.scrollLeft, {
+ origin: "header"
+ });
+ }
+ return this.blockEvents = false;
+ },
+ _adjustScrollingLeft: function(model, value, options) {
+ var scrollLeft;
+ if (((options != null ? options.origin : void 0) == null) || options.origin !== "header") {
+ scrollLeft = this.g.zoomer.get("_alignmentScrollLeft");
+ this.blockEvents = true;
+ return this.el.scrollLeft = scrollLeft;
+ }
+ },
+ _setSpacer: function() {
+ return this.el.style.marginLeft = this._getLabelWidth() + "px";
+ },
+ _getLabelWidth: function() {
+ var paddingLeft;
+ paddingLeft = 0;
+ if (this.g.vis.get("labels")) {
+ paddingLeft += this.g.zoomer.get("labelWidth");
+ }
+ if (this.g.vis.get("metacell")) {
+ paddingLeft += this.g.zoomer.get("metaWidth");
+ }
+ return paddingLeft;
+ },
+ _adjustWidth: function() {
+ return this.el.style.width = this.g.zoomer.get("alignmentWidth") + "px";
+ }
+});
+
+
+
+},{"../../algo/identityCalc":61,"./ConservationView":101,"./MarkerView":103,"backbone-childs":3,"underscore":59}],103:[function(require,module,exports){
+var HeaderView, dom, jbone, svg, view;
+
+view = require("backbone-viewj");
+
+dom = require("dom-helper");
+
+svg = require("../../utils/svg");
+
+jbone = require("jbone");
+
+HeaderView = view.extend({
+ className: "biojs_msa_marker",
+ initialize: function(data) {
+ this.g = data.g;
+ this.listenTo(this.g.zoomer, "change:stepSize change:labelWidth change:columnWidth change:markerStepSize change:markerFontsize", this.render);
+ this.listenTo(this.g.vis, "change:labels change:metacell", this.render);
+ return this.manageEvents();
+ },
+ render: function() {
+ var cellWidth, container, hidden, n, nMax, span, stepSize;
+ dom.removeAllChilds(this.el);
+ this.el.style.fontSize = this.g.zoomer.get("markerFontsize");
+ container = document.createElement("span");
+ n = 0;
+ cellWidth = this.g.zoomer.get("columnWidth");
+ nMax = this.model.getMaxLength();
+ stepSize = this.g.zoomer.get("stepSize");
+ hidden = this.g.columns.get("hidden");
+ while (n < nMax) {
+ if (hidden.indexOf(n) >= 0) {
+ this.markerHidden(span, n, stepSize);
+ n += stepSize;
+ continue;
+ }
+ span = document.createElement("span");
+ span.style.width = (cellWidth * stepSize) + "px";
+ span.style.display = "inline-block";
+ if ((n + 1) % this.g.zoomer.get('markerStepSize') === 0) {
+ span.textContent = n + 1;
+ } else {
+ span.textContent = ".";
+ }
+ span.rowPos = n;
+ n += stepSize;
+ container.appendChild(span);
+ }
+ this.el.appendChild(container);
+ return this;
+ },
+ markerHidden: function(span, n, stepSize) {
+ var hidden, index, j, length, min, nMax, prevHidden, s, triangle, _i, _j;
+ hidden = this.g.columns.get("hidden").slice(0);
+ min = Math.max(0, n - stepSize);
+ prevHidden = true;
+ for (j = _i = min; _i <= n; j = _i += 1) {
+ prevHidden &= hidden.indexOf(j) >= 0;
+ }
+ if (prevHidden) {
+ return;
+ }
+ nMax = this.model.getMaxLength();
+ length = 0;
+ index = -1;
+ for (n = _j = n; _j <= nMax; n = _j += 1) {
+ if (!(index >= 0)) {
+ index = hidden.indexOf(n);
+ }
+ if (hidden.indexOf(n) >= 0) {
+ length++;
+ } else {
+ break;
+ }
+ }
+ s = svg.base({
+ height: 10,
+ width: 10
+ });
+ s.style.position = "relative";
+ triangle = svg.polygon({
+ points: "0,0 5,5 10,0",
+ style: "fill:lime;stroke:purple;stroke-width:1"
+ });
+ jbone(triangle).on("click", (function(_this) {
+ return function(evt) {
+ hidden.splice(index, length);
+ return _this.g.columns.set("hidden", hidden);
+ };
+ })(this));
+ s.appendChild(triangle);
+ span.appendChild(s);
+ return s;
+ },
+ manageEvents: function() {
+ var events;
+ events = {};
+ if (this.g.config.get("registerMouseClicks")) {
+ events.click = "_onclick";
+ }
+ if (this.g.config.get("registerMouseHover")) {
+ events.mousein = "_onmousein";
+ events.mouseout = "_onmouseout";
+ }
+ this.delegateEvents(events);
+ this.listenTo(this.g.config, "change:registerMouseHover", this.manageEvents);
+ return this.listenTo(this.g.config, "change:registerMouseClick", this.manageEvents);
+ },
+ _onclick: function(evt) {
+ var rowPos, stepSize;
+ rowPos = evt.target.rowPos;
+ stepSize = this.g.zoomer.get("stepSize");
+ return this.g.trigger("column:click", {
+ rowPos: rowPos,
+ stepSize: stepSize,
+ evt: evt
+ });
+ },
+ _onmousein: function(evt) {
+ var rowPos, stepSize;
+ rowPos = this.g.zoomer.get("stepSize" * evt.rowPos);
+ stepSize = this.g.zoomer.get("stepSize");
+ return this.g.trigger("column:mousein", {
+ rowPos: rowPos,
+ stepSize: stepSize,
+ evt: evt
+ });
+ },
+ _onmouseout: function(evt) {
+ var rowPos, stepSize;
+ rowPos = this.g.zoomer.get("stepSize" * evt.rowPos);
+ stepSize = this.g.zoomer.get("stepSize");
+ return this.g.trigger("column:mouseout", {
+ rowPos: rowPos,
+ stepSize: stepSize,
+ evt: evt
+ });
+ }
+});
+
+module.exports = HeaderView;
+
+
+
+},{"../../utils/svg":95,"backbone-viewj":10,"dom-helper":49,"jbone":50}],104:[function(require,module,exports){
+var LabelRowView, boneView;
+
+LabelRowView = require("./LabelRowView");
+
+boneView = require("backbone-childs");
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.draw();
+ this.listenTo(this.g.zoomer, "change:_alignmentScrollTop", this._adjustScrollingTop);
+ return this.g.vis.once('change:loaded', this._adjustScrollingTop, this);
+ },
+ draw: function() {
+ var i, view, _i, _ref, _results;
+ this.removeViews();
+ _results = [];
+ for (i = _i = 0, _ref = this.model.length - 1; _i <= _ref; i = _i += 1) {
+ if (this.model.at(i).get('hidden')) {
+ continue;
+ }
+ view = new LabelRowView({
+ model: this.model.at(i),
+ g: this.g
+ });
+ view.ordering = i;
+ _results.push(this.addView("row_" + i, view));
+ }
+ return _results;
+ },
+ events: {
+ "scroll": "_sendScrollEvent"
+ },
+ _sendScrollEvent: function() {
+ return this.g.zoomer.set("_alignmentScrollTop", this.el.scrollTop, {
+ origin: "label"
+ });
+ },
+ _adjustScrollingTop: function() {
+ return this.el.scrollTop = this.g.zoomer.get("_alignmentScrollTop");
+ },
+ render: function() {
+ this.renderSubviews();
+ this.el.className = "biojs_msa_labelblock";
+ this.el.style.display = "inline-block";
+ this.el.style.verticalAlign = "top";
+ this.el.style.height = this.g.zoomer.get("alignmentHeight") + "px";
+ this.el.style.overflowY = "auto";
+ this.el.style.overflowX = "hidden";
+ this.el.style.fontSize = "" + (this.g.zoomer.get("labelFontsize"));
+ this.el.style.lineHeight = "" + (this.g.zoomer.get("labelLineHeight"));
+ return this;
+ }
+});
+
+
+
+},{"./LabelRowView":105,"backbone-childs":3}],105:[function(require,module,exports){
+var LabelView, MetaView, boneView;
+
+boneView = require("backbone-childs");
+
+LabelView = require("./LabelView");
+
+MetaView = require("./MetaView");
+
+module.exports = boneView.extend({
+ initialize: function(data) {
+ this.g = data.g;
+ this.draw();
+ this.listenTo(this.g.vis, "change:labels", this.drawR);
+ return this.listenTo(this.g.vis, "change:metacell", this.drawR);
+ },
+ draw: function() {
+ this.removeViews();
+ if (this.g.vis.get("labels")) {
+ this.addView("labels", new LabelView({
+ model: this.model,
+ g: this.g
+ }));
+ }
+ if (this.g.vis.get("metacell")) {
+ return this.addView("metacell", new MetaView({
+ model: this.model,
+ g: this.g
+ }));
+ }
+ },
+ drawR: function() {
+ this.draw();
+ return this.render();
+ },
+ render: function() {
+ this.renderSubviews();
+ this.el.setAttribute("class", "biojs_msa_labelrow");
+ this.el.style.height = this.g.zoomer.get("rowHeight");
+ return this;
+ }
+});
+
+
+
+},{"./LabelView":106,"./MetaView":107,"backbone-childs":3}],106:[function(require,module,exports){
+var LabelView, dom, view;
+
+view = require("backbone-viewj");
+
+dom = require("dom-helper");
+
+LabelView = view.extend({
+ initialize: function(data) {
+ this.seq = data.seq;
+ this.g = data.g;
+ return this.manageEvents();
+ },
+ manageEvents: function() {
+ var events;
+ events = {};
+ if (this.g.config.get("registerMouseClicks")) {
+ events.click = "_onclick";
+ }
+ if (this.g.config.get("registerMouseHover")) {
+ events.mousein = "_onmousein";
+ events.mouseout = "_onmouseout";
+ }
+ this.delegateEvents(events);
+ this.listenTo(this.g.config, "change:registerMouseHover", this.manageEvents);
+ this.listenTo(this.g.config, "change:registerMouseClick", this.manageEvents);
+ this.listenTo(this.g.vis, "change:labelName", this.render);
+ this.listenTo(this.g.vis, "change:labelId", this.render);
+ this.listenTo(this.g.vis, "change:labelPartition", this.render);
+ return this.listenTo(this.g.vis, "change:labelCheckbox", this.render);
+ },
+ render: function() {
+ var checkBox, id, name, part;
+ dom.removeAllChilds(this.el);
+ this.el.style.width = "" + (this.g.zoomer.get("labelWidth")) + "px";
+ this.el.style.height = "" + (this.g.zoomer.get("rowHeight")) + "px";
+ this.el.setAttribute("class", "biojs_msa_labels");
+ if (this.g.vis.get("labelCheckbox")) {
+ checkBox = document.createElement("input");
+ checkBox.setAttribute("type", "checkbox");
+ checkBox.value = this.model.get('id');
+ checkBox.name = "seq";
+ this.el.appendChild(checkBox);
+ }
+ if (this.g.vis.get("labelId")) {
+ id = document.createElement("span");
+ id.textContent = this.model.get("id");
+ id.style.width = this.g.zoomer.get("labelIdLength");
+ id.style.display = "inline-block";
+ this.el.appendChild(id);
+ }
+ if (this.g.vis.get("labelPartition")) {
+ part = document.createElement("span");
+ part.style.width = 15;
+ part.textContent = this.model.get("partition");
+ part.style.display = "inline-block";
+ this.el.appendChild(id);
+ this.el.appendChild(part);
+ }
+ if (this.g.vis.get("labelName")) {
+ name = document.createElement("span");
+ name.textContent = this.model.get("name");
+ this.el.appendChild(name);
+ }
+ this.el.style.overflow = scroll;
+ return this;
+ },
+ _onclick: function(evt) {
+ var seqId;
+ seqId = this.model.get("id");
+ return this.g.trigger("row:click", {
+ seqId: seqId,
+ evt: evt
+ });
+ },
+ _onmousein: function(evt) {
+ var seqId;
+ seqId = this.model.get("id");
+ return this.g.trigger("row:mouseout", {
+ seqId: seqId,
+ evt: evt
+ });
+ },
+ _onmouseout: function(evt) {
+ var seqId;
+ seqId = this.model.get("id");
+ return this.g.trigger("row:mouseout", {
+ seqId: seqId,
+ evt: evt
+ });
+ }
+});
+
+module.exports = LabelView;
+
+
+
+},{"backbone-viewj":10,"dom-helper":49}],107:[function(require,module,exports){
+var MenuBuilder, MetaView, dom, view, _;
+
+view = require("backbone-viewj");
+
+MenuBuilder = require("../../menu/menubuilder");
+
+_ = require('underscore');
+
+dom = require("dom-helper");
+
+module.exports = MetaView = view.extend({
+ className: "biojs_msa_metaview",
+ initialize: function(data) {
+ return this.g = data.g;
+ },
+ events: {
+ click: "_onclick",
+ mousein: "_onmousein",
+ mouseout: "_onmouseout"
+ },
+ render: function() {
+ var gapSpan, gaps, ident, identSpan, menu, seq, width;
+ dom.removeAllChilds(this.el);
+ this.el.style.display = "inline-block";
+ width = this.g.zoomer.get("metaWidth");
+ this.el.style.width = width - 5;
+ this.el.style.paddingRight = 5;
+ seq = this.model.get('seq');
+ gaps = _.reduce(seq, (function(memo, c) {
+ if (c === '-') {
+ memo++;
+ }
+ return memo;
+ }), 0);
+ gaps = (gaps / seq.length).toFixed(1);
+ gapSpan = document.createElement('span');
+ gapSpan.textContent = gaps;
+ gapSpan.style.display = "inline-block";
+ gapSpan.style.width = 35;
+ this.el.appendChild(gapSpan);
+ ident = this.model.get('identity');
+ identSpan = document.createElement('span');
+ identSpan.textContent = ident.toFixed(2);
+ identSpan.style.display = "inline-block";
+ identSpan.style.width = 40;
+ this.el.appendChild(identSpan);
+ menu = new MenuBuilder("↗");
+ menu.addNode("Uniprot", (function(_this) {
+ return function(e) {
+ return window.open("http://beta.uniprot.org/uniprot/Q7T2N8");
+ };
+ })(this));
+ this.el.appendChild(menu.buildDOM());
+ this.el.width = 10;
+ this.el.style.height = "" + (this.g.zoomer.get("rowHeight")) + "px";
+ return this.el.style.cursor = "pointer";
+ },
+ _onclick: function(evt) {
+ return this.g.trigger("meta:click", {
+ seqId: this.model.get("id", {
+ evt: evt
+ })
+ });
+ },
+ _onmousein: function(evt) {
+ return this.g.trigger("meta:mousein", {
+ seqId: this.model.get("id", {
+ evt: evt
+ })
+ });
+ },
+ _onmouseout: function(evt) {
+ return this.g.trigger("meta:mouseout", {
+ seqId: this.model.get("id", {
+ evt: evt
+ })
+ });
+ }
+});
+
+
+
+},{"../../menu/menubuilder":75,"backbone-viewj":10,"dom-helper":49,"underscore":59}],"biojs-io-clustal":[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+var Clustal, GenericReader, Seq, Str,
+ __hasProp = {}.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
+
+Str = require("./strings");
+
+GenericReader = require("./generic_reader");
+
+Seq = require("./seq");
+
+module.exports = Clustal = (function(_super) {
+ __extends(Clustal, _super);
+
+ function Clustal() {
+ return Clustal.__super__.constructor.apply(this, arguments);
+ }
+
+ Clustal.parse = function(text) {
+ var blockstate, k, label, line, lines, match, regex, seqCounter, seqs, sequence;
+ seqs = [];
+ if (Object.prototype.toString.call(text) === '[object Array]') {
+ lines = text;
+ } else {
+ lines = text.split("\n");
+ }
+ if (lines[0].slice(0, 6) === !"CLUSTAL") {
+ throw new Error("Invalid CLUSTAL Header");
+ }
+ k = 0;
+ blockstate = 1;
+ seqCounter = 0;
+ while (k < lines.length) {
+ k++;
+ line = lines[k];
+ if ((line == null) || line.length === 0) {
+ blockstate = 1;
+ continue;
+ }
+ if (line.trim().length === 0) {
+ blockstate = 1;
+ continue;
+ } else {
+ if (Str.contains(line, "*")) {
+ continue;
+ }
+ if (blockstate === 1) {
+ seqCounter = 0;
+ blockstate = 0;
+ }
+ regex = /^(?:\s*)(\S+)(?:\s+)(\S+)(?:\s*)(\d*)(?:\s*|$)/g;
+ match = regex.exec(line);
+ if (match != null) {
+ label = match[1];
+ sequence = match[2];
+ if (seqCounter >= seqs.length) {
+ seqs.push(new Seq(sequence, label, seqCounter));
+ } else {
+ seqs[seqCounter].seq += sequence;
+ }
+ seqCounter++;
+ } else {
+ console.log(line);
+ }
+ }
+ }
+ return seqs;
+ };
+
+ return Clustal;
+
+})(GenericReader);
+
+},{"./generic_reader":17,"./seq":18,"./strings":19}],"biojs-io-fasta":[function(require,module,exports){
+// Generated by CoffeeScript 1.8.0
+module.exports.parse = require("./parser");
+
+module.exports.writer = require("./writer");
+
+},{"./parser":21,"./writer":24}],"biojs-vis-msa":[function(require,module,exports){
+if (typeof biojs === 'undefined') {
+ biojs = {};
+}
+if (typeof biojs.vis === 'undefined') {
+ biojs.vis = {};
+}
+// use two namespaces
+window.msa = biojs.vis.msa = module.exports = require('./index');
+
+// TODO: how should this be bundled
+
+if (typeof biojs.io === 'undefined') {
+ biojs.io = {};
+}
+// just bundle the two parsers
+window.biojs.io.fasta = require("biojs-io-fasta");
+window.biojs.io.clustal = require("biojs-io-clustal");
+window.biojs.xhr = require("nets");
+
+// simulate standalone flag
+window.biojsVisMsa = window.msa;
+
+require('./build/msa.css');
+
+},{"./build/msa.css":1,"./index":2,"biojs-io-clustal":undefined,"biojs-io-fasta":undefined,"nets":undefined}],"nets":[function(require,module,exports){
+var req = require('request')
+
+module.exports = Nets
+
+function Nets(uri, opts, cb) {
+ req(uri, opts, cb)
+}
+},{"request":52}]},{},["biojs-vis-msa"])
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9idWlsZC9tc2EuY3NzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2EvaW5kZXguanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmFja2JvbmUtY2hpbGRzL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2JhY2tib25lLXRoaW4vY29sbGVjdGlvbi5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iYWNrYm9uZS10aGluL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2JhY2tib25lLXRoaW4vbW9kZWwuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmFja2JvbmUtdGhpbi9ub2RlX21vZHVsZXMvYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUvYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmFja2JvbmUtdGhpbi9ub2RlX21vZHVsZXMvYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUvaW5kZXguanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmFja2JvbmUtdGhpbi9ub2RlX21vZHVsZXMvYmFja2JvbmUtZXh0ZW5kLXN0YW5kYWxvbmUvYmFja2JvbmUtZXh0ZW5kLXN0YW5kYWxvbmUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmFja2JvbmUtdmlld2ovaW5kZXguanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtZXZlbnRzL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWNsdXN0YWwvbGliL2dlbmVyaWNfcmVhZGVyLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWNsdXN0YWwvbGliL3NlcS5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy1pby1jbHVzdGFsL2xpYi9zdHJpbmdzLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL2xpYi9wYXJzZXIuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbGliL3V0aWxzLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL2xpYi93cml0ZXIuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtaW8tZmFzdGEvbm9kZV9tb2R1bGVzL2Jpb2pzLW1vZGVsL3NyYy9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy1pby1mYXN0YS9ub2RlX21vZHVsZXMvYmlvanMtbW9kZWwvc3JjL3NlcS5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy11dGlsLWNvbG9yc2NoZW1lcy9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy11dGlsLWNvbG9yc2NoZW1lcy9zcmMvYnVyaWVkLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy9jaW5lbWEuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL2NsdXN0YWwuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL2NsdXN0YWwyLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy9oZWxpeC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy11dGlsLWNvbG9yc2NoZW1lcy9zcmMvaHlkcm9waG9iaWNpdHkuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy9sZXNrLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy9tYWUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL251Y2xlb3RpZGUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL3B1cmluZS5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy11dGlsLWNvbG9yc2NoZW1lcy9zcmMvc2VsZWN0b3IuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvYmlvanMtdXRpbC1jb2xvcnNjaGVtZXMvc3JjL3N0cmFuZC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy11dGlsLWNvbG9yc2NoZW1lcy9zcmMvdGF5bG9yLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy90dXJuLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLXV0aWwtY29sb3JzY2hlbWVzL3NyYy96YXBwby5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9ibHVlaW1wX2NhbnZhc3RvYmxvYi9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9icm93c2VyLXNhdmVhcy9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9jc3NpZnkvYnJvd3Nlci5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9kb20taGVscGVyL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2pib25lL2Rpc3QvamJvbmUuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvbW91c2UtcG9zL2luZGV4LmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL25ldHMvbm9kZV9tb2R1bGVzL3hoci9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9uZXRzL25vZGVfbW9kdWxlcy94aHIvbm9kZV9tb2R1bGVzL2dsb2JhbC93aW5kb3cuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvbmV0cy9ub2RlX21vZHVsZXMveGhyL25vZGVfbW9kdWxlcy9vbmNlL29uY2UuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvbmV0cy9ub2RlX21vZHVsZXMveGhyL25vZGVfbW9kdWxlcy9wYXJzZS1oZWFkZXJzL25vZGVfbW9kdWxlcy9mb3ItZWFjaC9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9uZXRzL25vZGVfbW9kdWxlcy94aHIvbm9kZV9tb2R1bGVzL3BhcnNlLWhlYWRlcnMvbm9kZV9tb2R1bGVzL2Zvci1lYWNoL25vZGVfbW9kdWxlcy9pcy1mdW5jdGlvbi9pbmRleC5qcyIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9uZXRzL25vZGVfbW9kdWxlcy94aHIvbm9kZV9tb2R1bGVzL3BhcnNlLWhlYWRlcnMvbm9kZV9tb2R1bGVzL3RyaW0vaW5kZXguanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvbmV0cy9ub2RlX21vZHVsZXMveGhyL25vZGVfbW9kdWxlcy9wYXJzZS1oZWFkZXJzL3BhcnNlLWhlYWRlcnMuanMiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9ub2RlX21vZHVsZXMvdW5kZXJzY29yZS91bmRlcnNjb3JlLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2FsZ28vQ29uc2Vuc3VzQ2FsYy5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvYWxnby9pZGVudGl0eUNhbGMuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2FsZ28vaW5kZXguY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2cvY29sb3JhdG9yLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9nL2NvbHVtbnMuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2cvY29uZmlnLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9nL2NvbnNlbnN1cy5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvZy9zZWxlY3Rpb24vU2VsZWN0aW9uLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9nL3NlbGVjdGlvbi9TZWxlY3Rpb25Db2wuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2cvdmlzT3JkZXJpbmcuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2cvdmlzaWJpbGl0eS5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvZy96b29tZXIuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL2luZGV4LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L2RlZmF1bHRtZW51LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L2luZGV4LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L21lbnVidWlsZGVyLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L3ZpZXdzL0NvbG9yTWVudS5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbWVudS92aWV3cy9FeHBvcnRNZW51LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L3ZpZXdzL0V4dHJhTWVudS5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbWVudS92aWV3cy9GaWx0ZXJNZW51LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L3ZpZXdzL0hlbHBNZW51LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L3ZpZXdzL0ltcG9ydE1lbnUuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL21lbnUvdmlld3MvT3JkZXJpbmdNZW51LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tZW51L3ZpZXdzL1NlbGVjdGlvbk1lbnUuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL21lbnUvdmlld3MvVmlzTWVudS5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbW9kZWwvRmVhdHVyZS5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbW9kZWwvRmVhdHVyZUNvbC5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbW9kZWwvU2VxQ29sbGVjdGlvbi5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvbW9kZWwvU2VxdWVuY2UuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL21vZGVsL2luZGV4LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy9tc2EuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL3V0aWxzL2JtYXRoLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy91dGlscy9pbmRleC5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdXRpbHMvcHJveHkuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL3V0aWxzL3NlcWdlbi5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdXRpbHMvc3ZnLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy92aWV3cy9BbGlnbm1lbnRCb2R5LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy92aWV3cy9DYW52YXNDaGFyQ2FjaGUuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL3ZpZXdzL0NhbnZhc1NlcUJsb2NrLmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy92aWV3cy9PdmVydmlld0JveC5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdmlld3MvU3RhZ2UuY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL3ZpZXdzL2hlYWRlci9Db25zZXJ2YXRpb25WaWV3LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy92aWV3cy9oZWFkZXIvSGVhZGVyQmxvY2suY29mZmVlIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evc3JjL3ZpZXdzL2hlYWRlci9NYXJrZXJWaWV3LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3NyYy92aWV3cy9sYWJlbHMvTGFiZWxCbG9jay5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdmlld3MvbGFiZWxzL0xhYmVsUm93Vmlldy5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdmlld3MvbGFiZWxzL0xhYmVsVmlldy5jb2ZmZWUiLCIvaG9tZS90cmF2aXMvYnVpbGQvZ3JlZW5pZnkvYmlvanMtdmlzLW1zYS9zcmMvdmlld3MvbGFiZWxzL01ldGFWaWV3LmNvZmZlZSIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9iaW9qcy1pby1jbHVzdGFsL2xpYi9jbHVzdGFsLmpzIiwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Jpb2pzLWlvLWZhc3RhL2xpYi9pbmRleC5qcyIsIi4vYnJvd3NlciIsIi9ob21lL3RyYXZpcy9idWlsZC9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL25vZGVfbW9kdWxlcy9uZXRzL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7O0FDQUE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcmJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclJBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUMvS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FDTkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2UEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3gxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2NENBLElBQUEsQ0FBQTs7QUFBQSxDQUFBLEdBQUksT0FBQSxDQUFRLFlBQVIsQ0FBSixDQUFBOztBQUFBLE1BSU0sQ0FBQyxPQUFQLEdBQWlCLFNBQUMsSUFBRCxHQUFBO0FBRWYsTUFBQSxJQUFBO0FBQUEs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Q0FyRFo7QUFBQSxFQXdEQSxXQUFBLEVBQWEsU0FBQyxHQUFELEdBQUE7V0FDWCxJQUFDLENBQUEsQ0FBQyxDQUFDLE9BQUgsQ0FBVyxlQUFYLEVBQTRCO0FBQUEsTUFBQyxLQUFBLEVBQU8sSUFBQyxDQUFBLEtBQUssQ0FBQyxHQUFQLENBQVcsSUFBWCxFQUFpQjtBQUFBLFFBQUEsR0FBQSxFQUFJLEdBQUo7T0FBakIsQ0FBUjtLQUE1QixFQURXO0VBQUEsQ0F4RGI7Q0FGMEIsQ0FMNUIsQ0FBQTs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsInZhciBjc3MgPSBcIi5iaW9qc19tc2Ffc3RhZ2Uge1xcbiAgY3Vyc29yOiBkZWZhdWx0O1xcbiAgbGluZS1oZWlnaHQ6IG5vcm1hbDsgfVxcblxcbi5iaW9qc19tc2FfbGFiZWxzIHtcXG4gIGNvbG9yOiBibGFjaztcXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcXG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XFxuICBjdXJzb3I6IHBvaW50ZXI7XFxuICB2ZXJ0aWNhbC1hbGlnbjogdG9wOyB9XFxuXFxuLmJpb2pzX21zYV9zZXFibG9jayB7XFxuICBjdXJzb3I6IG1vdmU7IH1cXG5cXG4uYmlvanNfbXNhX2xheWVyIHtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDsgfVxcblxcbi5iaW9qc19tc2FfbGFiZWxibG9jazo6LXdlYmtpdC1zY3JvbGxiYXIsIC5iaW9qc19tc2FfaGVhZGVyOjotd2Via2l0LXNjcm9sbGJhciB7XFxuICAtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XFxuICB3aWR0aDogN3B4O1xcbiAgaGVpZ2h0OiA3cHg7IH1cXG5cXG4uYmlvanNfbXNhX2xhYmVsYmxvY2s6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iLCAuYmlvanNfbXNhX2hlYWRlcjo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWIge1xcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjUpO1xcbiAgYm94LXNoYWRvdzogMCAwIDFweCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNSk7IH1cXG5cXG4uYmlvanNfbXNhX21hcmtlciB7XFxuICBjb2xvcjogZ3JleTtcXG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XFxuICBjdXJzb3I6IHBvaW50ZXI7IH1cXG5cXG4uYmlvanNfbXNhX21hcmtlciBzcGFuIHtcXG4gIHRleHQtYWxpZ246IGNlbnRlcjsgfVxcblxcbi5iaW9qc19tc2FfbWVudWJhciAuYmlvanNfbXNhX21lbnViYXJfYWxpbmsge1xcbiAgYmFja2dyb3VuZDogIzM0OThkYjtcXG4gIGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtbGluZWFyLWdyYWRpZW50KHRvcCwgIzM0OThkYiwgIzI5ODBiOSk7XFxuICBiYWNrZ3JvdW5kLWltYWdlOiAtbW96LWxpbmVhci1ncmFkaWVudCh0b3AsICMzNDk4ZGIsICMyOTgwYjkpO1xcbiAgYmFja2dyb3VuZC1pbWFnZTogLW1zLWxpbmVhci1ncmFkaWVudCh0b3AsICMzNDk4ZGIsICMyOTgwYjkpO1xcbiAgYmFja2dyb3VuZC1pbWFnZTogLW8tbGluZWFyLWdyYWRpZW50KHRvcCwgIzM0OThkYiwgIzI5ODBiOSk7XFxuICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gYm90dG9tLCAjMzQ5OGRiLCAjMjk4MGI5KTtcXG4gIC13ZWJraXQtYm9yZGVyLXJhZGl1czogMjg7XFxuICAtbW96LWJvcmRlci1yYWRpdXM6IDI4O1xcbiAgYm9yZGVyLXJhZGl1czogMjhweDtcXG4gIGZvbnQtZmFtaWx5OiBBcmlhbDtcXG4gIGNvbG9yOiAjZmZmZmZmO1xcbiAgcGFkZGluZzogM3B4IDEwcHggM3B4IDEwcHg7XFxuICBtYXJnaW4tbGVmdDogMTBweDtcXG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTsgfVxcblxcbi5iaW9qc19tc2FfbWVudWJhciAuYmlvanNfbXNhX21lbnViYXJfYWxpbms6aG92ZXIge1xcbiAgY3Vyc29yOiBwb2ludGVyOyB9XFxuXFxuLyoganF1ZXJ5IGRyb3Bkb3duIENTUyAqL1xcbi5kcm9wZG93biB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB6LWluZGV4OiA5OTk5OTk5O1xcbiAgZGlzcGxheTogbm9uZTsgfVxcblxcbi5kcm9wZG93biAuZHJvcGRvd24tbWVudSxcXG4uZHJvcGRvd24gLmRyb3Bkb3duLXBhbmVsIHtcXG4gIG1pbi13aWR0aDogMTYwcHg7XFxuICBtYXgtd2lkdGg6IDM2MHB4O1xcbiAgbGlzdC1zdHlsZTogbm9uZTtcXG4gIGJhY2tncm91bmQ6ICNGRkY7XFxuICBib3JkZXI6IHNvbGlkIDFweCAjREREO1xcbiAgYm9yZGVyOiBzb2xpZCAxcHggcmdiYSgwLCAwLCAwLCAwLjIpO1xcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xcbiAgYm94LXNoYWRvdzogMCA1cHggMTBweCByZ2JhKDAsIDAsIDAsIDAuMik7XFxuICBvdmVyZmxvdzogdmlzaWJsZTtcXG4gIHBhZGRpbmc6IDRweCAwO1xcbiAgbWFyZ2luOiAwOyB9XFxuXFxuLmRyb3Bkb3duIC5kcm9wZG93bi1wYW5lbCB7XFxuICBwYWRkaW5nOiAxMHB4OyB9XFxuXFxuLmRyb3Bkb3duLmRyb3Bkb3duLXNjcm9sbCAuZHJvcGRvd24tbWVudSxcXG4uZHJvcGRvd24uZHJvcGRvd24tc2Nyb2xsIC5kcm9wZG93bi1wYW5lbCB7XFxuICBtYXgtaGVpZ2h0OiAzNThweDtcXG4gIG92ZXJmbG93OiBhdXRvOyB9XFxuXFxuLmRyb3Bkb3duIC5kcm9wZG93bi1tZW51IExJIHtcXG4gIGxpc3Qtc3R5bGU6IG5vbmU7XFxuICBwYWRkaW5nOiAwIDA7XFxuICBtYXJnaW46IDA7XFxuICBsaW5lLWhlaWdodDogMThweDsgfVxcblxcbi5kcm9wZG93biAuZHJvcGRvd24tbWVudSBMSSxcXG4uZHJvcGRvd24gLmRyb3Bkb3duLW1lbnUgTEFCRUwge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICBjb2xvcjogIzU1NTtcXG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcXG4gIGxpbmUtaGVpZ2h0OiAxOHB4O1xcbiAgcGFkZGluZzogM3B4IDE1cHg7XFxuICB3aGl0ZS1zcGFjZTogbm93cmFwOyB9XFxuXFxuLmRyb3Bkb3duIC5kcm9wZG93bi1tZW51IExJOmhvdmVyLFxcbi5kcm9wZG93biAuZHJvcGRvd24tbWVudSBMQUJFTDpob3ZlciB7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDhDO1xcbiAgY29sb3I6ICNGRkY7XFxuICBjdXJzb3I6IHBvaW50ZXI7IH1cXG5cXG4uZHJvcGRvd24gLmRyb3Bkb3duLW1lbnUgLmRyb3Bkb3duLWRpdmlkZXIge1xcbiAgZm9udC1zaXplOiAxcHg7XFxuICBib3JkZXItdG9wOiBzb2xpZCAxcHggI0U1RTVFNTtcXG4gIHBhZGRpbmc6IDA7XFxuICBtYXJnaW46IDVweCAwOyB9XFxuXCI7IChyZXF1aXJlKFwiL2hvbWUvdHJhdmlzL2J1aWxkL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2Evbm9kZV9tb2R1bGVzL2Nzc2lmeVwiKSkoY3NzKTsgbW9kdWxlLmV4cG9ydHMgPSBjc3M7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9zcmMvaW5kZXhcIik7XG4iLCJ2YXIgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcbnZhciB2aWV3VHlwZSA9IHJlcXVpcmUoXCJiYWNrYm9uZS12aWV3alwiKTtcbnZhciBwbHVnaW5hdG9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHBsdWdpbmF0b3IgPSB2aWV3VHlwZS5leHRlbmQoe1xuICByZW5kZXJTdWJ2aWV3czogZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9sZEVsID0gdGhpcy5lbDtcbiAgICB2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIHRoaXMuc2V0RWxlbWVudChlbCk7XG4gICAgdmFyIGZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgaWYgKG9sZEVsLnBhcmVudE5vZGUgIT0gbnVsbCkge1xuICAgICAgb2xkRWwucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQodGhpcy5lbCwgb2xkRWwpO1xuICAgIH1cbiAgICB2YXIgdmlld3MgPSB0aGlzLl92aWV3cygpO1xuICAgIHZhciB2aWV3c1NvcnRlZCA9IF8uc29ydEJ5KHZpZXdzLCBmdW5jdGlvbihlbCkge1xuICAgICAgcmV0dXJuIGVsLm9yZGVyaW5nO1xuICAgIH0pO1xuICAgIHZhciB2aWV3LCBub2RlO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgIHZpZXdzU29ydGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2aWV3ID0gdmlld3NTb3J0ZWRbaV07XG4gICAgICB2aWV3LnJlbmRlcigpO1xuICAgICAgbm9kZSA9IHZpZXcuZWw7XG4gICAgICBpZiAobm9kZSAhPSBudWxsKSB7XG4gICAgICAgIGZyYWcuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGVsLmFwcGVuZENoaWxkKGZyYWcpO1xuICAgIHJldHVybiBlbDtcbiAgfSxcbiAgYWRkVmlldzogZnVuY3Rpb24oa2V5LCB2aWV3KSB7XG4gICAgdmFyIHZpZXdzID0gdGhpcy5fdmlld3MoKTtcbiAgICBpZiAodmlldyA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBcIkludmFsaWQgcGx1Z2luLiBcIjtcbiAgICB9XG4gICAgaWYgKHZpZXcub3JkZXJpbmcgPT0gbnVsbCkge1xuICAgICAgdmlldy5vcmRlcmluZyA9IGtleTtcbiAgICB9XG4gICAgcmV0dXJuIHZpZXdzW2tleV0gPSB2aWV3O1xuICB9LFxuICByZW1vdmVWaWV3czogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGVsLCBrZXk7XG4gICAgdmFyIHZpZXdzID0gdGhpcy5fdmlld3MoKTtcbiAgICBmb3IgKGtleSBpbiB2aWV3cykge1xuICAgICAgZWwgPSB2aWV3c1trZXldO1xuICAgICAgZWwudW5kZWxlZ2F0ZUV2ZW50cygpO1xuICAgICAgZWwudW5iaW5kKCk7XG4gICAgICBpZiAoZWwucmVtb3ZlVmlld3MgIT0gbnVsbCkge1xuICAgICAgICBlbC5yZW1vdmVWaWV3cygpO1xuICAgICAgfVxuICAgICAgZWwucmVtb3ZlKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnZpZXdzID0ge307XG4gIH0sXG4gIHJlbW92ZVZpZXc6IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciB2aWV3cyA9IHRoaXMuX3ZpZXdzKCk7XG4gICAgdmlld3Nba2V5XS5yZW1vdmUoKTtcbiAgICByZXR1cm4gZGVsZXRlIHZpZXdzW2tleV07XG4gIH0sXG4gIGdldFZpZXc6IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciB2aWV3cyA9IHRoaXMuX3ZpZXdzKCk7XG4gICAgcmV0dXJuIHZpZXdzW2tleV07XG4gIH0sXG4gIHJlbW92ZTogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5yZW1vdmVWaWV3cygpO1xuICAgIHJldHVybiB2aWV3VHlwZS5wcm90b3R5cGUucmVtb3ZlLmFwcGx5KHRoaXMpO1xuICB9LFxuICBfdmlld3M6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLnZpZXdzID09IG51bGwpIHtcbiAgICAgIHRoaXMudmlld3MgPSB7fTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudmlld3M7XG4gIH1cbn0pO1xuIiwiLy8gICAgIEJhY2tib25lLmpzIDEuMS4yXG5cbi8vICAgICAoYykgMjAxMC0yMDE0IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4vLyAgICAgQmFja2JvbmUgbWF5IGJlIGZyZWVseSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXG4vLyAgICAgRm9yIGFsbCBkZXRhaWxzIGFuZCBkb2N1bWVudGF0aW9uOlxuLy8gICAgIGh0dHA6Ly9iYWNrYm9uZWpzLm9yZ1xuXG52YXIgRXZlbnRzID0gcmVxdWlyZShcImJhY2tib25lLWV2ZW50cy1zdGFuZGFsb25lXCIpO1xudmFyIGV4dGVuZCA9IHJlcXVpcmUoXCJiYWNrYm9uZS1leHRlbmQtc3RhbmRhbG9uZVwiKTtcbnZhciBfID0gcmVxdWlyZShcInVuZGVyc2NvcmVcIik7XG52YXIgTW9kZWwgPSByZXF1aXJlKFwiLi9tb2RlbFwiKTtcblxuLy8gQ3JlYXRlIGxvY2FsIHJlZmVyZW5jZXMgdG8gYXJyYXkgbWV0aG9kcyB3ZSdsbCB3YW50IHRvIHVzZSBsYXRlci5cbnZhciBhcnJheSA9IFtdO1xudmFyIHNsaWNlID0gYXJyYXkuc2xpY2U7XG5cbi8vIEJhY2tib25lLkNvbGxlY3Rpb25cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gSWYgbW9kZWxzIHRlbmQgdG8gcmVwcmVzZW50IGEgc2luZ2xlIHJvdyBvZiBkYXRhLCBhIEJhY2tib25lIENvbGxlY3Rpb24gaXNcbi8vIG1vcmUgYW5hbG9nb3VzIHRvIGEgdGFibGUgZnVsbCBvZiBkYXRhIC4uLiBvciBhIHNtYWxsIHNsaWNlIG9yIHBhZ2Ugb2YgdGhhdFxuLy8gdGFibGUsIG9yIGEgY29sbGVjdGlvbiBvZiByb3dzIHRoYXQgYmVsb25nIHRvZ2V0aGVyIGZvciBhIHBhcnRpY3VsYXIgcmVhc29uXG4vLyAtLSBhbGwgb2YgdGhlIG1lc3NhZ2VzIGluIHRoaXMgcGFydGljdWxhciBmb2xkZXIsIGFsbCBvZiB0aGUgZG9jdW1lbnRzXG4vLyBiZWxvbmdpbmcgdG8gdGhpcyBwYXJ0aWN1bGFyIGF1dGhvciwgYW5kIHNvIG9uLiBDb2xsZWN0aW9ucyBtYWludGFpblxuLy8gaW5kZXhlcyBvZiB0aGVpciBtb2RlbHMsIGJvdGggaW4gb3JkZXIsIGFuZCBmb3IgbG9va3VwIGJ5IGBpZGAuXG5cbi8vIENyZWF0ZSBhIG5ldyAqKkNvbGxlY3Rpb24qKiwgcGVyaGFwcyB0byBjb250YWluIGEgc3BlY2lmaWMgdHlwZSBvZiBgbW9kZWxgLlxuLy8gSWYgYSBgY29tcGFyYXRvcmAgaXMgc3BlY2lmaWVkLCB0aGUgQ29sbGVjdGlvbiB3aWxsIG1haW50YWluXG4vLyBpdHMgbW9kZWxzIGluIHNvcnQgb3JkZXIsIGFzIHRoZXkncmUgYWRkZWQgYW5kIHJlbW92ZWQuXG52YXIgQ29sbGVjdGlvbiA9IGZ1bmN0aW9uKG1vZGVscywgb3B0aW9ucykge1xuICBvcHRpb25zIHx8IChvcHRpb25zID0ge30pO1xuICBpZiAob3B0aW9ucy5tb2RlbCkgdGhpcy5tb2RlbCA9IG9wdGlvbnMubW9kZWw7XG4gIGlmIChvcHRpb25zLmNvbXBhcmF0b3IgIT09IHZvaWQgMCkgdGhpcy5jb21wYXJhdG9yID0gb3B0aW9ucy5jb21wYXJhdG9yO1xuICB0aGlzLl9yZXNldCgpO1xuICB0aGlzLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgaWYgKG1vZGVscykgdGhpcy5yZXNldChtb2RlbHMsIF8uZXh0ZW5kKHtzaWxlbnQ6IHRydWV9LCBvcHRpb25zKSk7XG59O1xuXG4vLyBEZWZhdWx0IG9wdGlvbnMgZm9yIGBDb2xsZWN0aW9uI3NldGAuXG52YXIgc2V0T3B0aW9ucyA9IHthZGQ6IHRydWUsIHJlbW92ZTogdHJ1ZSwgbWVyZ2U6IHRydWV9O1xudmFyIGFkZE9wdGlvbnMgPSB7YWRkOiB0cnVlLCByZW1vdmU6IGZhbHNlfTtcblxuLy8gRGVmaW5lIHRoZSBDb2xsZWN0aW9uJ3MgaW5oZXJpdGFibGUgbWV0aG9kcy5cbl8uZXh0ZW5kKENvbGxlY3Rpb24ucHJvdG90eXBlLCBFdmVudHMsIHtcblxuICAvLyBUaGUgZGVmYXVsdCBtb2RlbCBmb3IgYSBjb2xsZWN0aW9uIGlzIGp1c3QgYSAqKkJhY2tib25lLk1vZGVsKiouXG4gIC8vIFRoaXMgc2hvdWxkIGJlIG92ZXJyaWRkZW4gaW4gbW9zdCBjYXNlcy5cbiAgbW9kZWw6IE1vZGVsLFxuXG4gIC8vIEluaXRpYWxpemUgaXMgYW4gZW1wdHkgZnVuY3Rpb24gYnkgZGVmYXVsdC4gT3ZlcnJpZGUgaXQgd2l0aCB5b3VyIG93blxuICAvLyBpbml0aWFsaXphdGlvbiBsb2dpYy5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXt9LFxuXG4gICAgLy8gVGhlIEpTT04gcmVwcmVzZW50YXRpb24gb2YgYSBDb2xsZWN0aW9uIGlzIGFuIGFycmF5IG9mIHRoZVxuICAgIC8vIG1vZGVscycgYXR0cmlidXRlcy5cbiAgdG9KU09OOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKG1vZGVsKXsgcmV0dXJuIG1vZGVsLnRvSlNPTihvcHRpb25zKTsgfSk7XG4gIH0sXG5cbiAgICAvLyBQcm94eSBgQmFja2JvbmUuc3luY2AgYnkgZGVmYXVsdC5cbiAgc3luYzogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIEJhY2tib25lLnN5bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfSxcblxuICAgIC8vIEFkZCBhIG1vZGVsLCBvciBsaXN0IG9mIG1vZGVscyB0byB0aGUgc2V0LlxuICBhZGQ6IGZ1bmN0aW9uKG1vZGVscywgb3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLnNldChtb2RlbHMsIF8uZXh0ZW5kKHttZXJnZTogZmFsc2V9LCBvcHRpb25zLCBhZGRPcHRpb25zKSk7XG4gIH0sXG5cbiAgICAvLyBSZW1vdmUgYSBtb2RlbCwgb3IgYSBsaXN0IG9mIG1vZGVscyBmcm9tIHRoZSBzZXQuXG4gIHJlbW92ZTogZnVuY3Rpb24obW9kZWxzLCBvcHRpb25zKSB7XG4gICAgdmFyIHNpbmd1bGFyID0gIV8uaXNBcnJheShtb2RlbHMpO1xuICAgIG1vZGVscyA9IHNpbmd1bGFyID8gW21vZGVsc10gOiBfLmNsb25lKG1vZGVscyk7XG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gbW9kZWxzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbW9kZWwgPSBtb2RlbHNbaV0gPSB0aGlzLmdldChtb2RlbHNbaV0pO1xuICAgICAgaWYgKCFtb2RlbCkgY29udGludWU7XG4gICAgICB2YXIgaWQgPSB0aGlzLm1vZGVsSWQobW9kZWwuYXR0cmlidXRlcyk7XG4gICAgICBpZiAoaWQgIT0gbnVsbCkgZGVsZXRlIHRoaXMuX2J5SWRbaWRdO1xuICAgICAgZGVsZXRlIHRoaXMuX2J5SWRbbW9kZWwuY2lkXTtcbiAgICAgIHZhciBpbmRleCA9IHRoaXMuaW5kZXhPZihtb2RlbCk7XG4gICAgICB0aGlzLm1vZGVscy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgdGhpcy5sZW5ndGgtLTtcbiAgICAgIGlmICghb3B0aW9ucy5zaWxlbnQpIHtcbiAgICAgICAgb3B0aW9ucy5pbmRleCA9IGluZGV4O1xuICAgICAgICBtb2RlbC50cmlnZ2VyKCdyZW1vdmUnLCBtb2RlbCwgdGhpcywgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgICB0aGlzLl9yZW1vdmVSZWZlcmVuY2UobW9kZWwsIG9wdGlvbnMpO1xuICAgIH1cbiAgICByZXR1cm4gc2luZ3VsYXIgPyBtb2RlbHNbMF0gOiBtb2RlbHM7XG4gIH0sXG5cbiAgICAvLyBVcGRhdGUgYSBjb2xsZWN0aW9uIGJ5IGBzZXRgLWluZyBhIG5ldyBsaXN0IG9mIG1vZGVscywgYWRkaW5nIG5ldyBvbmVzLFxuICAgIC8vIHJlbW92aW5nIG1vZGVscyB0aGF0IGFyZSBubyBsb25nZXIgcHJlc2VudCwgYW5kIG1lcmdpbmcgbW9kZWxzIHRoYXRcbiAgICAvLyBhbHJlYWR5IGV4aXN0IGluIHRoZSBjb2xsZWN0aW9uLCBhcyBuZWNlc3NhcnkuIFNpbWlsYXIgdG8gKipNb2RlbCNzZXQqKixcbiAgICAvLyB0aGUgY29yZSBvcGVyYXRpb24gZm9yIHVwZGF0aW5nIHRoZSBkYXRhIGNvbnRhaW5lZCBieSB0aGUgY29sbGVjdGlvbi5cbiAgc2V0OiBmdW5jdGlvbihtb2RlbHMsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gXy5kZWZhdWx0cyh7fSwgb3B0aW9ucywgc2V0T3B0aW9ucyk7XG4gICAgaWYgKG9wdGlvbnMucGFyc2UpIG1vZGVscyA9IHRoaXMucGFyc2UobW9kZWxzLCBvcHRpb25zKTtcbiAgICB2YXIgc2luZ3VsYXIgPSAhXy5pc0FycmF5KG1vZGVscyk7XG4gICAgbW9kZWxzID0gc2luZ3VsYXIgPyAobW9kZWxzID8gW21vZGVsc10gOiBbXSkgOiBtb2RlbHMuc2xpY2UoKTtcbiAgICB2YXIgaWQsIG1vZGVsLCBhdHRycywgZXhpc3RpbmcsIHNvcnQ7XG4gICAgdmFyIGF0ID0gb3B0aW9ucy5hdDtcbiAgICB2YXIgc29ydGFibGUgPSB0aGlzLmNvbXBhcmF0b3IgJiYgKGF0ID09IG51bGwpICYmIG9wdGlvbnMuc29ydCAhPT0gZmFsc2U7XG4gICAgdmFyIHNvcnRBdHRyID0gXy5pc1N0cmluZyh0aGlzLmNvbXBhcmF0b3IpID8gdGhpcy5jb21wYXJhdG9yIDogbnVsbDtcbiAgICB2YXIgdG9BZGQgPSBbXSwgdG9SZW1vdmUgPSBbXSwgbW9kZWxNYXAgPSB7fTtcbiAgICB2YXIgYWRkID0gb3B0aW9ucy5hZGQsIG1lcmdlID0gb3B0aW9ucy5tZXJnZSwgcmVtb3ZlID0gb3B0aW9ucy5yZW1vdmU7XG4gICAgdmFyIG9yZGVyID0gIXNvcnRhYmxlICYmIGFkZCAmJiByZW1vdmUgPyBbXSA6IGZhbHNlO1xuXG4gICAgLy8gVHVybiBiYXJlIG9iamVjdHMgaW50byBtb2RlbCByZWZlcmVuY2VzLCBhbmQgcHJldmVudCBpbnZhbGlkIG1vZGVsc1xuICAgIC8vIGZyb20gYmVpbmcgYWRkZWQuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IG1vZGVscy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgYXR0cnMgPSBtb2RlbHNbaV07XG5cbiAgICAgIC8vIElmIGEgZHVwbGljYXRlIGlzIGZvdW5kLCBwcmV2ZW50IGl0IGZyb20gYmVpbmcgYWRkZWQgYW5kXG4gICAgICAvLyBvcHRpb25hbGx5IG1lcmdlIGl0IGludG8gdGhlIGV4aXN0aW5nIG1vZGVsLlxuICAgICAgaWYgKGV4aXN0aW5nID0gdGhpcy5nZXQoYXR0cnMpKSB7XG4gICAgICAgIGlmIChyZW1vdmUpIG1vZGVsTWFwW2V4aXN0aW5nLmNpZF0gPSB0cnVlO1xuICAgICAgICBpZiAobWVyZ2UgJiYgYXR0cnMgIT09IGV4aXN0aW5nKSB7XG4gICAgICAgICAgYXR0cnMgPSB0aGlzLl9pc01vZGVsKGF0dHJzKSA/IGF0dHJzLmF0dHJpYnV0ZXMgOiBhdHRycztcbiAgICAgICAgICBpZiAob3B0aW9ucy5wYXJzZSkgYXR0cnMgPSBleGlzdGluZy5wYXJzZShhdHRycywgb3B0aW9ucyk7XG4gICAgICAgICAgZXhpc3Rpbmcuc2V0KGF0dHJzLCBvcHRpb25zKTtcbiAgICAgICAgICBpZiAoc29ydGFibGUgJiYgIXNvcnQgJiYgZXhpc3RpbmcuaGFzQ2hhbmdlZChzb3J0QXR0cikpIHNvcnQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIG1vZGVsc1tpXSA9IGV4aXN0aW5nO1xuXG4gICAgICAgIC8vIElmIHRoaXMgaXMgYSBuZXcsIHZhbGlkIG1vZGVsLCBwdXNoIGl0IHRvIHRoZSBgdG9BZGRgIGxpc3QuXG4gICAgICB9IGVsc2UgaWYgKGFkZCkge1xuICAgICAgICBtb2RlbCA9IG1vZGVsc1tpXSA9IHRoaXMuX3ByZXBhcmVNb2RlbChhdHRycywgb3B0aW9ucyk7XG4gICAgICAgIGlmICghbW9kZWwpIGNvbnRpbnVlO1xuICAgICAgICB0b0FkZC5wdXNoKG1vZGVsKTtcbiAgICAgICAgdGhpcy5fYWRkUmVmZXJlbmNlKG1vZGVsLCBvcHRpb25zKTtcbiAgICAgIH1cblxuICAgICAgLy8gRG8gbm90IGFkZCBtdWx0aXBsZSBtb2RlbHMgd2l0aCB0aGUgc2FtZSBgaWRgLlxuICAgICAgbW9kZWwgPSBleGlzdGluZyB8fCBtb2RlbDtcbiAgICAgIGlmICghbW9kZWwpIGNvbnRpbnVlO1xuICAgICAgaWQgPSB0aGlzLm1vZGVsSWQobW9kZWwuYXR0cmlidXRlcyk7XG4gICAgICBpZiAob3JkZXIgJiYgKG1vZGVsLmlzTmV3KCkgfHwgIW1vZGVsTWFwW2lkXSkpIG9yZGVyLnB1c2gobW9kZWwpO1xuICAgICAgbW9kZWxNYXBbaWRdID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgbm9uZXhpc3RlbnQgbW9kZWxzIGlmIGFwcHJvcHJpYXRlLlxuICAgIGlmIChyZW1vdmUpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSB0aGlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICghbW9kZWxNYXBbKG1vZGVsID0gdGhpcy5tb2RlbHNbaV0pLmNpZF0pIHRvUmVtb3ZlLnB1c2gobW9kZWwpO1xuICAgICAgfVxuICAgICAgaWYgKHRvUmVtb3ZlLmxlbmd0aCkgdGhpcy5yZW1vdmUodG9SZW1vdmUsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8vIFNlZSBpZiBzb3J0aW5nIGlzIG5lZWRlZCwgdXBkYXRlIGBsZW5ndGhgIGFuZCBzcGxpY2UgaW4gbmV3IG1vZGVscy5cbiAgICBpZiAodG9BZGQubGVuZ3RoIHx8IChvcmRlciAmJiBvcmRlci5sZW5ndGgpKSB7XG4gICAgICBpZiAoc29ydGFibGUpIHNvcnQgPSB0cnVlO1xuICAgICAgdGhpcy5sZW5ndGggKz0gdG9BZGQubGVuZ3RoO1xuICAgICAgaWYgKGF0ICE9IG51bGwpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IHRvQWRkLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdGhpcy5tb2RlbHMuc3BsaWNlKGF0ICsgaSwgMCwgdG9BZGRbaV0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAob3JkZXIpIHRoaXMubW9kZWxzLmxlbmd0aCA9IDA7XG4gICAgICAgIHZhciBvcmRlcmVkTW9kZWxzID0gb3JkZXIgfHwgdG9BZGQ7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBvcmRlcmVkTW9kZWxzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdGhpcy5tb2RlbHMucHVzaChvcmRlcmVkTW9kZWxzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNpbGVudGx5IHNvcnQgdGhlIGNvbGxlY3Rpb24gaWYgYXBwcm9wcmlhdGUuXG4gICAgaWYgKHNvcnQpIHRoaXMuc29ydCh7c2lsZW50OiB0cnVlfSk7XG5cbiAgICAvLyBVbmxlc3Mgc2lsZW5jZWQsIGl0J3MgdGltZSB0byBmaXJlIGFsbCBhcHByb3ByaWF0ZSBhZGQvc29ydCBldmVudHMuXG4gICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgICAgdmFyIGFkZE9wdHMgPSBhdCAhPSBudWxsID8gXy5jbG9uZShvcHRpb25zKSA6IG9wdGlvbnM7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gdG9BZGQubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGF0ICE9IG51bGwpIGFkZE9wdHMuaW5kZXggPSBhdCArIGk7XG4gICAgICAgIChtb2RlbCA9IHRvQWRkW2ldKS50cmlnZ2VyKCdhZGQnLCBtb2RlbCwgdGhpcywgYWRkT3B0cyk7XG4gICAgICB9XG4gICAgICBpZiAoc29ydCB8fCAob3JkZXIgJiYgb3JkZXIubGVuZ3RoKSkgdGhpcy50cmlnZ2VyKCdzb3J0JywgdGhpcywgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIHRoZSBhZGRlZCAob3IgbWVyZ2VkKSBtb2RlbCAob3IgbW9kZWxzKS5cbiAgICByZXR1cm4gc2luZ3VsYXIgPyBtb2RlbHNbMF0gOiBtb2RlbHM7XG4gIH0sXG5cbiAgICAvLyBXaGVuIHlvdSBoYXZlIG1vcmUgaXRlbXMgdGhhbiB5b3Ugd2FudCB0byBhZGQgb3IgcmVtb3ZlIGluZGl2aWR1YWxseSxcbiAgICAvLyB5b3UgY2FuIHJlc2V0IHRoZSBlbnRpcmUgc2V0IHdpdGggYSBuZXcgbGlzdCBvZiBtb2RlbHMsIHdpdGhvdXQgZmlyaW5nXG4gICAgLy8gYW55IGdyYW51bGFyIGBhZGRgIG9yIGByZW1vdmVgIGV2ZW50cy4gRmlyZXMgYHJlc2V0YCB3aGVuIGZpbmlzaGVkLlxuICAgIC8vIFVzZWZ1bCBmb3IgYnVsayBvcGVyYXRpb25zIGFuZCBvcHRpbWl6YXRpb25zLlxuICByZXNldDogZnVuY3Rpb24obW9kZWxzLCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gdGhpcy5tb2RlbHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuX3JlbW92ZVJlZmVyZW5jZSh0aGlzLm1vZGVsc1tpXSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIG9wdGlvbnMucHJldmlvdXNNb2RlbHMgPSB0aGlzLm1vZGVscztcbiAgICB0aGlzLl9yZXNldCgpO1xuICAgIG1vZGVscyA9IHRoaXMuYWRkKG1vZGVscywgXy5leHRlbmQoe3NpbGVudDogdHJ1ZX0sIG9wdGlvbnMpKTtcbiAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB0aGlzLnRyaWdnZXIoJ3Jlc2V0JywgdGhpcywgb3B0aW9ucyk7XG4gICAgcmV0dXJuIG1vZGVscztcbiAgfSxcblxuICAgIC8vIEFkZCBhIG1vZGVsIHRvIHRoZSBlbmQgb2YgdGhlIGNvbGxlY3Rpb24uXG4gIHB1c2g6IGZ1bmN0aW9uKG1vZGVsLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkKG1vZGVsLCBfLmV4dGVuZCh7YXQ6IHRoaXMubGVuZ3RofSwgb3B0aW9ucykpO1xuICB9LFxuXG4gICAgLy8gUmVtb3ZlIGEgbW9kZWwgZnJvbSB0aGUgZW5kIG9mIHRoZSBjb2xsZWN0aW9uLlxuICBwb3A6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICB2YXIgbW9kZWwgPSB0aGlzLmF0KHRoaXMubGVuZ3RoIC0gMSk7XG4gICAgdGhpcy5yZW1vdmUobW9kZWwsIG9wdGlvbnMpO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfSxcblxuICAgIC8vIEFkZCBhIG1vZGVsIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGNvbGxlY3Rpb24uXG4gIHVuc2hpZnQ6IGZ1bmN0aW9uKG1vZGVsLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkKG1vZGVsLCBfLmV4dGVuZCh7YXQ6IDB9LCBvcHRpb25zKSk7XG4gIH0sXG5cbiAgICAvLyBSZW1vdmUgYSBtb2RlbCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGNvbGxlY3Rpb24uXG4gIHNoaWZ0OiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgdmFyIG1vZGVsID0gdGhpcy5hdCgwKTtcbiAgICB0aGlzLnJlbW92ZShtb2RlbCwgb3B0aW9ucyk7XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9LFxuXG4gICAgLy8gU2xpY2Ugb3V0IGEgc3ViLWFycmF5IG9mIG1vZGVscyBmcm9tIHRoZSBjb2xsZWN0aW9uLlxuICBzbGljZTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNsaWNlLmFwcGx5KHRoaXMubW9kZWxzLCBhcmd1bWVudHMpO1xuICB9LFxuXG4gICAgLy8gR2V0IGEgbW9kZWwgZnJvbSB0aGUgc2V0IGJ5IGlkLlxuICBnZXQ6IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHZvaWQgMDtcbiAgICB2YXIgaWQgPSB0aGlzLm1vZGVsSWQodGhpcy5faXNNb2RlbChvYmopID8gb2JqLmF0dHJpYnV0ZXMgOiBvYmopO1xuICAgIHJldHVybiB0aGlzLl9ieUlkW29ial0gfHwgdGhpcy5fYnlJZFtpZF0gfHwgdGhpcy5fYnlJZFtvYmouY2lkXTtcbiAgfSxcblxuICAgIC8vIEdldCB0aGUgbW9kZWwgYXQgdGhlIGdpdmVuIGluZGV4LlxuICBhdDogZnVuY3Rpb24oaW5kZXgpIHtcbiAgICBpZiAoaW5kZXggPCAwKSBpbmRleCArPSB0aGlzLmxlbmd0aDtcbiAgICByZXR1cm4gdGhpcy5tb2RlbHNbaW5kZXhdO1xuICB9LFxuXG4gICAgLy8gUmV0dXJuIG1vZGVscyB3aXRoIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIFVzZWZ1bCBmb3Igc2ltcGxlIGNhc2VzIG9mXG4gICAgLy8gYGZpbHRlcmAuXG4gIHdoZXJlOiBmdW5jdGlvbihhdHRycywgZmlyc3QpIHtcbiAgICBpZiAoXy5pc0VtcHR5KGF0dHJzKSkgcmV0dXJuIGZpcnN0ID8gdm9pZCAwIDogW107XG4gICAgcmV0dXJuIHRoaXNbZmlyc3QgPyAnZmluZCcgOiAnZmlsdGVyJ10oZnVuY3Rpb24obW9kZWwpIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiBhdHRycykge1xuICAgICAgICBpZiAoYXR0cnNba2V5XSAhPT0gbW9kZWwuZ2V0KGtleSkpIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICB9LFxuXG4gICAgLy8gUmV0dXJuIHRoZSBmaXJzdCBtb2RlbCB3aXRoIG1hdGNoaW5nIGF0dHJpYnV0ZXMuIFVzZWZ1bCBmb3Igc2ltcGxlIGNhc2VzXG4gICAgLy8gb2YgYGZpbmRgLlxuICBmaW5kV2hlcmU6IGZ1bmN0aW9uKGF0dHJzKSB7XG4gICAgcmV0dXJuIHRoaXMud2hlcmUoYXR0cnMsIHRydWUpO1xuICB9LFxuXG4gICAgLy8gRm9yY2UgdGhlIGNvbGxlY3Rpb24gdG8gcmUtc29ydCBpdHNlbGYuIFlvdSBkb24ndCBuZWVkIHRvIGNhbGwgdGhpcyB1bmRlclxuICAgIC8vIG5vcm1hbCBjaXJjdW1zdGFuY2VzLCBhcyB0aGUgc2V0IHdpbGwgbWFpbnRhaW4gc29ydCBvcmRlciBhcyBlYWNoIGl0ZW1cbiAgICAvLyBpcyBhZGRlZC5cbiAgc29ydDogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgIGlmICghdGhpcy5jb21wYXJhdG9yKSB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBzb3J0IGEgc2V0IHdpdGhvdXQgYSBjb21wYXJhdG9yJyk7XG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcblxuICAgIC8vIFJ1biBzb3J0IGJhc2VkIG9uIHR5cGUgb2YgYGNvbXBhcmF0b3JgLlxuICAgIGlmIChfLmlzU3RyaW5nKHRoaXMuY29tcGFyYXRvcikgfHwgdGhpcy5jb21wYXJhdG9yLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdGhpcy5tb2RlbHMgPSB0aGlzLnNvcnRCeSh0aGlzLmNvbXBhcmF0b3IsIHRoaXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1vZGVscy5zb3J0KF8uYmluZCh0aGlzLmNvbXBhcmF0b3IsIHRoaXMpKTtcbiAgICB9XG5cbiAgICBpZiAoIW9wdGlvbnMuc2lsZW50KSB0aGlzLnRyaWdnZXIoJ3NvcnQnLCB0aGlzLCBvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICAgIC8vIFBsdWNrIGFuIGF0dHJpYnV0ZSBmcm9tIGVhY2ggbW9kZWwgaW4gdGhlIGNvbGxlY3Rpb24uXG4gIHBsdWNrOiBmdW5jdGlvbihhdHRyKSB7XG4gICAgcmV0dXJuIF8uaW52b2tlKHRoaXMubW9kZWxzLCAnZ2V0JywgYXR0cik7XG4gIH0sXG5cbiAgICAvLyBGZXRjaCB0aGUgZGVmYXVsdCBzZXQgb2YgbW9kZWxzIGZvciB0aGlzIGNvbGxlY3Rpb24sIHJlc2V0dGluZyB0aGVcbiAgICAvLyBjb2xsZWN0aW9uIHdoZW4gdGhleSBhcnJpdmUuIElmIGByZXNldDogdHJ1ZWAgaXMgcGFzc2VkLCB0aGUgcmVzcG9uc2VcbiAgICAvLyBkYXRhIHdpbGwgYmUgcGFzc2VkIHRocm91Z2ggdGhlIGByZXNldGAgbWV0aG9kIGluc3RlYWQgb2YgYHNldGAuXG4gIGZldGNoOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgPyBfLmNsb25lKG9wdGlvbnMpIDoge307XG4gICAgaWYgKG9wdGlvbnMucGFyc2UgPT09IHZvaWQgMCkgb3B0aW9ucy5wYXJzZSA9IHRydWU7XG4gICAgdmFyIHN1Y2Nlc3MgPSBvcHRpb25zLnN1Y2Nlc3M7XG4gICAgdmFyIGNvbGxlY3Rpb24gPSB0aGlzO1xuICAgIG9wdGlvbnMuc3VjY2VzcyA9IGZ1bmN0aW9uKHJlc3ApIHtcbiAgICAgIHZhciBtZXRob2QgPSBvcHRpb25zLnJlc2V0ID8gJ3Jlc2V0JyA6ICdzZXQnO1xuICAgICAgY29sbGVjdGlvblttZXRob2RdKHJlc3AsIG9wdGlvbnMpO1xuICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MoY29sbGVjdGlvbiwgcmVzcCwgb3B0aW9ucyk7XG4gICAgICBjb2xsZWN0aW9uLnRyaWdnZXIoJ3N5bmMnLCBjb2xsZWN0aW9uLCByZXNwLCBvcHRpb25zKTtcbiAgICB9O1xuICAgIHdyYXBFcnJvcih0aGlzLCBvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5zeW5jKCdyZWFkJywgdGhpcywgb3B0aW9ucyk7XG4gIH0sXG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgYSBtb2RlbCBpbiB0aGlzIGNvbGxlY3Rpb24uIEFkZCB0aGUgbW9kZWwgdG8gdGhlXG4gICAgLy8gY29sbGVjdGlvbiBpbW1lZGlhdGVseSwgdW5sZXNzIGB3YWl0OiB0cnVlYCBpcyBwYXNzZWQsIGluIHdoaWNoIGNhc2Ugd2VcbiAgICAvLyB3YWl0IGZvciB0aGUgc2VydmVyIHRvIGFncmVlLlxuICBjcmVhdGU6IGZ1bmN0aW9uKG1vZGVsLCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgPyBfLmNsb25lKG9wdGlvbnMpIDoge307XG4gICAgaWYgKCEobW9kZWwgPSB0aGlzLl9wcmVwYXJlTW9kZWwobW9kZWwsIG9wdGlvbnMpKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghb3B0aW9ucy53YWl0KSB0aGlzLmFkZChtb2RlbCwgb3B0aW9ucyk7XG4gICAgdmFyIGNvbGxlY3Rpb24gPSB0aGlzO1xuICAgIHZhciBzdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzO1xuICAgIG9wdGlvbnMuc3VjY2VzcyA9IGZ1bmN0aW9uKG1vZGVsLCByZXNwKSB7XG4gICAgICBpZiAob3B0aW9ucy53YWl0KSBjb2xsZWN0aW9uLmFkZChtb2RlbCwgb3B0aW9ucyk7XG4gICAgICBpZiAoc3VjY2Vzcykgc3VjY2Vzcyhtb2RlbCwgcmVzcCwgb3B0aW9ucyk7XG4gICAgfTtcbiAgICBtb2RlbC5zYXZlKG51bGwsIG9wdGlvbnMpO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfSxcblxuICAgIC8vICoqcGFyc2UqKiBjb252ZXJ0cyBhIHJlc3BvbnNlIGludG8gYSBsaXN0IG9mIG1vZGVscyB0byBiZSBhZGRlZCB0byB0aGVcbiAgICAvLyBjb2xsZWN0aW9uLiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBqdXN0IHRvIHBhc3MgaXQgdGhyb3VnaC5cbiAgcGFyc2U6IGZ1bmN0aW9uKHJlc3AsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gcmVzcDtcbiAgfSxcblxuICAgIC8vIENyZWF0ZSBhIG5ldyBjb2xsZWN0aW9uIHdpdGggYW4gaWRlbnRpY2FsIGxpc3Qgb2YgbW9kZWxzIGFzIHRoaXMgb25lLlxuICBjbG9uZTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMubW9kZWxzLCB7XG4gICAgICBtb2RlbDogdGhpcy5tb2RlbCxcbiAgICAgIGNvbXBhcmF0b3I6IHRoaXMuY29tcGFyYXRvclxuICAgIH0pO1xuICB9LFxuXG4gICAgLy8gRGVmaW5lIGhvdyB0byB1bmlxdWVseSBpZGVudGlmeSBtb2RlbHMgaW4gdGhlIGNvbGxlY3Rpb24uXG4gIG1vZGVsSWQ6IGZ1bmN0aW9uIChhdHRycykge1xuICAgIHJldHVybiBhdHRyc1t0aGlzLm1vZGVsLnByb3RvdHlwZS5pZEF0dHJpYnV0ZSB8fCAnaWQnXTtcbiAgfSxcblxuICAgIC8vIFByaXZhdGUgbWV0aG9kIHRvIHJlc2V0IGFsbCBpbnRlcm5hbCBzdGF0ZS4gQ2FsbGVkIHdoZW4gdGhlIGNvbGxlY3Rpb25cbiAgICAvLyBpcyBmaXJzdCBpbml0aWFsaXplZCBvciByZXNldC5cbiAgX3Jlc2V0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLmxlbmd0aCA9IDA7XG4gICAgdGhpcy5tb2RlbHMgPSBbXTtcbiAgICB0aGlzLl9ieUlkICA9IHt9O1xuICB9LFxuXG4gICAgLy8gUHJlcGFyZSBhIGhhc2ggb2YgYXR0cmlidXRlcyAob3Igb3RoZXIgbW9kZWwpIHRvIGJlIGFkZGVkIHRvIHRoaXNcbiAgICAvLyBjb2xsZWN0aW9uLlxuICBfcHJlcGFyZU1vZGVsOiBmdW5jdGlvbihhdHRycywgb3B0aW9ucykge1xuICAgIGlmICh0aGlzLl9pc01vZGVsKGF0dHJzKSkge1xuICAgICAgaWYgKCFhdHRycy5jb2xsZWN0aW9uKSBhdHRycy5jb2xsZWN0aW9uID0gdGhpcztcbiAgICAgIHJldHVybiBhdHRycztcbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgPyBfLmNsb25lKG9wdGlvbnMpIDoge307XG4gICAgb3B0aW9ucy5jb2xsZWN0aW9uID0gdGhpcztcbiAgICB2YXIgbW9kZWwgPSBuZXcgdGhpcy5tb2RlbChhdHRycywgb3B0aW9ucyk7XG4gICAgaWYgKCFtb2RlbC52YWxpZGF0aW9uRXJyb3IpIHJldHVybiBtb2RlbDtcbiAgICB0aGlzLnRyaWdnZXIoJ2ludmFsaWQnLCB0aGlzLCBtb2RlbC52YWxpZGF0aW9uRXJyb3IsIG9wdGlvbnMpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcblxuICAgIC8vIE1ldGhvZCBmb3IgY2hlY2tpbmcgd2hldGhlciBhbiBvYmplY3Qgc2hvdWxkIGJlIGNvbnNpZGVyZWQgYSBtb2RlbCBmb3JcbiAgICAvLyB0aGUgcHVycG9zZXMgb2YgYWRkaW5nIHRvIHRoZSBjb2xsZWN0aW9uLlxuICBfaXNNb2RlbDogZnVuY3Rpb24gKG1vZGVsKSB7XG4gICAgcmV0dXJuIG1vZGVsIGluc3RhbmNlb2YgTW9kZWw7XG4gIH0sXG5cbiAgICAvLyBJbnRlcm5hbCBtZXRob2QgdG8gY3JlYXRlIGEgbW9kZWwncyB0aWVzIHRvIGEgY29sbGVjdGlvbi5cbiAgX2FkZFJlZmVyZW5jZTogZnVuY3Rpb24obW9kZWwsIG9wdGlvbnMpIHtcbiAgICB0aGlzLl9ieUlkW21vZGVsLmNpZF0gPSBtb2RlbDtcbiAgICB2YXIgaWQgPSB0aGlzLm1vZGVsSWQobW9kZWwuYXR0cmlidXRlcyk7XG4gICAgaWYgKGlkICE9IG51bGwpIHRoaXMuX2J5SWRbaWRdID0gbW9kZWw7XG4gICAgbW9kZWwub24oJ2FsbCcsIHRoaXMuX29uTW9kZWxFdmVudCwgdGhpcyk7XG4gIH0sXG5cbiAgICAvLyBJbnRlcm5hbCBtZXRob2QgdG8gc2V2ZXIgYSBtb2RlbCdzIHRpZXMgdG8gYSBjb2xsZWN0aW9uLlxuICBfcmVtb3ZlUmVmZXJlbmNlOiBmdW5jdGlvbihtb2RlbCwgb3B0aW9ucykge1xuICAgIGlmICh0aGlzID09PSBtb2RlbC5jb2xsZWN0aW9uKSBkZWxldGUgbW9kZWwuY29sbGVjdGlvbjtcbiAgICBtb2RlbC5vZmYoJ2FsbCcsIHRoaXMuX29uTW9kZWxFdmVudCwgdGhpcyk7XG4gIH0sXG5cbiAgICAvLyBJbnRlcm5hbCBtZXRob2QgY2FsbGVkIGV2ZXJ5IHRpbWUgYSBtb2RlbCBpbiB0aGUgc2V0IGZpcmVzIGFuIGV2ZW50LlxuICAgIC8vIFNldHMgbmVlZCB0byB1cGRhdGUgdGhlaXIgaW5kZXhlcyB3aGVuIG1vZGVscyBjaGFuZ2UgaWRzLiBBbGwgb3RoZXJcbiAgICAvLyBldmVudHMgc2ltcGx5IHByb3h5IHRocm91Z2guIFwiYWRkXCIgYW5kIFwicmVtb3ZlXCIgZXZlbnRzIHRoYXQgb3JpZ2luYXRlXG4gICAgLy8gaW4gb3RoZXIgY29sbGVjdGlvbnMgYXJlIGlnbm9yZWQuXG4gIF9vbk1vZGVsRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50LCBtb2RlbCwgY29sbGVjdGlvbiwgb3B0aW9ucykge1xuICAgIGlmICgoZXZlbnQgPT09ICdhZGQnIHx8IGV2ZW50ID09PSAncmVtb3ZlJykgJiYgY29sbGVjdGlvbiAhPT0gdGhpcykgcmV0dXJuO1xuICAgIGlmIChldmVudCA9PT0gJ2Rlc3Ryb3knKSB0aGlzLnJlbW92ZShtb2RlbCwgb3B0aW9ucyk7XG4gICAgaWYgKGV2ZW50ID09PSAnY2hhbmdlJykge1xuICAgICAgdmFyIHByZXZJZCA9IHRoaXMubW9kZWxJZChtb2RlbC5wcmV2aW91c0F0dHJpYnV0ZXMoKSk7XG4gICAgICB2YXIgaWQgPSB0aGlzLm1vZGVsSWQobW9kZWwuYXR0cmlidXRlcyk7XG4gICAgICBpZiAocHJldklkICE9PSBpZCkge1xuICAgICAgICBpZiAocHJldklkICE9IG51bGwpIGRlbGV0ZSB0aGlzLl9ieUlkW3ByZXZJZF07XG4gICAgICAgIGlmIChpZCAhPSBudWxsKSB0aGlzLl9ieUlkW2lkXSA9IG1vZGVsO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnRyaWdnZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG59KTtcblxuLy8gVW5kZXJzY29yZSBtZXRob2RzIHRoYXQgd2Ugd2FudCB0byBpbXBsZW1lbnQgb24gdGhlIENvbGxlY3Rpb24uXG4vLyA5MCUgb2YgdGhlIGNvcmUgdXNlZnVsbmVzcyBvZiBCYWNrYm9uZSBDb2xsZWN0aW9ucyBpcyBhY3R1YWxseSBpbXBsZW1lbnRlZFxuLy8gcmlnaHQgaGVyZTpcbnZhciBtZXRob2RzID0gWydmb3JFYWNoJywgJ2VhY2gnLCAnbWFwJywgJ2NvbGxlY3QnLCAncmVkdWNlJywgJ2ZvbGRsJyxcbiAgICAnaW5qZWN0JywgJ3JlZHVjZVJpZ2h0JywgJ2ZvbGRyJywgJ2ZpbmQnLCAnZGV0ZWN0JywgJ2ZpbHRlcicsICdzZWxlY3QnLFxuICAgICdyZWplY3QnLCAnZXZlcnknLCAnYWxsJywgJ3NvbWUnLCAnYW55JywgJ2luY2x1ZGUnLCAnY29udGFpbnMnLCAnaW52b2tlJyxcbiAgICAnbWF4JywgJ21pbicsICd0b0FycmF5JywgJ3NpemUnLCAnZmlyc3QnLCAnaGVhZCcsICd0YWtlJywgJ2luaXRpYWwnLCAncmVzdCcsXG4gICAgJ3RhaWwnLCAnZHJvcCcsICdsYXN0JywgJ3dpdGhvdXQnLCAnZGlmZmVyZW5jZScsICdpbmRleE9mJywgJ3NodWZmbGUnLFxuICAgICdsYXN0SW5kZXhPZicsICdpc0VtcHR5JywgJ2NoYWluJywgJ3NhbXBsZScsICdwYXJ0aXRpb24nXTtcblxuLy8gTWl4IGluIGVhY2ggVW5kZXJzY29yZSBtZXRob2QgYXMgYSBwcm94eSB0byBgQ29sbGVjdGlvbiNtb2RlbHNgLlxuXy5lYWNoKG1ldGhvZHMsIGZ1bmN0aW9uKG1ldGhvZCkge1xuICBpZiAoIV9bbWV0aG9kXSkgcmV0dXJuO1xuICBDb2xsZWN0aW9uLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgYXJncy51bnNoaWZ0KHRoaXMubW9kZWxzKTtcbiAgICByZXR1cm4gX1ttZXRob2RdLmFwcGx5KF8sIGFyZ3MpO1xuICB9O1xufSk7XG5cbi8vIFVuZGVyc2NvcmUgbWV0aG9kcyB0aGF0IHRha2UgYSBwcm9wZXJ0eSBuYW1lIGFzIGFuIGFyZ3VtZW50LlxudmFyIGF0dHJpYnV0ZU1ldGhvZHMgPSBbJ2dyb3VwQnknLCAnY291bnRCeScsICdzb3J0QnknLCAnaW5kZXhCeSddO1xuXG4vLyBVc2UgYXR0cmlidXRlcyBpbnN0ZWFkIG9mIHByb3BlcnRpZXMuXG5fLmVhY2goYXR0cmlidXRlTWV0aG9kcywgZnVuY3Rpb24obWV0aG9kKSB7XG4gIGlmICghX1ttZXRob2RdKSByZXR1cm47XG4gIENvbGxlY3Rpb24ucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbih2YWx1ZSwgY29udGV4dCkge1xuICAgIHZhciBpdGVyYXRvciA9IF8uaXNGdW5jdGlvbih2YWx1ZSkgPyB2YWx1ZSA6IGZ1bmN0aW9uKG1vZGVsKSB7XG4gICAgICByZXR1cm4gbW9kZWwuZ2V0KHZhbHVlKTtcbiAgICB9O1xuICAgIHJldHVybiBfW21ldGhvZF0odGhpcy5tb2RlbHMsIGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgfTtcbn0pO1xuXG4vLyBzZXR1cCBpbmhlcml0YW5jZVxuQ29sbGVjdGlvbi5leHRlbmQgPSBleHRlbmQ7XG5tb2R1bGUuZXhwb3J0cyA9IENvbGxlY3Rpb247XG4iLCJtb2R1bGUuZXhwb3J0cy5Nb2RlbCA9IHJlcXVpcmUoXCIuL21vZGVsXCIpO1xubW9kdWxlLmV4cG9ydHMuQ29sbGVjdGlvbiA9IHJlcXVpcmUoXCIuL2NvbGxlY3Rpb25cIik7XG5tb2R1bGUuZXhwb3J0cy5FdmVudHMgPSByZXF1aXJlKFwiYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmVcIik7XG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgPSByZXF1aXJlKFwiYmFja2JvbmUtZXh0ZW5kLXN0YW5kYWxvbmVcIik7XG4iLCIvLyAgICAgQmFja2JvbmUuanMgMS4xLjJcblxuLy8gICAgIChjKSAyMDEwLTIwMTQgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbi8vICAgICBCYWNrYm9uZSBtYXkgYmUgZnJlZWx5IGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbi8vICAgICBGb3IgYWxsIGRldGFpbHMgYW5kIGRvY3VtZW50YXRpb246XG4vLyAgICAgaHR0cDovL2JhY2tib25lanMub3JnXG5cbnZhciBFdmVudHMgPSByZXF1aXJlKFwiYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmVcIik7XG52YXIgZXh0ZW5kID0gcmVxdWlyZShcImJhY2tib25lLWV4dGVuZC1zdGFuZGFsb25lXCIpO1xudmFyIF8gPSByZXF1aXJlKFwidW5kZXJzY29yZVwiKTtcblxuLy8gQmFja2JvbmUuTW9kZWxcbi8vIC0tLS0tLS0tLS0tLS0tXG5cbi8vIEJhY2tib25lICoqTW9kZWxzKiogYXJlIHRoZSBiYXNpYyBkYXRhIG9iamVjdCBpbiB0aGUgZnJhbWV3b3JrIC0tXG4vLyBmcmVxdWVudGx5IHJlcHJlc2VudGluZyBhIHJvdyBpbiBhIHRhYmxlIGluIGEgZGF0YWJhc2Ugb24geW91ciBzZXJ2ZXIuXG4vLyBBIGRpc2NyZXRlIGNodW5rIG9mIGRhdGEgYW5kIGEgYnVuY2ggb2YgdXNlZnVsLCByZWxhdGVkIG1ldGhvZHMgZm9yXG4vLyBwZXJmb3JtaW5nIGNvbXB1dGF0aW9ucyBhbmQgdHJhbnNmb3JtYXRpb25zIG9uIHRoYXQgZGF0YS5cblxuLy8gQ3JlYXRlIGEgbmV3IG1vZGVsIHdpdGggdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGVzLiBBIGNsaWVudCBpZCAoYGNpZGApXG4vLyBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBhbmQgYXNzaWduZWQgZm9yIHlvdS5cbnZhciBNb2RlbCA9IGZ1bmN0aW9uKGF0dHJpYnV0ZXMsIG9wdGlvbnMpIHtcbiAgdmFyIGF0dHJzID0gYXR0cmlidXRlcyB8fCB7fTtcbiAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcbiAgdGhpcy5jaWQgPSBfLnVuaXF1ZUlkKCdjJyk7XG4gIHRoaXMuYXR0cmlidXRlcyA9IHt9O1xuICBpZiAob3B0aW9ucy5jb2xsZWN0aW9uKSB0aGlzLmNvbGxlY3Rpb24gPSBvcHRpb25zLmNvbGxlY3Rpb247XG4gIGlmIChvcHRpb25zLnBhcnNlKSBhdHRycyA9IHRoaXMucGFyc2UoYXR0cnMsIG9wdGlvbnMpIHx8IHt9O1xuICBhdHRycyA9IF8uZGVmYXVsdHMoe30sIGF0dHJzLCBfLnJlc3VsdCh0aGlzLCAnZGVmYXVsdHMnKSk7XG4gIHRoaXMuc2V0KGF0dHJzLCBvcHRpb25zKTtcbiAgdGhpcy5jaGFuZ2VkID0ge307XG4gIHRoaXMuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufTtcblxuLy8gQXR0YWNoIGFsbCBpbmhlcml0YWJsZSBtZXRob2RzIHRvIHRoZSBNb2RlbCBwcm90b3R5cGUuXG5fLmV4dGVuZChNb2RlbC5wcm90b3R5cGUsIEV2ZW50cywge1xuXG4gIC8vIEEgaGFzaCBvZiBhdHRyaWJ1dGVzIHdob3NlIGN1cnJlbnQgYW5kIHByZXZpb3VzIHZhbHVlIGRpZmZlci5cbiAgY2hhbmdlZDogbnVsbCxcblxuICAvLyBUaGUgdmFsdWUgcmV0dXJuZWQgZHVyaW5nIHRoZSBsYXN0IGZhaWxlZCB2YWxpZGF0aW9uLlxuICB2YWxpZGF0aW9uRXJyb3I6IG51bGwsXG5cbiAgICAvLyBUaGUgZGVmYXVsdCBuYW1lIGZvciB0aGUgSlNPTiBgaWRgIGF0dHJpYnV0ZSBpcyBgXCJpZFwiYC4gTW9uZ29EQiBhbmRcbiAgICAvLyBDb3VjaERCIHVzZXJzIG1heSB3YW50IHRvIHNldCB0aGlzIHRvIGBcIl9pZFwiYC5cbiAgaWRBdHRyaWJ1dGU6ICdpZCcsXG5cbiAgICAvLyBJbml0aWFsaXplIGlzIGFuIGVtcHR5IGZ1bmN0aW9uIGJ5IGRlZmF1bHQuIE92ZXJyaWRlIGl0IHdpdGggeW91ciBvd25cbiAgICAvLyBpbml0aWFsaXphdGlvbiBsb2dpYy5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXt9LFxuXG4gICAgLy8gUmV0dXJuIGEgY29weSBvZiB0aGUgbW9kZWwncyBgYXR0cmlidXRlc2Agb2JqZWN0LlxuICB0b0pTT046IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gXy5jbG9uZSh0aGlzLmF0dHJpYnV0ZXMpO1xuICB9LFxuXG4gICAgLy8gUHJveHkgYEJhY2tib25lLnN5bmNgIGJ5IGRlZmF1bHQgLS0gYnV0IG92ZXJyaWRlIHRoaXMgaWYgeW91IG5lZWRcbiAgICAvLyBjdXN0b20gc3luY2luZyBzZW1hbnRpY3MgZm9yICp0aGlzKiBwYXJ0aWN1bGFyIG1vZGVsLlxuICBzeW5jOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gQmFja2JvbmUuc3luYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9LFxuXG4gICAgLy8gR2V0IHRoZSB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUuXG4gIGdldDogZnVuY3Rpb24oYXR0cikge1xuICAgIHJldHVybiB0aGlzLmF0dHJpYnV0ZXNbYXR0cl07XG4gIH0sXG5cbiAgICAvLyBHZXQgdGhlIEhUTUwtZXNjYXBlZCB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUuXG4gIGVzY2FwZTogZnVuY3Rpb24oYXR0cikge1xuICAgIHJldHVybiBfLmVzY2FwZSh0aGlzLmdldChhdHRyKSk7XG4gIH0sXG5cbiAgICAvLyBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXR0cmlidXRlIGNvbnRhaW5zIGEgdmFsdWUgdGhhdCBpcyBub3QgbnVsbFxuICAgIC8vIG9yIHVuZGVmaW5lZC5cbiAgaGFzOiBmdW5jdGlvbihhdHRyKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGF0dHIpICE9IG51bGw7XG4gIH0sXG5cbiAgICAvLyBTZXQgYSBoYXNoIG9mIG1vZGVsIGF0dHJpYnV0ZXMgb24gdGhlIG9iamVjdCwgZmlyaW5nIGBcImNoYW5nZVwiYC4gVGhpcyBpc1xuICAgIC8vIHRoZSBjb3JlIHByaW1pdGl2ZSBvcGVyYXRpb24gb2YgYSBtb2RlbCwgdXBkYXRpbmcgdGhlIGRhdGEgYW5kIG5vdGlmeWluZ1xuICAgIC8vIGFueW9uZSB3aG8gbmVlZHMgdG8ga25vdyBhYm91dCB0aGUgY2hhbmdlIGluIHN0YXRlLiBUaGUgaGVhcnQgb2YgdGhlIGJlYXN0LlxuICBzZXQ6IGZ1bmN0aW9uKGtleSwgdmFsLCBvcHRpb25zKSB7XG4gICAgdmFyIGF0dHIsIGF0dHJzLCB1bnNldCwgY2hhbmdlcywgc2lsZW50LCBjaGFuZ2luZywgcHJldiwgY3VycmVudDtcbiAgICBpZiAoa2V5ID09IG51bGwpIHJldHVybiB0aGlzO1xuXG4gICAgLy8gSGFuZGxlIGJvdGggYFwia2V5XCIsIHZhbHVlYCBhbmQgYHtrZXk6IHZhbHVlfWAgLXN0eWxlIGFyZ3VtZW50cy5cbiAgICBpZiAodHlwZW9mIGtleSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGF0dHJzID0ga2V5O1xuICAgICAgb3B0aW9ucyA9IHZhbDtcbiAgICB9IGVsc2Uge1xuICAgICAgKGF0dHJzID0ge30pW2tleV0gPSB2YWw7XG4gICAgfVxuXG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcblxuICAgIC8vIFJ1biB2YWxpZGF0aW9uLlxuICAgIGlmICghdGhpcy5fdmFsaWRhdGUoYXR0cnMsIG9wdGlvbnMpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBFeHRyYWN0IGF0dHJpYnV0ZXMgYW5kIG9wdGlvbnMuXG4gICAgdW5zZXQgICAgICAgICAgID0gb3B0aW9ucy51bnNldDtcbiAgICBzaWxlbnQgICAgICAgICAgPSBvcHRpb25zLnNpbGVudDtcbiAgICBjaGFuZ2VzICAgICAgICAgPSBbXTtcbiAgICBjaGFuZ2luZyAgICAgICAgPSB0aGlzLl9jaGFuZ2luZztcbiAgICB0aGlzLl9jaGFuZ2luZyAgPSB0cnVlO1xuXG4gICAgaWYgKCFjaGFuZ2luZykge1xuICAgICAgdGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzID0gXy5jbG9uZSh0aGlzLmF0dHJpYnV0ZXMpO1xuICAgICAgdGhpcy5jaGFuZ2VkID0ge307XG4gICAgfVxuICAgIGN1cnJlbnQgPSB0aGlzLmF0dHJpYnV0ZXMsIHByZXYgPSB0aGlzLl9wcmV2aW91c0F0dHJpYnV0ZXM7XG5cbiAgICAvLyBDaGVjayBmb3IgY2hhbmdlcyBvZiBgaWRgLlxuICAgIGlmICh0aGlzLmlkQXR0cmlidXRlIGluIGF0dHJzKSB0aGlzLmlkID0gYXR0cnNbdGhpcy5pZEF0dHJpYnV0ZV07XG5cbiAgICAvLyBGb3IgZWFjaCBgc2V0YCBhdHRyaWJ1dGUsIHVwZGF0ZSBvciBkZWxldGUgdGhlIGN1cnJlbnQgdmFsdWUuXG4gICAgZm9yIChhdHRyIGluIGF0dHJzKSB7XG4gICAgICB2YWwgPSBhdHRyc1thdHRyXTtcbiAgICAgIGlmICghXy5pc0VxdWFsKGN1cnJlbnRbYXR0cl0sIHZhbCkpIGNoYW5nZXMucHVzaChhdHRyKTtcbiAgICAgIGlmICghXy5pc0VxdWFsKHByZXZbYXR0cl0sIHZhbCkpIHtcbiAgICAgICAgdGhpcy5jaGFuZ2VkW2F0dHJdID0gdmFsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuY2hhbmdlZFthdHRyXTtcbiAgICAgIH1cbiAgICAgIHVuc2V0ID8gZGVsZXRlIGN1cnJlbnRbYXR0cl0gOiBjdXJyZW50W2F0dHJdID0gdmFsO1xuICAgIH1cblxuICAgIC8vIFRyaWdnZXIgYWxsIHJlbGV2YW50IGF0dHJpYnV0ZSBjaGFuZ2VzLlxuICAgIGlmICghc2lsZW50KSB7XG4gICAgICBpZiAoY2hhbmdlcy5sZW5ndGgpIHRoaXMuX3BlbmRpbmcgPSBvcHRpb25zO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGNoYW5nZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy50cmlnZ2VyKCdjaGFuZ2U6JyArIGNoYW5nZXNbaV0sIHRoaXMsIGN1cnJlbnRbY2hhbmdlc1tpXV0sIG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFlvdSBtaWdodCBiZSB3b25kZXJpbmcgd2h5IHRoZXJlJ3MgYSBgd2hpbGVgIGxvb3AgaGVyZS4gQ2hhbmdlcyBjYW5cbiAgICAvLyBiZSByZWN1cnNpdmVseSBuZXN0ZWQgd2l0aGluIGBcImNoYW5nZVwiYCBldmVudHMuXG4gICAgaWYgKGNoYW5naW5nKSByZXR1cm4gdGhpcztcbiAgICBpZiAoIXNpbGVudCkge1xuICAgICAgd2hpbGUgKHRoaXMuX3BlbmRpbmcpIHtcbiAgICAgICAgb3B0aW9ucyA9IHRoaXMuX3BlbmRpbmc7XG4gICAgICAgIHRoaXMuX3BlbmRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50cmlnZ2VyKCdjaGFuZ2UnLCB0aGlzLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5fcGVuZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuX2NoYW5naW5nID0gZmFsc2U7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgICAvLyBSZW1vdmUgYW4gYXR0cmlidXRlIGZyb20gdGhlIG1vZGVsLCBmaXJpbmcgYFwiY2hhbmdlXCJgLiBgdW5zZXRgIGlzIGEgbm9vcFxuICAgIC8vIGlmIHRoZSBhdHRyaWJ1dGUgZG9lc24ndCBleGlzdC5cbiAgdW5zZXQ6IGZ1bmN0aW9uKGF0dHIsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5zZXQoYXR0ciwgdm9pZCAwLCBfLmV4dGVuZCh7fSwgb3B0aW9ucywge3Vuc2V0OiB0cnVlfSkpO1xuICB9LFxuXG4gICAgLy8gQ2xlYXIgYWxsIGF0dHJpYnV0ZXMgb24gdGhlIG1vZGVsLCBmaXJpbmcgYFwiY2hhbmdlXCJgLlxuICBjbGVhcjogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgIHZhciBhdHRycyA9IHt9O1xuICAgIGZvciAodmFyIGtleSBpbiB0aGlzLmF0dHJpYnV0ZXMpIGF0dHJzW2tleV0gPSB2b2lkIDA7XG4gICAgcmV0dXJuIHRoaXMuc2V0KGF0dHJzLCBfLmV4dGVuZCh7fSwgb3B0aW9ucywge3Vuc2V0OiB0cnVlfSkpO1xuICB9LFxuXG4gICAgLy8gRGV0ZXJtaW5lIGlmIHRoZSBtb2RlbCBoYXMgY2hhbmdlZCBzaW5jZSB0aGUgbGFzdCBgXCJjaGFuZ2VcImAgZXZlbnQuXG4gICAgLy8gSWYgeW91IHNwZWNpZnkgYW4gYXR0cmlidXRlIG5hbWUsIGRldGVybWluZSBpZiB0aGF0IGF0dHJpYnV0ZSBoYXMgY2hhbmdlZC5cbiAgaGFzQ2hhbmdlZDogZnVuY3Rpb24oYXR0cikge1xuICAgIGlmIChhdHRyID09IG51bGwpIHJldHVybiAhXy5pc0VtcHR5KHRoaXMuY2hhbmdlZCk7XG4gICAgcmV0dXJuIF8uaGFzKHRoaXMuY2hhbmdlZCwgYXR0cik7XG4gIH0sXG5cbiAgICAvLyBSZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIHRoZSBhdHRyaWJ1dGVzIHRoYXQgaGF2ZSBjaGFuZ2VkLCBvclxuICAgIC8vIGZhbHNlIGlmIHRoZXJlIGFyZSBubyBjaGFuZ2VkIGF0dHJpYnV0ZXMuIFVzZWZ1bCBmb3IgZGV0ZXJtaW5pbmcgd2hhdFxuICAgIC8vIHBhcnRzIG9mIGEgdmlldyBuZWVkIHRvIGJlIHVwZGF0ZWQgYW5kL29yIHdoYXQgYXR0cmlidXRlcyBuZWVkIHRvIGJlXG4gICAgLy8gcGVyc2lzdGVkIHRvIHRoZSBzZXJ2ZXIuIFVuc2V0IGF0dHJpYnV0ZXMgd2lsbCBiZSBzZXQgdG8gdW5kZWZpbmVkLlxuICAgIC8vIFlvdSBjYW4gYWxzbyBwYXNzIGFuIGF0dHJpYnV0ZXMgb2JqZWN0IHRvIGRpZmYgYWdhaW5zdCB0aGUgbW9kZWwsXG4gICAgLy8gZGV0ZXJtaW5pbmcgaWYgdGhlcmUgKndvdWxkIGJlKiBhIGNoYW5nZS5cbiAgY2hhbmdlZEF0dHJpYnV0ZXM6IGZ1bmN0aW9uKGRpZmYpIHtcbiAgICBpZiAoIWRpZmYpIHJldHVybiB0aGlzLmhhc0NoYW5nZWQoKSA/IF8uY2xvbmUodGhpcy5jaGFuZ2VkKSA6IGZhbHNlO1xuICAgIHZhciB2YWwsIGNoYW5nZWQgPSBmYWxzZTtcbiAgICB2YXIgb2xkID0gdGhpcy5fY2hhbmdpbmcgPyB0aGlzLl9wcmV2aW91c0F0dHJpYnV0ZXMgOiB0aGlzLmF0dHJpYnV0ZXM7XG4gICAgZm9yICh2YXIgYXR0ciBpbiBkaWZmKSB7XG4gICAgICBpZiAoXy5pc0VxdWFsKG9sZFthdHRyXSwgKHZhbCA9IGRpZmZbYXR0cl0pKSkgY29udGludWU7XG4gICAgICAoY2hhbmdlZCB8fCAoY2hhbmdlZCA9IHt9KSlbYXR0cl0gPSB2YWw7XG4gICAgfVxuICAgIHJldHVybiBjaGFuZ2VkO1xuICB9LFxuXG4gICAgLy8gR2V0IHRoZSBwcmV2aW91cyB2YWx1ZSBvZiBhbiBhdHRyaWJ1dGUsIHJlY29yZGVkIGF0IHRoZSB0aW1lIHRoZSBsYXN0XG4gICAgLy8gYFwiY2hhbmdlXCJgIGV2ZW50IHdhcyBmaXJlZC5cbiAgcHJldmlvdXM6IGZ1bmN0aW9uKGF0dHIpIHtcbiAgICBpZiAoYXR0ciA9PSBudWxsIHx8ICF0aGlzLl9wcmV2aW91c0F0dHJpYnV0ZXMpIHJldHVybiBudWxsO1xuICAgIHJldHVybiB0aGlzLl9wcmV2aW91c0F0dHJpYnV0ZXNbYXR0cl07XG4gIH0sXG5cbiAgICAvLyBHZXQgYWxsIG9mIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBtb2RlbCBhdCB0aGUgdGltZSBvZiB0aGUgcHJldmlvdXNcbiAgICAvLyBgXCJjaGFuZ2VcImAgZXZlbnQuXG4gIHByZXZpb3VzQXR0cmlidXRlczogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIF8uY2xvbmUodGhpcy5fcHJldmlvdXNBdHRyaWJ1dGVzKTtcbiAgfSxcblxuICAgIC8vIEZldGNoIHRoZSBtb2RlbCBmcm9tIHRoZSBzZXJ2ZXIuIElmIHRoZSBzZXJ2ZXIncyByZXByZXNlbnRhdGlvbiBvZiB0aGVcbiAgICAvLyBtb2RlbCBkaWZmZXJzIGZyb20gaXRzIGN1cnJlbnQgYXR0cmlidXRlcywgdGhleSB3aWxsIGJlIG92ZXJyaWRkZW4sXG4gICAgLy8gdHJpZ2dlcmluZyBhIGBcImNoYW5nZVwiYCBldmVudC5cbiAgZmV0Y2g6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyA/IF8uY2xvbmUob3B0aW9ucykgOiB7fTtcbiAgICBpZiAob3B0aW9ucy5wYXJzZSA9PT0gdm9pZCAwKSBvcHRpb25zLnBhcnNlID0gdHJ1ZTtcbiAgICB2YXIgbW9kZWwgPSB0aGlzO1xuICAgIHZhciBzdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzO1xuICAgIG9wdGlvbnMuc3VjY2VzcyA9IGZ1bmN0aW9uKHJlc3ApIHtcbiAgICAgIGlmICghbW9kZWwuc2V0KG1vZGVsLnBhcnNlKHJlc3AsIG9wdGlvbnMpLCBvcHRpb25zKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MobW9kZWwsIHJlc3AsIG9wdGlvbnMpO1xuICAgICAgbW9kZWwudHJpZ2dlcignc3luYycsIG1vZGVsLCByZXNwLCBvcHRpb25zKTtcbiAgICB9O1xuICAgIHdyYXBFcnJvcih0aGlzLCBvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5zeW5jKCdyZWFkJywgdGhpcywgb3B0aW9ucyk7XG4gIH0sXG5cbiAgICAvLyBTZXQgYSBoYXNoIG9mIG1vZGVsIGF0dHJpYnV0ZXMsIGFuZCBzeW5jIHRoZSBtb2RlbCB0byB0aGUgc2VydmVyLlxuICAgIC8vIElmIHRoZSBzZXJ2ZXIgcmV0dXJucyBhbiBhdHRyaWJ1dGVzIGhhc2ggdGhhdCBkaWZmZXJzLCB0aGUgbW9kZWwnc1xuICAgIC8vIHN0YXRlIHdpbGwgYmUgYHNldGAgYWdhaW4uXG4gIHNhdmU6IGZ1bmN0aW9uKGtleSwgdmFsLCBvcHRpb25zKSB7XG4gICAgdmFyIGF0dHJzLCBtZXRob2QsIHhociwgYXR0cmlidXRlcyA9IHRoaXMuYXR0cmlidXRlcztcblxuICAgIC8vIEhhbmRsZSBib3RoIGBcImtleVwiLCB2YWx1ZWAgYW5kIGB7a2V5OiB2YWx1ZX1gIC1zdHlsZSBhcmd1bWVudHMuXG4gICAgaWYgKGtleSA9PSBudWxsIHx8IHR5cGVvZiBrZXkgPT09ICdvYmplY3QnKSB7XG4gICAgICBhdHRycyA9IGtleTtcbiAgICAgIG9wdGlvbnMgPSB2YWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIChhdHRycyA9IHt9KVtrZXldID0gdmFsO1xuICAgIH1cblxuICAgIG9wdGlvbnMgPSBfLmV4dGVuZCh7dmFsaWRhdGU6IHRydWV9LCBvcHRpb25zKTtcblxuICAgIC8vIElmIHdlJ3JlIG5vdCB3YWl0aW5nIGFuZCBhdHRyaWJ1dGVzIGV4aXN0LCBzYXZlIGFjdHMgYXNcbiAgICAvLyBgc2V0KGF0dHIpLnNhdmUobnVsbCwgb3B0cylgIHdpdGggdmFsaWRhdGlvbi4gT3RoZXJ3aXNlLCBjaGVjayBpZlxuICAgIC8vIHRoZSBtb2RlbCB3aWxsIGJlIHZhbGlkIHdoZW4gdGhlIGF0dHJpYnV0ZXMsIGlmIGFueSwgYXJlIHNldC5cbiAgICBpZiAoYXR0cnMgJiYgIW9wdGlvbnMud2FpdCkge1xuICAgICAgaWYgKCF0aGlzLnNldChhdHRycywgb3B0aW9ucykpIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF0aGlzLl92YWxpZGF0ZShhdHRycywgb3B0aW9ucykpIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBTZXQgdGVtcG9yYXJ5IGF0dHJpYnV0ZXMgaWYgYHt3YWl0OiB0cnVlfWAuXG4gICAgaWYgKGF0dHJzICYmIG9wdGlvbnMud2FpdCkge1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzID0gXy5leHRlbmQoe30sIGF0dHJpYnV0ZXMsIGF0dHJzKTtcbiAgICB9XG5cbiAgICAvLyBBZnRlciBhIHN1Y2Nlc3NmdWwgc2VydmVyLXNpZGUgc2F2ZSwgdGhlIGNsaWVudCBpcyAob3B0aW9uYWxseSlcbiAgICAvLyB1cGRhdGVkIHdpdGggdGhlIHNlcnZlci1zaWRlIHN0YXRlLlxuICAgIGlmIChvcHRpb25zLnBhcnNlID09PSB2b2lkIDApIG9wdGlvbnMucGFyc2UgPSB0cnVlO1xuICAgIHZhciBtb2RlbCA9IHRoaXM7XG4gICAgdmFyIHN1Y2Nlc3MgPSBvcHRpb25zLnN1Y2Nlc3M7XG4gICAgb3B0aW9ucy5zdWNjZXNzID0gZnVuY3Rpb24ocmVzcCkge1xuICAgICAgLy8gRW5zdXJlIGF0dHJpYnV0ZXMgYXJlIHJlc3RvcmVkIGR1cmluZyBzeW5jaHJvbm91cyBzYXZlcy5cbiAgICAgIG1vZGVsLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzO1xuICAgICAgdmFyIHNlcnZlckF0dHJzID0gbW9kZWwucGFyc2UocmVzcCwgb3B0aW9ucyk7XG4gICAgICBpZiAob3B0aW9ucy53YWl0KSBzZXJ2ZXJBdHRycyA9IF8uZXh0ZW5kKGF0dHJzIHx8IHt9LCBzZXJ2ZXJBdHRycyk7XG4gICAgICBpZiAoXy5pc09iamVjdChzZXJ2ZXJBdHRycykgJiYgIW1vZGVsLnNldChzZXJ2ZXJBdHRycywgb3B0aW9ucykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MobW9kZWwsIHJlc3AsIG9wdGlvbnMpO1xuICAgICAgbW9kZWwudHJpZ2dlcignc3luYycsIG1vZGVsLCByZXNwLCBvcHRpb25zKTtcbiAgICB9O1xuICAgIHdyYXBFcnJvcih0aGlzLCBvcHRpb25zKTtcblxuICAgIG1ldGhvZCA9IHRoaXMuaXNOZXcoKSA/ICdjcmVhdGUnIDogKG9wdGlvbnMucGF0Y2ggPyAncGF0Y2gnIDogJ3VwZGF0ZScpO1xuICAgIGlmIChtZXRob2QgPT09ICdwYXRjaCcgJiYgIW9wdGlvbnMuYXR0cnMpIG9wdGlvbnMuYXR0cnMgPSBhdHRycztcbiAgICB4aHIgPSB0aGlzLnN5bmMobWV0aG9kLCB0aGlzLCBvcHRpb25zKTtcblxuICAgIC8vIFJlc3RvcmUgYXR0cmlidXRlcy5cbiAgICBpZiAoYXR0cnMgJiYgb3B0aW9ucy53YWl0KSB0aGlzLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzO1xuXG4gICAgcmV0dXJuIHhocjtcbiAgfSxcblxuICAgIC8vIERlc3Ryb3kgdGhpcyBtb2RlbCBvbiB0aGUgc2VydmVyIGlmIGl0IHdhcyBhbHJlYWR5IHBlcnNpc3RlZC5cbiAgICAvLyBPcHRpbWlzdGljYWxseSByZW1vdmVzIHRoZSBtb2RlbCBmcm9tIGl0cyBjb2xsZWN0aW9uLCBpZiBpdCBoYXMgb25lLlxuICAgIC8vIElmIGB3YWl0OiB0cnVlYCBpcyBwYXNzZWQsIHdhaXRzIGZvciB0aGUgc2VydmVyIHRvIHJlc3BvbmQgYmVmb3JlIHJlbW92YWwuXG4gIGRlc3Ryb3k6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyA/IF8uY2xvbmUob3B0aW9ucykgOiB7fTtcbiAgICB2YXIgbW9kZWwgPSB0aGlzO1xuICAgIHZhciBzdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzO1xuXG4gICAgdmFyIGRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgICAgIG1vZGVsLnN0b3BMaXN0ZW5pbmcoKTtcbiAgICAgIG1vZGVsLnRyaWdnZXIoJ2Rlc3Ryb3knLCBtb2RlbCwgbW9kZWwuY29sbGVjdGlvbiwgb3B0aW9ucyk7XG4gICAgfTtcblxuICAgIG9wdGlvbnMuc3VjY2VzcyA9IGZ1bmN0aW9uKHJlc3ApIHtcbiAgICAgIGlmIChvcHRpb25zLndhaXQgfHwgbW9kZWwuaXNOZXcoKSkgZGVzdHJveSgpO1xuICAgICAgaWYgKHN1Y2Nlc3MpIHN1Y2Nlc3MobW9kZWwsIHJlc3AsIG9wdGlvbnMpO1xuICAgICAgaWYgKCFtb2RlbC5pc05ldygpKSBtb2RlbC50cmlnZ2VyKCdzeW5jJywgbW9kZWwsIHJlc3AsIG9wdGlvbnMpO1xuICAgIH07XG5cbiAgICBpZiAodGhpcy5pc05ldygpKSB7XG4gICAgICBvcHRpb25zLnN1Y2Nlc3MoKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgd3JhcEVycm9yKHRoaXMsIG9wdGlvbnMpO1xuXG4gICAgdmFyIHhociA9IHRoaXMuc3luYygnZGVsZXRlJywgdGhpcywgb3B0aW9ucyk7XG4gICAgaWYgKCFvcHRpb25zLndhaXQpIGRlc3Ryb3koKTtcbiAgICByZXR1cm4geGhyO1xuICB9LFxuXG4gICAgLy8gRGVmYXVsdCBVUkwgZm9yIHRoZSBtb2RlbCdzIHJlcHJlc2VudGF0aW9uIG9uIHRoZSBzZXJ2ZXIgLS0gaWYgeW91J3JlXG4gICAgLy8gdXNpbmcgQmFja2JvbmUncyByZXN0ZnVsIG1ldGhvZHMsIG92ZXJyaWRlIHRoaXMgdG8gY2hhbmdlIHRoZSBlbmRwb2ludFxuICAgIC8vIHRoYXQgd2lsbCBiZSBjYWxsZWQuXG4gIHVybDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJhc2UgPVxuICAgICAgXy5yZXN1bHQodGhpcywgJ3VybFJvb3QnKSB8fFxuICAgICAgXy5yZXN1bHQodGhpcy5jb2xsZWN0aW9uLCAndXJsJykgfHxcbiAgICAgIHVybEVycm9yKCk7XG4gICAgaWYgKHRoaXMuaXNOZXcoKSkgcmV0dXJuIGJhc2U7XG4gICAgcmV0dXJuIGJhc2UucmVwbGFjZSgvKFteXFwvXSkkLywgJyQxLycpICsgZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMuaWQpO1xuICB9LFxuXG4gICAgLy8gKipwYXJzZSoqIGNvbnZlcnRzIGEgcmVzcG9uc2UgaW50byB0aGUgaGFzaCBvZiBhdHRyaWJ1dGVzIHRvIGJlIGBzZXRgIG9uXG4gICAgLy8gdGhlIG1vZGVsLiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyBqdXN0IHRvIHBhc3MgdGhlIHJlc3BvbnNlIGFsb25nLlxuICBwYXJzZTogZnVuY3Rpb24ocmVzcCwgb3B0aW9ucykge1xuICAgIHJldHVybiByZXNwO1xuICB9LFxuXG4gICAgLy8gQ3JlYXRlIGEgbmV3IG1vZGVsIHdpdGggaWRlbnRpY2FsIGF0dHJpYnV0ZXMgdG8gdGhpcyBvbmUuXG4gIGNsb25lOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5hdHRyaWJ1dGVzKTtcbiAgfSxcblxuICAgIC8vIEEgbW9kZWwgaXMgbmV3IGlmIGl0IGhhcyBuZXZlciBiZWVuIHNhdmVkIHRvIHRoZSBzZXJ2ZXIsIGFuZCBsYWNrcyBhbiBpZC5cbiAgaXNOZXc6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiAhdGhpcy5oYXModGhpcy5pZEF0dHJpYnV0ZSk7XG4gIH0sXG5cbiAgICAvLyBDaGVjayBpZiB0aGUgbW9kZWwgaXMgY3VycmVudGx5IGluIGEgdmFsaWQgc3RhdGUuXG4gIGlzVmFsaWQ6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGUoe30sIF8uZXh0ZW5kKG9wdGlvbnMgfHwge30sIHsgdmFsaWRhdGU6IHRydWUgfSkpO1xuICB9LFxuXG4gICAgLy8gUnVuIHZhbGlkYXRpb24gYWdhaW5zdCB0aGUgbmV4dCBjb21wbGV0ZSBzZXQgb2YgbW9kZWwgYXR0cmlidXRlcyxcbiAgICAvLyByZXR1cm5pbmcgYHRydWVgIGlmIGFsbCBpcyB3ZWxsLiBPdGhlcndpc2UsIGZpcmUgYW4gYFwiaW52YWxpZFwiYCBldmVudC5cbiAgX3ZhbGlkYXRlOiBmdW5jdGlvbihhdHRycywgb3B0aW9ucykge1xuICAgIGlmICghb3B0aW9ucy52YWxpZGF0ZSB8fCAhdGhpcy52YWxpZGF0ZSkgcmV0dXJuIHRydWU7XG4gICAgYXR0cnMgPSBfLmV4dGVuZCh7fSwgdGhpcy5hdHRyaWJ1dGVzLCBhdHRycyk7XG4gICAgdmFyIGVycm9yID0gdGhpcy52YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlKGF0dHJzLCBvcHRpb25zKSB8fCBudWxsO1xuICAgIGlmICghZXJyb3IpIHJldHVybiB0cnVlO1xuICAgIHRoaXMudHJpZ2dlcignaW52YWxpZCcsIHRoaXMsIGVycm9yLCBfLmV4dGVuZChvcHRpb25zLCB7dmFsaWRhdGlvbkVycm9yOiBlcnJvcn0pKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxufSk7XG5cbi8vIFVuZGVyc2NvcmUgbWV0aG9kcyB0aGF0IHdlIHdhbnQgdG8gaW1wbGVtZW50IG9uIHRoZSBNb2RlbC5cbnZhciBtb2RlbE1ldGhvZHMgPSBbJ2tleXMnLCAndmFsdWVzJywgJ3BhaXJzJywgJ2ludmVydCcsICdwaWNrJywgJ29taXQnLCAnY2hhaW4nLCAnaXNFbXB0eSddO1xuXG4vLyBNaXggaW4gZWFjaCBVbmRlcnNjb3JlIG1ldGhvZCBhcyBhIHByb3h5IHRvIGBNb2RlbCNhdHRyaWJ1dGVzYC5cbl8uZWFjaChtb2RlbE1ldGhvZHMsIGZ1bmN0aW9uKG1ldGhvZCkge1xuICBpZiAoIV9bbWV0aG9kXSkgcmV0dXJuO1xuICBNb2RlbC5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzLmF0dHJpYnV0ZXMpO1xuICAgIHJldHVybiBfW21ldGhvZF0uYXBwbHkoXywgYXJncyk7XG4gIH07XG59KTtcblxuLy8gc2V0dXAgaW5oZXJpdGFuY2Vcbk1vZGVsLmV4dGVuZCA9IGV4dGVuZDtcbm1vZHVsZS5leHBvcnRzID0gTW9kZWw7XG4iLCIvKipcbiAqIFN0YW5kYWxvbmUgZXh0cmFjdGlvbiBvZiBCYWNrYm9uZS5FdmVudHMsIG5vIGV4dGVybmFsIGRlcGVuZGVuY3kgcmVxdWlyZWQuXG4gKiBEZWdyYWRlcyBuaWNlbHkgd2hlbiBCYWNrb25lL3VuZGVyc2NvcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50XG4gKiBnbG9iYWwgY29udGV4dC5cbiAqXG4gKiBOb3RlIHRoYXQgZG9jcyBzdWdnZXN0IHRvIHVzZSB1bmRlcnNjb3JlJ3MgYF8uZXh0ZW5kKClgIG1ldGhvZCB0byBhZGQgRXZlbnRzXG4gKiBzdXBwb3J0IHRvIHNvbWUgZ2l2ZW4gb2JqZWN0LiBBIGBtaXhpbigpYCBtZXRob2QgaGFzIGJlZW4gYWRkZWQgdG8gdGhlIEV2ZW50c1xuICogcHJvdG90eXBlIHRvIGF2b2lkIHVzaW5nIHVuZGVyc2NvcmUgZm9yIHRoYXQgc29sZSBwdXJwb3NlOlxuICpcbiAqICAgICB2YXIgbXlFdmVudEVtaXR0ZXIgPSBCYWNrYm9uZUV2ZW50cy5taXhpbih7fSk7XG4gKlxuICogT3IgZm9yIGEgZnVuY3Rpb24gY29uc3RydWN0b3I6XG4gKlxuICogICAgIGZ1bmN0aW9uIE15Q29uc3RydWN0b3IoKXt9XG4gKiAgICAgTXlDb25zdHJ1Y3Rvci5wcm90b3R5cGUuZm9vID0gZnVuY3Rpb24oKXt9XG4gKiAgICAgQmFja2JvbmVFdmVudHMubWl4aW4oTXlDb25zdHJ1Y3Rvci5wcm90b3R5cGUpO1xuICpcbiAqIChjKSAyMDA5LTIwMTMgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIEluYy5cbiAqIChjKSAyMDEzIE5pY29sYXMgUGVycmlhdWx0XG4gKi9cbi8qIGdsb2JhbCBleHBvcnRzOnRydWUsIGRlZmluZSwgbW9kdWxlICovXG4oZnVuY3Rpb24oKSB7XG4gIHZhciByb290ID0gdGhpcyxcbiAgICAgIGJyZWFrZXIgPSB7fSxcbiAgICAgIG5hdGl2ZUZvckVhY2ggPSBBcnJheS5wcm90b3R5cGUuZm9yRWFjaCxcbiAgICAgIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxcbiAgICAgIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLFxuICAgICAgaWRDb3VudGVyID0gMDtcblxuICAvLyBSZXR1cm5zIGEgcGFydGlhbCBpbXBsZW1lbnRhdGlvbiBtYXRjaGluZyB0aGUgbWluaW1hbCBBUEkgc3Vic2V0IHJlcXVpcmVkXG4gIC8vIGJ5IEJhY2tib25lLkV2ZW50c1xuICBmdW5jdGlvbiBtaW5pc2NvcmUoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleXM6IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmogIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iaiAhPT0gXCJmdW5jdGlvblwiIHx8IG9iaiA9PT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXlzKCkgY2FsbGVkIG9uIGEgbm9uLW9iamVjdFwiKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIga2V5LCBrZXlzID0gW107XG4gICAgICAgIGZvciAoa2V5IGluIG9iaikge1xuICAgICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAga2V5c1trZXlzLmxlbmd0aF0gPSBrZXk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrZXlzO1xuICAgICAgfSxcblxuICAgICAgdW5pcXVlSWQ6IGZ1bmN0aW9uKHByZWZpeCkge1xuICAgICAgICB2YXIgaWQgPSArK2lkQ291bnRlciArICcnO1xuICAgICAgICByZXR1cm4gcHJlZml4ID8gcHJlZml4ICsgaWQgOiBpZDtcbiAgICAgIH0sXG5cbiAgICAgIGhhczogZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICAgICAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpO1xuICAgICAgfSxcblxuICAgICAgZWFjaDogZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgICAgICBpZiAob2JqID09IG51bGwpIHJldHVybjtcbiAgICAgICAgaWYgKG5hdGl2ZUZvckVhY2ggJiYgb2JqLmZvckVhY2ggPT09IG5hdGl2ZUZvckVhY2gpIHtcbiAgICAgICAgICBvYmouZm9yRWFjaChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgICAgIH0gZWxzZSBpZiAob2JqLmxlbmd0aCA9PT0gK29iai5sZW5ndGgpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtpXSwgaSwgb2JqKSA9PT0gYnJlYWtlcikgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5oYXMob2JqLCBrZXkpKSB7XG4gICAgICAgICAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXldLCBrZXksIG9iaikgPT09IGJyZWFrZXIpIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIG9uY2U6IGZ1bmN0aW9uKGZ1bmMpIHtcbiAgICAgICAgdmFyIHJhbiA9IGZhbHNlLCBtZW1vO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKHJhbikgcmV0dXJuIG1lbW87XG4gICAgICAgICAgcmFuID0gdHJ1ZTtcbiAgICAgICAgICBtZW1vID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgIGZ1bmMgPSBudWxsO1xuICAgICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICB2YXIgXyA9IG1pbmlzY29yZSgpLCBFdmVudHM7XG5cbiAgLy8gQmFja2JvbmUuRXZlbnRzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLVxuXG4gIC8vIEEgbW9kdWxlIHRoYXQgY2FuIGJlIG1peGVkIGluIHRvICphbnkgb2JqZWN0KiBpbiBvcmRlciB0byBwcm92aWRlIGl0IHdpdGhcbiAgLy8gY3VzdG9tIGV2ZW50cy4gWW91IG1heSBiaW5kIHdpdGggYG9uYCBvciByZW1vdmUgd2l0aCBgb2ZmYCBjYWxsYmFja1xuICAvLyBmdW5jdGlvbnMgdG8gYW4gZXZlbnQ7IGB0cmlnZ2VyYC1pbmcgYW4gZXZlbnQgZmlyZXMgYWxsIGNhbGxiYWNrcyBpblxuICAvLyBzdWNjZXNzaW9uLlxuICAvL1xuICAvLyAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAvLyAgICAgXy5leHRlbmQob2JqZWN0LCBCYWNrYm9uZS5FdmVudHMpO1xuICAvLyAgICAgb2JqZWN0Lm9uKCdleHBhbmQnLCBmdW5jdGlvbigpeyBhbGVydCgnZXhwYW5kZWQnKTsgfSk7XG4gIC8vICAgICBvYmplY3QudHJpZ2dlcignZXhwYW5kJyk7XG4gIC8vXG4gIEV2ZW50cyA9IHtcblxuICAgIC8vIEJpbmQgYW4gZXZlbnQgdG8gYSBgY2FsbGJhY2tgIGZ1bmN0aW9uLiBQYXNzaW5nIGBcImFsbFwiYCB3aWxsIGJpbmRcbiAgICAvLyB0aGUgY2FsbGJhY2sgdG8gYWxsIGV2ZW50cyBmaXJlZC5cbiAgICBvbjogZnVuY3Rpb24obmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICAgIGlmICghZXZlbnRzQXBpKHRoaXMsICdvbicsIG5hbWUsIFtjYWxsYmFjaywgY29udGV4dF0pIHx8ICFjYWxsYmFjaykgcmV0dXJuIHRoaXM7XG4gICAgICB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICAgIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHNbbmFtZV0gfHwgKHRoaXMuX2V2ZW50c1tuYW1lXSA9IFtdKTtcbiAgICAgIGV2ZW50cy5wdXNoKHtjYWxsYmFjazogY2FsbGJhY2ssIGNvbnRleHQ6IGNvbnRleHQsIGN0eDogY29udGV4dCB8fCB0aGlzfSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLy8gQmluZCBhbiBldmVudCB0byBvbmx5IGJlIHRyaWdnZXJlZCBhIHNpbmdsZSB0aW1lLiBBZnRlciB0aGUgZmlyc3QgdGltZVxuICAgIC8vIHRoZSBjYWxsYmFjayBpcyBpbnZva2VkLCBpdCB3aWxsIGJlIHJlbW92ZWQuXG4gICAgb25jZTogZnVuY3Rpb24obmFtZSwgY2FsbGJhY2ssIGNvbnRleHQpIHtcbiAgICAgIGlmICghZXZlbnRzQXBpKHRoaXMsICdvbmNlJywgbmFtZSwgW2NhbGxiYWNrLCBjb250ZXh0XSkgfHwgIWNhbGxiYWNrKSByZXR1cm4gdGhpcztcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIHZhciBvbmNlID0gXy5vbmNlKGZ1bmN0aW9uKCkge1xuICAgICAgICBzZWxmLm9mZihuYW1lLCBvbmNlKTtcbiAgICAgICAgY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH0pO1xuICAgICAgb25jZS5fY2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICAgIHJldHVybiB0aGlzLm9uKG5hbWUsIG9uY2UsIGNvbnRleHQpO1xuICAgIH0sXG5cbiAgICAvLyBSZW1vdmUgb25lIG9yIG1hbnkgY2FsbGJhY2tzLiBJZiBgY29udGV4dGAgaXMgbnVsbCwgcmVtb3ZlcyBhbGxcbiAgICAvLyBjYWxsYmFja3Mgd2l0aCB0aGF0IGZ1bmN0aW9uLiBJZiBgY2FsbGJhY2tgIGlzIG51bGwsIHJlbW92ZXMgYWxsXG4gICAgLy8gY2FsbGJhY2tzIGZvciB0aGUgZXZlbnQuIElmIGBuYW1lYCBpcyBudWxsLCByZW1vdmVzIGFsbCBib3VuZFxuICAgIC8vIGNhbGxiYWNrcyBmb3IgYWxsIGV2ZW50cy5cbiAgICBvZmY6IGZ1bmN0aW9uKG5hbWUsIGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gICAgICB2YXIgcmV0YWluLCBldiwgZXZlbnRzLCBuYW1lcywgaSwgbCwgaiwgaztcbiAgICAgIGlmICghdGhpcy5fZXZlbnRzIHx8ICFldmVudHNBcGkodGhpcywgJ29mZicsIG5hbWUsIFtjYWxsYmFjaywgY29udGV4dF0pKSByZXR1cm4gdGhpcztcbiAgICAgIGlmICghbmFtZSAmJiAhY2FsbGJhY2sgJiYgIWNvbnRleHQpIHtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICBuYW1lcyA9IG5hbWUgPyBbbmFtZV0gOiBfLmtleXModGhpcy5fZXZlbnRzKTtcbiAgICAgIGZvciAoaSA9IDAsIGwgPSBuYW1lcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgbmFtZSA9IG5hbWVzW2ldO1xuICAgICAgICBpZiAoZXZlbnRzID0gdGhpcy5fZXZlbnRzW25hbWVdKSB7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzW25hbWVdID0gcmV0YWluID0gW107XG4gICAgICAgICAgaWYgKGNhbGxiYWNrIHx8IGNvbnRleHQpIHtcbiAgICAgICAgICAgIGZvciAoaiA9IDAsIGsgPSBldmVudHMubGVuZ3RoOyBqIDwgazsgaisrKSB7XG4gICAgICAgICAgICAgIGV2ID0gZXZlbnRzW2pdO1xuICAgICAgICAgICAgICBpZiAoKGNhbGxiYWNrICYmIGNhbGxiYWNrICE9PSBldi5jYWxsYmFjayAmJiBjYWxsYmFjayAhPT0gZXYuY2FsbGJhY2suX2NhbGxiYWNrKSB8fFxuICAgICAgICAgICAgICAgICAgKGNvbnRleHQgJiYgY29udGV4dCAhPT0gZXYuY29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICByZXRhaW4ucHVzaChldik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFyZXRhaW4ubGVuZ3RoKSBkZWxldGUgdGhpcy5fZXZlbnRzW25hbWVdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvLyBUcmlnZ2VyIG9uZSBvciBtYW55IGV2ZW50cywgZmlyaW5nIGFsbCBib3VuZCBjYWxsYmFja3MuIENhbGxiYWNrcyBhcmVcbiAgICAvLyBwYXNzZWQgdGhlIHNhbWUgYXJndW1lbnRzIGFzIGB0cmlnZ2VyYCBpcywgYXBhcnQgZnJvbSB0aGUgZXZlbnQgbmFtZVxuICAgIC8vICh1bmxlc3MgeW91J3JlIGxpc3RlbmluZyBvbiBgXCJhbGxcImAsIHdoaWNoIHdpbGwgY2F1c2UgeW91ciBjYWxsYmFjayB0b1xuICAgIC8vIHJlY2VpdmUgdGhlIHRydWUgbmFtZSBvZiB0aGUgZXZlbnQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50KS5cbiAgICB0cmlnZ2VyOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgICBpZiAoIXRoaXMuX2V2ZW50cykgcmV0dXJuIHRoaXM7XG4gICAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgIGlmICghZXZlbnRzQXBpKHRoaXMsICd0cmlnZ2VyJywgbmFtZSwgYXJncykpIHJldHVybiB0aGlzO1xuICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50c1tuYW1lXTtcbiAgICAgIHZhciBhbGxFdmVudHMgPSB0aGlzLl9ldmVudHMuYWxsO1xuICAgICAgaWYgKGV2ZW50cykgdHJpZ2dlckV2ZW50cyhldmVudHMsIGFyZ3MpO1xuICAgICAgaWYgKGFsbEV2ZW50cykgdHJpZ2dlckV2ZW50cyhhbGxFdmVudHMsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLy8gVGVsbCB0aGlzIG9iamVjdCB0byBzdG9wIGxpc3RlbmluZyB0byBlaXRoZXIgc3BlY2lmaWMgZXZlbnRzIC4uLiBvclxuICAgIC8vIHRvIGV2ZXJ5IG9iamVjdCBpdCdzIGN1cnJlbnRseSBsaXN0ZW5pbmcgdG8uXG4gICAgc3RvcExpc3RlbmluZzogZnVuY3Rpb24ob2JqLCBuYW1lLCBjYWxsYmFjaykge1xuICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycztcbiAgICAgIGlmICghbGlzdGVuZXJzKSByZXR1cm4gdGhpcztcbiAgICAgIHZhciBkZWxldGVMaXN0ZW5lciA9ICFuYW1lICYmICFjYWxsYmFjaztcbiAgICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ29iamVjdCcpIGNhbGxiYWNrID0gdGhpcztcbiAgICAgIGlmIChvYmopIChsaXN0ZW5lcnMgPSB7fSlbb2JqLl9saXN0ZW5lcklkXSA9IG9iajtcbiAgICAgIGZvciAodmFyIGlkIGluIGxpc3RlbmVycykge1xuICAgICAgICBsaXN0ZW5lcnNbaWRdLm9mZihuYW1lLCBjYWxsYmFjaywgdGhpcyk7XG4gICAgICAgIGlmIChkZWxldGVMaXN0ZW5lcikgZGVsZXRlIHRoaXMuX2xpc3RlbmVyc1tpZF07XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgfTtcblxuICAvLyBSZWd1bGFyIGV4cHJlc3Npb24gdXNlZCB0byBzcGxpdCBldmVudCBzdHJpbmdzLlxuICB2YXIgZXZlbnRTcGxpdHRlciA9IC9cXHMrLztcblxuICAvLyBJbXBsZW1lbnQgZmFuY3kgZmVhdHVyZXMgb2YgdGhlIEV2ZW50cyBBUEkgc3VjaCBhcyBtdWx0aXBsZSBldmVudFxuICAvLyBuYW1lcyBgXCJjaGFuZ2UgYmx1clwiYCBhbmQgalF1ZXJ5LXN0eWxlIGV2ZW50IG1hcHMgYHtjaGFuZ2U6IGFjdGlvbn1gXG4gIC8vIGluIHRlcm1zIG9mIHRoZSBleGlzdGluZyBBUEkuXG4gIHZhciBldmVudHNBcGkgPSBmdW5jdGlvbihvYmosIGFjdGlvbiwgbmFtZSwgcmVzdCkge1xuICAgIGlmICghbmFtZSkgcmV0dXJuIHRydWU7XG5cbiAgICAvLyBIYW5kbGUgZXZlbnQgbWFwcy5cbiAgICBpZiAodHlwZW9mIG5hbWUgPT09ICdvYmplY3QnKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gbmFtZSkge1xuICAgICAgICBvYmpbYWN0aW9uXS5hcHBseShvYmosIFtrZXksIG5hbWVba2V5XV0uY29uY2F0KHJlc3QpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgc3BhY2Ugc2VwYXJhdGVkIGV2ZW50IG5hbWVzLlxuICAgIGlmIChldmVudFNwbGl0dGVyLnRlc3QobmFtZSkpIHtcbiAgICAgIHZhciBuYW1lcyA9IG5hbWUuc3BsaXQoZXZlbnRTcGxpdHRlcik7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG5hbWVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICBvYmpbYWN0aW9uXS5hcHBseShvYmosIFtuYW1lc1tpXV0uY29uY2F0KHJlc3QpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICAvLyBBIGRpZmZpY3VsdC10by1iZWxpZXZlLCBidXQgb3B0aW1pemVkIGludGVybmFsIGRpc3BhdGNoIGZ1bmN0aW9uIGZvclxuICAvLyB0cmlnZ2VyaW5nIGV2ZW50cy4gVHJpZXMgdG8ga2VlcCB0aGUgdXN1YWwgY2FzZXMgc3BlZWR5IChtb3N0IGludGVybmFsXG4gIC8vIEJhY2tib25lIGV2ZW50cyBoYXZlIDMgYXJndW1lbnRzKS5cbiAgdmFyIHRyaWdnZXJFdmVudHMgPSBmdW5jdGlvbihldmVudHMsIGFyZ3MpIHtcbiAgICB2YXIgZXYsIGkgPSAtMSwgbCA9IGV2ZW50cy5sZW5ndGgsIGExID0gYXJnc1swXSwgYTIgPSBhcmdzWzFdLCBhMyA9IGFyZ3NbMl07XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5jYWxsKGV2LmN0eCk7IHJldHVybjtcbiAgICAgIGNhc2UgMTogd2hpbGUgKCsraSA8IGwpIChldiA9IGV2ZW50c1tpXSkuY2FsbGJhY2suY2FsbChldi5jdHgsIGExKTsgcmV0dXJuO1xuICAgICAgY2FzZSAyOiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5jYWxsKGV2LmN0eCwgYTEsIGEyKTsgcmV0dXJuO1xuICAgICAgY2FzZSAzOiB3aGlsZSAoKytpIDwgbCkgKGV2ID0gZXZlbnRzW2ldKS5jYWxsYmFjay5jYWxsKGV2LmN0eCwgYTEsIGEyLCBhMyk7IHJldHVybjtcbiAgICAgIGRlZmF1bHQ6IHdoaWxlICgrK2kgPCBsKSAoZXYgPSBldmVudHNbaV0pLmNhbGxiYWNrLmFwcGx5KGV2LmN0eCwgYXJncyk7XG4gICAgfVxuICB9O1xuXG4gIHZhciBsaXN0ZW5NZXRob2RzID0ge2xpc3RlblRvOiAnb24nLCBsaXN0ZW5Ub09uY2U6ICdvbmNlJ307XG5cbiAgLy8gSW52ZXJzaW9uLW9mLWNvbnRyb2wgdmVyc2lvbnMgb2YgYG9uYCBhbmQgYG9uY2VgLiBUZWxsICp0aGlzKiBvYmplY3QgdG9cbiAgLy8gbGlzdGVuIHRvIGFuIGV2ZW50IGluIGFub3RoZXIgb2JqZWN0IC4uLiBrZWVwaW5nIHRyYWNrIG9mIHdoYXQgaXQnc1xuICAvLyBsaXN0ZW5pbmcgdG8uXG4gIF8uZWFjaChsaXN0ZW5NZXRob2RzLCBmdW5jdGlvbihpbXBsZW1lbnRhdGlvbiwgbWV0aG9kKSB7XG4gICAgRXZlbnRzW21ldGhvZF0gPSBmdW5jdGlvbihvYmosIG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzIHx8ICh0aGlzLl9saXN0ZW5lcnMgPSB7fSk7XG4gICAgICB2YXIgaWQgPSBvYmouX2xpc3RlbmVySWQgfHwgKG9iai5fbGlzdGVuZXJJZCA9IF8udW5pcXVlSWQoJ2wnKSk7XG4gICAgICBsaXN0ZW5lcnNbaWRdID0gb2JqO1xuICAgICAgaWYgKHR5cGVvZiBuYW1lID09PSAnb2JqZWN0JykgY2FsbGJhY2sgPSB0aGlzO1xuICAgICAgb2JqW2ltcGxlbWVudGF0aW9uXShuYW1lLCBjYWxsYmFjaywgdGhpcyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICB9KTtcblxuICAvLyBBbGlhc2VzIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbiAgRXZlbnRzLmJpbmQgICA9IEV2ZW50cy5vbjtcbiAgRXZlbnRzLnVuYmluZCA9IEV2ZW50cy5vZmY7XG5cbiAgLy8gTWl4aW4gdXRpbGl0eVxuICBFdmVudHMubWl4aW4gPSBmdW5jdGlvbihwcm90bykge1xuICAgIHZhciBleHBvcnRzID0gWydvbicsICdvbmNlJywgJ29mZicsICd0cmlnZ2VyJywgJ3N0b3BMaXN0ZW5pbmcnLCAnbGlzdGVuVG8nLFxuICAgICAgICAgICAgICAgICAgICdsaXN0ZW5Ub09uY2UnLCAnYmluZCcsICd1bmJpbmQnXTtcbiAgICBfLmVhY2goZXhwb3J0cywgZnVuY3Rpb24obmFtZSkge1xuICAgICAgcHJvdG9bbmFtZV0gPSB0aGlzW25hbWVdO1xuICAgIH0sIHRoaXMpO1xuICAgIHJldHVybiBwcm90bztcbiAgfTtcblxuICAvLyBFeHBvcnQgRXZlbnRzIGFzIEJhY2tib25lRXZlbnRzIGRlcGVuZGluZyBvbiBjdXJyZW50IGNvbnRleHRcbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGRlZmluZShmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBFdmVudHM7XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBFdmVudHM7XG4gICAgfVxuICAgIGV4cG9ydHMuQmFja2JvbmVFdmVudHMgPSBFdmVudHM7XG4gIH0gZWxzZSB7XG4gICAgcm9vdC5CYWNrYm9uZUV2ZW50cyA9IEV2ZW50cztcbiAgfVxufSkodGhpcyk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmUnKTtcbiIsIihmdW5jdGlvbiAoZGVmaW5pdGlvbikge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcbiAgfVxuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICBkZWZpbmUoZGVmaW5pdGlvbik7XG4gIH1cbiAgZWxzZSB7XG4gICAgd2luZG93LkJhY2tib25lRXh0ZW5kID0gZGVmaW5pdGlvbigpO1xuICB9XG59KShmdW5jdGlvbiAoKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuICBcbiAgLy8gbWluaS11bmRlcnNjb3JlXG4gIHZhciBfID0ge1xuICAgIGhhczogZnVuY3Rpb24gKG9iaiwga2V5KSB7XG4gICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTtcbiAgICB9LFxuICBcbiAgICBleHRlbmQ6IGZ1bmN0aW9uKG9iaikge1xuICAgICAgZm9yICh2YXIgaT0xOyBpPGFyZ3VtZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuICAgICAgICBpZiAoc291cmNlKSB7XG4gICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIG9ialtwcm9wXSA9IHNvdXJjZVtwcm9wXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICB9O1xuXG4gIC8vLyBGb2xsb3dpbmcgY29kZSBpcyBwYXN0ZWQgZnJvbSBCYWNrYm9uZS5qcyAvLy9cblxuICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gY29ycmVjdGx5IHNldCB1cCB0aGUgcHJvdG90eXBlIGNoYWluLCBmb3Igc3ViY2xhc3Nlcy5cbiAgLy8gU2ltaWxhciB0byBgZ29vZy5pbmhlcml0c2AsIGJ1dCB1c2VzIGEgaGFzaCBvZiBwcm90b3R5cGUgcHJvcGVydGllcyBhbmRcbiAgLy8gY2xhc3MgcHJvcGVydGllcyB0byBiZSBleHRlbmRlZC5cbiAgdmFyIGV4dGVuZCA9IGZ1bmN0aW9uKHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gICAgdmFyIHBhcmVudCA9IHRoaXM7XG4gICAgdmFyIGNoaWxkO1xuXG4gICAgLy8gVGhlIGNvbnN0cnVjdG9yIGZ1bmN0aW9uIGZvciB0aGUgbmV3IHN1YmNsYXNzIGlzIGVpdGhlciBkZWZpbmVkIGJ5IHlvdVxuICAgIC8vICh0aGUgXCJjb25zdHJ1Y3RvclwiIHByb3BlcnR5IGluIHlvdXIgYGV4dGVuZGAgZGVmaW5pdGlvbiksIG9yIGRlZmF1bHRlZFxuICAgIC8vIGJ5IHVzIHRvIHNpbXBseSBjYWxsIHRoZSBwYXJlbnQncyBjb25zdHJ1Y3Rvci5cbiAgICBpZiAocHJvdG9Qcm9wcyAmJiBfLmhhcyhwcm90b1Byb3BzLCAnY29uc3RydWN0b3InKSkge1xuICAgICAgY2hpbGQgPSBwcm90b1Byb3BzLmNvbnN0cnVjdG9yO1xuICAgIH0gZWxzZSB7XG4gICAgICBjaGlsZCA9IGZ1bmN0aW9uKCl7IHJldHVybiBwYXJlbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfTtcbiAgICB9XG5cbiAgICAvLyBBZGQgc3RhdGljIHByb3BlcnRpZXMgdG8gdGhlIGNvbnN0cnVjdG9yIGZ1bmN0aW9uLCBpZiBzdXBwbGllZC5cbiAgICBfLmV4dGVuZChjaGlsZCwgcGFyZW50LCBzdGF0aWNQcm9wcyk7XG5cbiAgICAvLyBTZXQgdGhlIHByb3RvdHlwZSBjaGFpbiB0byBpbmhlcml0IGZyb20gYHBhcmVudGAsIHdpdGhvdXQgY2FsbGluZ1xuICAgIC8vIGBwYXJlbnRgJ3MgY29uc3RydWN0b3IgZnVuY3Rpb24uXG4gICAgdmFyIFN1cnJvZ2F0ZSA9IGZ1bmN0aW9uKCl7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfTtcbiAgICBTdXJyb2dhdGUucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTtcbiAgICBjaGlsZC5wcm90b3R5cGUgPSBuZXcgU3Vycm9nYXRlKCk7XG5cbiAgICAvLyBBZGQgcHJvdG90eXBlIHByb3BlcnRpZXMgKGluc3RhbmNlIHByb3BlcnRpZXMpIHRvIHRoZSBzdWJjbGFzcyxcbiAgICAvLyBpZiBzdXBwbGllZC5cbiAgICBpZiAocHJvdG9Qcm9wcykgXy5leHRlbmQoY2hpbGQucHJvdG90eXBlLCBwcm90b1Byb3BzKTtcblxuICAgIC8vIFNldCBhIGNvbnZlbmllbmNlIHByb3BlcnR5IGluIGNhc2UgdGhlIHBhcmVudCdzIHByb3RvdHlwZSBpcyBuZWVkZWRcbiAgICAvLyBsYXRlci5cbiAgICBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlO1xuXG4gICAgcmV0dXJuIGNoaWxkO1xuICB9O1xuXG4gIC8vIEV4cG9zZSB0aGUgZXh0ZW5kIGZ1bmN0aW9uXG4gIHJldHVybiBleHRlbmQ7XG59KTtcbiIsIi8vIHRoaXMgaXMgdGhlIGV4dHJhY3RlZCB2aWV3IG1vZGVsIGZyb20gYmFja2JvbmVcbi8vIG5vdGUgdGhhdCB3ZSBpbmplY3QgamJvbmUgYXMganF1ZXJ5IHJlcGxhY21lbnRcbi8vIChhbmQgdW5kZXJzY29yZSBkaXJlY3RseSlcbi8vXG4vLyBWaWV3cyBhcmUgYWxtb3N0IG1vcmUgY29udmVudGlvbiB0aGFuIHRoZXkgYXJlIGFjdHVhbCBjb2RlLlxuLy8gIE1WQyBwYXR0ZXJuXG4vLyBCYWNrYm9uZS5WaWV3XG4vLyAtLS0tLS0tLS0tLS0tXG5cbnZhciBfID0gcmVxdWlyZShcInVuZGVyc2NvcmVcIik7XG52YXIgRXZlbnRzID0gcmVxdWlyZShcImJhY2tib25lLWV2ZW50cy1zdGFuZGFsb25lXCIpO1xudmFyIGV4dGVuZCA9IHJlcXVpcmUoXCJiYWNrYm9uZS1leHRlbmQtc3RhbmRhbG9uZVwiKTtcbnZhciAkID0gcmVxdWlyZSgnamJvbmUnKTtcblxuLy8gQmFja2JvbmUgVmlld3MgYXJlIGFsbW9zdCBtb3JlIGNvbnZlbnRpb24gdGhhbiB0aGV5IGFyZSBhY3R1YWwgY29kZS4gQSBWaWV3XG4vLyBpcyBzaW1wbHkgYSBKYXZhU2NyaXB0IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYSBsb2dpY2FsIGNodW5rIG9mIFVJIGluIHRoZVxuLy8gRE9NLiBUaGlzIG1pZ2h0IGJlIGEgc2luZ2xlIGl0ZW0sIGFuIGVudGlyZSBsaXN0LCBhIHNpZGViYXIgb3IgcGFuZWwsIG9yXG4vLyBldmVuIHRoZSBzdXJyb3VuZGluZyBmcmFtZSB3aGljaCB3cmFwcyB5b3VyIHdob2xlIGFwcC4gRGVmaW5pbmcgYSBjaHVuayBvZlxuLy8gVUkgYXMgYSAqKlZpZXcqKiBhbGxvd3MgeW91IHRvIGRlZmluZSB5b3VyIERPTSBldmVudHMgZGVjbGFyYXRpdmVseSwgd2l0aG91dFxuLy8gaGF2aW5nIHRvIHdvcnJ5IGFib3V0IHJlbmRlciBvcmRlciAuLi4gYW5kIG1ha2VzIGl0IGVhc3kgZm9yIHRoZSB2aWV3IHRvXG4vLyByZWFjdCB0byBzcGVjaWZpYyBjaGFuZ2VzIGluIHRoZSBzdGF0ZSBvZiB5b3VyIG1vZGVscy5cblxuLy8gQ3JlYXRpbmcgYSBCYWNrYm9uZS5WaWV3IGNyZWF0ZXMgaXRzIGluaXRpYWwgZWxlbWVudCBvdXRzaWRlIG9mIHRoZSBET00sXG4vLyBpZiBhbiBleGlzdGluZyBlbGVtZW50IGlzIG5vdCBwcm92aWRlZC4uLlxudmFyIFZpZXcgPSAgZnVuY3Rpb24ob3B0aW9ucykge1xuICB0aGlzLmNpZCA9IF8udW5pcXVlSWQoJ3ZpZXcnKTtcbiAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcbiAgXy5leHRlbmQodGhpcywgXy5waWNrKG9wdGlvbnMsIHZpZXdPcHRpb25zKSk7XG4gIHRoaXMuX2Vuc3VyZUVsZW1lbnQoKTtcbiAgdGhpcy5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59O1xuXG4vLyBDYWNoZWQgcmVnZXggdG8gc3BsaXQga2V5cyBmb3IgYGRlbGVnYXRlYC5cbnZhciBkZWxlZ2F0ZUV2ZW50U3BsaXR0ZXIgPSAvXihcXFMrKVxccyooLiopJC87XG5cbi8vIExpc3Qgb2YgdmlldyBvcHRpb25zIHRvIGJlIG1lcmdlZCBhcyBwcm9wZXJ0aWVzLlxudmFyIHZpZXdPcHRpb25zID0gWydtb2RlbCcsICdjb2xsZWN0aW9uJywgJ2VsJywgJ2lkJywgJ2F0dHJpYnV0ZXMnLCAnY2xhc3NOYW1lJywgJ3RhZ05hbWUnLCAnZXZlbnRzJ107XG5cbi8vIFNldCB1cCBhbGwgaW5oZXJpdGFibGUgKipCYWNrYm9uZS5WaWV3KiogcHJvcGVydGllcyBhbmQgbWV0aG9kcy5cbl8uZXh0ZW5kKFZpZXcucHJvdG90eXBlLCBFdmVudHMsIHtcblxuICAvLyBUaGUgZGVmYXVsdCBgdGFnTmFtZWAgb2YgYSBWaWV3J3MgZWxlbWVudCBpcyBgXCJkaXZcImAuXG4gIHRhZ05hbWU6ICdkaXYnLFxuXG4gIC8vIGpRdWVyeSBkZWxlZ2F0ZSBmb3IgZWxlbWVudCBsb29rdXAsIHNjb3BlZCB0byBET00gZWxlbWVudHMgd2l0aGluIHRoZVxuICAvLyBjdXJyZW50IHZpZXcuIFRoaXMgc2hvdWxkIGJlIHByZWZlcnJlZCB0byBnbG9iYWwgbG9va3VwcyB3aGVyZSBwb3NzaWJsZS5cbiAgJDogZnVuY3Rpb24oc2VsZWN0b3IpIHtcbiAgICByZXR1cm4gdGhpcy4kZWwuZmluZChzZWxlY3Rvcik7XG4gIH0sXG5cbiAgICAvLyBJbml0aWFsaXplIGlzIGFuIGVtcHR5IGZ1bmN0aW9uIGJ5IGRlZmF1bHQuIE92ZXJyaWRlIGl0IHdpdGggeW91ciBvd25cbiAgICAvLyBpbml0aWFsaXphdGlvbiBsb2dpYy5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXt9LFxuXG4gICAgLy8gKipyZW5kZXIqKiBpcyB0aGUgY29yZSBmdW5jdGlvbiB0aGF0IHlvdXIgdmlldyBzaG91bGQgb3ZlcnJpZGUsIGluIG9yZGVyXG4gICAgLy8gdG8gcG9wdWxhdGUgaXRzIGVsZW1lbnQgKGB0aGlzLmVsYCksIHdpdGggdGhlIGFwcHJvcHJpYXRlIEhUTUwuIFRoZVxuICAgIC8vIGNvbnZlbnRpb24gaXMgZm9yICoqcmVuZGVyKiogdG8gYWx3YXlzIHJldHVybiBgdGhpc2AuXG4gIHJlbmRlcjogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgICAvLyBSZW1vdmUgdGhpcyB2aWV3IGJ5IHRha2luZyB0aGUgZWxlbWVudCBvdXQgb2YgdGhlIERPTSwgYW5kIHJlbW92aW5nIGFueVxuICAgIC8vIGFwcGxpY2FibGUgQmFja2JvbmUuRXZlbnRzIGxpc3RlbmVycy5cbiAgcmVtb3ZlOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9yZW1vdmVFbGVtZW50KCk7XG4gICAgdGhpcy5zdG9wTGlzdGVuaW5nKCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgICAvLyBSZW1vdmUgdGhpcyB2aWV3J3MgZWxlbWVudCBmcm9tIHRoZSBkb2N1bWVudCBhbmQgYWxsIGV2ZW50IGxpc3RlbmVyc1xuICAgIC8vIGF0dGFjaGVkIHRvIGl0LiBFeHBvc2VkIGZvciBzdWJjbGFzc2VzIHVzaW5nIGFuIGFsdGVybmF0aXZlIERPTVxuICAgIC8vIG1hbmlwdWxhdGlvbiBBUEkuXG4gIF9yZW1vdmVFbGVtZW50OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLiRlbC5yZW1vdmUoKTtcbiAgfSxcblxuICAgIC8vIENoYW5nZSB0aGUgdmlldydzIGVsZW1lbnQgKGB0aGlzLmVsYCBwcm9wZXJ0eSkgYW5kIHJlLWRlbGVnYXRlIHRoZVxuICAgIC8vIHZpZXcncyBldmVudHMgb24gdGhlIG5ldyBlbGVtZW50LlxuICBzZXRFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgdGhpcy51bmRlbGVnYXRlRXZlbnRzKCk7XG4gICAgdGhpcy5fc2V0RWxlbWVudChlbGVtZW50KTtcbiAgICB0aGlzLmRlbGVnYXRlRXZlbnRzKCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgICAvLyBDcmVhdGVzIHRoZSBgdGhpcy5lbGAgYW5kIGB0aGlzLiRlbGAgcmVmZXJlbmNlcyBmb3IgdGhpcyB2aWV3IHVzaW5nIHRoZVxuICAgIC8vIGdpdmVuIGBlbGAuIGBlbGAgY2FuIGJlIGEgQ1NTIHNlbGVjdG9yIG9yIGFuIEhUTUwgc3RyaW5nLCBhIGpRdWVyeVxuICAgIC8vIGNvbnRleHQgb3IgYW4gZWxlbWVudC4gU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUgdGhpcyB0byB1dGlsaXplIGFuXG4gICAgLy8gYWx0ZXJuYXRpdmUgRE9NIG1hbmlwdWxhdGlvbiBBUEkgYW5kIGFyZSBvbmx5IHJlcXVpcmVkIHRvIHNldCB0aGVcbiAgICAvLyBgdGhpcy5lbGAgcHJvcGVydHkuXG4gIF9zZXRFbGVtZW50OiBmdW5jdGlvbihlbCkge1xuICAgIHRoaXMuJGVsID0gZWwgaW5zdGFuY2VvZiAkID8gZWwgOiAkKGVsKTtcbiAgICB0aGlzLmVsID0gdGhpcy4kZWxbMF07XG4gIH0sXG5cbiAgICAvLyBTZXQgY2FsbGJhY2tzLCB3aGVyZSBgdGhpcy5ldmVudHNgIGlzIGEgaGFzaCBvZlxuICAgIC8vXG4gICAgLy8gKntcImV2ZW50IHNlbGVjdG9yXCI6IFwiY2FsbGJhY2tcIn0qXG4gICAgLy9cbiAgICAvLyAgICAge1xuICAgIC8vICAgICAgICdtb3VzZWRvd24gLnRpdGxlJzogICdlZGl0JyxcbiAgICAvLyAgICAgICAnY2xpY2sgLmJ1dHRvbic6ICAgICAnc2F2ZScsXG4gICAgLy8gICAgICAgJ2NsaWNrIC5vcGVuJzogICAgICAgZnVuY3Rpb24oZSkgeyAuLi4gfVxuICAgIC8vICAgICB9XG4gICAgLy9cbiAgICAvLyBwYWlycy4gQ2FsbGJhY2tzIHdpbGwgYmUgYm91bmQgdG8gdGhlIHZpZXcsIHdpdGggYHRoaXNgIHNldCBwcm9wZXJseS5cbiAgICAvLyBVc2VzIGV2ZW50IGRlbGVnYXRpb24gZm9yIGVmZmljaWVuY3kuXG4gICAgLy8gT21pdHRpbmcgdGhlIHNlbGVjdG9yIGJpbmRzIHRoZSBldmVudCB0byBgdGhpcy5lbGAuXG4gIGRlbGVnYXRlRXZlbnRzOiBmdW5jdGlvbihldmVudHMpIHtcbiAgICBpZiAoIShldmVudHMgfHwgKGV2ZW50cyA9IF8ucmVzdWx0KHRoaXMsICdldmVudHMnKSkpKSByZXR1cm4gdGhpcztcbiAgICB0aGlzLnVuZGVsZWdhdGVFdmVudHMoKTtcbiAgICBmb3IgKHZhciBrZXkgaW4gZXZlbnRzKSB7XG4gICAgICB2YXIgbWV0aG9kID0gZXZlbnRzW2tleV07XG4gICAgICBpZiAoIV8uaXNGdW5jdGlvbihtZXRob2QpKSBtZXRob2QgPSB0aGlzW2V2ZW50c1trZXldXTtcbiAgICAgIGlmICghbWV0aG9kKSBjb250aW51ZTtcbiAgICAgIHZhciBtYXRjaCA9IGtleS5tYXRjaChkZWxlZ2F0ZUV2ZW50U3BsaXR0ZXIpO1xuICAgICAgdGhpcy5kZWxlZ2F0ZShtYXRjaFsxXSwgbWF0Y2hbMl0sIF8uYmluZChtZXRob2QsIHRoaXMpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgICAvLyBBZGQgYSBzaW5nbGUgZXZlbnQgbGlzdGVuZXIgdG8gdGhlIHZpZXcncyBlbGVtZW50IChvciBhIGNoaWxkIGVsZW1lbnRcbiAgICAvLyB1c2luZyBgc2VsZWN0b3JgKS4gVGhpcyBvbmx5IHdvcmtzIGZvciBkZWxlZ2F0ZS1hYmxlIGV2ZW50czogbm90IGBmb2N1c2AsXG4gICAgLy8gYGJsdXJgLCBhbmQgbm90IGBjaGFuZ2VgLCBgc3VibWl0YCwgYW5kIGByZXNldGAgaW4gSW50ZXJuZXQgRXhwbG9yZXIuXG4gIGRlbGVnYXRlOiBmdW5jdGlvbihldmVudE5hbWUsIHNlbGVjdG9yLCBsaXN0ZW5lcikge1xuICAgIHRoaXMuJGVsLm9uKGV2ZW50TmFtZSArICcuZGVsZWdhdGVFdmVudHMnICsgdGhpcy5jaWQsIHNlbGVjdG9yLCBsaXN0ZW5lcik7XG4gIH0sXG5cbiAgICAvLyBDbGVhcnMgYWxsIGNhbGxiYWNrcyBwcmV2aW91c2x5IGJvdW5kIHRvIHRoZSB2aWV3IGJ5IGBkZWxlZ2F0ZUV2ZW50c2AuXG4gICAgLy8gWW91IHVzdWFsbHkgZG9uJ3QgbmVlZCB0byB1c2UgdGhpcywgYnV0IG1heSB3aXNoIHRvIGlmIHlvdSBoYXZlIG11bHRpcGxlXG4gICAgLy8gQmFja2JvbmUgdmlld3MgYXR0YWNoZWQgdG8gdGhlIHNhbWUgRE9NIGVsZW1lbnQuXG4gIHVuZGVsZWdhdGVFdmVudHM6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLiRlbCkgdGhpcy4kZWwub2ZmKCcuZGVsZWdhdGVFdmVudHMnICsgdGhpcy5jaWQpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gICAgLy8gQSBmaW5lci1ncmFpbmVkIGB1bmRlbGVnYXRlRXZlbnRzYCBmb3IgcmVtb3ZpbmcgYSBzaW5nbGUgZGVsZWdhdGVkIGV2ZW50LlxuICAgIC8vIGBzZWxlY3RvcmAgYW5kIGBsaXN0ZW5lcmAgYXJlIGJvdGggb3B0aW9uYWwuXG4gIHVuZGVsZWdhdGU6IGZ1bmN0aW9uKGV2ZW50TmFtZSwgc2VsZWN0b3IsIGxpc3RlbmVyKSB7XG4gICAgdGhpcy4kZWwub2ZmKGV2ZW50TmFtZSArICcuZGVsZWdhdGVFdmVudHMnICsgdGhpcy5jaWQsIHNlbGVjdG9yLCBsaXN0ZW5lcik7XG4gIH0sXG5cbiAgICAvLyBQcm9kdWNlcyBhIERPTSBlbGVtZW50IHRvIGJlIGFzc2lnbmVkIHRvIHlvdXIgdmlldy4gRXhwb3NlZCBmb3JcbiAgICAvLyBzdWJjbGFzc2VzIHVzaW5nIGFuIGFsdGVybmF0aXZlIERPTSBtYW5pcHVsYXRpb24gQVBJLlxuICBfY3JlYXRlRWxlbWVudDogZnVuY3Rpb24odGFnTmFtZSkge1xuICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpO1xuICB9LFxuXG4gICAgLy8gRW5zdXJlIHRoYXQgdGhlIFZpZXcgaGFzIGEgRE9NIGVsZW1lbnQgdG8gcmVuZGVyIGludG8uXG4gICAgLy8gSWYgYHRoaXMuZWxgIGlzIGEgc3RyaW5nLCBwYXNzIGl0IHRocm91Z2ggYCQoKWAsIHRha2UgdGhlIGZpcnN0XG4gICAgLy8gbWF0Y2hpbmcgZWxlbWVudCwgYW5kIHJlLWFzc2lnbiBpdCB0byBgZWxgLiBPdGhlcndpc2UsIGNyZWF0ZVxuICAgIC8vIGFuIGVsZW1lbnQgZnJvbSB0aGUgYGlkYCwgYGNsYXNzTmFtZWAgYW5kIGB0YWdOYW1lYCBwcm9wZXJ0aWVzLlxuICBfZW5zdXJlRWxlbWVudDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKCF0aGlzLmVsKSB7XG4gICAgICB2YXIgYXR0cnMgPSBfLmV4dGVuZCh7fSwgXy5yZXN1bHQodGhpcywgJ2F0dHJpYnV0ZXMnKSk7XG4gICAgICBpZiAodGhpcy5pZCkgYXR0cnMuaWQgPSBfLnJlc3VsdCh0aGlzLCAnaWQnKTtcbiAgICAgIGlmICh0aGlzLmNsYXNzTmFtZSkgYXR0cnNbJ2NsYXNzJ10gPSBfLnJlc3VsdCh0aGlzLCAnY2xhc3NOYW1lJyk7XG4gICAgICB0aGlzLnNldEVsZW1lbnQodGhpcy5fY3JlYXRlRWxlbWVudChfLnJlc3VsdCh0aGlzLCAndGFnTmFtZScpKSk7XG4gICAgICB0aGlzLl9zZXRBdHRyaWJ1dGVzKGF0dHJzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXRFbGVtZW50KF8ucmVzdWx0KHRoaXMsICdlbCcpKTtcbiAgICB9XG4gIH0sXG5cbiAgICAvLyBTZXQgYXR0cmlidXRlcyBmcm9tIGEgaGFzaCBvbiB0aGlzIHZpZXcncyBlbGVtZW50LiAgRXhwb3NlZCBmb3JcbiAgICAvLyBzdWJjbGFzc2VzIHVzaW5nIGFuIGFsdGVybmF0aXZlIERPTSBtYW5pcHVsYXRpb24gQVBJLlxuICBfc2V0QXR0cmlidXRlczogZnVuY3Rpb24oYXR0cmlidXRlcykge1xuICAgIHRoaXMuJGVsLmF0dHIoYXR0cmlidXRlcyk7XG4gIH1cblxufSk7XG5cbi8vIHNldHVwIGluaGVyaXRhbmNlXG5WaWV3LmV4dGVuZCA9IGV4dGVuZDtcbm1vZHVsZS5leHBvcnRzID0gVmlldztcbiIsInZhciBldmVudHMgPSByZXF1aXJlKFwiYmFja2JvbmUtZXZlbnRzLXN0YW5kYWxvbmVcIik7XG5cbmV2ZW50cy5vbkFsbCA9IGZ1bmN0aW9uKGNhbGxiYWNrLGNvbnRleHQpe1xuICB0aGlzLm9uKFwiYWxsXCIsIGNhbGxiYWNrLGNvbnRleHQpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIE1peGluIHV0aWxpdHlcbmV2ZW50cy5vbGRNaXhpbiA9IGV2ZW50cy5taXhpbjtcbmV2ZW50cy5taXhpbiA9IGZ1bmN0aW9uKHByb3RvKSB7XG4gIGV2ZW50cy5vbGRNaXhpbihwcm90byk7XG4gIC8vIGFkZCBjdXN0b20gb25BbGxcbiAgdmFyIGV4cG9ydHMgPSBbJ29uQWxsJ107XG4gIGZvcih2YXIgaT0wOyBpIDwgZXhwb3J0cy5sZW5ndGg7aSsrKXtcbiAgICB2YXIgbmFtZSA9IGV4cG9ydHNbaV07XG4gICAgcHJvdG9bbmFtZV0gPSB0aGlzW25hbWVdO1xuICB9XG4gIHJldHVybiBwcm90bztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZXZlbnRzO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjguMFxudmFyIEdlbmVyaWNSZWFkZXIsIHhocjtcblxueGhyID0gcmVxdWlyZSgnbmV0cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEdlbmVyaWNSZWFkZXIgPSAoZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIEdlbmVyaWNSZWFkZXIoKSB7fVxuXG4gIEdlbmVyaWNSZWFkZXIucmVhZCA9IGZ1bmN0aW9uKHVybCwgY2FsbGJhY2spIHtcbiAgICB2YXIgb25yZXQ7XG4gICAgb25yZXQgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihlcnIsIHJlc3BvbnNlLCB0ZXh0KSB7XG4gICAgICAgIHJldHVybiBfdGhpcy5fb25SZXRyaWV2YWwodGV4dCwgY2FsbGJhY2spO1xuICAgICAgfTtcbiAgICB9KSh0aGlzKTtcbiAgICByZXR1cm4geGhyKHVybCwgb25yZXQpO1xuICB9O1xuXG4gIEdlbmVyaWNSZWFkZXIuX29uUmV0cmlldmFsID0gZnVuY3Rpb24odGV4dCwgY2FsbGJhY2spIHtcbiAgICB2YXIgclRleHQ7XG4gICAgclRleHQgPSB0aGlzLnBhcnNlKHRleHQpO1xuICAgIHJldHVybiBjYWxsYmFjayhyVGV4dCk7XG4gIH07XG5cbiAgcmV0dXJuIEdlbmVyaWNSZWFkZXI7XG5cbn0pKCk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG52YXIgU2VxO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNlcSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gU2VxKHNlcSwgbmFtZSwgaWQpIHtcbiAgICB2YXIgbWV0YTtcbiAgICB0aGlzLnNlcSA9IHNlcTtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICBtZXRhID0ge307XG4gIH1cblxuICByZXR1cm4gU2VxO1xuXG59KSgpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjguMFxudmFyIHN0cmluZ3M7XG5cbnN0cmluZ3MgPSB7XG4gIGNvbnRhaW5zOiBmdW5jdGlvbih0ZXh0LCBzZWFyY2gpIHtcbiAgICByZXR1cm4gJycuaW5kZXhPZi5jYWxsKHRleHQsIHNlYXJjaCwgMCkgIT09IC0xO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHN0cmluZ3M7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG52YXIgRmFzdGEsIEdlbmVyaWNSZWFkZXIsIFNlcSwgU3RyLFxuICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgX19leHRlbmRzID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChfX2hhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH07XG5cblN0ciA9IHJlcXVpcmUoXCIuL3N0cmluZ3NcIik7XG5cbkdlbmVyaWNSZWFkZXIgPSByZXF1aXJlKFwiLi9nZW5lcmljX3JlYWRlclwiKTtcblxuU2VxID0gcmVxdWlyZShcImJpb2pzLW1vZGVsXCIpLnNlcTtcblxubW9kdWxlLmV4cG9ydHMgPSBGYXN0YSA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgX19leHRlbmRzKEZhc3RhLCBfc3VwZXIpO1xuXG4gIGZ1bmN0aW9uIEZhc3RhKCkge1xuICAgIHJldHVybiBGYXN0YS5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIEZhc3RhLnBhcnNlID0gZnVuY3Rpb24odGV4dCkge1xuICAgIHZhciBjdXJyZW50U2VxLCBkYXRhYmFzZSwgZGF0YWJhc2VJRCwgaWRlbnRpZmllcnMsIGssIGxhYmVsLCBsaW5lLCBzZXFzLCBfaSwgX2xlbjtcbiAgICBzZXFzID0gW107XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0ZXh0KSAhPT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgICAgdGV4dCA9IHRleHQuc3BsaXQoXCJcXG5cIik7XG4gICAgfVxuICAgIGZvciAoX2kgPSAwLCBfbGVuID0gdGV4dC5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgbGluZSA9IHRleHRbX2ldO1xuICAgICAgaWYgKGxpbmVbMF0gPT09IFwiPlwiIHx8IGxpbmVbMF0gPT09IFwiO1wiKSB7XG4gICAgICAgIGxhYmVsID0gbGluZS5zbGljZSgxKTtcbiAgICAgICAgY3VycmVudFNlcSA9IG5ldyBTZXEoXCJcIiwgbGFiZWwsIHNlcXMubGVuZ3RoKTtcbiAgICAgICAgc2Vxcy5wdXNoKGN1cnJlbnRTZXEpO1xuICAgICAgICBpZiAoU3RyLmNvbnRhaW5zKFwifFwiLCBsaW5lKSkge1xuICAgICAgICAgIGlkZW50aWZpZXJzID0gbGFiZWwuc3BsaXQoXCJ8XCIpO1xuICAgICAgICAgIGsgPSAxO1xuICAgICAgICAgIHdoaWxlIChrIDwgaWRlbnRpZmllcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBkYXRhYmFzZSA9IGlkZW50aWZpZXJzW2tdO1xuICAgICAgICAgICAgZGF0YWJhc2VJRCA9IGlkZW50aWZpZXJzW2sgKyAxXTtcbiAgICAgICAgICAgIGN1cnJlbnRTZXEubWV0YVtkYXRhYmFzZV0gPSBkYXRhYmFzZUlEO1xuICAgICAgICAgICAgayArPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJyZW50U2VxLm5hbWUgPSBpZGVudGlmaWVyc1tpZGVudGlmaWVycy5sZW5ndGggLSAxXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VycmVudFNlcS5zZXEgKz0gbGluZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNlcXM7XG4gIH07XG5cbiAgcmV0dXJuIEZhc3RhO1xuXG59KShHZW5lcmljUmVhZGVyKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS44LjBcbnZhciBVdGlscztcblxuVXRpbHMgPSB7fTtcblxuVXRpbHMuc3BsaXROQ2hhcnMgPSBmdW5jdGlvbih0eHQsIG51bSkge1xuICB2YXIgaSwgcmVzdWx0LCBfaSwgX3JlZjtcbiAgcmVzdWx0ID0gW107XG4gIGZvciAoaSA9IF9pID0gMCwgX3JlZiA9IHR4dC5sZW5ndGggLSAxOyBudW0gPiAwID8gX2kgPD0gX3JlZiA6IF9pID49IF9yZWY7IGkgPSBfaSArPSBudW0pIHtcbiAgICByZXN1bHQucHVzaCh0eHQuc3Vic3RyKGksIG51bSkpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFV0aWxzO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjguMFxudmFyIEZhc3RhRXhwb3J0ZXIsIFV0aWxzO1xuXG5VdGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZhc3RhRXhwb3J0ZXIgPSAoZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIEZhc3RhRXhwb3J0ZXIoKSB7fVxuXG4gIEZhc3RhRXhwb3J0ZXJbXCJleHBvcnRcIl0gPSBmdW5jdGlvbihzZXFzLCBhY2Nlc3MpIHtcbiAgICB2YXIgc2VxLCB0ZXh0LCBfaSwgX2xlbjtcbiAgICB0ZXh0ID0gXCJcIjtcbiAgICBmb3IgKF9pID0gMCwgX2xlbiA9IHNlcXMubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgIHNlcSA9IHNlcXNbX2ldO1xuICAgICAgaWYgKGFjY2VzcyAhPSBudWxsKSB7XG4gICAgICAgIHNlcSA9IGFjY2VzcyhzZXEpO1xuICAgICAgfVxuICAgICAgdGV4dCArPSBcIj5cIiArIHNlcS5uYW1lICsgXCJcXG5cIjtcbiAgICAgIHRleHQgKz0gKFV0aWxzLnNwbGl0TkNoYXJzKHNlcS5zZXEsIDgwKSkuam9pbihcIlxcblwiKTtcbiAgICAgIHRleHQgKz0gXCJcXG5cIjtcbiAgICB9XG4gICAgcmV0dXJuIHRleHQ7XG4gIH07XG5cbiAgcmV0dXJuIEZhc3RhRXhwb3J0ZXI7XG5cbn0pKCk7XG4iLCJtb2R1bGUuZXhwb3J0cy5zZXEgPSByZXF1aXJlKFwiLi9zZXFcIik7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHNlcSwgbmFtZSwgaWQpIHtcbiAgICB0aGlzLnNlcSA9IHNlcTtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICB0aGlzLm1ldGEgPSB7fTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vc3JjL2luZGV4LmpzJylcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBBOiBcIiMwMGEzNWNcIixcbiAgUjogXCIjMDBmYzAzXCIsXG4gIE46IFwiIzAwZWIxNFwiLFxuICBEOiBcIiMwMGViMTRcIixcbiAgQzogXCIjMDAwMGZmXCIsXG4gIFE6IFwiIzAwZjEwZVwiLFxuICBFOiBcIiMwMGYxMGVcIixcbiAgRzogXCIjMDA5ZDYyXCIsXG4gIEg6IFwiIzAwZDUyYVwiLFxuICBJOiBcIiMwMDU0YWJcIixcbiAgTDogXCIjMDA3Yjg0XCIsXG4gIEs6IFwiIzAwZmYwMFwiLFxuICBNOiBcIiMwMDk3NjhcIixcbiAgRjogXCIjMDA4Nzc4XCIsXG4gIFA6IFwiIzAwZTAxZlwiLFxuICBTOiBcIiMwMGQ1MmFcIixcbiAgVDogXCIjMDBkYjI0XCIsXG4gIFc6IFwiIzAwYTg1N1wiLFxuICBZOiBcIiMwMGU2MTlcIixcbiAgVjogXCIjMDA1ZmEwXCIsXG4gIEI6IFwiIzAwZWIxNFwiLFxuICBYOiBcIiMwMGI2NDlcIixcbiAgWjogXCIjMDBmMTBlXCJcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgQTogXCIjQkJCQkJCXCIsXG4gIEI6IFwiZ3JleVwiLFxuICBDOiBcInllbGxvd1wiLFxuICBEOiBcInJlZFwiLFxuICBFOiBcInJlZFwiLFxuICBGOiBcIm1hZ2VudGFcIixcbiAgRzogXCJicm93blwiLFxuICBIOiBcIiMwMEZGRkZcIixcbiAgSTogXCIjQkJCQkJCXCIsXG4gIEo6IFwiI2ZmZlwiLFxuICBLOiBcIiMwMEZGRkZcIixcbiAgTDogXCIjQkJCQkJCXCIsXG4gIE06IFwiI0JCQkJCQlwiLFxuICBOOiBcImdyZWVuXCIsXG4gIE86IFwiI2ZmZlwiLFxuICBQOiBcImJyb3duXCIsXG4gIFE6IFwiZ3JlZW5cIixcbiAgUjogXCIjMDBGRkZGXCIsXG4gIFM6IFwiZ3JlZW5cIixcbiAgVDogXCJncmVlblwiLFxuICBVOiBcIiNmZmZcIixcbiAgVjogXCIjQkJCQkJCXCIsXG4gIFc6IFwibWFnZW50YVwiLFxuICBYOiBcImdyZXlcIixcbiAgWTogXCJtYWdlbnRhXCIsXG4gIFo6IFwiZ3JleVwiLFxuICBHYXA6IFwiZ3JleVwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwib3JhbmdlXCIsXG4gIEI6IFwiI2ZmZlwiLFxuICBDOiBcImdyZWVuXCIsXG4gIEQ6IFwicmVkXCIsXG4gIEU6IFwicmVkXCIsXG4gIEY6IFwiYmx1ZVwiLFxuICBHOiBcIm9yYW5nZVwiLFxuICBIOiBcInJlZFwiLFxuICBJOiBcImdyZWVuXCIsXG4gIEo6IFwiI2ZmZlwiLFxuICBLOiBcInJlZFwiLFxuICBMOiBcImdyZWVuXCIsXG4gIE06IFwiZ3JlZW5cIixcbiAgTjogXCIjZmZmXCIsXG4gIE86IFwiI2ZmZlwiLFxuICBQOiBcIm9yYW5nZVwiLFxuICBROiBcIiNmZmZcIixcbiAgUjogXCJyZWRcIixcbiAgUzogXCJvcmFuZ2VcIixcbiAgVDogXCJvcmFuZ2VcIixcbiAgVTogXCIjZmZmXCIsXG4gIFY6IFwiZ3JlZW5cIixcbiAgVzogXCJibHVlXCIsXG4gIFg6IFwiI2ZmZlwiLFxuICBZOiBcImJsdWVcIixcbiAgWjogXCIjZmZmXCIsXG4gIEdhcDogXCIjZmZmXCJcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgQTogXCIjODBhMGYwXCIsXG4gIFI6IFwiI2YwMTUwNVwiLFxuICBOOiBcIiMwMGZmMDBcIixcbiAgRDogXCIjYzA0OGMwXCIsXG4gIEM6IFwiI2YwODA4MFwiLFxuICBROiBcIiMwMGZmMDBcIixcbiAgRTogXCIjYzA0OGMwXCIsXG4gIEc6IFwiI2YwOTA0OFwiLFxuICBIOiBcIiMxNWE0YTRcIixcbiAgSTogXCIjODBhMGYwXCIsXG4gIEw6IFwiIzgwYTBmMFwiLFxuICBLOiBcIiNmMDE1MDVcIixcbiAgTTogXCIjODBhMGYwXCIsXG4gIEY6IFwiIzgwYTBmMFwiLFxuICBQOiBcIiNmZmZmMDBcIixcbiAgUzogXCIjMDBmZjAwXCIsXG4gIFQ6IFwiIzAwZmYwMFwiLFxuICBXOiBcIiM4MGEwZjBcIixcbiAgWTogXCIjMTVhNGE0XCIsXG4gIFY6IFwiIzgwYTBmMFwiLFxuICBCOiBcIiNmZmZcIixcbiAgWDogXCIjZmZmXCIsXG4gIFo6IFwiI2ZmZlwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwiI2U3MThlN1wiLFxuICBSOiBcIiM2ZjkwNmZcIixcbiAgTjogXCIjMWJlNDFiXCIsXG4gIEQ6IFwiIzc3ODg3N1wiLFxuICBDOiBcIiMyM2RjMjNcIixcbiAgUTogXCIjOTI2ZDkyXCIsXG4gIEU6IFwiI2ZmMDBmZlwiLFxuICBHOiBcIiMwMGZmMDBcIixcbiAgSDogXCIjNzU4YTc1XCIsXG4gIEk6IFwiIzhhNzU4YVwiLFxuICBMOiBcIiNhZTUxYWVcIixcbiAgSzogXCIjYTA1ZmEwXCIsXG4gIE06IFwiI2VmMTBlZlwiLFxuICBGOiBcIiM5ODY3OThcIixcbiAgUDogXCIjMDBmZjAwXCIsXG4gIFM6IFwiIzM2YzkzNlwiLFxuICBUOiBcIiM0N2I4NDdcIixcbiAgVzogXCIjOGE3NThhXCIsXG4gIFk6IFwiIzIxZGUyMVwiLFxuICBWOiBcIiM4NTdhODVcIixcbiAgQjogXCIjNDliNjQ5XCIsXG4gIFg6IFwiIzc1OGE3NVwiLFxuICBaOiBcIiNjOTM2YzlcIlxufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBBOiBcIiNhZDAwNTJcIixcbiAgQjogXCIjMGMwMGYzXCIsXG4gIEM6IFwiI2MyMDAzZFwiLFxuICBEOiBcIiMwYzAwZjNcIixcbiAgRTogXCIjMGMwMGYzXCIsXG4gIEY6IFwiI2NiMDAzNFwiLFxuICBHOiBcIiM2YTAwOTVcIixcbiAgSDogXCIjMTUwMGVhXCIsXG4gIEk6IFwiI2ZmMDAwMFwiLFxuICBKOiBcIiNmZmZcIixcbiAgSzogXCIjMDAwMGZmXCIsXG4gIEw6IFwiI2VhMDAxNVwiLFxuICBNOiBcIiNiMDAwNGZcIixcbiAgTjogXCIjMGMwMGYzXCIsXG4gIE86IFwiI2ZmZlwiLFxuICBQOiBcIiM0NjAwYjlcIixcbiAgUTogXCIjMGMwMGYzXCIsXG4gIFI6IFwiIzAwMDBmZlwiLFxuICBTOiBcIiM1ZTAwYTFcIixcbiAgVDogXCIjNjEwMDllXCIsXG4gIFU6IFwiI2ZmZlwiLFxuICBWOiBcIiNmNjAwMDlcIixcbiAgVzogXCIjNWIwMGE0XCIsXG4gIFg6IFwiIzY4MDA5N1wiLFxuICBZOiBcIiM0ZjAwYjBcIixcbiAgWjogXCIjMGMwMGYzXCJcbn07XG4iLCJtb2R1bGUuZXhwb3J0cy5zZWxlY3RvciA9IHJlcXVpcmUoXCIuL3NlbGVjdG9yXCIpO1xuXG4vLyBiYXNpY3Ncbm1vZHVsZS5leHBvcnRzLnRheWxvciA9IHJlcXVpcmUoXCIuL3RheWxvclwiKTtcbm1vZHVsZS5leHBvcnRzLnphcHBvPSByZXF1aXJlKFwiLi96YXBwb1wiKTtcbm1vZHVsZS5leHBvcnRzLmh5ZHJvPSByZXF1aXJlKFwiLi9oeWRyb3Bob2JpY2l0eVwiKTtcblxubW9kdWxlLmV4cG9ydHMuY2x1c3RhbCA9IHJlcXVpcmUoXCIuL2NsdXN0YWxcIik7XG5tb2R1bGUuZXhwb3J0cy5jbHVzdGFsMiA9IHJlcXVpcmUoXCIuL2NsdXN0YWwyXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy5jdXJpZWQgPSByZXF1aXJlKFwiLi9idXJpZWRcIik7XG5tb2R1bGUuZXhwb3J0cy5jaW5lbWEgPSByZXF1aXJlKFwiLi9jaW5lbWFcIik7XG5tb2R1bGUuZXhwb3J0cy5udWNsZW90aWRlICA9IHJlcXVpcmUoXCIuL251Y2xlb3RpZGVcIik7XG5tb2R1bGUuZXhwb3J0cy5oZWxpeCAgPSByZXF1aXJlKFwiLi9oZWxpeFwiKTtcbm1vZHVsZS5leHBvcnRzLmxlc2sgID0gcmVxdWlyZShcIi4vbGVza1wiKTtcbm1vZHVsZS5leHBvcnRzLm1hZSA9IHJlcXVpcmUoXCIuL21hZVwiKTtcbm1vZHVsZS5leHBvcnRzLnB1cmluZSA9IHJlcXVpcmUoXCIuL3B1cmluZVwiKTtcbm1vZHVsZS5leHBvcnRzLnN0cmFuZCA9IHJlcXVpcmUoXCIuL3N0cmFuZFwiKTtcbm1vZHVsZS5leHBvcnRzLnR1cm4gPSByZXF1aXJlKFwiLi90dXJuXCIpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwiIG9yYW5nZVwiLFxuICBCOiBcIiAjZmZmXCIsXG4gIEM6IFwiIGdyZWVuXCIsXG4gIEQ6IFwiIHJlZFwiLFxuICBFOiBcIiByZWRcIixcbiAgRjogXCIgZ3JlZW5cIixcbiAgRzogXCIgb3JhbmdlXCIsXG4gIEg6IFwiIG1hZ2VudGFcIixcbiAgSTogXCIgZ3JlZW5cIixcbiAgSjogXCIgI2ZmZlwiLFxuICBLOiBcIiByZWRcIixcbiAgTDogXCIgZ3JlZW5cIixcbiAgTTogXCIgZ3JlZW5cIixcbiAgTjogXCIgbWFnZW50YVwiLFxuICBPOiBcIiAjZmZmXCIsXG4gIFA6IFwiIGdyZWVuXCIsXG4gIFE6IFwiIG1hZ2VudGFcIixcbiAgUjogXCIgcmVkXCIsXG4gIFM6IFwiIG9yYW5nZVwiLFxuICBUOiBcIiBvcmFuZ2VcIixcbiAgVTogXCIgI2ZmZlwiLFxuICBWOiBcIiBncmVlblwiLFxuICBXOiBcIiBncmVlblwiLFxuICBYOiBcIiAjZmZmXCIsXG4gIFk6IFwiIGdyZWVuXCIsXG4gIFo6IFwiICNmZmZcIixcbiAgR2FwOiBcIiAjZmZmXCJcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgQTogXCIgIzc3ZGQ4OFwiLFxuICBCOiBcIiAjZmZmXCIsXG4gIEM6IFwiICM5OWVlNjZcIixcbiAgRDogXCIgIzU1YmIzM1wiLFxuICBFOiBcIiAjNTViYjMzXCIsXG4gIEY6IFwiICM5OTk5ZmZcIixcbiAgRzogXCIgIzc3ZGQ4OFwiLFxuICBIOiBcIiAjNTU1NWZmXCIsXG4gIEk6IFwiICM2NmJiZmZcIixcbiAgSjogXCIgI2ZmZlwiLFxuICBLOiBcIiAjZmZjYzc3XCIsXG4gIEw6IFwiICM2NmJiZmZcIixcbiAgTTogXCIgIzY2YmJmZlwiLFxuICBOOiBcIiAjNTViYjMzXCIsXG4gIE86IFwiICNmZmZcIixcbiAgUDogXCIgI2VlYWFhYVwiLFxuICBROiBcIiAjNTViYjMzXCIsXG4gIFI6IFwiICNmZmNjNzdcIixcbiAgUzogXCIgI2ZmNDQ1NVwiLFxuICBUOiBcIiAjZmY0NDU1XCIsXG4gIFU6IFwiICNmZmZcIixcbiAgVjogXCIgIzY2YmJmZlwiLFxuICBXOiBcIiAjOTk5OWZmXCIsXG4gIFg6IFwiICNmZmZcIixcbiAgWTogXCIgIzk5OTlmZlwiLFxuICBaOiBcIiAjZmZmXCIsXG4gIEdhcDogXCIgI2ZmZlwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwiICM2NEY3M0ZcIixcbiAgQzogXCIgI0ZGQjM0MFwiLFxuICBHOiBcIiAjRUI0MTNDXCIsXG4gIFQ6IFwiICMzQzg4RUVcIixcbiAgVTogXCIgIzNDODhFRVwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwiICNGRjgzRkFcIixcbiAgQzogXCIgIzQwRTBEMFwiLFxuICBHOiBcIiAjRkY4M0ZBXCIsXG4gIFI6IFwiICNGRjgzRkFcIixcbiAgVDogXCIgIzQwRTBEMFwiLFxuICBVOiBcIiAjNDBFMEQwXCIsXG4gIFk6IFwiICM0MEUwRDBcIlxufTtcbiIsInZhciBCdXJpZWQgPSByZXF1aXJlKFwiLi9idXJpZWRcIik7XG52YXIgQ2luZW1hID0gcmVxdWlyZShcIi4vY2luZW1hXCIpO1xudmFyIENsdXN0YWwgPSByZXF1aXJlKFwiLi9jbHVzdGFsXCIpO1xudmFyIENsdXN0YWwyID0gcmVxdWlyZShcIi4vY2x1c3RhbDJcIik7XG52YXIgSGVsaXggPSByZXF1aXJlKFwiLi9oZWxpeFwiKTtcbnZhciBIeWRybyA9IHJlcXVpcmUoXCIuL2h5ZHJvcGhvYmljaXR5XCIpO1xudmFyIExlc2sgPSByZXF1aXJlKFwiLi9sZXNrXCIpO1xudmFyIE1hZSA9IHJlcXVpcmUoXCIuL21hZVwiKTtcbnZhciBOdWNsZW90aWRlID0gcmVxdWlyZShcIi4vbnVjbGVvdGlkZVwiKTtcbnZhciBQdXJpbmUgPSByZXF1aXJlKFwiLi9wdXJpbmVcIik7XG52YXIgU3RyYW5kID0gcmVxdWlyZShcIi4vc3RyYW5kXCIpO1xudmFyIFRheWxvciA9IHJlcXVpcmUoXCIuL3RheWxvclwiKTtcbnZhciBUdXJuID0gcmVxdWlyZShcIi4vdHVyblwiKTtcbnZhciBaYXBwbyA9IHJlcXVpcmUoXCIuL3phcHBvXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IENvbG9ycyA9IHtcbiAgbWFwcGluZzoge1xuICAgIGJ1cmllZDogQnVyaWVkLFxuICAgIGJ1cmllZF9pbmRleDogQnVyaWVkLFxuICAgIGNpbmVtYTogQ2luZW1hLFxuICAgIGNsdXN0YWwyOiBDbHVzdGFsMixcbiAgICBjbHVzdGFsOiBDbHVzdGFsLFxuICAgIGhlbGl4OiBIZWxpeCxcbiAgICBoZWxpeF9wcm9wZW5zaXR5OiBIZWxpeCxcbiAgICBoeWRybzogSHlkcm8sXG4gICAgbGVzazogTGVzayxcbiAgICBtYWU6IE1hZSxcbiAgICBudWNsZW90aWRlOiBOdWNsZW90aWRlLFxuICAgIHB1cmluZTogUHVyaW5lLFxuICAgIHB1cmluZV9weXJpbWlkaW5lOiBQdXJpbmUsXG4gICAgc3RyYW5kOiBTdHJhbmQsXG4gICAgc3RyYW5kX3Byb3BlbnNpdHk6IFN0cmFuZCxcbiAgICB0YXlsb3I6IFRheWxvcixcbiAgICB0dXJuOiBUdXJuLFxuICAgIHR1cm5fcHJvcGVuc2l0eTogVHVybixcbiAgICB6YXBwbzogWmFwcG8sXG4gIH0sXG4gIGdldENvbG9yOiBmdW5jdGlvbihzY2hlbWUpIHtcbiAgICB2YXIgY29sb3IgPSBDb2xvcnMubWFwcGluZ1tzY2hlbWVdO1xuICAgIGlmIChjb2xvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb2xvciA9IHt9O1xuICAgIH1cbiAgICByZXR1cm4gY29sb3I7XG4gIH1cbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgQTogXCIjNTg1OGE3XCIsXG4gIFI6IFwiIzZiNmI5NFwiLFxuICBOOiBcIiM2NDY0OWJcIixcbiAgRDogXCIjMjEyMWRlXCIsXG4gIEM6IFwiIzlkOWQ2MlwiLFxuICBROiBcIiM4YzhjNzNcIixcbiAgRTogXCIjMDAwMGZmXCIsXG4gIEc6IFwiIzQ5NDliNlwiLFxuICBIOiBcIiM2MDYwOWZcIixcbiAgSTogXCIjZWNlYzEzXCIsXG4gIEw6IFwiI2IyYjI0ZFwiLFxuICBLOiBcIiM0NzQ3YjhcIixcbiAgTTogXCIjODI4MjdkXCIsXG4gIEY6IFwiI2MyYzIzZFwiLFxuICBQOiBcIiMyMzIzZGNcIixcbiAgUzogXCIjNDk0OWI2XCIsXG4gIFQ6IFwiIzlkOWQ2MlwiLFxuICBXOiBcIiNjMGMwM2ZcIixcbiAgWTogXCIjZDNkMzJjXCIsXG4gIFY6IFwiI2ZmZmYwMFwiLFxuICBCOiBcIiM0MzQzYmNcIixcbiAgWDogXCIjNzk3OTg2XCIsXG4gIFo6IFwiIzQ3NDdiOFwiXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIEE6IFwiI2NjZmYwMFwiLFxuICBSOiBcIiMwMDAwZmZcIixcbiAgTjogXCIjY2MwMGZmXCIsXG4gIEQ6IFwiI2ZmMDAwMFwiLFxuICBDOiBcIiNmZmZmMDBcIixcbiAgUTogXCIjZmYwMGNjXCIsXG4gIEU6IFwiI2ZmMDA2NlwiLFxuICBHOiBcIiNmZjk5MDBcIixcbiAgSDogXCIjMDA2NmZmXCIsXG4gIEk6IFwiIzY2ZmYwMFwiLFxuICBMOiBcIiMzM2ZmMDBcIixcbiAgSzogXCIjNjYwMGZmXCIsXG4gIE06IFwiIzAwZmYwMFwiLFxuICBGOiBcIiMwMGZmNjZcIixcbiAgUDogXCIjZmZjYzAwXCIsXG4gIFM6IFwiI2ZmMzMwMFwiLFxuICBUOiBcIiNmZjY2MDBcIixcbiAgVzogXCIjMDBjY2ZmXCIsXG4gIFk6IFwiIzAwZmZjY1wiLFxuICBWOiBcIiM5OWZmMDBcIixcbiAgQjogXCIjZmZmXCIsXG4gIFg6IFwiI2ZmZlwiLFxuICBaOiBcIiNmZmZcIlxufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBBOiBcIiMyY2QzZDNcIixcbiAgUjogXCIjNzA4ZjhmXCIsXG4gIE46IFwiI2ZmMDAwMFwiLFxuICBEOiBcIiNlODE3MTdcIixcbiAgQzogXCIjYTg1NzU3XCIsXG4gIFE6IFwiIzNmYzBjMFwiLFxuICBFOiBcIiM3Nzg4ODhcIixcbiAgRzogXCIjZmYwMDAwXCIsXG4gIEg6IFwiIzcwOGY4ZlwiLFxuICBJOiBcIiMwMGZmZmZcIixcbiAgTDogXCIjMWNlM2UzXCIsXG4gIEs6IFwiIzdlODE4MVwiLFxuICBNOiBcIiMxZWUxZTFcIixcbiAgRjogXCIjMWVlMWUxXCIsXG4gIFA6IFwiI2Y2MDkwOVwiLFxuICBTOiBcIiNlMTFlMWVcIixcbiAgVDogXCIjNzM4YzhjXCIsXG4gIFc6IFwiIzczOGM4Y1wiLFxuICBZOiBcIiM5ZDYyNjJcIixcbiAgVjogXCIjMDdmOGY4XCIsXG4gIEI6IFwiI2YzMGMwY1wiLFxuICBYOiBcIiM3YzgzODNcIixcbiAgWjogXCIjNWJhNGE0XCJcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgQTogXCIjZmZhZmFmXCIsXG4gIFI6IFwiIzY0NjRmZlwiLFxuICBOOiBcIiMwMGZmMDBcIixcbiAgRDogXCIjZmYwMDAwXCIsXG4gIEM6IFwiI2ZmZmYwMFwiLFxuICBROiBcIiMwMGZmMDBcIixcbiAgRTogXCIjZmYwMDAwXCIsXG4gIEc6IFwiI2ZmMDBmZlwiLFxuICBIOiBcIiM2NDY0ZmZcIixcbiAgSTogXCIjZmZhZmFmXCIsXG4gIEw6IFwiI2ZmYWZhZlwiLFxuICBLOiBcIiM2NDY0ZmZcIixcbiAgTTogXCIjZmZhZmFmXCIsXG4gIEY6IFwiI2ZmYzgwMFwiLFxuICBQOiBcIiNmZjAwZmZcIixcbiAgUzogXCIjMDBmZjAwXCIsXG4gIFQ6IFwiIzAwZmYwMFwiLFxuICBXOiBcIiNmZmM4MDBcIixcbiAgWTogXCIjZmZjODAwXCIsXG4gIFY6IFwiI2ZmYWZhZlwiLFxuICBCOiBcIiNmZmZcIixcbiAgWDogXCIjZmZmXCIsXG4gIFo6IFwiI2ZmZlwiXG59O1xuIiwiLypcbiAqIEphdmFTY3JpcHQgQ2FudmFzIHRvIEJsb2IgMi4wLjVcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9ibHVlaW1wL0phdmFTY3JpcHQtQ2FudmFzLXRvLUJsb2JcbiAqXG4gKiBDb3B5cmlnaHQgMjAxMiwgU2ViYXN0aWFuIFRzY2hhblxuICogaHR0cHM6Ly9ibHVlaW1wLm5ldFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZTpcbiAqIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXG4gKlxuICogQmFzZWQgb24gc3RhY2tvdmVyZmxvdyB1c2VyIFN0b2l2ZSdzIGNvZGUgc25pcHBldDpcbiAqIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xLzQ5OTg5MDhcbiAqL1xudmFyIENhbnZhc1Byb3RvdHlwZSA9IHdpbmRvdy5IVE1MQ2FudmFzRWxlbWVudCAmJlxud2luZG93LkhUTUxDYW52YXNFbGVtZW50LnByb3RvdHlwZSxcbiAgaGFzQmxvYkNvbnN0cnVjdG9yID0gd2luZG93LkJsb2IgJiYgKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEJvb2xlYW4obmV3IEJsb2IoKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSgpKSxcbiAgaGFzQXJyYXlCdWZmZXJWaWV3U3VwcG9ydCA9IGhhc0Jsb2JDb25zdHJ1Y3RvciAmJiB3aW5kb3cuVWludDhBcnJheSAmJlxuICAoZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbmV3IEJsb2IoW25ldyBVaW50OEFycmF5KDEwMCldKS5zaXplID09PSAxMDA7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSgpKSxcbiAgQmxvYkJ1aWxkZXIgPSB3aW5kb3cuQmxvYkJ1aWxkZXIgfHwgd2luZG93LldlYktpdEJsb2JCdWlsZGVyIHx8XG4gIHdpbmRvdy5Nb3pCbG9iQnVpbGRlciB8fCB3aW5kb3cuTVNCbG9iQnVpbGRlcixcbiAgZGF0YVVSTHRvQmxvYiA9IChoYXNCbG9iQ29uc3RydWN0b3IgfHwgQmxvYkJ1aWxkZXIpICYmIHdpbmRvdy5hdG9iICYmXG4gIHdpbmRvdy5BcnJheUJ1ZmZlciAmJiB3aW5kb3cuVWludDhBcnJheSAmJiBmdW5jdGlvbiAoZGF0YVVSSSkge1xuICAgIHZhciBieXRlU3RyaW5nLFxuICAgIGFycmF5QnVmZmVyLFxuICAgIGludEFycmF5LFxuICAgICAgaSxcbiAgICAgIG1pbWVTdHJpbmcsXG4gICAgICAgIGJiO1xuICAgIGlmIChkYXRhVVJJLnNwbGl0KCcsJylbMF0uaW5kZXhPZignYmFzZTY0JykgPj0gMCkge1xuICAgICAgLy8gQ29udmVydCBiYXNlNjQgdG8gcmF3IGJpbmFyeSBkYXRhIGhlbGQgaW4gYSBzdHJpbmc6XG4gICAgICBieXRlU3RyaW5nID0gYXRvYihkYXRhVVJJLnNwbGl0KCcsJylbMV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDb252ZXJ0IGJhc2U2NC9VUkxFbmNvZGVkIGRhdGEgY29tcG9uZW50IHRvIHJhdyBiaW5hcnkgZGF0YTpcbiAgICAgIGJ5dGVTdHJpbmcgPSBkZWNvZGVVUklDb21wb25lbnQoZGF0YVVSSS5zcGxpdCgnLCcpWzFdKTtcbiAgICB9XG4gICAgLy8gV3JpdGUgdGhlIGJ5dGVzIG9mIHRoZSBzdHJpbmcgdG8gYW4gQXJyYXlCdWZmZXI6XG4gICAgYXJyYXlCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoYnl0ZVN0cmluZy5sZW5ndGgpO1xuICAgIGludEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlCdWZmZXIpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBieXRlU3RyaW5nLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBpbnRBcnJheVtpXSA9IGJ5dGVTdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICB9XG4gICAgLy8gU2VwYXJhdGUgb3V0IHRoZSBtaW1lIGNvbXBvbmVudDpcbiAgICBtaW1lU3RyaW5nID0gZGF0YVVSSS5zcGxpdCgnLCcpWzBdLnNwbGl0KCc6JylbMV0uc3BsaXQoJzsnKVswXTtcbiAgICAvLyBXcml0ZSB0aGUgQXJyYXlCdWZmZXIgKG9yIEFycmF5QnVmZmVyVmlldykgdG8gYSBibG9iOlxuICAgIGlmIChoYXNCbG9iQ29uc3RydWN0b3IpIHtcbiAgICAgIHJldHVybiBuZXcgQmxvYihcbiAgICAgICAgICBbaGFzQXJyYXlCdWZmZXJWaWV3U3VwcG9ydCA/IGludEFycmF5IDogYXJyYXlCdWZmZXJdLFxuICAgICAgICAgIHt0eXBlOiBtaW1lU3RyaW5nfVxuICAgICAgICAgICk7XG4gICAgfVxuICAgIGJiID0gbmV3IEJsb2JCdWlsZGVyKCk7XG4gICAgYmIuYXBwZW5kKGFycmF5QnVmZmVyKTtcbiAgICByZXR1cm4gYmIuZ2V0QmxvYihtaW1lU3RyaW5nKTtcbiAgfTtcbmlmICh3aW5kb3cuSFRNTENhbnZhc0VsZW1lbnQgJiYgIUNhbnZhc1Byb3RvdHlwZS50b0Jsb2IpIHtcbiAgaWYgKENhbnZhc1Byb3RvdHlwZS5tb3pHZXRBc0ZpbGUpIHtcbiAgICBDYW52YXNQcm90b3R5cGUudG9CbG9iID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0eXBlLCBxdWFsaXR5KSB7XG4gICAgICBpZiAocXVhbGl0eSAmJiBDYW52YXNQcm90b3R5cGUudG9EYXRhVVJMICYmIGRhdGFVUkx0b0Jsb2IpIHtcbiAgICAgICAgY2FsbGJhY2soZGF0YVVSTHRvQmxvYih0aGlzLnRvRGF0YVVSTCh0eXBlLCBxdWFsaXR5KSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sodGhpcy5tb3pHZXRBc0ZpbGUoJ2Jsb2InLCB0eXBlKSk7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIGlmIChDYW52YXNQcm90b3R5cGUudG9EYXRhVVJMICYmIGRhdGFVUkx0b0Jsb2IpIHtcbiAgICBDYW52YXNQcm90b3R5cGUudG9CbG9iID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0eXBlLCBxdWFsaXR5KSB7XG4gICAgICBjYWxsYmFjayhkYXRhVVJMdG9CbG9iKHRoaXMudG9EYXRhVVJMKHR5cGUsIHF1YWxpdHkpKSk7XG4gICAgfTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRhdGFVUkx0b0Jsb2I7XG4iLCIvKiBGaWxlU2F2ZXIuanNcbiAqICBBIHNhdmVBcygpIEZpbGVTYXZlciBpbXBsZW1lbnRhdGlvbi5cbiAqICAyMDE0LTA1LTI3XG4gKlxuICogIEJ5IEVsaSBHcmV5LCBodHRwOi8vZWxpZ3JleS5jb21cbiAqICBMaWNlbnNlOiBYMTEvTUlUXG4gKiAgICBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2VsaWdyZXkvRmlsZVNhdmVyLmpzL2Jsb2IvbWFzdGVyL0xJQ0VOU0UubWRcbiAqL1xuXG4vKmdsb2JhbCBzZWxmICovXG4vKmpzbGludCBiaXR3aXNlOiB0cnVlLCBpbmRlbnQ6IDQsIGxheGJyZWFrOiB0cnVlLCBsYXhjb21tYTogdHJ1ZSwgc21hcnR0YWJzOiB0cnVlLCBwbHVzcGx1czogdHJ1ZSAqL1xuXG4vKiEgQHNvdXJjZSBodHRwOi8vcHVybC5lbGlncmV5LmNvbS9naXRodWIvRmlsZVNhdmVyLmpzL2Jsb2IvbWFzdGVyL0ZpbGVTYXZlci5qcyAqL1xuXG52YXIgc2F2ZUFzID0gc2F2ZUFzXG4gIC8vIElFIDEwKyAobmF0aXZlIHNhdmVBcylcbiAgfHwgKHR5cGVvZiBuYXZpZ2F0b3IgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgIG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iICYmIG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iLmJpbmQobmF2aWdhdG9yKSlcbiAgLy8gRXZlcnlvbmUgZWxzZVxuICB8fCAoZnVuY3Rpb24odmlldykge1xuXHRcInVzZSBzdHJpY3RcIjtcblx0Ly8gSUUgPDEwIGlzIGV4cGxpY2l0bHkgdW5zdXBwb3J0ZWRcblx0aWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09IFwidW5kZWZpbmVkXCIgJiZcblx0ICAgIC9NU0lFIFsxLTldXFwuLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdHZhclxuXHRcdCAgZG9jID0gdmlldy5kb2N1bWVudFxuXHRcdCAgLy8gb25seSBnZXQgVVJMIHdoZW4gbmVjZXNzYXJ5IGluIGNhc2UgQmxvYi5qcyBoYXNuJ3Qgb3ZlcnJpZGRlbiBpdCB5ZXRcblx0XHQsIGdldF9VUkwgPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB2aWV3LlVSTCB8fCB2aWV3LndlYmtpdFVSTCB8fCB2aWV3O1xuXHRcdH1cblx0XHQsIHNhdmVfbGluayA9IGRvYy5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCIsIFwiYVwiKVxuXHRcdCwgY2FuX3VzZV9zYXZlX2xpbmsgPSAhdmlldy5leHRlcm5hbEhvc3QgJiYgXCJkb3dubG9hZFwiIGluIHNhdmVfbGlua1xuXHRcdCwgY2xpY2sgPSBmdW5jdGlvbihub2RlKSB7XG5cdFx0XHR2YXIgZXZlbnQgPSBkb2MuY3JlYXRlRXZlbnQoXCJNb3VzZUV2ZW50c1wiKTtcblx0XHRcdGV2ZW50LmluaXRNb3VzZUV2ZW50KFxuXHRcdFx0XHRcImNsaWNrXCIsIHRydWUsIGZhbHNlLCB2aWV3LCAwLCAwLCAwLCAwLCAwXG5cdFx0XHRcdCwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIDAsIG51bGxcblx0XHRcdCk7XG5cdFx0XHRub2RlLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuXHRcdH1cblx0XHQsIHdlYmtpdF9yZXFfZnMgPSB2aWV3LndlYmtpdFJlcXVlc3RGaWxlU3lzdGVtXG5cdFx0LCByZXFfZnMgPSB2aWV3LnJlcXVlc3RGaWxlU3lzdGVtIHx8IHdlYmtpdF9yZXFfZnMgfHwgdmlldy5tb3pSZXF1ZXN0RmlsZVN5c3RlbVxuXHRcdCwgdGhyb3dfb3V0c2lkZSA9IGZ1bmN0aW9uKGV4KSB7XG5cdFx0XHQodmlldy5zZXRJbW1lZGlhdGUgfHwgdmlldy5zZXRUaW1lb3V0KShmdW5jdGlvbigpIHtcblx0XHRcdFx0dGhyb3cgZXg7XG5cdFx0XHR9LCAwKTtcblx0XHR9XG5cdFx0LCBmb3JjZV9zYXZlYWJsZV90eXBlID0gXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1cIlxuXHRcdCwgZnNfbWluX3NpemUgPSAwXG5cdFx0LCBkZWxldGlvbl9xdWV1ZSA9IFtdXG5cdFx0LCBwcm9jZXNzX2RlbGV0aW9uX3F1ZXVlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgaSA9IGRlbGV0aW9uX3F1ZXVlLmxlbmd0aDtcblx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0dmFyIGZpbGUgPSBkZWxldGlvbl9xdWV1ZVtpXTtcblx0XHRcdFx0aWYgKHR5cGVvZiBmaWxlID09PSBcInN0cmluZ1wiKSB7IC8vIGZpbGUgaXMgYW4gb2JqZWN0IFVSTFxuXHRcdFx0XHRcdGdldF9VUkwoKS5yZXZva2VPYmplY3RVUkwoZmlsZSk7XG5cdFx0XHRcdH0gZWxzZSB7IC8vIGZpbGUgaXMgYSBGaWxlXG5cdFx0XHRcdFx0ZmlsZS5yZW1vdmUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0ZGVsZXRpb25fcXVldWUubGVuZ3RoID0gMDsgLy8gY2xlYXIgcXVldWVcblx0XHR9XG5cdFx0LCBkaXNwYXRjaCA9IGZ1bmN0aW9uKGZpbGVzYXZlciwgZXZlbnRfdHlwZXMsIGV2ZW50KSB7XG5cdFx0XHRldmVudF90eXBlcyA9IFtdLmNvbmNhdChldmVudF90eXBlcyk7XG5cdFx0XHR2YXIgaSA9IGV2ZW50X3R5cGVzLmxlbmd0aDtcblx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0dmFyIGxpc3RlbmVyID0gZmlsZXNhdmVyW1wib25cIiArIGV2ZW50X3R5cGVzW2ldXTtcblx0XHRcdFx0aWYgKHR5cGVvZiBsaXN0ZW5lciA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdGxpc3RlbmVyLmNhbGwoZmlsZXNhdmVyLCBldmVudCB8fCBmaWxlc2F2ZXIpO1xuXHRcdFx0XHRcdH0gY2F0Y2ggKGV4KSB7XG5cdFx0XHRcdFx0XHR0aHJvd19vdXRzaWRlKGV4KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0LCBGaWxlU2F2ZXIgPSBmdW5jdGlvbihibG9iLCBuYW1lKSB7XG5cdFx0XHQvLyBGaXJzdCB0cnkgYS5kb3dubG9hZCwgdGhlbiB3ZWIgZmlsZXN5c3RlbSwgdGhlbiBvYmplY3QgVVJMc1xuXHRcdFx0dmFyXG5cdFx0XHRcdCAgZmlsZXNhdmVyID0gdGhpc1xuXHRcdFx0XHQsIHR5cGUgPSBibG9iLnR5cGVcblx0XHRcdFx0LCBibG9iX2NoYW5nZWQgPSBmYWxzZVxuXHRcdFx0XHQsIG9iamVjdF91cmxcblx0XHRcdFx0LCB0YXJnZXRfdmlld1xuXHRcdFx0XHQsIGdldF9vYmplY3RfdXJsID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0dmFyIG9iamVjdF91cmwgPSBnZXRfVVJMKCkuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuXHRcdFx0XHRcdGRlbGV0aW9uX3F1ZXVlLnB1c2gob2JqZWN0X3VybCk7XG5cdFx0XHRcdFx0cmV0dXJuIG9iamVjdF91cmw7XG5cdFx0XHRcdH1cblx0XHRcdFx0LCBkaXNwYXRjaF9hbGwgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRkaXNwYXRjaChmaWxlc2F2ZXIsIFwid3JpdGVzdGFydCBwcm9ncmVzcyB3cml0ZSB3cml0ZWVuZFwiLnNwbGl0KFwiIFwiKSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly8gb24gYW55IGZpbGVzeXMgZXJyb3JzIHJldmVydCB0byBzYXZpbmcgd2l0aCBvYmplY3QgVVJMc1xuXHRcdFx0XHQsIGZzX2Vycm9yID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0Ly8gZG9uJ3QgY3JlYXRlIG1vcmUgb2JqZWN0IFVSTHMgdGhhbiBuZWVkZWRcblx0XHRcdFx0XHRpZiAoYmxvYl9jaGFuZ2VkIHx8ICFvYmplY3RfdXJsKSB7XG5cdFx0XHRcdFx0XHRvYmplY3RfdXJsID0gZ2V0X29iamVjdF91cmwoYmxvYik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICh0YXJnZXRfdmlldykge1xuXHRcdFx0XHRcdFx0dGFyZ2V0X3ZpZXcubG9jYXRpb24uaHJlZiA9IG9iamVjdF91cmw7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHdpbmRvdy5vcGVuKG9iamVjdF91cmwsIFwiX2JsYW5rXCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FO1xuXHRcdFx0XHRcdGRpc3BhdGNoX2FsbCgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCwgYWJvcnRhYmxlID0gZnVuY3Rpb24oZnVuYykge1xuXHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdGlmIChmaWxlc2F2ZXIucmVhZHlTdGF0ZSAhPT0gZmlsZXNhdmVyLkRPTkUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9XG5cdFx0XHRcdCwgY3JlYXRlX2lmX25vdF9mb3VuZCA9IHtjcmVhdGU6IHRydWUsIGV4Y2x1c2l2ZTogZmFsc2V9XG5cdFx0XHRcdCwgc2xpY2Vcblx0XHRcdDtcblx0XHRcdGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLklOSVQ7XG5cdFx0XHRpZiAoIW5hbWUpIHtcblx0XHRcdFx0bmFtZSA9IFwiZG93bmxvYWRcIjtcblx0XHRcdH1cblx0XHRcdGlmIChjYW5fdXNlX3NhdmVfbGluaykge1xuXHRcdFx0XHRvYmplY3RfdXJsID0gZ2V0X29iamVjdF91cmwoYmxvYik7XG5cdFx0XHRcdHNhdmVfbGluay5ocmVmID0gb2JqZWN0X3VybDtcblx0XHRcdFx0c2F2ZV9saW5rLmRvd25sb2FkID0gbmFtZTtcblx0XHRcdFx0Y2xpY2soc2F2ZV9saW5rKTtcblx0XHRcdFx0ZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTtcblx0XHRcdFx0ZGlzcGF0Y2hfYWxsKCk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdC8vIE9iamVjdCBhbmQgd2ViIGZpbGVzeXN0ZW0gVVJMcyBoYXZlIGEgcHJvYmxlbSBzYXZpbmcgaW4gR29vZ2xlIENocm9tZSB3aGVuXG5cdFx0XHQvLyB2aWV3ZWQgaW4gYSB0YWIsIHNvIEkgZm9yY2Ugc2F2ZSB3aXRoIGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVxuXHRcdFx0Ly8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9OTExNThcblx0XHRcdGlmICh2aWV3LmNocm9tZSAmJiB0eXBlICYmIHR5cGUgIT09IGZvcmNlX3NhdmVhYmxlX3R5cGUpIHtcblx0XHRcdFx0c2xpY2UgPSBibG9iLnNsaWNlIHx8IGJsb2Iud2Via2l0U2xpY2U7XG5cdFx0XHRcdGJsb2IgPSBzbGljZS5jYWxsKGJsb2IsIDAsIGJsb2Iuc2l6ZSwgZm9yY2Vfc2F2ZWFibGVfdHlwZSk7XG5cdFx0XHRcdGJsb2JfY2hhbmdlZCA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHQvLyBTaW5jZSBJIGNhbid0IGJlIHN1cmUgdGhhdCB0aGUgZ3Vlc3NlZCBtZWRpYSB0eXBlIHdpbGwgdHJpZ2dlciBhIGRvd25sb2FkXG5cdFx0XHQvLyBpbiBXZWJLaXQsIEkgYXBwZW5kIC5kb3dubG9hZCB0byB0aGUgZmlsZW5hbWUuXG5cdFx0XHQvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NjU0NDBcblx0XHRcdGlmICh3ZWJraXRfcmVxX2ZzICYmIG5hbWUgIT09IFwiZG93bmxvYWRcIikge1xuXHRcdFx0XHRuYW1lICs9IFwiLmRvd25sb2FkXCI7XG5cdFx0XHR9XG5cdFx0XHRpZiAodHlwZSA9PT0gZm9yY2Vfc2F2ZWFibGVfdHlwZSB8fCB3ZWJraXRfcmVxX2ZzKSB7XG5cdFx0XHRcdHRhcmdldF92aWV3ID0gdmlldztcblx0XHRcdH1cblx0XHRcdGlmICghcmVxX2ZzKSB7XG5cdFx0XHRcdGZzX2Vycm9yKCk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGZzX21pbl9zaXplICs9IGJsb2Iuc2l6ZTtcblx0XHRcdHJlcV9mcyh2aWV3LlRFTVBPUkFSWSwgZnNfbWluX3NpemUsIGFib3J0YWJsZShmdW5jdGlvbihmcykge1xuXHRcdFx0XHRmcy5yb290LmdldERpcmVjdG9yeShcInNhdmVkXCIsIGNyZWF0ZV9pZl9ub3RfZm91bmQsIGFib3J0YWJsZShmdW5jdGlvbihkaXIpIHtcblx0XHRcdFx0XHR2YXIgc2F2ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0ZGlyLmdldEZpbGUobmFtZSwgY3JlYXRlX2lmX25vdF9mb3VuZCwgYWJvcnRhYmxlKGZ1bmN0aW9uKGZpbGUpIHtcblx0XHRcdFx0XHRcdFx0ZmlsZS5jcmVhdGVXcml0ZXIoYWJvcnRhYmxlKGZ1bmN0aW9uKHdyaXRlcikge1xuXHRcdFx0XHRcdFx0XHRcdHdyaXRlci5vbndyaXRlZW5kID0gZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHRhcmdldF92aWV3LmxvY2F0aW9uLmhyZWYgPSBmaWxlLnRvVVJMKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRkZWxldGlvbl9xdWV1ZS5wdXNoKGZpbGUpO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTtcblx0XHRcdFx0XHRcdFx0XHRcdGRpc3BhdGNoKGZpbGVzYXZlciwgXCJ3cml0ZWVuZFwiLCBldmVudCk7XG5cdFx0XHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdFx0XHR3cml0ZXIub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dmFyIGVycm9yID0gd3JpdGVyLmVycm9yO1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKGVycm9yLmNvZGUgIT09IGVycm9yLkFCT1JUX0VSUikge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRmc19lcnJvcigpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0XHRcdFx0XCJ3cml0ZXN0YXJ0IHByb2dyZXNzIHdyaXRlIGFib3J0XCIuc3BsaXQoXCIgXCIpLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHdyaXRlcltcIm9uXCIgKyBldmVudF0gPSBmaWxlc2F2ZXJbXCJvblwiICsgZXZlbnRdO1xuXHRcdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHRcdHdyaXRlci53cml0ZShibG9iKTtcblx0XHRcdFx0XHRcdFx0XHRmaWxlc2F2ZXIuYWJvcnQgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdHdyaXRlci5hYm9ydCgpO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTtcblx0XHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0XHRcdGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLldSSVRJTkc7XG5cdFx0XHRcdFx0XHRcdH0pLCBmc19lcnJvcik7XG5cdFx0XHRcdFx0XHR9KSwgZnNfZXJyb3IpO1xuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0ZGlyLmdldEZpbGUobmFtZSwge2NyZWF0ZTogZmFsc2V9LCBhYm9ydGFibGUoZnVuY3Rpb24oZmlsZSkge1xuXHRcdFx0XHRcdFx0Ly8gZGVsZXRlIGZpbGUgaWYgaXQgYWxyZWFkeSBleGlzdHNcblx0XHRcdFx0XHRcdGZpbGUucmVtb3ZlKCk7XG5cdFx0XHRcdFx0XHRzYXZlKCk7XG5cdFx0XHRcdFx0fSksIGFib3J0YWJsZShmdW5jdGlvbihleCkge1xuXHRcdFx0XHRcdFx0aWYgKGV4LmNvZGUgPT09IGV4Lk5PVF9GT1VORF9FUlIpIHtcblx0XHRcdFx0XHRcdFx0c2F2ZSgpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0ZnNfZXJyb3IoKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSk7XG5cdFx0XHRcdH0pLCBmc19lcnJvcik7XG5cdFx0XHR9KSwgZnNfZXJyb3IpO1xuXHRcdH1cblx0XHQsIEZTX3Byb3RvID0gRmlsZVNhdmVyLnByb3RvdHlwZVxuXHRcdCwgc2F2ZUFzID0gZnVuY3Rpb24oYmxvYiwgbmFtZSkge1xuXHRcdFx0cmV0dXJuIG5ldyBGaWxlU2F2ZXIoYmxvYiwgbmFtZSk7XG5cdFx0fVxuXHQ7XG5cdEZTX3Byb3RvLmFib3J0ID0gZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGZpbGVzYXZlciA9IHRoaXM7XG5cdFx0ZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTtcblx0XHRkaXNwYXRjaChmaWxlc2F2ZXIsIFwiYWJvcnRcIik7XG5cdH07XG5cdEZTX3Byb3RvLnJlYWR5U3RhdGUgPSBGU19wcm90by5JTklUID0gMDtcblx0RlNfcHJvdG8uV1JJVElORyA9IDE7XG5cdEZTX3Byb3RvLkRPTkUgPSAyO1xuXG5cdEZTX3Byb3RvLmVycm9yID1cblx0RlNfcHJvdG8ub253cml0ZXN0YXJ0ID1cblx0RlNfcHJvdG8ub25wcm9ncmVzcyA9XG5cdEZTX3Byb3RvLm9ud3JpdGUgPVxuXHRGU19wcm90by5vbmFib3J0ID1cblx0RlNfcHJvdG8ub25lcnJvciA9XG5cdEZTX3Byb3RvLm9ud3JpdGVlbmQgPVxuXHRcdG51bGw7XG5cblx0dmlldy5hZGRFdmVudExpc3RlbmVyKFwidW5sb2FkXCIsIHByb2Nlc3NfZGVsZXRpb25fcXVldWUsIGZhbHNlKTtcblx0c2F2ZUFzLnVubG9hZCA9IGZ1bmN0aW9uKCkge1xuXHRcdHByb2Nlc3NfZGVsZXRpb25fcXVldWUoKTtcblx0XHR2aWV3LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ1bmxvYWRcIiwgcHJvY2Vzc19kZWxldGlvbl9xdWV1ZSwgZmFsc2UpO1xuXHR9O1xuXHRyZXR1cm4gc2F2ZUFzO1xufShcblx0ICAgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgJiYgc2VsZlxuXHR8fCB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvd1xuXHR8fCB0aGlzLmNvbnRlbnRcbikpO1xuLy8gYHNlbGZgIGlzIHVuZGVmaW5lZCBpbiBGaXJlZm94IGZvciBBbmRyb2lkIGNvbnRlbnQgc2NyaXB0IGNvbnRleHRcbi8vIHdoaWxlIGB0aGlzYCBpcyBuc0lDb250ZW50RnJhbWVNZXNzYWdlTWFuYWdlclxuLy8gd2l0aCBhbiBhdHRyaWJ1dGUgYGNvbnRlbnRgIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHdpbmRvd1xuXG5hbWREZWZpbmUgPSB3aW5kb3cuZGVmaW5lO1xuaWYoIHR5cGVvZiBhbWREZWZpbmUgPT09IFwidW5kZWZpbmVkXCIgJiYgKHR5cGVvZiB3aW5kb3cuYWxtb25kICE9PSBcInVuZGVmaW5lZFwiIFxuICAgICYmIFwiZGVmaW5lXCIgaW4gd2luZG93LmFsbW9uZCApKXtcbiAgYW1kRGVmaW5lID0gd2luZG93LmFsbW9uZC5kZWZpbmU7XG59XG5cbmlmICh0eXBlb2YgbW9kdWxlICE9PSBcInVuZGVmaW5lZFwiICYmIG1vZHVsZSAhPT0gbnVsbCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IHNhdmVBcztcbn0gZWxzZSBpZiAoKHR5cGVvZiBhbWREZWZpbmUgIT09IFwidW5kZWZpbmVkXCIgJiYgYW1kRGVmaW5lICE9PSBudWxsKSAmJiAoYW1kRGVmaW5lLmFtZCAhPSBudWxsKSkge1xuICBhbWREZWZpbmUoXCJzYXZlQXNcIixbXSwgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNhdmVBcztcbiAgfSk7XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjc3MsIGN1c3RvbURvY3VtZW50KSB7XG4gIHZhciBkb2MgPSBjdXN0b21Eb2N1bWVudCB8fCBkb2N1bWVudDtcbiAgaWYgKGRvYy5jcmVhdGVTdHlsZVNoZWV0KSB7XG4gICAgdmFyIHNoZWV0ID0gZG9jLmNyZWF0ZVN0eWxlU2hlZXQoKVxuICAgIHNoZWV0LmNzc1RleHQgPSBjc3M7XG4gICAgcmV0dXJuIHNoZWV0Lm93bmVyTm9kZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaGVhZCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdLFxuICAgICAgICBzdHlsZSA9IGRvYy5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuXG4gICAgc3R5bGUudHlwZSA9ICd0ZXh0L2Nzcyc7XG5cbiAgICBpZiAoc3R5bGUuc3R5bGVTaGVldCkge1xuICAgICAgc3R5bGUuc3R5bGVTaGVldC5jc3NUZXh0ID0gY3NzO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHlsZS5hcHBlbmRDaGlsZChkb2MuY3JlYXRlVGV4dE5vZGUoY3NzKSk7XG4gICAgfVxuXG4gICAgaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG4gICAgcmV0dXJuIHN0eWxlO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5ieVVybCA9IGZ1bmN0aW9uKHVybCkge1xuICBpZiAoZG9jdW1lbnQuY3JlYXRlU3R5bGVTaGVldCkge1xuICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVTdHlsZVNoZWV0KHVybCkub3duZXJOb2RlO1xuICB9IGVsc2Uge1xuICAgIHZhciBoZWFkID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXSxcbiAgICAgICAgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpbmsnKTtcblxuICAgIGxpbmsucmVsID0gJ3N0eWxlc2hlZXQnO1xuICAgIGxpbmsuaHJlZiA9IHVybDtcblxuICAgIGhlYWQuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgcmV0dXJuIGxpbms7XG4gIH1cbn07XG4iLCJ2YXIgVXRpbHMgPSB7fTtcblxuXG4vKlxuUmVtb3ZlIGFuIGVsZW1lbnQgYW5kIHByb3ZpZGUgYSBmdW5jdGlvbiB0aGF0IGluc2VydHMgaXQgaW50byBpdHMgb3JpZ2luYWwgcG9zaXRpb25cbmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3NwZWVkL2FydGljbGVzL2phdmFzY3JpcHQtZG9tXG5AcGFyYW0gZWxlbWVudCB7RWxlbWVudH0gVGhlIGVsZW1lbnQgdG8gYmUgdGVtcG9yYXJpbHkgcmVtb3ZlZFxuQHJldHVybiB7RnVuY3Rpb259IEEgZnVuY3Rpb24gdGhhdCBpbnNlcnRzIHRoZSBlbGVtZW50IGludG8gaXRzIG9yaWdpbmFsIHBvc2l0aW9uXG4gKi9cblxuVXRpbHMucmVtb3ZlVG9JbnNlcnRMYXRlciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgdmFyIG5leHRTaWJsaW5nLCBwYXJlbnROb2RlO1xuICBwYXJlbnROb2RlID0gZWxlbWVudC5wYXJlbnROb2RlO1xuICBuZXh0U2libGluZyA9IGVsZW1lbnQubmV4dFNpYmxpbmc7XG4gIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWxlbWVudCk7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBpZiAobmV4dFNpYmxpbmcpIHtcbiAgICAgIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnQsIG5leHRTaWJsaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICB9XG4gIH07XG59O1xuXG5cbi8qXG5mYXN0ZXN0IHBvc3NpYmxlIHdheSB0byBkZXN0cm95IGFsbCBzdWIgbm9kZXMgKGFrYSBjaGlsZHMpXG5odHRwOi8vanNwZXJmLmNvbS9pbm5lcmh0bWwtdnMtcmVtb3ZlY2hpbGQvMTVcbkBwYXJhbSBlbGVtZW50IHtFbGVtZW50fSBUaGUgZWxlbWVudCBmb3Igd2hpY2ggYWxsIGNoaWxkcyBzaG91bGQgYmUgcmVtb3ZlZFxuICovXG5cblV0aWxzLnJlbW92ZUFsbENoaWxkcyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgdmFyIGNvdW50O1xuICBjb3VudCA9IDA7XG4gIHdoaWxlIChlbGVtZW50LmZpcnN0Q2hpbGQpIHtcbiAgICBjb3VudCsrO1xuICAgIGVsZW1lbnQucmVtb3ZlQ2hpbGQoZWxlbWVudC5maXJzdENoaWxkKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBVdGlscztcbiIsIi8qIVxuICogakJvbmUgdjEuMC4xOSAtIDIwMTQtMTAtMTIgLSBMaWJyYXJ5IGZvciBET00gbWFuaXB1bGF0aW9uXG4gKlxuICogaHR0cHM6Ly9naXRodWIuY29tL2t1cHJpeWFuZW5rby9qYm9uZVxuICpcbiAqIENvcHlyaWdodCAyMDE0IEFsZXhleSBLdXByaXlhbmVua29cbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbiAqL1xuXG4oZnVuY3Rpb24gKHdpbikge1xuXG52YXJcbi8vIGNhY2hlIHByZXZpb3VzIHZlcnNpb25zXG5fJCA9IHdpbi4kLFxuX2pCb25lID0gd2luLmpCb25lLFxuXG4vLyBRdWljayBtYXRjaCBhIHN0YW5kYWxvbmUgdGFnXG5ycXVpY2tTaW5nbGVUYWcgPSAvXjwoXFx3KylcXHMqXFwvPz4kLyxcblxuLy8gQSBzaW1wbGUgd2F5IHRvIGNoZWNrIGZvciBIVE1MIHN0cmluZ3Ncbi8vIFByaW9yaXRpemUgI2lkIG92ZXIgPHRhZz4gdG8gYXZvaWQgWFNTIHZpYSBsb2NhdGlvbi5oYXNoXG5ycXVpY2tFeHByID0gL14oPzpbXiM8XSooPFtcXHdcXFddKz4pW14+XSokfCMoW1xcd1xcLV0qKSQpLyxcblxuLy8gQWxpYXMgZm9yIGZ1bmN0aW9uXG5zbGljZSA9IFtdLnNsaWNlLFxuc3BsaWNlID0gW10uc3BsaWNlLFxua2V5cyA9IE9iamVjdC5rZXlzLFxuXG4vLyBBbGlhcyBmb3IgZ2xvYmFsIHZhcmlhYmxlc1xuZG9jID0gZG9jdW1lbnQsXG5cbmlzU3RyaW5nID0gZnVuY3Rpb24oZWwpIHtcbiAgICByZXR1cm4gdHlwZW9mIGVsID09PSBcInN0cmluZ1wiO1xufSxcbmlzT2JqZWN0ID0gZnVuY3Rpb24oZWwpIHtcbiAgICByZXR1cm4gZWwgaW5zdGFuY2VvZiBPYmplY3Q7XG59LFxuaXNGdW5jdGlvbiA9IGZ1bmN0aW9uKGVsKSB7XG4gICAgdmFyIGdldFR5cGUgPSB7fTtcbiAgICByZXR1cm4gZWwgJiYgZ2V0VHlwZS50b1N0cmluZy5jYWxsKGVsKSA9PT0gXCJbb2JqZWN0IEZ1bmN0aW9uXVwiO1xufSxcbmlzQXJyYXkgPSBmdW5jdGlvbihlbCkge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KGVsKTtcbn0sXG5qQm9uZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIGRhdGEpIHtcbiAgICByZXR1cm4gbmV3IGZuLmluaXQoZWxlbWVudCwgZGF0YSk7XG59LFxuZm47XG5cbi8vIHNldCBwcmV2aW91cyB2YWx1ZXMgYW5kIHJldHVybiB0aGUgaW5zdGFuY2UgdXBvbiBjYWxsaW5nIHRoZSBuby1jb25mbGljdCBtb2RlXG5qQm9uZS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oKSB7XG4gICAgd2luLiQgPSBfJDtcbiAgICB3aW4uakJvbmUgPSBfakJvbmU7XG5cbiAgICByZXR1cm4gakJvbmU7XG59O1xuXG5mbiA9IGpCb25lLmZuID0gakJvbmUucHJvdG90eXBlID0ge1xuICAgIGluaXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGRhdGEpIHtcbiAgICAgICAgdmFyIGVsZW1lbnRzLCB0YWcsIHdyYXBlciwgZnJhZ21lbnQ7XG5cbiAgICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNTdHJpbmcoZWxlbWVudCkpIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSBzaW5nbGUgRE9NIGVsZW1lbnRcbiAgICAgICAgICAgIGlmICh0YWcgPSBycXVpY2tTaW5nbGVUYWcuZXhlYyhlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHRoaXNbMF0gPSBkb2MuY3JlYXRlRWxlbWVudCh0YWdbMV0pO1xuICAgICAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gMTtcblxuICAgICAgICAgICAgICAgIGlmIChpc09iamVjdChkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmF0dHIoZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBDcmVhdGUgRE9NIGNvbGxlY3Rpb25cbiAgICAgICAgICAgIGlmICgodGFnID0gcnF1aWNrRXhwci5leGVjKGVsZW1lbnQpKSAmJiB0YWdbMV0pIHtcbiAgICAgICAgICAgICAgICBmcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgICAgICAgICAgICAgd3JhcGVyID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgICAgICAgICAgd3JhcGVyLmlubmVySFRNTCA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHdyYXBlci5sYXN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQod3JhcGVyLmZpcnN0Q2hpbGQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbGVtZW50cyA9IHNsaWNlLmNhbGwoZnJhZ21lbnQuY2hpbGROb2Rlcyk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gakJvbmUubWVyZ2UodGhpcywgZWxlbWVudHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRmluZCBET00gZWxlbWVudHMgd2l0aCBxdWVyeVNlbGVjdG9yQWxsXG4gICAgICAgICAgICBpZiAoakJvbmUuaXNFbGVtZW50KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGpCb25lKGRhdGEpLmZpbmQoZWxlbWVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMgPSBkb2MucXVlcnlTZWxlY3RvckFsbChlbGVtZW50KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBqQm9uZS5tZXJnZSh0aGlzLCBlbGVtZW50cyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gV3JhcCBET01FbGVtZW50XG4gICAgICAgIGlmIChlbGVtZW50Lm5vZGVUeXBlKSB7XG4gICAgICAgICAgICB0aGlzWzBdID0gZWxlbWVudDtcbiAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gMTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUnVuIGZ1bmN0aW9uXG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudCgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJldHVybiBqQm9uZSBlbGVtZW50IGFzIGlzXG4gICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgakJvbmUpIHtcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmV0dXJuIGVsZW1lbnQgd3JhcHBlZCBieSBqQm9uZVxuICAgICAgICByZXR1cm4gakJvbmUubWFrZUFycmF5KGVsZW1lbnQsIHRoaXMpO1xuICAgIH0sXG5cbiAgICBwb3A6IFtdLnBvcCxcbiAgICBwdXNoOiBbXS5wdXNoLFxuICAgIHJldmVyc2U6IFtdLnJldmVyc2UsXG4gICAgc2hpZnQ6IFtdLnNoaWZ0LFxuICAgIHNvcnQ6IFtdLnNvcnQsXG4gICAgc3BsaWNlOiBbXS5zcGxpY2UsXG4gICAgc2xpY2U6IFtdLnNsaWNlLFxuICAgIGluZGV4T2Y6IFtdLmluZGV4T2YsXG4gICAgZm9yRWFjaDogW10uZm9yRWFjaCxcbiAgICB1bnNoaWZ0OiBbXS51bnNoaWZ0LFxuICAgIGNvbmNhdDogW10uY29uY2F0LFxuICAgIGpvaW46IFtdLmpvaW4sXG4gICAgZXZlcnk6IFtdLmV2ZXJ5LFxuICAgIHNvbWU6IFtdLnNvbWUsXG4gICAgZmlsdGVyOiBbXS5maWx0ZXIsXG4gICAgbWFwOiBbXS5tYXAsXG4gICAgcmVkdWNlOiBbXS5yZWR1Y2UsXG4gICAgcmVkdWNlUmlnaHQ6IFtdLnJlZHVjZVJpZ2h0LFxuICAgIGxlbmd0aDogMFxufTtcblxuZm4uY29uc3RydWN0b3IgPSBqQm9uZTtcblxuZm4uaW5pdC5wcm90b3R5cGUgPSBmbjtcblxuakJvbmUuc2V0SWQgPSBmdW5jdGlvbihlbCkge1xuICAgIHZhciBqaWQgPSBlbC5qaWQ7XG5cbiAgICBpZiAoZWwgPT09IHdpbikge1xuICAgICAgICBqaWQgPSBcIndpbmRvd1wiO1xuICAgIH0gZWxzZSBpZiAoZWwuamlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZWwuamlkID0gamlkID0gKytqQm9uZS5fY2FjaGUuamlkO1xuICAgIH1cblxuICAgIGlmICghakJvbmUuX2NhY2hlLmV2ZW50c1tqaWRdKSB7XG4gICAgICAgIGpCb25lLl9jYWNoZS5ldmVudHNbamlkXSA9IHt9O1xuICAgIH1cbn07XG5cbmpCb25lLmdldERhdGEgPSBmdW5jdGlvbihlbCkge1xuICAgIGVsID0gZWwgaW5zdGFuY2VvZiBqQm9uZSA/IGVsWzBdIDogZWw7XG5cbiAgICB2YXIgamlkID0gZWwgPT09IHdpbiA/IFwid2luZG93XCIgOiBlbC5qaWQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBqaWQ6IGppZCxcbiAgICAgICAgZXZlbnRzOiBqQm9uZS5fY2FjaGUuZXZlbnRzW2ppZF1cbiAgICB9O1xufTtcblxuakJvbmUuaXNFbGVtZW50ID0gZnVuY3Rpb24oZWwpIHtcbiAgICByZXR1cm4gZWwgJiYgZWwgaW5zdGFuY2VvZiBqQm9uZSB8fCBlbCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8IGlzU3RyaW5nKGVsKTtcbn07XG5cbmpCb25lLl9jYWNoZSA9IHtcbiAgICBldmVudHM6IHt9LFxuICAgIGppZDogMFxufTtcblxuZnVuY3Rpb24gaXNBcnJheWxpa2Uob2JqKSB7XG4gICAgdmFyIGxlbmd0aCA9IG9iai5sZW5ndGgsXG4gICAgICAgIHR5cGUgPSB0eXBlb2Ygb2JqO1xuXG4gICAgaWYgKGlzRnVuY3Rpb24odHlwZSkgfHwgb2JqID09PSB3aW4pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChvYmoubm9kZVR5cGUgPT09IDEgJiYgbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBpc0FycmF5KHR5cGUpIHx8IGxlbmd0aCA9PT0gMCB8fFxuICAgICAgICB0eXBlb2YgbGVuZ3RoID09PSBcIm51bWJlclwiICYmIGxlbmd0aCA+IDAgJiYgKGxlbmd0aCAtIDEpIGluIG9iajtcbn1cblxuakJvbmUubWVyZ2UgPSBmdW5jdGlvbihmaXJzdCwgc2Vjb25kKSB7XG4gICAgdmFyIGwgPSBzZWNvbmQubGVuZ3RoLFxuICAgICAgICBpID0gZmlyc3QubGVuZ3RoLFxuICAgICAgICBqID0gMDtcblxuICAgIHdoaWxlIChqIDwgbCkge1xuICAgICAgICBmaXJzdFtpKytdID0gc2Vjb25kW2orK107XG4gICAgfVxuXG4gICAgZmlyc3QubGVuZ3RoID0gaTtcblxuICAgIHJldHVybiBmaXJzdDtcbn07XG5cbmpCb25lLmNvbnRhaW5zID0gZnVuY3Rpb24oY29udGFpbmVyLCBjb250YWluZWQpIHtcbiAgICB2YXIgcmVzdWx0O1xuXG4gICAgY29udGFpbmVyLnJldmVyc2UoKS5zb21lKGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgIGlmIChlbC5jb250YWlucyhjb250YWluZWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0ID0gZWw7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG5qQm9uZS5leHRlbmQgPSBmdW5jdGlvbih0YXJnZXQpIHtcbiAgICB2YXIgaywga2wsIGksIHRnO1xuXG4gICAgc3BsaWNlLmNhbGwoYXJndW1lbnRzLCAxKS5mb3JFYWNoKGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgayA9IGtleXMob2JqZWN0KTtcbiAgICAgICAga2wgPSBrLmxlbmd0aDtcbiAgICAgICAgaSA9IDA7XG4gICAgICAgIHRnID0gdGFyZ2V0OyAvL2NhY2hpbmcgdGFyZ2V0IGZvciBwZXJmIGltcHJvdmVtZW50XG5cbiAgICAgICAgZm9yICg7IGkgPCBrbDsgaSsrKSB7XG4gICAgICAgICAgICB0Z1trW2ldXSA9IG9iamVjdFtrW2ldXTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRhcmdldDtcbn07XG5cbmpCb25lLm1ha2VBcnJheSA9IGZ1bmN0aW9uKGFyciwgcmVzdWx0cykge1xuICAgIHZhciByZXQgPSByZXN1bHRzIHx8IFtdO1xuXG4gICAgaWYgKGFyciAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoaXNBcnJheWxpa2UoYXJyKSkge1xuICAgICAgICAgICAgakJvbmUubWVyZ2UocmV0LCBpc1N0cmluZyhhcnIpID8gW2Fycl0gOiBhcnIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0LnB1c2goYXJyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBCb25lRXZlbnQoZSwgZGF0YSkge1xuICAgIHZhciBrZXksIHNldHRlcjtcblxuICAgIHRoaXMub3JpZ2luYWxFdmVudCA9IGU7XG5cbiAgICBzZXR0ZXIgPSBmdW5jdGlvbihrZXksIGUpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gXCJwcmV2ZW50RGVmYXVsdFwiKSB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBlW2tleV0oKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihlW2tleV0pKSB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZVtrZXldKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpc1trZXldID0gZVtrZXldO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGZvciAoa2V5IGluIGUpIHtcbiAgICAgICAgaWYgKGVba2V5XSB8fCB0eXBlb2YgZVtrZXldID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHNldHRlci5jYWxsKHRoaXMsIGtleSwgZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBqQm9uZS5leHRlbmQodGhpcywgZGF0YSk7XG59XG5cbmpCb25lLkV2ZW50ID0gZnVuY3Rpb24oZXZlbnQsIGRhdGEpIHtcbiAgICB2YXIgbmFtZXNwYWNlLCBldmVudFR5cGU7XG5cbiAgICBpZiAoZXZlbnQudHlwZSAmJiAhZGF0YSkge1xuICAgICAgICBkYXRhID0gZXZlbnQ7XG4gICAgICAgIGV2ZW50ID0gZXZlbnQudHlwZTtcbiAgICB9XG5cbiAgICBuYW1lc3BhY2UgPSBldmVudC5zcGxpdChcIi5cIikuc3BsaWNlKDEpLmpvaW4oXCIuXCIpO1xuICAgIGV2ZW50VHlwZSA9IGV2ZW50LnNwbGl0KFwiLlwiKVswXTtcblxuICAgIGV2ZW50ID0gZG9jLmNyZWF0ZUV2ZW50KFwiRXZlbnRcIik7XG4gICAgZXZlbnQuaW5pdEV2ZW50KGV2ZW50VHlwZSwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgICByZXR1cm4gakJvbmUuZXh0ZW5kKGV2ZW50LCB7XG4gICAgICAgIG5hbWVzcGFjZTogbmFtZXNwYWNlLFxuICAgICAgICBpc0RlZmF1bHRQcmV2ZW50ZWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQ7XG4gICAgICAgIH1cbiAgICB9LCBkYXRhKTtcbn07XG5cbmZuLm9uID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIGkgPSAwLFxuICAgICAgICBjYWxsYmFjaywgdGFyZ2V0LCBuYW1lc3BhY2UsIGZuLCBldmVudHMsIGV2ZW50VHlwZSwgZXhwZWN0ZWRUYXJnZXQsIGFkZExpc3RlbmVyO1xuXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIGNhbGxiYWNrID0gYXJnc1sxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0YXJnZXQgPSBhcmdzWzFdO1xuICAgICAgICBjYWxsYmFjayA9IGFyZ3NbMl07XG4gICAgfVxuXG4gICAgYWRkTGlzdGVuZXIgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICBqQm9uZS5zZXRJZChlbCk7XG4gICAgICAgIGV2ZW50cyA9IGpCb25lLmdldERhdGEoZWwpLmV2ZW50cztcbiAgICAgICAgZXZlbnQuc3BsaXQoXCIgXCIpLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGV2ZW50VHlwZSA9IGV2ZW50LnNwbGl0KFwiLlwiKVswXTtcbiAgICAgICAgICAgIG5hbWVzcGFjZSA9IGV2ZW50LnNwbGl0KFwiLlwiKS5zcGxpY2UoMSkuam9pbihcIi5cIik7XG4gICAgICAgICAgICBldmVudHNbZXZlbnRUeXBlXSA9IGV2ZW50c1tldmVudFR5cGVdIHx8IFtdO1xuXG4gICAgICAgICAgICBmbiA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoZS5uYW1lc3BhY2UgJiYgZS5uYW1lc3BhY2UgIT09IG5hbWVzcGFjZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWRUYXJnZXQgPSBudWxsO1xuICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoZWwsIGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAofmpCb25lKGVsKS5maW5kKHRhcmdldCkuaW5kZXhPZihlLnRhcmdldCkgfHwgKGV4cGVjdGVkVGFyZ2V0ID0gakJvbmUuY29udGFpbnMoakJvbmUoZWwpLmZpbmQodGFyZ2V0KSwgZS50YXJnZXQpKSkge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZFRhcmdldCA9IGV4cGVjdGVkVGFyZ2V0IHx8IGUudGFyZ2V0O1xuICAgICAgICAgICAgICAgICAgICBlID0gbmV3IEJvbmVFdmVudChlLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50VGFyZ2V0OiBleHBlY3RlZFRhcmdldFxuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKGV4cGVjdGVkVGFyZ2V0LCBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBldmVudHNbZXZlbnRUeXBlXS5wdXNoKHtcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IG5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgICBmbjogZm4sXG4gICAgICAgICAgICAgICAgb3JpZ2luZm46IGNhbGxiYWNrXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lciAmJiBlbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgZm4sIGZhbHNlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYWRkTGlzdGVuZXIodGhpc1tpXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mbi5vbmUgPSBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIGNhbGxiYWNrLCB0YXJnZXQsIGFkZExpc3RlbmVyO1xuXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIGNhbGxiYWNrID0gYXJnc1sxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0YXJnZXQgPSBhcmdzWzFdLCBjYWxsYmFjayA9IGFyZ3NbMl07XG4gICAgfVxuXG4gICAgYWRkTGlzdGVuZXIgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICBldmVudC5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgdmFyIGZuID0gZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIGpCb25lKGVsKS5vZmYoZXZlbnQsIGZuKTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKGVsLCBlKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgakJvbmUoZWwpLm9uKGV2ZW50LCBmbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGpCb25lKGVsKS5vbihldmVudCwgdGFyZ2V0LCBmbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGFkZExpc3RlbmVyKHRoaXNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4udHJpZ2dlciA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGV2ZW50cyA9IFtdLFxuICAgICAgICBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIGRpc3BhdGNoRXZlbnRzO1xuXG4gICAgaWYgKCFldmVudCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBpZiAoaXNTdHJpbmcoZXZlbnQpKSB7XG4gICAgICAgIGV2ZW50cyA9IGV2ZW50LnNwbGl0KFwiIFwiKS5tYXAoZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBqQm9uZS5FdmVudChldmVudCk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGV2ZW50ID0gZXZlbnQgaW5zdGFuY2VvZiBFdmVudCA/IGV2ZW50IDogakJvbmUuRXZlbnQoZXZlbnQpO1xuICAgICAgICBldmVudHMgPSBbZXZlbnRdO1xuICAgIH1cblxuICAgIGRpc3BhdGNoRXZlbnRzID0gZnVuY3Rpb24oZWwpIHtcbiAgICAgICAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICghZXZlbnQudHlwZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudCAmJiBlbC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZGlzcGF0Y2hFdmVudHModGhpc1tpXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mbi5vZmYgPSBmdW5jdGlvbihldmVudCwgZm4pIHtcbiAgICB2YXIgaSA9IDAsXG4gICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoLFxuICAgICAgICByZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50cywgZXZlbnRUeXBlLCBpbmRleCwgZWwsIGUpIHtcbiAgICAgICAgICAgIHZhciBjYWxsYmFjaztcblxuICAgICAgICAgICAgLy8gZ2V0IGNhbGxiYWNrXG4gICAgICAgICAgICBpZiAoKGZuICYmIGUub3JpZ2luZm4gPT09IGZuKSB8fCAhZm4pIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGUuZm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChldmVudHNbZXZlbnRUeXBlXVtpbmRleF0uZm4gPT09IGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGNhbGxiYWNrKTtcblxuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBoYW5kbGVyIGZyb20gY2FjaGVcbiAgICAgICAgICAgICAgICBqQm9uZS5fY2FjaGUuZXZlbnRzW2pCb25lLmdldERhdGEoZWwpLmppZF1bZXZlbnRUeXBlXS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBldmVudHMsIG5hbWVzcGFjZSwgcmVtb3ZlTGlzdGVuZXJzLCBldmVudFR5cGU7XG5cbiAgICByZW1vdmVMaXN0ZW5lcnMgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICB2YXIgbCwgZXZlbnRzQnlUeXBlLCBlO1xuXG4gICAgICAgIGV2ZW50cyA9IGpCb25lLmdldERhdGEoZWwpLmV2ZW50cztcblxuICAgICAgICBpZiAoIWV2ZW50cykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBldmVudHNcbiAgICAgICAgaWYgKCFldmVudCAmJiBldmVudHMpIHtcbiAgICAgICAgICAgIHJldHVybiBrZXlzKGV2ZW50cykuZm9yRWFjaChmdW5jdGlvbihldmVudFR5cGUpIHtcbiAgICAgICAgICAgICAgICBldmVudHNCeVR5cGUgPSBldmVudHNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICBsID0gZXZlbnRzQnlUeXBlLmxlbmd0aDtcblxuICAgICAgICAgICAgICAgIHdoaWxlKGwtLSkge1xuICAgICAgICAgICAgICAgICAgICByZW1vdmVMaXN0ZW5lcihldmVudHMsIGV2ZW50VHlwZSwgbCwgZWwsIGV2ZW50c0J5VHlwZVtsXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBldmVudC5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgZXZlbnRUeXBlID0gZXZlbnQuc3BsaXQoXCIuXCIpWzBdO1xuICAgICAgICAgICAgbmFtZXNwYWNlID0gZXZlbnQuc3BsaXQoXCIuXCIpLnNwbGljZSgxKS5qb2luKFwiLlwiKTtcblxuICAgICAgICAgICAgLy8gcmVtb3ZlIG5hbWVkIGV2ZW50c1xuICAgICAgICAgICAgaWYgKGV2ZW50c1tldmVudFR5cGVdKSB7XG4gICAgICAgICAgICAgICAgZXZlbnRzQnlUeXBlID0gZXZlbnRzW2V2ZW50VHlwZV07XG4gICAgICAgICAgICAgICAgbCA9IGV2ZW50c0J5VHlwZS5sZW5ndGg7XG5cbiAgICAgICAgICAgICAgICB3aGlsZShsLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgZSA9IGV2ZW50c0J5VHlwZVtsXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuYW1lc3BhY2UgfHwgKG5hbWVzcGFjZSAmJiBlLm5hbWVzcGFjZSA9PT0gbmFtZXNwYWNlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlTGlzdGVuZXIoZXZlbnRzLCBldmVudFR5cGUsIGwsIGVsLCBlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJlbW92ZSBhbGwgbmFtZXNwYWNlZCBldmVudHNcbiAgICAgICAgICAgIGVsc2UgaWYgKG5hbWVzcGFjZSkge1xuICAgICAgICAgICAgICAgIGtleXMoZXZlbnRzKS5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50VHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBldmVudHNCeVR5cGUgPSBldmVudHNbZXZlbnRUeXBlXTtcbiAgICAgICAgICAgICAgICAgICAgbCA9IGV2ZW50c0J5VHlwZS5sZW5ndGg7XG5cbiAgICAgICAgICAgICAgICAgICAgd2hpbGUobC0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlID0gZXZlbnRzQnlUeXBlW2xdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUubmFtZXNwYWNlLnNwbGl0KFwiLlwiKVswXSA9PT0gbmFtZXNwYWNlLnNwbGl0KFwiLlwiKVswXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50cywgZXZlbnRUeXBlLCBsLCBlbCwgZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVtb3ZlTGlzdGVuZXJzKHRoaXNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4uZmluZCA9IGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgdmFyIHJlc3VsdHMgPSBbXSxcbiAgICAgICAgaSA9IDAsXG4gICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoLFxuICAgICAgICBmaW5kZXIgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24oZWwucXVlcnlTZWxlY3RvckFsbCkpIHtcbiAgICAgICAgICAgICAgICBbXS5mb3JFYWNoLmNhbGwoZWwucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvciksIGZ1bmN0aW9uKGZvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChmb3VuZCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZpbmRlcih0aGlzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gakJvbmUocmVzdWx0cyk7XG59O1xuXG5mbi5nZXQgPSBmdW5jdGlvbihpbmRleCkge1xuICAgIHJldHVybiB0aGlzW2luZGV4XTtcbn07XG5cbmZuLmVxID0gZnVuY3Rpb24oaW5kZXgpIHtcbiAgICByZXR1cm4gakJvbmUodGhpc1tpbmRleF0pO1xufTtcblxuZm4ucGFyZW50ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJlc3VsdHMgPSBbXSxcbiAgICAgICAgcGFyZW50LFxuICAgICAgICBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICghfnJlc3VsdHMuaW5kZXhPZihwYXJlbnQgPSB0aGlzW2ldLnBhcmVudEVsZW1lbnQpICYmIHBhcmVudCkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHBhcmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gakJvbmUocmVzdWx0cyk7XG59O1xuXG5mbi50b0FycmF5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNsaWNlLmNhbGwodGhpcyk7XG59O1xuXG5mbi5pcyA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuXG4gICAgcmV0dXJuIHRoaXMuc29tZShmdW5jdGlvbihlbCkge1xuICAgICAgICByZXR1cm4gZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSBhcmdzWzBdO1xuICAgIH0pO1xufTtcblxuZm4uaGFzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG5cbiAgICByZXR1cm4gdGhpcy5zb21lKGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgIHJldHVybiBlbC5xdWVyeVNlbGVjdG9yQWxsKGFyZ3NbMF0pLmxlbmd0aDtcbiAgICB9KTtcbn07XG5cbmZuLmF0dHIgPSBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGkgPSAwLFxuICAgICAgICBsZW5ndGggPSB0aGlzLmxlbmd0aCxcbiAgICAgICAgc2V0dGVyO1xuXG4gICAgaWYgKGlzU3RyaW5nKGtleSkgJiYgYXJncy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbMF0gJiYgdGhpc1swXS5nZXRBdHRyaWJ1dGUoa2V5KTtcbiAgICB9XG5cbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgc2V0dGVyID0gZnVuY3Rpb24oZWwpIHtcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShrZXksIHZhbHVlKTtcbiAgICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KGtleSkpIHtcbiAgICAgICAgc2V0dGVyID0gZnVuY3Rpb24oZWwpIHtcbiAgICAgICAgICAgIGtleXMoa2V5KS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUobmFtZSwga2V5W25hbWVdKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgc2V0dGVyKHRoaXNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4ucmVtb3ZlQXR0ciA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXNbaV0ucmVtb3ZlQXR0cmlidXRlKGtleSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mbi52YWwgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpc1swXSAmJiB0aGlzWzBdLnZhbHVlO1xuICAgIH1cblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpc1tpXS52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4uY3NzID0gZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIHNldHRlcjtcblxuICAgIC8vIEdldCBhdHRyaWJ1dGVcbiAgICBpZiAoaXNTdHJpbmcoa2V5KSAmJiBhcmdzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gdGhpc1swXSAmJiB3aW4uZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzWzBdKVtrZXldO1xuICAgIH1cblxuICAgIC8vIFNldCBhdHRyaWJ1dGVzXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIHNldHRlciA9IGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgICAgICBlbC5zdHlsZVtrZXldID0gdmFsdWU7XG4gICAgICAgIH07XG4gICAgfSBlbHNlIGlmIChpc09iamVjdChrZXkpKSB7XG4gICAgICAgIHNldHRlciA9IGZ1bmN0aW9uKGVsKSB7XG4gICAgICAgICAgICBrZXlzKGtleSkuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgICAgICAgICAgZWwuc3R5bGVbbmFtZV0gPSBrZXlbbmFtZV07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHNldHRlcih0aGlzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbmZuLmRhdGEgPSBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsIGRhdGEgPSB7fSxcbiAgICAgICAgaSA9IDAsXG4gICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoLFxuICAgICAgICBzZXR0ZXIsXG4gICAgICAgIHNldFZhbHVlID0gZnVuY3Rpb24oZWwsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICBlbC5qZGF0YSA9IGVsLmpkYXRhIHx8IHt9O1xuICAgICAgICAgICAgICAgIGVsLmpkYXRhW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZWwuZGF0YXNldFtrZXldID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGdldFZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gXCJ0cnVlXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09IFwiZmFsc2VcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgLy8gR2V0IGFsbCBkYXRhXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXNbMF0uamRhdGEgJiYgKGRhdGEgPSB0aGlzWzBdLmpkYXRhKTtcblxuICAgICAgICBrZXlzKHRoaXNbMF0uZGF0YXNldCkuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgICAgIGRhdGFba2V5XSA9IGdldFZhbHVlKHRoaXNbMF0uZGF0YXNldFtrZXldKTtcbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIC8vIEdldCBkYXRhIGJ5IG5hbWVcbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgaXNTdHJpbmcoa2V5KSkge1xuICAgICAgICByZXR1cm4gdGhpc1swXSAmJiBnZXRWYWx1ZSh0aGlzWzBdLmRhdGFzZXRba2V5XSB8fCB0aGlzWzBdLmpkYXRhICYmIHRoaXNbMF0uamRhdGFba2V5XSk7XG4gICAgfVxuXG4gICAgLy8gU2V0IGRhdGFcbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgaXNPYmplY3Qoa2V5KSkge1xuICAgICAgICBzZXR0ZXIgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICAgICAga2V5cyhrZXkpLmZvckVhY2goZnVuY3Rpb24obmFtZSkge1xuICAgICAgICAgICAgICAgIHNldFZhbHVlKGVsLCBuYW1lLCBrZXlbbmFtZV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfSBlbHNlIGlmIChhcmdzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICBzZXR0ZXIgPSBmdW5jdGlvbihlbCkge1xuICAgICAgICAgICAgc2V0VmFsdWUoZWwsIGtleSwgdmFsdWUpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgc2V0dGVyKHRoaXNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4ucmVtb3ZlRGF0YSA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIGpkYXRhLCBkYXRhc2V0O1xuXG4gICAgZm9yICg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBqZGF0YSA9IHRoaXNbaV0uamRhdGE7XG4gICAgICAgIGRhdGFzZXQgPSB0aGlzW2ldLmRhdGFzZXQ7XG5cbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgamRhdGEgJiYgamRhdGFba2V5XSAmJiBkZWxldGUgamRhdGFba2V5XTtcbiAgICAgICAgICAgIGRlbGV0ZSBkYXRhc2V0W2tleV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBqZGF0YSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBqZGF0YVtrZXldO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGtleSBpbiBkYXRhc2V0KSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGRhdGFzZXRba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4uaHRtbCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGVsO1xuXG4gICAgLy8gYWRkIEhUTUwgaW50byBlbGVtZW50c1xuICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVtcHR5KCkuYXBwZW5kKHZhbHVlKTtcbiAgICB9XG4gICAgLy8gZ2V0IEhUTUwgZnJvbSBlbGVtZW50XG4gICAgZWxzZSBpZiAoYXJncy5sZW5ndGggPT09IDAgJiYgKGVsID0gdGhpc1swXSkpIHtcbiAgICAgICAgcmV0dXJuIGVsLmlubmVySFRNTDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbmZuLmFwcGVuZCA9IGZ1bmN0aW9uKGFwcGVuZGVkKSB7XG4gICAgdmFyIGkgPSAwLFxuICAgICAgICBsZW5ndGggPSB0aGlzLmxlbmd0aCxcbiAgICAgICAgc2V0dGVyO1xuXG4gICAgLy8gY3JlYXRlIGpCb25lIG9iamVjdCBhbmQgdGhlbiBhcHBlbmRcbiAgICBpZiAoaXNTdHJpbmcoYXBwZW5kZWQpICYmIHJxdWlja0V4cHIuZXhlYyhhcHBlbmRlZCkpIHtcbiAgICAgICAgYXBwZW5kZWQgPSBqQm9uZShhcHBlbmRlZCk7XG4gICAgfVxuICAgIC8vIGNyZWF0ZSB0ZXh0IG5vZGUgZm9yIGluc2VydGluZ1xuICAgIGVsc2UgaWYgKCFpc09iamVjdChhcHBlbmRlZCkpIHtcbiAgICAgICAgYXBwZW5kZWQgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShhcHBlbmRlZCk7XG4gICAgfVxuXG4gICAgYXBwZW5kZWQgPSBhcHBlbmRlZCBpbnN0YW5jZW9mIGpCb25lID8gYXBwZW5kZWQgOiBqQm9uZShhcHBlbmRlZCk7XG5cbiAgICBzZXR0ZXIgPSBmdW5jdGlvbihlbCwgaSkge1xuICAgICAgICBhcHBlbmRlZC5mb3JFYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgICAgIGlmIChpKSB7XG4gICAgICAgICAgICAgICAgZWwuYXBwZW5kQ2hpbGQobm9kZS5jbG9uZU5vZGUoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVsLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgZm9yICg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBzZXR0ZXIodGhpc1tpXSwgaSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mbi5hcHBlbmRUbyA9IGZ1bmN0aW9uKHRvKSB7XG4gICAgakJvbmUodG8pLmFwcGVuZCh0aGlzKTtcblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuZm4uZW1wdHkgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaSA9IDAsXG4gICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoLFxuICAgICAgICBlbDtcblxuICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZWwgPSB0aGlzW2ldO1xuXG4gICAgICAgIHdoaWxlIChlbC5sYXN0Q2hpbGQpIHtcbiAgICAgICAgICAgIGVsLnJlbW92ZUNoaWxkKGVsLmxhc3RDaGlsZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbmZuLnJlbW92ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGgsXG4gICAgICAgIGVsO1xuXG4gICAgLy8gcmVtb3ZlIGFsbCBsaXN0bmVyc1xuICAgIHRoaXMub2ZmKCk7XG5cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGVsID0gdGhpc1tpXTtcblxuICAgICAgICAvLyByZW1vdmUgZGF0YSBhbmQgbm9kZXNcbiAgICAgICAgZGVsZXRlIGVsLmpkYXRhO1xuICAgICAgICBlbC5wYXJlbnROb2RlICYmIGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWwpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuaWYgKHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIgJiYgbW9kdWxlICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuICAgIC8vIEV4cG9zZSBqQm9uZSBhcyBtb2R1bGUuZXhwb3J0cyBpbiBsb2FkZXJzIHRoYXQgaW1wbGVtZW50IHRoZSBOb2RlXG4gICAgLy8gbW9kdWxlIHBhdHRlcm4gKGluY2x1ZGluZyBicm93c2VyaWZ5KS4gRG8gbm90IGNyZWF0ZSB0aGUgZ2xvYmFsLCBzaW5jZVxuICAgIC8vIHRoZSB1c2VyIHdpbGwgYmUgc3RvcmluZyBpdCB0aGVtc2VsdmVzIGxvY2FsbHksIGFuZCBnbG9iYWxzIGFyZSBmcm93bmVkXG4gICAgLy8gdXBvbiBpbiB0aGUgTm9kZSBtb2R1bGUgd29ybGQuXG4gICAgbW9kdWxlLmV4cG9ydHMgPSBqQm9uZTtcbn1cbi8vIFJlZ2lzdGVyIGFzIGEgQU1EIG1vZHVsZVxuZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICBkZWZpbmUoZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBqQm9uZTtcbiAgICB9KTtcblxuICAgIHdpbi5qQm9uZSA9IHdpbi4kID0gakJvbmU7XG59IGVsc2UgaWYgKHR5cGVvZiB3aW4gPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHdpbi5kb2N1bWVudCA9PT0gXCJvYmplY3RcIikge1xuICAgIHdpbi5qQm9uZSA9IHdpbi4kID0gakJvbmU7XG59XG5cbn0od2luZG93KSk7XG4iLCJ2YXIgTW91c2U7XG5cbm1vZHVsZS5leHBvcnRzID0gTW91c2UgPSB7XG4gIHJlbDogZnVuY3Rpb24oZSkge1xuICAgIHZhciBtb3VzZVgsIG1vdXNlWSwgcmVjdCwgdGFyZ2V0O1xuICAgIG1vdXNlWCA9IGUub2Zmc2V0WDtcbiAgICBtb3VzZVkgPSBlLm9mZnNldFk7XG4gICAgaWYgKG1vdXNlWCA9PSBudWxsKSB7XG4gICAgICByZWN0ID0gdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgdGFyZ2V0ID0gZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50O1xuICAgICAgaWYgKG1vdXNlWCA9PSBudWxsKSB7XG4gICAgICAgIG1vdXNlWCA9IGUuY2xpZW50WCAtIHJlY3QubGVmdDtcbiAgICAgICAgbW91c2VZID0gZS5jbGllbnRZIC0gcmVjdC50b3A7XG4gICAgICB9XG4gICAgICBpZiAobW91c2VYID09IG51bGwpIHtcbiAgICAgICAgbW91c2VYID0gZS5wYWdlWCAtIHRhcmdldC5vZmZzZXRMZWZ0O1xuICAgICAgICBtb3VzZVkgPSBlLnBhZ2VZIC0gdGFyZ2V0Lm9mZnNldFRvcDtcbiAgICAgIH1cbiAgICAgIGlmIChtb3VzZVggPT0gbnVsbCkge1xuICAgICAgICBjb25zb2xlLmxvZyhlLCBcIm5vIG1vdXNlIGV2ZW50IGRlZmluZWQuIHlvdXIgYnJvd3NlciBzdWNrc1wiKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW21vdXNlWCwgbW91c2VZXTtcbiAgfSxcbiAgYWJzOiBmdW5jdGlvbihlKSB7XG4gICAgdmFyIG1vdXNlWCwgbW91c2VZO1xuICAgIG1vdXNlWCA9IGUucGFnZVg7XG4gICAgbW91c2VZID0gZS5wYWdlWTtcbiAgICBpZiAobW91c2VYID09IG51bGwpIHtcbiAgICAgIG1vdXNlWCA9IGUubGF5ZXJYO1xuICAgICAgbW91c2VZID0gZS5sYXllclk7XG4gICAgfVxuICAgIGlmIChtb3VzZVggPT0gbnVsbCkge1xuICAgICAgbW91c2VYID0gZS5jbGllbnRYO1xuICAgICAgbW91c2VZID0gZS5jbGllbnRZO1xuICAgIH1cbiAgICBpZiAobW91c2VYID09IG51bGwpIHtcbiAgICAgIG1vdXNlWCA9IGUueDtcbiAgICAgIG1vdXNlWSA9IGUueTtcbiAgICB9XG4gICAgcmV0dXJuIFttb3VzZVgsIG1vdXNlWV07XG4gIH0sXG4gIHdoZWVsRGVsdGE6IGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZGVsdGEsIGRpcjtcbiAgICBkZWx0YSA9IFtlLmRlbHRhWCwgZS5kZWx0YVldO1xuICAgIGlmIChkZWx0YVswXSA9PSBudWxsKSB7XG4gICAgICBkaXIgPSBNYXRoLmZsb29yKGUuZGV0YWlsIC8gMyk7XG4gICAgICBkZWx0YSA9IFswLCBlLm1vek1vdmVtZW50WCAqIGRpcl07XG4gICAgfVxuICAgIHJldHVybiBkZWx0YTtcbiAgfVxufTtcbiIsInZhciB3aW5kb3cgPSByZXF1aXJlKFwiZ2xvYmFsL3dpbmRvd1wiKVxudmFyIG9uY2UgPSByZXF1aXJlKFwib25jZVwiKVxudmFyIHBhcnNlSGVhZGVycyA9IHJlcXVpcmUoJ3BhcnNlLWhlYWRlcnMnKVxuXG52YXIgbWVzc2FnZXMgPSB7XG4gICAgXCIwXCI6IFwiSW50ZXJuYWwgWE1MSHR0cFJlcXVlc3QgRXJyb3JcIixcbiAgICBcIjRcIjogXCI0eHggQ2xpZW50IEVycm9yXCIsXG4gICAgXCI1XCI6IFwiNXh4IFNlcnZlciBFcnJvclwiXG59XG5cbnZhciBYSFIgPSB3aW5kb3cuWE1MSHR0cFJlcXVlc3QgfHwgbm9vcFxudmFyIFhEUiA9IFwid2l0aENyZWRlbnRpYWxzXCIgaW4gKG5ldyBYSFIoKSkgPyBYSFIgOiB3aW5kb3cuWERvbWFpblJlcXVlc3RcblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVYSFJcblxuZnVuY3Rpb24gY3JlYXRlWEhSKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIG9wdGlvbnMgPSB7IHVyaTogb3B0aW9ucyB9XG4gICAgfVxuXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgICBjYWxsYmFjayA9IG9uY2UoY2FsbGJhY2spXG5cbiAgICB2YXIgeGhyID0gb3B0aW9ucy54aHIgfHwgbnVsbFxuXG4gICAgaWYgKCF4aHIpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuY29ycyB8fCBvcHRpb25zLnVzZVhEUikge1xuICAgICAgICAgICAgeGhyID0gbmV3IFhEUigpXG4gICAgICAgIH1lbHNle1xuICAgICAgICAgICAgeGhyID0gbmV3IFhIUigpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgdXJpID0geGhyLnVybCA9IG9wdGlvbnMudXJpIHx8IG9wdGlvbnMudXJsXG4gICAgdmFyIG1ldGhvZCA9IHhoci5tZXRob2QgPSBvcHRpb25zLm1ldGhvZCB8fCBcIkdFVFwiXG4gICAgdmFyIGJvZHkgPSBvcHRpb25zLmJvZHkgfHwgb3B0aW9ucy5kYXRhXG4gICAgdmFyIGhlYWRlcnMgPSB4aHIuaGVhZGVycyA9IG9wdGlvbnMuaGVhZGVycyB8fCB7fVxuICAgIHZhciBzeW5jID0gISFvcHRpb25zLnN5bmNcbiAgICB2YXIgaXNKc29uID0gZmFsc2VcbiAgICB2YXIga2V5XG4gICAgdmFyIGxvYWQgPSBvcHRpb25zLnJlc3BvbnNlID8gbG9hZFJlc3BvbnNlIDogbG9hZFhoclxuXG4gICAgaWYgKFwianNvblwiIGluIG9wdGlvbnMpIHtcbiAgICAgICAgaXNKc29uID0gdHJ1ZVxuICAgICAgICBoZWFkZXJzW1wiQWNjZXB0XCJdID0gXCJhcHBsaWNhdGlvbi9qc29uXCJcbiAgICAgICAgaWYgKG1ldGhvZCAhPT0gXCJHRVRcIiAmJiBtZXRob2QgIT09IFwiSEVBRFwiKSB7XG4gICAgICAgICAgICBoZWFkZXJzW1wiQ29udGVudC1UeXBlXCJdID0gXCJhcHBsaWNhdGlvbi9qc29uXCJcbiAgICAgICAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShvcHRpb25zLmpzb24pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gcmVhZHlzdGF0ZWNoYW5nZVxuICAgIHhoci5vbmxvYWQgPSBsb2FkXG4gICAgeGhyLm9uZXJyb3IgPSBlcnJvclxuICAgIC8vIElFOSBtdXN0IGhhdmUgb25wcm9ncmVzcyBiZSBzZXQgdG8gYSB1bmlxdWUgZnVuY3Rpb24uXG4gICAgeGhyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIElFIG11c3QgZGllXG4gICAgfVxuICAgIC8vIGhhdGUgSUVcbiAgICB4aHIub250aW1lb3V0ID0gbm9vcFxuICAgIHhoci5vcGVuKG1ldGhvZCwgdXJpLCAhc3luYylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICAgIGlmIChvcHRpb25zLndpdGhDcmVkZW50aWFscyB8fCAob3B0aW9ucy5jb3JzICYmIG9wdGlvbnMud2l0aENyZWRlbnRpYWxzICE9PSBmYWxzZSkpIHtcbiAgICAgICAgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWVcbiAgICB9XG5cbiAgICAvLyBDYW5ub3Qgc2V0IHRpbWVvdXQgd2l0aCBzeW5jIHJlcXVlc3RcbiAgICBpZiAoIXN5bmMpIHtcbiAgICAgICAgeGhyLnRpbWVvdXQgPSBcInRpbWVvdXRcIiBpbiBvcHRpb25zID8gb3B0aW9ucy50aW1lb3V0IDogNTAwMFxuICAgIH1cblxuICAgIGlmICh4aHIuc2V0UmVxdWVzdEhlYWRlcikge1xuICAgICAgICBmb3Ioa2V5IGluIGhlYWRlcnMpe1xuICAgICAgICAgICAgaWYoaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKXtcbiAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkhlYWRlcnMgY2Fubm90IGJlIHNldCBvbiBhbiBYRG9tYWluUmVxdWVzdCBvYmplY3RcIilcbiAgICB9XG5cbiAgICBpZiAoXCJyZXNwb25zZVR5cGVcIiBpbiBvcHRpb25zKSB7XG4gICAgICAgIHhoci5yZXNwb25zZVR5cGUgPSBvcHRpb25zLnJlc3BvbnNlVHlwZVxuICAgIH1cbiAgICBcbiAgICBpZiAoXCJiZWZvcmVTZW5kXCIgaW4gb3B0aW9ucyAmJiBcbiAgICAgICAgdHlwZW9mIG9wdGlvbnMuYmVmb3JlU2VuZCA9PT0gXCJmdW5jdGlvblwiXG4gICAgKSB7XG4gICAgICAgIG9wdGlvbnMuYmVmb3JlU2VuZCh4aHIpXG4gICAgfVxuXG4gICAgeGhyLnNlbmQoYm9keSlcblxuICAgIHJldHVybiB4aHJcblxuICAgIGZ1bmN0aW9uIHJlYWR5c3RhdGVjaGFuZ2UoKSB7XG4gICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgbG9hZCgpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRCb2R5KCkge1xuICAgICAgICAvLyBDaHJvbWUgd2l0aCByZXF1ZXN0VHlwZT1ibG9iIHRocm93cyBlcnJvcnMgYXJyb3VuZCB3aGVuIGV2ZW4gdGVzdGluZyBhY2Nlc3MgdG8gcmVzcG9uc2VUZXh0XG4gICAgICAgIHZhciBib2R5ID0gbnVsbFxuXG4gICAgICAgIGlmICh4aHIucmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGJvZHkgPSB4aHIucmVzcG9uc2VcbiAgICAgICAgfSBlbHNlIGlmICh4aHIucmVzcG9uc2VUeXBlID09PSAndGV4dCcgfHwgIXhoci5yZXNwb25zZVR5cGUpIHtcbiAgICAgICAgICAgIGJvZHkgPSB4aHIucmVzcG9uc2VUZXh0IHx8IHhoci5yZXNwb25zZVhNTFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzSnNvbikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBib2R5ID0gSlNPTi5wYXJzZShib2R5KVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBib2R5XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U3RhdHVzQ29kZSgpIHtcbiAgICAgICAgcmV0dXJuIHhoci5zdGF0dXMgPT09IDEyMjMgPyAyMDQgOiB4aHIuc3RhdHVzXG4gICAgfVxuXG4gICAgLy8gaWYgd2UncmUgZ2V0dGluZyBhIG5vbmUtb2sgc3RhdHVzQ29kZSwgYnVpbGQgJiByZXR1cm4gYW4gZXJyb3JcbiAgICBmdW5jdGlvbiBlcnJvckZyb21TdGF0dXNDb2RlKHN0YXR1cykge1xuICAgICAgICB2YXIgZXJyb3IgPSBudWxsXG4gICAgICAgIGlmIChzdGF0dXMgPT09IDAgfHwgKHN0YXR1cyA+PSA0MDAgJiYgc3RhdHVzIDwgNjAwKSkge1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSAodHlwZW9mIGJvZHkgPT09IFwic3RyaW5nXCIgPyBib2R5IDogZmFsc2UpIHx8XG4gICAgICAgICAgICAgICAgbWVzc2FnZXNbU3RyaW5nKHN0YXR1cykuY2hhckF0KDApXVxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IobWVzc2FnZSlcbiAgICAgICAgICAgIGVycm9yLnN0YXR1c0NvZGUgPSBzdGF0dXNcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvclxuICAgIH1cblxuICAgIC8vIHdpbGwgbG9hZCB0aGUgZGF0YSAmIHByb2Nlc3MgdGhlIHJlc3BvbnNlIGluIGEgc3BlY2lhbCByZXNwb25zZSBvYmplY3RcbiAgICBmdW5jdGlvbiBsb2FkUmVzcG9uc2UoKSB7XG4gICAgICAgIHZhciBzdGF0dXMgPSBnZXRTdGF0dXNDb2RlKClcbiAgICAgICAgdmFyIGVycm9yID0gZXJyb3JGcm9tU3RhdHVzQ29kZShzdGF0dXMpXG4gICAgICAgIHZhciByZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGJvZHk6IGdldEJvZHkoKSxcbiAgICAgICAgICAgIHN0YXR1c0NvZGU6IHN0YXR1cyxcbiAgICAgICAgICAgIHN0YXR1c1RleHQ6IHhoci5zdGF0dXNUZXh0LFxuICAgICAgICAgICAgcmF3OiB4aHJcbiAgICAgICAgfVxuICAgICAgICBpZih4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKXsgLy9yZW1lbWJlciB4aHIgY2FuIGluIGZhY3QgYmUgWERSIGZvciBDT1JTIGluIElFXG4gICAgICAgICAgICByZXNwb25zZS5oZWFkZXJzID0gcGFyc2VIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc3BvbnNlLmhlYWRlcnMgPSB7fVxuICAgICAgICB9XG5cbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3BvbnNlLCByZXNwb25zZS5ib2R5KVxuICAgIH1cblxuICAgIC8vIHdpbGwgbG9hZCB0aGUgZGF0YSBhbmQgYWRkIHNvbWUgcmVzcG9uc2UgcHJvcGVydGllcyB0byB0aGUgc291cmNlIHhoclxuICAgIC8vIGFuZCB0aGVuIHJlc3BvbmQgd2l0aCB0aGF0XG4gICAgZnVuY3Rpb24gbG9hZFhocigpIHtcbiAgICAgICAgdmFyIHN0YXR1cyA9IGdldFN0YXR1c0NvZGUoKVxuICAgICAgICB2YXIgZXJyb3IgPSBlcnJvckZyb21TdGF0dXNDb2RlKHN0YXR1cylcblxuICAgICAgICB4aHIuc3RhdHVzID0geGhyLnN0YXR1c0NvZGUgPSBzdGF0dXNcbiAgICAgICAgeGhyLmJvZHkgPSBnZXRCb2R5KClcbiAgICAgICAgeGhyLmhlYWRlcnMgPSBwYXJzZUhlYWRlcnMoeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKVxuXG4gICAgICAgIGNhbGxiYWNrKGVycm9yLCB4aHIsIHhoci5ib2R5KVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGVycm9yKGV2dCkge1xuICAgICAgICBjYWxsYmFjayhldnQsIHhocilcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gbm9vcCgpIHt9XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gd2luZG93O1xufSBlbHNlIGlmICh0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBnbG9iYWw7XG59IGVsc2UgaWYgKHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiKXtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHNlbGY7XG59IGVsc2Uge1xuICAgIG1vZHVsZS5leHBvcnRzID0ge307XG59XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KSIsIm1vZHVsZS5leHBvcnRzID0gb25jZVxuXG5vbmNlLnByb3RvID0gb25jZShmdW5jdGlvbiAoKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGdW5jdGlvbi5wcm90b3R5cGUsICdvbmNlJywge1xuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gb25jZSh0aGlzKVxuICAgIH0sXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pXG59KVxuXG5mdW5jdGlvbiBvbmNlIChmbikge1xuICB2YXIgY2FsbGVkID0gZmFsc2VcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoY2FsbGVkKSByZXR1cm5cbiAgICBjYWxsZWQgPSB0cnVlXG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgfVxufVxuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCdpcy1mdW5jdGlvbicpXG5cbm1vZHVsZS5leHBvcnRzID0gZm9yRWFjaFxuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5XG5cbmZ1bmN0aW9uIGZvckVhY2gobGlzdCwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzRnVuY3Rpb24oaXRlcmF0b3IpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2l0ZXJhdG9yIG11c3QgYmUgYSBmdW5jdGlvbicpXG4gICAgfVxuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSB7XG4gICAgICAgIGNvbnRleHQgPSB0aGlzXG4gICAgfVxuICAgIFxuICAgIGlmICh0b1N0cmluZy5jYWxsKGxpc3QpID09PSAnW29iamVjdCBBcnJheV0nKVxuICAgICAgICBmb3JFYWNoQXJyYXkobGlzdCwgaXRlcmF0b3IsIGNvbnRleHQpXG4gICAgZWxzZSBpZiAodHlwZW9mIGxpc3QgPT09ICdzdHJpbmcnKVxuICAgICAgICBmb3JFYWNoU3RyaW5nKGxpc3QsIGl0ZXJhdG9yLCBjb250ZXh0KVxuICAgIGVsc2VcbiAgICAgICAgZm9yRWFjaE9iamVjdChsaXN0LCBpdGVyYXRvciwgY29udGV4dClcbn1cblxuZnVuY3Rpb24gZm9yRWFjaEFycmF5KGFycmF5LCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhcnJheS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChhcnJheSwgaSkpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgYXJyYXlbaV0sIGksIGFycmF5KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmb3JFYWNoU3RyaW5nKHN0cmluZywgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gc3RyaW5nLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIC8vIG5vIHN1Y2ggdGhpbmcgYXMgYSBzcGFyc2Ugc3RyaW5nLlxuICAgICAgICBpdGVyYXRvci5jYWxsKGNvbnRleHQsIHN0cmluZy5jaGFyQXQoaSksIGksIHN0cmluZylcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGZvckVhY2hPYmplY3Qob2JqZWN0LCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGZvciAodmFyIGsgaW4gb2JqZWN0KSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgaykpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqZWN0W2tdLCBrLCBvYmplY3QpXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGlzRnVuY3Rpb25cblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uIChmbikge1xuICB2YXIgc3RyaW5nID0gdG9TdHJpbmcuY2FsbChmbilcbiAgcmV0dXJuIHN0cmluZyA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJyB8fFxuICAgICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicgJiYgc3RyaW5nICE9PSAnW29iamVjdCBSZWdFeHBdJykgfHxcbiAgICAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgLy8gSUU4IGFuZCBiZWxvd1xuICAgICAoZm4gPT09IHdpbmRvdy5zZXRUaW1lb3V0IHx8XG4gICAgICBmbiA9PT0gd2luZG93LmFsZXJ0IHx8XG4gICAgICBmbiA9PT0gd2luZG93LmNvbmZpcm0gfHxcbiAgICAgIGZuID09PSB3aW5kb3cucHJvbXB0KSlcbn07XG4iLCJcbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHRyaW07XG5cbmZ1bmN0aW9uIHRyaW0oc3RyKXtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzKnxcXHMqJC9nLCAnJyk7XG59XG5cbmV4cG9ydHMubGVmdCA9IGZ1bmN0aW9uKHN0cil7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyovLCAnJyk7XG59O1xuXG5leHBvcnRzLnJpZ2h0ID0gZnVuY3Rpb24oc3RyKXtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cXHMqJC8sICcnKTtcbn07XG4iLCJ2YXIgdHJpbSA9IHJlcXVpcmUoJ3RyaW0nKVxuICAsIGZvckVhY2ggPSByZXF1aXJlKCdmb3ItZWFjaCcpXG4gICwgaXNBcnJheSA9IGZ1bmN0aW9uKGFyZykge1xuICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaGVhZGVycykge1xuICBpZiAoIWhlYWRlcnMpXG4gICAgcmV0dXJuIHt9XG5cbiAgdmFyIHJlc3VsdCA9IHt9XG5cbiAgZm9yRWFjaChcbiAgICAgIHRyaW0oaGVhZGVycykuc3BsaXQoJ1xcbicpXG4gICAgLCBmdW5jdGlvbiAocm93KSB7XG4gICAgICAgIHZhciBpbmRleCA9IHJvdy5pbmRleE9mKCc6JylcbiAgICAgICAgICAsIGtleSA9IHRyaW0ocm93LnNsaWNlKDAsIGluZGV4KSkudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICwgdmFsdWUgPSB0cmltKHJvdy5zbGljZShpbmRleCArIDEpKVxuXG4gICAgICAgIGlmICh0eXBlb2YocmVzdWx0W2tleV0pID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHJlc3VsdFtrZXldID0gdmFsdWVcbiAgICAgICAgfSBlbHNlIGlmIChpc0FycmF5KHJlc3VsdFtrZXldKSkge1xuICAgICAgICAgIHJlc3VsdFtrZXldLnB1c2godmFsdWUpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0W2tleV0gPSBbIHJlc3VsdFtrZXldLCB2YWx1ZSBdXG4gICAgICAgIH1cbiAgICAgIH1cbiAgKVxuXG4gIHJldHVybiByZXN1bHRcbn0iLCIvLyAgICAgVW5kZXJzY29yZS5qcyAxLjcuMFxuLy8gICAgIGh0dHA6Ly91bmRlcnNjb3JlanMub3JnXG4vLyAgICAgKGMpIDIwMDktMjAxNCBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9yc1xuLy8gICAgIFVuZGVyc2NvcmUgbWF5IGJlIGZyZWVseSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXG5cbihmdW5jdGlvbigpIHtcblxuICAvLyBCYXNlbGluZSBzZXR1cFxuICAvLyAtLS0tLS0tLS0tLS0tLVxuXG4gIC8vIEVzdGFibGlzaCB0aGUgcm9vdCBvYmplY3QsIGB3aW5kb3dgIGluIHRoZSBicm93c2VyLCBvciBgZXhwb3J0c2Agb24gdGhlIHNlcnZlci5cbiAgdmFyIHJvb3QgPSB0aGlzO1xuXG4gIC8vIFNhdmUgdGhlIHByZXZpb3VzIHZhbHVlIG9mIHRoZSBgX2AgdmFyaWFibGUuXG4gIHZhciBwcmV2aW91c1VuZGVyc2NvcmUgPSByb290Ll87XG5cbiAgLy8gU2F2ZSBieXRlcyBpbiB0aGUgbWluaWZpZWQgKGJ1dCBub3QgZ3ppcHBlZCkgdmVyc2lvbjpcbiAgdmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGUsIE9ialByb3RvID0gT2JqZWN0LnByb3RvdHlwZSwgRnVuY1Byb3RvID0gRnVuY3Rpb24ucHJvdG90eXBlO1xuXG4gIC8vIENyZWF0ZSBxdWljayByZWZlcmVuY2UgdmFyaWFibGVzIGZvciBzcGVlZCBhY2Nlc3MgdG8gY29yZSBwcm90b3R5cGVzLlxuICB2YXJcbiAgICBwdXNoICAgICAgICAgICAgID0gQXJyYXlQcm90by5wdXNoLFxuICAgIHNsaWNlICAgICAgICAgICAgPSBBcnJheVByb3RvLnNsaWNlLFxuICAgIGNvbmNhdCAgICAgICAgICAgPSBBcnJheVByb3RvLmNvbmNhdCxcbiAgICB0b1N0cmluZyAgICAgICAgID0gT2JqUHJvdG8udG9TdHJpbmcsXG4gICAgaGFzT3duUHJvcGVydHkgICA9IE9ialByb3RvLmhhc093blByb3BlcnR5O1xuXG4gIC8vIEFsbCAqKkVDTUFTY3JpcHQgNSoqIG5hdGl2ZSBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbnMgdGhhdCB3ZSBob3BlIHRvIHVzZVxuICAvLyBhcmUgZGVjbGFyZWQgaGVyZS5cbiAgdmFyXG4gICAgbmF0aXZlSXNBcnJheSAgICAgID0gQXJyYXkuaXNBcnJheSxcbiAgICBuYXRpdmVLZXlzICAgICAgICAgPSBPYmplY3Qua2V5cyxcbiAgICBuYXRpdmVCaW5kICAgICAgICAgPSBGdW5jUHJvdG8uYmluZDtcblxuICAvLyBDcmVhdGUgYSBzYWZlIHJlZmVyZW5jZSB0byB0aGUgVW5kZXJzY29yZSBvYmplY3QgZm9yIHVzZSBiZWxvdy5cbiAgdmFyIF8gPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAob2JqIGluc3RhbmNlb2YgXykgcmV0dXJuIG9iajtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgXykpIHJldHVybiBuZXcgXyhvYmopO1xuICAgIHRoaXMuX3dyYXBwZWQgPSBvYmo7XG4gIH07XG5cbiAgLy8gRXhwb3J0IHRoZSBVbmRlcnNjb3JlIG9iamVjdCBmb3IgKipOb2RlLmpzKiosIHdpdGhcbiAgLy8gYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgZm9yIHRoZSBvbGQgYHJlcXVpcmUoKWAgQVBJLiBJZiB3ZSdyZSBpblxuICAvLyB0aGUgYnJvd3NlciwgYWRkIGBfYCBhcyBhIGdsb2JhbCBvYmplY3QuXG4gIGlmICh0eXBlb2YgZXhwb3J0cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICAgIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IF87XG4gICAgfVxuICAgIGV4cG9ydHMuXyA9IF87XG4gIH0gZWxzZSB7XG4gICAgcm9vdC5fID0gXztcbiAgfVxuXG4gIC8vIEN1cnJlbnQgdmVyc2lvbi5cbiAgXy5WRVJTSU9OID0gJzEuNy4wJztcblxuICAvLyBJbnRlcm5hbCBmdW5jdGlvbiB0aGF0IHJldHVybnMgYW4gZWZmaWNpZW50IChmb3IgY3VycmVudCBlbmdpbmVzKSB2ZXJzaW9uXG4gIC8vIG9mIHRoZSBwYXNzZWQtaW4gY2FsbGJhY2ssIHRvIGJlIHJlcGVhdGVkbHkgYXBwbGllZCBpbiBvdGhlciBVbmRlcnNjb3JlXG4gIC8vIGZ1bmN0aW9ucy5cbiAgdmFyIGNyZWF0ZUNhbGxiYWNrID0gZnVuY3Rpb24oZnVuYywgY29udGV4dCwgYXJnQ291bnQpIHtcbiAgICBpZiAoY29udGV4dCA9PT0gdm9pZCAwKSByZXR1cm4gZnVuYztcbiAgICBzd2l0Y2ggKGFyZ0NvdW50ID09IG51bGwgPyAzIDogYXJnQ291bnQpIHtcbiAgICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgdmFsdWUpO1xuICAgICAgfTtcbiAgICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgICByZXR1cm4gZnVuYy5jYWxsKGNvbnRleHQsIHZhbHVlLCBvdGhlcik7XG4gICAgICB9O1xuICAgICAgY2FzZSAzOiByZXR1cm4gZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICAgIH07XG4gICAgICBjYXNlIDQ6IHJldHVybiBmdW5jdGlvbihhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZnVuYy5hcHBseShjb250ZXh0LCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH07XG5cbiAgLy8gQSBtb3N0bHktaW50ZXJuYWwgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgY2FsbGJhY2tzIHRoYXQgY2FuIGJlIGFwcGxpZWRcbiAgLy8gdG8gZWFjaCBlbGVtZW50IGluIGEgY29sbGVjdGlvbiwgcmV0dXJuaW5nIHRoZSBkZXNpcmVkIHJlc3VsdCDigJQgZWl0aGVyXG4gIC8vIGlkZW50aXR5LCBhbiBhcmJpdHJhcnkgY2FsbGJhY2ssIGEgcHJvcGVydHkgbWF0Y2hlciwgb3IgYSBwcm9wZXJ0eSBhY2Nlc3Nvci5cbiAgXy5pdGVyYXRlZSA9IGZ1bmN0aW9uKHZhbHVlLCBjb250ZXh0LCBhcmdDb3VudCkge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSByZXR1cm4gXy5pZGVudGl0eTtcbiAgICBpZiAoXy5pc0Z1bmN0aW9uKHZhbHVlKSkgcmV0dXJuIGNyZWF0ZUNhbGxiYWNrKHZhbHVlLCBjb250ZXh0LCBhcmdDb3VudCk7XG4gICAgaWYgKF8uaXNPYmplY3QodmFsdWUpKSByZXR1cm4gXy5tYXRjaGVzKHZhbHVlKTtcbiAgICByZXR1cm4gXy5wcm9wZXJ0eSh2YWx1ZSk7XG4gIH07XG5cbiAgLy8gQ29sbGVjdGlvbiBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBUaGUgY29ybmVyc3RvbmUsIGFuIGBlYWNoYCBpbXBsZW1lbnRhdGlvbiwgYWthIGBmb3JFYWNoYC5cbiAgLy8gSGFuZGxlcyByYXcgb2JqZWN0cyBpbiBhZGRpdGlvbiB0byBhcnJheS1saWtlcy4gVHJlYXRzIGFsbFxuICAvLyBzcGFyc2UgYXJyYXktbGlrZXMgYXMgaWYgdGhleSB3ZXJlIGRlbnNlLlxuICBfLmVhY2ggPSBfLmZvckVhY2ggPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gb2JqO1xuICAgIGl0ZXJhdGVlID0gY3JlYXRlQ2FsbGJhY2soaXRlcmF0ZWUsIGNvbnRleHQpO1xuICAgIHZhciBpLCBsZW5ndGggPSBvYmoubGVuZ3RoO1xuICAgIGlmIChsZW5ndGggPT09ICtsZW5ndGgpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBpdGVyYXRlZShvYmpbaV0sIGksIG9iaik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBrZXlzID0gXy5rZXlzKG9iaik7XG4gICAgICBmb3IgKGkgPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGl0ZXJhdGVlKG9ialtrZXlzW2ldXSwga2V5c1tpXSwgb2JqKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIHJlc3VsdHMgb2YgYXBwbHlpbmcgdGhlIGl0ZXJhdGVlIHRvIGVhY2ggZWxlbWVudC5cbiAgXy5tYXAgPSBfLmNvbGxlY3QgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gW107XG4gICAgaXRlcmF0ZWUgPSBfLml0ZXJhdGVlKGl0ZXJhdGVlLCBjb250ZXh0KTtcbiAgICB2YXIga2V5cyA9IG9iai5sZW5ndGggIT09ICtvYmoubGVuZ3RoICYmIF8ua2V5cyhvYmopLFxuICAgICAgICBsZW5ndGggPSAoa2V5cyB8fCBvYmopLmxlbmd0aCxcbiAgICAgICAgcmVzdWx0cyA9IEFycmF5KGxlbmd0aCksXG4gICAgICAgIGN1cnJlbnRLZXk7XG4gICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgY3VycmVudEtleSA9IGtleXMgPyBrZXlzW2luZGV4XSA6IGluZGV4O1xuICAgICAgcmVzdWx0c1tpbmRleF0gPSBpdGVyYXRlZShvYmpbY3VycmVudEtleV0sIGN1cnJlbnRLZXksIG9iaik7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9O1xuXG4gIHZhciByZWR1Y2VFcnJvciA9ICdSZWR1Y2Ugb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJztcblxuICAvLyAqKlJlZHVjZSoqIGJ1aWxkcyB1cCBhIHNpbmdsZSByZXN1bHQgZnJvbSBhIGxpc3Qgb2YgdmFsdWVzLCBha2EgYGluamVjdGAsXG4gIC8vIG9yIGBmb2xkbGAuXG4gIF8ucmVkdWNlID0gXy5mb2xkbCA9IF8uaW5qZWN0ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgbWVtbywgY29udGV4dCkge1xuICAgIGlmIChvYmogPT0gbnVsbCkgb2JqID0gW107XG4gICAgaXRlcmF0ZWUgPSBjcmVhdGVDYWxsYmFjayhpdGVyYXRlZSwgY29udGV4dCwgNCk7XG4gICAgdmFyIGtleXMgPSBvYmoubGVuZ3RoICE9PSArb2JqLmxlbmd0aCAmJiBfLmtleXMob2JqKSxcbiAgICAgICAgbGVuZ3RoID0gKGtleXMgfHwgb2JqKS5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gMCwgY3VycmVudEtleTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIHtcbiAgICAgIGlmICghbGVuZ3RoKSB0aHJvdyBuZXcgVHlwZUVycm9yKHJlZHVjZUVycm9yKTtcbiAgICAgIG1lbW8gPSBvYmpba2V5cyA/IGtleXNbaW5kZXgrK10gOiBpbmRleCsrXTtcbiAgICB9XG4gICAgZm9yICg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjdXJyZW50S2V5ID0ga2V5cyA/IGtleXNbaW5kZXhdIDogaW5kZXg7XG4gICAgICBtZW1vID0gaXRlcmF0ZWUobWVtbywgb2JqW2N1cnJlbnRLZXldLCBjdXJyZW50S2V5LCBvYmopO1xuICAgIH1cbiAgICByZXR1cm4gbWVtbztcbiAgfTtcblxuICAvLyBUaGUgcmlnaHQtYXNzb2NpYXRpdmUgdmVyc2lvbiBvZiByZWR1Y2UsIGFsc28ga25vd24gYXMgYGZvbGRyYC5cbiAgXy5yZWR1Y2VSaWdodCA9IF8uZm9sZHIgPSBmdW5jdGlvbihvYmosIGl0ZXJhdGVlLCBtZW1vLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSBvYmogPSBbXTtcbiAgICBpdGVyYXRlZSA9IGNyZWF0ZUNhbGxiYWNrKGl0ZXJhdGVlLCBjb250ZXh0LCA0KTtcbiAgICB2YXIga2V5cyA9IG9iai5sZW5ndGggIT09ICsgb2JqLmxlbmd0aCAmJiBfLmtleXMob2JqKSxcbiAgICAgICAgaW5kZXggPSAoa2V5cyB8fCBvYmopLmxlbmd0aCxcbiAgICAgICAgY3VycmVudEtleTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDMpIHtcbiAgICAgIGlmICghaW5kZXgpIHRocm93IG5ldyBUeXBlRXJyb3IocmVkdWNlRXJyb3IpO1xuICAgICAgbWVtbyA9IG9ialtrZXlzID8ga2V5c1stLWluZGV4XSA6IC0taW5kZXhdO1xuICAgIH1cbiAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgY3VycmVudEtleSA9IGtleXMgPyBrZXlzW2luZGV4XSA6IGluZGV4O1xuICAgICAgbWVtbyA9IGl0ZXJhdGVlKG1lbW8sIG9ialtjdXJyZW50S2V5XSwgY3VycmVudEtleSwgb2JqKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lbW87XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBmaXJzdCB2YWx1ZSB3aGljaCBwYXNzZXMgYSB0cnV0aCB0ZXN0LiBBbGlhc2VkIGFzIGBkZXRlY3RgLlxuICBfLmZpbmQgPSBfLmRldGVjdCA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdDtcbiAgICBwcmVkaWNhdGUgPSBfLml0ZXJhdGVlKHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgXy5zb21lKG9iaiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBsaXN0KSB7XG4gICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgbGlzdCkpIHtcbiAgICAgICAgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gUmV0dXJuIGFsbCB0aGUgZWxlbWVudHMgdGhhdCBwYXNzIGEgdHJ1dGggdGVzdC5cbiAgLy8gQWxpYXNlZCBhcyBgc2VsZWN0YC5cbiAgXy5maWx0ZXIgPSBfLnNlbGVjdCA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiByZXN1bHRzO1xuICAgIHByZWRpY2F0ZSA9IF8uaXRlcmF0ZWUocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICBfLmVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBsaXN0KSkgcmVzdWx0cy5wdXNoKHZhbHVlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICAvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyBmb3Igd2hpY2ggYSB0cnV0aCB0ZXN0IGZhaWxzLlxuICBfLnJlamVjdCA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIF8uZmlsdGVyKG9iaiwgXy5uZWdhdGUoXy5pdGVyYXRlZShwcmVkaWNhdGUpKSwgY29udGV4dCk7XG4gIH07XG5cbiAgLy8gRGV0ZXJtaW5lIHdoZXRoZXIgYWxsIG9mIHRoZSBlbGVtZW50cyBtYXRjaCBhIHRydXRoIHRlc3QuXG4gIC8vIEFsaWFzZWQgYXMgYGFsbGAuXG4gIF8uZXZlcnkgPSBfLmFsbCA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgICBwcmVkaWNhdGUgPSBfLml0ZXJhdGVlKHByZWRpY2F0ZSwgY29udGV4dCk7XG4gICAgdmFyIGtleXMgPSBvYmoubGVuZ3RoICE9PSArb2JqLmxlbmd0aCAmJiBfLmtleXMob2JqKSxcbiAgICAgICAgbGVuZ3RoID0gKGtleXMgfHwgb2JqKS5sZW5ndGgsXG4gICAgICAgIGluZGV4LCBjdXJyZW50S2V5O1xuICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgY3VycmVudEtleSA9IGtleXMgPyBrZXlzW2luZGV4XSA6IGluZGV4O1xuICAgICAgaWYgKCFwcmVkaWNhdGUob2JqW2N1cnJlbnRLZXldLCBjdXJyZW50S2V5LCBvYmopKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8vIERldGVybWluZSBpZiBhdCBsZWFzdCBvbmUgZWxlbWVudCBpbiB0aGUgb2JqZWN0IG1hdGNoZXMgYSB0cnV0aCB0ZXN0LlxuICAvLyBBbGlhc2VkIGFzIGBhbnlgLlxuICBfLnNvbWUgPSBfLmFueSA9IGZ1bmN0aW9uKG9iaiwgcHJlZGljYXRlLCBjb250ZXh0KSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgcHJlZGljYXRlID0gXy5pdGVyYXRlZShwcmVkaWNhdGUsIGNvbnRleHQpO1xuICAgIHZhciBrZXlzID0gb2JqLmxlbmd0aCAhPT0gK29iai5sZW5ndGggJiYgXy5rZXlzKG9iaiksXG4gICAgICAgIGxlbmd0aCA9IChrZXlzIHx8IG9iaikubGVuZ3RoLFxuICAgICAgICBpbmRleCwgY3VycmVudEtleTtcbiAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGN1cnJlbnRLZXkgPSBrZXlzID8ga2V5c1tpbmRleF0gOiBpbmRleDtcbiAgICAgIGlmIChwcmVkaWNhdGUob2JqW2N1cnJlbnRLZXldLCBjdXJyZW50S2V5LCBvYmopKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuXG4gIC8vIERldGVybWluZSBpZiB0aGUgYXJyYXkgb3Igb2JqZWN0IGNvbnRhaW5zIGEgZ2l2ZW4gdmFsdWUgKHVzaW5nIGA9PT1gKS5cbiAgLy8gQWxpYXNlZCBhcyBgaW5jbHVkZWAuXG4gIF8uY29udGFpbnMgPSBfLmluY2x1ZGUgPSBmdW5jdGlvbihvYmosIHRhcmdldCkge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChvYmoubGVuZ3RoICE9PSArb2JqLmxlbmd0aCkgb2JqID0gXy52YWx1ZXMob2JqKTtcbiAgICByZXR1cm4gXy5pbmRleE9mKG9iaiwgdGFyZ2V0KSA+PSAwO1xuICB9O1xuXG4gIC8vIEludm9rZSBhIG1ldGhvZCAod2l0aCBhcmd1bWVudHMpIG9uIGV2ZXJ5IGl0ZW0gaW4gYSBjb2xsZWN0aW9uLlxuICBfLmludm9rZSA9IGZ1bmN0aW9uKG9iaiwgbWV0aG9kKSB7XG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGlzRnVuYyA9IF8uaXNGdW5jdGlvbihtZXRob2QpO1xuICAgIHJldHVybiBfLm1hcChvYmosIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gKGlzRnVuYyA/IG1ldGhvZCA6IHZhbHVlW21ldGhvZF0pLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBDb252ZW5pZW5jZSB2ZXJzaW9uIG9mIGEgY29tbW9uIHVzZSBjYXNlIG9mIGBtYXBgOiBmZXRjaGluZyBhIHByb3BlcnR5LlxuICBfLnBsdWNrID0gZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICByZXR1cm4gXy5tYXAob2JqLCBfLnByb3BlcnR5KGtleSkpO1xuICB9O1xuXG4gIC8vIENvbnZlbmllbmNlIHZlcnNpb24gb2YgYSBjb21tb24gdXNlIGNhc2Ugb2YgYGZpbHRlcmA6IHNlbGVjdGluZyBvbmx5IG9iamVjdHNcbiAgLy8gY29udGFpbmluZyBzcGVjaWZpYyBga2V5OnZhbHVlYCBwYWlycy5cbiAgXy53aGVyZSA9IGZ1bmN0aW9uKG9iaiwgYXR0cnMpIHtcbiAgICByZXR1cm4gXy5maWx0ZXIob2JqLCBfLm1hdGNoZXMoYXR0cnMpKTtcbiAgfTtcblxuICAvLyBDb252ZW5pZW5jZSB2ZXJzaW9uIG9mIGEgY29tbW9uIHVzZSBjYXNlIG9mIGBmaW5kYDogZ2V0dGluZyB0aGUgZmlyc3Qgb2JqZWN0XG4gIC8vIGNvbnRhaW5pbmcgc3BlY2lmaWMgYGtleTp2YWx1ZWAgcGFpcnMuXG4gIF8uZmluZFdoZXJlID0gZnVuY3Rpb24ob2JqLCBhdHRycykge1xuICAgIHJldHVybiBfLmZpbmQob2JqLCBfLm1hdGNoZXMoYXR0cnMpKTtcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIG1heGltdW0gZWxlbWVudCAob3IgZWxlbWVudC1iYXNlZCBjb21wdXRhdGlvbikuXG4gIF8ubWF4ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgIHZhciByZXN1bHQgPSAtSW5maW5pdHksIGxhc3RDb21wdXRlZCA9IC1JbmZpbml0eSxcbiAgICAgICAgdmFsdWUsIGNvbXB1dGVkO1xuICAgIGlmIChpdGVyYXRlZSA9PSBudWxsICYmIG9iaiAhPSBudWxsKSB7XG4gICAgICBvYmogPSBvYmoubGVuZ3RoID09PSArb2JqLmxlbmd0aCA/IG9iaiA6IF8udmFsdWVzKG9iaik7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gb2JqLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhbHVlID0gb2JqW2ldO1xuICAgICAgICBpZiAodmFsdWUgPiByZXN1bHQpIHtcbiAgICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpdGVyYXRlZSA9IF8uaXRlcmF0ZWUoaXRlcmF0ZWUsIGNvbnRleHQpO1xuICAgICAgXy5lYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBsaXN0KSB7XG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUodmFsdWUsIGluZGV4LCBsaXN0KTtcbiAgICAgICAgaWYgKGNvbXB1dGVkID4gbGFzdENvbXB1dGVkIHx8IGNvbXB1dGVkID09PSAtSW5maW5pdHkgJiYgcmVzdWx0ID09PSAtSW5maW5pdHkpIHtcbiAgICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBsYXN0Q29tcHV0ZWQgPSBjb21wdXRlZDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBtaW5pbXVtIGVsZW1lbnQgKG9yIGVsZW1lbnQtYmFzZWQgY29tcHV0YXRpb24pLlxuICBfLm1pbiA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0ID0gSW5maW5pdHksIGxhc3RDb21wdXRlZCA9IEluZmluaXR5LFxuICAgICAgICB2YWx1ZSwgY29tcHV0ZWQ7XG4gICAgaWYgKGl0ZXJhdGVlID09IG51bGwgJiYgb2JqICE9IG51bGwpIHtcbiAgICAgIG9iaiA9IG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoID8gb2JqIDogXy52YWx1ZXMob2JqKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBvYmoubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFsdWUgPSBvYmpbaV07XG4gICAgICAgIGlmICh2YWx1ZSA8IHJlc3VsdCkge1xuICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGl0ZXJhdGVlID0gXy5pdGVyYXRlZShpdGVyYXRlZSwgY29udGV4dCk7XG4gICAgICBfLmVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSh2YWx1ZSwgaW5kZXgsIGxpc3QpO1xuICAgICAgICBpZiAoY29tcHV0ZWQgPCBsYXN0Q29tcHV0ZWQgfHwgY29tcHV0ZWQgPT09IEluZmluaXR5ICYmIHJlc3VsdCA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBsYXN0Q29tcHV0ZWQgPSBjb21wdXRlZDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gU2h1ZmZsZSBhIGNvbGxlY3Rpb24sIHVzaW5nIHRoZSBtb2Rlcm4gdmVyc2lvbiBvZiB0aGVcbiAgLy8gW0Zpc2hlci1ZYXRlcyBzaHVmZmxlXShodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Zpc2hlcuKAk1lhdGVzX3NodWZmbGUpLlxuICBfLnNodWZmbGUgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgc2V0ID0gb2JqICYmIG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoID8gb2JqIDogXy52YWx1ZXMob2JqKTtcbiAgICB2YXIgbGVuZ3RoID0gc2V0Lmxlbmd0aDtcbiAgICB2YXIgc2h1ZmZsZWQgPSBBcnJheShsZW5ndGgpO1xuICAgIGZvciAodmFyIGluZGV4ID0gMCwgcmFuZDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIHJhbmQgPSBfLnJhbmRvbSgwLCBpbmRleCk7XG4gICAgICBpZiAocmFuZCAhPT0gaW5kZXgpIHNodWZmbGVkW2luZGV4XSA9IHNodWZmbGVkW3JhbmRdO1xuICAgICAgc2h1ZmZsZWRbcmFuZF0gPSBzZXRbaW5kZXhdO1xuICAgIH1cbiAgICByZXR1cm4gc2h1ZmZsZWQ7XG4gIH07XG5cbiAgLy8gU2FtcGxlICoqbioqIHJhbmRvbSB2YWx1ZXMgZnJvbSBhIGNvbGxlY3Rpb24uXG4gIC8vIElmICoqbioqIGlzIG5vdCBzcGVjaWZpZWQsIHJldHVybnMgYSBzaW5nbGUgcmFuZG9tIGVsZW1lbnQuXG4gIC8vIFRoZSBpbnRlcm5hbCBgZ3VhcmRgIGFyZ3VtZW50IGFsbG93cyBpdCB0byB3b3JrIHdpdGggYG1hcGAuXG4gIF8uc2FtcGxlID0gZnVuY3Rpb24ob2JqLCBuLCBndWFyZCkge1xuICAgIGlmIChuID09IG51bGwgfHwgZ3VhcmQpIHtcbiAgICAgIGlmIChvYmoubGVuZ3RoICE9PSArb2JqLmxlbmd0aCkgb2JqID0gXy52YWx1ZXMob2JqKTtcbiAgICAgIHJldHVybiBvYmpbXy5yYW5kb20ob2JqLmxlbmd0aCAtIDEpXTtcbiAgICB9XG4gICAgcmV0dXJuIF8uc2h1ZmZsZShvYmopLnNsaWNlKDAsIE1hdGgubWF4KDAsIG4pKTtcbiAgfTtcblxuICAvLyBTb3J0IHRoZSBvYmplY3QncyB2YWx1ZXMgYnkgYSBjcml0ZXJpb24gcHJvZHVjZWQgYnkgYW4gaXRlcmF0ZWUuXG4gIF8uc29ydEJ5ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgIGl0ZXJhdGVlID0gXy5pdGVyYXRlZShpdGVyYXRlZSwgY29udGV4dCk7XG4gICAgcmV0dXJuIF8ucGx1Y2soXy5tYXAob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICBjcml0ZXJpYTogaXRlcmF0ZWUodmFsdWUsIGluZGV4LCBsaXN0KVxuICAgICAgfTtcbiAgICB9KS5zb3J0KGZ1bmN0aW9uKGxlZnQsIHJpZ2h0KSB7XG4gICAgICB2YXIgYSA9IGxlZnQuY3JpdGVyaWE7XG4gICAgICB2YXIgYiA9IHJpZ2h0LmNyaXRlcmlhO1xuICAgICAgaWYgKGEgIT09IGIpIHtcbiAgICAgICAgaWYgKGEgPiBiIHx8IGEgPT09IHZvaWQgMCkgcmV0dXJuIDE7XG4gICAgICAgIGlmIChhIDwgYiB8fCBiID09PSB2b2lkIDApIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBsZWZ0LmluZGV4IC0gcmlnaHQuaW5kZXg7XG4gICAgfSksICd2YWx1ZScpO1xuICB9O1xuXG4gIC8vIEFuIGludGVybmFsIGZ1bmN0aW9uIHVzZWQgZm9yIGFnZ3JlZ2F0ZSBcImdyb3VwIGJ5XCIgb3BlcmF0aW9ucy5cbiAgdmFyIGdyb3VwID0gZnVuY3Rpb24oYmVoYXZpb3IpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgaXRlcmF0ZWUgPSBfLml0ZXJhdGVlKGl0ZXJhdGVlLCBjb250ZXh0KTtcbiAgICAgIF8uZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgICB2YXIga2V5ID0gaXRlcmF0ZWUodmFsdWUsIGluZGV4LCBvYmopO1xuICAgICAgICBiZWhhdmlvcihyZXN1bHQsIHZhbHVlLCBrZXkpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH07XG5cbiAgLy8gR3JvdXBzIHRoZSBvYmplY3QncyB2YWx1ZXMgYnkgYSBjcml0ZXJpb24uIFBhc3MgZWl0aGVyIGEgc3RyaW5nIGF0dHJpYnV0ZVxuICAvLyB0byBncm91cCBieSwgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIGNyaXRlcmlvbi5cbiAgXy5ncm91cEJ5ID0gZ3JvdXAoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgaWYgKF8uaGFzKHJlc3VsdCwga2V5KSkgcmVzdWx0W2tleV0ucHVzaCh2YWx1ZSk7IGVsc2UgcmVzdWx0W2tleV0gPSBbdmFsdWVdO1xuICB9KTtcblxuICAvLyBJbmRleGVzIHRoZSBvYmplY3QncyB2YWx1ZXMgYnkgYSBjcml0ZXJpb24sIHNpbWlsYXIgdG8gYGdyb3VwQnlgLCBidXQgZm9yXG4gIC8vIHdoZW4geW91IGtub3cgdGhhdCB5b3VyIGluZGV4IHZhbHVlcyB3aWxsIGJlIHVuaXF1ZS5cbiAgXy5pbmRleEJ5ID0gZ3JvdXAoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgcmVzdWx0W2tleV0gPSB2YWx1ZTtcbiAgfSk7XG5cbiAgLy8gQ291bnRzIGluc3RhbmNlcyBvZiBhbiBvYmplY3QgdGhhdCBncm91cCBieSBhIGNlcnRhaW4gY3JpdGVyaW9uLiBQYXNzXG4gIC8vIGVpdGhlciBhIHN0cmluZyBhdHRyaWJ1dGUgdG8gY291bnQgYnksIG9yIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZVxuICAvLyBjcml0ZXJpb24uXG4gIF8uY291bnRCeSA9IGdyb3VwKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgIGlmIChfLmhhcyhyZXN1bHQsIGtleSkpIHJlc3VsdFtrZXldKys7IGVsc2UgcmVzdWx0W2tleV0gPSAxO1xuICB9KTtcblxuICAvLyBVc2UgYSBjb21wYXJhdG9yIGZ1bmN0aW9uIHRvIGZpZ3VyZSBvdXQgdGhlIHNtYWxsZXN0IGluZGV4IGF0IHdoaWNoXG4gIC8vIGFuIG9iamVjdCBzaG91bGQgYmUgaW5zZXJ0ZWQgc28gYXMgdG8gbWFpbnRhaW4gb3JkZXIuIFVzZXMgYmluYXJ5IHNlYXJjaC5cbiAgXy5zb3J0ZWRJbmRleCA9IGZ1bmN0aW9uKGFycmF5LCBvYmosIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgaXRlcmF0ZWUgPSBfLml0ZXJhdGVlKGl0ZXJhdGVlLCBjb250ZXh0LCAxKTtcbiAgICB2YXIgdmFsdWUgPSBpdGVyYXRlZShvYmopO1xuICAgIHZhciBsb3cgPSAwLCBoaWdoID0gYXJyYXkubGVuZ3RoO1xuICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICB2YXIgbWlkID0gbG93ICsgaGlnaCA+Pj4gMTtcbiAgICAgIGlmIChpdGVyYXRlZShhcnJheVttaWRdKSA8IHZhbHVlKSBsb3cgPSBtaWQgKyAxOyBlbHNlIGhpZ2ggPSBtaWQ7XG4gICAgfVxuICAgIHJldHVybiBsb3c7XG4gIH07XG5cbiAgLy8gU2FmZWx5IGNyZWF0ZSBhIHJlYWwsIGxpdmUgYXJyYXkgZnJvbSBhbnl0aGluZyBpdGVyYWJsZS5cbiAgXy50b0FycmF5ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFvYmopIHJldHVybiBbXTtcbiAgICBpZiAoXy5pc0FycmF5KG9iaikpIHJldHVybiBzbGljZS5jYWxsKG9iaik7XG4gICAgaWYgKG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoKSByZXR1cm4gXy5tYXAob2JqLCBfLmlkZW50aXR5KTtcbiAgICByZXR1cm4gXy52YWx1ZXMob2JqKTtcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBhbiBvYmplY3QuXG4gIF8uc2l6ZSA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIDA7XG4gICAgcmV0dXJuIG9iai5sZW5ndGggPT09ICtvYmoubGVuZ3RoID8gb2JqLmxlbmd0aCA6IF8ua2V5cyhvYmopLmxlbmd0aDtcbiAgfTtcblxuICAvLyBTcGxpdCBhIGNvbGxlY3Rpb24gaW50byB0d28gYXJyYXlzOiBvbmUgd2hvc2UgZWxlbWVudHMgYWxsIHNhdGlzZnkgdGhlIGdpdmVuXG4gIC8vIHByZWRpY2F0ZSwgYW5kIG9uZSB3aG9zZSBlbGVtZW50cyBhbGwgZG8gbm90IHNhdGlzZnkgdGhlIHByZWRpY2F0ZS5cbiAgXy5wYXJ0aXRpb24gPSBmdW5jdGlvbihvYmosIHByZWRpY2F0ZSwgY29udGV4dCkge1xuICAgIHByZWRpY2F0ZSA9IF8uaXRlcmF0ZWUocHJlZGljYXRlLCBjb250ZXh0KTtcbiAgICB2YXIgcGFzcyA9IFtdLCBmYWlsID0gW107XG4gICAgXy5lYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGtleSwgb2JqKSB7XG4gICAgICAocHJlZGljYXRlKHZhbHVlLCBrZXksIG9iaikgPyBwYXNzIDogZmFpbCkucHVzaCh2YWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIFtwYXNzLCBmYWlsXTtcbiAgfTtcblxuICAvLyBBcnJheSBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gR2V0IHRoZSBmaXJzdCBlbGVtZW50IG9mIGFuIGFycmF5LiBQYXNzaW5nICoqbioqIHdpbGwgcmV0dXJuIHRoZSBmaXJzdCBOXG4gIC8vIHZhbHVlcyBpbiB0aGUgYXJyYXkuIEFsaWFzZWQgYXMgYGhlYWRgIGFuZCBgdGFrZWAuIFRoZSAqKmd1YXJkKiogY2hlY2tcbiAgLy8gYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgXy5tYXBgLlxuICBfLmZpcnN0ID0gXy5oZWFkID0gXy50YWtlID0gZnVuY3Rpb24oYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiB2b2lkIDA7XG4gICAgaWYgKG4gPT0gbnVsbCB8fCBndWFyZCkgcmV0dXJuIGFycmF5WzBdO1xuICAgIGlmIChuIDwgMCkgcmV0dXJuIFtdO1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCAwLCBuKTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGV2ZXJ5dGhpbmcgYnV0IHRoZSBsYXN0IGVudHJ5IG9mIHRoZSBhcnJheS4gRXNwZWNpYWxseSB1c2VmdWwgb25cbiAgLy8gdGhlIGFyZ3VtZW50cyBvYmplY3QuIFBhc3NpbmcgKipuKiogd2lsbCByZXR1cm4gYWxsIHRoZSB2YWx1ZXMgaW5cbiAgLy8gdGhlIGFycmF5LCBleGNsdWRpbmcgdGhlIGxhc3QgTi4gVGhlICoqZ3VhcmQqKiBjaGVjayBhbGxvd3MgaXQgdG8gd29yayB3aXRoXG4gIC8vIGBfLm1hcGAuXG4gIF8uaW5pdGlhbCA9IGZ1bmN0aW9uKGFycmF5LCBuLCBndWFyZCkge1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCAwLCBNYXRoLm1heCgwLCBhcnJheS5sZW5ndGggLSAobiA9PSBudWxsIHx8IGd1YXJkID8gMSA6IG4pKSk7XG4gIH07XG5cbiAgLy8gR2V0IHRoZSBsYXN0IGVsZW1lbnQgb2YgYW4gYXJyYXkuIFBhc3NpbmcgKipuKiogd2lsbCByZXR1cm4gdGhlIGxhc3QgTlxuICAvLyB2YWx1ZXMgaW4gdGhlIGFycmF5LiBUaGUgKipndWFyZCoqIGNoZWNrIGFsbG93cyBpdCB0byB3b3JrIHdpdGggYF8ubWFwYC5cbiAgXy5sYXN0ID0gZnVuY3Rpb24oYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiB2b2lkIDA7XG4gICAgaWYgKG4gPT0gbnVsbCB8fCBndWFyZCkgcmV0dXJuIGFycmF5W2FycmF5Lmxlbmd0aCAtIDFdO1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCBNYXRoLm1heChhcnJheS5sZW5ndGggLSBuLCAwKSk7XG4gIH07XG5cbiAgLy8gUmV0dXJucyBldmVyeXRoaW5nIGJ1dCB0aGUgZmlyc3QgZW50cnkgb2YgdGhlIGFycmF5LiBBbGlhc2VkIGFzIGB0YWlsYCBhbmQgYGRyb3BgLlxuICAvLyBFc3BlY2lhbGx5IHVzZWZ1bCBvbiB0aGUgYXJndW1lbnRzIG9iamVjdC4gUGFzc2luZyBhbiAqKm4qKiB3aWxsIHJldHVyblxuICAvLyB0aGUgcmVzdCBOIHZhbHVlcyBpbiB0aGUgYXJyYXkuIFRoZSAqKmd1YXJkKipcbiAgLy8gY2hlY2sgYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgXy5tYXBgLlxuICBfLnJlc3QgPSBfLnRhaWwgPSBfLmRyb3AgPSBmdW5jdGlvbihhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICByZXR1cm4gc2xpY2UuY2FsbChhcnJheSwgbiA9PSBudWxsIHx8IGd1YXJkID8gMSA6IG4pO1xuICB9O1xuXG4gIC8vIFRyaW0gb3V0IGFsbCBmYWxzeSB2YWx1ZXMgZnJvbSBhbiBhcnJheS5cbiAgXy5jb21wYWN0ID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICByZXR1cm4gXy5maWx0ZXIoYXJyYXksIF8uaWRlbnRpdHkpO1xuICB9O1xuXG4gIC8vIEludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIGEgcmVjdXJzaXZlIGBmbGF0dGVuYCBmdW5jdGlvbi5cbiAgdmFyIGZsYXR0ZW4gPSBmdW5jdGlvbihpbnB1dCwgc2hhbGxvdywgc3RyaWN0LCBvdXRwdXQpIHtcbiAgICBpZiAoc2hhbGxvdyAmJiBfLmV2ZXJ5KGlucHV0LCBfLmlzQXJyYXkpKSB7XG4gICAgICByZXR1cm4gY29uY2F0LmFwcGx5KG91dHB1dCwgaW5wdXQpO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gaW5wdXQubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciB2YWx1ZSA9IGlucHV0W2ldO1xuICAgICAgaWYgKCFfLmlzQXJyYXkodmFsdWUpICYmICFfLmlzQXJndW1lbnRzKHZhbHVlKSkge1xuICAgICAgICBpZiAoIXN0cmljdCkgb3V0cHV0LnB1c2godmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChzaGFsbG93KSB7XG4gICAgICAgIHB1c2guYXBwbHkob3V0cHV0LCB2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmbGF0dGVuKHZhbHVlLCBzaGFsbG93LCBzdHJpY3QsIG91dHB1dCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH07XG5cbiAgLy8gRmxhdHRlbiBvdXQgYW4gYXJyYXksIGVpdGhlciByZWN1cnNpdmVseSAoYnkgZGVmYXVsdCksIG9yIGp1c3Qgb25lIGxldmVsLlxuICBfLmZsYXR0ZW4gPSBmdW5jdGlvbihhcnJheSwgc2hhbGxvdykge1xuICAgIHJldHVybiBmbGF0dGVuKGFycmF5LCBzaGFsbG93LCBmYWxzZSwgW10pO1xuICB9O1xuXG4gIC8vIFJldHVybiBhIHZlcnNpb24gb2YgdGhlIGFycmF5IHRoYXQgZG9lcyBub3QgY29udGFpbiB0aGUgc3BlY2lmaWVkIHZhbHVlKHMpLlxuICBfLndpdGhvdXQgPSBmdW5jdGlvbihhcnJheSkge1xuICAgIHJldHVybiBfLmRpZmZlcmVuY2UoYXJyYXksIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XG4gIH07XG5cbiAgLy8gUHJvZHVjZSBhIGR1cGxpY2F0ZS1mcmVlIHZlcnNpb24gb2YgdGhlIGFycmF5LiBJZiB0aGUgYXJyYXkgaGFzIGFscmVhZHlcbiAgLy8gYmVlbiBzb3J0ZWQsIHlvdSBoYXZlIHRoZSBvcHRpb24gb2YgdXNpbmcgYSBmYXN0ZXIgYWxnb3JpdGhtLlxuICAvLyBBbGlhc2VkIGFzIGB1bmlxdWVgLlxuICBfLnVuaXEgPSBfLnVuaXF1ZSA9IGZ1bmN0aW9uKGFycmF5LCBpc1NvcnRlZCwgaXRlcmF0ZWUsIGNvbnRleHQpIHtcbiAgICBpZiAoYXJyYXkgPT0gbnVsbCkgcmV0dXJuIFtdO1xuICAgIGlmICghXy5pc0Jvb2xlYW4oaXNTb3J0ZWQpKSB7XG4gICAgICBjb250ZXh0ID0gaXRlcmF0ZWU7XG4gICAgICBpdGVyYXRlZSA9IGlzU29ydGVkO1xuICAgICAgaXNTb3J0ZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGl0ZXJhdGVlICE9IG51bGwpIGl0ZXJhdGVlID0gXy5pdGVyYXRlZShpdGVyYXRlZSwgY29udGV4dCk7XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIHZhciBzZWVuID0gW107XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcnJheVtpXTtcbiAgICAgIGlmIChpc1NvcnRlZCkge1xuICAgICAgICBpZiAoIWkgfHwgc2VlbiAhPT0gdmFsdWUpIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgc2VlbiA9IHZhbHVlO1xuICAgICAgfSBlbHNlIGlmIChpdGVyYXRlZSkge1xuICAgICAgICB2YXIgY29tcHV0ZWQgPSBpdGVyYXRlZSh2YWx1ZSwgaSwgYXJyYXkpO1xuICAgICAgICBpZiAoXy5pbmRleE9mKHNlZW4sIGNvbXB1dGVkKSA8IDApIHtcbiAgICAgICAgICBzZWVuLnB1c2goY29tcHV0ZWQpO1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChfLmluZGV4T2YocmVzdWx0LCB2YWx1ZSkgPCAwKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBQcm9kdWNlIGFuIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIHVuaW9uOiBlYWNoIGRpc3RpbmN0IGVsZW1lbnQgZnJvbSBhbGwgb2ZcbiAgLy8gdGhlIHBhc3NlZC1pbiBhcnJheXMuXG4gIF8udW5pb24gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXy51bmlxKGZsYXR0ZW4oYXJndW1lbnRzLCB0cnVlLCB0cnVlLCBbXSkpO1xuICB9O1xuXG4gIC8vIFByb2R1Y2UgYW4gYXJyYXkgdGhhdCBjb250YWlucyBldmVyeSBpdGVtIHNoYXJlZCBiZXR3ZWVuIGFsbCB0aGVcbiAgLy8gcGFzc2VkLWluIGFycmF5cy5cbiAgXy5pbnRlcnNlY3Rpb24gPSBmdW5jdGlvbihhcnJheSkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gW107XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIHZhciBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBpdGVtID0gYXJyYXlbaV07XG4gICAgICBpZiAoXy5jb250YWlucyhyZXN1bHQsIGl0ZW0pKSBjb250aW51ZTtcbiAgICAgIGZvciAodmFyIGogPSAxOyBqIDwgYXJnc0xlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmICghXy5jb250YWlucyhhcmd1bWVudHNbal0sIGl0ZW0pKSBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChqID09PSBhcmdzTGVuZ3RoKSByZXN1bHQucHVzaChpdGVtKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBUYWtlIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gb25lIGFycmF5IGFuZCBhIG51bWJlciBvZiBvdGhlciBhcnJheXMuXG4gIC8vIE9ubHkgdGhlIGVsZW1lbnRzIHByZXNlbnQgaW4ganVzdCB0aGUgZmlyc3QgYXJyYXkgd2lsbCByZW1haW4uXG4gIF8uZGlmZmVyZW5jZSA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgdmFyIHJlc3QgPSBmbGF0dGVuKHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSwgdHJ1ZSwgdHJ1ZSwgW10pO1xuICAgIHJldHVybiBfLmZpbHRlcihhcnJheSwgZnVuY3Rpb24odmFsdWUpe1xuICAgICAgcmV0dXJuICFfLmNvbnRhaW5zKHJlc3QsIHZhbHVlKTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBaaXAgdG9nZXRoZXIgbXVsdGlwbGUgbGlzdHMgaW50byBhIHNpbmdsZSBhcnJheSAtLSBlbGVtZW50cyB0aGF0IHNoYXJlXG4gIC8vIGFuIGluZGV4IGdvIHRvZ2V0aGVyLlxuICBfLnppcCA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiBbXTtcbiAgICB2YXIgbGVuZ3RoID0gXy5tYXgoYXJndW1lbnRzLCAnbGVuZ3RoJykubGVuZ3RoO1xuICAgIHZhciByZXN1bHRzID0gQXJyYXkobGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHRzW2ldID0gXy5wbHVjayhhcmd1bWVudHMsIGkpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICAvLyBDb252ZXJ0cyBsaXN0cyBpbnRvIG9iamVjdHMuIFBhc3MgZWl0aGVyIGEgc2luZ2xlIGFycmF5IG9mIGBba2V5LCB2YWx1ZV1gXG4gIC8vIHBhaXJzLCBvciB0d28gcGFyYWxsZWwgYXJyYXlzIG9mIHRoZSBzYW1lIGxlbmd0aCAtLSBvbmUgb2Yga2V5cywgYW5kIG9uZSBvZlxuICAvLyB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gIF8ub2JqZWN0ID0gZnVuY3Rpb24obGlzdCwgdmFsdWVzKSB7XG4gICAgaWYgKGxpc3QgPT0gbnVsbCkgcmV0dXJuIHt9O1xuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gbGlzdC5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHZhbHVlcykge1xuICAgICAgICByZXN1bHRbbGlzdFtpXV0gPSB2YWx1ZXNbaV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRbbGlzdFtpXVswXV0gPSBsaXN0W2ldWzFdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYW4gaXRlbSBpbiBhbiBhcnJheSxcbiAgLy8gb3IgLTEgaWYgdGhlIGl0ZW0gaXMgbm90IGluY2x1ZGVkIGluIHRoZSBhcnJheS5cbiAgLy8gSWYgdGhlIGFycmF5IGlzIGxhcmdlIGFuZCBhbHJlYWR5IGluIHNvcnQgb3JkZXIsIHBhc3MgYHRydWVgXG4gIC8vIGZvciAqKmlzU29ydGVkKiogdG8gdXNlIGJpbmFyeSBzZWFyY2guXG4gIF8uaW5kZXhPZiA9IGZ1bmN0aW9uKGFycmF5LCBpdGVtLCBpc1NvcnRlZCkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gLTE7XG4gICAgdmFyIGkgPSAwLCBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgaWYgKGlzU29ydGVkKSB7XG4gICAgICBpZiAodHlwZW9mIGlzU29ydGVkID09ICdudW1iZXInKSB7XG4gICAgICAgIGkgPSBpc1NvcnRlZCA8IDAgPyBNYXRoLm1heCgwLCBsZW5ndGggKyBpc1NvcnRlZCkgOiBpc1NvcnRlZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGkgPSBfLnNvcnRlZEluZGV4KGFycmF5LCBpdGVtKTtcbiAgICAgICAgcmV0dXJuIGFycmF5W2ldID09PSBpdGVtID8gaSA6IC0xO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSBpZiAoYXJyYXlbaV0gPT09IGl0ZW0pIHJldHVybiBpO1xuICAgIHJldHVybiAtMTtcbiAgfTtcblxuICBfLmxhc3RJbmRleE9mID0gZnVuY3Rpb24oYXJyYXksIGl0ZW0sIGZyb20pIHtcbiAgICBpZiAoYXJyYXkgPT0gbnVsbCkgcmV0dXJuIC0xO1xuICAgIHZhciBpZHggPSBhcnJheS5sZW5ndGg7XG4gICAgaWYgKHR5cGVvZiBmcm9tID09ICdudW1iZXInKSB7XG4gICAgICBpZHggPSBmcm9tIDwgMCA/IGlkeCArIGZyb20gKyAxIDogTWF0aC5taW4oaWR4LCBmcm9tICsgMSk7XG4gICAgfVxuICAgIHdoaWxlICgtLWlkeCA+PSAwKSBpZiAoYXJyYXlbaWR4XSA9PT0gaXRlbSkgcmV0dXJuIGlkeDtcbiAgICByZXR1cm4gLTE7XG4gIH07XG5cbiAgLy8gR2VuZXJhdGUgYW4gaW50ZWdlciBBcnJheSBjb250YWluaW5nIGFuIGFyaXRobWV0aWMgcHJvZ3Jlc3Npb24uIEEgcG9ydCBvZlxuICAvLyB0aGUgbmF0aXZlIFB5dGhvbiBgcmFuZ2UoKWAgZnVuY3Rpb24uIFNlZVxuICAvLyBbdGhlIFB5dGhvbiBkb2N1bWVudGF0aW9uXShodHRwOi8vZG9jcy5weXRob24ub3JnL2xpYnJhcnkvZnVuY3Rpb25zLmh0bWwjcmFuZ2UpLlxuICBfLnJhbmdlID0gZnVuY3Rpb24oc3RhcnQsIHN0b3AsIHN0ZXApIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8PSAxKSB7XG4gICAgICBzdG9wID0gc3RhcnQgfHwgMDtcbiAgICAgIHN0YXJ0ID0gMDtcbiAgICB9XG4gICAgc3RlcCA9IHN0ZXAgfHwgMTtcblxuICAgIHZhciBsZW5ndGggPSBNYXRoLm1heChNYXRoLmNlaWwoKHN0b3AgLSBzdGFydCkgLyBzdGVwKSwgMCk7XG4gICAgdmFyIHJhbmdlID0gQXJyYXkobGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGlkeCA9IDA7IGlkeCA8IGxlbmd0aDsgaWR4KyssIHN0YXJ0ICs9IHN0ZXApIHtcbiAgICAgIHJhbmdlW2lkeF0gPSBzdGFydDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmFuZ2U7XG4gIH07XG5cbiAgLy8gRnVuY3Rpb24gKGFoZW0pIEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBSZXVzYWJsZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBmb3IgcHJvdG90eXBlIHNldHRpbmcuXG4gIHZhciBDdG9yID0gZnVuY3Rpb24oKXt9O1xuXG4gIC8vIENyZWF0ZSBhIGZ1bmN0aW9uIGJvdW5kIHRvIGEgZ2l2ZW4gb2JqZWN0IChhc3NpZ25pbmcgYHRoaXNgLCBhbmQgYXJndW1lbnRzLFxuICAvLyBvcHRpb25hbGx5KS4gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYEZ1bmN0aW9uLmJpbmRgIGlmXG4gIC8vIGF2YWlsYWJsZS5cbiAgXy5iaW5kID0gZnVuY3Rpb24oZnVuYywgY29udGV4dCkge1xuICAgIHZhciBhcmdzLCBib3VuZDtcbiAgICBpZiAobmF0aXZlQmluZCAmJiBmdW5jLmJpbmQgPT09IG5hdGl2ZUJpbmQpIHJldHVybiBuYXRpdmVCaW5kLmFwcGx5KGZ1bmMsIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XG4gICAgaWYgKCFfLmlzRnVuY3Rpb24oZnVuYykpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0JpbmQgbXVzdCBiZSBjYWxsZWQgb24gYSBmdW5jdGlvbicpO1xuICAgIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgYm91bmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBib3VuZCkpIHJldHVybiBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MuY29uY2F0KHNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xuICAgICAgQ3Rvci5wcm90b3R5cGUgPSBmdW5jLnByb3RvdHlwZTtcbiAgICAgIHZhciBzZWxmID0gbmV3IEN0b3I7XG4gICAgICBDdG9yLnByb3RvdHlwZSA9IG51bGw7XG4gICAgICB2YXIgcmVzdWx0ID0gZnVuYy5hcHBseShzZWxmLCBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgIGlmIChfLmlzT2JqZWN0KHJlc3VsdCkpIHJldHVybiByZXN1bHQ7XG4gICAgICByZXR1cm4gc2VsZjtcbiAgICB9O1xuICAgIHJldHVybiBib3VuZDtcbiAgfTtcblxuICAvLyBQYXJ0aWFsbHkgYXBwbHkgYSBmdW5jdGlvbiBieSBjcmVhdGluZyBhIHZlcnNpb24gdGhhdCBoYXMgaGFkIHNvbWUgb2YgaXRzXG4gIC8vIGFyZ3VtZW50cyBwcmUtZmlsbGVkLCB3aXRob3V0IGNoYW5naW5nIGl0cyBkeW5hbWljIGB0aGlzYCBjb250ZXh0LiBfIGFjdHNcbiAgLy8gYXMgYSBwbGFjZWhvbGRlciwgYWxsb3dpbmcgYW55IGNvbWJpbmF0aW9uIG9mIGFyZ3VtZW50cyB0byBiZSBwcmUtZmlsbGVkLlxuICBfLnBhcnRpYWwgPSBmdW5jdGlvbihmdW5jKSB7XG4gICAgdmFyIGJvdW5kQXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcG9zaXRpb24gPSAwO1xuICAgICAgdmFyIGFyZ3MgPSBib3VuZEFyZ3Muc2xpY2UoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBhcmdzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChhcmdzW2ldID09PSBfKSBhcmdzW2ldID0gYXJndW1lbnRzW3Bvc2l0aW9uKytdO1xuICAgICAgfVxuICAgICAgd2hpbGUgKHBvc2l0aW9uIDwgYXJndW1lbnRzLmxlbmd0aCkgYXJncy5wdXNoKGFyZ3VtZW50c1twb3NpdGlvbisrXSk7XG4gICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9O1xuICB9O1xuXG4gIC8vIEJpbmQgYSBudW1iZXIgb2YgYW4gb2JqZWN0J3MgbWV0aG9kcyB0byB0aGF0IG9iamVjdC4gUmVtYWluaW5nIGFyZ3VtZW50c1xuICAvLyBhcmUgdGhlIG1ldGhvZCBuYW1lcyB0byBiZSBib3VuZC4gVXNlZnVsIGZvciBlbnN1cmluZyB0aGF0IGFsbCBjYWxsYmFja3NcbiAgLy8gZGVmaW5lZCBvbiBhbiBvYmplY3QgYmVsb25nIHRvIGl0LlxuICBfLmJpbmRBbGwgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgaSwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCwga2V5O1xuICAgIGlmIChsZW5ndGggPD0gMSkgdGhyb3cgbmV3IEVycm9yKCdiaW5kQWxsIG11c3QgYmUgcGFzc2VkIGZ1bmN0aW9uIG5hbWVzJyk7XG4gICAgZm9yIChpID0gMTsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBrZXkgPSBhcmd1bWVudHNbaV07XG4gICAgICBvYmpba2V5XSA9IF8uYmluZChvYmpba2V5XSwgb2JqKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfTtcblxuICAvLyBNZW1vaXplIGFuIGV4cGVuc2l2ZSBmdW5jdGlvbiBieSBzdG9yaW5nIGl0cyByZXN1bHRzLlxuICBfLm1lbW9pemUgPSBmdW5jdGlvbihmdW5jLCBoYXNoZXIpIHtcbiAgICB2YXIgbWVtb2l6ZSA9IGZ1bmN0aW9uKGtleSkge1xuICAgICAgdmFyIGNhY2hlID0gbWVtb2l6ZS5jYWNoZTtcbiAgICAgIHZhciBhZGRyZXNzID0gaGFzaGVyID8gaGFzaGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiBrZXk7XG4gICAgICBpZiAoIV8uaGFzKGNhY2hlLCBhZGRyZXNzKSkgY2FjaGVbYWRkcmVzc10gPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gY2FjaGVbYWRkcmVzc107XG4gICAgfTtcbiAgICBtZW1vaXplLmNhY2hlID0ge307XG4gICAgcmV0dXJuIG1lbW9pemU7XG4gIH07XG5cbiAgLy8gRGVsYXlzIGEgZnVuY3Rpb24gZm9yIHRoZSBnaXZlbiBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLCBhbmQgdGhlbiBjYWxsc1xuICAvLyBpdCB3aXRoIHRoZSBhcmd1bWVudHMgc3VwcGxpZWQuXG4gIF8uZGVsYXkgPSBmdW5jdGlvbihmdW5jLCB3YWl0KSB7XG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIHJldHVybiBmdW5jLmFwcGx5KG51bGwsIGFyZ3MpO1xuICAgIH0sIHdhaXQpO1xuICB9O1xuXG4gIC8vIERlZmVycyBhIGZ1bmN0aW9uLCBzY2hlZHVsaW5nIGl0IHRvIHJ1biBhZnRlciB0aGUgY3VycmVudCBjYWxsIHN0YWNrIGhhc1xuICAvLyBjbGVhcmVkLlxuICBfLmRlZmVyID0gZnVuY3Rpb24oZnVuYykge1xuICAgIHJldHVybiBfLmRlbGF5LmFwcGx5KF8sIFtmdW5jLCAxXS5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKSk7XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uLCB0aGF0LCB3aGVuIGludm9rZWQsIHdpbGwgb25seSBiZSB0cmlnZ2VyZWQgYXQgbW9zdCBvbmNlXG4gIC8vIGR1cmluZyBhIGdpdmVuIHdpbmRvdyBvZiB0aW1lLiBOb3JtYWxseSwgdGhlIHRocm90dGxlZCBmdW5jdGlvbiB3aWxsIHJ1blxuICAvLyBhcyBtdWNoIGFzIGl0IGNhbiwgd2l0aG91dCBldmVyIGdvaW5nIG1vcmUgdGhhbiBvbmNlIHBlciBgd2FpdGAgZHVyYXRpb247XG4gIC8vIGJ1dCBpZiB5b3UnZCBsaWtlIHRvIGRpc2FibGUgdGhlIGV4ZWN1dGlvbiBvbiB0aGUgbGVhZGluZyBlZGdlLCBwYXNzXG4gIC8vIGB7bGVhZGluZzogZmFsc2V9YC4gVG8gZGlzYWJsZSBleGVjdXRpb24gb24gdGhlIHRyYWlsaW5nIGVkZ2UsIGRpdHRvLlxuICBfLnRocm90dGxlID0gZnVuY3Rpb24oZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICAgIHZhciBjb250ZXh0LCBhcmdzLCByZXN1bHQ7XG4gICAgdmFyIHRpbWVvdXQgPSBudWxsO1xuICAgIHZhciBwcmV2aW91cyA9IDA7XG4gICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgdmFyIGxhdGVyID0gZnVuY3Rpb24oKSB7XG4gICAgICBwcmV2aW91cyA9IG9wdGlvbnMubGVhZGluZyA9PT0gZmFsc2UgPyAwIDogXy5ub3coKTtcbiAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgIGlmICghdGltZW91dCkgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG5vdyA9IF8ubm93KCk7XG4gICAgICBpZiAoIXByZXZpb3VzICYmIG9wdGlvbnMubGVhZGluZyA9PT0gZmFsc2UpIHByZXZpb3VzID0gbm93O1xuICAgICAgdmFyIHJlbWFpbmluZyA9IHdhaXQgLSAobm93IC0gcHJldmlvdXMpO1xuICAgICAgY29udGV4dCA9IHRoaXM7XG4gICAgICBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgaWYgKHJlbWFpbmluZyA8PSAwIHx8IHJlbWFpbmluZyA+IHdhaXQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgcHJldmlvdXMgPSBub3c7XG4gICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgIGlmICghdGltZW91dCkgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgICAgfSBlbHNlIGlmICghdGltZW91dCAmJiBvcHRpb25zLnRyYWlsaW5nICE9PSBmYWxzZSkge1xuICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgcmVtYWluaW5nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24sIHRoYXQsIGFzIGxvbmcgYXMgaXQgY29udGludWVzIHRvIGJlIGludm9rZWQsIHdpbGwgbm90XG4gIC8vIGJlIHRyaWdnZXJlZC4gVGhlIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGl0IHN0b3BzIGJlaW5nIGNhbGxlZCBmb3JcbiAgLy8gTiBtaWxsaXNlY29uZHMuIElmIGBpbW1lZGlhdGVgIGlzIHBhc3NlZCwgdHJpZ2dlciB0aGUgZnVuY3Rpb24gb24gdGhlXG4gIC8vIGxlYWRpbmcgZWRnZSwgaW5zdGVhZCBvZiB0aGUgdHJhaWxpbmcuXG4gIF8uZGVib3VuY2UgPSBmdW5jdGlvbihmdW5jLCB3YWl0LCBpbW1lZGlhdGUpIHtcbiAgICB2YXIgdGltZW91dCwgYXJncywgY29udGV4dCwgdGltZXN0YW1wLCByZXN1bHQ7XG5cbiAgICB2YXIgbGF0ZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBsYXN0ID0gXy5ub3coKSAtIHRpbWVzdGFtcDtcblxuICAgICAgaWYgKGxhc3QgPCB3YWl0ICYmIGxhc3QgPiAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCB3YWl0IC0gbGFzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgaWYgKCFpbW1lZGlhdGUpIHtcbiAgICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgICAgICAgIGlmICghdGltZW91dCkgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnRleHQgPSB0aGlzO1xuICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgIHRpbWVzdGFtcCA9IF8ubm93KCk7XG4gICAgICB2YXIgY2FsbE5vdyA9IGltbWVkaWF0ZSAmJiAhdGltZW91dDtcbiAgICAgIGlmICghdGltZW91dCkgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpO1xuICAgICAgaWYgKGNhbGxOb3cpIHtcbiAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyB0aGUgZmlyc3QgZnVuY3Rpb24gcGFzc2VkIGFzIGFuIGFyZ3VtZW50IHRvIHRoZSBzZWNvbmQsXG4gIC8vIGFsbG93aW5nIHlvdSB0byBhZGp1c3QgYXJndW1lbnRzLCBydW4gY29kZSBiZWZvcmUgYW5kIGFmdGVyLCBhbmRcbiAgLy8gY29uZGl0aW9uYWxseSBleGVjdXRlIHRoZSBvcmlnaW5hbCBmdW5jdGlvbi5cbiAgXy53cmFwID0gZnVuY3Rpb24oZnVuYywgd3JhcHBlcikge1xuICAgIHJldHVybiBfLnBhcnRpYWwod3JhcHBlciwgZnVuYyk7XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIG5lZ2F0ZWQgdmVyc2lvbiBvZiB0aGUgcGFzc2VkLWluIHByZWRpY2F0ZS5cbiAgXy5uZWdhdGUgPSBmdW5jdGlvbihwcmVkaWNhdGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gIXByZWRpY2F0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIGEgbGlzdCBvZiBmdW5jdGlvbnMsIGVhY2hcbiAgLy8gY29uc3VtaW5nIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZ1bmN0aW9uIHRoYXQgZm9sbG93cy5cbiAgXy5jb21wb3NlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgdmFyIHN0YXJ0ID0gYXJncy5sZW5ndGggLSAxO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpID0gc3RhcnQ7XG4gICAgICB2YXIgcmVzdWx0ID0gYXJnc1tzdGFydF0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHdoaWxlIChpLS0pIHJlc3VsdCA9IGFyZ3NbaV0uY2FsbCh0aGlzLCByZXN1bHQpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9O1xuXG4gIC8vIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHdpbGwgb25seSBiZSBleGVjdXRlZCBhZnRlciBiZWluZyBjYWxsZWQgTiB0aW1lcy5cbiAgXy5hZnRlciA9IGZ1bmN0aW9uKHRpbWVzLCBmdW5jKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKC0tdGltZXMgPCAxKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCB3aWxsIG9ubHkgYmUgZXhlY3V0ZWQgYmVmb3JlIGJlaW5nIGNhbGxlZCBOIHRpbWVzLlxuICBfLmJlZm9yZSA9IGZ1bmN0aW9uKHRpbWVzLCBmdW5jKSB7XG4gICAgdmFyIG1lbW87XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKC0tdGltZXMgPiAwKSB7XG4gICAgICAgIG1lbW8gPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmdW5jID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBtZW1vO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBhdCBtb3N0IG9uZSB0aW1lLCBubyBtYXR0ZXIgaG93XG4gIC8vIG9mdGVuIHlvdSBjYWxsIGl0LiBVc2VmdWwgZm9yIGxhenkgaW5pdGlhbGl6YXRpb24uXG4gIF8ub25jZSA9IF8ucGFydGlhbChfLmJlZm9yZSwgMik7XG5cbiAgLy8gT2JqZWN0IEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gUmV0cmlldmUgdGhlIG5hbWVzIG9mIGFuIG9iamVjdCdzIHByb3BlcnRpZXMuXG4gIC8vIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGBPYmplY3Qua2V5c2BcbiAgXy5rZXlzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBbXTtcbiAgICBpZiAobmF0aXZlS2V5cykgcmV0dXJuIG5hdGl2ZUtleXMob2JqKTtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIGlmIChfLmhhcyhvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICAgIHJldHVybiBrZXlzO1xuICB9O1xuXG4gIC8vIFJldHJpZXZlIHRoZSB2YWx1ZXMgb2YgYW4gb2JqZWN0J3MgcHJvcGVydGllcy5cbiAgXy52YWx1ZXMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopO1xuICAgIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgICB2YXIgdmFsdWVzID0gQXJyYXkobGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWx1ZXNbaV0gPSBvYmpba2V5c1tpXV07XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZXM7XG4gIH07XG5cbiAgLy8gQ29udmVydCBhbiBvYmplY3QgaW50byBhIGxpc3Qgb2YgYFtrZXksIHZhbHVlXWAgcGFpcnMuXG4gIF8ucGFpcnMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopO1xuICAgIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgICB2YXIgcGFpcnMgPSBBcnJheShsZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHBhaXJzW2ldID0gW2tleXNbaV0sIG9ialtrZXlzW2ldXV07XG4gICAgfVxuICAgIHJldHVybiBwYWlycztcbiAgfTtcblxuICAvLyBJbnZlcnQgdGhlIGtleXMgYW5kIHZhbHVlcyBvZiBhbiBvYmplY3QuIFRoZSB2YWx1ZXMgbXVzdCBiZSBzZXJpYWxpemFibGUuXG4gIF8uaW52ZXJ0ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIHZhciBrZXlzID0gXy5rZXlzKG9iaik7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGtleXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdFtvYmpba2V5c1tpXV1dID0ga2V5c1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBSZXR1cm4gYSBzb3J0ZWQgbGlzdCBvZiB0aGUgZnVuY3Rpb24gbmFtZXMgYXZhaWxhYmxlIG9uIHRoZSBvYmplY3QuXG4gIC8vIEFsaWFzZWQgYXMgYG1ldGhvZHNgXG4gIF8uZnVuY3Rpb25zID0gXy5tZXRob2RzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIG5hbWVzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgaWYgKF8uaXNGdW5jdGlvbihvYmpba2V5XSkpIG5hbWVzLnB1c2goa2V5KTtcbiAgICB9XG4gICAgcmV0dXJuIG5hbWVzLnNvcnQoKTtcbiAgfTtcblxuICAvLyBFeHRlbmQgYSBnaXZlbiBvYmplY3Qgd2l0aCBhbGwgdGhlIHByb3BlcnRpZXMgaW4gcGFzc2VkLWluIG9iamVjdChzKS5cbiAgXy5leHRlbmQgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAoIV8uaXNPYmplY3Qob2JqKSkgcmV0dXJuIG9iajtcbiAgICB2YXIgc291cmNlLCBwcm9wO1xuICAgIGZvciAodmFyIGkgPSAxLCBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgIGZvciAocHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBwcm9wKSkge1xuICAgICAgICAgICAgb2JqW3Byb3BdID0gc291cmNlW3Byb3BdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmo7XG4gIH07XG5cbiAgLy8gUmV0dXJuIGEgY29weSBvZiB0aGUgb2JqZWN0IG9ubHkgY29udGFpbmluZyB0aGUgd2hpdGVsaXN0ZWQgcHJvcGVydGllcy5cbiAgXy5waWNrID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgIHZhciByZXN1bHQgPSB7fSwga2V5O1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdDtcbiAgICBpZiAoXy5pc0Z1bmN0aW9uKGl0ZXJhdGVlKSkge1xuICAgICAgaXRlcmF0ZWUgPSBjcmVhdGVDYWxsYmFjayhpdGVyYXRlZSwgY29udGV4dCk7XG4gICAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgICAgdmFyIHZhbHVlID0gb2JqW2tleV07XG4gICAgICAgIGlmIChpdGVyYXRlZSh2YWx1ZSwga2V5LCBvYmopKSByZXN1bHRba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIga2V5cyA9IGNvbmNhdC5hcHBseShbXSwgc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgICAgIG9iaiA9IG5ldyBPYmplY3Qob2JqKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgIGlmIChrZXkgaW4gb2JqKSByZXN1bHRba2V5XSA9IG9ialtrZXldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gICAvLyBSZXR1cm4gYSBjb3B5IG9mIHRoZSBvYmplY3Qgd2l0aG91dCB0aGUgYmxhY2tsaXN0ZWQgcHJvcGVydGllcy5cbiAgXy5vbWl0ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRlZSwgY29udGV4dCkge1xuICAgIGlmIChfLmlzRnVuY3Rpb24oaXRlcmF0ZWUpKSB7XG4gICAgICBpdGVyYXRlZSA9IF8ubmVnYXRlKGl0ZXJhdGVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGtleXMgPSBfLm1hcChjb25jYXQuYXBwbHkoW10sIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSksIFN0cmluZyk7XG4gICAgICBpdGVyYXRlZSA9IGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgcmV0dXJuICFfLmNvbnRhaW5zKGtleXMsIGtleSk7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gXy5waWNrKG9iaiwgaXRlcmF0ZWUsIGNvbnRleHQpO1xuICB9O1xuXG4gIC8vIEZpbGwgaW4gYSBnaXZlbiBvYmplY3Qgd2l0aCBkZWZhdWx0IHByb3BlcnRpZXMuXG4gIF8uZGVmYXVsdHMgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAoIV8uaXNPYmplY3Qob2JqKSkgcmV0dXJuIG9iajtcbiAgICBmb3IgKHZhciBpID0gMSwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKG9ialtwcm9wXSA9PT0gdm9pZCAwKSBvYmpbcHJvcF0gPSBzb3VyY2VbcHJvcF07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmo7XG4gIH07XG5cbiAgLy8gQ3JlYXRlIGEgKHNoYWxsb3ctY2xvbmVkKSBkdXBsaWNhdGUgb2YgYW4gb2JqZWN0LlxuICBfLmNsb25lID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gICAgcmV0dXJuIF8uaXNBcnJheShvYmopID8gb2JqLnNsaWNlKCkgOiBfLmV4dGVuZCh7fSwgb2JqKTtcbiAgfTtcblxuICAvLyBJbnZva2VzIGludGVyY2VwdG9yIHdpdGggdGhlIG9iaiwgYW5kIHRoZW4gcmV0dXJucyBvYmouXG4gIC8vIFRoZSBwcmltYXJ5IHB1cnBvc2Ugb2YgdGhpcyBtZXRob2QgaXMgdG8gXCJ0YXAgaW50b1wiIGEgbWV0aG9kIGNoYWluLCBpblxuICAvLyBvcmRlciB0byBwZXJmb3JtIG9wZXJhdGlvbnMgb24gaW50ZXJtZWRpYXRlIHJlc3VsdHMgd2l0aGluIHRoZSBjaGFpbi5cbiAgXy50YXAgPSBmdW5jdGlvbihvYmosIGludGVyY2VwdG9yKSB7XG4gICAgaW50ZXJjZXB0b3Iob2JqKTtcbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIEludGVybmFsIHJlY3Vyc2l2ZSBjb21wYXJpc29uIGZ1bmN0aW9uIGZvciBgaXNFcXVhbGAuXG4gIHZhciBlcSA9IGZ1bmN0aW9uKGEsIGIsIGFTdGFjaywgYlN0YWNrKSB7XG4gICAgLy8gSWRlbnRpY2FsIG9iamVjdHMgYXJlIGVxdWFsLiBgMCA9PT0gLTBgLCBidXQgdGhleSBhcmVuJ3QgaWRlbnRpY2FsLlxuICAgIC8vIFNlZSB0aGUgW0hhcm1vbnkgYGVnYWxgIHByb3Bvc2FsXShodHRwOi8vd2lraS5lY21hc2NyaXB0Lm9yZy9kb2t1LnBocD9pZD1oYXJtb255OmVnYWwpLlxuICAgIGlmIChhID09PSBiKSByZXR1cm4gYSAhPT0gMCB8fCAxIC8gYSA9PT0gMSAvIGI7XG4gICAgLy8gQSBzdHJpY3QgY29tcGFyaXNvbiBpcyBuZWNlc3NhcnkgYmVjYXVzZSBgbnVsbCA9PSB1bmRlZmluZWRgLlxuICAgIGlmIChhID09IG51bGwgfHwgYiA9PSBudWxsKSByZXR1cm4gYSA9PT0gYjtcbiAgICAvLyBVbndyYXAgYW55IHdyYXBwZWQgb2JqZWN0cy5cbiAgICBpZiAoYSBpbnN0YW5jZW9mIF8pIGEgPSBhLl93cmFwcGVkO1xuICAgIGlmIChiIGluc3RhbmNlb2YgXykgYiA9IGIuX3dyYXBwZWQ7XG4gICAgLy8gQ29tcGFyZSBgW1tDbGFzc11dYCBuYW1lcy5cbiAgICB2YXIgY2xhc3NOYW1lID0gdG9TdHJpbmcuY2FsbChhKTtcbiAgICBpZiAoY2xhc3NOYW1lICE9PSB0b1N0cmluZy5jYWxsKGIpKSByZXR1cm4gZmFsc2U7XG4gICAgc3dpdGNoIChjbGFzc05hbWUpIHtcbiAgICAgIC8vIFN0cmluZ3MsIG51bWJlcnMsIHJlZ3VsYXIgZXhwcmVzc2lvbnMsIGRhdGVzLCBhbmQgYm9vbGVhbnMgYXJlIGNvbXBhcmVkIGJ5IHZhbHVlLlxuICAgICAgY2FzZSAnW29iamVjdCBSZWdFeHBdJzpcbiAgICAgIC8vIFJlZ0V4cHMgYXJlIGNvZXJjZWQgdG8gc3RyaW5ncyBmb3IgY29tcGFyaXNvbiAoTm90ZTogJycgKyAvYS9pID09PSAnL2EvaScpXG4gICAgICBjYXNlICdbb2JqZWN0IFN0cmluZ10nOlxuICAgICAgICAvLyBQcmltaXRpdmVzIGFuZCB0aGVpciBjb3JyZXNwb25kaW5nIG9iamVjdCB3cmFwcGVycyBhcmUgZXF1aXZhbGVudDsgdGh1cywgYFwiNVwiYCBpc1xuICAgICAgICAvLyBlcXVpdmFsZW50IHRvIGBuZXcgU3RyaW5nKFwiNVwiKWAuXG4gICAgICAgIHJldHVybiAnJyArIGEgPT09ICcnICsgYjtcbiAgICAgIGNhc2UgJ1tvYmplY3QgTnVtYmVyXSc6XG4gICAgICAgIC8vIGBOYU5gcyBhcmUgZXF1aXZhbGVudCwgYnV0IG5vbi1yZWZsZXhpdmUuXG4gICAgICAgIC8vIE9iamVjdChOYU4pIGlzIGVxdWl2YWxlbnQgdG8gTmFOXG4gICAgICAgIGlmICgrYSAhPT0gK2EpIHJldHVybiArYiAhPT0gK2I7XG4gICAgICAgIC8vIEFuIGBlZ2FsYCBjb21wYXJpc29uIGlzIHBlcmZvcm1lZCBmb3Igb3RoZXIgbnVtZXJpYyB2YWx1ZXMuXG4gICAgICAgIHJldHVybiArYSA9PT0gMCA/IDEgLyArYSA9PT0gMSAvIGIgOiArYSA9PT0gK2I7XG4gICAgICBjYXNlICdbb2JqZWN0IERhdGVdJzpcbiAgICAgIGNhc2UgJ1tvYmplY3QgQm9vbGVhbl0nOlxuICAgICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWVyaWMgcHJpbWl0aXZlIHZhbHVlcy4gRGF0ZXMgYXJlIGNvbXBhcmVkIGJ5IHRoZWlyXG4gICAgICAgIC8vIG1pbGxpc2Vjb25kIHJlcHJlc2VudGF0aW9ucy4gTm90ZSB0aGF0IGludmFsaWQgZGF0ZXMgd2l0aCBtaWxsaXNlY29uZCByZXByZXNlbnRhdGlvbnNcbiAgICAgICAgLy8gb2YgYE5hTmAgYXJlIG5vdCBlcXVpdmFsZW50LlxuICAgICAgICByZXR1cm4gK2EgPT09ICtiO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGEgIT0gJ29iamVjdCcgfHwgdHlwZW9mIGIgIT0gJ29iamVjdCcpIHJldHVybiBmYWxzZTtcbiAgICAvLyBBc3N1bWUgZXF1YWxpdHkgZm9yIGN5Y2xpYyBzdHJ1Y3R1cmVzLiBUaGUgYWxnb3JpdGhtIGZvciBkZXRlY3RpbmcgY3ljbGljXG4gICAgLy8gc3RydWN0dXJlcyBpcyBhZGFwdGVkIGZyb20gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMywgYWJzdHJhY3Qgb3BlcmF0aW9uIGBKT2AuXG4gICAgdmFyIGxlbmd0aCA9IGFTdGFjay5sZW5ndGg7XG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAvLyBMaW5lYXIgc2VhcmNoLiBQZXJmb3JtYW5jZSBpcyBpbnZlcnNlbHkgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2ZcbiAgICAgIC8vIHVuaXF1ZSBuZXN0ZWQgc3RydWN0dXJlcy5cbiAgICAgIGlmIChhU3RhY2tbbGVuZ3RoXSA9PT0gYSkgcmV0dXJuIGJTdGFja1tsZW5ndGhdID09PSBiO1xuICAgIH1cbiAgICAvLyBPYmplY3RzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWl2YWxlbnQsIGJ1dCBgT2JqZWN0YHNcbiAgICAvLyBmcm9tIGRpZmZlcmVudCBmcmFtZXMgYXJlLlxuICAgIHZhciBhQ3RvciA9IGEuY29uc3RydWN0b3IsIGJDdG9yID0gYi5jb25zdHJ1Y3RvcjtcbiAgICBpZiAoXG4gICAgICBhQ3RvciAhPT0gYkN0b3IgJiZcbiAgICAgIC8vIEhhbmRsZSBPYmplY3QuY3JlYXRlKHgpIGNhc2VzXG4gICAgICAnY29uc3RydWN0b3InIGluIGEgJiYgJ2NvbnN0cnVjdG9yJyBpbiBiICYmXG4gICAgICAhKF8uaXNGdW5jdGlvbihhQ3RvcikgJiYgYUN0b3IgaW5zdGFuY2VvZiBhQ3RvciAmJlxuICAgICAgICBfLmlzRnVuY3Rpb24oYkN0b3IpICYmIGJDdG9yIGluc3RhbmNlb2YgYkN0b3IpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIEFkZCB0aGUgZmlyc3Qgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICBhU3RhY2sucHVzaChhKTtcbiAgICBiU3RhY2sucHVzaChiKTtcbiAgICB2YXIgc2l6ZSwgcmVzdWx0O1xuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyBhbmQgYXJyYXlzLlxuICAgIGlmIChjbGFzc05hbWUgPT09ICdbb2JqZWN0IEFycmF5XScpIHtcbiAgICAgIC8vIENvbXBhcmUgYXJyYXkgbGVuZ3RocyB0byBkZXRlcm1pbmUgaWYgYSBkZWVwIGNvbXBhcmlzb24gaXMgbmVjZXNzYXJ5LlxuICAgICAgc2l6ZSA9IGEubGVuZ3RoO1xuICAgICAgcmVzdWx0ID0gc2l6ZSA9PT0gYi5sZW5ndGg7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIC8vIERlZXAgY29tcGFyZSB0aGUgY29udGVudHMsIGlnbm9yaW5nIG5vbi1udW1lcmljIHByb3BlcnRpZXMuXG4gICAgICAgIHdoaWxlIChzaXplLS0pIHtcbiAgICAgICAgICBpZiAoIShyZXN1bHQgPSBlcShhW3NpemVdLCBiW3NpemVdLCBhU3RhY2ssIGJTdGFjaykpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWVwIGNvbXBhcmUgb2JqZWN0cy5cbiAgICAgIHZhciBrZXlzID0gXy5rZXlzKGEpLCBrZXk7XG4gICAgICBzaXplID0ga2V5cy5sZW5ndGg7XG4gICAgICAvLyBFbnN1cmUgdGhhdCBib3RoIG9iamVjdHMgY29udGFpbiB0aGUgc2FtZSBudW1iZXIgb2YgcHJvcGVydGllcyBiZWZvcmUgY29tcGFyaW5nIGRlZXAgZXF1YWxpdHkuXG4gICAgICByZXN1bHQgPSBfLmtleXMoYikubGVuZ3RoID09PSBzaXplO1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICB3aGlsZSAoc2l6ZS0tKSB7XG4gICAgICAgICAgLy8gRGVlcCBjb21wYXJlIGVhY2ggbWVtYmVyXG4gICAgICAgICAga2V5ID0ga2V5c1tzaXplXTtcbiAgICAgICAgICBpZiAoIShyZXN1bHQgPSBfLmhhcyhiLCBrZXkpICYmIGVxKGFba2V5XSwgYltrZXldLCBhU3RhY2ssIGJTdGFjaykpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBSZW1vdmUgdGhlIGZpcnN0IG9iamVjdCBmcm9tIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICBhU3RhY2sucG9wKCk7XG4gICAgYlN0YWNrLnBvcCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgLy8gUGVyZm9ybSBhIGRlZXAgY29tcGFyaXNvbiB0byBjaGVjayBpZiB0d28gb2JqZWN0cyBhcmUgZXF1YWwuXG4gIF8uaXNFcXVhbCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gZXEoYSwgYiwgW10sIFtdKTtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIGFycmF5LCBzdHJpbmcsIG9yIG9iamVjdCBlbXB0eT9cbiAgLy8gQW4gXCJlbXB0eVwiIG9iamVjdCBoYXMgbm8gZW51bWVyYWJsZSBvd24tcHJvcGVydGllcy5cbiAgXy5pc0VtcHR5ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoXy5pc0FycmF5KG9iaikgfHwgXy5pc1N0cmluZyhvYmopIHx8IF8uaXNBcmd1bWVudHMob2JqKSkgcmV0dXJuIG9iai5sZW5ndGggPT09IDA7XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikgaWYgKF8uaGFzKG9iaiwga2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gdmFsdWUgYSBET00gZWxlbWVudD9cbiAgXy5pc0VsZW1lbnQgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gISEob2JqICYmIG9iai5ub2RlVHlwZSA9PT0gMSk7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YWx1ZSBhbiBhcnJheT9cbiAgLy8gRGVsZWdhdGVzIHRvIEVDTUE1J3MgbmF0aXZlIEFycmF5LmlzQXJyYXlcbiAgXy5pc0FycmF5ID0gbmF0aXZlSXNBcnJheSB8fCBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gdG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBBcnJheV0nO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gdmFyaWFibGUgYW4gb2JqZWN0P1xuICBfLmlzT2JqZWN0ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIHR5cGUgPSB0eXBlb2Ygb2JqO1xuICAgIHJldHVybiB0eXBlID09PSAnZnVuY3Rpb24nIHx8IHR5cGUgPT09ICdvYmplY3QnICYmICEhb2JqO1xuICB9O1xuXG4gIC8vIEFkZCBzb21lIGlzVHlwZSBtZXRob2RzOiBpc0FyZ3VtZW50cywgaXNGdW5jdGlvbiwgaXNTdHJpbmcsIGlzTnVtYmVyLCBpc0RhdGUsIGlzUmVnRXhwLlxuICBfLmVhY2goWydBcmd1bWVudHMnLCAnRnVuY3Rpb24nLCAnU3RyaW5nJywgJ051bWJlcicsICdEYXRlJywgJ1JlZ0V4cCddLCBmdW5jdGlvbihuYW1lKSB7XG4gICAgX1snaXMnICsgbmFtZV0gPSBmdW5jdGlvbihvYmopIHtcbiAgICAgIHJldHVybiB0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0ICcgKyBuYW1lICsgJ10nO1xuICAgIH07XG4gIH0pO1xuXG4gIC8vIERlZmluZSBhIGZhbGxiYWNrIHZlcnNpb24gb2YgdGhlIG1ldGhvZCBpbiBicm93c2VycyAoYWhlbSwgSUUpLCB3aGVyZVxuICAvLyB0aGVyZSBpc24ndCBhbnkgaW5zcGVjdGFibGUgXCJBcmd1bWVudHNcIiB0eXBlLlxuICBpZiAoIV8uaXNBcmd1bWVudHMoYXJndW1lbnRzKSkge1xuICAgIF8uaXNBcmd1bWVudHMgPSBmdW5jdGlvbihvYmopIHtcbiAgICAgIHJldHVybiBfLmhhcyhvYmosICdjYWxsZWUnKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gT3B0aW1pemUgYGlzRnVuY3Rpb25gIGlmIGFwcHJvcHJpYXRlLiBXb3JrIGFyb3VuZCBhbiBJRSAxMSBidWcuXG4gIGlmICh0eXBlb2YgLy4vICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgXy5pc0Z1bmN0aW9uID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PSAnZnVuY3Rpb24nIHx8IGZhbHNlO1xuICAgIH07XG4gIH1cblxuICAvLyBJcyBhIGdpdmVuIG9iamVjdCBhIGZpbml0ZSBudW1iZXI/XG4gIF8uaXNGaW5pdGUgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gaXNGaW5pdGUob2JqKSAmJiAhaXNOYU4ocGFyc2VGbG9hdChvYmopKTtcbiAgfTtcblxuICAvLyBJcyB0aGUgZ2l2ZW4gdmFsdWUgYE5hTmA/IChOYU4gaXMgdGhlIG9ubHkgbnVtYmVyIHdoaWNoIGRvZXMgbm90IGVxdWFsIGl0c2VsZikuXG4gIF8uaXNOYU4gPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gXy5pc051bWJlcihvYmopICYmIG9iaiAhPT0gK29iajtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhbHVlIGEgYm9vbGVhbj9cbiAgXy5pc0Jvb2xlYW4gPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gb2JqID09PSB0cnVlIHx8IG9iaiA9PT0gZmFsc2UgfHwgdG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBCb29sZWFuXSc7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YWx1ZSBlcXVhbCB0byBudWxsP1xuICBfLmlzTnVsbCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBvYmogPT09IG51bGw7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YXJpYWJsZSB1bmRlZmluZWQ/XG4gIF8uaXNVbmRlZmluZWQgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gb2JqID09PSB2b2lkIDA7XG4gIH07XG5cbiAgLy8gU2hvcnRjdXQgZnVuY3Rpb24gZm9yIGNoZWNraW5nIGlmIGFuIG9iamVjdCBoYXMgYSBnaXZlbiBwcm9wZXJ0eSBkaXJlY3RseVxuICAvLyBvbiBpdHNlbGYgKGluIG90aGVyIHdvcmRzLCBub3Qgb24gYSBwcm90b3R5cGUpLlxuICBfLmhhcyA9IGZ1bmN0aW9uKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIG9iaiAhPSBudWxsICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpO1xuICB9O1xuXG4gIC8vIFV0aWxpdHkgRnVuY3Rpb25zXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gUnVuIFVuZGVyc2NvcmUuanMgaW4gKm5vQ29uZmxpY3QqIG1vZGUsIHJldHVybmluZyB0aGUgYF9gIHZhcmlhYmxlIHRvIGl0c1xuICAvLyBwcmV2aW91cyBvd25lci4gUmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgVW5kZXJzY29yZSBvYmplY3QuXG4gIF8ubm9Db25mbGljdCA9IGZ1bmN0aW9uKCkge1xuICAgIHJvb3QuXyA9IHByZXZpb3VzVW5kZXJzY29yZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvLyBLZWVwIHRoZSBpZGVudGl0eSBmdW5jdGlvbiBhcm91bmQgZm9yIGRlZmF1bHQgaXRlcmF0ZWVzLlxuICBfLmlkZW50aXR5ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH07XG5cbiAgXy5jb25zdGFudCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gIH07XG5cbiAgXy5ub29wID0gZnVuY3Rpb24oKXt9O1xuXG4gIF8ucHJvcGVydHkgPSBmdW5jdGlvbihrZXkpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24ob2JqKSB7XG4gICAgICByZXR1cm4gb2JqW2tleV07XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgcHJlZGljYXRlIGZvciBjaGVja2luZyB3aGV0aGVyIGFuIG9iamVjdCBoYXMgYSBnaXZlbiBzZXQgb2YgYGtleTp2YWx1ZWAgcGFpcnMuXG4gIF8ubWF0Y2hlcyA9IGZ1bmN0aW9uKGF0dHJzKSB7XG4gICAgdmFyIHBhaXJzID0gXy5wYWlycyhhdHRycyksIGxlbmd0aCA9IHBhaXJzLmxlbmd0aDtcbiAgICByZXR1cm4gZnVuY3Rpb24ob2JqKSB7XG4gICAgICBpZiAob2JqID09IG51bGwpIHJldHVybiAhbGVuZ3RoO1xuICAgICAgb2JqID0gbmV3IE9iamVjdChvYmopO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgcGFpciA9IHBhaXJzW2ldLCBrZXkgPSBwYWlyWzBdO1xuICAgICAgICBpZiAocGFpclsxXSAhPT0gb2JqW2tleV0gfHwgIShrZXkgaW4gb2JqKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgfTtcblxuICAvLyBSdW4gYSBmdW5jdGlvbiAqKm4qKiB0aW1lcy5cbiAgXy50aW1lcyA9IGZ1bmN0aW9uKG4sIGl0ZXJhdGVlLCBjb250ZXh0KSB7XG4gICAgdmFyIGFjY3VtID0gQXJyYXkoTWF0aC5tYXgoMCwgbikpO1xuICAgIGl0ZXJhdGVlID0gY3JlYXRlQ2FsbGJhY2soaXRlcmF0ZWUsIGNvbnRleHQsIDEpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSsrKSBhY2N1bVtpXSA9IGl0ZXJhdGVlKGkpO1xuICAgIHJldHVybiBhY2N1bTtcbiAgfTtcblxuICAvLyBSZXR1cm4gYSByYW5kb20gaW50ZWdlciBiZXR3ZWVuIG1pbiBhbmQgbWF4IChpbmNsdXNpdmUpLlxuICBfLnJhbmRvbSA9IGZ1bmN0aW9uKG1pbiwgbWF4KSB7XG4gICAgaWYgKG1heCA9PSBudWxsKSB7XG4gICAgICBtYXggPSBtaW47XG4gICAgICBtaW4gPSAwO1xuICAgIH1cbiAgICByZXR1cm4gbWluICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbiArIDEpKTtcbiAgfTtcblxuICAvLyBBIChwb3NzaWJseSBmYXN0ZXIpIHdheSB0byBnZXQgdGhlIGN1cnJlbnQgdGltZXN0YW1wIGFzIGFuIGludGVnZXIuXG4gIF8ubm93ID0gRGF0ZS5ub3cgfHwgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICB9O1xuXG4gICAvLyBMaXN0IG9mIEhUTUwgZW50aXRpZXMgZm9yIGVzY2FwaW5nLlxuICB2YXIgZXNjYXBlTWFwID0ge1xuICAgICcmJzogJyZhbXA7JyxcbiAgICAnPCc6ICcmbHQ7JyxcbiAgICAnPic6ICcmZ3Q7JyxcbiAgICAnXCInOiAnJnF1b3Q7JyxcbiAgICBcIidcIjogJyYjeDI3OycsXG4gICAgJ2AnOiAnJiN4NjA7J1xuICB9O1xuICB2YXIgdW5lc2NhcGVNYXAgPSBfLmludmVydChlc2NhcGVNYXApO1xuXG4gIC8vIEZ1bmN0aW9ucyBmb3IgZXNjYXBpbmcgYW5kIHVuZXNjYXBpbmcgc3RyaW5ncyB0by9mcm9tIEhUTUwgaW50ZXJwb2xhdGlvbi5cbiAgdmFyIGNyZWF0ZUVzY2FwZXIgPSBmdW5jdGlvbihtYXApIHtcbiAgICB2YXIgZXNjYXBlciA9IGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICByZXR1cm4gbWFwW21hdGNoXTtcbiAgICB9O1xuICAgIC8vIFJlZ2V4ZXMgZm9yIGlkZW50aWZ5aW5nIGEga2V5IHRoYXQgbmVlZHMgdG8gYmUgZXNjYXBlZFxuICAgIHZhciBzb3VyY2UgPSAnKD86JyArIF8ua2V5cyhtYXApLmpvaW4oJ3wnKSArICcpJztcbiAgICB2YXIgdGVzdFJlZ2V4cCA9IFJlZ0V4cChzb3VyY2UpO1xuICAgIHZhciByZXBsYWNlUmVnZXhwID0gUmVnRXhwKHNvdXJjZSwgJ2cnKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICBzdHJpbmcgPSBzdHJpbmcgPT0gbnVsbCA/ICcnIDogJycgKyBzdHJpbmc7XG4gICAgICByZXR1cm4gdGVzdFJlZ2V4cC50ZXN0KHN0cmluZykgPyBzdHJpbmcucmVwbGFjZShyZXBsYWNlUmVnZXhwLCBlc2NhcGVyKSA6IHN0cmluZztcbiAgICB9O1xuICB9O1xuICBfLmVzY2FwZSA9IGNyZWF0ZUVzY2FwZXIoZXNjYXBlTWFwKTtcbiAgXy51bmVzY2FwZSA9IGNyZWF0ZUVzY2FwZXIodW5lc2NhcGVNYXApO1xuXG4gIC8vIElmIHRoZSB2YWx1ZSBvZiB0aGUgbmFtZWQgYHByb3BlcnR5YCBpcyBhIGZ1bmN0aW9uIHRoZW4gaW52b2tlIGl0IHdpdGggdGhlXG4gIC8vIGBvYmplY3RgIGFzIGNvbnRleHQ7IG90aGVyd2lzZSwgcmV0dXJuIGl0LlxuICBfLnJlc3VsdCA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICBpZiAob2JqZWN0ID09IG51bGwpIHJldHVybiB2b2lkIDA7XG4gICAgdmFyIHZhbHVlID0gb2JqZWN0W3Byb3BlcnR5XTtcbiAgICByZXR1cm4gXy5pc0Z1bmN0aW9uKHZhbHVlKSA/IG9iamVjdFtwcm9wZXJ0eV0oKSA6IHZhbHVlO1xuICB9O1xuXG4gIC8vIEdlbmVyYXRlIGEgdW5pcXVlIGludGVnZXIgaWQgKHVuaXF1ZSB3aXRoaW4gdGhlIGVudGlyZSBjbGllbnQgc2Vzc2lvbikuXG4gIC8vIFVzZWZ1bCBmb3IgdGVtcG9yYXJ5IERPTSBpZHMuXG4gIHZhciBpZENvdW50ZXIgPSAwO1xuICBfLnVuaXF1ZUlkID0gZnVuY3Rpb24ocHJlZml4KSB7XG4gICAgdmFyIGlkID0gKytpZENvdW50ZXIgKyAnJztcbiAgICByZXR1cm4gcHJlZml4ID8gcHJlZml4ICsgaWQgOiBpZDtcbiAgfTtcblxuICAvLyBCeSBkZWZhdWx0LCBVbmRlcnNjb3JlIHVzZXMgRVJCLXN0eWxlIHRlbXBsYXRlIGRlbGltaXRlcnMsIGNoYW5nZSB0aGVcbiAgLy8gZm9sbG93aW5nIHRlbXBsYXRlIHNldHRpbmdzIHRvIHVzZSBhbHRlcm5hdGl2ZSBkZWxpbWl0ZXJzLlxuICBfLnRlbXBsYXRlU2V0dGluZ3MgPSB7XG4gICAgZXZhbHVhdGUgICAgOiAvPCUoW1xcc1xcU10rPyklPi9nLFxuICAgIGludGVycG9sYXRlIDogLzwlPShbXFxzXFxTXSs/KSU+L2csXG4gICAgZXNjYXBlICAgICAgOiAvPCUtKFtcXHNcXFNdKz8pJT4vZ1xuICB9O1xuXG4gIC8vIFdoZW4gY3VzdG9taXppbmcgYHRlbXBsYXRlU2V0dGluZ3NgLCBpZiB5b3UgZG9uJ3Qgd2FudCB0byBkZWZpbmUgYW5cbiAgLy8gaW50ZXJwb2xhdGlvbiwgZXZhbHVhdGlvbiBvciBlc2NhcGluZyByZWdleCwgd2UgbmVlZCBvbmUgdGhhdCBpc1xuICAvLyBndWFyYW50ZWVkIG5vdCB0byBtYXRjaC5cbiAgdmFyIG5vTWF0Y2ggPSAvKC4pXi87XG5cbiAgLy8gQ2VydGFpbiBjaGFyYWN0ZXJzIG5lZWQgdG8gYmUgZXNjYXBlZCBzbyB0aGF0IHRoZXkgY2FuIGJlIHB1dCBpbnRvIGFcbiAgLy8gc3RyaW5nIGxpdGVyYWwuXG4gIHZhciBlc2NhcGVzID0ge1xuICAgIFwiJ1wiOiAgICAgIFwiJ1wiLFxuICAgICdcXFxcJzogICAgICdcXFxcJyxcbiAgICAnXFxyJzogICAgICdyJyxcbiAgICAnXFxuJzogICAgICduJyxcbiAgICAnXFx1MjAyOCc6ICd1MjAyOCcsXG4gICAgJ1xcdTIwMjknOiAndTIwMjknXG4gIH07XG5cbiAgdmFyIGVzY2FwZXIgPSAvXFxcXHwnfFxccnxcXG58XFx1MjAyOHxcXHUyMDI5L2c7XG5cbiAgdmFyIGVzY2FwZUNoYXIgPSBmdW5jdGlvbihtYXRjaCkge1xuICAgIHJldHVybiAnXFxcXCcgKyBlc2NhcGVzW21hdGNoXTtcbiAgfTtcblxuICAvLyBKYXZhU2NyaXB0IG1pY3JvLXRlbXBsYXRpbmcsIHNpbWlsYXIgdG8gSm9obiBSZXNpZydzIGltcGxlbWVudGF0aW9uLlxuICAvLyBVbmRlcnNjb3JlIHRlbXBsYXRpbmcgaGFuZGxlcyBhcmJpdHJhcnkgZGVsaW1pdGVycywgcHJlc2VydmVzIHdoaXRlc3BhY2UsXG4gIC8vIGFuZCBjb3JyZWN0bHkgZXNjYXBlcyBxdW90ZXMgd2l0aGluIGludGVycG9sYXRlZCBjb2RlLlxuICAvLyBOQjogYG9sZFNldHRpbmdzYCBvbmx5IGV4aXN0cyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuXG4gIF8udGVtcGxhdGUgPSBmdW5jdGlvbih0ZXh0LCBzZXR0aW5ncywgb2xkU2V0dGluZ3MpIHtcbiAgICBpZiAoIXNldHRpbmdzICYmIG9sZFNldHRpbmdzKSBzZXR0aW5ncyA9IG9sZFNldHRpbmdzO1xuICAgIHNldHRpbmdzID0gXy5kZWZhdWx0cyh7fSwgc2V0dGluZ3MsIF8udGVtcGxhdGVTZXR0aW5ncyk7XG5cbiAgICAvLyBDb21iaW5lIGRlbGltaXRlcnMgaW50byBvbmUgcmVndWxhciBleHByZXNzaW9uIHZpYSBhbHRlcm5hdGlvbi5cbiAgICB2YXIgbWF0Y2hlciA9IFJlZ0V4cChbXG4gICAgICAoc2V0dGluZ3MuZXNjYXBlIHx8IG5vTWF0Y2gpLnNvdXJjZSxcbiAgICAgIChzZXR0aW5ncy5pbnRlcnBvbGF0ZSB8fCBub01hdGNoKS5zb3VyY2UsXG4gICAgICAoc2V0dGluZ3MuZXZhbHVhdGUgfHwgbm9NYXRjaCkuc291cmNlXG4gICAgXS5qb2luKCd8JykgKyAnfCQnLCAnZycpO1xuXG4gICAgLy8gQ29tcGlsZSB0aGUgdGVtcGxhdGUgc291cmNlLCBlc2NhcGluZyBzdHJpbmcgbGl0ZXJhbHMgYXBwcm9wcmlhdGVseS5cbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBzb3VyY2UgPSBcIl9fcCs9J1wiO1xuICAgIHRleHQucmVwbGFjZShtYXRjaGVyLCBmdW5jdGlvbihtYXRjaCwgZXNjYXBlLCBpbnRlcnBvbGF0ZSwgZXZhbHVhdGUsIG9mZnNldCkge1xuICAgICAgc291cmNlICs9IHRleHQuc2xpY2UoaW5kZXgsIG9mZnNldCkucmVwbGFjZShlc2NhcGVyLCBlc2NhcGVDaGFyKTtcbiAgICAgIGluZGV4ID0gb2Zmc2V0ICsgbWF0Y2gubGVuZ3RoO1xuXG4gICAgICBpZiAoZXNjYXBlKSB7XG4gICAgICAgIHNvdXJjZSArPSBcIicrXFxuKChfX3Q9KFwiICsgZXNjYXBlICsgXCIpKT09bnVsbD8nJzpfLmVzY2FwZShfX3QpKStcXG4nXCI7XG4gICAgICB9IGVsc2UgaWYgKGludGVycG9sYXRlKSB7XG4gICAgICAgIHNvdXJjZSArPSBcIicrXFxuKChfX3Q9KFwiICsgaW50ZXJwb2xhdGUgKyBcIikpPT1udWxsPycnOl9fdCkrXFxuJ1wiO1xuICAgICAgfSBlbHNlIGlmIChldmFsdWF0ZSkge1xuICAgICAgICBzb3VyY2UgKz0gXCInO1xcblwiICsgZXZhbHVhdGUgKyBcIlxcbl9fcCs9J1wiO1xuICAgICAgfVxuXG4gICAgICAvLyBBZG9iZSBWTXMgbmVlZCB0aGUgbWF0Y2ggcmV0dXJuZWQgdG8gcHJvZHVjZSB0aGUgY29ycmVjdCBvZmZlc3QuXG4gICAgICByZXR1cm4gbWF0Y2g7XG4gICAgfSk7XG4gICAgc291cmNlICs9IFwiJztcXG5cIjtcblxuICAgIC8vIElmIGEgdmFyaWFibGUgaXMgbm90IHNwZWNpZmllZCwgcGxhY2UgZGF0YSB2YWx1ZXMgaW4gbG9jYWwgc2NvcGUuXG4gICAgaWYgKCFzZXR0aW5ncy52YXJpYWJsZSkgc291cmNlID0gJ3dpdGgob2JqfHx7fSl7XFxuJyArIHNvdXJjZSArICd9XFxuJztcblxuICAgIHNvdXJjZSA9IFwidmFyIF9fdCxfX3A9JycsX19qPUFycmF5LnByb3RvdHlwZS5qb2luLFwiICtcbiAgICAgIFwicHJpbnQ9ZnVuY3Rpb24oKXtfX3ArPV9fai5jYWxsKGFyZ3VtZW50cywnJyk7fTtcXG5cIiArXG4gICAgICBzb3VyY2UgKyAncmV0dXJuIF9fcDtcXG4nO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciByZW5kZXIgPSBuZXcgRnVuY3Rpb24oc2V0dGluZ3MudmFyaWFibGUgfHwgJ29iaicsICdfJywgc291cmNlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBlLnNvdXJjZSA9IHNvdXJjZTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuXG4gICAgdmFyIHRlbXBsYXRlID0gZnVuY3Rpb24oZGF0YSkge1xuICAgICAgcmV0dXJuIHJlbmRlci5jYWxsKHRoaXMsIGRhdGEsIF8pO1xuICAgIH07XG5cbiAgICAvLyBQcm92aWRlIHRoZSBjb21waWxlZCBzb3VyY2UgYXMgYSBjb252ZW5pZW5jZSBmb3IgcHJlY29tcGlsYXRpb24uXG4gICAgdmFyIGFyZ3VtZW50ID0gc2V0dGluZ3MudmFyaWFibGUgfHwgJ29iaic7XG4gICAgdGVtcGxhdGUuc291cmNlID0gJ2Z1bmN0aW9uKCcgKyBhcmd1bWVudCArICcpe1xcbicgKyBzb3VyY2UgKyAnfSc7XG5cbiAgICByZXR1cm4gdGVtcGxhdGU7XG4gIH07XG5cbiAgLy8gQWRkIGEgXCJjaGFpblwiIGZ1bmN0aW9uLiBTdGFydCBjaGFpbmluZyBhIHdyYXBwZWQgVW5kZXJzY29yZSBvYmplY3QuXG4gIF8uY2hhaW4gPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBfKG9iaik7XG4gICAgaW5zdGFuY2UuX2NoYWluID0gdHJ1ZTtcbiAgICByZXR1cm4gaW5zdGFuY2U7XG4gIH07XG5cbiAgLy8gT09QXG4gIC8vIC0tLS0tLS0tLS0tLS0tLVxuICAvLyBJZiBVbmRlcnNjb3JlIGlzIGNhbGxlZCBhcyBhIGZ1bmN0aW9uLCBpdCByZXR1cm5zIGEgd3JhcHBlZCBvYmplY3QgdGhhdFxuICAvLyBjYW4gYmUgdXNlZCBPTy1zdHlsZS4gVGhpcyB3cmFwcGVyIGhvbGRzIGFsdGVyZWQgdmVyc2lvbnMgb2YgYWxsIHRoZVxuICAvLyB1bmRlcnNjb3JlIGZ1bmN0aW9ucy4gV3JhcHBlZCBvYmplY3RzIG1heSBiZSBjaGFpbmVkLlxuXG4gIC8vIEhlbHBlciBmdW5jdGlvbiB0byBjb250aW51ZSBjaGFpbmluZyBpbnRlcm1lZGlhdGUgcmVzdWx0cy5cbiAgdmFyIHJlc3VsdCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiB0aGlzLl9jaGFpbiA/IF8ob2JqKS5jaGFpbigpIDogb2JqO1xuICB9O1xuXG4gIC8vIEFkZCB5b3VyIG93biBjdXN0b20gZnVuY3Rpb25zIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdC5cbiAgXy5taXhpbiA9IGZ1bmN0aW9uKG9iaikge1xuICAgIF8uZWFjaChfLmZ1bmN0aW9ucyhvYmopLCBmdW5jdGlvbihuYW1lKSB7XG4gICAgICB2YXIgZnVuYyA9IF9bbmFtZV0gPSBvYmpbbmFtZV07XG4gICAgICBfLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYXJncyA9IFt0aGlzLl93cmFwcGVkXTtcbiAgICAgICAgcHVzaC5hcHBseShhcmdzLCBhcmd1bWVudHMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgZnVuYy5hcHBseShfLCBhcmdzKSk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIEFkZCBhbGwgb2YgdGhlIFVuZGVyc2NvcmUgZnVuY3Rpb25zIHRvIHRoZSB3cmFwcGVyIG9iamVjdC5cbiAgXy5taXhpbihfKTtcblxuICAvLyBBZGQgYWxsIG11dGF0b3IgQXJyYXkgZnVuY3Rpb25zIHRvIHRoZSB3cmFwcGVyLlxuICBfLmVhY2goWydwb3AnLCAncHVzaCcsICdyZXZlcnNlJywgJ3NoaWZ0JywgJ3NvcnQnLCAnc3BsaWNlJywgJ3Vuc2hpZnQnXSwgZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBtZXRob2QgPSBBcnJheVByb3RvW25hbWVdO1xuICAgIF8ucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgb2JqID0gdGhpcy5fd3JhcHBlZDtcbiAgICAgIG1ldGhvZC5hcHBseShvYmosIGFyZ3VtZW50cyk7XG4gICAgICBpZiAoKG5hbWUgPT09ICdzaGlmdCcgfHwgbmFtZSA9PT0gJ3NwbGljZScpICYmIG9iai5sZW5ndGggPT09IDApIGRlbGV0ZSBvYmpbMF07XG4gICAgICByZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgb2JqKTtcbiAgICB9O1xuICB9KTtcblxuICAvLyBBZGQgYWxsIGFjY2Vzc29yIEFycmF5IGZ1bmN0aW9ucyB0byB0aGUgd3JhcHBlci5cbiAgXy5lYWNoKFsnY29uY2F0JywgJ2pvaW4nLCAnc2xpY2UnXSwgZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBtZXRob2QgPSBBcnJheVByb3RvW25hbWVdO1xuICAgIF8ucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgbWV0aG9kLmFwcGx5KHRoaXMuX3dyYXBwZWQsIGFyZ3VtZW50cykpO1xuICAgIH07XG4gIH0pO1xuXG4gIC8vIEV4dHJhY3RzIHRoZSByZXN1bHQgZnJvbSBhIHdyYXBwZWQgYW5kIGNoYWluZWQgb2JqZWN0LlxuICBfLnByb3RvdHlwZS52YWx1ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl93cmFwcGVkO1xuICB9O1xuXG4gIC8vIEFNRCByZWdpc3RyYXRpb24gaGFwcGVucyBhdCB0aGUgZW5kIGZvciBjb21wYXRpYmlsaXR5IHdpdGggQU1EIGxvYWRlcnNcbiAgLy8gdGhhdCBtYXkgbm90IGVuZm9yY2UgbmV4dC10dXJuIHNlbWFudGljcyBvbiBtb2R1bGVzLiBFdmVuIHRob3VnaCBnZW5lcmFsXG4gIC8vIHByYWN0aWNlIGZvciBBTUQgcmVnaXN0cmF0aW9uIGlzIHRvIGJlIGFub255bW91cywgdW5kZXJzY29yZSByZWdpc3RlcnNcbiAgLy8gYXMgYSBuYW1lZCBtb2R1bGUgYmVjYXVzZSwgbGlrZSBqUXVlcnksIGl0IGlzIGEgYmFzZSBsaWJyYXJ5IHRoYXQgaXNcbiAgLy8gcG9wdWxhciBlbm91Z2ggdG8gYmUgYnVuZGxlZCBpbiBhIHRoaXJkIHBhcnR5IGxpYiwgYnV0IG5vdCBiZSBwYXJ0IG9mXG4gIC8vIGFuIEFNRCBsb2FkIHJlcXVlc3QuIFRob3NlIGNhc2VzIGNvdWxkIGdlbmVyYXRlIGFuIGVycm9yIHdoZW4gYW5cbiAgLy8gYW5vbnltb3VzIGRlZmluZSgpIGlzIGNhbGxlZCBvdXRzaWRlIG9mIGEgbG9hZGVyIHJlcXVlc3QuXG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICBkZWZpbmUoJ3VuZGVyc2NvcmUnLCBbXSwgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gXztcbiAgICB9KTtcbiAgfVxufS5jYWxsKHRoaXMpKTtcbiIsIl8gPSByZXF1aXJlIFwidW5kZXJzY29yZVwiXG5cbiMgY2FsY3VsYXRlIHRoZSBjb25zZW5zdXMgc2VxXG4jIFRPRE86IHZlcnkgbmFpdmUgd2F5XG5tb2R1bGUuZXhwb3J0cyA9IChzZXFzKSAtPlxuXG4gIHNlcXMgPSBzZXFzLm1hcCAoZWwpIC0+IGVsLmdldCBcInNlcVwiXG4gIG9jY3MgPSBuZXcgQXJyYXkgc2Vxcy5sZW5ndGhcblxuICAjIGNvdW50IHRoZSBvY2N1cmVuY2VzIG9mIHRoZSBjaGFycyBvZiBhIHBvc2l0aW9uXG4gIF8uZWFjaCBzZXFzLCAoZWwsaSkgLT5cbiAgICBfLmVhY2ggZWwsIChjaGFyLCBwb3MpIC0+XG4gICAgICBvY2NzW3Bvc10gPSB7fSB1bmxlc3Mgb2Njc1twb3NdP1xuICAgICAgb2Njc1twb3NdW2NoYXJdID0gMCB1bmxlc3Mgb2Njc1twb3NdW2NoYXJdP1xuICAgICAgb2Njc1twb3NdW2NoYXJdKytcblxuICAjIG5vdyBwaWNrIHRoZSBjaGFyIHdpdGggbW9zdCBvY2N1cmVuY2VzXG4gIF8ucmVkdWNlIG9jY3MsIChtZW1vLG9jYykgLT5cbiAgICBrZXlzID0gXy5rZXlzIG9jY1xuICAgIG1lbW8gKz0gIF8ubWF4IGtleXMsIChrZXkpIC0+IG9jY1trZXldXG4gICwgXCJcIlxuIiwiIyBmb3IgZWFjaCBzZXF1ZW5jZVxuIyAqIGNvdW50cyB0aGUgbWF0Y2hlcyB3aXRoIHRoZSBjb25zZW5zdXMgc2VxXG4jICogZXhjbHVkaW5nIGdhcHNcbiMgKiBpZGVudGl0eSA9IG1hdGNoZWRDaGFycyAvIHRvdGFsQ2hhcnMgKGV4Y2x1ZGluZyBnYXBzKVxubW9kdWxlLmV4cG9ydHMgPSBpZGVudGl0aXlDYWxjID0gKHNlcXMsIGNvbnNlbnN1cykgLT5cbiAgIyBkbyBub3RoaW5nIG9uIGludmFsaWQgY29uc2Vuc3VzXG4gIGlmIGNvbnNlbnN1cyBpcyB1bmRlZmluZWRcbiAgICBjb25zb2xlLndhcm4gXCJidWcgb24gY29uc2VudXMgY2FsY1wiXG4gICAgcmV0dXJuXG4gIHNlcXMuZWFjaCAoc2VxT2JqKSAtPlxuICAgIHNlcSA9IHNlcU9iai5nZXQgXCJzZXFcIlxuICAgIG1hdGNoZXMgPSAwXG4gICAgdG90YWwgPSAwXG4gICAgZm9yIGkgaW4gWzAuLnNlcS5sZW5ndGggLSAxXVxuICAgICAgaWYgc2VxW2ldIGlzbnQgXCItXCIgYW5kIGNvbnNlbnN1c1tpXSBpc250IFwiLVwiXG4gICAgICAgIHRvdGFsKytcbiAgICAgICAgbWF0Y2hlcysrIGlmIHNlcVtpXSBpcyBjb25zZW5zdXNbaV1cbiAgICBzZXFPYmouc2V0IFwiaWRlbnRpdHlcIiwgbWF0Y2hlcyAvIHRvdGFsXG4iLCJtb2R1bGUuZXhwb3J0cy5jb25zZW5zdXMgPSByZXF1aXJlIFwiLi9Db25zZW5zdXNDYWxjXCJcbiIsIk1vZGVsID0gcmVxdWlyZShcImJhY2tib25lLXRoaW5cIikuTW9kZWxcblxuIyB0aGlzIGlzIGFuIGV4YW1wbGUgb2YgaG93IG9uZSBjb3VsZCBjb2xvciB0aGUgTVNBXG4jIGZlZWwgZnJlZSB0byBjcmVhdGUgeW91ciBvd24gY29sb3Igc2NoZW1lIGluIHRoZSAvY3NzL3NjaGVtZXMgZm9sZGVyXG5tb2R1bGUuZXhwb3J0cyA9IENvbG9yYXRvciA9IE1vZGVsLmV4dGVuZFxuXG4gIGRlZmF1bHRzOlxuICAgIHNjaGVtZTogXCJ0YXlsb3JcIiAjIG5hbWUgb2YgeW91ciBjb2xvciBzY2hlbWUgKGNzcyBzdWZmaXgpXG4gICAgY29sb3JCYWNrZ3JvdW5kOiB0cnVlICMgb3RoZXJ3aXNlIG9ubHkgdGhlIHRleHQgd2lsbCBiZSBjb2xvcmVkXG4gICAgc2hvd0xvd2VyQ2FzZTogdHJ1ZSAjIHVzZWQgdG8gaGlkZSBhbmQgc2hvdyBsb3dlcmNhc2UgY2hhcnMgaW4gdGhlIG92ZXJ2aWV3Ym94XG4gICAgb3BhY2l0eTogMC42ICMgb3BhY2l0eSBmb3IgdGhlIHJlc2lkdWVzXG4iLCJNb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG5jb25zZW51cyA9IHJlcXVpcmUgXCIuLi9hbGdvL0NvbnNlbnN1c0NhbGNcIlxuXyA9IHJlcXVpcmUgXCJ1bmRlcnNjb3JlXCJcblxuIyBtb2RlbCBmb3IgY29sdW1uIHByb3BlcnRpZXMgKGxpa2UgdGhlaXIgaGlkZGVuIHN0YXRlKVxubW9kdWxlLmV4cG9ydHMgPSBDb2x1bW5zID0gTW9kZWwuZXh0ZW5kXG5cbiAgZGVmYXVsdHM6XG4gICAgc2NhbGluZzogXCJsaW5cIiAjIG9mIHRoZSBjb25zZXJ2YXRpb24gY2hhcnQgZS5nLiBcImxpblwiLCBcImV4cFwiLCBcImxvZ1wiXG5cbiAgaW5pdGlhbGl6ZTogLT5cbiAgICAjIGhpZGRlbiBjb2x1bW5zXG4gICAgQC5zZXQgXCJoaWRkZW5cIiwgW10gdW5sZXNzIEAuZ2V0KFwiaGlkZGVuXCIpP1xuXG4gICMgYXNzdW1lcyBoaWRkZW4gY29sdW1ucyBhcmUgc29ydGVkXG4gICMgQHJldHVybnMgbiBbaW50XSBudW1iZXIgb2YgaGlkZGVuIGNvbHVtbnMgdW50aWwgblxuICBjYWxjSGlkZGVuQ29sdW1uczogKG4pIC0+XG4gICAgaGlkZGVuID0gQGdldCBcImhpZGRlblwiXG4gICAgbmV3WCA9IG5cbiAgICBmb3IgaSBpbiBoaWRkZW5cbiAgICAgIGlmIGkgPD0gbmV3WFxuICAgICAgICBuZXdYKytcbiAgICBuZXdYIC0gblxuXG4gICMgY2FsY3MgY29uc2VydmF0aW9uXG4gIF9jYWxjQ29uc2VydmF0aW9uUHJlOiAoc2VxcykgLT5cblxuICAgICMgZW1lcmdlbmN5IGN1dG9mZlxuICAgIGNvbnNvbGUubG9nIHNlcXMubGVuZ3RoXG4gICAgaWYgc2Vxcy5sZW5ndGggPiAxMDAwXG4gICAgICByZXR1cm5cblxuICAgICMgY2FsYyBjb25zZW5zdXNcbiAgICBjb25zID0gY29uc2VudXMoc2VxcylcbiAgICBzZXFzID0gc2Vxcy5tYXAgKGVsKSAtPiBlbC5nZXQgXCJzZXFcIlxuICAgIG5NYXggPSAoXy5tYXggc2VxcywgKGVsKSAtPiBlbC5sZW5ndGgpLmxlbmd0aFxuXG4gICAgdG90YWwgPSBuZXcgQXJyYXkgbk1heFxuICAgIG1hdGNoZXMgPSBuZXcgQXJyYXkgbk1heFxuICAgICMgY2FsYyBkZXJpdmF0aW9uIGZyb20gY29uc2VudXNcbiAgICBfLmVhY2ggc2VxcywgKGVsLGkpIC0+XG4gICAgICBfLmVhY2ggZWwsIChjaGFyLCBwb3MpIC0+XG4gICAgICAgICNpZiBjb25zW3Bvc10gaXNudCBcIi1cIiBhbmQgbWF0Y2hlc1twb3NdIGlzbnQgZ2FwXG4gICAgICAgIHRvdGFsW3Bvc10gPSB0b3RhbFtwb3NdICsgMSB8fCAxXG4gICAgICAgIG1hdGNoZXNbcG9zXSA9IG1hdGNoZXNbcG9zXSArIDEgfHwgMSBpZiBjb25zW3Bvc10gaXMgY2hhclxuICAgIFttYXRjaGVzLCB0b3RhbCwgbk1heF1cblxuICBjYWxjQ29uc2VydmF0aW9uOiAoc2VxcykgLT5cbiAgICBpZiBAYXR0cmlidXRlcy5zY2FsaW5nIGlzIFwiZXhwXCJcbiAgICAgIHJldHVybiBAY2FsY0NvbnNlcnZhdGlvbkV4cCBzZXFzXG4gICAgZWxzZSBpZiBAYXR0cmlidXRlcy5zY2FsaW5nIGlzIFwibG9nXCJcbiAgICAgIHJldHVybiBAY2FsY0NvbnNlcnZhdGlvbkxvZyBzZXFzXG4gICAgZWxzZSBpZiBAYXR0cmlidXRlcy5zY2FsaW5nIGlzIFwibGluXCJcbiAgICAgIHJldHVybiBAY2FsY0NvbnNlcnZhdGlvbkxpbiBzZXFzXG5cbiAgIyAocGVyY2VudGFnZSBvZiBjaGFycyBvZiB0aGUgY29uc2VudXMgc2VxKVxuICBjYWxjQ29uc2VydmF0aW9uTGluOiAoc2VxcykgLT5cbiAgICBbbWF0Y2hlcyx0b3RhbCwgbk1heF0gPSBAX2NhbGNDb25zZXJ2YXRpb25QcmUgc2Vxc1xuICAgIGZvciBpIGluIFswIC4uIG5NYXggLSAxXVxuICAgICAgbWF0Y2hlc1tpXSA9IG1hdGNoZXNbaV0gLyB0b3RhbFtpXVxuICAgIEAuc2V0IFwiY29uc2VydlwiLCBtYXRjaGVzXG4gICAgbWF0Y2hlc1xuXG4gICMgKHBlcmNlbnRhZ2Ugb2YgY2hhcnMgb2YgdGhlIGNvbnNlbnVzIHNlcSlcbiAgY2FsY0NvbnNlcnZhdGlvbkxvZzogKHNlcXMpIC0+XG4gICAgW21hdGNoZXMsdG90YWwsIG5NYXhdID0gQF9jYWxjQ29uc2VydmF0aW9uUHJlIHNlcXNcbiAgICBmb3IgaSBpbiBbMCAuLiBuTWF4IC0gMV1cbiAgICAgIG1hdGNoZXNbaV0gPSBNYXRoLmxvZyhtYXRjaGVzW2ldICsgMSkgLyBNYXRoLmxvZyh0b3RhbFtpXSArIDEpXG4gICAgQC5zZXQgXCJjb25zZXJ2XCIsIG1hdGNoZXNcbiAgICBtYXRjaGVzXG5cbiAgY2FsY0NvbnNlcnZhdGlvbkV4cDogKHNlcXMpIC0+XG4gICAgW21hdGNoZXMsdG90YWwsIG5NYXhdID0gQF9jYWxjQ29uc2VydmF0aW9uUHJlIHNlcXNcbiAgICBmb3IgaSBpbiBbMCAuLiBuTWF4IC0gMV1cbiAgICAgIG1hdGNoZXNbaV0gPSBNYXRoLmV4cChtYXRjaGVzW2ldICsgMSkgLyBNYXRoLmV4cCh0b3RhbFtpXSArIDEpXG4gICAgQC5zZXQgXCJjb25zZXJ2XCIsIG1hdGNoZXNcbiAgICBtYXRjaGVzXG4iLCJNb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG5cbiMgc2ltcGxlIHVzZXIgY29uZmlnXG5tb2R1bGUuZXhwb3J0cyA9IENvbmZpZyA9IE1vZGVsLmV4dGVuZFxuXG4gIGRlZmF1bHRzOlxuICAgIHJlZ2lzdGVyTW91c2VIb3ZlcjogZmFsc2UsXG4gICAgcmVnaXN0ZXJNb3VzZUNsaWNrczogdHJ1ZSxcbiAgICBpbXBvcnRQcm94eTogXCJodHRwczovL2NvcnMtYW55d2hlcmUuaGVyb2t1YXBwLmNvbS9cIlxuICAgIGV2ZW50QnVzOiB0cnVlXG4iLCJNb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG5jb25zZW51c0NhbGMgPSByZXF1aXJlIFwiLi4vYWxnby9Db25zZW5zdXNDYWxjXCJcblxuIyBzaW1wbHkgc2F2ZSB0aGUgY29uc2VudXMgc2VxdWVuY2VzIGdsb2JhbGx5XG5tb2R1bGUuZXhwb3J0cyA9IENvbnNlbnVzID0gTW9kZWwuZXh0ZW5kXG5cbiAgZGVmYXVsdHM6XG4gICAgY29uc2VudXMgOiBcIlwiXG5cbiAgZ2V0Q29uc2Vuc3VzOiAoc2VxcykgLT5cbiAgICAjIGVtZXJnZW5jeSBjdXRvZmZcbiAgICBpZiBzZXFzLmxlbmd0aCA+IDEwMDBcbiAgICAgIHJldHVyblxuXG4gICAgY29ucyA9IGNvbnNlbnVzQ2FsYyhzZXFzKVxuICAgIEAuc2V0IFwiY29uc2VudXNcIiwgY29uc1xuICAgIGNvbnNcbiIsIl8gPSByZXF1aXJlIFwidW5kZXJzY29yZVwiXG5Nb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG5cbiMgaG9sZHMgdGhlIGN1cnJlbnQgdXNlciBzZWxlY3Rpb25cblNlbGVjdGlvbiA9IE1vZGVsLmV4dGVuZFxuICBkZWZhdWx0czpcbiAgICB0eXBlOiBcInN1cGVyXCJcblxuUm93U2VsZWN0aW9uID0gU2VsZWN0aW9uLmV4dGVuZFxuICBkZWZhdWx0czogXy5leHRlbmQge30sIFNlbGVjdGlvbjo6LmRlZmF1bHRzLFxuICAgIHR5cGU6IFwicm93XCJcbiAgICBzZXFJZDogXCJcIlxuXG4gIGluUm93OiAoc2VxSWQpIC0+XG4gICAgc2VxSWQgaXMgQC5nZXQgXCJzZXFJZFwiXG5cbiAgaW5Db2x1bW46IChyb3dQb3MpIC0+XG4gICAgdHJ1ZVxuXG4gIGdldExlbmd0aDogLT5cbiAgICAxXG5cbkNvbHVtblNlbGVjdGlvbiA9IFNlbGVjdGlvbi5leHRlbmRcbiAgZGVmYXVsdHM6IF8uZXh0ZW5kIHt9LCBTZWxlY3Rpb246Oi5kZWZhdWx0cyxcbiAgICB0eXBlOiBcImNvbHVtblwiXG4gICAgeFN0YXJ0OiAtMVxuICAgIHhFbmQ6IC0xXG5cbiAgaW5Sb3c6ICgpIC0+XG4gICAgdHJ1ZVxuXG4gIGluQ29sdW1uOiAocm93UG9zKSAtPlxuICAgIHhTdGFydCA8PSByb3dQb3MgJiYgcm93UG9zIDw9IHhFbmRcblxuICBnZXRMZW5ndGg6IC0+XG4gICAgeEVuZCAtIHhTdGFydFxuXG4jIHBvcyBpcyBhIG1peGluIG9mIGNvbHVtbiBhbmQgcm93XG4jIHN0YXJ0IHdpdGggUm93IGFuZCBvbmx5IG92ZXJ3cml0ZSBcImluQ29sdW1uXCIgZnJvbSBDb2x1bW5cblBvc1NlbGVjdGlvbiA9IFJvd1NlbGVjdGlvbi5leHRlbmQgXy5leHRlbmQge30sXy5waWNrKENvbHVtblNlbGVjdGlvbixcImluQ29sdW1uXCIpLFxuICBfLnBpY2soQ29sdW1uU2VsZWN0aW9uLFwiZ2V0TGVuZ3RoXCIpXG5cbiAgIyBtZXJnZSBib3RoIGRlZmF1bHRzXG4gIGRlZmF1bHRzOiBfLmV4dGVuZCB7fSwgQ29sdW1uU2VsZWN0aW9uOjouZGVmYXVsdHMsIFJvd1NlbGVjdGlvbjo6LmRlZmF1bHRzLFxuICAgIHR5cGU6IFwicG9zXCJcblxubW9kdWxlLmV4cG9ydHMuc2VsID0gU2VsZWN0aW9uXG5tb2R1bGUuZXhwb3J0cy5wb3NzZWwgPSBQb3NTZWxlY3Rpb25cbm1vZHVsZS5leHBvcnRzLnJvd3NlbCA9IFJvd1NlbGVjdGlvblxubW9kdWxlLmV4cG9ydHMuY29sdW1uc2VsID0gQ29sdW1uU2VsZWN0aW9uXG4iLCJzZWwgPSByZXF1aXJlIFwiLi9TZWxlY3Rpb25cIlxuXyA9IHJlcXVpcmUgXCJ1bmRlcnNjb3JlXCJcbkNvbGxlY3Rpb24gPSByZXF1aXJlKFwiYmFja2JvbmUtdGhpblwiKS5Db2xsZWN0aW9uXG5cbiMgaG9sZHMgdGhlIGN1cnJlbnQgdXNlciBzZWxlY3Rpb25cbm1vZHVsZS5leHBvcnRzID0gU2VsZWN0aW9uTWFuYWdlciA9IENvbGxlY3Rpb24uZXh0ZW5kXG5cbiAgbW9kZWw6IHNlbC5zZWxcblxuICBpbml0aWFsaXplOiAoZGF0YSwgb3B0cykgLT5cbiAgICBAZyA9IG9wdHMuZ1xuXG4gICAgQGxpc3RlblRvIEBnLCBcInJlc2lkdWU6Y2xpY2tcIiwgKGUpIC0+XG4gICAgICBAX2hhbmRsZUUgZS5ldnQsIG5ldyBzZWwucG9zc2VsXG4gICAgICAgIHhTdGFydDogZS5yb3dQb3NcbiAgICAgICAgeEVuZDogZS5yb3dQb3NcbiAgICAgICAgc2VxSWQ6IGUuc2VxSWRcblxuICAgIEBsaXN0ZW5UbyBAZywgXCJyb3c6Y2xpY2tcIiwgKGUpIC0+XG4gICAgICBAX2hhbmRsZUUgZS5ldnQsIG5ldyBzZWwucm93c2VsXG4gICAgICAgIHhTdGFydDogZS5yb3dQb3NcbiAgICAgICAgeEVuZDogZS5yb3dQb3NcbiAgICAgICAgc2VxSWQ6IGUuc2VxSWRcblxuICAgIEBsaXN0ZW5UbyBAZywgXCJjb2x1bW46Y2xpY2tcIiwgKGUpIC0+XG4gICAgICBAX2hhbmRsZUUgZS5ldnQsIG5ldyBzZWwuY29sdW1uc2VsXG4gICAgICAgIHhTdGFydDogZS5yb3dQb3NcbiAgICAgICAgeEVuZDogZS5yb3dQb3MgKyBlLnN0ZXBTaXplIC0gMVxuXG4gICAgI0BsaXN0ZW5UbyBALCBcImFkZCByZXNldFwiLCAoZSkgLT5cbiAgICAgICNAX3JlZHVjZUNvbHVtbnMoKVxuXG4gIGdldFNlbEZvclJvdzogKHNlcUlkKSAtPlxuICAgIEBmaWx0ZXIgKGVsKSAtPiBlbC5pblJvdyBzZXFJZFxuXG4gIGdldFNlbEZvckNvbHVtbnM6IChyb3dQb3MpIC0+XG4gICAgQGZpbHRlciAoZWwpIC0+IGVsLmluQ29sdW1uIHJvd1Bvc1xuXG4gICMgQHJldHVybnMgYXJyYXkgb2YgYWxsIHNlbGVjdGVkIHJlc2lkdWVzIGZvciBhIHJvd1xuICBnZXRCbG9ja3NGb3JSb3c6IChzZXFJZCwgbWF4TGVuKSAtPlxuICAgIHNlbGlzID0gQGZpbHRlciAoZWwpIC0+IGVsLmluUm93IHNlcUlkXG4gICAgYmxvY2tzID0gW11cbiAgICBmb3Igc2VsaSBpbiBzZWxpc1xuICAgICAgaWYgc2VsaS5hdHRyaWJ1dGVzLnR5cGUgaXMgXCJyb3dcIlxuICAgICAgICBibG9ja3MgPSBbMC4ubWF4TGVuXVxuICAgICAgICBicmVha1xuICAgICAgZWxzZVxuICAgICAgICBibG9ja3MgPSBibG9ja3MuY29uY2F0IFtzZWxpLmF0dHJpYnV0ZXMueFN0YXJ0IC4uIHNlbGkuYXR0cmlidXRlcy54RW5kXVxuICAgIGJsb2Nrc1xuXG4gICMgQHJldHVybnMgYXJyYXkgd2l0aCBhbGwgY29sdW1ucyBiZWluZyBzZWxlY3RlZFxuICAjIGV4YW1wbGU6IDAtNC4uLiAxMi0xNCBzZWxlY3RlZCAtPiBbMCwxLDIsMyw0LDEyLDEzLDE0XVxuICBnZXRBbGxDb2x1bW5CbG9ja3M6IChjb25mKSAtPlxuICAgIG1heExlbiA9IGNvbmYubWF4TGVuXG4gICAgd2l0aFBvcyA9IGNvbmYud2l0aFBvc1xuICAgIGJsb2NrcyA9IFtdXG4gICAgaWYgY29uZi53aXRoUG9zXG4gICAgICBmaWx0ZXJlZCA9IChAZmlsdGVyIChlbCkgLT4gZWwuZ2V0KCd4U3RhcnQnKT8gKVxuICAgIGVsc2VcbiAgICAgIGZpbHRlcmVkID0gKEBmaWx0ZXIgKGVsKSAtPiBlbC5nZXQoJ3R5cGUnKSBpcyBcImNvbHVtblwiKVxuICAgIGZvciBzZWxpIGluIGZpbHRlcmVkXG4gICAgICBibG9ja3MgPSBibG9ja3MuY29uY2F0IFtzZWxpLmF0dHJpYnV0ZXMueFN0YXJ0Li5zZWxpLmF0dHJpYnV0ZXMueEVuZF1cbiAgICBibG9ja3MgPSBfLnVuaXEgYmxvY2tzXG4gICAgcmV0dXJuIGJsb2Nrc1xuXG4gICMgaW52ZXJ0cyB0aGUgY3VycmVudCBzZWxlY3Rpb24gZm9yIGNvbHVtbnNcbiAgIyBAcGFyYW0gcm93cyBbQXJyYXldIGFsbCBhdmFpbGFibGUgc2VxSWRcbiAgaW52ZXJ0Um93OiAocm93cykgLT5cbiAgICBzZWxSb3dzID0gQHdoZXJlKHR5cGU6XCJyb3dcIilcbiAgICBzZWxSb3dzID0gXy5tYXAgc2VsUm93cywgKGVsKSAtPiBlbC5hdHRyaWJ1dGVzLnNlcUlkXG4gICAgaW52ZXJ0ZWQgPSBfLmZpbHRlciByb3dzLCAoZWwpIC0+XG4gICAgICByZXR1cm4gZmFsc2UgaWYgc2VsUm93cy5pbmRleE9mKGVsKSA+PSAwICMgZXhpc3Rpbmcgc2VsZWN0aW9uXG4gICAgICB0cnVlXG4gICAgIyBtYXNzIGluc2VydFxuICAgIHMgPSBbXVxuICAgIGZvciBlbCBpbiBpbnZlcnRlZFxuICAgICAgcy5wdXNoIG5ldyBzZWwucm93c2VsKHNlcUlkOmVsKVxuICAgIGNvbnNvbGUubG9nIHNcbiAgICBAcmVzZXQgc1xuXG4gICMgaW52ZXJ0cyB0aGUgY3VycmVudCBzZWxlY3Rpb24gZm9yIHJvd3NcbiAgIyBAcGFyYW0gcm93cyBbQXJyYXldIGFsbCBhdmFpbGFibGUgcm93cyAoMC4ubWF4Lmxlbmd0aClcbiAgaW52ZXJ0Q29sOiAoY29sdW1ucykgLT5cbiAgICBzZWxDb2x1bW5zID0gQHdoZXJlKHR5cGU6XCJjb2x1bW5cIilcbiAgICBzZWxDb2x1bW5zID0gXy5yZWR1Y2Ugc2VsQ29sdW1ucywgKG1lbW8sZWwpIC0+XG4gICAgICBtZW1vLmNvbmNhdCBbZWwuYXR0cmlidXRlcy54U3RhcnQgLi4gZWwuYXR0cmlidXRlcy54RW5kXVxuICAgICwgW11cbiAgICBpbnZlcnRlZCA9IF8uZmlsdGVyIGNvbHVtbnMsIChlbCkgLT5cbiAgICAgIGlmIHNlbENvbHVtbnMuaW5kZXhPZihlbCkgPj0gMFxuICAgICAgICAjIGV4aXN0aW5nIHNlbGVjdGlvblxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIHRydWVcbiAgICAjIG1hc3MgaW5zZXJ0XG4gICAgcmV0dXJuIGlmIGludmVydGVkLmxlbmd0aCA9PSAwXG4gICAgcyA9IFtdXG4gICAgY29uc29sZS5sb2cgaW52ZXJ0ZWRcbiAgICB4U3RhcnQgPSB4RW5kID0gaW52ZXJ0ZWRbMF1cbiAgICBmb3IgZWwgaW4gaW52ZXJ0ZWRcbiAgICAgIGlmIHhFbmQgKyAxIGlzIGVsXG4gICAgICAgICMgY29udGlndW91c1xuICAgICAgICB4RW5kID0gZWxcbiAgICAgIGVsc2VcbiAgICAgICAgIyBnYXAgYmV0d2VlblxuICAgICAgICBzLnB1c2ggbmV3IHNlbC5jb2x1bW5zZWwoeFN0YXJ0OnhTdGFydCwgeEVuZDogeEVuZClcbiAgICAgICAgeFN0YXJ0ID0geEVuZCA9IGVsXG4gICAgIyBjaGVjayBmb3IgbGFzdCBnYXBcbiAgICBzLnB1c2ggbmV3IHNlbC5jb2x1bW5zZWwoeFN0YXJ0OnhTdGFydCwgeEVuZDogaW52ZXJ0ZWRbaW52ZXJ0ZWQubGVuZ3RoIC0gMV0pIGlmIHhTdGFydCBpc250IHhFbmRcbiAgICBAcmVzZXQgc1xuXG4gICMgbWV0aG9kIHRvIGRlY2lkZSB3aGV0aGVyIHRvIHN0YXJ0IGEgbmV3IHNlbGVjdGlvblxuICAjIG9yIGFwcGVuZCB0byB0aGUgb2xkIG9uZSAoZGVwZW5kaW5nIHdoZXRoZXIgQ1RSTCB3YXMgcHJlc3NlZClcbiAgX2hhbmRsZUU6IChlLCBzZWxlY3Rpb24pIC0+XG4gICAgaWYgZS5jdHJsS2V5IG9yIGUubWV0YUtleVxuICAgICAgQGFkZCBzZWxlY3Rpb25cbiAgICBlbHNlXG4gICAgICBAcmVzZXQgW3NlbGVjdGlvbl1cblxuICAjIGV4cGVyaW1lbnRhbCByZWR1Y2UgbWV0aG9kIGZvciBjb2x1bW5zXG4gIF9yZWR1Y2VDb2x1bW5zOiAtPlxuICAgIEBlYWNoIChlbCwgaW5kZXgsIGFycikgLT5cbiAgICAgIGNvbHMgPSBfLmZpbHRlciBhcnIsIChlbCkgLT4gZWwuZ2V0KCd0eXBlJykgaXMgJ2NvbHVtbidcbiAgICAgIHhTdGFydCA9IGVsLmdldCgneFN0YXJ0JylcbiAgICAgIHhFbmQgPSBlbC5nZXQoJ3hFbmQnKVxuXG4gICAgICBsZWZ0cyA9IF8uZmlsdGVyIGNvbHMsIChlbCkgLT4gZWwuZ2V0KCd4RW5kJykgaXMgKHhTdGFydCAtIDEpXG4gICAgICBmb3IgbGVmdCBpbiBsZWZ0c1xuICAgICAgICBsZWZ0LnNldCAneEVuZCcsIHhTdGFydFxuXG4gICAgICByaWdodHMgPSBfLmZpbHRlciBjb2xzLCAoZWwpIC0+IGVsLmdldCgneFN0YXJ0JykgaXMgKHhFbmQgKyAxKVxuICAgICAgZm9yIHJpZ2h0IGluIHJpZ2h0c1xuICAgICAgICByaWdodC5zZXQgJ3hTdGFydCcsIHhFbmRcblxuICAgICAgaWYgbGVmdHMubGVuZ3RoID4gMCBvciByaWdodHMubGVuZ3RoID4gMFxuICAgICAgICBjb25zb2xlLmxvZyBcInJlbW92ZWQgZWxcIlxuICAgICAgICBlbC5jb2xsZWN0aW9uLnJlbW92ZSBlbFxuIiwiTW9kZWwgPSByZXF1aXJlKFwiYmFja2JvbmUtdGhpblwiKS5Nb2RlbFxuXG4jIHZpc2libGUgYXJlYXNcbm1vZHVsZS5leHBvcnRzID0gVmlzaWJpbGl0eSA9IE1vZGVsLmV4dGVuZFxuXG4gIGRlZmF1bHRzOlxuXG4gICAgIyBmb3IgdGhlIFN0YWdlXG4gICAgb3ZlcnZpZXdCb3g6IDMwXG4gICAgaGVhZGVyQm94OiAtMVxuICAgIGFsaWdubWVudEJvZHk6IDBcbiIsIk1vZGVsID0gcmVxdWlyZShcImJhY2tib25lLXRoaW5cIikuTW9kZWxcblxuIyB2aXNpYmxlIGFyZWFzXG5tb2R1bGUuZXhwb3J0cyA9IFZpc2liaWxpdHkgPSBNb2RlbC5leHRlbmRcblxuICBkZWZhdWx0czpcbiAgICBzZXF1ZW5jZXM6IHRydWVcbiAgICBtYXJrZXJzOiB0cnVlXG4gICAgbWV0YWNlbGw6IGZhbHNlXG4gICAgY29uc2VydjogdHJ1ZVxuICAgIG92ZXJ2aWV3Ym94OiBmYWxzZVxuXG4gICAgIyBhYm91dCB0aGUgbGFiZWxzXG4gICAgbGFiZWxzOiB0cnVlXG4gICAgbGFiZWxOYW1lOiB0cnVlXG4gICAgbGFiZWxJZDogdHJ1ZVxuICAgIGxhYmVsUGFydGl0aW9uOiBmYWxzZVxuICAgIGxhYmVsQ2hlY2tib3g6IGZhbHNlXG4iLCJNb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG4jIHBpeGVsIHByb3BlcnRpZXMgZm9yIHNvbWUgY29tcG9uZW50c1xubW9kdWxlLmV4cG9ydHMgPSBab29tZXIgPSBNb2RlbC5leHRlbmRcblxuICBjb25zdHJ1Y3RvcjogKGF0dHJpYnV0ZXMsb3B0aW9ucykgLT5cbiAgICBNb2RlbC5hcHBseSBALCBhcmd1bWVudHNcbiAgICBAZyA9IG9wdGlvbnMuZ1xuICAgIEBcblxuICBkZWZhdWx0czpcblxuICAgICMgZ2VuZXJhbFxuICAgIGFsaWdubWVudFdpZHRoOiBcImF1dG9cIlxuICAgIGFsaWdubWVudEhlaWdodDogMTk1XG4gICAgY29sdW1uV2lkdGg6IDE1XG4gICAgcm93SGVpZ2h0OiAxNVxuXG4gICAgIyBsYWJlbHNcbiAgICBsYWJlbFdpZHRoOiAxMDBcbiAgICBtZXRhV2lkdGg6IDEwMFxuICAgIHRleHRWaXNpYmxlOiB0cnVlXG4gICAgbGFiZWxJZExlbmd0aDogMzBcbiAgICBsYWJlbEZvbnRzaXplOiBcIjEzcHhcIlxuICAgIGxhYmVsTGluZUhlaWdodDogXCIxM3B4XCJcblxuICAgICMgbWFya2VyXG4gICAgbWFya2VyRm9udHNpemU6IFwiMTBweFwiXG4gICAgc3RlcFNpemU6IDFcbiAgICBtYXJrZXJTdGVwU2l6ZTogMlxuXG4gICAgIyBjYW52YXNcbiAgICByZXNpZHVlRm9udDogXCIxM3B4IG1vbm9cIlxuICAgIGNhbnZhc0V2ZW50U2NhbGU6IDFcblxuICAgIGJveFJlY3RIZWlnaHQ6IDVcbiAgICBib3hSZWN0V2lkdGg6IDVcblxuICAgICMgbWVudVxuICAgIG1lbnVGb250c2l6ZTogXCIyMHB4XCJcbiAgICBtZW51SXRlbUZvbnRzaXplOiBcIjE4cHhcIlxuICAgIG1lbnVJdGVtTGluZUhlaWdodDogXCIxOHB4XCJcbiAgICBtZW51TWFyZ2luTGVmdDogXCI1cHhcIlxuICAgIG1lbnVQYWRkaW5nOiBcIjNweCA1cHggM3B4IDVweFwiXG5cbiAgICAjIGludGVybmFsIHByb3BzXG4gICAgX2FsaWdubWVudFNjcm9sbExlZnQ6IDBcbiAgICBfYWxpZ25tZW50U2Nyb2xsVG9wOiAwXG5cbiAgIyBAcGFyYW0gbiBbaW50XSBtYXhMZW5ndGggb2YgYWxsIHNlcXNcbiAgZ2V0QWxpZ25tZW50V2lkdGg6IChuKSAtPlxuICAgIGlmIEBnZXQoXCJhbGlnbm1lbnRXaWR0aFwiKSBpcyBcImF1dG9cIlxuICAgICAgQGdldChcImNvbHVtbldpZHRoXCIpICogblxuICAgIGVsc2VcbiAgICAgIEBnZXQgXCJhbGlnbm1lbnRXaWR0aFwiXG5cbiAgIyBAcGFyYW0gbiBbaW50XSBudW1iZXIgb2YgcmVzaWR1ZXMgdG8gc2Nyb2xsIHRvIHRoZSByaWdodFxuICBzZXRMZWZ0T2Zmc2V0OiAobikgLT5cbiAgICB2YWwgPSAobiAtIDEpICogQGdldCgnY29sdW1uV2lkdGgnKVxuICAgIHZhbCA9IE1hdGgubWF4IDAsIHZhbFxuICAgIEBzZXQgXCJfYWxpZ25tZW50U2Nyb2xsTGVmdFwiLCB2YWxcblxuICAjIEBwYXJhbSBuIFtpbnRdIHJvdyB0aGF0IHNob3VsZCBiZSBvbiB0b3BcbiAgc2V0VG9wT2Zmc2V0OiAobikgLT5cbiAgICB2YWwgPSAobiAtIDEpICogQGdldCgncm93SGVpZ2h0JylcbiAgICB2YWwgPSBNYXRoLm1heCAwLCB2YWxcbiAgICBAc2V0IFwiX2FsaWdubWVudFNjcm9sbFRvcFwiLHZhbFxuXG4gICMgbGVuZ3RoIG9mIGFsbCBlbGVtZW50cyBsZWZ0IHRvIHRoZSBtYWluIHNlcXVlbmNlIGJvZHk6IGxhYmVscywgbWV0YWNlbGwsIC4uXG4gIGdldExhYmVsV2lkdGg6IC0+XG4gICAgIHBhZGRpbmdMZWZ0ID0gMFxuICAgICBwYWRkaW5nTGVmdCArPSBAZ2V0IFwibGFiZWxXaWR0aFwiIGlmIEBnLnZpcy5nZXQgXCJsYWJlbHNcIlxuICAgICBwYWRkaW5nTGVmdCArPSBAZ2V0IFwibWV0YVdpZHRoXCIgaWYgQGcudmlzLmdldCBcIm1ldGFjZWxsXCJcbiAgICAgcmV0dXJuIHBhZGRpbmdMZWZ0XG5cbiAgX2FkanVzdFdpZHRoOiAoZWwsIG1vZGVsKSAtPlxuICAgIGlmIGVsLnBhcmVudE5vZGU/IGFuZCBlbC5wYXJlbnROb2RlLm9mZnNldFdpZHRoIGlzbnQgMFxuICAgICAgcGFyZW50V2lkdGggPSBlbC5wYXJlbnROb2RlLm9mZnNldFdpZHRoXG4gICAgZWxzZVxuICAgICAgcGFyZW50V2lkdGggPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoIC0gMzVcblxuICAgICMgVE9ETzogZGlydHkgaGFja1xuICAgIG1heFdpZHRoID0gcGFyZW50V2lkdGggLSBAZ2V0TGFiZWxXaWR0aCgpXG4gICAgY2FsY1dpZHRoID0gQGdldEFsaWdubWVudFdpZHRoKCBtb2RlbC5nZXRNYXhMZW5ndGgoKSAtIEBnLmNvbHVtbnMuZ2V0KCdoaWRkZW4nKS5sZW5ndGgpXG4gICAgdmFsID0gTWF0aC5taW4obWF4V2lkdGgsY2FsY1dpZHRoKVxuICAgICMgcm91bmQgdG8gYSB2YWxpZCBBQSBib3hcbiAgICB2YWwgPSBNYXRoLmZsb29yKCB2YWwgLyBAZ2V0KFwiY29sdW1uV2lkdGhcIikpICogQGdldChcImNvbHVtbldpZHRoXCIpXG4gICAgQHNldCBcImFsaWdubWVudFdpZHRoXCIsIHZhbFxuICAgICNlbC5zdHlsZS53aWR0aCA9IE1hdGgubWluIGNhbGNXaWR0aCwgbWF4V2lkdGhcblxuICAjIHVwZGF0ZXMgYm90aCBzY3JvbGwgcHJvcGVydGllcyAoaWYgbmVlZGVkKVxuICBfY2hlY2tTY3JvbGxpbmc6IChzY3JvbGxPYmosIG9wdHMpIC0+XG4gICAgeFNjcm9sbCA9IHNjcm9sbE9ialswXVxuICAgIHlTY3JvbGwgPSBzY3JvbGxPYmpbMV1cblxuICAgIEBzZXQgXCJfYWxpZ25tZW50U2Nyb2xsTGVmdFwiLCB4U2Nyb2xsLCBvcHRzXG4gICAgQHNldCBcIl9hbGlnbm1lbnRTY3JvbGxUb3BcIiwgeVNjcm9sbCwgb3B0c1xuIiwibW9kdWxlLmV4cG9ydHMubXNhID0gcmVxdWlyZShcIi4vbXNhXCIpXG5cbiMgbW9kZWxzXG5tb2R1bGUuZXhwb3J0cy5tb2RlbCA9IHJlcXVpcmUoXCIuL21vZGVsXCIpXG5cbiMgZXh0cmEgcGx1Z2lucywgZXh0ZW5zaW9uc1xubW9kdWxlLmV4cG9ydHMuYWxnbyA9IHJlcXVpcmUoXCIuL2FsZ29cIilcbm1vZHVsZS5leHBvcnRzLm1lbnUgPSByZXF1aXJlKFwiLi9tZW51XCIpXG5tb2R1bGUuZXhwb3J0cy51dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpXG5cbiMgcHJvYmFibHkgbmVlZGVkIG1vcmUgb2Z0ZW5cbm1vZHVsZS5leHBvcnRzLnNlbGVjdGlvbiA9IHJlcXVpcmUoXCIuL2cvc2VsZWN0aW9uL1NlbGVjdGlvblwiKVxubW9kdWxlLmV4cG9ydHMudmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS12aWV3alwiKVxubW9kdWxlLmV4cG9ydHMuYm9uZVZpZXcgPSByZXF1aXJlKFwiYmFja2JvbmUtY2hpbGRzXCIpXG5cbiMgY29udmVuaWVuY2Vcbm1vZHVsZS5leHBvcnRzLl8gPSByZXF1aXJlICd1bmRlcnNjb3JlJ1xubW9kdWxlLmV4cG9ydHMuJCA9IHJlcXVpcmUgJ2pib25lJ1xuXG5tb2R1bGUuZXhwb3J0cy52ZXJzaW9uID0gXCIwLjEuMFwiXG4iLCJib25lVmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS1jaGlsZHNcIilcblxuIyBtZW51IHZpZXdzXG5JbXBvcnRNZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvSW1wb3J0TWVudVwiXG5GaWx0ZXJNZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvRmlsdGVyTWVudVwiXG5TZWxlY3Rpb25NZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvU2VsZWN0aW9uTWVudVwiXG5WaXNNZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvVmlzTWVudVwiXG5Db2xvck1lbnUgPSByZXF1aXJlIFwiLi92aWV3cy9Db2xvck1lbnVcIlxuT3JkZXJpbmdNZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvT3JkZXJpbmdNZW51XCJcbkV4dHJhTWVudSA9IHJlcXVpcmUgXCIuL3ZpZXdzL0V4dHJhTWVudVwiXG5FeHBvcnRNZW51ID0gcmVxdWlyZSBcIi4vdmlld3MvRXhwb3J0TWVudVwiXG5IZWxwTWVudSA9IHJlcXVpcmUgXCIuL3ZpZXdzL0hlbHBNZW51XCJcblxuIyB0aGlzIHZlcnkgYmFzaWMgbWVudSBkZW1vbnN0cmF0ZXMgY2FsbHMgdG8gdGhlIE1TQSBjb21wb25lbnRcbm1vZHVsZS5leHBvcnRzID0gTWVudVZpZXcgPSBib25lVmlldy5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAbXNhID0gZGF0YS5tc2FcblxuICAgIEBhZGRWaWV3ICBcIjEwX2ltcG9ydFwiLCBuZXcgSW1wb3J0TWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZ1xuICAgIEBhZGRWaWV3ICBcIjIwX2ZpbHRlclwiLCBuZXcgRmlsdGVyTWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZ1xuICAgIEBhZGRWaWV3ICBcIjMwX3NlbGVjdGlvblwiLCBuZXcgU2VsZWN0aW9uTWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZ1xuICAgIEBhZGRWaWV3ICBcIjQwX3Zpc1wiLCBuZXcgVmlzTWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZ1xuICAgIEBhZGRWaWV3ICBcIjUwX2NvbG9yXCIsIG5ldyBDb2xvck1lbnUgbW9kZWw6IEBtc2Euc2VxcywgZzpAbXNhLmdcbiAgICBAYWRkVmlldyAgXCI2MF9vcmRlcmluZ1wiLCBuZXcgT3JkZXJpbmdNZW51IG1vZGVsOiBAbXNhLnNlcXMsIGc6QG1zYS5nXG4gICAgQGFkZFZpZXcgIFwiNzBfZXh0cmFcIiwgbmV3IEV4dHJhTWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZ1xuICAgIEBhZGRWaWV3ICBcIjgwX2V4cG9ydFwiLCBuZXcgRXhwb3J0TWVudSBtb2RlbDogQG1zYS5zZXFzLCBnOkBtc2EuZywgbXNhOkBtc2FcbiAgICBAYWRkVmlldyAgXCI5MF9oZWxwXCIsIG5ldyBIZWxwTWVudSAgZzpAbXNhLmdcblxuICByZW5kZXI6IC0+XG4gICAgQHJlbmRlclN1YnZpZXdzKClcbiAgICAjIG90aGVyXG4gICAgQGVsLnNldEF0dHJpYnV0ZSBcImNsYXNzXCIsIFwiYmlvanNfbXNhX21lbnViYXJcIlxuICAgIEBlbC5hcHBlbmRDaGlsZCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwicFwiKVxuIiwibW9kdWxlLmV4cG9ydHMuZGVmYXVsdG1lbnUgPSByZXF1aXJlKFwiLi9kZWZhdWx0bWVudVwiKVxubW9kdWxlLmV4cG9ydHMubWVudWJ1aWxkZXIgPSByZXF1aXJlKFwiLi9tZW51YnVpbGRlclwiKVxuIiwiQk1hdGggPSByZXF1aXJlIFwiLi4vdXRpbHMvYm1hdGhcIlxuamJvbmUgPSByZXF1aXJlIFwiamJvbmVcIlxudmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS12aWV3alwiKVxuXG4jamJvbmUuZm4uYWRkQ2xhc3MgPSAoY2xhc3NOYW1lKSAtPlxuIyAgZm9yIGkgaW4gWzAuLiBALmxlbmd0aCAtIDFdIGJ5IDFcbiMgICAgQFtpXS5jbGFzc0xpc3QuYWRkIGNsYXNzTmFtZVxuIyAgQFxuXG5tb2R1bGUuZXhwb3J0cyA9IE1lbnVCdWlsZGVyID0gdmlldy5leHRlbmRcblxuICAgIHNldE5hbWU6IChAbmFtZSkgLT5cbiAgICAgIEBfbm9kZXMgPSAgW11cblxuICAgIGFkZE5vZGU6IChsYWJlbCwgY2FsbGJhY2ssIGRhdGEpIC0+XG4gICAgICBzdHlsZSA9IGRhdGEuc3R5bGUgaWYgZGF0YT9cbiAgICAgIEBfbm9kZXMgPSBbXSB1bmxlc3MgQF9ub2Rlcz9cbiAgICAgIEBfbm9kZXMucHVzaCB7bGFiZWw6IGxhYmVsLCBjYWxsYmFjazogY2FsbGJhY2ssIHN0eWxlOiBzdHlsZX1cblxuICAgIGJ1aWxkRE9NOiAtPlxuICAgICAgQF9idWlsZE1cbiAgICAgICAgbm9kZXM6IEBfbm9kZXNcbiAgICAgICAgbmFtZTogQG5hbWVcblxuICAgIF9idWlsZE06IChkYXRhKSAtPlxuICAgICAgbm9kZXMgPSBkYXRhLm5vZGVzXG4gICAgICBuYW1lID0gZGF0YS5uYW1lXG5cbiAgICAgIG1lbnUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwiZGl2XCJcbiAgICAgIG1lbnUuY2xhc3NOYW1lID0gXCJkcm9wZG93biBkcm9wZG93bi10aXBcIlxuICAgICAgbWVudS5pZCA9IFwiYWRyb3AtXCIgKyBCTWF0aC51bmlxdWVJZCgpXG4gICAgICBtZW51LnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIlxuXG4gICAgICBtZW51VWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwidWxcIlxuICAgICAgbWVudVVsLmNsYXNzTmFtZSA9IFwiZHJvcGRvd24tbWVudVwiXG5cbiAgICAgICMgZHJvcGRvd24gbWVudVxuICAgICAgZm9yIG5vZGUgaW4gbm9kZXNcbiAgICAgICAgbGkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwibGlcIlxuXG4gICAgICAgIGxpLnRleHRDb250ZW50ID0gbm9kZS5sYWJlbFxuICAgICAgICBmb3Iga2V5LHN0eWxlIG9mIG5vZGUuc3R5bGVcbiAgICAgICAgICBsaS5zdHlsZVtrZXldID0gc3R5bGVcbiAgICAgICAgbGkuYWRkRXZlbnRMaXN0ZW5lciBcImNsaWNrXCIsIG5vZGUuY2FsbGJhY2tcbiAgICAgICAgaWYgQGc/XG4gICAgICAgICAgbGkuc3R5bGUubGluZUhlaWdodCA9IEBnLnpvb21lci5nZXQgXCJtZW51SXRlbUxpbmVIZWlnaHRcIlxuXG4gICAgICAgIG1lbnVVbC5hcHBlbmRDaGlsZCBsaVxuXG4gICAgICBtZW51LmFwcGVuZENoaWxkIG1lbnVVbFxuXG4gICAgICBmcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpXG4gICAgICAjIGRpcGxheSBpdFxuICAgICAgZGlzcGxheWVkQnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcImFcIlxuICAgICAgZGlzcGxheWVkQnV0dG9uLnRleHRDb250ZW50ID0gbmFtZVxuICAgICAgZGlzcGxheWVkQnV0dG9uLmNsYXNzTmFtZSA9IFwiYmlvanNfbXNhX21lbnViYXJfYWxpbmtcIlxuXG4gICAgICAjIHRpbnkgc3R5bGVcbiAgICAgIGlmIEBnP1xuICAgICAgICBtZW51VWwuc3R5bGUuZm9udFNpemUgPSBAZy56b29tZXIuZ2V0IFwibWVudUl0ZW1Gb250c2l6ZVwiXG4gICAgICAgIGRpc3BsYXllZEJ1dHRvbi5zdHlsZS5mb250U2l6ZSA9IEBnLnpvb21lci5nZXQgXCJtZW51Rm9udHNpemVcIlxuICAgICAgICBkaXNwbGF5ZWRCdXR0b24uc3R5bGUubWFyZ2luTGVmdCA9IEBnLnpvb21lci5nZXQgXCJtZW51TWFyZ2luTGVmdFwiXG4gICAgICAgIGRpc3BsYXllZEJ1dHRvbi5zdHlsZS5wYWRkaW5nID0gQGcuem9vbWVyLmdldCBcIm1lbnVQYWRkaW5nXCJcblxuICAgICAgamJvbmUoZGlzcGxheWVkQnV0dG9uKS5vbiBcImNsaWNrXCIsIChlKSA9PlxuICAgICAgICBAX3Nob3dNZW51IGUsbWVudSxkaXNwbGF5ZWRCdXR0b25cblxuICAgICAgICAjIHdhaXQgdW50aWwgZXZlbnQgaXMgYnViYmxlZCB0byB0aGUgdG9wXG4gICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0IC0+XG4gICAgICAgICAgamJvbmUoZG9jdW1lbnQuYm9keSkub25lIFwiY2xpY2tcIiwgKGUpIC0+XG4gICAgICAgICAgICBjb25zb2xlLmxvZyBcIm5leHQgY2xpY2tcIlxuICAgICAgICAgICAgbWVudS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCJcbiAgICAgICAgLCA1XG5cblxuICAgICAgZnJhZy5hcHBlbmRDaGlsZCBtZW51XG4gICAgICBmcmFnLmFwcGVuZENoaWxkIGRpc3BsYXllZEJ1dHRvblxuICAgICAgcmV0dXJuICBmcmFnXG5cbiAgICBfc2hvd01lbnU6IChlLCBtZW51LCB0YXJnZXQpIC0+XG4gICAgICAjamJvbmUobWVudSkuYWRkQ2xhc3MgXCJkcm9wZG93bi1vcGVuXCJcbiAgICAgIG1lbnUuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIlxuICAgICAgbWVudS5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIlxuXG4gICAgICByZWN0ID0gdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICBtZW51LnN0eWxlLmxlZnQgPSByZWN0LmxlZnQgKyBcInB4XCJcbiAgICAgIG1lbnUuc3R5bGUudG9wID0gKHJlY3QudG9wICsgdGFyZ2V0Lm9mZnNldEhlaWdodCkgKyBcInB4XCJcbiIsIk1lbnVCdWlsZGVyID0gcmVxdWlyZSBcIi4uL21lbnVidWlsZGVyXCJcbl8gPSByZXF1aXJlIFwidW5kZXJzY29yZVwiXG5kb20gPSByZXF1aXJlIFwiZG9tLWhlbHBlclwiXG5cbm1vZHVsZS5leHBvcnRzID0gQ29sb3JNZW51ID0gTWVudUJ1aWxkZXIuZXh0ZW5kXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQGcgPSBkYXRhLmdcbiAgICBAZWwuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcbiAgICBAbGlzdGVuVG8gQGcuY29sb3JzY2hlbWUsIFwiY2hhbmdlXCIsIC0+XG4gICAgICBAcmVuZGVyKClcblxuICByZW5kZXI6IC0+XG4gICAgbWVudUNvbG9yID0gQHNldE5hbWUoXCJDb2xvciBzY2hlbWVcIilcblxuICAgIGNvbG9yc2NoZW1lcyA9IEBnZXRDb2xvcnNjaGVtZXMoKVxuICAgIGZvciBzY2hlbWUgaW4gY29sb3JzY2hlbWVzXG4gICAgICBAYWRkU2NoZW1lIG1lbnVDb2xvciwgc2NoZW1lXG5cbiAgICB0ZXh0ID0gXCJCYWNrZ3JvdW5kXCJcbiAgICBpZiBAZy5jb2xvcnNjaGVtZS5nZXQoXCJjb2xvckJhY2tncm91bmRcIilcbiAgICAgIHRleHQgPSBcIkhpZGUgXCIgKyB0ZXh0XG4gICAgZWxzZVxuICAgICAgdGV4dCA9IFwiU2hvdyBcIiArIHRleHRcblxuICAgIEBhZGROb2RlIHRleHQsID0+XG4gICAgICBAZy5jb2xvcnNjaGVtZS5zZXQgXCJjb2xvckJhY2tncm91bmRcIiwgIUBnLmNvbG9yc2NoZW1lLmdldChcImNvbG9yQmFja2dyb3VuZFwiKVxuXG4gICAgQGdyZXkgbWVudUNvbG9yXG5cbiAgICAjIFRPRE86IG1ha2UgbW9yZSBlZmZpY2llbnRcbiAgICBkb20ucmVtb3ZlQWxsQ2hpbGRzIEBlbFxuICAgIEBlbC5hcHBlbmRDaGlsZCBAYnVpbGRET00oKVxuICAgIEBcblxuICBhZGRTY2hlbWU6IChtZW51Q29sb3Isc2NoZW1lKSAtPlxuICAgIHN0eWxlID0ge31cbiAgICBjdXJyZW50ID0gQGcuY29sb3JzY2hlbWUuZ2V0KFwic2NoZW1lXCIpXG4gICAgaWYgY3VycmVudCBpcyBzY2hlbWUuaWRcbiAgICAgIHN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwiIzc3RUQ4MFwiXG5cbiAgICBAYWRkTm9kZSBzY2hlbWUubmFtZSwgPT5cbiAgICAgIEBnLmNvbG9yc2NoZW1lLnNldCBcInNjaGVtZVwiLCBzY2hlbWUuaWRcbiAgICAsXG4gICAgICBzdHlsZTogc3R5bGVcblxuICBnZXRDb2xvcnNjaGVtZXM6IC0+XG4gICAgc2NoZW1lcyAgPSBbXVxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIlphcHBvXCIsIGlkOiBcInphcHBvXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJUYXlsb3JcIiwgaWQ6IFwidGF5bG9yXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJIeWRyb3Bob2JpY2l0eVwiLCBpZDogXCJoeWRyb1wiXG4gICAgc2NoZW1lcy5wdXNoIG5hbWU6IFwiTGVza1wiLCBpZDogXCJsZXNrXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJDaW5lbWFcIiwgaWQ6IFwiY2luZW1hXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJNQUVcIiwgaWQ6IFwibWFlXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJDbHVzdGFsXCIsIGlkOiBcImNsdXN0YWxcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIkNsdXN0YWwyXCIsIGlkOiBcImNsdXN0YWwyXCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJUdXJuXCIsIGlkOiBcInR1cm5cIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIlN0cmFuZFwiLCBpZDogXCJzdHJhbmRcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIkJ1cmllZFwiLCBpZDogXCJidXJpZWRcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIkhlbGl4XCIsIGlkOiBcImhlbGl4XCJcbiAgICBzY2hlbWVzLnB1c2ggbmFtZTogXCJOdWNsZW90aWRlXCIsIGlkOiBcIm51Y2xlb3RpZGVcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIlB1cmluZVwiLCBpZDogXCJwdXJpbmVcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIlBJRFwiLCBpZDogXCJwaWRcIlxuICAgIHNjaGVtZXMucHVzaCBuYW1lOiBcIk5vIGNvbG9yXCIsIGlkOiBcImZvb1wiXG4gICAgc2NoZW1lc1xuXG4gIGdyZXk6IChtZW51Q29sb3IpIC0+XG4gICAgIyBncmV5cyBhbGwgbG93ZXJjYXNlIGxldHRlcnNcbiAgICBAYWRkTm9kZSBcIkdyZXlcIiwgPT5cbiAgICAgIEBnLmNvbG9yc2NoZW1lLnNldCBcInNob3dMb3dlckNhc2VcIiwgZmFsc2VcbiAgICAgIEBtb2RlbC5lYWNoIChzZXEpIC0+XG4gICAgICAgIHJlc2lkdWVzID0gc2VxLmdldCBcInNlcVwiXG4gICAgICAgIGdyZXkgPSBbXVxuICAgICAgICBfLmVhY2ggcmVzaWR1ZXMsIChlbCwgaW5kZXgpIC0+XG4gICAgICAgICAgaWYgZWwgaXMgZWwudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgZ3JleS5wdXNoIGluZGV4XG4gICAgICAgIHNlcS5zZXQgXCJncmV5XCIsIGdyZXlcblxuICAgIEBhZGROb2RlIFwiR3JleSBieSB0aHJlc2hvbGRcIiwgPT5cbiAgICAgIHRocmVzaG9sZCA9IHByb21wdCBcIkVudGVyIHRocmVzaG9sZCAoaW4gcGVyY2VudClcIiwgMjBcbiAgICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCAvIDEwMFxuICAgICAgbWF4TGVuID0gQG1vZGVsLmdldE1heExlbmd0aCgpXG4gICAgICBjb25zZXJ2ID0gQGcuY29sdW1ucy5nZXQoXCJjb25zZXJ2XCIpXG4gICAgICBncmV5ID0gW11cbiAgICAgIGZvciBpIGluIFswLi4gbWF4TGVuIC0gMV1cbiAgICAgICAgY29uc29sZS5sb2cgY29uc2VydltpXVxuICAgICAgICBpZiBjb25zZXJ2W2ldIDwgdGhyZXNob2xkXG4gICAgICAgICAgZ3JleS5wdXNoIGlcbiAgICAgIEBtb2RlbC5lYWNoIChzZXEpIC0+XG4gICAgICAgIHNlcS5zZXQgXCJncmV5XCIsIGdyZXlcblxuICAgIEBhZGROb2RlIFwiR3JleSBzZWxlY3Rpb25cIiwgPT5cbiAgICAgIG1heExlbiA9IEBtb2RlbC5nZXRNYXhMZW5ndGgoKVxuICAgICAgQG1vZGVsLmVhY2ggKHNlcSkgPT5cbiAgICAgICAgYmxvY2tzID0gQGcuc2VsY29sLmdldEJsb2Nrc0ZvclJvdyhzZXEuZ2V0KFwiaWRcIiksbWF4TGVuKVxuICAgICAgICBzZXEuc2V0IFwiZ3JleVwiLCBibG9ja3NcblxuICAgIEBhZGROb2RlIFwiUmVzZXQgZ3JleVwiLCA9PlxuICAgICAgQGcuY29sb3JzY2hlbWUuc2V0IFwic2hvd0xvd2VyQ2FzZVwiLCB0cnVlXG4gICAgICBAbW9kZWwuZWFjaCAoc2VxKSAtPlxuICAgICAgICBzZXEuc2V0IFwiZ3JleVwiLCBbXVxuIiwiTWVudUJ1aWxkZXIgPSByZXF1aXJlIFwiLi4vbWVudWJ1aWxkZXJcIlxuc2F2ZUFzID0gcmVxdWlyZSBcImJyb3dzZXItc2F2ZWFzXCJcbkZhc3RhRXhwb3J0ZXIgPSByZXF1aXJlKFwiYmlvanMtaW8tZmFzdGFcIikud3JpdGVyXG5fID0gcmVxdWlyZSBcInVuZGVyc2NvcmVcIlxuYmxvYlVSTCA9IHJlcXVpcmUgXCJibHVlaW1wX2NhbnZhc3RvYmxvYlwiXG5cbm1vZHVsZS5leHBvcnRzID0gRXhwb3J0TWVudSA9IE1lbnVCdWlsZGVyLmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQG1zYSA9IGRhdGEubXNhXG4gICAgQGVsLnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiXG5cbiAgcmVuZGVyOiAtPlxuICAgIEBzZXROYW1lKFwiRXhwb3J0XCIpXG5cbiAgICBAYWRkTm9kZSBcIkV4cG9ydCBzZXF1ZW5jZXNcIiwgPT5cbiAgICAgICMgbGltaXQgYXQgYWJvdXQgMjU2a1xuICAgICAgdGV4dCA9IEZhc3RhRXhwb3J0ZXIuZXhwb3J0IEBtb2RlbC50b0pTT04oKVxuICAgICAgYmxvYiA9IG5ldyBCbG9iKFt0ZXh0XSwge3R5cGUgOiAndGV4dC9wbGFpbid9KVxuICAgICAgc2F2ZUFzIGJsb2IsIFwiYWxsLmZhc3RhXCJcblxuICAgIEBhZGROb2RlIFwiRXhwb3J0IHNlbGVjdGlvblwiLCA9PlxuICAgICAgc2VsZWN0aW9uID0gQGcuc2VsY29sLnBsdWNrIFwic2VxSWRcIlxuICAgICAgaWYgc2VsZWN0aW9uP1xuICAgICAgICAjIGZpbHRlciB0aG9zZSBzZXFpZHNcbiAgICAgICAgc2VsZWN0aW9uID0gQG1vZGVsLmZpbHRlciAoZWwpIC0+XG4gICAgICAgICAgXy5jb250YWlucyBzZWxlY3Rpb24sIGVsLmdldCBcImlkXCJcbiAgICAgICAgZm9yIGkgaW4gWzAuLiBzZWxlY3Rpb24ubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgICAgIHNlbGVjdGlvbltpXSA9IHNlbGVjdGlvbltpXS50b0pTT04oKVxuICAgICAgZWxzZVxuICAgICAgICBzZWxlY3Rpb24gPSBAbW9kZWwudG9KU09OKClcbiAgICAgICAgY29uc29sZS5sb2cgXCJubyBzZWxlY3Rpb24gZm91bmRcIlxuICAgICAgdGV4dCA9IEZhc3RhRXhwb3J0ZXIuZXhwb3J0IHNlbGVjdGlvblxuICAgICAgYmxvYiA9IG5ldyBCbG9iKFt0ZXh0XSwge3R5cGUgOiAndGV4dC9wbGFpbid9KVxuICAgICAgc2F2ZUFzIGJsb2IsIFwic2VsZWN0aW9uLmZhc3RhXCJcblxuICAgICMgVE9ETzogdXNlIGh0dHBzOi8vZ2l0aHViLmNvbS9ibHVlaW1wL0phdmFTY3JpcHQtQ2FudmFzLXRvLUJsb2IvYmxvYi9tYXN0ZXIvanMvY2FudmFzLXRvLWJsb2IuanNcbiAgICBAYWRkTm9kZSBcIkV4cG9ydCBpbWFnZVwiLCA9PlxuICAgICAgIyBUT0RPOiB0aGlzIGlzIHZlcnkgdWdseVxuICAgICAgY2FudmFzID0gQG1zYS5nZXRWaWV3KCdzdGFnZScpLmdldFZpZXcoJ2JvZHknKS5nZXRWaWV3KCdzZXFibG9jaycpLmVsXG4gICAgICBpZiBjYW52YXM/XG4gICAgICAgIHVybCA9IGNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpXG4gICAgICAgIHNhdmVBcyBibG9iVVJMKHVybCksIFwiYmlvanMtbXNhLnBuZ1wiLCBcImltYWdlL3BuZ1wiXG5cbiAgICAgICMgYWRkIG9jdGV0LXN0cmVhbVxuICAgICAgI3VybCA9IHVybC5yZXBsYWNlKCAvLy8gIyBjcyBoZXJlZ2V4ZXNcbiAgICAgICMvXmRhdGFbOl1pbWFnZVxcLyhwbmd8anBnfGpwZWcpWztdL2lcbiAgICAgICMvLy8sIFwiZGF0YTphcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07XCIpXG5cbiAgICBAZWwuYXBwZW5kQ2hpbGQgQGJ1aWxkRE9NKClcbiAgICBAXG4iLCJNZW51QnVpbGRlciA9IHJlcXVpcmUgXCIuLi9tZW51YnVpbGRlclwiXG5jb25zZW51cyA9IHJlcXVpcmUgXCIuLi8uLi9hbGdvL0NvbnNlbnN1c0NhbGNcIlxuU2VxID0gcmVxdWlyZSBcIi4uLy4uL21vZGVsL1NlcXVlbmNlXCJcblxubW9kdWxlLmV4cG9ydHMgPSBFeHRyYU1lbnUgPSBNZW51QnVpbGRlci5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuICAgIEBlbC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuXG4gIHJlbmRlcjogLT5cbiAgICBAc2V0TmFtZShcIkV4dHJhc1wiKVxuICAgIEBhZGROb2RlIFwiQWRkIGNvbnNlbnN1cyBzZXFcIiwgPT5cbiAgICAgIGNvbiA9IGNvbnNlbnVzKEBtb2RlbClcbiAgICAgIGNvbnNvbGUubG9nIGNvblxuICAgICAgc2VxID0gbmV3IFNlcVxuICAgICAgICBzZXE6IGNvblxuICAgICAgICBpZDogXCIwY1wiXG4gICAgICAgIG5hbWU6IFwiY29uc2VudXNcIlxuICAgICAgQG1vZGVsLmFkZCBzZXFcbiAgICAgIEBtb2RlbC5jb21wYXJhdG9yID0gKHNlcSkgLT5cbiAgICAgICAgc2VxLmdldCBcImlkXCJcbiAgICAgIEBtb2RlbC5zb3J0KClcbiAgICBAYWRkTm9kZSBcIkluY3JlYXNlIGZvbnQgc2l6ZVwiLCA9PlxuICAgICAgQGcuem9vbWVyLnNldCBcImNvbHVtbldpZHRoXCIsIEBnLnpvb21lci5nZXQoXCJjb2x1bW5XaWR0aFwiKSArIDJcbiAgICAgIEBnLnpvb21lci5zZXQgXCJsYWJlbFdpZHRoXCIsIEBnLnpvb21lci5nZXQoXCJjb2x1bW5XaWR0aFwiKSArIDVcbiAgICAgIEBnLnpvb21lci5zZXQgXCJyb3dIZWlnaHRcIiwgQGcuem9vbWVyLmdldChcInJvd0hlaWdodFwiKSArIDJcbiAgICAgIEBnLnpvb21lci5zZXQgXCJsYWJlbEZvbnRTaXplXCIsIEBnLnpvb21lci5nZXQoXCJsYWJlbEZvbnRTaXplXCIpICsgMlxuICAgIEBhZGROb2RlIFwiRGVjcmVhc2UgZm9udCBzaXplXCIsID0+XG4gICAgICBAZy56b29tZXIuc2V0IFwiY29sdW1uV2lkdGhcIiwgQGcuem9vbWVyLmdldChcImNvbHVtbldpZHRoXCIpIC0gMlxuICAgICAgQGcuem9vbWVyLnNldCBcInJvd0hlaWdodFwiLCBAZy56b29tZXIuZ2V0KFwicm93SGVpZ2h0XCIpIC0gMlxuICAgICAgQGcuem9vbWVyLnNldCBcImxhYmVsRm9udFNpemVcIiwgQGcuem9vbWVyLmdldChcImxhYmVsRm9udFNpemVcIikgLSAyXG4gICAgICBpZiBAZy56b29tZXIuZ2V0KFwiY29sdW1uV2lkdGhcIikgPCA4XG4gICAgICAgIEBnLnpvb21lci5zZXQgXCJ0ZXh0VmlzaWJsZVwiLCBmYWxzZVxuXG4gICAgQGFkZE5vZGUgXCJCYXIgY2hhcnQgZXhwIHNjYWxpbmdcIiwgPT5cbiAgICAgIEBnLmNvbHVtbnMuc2V0IFwic2NhbGluZ1wiLCBcImV4cFwiXG4gICAgQGFkZE5vZGUgXCJCYXIgY2hhcnQgbGluZWFyIHNjYWxpbmdcIiwgPT5cbiAgICAgIEBnLmNvbHVtbnMuc2V0IFwic2NhbGluZ1wiLCBcImxpblwiXG4gICAgQGFkZE5vZGUgXCJCYXIgY2hhcnQgbG9nIHNjYWxpbmdcIiwgPT5cbiAgICAgIEBnLmNvbHVtbnMuc2V0IFwic2NhbGluZ1wiLCBcImxvZ1wiXG5cbiAgICBAYWRkTm9kZSBcIk1pbmltaXplZCB3aWR0aFwiLCA9PlxuICAgICAgQGcuem9vbWVyLnNldCBcImFsaWdubWVudFdpZHRoXCIsIDYwMFxuICAgIEBhZGROb2RlIFwiTWluaW1pemVkIGhlaWdodFwiLCA9PlxuICAgICAgQGcuem9vbWVyLnNldCBcImFsaWdubWVudEhlaWdodFwiLCAxMjBcblxuICAgIEBhZGROb2RlIFwiSnVtcCB0byBhIGNvbHVtblwiLCA9PlxuICAgICAgb2Zmc2V0ID0gcHJvbXB0IFwiQ29sdW1uXCIsIFwiMjBcIlxuICAgICAgaWYgb2Zmc2V0IDwgMCBvciBvZmZzZXQgPiBAbW9kZWwuZ2V0TWF4TGVuZ3RoKCkgb3IgaXNOYU4ob2Zmc2V0KVxuICAgICAgICBhbGVydCBcImludmFsaWQgY29sdW1uXCJcbiAgICAgICAgcmV0dXJuXG4gICAgICBAZy56b29tZXIuc2V0TGVmdE9mZnNldChvZmZzZXQpXG5cbiAgICBAZWwuYXBwZW5kQ2hpbGQgQGJ1aWxkRE9NKClcbiAgICBAXG4iLCJNZW51QnVpbGRlciA9IHJlcXVpcmUgXCIuLi9tZW51YnVpbGRlclwiXG5fID0gcmVxdWlyZSBcInVuZGVyc2NvcmVcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IEZpbHRlck1lbnUgPSBNZW51QnVpbGRlci5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuICAgIEBlbC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuXG4gIHJlbmRlcjogLT5cbiAgICBAc2V0TmFtZShcIkZpbHRlclwiKVxuICAgIEBhZGROb2RlIFwiSGlkZSBjb2x1bW5zIGJ5IHRocmVzaG9sZFwiLChlKSA9PlxuICAgICAgdGhyZXNob2xkID0gcHJvbXB0IFwiRW50ZXIgdGhyZXNob2xkIChpbiBwZXJjZW50KVwiLCAyMFxuICAgICAgdGhyZXNob2xkID0gdGhyZXNob2xkIC8gMTAwXG4gICAgICBtYXhMZW4gPSBAbW9kZWwuZ2V0TWF4TGVuZ3RoKClcbiAgICAgIGhpZGRlbiA9IFtdXG4gICAgICBjb25zZXJ2ID0gQGcuY29sdW1ucy5nZXQoXCJjb25zZXJ2XCIpXG4gICAgICBmb3IgaSBpbiBbMC4uIG1heExlbiAtIDFdXG4gICAgICAgIGlmIGNvbnNlcnZbaV0gPCB0aHJlc2hvbGRcbiAgICAgICAgICBoaWRkZW4ucHVzaCBpXG4gICAgICBAZy5jb2x1bW5zLnNldCBcImhpZGRlblwiLCBoaWRkZW5cblxuICAgIEBhZGROb2RlIFwiSGlkZSBjb2x1bW5zIGJ5IHNlbGVjdGlvblwiLCA9PlxuICAgICAgaGlkZGVuT2xkID0gQGcuY29sdW1ucy5nZXQgXCJoaWRkZW5cIlxuICAgICAgaGlkZGVuID0gaGlkZGVuT2xkLmNvbmNhdCBAZy5zZWxjb2wuZ2V0QWxsQ29sdW1uQmxvY2tzIG1heExlbjogQG1vZGVsLmdldE1heExlbmd0aCgpLCB3aXRoUG9zOiB0cnVlXG4gICAgICBAZy5zZWxjb2wucmVzZXQgW11cbiAgICAgIEBnLmNvbHVtbnMuc2V0IFwiaGlkZGVuXCIsIGhpZGRlblxuXG4gICAgQGFkZE5vZGUgXCJIaWRlIGNvbHVtbnMgYnkgZ2Fwc1wiLCA9PlxuICAgICAgdGhyZXNob2xkID0gcHJvbXB0IFwiRW50ZXIgdGhyZXNob2xkIChpbiBwZXJjZW50KVwiLCAyMFxuICAgICAgdGhyZXNob2xkID0gdGhyZXNob2xkIC8gMTAwXG4gICAgICBtYXhMZW4gPSBAbW9kZWwuZ2V0TWF4TGVuZ3RoKClcbiAgICAgIGhpZGRlbiA9IFtdXG4gICAgICBmb3IgaSBpbiBbMC4uIG1heExlbiAtIDFdXG4gICAgICAgIGdhcHMgPSAwXG4gICAgICAgIHRvdGFsID0gMFxuICAgICAgICBAbW9kZWwuZWFjaCAoZWwpIC0+XG4gICAgICAgICAgZ2FwcysrIGlmIGVsLmdldCgnc2VxJylbaV0gaXMgXCItXCJcbiAgICAgICAgICB0b3RhbCsrXG4gICAgICAgIGdhcENvbnRlbnQgPSBnYXBzIC8gdG90YWxcbiAgICAgICAgaWYgZ2FwQ29udGVudCA+IHRocmVzaG9sZFxuICAgICAgICAgIGhpZGRlbi5wdXNoIGlcbiAgICAgIEBnLmNvbHVtbnMuc2V0IFwiaGlkZGVuXCIsIGhpZGRlblxuXG4gICAgQGFkZE5vZGUgXCJIaWRlIHNlcXMgYnkgaWRlbnRpdHlcIiwgPT5cbiAgICAgIHRocmVzaG9sZCA9IHByb21wdCBcIkVudGVyIHRocmVzaG9sZCAoaW4gcGVyY2VudClcIiwgMjBcbiAgICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCAvIDEwMFxuICAgICAgQG1vZGVsLmVhY2ggKGVsKSAtPlxuICAgICAgICBpZiBlbC5nZXQoJ2lkZW50aXR5JykgPCB0aHJlc2hvbGRcbiAgICAgICAgICBlbC5zZXQoJ2hpZGRlbicsIHRydWUpXG5cbiAgICBAYWRkTm9kZSBcIkhpZGUgc2VxcyBieSBzZWxlY3Rpb25cIiwgPT5cbiAgICAgIGhpZGRlbiA9IEBnLnNlbGNvbC53aGVyZSB0eXBlOiBcInJvd1wiXG4gICAgICBpZHMgPSBfLm1hcCBoaWRkZW4sIChlbCkgLT4gZWwuZ2V0KCdzZXFJZCcpXG4gICAgICBAZy5zZWxjb2wucmVzZXQgW11cbiAgICAgIEBtb2RlbC5lYWNoIChlbCkgLT5cbiAgICAgICAgaWYgaWRzLmluZGV4T2YoZWwuZ2V0KCdpZCcpKSA+PSAwXG4gICAgICAgICAgZWwuc2V0KCdoaWRkZW4nLCB0cnVlKVxuXG4gICAgQGFkZE5vZGUgXCJIaWRlIHNlcXMgYnkgZ2Fwc1wiLCA9PlxuICAgICAgdGhyZXNob2xkID0gcHJvbXB0IFwiRW50ZXIgdGhyZXNob2xkIChpbiBwZXJjZW50KVwiLCA0MFxuICAgICAgQG1vZGVsLmVhY2ggKGVsLGkpIC0+XG4gICAgICAgIHNlcSA9IGVsLmdldCgnc2VxJylcbiAgICAgICAgZ2FwcyA9IF8ucmVkdWNlIHNlcSwgKChtZW1vLCBjKSAtPiBtZW1vKysgaWYgYyBpcyAnLSc7bWVtbyksMFxuICAgICAgICBjb25zb2xlLmxvZyBnYXBzXG4gICAgICAgIGlmIGdhcHMgPiAgdGhyZXNob2xkXG4gICAgICAgICAgZWwuc2V0KCdoaWRkZW4nLCB0cnVlKVxuXG4gICAgQGFkZE5vZGUgXCJSZXNldFwiLCA9PlxuICAgICAgQGcuY29sdW1ucy5zZXQgXCJoaWRkZW5cIiwgW11cbiAgICAgIEBtb2RlbC5lYWNoIChlbCkgLT5cbiAgICAgICAgaWYgZWwuZ2V0KCdoaWRkZW4nKVxuICAgICAgICAgIGVsLnNldCgnaGlkZGVuJywgZmFsc2UpXG5cbiAgICBAZWwuYXBwZW5kQ2hpbGQgQGJ1aWxkRE9NKClcbiAgICBAXG4iLCJNZW51QnVpbGRlciA9IHJlcXVpcmUgXCIuLi9tZW51YnVpbGRlclwiXG5cbm1vZHVsZS5leHBvcnRzID0gSGVscE1lbnUgPSBNZW51QnVpbGRlci5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuXG4gIHJlbmRlcjogLT5cbiAgICBAc2V0TmFtZShcIkhlbHBcIilcbiAgICBAYWRkTm9kZSBcIkFib3V0IHRoZSBwcm9qZWN0XCIsID0+XG4gICAgICB3aW5kb3cub3BlbiBcImh0dHBzOi8vZ2l0aHViLmNvbS9ncmVlbmlmeS9iaW9qcy12aXMtbXNhXCJcbiAgICBAYWRkTm9kZSBcIlJlcG9ydCBpc3N1ZXNcIiwgPT5cbiAgICAgIHdpbmRvdy5vcGVuIFwiaHR0cHM6Ly9naXRodWIuY29tL2dyZWVuaWZ5L2Jpb2pzLXZpcy1tc2EvaXNzdWVzXCJcbiAgICBAYWRkTm9kZSBcIlVzZXIgbWFudWFsXCIsID0+XG4gICAgICB3aW5kb3cub3BlbiBcImh0dHBzOi8vZ2l0aHViLmNvbS9ncmVlbmlmeS9iaW9qcy12aXMtbXNhL3dpa2lcIlxuICAgIEBlbC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuICAgIEBlbC5hcHBlbmRDaGlsZCBAYnVpbGRET00oKVxuICAgIEBcbiIsIkNsdXN0YWwgPSByZXF1aXJlIFwiYmlvanMtaW8tY2x1c3RhbFwiXG5GYXN0YVJlYWRlciA9IHJlcXVpcmUoXCJiaW9qcy1pby1mYXN0YVwiKS5wYXJzZVxuTWVudUJ1aWxkZXIgPSByZXF1aXJlIFwiLi4vbWVudWJ1aWxkZXJcIlxuY29yc1VSTCA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy9wcm94eVwiKS5jb3JzVVJMXG5cbm1vZHVsZS5leHBvcnRzID0gSW1wb3J0TWVudSA9IE1lbnVCdWlsZGVyLmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQGVsLnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiXG5cbiAgcmVuZGVyOiAtPlxuICAgIEBzZXROYW1lKFwiSW1wb3J0XCIpXG4gICAgQGFkZE5vZGUgXCJGQVNUQVwiLChlKSA9PlxuICAgICAgdXJsID0gcHJvbXB0IFwiVVJMXCIsIFwiL3Rlc3QvZHVtbXkvc2FtcGxlcy9wNTMuY2x1c3RhbG8uZmFzdGFcIlxuICAgICAgdXJsID0gY29yc1VSTCB1cmwsIEBnXG4gICAgICBGYXN0YVJlYWRlci5yZWFkIHVybCwgKHNlcXMpID0+XG4gICAgICAgICMgbWFzcyB1cGRhdGUgb24gem9vbWVyXG4gICAgICAgIHpvb21lciA9IEBnLnpvb21lci50b0pTT04oKVxuICAgICAgICAjem9vbWVyLnRleHRWaXNpYmxlID0gZmFsc2VcbiAgICAgICAgI3pvb21lci5jb2x1bW5XaWR0aCA9IDRcbiAgICAgICAgem9vbWVyLmxhYmVsV2lkdGggPSAyMDBcbiAgICAgICAgem9vbWVyLmJveFJlY3RIZWlnaHQgPSAyXG4gICAgICAgIHpvb21lci5ib3hSZWN0V2lkdGggPSAyXG4gICAgICAgIEBtb2RlbC5yZXNldCBbXVxuICAgICAgICBAZy56b29tZXIuc2V0IHpvb21lclxuICAgICAgICBAbW9kZWwucmVzZXQgc2Vxc1xuICAgICAgICBAZy5jb2x1bW5zLmNhbGNDb25zZXJ2YXRpb24gQG1vZGVsXG5cbiAgICBAYWRkTm9kZSBcIkNMVVNUQUxcIiwgPT5cbiAgICAgIHVybCA9IHByb21wdCBcIlVSTFwiLCBcIi90ZXN0L2R1bW15L3NhbXBsZXMvcDUzLmNsdXN0YWxvLmNsdXN0YWxcIlxuICAgICAgdXJsID0gY29yc1VSTCB1cmwsIEBnXG4gICAgICBDbHVzdGFsLnJlYWQgdXJsLCAoc2VxcykgPT5cbiAgICAgICAgem9vbWVyID0gQGcuem9vbWVyLnRvSlNPTigpXG4gICAgICAgICN6b29tZXIudGV4dFZpc2libGUgPSBmYWxzZVxuICAgICAgICAjem9vbWVyLmNvbHVtbldpZHRoID0gNFxuICAgICAgICB6b29tZXIubGFiZWxXaWR0aCA9IDIwMFxuICAgICAgICB6b29tZXIuYm94UmVjdEhlaWdodCA9IDJcbiAgICAgICAgem9vbWVyLmJveFJlY3RXaWR0aCA9IDJcbiAgICAgICAgQG1vZGVsLnJlc2V0IFtdXG4gICAgICAgIEBnLnpvb21lci5zZXQgem9vbWVyXG4gICAgICAgIEBtb2RlbC5yZXNldCBzZXFzXG4gICAgICAgIEBnLmNvbHVtbnMuY2FsY0NvbnNlcnZhdGlvbiBAbW9kZWxcblxuICAgIEBhZGROb2RlIFwiYWRkIHlvdXIgb3duIFBhcnNlclwiLCA9PlxuICAgICAgd2luZG93Lm9wZW4gXCJodHRwczovL2dpdGh1Yi5jb20vYmlvanMvYmlvanMyXCJcblxuICAgIEBlbC5hcHBlbmRDaGlsZCBAYnVpbGRET00oKVxuICAgIEBcbiIsIk1lbnVCdWlsZGVyID0gcmVxdWlyZSBcIi4uL21lbnVidWlsZGVyXCJcbmRvbSA9IHJlcXVpcmUgXCJkb20taGVscGVyXCJcbl8gPSByZXF1aXJlKCd1bmRlcnNjb3JlJylcblxubW9kdWxlLmV4cG9ydHMgPSBPcmRlcmluZ01lbnUgPSBNZW51QnVpbGRlci5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuICAgIEBvcmRlciA9IFwiSURcIlxuICAgIEBlbC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuXG4gIHNldE9yZGVyOiAob3JkZXIpIC0+XG4gICAgQG9yZGVyID0gb3JkZXJcbiAgICBAcmVuZGVyKClcblxuICAjIFRPRE86IG1ha2UgbW9yZSBnZW5lcmljXG4gIHJlbmRlcjogLT5cbiAgICBAc2V0TmFtZShcIk9yZGVyaW5nXCIpXG5cbiAgICBjb21wcyA9IEBnZXRDb21wYXJhdG9ycygpXG4gICAgZm9yIG0gaW4gY29tcHNcbiAgICAgIEBfYWRkTm9kZSBtXG5cbiAgICBlbCA9IEBidWlsZERPTSgpXG5cbiAgICAjIFRPRE86IG1ha2UgbW9yZSBlZmZpY2llbnRcbiAgICBkb20ucmVtb3ZlQWxsQ2hpbGRzIEBlbFxuICAgIEBlbC5hcHBlbmRDaGlsZCBlbFxuICAgIEBcblxuICBfYWRkTm9kZTogKG0pIC0+XG4gICAgdGV4dCA9IG0udGV4dFxuICAgIHN0eWxlID0ge31cbiAgICBpZiB0ZXh0IGlzIEBvcmRlclxuICAgICAgc3R5bGUuYmFja2dyb3VuZENvbG9yID0gXCIjNzdFRDgwXCJcbiAgICBAYWRkTm9kZSB0ZXh0LCA9PlxuICAgICAgbS5wcmVjb2RlKCkgaWYgbS5wcmVjb2RlP1xuICAgICAgQG1vZGVsLmNvbXBhcmF0b3IgPSBtLmNvbXBhcmF0b3JcbiAgICAgIEBtb2RlbC5zb3J0KClcbiAgICAgIEBzZXRPcmRlciBtLnRleHRcbiAgICAsXG4gICAgICBzdHlsZTogc3R5bGVcblxuICBnZXRDb21wYXJhdG9yczogLT5cbiAgICBtb2RlbHMgPSBbXVxuXG4gICAgbW9kZWxzLnB1c2ggdGV4dDogXCJJRFwiLCBjb21wYXJhdG9yOiBcImlkXCJcblxuICAgIG1vZGVscy5wdXNoIHRleHQ6IFwiSUQgRGVzY1wiLCBjb21wYXJhdG9yOiAoYSwgYikgLT5cbiAgICAgICAgLSBhLmdldChcImlkXCIpLmxvY2FsZUNvbXBhcmUoYi5nZXQoXCJpZFwiKSlcblxuICAgIG1vZGVscy5wdXNoIHRleHQ6IFwiTGFiZWxcIiwgY29tcGFyYXRvcjogXCJuYW1lXCJcblxuICAgIG1vZGVscy5wdXNoIHRleHQ6IFwiTGFiZWwgRGVzY1wiLCBjb21wYXJhdG9yOiAoYSwgYikgLT5cbiAgICAgICAgLSBhLmdldChcIm5hbWVcIikubG9jYWxlQ29tcGFyZShiLmdldChcIm5hbWVcIikpXG5cbiAgICBtb2RlbHMucHVzaCB0ZXh0OiBcIlNlcVwiLCBjb21wYXJhdG9yOiBcInNlcVwiXG5cbiAgICBtb2RlbHMucHVzaCB0ZXh0OiBcIlNlcSBEZXNjXCIsIGNvbXBhcmF0b3I6IChhLGIpIC0+XG4gICAgICAgIC0gYS5nZXQoXCJzZXFcIikubG9jYWxlQ29tcGFyZShiLmdldChcInNlcVwiKSlcblxuICAgIG1vZGVscy5wdXNoIHRleHQ6IFwiSWRlbnRpdHlcIiwgY29tcGFyYXRvcjogXCJpZGVudGl0eVwiXG5cbiAgICBtb2RlbHMucHVzaCB0ZXh0OiBcIklkZW50aXR5IERlc2NcIiwgY29tcGFyYXRvcjogKHNlcSkgLT5cbiAgICAgICAgLSBzZXEuZ2V0IFwiaWRlbnRpdHlcIlxuXG4gICAgbW9kZWxzLnB1c2ggdGV4dDogXCJQYXJ0aXRpb24gY29kZXNcIiwgY29tcGFyYXRvcjogXCJwYXJ0aXRpb25cIiwgcHJlY29kZTogPT5cbiAgICAgICMgc2V0IHBhcnRpdGlvbnMgcmFuZG9tXG4gICAgICBAZy52aXMuc2V0KCdsYWJlbFBhcnRpdGlvbicsIHRydWUpXG4gICAgICBAbW9kZWwuZWFjaCAoZWwpIC0+XG4gICAgICAgIGVsLnNldCgncGFydGl0aW9uJywgXy5yYW5kb20oMSwzKSlcblxuXG4gICAgcmV0dXJuIG1vZGVsc1xuIiwic2VsID0gcmVxdWlyZSBcIi4uLy4uL2cvc2VsZWN0aW9uL1NlbGVjdGlvblwiXG5cbk1lbnVCdWlsZGVyID0gcmVxdWlyZSBcIi4uL21lbnVidWlsZGVyXCJcblxubW9kdWxlLmV4cG9ydHMgPSBTZWxlY3Rpb25NZW51ID0gTWVudUJ1aWxkZXIuZXh0ZW5kXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQGcgPSBkYXRhLmdcbiAgICBAZWwuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcblxuICByZW5kZXI6IC0+XG4gICAgQHNldE5hbWUoXCJTZWxlY3Rpb25cIilcbiAgICBAYWRkTm9kZSBcIkZpbmQgTW90aWYgKHN1cHBvcnRzIFJlZ0V4KVwiLCA9PlxuICAgICAgc2VhcmNoID0gcHJvbXB0IFwieW91ciBzZWFyY2hcIiwgXCJEXCJcbiAgICAgICMgbWFya3MgYWxsIGhpdHNcbiAgICAgIHNlYXJjaCA9IG5ldyBSZWdFeHAgc2VhcmNoLCBcImdpXCJcbiAgICAgIHNlbGNvbCA9IEBnLnNlbGNvbFxuICAgICAgbmV3U2VsaSA9IFtdXG4gICAgICBsZWZ0ZXN0SW5kZXggPSBvcmlnSW5kZXggPSAxMDAwNDJcbiAgICAgIEBtb2RlbC5lYWNoIChzZXEpIC0+XG4gICAgICAgIHN0clNlcSA9IHNlcS5nZXQoXCJzZXFcIilcbiAgICAgICAgd2hpbGUgbWF0Y2ggPSBzZWFyY2guZXhlYyBzdHJTZXFcbiAgICAgICAgICBpbmRleCA9IG1hdGNoLmluZGV4XG4gICAgICAgICAgYXJncyA9IHt4U3RhcnQ6IGluZGV4LCB4RW5kOiBpbmRleCArIG1hdGNoWzBdLmxlbmd0aCAtIDEsIHNlcUlkOlxuICAgICAgICAgICAgc2VxLmdldChcImlkXCIpfVxuICAgICAgICAgIG5ld1NlbGkucHVzaCBuZXcgc2VsLnBvc3NlbChhcmdzKVxuICAgICAgICAgIGxlZnRlc3RJbmRleCA9IE1hdGgubWluIGluZGV4LCBsZWZ0ZXN0SW5kZXhcblxuICAgICAgaWYgbmV3U2VsaS5sZW5ndGggaXMgMFxuICAgICAgICBhbGVydCBcIm5vIHNlbGVjdGlvbiBmb3VuZFwiXG4gICAgICBzZWxjb2wucmVzZXQgbmV3U2VsaVxuXG4gICAgICAjIHNhZmV0eSBjaGVjayArIHVwZGF0ZSBvZmZzZXRcbiAgICAgIGxlZnRlc3RJbmRleCA9IDAgaWYgbGVmdGVzdEluZGV4IGlzIG9yaWdJbmRleFxuICAgICAgQGcuem9vbWVyLnNldExlZnRPZmZzZXQgbGVmdGVzdEluZGV4XG5cbiAgICBAYWRkTm9kZSBcIkludmVydCBjb2x1bW5zXCIsID0+XG4gICAgICBAZy5zZWxjb2wuaW52ZXJ0Q29sIFswLi5AbW9kZWwuZ2V0TWF4TGVuZ3RoKCldXG4gICAgQGFkZE5vZGUgXCJJbnZlcnQgcm93c1wiLCA9PlxuICAgICAgQGcuc2VsY29sLmludmVydFJvdyBAbW9kZWwucGx1Y2sgXCJpZFwiXG4gICAgQGFkZE5vZGUgXCJSZXNldFwiLCA9PlxuICAgICAgQGcuc2VsY29sLnJlc2V0KClcbiAgICBAZWwuYXBwZW5kQ2hpbGQgQGJ1aWxkRE9NKClcbiAgICBAXG4iLCJNZW51QnVpbGRlciA9IHJlcXVpcmUgXCIuLi9tZW51YnVpbGRlclwiXG5kb20gPSByZXF1aXJlIFwiZG9tLWhlbHBlclwiXG5cbm1vZHVsZS5leHBvcnRzID0gSW1wb3J0TWVudSA9IE1lbnVCdWlsZGVyLmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQGVsLnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiXG4gICAgQGxpc3RlblRvIEBnLnZpcywgXCJjaGFuZ2VcIiwgQHJlbmRlclxuXG4gIHJlbmRlcjogLT5cbiAgICBAc2V0TmFtZShcIlZpcy4gZWxlbWVudHNcIilcblxuICAgIHZpc0VsZW1lbnRzID0gQGdldFZpc0VsZW1lbnRzKClcbiAgICBmb3IgdmlzRWwgaW4gdmlzRWxlbWVudHNcbiAgICAgIEBfYWRkVmlzRWwgdmlzRWxcblxuICAgICMgb3RoZXJcbiAgICBAYWRkTm9kZSBcIlJlc2V0XCIsID0+XG4gICAgICBAZy52aXMuc2V0IFwibGFiZWxzXCIsIHRydWVcbiAgICAgIEBnLnZpcy5zZXQgXCJzZXF1ZW5jZXNcIiwgdHJ1ZVxuICAgICAgQGcudmlzLnNldCBcIm1ldGFjZWxsXCIsIHRydWVcbiAgICAgIEBnLnZpcy5zZXQgXCJjb25zZXJ2XCIsIHRydWVcbiAgICAgIEBnLnZpcy5zZXQgXCJsYWJlbElkXCIsIHRydWVcbiAgICAgIEBnLnZpcy5zZXQgXCJsYWJlbE5hbWVcIiwgdHJ1ZVxuICAgICAgQGcudmlzLnNldCBcImxhYmVsQ2hlY2tib3hcIiwgZmFsc2VcblxuICAgIEBhZGROb2RlIFwiVG9nZ2xlIG1vdXNlb3ZlciBldmVudHNcIiwgPT5cbiAgICAgIEBnLmNvbmZpZy5zZXQgXCJyZWdpc3Rlck1vdXNlSG92ZXJcIiwgIUBnLmNvbmZpZy5nZXQgXCJyZWdpc3Rlck1vdXNlSG92ZXJcIlxuXG4gICAgIyBUT0RPOiBtYWtlIG1vcmUgZWZmaWNpZW50XG4gICAgZG9tLnJlbW92ZUFsbENoaWxkcyBAZWxcbiAgICBAZWwuYXBwZW5kQ2hpbGQgQGJ1aWxkRE9NKClcbiAgICBAXG5cbiAgX2FkZFZpc0VsOiAodmlzRWwpIC0+XG4gICAgc3R5bGUgPSB7fVxuXG4gICAgaWYgQGcudmlzLmdldCB2aXNFbC5pZFxuICAgICAgcHJlID0gXCJIaWRlIFwiXG4gICAgICBzdHlsZS5jb2xvciA9IFwicmVkXCJcbiAgICBlbHNlXG4gICAgICBwcmUgPSBcIlNob3cgXCJcbiAgICAgIHN0eWxlLmNvbG9yID0gXCJncmVlblwiXG5cbiAgICBAYWRkTm9kZSAocHJlICsgdmlzRWwubmFtZSksID0+XG4gICAgICBAZy52aXMuc2V0IHZpc0VsLmlkLCAhIEBnLnZpcy5nZXQgdmlzRWwuaWRcbiAgICAsXG4gICAgICBzdHlsZTogc3R5bGVcblxuICBnZXRWaXNFbGVtZW50czogLT5cbiAgICB2aXMgPSBbXVxuICAgIHZpcy5wdXNoIG5hbWU6IFwiTWFya2Vyc1wiLCBpZDogXCJtYXJrZXJzXCJcbiAgICB2aXMucHVzaCBuYW1lOiBcIkxhYmVsc1wiLCBpZDogXCJsYWJlbHNcIlxuICAgIHZpcy5wdXNoIG5hbWU6IFwiU2VxdWVuY2VzXCIsIGlkOiBcInNlcXVlbmNlc1wiXG4gICAgdmlzLnB1c2ggbmFtZTogXCJNZXRhIGluZm9cIiwgaWQ6IFwibWV0YWNlbGxcIlxuICAgIHZpcy5wdXNoIG5hbWU6IFwiT3ZlcnZpZXdib3hcIiwgaWQ6IFwib3ZlcnZpZXdib3hcIlxuICAgIHZpcy5wdXNoIG5hbWU6IFwiY29uc2VydlwiLCBpZDogXCJjb25zZXJ2XCJcbiAgICB2aXMucHVzaCBuYW1lOiBcIkxhYmVsTmFtZVwiLCBpZDogXCJsYWJlbE5hbWVcIlxuICAgIHZpcy5wdXNoIG5hbWU6IFwiTGFiZWxJZFwiLCBpZDogXCJsYWJlbElkXCJcbiAgICB2aXMucHVzaCBuYW1lOiBcIkxhYmVsQ2hlY2tib3hcIiwgaWQ6IFwibGFiZWxDaGVja2JveFwiXG4gICAgcmV0dXJuIHZpc1xuIiwiRmVhdHVyZSA9IHJlcXVpcmUgXCIuL0ZlYXR1cmVcIlxuTW9kZWwgPSByZXF1aXJlKFwiYmFja2JvbmUtdGhpblwiKS5Nb2RlbFxuXG5tb2R1bGUuZXhwb3J0cyA9IEZlYXR1cmUgPSBNb2RlbC5leHRlbmRcblxuICBkZWZhdWx0czpcbiAgICB4U3RhcnQ6IC0xXG4gICAgeEVuZDogLTFcbiAgICBoZWlnaHQ6IC0xXG4gICAgdGV4dDogXCJcIlxuICAgIGZpbGxDb2xvcjogXCJyZWRcIlxuICAgIGZpbGxPcGFjaXR5OiAwLjVcbiAgICB0eXBlOiBcInJlY3RhbmdsZVwiXG4gICAgYm9yZGVyU2l6ZTogMVxuICAgIGJvcmRlckNvbG9yOiBcImJsYWNrXCJcbiAgICBib3JkZXJPcGFjaXR5OiAwLjVcbiAgICB2YWxpZGF0ZTogdHJ1ZVxuXG4gIHZhbGlkYXRlOiAtPlxuICAgIGlmIGlzTmFOIEBhdHRyaWJ1dGVzLnhTdGFydCBvciBpc05hTiBAYXR0cmlidXRlcy54RW5kXG4gICAgICBcImZlYXR1cmVzIG5lZWQgaW50ZWdlciBzdGFydCBhbmQgZW5kLlwiXG5cbiAgY29udGFpbnM6IChpbmRleCkgLT5cbiAgICByZXR1cm4gIEBhdHRyaWJ1dGVzLnhTdGFydCA8PSBpbmRleCAmJiBpbmRleCA8PSBAYXR0cmlidXRlcy54RW5kXG5cbiIsIkZlYXR1cmUgPSByZXF1aXJlIFwiLi9GZWF0dXJlXCJcbkNvbGxlY3Rpb24gPSByZXF1aXJlKFwiYmFja2JvbmUtdGhpblwiKS5Db2xsZWN0aW9uXG5fID0gcmVxdWlyZSBcInVuZGVyc2NvcmVcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IEZlYXR1cmVDb2wgPSBDb2xsZWN0aW9uLmV4dGVuZFxuICBtb2RlbDogRmVhdHVyZVxuXG4gIGNvbnN0cnVjdG9yOiAtPlxuICAgIEBzdGFydE9uQ2FjaGUgPSBbXVxuICAgICMgaW52YWxpZGF0ZSBjYWNoZVxuICAgIEBvbiBcImFsbFwiLCAtPlxuICAgICAgQHN0YXJ0T25DYWNoZSA9IFtdXG4gICAgLCBAXG4gICAgQ29sbGVjdGlvbi5hcHBseSBALCBhcmd1bWVudHNcblxuICAjIHJldHVybnMgYWxsIGZlYXR1cmVzIHN0YXJ0aW5nIG9uIGluZGV4XG4gIHN0YXJ0T246IChpbmRleCkgLT5cbiAgICB1bmxlc3MgQHN0YXJ0T25DYWNoZVtpbmRleF0/XG4gICAgICBAc3RhcnRPbkNhY2hlW2luZGV4XSA9IEB3aGVyZSh7eFN0YXJ0OiBpbmRleH0pXG4gICAgcmV0dXJuIEBzdGFydE9uQ2FjaGVbaW5kZXhdXG5cbiAgY29udGFpbnM6IChpbmRleCkgLT5cbiAgICBAcmVkdWNlIChlbCxtZW1vKSAtPlxuICAgICAgbWVtbyB8fCBlbC5jb250YWlucyBpbmRleFxuICAgICwgZmFsc2VcblxuICAjIGdpdmVzIHRoZSBtaW5pbWFsIG5lZWRlZCBudW1iZXIgb2Ygcm93c1xuICAjIG5vdCBhIHZlcnkgZWZmaWNpZW50IGFsZ29yaXRobVxuICAjICh0aGVyZSBpcyBvbmUgaW4gTyhuKSApXG4gIGdldE1pblJvd3M6IC0+XG5cbiAgICBsZW4gPSBAbWF4IChlbCkgLT4gZWwuZ2V0IFwieEVuZFwiXG4gICAgcm93cyA9ICgwIGZvciB4IGluIFsxLi5sZW5dKVxuXG4gICAgQGVhY2ggKGVsKSAtPlxuICAgICAgZm9yIHggaW4gW2VsLmdldChcInhTdGFydFwiKS4uZmVhdHVyZS5nZXQoXCJ4RW5kXCIpXSBieSAxXG4gICAgICAgIHJvd3NbeF0rK1xuXG4gICAgXy5tYXggcm93c1xuIiwiU2VxdWVuY2UgPSByZXF1aXJlIFwiLi9TZXF1ZW5jZVwiXG5Db2xsZWN0aW9uID0gcmVxdWlyZShcImJhY2tib25lLXRoaW5cIikuQ29sbGVjdGlvblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNlcU1hbmFnZXIgPSBDb2xsZWN0aW9uLmV4dGVuZFxuICBtb2RlbDogU2VxdWVuY2VcblxuICBjb25zdHJ1Y3RvcjogLT5cblxuICAgIENvbGxlY3Rpb24uYXBwbHkgQCwgYXJndW1lbnRzXG5cbiAgICAjIGludmFsaWRhdGUgY2FjaGVcbiAgICBAb24gXCJhbGxcIiwgLT5cbiAgICAgIEBsZW5ndGhDYWNoZSA9IG51bGxcbiAgICAsIEBcbiAgICBAbGVuZ3RoQ2FjaGUgPSBudWxsXG5cbiAgICBAXG5cbiAgIyBnaXZlcyB0aGUgbWF4IGxlbmd0aCBvZiBhbGwgc2VxdWVuY2VzXG4gICMgKGNhY2hlZClcbiAgZ2V0TWF4TGVuZ3RoOiAoKSAtPlxuICAgIHJldHVybiAwIGlmIEBtb2RlbHMubGVuZ3RoIGlzIDBcbiAgICBpZiBAbGVuZ3RoQ2FjaGUgaXMgbnVsbFxuICAgICAgQGxlbmd0aENhY2hlID0gQG1heCgoc2VxKSAtPiBzZXEuZ2V0KFwic2VxXCIpLmxlbmd0aCkuZ2V0KFwic2VxXCIpLmxlbmd0aFxuICAgIHJldHVybiBAbGVuZ3RoQ2FjaGVcblxuICAjIGdldHMgdGhlIHByZXZpb3VzIG1vZGVsXG4gICMgQHBhcmFtIGVuZGxlc3MgW2Jvb2xlYW5dIGZvciB0aGUgZmlyc3QgZWxlbWVudFxuICAjIHRydWU6IHJldHVybnMgdGhlIGxhc3QgZWxlbWVudCwgZmFsc2U6IHJldHVybnMgdW5kZWZpbmVkXG4gIHByZXY6IChtb2RlbCwgZW5kbGVzcykgLT5cbiAgICBpbmRleCA9IEBpbmRleE9mKG1vZGVsKSAtIDFcbiAgICBpbmRleCA9IEAubGVuZ3RoIC0gMSBpZiBpbmRleCA8IDAgYW5kIGVuZGxlc3NcbiAgICBAYXQoaW5kZXgpXG5cbiAgIyBnZXRzIHRoZSBuZXh0IG1vZGVsXG4gICMgQHBhcmFtIGVuZGxlc3MgW2Jvb2xlYW5dIGZvciB0aGUgbGFzdCBlbGVtZW50XG4gICMgdHJ1ZTogcmV0dXJucyB0aGUgZmlyc3QgZWxlbWVudCwgZmFsc2U6IHJldHVybnMgdW5kZWZpbmVkXG4gIG5leHQ6IChtb2RlbCwgZW5kbGVzcykgLT5cbiAgICBpbmRleCA9IEBpbmRleE9mKG1vZGVsKSArIDFcbiAgICBpbmRleCA9IDAgaWYgaW5kZXggPT0gQC5sZW5ndGggYW5kIGVuZGxlc3NcbiAgICBAYXQoaW5kZXgpXG5cbiAgIyBAcmV0dXJucyBuIFtpbnRdIG51bWJlciBvZiBoaWRkZW4gY29sdW1ucyB1bnRpbCBuXG4gIGNhbGNIaWRkZW5TZXFzOiAobikgLT5cbiAgICBuTmV3ID0gblxuICAgIGZvciBpIGluIFswLi5uTmV3XVxuICAgICAgaWYgQGF0KGkpLmdldChcImhpZGRlblwiKVxuICAgICAgICBuTmV3KytcbiAgICBuTmV3IC0gblxuXG4iLCJNb2RlbCA9IHJlcXVpcmUoXCJiYWNrYm9uZS10aGluXCIpLk1vZGVsXG5GZWF0dXJlQ29sID0gcmVxdWlyZSBcIi4vRmVhdHVyZUNvbFwiXG5cbm1vZHVsZS5leHBvcnRzID0gU2VxdWVuY2UgPSBNb2RlbC5leHRlbmRcblxuICBkZWZhdWx0czpcbiAgICBuYW1lOiBcIlwiXG4gICAgaWQ6IFwiXCJcbiAgICBzZXE6IFwiXCJcblxuICBpbml0aWFsaXplOiAtPlxuICAgICMgcmVzaWR1ZXMgd2l0aG91dCBjb2xvclxuICAgIEAuc2V0IFwiZ3JleVwiLCBbXVxuICAgIEAuc2V0IFwiZmVhdHVyZXNcIiwgbmV3IEZlYXR1cmVDb2woKVxuIiwibW9kdWxlLmV4cG9ydHMuc2VxID0gcmVxdWlyZSBcIi4vU2VxdWVuY2VcIlxubW9kdWxlLmV4cG9ydHMuc2VxY29sID0gcmVxdWlyZSBcIi4vU2VxQ29sbGVjdGlvblwiXG5tb2R1bGUuZXhwb3J0cy5mZWF0dXJlID0gcmVxdWlyZSBcIi4vRmVhdHVyZVwiXG5tb2R1bGUuZXhwb3J0cy5mZWF0dXJlY29sID0gcmVxdWlyZSBcIi4vRmVhdHVyZUNvbFwiXG4iLCIjIG1vZGVsc1xuU2VxQ29sbGVjdGlvbiA9IHJlcXVpcmUgXCIuL21vZGVsL1NlcUNvbGxlY3Rpb25cIlxuXG4jIGdsb2JhbHNcbkNvbG9yYXRvciA9IHJlcXVpcmUgXCIuL2cvY29sb3JhdG9yXCJcbkNvbnNlbnN1cyA9IHJlcXVpcmUgXCIuL2cvY29uc2Vuc3VzXCJcbkNvbHVtbnMgPSByZXF1aXJlIFwiLi9nL2NvbHVtbnNcIlxuQ29uZmlnID0gcmVxdWlyZSBcIi4vZy9jb25maWdcIlxuU2VsQ29sID0gcmVxdWlyZSBcIi4vZy9zZWxlY3Rpb24vU2VsZWN0aW9uQ29sXCJcblZpc2liaWxpdHkgPSByZXF1aXJlIFwiLi9nL3Zpc2liaWxpdHlcIlxuVmlzT3JkZXJpbmcgPSByZXF1aXJlIFwiLi9nL3Zpc09yZGVyaW5nXCJcblpvb21lciA9IHJlcXVpcmUgXCIuL2cvem9vbWVyXCJcblxuIyBNViBmcm9tIGJhY2tib25lXG5ib25lVmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS1jaGlsZHNcIilcbkV2ZW50aGFuZGxlciA9IHJlcXVpcmUgXCJiaW9qcy1ldmVudHNcIlxuXG4jIE1TQSB2aWV3c1xuU3RhZ2UgPSByZXF1aXJlIFwiLi92aWV3cy9TdGFnZVwiXG5cbiMgb3B0cyBpcyBhIGRpY3Rpb25hcnkgY29uc2lzdGluZyBvZlxuIyBAcGFyYW0gZWwgW1N0cmluZ10gaWQgb3IgcmVmZXJlbmNlIHRvIGEgRE9NIGVsZW1lbnRcbiMgQHBhcmFtIHNlcXMgW1NlcUFycmF5XSBBcnJheSBvZiBzZXF1ZW5jZXMgZm9yIGluaXRsaXphdGlvblxuIyBAcGFyYW0gY29uZiBbRGljdF0gdXNlciBjb25maWdcbiMgQHBhcmFtIHZpcyBbRGljdF0gY29uZmlnIG9mIHZpc2libGUgdmlld3NcbiMgQHBhcmFtIHpvb21lciBbRGljdF0gZGlzcGxheSBzZXR0aW5ncyBsaWtlIGNvbHVtbldpZHRoXG5tb2R1bGUuZXhwb3J0cyA9IGJvbmVWaWV3LmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuXG4gICAgIyBjaGVjayBmb3IgZGVmYXVsdCBhcnJheXNcbiAgICBkYXRhLmNvbHVtbnMgPSB7fSB1bmxlc3MgZGF0YS5jb2x1bW5zP1xuICAgIGRhdGEuY29uZiA9IHt9IHVubGVzcyBkYXRhLmNvbmY/XG4gICAgZGF0YS52aXMgPSB7fSB1bmxlc3MgZGF0YS52aXM/XG4gICAgZGF0YS52aXNvcmRlciA9IHt9IHVubGVzcyBkYXRhLnZpc29yZGVyID9cbiAgICBkYXRhLnpvb21lciA9IHt9IHVubGVzcyBkYXRhLnpvb21lcj9cblxuICAgICMgZyBpcyBvdXIgZ2xvYmFsIE1lZGlhdG9yXG4gICAgQGcgPSBFdmVudGhhbmRsZXIubWl4aW4ge31cblxuICAgIGlmIGRhdGEuc2VxcyBpcyB1bmRlZmluZWQgb3IgZGF0YS5zZXFzLmxlbmd0aCBpcyAwXG4gICAgICBjb25zb2xlLmxvZyBcIndhcm5pbmcuIGVtcHR5IHNlcXMuXCJcblxuICAgICMgbG9hZCBzZXFzIGFuZCBhZGQgc3Vidmlld3NcbiAgICBAc2VxcyA9IG5ldyBTZXFDb2xsZWN0aW9uIGRhdGEuc2Vxc1xuXG4gICAgIyBwb3B1bGF0ZSBpdCBhbmQgaW5pdCB0aGUgZ2xvYmFsIG1vZGVsc1xuICAgIEBnLmNvbmZpZyA9IG5ldyBDb25maWcgZGF0YS5jb25mXG4gICAgQGcuY29uc2Vuc3VzID0gbmV3IENvbnNlbnN1cygpXG4gICAgQGcuY29sdW1ucyA9IG5ldyBDb2x1bW5zIGRhdGEuY29sdW1ucyAgIyBmb3IgYWN0aW9uIG9uIHRoZSBjb2x1bW5zIGxpa2UgaGlkaW5nXG4gICAgQGcuY29sb3JzY2hlbWUgPSBuZXcgQ29sb3JhdG9yKClcbiAgICBAZy5zZWxjb2wgPSBuZXcgU2VsQ29sIFtdLHtnOkBnfVxuICAgIEBnLnZpcyA9IG5ldyBWaXNpYmlsaXR5IGRhdGEudmlzXG4gICAgQGcudmlzb3JkZXIgPSBuZXcgVmlzT3JkZXJpbmcgZGF0YS52aXNvcmRlclxuICAgIEBnLnpvb21lciA9IG5ldyBab29tZXIgZGF0YS56b29tZXIse2c6QGd9XG5cbiAgICBAYWRkVmlldyBcInN0YWdlXCIsbmV3IFN0YWdlIHttb2RlbDogQHNlcXMsIGc6IEBnfVxuICAgIEBlbC5zZXRBdHRyaWJ1dGUgXCJjbGFzc1wiLCBcImJpb2pzX21zYV9kaXZcIlxuXG4gICAgaWYgQGcuY29uZmlnLmdldChcImV2ZW50QnVzXCIpIGlzIHRydWVcbiAgICAgIEBzdGFydEV2ZW50QnVzKClcblxuICBzdGFydEV2ZW50QnVzOiAtPlxuICAgIGJ1c09ianMgPSBbXCJjb25maWdcIiwgXCJjb25zZW5zdXNcIiwgXCJjb2x1bW5zXCIsIFwiY29sb3JzY2hlbWVcIiwgXCJzZWxjb2xcIlxuICAgICxcInZpc1wiLCBcInZpc29yZGVyXCIsIFwiem9vbWVyXCJdXG4gICAgZm9yIGtleSBpbiBidXNPYmpzXG4gICAgICBAX3Byb3h5VG9HIGtleVxuXG4gIF9wcm94eVRvRzogKGtleSkgLT5cbiAgICBAbGlzdGVuVG8gQGdba2V5XSwgXCJhbGxcIiwobmFtZSxwcmV2LG5vdykgLT5cbiAgICAgICMgc3VwcHJlc3MgZHVwbGljYXRlIGV2ZW50c1xuICAgICAgcmV0dXJuIGlmIG5hbWUgaXMgXCJjaGFuZ2VcIlxuICAgICAgIyBiYWNrYm9uZSB1c2VzIHRoZSBzZWNvbmQgYXJndW1lbnQgZm9yIHRoZSBuZXh0IHZhbHVlIC0+IHN3YXBcbiAgICAgIEBnLnRyaWdnZXIoa2V5ICsgXCI6XCIgKyBuYW1lLG5vdylcblxuICByZW5kZXI6IC0+XG4gICAgQHJlbmRlclN1YnZpZXdzKClcbiAgICBAZy52aXMuc2V0IFwibG9hZGVkXCIsIHRydWVcbiAgICBAXG4iLCJtb2R1bGUuZXhwb3J0cyA9XG4gICMgbWF0aCB1dGlsaXRpZXNcbiAgY2xhc3MgQk1hdGhcbiAgICBAcmFuZG9tSW50OiAobG93ZXIsIHVwcGVyKSAtPlxuICAgICAgIyBDYWxsZWQgd2l0aCBvbmUgYXJndW1lbnRcbiAgICAgIFtsb3dlciwgdXBwZXJdID0gWzAsIGxvd2VyXSAgICAgdW5sZXNzIHVwcGVyP1xuICAgICAgIyBMb3dlciBtdXN0IGJlIGxlc3MgdGhlbiB1cHBlclxuICAgICAgW2xvd2VyLCB1cHBlcl0gPSBbdXBwZXIsIGxvd2VyXSBpZiBsb3dlciA+IHVwcGVyXG4gICAgICAjIExhc3Qgc3RhdGVtZW50IGlzIGEgcmV0dXJuIHZhbHVlXG4gICAgICBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAodXBwZXIgLSBsb3dlciArIDEpICsgbG93ZXIpXG5cbiAgICAjIEByZXR1cm4gW0ludGVnZXJdIHJhbmRvbSBpZFxuICAgIEB1bmlxdWVJZDogKGxlbmd0aCA9IDgpIC0+XG4gICAgICBpZCA9IFwiXCJcbiAgICAgIGlkICs9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyKSB3aGlsZSBpZC5sZW5ndGggPCBsZW5ndGhcbiAgICAgIGlkLnN1YnN0ciAwLCBsZW5ndGhcblxuICAgICMgUmV0dXJucyBhIHJhbmRvbSBpbnRlZ2VyIGJldHdlZW4gbWluIChpbmNsdXNpdmUpIGFuZCBtYXggKGluY2x1c2l2ZSlcbiAgICBAZ2V0UmFuZG9tSW50OiAobWluLCBtYXgpIC0+XG4gICAgICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heCAtIG1pbiArIDEpKSArIG1pblxuIiwibW9kdWxlLmV4cG9ydHMuYm1hdGggPSByZXF1aXJlKFwiLi9ibWF0aFwiKVxubW9kdWxlLmV4cG9ydHMucHJveHkgPSByZXF1aXJlKFwiLi9wcm94eVwiKVxubW9kdWxlLmV4cG9ydHMuc2VxZ2VuID0gcmVxdWlyZShcIi4vc2VxZ2VuXCIpXG4iLCJtb2R1bGUuZXhwb3J0cyA9IHByb3h5ID1cblxuICAgIGNvcnNVUkw6ICh1cmwsIEBnKSA9PlxuICAgICAgIyBkbyBub3QgZmlsdGVyIG9uIGxvY2FsaG9zdFxuICAgICAgcmV0dXJuIHVybCBpZiBkb2N1bWVudC5VUkwuaW5kZXhPZignbG9jYWxob3N0JykgPj0gMCBhbmQgdXJsWzBdIGlzIFwiL1wiXG5cbiAgICAgICMgcmVtb3ZlIHd3dyArIGh0dHBcbiAgICAgIHVybCA9IHVybC5yZXBsYWNlIFwid3d3XFwuXCIsIFwiXCJcbiAgICAgIHVybCA9IHVybC5yZXBsYWNlIFwiaHR0cDovL1wiLCBcIlwiXG5cbiAgICAgICMgcHJlcGVuZCBwcm94eVxuICAgICAgdXJsID0gQGcuY29uZmlnLmdldCgnaW1wb3J0UHJveHknKSArIHVybFxuICAgICAgdXJsXG4iLCJTZXF1ZW5jZSA9IHJlcXVpcmUoXCJiaW9qcy1tb2RlbFwiKS5zZXFcbkJNYXRoID0gcmVxdWlyZSBcIi4vYm1hdGhcIlxuXG5zZXFnZW4gPSBtb2R1bGUuZXhwb3J0cyA9XG4gIF9nZW5lcmF0ZVNlcXVlbmNlOiAobGVuKSAtPlxuICAgIHRleHQgPSBcIlwiXG4gICAgcG9zc2libGUgPSBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIlxuXG4gICAgZm9yIGkgaW4gWzAuLmxlbiAtIDFdIGJ5IDFcbiAgICAgIHRleHQgKz0gcG9zc2libGUuY2hhckF0IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHBvc3NpYmxlLmxlbmd0aClcbiAgICByZXR1cm4gdGV4dFxuXG4gICMgZ2VuZXJhdGVzIGEgZHVtbXkgc2VxdWVuY2VzXG4gICMgQHBhcmFtIGxlbiBbaW50XSBudW1iZXIgb2YgZ2VuZXJhdGVkIHNlcXVlbmNlc1xuICAjIEBwYXJhbSBzZXFMZW4gW2ludF0gbGVuZ3RoIG9mIHRoZSBnZW5lcmF0ZWQgc2VxdWVuY2VzXG4gIGdldER1bW15U2VxdWVuY2VzOiAobGVuLCBzZXFMZW4pIC0+XG4gICAgc2VxcyA9IFtdXG4gICAgbGVuID0gQk1hdGguZ2V0UmFuZG9tSW50IDMsNSB1bmxlc3MgbGVuP1xuICAgIHNlcUxlbiA9IEJNYXRoLmdldFJhbmRvbUludCA1MCwyMDAgdW5sZXNzIHNlcUxlbj9cblxuICAgIGZvciBpIGluIFsxLi5sZW5dIGJ5IDFcbiAgICAgIHNlcXMucHVzaCBuZXcgU2VxdWVuY2Uoc2VxZ2VuLl9nZW5lcmF0ZVNlcXVlbmNlKHNlcUxlbiksIFwic2VxXCIgKyBpLFxuICAgICAgXCJyXCIgKyBpKVxuICAgIHJldHVybiBzZXFzXG4iLCIjIG1pbmkgc3ZnIGhlbHBlclxuXG5zdmducyA9IFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuXG5zZXRBdHRyID0gKG9iaixvcHRzKSAtPlxuICBmb3IgbmFtZSwgdmFsdWUgb2Ygb3B0c1xuICAgIG9iai5zZXRBdHRyaWJ1dGVOUyBudWxsLCBuYW1lLCB2YWx1ZVxuICBvYmpcblxuQmFzZSA9IChvcHRzKSAtPlxuICBzdmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMgc3ZnbnMsICdzdmcnXG4gIHN2Zy5zZXRBdHRyaWJ1dGUgXCJ3aWR0aFwiLCBvcHRzLndpZHRoXG4gIHN2Zy5zZXRBdHRyaWJ1dGUgXCJoZWlnaHRcIiwgb3B0cy5oZWlnaHRcbiAgc3ZnXG5cblJlY3QgPSAob3B0cykgLT5cbiAgcmVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyBzdmducywgJ3JlY3QnXG4gIHNldEF0dHIgcmVjdCxvcHRzXG5cbkxpbmUgPSAob3B0cykgLT5cbiAgbGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyBzdmducywgJ2xpbmUnXG4gIHNldEF0dHIgbGluZSxvcHRzXG5cblBvbHlnb24gPSAob3B0cykgLT5cbiAgbGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyBzdmducywgJ3BvbHlnb24nXG4gIHNldEF0dHIgbGluZSxvcHRzXG5cbm1vZHVsZS5leHBvcnRzLnJlY3QgPSBSZWN0XG5tb2R1bGUuZXhwb3J0cy5saW5lID0gTGluZVxubW9kdWxlLmV4cG9ydHMucG9seWdvbiA9IFBvbHlnb25cbm1vZHVsZS5leHBvcnRzLmJhc2UgPSBCYXNlXG4iLCJib25lVmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS1jaGlsZHNcIilcblNlcUJsb2NrID0gcmVxdWlyZSBcIi4vQ2FudmFzU2VxQmxvY2tcIlxuTGFiZWxCbG9jayA9IHJlcXVpcmUgXCIuL2xhYmVscy9MYWJlbEJsb2NrXCJcblxubW9kdWxlLmV4cG9ydHMgPSBib25lVmlldy5leHRlbmRcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuXG4gICAgaWYgdHJ1ZVxuICAgICAgbGFiZWxibG9jayA9IG5ldyBMYWJlbEJsb2NrIHttb2RlbDogQG1vZGVsLCBnOiBAZ31cbiAgICAgIGxhYmVsYmxvY2sub3JkZXJpbmcgPSAtMVxuICAgICAgQGFkZFZpZXcgXCJsYWJlbGJsb2NrXCIsbGFiZWxibG9ja1xuXG4gICAgaWYgQGcudmlzLmdldCBcInNlcXVlbmNlc1wiXG4gICAgICBzZXFibG9jayA9IG5ldyBTZXFCbG9jayB7bW9kZWw6IEBtb2RlbCwgZzogQGd9XG4gICAgICBzZXFibG9jay5vcmRlcmluZyA9IDBcbiAgICAgIEBhZGRWaWV3IFwic2VxYmxvY2tcIixzZXFibG9ja1xuXG4gICAgQGxpc3RlblRvIEBnLnpvb21lciwgXCJjaGFuZ2U6YWxpZ25tZW50SGVpZ2h0XCIsIEBhZGp1c3RIZWlnaHRcbiAgICBAbGlzdGVuVG8gQGcuY29sdW1ucywgXCJjaGFuZ2U6aGlkZGVuXCIsIEBhZGp1c3RIZWlnaHRcblxuICByZW5kZXI6IC0+XG4gICAgQHJlbmRlclN1YnZpZXdzKClcbiAgICBAZWwuY2xhc3NOYW1lID0gXCJiaW9qc19tc2FfYWxib2R5XCJcbiAgICBAZWwuc3R5bGUud2hpdGVTcGFjZSA9IFwibm93cmFwXCJcbiAgICBAYWRqdXN0SGVpZ2h0KClcbiAgICBAXG5cbiAgYWRqdXN0SGVpZ2h0OiAtPlxuICAgIGlmIEBnLnpvb21lci5nZXQoXCJhbGlnbm1lbnRIZWlnaHRcIikgaXMgXCJhdXRvXCJcbiAgICAgICMgVE9ETzogZml4IHRoZSBtYWdpYyA1XG4gICAgICBAZWwuc3R5bGUuaGVpZ2h0ID0gKEBnLnpvb21lci5nZXQoXCJyb3dIZWlnaHRcIikgKiBAbW9kZWwubGVuZ3RoKSArIDVcbiAgICBlbHNlXG4gICAgICBAZWwuc3R5bGUuaGVpZ2h0ID0gQGcuem9vbWVyLmdldCBcImFsaWdubWVudEhlaWdodFwiXG5cbiAgICAjIFRPRE86IDE1IGlzIHRoZSB3aWR0aCBvZiB0aGUgc2Nyb2xsYmFyXG4gICAgQGVsLnN0eWxlLndpZHRoID0gQGdldFdpZHRoKCkgKyAxNVxuXG4gIGdldFdpZHRoOiAtPlxuICAgIHdpZHRoID0gMFxuICAgIGlmIEBnLnZpcy5nZXQgXCJsYWJlbHNcIlxuICAgICAgd2lkdGggKz0gQGcuem9vbWVyLmdldCBcImxhYmVsV2lkdGhcIlxuICAgIGlmIEBnLnZpcy5nZXQgXCJtZXRhY2VsbFwiXG4gICAgICB3aWR0aCArPSBAZy56b29tZXIuZ2V0IFwibWV0YVdpZHRoXCJcbiAgICBpZiBAZy52aXMuZ2V0IFwic2VxdWVuY2VzXCJcbiAgICAgIHdpZHRoICs9IEBnLnpvb21lci5nZXQgXCJhbGlnbm1lbnRXaWR0aFwiXG4gICAgd2lkdGhcbiIsIkV2ZW50cyA9IHJlcXVpcmUoXCJiaW9qcy1ldmVudHNcIilcblxubW9kdWxlLmV4cG9ydHMgPSBjbGFzcyBDYW52YXNDaGFyQ2FjaGVcblxuICBjb25zdHJ1Y3RvcjogKEBnKSAtPlxuICAgIEBjYWNoZSA9IHt9XG4gICAgQGNhY2hlSGVpZ2h0ID0gMFxuICAgIEBjYWNoZVdpZHRoID0gMFxuXG4gICMgcmV0dXJucyBhIGNhY2hlZCBjYW52YXNcbiAgZ2V0Rm9udFRpbGU6IChsZXR0ZXIsIHdpZHRoLCBoZWlnaHQpIC0+XG4gICAgIyB2YWxpZGF0ZSBjYWNoZVxuICAgIGlmIHdpZHRoIGlzbnQgQGNhY2hlV2lkdGggb3IgaGVpZ2h0IGlzbnQgQGNhY2hlSGVpZ2h0XG4gICAgICBAY2FjaGVIZWlnaHQgPSBoZWlnaHRcbiAgICAgIEBjYWNoZVdpZHRoID0gd2lkdGhcbiAgICAgIEBjYWNoZSA9IHt9XG5cbiAgICBpZiBAY2FjaGVbbGV0dGVyXSBpcyB1bmRlZmluZWRcbiAgICAgIEBjcmVhdGVUaWxlIGxldHRlciwgd2lkdGgsIGhlaWdodFxuXG4gICAgcmV0dXJuIEBjYWNoZVtsZXR0ZXJdXG5cbiAgIyBjcmVhdGVzIGEgY2FudmFzIHdpdGggYSBzaW5nbGUgbGV0dGVyXG4gICMgKGZvciB0aGUgZmFzdCBmb250IGNhY2hlKVxuICBjcmVhdGVUaWxlOiAobGV0dGVyLCB3aWR0aCwgaGVpZ2h0KSAtPlxuXG4gICAgY2FudmFzID0gQGNhY2hlW2xldHRlcl0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwiY2FudmFzXCJcbiAgICBjYW52YXMud2lkdGggPSB3aWR0aFxuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHRcbiAgICBAY3R4ID0gY2FudmFzLmdldENvbnRleHQgJzJkJ1xuICAgIEBjdHguZm9udCA9IEBnLnpvb21lci5nZXQgXCJyZXNpZHVlRm9udFwiXG4gICAgQGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJ1xuICAgIEBjdHgudGV4dEFsaWduID0gXCJjZW50ZXJcIlxuXG4gICAgQGN0eC5maWxsVGV4dCBsZXR0ZXIsd2lkdGggLyAyLGhlaWdodCAvIDIsd2lkdGhcbiIsImJvbmVWaWV3ID0gcmVxdWlyZShcImJhY2tib25lLWNoaWxkc1wiKVxubW91c2UgPSByZXF1aXJlIFwibW91c2UtcG9zXCJcbmNvbG9yU2VsZWN0b3IgPSByZXF1aXJlKFwiYmlvanMtdXRpbC1jb2xvcnNjaGVtZXNcIikuc2VsZWN0b3Jcbl8gPSByZXF1aXJlIFwidW5kZXJzY29yZVwiXG5qYm9uZSA9IHJlcXVpcmUgXCJqYm9uZVwiXG5DaGFyQ2FjaGUgPSByZXF1aXJlIFwiLi9DYW52YXNDaGFyQ2FjaGVcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IGJvbmVWaWV3LmV4dGVuZFxuXG4gIHRhZ05hbWU6IFwiY2FudmFzXCJcblxuICBpbml0aWFsaXplOiAoZGF0YSkgLT5cbiAgICBAZyA9IGRhdGEuZ1xuXG4gICAgQGxpc3RlblRvIEBnLnpvb21lciwgXCJjaGFuZ2U6X2FsaWdubWVudFNjcm9sbExlZnQgY2hhbmdlOl9hbGlnbm1lbnRTY3JvbGxUb3BcIiwgKG1vZGVsLHZhbHVlLCBvcHRpb25zKSAtPlxuICAgICAgaWYgKG5vdCBvcHRpb25zPy5vcmlnaW4/KSBvciBvcHRpb25zLm9yaWdpbiBpc250IFwiY2FudmFzc2VxXCJcbiAgICAgICAgQHJlbmRlcigpXG5cbiAgICBAbGlzdGVuVG8gQGcuY29sdW1ucyxcImNoYW5nZTpoaWRkZW5cIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAZy56b29tZXIsXCJjaGFuZ2U6YWxpZ25tZW50V2lkdGhcIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAZy5jb2xvcnNjaGVtZSwgXCJjaGFuZ2VcIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAZy5zZWxjb2wsIFwicmVzZXQgYWRkXCIsIEByZW5kZXJcblxuICAgICMgZWwgcHJvcHNcbiAgICBAZWwuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcbiAgICBAZWwuc3R5bGUub3ZlcmZsb3dYID0gXCJoaWRkZW5cIlxuICAgIEBlbC5zdHlsZS5vdmVyZmxvd1kgPSBcImhpZGRlblwiXG4gICAgQGVsLmNsYXNzTmFtZSA9IFwiYmlvanNfbXNhX3NlcWJsb2NrXCJcblxuICAgIEBjdHggPSBAZWwuZ2V0Q29udGV4dCAnMmQnXG4gICAgQGNhY2hlID0gbmV3IENoYXJDYWNoZSBAZ1xuXG4gICAgIyB0aHJvdHRsZSB0aGUgZXhwZW5zaXZlIGRyYXcgZnVuY3Rpb25cbiAgICBAdGhyb3R0bGVUaW1lID0gMFxuICAgIEB0aHJvdHRsZUNvdW50cyA9IDBcbiAgICBpZiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUud2Via2l0QXBwZWFyYW5jZT9cbiAgICAgICMgd2Via2l0IGJyb3dzZXIgLSBubyB0aHJvdHRsaW5nIG5lZWRlZFxuICAgICAgQHRocm90dGxlZERyYXcgPSAtPlxuICAgICAgICBzdGFydCA9ICtuZXcgRGF0ZSgpXG4gICAgICAgIEBkcmF3KClcbiAgICAgICAgQHRocm90dGxlVGltZSArPSArbmV3IERhdGUoKSAtIHN0YXJ0XG4gICAgICAgIEB0aHJvdHRsZUNvdW50cysrXG4gICAgICAgIGlmIEB0aHJvdHRsZUNvdW50cyA+IDE1XG4gICAgICAgICAgdFRpbWUgPSBNYXRoLmNlaWwoQHRocm90dGxlVGltZSAvIEB0aHJvdHRsZUNvdW50cylcbiAgICAgICAgICBjb25zb2xlLmxvZyBcImF2Z0RyYXdUaW1lL1dlYktpdFwiLCB0VGltZVxuICAgICAgICAgICMgcmVtb3ZlIHBlcmYgYW5hbHlzZXJcbiAgICAgICAgICBAdGhyb3R0bGVkRHJhdyA9IEBkcmF3XG4gICAgZWxzZVxuICAgICAgIyBzbG93IGJyb3dzZXJzIGxpa2UgR2Vja29cbiAgICAgIEB0aHJvdHRsZWREcmF3ID0gXy50aHJvdHRsZSBAdGhyb3R0bGVkRHJhdywgMzBcblxuICAgIEBtYW5hZ2VFdmVudHMoKVxuXG4gICMgbWVhc3VyZXMgdGhlIHRpbWUgb2YgYSByZWRyYXcgYW5kIHRodXMgc2V0IHRoZSB0aHJvdHRsZSBsaW1pdFxuICB0aHJvdHRsZWREcmF3OiAtPlxuICAgICMgK25ldyBpcyB0aGUgZmFzdGVzdDogaHR0cDovL2pzcGVyZi5jb20vbmV3LWRhdGUtdnMtZGF0ZS1ub3ctdnMtcGVyZm9ybWFuY2Utbm93LzZcbiAgICBzdGFydCA9ICtuZXcgRGF0ZSgpXG4gICAgQGRyYXcoKVxuICAgIEB0aHJvdHRsZVRpbWUgKz0gK25ldyBEYXRlKCkgLSBzdGFydFxuICAgIEB0aHJvdHRsZUNvdW50cysrXG5cbiAgICAjIHJlbW92ZSBpdHNlbGYgYWZ0ZXIgYW5hbHlzaXNcbiAgICBpZiBAdGhyb3R0bGVDb3VudHMgPiAxNVxuICAgICAgdFRpbWUgPSBNYXRoLmNlaWwoQHRocm90dGxlVGltZSAvIEB0aHJvdHRsZUNvdW50cylcbiAgICAgIGNvbnNvbGUubG9nIFwiYXZnRHJhd1RpbWVcIiwgdFRpbWVcbiAgICAgIHRUaW1lICo9ICAxLjIgIyBhZGQgc2FmZXR5IHRpbWVcbiAgICAgIHRUaW1lID0gTWF0aC5tYXggMjAsIHRUaW1lICMgbGltaXQgZm9yIHVsdHJhIGZhc3QgY29tcHV0ZXJzXG4gICAgICBAdGhyb3R0bGVkRHJhdyA9IF8udGhyb3R0bGUgQGRyYXcsIHRUaW1lXG5cbiAgbWFuYWdlRXZlbnRzOiAtPlxuICAgIGV2ZW50cyA9IHt9XG4gICAgZXZlbnRzLm1vdXNlZG93biA9IFwiX29ubW91c2Vkb3duXCJcbiAgICBldmVudHMudG91Y2hzdGFydCA9IFwiX29udG91Y2hzdGFydFwiXG5cbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUNsaWNrc1wiXG4gICAgICBldmVudHMuZGJsY2xpY2sgPSBcIl9vbmNsaWNrXCJcbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUhvdmVyXCJcbiAgICAgIGV2ZW50cy5tb3VzZWluID0gXCJfb25tb3VzZWluXCJcbiAgICAgIGV2ZW50cy5tb3VzZW91dCA9IFwiX29ubW91c2VvdXRcIlxuXG4gICAgZXZlbnRzLm1vdXNld2hlZWwgPSBcIl9vbm1vdXNld2hlZWxcIlxuICAgIGV2ZW50cy5ET01Nb3VzZVNjcm9sbCA9IFwiX29ubW91c2V3aGVlbFwiXG4gICAgQGRlbGVnYXRlRXZlbnRzIGV2ZW50c1xuXG4gICAgIyBsaXN0ZW4gZm9yIGNoYW5nZXNcbiAgICBAbGlzdGVuVG8gQGcuY29uZmlnLCBcImNoYW5nZTpyZWdpc3Rlck1vdXNlSG92ZXJcIiwgQG1hbmFnZUV2ZW50c1xuICAgIEBsaXN0ZW5UbyBAZy5jb25maWcsIFwiY2hhbmdlOnJlZ2lzdGVyTW91c2VDbGlja1wiLCBAbWFuYWdlRXZlbnRzXG4gICAgQGRyYWdTdGFydCA9IFtdXG5cbiAgZHJhdzogLT5cblxuICAgICMgZmFzdGVzdCB3YXkgdG8gY2xlYXIgdGhlIGNhbnZhc1xuICAgICMgaHR0cDovL2pzcGVyZi5jb20vY2FudmFzLWNsZWFyLXNwZWVkLzI1XG4gICAgQGVsLndpZHRoID0gQGVsLndpZHRoXG5cbiAgICByZWN0SGVpZ2h0ID0gQGcuem9vbWVyLmdldCBcInJvd0hlaWdodFwiXG5cbiAgICAjIHJlY3RzXG4gICAgQGN0eC5nbG9iYWxBbHBoYSA9IEBnLmNvbG9yc2NoZW1lLmdldCBcIm9wYWNpdHlcIlxuICAgIEBkcmF3U2VxcyAoZGF0YSkgLT4gQGRyYXdTZXEoZGF0YSwgQF9kcmF3UmVjdClcbiAgICBAY3R4Lmdsb2JhbEFscGhhID0gMVxuXG4gICAgIyBsZXR0ZXJzXG4gICAgQGRyYXdTZXFzIChkYXRhKSAtPiBAZHJhd1NlcShkYXRhLCBAX2RyYXdMZXR0ZXIpXG5cbiAgICAjIGZlYXR1cmVzLCBzZWxlY3Rpb25cbiAgICBAZHJhd1NlcXMgQGRyYXdTZXFFeHRlbmRlZFxuXG4gIGRyYXdTZXFzOiAoY2FsbGJhY2spIC0+XG4gICAgcmVjdEhlaWdodCA9IEBnLnpvb21lci5nZXQgXCJyb3dIZWlnaHRcIlxuICAgIGhpZGRlbiA9IEBnLmNvbHVtbnMuZ2V0IFwiaGlkZGVuXCJcblxuICAgIHN0YXJ0ID0gTWF0aC5tYXggMCwgTWF0aC5hYnMoTWF0aC5jZWlsKCAtIEBnLnpvb21lci5nZXQoJ19hbGlnbm1lbnRTY3JvbGxUb3AnKSAvIHJlY3RIZWlnaHQpKVxuICAgIHkgPSAtIE1hdGguYWJzKCAtIEBnLnpvb21lci5nZXQoJ19hbGlnbm1lbnRTY3JvbGxUb3AnKSAlIHJlY3RIZWlnaHQpXG4gICAgZm9yIGkgaW4gW3N0YXJ0Li4gQG1vZGVsLmxlbmd0aCAtIDFdIGJ5IDFcbiAgICAgIGNvbnRpbnVlIGlmIEBtb2RlbC5hdChpKS5nZXQoJ2hpZGRlbicpXG4gICAgICBjYWxsYmFjay5jYWxsIEAsIHttb2RlbDogQG1vZGVsLmF0KGkpLCB5OiB5LCBoaWRkZW46IGhpZGRlbn1cbiAgICAgIHkgPSB5ICsgcmVjdEhlaWdodFxuICAgICAgIyBvdXQgb2Ygdmlld3BvcnQgLSBzdG9wXG4gICAgICBpZiB5ID4gQGVsLmhlaWdodFxuICAgICAgICBicmVha1xuXG4gICMgVE9ETzogdmVyeSBleHBlbnNpdmUgbWV0aG9kXG4gIGRyYXdTZXE6IChkYXRhLCBjYWxsYmFjaykgLT5cbiAgICBzZXEgPSBkYXRhLm1vZGVsLmdldCBcInNlcVwiXG4gICAgeSA9IGRhdGEueVxuICAgIHJlY3RXaWR0aCA9IEBnLnpvb21lci5nZXQgXCJjb2x1bW5XaWR0aFwiXG4gICAgcmVjdEhlaWdodCA9IEBnLnpvb21lci5nZXQgXCJyb3dIZWlnaHRcIlxuXG4gICAgIyBza2lwIHVubmVlZGVkIGJsb2NrcyBhdCB0aGUgYmVnaW5uaW5nXG4gICAgc3RhcnQgPSBNYXRoLm1heCAwLCBNYXRoLmFicyhNYXRoLmNlaWwoIC0gQGcuem9vbWVyLmdldCgnX2FsaWdubWVudFNjcm9sbExlZnQnKSAvIHJlY3RXaWR0aCkpXG4gICAgeCA9IC0gTWF0aC5hYnMoIC0gQGcuem9vbWVyLmdldCgnX2FsaWdubWVudFNjcm9sbExlZnQnKSAlIHJlY3RXaWR0aClcblxuICAgIHJlcyA9IHtyZWN0V2lkdGg6IHJlY3RXaWR0aCwgcmVjdEhlaWdodDogcmVjdEhlaWdodCwgeTogeX1cbiAgICBlbFdpZHRoID0gQGVsLndpZHRoXG5cbiAgICBmb3IgaiBpbiBbc3RhcnQuLiBzZXEubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgYyA9IHNlcVtqXVxuICAgICAgYyA9IGMudG9VcHBlckNhc2UoKVxuXG4gICAgICAjIGNhbGwgdGhlIGN1c3RvbSBmdW5jdGlvblxuICAgICAgcmVzLnggPSB4XG4gICAgICByZXMuYyA9IGNcblxuICAgICAgIyBsb2NhbCBjYWxsIGlzIGZhc3RlciB0aGFuIGFwcGx5XG4gICAgICAjIGh0dHA6Ly9qc3BlcmYuY29tL2Z1bmN0aW9uLWNhbGxzLWRpcmVjdC12cy1hcHBseS12cy1jYWxsLXZzLWJpbmQvNlxuICAgICAgaWYgZGF0YS5oaWRkZW4uaW5kZXhPZihqKSA8IDBcbiAgICAgICAgY2FsbGJhY2sgQCxyZXNcbiAgICAgIGVsc2VcbiAgICAgICAgY29udGludWVcblxuICAgICAgIyBtb3ZlIHRvIHRoZSByaWdodFxuICAgICAgeCA9IHggKyByZWN0V2lkdGhcblxuICAgICAgIyBvdXQgb2Ygdmlld3BvcnQgLSBzdG9wXG4gICAgICBpZiB4ID4gZWxXaWR0aFxuICAgICAgICBicmVha1xuXG4gIF9kcmF3UmVjdDogKHRoYXQsIGRhdGEpIC0+XG4gICAgY29sb3IgPSB0aGF0LmNvbG9yW2RhdGEuY11cbiAgICBpZiBjb2xvcj9cbiAgICAgIHRoYXQuY3R4LmZpbGxTdHlsZSA9IGNvbG9yXG4gICAgICB0aGF0LmN0eC5maWxsUmVjdCBkYXRhLngsZGF0YS55LGRhdGEucmVjdFdpZHRoLGRhdGEucmVjdEhlaWdodFxuXG4gICMgUkVBTExZIGV4cGVuc2l2ZSBjYWxsIG9uIEZGXG4gICMgUGVyZm9ybWFuY2U6XG4gICMgY2hyb21lOiAyMDAwbXMgZHJhd0xldHRlciAtIDEwMDBtcyBkcmF3UmVjdFxuICAjIEZGOiAxNzAwbXMgZHJhd0xldHRlciAtIDMwMG1zIGRyYXdSZWN0XG4gIF9kcmF3TGV0dGVyOiAodGhhdCxkYXRhKSAtPlxuICAgIHRoYXQuY3R4LmRyYXdJbWFnZSB0aGF0LmNhY2hlLmdldEZvbnRUaWxlKGRhdGEuYywgZGF0YS5yZWN0V2lkdGgsXG4gICAgICBkYXRhLnJlY3RIZWlnaHQpLCBkYXRhLngsIGRhdGEueSxkYXRhLnJlY3RXaWR0aCxkYXRhLnJlY3RIZWlnaHRcblxuICBkcmF3U2VxRXh0ZW5kZWQ6IChkYXRhKSAtPlxuICAgIHNlcSA9IGRhdGEubW9kZWwuZ2V0IFwic2VxXCJcbiAgICByZWN0V2lkdGggPSBAZy56b29tZXIuZ2V0IFwiY29sdW1uV2lkdGhcIlxuICAgIHJlY3RIZWlnaHQgPSBAZy56b29tZXIuZ2V0IFwicm93SGVpZ2h0XCJcblxuICAgIHN0YXJ0ID0gTWF0aC5tYXggMCwgTWF0aC5hYnMoTWF0aC5jZWlsKCAtIEBnLnpvb21lci5nZXQoJ19hbGlnbm1lbnRTY3JvbGxMZWZ0JykgLyByZWN0V2lkdGgpKVxuICAgIHggPSAtIE1hdGguYWJzKCAtIEBnLnpvb21lci5nZXQoJ19hbGlnbm1lbnRTY3JvbGxMZWZ0JykgJSByZWN0V2lkdGgpXG4gICAgeFplcm8gPSB4IC0gc3RhcnQgKiByZWN0V2lkdGhcblxuICAgIHNlbGVjdGlvbiA9IEBfZ2V0U2VsZWN0aW9uIGRhdGEubW9kZWxcbiAgICBbbVByZXZTZWwsbU5leHRTZWxdID0gQF9nZXRQcmV2TmV4dFNlbGVjdGlvbiBkYXRhLm1vZGVsXG4gICAgZmVhdHVyZXMgPSBkYXRhLm1vZGVsLmdldCBcImZlYXR1cmVzXCJcblxuICAgIHlaZXJvID0gZGF0YS55XG5cbiAgICBmb3IgaiBpbiBbc3RhcnQuLiBzZXEubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgc3RhcnRzID0gZmVhdHVyZXMuc3RhcnRPbiBqXG5cbiAgICAgIGlmIGRhdGEuaGlkZGVuLmluZGV4T2YoaikgPj0gMFxuICAgICAgICBjb250aW51ZVxuXG4gICAgICBpZiBzdGFydHMubGVuZ3RoID4gMFxuICAgICAgICBmb3IgZiBpbiBzdGFydHNcbiAgICAgICAgICBAYXBwZW5kRmVhdHVyZSBmOiBmLHhaZXJvOiB4LCB5WmVybzogeVplcm9cblxuICAgICAgeCA9IHggKyByZWN0V2lkdGhcbiAgICAgICMgb3V0IG9mIHZpZXdwb3J0IC0gc3RvcFxuICAgICAgaWYgeCA+IEBlbC53aWR0aFxuICAgICAgICBicmVha1xuXG4gICAgQF9hcHBlbmRTZWxlY3Rpb24gbW9kZWw6IGRhdGEubW9kZWwsIHhaZXJvOiB4WmVybywgeVplcm86IHlaZXJvLCBoaWRkZW46XG4gICAgICBkYXRhLmhpZGRlblxuXG4gIHJlbmRlcjogLT5cblxuICAgIEBlbC5zZXRBdHRyaWJ1dGUgJ2hlaWdodCcsIEBnLnpvb21lci5nZXQgXCJhbGlnbm1lbnRIZWlnaHRcIlxuICAgIEBlbC5zZXRBdHRyaWJ1dGUgJ3dpZHRoJywgQGcuem9vbWVyLmdldCBcImFsaWdubWVudFdpZHRoXCJcblxuICAgIEBnLnpvb21lci5fYWRqdXN0V2lkdGggQGVsLCBAbW9kZWxcbiAgICBAZy56b29tZXIuX2NoZWNrU2Nyb2xsaW5nKCBAX2NoZWNrU2Nyb2xsaW5nKFtAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsTGVmdCcpLFxuICAgIEBnLnpvb21lci5nZXQoJ19hbGlnbm1lbnRTY3JvbGxUb3AnKV0gKSx7aGVhZGVyOiBcImNhbnZhc3NlcVwifSlcblxuICAgIEBjb2xvciA9IGNvbG9yU2VsZWN0b3IuZ2V0Q29sb3IgQGcuY29sb3JzY2hlbWUuZ2V0KFwic2NoZW1lXCIpXG5cbiAgICBAdGhyb3R0bGVkRHJhdygpXG4gICAgQFxuXG4gIF9vbm1vdXNlbW92ZTogKGUsIHJldmVyc2VkKSAtPlxuICAgIHJldHVybiBpZiBAZHJhZ1N0YXJ0Lmxlbmd0aCBpcyAwXG5cbiAgICBkcmFnRW5kID0gbW91c2UuYWJzIGVcbiAgICAjIHJlbGF0aXZlIHRvIGZpcnN0IGNsaWNrXG4gICAgcmVsRW5kID0gW2RyYWdFbmRbMF0gLSBAZHJhZ1N0YXJ0WzBdLCBkcmFnRW5kWzFdIC0gQGRyYWdTdGFydFsxXV1cbiAgICAjIHJlbGF0aXZlIHRvIGluaXRpYWwgc2Nyb2xsIHN0YXR1c1xuXG4gICAgIyBzY2FsZSBldmVudHNcbiAgICBzY2FsZUZhY3RvciA9IEBnLnpvb21lci5nZXQgXCJjYW52YXNFdmVudFNjYWxlXCJcbiAgICBpZiByZXZlcnNlZFxuICAgICAgc2NhbGVGYWN0b3IgPSAzXG4gICAgZm9yIGkgaW4gWzAuLjFdIGJ5IDFcbiAgICAgIHJlbEVuZFtpXSA9IHJlbEVuZFtpXSAqIHNjYWxlRmFjdG9yXG5cbiAgICAjIGNhbGN1bGF0ZSBuZXcgc2Nyb2xsaW5nIHZhbHNcbiAgICByZWxEaXN0ID0gW0BkcmFnU3RhcnRTY3JvbGxbMF0gLSByZWxFbmRbMF0sIEBkcmFnU3RhcnRTY3JvbGxbMV0gLSByZWxFbmRbMV1dXG5cbiAgICAjIHJvdW5kIHZhbHVlc1xuICAgIGZvciBpIGluIFswLi4xXSBieSAxXG4gICAgICByZWxEaXN0W2ldID0gTWF0aC5yb3VuZCByZWxEaXN0W2ldXG5cbiAgICAjIHVwZGF0ZSBzY3JvbGxiYXJcbiAgICBzY3JvbGxDb3JyZWN0ZWQgPSBAX2NoZWNrU2Nyb2xsaW5nKCByZWxEaXN0KVxuICAgIEBnLnpvb21lci5fY2hlY2tTY3JvbGxpbmcgc2Nyb2xsQ29ycmVjdGVkLCB7b3JpZ2luOiBcImNhbnZhc3NlcVwifVxuXG4gICAgIyByZXNldCBzdGFydCBpZiB1c2Ugc2Nyb2xscyBvdXQgb2YgYm91bmRzXG4gICAgZm9yIGkgaW4gWzAuLjFdIGJ5IDFcbiAgICAgIGlmIHNjcm9sbENvcnJlY3RlZFtpXSBpc250IHJlbERpc3RbaV1cbiAgICAgICAgaWYgc2Nyb2xsQ29ycmVjdGVkW2ldIGlzIDBcbiAgICAgICAgICAjIHJlc2V0IG9mIGxlZnQsIHRvcFxuICAgICAgICAgIEBkcmFnU3RhcnRbaV0gPSBkcmFnRW5kW2ldXG4gICAgICAgICAgQGRyYWdTdGFydFNjcm9sbFtpXSA9IDBcbiAgICAgICAgZWxzZVxuICAgICAgICAgICMgcmVjYWxpYnJhdGUgb24gcmlnaHQsIGJvdHRvbVxuICAgICAgICAgIEBkcmFnU3RhcnRbaV0gPSBkcmFnRW5kW2ldIC0gc2Nyb2xsQ29ycmVjdGVkW2ldXG5cbiAgICBAdGhyb3R0bGVkRHJhdygpXG5cbiAgICAjIGFib3J0IHNlbGVjdGlvbiBldmVudHMgb2YgdGhlIGJyb3dzZXIgKG1vdXNlIG9ubHkpXG4gICAgaWYgZS5wcmV2ZW50RGVmYXVsdD9cbiAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICMgY29udmVydHMgdG91Y2hlcyBpbnRvIG9sZCBtb3VzZSBldmVudFxuICBfb250b3VjaG1vdmU6IChlKSAtPlxuICAgIEBfb25tb3VzZW1vdmUgZS5jaGFuZ2VkVG91Y2hlc1swXSwgdHJ1ZVxuICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcblxuICAjIHN0YXJ0IHRoZSBkcmFnZ2luZyBtb2RlXG4gIF9vbm1vdXNlZG93bjogKGUpIC0+XG4gICAgQGRyYWdTdGFydCA9IG1vdXNlLmFicyBlXG4gICAgQGRyYWdTdGFydFNjcm9sbCA9IFtAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsTGVmdCcpLCBAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsVG9wJyldXG4gICAgamJvbmUoZG9jdW1lbnQuYm9keSkub24gJ21vdXNlbW92ZS5vdmVybW92ZScsIChlKSA9PiBAX29ubW91c2Vtb3ZlKGUpXG4gICAgamJvbmUoZG9jdW1lbnQuYm9keSkub24gJ21vdXNldXAub3ZlcnVwJywgPT4gQF9jbGVhbnVwKClcbiAgICAjamJvbmUoZG9jdW1lbnQuYm9keSkub24gJ21vdXNlb3V0Lm92ZXJvdXQnLCAoZSkgPT4gQF9vbm1vdXNld2lub3V0KGUpXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG5cbiAgIyBzdGFydHMgdGhlIHRvdWNoIG1vZGVcbiAgX29udG91Y2hzdGFydDogKGUpIC0+XG4gICAgQGRyYWdTdGFydCA9IG1vdXNlLmFicyBlLmNoYW5nZWRUb3VjaGVzWzBdXG4gICAgQGRyYWdTdGFydFNjcm9sbCA9IFtAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsTGVmdCcpLCBAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsVG9wJyldXG4gICAgamJvbmUoZG9jdW1lbnQuYm9keSkub24gJ3RvdWNobW92ZS5vdmVydG1vdmUnLCAoZSkgPT4gQF9vbnRvdWNobW92ZShlKVxuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9uICd0b3VjaGVuZC5vdmVydGVuZCB0b3VjaGxlYXZlLm92ZXJ0bGVhdmVcbiAgICB0b3VjaGNhbmNlbC5vdmVydGNhbmVsJywgKGUpID0+IEBfdG91Y2hDbGVhbnVwKGUpXG5cbiAgIyBjaGVja3Mgd2hldGhlciBtb3VzZSBtb3ZlZCBvdXQgb2YgdGhlIHdpbmRvd1xuICAjIC0+IHRlcm1pbmF0ZSBkcmFnZ2luZ1xuICBfb25tb3VzZXdpbm91dDogKGUpIC0+XG4gICAgaWYgZS50b0VsZW1lbnQgaXMgZG9jdW1lbnQuYm9keS5wYXJlbnROb2RlXG4gICAgICBAX2NsZWFudXAoKVxuXG4gICMgdGVybWluYXRlcyBkcmFnZ2luZ1xuICBfY2xlYW51cDogLT5cbiAgICBAZHJhZ1N0YXJ0ID0gW11cbiAgICAjIHJlbW92ZSBhbGwgbGlzdGVuZXJzXG4gICAgamJvbmUoZG9jdW1lbnQuYm9keSkub2ZmKCcub3Zlcm1vdmUnKVxuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9mZignLm92ZXJ1cCcpXG4gICAgamJvbmUoZG9jdW1lbnQuYm9keSkub2ZmKCcub3Zlcm91dCcpXG5cbiAgIyB0ZXJtaW5hdGVzIHRvdWNoaW5nXG4gIF90b3VjaENsZWFudXA6IChlKSAtPlxuICAgIGlmIGUuY2hhbmdlZFRvdWNoZXMubGVuZ3RoID4gMFxuICAgICAgIyBtYXliZSB3ZSBjYW4gc2VuZCBhIGZpbmFsIGV2ZW50XG4gICAgICBAX29ubW91c2Vtb3ZlIGUuY2hhbmdlZFRvdWNoZXNbMF0sIHRydWVcblxuICAgIEBkcmFnU3RhcnQgPSBbXVxuICAgICMgcmVtb3ZlIGFsbCBsaXN0ZW5lcnNcbiAgICBqYm9uZShkb2N1bWVudC5ib2R5KS5vZmYoJy5vdmVydG1vdmUnKVxuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9mZignLm92ZXJ0ZW5kJylcbiAgICBqYm9uZShkb2N1bWVudC5ib2R5KS5vZmYoJy5vdmVydGxlYXZlJylcbiAgICBqYm9uZShkb2N1bWVudC5ib2R5KS5vZmYoJy5vdmVydGNhbmNlbCcpXG5cbiAgIyBtaWdodCBiZSBpbmNvbXBhdGlibGUgd2l0aCBzb21lIGJyb3dzZXJzXG4gIF9vbm1vdXNld2hlZWw6IChlKSAtPlxuICAgIGRlbHRhID0gbW91c2Uud2hlZWxEZWx0YSBlXG4gICAgQGcuem9vbWVyLnNldCAnX2FsaWdubWVudFNjcm9sbExlZnQnLCBAZy56b29tZXIuZ2V0KCdfYWxpZ25tZW50U2Nyb2xsTGVmdCcpICsgZGVsdGFbMF1cbiAgICBAZy56b29tZXIuc2V0ICdfYWxpZ25tZW50U2Nyb2xsVG9wJywgQGcuem9vbWVyLmdldCgnX2FsaWdubWVudFNjcm9sbFRvcCcpICsgZGVsdGFbMV1cbiAgICBlLnByZXZlbnREZWZhdWx0KClcblxuICBfb25jbGljazogKGUpIC0+XG4gICAgQGcudHJpZ2dlciBcInJlc2lkdWU6Y2xpY2tcIiwgQF9nZXRDbGlja1BvcyhlKVxuICAgIEB0aHJvdHRsZWREcmF3KClcblxuICBfb25tb3VzZWluOiAoZSkgLT5cbiAgICBAZy50cmlnZ2VyIFwicmVzaWR1ZTpjbGlja1wiLCBAX2dldENsaWNrUG9zKGUpXG4gICAgQHRocm90dGxlZERyYXcoKVxuXG4gIF9vbm1vdXNlb3V0OiAoZSkgLT5cbiAgICBAZy50cmlnZ2VyIFwicmVzaWR1ZTpjbGlja1wiLCBAX2dldENsaWNrUG9zKGUpXG4gICAgQHRocm90dGxlZERyYXcoKVxuXG4gIF9nZXRDbGlja1BvczogKGUpIC0+XG4gICAgY29vcmRzID0gbW91c2UucmVsIGVcbiAgICBjb29yZHNbMF0gKz0gQGcuem9vbWVyLmdldChcIl9hbGlnbm1lbnRTY3JvbGxMZWZ0XCIpXG4gICAgY29vcmRzWzFdICs9IEBnLnpvb21lci5nZXQoXCJfYWxpZ25tZW50U2Nyb2xsVG9wXCIpXG4gICAgeCA9IE1hdGguZmxvb3IoY29vcmRzWzBdIC8gQGcuem9vbWVyLmdldChcImNvbHVtbldpZHRoXCIpIClcbiAgICB5ID0gTWF0aC5mbG9vcihjb29yZHNbMV0gLyBAZy56b29tZXIuZ2V0KFwicm93SGVpZ2h0XCIpKVxuXG4gICAgIyBhZGQgaGlkZGVuIGNvbHVtbnNcbiAgICB4ICs9IEBnLmNvbHVtbnMuY2FsY0hpZGRlbkNvbHVtbnMgeFxuICAgICMgYWRkIGhpZGRlbiBzZXFzXG4gICAgeSArPSBAbW9kZWwuY2FsY0hpZGRlblNlcXMgeVxuXG4gICAgeCA9IE1hdGgubWF4IDAseFxuICAgIHkgPSBNYXRoLm1heCAwLHlcbiAgICBzZXFJZCA9IEBtb2RlbC5hdCh5KS5nZXQgXCJpZFwiXG4gICAgcmV0dXJuIHtzZXFJZDpzZXFJZCwgcm93UG9zOiB4LCBldnQ6ZX1cblxuICAjIGNoZWNrcyB3aGV0aGVyIHRoZSBzY3JvbGxpbmcgY29vcmRpbmF0ZXMgYXJlIHZhbGlkXG4gICMgQHJldHVybnM6IFt4U2Nyb2xsLHlTY3JvbGxdIHZhbGlkIGNvb3JkaW5hdGVzXG4gIF9jaGVja1Njcm9sbGluZzogKHNjcm9sbE9iaikgLT5cblxuICAgICMgMDogbWF4TGVmdCwgMTogbWF4VG9wXG4gICAgbWF4ID0gW0Btb2RlbC5nZXRNYXhMZW5ndGgoKSAqIEBnLnpvb21lci5nZXQoXCJjb2x1bW5XaWR0aFwiKSAtIEBnLnpvb21lci5nZXQoJ2FsaWdubWVudFdpZHRoJyksXG4gICAgQG1vZGVsLmxlbmd0aCAgKiBAZy56b29tZXIuZ2V0KFwicm93SGVpZ2h0XCIpIC0gQGcuem9vbWVyLmdldCgnYWxpZ25tZW50SGVpZ2h0JyldXG5cbiAgICBmb3IgaSBpbiBbMC4uMV0gYnkgMVxuICAgICAgaWYgc2Nyb2xsT2JqW2ldID4gbWF4W2ldXG4gICAgICAgIHNjcm9sbE9ialtpXSA9IG1heFtpXVxuXG4gICAgICBpZiBzY3JvbGxPYmpbaV0gPCAwXG4gICAgICAgIHNjcm9sbE9ialtpXSA9IDBcblxuICAgIHJldHVybiBzY3JvbGxPYmpcblxuICAjIFRPRE86IHNob3VsZCBJIGJlIG1vdmVkIHRvIHRoZSBzZWxlY3Rpb24gbWFuYWdlcj9cbiAgIyByZXR1cm5zIGFuIGFycmF5IHdpdGggdGhlIGN1cnJlbnRseSBzZWxlY3RlZCByZXNpZHVlc1xuICAjIGUuZy4gWzAsM10gPSBwb3MgMCBhbmQgMyBhcmUgc2VsZWN0ZWRcbiAgX2dldFNlbGVjdGlvbjogKG1vZGVsKSAtPlxuICAgIG1heExlbiA9IG1vZGVsLmdldChcInNlcVwiKS5sZW5ndGhcbiAgICBzZWxlY3Rpb24gPSBbXVxuICAgIHNlbHMgPSBAZy5zZWxjb2wuZ2V0U2VsRm9yUm93IG1vZGVsLmdldCBcImlkXCJcbiAgICByb3dzID0gXy5maW5kIHNlbHMsIChlbCkgLT4gZWwuZ2V0KFwidHlwZVwiKSBpcyBcInJvd1wiXG4gICAgaWYgcm93cz9cbiAgICAgICMgZnVsbCBtYXRjaFxuICAgICAgZm9yIG4gaW4gWzAuLm1heExlbiAtIDFdIGJ5IDFcbiAgICAgICAgc2VsZWN0aW9uLnB1c2ggblxuICAgIGVsc2UgaWYgc2Vscy5sZW5ndGggPiAwXG4gICAgICBmb3Igc2VsIGluIHNlbHNcbiAgICAgICAgZm9yIG4gaW4gW3NlbC5nZXQoXCJ4U3RhcnRcIikuLnNlbC5nZXQoXCJ4RW5kXCIpXSBieSAxXG4gICAgICAgICAgc2VsZWN0aW9uLnB1c2ggblxuXG4gICAgcmV0dXJuIHNlbGVjdGlvblxuXG4gICMgZHJhd3MgZmVhdHVyZXNcbiAgYXBwZW5kRmVhdHVyZTogKGRhdGEpIC0+XG4gICAgZiA9IGRhdGEuZlxuICAgICMgVE9ETzogdGhpcyBpcyBhIHZlcnkgbmFpdmUgd2F5XG4gICAgYm94V2lkdGggPSBAZy56b29tZXIuZ2V0KFwiY29sdW1uV2lkdGhcIilcbiAgICBib3hIZWlnaHQgPSBAZy56b29tZXIuZ2V0KFwicm93SGVpZ2h0XCIpXG4gICAgd2lkdGggPSAoZi5nZXQoXCJ4RW5kXCIpIC0gZi5nZXQoXCJ4U3RhcnRcIikpICogYm94V2lkdGhcblxuICAgIGJlZm9yZVdpZHRoID0gQGN0eC5saW5lV2lkdGhcbiAgICBAY3R4LmxpbmVXaWR0aCA9IDNcbiAgICBiZWZvcmVTdHlsZSA9IEBjdHguc3Ryb2tlU3R5bGVcbiAgICBAY3R4LnN0cm9rZVN0eWxlID0gZi5nZXQgXCJmaWxsQ29sb3JcIlxuXG4gICAgQGN0eC5zdHJva2VSZWN0IGRhdGEueFplcm8sIGRhdGEueVplcm8sIHdpZHRoLGJveEhlaWdodFxuICAgIEBjdHguc3Ryb2tlU3R5bGUgPSBiZWZvcmVTdHlsZVxuICAgIEBjdHgubGluZVdpZHRoID0gYmVmb3JlV2lkdGhcblxuXG4gICMgbG9vcHMgb3ZlciBhbGwgc2VsZWN0aW9uIGFuZCBjYWxscyB0aGUgcmVuZGVyIG1ldGhvZFxuICBfYXBwZW5kU2VsZWN0aW9uOiAoZGF0YSkgLT5cbiAgICBzZXEgPSBkYXRhLm1vZGVsLmdldChcInNlcVwiKVxuICAgIHNlbGVjdGlvbiA9IEBfZ2V0U2VsZWN0aW9uIGRhdGEubW9kZWxcbiAgICAjIGdldCB0aGUgc3RhdHVzIG9mIHRoZSB1cHBlciBhbmQgbG93ZXIgcm93XG4gICAgW21QcmV2U2VsLG1OZXh0U2VsXSA9IEBfZ2V0UHJldk5leHRTZWxlY3Rpb24gZGF0YS5tb2RlbFxuXG4gICAgYm94V2lkdGggPSBAZy56b29tZXIuZ2V0KFwiY29sdW1uV2lkdGhcIilcbiAgICBib3hIZWlnaHQgPSBAZy56b29tZXIuZ2V0KFwicm93SGVpZ2h0XCIpXG5cbiAgICAjIGF2b2lkIHVubmVjZXNzYXJ5IGxvb3BzXG4gICAgcmV0dXJuIGlmIHNlbGVjdGlvbi5sZW5ndGggaXMgMFxuXG4gICAgaGlkZGVuT2Zmc2V0ID0gMFxuICAgIGZvciBuIGluIFswLi5zZXEubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgaWYgZGF0YS5oaWRkZW4uaW5kZXhPZihuKSA+PSAwXG4gICAgICAgIGhpZGRlbk9mZnNldCsrXG4gICAgICBlbHNlXG4gICAgICAgIGsgPSBuIC0gaGlkZGVuT2Zmc2V0XG4gICAgICAgICMgb25seSBpZiBpdHMgYSBuZXcgc2VsZWN0aW9uXG4gICAgICAgIGlmIHNlbGVjdGlvbi5pbmRleE9mKG4pID49IDAgYW5kIChrIGlzIDAgb3Igc2VsZWN0aW9uLmluZGV4T2YobiAtIDEpIDwgMCApXG4gICAgICAgICAgQF9yZW5kZXJTZWxlY3Rpb24gbjpuLGs6ayxzZWxlY3Rpb246IHNlbGVjdGlvbixtUHJldlNlbDogbVByZXZTZWwsbU5leHRTZWw6bU5leHRTZWwsIHhaZXJvOiBkYXRhLnhaZXJvLCB5WmVybzogZGF0YS55WmVybywgbW9kZWw6IGRhdGEubW9kZWxcblxuICAjIGRyYXdzIGEgc2luZ2xlIHVzZXIgc2VsZWN0aW9uXG4gIF9yZW5kZXJTZWxlY3Rpb246IChkYXRhKSAtPlxuXG4gICAgeFplcm8gPSBkYXRhLnhaZXJvXG4gICAgeVplcm8gPSBkYXRhLnlaZXJvXG4gICAgbiA9IGRhdGEublxuICAgIGsgPSBkYXRhLmtcbiAgICBzZWxlY3Rpb24gPSBkYXRhLnNlbGVjdGlvblxuICAgICMgYW5kIGNoZWNrcyB0aGUgcHJldiBhbmQgbmV4dCByb3cgZm9yIHNlbGVjdGlvbiAgLT4gbm8gYm9yZGVycyBpbiBhIHNlbGVjdGlvblxuICAgIG1QcmV2U2VsPSBkYXRhLm1QcmV2U2VsXG4gICAgbU5leHRTZWwgPSBkYXRhLm1OZXh0U2VsXG5cbiAgICAjIGdldCB0aGUgbGVuZ3RoIG9mIHRoaXMgc2VsZWN0aW9uXG4gICAgc2VsZWN0aW9uTGVuZ3RoID0gMFxuICAgIGZvciBpIGluIFtuLi4gZGF0YS5tb2RlbC5nZXQoXCJzZXFcIikubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgaWYgc2VsZWN0aW9uLmluZGV4T2YoaSkgPj0gMFxuICAgICAgICBzZWxlY3Rpb25MZW5ndGgrK1xuICAgICAgZWxzZVxuICAgICAgICBicmVha1xuXG4gICAgIyBUT0RPOiB1Z2x5IVxuICAgIGJveFdpZHRoID0gQGcuem9vbWVyLmdldChcImNvbHVtbldpZHRoXCIpXG4gICAgYm94SGVpZ2h0ID0gQGcuem9vbWVyLmdldChcInJvd0hlaWdodFwiKVxuICAgIHRvdGFsV2lkdGggPSAoYm94V2lkdGggKiBzZWxlY3Rpb25MZW5ndGgpICsgMVxuXG4gICAgaGlkZGVuID0gQGcuY29sdW1ucy5nZXQoJ2hpZGRlbicpXG5cbiAgICBAY3R4LmJlZ2luUGF0aCgpXG4gICAgYmVmb3JlV2lkdGggPSBAY3R4LmxpbmVXaWR0aFxuICAgIEBjdHgubGluZVdpZHRoID0gM1xuICAgIGJlZm9yZVN0eWxlID0gQGN0eC5zdHJva2VTdHlsZVxuICAgIEBjdHguc3Ryb2tlU3R5bGUgPSBcIiNGRjAwMDBcIlxuXG4gICAgeFplcm8gKz0gayAqIGJveFdpZHRoXG5cbiAgICAjIHNwbGl0IHVwIHRoZSBzZWxlY3Rpb24gaW50byBzaW5nbGUgY2VsbHNcbiAgICB4UGFydCA9IDBcbiAgICBmb3IgaSBpbiBbMC4uIHNlbGVjdGlvbkxlbmd0aCAtIDFdXG4gICAgICB4UG9zID0gbiArIGlcbiAgICAgIGlmIGhpZGRlbi5pbmRleE9mKHhQb3MpID49IDBcbiAgICAgICAgY29udGludWVcbiAgICAgICMgdXBwZXIgbGluZVxuICAgICAgdW5sZXNzIG1QcmV2U2VsPyBhbmQgbVByZXZTZWwuaW5kZXhPZih4UG9zKSA+PSAwXG4gICAgICAgIEBjdHgubW92ZVRvIHhaZXJvICsgeFBhcnQsIHlaZXJvXG4gICAgICAgIEBjdHgubGluZVRvIHhQYXJ0ICsgYm94V2lkdGggKyB4WmVybywgeVplcm9cbiAgICAgICMgbG93ZXIgbGluZVxuICAgICAgdW5sZXNzIG1OZXh0U2VsPyBhbmQgbU5leHRTZWwuaW5kZXhPZih4UG9zKSA+PSAwXG4gICAgICAgIEBjdHgubW92ZVRvIHhQYXJ0ICsgeFplcm8sIGJveEhlaWdodCArIHlaZXJvXG4gICAgICAgIEBjdHgubGluZVRvIHhQYXJ0ICsgYm94V2lkdGggKyB4WmVybywgYm94SGVpZ2h0ICsgeVplcm9cblxuICAgICAgeFBhcnQgKz0gYm94V2lkdGhcblxuICAgICMgbGVmdFxuICAgIEBjdHgubW92ZVRvIHhaZXJvLHlaZXJvXG4gICAgQGN0eC5saW5lVG8geFplcm8sIGJveEhlaWdodCArIHlaZXJvXG5cbiAgICAjIHJpZ2h0XG4gICAgQGN0eC5tb3ZlVG8geFplcm8gKyB0b3RhbFdpZHRoLHlaZXJvXG4gICAgQGN0eC5saW5lVG8geFplcm8gKyB0b3RhbFdpZHRoLCBib3hIZWlnaHQgKyB5WmVyb1xuXG4gICAgQGN0eC5zdHJva2UoKVxuICAgIEBjdHguc3Ryb2tlU3R5bGUgPSBiZWZvcmVTdHlsZVxuICAgIEBjdHgubGluZVdpZHRoID0gYmVmb3JlV2lkdGhcblxuICAjIGxvb2tzIGF0IHRoZSBzZWxlY3Rpb24gb2YgdGhlIHByZXYgYW5kIG5leHQgZWxcbiAgIyBUT0RPOiB0aGlzIGlzIHZlcnkgbmFpdmUsIGFzIHRoZXJlIG1pZ2h0IGJlIGdhcHMgYWJvdmUgb3IgYmVsb3dcbiAgX2dldFByZXZOZXh0U2VsZWN0aW9uOiAobW9kZWwpIC0+XG5cbiAgICBtb2RlbFByZXYgPSBtb2RlbC5jb2xsZWN0aW9uLnByZXYgbW9kZWxcbiAgICBtb2RlbE5leHQgPSBtb2RlbC5jb2xsZWN0aW9uLm5leHQgbW9kZWxcbiAgICBtUHJldlNlbCA9IEBfZ2V0U2VsZWN0aW9uIG1vZGVsUHJldiBpZiBtb2RlbFByZXY/XG4gICAgbU5leHRTZWwgPSBAX2dldFNlbGVjdGlvbiBtb2RlbE5leHQgaWYgbW9kZWxOZXh0P1xuICAgIFttUHJldlNlbCxtTmV4dFNlbF1cbiIsInZpZXcgPSByZXF1aXJlKFwiYmFja2JvbmUtdmlld2pcIilcbm1vdXNlID0gcmVxdWlyZSBcIm1vdXNlLXBvc1wiXG5zZWxlY3Rpb24gPSByZXF1aXJlIFwiLi4vZy9zZWxlY3Rpb24vU2VsZWN0aW9uXCJcbmNvbG9yU2VsZWN0b3IgPSByZXF1aXJlKFwiYmlvanMtdXRpbC1jb2xvcnNjaGVtZXNcIikuc2VsZWN0b3Jcbmpib25lID0gcmVxdWlyZSBcImpib25lXCJcbl8gPSByZXF1aXJlIFwidW5kZXJzY29yZVwiXG5cbm1vZHVsZS5leHBvcnRzID0gT3ZlcnZpZXdCb3ggPSB2aWV3LmV4dGVuZFxuXG4gIGNsYXNzTmFtZTogXCJiaW9qc19tc2Ffb3ZlcnZpZXdib3hcIlxuICB0YWdOYW1lOiBcImNhbnZhc1wiXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQGcgPSBkYXRhLmdcbiAgICBAbGlzdGVuVG8gQGcuem9vbWVyLFwiY2hhbmdlOmJveFJlY3RXaWR0aCBjaGFuZ2U6Ym94UmVjdEhlaWdodFwiLCBAcmVuZGVyXG4gICAgQGxpc3RlblRvIEBnLnNlbGNvbCwgXCJhZGQgcmVzZXQgY2hhbmdlXCIsIEByZW5kZXJcbiAgICBAbGlzdGVuVG8gQGcuY29sdW1ucywgXCJjaGFuZ2U6aGlkZGVuXCIsIEByZW5kZXJcbiAgICBAbGlzdGVuVG8gQGcuY29sb3JzY2hlbWUsIFwiY2hhbmdlOnNob3dMb3dlckNhc2VcIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAbW9kZWwsIFwiY2hhbmdlXCIsIF8uZGVib3VuY2UgQHJlbmRlciwgNVxuXG4gICAgIyBjb2xvclxuICAgIEBjb2xvciA9IGNvbG9yU2VsZWN0b3IuZ2V0Q29sb3IgQGcuY29sb3JzY2hlbWUuZ2V0KFwic2NoZW1lXCIpXG4gICAgQGxpc3RlblRvIEBnLmNvbG9yc2NoZW1lLCBcImNoYW5nZTpzY2hlbWVcIiwgLT5cbiAgICAgIEBjb2xvciA9IGNvbG9yU2VsZWN0b3IuZ2V0Q29sb3IgQGcuY29sb3JzY2hlbWUuZ2V0KFwic2NoZW1lXCIpXG4gICAgICBAcmVuZGVyKClcbiAgICBAZHJhZ1N0YXJ0ID0gW11cblxuICBldmVudHM6XG4gICAgY2xpY2s6IFwiX29uY2xpY2tcIlxuICAgIG1vdXNlZG93bjogXCJfb25tb3VzZWRvd25cIlxuXG4gIHJlbmRlcjogLT5cbiAgICBAX2NyZWF0ZUNhbnZhcygpXG4gICAgQGVsLnRleHRDb250ZW50ID0gXCJvdmVydmlld1wiXG5cbiAgICAjIGJhY2tncm91bmQgYmcgZm9yIG5vbi1kcmF3ZWQgYXJlYVxuICAgIEBjdHguZmlsbFN0eWxlID0gXCIjOTk5OTk5XCJcbiAgICBAY3R4LmZpbGxSZWN0IDAsMCxAZWwud2lkdGgsQGVsLmhlaWdodFxuXG4gICAgcmVjdFdpZHRoID0gQGcuem9vbWVyLmdldCBcImJveFJlY3RXaWR0aFwiXG4gICAgcmVjdEhlaWdodCA9IEBnLnpvb21lci5nZXQgXCJib3hSZWN0SGVpZ2h0XCJcbiAgICBoaWRkZW4gPSBAZy5jb2x1bW5zLmdldCBcImhpZGRlblwiXG4gICAgc2hvd0xvd2VyQ2FzZSA9IEBnLmNvbG9yc2NoZW1lLmdldCBcInNob3dMb3dlckNhc2VcIlxuXG4gICAgeSA9IC1yZWN0SGVpZ2h0XG4gICAgZm9yIGkgaW4gWzAuLiBAbW9kZWwubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgc2VxID0gQG1vZGVsLmF0KGkpLmdldCBcInNlcVwiXG4gICAgICB4ID0gMFxuICAgICAgeSA9IHkgKyByZWN0SGVpZ2h0XG5cblxuICAgICAgaWYgQG1vZGVsLmF0KGkpLmdldCBcImhpZGRlblwiXG4gICAgICAgICMgaGlkZGVuIHNlcVxuICAgICAgICBjb25zb2xlLmxvZyBAbW9kZWwuYXQoaSkuZ2V0IFwiaGlkZGVuXCJcbiAgICAgICAgQGN0eC5maWxsU3R5bGUgPSBcImdyZXlcIlxuICAgICAgICBAY3R4LmZpbGxSZWN0IDAseSxzZXEubGVuZ3RoICogcmVjdFdpZHRoLHJlY3RIZWlnaHRcbiAgICAgICAgY29udGludWVcblxuICAgICAgZm9yIGogaW4gWzAuLiBzZXEubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgICBjID0gc2VxW2pdXG4gICAgICAgICMgdG9kbzogb3B0aW9uYWwgdXBwZXJjYXNpbmdcbiAgICAgICAgYyA9IGMudG9VcHBlckNhc2UoKSBpZiBzaG93TG93ZXJDYXNlXG4gICAgICAgIGNvbG9yID0gQGNvbG9yW2NdXG5cbiAgICAgICAgaWYgaGlkZGVuLmluZGV4T2YoaikgPj0gMFxuICAgICAgICAgIGNvbG9yID0gXCJncmV5XCJcblxuICAgICAgICBpZiBjb2xvcj9cbiAgICAgICAgICBAY3R4LmZpbGxTdHlsZSA9IGNvbG9yXG4gICAgICAgICAgQGN0eC5maWxsUmVjdCB4LHkscmVjdFdpZHRoLHJlY3RIZWlnaHRcblxuICAgICAgICB4ID0geCArIHJlY3RXaWR0aFxuXG4gICAgQF9kcmF3U2VsZWN0aW9uKClcblxuICBfZHJhd1NlbGVjdGlvbjogLT5cbiAgICAjIGhpZGUgZHVyaW5nIHNlbGVjdGlvblxuICAgIHJldHVybiBpZiBAZHJhZ1N0YXJ0Lmxlbmd0aCA+IDAgYW5kIG5vdCBAcHJvbG9uZ1NlbGVjdGlvblxuXG4gICAgcmVjdFdpZHRoID0gQGcuem9vbWVyLmdldCBcImJveFJlY3RXaWR0aFwiXG4gICAgcmVjdEhlaWdodCA9IEBnLnpvb21lci5nZXQgXCJib3hSZWN0SGVpZ2h0XCJcbiAgICBtYXhIZWlnaHQgPSByZWN0SGVpZ2h0ICogQG1vZGVsLmxlbmd0aFxuICAgIEBjdHguZmlsbFN0eWxlID0gXCIjZmZmZjAwXCJcbiAgICBAY3R4Lmdsb2JhbEFscGhhID0gMC45XG4gICAgZm9yIGkgaW4gWzAuLiBAZy5zZWxjb2wubGVuZ3RoIC0gMV0gYnkgMVxuICAgICAgc2VsID0gQGcuc2VsY29sLmF0KGkpXG4gICAgICBpZiBzZWwuZ2V0KCd0eXBlJykgaXMgJ2NvbHVtbidcbiAgICAgICAgQGN0eC5maWxsUmVjdCByZWN0V2lkdGggKiBzZWwuZ2V0KCd4U3RhcnQnKSwwLHJlY3RXaWR0aCAqXG4gICAgICAgIChzZWwuZ2V0KCd4RW5kJykgLSBzZWwuZ2V0KCd4U3RhcnQnKSArIDEpLG1heEhlaWdodFxuICAgICAgZWxzZSBpZiBzZWwuZ2V0KCd0eXBlJykgaXMgJ3JvdydcbiAgICAgICAgc2VxID0gKEBtb2RlbC5maWx0ZXIgKGVsKSAtPiBlbC5nZXQoJ2lkJykgaXMgc2VsLmdldCgnc2VxSWQnKSlbMF1cbiAgICAgICAgcG9zID0gQG1vZGVsLmluZGV4T2Yoc2VxKVxuICAgICAgICBAY3R4LmZpbGxSZWN0IDAscmVjdEhlaWdodCAqIHBvcywgcmVjdFdpZHRoICogc2VxLmdldCgnc2VxJykubGVuZ3RoLCByZWN0SGVpZ2h0XG4gICAgICBlbHNlIGlmIHNlbC5nZXQoJ3R5cGUnKSBpcyAncG9zJ1xuICAgICAgICBzZXEgPSAoQG1vZGVsLmZpbHRlciAoZWwpIC0+IGVsLmdldCgnaWQnKSBpcyBzZWwuZ2V0KCdzZXFJZCcpKVswXVxuICAgICAgICBwb3MgPSBAbW9kZWwuaW5kZXhPZihzZXEpXG4gICAgICAgIEBjdHguZmlsbFJlY3QgcmVjdFdpZHRoICogc2VsLmdldCgneFN0YXJ0JykscmVjdEhlaWdodCAqIHBvcywgcmVjdFdpZHRoICogKHNlbC5nZXQoJ3hFbmQnKSAtIHNlbC5nZXQoJ3hTdGFydCcpICsgMSksIHJlY3RIZWlnaHRcblxuICAgIEBjdHguZ2xvYmFsQWxwaGEgPSAxXG5cbiAgX29uY2xpY2s6IChldnQpIC0+XG4gICAgQGcudHJpZ2dlciBcIm1ldGE6Y2xpY2tcIiwge3NlcUlkOiBAbW9kZWwuZ2V0IFwiaWRcIiwgZXZ0OmV2dH1cblxuICBfb25tb3VzZW1vdmU6IChlKSAtPlxuICAgICMgZHVwbGljYXRlIGV2ZW50c1xuICAgIHJldHVybiBpZiBAZHJhZ1N0YXJ0Lmxlbmd0aCBpcyAwXG5cbiAgICBAcmVuZGVyKClcbiAgICBAY3R4LmZpbGxTdHlsZSA9IFwiI2ZmZmYwMFwiXG4gICAgQGN0eC5nbG9iYWxBbHBoYSA9IDAuOVxuXG4gICAgcmVjdCA9IEBfY2FsY1NlbGVjdGlvbiggbW91c2UuYWJzIGUgKVxuICAgIEBjdHguZmlsbFJlY3QgcmVjdFswXVswXSxyZWN0WzFdWzBdLHJlY3RbMF1bMV0gLSByZWN0WzBdWzBdLCByZWN0WzFdWzFdIC0gcmVjdFsxXVswXVxuXG4gICAgIyBhYm9ydCBzZWxlY3Rpb24gZXZlbnRzIG9mIHRoZSBicm93c2VyXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICMgc3RhcnQgdGhlIHNlbGVjdGlvbiBtb2RlXG4gIF9vbm1vdXNlZG93bjogKGUpIC0+XG4gICAgQGRyYWdTdGFydCA9IG1vdXNlLmFicyBlXG4gICAgQGRyYWdTdGFydFJlbCA9IG1vdXNlLnJlbCBlXG5cbiAgICBpZiBlLmN0cmxLZXkgb3IgZS5tZXRhS2V5XG4gICAgICBAcHJvbG9uZ1NlbGVjdGlvbiA9IHRydWVcbiAgICBlbHNlXG4gICAgICBAcHJvbG9uZ1NlbGVjdGlvbiA9IGZhbHNlXG4gICAgIyBlbmFibGUgZ2xvYmFsIGxpc3RlbmVyc1xuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9uICdtb3VzZW1vdmUub3Zlcm1vdmUnLCAoZSkgPT4gQF9vbm1vdXNlbW92ZShlKVxuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9uICdtb3VzZXVwLm92ZXJ1cCcsIChlKSA9PiBAX29ubW91c2V1cChlKVxuICAgIHJldHVybiBAZHJhZ1N0YXJ0XG5cbiAgIyBjYWxjdWxhdGVzIHRoZSBjdXJyZW50IHNlbGVjdGlvblxuICBfY2FsY1NlbGVjdGlvbjogKGRyYWdNb3ZlKSAtPlxuICAgICMgcmVsYXRpdmUgdG8gZmlyc3QgY2xpY2tcbiAgICBkcmFnUmVsID0gW2RyYWdNb3ZlWzBdIC0gQGRyYWdTdGFydFswXSwgZHJhZ01vdmVbMV0gLSBAZHJhZ1N0YXJ0WzFdXVxuXG4gICAgIyByZWxhdGl2ZSB0byB0YXJnZXRcbiAgICBmb3IgaSBpbiBbMC4uMV0gYnkgMVxuICAgICAgZHJhZ1JlbFtpXSA9IEBkcmFnU3RhcnRSZWxbaV0gKyBkcmFnUmVsW2ldXG5cbiAgICAjIDA6eCwgMTogeVxuICAgIHJlY3QgPSBbW0BkcmFnU3RhcnRSZWxbMF0sIGRyYWdSZWxbMF1dLCBbQGRyYWdTdGFydFJlbFsxXSwgZHJhZ1JlbFsxXV1dXG5cbiAgICAjIHN3YXAgdGhlIGNvb3JkaW5hdGVzIGlmIG5lZWRlZFxuICAgIGZvciBpIGluIFswLi4xXSBieSAxXG4gICAgICBpZiByZWN0W2ldWzFdIDwgcmVjdFtpXVswXVxuICAgICAgICByZWN0W2ldID0gW3JlY3RbaV1bMV0sIHJlY3RbaV1bMF1dXG5cbiAgICAgICMgbG93ZXIgbGltaXRcbiAgICAgIHJlY3RbaV1bMF0gPSBNYXRoLm1heCByZWN0W2ldWzBdLCAwXG5cbiAgICByZXR1cm4gcmVjdFxuXG4gIF9lbmRTZWxlY3Rpb246IChkcmFnRW5kKSAtPlxuICAgICMgcmVtb3ZlIGxpc3RlbmVyc1xuICAgIGpib25lKGRvY3VtZW50LmJvZHkpLm9mZignLm92ZXJtb3ZlJylcbiAgICBqYm9uZShkb2N1bWVudC5ib2R5KS5vZmYoJy5vdmVydXAnKVxuXG4gICAgIyBkdXBsaWNhdGUgZXZlbnRzXG4gICAgcmV0dXJuIGlmIEBkcmFnU3RhcnQubGVuZ3RoIGlzIDBcblxuICAgIHJlY3QgPSBAX2NhbGNTZWxlY3Rpb24gZHJhZ0VuZFxuXG4gICAgIyB4XG4gICAgZm9yIGkgaW4gWzAuLjFdXG4gICAgICByZWN0WzBdW2ldID0gTWF0aC5mbG9vciggcmVjdFswXVtpXSAvIEBnLnpvb21lci5nZXQoXCJib3hSZWN0V2lkdGhcIikpXG5cbiAgICAjIHlcbiAgICBmb3IgaSBpbiBbMC4uMV1cbiAgICAgIHJlY3RbMV1baV0gPSBNYXRoLmZsb29yKCByZWN0WzFdW2ldIC8gQGcuem9vbWVyLmdldChcImJveFJlY3RIZWlnaHRcIikgKVxuXG4gICAgIyB1cHBlciBsaW1pdFxuICAgIHJlY3RbMF1bMV0gPSBNYXRoLm1pbihAbW9kZWwuZ2V0TWF4TGVuZ3RoKCkgLSAxLCByZWN0WzBdWzFdKVxuICAgIHJlY3RbMV1bMV0gPSBNYXRoLm1pbihAbW9kZWwubGVuZ3RoIC0gMSwgcmVjdFsxXVsxXSlcblxuICAgICMgc2VsZWN0XG4gICAgc2VsaXMgPSBbXVxuICAgIGZvciBqIGluIFtyZWN0WzFdWzBdLi5yZWN0WzFdWzFdXSBieSAxXG4gICAgICBhcmdzID0gc2VxSWQ6IEBtb2RlbC5hdChqKS5nZXQoJ2lkJyksIHhTdGFydDogcmVjdFswXVswXSwgeEVuZDogcmVjdFswXVsxXVxuICAgICAgc2VsaXMucHVzaCBuZXcgc2VsZWN0aW9uLnBvc3NlbCBhcmdzXG5cbiAgICAjIHJlc2V0XG4gICAgQGRyYWdTdGFydCA9IFtdXG4gICAgIyBsb29rIGZvciBjdHJsIGtleVxuICAgIGlmIEBwcm9sb25nU2VsZWN0aW9uXG4gICAgICBAZy5zZWxjb2wuYWRkIHNlbGlzXG4gICAgZWxzZVxuICAgICAgQGcuc2VsY29sLnJlc2V0IHNlbGlzXG5cbiAgICAjIHNhZmV0eSBjaGVjayArIHVwZGF0ZSBvZmZzZXRcbiAgICBAZy56b29tZXIuc2V0TGVmdE9mZnNldCByZWN0WzBdWzBdXG4gICAgQGcuem9vbWVyLnNldFRvcE9mZnNldCByZWN0WzFdWzBdXG5cbiAgIyBlbmRzIHRoZSBzZWxlY3Rpb24gbW9kZVxuICBfb25tb3VzZXVwOiAoZSkgLT5cbiAgICBAX2VuZFNlbGVjdGlvbiBtb3VzZS5hYnMgZVxuXG4gIF9vbm1vdXNlb3V0OiAoZSkgLT5cbiAgICBAX2VuZFNlbGVjdGlvbiBtb3VzZS5hYnMgZVxuXG4gIyBpbml0IHRoZSBjYW52YXNcbiAgX2NyZWF0ZUNhbnZhczogLT5cbiAgICByZWN0V2lkdGggPSBAZy56b29tZXIuZ2V0IFwiYm94UmVjdFdpZHRoXCJcbiAgICByZWN0SGVpZ2h0ID0gQGcuem9vbWVyLmdldCBcImJveFJlY3RIZWlnaHRcIlxuXG4gICAgQGVsLmhlaWdodCA9IEBtb2RlbC5sZW5ndGggKiByZWN0SGVpZ2h0XG4gICAgQGVsLndpZHRoID0gQG1vZGVsLmdldE1heExlbmd0aCgpICogcmVjdFdpZHRoXG4gICAgQGN0eCA9IEBlbC5nZXRDb250ZXh0IFwiMmRcIlxuICAgIEBlbC5zdHlsZS5vdmVyZmxvdyA9IFwic2Nyb2xsXCJcbiAgICBAZWwuc3R5bGUuY3Vyc29yID0gXCJjcm9zc2hhaXJcIlxuIiwiYm9uZVZpZXcgPSByZXF1aXJlKFwiYmFja2JvbmUtY2hpbGRzXCIpXG5BbGlnbm1lbnRCb2R5ID0gcmVxdWlyZSBcIi4vQWxpZ25tZW50Qm9keVwiXG5IZWFkZXJCbG9jayA9IHJlcXVpcmUgXCIuL2hlYWRlci9IZWFkZXJCbG9ja1wiXG5PdmVydmlld0JveCA9IHJlcXVpcmUgXCIuL092ZXJ2aWV3Qm94XCJcbmlkZW50aXR5Q2FsYyA9IHJlcXVpcmUgXCIuLi9hbGdvL2lkZW50aXR5Q2FsY1wiXG5fID0gcmVxdWlyZSAndW5kZXJzY29yZSdcblxuIyBhIG5lYXQgY29sbGVjdGlvbiB2aWV3XG5tb2R1bGUuZXhwb3J0cyA9IGJvbmVWaWV3LmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG5cbiAgICBAZHJhdygpXG4gICAgQGxpc3RlblRvIEBtb2RlbCxcInJlc2V0XCIsIC0+XG4gICAgICBAaXNOb3REaXJ0eSA9IGZhbHNlXG4gICAgICBAcmVyZW5kZXIoKVxuXG4gICAgIyBkZWJvdW5jZSBhIGJ1bGsgb3BlcmF0aW9uXG4gICAgQGxpc3RlblRvIEBtb2RlbCxcImNoYW5nZTpoaWRkZW5cIiwgXy5kZWJvdW5jZSBAcmVyZW5kZXIsIDEwXG5cbiAgICBAbGlzdGVuVG8gQG1vZGVsLFwic29ydFwiLCBAcmVyZW5kZXJcbiAgICBAbGlzdGVuVG8gQG1vZGVsLFwiYWRkXCIsIC0+XG4gICAgICBjb25zb2xlLmxvZyBcInNlcSBhZGRcIlxuXG4gICAgQGxpc3RlblRvIEBnLnZpcyxcImNoYW5nZTpzZXF1ZW5jZXNcIiwgQHJlcmVuZGVyXG4gICAgQGxpc3RlblRvIEBnLnZpcyxcImNoYW5nZTpvdmVydmlld2JveFwiLCBAcmVyZW5kZXJcbiAgICBAbGlzdGVuVG8gQGcudmlzb3JkZXIsXCJjaGFuZ2VcIiwgQHJlcmVuZGVyXG5cbiAgZHJhdzogLT5cbiAgICBAcmVtb3ZlVmlld3MoKVxuXG4gICAgdW5sZXNzIEBpc05vdERpcnR5XG4gICAgICAjIG9ubHkgZXhlY3V0ZWQgd2hlbiBuZXcgc2VxdWVuY2VzIGFyZSBhZGRlZCBvciBvbiBzdGFydFxuICAgICAgY29uc2Vuc3VzID0gQGcuY29uc2Vuc3VzLmdldENvbnNlbnN1cyBAbW9kZWxcbiAgICAgIGlkZW50aXR5Q2FsYyBAbW9kZWwsIGNvbnNlbnN1c1xuICAgICAgQGlzTm90RGlydHkgPSB0cnVlXG5cbiAgICBpZiBAZy52aXMuZ2V0IFwib3ZlcnZpZXdib3hcIlxuICAgICAgb3ZlcnZpZXdib3ggPSBuZXcgT3ZlcnZpZXdCb3gge21vZGVsOiBAbW9kZWwsIGc6IEBnfVxuICAgICAgb3ZlcnZpZXdib3gub3JkZXJpbmcgPSBAZy52aXNvcmRlci5nZXQgJ292ZXJ2aWV3Qm94J1xuICAgICAgQGFkZFZpZXcgXCJvdmVydmlld2JveFwiLG92ZXJ2aWV3Ym94XG5cbiAgICBpZiB0cnVlXG4gICAgICBoZWFkZXJibG9jayA9IG5ldyBIZWFkZXJCbG9jayB7bW9kZWw6IEBtb2RlbCwgZzogQGd9XG4gICAgICBoZWFkZXJibG9jay5vcmRlcmluZyA9IEBnLnZpc29yZGVyLmdldCAnaGVhZGVyQm94J1xuICAgICAgQGFkZFZpZXcgXCJoZWFkZXJibG9ja1wiLGhlYWRlcmJsb2NrXG5cbiAgICBib2R5ID0gbmV3IEFsaWdubWVudEJvZHkge21vZGVsOiBAbW9kZWwsIGc6IEBnfVxuICAgIGJvZHkub3JkZXJpbmcgPSBAZy52aXNvcmRlci5nZXQgJ2FsaWdubWVudEJvZHknXG4gICAgQGFkZFZpZXcgXCJib2R5XCIsYm9keVxuXG4gIHJlbmRlcjogLT5cbiAgICBAcmVuZGVyU3Vidmlld3MoKVxuICAgIEBlbC5jbGFzc05hbWUgPSBcImJpb2pzX21zYV9zdGFnZVwiXG4gICAgQFxuXG4gIHJlcmVuZGVyOiAtPlxuICAgIEBkcmF3KClcbiAgICBAcmVuZGVyKClcbiIsInZpZXcgPSByZXF1aXJlKFwiYmFja2JvbmUtdmlld2pcIilcbmRvbSA9IHJlcXVpcmUoXCJkb20taGVscGVyXCIpXG5zdmcgPSByZXF1aXJlKFwiLi4vLi4vdXRpbHMvc3ZnXCIpXG5cbkNvbnNlcnZhdGlvblZpZXcgPSB2aWV3LmV4dGVuZFxuXG4gIGNsYXNzTmFtZTogXCJiaW9qc19tc2FfY29uc2VydlwiXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQGcgPSBkYXRhLmdcbiAgICBAbGlzdGVuVG8gQGcuem9vbWVyLFwiY2hhbmdlOnN0ZXBTaXplIGNoYW5nZTpsYWJlbFdpZHRoIGNoYW5nZTpjb2x1bW5XaWR0aFwiLCBAcmVuZGVyXG4gICAgQGxpc3RlblRvIEBnLnZpcyxcImNoYW5nZTpsYWJlbHMgY2hhbmdlOm1ldGFjZWxsXCIsIEByZW5kZXJcbiAgICBAbGlzdGVuVG8gQGcuY29sdW1ucywgXCJjaGFuZ2U6c2NhbGluZ1wiLCBAcmVuZGVyXG4gICAgQGxpc3RlblRvIEBtb2RlbCwgXCJyZXNldFwiLEByZW5kZXJcbiAgICBAbWFuYWdlRXZlbnRzKClcblxuICByZW5kZXI6IC0+XG4gICAgQGcuY29sdW1ucy5jYWxjQ29uc2VydmF0aW9uIEBtb2RlbFxuXG4gICAgZG9tLnJlbW92ZUFsbENoaWxkcyBAZWxcblxuICAgIG5NYXggPSBAbW9kZWwuZ2V0TWF4TGVuZ3RoKClcbiAgICBjZWxsV2lkdGggPSBAZy56b29tZXIuZ2V0IFwiY29sdW1uV2lkdGhcIlxuICAgIG1heEhlaWdodCA9IDIwXG4gICAgd2lkdGggPSBjZWxsV2lkdGggKiAobk1heCAtIEBnLmNvbHVtbnMuZ2V0KCdoaWRkZW4nKS5sZW5ndGgpXG4gICAgY29uc29sZS5sb2cgQGcuY29sdW1ucy5nZXQoJ2hpZGRlbicpXG5cbiAgICBzID0gc3ZnLmJhc2UgaGVpZ2h0OiBtYXhIZWlnaHQsIHdpZHRoOiB3aWR0aFxuICAgIHMuc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcbiAgICBzLnN0eWxlLmN1cnNvciA9IFwicG9pbnRlclwiXG5cbiAgICBzdGVwU2l6ZSA9IEBnLnpvb21lci5nZXQgXCJzdGVwU2l6ZVwiXG4gICAgaGlkZGVuID0gQGcuY29sdW1ucy5nZXQgXCJoaWRkZW5cIlxuICAgIHggPSAwXG4gICAgbiA9IDBcbiAgICB3aGlsZSBuIDwgbk1heFxuICAgICAgaWYgaGlkZGVuLmluZGV4T2YobikgPj0gMFxuICAgICAgICBuICs9IHN0ZXBTaXplXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB3aWR0aCA9IGNlbGxXaWR0aCAqIHN0ZXBTaXplXG4gICAgICBhdmdIZWlnaHQgPSAwXG4gICAgICBmb3IgaSBpbiBbMCAuLiBzdGVwU2l6ZSAtIDFdXG4gICAgICAgIGF2Z0hlaWdodCArPSBAZy5jb2x1bW5zLmdldChcImNvbnNlcnZcIilbbl1cbiAgICAgIGhlaWdodCA9IG1heEhlaWdodCAqICAoYXZnSGVpZ2h0IC8gc3RlcFNpemUpXG5cbiAgICAgIHJlY3QgPSAgc3ZnLnJlY3QgeDp4LHk6IG1heEhlaWdodCAtIGhlaWdodCx3aWR0aDp3aWR0aCAtIGNlbGxXaWR0aCAvIDQsaGVpZ2h0OmhlaWdodCxzdHlsZTpcbiAgICAgICAgXCJzdHJva2U6cmVkO3N0cm9rZS13aWR0aDoxO1wiXG4gICAgICByZWN0LnJvd1BvcyA9IG5cbiAgICAgIHMuYXBwZW5kQ2hpbGQgcmVjdFxuICAgICAgeCArPSB3aWR0aFxuICAgICAgbiArPSBzdGVwU2l6ZVxuXG4gICAgQGVsLmFwcGVuZENoaWxkIHNcbiAgICBAXG5cbiAgI1RPRE86IG1ha2UgbW9yZSBnZW5lcmFsIHdpdGggSGVhZGVyVmlld1xuICBfb25jbGljazogKGV2dCkgLT5cbiAgICByb3dQb3MgPSBldnQudGFyZ2V0LnJvd1Bvc1xuICAgIHN0ZXBTaXplID0gQGcuem9vbWVyLmdldChcInN0ZXBTaXplXCIpXG4gICAgIyBzaW11bGF0ZSBoaWRkZW4gY29sdW1uc1xuICAgIGZvciBpIGluIFswLi5zdGVwU2l6ZSAtIDFdIGJ5IDFcbiAgICAgIEBnLnRyaWdnZXIgXCJiYXI6Y2xpY2tcIiwge3Jvd1Bvczogcm93UG9zICsgaSwgZXZ0OmV2dH1cblxuICBtYW5hZ2VFdmVudHM6IC0+XG4gICAgZXZlbnRzID0ge31cbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUNsaWNrc1wiXG4gICAgICBldmVudHMuY2xpY2sgPSBcIl9vbmNsaWNrXCJcbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUhvdmVyXCJcbiAgICAgIGV2ZW50cy5tb3VzZWluID0gXCJfb25tb3VzZWluXCJcbiAgICAgIGV2ZW50cy5tb3VzZW91dCA9IFwiX29ubW91c2VvdXRcIlxuICAgIEBkZWxlZ2F0ZUV2ZW50cyBldmVudHNcbiAgICBAbGlzdGVuVG8gQGcuY29uZmlnLCBcImNoYW5nZTpyZWdpc3Rlck1vdXNlSG92ZXJcIiwgQG1hbmFnZUV2ZW50c1xuICAgIEBsaXN0ZW5UbyBAZy5jb25maWcsIFwiY2hhbmdlOnJlZ2lzdGVyTW91c2VDbGlja1wiLCBAbWFuYWdlRXZlbnRzXG5cbiAgX29ubW91c2VpbjogKGV2dCkgLT5cbiAgICByb3dQb3MgPSBAZy56b29tZXIuZ2V0IFwic3RlcFNpemVcIiAqIGV2dC5yb3dQb3NcbiAgICBAZy50cmlnZ2VyIFwiYmFyOm1vdXNlaW5cIiwge3Jvd1Bvczogcm93UG9zLCBldnQ6ZXZ0fVxuXG4gIF9vbm1vdXNlb3V0OiAoZXZ0KSAtPlxuICAgIHJvd1BvcyA9IEBnLnpvb21lci5nZXQgXCJzdGVwU2l6ZVwiICogZXZ0LnJvd1Bvc1xuICAgIEBnLnRyaWdnZXIgXCJiYXI6bW91c2VvdXRcIiwge3Jvd1Bvczogcm93UG9zLCBldnQ6ZXZ0fVxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbnNlcnZhdGlvblZpZXdcbiIsIk1hcmtlclZpZXcgPSByZXF1aXJlIFwiLi9NYXJrZXJWaWV3XCJcbkNvbnNlcnZhdGlvblZpZXcgPSByZXF1aXJlIFwiLi9Db25zZXJ2YXRpb25WaWV3XCJcbmlkZW50aXR5Q2FsYyA9IHJlcXVpcmUgXCIuLi8uLi9hbGdvL2lkZW50aXR5Q2FsY1wiXG5ib25lVmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS1jaGlsZHNcIilcbl8gPSByZXF1aXJlICd1bmRlcnNjb3JlJ1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJvbmVWaWV3LmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQGJsb2NrRXZlbnRzID0gZmFsc2VcblxuICAgIEBsaXN0ZW5UbyBAZy52aXMsXCJjaGFuZ2U6bWFya2VycyBjaGFuZ2U6Y29uc2VydlwiLCAtPlxuICAgICAgQGRyYXcoKVxuICAgICAgQHJlbmRlcigpXG4gICAgQGxpc3RlblRvIEBnLnZpcyxcImNoYW5nZVwiLCBAX3NldFNwYWNlclxuICAgIEBsaXN0ZW5UbyBAZy56b29tZXIsXCJjaGFuZ2U6YWxpZ25tZW50V2lkdGhcIiwgLT5cbiAgICAgIEBfYWRqdXN0V2lkdGgoKVxuICAgIEBsaXN0ZW5UbyBAZy56b29tZXIsIFwiY2hhbmdlOl9hbGlnbm1lbnRTY3JvbGxMZWZ0XCIsIEBfYWRqdXN0U2Nyb2xsaW5nTGVmdFxuXG4gICAgIyBUT0RPOiBkdXBsaWNhdGUgcmVuZGVyaW5nXG4gICAgQGxpc3RlblRvIEBnLmNvbHVtbnMsIFwiY2hhbmdlOmhpZGRlblwiLCAtPlxuICAgICAgQGRyYXcoKVxuICAgICAgQHJlbmRlcigpXG5cbiAgICBAZHJhdygpXG4gICAgQF9vbnNjcm9sbCA9IEBfc2VuZFNjcm9sbEV2ZW50XG5cbiAgICBAZy52aXMub25jZSAnY2hhbmdlOmxvYWRlZCcsIEBfYWRqdXN0U2Nyb2xsaW5nTGVmdCwgQFxuXG4gIGV2ZW50czpcbiAgICBcInNjcm9sbFwiOiBcIl9vbnNjcm9sbFwiXG5cbiAgZHJhdzogLT5cbiAgICBAcmVtb3ZlVmlld3MoKVxuXG4gICAgdW5sZXNzIEBpc05vdERpcnR5XG4gICAgICAjIG9ubHkgZXhlY3V0ZWQgd2hlbiBuZXcgc2VxdWVuY2VzIGFyZSBhZGRlZCBvciBvbiBzdGFydFxuICAgICAgY29uc2Vuc3VzID0gQGcuY29uc2Vuc3VzLmdldENvbnNlbnN1cyBAbW9kZWxcbiAgICAgIGlkZW50aXR5Q2FsYyBAbW9kZWwsIGNvbnNlbnN1c1xuICAgICAgQGlzTm90RGlydHkgPSB0cnVlXG5cbiAgICBpZiBAZy52aXMuZ2V0IFwiY29uc2VydlwiXG4gICAgICBjb25zZXJ2ID0gbmV3IENvbnNlcnZhdGlvblZpZXcge21vZGVsOiBAbW9kZWwsIGc6IEBnfVxuICAgICAgY29uc2Vydi5vcmRlcmluZyA9IC0yMFxuICAgICAgQGFkZFZpZXcgXCJjb25zZXJ2XCIsY29uc2VydlxuXG4gICAgaWYgQGcudmlzLmdldCBcIm1hcmtlcnNcIlxuICAgICAgbWFya2VyID0gbmV3IE1hcmtlclZpZXcge21vZGVsOiBAbW9kZWwsIGc6IEBnfVxuICAgICAgbWFya2VyLm9yZGVyaW5nID0gLTEwXG4gICAgICBAYWRkVmlldyBcIm1hcmtlclwiLG1hcmtlclxuXG4gIHJlbmRlcjogLT5cbiAgICBAcmVuZGVyU3Vidmlld3MoKVxuXG4gICAgQF9zZXRTcGFjZXIoKVxuXG4gICAgQGVsLmNsYXNzTmFtZSA9IFwiYmlvanNfbXNhX2hlYWRlclwiXG4gICAgQGVsLnN0eWxlLm92ZXJmbG93WCA9IFwiYXV0b1wiXG4gICAgQF9hZGp1c3RXaWR0aCgpXG4gICAgQF9hZGp1c3RTY3JvbGxpbmdMZWZ0KClcbiAgICBAXG5cbiAgIyBzY3JvbGxMZWZ0IHRyaWdnZXJzIGEgcmVmbG93IG9mIHRoZSB3aG9sZSBhcmVhIChldmVuIG9ubHkgZ2V0KVxuICBfc2VuZFNjcm9sbEV2ZW50OiAtPlxuICAgIHVubGVzcyBAYmxvY2tFdmVudHNcbiAgICAgIEBnLnpvb21lci5zZXQgXCJfYWxpZ25tZW50U2Nyb2xsTGVmdFwiLCBAZWwuc2Nyb2xsTGVmdCwge29yaWdpbjogXCJoZWFkZXJcIn1cbiAgICBAYmxvY2tFdmVudHMgPSBmYWxzZVxuXG4gIF9hZGp1c3RTY3JvbGxpbmdMZWZ0OiAobW9kZWwsdmFsdWUsb3B0aW9ucykgLT5cbiAgICBpZiAobm90IG9wdGlvbnM/Lm9yaWdpbj8pIG9yIG9wdGlvbnMub3JpZ2luIGlzbnQgXCJoZWFkZXJcIlxuICAgICAgc2Nyb2xsTGVmdCA9IEBnLnpvb21lci5nZXQgXCJfYWxpZ25tZW50U2Nyb2xsTGVmdFwiXG4gICAgICBAYmxvY2tFdmVudHMgPSB0cnVlXG4gICAgICBAZWwuc2Nyb2xsTGVmdCA9IHNjcm9sbExlZnRcblxuICBfc2V0U3BhY2VyOiAtPlxuICAgICMgc3BhY2VyIC8gcGFkZGluZyBlbGVtZW50XG4gICAgQGVsLnN0eWxlLm1hcmdpbkxlZnQgPSBAX2dldExhYmVsV2lkdGgoKSArIFwicHhcIlxuXG4gIF9nZXRMYWJlbFdpZHRoOiAtPlxuICAgIHBhZGRpbmdMZWZ0ID0gMFxuICAgIHBhZGRpbmdMZWZ0ICs9IEBnLnpvb21lci5nZXQgXCJsYWJlbFdpZHRoXCIgaWYgQGcudmlzLmdldCBcImxhYmVsc1wiXG4gICAgcGFkZGluZ0xlZnQgKz0gQGcuem9vbWVyLmdldCBcIm1ldGFXaWR0aFwiIGlmIEBnLnZpcy5nZXQgXCJtZXRhY2VsbFwiXG4gICAgcmV0dXJuIHBhZGRpbmdMZWZ0XG5cbiAgX2FkanVzdFdpZHRoOiAtPlxuICAgIEBlbC5zdHlsZS53aWR0aCA9IEBnLnpvb21lci5nZXQoXCJhbGlnbm1lbnRXaWR0aFwiKSArIFwicHhcIlxuIiwidmlldyA9IHJlcXVpcmUoXCJiYWNrYm9uZS12aWV3alwiKVxuZG9tID0gcmVxdWlyZShcImRvbS1oZWxwZXJcIilcbnN2ZyA9IHJlcXVpcmUoXCIuLi8uLi91dGlscy9zdmdcIilcbmpib25lID0gcmVxdWlyZSBcImpib25lXCJcblxuSGVhZGVyVmlldyA9IHZpZXcuZXh0ZW5kXG5cbiAgY2xhc3NOYW1lOiBcImJpb2pzX21zYV9tYXJrZXJcIlxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQGxpc3RlblRvIEBnLnpvb21lcixcImNoYW5nZTpzdGVwU2l6ZSBjaGFuZ2U6bGFiZWxXaWR0aCBjaGFuZ2U6Y29sdW1uV2lkdGggY2hhbmdlOm1hcmtlclN0ZXBTaXplIGNoYW5nZTptYXJrZXJGb250c2l6ZVwiLCBAcmVuZGVyXG4gICAgQGxpc3RlblRvIEBnLnZpcyxcImNoYW5nZTpsYWJlbHMgY2hhbmdlOm1ldGFjZWxsXCIsIEByZW5kZXJcbiAgICBAbWFuYWdlRXZlbnRzKClcblxuICByZW5kZXI6IC0+XG4gICAgZG9tLnJlbW92ZUFsbENoaWxkcyBAZWxcblxuICAgIEBlbC5zdHlsZS5mb250U2l6ZSA9IEBnLnpvb21lci5nZXQgXCJtYXJrZXJGb250c2l6ZVwiXG5cbiAgICBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwic3BhblwiXG4gICAgbiA9IDBcbiAgICBjZWxsV2lkdGggPSBAZy56b29tZXIuZ2V0IFwiY29sdW1uV2lkdGhcIlxuXG4gICAgbk1heCA9IEBtb2RlbC5nZXRNYXhMZW5ndGgoKVxuICAgIHN0ZXBTaXplID0gQGcuem9vbWVyLmdldChcInN0ZXBTaXplXCIpXG4gICAgaGlkZGVuID0gQGcuY29sdW1ucy5nZXQgXCJoaWRkZW5cIlxuXG4gICAgd2hpbGUgbiA8IG5NYXhcbiAgICAgIGlmIGhpZGRlbi5pbmRleE9mKG4pID49IDBcbiAgICAgICAgQG1hcmtlckhpZGRlbihzcGFuLG4sIHN0ZXBTaXplKVxuICAgICAgICBuICs9IHN0ZXBTaXplXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICBzcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcInNwYW5cIlxuICAgICAgc3Bhbi5zdHlsZS53aWR0aCA9IChjZWxsV2lkdGggKiBzdGVwU2l6ZSkgKyBcInB4XCJcbiAgICAgIHNwYW4uc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcbiAgICAgICMgVE9ETzogdGhpcyBkb2Vzbid0IHdvcmsgZm9yIGEgbGFyZ2VyIHN0ZXBTaXplXG4gICAgICBpZiAobiArIDEpICUgQGcuem9vbWVyLmdldCgnbWFya2VyU3RlcFNpemUnKSBpcyAwXG4gICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSAobiArIDEpXG4gICAgICBlbHNlXG4gICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSBcIi5cIlxuICAgICAgc3Bhbi5yb3dQb3MgPSBuXG5cbiAgICAgIG4gKz0gc3RlcFNpemVcbiAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCBzcGFuXG5cbiAgICBAZWwuYXBwZW5kQ2hpbGQgY29udGFpbmVyXG4gICAgQFxuXG4gIG1hcmtlckhpZGRlbjogKHNwYW4sbixzdGVwU2l6ZSkgLT5cbiAgICBoaWRkZW4gPSBAZy5jb2x1bW5zLmdldChcImhpZGRlblwiKS5zbGljZSAwXG5cbiAgICBtaW4gPSBNYXRoLm1heCAwLCBuIC0gc3RlcFNpemVcbiAgICBwcmV2SGlkZGVuID0gdHJ1ZVxuICAgIGZvciBqIGluICBbbWluIC4uIG5dIGJ5IDFcbiAgICAgIHByZXZIaWRkZW4gJj0gaGlkZGVuLmluZGV4T2YoaikgPj0gMFxuXG4gICAgIyBmaWx0ZXIgZHVwbGljYXRlc1xuICAgIHJldHVybiBpZiBwcmV2SGlkZGVuXG5cbiAgICBuTWF4ID0gQG1vZGVsLmdldE1heExlbmd0aCgpXG5cbiAgICBsZW5ndGggPSAwXG4gICAgaW5kZXggPSAtMVxuICAgICMgYWNjdW1sYXRlIG11bHRpcGxlIHJvd3NcbiAgICBmb3IgbiBpbiBbbi4ubk1heF0gYnkgMVxuICAgICAgaW5kZXggPSBoaWRkZW4uaW5kZXhPZihuKSB1bmxlc3MgaW5kZXggPj0gMCMgc2V0cyB0aGUgZmlyc3QgaW5kZXhcbiAgICAgIGlmIGhpZGRlbi5pbmRleE9mKG4pID49IDBcbiAgICAgICAgbGVuZ3RoKytcbiAgICAgIGVsc2VcbiAgICAgICAgYnJlYWtcblxuICAgIHMgPSBzdmcuYmFzZSBoZWlnaHQ6IDEwLCB3aWR0aDogMTBcbiAgICBzLnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiXG4gICAgdHJpYW5nbGUgPSBzdmcucG9seWdvbiBwb2ludHM6IFwiMCwwIDUsNSAxMCwwXCIsIHN0eWxlOlxuICAgICAgXCJmaWxsOmxpbWU7c3Ryb2tlOnB1cnBsZTtzdHJva2Utd2lkdGg6MVwiXG4gICAgamJvbmUodHJpYW5nbGUpLm9uIFwiY2xpY2tcIiwgKGV2dCkgPT5cbiAgICAgIGhpZGRlbi5zcGxpY2UgaW5kZXgsIGxlbmd0aFxuICAgICAgQGcuY29sdW1ucy5zZXQgXCJoaWRkZW5cIiwgaGlkZGVuXG5cbiAgICBzLmFwcGVuZENoaWxkIHRyaWFuZ2xlXG4gICAgc3Bhbi5hcHBlbmRDaGlsZCBzXG4gICAgcmV0dXJuIHNcblxuICBtYW5hZ2VFdmVudHM6IC0+XG4gICAgZXZlbnRzID0ge31cbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUNsaWNrc1wiXG4gICAgICBldmVudHMuY2xpY2sgPSBcIl9vbmNsaWNrXCJcbiAgICBpZiBAZy5jb25maWcuZ2V0IFwicmVnaXN0ZXJNb3VzZUhvdmVyXCJcbiAgICAgIGV2ZW50cy5tb3VzZWluID0gXCJfb25tb3VzZWluXCJcbiAgICAgIGV2ZW50cy5tb3VzZW91dCA9IFwiX29ubW91c2VvdXRcIlxuICAgIEBkZWxlZ2F0ZUV2ZW50cyBldmVudHNcbiAgICBAbGlzdGVuVG8gQGcuY29uZmlnLCBcImNoYW5nZTpyZWdpc3Rlck1vdXNlSG92ZXJcIiwgQG1hbmFnZUV2ZW50c1xuICAgIEBsaXN0ZW5UbyBAZy5jb25maWcsIFwiY2hhbmdlOnJlZ2lzdGVyTW91c2VDbGlja1wiLCBAbWFuYWdlRXZlbnRzXG5cbiAgX29uY2xpY2s6IChldnQpIC0+XG4gICAgcm93UG9zID0gZXZ0LnRhcmdldC5yb3dQb3NcbiAgICBzdGVwU2l6ZSA9IEBnLnpvb21lci5nZXQoXCJzdGVwU2l6ZVwiKVxuICAgIEBnLnRyaWdnZXIgXCJjb2x1bW46Y2xpY2tcIiwge3Jvd1Bvczogcm93UG9zLHN0ZXBTaXplOiBzdGVwU2l6ZSwgZXZ0OmV2dH1cblxuICBfb25tb3VzZWluOiAoZXZ0KSAtPlxuICAgIHJvd1BvcyA9IEBnLnpvb21lci5nZXQgXCJzdGVwU2l6ZVwiICogZXZ0LnJvd1Bvc1xuICAgIHN0ZXBTaXplID0gQGcuem9vbWVyLmdldChcInN0ZXBTaXplXCIpXG4gICAgQGcudHJpZ2dlciBcImNvbHVtbjptb3VzZWluXCIsIHtyb3dQb3M6IHJvd1BvcyxzdGVwU2l6ZTogc3RlcFNpemUsIGV2dDpldnR9XG5cbiAgX29ubW91c2VvdXQ6IChldnQpIC0+XG4gICAgcm93UG9zID0gQGcuem9vbWVyLmdldCBcInN0ZXBTaXplXCIgKiBldnQucm93UG9zXG4gICAgc3RlcFNpemUgPSBAZy56b29tZXIuZ2V0KFwic3RlcFNpemVcIilcbiAgICBAZy50cmlnZ2VyIFwiY29sdW1uOm1vdXNlb3V0XCIsIHtyb3dQb3M6IHJvd1BvcyxzdGVwU2l6ZTogc3RlcFNpemUsIGV2dDpldnR9XG5cbm1vZHVsZS5leHBvcnRzID0gSGVhZGVyVmlld1xuIiwiTGFiZWxSb3dWaWV3ID0gcmVxdWlyZSBcIi4vTGFiZWxSb3dWaWV3XCJcbmJvbmVWaWV3ID0gcmVxdWlyZShcImJhY2tib25lLWNoaWxkc1wiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJvbmVWaWV3LmV4dGVuZFxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG4gICAgQGRyYXcoKVxuICAgIEBsaXN0ZW5UbyBAZy56b29tZXIsIFwiY2hhbmdlOl9hbGlnbm1lbnRTY3JvbGxUb3BcIiwgQF9hZGp1c3RTY3JvbGxpbmdUb3BcbiAgICBAZy52aXMub25jZSAnY2hhbmdlOmxvYWRlZCcsIEBfYWRqdXN0U2Nyb2xsaW5nVG9wICwgQFxuXG4gIGRyYXc6IC0+XG4gICAgQHJlbW92ZVZpZXdzKClcbiAgICBmb3IgaSBpbiBbMC4uIEBtb2RlbC5sZW5ndGggLSAxXSBieSAxXG4gICAgICBjb250aW51ZSBpZiBAbW9kZWwuYXQoaSkuZ2V0KCdoaWRkZW4nKVxuICAgICAgdmlldyA9IG5ldyBMYWJlbFJvd1ZpZXcge21vZGVsOiBAbW9kZWwuYXQoaSksIGc6IEBnfVxuICAgICAgdmlldy5vcmRlcmluZyA9IGlcbiAgICAgIEBhZGRWaWV3IFwicm93XyN7aX1cIiwgdmlld1xuXG4gIGV2ZW50czpcbiAgICBcInNjcm9sbFwiOiBcIl9zZW5kU2Nyb2xsRXZlbnRcIlxuXG4gICMgYnJvYWRjYXN0IHRoZSBzY3JvbGxpbmcgZXZlbnQgKGJ5IHRoZSBzY3JvbGxiYXIpXG4gIF9zZW5kU2Nyb2xsRXZlbnQ6IC0+XG4gICAgQGcuem9vbWVyLnNldCBcIl9hbGlnbm1lbnRTY3JvbGxUb3BcIiwgQGVsLnNjcm9sbFRvcCwge29yaWdpbjogXCJsYWJlbFwifVxuXG4gICMgc2V0cyB0aGUgc2Nyb2xsaW5nIHByb3BlcnR5IChmcm9tIGFub3RoZXIgZXZlbnQgZS5nLiBkcmFnZ2luZylcbiAgX2FkanVzdFNjcm9sbGluZ1RvcDogLT5cbiAgICBAZWwuc2Nyb2xsVG9wID0gIEBnLnpvb21lci5nZXQgXCJfYWxpZ25tZW50U2Nyb2xsVG9wXCJcblxuICByZW5kZXI6IC0+XG4gICAgQHJlbmRlclN1YnZpZXdzKClcbiAgICBAZWwuY2xhc3NOYW1lID0gXCJiaW9qc19tc2FfbGFiZWxibG9ja1wiXG4gICAgQGVsLnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiXG4gICAgQGVsLnN0eWxlLnZlcnRpY2FsQWxpZ24gPSBcInRvcFwiXG4gICAgQGVsLnN0eWxlLmhlaWdodCA9ICBAZy56b29tZXIuZ2V0KFwiYWxpZ25tZW50SGVpZ2h0XCIpICsgXCJweFwiXG4gICAgQGVsLnN0eWxlLm92ZXJmbG93WSA9IFwiYXV0b1wiXG4gICAgQGVsLnN0eWxlLm92ZXJmbG93WCA9IFwiaGlkZGVuXCJcbiAgICBAZWwuc3R5bGUuZm9udFNpemUgPSBcIiN7QGcuem9vbWVyLmdldCBcImxhYmVsRm9udHNpemVcIn1cIlxuICAgIEBlbC5zdHlsZS5saW5lSGVpZ2h0ID0gXCIje0BnLnpvb21lci5nZXQgXCJsYWJlbExpbmVIZWlnaHRcIn1cIlxuICAgIEBcbiIsImJvbmVWaWV3ID0gcmVxdWlyZShcImJhY2tib25lLWNoaWxkc1wiKVxuTGFiZWxWaWV3ID0gcmVxdWlyZShcIi4vTGFiZWxWaWV3XCIpXG5NZXRhVmlldyA9IHJlcXVpcmUoXCIuL01ldGFWaWV3XCIpXG5cbm1vZHVsZS5leHBvcnRzID0gYm9uZVZpZXcuZXh0ZW5kXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQGcgPSBkYXRhLmdcbiAgICBAZHJhdygpXG5cbiAgICBAbGlzdGVuVG8gQGcudmlzLFwiY2hhbmdlOmxhYmVsc1wiLCBAZHJhd1JcbiAgICBAbGlzdGVuVG8gQGcudmlzLFwiY2hhbmdlOm1ldGFjZWxsXCIsIEBkcmF3UlxuXG4gIGRyYXc6IC0+XG4gICAgQHJlbW92ZVZpZXdzKClcbiAgICBpZiBAZy52aXMuZ2V0IFwibGFiZWxzXCJcbiAgICAgIEBhZGRWaWV3IFwibGFiZWxzXCIsIG5ldyBMYWJlbFZpZXcge21vZGVsOiBAbW9kZWwsIGc6QGd9XG4gICAgaWYgQGcudmlzLmdldCBcIm1ldGFjZWxsXCJcbiAgICAgIEBhZGRWaWV3IFwibWV0YWNlbGxcIiwgbmV3IE1ldGFWaWV3IHttb2RlbDogQG1vZGVsLCBnOkBnfVxuXG4gIGRyYXdSOiAtPlxuICAgIEBkcmF3KClcbiAgICBAcmVuZGVyKClcblxuICByZW5kZXI6IC0+XG4gICAgQHJlbmRlclN1YnZpZXdzKClcbiAgICBAZWwuc2V0QXR0cmlidXRlIFwiY2xhc3NcIiwgXCJiaW9qc19tc2FfbGFiZWxyb3dcIlxuICAgIEBlbC5zdHlsZS5oZWlnaHQgPSBAZy56b29tZXIuZ2V0IFwicm93SGVpZ2h0XCJcbiAgICBAXG4iLCJ2aWV3ID0gcmVxdWlyZShcImJhY2tib25lLXZpZXdqXCIpXG5kb20gPSByZXF1aXJlIFwiZG9tLWhlbHBlclwiXG5cbkxhYmVsVmlldyA9IHZpZXcuZXh0ZW5kXG5cbiAgaW5pdGlhbGl6ZTogKGRhdGEpIC0+XG4gICAgQHNlcSA9IGRhdGEuc2VxXG4gICAgQGcgPSBkYXRhLmdcblxuICAgIEBtYW5hZ2VFdmVudHMoKVxuXG4gIG1hbmFnZUV2ZW50czogLT5cbiAgICBldmVudHMgPSB7fVxuICAgIGlmIEBnLmNvbmZpZy5nZXQgXCJyZWdpc3Rlck1vdXNlQ2xpY2tzXCJcbiAgICAgIGV2ZW50cy5jbGljayA9IFwiX29uY2xpY2tcIlxuICAgIGlmIEBnLmNvbmZpZy5nZXQgXCJyZWdpc3Rlck1vdXNlSG92ZXJcIlxuICAgICAgZXZlbnRzLm1vdXNlaW4gPSBcIl9vbm1vdXNlaW5cIlxuICAgICAgZXZlbnRzLm1vdXNlb3V0ID0gXCJfb25tb3VzZW91dFwiXG4gICAgQGRlbGVnYXRlRXZlbnRzIGV2ZW50c1xuICAgIEBsaXN0ZW5UbyBAZy5jb25maWcsIFwiY2hhbmdlOnJlZ2lzdGVyTW91c2VIb3ZlclwiLCBAbWFuYWdlRXZlbnRzXG4gICAgQGxpc3RlblRvIEBnLmNvbmZpZywgXCJjaGFuZ2U6cmVnaXN0ZXJNb3VzZUNsaWNrXCIsIEBtYW5hZ2VFdmVudHNcbiAgICBAbGlzdGVuVG8gQGcudmlzLCBcImNoYW5nZTpsYWJlbE5hbWVcIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAZy52aXMsIFwiY2hhbmdlOmxhYmVsSWRcIiwgQHJlbmRlclxuICAgIEBsaXN0ZW5UbyBAZy52aXMsIFwiY2hhbmdlOmxhYmVsUGFydGl0aW9uXCIsIEByZW5kZXJcbiAgICBAbGlzdGVuVG8gQGcudmlzLCBcImNoYW5nZTpsYWJlbENoZWNrYm94XCIsIEByZW5kZXJcblxuICByZW5kZXI6IC0+XG4gICAgZG9tLnJlbW92ZUFsbENoaWxkcyBAZWxcblxuICAgIEBlbC5zdHlsZS53aWR0aCA9IFwiI3tAZy56b29tZXIuZ2V0IFwibGFiZWxXaWR0aFwifXB4XCJcbiAgICBAZWwuc3R5bGUuaGVpZ2h0ID0gXCIje0BnLnpvb21lci5nZXQgXCJyb3dIZWlnaHRcIn1weFwiXG4gICAgQGVsLnNldEF0dHJpYnV0ZSBcImNsYXNzXCIsIFwiYmlvanNfbXNhX2xhYmVsc1wiXG5cbiAgICBpZiBALmcudmlzLmdldCBcImxhYmVsQ2hlY2tib3hcIlxuICAgICAgY2hlY2tCb3ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwiaW5wdXRcIlxuICAgICAgY2hlY2tCb3guc2V0QXR0cmlidXRlIFwidHlwZVwiLCBcImNoZWNrYm94XCJcbiAgICAgIGNoZWNrQm94LnZhbHVlID0gQG1vZGVsLmdldCgnaWQnKVxuICAgICAgY2hlY2tCb3gubmFtZSA9IFwic2VxXCJcbiAgICAgIEBlbC5hcHBlbmRDaGlsZCBjaGVja0JveFxuXG4gICAgaWYgQC5nLnZpcy5nZXQgXCJsYWJlbElkXCJcbiAgICAgIGlkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcInNwYW5cIlxuICAgICAgaWQudGV4dENvbnRlbnQgPSBAbW9kZWwuZ2V0IFwiaWRcIlxuICAgICAgaWQuc3R5bGUud2lkdGggPSBAZy56b29tZXIuZ2V0IFwibGFiZWxJZExlbmd0aFwiXG4gICAgICBpZC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuICAgICAgQGVsLmFwcGVuZENoaWxkIGlkXG5cbiAgICBpZiBALmcudmlzLmdldCBcImxhYmVsUGFydGl0aW9uXCJcbiAgICAgIHBhcnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwic3BhblwiXG4gICAgICBwYXJ0LnN0eWxlLndpZHRoID0gMTVcbiAgICAgIHBhcnQudGV4dENvbnRlbnQgPSBAbW9kZWwuZ2V0KFwicGFydGl0aW9uXCIpXG4gICAgICBwYXJ0LnN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiXG4gICAgICBAZWwuYXBwZW5kQ2hpbGQgaWRcbiAgICAgIEBlbC5hcHBlbmRDaGlsZCBwYXJ0XG5cbiAgICBpZiBALmcudmlzLmdldCBcImxhYmVsTmFtZVwiXG4gICAgICBuYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcInNwYW5cIlxuICAgICAgbmFtZS50ZXh0Q29udGVudCA9IEBtb2RlbC5nZXQoXCJuYW1lXCIpXG4gICAgICBAZWwuYXBwZW5kQ2hpbGQgbmFtZVxuXG5cbiAgICBAZWwuc3R5bGUub3ZlcmZsb3cgPSBzY3JvbGxcbiAgICBAXG5cbiAgX29uY2xpY2s6IChldnQpIC0+XG4gICAgc2VxSWQgPSBAbW9kZWwuZ2V0IFwiaWRcIlxuICAgIEBnLnRyaWdnZXIgXCJyb3c6Y2xpY2tcIiwge3NlcUlkOnNlcUlkLCBldnQ6ZXZ0fVxuXG4gIF9vbm1vdXNlaW46IChldnQpIC0+XG4gICAgc2VxSWQgPSBAbW9kZWwuZ2V0IFwiaWRcIlxuICAgIEBnLnRyaWdnZXIgXCJyb3c6bW91c2VvdXRcIiwge3NlcUlkOnNlcUlkLCBldnQ6ZXZ0fVxuXG4gIF9vbm1vdXNlb3V0OiAoZXZ0KSAtPlxuICAgIHNlcUlkID0gQG1vZGVsLmdldCBcImlkXCJcbiAgICBAZy50cmlnZ2VyIFwicm93Om1vdXNlb3V0XCIsIHtzZXFJZDpzZXFJZCwgZXZ0OmV2dH1cblxubW9kdWxlLmV4cG9ydHMgPSBMYWJlbFZpZXdcbiIsInZpZXcgPSByZXF1aXJlKFwiYmFja2JvbmUtdmlld2pcIilcbk1lbnVCdWlsZGVyID0gcmVxdWlyZSBcIi4uLy4uL21lbnUvbWVudWJ1aWxkZXJcIlxuXyA9IHJlcXVpcmUgJ3VuZGVyc2NvcmUnXG5kb20gPSByZXF1aXJlIFwiZG9tLWhlbHBlclwiXG5cbm1vZHVsZS5leHBvcnRzID0gTWV0YVZpZXcgPSB2aWV3LmV4dGVuZFxuXG4gIGNsYXNzTmFtZTogXCJiaW9qc19tc2FfbWV0YXZpZXdcIlxuXG4gIGluaXRpYWxpemU6IChkYXRhKSAtPlxuICAgIEBnID0gZGF0YS5nXG5cbiAgZXZlbnRzOlxuICAgIGNsaWNrOiBcIl9vbmNsaWNrXCJcbiAgICBtb3VzZWluOiBcIl9vbm1vdXNlaW5cIlxuICAgIG1vdXNlb3V0OiBcIl9vbm1vdXNlb3V0XCJcblxuICByZW5kZXI6IC0+XG4gICAgZG9tLnJlbW92ZUFsbENoaWxkcyBAZWxcblxuICAgIEBlbC5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuXG4gICAgd2lkdGggPSBAZy56b29tZXIuZ2V0IFwibWV0YVdpZHRoXCJcbiAgICBAZWwuc3R5bGUud2lkdGggPSB3aWR0aCAtIDVcbiAgICBAZWwuc3R5bGUucGFkZGluZ1JpZ2h0ID0gNVxuXG4gICAgIyBhZGRzIGdhcHNcbiAgICBzZXEgPSBAbW9kZWwuZ2V0KCdzZXEnKVxuICAgIGdhcHMgPSBfLnJlZHVjZSBzZXEsICgobWVtbywgYykgLT4gbWVtbysrIGlmIGMgaXMgJy0nO21lbW8pLDBcbiAgICBnYXBzID0gKGdhcHMgLyBzZXEubGVuZ3RoKS50b0ZpeGVkKDEpXG5cbiAgICAjIGFwcGVuZCBnYXAgY291bnRcbiAgICBnYXBTcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCAnc3BhbidcbiAgICBnYXBTcGFuLnRleHRDb250ZW50ID0gZ2Fwc1xuICAgIGdhcFNwYW4uc3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCJcbiAgICBnYXBTcGFuLnN0eWxlLndpZHRoID0gMzVcbiAgICBAZWwuYXBwZW5kQ2hpbGQgZ2FwU3BhblxuXG4gICAgIyBpZGVudGl0eVxuICAgIGlkZW50ID0gQG1vZGVsLmdldCgnaWRlbnRpdHknKVxuICAgIGlkZW50U3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgJ3NwYW4nXG4gICAgaWRlbnRTcGFuLnRleHRDb250ZW50ID0gaWRlbnQudG9GaXhlZCgyKVxuICAgIGlkZW50U3Bhbi5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuICAgIGlkZW50U3Bhbi5zdHlsZS53aWR0aCA9IDQwXG4gICAgQGVsLmFwcGVuZENoaWxkIGlkZW50U3BhblxuXG4gICAgIyBUT0RPOiB0aGlzIG1lbnUgYnVpbGRlciBpcyBqdXN0IGFuIGV4YW1wbGUgaG93IG9uZSBjb3VsZCBjdXN0b21pemUgdGhpc1xuICAgICMgdmlld1xuICAgIG1lbnUgPSBuZXcgTWVudUJ1aWxkZXIoXCLihpdcIilcbiAgICBtZW51LmFkZE5vZGUgXCJVbmlwcm90XCIsKGUpID0+XG4gICAgICB3aW5kb3cub3BlbiBcImh0dHA6Ly9iZXRhLnVuaXByb3Qub3JnL3VuaXByb3QvUTdUMk44XCJcbiAgICBAZWwuYXBwZW5kQ2hpbGQgbWVudS5idWlsZERPTSgpXG4gICAgQGVsLndpZHRoID0gMTBcblxuICAgIEBlbC5zdHlsZS5oZWlnaHQgPSBcIiN7QGcuem9vbWVyLmdldCBcInJvd0hlaWdodFwifXB4XCJcbiAgICBAZWwuc3R5bGUuY3Vyc29yID0gXCJwb2ludGVyXCJcblxuICBfb25jbGljazogKGV2dCkgLT5cbiAgICBAZy50cmlnZ2VyIFwibWV0YTpjbGlja1wiLCB7c2VxSWQ6IEBtb2RlbC5nZXQgXCJpZFwiLCBldnQ6ZXZ0fVxuXG4gIF9vbm1vdXNlaW46IChldnQpIC0+XG4gICAgQGcudHJpZ2dlciBcIm1ldGE6bW91c2VpblwiLCB7c2VxSWQ6IEBtb2RlbC5nZXQgXCJpZFwiLCBldnQ6ZXZ0fVxuXG4gIF9vbm1vdXNlb3V0OiAoZXZ0KSAtPlxuICAgIEBnLnRyaWdnZXIgXCJtZXRhOm1vdXNlb3V0XCIsIHtzZXFJZDogQG1vZGVsLmdldCBcImlkXCIsIGV2dDpldnR9XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuOC4wXG52YXIgQ2x1c3RhbCwgR2VuZXJpY1JlYWRlciwgU2VxLCBTdHIsXG4gIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5LFxuICBfX2V4dGVuZHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKF9faGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfTtcblxuU3RyID0gcmVxdWlyZShcIi4vc3RyaW5nc1wiKTtcblxuR2VuZXJpY1JlYWRlciA9IHJlcXVpcmUoXCIuL2dlbmVyaWNfcmVhZGVyXCIpO1xuXG5TZXEgPSByZXF1aXJlKFwiLi9zZXFcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gQ2x1c3RhbCA9IChmdW5jdGlvbihfc3VwZXIpIHtcbiAgX19leHRlbmRzKENsdXN0YWwsIF9zdXBlcik7XG5cbiAgZnVuY3Rpb24gQ2x1c3RhbCgpIHtcbiAgICByZXR1cm4gQ2x1c3RhbC5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIENsdXN0YWwucGFyc2UgPSBmdW5jdGlvbih0ZXh0KSB7XG4gICAgdmFyIGJsb2Nrc3RhdGUsIGssIGxhYmVsLCBsaW5lLCBsaW5lcywgbWF0Y2gsIHJlZ2V4LCBzZXFDb3VudGVyLCBzZXFzLCBzZXF1ZW5jZTtcbiAgICBzZXFzID0gW107XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0ZXh0KSA9PT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgICAgbGluZXMgPSB0ZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICBsaW5lcyA9IHRleHQuc3BsaXQoXCJcXG5cIik7XG4gICAgfVxuICAgIGlmIChsaW5lc1swXS5zbGljZSgwLCA2KSA9PT0gIVwiQ0xVU1RBTFwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIENMVVNUQUwgSGVhZGVyXCIpO1xuICAgIH1cbiAgICBrID0gMDtcbiAgICBibG9ja3N0YXRlID0gMTtcbiAgICBzZXFDb3VudGVyID0gMDtcbiAgICB3aGlsZSAoayA8IGxpbmVzLmxlbmd0aCkge1xuICAgICAgaysrO1xuICAgICAgbGluZSA9IGxpbmVzW2tdO1xuICAgICAgaWYgKChsaW5lID09IG51bGwpIHx8IGxpbmUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGJsb2Nrc3RhdGUgPSAxO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChsaW5lLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgYmxvY2tzdGF0ZSA9IDE7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKFN0ci5jb250YWlucyhsaW5lLCBcIipcIikpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYmxvY2tzdGF0ZSA9PT0gMSkge1xuICAgICAgICAgIHNlcUNvdW50ZXIgPSAwO1xuICAgICAgICAgIGJsb2Nrc3RhdGUgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHJlZ2V4ID0gL14oPzpcXHMqKShcXFMrKSg/OlxccyspKFxcUyspKD86XFxzKikoXFxkKikoPzpcXHMqfCQpL2c7XG4gICAgICAgIG1hdGNoID0gcmVnZXguZXhlYyhsaW5lKTtcbiAgICAgICAgaWYgKG1hdGNoICE9IG51bGwpIHtcbiAgICAgICAgICBsYWJlbCA9IG1hdGNoWzFdO1xuICAgICAgICAgIHNlcXVlbmNlID0gbWF0Y2hbMl07XG4gICAgICAgICAgaWYgKHNlcUNvdW50ZXIgPj0gc2Vxcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHNlcXMucHVzaChuZXcgU2VxKHNlcXVlbmNlLCBsYWJlbCwgc2VxQ291bnRlcikpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZXFzW3NlcUNvdW50ZXJdLnNlcSArPSBzZXF1ZW5jZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VxQ291bnRlcisrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGxpbmUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzZXFzO1xuICB9O1xuXG4gIHJldHVybiBDbHVzdGFsO1xuXG59KShHZW5lcmljUmVhZGVyKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS44LjBcbm1vZHVsZS5leHBvcnRzLnBhcnNlID0gcmVxdWlyZShcIi4vcGFyc2VyXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy53cml0ZXIgPSByZXF1aXJlKFwiLi93cml0ZXJcIik7XG4iLCJpZiAodHlwZW9mIGJpb2pzID09PSAndW5kZWZpbmVkJykge1xuICBiaW9qcyA9IHt9O1xufVxuaWYgKHR5cGVvZiBiaW9qcy52aXMgPT09ICd1bmRlZmluZWQnKSB7XG4gIGJpb2pzLnZpcyA9IHt9O1xufVxuLy8gdXNlIHR3byBuYW1lc3BhY2VzXG53aW5kb3cubXNhID0gYmlvanMudmlzLm1zYSA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9pbmRleCcpO1xuXG4vLyBUT0RPOiBob3cgc2hvdWxkIHRoaXMgYmUgYnVuZGxlZFxuXG5pZiAodHlwZW9mIGJpb2pzLmlvID09PSAndW5kZWZpbmVkJykge1xuICBiaW9qcy5pbyA9IHt9O1xufVxuLy8ganVzdCBidW5kbGUgdGhlIHR3byBwYXJzZXJzXG53aW5kb3cuYmlvanMuaW8uZmFzdGEgPSByZXF1aXJlKFwiYmlvanMtaW8tZmFzdGFcIik7XG53aW5kb3cuYmlvanMuaW8uY2x1c3RhbCA9IHJlcXVpcmUoXCJiaW9qcy1pby1jbHVzdGFsXCIpO1xud2luZG93LmJpb2pzLnhociA9IHJlcXVpcmUoXCJuZXRzXCIpO1xuXG4vLyBzaW11bGF0ZSBzdGFuZGFsb25lIGZsYWdcbndpbmRvdy5iaW9qc1Zpc01zYSA9IHdpbmRvdy5tc2E7XG5cbnJlcXVpcmUoJy4vYnVpbGQvbXNhLmNzcycpO1xuIiwidmFyIHJlcSA9IHJlcXVpcmUoJ3JlcXVlc3QnKVxuXG5tb2R1bGUuZXhwb3J0cyA9IE5ldHNcblxuZnVuY3Rpb24gTmV0cyh1cmksIG9wdHMsIGNiKSB7XG4gIHJlcSh1cmksIG9wdHMsIGNiKVxufSJdfQ==
+
+
+
+// this is a way how you use a bundled file parser
+biojs.io.clustal.read("#", function(seqs){
+var opts = {};
+
+// set your custom properties
+// @see: https://github.com/greenify/biojs-vis-msa/tree/master/src/g
+
+var jalviewData = JSON.parse(document.getElementById("seqData").value);
+opts.seqs = jalviewData['seqs'];
+
+opts.el = document.getElementById("yourDiv");
+opts.vis = {conserv: false, overviewbox: false, labelId: false};
+opts.zoomer = {alignmentHeight: 225, labelWidth: 130,labelFontsize: "13px",labelIdLength: 20, menuFontsize: "12px",menuMarginLeft: "3px", menuPadding: "3px 4px 3px 4px", menuItemFontsize: "14px", menuItemLineHeight: "14px"};
+
+
+
+// init msa
+var m = new msa.msa(opts);
+
+m.g.colorscheme.set("scheme", jalviewData['globalColorScheme']);
+
+var x = 0;
+jalviewData.seqs.forEach( function (seq)
+{
+m.seqs.at(x++).set("features", new msa.model.featurecol(seq.features));
+});
+
+// the menu is independent to the MSA container
+var menuOpts = {};
+menuOpts.el = document.getElementById('div');
+menuOpts.msa = m;
+var defMenu = new msa.menu.defaultmenu(menuOpts);
+m.addView("menu", defMenu);
+
+// call render at the end to display the whole MSA
+m.render();
+
+toggleMenuVisibility();
+toggleMenuVisibility();
+});
+</script>
\ No newline at end of file
<xs:attribute name="colour" type="xs:int" />
</xs:complexType>
</xs:element>
+ <xs:element name="property" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="value" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
</xs:sequence>
<xs:attribute name="graph" type="xs:boolean" use="required" />
<xs:attribute name="graphType" type="xs:int" use="optional" />
*/
package MCview;
-import java.util.*;
-
-import java.awt.*;
-
-import jalview.analysis.*;
-import jalview.datamodel.*;
-import jalview.schemes.*;
+import jalview.analysis.AlignSeq;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.schemes.ResidueProperties;
import jalview.structure.StructureMapping;
+import java.awt.Color;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Vector;
+
public class PDBChain
{
/**
public int offset;
- public Sequence sequence;
+ /**
+ * sequence is the sequence extracted by the chain parsing code
+ */
+ public SequenceI sequence;
+
+ /**
+ * shadow is the sequence created by any other parsing processes (e.g. Jmol,
+ * RNAview)
+ */
+ public SequenceI shadow = null;
public boolean isNa = false;
*/
protected String newline = System.getProperty("line.separator");
+ public Mapping shadowMap;
+
public void setNewlineString(String nl)
{
newline = nl;
+ ((tx.getStatus() == null || tx.getStatus().length() == 0) ? ""
: ":" + tx.getStatus()));
if (tx.begin != 0 && tx.end != 0)
+ {
sq.addSequenceFeature(tx);
+ }
}
}
return features;
// remains the same as the first atom's resNumber (res)
while ((resNumber == res) && (i < atoms.size()))
{
- resAtoms.addElement((Atom) atoms.elementAt(i));
+ resAtoms.addElement(atoms.elementAt(i));
i++;
if (i < atoms.size())
{
annots[i] = (Annotation) resAnnotation.elementAt(i);
if (annots[i].value > max)
+ {
max = annots[i].value;
+ }
resAnnotation.setElementAt(null, i);
}
AlignmentAnnotation tfactorann = new AlignmentAnnotation(
}
}
- public AlignmentAnnotation[] transferResidueAnnotation(SequenceI seq,
- String status)
- {
- AlignmentAnnotation[] transferred = null;
-
- return transferred;
-
- }
-
/**
* copy any sequence annotation onto the sequence mapped using the provided
* StructureMapping
*
* @param mapping
+ * - positional mapping between destination sequence and pdb resnum
+ * @param sqmpping
+ * - mapping between destination sequence and local chain
*/
- public void transferResidueAnnotation(StructureMapping mapping)
+ public void transferResidueAnnotation(
+ StructureMapping mapping, jalview.datamodel.Mapping sqmpping)
{
SequenceI sq = mapping.getSequence();
+ SequenceI dsq = sq;
if (sq != null)
{
- if (sequence != null && sequence.getAnnotation() != null)
+ while (dsq.getDatasetSequence() != null)
+ {
+ dsq = dsq.getDatasetSequence();
+ }
+ // any annotation will be transferred onto the dataset sequence
+
+ if (shadow != null && shadow.getAnnotation() != null)
{
+ for (AlignmentAnnotation ana : shadow.getAnnotation())
+ {
+ List<AlignmentAnnotation> transfer = sq.getAlignmentAnnotations(
+ ana.getCalcId(), ana.label);
+ if (transfer == null || transfer.size() == 0)
+ {
+ ana.liftOver(sequence, shadowMap);
+ ana.liftOver(dsq, sqmpping);
+ dsq.addAlignmentAnnotation(ana);
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ else
+ {
+ if (sequence != null && sequence.getAnnotation() != null)
+ {
+ for (AlignmentAnnotation ana : sequence.getAnnotation())
+ {
+ List<AlignmentAnnotation> transfer = sq.getAlignmentAnnotations(
+ ana.getCalcId(), ana.label);
+ if (transfer == null || transfer.size() == 0)
+ {
+ ana.liftOver(dsq, sqmpping);
+ // mapping.transfer(ana);
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
}
float min = -1, max = 0;
Annotation[] an = new Annotation[sq.getEnd() - sq.getStart() + 1];
{
int prn = mapping.getPDBResNum(k + 1);
- an[k] = new Annotation((float) prn);
+ an[k] = new Annotation(prn);
if (min == -1)
{
min = k;
}
sq.addAlignmentAnnotation(new AlignmentAnnotation("PDB.RESNUM",
"PDB Residue Numbering for " + this.pdbid + ":" + this.id,
- an, (float) min, (float) max, AlignmentAnnotation.LINE_GRAPH));
+ an, min, max, AlignmentAnnotation.LINE_GRAPH));
+
}
}
}
*/
package MCview;
-import java.io.*;
-
-import java.awt.event.*;
-import javax.swing.*;
-
-import jalview.datamodel.*;
-import jalview.gui.*;
-import jalview.io.*;
-import jalview.schemes.*;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignmentPanel;
+import jalview.gui.Desktop;
+import jalview.gui.OOMWarning;
+import jalview.gui.UserDefinedColours;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.HelixColourScheme;
+import jalview.schemes.HydrophobicColourScheme;
+import jalview.schemes.StrandColourScheme;
+import jalview.schemes.TaylorColourScheme;
+import jalview.schemes.TurnColourScheme;
+import jalview.schemes.UserColourScheme;
+import jalview.schemes.ZappoColourScheme;
import jalview.util.MessageManager;
import jalview.ws.ebi.EBIFetchClient;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.PrintWriter;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JInternalFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.SwingUtilities;
+
public class PDBViewer extends JInternalFrame implements Runnable
{
try
{
tmpPDBFile = pdbentry.getFile();
- PDBfile pdbfile = new PDBfile(tmpPDBFile,
+ PDBfile pdbfile = new PDBfile(false,false,tmpPDBFile,
jalview.io.AppletFormatAdapter.FILE);
pdbcanvas.init(pdbentry, seq, chains, ap, protocol);
.getAbsolutePath());
if (pdbentry.getFile() != null)
+ {
pdbcanvas.init(pdbentry, seq, chains, ap, protocol);
+ }
} catch (Exception ex)
{
pdbcanvas.errorMessage = "Error retrieving file: " + pdbentry.getId();
*/
public void eps_actionPerformed(ActionEvent e)
{
- makePDBImage(jalview.util.ImageMaker.EPS);
+ makePDBImage(jalview.util.ImageMaker.TYPE.EPS);
}
/**
*/
public void png_actionPerformed(ActionEvent e)
{
- makePDBImage(jalview.util.ImageMaker.PNG);
+ makePDBImage(jalview.util.ImageMaker.TYPE.PNG);
}
- void makePDBImage(int type)
+ void makePDBImage(jalview.util.ImageMaker.TYPE type)
{
int width = pdbcanvas.getWidth();
int height = pdbcanvas.getHeight();
jalview.util.ImageMaker im;
- if (type == jalview.util.ImageMaker.PNG)
+ if (type == jalview.util.ImageMaker.TYPE.PNG)
{
- im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.PNG,
+ im = new jalview.util.ImageMaker(this,
+ jalview.util.ImageMaker.TYPE.PNG,
"Make PNG image from view", width, height, null, null);
}
- else
+ else if (type == jalview.util.ImageMaker.TYPE.EPS)
{
- im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.EPS,
+ im = new jalview.util.ImageMaker(this,
+ jalview.util.ImageMaker.TYPE.EPS,
"Make EPS file from view", width, height, null,
this.getTitle());
}
+ else
+ {
+
+ im = new jalview.util.ImageMaker(this,
+ jalview.util.ImageMaker.TYPE.SVG, "Make SVG file from PCA",
+ width, height, null, this.getTitle());
+ }
if (im.getGraphics() != null)
{
jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Save PDB File");
+ chooser.setDialogTitle(MessageManager.getString("label.save_pdb_file"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
*/
package MCview;
-import java.io.*;
-import java.util.*;
-
-import java.awt.*;
-
import jalview.analysis.AlignSeq;
-import jalview.datamodel.*;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
import jalview.io.FileParse;
+import jalview.util.MessageManager;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
public class PDBfile extends jalview.io.AlignFile
{
- public Vector chains;
+ public Vector<PDBChain> chains;
public String id;
*/
boolean VisibleChainAnnotation = false;
- public PDBfile(String inFile, String inType) throws IOException
+ boolean processSecondaryStructure=true;
+
+
+ public PDBfile(boolean visibleChainAnnotation,
+ boolean processSecondaryStructure)
+ {
+ super();
+ VisibleChainAnnotation = visibleChainAnnotation;
+ this.processSecondaryStructure = processSecondaryStructure;
+ }
+
+ public PDBfile(boolean visibleChainAnnotation,
+ boolean processSecondaryStructure, String file, String protocol) throws IOException
{
- super(inFile, inType);
+ super(false, file, protocol);
+ VisibleChainAnnotation = visibleChainAnnotation;
+ this.processSecondaryStructure = processSecondaryStructure;
+ doParse();
}
- public PDBfile(FileParse source) throws IOException
+ public PDBfile(boolean visibleChainAnnotation,
+ boolean processSecondaryStructure, FileParse source) throws IOException
{
- super(source);
+ super(false, source);
+ VisibleChainAnnotation = visibleChainAnnotation;
+ this.processSecondaryStructure = processSecondaryStructure;
+ doParse();
}
public String print()
}
for (int i = 0; i < chains.size(); i++)
{
- SequenceI dataset = ((PDBChain) chains.elementAt(i)).sequence;
+ SequenceI dataset = chains.elementAt(i).sequence;
dataset.setName(id + "|" + dataset.getName());
PDBEntry entry = new PDBEntry();
entry.setId(id);
entry.setProperty(new Hashtable());
- if (((PDBChain) chains.elementAt(i)).id != null)
+ if (chains.elementAt(i).id != null)
{
entry.getProperty().put("CHAIN",
- ((PDBChain) chains.elementAt(i)).id);
+ chains.elementAt(i).id);
}
if (inFile != null)
{
{
for (int ai = 0; ai < chainannot.length; ai++)
{
-
chainannot[ai].visible = VisibleChainAnnotation;
annotations.addElement(chainannot[ai]);
}
}
}
+ if (processSecondaryStructure)
+ {
if (rna.size() > 0)
+ {
try
{
processPdbFileWithAnnotate3d(rna);
x.printStackTrace();
}
+ }
;
if (prot.size() > 0)
+ {
try
{
processPdbFileWithJmol(prot);
} catch (Exception x)
{
System.err
- .println("Exceptions when dealing with RNA in pdb file");
+ .println("Exceptions from Jmol when processing data in pdb file");
x.printStackTrace();
}
- ;
- if (prot.size() > 0)
- try
- {
- processPdbFileWithJmol(prot);
- } catch (Exception x)
- {
- System.err
- .println("Exceptions when dealing with RNA in pdb file");
- x.printStackTrace();
-
- }
- ;
+ }
+ }
} catch (OutOfMemoryError er)
{
System.out.println("OUT OF MEMORY LOADING PDB FILE");
- throw new IOException("Out of memory loading PDB File");
+ throw new IOException(
+ MessageManager
+ .getString("exception.outofmemory_loading_pdb_file"));
} catch (NumberFormatException ex)
{
if (line != null)
System.err.println(line);
}
}
+ markCalcIds();
+ }
+
+ private static String calcIdPrefix = "JalviewPDB";
+
+ public static boolean isCalcIdHandled(String calcId)
+ {
+ return calcId != null
+ && (calcIdPrefix.equals(calcId));
+ }
+
+ public static boolean isCalcIdForFile(AlignmentAnnotation alan, String pdbFile)
+ {
+ return alan.getCalcId() != null
+ && calcIdPrefix.equals(alan.getCalcId())
+ && pdbFile.equals(alan.getProperty("PDBID"));
}
+ public static String relocateCalcId(String calcId,
+ Hashtable<String, String> alreadyLoadedPDB) throws Exception
+ {
+ int s = calcIdPrefix.length(), end = calcId.indexOf(calcIdPrefix, s);
+ String between = calcId.substring(s, end - 1);
+ return calcIdPrefix + alreadyLoadedPDB.get(between) + ":"
+ + calcId.substring(end);
+ }
+
+ private void markCalcIds()
+ {
+ for (SequenceI sq : seqs)
+ {
+ for (AlignmentAnnotation aa : sq.getAnnotation())
+ {
+ String oldId = aa.getCalcId();
+ if (oldId == null)
+ {
+ oldId = "";
+ }
+ aa.setCalcId(calcIdPrefix);
+ aa.setProperty("PDBID", id);
+ aa.setProperty("oldCalcId", oldId);
+ }
+ }
+ }
private void processPdbFileWithJmol(ArrayList<SequenceI> prot)
throws Exception
{
{}).invoke(jmf));
cl.getMethod("addAnnotations", new Class[]
{ Alignment.class }).invoke(jmf, al);
- replaceMatchingSeqsWith(prot, al, AlignSeq.PEP);
+ for (SequenceI sq : al.getSequences())
+ {
+ if (sq.getDatasetSequence() != null)
+ {
+ sq.getDatasetSequence().getPDBId().clear();
+ }
+ else
+ {
+ sq.getPDBId().clear();
+ }
+ }
+ replaceAndUpdateChains(prot, al, AlignSeq.PEP, false);
}
} catch (ClassNotFoundException q)
{
}
}
+ private void replaceAndUpdateChains(ArrayList<SequenceI> prot,
+ AlignmentI al, String pep, boolean b)
+ {
+ List<List<? extends Object>> replaced = AlignSeq
+ .replaceMatchingSeqsWith(seqs,
+ annotations, prot, al, AlignSeq.PEP, false);
+ for (PDBChain ch : chains)
+ {
+ int p = 0;
+ for (SequenceI sq : (List<SequenceI>) replaced.get(0))
+ {
+ p++;
+ if (sq == ch.sequence || sq.getDatasetSequence() == ch.sequence)
+ {
+ p = -p;
+ break;
+ }
+ }
+ if (p < 0)
+ {
+ p = -p - 1;
+ // set shadow entry for chains
+ ch.shadow = (SequenceI) replaced.get(1).get(p);
+ ch.shadowMap = ((AlignSeq) replaced.get(2)
+.get(p))
+ .getMappingFromS1(false);
+ }
+ }
+ }
+
private void processPdbFileWithAnnotate3d(ArrayList<SequenceI> rna)
throws Exception
{
new Class[]
{ FileParse.class }).invoke(annotate3d, new Object[]
{ new FileParse(getDataName(), type) }));
- replaceMatchingSeqsWith(rna, al, AlignSeq.DNA);
- }
- } catch (ClassNotFoundException x)
- {
- // ignore classnotfounds - occurs in applet
- }
- ;
- }
-
- private void replaceMatchingSeqsWith(ArrayList<SequenceI> ochains,
- AlignmentI al, String dnaOrProtein)
- {
- if (al != null && al.getHeight() > 0)
- {
- ArrayList<SequenceI> matches = new ArrayList<SequenceI>();
- ArrayList<AlignSeq> aligns = new ArrayList<AlignSeq>();
-
- for (SequenceI sq : ochains)
- {
- SequenceI bestm = null;
- AlignSeq bestaseq = null;
- int bestscore = 0;
- for (SequenceI msq : al.getSequences())
+ for (SequenceI sq : al.getSequences())
{
- AlignSeq aseq = AlignSeq.doGlobalNWAlignment(msq, sq,
- dnaOrProtein);
- if (bestm == null || aseq.getMaxScore() > bestscore)
+ if (sq.getDatasetSequence() != null)
{
- bestscore = aseq.getMaxScore();
- bestaseq = aseq;
- bestm = msq;
- }
- }
- System.out.println("Best Score for " + (matches.size() + 1) + " :"
- + bestscore);
- matches.add(bestm);
- aligns.add(bestaseq);
- al.deleteSequence(bestm);
- }
- for (int p = 0, pSize = seqs.size(); p < pSize; p++)
- {
- SequenceI sq, sp = seqs.get(p);
- int q;
- if ((q = ochains.indexOf(sp)) > -1)
- {
- seqs.set(p, sq = matches.get(q));
- sq.setName(sp.getName());
- sq.setDescription(sp.getDescription());
- sq.transferAnnotation(sp, aligns.get(q).getMappingFromS1(false));
- int inspos = -1;
- for (int ap = 0; ap < annotations.size();)
- {
- if (((AlignmentAnnotation) annotations.get(ap)).sequenceRef == sp)
- {
- if (inspos == -1)
- {
- inspos = ap;
- }
- annotations.remove(ap);
- }
- else
+ if (sq.getDatasetSequence().getPDBId() != null)
{
- ap++;
+ sq.getDatasetSequence().getPDBId().clear();
}
}
- if (sq.getAnnotation() != null)
+ else
{
- annotations.addAll(inspos, Arrays.asList(sq.getAnnotation()));
+ if (sq.getPDBId() != null)
+ {
+ sq.getPDBId().clear();
+ }
}
}
+ replaceAndUpdateChains(rna, al, AlignSeq.DNA, false);
}
+ } catch (ClassNotFoundException x)
+ {
+ // ignore classnotfounds - occurs in applet
}
+ ;
}
/**
{
for (int i = 0; i < chains.size(); i++)
{
- ((PDBChain) chains.elementAt(i)).makeResidueList();
+ chains.elementAt(i).makeResidueList();
}
}
{
for (int i = 0; i < chains.size(); i++)
{
- ((PDBChain) chains.elementAt(i)).makeCaBondList();
+ chains.elementAt(i).makeCaBondList();
}
}
{
for (int i = 0; i < chains.size(); i++)
{
- if (((PDBChain) chains.elementAt(i)).id.equals(id))
+ if (chains.elementAt(i).id.equals(id))
{
- return (PDBChain) chains.elementAt(i);
+ return chains.elementAt(i);
}
}
{
for (int i = 0; i < chains.size(); i++)
{
- ((PDBChain) chains.elementAt(i)).setChargeColours();
+ chains.elementAt(i).setChargeColours();
}
}
{
for (int i = 0; i < chains.size(); i++)
{
- ((PDBChain) chains.elementAt(i)).setChainColours(cs);
+ chains.elementAt(i).setChainColours(cs);
}
}
{
for (int i = 0; i < chains.size(); i++)
{
- ((PDBChain) chains.elementAt(i)).setChainColours(Color.getHSBColor(
- 1.0f / (float) i, .4f, 1.0f));
+ chains.elementAt(i).setChainColours(Color.getHSBColor(
+ 1.0f / i, .4f, 1.0f));
}
}
# You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
# The Jalview Authors are detailed in the 'AUTHORS' file.
###############################################################################
-# THE CASTOR PROPERTIES FILE\r
-# This file specifies values for Castor run-time which may be configured\r
-# by the user.\r
-# $Id$\r
-\r
-# This section defines Backwards compatibility switches.\r
-#\r
-# Hashtable/Map default mapping.\r
-# For backward compatibility with 0.9.5.2 and earlier.\r
-#\r
-#org.exolab.castor.xml.saveMapKeys=false\r
-\r
-# Defines the default XML parser to be used by Castor.\r
-# The parser must implement org.xml.sax.Parser.\r
-#\r
-org.exolab.castor.parser=org.apache.xerces.parsers.SAXParser\r
-\r
-# Defines the (default) XML serializer factory to use by Castor, which must\r
-# implement org.exolab.castor.xml.SerializerFactory; default is \r
-# org.exolab.castor.xml.XercesXMLSerializerFactory\r
-# \r
-# When using Castor XML with JDK 5.0, you may switch to the XercesJDK5XMLSerializerFactory\r
-# which will use the Xerces instance as shipped with the JDK itself; this avoids\r
-# having to download another Xerces instance and installing it. \r
-org.exolab.castor.xml.serializer.factory=org.exolab.castor.xml.XercesXMLSerializerFactory\r
-#org.exolab.castor.xml.serializer.factory=org.exolab.castor.xml.XercesJDK5XMLSerializerFactory\r
-\r
-# Defines the NodeType for use with Java primitive types (int, long, boolean,\r
-# etc). This value is only used by the Introspector. Valid values are either\r
-# "attribute" or "element". By default, all primitives are marshaled as\r
-# attributes. Uncomment the following line to change the NodeType to element.\r
-#\r
-#org.exolab.castor.xml.introspector.primitive.nodetype=element\r
-\r
-# Defines the Naming "style" or conventions to use when creating XML names\r
-# from Java class or field names.\r
-# Valid values are as follows:\r
-# -----------------------------------------------------------------\r
-# lower (default) | All names are lowercase with hyphens\r
-# | separating words.\r
-# |\r
-# | Example: personInfo = person-info\r
-# -----------------------------------------------------------------\r
-# mixed | All names are mixed case, with Uppercase\r
-# | character as the first letter of a new word.\r
-# |\r
-# | Example: personInfo = personInfo\r
-# | Example: FooBar = fooBar\r
-# -----------------------------------------------------------------\r
-# {Any ClassName} | Any Class which implements\r
-# | org.exolab.castor.xml.XMLNaming\r
-# -----------------------------------------------------------------\r
-#\r
-# By default, all names are treated as the "lower" option. To preserve the\r
-# Java mixed-case conventions, uncomment the following line.\r
-#\r
-#org.exolab.castor.xml.naming=mixed\r
-\r
-###############################\r
-# REGULAR EXPRESSION EVALUATORS\r
-#\r
-# Defines the Regular Expression Evaluator to be used by Castor.\r
-# The evaluator must implement org.exolab.castor.util.RegExpEvaluator.\r
-#\r
-# Uncomment the following to basically suppress Regular expressions evaluation:\r
-#org.exolab.castor.regexp=org.exolab.castor.xml.util.AlwaysTrueRegExpEvaluator\r
-#\r
-# An implementation which uses the Jakarta RegExp library:\r
-#org.exolab.castor.regexp=org.exolab.castor.util.JakartaRegExpEvaluator\r
-#\r
-# An implementation which uses the Jakarta ORO library:\r
-org.exolab.castor.regexp=org.exolab.castor.util.JakartaOroEvaluator\r
-\r
-# True if all documents should be indented on output by default.\r
-# Defaults to false.\r
-#\r
-#org.exolab.castor.indent=true\r
-\r
-# True if xml documents should be validated by the SAX Parser\r
-# Defaults to false.\r
-#\r
-org.exolab.castor.parser.validation=false\r
-\r
-# True for parser to support Namespaces.\r
-# Defaults to false.\r
-#\r
-org.exolab.castor.parser.namespaces=false\r
-\r
-# True if all documents should be validated by the marshaling framework\r
-# Defaults to true.\r
-#\r
-org.exolab.castor.marshalling.validation=true\r
-\r
-# Comma separated list of SAX 2 features that should be enabled for the\r
-# default parser.\r
-#\r
-#org.exolab.castor.sax.features=\r
-\r
-# Comma separated list of SAX 2 features that should be disabled for the\r
-# default parser.\r
-#\r
-#org.exolab.castor.sax.features-to-disable\r
-\r
-# True if debugging output should be generated.\r
-# Defaults to false.\r
-#\r
-org.exolab.castor.debug=false\r
-\r
-# List of collection handlers for Java 1.1 and Java 1.2 run-times:\r
-#\r
-org.exolab.castor.mapping.collections=\\r
- org.exolab.castor.mapping.loader.J1CollectionHandlers,\\r
- org.exolab.castor.mapping.loader.J2CollectionHandlers\r
-\r
-# List of persistence factories for the supported database servers:\r
-#\r
-org.exolab.castor.jdo.engines=\\r
- org.exolab.castor.jdo.drivers.OracleFactory,\\r
- org.exolab.castor.jdo.drivers.PostgreSQLFactory,\\r
- org.exolab.castor.jdo.drivers.SybaseFactory,\\r
- org.exolab.castor.jdo.drivers.SQLServerFactory,\\r
- org.exolab.castor.jdo.drivers.DB2Factory,\\r
- org.exolab.castor.jdo.drivers.InformixFactory,\\r
- org.exolab.castor.jdo.drivers.HsqlFactory,\\r
- org.exolab.castor.jdo.drivers.InstantDBFactory,\\r
- org.exolab.castor.jdo.drivers.InterbaseFactory,\\r
- org.exolab.castor.jdo.drivers.MySQLFactory,\\r
- org.exolab.castor.jdo.drivers.SapDbFactory,\\r
- org.exolab.castor.jdo.drivers.GenericFactory,\\r
- org.exolab.castor.jdo.drivers.DerbyFactory,\\r
- org.castor.jdo.drivers.PointbaseFactory,\\r
- org.castor.jdo.drivers.ProgressFactory\r
-\r
-# List of key generator factories:\r
-#\r
-org.exolab.castor.jdo.keyGeneratorFactories=\\r
- org.exolab.castor.jdo.keygen.MaxKeyGeneratorFactory,\\r
- org.exolab.castor.jdo.keygen.HighLowKeyGeneratorFactory,\\r
- org.exolab.castor.jdo.keygen.IdentityKeyGeneratorFactory,\\r
- org.exolab.castor.jdo.keygen.SequenceKeyGeneratorFactory,\\r
- org.exolab.castor.jdo.keygen.UUIDKeyGeneratorFactory\r
-\r
-# Collection handlers for the source code generator:\r
-#\r
-org.exolab.castor.builder.type.j2=\\r
- org.exolab.castor.builder.FieldInfoFactoryJ2\r
-org.exolab.castor.builder.type.j1=\\r
- org.exolab.castor.builder.FieldInfoFactory\r
-org.exolab.castor.builder.type.odmg=\\r
- org.exolab.castor.builder.FieldInfoFactoryODMG30\r
-\r
-# Configures the default time zone to apply to dates/times fetched from\r
-# database fields (if not already part of the data). Specify same format as\r
-# in java.util.TimeZone.getTimeZone, or the empty string to use the computer's\r
-# local time zone. Please see http://de.wikipedia.org/wiki/Zeitzone for\r
-# detailed information about time zones.\r
-#\r
-org.exolab.castor.jdo.defaultTimeZone=\r
-#org.exolab.castor.jdo.defaultTimeZone=GMT-8:00\r
-\r
-# List of TxSynchronizeable implementations:\r
-#\r
-#org.exolab.castor.persist.TxSynchronizable=\r
-\r
-# Sets the buffer size in bytes for fetching LOBs (this is dependent upon\r
-# the JDBC driver implementation). The value below == 5k.\r
-#\r
-org.exolab.castor.jdo.lobBufferSize=5120\r
-\r
-# True if database configuration should be initalization\r
-# when loading it (default: true).\r
-#\r
-#org.exolab.castor.jdo.DatabaseInitializeAtLoad=true\r
-\r
-# True if proxy classes should be used for JDBC connections and\r
-# prepared statements.\r
-# Defaults to true.\r
-#\r
-org.exolab.castor.persist.useProxies=false\r
-\r
-# MappingLoader implementations:\r
-#\r
-org.castor.mapping.loaderFactories=\\r
- org.castor.mapping.JDOMappingLoaderFactory,\\r
- org.castor.mapping.XMLMappingLoaderFactory\r
-\r
-# Cache implementations:\r
-#\r
-org.castor.cache.Factories=\\r
- org.castor.cache.simple.NoCacheFactory,\\r
- org.castor.cache.simple.TimeLimitedFactory,\\r
- org.castor.cache.simple.CountLimitedFactory,\\r
- org.castor.cache.simple.UnlimitedFactory,\\r
- org.castor.cache.distributed.FKCacheFactory,\\r
- org.castor.cache.distributed.JcsCacheFactory,\\r
- org.castor.cache.distributed.JCacheFactory,\\r
- org.castor.cache.distributed.CoherenceCacheFactory,\\r
- org.castor.cache.distributed.OsCacheFactory,\\r
- org.castor.cache.hashbelt.FIFOHashbeltFactory,\\r
- org.castor.cache.hashbelt.LRUHashbeltFactory,\\r
- org.castor.cache.distributed.EHCacheFactory,\\r
- org.castor.cache.distributed.GigaspacesCacheFactory\r
-\r
-# TransactionManagerFactory implementations:\r
-#\r
-org.castor.transactionmanager.Factories=\\r
- org.castor.transactionmanager.WebSphereTransactionManagerFactory,\\r
- org.castor.transactionmanager.WebSphere5TransactionManagerFactory,\\r
- org.castor.transactionmanager.WebSphere51TransactionManagerFactory,\\r
- org.castor.transactionmanager.LocalTransactionManagerFactory,\\r
- org.castor.transactionmanager.JNDIENCTransactionManagerFactory,\\r
- org.castor.transactionmanager.JOTMTransactionManagerFactory\r
-\r
-# Selects whether the TransactionManager should be initialized at registration,\r
-# or lazily when requested for the first time.\r
-# Defaults to false.\r
-#\r
-org.castor.transactionmanager.InitializeAtRegistration=false\r
-\r
-# Instructs Castor JDO to use the JDBC 3.0-specific features to obtain\r
-# the generated value of an identity column.\r
-# Defaults to false.\r
-#\r
-org.castor.jdo.use.jdbc30=false\r
-\r
-# Specifies whether to use ANSI-compliant SQL for MS SQL Server.\r
-# Defaults to false.\r
-#\r
-org.exolab.castor.jdo.sqlserver.ansi-compliant=false\r
-\r
-# Specifyies whether the ClassDescriptorResolver should (automatically) search\r
-# for and consult with package mapping files (.castor.xml) to retrieve class\r
-# descriptor information; on by default.\r
-# Defaults to true.\r
-#\r
-#org.exolab.castor.xml.loadPackageMappings=false\r
+# THE CASTOR PROPERTIES FILE
+# This file specifies values for Castor run-time which may be configured
+# by the user.
+# $Id$
+
+# This section defines Backwards compatibility switches.
+#
+# Hashtable/Map default mapping.
+# For backward compatibility with 0.9.5.2 and earlier.
+#
+#org.exolab.castor.xml.saveMapKeys=false
+
+# Defines the default XML parser to be used by Castor.
+# The parser must implement org.xml.sax.Parser.
+#
+org.exolab.castor.parser=org.apache.xerces.parsers.SAXParser
+
+# Defines the (default) XML serializer factory to use by Castor, which must
+# implement org.exolab.castor.xml.SerializerFactory; default is
+# org.exolab.castor.xml.XercesXMLSerializerFactory
+#
+# When using Castor XML with JDK 5.0, you may switch to the XercesJDK5XMLSerializerFactory
+# which will use the Xerces instance as shipped with the JDK itself; this avoids
+# having to download another Xerces instance and installing it.
+org.exolab.castor.xml.serializer.factory=org.exolab.castor.xml.XercesXMLSerializerFactory
+#org.exolab.castor.xml.serializer.factory=org.exolab.castor.xml.XercesJDK5XMLSerializerFactory
+
+# Defines the NodeType for use with Java primitive types (int, long, boolean,
+# etc). This value is only used by the Introspector. Valid values are either
+# "attribute" or "element". By default, all primitives are marshaled as
+# attributes. Uncomment the following line to change the NodeType to element.
+#
+#org.exolab.castor.xml.introspector.primitive.nodetype=element
+
+# Defines the Naming "style" or conventions to use when creating XML names
+# from Java class or field names.
+# Valid values are as follows:
+# -----------------------------------------------------------------
+# lower (default) | All names are lowercase with hyphens
+# | separating words.
+# |
+# | Example: personInfo = person-info
+# -----------------------------------------------------------------
+# mixed | All names are mixed case, with Uppercase
+# | character as the first letter of a new word.
+# |
+# | Example: personInfo = personInfo
+# | Example: FooBar = fooBar
+# -----------------------------------------------------------------
+# {Any ClassName} | Any Class which implements
+# | org.exolab.castor.xml.XMLNaming
+# -----------------------------------------------------------------
+#
+# By default, all names are treated as the "lower" option. To preserve the
+# Java mixed-case conventions, uncomment the following line.
+#
+#org.exolab.castor.xml.naming=mixed
+
+###############################
+# REGULAR EXPRESSION EVALUATORS
+#
+# Defines the Regular Expression Evaluator to be used by Castor.
+# The evaluator must implement org.exolab.castor.util.RegExpEvaluator.
+#
+# Uncomment the following to basically suppress Regular expressions evaluation:
+#org.exolab.castor.regexp=org.exolab.castor.xml.util.AlwaysTrueRegExpEvaluator
+#
+# An implementation which uses the Jakarta RegExp library:
+#org.exolab.castor.regexp=org.exolab.castor.util.JakartaRegExpEvaluator
+#
+# An implementation which uses the Jakarta ORO library:
+org.exolab.castor.regexp=org.exolab.castor.util.JakartaOroEvaluator
+
+# True if all documents should be indented on output by default.
+# Defaults to false.
+#
+#org.exolab.castor.indent=true
+
+# True if xml documents should be validated by the SAX Parser
+# Defaults to false.
+#
+org.exolab.castor.parser.validation=false
+
+# True for parser to support Namespaces.
+# Defaults to false.
+#
+org.exolab.castor.parser.namespaces=false
+
+# True if all documents should be validated by the marshaling framework
+# Defaults to true.
+#
+org.exolab.castor.marshalling.validation=true
+
+# Comma separated list of SAX 2 features that should be enabled for the
+# default parser.
+#
+#org.exolab.castor.sax.features=
+
+# Comma separated list of SAX 2 features that should be disabled for the
+# default parser.
+#
+#org.exolab.castor.sax.features-to-disable
+
+# True if debugging output should be generated.
+# Defaults to false.
+#
+org.exolab.castor.debug=false
+
+# List of collection handlers for Java 1.1 and Java 1.2 run-times:
+#
+org.exolab.castor.mapping.collections=\
+ org.exolab.castor.mapping.loader.J1CollectionHandlers,\
+ org.exolab.castor.mapping.loader.J2CollectionHandlers
+
+# List of persistence factories for the supported database servers:
+#
+org.exolab.castor.jdo.engines=\
+ org.exolab.castor.jdo.drivers.OracleFactory,\
+ org.exolab.castor.jdo.drivers.PostgreSQLFactory,\
+ org.exolab.castor.jdo.drivers.SybaseFactory,\
+ org.exolab.castor.jdo.drivers.SQLServerFactory,\
+ org.exolab.castor.jdo.drivers.DB2Factory,\
+ org.exolab.castor.jdo.drivers.InformixFactory,\
+ org.exolab.castor.jdo.drivers.HsqlFactory,\
+ org.exolab.castor.jdo.drivers.InstantDBFactory,\
+ org.exolab.castor.jdo.drivers.InterbaseFactory,\
+ org.exolab.castor.jdo.drivers.MySQLFactory,\
+ org.exolab.castor.jdo.drivers.SapDbFactory,\
+ org.exolab.castor.jdo.drivers.GenericFactory,\
+ org.exolab.castor.jdo.drivers.DerbyFactory,\
+ org.castor.jdo.drivers.PointbaseFactory,\
+ org.castor.jdo.drivers.ProgressFactory
+
+# List of key generator factories:
+#
+org.exolab.castor.jdo.keyGeneratorFactories=\
+ org.exolab.castor.jdo.keygen.MaxKeyGeneratorFactory,\
+ org.exolab.castor.jdo.keygen.HighLowKeyGeneratorFactory,\
+ org.exolab.castor.jdo.keygen.IdentityKeyGeneratorFactory,\
+ org.exolab.castor.jdo.keygen.SequenceKeyGeneratorFactory,\
+ org.exolab.castor.jdo.keygen.UUIDKeyGeneratorFactory
+
+# Collection handlers for the source code generator:
+#
+org.exolab.castor.builder.type.j2=\
+ org.exolab.castor.builder.FieldInfoFactoryJ2
+org.exolab.castor.builder.type.j1=\
+ org.exolab.castor.builder.FieldInfoFactory
+org.exolab.castor.builder.type.odmg=\
+ org.exolab.castor.builder.FieldInfoFactoryODMG30
+
+# Configures the default time zone to apply to dates/times fetched from
+# database fields (if not already part of the data). Specify same format as
+# in java.util.TimeZone.getTimeZone, or the empty string to use the computer's
+# local time zone. Please see http://de.wikipedia.org/wiki/Zeitzone for
+# detailed information about time zones.
+#
+org.exolab.castor.jdo.defaultTimeZone=
+#org.exolab.castor.jdo.defaultTimeZone=GMT-8:00
+
+# List of TxSynchronizeable implementations:
+#
+#org.exolab.castor.persist.TxSynchronizable=
+
+# Sets the buffer size in bytes for fetching LOBs (this is dependent upon
+# the JDBC driver implementation). The value below == 5k.
+#
+org.exolab.castor.jdo.lobBufferSize=5120
+
+# True if database configuration should be initalization
+# when loading it (default: true).
+#
+#org.exolab.castor.jdo.DatabaseInitializeAtLoad=true
+
+# True if proxy classes should be used for JDBC connections and
+# prepared statements.
+# Defaults to true.
+#
+org.exolab.castor.persist.useProxies=false
+
+# MappingLoader implementations:
+#
+org.castor.mapping.loaderFactories=\
+ org.castor.mapping.JDOMappingLoaderFactory,\
+ org.castor.mapping.XMLMappingLoaderFactory
+
+# Cache implementations:
+#
+org.castor.cache.Factories=\
+ org.castor.cache.simple.NoCacheFactory,\
+ org.castor.cache.simple.TimeLimitedFactory,\
+ org.castor.cache.simple.CountLimitedFactory,\
+ org.castor.cache.simple.UnlimitedFactory,\
+ org.castor.cache.distributed.FKCacheFactory,\
+ org.castor.cache.distributed.JcsCacheFactory,\
+ org.castor.cache.distributed.JCacheFactory,\
+ org.castor.cache.distributed.CoherenceCacheFactory,\
+ org.castor.cache.distributed.OsCacheFactory,\
+ org.castor.cache.hashbelt.FIFOHashbeltFactory,\
+ org.castor.cache.hashbelt.LRUHashbeltFactory,\
+ org.castor.cache.distributed.EHCacheFactory,\
+ org.castor.cache.distributed.GigaspacesCacheFactory
+
+# TransactionManagerFactory implementations:
+#
+org.castor.transactionmanager.Factories=\
+ org.castor.transactionmanager.WebSphereTransactionManagerFactory,\
+ org.castor.transactionmanager.WebSphere5TransactionManagerFactory,\
+ org.castor.transactionmanager.WebSphere51TransactionManagerFactory,\
+ org.castor.transactionmanager.LocalTransactionManagerFactory,\
+ org.castor.transactionmanager.JNDIENCTransactionManagerFactory,\
+ org.castor.transactionmanager.JOTMTransactionManagerFactory
+
+# Selects whether the TransactionManager should be initialized at registration,
+# or lazily when requested for the first time.
+# Defaults to false.
+#
+org.castor.transactionmanager.InitializeAtRegistration=false
+
+# Instructs Castor JDO to use the JDBC 3.0-specific features to obtain
+# the generated value of an identity column.
+# Defaults to false.
+#
+org.castor.jdo.use.jdbc30=false
+
+# Specifies whether to use ANSI-compliant SQL for MS SQL Server.
+# Defaults to false.
+#
+org.exolab.castor.jdo.sqlserver.ansi-compliant=false
+
+# Specifyies whether the ClassDescriptorResolver should (automatically) search
+# for and consult with package mapping files (.castor.xml) to retrieve class
+# descriptor information; on by default.
+# Defaults to true.
+#
+#org.exolab.castor.xml.loadPackageMappings=false
//
package com.stevesoft.pat;
+import jalview.util.MessageManager;
+
import java.util.*;
/**
*/
Pattern clone1(Hashtable h)
{
- throw new Error("No such method as clone1 for " + getClass().getName());
+ throw new Error(MessageManager.formatMessage("error.no_such_method_as_clone1_for", new String[]{getClass().getName()}));
}
Pattern clone(Hashtable h)
p = clone1(h);
if (p == null)
{
- throw new Error("Null from clone1!");
+ throw new Error(MessageManager.getString("error.null_from_clone1"));
}
h.put(this, p);
h.put(p, p);
//
package com.stevesoft.pat;
+import jalview.util.MessageManager;
+
import java.io.*;
import java.util.*;
{
if (s == null)
{
- throw new NullPointerException("Null String Given to Regex.search");
+ throw new NullPointerException(MessageManager.getString("exception.null_string_given_to_regex_search"));
}
return _search(s, 0, s.length());
}
{
if (sl == null)
{
- throw new NullPointerException(
- "Null StringLike Given to Regex.search");
+ throw new NullPointerException(MessageManager.getString("exception.null_string_like_given_to_regex_search"));
}
return _search(sl, 0, sl.length());
}
{
if (s == null)
{
- throw new NullPointerException(
- "Null String Given to Regex.reverseSearch");
+ throw new NullPointerException(MessageManager.getString("exception.null_string_given_to_regex_reverse_search"));
}
return _reverseSearch(s, 0, s.length());
}
{
if (sl == null)
{
- throw new NullPointerException(
- "Null StringLike Given to Regex.reverseSearch");
+ throw new NullPointerException(MessageManager.getString("exception.null_string_like_given_to_regex_reverse_search"));
}
return _reverseSearch(sl, 0, sl.length());
}
{
if (s == null)
{
- throw new NullPointerException(
- "Null String Given to Regex.searchFrom");
+ throw new NullPointerException(MessageManager.getString("exception.null_string_like_given_to_regex_search_from"));
}
return _search(s, start, s.length());
}
{
if (s == null)
{
- throw new NullPointerException(
- "Null String Given to Regex.searchFrom");
+ throw new NullPointerException(MessageManager.getString("exception.null_string_like_given_to_regex_search_from"));
}
return _search(s, start, s.length());
}
{
if (s == null)
{
- throw new NullPointerException(
- "Null String Given to Regex.searchRegion");
+ throw new NullPointerException(MessageManager.getString("exception.null_string_like_given_to_regex_search_region"));
}
return _search(s, start, end);
}
//
package com.stevesoft.pat;
+import jalview.util.MessageManager;
+
import com.stevesoft.pat.wrap.*;
/** Internally used class. */
lastMatchedTo = 0;
if (rh.me == null)
{
- throw new NullPointerException("Replacer has null Regex pointer");
+ throw new NullPointerException(MessageManager.getString("exception.replace_null_regex_pointer"));
}
if (rh.me._search(s, start, end))
{
//
package com.stevesoft.pat;
+import jalview.util.MessageManager;
+
import com.stevesoft.pat.wrap.*;
/**
Regex r = Regex.perlCode(rs);
if (r == null)
{
- throw new NullPointerException("bad pattern to Regex.perlCode: " + rs);
+ throw new NullPointerException(MessageManager.formatMessage("exception.bad_pattern_to_regex_perl_code", new String[]{rs}));
}
add(r);
}
//
package com.stevesoft.pat.wrap;
+import jalview.util.MessageManager;
+
import java.io.*;
import com.stevesoft.pat.*;
{
}
- throw new ArrayIndexOutOfBoundsException("Out of bounds for file:"
- + " i=" + i + ", Final Buffer: i0=" + i0 + " iend=" + iend);
+ throw new ArrayIndexOutOfBoundsException(MessageManager.formatMessage("exception.out_of_bounds_for_file", new String[]{
+ Integer.valueOf(i).toString(),
+ Integer.valueOf(i0).toString(),
+ Integer.valueOf(iend).toString()
+ }));
}
public String toString()
{
- throw new Error("Not implemented");
+ throw new Error(MessageManager.getString("error.not_implemented"));
}
public int length()
--- /dev/null
+package ext.edu.ucsf.rbvi.strucviz2;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
+
+
+public abstract class ChimUtils {
+
+ private static Logger logger = LoggerFactory
+ .getLogger(ChimUtils.class);
+
+ static int MAX_SUB_MODELS = 1000;
+
+ public static final HashMap<String, String> aaNames;
+
+ public static String RESIDUE_ATTR = "ChimeraResidue";
+ public static String RINALYZER_ATTR = "RINalyzerResidue";
+ public static String DEFAULT_STRUCTURE_KEY = "pdbFileName";
+
+ /**
+ * Parse the model number returned by Chimera and return the int value
+ */
+ // invoked by the ChimeraModel constructor
+ // line = model id #0 type Molecule name 1ert
+ public static int[] parseModelNumber(String inputLine) {
+ int hash = inputLine.indexOf('#');
+ int space = inputLine.indexOf(' ', hash);
+ int decimal = inputLine.substring(hash + 1, space).indexOf('.');
+ // model number is between hash+1 and space
+ int modelNumber = -1;
+ int subModelNumber = 0;
+ try {
+ if (decimal > 0) {
+ subModelNumber = Integer.parseInt(inputLine.substring(decimal + hash + 2, space));
+ space = decimal + hash + 1;
+ }
+ modelNumber = Integer.parseInt(inputLine.substring(hash + 1, space));
+ } catch (Exception e) {
+ logger.warn("Unexpected return from Chimera: " + inputLine, e);
+ }
+ return new int[] { modelNumber, subModelNumber };
+ }
+
+ /**
+ * Parse the model number returned by Chimera and return the int value
+ */
+ // invoked by openModel in ChimeraManager
+ // line: #1, chain A: hiv-1 protease
+ public static int[] parseOpenedModelNumber(String inputLine) {
+ int hash = inputLine.indexOf('#');
+ int space = inputLine.indexOf(',', hash);
+ int decimal = inputLine.substring(hash + 1, space).indexOf('.');
+ // model number is between hash+1 and space
+ int modelNumber = -1;
+ int subModelNumber = 0;
+ try {
+ if (decimal > 0) {
+ subModelNumber = Integer.parseInt(inputLine.substring(decimal + hash + 2, space));
+ space = decimal + hash + 1;
+ }
+ modelNumber = Integer.parseInt(inputLine.substring(hash + 1, space));
+ } catch (Exception e) {
+ logger.warn("Unexpected return from Chimera: " + inputLine, e);
+ }
+ return new int[] { modelNumber, subModelNumber };
+ }
+
+ /**
+ * Parse the model identifier returned by Chimera and return the String value
+ */
+ // invoked by the ChimeraModel constructor
+ // line = model id #0 type Molecule name 1ert
+ public static String parseModelName(String inputLine) {
+ int start = inputLine.indexOf("name ");
+ if (start < 0)
+ return null;
+ // Might get a quoted string (don't understand why, but there you have it)
+ if (inputLine.startsWith("\"", start + 5)) {
+ start += 6; // Skip over the first quote
+ int end = inputLine.lastIndexOf('"');
+ if (end >= 1) {
+ return inputLine.substring(start, end);
+ } else
+ return inputLine.substring(start);
+ } else {
+ return inputLine.substring(start + 5);
+ }
+ }
+
+ public static Color parseModelColor(String inputLine) {
+ try {
+ int colorStart = inputLine.indexOf("color ");
+ String colorString = inputLine.substring(colorStart + 6);
+ String[] rgbStrings = colorString.split(",");
+ float[] rgbValues = new float[4];
+ for (int i = 0; i < rgbStrings.length; i++) {
+ Float f = new Float(rgbStrings[i]);
+ rgbValues[i] = f.floatValue();
+ }
+ if (rgbStrings.length == 4) {
+ return new Color(rgbValues[0], rgbValues[1], rgbValues[2], rgbValues[3]);
+ } else {
+ return new Color(rgbValues[0], rgbValues[1], rgbValues[2]);
+ }
+ } catch (Exception ex) {
+ logger.warn("Unexpected return from Chimera: " + inputLine, ex);
+ }
+ return Color.white;
+ }
+
+ /**
+ * Create the key to use for forming the model/submodel key into the modelHash
+ *
+ * @param model
+ * the model number
+ * @param subModel
+ * the submodel number
+ * @return the model key as an Integer
+ */
+ public static Integer makeModelKey(int model, int subModel) {
+ return new Integer(model * MAX_SUB_MODELS + subModel);
+ }
+
+ // invoked by the getResdiue (parseConnectivityReplies in CreateStructureNetworkTask)
+ // atomSpec = #0:1.A or #1:96.B@N
+ public static ChimeraModel getModel(String atomSpec, ChimeraManager chimeraManager) {
+ // System.out.println("getting model for "+atomSpec);
+ String[] split = atomSpec.split(":");
+ // No model specified....
+ if (split[0].length() == 0) {
+ logger.info("Unexpected return from Chimera: " + atomSpec);
+ return null;
+ }
+ // System.out.println("model = "+split[0].substring(1));
+ int model = 0;
+ int submodel = 0;
+ try {
+ String[] subSplit = split[0].substring(1).split("\\.");
+ if (subSplit.length > 0)
+ model = Integer.parseInt(subSplit[0]);
+ else
+ model = Integer.parseInt(split[0].substring(1));
+
+ if (subSplit.length > 1)
+ submodel = Integer.parseInt(subSplit[1]);
+ } catch (Exception e) {
+ // ignore
+ logger.warn("Unexpected return from Chimera: " + atomSpec, e);
+ }
+ return chimeraManager.getChimeraModel(model, submodel);
+ }
+
+ // invoked by the parseConnectivityReplies in CreateStructureNetworkTask
+ // atomSpec = #0:1.A or #1:96.B@N
+ public static ChimeraResidue getResidue(String atomSpec, ChimeraManager chimeraManager) {
+ // System.out.println("Getting residue from: "+atomSpec);
+ ChimeraModel model = getModel(atomSpec, chimeraManager); // Get the model
+ if (model == null) {
+ model = chimeraManager.getChimeraModel();
+ }
+ return getResidue(atomSpec, model);
+ }
+
+ // invoked by the getResdiue (parseConnectivityReplies in CreateStructureNetworkTask)
+ // atomSpec = #0:1.A or #1:96.B@N
+ public static ChimeraResidue getResidue(String atomSpec, ChimeraModel model) {
+ // System.out.println("Getting residue from: "+atomSpec);
+ String[] split = atomSpec.split(":|@");
+
+ // Split into residue and chain
+ String[] residueChain = split[1].split("\\.");
+
+ if (residueChain[0].length() == 0) {
+ logger.info("Unexpected return from Chimera: " + atomSpec);
+ return null;
+ }
+
+ if (residueChain.length == 2 && residueChain[1].length() > 0) {
+ ChimeraChain chain = model.getChain(residueChain[1]);
+ return chain.getResidue(residueChain[0]);
+ }
+ return model.getResidue("_", residueChain[0]);
+ }
+
+ public static ChimeraChain getChain(String atomSpec, ChimeraModel model) {
+ String[] split = atomSpec.split(":|@");
+
+ // Split into residue and chain
+ String[] residueChain = split[1].split("\\.");
+ if (residueChain.length == 1) {
+ logger.info("Unexpected return from Chimera: " + atomSpec);
+ return null;
+ }
+ return model.getChain(residueChain[1]);
+ }
+
+ public static String getAtomName(String atomSpec) {
+ String[] split = atomSpec.split("@");
+ if (split.length > 1) {
+ return split[1];
+ }
+ return atomSpec;
+ }
+
+ public static boolean isBackbone(String atom) {
+ if (atom.equals("C") || atom.equals("CA") || atom.equals("N") || atom.equals("O")
+ || atom.equals("H"))
+ return true;
+ return false;
+ }
+
+ public static String getIntSubtype(String node, String atom) {
+ String[] split = node.split("#| ");
+ String resType = "";
+ if (split.length == 2) {
+ resType = split[0].trim().toUpperCase();
+ } else if (split.length == 3) {
+ resType = split[1].trim().toUpperCase();
+ }
+ if (resType.equalsIgnoreCase("HOH") || resType.equalsIgnoreCase("WAT")) {
+ return "water";
+ } else if (aaNames.containsKey(resType)) {
+ if (atom.equals("C") || atom.equals("CA") || atom.equals("N") || atom.equals("O")
+ || atom.equals("H")) {
+ return "mc";
+ } else {
+ return "sc";
+ }
+ } else {
+ return "other";
+ }
+ }
+
+
+ public static String[] getResKeyParts(String resKey) {
+ // [pdbID[.modelNo]#][residueID][.chainID]
+ // pdbID := 4-character code | "URL" | "path"
+ String[] resKeyParts = new String[4];
+ String[] split = resKey.split("#");
+ String resChain = null;
+ // if no "#" then it is either only a pdb id or a residue or a chain
+ if (split.length == 1) {
+ // pdb id without model
+ if (resKey.length() == 4 && resKey.indexOf("\\.") < 0) {
+ parseModelID(resKey, resKeyParts);
+ }
+ // pdb link or file
+ else if (resKey.startsWith("\"")) {
+ parseModelID(resKey, resKeyParts);
+ }
+ // chain and residue or model and number
+ else {
+ String[] splitSplit = resKey.split("\\.");
+ if (splitSplit.length == 1) {
+ // only a chain or a residue
+ resChain = resKey;
+ } else {
+ try {
+ // pdb with a model
+ Integer.parseInt(splitSplit[1]);
+ parseModelID(resKey, resKeyParts);
+ } catch (NumberFormatException ex) {
+ // residue and chain
+ resChain = resKey;
+ }
+ }
+ }
+ } else if (split.length == 2) {
+ // model and residue+chain
+ parseModelID(split[0], resKeyParts);
+ resChain = split[1];
+ } else {
+ // model string with "#"
+ // TODO: [Optional] Are there more possibilities?
+ parseModelID(resKey.substring(0, resKey.lastIndexOf("#")), resKeyParts);
+ resChain = resKey.substring(resKey.lastIndexOf("#") + 1, resKey.length());
+ }
+ if (resChain != null) {
+ //System.out.println(resChain);
+ String[] resChainSplit = resChain.split("\\.");
+ if (resChainSplit.length == 1) {
+ // TODO: [Optional] Find a better way to distinguish between chain and residue
+ // if only one character and not an int, probably a chain
+ if (resChainSplit[0].length() == 1) {
+ try {
+ Integer.parseInt(resChainSplit[0]);
+ resKeyParts[3] = resChainSplit[0];
+ } catch (NumberFormatException ex) {
+ resKeyParts[2] = resChainSplit[0];
+ }
+ } else {
+ resKeyParts[3] = resChainSplit[0];
+ }
+ } else if (resChainSplit.length == 2) {
+ resKeyParts[2] = resChainSplit[0];
+ resKeyParts[3] = resChainSplit[1];
+ } else {
+ // too many dots?
+ logger.info("Could not parse residue identifier: " + resKey);
+ }
+ }
+ // String print = "";
+ // for (int i = 0; i < resKeyParts.length; i++) {
+ // if (resKeyParts[i] == null) {
+ // print += i + ": null\t";
+ // } else {
+ // print += i + ": " + resKeyParts[i] + ";";
+ // }
+ // }
+ // System.out.println(print);
+ return resKeyParts;
+ }
+
+ public static void parseModelID(String modelID, String[] resKeyParts) {
+ if (modelID.startsWith("\"")) {
+ if (modelID.endsWith("\"")) {
+ resKeyParts[0] = modelID.substring(1, modelID.length() - 1);
+ return;
+ } else {
+ try {
+ Integer.parseInt(modelID.substring(modelID.lastIndexOf("\"") + 2,
+ modelID.length()));
+ resKeyParts[0] = modelID.substring(0, modelID.lastIndexOf("\"") - 1);
+ resKeyParts[1] = modelID.substring(modelID.lastIndexOf("\"") + 2,
+ modelID.length());
+ } catch (NumberFormatException ex) {
+ resKeyParts[0] = modelID.substring(1);
+ }
+ }
+ } else {
+ String[] modelIDNo = modelID.split("\\.");
+ if (modelIDNo.length == 1) {
+ resKeyParts[0] = modelIDNo[0];
+ } else if (modelIDNo.length == 2) {
+ try {
+ Integer.parseInt(modelIDNo[1]);
+ resKeyParts[0] = modelIDNo[0];
+ resKeyParts[1] = modelIDNo[1];
+ } catch (NumberFormatException ex) {
+ resKeyParts[0] = modelID;
+ }
+ } else {
+ logger.info("Could not parse model identifier: " + modelID);
+ }
+ }
+ }
+
+ /**
+ * This method takes a Cytoscape attribute specification ([structure#][residue][.chainID]) and
+ * returns the lowest-level object referenced by the spec. For example, if the spec is "1tkk",
+ * this method will return a ChimeraModel. If the spec is ".A", it will return a ChimeraChain,
+ * etc.
+ *
+ * @param attrSpec
+ * the specification string
+ * @param chimeraManager
+ * the Chimera object we're currently using
+ * @return a ChimeraStructuralObject of the lowest type
+ */
+ public static ChimeraStructuralObject fromAttributeOld(String attrSpec,
+ ChimeraManager chimeraManager) {
+ if (attrSpec == null || attrSpec.indexOf(',') > 0 || attrSpec.indexOf('-') > 0) {
+ // No support for either lists or ranges
+ logger.warn("No support for identifier: " + attrSpec);
+ return null;
+ }
+
+ String residue = null;
+ String model = null;
+ String chain = null;
+
+ ChimeraModel chimeraModel = null;
+ ChimeraChain chimeraChain = null;
+ ChimeraResidue chimeraResidue = null;
+
+ // System.out.println("Getting object from attribute: "+attrSpec);
+ try {
+ String[] split = attrSpec.split("#");
+ String resChain = null;
+ if (split.length == 1) {
+ // no model
+ resChain = split[0];
+ } else if (split.length == 2) {
+ // model and rest
+ model = split[0];
+ resChain = split[1];
+ } else {
+ // model string with "#"
+ model = attrSpec.substring(0, attrSpec.lastIndexOf("#"));
+ resChain = attrSpec.substring(attrSpec.lastIndexOf("#") + 1, attrSpec.length());
+ }
+ if (resChain != null) {
+ String[] resChainSplit = resChain.split("\\.");
+ if (resChainSplit.length == 1) {
+ residue = resChainSplit[0];
+ } else if (resChainSplit.length == 2) {
+ residue = resChainSplit[0];
+ chain = resChainSplit[1];
+ } else {
+ // too many dots?
+ logger.warn("No support for identifier: " + attrSpec);
+ }
+ }
+
+ // if (split.length == 1) {
+ // // No model
+ // residue = split[0];
+ // } else if (split.length == 3) {
+ // // We have all three
+ // model = split[0];
+ // residue = split[1];
+ // chain = split[2];
+ // } else if (split.length == 2 && attrSpec.indexOf('#') > 0) {
+ // // Model and Residue
+ // model = split[0];
+ // residue = split[1];
+ // } else {
+ // // Residue and Chain
+ // residue = split[0];
+ // chain = split[1];
+ // }
+
+ // System.out.println("model = " + model + " chain = " + chain + " residue = " +
+ // residue);
+ if (model != null) {
+ List<ChimeraModel> models = chimeraManager.getChimeraModels(model,
+ ModelType.PDB_MODEL);
+ if (models.size() == 1) {
+ chimeraModel = models.get(0);
+ } else {
+ try {
+ chimeraModel = chimeraManager.getChimeraModel(Integer.valueOf(model), 0);
+ } catch (NumberFormatException ex) {
+ // ignore
+ }
+ }
+ }
+ if (chimeraModel == null) {
+ chimeraModel = chimeraManager.getChimeraModel();
+ }
+ // System.out.println("ChimeraModel = " + chimeraModel);
+
+ if (chain != null) {
+ chimeraChain = chimeraModel.getChain(chain);
+ // System.out.println("ChimeraChain = " + chimeraChain);
+ }
+ if (residue != null) {
+ if (chimeraChain != null) {
+ chimeraResidue = chimeraChain.getResidue(residue);
+ } else {
+ chimeraResidue = chimeraModel.getResidue("_", residue);
+ }
+ // System.out.println("ChimeraResidue = " + chimeraResidue);
+ }
+
+ if (chimeraResidue != null)
+ return chimeraResidue;
+
+ if (chimeraChain != null)
+ return chimeraChain;
+
+ if (chimeraModel != null)
+ return chimeraModel;
+
+ } catch (Exception ex) {
+ logger.warn("Could not parse residue identifier: " + attrSpec, ex);
+ }
+ return null;
+ }
+
+ public static ChimeraStructuralObject fromAttribute(String attrSpec,
+ ChimeraManager chimeraManager) {
+ // TODO: Make sure it is OK to remove this: || attrSpec.indexOf('-') > 0
+ if (attrSpec == null || attrSpec.indexOf(',') > 0) {
+ // No support for either lists or ranges
+ // System.out.println("No support for identifier: " + attrSpec);
+ logger.warn("No support for identifier: " + attrSpec);
+ return null;
+ }
+ String[] modelIDNoResChain = getResKeyParts(attrSpec);
+
+ ChimeraModel chimeraModel = null;
+ ChimeraChain chimeraChain = null;
+ ChimeraResidue chimeraResidue = null;
+
+ // System.out.println("Getting object from attribute: "+attrSpec);
+ try {
+ if (modelIDNoResChain[0] != null) {
+ String modelID = modelIDNoResChain[0];
+ List<ChimeraModel> models = chimeraManager.getChimeraModels(modelID,
+ ModelType.PDB_MODEL);
+ if (models.size() == 1) { // usual case with only one model
+ chimeraModel = models.get(0);
+ } else if (models.size() > 1 && modelIDNoResChain[1] != null) {
+ // there are several submodels
+ try {
+ int modelNo = Integer.valueOf(modelIDNoResChain[1]);
+ for (ChimeraModel model : models) {
+ if (model.getSubModelNumber() == modelNo) {
+ chimeraModel = model;
+ break;
+ }
+ }
+ } catch (NumberFormatException ex) {
+ // ignore
+ }
+ } else {
+ // TODO: [Optional] What is this doing?
+ try {
+ chimeraModel = chimeraManager.getChimeraModel(Integer.valueOf(modelID), 0);
+ } catch (NumberFormatException ex) {
+ // ignore
+ }
+ }
+ }
+ if (chimeraModel == null) {
+ // TODO: [Optional] Find a better way to handle this case
+ // If no model can be matched, continue
+ // System.out.println("No matching model could be find for " + attrSpec);
+ return null;
+ // chimeraModel = chimeraManager.getChimeraModel();
+ // logger.warn("No matching model could be find for " + attrSpec + ". Trying with "
+ // + chimeraModel.toSpec());
+ }
+ // System.out.println("ChimeraModel = " + chimeraModel);
+
+ if (modelIDNoResChain[3] != null) {
+ chimeraChain = chimeraModel.getChain(modelIDNoResChain[3]);
+ // System.out.println("ChimeraChain = " + chimeraChain);
+ }
+ if (modelIDNoResChain[2] != null) {
+ String residue = modelIDNoResChain[2];
+ if (chimeraChain != null) {
+ chimeraResidue = chimeraChain.getResidue(residue);
+ } else if (chimeraModel.getChain("_") != null) {
+ chimeraResidue = chimeraModel.getResidue("_", residue);
+ } else if (chimeraModel.getChainCount() == 1) {
+ chimeraResidue = chimeraModel.getResidue(chimeraModel.getChainNames()
+ .iterator().next(), residue);
+ }
+ // System.out.println("ChimeraResidue = " + chimeraResidue);
+ }
+
+ if (chimeraResidue != null)
+ return chimeraResidue;
+
+ if (chimeraChain != null)
+ return chimeraChain;
+
+ if (chimeraModel != null)
+ return chimeraModel;
+
+ } catch (Exception ex) {
+ // System.out.println("Could not parse chimera identifier: " +
+ // attrSpec+"("+ex.getMessage()+")");
+ logger.warn("Could not parse chimera identifier: " + attrSpec, ex);
+ }
+ return null;
+ }
+
+ /**
+ * Search for structure references in the residue list
+ *
+ * @param residueList
+ * the list of residues
+ * @return a concatenated list of structures encoded in the list
+ */
+ public static String findStructures(String residueList) {
+ if (residueList == null)
+ return null;
+ String[] residues = residueList.split(",");
+ Map<String, String> structureNameMap = new HashMap<String, String>();
+ for (int i = 0; i < residues.length; i++) {
+ String[] components = residues[i].split("#");
+ if (components.length > 1) {
+ structureNameMap.put(components[0], components[1]);
+ }
+ }
+ if (structureNameMap.isEmpty())
+ return null;
+
+ String structure = null;
+ for (String struct : structureNameMap.keySet()) {
+ if (structure == null)
+ structure = new String();
+ else
+ structure = structure.concat(",");
+ structure = structure.concat(struct);
+ }
+ return structure;
+ }
+
+ // invoked by openStructures in StructureManager
+ public static List<String> parseFuncRes(List<String> residueNames, String modelName) {
+ List<String> resRanges = new ArrayList<String>();
+ for (int i = 0; i < residueNames.size(); i++) {
+ String residue = residueNames.get(i);
+ // Parse out the structure, if there is one
+ String[] components = residue.split("#");
+ if (components.length > 1 && !modelName.equals(components[0])) {
+ continue;
+ } else if (components.length > 1) {
+ residue = components[1];
+ } else if (components.length == 1) {
+ residue = components[0];
+ }
+ // Check to see if we have a range-spec
+ String resRange = "";
+ if (residue == null || residue.equals("") || residue.length() == 0) {
+ continue;
+ }
+ String[] range = residue.split("-", 2);
+ String chain = null;
+ for (int res = 0; res < range.length; res++) {
+ if (res == 1) {
+ resRange = resRange.concat("-");
+ if (chain != null && range[res].indexOf('.') == -1)
+ range[res] = range[res].concat("." + chain);
+ }
+
+ if (res == 0 && range.length >= 2 && range[res].indexOf('.') > 0) {
+ // This is a range spec with the leading residue containing a chain spec
+ String[] resChain = range[res].split("\\.");
+ chain = resChain[1];
+ range[res] = resChain[0];
+ }
+ // Fix weird SFLD syntax...
+ if (range[res].indexOf('|') > 0 && Character.isDigit(range[res].charAt(0))) {
+ int offset = range[res].indexOf('|');
+ String str = range[res].substring(offset + 1) + range[res].substring(0, offset);
+ range[res] = str;
+ }
+
+ // Convert to legal atom-spec
+ if (Character.isDigit(range[res].charAt(0))) {
+ resRange = resRange.concat(range[res]);
+ } else if (Character.isDigit(range[res].charAt(1))) {
+ resRange = resRange.concat(range[res].substring(1));
+ } else if (range[res].charAt(0) == '.') {
+ // Do we have a chain spec?
+ resRange = resRange.concat(range[res]);
+ } else {
+ resRange = resRange.concat(range[res].substring(3));
+ }
+ }
+ if (!resRanges.contains(resRange)) {
+ resRanges.add(resRange);
+ }
+ }
+ return resRanges;
+ }
+
+ static {
+ aaNames = new HashMap<String, String>();
+ aaNames.put("ALA", "A Ala Alanine N[C@@H](C)C(O)=O");
+ aaNames.put("ARG", "R Arg Arginine N[C@@H](CCCNC(N)=N)C(O)=O");
+ aaNames.put("ASN", "N Asn Asparagine N[C@@H](CC(N)=O)C(O)=O");
+ aaNames.put("ASP", "D Asp Aspartic_acid N[C@@H](CC(O)=O)C(O)=O");
+ aaNames.put("CYS", "C Cys Cysteine N[C@@H](CS)C(O)=O");
+ aaNames.put("GLN", "Q Gln Glutamine N[C@H](C(O)=O)CCC(N)=O");
+ aaNames.put("GLU", "E Glu Glumatic_acid N[C@H](C(O)=O)CCC(O)=O");
+ aaNames.put("GLY", "G Gly Glycine NCC(O)=O");
+ aaNames.put("HIS", "H His Histidine N[C@@H](CC1=CN=CN1)C(O)=O");
+ aaNames.put("ILE", "I Ile Isoleucine N[C@]([C@H](C)CC)([H])C(O)=O");
+ aaNames.put("LEU", "L Leu Leucine N[C@](CC(C)C)([H])C(O)=O");
+ aaNames.put("LYS", "K Lys Lysine N[C@](CCCCN)([H])C(O)=O");
+ aaNames.put("DLY", "K Dly D-Lysine NCCCC[C@@H](N)C(O)=O");
+ aaNames.put("MET", "M Met Methionine N[C@](CCSC)([H])C(O)=O");
+ aaNames.put("PHE", "F Phe Phenylalanine N[C@](CC1=CC=CC=C1)([H])C(O)=O");
+ aaNames.put("PRO", "P Pro Proline OC([C@@]1([H])NCCC1)=O");
+ aaNames.put("SER", "S Ser Serine OC[C@](C(O)=O)([H])N");
+ aaNames.put("THR", "T Thr Threonine O[C@H](C)[C@](C(O)=O)([H])N");
+ aaNames.put("TRP", "W Trp Tryptophan N[C@@]([H])(CC1=CN([H])C2=C1C=CC=C2)C(O)=O");
+ aaNames.put("TYR", "Y Tyr Tyrosine N[C@@](C(O)=O)([H])CC1=CC=C(O)C=C1");
+ aaNames.put("VAL", "V Val Valine N[C@@](C(O)=O)([H])C(C)C");
+ aaNames.put("ASX", "B Asx Aspartic_acid_or_Asparagine");
+ aaNames.put("GLX", "Z Glx Glutamine_or_Glutamic_acid");
+ aaNames.put("XAA", "X Xaa Any_or_unknown_amino_acid");
+ aaNames.put("HOH", "HOH HOH Water [H]O[H]");
+ }
+
+ /**
+ * Convert the amino acid type to a full name
+ *
+ * @param aaType
+ * the residue type to convert
+ * @return the full name of the residue
+ */
+ public static String toFullName(String aaType) {
+ if (!aaNames.containsKey(aaType))
+ return aaType;
+ String[] ids = ((String) aaNames.get(aaType)).split(" ");
+ return ids[2].replace('_', ' ');
+ }
+
+ /**
+ * Convert the amino acid type to a single letter
+ *
+ * @param aaType
+ * the residue type to convert
+ * @return the single letter representation of the residue
+ */
+ public static String toSingleLetter(String aaType) {
+ if (!aaNames.containsKey(aaType))
+ return aaType;
+ String[] ids = ((String) aaNames.get(aaType)).split(" ");
+ return ids[0];
+ }
+
+ /**
+ * Convert the amino acid type to three letters
+ *
+ * @param aaType
+ * the residue type to convert
+ * @return the three letter representation of the residue
+ */
+ public static String toThreeLetter(String aaType) {
+ if (!aaNames.containsKey(aaType))
+ return aaType;
+ String[] ids = ((String) aaNames.get(aaType)).split(" ");
+ return ids[1];
+ }
+
+ /**
+ * Convert the amino acid type to its SMILES string
+ *
+ * @param aaType
+ * the residue type to convert
+ * @return the SMILES representation of the residue
+ */
+ public static String toSMILES(String aaType) {
+ if (!aaNames.containsKey(aaType))
+ return null;
+ String[] ids = ((String) aaNames.get(aaType)).split(" ");
+ if (ids.length < 4)
+ return null;
+ return ids[3];
+ }
+
+ public static String getAlignName(ChimeraStructuralObject chimObj) {
+ String name = chimObj.getChimeraModel().toString();
+ if (chimObj instanceof ChimeraChain) {
+ name = ((ChimeraChain) chimObj).toString() + " [" + name + "]";
+ }
+ return name;
+ }
+}
--- /dev/null
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions, and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. Redistributions must acknowledge that this software was
+ * originally developed by the UCSF Computer Graphics Laboratory
+ * under support by the NIH National Center for Research Resources,
+ * grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package ext.edu.ucsf.rbvi.strucviz2;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.TreeMap;
+
+/**
+ * This class provides the implementation for the ChimeraChain object
+ *
+ * @author scooter
+ *
+ */
+// TODO: [Optional] Implement toAttr() method
+public class ChimeraChain implements ChimeraStructuralObject {
+
+ /**
+ * The model/subModel number this chain is a part of
+ */
+ private int modelNumber;
+ private int subModelNumber;
+
+ /**
+ * A pointer to the model this chain is a part of
+ */
+ private ChimeraModel chimeraModel;
+
+ /**
+ * The chainID (from the PDB record)
+ */
+ private String chainId;
+
+ /**
+ * The residues that are part of this chain
+ */
+ private TreeMap<String, ChimeraResidue> residueMap;
+
+ /**
+ * userData to associate with this chain
+ */
+ private Object userData;
+
+ /**
+ * Flag to indicate the selection state
+ */
+ private boolean selected = false;
+
+ /**
+ * Constructor to create a new ChimeraChain
+ *
+ * @param model
+ * the model number this chain is part of
+ * @param subModel
+ * the subModel number this chain is part of
+ * @param chainId
+ * the chain ID for this chain
+ */
+ public ChimeraChain(int model, int subModel, String chainId) {
+ this.modelNumber = model;
+ this.subModelNumber = subModel;
+ this.chainId = chainId;
+ residueMap = new TreeMap<String, ChimeraResidue>();
+ }
+
+ /**
+ * set the selected state of this chain
+ *
+ * @param selected
+ * a boolean to set the selected state to
+ */
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ /**
+ * return the selected state of this chain
+ *
+ * @return the selected state
+ */
+ public boolean isSelected() {
+ return selected;
+ }
+
+ public boolean hasSelectedChildren() {
+ if (selected) {
+ return true;
+ } else {
+ for (ChimeraResidue residue : getResidues()) {
+ if (residue.isSelected())
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the list of selected residues
+ *
+ * @return all selected residues
+ */
+ public List<ChimeraResidue> getSelectedResidues() {
+ List<ChimeraResidue> residueList = new ArrayList<ChimeraResidue>();
+ if (selected) {
+ residueList.addAll(getResidues());
+ } else {
+ for (ChimeraResidue residue : getResidues()) {
+ if (residue.isSelected())
+ residueList.add(residue);
+ }
+ }
+ return residueList;
+ }
+
+ /**
+ * Add a residue to the chain.
+ *
+ * @param residue
+ * the ChimeraResidue to add to the chain.
+ */
+ public void addResidue(ChimeraResidue residue) {
+ String index = residue.getIndex();
+ // Put it in our map so that we can return it in order
+ residueMap.put(index, residue);
+ }
+
+ /**
+ * Return the list of residues in this chain in pdb residue order
+ *
+ * @return a Collection of residues in residue order
+ */
+ public Collection<ChimeraResidue> getResidues() {
+ return residueMap.values();
+ }
+
+ /**
+ * Return the list of residues in this chain as a list
+ *
+ * @return List of residues
+ */
+ public List<ChimeraStructuralObject> getChildren() {
+ return new ArrayList<ChimeraStructuralObject>(residueMap.values());
+ }
+
+ /**
+ * Get a specific residue
+ *
+ * @param residueIndex
+ * String representation of the residue index
+ * @return the ChimeraResidue represented by the residueIndex
+ */
+ public ChimeraResidue getResidue(String index) {
+ // Integer index = new Integer(residueIndex);
+ if (residueMap.containsKey(index))
+ return residueMap.get(index);
+ return null;
+ }
+
+ /**
+ * Get a list of residues as a residue range
+ *
+ * @param residueRange
+ * String representation of the residue range
+ * @return the List of ChimeraResidues represented by the range
+ */
+ public List<ChimeraResidue> getResidueRange(String residueRange) {
+ String[] range = residueRange.split("-", 2);
+ if (range[1] == null || range[1].length() == 0) {
+ range[1] = range[0];
+ }
+ List<ChimeraResidue> resultRange = new ArrayList<ChimeraResidue>();
+ int start = Integer.parseInt(range[0]);
+ int end = Integer.parseInt(range[1]);
+ for (int i = start; i <= end; i++) {
+ String index = String.valueOf(i);
+ if (residueMap.containsKey(index))
+ resultRange.add(residueMap.get(index));
+ }
+ return resultRange;
+ }
+
+ /**
+ * Get the ID for this chain
+ *
+ * @return String value of the chainId
+ */
+ public String getChainId() {
+ return chainId;
+ }
+
+ /**
+ * Get the model number for this chain
+ *
+ * @return the model number
+ */
+ public int getModelNumber() {
+ return modelNumber;
+ }
+
+ /**
+ * Get the sub-model number for this chain
+ *
+ * @return the sub-model number
+ */
+ public int getSubModelNumber() {
+ return subModelNumber;
+ }
+
+ /**
+ * Return a string representation of this chain as follows: Chain <i>chainId</i>
+ * (<i>residue_count</i> residues)
+ *
+ * @return String representation of chain
+ */
+ public String displayName() {
+ if (chainId.equals("_")) {
+ return ("Chain (no ID) (" + getResidueCount() + " residues)");
+ } else {
+ return ("Chain " + chainId + " (" + getResidueCount() + " residues)");
+ }
+ }
+
+ /**
+ * Return a string representation of this chain as follows: Node xxx [Model yyyy Chain
+ * <i>chainId</i>]
+ *
+ * @return String representation of chain
+ */
+ public String toString() {
+ String displayName = chimeraModel.getModelName();
+ if (displayName.length() > 14)
+ displayName = displayName.substring(0, 13) + "...";
+ if (chainId.equals("_")) {
+ return (displayName + " Chain (no ID) (" + getResidueCount() + " residues)");
+ } else {
+ return (displayName + " Chain " + chainId + " (" + getResidueCount() + " residues)");
+ }
+ }
+
+ /**
+ * Return the Chimera specification for this chain
+ *
+ * @return Chimera specification
+ */
+ public String toSpec() {
+ if (chainId.equals("_")) {
+ return ("#" + modelNumber + "." + subModelNumber + ":.");
+ } else {
+ return ("#" + modelNumber + "." + subModelNumber + ":." + chainId);
+ }
+ }
+
+ /**
+ * Return the number of residues in this chain
+ *
+ * @return integer number of residues
+ */
+ public int getResidueCount() {
+ return residueMap.size();
+ }
+
+ /**
+ * Set the ChimeraModel for this chain
+ *
+ * @param model
+ * ChimeraModel to associate with this chain
+ */
+ public void setChimeraModel(ChimeraModel model) {
+ this.chimeraModel = model;
+ }
+
+ /**
+ * Get the ChimeraModel for this chain
+ *
+ * @return ChimeraModel associated with this chain
+ */
+ public ChimeraModel getChimeraModel() {
+ return chimeraModel;
+ }
+
+ /**
+ * Get the user data for this Chain
+ *
+ * @return user data
+ */
+ public Object getUserData() {
+ return userData;
+ }
+
+ /**
+ * Set the user data for this Chain
+ *
+ * @param data
+ * the user data to associate with this chain
+ */
+ public void setUserData(Object data) {
+ this.userData = data;
+ }
+}
--- /dev/null
+package ext.edu.ucsf.rbvi.strucviz2;
+
+import java.awt.Color;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
+import ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads;
+
+/**
+ * This object maintains the Chimera communication information.
+ */
+public class ChimeraManager
+{
+
+ private Process chimera;
+
+ private ListenerThreads chimeraListenerThreads;
+
+ private Map<Integer, ChimeraModel> currentModelsMap;
+
+ private Logger logger = LoggerFactory
+ .getLogger(ext.edu.ucsf.rbvi.strucviz2.ChimeraManager.class);
+
+ private StructureManager structureManager;
+
+ public ChimeraManager(StructureManager structureManager)
+ {
+ this.structureManager = structureManager;
+ chimera = null;
+ chimeraListenerThreads = null;
+ currentModelsMap = new HashMap<Integer, ChimeraModel>();
+
+ }
+
+ public List<ChimeraModel> getChimeraModels(String modelName)
+ {
+ List<ChimeraModel> models = getChimeraModels(modelName,
+ ModelType.PDB_MODEL);
+ models.addAll(getChimeraModels(modelName, ModelType.SMILES));
+ return models;
+ }
+
+ public List<ChimeraModel> getChimeraModels(String modelName,
+ ModelType modelType)
+ {
+ List<ChimeraModel> models = new ArrayList<ChimeraModel>();
+ for (ChimeraModel model : currentModelsMap.values())
+ {
+ if (modelName.equals(model.getModelName())
+ && modelType.equals(model.getModelType()))
+ {
+ models.add(model);
+ }
+ }
+ return models;
+ }
+
+ public Map<String, List<ChimeraModel>> getChimeraModelsMap()
+ {
+ Map<String, List<ChimeraModel>> models = new HashMap<String, List<ChimeraModel>>();
+ for (ChimeraModel model : currentModelsMap.values())
+ {
+ String modelName = model.getModelName();
+ if (!models.containsKey(modelName))
+ {
+ models.put(modelName, new ArrayList<ChimeraModel>());
+ }
+ if (!models.get(modelName).contains(model))
+ {
+ models.get(modelName).add(model);
+ }
+ }
+ return models;
+ }
+
+ public ChimeraModel getChimeraModel(Integer modelNumber,
+ Integer subModelNumber)
+ {
+ Integer key = ChimUtils.makeModelKey(modelNumber, subModelNumber);
+ if (currentModelsMap.containsKey(key))
+ {
+ return currentModelsMap.get(key);
+ }
+ return null;
+ }
+
+ public ChimeraModel getChimeraModel()
+ {
+ return currentModelsMap.values().iterator().next();
+ }
+
+ public Collection<ChimeraModel> getChimeraModels()
+ {
+ // this method is invoked by the model navigator dialog
+ return currentModelsMap.values();
+ }
+
+ public int getChimeraModelsCount(boolean smiles)
+ {
+ // this method is invokes by the model navigator dialog
+ int counter = currentModelsMap.size();
+ if (smiles)
+ {
+ return counter;
+ }
+
+ for (ChimeraModel model : currentModelsMap.values())
+ {
+ if (model.getModelType() == ModelType.SMILES)
+ {
+ counter--;
+ }
+ }
+ return counter;
+ }
+
+ public boolean hasChimeraModel(Integer modelNubmer)
+ {
+ return hasChimeraModel(modelNubmer, 0);
+ }
+
+ public boolean hasChimeraModel(Integer modelNubmer, Integer subModelNumber)
+ {
+ return currentModelsMap.containsKey(ChimUtils.makeModelKey(modelNubmer,
+ subModelNumber));
+ }
+
+ public void addChimeraModel(Integer modelNumber, Integer subModelNumber,
+ ChimeraModel model)
+ {
+ currentModelsMap.put(
+ ChimUtils.makeModelKey(modelNumber, subModelNumber), model);
+ }
+
+ public void removeChimeraModel(Integer modelNumber, Integer subModelNumber)
+ {
+ int modelKey = ChimUtils.makeModelKey(modelNumber, subModelNumber);
+ if (currentModelsMap.containsKey(modelKey))
+ {
+ currentModelsMap.remove(modelKey);
+ }
+ }
+
+ public List<ChimeraModel> openModel(String modelPath, ModelType type)
+ {
+ return openModel(modelPath, getFileNameFromPath(modelPath), type);
+ }
+
+ /**
+ * Overloaded method to allow Jalview to pass in a model name.
+ *
+ * @param modelPath
+ * @param modelName
+ * @param type
+ * @return
+ */
+ public List<ChimeraModel> openModel(String modelPath, String modelName,
+ ModelType type)
+ {
+ logger.info("chimera open " + modelPath);
+ stopListening();
+ List<String> response = null;
+ // TODO: [Optional] Handle modbase models
+ if (type == ModelType.MODBASE_MODEL)
+ {
+ response = sendChimeraCommand("open modbase:" + modelPath, true);
+ // } else if (type == ModelType.SMILES) {
+ // response = sendChimeraCommand("open smiles:" + modelName, true);
+ // modelName = "smiles:" + modelName;
+ }
+ else
+ {
+ response = sendChimeraCommand("open " + modelPath, true);
+ }
+ if (response == null)
+ {
+ // something went wrong
+ logger.warn("Could not open " + modelPath);
+ return null;
+ }
+ List<ChimeraModel> models = new ArrayList<ChimeraModel>();
+ int[] modelNumbers = null;
+ if (type == ModelType.PDB_MODEL)
+ {
+ for (String line : response)
+ {
+ if (line.startsWith("#"))
+ {
+ modelNumbers = ChimUtils.parseOpenedModelNumber(line);
+ if (modelNumbers != null)
+ {
+ int modelNumber = ChimUtils.makeModelKey(modelNumbers[0],
+ modelNumbers[1]);
+ if (currentModelsMap.containsKey(modelNumber))
+ {
+ continue;
+ }
+ ChimeraModel newModel = new ChimeraModel(modelName, type,
+ modelNumbers[0], modelNumbers[1]);
+ currentModelsMap.put(modelNumber, newModel);
+ models.add(newModel);
+ // patch for Jalview - set model name in Chimera
+ sendChimeraCommand("setattr M name " + modelName + " #"
+ + modelNumbers[0], false);
+ // end patch for Jalview
+ modelNumbers = null;
+ }
+ }
+ }
+ }
+ else
+ {
+ // TODO: [Optional] Open smiles from file would fail. Do we need it?
+ // If parsing fails, iterate over all open models to get the right one
+ List<ChimeraModel> openModels = getModelList();
+ for (ChimeraModel openModel : openModels)
+ {
+ String openModelName = openModel.getModelName();
+ if (openModelName.endsWith("..."))
+ {
+ openModelName = openModelName.substring(0,
+ openModelName.length() - 3);
+ }
+ if (modelPath.startsWith(openModelName))
+ {
+ openModel.setModelName(modelPath);
+ int modelNumber = ChimUtils
+ .makeModelKey(openModel.getModelNumber(),
+ openModel.getSubModelNumber());
+ if (!currentModelsMap.containsKey(modelNumber))
+ {
+ currentModelsMap.put(modelNumber, openModel);
+ models.add(openModel);
+ }
+ }
+ }
+ }
+
+ // assign color and residues to open models
+ for (ChimeraModel newModel : models)
+ {
+ // get model color
+ Color modelColor = getModelColor(newModel);
+ if (modelColor != null)
+ {
+ newModel.setModelColor(modelColor);
+ }
+
+ // Get our properties (default color scheme, etc.)
+ // Make the molecule look decent
+ // chimeraSend("repr stick "+newModel.toSpec());
+
+ // Create the information we need for the navigator
+ if (type != ModelType.SMILES)
+ {
+ addResidues(newModel);
+ }
+ }
+
+ sendChimeraCommand("focus", false);
+ startListening();
+ return models;
+ }
+
+ /**
+ * Refactored method to extract the last (or only) element delimited by file
+ * path separator.
+ *
+ * @param modelPath
+ * @return
+ */
+ private String getFileNameFromPath(String modelPath)
+ {
+ String modelName = modelPath;
+ if (modelPath == null)
+ {
+ return null;
+ }
+ // TODO: [Optional] Convert path to name in a better way
+ if (modelPath.lastIndexOf(File.separator) > 0)
+ {
+ modelName = modelPath.substring(modelPath
+ .lastIndexOf(File.separator) + 1);
+ }
+ else if (modelPath.lastIndexOf("/") > 0)
+ {
+ modelName = modelPath
+ .substring(modelPath.lastIndexOf("/") + 1);
+ }
+ return modelName;
+ }
+
+ public void closeModel(ChimeraModel model)
+ {
+ // int model = structure.modelNumber();
+ // int subModel = structure.subModelNumber();
+ // Integer modelKey = makeModelKey(model, subModel);
+ stopListening();
+ logger.info("chimera close model " + model.getModelName());
+ if (currentModelsMap.containsKey(ChimUtils.makeModelKey(
+ model.getModelNumber(), model.getSubModelNumber())))
+ {
+ sendChimeraCommand("close " + model.toSpec(), false);
+ // currentModelNamesMap.remove(model.getModelName());
+ currentModelsMap.remove(ChimUtils.makeModelKey(
+ model.getModelNumber(), model.getSubModelNumber()));
+ // selectionList.remove(chimeraModel);
+ }
+ else
+ {
+ logger.warn("Could not find model " + model.getModelName()
+ + " to close.");
+ }
+ startListening();
+ }
+
+ public void startListening()
+ {
+ sendChimeraCommand("listen start models; listen start select", false);
+ }
+
+ public void stopListening()
+ {
+ sendChimeraCommand("listen stop models; listen stop select", false);
+ }
+
+ /**
+ * Select something in Chimera
+ *
+ * @param command
+ * the selection command to pass to Chimera
+ */
+ public void select(String command)
+ {
+ sendChimeraCommand("listen stop select; " + command
+ + "; listen start select", false);
+ }
+
+ public void focus()
+ {
+ sendChimeraCommand("focus", false);
+ }
+
+ public void clearOnChimeraExit()
+ {
+ chimera = null;
+ currentModelsMap.clear();
+ chimeraListenerThreads = null;
+ structureManager.clearOnChimeraExit();
+ }
+
+ public void exitChimera()
+ {
+ if (isChimeraLaunched() && chimera != null)
+ {
+ sendChimeraCommand("stop really", false);
+ try
+ {
+ chimera.destroy();
+ } catch (Exception ex)
+ {
+ // ignore
+ }
+ }
+ clearOnChimeraExit();
+ }
+
+ public Map<Integer, ChimeraModel> getSelectedModels()
+ {
+ Map<Integer, ChimeraModel> selectedModelsMap = new HashMap<Integer, ChimeraModel>();
+ List<String> chimeraReply = sendChimeraCommand(
+ "list selection level molecule", true);
+ if (chimeraReply != null)
+ {
+ for (String modelLine : chimeraReply)
+ {
+ ChimeraModel chimeraModel = new ChimeraModel(modelLine);
+ Integer modelKey = ChimUtils.makeModelKey(
+ chimeraModel.getModelNumber(),
+ chimeraModel.getSubModelNumber());
+ selectedModelsMap.put(modelKey, chimeraModel);
+ }
+ }
+ return selectedModelsMap;
+ }
+
+ public List<String> getSelectedResidueSpecs()
+ {
+ List<String> selectedResidues = new ArrayList<String>();
+ List<String> chimeraReply = sendChimeraCommand(
+ "list selection level residue", true);
+ if (chimeraReply != null)
+ {
+ for (String inputLine : chimeraReply)
+ {
+ String[] inputLineParts = inputLine.split("\\s+");
+ if (inputLineParts.length == 5)
+ {
+ selectedResidues.add(inputLineParts[2]);
+ }
+ }
+ }
+ return selectedResidues;
+ }
+
+ public void getSelectedResidues(
+ Map<Integer, ChimeraModel> selectedModelsMap)
+ {
+ List<String> chimeraReply = sendChimeraCommand(
+ "list selection level residue", true);
+ if (chimeraReply != null)
+ {
+ for (String inputLine : chimeraReply)
+ {
+ ChimeraResidue r = new ChimeraResidue(inputLine);
+ Integer modelKey = ChimUtils.makeModelKey(r.getModelNumber(),
+ r.getSubModelNumber());
+ if (selectedModelsMap.containsKey(modelKey))
+ {
+ ChimeraModel model = selectedModelsMap.get(modelKey);
+ model.addResidue(r);
+ }
+ }
+ }
+ }
+
+ /**
+ * Return the list of ChimeraModels currently open. Warning: if smiles model
+ * name too long, only part of it with "..." is printed.
+ *
+ *
+ * @return List of ChimeraModel's
+ */
+ // TODO: [Optional] Handle smiles names in a better way in Chimera?
+ public List<ChimeraModel> getModelList()
+ {
+ List<ChimeraModel> modelList = new ArrayList<ChimeraModel>();
+ List<String> list = sendChimeraCommand("list models type molecule",
+ true);
+ if (list != null)
+ {
+ for (String modelLine : list)
+ {
+ ChimeraModel chimeraModel = new ChimeraModel(modelLine);
+ modelList.add(chimeraModel);
+ }
+ }
+ return modelList;
+ }
+
+ /**
+ * Return the list of depiction presets available from within Chimera. Chimera
+ * will return the list as a series of lines with the format: Preset type
+ * number "description"
+ *
+ * @return list of presets
+ */
+ public List<String> getPresets()
+ {
+ ArrayList<String> presetList = new ArrayList<String>();
+ List<String> output = sendChimeraCommand("preset list", true);
+ if (output != null)
+ {
+ for (String preset : output)
+ {
+ preset = preset.substring(7); // Skip over the "Preset"
+ preset = preset.replaceFirst("\"", "(");
+ preset = preset.replaceFirst("\"", ")");
+ // string now looks like: type number (description)
+ presetList.add(preset);
+ }
+ }
+ return presetList;
+ }
+
+ public boolean isChimeraLaunched()
+ {
+ boolean launched = false;
+ if (chimera != null)
+ {
+ try
+ {
+ chimera.exitValue();
+ // if we get here, process has ended
+ } catch (IllegalThreadStateException e)
+ {
+ // ok - not yet terminated
+ launched = true;
+ }
+ }
+ return launched;
+ }
+
+ public boolean launchChimera(List<String> chimeraPaths)
+ {
+ // Do nothing if Chimera is already launched
+ if (isChimeraLaunched())
+ {
+ return true;
+ }
+
+ // Try to launch Chimera (eventually using one of the possible paths)
+ String error = "Error message: ";
+ String workingPath = "";
+ // iterate over possible paths for starting Chimera
+ for (String chimeraPath : chimeraPaths)
+ {
+ File path = new File(chimeraPath);
+ if (!path.canExecute())
+ {
+ error += "File '" + path + "' does not exist.\n";
+ continue;
+ }
+ try
+ {
+ List<String> args = new ArrayList<String>();
+ args.add(chimeraPath);
+ args.add("--start");
+ args.add("ReadStdin");
+ ProcessBuilder pb = new ProcessBuilder(args);
+ chimera = pb.start();
+ error = "";
+ workingPath = chimeraPath;
+ logger.info("Strarting " + chimeraPath);
+ break;
+ } catch (Exception e)
+ {
+ // Chimera could not be started
+ error += e.getMessage();
+ }
+ }
+ // If no error, then Chimera was launched successfully
+ if (error.length() == 0)
+ {
+ // Initialize the listener threads
+ chimeraListenerThreads = new ListenerThreads(chimera,
+ structureManager);
+ chimeraListenerThreads.start();
+ // structureManager.initChimTable();
+ structureManager.setChimeraPathProperty(workingPath);
+ // TODO: [Optional] Check Chimera version and show a warning if below 1.8
+ // Ask Chimera to give us updates
+ startListening();
+ return true;
+ }
+
+ // Tell the user that Chimera could not be started because of an error
+ logger.warn(error);
+ return false;
+ }
+
+ /**
+ * Determine the color that Chimera is using for this model.
+ *
+ * @param model
+ * the ChimeraModel we want to get the Color for
+ * @return the default model Color for this model in Chimera
+ */
+ public Color getModelColor(ChimeraModel model)
+ {
+ List<String> colorLines = sendChimeraCommand(
+ "list model spec " + model.toSpec() + " attribute color", true);
+ if (colorLines == null || colorLines.size() == 0)
+ {
+ return null;
+ }
+ return ChimUtils.parseModelColor(colorLines.get(0));
+ }
+
+ /**
+ *
+ * Get information about the residues associated with a model. This uses the
+ * Chimera listr command. We don't return the resulting residues, but we add
+ * the residues to the model.
+ *
+ * @param model
+ * the ChimeraModel to get residue information for
+ *
+ */
+ public void addResidues(ChimeraModel model)
+ {
+ int modelNumber = model.getModelNumber();
+ int subModelNumber = model.getSubModelNumber();
+ // Get the list -- it will be in the reply log
+ List<String> reply = sendChimeraCommand(
+ "list residues spec " + model.toSpec(), true);
+ if (reply == null)
+ {
+ return;
+ }
+ for (String inputLine : reply)
+ {
+ ChimeraResidue r = new ChimeraResidue(inputLine);
+ if (r.getModelNumber() == modelNumber
+ || r.getSubModelNumber() == subModelNumber)
+ {
+ model.addResidue(r);
+ }
+ }
+ }
+
+ public List<String> getAttrList()
+ {
+ List<String> attributes = new ArrayList<String>();
+ final List<String> reply = sendChimeraCommand("list resattr", true);
+ if (reply != null)
+ {
+ for (String inputLine : reply)
+ {
+ String[] lineParts = inputLine.split("\\s");
+ if (lineParts.length == 2 && lineParts[0].equals("resattr"))
+ {
+ attributes.add(lineParts[1]);
+ }
+ }
+ }
+ return attributes;
+ }
+
+ public Map<ChimeraResidue, Object> getAttrValues(String aCommand,
+ ChimeraModel model)
+ {
+ Map<ChimeraResidue, Object> values = new HashMap<ChimeraResidue, Object>();
+ final List<String> reply = sendChimeraCommand("list residue spec "
+ + model.toSpec() + " attribute " + aCommand, true);
+ if (reply != null)
+ {
+ for (String inputLine : reply)
+ {
+ String[] lineParts = inputLine.split("\\s");
+ if (lineParts.length == 5)
+ {
+ ChimeraResidue residue = ChimUtils
+ .getResidue(lineParts[2], model);
+ String value = lineParts[4];
+ if (residue != null)
+ {
+ if (value.equals("None"))
+ {
+ continue;
+ }
+ if (value.equals("True") || value.equals("False"))
+ {
+ values.put(residue, Boolean.valueOf(value));
+ continue;
+ }
+ try
+ {
+ Double doubleValue = Double.valueOf(value);
+ values.put(residue, doubleValue);
+ } catch (NumberFormatException ex)
+ {
+ values.put(residue, value);
+ }
+ }
+ }
+ }
+ }
+ return values;
+ }
+
+ private volatile boolean busy = false;
+
+ /**
+ * Send a command to Chimera.
+ *
+ * @param command
+ * Command string to be send.
+ * @param reply
+ * Flag indicating whether the method should return the reply from
+ * Chimera or not.
+ * @return List of Strings corresponding to the lines in the Chimera reply or
+ * <code>null</code>.
+ */
+ public List<String> sendChimeraCommand(String command, boolean reply)
+ {
+ if (!isChimeraLaunched())
+ {
+ return null;
+ }
+ // TODO do we need a maximum wait time before aborting?
+ while (busy)
+ {
+ try
+ {
+ Thread.sleep(25);
+ } catch (InterruptedException q)
+ {
+ }
+ ;
+ }
+ busy = true;
+ try
+ {
+ chimeraListenerThreads.clearResponse(command);
+ String text = command.concat("\n");
+ // System.out.println("send command to chimera: " + text);
+ try
+ {
+ // send the command
+ chimera.getOutputStream().write(text.getBytes());
+ chimera.getOutputStream().flush();
+ } catch (IOException e)
+ {
+ // logger.info("Unable to execute command: " + text);
+ // logger.info("Exiting...");
+ logger.warn("Unable to execute command: " + text);
+ logger.warn("Exiting...");
+ clearOnChimeraExit();
+ // busy = false;
+ return null;
+ }
+ if (!reply)
+ {
+ // busy = false;
+ return null;
+ }
+ List<String> rsp = chimeraListenerThreads.getResponse(command);
+ // busy = false;
+ return rsp;
+ } finally
+ {
+ busy = false;
+ }
+ }
+
+ public StructureManager getStructureManager()
+ {
+ return structureManager;
+ }
+
+ public boolean isBusy()
+ {
+ return busy;
+ }
+
+}
--- /dev/null
+package ext.edu.ucsf.rbvi.strucviz2;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
+
+/**
+ * This class provides the implementation for the ChimeraModel, ChimeraChain, and ChimeraResidue
+ * objects
+ *
+ * @author scooter
+ *
+ */
+public class ChimeraModel implements ChimeraStructuralObject {
+
+ private String name; // The name of this model
+ private ModelType type; // The type of the model
+ private int modelNumber; // The model number
+ private int subModelNumber; // The sub-model number
+
+ private Color modelColor = null; // The color of this model (from Chimera)
+ private Object userData = null; // User data associated with this model
+ private boolean selected = false; // The selected state of this model
+
+ private TreeMap<String, ChimeraChain> chainMap; // The list of chains
+ // private TreeMap<String, ChimeraResidue> residueMap; // The list of residues
+ private HashSet<ChimeraResidue> funcResidues; // List of functional residues
+
+ /**
+ * Constructor to create a model
+ *
+ * @param name
+ * the name of this model
+ * @param color
+ * the model Color
+ * @param modelNumber
+ * the model number
+ * @param subModelNumber
+ * the sub-model number
+ */
+ public ChimeraModel(String name, ModelType type, int modelNumber, int subModelNumber) {
+ this.name = name;
+ this.type = type;
+ this.modelNumber = modelNumber;
+ this.subModelNumber = subModelNumber;
+
+ this.chainMap = new TreeMap<String, ChimeraChain>();
+ this.funcResidues = new HashSet<ChimeraResidue>();
+ }
+
+ /**
+ * Constructor to create a model from the Chimera input line
+ *
+ * @param inputLine
+ * Chimera input line from which to construct this model
+ */
+ // TODO: [Optional] How to distinguish between PDB and MODBASE?
+ // invoked when listing models: listm type molecule; lists level molecule
+ // line = model id #0 type Molecule name 1ert
+ public ChimeraModel(String inputLine) {
+ this.name = ChimUtils.parseModelName(inputLine);
+ // TODO: [Optional] Write a separate method to get model type
+ if (name.startsWith("smiles")) {
+ this.type = ModelType.SMILES;
+ } else {
+ this.type = ModelType.PDB_MODEL;
+ }
+ this.modelNumber = ChimUtils.parseModelNumber(inputLine)[0];
+ this.subModelNumber = ChimUtils.parseModelNumber(inputLine)[1];
+
+ this.chainMap = new TreeMap<String, ChimeraChain>();
+ this.funcResidues = new HashSet<ChimeraResidue>();
+ }
+
+ /**
+ * Add a residue to this model
+ *
+ * @param residue
+ * to add to the model
+ */
+ public void addResidue(ChimeraResidue residue) {
+ residue.setChimeraModel(this);
+ // residueMap.put(residue.getIndex(), residue);
+ String chainId = residue.getChainId();
+ if (chainId != null) {
+ addResidue(chainId, residue);
+ } else {
+ addResidue("_", residue);
+ }
+ // Put it in our map so that we can return it in order
+ // residueMap.put(residue.getIndex(), residue);
+ }
+
+ /**
+ * Add a residue to a chain in this model. If the chain associated with chainId doesn't exist,
+ * it will be created.
+ *
+ * @param chainId
+ * to add the residue to
+ * @param residue
+ * to add to the chain
+ */
+ public void addResidue(String chainId, ChimeraResidue residue) {
+ ChimeraChain chain = null;
+ if (!chainMap.containsKey(chainId)) {
+ chain = new ChimeraChain(this.modelNumber, this.subModelNumber, chainId);
+ chain.setChimeraModel(this);
+ chainMap.put(chainId, chain);
+ } else {
+ chain = chainMap.get(chainId);
+ }
+ chain.addResidue(residue);
+ }
+
+ /**
+ * Get the ChimeraModel (required for ChimeraStructuralObject interface)
+ *
+ * @return ChimeraModel
+ */
+ public ChimeraModel getChimeraModel() {
+ return this;
+ }
+
+ /**
+ * Get the model color of this model
+ *
+ * @return model color of this model
+ */
+ public Color getModelColor() {
+ return this.modelColor;
+ }
+
+ /**
+ * Set the color of this model
+ *
+ * @param color
+ * Color of this model
+ */
+ public void setModelColor(Color color) {
+ this.modelColor = color;
+ }
+
+ /**
+ * Return the name of this model
+ *
+ * @return model name
+ */
+ public String getModelName() {
+ return name;
+ }
+
+ /**
+ * Set the name of this model
+ *
+ * @param name
+ * model name
+ */
+ public void setModelName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the model number of this model
+ *
+ * @return integer model number
+ */
+ public int getModelNumber() {
+ return modelNumber;
+ }
+
+ /**
+ * Set the model number of this model
+ *
+ * @param modelNumber
+ * integer model number
+ */
+ public void setModelNumber(int modelNumber) {
+ this.modelNumber = modelNumber;
+ }
+
+ /**
+ * Get the sub-model number of this model
+ *
+ * @return integer sub-model number
+ */
+ public int getSubModelNumber() {
+ return subModelNumber;
+ }
+
+ /**
+ * Set the sub-model number of this model
+ *
+ * @param subModelNumber
+ * integer model number
+ */
+ public void setSubModelNumber(int subModelNumber) {
+ this.subModelNumber = subModelNumber;
+ }
+
+ public ModelType getModelType() {
+ return type;
+ }
+
+ public void setModelType(ModelType type) {
+ this.type = type;
+ }
+
+ public HashSet<ChimeraResidue> getFuncResidues() {
+ return funcResidues;
+ }
+
+ public void setFuncResidues(List<String> residues) {
+ for (String residue : residues) {
+ for (ChimeraChain chain : getChains()) {
+ if (residue.indexOf("-") > 0) {
+ funcResidues.addAll(chain.getResidueRange(residue));
+ } else {
+ funcResidues.add(chain.getResidue(residue));
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the user data for this model
+ *
+ * @return user data
+ */
+ public Object getUserData() {
+ return userData;
+ }
+
+ /**
+ * Set the user data for this model
+ *
+ * @param data
+ * user data to associate with this model
+ */
+ public void setUserData(Object data) {
+ this.userData = data;
+ }
+
+ /**
+ * Return the selected state of this model
+ *
+ * @return the selected state
+ */
+ public boolean isSelected() {
+ return selected;
+ }
+
+ /**
+ * Set the selected state of this model
+ *
+ * @param selected
+ * a boolean to set the selected state to
+ */
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ /**
+ * Return the chains in this model as a List
+ *
+ * @return the chains in this model as a list
+ */
+ public List<ChimeraStructuralObject> getChildren() {
+ return new ArrayList<ChimeraStructuralObject>(chainMap.values());
+ }
+
+ /**
+ * Return the chains in this model as a colleciton
+ *
+ * @return the chains in this model
+ */
+ public Collection<ChimeraChain> getChains() {
+ return chainMap.values();
+ }
+
+ /**
+ * Get the number of chains in this model
+ *
+ * @return integer chain count
+ */
+ public int getChainCount() {
+ return chainMap.size();
+ }
+
+ /**
+ * Get the list of chain names associated with this model
+ *
+ * @return return the list of chain names for this model
+ */
+ public Collection<String> getChainNames() {
+ return chainMap.keySet();
+ }
+
+ /**
+ * Get the residues associated with this model
+ *
+ * @return the list of residues in this model
+ */
+ public Collection<ChimeraResidue> getResidues() {
+ Collection<ChimeraResidue> residues = new ArrayList<ChimeraResidue>();
+ for (ChimeraChain chain : getChains()) {
+ residues.addAll(chain.getResidues());
+ }
+ return residues;
+ }
+
+ /**
+ * Get the number of residues in this model
+ *
+ * @return integer residues count
+ */
+ public int getResidueCount() {
+ int count = 0;
+ for (ChimeraChain chain : getChains()) {
+ count += chain.getResidueCount();
+ }
+ return count;
+ }
+
+ /**
+ * Get a specific chain from the model
+ *
+ * @param chain
+ * the ID of the chain to return
+ * @return ChimeraChain associated with the chain
+ */
+ public ChimeraChain getChain(String chain) {
+ if (chainMap.containsKey(chain)) {
+ return chainMap.get(chain);
+ }
+ return null;
+ }
+
+ /**
+ * Return a specific residue based on its index
+ *
+ * @param index
+ * of the residue to return
+ * @return the residue associated with that index
+ */
+ public ChimeraResidue getResidue(String chainId, String index) {
+ if (chainMap.containsKey(chainId)) {
+ return chainMap.get(chainId).getResidue(index);
+ }
+ return null;
+ }
+
+ /**
+ * Checks if this model has selected children.
+ */
+ public boolean hasSelectedChildren() {
+ if (selected) {
+ return true;
+ } else {
+ for (ChimeraChain chain : getChains()) {
+ if (chain.hasSelectedChildren()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the list of selected residues
+ *
+ * @return all selected residues
+ */
+ public List<ChimeraResidue> getSelectedResidues() {
+ List<ChimeraResidue> residueList = new ArrayList<ChimeraResidue>();
+ for (ChimeraChain chain : getChains()) {
+ if (selected) {
+ residueList.addAll(chain.getSelectedResidues());
+ } else {
+ residueList.addAll(getResidues());
+ }
+ }
+ return residueList;
+ }
+
+
+ /**
+ * Return the Chimera specification for this model.
+ */
+ public String toSpec() {
+ if (subModelNumber == 0)
+ return ("#" + modelNumber);
+ return ("#" + modelNumber + "." + subModelNumber);
+ }
+
+ /**
+ * Return a string representation for the model. Shorten if longer than 100 characters.
+ */
+ public String toString() {
+ String modelName = "";
+ // TODO: [Optional] Change cutoff for shortening model names in the structure naviagator dialog
+ if (getChainCount() > 0) {
+ modelName = "Model " + toSpec() + " " + name + " (" + getChainCount() + " chains, "
+ + getResidueCount() + " residues)";
+ } else if (getResidueCount() > 0) {
+ modelName = "Model " + toSpec() + " " + name + " (" + getResidueCount() + " residues)";
+ } else {
+ modelName = "Model " + toSpec() + " " + name + "";
+ }
+
+ Set<String> networkNames = new HashSet<String>();
+ Set<String> nodeNames = new HashSet<String>();
+ Set<String> edgeNames = new HashSet<String>();
+
+ String cytoName = " [";
+ if (networkNames.size() > 0) {
+ if (networkNames.size() == 1) {
+ cytoName += "Network {";
+ } else if (networkNames.size() > 1) {
+ cytoName += "Networks {";
+ }
+ for (String cName : networkNames) {
+ cytoName += cName + ",";
+ }
+ cytoName = cytoName.substring(0, cytoName.length() - 1) + "}, ";
+ }
+ if (nodeNames.size() > 0) {
+ if (nodeNames.size() == 1) {
+ cytoName += "Node {";
+ } else if (nodeNames.size() > 1) {
+ cytoName += "Nodes {";
+ }
+ for (String cName : nodeNames) {
+ cytoName += cName + ",";
+ }
+ cytoName = cytoName.substring(0, cytoName.length() - 1) + "}, ";
+ }
+ if (edgeNames.size() > 0) {
+ if (edgeNames.size() == 1) {
+ cytoName += "Edge {";
+ } else if (edgeNames.size() > 1) {
+ cytoName += "Edges {";
+ }
+ for (String cName : edgeNames) {
+ cytoName += cName + ",";
+ }
+ cytoName = cytoName.substring(0, cytoName.length() - 1) + "}, ";
+ }
+ if (cytoName.endsWith(", ")) {
+ cytoName = cytoName.substring(0, cytoName.length() - 2);
+ }
+ cytoName += "]";
+ String nodeName = modelName + cytoName;
+ if (nodeName.length() > 100) {
+ nodeName = nodeName.substring(0, 100) + "...";
+ }
+ return nodeName;
+ }
+}
--- /dev/null
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions, and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. Redistributions must acknowledge that this software was
+ * originally developed by the UCSF Computer Graphics Laboratory
+ * under support by the NIH National Center for Research Resources,
+ * grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package ext.edu.ucsf.rbvi.strucviz2;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class provides the implementation for the ChimeraResidue, object
+ *
+ * @author scooter
+ *
+ */
+
+public class ChimeraResidue implements ChimeraStructuralObject, Comparable<ChimeraResidue> {
+
+ /* Constants */
+ public static final int SINGLE_LETTER = 0; // Display residues as a single
+ // letter
+ public static final int THREE_LETTER = 1; // Display residues as three letters
+ public static final int FULL_NAME = 2; // Display full residue names
+
+ private String type; // Residue type
+ private String index; // Residue index
+ private String chainId; // ChainID for this residue
+ private int modelNumber; // model number for this residue
+ private int subModelNumber; // sub-model number for this residue
+ protected int residueNumber;
+ protected String insertionCode;
+ private ChimeraModel chimeraModel; // ChimeraModel the residue is part of
+ private Object userData; // user data to associate with this residue
+ // public static HashMap<String, String> aaNames = null; // a map of amino acid
+ // names
+ private static int displayType = THREE_LETTER; // the current display type
+ private boolean selected = false; // the selection state
+
+ /**
+ * Constructor to create a new ChimeraResidue
+ *
+ * @param type
+ * the residue type
+ * @param index
+ * the index of the residue
+ * @param modelNumber
+ * the model number this residue is part of
+ */
+ public ChimeraResidue(String type, String index, int modelNumber) {
+ this(type, index, modelNumber, 0);
+ }
+
+ /**
+ * Constructor to create a new ChimeraResidue
+ *
+ * @param type
+ * the residue type
+ * @param index
+ * the index of the residue
+ * @param modelNumber
+ * the model number this residue is part of
+ * @param subModelNumber
+ * the sub-model number this residue is part of
+ */
+ public ChimeraResidue(String type, String index, int modelNumber, int subModelNumber) {
+ this.type = type;
+ this.index = index;
+ this.modelNumber = modelNumber;
+ this.subModelNumber = subModelNumber;
+ splitInsertionCode(this.index);
+ // if (aaNames == null) {
+ // initNames();
+ // }
+ }
+
+ /**
+ * Constructor to create a new ChimeraResidue from an input line
+ *
+ * @param chimeraInputLine
+ * a Chimera residue description
+ */
+ // invoked when listing (selected) residues: listr spec #0; lists level residue
+ // Line: residue id #0:37.A type MET
+ public ChimeraResidue(String chimeraInputLine) {
+ // initNames();
+ String[] split1 = chimeraInputLine.split(":");
+
+ // First half has model number -- get the number
+ int numberOffset = split1[0].indexOf('#');
+ String model = split1[0].substring(numberOffset + 1);
+ int decimalOffset = model.indexOf('.'); // Do we have a sub-model?
+ try {
+ this.subModelNumber = 0;
+ if (decimalOffset > 0) {
+ this.subModelNumber = Integer.parseInt(model.substring(decimalOffset + 1));
+ this.modelNumber = Integer.parseInt(model.substring(0, decimalOffset));
+ } else {
+ this.modelNumber = Integer.parseInt(model);
+ }
+ } catch (Exception e) {
+ LoggerFactory.getLogger(ChimeraResidue.class)
+ .error("Unexpected return from Chimera: " + model);
+ this.modelNumber = -1;
+ }
+
+ // Second half has residue info: index & type
+ String[] rTokens = split1[1].split(" ");
+ this.type = rTokens[2];
+
+ String[] iTokens = rTokens[0].split("\\.");
+ if (iTokens.length > 0) {
+ this.index = iTokens[0];
+
+ // Careful, might or might not have a chainID
+ if (iTokens.length > 1)
+ this.chainId = iTokens[1];
+ else
+ this.chainId = "_";
+ } else
+ this.index = rTokens[0];
+
+ splitInsertionCode(this.index);
+ }
+
+ /**
+ * Set the selected state for this residue
+ *
+ * @param selected
+ * the selection state to set
+ */
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ /**
+ * Return the selected state of this residue
+ *
+ * @return the selected state
+ */
+ public boolean isSelected() {
+ return selected;
+ }
+
+ /**
+ * Return an array made up of this residue (required for ChimeraStructuralObject interface
+ *
+ * @return a List with this residue as its sole member
+ */
+ public List<ChimeraStructuralObject> getChildren() {
+ List<ChimeraStructuralObject> v = new ArrayList<ChimeraStructuralObject>();
+ v.add(this);
+ return v;
+ }
+
+ /**
+ * Return the string representation of this residue as follows: "<i>residue_name</i> <i>index</i>"
+ * where <i>residue_name</i> could be either the single letter, three letter, or full name
+ * representation of the amino acid.
+ *
+ * @return the string representation
+ */
+ public String displayName() {
+ return toString();
+ }
+
+ /**
+ * Return the string representation of this residue as follows: "<i>residue_name</i> <i>index</i>"
+ * where <i>residue_name</i> could be either the single letter, three letter, or full name
+ * representation of the amino acid.
+ *
+ * @return the string representation
+ */
+ public String toString() {
+ if (displayType == FULL_NAME) {
+ return (ChimUtils.toFullName(type) + " " + index);
+ } else if (displayType == SINGLE_LETTER) {
+ return (ChimUtils.toSingleLetter(type) + " " + index);
+ } else if (displayType == THREE_LETTER) {
+ return (ChimUtils.toThreeLetter(type) + " " + index);
+ } else {
+ return (type + " " + index);
+ }
+ }
+
+ /**
+ * Return the Chimera specification for this Residue
+ *
+ * @return Chimera specification
+ */
+ public String toSpec() {
+ if (!chainId.equals("_"))
+ return ("#" + modelNumber + ":" + index + "." + chainId);
+ else
+ return ("#" + modelNumber + ":" + index + ".");
+ }
+
+ /**
+ * Get the index of this residue
+ *
+ * @return residue index
+ */
+ public String getIndex() {
+ return this.index;
+ }
+
+ /**
+ * Get the chainID for this residue
+ *
+ * @return String value of the chainId
+ */
+ public String getChainId() {
+ return this.chainId;
+ }
+
+ /**
+ * Get the type for this residue
+ *
+ * @return residue type
+ */
+ public String getType() {
+ return this.type;
+ }
+
+ /**
+ * Get the model number for this residue
+ *
+ * @return the model number
+ */
+ public int getModelNumber() {
+ return this.modelNumber;
+ }
+
+ /**
+ * Get the sub-model number for this residue
+ *
+ * @return the sub-model number
+ */
+ public int getSubModelNumber() {
+ return this.subModelNumber;
+ }
+
+ /**
+ * Get the model this residue is part of
+ *
+ * @return the ChimeraModel
+ */
+ public ChimeraModel getChimeraModel() {
+ return this.chimeraModel;
+ }
+
+ /**
+ * Set the model this residue is part of
+ *
+ * @param chimeraModel
+ * the ChimeraModel this model is part of
+ */
+ public void setChimeraModel(ChimeraModel chimeraModel) {
+ this.chimeraModel = chimeraModel;
+ }
+
+ /**
+ * Get the user data for this residue
+ *
+ * @return user data
+ */
+ public Object getUserData() {
+ return userData;
+ }
+
+ /**
+ * Set the user data for this Residue
+ *
+ * @param data
+ * the user data to associate with this residue
+ */
+ public void setUserData(Object data) {
+ this.userData = data;
+ }
+
+ public int compareTo(ChimeraResidue c2) {
+ if (residueNumber < c2.residueNumber)
+ return -1;
+ else if (residueNumber == c2.residueNumber) {
+ if (insertionCode == null && c2.insertionCode == null)
+ return 0;
+ else if (insertionCode == null)
+ return -1;
+ else if (c2.insertionCode == null)
+ return 1;
+ return (insertionCode.compareTo(c2.insertionCode));
+ }
+ return 1;
+ }
+
+ public void splitInsertionCode(String residue) {
+ // OK, split the index into number and insertion code
+ Pattern p = Pattern.compile("(\\d*)([A-Z]?)");
+ Matcher m = p.matcher(residue);
+ if (m.matches()) {
+ this.residueNumber = Integer.parseInt(m.group(1));
+ if (m.groupCount() > 1)
+ this.insertionCode = m.group(2);
+ else
+ this.insertionCode = null;
+ }
+ }
+
+ /**********************************************
+ * Static routines
+ *********************************************/
+
+ /**
+ * Initialize the residue names
+ */
+ // private static void initNames() {
+ // // Create our residue name table
+ // aaNames = new HashMap<String, String>();
+ // aaNames.put("ALA", "A Ala Alanine N[C@@H](C)C(O)=O");
+ // aaNames.put("ARG", "R Arg Arginine N[C@@H](CCCNC(N)=N)C(O)=O");
+ // aaNames.put("ASN", "N Asn Asparagine N[C@@H](CC(N)=O)C(O)=O");
+ // aaNames.put("ASP", "D Asp Aspartic_acid N[C@@H](CC(O)=O)C(O)=O");
+ // aaNames.put("CYS", "C Cys Cysteine N[C@@H](CS)C(O)=O");
+ // aaNames.put("GLN", "Q Gln Glutamine N[C@H](C(O)=O)CCC(N)=O");
+ // aaNames.put("GLU", "E Glu Glumatic_acid N[C@H](C(O)=O)CCC(O)=O");
+ // aaNames.put("GLY", "G Gly Glycine NCC(O)=O");
+ // aaNames.put("HIS", "H His Histidine N[C@@H](CC1=CN=CN1)C(O)=O");
+ // aaNames.put("ILE", "I Ile Isoleucine N[C@]([C@H](C)CC)([H])C(O)=O");
+ // aaNames.put("LEU", "L Leu Leucine N[C@](CC(C)C)([H])C(O)=O");
+ // aaNames.put("LYS", "K Lys Lysine N[C@](CCCCN)([H])C(O)=O");
+ // aaNames.put("DLY", "K Dly D-Lysine NCCCC[C@@H](N)C(O)=O");
+ // aaNames.put("MET", "M Met Methionine N[C@](CCSC)([H])C(O)=O");
+ // aaNames.put("PHE", "F Phe Phenylalanine N[C@](CC1=CC=CC=C1)([H])C(O)=O");
+ // aaNames.put("PRO", "P Pro Proline OC([C@@]1([H])NCCC1)=O");
+ // aaNames.put("SER", "S Ser Serine OC[C@](C(O)=O)([H])N");
+ // aaNames.put("THR", "T Thr Threonine O[C@H](C)[C@](C(O)=O)([H])N");
+ // aaNames.put("TRP", "W Trp Tryptophan N[C@@]([H])(CC1=CN([H])C2=C1C=CC=C2)C(O)=O");
+ // aaNames.put("TYR", "Y Tyr Tyrosine N[C@@](C(O)=O)([H])CC1=CC=C(O)C=C1");
+ // aaNames.put("VAL", "V Val Valine N[C@@](C(O)=O)([H])C(C)C");
+ // aaNames.put("ASX", "B Asx Aspartic_acid_or_Asparagine");
+ // aaNames.put("GLX", "Z Glx Glutamine_or_Glutamic_acid");
+ // aaNames.put("XAA", "X Xaa Any_or_unknown_amino_acid");
+ // aaNames.put("HOH", "HOH HOH Water [H]O[H]");
+ // }
+
+ /**
+ * Set the display type.
+ *
+ * @param type
+ * the display type
+ */
+ public static void setDisplayType(int type) {
+ displayType = type;
+ }
+
+ public static int getDisplayType() {
+ return displayType;
+ }
+
+ public boolean hasSelectedChildren() {
+ return false;
+ }
+}
--- /dev/null
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions, and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. Redistributions must acknowledge that this software was
+ * originally developed by the UCSF Computer Graphics Laboratory
+ * under support by the NIH National Center for Research Resources,
+ * grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package ext.edu.ucsf.rbvi.strucviz2;
+
+import java.lang.String;
+import java.util.List;
+
+/**
+ * This interface provides a common set of methods that are implemented by the ChimeraModel,
+ * ChimeraChain, and ChimeraResidue classes.
+ *
+ * @author scooter
+ *
+ */
+
+public interface ChimeraStructuralObject {
+
+ /**
+ * Return the Chimera selection specification for this object
+ *
+ * @return a String representing a Chimera atom-spec
+ */
+ public String toSpec();
+
+ /**
+ * Return a String representation for this object
+ *
+ * @return a String representing the object name
+ */
+ public String toString();
+
+ /**
+ * Return the userData for this object
+ *
+ * @return an Object representing the userData (usually TreePath)
+ */
+ public Object getUserData();
+
+ /**
+ * Set the userData for this object
+ *
+ * @param userData
+ * the Object representing the userData (usually TreePath)
+ */
+ public void setUserData(Object userData);
+
+ /**
+ * Return the ChimeraModel for this object
+ *
+ * @return the ChimeraModel this object is part of
+ */
+ public ChimeraModel getChimeraModel();
+
+ /**
+ * Set the "selected" state of this object
+ *
+ * @param selected
+ * boolean value as to whether this object is selected
+ */
+ public void setSelected(boolean selected);
+
+ /**
+ * Get the "selected" state of this object
+ *
+ * @return the selected state of this object
+ */
+ public boolean isSelected();
+
+ /**
+ * Get the selected state of this object and its children.
+ *
+ * @return true if any child is selected.
+ */
+ public boolean hasSelectedChildren();
+
+ /**
+ * Get the children of this object (if any)
+ *
+ * @return the children of the object
+ */
+ public List<ChimeraStructuralObject> getChildren();
+}
--- /dev/null
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions, and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. Redistributions must acknowledge that this software was
+ * originally developed by the UCSF Computer Graphics Laboratory
+ * under support by the NIH National Center for Research Resources,
+ * grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package ext.edu.ucsf.rbvi.strucviz2;
+
+// System imports
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.swing.JTree;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+// Cytoscape imports
+// StructureViz imports
+
+/**
+ * The ChimeraTreeModel class provides the underlying model
+ * for the navigation tree in the ModelNavigatorDialog.
+ *
+ * @author scooter
+ * @see ModelNavigatorDialog
+ */
+public class ChimeraTreeModel extends DefaultTreeModel {
+ private ChimeraManager chimeraManager;
+ private JTree navigationTree;
+ private int residueDisplay = ChimeraResidue.THREE_LETTER;
+
+ /**
+ * Constructor for the ChimeraTreeModel.
+ *
+ * @param chimeraObject the Chimera object that this tree represents
+ * @param tree the JTree used to display the object
+ * @see Chimera
+ */
+ public ChimeraTreeModel (ChimeraManager chimeraManager, JTree tree) {
+ super(new DefaultMutableTreeNode());
+ this.chimeraManager = chimeraManager;
+ this.navigationTree = tree;
+ DefaultMutableTreeNode rootNode = buildTree();
+ this.setRoot(rootNode);
+ }
+
+ /**
+ * Set the display type for the residues. The display type
+ * must be one of:
+ *
+ * ChimeraResidue.THREE_LETTER
+ * ChimeraResidue.SINGLE_LETTER
+ * ChimeraResidue.FULL_NAME
+ *
+ * @param newDisplay the display type
+ * @see ChimeraResidue
+ */
+ public void setResidueDisplay(int newDisplay) {
+ this.residueDisplay = newDisplay;
+ }
+
+ /**
+ * This method is called to rebuild the tree model "from scratch"
+ */
+ public void reload() {
+ // First, rebuild the tree with the new data
+ DefaultMutableTreeNode rootNode = buildTree();
+ this.setRoot(rootNode);
+
+ // Now let the superclass do all of the work
+ super.reload();
+ }
+
+ /**
+ * Rebuild an existing tree
+ */
+ public void rebuildTree() {
+ DefaultMutableTreeNode rootNode = buildTree();
+ DefaultTreeModel model = (DefaultTreeModel)navigationTree.getModel();
+ model.setRoot(rootNode);
+ model.reload();
+ }
+
+ /**
+ * Build the tree from the current Chimera data
+ *
+ * @return DefaultMutableTreeNode that represents the currently loaded Chimera models
+ */
+ private DefaultMutableTreeNode buildTree() {
+ int modelCount = chimeraManager.getChimeraModelsCount(true);
+ DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(modelCount+" Open Chimera Models");
+ TreePath rootPath = new TreePath(rootNode);
+
+ TreePath path = null;
+ DefaultMutableTreeNode model = null;
+
+ // Add all of the Chimera models
+ for (ChimeraModel chimeraModel: chimeraManager.getChimeraModels()) {
+ model = new DefaultMutableTreeNode(chimeraModel);
+ path = rootPath.pathByAddingChild(model);
+ chimeraModel.setUserData(path);
+ addChainNodes(chimeraModel, model, path);
+ rootNode.add(model);
+ }
+ return rootNode;
+ }
+
+ /**
+ * add chains to a tree model
+ *
+ * @param chimeraModel the ChimeraModel to get the chains from
+ * @param treeModel the tree model to add the chains to
+ * @param treePath the tree path where the chains should be added
+ */
+ private void addChainNodes(ChimeraModel chimeraModel,
+ DefaultMutableTreeNode treeModel,
+ TreePath treePath) {
+ DefaultMutableTreeNode chain = null;
+ TreePath chainPath = null;
+
+ // Get the list of chains
+ Collection<ChimeraChain> chainList = chimeraModel.getChains();
+
+ if (chainList.size() == 0) {
+ // No chains! Just add the residues
+ addResidues(chimeraModel.getResidues(), treeModel, treePath);
+ return;
+ }
+
+ // Iterate over the chains and add the chain and all of
+ // the chain's residues
+ for (ChimeraChain chimeraChain: chainList) {
+ chain = new DefaultMutableTreeNode(chimeraChain);
+ chainPath = treePath.pathByAddingChild(chain);
+ chimeraChain.setUserData(chainPath);
+ addResidues(chimeraChain.getResidues(), chain, chainPath);
+ treeModel.add(chain);
+ }
+ }
+
+ /**
+ * add residues to a tree model
+ *
+ * @param residues the residues to add
+ * @param treeModel the tree model to add the residues to
+ * @param treePath the tree path where the residues should be added
+ */
+ private void addResidues(Collection<ChimeraResidue> residues,
+ DefaultMutableTreeNode treeModel,
+ TreePath treePath) {
+ DefaultMutableTreeNode residue = null;
+ TreePath residuePath = null;
+
+ List<ChimeraResidue> sortedResidues = new ArrayList<ChimeraResidue>(residues);
+ Collections.sort(sortedResidues);
+
+ // Iterate over all residues & add them to the tree
+ for (ChimeraResidue res: sortedResidues) {
+ res.setDisplayType(this.residueDisplay);
+ residue = new DefaultMutableTreeNode(res);
+ residuePath = treePath.pathByAddingChild(residue);
+ res.setUserData(residuePath);
+ treeModel.add(residue);
+ }
+ }
+}
--- /dev/null
+package ext.edu.ucsf.rbvi.strucviz2;
+
+import jalview.bin.Cache;
+import jalview.gui.Preferences;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This object maintains the relationship between Chimera objects and Cytoscape
+ * objects.
+ */
+
+public class StructureManager
+{
+ static final String[] defaultStructureKeys =
+ { "Structure", "pdb", "pdbFileName", "PDB ID", "structure",
+ "biopax.xref.PDB", "pdb_ids", "ModelName", "ModelNumber" };
+
+ static final String[] defaultChemStructKeys =
+ { "Smiles", "smiles", "SMILES" };
+
+ static final String[] defaultResidueKeys =
+ { "FunctionalResidues", "ResidueList", "Residues" };
+
+ public enum ModelType
+ {
+ PDB_MODEL, MODBASE_MODEL, SMILES
+ };
+
+ public static Properties pathProps;
+
+ private String chimeraCommandAttr = "ChimeraCommand";
+
+ private String chimeraOutputTable = "ChimeraTable";
+
+ private String chimeraOutputAttr = "ChimeraOutput";
+
+ private boolean haveGUI = true;
+
+ private ChimeraManager chimeraManager = null;
+
+ static private List<ChimeraStructuralObject> chimSelectionList;
+
+ private boolean ignoreCySelection = false;
+
+ private File configurationDirectory = null;
+
+ private static Logger logger = LoggerFactory
+ .getLogger(ext.edu.ucsf.rbvi.strucviz2.StructureManager.class);
+
+ public StructureManager(boolean haveGUI)
+ {
+ this.haveGUI = haveGUI;
+ // Create the Chimera interface
+ chimeraManager = new ChimeraManager(this);
+ chimSelectionList = new ArrayList<ChimeraStructuralObject>();
+ pathProps = new Properties();
+ }
+
+ public ChimeraManager getChimeraManager()
+ {
+ return chimeraManager;
+ }
+
+ public boolean openStructures(Collection<List<String>> chimObjNames,
+ ModelType type)
+ {
+ // new models
+ Map<String, List<ChimeraModel>> newModels = new HashMap<String, List<ChimeraModel>>();
+ if (chimObjNames.size() > 0)
+ {
+ List<String> names = chimObjNames.iterator().next();
+ if (names == null)
+ {
+ return false;
+ }
+ for (String chimObjName : names)
+ {
+ // get or open the corresponding models if they already exist
+ List<ChimeraModel> currentModels = chimeraManager.getChimeraModels(
+ chimObjName, type);
+ if (currentModels.size() == 0)
+ {
+ // open and return models
+ currentModels = chimeraManager.openModel(chimObjName, type);
+ if (currentModels == null)
+ {
+ // failed to open model, continue with next
+ continue;
+ }
+ // if (type == ModelType.SMILES) {
+ // newModels.put("smiles:" + chimObjName, currentModels);
+ // } else {
+ newModels.put(chimObjName, currentModels);
+ // }
+ // for each model
+ for (ChimeraModel currentModel : currentModels)
+ {
+ // if not RIN then associate new model with the Cytoscape
+ // node
+ // if (!currentChimMap.containsKey(currentModel)) {
+ // currentChimMap.put(currentModel, new HashSet<CyIdentifiable>());
+ // }
+ }
+ }
+ }
+ }
+ else
+ {
+ return false;
+ }
+ // update dialog
+ // if (mnDialog != null) {
+ // mnDialog.modelChanged();
+ // }
+ // aTask.associate();
+ return true;
+
+ }
+
+ // TODO: [Release] Handle case where one network is associated with two models
+ // that are opened
+ // at the same time
+ /*
+ * public boolean openStructures(CyNetwork network, Map<CyIdentifiable,
+ * List<String>> chimObjNames, ModelType type) { if
+ * (!chimeraManager.isChimeraLaunched() &&
+ * !chimeraManager.launchChimera(getChimeraPaths(network))) {
+ * logger.error("Chimera could not be launched."); return false; } else if
+ * (chimObjNames.size() == 0) { return false; } else if (network == null) {
+ * return openStructures(chimObjNames.values(), type); }
+ *
+ * // potential rins Set<CyNetwork> potentialRINs = new HashSet<CyNetwork>();
+ * // attributes List<String> attrsFound = new ArrayList<String>();
+ * attrsFound.
+ * addAll(CytoUtils.getMatchingAttributes(network.getDefaultNodeTable(),
+ * getCurrentStructureKeys(network)));
+ * attrsFound.addAll(CytoUtils.getMatchingAttributes
+ * (network.getDefaultNodeTable(), getCurrentChemStructKeys(network))); // new
+ * models Map<String, List<ChimeraModel>> newModels = new HashMap<String,
+ * List<ChimeraModel>>(); // for each node that has an associated structure
+ * for (CyIdentifiable cyObj : chimObjNames.keySet()) { // get possible res
+ * specs List<String> specsFound = null; if (cyObj instanceof CyNode) {
+ * specsFound = ChimUtils.getResidueKeys(network.getDefaultNodeTable(), cyObj,
+ * attrsFound); } // save node to track its selection and mapping to chimera
+ * objects if (!currentCyMap.containsKey(cyObj)) { currentCyMap.put(cyObj, new
+ * HashSet<ChimeraStructuralObject>()); } // save node to network mapping to
+ * keep track of selection events if (!networkMap.containsKey(cyObj)) {
+ * networkMap.put(cyObj, new HashSet<CyNetwork>()); }
+ * networkMap.get(cyObj).add(network); // for each structure that has to be
+ * opened for (String chimObjName : chimObjNames.get(cyObj)) { // get or open
+ * the corresponding models if they already exist List<ChimeraModel>
+ * currentModels = chimeraManager.getChimeraModels(chimObjName, type); if
+ * (currentModels.size() == 0) { // open and return models currentModels =
+ * chimeraManager.openModel(chimObjName, type); if (currentModels == null) {
+ * // failed to open model, continue with next continue; } // if (type ==
+ * ModelType.SMILES) { // newModels.put("smiles:" + chimObjName,
+ * currentModels); // } else { newModels.put(chimObjName, currentModels); // }
+ * // for each model for (ChimeraModel currentModel : currentModels) { //
+ * check if it is a RIN boolean foundRIN = false; if
+ * (currentModel.getModelType().equals(ModelType.PDB_MODEL)) { // go through
+ * all node annotations and check if any of them is a residue // or a chain if
+ * (cyObj instanceof CyNode && network.containsNode((CyNode) cyObj) &&
+ * specsFound != null && specsFound.size() > 0) { for (String resSpec :
+ * specsFound) { ChimeraStructuralObject res =
+ * ChimUtils.fromAttribute(resSpec, chimeraManager); if (res != null && (res
+ * instanceof ChimeraResidue || res instanceof ChimeraChain)) { // if so,
+ * assume it might be a RIN potentialRINs.add(network); foundRIN = true;
+ * break; } } } else if (cyObj instanceof CyNetwork) { // if cyObj is a
+ * network, check for residue/chain annotations in an // arbitrary node
+ * CyNetwork rinNet = (CyNetwork) cyObj; if (rinNet.getNodeList().size() > 0)
+ * { specsFound = ChimUtils.getResidueKeys( rinNet.getDefaultNodeTable(),
+ * rinNet.getNodeList().get(0), attrsFound); for (String resSpec : specsFound)
+ * { ChimeraStructuralObject res = ChimUtils.fromAttribute( resSpec,
+ * chimeraManager); if (res != null && (res instanceof ChimeraResidue || res
+ * instanceof ChimeraChain)) { potentialRINs.add(network); foundRIN = true;
+ * break; } } } } } if (foundRIN) { continue; } // if not RIN then associate
+ * new model with the Cytoscape // node if
+ * (!currentChimMap.containsKey(currentModel)) {
+ * currentChimMap.put(currentModel, new HashSet<CyIdentifiable>()); } String
+ * cyObjName = network.getRow(cyObj).get(CyNetwork.NAME, String.class); if
+ * (cyObjName != null && cyObjName.endsWith(currentModel.getModelName())) { //
+ * it is a modbase model, associate directly
+ * currentCyMap.get(cyObj).add(currentModel);
+ * currentChimMap.get(currentModel).add(cyObj);
+ * currentModel.addCyObject(cyObj, network); } else if (specsFound != null &&
+ * specsFound.size() > 0) { for (String resSpec : specsFound) {
+ * ChimeraStructuralObject specModel = ChimUtils.fromAttribute( resSpec,
+ * chimeraManager); if (specModel == null &&
+ * resSpec.equals(currentModel.getModelName())) { specModel =
+ * chimeraManager.getChimeraModel( currentModel.getModelNumber(),
+ * currentModel.getSubModelNumber()); } if (specModel != null &&
+ * currentModel.toSpec().equals(specModel.toSpec()) ||
+ * currentModel.getModelName().equals("smiles:" + resSpec)) {
+ * currentCyMap.get(cyObj).add(currentModel);
+ * currentChimMap.get(currentModel).add(cyObj);
+ * currentModel.addCyObject(cyObj, network);
+ * currentModel.setFuncResidues(ChimUtils.parseFuncRes(
+ * getResidueList(network, cyObj), chimObjName)); } } } } } } } // networks
+ * that contain nodes associated to newly opened models // this will usually
+ * be of length 1 for (CyNetwork net : potentialRINs) {
+ * addStructureNetwork(net); } // update dialog if (mnDialog != null) {
+ * mnDialog.modelChanged(); } aTask.associate(); return true; }
+ */
+ public void closeStructures(Set<String> chimObjNames)
+ {
+ // for each cytoscape object and chimera model pair
+ for (String modelName : chimObjNames)
+ {
+ List<ChimeraModel> models = chimeraManager
+ .getChimeraModels(modelName);
+ for (ChimeraModel model : models)
+ {
+ closeModel(model);
+ }
+ }
+ // if (mnDialog != null) {
+ // mnDialog.modelChanged();
+ // }
+ }
+
+ // TODO: [Optional] Can we make a screenshot of a single molecule?
+ public File saveChimeraImage()
+ {
+ File tmpFile = null;
+ try
+ {
+ // Create the temp file name
+ tmpFile = File.createTempFile("structureViz", ".png");
+ chimeraManager.sendChimeraCommand("set bgTransparency", false);
+ chimeraManager.sendChimeraCommand(
+ "copy file " + tmpFile.getAbsolutePath() + " png", true);
+ chimeraManager.sendChimeraCommand("unset bgTransparency", false);
+ } catch (IOException ioe)
+ {
+ // Log error
+ logger.error("Error writing image", ioe);
+ }
+ return tmpFile;
+ }
+
+ public void closeModel(ChimeraModel model)
+ {
+ // close model in Chimera
+ chimeraManager.closeModel(model);
+ // remove all associations
+ // if (currentChimMap.containsKey(model)) {
+ // for (CyIdentifiable cyObj : model.getCyObjects().keySet()) {
+ // if (cyObj == null) {
+ // continue;
+ // } else if (currentCyMap.containsKey(cyObj)) {
+ // currentCyMap.get(cyObj).remove(model);
+ // } else if (cyObj instanceof CyNetwork) {
+ // for (ChimeraResidue residue : model.getResidues()) {
+ // if (currentChimMap.containsKey(residue)) {
+ // for (CyIdentifiable cyObjRes : currentChimMap.get(residue)) {
+ // if (currentCyMap.containsKey(cyObjRes)) {
+ // currentCyMap.get(cyObjRes).remove(residue);
+ // }
+ // }
+ // currentChimMap.remove(residue);
+ // }
+ // }
+ // }
+ // }
+ // currentChimMap.remove(model);
+ // }
+ }
+
+ // public void addStructureNetwork(CyNetwork rin) {
+ // if (rin == null) {
+ // return;
+ // }
+ // ChimeraModel model = null;
+ // // the network is not added to the model in the currentChimMap
+ // List<String> attrsFound =
+ // CytoUtils.getMatchingAttributes(rin.getDefaultNodeTable(),
+ // getCurrentStructureKeys(rin));
+ // for (CyNode node : rin.getNodeList()) {
+ // if (!networkMap.containsKey(node)) {
+ // networkMap.put(node, new HashSet<CyNetwork>());
+ // }
+ // networkMap.get(node).add(rin);
+ // List<String> specsFound =
+ // ChimUtils.getResidueKeys(rin.getDefaultNodeTable(), node,
+ // attrsFound);
+ // for (String residueSpec : specsFound) {
+ // // if (!rin.getRow(node).isSet(ChimUtils.RESIDUE_ATTR)) {
+ // // continue;
+ // // }
+ // // String residueSpec = rin.getRow(node).get(ChimUtils.RESIDUE_ATTR,
+ // String.class);
+ // ChimeraStructuralObject chimObj = ChimUtils.fromAttribute(residueSpec,
+ // chimeraManager);
+ // // chimObj.getChimeraModel().addCyObject(node, rin);
+ // if (chimObj == null || chimObj instanceof ChimeraModel) {
+ // continue;
+ // }
+ // model = chimObj.getChimeraModel();
+ // if (!currentCyMap.containsKey(node)) {
+ // currentCyMap.put(node, new HashSet<ChimeraStructuralObject>());
+ // }
+ // currentCyMap.get(node).add(chimObj);
+ // if (!currentChimMap.containsKey(chimObj)) {
+ // currentChimMap.put(chimObj, new HashSet<CyIdentifiable>());
+ // }
+ // currentChimMap.get(chimObj).add(node);
+ // }
+ // }
+ // if (model != null) {
+ // model.addCyObject(rin, rin);
+ // if (!currentCyMap.containsKey(rin)) {
+ // currentCyMap.put(rin, new HashSet<ChimeraStructuralObject>());
+ // }
+ // currentCyMap.get(rin).add(model);
+ // }
+ // }
+
+ public void exitChimera()
+ {
+ // // exit chimera, invokes clearOnExitChimera
+ // if (mnDialog != null) {
+ // mnDialog.setVisible(false);
+ // mnDialog = null;
+ // }
+ // if (alDialog != null) {
+ // alDialog.setVisible(false);
+ // }
+ chimeraManager.exitChimera();
+ }
+
+ // invoked by ChimeraManager whenever Chimera exits
+ public void clearOnChimeraExit()
+ {
+ // // clear structures
+ // currentCyMap.clear();
+ // currentChimMap.clear();
+ // networkMap.clear();
+ chimSelectionList.clear();
+ // if (chimTable != null) {
+ // ((CyTableManager)
+ // getService(CyTableManager.class)).deleteTable(chimTable.getSUID());
+ // }
+ // if (mnDialog != null) {
+ // if (mnDialog.isVisible()) {
+ // mnDialog.lostChimera();
+ // mnDialog.setVisible(false);
+ // }
+ // mnDialog = null;
+ // if (alDialog != null) {
+ // alDialog.setVisible(false);
+ // }
+ // }
+ }
+
+ // We need to do this in two passes since some parts of a structure might be
+ // selected and some might not. Our selection model (unfortunately) only
+ // tells
+ // us that something has changed, not what...
+ public void updateCytoscapeSelection()
+ {
+ // List<ChimeraStructuralObject> selectedChimObj
+ ignoreCySelection = true;
+ // System.out.println("update Cytoscape selection");
+ // find all possibly selected Cytoscape objects and unselect them
+ // Set<CyNetwork> networks = new HashSet<CyNetwork>();
+ // for (CyIdentifiable currentCyObj : currentCyMap.keySet()) {
+ // if (!networkMap.containsKey(currentCyObj)) {
+ // continue;
+ // }
+ // Set<CyNetwork> currentCyNetworks = networkMap.get(currentCyObj);
+ // if (currentCyNetworks == null || currentCyNetworks.size() == 0) {
+ //
+ // continue;
+ // }
+ // for (CyNetwork network : currentCyNetworks) {
+ // if ((currentCyObj instanceof CyNode && network.containsNode((CyNode)
+ // currentCyObj))
+ // || (currentCyObj instanceof CyEdge && network
+ // .containsEdge((CyEdge) currentCyObj))) {
+ // network.getRow(currentCyObj).set(CyNetwork.SELECTED, false);
+ // networks.add(network);
+ // }
+ // }
+ // }
+ //
+ // // select only those associated with selected Chimera objects
+ // Set<CyIdentifiable> currentCyObjs = new HashSet<CyIdentifiable>();
+ // for (ChimeraStructuralObject chimObj : chimSelectionList) {
+ // ChimeraModel currentSelModel = chimObj.getChimeraModel();
+ // if (currentChimMap.containsKey(currentSelModel)) {
+ // currentCyObjs.addAll(currentChimMap.get(currentSelModel));
+ // }
+ // if (currentChimMap.containsKey(chimObj)) {
+ // currentCyObjs.addAll(currentChimMap.get(chimObj));
+ // }
+ // // System.out.println(chimObj.toSpec() + ": " +
+ // // currentCyObjs.size());
+ // }
+ // for (CyIdentifiable cyObj : currentCyObjs) {
+ // // System.out.println(cyObj.toString());
+ // if (cyObj == null || !networkMap.containsKey(cyObj)) {
+ // continue;
+ // }
+ // Set<CyNetwork> currentCyNetworks = networkMap.get(cyObj);
+ // if (currentCyNetworks == null || currentCyNetworks.size() == 0) {
+ // continue;
+ // }
+ // for (CyNetwork network : currentCyNetworks) {
+ // if ((cyObj instanceof CyNode && network.containsNode((CyNode) cyObj))
+ // || (cyObj instanceof CyEdge && network.containsEdge((CyEdge) cyObj))) {
+ // network.getRow(cyObj).set(CyNetwork.SELECTED, true);
+ // networks.add(network);
+ // }
+ // }
+ // }
+ //
+ // CyNetworkViewManager cyNetViewManager = (CyNetworkViewManager)
+ // getService(CyNetworkViewManager.class);
+ // // Update network views
+ // for (CyNetwork network : networks) {
+ // Collection<CyNetworkView> views =
+ // cyNetViewManager.getNetworkViews(network);
+ // for (CyNetworkView view : views) {
+ // view.updateView();
+ // }
+ // }
+ ignoreCySelection = false;
+ }
+
+ public void cytoscapeSelectionChanged(Map<Long, Boolean> selectedRows)
+ {
+ // if (ignoreCySelection || currentCyMap.size() == 0) {
+ // return;
+ // }
+ // // clearSelectionList();
+ // // System.out.println("cytoscape selection changed");
+ // // iterate over all cy objects with associated models
+ // for (CyIdentifiable cyObj : currentCyMap.keySet()) {
+ // if (cyObj instanceof CyNetwork ||
+ // !selectedRows.containsKey(cyObj.getSUID())) {
+ // continue;
+ // }
+ // for (ChimeraStructuralObject chimObj : currentCyMap.get(cyObj)) {
+ // if (selectedRows.get(cyObj.getSUID())) {
+ // addChimSelection(chimObj);
+ // if (chimObj instanceof ChimeraResidue) {
+ // if (chimObj.getChimeraModel().isSelected()) {
+ // removeChimSelection(chimObj.getChimeraModel());
+ // } else if (chimObj.getChimeraModel()
+ // .getChain(((ChimeraResidue) chimObj).getChainId()).isSelected()) {
+ // removeChimSelection(chimObj.getChimeraModel().getChain(
+ // ((ChimeraResidue) chimObj).getChainId()));
+ // }
+ // }
+ // } else {
+ // removeChimSelection(chimObj);
+ // if (chimObj.hasSelectedChildren() && chimObj instanceof ChimeraModel) {
+ // for (ChimeraResidue residue : ((ChimeraModel) chimObj)
+ // .getSelectedResidues()) {
+ // removeChimSelection(residue);
+ // }
+ // }
+ // }
+ // }
+ // }
+ // System.out.println("selection list: " + getChimSelectionCount());
+ updateChimeraSelection();
+ selectionChanged();
+ }
+
+ // Save models in a HashMap/Set for better performance?
+ public void updateChimeraSelection()
+ {
+ // System.out.println("update Chimera selection");
+ String selSpec = "";
+ for (int i = 0; i < chimSelectionList.size(); i++)
+ {
+ ChimeraStructuralObject nodeInfo = chimSelectionList.get(i);
+ // we do not care about the model anymore
+ selSpec = selSpec.concat(nodeInfo.toSpec());
+ if (i < chimSelectionList.size() - 1)
+ {
+ selSpec.concat("|");
+ }
+ }
+ if (selSpec.length() > 0)
+ {
+ chimeraManager.select("sel " + selSpec);
+ }
+ else
+ {
+ chimeraManager.select("~sel");
+ }
+ }
+
+ /**
+ * This is called by the selectionListener to let us know that the user has
+ * changed their selection in Chimera. We need to go back to Chimera to find
+ * out what is currently selected and update our list.
+ */
+ public void chimeraSelectionChanged()
+ {
+ // System.out.println("Chimera selection changed");
+ clearSelectionList();
+ // Execute the command to get the list of models with selections
+ Map<Integer, ChimeraModel> selectedModelsMap = chimeraManager
+ .getSelectedModels();
+ // Now get the residue-level data
+ chimeraManager.getSelectedResidues(selectedModelsMap);
+ // Get the selected objects
+ try
+ {
+ for (ChimeraModel selectedModel : selectedModelsMap.values())
+ {
+ int modelNumber = selectedModel.getModelNumber();
+ int subModelNumber = selectedModel.getSubModelNumber();
+ // Get the corresponding "real" model
+ if (chimeraManager.hasChimeraModel(modelNumber, subModelNumber))
+ {
+ ChimeraModel dataModel = chimeraManager.getChimeraModel(
+ modelNumber, subModelNumber);
+ if (dataModel.getResidueCount() == selectedModel
+ .getResidueCount()
+ || dataModel.getModelType() == StructureManager.ModelType.SMILES)
+ {
+ // Select the entire model
+ addChimSelection(dataModel);
+ // dataModel.setSelected(true);
+ }
+ else
+ {
+ for (ChimeraChain selectedChain : selectedModel.getChains())
+ {
+ ChimeraChain dataChain = dataModel.getChain(selectedChain
+ .getChainId());
+ if (selectedChain.getResidueCount() == dataChain
+ .getResidueCount())
+ {
+ addChimSelection(dataChain);
+ // dataChain.setSelected(true);
+ }
+ // else {
+ // Need to select individual residues
+ for (ChimeraResidue res : selectedChain.getResidues())
+ {
+ String residueIndex = res.getIndex();
+ ChimeraResidue residue = dataChain.getResidue(residueIndex);
+ if (residue == null)
+ {
+ continue;
+ }
+ addChimSelection(residue);
+ // residue.setSelected(true);
+ } // resIter.hasNext
+ // }
+ } // chainIter.hasNext()
+ }
+ }
+ } // modelIter.hasNext()
+ } catch (Exception ex)
+ {
+ logger.warn("Could not update selection", ex);
+ }
+ // System.out.println("selection list: " + getChimSelectionCount());
+ // Finally, update the navigator panel
+ selectionChanged();
+ updateCytoscapeSelection();
+ }
+
+ public void selectFunctResidues(Collection<ChimeraModel> models)
+ {
+ clearSelectionList();
+ for (ChimeraModel model : models)
+ {
+ for (ChimeraResidue residue : model.getFuncResidues())
+ {
+ addChimSelection(residue);
+ }
+ }
+ updateChimeraSelection();
+ updateCytoscapeSelection();
+ selectionChanged();
+ }
+
+ // public void selectFunctResidues(CyNode node, CyNetwork network) {
+ // clearSelectionList();
+ // if (currentCyMap.containsKey(node)) {
+ // Set<ChimeraStructuralObject> chimObjects = currentCyMap.get(node);
+ // for (ChimeraStructuralObject obj : chimObjects) {
+ // if (obj instanceof ChimeraModel) {
+ // ChimeraModel model = (ChimeraModel) obj;
+ // for (ChimeraResidue residue : model.getFuncResidues()) {
+ // addChimSelection(residue);
+ // }
+ // }
+ // }
+ // }
+ // updateChimeraSelection();
+ // updateCytoscapeSelection();
+ // selectionChanged();
+ // }
+
+ public List<ChimeraStructuralObject> getChimSelectionList()
+ {
+ return chimSelectionList;
+ }
+
+ public int getChimSelectionCount()
+ {
+ return chimSelectionList.size();
+ }
+
+ /**
+ * Add a selection to the selection list. This is called primarily by the
+ * Model Navigator Dialog to keep the selections in sync
+ *
+ * @param selectionToAdd
+ * the selection to add to our list
+ */
+ public void addChimSelection(ChimeraStructuralObject selectionToAdd)
+ {
+ if (selectionToAdd != null
+ && !chimSelectionList.contains(selectionToAdd))
+ {
+ chimSelectionList.add(selectionToAdd);
+ selectionToAdd.setSelected(true);
+ }
+ }
+
+ /**
+ * Remove a selection from the selection list. This is called primarily by the
+ * Model Navigator Dialog to keep the selections in sync
+ *
+ * @param selectionToRemove
+ * the selection to remove from our list
+ */
+ public void removeChimSelection(ChimeraStructuralObject selectionToRemove)
+ {
+ if (selectionToRemove != null
+ && chimSelectionList.contains(selectionToRemove))
+ {
+ chimSelectionList.remove(selectionToRemove);
+ selectionToRemove.setSelected(false);
+ }
+ }
+
+ /**
+ * Clear the list of selected objects
+ */
+ public void clearSelectionList()
+ {
+ for (ChimeraStructuralObject cso : chimSelectionList)
+ {
+ if (cso != null)
+ {
+ cso.setSelected(false);
+ }
+ }
+ chimSelectionList.clear();
+ }
+
+ /**
+ * Associate a new network with the corresponding Chimera objects.
+ *
+ * @param network
+ */
+
+ /**
+ * Dump and refresh all of our model/chain/residue info
+ */
+ public void updateModels()
+ {
+ // Stop all of our listeners while we try to handle this
+ chimeraManager.stopListening();
+
+ // Get all of the open models
+ List<ChimeraModel> newModelList = chimeraManager.getModelList();
+
+ // Match them up -- assume that the model #'s haven't changed
+ for (ChimeraModel newModel : newModelList)
+ {
+ // Get the color (for our navigator)
+ newModel.setModelColor(chimeraManager.getModelColor(newModel));
+
+ // Get our model info
+ int modelNumber = newModel.getModelNumber();
+ int subModelNumber = newModel.getSubModelNumber();
+
+ // If we already know about this model number, get the Structure,
+ // which tells us about the associated CyNode
+ if (chimeraManager.hasChimeraModel(modelNumber, subModelNumber))
+ {
+ ChimeraModel oldModel = chimeraManager.getChimeraModel(modelNumber,
+ subModelNumber);
+ chimeraManager.removeChimeraModel(modelNumber, subModelNumber);
+ newModel.setModelType(oldModel.getModelType());
+ if (oldModel.getModelType() == ModelType.SMILES)
+ {
+ newModel.setModelName(oldModel.getModelName());
+ }
+ // re-assign associations to cytoscape objects
+ // Map<CyIdentifiable, CyNetwork> oldModelCyObjs =
+ // oldModel.getCyObjects();
+ // for (CyIdentifiable cyObj : oldModelCyObjs.keySet()) {
+ // // add cy objects to the new model
+ // newModel.addCyObject(cyObj, oldModelCyObjs.get(cyObj));
+ // if (currentCyMap.containsKey(cyObj)) {
+ // currentCyMap.get(cyObj).add(newModel);
+ // if (currentCyMap.get(cyObj).contains(oldModel)) {
+ // currentCyMap.get(cyObj).remove(oldModel);
+ // }
+ // }
+ // }
+ // // add new model to the chimera objects map and remove old model
+ // if (currentChimMap.containsKey(oldModel)) {
+ // currentChimMap.put(newModel, currentChimMap.get(oldModel));
+ // currentChimMap.remove(oldModel);
+ // }
+ }
+ // add new model to ChimeraManager
+ chimeraManager.addChimeraModel(modelNumber, subModelNumber, newModel);
+
+ // Get the residue information
+ if (newModel.getModelType() != ModelType.SMILES)
+ {
+ chimeraManager.addResidues(newModel);
+ }
+ // for (CyIdentifiable cyObj : newModel.getCyObjects().keySet()) {
+ // if (cyObj != null && cyObj instanceof CyNetwork) {
+ // addStructureNetwork((CyNetwork) cyObj);
+ // } else if (cyObj != null && cyObj instanceof CyNode) {
+ // newModel.setFuncResidues(ChimUtils.parseFuncRes(
+ // getResidueList(newModel.getCyObjects().get(cyObj), cyObj),
+ // newModel.getModelName()));
+ // }
+ // }
+ }
+
+ // associate all models with any node or network
+ // aTask.associate();
+
+ // Restart all of our listeners
+ chimeraManager.startListening();
+ // Done
+ }
+
+ public void launchModelNavigatorDialog()
+ {
+ // TODO: [Optional] Use haveGUI flag
+ // if (!haveGUI) {
+ // return;
+ // }
+ // if (mnDialog == null) {
+ // CySwingApplication cyApplication = (CySwingApplication)
+ // getService(CySwingApplication.class);
+ // mnDialog = new ModelNavigatorDialog(cyApplication.getJFrame(), this);
+ // mnDialog.pack();
+ // }
+ // mnDialog.setVisible(true);
+ }
+
+ public boolean isMNDialogOpen()
+ {
+ // if (mnDialog != null && mnDialog.isVisible()) {
+ // return true;
+ // }
+ return false;
+ }
+
+ /**
+ * Invoked by the listener thread.
+ */
+ public void modelChanged()
+ {
+ // if (mnDialog != null) {
+ // mnDialog.modelChanged();
+ // }
+ }
+
+ /**
+ * Inform our interface that the selection has changed
+ */
+ public void selectionChanged()
+ {
+ // if (mnDialog != null) {
+ // // System.out.println("update dialog selection");
+ // mnDialog.updateSelection(new
+ // ArrayList<ChimeraStructuralObject>(chimSelectionList));
+ // }
+ }
+
+ public void launchAlignDialog(boolean useChains)
+ {
+ // TODO: [Optional] Use haveGUI flag
+ // Sometimes it does not appear in Windows
+ // if (!haveGUI) {
+ // return;
+ // }
+ // if (alDialog != null) {
+ // alDialog.setVisible(false);
+ // alDialog.dispose();
+ // }
+ // System.out.println("launch align dialog");
+ List<ChimeraStructuralObject> chimObjectList = new ArrayList<ChimeraStructuralObject>();
+ for (ChimeraModel model : chimeraManager.getChimeraModels())
+ {
+ if (useChains)
+ {
+ for (ChimeraChain chain : model.getChains())
+ {
+ chimObjectList.add(chain);
+ }
+ }
+ else
+ {
+ chimObjectList.add(model);
+ }
+ }
+ // Bring up the dialog
+ // CySwingApplication cyApplication = (CySwingApplication)
+ // getService(CySwingApplication.class);
+ // alDialog = new AlignStructuresDialog(cyApplication.getJFrame(), this,
+ // chimObjectList);
+ // alDialog.pack();
+ // alDialog.setVisible(true);
+ }
+
+ public List<String> getAllStructureKeys()
+ {
+ return Arrays.asList(defaultStructureKeys);
+ }
+
+ public List<String> getAllChemStructKeys()
+ {
+ return Arrays.asList(defaultChemStructKeys);
+ }
+
+ public List<String> getAllResidueKeys()
+ {
+ return Arrays.asList(defaultResidueKeys);
+ }
+
+ public List<String> getAllChimeraResidueAttributes()
+ {
+ List<String> attributes = new ArrayList<String>();
+ // attributes.addAll(rinManager.getResAttrs());
+ attributes.addAll(chimeraManager.getAttrList());
+ return attributes;
+ }
+
+ StructureSettings defaultSettings = null;
+
+ // TODO: [Optional] Change priority of Chimera paths
+ public List<String> getChimeraPaths()
+ {
+ List<String> pathList = new ArrayList<String>();
+
+ // if no network is available and the settings have been modified by the
+ // user, check for a
+ // path to chimera
+ if (defaultSettings != null)
+ {
+ String defaultPath = defaultSettings.getChimeraPath();
+ if (defaultPath != null && !defaultPath.equals(""))
+ {
+ pathList.add(defaultPath);
+ return pathList;
+ }
+ }
+
+ /*
+ * Jalview addition: check if path set in user preferences.
+ */
+ String userPath = Cache.getDefault(Preferences.CHIMERA_PATH, null);
+ if (userPath != null)
+ {
+ pathList.add(userPath);
+ }
+
+ // Add default installation paths
+ String os = System.getProperty("os.name");
+ if (os.startsWith("Linux"))
+ {
+ pathList.add("/usr/local/chimera/bin/chimera");
+ pathList.add("/usr/local/bin/chimera");
+ pathList.add("/usr/bin/chimera");
+ }
+ else if (os.startsWith("Windows"))
+ {
+ pathList.add("\\Program Files\\Chimera\\bin\\chimera");
+ pathList.add("C:\\Program Files\\Chimera\\bin\\chimera.exe");
+ }
+ else if (os.startsWith("Mac"))
+ {
+ pathList.add("/Applications/Chimera.app/Contents/MacOS/chimera");
+ }
+ return pathList;
+ }
+
+ public void setChimeraPathProperty(String path)
+ {
+ // CytoUtils.setDefaultChimeraPath(registrar, chimeraPropertyName,
+ // chimeraPathPropertyKey,
+ // path);
+ }
+
+ public void setStructureSettings(StructureSettings structureSettings)
+ {
+ this.defaultSettings = structureSettings;
+ }
+
+ public String getCurrentChimeraPath(Object object)
+ {
+ if (defaultSettings != null)
+ {
+ return defaultSettings.getChimeraPath();
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+ // public void initChimTable() {
+ // CyTableManager manager = (CyTableManager) getService(CyTableManager.class);
+ // CyTableFactory factory = (CyTableFactory) getService(CyTableFactory.class);
+ // for (CyTable table : manager.getGlobalTables()) {
+ // if (table.getTitle().equals(chimeraOutputTable)) {
+ // manager.deleteTable(table.getSUID());
+ // }
+ // }
+ // chimTable = factory.createTable(chimeraOutputTable, chimeraCommandAttr,
+ // String.class,
+ // false, true);
+ // manager.addTable(chimTable);
+ // if (chimTable.getColumn(chimeraOutputAttr) == null) {
+ // chimTable.createListColumn(chimeraOutputAttr, String.class, false);
+ // }
+ // }
+
+ // public void addChimReply(String command, List<String> reply) {
+ // chimTable.getRow(command).set(chimeraOutputAttr, reply);
+ // }
+
+}
--- /dev/null
+package ext.edu.ucsf.rbvi.strucviz2;
+
+/**
+ * This object maintains the relationship between Chimera objects and Cytoscape objects.
+ */
+public class StructureSettings {
+
+// @Tunable(description = "Path to UCSF Chimera application", gravity = 4.0)
+ public String chimeraPath = null;
+
+ public StructureSettings(StructureManager manager) {
+
+ chimeraPath = manager.getCurrentChimeraPath(null);
+
+ // This seems a little strange, but it has to do with the order of tunable interceptor
+ // handling. We need to set these selectors in our structure manager and dynamically
+ // pull the data out as needed....
+ manager.setStructureSettings( this);
+ }
+
+
+ public String getChimeraPath() {
+ return chimeraPath;
+ }
+}
--- /dev/null
+package ext.edu.ucsf.rbvi.strucviz2.port;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
+
+/***************************************************
+ * Thread Classes *
+ **************************************************/
+
+/**
+ * Reply listener thread
+ */
+public class ListenerThreads extends Thread {
+ private InputStream readChan = null;
+ private BufferedReader lineReader = null;
+ private Process chimera = null;
+ private Map<String, List<String>> replyLog = null;
+ private Logger logger;
+ private StructureManager structureManager = null;
+
+ /**
+ * Create a new listener thread to read the responses from Chimera
+ *
+ * @param chimera
+ * a handle to the Chimera Process
+ * @param log
+ * a handle to a List to post the responses to
+ * @param chimeraObject
+ * a handle to the Chimera Object
+ */
+ public ListenerThreads(Process chimera, StructureManager structureManager) {
+ this.chimera = chimera;
+ this.structureManager = structureManager;
+ replyLog = new HashMap<String, List<String>>();
+ // Get a line-oriented reader
+ readChan = chimera.getInputStream();
+ lineReader = new BufferedReader(new InputStreamReader(readChan));
+ logger = LoggerFactory.getLogger(ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads.class);
+ }
+
+ /**
+ * Start the thread running
+ */
+ public void run() {
+ // System.out.println("ReplyLogListener running");
+ while (true) {
+ try {
+ chimeraRead();
+ } catch (IOException e) {
+ logger.warn("UCSF Chimera has exited: " + e.getMessage());
+ return;
+ }
+ }
+ }
+
+ public List<String> getResponse(String command) {
+ List<String> reply;
+ // System.out.println("getResponse: "+command);
+ // TODO do we need a maximum wait time before aborting?
+ while (!replyLog.containsKey(command)) {
+ try {
+ Thread.currentThread().sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ synchronized (replyLog) {
+ reply = replyLog.get(command);
+ // System.out.println("getResponse ("+command+") = "+reply);
+ replyLog.remove(command);
+ }
+ return reply;
+ }
+
+ public void clearResponse(String command) {
+ try {
+ Thread.currentThread().sleep(100);
+ } catch (InterruptedException e) {
+ }
+ if (replyLog.containsKey(command))
+ {
+ replyLog.remove(command);
+ }
+ return;
+ }
+
+ /**
+ * Read input from Chimera
+ *
+ * @return a List containing the replies from Chimera
+ */
+ private void chimeraRead() throws IOException {
+ if (chimera == null)
+ {
+ return;
+ }
+
+ String line = null;
+ while ((line = lineReader.readLine()) != null) {
+ // System.out.println("From Chimera-->" + line);
+ if (line.startsWith("CMD")) {
+ chimeraCommandRead(line.substring(4));
+ } else if (line.startsWith("ModelChanged: ")) {
+ (new ModelUpdater()).start();
+ } else if (line.startsWith("SelectionChanged: ")) {
+ (new SelectionUpdater()).start();
+ } else if (line.startsWith("Trajectory residue network info:")) {
+ (new NetworkUpdater(line)).start();
+ }
+ }
+ return;
+ }
+
+ private void chimeraCommandRead(String command) throws IOException {
+ // Generally -- looking for:
+ // CMD command
+ // ........
+ // END
+ // We return the text in between
+ List<String> reply = new ArrayList<String>();
+ boolean updateModels = false;
+ boolean updateSelection = false;
+ boolean importNetwork = false;
+ String line = null;
+
+ synchronized (replyLog) {
+ while ((line = lineReader.readLine()) != null) {
+ // System.out.println("From Chimera (" + command + ") -->" + line);
+ if (line.startsWith("CMD")) {
+ logger.warn("Got unexpected command from Chimera: " + line);
+
+ } else if (line.startsWith("END")) {
+ break;
+ }
+ if (line.startsWith("ModelChanged: ")) {
+ updateModels = true;
+ } else if (line.startsWith("SelectionChanged: ")) {
+ updateSelection = true;
+ } else if (line.length() == 0) {
+ continue;
+ } else if (!line.startsWith("CMD")) {
+ reply.add(line);
+ } else if (line.startsWith("Trajectory residue network info:")) {
+ importNetwork = true;
+ }
+ }
+ replyLog.put(command, reply);
+ }
+ if (updateModels)
+ {
+ (new ModelUpdater()).start();
+ }
+ if (updateSelection)
+ {
+ (new SelectionUpdater()).start();
+ }
+ if (importNetwork) {
+ (new NetworkUpdater(line)).start();
+ }
+ return;
+ }
+
+ /**
+ * Model updater thread
+ */
+ class ModelUpdater extends Thread {
+
+ public ModelUpdater() {
+ }
+
+ public void run() {
+ structureManager.updateModels();
+ structureManager.modelChanged();
+ }
+ }
+
+ /**
+ * Selection updater thread
+ */
+ class SelectionUpdater extends Thread {
+
+ public SelectionUpdater() {
+ }
+
+ public void run() {
+ try {
+ logger.info("Responding to chimera selection");
+ structureManager.chimeraSelectionChanged();
+ } catch (Exception e) {
+ logger.warn("Could not update selection", e);
+ }
+ }
+ }
+
+ /**
+ * Selection updater thread
+ */
+ class NetworkUpdater extends Thread {
+
+ private String line;
+
+ public NetworkUpdater(String line) {
+ this.line = line;
+ }
+
+ public void run() {
+ try {
+// ((TaskManager<?, ?>) structureManager.getService(TaskManager.class))
+// .execute(new ImportTrajectoryRINTaskFactory(structureManager, line)
+// .createTaskIterator());
+ } catch (Exception e) {
+ logger.warn("Could not import trajectory network", e);
+ }
+ }
+ }
+}
*/
package ext.vamsas;
+import jalview.util.MessageManager;
+
public class IRegistryServiceLocator extends org.apache.axis.client.Service
implements ext.vamsas.IRegistryService
{
{
throw new javax.xml.rpc.ServiceException(t);
}
- throw new javax.xml.rpc.ServiceException(
- "There is no stub implementation for the interface: "
- + (serviceEndpointInterface == null ? "null"
- : serviceEndpointInterface.getName()));
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.no_stub_implementation_for_interface", new String[]{(serviceEndpointInterface == null ? "null": serviceEndpointInterface.getName())}));
}
/**
}
else
{ // Unknown Port Name
- throw new javax.xml.rpc.ServiceException(
- " Cannot set Endpoint Address for Unknown Port" + portName);
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.cannot_set_endpoint_address_unknown_port", new String[]{portName}));
}
}
*/
package ext.vamsas;
+import jalview.util.MessageManager;
+
public class JpredServiceLocator extends org.apache.axis.client.Service
implements ext.vamsas.JpredService
{
{
throw new javax.xml.rpc.ServiceException(t);
}
- throw new javax.xml.rpc.ServiceException(
- "There is no stub implementation for the interface: "
- + (serviceEndpointInterface == null ? "null"
- : serviceEndpointInterface.getName()));
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.no_stub_implementation_for_interface", new String[]{(serviceEndpointInterface == null ? "null": serviceEndpointInterface.getName())}));
}
/**
}
else
{ // Unknown Port Name
- throw new javax.xml.rpc.ServiceException(
- " Cannot set Endpoint Address for Unknown Port" + portName);
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.cannot_set_endpoint_address_unknown_port", new String[]{portName}));
}
}
*/
package ext.vamsas;
+import jalview.util.MessageManager;
+
public class MuscleWSServiceLocator extends org.apache.axis.client.Service
implements ext.vamsas.MuscleWSService
{
throw new javax.xml.rpc.ServiceException(t);
}
- throw new javax.xml.rpc.ServiceException(
- "There is no stub implementation for the interface: "
- + ((serviceEndpointInterface == null) ? "null"
- : serviceEndpointInterface.getName()));
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.no_stub_implementation_for_interface", new String[]{(serviceEndpointInterface == null ? "null": serviceEndpointInterface.getName())}));
}
/**
}
else
{ // Unknown Port Name
- throw new javax.xml.rpc.ServiceException(
- " Cannot set Endpoint Address for Unknown Port" + portName);
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.cannot_set_endpoint_address_unknown_port", new String[]{portName}));
}
}
*/
package ext.vamsas;
+import jalview.util.MessageManager;
+
public class SeqSearchServiceLocator extends org.apache.axis.client.Service
implements ext.vamsas.SeqSearchServiceService
{
{
throw new javax.xml.rpc.ServiceException(t);
}
- throw new javax.xml.rpc.ServiceException(
- "There is no stub implementation for the interface: "
- + (serviceEndpointInterface == null ? "null"
- : serviceEndpointInterface.getName()));
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.no_stub_implementation_for_interface", new String[]{(serviceEndpointInterface == null ? "null": serviceEndpointInterface.getName())}));
}
/**
}
else
{ // Unknown Port Name
- throw new javax.xml.rpc.ServiceException(
- " Cannot set Endpoint Address for Unknown Port" + portName);
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.cannot_set_endpoint_address_unknown_port", new String[]{portName}));
}
}
*/
package jalview.analysis;
-import java.util.*;
-
-import java.awt.*;
-
-import jalview.datamodel.*;
-import jalview.schemes.*;
-import jalview.util.*;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.schemes.ResidueProperties;
+import jalview.schemes.ScoreMatrix;
+import jalview.util.Comparison;
+import jalview.util.Format;
+import jalview.util.MapList;
+import jalview.util.MessageManager;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringTokenizer;
/**
*
}
/**
+ *
+ * @return aligned instance of Seq 1
+ */
+ public SequenceI getAlignedSeq1()
+ {
+ SequenceI alSeq1 = new Sequence(s1.getName(), getAStr1());
+ alSeq1.setStart(s1.getStart() + getSeq1Start() - 1);
+ alSeq1.setEnd(s1.getStart() + getSeq1End() - 1);
+ alSeq1.setDatasetSequence(s1.getDatasetSequence() == null ? s1 : s1
+ .getDatasetSequence());
+ return alSeq1;
+ }
+
+ /**
+ *
+ * @return aligned instance of Seq 2
+ */
+ public SequenceI getAlignedSeq2()
+ {
+ SequenceI alSeq2 = new Sequence(s2.getName(), getAStr2());
+ alSeq2.setStart(s2.getStart() + getSeq2Start() - 1);
+ alSeq2.setEnd(s2.getStart() + getSeq2End() - 1);
+ alSeq2.setDatasetSequence(s2.getDatasetSequence() == null ? s2 : s2
+ .getDatasetSequence());
+ return alSeq2;
+ }
+
+ /**
* Construct score matrix for sequences with standard DNA or PEPTIDE matrix
*
* @param s1
else
{
output.append("Wrong type = dna or pep only");
- throw new Error("Unknown Type " + type2
- + " - dna or pep are the only allowed values.");
+ throw new Error(MessageManager.formatMessage("error.unknown_type_dna_or_pep", new String[]{type2}));
}
}
output = output.append("\n\n");
}
- pid = pid / (float) (aseq1.length - count) * 100;
+ pid = pid / (aseq1.length - count) * 100;
output = output.append(new Format("Percentage ID = %2.2f\n\n")
.form(pid));
if (allowmismatch || c1 == c2)
{
- lastmatch = true;
- // extend mapping interval.
+ // extend mapping interval
if (lp1 + 1 != alignpos || lp2 + 1 != pdbpos)
{
as1.add(Integer.valueOf(alignpos));
as2.add(Integer.valueOf(pdbpos));
}
+ lastmatch = true;
lp1 = alignpos;
lp2 = pdbpos;
}
else
{
+ // extend mapping interval
+ if (lastmatch)
+ {
+ as1.add(Integer.valueOf(lp1));
+ as2.add(Integer.valueOf(lp2));
+ }
lastmatch = false;
}
}
// construct range pairs
+
int[] mapseq1 = new int[as1.size() + (lastmatch ? 1 : 0)], mapseq2 = new int[as2
.size() + (lastmatch ? 1 : 0)];
int i = 0;
}
/**
+ * matches ochains against al and populates seqs with the best match between
+ * each ochain and the set in al
+ *
+ * @param ochains
+ * @param al
+ * @param dnaOrProtein
+ * @param removeOldAnnots
+ * when true, old annotation is cleared before new annotation
+ * transferred
+ * @return List<List<SequenceI> originals, List<SequenceI> replacement,
+ * List<AlignSeq> alignment between each>
+ */
+ public static List<List<? extends Object>> replaceMatchingSeqsWith(
+ List<SequenceI> seqs, List<AlignmentAnnotation> annotations,
+ List<SequenceI> ochains,
+ AlignmentI al, String dnaOrProtein, boolean removeOldAnnots)
+ {
+ List<SequenceI> orig = new ArrayList<SequenceI>(), repl = new ArrayList<SequenceI>();
+ List<AlignSeq> aligs = new ArrayList<AlignSeq>();
+ if (al != null && al.getHeight() > 0)
+ {
+ ArrayList<SequenceI> matches = new ArrayList<SequenceI>();
+ ArrayList<AlignSeq> aligns = new ArrayList<AlignSeq>();
+
+ for (SequenceI sq : ochains)
+ {
+ SequenceI bestm = null;
+ AlignSeq bestaseq = null;
+ int bestscore = 0;
+ for (SequenceI msq : al.getSequences())
+ {
+ AlignSeq aseq = doGlobalNWAlignment(msq, sq,
+ dnaOrProtein);
+ if (bestm == null || aseq.getMaxScore() > bestscore)
+ {
+ bestscore = aseq.getMaxScore();
+ bestaseq = aseq;
+ bestm = msq;
+ }
+ }
+ System.out.println("Best Score for " + (matches.size() + 1) + " :"
+ + bestscore);
+ matches.add(bestm);
+ aligns.add(bestaseq);
+ al.deleteSequence(bestm);
+ }
+ for (int p = 0, pSize = seqs.size(); p < pSize; p++)
+ {
+ SequenceI sq, sp = seqs.get(p);
+ int q;
+ if ((q = ochains.indexOf(sp)) > -1)
+ {
+ seqs.set(p, sq = matches.get(q));
+ orig.add(sp);
+ repl.add(sq);
+ sq.setName(sp.getName());
+ sq.setDescription(sp.getDescription());
+ Mapping sp2sq;
+ sq.transferAnnotation(sp, sp2sq = aligns.get(q).getMappingFromS1(false));
+ aligs.add(aligns.get(q));
+ int inspos = -1;
+ for (int ap = 0; ap < annotations.size();)
+ {
+ if (annotations.get(ap).sequenceRef == sp)
+ {
+ if (inspos == -1)
+ {
+ inspos = ap;
+ }
+ if (removeOldAnnots) {
+ annotations.remove(ap);
+ } else {
+ AlignmentAnnotation alan = annotations.remove(ap);
+ alan.liftOver(sq, sp2sq);
+ alan.setSequenceRef(sq);
+ sq.addAlignmentAnnotation(alan);
+ }
+ }
+ else
+ {
+ ap++;
+ }
+ }
+ if (sq.getAnnotation() != null)
+ {
+ annotations.addAll(inspos, Arrays.asList(sq.getAnnotation()));
+ }
+ }
+ }
+ }
+ return Arrays.asList(orig, repl, aligs);
+ }
+
+ /**
* compute the PID vector used by the redundancy filter.
*
* @param originalSequences
--- /dev/null
+package jalview.analysis;
+
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.SequenceI;
+import jalview.renderer.AnnotationRenderer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AlignmentAnnotationUtils
+{
+
+ /**
+ * Helper method to populate lists of annotation types for the Show/Hide
+ * Annotations menus. If sequenceGroup is not null, this is restricted to
+ * annotations which are associated with sequences in the selection group.
+ * <p/>
+ * If an annotation row is currently visible, its type (label) is added (once
+ * only per type), to the shownTypes list. If it is currently hidden, it is
+ * added to the hiddenTypesList.
+ * <p/>
+ * For rows that belong to a line graph group, so are always rendered
+ * together:
+ * <ul>
+ * <li>Treat all rows in the group as visible, if at least one of them is</li>
+ * <li>Build a list of all the annotation types that belong to the group</li>
+ * </ul>
+ *
+ * @param shownTypes
+ * a map, keyed by calcId (annotation source), whose entries are the
+ * lists of annotation types found for the calcId; each annotation
+ * type in turn may be a list (in the case of grouped annotations)
+ * @param hiddenTypes
+ * a map, similar to shownTypes, but for hidden annotation types
+ * @param annotations
+ * the annotations on the alignment to scan
+ * @param forSequences
+ * the sequences to restrict search to
+ */
+ public static void getShownHiddenTypes(
+ Map<String, List<List<String>>> shownTypes,
+ Map<String, List<List<String>>> hiddenTypes,
+ List<AlignmentAnnotation> annotations,
+ List<SequenceI> forSequences)
+ {
+ BitSet visibleGraphGroups = AlignmentAnnotationUtils
+ .getVisibleLineGraphGroups(annotations);
+
+ /*
+ * Build a lookup, by calcId (annotation source), of all annotation types in
+ * each graph group.
+ */
+ Map<String, Map<Integer, List<String>>> groupLabels = new HashMap<String, Map<Integer, List<String>>>();
+
+ // trackers for which calcId!label combinations we have dealt with
+ List<String> addedToShown = new ArrayList<String>();
+ List<String> addedToHidden = new ArrayList<String>();
+
+ for (AlignmentAnnotation aa : annotations)
+ {
+ if (forSequences != null
+ && (aa.sequenceRef != null && forSequences
+ .contains(aa.sequenceRef)))
+ {
+ String calcId = aa.getCalcId();
+
+ /*
+ * Build a 'composite label' for types in line graph groups.
+ */
+ final List<String> labelAsList = new ArrayList<String>();
+ final String displayLabel = aa.label;
+ labelAsList.add(displayLabel);
+ if (aa.graph == AlignmentAnnotation.LINE_GRAPH
+ && aa.graphGroup > -1)
+ {
+ if (!groupLabels.containsKey(calcId))
+ {
+ groupLabels.put(calcId, new HashMap<Integer, List<String>>());
+ }
+ Map<Integer, List<String>> groupLabelsForCalcId = groupLabels
+ .get(calcId);
+ if (groupLabelsForCalcId.containsKey(aa.graphGroup))
+ {
+ if (!groupLabelsForCalcId.get(aa.graphGroup).contains(
+ displayLabel))
+ {
+ groupLabelsForCalcId.get(aa.graphGroup).add(displayLabel);
+ }
+ }
+ else
+ {
+ groupLabelsForCalcId.put(aa.graphGroup, labelAsList);
+ }
+ }
+ else
+ /*
+ * 'Simple case' - not a grouped annotation type - list of one label
+ * only
+ */
+ {
+ String rememberAs = calcId + "!" + displayLabel;
+ if (aa.visible && !addedToShown.contains(rememberAs))
+ {
+ if (!shownTypes.containsKey(calcId))
+ {
+ shownTypes.put(calcId, new ArrayList<List<String>>());
+ }
+ shownTypes.get(calcId).add(labelAsList);
+ addedToShown.add(rememberAs);
+ }
+ else
+ {
+ if (!aa.visible && !addedToHidden.contains(rememberAs))
+ {
+ if (!hiddenTypes.containsKey(calcId))
+ {
+ hiddenTypes.put(calcId, new ArrayList<List<String>>());
+ }
+ hiddenTypes.get(calcId).add(labelAsList);
+ addedToHidden.add(rememberAs);
+ }
+ }
+ }
+ }
+ }
+ /*
+ * Finally add the 'composite group labels' to the appropriate lists,
+ * depending on whether the group is identified as visible or hidden. Don't
+ * add the same label more than once (there may be many graph groups that
+ * generate it).
+ */
+ for (String calcId : groupLabels.keySet())
+ {
+ for (int group : groupLabels.get(calcId).keySet())
+ {
+ final List<String> groupLabel = groupLabels.get(calcId).get(group);
+ // don't want to duplicate 'same types in different order'
+ Collections.sort(groupLabel);
+ if (visibleGraphGroups.get(group))
+ {
+ if (!shownTypes.containsKey(calcId))
+ {
+ shownTypes.put(calcId, new ArrayList<List<String>>());
+ }
+ if (!shownTypes.get(calcId).contains(groupLabel))
+ {
+ shownTypes.get(calcId).add(groupLabel);
+ }
+ }
+ else
+ {
+ if (!hiddenTypes.containsKey(calcId))
+ {
+ hiddenTypes.put(calcId, new ArrayList<List<String>>());
+ }
+ if (!hiddenTypes.get(calcId).contains(groupLabel))
+ {
+ hiddenTypes.get(calcId).add(groupLabel);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a BitSet (possibly empty) of those graphGroups for line graph
+ * annotations, which have at least one member annotation row marked visible.
+ * <p/>
+ * Only one row in each visible group is marked visible, but when it is drawn,
+ * so are all the other rows in the same group.
+ * <p/>
+ * This lookup set allows us to check whether rows apparently marked not
+ * visible are in fact shown.
+ *
+ * @see AnnotationRenderer#drawComponent
+ * @param annotations
+ * @return
+ */
+ public static BitSet getVisibleLineGraphGroups(
+ List<AlignmentAnnotation> annotations)
+ {
+ BitSet result = new BitSet();
+ for (AlignmentAnnotation ann : annotations)
+ {
+ if (ann.graph == AlignmentAnnotation.LINE_GRAPH && ann.visible)
+ {
+ int gg = ann.graphGroup;
+ if (gg > -1)
+ {
+ result.set(gg);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Converts an array of AlignmentAnnotation into a List of
+ * AlignmentAnnotation. A null array is converted to an empty list.
+ *
+ * @param anns
+ * @return
+ */
+ public static List<AlignmentAnnotation> asList(AlignmentAnnotation[] anns)
+ {
+ // TODO use AlignmentAnnotationI instead when it exists
+ return (anns == null ? Collections.<AlignmentAnnotation> emptyList()
+ : Arrays.asList(anns));
+ }
+}
if (method != FEATURE_SCORE && method != FEATURE_LABEL
&& method != FEATURE_DENSITY)
{
- throw new Error(
- "Implementation Error - sortByFeature method must be one of FEATURE_SCORE, FEATURE_LABEL or FEATURE_DENSITY.");
+ throw new Error(MessageManager.getString("error.implementation_error_sortbyfeature"));
}
boolean ignoreScore = method != FEATURE_SCORE;
StringBuffer scoreLabel = new StringBuffer();
{
if (method == FEATURE_LABEL)
{
- throw new Error("Not yet implemented.");
+ throw new Error(MessageManager.getString("error.not_yet_implemented"));
}
}
if (lastSortByFeatureScore == null
*/
package jalview.analysis;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+
import java.util.ArrayList;
import java.util.List;
-import jalview.datamodel.SequenceI;
-import jalview.datamodel.AlignmentI;
-
/**
* grab bag of useful alignment manipulation operations Expect these to be
* refactored elsewhere at some point.
newAl.setDataset(core.getDataset());
return newAl;
}
+
+ /**
+ * Returns the index (zero-based position) of a sequence in an alignment, or
+ * -1 if not found.
+ *
+ * @param al
+ * @param seq
+ * @return
+ */
+ public static int getSequenceIndex(AlignmentI al, SequenceI seq)
+ {
+ int result = -1;
+ int pos = 0;
+ for (SequenceI alSeq : al.getSequences())
+ {
+ if (alSeq == seq)
+ {
+ result = pos;
+ break;
+ }
+ pos++;
+ }
+ return result;
+ }
}
--- /dev/null
+package jalview.analysis;
+
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A helper class to sort all annotations associated with an alignment in
+ * various ways.
+ *
+ * @author gmcarstairs
+ *
+ */
+public class AnnotationSorter
+{
+
+ /**
+ * enum for annotation sort options. The text description is used in the
+ * Preferences drop-down options. The enum name is saved in the preferences
+ * file.
+ *
+ * @author gmcarstairs
+ *
+ */
+ public enum SequenceAnnotationOrder
+ {
+ // Text descriptions surface in the Preferences Sort by... options
+ SEQUENCE_AND_LABEL("Sequence"), LABEL_AND_SEQUENCE("Label"), NONE(
+ "No sort");
+
+ private String description;
+
+ private SequenceAnnotationOrder(String s)
+ {
+ description = s;
+ }
+
+ @Override
+ public String toString()
+ {
+ return description;
+ }
+
+ public static SequenceAnnotationOrder forDescription(String d) {
+ for (SequenceAnnotationOrder order : values())
+ {
+ if (order.toString().equals(d))
+ {
+ return order;
+ }
+ }
+ return null;
+ }
+ }
+
+ // the alignment with respect to which annotations are sorted
+ private final AlignmentI alignment;
+
+ // user preference for placement of non-sequence annotations
+ private boolean showAutocalcAbove;
+
+ // working map of sequence index in alignment
+ private final Map<SequenceI, Integer> sequenceIndices = new HashMap<SequenceI, Integer>();
+
+ /**
+ * Constructor given an alignment and the location (top or bottom) of
+ * Consensus and similar.
+ *
+ * @param alignmentI
+ * @param showAutocalculatedAbove
+ */
+ public AnnotationSorter(AlignmentI alignmentI,
+ boolean showAutocalculatedAbove)
+ {
+ this.alignment = alignmentI;
+ this.showAutocalcAbove = showAutocalculatedAbove;
+ }
+
+ /**
+ * Default comparator sorts as follows by annotation type within sequence
+ * order:
+ * <ul>
+ * <li>annotations with a reference to a sequence in the alignment are sorted
+ * on sequence ordering</li>
+ * <li>other annotations go 'at the end', with their mutual order unchanged</li>
+ * <li>within the same sequence ref, sort by label (non-case-sensitive)</li>
+ * </ul>
+ */
+ private final Comparator<? super AlignmentAnnotation> bySequenceAndLabel = new Comparator<AlignmentAnnotation>()
+ {
+ @Override
+ public int compare(AlignmentAnnotation o1, AlignmentAnnotation o2)
+ {
+ if (o1 == null && o2 == null)
+ {
+ return 0;
+ }
+ if (o1 == null)
+ {
+ return -1;
+ }
+ if (o2 == null)
+ {
+ return 1;
+ }
+
+ /*
+ * Ignore label (keep existing ordering) for
+ * Conservation/Quality/Consensus etc
+ */
+ if (o1.sequenceRef == null && o2.sequenceRef == null)
+ {
+ return 0;
+ }
+ int sequenceOrder = compareSequences(o1, o2);
+ return sequenceOrder == 0 ? compareLabels(o1, o2) : sequenceOrder;
+ }
+ };
+
+ /**
+ * This comparator sorts as follows by sequence order within annotation type
+ * <ul>
+ * <li>annotations with a reference to a sequence in the alignment are sorted
+ * on label (non-case-sensitive)</li>
+ * <li>other annotations go 'at the end', with their mutual order unchanged</li>
+ * <li>within the same label, sort by order of the related sequences</li>
+ * </ul>
+ */
+ private final Comparator<? super AlignmentAnnotation> byLabelAndSequence = new Comparator<AlignmentAnnotation>()
+ {
+ @Override
+ public int compare(AlignmentAnnotation o1, AlignmentAnnotation o2)
+ {
+ if (o1 == null && o2 == null)
+ {
+ return 0;
+ }
+ if (o1 == null)
+ {
+ return -1;
+ }
+ if (o2 == null)
+ {
+ return 1;
+ }
+
+ /*
+ * Ignore label (keep existing ordering) for
+ * Conservation/Quality/Consensus etc
+ */
+ if (o1.sequenceRef == null && o2.sequenceRef == null)
+ {
+ return 0;
+ }
+
+ /*
+ * Sort non-sequence-related before or after sequence-related.
+ */
+ if (o1.sequenceRef == null)
+ {
+ return showAutocalcAbove ? -1 : 1;
+ }
+ if (o2.sequenceRef == null)
+ {
+ return showAutocalcAbove ? 1 : -1;
+ }
+ int labelOrder = compareLabels(o1, o2);
+ return labelOrder == 0 ? compareSequences(o1, o2) : labelOrder;
+ }
+ };
+
+ /**
+ * noSort leaves sort order unchanged, within sequence- and
+ * non-sequence-related annotations, but may switch the ordering of these
+ * groups. Note this is guaranteed (at least in Java 7) as Arrays.sort() is
+ * guaranteed to be 'stable' (not change ordering of equal items).
+ */
+ private Comparator<? super AlignmentAnnotation> noSort = new Comparator<AlignmentAnnotation>()
+ {
+ @Override
+ public int compare(AlignmentAnnotation o1, AlignmentAnnotation o2)
+ {
+ if (o1 != null && o2 != null)
+ {
+ if (o1.sequenceRef == null && o2.sequenceRef != null)
+ {
+ return showAutocalcAbove ? -1 : 1;
+ }
+ if (o1.sequenceRef != null && o2.sequenceRef == null)
+ {
+ return showAutocalcAbove ? 1 : -1;
+ }
+ }
+ return 0;
+ }
+ };
+
+ /**
+ * Sort by the specified ordering of sequence-specific annotations.
+ *
+ * @param alignmentAnnotations
+ * @param order
+ */
+ public void sort(AlignmentAnnotation[] alignmentAnnotations,
+ SequenceAnnotationOrder order)
+ {
+ // cache 'alignment sequence position' for the annotations
+ saveSequenceIndices(alignmentAnnotations);
+
+ Comparator<? super AlignmentAnnotation> comparator = getComparator(order);
+
+ if (alignmentAnnotations != null)
+ {
+ synchronized (alignmentAnnotations)
+ {
+ Arrays.sort(alignmentAnnotations, comparator);
+ }
+ }
+ }
+
+ /**
+ * Calculate and save in a temporary map the position of each annotation's
+ * sequence (if it has one) in the alignment. Faster to do this once than for
+ * every annotation comparison.
+ *
+ * @param alignmentAnnotations
+ */
+ private void saveSequenceIndices(
+ AlignmentAnnotation[] alignmentAnnotations)
+ {
+ sequenceIndices.clear();
+ for (AlignmentAnnotation ann : alignmentAnnotations) {
+ SequenceI seq = ann.sequenceRef;
+ if (seq != null) {
+ int index = AlignmentUtils.getSequenceIndex(alignment, seq);
+ sequenceIndices.put(seq, index);
+ }
+ }
+ }
+
+ /**
+ * Get the comparator for the specified sort order.
+ *
+ * @param order
+ * @return
+ */
+ private Comparator<? super AlignmentAnnotation> getComparator(
+ SequenceAnnotationOrder order)
+ {
+ if (order == null)
+ {
+ return noSort;
+ }
+ switch (order)
+ {
+ case NONE:
+ return this.noSort;
+ case SEQUENCE_AND_LABEL:
+ return this.bySequenceAndLabel;
+ case LABEL_AND_SEQUENCE:
+ return this.byLabelAndSequence;
+ default:
+ throw new UnsupportedOperationException(order.toString());
+ }
+ }
+
+ /**
+ * Non-case-sensitive comparison of annotation labels. Returns zero if either
+ * argument is null.
+ *
+ * @param o1
+ * @param o2
+ * @return
+ */
+ private int compareLabels(AlignmentAnnotation o1, AlignmentAnnotation o2)
+ {
+ if (o1 == null || o2 == null)
+ {
+ return 0;
+ }
+ String label1 = o1.label;
+ String label2 = o2.label;
+ if (label1 == null && label2 == null)
+ {
+ return 0;
+ }
+ if (label1 == null)
+ {
+ return -1;
+ }
+ if (label2 == null)
+ {
+ return 1;
+ }
+ return label1.toUpperCase().compareTo(label2.toUpperCase());
+ }
+
+ /**
+ * Comparison based on position of associated sequence (if any) in the
+ * alignment. Returns zero if either argument is null.
+ *
+ * @param o1
+ * @param o2
+ * @return
+ */
+ private int compareSequences(AlignmentAnnotation o1,
+ AlignmentAnnotation o2)
+ {
+ SequenceI seq1 = o1.sequenceRef;
+ SequenceI seq2 = o2.sequenceRef;
+ if (seq1 == null && seq2 == null)
+ {
+ return 0;
+ }
+ /*
+ * Sort non-sequence-related before or after sequence-related.
+ */
+ if (seq1 == null)
+ {
+ return showAutocalcAbove ? -1 : 1;
+ }
+ if (seq2 == null)
+ {
+ return showAutocalcAbove ? 1 : -1;
+ }
+ // get sequence index - but note -1 means 'at end' so needs special handling
+ int index1 = sequenceIndices.get(seq1);
+ int index2 = sequenceIndices.get(seq2);
+ if (index1 == index2)
+ {
+ return 0;
+ }
+ if (index1 == -1)
+ {
+ return -1;
+ }
+ if (index2 == -1)
+ {
+ return 1;
+ }
+ return Integer.compare(index1, index2);
+ }
+}
import jalview.analysis.SecStrConsensus.SimpleBP;
import jalview.datamodel.SequenceFeature;
+import jalview.util.MessageManager;
public class Rna
{
{
if (!isClosingParenthesis(closingParenthesis))
{
- throw new WUSSParseException(
- "Querying matching opening parenthesis for non-closing parenthesis character "
- + closingParenthesis, -1);
+ throw new WUSSParseException(MessageManager.formatMessage("exception.querying_matching_opening_parenthesis_for_non_closing_parenthesis", new String[]{new StringBuffer(closingParenthesis).toString()}), -1);
}
return closingToOpening.get(closingParenthesis);
if (!stacks.containsKey(opening))
{
- throw new WUSSParseException(
- "Mismatched (unseen) closing character " + base, i);
+ throw new WUSSParseException(MessageManager.formatMessage("exception.mismatched_unseen_closing_char", new String[]{new StringBuffer(base).toString()}), i);
}
Stack<Integer> stack = stacks.get(opening);
if (stack.isEmpty())
{
// error whilst parsing i'th position. pass back
- throw new WUSSParseException("Mismatched closing character "
- + base, i);
+ throw new WUSSParseException(MessageManager.formatMessage("exception.mismatched_closing_char", new String[]{new StringBuffer(base).toString()}), i);
}
int temp = stack.pop();
Stack<Integer> stack = stacks.get(opening);
if (!stack.empty())
{
- throw new WUSSParseException("Mismatched opening character "
- + opening + " at " + stack.pop(), i);
+ throw new WUSSParseException(MessageManager.formatMessage("exception.mismatched_opening_char", new String[]{new StringBuffer(opening).toString(),Integer.valueOf(stack.pop()).toString()}), i);
}
}
return pairs;
*
* All operations should return true if the view has changed as a result
* of the operation
- * @param <ViewportI>
+ *
+ * The controller holds methods that operate on an alignment view,
+ * modifying its state in some way that may result in side effects
+ * reflected in an associated GUI
*
*/
-public interface AlignViewControllerI<ViewportI>
+public interface AlignViewControllerI
{
public boolean makeGroupsFromSelection();
import java.awt.Color;
import java.util.Hashtable;
+import java.util.List;
import java.util.Map;
import jalview.analysis.Conservation;
void setConservation(Conservation cons);
+ /**
+ * get a copy of the currently visible alignment annotation
+ * @param selectedOnly if true - trim to selected regions on the alignment
+ * @return an empty list or new alignment annotation objects shown only visible columns trimmed to selected region only
+ */
+ List<AlignmentAnnotation> getVisibleAlignmentAnnotation(
+ boolean selectedOnly);
+
FeaturesDisplayedI getFeaturesDisplayed();
String getSequenceSetId();
public interface SequenceStructureBinding
{
- // todo: decide what this really means - we could return a reference to the
- // alignment/jmol binding, or some other binding.
+ /**
+ *
+ * @return true if Jalview or the Viewer is still restoring state or loading
+ * is still going on (see setFinsihedLoadingFromArchive)
+ */
+ void setLoadingFromArchive(boolean loadingFromArchive);
+
+ boolean isLoadingFromArchive();
+
+ /**
+ * modify flag which controls if sequence colouring events are honoured by the
+ * binding. Should be true for normal operation
+ *
+ * @param finishedLoading
+ */
+ void setFinishedLoadingFromArchive(boolean finishedLoading);
+
+ boolean isLoadingFinished();
+
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview 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.
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.api.structures;
+
+import jalview.api.FeatureRenderer;
+import jalview.api.SequenceRenderer;
+import jalview.api.SequenceStructureBinding;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.ext.jmol.JalviewJmolBinding;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.UserColourScheme;
+import jalview.structure.StructureMappingcommandSet;
+import jalview.structure.StructureSelectionManager;
+
+public interface JalviewStructureDisplayI
+{
+
+ SequenceStructureBinding getBinding();
+
+ /**
+ * @return true if there is an active GUI handling a structure display
+ */
+ boolean isVisible();
+
+ /**
+ * enable or disable the structure display - note this might just hide or show
+ * a GUI element, but not actually reset the display
+ *
+ * @param b
+ */
+ void setVisible(boolean b);
+
+ /**
+ * free up any external resources that were used by this display and collect
+ * garbage
+ */
+ void dispose();
+
+ /**
+ * shutdown any structure viewing processes started by this display
+ */
+ void closeViewer();
+ /**
+ * apply a colourscheme to the structures in the viewer
+ * @param colourScheme
+ */
+ void setJalviewColourScheme(ColourSchemeI colourScheme);
+
+}
if (dialog.accept)
{
- EditCommand editCommand = new EditCommand("Edit Sequences",
+ EditCommand editCommand = new EditCommand(MessageManager.getString("label.edit_sequences"),
EditCommand.REPLACE, dialog.getName().replace(' ',
ap.av.getGapCharacter()),
sg.getSequencesAsArray(ap.av.getHiddenRepSequences()),
// TODO consider using getSequenceSelection instead here
cap.setText(new jalview.io.AppletFormatAdapter().formatSequences(
- e.getActionCommand(),
- new Alignment(ap.av.getSelectionAsNewSequence()),
- ap.av.showJVSuffix));
+ e.getActionCommand(),
+ ap.av.showJVSuffix, ap.av, true));
}
colourMenu.add(abovePIDColour);
colourMenu.add(conservationMenuItem);
- noColourmenuItem.setLabel("None");
+ noColourmenuItem.setLabel(MessageManager.getString("label.none"));
noColourmenuItem.addActionListener(this);
- clustalColour.setLabel("Clustalx colours");
+ clustalColour.setLabel(MessageManager.getString("label.clustalx_colours"));
clustalColour.addActionListener(this);
- zappoColour.setLabel("Zappo");
+ zappoColour.setLabel(MessageManager.getString("label.zappo"));
zappoColour.addActionListener(this);
- taylorColour.setLabel("Taylor");
+ taylorColour.setLabel(MessageManager.getString("label.taylor"));
taylorColour.addActionListener(this);
- hydrophobicityColour.setLabel("Hydrophobicity");
+ hydrophobicityColour.setLabel(MessageManager.getString("label.hydrophobicity"));
hydrophobicityColour.addActionListener(this);
- helixColour.setLabel("Helix propensity");
+ helixColour.setLabel(MessageManager.getString("label.helix_propensity"));
helixColour.addActionListener(this);
- strandColour.setLabel("Strand propensity");
+ strandColour.setLabel(MessageManager.getString("label.strand_propensity"));
strandColour.addActionListener(this);
- turnColour.setLabel("Turn propensity");
+ turnColour.setLabel(MessageManager.getString("label.turn_propensity"));
turnColour.addActionListener(this);
- buriedColour.setLabel("Buried Index");
+ buriedColour.setLabel(MessageManager.getString("label.buried_index"));
buriedColour.addActionListener(this);
- abovePIDColour.setLabel("Above % Identity");
+ abovePIDColour.setLabel(MessageManager.getString("label.above_identity_percentage"));
- userDefinedColour.setLabel("User Defined");
+ userDefinedColour.setLabel(MessageManager.getString("action.user_defined"));
userDefinedColour.addActionListener(this);
- PIDColour.setLabel("Percentage Identity");
+ PIDColour.setLabel(MessageManager.getString("action.percentage_identity"));
PIDColour.addActionListener(this);
BLOSUM62Colour.setLabel("BLOSUM62");
BLOSUM62Colour.addActionListener(this);
- conservationMenuItem.setLabel("Conservation");
+ conservationMenuItem.setLabel(MessageManager.getString("label.conservation"));
editMenu.add(copy);
copy.addActionListener(this);
package jalview.appletgui;
import jalview.analysis.AlignmentSorter;
-import jalview.analysis.Conservation;
import jalview.api.AlignViewControllerGuiI;
import jalview.api.AlignViewControllerI;
import jalview.api.SequenceStructureBinding;
import jalview.schemes.PurinePyrimidineColourScheme;
import jalview.schemes.RNAHelicesColourChooser;
import jalview.schemes.RNAInteractionColourScheme;
-import jalview.schemes.ResidueProperties;
import jalview.schemes.StrandColourScheme;
import jalview.schemes.TCoffeeColourScheme;
import jalview.schemes.TaylorColourScheme;
.getKeyCode() >= KeyEvent.VK_NUMPAD0 && evt
.getKeyCode() <= KeyEvent.VK_NUMPAD9))
&& Character.isDigit(evt.getKeyChar()))
+ {
alignPanel.seqPanel.numberPressed(evt.getKeyChar());
+ }
switch (evt.getKeyCode())
{
case KeyEvent.VK_LEFT:
if (evt.isAltDown() || !viewport.cursorMode)
+ {
slideSequences(false, alignPanel.seqPanel.getKeyboardNo1());
+ }
else
+ {
alignPanel.seqPanel.moveCursor(-1, 0);
+ }
break;
case KeyEvent.VK_RIGHT:
if (evt.isAltDown() || !viewport.cursorMode)
+ {
slideSequences(true, alignPanel.seqPanel.getKeyboardNo1());
+ }
else
+ {
alignPanel.seqPanel.moveCursor(1, 0);
+ }
break;
case KeyEvent.VK_SPACE:
else
{
if (features == null)
+ {
features = "";
+ }
}
return features;
for (int i = 0; i < viewport.getAlignment().getHeight(); i++)
{
if (!sg.contains(viewport.getAlignment().getSequenceAt(i)))
+ {
invertGroup.addElement(viewport.getAlignment().getSequenceAt(i));
+ }
}
SequenceI[] seqs1 = sg.toArray(new SequenceI[sg.size()]);
SequenceI[] seqs2 = invertGroup.toArray(new SequenceI[invertGroup
.size()]);
for (int i = 0; i < invertGroup.size(); i++)
+ {
seqs2[i] = invertGroup.elementAt(i);
+ }
SlideSequencesCommand ssc;
if (right)
+ {
ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1,
size, viewport.getGapCharacter());
+ }
else
+ {
ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2,
size, viewport.getGapCharacter());
+ }
int groupAdjustment = 0;
if (ssc.getGapsInsertedBegin() && right)
{
if (viewport.cursorMode)
+ {
alignPanel.seqPanel.moveCursor(size, 0);
+ }
else
+ {
groupAdjustment = size;
+ }
}
else if (!ssc.getGapsInsertedBegin() && !right)
{
if (viewport.cursorMode)
+ {
alignPanel.seqPanel.moveCursor(-size, 0);
+ }
else
+ {
groupAdjustment = -size;
+ }
}
if (groupAdjustment != 0)
}
if (!appendHistoryItem)
+ {
addHistoryItem(ssc);
+ }
repaint();
}
if (newAlignment)
{
- String newtitle = new String("Copied sequences");
- if (getTitle().startsWith("Copied sequences"))
+ String newtitle = MessageManager.getString("label.copied_sequences");
+ if (getTitle().startsWith(MessageManager.getString("label.copied_sequences")))
{
newtitle = getTitle();
}
else
{
- newtitle = newtitle.concat("- from " + getTitle());
+ newtitle = newtitle.concat(MessageManager.formatMessage("label.from_msname", new String[]{getTitle()}));
}
AlignFrame af = new AlignFrame(new Alignment(newSeqs),
viewport.applet, newtitle, false);
}
// !newAlignment
- addHistoryItem(new EditCommand("Add sequences", EditCommand.PASTE,
+ addHistoryItem(new EditCommand(MessageManager.getString("label.add_sequences"), EditCommand.PASTE,
seqs, 0, viewport.getAlignment().getWidth(),
viewport.getAlignment()));
/*
* //ADD HISTORY ITEM
*/
- addHistoryItem(new EditCommand("Cut Sequences", EditCommand.CUT, cut,
+ addHistoryItem(new EditCommand(MessageManager.getString("label.cut_sequences"), EditCommand.CUT, cut,
sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
viewport.getAlignment()));
MessageManager.getString("label.load_features_annotations"));
MenuItem outputFeatures = new MenuItem(
- MessageManager.getString("label.export_features"));
+ MessageManager.getString("label.export_features").concat("..."));
MenuItem outputAnnotations = new MenuItem(
- MessageManager.getString("label.export_annotations"));
+ MessageManager.getString("label.export_annotations").concat("..."));
MenuItem closeMenuItem = new MenuItem(
MessageManager.getString("action.close"));
sortGroupMenuItem.setLabel(MessageManager.getString("action.by_group"));
sortGroupMenuItem.addActionListener(this);
removeRedundancyMenuItem.setLabel(MessageManager
- .getString("action.remove_redundancy"));
+ .getString("action.remove_redundancy").concat("..."));
removeRedundancyMenuItem.addActionListener(this);
pairwiseAlignmentMenuItem.setLabel(MessageManager
.getString("action.pairwise_alignment"));
}
pdbentry.getProperty().put("protocol", protocol);
toaddpdb.addPDBId(pdbentry);
+ alignPanel.getStructureSelectionManager()
+ .registerPDBEntry(pdbentry);
}
}
return true;
fontChanged(); // This is so that the scalePanel is resized correctly
validate();
- sequenceHolderPanel.revalidate();
+ sequenceHolderPanel.validate();
repaint();
}
threshold.select(1);
break;
default:
- throw new Error(
- "Implementation error: don't know about threshold setting for current AnnotationColourGradient.");
+ throw new Error(MessageManager.getString("error.implementation_error_dont_know_thereshold_annotationcolourgradient"));
}
thresholdIsMin.setState(acg.thresholdIsMinMax);
thresholdValue.setText("" + acg.getAnnotationThreshold());
package jalview.appletgui;
import java.util.*;
-
import java.awt.*;
import java.awt.event.*;
{
popup.addSeparator();
final CheckboxMenuItem cbmi = new CheckboxMenuItem(
- "Ignore Gaps In Consensus",
+ MessageManager.getString("label.ignore_gaps_consensus"),
(aa[selectedRow].groupRef != null) ? aa[selectedRow].groupRef
.getIgnoreGapsConsensus() : ap.av
.getIgnoreGapsConsensus());
if (aaa.groupRef != null)
{
final CheckboxMenuItem chist = new CheckboxMenuItem(
- "Show Group Histogram",
+ MessageManager.getString("label.show_group_histogram"),
aa[selectedRow].groupRef.isShowConsensusHistogram());
chist.addItemListener(new ItemListener()
{
});
popup.add(chist);
final CheckboxMenuItem cprofl = new CheckboxMenuItem(
- "Show Group Logo",
+ MessageManager.getString("label.show_group_logo"),
aa[selectedRow].groupRef.isShowSequenceLogo());
cprofl.addItemListener(new ItemListener()
{
popup.add(cprofl);
final CheckboxMenuItem cprofn = new CheckboxMenuItem(
- "Normalise Group Logo",
+ MessageManager.getString("label.normalise_group_logo"),
aa[selectedRow].groupRef.isNormaliseSequenceLogo());
cprofn.addItemListener(new ItemListener()
{
else
{
final CheckboxMenuItem chist = new CheckboxMenuItem(
- "Show Histogram", av.isShowConsensusHistogram());
+ MessageManager.getString("label.show_histogram"), av.isShowConsensusHistogram());
chist.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
});
popup.add(chist);
final CheckboxMenuItem cprof = new CheckboxMenuItem(
- "Show Logo", av.isShowSequenceLogo());
+ MessageManager.getString("label.show_logo"), av.isShowSequenceLogo());
cprof.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
});
popup.add(cprof);
final CheckboxMenuItem cprofn = new CheckboxMenuItem(
- "Normalise Logo", av.isNormaliseSequenceLogo());
+ MessageManager.getString("label.normalise_logo"), av.isNormaliseSequenceLogo());
cprofn.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
}
else if (aa[selectedRow].sequenceRef != null)
{
- Vector sr = new Vector();
- sr.addElement(aa[selectedRow].sequenceRef);
if (evt.getClickCount() == 1)
{
- ap.seqPanel.ap.idPanel.highlightSearchResults(sr);
+ ap.seqPanel.ap.idPanel.highlightSearchResults(Arrays
+ .asList(new SequenceI[]
+ { aa[selectedRow].sequenceRef }));
}
else if (evt.getClickCount() >= 2)
{
ap.seqPanel.ap.idPanel.highlightSearchResults(null);
- SequenceGroup sg = new SequenceGroup();
- sg.addSequence(aa[selectedRow].sequenceRef, false);
+ SequenceGroup sg = ap.av.getSelectionGroup();
+ if (sg!=null)
+ {
+ // we make a copy rather than edit the current selection if no modifiers pressed
+ // see Enhancement JAL-1557
+ if (!(evt.isControlDown() || evt.isShiftDown()))
+ {
+ sg = new SequenceGroup(sg);
+ sg.clear();
+ sg.addSequence(aa[selectedRow].sequenceRef, false);
+ } else {
+ if (evt.isControlDown())
+ {
+ sg.addOrRemove(aa[selectedRow].sequenceRef, true);
+ } else {
+ // notionally, we should also add intermediate sequences from last added sequence ?
+ sg.addSequence(aa[selectedRow].sequenceRef, true);
+ }
+ }
+ } else {
+ sg = new SequenceGroup();
+ sg.setStartRes(0);
+ sg.setEndRes(ap.av.getAlignment().getWidth()-1);
+ sg.addSequence(aa[selectedRow].sequenceRef, false);
+ }
ap.av.setSelectionGroup(sg);
ap.paintAlignment(false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
public class AppletJmol extends EmbmenuFrame implements
// StructureListener,
- KeyListener, ActionListener, ItemListener, SequenceStructureBinding
+ KeyListener, ActionListener, ItemListener
{
Menu fileMenu = new Menu(MessageManager.getString("action.file"));
String[][] boundchains, boolean align, AlignmentPanel ap,
String protocol)
{
- throw new Error("Not yet implemented.");
+ throw new Error(MessageManager.getString("error.not_yet_implemented"));
}
public AppletJmol(PDBEntry pdbentry, SequenceI[] seq, String[] chains,
}
if (freader == null)
{
- throw new Exception(
- "Invalid datasource. Could not obtain Reader.");
+ throw new Exception(MessageManager.getString("exception.invalid_datasource_couldnt_obtain_reader"));
}
jmb.viewer.openReader(pdbentry.getFile(), pdbentry.getId(),
freader);
*/
package jalview.appletgui;
+import jalview.util.MessageManager;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
{
if (embeddedPopup == null)
{
- throw new Error(
- "Implementation error - embeddedPopup must be non-null");
+ throw new Error(MessageManager.getString("error.implementation_error_embeddedpopup_not_null"));
}
if (overrideFonts)
{
}
else
{
- throw new Error("Invalid color for MyCheckBox");
+ throw new Error(MessageManager.getString("error.invalid_colour_for_mycheckbox"));
}
if (col != null)
{
}
}
- String title = newFeatures ? "Create New Sequence Feature(s)"
- : "Amend/Delete Features for " + sequences[0].getName();
+ String title = newFeatures ? MessageManager.getString("label.create_new_sequence_features")
+ : MessageManager.formatMessage("label.amend_delete_features", new String[]{sequences[0].getName()});
final JVDialog dialog = new JVDialog(ap.alignFrame, title, true, 385,
240);
}
else
{
- throw new Error(
- "Implementation error: Unsupported feature colour object.");
+ throw new Error(MessageManager.getString("error.implementation_error_unsupported_feature_colour_object"));
}
refreshTable();
}
}
else
{
- throw new Error("Invalid color for MyCheckBox");
+ throw new Error(MessageManager.getString("error.invalid_colour_for_mycheckbox"));
}
if (col != null)
{
}
}
- EditCommand cut = new EditCommand("Remove Redundancy",
+ EditCommand cut = new EditCommand(MessageManager.getString("action.remove_redundancy"),
EditCommand.CUT, deleted, 0, width, ap.av.getAlignment());
AlignmentI alignment = ap.av.getAlignment();
for (int i = 0; i < del.size(); i++)
ap.alignFrame.addHistoryItem(cut);
PaintRefresher.Refresh(this, ap.av.getSequenceSetId(), true, true);
- // ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
- // .getSequences());
+ ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
}
}
{
ap.av.historyList.removeElement(command);
ap.alignFrame.updateEditMenuBar();
+ ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
}
ap.paintAlignment(true);
import jalview.structure.SelectionSource;
import jalview.structure.SequenceListener;
import jalview.structure.StructureSelectionManager;
+import jalview.util.MessageManager;
public class SeqPanel extends Panel implements MouseMotionListener,
MouseListener, SequenceListener
StringBuffer message = new StringBuffer();
if (groupEditing)
{
- message.append("Edit group:");
+ message.append(MessageManager.getString("action.edit_group")).append(":");
if (editCommand == null)
{
- editCommand = new EditCommand("Edit Group");
+ editCommand = new EditCommand(MessageManager.getString("action.edit_group"));
}
}
else
{
- message.append("Edit sequence: " + seq.getName());
+ message.append(MessageManager.getString("label.edit_sequence")).append(" " + seq.getName());
String label = seq.getName();
if (label.length() > 10)
{
}
if (editCommand == null)
{
- editCommand = new EditCommand("Edit " + label);
+ editCommand = new EditCommand(MessageManager.formatMessage("label.edit_params", new String[]{label}));
}
}
sp.cs = cs;
}
- conservationSlider.setTitle("Conservation Colour Increment (" + source
- + ")");
+ conservationSlider.setTitle(MessageManager.formatMessage("label.conservation_colour_increment", new String[]{source}));
if (ap.av.getAlignment().getGroups() != null)
{
sp.setAllGroupsCheckEnabled(true);
pid = (SliderPanel) PIDSlider.getComponent(0);
pid.cs = cs;
}
- PIDSlider.setTitle("Percentage Identity Threshold (" + source + ")");
+ PIDSlider.setTitle(MessageManager.formatMessage("label.percentage_identity_thereshold", new String[]{source}));
if (ap.av.getAlignment().getGroups() != null)
{
setTargetColour(colour);
okcancelPanel.setBounds(new Rectangle(0, 113, 400, 35));
- frame.setTitle("User Defined Colours - " + label);
+ frame.setTitle(MessageManager.getString("label.user_defined_colours") + " - " + label);
frame.setSize(420, 200);
}
// // not 1.1 compatible!
// dialog = new Dialog(((JVDialog)alignframe), title, true);
// } else {
- throw new Error("Unsupported owner for User Colour scheme dialog.");
+ throw new Error(MessageManager.getString("label.error_unsupported_owwner_user_colour_scheme"));
}
dialog.add(this);
import jalview.ws.dbsources.das.datamodel.DasSourceRegistry;
import java.awt.Color;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.TreeSet;
-import org.apache.log4j.*;
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.SimpleLayout;
/**
* Stores and retrieves Jalview Application Properties Lists and fields within
* <li>SHOW_QUALITY show alignment quality annotation</li>
* <li>SHOW_ANNOTATIONS show alignment annotation rows</li>
* <li>SHOW_CONSERVATION show alignment conservation annotation</li>
+ * <li>SORT_ANNOTATIONS currently either SEQUENCE_AND_LABEL or
+ * LABEL_AND_SEQUENCE</li>
+ * <li>SHOW_AUTOCALC_ABOVE true to show autocalculated annotations above
+ * sequence annotations</li>
* <li>CENTRE_COLUMN_LABELS centre the labels at each column in a displayed
* annotation row</li>
* <li>DEFAULT_COLOUR default colour scheme to apply for a new alignment</li>
* when shading by annotation</li>
* <li>www.jalview.org (http://www.jalview.org) a property enabling all HTTP
* requests to be redirected to a mirror of http://www.jalview.org</li>
- *
* <li>FIGURE_AUTOIDWIDTH (false) Expand the left hand column of an exported
* alignment figure to accommodate even the longest sequence ID or annotation
* label.</li>
* <li>FIGURE_FIXEDIDWIDTH Specifies the width to use for the left-hand column
* when exporting an alignment as a figure (setting FIGURE_AUTOIDWIDTH to true
* will override this).</li>
- * <li></li>
+ * <li>STRUCT_FROM_PDB (false) derive secondary structure annotation from PDB
+ * record</li>
+ * <li>USE_RNAVIEW (false) use RNAViewer to derive secondary structure</li>
+ * <li>ADD_SS_ANN (false) add secondary structure annotation to alignment
+ * display</li>
+ * <li>ADD_TEMPFACT_ANN (false) add Temperature Factor annotation to alignment
+ * display</li>
+ * <li>STRUCTURE_DISPLAY choose from JMOL (default) or CHIMERA for 3D structure
+ * display</li>
+ * <li>CHIMERA_PATH specify full path to Chimera program (if non-standard)</li>
*
* </ul>
* Deprecated settings:
public static Logger log;
/** Jalview Properties */
- public static Properties applicationProperties = new Properties();
+ public static Properties applicationProperties = new Properties() {
+ // override results in properties output in alphabetical order
+ @Override
+ public synchronized Enumeration<Object> keys() {
+ return Collections.enumeration(new TreeSet<Object>(super.keySet()));
+ }
+ };
/** Default file is ~/.jalview_properties */
static String propertiesFile;
if (log != null)
{
if (re != null)
+ {
log.debug("Caught runtime exception in googletracker init:", re);
+ }
if (ex != null)
+ {
log.warn(
"Failed to initialise GoogleTracker for Jalview Desktop with version "
+ vrs, ex);
+ }
if (err != null)
+ {
log.error(
"Whilst initing GoogleTracker for Jalview Desktop version "
+ vrs, err);
+ }
}
else
{
}
return sourceRegistry;
}
+
+ /**
+ * Set the specified value, or remove it if null or empty. Does not save the
+ * properties file.
+ *
+ * @param propName
+ * @param value
+ */
+ public static void setOrRemove(String propName, String value)
+ {
+ if (propName == null)
+ {
+ return;
+ }
+ if (value == null || value.trim().length() < 1)
+ {
+ Cache.applicationProperties.remove(propName);
+ }
+ else
+ {
+ Cache.applicationProperties.setProperty(propName, value);
+ }
+ }
}
import javax.swing.*;
import jalview.gui.*;
+import jalview.util.MessageManager;
import jalview.util.Platform;
/**
{
if (!headless)
{
- desktop.setProgressBar("Processing commandline arguments...",
+ desktop.setProgressBar(MessageManager.getString("status.processing_commandline_args"),
progress = System.currentTimeMillis());
}
System.out.println("Opening file: " + file);
running++;
}
- af.setProgressBar("DAS features being retrieved...", id);
+ af.setProgressBar(MessageManager.getString("status.das_features_being_retrived"), id);
af.featureSettings_actionPerformed(null);
af.featureSettings.fetchDasFeatures(dasSources, true);
af.setProgressBar(null, id);
}
else
{
- throw new Error(
- "Invalid separator parameter - must be non-zero length");
+ throw new Error(MessageManager.getString("error.invalid_separator_parameter"));
}
}
int r = 255;
{
String sequence = applet.getParameter("PDBSEQ");
if (sequence != null)
+ {
seqs = new SequenceI[]
{ matcher == null ? (Sequence) newAlignFrame
.getAlignViewport().getAlignment()
.findName(sequence) : matcher.findIdMatch(sequence) };
+ }
}
else
if (seqs[i] != null)
{
((Sequence) seqs[i]).addPDBId(pdb);
+ StructureSelectionManager.getStructureSelectionManager(
+ applet).registerPDBEntry(pdb);
}
else
{
// note separator local variable intentionally masks object field
int seplen = separator.length();
if (list == null || list.equals("") || list.equals(separator))
+ {
return null;
+ }
java.util.Vector jv = new Vector();
int cp = 0, pos;
while ((pos = list.indexOf(separator, cp)) > cp)
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._annotationElementList.size())
{
- throw new IndexOutOfBoundsException(
- "getAnnotationElement: Index value '" + index
- + "' not in range [0.."
- + (this._annotationElementList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getAnnotationElement",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._annotationElementList.size() - 1)).toString()
+ }));
}
return (jalview.binding.AnnotationElement) _annotationElementList
// check bounds for index
if (index < 0 || index >= this._annotationElementList.size())
{
- throw new IndexOutOfBoundsException(
- "setAnnotationElement: Index value '" + index
- + "' not in range [0.."
- + (this._annotationElementList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setAnnotationElement",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._annotationElementList.size() - 1)).toString()
+ }));
}
this._annotationElementList.set(index, vAnnotationElement);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._settingList.size())
{
- throw new IndexOutOfBoundsException("getSetting: Index value '"
- + index + "' not in range [0.."
- + (this._settingList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getSetting",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._settingList.size() - 1)).toString()
+ }));
}
return (jalview.binding.Setting) _settingList.get(index);
// check bounds for index
if (index < 0 || index >= this._settingList.size())
{
- throw new IndexOutOfBoundsException("setSetting: Index value '"
- + index + "' not in range [0.."
- + (this._settingList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setSetting",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._settingList.size() - 1)).toString()
+ }));
}
this._settingList.set(index, vSetting);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._seqList.size())
{
- throw new IndexOutOfBoundsException("getSeq: Index value '" + index
- + "' not in range [0.." + (this._seqList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getSeq",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._seqList.size() - 1)).toString()
+ }));
}
return ((java.lang.Integer) _seqList.get(index)).intValue();
// check bounds for index
if (index < 0 || index >= this._seqList.size())
{
- throw new IndexOutOfBoundsException("setSeq: Index value '" + index
- + "' not in range [0.." + (this._seqList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setSeq",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._seqList.size() - 1)).toString()
+ }));
}
this._seqList.set(index, new java.lang.Integer(vSeq));
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._featuresList.size())
{
- throw new IndexOutOfBoundsException("getFeatures: Index value '"
- + index + "' not in range [0.."
- + (this._featuresList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getFeatures",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._featuresList.size() - 1)).toString()
+ }));
}
return (jalview.binding.Features) _featuresList.get(index);
// check bounds for index
if (index < 0 || index >= this._pdbidsList.size())
{
- throw new IndexOutOfBoundsException("getPdbids: Index value '"
- + index + "' not in range [0.."
- + (this._pdbidsList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getPdbids",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._pdbidsList.size() - 1)).toString()
+ }));
}
return (jalview.binding.Pdbids) _pdbidsList.get(index);
// check bounds for index
if (index < 0 || index >= this._featuresList.size())
{
- throw new IndexOutOfBoundsException("setFeatures: Index value '"
- + index + "' not in range [0.."
- + (this._featuresList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setFeatures",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._featuresList.size() - 1)).toString()
+ }));
}
this._featuresList.set(index, vFeatures);
// check bounds for index
if (index < 0 || index >= this._pdbidsList.size())
{
- throw new IndexOutOfBoundsException("setPdbids: Index value '"
- + index + "' not in range [0.."
- + (this._pdbidsList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setPdbids",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._pdbidsList.size() - 1)).toString()
+ }));
}
this._pdbidsList.set(index, vPdbids);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._JGroupList.size())
{
- throw new IndexOutOfBoundsException("getJGroup: Index value '"
- + index + "' not in range [0.."
- + (this._JGroupList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getJGroup",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._JGroupList.size() - 1)).toString()
+ }));
}
return (jalview.binding.JGroup) _JGroupList.get(index);
// check bounds for index
if (index < 0 || index >= this._JSeqList.size())
{
- throw new IndexOutOfBoundsException("getJSeq: Index value '" + index
- + "' not in range [0.." + (this._JSeqList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getJSeq",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._JSeqList.size() - 1)).toString()
+ }));
}
return (jalview.binding.JSeq) _JSeqList.get(index);
// check bounds for index
if (index < 0 || index >= this._treeList.size())
{
- throw new IndexOutOfBoundsException("getTree: Index value '" + index
- + "' not in range [0.." + (this._treeList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getJgetTreeSeq",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._treeList.size() - 1)).toString()
+ }));
}
return (jalview.binding.Tree) _treeList.get(index);
// check bounds for index
if (index < 0 || index >= this._userColoursList.size())
{
- throw new IndexOutOfBoundsException("getUserColours: Index value '"
- + index + "' not in range [0.."
- + (this._userColoursList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getUserColours",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._userColoursList.size() - 1)).toString()
+ }));
}
return (jalview.binding.UserColours) _userColoursList.get(index);
// check bounds for index
if (index < 0 || index >= this._viewportList.size())
{
- throw new IndexOutOfBoundsException("getViewport: Index value '"
- + index + "' not in range [0.."
- + (this._viewportList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getViewport",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._viewportList.size() - 1)).toString()
+ }));
}
return (jalview.binding.Viewport) _viewportList.get(index);
// check bounds for index
if (index < 0 || index >= this._JGroupList.size())
{
- throw new IndexOutOfBoundsException("setJGroup: Index value '"
- + index + "' not in range [0.."
- + (this._JGroupList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setJGroup",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._JGroupList.size() - 1)).toString()
+ }));
}
this._JGroupList.set(index, vJGroup);
// check bounds for index
if (index < 0 || index >= this._JSeqList.size())
{
- throw new IndexOutOfBoundsException("setJSeq: Index value '" + index
- + "' not in range [0.." + (this._JSeqList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setJSeq",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._JSeqList.size() - 1)).toString()
+ }));
}
this._JSeqList.set(index, vJSeq);
// check bounds for index
if (index < 0 || index >= this._treeList.size())
{
- throw new IndexOutOfBoundsException("setTree: Index value '" + index
- + "' not in range [0.." + (this._treeList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setTree",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._treeList.size() - 1)).toString()
+ }));
}
this._treeList.set(index, vTree);
// check bounds for index
if (index < 0 || index >= this._userColoursList.size())
{
- throw new IndexOutOfBoundsException("setUserColours: Index value '"
- + index + "' not in range [0.."
- + (this._userColoursList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setUserColours",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._userColoursList.size() - 1)).toString()
+ }));
}
this._userColoursList.set(index, vUserColours);
// check bounds for index
if (index < 0 || index >= this._viewportList.size())
{
- throw new IndexOutOfBoundsException("setViewport: Index value '"
- + index + "' not in range [0.."
- + (this._viewportList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setViewport",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._viewportList.size() - 1)).toString()
+ }));
}
this._viewportList.set(index, vViewport);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._colourList.size())
{
- throw new IndexOutOfBoundsException("getColour: Index value '"
- + index + "' not in range [0.."
- + (this._colourList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getColour",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._colourList.size() - 1)).toString()
+ }));
}
return (Colour) _colourList.get(index);
// check bounds for index
if (index < 0 || index >= this._colourList.size())
{
- throw new IndexOutOfBoundsException("setColour: Index value '"
- + index + "' not in range [0.."
- + (this._colourList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setColour",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._colourList.size() - 1)).toString()
+ }));
}
this._colourList.set(index, vColour);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._items.size())
{
- throw new IndexOutOfBoundsException("getPdbentryItem: Index value '"
- + index + "' not in range [0.." + (this._items.size() - 1)
- + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getPdbentryItem",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._items.size() - 1)).toString()
+ }));
}
return (jalview.binding.PdbentryItem) _items.get(index);
// check bounds for index
if (index < 0 || index >= this._items.size())
{
- throw new IndexOutOfBoundsException("setPdbentryItem: Index value '"
- + index + "' not in range [0.." + (this._items.size() - 1)
- + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setPdbentryItem",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._items.size() - 1)).toString()
+ }));
}
this._items.set(index, vPdbentryItem);
*/
package jalview.binding;
+import jalview.util.MessageManager;
+
/**
* Class PdbentryItem.
*
// check bounds for index
if (index < 0 || index >= this._propertyList.size())
{
- throw new IndexOutOfBoundsException("getProperty: Index value '"
- + index + "' not in range [0.."
- + (this._propertyList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getProperty",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._propertyList.size() - 1)).toString()
+ }));
}
return (jalview.binding.Property) _propertyList.get(index);
// check bounds for index
if (index < 0 || index >= this._propertyList.size())
{
- throw new IndexOutOfBoundsException("setProperty: Index value '"
- + index + "' not in range [0.."
- + (this._propertyList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setProperty",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._propertyList.size() - 1)).toString()
+ }));
}
this._propertyList.set(index, vProperty);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._annotationList.size())
{
- throw new IndexOutOfBoundsException("getAnnotation: Index value '"
- + index + "' not in range [0.."
- + (this._annotationList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getAnnotation",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._annotationList.size() - 1)).toString()
+ }));
}
return (jalview.binding.Annotation) _annotationList.get(index);
// check bounds for index
if (index < 0 || index >= this._sequenceList.size())
{
- throw new IndexOutOfBoundsException("getSequence: Index value '"
- + index + "' not in range [0.."
- + (this._sequenceList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getSequence",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._sequenceList.size() - 1)).toString()
+ }));
}
return (jalview.binding.Sequence) _sequenceList.get(index);
// check bounds for index
if (index < 0 || index >= this._annotationList.size())
{
- throw new IndexOutOfBoundsException("setAnnotation: Index value '"
- + index + "' not in range [0.."
- + (this._annotationList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setAnnotation",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._annotationList.size() - 1)).toString()
+ }));
}
this._annotationList.set(index, vAnnotation);
// check bounds for index
if (index < 0 || index >= this._sequenceList.size())
{
- throw new IndexOutOfBoundsException("setSequence: Index value '"
- + index + "' not in range [0.."
- + (this._sequenceList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setSequence",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._sequenceList.size() - 1)).toString()
+ }));
}
this._sequenceList.set(index, vSequence);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._alignmentList.size())
{
- throw new IndexOutOfBoundsException("getAlignment: Index value '"
- + index + "' not in range [0.."
- + (this._alignmentList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getAlignment",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._alignmentList.size() - 1)).toString()
+ }));
}
return (Alignment) _alignmentList.get(index);
// check bounds for index
if (index < 0 || index >= this._sequenceSetList.size())
{
- throw new IndexOutOfBoundsException("getSequenceSet: Index value '"
- + index + "' not in range [0.."
- + (this._sequenceSetList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getSequenceSet",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._sequenceSetList.size() - 1)).toString()
+ }));
}
return (SequenceSet) _sequenceSetList.get(index);
// check bounds for index
if (index < 0 || index >= this._treeList.size())
{
- throw new IndexOutOfBoundsException("getTree: Index value '" + index
- + "' not in range [0.." + (this._treeList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getTree",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._treeList.size() - 1)).toString()
+ }));
}
return (java.lang.String) _treeList.get(index);
// check bounds for index
if (index < 0 || index >= this._alignmentList.size())
{
- throw new IndexOutOfBoundsException("setAlignment: Index value '"
- + index + "' not in range [0.."
- + (this._alignmentList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setAlignment",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._alignmentList.size() - 1)).toString()
+ }));
}
this._alignmentList.set(index, vAlignment);
// check bounds for index
if (index < 0 || index >= this._sequenceSetList.size())
{
- throw new IndexOutOfBoundsException("setSequenceSet: Index value '"
- + index + "' not in range [0.."
- + (this._sequenceSetList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setSequenceSet",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._sequenceSetList.size() - 1)).toString()
+ }));
}
this._sequenceSetList.set(index, vSequenceSet);
// check bounds for index
if (index < 0 || index >= this._treeList.size())
{
- throw new IndexOutOfBoundsException("setTree: Index value '" + index
- + "' not in range [0.." + (this._treeList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setTree",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._treeList.size() - 1)).toString()
+ }));
}
this._treeList.set(index, vTree);
*/
package jalview.commands;
-import java.util.*;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
-import jalview.datamodel.*;
+import java.util.Hashtable;
+import java.util.List;
/**
*
@Override
final public void undoCommand(AlignmentI[] views)
- {
- int e = 0, eSize = edits.length;
- for (e = eSize - 1; e > -1; e--)
- {
- switch (edits[e].command)
- {
- case INSERT_GAP:
- deleteGap(edits[e]);
- break;
- case DELETE_GAP:
- insertGap(edits[e]);
- break;
- case CUT:
- paste(edits[e], views);
- break;
- case PASTE:
- cut(edits[e], views);
- break;
- case REPLACE:
- replace(edits[e]);
- break;
- }
+ {
+ for(Edit e : edits){
+ switch (e.command)
+ {
+ case INSERT_GAP:
+ deleteGap(e);
+ break;
+ case DELETE_GAP:
+ insertGap(e);
+ break;
+ case CUT:
+ paste(e, views);
+ break;
+ case PASTE:
+ cut(e, views);
+ break;
+ case REPLACE:
+ replace(e);
+ break;
+ }
}
}
List<SequenceI> sequences;
synchronized (sequences = command.al.getSequences())
{
- sequences.add(command.alIndex[i], command.seqs[i]);
+ if (!(command.alIndex[i] < 0))
+ {
+ sequences.add(command.alIndex[i], command.seqs[i]);
+ }
}
}
else
+ command.number);
}
if (command.seqs[i].getStart() == start)
+ {
newstart--;
+ }
else
+ {
newend++;
+ }
}
}
command.string[i] = null;
{
temp = new Annotation[aSize + command.number];
if (annotations[a].padGaps)
+ {
for (int aa = 0; aa < temp.length; aa++)
{
temp[aa] = new Annotation(command.gapChar + "", null, ' ', 0);
}
+ }
}
else
{
int copylen = Math.min(command.position,
annotations[a].annotations.length);
if (copylen > 0)
+ {
System.arraycopy(annotations[a].annotations, 0, temp, 0,
copylen); // command.position);
+ }
Annotation[] deleted = new Annotation[command.number];
if (copylen >= command.position)
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
public class AlignViewController implements AlignViewControllerI
{
}
viewport.setColumnSelection(cs);
alignPanel.paintAlignment(true);
- avcg.setStatus((toggle ? "Toggled " : "Marked ")
- + (invert ? (alw - alStart) - bs.cardinality() : bs
- .cardinality()) + " columns "
- + (invert ? "not " : "") + "containing features of type "
- + featureType + " across " + nseq + " sequence(s)");
+ avcg.setStatus(MessageManager.formatMessage("label.view_controller_toggled_marked",
+ new String[]{
+ (toggle ? MessageManager.getString("label.toggled") : MessageManager.getString("label.marked")),
+ (invert ? (Integer.valueOf((alw - alStart) - bs.cardinality()).toString()):(Integer.valueOf(bs.cardinality()).toString())),
+ featureType, Integer.valueOf(nseq).toString()
+ }));
return true;
}
else
{
- avcg.setStatus("No features of type " + featureType + " found.");
+ avcg.setStatus(MessageManager.formatMessage("label.no_feature_of_type_found", new String[]{featureType}));
if (!extendCurrent && cs != null)
{
cs.clear();
*/
package jalview.datamodel;
-import java.util.*;
+import jalview.util.MessageManager;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
/**
* Data structure to hold and manipulate a multiple sequence alignment
*/
public static AlignmentI createAlignment(CigarArray compactAlignment)
{
- throw new Error("Alignment(CigarArray) not yet implemented");
+ throw new Error(MessageManager.getString("error.alignment_cigararray_not_implemented"));
// this(compactAlignment.refCigars);
}
import jalview.analysis.Rna;
import jalview.analysis.SecStrConsensus.SimpleBP;
-
import jalview.analysis.WUSSParseException;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Hashtable;
-
-import fr.orsay.lri.varna.models.rna.RNA;
+import java.util.Map;
+import java.util.Map.Entry;
/**
* DOCUMENT ME!
*/
public boolean autoCalculated = false;
+ /**
+ * unique ID for this annotation, used to match up the same annotation row
+ * shown in multiple views and alignments
+ */
public String annotationId;
+ /**
+ * the sequence this annotation is associated with (or null)
+ */
public SequenceI sequenceRef;
- /** DOCUMENT ME!! */
+ /** label shown in dropdown menus and in the annotation label area */
public String label;
- /** DOCUMENT ME!! */
+ /** longer description text shown as a tooltip */
public String description;
- /** DOCUMENT ME!! */
+ /** Array of annotations placed in the current coordinate system */
public Annotation[] annotations;
public ArrayList<SimpleBP> bps = null;
// System.out.println("featuregroup " + _rnasecstr[0].getFeatureGroup());
}
- public java.util.Hashtable sequenceMapping;
+ /**
+ * map of positions in the associated annotation
+ */
+ public java.util.Hashtable<Integer, Annotation> sequenceMapping;
/** DOCUMENT ME!! */
public float graphMin;
// Check for RNA secondary structure
{
// System.out.println(annotations[i].secondaryStructure);
- // TODO: 2.8.2 should this ss symbol validation check be a function in RNA/ResidueProperties ?
+ // TODO: 2.8.2 should this ss symbol validation check be a function in
+ // RNA/ResidueProperties ?
if (annotations[i].secondaryStructure == '('
|| annotations[i].secondaryStructure == '['
|| annotations[i].secondaryStructure == '<'
{
this.label = new String(annotation.label);
if (annotation.description != null)
+ {
this.description = new String(annotation.description);
+ }
this.graphMin = annotation.graphMin;
this.graphMax = annotation.graphMax;
this.graph = annotation.graph;
this.scaleColLabel = annotation.scaleColLabel;
this.showAllColLabels = annotation.showAllColLabels;
this.calcId = annotation.calcId;
+ if (annotation.properties!=null)
+ {
+ properties = new HashMap<String,String>();
+ for (Map.Entry<String, String> val:annotation.properties.entrySet())
+ {
+ properties.put(val.getKey(), val.getValue());
+ }
+ }
if (this.hasScore = annotation.hasScore)
{
this.score = annotation.score;
{
threshold = new GraphLine(annotation.threshold);
}
+ Annotation[] ann = annotation.annotations;
if (annotation.annotations != null)
{
- Annotation[] ann = annotation.annotations;
this.annotations = new Annotation[ann.length];
for (int i = 0; i < ann.length; i++)
{
}
}
}
- ;
- if (annotation.sequenceRef != null)
+ }
+ if (annotation.sequenceRef != null)
+ {
+ this.sequenceRef = annotation.sequenceRef;
+ if (annotation.sequenceMapping != null)
{
- this.sequenceRef = annotation.sequenceRef;
- if (annotation.sequenceMapping != null)
+ Integer p = null;
+ sequenceMapping = new Hashtable();
+ Enumeration pos = annotation.sequenceMapping.keys();
+ while (pos.hasMoreElements())
{
- Integer p = null;
- sequenceMapping = new Hashtable();
- Enumeration pos = annotation.sequenceMapping.keys();
- while (pos.hasMoreElements())
+ // could optimise this!
+ p = (Integer) pos.nextElement();
+ Annotation a = annotation.sequenceMapping.get(p);
+ if (a == null)
+ {
+ continue;
+ }
+ if (ann != null)
{
- // could optimise this!
- p = (Integer) pos.nextElement();
- Annotation a = (Annotation) annotation.sequenceMapping.get(p);
- if (a == null)
- {
- continue;
- }
for (int i = 0; i < ann.length; i++)
{
if (ann[i] == a)
}
}
}
- else
- {
- this.sequenceMapping = null;
- }
+ }
+ else
+ {
+ this.sequenceMapping = null;
}
}
// TODO: check if we need to do this: JAL-952
return;
}
if (startRes < 0)
+ {
startRes = 0;
+ }
if (startRes >= annotations.length)
+ {
startRes = annotations.length - 1;
+ }
if (endRes >= annotations.length)
+ {
endRes = annotations.length - 1;
+ }
if (annotations == null)
+ {
return;
+ }
Annotation[] temp = new Annotation[endRes - startRes + 1];
if (startRes < annotations.length)
{
public void adjustForAlignment()
{
if (sequenceRef == null)
+ {
return;
+ }
if (annotations == null)
{
{
position = sequenceRef.findIndex(a) - 1;
- temp[position] = (Annotation) sequenceMapping.get(index);
+ temp[position] = sequenceMapping.get(index);
}
}
if (annotations[i] == null)
{
if (i + 1 < iSize)
+ {
System.arraycopy(annotations, i + 1, annotations, i, iSize - i
- 1);
+ }
iSize--;
}
else
{
if (sequenceRef != null)
{
+ boolean rIsDs=sequenceRef.getDatasetSequence()==null,tIsDs=sequenceI.getDatasetSequence()==null;
if (sequenceRef != sequenceI
- && !sequenceRef.equals(sequenceI)
- && sequenceRef.getDatasetSequence() != sequenceI
+ && (rIsDs && !tIsDs && sequenceRef != sequenceI
.getDatasetSequence())
+ && (!rIsDs && tIsDs && sequenceRef.getDatasetSequence() != sequenceI)
+ && (!rIsDs && !tIsDs && sequenceRef.getDatasetSequence() != sequenceI
+ .getDatasetSequence())
+ && !sequenceRef.equals(sequenceI))
{
// if sequenceRef isn't intersecting with sequenceI
// throw away old mapping and reconstruct.
for (int i = 0; i < annotations.length; i++)
{
if (annotations[i] == null)
+ {
annotations[i] = new Annotation(String.valueOf(gapchar), null,
' ', 0f, null);
+ }
else if (annotations[i].displayCharacter == null
|| annotations[i].displayCharacter.equals(" "))
+ {
annotations[i].displayCharacter = String.valueOf(gapchar);
+ }
}
}
}
protected String calcId = "";
/**
+ * properties associated with the calcId
+ */
+ protected Map<String, String> properties = new HashMap<String, String>();
+
+ /**
* base colour for line graphs. If null, will be set automatically by
* searching the alignment annotation
*/
{
this.calcId = calcId;
}
+
+ public boolean isRNA()
+ {
+ return isrna;
+ }
+
+ /**
+ * transfer annotation to the given sequence using the given mapping from the
+ * current positions or an existing sequence mapping
+ *
+ * @param sq
+ * @param sp2sq
+ * map involving sq as To or From
+ */
+ public void liftOver(SequenceI sq, Mapping sp2sq)
+ {
+ if (sp2sq.getMappedWidth() != sp2sq.getWidth())
+ {
+ // TODO: employ getWord/MappedWord to transfer annotation between cDNA and Protein reference frames
+ throw new Error("liftOver currently not implemented for transfer of annotation between different types of seqeunce");
+ }
+ boolean mapIsTo = (sp2sq != null) ? (sp2sq.getTo() == sq || sp2sq
+ .getTo() == sq.getDatasetSequence()) : false;
+
+ // TODO build a better annotation element map and get rid of annotations[]
+ Hashtable<Integer, Annotation> mapForsq = new Hashtable();
+ if (sequenceMapping != null)
+ {
+ if (sp2sq != null)
+ {
+ for (Entry<Integer, Annotation> ie : sequenceMapping.entrySet())
+ {
+ Integer mpos = Integer.valueOf(mapIsTo ? sp2sq
+ .getMappedPosition(ie.getKey()) : sp2sq.getPosition(ie
+ .getKey()));
+ if (mpos >= sq.getStart() && mpos <= sq.getEnd())
+ {
+ mapForsq.put(mpos, ie.getValue());
+ }
+ }
+ sequenceMapping = mapForsq;
+ sequenceRef = sq;
+ adjustForAlignment();
+ }
+ else
+ {
+ // trim positions
+ }
+ }
+ }
+
+ /**
+ * like liftOver but more general.
+ *
+ * Takes an array of int pairs that will be used to update the internal
+ * sequenceMapping and so shuffle the annotated positions
+ *
+ * @param newref
+ * - new sequence reference for the annotation row - if null,
+ * sequenceRef is left unchanged
+ * @param mapping
+ * array of ints containing corresponding positions
+ * @param from
+ * - column for current coordinate system (-1 for index+1)
+ * @param to
+ * - column for destination coordinate system (-1 for index+1)
+ * @param idxoffset
+ * - offset added to index when referencing either coordinate system
+ * @note no checks are made as to whether from and/or to are sensible
+ * @note caller should add the remapped annotation to newref if they have not
+ * already
+ */
+ public void remap(SequenceI newref, int[][] mapping, int from, int to,
+ int idxoffset)
+ {
+ if (mapping != null)
+ {
+ Hashtable<Integer, Annotation> old = sequenceMapping, remap = new Hashtable<Integer, Annotation>();
+ int index = -1;
+ for (int mp[] : mapping)
+ {
+ if (index++ < 0)
+ {
+ continue;
+ }
+ Annotation ann = null;
+ if (from == -1)
+ {
+ ann = sequenceMapping.get(Integer.valueOf(idxoffset + index));
+ }
+ else
+ {
+ if (mp != null && mp.length > from)
+ {
+ ann = sequenceMapping.get(Integer.valueOf(mp[from]));
+ }
+ }
+ if (ann != null)
+ {
+ if (to == -1)
+ {
+ remap.put(Integer.valueOf(idxoffset + index), ann);
+ }
+ else
+ {
+ if (to > -1 && to < mp.length)
+ {
+ remap.put(Integer.valueOf(mp[to]), ann);
+ }
+ }
+ }
+ }
+ sequenceMapping = remap;
+ old.clear();
+ if (newref != null)
+ {
+ sequenceRef = newref;
+ }
+ adjustForAlignment();
+ }
+ }
+
+ public String getProperty(String property)
+ {
+ if (properties == null)
+ {
+ return null;
+ }
+ return properties.get(property);
+ }
+
+ public void setProperty(String property, String value)
+ {
+ if (properties==null)
+ {
+ properties = new HashMap<String,String>();
+ }
+ properties.put(property, value);
+ }
+
+ public boolean hasProperties()
+ {
+ return properties != null && properties.size() > 0;
+ }
+
+ public Collection<String> getProperties()
+ {
+ if (properties == null)
+ {
+ return Collections.EMPTY_LIST;
+ }
+ return properties.keySet();
+ }
}
*/
package jalview.datamodel;
-import java.util.*;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
/**
* Data structure to hold and manipulate a multiple sequence alignment
*/
package jalview.datamodel;
+import jalview.util.MessageManager;
import jalview.util.ShiftList;
import java.io.PrintStream;
{
if (!seqcigararray.isSeqCigarArray())
{
- throw new Error(
- "Implementation Error - can only make an alignment view from a CigarArray of sequences.");
+ throw new Error(MessageManager.getString("error.implementation_error_can_only_make_alignmnet_from_cigararray"));
}
// contigs = seqcigararray.applyDeletions();
contigs = seqcigararray.getDeletedRegions();
{
if (sequences == null || width <= 0)
{
- throw new Error("empty view cannot be updated.");
+ throw new Error(MessageManager.getString("error.empty_view_cannot_be_updated"));
}
if (nvismsa == null)
{
j++;
if (mseq.length != sequences.length)
{
- throw new Error(
- "Mismatch between number of sequences in block "
- + j + " (" + mseq.length
- + ") and the original view ("
- + sequences.length + ")");
+ throw new Error(MessageManager.formatMessage("error.mismatch_between_number_of_sequences_in_block", new String[]{Integer.valueOf(j).toString(),Integer.valueOf(mseq.length).toString(),Integer.valueOf(sequences.length).toString() }));
}
swidth = mseq[0].getLength(); // JBPNote: could ensure padded
// here.
else
{
// place gaps.
- throw new Error("Padding not yet implemented.");
+ throw new Error(MessageManager.getString("error.padding_not_yet_implemented"));
}
}
}
{
if (nvismsa.length != 1)
{
- throw new Error(
- "Mismatch between visible blocks to update and number of contigs in view (contigs=0,blocks="
- + nvismsa.length);
+ throw new Error(MessageManager.formatMessage("error.mismatch_between_visible_blocks_to_update_and_number_of_contigs_in_view", new String[]{Integer.valueOf(nvismsa.length).toString()}));
}
if (nvismsa[0] != null)
{
*/
package jalview.datamodel;
+import jalview.util.MessageManager;
+
import java.util.*;
public abstract class CigarBase
endpos = alcursor;
break;
default:
- throw new Error("Unknown SeqCigar operation '" + operation[i] + "'");
+ throw new Error(MessageManager.formatMessage("error.unknown_seq_cigar_operation", new String[]{new StringBuffer(operation[i]).toString()}));
}
}
if (++delcount > 0)
} while (c >= '0' && c <= '9' && j < l);
if (j >= l && c >= '0' && c <= '9')
{
- throw new Exception("Unterminated cigar string.");
+ throw new Exception(MessageManager.getString("exception.unterminated_cigar_string"));
}
try
{
i = j;
} catch (Exception e)
{
- throw new Error("Implementation bug in parseCigarString");
+ throw new Error(MessageManager.getString("error.implementation_bug_parse_cigar_string"));
}
if (c >= 'a' && c <= 'z')
{
}
else
{
- throw new Exception("Unexpected operation '" + c
- + "' in cigar string (position " + i + " in '"
- + cigarString + "'");
+ throw new Exception(MessageManager.formatMessage("exception.unexpected_operation_cigar_string_pos", new String[]{
+ new StringBuffer(c).toString(),
+ Integer.valueOf(i).toString(),
+ cigarString
+ }));
}
}
return new Object[]
}
if (op != M && op != D && op != I)
{
- throw new Error("Implementation error. Invalid operation string.");
+ throw new Error(MessageManager.getString("error.implementation_error_invalid_operation_string"));
}
if (range == 0)
{
}
if (range < 0)
{
- throw new Error(
- "Invalid range string (must be zero or positive number)");
+ throw new Error(MessageManager.getString("error.invalid_range_string"));
}
int lngth = 0;
if (operation == null)
}
if (start < 0 || start > end)
{
- throw new Error(
- "Implementation Error: deleteRange out of bounds: start must be non-negative and less than end.");
+ throw new Error(MessageManager.getString("error.implementation_error_delete_range_out_of_bounds"));
}
// find beginning
int cursor = 0; // mark the position for the current operation being edited.
}
break;
case D:
- throw new Error("Implementation error."); // do nothing;
+ throw new Error(MessageManager.getString("error.implementation_error")); // do nothing;
default:
- throw new Error("Implementation Error! Unknown operation '"
- + oldops[o] + "'");
+ throw new Error(MessageManager.formatMessage("error.implementation_error_unknown_operation", new String[]{new StringBuffer(oldops[o]).toString()}));
}
rlength -= remain;
remain = oldrange[++o]; // number of op characters left to edit
refseq.getSequenceAsString(start, end), GapChar);
if (edit_result == null)
{
- throw new Error(
- "Implementation Error - unexpected null from getSequenceAndDeletions");
+ throw new Error(MessageManager.getString("error.implementation_error_unexpected_null_from_get_sequence_and_deletions"));
}
int bounds[] = (int[]) edit_result[1];
seq = new Sequence(refseq.getName(), (String) edit_result[0],
boolean hasgaps = false;
if (seq == null)
{
- throw new Error("Implementation Error - _setSeq(null,...)");
+ throw new Error(MessageManager.getString("error.implementation_error_set_seq_null"));
}
if (_s < 0)
{
- throw new Error("Implementation Error: _s=" + _s);
+ throw new Error(MessageManager.formatMessage("error.implementation_error_s", new String[]{Integer.valueOf(_s).toString()}));
}
String seq_string = seq.getSequenceAsString();
if (_e == 0 || _e < _s || _e > seq_string.length())
// Check offsets
if (end > ds.getLength())
{
- throw new Error(
- "SeqCigar: Possible implementation error: sequence is longer than dataset sequence");
+ throw new Error(MessageManager.getString("error.implementation_error_seqcigar_possible"));
// end = ds.getLength();
}
super();
if (seq == null)
{
- throw new Error("Implementation Bug. Null seq !");
+ throw new Error(MessageManager.getString("error.implmentation_bug_seq_null"));
}
if (operation.length != range.length)
{
- throw new Error(
- "Implementation Bug. Cigar Operation list!= range list");
+ throw new Error(MessageManager.getString("error.implementation_bug_cigar_operation_list_range_list"));
}
if (operation != null)
if (_setSeq(seq, false, 0, 0))
{
- throw new Error(
- "NOT YET Implemented: Constructing a Cigar object from a cigar string and a gapped sequence.");
+ throw new Error(MessageManager.getString("error.not_yet_implemented_cigar_object_from_cigar_string"));
}
for (int i = this.length, j = 0; j < operation.length; i++, j++)
{
char op = operation[j];
if (op != M && op != I && op != D)
{
- throw new Error("Implementation Bug. Cigar Operation '" + j
- + "' '" + op + "' not one of '" + M + "', '" + I
- + "', or '" + D + "'.");
+ throw new Error(MessageManager.formatMessage("error.implementation_bug_cigar_operation", new String[]{Integer.valueOf(j).toString(),Integer.valueOf(op).toString(),Integer.valueOf(M).toString(),Integer.valueOf(I).toString(),Integer.valueOf(D).toString()}));
}
this.operation[i] = op;
this.range[i] = range[j];
this.length = 0;
if (_setSeq(seq, false, 0, 0))
{
- throw new Error(
- "NOT YET Implemented: Constructing a Cigar object from a cigar string and a gapped sequence.");
+ throw new Error(MessageManager.getString("error.not_yet_implemented_cigar_object_from_cigar_string"));
}
}
}
super();
if (seq == null)
{
- throw new Error("Implementation error for new Cigar(SequenceI)");
+ throw new Error(MessageManager.getString("error.implementation_error_for_new_cigar"));
}
_setSeq(seq, false, 0, 0);
// there is still work to do
super();
if (seq == null)
{
- throw new Error("Implementation error for new Cigar(SequenceI)");
+ throw new Error(MessageManager.getString("error.implementation_error_for_new_cigar"));
}
_setSeq(seq, false, start, end + 1);
// there is still work to do
// endcol}, hidden regions {{start, end, col}})
if (gs_regions[i] == null)
{
- throw new Error("Implementation error: " + i
- + "'th sequence Cigar has no operations.");
+ throw new Error(MessageManager.formatMessage("error.implementation_error_cigar_seq_no_operations", new String[]{Integer.valueOf(i).toString()}));
}
g_seqs[i] = new StringBuffer((String) ((Object[]) gs_regions[i])[0]); // the
// visible
import jalview.analysis.AlignSeq;
+import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.List;
import java.util.Vector;
import fr.orsay.lri.varna.models.rna.RNA;
/**
* This annotation is displayed below the alignment but the positions are tied
* to the residues of this sequence
+ *
+ * TODO: change to List<>
*/
- Vector annotation;
+ Vector<AlignmentAnnotation> annotation;
/**
* The index of the sequence in a MSA
public char[] getSequence(int start, int end)
{
if (start < 0)
+ {
start = 0;
+ }
// JBPNote - left to user to pad the result here (TODO:Decide on this
// policy)
if (start >= sequence.length)
return reply;
}
- /**
- * make a new Sequence object from start to end (including gaps) over this
- * seqeunce
- *
- * @param start
- * int
- * @param end
- * int
- * @return SequenceI
- */
+ @Override
public SequenceI getSubSequence(int start, int end)
{
if (start < 0)
}
}
- /**
- * Returns the sequence position for an alignment position
- *
- * @param i
- * column index in alignment (from 1)
- *
- * @return residue number for residue (left of and) nearest ith column
- */
+ @Override
public int findPosition(int i)
{
int j = 0;
AlignmentAnnotation[] ret = new AlignmentAnnotation[annotation.size()];
for (int r = 0; r < ret.length; r++)
{
- ret[r] = (AlignmentAnnotation) annotation.elementAt(r);
+ ret[r] = annotation.elementAt(r);
}
return ret;
{
this.annotation.removeElement(annotation);
if (this.annotation.size() == 0)
+ {
this.annotation = null;
+ }
}
}
datasetSequence.updatePDBIds();
if (annotation != null)
{
- Vector<AlignmentAnnotation> _annot = annotation;
- annotation = null;
- for (AlignmentAnnotation aa : _annot)
+ for (AlignmentAnnotation aa : annotation)
{
- aa.sequenceRef = datasetSequence;
- aa.adjustForAlignment(); // uses annotation's own record of
+ AlignmentAnnotation _aa = new AlignmentAnnotation(aa);
+ _aa.sequenceRef = datasetSequence;
+ _aa.adjustForAlignment(); // uses annotation's own record of
// sequence-column mapping
- datasetSequence.addAlignmentAnnotation(aa);
+ datasetSequence.addAlignmentAnnotation(_aa);
}
}
}
for (int i = 0; i < annotations.length; i++)
{
if (annotations[i] != null)
+ {
addAlignmentAnnotation(annotations[i]);
+ }
}
}
}
return rna;
}
+ /**
+ * Returns a (possibly empty) list of any annotations that match on given
+ * calcId (source) and label (type). Null values do not match.
+ *
+ * @param calcId
+ * @param label
+ */
+ @Override
+ public List<AlignmentAnnotation> getAlignmentAnnotations(String calcId,
+ String label)
+ {
+ List<AlignmentAnnotation> result = new ArrayList<AlignmentAnnotation>();
+ if (this.annotation != null) {
+ for (AlignmentAnnotation ann : annotation) {
+ if (ann.calcId != null && ann.calcId.equals(calcId)
+ && ann.label != null && ann.label.equals(label))
+ {
+ result.add(ann);
+ }
+ }
+ }
+ return result;
+ }
+
}
*/
package jalview.datamodel;
-import java.util.*;
+import jalview.analysis.AAFrequency;
+import jalview.analysis.Conservation;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ResidueProperties;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
import java.util.List;
-
-import java.awt.*;
-
-import jalview.analysis.*;
-import jalview.schemes.*;
+import java.util.Map;
+import java.util.Vector;
/**
* Collects a set contiguous ranges on a set of sequences
return eres;
}
+ @Override
public List<SequenceI> getSequences()
{
return sequences;
}
+ @Override
public List<SequenceI> getSequences(
Map<SequenceI, SequenceCollectionI> hiddenReps)
{
SequenceI seq;
for (int i = 0; i < sequences.size(); i++)
{
- seq = (SequenceI) sequences.elementAt(i);
+ seq = sequences.elementAt(i);
allSequences.addElement(seq);
if (hiddenReps.containsKey(seq))
{
*
* @return the first column selected by this group. Runs from 0<=i<N_cols
*/
+ @Override
public int getStartRes()
{
return startRes;
*
* @return the groups last selected column. Runs from 0<=i<N_cols
*/
+ @Override
public int getEndRes()
{
return endRes;
*/
public SequenceI getSequenceAt(int i)
{
- return (SequenceI) sequences.elementAt(i);
+ return sequences.elementAt(i);
}
/**
*
* @return DOCUMENT ME!
*/
+ @Override
public int getWidth()
{
// MC This needs to get reset when characters are inserted and deleted
if (sequences.size() > 0)
{
- width = ((SequenceI) sequences.elementAt(0)).getLength();
+ width = sequences.elementAt(0).getLength();
}
for (int i = 1; i < sequences.size(); i++)
{
- SequenceI seq = (SequenceI) sequences.elementAt(i);
+ SequenceI seq = sequences.elementAt(i);
if (seq.getLength() > width)
{
// TODO add in other methods like 'getAlignmentAnnotation(String label),
// etc'
ArrayList<AlignmentAnnotation> annot = new ArrayList<AlignmentAnnotation>();
- for (SequenceI seq : (Vector<SequenceI>) sequences)
+ for (SequenceI seq : sequences)
{
AlignmentAnnotation[] aa = seq.getAnnotation();
if (aa != null)
return aa;
}
+ /**
+ * Answer true if any annotation matches the calcId passed in (if not null).
+ *
+ * @param calcId
+ * @return
+ */
+ public boolean hasAnnotation(String calcId)
+ {
+ if (calcId != null && !"".equals(calcId))
+ {
+ for (AlignmentAnnotation a : getAlignmentAnnotation())
+ {
+ if (a.getCalcId() == calcId)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
public void clear()
{
sequences.clear();
*/
package jalview.datamodel;
+import java.util.List;
import java.util.Vector;
import fr.orsay.lri.varna.models.rna.RNA;
* create a new sequence object from start to end of this sequence
*
* @param start
- * int
+ * int index for start position
* @param end
- * int
+ * int index for end position
+ *
* @return SequenceI
+ * @note implementations may use getSequence to get the sequence data
*/
public SequenceI getSubSequence(int start, int end);
* Returns the sequence position for an alignment position
*
* @param i
- * column index in alignment (from 1)
+ * column index in alignment (from 0..<length)
*
* @return residue number for residue (left of and) nearest ith column
*/
public AlignmentAnnotation[] getAnnotation(String label);
/**
+ * Return a list of any annotations which match the given calcId (source) and
+ * label (type). Null values do not match.
+ *
+ * @param calcId
+ * @param label
+ * @return
+ */
+ public List<AlignmentAnnotation> getAlignmentAnnotations(String calcId,
+ String label);
+
+ /**
* create a new dataset sequence (if necessary) for this sequence and sets
* this sequence to refer to it. This call will move any features or
- * references on the sequence onto the dataset.
+ * references on the sequence onto the dataset. It will also make a duplicate
+ * of existing annotation rows for the dataset sequence, rather than relocate
+ * them in order to preserve external references (since 2.8.2).
*
* @return dataset sequence for this sequence
*/
/**
* Transfer any database references or annotation from entry under a sequence
- * mapping.
+ * mapping. <br/>
+ * <strong>Note: DOES NOT transfer sequence associated alignment
+ * annotation </strong><br/>
*
* @param entry
* @param mp
import jalview.structure.StructureListener;
import jalview.structure.StructureMapping;
import jalview.structure.StructureSelectionManager;
+import jalview.structures.models.SequenceStructureBindingModel;
+import jalview.util.MessageManager;
import java.awt.Color;
import java.awt.Container;
import org.jmol.constant.EnumCallback;
import org.jmol.popup.JmolPopup;
-public abstract class JalviewJmolBinding implements StructureListener,
+public abstract class JalviewJmolBinding extends SequenceStructureBindingModel implements StructureListener,
JmolStatusListener, SequenceStructureBinding,
JmolSelectionListener, ComponentListener,
StructureSelectionManagerProvider
{
/**
- * set if Jmol state is being restored from some source - instructs binding
- * not to apply default display style when structure set is updated for first
- * time.
- */
- private boolean loadingFromArchive = false;
-
- /**
- * second flag to indicate if the jmol viewer should ignore sequence colouring
- * events from the structure manager because the GUI is still setting up
- */
- private boolean loadingFinished = true;
-
- /**
* state flag used to check if the Jmol viewer's paint method can be called
*/
private boolean finishedInit = false;
// Jmol callback has completed.
if (mapping == null || mapping.length < 1)
{
- throw new Error(
- "Implementation error - Jmol seems to be still working on getting its data - report at http://issues.jalview.org/browse/JAL-1016");
+ throw new Error(MessageManager.getString("error.implementation_error_jmol_getting_data"));
}
int lastPos = -1;
for (int s = 0; s < sequence[pdbfnum].length; s++)
public void colourBySequence(boolean showFeatures,
jalview.api.AlignmentViewPanel alignmentv)
{
- if (!colourBySequence || !loadingFinished)
+ if (!colourBySequence || !isLoadingFinished())
return;
if (ssm == null)
{
showConsole(false);
}
- public void setLoadingFromArchive(boolean loadingFromArchive)
- {
- this.loadingFromArchive = loadingFromArchive;
- }
-
- /**
- *
- * @return true if Jmol is still restoring state or loading is still going on
- * (see setFinsihedLoadingFromArchive)
- */
- public boolean isLoadingFromArchive()
- {
- return loadingFromArchive && !loadingFinished;
- }
-
- /**
- * modify flag which controls if sequence colouring events are honoured by the
- * binding. Should be true for normal operation
- *
- * @param finishedLoading
- */
- public void setFinishedLoadingFromArchive(boolean finishedLoading)
- {
- loadingFinished = finishedLoading;
- }
-
public void setBackgroundColour(java.awt.Color col)
{
jmolHistory(false);
{
if (pe < 0 || pe >= pdbentry.length)
{
- throw new Error(
- "Implementation error - no corresponding pdbentry (for index "
- + pe + ") to add sequences mappings to");
+ throw new Error(MessageManager.formatMessage("error.implementation_error_no_pdbentry_from_index", new String[]{Integer.valueOf(pe).toString()}));
}
final String nullChain = "TheNullChain";
Vector s = new Vector();
*/
package jalview.ext.jmol;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.io.AlignFile;
+import jalview.io.FileParse;
+import jalview.schemes.ResidueProperties;
+import jalview.util.MessageManager;
+
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
import org.jmol.viewer.Viewer;
import org.openscience.jmol.app.JmolApp;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.PDBEntry;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceI;
-import jalview.io.AlignFile;
-import jalview.io.FileParse;
-
/**
* Import and process PDB files with Jmol
*
jmolApp.startViewer(viewer, null);
} catch (ClassCastException x)
{
- throw new Error(
- "Jmol version "
- + JmolViewer.getJmolVersion()
- + " is not compatible with this version of Jalview. Report this problem at issues.jalview.org",
+ throw new Error(MessageManager.formatMessage("error.jmol_version_not_compatible_with_jalview_version", new String[]{JmolViewer.getJmolVersion()}),
x);
}
}
{
if (len > 0)
{
+ boolean isNa = (biopoly.isDna() || biopoly.isRna());
+ // normalise sequence from Jmol to jalview
+ int[] cinds = isNa ? ResidueProperties.nucleotideIndex : ResidueProperties.aaIndex;
+ int nonGap = isNa ? ResidueProperties.maxNucleotideIndex
+ : ResidueProperties.maxProteinIndex;
+ char ngc = 'X';
char newseq[] = new char[len];
- System.arraycopy(seq, 0, newseq, 0, len);
- Annotation asecstr[] = new Annotation[len];
+ Annotation asecstr[] = new Annotation[len+firstrnum-1];
for (int p = 0; p < len; p++)
{
+ newseq[p] = cinds[seq[p]] == nonGap ? ngc : seq[p];
if (secstr[p] >= 'A' && secstr[p] <= 'z')
{
asecstr[p] = new Annotation("" + secstr[p], null,
sq.addPDBId(pdbe);
pdbe.setProperty(new Hashtable());
pdbe.getProperty().put("CHAIN", "" + _lastChainId);
+ // JAL-1533
+ // Need to put the number of models for this polymer somewhere for Chimera/others to grab
+ // pdbe.getProperty().put("PDBMODELS", biopoly.)
seqs.add(sq);
- if (!(biopoly.isDna() || biopoly.isRna()))
+ if (!isNa)
{
AlignmentAnnotation ann = new AlignmentAnnotation(
"Secondary Structure",
"Secondary Structure from PDB File", asecstr);
+ ann.belowAlignment=true;
+ ann.visible=true;
+ ann.autoCalculated=false;
ann.setCalcId(getClass().getName());
sq.addAlignmentAnnotation(ann);
+ ann.adjustForAlignment();
+ ann.validateRangeAndDisplay();
annotations.add(ann);
}
}
case MEASURE:
String mystatus = (String) data[3];
if (mystatus.indexOf("Picked") >= 0
- || mystatus.indexOf("Sequence") >= 0) // picking mode
+ || mystatus.indexOf("Sequence") >= 0)
+ {
+ // Picking mode
sendConsoleMessage(strInfo);
+ }
else if (mystatus.indexOf("Completed") >= 0)
+ {
sendConsoleEcho(strInfo.substring(strInfo.lastIndexOf(",") + 2,
strInfo.length() - 1));
+ }
break;
case MESSAGE:
sendConsoleMessage(data == null ? null : strInfo);
*/
package jalview.ext.paradise;
+import jalview.util.MessageManager;
import jalview.ws.HttpClientUtils;
import java.io.IOException;
@Override
public void remove()
{
- throw new Error("Remove: Not implemented");
+ throw new Error(MessageManager.getString("error.not_implemented_remove"));
}
@Override
protected Object clone() throws CloneNotSupportedException
{
- throw new CloneNotSupportedException("Clone: Not implemented");
+ throw new CloneNotSupportedException(MessageManager.getString("error.not_implemented_clone"));
}
@Override
};
} catch (Exception foo)
{
- throw new Exception(
- "Couldn't parse response from Annotate3d server.", foo);
+ throw new Exception(MessageManager.getString("exception.couldnt_parse_responde_from_annotated3d_server"), foo);
}
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview 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.
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ext.rbvi.chimera;
+
+import jalview.api.FeatureRenderer;
+import jalview.api.SequenceRenderer;
+import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureMappingcommandSet;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.Format;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+/**
+ * Routines for generating Chimera commands for Jalview/Chimera binding
+ *
+ * @author JimP
+ *
+ */
+public class ChimeraCommands
+{
+
+ /**
+ * utility to construct the commands to colour chains by the given alignment
+ * for passing to Chimera
+ *
+ * @returns Object[] { Object[] { <model being coloured>,
+ *
+ */
+ public static StructureMappingcommandSet[] getColourBySequenceCommand(
+ StructureSelectionManager ssm, String[] files,
+ SequenceI[][] sequence, SequenceRenderer sr, FeatureRenderer fr,
+ AlignmentI alignment)
+ {
+
+ ArrayList<StructureMappingcommandSet> cset = new ArrayList<StructureMappingcommandSet>();
+ Hashtable<String,StringBuffer> colranges=new Hashtable<String,StringBuffer>();
+ for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+ {
+ float cols[] = new float[4];
+ StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
+ StringBuffer command = new StringBuffer();
+ StructureMappingcommandSet smc;
+ ArrayList<String> str = new ArrayList<String>();
+
+ if (mapping == null || mapping.length < 1)
+ continue;
+
+ int startPos = -1, lastPos = -1, startModel = -1, lastModel = -1;
+ String startChain = "", lastChain = "";
+ Color lastCol = null;
+ for (int s = 0; s < sequence[pdbfnum].length; s++)
+ {
+ for (int sp, m = 0; m < mapping.length; m++)
+ {
+ if (mapping[m].getSequence() == sequence[pdbfnum][s]
+ && (sp = alignment.findIndex(sequence[pdbfnum][s])) > -1)
+ {
+ SequenceI asp = alignment.getSequenceAt(sp);
+ for (int r = 0; r < asp.getLength(); r++)
+ {
+ // no mapping to gaps in sequence
+ if (jalview.util.Comparison.isGap(asp.getCharAt(r)))
+ {
+ continue;
+ }
+ int pos = mapping[m].getPDBResNum(asp.findPosition(r));
+
+ if (pos < 1 || pos == lastPos)
+ continue;
+
+ Color col = sr.getResidueBoxColour(sequence[pdbfnum][s], r);
+
+ if (fr != null)
+ col = fr.findFeatureColour(col, sequence[pdbfnum][s], r);
+ if (lastCol != col || lastPos + 1 != pos
+ || pdbfnum != lastModel
+ || !mapping[m].getChain().equals(lastChain))
+ {
+ if (lastCol != null)
+ {
+ addColourRange(colranges, lastCol,startModel,startPos,lastPos,lastChain);
+ }
+ lastCol = null;
+ startPos = pos;
+ startModel = pdbfnum;
+ startChain = mapping[m].getChain();
+ }
+ lastCol = col;
+ lastPos = pos;
+ lastModel = pdbfnum;
+ lastChain = mapping[m].getChain();
+ }
+ // final colour range
+ if (lastCol != null)
+ {
+ addColourRange(colranges, lastCol,startModel,startPos,lastPos,lastChain);
+ }
+ break;
+ }
+ }
+ }
+ // Finally, add the command set ready to be returned.
+ StringBuffer coms=new StringBuffer();
+ for (String cr:colranges.keySet())
+ {
+ coms.append("color #"+cr+" "+colranges.get(cr)+";");
+ }
+ cset.add(new StructureMappingcommandSet(ChimeraCommands.class,
+ files[pdbfnum], new String[] { coms.toString() }));
+ }
+ return cset.toArray(new StructureMappingcommandSet[cset.size()]);
+ }
+
+ private static void addColourRange(Hashtable<String, StringBuffer> colranges, Color lastCol, int startModel,
+ int startPos, int lastPos, String lastChain)
+ {
+
+ String colstring = ((lastCol.getRed()< 16) ? "0":"")+Integer.toHexString(lastCol.getRed())
+ + ((lastCol.getGreen()< 16) ? "0":"")+Integer.toHexString(lastCol.getGreen())
+ + ((lastCol.getBlue()< 16) ? "0":"")+Integer.toHexString(lastCol.getBlue());
+ StringBuffer currange = colranges.get(colstring);
+ if (currange==null)
+ {
+ colranges.put(colstring,currange = new StringBuffer());
+ }
+ if (currange.length()>0)
+ {
+ currange.append("|");
+ }
+ currange.append("#" + startModel + ":" + ((startPos==lastPos) ? startPos : startPos + "-"
+ + lastPos) + "." + lastChain);
+ }
+
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview 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.
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ext.rbvi.chimera;
+
+import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureRenderer;
+import jalview.api.SequenceRenderer;
+import jalview.api.SequenceStructureBinding;
+import jalview.api.StructureSelectionManagerProvider;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.io.AppletFormatAdapter;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureListener;
+import jalview.structure.StructureMapping;
+import jalview.structure.StructureSelectionManager;
+import jalview.structures.models.SequenceStructureBindingModel;
+import jalview.util.MessageManager;
+
+import java.awt.Color;
+import java.awt.event.ComponentEvent;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import ext.edu.ucsf.rbvi.strucviz2.ChimeraManager;
+import ext.edu.ucsf.rbvi.strucviz2.ChimeraModel;
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
+import ext.edu.ucsf.rbvi.strucviz2.StructureManager.ModelType;
+
+public abstract class JalviewChimeraBinding extends
+ SequenceStructureBindingModel implements StructureListener,
+ SequenceStructureBinding, StructureSelectionManagerProvider
+
+{
+ private static final String PHOSPHORUS = "P";
+
+ private static final String ALPHACARBON = "CA";
+
+ private StructureManager csm;
+
+ private ChimeraManager viewer;
+
+ /**
+ * set if chimera state is being restored from some source - instructs binding
+ * not to apply default display style when structure set is updated for first
+ * time.
+ */
+ private boolean loadingFromArchive = false;
+
+ /**
+ * second flag to indicate if the jmol viewer should ignore sequence colouring
+ * events from the structure manager because the GUI is still setting up
+ */
+ private boolean loadingFinished = true;
+
+ /**
+ * state flag used to check if the Jmol viewer's paint method can be called
+ */
+ private boolean finishedInit = false;
+
+ public boolean isFinishedInit()
+ {
+ return finishedInit;
+ }
+
+ public void setFinishedInit(boolean finishedInit)
+ {
+ this.finishedInit = finishedInit;
+ }
+
+ boolean allChainsSelected = false;
+
+ /**
+ * when true, try to search the associated datamodel for sequences that are
+ * associated with any unknown structures in the Chimera view.
+ */
+ private boolean associateNewStructs = false;
+
+ List<String> atomsPicked = new ArrayList<String>();
+
+ public List<String> chainNames;
+
+ private Map<String, String> chainFile;
+
+ /**
+ * array of target chains for sequences - tied to pdbentry and sequence[]
+ */
+ protected String[][] chains;
+
+ boolean colourBySequence = true;
+
+ StringBuffer eval = new StringBuffer();
+
+ public String fileLoadingError;
+
+ private Map<String, List<ChimeraModel>> chimmaps = new LinkedHashMap<String, List<ChimeraModel>>();
+
+ private List<String> mdlToFile = new ArrayList<String>();
+
+ /**
+ * the default or current model displayed if the model cannot be identified
+ * from the selection message
+ */
+ int frameNo = 0;
+
+ String lastCommand;
+
+ String lastMessage;
+
+ boolean loadedInline;
+
+ public boolean openFile(PDBEntry pe)
+ {
+ String file = pe.getFile();
+ try
+ {
+ List<ChimeraModel> oldList = viewer.getModelList();
+ viewer.openModel(file, pe.getId(), ModelType.PDB_MODEL);
+ List<ChimeraModel> newList = viewer.getModelList();
+ if (oldList.size() < newList.size())
+ {
+ while (oldList.size() > 0)
+ {
+ oldList.remove(0);
+ newList.remove(0);
+ }
+ chimmaps.put(file, newList);
+ for (ChimeraModel cm : newList)
+ {
+ while (mdlToFile.size() < 1 + cm.getModelNumber())
+ {
+ mdlToFile.add(new String(""));
+ }
+ mdlToFile.set(cm.getModelNumber(), file);
+ }
+
+ File fl = new File(file);
+ String protocol = AppletFormatAdapter.URL;
+ try
+ {
+ if (fl.exists())
+ {
+ protocol = AppletFormatAdapter.FILE;
+ }
+ } catch (Exception e)
+ {
+ } catch (Error e)
+ {
+ }
+ // Explicitly map to the filename used by Jmol ;
+ // pdbentry[pe].getFile(), protocol);
+
+ if (ssm != null)
+ {
+ ssm.addStructureViewerListener(this);
+ // ssm.addSelectionListener(this);
+ FeatureRenderer fr = getFeatureRenderer(null);
+ if (fr != null)
+ {
+ fr.featuresAdded();
+ }
+ refreshGUI();
+ }
+ return true;
+ }
+ } catch (Exception q)
+ {
+ log("Exception when trying to open model " + file + "\n"
+ + q.toString());
+ q.printStackTrace();
+ }
+ return false;
+ }
+
+ /**
+ * current set of model filenames loaded
+ */
+ String[] modelFileNames = null;
+
+ public PDBEntry[] pdbentry;
+
+ /**
+ * datasource protocol for access to PDBEntrylatest
+ */
+ String protocol = null;
+
+ StringBuffer resetLastRes = new StringBuffer();
+
+ /**
+ * sequences mapped to each pdbentry
+ */
+ public SequenceI[][] sequence;
+
+ public StructureSelectionManager ssm;
+
+ private List<String> lastReply;
+
+ public JalviewChimeraBinding(StructureSelectionManager ssm,
+ PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains,
+ String protocol)
+ {
+ this.ssm = ssm;
+ this.sequence = sequenceIs;
+ this.chains = chains;
+ this.pdbentry = pdbentry;
+ this.protocol = protocol;
+ if (chains == null)
+ {
+ this.chains = new String[pdbentry.length][];
+ }
+ viewer = new ChimeraManager(
+ csm = new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true));
+ /*
+ * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
+ * "jalviewJmol", ap.av.applet .getDocumentBase(),
+ * ap.av.applet.getCodeBase(), "", this);
+ *
+ * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
+ */
+ }
+
+ public JalviewChimeraBinding(StructureSelectionManager ssm,
+ ChimeraManager viewer2)
+ {
+ this.ssm = ssm;
+ viewer = viewer2;
+ csm = viewer.getStructureManager();
+ }
+
+ /**
+ * Construct a title string for the viewer window based on the data Jalview
+ * knows about
+ *
+ * @param verbose
+ * @return
+ */
+ public String getViewerTitle(boolean verbose)
+ {
+ if (sequence == null || pdbentry == null || sequence.length < 1
+ || pdbentry.length < 1 || sequence[0].length < 1)
+ {
+ return ("Jalview Chimera Window");
+ }
+ // TODO: give a more informative title when multiple structures are
+ // displayed.
+ StringBuilder title = new StringBuilder(64);
+ title.append("Chimera view for " + sequence[0][0].getName() + ":"
+ + pdbentry[0].getId());
+
+ if (verbose)
+ {
+ if (pdbentry[0].getProperty() != null)
+ {
+ if (pdbentry[0].getProperty().get("method") != null)
+ {
+ title.append(" Method: ");
+ title.append(pdbentry[0].getProperty().get("method"));
+ }
+ if (pdbentry[0].getProperty().get("chains") != null)
+ {
+ title.append(" Chain:");
+ title.append(pdbentry[0].getProperty().get("chains"));
+ }
+ }
+ }
+ return title.toString();
+ }
+
+ /**
+ * prepare the view for a given set of models/chains. chainList contains
+ * strings of the form 'pdbfilename:Chaincode'
+ *
+ * @param toshow
+ * list of chains to make visible
+ */
+ public void centerViewer(List<String> toshow)
+ {
+ StringBuilder cmd = new StringBuilder(64);
+ int mlength, p;
+ for (String lbl : toshow)
+ {
+ mlength = 0;
+ do
+ {
+ p = mlength;
+ mlength = lbl.indexOf(":", p);
+ } while (p < mlength && mlength < (lbl.length() - 2));
+ // TODO: lookup each pdb id and recover proper model number for it.
+ cmd.append("#" + getModelNum(chainFile.get(lbl)) + "."
+ + lbl.substring(mlength + 1) + " or ");
+ }
+ if (cmd.length() > 0)
+ {
+ cmd.setLength(cmd.length() - 4);
+ }
+ String cmdstring = cmd.toString();
+ evalStateCommand("~display #*; ~ribbon #*; ribbon " + cmdstring
+ + ";focus " + cmdstring, false);
+ }
+
+ /**
+ * Close down the Jalview viewer, and (optionally) the associate Chimera
+ * window.
+ */
+ public void closeViewer(boolean closeChimera)
+ {
+ ssm.removeStructureViewerListener(this, this.getPdbFile());
+ if (closeChimera)
+ {
+ viewer.exitChimera();
+ }
+ // viewer.evalStringQuiet("zap");
+ // viewer.setJmolStatusListener(null);
+ lastCommand = null;
+ viewer = null;
+ releaseUIResources();
+ }
+
+ /**
+ * called by JalviewJmolbinding after closeViewer is called - release any
+ * resources and references so they can be garbage collected.
+ */
+ protected abstract void releaseUIResources();
+
+ public void colourByChain()
+ {
+ colourBySequence = false;
+ // TODO: colour by chain should colour each chain distinctly across all
+ // visible models
+ // TODO: http://issues.jalview.org/browse/JAL-628
+ evalStateCommand("select *;color chain",false);
+ }
+
+ public void colourByCharge()
+ {
+ colourBySequence = false;
+ evalStateCommand("colour *;color white;select ASP,GLU;color red;"
+ + "select LYS,ARG;color blue;select CYS;color yellow", false);
+ }
+
+ /**
+ * superpose the structures associated with sequences in the alignment
+ * according to their corresponding positions.
+ */
+ public void superposeStructures(AlignmentI alignment)
+ {
+ superposeStructures(alignment, -1, null);
+ }
+
+ /**
+ * superpose the structures associated with sequences in the alignment
+ * according to their corresponding positions. ded)
+ *
+ * @param refStructure
+ * - select which pdb file to use as reference (default is -1 - the
+ * first structure in the alignment)
+ */
+ public void superposeStructures(AlignmentI alignment, int refStructure)
+ {
+ superposeStructures(alignment, refStructure, null);
+ }
+
+ /**
+ * superpose the structures associated with sequences in the alignment
+ * according to their corresponding positions. ded)
+ *
+ * @param refStructure
+ * - select which pdb file to use as reference (default is -1 - the
+ * first structure in the alignment)
+ * @param hiddenCols
+ * TODO
+ */
+ public void superposeStructures(AlignmentI alignment, int refStructure,
+ ColumnSelection hiddenCols)
+ {
+ superposeStructures(new AlignmentI[]
+ { alignment }, new int[]
+ { refStructure }, new ColumnSelection[]
+ { hiddenCols });
+ }
+
+ public void superposeStructures(AlignmentI[] _alignment,
+ int[] _refStructure, ColumnSelection[] _hiddenCols)
+ {
+ assert (_alignment.length == _refStructure.length && _alignment.length != _hiddenCols.length);
+ StringBuilder allComs = new StringBuilder(128); // Chimera superposition cmd
+ String[] files = getPdbFile();
+ // check to see if we are still waiting for Jmol files
+ long starttime = System.currentTimeMillis();
+ boolean waiting = true;
+ do
+ {
+ waiting = false;
+ for (String file : files)
+ {
+ try
+ {
+ // HACK - in Jalview 2.8 this call may not be threadsafe so we catch
+ // every possible exception
+ StructureMapping[] sm = ssm.getMapping(file);
+ if (sm == null || sm.length == 0)
+ {
+ waiting = true;
+ }
+ } catch (Exception x)
+ {
+ waiting = true;
+ } catch (Error q)
+ {
+ waiting = true;
+ }
+ }
+ // we wait around for a reasonable time before we give up
+ } while (waiting
+ && System.currentTimeMillis() < (10000 + 1000 * files.length + starttime));
+ if (waiting)
+ {
+ System.err
+ .println("RUNTIME PROBLEM: Chimera seems to be taking a long time to process all the structures.");
+ return;
+ }
+ refreshPdbEntries();
+ StringBuffer selectioncom = new StringBuffer();
+ for (int a = 0; a < _alignment.length; a++)
+ {
+ int refStructure = _refStructure[a];
+ AlignmentI alignment = _alignment[a];
+ ColumnSelection hiddenCols = _hiddenCols[a];
+ if (a > 0
+ && selectioncom.length() > 0
+ && !selectioncom.substring(selectioncom.length() - 1).equals(
+ " "))
+ {
+ selectioncom.append(" ");
+ }
+ // process this alignment
+ if (refStructure >= files.length)
+ {
+ System.err.println("Invalid reference structure value "
+ + refStructure);
+ refStructure = -1;
+ }
+ if (refStructure < -1)
+ {
+ refStructure = -1;
+ }
+
+ boolean matched[] = new boolean[alignment.getWidth()];
+ for (int m = 0; m < matched.length; m++)
+ {
+
+ matched[m] = (hiddenCols != null) ? hiddenCols.isVisible(m) : true;
+ }
+
+ int commonrpositions[][] = new int[files.length][alignment.getWidth()];
+ String isel[] = new String[files.length];
+ String[] targetC = new String[files.length];
+ String[] chainNames = new String[files.length];
+ String[] atomSpec = new String[files.length];
+ for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+ {
+ StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
+ // RACE CONDITION - getMapping only returns Jmol loaded filenames once
+ // Jmol callback has completed.
+ if (mapping == null || mapping.length < 1)
+ {
+ throw new Error(MessageManager.getString("error.implementation_error_chimera_getting_data"));
+ }
+ int lastPos = -1;
+ for (int s = 0; s < sequence[pdbfnum].length; s++)
+ {
+ for (int sp, m = 0; m < mapping.length; m++)
+ {
+ if (mapping[m].getSequence() == sequence[pdbfnum][s]
+ && (sp = alignment.findIndex(sequence[pdbfnum][s])) > -1)
+ {
+ if (refStructure == -1)
+ {
+ refStructure = pdbfnum;
+ }
+ SequenceI asp = alignment.getSequenceAt(sp);
+ for (int r = 0; r < matched.length; r++)
+ {
+ if (!matched[r])
+ {
+ continue;
+ }
+ matched[r] = false; // assume this is not a good site
+ if (r >= asp.getLength())
+ {
+ continue;
+ }
+
+ if (jalview.util.Comparison.isGap(asp.getCharAt(r)))
+ {
+ // no mapping to gaps in sequence
+ continue;
+ }
+ int t = asp.findPosition(r); // sequence position
+ int apos = mapping[m].getAtomNum(t);
+ int pos = mapping[m].getPDBResNum(t);
+
+ if (pos < 1 || pos == lastPos)
+ {
+ // can't align unmapped sequence
+ continue;
+ }
+ matched[r] = true; // this is a good ite
+ lastPos = pos;
+ // just record this residue position
+ commonrpositions[pdbfnum][r] = pos;
+ }
+ // create model selection suffix
+ isel[pdbfnum] = "#" + pdbfnum;
+ if (mapping[m].getChain() == null
+ || mapping[m].getChain().trim().length() == 0)
+ {
+ targetC[pdbfnum] = "";
+ }
+ else
+ {
+ targetC[pdbfnum] = "." + mapping[m].getChain();
+ }
+ chainNames[pdbfnum] = mapping[m].getPdbId()
+ + targetC[pdbfnum];
+ atomSpec[pdbfnum] = asp.getRNA() != null ? PHOSPHORUS : ALPHACARBON;
+ // move on to next pdb file
+ s = sequence[pdbfnum].length;
+ break;
+ }
+ }
+ }
+ }
+
+ // TODO: consider bailing if nmatched less than 4 because superposition
+ // not
+ // well defined.
+ // TODO: refactor superposable position search (above) from jmol selection
+ // construction (below)
+
+ String[] selcom = new String[files.length];
+ int nmatched = 0;
+ String sep = "";
+ // generate select statements to select regions to superimpose structures
+ {
+ for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+ {
+ String chainCd = targetC[pdbfnum];
+ int lpos = -1;
+ boolean run = false;
+ StringBuffer molsel = new StringBuffer();
+ for (int r = 0; r < matched.length; r++)
+ {
+ if (matched[r])
+ {
+ if (pdbfnum == 0)
+ {
+ nmatched++;
+ }
+ if (lpos != commonrpositions[pdbfnum][r] - 1)
+ {
+ // discontinuity
+ if (lpos != -1)
+ {
+ molsel.append((run ? "" : ":") + lpos);
+ molsel.append(chainCd);
+ molsel.append(",");
+ }
+ }
+ else
+ {
+ // continuous run - and lpos >-1
+ if (!run)
+ {
+ // at the beginning, so add dash
+ molsel.append(":" + lpos);
+ molsel.append("-");
+ }
+ run = true;
+ }
+ lpos = commonrpositions[pdbfnum][r];
+ // molsel.append(lpos);
+ }
+ }
+ // add final selection phrase
+ if (lpos != -1)
+ {
+ molsel.append((run ? "" : ":") + lpos);
+ molsel.append(chainCd);
+ // molsel.append("");
+ }
+ if (molsel.length() > 1)
+ {
+ selcom[pdbfnum] = molsel.toString();
+ selectioncom.append("#" + pdbfnum);
+ selectioncom.append(selcom[pdbfnum]);
+ selectioncom.append(" ");
+ if (pdbfnum < files.length - 1)
+ {
+ selectioncom.append("| ");
+ }
+ }
+ else
+ {
+ selcom[pdbfnum] = null;
+ }
+ }
+ }
+ StringBuilder command = new StringBuilder(256);
+ for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
+ {
+ if (pdbfnum == refStructure || selcom[pdbfnum] == null
+ || selcom[refStructure] == null)
+ {
+ continue;
+ }
+ if (command.length() > 0)
+ {
+ command.append(";");
+ }
+
+ /*
+ * Form Chimera match command, from the 'new' structure to the
+ * 'reference' structure e.g. (residues 1-91, chain B/A, alphacarbons):
+ *
+ * match #1:1-91.B@CA #0:1-91.A@CA
+ *
+ * @see
+ * https://www.cgl.ucsf.edu/chimera/docs/UsersGuide/midas/match.html
+ */
+ command.append("match #" + pdbfnum /* +".1" */);
+ // TODO: handle sub-models
+ command.append(selcom[pdbfnum]);
+ command.append("@" + atomSpec[pdbfnum]);
+ command.append(" #" + refStructure /* +".1" */);
+ command.append(selcom[refStructure]);
+ command.append("@" + atomSpec[refStructure]);
+ }
+ if (selectioncom.length() > 0)
+ {
+ // TODO remove debug output
+ System.out.println("Select regions:\n" + selectioncom.toString());
+ System.out
+ .println("Superimpose command(s):\n" + command.toString());
+ allComs.append("~display all; chain @CA|P; ribbon "
+ + selectioncom.toString() + ";"+command.toString());
+ // selcom.append("; ribbons; ");
+ }
+ }
+ if (selectioncom.length() > 0)
+ {// finally, mark all regions that were superposed.
+ if (selectioncom.substring(selectioncom.length() - 1).equals("|"))
+ {
+ selectioncom.setLength(selectioncom.length() - 1);
+ }
+ System.out.println("Select regions:\n" + selectioncom.toString());
+ allComs.append("; ~display all; chain @CA|P; ribbon "
+ + selectioncom.toString() + "; focus");
+ // evalStateCommand("select *; backbone; select "+selcom.toString()+"; cartoons; center "+selcom.toString());
+ evalStateCommand(allComs.toString(), true /* false */);
+ }
+
+ }
+
+ private void checkLaunched()
+ {
+ if (!viewer.isChimeraLaunched())
+ {
+ viewer.launchChimera(csm.getChimeraPaths());
+ }
+ if (!viewer.isChimeraLaunched())
+ {
+ log("Failed to launch Chimera!");
+ }
+ }
+
+ /**
+ * Answers true if the Chimera process is still running, false if ended or not
+ * started.
+ *
+ * @return
+ */
+ public boolean isChimeraRunning()
+ {
+ return viewer.isChimeraLaunched();
+ }
+
+ /**
+ * Send a command to Chimera, and optionally log any responses.
+ *
+ * @param command
+ * @param logResponse
+ */
+ public void evalStateCommand(final String command, boolean logResponse)
+ {
+ viewerCommandHistory(false);
+ checkLaunched();
+ if (lastCommand == null || !lastCommand.equals(command))
+ {
+// Thread t = new Thread(new Runnable()
+// {
+// @Override
+// public void run()
+// {
+ // trim command or it may never find a match in the replyLog!!
+ lastReply = viewer.sendChimeraCommand(command.trim(), logResponse);
+ if (debug && logResponse)
+ {
+ log("Response from command ('" + command + "') was:\n"
+ + lastReply);
+ }
+// }
+// });
+ // TODO - use j7/8 thread management
+// try
+// {
+// t.join();
+// } catch (InterruptedException foo)
+// {
+// }
+// ;
+ }
+ viewerCommandHistory(true);
+ lastCommand = command;
+ }
+
+ /**
+ * colour any structures associated with sequences in the given alignment
+ * using the getFeatureRenderer() and getSequenceRenderer() renderers but only
+ * if colourBySequence is enabled.
+ */
+ public void colourBySequence(boolean showFeatures,
+ jalview.api.AlignmentViewPanel alignmentv)
+ {
+ if (!colourBySequence || !loadingFinished)
+ {
+ return;
+ }
+ if (ssm == null)
+ {
+ return;
+ }
+ String[] files = getPdbFile();
+
+ SequenceRenderer sr = getSequenceRenderer(alignmentv);
+
+ FeatureRenderer fr = null;
+ if (showFeatures)
+ {
+ fr = getFeatureRenderer(alignmentv);
+ }
+ AlignmentI alignment = alignmentv.getAlignment();
+
+ for (jalview.structure.StructureMappingcommandSet cpdbbyseq : ChimeraCommands
+ .getColourBySequenceCommand(ssm, files, sequence, sr, fr,
+ alignment))
+ {
+ for (String cbyseq : cpdbbyseq.commands)
+ {
+ waitForChimera();
+ evalStateCommand(cbyseq, false);
+ waitForChimera();
+ }
+ }
+ }
+
+ private void waitForChimera()
+ {
+ while (viewer.isBusy())
+ {
+ try {
+ Thread.sleep(15);
+ } catch (InterruptedException q)
+ {}
+ }
+ }
+
+ public boolean isColourBySequence()
+ {
+ return colourBySequence;
+ }
+
+ public void setColourBySequence(boolean colourBySequence)
+ {
+ this.colourBySequence = colourBySequence;
+ }
+
+ // End StructureListener
+ // //////////////////////////
+
+ public float[][] functionXY(String functionName, int x, int y)
+ {
+ return null;
+ }
+
+ public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Color getColour(int atomIndex, int pdbResNum, String chain,
+ String pdbfile)
+ {
+ if (getModelNum(pdbfile) < 0)
+ {
+ return null;
+ }
+ log("get model / residue colour attribute unimplemented");
+ return null;
+ }
+
+ /**
+ * returns the current featureRenderer that should be used to colour the
+ * structures
+ *
+ * @param alignment
+ *
+ * @return
+ */
+ public abstract FeatureRenderer getFeatureRenderer(
+ AlignmentViewPanel alignment);
+
+ /**
+ * instruct the Jalview binding to update the pdbentries vector if necessary
+ * prior to matching the jmol view's contents to the list of structure files
+ * Jalview knows about.
+ */
+ public abstract void refreshPdbEntries();
+
+ private int getModelNum(String modelFileName)
+ {
+ String[] mfn = getPdbFile();
+ if (mfn == null)
+ {
+ return -1;
+ }
+ for (int i = 0; i < mfn.length; i++)
+ {
+ if (mfn[i].equalsIgnoreCase(modelFileName))
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * map between index of model filename returned from getPdbFile and the first
+ * index of models from this file in the viewer. Note - this is not trimmed -
+ * use getPdbFile to get number of unique models.
+ */
+ private int _modelFileNameMap[];
+
+ // ////////////////////////////////
+ // /StructureListener
+ public synchronized String[] getPdbFile()
+ {
+ if (viewer == null)
+ {
+ return new String[0];
+ }
+ // if (modelFileNames == null)
+ // {
+ // Collection<ChimeraModel> chimodels = viewer.getChimeraModels();
+ // _modelFileNameMap = new int[chimodels.size()];
+ // int j = 0;
+ // for (ChimeraModel chimodel : chimodels)
+ // {
+ // String mdlName = chimodel.getModelName();
+ // }
+ // modelFileNames = new String[j];
+ // // System.arraycopy(mset, 0, modelFileNames, 0, j);
+ // }
+
+ return chimmaps.keySet().toArray(
+ modelFileNames = new String[chimmaps.size()]);
+ }
+
+ /**
+ * map from string to applet
+ */
+ public Map getRegistryInfo()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * returns the current sequenceRenderer that should be used to colour the
+ * structures
+ *
+ * @param alignment
+ *
+ * @return
+ */
+ public abstract SequenceRenderer getSequenceRenderer(
+ AlignmentViewPanel alignment);
+
+ // jmol/ssm only
+ public void highlightAtom(int atomIndex, int pdbResNum, String chain,
+ String pdbfile)
+ {
+ List<ChimeraModel> cms = chimmaps.get(pdbfile);
+ if (cms != null)
+ {
+ int mdlNum = cms.get(0).getModelNumber();
+
+ viewerCommandHistory(false);
+ // viewer.stopListening();
+ if (resetLastRes.length() > 0)
+ {
+ eval.setLength(0);
+ eval.append(resetLastRes.toString() + ";");
+ }
+
+ eval.append("display "); // +modelNum
+
+ resetLastRes.setLength(0);
+ resetLastRes.append("~display ");
+ {
+ eval.append(" #" + (mdlNum));
+ resetLastRes.append(" #" + (mdlNum));
+ }
+ // complete select string
+
+ eval.append(":" + pdbResNum);
+ resetLastRes.append(":" + pdbResNum);
+ if (!chain.equals(" "))
+ {
+ eval.append("." + chain);
+ resetLastRes.append("." + chain);
+ }
+
+ viewer.sendChimeraCommand(eval.toString(), false);
+ viewerCommandHistory(true);
+ // viewer.startListening();
+ }
+ }
+
+ boolean debug = true;
+
+ private void log(String message)
+ {
+ System.err.println("## Chimera log: " + message);
+ }
+
+ private void viewerCommandHistory(boolean enable)
+ {
+ log("(Not yet implemented) History "
+ + ((debug || enable) ? "on" : "off"));
+ }
+
+ public void loadInline(String string)
+ {
+ loadedInline = true;
+ // TODO: re JAL-623
+ // viewer.loadInline(strModel, isAppend);
+ // could do this:
+ // construct fake fullPathName and fileName so we can identify the file
+ // later.
+ // Then, construct pass a reader for the string to Jmol.
+ // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
+ // fileName, null, reader, false, null, null, 0);
+ // viewer.openStringInline(string);
+ log("cannot load inline in Chimera, yet");
+ }
+
+ public void mouseOverStructure(int atomIndex, String strInfo)
+ {
+ // function to parse a mouseOver event from Chimera
+ //
+ int pdbResNum;
+ int alocsep = strInfo.indexOf("^");
+ int mdlSep = strInfo.indexOf("/");
+ int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
+
+ if (chainSeparator == -1)
+ {
+ chainSeparator = strInfo.indexOf(".");
+ if (mdlSep > -1 && mdlSep < chainSeparator)
+ {
+ chainSeparator1 = chainSeparator;
+ chainSeparator = mdlSep;
+ }
+ }
+ // handle insertion codes
+ if (alocsep != -1)
+ {
+ pdbResNum = Integer.parseInt(strInfo.substring(
+ strInfo.indexOf("]") + 1, alocsep));
+
+ }
+ else
+ {
+ pdbResNum = Integer.parseInt(strInfo.substring(
+ strInfo.indexOf("]") + 1, chainSeparator));
+ }
+ String chainId;
+
+ if (strInfo.indexOf(":") > -1)
+ {
+ chainId = strInfo.substring(strInfo.indexOf(":") + 1,
+ strInfo.indexOf("."));
+ }
+ else
+ {
+ chainId = " ";
+ }
+
+ String pdbfilename = modelFileNames[frameNo]; // default is first or current
+ // model
+ if (mdlSep > -1)
+ {
+ if (chainSeparator1 == -1)
+ {
+ chainSeparator1 = strInfo.indexOf(".", mdlSep);
+ }
+ String mdlId = (chainSeparator1 > -1) ? strInfo.substring(mdlSep + 1,
+ chainSeparator1) : strInfo.substring(mdlSep + 1);
+ try
+ {
+ // recover PDB filename for the model hovered over.
+ int _mp = _modelFileNameMap.length - 1, mnumber = new Integer(mdlId)
+ .intValue() - 1;
+ while (mnumber < _modelFileNameMap[_mp])
+ {
+ _mp--;
+ }
+ pdbfilename = modelFileNames[_mp];
+ if (pdbfilename == null)
+ {
+ // pdbfilename = new File(viewer.getModelFileName(mnumber))
+ // .getAbsolutePath();
+ }
+
+ } catch (Exception e)
+ {
+ }
+ ;
+ }
+ if (lastMessage == null || !lastMessage.equals(strInfo))
+ {
+ ssm.mouseOverStructure(pdbResNum, chainId, pdbfilename);
+ }
+
+ lastMessage = strInfo;
+ }
+
+ public void notifyAtomPicked(int atomIndex, String strInfo, String strData)
+ {
+ /**
+ * this implements the toggle label behaviour copied from the original
+ * structure viewer, MCView
+ */
+ if (strData != null)
+ {
+ System.err.println("Ignoring additional pick data string " + strData);
+ }
+ // rewrite these selections for chimera (DNA, RNA and protein)
+ int chainSeparator = strInfo.indexOf(":");
+ int p = 0;
+ if (chainSeparator == -1)
+ {
+ chainSeparator = strInfo.indexOf(".");
+ }
+
+ String picked = strInfo.substring(strInfo.indexOf("]") + 1,
+ chainSeparator);
+ String mdlString = "";
+ if ((p = strInfo.indexOf(":")) > -1)
+ {
+ picked += strInfo.substring(p + 1, strInfo.indexOf("."));
+ }
+
+ if ((p = strInfo.indexOf("/")) > -1)
+ {
+ mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
+ }
+ picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
+ + mdlString + "))";
+ viewerCommandHistory(false);
+
+ if (!atomsPicked.contains(picked))
+ {
+ viewer.select(picked);
+ atomsPicked.add(picked);
+ }
+ else
+ {
+ viewer.select("not " + picked);
+ atomsPicked.remove(picked);
+ }
+ viewerCommandHistory(true);
+ // TODO: in application this happens
+ //
+ // if (scriptWindow != null)
+ // {
+ // scriptWindow.sendConsoleMessage(strInfo);
+ // scriptWindow.sendConsoleMessage("\n");
+ // }
+
+ }
+
+ // incremented every time a load notification is successfully handled -
+ // lightweight mechanism for other threads to detect when they can start
+ // referring to new structures.
+ private long loadNotifiesHandled = 0;
+
+ public long getLoadNotifiesHandled()
+ {
+ return loadNotifiesHandled;
+ }
+
+ public void notifyFileLoaded(String fullPathName, String fileName2,
+ String modelName, String errorMsg, int modelParts)
+ {
+ if (errorMsg != null)
+ {
+ fileLoadingError = errorMsg;
+ refreshGUI();
+ return;
+ }
+ // TODO: deal sensibly with models loaded inLine:
+ // modelName will be null, as will fullPathName.
+
+ // the rest of this routine ignores the arguments, and simply interrogates
+ // the Jmol view to find out what structures it contains, and adds them to
+ // the structure selection manager.
+ fileLoadingError = null;
+ String[] oldmodels = modelFileNames;
+ modelFileNames = null;
+ chainNames = new ArrayList<String>();
+ chainFile = new HashMap<String, String>();
+ boolean notifyLoaded = false;
+ String[] modelfilenames = getPdbFile();
+ // first check if we've lost any structures
+ if (oldmodels != null && oldmodels.length > 0)
+ {
+ int oldm = 0;
+ for (int i = 0; i < oldmodels.length; i++)
+ {
+ for (int n = 0; n < modelfilenames.length; n++)
+ {
+ if (modelfilenames[n] == oldmodels[i])
+ {
+ oldmodels[i] = null;
+ break;
+ }
+ }
+ if (oldmodels[i] != null)
+ {
+ oldm++;
+ }
+ }
+ if (oldm > 0)
+ {
+ String[] oldmfn = new String[oldm];
+ oldm = 0;
+ for (int i = 0; i < oldmodels.length; i++)
+ {
+ if (oldmodels[i] != null)
+ {
+ oldmfn[oldm++] = oldmodels[i];
+ }
+ }
+ // deregister the Jmol instance for these structures - we'll add
+ // ourselves again at the end for the current structure set.
+ ssm.removeStructureViewerListener(this, oldmfn);
+ }
+ }
+
+ // register ourselves as a listener and notify the gui that it needs to
+ // update itself.
+ ssm.addStructureViewerListener(this);
+
+ if (notifyLoaded)
+ {
+ FeatureRenderer fr = getFeatureRenderer(null);
+ if (fr != null)
+ {
+ fr.featuresAdded();
+ }
+ refreshGUI();
+ loadNotifiesHandled++;
+ }
+ setLoadingFromArchive(false);
+ }
+
+ public void setJalviewColourScheme(ColourSchemeI cs)
+ {
+ colourBySequence = false;
+
+ if (cs == null)
+ {
+ return;
+ }
+
+ String res;
+ int index;
+ Color col;
+ viewerCommandHistory(false);
+ // TODO: Switch between nucleotide or aa selection expressions
+ Enumeration en = ResidueProperties.aa3Hash.keys();
+ StringBuffer command = new StringBuffer("select *;color white;");
+ while (en.hasMoreElements())
+ {
+ res = en.nextElement().toString();
+ index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue();
+ if (index > 20)
+ {
+ continue;
+ }
+
+ col = cs.findColour(ResidueProperties.aa[index].charAt(0));
+ // TODO: need colour string function and res selection here
+ command.append("select " + res + ";color[" + col.getRed() + ","
+ + col.getGreen() + "," + col.getBlue() + "];");
+ }
+
+ evalStateCommand(command.toString(),false);
+ viewerCommandHistory(true);
+ }
+
+ public void showHelp()
+ {
+ // chimera help
+ showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
+ }
+
+ /**
+ * open the URL somehow
+ *
+ * @param target
+ */
+ public abstract void showUrl(String url, String target);
+
+ /**
+ * called when the binding thinks the UI needs to be refreshed after a Jmol
+ * state change. this could be because structures were loaded, or because an
+ * error has occured.
+ */
+ public abstract void refreshGUI();
+
+ public void componentResized(ComponentEvent e)
+ {
+
+ }
+
+ public void componentMoved(ComponentEvent e)
+ {
+
+ }
+
+ public void componentShown(ComponentEvent e)
+ {
+ }
+
+ public void componentHidden(ComponentEvent e)
+ {
+ }
+
+ public void setLoadingFromArchive(boolean loadingFromArchive)
+ {
+ this.loadingFromArchive = loadingFromArchive;
+ }
+
+ /**
+ *
+ * @return true if Jmol is still restoring state or loading is still going on
+ * (see setFinsihedLoadingFromArchive)
+ */
+ public boolean isLoadingFromArchive()
+ {
+ return loadingFromArchive && !loadingFinished;
+ }
+
+ /**
+ * modify flag which controls if sequence colouring events are honoured by the
+ * binding. Should be true for normal operation
+ *
+ * @param finishedLoading
+ */
+ public void setFinishedLoadingFromArchive(boolean finishedLoading)
+ {
+ loadingFinished = finishedLoading;
+ }
+
+ public void setBackgroundColour(java.awt.Color col)
+ {
+ viewerCommandHistory(false);
+ // todo set background colour
+ viewer.sendChimeraCommand(
+ "background [" + col.getRed() + "," + col.getGreen() + ","
+ + col.getBlue() + "];", false);
+ viewerCommandHistory(true);
+ }
+
+ /**
+ * add structures and any known sequence associations
+ *
+ * @returns the pdb entries added to the current set.
+ */
+ public synchronized PDBEntry[] addSequenceAndChain(PDBEntry[] pdbe,
+ SequenceI[][] seq, String[][] chns)
+ {
+ List<PDBEntry> v = new ArrayList<PDBEntry>();
+ List<int[]> rtn = new ArrayList<int[]>();
+ for (int i = 0; i < pdbentry.length; i++)
+ {
+ v.add(pdbentry[i]);
+ }
+ for (int i = 0; i < pdbe.length; i++)
+ {
+ int r = v.indexOf(pdbe[i]);
+ if (r == -1 || r >= pdbentry.length)
+ {
+ rtn.add(new int[]
+ { v.size(), i });
+ v.add(pdbe[i]);
+ }
+ else
+ {
+ // just make sure the sequence/chain entries are all up to date
+ addSequenceAndChain(r, seq[i], chns[i]);
+ }
+ }
+ pdbe = v.toArray(new PDBEntry[v.size()]);
+ pdbentry = pdbe;
+ if (rtn.size() > 0)
+ {
+ // expand the tied sequence[] and string[] arrays
+ SequenceI[][] sqs = new SequenceI[pdbentry.length][];
+ String[][] sch = new String[pdbentry.length][];
+ System.arraycopy(sequence, 0, sqs, 0, sequence.length);
+ System.arraycopy(chains, 0, sch, 0, this.chains.length);
+ sequence = sqs;
+ chains = sch;
+ pdbe = new PDBEntry[rtn.size()];
+ for (int r = 0; r < pdbe.length; r++)
+ {
+ int[] stri = (rtn.get(r));
+ // record the pdb file as a new addition
+ pdbe[r] = pdbentry[stri[0]];
+ // and add the new sequence/chain entries
+ addSequenceAndChain(stri[0], seq[stri[1]], chns[stri[1]]);
+ }
+ }
+ else
+ {
+ pdbe = null;
+ }
+ return pdbe;
+ }
+
+ /**
+ * Adds sequences to the pe'th pdbentry's sequence set.
+ *
+ * @param pe
+ * @param seq
+ */
+ public void addSequence(int pe, SequenceI[] seq)
+ {
+ addSequenceAndChain(pe, seq, null);
+ }
+
+ private void addSequenceAndChain(int pe, SequenceI[] seq, String[] tchain)
+ {
+ if (pe < 0 || pe >= pdbentry.length)
+ {
+ throw new Error(MessageManager.formatMessage(
+ "error.implementation_error_no_pdbentry_from_index",
+ new Object[]
+ { Integer.valueOf(pe).toString() }));
+ }
+ final String nullChain = "TheNullChain";
+ List<SequenceI> s = new ArrayList<SequenceI>();
+ List<String> c = new ArrayList<String>();
+ if (chains == null)
+ {
+ chains = new String[pdbentry.length][];
+ }
+ if (sequence[pe] != null)
+ {
+ for (int i = 0; i < sequence[pe].length; i++)
+ {
+ s.add(sequence[pe][i]);
+ if (chains[pe] != null)
+ {
+ if (i < chains[pe].length)
+ {
+ c.add(chains[pe][i]);
+ }
+ else
+ {
+ c.add(nullChain);
+ }
+ }
+ else
+ {
+ if (tchain != null && tchain.length > 0)
+ {
+ c.add(nullChain);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < seq.length; i++)
+ {
+ if (!s.contains(seq[i]))
+ {
+ s.add(seq[i]);
+ if (tchain != null && i < tchain.length)
+ {
+ c.add(tchain[i] == null ? nullChain : tchain[i]);
+ }
+ }
+ }
+ SequenceI[] tmp = s.toArray(new SequenceI[s.size()]);
+ sequence[pe] = tmp;
+ if (c.size() > 0)
+ {
+ String[] tch = c.toArray(new String[c.size()]);
+ for (int i = 0; i < tch.length; i++)
+ {
+ if (tch[i] == nullChain)
+ {
+ tch[i] = null;
+ }
+ }
+ chains[pe] = tch;
+ }
+ else
+ {
+ chains[pe] = null;
+ }
+ }
+
+ /**
+ *
+ * @param pdbfile
+ * @return text report of alignment between pdbfile and any associated
+ * alignment sequences
+ */
+ public String printMapping(String pdbfile)
+ {
+ return ssm.printMapping(pdbfile);
+ }
+
+}
import jalview.api.SequenceStructureBinding;
import jalview.api.StructureSelectionManagerProvider;
import jalview.structure.*;
+import jalview.structures.models.SequenceStructureBindingModel;
-public abstract class JalviewVarnaBinding implements StructureListener,
+public abstract class JalviewVarnaBinding extends SequenceStructureBindingModel implements StructureListener,
SequenceStructureBinding, ComponentListener,
StructureSelectionManagerProvider
import jalview.datamodel.SequenceI;
import jalview.io.AlignmentProperties;
import jalview.io.AnnotationFile;
+import jalview.io.BioJsHTMLOutput;
import jalview.io.FeaturesFile;
import jalview.io.FileLoader;
import jalview.io.FormatAdapter;
int width, int height, String sequenceSetId, String viewId)
{
setSize(width, height);
- viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
-
- alignPanel = new AlignmentPanel(this, viewport);
if (al.getDataset() == null)
{
al.setDataset(null);
}
+ viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
+
+ alignPanel = new AlignmentPanel(this, viewport);
+
+
addAlignmentPanel(alignPanel, true);
init();
}
/**
- * Make a new AlignFrame from exisiting alignmentPanels
+ * Make a new AlignFrame from existing alignmentPanels
*
* @param ap
* AlignmentPanel
setMenusFromViewport(viewport);
buildSortByAnnotationScoresMenu();
buildTreeMenu();
+
if (viewport.wrapAlignment)
{
wrapMenuItem_actionPerformed(null);
.getKeyCode() >= KeyEvent.VK_NUMPAD0 && evt
.getKeyCode() <= KeyEvent.VK_NUMPAD9))
&& Character.isDigit(evt.getKeyChar()))
+ {
alignPanel.seqPanel.numberPressed(evt.getKeyChar());
+ }
switch (evt.getKeyCode())
{
case KeyEvent.VK_DOWN:
if (evt.isAltDown() || !viewport.cursorMode)
+ {
moveSelectedSequences(false);
+ }
if (viewport.cursorMode)
+ {
alignPanel.seqPanel.moveCursor(0, 1);
+ }
break;
case KeyEvent.VK_UP:
if (evt.isAltDown() || !viewport.cursorMode)
+ {
moveSelectedSequences(true);
+ }
if (viewport.cursorMode)
+ {
alignPanel.seqPanel.moveCursor(0, -1);
+ }
break;
case KeyEvent.VK_LEFT:
if (evt.isAltDown() || !viewport.cursorMode)
+ {
slideSequences(false, alignPanel.seqPanel.getKeyboardNo1());
+ }
else
+ {
alignPanel.seqPanel.moveCursor(-1, 0);
+ }
break;
case KeyEvent.VK_RIGHT:
if (evt.isAltDown() || !viewport.cursorMode)
+ {
slideSequences(true, alignPanel.seqPanel.getKeyboardNo1());
+ }
else
+ {
alignPanel.seqPanel.moveCursor(1, 0);
+ }
break;
case KeyEvent.VK_SPACE:
case KeyEvent.VK_F1:
try
{
- ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
- java.net.URL url = javax.help.HelpSet.findHelpSet(cl,
- "help/help");
- javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
-
- javax.help.HelpBroker hb = hs.createHelpBroker();
- hb.setCurrentID("home");
- hb.setDisplayed(true);
+ Help.showHelpWindow();
} catch (Exception ex)
{
ex.printStackTrace();
{
case KeyEvent.VK_LEFT:
if (evt.isAltDown() || !viewport.cursorMode)
+ {
viewport.firePropertyChange("alignment", null, viewport
.getAlignment().getSequences());
+ }
break;
case KeyEvent.VK_RIGHT:
if (evt.isAltDown() || !viewport.cursorMode)
+ {
viewport.firePropertyChange("alignment", null, viewport
.getAlignment().getSequences());
+ }
break;
}
}
scaleLeft.setVisible(av.wrapAlignment);
scaleRight.setVisible(av.wrapAlignment);
annotationPanelMenuItem.setState(av.showAnnotation);
+ /*
+ * Show/hide annotations only enabled if annotation panel is shown
+ */
+ showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
+ hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
+ showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
+ hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
viewBoxesMenuItem.setSelected(av.showBoxes);
viewTextMenuItem.setSelected(av.showText);
showNonconservedMenuItem.setSelected(av.getShowUnconserved());
{
if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
{
- throw new Error(
- "call setProgressBar before registering the progress bar's handler.");
+ throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
}
progressBarHandlers.put(new Long(id), handler);
final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
public void actionPerformed(ActionEvent e)
{
handler.cancelActivity(id);
- us.setProgressBar(
- "Cancelled "
- + ((JLabel) progressPanel.getComponent(0))
- .getText(), id);
+ us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
}
});
progressPanel.add(cancel, BorderLayout.EAST);
currentFileFormat, false);
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Save Alignment to file");
+ chooser.setDialogTitle(MessageManager.getString("label.save_alignment_to_file"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
alignPanel.seqPanel.seqCanvas.getFeatureRenderer());
}
+ @Override
+ public void bioJSMenuItem_actionPerformed(ActionEvent e)
+ {
+ new BioJsHTMLOutput(alignPanel,
+ alignPanel.seqPanel.seqCanvas.getSequenceRenderer(),
+ alignPanel.seqPanel.seqCanvas.getFeatureRenderer());
+ }
public void createImageMap(File file, String image)
{
alignPanel.makePNGImageMap(file, image);
alignPanel.makeEPS(f);
}
+ public void createSVG(File f)
+ {
+ alignPanel.makeSVG(f);
+ }
@Override
public void pageSetup_actionPerformed(ActionEvent e)
{
protected void undoMenuItem_actionPerformed(ActionEvent e)
{
if (viewport.historyList.empty())
+ {
return;
+ }
CommandI command = (CommandI) viewport.historyList.pop();
viewport.redoList.push(command);
command.undoCommand(getViewAlignments());
for (int i = 0; i < viewport.getAlignment().getHeight(); i++)
{
if (!sg.contains(viewport.getAlignment().getSequenceAt(i)))
+ {
invertGroup.add(viewport.getAlignment().getSequenceAt(i));
+ }
}
SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
for (int i = 0; i < invertGroup.size(); i++)
+ {
seqs2[i] = (SequenceI) invertGroup.elementAt(i);
+ }
SlideSequencesCommand ssc;
if (right)
+ {
ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1,
size, viewport.getGapCharacter());
+ }
else
+ {
ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2,
size, viewport.getGapCharacter());
+ }
int groupAdjustment = 0;
if (ssc.getGapsInsertedBegin() && right)
{
if (viewport.cursorMode)
+ {
alignPanel.seqPanel.moveCursor(size, 0);
+ }
else
+ {
groupAdjustment = size;
+ }
}
else if (!ssc.getGapsInsertedBegin() && !right)
{
if (viewport.cursorMode)
+ {
alignPanel.seqPanel.moveCursor(-size, 0);
+ }
else
+ {
groupAdjustment = -size;
+ }
}
if (groupAdjustment != 0)
}
if (!appendHistoryItem)
+ {
addHistoryItem(ssc);
+ }
repaint();
}
// /////
// ADD HISTORY ITEM
//
- addHistoryItem(new EditCommand("Add sequences", EditCommand.PASTE,
+ addHistoryItem(new EditCommand(MessageManager.getString("label.add_sequences"), EditCommand.PASTE,
sequences, 0, alignment.getWidth(), alignment));
}
// Add any annotations attached to sequences
{
AlignmentAnnotation sann[] = sequences[i].getAnnotation();
if (sann == null)
+ {
continue;
+ }
for (int avnum = 0; avnum < alview.length; avnum++)
{
if (alview[avnum] != alignment)
return;
}
- Vector seqs = new Vector();
+ List<SequenceI> seqs = new ArrayList<SequenceI>(sg.getSize());
SequenceI seq;
for (int i = 0; i < sg.getSize(); i++)
{
seq = sg.getSequenceAt(i);
- seqs.addElement(seq);
+ seqs.add(seq);
}
- // If the cut affects all sequences, remove highlighted columns
+ // If the cut affects all sequences, warn, remove highlighted columns
if (sg.getSize() == viewport.getAlignment().getHeight())
{
+ int confirm = JOptionPane.showConfirmDialog(this,
+ MessageManager.getString("warn.delete_all"), // $NON-NLS-1$
+ MessageManager.getString("label.delete_all"), // $NON-NLS-1$
+ JOptionPane.OK_CANCEL_OPTION);
+
+ if (confirm == JOptionPane.CANCEL_OPTION
+ || confirm == JOptionPane.CLOSED_OPTION)
+ {
+ return;
+ }
viewport.getColumnSelection().removeElements(sg.getStartRes(),
sg.getEndRes() + 1);
}
SequenceI[] cut = new SequenceI[seqs.size()];
for (int i = 0; i < seqs.size(); i++)
{
- cut[i] = (SequenceI) seqs.elementAt(i);
+ cut[i] = seqs.get(i);
}
/*
* //ADD HISTORY ITEM
*/
- addHistoryItem(new EditCommand("Cut Sequences", EditCommand.CUT, cut,
+ addHistoryItem(new EditCommand(MessageManager.getString("label.cut_sequences"), EditCommand.CUT, cut,
sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
viewport.getAlignment()));
boolean addFirstIndex = false;
if (viewTitle == null || viewTitle.trim().length() == 0)
{
- viewTitle = "View";
+ viewTitle = MessageManager.getString("action.view");
addFirstIndex = true;
}
else
}
/**
- * DOCUMENT ME!
+ * Action on toggle of the 'Show annotations' menu item. This shows or hides
+ * the annotations panel as a whole.
+ *
+ * The options to show/hide all annotations should be enabled when the panel
+ * is shown, and disabled when the panel is hidden.
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
{
- viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());
- alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());
+ final boolean setVisible = annotationPanelMenuItem.isSelected();
+ viewport.setShowAnnotation(setVisible);
+ alignPanel.setAnnotationVisible(setVisible);
+ this.showAllSeqAnnotations.setEnabled(setVisible);
+ this.hideAllSeqAnnotations.setEnabled(setVisible);
+ this.showAllAlAnnotations.setEnabled(setVisible);
+ this.hideAllAlAnnotations.setEnabled(setVisible);
}
@Override
public void addSortByOrderMenuItem(String title,
final AlignmentOrder order)
{
- final JMenuItem item = new JMenuItem("by " + title);
+ final JMenuItem item = new JMenuItem(MessageManager.formatMessage("action.by_title_param", new String[]{title}));
sort.add(item);
item.addActionListener(new java.awt.event.ActionListener()
{
tm.setText(title);//
tm.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
NewTreePanel(type, (String) pwtype, title);
final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
final JMenu analymenu = new JMenu("Analysis");
final JMenu dismenu = new JMenu("Protein Disorder");
+ // final JMenu msawsmenu = new
+ // JMenu(MessageManager.getString("label.alignment"));
+ // final JMenu secstrmenu = new
+ // JMenu(MessageManager.getString("label.secondary_structure_prediction"));
+ // final JMenu seqsrchmenu = new
+ // JMenu(MessageManager.getString("label.sequence_database_search"));
+ // final JMenu analymenu = new
+ // JMenu(MessageManager.getString("label.analysis"));
+ // final JMenu dismenu = new
+ // JMenu(MessageManager.getString("label.protein_disorder"));
// JAL-940 - only show secondary structure prediction services from
// the legacy server
if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
public void run()
{
final long sttime = System.currentTimeMillis();
- ths.setProgressBar("Searching for sequences from " + fsrc, sttime);
+ ths.setProgressBar(MessageManager.formatMessage("status.searching_for_sequences_from", new String[]{fsrc}), sttime);
try
{
Alignment ds = ths.getViewport().getAlignment().getDataset(); // update
if (ds.getSequences() == null
|| !ds.getSequences().contains(
sprods[s].getDatasetSequence()))
+ {
ds.addSequence(sprods[s].getDatasetSequence());
+ }
sprods[s].updatePDBIds();
}
Alignment al = new Alignment(sprods);
jalview.bin.Cache.log.error("Error when finding crossreferences",
e);
}
- ths.setProgressBar("Finished searching for sequences from " + fsrc,
+ ths.setProgressBar(MessageManager.formatMessage("status.finished_searching_for_sequences_from", new String[]{fsrc}),
sttime);
}
{
PDBEntry pe = new AssociatePdbFileWithSeq()
.associatePdbWithSeq((String) fm[0],
- (String) fm[1], toassoc, false);
+ (String) fm[1], toassoc, false,
+ Desktop.instance);
if (pe != null)
{
System.err.println("Associated file : "
"AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false) || JOptionPane
.showConfirmDialog(
this,
- MessageManager
+ "<html>"+MessageManager
.formatMessage(
"label.ignore_unmatched_dropped_files_info",
new String[]
{ Integer.valueOf(
filesnotmatched
.size())
- .toString() }),
+ .toString() })+"</html>",
MessageManager
.getString("label.ignore_unmatched_dropped_files"),
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION))
trimrs.setSelected(Cache.getDefault("TRIM_FETCHED_DATASET_SEQS", true));
trimrs.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
trimrs.setSelected(trimrs.isSelected());
}
});
- fetchr.setToolTipText("<html>"
- + JvSwingUtils.wrapTooltip("Retrieve from "
- + src.getDbName()) + "<html>");
+ fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from", new String[]{src.getDbName()})));
dfetch.add(fetchr);
comp++;
}
}
});
- fetchr.setToolTipText("<html>"
- + JvSwingUtils.wrapTooltip("Retrieve from all "
- + otherdb.size() + " sources in "
- + src.getDbSource() + "<br>First is :"
- + src.getDbName()) + "<html>");
+ fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from_all_sources", new String[]{Integer.valueOf(otherdb.size()).toString(), src.getDbSource(), src.getDbName()})));
dfetch.add(fetchr);
comp++;
// and then build the rest of the individual menus
- ifetch = new JMenu("Sources from " + src.getDbSource());
+ ifetch = new JMenu(MessageManager.formatMessage("label.source_from_db_source", new String[]{src.getDbSource()}));
icomp = 0;
String imname = null;
int i = 0;
0, 10) + "..." : dbname;
if (imname == null)
{
- imname = "from '" + sname + "'";
+ imname = MessageManager.formatMessage("label.from_msname", new String[]{sname});
}
fetchr = new JMenuItem(msname);
final DbSourceProxy[] dassrc =
});
fetchr.setToolTipText("<html>"
- + JvSwingUtils.wrapTooltip("Retrieve from "
- + dbname) + "</html>");
+ + MessageManager.formatMessage("label.fetch_retrieve_from", new String[]{dbname}));
ifetch.add(fetchr);
++i;
if (++icomp >= mcomp || i == (otherdb.size()))
if (!viewport.getSequenceSetId().equals(
alignmentPanel.av.getSequenceSetId()))
{
- throw new Error(
- "Implementation error: cannot show a view from another alignment in an AlignFrame.");
+ throw new Error(MessageManager.getString("error.implementation_error_cannot_show_view_alignment_frame"));
}
if (tabbedPane != null
& alignPanels.indexOf(alignmentPanel) != tabbedPane
tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
}
}
+
+ /**
+ * Action on selection of menu options to Show or Hide annotations.
+ *
+ * @param visible
+ * @param forSequences
+ * update sequence-related annotations
+ * @param forAlignment
+ * update non-sequence-related annotations
+ */
+ @Override
+ protected void setAnnotationsVisibility(boolean visible,
+ boolean forSequences, boolean forAlignment)
+ {
+ for (AlignmentAnnotation aa : alignPanel.getAlignment()
+ .getAlignmentAnnotation())
+ {
+ boolean apply = (aa.sequenceRef == null && forAlignment)
+ || (aa.sequenceRef != null && forSequences);
+ if (apply)
+ {
+ aa.visible = visible;
+ }
+ }
+ this.alignPanel.paintAlignment(true);
+ }
+
+ /**
+ * Store selected annotation sort order for the view and repaint.
+ */
+ @Override
+ protected void sortAnnotations_actionPerformed()
+ {
+ this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
+ this.alignPanel.av
+ .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
+ alignPanel.paintAlignment(true);
+ }
}
class PrintThread extends Thread
*/
package jalview.gui;
+import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.analysis.NJTree;
import jalview.api.AlignViewportI;
import jalview.bin.Cache;
boolean showAnnotation = true;
+ SequenceAnnotationOrder sortAnnotationsBy = null;
+
int charHeight;
int charWidth;
}
}
- wrapAlignment = jalview.bin.Cache.getDefault("WRAP_ALIGNMENT", false);
- showUnconserved = jalview.bin.Cache.getDefault("SHOW_UNCONSERVED",
- false);
- sortByTree = jalview.bin.Cache.getDefault("SORT_BY_TREE", false);
- followSelection = jalview.bin.Cache.getDefault("FOLLOW_SELECTIONS",
- true);
+ wrapAlignment = Cache.getDefault("WRAP_ALIGNMENT", false);
+ showUnconserved = Cache.getDefault("SHOW_UNCONSERVED", false);
+ sortByTree = Cache.getDefault("SORT_BY_TREE", false);
+ followSelection = Cache.getDefault("FOLLOW_SELECTIONS", true);
+ sortAnnotationsBy = SequenceAnnotationOrder.valueOf(Cache.getDefault(
+ Preferences.SORT_ANNOTATIONS,
+ SequenceAnnotationOrder.NONE.name()));
+ showAutocalculatedAbove = Cache.getDefault(
+ Preferences.SHOW_AUTOCALC_ABOVE, false);
}
/**
{
// TODO: JAL-1126
if (historyList == null || redoList == null)
+ {
return new long[]
{ -1, -1 };
+ }
return new long[]
{ historyList.hashCode(), this.redoList.hashCode() };
}
Vector pdbs = alignment.getSequenceAt(i).getDatasetSequence()
.getPDBId();
if (pdbs == null)
+ {
continue;
+ }
SequenceI sq;
for (int p = 0; p < pdbs.size(); p++)
{
if (p1.getId().equals(pdb.getId()))
{
if (!seqs.contains(sq = alignment.getSequenceAt(i)))
+ {
seqs.add(sq);
+ }
continue;
}
private Hashtable<String, AutoCalcSetting> calcIdParams = new Hashtable<String, AutoCalcSetting>();
+ private boolean showAutocalculatedAbove;
+
public AutoCalcSetting getCalcIdSettingsFor(String calcId)
{
return calcIdParams.get(calcId);
Cache.log.debug("trigger update for " + calcId);
}
}
+
+ protected SequenceAnnotationOrder getSortAnnotationsBy()
+ {
+ return sortAnnotationsBy;
+ }
+
+ protected void setSortAnnotationsBy(SequenceAnnotationOrder sortAnnotationsBy)
+ {
+ this.sortAnnotationsBy = sortAnnotationsBy;
+ }
+
+ protected boolean isShowAutocalculatedAbove()
+ {
+ return showAutocalculatedAbove;
+ }
+
+ protected void setShowAutocalculatedAbove(boolean showAutocalculatedAbove)
+ {
+ this.showAutocalculatedAbove = showAutocalculatedAbove;
+ }
}
*/
package jalview.gui;
-import java.beans.*;
-import java.io.*;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.print.*;
-import javax.swing.*;
-
+import jalview.analysis.AnnotationSorter;
import jalview.api.AlignmentViewPanel;
import jalview.bin.Cache;
-import jalview.datamodel.*;
-import jalview.jbgui.*;
-import jalview.schemes.*;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.jbgui.GAlignmentPanel;
+import jalview.schemes.ResidueProperties;
import jalview.structure.StructureSelectionManager;
+import jalview.util.MessageManager;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+
+import javax.swing.SwingUtilities;
/**
* DOCUMENT ME!
int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
int maxwidth = Math.max(20,
- Math.min(afwidth - 200, (int) 2 * afwidth / 3));
+ Math.min(afwidth - 200, 2 * afwidth / 3));
return calculateIdWidth(maxwidth);
}
}
}
+ /**
+ * Repaint the alignment including the annotations and overview panels (if
+ * shown).
+ */
public void paintAlignment(boolean updateOverview)
{
+ final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
+ av.isShowAutocalculatedAbove());
+ sorter.sort(getAlignment()
+ .getAlignmentAnnotation(),
+ av.getSortAnnotationsBy());
repaint();
if (updateOverview)
// / How many sequences and residues can we fit on a printable page?
int totalRes = (pwidth - idWidth) / av.getCharWidth();
- int totalSeq = (int) ((pheight - scaleHeight) / av.getCharHeight()) - 1;
+ int totalSeq = (pheight - scaleHeight) / av.getCharHeight() - 1;
int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;
int offset = -alabels.scrollOffset;
pg.translate(0, offset);
pg.translate(-idWidth - 3, (endSeq - startSeq) * av.charHeight + 3);
- alabels.drawComponent((Graphics2D) pg, idWidth);
+ alabels.drawComponent(pg, idWidth);
pg.translate(idWidth + 3, 0);
annotationPanel.renderer.drawComponent(annotationPanel, av,
- (Graphics2D) pg, -1, startRes, endRes + 1);
+ pg, -1, startRes, endRes + 1);
pg.translate(0, -offset);
}
return idwidth.intValue() + 4;
}
- void makeAlignmentImage(int type, File file)
+ void makeAlignmentImage(jalview.util.ImageMaker.TYPE type, File file)
{
long progress = System.currentTimeMillis();
boolean headless = (System.getProperty("java.awt.headless") != null && System
.getProperty("java.awt.headless").equals("true"));
if (alignFrame != null && !headless)
{
- alignFrame.setProgressBar("Saving "
- + (type == jalview.util.ImageMaker.PNG ? "PNG image"
- : "EPS file"), progress);
+ alignFrame.setProgressBar(MessageManager.formatMessage(
+ "status.saving_file",
+ new String[]
+ { type.getLabel() }), progress);
}
try
{
jalview.util.ImageMaker im;
final String imageAction, imageTitle;
- if (type == jalview.util.ImageMaker.PNG)
+ if (type == jalview.util.ImageMaker.TYPE.PNG)
{
imageAction = "Create PNG image from alignment";
imageTitle = null;
}
- else
+ else if (type == jalview.util.ImageMaker.TYPE.EPS)
{
imageAction = "Create EPS file from alignment";
imageTitle = alignFrame.getTitle();
}
+ else
+ {
+ imageAction = "Create SVG file from alignment";
+ imageTitle = alignFrame.getTitle();
+ }
+
im = new jalview.util.ImageMaker(this, type, imageAction, width,
height, file, imageTitle);
if (av.getWrapAlignment())
{
if (alignFrame != null && !headless)
{
- alignFrame.setProgressBar("Export complete.", progress);
+ alignFrame.setProgressBar(MessageManager.getString("status.export_complete"), progress);
}
}
}
*/
public void makeEPS(File epsFile)
{
- makeAlignmentImage(jalview.util.ImageMaker.EPS, epsFile);
+ makeAlignmentImage(jalview.util.ImageMaker.TYPE.EPS, epsFile);
}
/**
*/
public void makePNG(File pngFile)
{
- makeAlignmentImage(jalview.util.ImageMaker.PNG, pngFile);
+ makeAlignmentImage(jalview.util.ImageMaker.TYPE.PNG, pngFile);
}
+ public void makeSVG(File svgFile)
+ {
+ makeAlignmentImage(jalview.util.ImageMaker.TYPE.SVG, svgFile);
+ }
public void makePNGImageMap(File imgMapFile, String imageName)
{
// /////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS
--- /dev/null
+package jalview.gui;
+
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceGroup;
+import jalview.util.MessageManager;
+
+import java.awt.BorderLayout;
+import java.awt.Checkbox;
+import java.awt.CheckboxGroup;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JButton;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.JPanel;
+
+/**
+ * A panel that allows the user to select which sequence-associated annotation
+ * rows to show or hide.
+ *
+ * @author gmcarstairs
+ *
+ */
+@SuppressWarnings("serial")
+public class AnnotationChooser extends JPanel
+{
+
+ private static final Font CHECKBOX_FONT = new Font("Serif", Font.BOLD, 12);
+
+ private static final int MY_FRAME_WIDTH = 600;
+
+ private static final int MY_FRAME_HEIGHT = 250;
+
+ private JInternalFrame frame;
+
+ private AlignmentPanel ap;
+
+ private SequenceGroup sg;
+
+ // all annotation rows' original visible state
+ private boolean[] resetState = null;
+
+ // is 'Show' selected?
+ private boolean showSelected;
+
+ // apply settings to selected (or all) sequences?
+ private boolean applyToSelectedSequences;
+
+ // apply settings to unselected (or all) sequences?
+ private boolean applyToUnselectedSequences;
+
+ // currently selected 'annotation type' checkboxes
+ private Map<String, String> selectedTypes = new HashMap<String, String>();
+
+ /**
+ * Constructor.
+ *
+ * @param alignPane
+ */
+ public AnnotationChooser(AlignmentPanel alignPane)
+ {
+ super();
+ this.ap = alignPane;
+ this.sg = alignPane.av.getSelectionGroup();
+ saveResetState(alignPane.getAlignment());
+
+ try
+ {
+ jbInit();
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ showFrame();
+ }
+
+ /**
+ * Save the initial show/hide state of all annotations to allow a Cancel
+ * operation.
+ *
+ * @param alignment
+ */
+ protected void saveResetState(AlignmentI alignment)
+ {
+ AlignmentAnnotation[] annotations = alignment.getAlignmentAnnotation();
+ final int count = annotations.length;
+ this.resetState = new boolean[count];
+ for (int i = 0; i < count; i++)
+ {
+ this.resetState[i] = annotations[i].visible;
+ }
+ }
+
+ /**
+ * Populate this frame with:
+ * <p>
+ * checkboxes for the types of annotation to show or hide (i.e. any annotation
+ * type shown for any sequence in the whole alignment)
+ * <p>
+ * option to show or hide selected types
+ * <p>
+ * option to show/hide for the currently selected group, or its inverse
+ * <p>
+ * OK and Cancel (reset) buttons
+ */
+ protected void jbInit()
+ {
+ setLayout(new GridLayout(3, 1));
+ add(buildAnnotationTypesPanel());
+ add(buildShowHideOptionsPanel());
+ add(buildActionButtonsPanel());
+ validate();
+ }
+
+ /**
+ * Construct the panel with checkboxes for annotation types.
+ *
+ * @return
+ */
+ protected JPanel buildAnnotationTypesPanel()
+ {
+ JPanel jp = new JPanel(new FlowLayout(FlowLayout.LEFT));
+
+ List<String> annotationTypes = getAnnotationTypes(
+ this.ap.getAlignment(), true);
+
+ for (final String type : annotationTypes)
+ {
+ final Checkbox check = new Checkbox(type);
+ check.setFont(CHECKBOX_FONT);
+ check.addItemListener(new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent evt)
+ {
+ if (evt.getStateChange() == ItemEvent.SELECTED)
+ {
+ AnnotationChooser.this.selectedTypes.put(type, type);
+ }
+ else
+ {
+ AnnotationChooser.this.selectedTypes.remove(type);
+ }
+ changeTypeSelected_actionPerformed(type);
+ }
+ });
+ jp.add(check);
+ }
+ return jp;
+ }
+
+ /**
+ * Update display when scope (All/Selected sequences/Unselected) is changed.
+ * <p>
+ * Set annotations (with one of the selected types) to the selected Show/Hide
+ * visibility, if they are in the new application scope. Set to the opposite
+ * if outside the scope.
+ * <p>
+ * Note this only affects sequence-specific annotations, others are left
+ * unchanged.
+ */
+ protected void changeApplyTo_actionPerformed()
+ {
+ setAnnotationVisibility(true);
+
+ // copied from AnnotationLabel.actionPerformed (after show/hide row)...
+ // TODO should drive this functionality into AlignmentPanel
+ ap.updateAnnotation();
+ // this.ap.annotationPanel.adjustPanelHeight();
+ // this.ap.alabels.setSize(this.ap.alabels.getSize().width,
+ // this.ap.annotationPanel.getSize().height);
+ // this.ap.validate();
+ this.ap.paintAlignment(true);
+ }
+
+ /**
+ * Update display when an annotation type is selected or deselected.
+ * <p>
+ * If the type is selected, set visibility of annotations of that type which
+ * are in the application scope (all, selected or unselected sequences).
+ * <p>
+ * If the type is unselected, set visibility to the opposite value. That is,
+ * treat select/deselect as a 'toggle' operation.
+ *
+ * @param type
+ */
+ protected void changeTypeSelected_actionPerformed(String type)
+ {
+ boolean typeSelected = this.selectedTypes.containsKey(type);
+ for (AlignmentAnnotation aa : this.ap.getAlignment()
+ .getAlignmentAnnotation())
+ {
+ if (aa.sequenceRef != null && type.equals(aa.label)
+ && isInActionScope(aa))
+ {
+ aa.visible = typeSelected ? this.showSelected : !this.showSelected;
+ }
+ }
+ ap.updateAnnotation();
+ // // this.ap.annotationPanel.adjustPanelHeight();
+ // this.ap.alabels.setSize(this.ap.alabels.getSize().width,
+ // this.ap.annotationPanel.getSize().height);
+ // this.ap.validate();
+ this.ap.paintAlignment(true);
+ }
+
+ /**
+ * Update display on change of choice of Show or Hide
+ * <p>
+ * For annotations of any selected type, set visibility of annotations of that
+ * type which are in the application scope (all, selected or unselected
+ * sequences).
+ *
+ * @param type
+ */
+ protected void changeShowHide_actionPerformed()
+ {
+ setAnnotationVisibility(false);
+
+ this.ap.updateAnnotation();
+ // this.ap.annotationPanel.adjustPanelHeight();
+ this.ap.paintAlignment(true);
+ }
+
+ /**
+ * Update visibility flags on annotation rows as per the current user choices.
+ *
+ * @param updateAllRows
+ */
+ protected void setAnnotationVisibility(boolean updateAllRows)
+ {
+ for (AlignmentAnnotation aa : this.ap.getAlignment()
+ .getAlignmentAnnotation())
+ {
+ if (aa.sequenceRef != null)
+ {
+ setAnnotationVisibility(aa, updateAllRows);
+ }
+ }
+ }
+
+ /**
+ * Determine and set the visibility of the given annotation from the currently
+ * selected options.
+ * <p>
+ * Only update annotations whose type is one of the selected types.
+ * <p>
+ * If its sequence is in the selected application scope
+ * (all/selected/unselected sequences), then we set its visibility according
+ * to the current choice of Show or Hide.
+ * <p>
+ * If force update of all rows is wanted, then set rows not in the sequence
+ * selection scope to the opposite visibility to those in scope.
+ *
+ * @param aa
+ * @param updateAllRows
+ */
+ protected void setAnnotationVisibility(AlignmentAnnotation aa,
+ boolean updateAllRows)
+ {
+ if (this.selectedTypes.containsKey(aa.label))
+ {
+ if (isInActionScope(aa))
+ {
+ aa.visible = this.showSelected;
+ }
+ else if (updateAllRows)
+ {
+ aa.visible = !this.showSelected;
+ }
+ }
+ // TODO force not visible if associated sequence is hidden?
+ // currently hiding a sequence does not hide its annotation rows
+ }
+
+ /**
+ * Answers true if the annotation falls in the current selection criteria for
+ * show/hide.
+ * <p>
+ * It must be in the sequence selection group (for 'Apply to selection'), or
+ * not in it (for 'Apply except to selection'). No check needed for 'Apply to
+ * all'.
+ *
+ * @param aa
+ * @return
+ */
+ protected boolean isInActionScope(AlignmentAnnotation aa)
+ {
+ boolean result = false;
+ if (this.applyToSelectedSequences && this.applyToUnselectedSequences)
+ {
+ // we don't care if the annotation's sequence is selected or not
+ result = true;
+ }
+ else if (this.sg == null)
+ {
+ // shouldn't happen - defensive programming
+ result = true;
+ }
+ else if (this.sg.getSequences().contains(aa.sequenceRef))
+ {
+ // annotation is for a member of the selection group
+ result = this.applyToSelectedSequences ? true : false;
+ }
+ else
+ {
+ // annotation is not associated with the selection group
+ result = this.applyToUnselectedSequences ? true : false;
+ }
+ return result;
+ }
+
+ /**
+ * Get annotation 'types' for an alignment, optionally restricted to
+ * sequence-specific annotations only. The label is currently used for 'type'.
+ *
+ * TODO refactor to helper class. See
+ * AnnotationColourChooser.getAnnotationItems() for another client
+ *
+ * @param alignment
+ * @param sequenceSpecific
+ * @return
+ */
+ public static List<String> getAnnotationTypes(AlignmentI alignment,
+ boolean sequenceSpecificOnly)
+ {
+ List<String> result = new ArrayList<String>();
+ for (AlignmentAnnotation aa : alignment.getAlignmentAnnotation())
+ {
+ if (!sequenceSpecificOnly || aa.sequenceRef != null)
+ {
+ String label = aa.label;
+ if (!result.contains(label))
+ {
+ result.add(label);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Construct the panel with options to:
+ * <p>
+ * show or hide the selected annotation types
+ * <p>
+ * do this for the current selection group or its inverse
+ *
+ * @return
+ */
+ protected JPanel buildShowHideOptionsPanel()
+ {
+ JPanel jp = new JPanel();
+ jp.setLayout(new BorderLayout());
+
+ JPanel showHideOptions = buildShowHidePanel();
+ jp.add(showHideOptions, BorderLayout.CENTER);
+
+ JPanel applyToOptions = buildApplyToOptionsPanel();
+ jp.add(applyToOptions, BorderLayout.SOUTH);
+
+ return jp;
+ }
+
+ /**
+ * Build a panel with radio buttons options for sequences to apply show/hide
+ * to. Options are all, current selection, all except current selection.
+ * Initial state has 'current selection' selected.
+ * <p>
+ * If the sequence group is null, then we are acting on the whole alignment,
+ * and only 'all sequences' is enabled (and selected).
+ *
+ * @return
+ */
+ protected JPanel buildApplyToOptionsPanel()
+ {
+ final boolean wholeAlignment = this.sg == null;
+ JPanel applyToOptions = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ CheckboxGroup actingOn = new CheckboxGroup();
+
+ String forAll = MessageManager.getString("label.all_sequences");
+ final Checkbox allSequences = new Checkbox(forAll, actingOn,
+ wholeAlignment);
+ allSequences.addItemListener(new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent evt)
+ {
+ if (evt.getStateChange() == ItemEvent.SELECTED) {
+ AnnotationChooser.this.setApplyToSelectedSequences(true);
+ AnnotationChooser.this.setApplyToUnselectedSequences(true);
+ AnnotationChooser.this.changeApplyTo_actionPerformed();
+ }
+ }
+ });
+ applyToOptions.add(allSequences);
+
+ String forSelected = MessageManager
+ .getString("label.selected_sequences");
+ final Checkbox selectedSequences = new Checkbox(forSelected, actingOn,
+ !wholeAlignment);
+ selectedSequences.setEnabled(!wholeAlignment);
+ selectedSequences.addItemListener(new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent evt)
+ {
+ if (evt.getStateChange() == ItemEvent.SELECTED)
+ {
+ AnnotationChooser.this.setApplyToSelectedSequences(true);
+ AnnotationChooser.this.setApplyToUnselectedSequences(false);
+ AnnotationChooser.this.changeApplyTo_actionPerformed();
+ }
+ }
+ });
+ applyToOptions.add(selectedSequences);
+
+ String exceptSelected = MessageManager
+ .getString("label.except_selected_sequences");
+ final Checkbox unselectedSequences = new Checkbox(exceptSelected, actingOn, false);
+ unselectedSequences.setEnabled(!wholeAlignment);
+ unselectedSequences.addItemListener(new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent evt)
+ {
+ if (evt.getStateChange() == ItemEvent.SELECTED)
+ {
+ AnnotationChooser.this.setApplyToSelectedSequences(false);
+ AnnotationChooser.this.setApplyToUnselectedSequences(true);
+ AnnotationChooser.this.changeApplyTo_actionPerformed();
+ }
+ }
+ });
+ applyToOptions.add(unselectedSequences);
+
+ // set member variables to match the initial selection state
+ this.applyToSelectedSequences = selectedSequences.getState()
+ || allSequences.getState();
+ this.applyToUnselectedSequences = unselectedSequences.getState()
+ || allSequences.getState();
+
+ return applyToOptions;
+ }
+
+ /**
+ * Build a panel with radio button options to show or hide selected
+ * annotations.
+ *
+ * @return
+ */
+ protected JPanel buildShowHidePanel()
+ {
+ JPanel showHideOptions = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ CheckboxGroup showOrHide = new CheckboxGroup();
+
+ /*
+ * Radio button 'Show selected annotations' - initially unselected
+ */
+ String showLabel = MessageManager
+ .getString("label.show_selected_annotations");
+ final Checkbox showOption = new Checkbox(showLabel, showOrHide, false);
+ showOption.addItemListener(new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent evt)
+ {
+ if (evt.getStateChange() == ItemEvent.SELECTED) {
+ AnnotationChooser.this.setShowSelected(true);
+ AnnotationChooser.this.changeShowHide_actionPerformed();
+ }
+ }
+ });
+ showHideOptions.add(showOption);
+
+ /*
+ * Radio button 'hide selected annotations'- initially selected
+ */
+ String hideLabel = MessageManager
+ .getString("label.hide_selected_annotations");
+ final Checkbox hideOption = new Checkbox(hideLabel, showOrHide, true);
+ hideOption.addItemListener(new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent evt)
+ {
+ if (evt.getStateChange() == ItemEvent.SELECTED)
+ {
+ AnnotationChooser.this.setShowSelected(false);
+ AnnotationChooser.this.changeShowHide_actionPerformed();
+ }
+ }
+ });
+ showHideOptions.add(hideOption);
+
+ /*
+ * Set member variable to match initial selection state
+ */
+ this.showSelected = showOption.getState();
+
+ return showHideOptions;
+ }
+
+ /**
+ * Construct the panel with OK and Cancel buttons.
+ *
+ * @return
+ */
+ protected JPanel buildActionButtonsPanel()
+ {
+ JPanel jp = new JPanel();
+ final Font labelFont = JvSwingUtils.getLabelFont();
+
+ JButton ok = new JButton(MessageManager.getString("action.ok"));
+ ok.setFont(labelFont);
+ ok.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ close_actionPerformed();
+ }
+ });
+ jp.add(ok);
+
+ JButton cancel = new JButton(MessageManager.getString("action.cancel"));
+ cancel.setFont(labelFont);
+ cancel.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ cancel_actionPerformed();
+ }
+ });
+ jp.add(cancel);
+
+ return jp;
+ }
+
+ /**
+ * On 'Cancel' button, undo any changes.
+ */
+ protected void cancel_actionPerformed()
+ {
+ resetOriginalState();
+ this.ap.repaint();
+ close_actionPerformed();
+ }
+
+ /**
+ * Restore annotation visibility to their state on entry here, and repaint
+ * alignment.
+ */
+ protected void resetOriginalState()
+ {
+ int i = 0;
+ for (AlignmentAnnotation aa : this.ap.getAlignment()
+ .getAlignmentAnnotation())
+ {
+ aa.visible = this.resetState[i++];
+ }
+ }
+
+ /**
+ * On 'Close' button, close the dialog.
+ */
+ protected void close_actionPerformed()
+ {
+ try
+ {
+ this.frame.setClosed(true);
+ } catch (Exception exe)
+ {
+ }
+ }
+
+ /**
+ * Render a frame containing this panel.
+ */
+ private void showFrame()
+ {
+ frame = new JInternalFrame();
+ frame.setContentPane(this);
+ frame.setLayer(JLayeredPane.PALETTE_LAYER);
+ Desktop.addInternalFrame(frame,
+ MessageManager.getString("label.choose_annotations"),
+ MY_FRAME_WIDTH, MY_FRAME_HEIGHT, true);
+ }
+
+ protected void setShowSelected(boolean showSelected)
+ {
+ this.showSelected = showSelected;
+ }
+
+ protected void setApplyToSelectedSequences(
+ boolean applyToSelectedSequences)
+ {
+ this.applyToSelectedSequences = applyToSelectedSequences;
+ }
+
+ protected void setApplyToUnselectedSequences(
+ boolean applyToUnselectedSequences)
+ {
+ this.applyToUnselectedSequences = applyToUnselectedSequences;
+ }
+
+ protected boolean isShowSelected()
+ {
+ return showSelected;
+ }
+
+ protected boolean isApplyToSelectedSequences()
+ {
+ return applyToSelectedSequences;
+ }
+
+ protected boolean isApplyToUnselectedSequences()
+ {
+ return applyToUnselectedSequences;
+ }
+
+}
*/
package jalview.gui;
-import java.util.*;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-import javax.swing.event.*;
-
-import net.miginfocom.swing.MigLayout;
-
import jalview.bin.Cache;
-import jalview.datamodel.*;
-import jalview.schemes.*;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.GraphLine;
+import jalview.datamodel.SequenceGroup;
+import jalview.schemes.AnnotationColourGradient;
+import jalview.schemes.ColourSchemeI;
import jalview.util.MessageManager;
+import java.awt.BorderLayout;
+import java.awt.Color;
import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JColorChooser;
+import javax.swing.JComboBox;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.JTextField;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import net.miginfocom.swing.MigLayout;
public class AnnotationColourChooser extends JPanel
{
slider.addChangeListener(new ChangeListener()
{
+ @Override
public void stateChanged(ChangeEvent evt)
{
if (!adjusting)
{
- thresholdValue.setText(((float) slider.getValue() / 1000f) + "");
+ thresholdValue.setText((slider.getValue() / 1000f) + "");
valueChanged(!sliderDragging);
}
}
super.mouseDragged(e);
}
+ @Override
public void mouseReleased(MouseEvent evt)
{
if (sliderDragging)
threshold.setSelectedIndex(2);
break;
default:
- throw new Error(
- "Implementation error: don't know about threshold setting for current AnnotationColourGradient.");
+ throw new Error(MessageManager.getString("error.implementation_error_dont_know_about_thereshold_setting"));
}
thresholdIsMin.setSelected(acg.thresholdIsMinMax);
thresholdValue.setText("" + acg.getAnnotationThreshold());
if (!list.contains(label))
{
anmap[list.size()] = i;
- list.addElement(label);
+ list.add(label);
}
else
if (!isSeqAssociated)
{
anmap[list.size()] = i;
- list.addElement(label + "_" + (index++));
+ list.add(label + "_" + (index++));
}
}
}
seqAssociated.setEnabled(enableSeqAss);
- annmap = new int[list.size()];
- System.arraycopy(anmap, 0, annmap, 0, annmap.length);
+ this.annmap = new int[list.size()];
+ System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length);
return list;
}
minColour.setToolTipText(MessageManager.getString("label.min_colour"));
minColour.addMouseListener(new MouseAdapter()
{
+ @Override
public void mousePressed(MouseEvent e)
{
if (minColour.isEnabled())
maxColour.setToolTipText(MessageManager.getString("label.max_colour"));
maxColour.addMouseListener(new MouseAdapter()
{
+ @Override
public void mousePressed(MouseEvent e)
{
if (maxColour.isEnabled())
ok.setText(MessageManager.getString("action.ok"));
ok.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
ok_actionPerformed(e);
cancel.setText(MessageManager.getString("action.cancel"));
cancel.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
cancel_actionPerformed(e);
annotations.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
annotations_actionPerformed(e);
});
threshold.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
threshold_actionPerformed(e);
});
thresholdValue.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
thresholdValue_actionPerformed(e);
.getString("label.use_original_colours"));
currentColours.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
currentColours_actionPerformed(e);
.getString("label.threshold_minmax"));
thresholdIsMin.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent actionEvent)
{
thresholdIsMin_actionPerformed(actionEvent);
public void minColour_actionPerformed()
{
Color col = JColorChooser.showDialog(this,
- "Select Colour for Minimum Value", minColour.getBackground());
+ MessageManager.getString("label.select_colour_minimum_value"), minColour.getBackground());
if (col != null)
{
minColour.setBackground(col);
public void maxColour_actionPerformed()
{
Color col = JColorChooser.showDialog(this,
- "Select Colour for Maximum Value", maxColour.getBackground());
+ MessageManager.getString("label.select_colour_maximum_value"), maxColour.getBackground());
if (col != null)
{
maxColour.setBackground(col);
{
changeColour();
}
- currentAnnotation.threshold.value = (float) slider.getValue() / 1000f;
+ currentAnnotation.threshold.value = slider.getValue() / 1000f;
propagateSeqAssociatedThreshold(updateAllAnnotation);
ap.paintAlignment(false);
}
for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
{
AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[i];
- if (aa.label.equals(currentAnnotation.label))
+ if (aa.label.equals(currentAnnotation.label)
+ && (currentAnnotation.getCalcId() == null ? aa.getCalcId() == null
+ : currentAnnotation.getCalcId()
+ .equals(aa.getCalcId())))
{
- aa.threshold.value = thr;
+ if (aa.threshold == null)
+ {
+ aa.threshold = new GraphLine(currentAnnotation.threshold);
+ }
+ else
+ {
+ aa.threshold.value = thr;
+ }
}
}
}
this.ap = ap;
features = true;
CSVFormat.setVisible(false);
- frame.setTitle("Export Features");
+ frame.setTitle(MessageManager.getString("label.export_features"));
}
public void exportAnnotations(AlignmentPanel ap,
this.annotations = annotations;
this.sequenceGroups = list;
this.alignmentProperties = alProperties;
- frame.setTitle("Export Annotations");
+ frame.setTitle(MessageManager.getString("label.export_annotations"));
}
public void toFile_actionPerformed(ActionEvent e)
jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle(features ? "Save Features to File"
- : "Save Annotation to File");
+ chooser.setDialogTitle(features ? MessageManager.getString("label.save_features_to_file")
+ : MessageManager.getString("label.save_annotation_to_file"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
if (value == JalviewFileChooser.APPROVE_OPTION)
{
- String text = "No features found on alignment";
+ String text = MessageManager.getString("label.no_features_on_alignment");
if (features)
{
if (GFFFormat.isSelected())
public void toTextbox_actionPerformed(ActionEvent e)
{
- String text = "No features found on alignment";
+ String text = MessageManager.getString("label.no_features_on_alignment");
if (features)
{
if (GFFFormat.isSelected())
*/
package jalview.gui;
-import java.util.*;
-import java.util.regex.Pattern;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.FormatAdapter;
+import jalview.util.MessageManager;
-import java.awt.*;
-import java.awt.datatransfer.*;
-import java.awt.event.*;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.RenderingHints;
+import java.awt.Toolkit;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
-import java.awt.image.*;
-import javax.swing.*;
+import java.awt.image.BufferedImage;
+import java.util.Arrays;
+import java.util.Vector;
+import java.util.regex.Pattern;
-import jalview.datamodel.*;
-import jalview.io.*;
-import jalview.util.MessageManager;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
/**
* DOCUMENT ME!
public class AnnotationLabels extends JPanel implements MouseListener,
MouseMotionListener, ActionListener
{
- static String TOGGLE_LABELSCALE = "Scale Label to Column";
+ String TOGGLE_LABELSCALE = MessageManager.getString("label.scale_label_to_column");
- static String ADDNEW = "Add New Row";
+ String ADDNEW = MessageManager.getString("label.add_new_row");
- static String EDITNAME = "Edit Label/Description";
+ String EDITNAME = MessageManager.getString("label.edit_label_description");
- static String HIDE = "Hide This Row";
+ String HIDE = MessageManager.getString("label.hide_row");
- static String DELETE = "Delete This Row";
+ String DELETE = MessageManager.getString("label.delete_row");
- static String SHOWALL = "Show All Hidden Rows";
+ String SHOWALL = MessageManager.getString("label.show_all_hidden_rows");
- static String OUTPUT_TEXT = "Export Annotation";
+ String OUTPUT_TEXT = MessageManager.getString("label.export_annotation");
- static String COPYCONS_SEQ = "Copy Consensus Sequence";
+ String COPYCONS_SEQ = MessageManager.getString("label.copy_consensus_sequence");
boolean resizePanel = false;
Graphics2D g = (Graphics2D) bi.getGraphics();
g.rotate(Math.toRadians(90));
g.drawImage(temp, 0, -bi.getWidth(this), this);
- image = (Image) bi;
+ image = bi;
addMouseListener(this);
addMouseMotionListener(this);
aa[selectedRow].scaleColLabel = !aa[selectedRow].scaleColLabel;
}
+ refresh();
+
+ }
+
+ /**
+ * Redraw sensibly.
+ */
+ protected void refresh()
+ {
ap.validateAnnotationDimensions(false);
ap.addNotify();
ap.repaint();
- // validate();
- // ap.paintAlignment(true);
}
/**
this.setToolTipText(desc.toString());
}
else
+ {
this.setToolTipText(null);
+ }
}
}
*/
public void mouseClicked(MouseEvent evt)
{
- AlignmentAnnotation[] aa = ap.av.getAlignment()
+ final AlignmentAnnotation[] aa = ap.av.getAlignment()
.getAlignmentAnnotation();
if (SwingUtilities.isLeftMouseButton(evt))
{
}
else if (aa[selectedRow].sequenceRef != null)
{
- Vector sr = new Vector();
- sr.addElement(aa[selectedRow].sequenceRef);
if (evt.getClickCount() == 1)
{
- ap.seqPanel.ap.idPanel.highlightSearchResults(sr);
+ ap.seqPanel.ap.idPanel.highlightSearchResults(Arrays
+ .asList(new SequenceI[]
+ { aa[selectedRow].sequenceRef }));
}
else if (evt.getClickCount() >= 2)
{
ap.seqPanel.ap.idPanel.highlightSearchResults(null);
- SequenceGroup sg = new SequenceGroup();
- sg.addSequence(aa[selectedRow].sequenceRef, false);
+ SequenceGroup sg = ap.av.getSelectionGroup();
+ if (sg!=null)
+ {
+ // we make a copy rather than edit the current selection if no modifiers pressed
+ // see Enhancement JAL-1557
+ if (!(evt.isControlDown() || evt.isShiftDown()))
+ {
+ sg = new SequenceGroup(sg);
+ sg.clear();
+ sg.addSequence(aa[selectedRow].sequenceRef, false);
+ } else {
+ if (evt.isControlDown())
+ {
+ sg.addOrRemove(aa[selectedRow].sequenceRef, true);
+ } else {
+ // notionally, we should also add intermediate sequences from last added sequence ?
+ sg.addSequence(aa[selectedRow].sequenceRef, true);
+ }
+ }
+ } else {
+ sg = new SequenceGroup();
+ sg.setStartRes(0);
+ sg.setEndRes(ap.av.getAlignment().getWidth()-1);
+ sg.addSequence(aa[selectedRow].sequenceRef, false);
+ }
ap.av.setSelectionGroup(sg);
ap.av.sendSelection();
ap.paintAlignment(false);
item = new JMenuItem(HIDE);
item.addActionListener(this);
pop.add(item);
+ // JAL-1264 hide all sequence-specific annotations of this type
+ final String label = aa[selectedRow].label;
+ if (selectedRow < aa.length)
+ {
+ if (aa[selectedRow].sequenceRef != null)
+ {
+ JMenuItem hideType = new JMenuItem();
+ String text = MessageManager.getString("label.hide_all") + " " + label;
+ hideType.setText(text);
+ hideType.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ for (AlignmentAnnotation ann : ap.av.getAlignment()
+ .getAlignmentAnnotation())
+ {
+ if (ann.sequenceRef != null && ann.label != null
+ && ann.label.equals(label))
+ {
+ ann.visible = false;
+ }
+ }
+ refresh();
+ }
+ });
+ pop.add(hideType);
+ }
+ }
item = new JMenuItem(DELETE);
item.addActionListener(this);
pop.add(item);
pop.add(item);
}
}
- else if (aa[selectedRow].label.indexOf("Consensus") > -1)
+ else if (label.indexOf("Consensus") > -1)
{
pop.addSeparator();
// av and sequencegroup need to implement same interface for
final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem(
- "Ignore Gaps In Consensus",
+ MessageManager.getString("label.ignore_gaps_consensus"),
(aa[selectedRow].groupRef != null) ? aa[selectedRow].groupRef
.getIgnoreGapsConsensus() : ap.av
.getIgnoreGapsConsensus());
if (aaa.groupRef != null)
{
final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
- "Show Group Histogram",
+ MessageManager.getString("label.show_group_histogram"),
aa[selectedRow].groupRef.isShowConsensusHistogram());
chist.addActionListener(new ActionListener()
{
});
pop.add(chist);
final JCheckBoxMenuItem cprofl = new JCheckBoxMenuItem(
- "Show Group Logo",
+ MessageManager.getString("label.show_group_logo"),
aa[selectedRow].groupRef.isShowSequenceLogo());
cprofl.addActionListener(new ActionListener()
{
});
pop.add(cprofl);
final JCheckBoxMenuItem cproflnorm = new JCheckBoxMenuItem(
- "Normalise Group Logo",
+ MessageManager.getString("label.normalise_group_logo"),
aa[selectedRow].groupRef.isNormaliseSequenceLogo());
cproflnorm.addActionListener(new ActionListener()
{
else
{
final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
- "Show Histogram", av.isShowConsensusHistogram());
+ MessageManager.getString("label.show_histogram"), av.isShowConsensusHistogram());
chist.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
});
pop.add(chist);
final JCheckBoxMenuItem cprof = new JCheckBoxMenuItem(
- "Show Logo", av.isShowSequenceLogo());
+ MessageManager.getString("label.show_logo"), av.isShowSequenceLogo());
cprof.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
});
pop.add(cprof);
final JCheckBoxMenuItem cprofnorm = new JCheckBoxMenuItem(
- "Normalise Logo", av.isNormaliseSequenceLogo());
+ MessageManager.getString("label.normalise_logo"), av.isNormaliseSequenceLogo());
cprofnorm.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
offset -= fm.getDescent();
}
else
+ {
offset += fm.getDescent();
+ }
x = width - fm.stringWidth(aa[i].label) - 3;
MouseListener, MouseWheelListener, MouseMotionListener,
ActionListener, AdjustmentListener, Scrollable
{
- final String HELIX = "Helix";
+ String HELIX = MessageManager.getString("label.helix");
- final String SHEET = "Sheet";
+ String SHEET = MessageManager.getString("label.sheet");
/**
* For RNA secondary structure "stems" aka helices
*/
- final String STEM = "RNA Helix";
+ String STEM = MessageManager.getString("label.rna_helix");
- final String LABEL = "Label";
+ String LABEL = MessageManager.getString("label.label");
- final String REMOVE = "Remove Annotation";
+ String REMOVE = MessageManager.getString("label.remove_annotation");
- final String COLOUR = "Colour";
+ String COLOUR = MessageManager.getString("action.colour");
public final Color HELIX_COLOUR = Color.red.darker();
else if (evt.getActionCommand().equals(COLOUR))
{
Color col = JColorChooser.showDialog(this,
- "Choose foreground colour", Color.black);
+ MessageManager.getString("label.select_foreground_colour"), Color.black);
for (int i = 0; i < av.getColumnSelection().size(); i++)
{
&& aa[row].annotations[res].description != null
&& aa[row].annotations[res].description.length() > 0)
{
- this.setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip(aa[row].annotations[res].description)
- + "</html>");
+ this.setToolTipText(JvSwingUtils
+ .wrapTooltip(true, aa[row].annotations[res].description));
}
else
{
*/
package jalview.gui;
-import java.util.*;
-import java.awt.*;
-import javax.swing.*;
-import javax.swing.event.*;
-
-import java.awt.event.*;
-import java.io.*;
-
-import jalview.jbgui.GStructureViewer;
-import jalview.api.SequenceStructureBinding;
+import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
-import jalview.datamodel.*;
-import jalview.gui.ViewSelectionMenu.ViewSetProvider;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
-import jalview.io.*;
-import jalview.schemes.*;
+import jalview.datamodel.SequenceI;
+import jalview.ext.jmol.JalviewJmolBinding;
+import jalview.gui.ViewSelectionMenu.ViewSetProvider;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.jbgui.GStructureViewer;
+import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.HelixColourScheme;
+import jalview.schemes.HydrophobicColourScheme;
+import jalview.schemes.PurinePyrimidineColourScheme;
+import jalview.schemes.StrandColourScheme;
+import jalview.schemes.TaylorColourScheme;
+import jalview.schemes.TurnColourScheme;
+import jalview.schemes.ZappoColourScheme;
import jalview.util.MessageManager;
import jalview.util.Platform;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JInternalFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JSplitPane;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
+
public class AppJmol extends GStructureViewer implements Runnable,
- SequenceStructureBinding, ViewSetProvider
+ ViewSetProvider, JalviewStructureDisplayI
{
AppJmolBinding jmb;
* @param bounds
* @deprecated defaults to AppJmol(String[] files, ... , viewid);
*/
+ @Deprecated
public AppJmol(String file, String id, SequenceI[] seq,
AlignmentPanel ap, String loadStatus, Rectangle bounds)
{
/**
* @deprecated
*/
+ @Deprecated
public AppJmol(String file, String id, SequenceI[] seq,
AlignmentPanel ap, String loadStatus, Rectangle bounds,
String viewid)
{
jmb.setColourBySequence(false);
seqColour.setSelected(false);
- jmolColour.setSelected(true);
+ viewerColour.setSelected(true);
}
if (usetoColour)
{
useAlignmentPanelForColourbyseq(ap);
jmb.setColourBySequence(true);
seqColour.setSelected(true);
- jmolColour.setSelected(false);
+ viewerColour.setSelected(false);
}
this.setBounds(bounds);
initMenus();
private void initMenus()
{
seqColour.setSelected(jmb.isColourBySequence());
- jmolColour.setSelected(!jmb.isColourBySequence());
+ viewerColour.setSelected(!jmb.isColourBySequence());
if (_colourwith == null)
{
_colourwith = new Vector<AlignmentPanel>();
_alignwith = new Vector<AlignmentPanel>();
}
- seqColourBy = new ViewSelectionMenu("Colour by ..", this, _colourwith,
+ seqColourBy = new ViewSelectionMenu(MessageManager.getString("label.colour_by"), this, _colourwith,
new ItemListener()
{
});
viewMenu.add(seqColourBy);
final ItemListener handler;
- JMenu alpanels = new ViewSelectionMenu("Superpose with ..", this,
+ JMenu alpanels = new ViewSelectionMenu(MessageManager.getString("label.superpose_with"), this,
_alignwith, handler = new ItemListener()
{
}
});
handler.itemStateChanged(null);
- jmolActionMenu.add(alpanels);
- jmolActionMenu.addMenuListener(new MenuListener()
+ viewerActionMenu.add(alpanels);
+ viewerActionMenu.addMenuListener(new MenuListener()
{
@Override
"label.pdb_entry_is_already_displayed", new String[]
{ pdbentry.getId() }), MessageManager.formatMessage(
"label.map_sequences_to_visible_window", new String[]
- { pdbentry.getId() }), JOptionPane.YES_NO_OPTION);
+ { pdbentry.getId() }),
+ JOptionPane.YES_NO_CANCEL_OPTION);
+ if (option == JOptionPane.CANCEL_OPTION)
+ {
+ return;
+ }
if (option == JOptionPane.YES_OPTION)
{
// TODO : Fix multiple seq to one chain issue here.
{ pdbentry.getId(), topJmol.getTitle() }),
MessageManager
.getString("label.align_to_existing_structure_view"),
- JOptionPane.YES_NO_OPTION);
+ JOptionPane.YES_NO_CANCEL_OPTION);
+ if (option == JOptionPane.CANCEL_OPTION)
+ {
+ return;
+ }
if (option == JOptionPane.YES_OPTION)
{
topJmol.useAlignmentPanelForSuperposition(ap);
useAlignmentPanelForColourbyseq(nap);
jmb.setColourBySequence(enableColourBySeq);
seqColour.setSelected(enableColourBySeq);
- jmolColour.setSelected(!enableColourBySeq);
+ viewerColour.setSelected(!enableColourBySeq);
}
public void useAlignmentPanelForColourbyseq(AlignmentPanel nap)
return;
}
- private Vector getJmolsFor(AlignmentPanel ap2)
+ private Vector getJmolsFor(AlignmentPanel apanel)
{
- Vector otherJmols = new Vector();
- // Now this AppJmol is mapped to new sequences. We must add them to
- // the exisiting array
+ Vector result = new Vector();
JInternalFrame[] frames = Desktop.instance.getAllFrames();
- for (int i = 0; i < frames.length; i++)
+ for (JInternalFrame frame : frames)
{
- if (frames[i] instanceof AppJmol)
+ if (frame instanceof AppJmol)
{
- AppJmol topJmol = ((AppJmol) frames[i]);
- if (topJmol.isLinkedWith(ap2))
+ if (((AppJmol) frame).isLinkedWith(apanel))
{
- otherJmols.addElement(topJmol);
+ result.addElement(frame);
}
}
}
- return otherJmols;
+ return result;
}
void initJmol(String command)
for (int i = 0; i < chainMenu.getItemCount(); i++)
{
if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
+ {
((JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true);
+ }
}
centerViewer();
allChainsSelected = false;
public void itemStateChanged(ItemEvent evt)
{
if (!allChainsSelected)
+ {
centerViewer();
+ }
}
});
jmb.centerViewer(toshow);
}
- void closeViewer()
+ public void closeViewer()
{
jmb.closeViewer();
ap = null;
long hdl = pdbid.hashCode() - System.currentTimeMillis();
if (progressBar != null)
{
- progressBar.setProgressBar("Fetching PDB " + pdbid, hdl);
+ progressBar.setProgressBar(MessageManager.formatMessage("status.fetching_pdb", new String[]{pdbid}), hdl);
}
try
{
}
if (progressBar != null)
{
- progressBar.setProgressBar("Finished.", hdl);
+ progressBar.setProgressBar(MessageManager.getString("label.state_completed"), hdl);
}
if (pdbseq != null)
{
worker = null;
}
+ @Override
public void pdbFile_actionPerformed(ActionEvent actionEvent)
{
JalviewFileChooser chooser = new JalviewFileChooser(
jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Save PDB File");
+ chooser.setDialogTitle(MessageManager.getString("label.save_pdb_file"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
}
}
+ @Override
public void viewMapping_actionPerformed(ActionEvent actionEvent)
{
jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer();
600);
}
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
+ @Override
public void eps_actionPerformed(ActionEvent e)
{
- makePDBImage(jalview.util.ImageMaker.EPS);
+ makePDBImage(jalview.util.ImageMaker.TYPE.EPS);
}
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
+ @Override
public void png_actionPerformed(ActionEvent e)
{
- makePDBImage(jalview.util.ImageMaker.PNG);
+ makePDBImage(jalview.util.ImageMaker.TYPE.PNG);
}
- void makePDBImage(int type)
+ void makePDBImage(jalview.util.ImageMaker.TYPE type)
{
int width = getWidth();
int height = getHeight();
jalview.util.ImageMaker im;
- if (type == jalview.util.ImageMaker.PNG)
+ if (type == jalview.util.ImageMaker.TYPE.PNG)
{
- im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.PNG,
+ im = new jalview.util.ImageMaker(this,
+ jalview.util.ImageMaker.TYPE.PNG,
"Make PNG image from view", width, height, null, null);
}
- else
+ else if (type == jalview.util.ImageMaker.TYPE.EPS)
{
- im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.EPS,
+ im = new jalview.util.ImageMaker(this,
+ jalview.util.ImageMaker.TYPE.EPS,
"Make EPS file from view", width, height, null,
this.getTitle());
}
+ else
+ {
+
+ im = new jalview.util.ImageMaker(this,
+ jalview.util.ImageMaker.TYPE.SVG, "Make SVG file from PCA",
+ width, height, null, this.getTitle());
+ }
if (im.getGraphics() != null)
{
}
}
- public void jmolColour_actionPerformed(ActionEvent actionEvent)
+ @Override
+ public void viewerColour_actionPerformed(ActionEvent actionEvent)
{
- if (jmolColour.isSelected())
+ if (viewerColour.isSelected())
{
// disable automatic sequence colouring.
jmb.setColourBySequence(false);
}
}
+ @Override
public void seqColour_actionPerformed(ActionEvent actionEvent)
{
jmb.setColourBySequence(seqColour.isSelected());
}
}
+ @Override
public void chainColour_actionPerformed(ActionEvent actionEvent)
{
chainColour.setSelected(true);
jmb.colourByChain();
}
+ @Override
public void chargeColour_actionPerformed(ActionEvent actionEvent)
{
chargeColour.setSelected(true);
jmb.colourByCharge();
}
+ @Override
public void zappoColour_actionPerformed(ActionEvent actionEvent)
{
zappoColour.setSelected(true);
jmb.setJalviewColourScheme(new ZappoColourScheme());
}
+ @Override
public void taylorColour_actionPerformed(ActionEvent actionEvent)
{
taylorColour.setSelected(true);
jmb.setJalviewColourScheme(new TaylorColourScheme());
}
+ @Override
public void hydroColour_actionPerformed(ActionEvent actionEvent)
{
hydroColour.setSelected(true);
jmb.setJalviewColourScheme(new HydrophobicColourScheme());
}
+ @Override
public void helixColour_actionPerformed(ActionEvent actionEvent)
{
helixColour.setSelected(true);
jmb.setJalviewColourScheme(new HelixColourScheme());
}
+ @Override
public void strandColour_actionPerformed(ActionEvent actionEvent)
{
strandColour.setSelected(true);
jmb.setJalviewColourScheme(new StrandColourScheme());
}
+ @Override
public void turnColour_actionPerformed(ActionEvent actionEvent)
{
turnColour.setSelected(true);
jmb.setJalviewColourScheme(new TurnColourScheme());
}
+ @Override
public void buriedColour_actionPerformed(ActionEvent actionEvent)
{
buriedColour.setSelected(true);
jmb.setJalviewColourScheme(new BuriedColourScheme());
}
+ @Override
public void purinePyrimidineColour_actionPerformed(ActionEvent actionEvent)
{
setJalviewColourScheme(new PurinePyrimidineColourScheme());
}
+ @Override
public void userColour_actionPerformed(ActionEvent actionEvent)
{
userColour.setSelected(true);
new UserDefinedColours(this, null);
}
+ @Override
public void backGround_actionPerformed(ActionEvent actionEvent)
{
java.awt.Color col = JColorChooser.showDialog(this,
- "Select Background Colour", null);
+ MessageManager.getString("label.select_backgroud_colour"), null);
if (col != null)
{
jmb.setBackgroundColour(col);
}
}
- public void jmolHelp_actionPerformed(ActionEvent actionEvent)
+ @Override
+ public void showHelp_actionPerformed(ActionEvent actionEvent)
{
try
{
this.setTitle(jmb.getViewerTitle());
if (jmb.getPdbFile().length > 1 && jmb.sequence.length > 1)
{
- jmolActionMenu.setVisible(true);
+ viewerActionMenu.setVisible(true);
}
if (!jmb.isLoadingFromArchive())
{
_alignwith.add(ap);
}
;
- for (Component c : jmolActionMenu.getMenuComponents())
+ for (Component c : viewerActionMenu.getMenuComponents())
{
if (c != alignStructs)
{
- jmolActionMenu.remove((JMenuItem) c);
+ viewerActionMenu.remove((JMenuItem) c);
}
}
final ItemListener handler;
return !jmb.isColourBySequence();
}
+ public JalviewJmolBinding getBinding()
+ {
+ return jmb;
+ }
+
}
*/
package jalview.gui;
-import javax.swing.JOptionPane;
+import jalview.api.StructureSelectionManagerProvider;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
+import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
+import javax.swing.JOptionPane;
+
/**
* GUI related routines for associating PDB files with sequences
*
* @param sequence
*/
public PDBEntry associatePdbWithSeq(String choice, String protocol,
- SequenceI sequence, boolean prompt)
+ SequenceI sequence, boolean prompt,
+ StructureSelectionManagerProvider ssmp)
{
PDBEntry entry = new PDBEntry();
- try
+ MCview.PDBfile pdbfile = null;
+ pdbfile = StructureSelectionManager.getStructureSelectionManager(ssmp)
+ .setMapping(false, new SequenceI[]
+ { sequence }, null, choice, protocol);
+ if (pdbfile == null)
+ {
+ // stacktrace already thrown so just return
+ return null;
+ }
+ if (pdbfile.id == null)
{
- MCview.PDBfile pdbfile = new MCview.PDBfile(choice, protocol);
+ String reply = null;
- if (pdbfile.id == null)
+ if (prompt)
{
- String reply = null;
-
- if (prompt)
- {
- reply = JOptionPane.showInternalInputDialog(Desktop.desktop,
- MessageManager
- .getString("label.couldnt_find_pdb_id_in_file"),
- MessageManager.getString("label.no_pdb_id_in_file"),
- JOptionPane.QUESTION_MESSAGE);
- }
- if (reply == null)
- {
- return null;
- }
-
- entry.setId(reply);
+ reply = JOptionPane.showInternalInputDialog(Desktop.desktop,
+ MessageManager
+ .getString("label.couldnt_find_pdb_id_in_file"),
+ MessageManager.getString("label.no_pdb_id_in_file"),
+ JOptionPane.QUESTION_MESSAGE);
}
- else
+ if (reply == null)
{
- entry.setId(pdbfile.id);
+ return null;
}
- } catch (java.io.IOException ex)
+ entry.setId(reply);
+ }
+ else
{
- ex.printStackTrace();
+ entry.setId(pdbfile.id);
}
- entry.setFile(choice);
- sequence.getDatasetSequence().addPDBId(entry);
+ if (pdbfile != null)
+ {
+ entry.setFile(choice);
+ sequence.getDatasetSequence().addPDBId(entry);
+ StructureSelectionManager.getStructureSelectionManager(ssmp)
+ .registerPDBEntry(entry);
+ }
return entry;
}
}
{
createDialog();
bounds = new Rectangle(5, 5, 550, 350);
- jd.initDialogFrame(me, false, false, "News from www.jalview.org",
+ jd.initDialogFrame(me, false, false, MessageManager.getString("label.news_from_jalview"),
bounds.width, bounds.height);
jd.frame.setModalExclusionType(ModalExclusionType.NO_EXCLUDE);
Cache.log.info("Displaying news.");
topBottomSplitPane.setBottomComponent(bottomPanel);
JScrollPane spTextDescription = new JScrollPane(textDescription);
textDescription.setText("");
- statusBar.setText(MessageManager.getString("label.status"));
+ statusBar.setText(new StringBuffer("[").append(MessageManager.getString("label.status")).append("]").toString());
buttonRefresh.addActionListener(new ActionListener()
{
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview 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.
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.gui;
+
+import jalview.api.SequenceStructureBinding;
+import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.gui.ViewSelectionMenu.ViewSetProvider;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.jbgui.GStructureViewer;
+import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.HelixColourScheme;
+import jalview.schemes.HydrophobicColourScheme;
+import jalview.schemes.PurinePyrimidineColourScheme;
+import jalview.schemes.StrandColourScheme;
+import jalview.schemes.TaylorColourScheme;
+import jalview.schemes.TurnColourScheme;
+import jalview.schemes.ZappoColourScheme;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+import jalview.ws.dbsources.Pdb;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JInternalFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
+
+/**
+ * GUI elements for handlnig an external chimera display
+ *
+ * @author jprocter
+ *
+ */
+public class ChimeraViewFrame extends GStructureViewer implements Runnable,
+ ViewSetProvider, JalviewStructureDisplayI
+
+{
+ private JalviewChimeraBindingModel jmb;
+
+ /*
+ * list of sequenceSet ids associated with the view
+ */
+ private ArrayList<String> _aps = new ArrayList<String>();
+
+ /*
+ * list of alignment panels to use for superposition
+ */
+ private Vector<AlignmentPanel> _alignwith = new Vector<AlignmentPanel>();
+
+ /*
+ * list of alignment panels that are used for colouring structures by aligned
+ * sequences
+ */
+ private Vector<AlignmentPanel> _colourwith = new Vector<AlignmentPanel>();
+
+ private boolean allChainsSelected = false;
+
+ private boolean alignAddedStructures = false;
+
+ AlignmentPanel ap;
+
+ /*
+ * state flag for PDB retrieval thread
+ */
+ private boolean _started = false;
+
+ private boolean addingStructures = false;
+
+ private IProgressIndicator progressBar = null;
+
+ private String viewId = null;
+
+ /*
+ * pdb retrieval thread.
+ */
+ private Thread worker = null;
+
+ /**
+ * Initialise menu options.
+ */
+ private void initMenus()
+ {
+ viewerActionMenu.setText(MessageManager.getString("label.chimera"));
+ viewerColour.setText(MessageManager
+ .getString("label.colour_with_chimera"));
+ viewerColour.setToolTipText(MessageManager
+ .getString("label.let_chimera_manage_structure_colours"));
+ helpItem.setText(MessageManager.getString("label.chimera_help"));
+ seqColour.setSelected(jmb.isColourBySequence());
+ viewerColour.setSelected(!jmb.isColourBySequence());
+ if (_colourwith == null)
+ {
+ _colourwith = new Vector<AlignmentPanel>();
+ }
+ if (_alignwith == null)
+ {
+ _alignwith = new Vector<AlignmentPanel>();
+ }
+
+ ViewSelectionMenu seqColourBy = new ViewSelectionMenu(
+ MessageManager.getString("label.colour_by"), this, _colourwith,
+ new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent e)
+ {
+ if (!seqColour.isSelected())
+ {
+ seqColour.doClick();
+ }
+ else
+ {
+ // update the Chimera display now.
+ seqColour_actionPerformed(null);
+ }
+ }
+ });
+ viewMenu.add(seqColourBy);
+ final ItemListener handler;
+ JMenu alpanels = new ViewSelectionMenu(
+ MessageManager.getString("label.superpose_with"), this,
+ _alignwith, handler = new ItemListener()
+ {
+ @Override
+ public void itemStateChanged(ItemEvent e)
+ {
+ alignStructs.setEnabled(_alignwith.size() > 0);
+ alignStructs.setToolTipText(MessageManager
+ .formatMessage(
+ "label.align_structures_using_linked_alignment_views",
+ new Object[]
+ { new Integer(_alignwith.size()).toString() }));
+ }
+ });
+ handler.itemStateChanged(null);
+ viewerActionMenu.add(alpanels);
+ viewerActionMenu.addMenuListener(new MenuListener()
+ {
+
+ @Override
+ public void menuSelected(MenuEvent e)
+ {
+ handler.itemStateChanged(null);
+ }
+
+ @Override
+ public void menuDeselected(MenuEvent e)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void menuCanceled(MenuEvent e)
+ {
+ // TODO Auto-generated method stub
+ }
+ });
+ }
+
+ /**
+ * add a single PDB structure to a new or existing Chimera view
+ *
+ * @param pdbentry
+ * @param seq
+ * @param chains
+ * @param ap
+ */
+ public ChimeraViewFrame(PDBEntry pdbentry, SequenceI[] seq,
+ String[] chains, final AlignmentPanel ap)
+ {
+ super();
+ progressBar = ap.alignFrame;
+ // ////////////////////////////////
+ // Is the pdb file already loaded?
+ String alreadyMapped = ap.getStructureSelectionManager()
+ .alreadyMappedToFile(pdbentry.getId());
+
+ if (alreadyMapped != null)
+ {
+ int option = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+ MessageManager.formatMessage(
+ "label.pdb_entry_is_already_displayed", new Object[]
+ { pdbentry.getId() }), MessageManager.formatMessage(
+ "label.map_sequences_to_visible_window", new Object[]
+ { pdbentry.getId() }),
+ JOptionPane.YES_NO_CANCEL_OPTION);
+
+ if (option == JOptionPane.CANCEL_OPTION)
+ {
+ return;
+ }
+ if (option == JOptionPane.YES_OPTION)
+ {
+ // TODO : Fix multiple seq to one chain issue here.
+ ap.getStructureSelectionManager().setMapping(seq, chains,
+ alreadyMapped, AppletFormatAdapter.FILE);
+ if (ap.seqPanel.seqCanvas.fr != null)
+ {
+ ap.seqPanel.seqCanvas.fr.featuresAdded();
+ ap.paintAlignment(true);
+ }
+
+ // Now this ChimeraViewFrame is mapped to new sequences. We must add
+ // them to the existing array
+ JInternalFrame[] frames = Desktop.instance.getAllFrames();
+
+ for (JInternalFrame frame : frames)
+ {
+ if (frame instanceof ChimeraViewFrame)
+ {
+ final ChimeraViewFrame topView = ((ChimeraViewFrame) frame);
+ // JBPNOTE: this looks like a binding routine, rather than a gui
+ // routine
+ for (int pe = 0; pe < topView.jmb.pdbentry.length; pe++)
+ {
+ if (topView.jmb.pdbentry[pe].getFile().equals(alreadyMapped))
+ {
+ topView.jmb.addSequence(pe, seq);
+ topView.addAlignmentPanel(ap);
+ // add it to the set used for colouring
+ topView.useAlignmentPanelForColourbyseq(ap);
+ topView.buildChimeraActionMenu();
+ ap.getStructureSelectionManager()
+ .sequenceColoursChanged(ap);
+ break;
+ }
+ }
+ }
+ }
+
+ return;
+ }
+ }
+ // /////////////////////////////////
+ // Check if there are other Chimera views involving this alignment
+ // and prompt user about adding this molecule to one of them
+ List<ChimeraViewFrame> existingViews = getChimeraWindowsFor(ap);
+ for (ChimeraViewFrame topView : existingViews)
+ {
+ // TODO: highlight topView in view somehow
+ int option = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
+ MessageManager.formatMessage("label.add_pdbentry_to_view",
+ new Object[]
+ { pdbentry.getId(), topView.getTitle() }),
+ MessageManager
+ .getString("label.align_to_existing_structure_view"),
+ JOptionPane.YES_NO_CANCEL_OPTION);
+ if (option == JOptionPane.CANCEL_OPTION)
+ {
+ return;
+ }
+ if (option == JOptionPane.YES_OPTION)
+ {
+ topView.useAlignmentPanelForSuperposition(ap);
+ topView.addStructure(pdbentry, seq, chains, true, ap.alignFrame);
+ return;
+ }
+ }
+ // /////////////////////////////////
+ openNewChimera(ap, new PDBEntry[]
+ { pdbentry }, new SequenceI[][]
+ { seq });
+ }
+
+ private void openNewChimera(AlignmentPanel ap, PDBEntry[] pdbentrys,
+ SequenceI[][] seqs)
+ {
+ progressBar = ap.alignFrame;
+ jmb = new JalviewChimeraBindingModel(this,
+ ap.getStructureSelectionManager(), pdbentrys, seqs, null, null);
+ addAlignmentPanel(ap);
+ useAlignmentPanelForColourbyseq(ap);
+ if (pdbentrys.length > 1)
+ {
+ alignAddedStructures = true;
+ useAlignmentPanelForSuperposition(ap);
+ }
+ jmb.setColourBySequence(true);
+ setSize(400, 400); // probably should be a configurable/dynamic default here
+ initMenus();
+ worker = null;
+ {
+ addingStructures = false;
+ worker = new Thread(this);
+ worker.start();
+ }
+ this.addInternalFrameListener(new InternalFrameAdapter()
+ {
+ public void internalFrameClosing(InternalFrameEvent internalFrameEvent)
+ {
+ closeViewer();
+ }
+ });
+
+ }
+
+ /**
+ * create a new viewer containing several structures superimposed using the
+ * given alignPanel.
+ *
+ * @param ap
+ * @param pe
+ * @param seqs
+ */
+ public ChimeraViewFrame(AlignmentPanel ap, PDBEntry[] pe,
+ SequenceI[][] seqs)
+ {
+ super();
+ openNewChimera(ap, pe, seqs);
+ }
+
+ public AlignmentPanel[] getAllAlignmentPanels()
+ {
+ AlignmentPanel[] t, list = new AlignmentPanel[0];
+ for (String setid : _aps)
+ {
+ AlignmentPanel[] panels = PaintRefresher.getAssociatedPanels(setid);
+ if (panels != null)
+ {
+ t = new AlignmentPanel[list.length + panels.length];
+ System.arraycopy(list, 0, t, 0, list.length);
+ System.arraycopy(panels, 0, t, list.length, panels.length);
+ list = t;
+ }
+ }
+
+ return list;
+ }
+
+ /**
+ * set the primary alignmentPanel reference and add another alignPanel to the
+ * list of ones to use for colouring and aligning
+ *
+ * @param nap
+ */
+ public void addAlignmentPanel(AlignmentPanel nap)
+ {
+ if (ap == null)
+ {
+ ap = nap;
+ }
+ if (!_aps.contains(nap.av.getSequenceSetId()))
+ {
+ _aps.add(nap.av.getSequenceSetId());
+ }
+ }
+
+ /**
+ * remove any references held to the given alignment panel
+ *
+ * @param nap
+ */
+ public void removeAlignmentPanel(AlignmentPanel nap)
+ {
+ try
+ {
+ _alignwith.remove(nap);
+ _colourwith.remove(nap);
+ if (ap == nap)
+ {
+ ap = null;
+ for (AlignmentPanel aps : getAllAlignmentPanels())
+ {
+ if (aps != nap)
+ {
+ ap = aps;
+ break;
+ }
+ }
+ }
+ } catch (Exception ex)
+ {
+ }
+ if (ap != null)
+ {
+ buildChimeraActionMenu();
+ }
+ }
+
+ public void useAlignmentPanelForSuperposition(AlignmentPanel nap)
+ {
+ addAlignmentPanel(nap);
+ if (!_alignwith.contains(nap))
+ {
+ _alignwith.add(nap);
+ }
+ }
+
+ public void excludeAlignmentPanelForSuperposition(AlignmentPanel nap)
+ {
+ if (_alignwith.contains(nap))
+ {
+ _alignwith.remove(nap);
+ }
+ }
+
+ public void useAlignmentPanelForColourbyseq(AlignmentPanel nap,
+ boolean enableColourBySeq)
+ {
+ useAlignmentPanelForColourbyseq(nap);
+ jmb.setColourBySequence(enableColourBySeq);
+ seqColour.setSelected(enableColourBySeq);
+ viewerColour.setSelected(!enableColourBySeq);
+ }
+
+ public void useAlignmentPanelForColourbyseq(AlignmentPanel nap)
+ {
+ addAlignmentPanel(nap);
+ if (!_colourwith.contains(nap))
+ {
+ _colourwith.add(nap);
+ }
+ }
+
+ public void excludeAlignmentPanelForColourbyseq(AlignmentPanel nap)
+ {
+ if (_colourwith.contains(nap))
+ {
+ _colourwith.remove(nap);
+ }
+ }
+
+ /**
+ * add a new structure (with associated sequences and chains) to this viewer,
+ * retrieving it if necessary first.
+ *
+ * @param pdbentry
+ * @param seq
+ * @param chains
+ * @param alignFrame
+ * @param align
+ * if true, new structure(s) will be align using associated alignment
+ */
+ private void addStructure(final PDBEntry pdbentry, final SequenceI[] seq,
+ final String[] chains, final boolean b,
+ final IProgressIndicator alignFrame)
+ {
+ if (pdbentry.getFile() == null)
+ {
+ if (worker != null && worker.isAlive())
+ {
+ // a retrieval is in progress, wait around and add ourselves to the
+ // queue.
+ new Thread(new Runnable()
+ {
+ public void run()
+ {
+ while (worker != null && worker.isAlive() && _started)
+ {
+ try
+ {
+ Thread.sleep(100 + ((int) Math.random() * 100));
+
+ } catch (Exception e)
+ {
+ }
+
+ }
+ // and call ourselves again.
+ addStructure(pdbentry, seq, chains, b, alignFrame);
+ }
+ }).start();
+ return;
+ }
+ }
+ // otherwise, start adding the structure.
+ jmb.addSequenceAndChain(new PDBEntry[]
+ { pdbentry }, new SequenceI[][]
+ { seq }, new String[][]
+ { chains });
+ addingStructures = true;
+ _started = false;
+ alignAddedStructures = b;
+ progressBar = alignFrame; // visual indication happens on caller frame.
+ (worker = new Thread(this)).start();
+ return;
+ }
+
+ private List<ChimeraViewFrame> getChimeraWindowsFor(AlignmentPanel apanel)
+ {
+ List<ChimeraViewFrame> result = new ArrayList<ChimeraViewFrame>();
+ JInternalFrame[] frames = Desktop.instance.getAllFrames();
+
+ for (JInternalFrame frame : frames)
+ {
+ if (frame instanceof ChimeraViewFrame)
+ {
+ if (((ChimeraViewFrame) frame).isLinkedWith(apanel))
+ {
+ result.add((ChimeraViewFrame) frame);
+ }
+ }
+ }
+ return result;
+ }
+
+ void initChimera(String command)
+ {
+ jmb.setFinishedInit(false);
+ // TODO: consider waiting until the structure/view is fully loaded before
+ // displaying
+ jalview.gui.Desktop.addInternalFrame(this, jmb.getViewerTitle(true),
+ getBounds().width, getBounds().height);
+ if (command == null)
+ {
+ command = "";
+ }
+ jmb.evalStateCommand(command, false);
+ jmb.setFinishedInit(true);
+ }
+
+ void setChainMenuItems(List<String> chainNames)
+ {
+ chainMenu.removeAll();
+ if (chainNames == null)
+ {
+ return;
+ }
+ JMenuItem menuItem = new JMenuItem(
+ MessageManager.getString("label.all"));
+ menuItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent evt)
+ {
+ allChainsSelected = true;
+ for (int i = 0; i < chainMenu.getItemCount(); i++)
+ {
+ if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
+ {
+ ((JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true);
+ }
+ }
+ centerViewer();
+ allChainsSelected = false;
+ }
+ });
+
+ chainMenu.add(menuItem);
+
+ for (String chainName : chainNames)
+ {
+ menuItem = new JCheckBoxMenuItem(chainName, true);
+ menuItem.addItemListener(new ItemListener()
+ {
+ public void itemStateChanged(ItemEvent evt)
+ {
+ if (!allChainsSelected)
+ {
+ centerViewer();
+ }
+ }
+ });
+
+ chainMenu.add(menuItem);
+ }
+ }
+
+ void centerViewer()
+ {
+ List<String> toshow = new ArrayList<String>();
+ for (int i = 0; i < chainMenu.getItemCount(); i++)
+ {
+ if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
+ {
+ JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i);
+ if (item.isSelected())
+ {
+ toshow.add(item.getText());
+ }
+ }
+ }
+ jmb.centerViewer(toshow);
+ }
+
+ /**
+ * Close down this instance of Jalview's Chimera viewer, giving the user the
+ * option to close the associated Chimera window (process). They may wish to
+ * keep it open until they have had an opportunity to save any work.
+ */
+ public void closeViewer()
+ {
+ if (jmb.isChimeraRunning())
+ {
+ String prompt = MessageManager
+ .formatMessage("label.confirm_close_chimera", new Object[]
+ { jmb.getViewerTitle(false) });
+ prompt = JvSwingUtils.wrapTooltip(true, prompt);
+ int confirm = JOptionPane.showConfirmDialog(this, prompt,
+ MessageManager.getString("label.close_viewer"),
+ JOptionPane.YES_NO_OPTION);
+ jmb.closeViewer(confirm == JOptionPane.YES_OPTION);
+ }
+ ap = null;
+ _aps.clear();
+ _alignwith.clear();
+ _colourwith.clear();
+ // TODO: check for memory leaks where instance isn't finalised because jmb
+ // holds a reference to the window
+ jmb = null;
+ }
+
+ /**
+ * Open any newly added PDB structures in Chimera, having first fetched data
+ * from PDB (if not already saved).
+ */
+ public void run()
+ {
+ _started = true;
+ // todo - record which pdbids were successfully imported.
+ StringBuilder errormsgs = new StringBuilder(128);
+ StringBuilder files = new StringBuilder(128);
+ List<PDBEntry> filePDB = new ArrayList<PDBEntry>();
+ List<Integer> filePDBpos = new ArrayList<Integer>();
+ PDBEntry thePdbEntry = null;
+ try
+ {
+ String[] curfiles = jmb.getPdbFile(); // files currently in viewer
+ // TODO: replace with reference fetching/transfer code (validate PDBentry
+ // as a DBRef?)
+ for (int pi = 0; pi < jmb.pdbentry.length; pi++)
+ {
+ String file = null;
+ thePdbEntry = jmb.pdbentry[pi];
+ if (thePdbEntry.getFile() == null)
+ {
+ /*
+ * Retrieve PDB data, save to file, attach to PDBEntry
+ */
+ file = fetchPdbFile(thePdbEntry);
+ if (file == null)
+ {
+ errormsgs.append("'" + thePdbEntry.getId() + "' ");
+ }
+ }
+ else
+ {
+ /*
+ * Got file already - ignore if already loaded in Chimera.
+ */
+ file = new File(thePdbEntry.getFile()).getAbsoluteFile()
+ .getPath();
+ if (curfiles != null && curfiles.length > 0)
+ {
+ addingStructures = true; // already files loaded.
+ for (int c = 0; c < curfiles.length; c++)
+ {
+ if (curfiles[c].equals(file))
+ {
+ file = null;
+ break;
+ }
+ }
+ }
+ }
+ if (file != null)
+ {
+ filePDB.add(thePdbEntry);
+ filePDBpos.add(Integer.valueOf(pi));
+ files.append(" \"" + Platform.escapeString(file) + "\"");
+ }
+ }
+ } catch (OutOfMemoryError oomerror)
+ {
+ new OOMWarning("Retrieving PDB files: " + thePdbEntry.getId(),
+ oomerror);
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ errormsgs.append("When retrieving pdbfiles for '"
+ + thePdbEntry.getId() + "'");
+ }
+ if (errormsgs.length() > 0)
+ {
+
+ JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+ .formatMessage("label.pdb_entries_couldnt_be_retrieved",
+ new Object[]
+ { errormsgs.toString() }), MessageManager
+ .getString("label.couldnt_load_file"),
+ JOptionPane.ERROR_MESSAGE);
+ }
+
+ if (files.length() > 0)
+ {
+ if (!addingStructures)
+ {
+ try
+ {
+ initChimera("");
+ } catch (Exception ex)
+ {
+ Cache.log.error("Couldn't open Chimera viewer!", ex);
+ }
+ }
+ int num = -1;
+ for (PDBEntry pe : filePDB)
+ {
+ num++;
+ if (pe.getFile() != null)
+ {
+ try
+ {
+ int pos = filePDBpos.get(num).intValue();
+ jmb.openFile(pe);
+ jmb.addSequence(pos, jmb.sequence[pos]);
+ File fl = new File(pe.getFile());
+ String protocol = AppletFormatAdapter.URL;
+ try
+ {
+ if (fl.exists())
+ {
+ protocol = AppletFormatAdapter.FILE;
+ }
+ } catch (Throwable e)
+ {
+ }
+ // Explicitly map to the filename used by Chimera ;
+ // TODO: use pe.getId() instead of pe.getFile() ?
+ jmb.ssm.setMapping(jmb.sequence[pos], null, pe.getFile(),
+ protocol);
+ } catch (OutOfMemoryError oomerror)
+ {
+ new OOMWarning(
+ "When trying to open and map structures from Chimera!",
+ oomerror);
+ } catch (Exception ex)
+ {
+ Cache.log.error("Couldn't open " + pe.getFile()
+ + " in Chimera viewer!", ex);
+ } finally
+ {
+ Cache.log.debug("File locations are " + files);
+ }
+ }
+ }
+ jmb.setFinishedInit(true);
+ jmb.setLoadingFromArchive(false);
+
+ // refresh the sequence colours for the new structure(s)
+ for (AlignmentPanel ap : _colourwith)
+ {
+ jmb.updateColours(ap);
+ }
+ // do superposition if asked to
+ if (alignAddedStructures)
+ {
+ new Thread(new Runnable()
+ {
+ public void run()
+ {
+ alignStructs_withAllAlignPanels();
+ }
+ }).start();
+ alignAddedStructures = false;
+ }
+ addingStructures = false;
+ }
+ _started = false;
+ worker = null;
+ }
+
+ /**
+ * Fetch PDB data and save to a local file. Returns the full path to the file,
+ * or null if fetch fails.
+ *
+ * @param processingEntry
+ * @return
+ * @throws Exception
+ */
+ private String fetchPdbFile(PDBEntry processingEntry) throws Exception
+ {
+ String filePath = null;
+ Pdb pdbclient = new Pdb();
+ AlignmentI pdbseq = null;
+ String pdbid = processingEntry.getId();
+ long hdl = pdbid.hashCode() - System.currentTimeMillis();
+ if (progressBar != null)
+ {
+ progressBar.setProgressBar(MessageManager.formatMessage(
+ "status.fetching_pdb", new Object[]
+ { pdbid }), hdl);
+ }
+ try
+ {
+ pdbseq = pdbclient.getSequenceRecords(pdbid);
+ } catch (OutOfMemoryError oomerror)
+ {
+ new OOMWarning("Retrieving PDB id " + pdbid, oomerror);
+ } finally
+ {
+ if (progressBar != null)
+ {
+ progressBar.setProgressBar(
+ MessageManager.getString("label.state_completed"), hdl);
+ }
+ }
+ /*
+ * If PDB data were saved and are not invalid (empty alignment), return the
+ * file path.
+ */
+ if (pdbseq != null && pdbseq.getHeight() > 0)
+ {
+ // just use the file name from the first sequence's first PDBEntry
+ filePath = new File(((PDBEntry) pdbseq.getSequenceAt(0).getPDBId()
+ .elementAt(0)).getFile()).getAbsolutePath();
+ processingEntry.setFile(filePath);
+ }
+ return filePath;
+ }
+
+ @Override
+ public void pdbFile_actionPerformed(ActionEvent actionEvent)
+ {
+ JalviewFileChooser chooser = new JalviewFileChooser(
+ jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
+
+ chooser.setFileView(new JalviewFileView());
+ chooser.setDialogTitle(MessageManager.getString("label.save_pdb_file"));
+ chooser.setToolTipText(MessageManager.getString("action.save"));
+
+ int value = chooser.showSaveDialog(this);
+
+ if (value == JalviewFileChooser.APPROVE_OPTION)
+ {
+ BufferedReader in = null;
+ try
+ {
+ // TODO: cope with multiple PDB files in view
+ in = new BufferedReader(new FileReader(jmb.getPdbFile()[0]));
+ File outFile = chooser.getSelectedFile();
+
+ PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
+ String data;
+ while ((data = in.readLine()) != null)
+ {
+ if (!(data.indexOf("<PRE>") > -1 || data.indexOf("</PRE>") > -1))
+ {
+ out.println(data);
+ }
+ }
+ out.close();
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ } finally
+ {
+ if (in != null)
+ {
+ try
+ {
+ in.close();
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void viewMapping_actionPerformed(ActionEvent actionEvent)
+ {
+ jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer();
+ try
+ {
+ for (int pdbe = 0; pdbe < jmb.pdbentry.length; pdbe++)
+ {
+ cap.appendText(jmb.printMapping(jmb.pdbentry[pdbe].getFile()));
+ cap.appendText("\n");
+ }
+ } catch (OutOfMemoryError e)
+ {
+ new OOMWarning(
+ "composing sequence-structure alignments for display in text box.",
+ e);
+ cap.dispose();
+ return;
+ }
+ jalview.gui.Desktop.addInternalFrame(cap,
+ MessageManager.getString("label.pdb_sequence_mapping"), 550,
+ 600);
+ }
+
+ @Override
+ public void eps_actionPerformed(ActionEvent e)
+ {
+ throw new Error(
+ MessageManager
+ .getString("error.eps_generation_not_implemented"));
+ }
+
+ @Override
+ public void png_actionPerformed(ActionEvent e)
+ {
+ throw new Error(
+ MessageManager
+ .getString("error.png_generation_not_implemented"));
+ }
+
+ @Override
+ public void viewerColour_actionPerformed(ActionEvent actionEvent)
+ {
+ if (viewerColour.isSelected())
+ {
+ // disable automatic sequence colouring.
+ jmb.setColourBySequence(false);
+ }
+ }
+
+ @Override
+ public void seqColour_actionPerformed(ActionEvent actionEvent)
+ {
+ jmb.setColourBySequence(seqColour.isSelected());
+ if (_colourwith == null)
+ {
+ _colourwith = new Vector<AlignmentPanel>();
+ }
+ if (jmb.isColourBySequence())
+ {
+ if (!jmb.isLoadingFromArchive())
+ {
+ if (_colourwith.size() == 0 && ap != null)
+ {
+ // Make the currently displayed alignment panel the associated view
+ _colourwith.add(ap.alignFrame.alignPanel);
+ }
+ }
+ // Set the colour using the current view for the associated alignframe
+ for (AlignmentPanel ap : _colourwith)
+ {
+ jmb.colourBySequence(ap.av.isShowSequenceFeatures(), ap);
+ }
+ }
+ }
+
+ @Override
+ public void chainColour_actionPerformed(ActionEvent actionEvent)
+ {
+ chainColour.setSelected(true);
+ jmb.colourByChain();
+ }
+
+ @Override
+ public void chargeColour_actionPerformed(ActionEvent actionEvent)
+ {
+ chargeColour.setSelected(true);
+ jmb.colourByCharge();
+ }
+
+ @Override
+ public void zappoColour_actionPerformed(ActionEvent actionEvent)
+ {
+ zappoColour.setSelected(true);
+ jmb.setJalviewColourScheme(new ZappoColourScheme());
+ }
+
+ @Override
+ public void taylorColour_actionPerformed(ActionEvent actionEvent)
+ {
+ taylorColour.setSelected(true);
+ jmb.setJalviewColourScheme(new TaylorColourScheme());
+ }
+
+ @Override
+ public void hydroColour_actionPerformed(ActionEvent actionEvent)
+ {
+ hydroColour.setSelected(true);
+ jmb.setJalviewColourScheme(new HydrophobicColourScheme());
+ }
+
+ @Override
+ public void helixColour_actionPerformed(ActionEvent actionEvent)
+ {
+ helixColour.setSelected(true);
+ jmb.setJalviewColourScheme(new HelixColourScheme());
+ }
+
+ @Override
+ public void strandColour_actionPerformed(ActionEvent actionEvent)
+ {
+ strandColour.setSelected(true);
+ jmb.setJalviewColourScheme(new StrandColourScheme());
+ }
+
+ @Override
+ public void turnColour_actionPerformed(ActionEvent actionEvent)
+ {
+ turnColour.setSelected(true);
+ jmb.setJalviewColourScheme(new TurnColourScheme());
+ }
+
+ @Override
+ public void buriedColour_actionPerformed(ActionEvent actionEvent)
+ {
+ buriedColour.setSelected(true);
+ jmb.setJalviewColourScheme(new BuriedColourScheme());
+ }
+
+ @Override
+ public void purinePyrimidineColour_actionPerformed(ActionEvent actionEvent)
+ {
+ setJalviewColourScheme(new PurinePyrimidineColourScheme());
+ }
+
+ @Override
+ public void userColour_actionPerformed(ActionEvent actionEvent)
+ {
+ userColour.setSelected(true);
+ new UserDefinedColours(this, null);
+ }
+
+ @Override
+ public void backGround_actionPerformed(ActionEvent actionEvent)
+ {
+ java.awt.Color col = JColorChooser
+ .showDialog(this, MessageManager
+ .getString("label.select_backgroud_colour"), null);
+ if (col != null)
+ {
+ jmb.setBackgroundColour(col);
+ }
+ }
+
+ @Override
+ public void showHelp_actionPerformed(ActionEvent actionEvent)
+ {
+ try
+ {
+ jalview.util.BrowserLauncher
+ .openURL("https://www.cgl.ucsf.edu/chimera/docs/UsersGuide");
+ } catch (Exception ex)
+ {
+ }
+ }
+
+ public String getViewId()
+ {
+ if (viewId == null)
+ {
+ viewId = System.currentTimeMillis() + "." + this.hashCode();
+ }
+ return viewId;
+ }
+
+ public void updateTitleAndMenus()
+ {
+ if (jmb.fileLoadingError != null && jmb.fileLoadingError.length() > 0)
+ {
+ repaint();
+ return;
+ }
+ setChainMenuItems(jmb.chainNames);
+
+ this.setTitle(jmb.getViewerTitle(true));
+ if (jmb.getPdbFile().length > 1 && jmb.sequence.length > 1)
+ {
+ viewerActionMenu.setVisible(true);
+ }
+ if (!jmb.isLoadingFromArchive())
+ {
+ seqColour_actionPerformed(null);
+ }
+ }
+
+ protected void buildChimeraActionMenu()
+ {
+ if (_alignwith == null)
+ {
+ _alignwith = new Vector<AlignmentPanel>();
+ }
+ if (_alignwith.size() == 0 && ap != null)
+ {
+ _alignwith.add(ap);
+ }
+ ;
+ for (Component c : viewerActionMenu.getMenuComponents())
+ {
+ if (c != alignStructs)
+ {
+ viewerActionMenu.remove((JMenuItem) c);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.jbgui.GStructureViewer#alignStructs_actionPerformed(java.awt.event
+ * .ActionEvent)
+ */
+ @Override
+ protected void alignStructs_actionPerformed(ActionEvent actionEvent)
+ {
+ alignStructs_withAllAlignPanels();
+ }
+
+ private void alignStructs_withAllAlignPanels()
+ {
+ if (ap == null)
+ {
+ return;
+ }
+ ;
+ if (_alignwith.size() == 0)
+ {
+ _alignwith.add(ap);
+ }
+ ;
+ try
+ {
+ AlignmentI[] als = new Alignment[_alignwith.size()];
+ ColumnSelection[] alc = new ColumnSelection[_alignwith.size()];
+ int[] alm = new int[_alignwith.size()];
+ int a = 0;
+
+ for (AlignmentPanel ap : _alignwith)
+ {
+ als[a] = ap.av.getAlignment();
+ alm[a] = -1;
+ alc[a++] = ap.av.getColumnSelection();
+ }
+ jmb.superposeStructures(als, alm, alc);
+ } catch (Exception e)
+ {
+ StringBuffer sp = new StringBuffer();
+ for (AlignmentPanel ap : _alignwith)
+ {
+ sp.append("'" + ap.alignFrame.getTitle() + "' ");
+ }
+ Cache.log.info("Couldn't align structures with the " + sp.toString()
+ + "associated alignment panels.", e);
+
+ }
+
+ }
+
+ public void setJalviewColourScheme(ColourSchemeI ucs)
+ {
+ jmb.setJalviewColourScheme(ucs);
+
+ }
+
+ /**
+ *
+ * @param alignment
+ * @return first alignment panel displaying given alignment, or the default
+ * alignment panel
+ */
+ public AlignmentPanel getAlignmentPanelFor(AlignmentI alignment)
+ {
+ for (AlignmentPanel ap : getAllAlignmentPanels())
+ {
+ if (ap.av.getAlignment() == alignment)
+ {
+ return ap;
+ }
+ }
+ return ap;
+ }
+
+ /**
+ *
+ * @param ap2
+ * @return true if this Chimera instance is linked with the given alignPanel
+ */
+ public boolean isLinkedWith(AlignmentPanel ap2)
+ {
+ return _aps.contains(ap2.av.getSequenceSetId());
+ }
+
+ public boolean isUsedforaligment(AlignmentPanel ap2)
+ {
+
+ return (_alignwith != null) && _alignwith.contains(ap2);
+ }
+
+ public boolean isUsedforcolourby(AlignmentPanel ap2)
+ {
+ return (_colourwith != null) && _colourwith.contains(ap2);
+ }
+
+ /**
+ *
+ * @return TRUE if the view is NOT being coloured by sequence associations.
+ */
+ public boolean isColouredByChimera()
+ {
+ return !jmb.isColourBySequence();
+ }
+
+ public SequenceStructureBinding getBinding()
+ {
+ return jmb;
+ }
+
+}
} catch (InterruptedException ie)
{
}
- throw new NullPointerException(
- "Application test: throwing an NullPointerException It should arrive at the console");
+ throw new NullPointerException(MessageManager.getString("exception.application_test_npe"));
}
}
chooser.setAcceptAllFileFilterUsed(false);
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Save Text to File");
+ chooser.setDialogTitle(MessageManager.getString("label.save_text_to_file"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
chooser.setAcceptAllFileFilterUsed(false);
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Save Text to File");
+ chooser.setDialogTitle(MessageManager.getString("label.save_text_to_file"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
}
private String[] columnNames = new String[]
- { "Nickname", "Use Source" };
+ { MessageManager.getString("label.nickname"), MessageManager.getString("label.use_source") };
private Object[][] data;
import jalview.io.IdentifyFile;
import jalview.io.JalviewFileChooser;
import jalview.io.JalviewFileView;
+import jalview.util.ImageMaker;
import jalview.util.MessageManager;
import jalview.ws.params.ParamManager;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkEvent.EventType;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
-import javax.swing.event.HyperlinkEvent.EventType;
/**
* Jalview Desktop
else
{
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- setBounds((int) (screenSize.width - 900) / 2,
- (int) (screenSize.height - 650) / 2, 900, 650);
+ setBounds((screenSize.width - 900) / 2,
+ (screenSize.height - 650) / 2, 900, 650);
}
jconsole = new Console(this, showjconsole);
// add essential build information
public void run()
{
long instance = System.currentTimeMillis();
- Desktop.instance.setProgressBar("Refreshing news", instance);
+ Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
jvnews.refreshNews();
Desktop.instance.setProgressBar(null, instance);
jvnews.showNews();
if (format.equals("URL NOT FOUND"))
{
JOptionPane.showInternalMessageDialog(Desktop.desktop,
- "Couldn't locate " + url, "URL not found",
+ MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
JOptionPane.WARNING_MESSAGE);
return;
{
CutAndPasteTransfer cap = new CutAndPasteTransfer();
cap.setForInput(viewport);
- Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
+ Desktop.addInternalFrame(cap, MessageManager.getString("label.cut_paste_alignmen_file"), 600, 500);
}
/*
{
try
{
- ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
- java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
- javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
-
- javax.help.HelpBroker hb = hs.createHelpBroker();
- hb.setCurrentID("home");
- hb.setDisplayed(true);
+ Help.showHelpWindow();
} catch (Exception ex)
{
}
{ "Jalview Project" }, "Jalview Project");
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Save State");
+ chooser.setDialogTitle(MessageManager.getString("label.save_state"));
int value = chooser.showSaveDialog(this);
public void run()
{
- setProgressBar("Saving jalview project " + choice.getName(),
+ setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
choice.hashCode());
jalview.bin.Cache.setProperty("LAST_DIRECTORY",
choice.getParent());
ex);
JOptionPane.showMessageDialog(
me,
- "Error whilst saving current state to "
- + choice.getName(), "Couldn't save project",
+ MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
+ MessageManager.getString("label.couldnt_save_project"),
JOptionPane.WARNING_MESSAGE);
}
setProgressBar(null, choice.hashCode());
{ "Jalview Project", "Jalview Project (old)" },
"Jalview Project");
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Restore state");
+ chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
int value = chooser.showOpenDialog(this);
{
public void run()
{
- setProgressBar("loading jalview project " + choice,
+ setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
choice.hashCode());
try
{
Cache.log.error("Problems whilst loading project from "
+ choice, ex);
JOptionPane.showMessageDialog(Desktop.desktop,
- "Error whilst loading project from " + choice,
- "Couldn't load project", JOptionPane.WARNING_MESSAGE);
+ MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
+ MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
}
setProgressBar(null, choice.hashCode());
}
{
if (fileLoadingCount == 0)
{
- fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName
- + " "));
+ fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
}
fileLoadingCount++;
}
jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Open a saved VAMSAS session");
+ chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
chooser.setToolTipText(MessageManager
.getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
return false;
}
- setProgressBar("Importing VAMSAS session from " + file.getName(),
+ setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
file.hashCode());
try
{
v_client = new jalview.gui.VamsasApplication(this, file, null);
} catch (Exception ex)
{
- setProgressBar("Importing VAMSAS session from " + file.getName(),
- file.hashCode());
+ setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
+ file.hashCode());
jalview.bin.Cache.log.error(
"New vamsas session from existing session file failed:", ex);
return false;
}
setupVamsasConnectedGui();
v_client.initial_update(); // TODO: thread ?
- setProgressBar("Importing VAMSAS session from " + file.getName(),
+ setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
file.hashCode());
return v_client.inSession();
}
{
if (v_client != null)
{
- throw new Error(
- "Trying to join a vamsas session when another is already connected.");
+ throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
}
if (mysesid == null)
{
- throw new Error("Invalid vamsas session id.");
+ throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
}
v_client = new VamsasApplication(this, mysesid);
setupVamsasConnectedGui();
{ "Vamsas Document" }, "Vamsas Document");
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Save Vamsas Document Archive");
+ chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
int value = chooser.showSaveDialog(this);
if (value == JalviewFileChooser.APPROVE_OPTION)
{
java.io.File choice = chooser.getSelectedFile();
- JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
- + choice.getName());
+ JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
String warnmsg = null;
String warnttl = null;
}
if (b)
{
- vamUpdate = this.addProgressPanel("Updating vamsas session");
+ vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
}
vamsasStart.setVisible(!b);
vamsasStop.setVisible(!b);
if (showMemoryUsage && g != null && df != null)
{
if (percentUsage < 20)
+ {
g.setColor(Color.red);
+ }
FontMetrics fm = g.getFontMetrics();
if (fm != null)
{
// use reflection to avoid creating compilation dependency.
if (!jalview.bin.Cache.groovyJarsPresent())
{
- throw new Error(
- "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
+ throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
}
try
{
.showInternalMessageDialog(
Desktop.desktop,
- "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
- "Jalview Groovy Support Failed",
+ MessageManager.getString("label.couldnt_create_groovy_shell"),
+ MessageManager.getString("label.groovy_support_failed"),
JOptionPane.ERROR_MESSAGE);
}
}
{
if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
{
- throw new Error(
- "call setProgressBar before registering the progress bar's handler.");
+ throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
}
progressBarHandlers.put(new Long(id), handler);
- final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
+ final JPanel progressPanel = progressBars.get(new Long(id));
if (handler.canCancel())
{
JButton cancel = new JButton(
public void actionPerformed(ActionEvent e)
{
handler.cancelActivity(id);
- us.setProgressBar(
- "Cancelled "
- + ((JLabel) progressPanel.getComponent(0))
- .getText(), id);
+ us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
}
});
progressPanel.add(cancel, BorderLayout.EAST);
{
if (progress != null)
{
- progress.setProgressBar("Opening " + url, this.hashCode());
+ progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
}
jalview.util.BrowserLauncher.openURL(url);
} catch (Exception ex)
JOptionPane
.showInternalMessageDialog(
Desktop.desktop,
- "Unixers: Couldn't find default web browser."
- + "\nAdd the full path to your browser in Preferences.",
- "Web browser not found",
+ MessageManager.getString("label.web_browser_not_found_unix"),
+ MessageManager.getString("label.web_browser_not_found"),
JOptionPane.WARNING_MESSAGE);
ex.printStackTrace();
dialogPause = false;
block.release();
}
+ @Override
+ protected void snapShotWindow_actionPerformed(ActionEvent e)
+ {
+ invalidate();
+ File of;
+ ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
+ "View of Desktop", getWidth(), getHeight(), of = new File(
+ "Jalview_snapshot" + System.currentTimeMillis()
+ + ".eps"), "View of desktop");
+ try {
+ paintAll(im.getGraphics());
+ im.writeImage();
+ } catch (Exception q)
+ {
+ Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
+ return;
+ }
+ Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());
+ }
}
if (fcol instanceof Color)
{
Color col = JColorChooser.showDialog(Desktop.desktop,
- "Select Feature Colour", ((Color) fcol));
+ MessageManager.getString("label.select_feature_colour"), ((Color) fcol));
if (col != null)
{
fcol = col;
{ "OK", "Cancel" };
}
- String title = newFeatures ? "Create New Sequence Feature(s)"
- : "Amend/Delete Features for " + sequences[0].getName();
+ String title = newFeatures ? MessageManager.getString("label.create_new_sequence_features")
+ : MessageManager.formatMessage("label.amend_delete_features", new String[]{sequences[0].getName()});
int reply = JOptionPane.showInternalOptionDialog(Desktop.desktop,
bigPanel, title, JOptionPane.YES_NO_CANCEL_OPTION,
- JOptionPane.QUESTION_MESSAGE, null, options, "OK");
+ JOptionPane.QUESTION_MESSAGE, null, options, MessageManager.getString("action.ok"));
jalview.io.FeaturesFile ffile = new jalview.io.FeaturesFile();
*/
package jalview.gui;
-import java.io.*;
-import java.util.*;
-import java.util.List;
-import java.awt.*;
-import java.awt.event.*;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-
-import javax.swing.*;
-import javax.swing.event.*;
-import javax.swing.table.*;
-
-import jalview.analysis.AlignmentSorter;
-import jalview.api.FeaturesDisplayedI;
import jalview.bin.Cache;
-import jalview.commands.OrderCommand;
-import jalview.datamodel.*;
-import jalview.io.*;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.io.JalviewFileChooser;
import jalview.schemes.AnnotationColourGradient;
import jalview.schemes.GraduatedColor;
import jalview.util.MessageManager;
import jalview.ws.dbsources.das.api.jalviewSourceI;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.GridLayout;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.swing.AbstractCellEditor;
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JDialog;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
+import javax.swing.JLayeredPane;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JSlider;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+
public class FeatureSettings extends JPanel
{
DasSourceBrowser dassourceBrowser;
public void mousePressed(MouseEvent evt)
{
selectedRow = table.rowAtPoint(evt.getPoint());
- if (evt.isPopupTrigger())
+ if (SwingUtilities.isRightMouseButton(evt))
{
popupSort(selectedRow, (String) table.getValueAt(selectedRow, 0),
table.getValueAt(selectedRow, 1), fr.getMinMax(),
(String) table.getValueAt(selectedRow, 0));
}
}
+
+ // isPopupTrigger fires on mouseReleased on Mac
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ selectedRow = table.rowAtPoint(evt.getPoint());
+ if (evt.isPopupTrigger())
+ {
+ popupSort(selectedRow, (String) table.getValueAt(selectedRow, 0),
+ table.getValueAt(selectedRow, 1), fr.getMinMax(),
+ evt.getX(),
+ evt.getY());
+ }
+ }
});
table.addMouseMotionListener(new MouseMotionAdapter()
}
}
});
- table.setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip("Click/drag feature types up or down to change render order.<br/>Double click to select columns containing feature in alignment/current selection<br/>Pressing Alt will select columns outside features rather than inside<br/>Pressing Shift to modify current selection (rather than clear current selection)<br/>Press CTRL or Command/Meta to toggle columns in/outside features<br/>")
- + "</html>");
+ table.setToolTipText(JvSwingUtils
+ .wrapTooltip(true, MessageManager.getString("label.feature_settings_click_drag")));
scrollPane.setViewportView(table);
dassourceBrowser = new DasSourceBrowser(this);
{
order[i] = fr.getOrder(data[i][0].toString());
if (order[i] < 0)
+ {
order[i] = fr.setOrder(data[i][0].toString(), i / order.length);
+ }
if (i > 1)
+ {
sort = sort || order[i - 1] > order[i];
+ }
}
if (sort)
+ {
jalview.util.QuickSort.sort(order, data);
+ }
}
void load()
{ "fc" }, new String[]
{ "Sequence Feature Colours" }, "Sequence Feature Colours");
chooser.setFileView(new jalview.io.JalviewFileView());
- chooser.setDialogTitle("Load Feature Colours");
+ chooser.setDialogTitle(MessageManager.getString("label.load_feature_colours"));
chooser.setToolTipText(MessageManager.getString("action.load"));
int value = chooser.showOpenDialog(this);
file), "UTF-8");
jalview.schemabinding.version2.JalviewUserColours jucs = new jalview.schemabinding.version2.JalviewUserColours();
- jucs = (jalview.schemabinding.version2.JalviewUserColours) jucs
+ jucs = jucs
.unmarshal(in);
for (int i = jucs.getColourCount() - 1; i >= 0; i--)
{ "fc" }, new String[]
{ "Sequence Feature Colours" }, "Sequence Feature Colours");
chooser.setFileView(new jalview.io.JalviewFileView());
- chooser.setDialogTitle("Save Feature Colour Scheme");
+ chooser.setDialogTitle(MessageManager.getString("label.save_feature_colours"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
public void orderByAvWidth()
{
if (table == null || table.getModel() == null)
+ {
return;
+ }
Object[][] data = ((FeatureTableModel) table.getModel()).getData();
float[] width = new float[data.length];
float[] awidth;
width[i] = 0;
}
if (max < width[i])
+ {
max = width[i];
+ }
}
boolean sort = false;
for (int i = 0; i < width.length; i++)
fr.setOrder(data[i][0].toString(), width[i]); // store for later
}
if (i > 0)
+ {
sort = sort || width[i - 1] > width[i];
+ }
}
if (sort)
+ {
jalview.util.QuickSort.sort(width, data);
// update global priority order
+ }
updateFeatureRenderer(data, false);
table.repaint();
{
public void stateChanged(ChangeEvent evt)
{
- fr.setTransparency((float) (100 - transparency.getValue()) / 100f);
+ fr.setTransparency((100 - transparency.getValue()) / 100f);
af.alignPanel.paintAlignment(true);
}
});
}
});
this.add(tabbedPane, java.awt.BorderLayout.CENTER);
- tabbedPane.addTab("Feature Settings", settingsPane);
- tabbedPane.addTab("DAS Settings", dasSettingsPane);
+ tabbedPane.addTab(MessageManager.getString("label.feature_settings"), settingsPane);
+ tabbedPane.addTab(MessageManager.getString("label.das_settings"), dasSettingsPane);
bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH);
transbuttons.add(optimizeOrder);
transbuttons.add(invert);
}
private String[] columnNames =
- { "Feature Type", "Colour", "Display" };
+ { MessageManager.getString("label.feature_type"), MessageManager.getString("action.colour"), MessageManager.getString("label.display") };
private Object[][] data;
*/
package jalview.gui;
-import java.util.*;
-import java.awt.event.*;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.jbgui.GFinder;
+import jalview.util.MessageManager;
-import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.util.Vector;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
-import jalview.datamodel.*;
-import jalview.jbgui.*;
-import jalview.util.MessageManager;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.JOptionPane;
/**
- * DOCUMENT ME!
+ * Performs the menu option for searching the alignment, for the next or all
+ * matches. If matches are found, they are highlighted, and the user has the
+ * option to create a new feature on the alignment for the matched positions.
+ *
+ * Searches can be for a simple base sequence, or may use a regular expression.
+ * Any gaps are ignored.
*
* @author $author$
* @version $Revision$
*/
public class Finder extends GFinder
{
+ private static final int HEIGHT = 110;
+
+ private static final int WIDTH = 340;
+
AlignViewport av;
AlignmentPanel ap;
SearchResults searchResults;
/**
- * Creates a new Finder object.
- *
- * @param av
- * DOCUMENT ME!
- * @param ap
- * DOCUMENT ME!
- * @param f
- * DOCUMENT ME!
+ * Creates a new Finder object with no associated viewport or panel.
*/
public Finder()
{
focusfixed = false;
}
+ /**
+ * Constructor given an associated viewport and alignment panel. Constructs
+ * and displays an internal frame where the user can enter a search string.
+ *
+ * @param viewport
+ * @param alignPanel
+ */
public Finder(AlignViewport viewport, AlignmentPanel alignPanel)
{
av = viewport;
frame = new JInternalFrame();
frame.setContentPane(this);
frame.setLayer(JLayeredPane.PALETTE_LAYER);
- Desktop.addInternalFrame(frame, "Find", 340, 110);
+ Desktop.addInternalFrame(frame, MessageManager.getString("label.find"),
+ WIDTH, HEIGHT);
textfield.requestFocus();
}
/**
- * DOCUMENT ME!
+ * Performs the 'Find Next' action.
*
* @param e
- * DOCUMENT ME!
*/
public void findNext_actionPerformed(ActionEvent e)
{
}
/**
- * DOCUMENT ME!
+ * Performs the 'Find All' action.
*
* @param e
- * DOCUMENT ME!
*/
public void findAll_actionPerformed(ActionEvent e)
{
}
/**
- * incrementally search the alignment
+ * Search the alignment for the next or all matches. If 'all matches', a
+ * dialog is shown with the number of sequence ids and subsequences matched.
*
* @param findAll
- * true means find all results and raise a dialog box
*/
void doSearch(boolean findAll)
{
String searchString = textfield.getText().trim();
- if (searchString.length() < 1)
+ if (isInvalidSearchString(searchString))
{
return;
}
}
}
+
+ /**
+ * Displays an error dialog, and answers false, if the search string is
+ * invalid, else answers true.
+ *
+ * @param searchString
+ * @return
+ */
+ protected boolean isInvalidSearchString(String searchString)
+ {
+ String error = getSearchValidationError(searchString);
+ if (error == null)
+ {
+ return false;
+ }
+ JOptionPane.showInternalMessageDialog(this, error,
+ MessageManager.getString("label.invalid_search"), // $NON-NLS-1$
+ JOptionPane.ERROR_MESSAGE);
+ return true;
+ }
+
+ /**
+ * Returns an error message string if the search string is invalid, else
+ * returns null.
+ *
+ * Currently validation is limited to checking the string is not empty, and is
+ * a valid regular expression (simple searches for base sub-sequences will
+ * pass this test). Additional validations may be added in future if the
+ * search syntax is expanded.
+ *
+ * @param searchString
+ * @return
+ */
+ protected String getSearchValidationError(String searchString)
+ {
+ String error = null;
+ if (searchString == null || searchString.length() == 0)
+ {
+ error = MessageManager.getString("label.invalid_search");
+ }
+ try
+ {
+ Pattern.compile(searchString);
+ } catch (PatternSyntaxException e)
+ {
+ error = MessageManager.getString("error.invalid_regex") + ": "
+ + e.getDescription();
+ }
+ return error;
+ }
}
JOptionPane
.showInternalMessageDialog(
this,
- "Font doesn't have letters defined\nso cannot be used\nwith alignment data.",
- "Invalid Font", JOptionPane.WARNING_MESSAGE);
+ MessageManager.getString("label.font_doesnt_have_letters_defined"),
+ MessageManager.getString("label.invalid_font"), JOptionPane.WARNING_MESSAGE);
return;
}
if (tp != null)
--- /dev/null
+package jalview.gui;
+
+import java.net.URL;
+
+import javax.help.HelpBroker;
+import javax.help.HelpSet;
+import javax.help.HelpSetException;
+
+/**
+ * Utility class to show the help documentation window.
+ *
+ * @author gmcarstairs
+ *
+ */
+public class Help
+{
+
+ private static final long HALF_A_MO = 500; // half a second
+
+ private static long lastOpenedTime = 0L;
+
+ /**
+ * Not instantiable
+ */
+ private Help()
+ {
+
+ }
+
+ /**
+ * Show help text in a new window. But do nothing if within half a second of
+ * the last invocation.
+ *
+ * This is a workaround for issue JAL-914 - both Desktop and AlignFrame
+ * responding to F1 key, resulting in duplicate help windows opened.
+ *
+ * @throws HelpSetException
+ */
+ public static void showHelpWindow() throws HelpSetException
+ {
+ long timeNow = System.currentTimeMillis();
+
+ if (timeNow - lastOpenedTime > HALF_A_MO)
+ {
+ lastOpenedTime = timeNow;
+ ClassLoader cl = Desktop.class.getClassLoader();
+ URL url = HelpSet.findHelpSet(cl, "help/help"); // $NON-NLS-$
+ HelpSet hs = new HelpSet(cl, url);
+
+ HelpBroker hb = hs.createHelpBroker();
+ hb.setCurrentID("home");
+ hb.setDisplayed(true);
+ }
+ }
+}
*/
package jalview.gui;
-import java.awt.*;
-import java.awt.event.*;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.SequenceAnnotationReport;
+import jalview.util.MessageManager;
+import jalview.util.UrlLink;
+
+import java.awt.BorderLayout;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
import java.util.List;
import java.util.Vector;
-import javax.swing.*;
-
-import jalview.datamodel.*;
-import jalview.io.SequenceAnnotationReport;
-import jalview.util.UrlLink;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
/**
- * DOCUMENT ME!
+ * This panel hosts alignment sequence ids and responds to mouse clicks on them,
+ * as well as highlighting ids matched by a search from the Find menu.
*
* @author $author$
* @version $Revision$
* Creates a new IdPanel object.
*
* @param av
- * DOCUMENT ME!
* @param parent
- * DOCUMENT ME!
*/
public IdPanel(AlignViewport av, AlignmentPanel parent)
{
}
/**
- * DOCUMENT ME!
+ * Respond to mouse movement by constructing tooltip text for the sequence id
+ * under the mouse.
*
* @param e
* DOCUMENT ME!
if (seq > -1 && seq < av.getAlignment().getHeight())
{
SequenceI sequence = av.getAlignment().getSequenceAt(seq);
- StringBuffer tip = new StringBuffer();
+ StringBuffer tip = new StringBuffer(64);
seqAnnotReport
.createSequenceAnnotationReport(tip, sequence,
av.isShowDbRefs(), av.isShowNpFeats(),
}
/**
- * DOCUMENT ME!
+ * Responds to a mouse drag by selecting the sequences under the dragged
+ * region.
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mouseDragged(MouseEvent e)
alignPanel.paintAlignment(true);
}
+ /**
+ * Response to the mouse wheel by scrolling the alignment panel.
+ */
@Override
public void mouseWheelMoved(MouseWheelEvent e)
{
if (e.isShiftDown())
{
alignPanel.scrollRight(true);
-
}
else
{
}
/**
- * DOCUMENT ME!
+ * Handle a mouse click event. Currently only responds to a double-click. The
+ * action is to try to open a browser window at a URL that searches for the
+ * selected sequence id. The search URL is configured in Preferences |
+ * Connections | URL link from Sequence ID. For example:
+ *
+ * http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mouseClicked(MouseEvent e)
{
- if (e.getClickCount() < 2)
+ /*
+ * Ignore single click. Ignore 'left' click followed by 'right' click (user
+ * selects a row then its pop-up menu).
+ */
+ if (e.getClickCount() < 2 || SwingUtilities.isRightMouseButton(e))
{
return;
}
- java.util.Vector links = Preferences.sequenceURLLinks;
+ Vector links = Preferences.sequenceURLLinks;
if (links == null || links.size() < 1)
{
return;
JOptionPane
.showInternalMessageDialog(
Desktop.desktop,
- "Unixers: Couldn't find default web browser."
- + "\nAdd the full path to your browser in Preferences.",
- "Web browser not found", JOptionPane.WARNING_MESSAGE);
+ MessageManager.getString("label.web_browser_not_found_unix"),
+ MessageManager.getString("label.web_browser_not_found"), JOptionPane.WARNING_MESSAGE);
ex.printStackTrace();
}
-
}
/**
}
/**
- * DOCUMENT ME!
+ * Respond to a mouse press. Does nothing for (left) double-click as this is
+ * handled by mouseClicked().
+ *
+ * Right mouse down - construct and show context menu.
+ *
+ * Ctrl-down or Shift-down - add to or expand current selection group if there
+ * is one.
+ *
+ * Mouse down - select this sequence.
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mousePressed(MouseEvent e)
{
- if (e.getClickCount() == 2)
+ if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e))
{
return;
}
int seq = alignPanel.seqPanel.findSeq(e);
- if (javax.swing.SwingUtilities.isRightMouseButton(e))
+ if (SwingUtilities.isRightMouseButton(e))
{
Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq);
// build a new links menu based on the current links + any non-positional
}
/**
- * DOCUMENT ME!
+ * Toggle whether the sequence is part of the current selection group.
*
* @param seq
- * DOCUMENT ME!
*/
void selectSeq(int seq)
{
}
/**
- * DOCUMENT ME!
+ * Add contiguous rows of the alignment to the current selection group. Does
+ * nothing if there is no selection group.
*
* @param start
- * DOCUMENT ME!
* @param end
- * DOCUMENT ME!
*/
void selectSeqs(int start, int end)
{
}
/**
- * DOCUMENT ME!
+ * Respond to mouse released. Refreshes the display and triggers broadcast of
+ * the new selection group to any listeners.
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mouseReleased(MouseEvent e)
}
/**
- * DOCUMENT ME!
+ * Highlight sequence ids that match the given list, and if necessary scroll
+ * to the start sequence of the list.
*
* @param list
- * DOCUMENT ME!
*/
public void highlightSearchResults(List<SequenceI> list)
{
public JDatabaseTree(jalview.ws.SequenceFetcher sfetch)
{
- initDialogFrame(this, true, false, "Select Database Retrieval Source",
+ initDialogFrame(this, true, false, MessageManager.getString("label.select_database_retrieval_source"),
650, 490);
/*
* Dynamically generated database list will need a translation function from
}
else
{
- throw new Error(
- "Implementation Error: Can't reorder this tree. Not DefaultMutableTreeNode.");
+ throw new Error(MessageManager.getString("error.implementation_error_cant_reorder_tree"));
}
}
jalview.util.QuickSort.sort(names, nodes);
*/
package jalview.gui;
-import java.awt.Rectangle;
-import java.io.*;
-import java.lang.reflect.InvocationTargetException;
-import java.net.*;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.jar.*;
-
-import javax.swing.*;
-
-import org.exolab.castor.xml.*;
-
+import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
-import jalview.schemabinding.version2.*;
-import jalview.schemes.*;
+import jalview.schemabinding.version2.AlcodMap;
+import jalview.schemabinding.version2.Alcodon;
+import jalview.schemabinding.version2.AlcodonFrame;
+import jalview.schemabinding.version2.Annotation;
+import jalview.schemabinding.version2.AnnotationColours;
+import jalview.schemabinding.version2.AnnotationElement;
+import jalview.schemabinding.version2.CalcIdParam;
+import jalview.schemabinding.version2.DBRef;
+import jalview.schemabinding.version2.Features;
+import jalview.schemabinding.version2.Group;
+import jalview.schemabinding.version2.HiddenColumns;
+import jalview.schemabinding.version2.JGroup;
+import jalview.schemabinding.version2.JSeq;
+import jalview.schemabinding.version2.JalviewModel;
+import jalview.schemabinding.version2.JalviewModelSequence;
+import jalview.schemabinding.version2.MapListFrom;
+import jalview.schemabinding.version2.MapListTo;
+import jalview.schemabinding.version2.Mapping;
+import jalview.schemabinding.version2.MappingChoice;
+import jalview.schemabinding.version2.OtherData;
+import jalview.schemabinding.version2.PdbentryItem;
+import jalview.schemabinding.version2.Pdbids;
+import jalview.schemabinding.version2.Property;
+import jalview.schemabinding.version2.Sequence;
+import jalview.schemabinding.version2.SequenceSet;
+import jalview.schemabinding.version2.SequenceSetProperties;
+import jalview.schemabinding.version2.Setting;
+import jalview.schemabinding.version2.StructureState;
+import jalview.schemabinding.version2.ThresholdLine;
+import jalview.schemabinding.version2.Tree;
+import jalview.schemabinding.version2.UserColours;
+import jalview.schemabinding.version2.Viewport;
+import jalview.schemes.AnnotationColourGradient;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.GraduatedColor;
+import jalview.schemes.ResidueColourScheme;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.MessageManager;
import jalview.util.Platform;
import jalview.util.jarInputStreamProvider;
import jalview.viewmodel.AlignmentViewport;
import jalview.ws.params.AutoCalcSetting;
import jalview.ws.params.WsParamSetI;
+import java.awt.Rectangle;
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+
+import javax.swing.JInternalFrame;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+import org.exolab.castor.xml.Unmarshaller;
+
/**
* Write out the current jalview desktop state as a Jalview XML stream.
*
for (String dssids : dsses.keySet())
{
AlignFrame _af = dsses.get(dssids);
- String jfileName = fileName + " Dataset for " + _af.getTitle();
+ String jfileName = MessageManager.formatMessage("label.dataset_for", new String[]{fileName,_af.getTitle()});
if (!jfileName.endsWith(".xml"))
{
jfileName = jfileName + ".xml";
.startsWith(
jmol.jmb.pdbentry[peid].getId()
.toLowerCase())))
+ {
continue;
+ }
if (matchedFile == null)
{
matchedFile = jmol.jmb.pdbentry[peid].getFile();
calcIdSet.add(aa[i].getCalcId());
an.setCalcId(aa[i].getCalcId());
}
+ if (aa[i].hasProperties())
+ {
+ for (String pr : aa[i].getProperties())
+ {
+ Property prop = new Property();
+ prop.setName(pr);
+ prop.setValue(aa[i].getProperty(pr));
+ an.addProperty(prop);
+ }
+ }
AnnotationElement ae;
if (aa[i].annotations != null)
ae = new AnnotationElement();
if (aa[i].annotations[a].description != null)
+ {
ae.setDescription(aa[i].annotations[a].description);
+ }
if (aa[i].annotations[a].displayCharacter != null)
+ {
ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
+ }
if (!Float.isNaN(aa[i].annotations[a].value))
+ {
ae.setValue(aa[i].annotations[a].value);
+ }
ae.setPosition(a);
if (aa[i].annotations[a].secondaryStructure != ' '
&& aa[i].annotations[a].secondaryStructure != '\0')
+ {
ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
+ "");
+ }
if (aa[i].annotations[a].colour != null
&& aa[i].annotations[a].colour != java.awt.Color.black)
return false;
}
}
- throw new Error("Unsupported Version for calcIdparam "
- + calcIdParam.toString());
+ throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
}
/**
try
{
// create list to store references for any new Jmol viewers created
- newStructureViewers = new Vector<AppJmol>();
+ newStructureViewers = new Vector<JalviewStructureDisplayI>();
// UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
// Workaround is to make sure caller implements the JarInputStreamProvider
// interface
errorMessage = null;
}
- Hashtable alreadyLoadedPDB;
+ Hashtable<String, String> alreadyLoadedPDB;
/**
* when set, local views will be updated from view stored in JalviewXML
String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
{
if (alreadyLoadedPDB == null)
+ {
alreadyLoadedPDB = new Hashtable();
+ }
if (alreadyLoadedPDB.containsKey(pdbId))
+ {
return alreadyLoadedPDB.get(pdbId).toString();
+ }
try
{
entry.setFile(pdbloaded.get(ids[p].getId()).toString());
}
}
-
+ StructureSelectionManager.getStructureSelectionManager(
+ Desktop.instance)
+ .registerPDBEntry(entry);
al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
}
}
// in principle Visible should always be true for annotation displayed
// in multiple views
if (an[i].hasVisible())
+ {
jda.visible = an[i].getVisible();
+ }
al.addAnnotation(jda);
anpos = ae[aa].getPosition();
if (anpos >= anot.length)
+ {
continue;
+ }
anot[anpos] = new jalview.datamodel.Annotation(
jaa.setScore(an[i].getScore());
}
if (an[i].hasVisible())
+ {
jaa.visible = an[i].getVisible();
+ }
if (an[i].hasCentreColLabels())
+ {
jaa.centreColLabels = an[i].getCentreColLabels();
+ }
if (an[i].hasScaleColLabels())
{
jaa.belowAlignment = an[i].isBelowAlignment();
}
jaa.setCalcId(an[i].getCalcId());
-
+ if (an[i].getPropertyCount() > 0)
+ {
+ for (jalview.schemabinding.version2.Property prop : an[i]
+ .getProperty())
+ {
+ jaa.setProperty(prop.getName(), prop.getValue());
+ }
+ }
if (jaa.autoCalculated)
{
autoAlan.add(new JvAnnotRow(i, jaa));
@Override
public void run()
{
- AppJmol sview = null;
+ JalviewStructureDisplayI sview = null;
try
{
- sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
+ // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
+ sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
useinJmolsuperpos, usetoColourbyseq,
jmolColouring, fileloc, rect, vid);
addNewStructureViewer(sview);
return true;
}
- Vector<AppJmol> newStructureViewers = null;
+ Vector<JalviewStructureDisplayI> newStructureViewers = null;
- protected void addNewStructureViewer(AppJmol sview)
+ protected void addNewStructureViewer(JalviewStructureDisplayI sview)
{
if (newStructureViewers != null)
{
- sview.jmb.setFinishedLoadingFromArchive(false);
+ sview.getBinding().setFinishedLoadingFromArchive(false);
newStructureViewers.add(sview);
}
}
{
if (newStructureViewers != null)
{
- for (AppJmol sview : newStructureViewers)
+ for (JalviewStructureDisplayI sview : newStructureViewers)
{
- sview.jmb.setFinishedLoadingFromArchive(true);
+ sview.getBinding().setFinishedLoadingFromArchive(true);
}
newStructureViewers.clear();
newStructureViewers = null;
}
}
else
+ {
Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
+ }
}
}
{
skipList = skipList2;
}
-
}
*/
package jalview.gui;
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
+import jalview.binding.Annotation;
+import jalview.binding.AnnotationElement;
+import jalview.binding.Features;
+import jalview.binding.JGroup;
+import jalview.binding.JSeq;
+import jalview.binding.JalviewModel;
+import jalview.binding.JalviewModelSequence;
+import jalview.binding.Pdbids;
+import jalview.binding.Sequence;
+import jalview.binding.SequenceSet;
+import jalview.binding.Setting;
+import jalview.binding.Tree;
+import jalview.binding.UserColours;
+import jalview.binding.Viewport;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.MessageManager;
+import jalview.util.jarInputStreamProvider;
-import javax.swing.*;
+import java.io.InputStreamReader;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
-import org.exolab.castor.xml.*;
+import javax.swing.JOptionPane;
-import jalview.binding.*;
-import jalview.schemes.*;
import jalview.util.MessageManager;
import jalview.util.jarInputStreamProvider;
+import org.exolab.castor.xml.IDResolver;
import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
/**
InputStreamReader in = new InputStreamReader(jin, "UTF-8");
JalviewModel object = new JalviewModel();
- object = (JalviewModel) object.unmarshal(in);
+ object = object.unmarshal(in);
af = LoadFromObject(object, file);
entryCount++;
{
JOptionPane.showInternalMessageDialog(Desktop.desktop,
- "Error loading " + file, "Error loading Jalview file",
+ MessageManager.formatMessage("label.error_loading_file_params", new String[]{file}), MessageManager.getString("label.error_loading_jalview_file"),
JOptionPane.WARNING_MESSAGE);
}
});
entry.setId(ids[p].getId());
entry.setType(ids[p].getType());
al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
+ StructureSelectionManager.getStructureSelectionManager(
+ Desktop.instance).registerPDBEntry(entry);
}
}
for (int s = 0; s < ids.length; s++)
{
- seqs.addElement((jalview.datamodel.SequenceI) seqids
+ seqs.addElement(seqids
.elementAt(ids[s]));
}
--- /dev/null
+package jalview.gui;
+
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.ext.rbvi.chimera.JalviewChimeraBinding;
+import jalview.structure.StructureSelectionManager;
+
+public class JalviewChimeraBindingModel extends JalviewChimeraBinding
+{
+ private ChimeraViewFrame cvf;
+
+ public JalviewChimeraBindingModel(ChimeraViewFrame chimeraViewFrame,
+ StructureSelectionManager ssm, PDBEntry[] pdbentry,
+ SequenceI[][] sequenceIs, String[][] chains, String protocol)
+ {
+ super(ssm, pdbentry, sequenceIs, chains, protocol);
+ cvf = chimeraViewFrame;
+ }
+
+ FeatureRenderer fr = null;
+
+ @Override
+ public jalview.api.FeatureRenderer getFeatureRenderer(
+ AlignmentViewPanel alignment)
+ {
+ AlignmentPanel ap = (alignment == null) ? cvf.ap
+ : (AlignmentPanel) alignment;
+ if (ap.av.isShowSequenceFeatures())
+ {
+ if (fr == null)
+ {
+ fr = (jalview.gui.FeatureRenderer) ap.cloneFeatureRenderer();
+ }
+ else
+ {
+ ap.updateFeatureRenderer(fr);
+ }
+ }
+
+ return fr;
+ }
+
+ @Override
+ public jalview.api.SequenceRenderer getSequenceRenderer(
+ AlignmentViewPanel alignment)
+ {
+ return new SequenceRenderer(((AlignmentPanel) alignment).av);
+ }
+ @Override
+ public void refreshGUI()
+ {
+ // appJmolWindow.repaint();
+ javax.swing.SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ cvf.updateTitleAndMenus();
+ cvf.revalidate();
+ }
+ });
+ }
+
+ public void updateColours(Object source)
+ {
+ AlignmentPanel ap = (AlignmentPanel) source, topap;
+ // ignore events from panels not used to colour this view
+ if (!cvf.isUsedforcolourby(ap))
+ {
+ return;
+ }
+ if (!isLoadingFromArchive())
+ {
+ colourBySequence(ap.av.isShowSequenceFeatures(), ap);
+ }
+ }
+ @Override
+ public void releaseReferences(Object svl)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void releaseUIResources()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void refreshPdbEntries()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void showUrl(String url, String target)
+ {
+ // TODO Auto-generated method stub
+
+ }
+}
* <table width=350>
* <tr>
* <td></td> field
+ * @param enclose TODO
+ * @param ttext
*
- * @param ttext
* @return
*/
- public static String wrapTooltip(String ttext)
+ public static String wrapTooltip(boolean enclose, String ttext)
{
+
if (ttext.length() < 60)
{
- return ttext;
+ return enclose ? "<html>"+ttext+"</html>" : ttext;
}
else
{
- return "<table width=350 border=0><tr><td>" + ttext
- + "</td></tr></table>";
+ return (enclose ? "<html>" : "") + "<table width=350 border=0><tr><td>" + ttext
+ + "</td></tr></table>" + ((enclose ? "</html>" : ""));
}
}
*/
package jalview.gui;
+import jalview.util.MessageManager;
+
import java.awt.Component;
public class OOMWarning implements Runnable
javax.swing.JOptionPane
.showInternalMessageDialog(
desktop,
- "Out of memory when "
- + action
- + "!!"
- + "\nSee help files for increasing Java Virtual Machine memory.",
- "Out of memory",
+ MessageManager.formatMessage("warn.out_of_memory_when_action", new String[]{action}),
+ MessageManager.getString("label.out_of_memory"),
javax.swing.JOptionPane.WARNING_MESSAGE);
// hope that there's enough memory left that no more appear.
oomInprogress = false;
{
hasLink = true;
- enabled.setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip(((desc == null || desc.trim().length() == 0) ? "see further details by right-clicking"
+ enabled.setToolTipText(
+ JvSwingUtils
+ .wrapTooltip(true, ((desc == null || desc.trim().length() == 0) ? MessageManager.getString("label.opt_and_params_further_details ")
: desc)
+ "<br><img src=\"" + linkImageURL + "\"/>")
- + "</html>");
+ );
enabled.addMouseListener(this);
}
else
{
if (desc != null && desc.trim().length() > 0)
{
- enabled.setToolTipText("<html>"
- + JvSwingUtils.wrapTooltip(opt.getDescription())
- + "</html>");
+ enabled.setToolTipText(
+ JvSwingUtils.wrapTooltip(true, opt.getDescription())
+ );
}
}
add(enabled, BorderLayout.NORTH);
&& parm.getDescription().trim().length() > 0)
{
// Only create description boxes if there actually is a description.
- ttipText = ("<html>"
- + JvSwingUtils
- .wrapTooltip(parm.getDescription()
+ ttipText = (JvSwingUtils
+ .wrapTooltip(true, parm.getDescription()
+ (finfo != null ? "<br><img src=\""
+ linkImageURL
- + "\"/> Right click for further information."
- : "")) + "</html>");
+ + "\"/>"+MessageManager.getString("label.opt_and_params_further_detail")
+ : "")));
}
JvSwingUtils.mgAddtoLayout(this, ttipText,
// Only create description boxes if there actually is a description.
if (finfo != null)
{
- showDesc.setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip("Click to show brief description<br><img src=\""
- + linkImageURL
- + "\"/> Right click for further information.")
- + "</html>");
+ showDesc.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.opt_and_params_show_brief_desc_image_link", new String[]{linkImageURL.toExternalForm()})));
showDesc.addMouseListener(this);
}
else
{
- showDesc.setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip("Click to show brief description.")
- + "</html>");
+ showDesc.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.getString("label.opt_and_params_show_brief_desc")));
}
showDesc.addActionListener(new ActionListener()
{
}
else
{
- throw new Error("Invalid value " + string + " for option " + option);
+ throw new Error(MessageManager.formatMessage("error.invalid_value_for_option", new String[]{string,option.getName()}));
}
}
*/
package jalview.gui;
-import java.util.*;
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.print.*;
-
-import javax.swing.*;
-
-import jalview.datamodel.*;
-import jalview.jbgui.*;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SeqCigar;
+import jalview.datamodel.SequenceI;
+import jalview.jbgui.GPCAPanel;
import jalview.schemes.ResidueProperties;
import jalview.util.MessageManager;
import jalview.viewmodel.PCAModel;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.util.Hashtable;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JRadioButtonMenuItem;
+
/**
* DOCUMENT ME!
*
JOptionPane
.showMessageDialog(
Desktop.desktop,
- "The sequences must be aligned before calculating PCA.\n"
- + "Try using the Pad function in the edit menu,\n"
- + "or one of the multiple sequence alignment web services.",
- "Sequences not aligned", JOptionPane.WARNING_MESSAGE);
+ MessageManager.getString("label.pca_sequences_not_aligned"),
+ MessageManager.getString("label.sequences_not_aligned"), JOptionPane.WARNING_MESSAGE);
return;
}
@Override
public void actionPerformed(ActionEvent e)
{
- if (!pcaModel.getScore_matrix().equals((String) sm))
+ if (!pcaModel.getScore_matrix().equals(sm))
{
- pcaModel.setScore_matrix((String) sm);
+ pcaModel.setScore_matrix(sm);
Thread worker = new Thread(us);
worker.start();
}
public void bgcolour_actionPerformed(ActionEvent e)
{
- Color col = JColorChooser.showDialog(this, "Select Background Colour",
+ Color col = JColorChooser.showDialog(this, MessageManager.getString("label.select_backgroud_colour"),
rc.bgColour);
if (col != null)
{
long progId = System.currentTimeMillis();
IProgressIndicator progress = this;
- String message = "Recalculating PCA";
+ String message = MessageManager.getString("label.pca_recalculating");
if (getParent() == null)
{
progress = ap.alignFrame;
- message = "Calculating PCA";
+ message = MessageManager.getString("label.pca_calculating");
}
progress.setProgressBar(message, progId);
try
*/
public void eps_actionPerformed(ActionEvent e)
{
- makePCAImage(jalview.util.ImageMaker.EPS);
+ makePCAImage(jalview.util.ImageMaker.TYPE.EPS);
}
/**
*/
public void png_actionPerformed(ActionEvent e)
{
- makePCAImage(jalview.util.ImageMaker.PNG);
+ makePCAImage(jalview.util.ImageMaker.TYPE.PNG);
}
- void makePCAImage(int type)
+ void makePCAImage(jalview.util.ImageMaker.TYPE type)
{
int width = rc.getWidth();
int height = rc.getHeight();
jalview.util.ImageMaker im;
- if (type == jalview.util.ImageMaker.PNG)
+ if (type == jalview.util.ImageMaker.TYPE.PNG)
{
- im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.PNG,
+ im = new jalview.util.ImageMaker(this,
+ jalview.util.ImageMaker.TYPE.PNG,
"Make PNG image from PCA", width, height, null, null);
}
- else
+ else if (type == jalview.util.ImageMaker.TYPE.EPS)
{
- im = new jalview.util.ImageMaker(this, jalview.util.ImageMaker.EPS,
+ im = new jalview.util.ImageMaker(this,
+ jalview.util.ImageMaker.TYPE.EPS,
"Make EPS file from PCA", width, height, null,
this.getTitle());
}
+ else
+ {
+ im = new jalview.util.ImageMaker(this,
+ jalview.util.ImageMaker.TYPE.SVG, "Make SVG file from PCA",
+ width, height, null, this.getTitle());
+
+ }
if (im.getGraphics() != null)
{
{
if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
{
- throw new Error(
- "call setProgressBar before registering the progress bar's handler.");
+ throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
}
progressBarHandlers.put(new Long(id), handler);
final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
public void actionPerformed(ActionEvent e)
{
handler.cancelActivity(id);
- us.setProgressBar(
- "Cancelled "
- + ((JLabel) progressPanel.getComponent(0))
- .getText(), id);
+ us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
}
});
progressPanel.add(cancel, BorderLayout.EAST);
*/
package jalview.gui;
-import java.util.*;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import jalview.analysis.*;
-import jalview.commands.*;
-import jalview.datamodel.*;
-import jalview.io.*;
-import jalview.schemes.*;
+import jalview.analysis.AAFrequency;
+import jalview.analysis.AlignmentAnnotationUtils;
+import jalview.analysis.Conservation;
+import jalview.commands.ChangeCaseCommand;
+import jalview.commands.EditCommand;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.FormatAdapter;
+import jalview.io.SequenceAnnotationReport;
+import jalview.schemes.AnnotationColourGradient;
+import jalview.schemes.Blosum62ColourScheme;
+import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.ClustalxColourScheme;
+import jalview.schemes.HelixColourScheme;
+import jalview.schemes.HydrophobicColourScheme;
+import jalview.schemes.NucleotideColourScheme;
+import jalview.schemes.PIDColourScheme;
+import jalview.schemes.PurinePyrimidineColourScheme;
+import jalview.schemes.ResidueProperties;
+import jalview.schemes.StrandColourScheme;
+import jalview.schemes.TaylorColourScheme;
+import jalview.schemes.TurnColourScheme;
+import jalview.schemes.UserColourScheme;
+import jalview.schemes.ZappoColourScheme;
import jalview.util.GroupUrlLink;
import jalview.util.GroupUrlLink.UrlStringTooLongException;
import jalview.util.MessageManager;
import jalview.util.UrlLink;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.Vector;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
+
/**
* DOCUMENT ME!
*
*/
public class PopupMenu extends JPopupMenu
{
+ private static final String ALL_ANNOTATIONS = "All";
+
+ private static final String COMMA = ",";
+
JMenu groupMenu = new JMenu();
JMenuItem groupName = new JMenuItem();
JMenuItem sequenceSelDetails = new JMenuItem();
+ JMenuItem chooseAnnotations = new JMenuItem();
+
SequenceI sequence;
JMenuItem createGroupMenuItem = new JMenuItem();
JMenu outputMenu = new JMenu();
+ JMenu seqShowAnnotationsMenu = new JMenu();
+
+ JMenu seqHideAnnotationsMenu = new JMenu();
+
+ JMenuItem seqAddReferenceAnnotations = new JMenuItem();
+
+ JMenu groupShowAnnotationsMenu = new JMenu();
+
+ JMenu groupHideAnnotationsMenu = new JMenu();
+
+ JMenuItem groupAddReferenceAnnotations = new JMenuItem();
+
JMenuItem sequenceFeature = new JMenuItem();
JMenuItem textColour = new JMenuItem();
item.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
outputText_actionPerformed(e);
outputMenu.add(item);
}
+ /*
+ * Build menus for annotation types that may be shown or hidden, and for
+ * 'reference annotations' that may be added to the alignment. First for the
+ * currently selected sequence (if there is one):
+ */
+ final List<SequenceI> selectedSequence = (seq == null ? Collections
+ .<SequenceI> emptyList() : Arrays.asList(seq));
+ buildAnnotationTypesMenus(seqShowAnnotationsMenu,
+ seqHideAnnotationsMenu, selectedSequence);
+ configureReferenceAnnotationsMenu(seqAddReferenceAnnotations,
+ selectedSequence);
+
+ /*
+ * And repeat for the current selection group (if there is one):
+ */
+ final List<SequenceI> selectedGroup = (ap.av.getSelectionGroup() == null ? Collections
+ .<SequenceI> emptyList() : ap.av.getSelectionGroup()
+ .getSequences());
+ buildAnnotationTypesMenus(groupShowAnnotationsMenu,
+ groupHideAnnotationsMenu, selectedGroup);
+ configureReferenceAnnotationsMenu(groupAddReferenceAnnotations,
+ selectedGroup);
+
try
{
jbInit();
menuItem = new JMenuItem();
menuItem.setText(pdb.getId());
- menuItem.addActionListener(new java.awt.event.ActionListener()
+ menuItem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
// TODO re JAL-860: optionally open dialog or provide a menu entry
// allowing user to open just one structure per sequence
- new AppJmol(pdb, ap.av.collateForPDB(new PDBEntry[]
- { pdb })[0], null, ap);
- // new PDBViewer(pdb, seqs2, null, ap, AppletFormatAdapter.FILE);
+ // new AppJmol(pdb, ap.av.collateForPDB(new PDBEntry[]
+ // { pdb })[0], null, ap);
+ new StructureViewer(ap.getStructureSelectionManager())
+ .viewStructures(pdb,
+ ap.av.collateForPDB(new PDBEntry[]
+ { pdb })[0], null, ap);
}
-
});
viewStructureMenu.add(menuItem);
"label.2d_rna_structure_line", new String[]
{ structureLine }));
menuItem.addActionListener(new java.awt.event.ActionListener()
-
{
+ @Override
public void actionPerformed(ActionEvent e)
{
// System.out.println("1:"+structureLine);
{ seq.getName() }));
menuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
// TODO: VARNA does'nt print gaps in the sequence
MessageManager.getString("action.hide_sequences"));
menuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
hideSequences(false);
{ seq.getName() }));
menuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
hideSequences(true);
MessageManager.getString("action.reveal_sequences"));
menuItem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
ap.av.showSequence(index);
MessageManager.getString("action.reveal_all"));
menuItem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
ap.av.showAllHiddenSeqs();
SequenceI sqass = null;
for (SequenceI sq : ap.av.getSequenceSelection())
{
- Vector<PDBEntry> pes = (Vector<PDBEntry>) sq.getDatasetSequence()
- .getPDBId();
- if (pes != null && pes.size()>0)
+ Vector<PDBEntry> pes = sq.getDatasetSequence().getPDBId();
+ if (pes != null && pes.size() > 0)
{
reppdb.put(pes.get(0).getId(), pes.get(0));
for (PDBEntry pe : pes)
@Override
public void actionPerformed(ActionEvent e)
{
- new AppJmol(ap, pe, ap.av.collateForPDB(pe));
+ new StructureViewer(ap.getStructureSelectionManager())
+ .viewStructures(ap, pe, ap.av.collateForPDB(pe));
}
});
if (reppdb.size() > 1 && reppdb.size() < pdbe.size())
@Override
public void actionPerformed(ActionEvent e)
{
- new AppJmol(ap, pr, ap.av.collateForPDB(pr));
+ new StructureViewer(ap.getStructureSelectionManager())
+ .viewStructures(ap, pr, ap.av.collateForPDB(pr));
}
});
}
}
}
+ /**
+ * Add annotation types to 'Show annotations' and/or 'Hide annotations' menus.
+ * "All" is added first, followed by a separator. Then add any annotation
+ * types associated with the current selection. Separate menus are built for
+ * the selected sequence group (if any), and the selected sequence.
+ * <p>
+ * Some annotation rows are always rendered together - these can be identified
+ * by a common graphGroup property > -1. Only one of each group will be marked
+ * as visible (to avoid duplication of the display). For such groups we add a
+ * composite type name, e.g.
+ * <p>
+ * IUPredWS (Long), IUPredWS (Short)
+ *
+ * @param seq
+ */
+ protected void buildAnnotationTypesMenus(JMenu showMenu, JMenu hideMenu,
+ List<SequenceI> forSequences)
+ {
+ showMenu.removeAll();
+ hideMenu.removeAll();
+
+ final List<String> all = Arrays.asList(ALL_ANNOTATIONS);
+ addAnnotationTypeToShowHide(showMenu, forSequences, "", all, true, true);
+ addAnnotationTypeToShowHide(hideMenu, forSequences, "", all, true,
+ false);
+ showMenu.addSeparator();
+ hideMenu.addSeparator();
+
+ final AlignmentAnnotation[] annotations = ap.getAlignment()
+ .getAlignmentAnnotation();
+
+ /*
+ * Find shown/hidden annotations types, distinguished by source (calcId),
+ * and grouped by graphGroup. Using LinkedHashMap means we will retrieve in
+ * the insertion order, which is the order of the annotations on the
+ * alignment.
+ */
+ Map<String, List<List<String>>> shownTypes = new LinkedHashMap<String, List<List<String>>>();
+ Map<String, List<List<String>>> hiddenTypes = new LinkedHashMap<String, List<List<String>>>();
+ AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes,
+ hiddenTypes,
+ AlignmentAnnotationUtils.asList(annotations),
+ forSequences);
+
+ for (String calcId : hiddenTypes.keySet())
+ {
+ for (List<String> type : hiddenTypes.get(calcId))
+ {
+ addAnnotationTypeToShowHide(showMenu, forSequences,
+ calcId, type, false, true);
+ }
+ }
+ // grey out 'show annotations' if none are hidden
+ showMenu.setEnabled(!hiddenTypes.isEmpty());
+
+ for (String calcId : shownTypes.keySet())
+ {
+ for (List<String> type : shownTypes.get(calcId))
+ {
+ addAnnotationTypeToShowHide(hideMenu, forSequences,
+ calcId, type, false, false);
+ }
+ }
+ // grey out 'hide annotations' if none are shown
+ hideMenu.setEnabled(!shownTypes.isEmpty());
+ }
+
+ /**
+ * Returns a list of sequences - either the current selection group (if there
+ * is one), else the specified single sequence.
+ *
+ * @param seq
+ * @return
+ */
+ protected List<SequenceI> getSequenceScope(SequenceI seq)
+ {
+ List<SequenceI> forSequences = null;
+ final SequenceGroup selectionGroup = ap.av.getSelectionGroup();
+ if (selectionGroup != null && selectionGroup.getSize() > 0)
+ {
+ forSequences = selectionGroup.getSequences();
+ }
+ else
+ {
+ forSequences = seq == null ? Collections.<SequenceI> emptyList()
+ : Arrays.asList(seq);
+ }
+ return forSequences;
+ }
+
+ /**
+ * Add one annotation type to the 'Show Annotations' or 'Hide Annotations'
+ * menus.
+ *
+ * @param showOrHideMenu
+ * the menu to add to
+ * @param forSequences
+ * the sequences whose annotations may be shown or hidden
+ * @param calcId
+ * @param types
+ * the label to add
+ * @param allTypes
+ * if true this is a special label meaning 'All'
+ * @param actionIsShow
+ * if true, the select menu item action is to show the annotation
+ * type, else hide
+ */
+ protected void addAnnotationTypeToShowHide(JMenu showOrHideMenu,
+ final List<SequenceI> forSequences, String calcId,
+ final List<String> types, final boolean allTypes,
+ final boolean actionIsShow)
+ {
+ String label = types.toString(); // [a, b, c]
+ label = label.substring(1, label.length() - 1);
+ final JMenuItem item = new JMenuItem(label);
+ item.setToolTipText(calcId);
+ item.addActionListener(new java.awt.event.ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ showHideAnnotation_actionPerformed(types, forSequences, allTypes,
+ actionIsShow);
+ }
+ });
+ showOrHideMenu.add(item);
+ }
+
+ /**
+ * Action on selecting a list of annotation type (or the 'all types' values)
+ * to show or hide for the specified sequences.
+ *
+ * @param types
+ * @param forSequences
+ * @param anyType
+ * @param doShow
+ */
+ protected void showHideAnnotation_actionPerformed(
+ Collection<String> types, List<SequenceI> forSequences,
+ boolean anyType, boolean doShow)
+ {
+ for (AlignmentAnnotation aa : ap.getAlignment()
+ .getAlignmentAnnotation())
+ {
+ if (anyType || types.contains(aa.label))
+ {
+ if ((aa.sequenceRef != null)
+ && forSequences.contains(aa.sequenceRef))
+ {
+ aa.visible = doShow;
+ }
+ }
+ }
+ refresh();
+ }
+
private void buildGroupURLMenu(SequenceGroup sg, Vector groupLinks)
{
{ url }));
item.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
new Thread(new Runnable()
{
+ @Override
public void run()
{
showLink(url);
// TODO: put in info about what is being sent.
item.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
new Thread(new Runnable()
{
+ @Override
public void run()
{
try
groupName.setText(MessageManager.getString("label.name"));
groupName.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
groupName_actionPerformed();
.getString("label.edit_name_description"));
sequenceName.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
sequenceName_actionPerformed();
}
});
+ chooseAnnotations.setText(MessageManager
+ .getString("label.choose_annotations") + "...");
+ chooseAnnotations.addActionListener(new java.awt.event.ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ chooseAnnotations_actionPerformed(e);
+ }
+ });
sequenceDetails.setText(MessageManager
.getString("label.sequence_details") + "...");
sequenceDetails.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
sequenceDetails_actionPerformed();
sequenceSelDetails
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
sequenceSelectionDetails_actionPerformed();
.setText(MessageManager.getString("action.remove_group"));
unGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
unGroupMenuItem_actionPerformed();
createGroupMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
createGroupMenuItem_actionPerformed();
outline.setText(MessageManager.getString("action.border_colour"));
outline.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
outline_actionPerformed();
.setText(MessageManager.getString("label.nucleotide"));
nucleotideMenuItem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
nucleotideMenuItem_actionPerformed();
showBoxes.setState(true);
showBoxes.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showBoxes_actionPerformed();
showText.setState(true);
showText.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showText_actionPerformed();
showColourText.setText(MessageManager.getString("label.colour_text"));
showColourText.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showColourText_actionPerformed();
displayNonconserved.setState(true);
displayNonconserved.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showNonconserved_actionPerformed();
cut.setText(MessageManager.getString("action.cut"));
cut.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
cut_actionPerformed();
upperCase.setText(MessageManager.getString("label.to_upper_case"));
upperCase.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
changeCase(e);
copy.setText(MessageManager.getString("action.copy"));
copy.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
copy_actionPerformed();
lowerCase.setText(MessageManager.getString("label.to_lower_case"));
lowerCase.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
changeCase(e);
toggle.setText(MessageManager.getString("label.toggle_case"));
toggle.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
changeCase(e);
pdbFromFile.setText(MessageManager.getString("label.from_file"));
pdbFromFile.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
pdbFromFile_actionPerformed();
enterPDB.setText(MessageManager.getString("label.enter_pdb_id"));
enterPDB.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
enterPDB_actionPerformed();
discoverPDB.setText(MessageManager.getString("label.discover_pdb_ids"));
discoverPDB.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
discoverPDB_actionPerformed();
});
outputMenu.setText(MessageManager.getString("label.out_to_textbox")
+ "...");
+ seqShowAnnotationsMenu.setText(MessageManager
+ .getString("label.show_annotations"));
+ seqHideAnnotationsMenu.setText(MessageManager
+ .getString("label.hide_annotations"));
+ groupShowAnnotationsMenu.setText(MessageManager
+ .getString("label.show_annotations"));
+ groupHideAnnotationsMenu.setText(MessageManager
+ .getString("label.hide_annotations"));
sequenceFeature.setText(MessageManager
.getString("label.create_sequence_feature"));
sequenceFeature.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
sequenceFeature_actionPerformed();
textColour.setText(MessageManager.getString("label.text_colour"));
textColour.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
textColour_actionPerformed();
+ "...");
editSequence.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent actionEvent)
{
editSequence_actionPerformed(actionEvent);
add(groupMenu);
add(sequenceMenu);
this.add(structureMenu);
+ // annotations configuration panel suppressed for now
+ // groupMenu.add(chooseAnnotations);
+
+ /*
+ * Add show/hide annotations to the Sequence menu, and to the Selection menu
+ * (if a selection group is in force).
+ */
+ sequenceMenu.add(seqShowAnnotationsMenu);
+ sequenceMenu.add(seqHideAnnotationsMenu);
+ sequenceMenu.add(seqAddReferenceAnnotations);
+ groupMenu.add(groupShowAnnotationsMenu);
+ groupMenu.add(groupHideAnnotationsMenu);
+ groupMenu.add(groupAddReferenceAnnotations);
groupMenu.add(editMenu);
groupMenu.add(outputMenu);
groupMenu.add(sequenceFeature);
JMenuItem item = new JMenuItem(userColours.nextElement().toString());
item.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent evt)
{
userDefinedColour_actionPerformed(evt);
noColourmenuItem.setText(MessageManager.getString("label.none"));
noColourmenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
noColourmenuItem_actionPerformed();
.getString("label.clustalx_colours"));
clustalColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
clustalColour_actionPerformed();
zappoColour.setText(MessageManager.getString("label.zappo"));
zappoColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
zappoColour_actionPerformed();
taylorColour.setText(MessageManager.getString("label.taylor"));
taylorColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
taylorColour_actionPerformed();
hydrophobicityColour
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
hydrophobicityColour_actionPerformed();
helixColour.setText(MessageManager.getString("label.helix_propensity"));
helixColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
helixColour_actionPerformed();
.getString("label.strand_propensity"));
strandColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
strandColour_actionPerformed();
turnColour.setText(MessageManager.getString("label.turn_propensity"));
turnColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
turnColour_actionPerformed();
buriedColour.setText(MessageManager.getString("label.buried_index"));
buriedColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
buriedColour_actionPerformed();
.getString("label.above_identity_percentage"));
abovePIDColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
abovePIDColour_actionPerformed();
.getString("action.user_defined"));
userDefinedColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
userDefinedColour_actionPerformed(e);
.setText(MessageManager.getString("label.percentage_identity"));
PIDColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
PIDColour_actionPerformed();
BLOSUM62Colour.setText(MessageManager.getString("label.blosum62"));
BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
BLOSUM62Colour_actionPerformed();
purinePyrimidineColour
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
purinePyrimidineColour_actionPerformed();
conservationMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
conservationMenuItem_actionPerformed();
});
}
+ /**
+ * Check for any annotations on the underlying dataset sequences (for the
+ * current selection group) which are not on the alignment annotations for the
+ * sequence. If any are found, enable the option to add them to the alignment.
+ * The criteria for 'on the alignment' is finding an alignment annotation on
+ * the sequence, that matches on calcId and label. A tooltip is also
+ * constructed that displays the source (calcId) and type (label) of the
+ * annotations that can be added.
+ *
+ * @param menuItem
+ * @param forSequences
+ */
+ protected void configureReferenceAnnotationsMenu(
+ JMenuItem menuItem, List<SequenceI> forSequences)
+ {
+ menuItem.setText(MessageManager
+ .getString("label.add_reference_annotations"));
+ menuItem.setEnabled(false);
+ if (forSequences == null)
+ {
+ return;
+ }
+
+ /*
+ * Temporary store to hold distinct calcId / type pairs for the tooltip.
+ * Using TreeMap means calcIds are shown in alphabetical order.
+ */
+ Map<String, String> tipEntries = new TreeMap<String, String>();
+ StringBuilder tooltip = new StringBuilder(64);
+ tooltip.append(MessageManager.getString("label.add_annotations_for"));
+
+ /*
+ * For each sequence selected in the alignment, make a list of any
+ * annotations on the underlying dataset sequence which are not already on
+ * the sequence in the alignment.
+ *
+ * Build a map of { alignmentSequence, <List of annotations to add> }
+ */
+ final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<SequenceI, List<AlignmentAnnotation>>();
+ for (SequenceI seq : forSequences)
+ {
+ SequenceI dataset = seq.getDatasetSequence();
+ if (dataset == null)
+ {
+ continue;
+ }
+ AlignmentAnnotation[] datasetAnnotations = dataset.getAnnotation();
+ if (datasetAnnotations == null)
+ {
+ continue;
+ }
+ final List<AlignmentAnnotation> result = new ArrayList<AlignmentAnnotation>();
+ for (AlignmentAnnotation dsann : datasetAnnotations)
+ {
+ /*
+ * If the sequence has no annotation that matches this one, then add
+ * this one to the results list.
+ */
+ if (seq.getAlignmentAnnotations(dsann.getCalcId(), dsann.label)
+ .isEmpty())
+ {
+ result.add(dsann);
+ tipEntries.put(dsann.getCalcId(), dsann.label);
+ }
+ }
+ /*
+ * Save any addable annotations for this sequence
+ */
+ if (!result.isEmpty())
+ {
+ candidates.put(seq, result);
+ }
+ }
+ if (!candidates.isEmpty())
+ {
+ /*
+ * Found annotations that could be added. Enable the menu item, and
+ * configure its tooltip and action.
+ */
+ menuItem.setEnabled(true);
+ for (String calcId : tipEntries.keySet())
+ {
+ tooltip.append("<br/>" + calcId + "/" + tipEntries.get(calcId));
+ }
+ String tooltipText = JvSwingUtils.wrapTooltip(true,
+ tooltip.toString());
+ menuItem.setToolTipText(tooltipText);
+
+ menuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ addReferenceAnnotations_actionPerformed(candidates);
+ }
+ });
+ }
+ }
+
+ /**
+ * Add annotations to the sequences and to the alignment.
+ *
+ * @param candidates
+ * a map whose keys are sequences on the alignment, and values a list
+ * of annotations to add to each sequence
+ */
+ protected void addReferenceAnnotations_actionPerformed(
+ Map<SequenceI, List<AlignmentAnnotation>> candidates)
+ {
+ /*
+ * Add annotations at the top of the annotation, in the same order as their
+ * related sequences.
+ */
+ for (SequenceI seq : candidates.keySet())
+ {
+ for (AlignmentAnnotation ann : candidates.get(seq))
+ {
+ AlignmentAnnotation copyAnn = new AlignmentAnnotation(ann);
+ int startRes = 0;
+ int endRes = ann.annotations.length;
+ final SequenceGroup selectionGroup = this.ap.av.getSelectionGroup();
+ if (selectionGroup != null)
+ {
+ startRes = selectionGroup.getStartRes();
+ endRes = selectionGroup.getEndRes();
+ }
+ copyAnn.restrict(startRes, endRes);
+
+ // add to the sequence (sets copyAnn.datasetSequence)
+ seq.addAlignmentAnnotation(copyAnn);
+ // adjust for gaps
+ copyAnn.adjustForAlignment();
+ // add to the alignment and set visible
+ this.ap.getAlignment().addAnnotation(copyAnn);
+ copyAnn.visible = true;
+ }
+ }
+ refresh();
+ }
+
protected void sequenceSelectionDetails_actionPerformed()
{
createSequenceDetailsReport(ap.av.getSequenceSelection());
}
/**
+ * Open a panel where the user can choose which types of sequence annotation
+ * to show or hide.
+ *
+ * @param e
+ */
+ protected void chooseAnnotations_actionPerformed(ActionEvent e)
+ {
+ // todo correct way to guard against opening a duplicate panel?
+ new AnnotationChooser(ap);
+ }
+
+ /**
* DOCUMENT ME!
*
* @param e
System.out.println("PROMPT USER HERE"); // TODO: decide if a prompt happens
// or we simply trust the user wants
// wysiwig behaviour
- SequenceGroup sg = ap.av.getSelectionGroup();
- ColumnSelection csel = new ColumnSelection(ap.av.getColumnSelection());
- omitHidden = ap.av.getViewAsString(true);
- Alignment oal = new Alignment(ap.av.getSequenceSelection());
- AlignmentAnnotation[] nala = ap.av.getAlignment()
- .getAlignmentAnnotation();
- if (nala != null)
- {
- for (int i = 0; i < nala.length; i++)
- {
- AlignmentAnnotation na = nala[i];
- oal.addAnnotation(na);
- }
- }
+
cap.setText(new FormatAdapter().formatSequences(e.getActionCommand(),
- oal, omitHidden, csel, sg));
- oal = null;
+ ap.av, true));
}
public void pdbFromFile_actionPerformed()
{ sequence.getDisplayId(false) }));
chooser.setToolTipText(MessageManager.formatMessage(
"label.load_pdb_file_associate_with_sequence", new String[]
- { new Integer(sequence.getDisplayId(false)).toString() }));
+ { sequence.getDisplayId(false) }));
int value = chooser.showOpenDialog(null);
String choice = chooser.getSelectedFile().getPath();
jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
new AssociatePdbFileWithSeq().associatePdbWithSeq(choice,
- jalview.io.AppletFormatAdapter.FILE, sequence, true);
+ jalview.io.AppletFormatAdapter.FILE, sequence, true,
+ Desktop.instance);
}
}
: ap.av.getSequenceSelection());
Thread discpdb = new Thread(new Runnable()
{
+ @Override
public void run()
{
if (sg != null)
{
if (sequence == null)
- sequence = (Sequence) sg.getSequenceAt(0);
+ {
+ sequence = sg.getSequenceAt(0);
+ }
EditNameDialog dialog = new EditNameDialog(
sequence.getSequenceAsString(sg.getStartRes(),
*/
package jalview.gui;
-import java.util.*;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import jalview.bin.*;
-import jalview.io.*;
-import jalview.jbgui.*;
-import jalview.schemes.*;
+import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
+import jalview.bin.Cache;
+import jalview.gui.StructureViewer.Viewer;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.jbgui.GPreferences;
+import jalview.jbgui.GSequenceLink;
+import jalview.schemes.ColourSchemeProperty;
import jalview.util.MessageManager;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.util.Collection;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.swing.JColorChooser;
+import javax.swing.JFileChooser;
+import javax.swing.JInternalFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+
/**
* DOCUMENT ME!
*
public class Preferences extends GPreferences
{
+ public static final String ADD_TEMPFACT_ANN = "ADD_TEMPFACT_ANN";
+
+ public static final String ADD_SS_ANN = "ADD_SS_ANN";
+
+ public static final String USE_RNAVIEW = "USE_RNAVIEW";
+
+ public static final String STRUCT_FROM_PDB = "STRUCT_FROM_PDB";
+
+ public static final String STRUCTURE_DISPLAY = "STRUCTURE_DISPLAY";
+
+ public static final String CHIMERA_PATH = "CHIMERA_PATH";
+
+ public static final String SORT_ANNOTATIONS = "SORT_ANNOTATIONS";
+
+ public static final String SHOW_AUTOCALC_ABOVE = "SHOW_AUTOCALC_ABOVE";
+
+ private static final int MIN_FONT_SIZE = 1;
+
+ private static final int MAX_FONT_SIZE = 30;
+
/**
* Holds name and link separated with | character. Sequence ID must be
* $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
*/
public Preferences()
{
-
+ super();
frame = new JInternalFrame();
frame.setContentPane(this);
dasSource = new DasSourceBrowser();
- dasPanel.add(dasSource, BorderLayout.CENTER);
+ dasTab.add(dasSource, BorderLayout.CENTER);
wsPrefs = new WsPreferences();
- wsPanel.add(wsPrefs, BorderLayout.CENTER);
+ wsTab.add(wsPrefs, BorderLayout.CENTER);
int width = 500, height = 420;
if (new jalview.util.Platform().isAMac())
{
MessageManager.getString("label.preferences"), width, height);
frame.setMinimumSize(new Dimension(width, height));
+ /*
+ * Set Visual tab defaults
+ */
seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true));
rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false));
fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false));
openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false));
showUnconserved
.setSelected(Cache.getDefault("SHOW_UNCONSERVED", false));
+ showGroupConsensus.setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS",
+ false));
+ showGroupConservation.setSelected(Cache.getDefault(
+ "SHOW_GROUP_CONSERVATION", false));
+ showConsensHistogram.setSelected(Cache.getDefault(
+ "SHOW_CONSENSUS_HISTOGRAM", true));
+ showConsensLogo.setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO",
+ false));
showNpTooltip.setSelected(Cache
.getDefault("SHOW_NPFEATS_TOOLTIP", true));
showDbRefTooltip.setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP",
true));
- sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
- for (int i = ColourSchemeProperty.FIRST_COLOUR; i <= ColourSchemeProperty.LAST_COLOUR; i++)
- {
- colour.addItem(ColourSchemeProperty.getColourName(i));
- }
-
- String string = Cache.getDefault("DEFAULT_COLOUR", "None");
-
- colour.setSelectedItem(string);
-
- /**
- * default min-max colours for annotation shading
- */
- minColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN",
- Color.orange));
- maxColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX",
- Color.red));
String[] fonts = java.awt.GraphicsEnvironment
.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
-
for (int i = 0; i < fonts.length; i++)
{
fontNameCB.addItem(fonts[i]);
}
- for (int i = 1; i < 31; i++)
+ for (int i = MIN_FONT_SIZE; i <= MAX_FONT_SIZE; i++)
{
fontSizeCB.addItem(i + "");
}
gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-"));
- startupCheckbox
- .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
- startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
- Cache.getDefault("www.jalview.org", "http://www.jalview.org")
- + "/examples/exampleFile_2_3.jar"));
-
sortby.addItem("No sort");
sortby.addItem("Id");
sortby.addItem("Pairwise Identity");
sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort"));
- epsRendering.addItem("Prompt each time");
- epsRendering.addItem("Lineart");
- epsRendering.addItem("Text");
- epsRendering.setSelectedItem(Cache.getDefault("EPS_RENDERING",
- "Prompt each time"));
- autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
- userIdWidth.setEnabled(autoIdWidth.isSelected());
- userIdWidthlabel.setEnabled(autoIdWidth.isSelected());
- Integer wi = Cache.getIntegerProperty("FIGURE_USERIDWIDTH");
- userIdWidth.setText(wi == null ? "" : wi.toString());
- blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
- clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
- fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
- msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
- pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
- pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
- pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
-
- modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
+ sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString());
+ sortAnnBy
+ .addItem(SequenceAnnotationOrder.SEQUENCE_AND_LABEL.toString());
+ sortAnnBy
+ .addItem(SequenceAnnotationOrder.LABEL_AND_SEQUENCE.toString());
+ SequenceAnnotationOrder savedSort = SequenceAnnotationOrder
+ .valueOf(Cache.getDefault(SORT_ANNOTATIONS,
+ SequenceAnnotationOrder.NONE.name()));
+ sortAnnBy.setSelectedItem(savedSort.toString());
+
+ sortAutocalc.addItem("Autocalculated first");
+ sortAutocalc.addItem("Autocalculated last");
+ final boolean showAbove = Cache.getDefault(SHOW_AUTOCALC_ABOVE,
+ true);
+ sortAutocalc.setSelectedItem(showAbove ? sortAutocalc.getItemAt(0)
+ : sortAutocalc.getItemAt(1));
+ startupCheckbox
+ .setSelected(Cache.getDefault("SHOW_STARTUP_FILE", true));
+ startupFileTextfield.setText(Cache.getDefault("STARTUP_FILE",
+ Cache.getDefault("www.jalview.org", "http://www.jalview.org")
+ + "/examples/exampleFile_2_3.jar"));
- autoCalculateConsCheck.setSelected(Cache.getDefault(
- "AUTO_CALC_CONSENSUS", true));
- showGroupConsensus.setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS",
- false));
- showGroupConservation.setSelected(Cache.getDefault(
- "SHOW_GROUP_CONSERVATION", false));
- showConsensHistogram.setSelected(Cache.getDefault(
- "SHOW_CONSENSUS_HISTOGRAM", true));
- showConsensLogo.setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO",
- false));
+ /*
+ * Set Colours tab defaults
+ */
+ for (int i = ColourSchemeProperty.FIRST_COLOUR; i <= ColourSchemeProperty.LAST_COLOUR; i++)
+ {
+ colour.addItem(ColourSchemeProperty.getColourName(i));
+ }
+ String string = Cache.getDefault("DEFAULT_COLOUR", "None");
+ colour.setSelectedItem(string);
+ minColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN",
+ Color.orange));
+ maxColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX",
+ Color.red));
- padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
+ /*
+ * Set Structure tab defaults.
+ */
+ final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, false);
+ structFromPdb.setSelected(structSelected);
+ useRnaView.setSelected(Cache.getDefault(USE_RNAVIEW, false));
+ useRnaView.setEnabled(structSelected);
+ addSecondaryStructure
+ .setSelected(Cache.getDefault(ADD_SS_ANN, false));
+ addSecondaryStructure.setEnabled(structSelected);
+ addTempFactor.setSelected(Cache.getDefault(ADD_TEMPFACT_ANN, false));
+ addTempFactor.setEnabled(structSelected);
+ structViewer.setSelectedItem(Cache.getDefault(STRUCTURE_DISPLAY,
+ Viewer.JMOL.name()));
+ chimeraPath.setText(Cache.getDefault(CHIMERA_PATH, ""));
+ chimeraPath.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (chimeraPath.getText().trim().length() > 0)
+ {
+ File f = new File(chimeraPath.getText());
+ if (!f.canExecute())
+ {
+ JOptionPane.showInternalMessageDialog(Desktop.desktop,
+ MessageManager.getString("label.invalid_path"),
+ MessageManager.getString("label.invalid_name"),
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+ });
- /***************************************************************************
- * Set up Connections
+ /*
+ * Set Connections tab defaults
*/
nameLinks = new Vector();
urlLinks = new Vector();
defaultBrowser.setText(Cache.getDefault("DEFAULT_BROWSER", ""));
usagestats.setSelected(Cache.getDefault("USAGESTATS", false));
+ // note antisense here: default is true
questionnaire
- .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null); // note
- // antisense
- // here
- versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true)); // default
- // is
- // true
+ .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null);
+ versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true));
+
+ /*
+ * Set Output tab defaults
+ */
+ epsRendering
+ .addItem(MessageManager.getString("label.prompt_each_time"));
+ epsRendering.addItem(MessageManager.getString("label.lineart"));
+ epsRendering.addItem(MessageManager.getString("action.text"));
+ epsRendering.setSelectedItem(Cache.getDefault("EPS_RENDERING",
+ "Prompt each time"));
+ autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
+ userIdWidth.setEnabled(autoIdWidth.isSelected());
+ userIdWidthlabel.setEnabled(autoIdWidth.isSelected());
+ Integer wi = Cache.getIntegerProperty("FIGURE_USERIDWIDTH");
+ userIdWidth.setText(wi == null ? "" : wi.toString());
+ blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
+ clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
+ fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
+ msfjv.setSelected(Cache.getDefault("MSF_JVSUFFIX", true));
+ pfamjv.setSelected(Cache.getDefault("PFAM_JVSUFFIX", true));
+ pileupjv.setSelected(Cache.getDefault("PILEUP_JVSUFFIX", true));
+ pirjv.setSelected(Cache.getDefault("PIR_JVSUFFIX", true));
+ modellerOutput.setSelected(Cache.getDefault("PIR_MODELLER", false));
+
+ /*
+ * Set Editing tab defaults
+ */
+ autoCalculateConsCheck.setSelected(Cache.getDefault(
+ "AUTO_CALC_CONSENSUS", true));
+ padGaps.setSelected(Cache.getDefault("PAD_GAPS", false));
+ sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false));
+
annotations_actionPerformed(null); // update the display of the annotation
// settings
- try
- {
- jbInit();
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
-
}
/**
- * DOCUMENT ME!
+ * Save user selections on the Preferences tabs to the Cache and write out to
+ * file.
*
* @param e
- * DOCUMENT ME!
*/
public void ok_actionPerformed(ActionEvent e)
{
-
+ /*
+ * Save Visual settings
+ */
Cache.applicationProperties.setProperty("SHOW_JVSUFFIX",
Boolean.toString(seqLimit.isSelected()));
Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS",
Cache.applicationProperties.setProperty("SHOW_IDENTITY",
Boolean.toString(identity.isSelected()));
- Cache.applicationProperties.setProperty("DEFAULT_COLOUR", colour
- .getSelectedItem().toString());
Cache.applicationProperties.setProperty("GAP_SYMBOL", gapSymbolCB
.getSelectedItem().toString());
Cache.applicationProperties.setProperty("SORT_ALIGNMENT", sortby
.getSelectedItem().toString());
+ // convert description of sort order to enum name for save
+ SequenceAnnotationOrder annSortOrder = SequenceAnnotationOrder
+ .forDescription(sortAnnBy.getSelectedItem().toString());
+ if (annSortOrder != null)
+ {
+ Cache.applicationProperties.setProperty(SORT_ANNOTATIONS,
+ annSortOrder.name());
+ }
+
+ final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0;
+ Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE,
+ Boolean.valueOf(showAutocalcFirst).toString());
+
+ /*
+ * Save Colours settings
+ */
+ Cache.applicationProperties.setProperty("DEFAULT_COLOUR", colour
+ .getSelectedItem().toString());
Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
minColour.getBackground());
Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
maxColour.getBackground());
+ /*
+ * Save Structure settings
+ */
+ Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
+ Boolean.toString(addTempFactor.isSelected()));
+ Cache.applicationProperties.setProperty(ADD_SS_ANN,
+ Boolean.toString(addSecondaryStructure.isSelected()));
+ Cache.applicationProperties.setProperty(USE_RNAVIEW,
+ Boolean.toString(useRnaView.isSelected()));
+ Cache.applicationProperties.setProperty(STRUCT_FROM_PDB,
+ Boolean.toString(structFromPdb.isSelected()));
+ Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, structViewer
+ .getSelectedItem().toString());
+ Cache.setOrRemove(CHIMERA_PATH, chimeraPath.getText());
+
+ /*
+ * Save Output settings
+ */
if (epsRendering.getSelectedItem().equals("Prompt each time"))
{
Cache.applicationProperties.remove("EPS_RENDERING");
.getSelectedItem().toString());
}
- if (defaultBrowser.getText().trim().length() < 1)
- {
- Cache.applicationProperties.remove("DEFAULT_BROWSER");
- }
- else
- {
- Cache.applicationProperties.setProperty("DEFAULT_BROWSER",
- defaultBrowser.getText());
- }
+ /*
+ * Save Connections settings
+ */
+ Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText());
jalview.util.BrowserLauncher.resetBrowser();
Cache.applicationProperties.setProperty("USE_PROXY",
Boolean.toString(useProxy.isSelected()));
- if (proxyServerTB.getText().trim().length() < 1)
- {
- Cache.applicationProperties.remove("PROXY_SERVER");
- }
- else
- {
- Cache.applicationProperties.setProperty("PROXY_SERVER",
- proxyServerTB.getText());
- }
+ Cache.setOrRemove("PROXY_SERVER", proxyServerTB.getText());
- if (proxyPortTB.getText().trim().length() < 1)
- {
- Cache.applicationProperties.remove("PROXY_PORT");
- }
- else
- {
- Cache.applicationProperties.setProperty("PROXY_PORT",
- proxyPortTB.getText());
- }
+ Cache.setOrRemove("PROXY_PORT", proxyPortTB.getText());
if (useProxy.isSelected())
{
// by just adding the given line
Cache.removeProperty("NOQUESTIONNAIRES");
}
+
+ /*
+ * Save Output settings
+ */
Cache.applicationProperties.setProperty("BLC_JVSUFFIX",
Boolean.toString(blcjv.isSelected()));
Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX",
Cache.applicationProperties.setProperty("FIGURE_USERIDWIDTH",
userIdWidth.getText());
+ /*
+ * Save Editing settings
+ */
Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS",
Boolean.toString(autoCalculateConsCheck.isSelected()));
Cache.applicationProperties.setProperty("SORT_BY_TREE",
dasSource.saveProperties(Cache.applicationProperties);
wsPrefs.updateAndRefreshWsMenuConfig(false);
+
Cache.saveProperties();
+
try
{
frame.setClosed(true);
{ "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview" },
jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Select startup file");
+ chooser.setDialogTitle(MessageManager.getString("label.select_startup_file"));
int value = chooser.showOpenDialog(this);
public void defaultBrowser_mouseClicked(MouseEvent e)
{
JFileChooser chooser = new JFileChooser(".");
- chooser.setDialogTitle("Select default web browser");
+ chooser.setDialogTitle(MessageManager.getString("label.select_default_browser"));
int value = chooser.showOpenDialog(this);
super.showunconserved_actionPerformed(e);
}
- private void jbInit() throws Exception
- {
- }
-
public static Collection getGroupURLLinks()
{
return groupURLLinks;
}
- public void minColour_actionPerformed()
+ @Override
+ public void minColour_actionPerformed(JPanel panel)
{
Color col = JColorChooser.showDialog(this,
- "Select Colour for Minimum Value", minColour.getBackground());
+ MessageManager.getString("label.select_colour_minimum_value"), minColour.getBackground());
if (col != null)
{
- minColour.setBackground(col);
+ panel.setBackground(col);
}
- minColour.repaint();
+ panel.repaint();
}
- public void maxColour_actionPerformed()
+ @Override
+ public void maxColour_actionPerformed(JPanel panel)
{
Color col = JColorChooser.showDialog(this,
- "Select Colour for Maximum Value", maxColour.getBackground());
+ MessageManager.getString("label.select_colour_maximum_value"), maxColour.getBackground());
if (col != null)
{
- maxColour.setBackground(col);
+ panel.setBackground(col);
}
- maxColour.repaint();
+ panel.repaint();
}
@Override
JOptionPane
.showInternalMessageDialog(
Desktop.desktop,
- "The user defined width for the\nannotation and sequence ID columns\nin exported figures must be\nat least 12 pixels wide.",
- "Invalid ID Column width",
+ MessageManager.getString("warn.user_defined_width_requirements"),
+ MessageManager.getString("label.invalid_id_column_width"),
JOptionPane.WARNING_MESSAGE);
userIdWidth.setText("");
}
progress.setVisible(false);
progress = null;
- label.setText("Enter the redundancy threshold");
+ label.setText(MessageManager.getString("label.enter_redundancy_thereshold"));
slider.setVisible(true);
applyButton.setEnabled(true);
valueField.setVisible(true);
}
}
- EditCommand cut = new EditCommand("Remove Redundancy",
+ EditCommand cut = new EditCommand(MessageManager.getString("action.remove_redundancy"),
EditCommand.CUT, deleted, 0, width, ap.av.getAlignment());
for (int i = 0; i < del.size(); i++)
ap.alignFrame.addHistoryItem(cut);
PaintRefresher.Refresh(this, ap.av.getSequenceSetId(), true, true);
- // ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
- // .getSequences());
+ ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
}
}
*/
public void undoButton_actionPerformed(ActionEvent e)
{
+ if(historyList == null || historyList.isEmpty()){
+ undoButton.setEnabled(false);
+ return;
+ }
+
CommandI command = (CommandI) historyList.pop();
- command.undoCommand(af.getViewAlignments());
-
if (ap.av.historyList.contains(command))
{
+ command.undoCommand(af.getViewAlignments());
ap.av.historyList.remove(command);
+ ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
af.updateEditMenuBar();
}
message.append("Edit group:");
if (editCommand == null)
{
- editCommand = new EditCommand("Edit Group");
+ editCommand = new EditCommand(MessageManager.getString("action.edit_group"));
}
}
else
}
if (editCommand == null)
{
- editCommand = new EditCommand("Edit " + label);
+ editCommand = new EditCommand(MessageManager.formatMessage("label.edit_params", new String[]{label}));
}
}
if (guiWindow != null)
{
guiWindow.setProgressBar(
- "Waiting for Sequence Database Fetchers to initialise",
+ MessageManager.getString("status.waiting_sequence_database_fetchers_init"),
Thread.currentThread().hashCode());
}
// initting happening on another thread - so wait around to see if it
if (guiWindow != null)
{
guiWindow.setProgressBar(
- "Waiting for Sequence Database Fetchers to initialise",
+ MessageManager.getString("status.waiting_sequence_database_fetchers_init"),
Thread.currentThread().hashCode());
}
}
*/
if (guiWindow != null)
{
- guiWindow.setProgressBar("Initialising Sequence Database Fetchers",
+ guiWindow.setProgressBar(MessageManager.getString("status.init_sequence_database_fetchers"),
Thread.currentThread().hashCode());
}
dasRegistry = jalview.bin.Cache.getDasSourceRegistry();
jalview.ws.SequenceFetcher sf = new jalview.ws.SequenceFetcher();
if (guiWindow != null)
{
- guiWindow.setProgressBar("Initialising Sequence Database Fetchers",
+ guiWindow.setProgressBar(MessageManager.getString("status.init_sequence_database_fetchers"),
Thread.currentThread().hashCode());
}
lastDasSourceRegistry = (dasRegistry.getDasRegistryURL() + dasRegistry
JOptionPane
.showInternalMessageDialog(
Desktop.desktop,
- "Could not create the sequence fetcher client. Check error logs for details.",
- "Couldn't create SequenceFetcher",
+ MessageManager.getString("warn.couldnt_create_sequence_fetcher_client"),
+ MessageManager.getString("label.couldnt_create_sequence_fetcher"),
JOptionPane.ERROR_MESSAGE);
}
});
private String getFrameTitle()
{
- return ((alignFrame == null) ? "New " : "Additional ")
- + "Sequence Fetcher";
+ return ((alignFrame == null) ? MessageManager.getString("label.new_sequence_fetcher") : MessageManager.getString("label.additional_sequence_fetcher"));
}
private void jbInit() throws Exception
try
{
// update status
- guiWindow.setProgressBar("Fetching " + nqueries
- + " sequence queries from " + proxy.getDbName(), Thread
+ guiWindow.setProgressBar(MessageManager.formatMessage("status.fetching_sequence_queries_from", new String[]{Integer.valueOf(nqueries).toString(),proxy.getDbName()}), Thread
.currentThread().hashCode());
isAliSource = proxy.isA(DBRefSource.ALIGNMENTDB);
if (proxy.getAccessionSeparator() == null)
presultTitle.add(titl);
}
}
- guiWindow.setProgressBar("Finished querying", Thread.currentThread()
+ guiWindow.setProgressBar(MessageManager.getString("status.finshed_querying"), Thread.currentThread()
.hashCode());
}
- guiWindow.setProgressBar((presult.size() > 0) ? "Parsing results."
- : "Processing ..", Thread.currentThread().hashCode());
+ guiWindow.setProgressBar((presult.size() > 0) ? MessageManager.getString("status.parsing_results")
+ : MessageManager.getString("status.processing"), Thread.currentThread().hashCode());
// process results
while (presult.size() > 0)
{
sp.cs = cs;
}
- conservationSlider.setTitle("Conservation Colour Increment (" + source
- + ")");
+ conservationSlider.setTitle(MessageManager.formatMessage("label.conservation_colour_increment", new String[]{source}));
if (ap.av.getAlignment().getGroups() != null)
{
pid.cs = cs;
}
- PIDSlider.setTitle("Percentage Identity Threshold (" + source + ")");
+ PIDSlider.setTitle(MessageManager.formatMessage("label.percentage_identity_thereshold", new String[]{source}));
if (ap.av.getAlignment().getGroups() != null)
{
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview 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.
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.gui;
+
+import jalview.api.structures.JalviewStructureDisplayI;
+import jalview.bin.Cache;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.structure.StructureSelectionManager;
+
+import java.awt.Rectangle;
+
+/**
+ * proxy for handling structure viewers.
+ *
+ * this allows new views to be created with the currently configured viewer, the
+ * preferred viewer to be set/read and existing views created previously with a
+ * particular viewer to be recovered
+ *
+ * @author jprocter
+ */
+public class StructureViewer
+{
+ StructureSelectionManager ssm;
+
+ public enum Viewer
+ {
+ JMOL, CHIMERA
+ };
+
+ public Viewer getViewerType()
+ {
+ String viewType = Cache.getDefault(Preferences.STRUCTURE_DISPLAY,
+ Viewer.JMOL.name());
+ return Viewer.valueOf(viewType);
+ }
+
+ public void setViewerType(Viewer type)
+ {
+ Cache.setProperty(Preferences.STRUCTURE_DISPLAY, type.name());
+ }
+
+ public StructureViewer(StructureSelectionManager structureSelectionManager)
+ {
+ ssm = structureSelectionManager;
+ }
+
+ public JalviewStructureDisplayI viewStructures(AlignmentPanel ap,
+ PDBEntry[] pr, SequenceI[][] collateForPDB)
+ {
+ return viewStructures(getViewerType(), ap, pr, collateForPDB);
+ }
+
+ public JalviewStructureDisplayI viewStructures(Viewer viewerType,
+ AlignmentPanel ap, PDBEntry[] pr, SequenceI[][] collateForPDB)
+ {
+ JalviewStructureDisplayI sview = null;
+ if (viewerType.equals(Viewer.JMOL))
+ {
+ sview = new AppJmol(ap, pr, ap.av.collateForPDB(pr));
+ }
+ else if (viewerType.equals(Viewer.CHIMERA))
+ {
+ sview = new ChimeraViewFrame(ap, pr, ap.av.collateForPDB(pr));
+ }
+ else
+ {
+ Cache.log.error("Unknown structure viewer type "
+ + getViewerType().toString());
+ }
+ return sview;
+ }
+
+ public JalviewStructureDisplayI viewStructures(Viewer viewerType,
+ AlignmentPanel ap, PDBEntry pr, SequenceI[] collateForPDB)
+ {
+ JalviewStructureDisplayI sview = null;
+ if (viewerType.equals(Viewer.JMOL))
+ {
+ sview = new AppJmol(pr, collateForPDB, null, ap);
+ }
+ else if (viewerType.equals(Viewer.CHIMERA))
+ {
+ sview = new ChimeraViewFrame(pr, collateForPDB, null, ap);
+ }
+ else
+ {
+ Cache.log.error("Unknown structure viewer type "
+ + getViewerType().toString());
+ }
+ return sview;
+ }
+
+ public JalviewStructureDisplayI viewStructures(PDBEntry pdb,
+ SequenceI[] sequenceIs, Object object, AlignmentPanel ap)
+ {
+ return viewStructures(getViewerType(), ap, pdb, sequenceIs);
+ }
+
+ public JalviewStructureDisplayI createView(Viewer viewer, String[] pdbf,
+ String[] id, SequenceI[][] sq, AlignmentPanel alignPanel,
+ boolean useinJmolsuperpos, boolean usetoColourbyseq,
+ boolean jmolColouring, String fileloc, Rectangle rect, String vid)
+ {
+ JalviewStructureDisplayI sview = null;
+ switch (viewer)
+ {
+ case JMOL:
+ sview = new AppJmol(pdbf, id, sq, alignPanel, useinJmolsuperpos,
+ usetoColourbyseq, jmolColouring, fileloc, rect, vid);
+ break;
+ case CHIMERA:
+ Cache.log.error("Unsupported structure viewer type "
+ + viewer.toString());
+ break;
+ default:
+ Cache.log.error("Unknown structure viewer type " + viewer.toString());
+ }
+ return sview;
+ }
+
+}
JPanel panel = new JPanel();
bigpanel.add(panel, BorderLayout.CENTER);
bigpanel.add(
- new JLabel(
- "<html><i>Select a dark and light text colour, then set the threshold to"
- + "<br>switch between colours, based on background colour</i></html>"),
+ new JLabel("<html>"+MessageManager.getString("label.select_dark_light_set_thereshold")+"</html>"),
BorderLayout.NORTH);
panel.add(col1);
panel.add(slider);
public void mousePressed(MouseEvent e)
{
Color col = JColorChooser.showDialog(bigpanel,
- "Select Colour for Text", col1.getBackground());
+ MessageManager.getString("label.select_colour_for_text"), col1.getBackground());
if (col != null)
{
colour1Changed(col);
public void mousePressed(MouseEvent e)
{
Color col = JColorChooser.showDialog(bigpanel,
- "Select Colour for Text", col2.getBackground());
+ MessageManager.getString("label.select_colour_for_text"), col2.getBackground());
if (col != null)
{
colour2Changed(col);
});
int reply = JOptionPane.showInternalOptionDialog(ap, bigpanel,
- "Adjust Foreground Text Colour Threshold",
+ MessageManager.getString("label.adjunst_foreground_text_colour_thereshold"),
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE,
null, null, null);
if (SwingUtilities.isRightMouseButton(evt))
{
Color col = JColorChooser.showDialog(this,
- "Select Sub-Tree Colour", highlightNode.color);
+ MessageManager.getString("label.select_subtree_colour"), highlightNode.color);
if (col != null)
{
setColor(highlightNode, col);
JalviewFileChooser chooser = new JalviewFileChooser(
jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Save tree as newick file");
+ chooser.setDialogTitle(MessageManager.getString("label.save_tree_as_newick"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(null);
{ "eps" }, new String[]
{ "Encapsulated Postscript" }, "Encapsulated Postscript");
chooser.setFileView(new jalview.io.JalviewFileView());
- chooser.setDialogTitle("Create EPS file from tree");
+ chooser.setDialogTitle(MessageManager.getString("label.create_eps_from_tree"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
{ "Portable network graphics" }, "Portable network graphics");
chooser.setFileView(new jalview.io.JalviewFileView());
- chooser.setDialogTitle("Create PNG image from tree");
+ chooser.setDialogTitle(MessageManager.getString("label.create_png_from_tree"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
*/
package jalview.gui;
+import jalview.api.structures.JalviewStructureDisplayI;
import jalview.datamodel.SequenceGroup;
import jalview.io.JalviewFileChooser;
import jalview.jbgui.GUserDefinedColours;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ResidueProperties;
import jalview.schemes.UserColourScheme;
+import jalview.util.ColorUtils;
import jalview.util.MessageManager;
import java.awt.Color;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.Hashtable;
import java.util.StringTokenizer;
-import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.event.ChangeListener;
/**
- * DOCUMENT ME!
+ * This panel allows the user to assign colours to Amino Acid residue codes, and
+ * save the colour scheme.
*
- * @author $author$
- * @version $Revision$
+ * @author Andrew Waterhouse
+ * @author Mungo Carstairs
*/
public class UserDefinedColours extends GUserDefinedColours implements
ChangeListener
{
+ private static final int MY_FRAME_HEIGHT = 420;
+
+ private static final int MY_FRAME_WIDTH = 810;
+
+ private static final int MY_FRAME_WIDTH_CASE_SENSITIVE = 970;
+
AlignmentPanel ap;
SequenceGroup seqGroup;
- Vector selectedButtons;
+ ArrayList<JButton> selectedButtons;
ColourSchemeI oldColourScheme;
JInternalFrame frame;
- AppJmol jmol;
+ JalviewStructureDisplayI jmol;
- Vector upperCaseButtons;
+ ArrayList<JButton> upperCaseButtons;
- Vector lowerCaseButtons;
+ ArrayList<JButton> lowerCaseButtons;
/**
* Creates a new UserDefinedColours object.
showFrame();
}
- public UserDefinedColours(AppJmol jmol, ColourSchemeI oldcs)
+ public UserDefinedColours(JalviewStructureDisplayI jmol,
+ ColourSchemeI oldcs)
{
super();
this.jmol = jmol;
frame = new JInternalFrame();
frame.setContentPane(this);
Desktop.addInternalFrame(frame,
- MessageManager.getString("label.user_defined_colours"), 720,
- 370, true);
+ MessageManager.getString("label.user_defined_colours"),
+ MY_FRAME_WIDTH, MY_FRAME_HEIGHT, true);
if (seqGroup != null)
{
frame.setTitle(frame.getTitle() + " (" + seqGroup.getName() + ")");
}
-
- if (new jalview.util.Platform().isAMac())
- {
- frame.setSize(760, 370);
- }
}
void resetButtonPanel(boolean caseSensitive)
if (upperCaseButtons == null)
{
- upperCaseButtons = new Vector();
+ upperCaseButtons = new ArrayList<JButton>();
}
JButton button;
if (lowerCaseButtons == null)
{
- lowerCaseButtons = new Vector();
+ lowerCaseButtons = new ArrayList<JButton>();
}
for (int i = 0; i < 20; i++)
buttonPanel.add(makeButton("x", "x", lowerCaseButtons, 22));
}
+ // JAL-1360 widen the frame dynamically to accommodate case-sensitive AA
+ // codes
+ if (this.frame != null)
+ {
+ int newWidth = caseSensitive ? MY_FRAME_WIDTH_CASE_SENSITIVE
+ : MY_FRAME_WIDTH;
+ this.frame.setSize(newWidth, this.frame.getHeight());
+ }
+
buttonPanel.validate();
validate();
}
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void stateChanged(ChangeEvent evt)
{
if (selectedButtons != null)
{
JButton button = null;
+ final Color newColour = colorChooser.getColor();
for (int i = 0; i < selectedButtons.size(); i++)
{
- button = (JButton) selectedButtons.elementAt(i);
- button.setBackground(colorChooser.getColor());
- button.setForeground(button.getBackground().brighter().brighter()
- .brighter());
+ button = selectedButtons.get(i);
+ button.setBackground(newColour);
+ button.setForeground(ColorUtils.brighterThan(newColour));
}
if (button == lcaseColour)
{
for (int i = 0; i < lowerCaseButtons.size(); i++)
{
- button = (JButton) lowerCaseButtons.elementAt(i);
- button.setBackground(colorChooser.getColor());
- button.setForeground(button.getBackground().brighter().brighter()
- .brighter());
+ button = lowerCaseButtons.get(i);
+ button.setBackground(newColour);
+ button.setForeground(ColorUtils.brighterThan(button
+ .getBackground()));
}
}
}
}
/**
- * DOCUMENT ME!
+ * Performs actions when a residue button is clicked. This manages the button
+ * selection set (highlighted by brighter foreground text).
+ * <p>
+ * On select button(s) with Ctrl/click or Shift/click: set button foreground
+ * text to brighter than background.
+ * <p>
+ * On unselect button(s) with Ctrl/click on selected, or click to release
+ * current selection: reset foreground text to darker than background.
+ * <p>
+ * Simple click: clear selection (resetting foreground to darker); set clicked
+ * button foreground to brighter
+ * <p>
+ * Finally, synchronize the colour chooser to the colour of the first button
+ * in the selected set.
*
* @param e
- * DOCUMENT ME!
*/
public void colourButtonPressed(MouseEvent e)
{
if (selectedButtons == null)
{
- selectedButtons = new Vector();
+ selectedButtons = new ArrayList<JButton>();
}
JButton pressed = (JButton) e.getSource();
JButton start, end = (JButton) e.getSource();
if (selectedButtons.size() > 0)
{
- start = (JButton) selectedButtons
- .elementAt(selectedButtons.size() - 1);
+ start = selectedButtons.get(selectedButtons.size() - 1);
}
else
{
JButton button = (JButton) buttonPanel.getComponent(b);
if (!selectedButtons.contains(button))
{
- button.setForeground(button.getBackground().brighter().brighter());
+ button.setForeground(ColorUtils.brighterThan(button
+ .getBackground()));
selectedButtons.add(button);
}
}
{
for (int b = 0; b < selectedButtons.size(); b++)
{
- JButton button = (JButton) selectedButtons.elementAt(b);
- button.setForeground(button.getBackground().darker().darker());
+ JButton button = selectedButtons.get(b);
+ button.setForeground(ColorUtils.darkerThan(button.getBackground()));
}
selectedButtons.clear();
- pressed.setForeground(pressed.getBackground().brighter().brighter());
- selectedButtons.addElement(pressed);
+ pressed.setForeground(ColorUtils.brighterThan(pressed.getBackground()));
+ selectedButtons.add(pressed);
}
else if (e.isControlDown())
{
if (selectedButtons.contains(pressed))
{
- pressed.setForeground(pressed.getBackground().darker().darker());
+ pressed.setForeground(ColorUtils.darkerThan(pressed.getBackground()));
selectedButtons.remove(pressed);
}
else
{
- pressed.setForeground(pressed.getBackground().brighter().brighter());
- selectedButtons.addElement(pressed);
+ pressed.setForeground(ColorUtils.brighterThan(pressed
+ .getBackground()));
+ selectedButtons.add(pressed);
}
}
if (selectedButtons.size() > 0)
{
- colorChooser.setColor(((JButton) selectedButtons.elementAt(0))
- .getBackground());
+ colorChooser.setColor((selectedButtons.get(0)).getBackground());
}
}
* @param aa
* DOCUMENT ME!
*/
- JButton makeButton(String label, String aa, Vector caseSensitiveButtons,
- int buttonIndex)
+ JButton makeButton(String label, String aa,
+ ArrayList<JButton> caseSensitiveButtons, int buttonIndex)
{
final JButton button;
Color col;
if (buttonIndex < caseSensitiveButtons.size())
{
- button = (JButton) caseSensitiveButtons.elementAt(buttonIndex);
+ button = caseSensitiveButtons.get(buttonIndex);
col = button.getBackground();
}
else
button = new JButton();
button.addMouseListener(new java.awt.event.MouseAdapter()
{
+ @Override
public void mouseClicked(MouseEvent e)
{
colourButtonPressed(e);
}
});
- caseSensitiveButtons.addElement(button);
+ caseSensitiveButtons.add(button);
col = Color.white;
if (oldColourScheme != null)
button.setMargin(new java.awt.Insets(2, 14, 2, 14));
}
+ button.setOpaque(true); // required for the next line to have effect
button.setBackground(col);
button.setText(label);
- button.setForeground(col.darker().darker().darker());
+ button.setForeground(ColorUtils.darkerThan(col));
button.setFont(new java.awt.Font("Verdana", Font.BOLD, 10));
return button;
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void okButton_actionPerformed(ActionEvent e)
{
- applyButton_actionPerformed(null);
-
- try
- {
- frame.setClosed(true);
- } catch (Exception ex)
- {
- }
+ //Check if the user have done any selection
+ boolean showWarning = (upperCaseButtons==null) ||
+ ((upperCaseButtons!=null) && (upperCaseButtons.size()==0)) ||
+ (lowerCaseButtons==null) ||
+ ((lowerCaseButtons!=null) && (lowerCaseButtons.size()==0));
+ if (showWarning){
+ JOptionPane.showMessageDialog(Desktop.desktop,
+ MessageManager.getString("label.no_colour_selection_in_scheme"),MessageManager.getString("label.no_colour_selection_warn"),
+ JOptionPane.WARNING_MESSAGE);
+
+ }else{
+ applyButton_actionPerformed(null);
+
+ try
+ {
+ frame.setClosed(true);
+ } catch (Exception ex)
+ {
+ }
+ }
}
/**
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void applyButton_actionPerformed(ActionEvent e)
{
- UserColourScheme ucs = getSchemeFromButtons();
+ //Check if the user have done any selection
+ boolean showWarning = (upperCaseButtons==null) ||
+ ((upperCaseButtons!=null) && (upperCaseButtons.size()==0)) ||
+ (lowerCaseButtons==null) ||
+ ((lowerCaseButtons!=null) && (lowerCaseButtons.size()==0));
+ if (showWarning){
+ JOptionPane.showMessageDialog(Desktop.desktop,
+ MessageManager.getString("label.no_colour_selection_in_scheme"),MessageManager.getString("label.no_colour_selection_warn"),
+ JOptionPane.WARNING_MESSAGE);
+
+ }
+ UserColourScheme ucs = getSchemeFromButtons();
ucs.setName(schemeName.getText());
if (seqGroup != null)
Color[] newColours = new Color[24];
- for (int i = 0; i < 24; i++)
- {
- JButton button = (JButton) upperCaseButtons.elementAt(i);
- newColours[i] = button.getBackground();
+ int length = upperCaseButtons.size();
+ if (length<24){
+ int i = 0;
+ for (JButton btn:upperCaseButtons){
+ newColours[i] = btn.getBackground();
+ i++;
+ }
+ }else{
+ for (int i = 0; i < 24; i++){
+ JButton button = (JButton) upperCaseButtons.get(i);
+ newColours[i] = button.getBackground();
+ }
}
UserColourScheme ucs = new UserColourScheme(newColours);
if (caseSensitive.isSelected())
{
newColours = new Color[23];
- for (int i = 0; i < 23; i++)
- {
- JButton button = (JButton) lowerCaseButtons.elementAt(i);
- newColours[i] = button.getBackground();
+ length = lowerCaseButtons.size();
+ if (length<23){
+ int i = 0;
+ for (JButton btn:lowerCaseButtons){
+ newColours[i] = btn.getBackground();
+ i++;
+ }
+ }else{
+ for (int i = 0; i < 23; i++){
+ JButton button = (JButton) lowerCaseButtons.get(i);
+ newColours[i] = button.getBackground();
+ }
}
ucs.setLowerCaseColours(newColours);
}
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void loadbutton_actionPerformed(ActionEvent e)
{
- upperCaseButtons = new Vector();
- lowerCaseButtons = new Vector();
+ upperCaseButtons = new ArrayList<JButton>();
+ lowerCaseButtons = new ArrayList<JButton>();
JalviewFileChooser chooser = new JalviewFileChooser(
jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
resetButtonPanel(true);
for (int i = 0; i < lowerCaseButtons.size(); i++)
{
- JButton button = (JButton) lowerCaseButtons.elementAt(i);
+ JButton button = lowerCaseButtons.get(i);
button.setBackground(ucs.getLowerCaseColours()[i]);
}
for (int i = 0; i < upperCaseButtons.size(); i++)
{
- JButton button = (JButton) upperCaseButtons.elementAt(i);
+ JButton button = upperCaseButtons.get(i);
button.setBackground(colors[i]);
}
jalview.binding.JalviewUserColours jucs = new jalview.binding.JalviewUserColours();
- jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);
+ jucs = jucs.unmarshal(in);
newColours = new Color[jucs.getColourCount()];
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void savebutton_actionPerformed(ActionEvent e)
{
if (schemeName.getText().trim().length() < 1)
{
int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
MessageManager.formatMessage(
- "label.colour_scheme_exists_overwrite", new String[]
+ "label.colour_scheme_exists_overwrite", new Object[]
{ schemeName.getText(), schemeName.getText() }),
MessageManager.getString("label.duplicate_scheme_name"),
JOptionPane.YES_NO_OPTION);
{ "Jalview User Colours" }, "Jalview User Colours");
chooser.setFileView(new jalview.io.JalviewFileView());
- chooser.setDialogTitle("Save colour scheme");
+ chooser.setDialogTitle(MessageManager.getString("label.save_colour_scheme"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(this);
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void cancelButton_actionPerformed(ActionEvent e)
{
if (ap != null)
}
+ @Override
public void caseSensitive_actionPerformed(ActionEvent e)
{
resetButtonPanel(caseSensitive.isSelected());
lcaseColour.setEnabled(caseSensitive.isSelected());
}
+ @Override
public void lcaseColour_actionPerformed(ActionEvent e)
{
if (selectedButtons == null)
{
- selectedButtons = new Vector();
+ selectedButtons = new ArrayList<JButton>();
}
else
{
}
selectedButtons.add(lcaseColour);
}
-
}
import jalview.structure.StructureSelectionManager;
import jalview.structure.VamsasListener;
import jalview.structure.VamsasSource;
+import jalview.util.MessageManager;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
{
if (sess != null)
{
- throw new Error(
- "Implementation Error - cannot import existing vamsas document into an existing session, Yet!");
+ throw new Error(MessageManager.getString("error.implementation_error_cannot_import_vamsas_doc"));
}
try
{
.showInternalMessageDialog(
Desktop.desktop,
- "VAMSAS Document could not be opened as a new session - please choose another",
- "VAMSAS Document Import Failed",
+ MessageManager.getString("label.vamsas_doc_couldnt_be_opened_as_new_session"),
+ MessageManager.getString("label.vamsas_document_import_failed"),
JOptionPane.ERROR_MESSAGE);
}
{
if (!inSession())
{
- throw new Error(
- "Impementation error! Vamsas Operations when client not initialised and connected.");
+ throw new Error(MessageManager.getString("error.implementation_error_vamsas_operation_not_init"));
}
addDocumentUpdateHandler();
addStoreDocumentHandler();
public void end_session(boolean promptUser)
{
if (!inSession())
- throw new Error("Jalview not connected to Vamsas session.");
+ throw new Error(MessageManager.getString("error.jalview_no_connected_vamsas_session"));
Cache.log.info("Jalview disconnecting from the Vamsas Session.");
try
{
return;
}
- throw new Error(
- "IMPLEMENTATION ERROR: Cannot recover vamsas object mappings - no backup was made.");
+ throw new Error(MessageManager.getString("error.implementation_error_cannot_recover_vamsas_object_mappings"));
}
jv2vobj.clear();
Iterator el = _backup_jv2vobj.entrySet().iterator();
{
if (jobpane < 0 || jobpane >= jobPanes.size())
{
- throw new Error("setStatus called for non-existent job pane."
- + jobpane);
+ throw new Error(MessageManager.formatMessage("error.setstatus_called_non_existent_job_pane", new String[]{Integer.valueOf(jobpane).toString()}));
}
switch (status)
{
// anyhow - it has to stop threads and clean up
// JBPNote : TODO: Instead of a warning, we should have an optional 'Are
// you sure?' prompt
- warnUser("This job cannot be cancelled.\nJust close the window.",
- "Cancel job");
+ warnUser(MessageManager.getString("warn.job_cannot_be_cancelled_close_window"),
+ MessageManager.getString("action.cancel_job"));
}
else
{
{
if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
{
- throw new Error(
- "call setProgressBar before registering the progress bar's handler.");
+ throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
}
progressBarHandlers.put(new Long(id), handler);
final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
public void actionPerformed(ActionEvent e)
{
handler.cancelActivity(id);
- us.setProgressBar(
- "Cancelled "
- + ((JLabel) progressPanel.getComponent(0))
- .getText(), id);
+ us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
}
});
progressPanel.add(cancel, BorderLayout.EAST);
frame = new JDialog(Desktop.instance, true);
- frame.setTitle("Edit parameters for " + service.getActionText());
+ frame.setTitle(MessageManager.formatMessage("label.edit_params_for", new String[]{service.getActionText()}));
Rectangle deskr = Desktop.instance.getBounds();
Dimension pref = this.getPreferredSize();
frame.setBounds(new Rectangle(
}
WsJobParameters pgui = new WsJobParameters(lastserv,
new JabaPreset(lastserv, pr));
- JFrame jf = new JFrame("Parameters for "
- + lastserv.getActionText());
+ JFrame jf = new JFrame(MessageManager.formatMessage("label.ws_parameters_for", new String[]{lastserv.getActionText()}));
JPanel cont = new JPanel(new BorderLayout());
pgui.validate();
cont.setPreferredSize(pgui.getPreferredSize());
public void run()
{
JOptionPane.showMessageDialog(ourframe,
- "Invalid name - preset already exists.",
- "Invalid name", JOptionPane.WARNING_MESSAGE);
+ MessageManager.getString("label.invalid_name_preset_exists"),
+ MessageManager.getString("label.invalid_name"), JOptionPane.WARNING_MESSAGE);
}
});
}
if (parser == null)
{
- throw new Error(
- "Implementation error: Can't find a marshaller for the parameter set");
+ throw new Error(MessageManager.getString("error.implementation_error_cannot_find_marshaller_for_param_set"));
}
if (filename == null)
{
{ "Web Service Parameter File" },
"Web Service Parameter File");
chooser.setFileView(new jalview.io.JalviewFileView());
- chooser.setDialogTitle("Choose a filename for this parameter file");
+ chooser.setDialogTitle(MessageManager.getString("label.choose_filename_for_param_file"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(Desktop.instance);
if (value == JalviewFileChooser.APPROVE_OPTION)
}
wsList.setModel(new WsUrlTableModel(tdat));
- wsList.getColumn("Status").setMinWidth(10);
+ wsList.getColumn(MessageManager.getString("label.status")).setMinWidth(10);
}
private class JabaWSStatusRenderer extends JPanel implements
{
private Object[][] data;
+ private String[] columnNames = new String[]
+ { MessageManager.getString("label.service_url"), MessageManager.getString("label.status") };
public WsUrlTableModel(Object[][] tdat)
{
@Override
public String getColumnName(int column)
{
- if (column == 1)
- {
- return "Status";
- }
- return "Service URL";
+ return columnNames[column];
}
@Override
int sel = wsList.getSelectedRow();
if (sel > -1)
{
- String url = editUrl(wsUrls.elementAt(sel), "Edit JABAWS URL");
+ String url = editUrl(wsUrls.elementAt(sel), MessageManager.getString("label.edit_jabaws_url"));
if (url != null)
{
int present = wsUrls.indexOf(url);
protected void newSbrsUrl_actionPerformed(ActionEvent e)
{
RestServiceEditorPane rse = new RestServiceEditorPane();
- rse.showDialog("Add a new Simple Bioinformatics Rest Service");
+ rse.showDialog(MessageManager.getString("label.add_new_sbrs_service"));
String rservice = rse.getEditedRestService();
if (rservice != null && !rsbsUrls.contains(rservice))
{
{
RestServiceEditorPane rse = new RestServiceEditorPane(
new RestServiceDescription(rsbsUrls.elementAt(sel)));
- rse.showDialog("Edit Simple Bioinformatics Rest Service entry");
+ rse.showDialog(MessageManager.getString("label.edit_sbrs_entry"));
String rservice = rse.getEditedRestService();
if (rservice != null)
{
int validate = JOptionPane
.showInternalConfirmDialog(
Desktop.desktop,
- "Validate JabaWS Server ?\n(Look in console output for results)",
- "Test Server?", JOptionPane.YES_NO_OPTION);
+ MessageManager.getString("info.validate_jabaws_server"),
+ MessageManager.getString("label.test_server"), JOptionPane.YES_NO_OPTION);
if (validate == JOptionPane.OK_OPTION)
{
if (jalview.ws.jws2.Jws2Discoverer.testServiceUrl(foo))
JOptionPane
.showInternalMessageDialog(
Desktop.desktop,
- "Service did not pass validation.\nCheck the Jalview Console for more details.");
+ MessageManager.getString("warn.server_didnt_pass_validation"));
}
}
else
@Override
protected void newWsUrl_actionPerformed(ActionEvent e)
{
- String url = editUrl(null, "Add new JABAWS URL");
+ String url = editUrl(null, MessageManager.getString("label.add_jabaws_url"));
if (url != null)
{
if (!wsUrls.contains(url))
public void run()
{
long ct = System.currentTimeMillis();
- Desktop.instance.setProgressBar("Refreshing Web Service Menus",
+ Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_web_service_menus"),
ct);
if (lastrefresh != update)
{
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
import java.io.IOException;
import java.util.Enumeration;
/**
* annotation to be added to generated alignment object
*/
- protected Vector annotations;
+ protected Vector<AlignmentAnnotation> annotations;
/**
* Properties to be added to generated alignment object
boolean jvSuffix = true;
+ private boolean parseCalled;
+
/**
* Creates a new AlignFile object.
*/
*/
public AlignFile(String inFile, String type) throws IOException
{
+ this(true, inFile, type);
+ }
+
+ /**
+ * Constructor which (optionally delays) parsing of data from a file of some specified type.
+ *
+ * @param parseImmediately
+ * if false, need to call 'doParse()' to begin parsing data
+ * @param inFile
+ * Filename to read from.
+ * @param type
+ * What type of file to read from (File, URL)
+ * @throws IOException
+ */
+ public AlignFile(boolean parseImmediately, String inFile, String type) throws IOException
+ {
super(inFile, type);
initData();
- parse();
- // sets the index of each sequence in the alignment
- for (int i = 0, c = seqs.size(); i < c; i++)
- {
- seqs.get(i).setIndex(i);
+ if (parseImmediately) {
+ doParse();
}
}
-
/**
* Attempt to read from the position where some other parsing process left
* off.
*/
public AlignFile(FileParse source) throws IOException
{
+ this(true,source);
+ }
+ /**
+ * Construct a new parser to read from the position where some other parsing process left
+ *
+ * @param parseImmediately
+ * if false, need to call 'doParse()' to begin parsing data
+ * @param source
+ */
+ public AlignFile(boolean parseImmediately, FileParse source) throws IOException
+ {
super(source);
initData();
+ if (parseImmediately) {
+ doParse();
+ }
+ }
+ /**
+ * called if parsing was delayed till after parser was constructed
+ * @throws IOException
+ */
+ public void doParse() throws IOException
+ {
+ if (parseCalled)
+ {
+ throw new IOException(
+ "Implementation error: Parser called twice for same data.\n"
+ + "Need to call initData() again before parsing can be reattempted.");
+ }
+ parseCalled=true;
parse();
// sets the index of each sequence in the alignment
for (int i = 0, c = seqs.size(); i < c; i++)
}
}
+
/**
* Return the seqs Vector
*/
{
if (key == null)
{
- throw new Error(
- "Implementation error: Cannot have null alignment property key.");
+ throw new Error(MessageManager.getString("error.implementation_error_cannot_have_null_alignment"));
}
if (value == null)
{
{
seqs = new Vector();
annotations = new Vector();
+ parseCalled=false;
}
/**
/*
* Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
* Copyright (C) 2014 The Jalview Authors
- *
+ *
* This file is part of Jalview.
- *
+ *
* Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
+ * 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.
- *
- * Jalview 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
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
package jalview.io;
+import jalview.api.AlignViewportI;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentView;
+import jalview.util.MessageManager;
+
import java.io.File;
import java.io.InputStream;
-
-import jalview.datamodel.*;
+import java.util.List;
/**
* A low level class for alignment and feature IO with alignment formatting
* methods used by both applet and application for generating flat alignment
* files. It also holds the lists of magic format names that the applet and
* application will allow the user to read or write files with.
- *
+ *
* @author $author$
* @version $Revision$
*/
* List of valid format strings used in the isValidFormat method
*/
public static final String[] READABLE_FORMATS = new String[]
- { "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH",
- "PDB", "JnetFile", "RNAML" }; // , "SimpleBLAST" };
+ { "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH",
+ "PDB", "JnetFile", "RNAML", PhylipFile.FILE_DESC, "HTML" }; // ,
+ // "SimpleBLAST"
+ // };
/**
* List of valid format strings for use by callers of the formatSequences
* method
*/
public static final String[] WRITEABLE_FORMATS = new String[]
- { "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "AMSA" };
+ { "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "AMSA",
+ "STH", PhylipFile.FILE_DESC };
/**
* List of extensions corresponding to file format types in WRITABLE_FNAMES
* that are writable by the application.
*/
public static final String[] WRITABLE_EXTENSIONS = new String[]
- { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
- "jvp", "sto,stk", "jar" };
+ { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
+ "jvp", "sto,stk", "jar", PhylipFile.FILE_EXT };
/**
* List of writable formats by the application. Order must correspond with the
* WRITABLE_EXTENSIONS list of formats.
*/
public static final String[] WRITABLE_FNAMES = new String[]
- { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Jalview",
- "STH", "Jalview" };
+ { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Jalview",
+ "STH", "Jalview", PhylipFile.FILE_DESC };
/**
* List of readable format file extensions by application in order
* corresponding to READABLE_FNAMES
*/
public static final String[] READABLE_EXTENSIONS = new String[]
- { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
- "jar,jvp", "sto,stk", "xml,rnaml" }; // ".blast"
+ { "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
+ "jar,jvp", "sto,stk", "xml,rnaml", PhylipFile.FILE_EXT,
+ "html" }; // ".blast"
/**
* List of readable formats by application in order corresponding to
* READABLE_EXTENSIONS
*/
public static final String[] READABLE_FNAMES = new String[]
- { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Jalview",
- "Stockholm", "RNAML" };// ,
+ { "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Jalview",
+ "Stockholm", "RNAML", PhylipFile.FILE_DESC, "HTML" };// ,
// "SimpleBLAST"
// };
+ prettyPrint(READABLE_FORMATS);
/**
- *
+ *
* @param els
* @return grammatically correct(ish) list consisting of els elements.
*/
for (int i = 0, iSize = els.length - 1; i < iSize; i++)
{
list.append(els[i]);
- list.append(",");
+ list.append(", ");
}
list.append(" and " + els[els.length - 1] + ".");
return list.toString();
/**
* check that this format is valid for reading
- *
+ *
* @param format
* a format string to be compared with READABLE_FORMATS
* @return true if format is readable
/**
* validate format is valid for IO
- *
+ *
* @param format
* a format string to be compared with either READABLE_FORMATS or
* WRITEABLE_FORMATS
boolean valid = false;
String[] format_list = (forwriting) ? WRITEABLE_FORMATS
: READABLE_FORMATS;
- for (int i = 0; i < format_list.length; i++)
+ for (String element : format_list)
{
- if (format_list[i].equalsIgnoreCase(format))
+ if (element.equalsIgnoreCase(format))
{
return true;
}
/**
* Constructs the correct filetype parser for a characterised datasource
- *
+ *
* @param inFile
* data/data location
* @param type
* type of datasource
* @param format
* File format of data provided by datasource
- *
+ *
* @return DOCUMENT ME!
*/
public Alignment readFile(String inFile, String type, String format)
}
else if (format.equals("PDB"))
{
- afile = new MCview.PDBfile(inFile, type);
+ afile = new MCview.PDBfile(true,true,inFile, type);
// Uncomment to test Jmol data based PDB processing: JAL-1213
// afile = new jalview.ext.jmol.PDBFileWithJmol(inFile, type);
}
{
afile = new SimpleBlastFile(inFile, type);
}
+ else if (format.equals(PhylipFile.FILE_DESC))
+ {
+ afile = new PhylipFile(inFile, type);
+ }
+ // else if (format.equals(HtmlFile.FILE_DESC))
+ // {
+ // afile = new HtmlFile(inFile, type);
+ // }
else if (format.equals("RNAML"))
{
afile = new RnamlFile(inFile, type);
/**
* Constructs the correct filetype parser for an already open datasource
- *
+ *
* @param source
* an existing datasource
* @param format
* File format of data that will be provided by datasource
- *
+ *
* @return DOCUMENT ME!
*/
public AlignmentI readFromFile(FileParse source, String format)
}
else if (format.equals("PDB"))
{
- afile = new MCview.PDBfile(source);
+ afile = new MCview.PDBfile(true,true,source);
}
else if (format.equals("STH"))
{
{
afile = new SimpleBlastFile(source);
}
-
+ else if (format.equals(PhylipFile.FILE_DESC))
+ {
+ afile = new PhylipFile(source);
+ }
+ // else if (format.equals(HtmlFile.FILE_DESC))
+ // {
+ // afile = new HtmlFile(source);
+ // }
Alignment al = new Alignment(afile.getSeqsAsArray());
afile.addAnnotations(al);
}
}
+
+ /**
+ * create an alignment flatfile from a Jalview alignment view
+ * @param format
+ * @param jvsuffix
+ * @param av
+ * @param selectedOnly
+ * @return flatfile in a string
+ */
+ public String formatSequences(String format, boolean jvsuffix,
+ AlignViewportI av, boolean selectedOnly)
+ {
+
+ AlignmentView selvew = av.getAlignmentView(selectedOnly, false);
+ AlignmentI aselview = selvew.getVisibleAlignment(av
+ .getGapCharacter());
+ List<AlignmentAnnotation> ala = (av
+ .getVisibleAlignmentAnnotation(selectedOnly));
+ if (ala != null)
+ {
+ for (AlignmentAnnotation aa : ala)
+ {
+ aselview.addAnnotation(aa);
+ }
+ }
+
+ return formatSequences(format, aselview, jvsuffix);
+ }
+
/**
* Construct an output class for an alignment in a particular filetype TODO:
* allow caller to detect errors and warnings encountered when generating
* output
- *
+ *
* @param format
* string name of alignment format
* @param alignment
* @param jvsuffix
* passed to AlnFile class controls whether /START-END is added to
* sequence names
- *
+ *
* @return alignment flat file contents
*/
public String formatSequences(String format, AlignmentI alignment,
{
afile = new AMSAFile(alignment);
}
+ else if (format.equalsIgnoreCase(PhylipFile.FILE_DESC))
+ {
+ afile = new PhylipFile();
+ }
+ // else if (format.equalsIgnoreCase(HtmlFile.FILE_DESC))
+ // {
+ // afile = new HtmlFile();
+ // }
else if (format.equalsIgnoreCase("RNAML"))
{
afile = new RnamlFile();
else
{
- throw new Exception(
- "Implementation error: Unknown file format string");
+ throw new Exception(MessageManager.getString("error.implementation_error_unknown_file_format_string"));
}
afile.setNewlineString(newline);
afile.addJVSuffix(jvsuffix);
} catch (Exception e)
{
System.err
- .println("Couln't format the alignment for output as a FASTA file.");
+ .println("Couln't format the alignment for output as a FASTA file.");
e.printStackTrace(System.err);
}
}
}
System.out.println("Read took " + (t1 / 1000.0) + " seconds.");
System.out
- .println("Difference between free memory now and before is "
- + (memf / (1024.0 * 1024.0) * 1.0) + " MB");
+ .println("Difference between free memory now and before is "
+ + (memf / (1024.0 * 1024.0) * 1.0) + " MB");
} catch (Exception e)
{
System.err.println("Exception when dealing with " + i
/**
* try to discover how to access the given file as a valid datasource that
* will be identified as the given type.
- *
+ *
* @param file
* @param format
* @return protocol that yields the data parsable as the given type
} catch (Exception ex)
{
System.err
- .println("Exception checking resources: " + file + " " + ex);
+ .println("Exception checking resources: " + file + " " + ex);
}
if (file.indexOf("://") > -1)
if (debug)
{
System.out
- .println("File deemed not accessible via " + protocol);
+ .println("File deemed not accessible via " + protocol);
}
fp.close();
return null;
--- /dev/null
+package jalview.io;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignViewport;
+import jalview.gui.AlignmentPanel;
+import jalview.gui.FeatureRenderer;
+import jalview.gui.SequenceRenderer;
+import jalview.json.binding.v1.BioJsAlignmentPojo;
+import jalview.json.binding.v1.BioJsFeaturePojo;
+import jalview.json.binding.v1.BioJsSeqPojo;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.util.MessageManager;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.util.ArrayList;
+
+import com.json.JSONException;
+
+public class BioJsHTMLOutput
+{
+ private AlignViewport av;
+
+ private FeatureRenderer fr;
+
+ public BioJsHTMLOutput(AlignmentPanel ap, SequenceRenderer sr,
+ FeatureRenderer fr1)
+ {
+ this.av = ap.av;
+ this.fr = new FeatureRenderer(ap);
+ fr.transferSettings(fr1);
+
+ exportAsBioJsHtml();
+ }
+
+ private void exportAsBioJsHtml()
+ {
+ try
+ {
+ JalviewFileChooser jvFileChooser = getJalviewFileChooserOption();
+ int fileChooserOpt = jvFileChooser.showSaveDialog(null);
+ if (fileChooserOpt == JalviewFileChooser.APPROVE_OPTION)
+ {
+ jalview.bin.Cache.setProperty("LAST_DIRECTORY", jvFileChooser
+ .getSelectedFile().getParent());
+ String selectedFile = jvFileChooser.getSelectedFile().getPath();
+ String generartedBioJs = generateBioJsAlignmentData(av
+ .getAlignment());
+ PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
+ selectedFile));
+ out.print(generartedBioJs);
+ out.close();
+ jalview.util.BrowserLauncher.openURL("file:///" + selectedFile);
+ }
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ private JalviewFileChooser getJalviewFileChooserOption()
+ {
+ JalviewFileChooser chooser = new JalviewFileChooser(
+ jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
+ { "html" }, new String[]
+ { "HTML files" }, "HTML files");
+ chooser.setFileView(new JalviewFileView());
+
+ // TODO uncomment when supported by MassageManager
+ chooser.setDialogTitle(MessageManager
+ .getString("label.save_as_biojs_html"));
+ chooser.setDialogTitle("save as BioJs HTML");
+ chooser.setToolTipText(MessageManager.getString("action.save"));
+
+ return chooser;
+ }
+
+ private String generateBioJsAlignmentData(AlignmentI alignment)
+ throws IOException, JSONException
+ {
+ BioJsAlignmentPojo bjsAlignment = new BioJsAlignmentPojo();
+ bjsAlignment.setGlobalColorScheme(ColourSchemeProperty.getColourName(av
+ .getGlobalColourScheme()));
+
+ // av.setGlobalColourScheme(cs);
+ int count = 0;
+ for (SequenceI seq : alignment.getSequences())
+ {
+ StringBuilder name = new StringBuilder();
+ name.append(seq.getName()).append("/").append(seq.getStart())
+ .append("-").append(seq.getEnd());
+ // BioJsSeqPojo seqPojo = new BioJsSeqPojo(seq.getStart(), seq.getEnd(),
+ // String.valueOf(++count),
+ // name.toString(), seq.getSequenceAsString());
+ //
+ BioJsSeqPojo seqPojo = new BioJsSeqPojo();
+ seqPojo.setId(String.valueOf(++count));
+ seqPojo.setEnd(seq.getEnd());
+ seqPojo.setStart(seq.getStart());
+ seqPojo.setName(name.toString());
+ seqPojo.setSeq(seq.getSequenceAsString());
+
+ SequenceFeature[] seqFeatures = seq.getDatasetSequence()
+ .getSequenceFeatures();
+ if (seqFeatures != null)
+ {
+
+ ArrayList<BioJsFeaturePojo> bjsSeqFeatures = new ArrayList<BioJsFeaturePojo>();
+ for (SequenceFeature sf : seqFeatures)
+ {
+
+ String featureColour = jalview.util.Format.getHexString(fr
+ .getColour(sf));
+ BioJsFeaturePojo bjsFeature = new BioJsFeaturePojo();
+ bjsFeature.setFillColor(featureColour);
+ bjsFeature.setXstart(sf.getBegin());
+ bjsFeature.setXend(sf.getEnd());
+ bjsFeature.setText(sf.getType());
+
+ bjsSeqFeatures.add(bjsFeature);
+
+ }
+
+ seqPojo.setFeatures(bjsSeqFeatures);
+ }
+ bjsAlignment.getSeqs().add(seqPojo);
+ }
+
+ String jalviewData = new com.json.JSONObject(bjsAlignment).toString()
+ .replaceAll("xstart", "xStart").replaceAll("xend", "xEnd");
+ // String bioJSTemplate = new String(
+ // java.nio.file.Files.readAllBytes(java.nio.file.Paths
+ // .get("resources/templates/BioJSTemplate.txt")));
+ String bioJSTemplate = getBioJsTemplateAsString(this);
+
+ return bioJSTemplate.replaceAll("#sequenceData#", jalviewData)
+ .replaceAll(
+ "#jalview_logo#",
+ alignment.getClass()
+ .getResource("/images/Jalview_Logo.png")
+ .toString());
+ }
+
+ public static String getBioJsTemplateAsString(Object currentObj)
+ throws IOException
+ {
+ InputStreamReader isReader = null;
+ BufferedReader buffReader = null;
+ StringBuilder sb = new StringBuilder();
+ URL url = currentObj.getClass().getResource(
+ "/templates/BioJSTemplate.txt");
+ if (url != null)
+ {
+ try
+ {
+ isReader = new InputStreamReader(url.openStream());
+ buffReader = new BufferedReader(isReader);
+ String line;
+ String lineSeparator = System.getProperty("line.separator");
+ while ((line = buffReader.readLine()) != null)
+ {
+ sb.append(line).append(lineSeparator);
+ }
+
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ } finally
+ {
+ if (isReader != null)
+ {
+ isReader.close();
+ }
+
+ if (buffReader != null)
+ {
+ buffReader.close();
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+
+}
package jalview.io;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.gui.AlignViewport;
import jalview.gui.Desktop;
import jalview.gui.Jalview2XML;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.MessageManager;
+import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
-import jalview.util.MessageManager;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public AlignFrame LoadFileWaitTillLoaded(FileParse source, String format)
{
this.source = source;
+
file = source.getInFile();
protocol = source.type;
this.format = format;
if ((al != null) && (al.getHeight() > 0))
{
+ for (SequenceI sq : al.getSequences())
+ {
+ while (sq.getDatasetSequence() != null)
+ {
+ sq = sq.getDatasetSequence();
+ }
+ if (sq.getPDBId() != null)
+ {
+ for (PDBEntry pdbe : (List<PDBEntry>) sq.getPDBId())
+ {
+ StructureSelectionManager.getStructureSelectionManager(
+ Desktop.instance).registerPDBEntry(pdbe);
+ }
+ }
+ }
if (viewport != null)
{
// TODO: create undo object for this JAL-1101
}
viewport.firePropertyChange("alignment", null, viewport
.getAlignment().getSequences());
-
}
else
{
{ title }));
if (!protocol.equals(AppletFormatAdapter.PASTE))
+ {
alignFrame.setFileName(file, format);
+ }
+ if (source instanceof HtmlFile)
+ {
+ ((HtmlFile) source).LoadAlignmentFeatures(alignFrame);
+
+ }
if (raiseGUI)
{
// add the window to the GUI
javax.swing.JOptionPane
.showInternalMessageDialog(
Desktop.desktop,
- "Out of memory loading file "
- + file
- + "!!"
- + "\nSee help files for increasing Java Virtual Machine memory.",
- "Out of memory",
+ MessageManager.formatMessage("warn.out_of_memory_loading_file", new String[]{file}),
+ MessageManager.getString("label.out_of_memory"),
javax.swing.JOptionPane.WARNING_MESSAGE);
}
});
*/
package jalview.io;
+import jalview.util.MessageManager;
+
import java.io.*;
import java.net.*;
import java.util.zip.GZIPInputStream;
public void setNewlineString(String nl)
{
- newline = nl;
+ newline = nl;
}
public String getNewlineString()
{
if (from == null)
{
- throw new Error(
- "Implementation error. Null FileParse in copy constructor");
+ throw new Error(MessageManager.getString("error.implementation_error_null_fileparse"));
}
if (from == this)
return;
{
if (e != null)
{
- throw new IOException("Failed to resolve GZIP stream", e);
+ throw new IOException(MessageManager.getString("exception.failed_to_resolve_gzip_stream"), e);
}
throw q;
}
{
if (checkFileSource(suffixLess))
{
- throw new IOException("Problem opening " + inFile
- + " (also tried " + suffixLess + ") : " + errormessage);
+ throw new IOException(MessageManager.formatMessage("exception.problem_opening_file_also_tried", new String[]{inFile.getName(),suffixLess,errormessage}));
}
}
else
{
- throw new IOException("Problem opening " + inFile + " : "
- + errormessage);
+ throw new IOException(MessageManager.formatMessage("exception.problem_opening_file", new String[]{inFile.getName(),errormessage}));
}
}
}
if (dataIn == null || error)
{
// pass up the reason why we have no source to read from
- throw new IOException("Failed to read data from source:\n"
- + errormessage);
+ throw new IOException(MessageManager.formatMessage("exception.failed_to_read_data_from_source", new String[]{errormessage}));
}
error = false;
dataIn.mark(READAHEAD_LIMIT);
}
else
{
- throw new IOException("Unitialised Source Stream");
+ throw new IOException(MessageManager.getString("exception.no_init_source_stream"));
}
}
{
if (!error)
return dataIn.readLine();
- throw new IOException("Invalid Source Stream:" + errormessage);
+ throw new IOException(MessageManager.formatMessage("exception.invalid_source_stream", new String[]{errormessage}));
}
public boolean isValid()
}
else
{
- throw new IOException(
- "Implementation Error: Reset called for invalid source.");
+ throw new IOException(MessageManager.getString("error.implementation_error_reset_called_for_invalid_source"));
}
}
*/
package jalview.io;
-import jalview.datamodel.*;
+import jalview.api.AlignViewportI;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
/**
* Additional formatting methods used by the application in a number of places.
public boolean getCacheSuffixDefault(String format)
{
if (isValidFormat(format))
+ {
return jalview.bin.Cache.getDefault(format.toUpperCase()
+ "_JVSUFFIX", true);
+ }
return false;
}
return this.formatSequences(format, alignment, suffix);
}
+ public Alignment readFile(String inFile, String type, String format)
+ throws java.io.IOException
+ {
+ Alignment al;
+ if (format.equals("HTML"))
+ {
+ afile = new HtmlFile(inFile, type);
+ al = new Alignment(afile.getSeqsAsArray());
+ afile.addAnnotations(al);
+ }
+ else
+ {
+ al = super.readFile(inFile, type, format);
+ }
+
+ return al;
+ }
+
+ public AlignmentI readFromFile(FileParse source, String format)
+ throws java.io.IOException
+ {
+ Alignment al;
+ if (format.equals("HTML"))
+ {
+ afile = new HtmlFile(source);
+ al = new Alignment(afile.getSeqsAsArray());
+ afile.addAnnotations(al);
+ }
+ else
+ {
+ al = (Alignment) super.readFromFile(source, format);
+ }
+ return al;
+ }
+
/**
* validate format is valid for IO in Application. This is basically the
* AppletFormatAdapter.isValidFormat call with additional checks for
}
return AppletFormatAdapter.isValidFormat(format, forwriting);
}
+
+ /**
+ * Create a flat file representation of a given view or selected region of a view
+ * @param format
+ * @param av
+ * @return String containing flat file
+ */
+ public String formatSequences(String format, AlignViewportI av, boolean selectedOnly)
+ {
+ return formatSequences(format, getCacheSuffixDefault(format), av, selectedOnly);
+ }
+
}
{ "HTML files" }, "HTML files");
chooser.setFileView(new JalviewFileView());
- chooser.setDialogTitle("Save as HTML");
+ chooser.setDialogTitle(MessageManager.getString("label.save_as_html"));
chooser.setToolTipText(MessageManager.getString("action.save"));
int value = chooser.showSaveDialog(null);
--- /dev/null
+package jalview.io;
+
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.gui.AlignFrame;
+import jalview.json.binding.v1.BioJsAlignmentPojo.JalviewBioJsColorSchemeMapper;
+import jalview.schemes.ColourSchemeI;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+public class HtmlFile extends AlignFile
+{
+ // public static final String FILE_EXT = "html";
+ //
+ // public static final String FILE_DESC = "HTML";
+
+ private ColourSchemeI cs;
+
+ public HtmlFile()
+ {
+ super();
+ }
+
+ public HtmlFile(FileParse source) throws IOException
+ {
+ super(source);
+ }
+
+ public HtmlFile(String inFile, String type) throws IOException
+ {
+ super(inFile, type);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void parse() throws IOException
+ {
+ try
+ {
+ StringBuilder htmlData = new StringBuilder();
+ String currentLine;
+ while ((currentLine = nextLine()) != null)
+ {
+ htmlData.append(currentLine);
+ }
+
+ Document doc = Jsoup.parse(htmlData.toString());
+ Element content = doc.getElementById("seqData");
+
+ String alignmentJsonString = content.val();
+ JSONParser jsonParser = new JSONParser();
+ JSONObject alignmentJsonObj = (JSONObject) jsonParser
+ .parse(alignmentJsonString);
+ JSONArray seqJsonArray = (JSONArray) alignmentJsonObj.get("seqs");
+ String bioJsColourScheme = (String) alignmentJsonObj
+ .get("globalColorScheme");
+ cs = getJalviewColorScheme(bioJsColourScheme);
+
+ for (Iterator<JSONObject> sequenceIter = seqJsonArray.iterator(); sequenceIter
+ .hasNext();)
+ {
+ JSONObject sequence = sequenceIter.next();
+ String sequcenceString = sequence.get("seq").toString();
+ Sequence seq = new Sequence(sequence.get("name").toString(),
+ sequcenceString, 0, sequcenceString.length());
+
+ JSONArray jsonSeqArray = (JSONArray) sequence.get("features");
+ SequenceFeature[] retrievedSeqFeatures = getJalviewSequenceFeatures(jsonSeqArray);
+ if (retrievedSeqFeatures != null)
+ {
+ seq.setSequenceFeatures(retrievedSeqFeatures);
+ }
+ seqs.add(seq);
+
+ }
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public SequenceFeature[] getJalviewSequenceFeatures(
+ JSONArray jsonSeqFeatures)
+ {
+ SequenceFeature[] seqFeatures = null;
+ int count = 0;
+ if (jsonSeqFeatures != null)
+ {
+ seqFeatures = new SequenceFeature[jsonSeqFeatures.size()];
+ for (Iterator<JSONObject> seqFeatureItr = jsonSeqFeatures.iterator(); seqFeatureItr
+ .hasNext();)
+ {
+
+ SequenceFeature sequenceFeature = new SequenceFeature();
+ JSONObject jsonFeature = seqFeatureItr.next();
+ Long begin = (Long) jsonFeature.get("xStart");
+ Long end = (Long) jsonFeature.get("xEnd");
+ String type = (String) jsonFeature.get("text");
+
+ String color = (String) jsonFeature.get("fillColor");
+
+ sequenceFeature.setBegin(begin.intValue());
+ sequenceFeature.setEnd(end.intValue());
+ sequenceFeature.setType(type);
+ seqFeatures[count++] = sequenceFeature;
+ }
+ }
+ return seqFeatures;
+ }
+
+ public void LoadAlignmentFeatures(AlignFrame af)
+ {
+
+ af.setShowSeqFeatures(true);
+ af.changeColour(cs);
+ af.setMenusForViewport();
+ }
+
+ private ColourSchemeI getJalviewColorScheme(String bioJsColourSchemeName)
+ {
+ ColourSchemeI jalviewColor = null;
+ for (JalviewBioJsColorSchemeMapper cs : JalviewBioJsColorSchemeMapper
+ .values())
+ {
+ if (cs.getBioJsName().equals(bioJsColourSchemeName))
+ {
+ jalviewColor = cs.getJvColourScheme();
+ break;
+ }
+ }
+ return jalviewColor;
+ }
+
+ @Override
+ public String print()
+ {
+ throw new UnsupportedOperationException(
+ "Print method of HtmlFile not yet supported!");
+ }
+
+}
/*
* Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
* Copyright (C) 2014 The Jalview Authors
- *
+ *
* This file is part of Jalview.
- *
+ *
* Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
+ * 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.
- *
- * Jalview 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
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
package jalview.io;
-import java.io.*;
+import java.io.IOException;
/**
* DOCUMENT ME!
- *
+ *
* @author $author$
* @version $Revision$
*/
{
/**
* Identify a datasource's file content.
- *
+ *
* @note Do not use this method for stream sources - create a FileParse object
* instead.
- *
+ *
* @param file
* DOCUMENT ME!
* @param protocol
emessage = e.getMessage();
}
if (parser != null)
+ {
return parser.errormessage;
+ }
return emessage;
}
/**
* Identify contents of source, closing it or resetting source to start
* afterwards.
- *
+ *
* @param source
* @param closeSource
* @return filetype string
break;
}
+ if (data.matches("<(\"[^\"]*\"|'[^']*'|[^'\">])*>"))
+ {
+ reply = "HTML";
+ break;
+ }
if ((data.indexOf("<") > -1))
{
else
{
reply = "FASTA"; // possibly a bad choice - may be recognised as
- // PIR
+ // PIR
}
// otherwise can still possibly be a PIR file
}
reply = "PDB";
break;
}
+ else if (data.matches("\\s*\\d+\\s+\\d+\\s*"))
+ {
+ reply = PhylipFile.FILE_DESC;
+ break;
+ }
+
+
/*
* // TODO comment out SimpleBLAST identification for Jalview 2.4.1 else
* if (!lineswereskipped && data.indexOf("BLAST")<4) { reply =
* "SimpleBLAST"; break;
- *
+ *
* } // end comments for Jalview 2.4.1
*/
else if (!lineswereskipped && data.charAt(0) != '*'
&& data.charAt(0) != ' '
&& data.indexOf(":") < data.indexOf(",")) // &&
- // data.indexOf(",")<data.indexOf(",",
- // data.indexOf(",")))
+ // data.indexOf(",")<data.indexOf(",",
+ // data.indexOf(",")))
{
// file looks like a concise JNet file
reply = "JnetFile";
if (length == 0)
{
System.err
- .println("File Identification failed! - Empty file was read.");
+ .println("File Identification failed! - Empty file was read.");
return "EMPTY DATA FILE";
}
return reply;
public static void main(String[] args)
{
+
for (int i = 0; args != null && i < args.length; i++)
{
IdentifyFile ider = new IdentifyFile();
import java.util.*;
import jalview.datamodel.*;
+import jalview.util.MessageManager;
/**
* Parser for the JPred/JNet concise format. This is a series of CSV lines, each
if (maxLength != seq_entries.elementAt(i).toString().length())
{
- throw new IOException("JPredConcise: Entry ("
- + ids.elementAt(i).toString()
- + ") has an unexpected number of columns");
+ throw new IOException(MessageManager.formatMessage("exception.jpredconcide_entry_has_unexpected_number_of_columns", new String[]{ids.elementAt(i).toString()}));
}
if ((newSeq.getName().startsWith("QUERY") || newSeq.getName()
} catch (Exception e)
{
tal = null;
- IOException ex = new IOException(
- "Couldn't parse concise annotation for prediction profile.\n"
- + e);
+ IOException ex = new IOException(MessageManager.formatMessage("exception.couldnt_parse_concise_annotation_for_prediction", new String[]{e.getMessage()}));
e.printStackTrace(); // java 1.1 does not have :
// ex.setStackTrace(e.getStackTrace());
throw ex;
/*
* Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
* Copyright (C) 2014 The Jalview Authors
- *
+ *
* This file is part of Jalview.
- *
+ *
* Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
+ * 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.
- *
- * Jalview 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
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
import jalview.util.MessageManager;
-import java.io.*;
-import java.util.*;
-
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.HeadlessException;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.JFileChooser;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
/**
* Enhanced file chooser dialog box.
- *
+ *
* NOTE: bug on Windows systems when filechooser opened on directory to view
* files with colons in title.
- *
+ *
* @author AMW
- *
+ *
*/
public class JalviewFileChooser extends JFileChooser
{
setAccessory(new RecentlyOpened());
}
+ @Override
public void setFileFilter(javax.swing.filechooser.FileFilter filter)
{
super.setFileFilter(filter);
EventQueue.invokeLater(new Thread()
{
+ @Override
public void run()
{
String currentName = ui.getFileName();
{
format = "PFAM";
}
+ else if (format.toUpperCase().startsWith(PhylipFile.FILE_DESC))
+ {
+ format = PhylipFile.FILE_DESC;
+ }
return format;
}
+ @Override
public int showSaveDialog(Component parent) throws HeadlessException
{
this.setAccessory(null);
&& getSelectedFile().exists())
{
int confirm = JOptionPane.showConfirmDialog(parent,
- "Overwrite existing file?", "File exists",
+ MessageManager.getString("label.overwrite_existing_file"), MessageManager.getString("label.file_already_exists"),
JOptionPane.YES_NO_OPTION);
if (confirm != JOptionPane.YES_OPTION)
list.addMouseListener(new MouseAdapter()
{
+ @Override
public void mousePressed(MouseEvent evt)
{
recentListSelectionChanged(list.getSelectedValue());
}
});
- this.setBorder(new javax.swing.border.TitledBorder("Recently Opened"));
+ this.setBorder(new javax.swing.border.TitledBorder(MessageManager.getString("label.recently_opened")));
final JScrollPane scroller = new JScrollPane(list);
scroller.setPreferredSize(new Dimension(130, 200));
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
+ @Override
public void run()
{
scroller.getHorizontalScrollBar().setValue(
package jalview.io;
import jalview.datamodel.*;
+import jalview.util.MessageManager;
public class JnetAnnotationMaker
{
if ((delMap != null && delMap.length > width)
|| (delMap == null && gapmap.length != width))
{
- throw (new Exception("Number of residues in "
- + (delMap == null ? "" : " mapped ")
- + "supposed query sequence ('"
- + al.getSequenceAt(firstSeq).getName() + "'\n"
- + al.getSequenceAt(firstSeq).getSequenceAsString()
- + ")\ndiffer from number of prediction sites in prediction ("
- + width + ")"));
+ throw (new Exception(MessageManager.formatMessage("exception.number_of_residues_in_query_sequence_differ_from_prediction", new String[]{
+ (delMap == null ? "" : MessageManager.getString("label.mapped")),
+ al.getSequenceAt(firstSeq).getName(),
+ al.getSequenceAt(firstSeq).getSequenceAsString(),
+ Integer.valueOf(width).toString()
+ })));
}
AlignmentAnnotation annot;
import java.util.StringTokenizer;
import jalview.datamodel.*;
+import jalview.util.MessageManager;
/**
* Parse a new hanpshire style tree Caveats: NHX files are NOT supported and the
if (Error != null)
{
- throw (new IOException("NewickFile: " + Error + "\n"));
+ throw (new IOException(MessageManager.formatMessage("exception.newfile", new String[]{Error.toString()})));
}
if (root == null)
{
- throw (new IOException("NewickFile: No Tree read in\n"));
+ throw (new IOException(MessageManager.formatMessage("exception.newfile", new String[]{MessageManager.getString("label.no_tree_read_in")})));
}
// THe next line is failing for topali trees - not sure why yet. if
// (root.right()!=null && root.isDummy())
if (noSeqs < 1)
{
- throw new IOException("No sequences found (PFAM input)");
+ throw new IOException(MessageManager.getString("exception.pfam_no_sequences_found"));
}
for (i = 0; i < headers.size(); i++)
--- /dev/null
+/**
+ *
+ */
+package jalview.io;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import java.io.IOException;
+
+/**
+ * <p>
+ * Parser and exporter for PHYLIP file format, as defined <a
+ * href="http://evolution.genetics.washington.edu/phylip/doc/main.html">in the
+ * documentation</a>. The parser imports PHYLIP files in both sequential and
+ * interleaved format, and (currently) exports in interleaved format (using 60
+ * characters per matrix for the sequence).
+ * <p>
+ *
+ * <p>
+ * The following assumptions have been made for input
+ * <ul>
+ * <li>Sequences are expressed as letters, not real numbers with decimal points
+ * separated by blanks (which is a valid option according to the specification)</li>
+ * </ul>
+ *
+ * The following assumptions have been made for output
+ * <ul>
+ * <li>Interleaved format is used, with each matrix consisting of 60 characters;
+ * </li>
+ * <li>a blank line is added between each matrix;</li>
+ * <li>no spacing is added between the sequence characters.</li>
+ * </ul>
+ *
+ *
+ * </p>
+ *
+ * @author David Corsar
+ *
+ *
+ */
+public class PhylipFile extends AlignFile
+{
+
+ // Define file extension and description to save repeating it elsewhere
+ public static final String FILE_EXT = "phy";
+
+ public static final String FILE_DESC = "PHYLIP";
+
+ /**
+ *
+ * @see {@link AlignFile#AlignFile()}
+ */
+ public PhylipFile()
+ {
+ super();
+ }
+
+ /**
+ *
+ * @param source
+ * @throws IOException
+ */
+ public PhylipFile(FileParse source) throws IOException
+ {
+ super(source);
+ }
+
+ /**
+ * @param inFile
+ * @param type
+ * @throws IOException
+ * @see {@link AlignFile#AlignFile(FileParse)}
+ */
+ public PhylipFile(String inFile, String type) throws IOException
+ {
+ super(inFile, type);
+ }
+
+ /**
+ * Parses the input source
+ *
+ * @see {@link AlignFile#parse()}
+ */
+ @Override
+ public void parse() throws IOException
+ {
+ try
+ {
+ // First line should contain number of species and number of
+ // characters, separated by blanks
+ String line = nextLine();
+ String[] lineElements = line.trim().split("\\s+");
+ if (lineElements.length < 2)
+ {
+ throw new IOException(
+ "First line must contain the number of specifies and number of characters");
+ }
+
+ int numberSpecies = Integer.parseInt(lineElements[0]), numberCharacters = Integer
+ .parseInt(lineElements[1]);
+
+ if (numberSpecies <= 0)
+ {
+ // there are no sequences in this file so exit a nothing to
+ // parse
+ return;
+ }
+
+ SequenceI[] sequenceElements = new Sequence[numberSpecies];
+ StringBuffer[] sequences = new StringBuffer[numberSpecies];
+
+ // if file is in sequential format there is only one data matrix,
+ // else there are multiple
+
+ // read the first data matrix
+ for (int i = 0; i < numberSpecies; i++)
+ {
+ line = nextLine();
+ // lines start with the name - a maximum of 10 characters
+ // if less, then padded out or terminated with a tab
+ String potentialName = line.substring(0, 10);
+ int tabIndex = potentialName.indexOf('\t');
+ if (tabIndex == -1)
+ {
+ sequenceElements[i] = parseId(validateName(potentialName));
+ sequences[i] = new StringBuffer(
+ removeWhitespace(line.substring(10)));
+ }
+ else
+ {
+ sequenceElements[i] = parseId(validateName(potentialName
+ .substring(0, tabIndex)));
+ sequences[i] = new StringBuffer(
+ removeWhitespace(line.substring(tabIndex)));
+ }
+ }
+
+ // determine if interleaved
+ if ((sequences[0]).length() != numberCharacters)
+ {
+ // interleaved file, so have to read the remainder
+ int i = 0;
+ for (line = nextLine(); line != null; line = nextLine())
+ {
+ // ignore blank lines, as defined by the specification
+ if (line.length() > 0)
+ {
+ sequences[i++].append(removeWhitespace(line));
+ }
+ // reached end of matrix, so get ready for the next one
+ if (i == sequences.length)
+ {
+ i = 0;
+ }
+ }
+ }
+
+ // file parsed completely, now store sequences
+ for (int i = 0; i < numberSpecies; i++)
+ {
+ // first check sequence is the expected length
+ if (sequences[i].length() != numberCharacters)
+ {
+ throw new IOException(sequenceElements[i].getName()
+ + " sequence is incorrect length - should be "
+ + numberCharacters + " but is " + sequences[i].length());
+ }
+ sequenceElements[i].setSequence(sequences[i].toString());
+ seqs.add(sequenceElements[i]);
+ }
+
+ // create an alignment based on the sequences
+ Alignment a = new Alignment(sequenceElements);
+ // add annotations - although comments say addAnnotations
+ // is used by AppletFormatAdapter, it doesn't say other
+ // classes should/can not use it
+ addAnnotations(a);
+
+ } catch (IOException e)
+ {
+ System.err.println("Exception parsing PHYLIP file " + e);
+ e.printStackTrace(System.err);
+ throw e;
+ }
+
+ }
+
+ /**
+ * Removes any whitespace from txt, used to strip and spaces added to
+ * sequences to improve human readability
+ *
+ * @param txt
+ * @return
+ */
+ private String removeWhitespace(String txt)
+ {
+ return txt.replaceAll("\\s*", "");
+ }
+
+ /**
+ * According to the specification, the name cannot have parentheses, square
+ * brackets, colon, semicolon, comma
+ *
+ * @param name
+ * @return
+ * @throws IOException
+ */
+ private String validateName(String name) throws IOException
+ {
+ char[] invalidCharacters = new char[]
+ { '(', ')', '[', ']', ':', ';', ',' };
+ for (char c : invalidCharacters)
+ {
+ if (name.indexOf(c) > -1)
+ {
+ throw new IOException("Species name contains illegal character "
+ + c);
+ }
+ }
+ return name;
+ }
+
+ /**
+ * <p>
+ * Prints the seqs in interleaved format, with each matrix consisting of 60
+ * characters; a blank line is added between each matrix; no spacing is added
+ * between the sequence characters.
+ * </p>
+ *
+ *
+ * @see {@link AlignFile#print()}
+ */
+ @Override
+ public String print()
+ {
+
+ StringBuffer sb = new StringBuffer(Integer.toString(seqs.size()));
+ sb.append(" ");
+ // if there are no sequences, then define the number of characters as 0
+ sb.append(
+ (seqs.size() > 0) ? Integer
+ .toString(seqs.get(0).getSequence().length) : "0")
+ .append(newline);
+
+ // Due to how IO is handled, there doesn't appear to be a way to store
+ // if the original file was sequential or interleaved; if there is, then
+ // use that to set the value of the following variable
+ boolean sequential = false;
+
+ // maximum number of columns for each row of interleaved format
+ int numInterleavedColumns = 60;
+
+ int sequenceLength = 0;
+ for (SequenceI s : seqs)
+ {
+
+ // ensure name is only 10 characters
+ String name = s.getName();
+ if (name.length() > 10)
+ {
+ name = name.substring(0, 10);
+ }
+ else
+ {
+ // add padding 10 characters
+ name = String.format("%1$-" + 10 + "s", s.getName());
+ }
+ sb.append(name);
+
+ // sequential has the entire sequence following the name
+ if (sequential)
+ {
+ sb.append(s.getSequence());
+ }
+ else
+ {
+ // Jalview ensures all sequences are of same length so no need
+ // to keep track of min/max length
+ sequenceLength = s.getSequence().length;
+ // interleaved breaks the sequence into chunks for
+ // interleavedColumns characters
+ sb.append(s.getSequence(0,
+ Math.min(numInterleavedColumns, sequenceLength)));
+ }
+ sb.append(newline);
+ }
+
+ // add the remaining matrixes if interleaved and there is something to
+ // add
+ if (!sequential && sequenceLength > numInterleavedColumns)
+ {
+ // determine number of remaining matrixes
+ int numMatrics = sequenceLength / numInterleavedColumns;
+ if ((sequenceLength % numInterleavedColumns) > 0)
+ {
+ numMatrics++;
+ }
+
+ // start i = 1 as first matrix has already been printed
+ for (int i = 1; i < numMatrics; i++)
+ {
+ // add blank line to separate this matrix from previous
+ sb.append(newline);
+ int start = i * numInterleavedColumns;
+ for (SequenceI s : seqs)
+ {
+ sb.append(
+ s.getSequence(start, Math.min(start
+ + numInterleavedColumns, sequenceLength)))
+ .append(newline);
+ }
+ }
+
+ }
+
+ return sb.toString();
+ }
+}
\ No newline at end of file
import jalview.datamodel.Annotation;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
_parse();
} catch (ExceptionPermissionDenied pdx)
{
- errormessage = "Couldn't access datasource (" + pdx.getMessage()
- + ")";
+ errormessage = MessageManager.formatMessage("exception.rnaml_couldnt_access_datasource", new String[]{pdx.getMessage()});
throw new IOException(pdx);
} catch (ExceptionLoadingFailed lf)
{
- errormessage = "Couldn't process data as RNAML file ("
- + lf.getMessage() + ")";
+ errormessage = MessageManager.formatMessage("exception.ranml_couldnt_process_data", new String[]{lf.getMessage()});
throw new IOException(lf);
} catch (ExceptionFileFormatOrSyntax iff)
{
- errormessage = "Invalid RNAML file (" + iff.getMessage() + ")";
+ errormessage = MessageManager.formatMessage("exception.ranml_invalid_file", new String[]{iff.getMessage()});
throw new IOException(iff);
} catch (Exception x)
{
error = true;
- errormessage = "Problem parsing data as RNAML (" + x.getMessage()
- + ")";
- throw new IOException("Couldn't parse the datasource as RNAML", x);
+ errormessage = MessageManager.formatMessage("exception.ranml_problem_parsing_data", new String[]{x.getMessage()});
+ throw new IOException(errormessage , x);
}
}
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.util.Format;
+import jalview.util.MessageManager;
import java.io.BufferedReader;
import java.io.FileReader;
r = new Regex("# STOCKHOLM ([\\d\\.]+)");
if (!r.search(nextLine()))
{
- throw new IOException(
- "This file is not in valid STOCKHOLM format: First line does not contain '# STOCKHOLM'");
+ throw new IOException(MessageManager.getString("exception.stockholm_invalid_format"));
}
else
{
if (!x.search(line))
{
// logger.error("Could not parse sequence line: " + line);
- throw new IOException("Could not parse sequence line: " + line);
+ throw new IOException(MessageManager.formatMessage("exception.couldnt_parse_sequence_line", new String[]{line}));
}
String ns = (String) seqs.get(x.stringMatched(1));
if (ns == null)
}
else
{
- throw new IOException("Error parsing " + line);
+ throw new IOException(MessageManager.formatMessage("exception.error_parsing_line", new String[]{line}));
}
}
else if (annType.equals("GC"))
}
else
{
- throw new IOException("Unknown annotation detected: " + annType
- + " " + annContent);
+ throw new IOException(MessageManager.formatMessage("exception.unknown_annotation_detected", new String[]{annType,annContent}));
}
}
}
import jalview.io.vamsas.DatastoreItem;
import jalview.io.vamsas.DatastoreRegistry;
import jalview.io.vamsas.Rangetype;
+import jalview.util.MessageManager;
+
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
{
Cache.log.debug(
"Warning? Overwriting existing vamsas id binding for "
- + vobj.getVorbaId(), new Exception(
- "Overwriting vamsas id binding."));
+ + vobj.getVorbaId(), new Exception(MessageManager.getString("exception.overwriting_vamsas_id_binding")));
}
else if (jv2vobj.containsKey(jvobj)
&& !((VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId()))
if (vbound.getV_parent() != null
&& dataset != vbound.getV_parent())
{
- throw new Error(
- "IMPLEMENTATION ERROR: Cannot map an alignment of sequences from different datasets into a single alignment in the vamsas document.");
+ throw new Error(MessageManager.getString("error.implementation_error_cannot_map_alignment_sequences"));
// This occurs because the dataset for the alignment we are
// trying to
}
{
// NOTE: this happens if user deletes object in one session then updates
// from another client
- throw new Error(
- "IMPLEMENTATION ERROR: old jalview object is not bound ! ("
- + oldjvobject + ")");
+ throw new Error(MessageManager.formatMessage("error.implementation_error_old_jalview_object_not_bound", new String[]{oldjvobject.toString()}));
}
if (newjvobject != null)
{
int[] se = null;
if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
{
- throw new Error(
- "Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
+ throw new Error(MessageManager.getString("error.invalid_vamsas_rangetype_cannot_resolve_lists"));
}
if (dseta.getSegCount() > 0)
{
int[] se = null;
if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
{
- throw new Error(
- "Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
+ throw new Error(MessageManager.getString("error.invalid_vamsas_rangetype_cannot_resolve_lists"));
}
if (dseta.getSegCount() > 0)
{
}
} catch (Exception e)
{
- throw new Exception("Couldn't store sequence mappings for " + title,
- e);
+ throw new Exception(MessageManager.formatMessage("exception.couldnt_store_sequence_mappings", new String[]{title}),e);
}
}
imageIndex++;
imageIndex %= 9;
output.setFrameIcon(imageIcon[imageIndex]);
- output.setTitle("BLASTing for unidentified sequences - "
- + jobsRunning + " jobs running.");
+ output.setTitle(MessageManager.formatMessage("label.blasting_for_unidentified_sequence_jobs_running", new String[]{Integer.valueOf(jobsRunning).toString()}));
} catch (Exception ex)
{
}
import jalview.bin.Cache;
import jalview.io.VamsasAppDatastore;
+import jalview.util.MessageManager;
import java.util.Enumeration;
import java.util.Hashtable;
{
Cache.log.debug(
"Warning? Overwriting existing vamsas id binding for "
- + vobj.getVorbaId(), new Exception(
- "Overwriting vamsas id binding."));
+ + vobj.getVorbaId(), new Exception(MessageManager.getString("exception.overwriting_vamsas_id_binding")));
}
else if (jv2vobj.containsKey(jvobj)
&& !((VorbaId) jv2vobj.get(jvobj)).equals(vobj.getVorbaId()))
{
Cache.log.debug(
"Warning? Overwriting existing jalview object binding for "
- + jvobj, new Exception(
- "Overwriting jalview object binding."));
+ + jvobj, new Exception(MessageManager.getString("exception.overwriting_jalview_id_binding")));
}
/*
* Cache.log.error("Attempt to make conflicting object binding! "+vobj+" id "
Object vobject = jv2vobj.remove(oldjvobject);
if (vobject == null)
{
- throw new Error(
- "IMPLEMENTATION ERROR: old jalview object is not bound ! ("
- + oldjvobject + ")");
+ throw new Error(MessageManager.formatMessage("error.implementation_error_old_jalview_object_not_bound", new String[]{oldjvobject.toString()}));
}
if (newjvobject != null)
{
tojalview = true;
if (jvobj != null && !(boundType.isAssignableFrom(jvobj.getClass())))
{
- throw new Error("Implementation Error: Vamsas Document Class "
- + vobj.getClass() + " should bind to a " + boundType
- + " (found a " + jvobj.getClass() + ")");
+ throw new Error(MessageManager.formatMessage("error.implementation_error_vamsas_doc_class_should_bind_to_type"
+ , new String[]{vobj.getClass().toString(),boundType.toString(),jvobj.getClass().toString()}));
}
dsReg.registerDsObj(this);
}
vobj = getjv2vObj(jvobj);
if (vobj != null && !(boundToType.isAssignableFrom(vobj.getClass())))
{
- throw new Error("Implementation Error: Jalview Class "
- + jvobj2.getClass() + " should bind to a " + boundToType
- + " (found a " + vobj.getClass() + ")");
+ throw new Error(MessageManager.formatMessage("error.implementation_error_vamsas_doc_class_should_bind_to_type"
+ , new String[]{jvobj2.getClass().toString(),boundToType.toString(),vobj.getClass().toString()}));
}
dsReg.registerDsObj(this);
}
import uk.ac.vamsas.objects.core.RangeType;
import uk.ac.vamsas.objects.core.Seg;
import jalview.io.VamsasAppDatastore;
+import jalview.util.MessageManager;
/**
* Enhances DatastoreItem objects with additional functions to do with RangeType
int[] se = null;
if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
{
- throw new Error(
- "Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
+ throw new Error(MessageManager.getString("error.invalid_vamsas_rangetype_cannot_resolve_lists"));
}
if (dseta.getSegCount() > 0)
{
int[] se = null;
if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)
{
- throw new Error(
- "Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
+ throw new Error(MessageManager.getString("error.invalid_vamsas_rangetype_cannot_resolve_lists"));
}
if (dseta.getSegCount() > 0)
{
int[] se = null;
if (range.getSegCount() > 0 && range.getPosCount() > 0)
{
- throw new Error(
- "Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");
+ throw new Error(MessageManager.getString("error.invalid_vamsas_rangetype_cannot_resolve_lists"));
}
if (range.getSegCount() > 0)
{
{
if (ml == null)
{
- throw new Error(
- "Implementation error. MapList is null for initMapType.");
+ throw new Error(MessageManager.getString("error.implementation_error_maplist_is_null"));
}
maprange.setLocal(new Local());
maprange.setMapped(new Mapped());
*/
package jalview.jbgui;
+import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
+import jalview.bin.Cache;
+import jalview.gui.JvSwingUtils;
+import jalview.gui.Preferences;
import jalview.schemes.ColourSchemeProperty;
import jalview.util.MessageManager;
protected JMenu viewMenu = new JMenu();
+ protected JMenu annotationsMenu = new JMenu();
+
protected JMenu colourMenu = new JMenu();
protected JMenu calculateMenu = new JMenu();
JMenuItem createPNG = new JMenuItem();
+ JMenuItem createBioJS = new JMenuItem();
+
+ JMenuItem createSVG = new JMenuItem();
+
protected JMenuItem font = new JMenuItem();
public JCheckBoxMenuItem seqLimits = new JCheckBoxMenuItem();
JMenuItem showAllhidden = new JMenuItem();
+ protected JMenuItem showAllSeqAnnotations = new JMenuItem();
+
+ protected JMenuItem hideAllSeqAnnotations = new JMenuItem();
+
+ protected JMenuItem showAllAlAnnotations = new JMenuItem();
+
+ protected JMenuItem hideAllAlAnnotations = new JMenuItem();
+
+ protected JCheckBoxMenuItem sortAnnBySequence = new JCheckBoxMenuItem();
+
+ protected JCheckBoxMenuItem sortAnnByLabel = new JCheckBoxMenuItem();
+
protected JCheckBoxMenuItem hiddenMarkers = new JCheckBoxMenuItem();
JMenuItem invertColSel = new JMenuItem();
protected JCheckBoxMenuItem applyAutoAnnotationSettings = new JCheckBoxMenuItem();
+ protected JRadioButtonMenuItem showAutoFirst = new JRadioButtonMenuItem();
+
+ protected JRadioButtonMenuItem showAutoLast = new JRadioButtonMenuItem();
+
private JMenuItem grpsFromSelection = new JMenuItem();
+ private SequenceAnnotationOrder annotationSortOrder;
+
+ private boolean showAutoCalculatedAbove = false;
+
public GAlignFrame()
{
try
item.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
outputText_actionPerformed(e);
}
} catch (Exception e)
{
+ System.err.println(e.toString());
}
if (!new jalview.util.Platform().isAMac())
radioItem.setName("USER_DEFINED");
radioItem.addMouseListener(new MouseAdapter()
{
+ @Override
public void mousePressed(MouseEvent evt)
{
if (evt.isControlDown()
{
radioItem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent evt)
{
userDefinedColour_actionPerformed(evt);
});
radioItem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent evt)
{
userDefinedColour_actionPerformed(evt);
| java.awt.event.KeyEvent.SHIFT_MASK, false));
saveAs.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
saveAs_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
closeMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
closeMenuItem_actionPerformed(false);
});
editMenu.setText(MessageManager.getString("action.edit"));
viewMenu.setText(MessageManager.getString("action.view"));
+ annotationsMenu.setText(MessageManager.getString("action.annotations"));
colourMenu.setText(MessageManager.getString("action.colour"));
calculateMenu.setText(MessageManager.getString("action.calculate"));
webService.setText(MessageManager.getString("action.web_service"));
selectAllSequenceMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
selectAllSequenceMenuItem_actionPerformed(e);
deselectAllSequenceMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
deselectAllSequenceMenuItem_actionPerformed(e);
invertSequenceMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
invertSequenceMenuItem_actionPerformed(e);
.getString("action.make_groups_selection"));
grpsFromSelection.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
makeGrpsFromSelection_actionPerformed(e);
remove2LeftMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
remove2LeftMenuItem_actionPerformed(e);
remove2RightMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
remove2RightMenuItem_actionPerformed(e);
removeGappedColumnMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
removeGappedColumnMenuItem_actionPerformed(e);
removeAllGapsMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
removeAllGapsMenuItem_actionPerformed(e);
justifyLeftMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
justifyLeftMenuItem_actionPerformed(e);
justifyRightMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
justifyRightMenuItem_actionPerformed(e);
viewBoxesMenuItem.setState(true);
viewBoxesMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
viewBoxesMenuItem_actionPerformed(e);
viewTextMenuItem.setState(true);
viewTextMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
viewTextMenuItem_actionPerformed(e);
showNonconservedMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showUnconservedMenuItem_actionPerformed(e);
sortPairwiseMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
sortPairwiseMenuItem_actionPerformed(e);
sortIDMenuItem.setText(MessageManager.getString("action.by_id"));
sortIDMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
sortIDMenuItem_actionPerformed(e);
sortLengthMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
sortLengthMenuItem_actionPerformed(e);
sortGroupMenuItem.setText(MessageManager.getString("action.by_group"));
sortGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
sortGroupMenuItem_actionPerformed(e);
}
});
removeRedundancyMenuItem.setText(MessageManager
- .getString("action.remove_redundancy"));
+ .getString("action.remove_redundancy").concat("..."));
removeRedundancyMenuItem.setAccelerator(javax.swing.KeyStroke
.getKeyStroke(java.awt.event.KeyEvent.VK_D, Toolkit
.getDefaultToolkit().getMenuShortcutKeyMask(), false));
removeRedundancyMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
removeRedundancyMenuItem_actionPerformed(e);
pairwiseAlignmentMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
pairwiseAlignmentMenuItem_actionPerformed(e);
.getString("label.principal_component_analysis"));
PCAMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
PCAMenuItem_actionPerformed(e);
averageDistanceTreeMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
averageDistanceTreeMenuItem_actionPerformed(e);
neighbourTreeMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
neighbourTreeMenuItem_actionPerformed(e);
clustalColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
clustalColour_actionPerformed(e);
zappoColour.setText(MessageManager.getString("label.zappo"));
zappoColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
zappoColour_actionPerformed(e);
taylorColour.setText(MessageManager.getString("label.taylor"));
taylorColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
taylorColour_actionPerformed(e);
hydrophobicityColour
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
hydrophobicityColour_actionPerformed(e);
helixColour.setText(MessageManager.getString("label.helix_propensity"));
helixColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
helixColour_actionPerformed(e);
.getString("label.strand_propensity"));
strandColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
strandColour_actionPerformed(e);
turnColour.setText(MessageManager.getString("label.turn_propensity"));
turnColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
turnColour_actionPerformed(e);
buriedColour.setText(MessageManager.getString("label.buried_index"));
buriedColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
buriedColour_actionPerformed(e);
.getString("action.user_defined"));
userDefinedColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
userDefinedColour_actionPerformed(e);
.setText(MessageManager.getString("label.percentage_identity"));
PIDColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
PIDColour_actionPerformed(e);
.setText(MessageManager.getString("label.blosum62_score"));
BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
BLOSUM62Colour_actionPerformed(e);
nucleotideColour.setText(MessageManager.getString("label.nucleotide"));
nucleotideColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
nucleotideColour_actionPerformed(e);
purinePyrimidineColour
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
purinePyrimidineColour_actionPerformed(e);
RNAInteractionColour
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
RNAInteractionColour_actionPerformed(e);
avDistanceTreeBlosumMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
avTreeBlosumMenuItem_actionPerformed(e);
njTreeBlosumMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
njTreeBlosumMenuItem_actionPerformed(e);
annotationPanelMenuItem.setActionCommand("");
annotationPanelMenuItem.setText(MessageManager
.getString("label.show_annotations"));
- annotationPanelMenuItem.setState(jalview.bin.Cache.getDefault(
- "SHOW_ANNOTATIONS", true));
- annotationPanelMenuItem
- .addActionListener(new java.awt.event.ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- annotationPanelMenuItem_actionPerformed(e);
- }
- });
+ annotationPanelMenuItem.setState(Cache.getDefault("SHOW_ANNOTATIONS",
+ true));
+ annotationPanelMenuItem.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ annotationPanelMenuItem_actionPerformed(e);
+ }
+ });
+ showAllAlAnnotations.setText(MessageManager
+ .getString("label.show_all_al_annotations"));
+ final boolean isAnnotationPanelShown = annotationPanelMenuItem
+ .getState();
+ showAllAlAnnotations.setEnabled(isAnnotationPanelShown);
+ showAllAlAnnotations.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ showAllAnnotations_actionPerformed(false, true);
+ }
+ });
+ hideAllAlAnnotations.setText(MessageManager
+ .getString("label.hide_all_al_annotations"));
+ hideAllAlAnnotations.setEnabled(isAnnotationPanelShown);
+ hideAllAlAnnotations.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ hideAllAnnotations_actionPerformed(false, true);
+ }
+ });
+ showAllSeqAnnotations.setText(MessageManager
+ .getString("label.show_all_seq_annotations"));
+ showAllSeqAnnotations.setEnabled(isAnnotationPanelShown);
+ showAllSeqAnnotations.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ showAllAnnotations_actionPerformed(true, false);
+ }
+ });
+ hideAllSeqAnnotations.setText(MessageManager
+ .getString("label.hide_all_seq_annotations"));
+ hideAllSeqAnnotations.setEnabled(isAnnotationPanelShown);
+ hideAllSeqAnnotations.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ hideAllAnnotations_actionPerformed(true, false);
+ }
+ });
+ SequenceAnnotationOrder sortAnnotationsBy = SequenceAnnotationOrder
+ .valueOf(Cache.getDefault(Preferences.SORT_ANNOTATIONS,
+ SequenceAnnotationOrder.NONE.name()));
+ sortAnnBySequence.setText(MessageManager
+ .getString("label.sort_annotations_by_sequence"));
+ sortAnnBySequence
+ .setSelected(sortAnnotationsBy == SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ sortAnnBySequence.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ boolean newState = sortAnnBySequence.getState();
+ sortAnnByLabel.setSelected(false);
+ setAnnotationSortOrder(newState ? SequenceAnnotationOrder.SEQUENCE_AND_LABEL
+ : SequenceAnnotationOrder.NONE);
+ sortAnnotations_actionPerformed();
+ }
+ });
+ sortAnnByLabel.setText(MessageManager
+ .getString("label.sort_annotations_by_label"));
+ sortAnnByLabel
+ .setSelected(sortAnnotationsBy == SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ sortAnnByLabel.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ boolean newState = sortAnnByLabel.getState();
+ sortAnnBySequence.setSelected(false);
+ setAnnotationSortOrder(newState ? SequenceAnnotationOrder.LABEL_AND_SEQUENCE
+ : SequenceAnnotationOrder.NONE);
+ sortAnnotations_actionPerformed();
+ }
+ });
colourTextMenuItem.setText(MessageManager
.getString("label.colour_text"));
colourTextMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
colourTextMenuItem_actionPerformed(e);
htmlMenuItem.setText(MessageManager.getString("label.html"));
htmlMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
htmlMenuItem_actionPerformed(e);
}
});
+
+ // TODO uncomment when supported by MassageManager
+ // createBioJS.setText(MessageManager.getString("label.biojs_html_export"));
+ createBioJS.setText("BioJS");
+ createBioJS.addActionListener(new java.awt.event.ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ bioJSMenuItem_actionPerformed(e);
+ }
+ });
+
overviewMenuItem.setText(MessageManager
.getString("label.overview_window"));
overviewMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
overviewMenuItem_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
undoMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
undoMenuItem_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
redoMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
redoMenuItem_actionPerformed(e);
conservationMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
conservationMenuItem_actionPerformed(e);
noColourmenuItem.setText(MessageManager.getString("label.none"));
noColourmenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
noColourmenuItem_actionPerformed(e);
wrapMenuItem.setText(MessageManager.getString("label.wrap"));
wrapMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
wrapMenuItem_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
printMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
printMenuItem_actionPerformed(e);
renderGapsMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
renderGapsMenuItem_actionPerformed(e);
findMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_F, Toolkit.getDefaultToolkit()
.getMenuShortcutKeyMask(), false));
+ findMenuItem.setToolTipText(JvSwingUtils.wrapTooltip(true,
+ MessageManager.getString("label.find_tip")));
findMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
findMenuItem_actionPerformed(e);
.getString("label.above_identity_threshold"));
abovePIDThreshold.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
abovePIDThreshold_actionPerformed(e);
.getString("label.show_sequence_features"));
showSeqFeatures.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent actionEvent)
{
showSeqFeatures_actionPerformed(actionEvent);
showDbRefsMenuitem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showDbRefs_actionPerformed(e);
showNpFeatsMenuitem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showNpFeats_actionPerformed(e);
showGroupConservation.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showGroupConservation_actionPerformed(e);
showGroupConsensus.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showGroupConsensus_actionPerformed(e);
showConsensusHistogram.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showConsensusHistogram_actionPerformed(e);
showSequenceLogo.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showSequenceLogo_actionPerformed(e);
normaliseSequenceLogo.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
normaliseSequenceLogo_actionPerformed(e);
applyAutoAnnotationSettings.setVisible(true);
applyAutoAnnotationSettings.addActionListener(new ActionListener()
{
-
+ @Override
public void actionPerformed(ActionEvent e)
{
applyAutoAnnotationSettings_actionPerformed(e);
}
+ });
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(showAutoFirst);
+ buttonGroup.add(showAutoLast);
+ showAutoFirst.setText(MessageManager.getString("label.show_first"));
+ showAutoFirst.setSelected(Cache.getDefault(
+ Preferences.SHOW_AUTOCALC_ABOVE,
+ false));
+ showAutoFirst.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ setShowAutoCalculatedAbove(showAutoFirst.isSelected());
+ sortAnnotations_actionPerformed();
+ }
+ });
+ showAutoLast.setText(MessageManager.getString("label.show_last"));
+ showAutoLast.setSelected(!showAutoFirst.isSelected());
+ showAutoLast.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ setShowAutoCalculatedAbove(!showAutoLast.isSelected());
+ sortAnnotations_actionPerformed();
+ }
});
nucleotideColour.setText(MessageManager.getString("label.nucleotide"));
nucleotideColour.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
nucleotideColour_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
deleteGroups.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
deleteGroups_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
createGroup.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
createGroup_actionPerformed(e);
| java.awt.event.KeyEvent.SHIFT_MASK, false));
unGroup.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
unGroup_actionPerformed(e);
copy.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
copy_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
cut.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
cut_actionPerformed(e);
}
});
delete.setText(MessageManager.getString("action.delete"));
- delete.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
- java.awt.event.KeyEvent.VK_BACK_SPACE, 0, false));
delete.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
delete_actionPerformed(e);
| java.awt.event.KeyEvent.SHIFT_MASK, false));
pasteNew.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
pasteNew_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
pasteThis.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
pasteThis_actionPerformed(e);
.getString("label.apply_colour_to_all_groups"));
applyToAllGroups.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
applyToAllGroups_actionPerformed(e);
});
createPNG.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
createPNG(null);
createPNG.setActionCommand(MessageManager
.getString("label.save_png_image"));
createPNG.setText("PNG");
+
font.setText(MessageManager.getString("action.font"));
font.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
font_actionPerformed(e);
}
});
-
seqLimits.setText(MessageManager
.getString("label.show_sequence_limits"));
seqLimits.setState(jalview.bin.Cache.getDefault("SHOW_JVSUFFIX", true));
seqLimits.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
seqLimit_actionPerformed(e);
epsFile.setText("EPS");
epsFile.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
createEPS(null);
}
});
+
+ createSVG.setText("SVG");
+ createSVG.addActionListener(new java.awt.event.ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ createSVG(null);
+ }
+ });
+
LoadtreeMenuItem.setActionCommand(MessageManager
.getString("label.load_tree_for_sequence_set"));
LoadtreeMenuItem.setText(MessageManager
.getString("label.load_associated_tree"));
LoadtreeMenuItem.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
LoadtreeMenuItem_actionPerformed(e);
scaleAbove.setText(MessageManager.getString("action.scale_above"));
scaleAbove.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
scaleAbove_actionPerformed(e);
scaleLeft.setText(MessageManager.getString("action.scale_left"));
scaleLeft.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
scaleLeft_actionPerformed(e);
scaleRight.setText(MessageManager.getString("action.scale_right"));
scaleRight.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
scaleRight_actionPerformed(e);
centreColumnLabelsMenuItem
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
centreColumnLabels_actionPerformed(e);
followHighlightMenuItem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
followHighlight_actionPerformed();
.getString("label.modify_identity_thereshold"));
modifyPID.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
modifyPID_actionPerformed(e);
modifyConservation
.addActionListener(new java.awt.event.ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
modifyConservation_actionPerformed(e);
sort.setText(MessageManager.getString("action.sort"));
sort.addMenuListener(new MenuListener()
{
+ @Override
public void menuSelected(MenuEvent e)
{
buildTreeMenu();
}
+ @Override
public void menuDeselected(MenuEvent e)
{
}
+ @Override
public void menuCanceled(MenuEvent e)
{
}
sortByAnnotScore.addMenuListener(new javax.swing.event.MenuListener()
{
+ @Override
public void menuCanceled(MenuEvent e)
{
}
+ @Override
public void menuDeselected(MenuEvent e)
{
}
+ @Override
public void menuSelected(MenuEvent e)
{
buildSortByAnnotationScoresMenu();
.getDefault("PAD_GAPS", false));
padGapsMenuitem.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
padGapsMenuitem_actionPerformed(e);
vamsasStore.setText(MessageManager.getString("label.vamsas_store"));
vamsasStore.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
vamsasStore_actionPerformed(e);
.getString("label.translate_cDNA"));
showTranslation.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showTranslation_actionPerformed(e);
+ "...");
extractScores.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
extractScores_actionPerformed(e);
.getString("label.feature_settings"));
openFeatureSettings.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
featureSettings_actionPerformed(e);
.setText(MessageManager.getString("label.fetch_sequences"));
fetchSequence.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
fetchSequence_actionPerformed(e);
.getString("action.by_annotation"));
annotationColour.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
annotationColour_actionPerformed(e);
.getString("action.by_rna_helixes"));
rnahelicesColour.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
rnahelicesColour_actionPerformed(e);
.getString("label.load_features_annotations"));
associatedData.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
associatedData_actionPerformed(e);
"AUTO_CALC_CONSENSUS", true));
autoCalculate.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
autoCalculate_actionPerformed(e);
.setState(jalview.bin.Cache.getDefault("SORT_BY_TREE", false));
sortByTree.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
sortByTreeOption_actionPerformed(e);
listenToViewSelections.setState(false);
listenToViewSelections.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
listenToViewSelections_actionPerformed(e);
addFromFile.setText(MessageManager.getString("label.from_file"));
addFromFile.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
addFromFile_actionPerformed(e);
addFromText.setText(MessageManager.getString("label.from_textbox"));
addFromText.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
addFromText_actionPerformed(e);
addFromURL.setText(MessageManager.getString("label.from_url"));
addFromURL.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
addFromURL_actionPerformed(e);
.getString("label.export_features"));
exportFeatures.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
exportFeatures_actionPerformed(e);
.getString("label.export_annotations"));
exportAnnotations.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
exportAnnotations_actionPerformed(e);
.getString("label.toggle_sequence_visibility"));
showAllSeqs.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showAllSeqs_actionPerformed(e);
.getString("label.toggle_columns_visibility"));
showAllColumns.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showAllColumns_actionPerformed(e);
.getString("label.toggle_sequence_visibility"));
hideSelSequences.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
hideSelSequences_actionPerformed(e);
.getString("label.toggle_columns_visibility"));
hideSelColumns.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
hideSelColumns_actionPerformed(e);
.getString("label.selected_region"));
hideAllSelection.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
hideAllSelection_actionPerformed(e);
.getString("label.all_but_selected_region"));
hideAllButSelection.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
hideAllButSelection_actionPerformed(e);
.getString("label.toggles_visibility_hidden_selected_regions"));
showAllhidden.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
showAllhidden_actionPerformed(e);
}
});
-
hiddenMarkers.setText(MessageManager
.getString("action.show_hidden_markers"));
hiddenMarkers.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
hiddenMarkers_actionPerformed(e);
| java.awt.event.KeyEvent.ALT_MASK, false));
invertColSel.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
invertColSel_actionPerformed(e);
});
tabbedPane.addChangeListener(new javax.swing.event.ChangeListener()
{
+ @Override
public void stateChanged(ChangeEvent evt)
{
JTabbedPane pane = (JTabbedPane) evt.getSource();
});
tabbedPane.addMouseListener(new MouseAdapter()
{
+ @Override
public void mousePressed(MouseEvent e)
{
tabbedPane_mousePressed(e);
});
tabbedPane.addFocusListener(new FocusAdapter()
{
+ @Override
public void focusGained(FocusEvent e)
{
tabbedPane_focusGained(e);
.getMenuShortcutKeyMask(), false));
save.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
save_actionPerformed(e);
reload.setText(MessageManager.getString("action.reload"));
reload.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
reload_actionPerformed(e);
.getMenuShortcutKeyMask(), false));
newView.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
newView_actionPerformed(e);
+ "...");
textColour.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
textColour_actionPerformed(e);
.getString("label.right_align_sequence_id"));
idRightAlign.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
idRightAlign_actionPerformed(e);
java.awt.event.KeyEvent.VK_G, 0, false));
gatherViews.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
gatherViews_actionPerformed(e);
java.awt.event.KeyEvent.VK_X, 0, false));
expandViews.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
expandViews_actionPerformed(e);
.setText(MessageManager.getString("action.page_setup") + "...");
pageSetup.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
pageSetup_actionPerformed(e);
.getString("label.alignment_props") + "...");
alignmentProperties.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent actionEvent)
{
alignmentProperties();
alignFrameMenuBar.add(editMenu);
alignFrameMenuBar.add(selectMenu);
alignFrameMenuBar.add(viewMenu);
+ alignFrameMenuBar.add(annotationsMenu);
alignFrameMenuBar.add(formatMenu);
alignFrameMenuBar.add(colourMenu);
alignFrameMenuBar.add(calculateMenu);
viewMenu.add(hideMenu);
viewMenu.addSeparator();
viewMenu.add(followHighlightMenuItem);
- viewMenu.add(annotationPanelMenuItem);
+ annotationsMenu.add(annotationPanelMenuItem);
+ annotationsMenu.addSeparator();
+ annotationsMenu.add(showAllAlAnnotations);
+ annotationsMenu.add(hideAllAlAnnotations);
+ annotationsMenu.addSeparator();
+ annotationsMenu.add(showAllSeqAnnotations);
+ annotationsMenu.add(hideAllSeqAnnotations);
+ annotationsMenu.add(sortAnnBySequence);
+ annotationsMenu.add(sortAnnByLabel);
+ annotationsMenu.addSeparator();
+ autoAnnMenu.add(showAutoFirst);
+ autoAnnMenu.add(showAutoLast);
+ autoAnnMenu.addSeparator();
autoAnnMenu.add(applyAutoAnnotationSettings);
autoAnnMenu.add(showConsensusHistogram);
autoAnnMenu.add(showSequenceLogo);
autoAnnMenu.addSeparator();
autoAnnMenu.add(showGroupConservation);
autoAnnMenu.add(showGroupConsensus);
- viewMenu.add(autoAnnMenu);
+ annotationsMenu.add(autoAnnMenu);
viewMenu.addSeparator();
viewMenu.add(showSeqFeatures);
// viewMenu.add(showSeqFeaturesHeight);
jMenu2.add(htmlMenuItem);
jMenu2.add(epsFile);
jMenu2.add(createPNG);
+ jMenu2.add(createBioJS);
+ jMenu2.add(createSVG);
addSequenceMenu.add(addFromFile);
addSequenceMenu.add(addFromText);
addSequenceMenu.add(addFromURL);
// selectMenu.add(listenToViewSelections);
}
+ /**
+ * Action on clicking sort annotations by type.
+ *
+ * @param sortOrder
+ */
+ protected void sortAnnotations_actionPerformed()
+ {
+ }
+
+ /**
+ * Action on clicking Show all annotations.
+ *
+ * @param forSequences
+ * update sequence-related annotations
+ * @param forAlignment
+ * update non-sequence-related annotations
+ */
+ protected void showAllAnnotations_actionPerformed(boolean forSequences,
+ boolean forAlignment)
+ {
+ setAnnotationsVisibility(true, forSequences, forAlignment);
+ }
+
+ /**
+ * Action on clicking Hide all annotations.
+ *
+ * @param forSequences
+ * update sequence-related annotations
+ * @param forAlignment
+ * update non-sequence-related annotations
+ */
+ protected void hideAllAnnotations_actionPerformed(boolean forSequences,
+ boolean forAlignment)
+ {
+ setAnnotationsVisibility(false, forSequences, forAlignment);
+ }
+
+ /**
+ * Set the visibility of annotations to true or false. Can act on
+ * sequence-related annotations, or alignment-related, or both.
+ *
+ * @param visible
+ * @param forSequences
+ * update sequence-related annotations
+ * @param forAlignment
+ * update non-sequence-related annotations
+ */
+ protected void setAnnotationsVisibility(boolean visible,
+ boolean forSequences, boolean forAlignment)
+ {
+
+ }
+
protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
{
}
+ protected void bioJSMenuItem_actionPerformed(ActionEvent e)
+ {
+
+ }
+
protected void closeMenuItem_actionPerformed(boolean b)
{
}
{
}
+ public void createSVG(java.io.File f)
+ {
+
+ }
protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
}
+
+ protected boolean isShowAutoCalculatedAbove()
+ {
+ return showAutoCalculatedAbove;
+ }
+
+ protected void setShowAutoCalculatedAbove(boolean showAutoCalculatedAbove)
+ {
+ this.showAutoCalculatedAbove = showAutoCalculatedAbove;
+ }
+
+ protected SequenceAnnotationOrder getAnnotationSortOrder()
+ {
+ return annotationSortOrder;
+ }
+
+ protected void setAnnotationSortOrder(SequenceAnnotationOrder annotationSortOrder)
+ {
+ this.annotationSortOrder = annotationSortOrder;
+ }
}
JMenuItem saveState = new JMenuItem();
JMenuItem loadState = new JMenuItem();
-
+
JMenu inputMenu = new JMenu();
protected JMenuItem vamsasStart = new JMenuItem();
protected JCheckBoxMenuItem showConsole = new JCheckBoxMenuItem();
protected JCheckBoxMenuItem showNews = new JCheckBoxMenuItem();
-
+
+ protected JMenuItem snapShotWindow = new JMenuItem();
/**
* Creates a new GDesktop object.
*/
showNews_actionPerformed(e);
}
});
+ snapShotWindow.setText(MessageManager.getString("label.take_snapshot"));
+ snapShotWindow.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ snapShotWindow_actionPerformed(e);
+ }
+ });
+
desktopMenubar.add(FileMenu);
desktopMenubar.add(toolsMenu);
VamsasMenu.setVisible(false);
toolsMenu.add(showConsole);
toolsMenu.add(showNews);
toolsMenu.add(garbageCollect);
+ toolsMenu.add(snapShotWindow);
inputMenu.add(inputLocalFileMenuItem);
inputMenu.add(inputURLMenuItem);
inputMenu.add(inputTextboxMenuItem);
// inputMenu.add(vamsasLoad);
}
+ protected void snapShotWindow_actionPerformed(ActionEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
protected void showConsole_actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
package jalview.jbgui;
import jalview.gui.JvSwingUtils;
+import jalview.gui.StructureViewer.Viewer;
import jalview.util.MessageManager;
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-import javax.swing.border.*;
-import javax.swing.event.*;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.Insets;
import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+import javax.swing.BorderFactory;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingConstants;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
/**
- * DOCUMENT ME!
+ * Base class for the Preferences panel.
*
* @author $author$
* @version $Revision$
*/
public class GPreferences extends JPanel
{
- JTabbedPane tabbedPane = new JTabbedPane();
-
- JButton ok = new JButton();
-
- JButton cancel = new JButton();
-
- JPanel okCancelPanel = new JPanel();
-
- BorderLayout borderLayout1 = new BorderLayout();
-
- protected JCheckBox quality = new JCheckBox();
-
- JPanel visualTab = new JPanel();
-
- JPanel visual2Tab = new JPanel();
+ private static final Font verdana11 = JvSwingUtils.getLabelFont();
+ /*
+ * Visual tab components
+ */
protected JCheckBox fullScreen = new JCheckBox();
- protected JCheckBox conservation = new JCheckBox();
-
- protected JCheckBox identity = new JCheckBox();
+ protected JCheckBox openoverv = new JCheckBox();
- protected JCheckBox annotations = new JCheckBox();
+ protected JCheckBox seqLimit = new JCheckBox();
- protected JPanel minColour = new JPanel();
+ protected JCheckBox rightAlign = new JCheckBox();
- JLabel mincolourLabel = new JLabel();
+ protected JComboBox<String> fontSizeCB = new JComboBox<String>();
- protected JPanel maxColour = new JPanel();
+ protected JComboBox<String> fontStyleCB = new JComboBox<String>();
- JLabel maxcolourLabel = new JLabel();
+ protected JComboBox<String> fontNameCB = new JComboBox<String>();
- JLabel gapLabel = new JLabel();
+ protected JCheckBox showUnconserved = new JCheckBox();
- protected JComboBox colour = new JComboBox();
+ protected JCheckBox idItalics = new JCheckBox();
- JLabel colourLabel = new JLabel();
+ protected JCheckBox smoothFont = new JCheckBox();
- JLabel fontLabel = new JLabel();
+ protected JComboBox<String> gapSymbolCB = new JComboBox<String>();
- protected JComboBox fontSizeCB = new JComboBox();
+ protected JCheckBox wrap = new JCheckBox();
- protected JComboBox fontStyleCB = new JComboBox();
+ protected JComboBox<String> sortby = new JComboBox<String>();
- protected JComboBox fontNameCB = new JComboBox();
+ protected JComboBox<String> sortAnnBy = new JComboBox<String>();
- protected JComboBox gapSymbolCB = new JComboBox();
+ protected JComboBox<String> sortAutocalc = new JComboBox<String>();
protected JCheckBox startupCheckbox = new JCheckBox();
protected JTextField startupFileTextfield = new JTextField();
- JPanel connectTab = new JPanel();
-
- JLabel serverLabel = new JLabel();
-
- protected JList linkURLList = new JList();
-
- protected JTextField proxyServerTB = new JTextField();
-
- protected JTextField proxyPortTB = new JTextField();
-
- JLabel portLabel = new JLabel();
-
- JLabel browserLabel = new JLabel();
-
- protected JTextField defaultBrowser = new JTextField();
-
- JButton newLink = new JButton();
-
- JButton editLink = new JButton();
-
- JButton deleteLink = new JButton();
+ // below are in the 'second column'
+ protected JCheckBox annotations = new JCheckBox();
- JScrollPane linkScrollPane = new JScrollPane();
+ protected JCheckBox quality = new JCheckBox();
- JPanel linkPanel = new JPanel();
+ protected JCheckBox conservation = new JCheckBox();
- BorderLayout borderLayout2 = new BorderLayout();
+ protected JCheckBox identity = new JCheckBox();
- JPanel editLinkButtons = new JPanel();
+ protected JCheckBox showGroupConsensus = new JCheckBox();
- GridLayout gridLayout1 = new GridLayout();
+ protected JCheckBox showGroupConservation = new JCheckBox();
- protected JList linkNameList = new JList();
+ protected JCheckBox showConsensHistogram = new JCheckBox();
- JPanel linkPanel2 = new JPanel();
+ protected JCheckBox showConsensLogo = new JCheckBox();
- BorderLayout borderLayout3 = new BorderLayout();
+ protected JCheckBox showDbRefTooltip = new JCheckBox();
- protected JCheckBox useProxy = new JCheckBox();
+ protected JCheckBox showNpTooltip = new JCheckBox();
- JPanel jPanel1 = new JPanel();
+ /*
+ * Annotations tab components
+ */
+ protected JCheckBox structFromPdb = new JCheckBox();
- TitledBorder titledBorder1 = new TitledBorder(
- MessageManager.getString("label.proxy_server"));
+ protected JCheckBox useRnaView = new JCheckBox();
- TitledBorder titledBorder2 = new TitledBorder(
- MessageManager.getString("label.file_output"));
+ protected JCheckBox addSecondaryStructure = new JCheckBox();
- GridBagLayout gridBagLayout2 = new GridBagLayout();
+ protected JCheckBox addTempFactor = new JCheckBox();
- GridBagLayout gridBagLayout1 = new GridBagLayout();
+ protected JComboBox<String> structViewer = new JComboBox<String>();
- GridBagLayout gridBagLayout3 = new GridBagLayout();
+ protected JTextField chimeraPath = new JTextField();
- protected JComboBox sortby = new JComboBox();
+ /*
+ * Colours tab components
+ */
+ protected JPanel minColour = new JPanel();
- JLabel sortLabel = new JLabel();
+ protected JPanel maxColour = new JPanel();
- JPanel jPanel2 = new JPanel();
+ protected JComboBox<String> colour = new JComboBox<String>();
- JPanel visual2panel = new JPanel();
+ /*
+ * Connections tab components
+ */
+ protected JList linkURLList = new JList();
- GridLayout gridLayout2 = new GridLayout();
+ protected JTextField proxyServerTB = new JTextField();
- GridLayout gridLayout4 = new GridLayout();
+ protected JTextField proxyPortTB = new JTextField();
- JPanel annsettingsPanel = new JPanel();
+ protected JTextField defaultBrowser = new JTextField();
- JPanel autoAnnotSettings1 = new JPanel();
+ protected JList linkNameList = new JList();
- JPanel autoAnnotSettings2 = new JPanel();
+ protected JCheckBox useProxy = new JCheckBox();
- JPanel autoAnnotSettings3 = new JPanel();
+ protected JCheckBox usagestats = new JCheckBox();
- JPanel exportTab = new JPanel();
+ protected JCheckBox questionnaire = new JCheckBox();
- JLabel epsLabel = new JLabel();
+ protected JCheckBox versioncheck = new JCheckBox();
- protected JComboBox epsRendering = new JComboBox();
+ /*
+ * Output tab components
+ */
+ protected JComboBox<String> epsRendering = new JComboBox<String>();
protected JLabel userIdWidthlabel = new JLabel();
protected JTextField userIdWidth = new JTextField();
- JLabel jLabel1 = new JLabel();
-
protected JCheckBox blcjv = new JCheckBox();
protected JCheckBox pileupjv = new JCheckBox();
protected JCheckBox pfamjv = new JCheckBox();
- FlowLayout flowLayout1 = new FlowLayout();
-
protected JCheckBox pirjv = new JCheckBox();
- JPanel jPanel11 = new JPanel();
-
- Font verdana11 = JvSwingUtils.getLabelFont();
-
- protected JCheckBox seqLimit = new JCheckBox();
-
- GridLayout gridLayout3 = new GridLayout();
-
- protected JCheckBox smoothFont = new JCheckBox();
-
- JPanel calcTab = new JPanel();
+ protected JCheckBox modellerOutput = new JCheckBox();
+ /*
+ * Editing tab components
+ */
protected JCheckBox autoCalculateConsCheck = new JCheckBox();
protected JCheckBox padGaps = new JCheckBox();
- protected JCheckBox modellerOutput = new JCheckBox();
-
- protected JPanel dasPanel = new JPanel();
-
- BorderLayout borderLayout4 = new BorderLayout();
-
- protected JPanel wsPanel = new JPanel();
-
- BorderLayout borderLayout5 = new BorderLayout();
-
- protected JCheckBox wrap = new JCheckBox();
-
- protected JCheckBox rightAlign = new JCheckBox();
-
- protected JCheckBox showUnconserved = new JCheckBox();
-
- protected JCheckBox showDbRefTooltip = new JCheckBox();
-
- protected JCheckBox showNpTooltip = new JCheckBox();
-
- protected JCheckBox idItalics = new JCheckBox();
-
- protected JCheckBox openoverv = new JCheckBox();
-
- protected JCheckBox usagestats = new JCheckBox();
-
- protected JCheckBox questionnaire = new JCheckBox();
-
- protected JCheckBox versioncheck = new JCheckBox();
-
- protected JLabel showGroupbits = new JLabel();
-
- protected JLabel showConsensbits = new JLabel();
-
- protected JCheckBox showConsensLogo = new JCheckBox();
-
- protected JCheckBox showConsensHistogram = new JCheckBox();
-
- protected JCheckBox showGroupConsensus = new JCheckBox();
-
- protected JCheckBox showGroupConservation = new JCheckBox();
-
- protected JCheckBox shareSelections = new JCheckBox();
+ protected JCheckBox sortByTree = new JCheckBox();
- protected JCheckBox followHighlight = new JCheckBox();
+ /*
+ * DAS Settings tab
+ */
+ protected JPanel dasTab = new JPanel();
- protected JCheckBox sortByTree = new JCheckBox();
+ /*
+ * Web Services tab
+ */
+ protected JPanel wsTab = new JPanel();
/**
* Creates a new GPreferences object.
}
/**
- * DOCUMENT ME!
+ * Construct the panel and its tabbed sub-panels.
*
* @throws Exception
- * DOCUMENT ME!
*/
private void jbInit() throws Exception
{
- this.setLayout(borderLayout1);
- ok.setText(MessageManager.getString("action.ok"));
- ok.addActionListener(new ActionListener()
+ JTabbedPane tabbedPane = new JTabbedPane();
+ this.setLayout(new BorderLayout());
+ JPanel okCancelPanel = initOkCancelPanel();
+ this.add(tabbedPane, BorderLayout.CENTER);
+ this.add(okCancelPanel, BorderLayout.SOUTH);
+
+ tabbedPane.add(initVisualTab(),
+ MessageManager.getString("label.visual"));
+
+ tabbedPane.add(initColoursTab(),
+ MessageManager.getString("label.colours"));
+
+ tabbedPane.add(initStructureTab(),
+ MessageManager.getString("label.structure"));
+
+ tabbedPane.add(initConnectionsTab(),
+ MessageManager.getString("label.connections"));
+
+ tabbedPane.add(initOutputTab(), MessageManager.getString("label.output"));
+
+ tabbedPane.add(initEditingTab(), MessageManager.getString("label.editing"));
+
+ /*
+ * See DasSourceBrowser for the real work of configuring this tab.
+ */
+ dasTab.setLayout(new BorderLayout());
+ tabbedPane
+ .add(dasTab, MessageManager.getString("label.das_settings"));
+
+ /*
+ * See WsPreferences for the real work of configuring this tab.
+ */
+ wsTab.setLayout(new BorderLayout());
+ tabbedPane.add(wsTab, MessageManager.getString("label.web_services"));
+ }
+
+ /**
+ * Initialises the Editing tabbed panel.
+ *
+ * @return
+ */
+ private JPanel initEditingTab()
+ {
+ JPanel editingTab = new JPanel();
+ editingTab.setLayout(null);
+ autoCalculateConsCheck.setFont(verdana11);
+ autoCalculateConsCheck.setText(MessageManager
+ .getString("label.autocalculate_consensus"));
+ autoCalculateConsCheck.setBounds(new Rectangle(21, 52, 209, 23));
+ padGaps.setFont(verdana11);
+ padGaps.setText(MessageManager.getString("label.pad_gaps_when_editing"));
+ padGaps.setBounds(new Rectangle(22, 94, 168, 23));
+ sortByTree.setFont(verdana11);
+ sortByTree
+ .setText(MessageManager.getString("label.sort_with_new_tree"));
+ sortByTree
+ .setToolTipText(MessageManager
+ .getString("label.any_trees_calculated_or_loaded_alignment_automatically_sort"));
+ sortByTree.setBounds(new Rectangle(22, 136, 168, 23));
+ editingTab.add(autoCalculateConsCheck);
+ editingTab.add(padGaps);
+ editingTab.add(sortByTree);
+ return editingTab;
+ }
+
+ /**
+ * Initialises the Output tabbed panel.
+ *
+ * @return
+ */
+ private JPanel initOutputTab()
+ {
+ JPanel outputTab = new JPanel();
+ outputTab.setLayout(null);
+ JLabel epsLabel = new JLabel();
+ epsLabel.setFont(verdana11);
+ epsLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ epsLabel.setText(MessageManager.getString("label.eps_rendering_style"));
+ epsLabel.setBounds(new Rectangle(9, 31, 140, 24));
+ epsRendering.setFont(verdana11);
+ epsRendering.setBounds(new Rectangle(154, 34, 187, 21));
+ JLabel jLabel1 = new JLabel();
+ jLabel1.setFont(verdana11);
+ jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
+ jLabel1.setText(MessageManager.getString("label.append_start_end"));
+ jLabel1.setFont(verdana11);
+ fastajv.setFont(verdana11);
+ fastajv.setHorizontalAlignment(SwingConstants.LEFT);
+ clustaljv.setText(MessageManager.getString("label.clustal") + " ");
+ blcjv.setText(MessageManager.getString("label.blc") + " ");
+ fastajv.setText(MessageManager.getString("label.fasta") + " ");
+ msfjv.setText(MessageManager.getString("label.msf") + " ");
+ pfamjv.setText(MessageManager.getString("label.pfam") + " ");
+ pileupjv.setText(MessageManager.getString("label.pileup") + " ");
+ msfjv.setFont(verdana11);
+ msfjv.setHorizontalAlignment(SwingConstants.LEFT);
+ pirjv.setText(MessageManager.getString("label.pir") + " ");
+ JPanel jPanel11 = new JPanel();
+ jPanel11.setFont(verdana11);
+ TitledBorder titledBorder2 = new TitledBorder(
+ MessageManager.getString("label.file_output"));
+ jPanel11.setBorder(titledBorder2);
+ jPanel11.setBounds(new Rectangle(30, 72, 196, 182));
+ GridLayout gridLayout3 = new GridLayout();
+ jPanel11.setLayout(gridLayout3);
+ gridLayout3.setRows(8);
+ blcjv.setFont(verdana11);
+ blcjv.setHorizontalAlignment(SwingConstants.LEFT);
+ clustaljv.setFont(verdana11);
+ clustaljv.setHorizontalAlignment(SwingConstants.LEFT);
+ pfamjv.setFont(verdana11);
+ pfamjv.setHorizontalAlignment(SwingConstants.LEFT);
+ pileupjv.setFont(verdana11);
+ pileupjv.setHorizontalAlignment(SwingConstants.LEFT);
+ pirjv.setFont(verdana11);
+ pirjv.setHorizontalAlignment(SwingConstants.LEFT);
+ autoIdWidth.setFont(verdana11);
+ autoIdWidth.setText(MessageManager
+ .getString("label.automatically_set_id_width"));
+ autoIdWidth
+ .setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.getString("label.adjusts_width_generated_eps_png")));
+ autoIdWidth.setBounds(new Rectangle(228, 96, 188, 23));
+ autoIdWidth.addActionListener(new ActionListener()
{
+
+ @Override
public void actionPerformed(ActionEvent e)
{
- ok_actionPerformed(e);
+ autoIdWidth_actionPerformed();
}
});
- cancel.setText(MessageManager.getString("action.cancel"));
- cancel.addActionListener(new ActionListener()
+ userIdWidthlabel.setFont(verdana11);
+ userIdWidthlabel.setText(MessageManager
+ .getString("label.figure_id_column_width"));
+ userIdWidth
+ .setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.getString("label.manually_specify_width_left_column")));
+ userIdWidthlabel
+ .setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.getString("label.manually_specify_width_left_column")));
+ userIdWidthlabel.setBounds(new Rectangle(236, 120, 168, 23));
+ userIdWidth.setFont(JvSwingUtils.getTextAreaFont());
+ userIdWidth.setText("");
+ userIdWidth.setBounds(new Rectangle(232, 144, 84, 23));
+ userIdWidth.addActionListener(new ActionListener()
{
+
+ @Override
public void actionPerformed(ActionEvent e)
{
- cancel_actionPerformed(e);
- }
- });
- quality.setEnabled(false);
- quality.setFont(verdana11);
- quality.setHorizontalAlignment(SwingConstants.RIGHT);
- quality.setHorizontalTextPosition(SwingConstants.LEFT);
- quality.setSelected(true);
- quality.setText(MessageManager.getString("label.quality"));
- visualTab.setBorder(new TitledBorder(MessageManager
- .getString("action.open_new_aligmnent")));
- visualTab.setLayout(null);
- visual2Tab.setBorder(new TitledBorder(MessageManager
- .getString("action.open_new_aligmnent")));
- visual2Tab.setLayout(new FlowLayout());
- fullScreen.setFont(verdana11);
- fullScreen.setHorizontalAlignment(SwingConstants.RIGHT);
- fullScreen.setHorizontalTextPosition(SwingConstants.LEFT);
- fullScreen.setText(MessageManager.getString("label.maximize_window"));
- conservation.setEnabled(false);
- conservation.setFont(verdana11);
- conservation.setHorizontalAlignment(SwingConstants.RIGHT);
- conservation.setHorizontalTextPosition(SwingConstants.LEFT);
- conservation.setSelected(true);
- conservation.setText(MessageManager.getString("label.conservation"));
- identity.setEnabled(false);
- identity.setFont(verdana11);
- identity.setHorizontalAlignment(SwingConstants.RIGHT);
- identity.setHorizontalTextPosition(SwingConstants.LEFT);
- identity.setSelected(true);
- identity.setText(MessageManager.getString("label.consensus"));
- showGroupbits.setFont(verdana11);
- showGroupbits.setHorizontalAlignment(SwingConstants.RIGHT);
- showGroupbits.setHorizontalTextPosition(SwingConstants.LEFT);
- showGroupbits.setText(MessageManager.getString("action.show_group")
- + ":");
- showConsensbits.setFont(verdana11);
- showConsensbits.setHorizontalAlignment(SwingConstants.RIGHT);
- showConsensbits.setHorizontalTextPosition(SwingConstants.LEFT);
- showConsensbits.setText(MessageManager.getString("label.consensus")
- + ":");
- showConsensHistogram.setEnabled(false);
- showConsensHistogram.setFont(verdana11);
- showConsensHistogram.setHorizontalAlignment(SwingConstants.RIGHT);
- showConsensHistogram.setHorizontalTextPosition(SwingConstants.LEFT);
- showConsensHistogram.setSelected(true);
- showConsensHistogram.setText(MessageManager
- .getString("label.histogram"));
- showConsensLogo.setEnabled(false);
- showConsensLogo.setFont(verdana11);
- showConsensLogo.setHorizontalAlignment(SwingConstants.RIGHT);
- showConsensLogo.setHorizontalTextPosition(SwingConstants.LEFT);
- showConsensLogo.setSelected(true);
- showConsensLogo.setText(MessageManager.getString("label.logo"));
- showGroupConsensus.setEnabled(false);
- showGroupConsensus.setFont(verdana11);
- showGroupConsensus.setHorizontalAlignment(SwingConstants.RIGHT);
- showGroupConsensus.setHorizontalTextPosition(SwingConstants.LEFT);
- showGroupConsensus.setSelected(true);
- showGroupConsensus.setText(MessageManager.getString("label.consensus"));
- showGroupConservation.setEnabled(false);
- showGroupConservation.setFont(verdana11);
- showGroupConservation.setHorizontalAlignment(SwingConstants.RIGHT);
- showGroupConservation.setHorizontalTextPosition(SwingConstants.LEFT);
- showGroupConservation.setSelected(true);
- showGroupConservation.setText(MessageManager
- .getString("label.conservation"));
- showNpTooltip.setEnabled(true);
- showNpTooltip.setFont(verdana11);
- showNpTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
- showNpTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
- showNpTooltip.setSelected(true);
- showNpTooltip.setText(MessageManager
- .getString("label.non_positional_features"));
- showDbRefTooltip.setEnabled(true);
- showDbRefTooltip.setFont(verdana11);
- showDbRefTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
- showDbRefTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
- showDbRefTooltip.setSelected(true);
- showDbRefTooltip.setText(MessageManager
- .getString("label.database_references"));
- annotations.setFont(verdana11);
- annotations.setHorizontalAlignment(SwingConstants.RIGHT);
- annotations.setHorizontalTextPosition(SwingConstants.LEADING);
- annotations.setSelected(true);
- annotations.setText(MessageManager.getString("label.show_annotations"));
- annotations.setBounds(new Rectangle(169, 12, 200, 23));
- annotations.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- annotations_actionPerformed(e);
- }
- });
- identity.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- annotations_actionPerformed(e);
- }
- });
- showGroupConsensus.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- annotations_actionPerformed(e);
- }
- });
- showUnconserved.setFont(verdana11);
- showUnconserved.setHorizontalAlignment(SwingConstants.RIGHT);
- showUnconserved.setHorizontalTextPosition(SwingConstants.LEFT);
- showUnconserved.setSelected(true);
- showUnconserved.setText(MessageManager
- .getString("action.show_unconserved"));
- showUnconserved.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- showunconserved_actionPerformed(e);
- }
- });
- // / TODO: fit these in to preferences panel!!!!!
- shareSelections.setFont(verdana11);
- shareSelections.setHorizontalAlignment(SwingConstants.RIGHT);
- shareSelections.setHorizontalTextPosition(SwingConstants.LEFT);
- shareSelections.setSelected(true);
- shareSelections.setText(MessageManager
- .getString("label.share_selection_across_views"));
- followHighlight.setFont(verdana11);
- followHighlight.setHorizontalAlignment(SwingConstants.RIGHT);
- followHighlight.setHorizontalTextPosition(SwingConstants.LEFT);
- // showUnconserved.setBounds(new Rectangle(169, 40, 200, 23));
- followHighlight.setSelected(true);
- followHighlight.setText(MessageManager
- .getString("label.scroll_highlighted_regions"));
-
- gapLabel.setFont(verdana11);
- gapLabel.setHorizontalAlignment(SwingConstants.RIGHT);
- gapLabel.setText(MessageManager.getString("label.gap_symbol") + " ");
- colour.setFont(verdana11);
- colour.setBounds(new Rectangle(172, 225, 155, 21));
- colourLabel.setFont(verdana11);
- colourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
- colourLabel.setText(MessageManager.getString("label.alignment_colour")
- + " ");
- fontLabel.setFont(verdana11);
- fontLabel.setHorizontalAlignment(SwingConstants.RIGHT);
- fontLabel.setText(MessageManager.getString("label.font"));
- fontSizeCB.setFont(verdana11);
- fontSizeCB.setBounds(new Rectangle(319, 104, 49, 23));
- fontStyleCB.setFont(verdana11);
- fontStyleCB.setBounds(new Rectangle(367, 104, 70, 23));
- fontNameCB.setFont(verdana11);
- fontNameCB.setBounds(new Rectangle(172, 104, 147, 23));
- gapSymbolCB.setFont(verdana11);
- gapSymbolCB.setBounds(new Rectangle(172, 204, 69, 23));
- mincolourLabel.setFont(verdana11);
- mincolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
- mincolourLabel.setText(MessageManager.getString("label.min_colour"));
- minColour.setFont(verdana11);
- minColour.setBorder(BorderFactory.createEtchedBorder());
- minColour.setPreferredSize(new Dimension(40, 20));
- minColour.addMouseListener(new MouseAdapter()
- {
- public void mousePressed(MouseEvent e)
- {
- minColour_actionPerformed();
- }
- });
- maxcolourLabel.setFont(verdana11);
- maxcolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
- maxcolourLabel.setText(MessageManager.getString("label.max_colour"));
- maxColour.setFont(verdana11);
- maxColour.setBorder(BorderFactory.createEtchedBorder());
- maxColour.setPreferredSize(new Dimension(40, 20));
- maxColour.addMouseListener(new MouseAdapter()
- {
- public void mousePressed(MouseEvent e)
- {
- maxColour_actionPerformed();
- }
- });
-
- startupCheckbox.setText(MessageManager.getString("action.open_file"));
- startupCheckbox.setFont(verdana11);
- startupCheckbox.setHorizontalAlignment(SwingConstants.RIGHT);
- startupCheckbox.setHorizontalTextPosition(SwingConstants.LEFT);
- startupCheckbox.setSelected(true);
- startupFileTextfield.setFont(verdana11);
- startupFileTextfield.setBounds(new Rectangle(172, 273, 270, 20));
- startupFileTextfield.addMouseListener(new MouseAdapter()
- {
- public void mouseClicked(MouseEvent e)
- {
- if (e.getClickCount() > 1)
- {
- startupFileTextfield_mouseClicked();
- }
+ userIdWidth_actionPerformed();
}
});
+ jPanel11.add(jLabel1);
+ jPanel11.add(blcjv);
+ jPanel11.add(clustaljv);
+ jPanel11.add(fastajv);
+ jPanel11.add(msfjv);
+ jPanel11.add(pfamjv);
+ jPanel11.add(pileupjv);
+ jPanel11.add(pirjv);
+ outputTab.add(autoIdWidth);
+ outputTab.add(userIdWidth);
+ outputTab.add(userIdWidthlabel);
+ outputTab.add(modellerOutput);
+ outputTab.add(epsLabel);
+ outputTab.add(epsRendering);
+ outputTab.add(jPanel11);
+ modellerOutput.setFont(verdana11);
+ modellerOutput.setText(MessageManager
+ .getString("label.use_modeller_output"));
+ modellerOutput.setBounds(new Rectangle(228, 226, 168, 23));
+ return outputTab;
+ }
- connectTab.setLayout(gridBagLayout3);
+ /**
+ * Initialises the Connections tabbed panel.
+ *
+ * @return
+ */
+ private JPanel initConnectionsTab()
+ {
+ JPanel connectTab = new JPanel();
+ connectTab.setLayout(new GridBagLayout());
+ JLabel serverLabel = new JLabel();
serverLabel.setText(MessageManager.getString("label.address"));
serverLabel.setHorizontalAlignment(SwingConstants.RIGHT);
serverLabel.setFont(verdana11);
proxyServerTB.setFont(verdana11);
proxyPortTB.setFont(verdana11);
+ JLabel portLabel = new JLabel();
portLabel.setFont(verdana11);
portLabel.setHorizontalAlignment(SwingConstants.RIGHT);
portLabel.setText(MessageManager.getString("label.port"));
+ JLabel browserLabel = new JLabel();
browserLabel.setFont(new java.awt.Font("SansSerif", 0, 11));
browserLabel.setHorizontalAlignment(SwingConstants.TRAILING);
browserLabel.setText(MessageManager
versioncheck.setFont(verdana11);
versioncheck.setHorizontalAlignment(SwingConstants.RIGHT);
versioncheck.setHorizontalTextPosition(SwingConstants.LEADING);
+ JButton newLink = new JButton();
newLink.setText(MessageManager.getString("action.new"));
newLink.addActionListener(new java.awt.event.ActionListener()
{
newLink_actionPerformed(e);
}
});
+ JButton editLink = new JButton();
editLink.setText(MessageManager.getString("action.edit"));
editLink.addActionListener(new java.awt.event.ActionListener()
{
editLink_actionPerformed(e);
}
});
+ JButton deleteLink = new JButton();
deleteLink.setText(MessageManager.getString("action.delete"));
deleteLink.addActionListener(new java.awt.event.ActionListener()
{
}
});
+ JScrollPane linkScrollPane = new JScrollPane();
linkScrollPane.setBorder(null);
+ JPanel linkPanel = new JPanel();
linkPanel.setBorder(new TitledBorder(MessageManager
.getString("label.url_linkfrom_sequence_id")));
- linkPanel.setLayout(borderLayout2);
+ linkPanel.setLayout(new BorderLayout());
+ GridLayout gridLayout1 = new GridLayout();
+ JPanel editLinkButtons = new JPanel();
editLinkButtons.setLayout(gridLayout1);
gridLayout1.setRows(3);
linkNameList.setFont(verdana11);
linkNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ BorderLayout borderLayout3 = new BorderLayout();
+ JPanel linkPanel2 = new JPanel();
linkPanel2.setLayout(borderLayout3);
linkURLList.setFont(verdana11);
linkURLList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
useProxy_actionPerformed();
}
});
+ linkPanel.add(editLinkButtons, BorderLayout.EAST);
+ editLinkButtons.add(newLink, null);
+ editLinkButtons.add(editLink, null);
+ editLinkButtons.add(deleteLink, null);
+ linkPanel.add(linkScrollPane, BorderLayout.CENTER);
+ linkScrollPane.getViewport().add(linkPanel2, null);
+ linkPanel2.add(linkURLList, BorderLayout.CENTER);
+ linkPanel2.add(linkNameList, BorderLayout.WEST);
+ JPanel jPanel1 = new JPanel();
+ TitledBorder titledBorder1 = new TitledBorder(
+ MessageManager.getString("label.proxy_server"));
jPanel1.setBorder(titledBorder1);
- jPanel1.setLayout(gridBagLayout1);
- sortby.setFont(verdana11);
- sortby.setBounds(new Rectangle(172, 249, 155, 21));
- sortLabel.setFont(verdana11);
- sortLabel.setHorizontalAlignment(SwingConstants.RIGHT);
- sortLabel.setText(MessageManager.getString("label.sort_by"));
- jPanel2.setBounds(new Rectangle(7, 17, 158, 278));
- jPanel2.setLayout(gridLayout2);
- gridLayout2.setRows(12);
- exportTab.setLayout(null);
- epsLabel.setFont(verdana11);
- epsLabel.setHorizontalAlignment(SwingConstants.RIGHT);
- epsLabel.setText(MessageManager.getString("label.eps_rendering_style"));
- epsLabel.setBounds(new Rectangle(9, 31, 140, 24));
- epsRendering.setFont(verdana11);
- epsRendering.setBounds(new Rectangle(154, 34, 187, 21));
- jLabel1.setFont(verdana11);
- jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
- jLabel1.setText(MessageManager.getString("label.append_start_end"));
- jLabel1.setFont(verdana11);
- fastajv.setFont(verdana11);
- fastajv.setHorizontalAlignment(SwingConstants.LEFT);
- clustaljv.setText(MessageManager.getString("label.clustal") + " ");
- blcjv.setText(MessageManager.getString("label.blc") + " ");
- fastajv.setText(MessageManager.getString("label.fasta") + " ");
- msfjv.setText(MessageManager.getString("label.msf") + " ");
- pfamjv.setText(MessageManager.getString("label.pfam") + " ");
- pileupjv.setText(MessageManager.getString("label.pileup") + " ");
- msfjv.setFont(verdana11);
- msfjv.setHorizontalAlignment(SwingConstants.LEFT);
- pirjv.setText(MessageManager.getString("label.pir") + " ");
- jPanel11.setFont(verdana11);
- jPanel11.setBorder(titledBorder2);
- jPanel11.setBounds(new Rectangle(30, 72, 196, 182));
- jPanel11.setLayout(gridLayout3);
- blcjv.setFont(verdana11);
- blcjv.setHorizontalAlignment(SwingConstants.LEFT);
- clustaljv.setFont(verdana11);
- clustaljv.setHorizontalAlignment(SwingConstants.LEFT);
- pfamjv.setFont(verdana11);
- pfamjv.setHorizontalAlignment(SwingConstants.LEFT);
- pileupjv.setFont(verdana11);
- pileupjv.setHorizontalAlignment(SwingConstants.LEFT);
- pirjv.setFont(verdana11);
- pirjv.setHorizontalAlignment(SwingConstants.LEFT);
- seqLimit.setFont(verdana11);
- seqLimit.setHorizontalAlignment(SwingConstants.RIGHT);
- seqLimit.setHorizontalTextPosition(SwingConstants.LEFT);
- seqLimit.setText(MessageManager.getString("label.full_sequence_id"));
- gridLayout3.setRows(8);
- smoothFont.setFont(verdana11);
- smoothFont.setHorizontalAlignment(SwingConstants.RIGHT);
- smoothFont.setHorizontalTextPosition(SwingConstants.LEADING);
- smoothFont.setText(MessageManager.getString("label.smooth_font"));
- calcTab.setLayout(null);
- autoCalculateConsCheck.setFont(JvSwingUtils.getLabelFont());
- autoCalculateConsCheck.setText(MessageManager
- .getString("label.autocalculate_consensus"));
- autoCalculateConsCheck.setBounds(new Rectangle(21, 52, 209, 23));
- padGaps.setFont(JvSwingUtils.getLabelFont());
- padGaps.setText(MessageManager.getString("label.pad_gaps_when_editing"));
- padGaps.setBounds(new Rectangle(22, 94, 168, 23));
- sortByTree.setFont(JvSwingUtils.getLabelFont());
- sortByTree
- .setText(MessageManager.getString("label.sort_with_new_tree"));
- sortByTree
- .setToolTipText(MessageManager
- .getString("label.any_trees_calculated_or_loaded_alignment_automatically_sort"));
- sortByTree.setBounds(new Rectangle(22, 136, 168, 23));
-
- autoIdWidth.setFont(JvSwingUtils.getLabelFont());
- autoIdWidth.setText(MessageManager
- .getString("label.automatically_set_id_width"));
- autoIdWidth
- .setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip("Adjusts the width of the generated EPS or PNG file to ensure even the longest sequence ID or annotation label is displayed")
- + "</html>");
- autoIdWidth.setBounds(new Rectangle(228, 96, 188, 23));
- autoIdWidth.addActionListener(new ActionListener()
- {
+ jPanel1.setLayout(new GridBagLayout());
+ jPanel1.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
+ 2, 4, 0), 5, 0));
+ jPanel1.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
+ 0, 4, 0), 11, 6));
+ connectTab.add(linkPanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0,
+ GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
+ 16, 0, 0, 12), 359, -17));
+ connectTab.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0,
+ GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
+ 21, 0, 35, 12), 4, 6));
+ connectTab.add(browserLabel, new GridBagConstraints(0, 1, 1, 1, 0.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
+ new Insets(16, 0, 0, 0), 5, 1));
+ jPanel1.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
+ 2, 5, 185), 2, -4));
+ jPanel1.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 4, 2), 54, 1));
+ jPanel1.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 4, 0), 263, 1));
+ connectTab.add(defaultBrowser, new GridBagConstraints(1, 1, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(15, 0, 0, 15), 307, 1));
+ connectTab.add(usagestats, new GridBagConstraints(0, 4, 1, 1, 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 4, 2), 70, 1));
+ connectTab.add(questionnaire, new GridBagConstraints(1, 4, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 4, 2), 70, 1));
+ connectTab.add(versioncheck, new GridBagConstraints(0, 5, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 4, 2), 70, 1));
+ return connectTab;
+ }
- @Override
+ /**
+ * Initialises the parent panel which contains the tabbed sections.
+ *
+ * @return
+ */
+ private JPanel initOkCancelPanel()
+ {
+ JButton ok = new JButton();
+ ok.setText(MessageManager.getString("action.ok"));
+ ok.addActionListener(new ActionListener()
+ {
public void actionPerformed(ActionEvent e)
{
- autoIdWidth_actionPerformed();
+ ok_actionPerformed(e);
}
});
- userIdWidthlabel.setFont(JvSwingUtils.getLabelFont());
- userIdWidthlabel.setText(MessageManager
- .getString("label.figure_id_column_width"));
- userIdWidth
- .setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip("Manually specify the width of the left hand column where sequence IDs and annotation labels will be rendered in exported alignment figures. This setting will be ignored if 'Automatically set ID width' is set")
- + "</html>");
- userIdWidthlabel
- .setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip("Manually specify the width of the left hand column where sequence IDs and annotation labels will be rendered in exported alignment figures. This setting will be ignored if 'Automatically set ID width' is set")
- + "</html>");
- userIdWidthlabel.setBounds(new Rectangle(236, 120, 168, 23));
- userIdWidth.setFont(JvSwingUtils.getTextAreaFont());
- userIdWidth.setText("");
- userIdWidth.setBounds(new Rectangle(232, 144, 84, 23));
- userIdWidth.addActionListener(new ActionListener()
+ JButton cancel = new JButton();
+ cancel.setText(MessageManager.getString("action.cancel"));
+ cancel.addActionListener(new ActionListener()
{
+ public void actionPerformed(ActionEvent e)
+ {
+ cancel_actionPerformed(e);
+ }
+ });
+ JPanel okCancelPanel = new JPanel();
+ okCancelPanel.add(ok);
+ okCancelPanel.add(cancel);
+ return okCancelPanel;
+ }
+ /**
+ * Initialises the Colours tabbed panel.
+ *
+ * @return
+ */
+ private JPanel initColoursTab()
+ {
+ JPanel coloursTab = new JPanel();
+ coloursTab.setBorder(new TitledBorder(MessageManager
+ .getString("action.open_new_alignment")));
+ coloursTab.setLayout(new FlowLayout());
+ JLabel mincolourLabel = new JLabel();
+ mincolourLabel.setFont(verdana11);
+ mincolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ mincolourLabel.setText(MessageManager.getString("label.min_colour"));
+ minColour.setFont(verdana11);
+ minColour.setBorder(BorderFactory.createEtchedBorder());
+ minColour.setPreferredSize(new Dimension(40, 20));
+ minColour.addMouseListener(new MouseAdapter()
+ {
+ public void mousePressed(MouseEvent e)
+ {
+ minColour_actionPerformed(minColour);
+ }
+ });
+ JLabel maxcolourLabel = new JLabel();
+ maxcolourLabel.setFont(verdana11);
+ maxcolourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ maxcolourLabel.setText(MessageManager.getString("label.max_colour"));
+ maxColour.setFont(verdana11);
+ maxColour.setBorder(BorderFactory.createEtchedBorder());
+ maxColour.setPreferredSize(new Dimension(40, 20));
+ maxColour.addMouseListener(new MouseAdapter()
+ {
+ public void mousePressed(MouseEvent e)
+ {
+ maxColour_actionPerformed(maxColour);
+ }
+ });
+ colour.setFont(verdana11);
+ colour.setBounds(new Rectangle(172, 225, 155, 21));
+ JLabel colourLabel = new JLabel();
+ colourLabel.setFont(verdana11);
+ colourLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ colourLabel.setText(MessageManager.getString("label.alignment_colour")
+ + " ");
+ JvSwingUtils.addtoLayout(coloursTab, MessageManager
+ .getString("label.default_colour_scheme_for_alignment"),
+ colourLabel, colour);
+ JPanel annotationShding = new JPanel();
+ annotationShding.setBorder(new TitledBorder(MessageManager
+ .getString("label.annotation_shading_default")));
+ annotationShding.setLayout(new GridLayout(1, 2));
+ JvSwingUtils.addtoLayout(annotationShding, MessageManager
+ .getString("label.default_minimum_colour_annotation_shading"),
+ mincolourLabel, minColour);
+ JvSwingUtils.addtoLayout(annotationShding, MessageManager
+ .getString("label.default_maximum_colour_annotation_shading"),
+ maxcolourLabel, maxColour);
+ coloursTab.add(annotationShding); // , FlowLayout.LEFT);
+ return coloursTab;
+ }
+
+ /**
+ * Initialises the Structure tabbed panel.
+ *
+ * @return
+ */
+ private JPanel initStructureTab()
+ {
+ JPanel structureTab = new JPanel();
+ structureTab.setBorder(new TitledBorder(MessageManager
+ .getString("label.structure_options")));
+ structureTab.setLayout(null);
+ final int width = 400;
+ final int height = 23;
+ final int lineSpacing = 30;
+ int ypos = 30;
+
+ structFromPdb.setFont(verdana11);
+ structFromPdb.setText(MessageManager.getString("label.struct_from_pdb"));
+ structFromPdb.setBounds(new Rectangle(5, ypos, width, height));
+ structFromPdb.addActionListener(new ActionListener()
+ {
@Override
public void actionPerformed(ActionEvent e)
{
- userIdWidth_actionPerformed();
+ boolean selected = structFromPdb.isSelected();
+ // enable other options only when the first is checked
+ useRnaView.setEnabled(selected);
+ addSecondaryStructure.setEnabled(selected);
+ addTempFactor.setEnabled(selected);
}
});
- modellerOutput.setFont(JvSwingUtils.getLabelFont());
- modellerOutput.setText(MessageManager
- .getString("label.use_modeller_output"));
- modellerOutput.setBounds(new Rectangle(228, 226, 168, 23));
+ structureTab.add(structFromPdb);
+
+ // indent checkboxes that are conditional on the first one
+ ypos += lineSpacing;
+ useRnaView.setFont(verdana11);
+ useRnaView.setText(MessageManager.getString("label.use_rnaview"));
+ useRnaView.setBounds(new Rectangle(25, ypos, width, height));
+ structureTab.add(useRnaView);
+
+ ypos += lineSpacing;
+ addSecondaryStructure.setFont(verdana11);
+ addSecondaryStructure.setText(MessageManager
+ .getString("label.autoadd_secstr"));
+ addSecondaryStructure.setBounds(new Rectangle(25, ypos, width, height));
+ structureTab.add(addSecondaryStructure);
+
+ ypos += lineSpacing;
+ addTempFactor.setFont(verdana11);
+ addTempFactor.setText(MessageManager.getString("label.autoadd_temp"));
+ addTempFactor.setBounds(new Rectangle(25, ypos, width, height));
+ structureTab.add(addTempFactor);
+
+ ypos += lineSpacing;
+ JLabel viewerLabel = new JLabel();
+ viewerLabel.setFont(verdana11);
+ viewerLabel.setHorizontalAlignment(SwingConstants.LEFT);
+ viewerLabel.setText(MessageManager.getString("label.structure_viewer"));
+ viewerLabel.setBounds(new Rectangle(10, ypos, 200, height));
+ structureTab.add(viewerLabel);
+
+ structViewer.setFont(verdana11);
+ structViewer.setBounds(new Rectangle(160, ypos, 120, height));
+ structViewer.addItem(Viewer.JMOL.name());
+ structViewer.addItem(Viewer.CHIMERA.name());
+ structureTab.add(structViewer);
+
+ ypos += lineSpacing;
+ JLabel pathLabel = new JLabel();
+ pathLabel.setFont(new java.awt.Font("SansSerif", 0, 11));
+ pathLabel.setHorizontalAlignment(SwingConstants.LEFT);
+ pathLabel.setText(MessageManager.getString("label.chimera_path"));
+ pathLabel.setToolTipText(MessageManager
+ .getString("label.chimera_path_tip"));
+ pathLabel.setBounds(new Rectangle(10, ypos, 140, height));
+ structureTab.add(pathLabel);
+
+ chimeraPath.setFont(verdana11);
+ chimeraPath.setText("");
+ chimeraPath.setBounds(new Rectangle(160, ypos, 300, height));
+ structureTab.add(chimeraPath);
+
+ return structureTab;
+ }
- dasPanel.setLayout(borderLayout4);
- wsPanel.setLayout(borderLayout5);
- wrap.setFont(JvSwingUtils.getLabelFont());
- wrap.setHorizontalAlignment(SwingConstants.TRAILING);
- wrap.setHorizontalTextPosition(SwingConstants.LEADING);
- wrap.setText(MessageManager.getString("label.wrap_alignment"));
- rightAlign.setFont(JvSwingUtils.getLabelFont());
- rightAlign.setForeground(Color.black);
- rightAlign.setHorizontalAlignment(SwingConstants.RIGHT);
- rightAlign.setHorizontalTextPosition(SwingConstants.LEFT);
- rightAlign.setText(MessageManager.getString("label.right_align_ids"));
- idItalics.setFont(JvSwingUtils.getLabelFont());
- idItalics.setHorizontalAlignment(SwingConstants.RIGHT);
- idItalics.setHorizontalTextPosition(SwingConstants.LEADING);
- idItalics.setText(MessageManager
- .getString("label.sequence_name_italics"));
- openoverv.setFont(JvSwingUtils.getLabelFont());
- openoverv.setActionCommand(MessageManager
- .getString("label.open_overview"));
- openoverv.setHorizontalAlignment(SwingConstants.RIGHT);
- openoverv.setHorizontalTextPosition(SwingConstants.LEFT);
- openoverv.setText(MessageManager.getString(("label.open_overview")));
- jPanel2.add(fullScreen);
- jPanel2.add(openoverv);
- jPanel2.add(seqLimit);
- jPanel2.add(rightAlign);
- jPanel2.add(fontLabel);
- jPanel2.add(showUnconserved);
- jPanel2.add(idItalics);
- jPanel2.add(smoothFont);
- jPanel2.add(gapLabel);
- jPanel2.add(wrap);
- jPanel2.add(sortLabel);
- jPanel2.add(startupCheckbox);
- visualTab.add(annotations);
- visualTab.add(startupFileTextfield);
- visualTab.add(sortby);
- visualTab.add(gapSymbolCB);
- visualTab.add(fontNameCB);
- visualTab.add(fontSizeCB);
- visualTab.add(fontStyleCB);
+ /**
+ * Initialises the Visual tabbed panel.
+ *
+ * @return
+ */
+ private JPanel initVisualTab()
+ {
+ JPanel visualTab = new JPanel();
+ visualTab.setBorder(new TitledBorder(MessageManager
+ .getString("action.open_new_alignment")));
+ visualTab.setLayout(null);
+ fullScreen.setFont(verdana11);
+ fullScreen.setHorizontalAlignment(SwingConstants.RIGHT);
+ fullScreen.setHorizontalTextPosition(SwingConstants.LEFT);
+ fullScreen.setText(MessageManager.getString("label.maximize_window"));
+ quality.setEnabled(false);
+ quality.setFont(verdana11);
+ quality.setHorizontalAlignment(SwingConstants.RIGHT);
+ quality.setHorizontalTextPosition(SwingConstants.LEFT);
+ quality.setSelected(true);
+ quality.setText(MessageManager.getString("label.quality"));
+ conservation.setEnabled(false);
+ conservation.setFont(verdana11);
+ conservation.setHorizontalAlignment(SwingConstants.RIGHT);
+ conservation.setHorizontalTextPosition(SwingConstants.LEFT);
+ conservation.setSelected(true);
+ conservation.setText(MessageManager.getString("label.conservation"));
+ identity.setEnabled(false);
+ identity.setFont(verdana11);
+ identity.setHorizontalAlignment(SwingConstants.RIGHT);
+ identity.setHorizontalTextPosition(SwingConstants.LEFT);
+ identity.setSelected(true);
+ identity.setText(MessageManager.getString("label.consensus"));
+ JLabel showGroupbits = new JLabel();
+ showGroupbits.setFont(verdana11);
+ showGroupbits.setHorizontalAlignment(SwingConstants.RIGHT);
+ showGroupbits.setHorizontalTextPosition(SwingConstants.LEFT);
+ showGroupbits.setText(MessageManager.getString("action.show_group")
+ + ":");
+ JLabel showConsensbits = new JLabel();
+ showConsensbits.setFont(verdana11);
+ showConsensbits.setHorizontalAlignment(SwingConstants.RIGHT);
+ showConsensbits.setHorizontalTextPosition(SwingConstants.LEFT);
+ showConsensbits.setText(MessageManager.getString("label.consensus")
+ + ":");
+ showConsensHistogram.setEnabled(false);
+ showConsensHistogram.setFont(verdana11);
+ showConsensHistogram.setHorizontalAlignment(SwingConstants.RIGHT);
+ showConsensHistogram.setHorizontalTextPosition(SwingConstants.LEFT);
+ showConsensHistogram.setSelected(true);
+ showConsensHistogram.setText(MessageManager
+ .getString("label.histogram"));
+ showConsensLogo.setEnabled(false);
+ showConsensLogo.setFont(verdana11);
+ showConsensLogo.setHorizontalAlignment(SwingConstants.RIGHT);
+ showConsensLogo.setHorizontalTextPosition(SwingConstants.LEFT);
+ showConsensLogo.setSelected(true);
+ showConsensLogo.setText(MessageManager.getString("label.logo"));
+ showGroupConsensus.setEnabled(false);
+ showGroupConsensus.setFont(verdana11);
+ showGroupConsensus.setHorizontalAlignment(SwingConstants.RIGHT);
+ showGroupConsensus.setHorizontalTextPosition(SwingConstants.LEFT);
+ showGroupConsensus.setSelected(true);
+ showGroupConsensus.setText(MessageManager.getString("label.consensus"));
+ showGroupConservation.setEnabled(false);
+ showGroupConservation.setFont(verdana11);
+ showGroupConservation.setHorizontalAlignment(SwingConstants.RIGHT);
+ showGroupConservation.setHorizontalTextPosition(SwingConstants.LEFT);
+ showGroupConservation.setSelected(true);
+ showGroupConservation.setText(MessageManager
+ .getString("label.conservation"));
+ showNpTooltip.setEnabled(true);
+ showNpTooltip.setFont(verdana11);
+ showNpTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
+ showNpTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
+ showNpTooltip.setSelected(true);
+ showNpTooltip.setText(MessageManager
+ .getString("label.non_positional_features"));
+ showDbRefTooltip.setEnabled(true);
+ showDbRefTooltip.setFont(verdana11);
+ showDbRefTooltip.setHorizontalAlignment(SwingConstants.RIGHT);
+ showDbRefTooltip.setHorizontalTextPosition(SwingConstants.LEFT);
+ showDbRefTooltip.setSelected(true);
+ showDbRefTooltip.setText(MessageManager
+ .getString("label.database_references"));
+ annotations.setFont(verdana11);
+ annotations.setHorizontalAlignment(SwingConstants.RIGHT);
+ annotations.setHorizontalTextPosition(SwingConstants.LEADING);
+ annotations.setSelected(true);
+ annotations.setText(MessageManager.getString("label.show_annotations"));
+ annotations.setBounds(new Rectangle(169, 12, 200, 23));
+ annotations.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ annotations_actionPerformed(e);
+ }
+ });
+ identity.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ annotations_actionPerformed(e);
+ }
+ });
+ showGroupConsensus.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ annotations_actionPerformed(e);
+ }
+ });
+ showUnconserved.setFont(verdana11);
+ showUnconserved.setHorizontalAlignment(SwingConstants.RIGHT);
+ showUnconserved.setHorizontalTextPosition(SwingConstants.LEFT);
+ showUnconserved.setSelected(true);
+ showUnconserved.setText(MessageManager
+ .getString("action.show_unconserved"));
+ showUnconserved.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ showunconserved_actionPerformed(e);
+ }
+ });
+
+ // TODO these are not yet added to / action from Preferences
+ // JCheckBox shareSelections = new JCheckBox();
+ // shareSelections.setFont(verdana11);
+ // shareSelections.setHorizontalAlignment(SwingConstants.RIGHT);
+ // shareSelections.setHorizontalTextPosition(SwingConstants.LEFT);
+ // shareSelections.setSelected(true);
+ // shareSelections.setText(MessageManager
+ // .getString("label.share_selection_across_views"));
+ // JCheckBox followHighlight = new JCheckBox();
+ // followHighlight.setFont(verdana11);
+ // followHighlight.setHorizontalAlignment(SwingConstants.RIGHT);
+ // followHighlight.setHorizontalTextPosition(SwingConstants.LEFT);
+ // // showUnconserved.setBounds(new Rectangle(169, 40, 200, 23));
+ // followHighlight.setSelected(true);
+ // followHighlight.setText(MessageManager
+ // .getString("label.scroll_highlighted_regions"));
+
+ seqLimit.setFont(verdana11);
+ seqLimit.setHorizontalAlignment(SwingConstants.RIGHT);
+ seqLimit.setHorizontalTextPosition(SwingConstants.LEFT);
+ seqLimit.setText(MessageManager.getString("label.full_sequence_id"));
+ smoothFont.setFont(verdana11);
+ smoothFont.setHorizontalAlignment(SwingConstants.RIGHT);
+ smoothFont.setHorizontalTextPosition(SwingConstants.LEADING);
+ smoothFont.setText(MessageManager.getString("label.smooth_font"));
+ JLabel gapLabel = new JLabel();
+ gapLabel.setFont(verdana11);
+ gapLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ gapLabel.setText(MessageManager.getString("label.gap_symbol") + " ");
+ JLabel fontLabel = new JLabel();
+ fontLabel.setFont(verdana11);
+ fontLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ fontLabel.setText(MessageManager.getString("label.font"));
+ fontSizeCB.setFont(verdana11);
+ fontSizeCB.setBounds(new Rectangle(320, 104, 65, 23));
+ fontStyleCB.setFont(verdana11);
+ fontStyleCB.setBounds(new Rectangle(382, 104, 80, 23));
+ fontNameCB.setFont(verdana11);
+ fontNameCB.setBounds(new Rectangle(172, 104, 147, 23));
+ gapSymbolCB.setFont(verdana11);
+ gapSymbolCB.setBounds(new Rectangle(172, 196, 69, 23));
+ DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
+ dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);
+ gapSymbolCB.setRenderer(dlcr);
+
+ startupCheckbox.setText(MessageManager.getString("action.open_file"));
+ startupCheckbox.setFont(verdana11);
+ startupCheckbox.setHorizontalAlignment(SwingConstants.RIGHT);
+ startupCheckbox.setHorizontalTextPosition(SwingConstants.LEFT);
+ startupCheckbox.setSelected(true);
+ startupFileTextfield.setFont(verdana11);
+ startupFileTextfield.setBounds(new Rectangle(172, 290, 270, 20));
+ startupFileTextfield.addMouseListener(new MouseAdapter()
+ {
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() > 1)
+ {
+ startupFileTextfield_mouseClicked();
+ }
+ }
+ });
+
+ sortby.setFont(verdana11);
+ sortby.setBounds(new Rectangle(172, 240, 155, 21));
+ JLabel sortLabel = new JLabel();
+ sortLabel.setFont(verdana11);
+ sortLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ sortLabel.setText(MessageManager.getString("label.sort_by"));
+ sortAnnBy.setFont(verdana11);
+ sortAnnBy.setBounds(new Rectangle(172, 265, 110, 21));
+ JLabel sortAnnLabel = new JLabel();
+ sortAnnLabel.setFont(verdana11);
+ sortAnnLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ sortAnnLabel.setText(MessageManager.getString("label.sort_ann_by"));
+ sortAutocalc.setFont(verdana11);
+ sortAutocalc.setBounds(new Rectangle(290, 265, 165, 21));
+ JPanel annsettingsPanel = new JPanel();
annsettingsPanel.setBounds(new Rectangle(173, 34, 300, 61));
annsettingsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
- annsettingsPanel.add(autoAnnotSettings1);
- annsettingsPanel.add(autoAnnotSettings2);
- annsettingsPanel.add(autoAnnotSettings3);
+ JPanel autoAnnotSettings1 = new JPanel();
autoAnnotSettings1.setLayout(new GridLayout(3, 1, 0, 0));
+ annsettingsPanel.add(autoAnnotSettings1);
+ JPanel autoAnnotSettings2 = new JPanel();
autoAnnotSettings2.setLayout(new GridLayout(3, 1, 0, 0));
+ annsettingsPanel.add(autoAnnotSettings2);
+ JPanel autoAnnotSettings3 = new JPanel();
autoAnnotSettings3.setLayout(new GridLayout(3, 1, 0, 0));
+ annsettingsPanel.add(autoAnnotSettings3);
visualTab.add(annsettingsPanel);
Border jb = new EmptyBorder(1, 1, 4, 5);
quality.setBorder(jb);
tooltipSettings.add(showDbRefTooltip);
tooltipSettings.add(showNpTooltip);
visualTab.add(tooltipSettings);
- visualTab.add(jPanel2);
- JvSwingUtils.addtoLayout(visual2Tab, MessageManager
- .getString("label.default_colour_scheme_for_alignment"),
- colourLabel, colour);
- JPanel annotationShding = new JPanel();
- annotationShding.setBorder(new TitledBorder(MessageManager
- .getString("label.annotation_shading_default")));
- annotationShding.setLayout(new GridLayout(1, 2));
- JvSwingUtils.addtoLayout(annotationShding, MessageManager
- .getString("label.default_minimum_colour_annotation_shading"),
- mincolourLabel, minColour);
- JvSwingUtils.addtoLayout(annotationShding, MessageManager
- .getString("label.default_maximum_colour_annotation_shading"),
- maxcolourLabel, maxColour);
- visual2Tab.add(annotationShding); // , FlowLayout.LEFT);
-
- // visual2panel.add(minColour);
- // visual2panel.add(maxColour);
- // visual2Tab.add(visual2panel);
- linkPanel.add(editLinkButtons, BorderLayout.EAST);
- editLinkButtons.add(newLink, null);
- editLinkButtons.add(editLink, null);
- editLinkButtons.add(deleteLink, null);
- linkPanel.add(linkScrollPane, BorderLayout.CENTER);
- linkScrollPane.getViewport().add(linkPanel2, null);
- linkPanel2.add(linkURLList, BorderLayout.CENTER);
- linkPanel2.add(linkNameList, BorderLayout.WEST);
- okCancelPanel.add(ok);
- okCancelPanel.add(cancel);
- this.add(tabbedPane, java.awt.BorderLayout.CENTER);
-
- this.add(okCancelPanel, java.awt.BorderLayout.SOUTH);
- jPanel1.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
- 2, 4, 0), 5, 0));
- jPanel1.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
- 0, 4, 0), 11, 6));
- connectTab.add(linkPanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0,
- GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
- 16, 0, 0, 12), 359, -17));
- connectTab.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0,
- GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
- 21, 0, 35, 12), 4, 6));
- connectTab.add(browserLabel, new GridBagConstraints(0, 1, 1, 1, 0.0,
- 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
- new Insets(16, 0, 0, 0), 5, 1));
- jPanel1.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 54, 1));
- jPanel1.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 0), 263, 1));
- connectTab.add(defaultBrowser, new GridBagConstraints(1, 1, 1, 1, 1.0,
- 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(15, 0, 0, 15), 307, 1));
- connectTab.add(usagestats, new GridBagConstraints(0, 4, 1, 1, 1.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 70, 1));
- connectTab.add(questionnaire, new GridBagConstraints(1, 4, 1, 1, 1.0,
- 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 70, 1));
- connectTab.add(versioncheck, new GridBagConstraints(0, 5, 1, 1, 1.0,
- 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 70, 1));
-
- jPanel1.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
- 2, 5, 185), 2, -4));
- DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
- dlcr.setHorizontalAlignment(DefaultListCellRenderer.CENTER);
- gapSymbolCB.setRenderer(dlcr);
-
- tabbedPane.add(visualTab, MessageManager.getString("label.visual"));
- tabbedPane.add(visual2Tab, MessageManager.getString("label.colours"));
- tabbedPane.add(connectTab,
- MessageManager.getString("label.connections"));
- tabbedPane.add(exportTab, MessageManager.getString("label.output"));
- jPanel11.add(jLabel1);
- jPanel11.add(blcjv);
- jPanel11.add(clustaljv);
- jPanel11.add(fastajv);
- jPanel11.add(msfjv);
- jPanel11.add(pfamjv);
- jPanel11.add(pileupjv);
- jPanel11.add(pirjv);
- exportTab.add(autoIdWidth);
- exportTab.add(userIdWidth);
- exportTab.add(userIdWidthlabel);
- exportTab.add(modellerOutput);
- tabbedPane.add(calcTab, MessageManager.getString("label.editing"));
- calcTab.add(autoCalculateConsCheck);
- calcTab.add(padGaps);
- calcTab.add(sortByTree);
-
- tabbedPane
- .add(dasPanel, MessageManager.getString("label.das_settings"));
- tabbedPane.add(wsPanel, MessageManager.getString("label.web_services"));
-
- exportTab.add(epsLabel);
- exportTab.add(epsRendering);
- exportTab.add(jPanel11);
+ wrap.setFont(verdana11);
+ wrap.setHorizontalAlignment(SwingConstants.TRAILING);
+ wrap.setHorizontalTextPosition(SwingConstants.LEADING);
+ wrap.setText(MessageManager.getString("label.wrap_alignment"));
+ rightAlign.setFont(verdana11);
+ rightAlign.setForeground(Color.black);
+ rightAlign.setHorizontalAlignment(SwingConstants.RIGHT);
+ rightAlign.setHorizontalTextPosition(SwingConstants.LEFT);
+ rightAlign.setText(MessageManager.getString("label.right_align_ids"));
+ idItalics.setFont(verdana11);
+ idItalics.setHorizontalAlignment(SwingConstants.RIGHT);
+ idItalics.setHorizontalTextPosition(SwingConstants.LEADING);
+ idItalics.setText(MessageManager
+ .getString("label.sequence_name_italics"));
+ openoverv.setFont(verdana11);
+ openoverv.setActionCommand(MessageManager
+ .getString("label.open_overview"));
+ openoverv.setHorizontalAlignment(SwingConstants.RIGHT);
+ openoverv.setHorizontalTextPosition(SwingConstants.LEFT);
+ openoverv.setText(MessageManager.getString(("label.open_overview")));
+ JPanel jPanel2 = new JPanel();
+ jPanel2.setBounds(new Rectangle(7, 17, 158, 297));
+ GridLayout gridLayout2 = new GridLayout();
+ jPanel2.setLayout(gridLayout2);
+ gridLayout2.setRows(13);
+ jPanel2.add(fullScreen);
+ jPanel2.add(openoverv);
+ jPanel2.add(seqLimit);
+ jPanel2.add(rightAlign);
+ jPanel2.add(fontLabel);
+ jPanel2.add(showUnconserved);
+ jPanel2.add(idItalics);
+ jPanel2.add(smoothFont);
+ jPanel2.add(gapLabel);
+ jPanel2.add(wrap);
+ jPanel2.add(sortLabel);
+ jPanel2.add(sortAnnLabel);
+ jPanel2.add(startupCheckbox);
+ visualTab.add(jPanel2);
+ visualTab.add(annotations);
+ visualTab.add(startupFileTextfield);
+ visualTab.add(sortby);
+ visualTab.add(sortAnnBy);
+ visualTab.add(sortAutocalc);
+ visualTab.add(gapSymbolCB);
+ visualTab.add(fontNameCB);
+ visualTab.add(fontSizeCB);
+ visualTab.add(fontStyleCB);
+ return visualTab;
}
protected void autoIdWidth_actionPerformed()
}
- protected void maxColour_actionPerformed()
+ protected void maxColour_actionPerformed(JPanel panel)
{
- // TODO Auto-generated method stub
-
}
- protected void minColour_actionPerformed()
+ protected void minColour_actionPerformed(JPanel panel)
{
- // TODO Auto-generated method stub
-
}
protected void showunconserved_actionPerformed(ActionEvent e)
// cpanel.setLayout(new FlowLayout());
hSeparable = new JCheckBox(MessageManager.getString("label.per_seq"));
hSeparable
- .setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip("When checked, a job is created for every sequence in the current selection.")
- + "<html>");
+ .setToolTipText(JvSwingUtils
+ .wrapTooltip(true, MessageManager.getString("label.job_created_when_checked")));
hSeparable.addActionListener(new ActionListener()
{
vSeparable = new JCheckBox(
MessageManager.getString("label.result_vertically_separable"));
vSeparable
- .setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip("When checked, a single job is created for the visible region and results"
- + " mapped back onto their location in the alignment. Otherwise, a job would be"
- + " created for every contiguous region visible in the alignment or current"
- + " selection (e.g. a multiple alignment).")
- + "</html>");
+ .setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.getString("label.when_checked_job_visible_region_and_results")));
vSeparable.addActionListener(new ActionListener()
{
urldescPane.add(urldescVp, "span");
paste.add(urldescPane, "span");
urldescPane
- .setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip("Flat file representation of this rest service using the Really Simple Bioinformatics Service formalism"));
+ .setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.getString("label.flat_file_representation")));
parseRes = new JTextArea();
parseResVp = new JScrollPane();
parseWarnings.setBorder(new TitledBorder(MessageManager
.getString("label.parsing_errors")));
parseWarnings
- .setToolTipText("<html>"
- + JvSwingUtils
- .wrapTooltip("Results of parsing the RSBS representation")
- + "</html>");
+ .setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.getString("label.result_of_parsing_rsbs")));
parseWarnings.add(parseResVp, "center");
parseRes.setEditable(false);
paste.add(parseWarnings, "span");
jLabel2.setText(MessageManager.getString("label.url"));
jLabel2.setBounds(new Rectangle(17, 37, 54, 27));
jLabel3.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
- jLabel3.setText("Use $SEQUENCE_ID$ or $SEQUENCE_ID=/<regex>/=$");
+ jLabel3.setText(MessageManager.getString("label.use_sequence_id_1"));
jLabel3.setBounds(new Rectangle(21, 72, 351, 15));
jLabel4.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
- jLabel4.setText("\nto embed sequence id in URL");
+ jLabel4.setText(MessageManager.getString("label.use_sequence_id_2"));
jLabel4.setBounds(new Rectangle(21, 93, 351, 15));
jPanel1.setBorder(BorderFactory.createEtchedBorder());
jPanel1.setLayout(null);
JOptionPane
.showInternalMessageDialog(
jalview.gui.Desktop.desktop,
- "Sequence URL must contain $SEQUENCE_ID$ or a regex $SEQUENCE_ID=/<regex>/=$",
- "URL not valid", JOptionPane.WARNING_MESSAGE);
+ MessageManager.getString("warn.url_must_contain"),
+ MessageManager.getString("label.invalid_url"), JOptionPane.WARNING_MESSAGE);
return false;
}
import jalview.util.MessageManager;
-import javax.swing.*;
-import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JInternalFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JRadioButtonMenuItem;
public class GStructureViewer extends JInternalFrame
{
userColour_actionPerformed(actionEvent);
}
});
- jmolColour.setSelected(false);
- jmolColour.setText(MessageManager.getString("label.colour_with_jmol"));
- jmolColour.setToolTipText(MessageManager
+ viewerColour.setSelected(false);
+ viewerColour
+ .setText(MessageManager.getString("label.colour_with_jmol"));
+ viewerColour.setToolTipText(MessageManager
.getString("label.let_jmol_manage_structure_colours"));
- jmolColour.addActionListener(new ActionListener()
+ viewerColour.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent actionEvent)
{
- jmolColour_actionPerformed(actionEvent);
+ viewerColour_actionPerformed(actionEvent);
}
});
helpMenu.setText(MessageManager.getString("action.help"));
- jmolHelp.setText(MessageManager.getString("label.jmol_help"));
- jmolHelp.addActionListener(new ActionListener()
+ helpItem.setText(MessageManager.getString("label.jmol_help"));
+ helpItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent actionEvent)
{
- jmolHelp_actionPerformed(actionEvent);
+ showHelp_actionPerformed(actionEvent);
}
});
alignStructs
alignStructs_actionPerformed(actionEvent);
}
});
- jmolActionMenu.setText(MessageManager.getString("label.jmol"));
+ viewerActionMenu.setText(MessageManager.getString("label.jmol"));
menuBar.add(fileMenu);
menuBar.add(viewMenu);
menuBar.add(colourMenu);
- menuBar.add(jmolActionMenu);
- jmolActionMenu.setVisible(false);
+ menuBar.add(viewerActionMenu);
+ viewerActionMenu.setVisible(false);
menuBar.add(helpMenu);
fileMenu.add(savemenu);
fileMenu.add(viewMapping);
colourMenu.add(buriedColour);
colourMenu.add(purinePyrimidineColour);
colourMenu.add(userColour);
- colourMenu.add(jmolColour);
+ colourMenu.add(viewerColour);
colourMenu.add(backGround);
colourButtons.add(seqColour);
colourButtons.add(turnColour);
colourButtons.add(buriedColour);
colourButtons.add(userColour);
- colourButtons.add(jmolColour);
+ colourButtons.add(viewerColour);
- helpMenu.add(jmolHelp);
- jmolActionMenu.add(alignStructs);
+ helpMenu.add(helpItem);
+ viewerActionMenu.add(alignStructs);
}
- protected void jmolColour_actionPerformed(ActionEvent actionEvent)
+ protected void viewerColour_actionPerformed(ActionEvent actionEvent)
{
}
protected JMenu colourMenu = new JMenu();
- protected JMenu jmolActionMenu = new JMenu();
+ protected JMenu viewerActionMenu = new JMenu();
protected JMenuItem alignStructs = new JMenuItem();
protected JRadioButtonMenuItem userColour = new JRadioButtonMenuItem();
- protected JRadioButtonMenuItem jmolColour = new JRadioButtonMenuItem();
+ protected JRadioButtonMenuItem viewerColour = new JRadioButtonMenuItem();
protected ButtonGroup colourButtons = new ButtonGroup();
JMenu helpMenu = new JMenu();
- JMenuItem jmolHelp = new JMenuItem();
+ protected JMenuItem helpItem = new JMenuItem();
public void pdbFile_actionPerformed(ActionEvent actionEvent)
{
}
- public void jmolHelp_actionPerformed(ActionEvent actionEvent)
+ public void showHelp_actionPerformed(ActionEvent actionEvent)
{
}
import java.awt.*;
import java.awt.event.*;
+
import javax.swing.*;
+import javax.swing.colorchooser.AbstractColorChooserPanel;
/**
* DOCUMENT ME!
jPanel4.add(panel1, java.awt.BorderLayout.CENTER);
this.add(jPanel4, java.awt.BorderLayout.CENTER);
this.add(colorChooser, java.awt.BorderLayout.EAST);
+
+ AbstractColorChooserPanel[] choosers = colorChooser.getChooserPanels();
+ // JAL-1360 larger JColorChooser in Java 7 overwrites AA panel; restrict to swatch picker only
+ if (choosers.length > 3) {
+ // Java 7 default has 5 options rather than 3 for choosing colours; keep the first only
+ colorChooser.setChooserPanels(new AbstractColorChooserPanel[]{choosers[0]});
+ }
}
/**
--- /dev/null
+package jalview.json.binding.v1;
+
+import jalview.schemes.Blosum62ColourScheme;
+import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.HelixColourScheme;
+import jalview.schemes.HydrophobicColourScheme;
+import jalview.schemes.NucleotideColourScheme;
+import jalview.schemes.PIDColourScheme;
+import jalview.schemes.PurinePyrimidineColourScheme;
+import jalview.schemes.RNAInteractionColourScheme;
+import jalview.schemes.StrandColourScheme;
+import jalview.schemes.TaylorColourScheme;
+import jalview.schemes.TurnColourScheme;
+import jalview.schemes.ZappoColourScheme;
+
+import java.util.ArrayList;
+
+public class BioJsAlignmentPojo
+{
+ private String globalColorScheme = "none";
+ private ArrayList<BioJsSeqPojo> seqs = new ArrayList<BioJsSeqPojo>();
+
+ public BioJsAlignmentPojo()
+ {
+
+ }
+ public ArrayList<BioJsSeqPojo> getSeqs()
+ {
+ return seqs;
+ }
+
+ public void setSeqs(ArrayList<BioJsSeqPojo> seqs)
+ {
+ this.seqs = seqs;
+ }
+ public String getGlobalColorScheme()
+ {
+ return globalColorScheme;
+ }
+ public void setGlobalColorScheme(String globalColorScheme)
+ {
+ for (JalviewBioJsColorSchemeMapper cs : JalviewBioJsColorSchemeMapper
+ .values())
+ {
+ if (cs.getJalviewName().equals(globalColorScheme))
+ {
+ this.globalColorScheme = cs.getBioJsName();
+ break;
+ }
+ }
+
+ // JALVIEW colors not in biojs
+ // Blosum62
+ // T-Coffee Scores (almost same with Blosom62
+ // RNA Interaction type - no color applied
+ // RNA Helices - missing
+
+ // BIOJS Colour not in jalview
+ // schemes.push name: "Lesk", id: "lesk"
+ // schemes.push name: "Cinema", id: "cinema"
+ // schemes.push name: "MAE", id: "mae"
+ // schemes.push name: "Clustal2", id: "clustal2"
+
+ }
+
+
+ public enum JalviewBioJsColorSchemeMapper
+ {
+ USER_DEFINED("User Defined", "user defined", null), NONE("None", "foo",
+ null), CLUSTAL("Clustal", "clustal", null), ZAPPO("Zappo",
+ "zappo", new ZappoColourScheme()), TAYLOR(
+ "Taylor", "taylor", new TaylorColourScheme()), NUCLEOTIDE(
+ "Nucleotide", "nucleotide", new NucleotideColourScheme()), PURINE_PYRIMIDINE(
+ "Purine/Pyrimidine", "purine",
+ new PurinePyrimidineColourScheme()), HELIX_PROPENCITY(
+ "Helix Propensity", "helix", new HelixColourScheme()), TURN_PROPENSITY(
+ "Turn Propensity", "turn", new TurnColourScheme()), STRAND_PROPENSITY(
+ "Strand Propensity", "strand", new StrandColourScheme()), BURIED_INDEX(
+ "Buried Index", "buried", new BuriedColourScheme()), HYDROPHOBIC(
+ "Hydrophobic", "hydro", new HydrophobicColourScheme()),
+
+ // The color types below are not yet supported by BioJs MSA viewer
+ T_COFFE_SCORES("T-Coffee Scores", "T-Coffee Scores",
+ null), RNA_INT_TYPE(
+ "RNA Interaction type", "RNA Interaction type",
+ new RNAInteractionColourScheme()), BLOSUM62("Blosum62",
+ "Blosum62", new Blosum62ColourScheme()), RNA_HELICES(
+ "RNA Helices", "RNA Helices", null), PERCENTAGE_IDENTITY(
+ "% Identity", "pid",
+ new PIDColourScheme());
+
+ private String jalviewName;
+ private String bioJsName;
+
+ private ColourSchemeI jvColourScheme;
+
+ private JalviewBioJsColorSchemeMapper(String jalviewName,
+ String bioJsName, ColourSchemeI jvColourScheme)
+ {
+ this.jalviewName = jalviewName;
+ this.bioJsName = bioJsName;
+ this.setJvColourScheme(jvColourScheme);
+ }
+
+ public String getJalviewName()
+ {
+ return jalviewName;
+ }
+
+ public String getBioJsName()
+ {
+ return bioJsName;
+ }
+
+ public ColourSchemeI getJvColourScheme()
+ {
+ return jvColourScheme;
+ }
+
+ public void setJvColourScheme(ColourSchemeI jvColourScheme)
+ {
+ this.jvColourScheme = jvColourScheme;
+ }
+
+ }
+}
--- /dev/null
+package jalview.json.binding.v1;
+
+public class BioJsFeaturePojo
+{
+
+ private int xstart;
+
+ private int xend;
+
+ private String text;
+
+ private String fillColor;
+
+ public BioJsFeaturePojo()
+ {
+ }
+
+
+ public String getText()
+ {
+ return text;
+ }
+
+ public void setText(String text)
+ {
+ this.text = text;
+ }
+
+ public String getFillColor()
+ {
+ return "#" + fillColor;
+ }
+
+ public void setFillColor(String fillColor)
+ {
+ this.fillColor = fillColor;
+ }
+
+ public int getXstart()
+ {
+ return xstart;
+ }
+
+ public void setXstart(int xstart)
+ {
+ this.xstart = xstart;
+ }
+
+ public int getXend()
+ {
+ return xend;
+ }
+
+ public void setXend(int xend)
+ {
+ this.xend = xend;
+ }
+
+
+}
--- /dev/null
+package jalview.json.binding.v1;
+
+import java.util.ArrayList;
+
+
+public class BioJsSeqPojo
+{
+ private String seq;
+
+ private String name;
+
+ private String id;
+
+ private int start;
+
+ private int end;
+
+ private ArrayList<BioJsFeaturePojo> features = new ArrayList<BioJsFeaturePojo>();
+
+ public BioJsSeqPojo()
+ {
+ }
+
+ public BioJsSeqPojo(int start, int end, String id, String name, String seq)
+ {
+ this.id = id;
+ this.name = name;
+ this.seq = seq;
+ }
+ public String getSeq()
+ {
+ return seq;
+ }
+
+ public void setSeq(String seq)
+ {
+ this.seq = seq;
+ }
+
+ public String getName()
+ {
+
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public void setId(String id)
+ {
+ this.id = id;
+ }
+
+ public int getStart()
+ {
+ return start;
+ }
+
+ public void setStart(int start)
+ {
+ this.start = start;
+ }
+
+ public int getEnd()
+ {
+ return end;
+ }
+
+ public void setEnd(int end)
+ {
+ this.end = end;
+ }
+
+ public ArrayList<BioJsFeaturePojo> getFeatures()
+ {
+ return features;
+ }
+
+ public void setFeatures(ArrayList<BioJsFeaturePojo> features)
+ {
+ this.features = features;
+ }
+}
if (iter == maxIter)
{
- throw new Exception("Too many iterations in tqli (" + maxIter
- + ")");
+ throw new Exception(MessageManager.formatMessage("exception.matrix_too_many_iteration", new String[]{"tqli", Integer.valueOf(maxIter).toString()}));
}
else
{
if (iter == maxIter)
{
- throw new Exception("Too many iterations in tqli2 (max is "
- + maxIter + ")");
+ throw new Exception(MessageManager.formatMessage("exception.matrix_too_many_iteration", new String[]{"tqli2", Integer.valueOf(maxIter).toString()}));
}
else
{
profcolour = av.getAlignment().isNucleotide() ? new jalview.schemes.NucleotideColourScheme()
: new jalview.schemes.ZappoColourScheme();
}
+ boolean rna = av.getAlignment().isNucleotide();
columnSelection = av.getColumnSelection();
hconsensus = av.getSequenceConsensusHash();// hconsensus;
hStrucConsensus = av.getRnaStructureConsensusHash(); // hStrucConsensus;
return null;
}
+ boolean rna = false;
+
/**
* Render the annotation rows associated with an alignment.
*
AlignmentAnnotation consensusAnnot = av
.getAlignmentConsensusAnnotation(), structConsensusAnnot = av
.getAlignmentStrucConsensusAnnotation();
- boolean renderHistogram = true, renderProfile = true, normaliseProfile = false;
+ boolean renderHistogram = true, renderProfile = true, normaliseProfile = false, isRNA = rna;
BitSet graphGroupDrawn = new BitSet();
int charOffset = 0; // offset for a label
for (int i = 0; i < aa.length; i++)
{
AlignmentAnnotation row = aa[i];
+ isRNA = row.isRNA();
{
// check if this is a consensus annotation row and set the display
// settings appropriately
// System.out.println("\t type :"+lastSS+"\t x :"+x+"\t nbre annot :"+nb_annot);
switch (lastSS)
{
-
- case '$':
- drawHelixAnnot(g, row_annotations, lastSSX, x, y,
- iconOffset, startRes, column, validRes, validEnd);
- break;
-
- case 0xCE:
- drawSheetAnnot(g, row_annotations, lastSSX, x, y,
- iconOffset, startRes, column, validRes, validEnd);
- break;
-
case '(': // Stem case for RNA secondary structure
case ')': // and opposite direction
drawStemAnnot(g, row_annotations, lastSSX, x, y,
iconOffset, startRes, column, validRes, validEnd);
temp = x;
break;
+
+ case 'H':
+ if (!isRNA)
+ {
+ drawHelixAnnot(g, row_annotations, lastSSX, x, y,
+ iconOffset, startRes, column, validRes,
+ validEnd);
+ break;
+ }
+
+ case 'E':
+ if (!isRNA)
+ {
+ drawSheetAnnot(g, row_annotations, lastSSX, x, y,
+ iconOffset, startRes, column, validRes,
+ validEnd);
+ break;
+ }
+
case '{':
case '}':
case '[':
case 'c':
case 'D':
case 'd':
- case 'E':
case 'e':
case 'F':
case 'f':
case 'G':
case 'g':
- case 'H':
case 'h':
case 'I':
case 'i':
{
switch (lastSS)
{
- case '$':
- drawHelixAnnot(g, row_annotations, lastSSX, x, y, iconOffset,
- startRes, column, validRes, validEnd);
- break;
- case 0xCE:
- drawSheetAnnot(g, row_annotations, lastSSX, x, y, iconOffset,
- startRes, column, validRes, validEnd);
- break;
- case 's':
- case 'S': // Stem case for RNA secondary structure
+ case 'H':
+ if (!isRNA)
+ {
+ drawHelixAnnot(g, row_annotations, lastSSX, x, y, iconOffset,
+ startRes, column, validRes, validEnd);
+ break;
+ }
+
+ case 'E':
+ if (!isRNA)
+ {
+ drawSheetAnnot(g, row_annotations, lastSSX, x, y, iconOffset,
+ startRes, column, validRes, validEnd);
+ break;
+ }
+
+ case '(':
+ case ')': // Stem case for RNA secondary structure
drawStemAnnot(g, row_annotations, lastSSX, x, y, iconOffset,
startRes, column, validRes, validEnd);
case 'c':
case 'D':
case 'd':
- case 'E':
case 'e':
case 'F':
case 'f':
case 'G':
case 'g':
- case 'H':
case 'h':
case 'I':
case 'i':
return !usedFaded;
}
- private final Color GLYPHLINE_COLOR = Color.gray;
+ public static final Color GLYPHLINE_COLOR = Color.gray;
- private final Color SHEET_COLOUR = Color.green;
+ public static final Color SHEET_COLOUR = Color.green;
- private final Color HELIX_COLOUR = Color.red;
+ public static final Color HELIX_COLOUR = Color.red;
- private final Color STEM_COLOUR = Color.blue;
+ public static final Color STEM_COLOUR = Color.blue;
private Color sdNOTCANONICAL_COLOUR;
-#Thu May 01 17:34:18 BST 2014
+#Fri Oct 31 16:47:51 GMT 2014
jalview.schemabinding.version2.ThresholdLine=jalview.schemabinding.version2.descriptors.ThresholdLineDescriptor
jalview.schemabinding.version2.SequenceSetProperties=jalview.schemabinding.version2.descriptors.SequenceSetPropertiesDescriptor
jalview.schemabinding.version2.StructureState=jalview.schemabinding.version2.descriptors.StructureStateDescriptor
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._alcodMapList.size())
{
- throw new IndexOutOfBoundsException("getAlcodMap: Index value '"
- + index + "' not in range [0.."
- + (this._alcodMapList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getAlcodMap",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._alcodMapList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.AlcodMap) _alcodMapList
// check bounds for index
if (index < 0 || index >= this._alcodonList.size())
{
- throw new IndexOutOfBoundsException("getAlcodon: Index value '"
- + index + "' not in range [0.."
- + (this._alcodonList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getAlcodon",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._alcodonList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.Alcodon) _alcodonList.get(index);
// check bounds for index
if (index < 0 || index >= this._alcodMapList.size())
{
- throw new IndexOutOfBoundsException("setAlcodMap: Index value '"
- + index + "' not in range [0.."
- + (this._alcodMapList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setAlcodMap",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._alcodonList.size() - 1)).toString()
+ }));
}
this._alcodMapList.set(index, vAlcodMap);
// check bounds for index
if (index < 0 || index >= this._alcodonList.size())
{
- throw new IndexOutOfBoundsException("setAlcodon: Index value '"
- + index + "' not in range [0.."
- + (this._alcodonList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setAlcodon",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._alcodonList.size() - 1)).toString()
+ }));
}
this._alcodonList.set(index, vAlcodon);
/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
- *
- * This file is part of Jalview.
- *
- * Jalview 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.
- *
- * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
+ * This class was automatically generated with
+ * <a href="http://www.castor.org">Castor 1.1</a>, using an XML
+ * Schema.
+ * $Id$
*/
+
package jalview.schemabinding.version2;
-//---------------------------------/
-//- Imported classes and packages -/
+ //---------------------------------/
+ //- Imported classes and packages -/
//---------------------------------/
import org.exolab.castor.xml.Marshaller;
*
* @version $Revision$ $Date$
*/
-public class Annotation implements java.io.Serializable
-{
-
- // --------------------------/
- // - Class/Member Variables -/
- // --------------------------/
-
- /**
- * Field _graph.
- */
- private boolean _graph;
-
- /**
- * keeps track of state for field: _graph
- */
- private boolean _has_graph;
-
- /**
- * Field _graphType.
- */
- private int _graphType;
-
- /**
- * keeps track of state for field: _graphType
- */
- private boolean _has_graphType;
-
- /**
- * Field _sequenceRef.
- */
- private java.lang.String _sequenceRef;
-
- /**
- * Field _groupRef.
- */
- private java.lang.String _groupRef;
-
- /**
- * Field _graphColour.
- */
- private int _graphColour;
-
- /**
- * keeps track of state for field: _graphColour
- */
- private boolean _has_graphColour;
-
- /**
- * Field _graphGroup.
- */
- private int _graphGroup;
-
- /**
- * keeps track of state for field: _graphGroup
- */
- private boolean _has_graphGroup;
-
- /**
- * height in pixels for the graph if this is a graph-type annotation.
- */
- private int _graphHeight;
-
- /**
- * keeps track of state for field: _graphHeight
- */
- private boolean _has_graphHeight;
-
- /**
- * Field _id.
- */
- private java.lang.String _id;
-
- /**
- * Field _scoreOnly.
- */
- private boolean _scoreOnly = false;
-
- /**
- * keeps track of state for field: _scoreOnly
- */
- private boolean _has_scoreOnly;
-
- /**
- * Field _score.
- */
- private double _score;
-
- /**
- * keeps track of state for field: _score
- */
- private boolean _has_score;
-
- /**
- * Field _visible.
- */
- private boolean _visible;
-
- /**
- * keeps track of state for field: _visible
- */
- private boolean _has_visible;
-
- /**
- * Field _centreColLabels.
- */
- private boolean _centreColLabels;
-
- /**
- * keeps track of state for field: _centreColLabels
- */
- private boolean _has_centreColLabels;
-
- /**
- * Field _scaleColLabels.
- */
- private boolean _scaleColLabels;
-
- /**
- * keeps track of state for field: _scaleColLabels
- */
- private boolean _has_scaleColLabels;
-
- /**
- * Field _showAllColLabels.
- */
- private boolean _showAllColLabels;
-
- /**
- * keeps track of state for field: _showAllColLabels
- */
- private boolean _has_showAllColLabels;
-
- /**
- * is an autocalculated annotation row
- */
- private boolean _autoCalculated = false;
-
- /**
- * keeps track of state for field: _autoCalculated
- */
- private boolean _has_autoCalculated;
-
- /**
- * is to be shown below the alignment - introduced in Jalview 2.8 for
- * visualizing T-COFFEE alignment scores
- */
- private boolean _belowAlignment = true;
-
- /**
- * keeps track of state for field: _belowAlignment
- */
- private boolean _has_belowAlignment;
-
- /**
- * Optional string identifier used to group sets of annotation produced by a
- * particular calculation. Values are opaque strings but have semantic meaning
- * to Jalview's renderer, data importer and calculation system.
- */
- private java.lang.String _calcId;
-
- /**
- * Field _annotationElementList.
- */
- private java.util.Vector _annotationElementList;
-
- /**
- * Field _label.
- */
- private java.lang.String _label;
-
- /**
- * Field _description.
- */
- private java.lang.String _description;
-
- /**
- * Field _thresholdLine.
- */
- private jalview.schemabinding.version2.ThresholdLine _thresholdLine;
-
- // ----------------/
- // - Constructors -/
- // ----------------/
-
- public Annotation()
- {
- super();
- this._annotationElementList = new java.util.Vector();
- }
-
- // -----------/
- // - Methods -/
- // -----------/
-
- /**
- *
- *
- * @param vAnnotationElement
- * @throws java.lang.IndexOutOfBoundsException
- * if the index given is outside the bounds of the collection
- */
- public void addAnnotationElement(
- final jalview.schemabinding.version2.AnnotationElement vAnnotationElement)
- throws java.lang.IndexOutOfBoundsException
- {
- this._annotationElementList.addElement(vAnnotationElement);
- }
-
- /**
- *
- *
- * @param index
- * @param vAnnotationElement
- * @throws java.lang.IndexOutOfBoundsException
- * if the index given is outside the bounds of the collection
- */
- public void addAnnotationElement(
- final int index,
- final jalview.schemabinding.version2.AnnotationElement vAnnotationElement)
- throws java.lang.IndexOutOfBoundsException
- {
- this._annotationElementList.add(index, vAnnotationElement);
- }
-
- /**
- */
- public void deleteAutoCalculated()
- {
- this._has_autoCalculated = false;
- }
-
- /**
- */
- public void deleteBelowAlignment()
- {
- this._has_belowAlignment = false;
- }
-
- /**
- */
- public void deleteCentreColLabels()
- {
- this._has_centreColLabels = false;
- }
-
- /**
- */
- public void deleteGraph()
- {
- this._has_graph = false;
- }
-
- /**
- */
- public void deleteGraphColour()
- {
- this._has_graphColour = false;
- }
-
- /**
- */
- public void deleteGraphGroup()
- {
- this._has_graphGroup = false;
- }
-
- /**
- */
- public void deleteGraphHeight()
- {
- this._has_graphHeight = false;
- }
-
- /**
- */
- public void deleteGraphType()
- {
- this._has_graphType = false;
- }
-
- /**
- */
- public void deleteScaleColLabels()
- {
- this._has_scaleColLabels = false;
- }
-
- /**
- */
- public void deleteScore()
- {
- this._has_score = false;
- }
-
- /**
- */
- public void deleteScoreOnly()
- {
- this._has_scoreOnly = false;
- }
-
- /**
- */
- public void deleteShowAllColLabels()
- {
- this._has_showAllColLabels = false;
- }
-
- /**
- */
- public void deleteVisible()
- {
- this._has_visible = false;
- }
-
- /**
- * Method enumerateAnnotationElement.
- *
- * @return an Enumeration over all
- * jalview.schemabinding.version2.AnnotationElement elements
- */
- public java.util.Enumeration enumerateAnnotationElement()
- {
- return this._annotationElementList.elements();
- }
-
- /**
- * Method getAnnotationElement.
- *
- * @param index
- * @throws java.lang.IndexOutOfBoundsException
- * if the index given is outside the bounds of the collection
- * @return the value of the jalview.schemabinding.version2.AnnotationElement
- * at the given index
- */
- public jalview.schemabinding.version2.AnnotationElement getAnnotationElement(
- final int index) throws java.lang.IndexOutOfBoundsException
- {
- // check bounds for index
- if (index < 0 || index >= this._annotationElementList.size())
- {
- throw new IndexOutOfBoundsException(
- "getAnnotationElement: Index value '" + index
- + "' not in range [0.."
- + (this._annotationElementList.size() - 1) + "]");
- }
-
- return (jalview.schemabinding.version2.AnnotationElement) _annotationElementList
- .get(index);
- }
-
- /**
- * Method getAnnotationElement.Returns the contents of the collection in an
- * Array.
- * <p>
- * Note: Just in case the collection contents are changing in another thread,
- * we pass a 0-length Array of the correct type into the API call. This way we
- * <i>know</i> that the Array returned is of exactly the correct length.
- *
- * @return this collection as an Array
- */
- public jalview.schemabinding.version2.AnnotationElement[] getAnnotationElement()
- {
- jalview.schemabinding.version2.AnnotationElement[] array = new jalview.schemabinding.version2.AnnotationElement[0];
- return (jalview.schemabinding.version2.AnnotationElement[]) this._annotationElementList
- .toArray(array);
- }
-
- /**
- * Method getAnnotationElementCount.
- *
- * @return the size of this collection
- */
- public int getAnnotationElementCount()
- {
- return this._annotationElementList.size();
- }
-
- /**
- * Returns the value of field 'autoCalculated'. The field 'autoCalculated' has
- * the following description: is an autocalculated annotation row
- *
- * @return the value of field 'AutoCalculated'.
- */
- public boolean getAutoCalculated()
- {
- return this._autoCalculated;
- }
-
- /**
- * Returns the value of field 'belowAlignment'. The field 'belowAlignment' has
- * the following description: is to be shown below the alignment - introduced
- * in Jalview 2.8 for visualizing T-COFFEE alignment scores
- *
- * @return the value of field 'BelowAlignment'.
- */
- public boolean getBelowAlignment()
- {
- return this._belowAlignment;
- }
-
- /**
- * Returns the value of field 'calcId'. The field 'calcId' has the following
- * description: Optional string identifier used to group sets of annotation
- * produced by a particular calculation. Values are opaque strings but have
- * semantic meaning to Jalview's renderer, data importer and calculation
- * system.
- *
- * @return the value of field 'CalcId'.
- */
- public java.lang.String getCalcId()
- {
- return this._calcId;
- }
-
- /**
- * Returns the value of field 'centreColLabels'.
- *
- * @return the value of field 'CentreColLabels'.
- */
- public boolean getCentreColLabels()
- {
- return this._centreColLabels;
- }
-
- /**
- * Returns the value of field 'description'.
- *
- * @return the value of field 'Description'.
- */
- public java.lang.String getDescription()
- {
- return this._description;
- }
-
- /**
- * Returns the value of field 'graph'.
- *
- * @return the value of field 'Graph'.
- */
- public boolean getGraph()
- {
- return this._graph;
- }
-
- /**
- * Returns the value of field 'graphColour'.
- *
- * @return the value of field 'GraphColour'.
- */
- public int getGraphColour()
- {
- return this._graphColour;
- }
-
- /**
- * Returns the value of field 'graphGroup'.
- *
- * @return the value of field 'GraphGroup'.
- */
- public int getGraphGroup()
- {
- return this._graphGroup;
- }
-
- /**
- * Returns the value of field 'graphHeight'. The field 'graphHeight' has the
- * following description: height in pixels for the graph if this is a
- * graph-type annotation.
- *
- * @return the value of field 'GraphHeight'.
- */
- public int getGraphHeight()
- {
- return this._graphHeight;
- }
-
- /**
- * Returns the value of field 'graphType'.
- *
- * @return the value of field 'GraphType'.
- */
- public int getGraphType()
- {
- return this._graphType;
- }
-
- /**
- * Returns the value of field 'groupRef'.
- *
- * @return the value of field 'GroupRef'.
- */
- public java.lang.String getGroupRef()
- {
- return this._groupRef;
- }
-
- /**
- * Returns the value of field 'id'.
- *
- * @return the value of field 'Id'.
- */
- public java.lang.String getId()
- {
- return this._id;
- }
-
- /**
- * Returns the value of field 'label'.
- *
- * @return the value of field 'Label'.
- */
- public java.lang.String getLabel()
- {
- return this._label;
- }
-
- /**
- * Returns the value of field 'scaleColLabels'.
- *
- * @return the value of field 'ScaleColLabels'.
- */
- public boolean getScaleColLabels()
- {
- return this._scaleColLabels;
- }
-
- /**
- * Returns the value of field 'score'.
- *
- * @return the value of field 'Score'.
- */
- public double getScore()
- {
- return this._score;
- }
-
- /**
- * Returns the value of field 'scoreOnly'.
- *
- * @return the value of field 'ScoreOnly'.
- */
- public boolean getScoreOnly()
- {
- return this._scoreOnly;
- }
-
- /**
- * Returns the value of field 'sequenceRef'.
- *
- * @return the value of field 'SequenceRef'.
- */
- public java.lang.String getSequenceRef()
- {
- return this._sequenceRef;
- }
-
- /**
- * Returns the value of field 'showAllColLabels'.
- *
- * @return the value of field 'ShowAllColLabels'.
- */
- public boolean getShowAllColLabels()
- {
- return this._showAllColLabels;
- }
-
- /**
- * Returns the value of field 'thresholdLine'.
- *
- * @return the value of field 'ThresholdLine'.
- */
- public jalview.schemabinding.version2.ThresholdLine getThresholdLine()
- {
- return this._thresholdLine;
- }
-
- /**
- * Returns the value of field 'visible'.
- *
- * @return the value of field 'Visible'.
- */
- public boolean getVisible()
- {
- return this._visible;
- }
-
- /**
- * Method hasAutoCalculated.
- *
- * @return true if at least one AutoCalculated has been added
- */
- public boolean hasAutoCalculated()
- {
- return this._has_autoCalculated;
- }
-
- /**
- * Method hasBelowAlignment.
- *
- * @return true if at least one BelowAlignment has been added
- */
- public boolean hasBelowAlignment()
- {
- return this._has_belowAlignment;
- }
-
- /**
- * Method hasCentreColLabels.
- *
- * @return true if at least one CentreColLabels has been added
- */
- public boolean hasCentreColLabels()
- {
- return this._has_centreColLabels;
- }
-
- /**
- * Method hasGraph.
- *
- * @return true if at least one Graph has been added
- */
- public boolean hasGraph()
- {
- return this._has_graph;
- }
-
- /**
- * Method hasGraphColour.
- *
- * @return true if at least one GraphColour has been added
- */
- public boolean hasGraphColour()
- {
- return this._has_graphColour;
- }
-
- /**
- * Method hasGraphGroup.
- *
- * @return true if at least one GraphGroup has been added
- */
- public boolean hasGraphGroup()
- {
- return this._has_graphGroup;
- }
-
- /**
- * Method hasGraphHeight.
- *
- * @return true if at least one GraphHeight has been added
- */
- public boolean hasGraphHeight()
- {
- return this._has_graphHeight;
- }
-
- /**
- * Method hasGraphType.
- *
- * @return true if at least one GraphType has been added
- */
- public boolean hasGraphType()
- {
- return this._has_graphType;
- }
-
- /**
- * Method hasScaleColLabels.
- *
- * @return true if at least one ScaleColLabels has been added
- */
- public boolean hasScaleColLabels()
- {
- return this._has_scaleColLabels;
- }
-
- /**
- * Method hasScore.
- *
- * @return true if at least one Score has been added
- */
- public boolean hasScore()
- {
- return this._has_score;
- }
-
- /**
- * Method hasScoreOnly.
- *
- * @return true if at least one ScoreOnly has been added
- */
- public boolean hasScoreOnly()
- {
- return this._has_scoreOnly;
- }
-
- /**
- * Method hasShowAllColLabels.
- *
- * @return true if at least one ShowAllColLabels has been added
- */
- public boolean hasShowAllColLabels()
- {
- return this._has_showAllColLabels;
- }
-
- /**
- * Method hasVisible.
- *
- * @return true if at least one Visible has been added
- */
- public boolean hasVisible()
- {
- return this._has_visible;
- }
-
- /**
- * Returns the value of field 'autoCalculated'. The field 'autoCalculated' has
- * the following description: is an autocalculated annotation row
- *
- * @return the value of field 'AutoCalculated'.
- */
- public boolean isAutoCalculated()
- {
- return this._autoCalculated;
- }
-
- /**
- * Returns the value of field 'belowAlignment'. The field 'belowAlignment' has
- * the following description: is to be shown below the alignment - introduced
- * in Jalview 2.8 for visualizing T-COFFEE alignment scores
- *
- * @return the value of field 'BelowAlignment'.
- */
- public boolean isBelowAlignment()
- {
- return this._belowAlignment;
- }
-
- /**
- * Returns the value of field 'centreColLabels'.
- *
- * @return the value of field 'CentreColLabels'.
- */
- public boolean isCentreColLabels()
- {
- return this._centreColLabels;
- }
-
- /**
- * Returns the value of field 'graph'.
- *
- * @return the value of field 'Graph'.
- */
- public boolean isGraph()
- {
- return this._graph;
- }
-
- /**
- * Returns the value of field 'scaleColLabels'.
- *
- * @return the value of field 'ScaleColLabels'.
- */
- public boolean isScaleColLabels()
- {
- return this._scaleColLabels;
- }
-
- /**
- * Returns the value of field 'scoreOnly'.
- *
- * @return the value of field 'ScoreOnly'.
- */
- public boolean isScoreOnly()
- {
- return this._scoreOnly;
- }
-
- /**
- * Returns the value of field 'showAllColLabels'.
- *
- * @return the value of field 'ShowAllColLabels'.
- */
- public boolean isShowAllColLabels()
- {
- return this._showAllColLabels;
- }
-
- /**
- * Method isValid.
- *
- * @return true if this object is valid according to the schema
- */
- public boolean isValid()
- {
- try
- {
- validate();
- } catch (org.exolab.castor.xml.ValidationException vex)
- {
- return false;
- }
- return true;
- }
-
- /**
- * Returns the value of field 'visible'.
- *
- * @return the value of field 'Visible'.
- */
- public boolean isVisible()
- {
- return this._visible;
- }
-
- /**
- *
- *
- * @param out
- * @throws org.exolab.castor.xml.MarshalException
- * if object is null or if any SAXException is thrown during
- * marshaling
- * @throws org.exolab.castor.xml.ValidationException
- * if this object is an invalid instance according to the schema
- */
- public void marshal(final java.io.Writer out)
- throws org.exolab.castor.xml.MarshalException,
- org.exolab.castor.xml.ValidationException
- {
- Marshaller.marshal(this, out);
- }
-
- /**
- *
- *
- * @param handler
- * @throws java.io.IOException
- * if an IOException occurs during marshaling
- * @throws org.exolab.castor.xml.ValidationException
- * if this object is an invalid instance according to the schema
- * @throws org.exolab.castor.xml.MarshalException
- * if object is null or if any SAXException is thrown during
- * marshaling
- */
- public void marshal(final org.xml.sax.ContentHandler handler)
- throws java.io.IOException,
- org.exolab.castor.xml.MarshalException,
- org.exolab.castor.xml.ValidationException
- {
- Marshaller.marshal(this, handler);
- }
-
- /**
- */
- public void removeAllAnnotationElement()
- {
- this._annotationElementList.clear();
- }
-
- /**
- * Method removeAnnotationElement.
- *
- * @param vAnnotationElement
- * @return true if the object was removed from the collection.
- */
- public boolean removeAnnotationElement(
- final jalview.schemabinding.version2.AnnotationElement vAnnotationElement)
- {
- boolean removed = _annotationElementList.remove(vAnnotationElement);
- return removed;
- }
-
- /**
- * Method removeAnnotationElementAt.
- *
- * @param index
- * @return the element removed from the collection
- */
- public jalview.schemabinding.version2.AnnotationElement removeAnnotationElementAt(
- final int index)
- {
- java.lang.Object obj = this._annotationElementList.remove(index);
- return (jalview.schemabinding.version2.AnnotationElement) obj;
- }
-
- /**
- *
- *
- * @param index
- * @param vAnnotationElement
- * @throws java.lang.IndexOutOfBoundsException
- * if the index given is outside the bounds of the collection
- */
- public void setAnnotationElement(
- final int index,
- final jalview.schemabinding.version2.AnnotationElement vAnnotationElement)
- throws java.lang.IndexOutOfBoundsException
- {
- // check bounds for index
- if (index < 0 || index >= this._annotationElementList.size())
- {
- throw new IndexOutOfBoundsException(
- "setAnnotationElement: Index value '" + index
- + "' not in range [0.."
- + (this._annotationElementList.size() - 1) + "]");
- }
-
- this._annotationElementList.set(index, vAnnotationElement);
- }
-
- /**
- *
- *
- * @param vAnnotationElementArray
- */
- public void setAnnotationElement(
- final jalview.schemabinding.version2.AnnotationElement[] vAnnotationElementArray)
- {
- // -- copy array
- _annotationElementList.clear();
-
- for (int i = 0; i < vAnnotationElementArray.length; i++)
- {
- this._annotationElementList.add(vAnnotationElementArray[i]);
- }
- }
-
- /**
- * Sets the value of field 'autoCalculated'. The field 'autoCalculated' has
- * the following description: is an autocalculated annotation row
- *
- * @param autoCalculated
- * the value of field 'autoCalculated'.
- */
- public void setAutoCalculated(final boolean autoCalculated)
- {
- this._autoCalculated = autoCalculated;
- this._has_autoCalculated = true;
- }
-
- /**
- * Sets the value of field 'belowAlignment'. The field 'belowAlignment' has
- * the following description: is to be shown below the alignment - introduced
- * in Jalview 2.8 for visualizing T-COFFEE alignment scores
- *
- * @param belowAlignment
- * the value of field 'belowAlignment'.
- */
- public void setBelowAlignment(final boolean belowAlignment)
- {
- this._belowAlignment = belowAlignment;
- this._has_belowAlignment = true;
- }
-
- /**
- * Sets the value of field 'calcId'. The field 'calcId' has the following
- * description: Optional string identifier used to group sets of annotation
- * produced by a particular calculation. Values are opaque strings but have
- * semantic meaning to Jalview's renderer, data importer and calculation
- * system.
- *
- * @param calcId
- * the value of field 'calcId'.
- */
- public void setCalcId(final java.lang.String calcId)
- {
- this._calcId = calcId;
- }
-
- /**
- * Sets the value of field 'centreColLabels'.
- *
- * @param centreColLabels
- * the value of field 'centreColLabels'.
- */
- public void setCentreColLabels(final boolean centreColLabels)
- {
- this._centreColLabels = centreColLabels;
- this._has_centreColLabels = true;
- }
-
- /**
- * Sets the value of field 'description'.
- *
- * @param description
- * the value of field 'description'.
- */
- public void setDescription(final java.lang.String description)
- {
- this._description = description;
- }
-
- /**
- * Sets the value of field 'graph'.
- *
- * @param graph
- * the value of field 'graph'.
- */
- public void setGraph(final boolean graph)
- {
- this._graph = graph;
- this._has_graph = true;
- }
-
- /**
- * Sets the value of field 'graphColour'.
- *
- * @param graphColour
- * the value of field 'graphColour'.
- */
- public void setGraphColour(final int graphColour)
- {
- this._graphColour = graphColour;
- this._has_graphColour = true;
- }
-
- /**
- * Sets the value of field 'graphGroup'.
- *
- * @param graphGroup
- * the value of field 'graphGroup'.
- */
- public void setGraphGroup(final int graphGroup)
- {
- this._graphGroup = graphGroup;
- this._has_graphGroup = true;
- }
-
- /**
- * Sets the value of field 'graphHeight'. The field 'graphHeight' has the
- * following description: height in pixels for the graph if this is a
- * graph-type annotation.
- *
- * @param graphHeight
- * the value of field 'graphHeight'.
- */
- public void setGraphHeight(final int graphHeight)
- {
- this._graphHeight = graphHeight;
- this._has_graphHeight = true;
- }
-
- /**
- * Sets the value of field 'graphType'.
- *
- * @param graphType
- * the value of field 'graphType'.
- */
- public void setGraphType(final int graphType)
- {
- this._graphType = graphType;
- this._has_graphType = true;
- }
-
- /**
- * Sets the value of field 'groupRef'.
- *
- * @param groupRef
- * the value of field 'groupRef'.
- */
- public void setGroupRef(final java.lang.String groupRef)
- {
- this._groupRef = groupRef;
- }
-
- /**
- * Sets the value of field 'id'.
- *
- * @param id
- * the value of field 'id'.
- */
- public void setId(final java.lang.String id)
- {
- this._id = id;
- }
-
- /**
- * Sets the value of field 'label'.
- *
- * @param label
- * the value of field 'label'.
- */
- public void setLabel(final java.lang.String label)
- {
- this._label = label;
- }
-
- /**
- * Sets the value of field 'scaleColLabels'.
- *
- * @param scaleColLabels
- * the value of field 'scaleColLabels'.
- */
- public void setScaleColLabels(final boolean scaleColLabels)
- {
- this._scaleColLabels = scaleColLabels;
- this._has_scaleColLabels = true;
- }
-
- /**
- * Sets the value of field 'score'.
- *
- * @param score
- * the value of field 'score'.
- */
- public void setScore(final double score)
- {
- this._score = score;
- this._has_score = true;
- }
-
- /**
- * Sets the value of field 'scoreOnly'.
- *
- * @param scoreOnly
- * the value of field 'scoreOnly'.
- */
- public void setScoreOnly(final boolean scoreOnly)
- {
- this._scoreOnly = scoreOnly;
- this._has_scoreOnly = true;
- }
-
- /**
- * Sets the value of field 'sequenceRef'.
- *
- * @param sequenceRef
- * the value of field 'sequenceRef'.
- */
- public void setSequenceRef(final java.lang.String sequenceRef)
- {
- this._sequenceRef = sequenceRef;
- }
-
- /**
- * Sets the value of field 'showAllColLabels'.
- *
- * @param showAllColLabels
- * the value of field 'showAllColLabels'
- */
- public void setShowAllColLabels(final boolean showAllColLabels)
- {
- this._showAllColLabels = showAllColLabels;
- this._has_showAllColLabels = true;
- }
-
- /**
- * Sets the value of field 'thresholdLine'.
- *
- * @param thresholdLine
- * the value of field 'thresholdLine'.
- */
- public void setThresholdLine(
- final jalview.schemabinding.version2.ThresholdLine thresholdLine)
- {
- this._thresholdLine = thresholdLine;
- }
-
- /**
- * Sets the value of field 'visible'.
- *
- * @param visible
- * the value of field 'visible'.
- */
- public void setVisible(final boolean visible)
- {
- this._visible = visible;
- this._has_visible = true;
- }
-
- /**
- * Method unmarshal.
- *
- * @param reader
- * @throws org.exolab.castor.xml.MarshalException
- * if object is null or if any SAXException is thrown during
- * marshaling
- * @throws org.exolab.castor.xml.ValidationException
- * if this object is an invalid instance according to the schema
- * @return the unmarshaled jalview.schemabinding.version2.Annotation
- */
- public static jalview.schemabinding.version2.Annotation unmarshal(
- final java.io.Reader reader)
- throws org.exolab.castor.xml.MarshalException,
- org.exolab.castor.xml.ValidationException
- {
- return (jalview.schemabinding.version2.Annotation) Unmarshaller
- .unmarshal(jalview.schemabinding.version2.Annotation.class,
- reader);
- }
-
- /**
- *
- *
- * @throws org.exolab.castor.xml.ValidationException
- * if this object is an invalid instance according to the schema
- */
- public void validate() throws org.exolab.castor.xml.ValidationException
- {
- org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator();
- validator.validate(this);
- }
+public class Annotation implements java.io.Serializable {
+
+
+ //--------------------------/
+ //- Class/Member Variables -/
+ //--------------------------/
+
+ /**
+ * Field _graph.
+ */
+ private boolean _graph;
+
+ /**
+ * keeps track of state for field: _graph
+ */
+ private boolean _has_graph;
+
+ /**
+ * Field _graphType.
+ */
+ private int _graphType;
+
+ /**
+ * keeps track of state for field: _graphType
+ */
+ private boolean _has_graphType;
+
+ /**
+ * Field _sequenceRef.
+ */
+ private java.lang.String _sequenceRef;
+
+ /**
+ * Field _groupRef.
+ */
+ private java.lang.String _groupRef;
+
+ /**
+ * Field _graphColour.
+ */
+ private int _graphColour;
+
+ /**
+ * keeps track of state for field: _graphColour
+ */
+ private boolean _has_graphColour;
+
+ /**
+ * Field _graphGroup.
+ */
+ private int _graphGroup;
+
+ /**
+ * keeps track of state for field: _graphGroup
+ */
+ private boolean _has_graphGroup;
+
+ /**
+ * height in pixels for the graph if this is a graph-type
+ * annotation.
+ */
+ private int _graphHeight;
+
+ /**
+ * keeps track of state for field: _graphHeight
+ */
+ private boolean _has_graphHeight;
+
+ /**
+ * Field _id.
+ */
+ private java.lang.String _id;
+
+ /**
+ * Field _scoreOnly.
+ */
+ private boolean _scoreOnly = false;
+
+ /**
+ * keeps track of state for field: _scoreOnly
+ */
+ private boolean _has_scoreOnly;
+
+ /**
+ * Field _score.
+ */
+ private double _score;
+
+ /**
+ * keeps track of state for field: _score
+ */
+ private boolean _has_score;
+
+ /**
+ * Field _visible.
+ */
+ private boolean _visible;
+
+ /**
+ * keeps track of state for field: _visible
+ */
+ private boolean _has_visible;
+
+ /**
+ * Field _centreColLabels.
+ */
+ private boolean _centreColLabels;
+
+ /**
+ * keeps track of state for field: _centreColLabels
+ */
+ private boolean _has_centreColLabels;
+
+ /**
+ * Field _scaleColLabels.
+ */
+ private boolean _scaleColLabels;
+
+ /**
+ * keeps track of state for field: _scaleColLabels
+ */
+ private boolean _has_scaleColLabels;
+
+ /**
+ * Field _showAllColLabels.
+ */
+ private boolean _showAllColLabels;
+
+ /**
+ * keeps track of state for field: _showAllColLabels
+ */
+ private boolean _has_showAllColLabels;
+
+ /**
+ * is an autocalculated annotation row
+ */
+ private boolean _autoCalculated = false;
+
+ /**
+ * keeps track of state for field: _autoCalculated
+ */
+ private boolean _has_autoCalculated;
+
+ /**
+ * is to be shown below the alignment - introduced in Jalview
+ * 2.8 for visualizing T-COFFEE alignment scores
+ */
+ private boolean _belowAlignment = true;
+
+ /**
+ * keeps track of state for field: _belowAlignment
+ */
+ private boolean _has_belowAlignment;
+
+ /**
+ * Optional string identifier used to group sets of annotation
+ * produced by a particular calculation. Values are opaque
+ * strings but have semantic meaning to Jalview's renderer,
+ * data importer and calculation system.
+ */
+ private java.lang.String _calcId;
+
+ /**
+ * Field _annotationElementList.
+ */
+ private java.util.Vector _annotationElementList;
+
+ /**
+ * Field _label.
+ */
+ private java.lang.String _label;
+
+ /**
+ * Field _description.
+ */
+ private java.lang.String _description;
+
+ /**
+ * Field _thresholdLine.
+ */
+ private jalview.schemabinding.version2.ThresholdLine _thresholdLine;
+
+ /**
+ * Field _propertyList.
+ */
+ private java.util.Vector _propertyList;
+
+
+ //----------------/
+ //- Constructors -/
+ //----------------/
+
+ public Annotation() {
+ super();
+ this._annotationElementList = new java.util.Vector();
+ this._propertyList = new java.util.Vector();
+ }
+
+
+ //-----------/
+ //- Methods -/
+ //-----------/
+
+ /**
+ *
+ *
+ * @param vAnnotationElement
+ * @throws java.lang.IndexOutOfBoundsException if the index
+ * given is outside the bounds of the collection
+ */
+ public void addAnnotationElement(
+ final jalview.schemabinding.version2.AnnotationElement vAnnotationElement)
+ throws java.lang.IndexOutOfBoundsException {
+ this._annotationElementList.addElement(vAnnotationElement);
+ }
+
+ /**
+ *
+ *
+ * @param index
+ * @param vAnnotationElement
+ * @throws java.lang.IndexOutOfBoundsException if the index
+ * given is outside the bounds of the collection
+ */
+ public void addAnnotationElement(
+ final int index,
+ final jalview.schemabinding.version2.AnnotationElement vAnnotationElement)
+ throws java.lang.IndexOutOfBoundsException {
+ this._annotationElementList.add(index, vAnnotationElement);
+ }
+
+ /**
+ *
+ *
+ * @param vProperty
+ * @throws java.lang.IndexOutOfBoundsException if the index
+ * given is outside the bounds of the collection
+ */
+ public void addProperty(
+ final jalview.schemabinding.version2.Property vProperty)
+ throws java.lang.IndexOutOfBoundsException {
+ this._propertyList.addElement(vProperty);
+ }
+
+ /**
+ *
+ *
+ * @param index
+ * @param vProperty
+ * @throws java.lang.IndexOutOfBoundsException if the index
+ * given is outside the bounds of the collection
+ */
+ public void addProperty(
+ final int index,
+ final jalview.schemabinding.version2.Property vProperty)
+ throws java.lang.IndexOutOfBoundsException {
+ this._propertyList.add(index, vProperty);
+ }
+
+ /**
+ */
+ public void deleteAutoCalculated(
+ ) {
+ this._has_autoCalculated= false;
+ }
+
+ /**
+ */
+ public void deleteBelowAlignment(
+ ) {
+ this._has_belowAlignment= false;
+ }
+
+ /**
+ */
+ public void deleteCentreColLabels(
+ ) {
+ this._has_centreColLabels= false;
+ }
+
+ /**
+ */
+ public void deleteGraph(
+ ) {
+ this._has_graph= false;
+ }
+
+ /**
+ */
+ public void deleteGraphColour(
+ ) {
+ this._has_graphColour= false;
+ }
+
+ /**
+ */
+ public void deleteGraphGroup(
+ ) {
+ this._has_graphGroup= false;
+ }
+
+ /**
+ */
+ public void deleteGraphHeight(
+ ) {
+ this._has_graphHeight= false;
+ }
+
+ /**
+ */
+ public void deleteGraphType(
+ ) {
+ this._has_graphType= false;
+ }
+
+ /**
+ */
+ public void deleteScaleColLabels(
+ ) {
+ this._has_scaleColLabels= false;
+ }
+
+ /**
+ */
+ public void deleteScore(
+ ) {
+ this._has_score= false;
+ }
+
+ /**
+ */
+ public void deleteScoreOnly(
+ ) {
+ this._has_scoreOnly= false;
+ }
+
+ /**
+ */
+ public void deleteShowAllColLabels(
+ ) {
+ this._has_showAllColLabels= false;
+ }
+
+ /**
+ */
+ public void deleteVisible(
+ ) {
+ this._has_visible= false;
+ }
+
+ /**
+ * Method enumerateAnnotationElement.
+ *
+ * @return an Enumeration over all
+ * jalview.schemabinding.version2.AnnotationElement elements
+ */
+ public java.util.Enumeration enumerateAnnotationElement(
+ ) {
+ return this._annotationElementList.elements();
+ }
+
+ /**
+ * Method enumerateProperty.
+ *
+ * @return an Enumeration over all
+ * jalview.schemabinding.version2.Property elements
+ */
+ public java.util.Enumeration enumerateProperty(
+ ) {
+ return this._propertyList.elements();
+ }
+
+ /**
+ * Method getAnnotationElement.
+ *
+ * @param index
+ * @throws java.lang.IndexOutOfBoundsException if the index
+ * given is outside the bounds of the collection
+ * @return the value of the
+ * jalview.schemabinding.version2.AnnotationElement at the
+ * given index
+ */
+ public jalview.schemabinding.version2.AnnotationElement getAnnotationElement(
+ final int index)
+ throws java.lang.IndexOutOfBoundsException {
+ // check bounds for index
+ if (index < 0 || index >= this._annotationElementList.size()) {
+ throw new IndexOutOfBoundsException("getAnnotationElement: Index value '" + index + "' not in range [0.." + (this._annotationElementList.size() - 1) + "]");
+ }
+
+ return (jalview.schemabinding.version2.AnnotationElement) _annotationElementList.get(index);
+ }
+
+ /**
+ * Method getAnnotationElement.Returns the contents of the
+ * collection in an Array. <p>Note: Just in case the
+ * collection contents are changing in another thread, we pass
+ * a 0-length Array of the correct type into the API call.
+ * This way we <i>know</i> that the Array returned is of
+ * exactly the correct length.
+ *
+ * @return this collection as an Array
+ */
+ public jalview.schemabinding.version2.AnnotationElement[] getAnnotationElement(
+ ) {
+ jalview.schemabinding.version2.AnnotationElement[] array = new jalview.schemabinding.version2.AnnotationElement[0];
+ return (jalview.schemabinding.version2.AnnotationElement[]) this._annotationElementList.toArray(array);
+ }
+
+ /**
+ * Method getAnnotationElementCount.
+ *
+ * @return the size of this collection
+ */
+ public int getAnnotationElementCount(
+ ) {
+ return this._annotationElementList.size();
+ }
+
+ /**
+ * Returns the value of field 'autoCalculated'. The field
+ * 'autoCalculated' has the following description: is an
+ * autocalculated annotation row
+ *
+ * @return the value of field 'AutoCalculated'.
+ */
+ public boolean getAutoCalculated(
+ ) {
+ return this._autoCalculated;
+ }
+
+ /**
+ * Returns the value of field 'belowAlignment'. The field
+ * 'belowAlignment' has the following description: is to be
+ * shown below the alignment - introduced in Jalview 2.8 for
+ * visualizing T-COFFEE alignment scores
+ *
+ * @return the value of field 'BelowAlignment'.
+ */
+ public boolean getBelowAlignment(
+ ) {
+ return this._belowAlignment;
+ }
+
+ /**
+ * Returns the value of field 'calcId'. The field 'calcId' has
+ * the following description: Optional string identifier used
+ * to group sets of annotation produced by a particular
+ * calculation. Values are opaque strings but have semantic
+ * meaning to Jalview's renderer, data importer and calculation
+ * system.
+ *
+ * @return the value of field 'CalcId'.
+ */
+ public java.lang.String getCalcId(
+ ) {
+ return this._calcId;
+ }
+
+ /**
+ * Returns the value of field 'centreColLabels'.
+ *
+ * @return the value of field 'CentreColLabels'.
+ */
+ public boolean getCentreColLabels(
+ ) {
+ return this._centreColLabels;
+ }
+
+ /**
+ * Returns the value of field 'description'.
+ *
+ * @return the value of field 'Description'.
+ */
+ public java.lang.String getDescription(
+ ) {
+ return this._description;
+ }
+
+ /**
+ * Returns the value of field 'graph'.
+ *
+ * @return the value of field 'Graph'.
+ */
+ public boolean getGraph(
+ ) {
+ return this._graph;
+ }
+
+ /**
+ * Returns the value of field 'graphColour'.
+ *
+ * @return the value of field 'GraphColour'.
+ */
+ public int getGraphColour(
+ ) {
+ return this._graphColour;
+ }
+
+ /**
+ * Returns the value of field 'graphGroup'.
+ *
+ * @return the value of field 'GraphGroup'.
+ */
+ public int getGraphGroup(
+ ) {
+ return this._graphGroup;
+ }
+
+ /**
+ * Returns the value of field 'graphHeight'. The field
+ * 'graphHeight' has the following description: height in
+ * pixels for the graph if this is a graph-type annotation.
+ *
+ * @return the value of field 'GraphHeight'.
+ */
+ public int getGraphHeight(
+ ) {
+ return this._graphHeight;
+ }
+
+ /**
+ * Returns the value of field 'graphType'.
+ *
+ * @return the value of field 'GraphType'.
+ */
+ public int getGraphType(
+ ) {
+ return this._graphType;
+ }
+
+ /**
+ * Returns the value of field 'groupRef'.
+ *
+ * @return the value of field 'GroupRef'.
+ */
+ public java.lang.String getGroupRef(
+ ) {
+ return this._groupRef;
+ }
+
+ /**
+ * Returns the value of field 'id'.
+ *
+ * @return the value of field 'Id'.
+ */
+ public java.lang.String getId(
+ ) {
+ return this._id;
+ }
+
+ /**
+ * Returns the value of field 'label'.
+ *
+ * @return the value of field 'Label'.
+ */
+ public java.lang.String getLabel(
+ ) {
+ return this._label;
+ }
+
+ /**
+ * Method getProperty.
+ *
+ * @param index
+ * @throws java.lang.IndexOutOfBoundsException if the index
+ * given is outside the bounds of the collection
+ * @return the value of the
+ * jalview.schemabinding.version2.Property at the given index
+ */
+ public jalview.schemabinding.version2.Property getProperty(
+ final int index)
+ throws java.lang.IndexOutOfBoundsException {
+ // check bounds for index
+ if (index < 0 || index >= this._propertyList.size()) {
+ throw new IndexOutOfBoundsException("getProperty: Index value '" + index + "' not in range [0.." + (this._propertyList.size() - 1) + "]");
+ }
+
+ return (jalview.schemabinding.version2.Property) _propertyList.get(index);
+ }
+
+ /**
+ * Method getProperty.Returns the contents of the collection in
+ * an Array. <p>Note: Just in case the collection contents
+ * are changing in another thread, we pass a 0-length Array of
+ * the correct type into the API call. This way we <i>know</i>
+ * that the Array returned is of exactly the correct length.
+ *
+ * @return this collection as an Array
+ */
+ public jalview.schemabinding.version2.Property[] getProperty(
+ ) {
+ jalview.schemabinding.version2.Property[] array = new jalview.schemabinding.version2.Property[0];
+ return (jalview.schemabinding.version2.Property[]) this._propertyList.toArray(array);
+ }
+
+ /**
+ * Method getPropertyCount.
+ *
+ * @return the size of this collection
+ */
+ public int getPropertyCount(
+ ) {
+ return this._propertyList.size();
+ }
+
+ /**
+ * Returns the value of field 'scaleColLabels'.
+ *
+ * @return the value of field 'ScaleColLabels'.
+ */
+ public boolean getScaleColLabels(
+ ) {
+ return this._scaleColLabels;
+ }
+
+ /**
+ * Returns the value of field 'score'.
+ *
+ * @return the value of field 'Score'.
+ */
+ public double getScore(
+ ) {
+ return this._score;
+ }
+
+ /**
+ * Returns the value of field 'scoreOnly'.
+ *
+ * @return the value of field 'ScoreOnly'.
+ */
+ public boolean getScoreOnly(
+ ) {
+ return this._scoreOnly;
+ }
+
+ /**
+ * Returns the value of field 'sequenceRef'.
+ *
+ * @return the value of field 'SequenceRef'.
+ */
+ public java.lang.String getSequenceRef(
+ ) {
+ return this._sequenceRef;
+ }
+
+ /**
+ * Returns the value of field 'showAllColLabels'.
+ *
+ * @return the value of field 'ShowAllColLabels'.
+ */
+ public boolean getShowAllColLabels(
+ ) {
+ return this._showAllColLabels;
+ }
+
+ /**
+ * Returns the value of field 'thresholdLine'.
+ *
+ * @return the value of field 'ThresholdLine'.
+ */
+ public jalview.schemabinding.version2.ThresholdLine getThresholdLine(
+ ) {
+ return this._thresholdLine;
+ }
+
+ /**
+ * Returns the value of field 'visible'.
+ *
+ * @return the value of field 'Visible'.
+ */
+ public boolean getVisible(
+ ) {
+ return this._visible;
+ }
+
+ /**
+ * Method hasAutoCalculated.
+ *
+ * @return true if at least one AutoCalculated has been added
+ */
+ public boolean hasAutoCalculated(
+ ) {
+ return this._has_autoCalculated;
+ }
+
+ /**
+ * Method hasBelowAlignment.
+ *
+ * @return true if at least one BelowAlignment has been added
+ */
+ public boolean hasBelowAlignment(
+ ) {
+ return this._has_belowAlignment;
+ }
+
+ /**
+ * Method hasCentreColLabels.
+ *
+ * @return true if at least one CentreColLabels has been added
+ */
+ public boolean hasCentreColLabels(
+ ) {
+ return this._has_centreColLabels;
+ }
+
+ /**
+ * Method hasGraph.
+ *
+ * @return true if at least one Graph has been added
+ */
+ public boolean hasGraph(
+ ) {
+ return this._has_graph;
+ }
+
+ /**
+ * Method hasGraphColour.
+ *
+ * @return true if at least one GraphColour has been added
+ */
+ public boolean hasGraphColour(
+ ) {
+ return this._has_graphColour;
+ }
+
+ /**
+ * Method hasGraphGroup.
+ *
+ * @return true if at least one GraphGroup has been added
+ */
+ public boolean hasGraphGroup(
+ ) {
+ return this._has_graphGroup;
+ }
+
+ /**
+ * Method hasGraphHeight.
+ *
+ * @return true if at least one GraphHeight has been added
+ */
+ public boolean hasGraphHeight(
+ ) {
+ return this._has_graphHeight;
+ }
+
+ /**
+ * Method hasGraphType.
+ *
+ * @return true if at least one GraphType has been added
+ */
+ public boolean hasGraphType(
+ ) {
+ return this._has_graphType;
+ }
+
+ /**
+ * Method hasScaleColLabels.
+ *
+ * @return true if at least one ScaleColLabels has been added
+ */
+ public boolean hasScaleColLabels(
+ ) {
+ return this._has_scaleColLabels;
+ }
+
+ /**
+ * Method hasScore.
+ *
+ * @return true if at least one Score has been added
+ */
+ public boolean hasScore(
+ ) {
+ return this._has_score;
+ }
+
+ /**
+ * Method hasScoreOnly.
+ *
+ * @return true if at least one ScoreOnly has been added
+ */
+ public boolean hasScoreOnly(
+ ) {
+ return this._has_scoreOnly;
+ }
+
+ /**
+ * Method hasShowAllColLabels.
+ *
+ * @return true if at least one ShowAllColLabels has been added
+ */
+ public boolean hasShowAllColLabels(
+ ) {
+ return this._has_showAllColLabels;
+ }
+
+ /**
+ * Method hasVisible.
+ *
+ * @return true if at least one Visible has been added
+ */
+ public boolean hasVisible(
+ ) {
+ return this._has_visible;
+ }
+
+ /**
+ * Returns the value of field 'autoCalculated'. The field
+ * 'autoCalculated' has the following description: is an
+ * autocalculated annotation row
+ *
+ * @return the value of field 'AutoCalculated'.
+ */
+ public boolean isAutoCalculated(
+ ) {
+ return this._autoCalculated;
+ }
+
+ /**
+ * Returns the value of field 'belowAlignment'. The field
+ * 'belowAlignment' has the following description: is to be
+ * shown below the alignment - introduced in Jalview 2.8 for
+ * visualizing T-COFFEE alignment scores
+ *
+ * @return the value of field 'BelowAlignment'.
+ */
+ public boolean isBelowAlignment(
+ ) {
+ return this._belowAlignment;
+ }
+
+ /**
+ * Returns the value of field 'centreColLabels'.
+ *
+ * @return the value of field 'CentreColLabels'.
+ */
+ public boolean isCentreColLabels(
+ ) {
+ return this._centreColLabels;
+ }
+
+ /**
+ * Returns the value of field 'graph'.
+ *
+ * @return the value of field 'Graph'.
+ */
+ public boolean isGraph(
+ ) {
+ return this._graph;
+ }
+
+ /**
+ * Returns the value of field 'scaleColLabels'.
+ *
+ * @return the value of field 'ScaleColLabels'.
+ */
+ public boolean isScaleColLabels(
+ ) {
+ return this._scaleColLabels;
+ }
+
+ /**
+ * Returns the value of field 'scoreOnly'.
+ *
+ * @return the value of field 'ScoreOnly'.
+ */
+ public boolean isScoreOnly(
+ ) {
+ return this._scoreOnly;
+ }
+
+ /**
+ * Returns the value of field 'showAllColLabels'.
+ *
+ * @return the value of field 'ShowAllColLabels'.
+ */
+ public boolean isShowAllColLabels(
+ ) {
+ return this._showAllColLabels;
+ }
+
+ /**
+ * Method isValid.
+ *
+ * @return true if this object is valid according to the schema
+ */
+ public boolean isValid(
+ ) {
+ try {
+ validate();
+ } catch (org.exolab.castor.xml.ValidationException vex) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns the value of field 'visible'.
+ *
+ * @return the value of field 'Visible'.
+ */
+ public boolean isVisible(
+ ) {
+ return this._visible;
+ }
+
+ /**
+ *
+ *
+ * @param out
+ * @throws org.exolab.castor.xml.MarshalException if object is
+ * null or if any SAXException is thrown during marshaling
+ * @throws org.exolab.castor.xml.ValidationException if this
+ * object is an invalid instance according to the schema
+ */
+ public void marshal(
+ final java.io.Writer out)
+ throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
+ Marshaller.marshal(this, out);
+ }
+
+ /**
+ *
+ *
+ * @param handler
+ * @throws java.io.IOException if an IOException occurs during
+ * marshaling
+ * @throws org.exolab.castor.xml.ValidationException if this
+ * object is an invalid instance according to the schema
+ * @throws org.exolab.castor.xml.MarshalException if object is
+ * null or if any SAXException is thrown during marshaling
+ */
+ public void marshal(
+ final org.xml.sax.ContentHandler handler)
+ throws java.io.IOException, org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
+ Marshaller.marshal(this, handler);
+ }
+
+ /**
+ */
+ public void removeAllAnnotationElement(
+ ) {
+ this._annotationElementList.clear();
+ }
+
+ /**
+ */
+ public void removeAllProperty(
+ ) {
+ this._propertyList.clear();
+ }
+
+ /**
+ * Method removeAnnotationElement.
+ *
+ * @param vAnnotationElement
+ * @return true if the object was removed from the collection.
+ */
+ public boolean removeAnnotationElement(
+ final jalview.schemabinding.version2.AnnotationElement vAnnotationElement) {
+ boolean removed = _annotationElementList.remove(vAnnotationElement);
+ return removed;
+ }
+
+ /**
+ * Method removeAnnotationElementAt.
+ *
+ * @param index
+ * @return the element removed from the collection
+ */
+ public jalview.schemabinding.version2.AnnotationElement removeAnnotationElementAt(
+ final int index) {
+ java.lang.Object obj = this._annotationElementList.remove(index);
+ return (jalview.schemabinding.version2.AnnotationElement) obj;
+ }
+
+ /**
+ * Method removeProperty.
+ *
+ * @param vProperty
+ * @return true if the object was removed from the collection.
+ */
+ public boolean removeProperty(
+ final jalview.schemabinding.version2.Property vProperty) {
+ boolean removed = _propertyList.remove(vProperty);
+ return removed;
+ }
+
+ /**
+ * Method removePropertyAt.
+ *
+ * @param index
+ * @return the element removed from the collection
+ */
+ public jalview.schemabinding.version2.Property removePropertyAt(
+ final int index) {
+ java.lang.Object obj = this._propertyList.remove(index);
+ return (jalview.schemabinding.version2.Property) obj;
+ }
+
+ /**
+ *
+ *
+ * @param index
+ * @param vAnnotationElement
+ * @throws java.lang.IndexOutOfBoundsException if the index
+ * given is outside the bounds of the collection
+ */
+ public void setAnnotationElement(
+ final int index,
+ final jalview.schemabinding.version2.AnnotationElement vAnnotationElement)
+ throws java.lang.IndexOutOfBoundsException {
+ // check bounds for index
+ if (index < 0 || index >= this._annotationElementList.size()) {
+ throw new IndexOutOfBoundsException("setAnnotationElement: Index value '" + index + "' not in range [0.." + (this._annotationElementList.size() - 1) + "]");
+ }
+
+ this._annotationElementList.set(index, vAnnotationElement);
+ }
+
+ /**
+ *
+ *
+ * @param vAnnotationElementArray
+ */
+ public void setAnnotationElement(
+ final jalview.schemabinding.version2.AnnotationElement[] vAnnotationElementArray) {
+ //-- copy array
+ _annotationElementList.clear();
+
+ for (int i = 0; i < vAnnotationElementArray.length; i++) {
+ this._annotationElementList.add(vAnnotationElementArray[i]);
+ }
+ }
+
+ /**
+ * Sets the value of field 'autoCalculated'. The field
+ * 'autoCalculated' has the following description: is an
+ * autocalculated annotation row
+ *
+ * @param autoCalculated the value of field 'autoCalculated'.
+ */
+ public void setAutoCalculated(
+ final boolean autoCalculated) {
+ this._autoCalculated = autoCalculated;
+ this._has_autoCalculated = true;
+ }
+
+ /**
+ * Sets the value of field 'belowAlignment'. The field
+ * 'belowAlignment' has the following description: is to be
+ * shown below the alignment - introduced in Jalview 2.8 for
+ * visualizing T-COFFEE alignment scores
+ *
+ * @param belowAlignment the value of field 'belowAlignment'.
+ */
+ public void setBelowAlignment(
+ final boolean belowAlignment) {
+ this._belowAlignment = belowAlignment;
+ this._has_belowAlignment = true;
+ }
+
+ /**
+ * Sets the value of field 'calcId'. The field 'calcId' has the
+ * following description: Optional string identifier used to
+ * group sets of annotation produced by a particular
+ * calculation. Values are opaque strings but have semantic
+ * meaning to Jalview's renderer, data importer and calculation
+ * system.
+ *
+ * @param calcId the value of field 'calcId'.
+ */
+ public void setCalcId(
+ final java.lang.String calcId) {
+ this._calcId = calcId;
+ }
+
+ /**
+ * Sets the value of field 'centreColLabels'.
+ *
+ * @param centreColLabels the value of field 'centreColLabels'.
+ */
+ public void setCentreColLabels(
+ final boolean centreColLabels) {
+ this._centreColLabels = centreColLabels;
+ this._has_centreColLabels = true;
+ }
+
+ /**
+ * Sets the value of field 'description'.
+ *
+ * @param description the value of field 'description'.
+ */
+ public void setDescription(
+ final java.lang.String description) {
+ this._description = description;
+ }
+
+ /**
+ * Sets the value of field 'graph'.
+ *
+ * @param graph the value of field 'graph'.
+ */
+ public void setGraph(
+ final boolean graph) {
+ this._graph = graph;
+ this._has_graph = true;
+ }
+
+ /**
+ * Sets the value of field 'graphColour'.
+ *
+ * @param graphColour the value of field 'graphColour'.
+ */
+ public void setGraphColour(
+ final int graphColour) {
+ this._graphColour = graphColour;
+ this._has_graphColour = true;
+ }
+
+ /**
+ * Sets the value of field 'graphGroup'.
+ *
+ * @param graphGroup the value of field 'graphGroup'.
+ */
+ public void setGraphGroup(
+ final int graphGroup) {
+ this._graphGroup = graphGroup;
+ this._has_graphGroup = true;
+ }
+
+ /**
+ * Sets the value of field 'graphHeight'. The field
+ * 'graphHeight' has the following description: height in
+ * pixels for the graph if this is a graph-type annotation.
+ *
+ * @param graphHeight the value of field 'graphHeight'.
+ */
+ public void setGraphHeight(
+ final int graphHeight) {
+ this._graphHeight = graphHeight;
+ this._has_graphHeight = true;
+ }
+
+ /**
+ * Sets the value of field 'graphType'.
+ *
+ * @param graphType the value of field 'graphType'.
+ */
+ public void setGraphType(
+ final int graphType) {
+ this._graphType = graphType;
+ this._has_graphType = true;
+ }
+
+ /**
+ * Sets the value of field 'groupRef'.
+ *
+ * @param groupRef the value of field 'groupRef'.
+ */
+ public void setGroupRef(
+ final java.lang.String groupRef) {
+ this._groupRef = groupRef;
+ }
+
+ /**
+ * Sets the value of field 'id'.
+ *
+ * @param id the value of field 'id'.
+ */
+ public void setId(
+ final java.lang.String id) {
+ this._id = id;
+ }
+
+ /**
+ * Sets the value of field 'label'.
+ *
+ * @param label the value of field 'label'.
+ */
+ public void setLabel(
+ final java.lang.String label) {
+ this._label = label;
+ }
+
+ /**
+ *
+ *
+ * @param index
+ * @param vProperty
+ * @throws java.lang.IndexOutOfBoundsException if the index
+ * given is outside the bounds of the collection
+ */
+ public void setProperty(
+ final int index,
+ final jalview.schemabinding.version2.Property vProperty)
+ throws java.lang.IndexOutOfBoundsException {
+ // check bounds for index
+ if (index < 0 || index >= this._propertyList.size()) {
+ throw new IndexOutOfBoundsException("setProperty: Index value '" + index + "' not in range [0.." + (this._propertyList.size() - 1) + "]");
+ }
+
+ this._propertyList.set(index, vProperty);
+ }
+
+ /**
+ *
+ *
+ * @param vPropertyArray
+ */
+ public void setProperty(
+ final jalview.schemabinding.version2.Property[] vPropertyArray) {
+ //-- copy array
+ _propertyList.clear();
+
+ for (int i = 0; i < vPropertyArray.length; i++) {
+ this._propertyList.add(vPropertyArray[i]);
+ }
+ }
+
+ /**
+ * Sets the value of field 'scaleColLabels'.
+ *
+ * @param scaleColLabels the value of field 'scaleColLabels'.
+ */
+ public void setScaleColLabels(
+ final boolean scaleColLabels) {
+ this._scaleColLabels = scaleColLabels;
+ this._has_scaleColLabels = true;
+ }
+
+ /**
+ * Sets the value of field 'score'.
+ *
+ * @param score the value of field 'score'.
+ */
+ public void setScore(
+ final double score) {
+ this._score = score;
+ this._has_score = true;
+ }
+
+ /**
+ * Sets the value of field 'scoreOnly'.
+ *
+ * @param scoreOnly the value of field 'scoreOnly'.
+ */
+ public void setScoreOnly(
+ final boolean scoreOnly) {
+ this._scoreOnly = scoreOnly;
+ this._has_scoreOnly = true;
+ }
+
+ /**
+ * Sets the value of field 'sequenceRef'.
+ *
+ * @param sequenceRef the value of field 'sequenceRef'.
+ */
+ public void setSequenceRef(
+ final java.lang.String sequenceRef) {
+ this._sequenceRef = sequenceRef;
+ }
+
+ /**
+ * Sets the value of field 'showAllColLabels'.
+ *
+ * @param showAllColLabels the value of field 'showAllColLabels'
+ */
+ public void setShowAllColLabels(
+ final boolean showAllColLabels) {
+ this._showAllColLabels = showAllColLabels;
+ this._has_showAllColLabels = true;
+ }
+
+ /**
+ * Sets the value of field 'thresholdLine'.
+ *
+ * @param thresholdLine the value of field 'thresholdLine'.
+ */
+ public void setThresholdLine(
+ final jalview.schemabinding.version2.ThresholdLine thresholdLine) {
+ this._thresholdLine = thresholdLine;
+ }
+
+ /**
+ * Sets the value of field 'visible'.
+ *
+ * @param visible the value of field 'visible'.
+ */
+ public void setVisible(
+ final boolean visible) {
+ this._visible = visible;
+ this._has_visible = true;
+ }
+
+ /**
+ * Method unmarshal.
+ *
+ * @param reader
+ * @throws org.exolab.castor.xml.MarshalException if object is
+ * null or if any SAXException is thrown during marshaling
+ * @throws org.exolab.castor.xml.ValidationException if this
+ * object is an invalid instance according to the schema
+ * @return the unmarshaled
+ * jalview.schemabinding.version2.Annotation
+ */
+ public static jalview.schemabinding.version2.Annotation unmarshal(
+ final java.io.Reader reader)
+ throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
+ return (jalview.schemabinding.version2.Annotation) Unmarshaller.unmarshal(jalview.schemabinding.version2.Annotation.class, reader);
+ }
+
+ /**
+ *
+ *
+ * @throws org.exolab.castor.xml.ValidationException if this
+ * object is an invalid instance according to the schema
+ */
+ public void validate(
+ )
+ throws org.exolab.castor.xml.ValidationException {
+ org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator();
+ validator.validate(this);
+ }
}
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._otherDataList.size())
{
- throw new IndexOutOfBoundsException("getOtherData: Index value '"
- + index + "' not in range [0.."
- + (this._otherDataList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getOtherData",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._otherDataList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.OtherData) _otherDataList
// check bounds for index
if (index < 0 || index >= this._otherDataList.size())
{
- throw new IndexOutOfBoundsException("setOtherData: Index value '"
- + index + "' not in range [0.."
- + (this._otherDataList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setOtherData",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._otherDataList.size() - 1)).toString()
+ }));
}
this._otherDataList.set(index, vOtherData);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._groupList.size())
{
- throw new IndexOutOfBoundsException("getGroup: Index value '" + index
- + "' not in range [0.." + (this._groupList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getGroup",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._groupList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.Group) _groupList.get(index);
// check bounds for index
if (index < 0 || index >= this._settingList.size())
{
- throw new IndexOutOfBoundsException("getSetting: Index value '"
- + index + "' not in range [0.."
- + (this._settingList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getSetting",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._settingList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.Setting) _settingList.get(index);
// check bounds for index
if (index < 0 || index >= this._groupList.size())
{
- throw new IndexOutOfBoundsException("setGroup: Index value '" + index
- + "' not in range [0.." + (this._groupList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setGroup",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._groupList.size() - 1)).toString()
+ }));
}
this._groupList.set(index, vGroup);
// check bounds for index
if (index < 0 || index >= this._settingList.size())
{
- throw new IndexOutOfBoundsException("setSetting: Index value '"
- + index + "' not in range [0.."
- + (this._settingList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setSetting",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._settingList.size() - 1)).toString()
+ }));
}
this._settingList.set(index, vSetting);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._seqList.size())
{
- throw new IndexOutOfBoundsException("getSeq: Index value '" + index
- + "' not in range [0.." + (this._seqList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getSeq",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._seqList.size() - 1)).toString()
+ }));
}
return (java.lang.String) _seqList.get(index);
// check bounds for index
if (index < 0 || index >= this._seqList.size())
{
- throw new IndexOutOfBoundsException("setSeq: Index value '" + index
- + "' not in range [0.." + (this._seqList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setSeq",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._seqList.size() - 1)).toString()
+ }));
}
this._seqList.set(index, vSeq);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._featuresList.size())
{
- throw new IndexOutOfBoundsException("getFeatures: Index value '"
- + index + "' not in range [0.."
- + (this._featuresList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getFeatures",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._featuresList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.Features) _featuresList
// check bounds for index
if (index < 0 || index >= this._hiddenSequencesList.size())
{
- throw new IndexOutOfBoundsException(
- "getHiddenSequences: Index value '" + index
- + "' not in range [0.."
- + (this._hiddenSequencesList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getHiddenSequences",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._hiddenSequencesList.size() - 1)).toString()
+ }));
}
return ((java.lang.Integer) _hiddenSequencesList.get(index)).intValue();
// check bounds for index
if (index < 0 || index >= this._pdbidsList.size())
{
- throw new IndexOutOfBoundsException("getPdbids: Index value '"
- + index + "' not in range [0.."
- + (this._pdbidsList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getPdbids",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._pdbidsList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.Pdbids) _pdbidsList.get(index);
// check bounds for index
if (index < 0 || index >= this._featuresList.size())
{
- throw new IndexOutOfBoundsException("setFeatures: Index value '"
- + index + "' not in range [0.."
- + (this._featuresList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setFeatures",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._featuresList.size() - 1)).toString()
+ }));
}
this._featuresList.set(index, vFeatures);
// check bounds for index
if (index < 0 || index >= this._hiddenSequencesList.size())
{
- throw new IndexOutOfBoundsException(
- "setHiddenSequences: Index value '" + index
- + "' not in range [0.."
- + (this._hiddenSequencesList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setHiddenSequences",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._hiddenSequencesList.size() - 1)).toString()
+ }));
}
this._hiddenSequencesList.set(index, new java.lang.Integer(
// check bounds for index
if (index < 0 || index >= this._pdbidsList.size())
{
- throw new IndexOutOfBoundsException("setPdbids: Index value '"
- + index + "' not in range [0.."
- + (this._pdbidsList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setPdbids",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._pdbidsList.size() - 1)).toString()
+ }));
}
this._pdbidsList.set(index, vPdbids);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._JGroupList.size())
{
- throw new IndexOutOfBoundsException("getJGroup: Index value '"
- + index + "' not in range [0.."
- + (this._JGroupList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getJGroup",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._JGroupList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.JGroup) _JGroupList.get(index);
// check bounds for index
if (index < 0 || index >= this._JSeqList.size())
{
- throw new IndexOutOfBoundsException("getJSeq: Index value '" + index
- + "' not in range [0.." + (this._JSeqList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getJSeq",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._JSeqList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.JSeq) _JSeqList.get(index);
// check bounds for index
if (index < 0 || index >= this._treeList.size())
{
- throw new IndexOutOfBoundsException("getTree: Index value '" + index
- + "' not in range [0.." + (this._treeList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getJgetTreeSeq",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._treeList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.Tree) _treeList.get(index);
// check bounds for index
if (index < 0 || index >= this._userColoursList.size())
{
- throw new IndexOutOfBoundsException("getUserColours: Index value '"
- + index + "' not in range [0.."
- + (this._userColoursList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getUserColours",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._userColoursList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.UserColours) _userColoursList
// check bounds for index
if (index < 0 || index >= this._viewportList.size())
{
- throw new IndexOutOfBoundsException("getViewport: Index value '"
- + index + "' not in range [0.."
- + (this._viewportList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getViewport",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._viewportList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.Viewport) _viewportList
// check bounds for index
if (index < 0 || index >= this._JGroupList.size())
{
- throw new IndexOutOfBoundsException("setJGroup: Index value '"
- + index + "' not in range [0.."
- + (this._JGroupList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setJGroup",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._JGroupList.size() - 1)).toString()
+ }));
}
this._JGroupList.set(index, vJGroup);
// check bounds for index
if (index < 0 || index >= this._JSeqList.size())
{
- throw new IndexOutOfBoundsException("setJSeq: Index value '" + index
- + "' not in range [0.." + (this._JSeqList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setJSeq",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._JSeqList.size() - 1)).toString()
+ }));
}
this._JSeqList.set(index, vJSeq);
// check bounds for index
if (index < 0 || index >= this._treeList.size())
{
- throw new IndexOutOfBoundsException("setTree: Index value '" + index
- + "' not in range [0.." + (this._treeList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setTree",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._treeList.size() - 1)).toString()
+ }));
}
this._treeList.set(index, vTree);
// check bounds for index
if (index < 0 || index >= this._userColoursList.size())
{
- throw new IndexOutOfBoundsException("setUserColours: Index value '"
- + index + "' not in range [0.."
- + (this._userColoursList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setUserColours",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._userColoursList.size() - 1)).toString()
+ }));
}
this._userColoursList.set(index, vUserColours);
// check bounds for index
if (index < 0 || index >= this._viewportList.size())
{
- throw new IndexOutOfBoundsException("setViewport: Index value '"
- + index + "' not in range [0.."
- + (this._viewportList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setViewport",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._viewportList.size() - 1)).toString()
+ }));
}
this._viewportList.set(index, vViewport);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._colourList.size())
{
- throw new IndexOutOfBoundsException("getColour: Index value '"
- + index + "' not in range [0.."
- + (this._colourList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getColour",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._colourList.size() - 1)).toString()
+ }));
}
return (Colour) _colourList.get(index);
// check bounds for index
if (index < 0 || index >= this._colourList.size())
{
- throw new IndexOutOfBoundsException("setColour: Index value '"
- + index + "' not in range [0.."
- + (this._colourList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setColour",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._colourList.size() - 1)).toString()
+ }));
}
this._colourList.set(index, vColour);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._mapListFromList.size())
{
- throw new IndexOutOfBoundsException("getMapListFrom: Index value '"
- + index + "' not in range [0.."
- + (this._mapListFromList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getMapListFrom",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._mapListFromList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.MapListFrom) _mapListFromList
// check bounds for index
if (index < 0 || index >= this._mapListToList.size())
{
- throw new IndexOutOfBoundsException("getMapListTo: Index value '"
- + index + "' not in range [0.."
- + (this._mapListToList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getMapListTo",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._mapListToList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.MapListTo) _mapListToList
// check bounds for index
if (index < 0 || index >= this._mapListFromList.size())
{
- throw new IndexOutOfBoundsException("setMapListFrom: Index value '"
- + index + "' not in range [0.."
- + (this._mapListFromList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setMapListFrom",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._mapListFromList.size() - 1)).toString()
+ }));
}
this._mapListFromList.set(index, vMapListFrom);
// check bounds for index
if (index < 0 || index >= this._mapListToList.size())
{
- throw new IndexOutOfBoundsException("setMapListTo: Index value '"
- + index + "' not in range [0.."
- + (this._mapListToList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setMapListTo",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._mapListToList.size() - 1)).toString()
+ }));
}
this._mapListToList.set(index, vMapListTo);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._items.size())
{
- throw new IndexOutOfBoundsException("getPdbentryItem: Index value '"
- + index + "' not in range [0.." + (this._items.size() - 1)
- + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getPdbentryItem",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._items.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.PdbentryItem) _items.get(index);
// check bounds for index
if (index < 0 || index >= this._items.size())
{
- throw new IndexOutOfBoundsException("setPdbentryItem: Index value '"
- + index + "' not in range [0.." + (this._items.size() - 1)
- + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setPdbentryItem",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._items.size() - 1)).toString()
+ }));
}
this._items.set(index, vPdbentryItem);
*/
package jalview.schemabinding.version2;
+import jalview.util.MessageManager;
+
/**
* Class PdbentryItem.
*
// check bounds for index
if (index < 0 || index >= this._propertyList.size())
{
- throw new IndexOutOfBoundsException("getProperty: Index value '"
- + index + "' not in range [0.."
- + (this._propertyList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getProperty",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._propertyList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.Property) _propertyList
// check bounds for index
if (index < 0 || index >= this._propertyList.size())
{
- throw new IndexOutOfBoundsException("setProperty: Index value '"
- + index + "' not in range [0.."
- + (this._propertyList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setProperty",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._propertyList.size() - 1)).toString()
+ }));
}
this._propertyList.set(index, vProperty);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._structureStateList.size())
{
- throw new IndexOutOfBoundsException(
- "getStructureState: Index value '" + index
- + "' not in range [0.."
- + (this._structureStateList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getStructureState",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._structureStateList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.StructureState) _structureStateList
// check bounds for index
if (index < 0 || index >= this._structureStateList.size())
{
- throw new IndexOutOfBoundsException(
- "setStructureState: Index value '" + index
- + "' not in range [0.."
- + (this._structureStateList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setStructureState",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._structureStateList.size() - 1)).toString()
+ }));
}
this._structureStateList.set(index, vStructureState);
/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
- *
- * This file is part of Jalview.
- *
- * Jalview 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.
- *
- * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
+ * This class was automatically generated with
+ * <a href="http://www.castor.org">Castor 1.1</a>, using an XML
+ * Schema.
+ * $Id$
*/
+
package jalview.schemabinding.version2;
-//---------------------------------/
-//- Imported classes and packages -/
+ //---------------------------------/
+ //- Imported classes and packages -/
//---------------------------------/
import org.exolab.castor.xml.Marshaller;
*
* @version $Revision$ $Date$
*/
-public class Property implements java.io.Serializable
-{
-
- // --------------------------/
- // - Class/Member Variables -/
- // --------------------------/
-
- /**
- * Field _name.
- */
- private java.lang.String _name;
-
- /**
- * Field _value.
- */
- private java.lang.String _value;
-
- // ----------------/
- // - Constructors -/
- // ----------------/
-
- public Property()
- {
- super();
- }
-
- // -----------/
- // - Methods -/
- // -----------/
-
- /**
- * Returns the value of field 'name'.
- *
- * @return the value of field 'Name'.
- */
- public java.lang.String getName()
- {
- return this._name;
- }
-
- /**
- * Returns the value of field 'value'.
- *
- * @return the value of field 'Value'.
- */
- public java.lang.String getValue()
- {
- return this._value;
- }
-
- /**
- * Method isValid.
- *
- * @return true if this object is valid according to the schema
- */
- public boolean isValid()
- {
- try
- {
- validate();
- } catch (org.exolab.castor.xml.ValidationException vex)
- {
- return false;
+public class Property implements java.io.Serializable {
+
+
+ //--------------------------/
+ //- Class/Member Variables -/
+ //--------------------------/
+
+ /**
+ * Field _name.
+ */
+ private java.lang.String _name;
+
+ /**
+ * Field _value.
+ */
+ private java.lang.String _value;
+
+
+ //----------------/
+ //- Constructors -/
+ //----------------/
+
+ public Property() {
+ super();
+ }
+
+
+ //-----------/
+ //- Methods -/
+ //-----------/
+
+ /**
+ * Returns the value of field 'name'.
+ *
+ * @return the value of field 'Name'.
+ */
+ public java.lang.String getName(
+ ) {
+ return this._name;
+ }
+
+ /**
+ * Returns the value of field 'value'.
+ *
+ * @return the value of field 'Value'.
+ */
+ public java.lang.String getValue(
+ ) {
+ return this._value;
+ }
+
+ /**
+ * Method isValid.
+ *
+ * @return true if this object is valid according to the schema
+ */
+ public boolean isValid(
+ ) {
+ try {
+ validate();
+ } catch (org.exolab.castor.xml.ValidationException vex) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ *
+ *
+ * @param out
+ * @throws org.exolab.castor.xml.MarshalException if object is
+ * null or if any SAXException is thrown during marshaling
+ * @throws org.exolab.castor.xml.ValidationException if this
+ * object is an invalid instance according to the schema
+ */
+ public void marshal(
+ final java.io.Writer out)
+ throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
+ Marshaller.marshal(this, out);
+ }
+
+ /**
+ *
+ *
+ * @param handler
+ * @throws java.io.IOException if an IOException occurs during
+ * marshaling
+ * @throws org.exolab.castor.xml.ValidationException if this
+ * object is an invalid instance according to the schema
+ * @throws org.exolab.castor.xml.MarshalException if object is
+ * null or if any SAXException is thrown during marshaling
+ */
+ public void marshal(
+ final org.xml.sax.ContentHandler handler)
+ throws java.io.IOException, org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
+ Marshaller.marshal(this, handler);
+ }
+
+ /**
+ * Sets the value of field 'name'.
+ *
+ * @param name the value of field 'name'.
+ */
+ public void setName(
+ final java.lang.String name) {
+ this._name = name;
+ }
+
+ /**
+ * Sets the value of field 'value'.
+ *
+ * @param value the value of field 'value'.
+ */
+ public void setValue(
+ final java.lang.String value) {
+ this._value = value;
+ }
+
+ /**
+ * Method unmarshal.
+ *
+ * @param reader
+ * @throws org.exolab.castor.xml.MarshalException if object is
+ * null or if any SAXException is thrown during marshaling
+ * @throws org.exolab.castor.xml.ValidationException if this
+ * object is an invalid instance according to the schema
+ * @return the unmarshaled
+ * jalview.schemabinding.version2.Property
+ */
+ public static jalview.schemabinding.version2.Property unmarshal(
+ final java.io.Reader reader)
+ throws org.exolab.castor.xml.MarshalException, org.exolab.castor.xml.ValidationException {
+ return (jalview.schemabinding.version2.Property) Unmarshaller.unmarshal(jalview.schemabinding.version2.Property.class, reader);
+ }
+
+ /**
+ *
+ *
+ * @throws org.exolab.castor.xml.ValidationException if this
+ * object is an invalid instance according to the schema
+ */
+ public void validate(
+ )
+ throws org.exolab.castor.xml.ValidationException {
+ org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator();
+ validator.validate(this);
}
- return true;
- }
-
- /**
- *
- *
- * @param out
- * @throws org.exolab.castor.xml.MarshalException
- * if object is null or if any SAXException is thrown during
- * marshaling
- * @throws org.exolab.castor.xml.ValidationException
- * if this object is an invalid instance according to the schema
- */
- public void marshal(final java.io.Writer out)
- throws org.exolab.castor.xml.MarshalException,
- org.exolab.castor.xml.ValidationException
- {
- Marshaller.marshal(this, out);
- }
-
- /**
- *
- *
- * @param handler
- * @throws java.io.IOException
- * if an IOException occurs during marshaling
- * @throws org.exolab.castor.xml.ValidationException
- * if this object is an invalid instance according to the schema
- * @throws org.exolab.castor.xml.MarshalException
- * if object is null or if any SAXException is thrown during
- * marshaling
- */
- public void marshal(final org.xml.sax.ContentHandler handler)
- throws java.io.IOException,
- org.exolab.castor.xml.MarshalException,
- org.exolab.castor.xml.ValidationException
- {
- Marshaller.marshal(this, handler);
- }
-
- /**
- * Sets the value of field 'name'.
- *
- * @param name
- * the value of field 'name'.
- */
- public void setName(final java.lang.String name)
- {
- this._name = name;
- }
-
- /**
- * Sets the value of field 'value'.
- *
- * @param value
- * the value of field 'value'.
- */
- public void setValue(final java.lang.String value)
- {
- this._value = value;
- }
-
- /**
- * Method unmarshal.
- *
- * @param reader
- * @throws org.exolab.castor.xml.MarshalException
- * if object is null or if any SAXException is thrown during
- * marshaling
- * @throws org.exolab.castor.xml.ValidationException
- * if this object is an invalid instance according to the schema
- * @return the unmarshaled jalview.schemabinding.version2.Property
- */
- public static jalview.schemabinding.version2.Property unmarshal(
- final java.io.Reader reader)
- throws org.exolab.castor.xml.MarshalException,
- org.exolab.castor.xml.ValidationException
- {
- return (jalview.schemabinding.version2.Property) Unmarshaller
- .unmarshal(jalview.schemabinding.version2.Property.class,
- reader);
- }
-
- /**
- *
- *
- * @throws org.exolab.castor.xml.ValidationException
- * if this object is an invalid instance according to the schema
- */
- public void validate() throws org.exolab.castor.xml.ValidationException
- {
- org.exolab.castor.xml.Validator validator = new org.exolab.castor.xml.Validator();
- validator.validate(this);
- }
}
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._DBRefList.size())
{
- throw new IndexOutOfBoundsException("getDBRef: Index value '" + index
- + "' not in range [0.." + (this._DBRefList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getDBRef",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._DBRefList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.DBRef) _DBRefList.get(index);
// check bounds for index
if (index < 0 || index >= this._DBRefList.size())
{
- throw new IndexOutOfBoundsException("setDBRef: Index value '" + index
- + "' not in range [0.." + (this._DBRefList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setDBRef",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._DBRefList.size() - 1)).toString()
+ }));
}
this._DBRefList.set(index, vDBRef);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._alcodonFrameList.size())
{
- throw new IndexOutOfBoundsException("getAlcodonFrame: Index value '"
- + index + "' not in range [0.."
- + (this._alcodonFrameList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getAlcodonFrame",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._alcodonFrameList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.AlcodonFrame) _alcodonFrameList
// check bounds for index
if (index < 0 || index >= this._annotationList.size())
{
- throw new IndexOutOfBoundsException("getAnnotation: Index value '"
- + index + "' not in range [0.."
- + (this._annotationList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getAnnotation",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._alcodonFrameList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.Annotation) _annotationList
// check bounds for index
if (index < 0 || index >= this._sequenceList.size())
{
- throw new IndexOutOfBoundsException("getSequence: Index value '"
- + index + "' not in range [0.."
- + (this._sequenceList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getSequence",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._sequenceList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.Sequence) _sequenceList
// check bounds for index
if (index < 0 || index >= this._sequenceSetPropertiesList.size())
{
- throw new IndexOutOfBoundsException(
- "getSequenceSetProperties: Index value '" + index
- + "' not in range [0.."
- + (this._sequenceSetPropertiesList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getSequenceSetProperties",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._sequenceSetPropertiesList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.SequenceSetProperties) _sequenceSetPropertiesList
// check bounds for index
if (index < 0 || index >= this._alcodonFrameList.size())
{
- throw new IndexOutOfBoundsException("setAlcodonFrame: Index value '"
- + index + "' not in range [0.."
- + (this._alcodonFrameList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setAlcodonFrame",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._alcodonFrameList.size() - 1)).toString()
+ }));
}
this._alcodonFrameList.set(index, vAlcodonFrame);
// check bounds for index
if (index < 0 || index >= this._annotationList.size())
{
- throw new IndexOutOfBoundsException("setAnnotation: Index value '"
- + index + "' not in range [0.."
- + (this._annotationList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setAnnotation",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._annotationList.size() - 1)).toString()
+ }));
}
this._annotationList.set(index, vAnnotation);
// check bounds for index
if (index < 0 || index >= this._sequenceList.size())
{
- throw new IndexOutOfBoundsException("setSequence: Index value '"
- + index + "' not in range [0.."
- + (this._sequenceList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setSequence",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._sequenceList.size() - 1)).toString()
+ }));
}
this._sequenceList.set(index, vSequence);
// check bounds for index
if (index < 0 || index >= this._sequenceSetPropertiesList.size())
{
- throw new IndexOutOfBoundsException(
- "setSequenceSetProperties: Index value '" + index
- + "' not in range [0.."
- + (this._sequenceSetPropertiesList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setSequenceSetProperties",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._sequenceSetPropertiesList.size() - 1)).toString()
+ }));
}
this._sequenceSetPropertiesList.set(index, vSequenceSetProperties);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._sequenceSetList.size())
{
- throw new IndexOutOfBoundsException("getSequenceSet: Index value '"
- + index + "' not in range [0.."
- + (this._sequenceSetList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getSequenceSet",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._sequenceSetList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.SequenceSet) _sequenceSetList
// check bounds for index
if (index < 0 || index >= this._treeList.size())
{
- throw new IndexOutOfBoundsException("getTree: Index value '" + index
- + "' not in range [0.." + (this._treeList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getTree",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._treeList.size() - 1)).toString()
+ }));
}
return (java.lang.String) _treeList.get(index);
// check bounds for index
if (index < 0 || index >= this._sequenceSetList.size())
{
- throw new IndexOutOfBoundsException("setSequenceSet: Index value '"
- + index + "' not in range [0.."
- + (this._sequenceSetList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setSequenceSet",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._sequenceSetList.size() - 1)).toString()
+ }));
}
this._sequenceSetList.set(index, vSequenceSet);
// check bounds for index
if (index < 0 || index >= this._treeList.size())
{
- throw new IndexOutOfBoundsException("setTree: Index value '" + index
- + "' not in range [0.." + (this._treeList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setTree",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._treeList.size() - 1)).toString()
+ }));
}
this._treeList.set(index, vTree);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._calcIdParamList.size())
{
- throw new IndexOutOfBoundsException("getCalcIdParam: Index value '"
- + index + "' not in range [0.."
- + (this._calcIdParamList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getCalcIdParam",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._calcIdParamList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.CalcIdParam) _calcIdParamList
// check bounds for index
if (index < 0 || index >= this._hiddenColumnsList.size())
{
- throw new IndexOutOfBoundsException("getHiddenColumns: Index value '"
- + index + "' not in range [0.."
- + (this._hiddenColumnsList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getHiddenColumns",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._hiddenColumnsList.size() - 1)).toString()
+ }));
}
return (jalview.schemabinding.version2.HiddenColumns) _hiddenColumnsList
// check bounds for index
if (index < 0 || index >= this._calcIdParamList.size())
{
- throw new IndexOutOfBoundsException("setCalcIdParam: Index value '"
- + index + "' not in range [0.."
- + (this._calcIdParamList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setCalcIdParam",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._calcIdParamList.size() - 1)).toString()
+ }));
}
this._calcIdParamList.set(index, vCalcIdParam);
// check bounds for index
if (index < 0 || index >= this._hiddenColumnsList.size())
{
- throw new IndexOutOfBoundsException("setHiddenColumns: Index value '"
- + index + "' not in range [0.."
- + (this._hiddenColumnsList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setHiddenColumns",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._hiddenColumnsList.size() - 1)).toString()
+ }));
}
this._hiddenColumnsList.set(index, vHiddenColumns);
//- Imported classes and packages -/
//---------------------------------/
+import jalview.util.MessageManager;
+
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
// check bounds for index
if (index < 0 || index >= this._serviceURLList.size())
{
- throw new IndexOutOfBoundsException("getServiceURL: Index value '"
- + index + "' not in range [0.."
- + (this._serviceURLList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "getServiceURL",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._serviceURLList.size() - 1)).toString()
+ }));
}
return (java.lang.String) _serviceURLList.get(index);
// check bounds for index
if (index < 0 || index >= this._serviceURLList.size())
{
- throw new IndexOutOfBoundsException("setServiceURL: Index value '"
- + index + "' not in range [0.."
- + (this._serviceURLList.size() - 1) + "]");
+ throw new IndexOutOfBoundsException(MessageManager.formatMessage("exception.index_value_not_in_range", new String[]{
+ "setServiceURL",
+ Integer.valueOf(index).toString(),
+ Integer.valueOf((this._serviceURLList.size() - 1)).toString()
+ }));
}
this._serviceURLList.set(index, vServiceURL);
*/
package jalview.schemabinding.version2.descriptors;
-//---------------------------------/
-//- Imported classes and packages -/
+ //---------------------------------/
+ //- Imported classes and packages -/
//---------------------------------/
import jalview.schemabinding.version2.Annotation;
*
* @version $Revision$ $Date$
*/
-public class AnnotationDescriptor extends
- org.exolab.castor.xml.util.XMLClassDescriptorImpl
-{
-
- // --------------------------/
- // - Class/Member Variables -/
- // --------------------------/
-
- /**
- * Field _elementDefinition.
- */
- private boolean _elementDefinition;
-
- /**
- * Field _nsPrefix.
- */
- private java.lang.String _nsPrefix;
-
- /**
- * Field _nsURI.
- */
- private java.lang.String _nsURI;
-
- /**
- * Field _xmlName.
- */
- private java.lang.String _xmlName;
-
- // ----------------/
- // - Constructors -/
- // ----------------/
-
- public AnnotationDescriptor()
- {
- super();
- _nsURI = "www.vamsas.ac.uk/jalview/version2";
- _xmlName = "Annotation";
- _elementDefinition = true;
-
- // -- set grouping compositor
- setCompositorAsSequence();
- org.exolab.castor.xml.util.XMLFieldDescriptorImpl desc = null;
- org.exolab.castor.mapping.FieldHandler handler = null;
- org.exolab.castor.xml.FieldValidator fieldValidator = null;
- // -- initialize attribute descriptors
-
- // -- _graph
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Boolean.TYPE, "_graph", "graph",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasGraph())
- {
- return null;
+public class AnnotationDescriptor extends org.exolab.castor.xml.util.XMLClassDescriptorImpl {
+
+
+ //--------------------------/
+ //- Class/Member Variables -/
+ //--------------------------/
+
+ /**
+ * Field _elementDefinition.
+ */
+ private boolean _elementDefinition;
+
+ /**
+ * Field _nsPrefix.
+ */
+ private java.lang.String _nsPrefix;
+
+ /**
+ * Field _nsURI.
+ */
+ private java.lang.String _nsURI;
+
+ /**
+ * Field _xmlName.
+ */
+ private java.lang.String _xmlName;
+
+
+ //----------------/
+ //- Constructors -/
+ //----------------/
+
+ public AnnotationDescriptor() {
+ super();
+ _nsURI = "www.vamsas.ac.uk/jalview/version2";
+ _xmlName = "Annotation";
+ _elementDefinition = true;
+
+ //-- set grouping compositor
+ setCompositorAsSequence();
+ org.exolab.castor.xml.util.XMLFieldDescriptorImpl desc = null;
+ org.exolab.castor.mapping.FieldHandler handler = null;
+ org.exolab.castor.xml.FieldValidator fieldValidator = null;
+ //-- initialize attribute descriptors
+
+ //-- _graph
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_graph", "graph", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasGraph()) { return null; }
+ return (target.getGraph() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // ignore null values for non optional primitives
+ if (value == null) { return; }
+
+ target.setGraph( ((java.lang.Boolean) value).booleanValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setRequired(true);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _graph
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ fieldValidator.setMinOccurs(1);
+ { //-- local scope
+ org.exolab.castor.xml.validators.BooleanValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
+ fieldValidator.setValidator(typeValidator);
}
- return (target.getGraph() ? java.lang.Boolean.TRUE
- : java.lang.Boolean.FALSE);
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // ignore null values for non optional primitives
- if (value == null)
- {
- return;
- }
-
- target.setGraph(((java.lang.Boolean) value).booleanValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
- }
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setRequired(true);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _graph
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- fieldValidator.setMinOccurs(1);
- { // -- local scope
- org.exolab.castor.xml.validators.BooleanValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
- fieldValidator.setValidator(typeValidator);
- }
- desc.setValidator(fieldValidator);
- // -- _graphType
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Integer.TYPE, "_graphType", "graphType",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasGraphType())
- {
- return null;
+ desc.setValidator(fieldValidator);
+ //-- _graphType
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_graphType", "graphType", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasGraphType()) { return null; }
+ return new java.lang.Integer(target.getGraphType());
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteGraphType();
+ return;
+ }
+ target.setGraphType( ((java.lang.Integer) value).intValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _graphType
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.IntValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.IntValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setMinInclusive(-2147483648);
+ typeValidator.setMaxInclusive(2147483647);
}
- return new java.lang.Integer(target.getGraphType());
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteGraphType();
- return;
- }
- target.setGraphType(((java.lang.Integer) value).intValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _sequenceRef
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_sequenceRef", "sequenceRef", org.exolab.castor.xml.NodeType.Attribute);
+ desc.setImmutable(true);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ return target.getSequenceRef();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ target.setSequenceRef( (java.lang.String) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _sequenceRef
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.StringValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.StringValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setWhiteSpace("preserve");
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _graphType
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.IntValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.IntValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setMinInclusive(-2147483648);
- typeValidator.setMaxInclusive(2147483647);
- }
- desc.setValidator(fieldValidator);
- // -- _sequenceRef
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.String.class, "_sequenceRef", "sequenceRef",
- org.exolab.castor.xml.NodeType.Attribute);
- desc.setImmutable(true);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- return target.getSequenceRef();
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- target.setSequenceRef((java.lang.String) value);
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _groupRef
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_groupRef", "groupRef", org.exolab.castor.xml.NodeType.Attribute);
+ desc.setImmutable(true);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ return target.getGroupRef();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ target.setGroupRef( (java.lang.String) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _groupRef
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.StringValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.StringValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setWhiteSpace("preserve");
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _sequenceRef
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.StringValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.StringValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setWhiteSpace("preserve");
- }
- desc.setValidator(fieldValidator);
- // -- _groupRef
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.String.class, "_groupRef", "groupRef",
- org.exolab.castor.xml.NodeType.Attribute);
- desc.setImmutable(true);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- return target.getGroupRef();
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- target.setGroupRef((java.lang.String) value);
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _graphColour
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_graphColour", "graphColour", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasGraphColour()) { return null; }
+ return new java.lang.Integer(target.getGraphColour());
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteGraphColour();
+ return;
+ }
+ target.setGraphColour( ((java.lang.Integer) value).intValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _graphColour
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.IntValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.IntValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setMinInclusive(-2147483648);
+ typeValidator.setMaxInclusive(2147483647);
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _groupRef
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.StringValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.StringValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setWhiteSpace("preserve");
- }
- desc.setValidator(fieldValidator);
- // -- _graphColour
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Integer.TYPE, "_graphColour", "graphColour",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasGraphColour())
- {
- return null;
+ desc.setValidator(fieldValidator);
+ //-- _graphGroup
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_graphGroup", "graphGroup", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasGraphGroup()) { return null; }
+ return new java.lang.Integer(target.getGraphGroup());
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteGraphGroup();
+ return;
+ }
+ target.setGraphGroup( ((java.lang.Integer) value).intValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _graphGroup
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.IntValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.IntValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setMinInclusive(-2147483648);
+ typeValidator.setMaxInclusive(2147483647);
}
- return new java.lang.Integer(target.getGraphColour());
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteGraphColour();
- return;
- }
- target.setGraphColour(((java.lang.Integer) value).intValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _graphHeight
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Integer.TYPE, "_graphHeight", "graphHeight", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasGraphHeight()) { return null; }
+ return new java.lang.Integer(target.getGraphHeight());
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteGraphHeight();
+ return;
+ }
+ target.setGraphHeight( ((java.lang.Integer) value).intValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _graphHeight
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.IntValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.IntValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setMinInclusive(-2147483648);
+ typeValidator.setMaxInclusive(2147483647);
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _graphColour
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.IntValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.IntValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setMinInclusive(-2147483648);
- typeValidator.setMaxInclusive(2147483647);
- }
- desc.setValidator(fieldValidator);
- // -- _graphGroup
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Integer.TYPE, "_graphGroup", "graphGroup",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasGraphGroup())
- {
- return null;
+ desc.setValidator(fieldValidator);
+ //-- _id
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_id", "id", org.exolab.castor.xml.NodeType.Attribute);
+ desc.setImmutable(true);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ return target.getId();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ target.setId( (java.lang.String) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _id
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.StringValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.StringValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setWhiteSpace("preserve");
}
- return new java.lang.Integer(target.getGraphGroup());
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteGraphGroup();
- return;
- }
- target.setGraphGroup(((java.lang.Integer) value).intValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _scoreOnly
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_scoreOnly", "scoreOnly", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasScoreOnly()) { return null; }
+ return (target.getScoreOnly() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteScoreOnly();
+ return;
+ }
+ target.setScoreOnly( ((java.lang.Boolean) value).booleanValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _scoreOnly
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.BooleanValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
+ fieldValidator.setValidator(typeValidator);
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _graphGroup
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.IntValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.IntValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setMinInclusive(-2147483648);
- typeValidator.setMaxInclusive(2147483647);
- }
- desc.setValidator(fieldValidator);
- // -- _graphHeight
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Integer.TYPE, "_graphHeight", "graphHeight",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasGraphHeight())
- {
- return null;
+ desc.setValidator(fieldValidator);
+ //-- _score
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Double.TYPE, "_score", "score", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasScore()) { return null; }
+ return new java.lang.Double(target.getScore());
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteScore();
+ return;
+ }
+ target.setScore( ((java.lang.Double) value).doubleValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _score
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.DoubleValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.DoubleValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setMinInclusive(-1.7976931348623157E308);
+ typeValidator.setMaxInclusive(1.7976931348623157E308);
}
- return new java.lang.Integer(target.getGraphHeight());
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteGraphHeight();
- return;
- }
- target.setGraphHeight(((java.lang.Integer) value).intValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _visible
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_visible", "visible", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasVisible()) { return null; }
+ return (target.getVisible() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteVisible();
+ return;
+ }
+ target.setVisible( ((java.lang.Boolean) value).booleanValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _visible
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.BooleanValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
+ fieldValidator.setValidator(typeValidator);
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _graphHeight
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.IntValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.IntValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setMinInclusive(-2147483648);
- typeValidator.setMaxInclusive(2147483647);
- }
- desc.setValidator(fieldValidator);
- // -- _id
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.String.class, "_id", "id",
- org.exolab.castor.xml.NodeType.Attribute);
- desc.setImmutable(true);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- return target.getId();
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- target.setId((java.lang.String) value);
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _centreColLabels
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_centreColLabels", "centreColLabels", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasCentreColLabels()) { return null; }
+ return (target.getCentreColLabels() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteCentreColLabels();
+ return;
+ }
+ target.setCentreColLabels( ((java.lang.Boolean) value).booleanValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _centreColLabels
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.BooleanValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
+ fieldValidator.setValidator(typeValidator);
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _id
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.StringValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.StringValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setWhiteSpace("preserve");
- }
- desc.setValidator(fieldValidator);
- // -- _scoreOnly
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Boolean.TYPE, "_scoreOnly", "scoreOnly",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasScoreOnly())
- {
- return null;
+ desc.setValidator(fieldValidator);
+ //-- _scaleColLabels
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_scaleColLabels", "scaleColLabels", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasScaleColLabels()) { return null; }
+ return (target.getScaleColLabels() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteScaleColLabels();
+ return;
+ }
+ target.setScaleColLabels( ((java.lang.Boolean) value).booleanValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _scaleColLabels
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.BooleanValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
+ fieldValidator.setValidator(typeValidator);
}
- return (target.getScoreOnly() ? java.lang.Boolean.TRUE
- : java.lang.Boolean.FALSE);
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteScoreOnly();
- return;
- }
- target.setScoreOnly(((java.lang.Boolean) value).booleanValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _showAllColLabels
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_showAllColLabels", "showAllColLabels", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasShowAllColLabels()) { return null; }
+ return (target.getShowAllColLabels() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteShowAllColLabels();
+ return;
+ }
+ target.setShowAllColLabels( ((java.lang.Boolean) value).booleanValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _showAllColLabels
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.BooleanValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
+ fieldValidator.setValidator(typeValidator);
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _scoreOnly
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.BooleanValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
- fieldValidator.setValidator(typeValidator);
- }
- desc.setValidator(fieldValidator);
- // -- _score
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Double.TYPE, "_score", "score",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasScore())
- {
- return null;
+ desc.setValidator(fieldValidator);
+ //-- _autoCalculated
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_autoCalculated", "autoCalculated", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasAutoCalculated()) { return null; }
+ return (target.getAutoCalculated() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteAutoCalculated();
+ return;
+ }
+ target.setAutoCalculated( ((java.lang.Boolean) value).booleanValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _autoCalculated
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.BooleanValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
+ fieldValidator.setValidator(typeValidator);
}
- return new java.lang.Double(target.getScore());
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteScore();
- return;
- }
- target.setScore(((java.lang.Double) value).doubleValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _belowAlignment
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.Boolean.TYPE, "_belowAlignment", "belowAlignment", org.exolab.castor.xml.NodeType.Attribute);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ if (!target.hasBelowAlignment()) { return null; }
+ return (target.getBelowAlignment() ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ // if null, use delete method for optional primitives
+ if (value == null) {
+ target.deleteBelowAlignment();
+ return;
+ }
+ target.setBelowAlignment( ((java.lang.Boolean) value).booleanValue());
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _belowAlignment
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.BooleanValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
+ fieldValidator.setValidator(typeValidator);
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _score
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.DoubleValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.DoubleValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setMinInclusive(-1.7976931348623157E308);
- typeValidator.setMaxInclusive(1.7976931348623157E308);
- }
- desc.setValidator(fieldValidator);
- // -- _visible
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Boolean.TYPE, "_visible", "visible",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasVisible())
- {
- return null;
+ desc.setValidator(fieldValidator);
+ //-- _calcId
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_calcId", "calcId", org.exolab.castor.xml.NodeType.Attribute);
+ desc.setImmutable(true);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ return target.getCalcId();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ target.setCalcId( (java.lang.String) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _calcId
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.StringValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.StringValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setWhiteSpace("preserve");
}
- return (target.getVisible() ? java.lang.Boolean.TRUE
- : java.lang.Boolean.FALSE);
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteVisible();
- return;
- }
- target.setVisible(((java.lang.Boolean) value).booleanValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- initialize element descriptors
+
+ //-- _annotationElementList
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(jalview.schemabinding.version2.AnnotationElement.class, "_annotationElementList", "annotationElement", org.exolab.castor.xml.NodeType.Element);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ return target.getAnnotationElement();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ target.addAnnotationElement( (jalview.schemabinding.version2.AnnotationElement) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public void resetValue(Object object) throws IllegalStateException, IllegalArgumentException {
+ try {
+ Annotation target = (Annotation) object;
+ target.removeAllAnnotationElement();
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return new jalview.schemabinding.version2.AnnotationElement();
+ }
+ };
+ desc.setHandler(handler);
+ desc.setNameSpaceURI("www.vamsas.ac.uk/jalview/version2");
+ desc.setMultivalued(true);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _annotationElementList
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ fieldValidator.setMinOccurs(0);
+ { //-- local scope
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _visible
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.BooleanValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
- fieldValidator.setValidator(typeValidator);
- }
- desc.setValidator(fieldValidator);
- // -- _centreColLabels
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Boolean.TYPE, "_centreColLabels", "centreColLabels",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasCentreColLabels())
- {
- return null;
+ desc.setValidator(fieldValidator);
+ //-- _label
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_label", "label", org.exolab.castor.xml.NodeType.Element);
+ desc.setImmutable(true);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ return target.getLabel();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ target.setLabel( (java.lang.String) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setNameSpaceURI("www.vamsas.ac.uk/jalview/version2");
+ desc.setRequired(true);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _label
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ fieldValidator.setMinOccurs(1);
+ { //-- local scope
+ org.exolab.castor.xml.validators.StringValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.StringValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setWhiteSpace("preserve");
}
- return (target.getCentreColLabels() ? java.lang.Boolean.TRUE
- : java.lang.Boolean.FALSE);
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteCentreColLabels();
- return;
- }
- target.setCentreColLabels(((java.lang.Boolean) value)
- .booleanValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _description
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_description", "description", org.exolab.castor.xml.NodeType.Element);
+ desc.setImmutable(true);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ return target.getDescription();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ target.setDescription( (java.lang.String) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setNameSpaceURI("www.vamsas.ac.uk/jalview/version2");
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _description
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
+ org.exolab.castor.xml.validators.StringValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.StringValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setWhiteSpace("preserve");
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _centreColLabels
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.BooleanValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
- fieldValidator.setValidator(typeValidator);
- }
- desc.setValidator(fieldValidator);
- // -- _scaleColLabels
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Boolean.TYPE, "_scaleColLabels", "scaleColLabels",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasScaleColLabels())
- {
- return null;
+ desc.setValidator(fieldValidator);
+ //-- _thresholdLine
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(jalview.schemabinding.version2.ThresholdLine.class, "_thresholdLine", "thresholdLine", org.exolab.castor.xml.NodeType.Element);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ return target.getThresholdLine();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ target.setThresholdLine( (jalview.schemabinding.version2.ThresholdLine) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return new jalview.schemabinding.version2.ThresholdLine();
+ }
+ };
+ desc.setHandler(handler);
+ desc.setNameSpaceURI("www.vamsas.ac.uk/jalview/version2");
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _thresholdLine
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ { //-- local scope
}
- return (target.getScaleColLabels() ? java.lang.Boolean.TRUE
- : java.lang.Boolean.FALSE);
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteScaleColLabels();
- return;
- }
- target.setScaleColLabels(((java.lang.Boolean) value)
- .booleanValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _propertyList
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(jalview.schemabinding.version2.Property.class, "_propertyList", "property", org.exolab.castor.xml.NodeType.Element);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Annotation target = (Annotation) object;
+ return target.getProperty();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Annotation target = (Annotation) object;
+ target.addProperty( (jalview.schemabinding.version2.Property) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public void resetValue(Object object) throws IllegalStateException, IllegalArgumentException {
+ try {
+ Annotation target = (Annotation) object;
+ target.removeAllProperty();
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return new jalview.schemabinding.version2.Property();
+ }
+ };
+ desc.setHandler(handler);
+ desc.setNameSpaceURI("www.vamsas.ac.uk/jalview/version2");
+ desc.setMultivalued(true);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _propertyList
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ fieldValidator.setMinOccurs(0);
+ { //-- local scope
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _scaleColLabels
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.BooleanValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
- fieldValidator.setValidator(typeValidator);
+ desc.setValidator(fieldValidator);
}
- desc.setValidator(fieldValidator);
- // -- _showAllColLabels
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Boolean.TYPE, "_showAllColLabels",
- "showAllColLabels", org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasShowAllColLabels())
- {
- return null;
- }
- return (target.getShowAllColLabels() ? java.lang.Boolean.TRUE
- : java.lang.Boolean.FALSE);
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteShowAllColLabels();
- return;
- }
- target.setShowAllColLabels(((java.lang.Boolean) value)
- .booleanValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
- }
- }
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
- // -- validation code for: _showAllColLabels
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.BooleanValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
- fieldValidator.setValidator(typeValidator);
- }
- desc.setValidator(fieldValidator);
- // -- _autoCalculated
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Boolean.TYPE, "_autoCalculated", "autoCalculated",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasAutoCalculated())
- {
- return null;
- }
- return (target.getAutoCalculated() ? java.lang.Boolean.TRUE
- : java.lang.Boolean.FALSE);
- }
+ //-----------/
+ //- Methods -/
+ //-----------/
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteAutoCalculated();
- return;
- }
- target.setAutoCalculated(((java.lang.Boolean) value)
- .booleanValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
- }
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
+ /**
+ * Method getAccessMode.
+ *
+ * @return the access mode specified for this class.
+ */
+ public org.exolab.castor.mapping.AccessMode getAccessMode(
+ ) {
return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _autoCalculated
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.BooleanValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
- fieldValidator.setValidator(typeValidator);
}
- desc.setValidator(fieldValidator);
- // -- _belowAlignment
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.Boolean.TYPE, "_belowAlignment", "belowAlignment",
- org.exolab.castor.xml.NodeType.Attribute);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- if (!target.hasBelowAlignment())
- {
- return null;
- }
- return (target.getBelowAlignment() ? java.lang.Boolean.TRUE
- : java.lang.Boolean.FALSE);
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- // if null, use delete method for optional primitives
- if (value == null)
- {
- target.deleteBelowAlignment();
- return;
- }
- target.setBelowAlignment(((java.lang.Boolean) value)
- .booleanValue());
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
- }
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
- // -- validation code for: _belowAlignment
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.BooleanValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
- fieldValidator.setValidator(typeValidator);
+ /**
+ * Method getIdentity.
+ *
+ * @return the identity field, null if this class has no
+ * identity.
+ */
+ public org.exolab.castor.mapping.FieldDescriptor getIdentity(
+ ) {
+ return super.getIdentity();
}
- desc.setValidator(fieldValidator);
- // -- _calcId
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.String.class, "_calcId", "calcId",
- org.exolab.castor.xml.NodeType.Attribute);
- desc.setImmutable(true);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- return target.getCalcId();
- }
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- target.setCalcId((java.lang.String) value);
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
- }
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _calcId
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.StringValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.StringValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setWhiteSpace("preserve");
+ /**
+ * Method getJavaClass.
+ *
+ * @return the Java class represented by this descriptor.
+ */
+ public java.lang.Class getJavaClass(
+ ) {
+ return jalview.schemabinding.version2.Annotation.class;
}
- desc.setValidator(fieldValidator);
- // -- initialize element descriptors
- // -- _annotationElementList
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- jalview.schemabinding.version2.AnnotationElement.class,
- "_annotationElementList", "annotationElement",
- org.exolab.castor.xml.NodeType.Element);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- return target.getAnnotationElement();
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- target.addAnnotationElement((jalview.schemabinding.version2.AnnotationElement) value);
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
- }
- }
-
- public void resetValue(Object object) throws IllegalStateException,
- IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- target.removeAllAnnotationElement();
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
- }
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return new jalview.schemabinding.version2.AnnotationElement();
- }
- };
- desc.setHandler(handler);
- desc.setNameSpaceURI("www.vamsas.ac.uk/jalview/version2");
- desc.setMultivalued(true);
- addFieldDescriptor(desc);
-
- // -- validation code for: _annotationElementList
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- fieldValidator.setMinOccurs(0);
- { // -- local scope
+ /**
+ * Method getNameSpacePrefix.
+ *
+ * @return the namespace prefix to use when marshaling as XML.
+ */
+ public java.lang.String getNameSpacePrefix(
+ ) {
+ return _nsPrefix;
}
- desc.setValidator(fieldValidator);
- // -- _label
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.String.class, "_label", "label",
- org.exolab.castor.xml.NodeType.Element);
- desc.setImmutable(true);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- return target.getLabel();
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- target.setLabel((java.lang.String) value);
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
- }
- }
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setNameSpaceURI("www.vamsas.ac.uk/jalview/version2");
- desc.setRequired(true);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _label
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- fieldValidator.setMinOccurs(1);
- { // -- local scope
- org.exolab.castor.xml.validators.StringValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.StringValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setWhiteSpace("preserve");
+ /**
+ * Method getNameSpaceURI.
+ *
+ * @return the namespace URI used when marshaling and
+ * unmarshaling as XML.
+ */
+ public java.lang.String getNameSpaceURI(
+ ) {
+ return _nsURI;
}
- desc.setValidator(fieldValidator);
- // -- _description
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.String.class, "_description", "description",
- org.exolab.castor.xml.NodeType.Element);
- desc.setImmutable(true);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- return target.getDescription();
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- target.setDescription((java.lang.String) value);
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
- }
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setNameSpaceURI("www.vamsas.ac.uk/jalview/version2");
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
- // -- validation code for: _description
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
- org.exolab.castor.xml.validators.StringValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.StringValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setWhiteSpace("preserve");
+ /**
+ * Method getValidator.
+ *
+ * @return a specific validator for the class described by this
+ * ClassDescriptor.
+ */
+ public org.exolab.castor.xml.TypeValidator getValidator(
+ ) {
+ return this;
}
- desc.setValidator(fieldValidator);
- // -- _thresholdLine
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- jalview.schemabinding.version2.ThresholdLine.class,
- "_thresholdLine", "thresholdLine",
- org.exolab.castor.xml.NodeType.Element);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Annotation target = (Annotation) object;
- return target.getThresholdLine();
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Annotation target = (Annotation) object;
- target.setThresholdLine((jalview.schemabinding.version2.ThresholdLine) value);
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
- }
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return new jalview.schemabinding.version2.ThresholdLine();
- }
- };
- desc.setHandler(handler);
- desc.setNameSpaceURI("www.vamsas.ac.uk/jalview/version2");
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
- // -- validation code for: _thresholdLine
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- { // -- local scope
+ /**
+ * Method getXMLName.
+ *
+ * @return the XML Name for the Class being described.
+ */
+ public java.lang.String getXMLName(
+ ) {
+ return _xmlName;
}
- desc.setValidator(fieldValidator);
- }
-
- // -----------/
- // - Methods -/
- // -----------/
-
- /**
- * Method getAccessMode.
- *
- * @return the access mode specified for this class.
- */
- public org.exolab.castor.mapping.AccessMode getAccessMode()
- {
- return null;
- }
- /**
- * Method getIdentity.
- *
- * @return the identity field, null if this class has no identity.
- */
- public org.exolab.castor.mapping.FieldDescriptor getIdentity()
- {
- return super.getIdentity();
- }
-
- /**
- * Method getJavaClass.
- *
- * @return the Java class represented by this descriptor.
- */
- public java.lang.Class getJavaClass()
- {
- return jalview.schemabinding.version2.Annotation.class;
- }
-
- /**
- * Method getNameSpacePrefix.
- *
- * @return the namespace prefix to use when marshaling as XML.
- */
- public java.lang.String getNameSpacePrefix()
- {
- return _nsPrefix;
- }
-
- /**
- * Method getNameSpaceURI.
- *
- * @return the namespace URI used when marshaling and unmarshaling as XML.
- */
- public java.lang.String getNameSpaceURI()
- {
- return _nsURI;
- }
-
- /**
- * Method getValidator.
- *
- * @return a specific validator for the class described by this
- * ClassDescriptor.
- */
- public org.exolab.castor.xml.TypeValidator getValidator()
- {
- return this;
- }
-
- /**
- * Method getXMLName.
- *
- * @return the XML Name for the Class being described.
- */
- public java.lang.String getXMLName()
- {
- return _xmlName;
- }
-
- /**
- * Method isElementDefinition.
- *
- * @return true if XML schema definition of this Class is that of a global
- * element or element with anonymous type definition.
- */
- public boolean isElementDefinition()
- {
- return _elementDefinition;
- }
+ /**
+ * Method isElementDefinition.
+ *
+ * @return true if XML schema definition of this Class is that
+ * of a global
+ * element or element with anonymous type definition.
+ */
+ public boolean isElementDefinition(
+ ) {
+ return _elementDefinition;
+ }
}
*/
package jalview.schemabinding.version2.descriptors;
-//---------------------------------/
-//- Imported classes and packages -/
+ //---------------------------------/
+ //- Imported classes and packages -/
//---------------------------------/
import jalview.schemabinding.version2.Property;
*
* @version $Revision$ $Date$
*/
-public class PropertyDescriptor extends
- org.exolab.castor.xml.util.XMLClassDescriptorImpl
-{
-
- // --------------------------/
- // - Class/Member Variables -/
- // --------------------------/
-
- /**
- * Field _elementDefinition.
- */
- private boolean _elementDefinition;
-
- /**
- * Field _nsPrefix.
- */
- private java.lang.String _nsPrefix;
-
- /**
- * Field _nsURI.
- */
- private java.lang.String _nsURI;
-
- /**
- * Field _xmlName.
- */
- private java.lang.String _xmlName;
-
- // ----------------/
- // - Constructors -/
- // ----------------/
-
- public PropertyDescriptor()
- {
- super();
- _nsURI = "www.jalview.org";
- _xmlName = "property";
- _elementDefinition = true;
- org.exolab.castor.xml.util.XMLFieldDescriptorImpl desc = null;
- org.exolab.castor.mapping.FieldHandler handler = null;
- org.exolab.castor.xml.FieldValidator fieldValidator = null;
- // -- initialize attribute descriptors
-
- // -- _name
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.String.class, "_name", "name",
- org.exolab.castor.xml.NodeType.Attribute);
- desc.setImmutable(true);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Property target = (Property) object;
- return target.getName();
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Property target = (Property) object;
- target.setName((java.lang.String) value);
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+public class PropertyDescriptor extends org.exolab.castor.xml.util.XMLClassDescriptorImpl {
+
+
+ //--------------------------/
+ //- Class/Member Variables -/
+ //--------------------------/
+
+ /**
+ * Field _elementDefinition.
+ */
+ private boolean _elementDefinition;
+
+ /**
+ * Field _nsPrefix.
+ */
+ private java.lang.String _nsPrefix;
+
+ /**
+ * Field _nsURI.
+ */
+ private java.lang.String _nsURI;
+
+ /**
+ * Field _xmlName.
+ */
+ private java.lang.String _xmlName;
+
+
+ //----------------/
+ //- Constructors -/
+ //----------------/
+
+ public PropertyDescriptor() {
+ super();
+ _nsURI = "www.jalview.org";
+ _xmlName = "property";
+ _elementDefinition = true;
+ org.exolab.castor.xml.util.XMLFieldDescriptorImpl desc = null;
+ org.exolab.castor.mapping.FieldHandler handler = null;
+ org.exolab.castor.xml.FieldValidator fieldValidator = null;
+ //-- initialize attribute descriptors
+
+ //-- _name
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_name", "name", org.exolab.castor.xml.NodeType.Attribute);
+ desc.setImmutable(true);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Property target = (Property) object;
+ return target.getName();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Property target = (Property) object;
+ target.setName( (java.lang.String) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setRequired(true);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _name
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ fieldValidator.setMinOccurs(1);
+ { //-- local scope
+ org.exolab.castor.xml.validators.StringValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.StringValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setWhiteSpace("preserve");
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setRequired(true);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _name
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- fieldValidator.setMinOccurs(1);
- { // -- local scope
- org.exolab.castor.xml.validators.StringValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.StringValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setWhiteSpace("preserve");
- }
- desc.setValidator(fieldValidator);
- // -- _value
- desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
- java.lang.String.class, "_value", "value",
- org.exolab.castor.xml.NodeType.Attribute);
- desc.setImmutable(true);
- handler = new org.exolab.castor.xml.XMLFieldHandler()
- {
- public java.lang.Object getValue(java.lang.Object object)
- throws IllegalStateException
- {
- Property target = (Property) object;
- return target.getValue();
- }
-
- public void setValue(java.lang.Object object, java.lang.Object value)
- throws IllegalStateException, IllegalArgumentException
- {
- try
- {
- Property target = (Property) object;
- target.setValue((java.lang.String) value);
- } catch (java.lang.Exception ex)
- {
- throw new IllegalStateException(ex.toString());
+ desc.setValidator(fieldValidator);
+ //-- _value
+ desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(java.lang.String.class, "_value", "value", org.exolab.castor.xml.NodeType.Attribute);
+ desc.setImmutable(true);
+ handler = new org.exolab.castor.xml.XMLFieldHandler() {
+ public java.lang.Object getValue( java.lang.Object object )
+ throws IllegalStateException
+ {
+ Property target = (Property) object;
+ return target.getValue();
+ }
+ public void setValue( java.lang.Object object, java.lang.Object value)
+ throws IllegalStateException, IllegalArgumentException
+ {
+ try {
+ Property target = (Property) object;
+ target.setValue( (java.lang.String) value);
+ } catch (java.lang.Exception ex) {
+ throw new IllegalStateException(ex.toString());
+ }
+ }
+ public java.lang.Object newInstance(java.lang.Object parent) {
+ return null;
+ }
+ };
+ desc.setHandler(handler);
+ desc.setRequired(true);
+ desc.setMultivalued(false);
+ addFieldDescriptor(desc);
+
+ //-- validation code for: _value
+ fieldValidator = new org.exolab.castor.xml.FieldValidator();
+ fieldValidator.setMinOccurs(1);
+ { //-- local scope
+ org.exolab.castor.xml.validators.StringValidator typeValidator;
+ typeValidator = new org.exolab.castor.xml.validators.StringValidator();
+ fieldValidator.setValidator(typeValidator);
+ typeValidator.setWhiteSpace("preserve");
}
- }
-
- public java.lang.Object newInstance(java.lang.Object parent)
- {
- return null;
- }
- };
- desc.setHandler(handler);
- desc.setRequired(true);
- desc.setMultivalued(false);
- addFieldDescriptor(desc);
-
- // -- validation code for: _value
- fieldValidator = new org.exolab.castor.xml.FieldValidator();
- fieldValidator.setMinOccurs(1);
- { // -- local scope
- org.exolab.castor.xml.validators.StringValidator typeValidator;
- typeValidator = new org.exolab.castor.xml.validators.StringValidator();
- fieldValidator.setValidator(typeValidator);
- typeValidator.setWhiteSpace("preserve");
+ desc.setValidator(fieldValidator);
+ //-- initialize element descriptors
+
}
- desc.setValidator(fieldValidator);
- // -- initialize element descriptors
- }
- // -----------/
- // - Methods -/
- // -----------/
+ //-----------/
+ //- Methods -/
+ //-----------/
- /**
- * Method getAccessMode.
- *
- * @return the access mode specified for this class.
- */
- public org.exolab.castor.mapping.AccessMode getAccessMode()
- {
- return null;
- }
+ /**
+ * Method getAccessMode.
+ *
+ * @return the access mode specified for this class.
+ */
+ public org.exolab.castor.mapping.AccessMode getAccessMode(
+ ) {
+ return null;
+ }
- /**
- * Method getIdentity.
- *
- * @return the identity field, null if this class has no identity.
- */
- public org.exolab.castor.mapping.FieldDescriptor getIdentity()
- {
- return super.getIdentity();
- }
+ /**
+ * Method getIdentity.
+ *
+ * @return the identity field, null if this class has no
+ * identity.
+ */
+ public org.exolab.castor.mapping.FieldDescriptor getIdentity(
+ ) {
+ return super.getIdentity();
+ }
- /**
- * Method getJavaClass.
- *
- * @return the Java class represented by this descriptor.
- */
- public java.lang.Class getJavaClass()
- {
- return jalview.schemabinding.version2.Property.class;
- }
+ /**
+ * Method getJavaClass.
+ *
+ * @return the Java class represented by this descriptor.
+ */
+ public java.lang.Class getJavaClass(
+ ) {
+ return jalview.schemabinding.version2.Property.class;
+ }
- /**
- * Method getNameSpacePrefix.
- *
- * @return the namespace prefix to use when marshaling as XML.
- */
- public java.lang.String getNameSpacePrefix()
- {
- return _nsPrefix;
- }
+ /**
+ * Method getNameSpacePrefix.
+ *
+ * @return the namespace prefix to use when marshaling as XML.
+ */
+ public java.lang.String getNameSpacePrefix(
+ ) {
+ return _nsPrefix;
+ }
- /**
- * Method getNameSpaceURI.
- *
- * @return the namespace URI used when marshaling and unmarshaling as XML.
- */
- public java.lang.String getNameSpaceURI()
- {
- return _nsURI;
- }
+ /**
+ * Method getNameSpaceURI.
+ *
+ * @return the namespace URI used when marshaling and
+ * unmarshaling as XML.
+ */
+ public java.lang.String getNameSpaceURI(
+ ) {
+ return _nsURI;
+ }
- /**
- * Method getValidator.
- *
- * @return a specific validator for the class described by this
- * ClassDescriptor.
- */
- public org.exolab.castor.xml.TypeValidator getValidator()
- {
- return this;
- }
+ /**
+ * Method getValidator.
+ *
+ * @return a specific validator for the class described by this
+ * ClassDescriptor.
+ */
+ public org.exolab.castor.xml.TypeValidator getValidator(
+ ) {
+ return this;
+ }
- /**
- * Method getXMLName.
- *
- * @return the XML Name for the Class being described.
- */
- public java.lang.String getXMLName()
- {
- return _xmlName;
- }
+ /**
+ * Method getXMLName.
+ *
+ * @return the XML Name for the Class being described.
+ */
+ public java.lang.String getXMLName(
+ ) {
+ return _xmlName;
+ }
- /**
- * Method isElementDefinition.
- *
- * @return true if XML schema definition of this Class is that of a global
- * element or element with anonymous type definition.
- */
- public boolean isElementDefinition()
- {
- return _elementDefinition;
- }
+ /**
+ * Method isElementDefinition.
+ *
+ * @return true if XML schema definition of this Class is that
+ * of a global
+ * element or element with anonymous type definition.
+ */
+ public boolean isElementDefinition(
+ ) {
+ return _elementDefinition;
+ }
}
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.Annotation;
import jalview.datamodel.GraphLine;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
GraphLine annotationThreshold;
- float r1, g1, b1, rr, gg, bb, dr, dg, db;
+ float r1, g1, b1, rr, gg, bb;
private boolean predefinedColours = false;
private boolean seqAssociated = false;
+ /**
+ * false if the scheme was constructed without a minColour and maxColour used
+ * to decide if existing colours should be taken from annotation elements when
+ * they exist
+ */
+ private boolean noGradient = false;
IdentityHashMap<SequenceI, AlignmentAnnotation> seqannot = null;
@Override
acg.rr = rr;
acg.gg = gg;
acg.bb = bb;
- acg.dr = dr;
- acg.dg = dg;
- acg.db = db;
acg.predefinedColours = predefinedColours;
acg.seqAssociated = seqAssociated;
-
+ acg.noGradient = noGradient;
return acg;
}
{
annotationThreshold = annotation.threshold;
}
+ // clear values so we don't get weird black bands...
+ r1 = 254;
+ g1 = 254;
+ b1 = 254;
+ rr = 0;
+ gg = 0;
+ bb = 0;
+
+ noGradient = true;
}
/**
rr = maxColour.getRed() - r1;
gg = maxColour.getGreen() - g1;
bb = maxColour.getBlue() - b1;
+
+ noGradient = false;
}
@Override
&& annotation.annotations[j] != null
&& !jalview.util.Comparison.isGap(c))
{
-
- if (predefinedColours)
- {
- if (annotation.annotations[j].colour != null)
- return annotation.annotations[j].colour;
- else
- return currentColour;
- }
+ Annotation aj = annotation.annotations[j];
+ // 'use original colours' => colourScheme != null
+ // -> look up colour to be used
+ // predefined colours => preconfigured shading
+ // -> only use original colours reference if thresholding enabled &
+ // minmax exists
+ // annotation.hasIcons => null or black colours replaced with glyph
+ // colours
+ // -> reuse original colours if present
+ // -> if thresholding enabled then return colour on non-whitespace glyph
if (aboveAnnotationThreshold == NO_THRESHOLD
- || (annotationThreshold != null
- && aboveAnnotationThreshold == ABOVE_THRESHOLD && annotation.annotations[j].value >= annotationThreshold.value)
- || (annotationThreshold != null
- && aboveAnnotationThreshold == BELOW_THRESHOLD && annotation.annotations[j].value <= annotationThreshold.value))
+ || (annotationThreshold != null && (aboveAnnotationThreshold == ABOVE_THRESHOLD ? aj.value >= annotationThreshold.value
+ : aj.value <= annotationThreshold.value)))
{
-
- float range = 1f;
- if (thresholdIsMinMax
- && annotation.threshold != null
- && aboveAnnotationThreshold == ABOVE_THRESHOLD
- && annotation.annotations[j].value >= annotation.threshold.value)
+ if (predefinedColours && aj.colour != null)
{
- range = (annotation.annotations[j].value - annotation.threshold.value)
- / (annotation.graphMax - annotation.threshold.value);
+ currentColour = aj.colour;
}
- else if (thresholdIsMinMax && annotation.threshold != null
- && aboveAnnotationThreshold == BELOW_THRESHOLD
- && annotation.annotations[j].value >= annotation.graphMin)
+ else if (annotation.hasIcons
+ && annotation.graph == AlignmentAnnotation.NO_GRAPH)
{
- range = (annotation.annotations[j].value - annotation.graphMin)
- / (annotation.threshold.value - annotation.graphMin);
+ if (aj.secondaryStructure > ' ' && aj.secondaryStructure != '.'
+ && aj.secondaryStructure != '-')
+ {
+ if (colourScheme != null)
+ {
+ currentColour = colourScheme.findColour(c, j, seq);
+ }
+ else
+ {
+ currentColour = annotation.annotations[j].secondaryStructure == 'H' ? jalview.renderer.AnnotationRenderer.HELIX_COLOUR
+ : annotation.annotations[j].secondaryStructure == 'E' ? jalview.renderer.AnnotationRenderer.SHEET_COLOUR
+ : jalview.renderer.AnnotationRenderer.STEM_COLOUR;
+ }
+ }
+ else
+ {
+ //
+ return Color.white;
+ }
}
- else
+ else if (noGradient)
{
- range = (annotation.annotations[j].value - annotation.graphMin)
- / (annotation.graphMax - annotation.graphMin);
- }
-
- if (colourScheme != null)
- {
- currentColour = colourScheme.findColour(c, j, seq);
+ if (colourScheme != null)
+ {
+ currentColour = colourScheme.findColour(c, j, seq);
+ }
+ else
+ {
+ if (aj.colour != null)
+ {
+ currentColour = aj.colour;
+ }
+ }
}
else
{
- dr = rr * range + r1;
- dg = gg * range + g1;
- db = bb * range + b1;
+ // calculate a shade
+ float range = 1f;
+ if (thresholdIsMinMax
+ && annotation.threshold != null
+ && aboveAnnotationThreshold == ABOVE_THRESHOLD
+ && annotation.annotations[j].value >= annotation.threshold.value)
+ {
+ range = (annotation.annotations[j].value - annotation.threshold.value)
+ / (annotation.graphMax - annotation.threshold.value);
+ }
+ else if (thresholdIsMinMax
+ && annotation.threshold != null
+ && aboveAnnotationThreshold == BELOW_THRESHOLD
+ && annotation.annotations[j].value >= annotation.graphMin)
+ {
+ range = (annotation.annotations[j].value - annotation.graphMin)
+ / (annotation.threshold.value - annotation.graphMin);
+ }
+ else
+ {
+ range = (annotation.annotations[j].value - annotation.graphMin)
+ / (annotation.graphMax - annotation.graphMin);
+ }
+
+ int dr = (int) (rr * range + r1), dg = (int) (gg * range + g1), db = (int) (bb
+ * range + b1);
+
+ currentColour = new Color(dr, dg, db);
- currentColour = new Color((int) dr, (int) dg, (int) db);
}
}
+ if (conservationColouring)
+ {
+ currentColour = applyConservation(currentColour, j);
+ }
}
}
-
- if (conservationColouring)
- {
- currentColour = applyConservation(currentColour, j);
- }
-
return currentColour;
}
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
import java.awt.Color;
import java.util.Hashtable;
return getClass().newInstance();
} catch (Exception q)
{
- throw new Error(
- "Serious implementation error: cannot duplicate colourscheme "
- + getClass().getName(), q);
+ throw new Error(MessageManager.formatMessage("error.implementation_error_cannot_duplicate_colour_scheme", new String[]{getClass().getName()}), q);
}
}
}
*/
package jalview.structure;
-import jalview.datamodel.*;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.SequenceI;
public class StructureMapping
{
return pdbid;
}
+ /**
+ *
+ * @param seqpos
+ * @return 0 or corresponding atom number for the sequence position
+ */
public int getAtomNum(int seqpos)
{
if (mapping.length > seqpos)
}
}
+ /**
+ *
+ * @param seqpos
+ * @return 0 or the corresponding residue number for the sequence position
+ */
public int getPDBResNum(int seqpos)
{
if (mapping.length > seqpos)
}
}
+ /**
+ *
+ * @param pdbResNum
+ * @return -1 or the corresponding sequence position for a pdb residue number
+ */
public int getSeqPos(int pdbResNum)
{
for (int i = 0; i < mapping.length; i++)
}
return -1;
}
+
+ /**
+ * transfer a copy of an alignment annotation row in the PDB chain coordinate
+ * system onto the mapped sequence
+ *
+ * @param ana
+ * @return the copy that was remapped to the mapped sequence
+ * @note this method will create a copy and add it to the dataset sequence for
+ * the mapped sequence as well as the mapped sequence (if it is not a
+ * dataset sequence).
+ */
+ public AlignmentAnnotation transfer(AlignmentAnnotation ana)
+ {
+ AlignmentAnnotation ala_copy = new AlignmentAnnotation(ana);
+ SequenceI ds = sequence;
+ while (ds.getDatasetSequence() != null)
+ {
+ ds = ds.getDatasetSequence();
+ }
+ // need to relocate annotation from pdb coordinates to local sequence
+ // -1,-1 doesn't look at pdbresnum but fails to remap sequence positions...
+
+ ala_copy.remap(ds, mapping, -1, -1, 0);
+ ds.addAlignmentAnnotation(ala_copy);
+ if (ds != sequence)
+ {
+ // mapping wasn't to an original dataset sequence, so we make a copy on
+ // the mapped sequence too
+ ala_copy = new AlignmentAnnotation(ala_copy);
+ sequence.addAlignmentAnnotation(ala_copy);
+ }
+ return ala_copy;
+ }
}
*/
package jalview.structure;
-import java.io.*;
-import java.util.*;
-
-import MCview.*;
-import jalview.analysis.*;
-import jalview.api.AlignmentViewPanel;
+import jalview.analysis.AlignSeq;
import jalview.api.StructureSelectionManagerProvider;
-import jalview.datamodel.*;
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SequenceI;
+import jalview.io.AppletFormatAdapter;
+import jalview.util.MessageManager;
+
+import java.io.PrintStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Vector;
+
+import MCview.Atom;
+import MCview.PDBChain;
public class StructureSelectionManager
{
}
}
- Hashtable mappingData = new Hashtable();
+ /**
+ * map between the PDB IDs (or structure identifiers) used by Jalview and the
+ * absolute filenames for PDB data that corresponds to it
+ */
+ HashMap<String, String> pdbIdFileName = new HashMap<String, String>(),
+ pdbFileNameId = new HashMap<String, String>();
+
+ public void registerPDBFile(String idForFile, String absoluteFile)
+ {
+ pdbIdFileName.put(idForFile, absoluteFile);
+ pdbFileNameId.put(absoluteFile, idForFile);
+ }
+
+ public String findIdForPDBFile(String idOrFile)
+ {
+ String id = pdbFileNameId.get(idOrFile);
+ return id;
+ }
+
+ public String findFileForPDBId(String idOrFile)
+ {
+ String id = pdbIdFileName.get(idOrFile);
+ return id;
+ }
+
+ public boolean isPDBFileRegistered(String idOrFile)
+ {
+ return pdbFileNameId.containsKey(idOrFile)
+ || pdbIdFileName.containsKey(idOrFile);
+ }
private static StructureSelectionManager nullProvider = null;
{
if (instances != null)
{
- throw new Error(
- "Implementation error. Structure selection manager's context is 'null'",
- new NullPointerException("SSM context is null"));
+ throw new Error(MessageManager.getString("error.implementation_error_structure_selection_manager_null"),
+ new NullPointerException(MessageManager.getString("exception.ssm_context_is_null")));
}
else
{
}
/**
+ * Import structure data and register a structure mapping for broadcasting
+ * colouring, mouseovers and selection events (convenience wrapper).
+ *
+ * @param sequence
+ * - one or more sequences to be mapped to pdbFile
+ * @param targetChains
+ * - optional chain specification for mapping each sequence to pdb
+ * (may be nill, individual elements may be nill)
+ * @param pdbFile
+ * - structure data resource
+ * @param protocol
+ * - how to resolve data from resource
+ * @return null or the structure data parsed as a pdb file
+ */
+ synchronized public MCview.PDBfile setMapping(SequenceI[] sequence,
+ String[] targetChains, String pdbFile, String protocol)
+ {
+ return setMapping(true, sequence, targetChains, pdbFile, protocol);
+ }
+
+ /**
* create sequence structure mappings between each sequence and the given
* pdbFile (retrieved via the given protocol).
*
+ * @param forStructureView
+ * when true, record the mapping for use in mouseOvers
+ *
* @param sequence
* - one or more sequences to be mapped to pdbFile
* @param targetChains
* - how to resolve data from resource
* @return null or the structure data parsed as a pdb file
*/
- synchronized public MCview.PDBfile setMapping(SequenceI[] sequence,
+ synchronized public MCview.PDBfile setMapping(boolean forStructureView,
+ SequenceI[] sequence,
String[] targetChains, String pdbFile, String protocol)
{
/*
* the tried and tested MCview pdb mapping
*/
MCview.PDBfile pdb = null;
+ boolean parseSecStr=true;
+ if (isPDBFileRegistered(pdbFile))
+ {
+ for (SequenceI sq : sequence)
+ {
+ SequenceI ds = sq;
+ while (ds.getDatasetSequence() != null)
+ {
+ ds = ds.getDatasetSequence();
+ }
+ ;
+ if (ds.getAnnotation() != null)
+ {
+ for (AlignmentAnnotation ala : ds.getAnnotation())
+ {
+ // false if any annotation present from this structure
+ // JBPNote this fails for jmol/chimera view because the *file* is
+ // passed, not the structure data ID -
+ if (MCview.PDBfile.isCalcIdForFile(ala,
+ findIdForPDBFile(pdbFile)))
+ {
+ parseSecStr = false;
+ }
+ }
+ }
+ }
+ }
try
{
- pdb = new MCview.PDBfile(pdbFile, protocol);
+ pdb = new MCview.PDBfile(true, parseSecStr, pdbFile, protocol);
+ if (pdb.id != null && pdb.id.trim().length() > 0
+ && AppletFormatAdapter.FILE.equals(protocol))
+ {
+ registerPDBFile(pdb.id.trim(), pdbFile);
+ }
} catch (Exception ex)
{
ex.printStackTrace();
}
}
else
+ {
targetChain = "";
+ }
int max = -10;
AlignSeq maxAlignseq = null;
boolean first = true;
for (int i = 0; i < pdb.chains.size(); i++)
{
- PDBChain chain = ((PDBChain) pdb.chains.elementAt(i));
+ PDBChain chain = (pdb.chains.elementAt(i));
if (targetChain.length() > 0 && !targetChain.equals(chain.id)
&& !infChain)
{
// TODO: correctly determine sequence type for mixed na/peptide
// structures
AlignSeq as = new AlignSeq(sequence[s],
- ((PDBChain) pdb.chains.elementAt(i)).sequence,
- ((PDBChain) pdb.chains.elementAt(i)).isNa ? AlignSeq.DNA
+ pdb.chains.elementAt(i).sequence,
+ pdb.chains.elementAt(i).isNa ? AlignSeq.DNA
: AlignSeq.PEP);
as.calcScoreMatrix();
as.traceAlignment();
+ (maxAlignseq.seq1end + sequence[s].getEnd() - 1));
maxChain.makeExactMapping(maxAlignseq, sequence[s]);
-
+ jalview.datamodel.Mapping sqmpping = maxAlignseq
+ .getMappingFromS1(false);
+ jalview.datamodel.Mapping omap = new jalview.datamodel.Mapping(
+ sqmpping.getMap().getInverse());
maxChain.transferRESNUMFeatures(sequence[s], null);
// allocate enough slots to store the mapping from positions in
index++;
} while (index < maxChain.atoms.size());
- if (mappings == null)
+ if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
{
- mappings = new StructureMapping[1];
+ pdbFile = "INLINE" + pdb.id;
}
- else
+ StructureMapping newMapping = new StructureMapping(sequence[s],
+ pdbFile, pdb.id, maxChainId, mapping,
+ mappingDetails.toString());
+ if (forStructureView)
{
- StructureMapping[] tmp = new StructureMapping[mappings.length + 1];
- System.arraycopy(mappings, 0, tmp, 0, mappings.length);
- mappings = tmp;
- }
- if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
- pdbFile = "INLINE" + pdb.id;
+ if (mappings == null)
+ {
+ mappings = new StructureMapping[1];
+ }
+ else
+ {
+ StructureMapping[] tmp = new StructureMapping[mappings.length + 1];
+ System.arraycopy(mappings, 0, tmp, 0, mappings.length);
+ mappings = tmp;
+ }
- mappings[mappings.length - 1] = new StructureMapping(sequence[s],
- pdbFile, pdb.id, maxChainId, mapping,
- mappingDetails.toString());
- maxChain.transferResidueAnnotation(mappings[mappings.length - 1]);
+ mappings[mappings.length - 1] = newMapping;
+ }
+ maxChain.transferResidueAnnotation(newMapping, sqmpping);
}
// ///////
String[] handlepdbs;
Vector pdbs = new Vector();
for (int i = 0; i < pdbfiles.length; pdbs.addElement(pdbfiles[i++]))
+ {
;
+ }
StructureListener sl;
for (int i = 0; i < listeners.size(); i++)
{
{
Object li = listeners.elementAt(i);
if (li instanceof SequenceListener)
+ {
((SequenceListener) li).highlightSequence(results);
+ }
}
}
}
boolean hasSequenceListeners = handlingVamsasMo || seqmappings != null;
SearchResults results = null;
if (index == -1)
+ {
index = seq.findPosition(indexpos);
+ }
StructureListener sl;
int atomNo = 0;
for (int i = 0; i < listeners.size(); i++)
AlignedCodonFrame[] codonFrames)
{
if (!add && (seqmappings == null || seqmappings.size() == 0))
+ {
return;
+ }
if (seqmappings == null)
+ {
seqmappings = new Vector();
+ }
if (codonFrames != null && codonFrames.length > 0)
{
for (int cf = 0; cf < codonFrames.length; cf++)
int[] nsr = new int[(seqmappingrefs == null) ? 1
: seqmappingrefs.length + 1];
if (seqmappingrefs != null && seqmappingrefs.length > 0)
+ {
System.arraycopy(seqmappingrefs, 0, nsr, 0,
seqmappingrefs.length);
+ }
nsr[(seqmappingrefs == null) ? 0 : seqmappingrefs.length] = 1;
seqmappingrefs = nsr;
}
listeners.clear();
listeners = null;
}
- if (mappingData != null)
+ if (pdbIdFileName != null)
{
- mappingData.clear();
- mappingData = null;
+ pdbIdFileName.clear();
+ pdbIdFileName = null;
}
if (sel_listeners != null)
{
}
}
+ public void registerPDBEntry(PDBEntry pdbentry)
+ {
+ if (pdbentry.getFile() != null
+ && pdbentry.getFile().trim().length() > 0)
+ {
+ registerPDBFile(pdbentry.getId(), pdbentry.getFile());
+ }
+ }
+
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview 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.
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.structures.models;
+
+import jalview.api.SequenceStructureBinding;
+
+public class SequenceStructureBindingModel implements
+ SequenceStructureBinding
+{
+
+ /**
+ * set if Structure Viewer state is being restored from some source -
+ * instructs binding not to apply default display style when structure set is
+ * updated for first time.
+ */
+ private boolean loadingFromArchive = false;
+
+ /**
+ * second flag to indicate if the Structure viewer should ignore sequence
+ * colouring events from the structure manager because the GUI is still
+ * setting up
+ */
+ private boolean loadingFinished = true;
+
+ @Override
+ public void setLoadingFromArchive(boolean loadingFromArchive)
+ {
+ this.loadingFromArchive = loadingFromArchive;
+ }
+
+ /**
+ *
+ * @return true if Jmol is still restoring state or loading is still going on
+ * (see setFinsihedLoadingFromArchive)
+ */
+ @Override
+ public boolean isLoadingFromArchive()
+ {
+ return loadingFromArchive && !loadingFinished;
+ }
+
+ @Override
+ public boolean isLoadingFinished()
+ {
+ return loadingFinished;
+ }
+
+ @Override
+ public void setFinishedLoadingFromArchive(boolean finishedLoading)
+ {
+ loadingFinished = finishedLoading;
+ }
+
+}
} catch (InterruptedException ie)
{
}
- throw new NullPointerException(
- "Application test: throwing an NullPointerException It should arrive at the console");
+ throw new NullPointerException(MessageManager.getString("exception.application_test_npe"));
}
}
{
if (!loadedWithoutErrors)
{
- throw new IOException("Exception in finding browser: " + errorMessage);
+ throw new IOException(MessageManager.formatMessage("exception.browser_not_found", new String[]{errorMessage}));
}
Object browser = locateBrowser();
if (browser == null)
{
- throw new IOException("Unable to locate browser: " + errorMessage);
+ throw new IOException(MessageManager.formatMessage("exception.browser_unable_to_locate", new String[]{errorMessage}));
}
switch (jvm)
{});
} catch (InvocationTargetException ite)
{
- throw new IOException(
- "InvocationTargetException while creating AEDesc: "
- + ite.getMessage());
+ throw new IOException(MessageManager.formatMessage("exception.invocation_target_exception_creating_aedesc", new String[]{ite.getMessage()}));
} catch (IllegalAccessException iae)
{
- throw new IOException(
- "IllegalAccessException while building AppleEvent: "
- + iae.getMessage());
+ throw new IOException(MessageManager.formatMessage("exception.illegal_access_building_apple_evt", new String[]{iae.getMessage()}));
} catch (InstantiationException ie)
{
- throw new IOException(
- "InstantiationException while creating AEDesc: "
- + ie.getMessage());
+ throw new IOException(MessageManager.formatMessage("exception.illegal_access_building_apple_evt", new String[]{ie.getMessage()}));
} finally
{
aeDesc = null; // Encourage it to get disposed if it was created
}
else
{
- throw new IOException("Unable to launch URL: " + result);
+ throw new IOException(MessageManager.formatMessage("exception.unable_to_launch_url", new String[]{Integer.valueOf(result).toString()}));
}
}
else
{
- throw new IOException(
- "Unable to create an Internet Config instance: " + result);
+ throw new IOException(MessageManager.formatMessage("exception.unable_to_create_internet_config", new String[]{Integer.valueOf(result).toString()}));
}
break;
{ url });
} catch (InvocationTargetException ite)
{
- throw new IOException(
- "InvocationTargetException while calling openURL: "
- + ite.getMessage());
+ throw new IOException(MessageManager.formatMessage("exception.invocation_target_calling_url", new String[]{ite.getMessage()}));
} catch (IllegalAccessException iae)
{
- throw new IOException(
- "IllegalAccessException while calling openURL: "
- + iae.getMessage());
+ throw new IOException(MessageManager.formatMessage("exception.illegal_access_calling_url", new String[]{iae.getMessage()}));
}
break;
process.exitValue();
} catch (InterruptedException ie)
{
- throw new IOException(
- "InterruptedException while launching browser: "
- + ie.getMessage());
+ throw new IOException(MessageManager.formatMessage("exception.interrupted_launching_browser", new String[]{ie.getMessage()}));
}
break;
}
} catch (InterruptedException ie)
{
- throw new IOException(
- "InterruptedException while launching browser: "
- + ie.getMessage());
+ throw new IOException(MessageManager.formatMessage("exception.interrupted_launching_browser", new String[]{ie.getMessage()}));
}
break;
}
+ /**
+ * Returns a colour three shades darker. Note you can't guarantee that
+ * brighterThan reverses this, as darkerThan may result in black.
+ *
+ * @param col
+ * @return
+ */
+ public static Color darkerThan(Color col)
+ {
+ return col == null ? null : col.darker().darker().darker();
+ }
+
+ /**
+ * Returns a colour three shades brighter. Note you can't guarantee that
+ * darkerThan reverses this, as brighterThan may result in white.
+ *
+ * @param col
+ * @return
+ */
+ public static Color brighterThan(Color col)
+ {
+ return col == null ? null : col.brighter().brighter().brighter();
+ }
+
}
// check for chaincode and mapping
// PFAM style stockhom PDB citation
com.stevesoft.pat.Regex r = new com.stevesoft.pat.Regex(
- "([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;([0-9]+)-([0-9]+)");
+ "([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;\\s*([0-9]+)-([0-9]+)");
if (r.search(acn.trim()))
{
String pdbid = r.stringMatched(1);
String chaincode = r.stringMatched(2);
+ if (chaincode==null)
+ {
+ chaincode = " ";
+ }
String mapstart = r.stringMatched(3);
String mapend = r.stringMatched(4);
if (chaincode.equals(" "))
ref = new DBRefEntry(locsrc, version, pdbid + chaincode);
PDBEntry pdbr = new PDBEntry();
pdbr.setId(pdbid);
+ pdbr.setProperty(new Hashtable());
pdbr.getProperty().put("CHAIN", chaincode);
seq.addPDBId(pdbr);
+ } else {
+ System.err.println("Malformed PDB DR line:"+acn);
}
}
else
{ dsstring });
if (idstrings.length != seqstrings.length)
{
- throw new Error(
- "idstrings and seqstrings contain one string each per sequence.");
+ throw new Error(MessageManager.getString("error.idstring_seqstrings_only_one_per_sequence"));
}
return rstrings;
}
{
if (maxs != idseq[i].length)
{
- throw new Error(
- "Cannot have mixed length replacement vectors. Replacement vector for "
- + (mtch[i]) + " is " + idseq[i].length
- + " strings long, and have already seen a "
- + maxs + " length vector.");
+ throw new Error(MessageManager.formatMessage("error.cannot_have_mixed_length_replacement_vectors",
+ new String[]{(mtch[i]), Integer.valueOf(idseq[i].length).toString(),Integer.valueOf(maxs).toString()}));
}
}
}
else
{
- throw new Error(
- "Cannot have zero length vector of replacement strings - either 1 value or n values.");
+ throw new Error(MessageManager.getString("error.cannot_have_zero_length_vector_replacement_strings"));
}
}
// iterate through input, collating segments to be inserted into url
*/
package jalview.util;
-import java.io.*;
-import javax.imageio.*;
+import jalview.gui.EPSOptions;
+import jalview.io.JalviewFileChooser;
-import java.awt.*;
-import java.awt.image.*;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileOutputStream;
-import org.jibble.epsgraphics.*;
-import jalview.gui.*;
-import jalview.io.*;
+import javax.imageio.ImageIO;
+
+import org.jfree.graphics2d.svg.SVGGraphics2D;
+import org.jibble.epsgraphics.EpsGraphics2D;
public class ImageMaker
{
- public static final int EPS = 0;
-
- public static final int PNG = 1;
-
- int type = -1;
-
EpsGraphics2D pg;
+ SVGGraphics2D g2;
+
Graphics graphics;
FileOutputStream out;
BufferedImage bi;
- public ImageMaker(Component parent, int type, String title, int width,
- int height, File file, String EPStitle)
+ TYPE type;
+
+ public enum TYPE
+ {
+ EPS("EPS", MessageManager.getString("label.eps_file"), getEPSChooser()), PNG(
+ "PNG", MessageManager.getString("label.png_image"),
+ getPNGChooser()), SVG("SVG", "SVG", getSVGChooser());
+
+ private JalviewFileChooser chooser;
+
+ private String name;
+
+ private String label;
+
+ TYPE(String name, String label, JalviewFileChooser chooser)
+ {
+ this.name = name;
+ this.label = label;
+ this.chooser = chooser;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public JalviewFileChooser getChooser()
+ {
+ return chooser;
+ }
+
+ public String getLabel()
+ {
+ return label;
+ }
+
+ }
+
+
+ public ImageMaker(Component parent, TYPE type, String title, int width,
+ int height, File file, String fileTitle)
{
this.type = type;
if (file == null)
{
JalviewFileChooser chooser;
- chooser = type == EPS ? getEPSChooser() : getPNGChooser();
-
+ chooser = type.getChooser();
chooser.setFileView(new jalview.io.JalviewFileView());
chooser.setDialogTitle(title);
chooser.setToolTipText(MessageManager.getString("action.save"));
-
int value = chooser.showSaveDialog(parent);
if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
{
jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
.getSelectedFile().getParent());
-
file = chooser.getSelectedFile();
}
}
try
{
out = new FileOutputStream(file);
-
- if (type == EPS)
+ if (type == TYPE.SVG)
{
- setupEPS(width, height, EPStitle);
+ setupSVG(width, height, fileTitle);
}
- else
+ else if (type == TYPE.EPS)
+ {
+ setupEPS(width, height, fileTitle);
+ }
+ else if (type == TYPE.PNG)
{
setupPNG(width, height);
}
+
} catch (Exception ex)
{
System.out.println("Error creating "
- + (type == EPS ? "EPS" : "PNG") + " file.");
+ + type.getName() + " file.");
}
}
}
return graphics;
}
- void setupPNG(int width, int height)
- {
- bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- graphics = bi.getGraphics();
- Graphics2D ig2 = (Graphics2D) graphics;
- ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- }
+
public void writeImage()
{
pg.flush();
pg.close();
break;
+ case SVG:
+ String svgData = ((SVGGraphics2D) getGraphics()).getSVGDocument();
+ out.write(svgData.getBytes());
+ out.flush();
+ out.close();
+ break;
case PNG:
ImageIO.write(bi, "png", out);
+ out.flush();
out.close();
break;
}
try
{
pg = new EpsGraphics2D(title, out, 0, 0, width, height);
- Graphics2D ig2 = (Graphics2D) pg;
+ Graphics2D ig2 = pg;
ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
}
- JalviewFileChooser getPNGChooser()
+ void setupPNG(int width, int height)
+ {
+ bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ graphics = bi.getGraphics();
+ Graphics2D ig2 = (Graphics2D) graphics;
+ ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ }
+
+ void setupSVG(int width, int height, String title)
+ {
+ g2 = new SVGGraphics2D(width, height);
+ graphics = g2;
+ }
+
+ static JalviewFileChooser getPNGChooser()
{
return new jalview.io.JalviewFileChooser(
jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
{ "Portable network graphics" }, "Portable network graphics");
}
- JalviewFileChooser getEPSChooser()
+ static JalviewFileChooser getEPSChooser()
{
return new jalview.io.JalviewFileChooser(
jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
{ "eps" }, new String[]
{ "Encapsulated Postscript" }, "Encapsulated Postscript");
}
+
+ static JalviewFileChooser getSVGChooser()
+ {
+ return new jalview.io.JalviewFileChooser(
+ jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
+ { "svg" }, new String[]
+ { "Scalable Vector Graphics" }, "Scalable Vector Graphics");
+ }
}
}
+ @Override
+ public List<AlignmentAnnotation> getVisibleAlignmentAnnotation(boolean selectedOnly)
+ {
+ ArrayList<AlignmentAnnotation> ala = new ArrayList<AlignmentAnnotation>();
+ AlignmentAnnotation[] aa;
+ if ((aa=alignment.getAlignmentAnnotation())!=null)
+ {
+ for (AlignmentAnnotation annot:aa)
+ {
+ AlignmentAnnotation clone = new AlignmentAnnotation(annot);
+ if (selectedOnly && selectionGroup!=null)
+ {
+ colSel.makeVisibleAnnotation(selectionGroup.getStartRes(), selectionGroup.getEndRes(),clone);
+ } else {
+ colSel.makeVisibleAnnotation(clone);
+ }
+ ala.add(clone);
+ }
+ }
+ return ala;
+ }
+
/**
* @return the padGaps
*/
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
public abstract class FeatureRendererModel implements
if (features[i].featureGroup != null
&& featureGroups != null
&& featureGroups.containsKey(features[i].featureGroup)
- && !((Boolean) featureGroups.get(features[i].featureGroup))
+ && !featureGroups.get(features[i].featureGroup)
.booleanValue())
+ {
continue;
+ }
if ((features[i].getBegin() <= res)
&& (features[i].getEnd() >= res))
groupDisplayed = Boolean.valueOf(newMadeVisible);
featureGroups.put(fgrp, groupDisplayed);
}
- if (!((Boolean) groupDisplayed).booleanValue())
+ if (!groupDisplayed.booleanValue())
{
index++;
continue;
if (initOrders)
{
setOrder(oldRender[j], (1 - (1 + (float) j)
- / (float) oldRender.length));
+ / oldRender.length));
}
if (allfeatures.contains(oldRender[j]))
{
}
@Override
- public Map getFeatureColours()
+ public Map<String, Object> getFeatureColours()
{
- return new ConcurrentHashMap<>(featureColours);
+ return new ConcurrentHashMap<String, Object>(featureColours);
}
/**
}
if (featureGroups.containsKey(group))
{
- return ((Boolean) featureGroups.get(group)).booleanValue();
+ return featureGroups.get(group).booleanValue();
}
if (newGroupsVisible)
{
for (Object grp : featureGroups.keySet())
{
- Boolean state = (Boolean) featureGroups.get(grp);
+ Boolean state = featureGroups.get(grp);
if (state.booleanValue() == visible)
{
gp.add(grp);
featureGroups.put(gst, new Boolean(visible));
if (st != null)
{
- rdrw = rdrw || (visible != ((Boolean) st).booleanValue());
+ rdrw = rdrw || (visible != st.booleanValue());
}
}
if (rdrw)
if (alignViewport.isClosed())
{
abortAndDestroy();
+ return;
}
AlignmentI alignment = alignViewport.getAlignment();
*/
package jalview.workers;
-import java.util.ArrayList;
-import java.util.List;
-
import jalview.analysis.Conservation;
import jalview.api.AlignCalcWorkerI;
-import jalview.api.AlignmentViewPanel;
import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
+import java.util.ArrayList;
+import java.util.List;
+
public class ConservationThread extends AlignCalcWorker implements
AlignCalcWorkerI
{
if (alignViewport.isClosed())
{
abortAndDestroy();
+ return;
}
List<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
AlignmentI alignment = alignViewport.getAlignment();
*/
package jalview.workers;
-import java.util.Hashtable;
-
import jalview.analysis.StructureFrequency;
import jalview.api.AlignCalcWorkerI;
import jalview.api.AlignViewportI;
import jalview.datamodel.Annotation;
import jalview.datamodel.SequenceI;
+import java.util.Hashtable;
+
public class StrucConsensusThread extends AlignCalcWorker implements
AlignCalcWorkerI
{
if (alignViewport.isClosed())
{
abortAndDestroy();
+ return;
}
AlignmentI alignment = alignViewport.getAlignment();
import jalview.gui.AlignFrame;
import jalview.gui.WebserviceInfo;
import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
+import jalview.util.MessageManager;
public abstract class AWSThread extends Thread
{
} catch (Exception ex)
{
// Deal with Transaction exceptions
- wsInfo.appendProgressText(jobs[j].jobnum, "\n" + WebServiceName
- + " Server exception!\n" + ex.getMessage());
+ wsInfo.appendProgressText(jobs[j].jobnum,
+ MessageManager.formatMessage("info.server_exception", new String[]{WebServiceName,ex.getMessage()}));
// always output the exception's stack trace to the log
Cache.log.warn(WebServiceName + " job(" + jobs[j].jobnum
+ ") Server exception.");
Cache.log
.debug("WebServiceJob poll loop finished with no jobs created.");
wsInfo.setStatus(wsInfo.STATE_STOPPED_ERROR);
- wsInfo.appendProgressText("No jobs ran.");
+ wsInfo.appendProgressText(MessageManager.getString("info.no_jobs_ran"));
wsInfo.setFinishedNoResults();
}
}
{
if (dbSources == null)
{
- throw new Error("Implementation error. Must initialise dbSources");
+ throw new Error(MessageManager.getString("error.implementation_error_must_init_dbsources"));
}
running = true;
long startTime = System.currentTimeMillis();
- af.setProgressBar("Fetching db refs", startTime);
+ af.setProgressBar(MessageManager.getString("status.fetching_db_refs"), startTime);
try
{
if (Cache.getDefault("DBREFFETCH_USEPICR", false))
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.gui.FeatureSettings;
+import jalview.util.MessageManager;
import jalview.util.UrlLink;
import jalview.ws.dbsources.das.api.DasSourceRegistryI;
import jalview.ws.dbsources.das.api.jalviewSourceI;
reply = JOptionPane
.showInternalConfirmDialog(
Desktop.desktop,
- "Do you want Jalview to find\n"
- + "Uniprot Accession ids for given sequence names?",
- "Find Uniprot Accession Ids",
+ MessageManager.getString("info.you_want_jalview_to_find_uniprot_accessions"),
+ MessageManager.getString("label.find_uniprot_accession_ids"),
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
}
startTime = System.currentTimeMillis();
if (af != null)
{
- af.setProgressBar("Fetching DAS Sequence Features", startTime);
+ af.setProgressBar(MessageManager.getString("status.fetching_das_sequence_features"), startTime);
}
if (sourceRegistry == null)
{
if (af != null)
{
- af.setProgressBar("No DAS Sources Active", startTime);
+ af.setProgressBar(MessageManager.getString("status.no_das_sources_active"), startTime);
}
if (getFeatSettings() != null)
{
{
if (af != null)
{
- af.setProgressBar("DAS Feature Fetching Cancelled", startTime);
+ af.setProgressBar(MessageManager.getString("status.das_feature_fetching_cancelled"), startTime);
}
cancelled = true;
}
if (!cancelled && af != null)
{
// only update the progress bar if we've completed the fetch normally
- af.setProgressBar("DAS Feature Fetching Complete", startTime);
+ af.setProgressBar(MessageManager.getString("status.das_feature_fetching_complete"), startTime);
}
if (af != null && af.featureSettings != null)
import jalview.gui.Desktop;
import jalview.gui.JvSwingUtils;
import jalview.util.GroupUrlLink;
+import jalview.util.MessageManager;
import jalview.util.GroupUrlLink.UrlStringTooLongException;
import java.awt.Component;
{
dbname = "";
}
- item.setToolTipText("<html>"
- + JvSwingUtils.wrapTooltip("Submit " + i + " " + dbname + " "
- + (seqsorids ? "sequence" : "sequence id")
- + (i > 1 ? "s" : "")
-
- + " to<br/>" + descr) + "</html>");
+ item.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.submit_sequence", new String[]{Integer.valueOf(i).toString(), dbname, (seqsorids ? "sequence" : "sequence id"), (i > 1 ? "s" : "")})));
item.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
JOptionPane
.showInternalMessageDialog(
Desktop.desktop,
- "Unixers: Couldn't find default web browser."
- + "\nAdd the full path to your browser in Preferences.",
- "Web browser not found", JOptionPane.WARNING_MESSAGE);
+ MessageManager.getString("label.web_browser_not_found_unix"),
+ MessageManager.getString("label.web_browser_not_found"), JOptionPane.WARNING_MESSAGE);
ex.printStackTrace();
}
// menu appears asap
// sequence only URLs
// ID/regex match URLs
- JMenu groupLinksMenu = new JMenu("Group Link");
+ JMenu groupLinksMenu = new JMenu(MessageManager.getString("action.group_link"));
String[][] idandseqs = GroupUrlLink.formStrings(seqs);
Hashtable commonDbrefs = new Hashtable();
for (int sq = 0; sq < seqs.length; sq++)
// three types of url that might be
// created.
wflinkMenus = new JMenu[]
- { null, new JMenu("IDS"), new JMenu("Sequences"),
- new JMenu("IDS and Sequences") };
+ { null, new JMenu(MessageManager.getString("action.ids")), new JMenu(MessageManager.getString("action.sequences")),
+ new JMenu(MessageManager.getString("action.ids_sequences")) };
gurlMenus.put(label, wflinkMenus);
}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
import jalview.datamodel.xdb.embl.EmblEntry;
+import jalview.util.MessageManager;
import jalview.ws.ebi.EBIFetchClient;
import java.io.File;
} catch (Exception e)
{
stopQuery();
- throw new Exception("EBI EMBL XML retrieval failed on "
- + emprefx.toLowerCase() + ":" + query.trim(), e);
+ throw new Exception(MessageManager.formatMessage("exception.ebiembl_retrieval_failed_on", new String[]{emprefx.toLowerCase(),query.trim()}), e);
}
return getEmblSequenceRecords(emprefx, query, reply);
}
}
else
{
- result.append("# No EMBL record retrieved for "
- + emprefx.toLowerCase() + ":" + query.trim());
+ result.append(MessageManager.formatMessage("label.no_embl_record_found", new String[]{emprefx.toLowerCase(),query.trim()}));
}
}
if (efile != null)
if (seqs != null && seqs.length > 0)
{
al = new Alignment(seqs);
- result.append("# Successfully parsed the " + emprefx
- + " queries into an Alignment");
+ result.append(MessageManager.formatMessage("label.embl_successfully_parsed", new String[]{emprefx}));
results = result;
}
stopQuery();
package jalview.ws.dbsources;
import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.AlignmentI;
import jalview.io.FormatAdapter;
+import jalview.util.MessageManager;
import jalview.ws.ebi.EBIFetchClient;
import jalview.ws.seqfetcher.DbSourceProxy;
for (SequenceI pdbcs : toremove)
{
pdbfile.deleteSequence(pdbcs);
+ if (pdbcs.getAnnotation()!=null)
+ {
+ for (AlignmentAnnotation aa: pdbcs.getAnnotation())
+ {
+ pdbfile.deleteAnnotation(aa);
+ }
+ }
}
}
if (pdbfile == null || pdbfile.getHeight() < 1)
{
- throw new Exception("No PDB Records for " + id + " chain "
- + ((chain == null) ? "' '" : chain));
+ throw new Exception(MessageManager.formatMessage("exception.no_pdb_records_for_chain", new String[]{id, ((chain == null) ? "' '" : chain)}));
}
} catch (Exception ex) // Problem parsing PDB file
import com.stevesoft.pat.Regex;
+import jalview.util.MessageManager;
import jalview.ws.dbsources.das.api.jalviewSourceI;
import jalview.ws.seqfetcher.*;
import jalview.bin.Cache;
if (!(jsrc = new JalviewSource(source, connprops, false))
.isSequenceSource())
{
- throw new Exception("Source " + source.getTitle()
- + " does not support the sequence command.");
+ throw new Exception(MessageManager.formatMessage("exception.das_source_doesnt_support_sequence_command", new String[]{source.getTitle()}));
}
this.tier = 1 + ((jsrc.isLocal() || jsrc.isReferenceSource()) ? 0 : 1);
this.source = source;
import org.biodas.jdas.schema.sources.SOURCE;
import org.biodas.jdas.schema.sources.VERSION;
+import jalview.util.MessageManager;
import jalview.ws.dbsources.das.api.jalviewSourceI;
import jalview.ws.seqfetcher.DbSourceProxy;
int p = cap.getQueryUri().lastIndexOf(capname);
if (p < -1)
{
- throw new Exception("Invalid das source: " + source.getUri());
+ throw new Exception(MessageManager.formatMessage("exception.invalid_das_source", new String[]{source.getUri()}));
}
if (cap.getQueryUri().charAt(p) == '/')
{
*/
package jalview.ws.ebi;
+import jalview.util.MessageManager;
+
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
public String[] getSupportedDBs()
{
// TODO - implement rest call for dbfetch getSupportedDBs
- throw new Error("Not yet implemented");
+ throw new Error(MessageManager.getString("error.not_yet_implemented"));
}
/**
public String[] getSupportedFormats()
{
// TODO - implement rest call for dbfetch getSupportedFormats
- throw new Error("Not yet implemented");
+ throw new Error(MessageManager.getString("error.not_yet_implemented"));
}
/**
public String[] getSupportedStyles()
{
// TODO - implement rest call for dbfetch getSupportedStyles
- throw new Error("Not yet implemented");
+ throw new Error(MessageManager.getString("error.not_yet_implemented"));
}
public File fetchDataAsFile(String ids, String f, String s)
import jalview.io.FileParse;
import jalview.io.FormatAdapter;
import jalview.io.InputStreamParser;
+import jalview.util.MessageManager;
import java.io.BufferedReader;
import java.io.FileReader;
}
else
{
- throw new IOException(
- "Unexpected exception when handling RNAML translation of PDB data",
+ throw new IOException(MessageManager.getString("exception.unexpected_handling_rnaml_translation_for_pdb"),
x);
}
}
*/
package jalview.ws.jws1;
+import jalview.util.MessageManager;
+
import java.util.*;
import javax.swing.*;
"Edgar, Robert C. (2004), MUSCLE: multiple sequence alignment "
+ "with high accuracy and high throughput, Nucleic Acids Research 32(5), 1792-97.",
"http://www.compbio.dundee.ac.uk/JalviewWS/services/MuscleWS",
- "Muscle Multiple Protein Sequence Alignment"),
+ MessageManager.getString("label.muscle_multiple_protein_sequence_alignment")),
new ServiceHandle(
"MsaWS",
"Katoh, K., K. Kuma, K., Toh, H., and Miyata, T. (2005) "
+ "\"MAFFT version 5: improvement in accuracy of multiple sequence alignment.\""
+ " Nucleic Acids Research, 33 511-518",
"http://www.compbio.dundee.ac.uk/JalviewWS/services/MafftWS",
- "MAFFT Multiple Sequence Alignment"),
+ MessageManager.getString("label.mafft_multiple_sequence_alignment")),
new ServiceHandle(
"MsaWS",
"Thompson, J.D., Higgins, D.G. and Gibson, T.J. (1994) CLUSTAL W: improving the sensitivity of progressive multiple"
+ " sequence alignment through sequence weighting, position specific gap penalties and weight matrix choice."
+ " Nucleic Acids Research, 22 4673-4680",
"http://www.compbio.dundee.ac.uk/JalviewWS/services/ClustalWS",
- "ClustalW Multiple Sequence Alignment"),
+ MessageManager.getString("label.clustalw_multiple_sequence_alignment")),
new ServiceHandle(
"SecStrPred",
"Cole C., Barber J. D., Barton G.J (2008) "
JOptionPane
.showMessageDialog(
jalview.gui.Desktop.desktop,
- "Please set up your proxy settings in the 'Connections' tab of the Preferences window",
- "Proxy Authorization Failed",
+ MessageManager.getString("label.set_proxy_settings"),
+ MessageManager.getString("label.proxy_authorization_failed"),
JOptionPane.WARNING_MESSAGE);
}
}
import jalview.bin.*;
import jalview.datamodel.*;
import jalview.gui.*;
+import jalview.util.MessageManager;
public class JPredClient extends WS1Client
{
{
if (!msa && msf.length > 1)
{
- throw new Error(
- "Implementation Error! Multiple single sequence prediction jobs are not yet supported.");
+ throw new Error(MessageManager.getString("error.implementation_error_multiple_single_sequence_prediction_jobs_not_supported"));
}
String altitle = getPredictionName(WebServiceName) + " for "
private WebserviceInfo setWebService()
{
WebServiceName = "JNetWS";
- WebServiceJobTitle = "JNet secondary structure prediction";
+ WebServiceJobTitle = MessageManager.getString("label.jnet_secondary_structure_prediction");
WebServiceReference = "\"Cuff J. A and Barton G.J (2000) Application of "
+ "multiple sequence alignment profiles to improve protein secondary structure prediction, "
+ "Proteins 40:502-511\".";
} catch (Exception ex)
{
JOptionPane.showMessageDialog(Desktop.desktop,
- "The Secondary Structure Prediction Service named "
- + WebServiceName + " at " + WsURL
- + " couldn't be located.", "Internal Jalview Error",
+ MessageManager.formatMessage("label.secondary_structure_prediction_service_couldnt_be_located", new String[]{WebServiceName,WsURL}),
+ MessageManager.getString("label.internal_jalview_error"),
JOptionPane.WARNING_MESSAGE);
- wsInfo.setProgressText("Serious! " + WebServiceName
- + " Service location failed\nfor URL :" + WsURL + "\n"
+ wsInfo.setProgressText(MessageManager.formatMessage("label.secondary_structure_prediction_service_couldnt_be_located", new String[]{WebServiceName,WsURL})
+ + "\n"
+ ex.getMessage());
wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
if (!jalview.analysis.SeqsetUtils.deuniquify(
(Hashtable) SequenceInfo, sqs))
{
- throw (new Exception(
- "Couldn't recover sequence properties for alignment."));
+ throw (new Exception(MessageManager.getString("exception.couldnt_recover_sequence_properties_for_alignment")));
}
}
FirstSeq = 0;
}
else
{
- throw (new Exception("Unknown format " + format
- + " for file : \n" + result.getAligfile()));
+ throw (new Exception(MessageManager.formatMessage("exception.unknown_format_for_file", new String[]{format,result.getAligfile()})));
}
}
else
.getAlignmentAndColumnSelection(gc))[0];
if (this.msaIndex >= sqs.length)
{
- throw new Error(
- "Implementation Error! Invalid msaIndex for JPredJob on parent MSA input object!");
+ throw new Error(MessageManager.getString("error.implementation_error_invalid_msa_index_for_job"));
}
// ///
// Uses RemoveGapsCommand
// ///
- new jalview.commands.RemoveGapsCommand("Remove Gaps",
+ new jalview.commands.RemoveGapsCommand(MessageManager.getString("label.remove_gaps"),
new SequenceI[]
{ sqs[msaIndex] }, currentView);
if (!jalview.analysis.SeqsetUtils.SeqCharacterUnhash(
al.getSequenceAt(FirstSeq), SequenceInfo))
{
- throw (new Exception(
- "Couldn't recover sequence properties for JNet Query sequence!"));
+ throw (new Exception(MessageManager.getString("exception.couldnt_recover_sequence_props_for_jnet_query")));
}
else
{
{
if (!(j instanceof JPredJob))
{
- throw new Error(
- "Implementation error - StartJob(JpredJob) called on "
- + j.getClass());
+ throw new Error(MessageManager.formatMessage("error.implementation_error_startjob_called", new String[]{j.getClass().toString()}));
}
try
{
{
job.result = (vamsas.objects.simple.Result) new JpredResult();
job.result.setInvalid(true);
- job.result.setStatus("Submission " + job.getJobId());
+ job.result.setStatus(MessageManager.formatMessage("label.submission_params", new String[]{job.getJobId().toString()}));
throw new Exception(job.getJobId());
}
else
}
else
{
- throw new Exception("Server timed out - try again later\n");
+ throw new Exception(MessageManager.getString("exception.server_timeout_try_later"));
}
} catch (Exception e)
{
{
wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR);
// JBPNote - this could be a popup informing the user of the problem.
- wsInfo.appendProgressText(j.getJobnum(),
- "Failed to submit the prediction:\n" + e.getMessage()
- + wsInfo.getProgressText());
+ wsInfo.appendProgressText(j.getJobnum(), MessageManager.formatMessage("info.failed_to_submit_prediction", new String[]{e.getMessage(),wsInfo.getProgressText()}));
jalview.bin.Cache.log.debug(
"Failed Submission of job " + j.getJobnum(), e);
else
{
// do merge with other job results
- throw new Error(
- "Multiple JNet subjob merging not yet implemented.");
+ throw new Error(MessageManager.getString("error.multiple_jnet_subjob_merge_not_implemented"));
}
} catch (Exception e)
{
"JNet Client: JPred Annotation Parse Error", e);
wsInfo.setStatus(j.getJobnum(),
WebserviceInfo.STATE_STOPPED_ERROR);
- wsInfo.appendProgressText(j.getJobnum(), OutputHeader + "\n"
- + j.result.getStatus()
- + "\nInvalid JNet job result data!\n" + e.getMessage());
+ wsInfo.appendProgressText(j.getJobnum(), MessageManager.formatMessage("info.invalid_jnet_job_result_data", new String[]{OutputHeader.toString(),j.result.getStatus(), e.getMessage() }));
j.result.setBroken(true);
}
}
public void cancelJob()
{
- throw new Error("Implementation error!");
+ throw new Error(MessageManager.getString("error.implementation_error"));
}
public boolean canMergeResults()
import ext.vamsas.*;
import jalview.datamodel.*;
import jalview.gui.*;
+import jalview.util.MessageManager;
/**
* DOCUMENT ME!
JOptionPane
.showMessageDialog(
Desktop.desktop,
- "The Service called \n"
- + sh.getName()
- + "\nis not a \nMultiple Sequence Alignment Service !",
- "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
+ MessageManager.formatMessage("label.service_called_is_not_msa_service", new String[]{sh.getName()}),
+ MessageManager.getString("label.internal_jalview_error"), JOptionPane.WARNING_MESSAGE);
return;
}
{
JOptionPane.showMessageDialog(
Desktop.desktop,
- "The Multiple Sequence Alignment Service named "
- + sh.getName() + " is unknown",
- "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
+ MessageManager.formatMessage("label.msa_service_is_unknown", new String[]{sh.getName()}),
+ MessageManager.getString("label.internal_jalview_error"), JOptionPane.WARNING_MESSAGE);
return;
}
import jalview.bin.*;
import jalview.datamodel.*;
import jalview.gui.*;
+import jalview.util.MessageManager;
import jalview.ws.AWsJob;
import jalview.ws.JobStateSummary;
import jalview.ws.WSClientI;
subjobComplete = true;
result = new MsaResult();
result.setFinished(true);
- result.setStatus("Job never ran - input returned to user.");
+ result.setStatus(MessageManager.getString("label.job_never_ran"));
}
}
int nseqs = 0;
if (minlen < 0)
{
- throw new Error(
- "Implementation error: minlen must be zero or more.");
+ throw new Error(MessageManager.getString("error.implementation_error_minlen_must_be_greater_zero"));
}
for (int i = 0; i < seqs.length; i++)
{
{
if (!(job instanceof MsaWSJob))
{
- throw new Error("StartJob(MsaWSJob) called on a WSJobInstance "
- + job.getClass());
+ throw new Error(MessageManager.formatMessage("error.implementation_error_msawbjob_called", new String[]{job.getClass().toString()}));
}
MsaWSJob j = (MsaWSJob) job;
if (j.isSubmitted())
j.setSubmitted(true);
j.result = new MsaResult();
j.result.setFinished(true);
- j.result.setStatus("Empty Alignment Job");
+ j.result.setStatus(MessageManager.getString("label.empty_alignment_job"));
((MsaResult) j.result).setMsa(null);
}
try
{
if (jobsubmit == null)
{
- throw new Exception(
- "Server at "
- + WsUrl
- + " returned null object, it probably cannot be contacted. Try again later ?");
+ throw new Exception(MessageManager.formatMessage("exception.web_service_returned_null_try_later", new String[]{WsUrl}));
}
throw new Exception(jobsubmit.getJobId());
WebserviceInfo.STATE_STOPPED_SERVERERROR);
wsInfo.appendProgressText(
j.getJobnum(),
- "Failed to submit sequences for alignment.\n"
- + "It is most likely that there is a problem with the server.\n"
- + "Just close the window\n");
+ MessageManager.getString("info.failed_to_submit_sequences_for_alignment"));
// e.printStackTrace(); // TODO: JBPNote DEBUG
}
if (valign != null)
{
wsInfo.appendProgressText(jobs[j].getJobnum(),
- "\nAlignment Object Method Notes\n");
+ MessageManager.getString("info.alignment_object_method_notes"));
String[] lines = valign.getMethod();
for (int line = 0; line < lines.length; line++)
{
import ext.vamsas.*;
import jalview.datamodel.*;
import jalview.gui.*;
+import jalview.util.MessageManager;
/**
* DOCUMENT ME!
if (!sh.getAbstractName().equals(this.getServiceActionKey()))
{
JOptionPane.showMessageDialog(Desktop.desktop,
- "The Service called \n" + sh.getName()
- + "\nis not a \nSequence Search Service !",
- "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
+ MessageManager.formatMessage("label.service_called_is_not_seq_search_service", new String[]{sh.getName()}),
+ MessageManager.getString("label.internal_jalview_error"), JOptionPane.WARNING_MESSAGE);
return;
}
if ((wsInfo = setWebService(sh)) == null)
{
JOptionPane.showMessageDialog(Desktop.desktop,
- "The Sequence Search Service named " + sh.getName()
- + " is unknown", "Internal Jalview Error",
+ MessageManager.formatMessage("label.seq_search_service_is_unknown", new String[]{sh.getName()}),
+ MessageManager.getString("label.internal_jalview_error"),
JOptionPane.WARNING_MESSAGE);
return;
}
if (!locateWebService())
{
- throw new Exception("Cannot contact service endpoint at " + WsURL);
+ throw new Exception(MessageManager.formatMessage("exception.cannot_contact_service_endpoint_at", new String[]{WsURL}));
}
String database = server.getDatabase();
if (database == null)
import jalview.datamodel.*;
import jalview.gui.*;
import jalview.io.NewickFile;
+import jalview.util.MessageManager;
import jalview.ws.AWsJob;
import jalview.ws.JobStateSummary;
import jalview.ws.WSClientI;
subjobComplete = true;
result = new MsaResult();
result.setFinished(true);
- result.setStatus("Job never ran - input returned to user.");
+ result.setStatus(MessageManager.getString("label.job_never_ran"));
}
}
int nseqs = 0;
if (minlen < 0)
{
- throw new Error(
- "Implementation error: minlen must be zero or more.");
+ throw new Error(MessageManager.getString("error.implementation_error_minlen_must_be_greater_zero"));
}
for (int i = 0; i < seqs.length; i++)
{
{
if (!(job instanceof SeqSearchWSJob))
{
- throw new Error("StartJob(MsaWSJob) called on a WSJobInstance "
- + job.getClass());
+ throw new Error(MessageManager.formatMessage("error.implementation_error_msawbjob_called", new String[]{job.getClass().toString()}));
}
SeqSearchWSJob j = (SeqSearchWSJob) job;
if (j.isSubmitted())
j.setSubmitted(true);
j.result = new MsaResult();
j.result.setFinished(true);
- j.result.setStatus("Empty Alignment Job");
+ j.result.setStatus(MessageManager.getString("label.empty_alignment_job"));
((MsaResult) j.result).setMsa(null);
}
try
{
if (jobsubmit == null)
{
- throw new Exception(
- "Server at "
- + WsUrl
- + " returned null object, it probably cannot be contacted. Try again later ?");
+ throw new Exception(MessageManager.formatMessage("exception.web_service_returned_null_try_later", new String[]{WsUrl}));
}
throw new Exception(jobsubmit.getJobId());
WebserviceInfo.STATE_STOPPED_SERVERERROR);
wsInfo.appendProgressText(
j.getJobnum(),
- "Failed to submit sequences for alignment.\n"
- + "It is most likely that there is a problem with the server.\n"
- + "Just close the window\n");
+ MessageManager.getString("info.failed_to_submit_sequences_for_alignment"));
// e.printStackTrace(); // TODO: JBPNote DEBUG
}
if (valign != null)
{
wsInfo.appendProgressText(jobs[j].getJobnum(),
- "\nAlignment Object Method Notes\n");
+ MessageManager.getString("info.alignment_object_method_notes"));
String[] lines = valign.getMethod();
for (int line = 0; line < lines.length; line++)
{
AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
if (nf != null)
{
- af.ShowNewickTree(nf, "Tree from " + this.alTitle);
+ af.ShowNewickTree(nf, MessageManager.formatMessage("label.tree_from", new String[]{this.alTitle}));
}
// initialise with same renderer settings as in parent alignframe.
af.getFeatureRenderer().transferSettings(this.featureSettings);
import jalview.gui.AlignFrame;
import jalview.gui.WebserviceInfo;
+import jalview.util.MessageManager;
import jalview.ws.WSClient;
import jalview.ws.WSMenuEntryProviderI;
{
if (serviceHandle == null)
{
- throw new Error(
- "IMPLEMENTATION ERROR: cannot attach WS Menu Entry without service handle reference!");
+ throw new Error(MessageManager.getString("error.implementation_error_cannot_attach_ws_menu_entry"));
}
attachWSMenuEntry(wsmenu, serviceHandle, alignFrame);
}
import jalview.ws.params.WsParamSetI;
import jalview.ws.uimodel.AlignAnalysisUIText;
+import java.awt.Color;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public List<Argument> selectDefaultArgs()
{
List<ArgumentI> rgs = new ArrayList<ArgumentI>();
- for (ArgumentI argi: service.getParamStore().getServiceParameters())
+ for (ArgumentI argi : service.getParamStore().getServiceParameters())
{
if (argi instanceof OptionI)
{
List<String> o = ((OptionI) argi).getPossibleValues();
if (o.contains("-pred-nohits"))
{
- OptionI cpy = ((OptionI)argi).copy();
+ OptionI cpy = ((OptionI) argi).copy();
cpy.setValue("-pred-nohits");
rgs.add(cpy);
}
{
return "calculating consensus secondary structure prediction using JPred service";
}
- private static HashMap<String, String[]> jpredRowLabels = new HashMap<String,String[]>();
- private static HashSet<String>jpredRes_graph,jpredRes_ssonly;
+
+ private static HashMap<String, String[]> jpredRowLabels = new HashMap<String, String[]>();
+
+ private static HashSet<String> jpredRes_graph, jpredRes_ssonly;
{
- jpredRes_ssonly=new HashSet();
+ jpredRes_ssonly = new HashSet();
jpredRes_ssonly.add("jnetpred".toLowerCase());
- jpredRes_graph=new HashSet();
+ jpredRes_ssonly.add("jnetpssm".toLowerCase());
+ jpredRes_ssonly.add("jnethmm".toLowerCase());
+ jpredRes_graph = new HashSet();
jpredRes_graph.add("jnetconf".toLowerCase());
-
+ jpredRes_graph.add("jnet burial".toLowerCase());
}
+
/**
* update the consensus annotation from the sequence profile data using
* current visualization settings.
JpredAlignment jpres = (JpredAlignment) msascoreset;
int alWidth = alignViewport.getAlignment().getWidth();
ArrayList<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
- for (FastaSequence fsq:jpres.getJpredSequences())
+ char[] sol = new char[jpres.getJpredSequences().get(0).getLength()];
+ boolean firstsol = true;
+ for (FastaSequence fsq : jpres.getJpredSequences())
{
String[] k = jpredRowLabels.get(fsq.getId());
- if (k==null)
+ if (k == null)
+ {
+ k = new String[]
+ { fsq.getId(), "JNet Output" };
+ }
+ if (fsq.getId().startsWith("JNETSOL"))
+ {
+ char amnt = (fsq.getId().endsWith("25") ? "3" : fsq.getId()
+ .endsWith("5") ? "6" : "9").charAt(0);
+ char[] vseq = fsq.getSequence().toCharArray();
+ for (int spos = 0, sposL = fsq.getLength(); spos < sposL; spos++)
+ {
+ if (firstsol)
+ {
+ sol[spos] = '0';
+ }
+ if (vseq[spos] == 'B' && (sol[spos]=='0' || sol[spos] < amnt))
+ {
+ sol[spos] = amnt;
+ }
+ }
+ firstsol = false;
+ }
+ else
{
- k = new String[] { fsq.getId(), "JNet Output"};
+ createAnnotationRowFromString(
+ ourAnnot,
+ getCalcId(),
+ alWidth,
+ k[0],
+ k[1],
+ jpredRes_graph.contains(fsq.getId()) ? AlignmentAnnotation.BAR_GRAPH
+ : AlignmentAnnotation.NO_GRAPH, 0f, 9f,
+ fsq.getSequence());
}
- createAnnotationRowFromString(ourAnnot, getCalcId(), alWidth,
- k[0],k[1],
- jpredRes_graph.contains(fsq.getId()) ? AlignmentAnnotation.BAR_GRAPH : AlignmentAnnotation.NO_GRAPH, 0f, 0f,
- fsq.getSequence());
}
- for (FastaSequence fsq: jpres.getSequences())
+ createAnnotationRowFromString(
+ ourAnnot,
+ getCalcId(),
+ alWidth,
+ "Jnet Burial",
+ "<html>Prediction of Solvent Accessibility<br/>levels are<ul><li>0 - Exposed</li><li>3 - 25% or more S.A. accessible</li><li>6 - 5% or more S.A. accessible</li><li>9 - Buried (<5% exposed)</li></ul>",
+ AlignmentAnnotation.BAR_GRAPH, 0f, 9f, new String(sol));
+ for (FastaSequence fsq : jpres.getSequences())
{
if (fsq.getId().equalsIgnoreCase("QUERY"))
{
createAnnotationRowFromString(ourAnnot, getCalcId(), alWidth,
"Query", "JPred Reference Sequence",
- AlignmentAnnotation.NO_GRAPH, 0f, 0f,
- fsq.getSequence());
+ AlignmentAnnotation.NO_GRAPH, 0f, 0f, fsq.getSequence());
}
}
if (ourAnnot.size() > 0)
{
// created a valid annotation from the data
ourAnnot.add(annotation);
+ // annotation.validateRangeAndDisplay();
}
}
}
AlignmentAnnotation annotation, String sourceData, int alWidth,
int rowType)
{
- if (sourceData.length()==0 && alWidth>0)
+ if (sourceData.length() == 0 && alWidth > 0)
{
return false;
}
Annotation[] elm = new Annotation[alWidth];
+ boolean ssOnly = jpredRes_ssonly.contains(annotation.label
+ .toLowerCase());
+ boolean graphOnly = rowType != AlignmentAnnotation.NO_GRAPH;
+ if (!ssOnly && !graphOnly)
+ {
+ // for burial 'B'
+ annotation.showAllColLabels = true;
+ }
for (int i = 0, iSize = sourceData.length(); i < iSize; i++)
{
switch (rowType)
{
case AlignmentAnnotation.NO_GRAPH:
- elm[i] = new Annotation("" + annot, "" + annot, annot, Float.NaN);
+ elm[i] = ssOnly ? new Annotation("", "", annot, Float.NaN,
+ colourSS(annot)) : new Annotation("" + annot, "" + annot,
+ '\0', Float.NaN);
break;
default:
try
{
elm[i] = new Annotation("" + annot, "" + annot, annot,
- Integer.valueOf(annot));
+ Integer.valueOf(""+annot));
} catch (Exception x)
{
System.err.println("Expected numeric value in character '"
return true;
}
+ private Color colourSS(char annot)
+ {
+ switch (annot)
+ {
+ case 'H':
+ return jalview.renderer.AnnotationRenderer.HELIX_COLOUR;
+ case 'E':
+ return jalview.renderer.AnnotationRenderer.SHEET_COLOUR;
+ }
+ return jalview.renderer.AnnotationRenderer.GLYPHLINE_COLOR;
+ }
+
@Override
public String getCalcId()
{
import compbio.metadata.PresetManager;
import compbio.metadata.RunnerConfig;
+import jalview.util.MessageManager;
import jalview.ws.jws2.dm.JabaOption;
import jalview.ws.jws2.dm.JabaParameter;
import jalview.ws.jws2.dm.JabaWsParamSet;
}
if (narg == null)
{
- throw new Error(
- "Implementation Error: Cannot handle Jaba parameter object "
- + rg.getClass());
+ throw new Error(MessageManager.formatMessage("error.implementation_error_cannot_handle_jaba_param", new String[]{rg.getClass().toString()}));
}
else
{
.getOption() : null;
if (narg == null)
{
- throw new Error(
- "Implementation Error: Cannot handle Jaba parameter object "
- + rg.getClass());
+ throw new Error(MessageManager.formatMessage("error.implementation_error_cannot_handle_jaba_param", new String[]{rg.getClass().toString()}));
}
else
{
}
if (servicePresets.containsKey(name))
{
- throw new Error(
- "Implementation error: Attempt to delete a service preset!");
+ throw new Error(MessageManager.getString("error.implementation_error_attempt_to_delete_service_preset"));
}
}
: getPreset(presetName));
if (jps == null)
{
- throw new Error("Implementation error: Can't locate either oldname ("
- + oldName + ") or presetName (" + presetName
- + "in the datastore!");
+ throw new Error(MessageManager.formatMessage("error.implementation_error_cannot_locate_oldname_presetname", new String[]{oldName,presetName}));
}
jps.setName(presetName);
jps.setDescription(text);
{
if (!involves(urls))
{
- throw new IOException(
- "Implementation error: Cannot find service url in the given url set!");
+ throw new IOException(MessageManager.getString("error.implementation_error_cannot_find_service_url_in_given_set"));
}
JabaWsParamSet wsp = new JabaWsParamSet();
{
if (!involves(pset.getApplicableUrls()))
{
- throw new IOException(
- "Implementation error: Cannot find service url in the given url set for this service parameter store ("
- + service.getUri() + ") !");
-
+ throw new IOException(MessageManager.formatMessage("error.implementation_error_cannot_find_service_url_in_given_set_param_store", new String[]{service.getUri()}));
}
if (!(pset instanceof JabaWsParamSet))
{
- throw new Error(
- "Implementation error: JabaWsParamSets can only be handled by JabaParamStore");
+ throw new Error(MessageManager.getString("error.implementation_error_jabaws_param_set_only_handled_by"));
}
StringBuffer rslt = new StringBuffer();
*/
package jalview.ws.jws2;
+import jalview.util.MessageManager;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.params.ArgumentI;
import jalview.ws.params.WsParamSetI;
@Override
public void setSourceFile(String newfile)
{
- throw new Error("Cannot set source file for " + getClass());
+ throw new Error(MessageManager.formatMessage("error.cannot_set_source_file_for", new String[]{getClass().toString()}));
}
@Override
} catch (Exception e)
{
e.printStackTrace();
- throw new Error(
- "Probable mismatch between service instance and preset!");
+ throw new Error(MessageManager.getString("error.mismatch_service_instance_preset"));
}
}
@Override
public void setArguments(List<ArgumentI> args)
{
- throw new Error("Cannot set Parameters for a Jaba Web service's preset");
+ throw new Error(MessageManager.getString("error.cannot_set_params_for_ws_preset"));
}
}
import jalview.datamodel.Annotation;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
+import jalview.util.MessageManager;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.params.WsParamSetI;
rslt = aaservice.customAnalize(seqs, getJabaArguments());
} catch (WrongParameterException x)
{
- throw new JobSubmissionException(
- "Invalid parameter set. Check Jalview implementation.", x);
+ throw new JobSubmissionException(MessageManager.getString("exception.jobsubmission_invalid_params_set"), x);
}
}
import jalview.datamodel.Annotation;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
+import jalview.util.MessageManager;
import jalview.workers.AlignCalcWorker;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.params.WsParamSetI;
rslt = msaservice.customAlign(seqs, getJabaArguments());
} catch (WrongParameterException x)
{
- throw new JobSubmissionException(
- "Invalid parameter set. Check Jalview implementation.", x);
-
+ throw new JobSubmissionException(MessageManager.getString("exception.jobsubmission_invalid_params_set"), x);
}
}
return rslt;
* arguments. for (Argument opt : arguments) { newargs.add(opt); } }
* paramset = newargs; } else {
*/
- throw new Error(
- "Implementation error: Can only instantiate Jaba parameter sets.");
+ throw new Error(MessageManager.getString("error.implementation_error_can_only_instantiate_jaba_param_sets"));
}
}
else
final JCheckBoxMenuItem aaConEnabled = new JCheckBoxMenuItem(
aaui.getAAconToggle());
- aaConEnabled.setToolTipText("<html><p>"
- + JvSwingUtils.wrapTooltip(aaui.getAAconToggleTooltip()
- + "</p>") + "</html>");
+ aaConEnabled.setToolTipText(JvSwingUtils.wrapTooltip(true, aaui.getAAconToggleTooltip()));
aaConEnabled.addActionListener(new ActionListener()
{
@Override
wsmenu.add(aaConEnabled);
final JMenuItem modifyParams = new JMenuItem(aaui.getAAeditSettings());
modifyParams.setToolTipText("<html><p>"
- + JvSwingUtils.wrapTooltip(aaui.getAAeditSettingsTooltip()
+ + JvSwingUtils.wrapTooltip(false, aaui.getAAeditSettingsTooltip()
+ "</p>") + "</html>");
modifyParams.addActionListener(new ActionListener()
{
{
// TODO raise dialog box explaining error, and/or open the JABA
// preferences menu.
- throw new Error("No AACon service found.");
+ throw new Error(MessageManager.getString("error.no_aacon_service_found"));
}
return new AAConSettings(true, service, null, null);
}
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.gui.JvSwingUtils;
+import jalview.util.MessageManager;
import jalview.ws.WSMenuEntryProviderI;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.params.ParamDatastoreI;
}
});
hitm.setToolTipText(JvSwingUtils
- .wrapTooltip("Opens the JABAWS server's homepage in web browser"));
+ .wrapTooltip(false, MessageManager.getString("label.open_jabaws_web_page ")));
service.attachWSMenuEntry(atpoint, alignFrame);
if (alternates.containsKey(service.serviceType))
{
- atpoint.add(hitm = new JMenu("Switch server"));
+ atpoint.add(hitm = new JMenu(MessageManager.getString("label.switch_server")));
hitm.setToolTipText(JvSwingUtils
- .wrapTooltip("Choose a server for running this service"));
+ .wrapTooltip(false, MessageManager.getString("label.choose_jabaws_server")));
for (final Jws2Instance sv : alternates.get(service.serviceType))
{
JMenuItem itm;
atpoint = JvSwingUtils.findOrCreateMenu(atpoint, host);
if (atpoint.getToolTipText() == null)
{
- atpoint.setToolTipText("Services at " + host);
+ atpoint.setToolTipText(MessageManager.formatMessage("label.services_at", new String[]{host}));
}
}
if (bytype)
}
});
hitm.setToolTipText(JvSwingUtils
- .wrapTooltip("Opens the JABAWS server's homepage in web browser"));
+ .wrapTooltip(true, MessageManager.getString("label.open_jabaws_web_page")));
lasthostFor.put(service.action, host);
}
hostLabels.add(host + service.serviceType
JOptionPane
.showMessageDialog(
Desktop.desktop,
- "The Service called \n"
- + sh.serviceType
- + "\nis not a \nMultiple Sequence Alignment Service !",
- "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
+ MessageManager.formatMessage("label.service_called_is_not_msa_service", new String[]{sh.serviceType}),
+ MessageManager.getString("label.internal_jalview_error"), JOptionPane.WARNING_MESSAGE);
return;
}
if ((wsInfo = setWebService(sh, false)) == null)
{
JOptionPane.showMessageDialog(Desktop.desktop,
- "The Multiple Sequence Alignment Service named "
- + sh.serviceType + " is unknown",
- "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
+ MessageManager.formatMessage("label.msa_service_is_unknown", new String[]{sh.serviceType}),
+ MessageManager.getString("label.internal_jalview_error"), JOptionPane.WARNING_MESSAGE);
return;
}
for (final WsParamSetI preset : presets)
{
final JMenuItem methodR = new JMenuItem(preset.getName());
- methodR.setToolTipText("<html><p>"
- + JvSwingUtils.wrapTooltip("<strong>"
- + (preset.isModifiable() ? "User Preset"
- : "Service Preset") + "</strong><br/>"
- + preset.getDescription() + "</p>") + "</html>");
+ methodR.setToolTipText(JvSwingUtils.wrapTooltip(true, "<p><strong>"
+ + (preset.isModifiable() ? MessageManager.getString("label.user_preset")
+ : MessageManager.getString("label.service_preset")) + "</strong><br/>"
+ + preset.getDescription() + "</p>"));
methodR.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
import jalview.bin.*;
import jalview.datamodel.*;
import jalview.gui.*;
+import jalview.util.MessageManager;
import jalview.ws.AWsJob;
import jalview.ws.WSClientI;
import jalview.ws.JobStateSummary;
int nseqs = 0;
if (minlen < 0)
{
- throw new Error(
- "Implementation error: minlen must be zero or more.");
+ throw new Error(MessageManager.getString("error.implementation_error_minlen_must_be_greater_zero"));
}
for (int i = 0; i < seqs.length; i++)
{
// boiler plate template
if (!(job instanceof MsaWSJob))
{
- throw new Error("StartJob(MsaWSJob) called on a WSJobInstance "
- + job.getClass());
+ throw new Error(MessageManager.formatMessage("error.implementation_error_msawbjob_called", new String[]{job.getClass().toString()}));
}
MsaWSJob j = (MsaWSJob) job;
if (j.isSubmitted())
{
// special case - selection consisted entirely of empty sequences...
j.setjobStatus(JobStatus.FINISHED);
- j.setStatus("Empty Alignment Job");
+ j.setStatus(MessageManager.getString("label.empty_alignment_job"));
}
try
{
}
else
{
- throw new Exception(
- "Server at "
- + WsUrl
- + " returned null string for job id, it probably cannot be contacted. Try again later ?");
+ throw new Exception(MessageManager.formatMessage("exception.web_service_returned_null_try_later", new String[]{WsUrl}));
}
} catch (compbio.metadata.UnsupportedRuntimeException _lex)
{
lex = _lex;
- wsInfo.appendProgressText("Job could not be run because the server doesn't support this program.\n"
- + _lex.getMessage());
- wsInfo.warnUser(_lex.getMessage(), "Service not supported!");
+ wsInfo.appendProgressText(MessageManager.formatMessage("info.job_couldnt_be_run_server_doesnt_support_program", new String[]{_lex.getMessage()}));
+ wsInfo.warnUser(_lex.getMessage(), MessageManager.getString("warn.service_not_supported"));
wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
wsInfo.setStatus(j.getJobnum(),
WebserviceInfo.STATE_STOPPED_SERVERERROR);
} catch (compbio.metadata.LimitExceededException _lex)
{
lex = _lex;
- wsInfo.appendProgressText("Job could not be run because it exceeded a hard limit on the server.\n"
- + _lex.getMessage());
- wsInfo.warnUser(_lex.getMessage(), "Input is too big!");
+ wsInfo.appendProgressText(MessageManager.formatMessage("info.job_couldnt_be_run_exceeded_hard_limit", new String[]{_lex.getMessage()}));
+ wsInfo.warnUser(_lex.getMessage(), MessageManager.getString("warn.input_is_too_big"));
wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR);
} catch (compbio.metadata.WrongParameterException _lex)
{
lex = _lex;
- wsInfo.warnUser(_lex.getMessage(), "Invalid job parameter set!");
- wsInfo.appendProgressText("Job could not be run because some of the parameter settings are not supported by the server.\n"
- + _lex.getMessage()
- + "\nPlease check to make sure you have used the correct parameter set for this service!\n");
+ wsInfo.warnUser(_lex.getMessage(), MessageManager.getString("warn.invalid_job_param_set"));
+ wsInfo.appendProgressText(MessageManager.formatMessage("info.job_couldnt_be_run_incorrect_param_setting", new String[]{_lex.getMessage()}));
wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR);
} catch (Error e)
j.setAllowedServerExceptions(0);
wsInfo.appendProgressText(j.getJobnum(),
- "Failed to submit sequences for alignment.\n"
- + "Just close the window\n");
+ MessageManager.getString("info.failed_to_submit_sequences_for_alignment"));
}
}
}
public void parseResult()
{
long progbar = System.currentTimeMillis();
- wsInfo.setProgressBar("Collecting job results.", progbar);
+ wsInfo.setProgressBar(MessageManager.getString("status.collecting_job_results"), progbar);
int results = 0; // number of result sets received
JobStateSummary finalState = new JobStateSummary();
try
*/
package jalview.ws.jws2;
+import jalview.util.MessageManager;
+
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashSet;
} catch (Exception e)
{
e.printStackTrace();
- throw new Error(
- "Implementation error: could not copy ValueConstrain!");
+ throw new Error(MessageManager.getString("error.implementation_error_couldnt_copy_value_constraint"));
}
}
} catch (Exception x)
{
x.printStackTrace();
- throw new Error("Implementation error", x);
+ throw new Error(MessageManager.getString("error.implementation_error"), x);
}
alignFrame.getViewport().getCalcManager().registerWorker(worker);
alignFrame.getViewport().getCalcManager().startWorker(worker);
List<WsParamSetI> presets = service.getParamStore().getPresets();
if (presets != null && presets.size() > 0)
{
- JMenu presetlist = new JMenu("Run " + calcName + "with preset");
+ JMenu presetlist = new JMenu(MessageManager.formatMessage("label.run_with_preset", new String[]{calcName}));
for (final WsParamSetI preset : presets)
{
final JMenuItem methodR = new JMenuItem(preset.getName());
- methodR.setToolTipText("<html><p>"
- + JvSwingUtils.wrapTooltip("<strong>"
- + (preset.isModifiable() ? "User Preset"
- : "Service Preset") + "</strong><br/>"
- + preset.getDescription() + "</p>") + "</html>");
+ methodR.setToolTipText(JvSwingUtils.wrapTooltip(true, "<strong>"
+ + (preset.isModifiable() ? MessageManager.getString("label.user_preset")
+ : MessageManager.getString("label.service_preset")) + "</strong><br/>"
+ + preset.getDescription()));
methodR.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
Desktop.instance.showUrl(service.docUrl);
}
});
- annotservice.setToolTipText("<html>"
- + JvSwingUtils.wrapTooltip("View <a href=\""
- + service.docUrl + "\">" + service.docUrl + "</a>")
- + "</html>");
+ annotservice.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.view_service_doc_url", new String[]{service.docUrl,service.docUrl})));
wsmenu.add(annotservice);
}
}
import compbio.metadata.Argument;
import compbio.metadata.Option;
+import jalview.util.MessageManager;
import jalview.ws.jws2.JabaParamStore;
import jalview.ws.jws2.JabaPreset;
import jalview.ws.jws2.ParameterUtils;
return;
}
// Try even harder to migrate arguments.
- throw new Error("Parameter migration not implemented yet");
+ throw new Error(MessageManager.getString("error.parameter_migration_not_implemented_yet"));
}
}
*/
package jalview.ws.jws2.dm;
+import jalview.util.MessageManager;
import jalview.ws.jws2.ParameterUtils;
import jalview.ws.params.OptionI;
} catch (Exception e)
{
e.printStackTrace();
- throw new Error(
- "Implementation error: cannot set Jaba Option to a value outside its allowed value range!");
+ throw new Error(MessageManager.getString("error.implementation_error_cannot_set_jaba_option"));
}
}
import compbio.metadata.ValueConstrain;
+import jalview.util.MessageManager;
import jalview.ws.params.ValueConstrainI;
public class JabaValueConstrain implements ValueConstrainI
{
return ValueType.Integer;
}
- throw new Error(
- "IMPLEMENTATION ERROR: jalview.ws.params.ValueConstrainI.ValueType does not support the JABAWS type :"
- + vc.toString());
+ throw new Error(MessageManager.formatMessage("error.implementation_error_valuetype_doesnt_support_jabaws_type", new String[]{vc.toString()}));
}
@Override
import compbio.metadata.Option;
+import jalview.util.MessageManager;
import jalview.ws.jws2.JabaParamStore;
import jalview.ws.params.ArgumentI;
import jalview.ws.params.WsParamSetI;
{
if (!allJaba(jobParams))
{
- throw new Error(
- "Cannot create a JabaWSParamSet from non-JabaWS parameters");
+ throw new Error(MessageManager.getString("error.cannot_create_jabaws_param_set"));
}
else
{
{
if (!allJaba(args))
{
- throw new Error(
- "Cannot set arguments to a JabaWSParamSet that are not JabaWS arguments");
+ throw new Error(MessageManager.getString("error.cannot_set_arguments_to_jabaws_param_set"));
}
jabaArguments = new ArrayList<Option>();
for (ArgumentI rg : args)
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
+import jalview.util.MessageManager;
import jalview.ws.jws2.JabaParamStore;
import jalview.ws.jws2.MsaWSClient;
import jalview.ws.jws2.SequenceAnnotationWSClient;
{
return ((SequenceAnnotation) service).getRunnerOptions();
}
- throw new Error(
- "Implementation Error: Runner Config not available for a JABAWS service of type "
- + serviceType + " (" + service.getClass() + ")");
+ throw new Error(MessageManager.formatMessage("error.implementation_error_runner_config_not_available", new String[]{serviceType,service.getClass().toString()}));
}
@Override
import jalview.io.packed.ParsePackedSet;
import jalview.io.packed.SimpleDataProvider;
import jalview.io.packed.DataProvider.JvDataType;
+import jalview.util.MessageManager;
import jalview.ws.io.mime.JalviewMimeContentHandler;
import java.io.BufferedReader;
if (en == null)
{
- throw new Error(
- "Implementation Error: need to have an HttpResponse to process.");
+ throw new Error(MessageManager.getString("error.implementation_error_need_to_have_httpresponse"));
}
jalview.io.packed.JalviewDataset ds = restJob.newJalviewDataset();
// Decide how we deal with content.
import jalview.gui.Desktop;
import jalview.gui.WebserviceInfo;
import jalview.io.packed.DataProvider.JvDataType;
+import jalview.util.MessageManager;
import jalview.ws.WSClient;
import jalview.ws.WSClientI;
import jalview.ws.WSMenuEntryProviderI;
public void setWebserviceInfo(boolean headless)
{
- WebServiceJobTitle = service.details.Action + " using "
- + service.details.Name;
+ WebServiceJobTitle = MessageManager.formatMessage("label.webservice_job_title", new String[]{service.details.Action,service.details.Name});
WebServiceName = service.details.Name;
WebServiceReference = "No reference - go to url for more info";
if (service.details.description != null)
final AlignFrame alignFrame)
{
JMenuItem submit = new JMenuItem(service.details.Name);
- submit.setToolTipText(service.details.Action + " using "
- + service.details.Name);
+ submit.setToolTipText(MessageManager.formatMessage("label.rest_client_submit", new String[]{service.details.Action,service.details.Name}));
submit.addActionListener(new ActionListener()
{
_input = new AlignmentView(av.getAlignment(),
av.getColumnSelection(), av.getSelectionGroup(),
av.hasHiddenColumns(), true, true);
- viewTitle = "selected "
- + (av.hasHiddenColumns() ? "visible" : "")
- + " region of " + af.getTitle();
+ viewTitle = MessageManager.formatMessage("label.select_visible_region_of", new String[]{(av.hasHiddenColumns() ? MessageManager.getString("label.visible") : ""),af.getTitle()});
}
else
{
av.getColumnSelection(), av.getSelectionGroup(),
av.hasHiddenColumns(), false, true);
}
- viewTitle = "select and unselected "
- + (av.hasHiddenColumns() ? "visible" : "")
- + " regions from " + af.getTitle();
+ viewTitle = MessageManager.formatMessage("label.select_unselect_visible_regions_from", new String[]{(av.hasHiddenColumns() ? MessageManager.getString("label.visible") : ""),af.getTitle()});
}
else
{
_input = new AlignmentView(av.getAlignment(),
av.getColumnSelection(), av.getSelectionGroup(),
av.hasHiddenColumns(), true, true);
- viewTitle = "selected " + (av.hasHiddenColumns() ? "visible" : "")
- + " region of " + af.getTitle();
+ viewTitle = MessageManager.formatMessage("label.select_visible_region_of", new String[]{(av.hasHiddenColumns() ? MessageManager.getString("label.visible") : ""),af.getTitle()});
}
}
else
_input = new AlignmentView(av.getAlignment(),
av.getColumnSelection(), null, av.hasHiddenColumns(), false,
true);
- viewTitle = "" + (av.hasHiddenColumns() ? "visible region of " : "")
+ viewTitle = "" + (av.hasHiddenColumns() ? (new StringBuffer(" ").append(MessageManager.getString("label.visible_region_of")).toString()) : "")
+ af.getTitle();
}
.showMessageDialog(
Desktop.desktop,
(jobsthread.hasWarnings() ? jobsthread.getWarnings()
- : "The Job couldn't be started. Please check your input, and the Jalview console for any warning messages."),
- "Unable to start web service analysis",
+ : MessageManager.getString("label.job_couldnt_be_started_check_input")),
+ MessageManager.getString("label.unable_start_web_service_analysis"),
JOptionPane.WARNING_MESSAGE);
}
}
public static RestClient makeShmmrRestClient()
{
- String action = "Analysis", description = "Sequence Harmony and Multi-Relief (Brandt et al. 2010)", name = "Multi-Harmony";
+ String action = "Analysis", description = "Sequence Harmony and Multi-Relief (Brandt et al. 2010)", name = MessageManager.getString("label.multiharmony");
Hashtable<String, InputType> iparams = new Hashtable<String, InputType>();
jalview.ws.rest.params.JobConstant toolp;
// toolp = new jalview.ws.rest.JobConstant("tool","jalview");
import jalview.io.NewickFile;
import jalview.io.packed.JalviewDataset;
import jalview.io.packed.JalviewDataset.AlignmentSet;
+import jalview.util.MessageManager;
import jalview.ws.AWSThread;
import jalview.ws.AWsJob;
destAls.add(destAl);
destColsel.add(destCs);
resultDest.add(AddDataTo.newAlignment);
- throw new Error("Impl. Error! TODO: ");
+ throw new Error(MessageManager.getString("error.implementation_error")+"TODO: ");
}
}
/**
{
AlignmentI destal;
ColumnSelection destcs;
- String alTitle = restClient.service.details.Action + " using "
- + restClient.service.details.Name + " on "
- + restClient.viewTitle;
+ String alTitle = MessageManager.formatMessage("label.webservice_job_title_on", new String[]{restClient.service.details.Action,restClient.service.details.Name,restClient.viewTitle});
switch (action)
{
case newAlignment:
*/
package jalview.ws.rest.params;
+import jalview.util.MessageManager;
import jalview.ws.params.OptionI;
import jalview.ws.rest.InputType;
import jalview.ws.rest.NoValidInputDataException;
prm.add(URLEncoder.encode(value, "UTF-8"));
} catch (UnsupportedEncodingException ex)
{
- throw new Error("Couldn't encode '" + value + "' as UTF-8.", ex);
+ throw new Error(MessageManager.formatMessage("error.couldnt_encode_as_utf8", new String[]{value}), ex);
}
}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
import jalview.ws.params.OptionI;
import jalview.ws.params.simple.IntegerParameter;
import jalview.ws.params.simple.Option;
{
if (sg.getSize() < minsize)
{
- throw new NoValidInputDataException("Group contains less than "
- + minsize + " sequences.");
+ throw new NoValidInputDataException(MessageManager.formatMessage("exception.notvaliddata_group_contains_less_than_min_seqs", new String[]{Integer.valueOf(minsize).toString()}));
}
// TODO: refactor to sequenceGroup for efficiency -
// getAlignmentRowInterval(AlignmentI al)
*/
package jalview.ws.rest.params;
+import jalview.util.MessageManager;
import jalview.ws.params.OptionI;
import jalview.ws.rest.InputType;
import jalview.ws.rest.RestJob;
/*
* rj.getTreeForInput(token); return new StringBody(new )
*/
- throw new Error("Tree InputType not yet implemented");
+ throw new Error(MessageManager.getString("error.tree_inputtype_not_yet_implemented"));
// return null;
}
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.SequenceI;
import jalview.util.DBRefUtils;
+import jalview.util.MessageManager;
import java.util.ArrayList;
import java.util.Enumeration;
} catch (Exception e)
{
// Serious problems if this happens.
- throw new Error("DBRefSource Implementation Exception", e);
+ throw new Error(MessageManager.getString("error.dbrefsource_implementation_exception"), e);
}
addDbRefSourceImpl(proxy);
}
{
if (!jalview.ws.seqfetcher.DbSourceProxy.class.isAssignableFrom(class1))
{
- throw new Error(
- "Implmentation Error - getDbInstances must be given a class that implements jalview.ws.seqfetcher.DbSourceProxy (was given '"
- + class1 + "')");
+ throw new Error(MessageManager.formatMessage("error.implementation_error_dbinstance_must_implement_interface", new String[]{class1.toString()}));
}
if (FETCHABLEDBS == null)
{
*/
package org.jibble.epsgraphics;
+import jalview.util.MessageManager;
+
import java.io.*;
import java.util.*;
_bufferedWriter.write(line + "\n");
} catch (IOException e)
{
- throw new EpsException("Could not write to the output file: " + e);
+ throw new EpsException(MessageManager.formatMessage("exception.eps_coudnt_write_output_file", new String[]{e.getMessage()}));
}
}
*/
package org.jibble.epsgraphics;
+import jalview.util.MessageManager;
+
import java.io.*;
import java.text.*;
import java.util.*;
*/
private void methodNotSupported()
{
- EpsException e = new EpsException(
- "Method not currently supported by EpsGraphics2D version "
- + VERSION);
+ EpsException e = new EpsException(MessageManager.formatMessage("exception.eps_method_not_supported", new String[]{VERSION}));
e.printStackTrace(System.err);
}
return t.createTransformedShape(_clip);
} catch (Exception e)
{
- throw new EpsException("Unable to get inverse of matrix: "
- + _transform);
+ throw new EpsException(MessageManager.formatMessage("exception.eps_unable_to_get_inverse_matrix", new String[]{_transform.toString()}));
}
}
}
matrix = matrix.createInverse();
} catch (Exception e)
{
- throw new EpsException("Unable to get inverse of matrix: " + matrix);
+ throw new EpsException(MessageManager.formatMessage("exception.eps_unable_to_get_inverse_matrix", new String[]{matrix.toString()}));
}
matrix.scale(1, -1);
matrix.getMatrix(m);
*/
package uk.ac.ebi.www;
+import jalview.util.MessageManager;
+
public class WSWUBlastServiceLocator extends org.apache.axis.client.Service
implements uk.ac.ebi.www.WSWUBlastService
{
{
throw new javax.xml.rpc.ServiceException(t);
}
- throw new javax.xml.rpc.ServiceException(
- "There is no stub implementation for the interface: "
- + (serviceEndpointInterface == null ? "null"
- : serviceEndpointInterface.getName()));
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.no_stub_implementation_for_interface", new String[]{(serviceEndpointInterface == null ? "null": serviceEndpointInterface.getName())}));
}
/**
*/
package uk.ac.ebi.www.picr.AccessionMappingService;
+import jalview.util.MessageManager;
+
public class AccessionMapperServiceLocator extends
org.apache.axis.client.Service implements
uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperService
{
throw new javax.xml.rpc.ServiceException(t);
}
- throw new javax.xml.rpc.ServiceException(
- "There is no stub implementation for the interface: "
- + (serviceEndpointInterface == null ? "null"
- : serviceEndpointInterface.getName()));
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.no_stub_implementation_for_interface", new String[]{(serviceEndpointInterface == null ? "null": serviceEndpointInterface.getName())}));
}
/**
}
else
{ // Unknown Port Name
- throw new javax.xml.rpc.ServiceException(
- " Cannot set Endpoint Address for Unknown Port" + portName);
+ throw new javax.xml.rpc.ServiceException(MessageManager.formatMessage("exception.cannot_set_endpoint_address_unknown_port", new String[]{portName}));
}
}
--- /dev/null
+package jalview.analysis;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.io.AppletFormatAdapter;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class AlignmentAnnotationUtilsTest
+{
+ // 4 sequences x 13 positions
+ final static String EOL = "\n";
+
+ // @formatter:off
+ final static String TEST_DATA =
+ ">FER_CAPAA Ferredoxin" + EOL +
+ "TIETHKEAELVG-" + EOL +
+ ">FER_CAPAN Ferredoxin, chloroplast precursor" + EOL +
+ "TIETHKEAELVG-" + EOL +
+ ">FER1_SOLLC Ferredoxin-1, chloroplast precursor" + EOL +
+ "TIETHKEEELTA-" + EOL +
+ ">Q93XJ9_SOLTU Ferredoxin I precursor" + EOL +
+ "TIETHKEEELTA-" + EOL;
+ // @formatter:on
+
+ private static final int SEQ_ANN_COUNT = 12;
+
+ private AlignmentI alignment;
+
+ /**
+ * Test method that converts a (possibly null) array to a list.
+ */
+ @Test
+ public void testAsList()
+ {
+ // null array
+ Collection<AlignmentAnnotation> c1 = AlignmentAnnotationUtils
+ .asList(null);
+ assertTrue(c1.isEmpty());
+
+ // empty array
+ AlignmentAnnotation[] anns = new AlignmentAnnotation[0];
+ c1 = AlignmentAnnotationUtils.asList(anns);
+ assertTrue(c1.isEmpty());
+
+ // non-empty array
+ anns = new AlignmentAnnotation[2];
+ anns[0] = new AlignmentAnnotation("label0", "desc0", 0.0f);
+ anns[1] = new AlignmentAnnotation("label1", "desc1", 1.0f);
+ c1 = AlignmentAnnotationUtils.asList(anns);
+ assertEquals(2, c1.size());
+ assertTrue(c1.contains(anns[0]));
+ assertTrue(c1.contains(anns[1]));
+ }
+
+ /**
+ * This output is not part of the test but may help make sense of it...
+ *
+ * @param shownTypes
+ * @param hiddenTypes
+ */
+ protected void consoleDebug(Map<String, List<List<String>>> shownTypes,
+ Map<String, List<List<String>>> hiddenTypes)
+ {
+ for (String calcId : shownTypes.keySet())
+ {
+ System.out.println("Visible annotation types for calcId=" + calcId);
+ for (List<String> type : shownTypes.get(calcId))
+ {
+ System.out.println(" " + type);
+ }
+ }
+ for (String calcId : hiddenTypes.keySet())
+ {
+ System.out.println("Hidden annotation types for calcId=" + calcId);
+ for (List<String> type : hiddenTypes.get(calcId))
+ {
+ System.out.println(" " + type);
+ }
+ }
+ }
+
+ /**
+ * Add a sequence group to the alignment with the specified sequences (base 0)
+ * in it
+ *
+ * @param i
+ * @param more
+ */
+ private List<SequenceI> selectSequences(int... selected)
+ {
+ List<SequenceI> result = new ArrayList<SequenceI>();
+ SequenceI[] seqs = alignment.getSequencesArray();
+ for (int i : selected)
+ {
+ result.add(seqs[i]);
+ }
+ return result;
+ }
+
+ @Before
+ public void setUp() throws IOException
+ {
+ alignment = new jalview.io.FormatAdapter().readFile(TEST_DATA,
+ AppletFormatAdapter.PASTE, "FASTA");
+
+ AlignmentAnnotation[] anns = new AlignmentAnnotation[SEQ_ANN_COUNT];
+ for (int i = 0; i < anns.length; i++)
+ {
+ anns[i] = new AlignmentAnnotation("Label" + i, null, 0d);
+ anns[i].setCalcId("CalcId" + i);
+ anns[i].visible = true;
+ alignment.addAnnotation(anns[i]);
+ }
+ }
+
+ /**
+ * Test a mixture of show/hidden annotations in/outside selection group.
+ */
+ @Test
+ public void testGetShownHiddenTypes_forSelectionGroup()
+ {
+ Map<String, List<List<String>>> shownTypes = new HashMap<String, List<List<String>>>();
+ Map<String, List<List<String>>> hiddenTypes = new HashMap<String, List<List<String>>>();
+ AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
+ SequenceI[] seqs = alignment.getSequencesArray();
+
+ /*
+ * Configure annotation properties for test
+ */
+ // not in selection group (should be ignored):
+ // hidden annotation Label4 not in selection group
+ anns[4].sequenceRef = seqs[2];
+ anns[4].visible = false;
+ anns[7].sequenceRef = seqs[1];
+ anns[7].visible = true;
+
+ /*
+ * in selection group, hidden:
+ */
+ anns[2].sequenceRef = seqs[3]; // CalcId2/Label2
+ anns[2].visible = false;
+ anns[3].sequenceRef = seqs[3]; // CalcId3/Label2
+ anns[3].visible = false;
+ anns[3].label = "Label2";
+ anns[4].sequenceRef = seqs[3]; // CalcId2/Label3
+ anns[4].visible = false;
+ anns[4].label = "Label3";
+ anns[4].setCalcId("CalcId2");
+ anns[8].sequenceRef = seqs[0]; // CalcId9/Label9
+ anns[8].visible = false;
+ anns[8].label = "Label9";
+ anns[8].setCalcId("CalcId9");
+ /*
+ * in selection group, visible
+ */
+ anns[6].sequenceRef = seqs[0]; // CalcId6/Label6
+ anns[6].visible = true;
+ anns[9].sequenceRef = seqs[3]; // CalcId9/Label9
+ anns[9].visible = true;
+
+ List<SequenceI> selected = selectSequences(0, 3);
+ AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
+ AlignmentAnnotationUtils.asList(anns),
+ selected);
+
+ // check results; note CalcId9/Label9 is both hidden and shown (for
+ // different sequences) so should be in both
+ // shown: CalcId6/Label6 and CalcId9/Label9
+ assertEquals(2, shownTypes.size());
+ assertEquals(1, shownTypes.get("CalcId6").size());
+ assertEquals(1, shownTypes.get("CalcId6").get(0).size());
+ assertEquals("Label6", shownTypes.get("CalcId6").get(0).get(0));
+ assertEquals(1, shownTypes.get("CalcId9").size());
+ assertEquals(1, shownTypes.get("CalcId9").get(0).size());
+ assertEquals("Label9", shownTypes.get("CalcId9").get(0).get(0));
+
+ // hidden: CalcId2/Label2, CalcId2/Label3, CalcId3/Label2, CalcId9/Label9
+ assertEquals(3, hiddenTypes.size());
+ assertEquals(2, hiddenTypes.get("CalcId2").size());
+ assertEquals(1, hiddenTypes.get("CalcId2").get(0).size());
+ assertEquals("Label2", hiddenTypes.get("CalcId2").get(0).get(0));
+ assertEquals(1, hiddenTypes.get("CalcId2").get(1).size());
+ assertEquals("Label3", hiddenTypes.get("CalcId2").get(1).get(0));
+ assertEquals(1, hiddenTypes.get("CalcId3").size());
+ assertEquals(1, hiddenTypes.get("CalcId3").get(0).size());
+ assertEquals("Label2", hiddenTypes.get("CalcId3").get(0).get(0));
+ assertEquals(1, hiddenTypes.get("CalcId9").size());
+ assertEquals(1, hiddenTypes.get("CalcId9").get(0).size());
+ assertEquals("Label9", hiddenTypes.get("CalcId9").get(0).get(0));
+
+ consoleDebug(shownTypes, hiddenTypes);
+ }
+
+ /**
+ * Test case where there are 'grouped' annotations, visible and hidden, within
+ * and without the selection group.
+ */
+ @Test
+ public void testGetShownHiddenTypes_withGraphGroups()
+ {
+ final int GROUP_3 = 3;
+ final int GROUP_4 = 4;
+ final int GROUP_5 = 5;
+ final int GROUP_6 = 6;
+
+ Map<String, List<List<String>>> shownTypes = new HashMap<String, List<List<String>>>();
+ Map<String, List<List<String>>> hiddenTypes = new HashMap<String, List<List<String>>>();
+ AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
+ SequenceI[] seqs = alignment.getSequencesArray();
+
+ /*
+ * Annotations for selection group and graph group
+ *
+ * Hidden annotations Label2, Label3, in (hidden) group 5
+ */
+ anns[2].sequenceRef = seqs[3];
+ anns[2].visible = false;
+ anns[2].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[2].graphGroup = GROUP_5; // not a visible group
+ anns[3].sequenceRef = seqs[0];
+ anns[3].visible = false;
+ anns[3].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[3].graphGroup = GROUP_5;
+ // need to ensure annotations have the same calcId as well
+ anns[3].setCalcId("CalcId2");
+ // annotations for a different hidden group generating the same group label
+ anns[10].sequenceRef = seqs[0];
+ anns[10].visible = false;
+ anns[10].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[10].graphGroup = GROUP_3;
+ anns[10].label = "Label3";
+ anns[10].setCalcId("CalcId2");
+ anns[11].sequenceRef = seqs[3];
+ anns[11].visible = false;
+ anns[11].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[11].graphGroup = GROUP_3;
+ anns[11].label = "Label2";
+ anns[11].setCalcId("CalcId2");
+
+ // annotations Label1 (hidden), Label5 (visible) in group 6 (visible)
+ anns[1].sequenceRef = seqs[3];
+ // being in a visible group should take precedence over this visibility
+ anns[1].visible = false;
+ anns[1].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[1].graphGroup = GROUP_6;
+ anns[5].sequenceRef = seqs[0];
+ anns[5].visible = true;
+ anns[5].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[5].graphGroup = GROUP_6;
+ anns[5].setCalcId("CalcId1");
+ /*
+ * Annotations 0 and 4 are visible, for a different CalcId and graph group.
+ * They produce the same label as annotations 1 and 5, which should not be
+ * duplicated in the results. This case corresponds to (e.g.) many
+ * occurrences of an IUPred Short/Long annotation group, one per sequence.
+ */
+ anns[4].sequenceRef = seqs[0];
+ anns[4].visible = false;
+ anns[4].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[4].graphGroup = GROUP_4;
+ anns[4].label = "Label1";
+ anns[4].setCalcId("CalcId1");
+ anns[0].sequenceRef = seqs[0];
+ anns[0].visible = true;
+ anns[0].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[0].graphGroup = GROUP_4;
+ anns[0].label = "Label5";
+ anns[0].setCalcId("CalcId1");
+
+ /*
+ * Annotations outwith selection group - should be ignored.
+ */
+ // Hidden grouped annotations
+ anns[6].sequenceRef = seqs[2];
+ anns[6].visible = false;
+ anns[6].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[6].graphGroup = GROUP_4;
+ anns[8].sequenceRef = seqs[1];
+ anns[8].visible = false;
+ anns[8].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[8].graphGroup = GROUP_4;
+
+ // visible grouped annotations Label7, Label9
+ anns[7].sequenceRef = seqs[2];
+ anns[7].visible = true;
+ anns[7].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[7].graphGroup = GROUP_4;
+ anns[9].sequenceRef = seqs[1];
+ anns[9].visible = true;
+ anns[9].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[9].graphGroup = GROUP_4;
+
+ List<SequenceI> selected = selectSequences(0, 3);
+ AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
+ AlignmentAnnotationUtils.asList(anns),
+ selected);
+
+ consoleDebug(shownTypes, hiddenTypes);
+
+ // CalcId1 / Label1, Label5 (only) should be 'shown', once, as a compound
+ // type
+ assertEquals(1, shownTypes.size());
+ assertEquals(1, shownTypes.get("CalcId1").size());
+ assertEquals(2, shownTypes.get("CalcId1").get(0).size());
+ assertEquals("Label1", shownTypes.get("CalcId1").get(0).get(0));
+ assertEquals("Label5", shownTypes.get("CalcId1").get(0).get(1));
+
+ // CalcId2 / Label2, Label3 (only) should be 'hidden'
+ assertEquals(1, hiddenTypes.size());
+ assertEquals(1, hiddenTypes.get("CalcId2").size());
+ assertEquals(2, hiddenTypes.get("CalcId2").get(0).size());
+ assertEquals("Label2", hiddenTypes.get("CalcId2").get(0).get(0));
+ assertEquals("Label3", hiddenTypes.get("CalcId2").get(0).get(1));
+ }
+
+ /**
+ * Test method that determines visible graph groups.
+ */
+ @Test
+ public void testGetVisibleGraphGroups()
+ {
+ AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
+ /*
+ * a bar graph group is not included
+ */
+ anns[0].graph = AlignmentAnnotation.BAR_GRAPH;
+ anns[0].graphGroup = 1;
+ anns[0].visible = true;
+
+ /*
+ * a line graph group is included as long as one of its members is visible
+ */
+ anns[1].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[1].graphGroup = 5;
+ anns[1].visible = false;
+ anns[2].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[2].graphGroup = 5;
+ anns[2].visible = true;
+
+ /*
+ * a line graph group with no visible rows is not included
+ */
+ anns[3].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[3].graphGroup = 3;
+ anns[3].visible = false;
+
+ // a visible line graph with no graph group is not included
+ anns[4].graph = AlignmentAnnotation.LINE_GRAPH;
+ anns[4].graphGroup = -1;
+ anns[4].visible = true;
+
+ BitSet result = AlignmentAnnotationUtils
+ .getVisibleLineGraphGroups(AlignmentAnnotationUtils
+ .asList(anns));
+ assertTrue(result.get(5));
+ assertFalse(result.get(0));
+ assertFalse(result.get(1));
+ assertFalse(result.get(2));
+ assertFalse(result.get(3));
+ }
+
+ /**
+ * Test for case where no sequence is selected. Shouldn't normally arise but
+ * check it handles it gracefully.
+ */
+ @Test
+ public void testGetShownHiddenTypes_noSequenceSelected()
+ {
+ Map<String, List<List<String>>> shownTypes = new HashMap<String, List<List<String>>>();
+ Map<String, List<List<String>>> hiddenTypes = new HashMap<String, List<List<String>>>();
+ AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
+ // selected sequences null
+ AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
+ AlignmentAnnotationUtils.asList(anns), null);
+ assertTrue(shownTypes.isEmpty());
+ assertTrue(hiddenTypes.isEmpty());
+
+ List<SequenceI> sequences = new ArrayList<SequenceI>();
+ // selected sequences empty list
+ AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
+ AlignmentAnnotationUtils.asList(anns), sequences);
+ assertTrue(shownTypes.isEmpty());
+ assertTrue(hiddenTypes.isEmpty());
+ }
+}
--- /dev/null
+package jalview.analysis;
+
+import static org.junit.Assert.assertEquals;
+import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class AnnotationSorterTest
+{
+ private static final int NUM_SEQS = 6;
+
+ private static final int NUM_ANNS = 7;
+
+ private static final String SS = "secondary structure";
+
+ AlignmentAnnotation[] anns = new AlignmentAnnotation[0];
+
+ Alignment al = null;
+
+ /*
+ * Set up 6 sequences and 7 annotations.
+ */
+ @Before
+ public void setUp()
+ {
+ al = buildAlignment(NUM_SEQS);
+ anns = buildAnnotations(NUM_ANNS);
+ }
+
+ /**
+ * Construct an array of numAnns annotations
+ *
+ * @param numAnns
+ *
+ * @return
+ */
+ protected AlignmentAnnotation[] buildAnnotations(int numAnns)
+ {
+ List<AlignmentAnnotation> annlist = new ArrayList<AlignmentAnnotation>();
+ for (int i = 0; i < numAnns; i++)
+ {
+ AlignmentAnnotation ann = new AlignmentAnnotation(SS + i, "", 0);
+ annlist.add(ann);
+ }
+ return annlist.toArray(anns);
+ }
+
+ /**
+ * Make an alignment with numSeqs sequences in it.
+ *
+ * @param numSeqs
+ *
+ * @return
+ */
+ private Alignment buildAlignment(int numSeqs)
+ {
+ SequenceI[] seqs = new Sequence[numSeqs];
+ for (int i = 0; i < numSeqs; i++)
+ {
+ seqs[i] = new Sequence("Sequence" + i, "axrdkfp");
+ }
+ return new Alignment(seqs);
+ }
+
+ /**
+ * Test sorting by annotation type (label) within sequence order, including
+ * <ul>
+ * <li>annotations with no sequence reference - sort to end keeping mutual
+ * ordering</li>
+ * <li>annotations with sequence ref = sort in sequence order</li>
+ * <li>multiple annotations for same sequence ref - sort by label
+ * non-case-specific</li>
+ * <li>annotations with reference to sequence not in alignment - treat like no
+ * sequence ref</li>
+ * </ul>
+ */
+ @Test
+ public void testSortBySequenceAndType_autocalcLast()
+ {
+ // @formatter:off
+ anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
+ anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
+ anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
+ anns[3].sequenceRef = null; anns[3].label = "Quality";
+ anns[4].sequenceRef = null; anns[4].label = "Consensus";
+ anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "label5";
+ anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
+ // @formatter:on
+
+ AnnotationSorter testee = new AnnotationSorter(al, false);
+ testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ assertEquals("label5", anns[0].label); // for sequence 0
+ assertEquals("label0", anns[1].label); // for sequence 1
+ assertEquals("iron", anns[2].label); // sequence 3 /iron
+ assertEquals("IRP", anns[3].label); // sequence 3/IRP
+ assertEquals("structure", anns[4].label); // sequence 3/structure
+ assertEquals("Quality", anns[5].label); // non-sequence annotations
+ assertEquals("Consensus", anns[6].label); // retain ordering
+ }
+
+ /**
+ * Variant with autocalculated annotations sorting to front
+ */
+ @Test
+ public void testSortBySequenceAndType_autocalcFirst()
+ {
+ // @formatter:off
+ anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
+ anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
+ anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
+ anns[3].sequenceRef = null; anns[3].label = "Quality";
+ anns[4].sequenceRef = null; anns[4].label = "Consensus";
+ anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "label5";
+ anns[6].sequenceRef = al.getSequenceAt(3); anns[6].label = "IRP";
+ // @formatter:on
+
+ AnnotationSorter testee = new AnnotationSorter(al, true);
+ testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ assertEquals("Quality", anns[0].label); // non-sequence annotations
+ assertEquals("Consensus", anns[1].label); // retain ordering
+ assertEquals("label5", anns[2].label); // for sequence 0
+ assertEquals("label0", anns[3].label); // for sequence 1
+ assertEquals("iron", anns[4].label); // sequence 3 /iron
+ assertEquals("IRP", anns[5].label); // sequence 3/IRP
+ assertEquals("structure", anns[6].label); // sequence 3/structure
+ }
+
+ /**
+ * Test sorting by annotation type (label) within sequence order, including
+ * <ul>
+ * <li>annotations with no sequence reference - sort to end keeping mutual
+ * ordering</li>
+ * <li>annotations with sequence ref = sort in sequence order</li>
+ * <li>multiple annotations for same sequence ref - sort by label
+ * non-case-specific</li>
+ * <li>annotations with reference to sequence not in alignment - treat like no
+ * sequence ref</li>
+ * </ul>
+ */
+ @Test
+ public void testSortByTypeAndSequence_autocalcLast()
+ {
+ // @formatter:off
+ anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
+ anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
+ anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
+ anns[3].sequenceRef = null; anns[3].label = "Quality";
+ anns[4].sequenceRef = null; anns[4].label = "Consensus";
+ anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "IRON";
+ anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
+ // @formatter:on
+
+ AnnotationSorter testee = new AnnotationSorter(al, false);
+ testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ assertEquals("IRON", anns[0].label); // IRON / sequence 0
+ assertEquals("iron", anns[1].label); // iron / sequence 3
+ assertEquals("label0", anns[2].label); // label0 / sequence 1
+ assertEquals("Structure", anns[3].label); // Structure / sequence 2
+ assertEquals("structure", anns[4].label); // structure / sequence 3
+ assertEquals("Quality", anns[5].label); // non-sequence annotations
+ assertEquals("Consensus", anns[6].label); // retain ordering
+ }
+
+ /**
+ * Variant of test with autocalculated annotations sorted to front
+ */
+ @Test
+ public void testSortByTypeAndSequence_autocalcFirst()
+ {
+ // @formatter:off
+ anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
+ anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
+ anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
+ anns[3].sequenceRef = null; anns[3].label = "Quality";
+ anns[4].sequenceRef = null; anns[4].label = "Consensus";
+ anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "IRON";
+ anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
+ // @formatter:on
+
+ AnnotationSorter testee = new AnnotationSorter(al, true);
+ testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ assertEquals("Quality", anns[0].label); // non-sequence annotations
+ assertEquals("Consensus", anns[1].label); // retain ordering
+ assertEquals("IRON", anns[2].label); // IRON / sequence 0
+ assertEquals("iron", anns[3].label); // iron / sequence 3
+ assertEquals("label0", anns[4].label); // label0 / sequence 1
+ assertEquals("Structure", anns[5].label); // Structure / sequence 2
+ assertEquals("structure", anns[6].label); // structure / sequence 3
+ }
+
+ /**
+ * Variant of test with autocalculated annotations sorted to front but
+ * otherwise no change.
+ */
+ @Test
+ public void testNoSort_autocalcFirst()
+ {
+ // @formatter:off
+ anns[0].sequenceRef = al.getSequenceAt(1); anns[0].label = "label0";
+ anns[1].sequenceRef = al.getSequenceAt(3); anns[1].label = "structure";
+ anns[2].sequenceRef = al.getSequenceAt(3); anns[2].label = "iron";
+ anns[3].sequenceRef = null; anns[3].label = "Quality";
+ anns[4].sequenceRef = null; anns[4].label = "Consensus";
+ anns[5].sequenceRef = al.getSequenceAt(0); anns[5].label = "IRON";
+ anns[6].sequenceRef = al.getSequenceAt(2); anns[6].label = "Structure";
+ // @formatter:on
+
+ AnnotationSorter testee = new AnnotationSorter(al, true);
+ testee.sort(anns, SequenceAnnotationOrder.NONE);
+ assertEquals("Quality", anns[0].label); // non-sequence annotations
+ assertEquals("Consensus", anns[1].label); // retain ordering
+ assertEquals("label0", anns[2].label);
+ assertEquals("structure", anns[3].label);
+ assertEquals("iron", anns[4].label);
+ assertEquals("IRON", anns[5].label);
+ assertEquals("Structure", anns[6].label);
+ }
+
+ @Test
+ public void testSort_timingPresorted()
+ {
+ testTiming_presorted(50, 100);
+ testTiming_presorted(500, 1000);
+ testTiming_presorted(5000, 10000);
+ }
+
+ /**
+ * Test timing to sort annotations already in the sort order.
+ *
+ * @param numSeqs
+ * @param numAnns
+ */
+ private void testTiming_presorted(final int numSeqs, final int numAnns)
+ {
+ al = buildAlignment(numSeqs);
+ anns = buildAnnotations(numAnns);
+
+ /*
+ * Set the annotations presorted by label
+ */
+ Random r = new Random();
+ final SequenceI[] sequences = al.getSequencesArray();
+ for (int i = 0; i < anns.length; i++)
+ {
+ SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
+ anns[i].sequenceRef = randomSequenceRef;
+ anns[i].label = "label" + i;
+ }
+ long startTime = System.currentTimeMillis();
+ AnnotationSorter testee = new AnnotationSorter(al, false);
+ testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ long endTime = System.currentTimeMillis();
+ final long elapsed = endTime - startTime;
+ System.out.println("Timing test for presorted " + numSeqs
+ + " sequences and "
+ + numAnns + " annotations took " + elapsed + "ms");
+ }
+
+ /**
+ * Timing tests for sorting randomly sorted annotations for various sizes.
+ */
+ @Test
+ public void testSort_timingUnsorted()
+ {
+ testTiming_unsorted(50, 100);
+ testTiming_unsorted(500, 1000);
+ testTiming_unsorted(5000, 10000);
+ }
+
+ /**
+ * Generate annotations randomly sorted with respect to sequences, and time
+ * sorting.
+ *
+ * @param numSeqs
+ * @param numAnns
+ */
+ private void testTiming_unsorted(final int numSeqs, final int numAnns)
+ {
+ al = buildAlignment(numSeqs);
+ anns = buildAnnotations(numAnns);
+
+ /*
+ * Set the annotations in random order with respect to the sequences
+ */
+ Random r = new Random();
+ final SequenceI[] sequences = al.getSequencesArray();
+ for (int i = 0; i < anns.length; i++)
+ {
+ SequenceI randomSequenceRef = sequences[r.nextInt(sequences.length)];
+ anns[i].sequenceRef = randomSequenceRef;
+ anns[i].label = "label" + i;
+ }
+ long startTime = System.currentTimeMillis();
+ AnnotationSorter testee = new AnnotationSorter(al, false);
+ testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ long endTime = System.currentTimeMillis();
+ final long elapsed = endTime - startTime;
+ System.out.println("Timing test for unsorted " + numSeqs
+ + " sequences and "
+ + numAnns + " annotations took " + elapsed + "ms");
+ }
+
+ /**
+ * Timing test for sorting annotations with a limited range of types (labels).
+ */
+ @Test
+ public void testSort_timingSemisorted()
+ {
+ testTiming_semiSorted(50, 100);
+ testTiming_semiSorted(500, 1000);
+ testTiming_semiSorted(5000, 10000);
+ }
+
+ /**
+ * Mimic 'semi-sorted' annotations:
+ * <ul>
+ * <li>set up in sequence order, with randomly assigned labels from a limited
+ * range</li>
+ * <li>sort by label and sequence order, report timing</li>
+ * <li>resort by sequence and label, report timing</li>
+ * <li>resort by label and sequence, report timing</li>
+ * </ul>
+ *
+ * @param numSeqs
+ * @param numAnns
+ */
+ private void testTiming_semiSorted(final int numSeqs, final int numAnns)
+ {
+ al = buildAlignment(numSeqs);
+ anns = buildAnnotations(numAnns);
+
+ String[] labels = new String[]
+ { "label1", "label2", "label3", "label4", "label5", "label6" };
+
+ /*
+ * Set the annotations in sequence order with randomly assigned labels.
+ */
+ Random r = new Random();
+ final SequenceI[] sequences = al.getSequencesArray();
+ for (int i = 0; i < anns.length; i++)
+ {
+ SequenceI sequenceRef = sequences[i % sequences.length];
+ anns[i].sequenceRef = sequenceRef;
+ anns[i].label = labels[r.nextInt(labels.length)];
+ }
+ long startTime = System.currentTimeMillis();
+ AnnotationSorter testee = new AnnotationSorter(al, false);
+ testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ long endTime = System.currentTimeMillis();
+ long elapsed = endTime - startTime;
+ System.out.println("Sort by label for semisorted " + numSeqs
+ + " sequences and "
+ + numAnns + " annotations took " + elapsed + "ms");
+
+ // now resort by sequence
+ startTime = System.currentTimeMillis();
+ testee.sort(anns, SequenceAnnotationOrder.SEQUENCE_AND_LABEL);
+ endTime = System.currentTimeMillis();
+ elapsed = endTime - startTime;
+ System.out.println("Resort by sequence for semisorted " + numSeqs
+ + " sequences and " + numAnns + " annotations took " + elapsed
+ + "ms");
+
+ // now resort by label
+ startTime = System.currentTimeMillis();
+ testee.sort(anns, SequenceAnnotationOrder.LABEL_AND_SEQUENCE);
+ endTime = System.currentTimeMillis();
+ elapsed = endTime - startTime;
+ System.out.println("Resort by label for semisorted " + numSeqs
+ + " sequences and " + numAnns + " annotations took " + elapsed
+ + "ms");
+ }
+}
--- /dev/null
+package jalview.datamodel;
+
+import static org.junit.Assert.assertEquals;
+import jalview.analysis.AlignSeq;
+import jalview.io.AppletFormatAdapter;
+
+import org.junit.Test;
+
+public class AlignmentAnnotationTests
+{
+ @Test
+ public void testCopyConstructor()
+ {
+ SequenceI sq = new Sequence("Foo", "ARAARARARAWEAWEAWRAWEAWE");
+ createAnnotation(sq);
+ AlignmentAnnotation alc, alo = sq.getAnnotation()[0];
+ alc = new AlignmentAnnotation(alo);
+ for (String key : alo.getProperties())
+ {
+ assertEquals("Property mismatch", alo.getProperty(key),
+ alc.getProperty(key));
+ }
+ }
+ /**
+ * create some dummy annotation derived from the sequence
+ *
+ * @param sq
+ */
+ public static void createAnnotation(SequenceI sq)
+ {
+ Annotation[] al = new Annotation[sq.getLength()];
+ for (int i = 0; i < al.length; i++)
+ {
+ al[i] = new Annotation(new Annotation("" + sq.getCharAt(i), "",
+ (char) 0, sq.findPosition(i)));
+ }
+ AlignmentAnnotation alan = new AlignmentAnnotation("For "
+ + sq.getName(), "Fake alignment annot", al);
+ // create a sequence mapping for the annotation vector in its current state
+ alan.createSequenceMapping(sq, sq.getStart(), false);
+ alan.setProperty("CreatedBy", "createAnnotation");
+ sq.addAlignmentAnnotation(alan);
+ }
+
+ /**
+ * use this to test annotation derived from method above as it is transferred
+ * across different sequences derived from same dataset coordinate frame
+ *
+ * @param ala
+ */
+ public static void testAnnotTransfer(AlignmentAnnotation ala)
+ {
+ assertEquals(
+ "Failed - need annotation created by createAnnotation method",
+ ala.description, "Fake alignment annot");
+ ala.adjustForAlignment();
+ for (int p = 0; p < ala.annotations.length; p++)
+ {
+ if (ala.annotations[p] != null)
+ {
+ assertEquals("Mismatch at position " + p
+ + " between annotation position value and sequence"
+ + ala.annotations[p], (int) ala.annotations[p].value,
+ ala.sequenceRef.findPosition(p));
+ }
+ }
+ }
+
+ /**
+ * Tests the liftOver method and also exercises the functions for remapping
+ * annotation across different reference sequences. Here, the test is between
+ * different dataset frames (annotation transferred by mapping between
+ * sequences)
+ */
+ @Test
+ public void testLiftOver()
+ {
+ SequenceI sqFrom = new Sequence("fromLong", "QQQCDEWGH");
+ sqFrom.setStart(10);
+ sqFrom.setEnd(sqFrom.findPosition(sqFrom.getLength() - 1));
+ SequenceI sqTo = new Sequence("toShort", "RCDEW");
+ sqTo.setStart(20);
+ sqTo.setEnd(sqTo.findPosition(sqTo.getLength() - 1));
+ createAnnotation(sqTo);
+ AlignmentAnnotation origTo = sqTo.getAnnotation()[0];
+ createAnnotation(sqFrom);
+ AlignmentAnnotation origFrom = sqFrom.getAnnotation()[0];
+ AlignSeq align = AlignSeq.doGlobalNWAlignment(sqFrom, sqTo,
+ AlignSeq.PEP);
+ SequenceI alSeq1 = new Sequence(sqFrom.getName(), align.getAStr1());
+ alSeq1.setStart(sqFrom.getStart() + align.getSeq1Start() - 1);
+ alSeq1.setEnd(sqFrom.getStart() + align.getSeq1End() - 1);
+ alSeq1.setDatasetSequence(sqFrom);
+ SequenceI alSeq2 = new Sequence(sqTo.getName(), align.getAStr2());
+ alSeq2.setStart(sqTo.getStart() + align.getSeq2Start() - 1);
+ alSeq2.setEnd(sqTo.getStart() + align.getSeq2End() - 1);
+ alSeq2.setDatasetSequence(sqTo);
+ System.out.println(new AppletFormatAdapter().formatSequences("STH",
+ new Alignment(new SequenceI[]
+ { sqFrom, alSeq1, sqTo, alSeq2 }), true));
+
+ Mapping mp = align.getMappingFromS1(false);
+
+ AlignmentAnnotation almap1 = new AlignmentAnnotation(
+ sqTo.getAnnotation()[0]);
+ almap1.liftOver(sqFrom, mp);
+ assertEquals(almap1.sequenceRef, sqFrom);
+ alSeq1.addAlignmentAnnotation(almap1);
+ almap1.setSequenceRef(alSeq1);
+ almap1.adjustForAlignment();
+ AlignmentAnnotation almap2 = new AlignmentAnnotation(
+ sqFrom.getAnnotation()[0]);
+ almap2.liftOver(sqTo, mp);
+ assertEquals(almap2.sequenceRef, sqTo);
+
+ alSeq2.addAlignmentAnnotation(almap2);
+ almap2.setSequenceRef(alSeq2);
+ almap2.adjustForAlignment();
+
+ AlignmentI all = new Alignment(new SequenceI[]
+ { alSeq1, alSeq2 });
+ all.addAnnotation(almap1);
+ all.addAnnotation(almap2);
+ System.out.println(new AppletFormatAdapter().formatSequences("STH",
+ all, true));
+
+ for (int p = 0; p < alSeq1.getLength(); p++)
+ {
+ Annotation orig1, trans1, orig2, trans2;
+ trans2 = almap2.annotations[p];
+ orig2 = origFrom.annotations[alSeq1.findPosition(p)
+ - sqFrom.getStart()];
+ orig1 = origTo.annotations[alSeq2.findPosition(p) - sqTo.getStart()];
+ trans1 = almap1.annotations[p];
+ if (trans1 == trans2)
+ {
+ System.out.println("Pos " + p + " mismatch");
+ continue;
+ }
+ assertEquals(
+ "Mismatch on Original From and transferred annotation on 2",
+ (orig2 != null) ? orig2.toString() : null,
+ (trans2 != null) ? trans2.toString() : null);
+ assertEquals(
+ "Mismatch on Original To and transferred annotation on 1",
+ (orig1 != null) ? orig1.toString() : null,
+ (trans1 != null) ? trans1.toString() : null);
+ String alm1 = ""
+ + (almap1.annotations.length > p ? almap1.annotations[p].displayCharacter
+ : "Out of range");
+ String alm2 = ""
+ + (almap2.annotations.length > p ? almap2.annotations[p].displayCharacter
+ : "Out of range");
+ assertEquals("Position " + p + " " + alm1 + " " + alm2, alm1, alm2);
+ }
+ // new jalview.io.FormatAdapter().formatSequences("STOCKHOLM", n)
+ }
+
+}
--- /dev/null
+package jalview.datamodel;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import jalview.io.AppletFormatAdapter;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for Alignment datamodel.
+ *
+ * @author gmcarstairs
+ *
+ */
+public class AlignmentTest
+{
+ // @formatter:off
+ private static final String TEST_DATA =
+ "# STOCKHOLM 1.0\n" +
+ "#=GS D.melanogaster.1 AC AY119185.1/838-902\n" +
+ "#=GS D.melanogaster.2 AC AC092237.1/57223-57161\n" +
+ "#=GS D.melanogaster.3 AC AY060611.1/560-627\n" +
+ "D.melanogaster.1 G.AGCC.CU...AUGAUCGA\n" +
+ "#=GR D.melanogaster.1 SS ................((((\n" +
+ "D.melanogaster.2 C.AUUCAACU.UAUGAGGAU\n" +
+ "#=GR D.melanogaster.2 SS ................((((\n" +
+ "D.melanogaster.3 G.UGGCGCU..UAUGACGCA\n" +
+ "#=GR D.melanogaster.3 SS (.(((...(....(((((((\n" +
+ "//";
+ // @formatter:on
+
+
+ private Alignment al;
+
+ /*
+ * Read in Stockholm format test data including secondary structure
+ * annotations.
+ */
+ @Before
+ public void setUp() throws IOException
+ {
+ al = new jalview.io.FormatAdapter().readFile(TEST_DATA,
+ AppletFormatAdapter.PASTE, "STH");
+ for (int i = 0; i < al.getSequencesArray().length; ++i)
+ {
+ al.addAnnotation(al.getSequenceAt(i).getAnnotation()[0]);
+ al.getSequenceAt(i).getAnnotation()[0].setCalcId("CalcIdFor"
+ + al.getSequenceAt(i).getName());
+ }
+ }
+
+ /**
+ * Test method that returns annotations that match on calcId.
+ */
+ @Test
+ public void testFindAnnotation_byCalcId()
+ {
+ Iterable<AlignmentAnnotation> anns = al
+ .findAnnotation("CalcIdForD.melanogaster.2");
+ Iterator<AlignmentAnnotation> iter = anns.iterator();
+ assertTrue(iter.hasNext());
+ AlignmentAnnotation ann = iter.next();
+ assertEquals("D.melanogaster.2", ann.sequenceRef.getName());
+ assertFalse(iter.hasNext());
+ }
+}
--- /dev/null
+package jalview.datamodel;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class SequenceTest
+{
+ Sequence seq;
+
+ @Before
+ public void setUp()
+ {
+ seq = new Sequence("FER1", "AKPNGVL");
+ }
+ @Test
+ public void testGetAnnotation()
+ {
+ // initial state returns null not an empty array
+ assertNull(seq.getAnnotation());
+ AlignmentAnnotation ann = addAnnotation("label1", "desc1", "calcId1",
+ 1f);
+ AlignmentAnnotation[] anns = seq.getAnnotation();
+ assertEquals(1, anns.length);
+ assertSame(ann, anns[0]);
+
+ // removing all annotations reverts array to null
+ seq.removeAlignmentAnnotation(ann);
+ assertNull(seq.getAnnotation());
+ }
+
+ @Test
+ public void testGetAnnotation_forLabel()
+ {
+ AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1", 1f);
+ AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2", 1f);
+ AlignmentAnnotation ann3 = addAnnotation("label1", "desc3", "calcId3", 1f);
+ AlignmentAnnotation[] anns = seq.getAnnotation("label1");
+ assertEquals(2, anns.length);
+ assertSame(ann1, anns[0]);
+ assertSame(ann3, anns[1]);
+ }
+
+ private AlignmentAnnotation addAnnotation(String label,
+ String description, String calcId,
+ float value)
+ {
+ final AlignmentAnnotation annotation = new AlignmentAnnotation(label, description,
+ value);
+ annotation.setCalcId(calcId);
+ seq.addAlignmentAnnotation(annotation);
+ return annotation;
+ }
+
+ @Test
+ public void testGetAlignmentAnnotations_forCalcIdAndLabel()
+ {
+ AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1",
+ 1f);
+ AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2",
+ 1f);
+ AlignmentAnnotation ann3 = addAnnotation("label2", "desc3", "calcId3",
+ 1f);
+ AlignmentAnnotation ann4 = addAnnotation("label2", "desc3", "calcId2",
+ 1f);
+ AlignmentAnnotation ann5 = addAnnotation("label5", "desc3", null,
+ 1f);
+ AlignmentAnnotation ann6 = addAnnotation(null, "desc3", "calcId3",
+ 1f);
+ List<AlignmentAnnotation> anns = seq.getAlignmentAnnotations("calcId2",
+ "label2");
+ assertEquals(2, anns.size());
+ assertSame(ann2, anns.get(0));
+ assertSame(ann4, anns.get(1));
+
+ assertTrue(seq.getAlignmentAnnotations("calcId2", "label3").isEmpty());
+ assertTrue(seq.getAlignmentAnnotations("calcId3", "label5").isEmpty());
+ assertTrue(seq.getAlignmentAnnotations("calcId2", null).isEmpty());
+ assertTrue(seq.getAlignmentAnnotations(null, "label3").isEmpty());
+ assertTrue(seq.getAlignmentAnnotations(null, null).isEmpty());
+ }
+
+ /**
+ * Tests for addAlignmentAnnotation. Note this method has the side-effect of
+ * setting the sequenceRef on the annotation.
+ */
+ @Test
+ public void testAddAlignmentAnnotation()
+ {
+ assertNull(seq.annotation);
+ final AlignmentAnnotation annotation = new AlignmentAnnotation("a",
+ "b", 2d);
+ assertNull(annotation.sequenceRef);
+ seq.addAlignmentAnnotation(annotation);
+ assertSame(seq, annotation.sequenceRef);
+ AlignmentAnnotation[] anns = seq.getAnnotation();
+ assertEquals(1, anns.length);
+ assertSame(annotation, anns[0]);
+ }
+}
--- /dev/null
+HEADER TYROSINE KINASE 04-MAY-99 1QCF
+TITLE CRYSTAL STRUCTURE OF HCK IN COMPLEX WITH A SRC FAMILY-
+TITLE 2 SELECTIVE TYROSINE KINASE INHIBITOR
+COMPND MOL_ID: 1;
+COMPND 2 MOLECULE: HAEMATOPOETIC CELL KINASE (HCK);
+COMPND 3 CHAIN: A;
+COMPND 4 FRAGMENT: SH3-SH2-KINASE-HIGH AFFINITY TAIL;
+COMPND 5 ENGINEERED: YES;
+COMPND 6 MUTATION: YES
+SOURCE MOL_ID: 1;
+SOURCE 2 ORGANISM_SCIENTIFIC: HOMO SAPIENS;
+SOURCE 3 ORGANISM_COMMON: HUMAN;
+SOURCE 4 ORGANISM_TAXID: 9606;
+SOURCE 5 EXPRESSION_SYSTEM_COMMON: INSECT CELLS, BACULOVIRUS
+KEYWDS TYROSINE KINASE-INHIBITOR COMPLEX, DOWN-REGULATED KINASE,
+KEYWDS 2 ORDERED ACTIVATION LOOP
+EXPDTA X-RAY DIFFRACTION
+AUTHOR T.SCHINDLER,F.SICHERI,A.PICO,A.GAZIT,A.LEVITZKI,J.KURIYAN
+REVDAT 3 24-FEB-09 1QCF 1 VERSN
+REVDAT 2 23-SEP-03 1QCF 1 JRNL DBREF
+REVDAT 1 08-JUN-99 1QCF 0
+JRNL AUTH T.SCHINDLER,F.SICHERI,A.PICO,A.GAZIT,A.LEVITZKI,
+JRNL AUTH 2 J.KURIYAN
+JRNL TITL CRYSTAL STRUCTURE OF HCK IN COMPLEX WITH A SRC
+JRNL TITL 2 FAMILY-SELECTIVE TYROSINE KINASE INHIBITOR.
+JRNL REF MOL.CELL V. 3 639 1999
+JRNL REFN ISSN 1097-2765
+JRNL PMID 10360180
+JRNL DOI 10.1016/S1097-2765(00)80357-3
+REMARK 1
+REMARK 2
+REMARK 2 RESOLUTION. 2.00 ANGSTROMS.
+REMARK 3
+REMARK 3 REFINEMENT.
+REMARK 3 PROGRAM : CNS
+REMARK 3 AUTHORS : BRUNGER,ADAMS,CLORE,DELANO,GROS,GROSSE-
+REMARK 3 : KUNSTLEVE,JIANG,KUSZEWSKI,NILGES, PANNU,
+REMARK 3 : READ,RICE,SIMONSON,WARREN
+REMARK 3
+REMARK 3 REFINEMENT TARGET : ENGH & HUBER
+REMARK 3
+REMARK 3 DATA USED IN REFINEMENT.
+REMARK 3 RESOLUTION RANGE HIGH (ANGSTROMS) : 2.00
+REMARK 3 RESOLUTION RANGE LOW (ANGSTROMS) : 99.00
+REMARK 3 DATA CUTOFF (SIGMA(F)) : 0.000
+REMARK 3 DATA CUTOFF HIGH (ABS(F)) : NULL
+REMARK 3 DATA CUTOFF LOW (ABS(F)) : NULL
+REMARK 3 COMPLETENESS (WORKING+TEST) (%) : 98.1
+REMARK 3 NUMBER OF REFLECTIONS : 35005
+REMARK 3
+REMARK 3 FIT TO DATA USED IN REFINEMENT.
+REMARK 3 CROSS-VALIDATION METHOD : NULL
+REMARK 3 FREE R VALUE TEST SET SELECTION : NULL
+REMARK 3 R VALUE (WORKING SET) : 0.215
+REMARK 3 FREE R VALUE : 0.257
+REMARK 3 FREE R VALUE TEST SET SIZE (%) : NULL
+REMARK 3 FREE R VALUE TEST SET COUNT : 3475
+REMARK 3 ESTIMATED ERROR OF FREE R VALUE : NULL
+REMARK 3
+REMARK 3 FIT IN THE HIGHEST RESOLUTION BIN.
+REMARK 3 TOTAL NUMBER OF BINS USED : NULL
+REMARK 3 BIN RESOLUTION RANGE HIGH (A) : NULL
+REMARK 3 BIN RESOLUTION RANGE LOW (A) : NULL
+REMARK 3 BIN COMPLETENESS (WORKING+TEST) (%) : NULL
+REMARK 3 REFLECTIONS IN BIN (WORKING SET) : NULL
+REMARK 3 BIN R VALUE (WORKING SET) : NULL
+REMARK 3 BIN FREE R VALUE : NULL
+REMARK 3 BIN FREE R VALUE TEST SET SIZE (%) : NULL
+REMARK 3 BIN FREE R VALUE TEST SET COUNT : NULL
+REMARK 3 ESTIMATED ERROR OF BIN FREE R VALUE : NULL
+REMARK 3
+REMARK 3 NUMBER OF NON-HYDROGEN ATOMS USED IN REFINEMENT.
+REMARK 3 PROTEIN ATOMS : 3626
+REMARK 3 NUCLEIC ACID ATOMS : 0
+REMARK 3 HETEROGEN ATOMS : 21
+REMARK 3 SOLVENT ATOMS : 312
+REMARK 3
+REMARK 3 B VALUES.
+REMARK 3 FROM WILSON PLOT (A**2) : 25.60
+REMARK 3 MEAN B VALUE (OVERALL, A**2) : NULL
+REMARK 3 OVERALL ANISOTROPIC B VALUE.
+REMARK 3 B11 (A**2) : NULL
+REMARK 3 B22 (A**2) : NULL
+REMARK 3 B33 (A**2) : NULL
+REMARK 3 B12 (A**2) : NULL
+REMARK 3 B13 (A**2) : NULL
+REMARK 3 B23 (A**2) : NULL
+REMARK 3
+REMARK 3 ESTIMATED COORDINATE ERROR.
+REMARK 3 ESD FROM LUZZATI PLOT (A) : NULL
+REMARK 3 ESD FROM SIGMAA (A) : NULL
+REMARK 3 LOW RESOLUTION CUTOFF (A) : NULL
+REMARK 3
+REMARK 3 CROSS-VALIDATED ESTIMATED COORDINATE ERROR.
+REMARK 3 ESD FROM C-V LUZZATI PLOT (A) : NULL
+REMARK 3 ESD FROM C-V SIGMAA (A) : NULL
+REMARK 3
+REMARK 3 RMS DEVIATIONS FROM IDEAL VALUES.
+REMARK 3 BOND LENGTHS (A) : 0.007
+REMARK 3 BOND ANGLES (DEGREES) : 1.54
+REMARK 3 DIHEDRAL ANGLES (DEGREES) : NULL
+REMARK 3 IMPROPER ANGLES (DEGREES) : NULL
+REMARK 3
+REMARK 3 ISOTROPIC THERMAL MODEL : NULL
+REMARK 3
+REMARK 3 ISOTROPIC THERMAL FACTOR RESTRAINTS. RMS SIGMA
+REMARK 3 MAIN-CHAIN BOND (A**2) : NULL ; NULL
+REMARK 3 MAIN-CHAIN ANGLE (A**2) : NULL ; NULL
+REMARK 3 SIDE-CHAIN BOND (A**2) : NULL ; NULL
+REMARK 3 SIDE-CHAIN ANGLE (A**2) : NULL ; NULL
+REMARK 3
+REMARK 3 BULK SOLVENT MODELING.
+REMARK 3 METHOD USED : NULL
+REMARK 3 KSOL : NULL
+REMARK 3 BSOL : NULL
+REMARK 3
+REMARK 3 NCS MODEL : NULL
+REMARK 3
+REMARK 3 NCS RESTRAINTS. RMS SIGMA/WEIGHT
+REMARK 3 GROUP 1 POSITIONAL (A) : NULL ; NULL
+REMARK 3 GROUP 1 B-FACTOR (A**2) : NULL ; NULL
+REMARK 3
+REMARK 3 PARAMETER FILE 1 : NULL
+REMARK 3 TOPOLOGY FILE 1 : NULL
+REMARK 3
+REMARK 3 OTHER REFINEMENT REMARKS: NULL
+REMARK 4
+REMARK 4 1QCF COMPLIES WITH FORMAT V. 3.15, 01-DEC-08
+REMARK 100
+REMARK 100 THIS ENTRY HAS BEEN PROCESSED BY RCSB ON 11-MAY-99.
+REMARK 100 THE RCSB ID CODE IS RCSB009070.
+REMARK 200
+REMARK 200 EXPERIMENTAL DETAILS
+REMARK 200 EXPERIMENT TYPE : X-RAY DIFFRACTION
+REMARK 200 DATE OF DATA COLLECTION : 22-OCT-99
+REMARK 200 TEMPERATURE (KELVIN) : 105
+REMARK 200 PH : 7.0
+REMARK 200 NUMBER OF CRYSTALS USED : 1
+REMARK 200
+REMARK 200 SYNCHROTRON (Y/N) : N
+REMARK 200 RADIATION SOURCE : ROTATING ANODE
+REMARK 200 BEAMLINE : NULL
+REMARK 200 X-RAY GENERATOR MODEL : RIGAKU RU200
+REMARK 200 MONOCHROMATIC OR LAUE (M/L) : M
+REMARK 200 WAVELENGTH OR RANGE (A) : 1.5418
+REMARK 200 MONOCHROMATOR : NULL
+REMARK 200 OPTICS : NULL
+REMARK 200
+REMARK 200 DETECTOR TYPE : IMAGE PLATE
+REMARK 200 DETECTOR MANUFACTURER : RIGAKU RAXIS IIC
+REMARK 200 INTENSITY-INTEGRATION SOFTWARE : R-AXIS
+REMARK 200 DATA SCALING SOFTWARE : SCALEPACK
+REMARK 200
+REMARK 200 NUMBER OF UNIQUE REFLECTIONS : 35042
+REMARK 200 RESOLUTION RANGE HIGH (A) : 2.000
+REMARK 200 RESOLUTION RANGE LOW (A) : 99.000
+REMARK 200 REJECTION CRITERIA (SIGMA(I)) : 0.000
+REMARK 200
+REMARK 200 OVERALL.
+REMARK 200 COMPLETENESS FOR RANGE (%) : 98.3
+REMARK 200 DATA REDUNDANCY : 6.400
+REMARK 200 R MERGE (I) : 0.08600
+REMARK 200 R SYM (I) : NULL
+REMARK 200 <I/SIGMA(I)> FOR THE DATA SET : 28.2000
+REMARK 200
+REMARK 200 IN THE HIGHEST RESOLUTION SHELL.
+REMARK 200 HIGHEST RESOLUTION SHELL, RANGE HIGH (A) : 2.00
+REMARK 200 HIGHEST RESOLUTION SHELL, RANGE LOW (A) : 2.10
+REMARK 200 COMPLETENESS FOR SHELL (%) : 95.2
+REMARK 200 DATA REDUNDANCY IN SHELL : 5.40
+REMARK 200 R MERGE FOR SHELL (I) : 0.27700
+REMARK 200 R SYM FOR SHELL (I) : NULL
+REMARK 200 <I/SIGMA(I)> FOR SHELL : NULL
+REMARK 200
+REMARK 200 DIFFRACTION PROTOCOL: SINGLE WAVELENGTH
+REMARK 200 METHOD USED TO DETERMINE THE STRUCTURE: NULL
+REMARK 200 SOFTWARE USED: AMORE
+REMARK 200 STARTING MODEL: NULL
+REMARK 200
+REMARK 200 REMARK: NULL
+REMARK 280
+REMARK 280 CRYSTAL
+REMARK 280 SOLVENT CONTENT, VS (%): 50.98
+REMARK 280 MATTHEWS COEFFICIENT, VM (ANGSTROMS**3/DA): 2.51
+REMARK 280
+REMARK 280 CRYSTALLIZATION CONDITIONS: PEG 10000, DIMETHYL SULFOXIDE, N-
+REMARK 280 (2-HYDROXYETHYL)PIPERAZINE-N-(2- ETHANESULFONIC ACID), PH 7.0,
+REMARK 280 VAPOR DIFFUSION, HANGING DROP, TEMPERATURE 293K
+REMARK 290
+REMARK 290 CRYSTALLOGRAPHIC SYMMETRY
+REMARK 290 SYMMETRY OPERATORS FOR SPACE GROUP: P 21 21 21
+REMARK 290
+REMARK 290 SYMOP SYMMETRY
+REMARK 290 NNNMMM OPERATOR
+REMARK 290 1555 X,Y,Z
+REMARK 290 2555 -X+1/2,-Y,Z+1/2
+REMARK 290 3555 -X,Y+1/2,-Z+1/2
+REMARK 290 4555 X+1/2,-Y+1/2,-Z
+REMARK 290
+REMARK 290 WHERE NNN -> OPERATOR NUMBER
+REMARK 290 MMM -> TRANSLATION VECTOR
+REMARK 290
+REMARK 290 CRYSTALLOGRAPHIC SYMMETRY TRANSFORMATIONS
+REMARK 290 THE FOLLOWING TRANSFORMATIONS OPERATE ON THE ATOM/HETATM
+REMARK 290 RECORDS IN THIS ENTRY TO PRODUCE CRYSTALLOGRAPHICALLY
+REMARK 290 RELATED MOLECULES.
+REMARK 290 SMTRY1 1 1.000000 0.000000 0.000000 0.00000
+REMARK 290 SMTRY2 1 0.000000 1.000000 0.000000 0.00000
+REMARK 290 SMTRY3 1 0.000000 0.000000 1.000000 0.00000
+REMARK 290 SMTRY1 2 -1.000000 0.000000 0.000000 25.50750
+REMARK 290 SMTRY2 2 0.000000 -1.000000 0.000000 0.00000
+REMARK 290 SMTRY3 2 0.000000 0.000000 1.000000 51.69350
+REMARK 290 SMTRY1 3 -1.000000 0.000000 0.000000 0.00000
+REMARK 290 SMTRY2 3 0.000000 1.000000 0.000000 49.50100
+REMARK 290 SMTRY3 3 0.000000 0.000000 -1.000000 51.69350
+REMARK 290 SMTRY1 4 1.000000 0.000000 0.000000 25.50750
+REMARK 290 SMTRY2 4 0.000000 -1.000000 0.000000 49.50100
+REMARK 290 SMTRY3 4 0.000000 0.000000 -1.000000 0.00000
+REMARK 290
+REMARK 290 REMARK: NULL
+REMARK 300
+REMARK 300 BIOMOLECULE: 1
+REMARK 300 SEE REMARK 350 FOR THE AUTHOR PROVIDED AND/OR PROGRAM
+REMARK 300 GENERATED ASSEMBLY INFORMATION FOR THE STRUCTURE IN
+REMARK 300 THIS ENTRY. THE REMARK MAY ALSO PROVIDE INFORMATION ON
+REMARK 300 BURIED SURFACE AREA.
+REMARK 350
+REMARK 350 COORDINATES FOR A COMPLETE MULTIMER REPRESENTING THE KNOWN
+REMARK 350 BIOLOGICALLY SIGNIFICANT OLIGOMERIZATION STATE OF THE
+REMARK 350 MOLECULE CAN BE GENERATED BY APPLYING BIOMT TRANSFORMATIONS
+REMARK 350 GIVEN BELOW. BOTH NON-CRYSTALLOGRAPHIC AND
+REMARK 350 CRYSTALLOGRAPHIC OPERATIONS ARE GIVEN.
+REMARK 350
+REMARK 350 BIOMOLECULE: 1
+REMARK 350 AUTHOR DETERMINED BIOLOGICAL UNIT: MONOMERIC
+REMARK 350 APPLY THE FOLLOWING TO CHAINS: A
+REMARK 350 BIOMT1 1 1.000000 0.000000 0.000000 0.00000
+REMARK 350 BIOMT2 1 0.000000 1.000000 0.000000 0.00000
+REMARK 350 BIOMT3 1 0.000000 0.000000 1.000000 0.00000
+REMARK 465
+REMARK 465 MISSING RESIDUES
+REMARK 465 THE FOLLOWING RESIDUES WERE NOT LOCATED IN THE
+REMARK 465 EXPERIMENT. (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN
+REMARK 465 IDENTIFIER; SSSEQ=SEQUENCE NUMBER; I=INSERTION CODE.)
+REMARK 465
+REMARK 465 M RES C SSSEQI
+REMARK 465 GLY A 76
+REMARK 465 ALA A 77
+REMARK 465 MET A 78
+REMARK 465 GLY A 79
+REMARK 470
+REMARK 470 MISSING ATOM
+REMARK 470 THE FOLLOWING RESIDUES HAVE MISSING ATOMS(M=MODEL NUMBER;
+REMARK 470 RES=RESIDUE NAME; C=CHAIN IDENTIFIER; SSEQ=SEQUENCE NUMBER;
+REMARK 470 I=INSERTION CODE):
+REMARK 470 M RES CSSEQI ATOMS
+REMARK 470 ARG A 477 CG CD NE CZ NH1 NH2
+REMARK 500
+REMARK 500 GEOMETRY AND STEREOCHEMISTRY
+REMARK 500 SUBTOPIC: CLOSE CONTACTS IN SAME ASYMMETRIC UNIT
+REMARK 500
+REMARK 500 THE FOLLOWING ATOMS ARE IN CLOSE CONTACT.
+REMARK 500
+REMARK 500 ATM1 RES C SSEQI ATM2 RES C SSEQI DISTANCE
+REMARK 500 O THR A 521 O THR A 523 2.15
+REMARK 500
+REMARK 500 REMARK: NULL
+REMARK 500
+REMARK 500 GEOMETRY AND STEREOCHEMISTRY
+REMARK 500 SUBTOPIC: COVALENT BOND ANGLES
+REMARK 500
+REMARK 500 THE STEREOCHEMICAL PARAMETERS OF THE FOLLOWING RESIDUES
+REMARK 500 HAVE VALUES WHICH DEVIATE FROM EXPECTED VALUES BY MORE
+REMARK 500 THAN 6*RMSD (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN
+REMARK 500 IDENTIFIER; SSEQ=SEQUENCE NUMBER; I=INSERTION CODE).
+REMARK 500
+REMARK 500 STANDARD TABLE:
+REMARK 500 FORMAT: (10X,I3,1X,A3,1X,A1,I4,A1,3(1X,A4,2X),12X,F5.1)
+REMARK 500
+REMARK 500 EXPECTED VALUES PROTEIN: ENGH AND HUBER, 1999
+REMARK 500 EXPECTED VALUES NUCLEIC ACID: CLOWNEY ET AL 1996
+REMARK 500
+REMARK 500 M RES CSSEQI ATM1 ATM2 ATM3
+REMARK 500 PRO A 531 C - N - CA ANGL. DEV. = 24.0 DEGREES
+REMARK 500 PRO A 531 C - N - CD ANGL. DEV. = -23.8 DEGREES
+REMARK 500
+REMARK 500 REMARK: NULL
+REMARK 500
+REMARK 500 GEOMETRY AND STEREOCHEMISTRY
+REMARK 500 SUBTOPIC: TORSION ANGLES
+REMARK 500
+REMARK 500 TORSION ANGLES OUTSIDE THE EXPECTED RAMACHANDRAN REGIONS:
+REMARK 500 (M=MODEL NUMBER; RES=RESIDUE NAME; C=CHAIN IDENTIFIER;
+REMARK 500 SSEQ=SEQUENCE NUMBER; I=INSERTION CODE).
+REMARK 500
+REMARK 500 STANDARD TABLE:
+REMARK 500 FORMAT:(10X,I3,1X,A3,1X,A1,I4,A1,4X,F7.2,3X,F7.2)
+REMARK 500
+REMARK 500 EXPECTED VALUES: GJ KLEYWEGT AND TA JONES (1996). PHI/PSI-
+REMARK 500 CHOLOGY: RAMACHANDRAN REVISITED. STRUCTURE 4, 1395 - 1400
+REMARK 500
+REMARK 500 M RES CSSEQI PSI PHI
+REMARK 500 GLU A 113 64.07 -109.04
+REMARK 500 ALA A 125 -79.28 -87.40
+REMARK 500 ARG A 127 14.67 55.46
+REMARK 500 ASP A 141 11.04 53.98
+REMARK 500 ASN A 209 32.97 75.81
+REMARK 500 PRO A 216 -6.39 -59.13
+REMARK 500 TYR A 230 -8.49 -57.61
+REMARK 500 ASP A 235 53.62 36.77
+REMARK 500 SER A 242 -86.94 -102.49
+REMARK 500 ALA A 259 54.42 -110.81
+REMARK 500 LYS A 288 12.84 54.99
+REMARK 500 ARG A 385 -15.14 83.68
+REMARK 500 ASP A 386 53.00 -150.15
+REMARK 500 ASP A 413 112.28 -20.16
+REMARK 500 TYR A 463 60.93 38.29
+REMARK 500 TRP A 499 32.13 -93.55
+REMARK 500 TYR A 520 -166.30 -109.43
+REMARK 500 ALA A 522 -102.78 -0.05
+REMARK 500 THR A 523 -169.49 -62.46
+REMARK 500 GLU A 524 155.80 129.52
+REMARK 500 SER A 525 46.68 -151.80
+REMARK 500
+REMARK 500 REMARK: NULL
+REMARK 525
+REMARK 525 SOLVENT
+REMARK 525
+REMARK 525 THE SOLVENT MOLECULES HAVE CHAIN IDENTIFIERS THAT
+REMARK 525 INDICATE THE POLYMER CHAIN WITH WHICH THEY ARE MOST
+REMARK 525 CLOSELY ASSOCIATED. THE REMARK LISTS ALL THE SOLVENT
+REMARK 525 MOLECULES WHICH ARE MORE THAN 5A AWAY FROM THE
+REMARK 525 NEAREST POLYMER CHAIN (M = MODEL NUMBER;
+REMARK 525 RES=RESIDUE NAME; C=CHAIN IDENTIFIER; SSEQ=SEQUENCE
+REMARK 525 NUMBER; I=INSERTION CODE):
+REMARK 525
+REMARK 525 M RES CSSEQI
+REMARK 525 HOH A 807 DISTANCE = 8.64 ANGSTROMS
+REMARK 525 HOH A 837 DISTANCE = 5.22 ANGSTROMS
+REMARK 800
+REMARK 800 SITE
+REMARK 800 SITE_IDENTIFIER: AC1
+REMARK 800 EVIDENCE_CODE: SOFTWARE
+REMARK 800 SITE_DESCRIPTION: BINDING SITE FOR RESIDUE PP1 A 532
+REMARK 900
+REMARK 900 RELATED ENTRIES
+REMARK 900 RELATED ID: 1AD5 RELATED DB: PDB
+REMARK 900 1AD5 CONTAINS THE WILD-TYPE PROTEIN COMPLEXED WITH AMP-PNP
+DBREF 1QCF A 76 531 UNP P08631 HCK_HUMAN 74 526
+SEQADV 1QCF GLU A 528 UNP P08631 GLN 523
+SEQADV 1QCF GLU A 529 UNP P08631 GLN 524
+SEQADV 1QCF ILE A 530 UNP P08631 GLU 525
+SEQRES 1 A 454 GLY ALA MET GLY SER GLY ILE ARG ILE ILE VAL VAL ALA
+SEQRES 2 A 454 LEU TYR ASP TYR GLU ALA ILE HIS HIS GLU ASP LEU SER
+SEQRES 3 A 454 PHE GLN LYS GLY ASP GLN MET VAL VAL LEU GLU GLU SER
+SEQRES 4 A 454 GLY GLU TRP TRP LYS ALA ARG SER LEU ALA THR ARG LYS
+SEQRES 5 A 454 GLU GLY TYR ILE PRO SER ASN TYR VAL ALA ARG VAL ASP
+SEQRES 6 A 454 SER LEU GLU THR GLU GLU TRP PHE PHE LYS GLY ILE SER
+SEQRES 7 A 454 ARG LYS ASP ALA GLU ARG GLN LEU LEU ALA PRO GLY ASN
+SEQRES 8 A 454 MET LEU GLY SER PHE MET ILE ARG ASP SER GLU THR THR
+SEQRES 9 A 454 LYS GLY SER TYR SER LEU SER VAL ARG ASP TYR ASP PRO
+SEQRES 10 A 454 ARG GLN GLY ASP THR VAL LYS HIS TYR LYS ILE ARG THR
+SEQRES 11 A 454 LEU ASP ASN GLY GLY PHE TYR ILE SER PRO ARG SER THR
+SEQRES 12 A 454 PHE SER THR LEU GLN GLU LEU VAL ASP HIS TYR LYS LYS
+SEQRES 13 A 454 GLY ASN ASP GLY LEU CYS GLN LYS LEU SER VAL PRO CYS
+SEQRES 14 A 454 MET SER SER LYS PRO GLN LYS PRO TRP GLU LYS ASP ALA
+SEQRES 15 A 454 TRP GLU ILE PRO ARG GLU SER LEU LYS LEU GLU LYS LYS
+SEQRES 16 A 454 LEU GLY ALA GLY GLN PHE GLY GLU VAL TRP MET ALA THR
+SEQRES 17 A 454 TYR ASN LYS HIS THR LYS VAL ALA VAL LYS THR MET LYS
+SEQRES 18 A 454 PRO GLY SER MET SER VAL GLU ALA PHE LEU ALA GLU ALA
+SEQRES 19 A 454 ASN VAL MET LYS THR LEU GLN HIS ASP LYS LEU VAL LYS
+SEQRES 20 A 454 LEU HIS ALA VAL VAL THR LYS GLU PRO ILE TYR ILE ILE
+SEQRES 21 A 454 THR GLU PHE MET ALA LYS GLY SER LEU LEU ASP PHE LEU
+SEQRES 22 A 454 LYS SER ASP GLU GLY SER LYS GLN PRO LEU PRO LYS LEU
+SEQRES 23 A 454 ILE ASP PHE SER ALA GLN ILE ALA GLU GLY MET ALA PHE
+SEQRES 24 A 454 ILE GLU GLN ARG ASN TYR ILE HIS ARG ASP LEU ARG ALA
+SEQRES 25 A 454 ALA ASN ILE LEU VAL SER ALA SER LEU VAL CYS LYS ILE
+SEQRES 26 A 454 ALA ASP PHE GLY LEU ALA ARG VAL ILE GLU ASP ASN GLU
+SEQRES 27 A 454 TYR THR ALA ARG GLU GLY ALA LYS PHE PRO ILE LYS TRP
+SEQRES 28 A 454 THR ALA PRO GLU ALA ILE ASN PHE GLY SER PHE THR ILE
+SEQRES 29 A 454 LYS SER ASP VAL TRP SER PHE GLY ILE LEU LEU MET GLU
+SEQRES 30 A 454 ILE VAL THR TYR GLY ARG ILE PRO TYR PRO GLY MET SER
+SEQRES 31 A 454 ASN PRO GLU VAL ILE ARG ALA LEU GLU ARG GLY TYR ARG
+SEQRES 32 A 454 MET PRO ARG PRO GLU ASN CYS PRO GLU GLU LEU TYR ASN
+SEQRES 33 A 454 ILE MET MET ARG CYS TRP LYS ASN ARG PRO GLU GLU ARG
+SEQRES 34 A 454 PRO THR PHE GLU TYR ILE GLN SER VAL LEU ASP ASP PHE
+SEQRES 35 A 454 TYR THR ALA THR GLU SER GLN PTR GLU GLU ILE PRO
+MODRES 1QCF PTR A 527 TYR O-PHOSPHOTYROSINE
+HET PTR A 527 16
+HET PP1 A 532 21
+HETNAM PTR O-PHOSPHOTYROSINE
+HETNAM PP1 1-TER-BUTYL-3-P-TOLYL-1H-PYRAZOLO[3,4-D]PYRIMIDIN-4-
+HETNAM 2 PP1 YLAMINE
+HETSYN PTR PHOSPHONOTYROSINE
+FORMUL 1 PTR C9 H12 N O6 P
+FORMUL 2 PP1 C16 H19 N5
+FORMUL 3 HOH *312(H2 O)
+HELIX 1 1 SER A 142 GLU A 146 5 5
+HELIX 2 2 SER A 154 ALA A 164 1 11
+HELIX 3 3 THR A 222 LYS A 231 1 10
+HELIX 4 4 PRO A 263 GLU A 265 5 3
+HELIX 5 5 SER A 303 LYS A 315 1 13
+HELIX 6 6 SER A 345 SER A 352 1 8
+HELIX 7 7 SER A 352 LYS A 357 1 6
+HELIX 8 8 PRO A 359 ARG A 380 1 22
+HELIX 9 9 ARG A 388 ALA A 390 5 3
+HELIX 10 10 GLY A 406 VAL A 410 5 5
+HELIX 11 11 ASP A 413 ALA A 418 1 6
+HELIX 12 12 PRO A 425 THR A 429 5 5
+HELIX 13 13 ALA A 430 GLY A 437 1 8
+HELIX 14 14 THR A 440 THR A 457 1 18
+HELIX 15 15 SER A 467 GLY A 478 1 12
+HELIX 16 16 PRO A 488 TRP A 499 1 12
+HELIX 17 17 ARG A 502 ARG A 506 5 5
+HELIX 18 18 THR A 508 ASP A 518 1 11
+SHEET 1 A 5 GLU A 129 PRO A 133 0
+SHEET 2 A 5 TRP A 118 SER A 123 -1 O TRP A 119 N ILE A 132
+SHEET 3 A 5 GLN A 107 GLU A 112 -1 N VAL A 109 O ARG A 122
+SHEET 4 A 5 ILE A 85 ALA A 88 -1 O VAL A 86 N MET A 108
+SHEET 5 A 5 VAL A 137 ARG A 139 -1 O ALA A 138 N VAL A 87
+SHEET 1 B 5 PHE A 149 PHE A 150 0
+SHEET 2 B 5 PHE A 172 ASP A 176 1 O ILE A 174 N PHE A 150
+SHEET 3 B 5 TYR A 184 ASP A 192 -1 O SER A 185 N ARG A 175
+SHEET 4 B 5 GLY A 196 THR A 206 -1 N GLY A 196 O ASP A 192
+SHEET 5 B 5 PHE A 212 TYR A 213 -1 O TYR A 213 N ARG A 205
+SHEET 1 C 5 LEU A 267 GLY A 274 0
+SHEET 2 C 5 GLY A 279 TYR A 286 -1 N VAL A 281 O GLY A 274
+SHEET 3 C 5 THR A 290 MET A 297 -1 O THR A 290 N TYR A 286
+SHEET 4 C 5 TYR A 335 THR A 338 -1 O ILE A 336 N LYS A 295
+SHEET 5 C 5 LEU A 325 VAL A 329 -1 N HIS A 326 O ILE A 337
+SHEET 1 D 2 ILE A 392 VAL A 394 0
+SHEET 2 D 2 CYS A 400 ILE A 402 -1 O LYS A 401 N LEU A 393
+LINK C GLN A 526 N PTR A 527 1555 1555 1.32
+LINK C PTR A 527 N GLU A 528 1555 1555 1.32
+CISPEP 1 GLU A 332 PRO A 333 0 -0.10
+CISPEP 2 ILE A 530 PRO A 531 0 -1.93
+SITE 1 AC1 12 LEU A 273 VAL A 281 ALA A 293 ILE A 336
+SITE 2 AC1 12 THR A 338 GLU A 339 MET A 341 SER A 345
+SITE 3 AC1 12 LEU A 393 ASP A 404 HOH A 582 HOH A 774
+CRYST1 51.015 99.002 103.387 90.00 90.00 90.00 P 21 21 21 4
+ORIGX1 1.000000 0.000000 0.000000 0.00000
+ORIGX2 0.000000 1.000000 0.000000 0.00000
+ORIGX3 0.000000 0.000000 1.000000 0.00000
+SCALE1 0.019602 0.000000 0.000000 0.00000
+SCALE2 0.000000 0.010101 0.000000 0.00000
+SCALE3 0.000000 0.000000 0.009672 0.00000
+ATOM 1 N SER A 80 -12.315 3.135 35.123 1.00 58.24 N
+ATOM 2 CA SER A 80 -12.056 1.909 35.930 1.00 56.45 C
+ATOM 3 C SER A 80 -10.561 1.626 35.997 1.00 54.76 C
+ATOM 4 O SER A 80 -9.758 2.328 35.378 1.00 55.95 O
+ATOM 5 CB SER A 80 -12.772 0.705 35.308 1.00 57.12 C
+ATOM 6 OG SER A 80 -14.175 0.912 35.247 1.00 59.13 O
+ATOM 7 N GLY A 81 -10.198 0.598 36.758 1.00 51.37 N
+ATOM 8 CA GLY A 81 -8.804 0.220 36.882 1.00 44.34 C
+ATOM 9 C GLY A 81 -8.315 -0.399 35.586 1.00 39.98 C
+ATOM 10 O GLY A 81 -8.076 -1.607 35.498 1.00 36.92 O
+ATOM 11 N ILE A 82 -8.175 0.445 34.571 1.00 35.38 N
+ATOM 12 CA ILE A 82 -7.713 0.023 33.258 1.00 33.74 C
+ATOM 13 C ILE A 82 -6.193 0.115 33.179 1.00 32.49 C
+ATOM 14 O ILE A 82 -5.602 1.114 33.580 1.00 33.80 O
+ATOM 15 CB ILE A 82 -8.356 0.905 32.167 1.00 33.93 C
+ATOM 16 CG1 ILE A 82 -9.875 0.670 32.170 1.00 32.55 C
+ATOM 17 CG2 ILE A 82 -7.730 0.608 30.805 1.00 32.89 C
+ATOM 18 CD1 ILE A 82 -10.674 1.635 31.319 1.00 30.01 C
+ATOM 19 N ARG A 83 -5.561 -0.930 32.660 1.00 30.03 N
+ATOM 20 CA ARG A 83 -4.110 -0.946 32.548 1.00 29.23 C
+ATOM 21 C ARG A 83 -3.665 0.213 31.660 1.00 31.20 C
+ATOM 22 O ARG A 83 -4.206 0.425 30.574 1.00 28.24 O
+ATOM 23 CB ARG A 83 -3.638 -2.289 31.975 1.00 30.07 C
+ATOM 24 CG ARG A 83 -2.157 -2.540 32.170 1.00 30.09 C
+ATOM 25 CD ARG A 83 -1.725 -3.917 31.700 1.00 28.81 C
+ATOM 26 NE ARG A 83 -2.015 -4.114 30.287 1.00 28.47 N
+ATOM 27 CZ ARG A 83 -1.360 -4.964 29.509 1.00 29.57 C
+ATOM 28 NH1 ARG A 83 -0.371 -5.694 30.011 1.00 31.86 N
+ATOM 29 NH2 ARG A 83 -1.688 -5.078 28.229 1.00 32.35 N
+ATOM 30 N ILE A 84 -2.685 0.975 32.132 1.00 32.14 N
+ATOM 31 CA ILE A 84 -2.197 2.116 31.374 1.00 34.25 C
+ATOM 32 C ILE A 84 -0.855 1.789 30.728 1.00 34.69 C
+ATOM 33 O ILE A 84 0.091 1.363 31.398 1.00 31.70 O
+ATOM 34 CB ILE A 84 -2.079 3.355 32.293 1.00 38.13 C
+ATOM 35 CG1 ILE A 84 -1.720 4.610 31.486 1.00 40.14 C
+ATOM 36 CG2 ILE A 84 -1.055 3.087 33.371 1.00 39.84 C
+ATOM 37 CD1 ILE A 84 -0.316 4.642 30.930 1.00 43.16 C
+ATOM 38 N ILE A 85 -0.786 1.991 29.415 1.00 35.19 N
+ATOM 39 CA ILE A 85 0.423 1.715 28.649 1.00 35.69 C
+ATOM 40 C ILE A 85 1.006 2.998 28.062 1.00 36.73 C
+ATOM 41 O ILE A 85 0.277 3.949 27.768 1.00 36.76 O
+ATOM 42 CB ILE A 85 0.118 0.711 27.507 1.00 37.70 C
+ATOM 43 CG1 ILE A 85 -0.348 -0.617 28.112 1.00 38.50 C
+ATOM 44 CG2 ILE A 85 1.355 0.483 26.643 1.00 36.42 C
+ATOM 45 CD1 ILE A 85 -0.801 -1.634 27.093 1.00 42.64 C
+ATOM 46 N VAL A 86 2.329 3.019 27.911 1.00 34.69 N
+ATOM 47 CA VAL A 86 3.022 4.170 27.344 1.00 31.49 C
+ATOM 48 C VAL A 86 4.164 3.694 26.461 1.00 31.07 C
+ATOM 49 O VAL A 86 4.579 2.534 26.530 1.00 27.78 O
+ATOM 50 CB VAL A 86 3.616 5.095 28.440 1.00 30.31 C
+ATOM 51 CG1 VAL A 86 2.510 5.682 29.289 1.00 27.82 C
+ATOM 52 CG2 VAL A 86 4.595 4.316 29.304 1.00 28.63 C
+ATOM 53 N VAL A 87 4.668 4.597 25.629 1.00 30.20 N
+ATOM 54 CA VAL A 87 5.779 4.279 24.746 1.00 31.48 C
+ATOM 55 C VAL A 87 6.949 5.211 25.054 1.00 29.88 C
+ATOM 56 O VAL A 87 6.750 6.390 25.329 1.00 28.48 O
+ATOM 57 CB VAL A 87 5.383 4.439 23.266 1.00 30.59 C
+ATOM 58 CG1 VAL A 87 4.841 5.835 23.020 1.00 33.37 C
+ATOM 59 CG2 VAL A 87 6.590 4.171 22.379 1.00 32.04 C
+ATOM 60 N ALA A 88 8.162 4.669 25.010 1.00 31.06 N
+ATOM 61 CA ALA A 88 9.369 5.440 25.288 1.00 33.50 C
+ATOM 62 C ALA A 88 9.725 6.397 24.151 1.00 34.65 C
+ATOM 63 O ALA A 88 9.947 5.971 23.016 1.00 35.81 O
+ATOM 64 CB ALA A 88 10.530 4.494 25.547 1.00 31.62 C
+ATOM 65 N LEU A 89 9.791 7.687 24.473 1.00 34.33 N
+ATOM 66 CA LEU A 89 10.128 8.724 23.501 1.00 35.85 C
+ATOM 67 C LEU A 89 11.635 8.848 23.262 1.00 35.36 C
+ATOM 68 O LEU A 89 12.059 9.477 22.292 1.00 36.91 O
+ATOM 69 CB LEU A 89 9.597 10.080 23.972 1.00 33.18 C
+ATOM 70 CG LEU A 89 8.090 10.255 24.157 1.00 33.16 C
+ATOM 71 CD1 LEU A 89 7.828 11.619 24.770 1.00 30.41 C
+ATOM 72 CD2 LEU A 89 7.362 10.103 22.820 1.00 33.68 C
+ATOM 73 N TYR A 90 12.435 8.263 24.150 1.00 34.87 N
+ATOM 74 CA TYR A 90 13.897 8.323 24.045 1.00 35.34 C
+ATOM 75 C TYR A 90 14.479 7.079 24.698 1.00 34.67 C
+ATOM 76 O TYR A 90 13.766 6.325 25.362 1.00 35.13 O
+ATOM 77 CB TYR A 90 14.447 9.522 24.825 1.00 34.85 C
+ATOM 78 CG TYR A 90 13.701 10.818 24.633 1.00 37.00 C
+ATOM 79 CD1 TYR A 90 13.845 11.573 23.471 1.00 37.27 C
+ATOM 80 CD2 TYR A 90 12.838 11.285 25.621 1.00 36.75 C
+ATOM 81 CE1 TYR A 90 13.144 12.766 23.302 1.00 37.86 C
+ATOM 82 CE2 TYR A 90 12.135 12.469 25.461 1.00 39.51 C
+ATOM 83 CZ TYR A 90 12.291 13.205 24.302 1.00 38.69 C
+ATOM 84 OH TYR A 90 11.594 14.383 24.160 1.00 43.44 O
+ATOM 85 N ASP A 91 15.780 6.873 24.517 1.00 35.19 N
+ATOM 86 CA ASP A 91 16.461 5.752 25.150 1.00 36.29 C
+ATOM 87 C ASP A 91 16.757 6.233 26.568 1.00 36.32 C
+ATOM 88 O ASP A 91 16.833 7.433 26.810 1.00 35.87 O
+ATOM 89 CB ASP A 91 17.789 5.443 24.451 1.00 40.07 C
+ATOM 90 CG ASP A 91 17.611 4.909 23.041 1.00 43.56 C
+ATOM 91 OD1 ASP A 91 18.639 4.672 22.375 1.00 46.78 O
+ATOM 92 OD2 ASP A 91 16.460 4.720 22.597 1.00 46.84 O
+ATOM 93 N TYR A 92 16.915 5.312 27.508 1.00 36.46 N
+ATOM 94 CA TYR A 92 17.232 5.708 28.874 1.00 36.00 C
+ATOM 95 C TYR A 92 18.064 4.631 29.541 1.00 37.61 C
+ATOM 96 O TYR A 92 17.676 3.465 29.558 1.00 36.97 O
+ATOM 97 CB TYR A 92 15.962 5.946 29.694 1.00 34.09 C
+ATOM 98 CG TYR A 92 16.261 6.309 31.133 1.00 35.24 C
+ATOM 99 CD1 TYR A 92 16.926 7.492 31.448 1.00 37.65 C
+ATOM 100 CD2 TYR A 92 15.941 5.440 32.173 1.00 35.48 C
+ATOM 101 CE1 TYR A 92 17.269 7.798 32.765 1.00 38.85 C
+ATOM 102 CE2 TYR A 92 16.280 5.737 33.492 1.00 36.72 C
+ATOM 103 CZ TYR A 92 16.944 6.915 33.779 1.00 37.60 C
+ATOM 104 OH TYR A 92 17.292 7.210 35.078 1.00 42.53 O
+ATOM 105 N GLU A 93 19.215 5.018 30.079 1.00 38.99 N
+ATOM 106 CA GLU A 93 20.077 4.059 30.753 1.00 42.62 C
+ATOM 107 C GLU A 93 19.948 4.232 32.256 1.00 42.67 C
+ATOM 108 O GLU A 93 20.068 5.339 32.776 1.00 41.84 O
+ATOM 109 CB GLU A 93 21.538 4.251 30.338 1.00 45.96 C
+ATOM 110 CG GLU A 93 22.490 3.277 31.017 1.00 52.30 C
+ATOM 111 CD GLU A 93 23.926 3.412 30.534 1.00 56.09 C
+ATOM 112 OE1 GLU A 93 24.531 4.489 30.722 1.00 58.01 O
+ATOM 113 OE2 GLU A 93 24.448 2.432 29.963 1.00 58.62 O
+ATOM 114 N ALA A 94 19.693 3.130 32.948 1.00 43.87 N
+ATOM 115 CA ALA A 94 19.548 3.158 34.393 1.00 45.92 C
+ATOM 116 C ALA A 94 20.853 3.582 35.057 1.00 47.69 C
+ATOM 117 O ALA A 94 21.910 3.014 34.788 1.00 44.95 O
+ATOM 118 CB ALA A 94 19.133 1.784 34.897 1.00 44.26 C
+ATOM 119 N ILE A 95 20.772 4.592 35.915 1.00 50.71 N
+ATOM 120 CA ILE A 95 21.940 5.074 36.633 1.00 55.05 C
+ATOM 121 C ILE A 95 21.695 4.866 38.122 1.00 57.48 C
+ATOM 122 O ILE A 95 22.635 4.790 38.911 1.00 58.53 O
+ATOM 123 CB ILE A 95 22.210 6.577 36.354 1.00 56.23 C
+ATOM 124 CG1 ILE A 95 21.017 7.428 36.790 1.00 56.58 C
+ATOM 125 CG2 ILE A 95 22.480 6.790 34.873 1.00 56.24 C
+ATOM 126 CD1 ILE A 95 21.224 8.923 36.574 1.00 56.85 C
+ATOM 127 N HIS A 96 20.421 4.760 38.493 1.00 60.30 N
+ATOM 128 CA HIS A 96 20.032 4.555 39.885 1.00 61.59 C
+ATOM 129 C HIS A 96 19.652 3.094 40.130 1.00 63.02 C
+ATOM 130 O HIS A 96 19.282 2.371 39.202 1.00 63.01 O
+ATOM 131 CB HIS A 96 18.856 5.470 40.245 1.00 60.97 C
+ATOM 132 CG HIS A 96 19.120 6.923 39.991 1.00 62.42 C
+ATOM 133 ND1 HIS A 96 20.134 7.616 40.619 1.00 62.32 N
+ATOM 134 CD2 HIS A 96 18.518 7.808 39.163 1.00 62.31 C
+ATOM 135 CE1 HIS A 96 20.144 8.865 40.186 1.00 63.13 C
+ATOM 136 NE2 HIS A 96 19.173 9.008 39.302 1.00 61.82 N
+ATOM 137 N HIS A 97 19.745 2.677 41.389 1.00 63.58 N
+ATOM 138 CA HIS A 97 19.443 1.310 41.810 1.00 64.78 C
+ATOM 139 C HIS A 97 18.144 0.693 41.275 1.00 64.19 C
+ATOM 140 O HIS A 97 18.165 -0.377 40.659 1.00 63.54 O
+ATOM 141 CB HIS A 97 19.435 1.242 43.340 1.00 66.65 C
+ATOM 142 CG HIS A 97 19.091 -0.110 43.882 1.00 69.91 C
+ATOM 143 ND1 HIS A 97 19.840 -1.234 43.612 1.00 71.18 N
+ATOM 144 CD2 HIS A 97 18.070 -0.520 44.674 1.00 70.93 C
+ATOM 145 CE1 HIS A 97 19.298 -2.279 44.212 1.00 72.26 C
+ATOM 146 NE2 HIS A 97 18.222 -1.872 44.863 1.00 72.48 N
+ATOM 147 N GLU A 98 17.020 1.356 41.521 1.00 63.07 N
+ATOM 148 CA GLU A 98 15.721 0.852 41.079 1.00 62.06 C
+ATOM 149 C GLU A 98 15.320 1.309 39.674 1.00 59.39 C
+ATOM 150 O GLU A 98 14.177 1.124 39.253 1.00 57.96 O
+ATOM 151 CB GLU A 98 14.650 1.268 42.085 1.00 64.63 C
+ATOM 152 CG GLU A 98 14.881 0.722 43.485 1.00 68.33 C
+ATOM 153 CD GLU A 98 13.877 1.257 44.488 1.00 72.77 C
+ATOM 154 OE1 GLU A 98 13.899 2.479 44.764 1.00 72.46 O
+ATOM 155 OE2 GLU A 98 13.060 0.457 44.994 1.00 74.85 O
+ATOM 156 N ASP A 99 16.263 1.904 38.952 1.00 56.28 N
+ATOM 157 CA ASP A 99 16.014 2.378 37.596 1.00 52.13 C
+ATOM 158 C ASP A 99 15.701 1.255 36.622 1.00 50.96 C
+ATOM 159 O ASP A 99 16.193 0.134 36.760 1.00 52.38 O
+ATOM 160 CB ASP A 99 17.226 3.155 37.084 1.00 51.87 C
+ATOM 161 CG ASP A 99 17.211 4.603 37.504 1.00 51.68 C
+ATOM 162 OD1 ASP A 99 16.583 4.910 38.538 1.00 52.27 O
+ATOM 163 OD2 ASP A 99 17.845 5.428 36.807 1.00 48.20 O
+ATOM 164 N LEU A 100 14.878 1.569 35.631 1.00 48.34 N
+ATOM 165 CA LEU A 100 14.513 0.604 34.610 1.00 44.41 C
+ATOM 166 C LEU A 100 15.020 1.208 33.307 1.00 43.33 C
+ATOM 167 O LEU A 100 14.627 2.313 32.933 1.00 40.90 O
+ATOM 168 CB LEU A 100 12.991 0.430 34.560 1.00 44.99 C
+ATOM 169 CG LEU A 100 12.403 -0.751 33.778 1.00 42.66 C
+ATOM 170 CD1 LEU A 100 10.891 -0.683 33.832 1.00 44.47 C
+ATOM 171 CD2 LEU A 100 12.870 -0.731 32.345 1.00 45.53 C
+ATOM 172 N SER A 101 15.914 0.497 32.628 1.00 43.53 N
+ATOM 173 CA SER A 101 16.458 0.984 31.366 1.00 42.17 C
+ATOM 174 C SER A 101 15.539 0.577 30.224 1.00 40.58 C
+ATOM 175 O SER A 101 14.941 -0.497 30.250 1.00 41.76 O
+ATOM 176 CB SER A 101 17.856 0.408 31.123 1.00 42.86 C
+ATOM 177 OG SER A 101 18.747 0.762 32.166 1.00 44.85 O
+ATOM 178 N PHE A 102 15.425 1.444 29.226 1.00 37.21 N
+ATOM 179 CA PHE A 102 14.593 1.168 28.069 1.00 34.66 C
+ATOM 180 C PHE A 102 15.129 1.914 26.858 1.00 37.23 C
+ATOM 181 O PHE A 102 15.856 2.896 26.990 1.00 35.65 O
+ATOM 182 CB PHE A 102 13.135 1.556 28.359 1.00 30.36 C
+ATOM 183 CG PHE A 102 12.950 2.990 28.780 1.00 27.41 C
+ATOM 184 CD1 PHE A 102 12.989 4.021 27.848 1.00 28.02 C
+ATOM 185 CD2 PHE A 102 12.727 3.305 30.119 1.00 26.95 C
+ATOM 186 CE1 PHE A 102 12.804 5.353 28.243 1.00 26.97 C
+ATOM 187 CE2 PHE A 102 12.542 4.630 30.527 1.00 22.91 C
+ATOM 188 CZ PHE A 102 12.579 5.654 29.588 1.00 24.41 C
+ATOM 189 N GLN A 103 14.790 1.430 25.672 1.00 40.15 N
+ATOM 190 CA GLN A 103 15.252 2.071 24.457 1.00 39.70 C
+ATOM 191 C GLN A 103 14.021 2.665 23.779 1.00 39.87 C
+ATOM 192 O GLN A 103 12.912 2.154 23.943 1.00 36.73 O
+ATOM 193 CB GLN A 103 15.963 1.038 23.577 1.00 45.83 C
+ATOM 194 CG GLN A 103 16.896 1.633 22.530 1.00 53.12 C
+ATOM 195 CD GLN A 103 17.974 0.650 22.092 1.00 57.56 C
+ATOM 196 OE1 GLN A 103 17.677 -0.427 21.573 1.00 60.41 O
+ATOM 197 NE2 GLN A 103 19.236 1.019 22.310 1.00 57.53 N
+ATOM 198 N LYS A 104 14.211 3.763 23.053 1.00 37.71 N
+ATOM 199 CA LYS A 104 13.108 4.440 22.381 1.00 40.24 C
+ATOM 200 C LYS A 104 12.163 3.456 21.706 1.00 39.27 C
+ATOM 201 O LYS A 104 12.594 2.454 21.135 1.00 39.16 O
+ATOM 202 CB LYS A 104 13.647 5.436 21.350 1.00 40.10 C
+ATOM 203 CG LYS A 104 12.571 6.248 20.659 1.00 41.56 C
+ATOM 204 CD LYS A 104 13.176 7.284 19.731 1.00 44.35 C
+ATOM 205 CE LYS A 104 12.098 8.137 19.081 1.00 45.99 C
+ATOM 206 NZ LYS A 104 12.680 9.165 18.170 1.00 46.99 N
+ATOM 207 N GLY A 105 10.870 3.749 21.783 1.00 41.17 N
+ATOM 208 CA GLY A 105 9.879 2.882 21.179 1.00 42.10 C
+ATOM 209 C GLY A 105 9.289 1.833 22.110 1.00 41.77 C
+ATOM 210 O GLY A 105 8.092 1.566 22.040 1.00 43.81 O
+ATOM 211 N ASP A 106 10.103 1.240 22.983 1.00 41.11 N
+ATOM 212 CA ASP A 106 9.600 0.207 23.892 1.00 41.68 C
+ATOM 213 C ASP A 106 8.353 0.683 24.623 1.00 38.60 C
+ATOM 214 O ASP A 106 8.242 1.856 24.974 1.00 40.05 O
+ATOM 215 CB ASP A 106 10.643 -0.189 24.943 1.00 41.68 C
+ATOM 216 CG ASP A 106 11.984 -0.550 24.343 1.00 47.29 C
+ATOM 217 OD1 ASP A 106 12.025 -1.122 23.232 1.00 46.79 O
+ATOM 218 OD2 ASP A 106 13.006 -0.282 25.011 1.00 46.82 O
+ATOM 219 N GLN A 107 7.417 -0.232 24.856 1.00 38.75 N
+ATOM 220 CA GLN A 107 6.181 0.101 25.560 1.00 34.83 C
+ATOM 221 C GLN A 107 6.196 -0.453 26.976 1.00 33.37 C
+ATOM 222 O GLN A 107 6.695 -1.555 27.216 1.00 32.05 O
+ATOM 223 CB GLN A 107 4.972 -0.433 24.796 1.00 36.28 C
+ATOM 224 CG GLN A 107 4.716 0.315 23.498 1.00 37.97 C
+ATOM 225 CD GLN A 107 3.521 -0.219 22.733 1.00 36.35 C
+ATOM 226 OE1 GLN A 107 2.404 -0.263 23.247 1.00 37.70 O
+ATOM 227 NE2 GLN A 107 3.754 -0.622 21.491 1.00 38.28 N
+ATOM 228 N MET A 108 5.641 0.320 27.905 1.00 32.28 N
+ATOM 229 CA MET A 108 5.608 -0.055 29.316 1.00 30.78 C
+ATOM 230 C MET A 108 4.265 0.193 29.986 1.00 26.76 C
+ATOM 231 O MET A 108 3.483 1.032 29.547 1.00 29.95 O
+ATOM 232 CB MET A 108 6.694 0.719 30.074 1.00 31.18 C
+ATOM 233 CG MET A 108 8.114 0.291 29.736 1.00 28.81 C
+ATOM 234 SD MET A 108 9.353 1.517 30.215 1.00 29.93 S
+ATOM 235 CE MET A 108 8.961 2.819 29.081 1.00 25.56 C
+ATOM 236 N VAL A 109 4.018 -0.548 31.061 1.00 28.08 N
+ATOM 237 CA VAL A 109 2.800 -0.421 31.854 1.00 26.73 C
+ATOM 238 C VAL A 109 3.133 0.448 33.071 1.00 27.23 C
+ATOM 239 O VAL A 109 4.143 0.222 33.734 1.00 27.51 O
+ATOM 240 CB VAL A 109 2.322 -1.795 32.370 1.00 27.03 C
+ATOM 241 CG1 VAL A 109 1.071 -1.623 33.223 1.00 24.38 C
+ATOM 242 CG2 VAL A 109 2.045 -2.731 31.195 1.00 34.35 C
+ATOM 243 N VAL A 110 2.289 1.431 33.368 1.00 28.59 N
+ATOM 244 CA VAL A 110 2.522 2.310 34.514 1.00 29.57 C
+ATOM 245 C VAL A 110 1.962 1.724 35.815 1.00 29.27 C
+ATOM 246 O VAL A 110 0.766 1.440 35.910 1.00 30.35 O
+ATOM 247 CB VAL A 110 1.889 3.696 34.284 1.00 30.69 C
+ATOM 248 CG1 VAL A 110 2.107 4.571 35.505 1.00 27.01 C
+ATOM 249 CG2 VAL A 110 2.491 4.343 33.041 1.00 31.83 C
+ATOM 250 N LEU A 111 2.826 1.550 36.815 1.00 28.85 N
+ATOM 251 CA LEU A 111 2.401 0.989 38.098 1.00 30.67 C
+ATOM 252 C LEU A 111 2.126 2.060 39.150 1.00 33.88 C
+ATOM 253 O LEU A 111 1.167 1.955 39.910 1.00 32.75 O
+ATOM 254 CB LEU A 111 3.452 0.024 38.641 1.00 29.69 C
+ATOM 255 CG LEU A 111 4.001 -1.058 37.711 1.00 28.40 C
+ATOM 256 CD1 LEU A 111 4.770 -2.068 38.569 1.00 27.76 C
+ATOM 257 CD2 LEU A 111 2.876 -1.754 36.955 1.00 31.48 C
+ATOM 258 N GLU A 112 2.987 3.072 39.207 1.00 35.09 N
+ATOM 259 CA GLU A 112 2.831 4.179 40.149 1.00 36.06 C
+ATOM 260 C GLU A 112 3.113 5.449 39.377 1.00 37.76 C
+ATOM 261 O GLU A 112 4.098 5.532 38.644 1.00 32.94 O
+ATOM 262 CB GLU A 112 3.815 4.080 41.317 1.00 37.39 C
+ATOM 263 CG GLU A 112 3.629 2.872 42.217 1.00 43.66 C
+ATOM 264 CD GLU A 112 4.670 2.807 43.329 1.00 48.09 C
+ATOM 265 OE1 GLU A 112 4.674 1.806 44.081 1.00 51.07 O
+ATOM 266 OE2 GLU A 112 5.480 3.756 43.450 1.00 44.57 O
+ATOM 267 N GLU A 113 2.246 6.436 39.548 1.00 39.43 N
+ATOM 268 CA GLU A 113 2.387 7.703 38.853 1.00 44.22 C
+ATOM 269 C GLU A 113 2.798 8.760 39.881 1.00 45.95 C
+ATOM 270 O GLU A 113 2.070 9.718 40.138 1.00 47.48 O
+ATOM 271 CB GLU A 113 1.050 8.037 38.188 1.00 46.63 C
+ATOM 272 CG GLU A 113 1.101 9.108 37.125 1.00 52.38 C
+ATOM 273 CD GLU A 113 -0.187 9.176 36.325 1.00 55.07 C
+ATOM 274 OE1 GLU A 113 -0.534 8.175 35.659 1.00 55.80 O
+ATOM 275 OE2 GLU A 113 -0.855 10.229 36.362 1.00 60.95 O
+ATOM 276 N SER A 114 3.986 8.567 40.452 1.00 47.39 N
+ATOM 277 CA SER A 114 4.537 9.445 41.482 1.00 49.04 C
+ATOM 278 C SER A 114 5.346 10.656 40.999 1.00 48.27 C
+ATOM 279 O SER A 114 6.543 10.759 41.273 1.00 51.26 O
+ATOM 280 CB SER A 114 5.412 8.621 42.434 1.00 52.89 C
+ATOM 281 OG SER A 114 4.691 7.538 43.000 1.00 57.97 O
+ATOM 282 N GLY A 116 4.700 11.572 40.288 1.00 45.70 N
+ATOM 283 CA GLY A 116 5.391 12.765 39.827 1.00 42.46 C
+ATOM 284 C GLY A 116 6.474 12.618 38.771 1.00 40.60 C
+ATOM 285 O GLY A 116 6.242 12.079 37.690 1.00 39.85 O
+ATOM 286 N GLU A 117 7.670 13.102 39.094 1.00 38.51 N
+ATOM 287 CA GLU A 117 8.800 13.077 38.166 1.00 35.67 C
+ATOM 288 C GLU A 117 9.235 11.669 37.773 1.00 32.76 C
+ATOM 289 O GLU A 117 9.690 11.441 36.652 1.00 31.67 O
+ATOM 290 CB GLU A 117 9.970 13.850 38.776 1.00 41.01 C
+ATOM 291 CG GLU A 117 11.043 14.255 37.786 1.00 44.24 C
+ATOM 292 CD GLU A 117 11.948 15.339 38.347 1.00 47.88 C
+ATOM 293 OE1 GLU A 117 12.714 15.059 39.298 1.00 47.58 O
+ATOM 294 OE2 GLU A 117 11.869 16.482 37.843 1.00 46.83 O
+ATOM 295 N TRP A 118 9.108 10.731 38.704 1.00 29.96 N
+ATOM 296 CA TRP A 118 9.447 9.342 38.435 1.00 29.82 C
+ATOM 297 C TRP A 118 8.205 8.476 38.550 1.00 30.69 C
+ATOM 298 O TRP A 118 7.371 8.680 39.438 1.00 30.12 O
+ATOM 299 CB TRP A 118 10.498 8.809 39.416 1.00 29.55 C
+ATOM 300 CG TRP A 118 11.822 9.459 39.292 1.00 27.62 C
+ATOM 301 CD1 TRP A 118 12.194 10.673 39.795 1.00 28.09 C
+ATOM 302 CD2 TRP A 118 12.944 8.965 38.555 1.00 27.54 C
+ATOM 303 NE1 TRP A 118 13.484 10.965 39.415 1.00 28.45 N
+ATOM 304 CE2 TRP A 118 13.966 9.936 38.651 1.00 28.22 C
+ATOM 305 CE3 TRP A 118 13.184 7.796 37.818 1.00 27.52 C
+ATOM 306 CZ2 TRP A 118 15.217 9.771 38.038 1.00 28.75 C
+ATOM 307 CZ3 TRP A 118 14.428 7.633 37.205 1.00 28.79 C
+ATOM 308 CH2 TRP A 118 15.428 8.620 37.321 1.00 28.51 C
+ATOM 309 N TRP A 119 8.089 7.513 37.642 1.00 27.86 N
+ATOM 310 CA TRP A 119 6.974 6.579 37.642 1.00 29.23 C
+ATOM 311 C TRP A 119 7.520 5.168 37.766 1.00 28.43 C
+ATOM 312 O TRP A 119 8.601 4.865 37.260 1.00 30.10 O
+ATOM 313 CB TRP A 119 6.174 6.678 36.341 1.00 27.68 C
+ATOM 314 CG TRP A 119 5.389 7.934 36.172 1.00 31.57 C
+ATOM 315 CD1 TRP A 119 5.365 9.015 37.007 1.00 32.31 C
+ATOM 316 CD2 TRP A 119 4.499 8.238 35.095 1.00 30.83 C
+ATOM 317 NE1 TRP A 119 4.511 9.973 36.516 1.00 29.13 N
+ATOM 318 CE2 TRP A 119 3.967 9.522 35.345 1.00 31.85 C
+ATOM 319 CE3 TRP A 119 4.098 7.548 33.944 1.00 33.26 C
+ATOM 320 CZ2 TRP A 119 3.051 10.131 34.481 1.00 32.84 C
+ATOM 321 CZ3 TRP A 119 3.190 8.155 33.086 1.00 34.38 C
+ATOM 322 CH2 TRP A 119 2.676 9.436 33.362 1.00 33.25 C
+ATOM 323 N LYS A 120 6.782 4.306 38.451 1.00 28.41 N
+ATOM 324 CA LYS A 120 7.199 2.924 38.582 1.00 29.98 C
+ATOM 325 C LYS A 120 6.518 2.250 37.401 1.00 28.62 C
+ATOM 326 O LYS A 120 5.310 2.380 37.226 1.00 26.36 O
+ATOM 327 CB LYS A 120 6.712 2.321 39.904 1.00 32.23 C
+ATOM 328 CG LYS A 120 7.267 0.921 40.157 1.00 36.61 C
+ATOM 329 CD LYS A 120 6.930 0.399 41.547 1.00 38.85 C
+ATOM 330 CE LYS A 120 7.595 -0.955 41.792 1.00 42.51 C
+ATOM 331 NZ LYS A 120 7.334 -1.486 43.162 1.00 42.00 N
+ATOM 332 N ALA A 121 7.294 1.558 36.576 1.00 29.39 N
+ATOM 333 CA ALA A 121 6.735 0.902 35.402 1.00 30.73 C
+ATOM 334 C ALA A 121 7.155 -0.550 35.276 1.00 32.55 C
+ATOM 335 O ALA A 121 7.969 -1.054 36.055 1.00 30.55 O
+ATOM 336 CB ALA A 121 7.135 1.661 34.142 1.00 30.38 C
+ATOM 337 N ARG A 122 6.588 -1.207 34.272 1.00 32.21 N
+ATOM 338 CA ARG A 122 6.857 -2.608 33.998 1.00 34.01 C
+ATOM 339 C ARG A 122 7.136 -2.775 32.512 1.00 33.47 C
+ATOM 340 O ARG A 122 6.379 -2.296 31.677 1.00 31.42 O
+ATOM 341 CB ARG A 122 5.642 -3.447 34.390 1.00 37.44 C
+ATOM 342 CG ARG A 122 5.743 -4.916 34.026 1.00 43.03 C
+ATOM 343 CD ARG A 122 4.461 -5.649 34.385 1.00 40.41 C
+ATOM 344 NE ARG A 122 4.167 -5.550 35.812 1.00 45.50 N
+ATOM 345 CZ ARG A 122 3.091 -4.957 36.313 1.00 46.83 C
+ATOM 346 NH1 ARG A 122 2.198 -4.405 35.499 1.00 48.08 N
+ATOM 347 NH2 ARG A 122 2.884 -4.943 37.626 1.00 47.66 N
+ATOM 348 N SER A 123 8.227 -3.454 32.185 1.00 37.44 N
+ATOM 349 CA SER A 123 8.584 -3.679 30.790 1.00 42.30 C
+ATOM 350 C SER A 123 7.759 -4.808 30.183 1.00 44.87 C
+ATOM 351 O SER A 123 7.747 -5.922 30.706 1.00 44.72 O
+ATOM 352 CB SER A 123 10.072 -4.026 30.672 1.00 43.18 C
+ATOM 353 OG SER A 123 10.415 -4.351 29.334 1.00 44.42 O
+ATOM 354 N LEU A 124 7.066 -4.515 29.085 1.00 47.41 N
+ATOM 355 CA LEU A 124 6.266 -5.524 28.400 1.00 49.82 C
+ATOM 356 C LEU A 124 7.193 -6.558 27.772 1.00 53.82 C
+ATOM 357 O LEU A 124 6.757 -7.626 27.348 1.00 54.71 O
+ATOM 358 CB LEU A 124 5.402 -4.887 27.307 1.00 48.16 C
+ATOM 359 CG LEU A 124 4.156 -4.098 27.711 1.00 45.76 C
+ATOM 360 CD1 LEU A 124 4.519 -2.998 28.680 1.00 48.82 C
+ATOM 361 CD2 LEU A 124 3.505 -3.526 26.468 1.00 43.90 C
+ATOM 362 N ALA A 125 8.478 -6.229 27.709 1.00 56.29 N
+ATOM 363 CA ALA A 125 9.463 -7.133 27.135 1.00 57.66 C
+ATOM 364 C ALA A 125 9.987 -8.090 28.201 1.00 58.58 C
+ATOM 365 O ALA A 125 9.558 -9.241 28.286 1.00 59.91 O
+ATOM 366 CB ALA A 125 10.614 -6.334 26.534 1.00 58.46 C
+ATOM 367 N THR A 126 10.907 -7.598 29.022 1.00 59.72 N
+ATOM 368 CA THR A 126 11.515 -8.396 30.080 1.00 60.28 C
+ATOM 369 C THR A 126 10.619 -8.533 31.304 1.00 59.30 C
+ATOM 370 O THR A 126 11.006 -9.154 32.295 1.00 57.97 O
+ATOM 371 CB THR A 126 12.846 -7.770 30.537 1.00 61.26 C
+ATOM 372 OG1 THR A 126 12.597 -6.473 31.095 1.00 61.67 O
+ATOM 373 CG2 THR A 126 13.796 -7.628 29.359 1.00 61.98 C
+ATOM 374 N ARG A 127 9.424 -7.956 31.234 1.00 59.62 N
+ATOM 375 CA ARG A 127 8.493 -7.998 32.355 1.00 58.74 C
+ATOM 376 C ARG A 127 9.112 -7.449 33.628 1.00 56.83 C
+ATOM 377 O ARG A 127 8.579 -7.649 34.720 1.00 56.32 O
+ATOM 378 CB ARG A 127 8.000 -9.425 32.603 1.00 62.05 C
+ATOM 379 CG ARG A 127 6.875 -9.847 31.680 1.00 65.69 C
+ATOM 380 CD ARG A 127 5.665 -8.936 31.875 1.00 70.08 C
+ATOM 381 NE ARG A 127 4.530 -9.320 31.039 1.00 73.85 N
+ATOM 382 CZ ARG A 127 4.564 -9.385 29.712 1.00 74.78 C
+ATOM 383 NH1 ARG A 127 5.679 -9.088 29.061 1.00 75.74 N
+ATOM 384 NH2 ARG A 127 3.482 -9.745 29.033 1.00 75.75 N
+ATOM 385 N LYS A 128 10.237 -6.755 33.492 1.00 53.42 N
+ATOM 386 CA LYS A 128 10.895 -6.189 34.659 1.00 51.16 C
+ATOM 387 C LYS A 128 10.237 -4.886 35.095 1.00 47.04 C
+ATOM 388 O LYS A 128 9.660 -4.161 34.285 1.00 43.08 O
+ATOM 389 CB LYS A 128 12.386 -5.969 34.387 1.00 53.49 C
+ATOM 390 CG LYS A 128 13.151 -5.392 35.580 1.00 57.21 C
+ATOM 391 CD LYS A 128 12.784 -6.097 36.893 1.00 60.48 C
+ATOM 392 CE LYS A 128 13.005 -7.604 36.830 1.00 62.93 C
+ATOM 393 NZ LYS A 128 12.573 -8.274 38.090 1.00 63.07 N
+ATOM 394 N GLU A 129 10.328 -4.601 36.388 1.00 45.96 N
+ATOM 395 CA GLU A 129 9.730 -3.404 36.951 1.00 43.60 C
+ATOM 396 C GLU A 129 10.797 -2.491 37.537 1.00 41.53 C
+ATOM 397 O GLU A 129 11.820 -2.955 38.043 1.00 41.05 O
+ATOM 398 CB GLU A 129 8.716 -3.800 38.025 1.00 44.33 C
+ATOM 399 CG GLU A 129 7.702 -4.823 37.526 1.00 49.93 C
+ATOM 400 CD GLU A 129 6.671 -5.207 38.568 1.00 52.79 C
+ATOM 401 OE1 GLU A 129 7.066 -5.602 39.683 1.00 57.09 O
+ATOM 402 OE2 GLU A 129 5.463 -5.128 38.267 1.00 56.77 O
+ATOM 403 N GLY A 130 10.547 -1.188 37.454 1.00 37.50 N
+ATOM 404 CA GLY A 130 11.479 -0.204 37.972 1.00 34.21 C
+ATOM 405 C GLY A 130 10.943 1.202 37.774 1.00 32.56 C
+ATOM 406 O GLY A 130 9.857 1.384 37.215 1.00 31.59 O
+ATOM 407 N TYR A 131 11.690 2.202 38.233 1.00 27.16 N
+ATOM 408 CA TYR A 131 11.262 3.588 38.087 1.00 29.35 C
+ATOM 409 C TYR A 131 11.823 4.187 36.808 1.00 26.19 C
+ATOM 410 O TYR A 131 12.963 3.918 36.440 1.00 27.68 O
+ATOM 411 CB TYR A 131 11.712 4.404 39.299 1.00 33.03 C
+ATOM 412 CG TYR A 131 11.035 3.974 40.580 1.00 36.29 C
+ATOM 413 CD1 TYR A 131 9.692 4.274 40.817 1.00 39.72 C
+ATOM 414 CD2 TYR A 131 11.724 3.234 41.539 1.00 39.16 C
+ATOM 415 CE1 TYR A 131 9.050 3.847 41.981 1.00 40.43 C
+ATOM 416 CE2 TYR A 131 11.093 2.800 42.705 1.00 41.97 C
+ATOM 417 CZ TYR A 131 9.756 3.108 42.918 1.00 42.45 C
+ATOM 418 OH TYR A 131 9.119 2.658 44.056 1.00 45.56 O
+ATOM 419 N ILE A 132 11.007 4.994 36.135 1.00 25.50 N
+ATOM 420 CA ILE A 132 11.395 5.641 34.884 1.00 22.51 C
+ATOM 421 C ILE A 132 11.040 7.123 34.945 1.00 21.76 C
+ATOM 422 O ILE A 132 10.174 7.525 35.723 1.00 22.68 O
+ATOM 423 CB ILE A 132 10.638 5.042 33.688 1.00 24.59 C
+ATOM 424 CG1 ILE A 132 9.129 5.291 33.855 1.00 25.52 C
+ATOM 425 CG2 ILE A 132 10.945 3.555 33.580 1.00 26.72 C
+ATOM 426 CD1 ILE A 132 8.277 4.849 32.676 1.00 25.75 C
+ATOM 427 N PRO A 133 11.721 7.958 34.138 1.00 22.49 N
+ATOM 428 CA PRO A 133 11.486 9.405 34.076 1.00 20.96 C
+ATOM 429 C PRO A 133 10.140 9.620 33.398 1.00 22.88 C
+ATOM 430 O PRO A 133 9.963 9.199 32.263 1.00 22.46 O
+ATOM 431 CB PRO A 133 12.632 9.894 33.189 1.00 22.15 C
+ATOM 432 CG PRO A 133 13.689 8.812 33.361 1.00 24.09 C
+ATOM 433 CD PRO A 133 12.819 7.604 33.225 1.00 21.64 C
+ATOM 434 N SER A 134 9.199 10.280 34.068 1.00 24.77 N
+ATOM 435 CA SER A 134 7.879 10.486 33.469 1.00 28.42 C
+ATOM 436 C SER A 134 7.885 11.311 32.180 1.00 30.00 C
+ATOM 437 O SER A 134 6.984 11.175 31.352 1.00 29.76 O
+ATOM 438 CB SER A 134 6.914 11.109 34.493 1.00 30.03 C
+ATOM 439 OG SER A 134 7.391 12.342 35.006 1.00 30.21 O
+ATOM 440 N ASN A 135 8.907 12.142 31.993 1.00 30.34 N
+ATOM 441 CA ASN A 135 8.989 12.985 30.799 1.00 31.08 C
+ATOM 442 C ASN A 135 9.609 12.264 29.602 1.00 29.07 C
+ATOM 443 O ASN A 135 9.748 12.841 28.524 1.00 31.80 O
+ATOM 444 CB ASN A 135 9.799 14.250 31.105 1.00 36.49 C
+ATOM 445 CG ASN A 135 11.276 13.968 31.254 1.00 37.56 C
+ATOM 446 OD1 ASN A 135 11.680 13.120 32.045 1.00 39.87 O
+ATOM 447 ND2 ASN A 135 12.093 14.682 30.491 1.00 47.17 N
+ATOM 448 N TYR A 136 9.991 11.006 29.793 1.00 24.92 N
+ATOM 449 CA TYR A 136 10.580 10.213 28.719 1.00 26.53 C
+ATOM 450 C TYR A 136 9.563 9.316 28.018 1.00 26.66 C
+ATOM 451 O TYR A 136 9.905 8.617 27.065 1.00 26.97 O
+ATOM 452 CB TYR A 136 11.704 9.331 29.264 1.00 25.28 C
+ATOM 453 CG TYR A 136 13.055 9.999 29.351 1.00 25.33 C
+ATOM 454 CD1 TYR A 136 13.227 11.209 30.027 1.00 29.90 C
+ATOM 455 CD2 TYR A 136 14.176 9.399 28.777 1.00 28.02 C
+ATOM 456 CE1 TYR A 136 14.493 11.803 30.128 1.00 25.77 C
+ATOM 457 CE2 TYR A 136 15.436 9.978 28.872 1.00 27.00 C
+ATOM 458 CZ TYR A 136 15.590 11.175 29.546 1.00 28.82 C
+ATOM 459 OH TYR A 136 16.846 11.727 29.640 1.00 30.24 O
+ATOM 460 N VAL A 137 8.322 9.332 28.493 1.00 29.13 N
+ATOM 461 CA VAL A 137 7.280 8.491 27.915 1.00 30.53 C
+ATOM 462 C VAL A 137 6.003 9.262 27.606 1.00 31.22 C
+ATOM 463 O VAL A 137 5.822 10.393 28.052 1.00 31.98 O
+ATOM 464 CB VAL A 137 6.922 7.323 28.868 1.00 28.48 C
+ATOM 465 CG1 VAL A 137 8.174 6.517 29.199 1.00 27.00 C
+ATOM 466 CG2 VAL A 137 6.280 7.859 30.132 1.00 24.25 C
+ATOM 467 N ALA A 138 5.110 8.634 26.846 1.00 33.46 N
+ATOM 468 CA ALA A 138 3.844 9.260 26.489 1.00 35.07 C
+ATOM 469 C ALA A 138 2.827 8.209 26.052 1.00 35.58 C
+ATOM 470 O ALA A 138 3.194 7.069 25.751 1.00 35.02 O
+ATOM 471 CB ALA A 138 4.064 10.277 25.369 1.00 35.23 C
+ATOM 472 N ARG A 139 1.553 8.593 26.026 1.00 39.77 N
+ATOM 473 CA ARG A 139 0.497 7.676 25.603 1.00 43.18 C
+ATOM 474 C ARG A 139 0.874 7.166 24.226 1.00 42.57 C
+ATOM 475 O ARG A 139 1.474 7.893 23.431 1.00 43.15 O
+ATOM 476 CB ARG A 139 -0.857 8.393 25.518 1.00 47.51 C
+ATOM 477 CG ARG A 139 -2.029 7.477 25.124 1.00 54.90 C
+ATOM 478 CD ARG A 139 -2.763 7.976 23.875 1.00 59.83 C
+ATOM 479 NE ARG A 139 -3.327 9.316 24.041 1.00 63.21 N
+ATOM 480 CZ ARG A 139 -3.949 9.994 23.077 1.00 65.78 C
+ATOM 481 NH1 ARG A 139 -4.089 9.462 21.870 1.00 66.48 N
+ATOM 482 NH2 ARG A 139 -4.427 11.208 23.317 1.00 67.91 N
+ATOM 483 N VAL A 140 0.524 5.920 23.937 1.00 41.18 N
+ATOM 484 CA VAL A 140 0.845 5.338 22.642 1.00 42.23 C
+ATOM 485 C VAL A 140 0.149 6.090 21.509 1.00 41.86 C
+ATOM 486 O VAL A 140 -0.977 6.558 21.664 1.00 37.75 O
+ATOM 487 CB VAL A 140 0.432 3.856 22.582 1.00 43.21 C
+ATOM 488 CG1 VAL A 140 0.810 3.270 21.232 1.00 46.12 C
+ATOM 489 CG2 VAL A 140 1.105 3.084 23.710 1.00 45.39 C
+ATOM 490 N ASP A 141 0.835 6.201 20.375 1.00 44.04 N
+ATOM 491 CA ASP A 141 0.307 6.893 19.199 1.00 46.01 C
+ATOM 492 C ASP A 141 -0.155 8.323 19.494 1.00 45.18 C
+ATOM 493 O ASP A 141 -0.796 8.958 18.659 1.00 46.61 O
+ATOM 494 CB ASP A 141 -0.846 6.087 18.586 1.00 47.67 C
+ATOM 495 CG ASP A 141 -1.453 6.766 17.368 1.00 53.70 C
+ATOM 496 OD1 ASP A 141 -0.705 7.048 16.404 1.00 56.22 O
+ATOM 497 OD2 ASP A 141 -2.678 7.021 17.374 1.00 55.21 O
+ATOM 498 N SER A 142 0.175 8.836 20.676 1.00 44.75 N
+ATOM 499 CA SER A 142 -0.223 10.193 21.026 1.00 40.56 C
+ATOM 500 C SER A 142 0.496 11.171 20.108 1.00 40.45 C
+ATOM 501 O SER A 142 1.394 10.794 19.355 1.00 38.84 O
+ATOM 502 CB SER A 142 0.115 10.506 22.486 1.00 43.21 C
+ATOM 503 OG SER A 142 1.513 10.490 22.707 1.00 44.57 O
+ATOM 504 N LEU A 143 0.100 12.433 20.181 1.00 37.92 N
+ATOM 505 CA LEU A 143 0.682 13.459 19.341 1.00 38.43 C
+ATOM 506 C LEU A 143 2.130 13.790 19.733 1.00 37.33 C
+ATOM 507 O LEU A 143 2.885 14.325 18.922 1.00 36.92 O
+ATOM 508 CB LEU A 143 -0.209 14.698 19.406 1.00 42.86 C
+ATOM 509 CG LEU A 143 -0.103 15.747 18.306 1.00 42.60 C
+ATOM 510 CD1 LEU A 143 -0.249 15.088 16.943 1.00 43.56 C
+ATOM 511 CD2 LEU A 143 -1.192 16.785 18.515 1.00 43.86 C
+ATOM 512 N GLU A 144 2.524 13.450 20.960 1.00 33.59 N
+ATOM 513 CA GLU A 144 3.885 13.721 21.423 1.00 33.90 C
+ATOM 514 C GLU A 144 4.907 12.742 20.866 1.00 30.61 C
+ATOM 515 O GLU A 144 6.103 12.902 21.104 1.00 29.05 O
+ATOM 516 CB GLU A 144 3.986 13.681 22.955 1.00 36.54 C
+ATOM 517 CG GLU A 144 3.033 14.592 23.692 1.00 43.36 C
+ATOM 518 CD GLU A 144 1.662 13.977 23.860 1.00 47.09 C
+ATOM 519 OE1 GLU A 144 1.553 12.993 24.622 1.00 50.21 O
+ATOM 520 OE2 GLU A 144 0.698 14.462 23.232 1.00 49.26 O
+ATOM 521 N THR A 145 4.446 11.727 20.141 1.00 27.90 N
+ATOM 522 CA THR A 145 5.356 10.735 19.576 1.00 29.17 C
+ATOM 523 C THR A 145 5.897 11.148 18.209 1.00 31.65 C
+ATOM 524 O THR A 145 6.795 10.496 17.669 1.00 34.12 O
+ATOM 525 CB THR A 145 4.673 9.357 19.420 1.00 29.72 C
+ATOM 526 OG1 THR A 145 3.556 9.474 18.529 1.00 25.91 O
+ATOM 527 CG2 THR A 145 4.186 8.843 20.768 1.00 28.80 C
+ATOM 528 N GLU A 146 5.352 12.227 17.653 1.00 30.68 N
+ATOM 529 CA GLU A 146 5.781 12.712 16.341 1.00 33.04 C
+ATOM 530 C GLU A 146 6.996 13.628 16.437 1.00 32.95 C
+ATOM 531 O GLU A 146 7.146 14.377 17.401 1.00 31.72 O
+ATOM 532 CB GLU A 146 4.640 13.462 15.653 1.00 36.81 C
+ATOM 533 CG GLU A 146 3.381 12.637 15.415 1.00 39.10 C
+ATOM 534 CD GLU A 146 3.588 11.490 14.437 1.00 43.96 C
+ATOM 535 OE1 GLU A 146 2.598 10.784 14.143 1.00 45.04 O
+ATOM 536 OE2 GLU A 146 4.729 11.294 13.961 1.00 44.83 O
+ATOM 537 N GLU A 147 7.853 13.566 15.420 1.00 33.78 N
+ATOM 538 CA GLU A 147 9.068 14.370 15.364 1.00 35.16 C
+ATOM 539 C GLU A 147 8.770 15.853 15.159 1.00 32.58 C
+ATOM 540 O GLU A 147 9.519 16.716 15.611 1.00 31.37 O
+ATOM 541 CB GLU A 147 9.966 13.871 14.225 1.00 40.20 C
+ATOM 542 CG GLU A 147 9.300 13.944 12.843 1.00 48.61 C
+ATOM 543 CD GLU A 147 10.202 13.469 11.708 1.00 50.30 C
+ATOM 544 OE1 GLU A 147 10.629 12.294 11.728 1.00 53.72 O
+ATOM 545 OE2 GLU A 147 10.481 14.272 10.792 1.00 50.02 O
+ATOM 546 N TRP A 148 7.667 16.140 14.478 1.00 30.99 N
+ATOM 547 CA TRP A 148 7.278 17.513 14.188 1.00 29.81 C
+ATOM 548 C TRP A 148 6.376 18.196 15.220 1.00 29.32 C
+ATOM 549 O TRP A 148 6.019 19.362 15.042 1.00 27.96 O
+ATOM 550 CB TRP A 148 6.612 17.580 12.804 1.00 27.93 C
+ATOM 551 CG TRP A 148 5.597 16.496 12.555 1.00 28.85 C
+ATOM 552 CD1 TRP A 148 5.796 15.332 11.868 1.00 30.04 C
+ATOM 553 CD2 TRP A 148 4.251 16.438 13.057 1.00 27.69 C
+ATOM 554 NE1 TRP A 148 4.661 14.555 11.910 1.00 26.85 N
+ATOM 555 CE2 TRP A 148 3.699 15.208 12.633 1.00 28.32 C
+ATOM 556 CE3 TRP A 148 3.461 17.306 13.822 1.00 26.17 C
+ATOM 557 CZ2 TRP A 148 2.386 14.821 12.950 1.00 27.06 C
+ATOM 558 CZ3 TRP A 148 2.157 16.921 14.140 1.00 29.62 C
+ATOM 559 CH2 TRP A 148 1.634 15.685 13.701 1.00 25.27 C
+ATOM 560 N PHE A 149 6.011 17.498 16.294 1.00 26.07 N
+ATOM 561 CA PHE A 149 5.147 18.110 17.305 1.00 26.00 C
+ATOM 562 C PHE A 149 5.932 18.502 18.552 1.00 28.15 C
+ATOM 563 O PHE A 149 6.750 17.731 19.054 1.00 25.70 O
+ATOM 564 CB PHE A 149 4.018 17.158 17.717 1.00 22.29 C
+ATOM 565 CG PHE A 149 2.939 17.821 18.540 1.00 27.23 C
+ATOM 566 CD1 PHE A 149 2.010 18.672 17.942 1.00 30.01 C
+ATOM 567 CD2 PHE A 149 2.883 17.638 19.915 1.00 23.13 C
+ATOM 568 CE1 PHE A 149 1.041 19.331 18.709 1.00 28.70 C
+ATOM 569 CE2 PHE A 149 1.921 18.292 20.686 1.00 26.85 C
+ATOM 570 CZ PHE A 149 1.002 19.138 20.083 1.00 26.71 C
+ATOM 571 N PHE A 150 5.687 19.712 19.044 1.00 28.23 N
+ATOM 572 CA PHE A 150 6.354 20.189 20.248 1.00 31.12 C
+ATOM 573 C PHE A 150 5.312 20.528 21.300 1.00 31.48 C
+ATOM 574 O PHE A 150 4.665 21.570 21.242 1.00 31.75 O
+ATOM 575 CB PHE A 150 7.222 21.413 19.941 1.00 31.13 C
+ATOM 576 CG PHE A 150 8.474 21.084 19.184 1.00 30.73 C
+ATOM 577 CD1 PHE A 150 8.412 20.600 17.885 1.00 30.10 C
+ATOM 578 CD2 PHE A 150 9.718 21.218 19.790 1.00 31.91 C
+ATOM 579 CE1 PHE A 150 9.567 20.252 17.199 1.00 31.38 C
+ATOM 580 CE2 PHE A 150 10.882 20.870 19.109 1.00 32.77 C
+ATOM 581 CZ PHE A 150 10.807 20.387 17.815 1.00 29.83 C
+ATOM 582 N LYS A 151 5.166 19.635 22.269 1.00 32.95 N
+ATOM 583 CA LYS A 151 4.184 19.796 23.330 1.00 34.22 C
+ATOM 584 C LYS A 151 4.542 20.828 24.391 1.00 36.50 C
+ATOM 585 O LYS A 151 5.694 20.927 24.824 1.00 38.35 O
+ATOM 586 CB LYS A 151 3.948 18.449 24.010 1.00 36.11 C
+ATOM 587 CG LYS A 151 2.898 18.468 25.107 1.00 37.44 C
+ATOM 588 CD LYS A 151 2.807 17.098 25.748 1.00 42.34 C
+ATOM 589 CE LYS A 151 1.685 17.017 26.762 1.00 45.51 C
+ATOM 590 NZ LYS A 151 1.620 15.655 27.371 1.00 49.26 N
+ATOM 591 N GLY A 152 3.533 21.589 24.801 1.00 34.34 N
+ATOM 592 CA GLY A 152 3.700 22.594 25.835 1.00 37.16 C
+ATOM 593 C GLY A 152 4.665 23.742 25.605 1.00 37.54 C
+ATOM 594 O GLY A 152 5.125 24.348 26.570 1.00 42.89 O
+ATOM 595 N ILE A 153 4.984 24.059 24.354 1.00 35.48 N
+ATOM 596 CA ILE A 153 5.904 25.165 24.094 1.00 31.70 C
+ATOM 597 C ILE A 153 5.107 26.395 23.661 1.00 31.59 C
+ATOM 598 O ILE A 153 4.214 26.305 22.818 1.00 32.46 O
+ATOM 599 CB ILE A 153 6.937 24.797 22.999 1.00 29.71 C
+ATOM 600 CG1 ILE A 153 7.982 25.906 22.873 1.00 28.86 C
+ATOM 601 CG2 ILE A 153 6.235 24.597 21.663 1.00 28.20 C
+ATOM 602 CD1 ILE A 153 9.083 25.598 21.889 1.00 29.43 C
+ATOM 603 N SER A 154 5.418 27.542 24.251 1.00 27.09 N
+ATOM 604 CA SER A 154 4.716 28.781 23.927 1.00 26.96 C
+ATOM 605 C SER A 154 5.199 29.353 22.600 1.00 26.46 C
+ATOM 606 O SER A 154 6.224 28.928 22.064 1.00 27.25 O
+ATOM 607 CB SER A 154 4.979 29.827 25.004 1.00 26.22 C
+ATOM 608 OG SER A 154 6.347 30.199 24.972 1.00 22.54 O
+ATOM 609 N ARG A 155 4.461 30.328 22.080 1.00 25.24 N
+ATOM 610 CA ARG A 155 4.845 30.988 20.839 1.00 25.60 C
+ATOM 611 C ARG A 155 6.261 31.560 20.957 1.00 22.61 C
+ATOM 612 O ARG A 155 7.114 31.292 20.116 1.00 22.83 O
+ATOM 613 CB ARG A 155 3.877 32.129 20.524 1.00 29.33 C
+ATOM 614 CG ARG A 155 4.426 33.144 19.518 1.00 31.78 C
+ATOM 615 CD ARG A 155 3.545 34.377 19.479 1.00 37.38 C
+ATOM 616 NE ARG A 155 2.299 34.106 18.786 1.00 42.94 N
+ATOM 617 CZ ARG A 155 2.072 34.426 17.517 1.00 49.13 C
+ATOM 618 NH1 ARG A 155 3.012 35.036 16.800 1.00 50.45 N
+ATOM 619 NH2 ARG A 155 0.917 34.104 16.954 1.00 47.33 N
+ATOM 620 N LYS A 156 6.507 32.349 22.000 1.00 23.34 N
+ATOM 621 CA LYS A 156 7.822 32.958 22.186 1.00 21.61 C
+ATOM 622 C LYS A 156 8.945 31.936 22.252 1.00 22.00 C
+ATOM 623 O LYS A 156 9.993 32.133 21.639 1.00 22.71 O
+ATOM 624 CB LYS A 156 7.853 33.827 23.453 1.00 26.67 C
+ATOM 625 CG LYS A 156 6.870 34.992 23.445 1.00 30.17 C
+ATOM 626 CD LYS A 156 7.119 35.954 22.291 1.00 29.17 C
+ATOM 627 CE LYS A 156 8.498 36.576 22.358 1.00 32.79 C
+ATOM 628 NZ LYS A 156 8.671 37.582 21.279 1.00 39.05 N
+ATOM 629 N ASP A 157 8.756 30.855 23.004 1.00 18.64 N
+ATOM 630 CA ASP A 157 9.811 29.853 23.074 1.00 19.52 C
+ATOM 631 C ASP A 157 9.963 29.121 21.742 1.00 19.65 C
+ATOM 632 O ASP A 157 11.064 28.713 21.370 1.00 20.67 O
+ATOM 633 CB ASP A 157 9.573 28.851 24.212 1.00 21.10 C
+ATOM 634 CG ASP A 157 9.858 29.449 25.588 1.00 24.07 C
+ATOM 635 OD1 ASP A 157 10.818 30.236 25.712 1.00 23.34 O
+ATOM 636 OD2 ASP A 157 9.145 29.108 26.551 1.00 26.01 O
+ATOM 637 N ALA A 158 8.861 28.947 21.020 1.00 18.35 N
+ATOM 638 CA ALA A 158 8.940 28.305 19.712 1.00 21.49 C
+ATOM 639 C ALA A 158 9.867 29.159 18.839 1.00 22.27 C
+ATOM 640 O ALA A 158 10.682 28.630 18.087 1.00 23.96 O
+ATOM 641 CB ALA A 158 7.555 28.219 19.080 1.00 22.26 C
+ATOM 642 N GLU A 159 9.753 30.482 18.951 1.00 24.93 N
+ATOM 643 CA GLU A 159 10.597 31.371 18.149 1.00 24.98 C
+ATOM 644 C GLU A 159 12.064 31.256 18.545 1.00 24.37 C
+ATOM 645 O GLU A 159 12.942 31.153 17.687 1.00 23.37 O
+ATOM 646 CB GLU A 159 10.176 32.837 18.301 1.00 23.58 C
+ATOM 647 CG GLU A 159 8.683 33.090 18.234 1.00 31.01 C
+ATOM 648 CD GLU A 159 8.341 34.574 18.234 1.00 32.24 C
+ATOM 649 OE1 GLU A 159 9.054 35.363 18.894 1.00 30.99 O
+ATOM 650 OE2 GLU A 159 7.338 34.947 17.592 1.00 34.52 O
+ATOM 651 N ARG A 160 12.331 31.292 19.847 1.00 23.25 N
+ATOM 652 CA ARG A 160 13.703 31.203 20.341 1.00 24.41 C
+ATOM 653 C ARG A 160 14.381 29.891 19.930 1.00 24.72 C
+ATOM 654 O ARG A 160 15.550 29.877 19.554 1.00 24.71 O
+ATOM 655 CB ARG A 160 13.717 31.356 21.875 1.00 24.73 C
+ATOM 656 CG ARG A 160 13.167 32.703 22.353 1.00 22.51 C
+ATOM 657 CD ARG A 160 12.850 32.739 23.854 1.00 20.93 C
+ATOM 658 NE ARG A 160 12.272 34.032 24.225 1.00 17.83 N
+ATOM 659 CZ ARG A 160 11.259 34.195 25.072 1.00 16.64 C
+ATOM 660 NH1 ARG A 160 10.698 33.146 25.650 1.00 19.48 N
+ATOM 661 NH2 ARG A 160 10.786 35.411 25.320 1.00 19.45 N
+ATOM 662 N GLN A 161 13.658 28.783 20.001 1.00 25.14 N
+ATOM 663 CA GLN A 161 14.257 27.507 19.632 1.00 26.24 C
+ATOM 664 C GLN A 161 14.495 27.393 18.126 1.00 26.68 C
+ATOM 665 O GLN A 161 15.554 26.935 17.693 1.00 24.90 O
+ATOM 666 CB GLN A 161 13.395 26.361 20.168 1.00 27.88 C
+ATOM 667 CG GLN A 161 13.525 26.235 21.689 1.00 32.29 C
+ATOM 668 CD GLN A 161 12.566 25.236 22.310 1.00 35.38 C
+ATOM 669 OE1 GLN A 161 12.342 24.150 21.771 1.00 33.43 O
+ATOM 670 NE2 GLN A 161 12.017 25.590 23.474 1.00 34.45 N
+ATOM 671 N LEU A 162 13.528 27.821 17.323 1.00 25.41 N
+ATOM 672 CA LEU A 162 13.697 27.769 15.871 1.00 26.57 C
+ATOM 673 C LEU A 162 14.817 28.694 15.395 1.00 26.94 C
+ATOM 674 O LEU A 162 15.490 28.406 14.404 1.00 29.55 O
+ATOM 675 CB LEU A 162 12.389 28.140 15.165 1.00 22.12 C
+ATOM 676 CG LEU A 162 11.361 27.017 15.053 1.00 25.00 C
+ATOM 677 CD1 LEU A 162 10.021 27.556 14.584 1.00 22.00 C
+ATOM 678 CD2 LEU A 162 11.897 25.967 14.095 1.00 26.73 C
+ATOM 679 N LEU A 163 15.021 29.801 16.103 1.00 28.75 N
+ATOM 680 CA LEU A 163 16.057 30.758 15.727 1.00 31.72 C
+ATOM 681 C LEU A 163 17.438 30.366 16.234 1.00 33.50 C
+ATOM 682 O LEU A 163 18.444 30.942 15.823 1.00 31.53 O
+ATOM 683 CB LEU A 163 15.695 32.156 16.236 1.00 30.22 C
+ATOM 684 CG LEU A 163 14.481 32.837 15.595 1.00 28.90 C
+ATOM 685 CD1 LEU A 163 14.189 34.139 16.329 1.00 30.83 C
+ATOM 686 CD2 LEU A 163 14.746 33.101 14.112 1.00 33.00 C
+ATOM 687 N ALA A 164 17.484 29.386 17.128 1.00 36.39 N
+ATOM 688 CA ALA A 164 18.752 28.925 17.679 1.00 39.13 C
+ATOM 689 C ALA A 164 19.612 28.353 16.561 1.00 41.48 C
+ATOM 690 O ALA A 164 19.099 27.822 15.577 1.00 41.54 O
+ATOM 691 CB ALA A 164 18.509 27.862 18.743 1.00 38.23 C
+ATOM 692 N PRO A 165 20.940 28.453 16.699 1.00 44.18 N
+ATOM 693 CA PRO A 165 21.845 27.931 15.676 1.00 46.13 C
+ATOM 694 C PRO A 165 21.648 26.430 15.486 1.00 46.36 C
+ATOM 695 O PRO A 165 21.467 25.696 16.455 1.00 48.25 O
+ATOM 696 CB PRO A 165 23.222 28.276 16.246 1.00 47.44 C
+ATOM 697 CG PRO A 165 22.925 29.543 17.057 1.00 47.17 C
+ATOM 698 CD PRO A 165 21.717 29.043 17.800 1.00 45.55 C
+ATOM 699 N GLY A 166 21.679 25.977 14.238 1.00 45.67 N
+ATOM 700 CA GLY A 166 21.506 24.561 13.976 1.00 44.65 C
+ATOM 701 C GLY A 166 20.260 24.303 13.163 1.00 42.49 C
+ATOM 702 O GLY A 166 20.095 23.236 12.575 1.00 45.65 O
+ATOM 703 N ASN A 167 19.369 25.284 13.142 1.00 38.56 N
+ATOM 704 CA ASN A 167 18.138 25.165 12.382 1.00 34.97 C
+ATOM 705 C ASN A 167 18.357 25.830 11.038 1.00 36.44 C
+ATOM 706 O ASN A 167 19.352 26.524 10.831 1.00 30.76 O
+ATOM 707 CB ASN A 167 16.989 25.839 13.128 1.00 33.59 C
+ATOM 708 CG ASN A 167 16.651 25.129 14.422 1.00 33.28 C
+ATOM 709 OD1 ASN A 167 16.162 23.999 14.410 1.00 31.22 O
+ATOM 710 ND2 ASN A 167 16.930 25.779 15.548 1.00 26.31 N
+ATOM 711 N MET A 168 17.423 25.625 10.124 1.00 36.40 N
+ATOM 712 CA MET A 168 17.565 26.213 8.815 1.00 40.60 C
+ATOM 713 C MET A 168 16.271 26.772 8.270 1.00 38.86 C
+ATOM 714 O MET A 168 15.203 26.658 8.873 1.00 35.45 O
+ATOM 715 CB MET A 168 18.144 25.185 7.840 1.00 44.18 C
+ATOM 716 CG MET A 168 17.335 23.903 7.732 1.00 54.38 C
+ATOM 717 SD MET A 168 18.133 22.682 6.661 1.00 64.13 S
+ATOM 718 CE MET A 168 16.982 21.309 6.772 1.00 61.43 C
+ATOM 719 N LEU A 169 16.398 27.395 7.112 1.00 38.94 N
+ATOM 720 CA LEU A 169 15.282 27.996 6.428 1.00 38.06 C
+ATOM 721 C LEU A 169 14.225 26.899 6.263 1.00 36.85 C
+ATOM 722 O LEU A 169 14.523 25.803 5.783 1.00 36.24 O
+ATOM 723 CB LEU A 169 15.793 28.542 5.086 1.00 40.10 C
+ATOM 724 CG LEU A 169 14.947 29.495 4.248 1.00 43.17 C
+ATOM 725 CD1 LEU A 169 13.850 28.727 3.565 1.00 46.74 C
+ATOM 726 CD2 LEU A 169 14.411 30.615 5.130 1.00 41.55 C
+ATOM 727 N GLY A 170 13.001 27.180 6.703 1.00 31.79 N
+ATOM 728 CA GLY A 170 11.940 26.197 6.594 1.00 30.88 C
+ATOM 729 C GLY A 170 11.789 25.301 7.815 1.00 31.35 C
+ATOM 730 O GLY A 170 10.841 24.523 7.889 1.00 30.37 O
+ATOM 731 N SER A 171 12.719 25.384 8.767 1.00 31.56 N
+ATOM 732 CA SER A 171 12.617 24.563 9.973 1.00 29.93 C
+ATOM 733 C SER A 171 11.302 24.917 10.655 1.00 29.06 C
+ATOM 734 O SER A 171 10.928 26.091 10.731 1.00 28.62 O
+ATOM 735 CB SER A 171 13.801 24.818 10.910 1.00 27.69 C
+ATOM 736 OG SER A 171 15.016 24.359 10.331 1.00 30.03 O
+ATOM 737 N PHE A 172 10.599 23.905 11.153 1.00 28.10 N
+ATOM 738 CA PHE A 172 9.305 24.147 11.769 1.00 29.23 C
+ATOM 739 C PHE A 172 8.979 23.279 12.974 1.00 28.18 C
+ATOM 740 O PHE A 172 9.781 22.465 13.439 1.00 29.18 O
+ATOM 741 CB PHE A 172 8.204 23.901 10.747 1.00 30.17 C
+ATOM 742 CG PHE A 172 8.053 22.449 10.379 1.00 33.63 C
+ATOM 743 CD1 PHE A 172 9.047 21.791 9.663 1.00 32.53 C
+ATOM 744 CD2 PHE A 172 6.941 21.724 10.802 1.00 33.73 C
+ATOM 745 CE1 PHE A 172 8.937 20.432 9.375 1.00 33.83 C
+ATOM 746 CE2 PHE A 172 6.821 20.368 10.521 1.00 32.79 C
+ATOM 747 CZ PHE A 172 7.821 19.719 9.806 1.00 34.18 C
+ATOM 748 N MET A 173 7.762 23.479 13.462 1.00 27.66 N
+ATOM 749 CA MET A 173 7.222 22.711 14.562 1.00 28.28 C
+ATOM 750 C MET A 173 5.732 22.983 14.598 1.00 27.87 C
+ATOM 751 O MET A 173 5.272 24.069 14.235 1.00 28.27 O
+ATOM 752 CB MET A 173 7.856 23.094 15.916 1.00 28.62 C
+ATOM 753 CG MET A 173 7.406 24.421 16.534 1.00 29.33 C
+ATOM 754 SD MET A 173 7.997 24.656 18.269 1.00 30.65 S
+ATOM 755 CE MET A 173 9.721 24.659 18.068 1.00 26.07 C
+ATOM 756 N ILE A 174 4.978 21.961 14.971 1.00 27.89 N
+ATOM 757 CA ILE A 174 3.543 22.082 15.130 1.00 28.48 C
+ATOM 758 C ILE A 174 3.467 22.070 16.647 1.00 27.67 C
+ATOM 759 O ILE A 174 4.119 21.252 17.290 1.00 28.21 O
+ATOM 760 CB ILE A 174 2.781 20.854 14.588 1.00 32.07 C
+ATOM 761 CG1 ILE A 174 2.992 20.713 13.076 1.00 34.92 C
+ATOM 762 CG2 ILE A 174 1.304 20.989 14.929 1.00 34.48 C
+ATOM 763 CD1 ILE A 174 2.432 21.855 12.254 1.00 36.99 C
+ATOM 764 N ARG A 175 2.687 22.972 17.221 1.00 26.34 N
+ATOM 765 CA ARG A 175 2.581 23.063 18.669 1.00 26.31 C
+ATOM 766 C ARG A 175 1.146 23.376 19.052 1.00 26.93 C
+ATOM 767 O ARG A 175 0.327 23.693 18.190 1.00 28.20 O
+ATOM 768 CB ARG A 175 3.510 24.175 19.165 1.00 23.78 C
+ATOM 769 CG ARG A 175 3.224 25.521 18.508 1.00 24.41 C
+ATOM 770 CD ARG A 175 4.268 26.584 18.839 1.00 22.57 C
+ATOM 771 NE ARG A 175 4.005 27.829 18.116 1.00 22.86 N
+ATOM 772 CZ ARG A 175 2.998 28.655 18.386 1.00 24.94 C
+ATOM 773 NH1 ARG A 175 2.153 28.376 19.369 1.00 24.76 N
+ATOM 774 NH2 ARG A 175 2.820 29.750 17.660 1.00 27.28 N
+ATOM 775 N ASP A 176 0.841 23.267 20.342 1.00 28.77 N
+ATOM 776 CA ASP A 176 -0.496 23.576 20.835 1.00 31.99 C
+ATOM 777 C ASP A 176 -0.676 25.079 20.710 1.00 33.53 C
+ATOM 778 O ASP A 176 0.251 25.840 20.984 1.00 35.08 O
+ATOM 779 CB ASP A 176 -0.644 23.171 22.303 1.00 34.60 C
+ATOM 780 CG ASP A 176 -0.625 21.670 22.502 1.00 39.04 C
+ATOM 781 OD1 ASP A 176 -1.468 20.989 21.881 1.00 38.93 O
+ATOM 782 OD2 ASP A 176 0.221 21.175 23.281 1.00 39.59 O
+ATOM 783 N SER A 177 -1.857 25.512 20.291 1.00 35.06 N
+ATOM 784 CA SER A 177 -2.111 26.939 20.138 1.00 36.69 C
+ATOM 785 C SER A 177 -2.382 27.591 21.491 1.00 37.30 C
+ATOM 786 O SER A 177 -3.133 27.051 22.301 1.00 35.13 O
+ATOM 787 CB SER A 177 -3.307 27.163 19.205 1.00 37.36 C
+ATOM 788 OG SER A 177 -3.563 28.547 19.022 1.00 37.78 O
+ATOM 789 N GLU A 178 -1.753 28.740 21.735 1.00 38.28 N
+ATOM 790 CA GLU A 178 -1.952 29.479 22.980 1.00 40.38 C
+ATOM 791 C GLU A 178 -3.189 30.359 22.863 1.00 40.93 C
+ATOM 792 O GLU A 178 -3.903 30.579 23.839 1.00 42.98 O
+ATOM 793 CB GLU A 178 -0.746 30.373 23.306 1.00 40.11 C
+ATOM 794 CG GLU A 178 0.476 29.652 23.866 1.00 41.21 C
+ATOM 795 CD GLU A 178 1.562 30.619 24.338 1.00 43.00 C
+ATOM 796 OE1 GLU A 178 2.145 31.332 23.494 1.00 39.50 O
+ATOM 797 OE2 GLU A 178 1.828 30.671 25.560 1.00 41.89 O
+ATOM 798 N THR A 179 -3.439 30.851 21.656 1.00 43.53 N
+ATOM 799 CA THR A 179 -4.576 31.724 21.395 1.00 45.96 C
+ATOM 800 C THR A 179 -5.905 30.983 21.323 1.00 46.67 C
+ATOM 801 O THR A 179 -6.906 31.426 21.888 1.00 47.49 O
+ATOM 802 CB THR A 179 -4.378 32.478 20.080 1.00 45.48 C
+ATOM 803 OG1 THR A 179 -3.151 33.210 20.142 1.00 49.05 O
+ATOM 804 CG2 THR A 179 -5.525 33.447 19.840 1.00 49.87 C
+ATOM 805 N THR A 180 -5.913 29.864 20.608 1.00 46.55 N
+ATOM 806 CA THR A 180 -7.121 29.066 20.460 1.00 45.69 C
+ATOM 807 C THR A 180 -6.900 27.720 21.140 1.00 46.34 C
+ATOM 808 O THR A 180 -6.446 26.766 20.509 1.00 44.66 O
+ATOM 809 CB THR A 180 -7.453 28.825 18.969 1.00 44.04 C
+ATOM 810 OG1 THR A 180 -7.483 30.077 18.272 1.00 43.33 O
+ATOM 811 CG2 THR A 180 -8.808 28.148 18.831 1.00 42.29 C
+ATOM 812 N LYS A 181 -7.217 27.649 22.429 1.00 47.48 N
+ATOM 813 CA LYS A 181 -7.042 26.416 23.191 1.00 50.48 C
+ATOM 814 C LYS A 181 -7.622 25.204 22.462 1.00 51.35 C
+ATOM 815 O LYS A 181 -8.697 25.279 21.866 1.00 54.02 O
+ATOM 816 CB LYS A 181 -7.704 26.550 24.565 1.00 50.87 C
+ATOM 817 CG LYS A 181 -7.103 27.626 25.461 1.00 52.66 C
+ATOM 818 CD LYS A 181 -5.673 27.300 25.867 1.00 53.35 C
+ATOM 819 CE LYS A 181 -5.122 28.359 26.815 1.00 54.97 C
+ATOM 820 NZ LYS A 181 -3.740 28.051 27.284 1.00 51.89 N
+ATOM 821 N GLY A 182 -6.899 24.087 22.508 1.00 50.06 N
+ATOM 822 CA GLY A 182 -7.370 22.878 21.857 1.00 47.63 C
+ATOM 823 C GLY A 182 -6.948 22.752 20.406 1.00 46.33 C
+ATOM 824 O GLY A 182 -6.833 21.643 19.880 1.00 46.26 O
+ATOM 825 N SER A 183 -6.721 23.884 19.750 1.00 43.99 N
+ATOM 826 CA SER A 183 -6.307 23.866 18.358 1.00 42.16 C
+ATOM 827 C SER A 183 -4.790 23.843 18.254 1.00 39.55 C
+ATOM 828 O SER A 183 -4.094 23.719 19.261 1.00 41.11 O
+ATOM 829 CB SER A 183 -6.878 25.076 17.615 1.00 44.69 C
+ATOM 830 OG SER A 183 -8.295 24.999 17.558 1.00 49.15 O
+ATOM 831 N TYR A 184 -4.283 23.973 17.035 1.00 35.65 N
+ATOM 832 CA TYR A 184 -2.848 23.934 16.804 1.00 36.02 C
+ATOM 833 C TYR A 184 -2.340 25.119 15.997 1.00 35.47 C
+ATOM 834 O TYR A 184 -3.119 25.863 15.394 1.00 34.99 O
+ATOM 835 CB TYR A 184 -2.502 22.630 16.088 1.00 35.07 C
+ATOM 836 CG TYR A 184 -2.923 21.420 16.882 1.00 40.13 C
+ATOM 837 CD1 TYR A 184 -2.223 21.040 18.026 1.00 38.63 C
+ATOM 838 CD2 TYR A 184 -4.070 20.703 16.541 1.00 40.44 C
+ATOM 839 CE1 TYR A 184 -2.654 19.981 18.812 1.00 42.34 C
+ATOM 840 CE2 TYR A 184 -4.513 19.639 17.322 1.00 41.28 C
+ATOM 841 CZ TYR A 184 -3.802 19.284 18.456 1.00 41.96 C
+ATOM 842 OH TYR A 184 -4.240 18.244 19.239 1.00 39.03 O
+ATOM 843 N SER A 185 -1.020 25.282 16.002 1.00 32.59 N
+ATOM 844 CA SER A 185 -0.361 26.348 15.265 1.00 30.43 C
+ATOM 845 C SER A 185 0.922 25.823 14.641 1.00 30.08 C
+ATOM 846 O SER A 185 1.560 24.904 15.165 1.00 30.57 O
+ATOM 847 CB SER A 185 -0.032 27.524 16.193 1.00 32.57 C
+ATOM 848 OG SER A 185 -1.212 28.109 16.714 1.00 30.79 O
+ATOM 849 N LEU A 186 1.291 26.409 13.512 1.00 28.78 N
+ATOM 850 CA LEU A 186 2.505 26.027 12.819 1.00 29.75 C
+ATOM 851 C LEU A 186 3.498 27.176 12.917 1.00 30.54 C
+ATOM 852 O LEU A 186 3.136 28.335 12.708 1.00 31.57 O
+ATOM 853 CB LEU A 186 2.204 25.722 11.347 1.00 30.68 C
+ATOM 854 CG LEU A 186 3.403 25.483 10.422 1.00 33.05 C
+ATOM 855 CD1 LEU A 186 4.200 24.278 10.889 1.00 29.59 C
+ATOM 856 CD2 LEU A 186 2.910 25.277 8.991 1.00 34.10 C
+ATOM 857 N SER A 187 4.739 26.855 13.264 1.00 28.82 N
+ATOM 858 CA SER A 187 5.791 27.855 13.363 1.00 26.21 C
+ATOM 859 C SER A 187 6.855 27.479 12.350 1.00 28.42 C
+ATOM 860 O SER A 187 7.332 26.339 12.326 1.00 26.61 O
+ATOM 861 CB SER A 187 6.374 27.895 14.772 1.00 25.28 C
+ATOM 862 OG SER A 187 5.403 28.370 15.686 1.00 23.67 O
+ATOM 863 N VAL A 188 7.223 28.448 11.517 1.00 28.78 N
+ATOM 864 CA VAL A 188 8.190 28.220 10.453 1.00 26.90 C
+ATOM 865 C VAL A 188 9.293 29.272 10.417 1.00 27.17 C
+ATOM 866 O VAL A 188 9.031 30.467 10.539 1.00 27.15 O
+ATOM 867 CB VAL A 188 7.468 28.224 9.088 1.00 29.40 C
+ATOM 868 CG1 VAL A 188 8.397 27.728 8.005 1.00 27.83 C
+ATOM 869 CG2 VAL A 188 6.200 27.373 9.167 1.00 27.32 C
+ATOM 870 N ARG A 189 10.532 28.825 10.257 1.00 27.88 N
+ATOM 871 CA ARG A 189 11.641 29.757 10.187 1.00 31.21 C
+ATOM 872 C ARG A 189 11.640 30.422 8.811 1.00 32.78 C
+ATOM 873 O ARG A 189 11.501 29.756 7.782 1.00 33.52 O
+ATOM 874 CB ARG A 189 12.967 29.038 10.445 1.00 31.32 C
+ATOM 875 CG ARG A 189 14.156 29.976 10.408 1.00 34.10 C
+ATOM 876 CD ARG A 189 15.349 29.402 11.129 1.00 37.67 C
+ATOM 877 NE ARG A 189 16.489 30.308 11.070 1.00 34.86 N
+ATOM 878 CZ ARG A 189 17.626 30.117 11.726 1.00 39.02 C
+ATOM 879 NH1 ARG A 189 17.776 29.048 12.498 1.00 34.80 N
+ATOM 880 NH2 ARG A 189 18.619 30.987 11.599 1.00 39.24 N
+ATOM 881 N ASP A 190 11.784 31.742 8.801 1.00 34.61 N
+ATOM 882 CA ASP A 190 11.774 32.505 7.561 1.00 37.59 C
+ATOM 883 C ASP A 190 12.947 33.479 7.505 1.00 39.08 C
+ATOM 884 O ASP A 190 13.735 33.572 8.448 1.00 38.87 O
+ATOM 885 CB ASP A 190 10.441 33.250 7.456 1.00 40.35 C
+ATOM 886 CG ASP A 190 10.327 34.078 6.199 1.00 40.90 C
+ATOM 887 OD1 ASP A 190 10.451 33.500 5.095 1.00 39.34 O
+ATOM 888 OD2 ASP A 190 10.102 35.303 6.327 1.00 38.80 O
+ATOM 889 N TYR A 191 13.072 34.192 6.391 1.00 39.96 N
+ATOM 890 CA TYR A 191 14.148 35.158 6.224 1.00 37.67 C
+ATOM 891 C TYR A 191 13.899 36.172 5.117 1.00 37.07 C
+ATOM 892 O TYR A 191 13.424 35.825 4.042 1.00 36.05 O
+ATOM 893 CB TYR A 191 15.480 34.440 5.951 1.00 38.35 C
+ATOM 894 CG TYR A 191 16.595 35.380 5.523 1.00 39.72 C
+ATOM 895 CD1 TYR A 191 16.610 35.944 4.244 1.00 41.35 C
+ATOM 896 CD2 TYR A 191 17.581 35.776 6.423 1.00 38.48 C
+ATOM 897 CE1 TYR A 191 17.568 36.883 3.881 1.00 40.03 C
+ATOM 898 CE2 TYR A 191 18.542 36.714 6.069 1.00 39.63 C
+ATOM 899 CZ TYR A 191 18.527 37.265 4.799 1.00 39.53 C
+ATOM 900 OH TYR A 191 19.455 38.217 4.458 1.00 39.04 O
+ATOM 901 N ASP A 192 14.224 37.430 5.400 1.00 36.36 N
+ATOM 902 CA ASP A 192 14.108 38.509 4.422 1.00 36.35 C
+ATOM 903 C ASP A 192 15.211 39.498 4.770 1.00 37.24 C
+ATOM 904 O ASP A 192 15.595 39.630 5.930 1.00 38.65 O
+ATOM 905 CB ASP A 192 12.717 39.170 4.453 1.00 36.77 C
+ATOM 906 CG ASP A 192 12.421 39.880 5.758 1.00 37.97 C
+ATOM 907 OD1 ASP A 192 13.004 40.959 6.007 1.00 35.29 O
+ATOM 908 OD2 ASP A 192 11.602 39.346 6.537 1.00 36.32 O
+ATOM 909 N PRO A 193 15.759 40.190 3.765 1.00 37.65 N
+ATOM 910 CA PRO A 193 16.831 41.155 4.015 1.00 36.04 C
+ATOM 911 C PRO A 193 16.526 42.256 5.035 1.00 35.31 C
+ATOM 912 O PRO A 193 17.430 42.751 5.705 1.00 34.78 O
+ATOM 913 CB PRO A 193 17.116 41.700 2.613 1.00 37.72 C
+ATOM 914 CG PRO A 193 15.751 41.556 1.925 1.00 38.41 C
+ATOM 915 CD PRO A 193 15.443 40.144 2.328 1.00 35.92 C
+ATOM 916 N ARG A 194 15.257 42.625 5.165 1.00 35.02 N
+ATOM 917 CA ARG A 194 14.870 43.688 6.092 1.00 36.77 C
+ATOM 918 C ARG A 194 14.901 43.291 7.568 1.00 35.60 C
+ATOM 919 O ARG A 194 15.468 44.007 8.397 1.00 34.31 O
+ATOM 920 CB ARG A 194 13.477 44.219 5.732 1.00 38.29 C
+ATOM 921 CG ARG A 194 13.015 45.360 6.622 1.00 41.44 C
+ATOM 922 CD ARG A 194 11.718 45.982 6.132 1.00 44.79 C
+ATOM 923 NE ARG A 194 11.355 47.134 6.955 1.00 48.55 N
+ATOM 924 CZ ARG A 194 10.376 47.991 6.675 1.00 46.60 C
+ATOM 925 NH1 ARG A 194 9.638 47.841 5.581 1.00 43.84 N
+ATOM 926 NH2 ARG A 194 10.141 49.007 7.495 1.00 47.58 N
+ATOM 927 N GLN A 195 14.299 42.150 7.891 1.00 34.54 N
+ATOM 928 CA GLN A 195 14.245 41.671 9.269 1.00 36.07 C
+ATOM 929 C GLN A 195 15.242 40.562 9.590 1.00 34.47 C
+ATOM 930 O GLN A 195 15.520 40.288 10.759 1.00 33.70 O
+ATOM 931 CB GLN A 195 12.828 41.189 9.591 1.00 40.07 C
+ATOM 932 CG GLN A 195 11.775 42.271 9.422 1.00 46.80 C
+ATOM 933 CD GLN A 195 10.403 41.840 9.892 1.00 53.51 C
+ATOM 934 OE1 GLN A 195 9.435 42.598 9.792 1.00 58.78 O
+ATOM 935 NE2 GLN A 195 10.309 40.622 10.414 1.00 55.40 N
+ATOM 936 N GLY A 196 15.785 39.930 8.556 1.00 33.39 N
+ATOM 937 CA GLY A 196 16.730 38.852 8.773 1.00 30.80 C
+ATOM 938 C GLY A 196 15.982 37.570 9.086 1.00 29.99 C
+ATOM 939 O GLY A 196 14.869 37.360 8.597 1.00 27.45 O
+ATOM 940 N ASP A 197 16.583 36.704 9.898 1.00 31.85 N
+ATOM 941 CA ASP A 197 15.932 35.451 10.263 1.00 29.51 C
+ATOM 942 C ASP A 197 14.745 35.758 11.156 1.00 27.75 C
+ATOM 943 O ASP A 197 14.864 36.533 12.104 1.00 28.15 O
+ATOM 944 CB ASP A 197 16.890 34.535 11.024 1.00 30.49 C
+ATOM 945 CG ASP A 197 18.103 34.171 10.219 1.00 32.78 C
+ATOM 946 OD1 ASP A 197 17.926 33.674 9.089 1.00 37.66 O
+ATOM 947 OD2 ASP A 197 19.231 34.373 10.718 1.00 37.87 O
+ATOM 948 N THR A 198 13.601 35.161 10.849 1.00 27.74 N
+ATOM 949 CA THR A 198 12.409 35.361 11.659 1.00 29.38 C
+ATOM 950 C THR A 198 11.631 34.062 11.726 1.00 28.29 C
+ATOM 951 O THR A 198 11.946 33.090 11.036 1.00 31.97 O
+ATOM 952 CB THR A 198 11.466 36.425 11.067 1.00 30.70 C
+ATOM 953 OG1 THR A 198 10.897 35.931 9.847 1.00 31.46 O
+ATOM 954 CG2 THR A 198 12.226 37.726 10.798 1.00 29.96 C
+ATOM 955 N VAL A 199 10.607 34.056 12.564 1.00 27.19 N
+ATOM 956 CA VAL A 199 9.758 32.894 12.708 1.00 26.67 C
+ATOM 957 C VAL A 199 8.329 33.356 12.500 1.00 28.48 C
+ATOM 958 O VAL A 199 7.847 34.257 13.189 1.00 28.94 O
+ATOM 959 CB VAL A 199 9.912 32.254 14.104 1.00 26.01 C
+ATOM 960 CG1 VAL A 199 8.944 31.100 14.258 1.00 27.50 C
+ATOM 961 CG2 VAL A 199 11.344 31.768 14.289 1.00 26.92 C
+ATOM 962 N LYS A 200 7.667 32.752 11.520 1.00 30.09 N
+ATOM 963 CA LYS A 200 6.286 33.084 11.208 1.00 29.07 C
+ATOM 964 C LYS A 200 5.375 32.019 11.812 1.00 30.03 C
+ATOM 965 O LYS A 200 5.728 30.837 11.857 1.00 27.25 O
+ATOM 966 CB LYS A 200 6.085 33.151 9.688 1.00 34.02 C
+ATOM 967 CG LYS A 200 6.838 34.284 8.966 1.00 32.88 C
+ATOM 968 CD LYS A 200 6.383 35.662 9.431 1.00 35.05 C
+ATOM 969 CE LYS A 200 6.901 36.780 8.521 1.00 36.46 C
+ATOM 970 NZ LYS A 200 8.386 36.859 8.429 1.00 37.68 N
+ATOM 971 N HIS A 201 4.205 32.445 12.278 1.00 27.77 N
+ATOM 972 CA HIS A 201 3.246 31.541 12.900 1.00 29.90 C
+ATOM 973 C HIS A 201 1.932 31.506 12.122 1.00 33.43 C
+ATOM 974 O HIS A 201 1.408 32.554 11.740 1.00 34.12 O
+ATOM 975 CB HIS A 201 2.962 32.002 14.331 1.00 28.13 C
+ATOM 976 CG HIS A 201 4.183 32.093 15.195 1.00 29.35 C
+ATOM 977 ND1 HIS A 201 4.873 30.983 15.634 1.00 27.37 N
+ATOM 978 CD2 HIS A 201 4.844 33.166 15.691 1.00 29.39 C
+ATOM 979 CE1 HIS A 201 5.904 31.369 16.365 1.00 28.70 C
+ATOM 980 NE2 HIS A 201 5.910 32.689 16.415 1.00 27.43 N
+ATOM 981 N TYR A 202 1.398 30.307 11.899 1.00 33.00 N
+ATOM 982 CA TYR A 202 0.133 30.160 11.183 1.00 33.65 C
+ATOM 983 C TYR A 202 -0.868 29.369 12.004 1.00 33.63 C
+ATOM 984 O TYR A 202 -0.533 28.338 12.592 1.00 32.94 O
+ATOM 985 CB TYR A 202 0.320 29.439 9.846 1.00 34.31 C
+ATOM 986 CG TYR A 202 1.267 30.111 8.889 1.00 35.82 C
+ATOM 987 CD1 TYR A 202 2.645 30.018 9.062 1.00 36.96 C
+ATOM 988 CD2 TYR A 202 0.785 30.853 7.813 1.00 38.42 C
+ATOM 989 CE1 TYR A 202 3.521 30.644 8.188 1.00 37.52 C
+ATOM 990 CE2 TYR A 202 1.651 31.485 6.932 1.00 40.31 C
+ATOM 991 CZ TYR A 202 3.018 31.376 7.125 1.00 41.17 C
+ATOM 992 OH TYR A 202 3.884 31.989 6.250 1.00 44.01 O
+ATOM 993 N LYS A 203 -2.104 29.846 12.045 1.00 33.50 N
+ATOM 994 CA LYS A 203 -3.131 29.136 12.785 1.00 36.84 C
+ATOM 995 C LYS A 203 -3.564 27.926 11.973 1.00 38.49 C
+ATOM 996 O LYS A 203 -3.773 28.022 10.764 1.00 39.04 O
+ATOM 997 CB LYS A 203 -4.348 30.028 13.031 1.00 38.99 C
+ATOM 998 CG LYS A 203 -4.050 31.284 13.821 1.00 43.25 C
+ATOM 999 CD LYS A 203 -5.326 32.041 14.169 1.00 48.65 C
+ATOM 1000 CE LYS A 203 -6.224 31.213 15.080 1.00 50.44 C
+ATOM 1001 NZ LYS A 203 -5.535 30.840 16.353 1.00 50.87 N
+ATOM 1002 N ILE A 204 -3.667 26.781 12.638 1.00 38.60 N
+ATOM 1003 CA ILE A 204 -4.123 25.563 11.988 1.00 41.36 C
+ATOM 1004 C ILE A 204 -5.515 25.391 12.572 1.00 44.11 C
+ATOM 1005 O ILE A 204 -5.670 25.144 13.764 1.00 45.95 O
+ATOM 1006 CB ILE A 204 -3.247 24.349 12.351 1.00 38.96 C
+ATOM 1007 CG1 ILE A 204 -1.815 24.569 11.855 1.00 36.65 C
+ATOM 1008 CG2 ILE A 204 -3.821 23.094 11.722 1.00 41.66 C
+ATOM 1009 CD1 ILE A 204 -0.868 23.433 12.194 1.00 38.39 C
+ATOM 1010 N ARG A 205 -6.531 25.553 11.735 1.00 47.12 N
+ATOM 1011 CA ARG A 205 -7.905 25.457 12.199 1.00 49.17 C
+ATOM 1012 C ARG A 205 -8.403 24.023 12.217 1.00 48.51 C
+ATOM 1013 O ARG A 205 -8.200 23.274 11.260 1.00 46.62 O
+ATOM 1014 CB ARG A 205 -8.796 26.312 11.303 1.00 53.02 C
+ATOM 1015 CG ARG A 205 -9.856 27.100 12.041 1.00 58.13 C
+ATOM 1016 CD ARG A 205 -10.393 28.169 11.123 1.00 62.86 C
+ATOM 1017 NE ARG A 205 -9.287 28.849 10.452 1.00 65.94 N
+ATOM 1018 CZ ARG A 205 -9.402 29.975 9.757 1.00 66.93 C
+ATOM 1019 NH1 ARG A 205 -10.581 30.569 9.637 1.00 66.68 N
+ATOM 1020 NH2 ARG A 205 -8.335 30.507 9.177 1.00 65.77 N
+ATOM 1021 N THR A 206 -9.050 23.647 13.316 1.00 49.04 N
+ATOM 1022 CA THR A 206 -9.595 22.305 13.461 1.00 52.07 C
+ATOM 1023 C THR A 206 -11.055 22.328 13.035 1.00 55.26 C
+ATOM 1024 O THR A 206 -11.890 22.962 13.685 1.00 55.29 O
+ATOM 1025 CB THR A 206 -9.505 21.804 14.921 1.00 50.70 C
+ATOM 1026 OG1 THR A 206 -8.132 21.738 15.322 1.00 53.22 O
+ATOM 1027 CG2 THR A 206 -10.126 20.417 15.052 1.00 49.00 C
+ATOM 1028 N LEU A 207 -11.351 21.640 11.935 1.00 57.57 N
+ATOM 1029 CA LEU A 207 -12.708 21.575 11.405 1.00 60.16 C
+ATOM 1030 C LEU A 207 -13.527 20.537 12.134 1.00 60.90 C
+ATOM 1031 O LEU A 207 -13.081 19.404 12.324 1.00 60.55 O
+ATOM 1032 CB LEU A 207 -12.707 21.205 9.917 1.00 61.39 C
+ATOM 1033 CG LEU A 207 -12.009 22.117 8.913 1.00 62.55 C
+ATOM 1034 CD1 LEU A 207 -12.615 23.511 8.997 1.00 63.41 C
+ATOM 1035 CD2 LEU A 207 -10.518 22.145 9.203 1.00 63.18 C
+ATOM 1036 N ASP A 208 -14.725 20.923 12.553 1.00 62.47 N
+ATOM 1037 CA ASP A 208 -15.602 19.975 13.212 1.00 64.08 C
+ATOM 1038 C ASP A 208 -15.853 18.929 12.132 1.00 62.20 C
+ATOM 1039 O ASP A 208 -15.928 19.264 10.948 1.00 62.58 O
+ATOM 1040 CB ASP A 208 -16.901 20.666 13.643 1.00 67.26 C
+ATOM 1041 CG ASP A 208 -17.546 21.453 12.519 1.00 69.12 C
+ATOM 1042 OD1 ASP A 208 -17.975 20.832 11.524 1.00 71.09 O
+ATOM 1043 OD2 ASP A 208 -17.616 22.697 12.630 1.00 70.02 O
+ATOM 1044 N ASN A 209 -15.950 17.667 12.532 1.00 60.49 N
+ATOM 1045 CA ASN A 209 -16.161 16.571 11.589 1.00 59.46 C
+ATOM 1046 C ASN A 209 -14.867 16.249 10.842 1.00 59.03 C
+ATOM 1047 O ASN A 209 -14.889 15.858 9.671 1.00 58.14 O
+ATOM 1048 CB ASN A 209 -17.266 16.910 10.581 1.00 59.69 C
+ATOM 1049 CG ASN A 209 -18.611 17.136 11.243 1.00 59.65 C
+ATOM 1050 OD1 ASN A 209 -19.094 16.290 11.997 1.00 60.68 O
+ATOM 1051 ND2 ASN A 209 -19.230 18.277 10.955 1.00 58.74 N
+ATOM 1052 N GLY A 210 -13.743 16.424 11.533 1.00 58.21 N
+ATOM 1053 CA GLY A 210 -12.445 16.133 10.950 1.00 56.12 C
+ATOM 1054 C GLY A 210 -11.934 17.126 9.923 1.00 55.04 C
+ATOM 1055 O GLY A 210 -12.710 17.705 9.156 1.00 53.45 O
+ATOM 1056 N GLY A 211 -10.615 17.317 9.910 1.00 52.70 N
+ATOM 1057 CA GLY A 211 -10.005 18.234 8.964 1.00 51.64 C
+ATOM 1058 C GLY A 211 -9.080 19.262 9.590 1.00 49.38 C
+ATOM 1059 O GLY A 211 -9.305 19.720 10.708 1.00 49.61 O
+ATOM 1060 N PHE A 212 -8.038 19.630 8.854 1.00 47.21 N
+ATOM 1061 CA PHE A 212 -7.064 20.611 9.316 1.00 46.41 C
+ATOM 1062 C PHE A 212 -6.623 21.477 8.150 1.00 46.81 C
+ATOM 1063 O PHE A 212 -6.434 20.983 7.038 1.00 46.39 O
+ATOM 1064 CB PHE A 212 -5.836 19.908 9.894 1.00 45.52 C
+ATOM 1065 CG PHE A 212 -6.109 19.133 11.147 1.00 43.30 C
+ATOM 1066 CD1 PHE A 212 -6.431 19.790 12.331 1.00 42.11 C
+ATOM 1067 CD2 PHE A 212 -6.038 17.746 11.149 1.00 42.44 C
+ATOM 1068 CE1 PHE A 212 -6.676 19.077 13.501 1.00 38.18 C
+ATOM 1069 CE2 PHE A 212 -6.283 17.025 12.313 1.00 40.58 C
+ATOM 1070 CZ PHE A 212 -6.602 17.693 13.492 1.00 40.29 C
+ATOM 1071 N TYR A 213 -6.457 22.771 8.393 1.00 48.06 N
+ATOM 1072 CA TYR A 213 -6.010 23.646 7.325 1.00 49.08 C
+ATOM 1073 C TYR A 213 -5.545 25.005 7.803 1.00 48.72 C
+ATOM 1074 O TYR A 213 -5.969 25.507 8.842 1.00 47.63 O
+ATOM 1075 CB TYR A 213 -7.120 23.876 6.299 1.00 51.11 C
+ATOM 1076 CG TYR A 213 -8.189 24.836 6.769 1.00 52.15 C
+ATOM 1077 CD1 TYR A 213 -9.115 24.465 7.735 1.00 52.07 C
+ATOM 1078 CD2 TYR A 213 -8.248 26.134 6.269 1.00 54.02 C
+ATOM 1079 CE1 TYR A 213 -10.077 25.362 8.191 1.00 53.22 C
+ATOM 1080 CE2 TYR A 213 -9.203 27.040 6.716 1.00 54.20 C
+ATOM 1081 CZ TYR A 213 -10.116 26.647 7.677 1.00 54.91 C
+ATOM 1082 OH TYR A 213 -11.068 27.539 8.118 1.00 54.53 O
+ATOM 1083 N ILE A 214 -4.663 25.593 7.012 1.00 50.79 N
+ATOM 1084 CA ILE A 214 -4.153 26.920 7.275 1.00 54.06 C
+ATOM 1085 C ILE A 214 -4.854 27.742 6.200 1.00 57.06 C
+ATOM 1086 O ILE A 214 -5.220 28.894 6.418 1.00 57.10 O
+ATOM 1087 CB ILE A 214 -2.621 26.974 7.092 1.00 53.19 C
+ATOM 1088 CG1 ILE A 214 -1.956 26.029 8.100 1.00 53.14 C
+ATOM 1089 CG2 ILE A 214 -2.116 28.399 7.279 1.00 54.11 C
+ATOM 1090 CD1 ILE A 214 -0.449 25.967 7.999 1.00 51.61 C
+ATOM 1091 N SER A 215 -5.066 27.098 5.050 1.00 59.99 N
+ATOM 1092 CA SER A 215 -5.723 27.689 3.884 1.00 62.59 C
+ATOM 1093 C SER A 215 -7.022 26.919 3.627 1.00 63.58 C
+ATOM 1094 O SER A 215 -6.992 25.698 3.467 1.00 63.23 O
+ATOM 1095 CB SER A 215 -4.828 27.535 2.649 1.00 63.38 C
+ATOM 1096 OG SER A 215 -3.487 27.904 2.922 1.00 65.21 O
+ATOM 1097 N PRO A 216 -8.177 27.608 3.582 1.00 64.89 N
+ATOM 1098 CA PRO A 216 -9.408 26.852 3.331 1.00 65.58 C
+ATOM 1099 C PRO A 216 -9.314 26.123 1.992 1.00 65.22 C
+ATOM 1100 O PRO A 216 -10.178 25.325 1.633 1.00 66.63 O
+ATOM 1101 CB PRO A 216 -10.481 27.940 3.351 1.00 65.32 C
+ATOM 1102 CG PRO A 216 -9.713 29.155 2.847 1.00 66.01 C
+ATOM 1103 CD PRO A 216 -8.492 29.038 3.733 1.00 65.01 C
+ATOM 1104 N ARG A 217 -8.235 26.409 1.271 1.00 64.85 N
+ATOM 1105 CA ARG A 217 -7.958 25.811 -0.026 1.00 64.16 C
+ATOM 1106 C ARG A 217 -7.347 24.423 0.127 1.00 63.10 C
+ATOM 1107 O ARG A 217 -7.889 23.437 -0.375 1.00 63.70 O
+ATOM 1108 CB ARG A 217 -6.997 26.711 -0.797 1.00 65.52 C
+ATOM 1109 CG ARG A 217 -6.417 26.109 -2.062 1.00 67.58 C
+ATOM 1110 CD ARG A 217 -5.444 27.097 -2.672 1.00 70.20 C
+ATOM 1111 NE ARG A 217 -4.365 27.430 -1.743 1.00 72.36 N
+ATOM 1112 CZ ARG A 217 -3.512 28.435 -1.915 1.00 73.05 C
+ATOM 1113 NH1 ARG A 217 -3.609 29.215 -2.983 1.00 73.93 N
+ATOM 1114 NH2 ARG A 217 -2.558 28.661 -1.021 1.00 73.75 N
+ATOM 1115 N SER A 218 -6.214 24.358 0.821 1.00 60.55 N
+ATOM 1116 CA SER A 218 -5.509 23.100 1.038 1.00 58.19 C
+ATOM 1117 C SER A 218 -5.877 22.452 2.371 1.00 56.52 C
+ATOM 1118 O SER A 218 -5.163 22.611 3.360 1.00 56.19 O
+ATOM 1119 CB SER A 218 -3.996 23.338 0.989 1.00 59.02 C
+ATOM 1120 OG SER A 218 -3.600 23.900 -0.252 1.00 60.63 O
+ATOM 1121 N THR A 219 -6.986 21.720 2.396 1.00 54.12 N
+ATOM 1122 CA THR A 219 -7.421 21.056 3.621 1.00 53.36 C
+ATOM 1123 C THR A 219 -6.836 19.648 3.704 1.00 51.74 C
+ATOM 1124 O THR A 219 -6.516 19.037 2.682 1.00 50.99 O
+ATOM 1125 CB THR A 219 -8.960 20.981 3.699 1.00 54.69 C
+ATOM 1126 OG1 THR A 219 -9.500 22.309 3.688 1.00 56.04 O
+ATOM 1127 CG2 THR A 219 -9.399 20.275 4.976 1.00 54.89 C
+ATOM 1128 N PHE A 220 -6.702 19.139 4.926 1.00 49.35 N
+ATOM 1129 CA PHE A 220 -6.128 17.816 5.147 1.00 47.85 C
+ATOM 1130 C PHE A 220 -6.885 17.040 6.216 1.00 44.57 C
+ATOM 1131 O PHE A 220 -7.535 17.628 7.080 1.00 44.38 O
+ATOM 1132 CB PHE A 220 -4.674 17.970 5.577 1.00 50.37 C
+ATOM 1133 CG PHE A 220 -3.882 18.867 4.682 1.00 52.72 C
+ATOM 1134 CD1 PHE A 220 -3.574 18.482 3.381 1.00 52.84 C
+ATOM 1135 CD2 PHE A 220 -3.478 20.119 5.127 1.00 54.17 C
+ATOM 1136 CE1 PHE A 220 -2.875 19.336 2.537 1.00 54.98 C
+ATOM 1137 CE2 PHE A 220 -2.779 20.978 4.292 1.00 55.60 C
+ATOM 1138 CZ PHE A 220 -2.478 20.587 2.998 1.00 54.40 C
+ATOM 1139 N SER A 221 -6.786 15.718 6.168 1.00 40.55 N
+ATOM 1140 CA SER A 221 -7.474 14.896 7.150 1.00 39.31 C
+ATOM 1141 C SER A 221 -6.658 14.767 8.432 1.00 37.09 C
+ATOM 1142 O SER A 221 -7.221 14.574 9.509 1.00 37.26 O
+ATOM 1143 CB SER A 221 -7.780 13.507 6.576 1.00 37.70 C
+ATOM 1144 OG SER A 221 -6.595 12.817 6.228 1.00 36.97 O
+ATOM 1145 N THR A 222 -5.337 14.883 8.321 1.00 36.62 N
+ATOM 1146 CA THR A 222 -4.474 14.777 9.497 1.00 37.16 C
+ATOM 1147 C THR A 222 -3.317 15.771 9.456 1.00 36.26 C
+ATOM 1148 O THR A 222 -2.908 16.233 8.387 1.00 36.61 O
+ATOM 1149 CB THR A 222 -3.860 13.381 9.621 1.00 36.49 C
+ATOM 1150 OG1 THR A 222 -2.866 13.212 8.603 1.00 41.53 O
+ATOM 1151 CG2 THR A 222 -4.933 12.316 9.455 1.00 39.17 C
+ATOM 1152 N LEU A 223 -2.786 16.092 10.630 1.00 34.37 N
+ATOM 1153 CA LEU A 223 -1.671 17.022 10.719 1.00 33.04 C
+ATOM 1154 C LEU A 223 -0.485 16.507 9.905 1.00 31.98 C
+ATOM 1155 O LEU A 223 0.195 17.286 9.233 1.00 30.82 O
+ATOM 1156 CB LEU A 223 -1.264 17.224 12.183 1.00 31.65 C
+ATOM 1157 CG LEU A 223 -2.285 17.933 13.083 1.00 34.62 C
+ATOM 1158 CD1 LEU A 223 -1.798 17.921 14.519 1.00 33.35 C
+ATOM 1159 CD2 LEU A 223 -2.498 19.364 12.605 1.00 30.59 C
+ATOM 1160 N GLN A 224 -0.249 15.196 9.952 1.00 32.02 N
+ATOM 1161 CA GLN A 224 0.861 14.603 9.210 1.00 35.23 C
+ATOM 1162 C GLN A 224 0.765 14.927 7.720 1.00 36.35 C
+ATOM 1163 O GLN A 224 1.764 15.259 7.079 1.00 36.07 O
+ATOM 1164 CB GLN A 224 0.893 13.082 9.400 1.00 36.79 C
+ATOM 1165 CG GLN A 224 2.048 12.399 8.662 1.00 37.91 C
+ATOM 1166 CD GLN A 224 3.419 12.802 9.194 1.00 38.90 C
+ATOM 1167 OE1 GLN A 224 3.757 12.524 10.345 1.00 36.82 O
+ATOM 1168 NE2 GLN A 224 4.213 13.459 8.356 1.00 33.61 N
+ATOM 1169 N GLU A 225 -0.440 14.830 7.170 1.00 37.59 N
+ATOM 1170 CA GLU A 225 -0.642 15.125 5.760 1.00 40.60 C
+ATOM 1171 C GLU A 225 -0.435 16.607 5.506 1.00 40.15 C
+ATOM 1172 O GLU A 225 0.052 17.005 4.445 1.00 39.95 O
+ATOM 1173 CB GLU A 225 -2.044 14.711 5.332 1.00 43.22 C
+ATOM 1174 CG GLU A 225 -2.264 13.218 5.401 1.00 48.37 C
+ATOM 1175 CD GLU A 225 -3.676 12.830 5.048 1.00 51.20 C
+ATOM 1176 OE1 GLU A 225 -4.140 13.212 3.953 1.00 53.95 O
+ATOM 1177 OE2 GLU A 225 -4.318 12.137 5.863 1.00 56.29 O
+ATOM 1178 N LEU A 226 -0.809 17.419 6.489 1.00 39.35 N
+ATOM 1179 CA LEU A 226 -0.646 18.861 6.383 1.00 39.28 C
+ATOM 1180 C LEU A 226 0.844 19.126 6.232 1.00 37.48 C
+ATOM 1181 O LEU A 226 1.266 19.904 5.373 1.00 39.76 O
+ATOM 1182 CB LEU A 226 -1.196 19.546 7.641 1.00 38.94 C
+ATOM 1183 CG LEU A 226 -1.169 21.077 7.722 1.00 43.26 C
+ATOM 1184 CD1 LEU A 226 -1.975 21.528 8.927 1.00 43.10 C
+ATOM 1185 CD2 LEU A 226 0.266 21.585 7.816 1.00 42.59 C
+ATOM 1186 N VAL A 227 1.637 18.457 7.063 1.00 37.35 N
+ATOM 1187 CA VAL A 227 3.083 18.606 7.031 1.00 37.21 C
+ATOM 1188 C VAL A 227 3.655 18.131 5.699 1.00 40.80 C
+ATOM 1189 O VAL A 227 4.377 18.872 5.033 1.00 41.93 O
+ATOM 1190 CB VAL A 227 3.747 17.816 8.172 1.00 35.83 C
+ATOM 1191 CG1 VAL A 227 5.259 17.922 8.067 1.00 34.12 C
+ATOM 1192 CG2 VAL A 227 3.272 18.357 9.520 1.00 39.16 C
+ATOM 1193 N ASP A 228 3.328 16.900 5.309 1.00 43.66 N
+ATOM 1194 CA ASP A 228 3.827 16.350 4.051 1.00 46.53 C
+ATOM 1195 C ASP A 228 3.553 17.272 2.868 1.00 47.92 C
+ATOM 1196 O ASP A 228 4.398 17.419 1.986 1.00 48.00 O
+ATOM 1197 CB ASP A 228 3.221 14.968 3.779 1.00 47.31 C
+ATOM 1198 CG ASP A 228 3.636 13.932 4.813 1.00 46.38 C
+ATOM 1199 OD1 ASP A 228 4.853 13.785 5.057 1.00 46.27 O
+ATOM 1200 OD2 ASP A 228 2.749 13.255 5.369 1.00 48.25 O
+ATOM 1201 N HIS A 229 2.377 17.894 2.847 1.00 50.25 N
+ATOM 1202 CA HIS A 229 2.040 18.799 1.758 1.00 51.55 C
+ATOM 1203 C HIS A 229 2.987 19.990 1.747 1.00 52.52 C
+ATOM 1204 O HIS A 229 3.818 20.122 0.849 1.00 52.51 O
+ATOM 1205 CB HIS A 229 0.602 19.308 1.883 1.00 53.63 C
+ATOM 1206 CG HIS A 229 0.222 20.302 0.826 1.00 58.25 C
+ATOM 1207 ND1 HIS A 229 -1.016 20.904 0.778 1.00 60.11 N
+ATOM 1208 CD2 HIS A 229 0.924 20.809 -0.217 1.00 59.50 C
+ATOM 1209 CE1 HIS A 229 -1.062 21.738 -0.244 1.00 59.43 C
+ATOM 1210 NE2 HIS A 229 0.102 21.700 -0.865 1.00 60.77 N
+ATOM 1211 N TYR A 230 2.853 20.857 2.747 1.00 51.82 N
+ATOM 1212 CA TYR A 230 3.691 22.046 2.852 1.00 51.07 C
+ATOM 1213 C TYR A 230 5.169 21.693 2.898 1.00 51.47 C
+ATOM 1214 O TYR A 230 6.034 22.569 2.828 1.00 52.06 O
+ATOM 1215 CB TYR A 230 3.297 22.853 4.089 1.00 47.64 C
+ATOM 1216 CG TYR A 230 1.924 23.468 3.980 1.00 44.91 C
+ATOM 1217 CD1 TYR A 230 1.669 24.490 3.066 1.00 44.77 C
+ATOM 1218 CD2 TYR A 230 0.874 23.022 4.779 1.00 43.53 C
+ATOM 1219 CE1 TYR A 230 0.404 25.053 2.953 1.00 44.08 C
+ATOM 1220 CE2 TYR A 230 -0.392 23.575 4.675 1.00 43.78 C
+ATOM 1221 CZ TYR A 230 -0.620 24.592 3.760 1.00 45.11 C
+ATOM 1222 OH TYR A 230 -1.870 25.154 3.662 1.00 46.09 O
+ATOM 1223 N LYS A 231 5.451 20.402 3.014 1.00 52.47 N
+ATOM 1224 CA LYS A 231 6.821 19.925 3.049 1.00 53.67 C
+ATOM 1225 C LYS A 231 7.252 19.813 1.585 1.00 56.46 C
+ATOM 1226 O LYS A 231 8.430 19.643 1.277 1.00 56.59 O
+ATOM 1227 CB LYS A 231 6.866 18.571 3.760 1.00 53.41 C
+ATOM 1228 CG LYS A 231 8.225 18.160 4.295 1.00 52.49 C
+ATOM 1229 CD LYS A 231 8.072 16.975 5.239 1.00 51.56 C
+ATOM 1230 CE LYS A 231 9.405 16.525 5.808 1.00 51.37 C
+ATOM 1231 NZ LYS A 231 10.325 16.047 4.741 1.00 50.67 N
+ATOM 1232 N LYS A 232 6.270 19.929 0.691 1.00 58.11 N
+ATOM 1233 CA LYS A 232 6.486 19.872 -0.756 1.00 59.89 C
+ATOM 1234 C LYS A 232 6.000 21.190 -1.346 1.00 59.82 C
+ATOM 1235 O LYS A 232 4.873 21.275 -1.830 1.00 60.73 O
+ATOM 1236 CB LYS A 232 5.675 18.737 -1.395 1.00 60.27 C
+ATOM 1237 CG LYS A 232 5.935 17.354 -0.837 1.00 61.52 C
+ATOM 1238 CD LYS A 232 5.141 16.277 -1.584 1.00 63.06 C
+ATOM 1239 CE LYS A 232 3.625 16.481 -1.510 1.00 63.03 C
+ATOM 1240 NZ LYS A 232 3.133 17.671 -2.266 1.00 62.92 N
+ATOM 1241 N GLY A 233 6.843 22.215 -1.306 1.00 60.48 N
+ATOM 1242 CA GLY A 233 6.441 23.503 -1.840 1.00 61.23 C
+ATOM 1243 C GLY A 233 5.639 24.282 -0.816 1.00 61.86 C
+ATOM 1244 O GLY A 233 4.679 23.765 -0.237 1.00 61.98 O
+ATOM 1245 N ASN A 234 6.030 25.534 -0.601 1.00 61.32 N
+ATOM 1246 CA ASN A 234 5.372 26.398 0.371 1.00 60.01 C
+ATOM 1247 C ASN A 234 3.868 26.576 0.181 1.00 58.71 C
+ATOM 1248 O ASN A 234 3.156 26.880 1.139 1.00 59.06 O
+ATOM 1249 CB ASN A 234 6.053 27.771 0.389 1.00 62.46 C
+ATOM 1250 CG ASN A 234 6.046 28.446 -0.968 1.00 62.90 C
+ATOM 1251 OD1 ASN A 234 4.987 28.711 -1.540 1.00 62.25 O
+ATOM 1252 ND2 ASN A 234 7.232 28.731 -1.491 1.00 61.76 N
+ATOM 1253 N ASP A 235 3.382 26.383 -1.041 1.00 56.50 N
+ATOM 1254 CA ASP A 235 1.956 26.545 -1.330 1.00 55.39 C
+ATOM 1255 C ASP A 235 1.352 27.700 -0.531 1.00 54.57 C
+ATOM 1256 O ASP A 235 0.360 27.529 0.178 1.00 54.88 O
+ATOM 1257 CB ASP A 235 1.184 25.255 -1.017 1.00 52.75 C
+ATOM 1258 CG ASP A 235 -0.306 25.370 -1.336 1.00 54.23 C
+ATOM 1259 OD1 ASP A 235 -1.051 24.406 -1.069 1.00 52.92 O
+ATOM 1260 OD2 ASP A 235 -0.740 26.421 -1.858 1.00 52.56 O
+ATOM 1261 N GLY A 236 1.960 28.875 -0.640 1.00 55.21 N
+ATOM 1262 CA GLY A 236 1.443 30.025 0.076 1.00 57.27 C
+ATOM 1263 C GLY A 236 2.206 30.381 1.337 1.00 58.00 C
+ATOM 1264 O GLY A 236 2.402 31.563 1.625 1.00 60.57 O
+ATOM 1265 N LEU A 237 2.629 29.375 2.098 1.00 56.48 N
+ATOM 1266 CA LEU A 237 3.372 29.634 3.326 1.00 55.72 C
+ATOM 1267 C LEU A 237 4.612 30.453 3.018 1.00 54.44 C
+ATOM 1268 O LEU A 237 5.185 30.340 1.934 1.00 55.59 O
+ATOM 1269 CB LEU A 237 3.778 28.325 4.012 1.00 54.80 C
+ATOM 1270 CG LEU A 237 2.665 27.451 4.594 1.00 54.35 C
+ATOM 1271 CD1 LEU A 237 3.288 26.255 5.300 1.00 54.40 C
+ATOM 1272 CD2 LEU A 237 1.828 28.260 5.577 1.00 53.82 C
+ATOM 1273 N CYS A 238 5.024 31.277 3.976 1.00 52.26 N
+ATOM 1274 CA CYS A 238 6.194 32.125 3.799 1.00 50.38 C
+ATOM 1275 C CYS A 238 7.374 31.289 3.348 1.00 48.27 C
+ATOM 1276 O CYS A 238 8.340 31.814 2.799 1.00 48.50 O
+ATOM 1277 CB CYS A 238 6.565 32.823 5.110 1.00 51.59 C
+ATOM 1278 SG CYS A 238 7.276 31.720 6.359 1.00 50.45 S
+ATOM 1279 N GLN A 239 7.296 29.982 3.573 1.00 49.00 N
+ATOM 1280 CA GLN A 239 8.398 29.115 3.197 1.00 48.97 C
+ATOM 1281 C GLN A 239 8.002 27.652 3.047 1.00 47.61 C
+ATOM 1282 O GLN A 239 6.926 27.234 3.467 1.00 46.89 O
+ATOM 1283 CB GLN A 239 9.500 29.222 4.248 1.00 51.54 C
+ATOM 1284 CG GLN A 239 10.883 29.158 3.677 1.00 55.86 C
+ATOM 1285 CD GLN A 239 11.198 30.369 2.819 1.00 57.66 C
+ATOM 1286 OE1 GLN A 239 10.498 30.657 1.849 1.00 60.62 O
+ATOM 1287 NE2 GLN A 239 12.254 31.088 3.176 1.00 59.22 N
+ATOM 1288 N LYS A 240 8.893 26.882 2.435 1.00 47.16 N
+ATOM 1289 CA LYS A 240 8.690 25.454 2.233 1.00 47.86 C
+ATOM 1290 C LYS A 240 9.221 24.751 3.476 1.00 45.74 C
+ATOM 1291 O LYS A 240 10.380 24.944 3.843 1.00 45.47 O
+ATOM 1292 CB LYS A 240 9.480 24.989 1.011 1.00 51.04 C
+ATOM 1293 CG LYS A 240 9.554 23.485 0.847 1.00 53.15 C
+ATOM 1294 CD LYS A 240 10.496 23.113 -0.285 1.00 55.40 C
+ATOM 1295 CE LYS A 240 10.644 21.608 -0.392 1.00 57.96 C
+ATOM 1296 NZ LYS A 240 9.329 20.961 -0.630 1.00 60.86 N
+ATOM 1297 N LEU A 241 8.386 23.941 4.121 1.00 43.25 N
+ATOM 1298 CA LEU A 241 8.816 23.238 5.326 1.00 42.95 C
+ATOM 1299 C LEU A 241 9.997 22.321 5.029 1.00 42.78 C
+ATOM 1300 O LEU A 241 9.955 21.538 4.080 1.00 44.52 O
+ATOM 1301 CB LEU A 241 7.672 22.401 5.909 1.00 38.01 C
+ATOM 1302 CG LEU A 241 6.354 23.087 6.271 1.00 36.96 C
+ATOM 1303 CD1 LEU A 241 5.434 22.054 6.895 1.00 38.53 C
+ATOM 1304 CD2 LEU A 241 6.585 24.239 7.241 1.00 38.51 C
+ATOM 1305 N SER A 242 11.051 22.427 5.833 1.00 42.48 N
+ATOM 1306 CA SER A 242 12.226 21.581 5.655 1.00 40.84 C
+ATOM 1307 C SER A 242 12.225 20.458 6.693 1.00 40.23 C
+ATOM 1308 O SER A 242 11.720 19.368 6.425 1.00 40.69 O
+ATOM 1309 CB SER A 242 13.511 22.410 5.769 1.00 42.74 C
+ATOM 1310 OG SER A 242 13.596 23.078 7.016 1.00 45.46 O
+ATOM 1311 N VAL A 243 12.780 20.727 7.873 1.00 37.04 N
+ATOM 1312 CA VAL A 243 12.838 19.737 8.946 1.00 34.02 C
+ATOM 1313 C VAL A 243 12.389 20.319 10.285 1.00 33.84 C
+ATOM 1314 O VAL A 243 12.412 21.536 10.488 1.00 29.41 O
+ATOM 1315 CB VAL A 243 14.269 19.171 9.128 1.00 33.00 C
+ATOM 1316 CG1 VAL A 243 14.724 18.467 7.853 1.00 36.56 C
+ATOM 1317 CG2 VAL A 243 15.225 20.293 9.506 1.00 32.27 C
+ATOM 1318 N PRO A 244 11.984 19.447 11.224 1.00 32.48 N
+ATOM 1319 CA PRO A 244 11.527 19.852 12.554 1.00 29.31 C
+ATOM 1320 C PRO A 244 12.607 20.631 13.291 1.00 28.34 C
+ATOM 1321 O PRO A 244 13.797 20.401 13.076 1.00 29.43 O
+ATOM 1322 CB PRO A 244 11.237 18.510 13.230 1.00 31.74 C
+ATOM 1323 CG PRO A 244 10.822 17.636 12.053 1.00 34.45 C
+ATOM 1324 CD PRO A 244 11.952 17.977 11.115 1.00 34.56 C
+ATOM 1325 N CYS A 245 12.189 21.547 14.159 1.00 28.55 N
+ATOM 1326 CA CYS A 245 13.129 22.340 14.938 1.00 27.95 C
+ATOM 1327 C CYS A 245 14.078 21.414 15.686 1.00 30.29 C
+ATOM 1328 O CYS A 245 13.684 20.328 16.117 1.00 25.53 O
+ATOM 1329 CB CYS A 245 12.384 23.211 15.950 1.00 25.75 C
+ATOM 1330 SG CYS A 245 13.481 24.191 16.988 1.00 27.82 S
+ATOM 1331 N MET A 246 15.328 21.837 15.832 1.00 32.93 N
+ATOM 1332 CA MET A 246 16.307 21.032 16.547 1.00 39.36 C
+ATOM 1333 C MET A 246 15.956 20.996 18.029 1.00 42.45 C
+ATOM 1334 O MET A 246 15.562 22.010 18.612 1.00 43.59 O
+ATOM 1335 CB MET A 246 17.713 21.609 16.372 1.00 42.56 C
+ATOM 1336 CG MET A 246 18.238 21.598 14.943 1.00 49.98 C
+ATOM 1337 SD MET A 246 18.511 19.945 14.256 1.00 55.26 S
+ATOM 1338 CE MET A 246 16.840 19.296 14.099 1.00 53.10 C
+ATOM 1339 N SER A 247 16.090 19.822 18.631 1.00 44.50 N
+ATOM 1340 CA SER A 247 15.804 19.658 20.049 1.00 47.23 C
+ATOM 1341 C SER A 247 16.765 18.624 20.615 1.00 49.46 C
+ATOM 1342 O SER A 247 17.104 17.644 19.948 1.00 48.97 O
+ATOM 1343 CB SER A 247 14.369 19.179 20.256 1.00 45.97 C
+ATOM 1344 OG SER A 247 14.205 17.881 19.719 1.00 48.40 O
+ATOM 1345 N SER A 248 17.211 18.849 21.843 1.00 52.14 N
+ATOM 1346 CA SER A 248 18.126 17.921 22.486 1.00 54.27 C
+ATOM 1347 C SER A 248 17.354 17.064 23.480 1.00 52.91 C
+ATOM 1348 O SER A 248 16.419 17.538 24.130 1.00 52.11 O
+ATOM 1349 CB SER A 248 19.244 18.688 23.197 1.00 54.71 C
+ATOM 1350 OG SER A 248 18.717 19.586 24.160 1.00 61.09 O
+ATOM 1351 N LYS A 249 17.740 15.796 23.576 1.00 53.01 N
+ATOM 1352 CA LYS A 249 17.103 14.855 24.491 1.00 52.66 C
+ATOM 1353 C LYS A 249 16.991 15.489 25.872 1.00 51.40 C
+ATOM 1354 O LYS A 249 17.965 16.036 26.386 1.00 51.72 O
+ATOM 1355 CB LYS A 249 17.940 13.579 24.571 1.00 52.77 C
+ATOM 1356 CG LYS A 249 17.381 12.495 25.475 1.00 53.76 C
+ATOM 1357 CD LYS A 249 18.292 11.279 25.425 1.00 54.78 C
+ATOM 1358 CE LYS A 249 17.753 10.118 26.234 1.00 56.11 C
+ATOM 1359 NZ LYS A 249 18.658 8.941 26.118 1.00 55.17 N
+ATOM 1360 N PRO A 250 15.800 15.422 26.492 1.00 50.80 N
+ATOM 1361 CA PRO A 250 15.592 16.005 27.820 1.00 50.11 C
+ATOM 1362 C PRO A 250 16.567 15.424 28.830 1.00 47.53 C
+ATOM 1363 O PRO A 250 16.855 14.228 28.807 1.00 47.79 O
+ATOM 1364 CB PRO A 250 14.139 15.638 28.123 1.00 52.05 C
+ATOM 1365 CG PRO A 250 13.520 15.635 26.735 1.00 52.20 C
+ATOM 1366 CD PRO A 250 14.557 14.783 26.035 1.00 51.76 C
+ATOM 1367 N GLN A 251 17.085 16.271 29.708 1.00 46.37 N
+ATOM 1368 CA GLN A 251 18.027 15.805 30.712 1.00 45.68 C
+ATOM 1369 C GLN A 251 17.293 14.894 31.677 1.00 42.35 C
+ATOM 1370 O GLN A 251 16.097 15.068 31.918 1.00 37.76 O
+ATOM 1371 CB GLN A 251 18.631 16.985 31.473 1.00 50.50 C
+ATOM 1372 CG GLN A 251 19.310 18.000 30.580 1.00 55.31 C
+ATOM 1373 CD GLN A 251 19.962 19.111 31.369 1.00 59.71 C
+ATOM 1374 OE1 GLN A 251 20.955 18.895 32.066 1.00 63.09 O
+ATOM 1375 NE2 GLN A 251 19.396 20.309 31.276 1.00 61.26 N
+ATOM 1376 N LYS A 252 18.009 13.911 32.209 1.00 41.57 N
+ATOM 1377 CA LYS A 252 17.425 12.979 33.157 1.00 42.57 C
+ATOM 1378 C LYS A 252 16.960 13.774 34.363 1.00 40.21 C
+ATOM 1379 O LYS A 252 17.597 14.753 34.751 1.00 39.99 O
+ATOM 1380 CB LYS A 252 18.462 11.945 33.603 1.00 46.81 C
+ATOM 1381 CG LYS A 252 19.026 11.100 32.473 1.00 51.59 C
+ATOM 1382 CD LYS A 252 19.968 10.017 32.993 1.00 54.94 C
+ATOM 1383 CE LYS A 252 20.473 9.136 31.857 1.00 56.53 C
+ATOM 1384 NZ LYS A 252 21.363 8.038 32.336 1.00 59.73 N
+ATOM 1385 N PRO A 253 15.820 13.393 34.950 1.00 37.70 N
+ATOM 1386 CA PRO A 253 15.359 14.139 36.118 1.00 37.07 C
+ATOM 1387 C PRO A 253 16.321 13.859 37.270 1.00 34.53 C
+ATOM 1388 O PRO A 253 17.158 12.955 37.189 1.00 34.20 O
+ATOM 1389 CB PRO A 253 13.971 13.556 36.354 1.00 39.54 C
+ATOM 1390 CG PRO A 253 14.176 12.117 35.945 1.00 40.52 C
+ATOM 1391 CD PRO A 253 14.853 12.337 34.610 1.00 39.72 C
+ATOM 1392 N TRP A 254 16.210 14.641 38.333 1.00 31.40 N
+ATOM 1393 CA TRP A 254 17.073 14.455 39.486 1.00 27.94 C
+ATOM 1394 C TRP A 254 16.656 13.155 40.169 1.00 28.57 C
+ATOM 1395 O TRP A 254 15.485 12.773 40.128 1.00 25.12 O
+ATOM 1396 CB TRP A 254 16.917 15.645 40.433 1.00 25.91 C
+ATOM 1397 CG TRP A 254 17.856 15.638 41.585 1.00 26.14 C
+ATOM 1398 CD1 TRP A 254 17.571 15.317 42.880 1.00 24.52 C
+ATOM 1399 CD2 TRP A 254 19.247 15.962 41.546 1.00 20.84 C
+ATOM 1400 NE1 TRP A 254 18.702 15.424 43.653 1.00 24.50 N
+ATOM 1401 CE2 TRP A 254 19.746 15.820 42.858 1.00 19.78 C
+ATOM 1402 CE3 TRP A 254 20.122 16.362 40.527 1.00 19.86 C
+ATOM 1403 CZ2 TRP A 254 21.079 16.061 43.181 1.00 21.84 C
+ATOM 1404 CZ3 TRP A 254 21.458 16.603 40.851 1.00 17.94 C
+ATOM 1405 CH2 TRP A 254 21.919 16.451 42.166 1.00 18.25 C
+ATOM 1406 N GLU A 255 17.621 12.467 40.770 1.00 28.53 N
+ATOM 1407 CA GLU A 255 17.359 11.211 41.470 1.00 26.90 C
+ATOM 1408 C GLU A 255 16.109 11.287 42.340 1.00 27.77 C
+ATOM 1409 O GLU A 255 15.870 12.284 43.019 1.00 23.72 O
+ATOM 1410 CB GLU A 255 18.556 10.847 42.346 1.00 30.79 C
+ATOM 1411 CG GLU A 255 18.400 9.542 43.104 1.00 34.55 C
+ATOM 1412 CD GLU A 255 19.616 9.213 43.942 1.00 41.24 C
+ATOM 1413 OE1 GLU A 255 19.625 8.128 44.560 1.00 46.57 O
+ATOM 1414 OE2 GLU A 255 20.560 10.036 43.984 1.00 40.18 O
+ATOM 1415 N LYS A 257 15.324 10.217 42.331 1.00 28.01 N
+ATOM 1416 CA LYS A 257 14.095 10.165 43.112 1.00 30.22 C
+ATOM 1417 C LYS A 257 14.365 10.297 44.610 1.00 28.06 C
+ATOM 1418 O LYS A 257 15.308 9.710 45.131 1.00 25.31 O
+ATOM 1419 CB LYS A 257 13.356 8.848 42.860 1.00 35.46 C
+ATOM 1420 CG LYS A 257 11.998 8.785 43.550 1.00 44.74 C
+ATOM 1421 CD LYS A 257 11.384 7.387 43.554 1.00 51.67 C
+ATOM 1422 CE LYS A 257 11.218 6.818 42.160 1.00 55.78 C
+ATOM 1423 NZ LYS A 257 12.518 6.508 41.500 1.00 58.30 N
+ATOM 1424 N ASP A 258 13.516 11.064 45.289 1.00 29.07 N
+ATOM 1425 CA ASP A 258 13.619 11.288 46.730 1.00 32.27 C
+ATOM 1426 C ASP A 258 15.009 11.714 47.193 1.00 31.41 C
+ATOM 1427 O ASP A 258 15.436 11.350 48.287 1.00 33.44 O
+ATOM 1428 CB ASP A 258 13.200 10.027 47.495 1.00 32.83 C
+ATOM 1429 CG ASP A 258 11.816 9.537 47.102 1.00 37.59 C
+ATOM 1430 OD1 ASP A 258 10.864 10.348 47.133 1.00 38.05 O
+ATOM 1431 OD2 ASP A 258 11.682 8.338 46.769 1.00 40.37 O
+ATOM 1432 N ALA A 259 15.711 12.486 46.370 1.00 28.54 N
+ATOM 1433 CA ALA A 259 17.047 12.953 46.726 1.00 27.48 C
+ATOM 1434 C ALA A 259 17.029 14.459 46.979 1.00 25.31 C
+ATOM 1435 O ALA A 259 17.787 15.207 46.367 1.00 25.19 O
+ATOM 1436 CB ALA A 259 18.035 12.617 45.610 1.00 25.32 C
+ATOM 1437 N TRP A 260 16.149 14.897 47.875 1.00 23.61 N
+ATOM 1438 CA TRP A 260 16.033 16.312 48.210 1.00 21.03 C
+ATOM 1439 C TRP A 260 17.121 16.700 49.211 1.00 20.94 C
+ATOM 1440 O TRP A 260 17.917 17.601 48.957 1.00 19.84 O
+ATOM 1441 CB TRP A 260 14.648 16.595 48.794 1.00 20.11 C
+ATOM 1442 CG TRP A 260 14.478 17.996 49.306 1.00 19.28 C
+ATOM 1443 CD1 TRP A 260 14.048 18.355 50.546 1.00 18.54 C
+ATOM 1444 CD2 TRP A 260 14.751 19.217 48.606 1.00 15.81 C
+ATOM 1445 NE1 TRP A 260 14.039 19.717 50.670 1.00 16.64 N
+ATOM 1446 CE2 TRP A 260 14.467 20.276 49.493 1.00 15.54 C
+ATOM 1447 CE3 TRP A 260 15.212 19.522 47.317 1.00 16.86 C
+ATOM 1448 CZ2 TRP A 260 14.625 21.622 49.140 1.00 16.38 C
+ATOM 1449 CZ3 TRP A 260 15.371 20.865 46.961 1.00 17.40 C
+ATOM 1450 CH2 TRP A 260 15.078 21.897 47.875 1.00 13.59 C
+ATOM 1451 N GLU A 261 17.144 16.033 50.358 1.00 19.45 N
+ATOM 1452 CA GLU A 261 18.173 16.305 51.353 1.00 20.11 C
+ATOM 1453 C GLU A 261 19.212 15.232 51.081 1.00 21.20 C
+ATOM 1454 O GLU A 261 18.934 14.043 51.252 1.00 22.36 O
+ATOM 1455 CB GLU A 261 17.630 16.155 52.771 1.00 20.94 C
+ATOM 1456 CG GLU A 261 16.451 17.054 53.091 1.00 27.68 C
+ATOM 1457 CD GLU A 261 16.050 16.974 54.556 1.00 30.79 C
+ATOM 1458 OE1 GLU A 261 14.990 17.522 54.909 1.00 31.60 O
+ATOM 1459 OE2 GLU A 261 16.802 16.374 55.356 1.00 35.78 O
+ATOM 1460 N ILE A 262 20.394 15.651 50.640 1.00 19.78 N
+ATOM 1461 CA ILE A 262 21.458 14.719 50.302 1.00 15.57 C
+ATOM 1462 C ILE A 262 22.695 14.851 51.178 1.00 16.43 C
+ATOM 1463 O ILE A 262 22.989 15.919 51.709 1.00 16.70 O
+ATOM 1464 CB ILE A 262 21.910 14.914 48.842 1.00 17.47 C
+ATOM 1465 CG1 ILE A 262 22.487 16.326 48.674 1.00 18.88 C
+ATOM 1466 CG2 ILE A 262 20.730 14.684 47.893 1.00 14.05 C
+ATOM 1467 CD1 ILE A 262 22.970 16.643 47.278 1.00 17.07 C
+ATOM 1468 N PRO A 263 23.451 13.756 51.321 1.00 15.11 N
+ATOM 1469 CA PRO A 263 24.667 13.754 52.132 1.00 16.94 C
+ATOM 1470 C PRO A 263 25.689 14.685 51.485 1.00 15.79 C
+ATOM 1471 O PRO A 263 25.792 14.746 50.260 1.00 17.33 O
+ATOM 1472 CB PRO A 263 25.109 12.284 52.074 1.00 17.73 C
+ATOM 1473 CG PRO A 263 23.789 11.532 51.822 1.00 18.76 C
+ATOM 1474 CD PRO A 263 23.237 12.425 50.728 1.00 14.60 C
+ATOM 1475 N ARG A 264 26.446 15.410 52.299 1.00 13.29 N
+ATOM 1476 CA ARG A 264 27.462 16.306 51.765 1.00 14.83 C
+ATOM 1477 C ARG A 264 28.451 15.520 50.885 1.00 13.57 C
+ATOM 1478 O ARG A 264 28.885 16.003 49.833 1.00 11.65 O
+ATOM 1479 CB ARG A 264 28.220 16.987 52.916 1.00 14.81 C
+ATOM 1480 CG ARG A 264 29.153 18.124 52.492 1.00 16.29 C
+ATOM 1481 CD ARG A 264 29.955 18.615 53.691 1.00 20.65 C
+ATOM 1482 NE ARG A 264 29.085 19.007 54.799 1.00 18.13 N
+ATOM 1483 CZ ARG A 264 28.305 20.087 54.799 1.00 18.59 C
+ATOM 1484 NH1 ARG A 264 28.274 20.900 53.752 1.00 18.53 N
+ATOM 1485 NH2 ARG A 264 27.537 20.346 55.846 1.00 22.95 N
+ATOM 1486 N GLU A 265 28.802 14.304 51.300 1.00 16.78 N
+ATOM 1487 CA GLU A 265 29.764 13.512 50.528 1.00 15.97 C
+ATOM 1488 C GLU A 265 29.312 13.099 49.121 1.00 14.55 C
+ATOM 1489 O GLU A 265 30.133 12.656 48.322 1.00 16.12 O
+ATOM 1490 CB GLU A 265 30.220 12.252 51.304 1.00 15.32 C
+ATOM 1491 CG GLU A 265 29.113 11.266 51.663 1.00 14.95 C
+ATOM 1492 CD GLU A 265 28.493 11.550 53.009 1.00 13.55 C
+ATOM 1493 OE1 GLU A 265 28.400 12.739 53.381 1.00 17.65 O
+ATOM 1494 OE2 GLU A 265 28.076 10.583 53.683 1.00 16.72 O
+ATOM 1495 N SER A 266 28.023 13.231 48.810 1.00 14.81 N
+ATOM 1496 CA SER A 266 27.533 12.861 47.481 1.00 15.35 C
+ATOM 1497 C SER A 266 28.021 13.850 46.431 1.00 15.51 C
+ATOM 1498 O SER A 266 28.011 13.562 45.229 1.00 15.61 O
+ATOM 1499 CB SER A 266 26.002 12.831 47.452 1.00 14.20 C
+ATOM 1500 OG SER A 266 25.476 14.125 47.679 1.00 13.59 O
+ATOM 1501 N LEU A 267 28.428 15.027 46.891 1.00 15.77 N
+ATOM 1502 CA LEU A 267 28.924 16.066 46.005 1.00 16.22 C
+ATOM 1503 C LEU A 267 30.445 16.153 45.997 1.00 18.24 C
+ATOM 1504 O LEU A 267 31.084 16.042 47.039 1.00 18.76 O
+ATOM 1505 CB LEU A 267 28.365 17.424 46.432 1.00 18.89 C
+ATOM 1506 CG LEU A 267 26.854 17.598 46.307 1.00 18.02 C
+ATOM 1507 CD1 LEU A 267 26.424 18.841 47.036 1.00 16.14 C
+ATOM 1508 CD2 LEU A 267 26.482 17.670 44.825 1.00 17.76 C
+ATOM 1509 N LYS A 268 31.013 16.357 44.812 1.00 16.16 N
+ATOM 1510 CA LYS A 268 32.453 16.535 44.654 1.00 19.39 C
+ATOM 1511 C LYS A 268 32.648 17.952 44.104 1.00 16.23 C
+ATOM 1512 O LYS A 268 32.431 18.184 42.911 1.00 18.30 O
+ATOM 1513 CB LYS A 268 33.021 15.513 43.662 1.00 20.21 C
+ATOM 1514 CG LYS A 268 34.508 15.711 43.338 1.00 19.55 C
+ATOM 1515 CD LYS A 268 35.369 15.539 44.573 1.00 25.85 C
+ATOM 1516 CE LYS A 268 36.862 15.674 44.260 1.00 30.68 C
+ATOM 1517 NZ LYS A 268 37.669 15.441 45.489 1.00 27.22 N
+ATOM 1518 N LEU A 269 33.032 18.899 44.967 1.00 17.89 N
+ATOM 1519 CA LEU A 269 33.245 20.288 44.541 1.00 17.75 C
+ATOM 1520 C LEU A 269 34.570 20.389 43.796 1.00 22.11 C
+ATOM 1521 O LEU A 269 35.626 20.044 44.329 1.00 21.06 O
+ATOM 1522 CB LEU A 269 33.196 21.252 45.742 1.00 19.52 C
+ATOM 1523 CG LEU A 269 31.778 21.664 46.193 1.00 19.50 C
+ATOM 1524 CD1 LEU A 269 30.961 20.436 46.535 1.00 20.13 C
+ATOM 1525 CD2 LEU A 269 31.851 22.604 47.386 1.00 23.13 C
+ATOM 1526 N GLU A 270 34.500 20.885 42.563 1.00 22.96 N
+ATOM 1527 CA GLU A 270 35.660 20.951 41.681 1.00 26.05 C
+ATOM 1528 C GLU A 270 36.372 22.292 41.495 1.00 27.96 C
+ATOM 1529 O GLU A 270 37.578 22.383 41.715 1.00 27.83 O
+ATOM 1530 CB GLU A 270 35.231 20.404 40.321 1.00 25.67 C
+ATOM 1531 CG GLU A 270 34.460 19.099 40.455 1.00 30.03 C
+ATOM 1532 CD GLU A 270 33.713 18.706 39.193 1.00 29.93 C
+ATOM 1533 OE1 GLU A 270 33.133 19.598 38.537 1.00 28.32 O
+ATOM 1534 OE2 GLU A 270 33.674 17.500 38.878 1.00 33.98 O
+ATOM 1535 N LYS A 271 35.640 23.318 41.062 1.00 30.80 N
+ATOM 1536 CA LYS A 271 36.230 24.641 40.837 1.00 29.56 C
+ATOM 1537 C LYS A 271 35.264 25.738 41.257 1.00 30.67 C
+ATOM 1538 O LYS A 271 34.049 25.580 41.159 1.00 26.47 O
+ATOM 1539 CB LYS A 271 36.587 24.834 39.361 1.00 33.28 C
+ATOM 1540 CG LYS A 271 35.393 24.843 38.424 1.00 37.28 C
+ATOM 1541 CD LYS A 271 35.795 25.116 36.974 1.00 42.29 C
+ATOM 1542 CE LYS A 271 34.567 25.114 36.061 1.00 44.20 C
+ATOM 1543 NZ LYS A 271 34.888 25.332 34.621 1.00 46.47 N
+ATOM 1544 N LYS A 272 35.813 26.855 41.718 1.00 27.86 N
+ATOM 1545 CA LYS A 272 35.006 27.977 42.171 1.00 28.05 C
+ATOM 1546 C LYS A 272 34.495 28.782 40.980 1.00 26.73 C
+ATOM 1547 O LYS A 272 35.279 29.232 40.147 1.00 23.84 O
+ATOM 1548 CB LYS A 272 35.848 28.852 43.108 1.00 29.50 C
+ATOM 1549 CG LYS A 272 35.107 29.997 43.763 1.00 34.51 C
+ATOM 1550 CD LYS A 272 36.015 30.736 44.731 1.00 33.91 C
+ATOM 1551 CE LYS A 272 35.330 31.955 45.319 1.00 34.28 C
+ATOM 1552 NZ LYS A 272 36.233 32.680 46.258 1.00 42.03 N
+ATOM 1553 N LEU A 273 33.176 28.949 40.898 1.00 24.01 N
+ATOM 1554 CA LEU A 273 32.558 29.694 39.802 1.00 23.10 C
+ATOM 1555 C LEU A 273 32.368 31.171 40.123 1.00 24.28 C
+ATOM 1556 O LEU A 273 32.458 32.015 39.239 1.00 27.10 O
+ATOM 1557 CB LEU A 273 31.196 29.085 39.441 1.00 21.71 C
+ATOM 1558 CG LEU A 273 31.220 27.655 38.908 1.00 23.39 C
+ATOM 1559 CD1 LEU A 273 29.803 27.143 38.708 1.00 20.84 C
+ATOM 1560 CD2 LEU A 273 31.995 27.625 37.595 1.00 26.77 C
+ATOM 1561 N GLY A 274 32.092 31.483 41.383 1.00 25.25 N
+ATOM 1562 CA GLY A 274 31.882 32.869 41.753 1.00 28.97 C
+ATOM 1563 C GLY A 274 31.738 33.041 43.249 1.00 34.27 C
+ATOM 1564 O GLY A 274 31.606 32.064 43.987 1.00 30.90 O
+ATOM 1565 N ALA A 275 31.771 34.285 43.708 1.00 35.74 N
+ATOM 1566 CA ALA A 275 31.642 34.549 45.131 1.00 39.92 C
+ATOM 1567 C ALA A 275 30.370 35.323 45.427 1.00 42.67 C
+ATOM 1568 O ALA A 275 29.594 35.641 44.527 1.00 46.66 O
+ATOM 1569 CB ALA A 275 32.851 35.319 45.631 1.00 40.80 C
+ATOM 1570 N GLY A 276 30.164 35.615 46.704 1.00 44.32 N
+ATOM 1571 CA GLY A 276 28.991 36.353 47.129 1.00 45.46 C
+ATOM 1572 C GLY A 276 29.203 36.804 48.558 1.00 45.72 C
+ATOM 1573 O GLY A 276 30.140 36.350 49.213 1.00 47.06 O
+ATOM 1574 N GLN A 277 28.340 37.683 49.053 1.00 47.71 N
+ATOM 1575 CA GLN A 277 28.481 38.179 50.414 1.00 47.23 C
+ATOM 1576 C GLN A 277 28.039 37.198 51.492 1.00 43.90 C
+ATOM 1577 O GLN A 277 28.413 37.347 52.655 1.00 43.95 O
+ATOM 1578 CB GLN A 277 27.722 39.490 50.568 1.00 52.57 C
+ATOM 1579 CG GLN A 277 28.331 40.634 49.783 1.00 60.66 C
+ATOM 1580 CD GLN A 277 27.492 41.888 49.866 1.00 65.22 C
+ATOM 1581 OE1 GLN A 277 27.912 42.963 49.436 1.00 67.89 O
+ATOM 1582 NE2 GLN A 277 26.288 41.753 50.411 1.00 67.38 N
+ATOM 1583 N PHE A 278 27.247 36.199 51.119 1.00 40.10 N
+ATOM 1584 CA PHE A 278 26.791 35.216 52.097 1.00 35.61 C
+ATOM 1585 C PHE A 278 27.155 33.786 51.723 1.00 35.34 C
+ATOM 1586 O PHE A 278 26.760 32.842 52.402 1.00 34.32 O
+ATOM 1587 CB PHE A 278 25.279 35.319 52.302 1.00 33.89 C
+ATOM 1588 CG PHE A 278 24.837 36.636 52.856 1.00 30.71 C
+ATOM 1589 CD1 PHE A 278 24.193 37.562 52.051 1.00 29.64 C
+ATOM 1590 CD2 PHE A 278 25.107 36.968 54.176 1.00 33.59 C
+ATOM 1591 CE1 PHE A 278 23.824 38.799 52.551 1.00 31.20 C
+ATOM 1592 CE2 PHE A 278 24.743 38.207 54.689 1.00 31.15 C
+ATOM 1593 CZ PHE A 278 24.102 39.123 53.877 1.00 31.75 C
+ATOM 1594 N GLY A 279 27.916 33.630 50.650 1.00 35.45 N
+ATOM 1595 CA GLY A 279 28.304 32.301 50.220 1.00 36.35 C
+ATOM 1596 C GLY A 279 28.969 32.308 48.861 1.00 34.23 C
+ATOM 1597 O GLY A 279 28.911 33.301 48.134 1.00 37.46 O
+ATOM 1598 N GLU A 280 29.610 31.199 48.516 1.00 28.03 N
+ATOM 1599 CA GLU A 280 30.287 31.089 47.235 1.00 24.95 C
+ATOM 1600 C GLU A 280 29.544 30.091 46.354 1.00 21.60 C
+ATOM 1601 O GLU A 280 28.675 29.356 46.825 1.00 21.98 O
+ATOM 1602 CB GLU A 280 31.716 30.592 47.431 1.00 27.29 C
+ATOM 1603 CG GLU A 280 32.529 31.331 48.475 1.00 33.13 C
+ATOM 1604 CD GLU A 280 34.007 30.992 48.366 1.00 37.03 C
+ATOM 1605 OE1 GLU A 280 34.331 29.794 48.222 1.00 35.83 O
+ATOM 1606 OE2 GLU A 280 34.844 31.918 48.426 1.00 41.20 O
+ATOM 1607 N VAL A 281 29.895 30.059 45.077 1.00 20.09 N
+ATOM 1608 CA VAL A 281 29.265 29.130 44.150 1.00 21.15 C
+ATOM 1609 C VAL A 281 30.351 28.292 43.501 1.00 21.80 C
+ATOM 1610 O VAL A 281 31.351 28.828 43.015 1.00 20.72 O
+ATOM 1611 CB VAL A 281 28.455 29.876 43.071 1.00 20.56 C
+ATOM 1612 CG1 VAL A 281 27.849 28.880 42.090 1.00 19.19 C
+ATOM 1613 CG2 VAL A 281 27.343 30.681 43.740 1.00 20.18 C
+ATOM 1614 N TRP A 282 30.143 26.977 43.505 1.00 16.61 N
+ATOM 1615 CA TRP A 282 31.099 26.027 42.949 1.00 18.89 C
+ATOM 1616 C TRP A 282 30.508 25.075 41.922 1.00 20.29 C
+ATOM 1617 O TRP A 282 29.321 24.754 41.964 1.00 17.22 O
+ATOM 1618 CB TRP A 282 31.709 25.163 44.063 1.00 18.56 C
+ATOM 1619 CG TRP A 282 32.612 25.894 44.986 1.00 26.18 C
+ATOM 1620 CD1 TRP A 282 32.258 26.788 45.953 1.00 28.48 C
+ATOM 1621 CD2 TRP A 282 34.039 25.833 44.995 1.00 26.22 C
+ATOM 1622 NE1 TRP A 282 33.381 27.293 46.563 1.00 29.55 N
+ATOM 1623 CE2 TRP A 282 34.491 26.721 45.990 1.00 28.26 C
+ATOM 1624 CE3 TRP A 282 34.988 25.114 44.250 1.00 33.53 C
+ATOM 1625 CZ2 TRP A 282 35.844 26.911 46.267 1.00 24.43 C
+ATOM 1626 CZ3 TRP A 282 36.341 25.302 44.525 1.00 30.87 C
+ATOM 1627 CH2 TRP A 282 36.753 26.196 45.525 1.00 30.88 C
+ATOM 1628 N MET A 283 31.364 24.623 41.011 1.00 17.89 N
+ATOM 1629 CA MET A 283 31.004 23.646 39.989 1.00 19.38 C
+ATOM 1630 C MET A 283 31.231 22.326 40.719 1.00 19.61 C
+ATOM 1631 O MET A 283 32.210 22.208 41.459 1.00 19.82 O
+ATOM 1632 CB MET A 283 31.981 23.729 38.814 1.00 24.49 C
+ATOM 1633 CG MET A 283 31.689 22.806 37.639 1.00 34.44 C
+ATOM 1634 SD MET A 283 30.316 23.395 36.627 1.00 47.43 S
+ATOM 1635 CE MET A 283 28.982 23.144 37.693 1.00 44.86 C
+ATOM 1636 N ALA A 284 30.354 21.342 40.526 1.00 15.62 N
+ATOM 1637 CA ALA A 284 30.523 20.056 41.201 1.00 16.55 C
+ATOM 1638 C ALA A 284 29.831 18.914 40.476 1.00 15.37 C
+ATOM 1639 O ALA A 284 29.069 19.128 39.526 1.00 16.93 O
+ATOM 1640 CB ALA A 284 29.990 20.139 42.628 1.00 17.36 C
+ATOM 1641 N THR A 285 30.111 17.700 40.937 1.00 15.46 N
+ATOM 1642 CA THR A 285 29.501 16.505 40.383 1.00 17.26 C
+ATOM 1643 C THR A 285 28.832 15.725 41.506 1.00 19.09 C
+ATOM 1644 O THR A 285 29.442 15.450 42.546 1.00 16.62 O
+ATOM 1645 CB THR A 285 30.532 15.606 39.701 1.00 19.54 C
+ATOM 1646 OG1 THR A 285 31.145 16.322 38.623 1.00 21.75 O
+ATOM 1647 CG2 THR A 285 29.866 14.353 39.163 1.00 21.75 C
+ATOM 1648 N TYR A 286 27.564 15.397 41.286 1.00 15.80 N
+ATOM 1649 CA TYR A 286 26.756 14.638 42.230 1.00 17.32 C
+ATOM 1650 C TYR A 286 26.873 13.146 41.912 1.00 20.10 C
+ATOM 1651 O TYR A 286 26.578 12.723 40.792 1.00 18.25 O
+ATOM 1652 CB TYR A 286 25.291 15.073 42.115 1.00 16.09 C
+ATOM 1653 CG TYR A 286 24.333 14.251 42.941 1.00 16.93 C
+ATOM 1654 CD1 TYR A 286 24.341 14.316 44.333 1.00 17.13 C
+ATOM 1655 CD2 TYR A 286 23.415 13.399 42.327 1.00 15.98 C
+ATOM 1656 CE1 TYR A 286 23.450 13.555 45.093 1.00 20.89 C
+ATOM 1657 CE2 TYR A 286 22.525 12.636 43.075 1.00 19.52 C
+ATOM 1658 CZ TYR A 286 22.546 12.718 44.453 1.00 20.36 C
+ATOM 1659 OH TYR A 286 21.665 11.960 45.187 1.00 20.35 O
+ATOM 1660 N ASN A 287 27.282 12.362 42.909 1.00 20.84 N
+ATOM 1661 CA ASN A 287 27.462 10.915 42.780 1.00 19.92 C
+ATOM 1662 C ASN A 287 28.086 10.449 41.473 1.00 21.39 C
+ATOM 1663 O ASN A 287 27.630 9.486 40.852 1.00 19.31 O
+ATOM 1664 CB ASN A 287 26.149 10.156 43.032 1.00 17.29 C
+ATOM 1665 CG ASN A 287 25.775 10.111 44.510 1.00 21.43 C
+ATOM 1666 OD1 ASN A 287 26.646 10.137 45.380 1.00 19.80 O
+ATOM 1667 ND2 ASN A 287 24.484 10.005 44.798 1.00 22.22 N
+ATOM 1668 N LYS A 288 29.137 11.152 41.073 1.00 21.94 N
+ATOM 1669 CA LYS A 288 29.891 10.837 39.871 1.00 24.12 C
+ATOM 1670 C LYS A 288 29.096 10.749 38.571 1.00 26.01 C
+ATOM 1671 O LYS A 288 29.623 10.268 37.568 1.00 25.01 O
+ATOM 1672 CB LYS A 288 30.662 9.528 40.093 1.00 28.88 C
+ATOM 1673 CG LYS A 288 31.693 9.611 41.226 1.00 33.29 C
+ATOM 1674 CD LYS A 288 32.405 8.274 41.488 1.00 38.07 C
+ATOM 1675 CE LYS A 288 31.457 7.234 42.084 1.00 43.57 C
+ATOM 1676 NZ LYS A 288 32.132 5.926 42.376 1.00 47.13 N
+ATOM 1677 N HIS A 289 27.846 11.210 38.559 1.00 23.86 N
+ATOM 1678 CA HIS A 289 27.074 11.126 37.320 1.00 25.46 C
+ATOM 1679 C HIS A 289 26.414 12.416 36.829 1.00 26.03 C
+ATOM 1680 O HIS A 289 26.077 12.528 35.648 1.00 23.25 O
+ATOM 1681 CB HIS A 289 26.023 10.002 37.412 1.00 23.38 C
+ATOM 1682 CG HIS A 289 24.984 10.207 38.470 1.00 22.09 C
+ATOM 1683 ND1 HIS A 289 24.111 11.273 38.463 1.00 24.27 N
+ATOM 1684 CD2 HIS A 289 24.666 9.470 39.561 1.00 23.52 C
+ATOM 1685 CE1 HIS A 289 23.300 11.185 39.504 1.00 21.80 C
+ATOM 1686 NE2 HIS A 289 23.618 10.100 40.186 1.00 22.01 N
+ATOM 1687 N THR A 290 26.239 13.396 37.709 1.00 21.29 N
+ATOM 1688 CA THR A 290 25.600 14.639 37.291 1.00 19.67 C
+ATOM 1689 C THR A 290 26.317 15.926 37.682 1.00 21.48 C
+ATOM 1690 O THR A 290 26.592 16.169 38.855 1.00 16.42 O
+ATOM 1691 CB THR A 290 24.166 14.733 37.835 1.00 18.66 C
+ATOM 1692 OG1 THR A 290 23.423 13.582 37.421 1.00 19.98 O
+ATOM 1693 CG2 THR A 290 23.478 15.997 37.313 1.00 21.70 C
+ATOM 1694 N LYS A 291 26.583 16.756 36.677 1.00 21.81 N
+ATOM 1695 CA LYS A 291 27.230 18.052 36.859 1.00 23.05 C
+ATOM 1696 C LYS A 291 26.191 19.055 37.381 1.00 22.70 C
+ATOM 1697 O LYS A 291 25.098 19.178 36.821 1.00 18.70 O
+ATOM 1698 CB LYS A 291 27.796 18.521 35.518 1.00 27.63 C
+ATOM 1699 CG LYS A 291 28.440 19.894 35.521 1.00 36.74 C
+ATOM 1700 CD LYS A 291 29.124 20.142 34.182 1.00 41.65 C
+ATOM 1701 CE LYS A 291 29.847 21.473 34.142 1.00 41.56 C
+ATOM 1702 NZ LYS A 291 30.616 21.637 32.872 1.00 45.80 N
+ATOM 1703 N VAL A 292 26.539 19.761 38.454 1.00 16.95 N
+ATOM 1704 CA VAL A 292 25.638 20.732 39.067 1.00 15.95 C
+ATOM 1705 C VAL A 292 26.424 21.923 39.592 1.00 16.92 C
+ATOM 1706 O VAL A 292 27.656 21.915 39.601 1.00 16.75 O
+ATOM 1707 CB VAL A 292 24.892 20.105 40.273 1.00 17.22 C
+ATOM 1708 CG1 VAL A 292 24.088 18.892 39.826 1.00 12.92 C
+ATOM 1709 CG2 VAL A 292 25.903 19.677 41.340 1.00 15.42 C
+ATOM 1710 N ALA A 293 25.704 22.959 40.003 1.00 16.84 N
+ATOM 1711 CA ALA A 293 26.329 24.131 40.595 1.00 15.61 C
+ATOM 1712 C ALA A 293 25.932 23.999 42.060 1.00 17.91 C
+ATOM 1713 O ALA A 293 24.859 23.482 42.366 1.00 18.91 O
+ATOM 1714 CB ALA A 293 25.754 25.408 40.006 1.00 22.40 C
+ATOM 1715 N VAL A 294 26.794 24.443 42.962 1.00 15.28 N
+ATOM 1716 CA VAL A 294 26.491 24.345 44.379 1.00 15.17 C
+ATOM 1717 C VAL A 294 26.783 25.671 45.050 1.00 18.56 C
+ATOM 1718 O VAL A 294 27.906 26.178 44.972 1.00 19.42 O
+ATOM 1719 CB VAL A 294 27.353 23.256 45.080 1.00 19.83 C
+ATOM 1720 CG1 VAL A 294 26.989 23.171 46.570 1.00 10.68 C
+ATOM 1721 CG2 VAL A 294 27.152 21.905 44.403 1.00 17.98 C
+ATOM 1722 N LYS A 295 25.770 26.247 45.687 1.00 16.57 N
+ATOM 1723 CA LYS A 295 25.976 27.482 46.410 1.00 14.09 C
+ATOM 1724 C LYS A 295 26.196 27.074 47.855 1.00 16.40 C
+ATOM 1725 O LYS A 295 25.386 26.345 48.428 1.00 17.56 O
+ATOM 1726 CB LYS A 295 24.766 28.423 46.312 1.00 15.69 C
+ATOM 1727 CG LYS A 295 24.929 29.650 47.214 1.00 15.70 C
+ATOM 1728 CD LYS A 295 23.906 30.761 46.954 1.00 21.40 C
+ATOM 1729 CE LYS A 295 24.187 31.474 45.642 1.00 19.58 C
+ATOM 1730 NZ LYS A 295 23.423 32.757 45.496 1.00 21.14 N
+ATOM 1731 N THR A 296 27.309 27.523 48.425 1.00 16.56 N
+ATOM 1732 CA THR A 296 27.661 27.224 49.811 1.00 17.12 C
+ATOM 1733 C THR A 296 27.437 28.495 50.633 1.00 19.27 C
+ATOM 1734 O THR A 296 28.008 29.535 50.325 1.00 24.33 O
+ATOM 1735 CB THR A 296 29.148 26.854 49.934 1.00 19.19 C
+ATOM 1736 OG1 THR A 296 29.940 27.991 49.581 1.00 20.93 O
+ATOM 1737 CG2 THR A 296 29.504 25.711 48.993 1.00 18.01 C
+ATOM 1738 N MET A 297 26.619 28.413 51.676 1.00 21.45 N
+ATOM 1739 CA MET A 297 26.330 29.575 52.519 1.00 20.71 C
+ATOM 1740 C MET A 297 27.244 29.550 53.743 1.00 22.11 C
+ATOM 1741 O MET A 297 27.444 28.496 54.342 1.00 17.88 O
+ATOM 1742 CB MET A 297 24.872 29.526 52.975 1.00 22.26 C
+ATOM 1743 CG MET A 297 23.869 29.459 51.837 1.00 25.98 C
+ATOM 1744 SD MET A 297 23.930 30.915 50.811 1.00 27.90 S
+ATOM 1745 CE MET A 297 23.350 32.176 51.937 1.00 29.86 C
+ATOM 1746 N LYS A 298 27.796 30.697 54.123 1.00 23.01 N
+ATOM 1747 CA LYS A 298 28.672 30.734 55.290 1.00 25.03 C
+ATOM 1748 C LYS A 298 27.878 30.422 56.552 1.00 23.38 C
+ATOM 1749 O LYS A 298 26.708 30.788 56.675 1.00 19.30 O
+ATOM 1750 CB LYS A 298 29.365 32.098 55.407 1.00 29.74 C
+ATOM 1751 CG LYS A 298 30.232 32.429 54.186 1.00 38.20 C
+ATOM 1752 CD LYS A 298 31.126 33.663 54.367 1.00 44.02 C
+ATOM 1753 CE LYS A 298 30.350 34.927 54.715 1.00 46.23 C
+ATOM 1754 NZ LYS A 298 29.801 34.895 56.103 1.00 48.02 N
+ATOM 1755 N PRO A 299 28.507 29.731 57.513 1.00 24.20 N
+ATOM 1756 CA PRO A 299 27.826 29.378 58.760 1.00 23.08 C
+ATOM 1757 C PRO A 299 27.273 30.618 59.438 1.00 22.15 C
+ATOM 1758 O PRO A 299 27.930 31.658 59.459 1.00 18.21 O
+ATOM 1759 CB PRO A 299 28.938 28.711 59.568 1.00 26.84 C
+ATOM 1760 CG PRO A 299 29.768 28.067 58.473 1.00 24.26 C
+ATOM 1761 CD PRO A 299 29.899 29.255 57.553 1.00 24.19 C
+ATOM 1762 N GLY A 300 26.064 30.504 59.979 1.00 21.02 N
+ATOM 1763 CA GLY A 300 25.441 31.631 60.651 1.00 26.81 C
+ATOM 1764 C GLY A 300 24.791 32.647 59.723 1.00 27.28 C
+ATOM 1765 O GLY A 300 24.178 33.602 60.193 1.00 29.47 O
+ATOM 1766 N SER A 301 24.910 32.445 58.412 1.00 28.40 N
+ATOM 1767 CA SER A 301 24.334 33.373 57.434 1.00 28.18 C
+ATOM 1768 C SER A 301 22.823 33.256 57.361 1.00 30.06 C
+ATOM 1769 O SER A 301 22.147 34.151 56.857 1.00 28.89 O
+ATOM 1770 CB SER A 301 24.900 33.112 56.042 1.00 27.74 C
+ATOM 1771 OG SER A 301 24.522 31.821 55.602 1.00 24.01 O
+ATOM 1772 N MET A 302 22.290 32.139 57.832 1.00 29.67 N
+ATOM 1773 CA MET A 302 20.851 31.967 57.818 1.00 32.30 C
+ATOM 1774 C MET A 302 20.357 30.968 58.836 1.00 30.22 C
+ATOM 1775 O MET A 302 21.128 30.156 59.340 1.00 26.15 O
+ATOM 1776 CB MET A 302 20.355 31.597 56.403 1.00 35.66 C
+ATOM 1777 CG MET A 302 21.072 30.480 55.665 1.00 34.39 C
+ATOM 1778 SD MET A 302 20.332 30.204 53.995 1.00 30.34 S
+ATOM 1779 CE MET A 302 20.425 31.833 53.336 1.00 36.64 C
+ATOM 1780 N SER A 303 19.073 31.065 59.170 1.00 32.27 N
+ATOM 1781 CA SER A 303 18.451 30.139 60.113 1.00 32.44 C
+ATOM 1782 C SER A 303 18.314 28.820 59.372 1.00 33.44 C
+ATOM 1783 O SER A 303 17.629 28.750 58.351 1.00 34.50 O
+ATOM 1784 CB SER A 303 17.058 30.630 60.534 1.00 35.82 C
+ATOM 1785 OG SER A 303 16.374 29.649 61.310 1.00 36.23 O
+ATOM 1786 N VAL A 304 18.960 27.778 59.878 1.00 29.97 N
+ATOM 1787 CA VAL A 304 18.898 26.483 59.223 1.00 30.05 C
+ATOM 1788 C VAL A 304 17.470 25.967 59.092 1.00 31.04 C
+ATOM 1789 O VAL A 304 17.069 25.503 58.024 1.00 27.91 O
+ATOM 1790 CB VAL A 304 19.740 25.441 59.972 1.00 28.52 C
+ATOM 1791 CG1 VAL A 304 19.599 24.092 59.306 1.00 30.66 C
+ATOM 1792 CG2 VAL A 304 21.198 25.872 59.986 1.00 33.44 C
+ATOM 1793 N GLU A 305 16.699 26.053 60.170 1.00 28.84 N
+ATOM 1794 CA GLU A 305 15.324 25.575 60.138 1.00 28.78 C
+ATOM 1795 C GLU A 305 14.471 26.385 59.168 1.00 22.78 C
+ATOM 1796 O GLU A 305 13.735 25.821 58.362 1.00 23.91 O
+ATOM 1797 CB GLU A 305 14.704 25.641 61.535 1.00 36.24 C
+ATOM 1798 CG GLU A 305 15.481 24.887 62.598 1.00 46.60 C
+ATOM 1799 CD GLU A 305 14.789 24.921 63.949 1.00 53.26 C
+ATOM 1800 OE1 GLU A 305 14.510 26.032 64.456 1.00 57.10 O
+ATOM 1801 OE2 GLU A 305 14.524 23.833 64.503 1.00 57.88 O
+ATOM 1802 N ALA A 306 14.576 27.707 59.242 1.00 18.60 N
+ATOM 1803 CA ALA A 306 13.794 28.572 58.374 1.00 18.36 C
+ATOM 1804 C ALA A 306 14.191 28.385 56.913 1.00 19.43 C
+ATOM 1805 O ALA A 306 13.336 28.392 56.030 1.00 15.23 O
+ATOM 1806 CB ALA A 306 13.962 30.022 58.795 1.00 19.81 C
+ATOM 1807 N PHE A 307 15.485 28.218 56.659 1.00 18.17 N
+ATOM 1808 CA PHE A 307 15.952 28.006 55.293 1.00 17.62 C
+ATOM 1809 C PHE A 307 15.246 26.798 54.693 1.00 19.11 C
+ATOM 1810 O PHE A 307 14.660 26.885 53.619 1.00 19.63 O
+ATOM 1811 CB PHE A 307 17.462 27.751 55.250 1.00 17.22 C
+ATOM 1812 CG PHE A 307 17.922 27.144 53.954 1.00 17.07 C
+ATOM 1813 CD1 PHE A 307 17.917 27.886 52.783 1.00 17.22 C
+ATOM 1814 CD2 PHE A 307 18.274 25.800 53.893 1.00 18.01 C
+ATOM 1815 CE1 PHE A 307 18.254 27.291 51.558 1.00 19.22 C
+ATOM 1816 CE2 PHE A 307 18.610 25.195 52.683 1.00 14.62 C
+ATOM 1817 CZ PHE A 307 18.599 25.946 51.513 1.00 19.18 C
+ATOM 1818 N LEU A 308 15.303 25.673 55.400 1.00 17.92 N
+ATOM 1819 CA LEU A 308 14.686 24.435 54.928 1.00 19.22 C
+ATOM 1820 C LEU A 308 13.220 24.603 54.554 1.00 20.42 C
+ATOM 1821 O LEU A 308 12.774 24.102 53.523 1.00 19.64 O
+ATOM 1822 CB LEU A 308 14.821 23.342 55.990 1.00 24.73 C
+ATOM 1823 CG LEU A 308 16.264 22.992 56.383 1.00 32.54 C
+ATOM 1824 CD1 LEU A 308 16.269 22.001 57.548 1.00 32.15 C
+ATOM 1825 CD2 LEU A 308 16.998 22.423 55.177 1.00 31.29 C
+ATOM 1826 N ALA A 309 12.471 25.302 55.396 1.00 18.53 N
+ATOM 1827 CA ALA A 309 11.055 25.529 55.132 1.00 20.29 C
+ATOM 1828 C ALA A 309 10.871 26.314 53.831 1.00 19.53 C
+ATOM 1829 O ALA A 309 10.014 25.995 53.005 1.00 21.32 O
+ATOM 1830 CB ALA A 309 10.425 26.289 56.307 1.00 19.54 C
+ATOM 1831 N GLU A 310 11.695 27.337 53.649 1.00 18.24 N
+ATOM 1832 CA GLU A 310 11.630 28.189 52.465 1.00 18.02 C
+ATOM 1833 C GLU A 310 12.096 27.417 51.223 1.00 18.17 C
+ATOM 1834 O GLU A 310 11.519 27.538 50.139 1.00 15.81 O
+ATOM 1835 CB GLU A 310 12.511 29.415 52.697 1.00 24.52 C
+ATOM 1836 CG GLU A 310 12.165 30.620 51.866 1.00 27.69 C
+ATOM 1837 CD GLU A 310 10.782 31.153 52.188 1.00 27.72 C
+ATOM 1838 OE1 GLU A 310 10.435 31.199 53.386 1.00 30.28 O
+ATOM 1839 OE2 GLU A 310 10.056 31.547 51.255 1.00 23.72 O
+ATOM 1840 N ALA A 311 13.148 26.620 51.382 1.00 16.54 N
+ATOM 1841 CA ALA A 311 13.649 25.817 50.272 1.00 18.36 C
+ATOM 1842 C ALA A 311 12.563 24.834 49.811 1.00 18.05 C
+ATOM 1843 O ALA A 311 12.512 24.473 48.634 1.00 14.94 O
+ATOM 1844 CB ALA A 311 14.910 25.062 50.691 1.00 18.22 C
+ATOM 1845 N ASN A 312 11.693 24.391 50.720 1.00 17.59 N
+ATOM 1846 CA ASN A 312 10.634 23.472 50.286 1.00 21.41 C
+ATOM 1847 C ASN A 312 9.595 24.143 49.383 1.00 19.83 C
+ATOM 1848 O ASN A 312 8.833 23.463 48.692 1.00 21.12 O
+ATOM 1849 CB ASN A 312 9.935 22.806 51.471 1.00 25.12 C
+ATOM 1850 CG ASN A 312 10.748 21.657 52.057 1.00 31.64 C
+ATOM 1851 OD1 ASN A 312 11.223 20.769 51.329 1.00 21.02 O
+ATOM 1852 ND2 ASN A 312 10.890 21.653 53.376 1.00 28.64 N
+ATOM 1853 N VAL A 313 9.555 25.472 49.393 1.00 17.61 N
+ATOM 1854 CA VAL A 313 8.634 26.201 48.527 1.00 17.75 C
+ATOM 1855 C VAL A 313 9.384 26.450 47.232 1.00 16.80 C
+ATOM 1856 O VAL A 313 8.874 26.195 46.141 1.00 17.19 O
+ATOM 1857 CB VAL A 313 8.205 27.560 49.143 1.00 21.55 C
+ATOM 1858 CG1 VAL A 313 7.275 28.306 48.189 1.00 17.70 C
+ATOM 1859 CG2 VAL A 313 7.493 27.320 50.458 1.00 23.28 C
+ATOM 1860 N MET A 314 10.621 26.923 47.368 1.00 18.04 N
+ATOM 1861 CA MET A 314 11.480 27.214 46.222 1.00 18.68 C
+ATOM 1862 C MET A 314 11.503 26.087 45.207 1.00 20.46 C
+ATOM 1863 O MET A 314 11.305 26.310 44.010 1.00 20.56 O
+ATOM 1864 CB MET A 314 12.930 27.457 46.672 1.00 15.46 C
+ATOM 1865 CG MET A 314 13.138 28.682 47.532 1.00 17.78 C
+ATOM 1866 SD MET A 314 14.850 28.795 48.104 1.00 18.85 S
+ATOM 1867 CE MET A 314 14.719 30.236 49.097 1.00 18.47 C
+ATOM 1868 N LYS A 315 11.762 24.878 45.700 1.00 18.47 N
+ATOM 1869 CA LYS A 315 11.873 23.715 44.836 1.00 16.63 C
+ATOM 1870 C LYS A 315 10.637 23.450 43.982 1.00 17.57 C
+ATOM 1871 O LYS A 315 10.749 22.863 42.907 1.00 15.37 O
+ATOM 1872 CB LYS A 315 12.217 22.463 45.660 1.00 17.24 C
+ATOM 1873 CG LYS A 315 11.118 21.964 46.604 1.00 13.83 C
+ATOM 1874 CD LYS A 315 11.591 20.696 47.325 1.00 20.29 C
+ATOM 1875 CE LYS A 315 10.528 20.120 48.254 1.00 20.68 C
+ATOM 1876 NZ LYS A 315 11.002 18.902 48.975 1.00 21.23 N
+ATOM 1877 N THR A 316 9.471 23.897 44.443 1.00 15.07 N
+ATOM 1878 CA THR A 316 8.230 23.669 43.704 1.00 14.10 C
+ATOM 1879 C THR A 316 7.994 24.686 42.595 1.00 16.62 C
+ATOM 1880 O THR A 316 7.054 24.538 41.804 1.00 15.89 O
+ATOM 1881 CB THR A 316 6.999 23.758 44.614 1.00 15.95 C
+ATOM 1882 OG1 THR A 316 6.789 25.128 44.976 1.00 13.19 O
+ATOM 1883 CG2 THR A 316 7.190 22.918 45.878 1.00 16.07 C
+ATOM 1884 N LEU A 317 8.824 25.724 42.543 1.00 13.11 N
+ATOM 1885 CA LEU A 317 8.653 26.766 41.539 1.00 15.78 C
+ATOM 1886 C LEU A 317 9.430 26.387 40.292 1.00 16.96 C
+ATOM 1887 O LEU A 317 10.494 26.923 40.003 1.00 19.00 O
+ATOM 1888 CB LEU A 317 9.105 28.115 42.108 1.00 15.26 C
+ATOM 1889 CG LEU A 317 8.276 28.559 43.323 1.00 17.24 C
+ATOM 1890 CD1 LEU A 317 8.942 29.722 44.036 1.00 17.59 C
+ATOM 1891 CD2 LEU A 317 6.865 28.940 42.872 1.00 16.70 C
+ATOM 1892 N GLN A 318 8.871 25.429 39.566 1.00 16.55 N
+ATOM 1893 CA GLN A 318 9.475 24.913 38.355 1.00 16.18 C
+ATOM 1894 C GLN A 318 8.886 25.577 37.128 1.00 18.61 C
+ATOM 1895 O GLN A 318 7.683 25.496 36.888 1.00 15.96 O
+ATOM 1896 CB GLN A 318 9.287 23.395 38.318 1.00 16.71 C
+ATOM 1897 CG GLN A 318 10.088 22.708 39.418 1.00 20.71 C
+ATOM 1898 CD GLN A 318 9.785 21.234 39.555 1.00 25.18 C
+ATOM 1899 OE1 GLN A 318 9.697 20.512 38.568 1.00 30.99 O
+ATOM 1900 NE2 GLN A 318 9.654 20.776 40.788 1.00 27.99 N
+ATOM 1901 N HIS A 319 9.758 26.234 36.365 1.00 18.10 N
+ATOM 1902 CA HIS A 319 9.384 26.961 35.155 1.00 16.65 C
+ATOM 1903 C HIS A 319 10.649 27.111 34.309 1.00 19.02 C
+ATOM 1904 O HIS A 319 11.763 27.132 34.841 1.00 15.68 O
+ATOM 1905 CB HIS A 319 8.813 28.330 35.551 1.00 16.05 C
+ATOM 1906 CG HIS A 319 8.300 29.141 34.402 1.00 14.40 C
+ATOM 1907 ND1 HIS A 319 9.128 29.819 33.535 1.00 15.01 N
+ATOM 1908 CD2 HIS A 319 7.036 29.359 33.964 1.00 15.99 C
+ATOM 1909 CE1 HIS A 319 8.397 30.421 32.612 1.00 14.70 C
+ATOM 1910 NE2 HIS A 319 7.125 30.158 32.850 1.00 14.71 N
+ATOM 1911 N ASP A 320 10.481 27.198 32.994 1.00 17.74 N
+ATOM 1912 CA ASP A 320 11.622 27.315 32.091 1.00 17.58 C
+ATOM 1913 C ASP A 320 12.471 28.550 32.379 1.00 15.62 C
+ATOM 1914 O ASP A 320 13.663 28.570 32.080 1.00 14.58 O
+ATOM 1915 CB ASP A 320 11.143 27.360 30.637 1.00 18.00 C
+ATOM 1916 CG ASP A 320 12.287 27.302 29.647 1.00 19.92 C
+ATOM 1917 OD1 ASP A 320 12.985 26.273 29.623 1.00 24.25 O
+ATOM 1918 OD2 ASP A 320 12.505 28.281 28.903 1.00 20.55 O
+ATOM 1919 N LYS A 321 11.870 29.580 32.964 1.00 14.85 N
+ATOM 1920 CA LYS A 321 12.633 30.789 33.239 1.00 13.49 C
+ATOM 1921 C LYS A 321 13.135 30.929 34.685 1.00 13.33 C
+ATOM 1922 O LYS A 321 13.540 32.013 35.106 1.00 11.88 O
+ATOM 1923 CB LYS A 321 11.821 32.019 32.811 1.00 17.25 C
+ATOM 1924 CG LYS A 321 11.384 31.983 31.323 1.00 15.29 C
+ATOM 1925 CD LYS A 321 12.585 31.725 30.394 1.00 18.62 C
+ATOM 1926 CE LYS A 321 12.200 31.747 28.913 1.00 16.22 C
+ATOM 1927 NZ LYS A 321 11.175 30.715 28.577 1.00 19.77 N
+ATOM 1928 N LEU A 322 13.107 29.831 35.438 1.00 13.13 N
+ATOM 1929 CA LEU A 322 13.611 29.811 36.817 1.00 13.45 C
+ATOM 1930 C LEU A 322 14.647 28.691 36.920 1.00 12.10 C
+ATOM 1931 O LEU A 322 14.430 27.594 36.408 1.00 10.81 O
+ATOM 1932 CB LEU A 322 12.507 29.521 37.842 1.00 12.32 C
+ATOM 1933 CG LEU A 322 11.250 30.385 37.994 1.00 23.08 C
+ATOM 1934 CD1 LEU A 322 10.857 30.386 39.477 1.00 15.28 C
+ATOM 1935 CD2 LEU A 322 11.483 31.802 37.524 1.00 14.60 C
+ATOM 1936 N VAL A 323 15.768 28.949 37.583 1.00 14.70 N
+ATOM 1937 CA VAL A 323 16.778 27.908 37.706 1.00 14.93 C
+ATOM 1938 C VAL A 323 16.204 26.788 38.562 1.00 13.52 C
+ATOM 1939 O VAL A 323 15.516 27.046 39.551 1.00 14.82 O
+ATOM 1940 CB VAL A 323 18.077 28.443 38.360 1.00 17.27 C
+ATOM 1941 CG1 VAL A 323 17.822 28.817 39.817 1.00 18.14 C
+ATOM 1942 CG2 VAL A 323 19.185 27.387 38.253 1.00 20.32 C
+ATOM 1943 N LYS A 324 16.464 25.547 38.168 1.00 12.64 N
+ATOM 1944 CA LYS A 324 15.982 24.400 38.922 1.00 14.11 C
+ATOM 1945 C LYS A 324 16.808 24.204 40.179 1.00 16.16 C
+ATOM 1946 O LYS A 324 18.038 24.276 40.142 1.00 14.98 O
+ATOM 1947 CB LYS A 324 16.072 23.113 38.101 1.00 21.41 C
+ATOM 1948 CG LYS A 324 15.115 23.009 36.943 1.00 25.02 C
+ATOM 1949 CD LYS A 324 15.326 21.677 36.241 1.00 32.39 C
+ATOM 1950 CE LYS A 324 14.437 21.549 35.023 1.00 33.81 C
+ATOM 1951 NZ LYS A 324 14.717 20.280 34.303 1.00 45.18 N
+ATOM 1952 N LEU A 325 16.114 23.937 41.279 1.00 16.03 N
+ATOM 1953 CA LEU A 325 16.736 23.686 42.571 1.00 19.27 C
+ATOM 1954 C LEU A 325 16.613 22.177 42.830 1.00 23.60 C
+ATOM 1955 O LEU A 325 15.532 21.682 43.158 1.00 26.38 O
+ATOM 1956 CB LEU A 325 16.013 24.500 43.652 1.00 21.46 C
+ATOM 1957 CG LEU A 325 16.439 24.321 45.108 1.00 28.39 C
+ATOM 1958 CD1 LEU A 325 17.948 24.305 45.210 1.00 31.26 C
+ATOM 1959 CD2 LEU A 325 15.847 25.444 45.949 1.00 30.33 C
+ATOM 1960 N HIS A 326 17.721 21.453 42.671 1.00 17.38 N
+ATOM 1961 CA HIS A 326 17.740 19.996 42.843 1.00 18.99 C
+ATOM 1962 C HIS A 326 17.739 19.438 44.265 1.00 19.18 C
+ATOM 1963 O HIS A 326 17.030 18.475 44.573 1.00 20.29 O
+ATOM 1964 CB HIS A 326 18.966 19.384 42.167 1.00 17.18 C
+ATOM 1965 CG HIS A 326 19.064 19.640 40.699 1.00 18.26 C
+ATOM 1966 ND1 HIS A 326 18.037 19.369 39.819 1.00 20.27 N
+ATOM 1967 CD2 HIS A 326 20.113 20.039 39.939 1.00 17.74 C
+ATOM 1968 CE1 HIS A 326 18.451 19.586 38.584 1.00 21.97 C
+ATOM 1969 NE2 HIS A 326 19.706 19.993 38.628 1.00 18.61 N
+ATOM 1970 N ALA A 327 18.561 20.017 45.129 1.00 14.51 N
+ATOM 1971 CA ALA A 327 18.678 19.481 46.473 1.00 14.10 C
+ATOM 1972 C ALA A 327 19.393 20.444 47.400 1.00 9.97 C
+ATOM 1973 O ALA A 327 19.811 21.524 46.985 1.00 12.97 O
+ATOM 1974 CB ALA A 327 19.449 18.162 46.409 1.00 14.09 C
+ATOM 1975 N VAL A 328 19.529 20.033 48.657 1.00 13.67 N
+ATOM 1976 CA VAL A 328 20.206 20.832 49.671 1.00 13.56 C
+ATOM 1977 C VAL A 328 20.965 19.926 50.640 1.00 14.33 C
+ATOM 1978 O VAL A 328 20.641 18.750 50.777 1.00 15.51 O
+ATOM 1979 CB VAL A 328 19.194 21.653 50.521 1.00 14.43 C
+ATOM 1980 CG1 VAL A 328 18.439 22.638 49.650 1.00 15.37 C
+ATOM 1981 CG2 VAL A 328 18.215 20.703 51.230 1.00 9.80 C
+ATOM 1982 N VAL A 329 21.992 20.474 51.285 1.00 16.08 N
+ATOM 1983 CA VAL A 329 22.726 19.748 52.320 1.00 14.33 C
+ATOM 1984 C VAL A 329 22.300 20.587 53.508 1.00 14.35 C
+ATOM 1985 O VAL A 329 22.592 21.774 53.552 1.00 13.72 O
+ATOM 1986 CB VAL A 329 24.259 19.801 52.145 1.00 14.11 C
+ATOM 1987 CG1 VAL A 329 24.947 19.198 53.396 1.00 14.01 C
+ATOM 1988 CG2 VAL A 329 24.660 18.999 50.928 1.00 12.76 C
+ATOM 1989 N THR A 330 21.586 19.965 54.447 1.00 16.89 N
+ATOM 1990 CA THR A 330 21.005 20.639 55.617 1.00 21.91 C
+ATOM 1991 C THR A 330 21.876 21.059 56.809 1.00 25.35 C
+ATOM 1992 O THR A 330 21.403 21.802 57.674 1.00 25.25 O
+ATOM 1993 CB THR A 330 19.849 19.791 56.192 1.00 21.06 C
+ATOM 1994 OG1 THR A 330 20.368 18.545 56.670 1.00 25.52 O
+ATOM 1995 CG2 THR A 330 18.822 19.489 55.125 1.00 23.97 C
+ATOM 1996 N LYS A 331 23.121 20.594 56.876 1.00 20.91 N
+ATOM 1997 CA LYS A 331 24.000 20.955 57.998 1.00 20.86 C
+ATOM 1998 C LYS A 331 24.982 22.042 57.569 1.00 21.05 C
+ATOM 1999 O LYS A 331 25.442 22.043 56.434 1.00 19.74 O
+ATOM 2000 CB LYS A 331 24.775 19.727 58.480 1.00 17.91 C
+ATOM 2001 CG LYS A 331 23.899 18.553 58.897 1.00 20.30 C
+ATOM 2002 CD LYS A 331 23.017 18.883 60.091 1.00 24.96 C
+ATOM 2003 CE LYS A 331 22.121 17.699 60.417 1.00 30.86 C
+ATOM 2004 NZ LYS A 331 21.263 17.936 61.609 1.00 38.75 N
+ATOM 2005 N GLU A 332 25.320 22.963 58.467 1.00 17.36 N
+ATOM 2006 CA GLU A 332 26.241 24.031 58.099 1.00 18.95 C
+ATOM 2007 C GLU A 332 27.626 23.474 57.776 1.00 15.37 C
+ATOM 2008 O GLU A 332 28.109 22.562 58.436 1.00 16.86 O
+ATOM 2009 CB GLU A 332 26.336 25.085 59.214 1.00 20.65 C
+ATOM 2010 CG GLU A 332 25.023 25.801 59.503 1.00 23.30 C
+ATOM 2011 CD GLU A 332 25.179 26.955 60.483 1.00 29.74 C
+ATOM 2012 OE1 GLU A 332 25.741 26.737 61.577 1.00 29.11 O
+ATOM 2013 OE2 GLU A 332 24.733 28.079 60.162 1.00 27.22 O
+ATOM 2014 N PRO A 333 28.274 24.010 56.736 1.00 16.32 N
+ATOM 2015 CA PRO A 333 27.774 25.084 55.875 1.00 15.48 C
+ATOM 2016 C PRO A 333 26.707 24.546 54.909 1.00 16.58 C
+ATOM 2017 O PRO A 333 26.911 23.531 54.246 1.00 15.81 O
+ATOM 2018 CB PRO A 333 29.045 25.546 55.170 1.00 15.00 C
+ATOM 2019 CG PRO A 333 29.733 24.233 54.938 1.00 13.90 C
+ATOM 2020 CD PRO A 333 29.632 23.614 56.319 1.00 18.41 C
+ATOM 2021 N ILE A 334 25.572 25.236 54.836 1.00 16.66 N
+ATOM 2022 CA ILE A 334 24.465 24.819 53.978 1.00 16.79 C
+ATOM 2023 C ILE A 334 24.818 24.847 52.490 1.00 13.40 C
+ATOM 2024 O ILE A 334 25.486 25.761 52.030 1.00 17.71 O
+ATOM 2025 CB ILE A 334 23.212 25.721 54.212 1.00 18.98 C
+ATOM 2026 CG1 ILE A 334 22.719 25.579 55.658 1.00 20.00 C
+ATOM 2027 CG2 ILE A 334 22.105 25.380 53.203 1.00 18.44 C
+ATOM 2028 CD1 ILE A 334 22.442 24.177 56.085 1.00 24.45 C
+ATOM 2029 N TYR A 335 24.380 23.824 51.755 1.00 14.15 N
+ATOM 2030 CA TYR A 335 24.594 23.732 50.308 1.00 16.78 C
+ATOM 2031 C TYR A 335 23.245 23.769 49.589 1.00 16.48 C
+ATOM 2032 O TYR A 335 22.311 23.075 49.994 1.00 14.65 O
+ATOM 2033 CB TYR A 335 25.283 22.414 49.917 1.00 17.87 C
+ATOM 2034 CG TYR A 335 26.768 22.336 50.193 1.00 19.62 C
+ATOM 2035 CD1 TYR A 335 27.463 23.422 50.730 1.00 21.36 C
+ATOM 2036 CD2 TYR A 335 27.490 21.182 49.882 1.00 23.68 C
+ATOM 2037 CE1 TYR A 335 28.844 23.362 50.947 1.00 26.88 C
+ATOM 2038 CE2 TYR A 335 28.877 21.113 50.096 1.00 26.23 C
+ATOM 2039 CZ TYR A 335 29.541 22.207 50.626 1.00 26.30 C
+ATOM 2040 OH TYR A 335 30.903 22.159 50.820 1.00 30.70 O
+ATOM 2041 N ILE A 336 23.156 24.580 48.536 1.00 15.82 N
+ATOM 2042 CA ILE A 336 21.956 24.684 47.713 1.00 15.43 C
+ATOM 2043 C ILE A 336 22.412 24.210 46.333 1.00 15.22 C
+ATOM 2044 O ILE A 336 23.196 24.898 45.662 1.00 14.91 O
+ATOM 2045 CB ILE A 336 21.462 26.136 47.589 1.00 18.57 C
+ATOM 2046 CG1 ILE A 336 21.295 26.756 48.975 1.00 21.01 C
+ATOM 2047 CG2 ILE A 336 20.125 26.154 46.859 1.00 19.38 C
+ATOM 2048 CD1 ILE A 336 20.873 28.225 48.956 1.00 21.72 C
+ATOM 2049 N ILE A 337 21.936 23.036 45.921 1.00 11.75 N
+ATOM 2050 CA ILE A 337 22.332 22.464 44.645 1.00 11.57 C
+ATOM 2051 C ILE A 337 21.340 22.778 43.527 1.00 13.31 C
+ATOM 2052 O ILE A 337 20.151 22.481 43.639 1.00 12.17 O
+ATOM 2053 CB ILE A 337 22.512 20.919 44.741 1.00 11.70 C
+ATOM 2054 CG1 ILE A 337 23.574 20.555 45.799 1.00 11.90 C
+ATOM 2055 CG2 ILE A 337 22.970 20.364 43.378 1.00 13.51 C
+ATOM 2056 CD1 ILE A 337 23.040 20.495 47.246 1.00 13.64 C
+ATOM 2057 N THR A 338 21.833 23.380 42.450 1.00 12.31 N
+ATOM 2058 CA THR A 338 20.973 23.725 41.324 1.00 13.77 C
+ATOM 2059 C THR A 338 21.597 23.262 40.025 1.00 16.68 C
+ATOM 2060 O THR A 338 22.712 22.723 40.003 1.00 13.07 O
+ATOM 2061 CB THR A 338 20.760 25.248 41.197 1.00 15.11 C
+ATOM 2062 OG1 THR A 338 21.973 25.864 40.747 1.00 17.45 O
+ATOM 2063 CG2 THR A 338 20.365 25.852 42.540 1.00 16.61 C
+ATOM 2064 N GLU A 339 20.873 23.472 38.934 1.00 17.77 N
+ATOM 2065 CA GLU A 339 21.397 23.102 37.633 1.00 16.28 C
+ATOM 2066 C GLU A 339 22.510 24.107 37.329 1.00 17.39 C
+ATOM 2067 O GLU A 339 22.509 25.218 37.858 1.00 15.68 O
+ATOM 2068 CB GLU A 339 20.286 23.167 36.573 1.00 20.60 C
+ATOM 2069 CG GLU A 339 19.679 24.546 36.348 1.00 19.80 C
+ATOM 2070 CD GLU A 339 18.532 24.504 35.353 1.00 23.99 C
+ATOM 2071 OE1 GLU A 339 18.700 23.867 34.288 1.00 23.85 O
+ATOM 2072 OE2 GLU A 339 17.475 25.112 35.630 1.00 16.41 O
+ATOM 2073 N PHE A 340 23.468 23.706 36.502 1.00 17.92 N
+ATOM 2074 CA PHE A 340 24.586 24.570 36.132 1.00 17.78 C
+ATOM 2075 C PHE A 340 24.275 25.358 34.860 1.00 18.48 C
+ATOM 2076 O PHE A 340 23.824 24.791 33.869 1.00 17.53 O
+ATOM 2077 CB PHE A 340 25.834 23.717 35.912 1.00 17.42 C
+ATOM 2078 CG PHE A 340 26.961 24.457 35.281 1.00 19.75 C
+ATOM 2079 CD1 PHE A 340 27.610 25.478 35.962 1.00 19.92 C
+ATOM 2080 CD2 PHE A 340 27.346 24.167 33.979 1.00 18.46 C
+ATOM 2081 CE1 PHE A 340 28.626 26.203 35.358 1.00 20.94 C
+ATOM 2082 CE2 PHE A 340 28.366 24.890 33.361 1.00 23.96 C
+ATOM 2083 CZ PHE A 340 29.004 25.911 34.056 1.00 20.30 C
+ATOM 2084 N MET A 341 24.523 26.664 34.891 1.00 18.66 N
+ATOM 2085 CA MET A 341 24.271 27.523 33.736 1.00 20.97 C
+ATOM 2086 C MET A 341 25.602 27.965 33.124 1.00 21.27 C
+ATOM 2087 O MET A 341 26.352 28.750 33.709 1.00 19.04 O
+ATOM 2088 CB MET A 341 23.418 28.720 34.162 1.00 21.30 C
+ATOM 2089 CG MET A 341 22.003 28.312 34.559 1.00 25.04 C
+ATOM 2090 SD MET A 341 21.047 27.703 33.147 1.00 29.08 S
+ATOM 2091 CE MET A 341 19.614 27.114 33.960 1.00 35.21 C
+ATOM 2092 N ALA A 342 25.879 27.435 31.937 1.00 20.33 N
+ATOM 2093 CA ALA A 342 27.125 27.675 31.219 1.00 22.34 C
+ATOM 2094 C ALA A 342 27.597 29.113 31.063 1.00 22.58 C
+ATOM 2095 O ALA A 342 28.796 29.373 31.129 1.00 23.85 O
+ATOM 2096 CB ALA A 342 27.058 26.994 29.836 1.00 22.89 C
+ATOM 2097 N LYS A 343 26.680 30.056 30.876 1.00 22.00 N
+ATOM 2098 CA LYS A 343 27.108 31.437 30.685 1.00 23.86 C
+ATOM 2099 C LYS A 343 27.078 32.400 31.867 1.00 23.05 C
+ATOM 2100 O LYS A 343 27.114 33.609 31.674 1.00 23.00 O
+ATOM 2101 CB LYS A 343 26.362 32.041 29.498 1.00 26.46 C
+ATOM 2102 CG LYS A 343 26.722 31.358 28.186 1.00 33.46 C
+ATOM 2103 CD LYS A 343 26.003 31.979 27.009 1.00 36.60 C
+ATOM 2104 CE LYS A 343 26.340 31.246 25.724 1.00 39.07 C
+ATOM 2105 NZ LYS A 343 27.796 31.297 25.444 1.00 41.33 N
+ATOM 2106 N GLY A 344 27.021 31.866 33.083 1.00 23.98 N
+ATOM 2107 CA GLY A 344 27.037 32.706 34.270 1.00 19.79 C
+ATOM 2108 C GLY A 344 25.865 33.643 34.478 1.00 16.74 C
+ATOM 2109 O GLY A 344 24.763 33.381 34.005 1.00 19.56 O
+ATOM 2110 N SER A 345 26.097 34.733 35.205 1.00 17.29 N
+ATOM 2111 CA SER A 345 25.033 35.697 35.470 1.00 20.81 C
+ATOM 2112 C SER A 345 24.841 36.605 34.269 1.00 22.11 C
+ATOM 2113 O SER A 345 25.773 36.842 33.492 1.00 21.87 O
+ATOM 2114 CB SER A 345 25.357 36.558 36.690 1.00 18.24 C
+ATOM 2115 OG SER A 345 26.481 37.380 36.440 1.00 26.65 O
+ATOM 2116 N LEU A 346 23.624 37.111 34.122 1.00 21.12 N
+ATOM 2117 CA LEU A 346 23.298 38.006 33.022 1.00 18.63 C
+ATOM 2118 C LEU A 346 24.206 39.221 33.124 1.00 19.00 C
+ATOM 2119 O LEU A 346 24.618 39.798 32.119 1.00 16.47 O
+ATOM 2120 CB LEU A 346 21.835 38.436 33.118 1.00 15.56 C
+ATOM 2121 CG LEU A 346 21.323 39.424 32.068 1.00 15.10 C
+ATOM 2122 CD1 LEU A 346 21.512 38.843 30.688 1.00 13.80 C
+ATOM 2123 CD2 LEU A 346 19.850 39.722 32.321 1.00 20.80 C
+ATOM 2124 N LEU A 347 24.521 39.601 34.353 1.00 19.15 N
+ATOM 2125 CA LEU A 347 25.383 40.743 34.581 1.00 25.59 C
+ATOM 2126 C LEU A 347 26.747 40.512 33.923 1.00 27.21 C
+ATOM 2127 O LEU A 347 27.177 41.306 33.091 1.00 30.86 O
+ATOM 2128 CB LEU A 347 25.535 40.985 36.083 1.00 25.16 C
+ATOM 2129 CG LEU A 347 26.338 42.224 36.468 1.00 29.44 C
+ATOM 2130 CD1 LEU A 347 25.701 43.460 35.837 1.00 25.05 C
+ATOM 2131 CD2 LEU A 347 26.395 42.347 37.979 1.00 29.42 C
+ATOM 2132 N ASP A 348 27.422 39.421 34.271 1.00 30.77 N
+ATOM 2133 CA ASP A 348 28.725 39.146 33.670 1.00 31.67 C
+ATOM 2134 C ASP A 348 28.598 38.970 32.163 1.00 31.26 C
+ATOM 2135 O ASP A 348 29.439 39.450 31.400 1.00 31.04 O
+ATOM 2136 CB ASP A 348 29.361 37.880 34.248 1.00 32.75 C
+ATOM 2137 CG ASP A 348 29.588 37.964 35.740 1.00 35.56 C
+ATOM 2138 OD1 ASP A 348 29.991 39.039 36.246 1.00 36.10 O
+ATOM 2139 OD2 ASP A 348 29.390 36.927 36.402 1.00 38.06 O
+ATOM 2140 N PHE A 349 27.547 38.274 31.738 1.00 26.76 N
+ATOM 2141 CA PHE A 349 27.320 38.036 30.318 1.00 26.10 C
+ATOM 2142 C PHE A 349 27.177 39.330 29.524 1.00 26.54 C
+ATOM 2143 O PHE A 349 27.744 39.469 28.444 1.00 27.64 O
+ATOM 2144 CB PHE A 349 26.069 37.183 30.108 1.00 26.31 C
+ATOM 2145 CG PHE A 349 25.718 36.979 28.665 1.00 27.32 C
+ATOM 2146 CD1 PHE A 349 26.569 36.273 27.823 1.00 27.28 C
+ATOM 2147 CD2 PHE A 349 24.555 37.528 28.135 1.00 28.35 C
+ATOM 2148 CE1 PHE A 349 26.268 36.118 26.474 1.00 30.42 C
+ATOM 2149 CE2 PHE A 349 24.243 37.382 26.792 1.00 27.67 C
+ATOM 2150 CZ PHE A 349 25.101 36.675 25.956 1.00 32.35 C
+ATOM 2151 N LEU A 350 26.420 40.284 30.051 1.00 27.29 N
+ATOM 2152 CA LEU A 350 26.230 41.542 29.337 1.00 27.47 C
+ATOM 2153 C LEU A 350 27.496 42.389 29.252 1.00 30.80 C
+ATOM 2154 O LEU A 350 27.680 43.143 28.295 1.00 25.94 O
+ATOM 2155 CB LEU A 350 25.109 42.357 29.982 1.00 25.12 C
+ATOM 2156 CG LEU A 350 23.712 41.739 29.865 1.00 26.95 C
+ATOM 2157 CD1 LEU A 350 22.701 42.626 30.565 1.00 24.57 C
+ATOM 2158 CD2 LEU A 350 23.352 41.567 28.399 1.00 24.89 C
+ATOM 2159 N LYS A 351 28.365 42.259 30.250 1.00 32.08 N
+ATOM 2160 CA LYS A 351 29.605 43.026 30.288 1.00 32.65 C
+ATOM 2161 C LYS A 351 30.722 42.326 29.513 1.00 33.49 C
+ATOM 2162 O LYS A 351 31.806 42.884 29.332 1.00 33.40 O
+ATOM 2163 CB LYS A 351 30.028 43.255 31.747 1.00 33.97 C
+ATOM 2164 CG LYS A 351 28.988 44.030 32.582 1.00 33.62 C
+ATOM 2165 CD LYS A 351 29.295 44.027 34.088 1.00 32.98 C
+ATOM 2166 CE LYS A 351 30.617 44.699 34.424 1.00 40.12 C
+ATOM 2167 NZ LYS A 351 30.638 46.137 34.023 1.00 44.71 N
+ATOM 2168 N SER A 352 30.451 41.108 29.052 1.00 33.22 N
+ATOM 2169 CA SER A 352 31.438 40.348 28.296 1.00 33.96 C
+ATOM 2170 C SER A 352 31.370 40.741 26.827 1.00 36.28 C
+ATOM 2171 O SER A 352 30.516 41.532 26.424 1.00 34.02 O
+ATOM 2172 CB SER A 352 31.178 38.849 28.411 1.00 33.05 C
+ATOM 2173 OG SER A 352 30.075 38.463 27.610 1.00 31.80 O
+ATOM 2174 N ASP A 353 32.258 40.157 26.028 1.00 37.43 N
+ATOM 2175 CA ASP A 353 32.322 40.452 24.600 1.00 38.14 C
+ATOM 2176 C ASP A 353 31.059 40.007 23.862 1.00 36.66 C
+ATOM 2177 O ASP A 353 30.425 40.802 23.162 1.00 35.51 O
+ATOM 2178 CB ASP A 353 33.557 39.783 23.983 1.00 38.45 C
+ATOM 2179 CG ASP A 353 33.795 40.211 22.546 1.00 41.95 C
+ATOM 2180 OD1 ASP A 353 33.969 41.426 22.310 1.00 37.79 O
+ATOM 2181 OD2 ASP A 353 33.809 39.336 21.653 1.00 45.21 O
+ATOM 2182 N GLU A 354 30.694 38.738 24.011 1.00 35.14 N
+ATOM 2183 CA GLU A 354 29.497 38.228 23.352 1.00 35.63 C
+ATOM 2184 C GLU A 354 28.272 39.015 23.798 1.00 34.76 C
+ATOM 2185 O GLU A 354 27.299 39.144 23.054 1.00 35.50 O
+ATOM 2186 CB GLU A 354 29.297 36.746 23.666 1.00 36.91 C
+ATOM 2187 CG GLU A 354 27.926 36.221 23.275 1.00 40.58 C
+ATOM 2188 CD GLU A 354 27.744 34.761 23.620 1.00 42.30 C
+ATOM 2189 OE1 GLU A 354 28.203 34.357 24.707 1.00 45.83 O
+ATOM 2190 OE2 GLU A 354 27.124 34.023 22.826 1.00 43.84 O
+ATOM 2191 N GLY A 355 28.326 39.543 25.015 1.00 33.88 N
+ATOM 2192 CA GLY A 355 27.208 40.313 25.529 1.00 35.31 C
+ATOM 2193 C GLY A 355 27.081 41.682 24.885 1.00 33.69 C
+ATOM 2194 O GLY A 355 25.974 42.148 24.610 1.00 33.05 O
+ATOM 2195 N SER A 356 28.215 42.332 24.640 1.00 33.69 N
+ATOM 2196 CA SER A 356 28.210 43.656 24.030 1.00 34.85 C
+ATOM 2197 C SER A 356 27.623 43.596 22.622 1.00 34.90 C
+ATOM 2198 O SER A 356 27.107 44.590 22.116 1.00 35.64 O
+ATOM 2199 CB SER A 356 29.635 44.222 23.970 1.00 35.14 C
+ATOM 2200 OG SER A 356 30.459 43.436 23.124 1.00 37.58 O
+ATOM 2201 N LYS A 357 27.692 42.428 21.995 1.00 33.23 N
+ATOM 2202 CA LYS A 357 27.178 42.267 20.638 1.00 35.36 C
+ATOM 2203 C LYS A 357 25.682 41.948 20.553 1.00 34.05 C
+ATOM 2204 O LYS A 357 25.147 41.766 19.457 1.00 32.78 O
+ATOM 2205 CB LYS A 357 27.966 41.180 19.906 1.00 36.98 C
+ATOM 2206 CG LYS A 357 29.453 41.469 19.755 1.00 41.65 C
+ATOM 2207 CD LYS A 357 30.141 40.330 19.014 1.00 45.86 C
+ATOM 2208 CE LYS A 357 31.635 40.572 18.847 1.00 47.52 C
+ATOM 2209 NZ LYS A 357 32.259 39.451 18.087 1.00 48.88 N
+ATOM 2210 N GLN A 358 25.012 41.867 21.696 1.00 31.52 N
+ATOM 2211 CA GLN A 358 23.581 41.577 21.701 1.00 31.01 C
+ATOM 2212 C GLN A 358 22.817 42.855 21.362 1.00 30.49 C
+ATOM 2213 O GLN A 358 22.917 43.848 22.079 1.00 31.21 O
+ATOM 2214 CB GLN A 358 23.129 41.070 23.079 1.00 30.82 C
+ATOM 2215 CG GLN A 358 23.859 39.832 23.581 1.00 29.67 C
+ATOM 2216 CD GLN A 358 23.771 38.655 22.621 1.00 31.98 C
+ATOM 2217 OE1 GLN A 358 22.686 38.142 22.333 1.00 31.27 O
+ATOM 2218 NE2 GLN A 358 24.922 38.221 22.121 1.00 31.56 N
+ATOM 2219 N PRO A 359 22.059 42.853 20.253 1.00 31.12 N
+ATOM 2220 CA PRO A 359 21.267 44.004 19.808 1.00 31.81 C
+ATOM 2221 C PRO A 359 20.101 44.318 20.755 1.00 32.80 C
+ATOM 2222 O PRO A 359 19.622 43.441 21.475 1.00 30.98 O
+ATOM 2223 CB PRO A 359 20.790 43.560 18.428 1.00 33.21 C
+ATOM 2224 CG PRO A 359 20.592 42.086 18.643 1.00 33.82 C
+ATOM 2225 CD PRO A 359 21.926 41.756 19.281 1.00 30.97 C
+ATOM 2226 N LEU A 360 19.642 45.566 20.740 1.00 31.85 N
+ATOM 2227 CA LEU A 360 18.544 45.997 21.604 1.00 31.30 C
+ATOM 2228 C LEU A 360 17.344 45.043 21.610 1.00 28.87 C
+ATOM 2229 O LEU A 360 16.766 44.779 22.662 1.00 30.11 O
+ATOM 2230 CB LEU A 360 18.091 47.405 21.209 1.00 32.24 C
+ATOM 2231 CG LEU A 360 16.956 48.034 22.021 1.00 34.57 C
+ATOM 2232 CD1 LEU A 360 17.328 48.103 23.500 1.00 33.69 C
+ATOM 2233 CD2 LEU A 360 16.676 49.427 21.476 1.00 34.87 C
+ATOM 2234 N PRO A 361 16.929 44.545 20.432 1.00 26.37 N
+ATOM 2235 CA PRO A 361 15.792 43.621 20.376 1.00 26.15 C
+ATOM 2236 C PRO A 361 16.066 42.360 21.206 1.00 25.71 C
+ATOM 2237 O PRO A 361 15.153 41.778 21.804 1.00 19.80 O
+ATOM 2238 CB PRO A 361 15.684 43.319 18.880 1.00 26.77 C
+ATOM 2239 CG PRO A 361 16.149 44.621 18.262 1.00 25.09 C
+ATOM 2240 CD PRO A 361 17.418 44.809 19.070 1.00 28.73 C
+ATOM 2241 N LYS A 362 17.329 41.943 21.234 1.00 23.81 N
+ATOM 2242 CA LYS A 362 17.704 40.758 21.993 1.00 26.32 C
+ATOM 2243 C LYS A 362 17.665 41.076 23.475 1.00 23.24 C
+ATOM 2244 O LYS A 362 17.257 40.244 24.277 1.00 24.59 O
+ATOM 2245 CB LYS A 362 19.104 40.277 21.619 1.00 28.79 C
+ATOM 2246 CG LYS A 362 19.150 38.810 21.220 1.00 36.45 C
+ATOM 2247 CD LYS A 362 18.507 37.908 22.259 1.00 36.15 C
+ATOM 2248 CE LYS A 362 18.428 36.480 21.746 1.00 42.18 C
+ATOM 2249 NZ LYS A 362 17.665 35.586 22.654 1.00 40.93 N
+ATOM 2250 N LEU A 363 18.101 42.277 23.841 1.00 19.76 N
+ATOM 2251 CA LEU A 363 18.082 42.680 25.243 1.00 19.85 C
+ATOM 2252 C LEU A 363 16.631 42.748 25.720 1.00 20.85 C
+ATOM 2253 O LEU A 363 16.320 42.416 26.862 1.00 20.47 O
+ATOM 2254 CB LEU A 363 18.752 44.043 25.415 1.00 20.58 C
+ATOM 2255 CG LEU A 363 20.228 44.145 25.014 1.00 21.75 C
+ATOM 2256 CD1 LEU A 363 20.690 45.584 25.188 1.00 22.46 C
+ATOM 2257 CD2 LEU A 363 21.071 43.203 25.852 1.00 16.66 C
+ATOM 2258 N ILE A 364 15.741 43.186 24.836 1.00 19.92 N
+ATOM 2259 CA ILE A 364 14.333 43.264 25.175 1.00 21.25 C
+ATOM 2260 C ILE A 364 13.800 41.848 25.366 1.00 20.67 C
+ATOM 2261 O ILE A 364 12.989 41.609 26.257 1.00 19.87 O
+ATOM 2262 CB ILE A 364 13.513 43.962 24.061 1.00 24.30 C
+ATOM 2263 CG1 ILE A 364 13.983 45.411 23.891 1.00 24.42 C
+ATOM 2264 CG2 ILE A 364 12.036 43.913 24.395 1.00 21.93 C
+ATOM 2265 CD1 ILE A 364 13.853 46.247 25.130 1.00 25.22 C
+ATOM 2266 N ASP A 365 14.252 40.907 24.535 1.00 18.64 N
+ATOM 2267 CA ASP A 365 13.774 39.538 24.672 1.00 16.40 C
+ATOM 2268 C ASP A 365 14.245 38.955 26.000 1.00 16.52 C
+ATOM 2269 O ASP A 365 13.514 38.194 26.637 1.00 13.93 O
+ATOM 2270 CB ASP A 365 14.238 38.646 23.523 1.00 17.71 C
+ATOM 2271 CG ASP A 365 13.586 37.276 23.573 1.00 18.82 C
+ATOM 2272 OD1 ASP A 365 12.342 37.215 23.542 1.00 20.31 O
+ATOM 2273 OD2 ASP A 365 14.302 36.263 23.662 1.00 22.60 O
+ATOM 2274 N PHE A 366 15.463 39.300 26.414 1.00 15.95 N
+ATOM 2275 CA PHE A 366 15.963 38.835 27.706 1.00 18.95 C
+ATOM 2276 C PHE A 366 15.025 39.382 28.790 1.00 17.56 C
+ATOM 2277 O PHE A 366 14.646 38.675 29.725 1.00 17.73 O
+ATOM 2278 CB PHE A 366 17.382 39.348 27.991 1.00 16.89 C
+ATOM 2279 CG PHE A 366 18.453 38.751 27.114 1.00 18.95 C
+ATOM 2280 CD1 PHE A 366 18.434 37.405 26.780 1.00 20.19 C
+ATOM 2281 CD2 PHE A 366 19.535 39.524 26.696 1.00 19.58 C
+ATOM 2282 CE1 PHE A 366 19.481 36.832 26.043 1.00 24.03 C
+ATOM 2283 CE2 PHE A 366 20.589 38.958 25.960 1.00 22.29 C
+ATOM 2284 CZ PHE A 366 20.559 37.611 25.635 1.00 23.27 C
+ATOM 2285 N SER A 367 14.658 40.653 28.663 1.00 18.26 N
+ATOM 2286 CA SER A 367 13.759 41.282 29.629 1.00 17.05 C
+ATOM 2287 C SER A 367 12.401 40.590 29.657 1.00 15.36 C
+ATOM 2288 O SER A 367 11.797 40.426 30.721 1.00 16.67 O
+ATOM 2289 CB SER A 367 13.568 42.760 29.285 1.00 20.54 C
+ATOM 2290 OG SER A 367 14.791 43.455 29.410 1.00 22.25 O
+ATOM 2291 N ALA A 368 11.919 40.189 28.484 1.00 14.82 N
+ATOM 2292 CA ALA A 368 10.627 39.511 28.372 1.00 13.78 C
+ATOM 2293 C ALA A 368 10.685 38.130 29.025 1.00 16.62 C
+ATOM 2294 O ALA A 368 9.718 37.675 29.648 1.00 14.75 O
+ATOM 2295 CB ALA A 368 10.223 39.379 26.893 1.00 15.33 C
+ATOM 2296 N GLN A 369 11.817 37.451 28.870 1.00 16.05 N
+ATOM 2297 CA GLN A 369 11.978 36.130 29.478 1.00 15.17 C
+ATOM 2298 C GLN A 369 11.916 36.224 30.997 1.00 15.20 C
+ATOM 2299 O GLN A 369 11.254 35.420 31.664 1.00 16.41 O
+ATOM 2300 CB GLN A 369 13.317 35.520 29.078 1.00 15.07 C
+ATOM 2301 CG GLN A 369 13.385 35.023 27.658 1.00 17.98 C
+ATOM 2302 CD GLN A 369 14.743 34.446 27.344 1.00 19.59 C
+ATOM 2303 OE1 GLN A 369 15.293 33.656 28.119 1.00 20.13 O
+ATOM 2304 NE2 GLN A 369 15.291 34.821 26.200 1.00 18.20 N
+ATOM 2305 N ILE A 370 12.616 37.212 31.541 1.00 13.79 N
+ATOM 2306 CA ILE A 370 12.655 37.405 32.983 1.00 14.39 C
+ATOM 2307 C ILE A 370 11.261 37.784 33.488 1.00 13.69 C
+ATOM 2308 O ILE A 370 10.794 37.277 34.511 1.00 16.05 O
+ATOM 2309 CB ILE A 370 13.687 38.497 33.335 1.00 11.90 C
+ATOM 2310 CG1 ILE A 370 15.078 38.044 32.851 1.00 13.41 C
+ATOM 2311 CG2 ILE A 370 13.661 38.778 34.846 1.00 11.91 C
+ATOM 2312 CD1 ILE A 370 16.179 39.093 32.952 1.00 12.55 C
+ATOM 2313 N ALA A 371 10.595 38.671 32.756 1.00 13.16 N
+ATOM 2314 CA ALA A 371 9.252 39.105 33.121 1.00 13.95 C
+ATOM 2315 C ALA A 371 8.342 37.888 33.125 1.00 16.39 C
+ATOM 2316 O ALA A 371 7.434 37.778 33.952 1.00 16.80 O
+ATOM 2317 CB ALA A 371 8.736 40.152 32.117 1.00 15.39 C
+ATOM 2318 N GLU A 372 8.600 36.969 32.200 1.00 16.29 N
+ATOM 2319 CA GLU A 372 7.809 35.750 32.093 1.00 16.17 C
+ATOM 2320 C GLU A 372 8.023 34.904 33.346 1.00 16.52 C
+ATOM 2321 O GLU A 372 7.077 34.343 33.912 1.00 14.28 O
+ATOM 2322 CB GLU A 372 8.242 34.952 30.864 1.00 14.52 C
+ATOM 2323 CG GLU A 372 7.388 33.743 30.592 1.00 18.99 C
+ATOM 2324 CD GLU A 372 7.962 32.876 29.493 1.00 25.72 C
+ATOM 2325 OE1 GLU A 372 8.592 33.431 28.563 1.00 29.13 O
+ATOM 2326 OE2 GLU A 372 7.759 31.648 29.548 1.00 23.99 O
+ATOM 2327 N GLY A 373 9.282 34.808 33.762 1.00 13.85 N
+ATOM 2328 CA GLY A 373 9.610 34.056 34.959 1.00 13.42 C
+ATOM 2329 C GLY A 373 8.966 34.722 36.162 1.00 13.50 C
+ATOM 2330 O GLY A 373 8.442 34.041 37.040 1.00 14.72 O
+ATOM 2331 N MET A 374 9.004 36.053 36.211 1.00 13.49 N
+ATOM 2332 CA MET A 374 8.397 36.769 37.333 1.00 13.38 C
+ATOM 2333 C MET A 374 6.872 36.678 37.319 1.00 12.31 C
+ATOM 2334 O MET A 374 6.238 36.701 38.375 1.00 12.70 O
+ATOM 2335 CB MET A 374 8.849 38.239 37.362 1.00 12.80 C
+ATOM 2336 CG MET A 374 10.338 38.439 37.711 1.00 12.11 C
+ATOM 2337 SD MET A 374 10.789 37.654 39.278 1.00 14.35 S
+ATOM 2338 CE MET A 374 9.528 38.434 40.393 1.00 9.47 C
+ATOM 2339 N ALA A 375 6.273 36.577 36.135 1.00 12.63 N
+ATOM 2340 CA ALA A 375 4.819 36.435 36.061 1.00 11.25 C
+ATOM 2341 C ALA A 375 4.442 35.078 36.662 1.00 10.57 C
+ATOM 2342 O ALA A 375 3.392 34.933 37.286 1.00 13.22 O
+ATOM 2343 CB ALA A 375 4.341 36.528 34.609 1.00 11.31 C
+ATOM 2344 N PHE A 376 5.299 34.080 36.468 1.00 10.92 N
+ATOM 2345 CA PHE A 376 5.060 32.747 37.036 1.00 11.52 C
+ATOM 2346 C PHE A 376 5.121 32.853 38.572 1.00 14.01 C
+ATOM 2347 O PHE A 376 4.273 32.316 39.284 1.00 13.29 O
+ATOM 2348 CB PHE A 376 6.134 31.765 36.543 1.00 16.20 C
+ATOM 2349 CG PHE A 376 6.113 30.431 37.240 1.00 14.99 C
+ATOM 2350 CD1 PHE A 376 5.070 29.534 37.038 1.00 14.80 C
+ATOM 2351 CD2 PHE A 376 7.138 30.080 38.117 1.00 13.65 C
+ATOM 2352 CE1 PHE A 376 5.042 28.297 37.700 1.00 14.65 C
+ATOM 2353 CE2 PHE A 376 7.122 28.850 38.783 1.00 13.50 C
+ATOM 2354 CZ PHE A 376 6.074 27.958 38.574 1.00 15.54 C
+ATOM 2355 N ILE A 377 6.140 33.544 39.075 1.00 14.26 N
+ATOM 2356 CA ILE A 377 6.311 33.738 40.519 1.00 13.38 C
+ATOM 2357 C ILE A 377 5.096 34.493 41.075 1.00 12.93 C
+ATOM 2358 O ILE A 377 4.583 34.178 42.154 1.00 13.57 O
+ATOM 2359 CB ILE A 377 7.635 34.505 40.795 1.00 12.29 C
+ATOM 2360 CG1 ILE A 377 8.815 33.576 40.462 1.00 12.23 C
+ATOM 2361 CG2 ILE A 377 7.691 35.006 42.250 1.00 15.11 C
+ATOM 2362 CD1 ILE A 377 10.191 34.211 40.577 1.00 9.13 C
+ATOM 2363 N GLU A 378 4.636 35.478 40.312 1.00 14.62 N
+ATOM 2364 CA GLU A 378 3.466 36.271 40.672 1.00 16.13 C
+ATOM 2365 C GLU A 378 2.245 35.341 40.790 1.00 16.19 C
+ATOM 2366 O GLU A 378 1.488 35.403 41.767 1.00 14.64 O
+ATOM 2367 CB GLU A 378 3.237 37.332 39.586 1.00 15.81 C
+ATOM 2368 CG GLU A 378 2.102 38.309 39.855 1.00 15.77 C
+ATOM 2369 CD GLU A 378 2.001 39.372 38.783 1.00 15.89 C
+ATOM 2370 OE1 GLU A 378 1.483 39.081 37.678 1.00 13.44 O
+ATOM 2371 OE2 GLU A 378 2.469 40.499 39.041 1.00 16.56 O
+ATOM 2372 N GLN A 379 2.058 34.473 39.797 1.00 14.95 N
+ATOM 2373 CA GLN A 379 0.931 33.538 39.807 1.00 16.33 C
+ATOM 2374 C GLN A 379 0.954 32.564 40.965 1.00 17.32 C
+ATOM 2375 O GLN A 379 -0.101 32.180 41.473 1.00 15.68 O
+ATOM 2376 CB GLN A 379 0.855 32.733 38.501 1.00 19.31 C
+ATOM 2377 CG GLN A 379 0.359 33.552 37.345 1.00 27.32 C
+ATOM 2378 CD GLN A 379 -1.024 34.133 37.607 1.00 34.26 C
+ATOM 2379 OE1 GLN A 379 -1.336 35.241 37.161 1.00 37.20 O
+ATOM 2380 NE2 GLN A 379 -1.865 33.380 38.316 1.00 30.52 N
+ATOM 2381 N ARG A 380 2.151 32.158 41.376 1.00 14.97 N
+ATOM 2382 CA ARG A 380 2.301 31.210 42.474 1.00 15.36 C
+ATOM 2383 C ARG A 380 2.355 31.878 43.853 1.00 13.62 C
+ATOM 2384 O ARG A 380 2.548 31.209 44.862 1.00 14.41 O
+ATOM 2385 CB ARG A 380 3.555 30.348 42.245 1.00 19.87 C
+ATOM 2386 CG ARG A 380 3.486 29.450 40.980 1.00 21.47 C
+ATOM 2387 CD ARG A 380 2.501 28.291 41.167 1.00 20.19 C
+ATOM 2388 NE ARG A 380 3.010 27.405 42.205 1.00 23.74 N
+ATOM 2389 CZ ARG A 380 3.924 26.462 41.998 1.00 24.65 C
+ATOM 2390 NH1 ARG A 380 4.427 26.264 40.786 1.00 20.41 N
+ATOM 2391 NH2 ARG A 380 4.395 25.764 43.019 1.00 29.65 N
+ATOM 2392 N ASN A 381 2.156 33.191 43.899 1.00 12.05 N
+ATOM 2393 CA ASN A 381 2.196 33.939 45.165 1.00 17.55 C
+ATOM 2394 C ASN A 381 3.528 33.783 45.897 1.00 15.93 C
+ATOM 2395 O ASN A 381 3.555 33.434 47.080 1.00 16.13 O
+ATOM 2396 CB ASN A 381 1.056 33.509 46.112 1.00 14.64 C
+ATOM 2397 CG ASN A 381 0.953 34.386 47.384 1.00 19.79 C
+ATOM 2398 OD1 ASN A 381 0.258 34.022 48.339 1.00 19.13 O
+ATOM 2399 ND2 ASN A 381 1.624 35.538 47.388 1.00 15.35 N
+ATOM 2400 N TYR A 382 4.635 33.992 45.192 1.00 16.03 N
+ATOM 2401 CA TYR A 382 5.935 33.954 45.853 1.00 12.73 C
+ATOM 2402 C TYR A 382 6.541 35.328 45.595 1.00 11.71 C
+ATOM 2403 O TYR A 382 5.923 36.170 44.937 1.00 11.61 O
+ATOM 2404 CB TYR A 382 6.845 32.835 45.310 1.00 11.84 C
+ATOM 2405 CG TYR A 382 7.960 32.467 46.282 1.00 14.16 C
+ATOM 2406 CD1 TYR A 382 7.661 32.077 47.595 1.00 14.96 C
+ATOM 2407 CD2 TYR A 382 9.301 32.492 45.894 1.00 12.80 C
+ATOM 2408 CE1 TYR A 382 8.673 31.718 48.497 1.00 14.14 C
+ATOM 2409 CE2 TYR A 382 10.321 32.133 46.790 1.00 13.96 C
+ATOM 2410 CZ TYR A 382 9.996 31.745 48.086 1.00 14.40 C
+ATOM 2411 OH TYR A 382 10.988 31.367 48.968 1.00 16.69 O
+ATOM 2412 N ILE A 383 7.732 35.574 46.126 1.00 10.35 N
+ATOM 2413 CA ILE A 383 8.377 36.867 45.952 1.00 9.38 C
+ATOM 2414 C ILE A 383 9.864 36.604 45.791 1.00 10.29 C
+ATOM 2415 O ILE A 383 10.428 35.784 46.511 1.00 10.25 O
+ATOM 2416 CB ILE A 383 8.176 37.755 47.205 1.00 11.81 C
+ATOM 2417 CG1 ILE A 383 6.685 37.893 47.512 1.00 8.97 C
+ATOM 2418 CG2 ILE A 383 8.786 39.140 46.978 1.00 12.52 C
+ATOM 2419 CD1 ILE A 383 6.393 38.601 48.809 1.00 7.93 C
+ATOM 2420 N HIS A 384 10.504 37.288 44.854 1.00 10.25 N
+ATOM 2421 CA HIS A 384 11.937 37.082 44.667 1.00 13.95 C
+ATOM 2422 C HIS A 384 12.730 37.683 45.830 1.00 13.59 C
+ATOM 2423 O HIS A 384 13.514 36.990 46.472 1.00 16.31 O
+ATOM 2424 CB HIS A 384 12.417 37.691 43.354 1.00 12.11 C
+ATOM 2425 CG HIS A 384 13.816 37.294 43.010 1.00 9.86 C
+ATOM 2426 ND1 HIS A 384 14.895 37.640 43.792 1.00 13.78 N
+ATOM 2427 CD2 HIS A 384 14.294 36.460 42.058 1.00 10.47 C
+ATOM 2428 CE1 HIS A 384 15.978 37.031 43.343 1.00 12.35 C
+ATOM 2429 NE2 HIS A 384 15.640 36.308 42.290 1.00 14.64 N
+ATOM 2430 N ARG A 385 12.515 38.975 46.076 1.00 12.61 N
+ATOM 2431 CA ARG A 385 13.147 39.728 47.162 1.00 11.92 C
+ATOM 2432 C ARG A 385 14.540 40.277 46.874 1.00 14.06 C
+ATOM 2433 O ARG A 385 15.013 41.153 47.596 1.00 15.13 O
+ATOM 2434 CB ARG A 385 13.150 38.905 48.464 1.00 14.89 C
+ATOM 2435 CG ARG A 385 11.734 38.620 49.007 1.00 13.17 C
+ATOM 2436 CD ARG A 385 11.724 37.752 50.275 1.00 16.96 C
+ATOM 2437 NE ARG A 385 10.360 37.377 50.664 1.00 16.67 N
+ATOM 2438 CZ ARG A 385 9.683 37.899 51.684 1.00 17.13 C
+ATOM 2439 NH1 ARG A 385 10.231 38.838 52.447 1.00 17.17 N
+ATOM 2440 NH2 ARG A 385 8.458 37.465 51.956 1.00 16.35 N
+ATOM 2441 N ASP A 386 15.190 39.789 45.822 1.00 12.88 N
+ATOM 2442 CA ASP A 386 16.516 40.300 45.464 1.00 16.02 C
+ATOM 2443 C ASP A 386 16.716 40.186 43.959 1.00 16.99 C
+ATOM 2444 O ASP A 386 17.702 39.625 43.477 1.00 17.13 O
+ATOM 2445 CB ASP A 386 17.603 39.541 46.247 1.00 17.00 C
+ATOM 2446 CG ASP A 386 18.997 40.131 46.055 1.00 19.96 C
+ATOM 2447 OD1 ASP A 386 19.114 41.365 45.879 1.00 21.44 O
+ATOM 2448 OD2 ASP A 386 19.979 39.358 46.116 1.00 20.68 O
+ATOM 2449 N LEU A 387 15.760 40.735 43.215 1.00 16.57 N
+ATOM 2450 CA LEU A 387 15.816 40.685 41.766 1.00 15.50 C
+ATOM 2451 C LEU A 387 16.802 41.710 41.213 1.00 15.14 C
+ATOM 2452 O LEU A 387 16.697 42.893 41.495 1.00 17.19 O
+ATOM 2453 CB LEU A 387 14.418 40.926 41.183 1.00 16.94 C
+ATOM 2454 CG LEU A 387 14.247 40.766 39.669 1.00 18.98 C
+ATOM 2455 CD1 LEU A 387 14.575 39.332 39.267 1.00 14.63 C
+ATOM 2456 CD2 LEU A 387 12.794 41.112 39.282 1.00 16.73 C
+ATOM 2457 N ARG A 388 17.768 41.235 40.439 1.00 14.79 N
+ATOM 2458 CA ARG A 388 18.786 42.082 39.826 1.00 16.03 C
+ATOM 2459 C ARG A 388 19.565 41.216 38.833 1.00 17.06 C
+ATOM 2460 O ARG A 388 19.514 39.978 38.911 1.00 11.95 O
+ATOM 2461 CB ARG A 388 19.698 42.734 40.907 1.00 16.39 C
+ATOM 2462 CG ARG A 388 20.347 41.804 41.941 1.00 21.57 C
+ATOM 2463 CD ARG A 388 21.095 42.592 43.067 1.00 16.56 C
+ATOM 2464 NE ARG A 388 21.437 41.719 44.197 1.00 21.69 N
+ATOM 2465 CZ ARG A 388 22.551 40.995 44.303 1.00 22.73 C
+ATOM 2466 NH1 ARG A 388 23.471 41.030 43.349 1.00 24.89 N
+ATOM 2467 NH2 ARG A 388 22.714 40.177 45.336 1.00 19.39 N
+ATOM 2468 N ALA A 389 20.265 41.854 37.892 1.00 15.85 N
+ATOM 2469 CA ALA A 389 21.005 41.123 36.861 1.00 17.36 C
+ATOM 2470 C ALA A 389 21.995 40.095 37.402 1.00 17.79 C
+ATOM 2471 O ALA A 389 22.280 39.100 36.740 1.00 17.27 O
+ATOM 2472 CB ALA A 389 21.722 42.103 35.925 1.00 16.70 C
+ATOM 2473 N ALA A 390 22.527 40.332 38.595 1.00 19.64 N
+ATOM 2474 CA ALA A 390 23.469 39.386 39.183 1.00 18.97 C
+ATOM 2475 C ALA A 390 22.748 38.082 39.517 1.00 19.99 C
+ATOM 2476 O ALA A 390 23.371 37.019 39.574 1.00 16.95 O
+ATOM 2477 CB ALA A 390 24.090 39.972 40.446 1.00 20.67 C
+ATOM 2478 N ASN A 391 21.435 38.170 39.739 1.00 18.17 N
+ATOM 2479 CA ASN A 391 20.646 36.992 40.081 1.00 17.78 C
+ATOM 2480 C ASN A 391 19.850 36.382 38.940 1.00 17.24 C
+ATOM 2481 O ASN A 391 18.868 35.658 39.154 1.00 15.04 O
+ATOM 2482 CB ASN A 391 19.735 37.270 41.283 1.00 18.02 C
+ATOM 2483 CG ASN A 391 20.528 37.472 42.576 1.00 22.85 C
+ATOM 2484 OD1 ASN A 391 21.618 36.918 42.737 1.00 21.93 O
+ATOM 2485 ND2 ASN A 391 19.970 38.235 43.507 1.00 16.19 N
+ATOM 2486 N ILE A 392 20.274 36.691 37.722 1.00 16.53 N
+ATOM 2487 CA ILE A 392 19.666 36.103 36.542 1.00 14.82 C
+ATOM 2488 C ILE A 392 20.817 35.294 35.929 1.00 11.41 C
+ATOM 2489 O ILE A 392 21.919 35.814 35.803 1.00 11.96 O
+ATOM 2490 CB ILE A 392 19.205 37.159 35.515 1.00 13.06 C
+ATOM 2491 CG1 ILE A 392 18.214 38.143 36.151 1.00 11.78 C
+ATOM 2492 CG2 ILE A 392 18.532 36.447 34.342 1.00 13.93 C
+ATOM 2493 CD1 ILE A 392 16.946 37.477 36.686 1.00 12.95 C
+ATOM 2494 N LEU A 393 20.580 34.029 35.586 1.00 15.22 N
+ATOM 2495 CA LEU A 393 21.621 33.198 34.987 1.00 14.11 C
+ATOM 2496 C LEU A 393 21.311 33.010 33.509 1.00 18.43 C
+ATOM 2497 O LEU A 393 20.158 33.120 33.095 1.00 17.19 O
+ATOM 2498 CB LEU A 393 21.686 31.835 35.676 1.00 14.71 C
+ATOM 2499 CG LEU A 393 21.955 31.885 37.186 1.00 18.10 C
+ATOM 2500 CD1 LEU A 393 21.960 30.471 37.742 1.00 17.40 C
+ATOM 2501 CD2 LEU A 393 23.286 32.565 37.463 1.00 19.55 C
+ATOM 2502 N VAL A 394 22.339 32.704 32.724 1.00 18.42 N
+ATOM 2503 CA VAL A 394 22.182 32.525 31.281 1.00 17.15 C
+ATOM 2504 C VAL A 394 22.680 31.162 30.841 1.00 17.05 C
+ATOM 2505 O VAL A 394 23.835 30.834 31.078 1.00 19.72 O
+ATOM 2506 CB VAL A 394 22.988 33.599 30.512 1.00 17.67 C
+ATOM 2507 CG1 VAL A 394 22.710 33.501 29.023 1.00 17.23 C
+ATOM 2508 CG2 VAL A 394 22.654 34.978 31.048 1.00 17.35 C
+ATOM 2509 N SER A 395 21.821 30.376 30.194 1.00 17.31 N
+ATOM 2510 CA SER A 395 22.209 29.043 29.726 1.00 22.88 C
+ATOM 2511 C SER A 395 23.064 29.145 28.464 1.00 21.22 C
+ATOM 2512 O SER A 395 23.265 30.231 27.922 1.00 22.27 O
+ATOM 2513 CB SER A 395 20.976 28.193 29.410 1.00 19.14 C
+ATOM 2514 OG SER A 395 20.342 28.655 28.230 1.00 25.24 O
+ATOM 2515 N ALA A 396 23.560 28.006 27.995 1.00 22.22 N
+ATOM 2516 CA ALA A 396 24.388 27.983 26.795 1.00 24.53 C
+ATOM 2517 C ALA A 396 23.619 28.487 25.572 1.00 24.77 C
+ATOM 2518 O ALA A 396 24.213 29.040 24.652 1.00 24.40 O
+ATOM 2519 CB ALA A 396 24.912 26.573 26.545 1.00 24.39 C
+ATOM 2520 N SER A 397 22.300 28.310 25.569 1.00 23.70 N
+ATOM 2521 CA SER A 397 21.470 28.758 24.447 1.00 23.28 C
+ATOM 2522 C SER A 397 20.924 30.177 24.646 1.00 23.69 C
+ATOM 2523 O SER A 397 20.033 30.623 23.916 1.00 24.71 O
+ATOM 2524 CB SER A 397 20.311 27.782 24.238 1.00 26.09 C
+ATOM 2525 OG SER A 397 19.534 27.644 25.419 1.00 31.46 O
+ATOM 2526 N LEU A 398 21.463 30.874 25.642 1.00 21.31 N
+ATOM 2527 CA LEU A 398 21.066 32.242 25.966 1.00 24.23 C
+ATOM 2528 C LEU A 398 19.680 32.391 26.594 1.00 22.19 C
+ATOM 2529 O LEU A 398 19.042 33.428 26.449 1.00 25.17 O
+ATOM 2530 CB LEU A 398 21.161 33.142 24.723 1.00 25.89 C
+ATOM 2531 CG LEU A 398 22.546 33.242 24.074 1.00 29.74 C
+ATOM 2532 CD1 LEU A 398 22.503 34.240 22.920 1.00 31.29 C
+ATOM 2533 CD2 LEU A 398 23.569 33.682 25.110 1.00 29.28 C
+ATOM 2534 N VAL A 399 19.207 31.361 27.285 1.00 22.88 N
+ATOM 2535 CA VAL A 399 17.910 31.449 27.949 1.00 20.20 C
+ATOM 2536 C VAL A 399 18.130 31.955 29.377 1.00 22.58 C
+ATOM 2537 O VAL A 399 19.037 31.500 30.081 1.00 21.05 O
+ATOM 2538 CB VAL A 399 17.196 30.081 27.986 1.00 21.62 C
+ATOM 2539 CG1 VAL A 399 15.912 30.172 28.820 1.00 16.21 C
+ATOM 2540 CG2 VAL A 399 16.855 29.645 26.562 1.00 21.47 C
+ATOM 2541 N CYS A 400 17.311 32.912 29.794 1.00 18.51 N
+ATOM 2542 CA CYS A 400 17.427 33.478 31.133 1.00 19.40 C
+ATOM 2543 C CYS A 400 16.721 32.649 32.181 1.00 18.25 C
+ATOM 2544 O CYS A 400 15.593 32.204 31.983 1.00 18.34 O
+ATOM 2545 CB CYS A 400 16.872 34.898 31.161 1.00 18.41 C
+ATOM 2546 SG CYS A 400 17.856 36.038 30.208 1.00 25.24 S
+ATOM 2547 N LYS A 401 17.409 32.432 33.293 1.00 15.06 N
+ATOM 2548 CA LYS A 401 16.855 31.668 34.393 1.00 18.46 C
+ATOM 2549 C LYS A 401 17.016 32.474 35.674 1.00 18.07 C
+ATOM 2550 O LYS A 401 18.134 32.770 36.104 1.00 17.56 O
+ATOM 2551 CB LYS A 401 17.564 30.315 34.559 1.00 22.38 C
+ATOM 2552 CG LYS A 401 17.005 29.113 33.772 1.00 24.36 C
+ATOM 2553 CD LYS A 401 17.198 29.218 32.280 1.00 28.23 C
+ATOM 2554 CE LYS A 401 17.124 27.840 31.620 1.00 22.22 C
+ATOM 2555 NZ LYS A 401 15.868 27.095 31.872 1.00 18.93 N
+ATOM 2556 N ILE A 402 15.889 32.823 36.277 1.00 15.12 N
+ATOM 2557 CA ILE A 402 15.887 33.581 37.516 1.00 14.49 C
+ATOM 2558 C ILE A 402 16.415 32.690 38.643 1.00 13.53 C
+ATOM 2559 O ILE A 402 15.962 31.546 38.814 1.00 13.24 O
+ATOM 2560 CB ILE A 402 14.464 34.053 37.831 1.00 15.75 C
+ATOM 2561 CG1 ILE A 402 13.947 34.915 36.671 1.00 13.84 C
+ATOM 2562 CG2 ILE A 402 14.448 34.838 39.120 1.00 12.38 C
+ATOM 2563 CD1 ILE A 402 12.512 35.353 36.835 1.00 11.62 C
+ATOM 2564 N ALA A 403 17.378 33.217 39.399 1.00 13.65 N
+ATOM 2565 CA ALA A 403 17.994 32.499 40.510 1.00 12.46 C
+ATOM 2566 C ALA A 403 17.867 33.235 41.841 1.00 15.27 C
+ATOM 2567 O ALA A 403 17.598 34.439 41.873 1.00 16.11 O
+ATOM 2568 CB ALA A 403 19.469 32.258 40.209 1.00 15.73 C
+ATOM 2569 N ASP A 404 18.074 32.503 42.938 1.00 14.25 N
+ATOM 2570 CA ASP A 404 18.020 33.085 44.283 1.00 16.29 C
+ATOM 2571 C ASP A 404 16.646 33.588 44.719 1.00 14.02 C
+ATOM 2572 O ASP A 404 16.548 34.324 45.692 1.00 13.60 O
+ATOM 2573 CB ASP A 404 19.030 34.243 44.388 1.00 14.64 C
+ATOM 2574 CG ASP A 404 20.308 33.855 45.124 1.00 23.19 C
+ATOM 2575 OD1 ASP A 404 20.786 32.717 44.952 1.00 22.90 O
+ATOM 2576 OD2 ASP A 404 20.848 34.708 45.863 1.00 26.78 O
+ATOM 2577 N PHE A 405 15.584 33.211 44.016 1.00 14.00 N
+ATOM 2578 CA PHE A 405 14.262 33.684 44.418 1.00 13.02 C
+ATOM 2579 C PHE A 405 13.900 33.283 45.841 1.00 11.92 C
+ATOM 2580 O PHE A 405 13.974 32.108 46.199 1.00 13.04 O
+ATOM 2581 CB PHE A 405 13.164 33.190 43.453 1.00 12.37 C
+ATOM 2582 CG PHE A 405 13.324 31.759 43.000 1.00 12.03 C
+ATOM 2583 CD1 PHE A 405 14.113 31.448 41.892 1.00 12.98 C
+ATOM 2584 CD2 PHE A 405 12.671 30.728 43.662 1.00 12.16 C
+ATOM 2585 CE1 PHE A 405 14.241 30.118 41.447 1.00 14.91 C
+ATOM 2586 CE2 PHE A 405 12.792 29.410 43.233 1.00 14.16 C
+ATOM 2587 CZ PHE A 405 13.579 29.103 42.119 1.00 16.71 C
+ATOM 2588 N GLY A 406 13.532 34.285 46.640 1.00 13.40 N
+ATOM 2589 CA GLY A 406 13.126 34.085 48.023 1.00 14.03 C
+ATOM 2590 C GLY A 406 14.210 33.874 49.071 1.00 16.48 C
+ATOM 2591 O GLY A 406 13.942 33.931 50.275 1.00 11.17 O
+ATOM 2592 N LEU A 407 15.438 33.646 48.629 1.00 16.79 N
+ATOM 2593 CA LEU A 407 16.528 33.381 49.561 1.00 17.97 C
+ATOM 2594 C LEU A 407 16.790 34.483 50.590 1.00 17.49 C
+ATOM 2595 O LEU A 407 17.138 34.194 51.737 1.00 18.06 O
+ATOM 2596 CB LEU A 407 17.815 33.095 48.785 1.00 16.97 C
+ATOM 2597 CG LEU A 407 19.000 32.625 49.629 1.00 20.18 C
+ATOM 2598 CD1 LEU A 407 18.649 31.282 50.261 1.00 21.40 C
+ATOM 2599 CD2 LEU A 407 20.239 32.484 48.751 1.00 23.76 C
+ATOM 2600 N ALA A 408 16.623 35.738 50.181 1.00 16.43 N
+ATOM 2601 CA ALA A 408 16.871 36.873 51.067 1.00 16.32 C
+ATOM 2602 C ALA A 408 16.074 36.838 52.354 1.00 19.31 C
+ATOM 2603 O ALA A 408 16.537 37.341 53.378 1.00 17.67 O
+ATOM 2604 CB ALA A 408 16.601 38.191 50.338 1.00 17.61 C
+ATOM 2605 N ARG A 409 14.883 36.249 52.322 1.00 18.55 N
+ATOM 2606 CA ARG A 409 14.067 36.216 53.529 1.00 19.25 C
+ATOM 2607 C ARG A 409 14.688 35.434 54.694 1.00 20.62 C
+ATOM 2608 O ARG A 409 14.365 35.691 55.855 1.00 19.33 O
+ATOM 2609 CB ARG A 409 12.676 35.656 53.237 1.00 19.41 C
+ATOM 2610 CG ARG A 409 11.703 35.963 54.365 1.00 24.00 C
+ATOM 2611 CD ARG A 409 10.318 35.402 54.128 1.00 24.74 C
+ATOM 2612 NE ARG A 409 9.401 35.876 55.160 1.00 29.03 N
+ATOM 2613 CZ ARG A 409 8.144 35.472 55.298 1.00 31.16 C
+ATOM 2614 NH1 ARG A 409 7.633 34.578 54.466 1.00 27.98 N
+ATOM 2615 NH2 ARG A 409 7.391 35.981 56.264 1.00 34.05 N
+ATOM 2616 N VAL A 410 15.571 34.483 54.408 1.00 18.62 N
+ATOM 2617 CA VAL A 410 16.169 33.733 55.506 1.00 18.07 C
+ATOM 2618 C VAL A 410 17.604 34.122 55.903 1.00 20.76 C
+ATOM 2619 O VAL A 410 18.258 33.402 56.653 1.00 22.74 O
+ATOM 2620 CB VAL A 410 16.068 32.204 55.256 1.00 15.16 C
+ATOM 2621 CG1 VAL A 410 14.599 31.774 55.312 1.00 19.11 C
+ATOM 2622 CG2 VAL A 410 16.656 31.845 53.897 1.00 20.45 C
+ATOM 2623 N ILE A 411 18.091 35.262 55.411 1.00 22.92 N
+ATOM 2624 CA ILE A 411 19.427 35.744 55.778 1.00 23.87 C
+ATOM 2625 C ILE A 411 19.320 36.282 57.208 1.00 25.13 C
+ATOM 2626 O ILE A 411 18.374 36.993 57.527 1.00 24.11 O
+ATOM 2627 CB ILE A 411 19.887 36.900 54.865 1.00 25.85 C
+ATOM 2628 CG1 ILE A 411 20.095 36.400 53.432 1.00 23.36 C
+ATOM 2629 CG2 ILE A 411 21.170 37.521 55.420 1.00 27.35 C
+ATOM 2630 CD1 ILE A 411 21.220 35.389 53.281 1.00 25.33 C
+ATOM 2631 N GLU A 412 20.280 35.963 58.070 1.00 29.37 N
+ATOM 2632 CA GLU A 412 20.216 36.427 59.461 1.00 35.38 C
+ATOM 2633 C GLU A 412 20.735 37.839 59.738 1.00 37.86 C
+ATOM 2634 O GLU A 412 20.116 38.601 60.481 1.00 42.03 O
+ATOM 2635 CB GLU A 412 20.940 35.434 60.371 1.00 38.97 C
+ATOM 2636 CG GLU A 412 20.176 34.145 60.600 1.00 41.87 C
+ATOM 2637 CD GLU A 412 18.910 34.372 61.408 1.00 46.16 C
+ATOM 2638 OE1 GLU A 412 19.025 34.838 62.559 1.00 48.75 O
+ATOM 2639 OE2 GLU A 412 17.806 34.092 60.896 1.00 48.05 O
+ATOM 2640 N ASP A 413 21.876 38.169 59.143 1.00 40.07 N
+ATOM 2641 CA ASP A 413 22.529 39.468 59.296 1.00 41.13 C
+ATOM 2642 C ASP A 413 21.628 40.616 59.784 1.00 42.17 C
+ATOM 2643 O ASP A 413 20.727 41.069 59.072 1.00 39.42 O
+ATOM 2644 CB ASP A 413 23.191 39.837 57.967 1.00 40.97 C
+ATOM 2645 CG ASP A 413 23.976 41.125 58.042 1.00 43.94 C
+ATOM 2646 OD1 ASP A 413 23.363 42.187 58.280 1.00 39.53 O
+ATOM 2647 OD2 ASP A 413 25.213 41.069 57.861 1.00 46.75 O
+ATOM 2648 N ASN A 414 21.892 41.085 61.003 1.00 42.32 N
+ATOM 2649 CA ASN A 414 21.122 42.170 61.613 1.00 44.01 C
+ATOM 2650 C ASN A 414 20.919 43.391 60.712 1.00 40.94 C
+ATOM 2651 O ASN A 414 19.818 43.930 60.638 1.00 40.95 O
+ATOM 2652 CB ASN A 414 21.773 42.601 62.938 1.00 46.42 C
+ATOM 2653 CG ASN A 414 21.588 41.572 64.052 1.00 51.39 C
+ATOM 2654 OD1 ASN A 414 22.131 41.722 65.150 1.00 54.20 O
+ATOM 2655 ND2 ASN A 414 20.807 40.531 63.778 1.00 50.96 N
+ATOM 2656 N GLU A 415 21.971 43.832 60.030 1.00 38.83 N
+ATOM 2657 CA GLU A 415 21.855 44.987 59.144 1.00 36.62 C
+ATOM 2658 C GLU A 415 20.979 44.659 57.937 1.00 36.39 C
+ATOM 2659 O GLU A 415 20.108 45.445 57.555 1.00 35.34 O
+ATOM 2660 CB GLU A 415 23.236 45.431 58.657 1.00 39.78 C
+ATOM 2661 CG GLU A 415 24.186 45.865 59.762 1.00 42.87 C
+ATOM 2662 CD GLU A 415 25.550 46.266 59.228 1.00 45.27 C
+ATOM 2663 OE1 GLU A 415 25.633 47.251 58.459 1.00 41.52 O
+ATOM 2664 OE2 GLU A 415 26.539 45.586 59.576 1.00 48.31 O
+ATOM 2665 N TYR A 416 21.216 43.494 57.339 1.00 33.98 N
+ATOM 2666 CA TYR A 416 20.458 43.066 56.166 1.00 32.45 C
+ATOM 2667 C TYR A 416 18.968 42.990 56.509 1.00 33.22 C
+ATOM 2668 O TYR A 416 18.114 43.421 55.725 1.00 31.71 O
+ATOM 2669 CB TYR A 416 20.937 41.692 55.692 1.00 30.75 C
+ATOM 2670 CG TYR A 416 20.505 41.348 54.282 1.00 31.10 C
+ATOM 2671 CD1 TYR A 416 21.251 41.777 53.182 1.00 29.62 C
+ATOM 2672 CD2 TYR A 416 19.332 40.635 54.044 1.00 29.81 C
+ATOM 2673 CE1 TYR A 416 20.842 41.505 51.878 1.00 27.62 C
+ATOM 2674 CE2 TYR A 416 18.909 40.358 52.739 1.00 29.02 C
+ATOM 2675 CZ TYR A 416 19.668 40.798 51.663 1.00 28.42 C
+ATOM 2676 OH TYR A 416 19.255 40.542 50.372 1.00 28.54 O
+ATOM 2677 N THR A 417 18.655 42.443 57.681 1.00 32.73 N
+ATOM 2678 CA THR A 417 17.264 42.327 58.105 1.00 39.13 C
+ATOM 2679 C THR A 417 16.600 43.698 58.206 1.00 38.25 C
+ATOM 2680 O THR A 417 15.395 43.828 57.993 1.00 39.75 O
+ATOM 2681 CB THR A 417 17.144 41.613 59.465 1.00 38.98 C
+ATOM 2682 OG1 THR A 417 17.660 40.282 59.347 1.00 44.66 O
+ATOM 2683 CG2 THR A 417 15.681 41.542 59.905 1.00 42.32 C
+ATOM 2684 N ALA A 418 17.388 44.720 58.523 1.00 37.24 N
+ATOM 2685 CA ALA A 418 16.857 46.075 58.636 1.00 38.66 C
+ATOM 2686 C ALA A 418 17.033 46.856 57.335 1.00 37.08 C
+ATOM 2687 O ALA A 418 16.915 48.080 57.321 1.00 38.42 O
+ATOM 2688 CB ALA A 418 17.544 46.815 59.787 1.00 39.58 C
+ATOM 2689 N ARG A 419 17.311 46.147 56.245 1.00 36.49 N
+ATOM 2690 CA ARG A 419 17.511 46.781 54.943 1.00 36.36 C
+ATOM 2691 C ARG A 419 18.547 47.902 55.036 1.00 37.07 C
+ATOM 2692 O ARG A 419 18.342 48.990 54.500 1.00 34.75 O
+ATOM 2693 CB ARG A 419 16.190 47.361 54.400 1.00 36.99 C
+ATOM 2694 CG ARG A 419 15.055 46.349 54.204 1.00 33.96 C
+ATOM 2695 CD ARG A 419 14.420 45.941 55.523 1.00 34.55 C
+ATOM 2696 NE ARG A 419 13.684 47.051 56.126 1.00 39.41 N
+ATOM 2697 CZ ARG A 419 13.097 47.003 57.319 1.00 41.97 C
+ATOM 2698 NH1 ARG A 419 13.156 45.898 58.051 1.00 44.12 N
+ATOM 2699 NH2 ARG A 419 12.434 48.056 57.773 1.00 44.07 N
+ATOM 2700 N GLU A 420 19.655 47.633 55.723 1.00 39.82 N
+ATOM 2701 CA GLU A 420 20.725 48.622 55.889 1.00 41.39 C
+ATOM 2702 C GLU A 420 22.084 47.958 55.678 1.00 41.06 C
+ATOM 2703 O GLU A 420 22.204 46.739 55.768 1.00 39.91 O
+ATOM 2704 CB GLU A 420 20.674 49.231 57.299 1.00 42.09 C
+ATOM 2705 CG GLU A 420 19.337 49.867 57.656 1.00 47.68 C
+ATOM 2706 CD GLU A 420 19.304 50.446 59.061 1.00 49.43 C
+ATOM 2707 OE1 GLU A 420 19.568 49.696 60.025 1.00 51.92 O
+ATOM 2708 OE2 GLU A 420 19.002 51.652 59.202 1.00 50.28 O
+ATOM 2709 N GLY A 421 23.106 48.758 55.393 1.00 40.97 N
+ATOM 2710 CA GLY A 421 24.431 48.193 55.201 1.00 42.21 C
+ATOM 2711 C GLY A 421 24.897 48.049 53.766 1.00 41.74 C
+ATOM 2712 O GLY A 421 24.118 48.196 52.824 1.00 43.72 O
+ATOM 2713 N ALA A 422 26.181 47.744 53.606 1.00 42.01 N
+ATOM 2714 CA ALA A 422 26.790 47.585 52.291 1.00 41.99 C
+ATOM 2715 C ALA A 422 26.477 46.231 51.666 1.00 41.83 C
+ATOM 2716 O ALA A 422 26.884 45.950 50.538 1.00 43.67 O
+ATOM 2717 CB ALA A 422 28.305 47.771 52.396 1.00 43.63 C
+ATOM 2718 N LYS A 423 25.765 45.386 52.400 1.00 40.18 N
+ATOM 2719 CA LYS A 423 25.416 44.078 51.874 1.00 39.16 C
+ATOM 2720 C LYS A 423 24.013 44.082 51.268 1.00 36.80 C
+ATOM 2721 O LYS A 423 23.714 43.273 50.388 1.00 37.20 O
+ATOM 2722 CB LYS A 423 25.510 43.014 52.975 1.00 39.68 C
+ATOM 2723 CG LYS A 423 26.896 42.886 53.594 1.00 44.53 C
+ATOM 2724 CD LYS A 423 26.967 41.745 54.603 1.00 45.84 C
+ATOM 2725 CE LYS A 423 28.372 41.608 55.186 1.00 46.02 C
+ATOM 2726 NZ LYS A 423 28.479 40.474 56.151 1.00 47.25 N
+ATOM 2727 N PHE A 424 23.167 45.005 51.724 1.00 33.14 N
+ATOM 2728 CA PHE A 424 21.787 45.092 51.241 1.00 29.28 C
+ATOM 2729 C PHE A 424 21.659 45.822 49.903 1.00 30.33 C
+ATOM 2730 O PHE A 424 22.255 46.885 49.709 1.00 28.30 O
+ATOM 2731 CB PHE A 424 20.905 45.800 52.269 1.00 31.31 C
+ATOM 2732 CG PHE A 424 19.440 45.627 52.013 1.00 32.64 C
+ATOM 2733 CD1 PHE A 424 18.807 44.426 52.325 1.00 31.02 C
+ATOM 2734 CD2 PHE A 424 18.704 46.633 51.395 1.00 33.26 C
+ATOM 2735 CE1 PHE A 424 17.459 44.229 52.025 1.00 31.52 C
+ATOM 2736 CE2 PHE A 424 17.357 46.446 51.088 1.00 35.85 C
+ATOM 2737 CZ PHE A 424 16.734 45.237 51.404 1.00 33.91 C
+ATOM 2738 N PRO A 425 20.864 45.260 48.968 1.00 26.93 N
+ATOM 2739 CA PRO A 425 20.600 45.780 47.621 1.00 25.89 C
+ATOM 2740 C PRO A 425 19.698 47.015 47.563 1.00 26.00 C
+ATOM 2741 O PRO A 425 18.710 47.022 46.822 1.00 22.59 O
+ATOM 2742 CB PRO A 425 19.957 44.580 46.928 1.00 25.41 C
+ATOM 2743 CG PRO A 425 19.107 44.030 48.048 1.00 27.80 C
+ATOM 2744 CD PRO A 425 20.167 43.969 49.142 1.00 25.81 C
+ATOM 2745 N ILE A 426 20.050 48.053 48.321 1.00 23.69 N
+ATOM 2746 CA ILE A 426 19.275 49.297 48.369 1.00 22.91 C
+ATOM 2747 C ILE A 426 18.852 49.865 47.020 1.00 22.18 C
+ATOM 2748 O ILE A 426 17.694 50.227 46.822 1.00 22.87 O
+ATOM 2749 CB ILE A 426 20.054 50.424 49.112 1.00 25.41 C
+ATOM 2750 CG1 ILE A 426 20.181 50.082 50.596 1.00 23.08 C
+ATOM 2751 CG2 ILE A 426 19.344 51.770 48.931 1.00 23.30 C
+ATOM 2752 CD1 ILE A 426 18.851 50.009 51.328 1.00 26.69 C
+ATOM 2753 N LYS A 427 19.790 49.952 46.089 1.00 24.50 N
+ATOM 2754 CA LYS A 427 19.479 50.527 44.792 1.00 24.12 C
+ATOM 2755 C LYS A 427 18.393 49.821 43.972 1.00 24.03 C
+ATOM 2756 O LYS A 427 17.799 50.434 43.089 1.00 23.50 O
+ATOM 2757 CB LYS A 427 20.770 50.666 43.979 1.00 25.80 C
+ATOM 2758 CG LYS A 427 21.758 51.668 44.597 1.00 26.83 C
+ATOM 2759 CD LYS A 427 22.967 51.877 43.700 1.00 26.42 C
+ATOM 2760 CE LYS A 427 23.920 52.923 44.263 1.00 26.91 C
+ATOM 2761 NZ LYS A 427 25.044 53.183 43.311 1.00 28.92 N
+ATOM 2762 N TRP A 428 18.125 48.552 44.277 1.00 25.59 N
+ATOM 2763 CA TRP A 428 17.112 47.751 43.565 1.00 21.07 C
+ATOM 2764 C TRP A 428 15.832 47.570 44.374 1.00 21.51 C
+ATOM 2765 O TRP A 428 14.843 47.040 43.870 1.00 21.86 O
+ATOM 2766 CB TRP A 428 17.658 46.343 43.278 1.00 20.63 C
+ATOM 2767 CG TRP A 428 18.713 46.245 42.225 1.00 21.62 C
+ATOM 2768 CD1 TRP A 428 18.524 45.976 40.897 1.00 22.18 C
+ATOM 2769 CD2 TRP A 428 20.124 46.415 42.403 1.00 22.24 C
+ATOM 2770 NE1 TRP A 428 19.729 45.965 40.239 1.00 22.45 N
+ATOM 2771 CE2 TRP A 428 20.729 46.232 41.139 1.00 23.52 C
+ATOM 2772 CE3 TRP A 428 20.937 46.703 43.507 1.00 21.30 C
+ATOM 2773 CZ2 TRP A 428 22.115 46.327 40.948 1.00 21.03 C
+ATOM 2774 CZ3 TRP A 428 22.318 46.800 43.316 1.00 23.77 C
+ATOM 2775 CH2 TRP A 428 22.889 46.610 42.045 1.00 21.34 C
+ATOM 2776 N THR A 429 15.847 48.016 45.622 1.00 20.31 N
+ATOM 2777 CA THR A 429 14.710 47.802 46.503 1.00 19.80 C
+ATOM 2778 C THR A 429 13.666 48.900 46.596 1.00 21.31 C
+ATOM 2779 O THR A 429 13.993 50.076 46.702 1.00 22.72 O
+ATOM 2780 CB THR A 429 15.224 47.474 47.903 1.00 20.16 C
+ATOM 2781 OG1 THR A 429 16.147 46.381 47.808 1.00 17.74 O
+ATOM 2782 CG2 THR A 429 14.084 47.092 48.818 1.00 20.59 C
+ATOM 2783 N ALA A 430 12.400 48.489 46.558 1.00 19.67 N
+ATOM 2784 CA ALA A 430 11.270 49.414 46.641 1.00 22.31 C
+ATOM 2785 C ALA A 430 11.273 50.161 47.970 1.00 22.20 C
+ATOM 2786 O ALA A 430 11.544 49.577 49.022 1.00 21.16 O
+ATOM 2787 CB ALA A 430 9.960 48.651 46.489 1.00 17.38 C
+ATOM 2788 N PRO A 431 10.937 51.458 47.943 1.00 22.73 N
+ATOM 2789 CA PRO A 431 10.904 52.283 49.150 1.00 22.67 C
+ATOM 2790 C PRO A 431 10.149 51.677 50.332 1.00 25.28 C
+ATOM 2791 O PRO A 431 10.616 51.763 51.469 1.00 27.15 O
+ATOM 2792 CB PRO A 431 10.275 53.581 48.647 1.00 24.02 C
+ATOM 2793 CG PRO A 431 10.847 53.676 47.259 1.00 25.48 C
+ATOM 2794 CD PRO A 431 10.538 52.265 46.776 1.00 26.05 C
+ATOM 2795 N GLU A 432 8.992 51.063 50.083 1.00 21.52 N
+ATOM 2796 CA GLU A 432 8.243 50.487 51.192 1.00 22.84 C
+ATOM 2797 C GLU A 432 8.910 49.223 51.747 1.00 20.87 C
+ATOM 2798 O GLU A 432 8.698 48.862 52.903 1.00 21.85 O
+ATOM 2799 CB GLU A 432 6.786 50.174 50.797 1.00 23.61 C
+ATOM 2800 CG GLU A 432 6.605 48.974 49.856 1.00 21.11 C
+ATOM 2801 CD GLU A 432 6.879 49.293 48.392 1.00 17.79 C
+ATOM 2802 OE1 GLU A 432 7.406 50.384 48.089 1.00 16.50 O
+ATOM 2803 OE2 GLU A 432 6.570 48.433 47.542 1.00 18.83 O
+ATOM 2804 N ALA A 433 9.716 48.551 50.932 1.00 20.31 N
+ATOM 2805 CA ALA A 433 10.392 47.344 51.394 1.00 20.87 C
+ATOM 2806 C ALA A 433 11.569 47.755 52.264 1.00 22.06 C
+ATOM 2807 O ALA A 433 11.854 47.124 53.279 1.00 25.32 O
+ATOM 2808 CB ALA A 433 10.874 46.510 50.211 1.00 23.69 C
+ATOM 2809 N ILE A 434 12.253 48.818 51.860 1.00 24.22 N
+ATOM 2810 CA ILE A 434 13.386 49.321 52.627 1.00 29.10 C
+ATOM 2811 C ILE A 434 12.906 49.917 53.949 1.00 29.08 C
+ATOM 2812 O ILE A 434 13.468 49.633 55.005 1.00 32.09 O
+ATOM 2813 CB ILE A 434 14.144 50.434 51.871 1.00 28.04 C
+ATOM 2814 CG1 ILE A 434 14.793 49.874 50.609 1.00 29.51 C
+ATOM 2815 CG2 ILE A 434 15.214 51.043 52.774 1.00 30.64 C
+ATOM 2816 CD1 ILE A 434 15.513 50.931 49.786 1.00 29.19 C
+ATOM 2817 N ASN A 435 11.859 50.736 53.885 1.00 30.35 N
+ATOM 2818 CA ASN A 435 11.339 51.403 55.079 1.00 30.46 C
+ATOM 2819 C ASN A 435 10.555 50.563 56.072 1.00 31.08 C
+ATOM 2820 O ASN A 435 10.710 50.741 57.280 1.00 28.38 O
+ATOM 2821 CB ASN A 435 10.493 52.621 54.689 1.00 28.53 C
+ATOM 2822 CG ASN A 435 11.271 53.621 53.871 1.00 28.90 C
+ATOM 2823 OD1 ASN A 435 12.474 53.794 54.076 1.00 29.25 O
+ATOM 2824 ND2 ASN A 435 10.589 54.308 52.954 1.00 24.14 N
+ATOM 2825 N PHE A 436 9.712 49.655 55.594 1.00 28.38 N
+ATOM 2826 CA PHE A 436 8.938 48.853 56.531 1.00 31.21 C
+ATOM 2827 C PHE A 436 9.099 47.358 56.341 1.00 31.26 C
+ATOM 2828 O PHE A 436 8.407 46.571 56.993 1.00 30.57 O
+ATOM 2829 CB PHE A 436 7.450 49.209 56.440 1.00 33.86 C
+ATOM 2830 CG PHE A 436 7.181 50.682 56.464 1.00 38.94 C
+ATOM 2831 CD1 PHE A 436 7.147 51.413 55.284 1.00 40.78 C
+ATOM 2832 CD2 PHE A 436 7.016 51.353 57.671 1.00 40.53 C
+ATOM 2833 CE1 PHE A 436 6.951 52.796 55.303 1.00 42.75 C
+ATOM 2834 CE2 PHE A 436 6.822 52.735 57.699 1.00 39.71 C
+ATOM 2835 CZ PHE A 436 6.790 53.455 56.512 1.00 39.15 C
+ATOM 2836 N GLY A 437 10.013 46.963 55.463 1.00 27.70 N
+ATOM 2837 CA GLY A 437 10.197 45.547 55.214 1.00 26.94 C
+ATOM 2838 C GLY A 437 8.934 44.970 54.591 1.00 25.34 C
+ATOM 2839 O GLY A 437 8.592 43.806 54.815 1.00 23.40 O
+ATOM 2840 N SER A 438 8.235 45.795 53.812 1.00 23.83 N
+ATOM 2841 CA SER A 438 7.000 45.382 53.151 1.00 24.94 C
+ATOM 2842 C SER A 438 7.290 44.744 51.795 1.00 24.04 C
+ATOM 2843 O SER A 438 7.081 45.366 50.749 1.00 23.49 O
+ATOM 2844 CB SER A 438 6.084 46.589 52.944 1.00 24.53 C
+ATOM 2845 OG SER A 438 5.802 47.222 54.175 1.00 31.48 O
+ATOM 2846 N PHE A 439 7.786 43.512 51.814 1.00 22.25 N
+ATOM 2847 CA PHE A 439 8.086 42.813 50.573 1.00 21.56 C
+ATOM 2848 C PHE A 439 6.832 42.166 49.998 1.00 18.23 C
+ATOM 2849 O PHE A 439 6.093 41.475 50.704 1.00 16.28 O
+ATOM 2850 CB PHE A 439 9.163 41.735 50.787 1.00 22.76 C
+ATOM 2851 CG PHE A 439 10.516 42.284 51.177 1.00 22.60 C
+ATOM 2852 CD1 PHE A 439 10.862 42.454 52.514 1.00 21.51 C
+ATOM 2853 CD2 PHE A 439 11.435 42.653 50.200 1.00 23.24 C
+ATOM 2854 CE1 PHE A 439 12.101 42.982 52.871 1.00 19.05 C
+ATOM 2855 CE2 PHE A 439 12.677 43.185 50.549 1.00 23.01 C
+ATOM 2856 CZ PHE A 439 13.009 43.349 51.886 1.00 19.04 C
+ATOM 2857 N THR A 440 6.579 42.419 48.717 1.00 18.69 N
+ATOM 2858 CA THR A 440 5.431 41.835 48.026 1.00 15.30 C
+ATOM 2859 C THR A 440 5.829 41.706 46.566 1.00 16.33 C
+ATOM 2860 O THR A 440 6.915 42.127 46.171 1.00 16.60 O
+ATOM 2861 CB THR A 440 4.174 42.738 48.066 1.00 18.01 C
+ATOM 2862 OG1 THR A 440 4.415 43.909 47.281 1.00 17.95 O
+ATOM 2863 CG2 THR A 440 3.825 43.149 49.504 1.00 18.60 C
+ATOM 2864 N ILE A 441 4.952 41.134 45.754 1.00 14.76 N
+ATOM 2865 CA ILE A 441 5.274 41.011 44.347 1.00 14.26 C
+ATOM 2866 C ILE A 441 5.433 42.421 43.750 1.00 14.48 C
+ATOM 2867 O ILE A 441 6.120 42.599 42.746 1.00 14.64 O
+ATOM 2868 CB ILE A 441 4.189 40.178 43.590 1.00 13.07 C
+ATOM 2869 CG1 ILE A 441 4.662 39.884 42.165 1.00 12.44 C
+ATOM 2870 CG2 ILE A 441 2.851 40.892 43.600 1.00 14.53 C
+ATOM 2871 CD1 ILE A 441 5.856 38.929 42.116 1.00 15.06 C
+ATOM 2872 N LYS A 442 4.827 43.431 44.380 1.00 12.33 N
+ATOM 2873 CA LYS A 442 4.961 44.797 43.879 1.00 14.56 C
+ATOM 2874 C LYS A 442 6.343 45.398 44.144 1.00 15.80 C
+ATOM 2875 O LYS A 442 6.793 46.248 43.379 1.00 12.31 O
+ATOM 2876 CB LYS A 442 3.878 45.713 44.460 1.00 14.99 C
+ATOM 2877 CG LYS A 442 2.465 45.391 43.965 1.00 17.40 C
+ATOM 2878 CD LYS A 442 2.344 45.445 42.440 1.00 13.82 C
+ATOM 2879 CE LYS A 442 0.888 45.242 42.003 1.00 18.53 C
+ATOM 2880 NZ LYS A 442 0.717 45.115 40.523 1.00 17.10 N
+ATOM 2881 N SER A 443 7.006 44.993 45.230 1.00 12.78 N
+ATOM 2882 CA SER A 443 8.346 45.510 45.479 1.00 14.07 C
+ATOM 2883 C SER A 443 9.282 44.875 44.443 1.00 11.28 C
+ATOM 2884 O SER A 443 10.263 45.489 44.050 1.00 15.49 O
+ATOM 2885 CB SER A 443 8.805 45.257 46.936 1.00 11.37 C
+ATOM 2886 OG SER A 443 8.705 43.906 47.353 1.00 15.99 O
+ATOM 2887 N ASP A 444 8.977 43.652 43.997 1.00 11.90 N
+ATOM 2888 CA ASP A 444 9.771 43.010 42.941 1.00 10.36 C
+ATOM 2889 C ASP A 444 9.584 43.786 41.626 1.00 14.26 C
+ATOM 2890 O ASP A 444 10.524 43.936 40.846 1.00 12.13 O
+ATOM 2891 CB ASP A 444 9.347 41.553 42.682 1.00 11.64 C
+ATOM 2892 CG ASP A 444 9.926 40.572 43.681 1.00 13.49 C
+ATOM 2893 OD1 ASP A 444 10.924 40.905 44.362 1.00 13.08 O
+ATOM 2894 OD2 ASP A 444 9.398 39.443 43.753 1.00 15.37 O
+ATOM 2895 N VAL A 445 8.367 44.258 41.368 1.00 13.71 N
+ATOM 2896 CA VAL A 445 8.121 45.013 40.144 1.00 13.87 C
+ATOM 2897 C VAL A 445 9.056 46.209 40.121 1.00 16.19 C
+ATOM 2898 O VAL A 445 9.655 46.509 39.091 1.00 15.78 O
+ATOM 2899 CB VAL A 445 6.665 45.502 40.044 1.00 16.53 C
+ATOM 2900 CG1 VAL A 445 6.533 46.486 38.882 1.00 15.96 C
+ATOM 2901 CG2 VAL A 445 5.735 44.315 39.810 1.00 12.87 C
+ATOM 2902 N TRP A 446 9.180 46.899 41.252 1.00 17.86 N
+ATOM 2903 CA TRP A 446 10.103 48.026 41.320 1.00 19.73 C
+ATOM 2904 C TRP A 446 11.496 47.522 40.923 1.00 20.03 C
+ATOM 2905 O TRP A 446 12.163 48.121 40.081 1.00 17.71 O
+ATOM 2906 CB TRP A 446 10.129 48.615 42.741 1.00 19.58 C
+ATOM 2907 CG TRP A 446 11.129 49.725 42.937 1.00 20.31 C
+ATOM 2908 CD1 TRP A 446 12.492 49.617 42.922 1.00 18.89 C
+ATOM 2909 CD2 TRP A 446 10.840 51.112 43.164 1.00 21.56 C
+ATOM 2910 NE1 TRP A 446 13.069 50.849 43.123 1.00 19.88 N
+ATOM 2911 CE2 TRP A 446 12.081 51.782 43.275 1.00 23.02 C
+ATOM 2912 CE3 TRP A 446 9.657 51.853 43.282 1.00 22.75 C
+ATOM 2913 CZ2 TRP A 446 12.169 53.163 43.499 1.00 22.56 C
+ATOM 2914 CZ3 TRP A 446 9.748 53.229 43.508 1.00 23.65 C
+ATOM 2915 CH2 TRP A 446 10.997 53.865 43.612 1.00 23.16 C
+ATOM 2916 N SER A 447 11.923 46.415 41.526 1.00 17.71 N
+ATOM 2917 CA SER A 447 13.233 45.833 41.229 1.00 16.14 C
+ATOM 2918 C SER A 447 13.413 45.520 39.742 1.00 16.38 C
+ATOM 2919 O SER A 447 14.482 45.755 39.178 1.00 16.10 O
+ATOM 2920 CB SER A 447 13.446 44.549 42.040 1.00 16.45 C
+ATOM 2921 OG SER A 447 13.430 44.801 43.432 1.00 16.54 O
+ATOM 2922 N PHE A 448 12.368 44.989 39.111 1.00 15.72 N
+ATOM 2923 CA PHE A 448 12.428 44.653 37.689 1.00 15.55 C
+ATOM 2924 C PHE A 448 12.729 45.910 36.867 1.00 17.05 C
+ATOM 2925 O PHE A 448 13.415 45.852 35.844 1.00 18.10 O
+ATOM 2926 CB PHE A 448 11.096 44.057 37.230 1.00 14.93 C
+ATOM 2927 CG PHE A 448 11.095 43.624 35.794 1.00 14.38 C
+ATOM 2928 CD1 PHE A 448 11.678 42.420 35.416 1.00 18.31 C
+ATOM 2929 CD2 PHE A 448 10.555 44.449 34.809 1.00 12.15 C
+ATOM 2930 CE1 PHE A 448 11.728 42.035 34.075 1.00 17.49 C
+ATOM 2931 CE2 PHE A 448 10.596 44.081 33.464 1.00 17.64 C
+ATOM 2932 CZ PHE A 448 11.183 42.871 33.092 1.00 16.35 C
+ATOM 2933 N GLY A 449 12.197 47.044 37.315 1.00 18.53 N
+ATOM 2934 CA GLY A 449 12.439 48.295 36.617 1.00 19.65 C
+ATOM 2935 C GLY A 449 13.914 48.641 36.668 1.00 18.25 C
+ATOM 2936 O GLY A 449 14.498 49.051 35.673 1.00 18.33 O
+ATOM 2937 N ILE A 450 14.524 48.486 37.837 1.00 17.24 N
+ATOM 2938 CA ILE A 450 15.950 48.770 37.970 1.00 15.92 C
+ATOM 2939 C ILE A 450 16.693 47.767 37.077 1.00 18.60 C
+ATOM 2940 O ILE A 450 17.633 48.129 36.373 1.00 21.10 O
+ATOM 2941 CB ILE A 450 16.413 48.632 39.453 1.00 16.33 C
+ATOM 2942 CG1 ILE A 450 15.558 49.534 40.355 1.00 15.37 C
+ATOM 2943 CG2 ILE A 450 17.881 49.040 39.600 1.00 15.03 C
+ATOM 2944 CD1 ILE A 450 15.702 51.047 40.084 1.00 16.18 C
+ATOM 2945 N LEU A 451 16.246 46.510 37.089 1.00 18.58 N
+ATOM 2946 CA LEU A 451 16.856 45.457 36.275 1.00 19.13 C
+ATOM 2947 C LEU A 451 16.784 45.810 34.793 1.00 19.64 C
+ATOM 2948 O LEU A 451 17.728 45.550 34.040 1.00 18.43 O
+ATOM 2949 CB LEU A 451 16.155 44.108 36.514 1.00 14.91 C
+ATOM 2950 CG LEU A 451 16.570 42.915 35.634 1.00 17.89 C
+ATOM 2951 CD1 LEU A 451 18.087 42.711 35.656 1.00 17.50 C
+ATOM 2952 CD2 LEU A 451 15.850 41.656 36.131 1.00 19.89 C
+ATOM 2953 N LEU A 452 15.658 46.383 34.372 1.00 19.10 N
+ATOM 2954 CA LEU A 452 15.494 46.774 32.974 1.00 21.07 C
+ATOM 2955 C LEU A 452 16.601 47.732 32.575 1.00 19.48 C
+ATOM 2956 O LEU A 452 17.168 47.613 31.489 1.00 22.06 O
+ATOM 2957 CB LEU A 452 14.138 47.451 32.737 1.00 20.73 C
+ATOM 2958 CG LEU A 452 12.902 46.558 32.663 1.00 26.36 C
+ATOM 2959 CD1 LEU A 452 11.673 47.409 32.338 1.00 26.27 C
+ATOM 2960 CD2 LEU A 452 13.110 45.504 31.572 1.00 29.02 C
+ATOM 2961 N MET A 453 16.902 48.676 33.465 1.00 20.04 N
+ATOM 2962 CA MET A 453 17.944 49.666 33.218 1.00 22.89 C
+ATOM 2963 C MET A 453 19.310 48.991 33.173 1.00 22.51 C
+ATOM 2964 O MET A 453 20.141 49.345 32.342 1.00 26.46 O
+ATOM 2965 CB MET A 453 17.928 50.758 34.298 1.00 22.50 C
+ATOM 2966 CG MET A 453 18.936 51.884 34.046 1.00 25.83 C
+ATOM 2967 SD MET A 453 18.512 52.908 32.608 1.00 26.90 S
+ATOM 2968 CE MET A 453 17.117 53.775 33.285 1.00 27.04 C
+ATOM 2969 N GLU A 454 19.559 48.023 34.053 1.00 22.34 N
+ATOM 2970 CA GLU A 454 20.850 47.339 34.004 1.00 21.66 C
+ATOM 2971 C GLU A 454 21.021 46.690 32.641 1.00 21.19 C
+ATOM 2972 O GLU A 454 22.086 46.764 32.034 1.00 24.50 O
+ATOM 2973 CB GLU A 454 20.965 46.208 35.029 1.00 22.27 C
+ATOM 2974 CG GLU A 454 21.012 46.587 36.467 1.00 25.39 C
+ATOM 2975 CD GLU A 454 21.270 45.368 37.342 1.00 24.68 C
+ATOM 2976 OE1 GLU A 454 22.447 45.000 37.565 1.00 23.93 O
+ATOM 2977 OE2 GLU A 454 20.280 44.759 37.781 1.00 22.23 O
+ATOM 2978 N ILE A 455 19.967 46.025 32.180 1.00 20.14 N
+ATOM 2979 CA ILE A 455 20.004 45.328 30.903 1.00 19.71 C
+ATOM 2980 C ILE A 455 20.234 46.241 29.701 1.00 22.93 C
+ATOM 2981 O ILE A 455 21.128 45.989 28.882 1.00 21.96 O
+ATOM 2982 CB ILE A 455 18.707 44.512 30.691 1.00 21.77 C
+ATOM 2983 CG1 ILE A 455 18.613 43.410 31.759 1.00 19.96 C
+ATOM 2984 CG2 ILE A 455 18.678 43.932 29.289 1.00 19.38 C
+ATOM 2985 CD1 ILE A 455 17.365 42.550 31.682 1.00 21.23 C
+ATOM 2986 N VAL A 456 19.439 47.302 29.598 1.00 19.10 N
+ATOM 2987 CA VAL A 456 19.563 48.223 28.474 1.00 22.08 C
+ATOM 2988 C VAL A 456 20.890 48.984 28.496 1.00 24.41 C
+ATOM 2989 O VAL A 456 21.291 49.567 27.491 1.00 25.90 O
+ATOM 2990 CB VAL A 456 18.366 49.226 28.429 1.00 24.63 C
+ATOM 2991 CG1 VAL A 456 18.394 50.150 29.629 1.00 27.16 C
+ATOM 2992 CG2 VAL A 456 18.395 50.019 27.138 1.00 31.09 C
+ATOM 2993 N THR A 457 21.581 48.965 29.632 1.00 26.20 N
+ATOM 2994 CA THR A 457 22.868 49.648 29.732 1.00 29.03 C
+ATOM 2995 C THR A 457 24.024 48.656 29.793 1.00 27.81 C
+ATOM 2996 O THR A 457 25.152 49.020 30.131 1.00 25.73 O
+ATOM 2997 CB THR A 457 22.945 50.540 30.976 1.00 29.04 C
+ATOM 2998 OG1 THR A 457 22.803 49.733 32.150 1.00 30.85 O
+ATOM 2999 CG2 THR A 457 21.852 51.595 30.940 1.00 26.78 C
+ATOM 3000 N TYR A 458 23.735 47.399 29.479 1.00 25.59 N
+ATOM 3001 CA TYR A 458 24.758 46.362 29.481 1.00 26.23 C
+ATOM 3002 C TYR A 458 25.435 46.095 30.832 1.00 25.04 C
+ATOM 3003 O TYR A 458 26.643 45.869 30.902 1.00 24.97 O
+ATOM 3004 CB TYR A 458 25.798 46.700 28.407 1.00 26.83 C
+ATOM 3005 CG TYR A 458 25.247 46.574 27.002 1.00 26.82 C
+ATOM 3006 CD1 TYR A 458 25.244 45.343 26.345 1.00 25.82 C
+ATOM 3007 CD2 TYR A 458 24.672 47.672 26.350 1.00 27.42 C
+ATOM 3008 CE1 TYR A 458 24.687 45.201 25.076 1.00 25.54 C
+ATOM 3009 CE2 TYR A 458 24.107 47.539 25.074 1.00 29.08 C
+ATOM 3010 CZ TYR A 458 24.118 46.300 24.446 1.00 27.66 C
+ATOM 3011 OH TYR A 458 23.565 46.154 23.192 1.00 31.80 O
+ATOM 3012 N GLY A 459 24.654 46.123 31.905 1.00 25.10 N
+ATOM 3013 CA GLY A 459 25.207 45.841 33.219 1.00 26.23 C
+ATOM 3014 C GLY A 459 25.737 47.001 34.036 1.00 27.75 C
+ATOM 3015 O GLY A 459 26.350 46.782 35.081 1.00 27.13 O
+ATOM 3016 N ARG A 460 25.518 48.231 33.581 1.00 29.79 N
+ATOM 3017 CA ARG A 460 25.999 49.387 34.332 1.00 31.34 C
+ATOM 3018 C ARG A 460 25.339 49.390 35.700 1.00 31.24 C
+ATOM 3019 O ARG A 460 24.207 48.941 35.852 1.00 31.10 O
+ATOM 3020 CB ARG A 460 25.640 50.695 33.626 1.00 35.29 C
+ATOM 3021 CG ARG A 460 26.153 51.944 34.352 1.00 41.46 C
+ATOM 3022 CD ARG A 460 25.369 53.183 33.940 1.00 44.88 C
+ATOM 3023 NE ARG A 460 23.980 53.085 34.385 1.00 49.46 N
+ATOM 3024 CZ ARG A 460 23.029 53.964 34.088 1.00 52.12 C
+ATOM 3025 NH1 ARG A 460 23.304 55.024 33.339 1.00 51.07 N
+ATOM 3026 NH2 ARG A 460 21.796 53.780 34.542 1.00 52.21 N
+ATOM 3027 N ILE A 461 26.046 49.913 36.690 1.00 32.11 N
+ATOM 3028 CA ILE A 461 25.520 49.984 38.045 1.00 33.49 C
+ATOM 3029 C ILE A 461 24.395 51.029 38.093 1.00 32.55 C
+ATOM 3030 O ILE A 461 24.449 52.031 37.382 1.00 30.83 O
+ATOM 3031 CB ILE A 461 26.627 50.423 39.029 1.00 36.39 C
+ATOM 3032 CG1 ILE A 461 27.870 49.539 38.866 1.00 36.98 C
+ATOM 3033 CG2 ILE A 461 26.107 50.377 40.455 1.00 36.51 C
+ATOM 3034 CD1 ILE A 461 27.643 48.074 39.128 1.00 40.95 C
+ATOM 3035 N PRO A 462 23.344 50.788 38.902 1.00 30.46 N
+ATOM 3036 CA PRO A 462 22.225 51.731 39.032 1.00 28.48 C
+ATOM 3037 C PRO A 462 22.698 52.985 39.791 1.00 28.11 C
+ATOM 3038 O PRO A 462 23.634 52.910 40.582 1.00 24.43 O
+ATOM 3039 CB PRO A 462 21.204 50.931 39.842 1.00 28.65 C
+ATOM 3040 CG PRO A 462 21.586 49.471 39.541 1.00 33.34 C
+ATOM 3041 CD PRO A 462 23.072 49.595 39.718 1.00 32.01 C
+ATOM 3042 N TYR A 463 22.035 54.118 39.572 1.00 29.61 N
+ATOM 3043 CA TYR A 463 22.404 55.378 40.224 1.00 28.23 C
+ATOM 3044 C TYR A 463 23.923 55.525 40.332 1.00 31.07 C
+ATOM 3045 O TYR A 463 24.471 55.637 41.433 1.00 27.74 O
+ATOM 3046 CB TYR A 463 21.803 55.464 41.627 1.00 29.02 C
+ATOM 3047 CG TYR A 463 20.333 55.141 41.682 1.00 29.15 C
+ATOM 3048 CD1 TYR A 463 19.897 53.823 41.800 1.00 27.04 C
+ATOM 3049 CD2 TYR A 463 19.374 56.147 41.553 1.00 27.52 C
+ATOM 3050 CE1 TYR A 463 18.542 53.512 41.789 1.00 27.03 C
+ATOM 3051 CE2 TYR A 463 18.009 55.846 41.538 1.00 28.52 C
+ATOM 3052 CZ TYR A 463 17.603 54.528 41.657 1.00 26.91 C
+ATOM 3053 OH TYR A 463 16.265 54.221 41.660 1.00 23.35 O
+ATOM 3054 N PRO A 464 24.617 55.545 39.187 1.00 32.79 N
+ATOM 3055 CA PRO A 464 26.076 55.673 39.137 1.00 36.62 C
+ATOM 3056 C PRO A 464 26.618 56.885 39.885 1.00 39.25 C
+ATOM 3057 O PRO A 464 26.271 58.024 39.573 1.00 41.96 O
+ATOM 3058 CB PRO A 464 26.356 55.733 37.634 1.00 39.08 C
+ATOM 3059 CG PRO A 464 25.064 56.350 37.081 1.00 39.06 C
+ATOM 3060 CD PRO A 464 24.073 55.483 37.821 1.00 35.59 C
+ATOM 3061 N GLY A 465 27.461 56.627 40.880 1.00 38.99 N
+ATOM 3062 CA GLY A 465 28.056 57.705 41.650 1.00 41.00 C
+ATOM 3063 C GLY A 465 27.303 58.111 42.901 1.00 41.57 C
+ATOM 3064 O GLY A 465 27.826 58.863 43.722 1.00 41.21 O
+ATOM 3065 N MET A 466 26.079 57.623 43.057 1.00 41.31 N
+ATOM 3066 CA MET A 466 25.279 57.966 44.229 1.00 41.51 C
+ATOM 3067 C MET A 466 25.439 56.934 45.333 1.00 42.25 C
+ATOM 3068 O MET A 466 25.686 55.756 45.062 1.00 42.84 O
+ATOM 3069 CB MET A 466 23.800 58.067 43.850 1.00 40.62 C
+ATOM 3070 CG MET A 466 23.512 59.071 42.750 1.00 38.99 C
+ATOM 3071 SD MET A 466 21.751 59.203 42.365 1.00 36.04 S
+ATOM 3072 CE MET A 466 21.098 59.755 43.904 1.00 33.29 C
+ATOM 3073 N SER A 467 25.299 57.378 46.579 1.00 42.53 N
+ATOM 3074 CA SER A 467 25.413 56.466 47.709 1.00 43.45 C
+ATOM 3075 C SER A 467 24.009 56.038 48.111 1.00 42.81 C
+ATOM 3076 O SER A 467 23.022 56.655 47.709 1.00 42.83 O
+ATOM 3077 CB SER A 467 26.108 57.139 48.899 1.00 43.57 C
+ATOM 3078 OG SER A 467 25.283 58.124 49.500 1.00 46.68 O
+ATOM 3079 N ASN A 468 23.919 54.979 48.903 1.00 42.01 N
+ATOM 3080 CA ASN A 468 22.624 54.480 49.342 1.00 42.13 C
+ATOM 3081 C ASN A 468 21.772 55.556 50.014 1.00 39.20 C
+ATOM 3082 O ASN A 468 20.579 55.667 49.746 1.00 35.85 O
+ATOM 3083 CB ASN A 468 22.817 53.290 50.286 1.00 40.67 C
+ATOM 3084 CG ASN A 468 23.394 52.075 49.583 1.00 42.59 C
+ATOM 3085 OD1 ASN A 468 23.756 51.089 50.225 1.00 44.96 O
+ATOM 3086 ND2 ASN A 468 23.467 52.134 48.256 1.00 39.82 N
+ATOM 3087 N PRO A 469 22.371 56.361 50.902 1.00 38.04 N
+ATOM 3088 CA PRO A 469 21.604 57.410 51.578 1.00 37.26 C
+ATOM 3089 C PRO A 469 21.068 58.455 50.602 1.00 34.79 C
+ATOM 3090 O PRO A 469 19.955 58.957 50.761 1.00 35.50 O
+ATOM 3091 CB PRO A 469 22.628 57.990 52.556 1.00 38.86 C
+ATOM 3092 CG PRO A 469 23.548 56.795 52.814 1.00 38.95 C
+ATOM 3093 CD PRO A 469 23.759 56.377 51.387 1.00 39.03 C
+ATOM 3094 N GLU A 470 21.870 58.774 49.592 1.00 29.96 N
+ATOM 3095 CA GLU A 470 21.492 59.758 48.590 1.00 31.75 C
+ATOM 3096 C GLU A 470 20.380 59.242 47.685 1.00 30.49 C
+ATOM 3097 O GLU A 470 19.504 60.004 47.271 1.00 25.72 O
+ATOM 3098 CB GLU A 470 22.710 60.131 47.746 1.00 34.07 C
+ATOM 3099 CG GLU A 470 23.871 60.661 48.564 1.00 36.61 C
+ATOM 3100 CD GLU A 470 25.064 61.023 47.710 1.00 38.33 C
+ATOM 3101 OE1 GLU A 470 25.531 60.149 46.949 1.00 38.17 O
+ATOM 3102 OE2 GLU A 470 25.537 62.178 47.804 1.00 39.96 O
+ATOM 3103 N VAL A 471 20.421 57.949 47.372 1.00 29.01 N
+ATOM 3104 CA VAL A 471 19.405 57.352 46.514 1.00 25.22 C
+ATOM 3105 C VAL A 471 18.072 57.355 47.245 1.00 26.94 C
+ATOM 3106 O VAL A 471 17.045 57.752 46.684 1.00 25.08 O
+ATOM 3107 CB VAL A 471 19.773 55.897 46.124 1.00 27.10 C
+ATOM 3108 CG1 VAL A 471 18.682 55.291 45.249 1.00 23.32 C
+ATOM 3109 CG2 VAL A 471 21.081 55.886 45.370 1.00 25.71 C
+ATOM 3110 N ILE A 472 18.097 56.922 48.504 1.00 25.02 N
+ATOM 3111 CA ILE A 472 16.892 56.868 49.320 1.00 27.85 C
+ATOM 3112 C ILE A 472 16.264 58.255 49.428 1.00 30.73 C
+ATOM 3113 O ILE A 472 15.042 58.401 49.333 1.00 31.59 O
+ATOM 3114 CB ILE A 472 17.200 56.317 50.732 1.00 27.62 C
+ATOM 3115 CG1 ILE A 472 17.703 54.873 50.616 1.00 29.41 C
+ATOM 3116 CG2 ILE A 472 15.953 56.388 51.608 1.00 31.42 C
+ATOM 3117 CD1 ILE A 472 18.044 54.209 51.940 1.00 30.58 C
+ATOM 3118 N ARG A 473 17.108 59.268 49.616 1.00 30.36 N
+ATOM 3119 CA ARG A 473 16.647 60.649 49.717 1.00 31.50 C
+ATOM 3120 C ARG A 473 16.104 61.195 48.404 1.00 29.87 C
+ATOM 3121 O ARG A 473 15.048 61.827 48.379 1.00 28.22 O
+ATOM 3122 CB ARG A 473 17.780 61.553 50.212 1.00 32.82 C
+ATOM 3123 CG ARG A 473 17.770 61.731 51.707 1.00 42.81 C
+ATOM 3124 CD ARG A 473 16.499 62.466 52.101 1.00 47.83 C
+ATOM 3125 NE ARG A 473 16.312 62.522 53.544 1.00 53.65 N
+ATOM 3126 CZ ARG A 473 15.294 63.134 54.139 1.00 53.53 C
+ATOM 3127 NH1 ARG A 473 14.368 63.747 53.415 1.00 54.45 N
+ATOM 3128 NH2 ARG A 473 15.195 63.119 55.459 1.00 54.57 N
+ATOM 3129 N ALA A 474 16.836 60.960 47.320 1.00 27.24 N
+ATOM 3130 CA ALA A 474 16.424 61.430 46.008 1.00 29.09 C
+ATOM 3131 C ALA A 474 15.072 60.846 45.594 1.00 28.85 C
+ATOM 3132 O ALA A 474 14.204 61.571 45.116 1.00 28.15 O
+ATOM 3133 CB ALA A 474 17.488 61.079 44.975 1.00 27.64 C
+ATOM 3134 N LEU A 475 14.895 59.539 45.780 1.00 29.49 N
+ATOM 3135 CA LEU A 475 13.643 58.876 45.415 1.00 27.57 C
+ATOM 3136 C LEU A 475 12.464 59.468 46.177 1.00 29.89 C
+ATOM 3137 O LEU A 475 11.368 59.612 45.631 1.00 28.32 O
+ATOM 3138 CB LEU A 475 13.737 57.369 45.685 1.00 23.49 C
+ATOM 3139 CG LEU A 475 14.756 56.590 44.839 1.00 22.50 C
+ATOM 3140 CD1 LEU A 475 14.879 55.133 45.336 1.00 19.28 C
+ATOM 3141 CD2 LEU A 475 14.319 56.626 43.382 1.00 19.45 C
+ATOM 3142 N GLU A 476 12.691 59.804 47.444 1.00 29.44 N
+ATOM 3143 CA GLU A 476 11.648 60.401 48.267 1.00 31.06 C
+ATOM 3144 C GLU A 476 11.302 61.783 47.712 1.00 28.79 C
+ATOM 3145 O GLU A 476 10.165 62.236 47.833 1.00 27.67 O
+ATOM 3146 CB GLU A 476 12.116 60.501 49.733 1.00 33.63 C
+ATOM 3147 CG GLU A 476 12.211 59.143 50.440 1.00 38.16 C
+ATOM 3148 CD GLU A 476 12.923 59.187 51.798 1.00 41.97 C
+ATOM 3149 OE1 GLU A 476 12.869 58.168 52.523 1.00 40.84 O
+ATOM 3150 OE2 GLU A 476 13.547 60.217 52.138 1.00 39.13 O
+ATOM 3151 N ARG A 477 12.285 62.430 47.085 1.00 27.70 N
+ATOM 3152 CA ARG A 477 12.110 63.762 46.508 1.00 30.68 C
+ATOM 3153 C ARG A 477 11.399 63.719 45.159 1.00 31.73 C
+ATOM 3154 O ARG A 477 10.817 64.710 44.727 1.00 31.88 O
+ATOM 3155 CB ARG A 477 13.461 64.442 46.353 1.00 33.75 C
+ATOM 3156 N GLY A 478 11.452 62.570 44.495 1.00 31.20 N
+ATOM 3157 CA GLY A 478 10.794 62.436 43.208 1.00 28.77 C
+ATOM 3158 C GLY A 478 11.764 62.095 42.096 1.00 27.78 C
+ATOM 3159 O GLY A 478 11.365 61.887 40.951 1.00 27.00 O
+ATOM 3160 N TYR A 479 13.047 62.050 42.433 1.00 23.87 N
+ATOM 3161 CA TYR A 479 14.077 61.720 41.461 1.00 24.61 C
+ATOM 3162 C TYR A 479 13.920 60.295 40.941 1.00 26.17 C
+ATOM 3163 O TYR A 479 13.462 59.402 41.654 1.00 28.42 O
+ATOM 3164 CB TYR A 479 15.460 61.838 42.099 1.00 26.25 C
+ATOM 3165 CG TYR A 479 16.598 61.453 41.178 1.00 24.44 C
+ATOM 3166 CD1 TYR A 479 17.013 62.301 40.153 1.00 28.10 C
+ATOM 3167 CD2 TYR A 479 17.240 60.223 41.315 1.00 26.32 C
+ATOM 3168 CE1 TYR A 479 18.042 61.932 39.286 1.00 27.67 C
+ATOM 3169 CE2 TYR A 479 18.264 59.845 40.456 1.00 24.23 C
+ATOM 3170 CZ TYR A 479 18.660 60.702 39.445 1.00 25.73 C
+ATOM 3171 OH TYR A 479 19.667 60.320 38.594 1.00 27.67 O
+ATOM 3172 N ARG A 480 14.321 60.096 39.693 1.00 26.79 N
+ATOM 3173 CA ARG A 480 14.293 58.791 39.048 1.00 28.17 C
+ATOM 3174 C ARG A 480 15.425 58.830 38.032 1.00 29.15 C
+ATOM 3175 O ARG A 480 15.653 59.868 37.408 1.00 28.31 O
+ATOM 3176 CB ARG A 480 12.957 58.563 38.339 1.00 23.89 C
+ATOM 3177 CG ARG A 480 11.759 58.439 39.280 1.00 28.89 C
+ATOM 3178 CD ARG A 480 11.823 57.154 40.084 1.00 28.09 C
+ATOM 3179 NE ARG A 480 10.638 56.937 40.915 1.00 28.31 N
+ATOM 3180 CZ ARG A 480 10.379 57.573 42.054 1.00 29.91 C
+ATOM 3181 NH1 ARG A 480 11.225 58.483 42.520 1.00 30.64 N
+ATOM 3182 NH2 ARG A 480 9.274 57.287 42.733 1.00 26.68 N
+ATOM 3183 N MET A 481 16.157 57.729 37.883 1.00 28.37 N
+ATOM 3184 CA MET A 481 17.246 57.708 36.913 1.00 29.52 C
+ATOM 3185 C MET A 481 16.718 58.132 35.553 1.00 29.34 C
+ATOM 3186 O MET A 481 15.651 57.687 35.129 1.00 31.02 O
+ATOM 3187 CB MET A 481 17.856 56.313 36.777 1.00 31.15 C
+ATOM 3188 CG MET A 481 18.677 55.835 37.962 1.00 31.92 C
+ATOM 3189 SD MET A 481 19.363 54.198 37.612 1.00 33.13 S
+ATOM 3190 CE MET A 481 17.848 53.223 37.505 1.00 28.87 C
+ATOM 3191 N PRO A 482 17.448 59.024 34.866 1.00 30.83 N
+ATOM 3192 CA PRO A 482 17.080 59.526 33.539 1.00 30.42 C
+ATOM 3193 C PRO A 482 17.203 58.427 32.483 1.00 31.87 C
+ATOM 3194 O PRO A 482 17.863 57.413 32.711 1.00 31.44 O
+ATOM 3195 CB PRO A 482 18.091 60.650 33.322 1.00 32.23 C
+ATOM 3196 CG PRO A 482 19.322 60.096 34.026 1.00 31.33 C
+ATOM 3197 CD PRO A 482 18.673 59.698 35.336 1.00 27.89 C
+ATOM 3198 N ARG A 483 16.571 58.631 31.331 1.00 31.14 N
+ATOM 3199 CA ARG A 483 16.622 57.656 30.246 1.00 31.28 C
+ATOM 3200 C ARG A 483 17.925 57.729 29.456 1.00 33.21 C
+ATOM 3201 O ARG A 483 18.302 58.790 28.968 1.00 32.15 O
+ATOM 3202 CB ARG A 483 15.450 57.868 29.281 1.00 31.52 C
+ATOM 3203 CG ARG A 483 15.455 56.910 28.081 1.00 31.95 C
+ATOM 3204 CD ARG A 483 14.208 57.053 27.205 1.00 32.59 C
+ATOM 3205 NE ARG A 483 14.135 58.322 26.484 1.00 36.70 N
+ATOM 3206 CZ ARG A 483 14.919 58.657 25.463 1.00 37.29 C
+ATOM 3207 NH1 ARG A 483 15.849 57.820 25.028 1.00 41.18 N
+ATOM 3208 NH2 ARG A 483 14.779 59.838 24.878 1.00 38.85 N
+ATOM 3209 N PRO A 484 18.630 56.595 29.317 1.00 35.54 N
+ATOM 3210 CA PRO A 484 19.895 56.526 28.575 1.00 36.23 C
+ATOM 3211 C PRO A 484 19.646 56.738 27.080 1.00 38.94 C
+ATOM 3212 O PRO A 484 18.535 56.521 26.598 1.00 38.73 O
+ATOM 3213 CB PRO A 484 20.388 55.109 28.880 1.00 37.04 C
+ATOM 3214 CG PRO A 484 19.715 54.793 30.214 1.00 36.28 C
+ATOM 3215 CD PRO A 484 18.323 55.273 29.882 1.00 34.21 C
+ATOM 3216 N GLU A 485 20.680 57.146 26.351 1.00 42.50 N
+ATOM 3217 CA GLU A 485 20.562 57.397 24.912 1.00 45.38 C
+ATOM 3218 C GLU A 485 20.060 56.212 24.088 1.00 45.15 C
+ATOM 3219 O GLU A 485 19.209 56.373 23.213 1.00 44.84 O
+ATOM 3220 CB GLU A 485 21.910 57.850 24.340 1.00 51.03 C
+ATOM 3221 CG GLU A 485 21.906 58.044 22.820 1.00 56.34 C
+ATOM 3222 CD GLU A 485 23.284 58.380 22.261 1.00 60.17 C
+ATOM 3223 OE1 GLU A 485 23.856 59.415 22.666 1.00 60.71 O
+ATOM 3224 OE2 GLU A 485 23.793 57.607 21.417 1.00 61.52 O
+ATOM 3225 N ASN A 486 20.596 55.027 24.352 1.00 43.77 N
+ATOM 3226 CA ASN A 486 20.193 53.845 23.601 1.00 44.80 C
+ATOM 3227 C ASN A 486 18.974 53.131 24.173 1.00 42.81 C
+ATOM 3228 O ASN A 486 18.763 51.946 23.919 1.00 43.81 O
+ATOM 3229 CB ASN A 486 21.363 52.867 23.499 1.00 46.89 C
+ATOM 3230 CG ASN A 486 22.507 53.421 22.675 1.00 52.48 C
+ATOM 3231 OD1 ASN A 486 22.315 53.828 21.527 1.00 55.33 O
+ATOM 3232 ND2 ASN A 486 23.706 53.436 23.252 1.00 52.18 N
+ATOM 3233 N CYS A 487 18.170 53.857 24.942 1.00 39.76 N
+ATOM 3234 CA CYS A 487 16.973 53.279 25.538 1.00 34.85 C
+ATOM 3235 C CYS A 487 15.716 53.914 24.958 1.00 33.82 C
+ATOM 3236 O CYS A 487 15.435 55.086 25.196 1.00 32.07 O
+ATOM 3237 CB CYS A 487 16.986 53.471 27.055 1.00 33.25 C
+ATOM 3238 SG CYS A 487 15.500 52.846 27.878 1.00 30.26 S
+ATOM 3239 N PRO A 488 14.939 53.141 24.189 1.00 33.05 N
+ATOM 3240 CA PRO A 488 13.710 53.661 23.589 1.00 34.02 C
+ATOM 3241 C PRO A 488 12.779 54.218 24.664 1.00 33.17 C
+ATOM 3242 O PRO A 488 12.735 53.704 25.788 1.00 30.98 O
+ATOM 3243 CB PRO A 488 13.137 52.430 22.881 1.00 33.67 C
+ATOM 3244 CG PRO A 488 13.677 51.285 23.738 1.00 34.41 C
+ATOM 3245 CD PRO A 488 15.111 51.724 23.836 1.00 31.59 C
+ATOM 3246 N GLU A 489 12.048 55.274 24.322 1.00 28.83 N
+ATOM 3247 CA GLU A 489 11.120 55.893 25.264 1.00 31.07 C
+ATOM 3248 C GLU A 489 10.076 54.920 25.784 1.00 26.34 C
+ATOM 3249 O GLU A 489 9.717 54.966 26.959 1.00 27.48 O
+ATOM 3250 CB GLU A 489 10.408 57.092 24.625 1.00 32.75 C
+ATOM 3251 CG GLU A 489 11.300 58.291 24.378 1.00 43.54 C
+ATOM 3252 CD GLU A 489 10.547 59.447 23.744 1.00 51.63 C
+ATOM 3253 OE1 GLU A 489 10.118 59.308 22.576 1.00 52.92 O
+ATOM 3254 OE2 GLU A 489 10.374 60.488 24.418 1.00 54.00 O
+ATOM 3255 N GLU A 490 9.579 54.047 24.915 1.00 27.44 N
+ATOM 3256 CA GLU A 490 8.568 53.083 25.330 1.00 28.74 C
+ATOM 3257 C GLU A 490 9.108 52.159 26.415 1.00 28.88 C
+ATOM 3258 O GLU A 490 8.378 51.775 27.326 1.00 28.60 O
+ATOM 3259 CB GLU A 490 8.090 52.233 24.148 1.00 31.96 C
+ATOM 3260 CG GLU A 490 7.399 52.996 23.030 1.00 39.86 C
+ATOM 3261 CD GLU A 490 8.333 53.936 22.297 1.00 44.73 C
+ATOM 3262 OE1 GLU A 490 9.383 53.469 21.807 1.00 45.96 O
+ATOM 3263 OE2 GLU A 490 8.013 55.139 22.201 1.00 51.63 O
+ATOM 3264 N LEU A 491 10.383 51.794 26.317 1.00 27.16 N
+ATOM 3265 CA LEU A 491 10.974 50.910 27.311 1.00 26.59 C
+ATOM 3266 C LEU A 491 11.162 51.689 28.607 1.00 26.78 C
+ATOM 3267 O LEU A 491 10.962 51.160 29.703 1.00 24.69 O
+ATOM 3268 CB LEU A 491 12.317 50.364 26.818 1.00 27.57 C
+ATOM 3269 CG LEU A 491 12.990 49.374 27.775 1.00 31.18 C
+ATOM 3270 CD1 LEU A 491 12.088 48.161 27.973 1.00 28.40 C
+ATOM 3271 CD2 LEU A 491 14.341 48.942 27.205 1.00 28.87 C
+ATOM 3272 N TYR A 492 11.535 52.956 28.476 1.00 25.28 N
+ATOM 3273 CA TYR A 492 11.727 53.809 29.638 1.00 22.47 C
+ATOM 3274 C TYR A 492 10.383 54.028 30.341 1.00 23.62 C
+ATOM 3275 O TYR A 492 10.307 54.043 31.580 1.00 22.28 O
+ATOM 3276 CB TYR A 492 12.326 55.153 29.215 1.00 24.63 C
+ATOM 3277 CG TYR A 492 12.676 56.059 30.377 1.00 25.60 C
+ATOM 3278 CD1 TYR A 492 13.656 55.696 31.301 1.00 27.79 C
+ATOM 3279 CD2 TYR A 492 12.017 57.272 30.562 1.00 26.10 C
+ATOM 3280 CE1 TYR A 492 13.968 56.516 32.376 1.00 23.59 C
+ATOM 3281 CE2 TYR A 492 12.321 58.099 31.632 1.00 25.41 C
+ATOM 3282 CZ TYR A 492 13.296 57.717 32.534 1.00 26.95 C
+ATOM 3283 OH TYR A 492 13.601 58.542 33.586 1.00 26.10 O
+ATOM 3284 N ASN A 493 9.318 54.186 29.557 1.00 20.75 N
+ATOM 3285 CA ASN A 493 8.000 54.392 30.147 1.00 22.36 C
+ATOM 3286 C ASN A 493 7.622 53.238 31.065 1.00 20.69 C
+ATOM 3287 O ASN A 493 7.020 53.449 32.115 1.00 24.16 O
+ATOM 3288 CB ASN A 493 6.922 54.569 29.074 1.00 24.15 C
+ATOM 3289 CG ASN A 493 7.032 55.900 28.354 1.00 32.80 C
+ATOM 3290 OD1 ASN A 493 7.342 56.924 28.969 1.00 34.75 O
+ATOM 3291 ND2 ASN A 493 6.749 55.901 27.054 1.00 34.19 N
+ATOM 3292 N ILE A 494 7.973 52.021 30.669 1.00 20.38 N
+ATOM 3293 CA ILE A 494 7.675 50.856 31.494 1.00 22.01 C
+ATOM 3294 C ILE A 494 8.461 50.959 32.801 1.00 21.18 C
+ATOM 3295 O ILE A 494 7.918 50.733 33.878 1.00 23.78 O
+ATOM 3296 CB ILE A 494 8.022 49.553 30.747 1.00 23.61 C
+ATOM 3297 CG1 ILE A 494 7.145 49.448 29.494 1.00 26.42 C
+ATOM 3298 CG2 ILE A 494 7.810 48.345 31.657 1.00 25.67 C
+ATOM 3299 CD1 ILE A 494 7.410 48.231 28.641 1.00 28.36 C
+ATOM 3300 N MET A 495 9.739 51.312 32.709 1.00 21.59 N
+ATOM 3301 CA MET A 495 10.558 51.471 33.908 1.00 23.60 C
+ATOM 3302 C MET A 495 9.862 52.445 34.863 1.00 20.98 C
+ATOM 3303 O MET A 495 9.679 52.153 36.047 1.00 19.81 O
+ATOM 3304 CB MET A 495 11.937 52.041 33.559 1.00 20.97 C
+ATOM 3305 CG MET A 495 12.785 51.188 32.627 1.00 25.61 C
+ATOM 3306 SD MET A 495 14.400 51.963 32.345 1.00 22.34 S
+ATOM 3307 CE MET A 495 15.086 50.913 31.091 1.00 21.47 C
+ATOM 3308 N MET A 496 9.470 53.604 34.335 1.00 18.66 N
+ATOM 3309 CA MET A 496 8.824 54.626 35.152 1.00 20.90 C
+ATOM 3310 C MET A 496 7.581 54.120 35.860 1.00 19.18 C
+ATOM 3311 O MET A 496 7.307 54.522 36.986 1.00 20.91 O
+ATOM 3312 CB MET A 496 8.498 55.874 34.312 1.00 20.32 C
+ATOM 3313 CG MET A 496 9.736 56.674 33.929 1.00 23.42 C
+ATOM 3314 SD MET A 496 10.586 57.431 35.367 1.00 27.24 S
+ATOM 3315 CE MET A 496 9.402 58.679 35.862 1.00 30.44 C
+ATOM 3316 N ARG A 497 6.830 53.234 35.212 1.00 19.91 N
+ATOM 3317 CA ARG A 497 5.636 52.691 35.843 1.00 22.22 C
+ATOM 3318 C ARG A 497 6.035 51.733 36.961 1.00 23.43 C
+ATOM 3319 O ARG A 497 5.341 51.629 37.977 1.00 22.27 O
+ATOM 3320 CB ARG A 497 4.752 51.986 34.813 1.00 24.12 C
+ATOM 3321 CG ARG A 497 4.137 52.927 33.769 1.00 26.85 C
+ATOM 3322 CD ARG A 497 3.083 52.194 32.959 1.00 29.59 C
+ATOM 3323 NE ARG A 497 2.048 51.671 33.848 1.00 37.25 N
+ATOM 3324 CZ ARG A 497 1.034 50.904 33.465 1.00 40.41 C
+ATOM 3325 NH1 ARG A 497 0.898 50.558 32.192 1.00 38.41 N
+ATOM 3326 NH2 ARG A 497 0.157 50.473 34.364 1.00 41.82 N
+ATOM 3327 N CYS A 498 7.154 51.038 36.777 1.00 21.20 N
+ATOM 3328 CA CYS A 498 7.639 50.123 37.804 1.00 20.68 C
+ATOM 3329 C CYS A 498 8.075 50.888 39.044 1.00 20.43 C
+ATOM 3330 O CYS A 498 7.969 50.376 40.161 1.00 20.84 O
+ATOM 3331 CB CYS A 498 8.828 49.304 37.299 1.00 19.75 C
+ATOM 3332 SG CYS A 498 8.381 48.072 36.084 1.00 19.34 S
+ATOM 3333 N TRP A 499 8.560 52.112 38.845 1.00 20.79 N
+ATOM 3334 CA TRP A 499 9.041 52.927 39.958 1.00 22.26 C
+ATOM 3335 C TRP A 499 8.028 53.886 40.574 1.00 23.52 C
+ATOM 3336 O TRP A 499 8.403 54.964 41.039 1.00 25.98 O
+ATOM 3337 CB TRP A 499 10.280 53.732 39.551 1.00 21.99 C
+ATOM 3338 CG TRP A 499 11.388 52.909 38.981 1.00 21.07 C
+ATOM 3339 CD1 TRP A 499 11.777 51.659 39.376 1.00 20.79 C
+ATOM 3340 CD2 TRP A 499 12.293 53.303 37.946 1.00 20.27 C
+ATOM 3341 NE1 TRP A 499 12.872 51.250 38.647 1.00 19.82 N
+ATOM 3342 CE2 TRP A 499 13.208 52.242 37.762 1.00 19.99 C
+ATOM 3343 CE3 TRP A 499 12.420 54.453 37.154 1.00 20.76 C
+ATOM 3344 CZ2 TRP A 499 14.238 52.298 36.821 1.00 22.05 C
+ATOM 3345 CZ3 TRP A 499 13.440 54.509 36.219 1.00 19.77 C
+ATOM 3346 CH2 TRP A 499 14.338 53.437 36.060 1.00 23.72 C
+ATOM 3347 N LYS A 500 6.754 53.512 40.575 1.00 22.20 N
+ATOM 3348 CA LYS A 500 5.743 54.361 41.189 1.00 23.61 C
+ATOM 3349 C LYS A 500 5.910 54.237 42.687 1.00 25.33 C
+ATOM 3350 O LYS A 500 6.157 53.144 43.203 1.00 20.53 O
+ATOM 3351 CB LYS A 500 4.330 53.922 40.797 1.00 24.99 C
+ATOM 3352 CG LYS A 500 3.936 54.323 39.393 1.00 26.30 C
+ATOM 3353 CD LYS A 500 4.028 55.841 39.240 1.00 30.76 C
+ATOM 3354 CE LYS A 500 3.441 56.312 37.924 1.00 37.05 C
+ATOM 3355 NZ LYS A 500 1.995 55.948 37.849 1.00 44.39 N
+ATOM 3356 N ASN A 501 5.780 55.354 43.387 1.00 23.08 N
+ATOM 3357 CA ASN A 501 5.923 55.333 44.827 1.00 25.92 C
+ATOM 3358 C ASN A 501 4.854 54.448 45.454 1.00 26.50 C
+ATOM 3359 O ASN A 501 5.129 53.708 46.399 1.00 28.08 O
+ATOM 3360 CB ASN A 501 5.825 56.743 45.401 1.00 31.54 C
+ATOM 3361 CG ASN A 501 6.041 56.763 46.886 1.00 37.29 C
+ATOM 3362 OD1 ASN A 501 7.114 56.397 47.368 1.00 41.79 O
+ATOM 3363 ND2 ASN A 501 5.019 57.169 47.631 1.00 44.96 N
+ATOM 3364 N ARG A 502 3.632 54.519 44.939 1.00 26.56 N
+ATOM 3365 CA ARG A 502 2.559 53.690 45.487 1.00 28.34 C
+ATOM 3366 C ARG A 502 2.618 52.302 44.852 1.00 26.80 C
+ATOM 3367 O ARG A 502 2.416 52.156 43.645 1.00 25.54 O
+ATOM 3368 CB ARG A 502 1.196 54.325 45.224 1.00 33.15 C
+ATOM 3369 CG ARG A 502 1.087 55.757 45.714 1.00 40.31 C
+ATOM 3370 CD ARG A 502 -0.340 56.119 46.090 1.00 46.61 C
+ATOM 3371 NE ARG A 502 -0.788 55.332 47.239 1.00 52.18 N
+ATOM 3372 CZ ARG A 502 -1.881 55.590 47.952 1.00 54.72 C
+ATOM 3373 NH1 ARG A 502 -2.654 56.623 47.641 1.00 56.43 N
+ATOM 3374 NH2 ARG A 502 -2.195 54.824 48.988 1.00 56.63 N
+ATOM 3375 N PRO A 503 2.894 51.261 45.655 1.00 25.04 N
+ATOM 3376 CA PRO A 503 2.967 49.918 45.078 1.00 24.64 C
+ATOM 3377 C PRO A 503 1.770 49.475 44.249 1.00 25.19 C
+ATOM 3378 O PRO A 503 1.954 48.836 43.213 1.00 21.04 O
+ATOM 3379 CB PRO A 503 3.225 49.031 46.305 1.00 27.14 C
+ATOM 3380 CG PRO A 503 2.623 49.844 47.446 1.00 30.86 C
+ATOM 3381 CD PRO A 503 3.175 51.203 47.098 1.00 28.00 C
+ATOM 3382 N GLU A 504 0.553 49.819 44.670 1.00 23.56 N
+ATOM 3383 CA GLU A 504 -0.615 49.394 43.907 1.00 25.01 C
+ATOM 3384 C GLU A 504 -0.719 50.044 42.538 1.00 25.45 C
+ATOM 3385 O GLU A 504 -1.507 49.612 41.695 1.00 29.73 O
+ATOM 3386 CB GLU A 504 -1.919 49.603 44.698 1.00 26.26 C
+ATOM 3387 CG GLU A 504 -2.335 51.027 45.048 1.00 28.24 C
+ATOM 3388 CD GLU A 504 -1.340 51.758 45.922 1.00 31.17 C
+ATOM 3389 OE1 GLU A 504 -0.677 51.120 46.769 1.00 30.73 O
+ATOM 3390 OE2 GLU A 504 -1.245 52.991 45.776 1.00 37.76 O
+ATOM 3391 N GLU A 505 0.089 51.070 42.300 1.00 25.74 N
+ATOM 3392 CA GLU A 505 0.064 51.740 41.010 1.00 24.59 C
+ATOM 3393 C GLU A 505 1.079 51.185 40.016 1.00 25.43 C
+ATOM 3394 O GLU A 505 1.144 51.636 38.872 1.00 22.81 O
+ATOM 3395 CB GLU A 505 0.252 53.244 41.192 1.00 27.30 C
+ATOM 3396 CG GLU A 505 -1.026 53.925 41.653 1.00 34.13 C
+ATOM 3397 CD GLU A 505 -0.848 55.400 41.912 1.00 37.07 C
+ATOM 3398 OE1 GLU A 505 -0.309 56.102 41.029 1.00 40.66 O
+ATOM 3399 OE2 GLU A 505 -1.261 55.858 42.998 1.00 44.13 O
+ATOM 3400 N ARG A 506 1.869 50.209 40.456 1.00 21.14 N
+ATOM 3401 CA ARG A 506 2.849 49.558 39.583 1.00 20.17 C
+ATOM 3402 C ARG A 506 2.101 48.441 38.837 1.00 18.37 C
+ATOM 3403 O ARG A 506 1.189 47.820 39.382 1.00 19.32 O
+ATOM 3404 CB ARG A 506 3.986 48.953 40.418 1.00 19.24 C
+ATOM 3405 CG ARG A 506 4.749 49.977 41.247 1.00 20.70 C
+ATOM 3406 CD ARG A 506 5.681 49.338 42.275 1.00 22.92 C
+ATOM 3407 NE ARG A 506 6.139 50.352 43.224 1.00 19.81 N
+ATOM 3408 CZ ARG A 506 6.626 50.088 44.429 1.00 19.17 C
+ATOM 3409 NH1 ARG A 506 6.730 48.829 44.848 1.00 14.79 N
+ATOM 3410 NH2 ARG A 506 6.960 51.087 45.235 1.00 16.78 N
+ATOM 3411 N PRO A 507 2.463 48.183 37.577 1.00 18.24 N
+ATOM 3412 CA PRO A 507 1.783 47.126 36.820 1.00 19.67 C
+ATOM 3413 C PRO A 507 2.107 45.730 37.346 1.00 18.96 C
+ATOM 3414 O PRO A 507 3.012 45.556 38.162 1.00 19.78 O
+ATOM 3415 CB PRO A 507 2.314 47.341 35.409 1.00 20.23 C
+ATOM 3416 CG PRO A 507 3.740 47.788 35.693 1.00 22.95 C
+ATOM 3417 CD PRO A 507 3.474 48.847 36.736 1.00 19.14 C
+ATOM 3418 N THR A 508 1.352 44.735 36.895 1.00 17.77 N
+ATOM 3419 CA THR A 508 1.617 43.357 37.304 1.00 16.80 C
+ATOM 3420 C THR A 508 2.670 42.818 36.330 1.00 16.66 C
+ATOM 3421 O THR A 508 2.890 43.403 35.262 1.00 13.81 O
+ATOM 3422 CB THR A 508 0.369 42.487 37.167 1.00 16.28 C
+ATOM 3423 OG1 THR A 508 -0.025 42.466 35.790 1.00 19.56 O
+ATOM 3424 CG2 THR A 508 -0.780 43.042 38.026 1.00 17.66 C
+ATOM 3425 N PHE A 509 3.326 41.718 36.693 1.00 15.87 N
+ATOM 3426 CA PHE A 509 4.317 41.120 35.804 1.00 15.68 C
+ATOM 3427 C PHE A 509 3.598 40.513 34.611 1.00 14.23 C
+ATOM 3428 O PHE A 509 4.161 40.410 33.517 1.00 15.95 O
+ATOM 3429 CB PHE A 509 5.135 40.051 36.531 1.00 13.92 C
+ATOM 3430 CG PHE A 509 6.252 40.616 37.361 1.00 11.94 C
+ATOM 3431 CD1 PHE A 509 7.313 41.272 36.745 1.00 15.42 C
+ATOM 3432 CD2 PHE A 509 6.246 40.507 38.747 1.00 13.14 C
+ATOM 3433 CE1 PHE A 509 8.362 41.818 37.492 1.00 11.42 C
+ATOM 3434 CE2 PHE A 509 7.295 41.052 39.504 1.00 12.08 C
+ATOM 3435 CZ PHE A 509 8.355 41.710 38.859 1.00 7.43 C
+ATOM 3436 N GLU A 510 2.348 40.108 34.821 1.00 16.01 N
+ATOM 3437 CA GLU A 510 1.565 39.553 33.723 1.00 19.09 C
+ATOM 3438 C GLU A 510 1.459 40.614 32.626 1.00 16.88 C
+ATOM 3439 O GLU A 510 1.616 40.315 31.448 1.00 18.25 O
+ATOM 3440 CB GLU A 510 0.160 39.149 34.191 1.00 21.91 C
+ATOM 3441 CG GLU A 510 -0.791 38.878 33.022 1.00 27.70 C
+ATOM 3442 CD GLU A 510 -2.158 38.385 33.448 1.00 33.90 C
+ATOM 3443 OE1 GLU A 510 -2.749 38.980 34.373 1.00 37.85 O
+ATOM 3444 OE2 GLU A 510 -2.651 37.411 32.841 1.00 38.39 O
+ATOM 3445 N TYR A 511 1.198 41.856 33.022 1.00 18.56 N
+ATOM 3446 CA TYR A 511 1.084 42.958 32.065 1.00 18.75 C
+ATOM 3447 C TYR A 511 2.441 43.241 31.429 1.00 16.10 C
+ATOM 3448 O TYR A 511 2.565 43.321 30.211 1.00 17.03 O
+ATOM 3449 CB TYR A 511 0.603 44.231 32.763 1.00 21.50 C
+ATOM 3450 CG TYR A 511 0.392 45.388 31.813 1.00 26.89 C
+ATOM 3451 CD1 TYR A 511 -0.726 45.429 30.980 1.00 28.62 C
+ATOM 3452 CD2 TYR A 511 1.320 46.426 31.727 1.00 27.38 C
+ATOM 3453 CE1 TYR A 511 -0.920 46.476 30.084 1.00 30.42 C
+ATOM 3454 CE2 TYR A 511 1.136 47.482 30.829 1.00 30.15 C
+ATOM 3455 CZ TYR A 511 0.011 47.497 30.012 1.00 32.49 C
+ATOM 3456 OH TYR A 511 -0.187 48.524 29.117 1.00 36.29 O
+ATOM 3457 N ILE A 512 3.454 43.416 32.273 1.00 17.39 N
+ATOM 3458 CA ILE A 512 4.813 43.687 31.818 1.00 15.54 C
+ATOM 3459 C ILE A 512 5.278 42.657 30.787 1.00 17.33 C
+ATOM 3460 O ILE A 512 5.886 43.004 29.768 1.00 19.34 O
+ATOM 3461 CB ILE A 512 5.792 43.707 33.031 1.00 17.60 C
+ATOM 3462 CG1 ILE A 512 5.518 44.952 33.880 1.00 16.09 C
+ATOM 3463 CG2 ILE A 512 7.248 43.669 32.553 1.00 15.66 C
+ATOM 3464 CD1 ILE A 512 6.199 44.966 35.243 1.00 15.70 C
+ATOM 3465 N GLN A 513 4.993 41.387 31.051 1.00 18.07 N
+ATOM 3466 CA GLN A 513 5.385 40.331 30.125 1.00 16.25 C
+ATOM 3467 C GLN A 513 4.664 40.537 28.798 1.00 17.96 C
+ATOM 3468 O GLN A 513 5.271 40.435 27.735 1.00 20.35 O
+ATOM 3469 CB GLN A 513 5.005 38.955 30.656 1.00 14.36 C
+ATOM 3470 CG GLN A 513 5.571 37.824 29.816 1.00 15.83 C
+ATOM 3471 CD GLN A 513 4.857 36.517 30.039 1.00 18.51 C
+ATOM 3472 OE1 GLN A 513 4.501 36.175 31.163 1.00 21.39 O
+ATOM 3473 NE2 GLN A 513 4.660 35.763 28.964 1.00 22.51 N
+ATOM 3474 N SER A 514 3.366 40.826 28.864 1.00 18.99 N
+ATOM 3475 CA SER A 514 2.592 41.029 27.644 1.00 21.86 C
+ATOM 3476 C SER A 514 3.199 42.173 26.833 1.00 21.31 C
+ATOM 3477 O SER A 514 3.396 42.046 25.630 1.00 24.36 O
+ATOM 3478 CB SER A 514 1.125 41.349 27.961 1.00 21.27 C
+ATOM 3479 OG SER A 514 0.959 42.701 28.366 1.00 23.54 O
+ATOM 3480 N VAL A 515 3.512 43.289 27.484 1.00 21.41 N
+ATOM 3481 CA VAL A 515 4.090 44.417 26.756 1.00 24.31 C
+ATOM 3482 C VAL A 515 5.469 44.111 26.162 1.00 24.63 C
+ATOM 3483 O VAL A 515 5.769 44.520 25.039 1.00 24.57 O
+ATOM 3484 CB VAL A 515 4.191 45.678 27.646 1.00 24.13 C
+ATOM 3485 CG1 VAL A 515 4.955 46.773 26.909 1.00 27.37 C
+ATOM 3486 CG2 VAL A 515 2.790 46.185 27.986 1.00 29.28 C
+ATOM 3487 N LEU A 516 6.312 43.395 26.900 1.00 20.42 N
+ATOM 3488 CA LEU A 516 7.638 43.074 26.382 1.00 20.92 C
+ATOM 3489 C LEU A 516 7.641 41.969 25.327 1.00 19.75 C
+ATOM 3490 O LEU A 516 8.419 42.041 24.381 1.00 19.83 O
+ATOM 3491 CB LEU A 516 8.596 42.708 27.520 1.00 19.70 C
+ATOM 3492 CG LEU A 516 8.853 43.830 28.531 1.00 19.54 C
+ATOM 3493 CD1 LEU A 516 9.763 43.305 29.646 1.00 19.43 C
+ATOM 3494 CD2 LEU A 516 9.481 45.033 27.835 1.00 20.18 C
+ATOM 3495 N ASP A 517 6.799 40.945 25.470 1.00 20.48 N
+ATOM 3496 CA ASP A 517 6.785 39.886 24.453 1.00 22.93 C
+ATOM 3497 C ASP A 517 6.443 40.466 23.089 1.00 23.12 C
+ATOM 3498 O ASP A 517 7.003 40.055 22.075 1.00 22.50 O
+ATOM 3499 CB ASP A 517 5.755 38.782 24.745 1.00 19.36 C
+ATOM 3500 CG ASP A 517 6.182 37.848 25.853 1.00 22.39 C
+ATOM 3501 OD1 ASP A 517 7.394 37.779 26.138 1.00 20.05 O
+ATOM 3502 OD2 ASP A 517 5.301 37.154 26.410 1.00 19.89 O
+ATOM 3503 N ASP A 518 5.519 41.420 23.066 1.00 24.53 N
+ATOM 3504 CA ASP A 518 5.095 42.010 21.802 1.00 26.35 C
+ATOM 3505 C ASP A 518 5.552 43.450 21.613 1.00 26.17 C
+ATOM 3506 O ASP A 518 4.895 44.237 20.932 1.00 24.80 O
+ATOM 3507 CB ASP A 518 3.568 41.930 21.674 1.00 26.18 C
+ATOM 3508 CG ASP A 518 3.050 40.493 21.686 1.00 29.09 C
+ATOM 3509 OD1 ASP A 518 3.637 39.649 20.980 1.00 32.40 O
+ATOM 3510 OD2 ASP A 518 2.048 40.214 22.382 1.00 29.76 O
+ATOM 3511 N PHE A 519 6.696 43.779 22.199 1.00 25.04 N
+ATOM 3512 CA PHE A 519 7.242 45.127 22.125 1.00 25.75 C
+ATOM 3513 C PHE A 519 7.462 45.585 20.680 1.00 29.76 C
+ATOM 3514 O PHE A 519 7.297 46.769 20.374 1.00 26.90 O
+ATOM 3515 CB PHE A 519 8.569 45.177 22.888 1.00 24.73 C
+ATOM 3516 CG PHE A 519 9.065 46.567 23.176 1.00 24.90 C
+ATOM 3517 CD1 PHE A 519 8.427 47.365 24.116 1.00 23.67 C
+ATOM 3518 CD2 PHE A 519 10.185 47.068 22.525 1.00 25.57 C
+ATOM 3519 CE1 PHE A 519 8.905 48.640 24.409 1.00 22.79 C
+ATOM 3520 CE2 PHE A 519 10.668 48.343 22.811 1.00 28.42 C
+ATOM 3521 CZ PHE A 519 10.027 49.130 23.756 1.00 24.58 C
+ATOM 3522 N TYR A 520 7.830 44.649 19.804 1.00 30.82 N
+ATOM 3523 CA TYR A 520 8.095 44.959 18.398 1.00 38.37 C
+ATOM 3524 C TYR A 520 7.106 44.464 17.356 1.00 43.79 C
+ATOM 3525 O TYR A 520 6.006 44.019 17.664 1.00 45.21 O
+ATOM 3526 CB TYR A 520 9.471 44.453 17.968 1.00 34.60 C
+ATOM 3527 CG TYR A 520 10.636 45.155 18.606 1.00 35.96 C
+ATOM 3528 CD1 TYR A 520 11.266 44.624 19.726 1.00 33.58 C
+ATOM 3529 CD2 TYR A 520 11.123 46.344 18.074 1.00 32.77 C
+ATOM 3530 CE1 TYR A 520 12.360 45.256 20.298 1.00 30.98 C
+ATOM 3531 CE2 TYR A 520 12.215 46.988 18.636 1.00 34.22 C
+ATOM 3532 CZ TYR A 520 12.832 46.434 19.748 1.00 32.73 C
+ATOM 3533 OH TYR A 520 13.934 47.040 20.297 1.00 31.24 O
+ATOM 3534 N THR A 521 7.556 44.532 16.105 1.00 54.70 N
+ATOM 3535 CA THR A 521 6.763 44.137 14.954 1.00 61.02 C
+ATOM 3536 C THR A 521 5.504 45.009 15.074 1.00 64.35 C
+ATOM 3537 O THR A 521 4.384 44.512 15.056 1.00 64.43 O
+ATOM 3538 CB THR A 521 6.424 42.618 15.001 1.00 63.98 C
+ATOM 3539 OG1 THR A 521 7.420 41.925 15.768 1.00 66.95 O
+ATOM 3540 CG2 THR A 521 6.449 42.023 13.592 1.00 64.24 C
+ATOM 3541 N ALA A 522 5.752 46.314 15.224 1.00 67.71 N
+ATOM 3542 CA ALA A 522 4.758 47.393 15.369 1.00 70.38 C
+ATOM 3543 C ALA A 522 3.268 47.022 15.350 1.00 73.25 C
+ATOM 3544 O ALA A 522 2.718 46.565 16.357 1.00 74.15 O
+ATOM 3545 CB ALA A 522 5.036 48.459 14.316 1.00 70.79 C
+ATOM 3546 N THR A 523 2.609 47.270 14.219 1.00 75.85 N
+ATOM 3547 CA THR A 523 1.194 46.923 14.036 1.00 78.14 C
+ATOM 3548 C THR A 523 1.278 45.394 14.181 1.00 80.27 C
+ATOM 3549 O THR A 523 2.326 44.915 14.585 1.00 82.13 O
+ATOM 3550 CB THR A 523 0.726 47.333 12.612 1.00 78.07 C
+ATOM 3551 OG1 THR A 523 1.116 48.691 12.361 1.00 77.25 O
+ATOM 3552 CG2 THR A 523 -0.790 47.240 12.480 1.00 79.07 C
+ATOM 3553 N GLU A 524 0.222 44.628 13.874 1.00 81.42 N
+ATOM 3554 CA GLU A 524 0.300 43.155 14.007 1.00 82.73 C
+ATOM 3555 C GLU A 524 -0.819 42.499 14.779 1.00 83.66 C
+ATOM 3556 O GLU A 524 -1.396 43.085 15.675 1.00 85.56 O
+ATOM 3557 CB GLU A 524 1.544 42.691 14.759 1.00 82.14 C
+ATOM 3558 CG GLU A 524 1.398 42.843 16.278 1.00 82.43 C
+ATOM 3559 CD GLU A 524 2.516 42.197 17.051 1.00 83.12 C
+ATOM 3560 OE1 GLU A 524 3.618 42.771 17.069 1.00 83.34 O
+ATOM 3561 OE2 GLU A 524 2.298 41.113 17.632 1.00 83.77 O
+ATOM 3562 N SER A 525 -1.018 41.232 14.476 1.00 82.93 N
+ATOM 3563 CA SER A 525 -1.987 40.384 15.139 1.00 81.67 C
+ATOM 3564 C SER A 525 -1.223 39.078 14.900 1.00 80.25 C
+ATOM 3565 O SER A 525 -1.775 38.086 14.428 1.00 80.93 O
+ATOM 3566 CB SER A 525 -3.322 40.418 14.383 1.00 82.54 C
+ATOM 3567 OG SER A 525 -4.448 40.227 15.231 1.00 83.65 O
+ATOM 3568 N GLN A 526 0.079 39.144 15.185 1.00 76.67 N
+ATOM 3569 CA GLN A 526 1.029 38.042 15.039 1.00 72.79 C
+ATOM 3570 C GLN A 526 0.384 36.698 14.751 1.00 70.74 C
+ATOM 3571 O GLN A 526 0.169 35.891 15.646 1.00 72.78 O
+ATOM 3572 CB GLN A 526 1.879 37.950 16.301 1.00 70.94 C
+ATOM 3573 CG GLN A 526 1.030 37.824 17.545 1.00 66.13 C
+ATOM 3574 CD GLN A 526 1.823 37.939 18.823 1.00 65.38 C
+ATOM 3575 OE1 GLN A 526 1.274 37.791 19.914 1.00 64.80 O
+ATOM 3576 NE2 GLN A 526 3.118 38.212 18.702 1.00 64.22 N
+HETATM 3577 N PTR A 527 0.080 36.471 13.486 1.00 67.65 N
+HETATM 3578 CA PTR A 527 -0.539 35.238 13.033 1.00 65.18 C
+HETATM 3579 C PTR A 527 -0.721 35.426 11.552 1.00 66.59 C
+HETATM 3580 O PTR A 527 -1.790 35.835 11.100 1.00 66.62 O
+HETATM 3581 CB PTR A 527 -1.899 35.015 13.707 1.00 60.91 C
+HETATM 3582 CG PTR A 527 -1.857 33.919 14.773 1.00 55.97 C
+HETATM 3583 CD1 PTR A 527 -2.790 33.911 15.849 1.00 55.70 C
+HETATM 3584 CD2 PTR A 527 -0.881 32.884 14.695 1.00 52.68 C
+HETATM 3585 CE1 PTR A 527 -2.710 32.873 16.819 1.00 52.26 C
+HETATM 3586 CE2 PTR A 527 -0.791 31.850 15.648 1.00 47.70 C
+HETATM 3587 CZ PTR A 527 -1.713 31.870 16.700 1.00 48.24 C
+HETATM 3588 OH PTR A 527 -1.590 30.803 17.660 1.00 44.43 O
+HETATM 3589 P PTR A 527 -0.531 30.988 18.896 1.00 41.75 P
+HETATM 3590 O1P PTR A 527 -1.078 31.998 19.812 1.00 40.80 O
+HETATM 3591 O2P PTR A 527 0.778 31.450 18.390 1.00 40.71 O
+HETATM 3592 O3P PTR A 527 -0.365 29.723 19.661 1.00 42.33 O
+ATOM 3593 N GLU A 528 0.351 35.181 10.815 1.00 68.30 N
+ATOM 3594 CA GLU A 528 0.317 35.312 9.367 1.00 70.89 C
+ATOM 3595 C GLU A 528 -0.980 34.660 8.939 1.00 72.96 C
+ATOM 3596 O GLU A 528 -1.293 33.560 9.385 1.00 74.16 O
+ATOM 3597 CB GLU A 528 1.469 34.543 8.718 1.00 69.66 C
+ATOM 3598 CG GLU A 528 2.831 34.803 9.312 1.00 71.00 C
+ATOM 3599 CD GLU A 528 3.227 36.253 9.236 1.00 71.74 C
+ATOM 3600 OE1 GLU A 528 3.322 36.777 8.109 1.00 72.06 O
+ATOM 3601 OE2 GLU A 528 3.442 36.868 10.301 1.00 71.33 O
+ATOM 3602 N GLU A 529 -1.753 35.334 8.103 1.00 75.36 N
+ATOM 3603 CA GLU A 529 -2.987 34.727 7.641 1.00 77.37 C
+ATOM 3604 C GLU A 529 -2.609 34.158 6.273 1.00 77.80 C
+ATOM 3605 O GLU A 529 -1.786 34.751 5.559 1.00 76.93 O
+ATOM 3606 CB GLU A 529 -4.100 35.773 7.524 1.00 78.67 C
+ATOM 3607 CG GLU A 529 -5.469 35.225 7.919 1.00 81.63 C
+ATOM 3608 CD GLU A 529 -5.935 35.703 9.291 1.00 83.95 C
+ATOM 3609 OE1 GLU A 529 -5.173 35.592 10.279 1.00 85.36 O
+ATOM 3610 OE2 GLU A 529 -7.084 36.185 9.377 1.00 85.21 O
+ATOM 3611 N ILE A 530 -3.167 33.004 5.908 1.00 78.47 N
+ATOM 3612 CA ILE A 530 -2.808 32.420 4.619 1.00 78.94 C
+ATOM 3613 C ILE A 530 -3.930 32.437 3.593 1.00 80.35 C
+ATOM 3614 O ILE A 530 -4.985 31.838 3.784 1.00 80.42 O
+ATOM 3615 CB ILE A 530 -2.312 30.937 4.754 1.00 78.26 C
+ATOM 3616 CG1 ILE A 530 -1.420 30.566 3.569 1.00 76.94 C
+ATOM 3617 CG2 ILE A 530 -3.470 29.981 4.813 1.00 77.33 C
+ATOM 3618 CD1 ILE A 530 -0.019 31.082 3.719 1.00 76.11 C
+ATOM 3619 N PRO A 531 -3.715 33.115 2.467 1.00 81.09 N
+ATOM 3620 CA PRO A 531 -2.869 33.964 1.624 1.00 81.63 C
+ATOM 3621 C PRO A 531 -3.550 35.248 1.131 1.00 82.32 C
+ATOM 3622 O PRO A 531 -3.909 35.278 -0.063 1.00 82.96 O
+ATOM 3623 CB PRO A 531 -2.532 33.025 0.449 1.00 80.93 C
+ATOM 3624 CG PRO A 531 -3.181 31.637 0.875 1.00 80.28 C
+ATOM 3625 CD PRO A 531 -4.391 32.182 1.571 1.00 81.00 C
+ATOM 3626 OXT PRO A 531 -3.724 36.207 1.914 1.00 83.32 O
+TER 3627 PRO A 531
+HETATM 3628 N1 PP1 A 532 26.428 31.461 39.668 1.00 16.92 N
+HETATM 3629 C2 PP1 A 532 26.466 28.964 36.863 1.00 15.69 C
+HETATM 3630 N3 PP1 A 532 26.860 30.084 37.584 1.00 14.95 N
+HETATM 3631 C4 PP1 A 532 26.227 30.417 38.776 1.00 19.51 C
+HETATM 3632 C5 PP1 A 532 25.186 29.632 39.257 1.00 18.34 C
+HETATM 3633 C6 PP1 A 532 24.789 28.506 38.521 1.00 18.09 C
+HETATM 3634 N7 PP1 A 532 25.428 28.183 37.336 1.00 16.77 N
+HETATM 3635 N8 PP1 A 532 25.520 31.311 40.699 1.00 19.06 N
+HETATM 3636 C9 PP1 A 532 24.754 30.187 40.454 1.00 16.67 C
+HETATM 3637 N10 PP1 A 532 23.776 27.724 38.945 1.00 15.37 N
+HETATM 3638 C11 PP1 A 532 23.750 29.898 41.485 1.00 16.81 C
+HETATM 3639 C12 PP1 A 532 23.784 28.645 42.127 1.00 17.35 C
+HETATM 3640 C13 PP1 A 532 22.852 28.331 43.124 1.00 19.29 C
+HETATM 3641 C14 PP1 A 532 21.875 29.265 43.494 1.00 18.96 C
+HETATM 3642 C15 PP1 A 532 21.827 30.527 42.857 1.00 17.02 C
+HETATM 3643 C16 PP1 A 532 22.769 30.846 41.847 1.00 15.16 C
+HETATM 3644 C24 PP1 A 532 20.882 28.910 44.572 1.00 16.99 C
+HETATM 3645 C28 PP1 A 532 27.365 32.599 39.461 1.00 22.83 C
+HETATM 3646 C29 PP1 A 532 27.189 33.701 40.509 1.00 25.14 C
+HETATM 3647 C33 PP1 A 532 27.183 33.293 38.111 1.00 24.71 C
+HETATM 3648 C37 PP1 A 532 28.837 32.170 39.535 1.00 27.58 C
+HETATM 3649 O HOH A 533 8.538 6.785 20.622 1.00 39.10 O
+HETATM 3650 O HOH A 534 20.508 13.121 40.419 1.00 18.50 O
+HETATM 3651 O HOH A 535 2.133 12.250 37.545 1.00 45.12 O
+HETATM 3652 O HOH A 536 7.164 27.373 26.428 1.00 21.01 O
+HETATM 3653 O HOH A 537 3.610 35.361 12.519 1.00 28.62 O
+HETATM 3654 O HOH A 538 17.195 31.681 20.260 1.00 28.18 O
+HETATM 3655 O HOH A 539 9.799 39.319 2.337 1.00 38.02 O
+HETATM 3656 O HOH A 540 -3.822 14.608 12.815 1.00 28.95 O
+HETATM 3657 O HOH A 541 20.669 13.477 37.895 1.00 18.36 O
+HETATM 3658 O HOH A 542 26.903 8.837 51.932 1.00 23.15 O
+HETATM 3659 O HOH A 543 26.378 10.051 49.506 1.00 21.15 O
+HETATM 3660 O HOH A 544 30.668 13.118 42.446 1.00 19.59 O
+HETATM 3661 O HOH A 545 32.135 28.148 33.924 1.00 32.09 O
+HETATM 3662 O HOH A 546 7.455 25.098 52.971 1.00 28.40 O
+HETATM 3663 O HOH A 547 14.631 21.477 53.253 1.00 40.49 O
+HETATM 3664 O HOH A 548 11.220 33.940 50.906 1.00 18.11 O
+HETATM 3665 O HOH A 549 9.679 35.187 49.107 1.00 13.63 O
+HETATM 3666 O HOH A 550 12.978 23.656 41.467 1.00 19.13 O
+HETATM 3667 O HOH A 551 13.403 21.065 39.767 1.00 31.10 O
+HETATM 3668 O HOH A 552 13.137 20.226 42.769 1.00 36.77 O
+HETATM 3669 O HOH A 553 5.867 24.478 38.739 1.00 15.41 O
+HETATM 3670 O HOH A 554 12.686 25.631 37.215 1.00 14.46 O
+HETATM 3671 O HOH A 555 9.598 23.668 34.183 1.00 32.36 O
+HETATM 3672 O HOH A 556 15.329 25.647 29.196 1.00 27.97 O
+HETATM 3673 O HOH A 557 8.055 26.908 31.369 1.00 30.64 O
+HETATM 3674 O HOH A 558 15.265 18.981 40.138 1.00 21.83 O
+HETATM 3675 O HOH A 559 2.565 33.132 34.297 1.00 26.31 O
+HETATM 3676 O HOH A 560 0.680 35.457 34.317 1.00 26.09 O
+HETATM 3677 O HOH A 561 4.783 33.670 32.644 1.00 27.71 O
+HETATM 3678 O HOH A 562 2.981 39.407 47.063 1.00 12.85 O
+HETATM 3679 O HOH A 563 28.036 27.530 26.347 1.00 32.09 O
+HETATM 3680 O HOH A 564 5.595 45.931 48.723 1.00 15.38 O
+HETATM 3681 O HOH A 565 10.848 42.521 46.656 1.00 13.86 O
+HETATM 3682 O HOH A 566 11.959 56.210 51.149 1.00 30.46 O
+HETATM 3683 O HOH A 567 2.652 56.245 42.937 1.00 36.04 O
+HETATM 3684 O HOH A 568 -2.637 47.161 41.999 1.00 24.95 O
+HETATM 3685 O HOH A 569 -1.933 46.031 44.244 1.00 23.10 O
+HETATM 3686 O HOH A 570 0.108 47.071 46.158 1.00 33.24 O
+HETATM 3687 O HOH A 571 -1.003 43.270 44.358 1.00 28.25 O
+HETATM 3688 O HOH A 572 1.008 43.132 45.997 1.00 28.96 O
+HETATM 3689 O HOH A 573 -0.815 45.913 35.424 1.00 21.50 O
+HETATM 3690 O HOH A 574 -2.409 46.586 37.542 1.00 26.75 O
+HETATM 3691 O HOH A 575 1.618 42.653 40.550 1.00 15.14 O
+HETATM 3692 O HOH A 576 -0.543 41.646 42.136 1.00 27.59 O
+HETATM 3693 O HOH A 577 -2.388 41.835 35.140 1.00 33.54 O
+HETATM 3694 O HOH A 578 12.445 42.135 21.189 1.00 28.92 O
+HETATM 3695 O HOH A 579 -2.628 31.464 9.998 1.00 49.57 O
+HETATM 3696 O HOH A 580 -3.562 51.223 39.974 1.00 43.26 O
+HETATM 3697 O HOH A 581 -5.692 23.044 14.793 1.00 36.96 O
+HETATM 3698 O HOH A 582 24.713 33.372 42.779 1.00 13.92 O
+HETATM 3699 O HOH A 583 22.627 8.922 42.811 1.00 33.50 O
+HETATM 3700 O HOH A 584 15.355 25.604 34.286 1.00 16.83 O
+HETATM 3701 O HOH A 585 8.745 29.415 29.287 1.00 24.76 O
+HETATM 3702 O HOH A 586 5.660 34.155 26.053 1.00 25.20 O
+HETATM 3703 O HOH A 587 15.667 52.027 46.369 1.00 24.43 O
+HETATM 3704 O HOH A 588 3.397 37.125 45.563 1.00 9.67 O
+HETATM 3705 O HOH A 589 24.594 46.480 37.707 1.00 20.24 O
+HETATM 3706 O HOH A 590 16.619 41.647 49.954 1.00 22.16 O
+HETATM 3707 O HOH A 591 -1.320 35.517 42.237 1.00 24.67 O
+HETATM 3708 O HOH A 592 1.668 37.402 43.531 1.00 15.49 O
+HETATM 3709 O HOH A 593 17.707 43.297 44.274 1.00 25.88 O
+HETATM 3710 O HOH A 594 15.604 52.058 43.372 1.00 17.35 O
+HETATM 3711 O HOH A 595 13.576 23.828 33.304 1.00 24.36 O
+HETATM 3712 O HOH A 596 13.402 42.111 44.341 1.00 14.72 O
+HETATM 3713 O HOH A 597 25.537 27.625 56.453 1.00 15.39 O
+HETATM 3714 O HOH A 598 21.081 25.340 26.683 1.00 29.13 O
+HETATM 3715 O HOH A 599 18.507 26.717 28.023 1.00 26.28 O
+HETATM 3716 O HOH A 600 15.233 44.228 45.753 1.00 22.02 O
+HETATM 3717 O HOH A 601 30.382 14.477 54.424 1.00 13.46 O
+HETATM 3718 O HOH A 602 -1.917 32.631 47.501 1.00 17.89 O
+HETATM 3719 O HOH A 603 16.412 36.624 47.382 1.00 15.80 O
+HETATM 3720 O HOH A 604 10.572 57.082 47.743 1.00 27.85 O
+HETATM 3721 O HOH A 605 4.242 33.024 24.052 1.00 24.09 O
+HETATM 3722 O HOH A 606 32.177 19.908 50.320 1.00 30.81 O
+HETATM 3723 O HOH A 607 25.821 24.130 63.208 1.00 33.87 O
+HETATM 3724 O HOH A 608 -0.384 39.362 43.833 1.00 19.16 O
+HETATM 3725 O HOH A 609 21.616 17.000 54.048 1.00 16.19 O
+HETATM 3726 O HOH A 610 1.213 36.688 36.689 1.00 12.15 O
+HETATM 3727 O HOH A 611 17.229 24.335 31.963 1.00 22.11 O
+HETATM 3728 O HOH A 612 17.107 33.368 24.123 1.00 26.67 O
+HETATM 3729 O HOH A 613 22.907 42.964 39.537 1.00 18.23 O
+HETATM 3730 O HOH A 614 33.701 18.019 47.667 1.00 22.44 O
+HETATM 3731 O HOH A 615 31.380 17.671 49.569 1.00 25.24 O
+HETATM 3732 O HOH A 616 11.899 23.525 35.715 1.00 21.98 O
+HETATM 3733 O HOH A 617 8.828 35.663 27.039 1.00 23.23 O
+HETATM 3734 O HOH A 618 0.602 40.204 46.308 1.00 27.66 O
+HETATM 3735 O HOH A 619 31.776 27.801 54.194 1.00 43.62 O
+HETATM 3736 O HOH A 620 -1.869 45.484 40.096 1.00 21.04 O
+HETATM 3737 O HOH A 621 12.977 25.999 39.801 1.00 14.56 O
+HETATM 3738 O HOH A 622 7.329 35.033 50.247 1.00 11.88 O
+HETATM 3739 O HOH A 623 12.036 45.546 46.139 1.00 17.98 O
+HETATM 3740 O HOH A 624 16.026 30.409 45.404 1.00 17.74 O
+HETATM 3741 O HOH A 625 10.145 41.343 22.267 1.00 33.16 O
+HETATM 3742 O HOH A 626 12.895 39.404 53.100 1.00 23.25 O
+HETATM 3743 O HOH A 627 17.585 29.784 43.307 1.00 26.56 O
+HETATM 3744 O HOH A 628 25.093 43.462 41.252 1.00 20.06 O
+HETATM 3745 O HOH A 629 13.283 43.415 47.010 1.00 32.27 O
+HETATM 3746 O HOH A 630 15.201 40.978 52.357 1.00 23.06 O
+HETATM 3747 O HOH A 631 21.153 40.845 48.452 1.00 34.61 O
+HETATM 3748 O HOH A 632 -1.323 39.103 37.705 1.00 25.81 O
+HETATM 3749 O HOH A 633 10.671 38.750 21.925 1.00 37.57 O
+HETATM 3750 O HOH A 634 7.741 33.012 52.174 1.00 20.89 O
+HETATM 3751 O HOH A 635 14.082 13.397 49.707 1.00 35.42 O
+HETATM 3752 O HOH A 636 5.807 22.276 41.683 1.00 26.93 O
+HETATM 3753 O HOH A 637 4.798 31.059 31.573 1.00 25.23 O
+HETATM 3754 O HOH A 638 4.429 52.010 29.571 1.00 42.43 O
+HETATM 3755 O HOH A 639 24.002 9.672 48.364 1.00 27.06 O
+HETATM 3756 O HOH A 640 15.004 61.143 31.528 1.00 33.22 O
+HETATM 3757 O HOH A 641 4.827 44.981 56.140 1.00 31.53 O
+HETATM 3758 O HOH A 642 13.335 56.332 48.810 1.00 27.49 O
+HETATM 3759 O HOH A 643 18.947 24.871 30.066 1.00 25.42 O
+HETATM 3760 O HOH A 644 -3.548 22.339 21.403 1.00 38.66 O
+HETATM 3761 O HOH A 645 21.998 50.447 35.178 1.00 25.96 O
+HETATM 3762 O HOH A 646 15.157 55.429 39.317 1.00 24.42 O
+HETATM 3763 O HOH A 647 -2.529 34.018 45.595 1.00 35.06 O
+HETATM 3764 O HOH A 648 22.093 11.286 47.780 1.00 26.18 O
+HETATM 3765 O HOH A 649 26.801 28.926 62.954 1.00 31.43 O
+HETATM 3766 O HOH A 650 22.581 49.509 46.504 1.00 27.21 O
+HETATM 3767 O HOH A 651 17.913 44.066 62.407 1.00 40.66 O
+HETATM 3768 O HOH A 652 23.454 21.101 35.626 1.00 33.39 O
+HETATM 3769 O HOH A 653 15.783 22.248 12.294 1.00 34.00 O
+HETATM 3770 O HOH A 654 17.460 31.013 23.014 1.00 26.56 O
+HETATM 3771 O HOH A 655 -8.044 20.579 -0.110 1.00 35.01 O
+HETATM 3772 O HOH A 656 28.060 9.122 47.947 1.00 24.96 O
+HETATM 3773 O HOH A 657 26.576 47.333 42.162 1.00 31.02 O
+HETATM 3774 O HOH A 658 12.073 60.860 34.675 1.00 31.52 O
+HETATM 3775 O HOH A 659 6.528 0.992 20.098 1.00 36.25 O
+HETATM 3776 O HOH A 660 19.122 36.834 47.411 1.00 21.29 O
+HETATM 3777 O HOH A 661 6.846 19.834 42.404 1.00 32.91 O
+HETATM 3778 O HOH A 662 20.313 31.022 20.399 1.00 57.06 O
+HETATM 3779 O HOH A 663 28.861 50.781 36.179 1.00 34.96 O
+HETATM 3780 O HOH A 664 14.655 17.258 38.096 1.00 20.21 O
+HETATM 3781 O HOH A 665 8.599 24.824 26.837 1.00 33.63 O
+HETATM 3782 O HOH A 666 13.342 36.808 1.406 1.00 39.19 O
+HETATM 3783 O HOH A 667 19.557 50.397 36.953 1.00 28.09 O
+HETATM 3784 O HOH A 668 24.341 22.467 61.358 1.00 25.34 O
+HETATM 3785 O HOH A 669 8.486 20.269 44.415 1.00 32.07 O
+HETATM 3786 O HOH A 670 -4.130 24.596 23.007 1.00 31.44 O
+HETATM 3787 O HOH A 671 4.087 49.247 53.736 1.00 34.04 O
+HETATM 3788 O HOH A 672 1.110 45.223 47.580 1.00 34.50 O
+HETATM 3789 O HOH A 673 19.758 11.043 49.038 1.00 29.26 O
+HETATM 3790 O HOH A 674 -4.197 24.641 4.660 1.00 36.31 O
+HETATM 3791 O HOH A 675 5.119 27.093 28.220 1.00 43.37 O
+HETATM 3792 O HOH A 676 31.128 32.385 36.222 1.00 31.45 O
+HETATM 3793 O HOH A 677 1.160 38.035 30.077 1.00 24.74 O
+HETATM 3794 O HOH A 678 -1.498 49.011 38.880 1.00 33.11 O
+HETATM 3795 O HOH A 679 16.018 12.909 55.048 1.00 46.02 O
+HETATM 3796 O HOH A 680 3.662 29.113 32.921 1.00 32.81 O
+HETATM 3797 O HOH A 681 17.268 26.958 24.113 1.00 28.83 O
+HETATM 3798 O HOH A 682 13.572 29.321 62.311 1.00 35.65 O
+HETATM 3799 O HOH A 683 23.904 58.996 39.091 1.00 25.06 O
+HETATM 3800 O HOH A 684 32.908 13.054 41.220 1.00 19.88 O
+HETATM 3801 O HOH A 685 3.012 46.706 49.668 1.00 25.61 O
+HETATM 3802 O HOH A 686 -1.644 0.571 34.683 1.00 26.02 O
+HETATM 3803 O HOH A 687 -1.056 48.307 33.534 1.00 30.78 O
+HETATM 3804 O HOH A 688 2.586 50.441 30.391 1.00 29.98 O
+HETATM 3805 O HOH A 689 3.733 49.895 25.854 1.00 27.71 O
+HETATM 3806 O HOH A 690 26.171 45.583 39.967 1.00 35.88 O
+HETATM 3807 O HOH A 691 19.124 21.337 33.925 1.00 39.28 O
+HETATM 3808 O HOH A 692 25.572 43.357 56.592 1.00 36.91 O
+HETATM 3809 O HOH A 693 5.315 51.733 27.091 1.00 31.86 O
+HETATM 3810 O HOH A 694 27.152 41.691 41.744 1.00 30.42 O
+HETATM 3811 O HOH A 695 1.961 36.086 31.859 1.00 33.10 O
+HETATM 3812 O HOH A 696 18.436 42.411 11.307 1.00 41.81 O
+HETATM 3813 O HOH A 697 32.199 44.371 26.404 1.00 40.93 O
+HETATM 3814 O HOH A 698 20.431 37.088 49.544 1.00 33.71 O
+HETATM 3815 O HOH A 699 8.847 46.028 3.578 1.00 32.97 O
+HETATM 3816 O HOH A 700 12.944 28.805 24.638 1.00 38.37 O
+HETATM 3817 O HOH A 701 5.908 57.891 42.240 1.00 26.17 O
+HETATM 3818 O HOH A 702 6.647 23.097 51.450 1.00 35.27 O
+HETATM 3819 O HOH A 703 5.598 56.222 21.969 1.00 36.08 O
+HETATM 3820 O HOH A 704 10.353 13.398 34.474 1.00 33.56 O
+HETATM 3821 O HOH A 705 14.521 53.787 48.819 1.00 29.29 O
+HETATM 3822 O HOH A 706 -14.407 0.072 32.859 1.00 42.00 O
+HETATM 3823 O HOH A 707 14.790 16.948 44.236 1.00 31.76 O
+HETATM 3824 O HOH A 708 15.592 28.915 23.232 1.00 36.49 O
+HETATM 3825 O HOH A 709 7.140 38.375 54.236 1.00 35.85 O
+HETATM 3826 O HOH A 710 26.052 15.950 33.920 1.00 39.31 O
+HETATM 3827 O HOH A 711 14.276 14.128 44.555 1.00 40.73 O
+HETATM 3828 O HOH A 712 7.367 54.628 50.764 1.00 34.29 O
+HETATM 3829 O HOH A 713 0.616 58.938 41.965 1.00 39.15 O
+HETATM 3830 O HOH A 714 21.861 36.431 20.411 1.00 43.46 O
+HETATM 3831 O HOH A 715 -3.368 2.240 28.249 1.00 40.81 O
+HETATM 3832 O HOH A 716 23.917 40.346 62.520 1.00 43.52 O
+HETATM 3833 O HOH A 717 -3.112 44.585 33.954 1.00 35.89 O
+HETATM 3834 O HOH A 718 25.491 44.722 44.317 1.00 45.77 O
+HETATM 3835 O HOH A 719 24.278 45.080 54.544 1.00 42.84 O
+HETATM 3836 O HOH A 720 15.697 62.632 36.182 1.00 42.62 O
+HETATM 3837 O HOH A 721 15.432 42.651 54.676 1.00 33.95 O
+HETATM 3838 O HOH A 722 36.705 17.642 47.363 1.00 39.51 O
+HETATM 3839 O HOH A 723 14.375 62.256 33.752 1.00 33.89 O
+HETATM 3840 O HOH A 724 25.850 35.626 21.216 1.00 45.67 O
+HETATM 3841 O HOH A 725 12.135 59.827 27.536 1.00 41.89 O
+HETATM 3842 O HOH A 726 13.913 62.894 38.162 1.00 42.93 O
+HETATM 3843 O HOH A 727 7.803 18.625 51.210 1.00 34.42 O
+HETATM 3844 O HOH A 728 20.229 12.147 52.899 1.00 40.53 O
+HETATM 3845 O HOH A 729 6.177 21.540 38.552 1.00 41.02 O
+HETATM 3846 O HOH A 730 26.640 34.612 44.166 1.00 38.11 O
+HETATM 3847 O HOH A 731 18.674 51.686 54.639 1.00 38.60 O
+HETATM 3848 O HOH A 732 17.034 24.579 18.637 1.00 34.00 O
+HETATM 3849 O HOH A 733 5.299 55.660 32.246 1.00 27.21 O
+HETATM 3850 O HOH A 734 10.769 36.306 14.942 1.00 44.40 O
+HETATM 3851 O HOH A 735 13.424 39.512 55.608 1.00 42.03 O
+HETATM 3852 O HOH A 736 -5.045 15.220 15.336 1.00 51.90 O
+HETATM 3853 O HOH A 737 28.618 7.391 43.699 1.00 43.86 O
+HETATM 3854 O HOH A 738 2.076 3.100 47.155 1.00 38.22 O
+HETATM 3855 O HOH A 739 13.620 27.240 26.596 1.00 33.48 O
+HETATM 3856 O HOH A 740 23.032 13.187 34.129 1.00 44.64 O
+HETATM 3857 O HOH A 741 -2.384 40.368 39.677 1.00 41.85 O
+HETATM 3858 O HOH A 742 4.504 53.148 50.224 1.00 42.20 O
+HETATM 3859 O HOH A 743 10.048 61.312 32.810 1.00 37.44 O
+HETATM 3860 O HOH A 744 -6.247 5.942 34.270 1.00 49.98 O
+HETATM 3861 O HOH A 745 34.513 39.617 27.581 1.00 43.68 O
+HETATM 3862 O HOH A 746 30.892 31.605 29.285 1.00 52.12 O
+HETATM 3863 O HOH A 747 22.996 50.959 52.839 1.00 43.52 O
+HETATM 3864 O HOH A 748 -6.210 15.144 3.020 1.00 44.30 O
+HETATM 3865 O HOH A 749 7.737 32.127 26.532 1.00 43.55 O
+HETATM 3866 O HOH A 750 34.090 48.369 34.333 1.00 47.77 O
+HETATM 3867 O HOH A 751 23.093 34.772 48.707 1.00 34.63 O
+HETATM 3868 O HOH A 752 29.324 13.566 35.101 1.00 56.81 O
+HETATM 3869 O HOH A 753 2.781 10.569 11.433 1.00 31.41 O
+HETATM 3870 O HOH A 754 39.058 32.283 46.442 1.00 42.07 O
+HETATM 3871 O HOH A 755 27.393 38.611 38.510 1.00 41.75 O
+HETATM 3872 O HOH A 756 23.776 12.520 55.591 1.00 31.10 O
+HETATM 3873 O HOH A 757 23.261 36.351 57.952 1.00 53.24 O
+HETATM 3874 O HOH A 758 9.280 56.903 49.923 1.00 39.62 O
+HETATM 3875 O HOH A 759 6.542 17.218 21.802 1.00 38.78 O
+HETATM 3876 O HOH A 760 -1.313 17.242 28.604 1.00 53.99 O
+HETATM 3877 O HOH A 761 3.056 33.145 29.301 1.00 43.60 O
+HETATM 3878 O HOH A 762 37.316 12.396 42.666 1.00 39.00 O
+HETATM 3879 O HOH A 763 -0.942 13.086 12.056 1.00 37.42 O
+HETATM 3880 O HOH A 764 20.476 17.550 35.339 1.00 27.16 O
+HETATM 3881 O HOH A 765 -8.132 17.961 16.818 1.00 37.13 O
+HETATM 3882 O HOH A 766 17.662 37.958 12.839 1.00 56.12 O
+HETATM 3883 O HOH A 767 8.893 15.841 9.655 1.00 35.94 O
+HETATM 3884 O HOH A 768 16.937 8.720 21.935 1.00 46.32 O
+HETATM 3885 O HOH A 769 14.629 44.554 61.958 1.00 57.08 O
+HETATM 3886 O HOH A 770 20.260 42.727 5.436 1.00 41.70 O
+HETATM 3887 O HOH A 771 -4.475 1.425 36.545 1.00 51.90 O
+HETATM 3888 O HOH A 772 12.017 15.392 34.354 1.00 54.18 O
+HETATM 3889 O HOH A 773 -4.889 33.583 37.222 1.00 52.47 O
+HETATM 3890 O HOH A 774 29.208 30.315 36.175 1.00 27.43 O
+HETATM 3891 O HOH A 775 10.291 42.109 56.286 1.00 30.42 O
+HETATM 3892 O HOH A 776 24.485 48.493 49.776 1.00 52.97 O
+HETATM 3893 O HOH A 777 16.725 15.091 20.214 1.00 55.30 O
+HETATM 3894 O HOH A 778 7.089 58.361 39.843 1.00 38.04 O
+HETATM 3895 O HOH A 779 2.068 52.703 36.797 1.00 42.49 O
+HETATM 3896 O HOH A 780 3.174 49.501 50.677 1.00 45.70 O
+HETATM 3897 O HOH A 781 16.826 18.566 58.409 1.00 48.87 O
+HETATM 3898 O HOH A 782 11.906 41.088 18.503 1.00 34.98 O
+HETATM 3899 O HOH A 783 23.055 36.354 44.925 1.00 31.75 O
+HETATM 3900 O HOH A 784 14.297 24.750 2.159 1.00 42.76 O
+HETATM 3901 O HOH A 785 -11.182 24.647 3.892 1.00 52.94 O
+HETATM 3902 O HOH A 786 -15.434 16.221 14.663 1.00 51.70 O
+HETATM 3903 O HOH A 787 -10.669 26.264 23.480 1.00 46.53 O
+HETATM 3904 O HOH A 788 4.918 54.258 25.759 1.00 41.26 O
+HETATM 3905 O HOH A 789 20.700 32.042 9.279 1.00 44.20 O
+HETATM 3906 O HOH A 790 27.514 34.516 58.919 1.00 41.59 O
+HETATM 3907 O HOH A 791 22.478 24.660 24.422 1.00 34.19 O
+HETATM 3908 O HOH A 792 21.233 8.200 46.441 1.00 36.05 O
+HETATM 3909 O HOH A 793 35.913 32.234 40.913 1.00 39.06 O
+HETATM 3910 O HOH A 794 22.938 34.662 41.850 1.00 41.92 O
+HETATM 3911 O HOH A 795 5.765 25.584 34.918 1.00 41.27 O
+HETATM 3912 O HOH A 796 18.162 63.440 35.454 1.00 34.17 O
+HETATM 3913 O HOH A 797 6.615 14.881 25.048 1.00 44.10 O
+HETATM 3914 O HOH A 798 28.285 15.969 32.625 1.00 55.38 O
+HETATM 3915 O HOH A 799 -3.305 5.072 22.803 1.00 43.26 O
+HETATM 3916 O HOH A 800 9.542 21.690 27.424 1.00 53.30 O
+HETATM 3917 O HOH A 801 11.403 -1.770 28.423 1.00 50.42 O
+HETATM 3918 O HOH A 802 9.665 38.895 55.851 1.00 38.71 O
+HETATM 3919 O HOH A 803 3.121 -2.282 19.447 1.00 56.50 O
+HETATM 3920 O HOH A 804 11.943 5.541 45.649 1.00 60.37 O
+HETATM 3921 O HOH A 805 0.520 38.070 25.139 1.00 40.62 O
+HETATM 3922 O HOH A 806 16.120 34.272 20.016 1.00 34.95 O
+HETATM 3923 O HOH A 807 -7.210 40.419 41.636 1.00 49.81 O
+HETATM 3924 O HOH A 808 2.956 59.236 40.694 1.00 53.41 O
+HETATM 3925 O HOH A 809 24.019 50.079 58.629 1.00 42.95 O
+HETATM 3926 O HOH A 810 8.467 24.971 29.756 1.00 30.24 O
+HETATM 3927 O HOH A 811 8.901 41.258 4.699 1.00 43.21 O
+HETATM 3928 O HOH A 812 16.546 17.538 16.820 1.00 47.55 O
+HETATM 3929 O HOH A 813 9.399 40.813 17.522 1.00 31.20 O
+HETATM 3930 O HOH A 814 37.472 20.920 36.812 1.00 44.24 O
+HETATM 3931 O HOH A 815 19.514 20.018 59.682 1.00 48.20 O
+HETATM 3932 O HOH A 816 12.416 24.140 31.040 1.00 21.99 O
+HETATM 3933 O HOH A 817 28.984 47.254 30.890 1.00 53.94 O
+HETATM 3934 O HOH A 818 26.261 21.049 32.479 1.00 40.15 O
+HETATM 3935 O HOH A 819 -1.160 4.529 38.052 1.00 52.63 O
+HETATM 3936 O HOH A 820 32.486 30.153 55.780 1.00 38.79 O
+HETATM 3937 O HOH A 821 6.621 7.205 45.903 1.00 40.63 O
+HETATM 3938 O HOH A 822 12.003 32.739 0.191 1.00 47.05 O
+HETATM 3939 O HOH A 823 29.652 9.414 34.130 1.00 55.26 O
+HETATM 3940 O HOH A 824 1.953 37.545 27.203 1.00 50.72 O
+HETATM 3941 O HOH A 825 -3.539 36.988 36.532 1.00 44.59 O
+HETATM 3942 O HOH A 826 37.282 12.429 45.414 1.00 39.36 O
+HETATM 3943 O HOH A 827 -7.366 40.298 7.981 1.00 49.91 O
+HETATM 3944 O HOH A 828 10.889 19.164 43.282 1.00 35.29 O
+HETATM 3945 O HOH A 829 8.996 32.523 -0.083 1.00 49.87 O
+HETATM 3946 O HOH A 830 28.258 42.343 58.771 1.00 45.18 O
+HETATM 3947 O HOH A 831 30.350 33.296 20.403 1.00 63.69 O
+HETATM 3948 O HOH A 832 3.755 14.001 36.126 1.00 63.63 O
+HETATM 3949 O HOH A 833 4.928 15.828 -5.356 1.00 46.39 O
+HETATM 3950 O HOH A 834 7.494 -4.251 24.019 1.00 50.04 O
+HETATM 3951 O HOH A 835 19.318 21.643 20.211 1.00 42.29 O
+HETATM 3952 O HOH A 836 8.136 20.658 35.398 1.00 50.22 O
+HETATM 3953 O HOH A 837 -5.620 49.525 47.259 1.00 64.36 O
+HETATM 3954 O HOH A 838 12.458 61.822 25.714 1.00 51.75 O
+HETATM 3955 O HOH A 839 -1.517 39.009 26.597 1.00 43.83 O
+HETATM 3956 O HOH A 840 -2.836 9.430 6.110 1.00 34.54 O
+HETATM 3957 O HOH A 841 0.539 20.288 -4.532 1.00 39.94 O
+HETATM 3958 O HOH A 842 30.924 18.835 36.853 1.00 47.22 O
+HETATM 3959 O HOH A 843 30.580 48.798 37.028 1.00 52.91 O
+HETATM 3960 O HOH A 844 -5.173 37.188 33.420 1.00 64.07 O
+CONECT 3570 3577
+CONECT 3577 3570 3578
+CONECT 3578 3577 3579 3581
+CONECT 3579 3578 3580 3593
+CONECT 3580 3579
+CONECT 3581 3578 3582
+CONECT 3582 3581 3583 3584
+CONECT 3583 3582 3585
+CONECT 3584 3582 3586
+CONECT 3585 3583 3587
+CONECT 3586 3584 3587
+CONECT 3587 3585 3586 3588
+CONECT 3588 3587 3589
+CONECT 3589 3588 3590 3591 3592
+CONECT 3590 3589
+CONECT 3591 3589
+CONECT 3592 3589
+CONECT 3593 3579
+CONECT 3628 3631 3635 3645
+CONECT 3629 3630 3634
+CONECT 3630 3629 3631
+CONECT 3631 3628 3630 3632
+CONECT 3632 3631 3633 3636
+CONECT 3633 3632 3634 3637
+CONECT 3634 3629 3633
+CONECT 3635 3628 3636
+CONECT 3636 3632 3635 3638
+CONECT 3637 3633
+CONECT 3638 3636 3639 3643
+CONECT 3639 3638 3640
+CONECT 3640 3639 3641
+CONECT 3641 3640 3642 3644
+CONECT 3642 3641 3643
+CONECT 3643 3638 3642
+CONECT 3644 3641
+CONECT 3645 3628 3646 3647 3648
+CONECT 3646 3645
+CONECT 3647 3645
+CONECT 3648 3645
+MASTER 319 0 2 18 17 0 3 6 3959 1 39 35
+END
*/
package jalview.ext.jmol;
-import static org.junit.Assert.*;
-
-import java.util.Vector;
-
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.FileLoader;
+
+import java.util.Vector;
import org.junit.Test;
+import MCview.PDBfile;
+
/**
* @author jimp
*
*/
public class PDBFileWithJmolTest
{
+ String[] testFile = new String[]
+ { "./examples/1GAQ.txt", "./test/jalview/ext/jmol/1QCF.pdb" }; // ,
+
+ // "./examples/DNMT1_MOUSE.pdb"
+ // };
@Test
- public void test() throws Exception
+ public void testAlignmentLoader() throws Exception
{
- PDBFileWithJmol jtest = new PDBFileWithJmol("./examples/1GAQ.txt",
- jalview.io.AppletFormatAdapter.FILE);
- Vector<SequenceI> seqs = jtest.getSeqs();
+ for (String f : testFile)
+ {
+ FileLoader fl = new jalview.io.FileLoader(false);
+ AlignFrame af = fl
+ .LoadFileWaitTillLoaded(f, AppletFormatAdapter.FILE);
+ validateSecStrRows(af.getViewport().getAlignment());
+ }
+ }
- assertTrue(
- "No sequences extracted from testfile\n"
- + (jtest.hasWarningMessage() ? jtest.getWarningMessage()
- : "(No warnings raised)"),
- seqs != null && seqs.size() > 0);
- for (SequenceI sq : seqs)
+ @Test
+ public void testFileParser() throws Exception
+ {
+ for (String pdbStr : testFile)
{
- AlignmentI al = new Alignment(new SequenceI[]
- { sq });
- if (!al.isNucleotide())
+ PDBfile mctest = new PDBfile(false, false, pdbStr,
+ AppletFormatAdapter.FILE);
+ PDBFileWithJmol jtest = new PDBFileWithJmol(pdbStr,
+ jalview.io.AppletFormatAdapter.FILE);
+ Vector<SequenceI> seqs = jtest.getSeqs(), mcseqs = mctest.getSeqs();
+
+ assertTrue(
+ "No sequences extracted from testfile\n"
+ + (jtest.hasWarningMessage() ? jtest.getWarningMessage()
+ : "(No warnings raised)"), seqs != null
+ && seqs.size() > 0);
+ for (SequenceI sq : seqs)
+ {
+ assertEquals("JMol didn't process " + pdbStr
+ + " to the same sequence as MCView",
+ sq.getSequenceAsString(), mcseqs.remove(0)
+ .getSequenceAsString());
+ AlignmentI al = new Alignment(new SequenceI[]
+ { sq });
+ validateSecStrRows(al);
+ }
+ }
+ }
+
+
+ private void validateSecStrRows(AlignmentI al)
+ {
+ if (!al.isNucleotide())
+ {
+ for (SequenceI asq : al.getSequences())
{
- assertTrue(
- "No secondary structure assigned for protein sequence.",
- sq.getAnnotation() != null
- && sq.getAnnotation().length >= 1
- && sq.getAnnotation()[0].hasIcons);
+ SequenceI sq = asq;
+ boolean hasDs = false;
+ while (sq.getDatasetSequence() != null
+ && sq.getAnnotation() == null)
+ {
+ sq = sq.getDatasetSequence();
+ hasDs = true;
+ }
+ checkFirstAAIsAssoc(sq);
+ if (hasDs)
+ {
+ // also verify if alignment sequence has annotation on it
+ // that is correctly mapped
+ checkFirstAAIsAssoc(asq);
+ }
}
}
}
+ private void checkFirstAAIsAssoc(SequenceI sq)
+ {
+ assertTrue("No secondary structure assigned for protein sequence.",
+ sq.getAnnotation() != null && sq.getAnnotation().length >= 1
+ && sq.getAnnotation()[0].hasIcons);
+ assertTrue(
+ "Secondary structure not associated for sequence "
+ + sq.getName(), sq.getAnnotation()[0].sequenceRef == sq);
+ }
}
@Test
public void testPDBfileVsRNAML() throws Exception
{
- PDBfile pdbf = new PDBfile("examples/2GIS.pdb", FormatAdapter.FILE);
+ PDBfile pdbf = new PDBfile(true,true,"examples/2GIS.pdb", FormatAdapter.FILE);
Assert.assertTrue(pdbf.isValid());
// Comment - should add new FileParse constructor like new FileParse(Reader
// ..). for direct reading
--- /dev/null
+package jalview.ext.rbvi.chimera;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses(
+{})
+public class AllTests
+{
+
+}
--- /dev/null
+package jalview.ext.rbvi.chimera;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Test;
+
+import ext.edu.ucsf.rbvi.strucviz2.*;
+
+public class ChimeraConnect
+{
+
+ @Test
+ public void test()
+ {
+ StructureManager csm;
+ ext.edu.ucsf.rbvi.strucviz2.ChimeraManager cm = new ChimeraManager(csm = new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true));
+ assertTrue("Couldn't launch chimera",cm.launchChimera(csm.getChimeraPaths()));
+ int n=0;
+ while (n++<100)
+ {
+ try {
+ Thread.sleep(1000);
+ } catch (Exception q)
+ {
+
+ }
+ Collection<ChimeraModel> cms = cm.getChimeraModels();
+ for (ChimeraModel cmod :cms) {
+ System.out.println(cmod.getModelName());
+ }
+ }
+ cm.exitChimera();
+ }
+
+}
--- /dev/null
+package jalview.ext.rbvi.chimera;
+
+import static org.junit.Assert.*;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.StructureViewer;
+import jalview.gui.StructureViewer.Viewer;
+import jalview.io.FormatAdapter;
+
+import java.awt.Desktop;
+import java.io.File;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class JalviewChimeraView
+{
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception
+ {
+ jalview.bin.Jalview.main(new String[]
+ { "-noquestionnaire -nonews -props", "test/src/jalview/ext/rbvi/chimera/testProps.jvprops" });
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception
+ {
+ jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+
+ }
+
+
+ @Test
+ public void testSingleSeqView()
+ {
+ String inFile = "examples/1gaq.txt";
+ AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
+ inFile, FormatAdapter.FILE);
+ assertTrue("Didn't read input file " + inFile, af != null);
+ for (SequenceI sq:af.getViewport().getAlignment().getSequences())
+ {
+ SequenceI dsq=sq.getDatasetSequence();
+ while (dsq.getDatasetSequence()!=null)
+ {
+ dsq=dsq.getDatasetSequence();
+ }
+ if (dsq.getPDBId()!=null && dsq.getPDBId().size()>0) {
+ for (int q=0;q<dsq.getPDBId().size();q++)
+ {
+ new StructureViewer(af.getViewport().getStructureSelectionManager()).viewStructures(Viewer.JMOL,
+ af.getCurrentView().getAlignPanel(),
+ new PDBEntry[] { (PDBEntry)dsq.getPDBId().elementAt(q) },
+ new SequenceI[][] { new SequenceI[] { sq } });
+
+ new StructureViewer(af.getViewport().getStructureSelectionManager()).viewStructures(Viewer.CHIMERA,
+ af.getCurrentView().getAlignPanel(),
+ new PDBEntry[] { (PDBEntry)dsq.getPDBId().elementAt(q) },
+ new SequenceI[][] { new SequenceI[] { sq } });
+ break;
+ }
+ break;
+ }
+ }
+ try {
+ Thread.sleep(200000);
+ } catch (InterruptedException q)
+ {
+
+ }
+ }
+}
--- /dev/null
+#---JalviewX Properties File---
+#Fri Apr 25 09:54:25 BST 2014
+SCREEN_Y=768
+SCREEN_X=936
+SHOW_WSDISCOVERY_ERRORS=true
+LATEST_VERSION=2.8.0b1
+SHOW_CONSERVATION=true
+JALVIEW_RSS_WINDOW_SCREEN_WIDTH=550
+JAVA_CONSOLE_SCREEN_WIDTH=450
+LAST_DIRECTORY=/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples
+ID_ITALICS=true
+SORT_ALIGNMENT=No sort
+SHOW_IDENTITY=true
+WSMENU_BYHOST=false
+SEQUENCE_LINKS=EMBL-EBI Search|http\://www.ebi.ac.uk/ebisearch/search.ebi?db\=allebi&query\=$SEQUENCE_ID$
+SHOW_FULLSCREEN=false
+RECENT_URL=http\://www.jalview.org/examples/exampleFile_2_7.jar
+FONT_NAME=SansSerif
+BLC_JVSUFFIX=true
+VERSION_CHECK=false
+YEAR=2011
+SHOW_DBREFS_TOOLTIP=true
+MSF_JVSUFFIX=true
+SCREENGEOMETRY_HEIGHT=1600
+JAVA_CONSOLE_SCREEN_Y=475
+JAVA_CONSOLE_SCREEN_X=830
+PFAM_JVSUFFIX=true
+PIR_JVSUFFIX=true
+STARTUP_FILE=http\://www.jalview.org/examples/exampleFile_2_3.jar
+JAVA_CONSOLE_SCREEN_HEIGHT=162
+PIR_MODELLER=false
+GAP_SYMBOL=-
+SHOW_QUALITY=true
+SHOW_GROUP_CONSERVATION=false
+SHOW_JWS2_SERVICES=true
+SHOW_NPFEATS_TOOLTIP=true
+FONT_STYLE=plain
+ANTI_ALIAS=false
+SORT_BY_TREE=false
+RSBS_SERVICES=|Multi-Harmony|Analysis|Sequence Harmony and Multi-Relief (Brandt et al. 2010)|hseparable,gapCharacter\='-',returns\='ANNOTATION'|?tool\=jalview|http\://zeus.few.vu.nl/programs/shmrwww/index.php?tool\=jalview&groups\=$PARTITION\:min\='2',minsize\='2',sep\=' '$&ali_file\=$ALIGNMENT\:format\='FASTA',writeasfile$
+AUTHORFNAMES=Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
+JALVIEW_RSS_WINDOW_SCREEN_HEIGHT=328
+SHOW_GROUP_CONSENSUS=false
+SHOW_CONSENSUS_HISTOGRAM=true
+SHOW_OVERVIEW=false
+AUTHORS=J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
+FIGURE_AUTOIDWIDTH=false
+SCREEN_WIDTH=900
+ANNOTATIONCOLOUR_MIN=ffc800
+SHOW_STARTUP_FILE=false
+RECENT_FILE=examples/uniref50.fa\t/Volumes/Data/Users/jimp/Documents/testing/Jalview/examples/RF00031_folded.stk\t/Volumes/Data/Users/jimp/bs_ig_mult.out
+DEFAULT_FILE_FORMAT=FASTA
+SHOW_JAVA_CONSOLE=false
+VERSION=2.8b1
+FIGURE_USERIDWIDTH=
+WSMENU_BYTYPE=false
+DEFAULT_COLOUR=None
+NOQUESTIONNAIRES=true
+JALVIEW_NEWS_RSS_LASTMODIFIED=Apr 23, 2014 2\:53\:26 PM
+BUILD_DATE=01 November 2013
+PILEUP_JVSUFFIX=true
+SHOW_CONSENSUS_LOGO=false
+SCREENGEOMETRY_WIDTH=2560
+SHOW_ANNOTATIONS=true
+JALVIEW_RSS_WINDOW_SCREEN_Y=0
+USAGESTATS=false
+JALVIEW_RSS_WINDOW_SCREEN_X=0
+SHOW_UNCONSERVED=false
+SHOW_JVSUFFIX=true
+DAS_LOCAL_SOURCE=
+SCREEN_HEIGHT=650
+ANNOTATIONCOLOUR_MAX=ff0000
+AUTO_CALC_CONSENSUS=true
+FASTA_JVSUFFIX=true
+DAS_ACTIVE_SOURCE=uniprot\t
+JWS2HOSTURLS=http\://www.compbio.dundee.ac.uk/jabaws
+PAD_GAPS=false
+CLUSTAL_JVSUFFIX=true
+SHOW_ENFIN_SERVICES=true
+FONT_SIZE=10
+RIGHT_ALIGN_IDS=false
+USE_PROXY=false
+WRAP_ALIGNMENT=false
+DAS_REGISTRY_URL=http\://www.dasregistry.org/das/
--- /dev/null
+package jalview.gui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.AppletFormatAdapter;
+import jalview.util.MessageManager;
+
+import java.awt.BorderLayout;
+import java.awt.Checkbox;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.FlowLayout;
+import java.awt.event.ItemEvent;
+import java.io.IOException;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JPanel;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for AnnotationChooser
+ *
+ * @author gmcarstairs
+ *
+ */
+public class AnnotationChooserTest
+{
+ // 4 sequences x 13 positions
+ final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n"
+ + "TIETHKEAELVG-\n"
+ + ">FER_CAPAN Ferredoxin, chloroplast precursor\n"
+ + "TIETHKEAELVG-\n"
+ + ">FER1_SOLLC Ferredoxin-1, chloroplast precursor\n"
+ + "TIETHKEEELTA-\n" + ">Q93XJ9_SOLTU Ferredoxin I precursor\n"
+ + "TIETHKEEELTA-\n";
+
+ AnnotationChooser testee;
+
+ AlignmentPanel parentPanel;
+
+ AlignFrame af;
+
+ @Before
+ public void setUp() throws IOException
+ {
+ AlignmentI al = new jalview.io.FormatAdapter().readFile(TEST_DATA,
+ AppletFormatAdapter.PASTE, "FASTA");
+ af = new AlignFrame(al, 700, 500);
+ parentPanel = new AlignmentPanel(af, af.getViewport());
+ addAnnotations();
+ }
+
+ /**
+ * Add 4 annotations, 3 of them sequence-specific.
+ *
+ * <PRE>
+ * ann1 - for sequence 0 - label 'IUPRED'
+ * ann2 - not sequence related - label 'Beauty'
+ * ann3 - for sequence 3 - label 'JMol'
+ * ann4 - for sequence 2 - label 'IUPRED'
+ * ann5 - for sequence 1 - label 'JMol'
+ */
+ private void addAnnotations()
+ {
+ Annotation an = new Annotation(2f);
+ Annotation[] anns = new Annotation[]
+ { an, an, an };
+ AlignmentAnnotation ann0 = new AlignmentAnnotation("IUPRED", "", anns);
+ AlignmentAnnotation ann1 = new AlignmentAnnotation("Beauty", "", anns);
+ AlignmentAnnotation ann2 = new AlignmentAnnotation("JMol", "", anns);
+ AlignmentAnnotation ann3 = new AlignmentAnnotation("IUPRED", "", anns);
+ AlignmentAnnotation ann4 = new AlignmentAnnotation("JMol", "", anns);
+ SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray();
+ ann0.setSequenceRef(seqs[0]);
+ ann2.setSequenceRef(seqs[3]);
+ ann3.setSequenceRef(seqs[2]);
+ ann4.setSequenceRef(seqs[1]);
+ parentPanel.getAlignment().addAnnotation(ann0);
+ parentPanel.getAlignment().addAnnotation(ann1);
+ parentPanel.getAlignment().addAnnotation(ann2);
+ parentPanel.getAlignment().addAnnotation(ann3);
+ parentPanel.getAlignment().addAnnotation(ann4);
+ }
+
+ /**
+ * Test creation of panel with OK and Cancel buttons
+ */
+ @Test
+ public void testBuildActionButtonsPanel()
+ {
+ testee = new AnnotationChooser(parentPanel);
+ JPanel jp = testee.buildActionButtonsPanel();
+ assertTrue("Wrong layout", jp.getLayout() instanceof FlowLayout);
+
+ Component[] comps = jp.getComponents();
+ assertEquals("Not 2 action buttons", 2, comps.length);
+
+ final Component jb1 = comps[0];
+ final Component jb2 = comps[1];
+
+ assertEquals("Not 'OK' button", MessageManager.getString("action.ok"),
+ ((JButton) jb1).getText());
+ assertEquals("Wrong button font", JvSwingUtils.getLabelFont(),
+ jb1.getFont());
+
+ assertEquals("Not 'Cancel' button",
+ MessageManager.getString("action.cancel"),
+ ((JButton) jb2).getText());
+ assertEquals("Wrong button font", JvSwingUtils.getLabelFont(),
+ jb2.getFont());
+ }
+
+ /**
+ * Test 'Apply to' has 3 radio buttons enabled, 'Selected Sequences' selected,
+ * when there is a current selection group.
+ */
+ @Test
+ public void testBuildApplyToOptionsPanel_withSelectionGroup()
+ {
+ selectSequences(0, 2, 3);
+ testee = new AnnotationChooser(parentPanel);
+
+ JPanel jp = testee.buildApplyToOptionsPanel();
+ Component[] comps = jp.getComponents();
+ assertEquals("Not 3 radio buttons", 3, comps.length);
+
+ final Checkbox cb1 = (Checkbox) comps[0];
+ final Checkbox cb2 = (Checkbox) comps[1];
+ final Checkbox cb3 = (Checkbox) comps[2];
+
+ assertTrue("Not enabled", cb1.isEnabled());
+ assertTrue("Not enabled", cb2.isEnabled());
+ assertTrue("Not enabled", cb3.isEnabled());
+ assertEquals("Option not selected", cb2, cb2.getCheckboxGroup()
+ .getSelectedCheckbox());
+
+ // check state variables match checkbox selection
+ assertTrue(testee.isApplyToSelectedSequences());
+ assertFalse(testee.isApplyToUnselectedSequences());
+ }
+
+ /**
+ * Add a sequence group to the alignment with the specified sequences (base 0)
+ * in it
+ *
+ * @param i
+ * @param more
+ */
+ private void selectSequences(int... selected)
+ {
+ SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray();
+ SequenceGroup sg = new SequenceGroup();
+ for (int i : selected)
+ {
+ sg.addSequence(seqs[i], false);
+ }
+ parentPanel.av.setSelectionGroup(sg);
+ }
+
+ /**
+ * Test 'Apply to' has 1 radio button enabled, 'All Sequences' selected, when
+ * there is no current selection group.
+ */
+ @Test
+ public void testBuildApplyToOptionsPanel_noSelectionGroup()
+ {
+ testee = new AnnotationChooser(parentPanel);
+ JPanel jp = testee.buildApplyToOptionsPanel();
+ verifyApplyToOptionsPanel_noSelectionGroup(jp);
+ }
+
+ protected void verifyApplyToOptionsPanel_noSelectionGroup(JPanel jp)
+ {
+ assertTrue("Wrong layout", jp.getLayout() instanceof FlowLayout);
+ Component[] comps = jp.getComponents();
+ assertEquals("Not 3 radio buttons", 3, comps.length);
+
+ final Checkbox cb1 = (Checkbox) comps[0];
+ final Checkbox cb2 = (Checkbox) comps[1];
+ final Checkbox cb3 = (Checkbox) comps[2];
+
+ assertTrue("Not enabled", cb1.isEnabled());
+ assertFalse("Enabled", cb2.isEnabled());
+ assertFalse("Enabled", cb3.isEnabled());
+ assertEquals("Not selected", cb1, cb1.getCheckboxGroup()
+ .getSelectedCheckbox());
+
+ // check state variables match checkbox selection
+ assertTrue(testee.isApplyToSelectedSequences());
+ assertTrue(testee.isApplyToUnselectedSequences());
+
+ assertEquals("Wrong text",
+ MessageManager.getString("label.all_sequences"), cb1.getLabel());
+ assertEquals("Wrong text",
+ MessageManager.getString("label.selected_sequences"),
+ cb2.getLabel());
+ assertEquals("Wrong text",
+ MessageManager.getString("label.except_selected_sequences"),
+ cb3.getLabel());
+ }
+
+ /**
+ * Test Show and Hide radio buttons created, with Hide initially selected.
+ */
+ @Test
+ public void testBuildShowHidePanel()
+ {
+ testee = new AnnotationChooser(parentPanel);
+ JPanel jp = testee.buildShowHidePanel();
+ verifyShowHidePanel(jp);
+
+ }
+
+ protected void verifyShowHidePanel(JPanel jp)
+ {
+ assertTrue("Wrong layout", jp.getLayout() instanceof FlowLayout);
+ Component[] comps = jp.getComponents();
+ assertEquals("Not 2 radio buttons", 2, comps.length);
+
+ final Checkbox cb1 = (Checkbox) comps[0];
+ final Checkbox cb2 = (Checkbox) comps[1];
+
+ assertTrue("Show not enabled", cb1.isEnabled());
+ assertTrue("Hide not enabled", cb2.isEnabled());
+
+ // Hide (button 2) selected; note this may change to none (null)
+ assertEquals("Not selected", cb2, cb2.getCheckboxGroup()
+ .getSelectedCheckbox());
+
+ assertTrue("Show is flagged", !testee.isShowSelected());
+
+ assertEquals("Wrong text",
+ MessageManager.getString("label.show_selected_annotations"),
+ cb1.getLabel());
+ assertEquals("Wrong text",
+ MessageManager.getString("label.hide_selected_annotations"),
+ cb2.getLabel());
+ }
+
+ /**
+ * Test construction of panel containing two sub-panels
+ */
+ @Test
+ public void testBuildShowHideOptionsPanel()
+ {
+ testee = new AnnotationChooser(parentPanel);
+ JPanel jp = testee.buildShowHideOptionsPanel();
+ assertTrue("Wrong layout", jp.getLayout() instanceof BorderLayout);
+ Component[] comps = jp.getComponents();
+ assertEquals("Not 2 sub-panels", 2, comps.length);
+
+ verifyShowHidePanel((JPanel) comps[0]);
+ verifyApplyToOptionsPanel_noSelectionGroup((JPanel) comps[1]);
+ }
+
+ /**
+ * Test that annotation types are (uniquely) identified.
+ *
+ */
+ @Test
+ public void testGetAnnotationTypes()
+ {
+ selectSequences(1);
+ testee = new AnnotationChooser(parentPanel);
+ // selection group should make no difference to the result
+ // as all annotation types for the alignment are considered
+
+ List<String> types = AnnotationChooser.getAnnotationTypes(
+ parentPanel.getAlignment(), true);
+ assertEquals("Not two annotation types", 2, types.size());
+ assertTrue("IUPRED missing", types.contains("IUPRED"));
+ assertTrue("JMol missing", types.contains("JMol"));
+
+ types = AnnotationChooser.getAnnotationTypes(
+ parentPanel.getAlignment(), false);
+ assertEquals("Not six annotation types", 6, types.size());
+ assertTrue("IUPRED missing", types.contains("IUPRED"));
+ assertTrue("JMol missing", types.contains("JMol"));
+ assertTrue("Beauty missing", types.contains("Beauty"));
+ // These are added by viewmodel.AlignViewport.initAutoAnnotation():
+ assertTrue("Consensus missing", types.contains("Consensus"));
+ assertTrue("Quality missing", types.contains("Quality"));
+ assertTrue("Conservation missing", types.contains("Conservation"));
+ }
+
+ /**
+ * Test result of selecting an annotation type, with 'Hide for all sequences'.
+ *
+ * We expect all annotations of that type to be set hidden. Other annotations
+ * should be left visible.
+ */
+ @Test
+ public void testSelectType_hideForAll()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+ setSelected(hideCheckbox, true);
+
+ final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
+ 1, 1, 0);
+ setSelected(allSequencesCheckbox, true);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[7].visible); // JMol for seq1
+
+ setSelected(getTypeCheckbox("JMol"), true);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertFalse(anns[5].visible); // JMol for seq3 - not selected but hidden
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertFalse(anns[7].visible); // JMol for seq1 - selected and hidden
+ }
+
+ /**
+ * Test result of selecting an annotation type, with 'Hide for selected
+ * sequences'.
+ *
+ * We expect the annotations of that type, linked to the sequence group, to be
+ * set hidden. Other annotations should be left visible.
+ */
+ @Test
+ public void testSelectType_hideForSelected()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+ setSelected(hideCheckbox, true);
+
+ /*
+ * Don't set the 'selected sequences' radio button since this would trigger
+ * an update, including unselected sequences / annotation types
+ */
+ // setSelected(getSelectedSequencesCheckbox());
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ assertTrue(anns[7].visible); // JMol for seq1
+
+ setSelected(getTypeCheckbox("JMol"), true);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3 not in selection group
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertFalse(anns[7].visible); // JMol for seq1 in selection group
+ }
+
+ /**
+ * Test result of deselecting an annotation type, with 'Hide for all
+ * sequences'.
+ *
+ * We expect all annotations of that type to be set visible. Other annotations
+ * should be left unchanged.
+ */
+ @Test
+ public void testDeselectType_hideForAll()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+ setSelected(hideCheckbox, true);
+
+ final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
+ 1, 1, 0);
+ setSelected(allSequencesCheckbox, true);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ final Checkbox typeCheckbox = getTypeCheckbox("JMol");
+
+ // select JMol - all hidden
+ setSelected(typeCheckbox, true);
+ assertFalse(anns[5].visible); // JMol for seq3
+ assertFalse(anns[7].visible); // JMol for seq1
+
+ // deselect JMol - all unhidden
+ setSelected(typeCheckbox, false);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertTrue(anns[7].visible); // JMol for seq1
+ }
+
+ /**
+ * Test result of deselecting an annotation type, with 'Hide for selected
+ * sequences'.
+ *
+ * We expect the annotations of that type, linked to the sequence group, to be
+ * set visible. Other annotations should be left unchanged.
+ */
+ @Test
+ public void testDeselectType_hideForSelected()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+ setSelected(hideCheckbox, true);
+
+ /*
+ * Don't set the 'selected sequences' radio button since this would trigger
+ * an update, including unselected sequences / annotation types
+ */
+ // setSelected(getSelectedSequencesCheckbox());
+
+ setSelected(getTypeCheckbox("JMol"), true);
+ setSelected(getTypeCheckbox("JMol"), false);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3 not in selection group
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertTrue(anns[7].visible); // JMol for seq1 in selection group
+ }
+
+ /**
+ * Test result of selecting an annotation type, with 'Show for all sequences'.
+ *
+ * We expect all annotations of that type to be set visible. Other annotations
+ * should be left unchanged
+ */
+ @Test
+ public void testSelectType_showForAll()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+
+ final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
+ 1, 1, 0);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ // hide all JMol annotations
+ setSelected(allSequencesCheckbox, true);
+ setSelected(hideCheckbox, true);
+ setSelected(getTypeCheckbox("JMol"), true);
+ assertFalse(anns[5].visible); // JMol for seq3
+ assertFalse(anns[7].visible); // JMol for seq1
+ // ...now show them...
+ setSelected(showCheckbox, true);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertTrue(anns[7].visible); // JMol for seq1
+ }
+
+ /**
+ * Test result of selecting an annotation type, with 'Show for selected
+ * sequences'.
+ *
+ * We expect all annotations of that type, linked to the sequence group, to be
+ * set visible. Other annotations should be left unchanged
+ */
+ @Test
+ public void testSelectType_showForSelected()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+
+ final Checkbox selectedSequencesCheckbox = (Checkbox) getComponent(
+ testee, 1, 1, 1);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ // hide all JMol annotations in the selection region (== annotation 7)
+ setSelected(selectedSequencesCheckbox, true);
+ setSelected(hideCheckbox, true);
+ setSelected(getTypeCheckbox("JMol"), true);
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertFalse(anns[7].visible); // JMol for seq1
+ // ...now show them...
+ setSelected(showCheckbox, true);
+
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertTrue(anns[7].visible); // JMol for seq1
+ }
+
+ /**
+ * Test result of deselecting an annotation type, with 'Show for all
+ * sequences'.
+ *
+ * We expect all annotations of that type to be set hidden. Other annotations
+ * should be left unchanged.
+ */
+ @Test
+ public void testDeselectType_showForAll()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+
+ final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
+ setSelected(showCheckbox, true);
+
+ final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
+ 1, 1, 0);
+ setSelected(allSequencesCheckbox, true);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ final Checkbox typeCheckbox = getTypeCheckbox("JMol");
+ // select JMol - all shown
+ setSelected(typeCheckbox, true);
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[7].visible); // JMol for seq1
+
+ // deselect JMol - all hidden
+ setSelected(typeCheckbox, false);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertFalse(anns[5].visible); // JMol for seq3
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertFalse(anns[7].visible); // JMol for seq1
+ }
+
+ /**
+ * Test result of deselecting an annotation type, with 'Show for selected
+ * sequences'.
+ *
+ * We expect the annotations of that type, linked to the sequence group, to be
+ * set hidden. Other annotations should be left unchanged.
+ */
+ @Test
+ public void testDeselectType_showForSelected()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
+ setSelected(showCheckbox, true);
+
+ /*
+ * Don't set the 'selected sequences' radio button since this would trigger
+ * an update, including unselected sequences / annotation types
+ */
+ // setSelected(getSelectedSequencesCheckbox());
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ // select JMol - should remain visible
+ setSelected(getTypeCheckbox("JMol"), true);
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[7].visible); // JMol for seq1
+
+ // deselect JMol - should be hidden for selected sequences only
+ setSelected(getTypeCheckbox("JMol"), false);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3 not in selection group
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertFalse(anns[7].visible); // JMol for seq1 in selection group
+ }
+
+ /**
+ * Helper method to drill down to a sub-component in a Container hierarchy.
+ *
+ * @param cont
+ * @param i
+ * @param j
+ * @param k
+ * @return
+ */
+ public static Component getComponent(Container cont, int... positions)
+ {
+ Component comp = cont;
+ for (int i : positions)
+ {
+ comp = ((Container) comp).getComponent(i);
+ }
+ return comp;
+ }
+
+ /**
+ * Helper method to set or unset a checkbox and fire its action listener.
+ *
+ * @param cb
+ * @param select
+ */
+ protected void setSelected(Checkbox cb, boolean select)
+ {
+ // TODO refactor to a test utility class
+ cb.setState(select);
+ // have to manually fire the action listener
+ cb.getItemListeners()[0].itemStateChanged(new ItemEvent(cb,
+ ItemEvent.ITEM_STATE_CHANGED, cb, select ? ItemEvent.SELECTED
+ : ItemEvent.DESELECTED));
+ }
+
+ /**
+ * Helper method to drill down to the 'Annotation type' checkbox with given
+ * label.
+ *
+ * @return
+ */
+ private Checkbox getTypeCheckbox(String forLabel)
+ {
+ Component[] cbs = ((JPanel) testee.getComponent(0)).getComponents();
+ for (Component comp : cbs)
+ {
+ final Checkbox cb = (Checkbox) comp;
+ if (cb.getLabel().equals(forLabel))
+ {
+ return cb;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Test isInActionScope for the case where the scope is selected sequences.
+ * Test cases include sequences in the selection group, and others not in the
+ * group.
+ */
+ @Test
+ public void testIsInActionScope_selectedScope()
+ {
+ // sequences 1 and 2 have annotations 4 and 3 respectively
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+
+ final Checkbox selectedSequencesCheckbox = (Checkbox) getComponent(
+ testee, 1, 1, 1);
+ setSelected(selectedSequencesCheckbox, true);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+ // remember 3 annotations to skip (Conservation/Quality/Consensus)
+ assertFalse(testee.isInActionScope(anns[3]));
+ assertFalse(testee.isInActionScope(anns[4]));
+ assertFalse(testee.isInActionScope(anns[5]));
+ assertTrue(testee.isInActionScope(anns[6]));
+ assertTrue(testee.isInActionScope(anns[7]));
+ }
+
+ /**
+ * Test isInActionScope for the case where the scope is unselected sequences.
+ * Test cases include sequences in the selection group, and others not in the
+ * group.
+ */
+ @Test
+ public void testIsInActionScope_unselectedScope()
+ {
+ // sequences 1 and 2 have annotations 4 and 3 respectively
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+
+ final Checkbox unselectedSequencesCheckbox = (Checkbox) getComponent(
+ testee, 1, 1, 2);
+ setSelected(unselectedSequencesCheckbox, true);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+ // remember 3 annotations to skip (Conservation/Quality/Consensus)
+ assertTrue(testee.isInActionScope(anns[3]));
+ assertTrue(testee.isInActionScope(anns[4]));
+ assertTrue(testee.isInActionScope(anns[5]));
+ assertFalse(testee.isInActionScope(anns[6]));
+ assertFalse(testee.isInActionScope(anns[7]));
+ }
+
+ /**
+ * Test that the reset method restores previous visibility flags.
+ */
+ @Test
+ public void testResetOriginalState()
+ {
+ testee = new AnnotationChooser(parentPanel);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+ // all start visible
+ for (int i = 0; i < anns.length; i++)
+ {
+ assertTrue(i + "'th sequence not visible", anns[i].visible);
+ }
+
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+ setSelected(hideCheckbox, true);
+
+ final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
+ 1, 1, 0);
+ setSelected(allSequencesCheckbox, true);
+
+ setSelected(getTypeCheckbox("JMol"), true);
+ setSelected(getTypeCheckbox("IUPRED"), true);
+
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertFalse(anns[3].visible); // IUPRED
+ assertTrue(anns[4].visible); // Beauty (not seq-related)
+ assertFalse(anns[5].visible); // JMol
+ assertFalse(anns[6].visible); // IUPRED
+ assertFalse(anns[7].visible); // JMol
+
+ // reset - should all be visible
+ testee.resetOriginalState();
+ for (int i = 0; i < anns.length; i++)
+ {
+ assertTrue(i + "'th sequence not visible", anns[i].visible);
+ }
+ }
+}
*/
package jalview.gui;
-import static org.junit.Assert.*;
import jalview.bin.Cache;
-import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
-import javax.swing.JPanel;
import javax.swing.JTextArea;
import org.junit.AfterClass;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
public class JAL1353bugdemo
volatile boolean finish = false;
@Test
+ @Ignore
+ // comment out @Ignore to enable this test
public void test()
{
Cache.initLogger();
--- /dev/null
+package jalview.gui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+import jalview.io.AppletFormatAdapter;
+import jalview.util.MessageManager;
+
+import java.awt.Component;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JSeparator;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class PopupMenuTest
+{
+ // 4 sequences x 13 positions
+ final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n"
+ + "TIETHKEAELVG-\n"
+ + ">FER_CAPAN Ferredoxin, chloroplast precursor\n"
+ + "TIETHKEAELVG-\n"
+ + ">FER1_SOLLC Ferredoxin-1, chloroplast precursor\n"
+ + "TIETHKEEELTA-\n" + ">Q93XJ9_SOLTU Ferredoxin I precursor\n"
+ + "TIETHKEEELTA-\n";
+
+ AlignmentI alignment;
+
+ AlignmentPanel parentPanel;
+
+ PopupMenu testee = null;
+
+ @Before
+ public void setUp() throws IOException
+ {
+ alignment = new jalview.io.FormatAdapter().readFile(TEST_DATA,
+ AppletFormatAdapter.PASTE, "FASTA");
+ AlignFrame af = new AlignFrame(alignment, 700, 500);
+ parentPanel = new AlignmentPanel(af, af.getViewport());
+ testee = new PopupMenu(parentPanel, null, null);
+ int i = 0;
+ for (SequenceI seq : alignment.getSequences())
+ {
+ final AlignmentAnnotation annotation = new AlignmentAnnotation("label" + i,
+ "desc" + i, i);
+ annotation.setCalcId("calcId" + i);
+ seq.addAlignmentAnnotation(annotation);
+ annotation.setSequenceRef(seq);
+ }
+ }
+
+ @Test
+ public void testConfigureReferenceAnnotationsMenu_noSequenceSelected()
+ {
+ JMenuItem menu = new JMenuItem();
+ List<SequenceI> seqs = new ArrayList<SequenceI>();
+ testee.configureReferenceAnnotationsMenu(menu, seqs);
+ assertFalse(menu.isEnabled());
+ assertEquals(
+ MessageManager.getString("label.add_reference_annotations"),
+ menu.getText());
+ // now try null list
+ menu.setEnabled(true);
+ testee.configureReferenceAnnotationsMenu(menu, seqs);
+ assertFalse(menu.isEnabled());
+ }
+
+ /**
+ * Test building the 'add reference annotations' menu for the case where there
+ * are no reference annotations to add to the alignment. The menu item should
+ * be disabled.
+ */
+ @Test
+ public void testConfigureReferenceAnnotationsMenu_noReferenceAnnotations()
+ {
+ JMenuItem menu = new JMenuItem();
+ List<SequenceI> seqs = new ArrayList<SequenceI>();
+
+ /*
+ * Initial state is that sequences have annotations, and have dataset
+ * sequences, but the dataset sequences have no annotations. Hence nothing
+ * to add.
+ */
+ seqs = parentPanel.getAlignment().getSequences();
+
+ testee.configureReferenceAnnotationsMenu(menu, seqs);
+ assertFalse(menu.isEnabled());
+ }
+
+ /**
+ * Test building the 'add reference annotations' menu for the case where all
+ * reference annotations are already on the alignment. The menu item should be
+ * disabled.
+ */
+ @Test
+ public void testConfigureReferenceAnnotationsMenu_alreadyAdded()
+ {
+ JMenuItem menu = new JMenuItem();
+ List<SequenceI> seqs = new ArrayList<SequenceI>();
+
+ seqs = parentPanel.getAlignment().getSequences();
+ // copy annotation from sequence to dataset
+ seqs.get(1).getDatasetSequence()
+ .addAlignmentAnnotation(seqs.get(1).getAnnotation()[0]);
+ testee.configureReferenceAnnotationsMenu(menu, seqs);
+ assertFalse(menu.isEnabled());
+ }
+
+ /**
+ * Test building the 'add reference annotations' menu for the case where
+ * several reference annotations are on the dataset but not on the sequences.
+ * The menu item should be enabled, and acquire a tooltip which lists the
+ * annotation sources (calcIds) and type (labels).
+ */
+ @Test
+ public void testConfigureReferenceAnnotationsMenu()
+ {
+ JMenuItem menu = new JMenuItem();
+ List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
+ // make up new annotations and add to dataset sequences
+
+ // PDB.secondary structure on Sequence0
+ AlignmentAnnotation annotation = new AlignmentAnnotation(
+ "secondary structure", "", 0);
+ annotation.setCalcId("PBD");
+ seqs.get(0).getDatasetSequence().addAlignmentAnnotation(annotation);
+
+ // PDB.Temp on Sequence1
+ annotation = new AlignmentAnnotation("Temp", "", 0);
+ annotation.setCalcId("PBD");
+ seqs.get(1).getDatasetSequence().addAlignmentAnnotation(annotation);
+
+ // JMOL.secondary structure on Sequence0
+ annotation = new AlignmentAnnotation("secondary structure", "", 0);
+ annotation.setCalcId("JMOL");
+ seqs.get(0).getDatasetSequence().addAlignmentAnnotation(annotation);
+
+ testee.configureReferenceAnnotationsMenu(menu, seqs);
+ assertTrue(menu.isEnabled());
+ String expected = "<html><table width=350 border=0><tr><td>Add annotations for<br/>JMOL/secondary structure<br/>PBD/Temp</td></tr></table></html>";
+ assertEquals(expected, menu.getToolTipText());
+ }
+
+ /**
+ * Test for building menu options including 'show' and 'hide' annotation
+ * types.
+ */
+ @Test
+ public void testBuildAnnotationTypesMenus()
+ {
+ JMenu showMenu = new JMenu();
+ JMenu hideMenu = new JMenu();
+ List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
+
+ // make up new annotations and add to sequences and to the alignment
+
+ // PDB.secondary structure on Sequence0
+ AlignmentAnnotation annotation = new AlignmentAnnotation(
+ "secondary structure", "", 0);
+ annotation.setCalcId("PDB");
+ annotation.visible = true;
+ seqs.get(0).addAlignmentAnnotation(annotation);
+ parentPanel.getAlignment().addAnnotation(annotation);
+
+ // JMOL.secondary structure on Sequence0 - hidden
+ annotation = new AlignmentAnnotation("secondary structure", "", 0);
+ annotation.setCalcId("JMOL");
+ annotation.visible = false;
+ seqs.get(0).addAlignmentAnnotation(annotation);
+ parentPanel.getAlignment().addAnnotation(annotation);
+
+ // Jpred.SSP on Sequence0 - hidden
+ annotation = new AlignmentAnnotation("SSP", "", 0);
+ annotation.setCalcId("JPred");
+ annotation.visible = false;
+ seqs.get(0).addAlignmentAnnotation(annotation);
+ parentPanel.getAlignment().addAnnotation(annotation);
+
+ // PDB.Temp on Sequence1
+ annotation = new AlignmentAnnotation("Temp", "", 0);
+ annotation.setCalcId("PDB");
+ annotation.visible = true;
+ seqs.get(1).addAlignmentAnnotation(annotation);
+ parentPanel.getAlignment().addAnnotation(annotation);
+
+ /*
+ * Expect menu options to show "secondary structure" and "SSP", and to hide
+ * "secondary structure" and "Temp". Tooltip should be calcId.
+ */
+ testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs);
+
+ assertTrue(showMenu.isEnabled());
+ assertTrue(hideMenu.isEnabled());
+
+ Component[] showOptions = showMenu.getMenuComponents();
+ Component[] hideOptions = hideMenu.getMenuComponents();
+
+ assertEquals(4, showOptions.length); // includes 'All' and separator
+ assertEquals(4, hideOptions.length);
+ assertEquals("All",
+ ((JMenuItem) showOptions[0]).getText());
+ assertTrue(showOptions[1] instanceof JPopupMenu.Separator);
+ assertEquals(JSeparator.HORIZONTAL,
+ ((JSeparator) showOptions[1]).getOrientation());
+ assertEquals("secondary structure",
+ ((JMenuItem) showOptions[2]).getText());
+ assertEquals("JMOL", ((JMenuItem) showOptions[2]).getToolTipText());
+ assertEquals("SSP", ((JMenuItem) showOptions[3]).getText());
+ assertEquals("JPred", ((JMenuItem) showOptions[3]).getToolTipText());
+
+ assertEquals("All",
+ ((JMenuItem) hideOptions[0]).getText());
+ assertTrue(hideOptions[1] instanceof JPopupMenu.Separator);
+ assertEquals(JSeparator.HORIZONTAL,
+ ((JSeparator) hideOptions[1]).getOrientation());
+ assertEquals("secondary structure",
+ ((JMenuItem) hideOptions[2]).getText());
+ assertEquals("PDB", ((JMenuItem) hideOptions[2]).getToolTipText());
+ assertEquals("Temp", ((JMenuItem) hideOptions[3]).getText());
+ assertEquals("PDB", ((JMenuItem) hideOptions[3]).getToolTipText());
+ }
+
+ /**
+ * Test for building menu options with only 'hide' annotation types enabled.
+ */
+ @Test
+ public void testBuildAnnotationTypesMenus_showDisabled()
+ {
+ JMenu showMenu = new JMenu();
+ JMenu hideMenu = new JMenu();
+ List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
+
+ // make up new annotations and add to sequences and to the alignment
+
+ // PDB.secondary structure on Sequence0
+ AlignmentAnnotation annotation = new AlignmentAnnotation(
+ "secondary structure", "", 0);
+ annotation.setCalcId("PDB");
+ annotation.visible = true;
+ seqs.get(0).addAlignmentAnnotation(annotation);
+ parentPanel.getAlignment().addAnnotation(annotation);
+
+ // PDB.Temp on Sequence1
+ annotation = new AlignmentAnnotation("Temp", "", 0);
+ annotation.setCalcId("PDB");
+ annotation.visible = true;
+ seqs.get(1).addAlignmentAnnotation(annotation);
+ parentPanel.getAlignment().addAnnotation(annotation);
+
+ /*
+ * Expect menu options to hide "secondary structure" and "Temp". Tooltip
+ * should be calcId. 'Show' menu should be disabled.
+ */
+ testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs);
+
+ assertFalse(showMenu.isEnabled());
+ assertTrue(hideMenu.isEnabled());
+
+ Component[] showOptions = showMenu.getMenuComponents();
+ Component[] hideOptions = hideMenu.getMenuComponents();
+
+ assertEquals(2, showOptions.length); // includes 'All' and separator
+ assertEquals(4, hideOptions.length);
+ assertEquals("All", ((JMenuItem) showOptions[0]).getText());
+ assertTrue(showOptions[1] instanceof JPopupMenu.Separator);
+ assertEquals(JSeparator.HORIZONTAL,
+ ((JSeparator) showOptions[1]).getOrientation());
+
+ assertEquals("All", ((JMenuItem) hideOptions[0]).getText());
+ assertTrue(hideOptions[1] instanceof JPopupMenu.Separator);
+ assertEquals(JSeparator.HORIZONTAL,
+ ((JSeparator) hideOptions[1]).getOrientation());
+ assertEquals("secondary structure",
+ ((JMenuItem) hideOptions[2]).getText());
+ assertEquals("PDB", ((JMenuItem) hideOptions[2]).getToolTipText());
+ assertEquals("Temp", ((JMenuItem) hideOptions[3]).getText());
+ assertEquals("PDB", ((JMenuItem) hideOptions[3]).getToolTipText());
+ }
+
+ /**
+ * Test for building menu options with only 'show' annotation types enabled.
+ */
+ @Test
+ public void testBuildAnnotationTypesMenus_hideDisabled()
+ {
+ JMenu showMenu = new JMenu();
+ JMenu hideMenu = new JMenu();
+ List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
+
+ // make up new annotations and add to sequences and to the alignment
+
+ // PDB.secondary structure on Sequence0
+ AlignmentAnnotation annotation = new AlignmentAnnotation(
+ "secondary structure", "", 0);
+ annotation.setCalcId("PDB");
+ annotation.visible = false;
+ seqs.get(0).addAlignmentAnnotation(annotation);
+ parentPanel.getAlignment().addAnnotation(annotation);
+
+ // PDB.Temp on Sequence1
+ annotation = new AlignmentAnnotation("Temp", "", 0);
+ annotation.setCalcId("PDB2");
+ annotation.visible = false;
+ seqs.get(1).addAlignmentAnnotation(annotation);
+ parentPanel.getAlignment().addAnnotation(annotation);
+
+ /*
+ * Expect menu options to show "secondary structure" and "Temp". Tooltip
+ * should be calcId. 'hide' menu should be disabled.
+ */
+ testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs);
+
+ assertTrue(showMenu.isEnabled());
+ assertFalse(hideMenu.isEnabled());
+
+ Component[] showOptions = showMenu.getMenuComponents();
+ Component[] hideOptions = hideMenu.getMenuComponents();
+
+ assertEquals(4, showOptions.length); // includes 'All' and separator
+ assertEquals(2, hideOptions.length);
+ assertEquals("All", ((JMenuItem) showOptions[0]).getText());
+ assertTrue(showOptions[1] instanceof JPopupMenu.Separator);
+ assertEquals(JSeparator.HORIZONTAL,
+ ((JSeparator) showOptions[1]).getOrientation());
+ assertEquals("secondary structure",
+ ((JMenuItem) showOptions[2]).getText());
+ assertEquals("PDB", ((JMenuItem) showOptions[2]).getToolTipText());
+ assertEquals("Temp", ((JMenuItem) showOptions[3]).getText());
+ assertEquals("PDB2", ((JMenuItem) showOptions[3]).getToolTipText());
+
+ assertEquals("All", ((JMenuItem) hideOptions[0]).getText());
+ assertTrue(hideOptions[1] instanceof JPopupMenu.Separator);
+ assertEquals(JSeparator.HORIZONTAL,
+ ((JSeparator) hideOptions[1]).getOrientation());
+ }
+}
--- /dev/null
+package jalview.io;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+
+import java.io.File;
+import java.util.Vector;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class AnnotatedPDBFileInputTest
+{
+
+ AlignmentI al;
+
+ String pdbStr = "examples/1gaq.txt";
+
+ String pdbId;
+
+ @Before
+ public void setup() throws Exception
+ {
+ FileLoader loader = new FileLoader(false);
+ AlignFrame af = loader.LoadFileWaitTillLoaded(pdbStr,
+ FormatAdapter.FILE);
+ al = af.getViewport().getAlignment();
+ pdbId = ((PDBEntry) al.getSequenceAt(0).getDatasetSequence().getPDBId()
+ .get(0)).getId();
+ }
+
+ @Test
+ public void checkNoDuplicates()
+ {
+ // not strictly a requirement, but strange things may happen if multiple
+ // instances of the same annotation are placed in the alignment annotation
+ // vector
+ assertNotNull(al.getAlignmentAnnotation());
+ // verify that all sequence annotation is doubly referenced
+ AlignmentAnnotation[] avec = al.getAlignmentAnnotation();
+ for (int p = 0; p < avec.length; p++)
+ {
+ for (int q = p + 1; q < avec.length; q++)
+ {
+ assertNotEquals(
+ "Found a duplicate annotation row " + avec[p].label,
+ avec[p], avec[q]);
+ }
+ }
+ }
+
+ @Test
+ public void checkPDBannotationSource()
+ {
+
+ for (SequenceI asq : al.getSequences())
+ {
+ for (AlignmentAnnotation aa : asq.getAnnotation())
+ {
+
+ System.out.println("CalcId: " + aa.getCalcId());
+ assertTrue(MCview.PDBfile.isCalcIdForFile(aa, pdbId));
+ }
+ }
+ }
+
+ @Test
+ public void checkAnnotationWiring()
+ {
+ assertTrue(al.getAlignmentAnnotation() != null);
+ // verify that all sequence annotation is doubly referenced
+ for (AlignmentAnnotation aa : al.getAlignmentAnnotation())
+ {
+ if (aa.sequenceRef != null)
+ {
+ assertTrue(al.getSequences().contains(aa.sequenceRef));
+ assertNotNull(aa.sequenceRef.getAnnotation());
+ boolean found = false;
+ for (AlignmentAnnotation sqan : aa.sequenceRef.getAnnotation())
+ {
+ if (sqan == aa)
+ {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(
+ "Couldn't find sequence associated annotation "
+ + aa.label
+ + " on the sequence it is associated with.\nSequence associated editing will fail.",
+ found);
+ }
+ }
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception
+ {
+ jalview.bin.Jalview.main(new String[]
+ { "-props", "test/src/jalview/io/testProps.jvprops" });
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception
+ {
+ jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
+
+ }
+
+ @Test
+ public void testJalviewProjectRelocationAnnotation() throws Exception
+ {
+
+ String inFile = "examples/1gaq.txt";
+ String tfile = File.createTempFile("JalviewTest", ".jvp")
+ .getAbsolutePath();
+ AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
+ inFile, FormatAdapter.FILE);
+ assertTrue("Didn't read input file " + inFile, af != null);
+ assertTrue("Failed to store as a project.",
+ af.saveAlignment(tfile, "Jalview"));
+ af.closeMenuItem_actionPerformed(true);
+ af = null;
+ af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(tfile,
+ FormatAdapter.FILE);
+ assertTrue("Failed to import new project", af != null);
+ for (SequenceI asq : af.getViewport().getAlignment().getSequences())
+ {
+ SequenceI sq = asq;
+ while (sq.getDatasetSequence() != null)
+ {
+ sq = sq.getDatasetSequence();
+ }
+ assertNotNull(sq.getPDBId());
+ assertEquals("Expected only one PDB ID", sq.getPDBId().size(), 1);
+ for (PDBEntry pdbentry : (Vector<PDBEntry>) sq.getPDBId())
+ {
+ System.err.println("PDB Entry " + pdbentry.getId() + " "
+ + pdbentry.getFile());
+ boolean exists = false, found = false;
+ for (AlignmentAnnotation ana : sq.getAnnotation())
+ {
+ System.err.println("CalcId " + ana.getCalcId());
+ if (ana.getCalcId() != null
+ && MCview.PDBfile.isCalcIdHandled(ana.getCalcId()))
+ {
+ exists = true;
+ if (MCview.PDBfile.isCalcIdForFile(ana,
+ pdbentry.getId()))
+ {
+ found = true;
+ }
+ }
+ }
+ if (exists)
+ {
+ assertTrue("Couldn't find any annotation for " + pdbentry.getId()
+ + " (file handle " + pdbentry.getFile() + ")", found);
+ }
+ }
+ }
+ }
+}
--- /dev/null
+package jalview.io;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.SequenceI;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+/**
+ * Test file for {@link PhylipFile}.
+ *
+ * Tests use example data obtained from <a
+ * href="http://www.molecularevolution.org/resources/fileformats"
+ * >molecularrevolution.org<a>.
+ *
+ * @author David Corsar
+ *
+ */
+public class PhylipFileTests
+{
+
+ // interleaved file from
+ // http://www.molecularevolution.org/molevolfiles/fileformats/dna.phy.dat
+ // sequential file is the interleave file converted into sequential format
+
+ static String sequentialFile = "examples/dna_sequential.phy",
+ interleavedFile = "examples/dna_interleaved.phy";
+
+ /**
+ * Creates a name:sequence map for the data in the above files
+ *
+ * @return
+ */
+ private static Map<String, String> getTestData()
+ {
+ Map<String, String> data = new HashMap<String, String>();
+ data.put(
+ "Cow",
+ "ATGGCATATCCCATACAACTAGGATTCCAAGATGCAACATCACCAATCATAGAAGAACTACTTCACTTTCATGACCACACGCTAATAATTGTCTTCTTAATTAGCTCATTAGTACTTTACATTATTTCACTAATACTAACGACAAAGCTGACCCATACAAGCACGATAGATGCACAAGAAGTAGAGACAATCTGAACCATTCTGCCCGCCATCATCTTAATTCTAATTGCTCTTCCTTCTTTACGAATTCTATACATAATAGATGAAATCAATAACCCATCTCTTACAGTAAAAACCATAGGACATCAGTGATACTGAAGCTATGAGTATACAGATTATGAGGACTTAAGCTTCGACTCCTACATAATTCCAACATCAGAATTAAAGCCAGGGGAGCTACGACTATTAGAAGTCGATAATCGAGTTGTACTACCAATAGAAATAACAATCCGAATGTTAGTCTCCTCTGAAGACGTATTACACTCATGAGCTGTGCCCTCTCTAGGACTAAAAACAGACGCAATCCCAGGCCGTCTAAACCAAACAACCCTTATATCGTCCCGTCCAGGCTTATATTACGGTCAATGCTCAGAAATTTGCGGGTCAAACCACAGTTTCATACCCATTGTCCTTGAGTTAGTCCCACTAAAGTACTTTGAAAAATGATCTGCGTCAATATTA---------------------TAA");
+ data.put(
+ "Carp",
+ "ATGGCACACCCAACGCAACTAGGTTTCAAGGACGCGGCCATACCCGTTATAGAGGAACTTCTTCACTTCCACGACCACGCATTAATAATTGTGCTCCTAATTAGCACTTTAGTTTTATATATTATTACTGCAATGGTATCAACTAAACTTACTAATAAATATATTCTAGACTCCCAAGAAATCGAAATCGTATGAACCATTCTACCAGCCGTCATTTTAGTACTAATCGCCCTGCCCTCCCTACGCATCCTGTACCTTATAGACGAAATTAACGACCCTCACCTGACAATTAAAGCAATAGGACACCAATGATACTGAAGTTACGAGTATACAGACTATGAAAATCTAGGATTCGACTCCTATATAGTACCAACCCAAGACCTTGCCCCCGGACAATTCCGACTTCTGGAAACAGACCACCGAATAGTTGTTCCAATAGAATCCCCAGTCCGTGTCCTAGTATCTGCTGAAGACGTGCTACATTCTTGAGCTGTTCCATCCCTTGGCGTAAAAATGGACGCAGTCCCAGGACGACTAAATCAAGCCGCCTTTATTGCCTCACGCCCAGGGGTCTTTTACGGACAATGCTCTGAAATTTGTGGAGCTAATCACAGCTTTATACCAATTGTAGTTGAAGCAGTACCTCTCGAACACTTCGAAAACTGATCCTCATTAATACTAGAAGACGCCTCGCTAGGAAGCTAA");
+ data.put(
+ "Chicken",
+ "ATGGCCAACCACTCCCAACTAGGCTTTCAAGACGCCTCATCCCCCATCATAGAAGAGCTCGTTGAATTCCACGACCACGCCCTGATAGTCGCACTAGCAATTTGCAGCTTAGTACTCTACCTTCTAACTCTTATACTTATAGAAAAACTATCA---TCAAACACCGTAGATGCCCAAGAAGTTGAACTAATCTGAACCATCCTACCCGCTATTGTCCTAGTCCTGCTTGCCCTCCCCTCCCTCCAAATCCTCTACATAATAGACGAAATCGACGAACCTGATCTCACCCTAAAAGCCATCGGACACCAATGATACTGAACCTATGAATACACAGACTTCAAGGACCTCTCATTTGACTCCTACATAACCCCAACAACAGACCTCCCCCTAGGCCACTTCCGCCTACTAGAAGTCGACCATCGCATTGTAATCCCCATAGAATCCCCCATTCGAGTAATCATCACCGCTGATGACGTCCTCCACTCATGAGCCGTACCCGCCCTCGGGGTAAAAACAGACGCAATCCCTGGACGACTAAATCAAACCTCCTTCATCACCACTCGACCAGGAGTGTTTTACGGACAATGCTCAGAAATCTGCGGAGCTAACCACAGCTACATACCCATTGTAGTAGAGTCTACCCCCCTAAAACACTTTGAAGCCTGATCCTCACTA------------------CTGTCATCTTAA");
+ data.put(
+ "Human",
+ "ATGGCACATGCAGCGCAAGTAGGTCTACAAGACGCTACTTCCCCTATCATAGAAGAGCTTATCACCTTTCATGATCACGCCCTCATAATCATTTTCCTTATCTGCTTCCTAGTCCTGTATGCCCTTTTCCTAACACTCACAACAAAACTAACTAATACTAACATCTCAGACGCTCAGGAAATAGAAACCGTCTGAACTATCCTGCCCGCCATCATCCTAGTCCTCATCGCCCTCCCATCCCTACGCATCCTTTACATAACAGACGAGGTCAACGATCCCTCCCTTACCATCAAATCAATTGGCCACCAATGGTACTGAACCTACGAGTACACCGACTACGGCGGACTAATCTTCAACTCCTACATACTTCCCCCATTATTCCTAGAACCAGGCGACCTGCGACTCCTTGACGTTGACAATCGAGTAGTACTCCCGATTGAAGCCCCCATTCGTATAATAATTACATCACAAGACGTCTTGCACTCATGAGCTGTCCCCACATTAGGCTTAAAAACAGATGCAATTCCCGGACGTCTAAACCAAACCACTTTCACCGCTACACGACCGGGGGTATACTACGGTCAATGCTCTGAAATCTGTGGAGCAAACCACAGTTTCATGCCCATCGTCCTAGAATTAATTCCCCTAAAAATCTTTGAAATA---------------------GGGCCCGTATTTACCCTATAG");
+ data.put(
+ "Loach",
+ "ATGGCACATCCCACACAATTAGGATTCCAAGACGCGGCCTCACCCGTAATAGAAGAACTTCTTCACTTCCATGACCATGCCCTAATAATTGTATTTTTGATTAGCGCCCTAGTACTTTATGTTATTATTACAACCGTCTCAACAAAACTCACTAACATATATATTTTGGACTCACAAGAAATTGAAATCGTATGAACTGTGCTCCCTGCCCTAATCCTCATTTTAATCGCCCTCCCCTCACTACGAATTCTATATCTTATAGACGAGATTAATGACCCCCACCTAACAATTAAGGCCATGGGGCACCAATGATACTGAAGCTACGAGTATACTGATTATGAAAACTTAAGTTTTGACTCCTACATAATCCCCACCCAGGACCTAACCCCTGGACAATTCCGGCTACTAGAGACAGACCACCGAATGGTTGTTCCCATAGAATCCCCTATTCGCATTCTTGTTTCCGCCGAAGATGTACTACACTCCTGGGCCCTTCCAGCCATGGGGGTAAAGATAGACGCGGTCCCAGGACGCCTTAACCAAACCGCCTTTATTGCCTCCCGCCCCGGGGTATTCTATGGGCAATGCTCAGAAATCTGTGGAGCAAACCACAGCTTTATACCCATCGTAGTAGAAGCGGTCCCACTATCTCACTTCGAAAACTGGTCCACCCTTATACTAAAAGACGCCTCACTAGGAAGCTAA");
+ data.put(
+ "Mouse",
+ "ATGGCCTACCCATTCCAACTTGGTCTACAAGACGCCACATCCCCTATTATAGAAGAGCTAATAAATTTCCATGATCACACACTAATAATTGTTTTCCTAATTAGCTCCTTAGTCCTCTATATCATCTCGCTAATATTAACAACAAAACTAACACATACAAGCACAATAGATGCACAAGAAGTTGAAACCATTTGAACTATTCTACCAGCTGTAATCCTTATCATAATTGCTCTCCCCTCTCTACGCATTCTATATATAATAGACGAAATCAACAACCCCGTATTAACCGTTAAAACCATAGGGCACCAATGATACTGAAGCTACGAATATACTGACTATGAAGACCTATGCTTTGATTCATATATAATCCCAACAAACGACCTAAAACCTGGTGAACTACGACTGCTAGAAGTTGATAACCGAGTCGTTCTGCCAATAGAACTTCCAATCCGTATATTAATTTCATCTGAAGACGTCCTCCACTCATGAGCAGTCCCCTCCCTAGGACTTAAAACTGATGCCATCCCAGGCCGACTAAATCAAGCAACAGTAACATCAAACCGACCAGGGTTATTCTATGGCCAATGCTCTGAAATTTGTGGATCTAACCATAGCTTTATGCCCATTGTCCTAGAAATGGTTCCACTAAAATATTTCGAAAACTGATCTGCTTCAATAATT---------------------TAA");
+ data.put(
+ "Rat",
+ "ATGGCTTACCCATTTCAACTTGGCTTACAAGACGCTACATCACCTATCATAGAAGAACTTACAAACTTTCATGACCACACCCTAATAATTGTATTCCTCATCAGCTCCCTAGTACTTTATATTATTTCACTAATACTAACAACAAAACTAACACACACAAGCACAATAGACGCCCAAGAAGTAGAAACAATTTGAACAATTCTCCCAGCTGTCATTCTTATTCTAATTGCCCTTCCCTCCCTACGAATTCTATACATAATAGACGAGATTAATAACCCAGTTCTAACAGTAAAAACTATAGGACACCAATGATACTGAAGCTATGAATATACTGACTATGAAGACCTATGCTTTGACTCCTACATAATCCCAACCAATGACCTAAAACCAGGTGAACTTCGTCTATTAGAAGTTGATAATCGGGTAGTCTTACCAATAGAACTTCCAATTCGTATACTAATCTCATCCGAAGACGTCCTGCACTCATGAGCCATCCCTTCACTAGGGTTAAAAACCGACGCAATCCCCGGCCGCCTAAACCAAGCTACAGTCACATCAAACCGACCAGGTCTATTCTATGGCCAATGCTCTGAAATTTGCGGCTCAAATCACAGCTTCATACCCATTGTACTAGAAATAGTGCCTCTAAAATATTTCGAAAACTGATCAGCTTCTATAATT---------------------TAA");
+ data.put(
+ "Seal",
+ "ATGGCATACCCCCTACAAATAGGCCTACAAGATGCAACCTCTCCCATTATAGAGGAGTTACTACACTTCCATGACCACACATTAATAATTGTGTTCCTAATTAGCTCATTAGTACTCTACATTATCTCACTTATACTAACCACGAAACTCACCCACACAAGTACAATAGACGCACAAGAAGTGGAAACGGTGTGAACGATCCTACCCGCTATCATTTTAATTCTCATTGCCCTACCATCATTACGAATCCTCTACATAATGGACGAGATCAATAACCCTTCCTTGACCGTAAAAACTATAGGACATCAGTGATACTGAAGCTATGAGTACACAGACTACGAAGACCTGAACTTTGACTCATATATGATCCCCACACAAGAACTAAAGCCCGGAGAACTACGACTGCTAGAAGTAGACAATCGAGTAGTCCTCCCAATAGAAATAACAATCCGCATACTAATCTCATCAGAAGATGTACTCCACTCATGAGCCGTACCGTCCCTAGGACTAAAAACTGATGCTATCCCAGGACGACTAAACCAAACAACCCTAATAACCATACGACCAGGACTGTACTACGGTCAATGCTCAGAAATCTGTGGTTCAAACCACAGCTTCATACCTATTGTCCTCGAATTGGTCCCACTATCCCACTTCGAGAAATGATCTACCTCAATGCTT---------------------TAA");
+ data.put(
+ "Whale",
+ "ATGGCATATCCATTCCAACTAGGTTTCCAAGATGCAGCATCACCCATCATAGAAGAGCTCCTACACTTTCACGATCATACACTAATAATCGTTTTTCTAATTAGCTCTTTAGTTCTCTACATTATTACCCTAATGCTTACAACCAAATTAACACATACTAGTACAATAGACGCCCAAGAAGTAGAAACTGTCTGAACTATCCTCCCAGCCATTATCTTAATTTTAATTGCCTTGCCTTCATTACGGATCCTTTACATAATAGACGAAGTCAATAACCCCTCCCTCACTGTAAAAACAATAGGTCACCAATGATATTGAAGCTATGAGTATACCGACTACGAAGACCTAAGCTTCGACTCCTATATAATCCCAACATCAGACCTAAAGCCAGGAGAACTACGATTATTAGAAGTAGATAACCGAGTTGTCTTACCTATAGAAATAACAATCCGAATATTAGTCTCATCAGAAGACGTACTCCACTCATGGGCCGTACCCTCCTTGGGCCTAAAAACAGATGCAATCCCAGGACGCCTAAACCAAACAACCTTAATATCAACACGACCAGGCCTATTTTATGGACAATGCTCAGAGATCTGCGGCTCAAACCACAGTTTCATACCAATTGTCCTAGAACTAGTACCCCTAGAAGTCTTTGAAAAATGATCTGTATCAATACTA---------------------TAA");
+ data.put(
+ "Frog",
+ "ATGGCACACCCATCACAATTAGGTTTTCAAGACGCAGCCTCTCCAATTATAGAAGAATTACTTCACTTCCACGACCATACCCTCATAGCCGTTTTTCTTATTAGTACGCTAGTTCTTTACATTATTACTATTATAATAACTACTAAACTAACTAATACAAACCTAATGGACGCACAAGAGATCGAAATAGTGTGAACTATTATACCAGCTATTAGCCTCATCATAATTGCCCTTCCATCCCTTCGTATCCTATATTTAATAGATGAAGTTAATGATCCACACTTAACAATTAAAGCAATCGGCCACCAATGATACTGAAGCTACGAATATACTAACTATGAGGATCTCTCATTTGACTCTTATATAATTCCAACTAATGACCTTACCCCTGGACAATTCCGGCTGCTAGAAGTTGATAATCGAATAGTAGTCCCAATAGAATCTCCAACCCGACTTTTAGTTACAGCCGAAGACGTCCTCCACTCGTGAGCTGTACCCTCCTTGGGTGTCAAAACAGATGCAATCCCAGGACGACTTCATCAAACATCATTTATTGCTACTCGTCCGGGAGTATTTTACGGACAATGTTCAGAAATTTGCGGAGCAAACCACAGCTTTATACCAATTGTAGTTGAAGCAGTACCGCTAACCGACTTTGAAAACTGATCTTCATCAATACTA---GAAGCATCACTA------AGA");
+ return data;
+ }
+
+ /**
+ * Tests sequential format file is read correctly by comparing read sequence
+ * with that in the test data.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testSequentialDataExtraction() throws Exception
+ {
+ testDataExtraction(sequentialFile);
+ }
+
+ /**
+ * Tests interleaved format file is read correctly by comparing read sequence
+ * with that in the test data.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testInterleavedDataExtraction() throws Exception
+ {
+ testDataExtraction(interleavedFile);
+ }
+
+ /**
+ * Tests a PHYLIP file is read correctly by comparing read sequence with that
+ * in the test data.
+ *
+ * @throws Exception
+ */
+ private void testDataExtraction(String file) throws IOException
+ {
+ AppletFormatAdapter rf = new AppletFormatAdapter();
+ Alignment al = rf.readFile(file, AppletFormatAdapter.FILE,
+ PhylipFile.FILE_DESC);
+ assertNotNull("Couldn't read supplied alignment data.", al);
+
+ Map<String, String> data = PhylipFileTests.getTestData();
+ for (SequenceI s : al.getSequencesArray())
+ {
+ assertTrue(s.getName() + " sequence did not match test data.", data
+ .get(s.getName()).equals(s.getSequenceAsString()));
+ }
+ }
+
+ /**
+ * Tests sequential format file reading and writing without data lose using
+ * similar approach to {@link StockholmFileTest}
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testSequentialIO() throws Exception
+ {
+ testIO(sequentialFile);
+ }
+
+ /**
+ * Tests interleaved format file reading and writing without data lose using
+ * similar approach to {@link StockholmFileTest}
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testInterleavedIO() throws Exception
+ {
+ testIO(interleavedFile);
+ }
+
+ /**
+ * Uses {@link StockholmFileTest} to test read/write/read
+ *
+ * @param file
+ * @throws IOException
+ */
+ public void testIO(String file) throws IOException
+ {
+ AppletFormatAdapter rf = new AppletFormatAdapter();
+ Alignment al = rf.readFile(file, AppletFormatAdapter.FILE,
+ PhylipFile.FILE_DESC);
+ assertNotNull("Couldn't read supplied alignment data.", al);
+
+ String outputfile = rf.formatSequences(PhylipFile.FILE_DESC, al, true);
+
+ Alignment al_input = new AppletFormatAdapter().readFile(outputfile,
+ AppletFormatAdapter.PASTE, PhylipFile.FILE_DESC);
+ assertNotNull("Couldn't parse reimported alignment data.", al_input);
+
+ StockholmFileTest.testAlignmentEquivalence(al, al_input);
+
+ }
+}
\ No newline at end of file
--- /dev/null
+>1PHT
+YQYRALYDYKKEREEDIDLHLGDILTVNKGSLVALGFSDGQEARPEEI--
+--------GWLNGYNETTGERGDFPGTYVEYIG
+>1BB9
+FKVQAQHDYTATDTDELQLKAGDVVLVIP-------FQNP----EEQDEG
+WLMGVKESDWNQHK-ELEKCRGVFPENFTERVQ
+>1UHC
+QVYFAVYTFKARNPNELSVSANQKLKILE-------FKDV----TGNT--
+--------EWWLAE--VNGKKGYVPSNYIRKTE
+>1YCS
+GVIYALWDYEPQNDDELPMKEGDCMTIIH-------REDE----D-EI--
+--------EWWWA--RLNDKEGYVPRNLLGLYP
+>1OOT
+PKAVALYSFAGEESGDLPFRKGDVITILKK-------S------DSQN--
+--------DWWTG--RVNGREGIFPANYVE-LV
+>1ABO
+NLFVALYDFVASGDNTLSITKGEKLRVLG-------YNH-------NG--
+--------EWCEAQ--TKNGQGWVPSNYITPVN
+>1FYN
+TLFVALYDYEARTEDDLSFHKGEKFQILN-------SS--------EG--
+--------DWWEARSLTTGETGYIPSNYVAPVD
+>1QCF
+IIVVALYDYEAIHHEDLSFQKGDQMVVLE-------E---------SG--
+--------EWWKARSLATRKEGYIPSNYVARVD
\ No newline at end of file
--- /dev/null
+package jalview.structure;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.io.FileLoader;
+import jalview.io.FormatAdapter;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import MCview.PDBfile;
+
+public class Mapping
+{
+
+ /*
+ * more test data
+ *
+ * 1QCF|A/101-121 SFQKGDQMVVLEESGEWWKAR Ser 114 jumps to Gly 116 at position
+ * 115 in PDB Res Numbering secondary structure numbers in jmol seem to be in
+ * msd numbering, not pdb res numbering.
+ */
+ @Test
+ public void pdbEntryPositionMap() throws Exception
+ {
+ fail("This test intentionally left to fail");
+ for (int offset = 0; offset < 20; offset += 6)
+ {
+ // check we put the secondary structure in the right position
+ Sequence uprot = new Sequence("TheProtSeq",
+ "DAWEIPRESLKLEKKLGAGQFGEVWMATYNKHTKVAVKTMKPGSMSVEAFLAEANVMKTL");
+ uprot.setStart(offset + 258); // make it harder - create a fake
+ // relocation problem for jalview to
+ // deal with
+ uprot.setEnd(uprot.getStart() + uprot.getLength() - 1);
+ // original numbers taken from
+ // http://www.ebi.ac.uk/pdbe-srv/view/entry/1qcf/secondary.html
+ // these are in numbering relative to the subsequence above
+ int coils[] =
+ { 266, 275, 278, 287, 289, 298, 302, 316 }, helices[] = new int[]
+ { 303, 315 }, sheets[] = new int[]
+ { 267, 268, 269, 270 };
+
+ StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
+ PDBfile pmap = ssm.setMapping(true, new SequenceI[]
+ { uprot }, new String[]
+ { "A" }, "test/jalview/ext/jmol/1QCF.pdb",
+ jalview.io.FormatAdapter.FILE);
+ assertTrue(pmap != null);
+ SequenceI protseq = pmap.getSeqsAsArray()[0];
+ AlignmentAnnotation pstra = protseq
+ .getAnnotation("Secondary Structure")[0];
+ int pinds, pinde;
+ pstra.restrict((pinds = protseq.findIndex(258) - 1),
+ pinde = (protseq.findIndex(317) - 1));
+ int op;
+ System.out.println("PDB Annot");
+ for (char c : protseq.getSubSequence(pinds, pinde).getSequence())
+ {
+ System.out.print(c + ", ");
+ }
+ System.out.println("\n" + pstra + "\n\nsubsequence\n");
+ for (char c : uprot.getSequence())
+ {
+ System.out.print(c + ", ");
+ }
+ System.out.println("");
+ for (AlignmentAnnotation ss : uprot
+ .getAnnotation("Secondary Structure"))
+ {
+ ss.adjustForAlignment();
+ System.out.println("Uniprot Annot\n" + ss);
+ assertTrue(ss.hasIcons);
+ char expected = 'H';
+ for (int p : helices)
+ {
+ Annotation a = ss.annotations[op = (uprot.findIndex(offset + p) - 1)];
+ assertTrue(
+ "Expected a helix at position " + p + uprot.getCharAt(op)
+ + " but got coil", a != null);
+ assertEquals("Expected a helix at position " + p,
+ a.secondaryStructure, expected);
+ }
+ expected = 'E';
+ for (int p : sheets)
+ {
+ Annotation a = ss.annotations[uprot.findIndex(offset + p) - 1];
+ assertTrue(
+ "Expected a strand at position " + p + " but got coil",
+ a != null);
+ assertEquals("Expected a strand at position " + p,
+ a.secondaryStructure, expected);
+ }
+ expected = ' ';
+ for (int p : coils)
+ {
+ Annotation a = ss.annotations[uprot.findIndex(offset + p) - 1];
+ assertTrue("Expected coil at position " + p + " but got "
+ + a.secondaryStructure, a == null);
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testPDBentryMapping() throws Exception
+ {
+ fail("This test intentionally left to fail");
+ Sequence sq = new Sequence(
+ "1GAQ A subseq 126 to 219",
+ "EIVKGVCSNFLCDLQPGDNVQITGPVGKEMLMPKDPNATIIMLATGTGIAPFRSFLWKMFFEKHDDYKFNGLGWLFLGVPTSSSLLYKEEFGKM");
+ Sequence sq1 = new Sequence(sq);
+ String inFile;
+ StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
+ // Associate the 1GAQ pdb file with the subsequence 'imported' from another
+ // source
+ PDBfile pde = ssm.setMapping(true, new SequenceI[]
+ { sq }, new String[]
+ { "A" }, inFile = "examples/1gaq.txt", jalview.io.FormatAdapter.FILE);
+ assertTrue("PDB File couldn't be found", pde != null);
+ StructureMapping[] mp = ssm.getMapping(inFile);
+ assertTrue("No mappings made.", mp != null && mp.length > 0);
+ int nsecStr = 0, nsTemp = 0;
+ // test for presence of transferred annotation on sequence
+ for (AlignmentAnnotation alan : sq.getAnnotation())
+ {
+ if (alan.hasIcons)
+ {
+ nsecStr++;
+ }
+ if (alan.graph == alan.LINE_GRAPH)
+ {
+ nsTemp++;
+ }
+ }
+ assertEquals(
+ "Only one secondary structure should be transferred to associated sequence.",
+ 1, nsecStr);
+ assertEquals(
+ "Only two line graphs should be transferred to associated sequence.",
+ 2, nsTemp);
+ // Now test the transfer function and compare annotated positions
+ for (StructureMapping origMap : mp)
+ {
+ if (origMap.getSequence() == sq)
+ {
+ assertEquals("Mapping was incomplete.", sq.getLength() - 1,
+ (origMap.getPDBResNum(sq.getEnd()) - origMap
+ .getPDBResNum(sq.getStart())));
+ // sanity check - if this fails, mapping from first position in sequence
+ // we want to transfer to is not where we expect
+ assertEquals(1, origMap.getSeqPos(126));
+ SequenceI firstChain = pde.getSeqs().get(0);
+ // Compare the annotated positions on the PDB chain sequence with the
+ // annotation on the associated sequence
+ for (AlignmentAnnotation alan : firstChain.getAnnotation())
+ {
+ AlignmentAnnotation transfer = origMap.transfer(alan);
+ System.out.println("pdb:" + firstChain.getSequenceAsString());
+ System.out.println("ann:" + alan.toString());
+ System.out.println("pdb:" + sq.getSequenceAsString());
+ System.out.println("ann:" + transfer.toString());
+
+ for (int p = 0, pSize = firstChain.getLength(); p < pSize; p++)
+ {
+ // walk along the pdb chain's jalview sequence
+ int rseqpos;
+ int fpos = origMap.getSeqPos(rseqpos = firstChain
+ .findPosition(p));
+ // only look at positions where there is a corresponding position in
+ // mapping
+ if (fpos < 1)
+ {
+ continue;
+ }
+ // p is index into PDB residue entries
+ // rseqpos is pdb sequence position for position p
+ // fpos is sequence position for associated position for rseqpos
+ // tanpos is the column for the mapped sequence position
+ int tanpos = sq.findIndex(fpos) - 1;
+ if (tanpos < 0 || transfer.annotations.length <= tanpos)
+ {
+ // gone beyond mapping to the sequence
+ break;
+ }
+
+ Annotation a = transfer.annotations[tanpos], b = alan.annotations[p];
+ assertEquals("Non-equivalent annotation element at " + p + "("
+ + rseqpos + ")" + " expected at " + fpos + " (alIndex "
+ + tanpos + ")",
+ a == null ? a : a.toString(),
+ b == null ? b : b.toString());
+ System.out.print("(" + a + "|" + b + ")");
+ }
+
+ }
+ }
+ }
+ }
+
+ /**
+ * corner case for pdb mapping - revealed a problem with the AlignSeq->Mapping
+ * transform
+ *
+ */
+ @Test
+ public void mapFer1From3W5V() throws Exception
+ {
+ AlignFrame seqf = new FileLoader(false)
+ .LoadFileWaitTillLoaded(
+ ">FER1_MAIZE/1-150 Ferredoxin-1, chloroplast precursor\nMATVLGSPRAPAFFFSSSSLRAAPAPTAVALPAAKVGIMGRSASSRRRLRAQATYNVKLITPEGEVELQVPD\nDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSYLDDGQIADGWVLTCHAYPTSDVVIETHKE\nEELTGA",
+ FormatAdapter.PASTE, "FASTA");
+ SequenceI newseq = seqf.getViewport().getAlignment().getSequenceAt(0);
+ StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
+ PDBfile pmap = ssm.setMapping(true, new SequenceI[]
+ { newseq }, new String[]
+ { null }, "examples/3W5V.pdb",
+ jalview.io.FormatAdapter.FILE);
+ if (pmap == null)
+ {
+ Assert.fail("Couldn't make a mapping for 3W5V to FER1_MAIZE");
+ }
+ }
+
+ /**
+ * compare reference annotation for imported pdb sequence to identical
+ * seuqence with transferred annotation from mapped pdb file
+ */
+ @Test
+ public void compareTransferredToRefPDBAnnot() throws Exception
+ {
+ AlignFrame ref = new FileLoader(false)
+ .LoadFileWaitTillLoaded("test/jalview/ext/jmol/1QCF.pdb",
+ jalview.io.FormatAdapter.FILE);
+ SequenceI refseq = ref.getViewport().getAlignment().getSequenceAt(0);
+ SequenceI newseq = new Sequence(refseq.getName() + "Copy",
+ refseq.getSequenceAsString());
+ // make it harder by shifting the copy vs the reference
+ newseq.setStart(refseq.getStart() + 25);
+ newseq.setEnd(refseq.getLength() + 25 + refseq.getStart());
+ StructureSelectionManager ssm = new jalview.structure.StructureSelectionManager();
+ PDBfile pmap = ssm.setMapping(true, new SequenceI[]
+ { newseq }, new String[]
+ { null }, "test/jalview/ext/jmol/1QCF.pdb",
+ jalview.io.FormatAdapter.FILE);
+ assertTrue(pmap != null);
+ assertEquals("Original and copied sequence of different lengths.",
+ refseq.getLength(), newseq.getLength());
+ assertTrue(refseq.getAnnotation().length > 0
+ && newseq.getAnnotation().length > 0);
+ for (AlignmentAnnotation oannot : refseq.getAnnotation())
+ {
+ for (AlignmentAnnotation tannot : newseq.getAnnotation(oannot.label))
+ {
+ for (int p = 0, pSize = refseq.getLength(); p < pSize; p++)
+ {
+ Annotation orig = oannot.annotations[p], tran = tannot.annotations[p];
+ assertTrue("Mismatch: coil and non coil site " + p, orig == tran
+ || orig != null && tran != null);
+ if (tran != null)
+ {
+ assertEquals("Mismatch in secondary structure at site " + p,
+ tran.secondaryStructure, orig.secondaryStructure);
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+package jalview.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.awt.Color;
+
+import org.junit.Test;
+
+public class ColorUtilsTest
+{
+
+ Color paleColour = new Color(97, 203, 111); // pale green
+
+ Color midColour = new Color(135, 57, 41); // mid red
+
+ Color darkColour = new Color(11, 30, 50); // dark blue
+
+ @Test
+ public void testDarkerThan()
+ {
+ assertEquals("Wrong darker shade", new Color(32, 69, 37),
+ ColorUtils.darkerThan(paleColour));
+ assertEquals("Wrong darker shade", new Color(45, 18, 13),
+ ColorUtils.darkerThan(midColour));
+ assertEquals("Wrong darker shade", new Color(2, 9, 16),
+ ColorUtils.darkerThan(darkColour));
+ assertNull(ColorUtils.darkerThan(null));
+ }
+
+ @Test
+ public void testBrighterThan()
+ {
+ assertEquals("Wrong brighter shade", new Color(255, 255, 255), // white
+ ColorUtils.brighterThan(paleColour));
+ assertEquals("Wrong brighter shade", new Color(255, 164, 117),
+ ColorUtils.brighterThan(midColour));
+ assertEquals("Wrong brighter shade", new Color(30, 85, 144),
+ ColorUtils.brighterThan(darkColour));
+ assertNull(ColorUtils.brighterThan(null));
+ }
+}
}
@Test
- public void testPdbPerChainRetrieve() throws Exception
- {
- List<DbSourceProxy> sps = sf.getSourceProxy("PDB");
- AlignmentI response = sps.get(0).getSequenceRecords("1QIPA");
- assertTrue(response != null);
- assertTrue(response.getHeight() == 1);
- }
-
- @Test
public void testRnaSeqRetrieve() throws Exception
{
List<DbSourceProxy> sps = sf.getSourceProxy("PDB");
import static org.junit.Assert.*;
import jalview.gui.WsJobParameters;
+import jalview.util.MessageManager;
import jalview.ws.jabaws.JalviewJabawsTestUtils;
import jalview.ws.jws2.JabaPreset;
import jalview.ws.jws2.Jws2Discoverer;
}
WsJobParameters pgui = new WsJobParameters(lastserv,
new JabaPreset(lastserv, pr));
- JFrame jf = new JFrame("Parameters for "
- + lastserv.getActionText());
+ JFrame jf = new JFrame(MessageManager.formatMessage("label.ws_parameters_for", new String[]{lastserv.getActionText()}));
JPanel cont = new JPanel(new BorderLayout());
pgui.validate();
cont.setPreferredSize(pgui.getPreferredSize());
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview 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.
+ *
+ * Jalview 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 Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ws.jabaws;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import jalview.datamodel.AlignmentI;
+import jalview.gui.Jalview2XML;
+import jalview.io.AnnotationFile;
+import jalview.io.FormatAdapter;
+import jalview.io.StockholmFileTest;
+import jalview.ws.jws2.JPred301Client;
+import jalview.ws.jws2.JabaParamStore;
+import jalview.ws.jws2.Jws2Discoverer;
+import jalview.ws.jws2.SequenceAnnotationWSClient;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.ArgumentI;
+import jalview.ws.params.AutoCalcSetting;
+
+import java.awt.Component;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import compbio.metadata.Argument;
+import compbio.metadata.WrongParameterException;
+
+public class JpredJabaStructExportImport
+{
+ public static String testseqs = "examples/uniref50.fa";
+
+ public static Jws2Discoverer disc;
+
+ public static Jws2Instance jpredws;
+
+ jalview.ws.jws2.JPred301Client jpredClient;
+
+ public static jalview.gui.AlignFrame af = null;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception
+ {
+
+ jalview.bin.Cache.initLogger();
+ disc = JalviewJabawsTestUtils.getJabawsDiscoverer(false);
+
+ for (Jws2Instance svc : disc.getServices())
+ {
+
+ if (svc.getServiceTypeURI().toLowerCase().contains("jpred"))
+ {
+ jpredws = svc;
+ }
+ }
+
+ System.out.println("State of jpredws: " + jpredws);
+
+ if (jpredws == null)
+ System.exit(0);
+
+ jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
+
+ af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.FormatAdapter.FILE);
+
+ assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
+
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception
+ {
+ if (af != null)
+ {
+ af.setVisible(false);
+ af.dispose();
+ }
+ }
+
+ @Test
+ public void testJPredStructOneSeqOnly()
+ {
+ af.selectAllSequenceMenuItem_actionPerformed(null);
+ af.getViewport()
+ .getSelectionGroup()
+ .addOrRemove(
+ af.getViewport().getSelectionGroup().getSequenceAt(0),
+ false);
+ af.hideSelSequences_actionPerformed(null);
+ jpredClient = new JPred301Client(jpredws, af, null, null);
+
+ assertTrue(
+ "Didn't find any default args to check for. Buggy implementation of hardwired arguments in client.",
+ jpredClient.selectDefaultArgs().size() > 0);
+
+ boolean success = false;
+ af.getViewport().getCalcManager().startWorker(jpredClient);
+ do
+ {
+ try
+ {
+ Thread.sleep(500);
+ List<Argument> args = JabaParamStore.getJabafromJwsArgs(af
+ .getViewport()
+ .getCalcIdSettingsFor(jpredClient.getCalcId())
+ .getArgumentSet()), defargs = jpredClient
+ .selectDefaultArgs();
+ for (Argument rg : args)
+ {
+ for (Argument defg : defargs)
+ {
+ if (defg.equals(rg))
+ {
+ success = true;
+ }
+ }
+ }
+ if (!success)
+ {
+ jpredClient.cancelCurrentJob();
+ fail("Jpred Client didn't run with hardwired default parameters.");
+ }
+
+ } catch (InterruptedException x)
+ {
+ }
+ ;
+ } while (af.getViewport().getCalcManager().isWorking());
+
+ }
+
+ @Test
+ public void testJPredStructExport()
+ {
+
+ jpredClient = new JPred301Client(jpredws, af, null, null);
+
+ af.getViewport().getCalcManager().startWorker(jpredClient);
+
+ do
+ {
+ try
+ {
+ Thread.sleep(50);
+ } catch (InterruptedException x)
+ {
+ }
+ ;
+ } while (af.getViewport().getCalcManager().isWorking());
+
+ AlignmentI orig_alig = af.getViewport().getAlignment();
+
+ testAnnotationFileIO("Testing JPredWS Annotation IO", orig_alig);
+
+ }
+
+ public static void testAnnotationFileIO(String testname, AlignmentI al)
+ {
+ try
+ {
+ // what format would be appropriate for RNAalifold annotations?
+ String aligfileout = new FormatAdapter().formatSequences("PFAM",
+ al.getSequencesArray());
+
+ String anfileout = new AnnotationFile().printAnnotations(
+ al.getAlignmentAnnotation(), al.getGroups(),
+ al.getProperties());
+ assertTrue(
+ "Test "
+ + testname
+ + "\nAlignment annotation file was not regenerated. Null string",
+ anfileout != null);
+ assertTrue(
+ "Test "
+ + testname
+ + "\nAlignment annotation file was not regenerated. Empty string",
+ anfileout.length() > "JALVIEW_ANNOTATION".length());
+
+ System.out.println("Output annotation file:\n" + anfileout
+ + "\n<<EOF\n");
+
+ // again what format would be appropriate?
+ AlignmentI al_new = new FormatAdapter().readFile(aligfileout,
+ FormatAdapter.PASTE, "PFAM");
+ assertTrue(
+ "Test "
+ + testname
+ + "\nregenerated annotation file did not annotate alignment.",
+ new AnnotationFile().readAnnotationFile(al_new, anfileout,
+ FormatAdapter.PASTE));
+
+ // test for consistency in io
+ StockholmFileTest.testAlignmentEquivalence(al, al_new);
+ return;
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ fail("Test "
+ + testname
+ + "\nCouldn't complete Annotation file roundtrip input/output/input test.");
+ }
+
+ // @Test
+ public void testJpredwsSettingsRecovery()
+ {
+ fail("not implemnented");
+ List<compbio.metadata.Argument> opts = new ArrayList<compbio.metadata.Argument>();
+ for (compbio.metadata.Argument rg : (List<compbio.metadata.Argument>) jpredws
+ .getRunnerConfig().getArguments())
+ {
+ if (rg.getDescription().contains("emperature"))
+ {
+ try
+ {
+ rg.setValue("292");
+ } catch (WrongParameterException q)
+ {
+ fail("Couldn't set the temperature parameter "
+ + q.getStackTrace());
+ }
+ opts.add(rg);
+ }
+ if (rg.getDescription().contains("max"))
+ {
+ opts.add(rg);
+ }
+ }
+ jpredClient = new JPred301Client(jpredws, af, null, opts);
+
+ af.getViewport().getCalcManager().startWorker(jpredClient);
+
+ do
+ {
+ try
+ {
+ Thread.sleep(50);
+ } catch (InterruptedException x)
+ {
+ }
+ ;
+ } while (af.getViewport().getCalcManager().isWorking());
+ AutoCalcSetting oldacs = af.getViewport().getCalcIdSettingsFor(
+ jpredClient.getCalcId());
+ String oldsettings = oldacs.getWsParamFile();
+ // write out parameters
+ jalview.gui.AlignFrame nalf = null;
+ assertTrue("Couldn't write out the Jar file",
+ new Jalview2XML(false).SaveAlignment(af,
+ "testJPredWS_param.jar", "trial parameter writeout"));
+ assertTrue("Couldn't read back the Jar file", (nalf = new Jalview2XML(
+ false).LoadJalviewAlign("testJpredWS_param.jar")) != null);
+ if (nalf != null)
+ {
+ AutoCalcSetting acs = af.getViewport().getCalcIdSettingsFor(
+ jpredClient.getCalcId());
+ assertTrue("Calc ID settings not recovered from viewport stash",
+ acs.equals(oldacs));
+ assertTrue(
+ "Serialised Calc ID settings not identical to those recovered from viewport stash",
+ acs.getWsParamFile().equals(oldsettings));
+ JMenu nmenu = new JMenu();
+ new SequenceAnnotationWSClient()
+ .attachWSMenuEntry(nmenu, jpredws, af);
+ assertTrue("Couldn't get menu entry for service",
+ nmenu.getItemCount() > 0);
+ for (Component itm : nmenu.getMenuComponents())
+ {
+ if (itm instanceof JMenuItem)
+ {
+ JMenuItem i = (JMenuItem) itm;
+ if (i.getText().equals(
+ jpredws.getAlignAnalysisUI().getAAconToggle()))
+ {
+ i.doClick();
+ break;
+ }
+ }
+ }
+ while (af.getViewport().isCalcInProgress())
+ {
+ try
+ {
+ Thread.sleep(200);
+ } catch (Exception x)
+ {
+ }
+ ;
+ }
+ AutoCalcSetting acs2 = af.getViewport().getCalcIdSettingsFor(
+ jpredClient.getCalcId());
+ assertTrue(
+ "Calc ID settings after recalculation has not been recovered.",
+ acs2.getWsParamFile().equals(oldsettings));
+ }
+ }
+}
--- /dev/null
+package jalview.ws.jabaws;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import compbio.data.msa.MsaWS;
+import compbio.data.msa.RegistryWS;
+import compbio.data.sequence.FastaSequence;
+import compbio.metadata.JobStatus;
+import compbio.ws.client.Jws2Client;
+import compbio.ws.client.Services;
+
+public class MinJabawsClientTests {
+
+ /**
+ * simple test for the benefit of JAL-1338
+ * @throws Exception
+ */
+ @SuppressWarnings("rawtypes")
+ @Test
+ public void msaTest() throws Exception {
+ String url;
+ RegistryWS registry = Jws2Client
+ .connectToRegistry(url = "http://www.compbio.dundee.ac.uk/jabaws");
+ if (registry != null) {
+
+ MsaWS msaservice = null;
+ for (Services service : registry.getSupportedServices()) {
+ if (service.equals(Services.ClustalOWS)) {
+ msaservice = (MsaWS) Jws2Client.connect(url, service);
+ if (msaservice != null) {
+ break;
+ }
+ }
+ }
+ if (msaservice == null) {
+ fail("couldn't find a clustalO service on the public registry");
+ }
+ FastaSequence fsq = new FastaSequence("seqA",
+ "SESESESESESESESSESESSESESESESESESESESESEEEEEESSESESESESSSSESESESESESESE");
+ List<FastaSequence> iseqs = new ArrayList<FastaSequence>();
+ for (int i = 0; i < 9; i++) {
+ iseqs.add(new FastaSequence(fsq.getId() + i, fsq.getSequence()
+ + fsq.getSequence().substring(i + 3, i + 3 + i)));
+ }
+
+ String jobid = msaservice.align(iseqs);
+ if (jobid != null)
+ {
+ JobStatus js = null;
+ do
+ {
+ try
+ {
+ Thread.sleep(500);
+ } catch (InterruptedException q)
+ {
+ }
+ ;
+ js = msaservice.getJobStatus(jobid);
+ } while (!js.equals(JobStatus.FAILED)
+ && !js.equals(JobStatus.CANCELLED)
+ && !js.equals(JobStatus.FINISHED));
+ assertEquals("Trial alignment failed. State was " + js.name(), js,
+ JobStatus.FINISHED);
+ assertEquals(
+ "Mismatch in number of input and result sequences - assume alignment service wasn't interacted with correctly",
+ msaservice.getResult(jobid).getSequences().size(),
+ iseqs.size());
+ for (FastaSequence t : msaservice.getResult(jobid).getSequences())
+ {
+ System.out.println(">" + t.getId());
+ System.out.println(t.getFormattedFasta());
+ }
+ // .forEach(new Consumer<FastaSequence>() {
+ // @Override
+ // public void accept(FastaSequence t) {
+ // System.out.println(">"+t.getId());
+ // System.out.println(t.getFormattedFasta());
+ // }
+ // });
+ }
+
+ }
+ }
+}
--- /dev/null
+package jalview.ws.seqfetcher;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class DasSequenceFetcher
+{
+
+ @Test
+ public void testDasRegistryContact()
+ {
+ jalview.bin.Cache.getDasSourceRegistry().refreshSources();
+ assertTrue(
+ "Expected to find at least one DAS source at the registry. Check config.",
+ jalview.bin.Cache.getDasSourceRegistry().getSources().size() > 0);
+ }
+
+}
-help2Website.class\r
-getJavaVersion.class\r
+help2Website.class
+getJavaVersion.class
<string><![CDATA[664]]></string>
</property>
<property name="sourceName">
- <string><![CDATA[log4j-1.2.8.jar]]></string>
+ <string><![CDATA[slf4j-api-1.7.7.jar]]></string>
</property>
<property name="overrideUnixPermissions">
<boolean>false</boolean>
<boolean>true</boolean>
</property>
<property name="destinationName">
- <string><![CDATA[log4j-1.2.8.jar]]></string>
+ <string><![CDATA[slf4j-api-1.7.7.jar]]></string>
+ </property>
+ <property name="fileSize">
+ <long>348699</long>
+ </property>
+ <property name="macBinary">
+ <boolean>false</boolean>
+ </property>
+ <property name="targetCheckKind">
+ <int>0</int>
+ </property>
+ <property name="ruleExpression">
+ <string><![CDATA[]]></string>
+ </property>
+ </object>
+ </method>
+ <method name="addElement">
+ <object class="com.zerog.ia.installer.actions.InstallZipfile" objectID="244fff00ffff">
+ <property name="belongsToUninstallPhase">
+ <boolean>false</boolean>
+ </property>
+ <property name="rollbackEnabledCancel">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledError">
+ <boolean>true</boolean>
+ </property>
+ <property name="ruleExpression">
+ <string><![CDATA[]]></string>
+ </property>
+ <property name="unixPermissions">
+ <string><![CDATA[664]]></string>
+ </property>
+ <property name="sourceName">
+ <string><![CDATA[jsoup-1.8.1.jar]]></string>
+ </property>
+ <property name="overrideUnixPermissions">
+ <boolean>false</boolean>
+ </property>
+ <property name="sourcePath">
+ <string><![CDATA[/home/cruisecontrol/jalview/lib/]]></string>
+ </property>
+ <property name="shouldUninstall">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledCancel">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledError">
+ <boolean>true</boolean>
+ </property>
+ <property name="destinationName">
+ <string><![CDATA[jsoup-1.8.1.jar]]></string>
</property>
<property name="fileSize">
<long>348699</long>
</property>
</object>
</method>
+ <method name="addElement">
+ <object class="com.zerog.ia.installer.actions.InstallZipfile" objectID="244ffffaa672">
+ <property name="belongsToUninstallPhase">
+ <boolean>false</boolean>
+ </property>
+ <property name="rollbackEnabledCancel">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledError">
+ <boolean>true</boolean>
+ </property>
+ <property name="ruleExpression">
+ <string><![CDATA[]]></string>
+ </property>
+ <property name="unixPermissions">
+ <string><![CDATA[664]]></string>
+ </property>
+ <property name="sourceName">
+ <string><![CDATA[log4j-to-slf4j-2.0-rc2.jar]]></string>
+ </property>
+ <property name="overrideUnixPermissions">
+ <boolean>false</boolean>
+ </property>
+ <property name="sourcePath">
+ <string><![CDATA[/home/cruisecontrol/jalview/lib/]]></string>
+ </property>
+ <property name="shouldUninstall">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledCancel">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledError">
+ <boolean>true</boolean>
+ </property>
+ <property name="destinationName">
+ <string><![CDATA[log4j-to-slf4j-2.0-rc2.jar]]></string>
+ </property>
+ <property name="fileSize">
+ <long>348699</long>
+ </property>
+ <property name="macBinary">
+ <boolean>false</boolean>
+ </property>
+ <property name="targetCheckKind">
+ <int>0</int>
+ </property>
+ <property name="ruleExpression">
+ <string><![CDATA[]]></string>
+ </property>
+ </object>
+ </method>
+ <method name="addElement">
+ <object class="com.zerog.ia.installer.actions.InstallZipfile" objectID="244f00faa672">
+ <property name="belongsToUninstallPhase">
+ <boolean>false</boolean>
+ </property>
+ <property name="rollbackEnabledCancel">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledError">
+ <boolean>true</boolean>
+ </property>
+ <property name="ruleExpression">
+ <string><![CDATA[]]></string>
+ </property>
+ <property name="unixPermissions">
+ <string><![CDATA[664]]></string>
+ </property>
+ <property name="sourceName">
+ <string><![CDATA[slf4j-log4j12-1.7.7.jar]]></string>
+ </property>
+ <property name="overrideUnixPermissions">
+ <boolean>false</boolean>
+ </property>
+ <property name="sourcePath">
+ <string><![CDATA[/home/cruisecontrol/jalview/lib/]]></string>
+ </property>
+ <property name="shouldUninstall">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledCancel">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledError">
+ <boolean>true</boolean>
+ </property>
+ <property name="destinationName">
+ <string><![CDATA[slf4j-log4j12-1.7.7.jar]]></string>
+ </property>
+ <property name="fileSize">
+ <long>348699</long>
+ </property>
+ <property name="macBinary">
+ <boolean>false</boolean>
+ </property>
+ <property name="targetCheckKind">
+ <int>0</int>
+ </property>
+ <property name="ruleExpression">
+ <string><![CDATA[]]></string>
+ </property>
+ </object>
+ </method>
<method name="addElement">
<object class="com.zerog.ia.installer.actions.InstallZipfile" objectID="88d4aff3b0c6">
<property name="belongsToUninstallPhase">
<string><![CDATA[664]]></string>
</property>
<property name="sourceName">
- <string><![CDATA[VARNAv3-9.jar]]></string>
+ <string><![CDATA[VARNAv3-91.jar]]></string>
</property>
<property name="overrideUnixPermissions">
<boolean>false</boolean>
<boolean>true</boolean>
</property>
<property name="destinationName">
- <string><![CDATA[VARNAv3-9.jar]]></string>
+ <string><![CDATA[VARNAv3-91.jar]]></string>
</property>
<property name="fileSize">
<long>663408</long>
</property>
</object>
</method>
+ <method name="addElement">
+ <object class="com.zerog.ia.installer.actions.InstallZipfile" objectID="1f46cffffab93">
+ <property name="belongsToUninstallPhase">
+ <boolean>false</boolean>
+ </property>
+ <property name="rollbackEnabledCancel">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledError">
+ <boolean>true</boolean>
+ </property>
+ <property name="ruleExpression">
+ <string><![CDATA[]]></string>
+ </property>
+ <property name="unixPermissions">
+ <string><![CDATA[664]]></string>
+ </property>
+ <property name="sourceName">
+ <string><![CDATA[jfreesvg-2.1.jar]]></string>
+ </property>
+ <property name="overrideUnixPermissions">
+ <boolean>false</boolean>
+ </property>
+ <property name="sourcePath">
+ <string><![CDATA[/home/cruisecontrol/jalview/lib/]]></string>
+ </property>
+ <property name="shouldUninstall">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledCancel">
+ <boolean>true</boolean>
+ </property>
+ <property name="rollbackEnabledError">
+ <boolean>true</boolean>
+ </property>
+ <property name="destinationName">
+ <string><![CDATA[jfreesvg-2.1.jar]]></string>
+ </property>
+ <property name="fileSize">
+ <long>382442</long>
+ </property>
+ <property name="macBinary">
+ <boolean>false</boolean>
+ </property>
+ <property name="targetCheckKind">
+ <int>0</int>
+ </property>
+ <property name="ruleExpression">
+ <string><![CDATA[]]></string>
+ </property>
+ </object>
+ </method>
</object>
</property>
<property name="rulesFailedMessage">
<object refID="24485f8aa671"/>
<object refID="24485f89a672"/>
<object refID="24485f8aa672"/>
+ <object refID="244fff00ffff"/>
+ <object refID="244ffffaa672"/>
+ <object refID="244f00faa672"/>
<object refID="24485f8ba672"/>
<object refID="24485f8aa673"/>
<object refID="24485f8ba673"/>
<object refID="f44ca391ab9f"/>
<object refID="f44ca392ab9f"/>
<object refID="f44ca393ab9f"/>
+ <object refID=""1f46cffffab93"/>
<object class="com.zerog.ia.installer.actions.InstallFile" objectID="f44fc5b2aba1">
<property name="belongsToUninstallPhase">
<boolean>false</boolean>
<object refID="24485f8aa671"/>
<object refID="24485f89a672"/>
<object refID="24485f8aa672"/>
+ <object refID="244fff00ffff"/>
+ <object refID="244ffffaa672"/>
+ <object refID="244f00faa672"/>
<object refID="24485f8ba672"/>
<object refID="24485f8aa673"/>
<object refID="24485f8ba673"/>
<object refID="f44ca392ab9f"/>
<object refID="f44ca393ab9f"/>
<object refID="f46c2f42ab93"/>
+ <object refID="1f46cffffab93"/>
</visualChildren>
</object>
<object class="com.zerog.ia.installer.actions.InstallDirectory" objectID="f44fc5d5aba1">
# You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
# The Jalview Authors are detailed in the 'AUTHORS' file.
##
- \r
-# Splits a concatenated set of Stockholm Files into several individual files.\r
-\r
-use strict;\r
-use FileHandle;\r
-my $ac;\r
-my $lns="";\r
-my $fh;\r
-while (<>) {\r
- if ($_=~m!^//!) {\r
- $fh->print("//\n");\r
- $fh->close();\r
- $ac = undef;\r
- $lns = "";\r
- } else {\r
- if ($_=~/GF\s+AC\s+([0-9.RPF]+)/) { \r
- $ac=$1; \r
- ($fh=new FileHandle)->open(">$ac.stk") or die("Couldn't open file '$ac.stk'"); \r
- $lns=~/^. STOCKHOLM 1.0/ or $fh->print("# STOCKHOLM 1.0\n");\r
- };\r
- if (defined($fh)) {\r
- if (defined $lns) { \r
- $fh->print($lns); $lns=undef; }\r
- \r
- $fh->print($_);\r
- } else {\r
- $lns .= $_;\r
- }\r
- }\r
-}\r
+
+# Splits a concatenated set of Stockholm Files into several individual files.
+
+use strict;
+use FileHandle;
+my $ac;
+my $lns="";
+my $fh;
+while (<>) {
+ if ($_=~m!^//!) {
+ $fh->print("//\n");
+ $fh->close();
+ $ac = undef;
+ $lns = "";
+ } else {
+ if ($_=~/GF\s+AC\s+([0-9.RPF]+)/) {
+ $ac=$1;
+ ($fh=new FileHandle)->open(">$ac.stk") or die("Couldn't open file '$ac.stk'");
+ $lns=~/^. STOCKHOLM 1.0/ or $fh->print("# STOCKHOLM 1.0\n");
+ };
+ if (defined($fh)) {
+ if (defined $lns) {
+ $fh->print($lns); $lns=undef; }
+
+ $fh->print($_);
+ } else {
+ $lns .= $_;
+ }
+ }
+}