[
  {
    "path": ".editorconfig",
    "content": "[*]\r\ncharset = utf-8\r\nend_of_line = lf\r\nindent_size = 2\r\nindent_style = space\r\ninsert_final_newline = false\r\nmax_line_length = 100\r\ntab_width = 2\r\nij_continuation_indent_size = 4\r\nij_formatter_off_tag = @formatter:off\r\nij_formatter_on_tag = @formatter:on\r\nij_formatter_tags_enabled = false\r\nij_smart_tabs = false\r\nij_visual_guides = 100\r\nij_wrap_on_typing = true\r\n\r\n[]\r\nij_json_keep_blank_lines_in_code = 0\r\nij_json_keep_indents_on_empty_lines = false\r\nij_json_keep_line_breaks = true\r\nij_json_space_after_colon = true\r\nij_json_space_after_comma = true\r\nij_json_space_before_colon = true\r\nij_json_space_before_comma = false\r\nij_json_spaces_within_braces = false\r\nij_json_spaces_within_brackets = false\r\nij_json_wrap_long_lines = false\r\n\r\n[*.bib]\r\nindent_size = 4\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_bibtex_keep_first_column_comment = true\r\nij_bibtex_keep_indents_on_empty_lines = false\r\nij_bibtex_wrap_long_lines = false\r\n\r\n[*.css]\r\nij_css_align_closing_brace_with_properties = false\r\nij_css_blank_lines_around_nested_selector = 1\r\nij_css_blank_lines_between_blocks = 1\r\nij_css_brace_placement = end_of_line\r\nij_css_enforce_quotes_on_format = false\r\nij_css_hex_color_long_format = false\r\nij_css_hex_color_lower_case = false\r\nij_css_hex_color_short_format = false\r\nij_css_hex_color_upper_case = false\r\nij_css_keep_blank_lines_in_code = 2\r\nij_css_keep_indents_on_empty_lines = false\r\nij_css_keep_single_line_blocks = false\r\nij_css_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow\r\nij_css_space_after_colon = true\r\nij_css_space_before_opening_brace = true\r\nij_css_use_double_quotes = true\r\nij_css_value_alignment = do_not_align\r\n\r\n[*.csv]\r\nmax_line_length = 2147483647\r\nij_wrap_on_typing = false\r\nij_csv_wrap_long_lines = false\r\n\r\n[*.feature]\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_gherkin_keep_indents_on_empty_lines = false\r\n\r\n[*.gsp]\r\nindent_size = 4\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_gsp_keep_indents_on_empty_lines = false\r\n\r\n[*.haml]\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_haml_keep_indents_on_empty_lines = false\r\n\r\n[*.java]\r\nij_wrap_on_typing = false\r\nij_java_align_consecutive_assignments = false\r\nij_java_align_consecutive_variable_declarations = false\r\nij_java_align_group_field_declarations = false\r\nij_java_align_multiline_annotation_parameters = false\r\nij_java_align_multiline_array_initializer_expression = false\r\nij_java_align_multiline_assignment = false\r\nij_java_align_multiline_binary_operation = true\r\nij_java_align_multiline_chained_methods = false\r\nij_java_align_multiline_extends_list = false\r\nij_java_align_multiline_for = false\r\nij_java_align_multiline_method_parentheses = false\r\nij_java_align_multiline_parameters = false\r\nij_java_align_multiline_parameters_in_calls = false\r\nij_java_align_multiline_parenthesized_expression = false\r\nij_java_align_multiline_records = false\r\nij_java_align_multiline_resources = false\r\nij_java_align_multiline_ternary_operation = false\r\nij_java_align_multiline_text_blocks = false\r\nij_java_align_multiline_throws_list = false\r\nij_java_align_subsequent_simple_methods = false\r\nij_java_align_throws_keyword = false\r\nij_java_annotation_parameter_wrap = off\r\nij_java_array_initializer_new_line_after_left_brace = true\r\nij_java_array_initializer_right_brace_on_new_line = false\r\nij_java_array_initializer_wrap = on_every_item\r\nij_java_assert_statement_colon_on_next_line = false\r\nij_java_assert_statement_wrap = off\r\nij_java_assignment_wrap = off\r\nij_java_binary_operation_sign_on_next_line = true\r\nij_java_binary_operation_wrap = on_every_item\r\nij_java_blank_lines_after_anonymous_class_header = 0\r\nij_java_blank_lines_after_class_header = 1\r\nij_java_blank_lines_after_imports = 1\r\nij_java_blank_lines_after_package = 1\r\nij_java_blank_lines_around_class = 1\r\nij_java_blank_lines_around_field = 0\r\nij_java_blank_lines_around_field_in_interface = 0\r\nij_java_blank_lines_around_initializer = 1\r\nij_java_blank_lines_around_method = 1\r\nij_java_blank_lines_around_method_in_interface = 1\r\nij_java_blank_lines_before_class_end = 0\r\nij_java_blank_lines_before_imports = 1\r\nij_java_blank_lines_before_method_body = 0\r\nij_java_blank_lines_before_package = 0\r\nij_java_block_brace_style = end_of_line\r\nij_java_block_comment_at_first_column = true\r\nij_java_call_parameters_new_line_after_left_paren = true\r\nij_java_call_parameters_right_paren_on_new_line = false\r\nij_java_call_parameters_wrap = on_every_item\r\nij_java_case_statement_on_separate_line = true\r\nij_java_catch_on_new_line = false\r\nij_java_class_annotation_wrap = split_into_lines\r\nij_java_class_brace_style = end_of_line\r\nij_java_class_count_to_use_import_on_demand = 5\r\nij_java_class_names_in_javadoc = 1\r\nij_java_do_not_indent_top_level_class_members = false\r\nij_java_do_not_wrap_after_single_annotation = true\r\nij_java_do_while_brace_force = never\r\nij_java_doc_add_blank_line_after_description = true\r\nij_java_doc_add_blank_line_after_param_comments = false\r\nij_java_doc_add_blank_line_after_return = false\r\nij_java_doc_add_p_tag_on_empty_lines = true\r\nij_java_doc_align_exception_comments = true\r\nij_java_doc_align_param_comments = true\r\nij_java_doc_do_not_wrap_if_one_line = false\r\nij_java_doc_enable_formatting = true\r\nij_java_doc_enable_leading_asterisks = true\r\nij_java_doc_indent_on_continuation = false\r\nij_java_doc_keep_empty_lines = true\r\nij_java_doc_keep_empty_parameter_tag = true\r\nij_java_doc_keep_empty_return_tag = true\r\nij_java_doc_keep_empty_throws_tag = true\r\nij_java_doc_keep_invalid_tags = true\r\nij_java_doc_param_description_on_new_line = false\r\nij_java_doc_preserve_line_breaks = false\r\nij_java_doc_use_throws_not_exception_tag = true\r\nij_java_else_on_new_line = false\r\nij_java_entity_dd_suffix = EJB\r\nij_java_entity_eb_suffix = Bean\r\nij_java_entity_hi_suffix = Home\r\nij_java_entity_lhi_prefix = Local\r\nij_java_entity_lhi_suffix = Home\r\nij_java_entity_li_prefix = Local\r\nij_java_entity_pk_class = java.lang.String\r\nij_java_entity_vo_suffix = VO\r\nij_java_enum_constants_wrap = off\r\nij_java_extends_keyword_wrap = off\r\nij_java_extends_list_wrap = on_every_item\r\nij_java_field_annotation_wrap = on_every_item\r\nij_java_finally_on_new_line = false\r\nij_java_for_brace_force = never\r\nij_java_for_statement_new_line_after_left_paren = true\r\nij_java_for_statement_right_paren_on_new_line = false\r\nij_java_for_statement_wrap = on_every_item\r\nij_java_generate_final_locals = false\r\nij_java_generate_final_parameters = false\r\nij_java_if_brace_force = never\r\nij_java_imports_layout = $*, |, *\r\nij_java_indent_case_from_switch = true\r\nij_java_insert_inner_class_imports = true\r\nij_java_insert_override_annotation = true\r\nij_java_keep_blank_lines_before_right_brace = 1\r\nij_java_keep_blank_lines_between_package_declaration_and_header = 1\r\nij_java_keep_blank_lines_in_code = 1\r\nij_java_keep_blank_lines_in_declarations = 1\r\nij_java_keep_control_statement_in_one_line = false\r\nij_java_keep_first_column_comment = true\r\nij_java_keep_indents_on_empty_lines = false\r\nij_java_keep_line_breaks = true\r\nij_java_keep_multiple_expressions_in_one_line = false\r\nij_java_keep_simple_blocks_in_one_line = false\r\nij_java_keep_simple_classes_in_one_line = false\r\nij_java_keep_simple_lambdas_in_one_line = false\r\nij_java_keep_simple_methods_in_one_line = false\r\nij_java_label_indent_absolute = false\r\nij_java_label_indent_size = 0\r\nij_java_lambda_brace_style = end_of_line\r\nij_java_layout_static_imports_separately = true\r\nij_java_line_comment_add_space = false\r\nij_java_line_comment_at_first_column = true\r\nij_java_message_dd_suffix = EJB\r\nij_java_message_eb_suffix = Bean\r\nij_java_method_annotation_wrap = split_into_lines\r\nij_java_method_brace_style = end_of_line\r\nij_java_method_call_chain_wrap = on_every_item\r\nij_java_method_parameters_new_line_after_left_paren = true\r\nij_java_method_parameters_right_paren_on_new_line = false\r\nij_java_method_parameters_wrap = on_every_item\r\nij_java_modifier_list_wrap = false\r\nij_java_names_count_to_use_import_on_demand = 5\r\nij_java_new_line_after_lparen_in_record_header = true\r\nij_java_parameter_annotation_wrap = off\r\nij_java_parentheses_expression_new_line_after_left_paren = true\r\nij_java_parentheses_expression_right_paren_on_new_line = false\r\nij_java_place_assignment_sign_on_next_line = false\r\nij_java_prefer_longer_names = true\r\nij_java_prefer_parameters_wrap = false\r\nij_java_record_components_wrap = on_every_item\r\nij_java_repeat_synchronized = true\r\nij_java_replace_instanceof_and_cast = false\r\nij_java_replace_null_check = true\r\nij_java_replace_sum_lambda_with_method_ref = true\r\nij_java_resource_list_new_line_after_left_paren = true\r\nij_java_resource_list_right_paren_on_new_line = false\r\nij_java_resource_list_wrap = off\r\nij_java_rparen_on_new_line_in_record_header = false\r\nij_java_session_dd_suffix = EJB\r\nij_java_session_eb_suffix = Bean\r\nij_java_session_hi_suffix = Home\r\nij_java_session_lhi_prefix = Local\r\nij_java_session_lhi_suffix = Home\r\nij_java_session_li_prefix = Local\r\nij_java_session_si_suffix = Service\r\nij_java_space_after_closing_angle_bracket_in_type_argument = false\r\nij_java_space_after_colon = true\r\nij_java_space_after_comma = true\r\nij_java_space_after_comma_in_type_arguments = true\r\nij_java_space_after_for_semicolon = true\r\nij_java_space_after_quest = true\r\nij_java_space_after_type_cast = true\r\nij_java_space_before_annotation_array_initializer_left_brace = false\r\nij_java_space_before_annotation_parameter_list = false\r\nij_java_space_before_array_initializer_left_brace = false\r\nij_java_space_before_catch_keyword = true\r\nij_java_space_before_catch_left_brace = true\r\nij_java_space_before_catch_parentheses = true\r\nij_java_space_before_class_left_brace = true\r\nij_java_space_before_colon = true\r\nij_java_space_before_colon_in_foreach = true\r\nij_java_space_before_comma = false\r\nij_java_space_before_do_left_brace = true\r\nij_java_space_before_else_keyword = true\r\nij_java_space_before_else_left_brace = true\r\nij_java_space_before_finally_keyword = true\r\nij_java_space_before_finally_left_brace = true\r\nij_java_space_before_for_left_brace = true\r\nij_java_space_before_for_parentheses = true\r\nij_java_space_before_for_semicolon = false\r\nij_java_space_before_if_left_brace = true\r\nij_java_space_before_if_parentheses = true\r\nij_java_space_before_method_call_parentheses = false\r\nij_java_space_before_method_left_brace = true\r\nij_java_space_before_method_parentheses = false\r\nij_java_space_before_opening_angle_bracket_in_type_parameter = false\r\nij_java_space_before_quest = true\r\nij_java_space_before_switch_left_brace = true\r\nij_java_space_before_switch_parentheses = true\r\nij_java_space_before_synchronized_left_brace = true\r\nij_java_space_before_synchronized_parentheses = true\r\nij_java_space_before_try_left_brace = true\r\nij_java_space_before_try_parentheses = true\r\nij_java_space_before_type_parameter_list = false\r\nij_java_space_before_while_keyword = true\r\nij_java_space_before_while_left_brace = true\r\nij_java_space_before_while_parentheses = true\r\nij_java_space_inside_one_line_enum_braces = false\r\nij_java_space_within_empty_array_initializer_braces = false\r\nij_java_space_within_empty_method_call_parentheses = false\r\nij_java_space_within_empty_method_parentheses = false\r\nij_java_spaces_around_additive_operators = true\r\nij_java_spaces_around_assignment_operators = true\r\nij_java_spaces_around_bitwise_operators = true\r\nij_java_spaces_around_equality_operators = true\r\nij_java_spaces_around_lambda_arrow = true\r\nij_java_spaces_around_logical_operators = true\r\nij_java_spaces_around_method_ref_dbl_colon = false\r\nij_java_spaces_around_multiplicative_operators = true\r\nij_java_spaces_around_relational_operators = true\r\nij_java_spaces_around_shift_operators = true\r\nij_java_spaces_around_type_bounds_in_type_parameters = true\r\nij_java_spaces_around_unary_operator = false\r\nij_java_spaces_within_angle_brackets = false\r\nij_java_spaces_within_annotation_parentheses = false\r\nij_java_spaces_within_array_initializer_braces = false\r\nij_java_spaces_within_braces = false\r\nij_java_spaces_within_brackets = false\r\nij_java_spaces_within_cast_parentheses = false\r\nij_java_spaces_within_catch_parentheses = false\r\nij_java_spaces_within_for_parentheses = false\r\nij_java_spaces_within_if_parentheses = false\r\nij_java_spaces_within_method_call_parentheses = false\r\nij_java_spaces_within_method_parentheses = false\r\nij_java_spaces_within_parentheses = false\r\nij_java_spaces_within_switch_parentheses = false\r\nij_java_spaces_within_synchronized_parentheses = false\r\nij_java_spaces_within_try_parentheses = false\r\nij_java_spaces_within_while_parentheses = false\r\nij_java_special_else_if_treatment = true\r\nij_java_subclass_name_suffix = Impl\r\nij_java_ternary_operation_signs_on_next_line = true\r\nij_java_ternary_operation_wrap = on_every_item\r\nij_java_test_name_suffix = Test\r\nij_java_throws_keyword_wrap = normal\r\nij_java_throws_list_wrap = off\r\nij_java_use_external_annotations = false\r\nij_java_use_fq_class_names = false\r\nij_java_use_relative_indents = false\r\nij_java_use_single_class_imports = true\r\nij_java_variable_annotation_wrap = off\r\nij_java_visibility = public\r\nij_java_while_brace_force = never\r\nij_java_while_on_new_line = false\r\nij_java_wrap_comments = true\r\nij_java_wrap_first_method_in_call_chain = true\r\nij_java_wrap_long_lines = false\r\n\r\n[*.less]\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_less_align_closing_brace_with_properties = false\r\nij_less_blank_lines_around_nested_selector = 1\r\nij_less_blank_lines_between_blocks = 1\r\nij_less_brace_placement = 0\r\nij_less_enforce_quotes_on_format = false\r\nij_less_hex_color_long_format = false\r\nij_less_hex_color_lower_case = false\r\nij_less_hex_color_short_format = false\r\nij_less_hex_color_upper_case = false\r\nij_less_keep_blank_lines_in_code = 2\r\nij_less_keep_indents_on_empty_lines = false\r\nij_less_keep_single_line_blocks = false\r\nij_less_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow\r\nij_less_space_after_colon = true\r\nij_less_space_before_opening_brace = true\r\nij_less_use_double_quotes = true\r\nij_less_value_alignment = 0\r\n\r\n[*.nbtt]\r\nindent_size = 4\r\nmax_line_length = 150\r\ntab_width = 4\r\nij_nbtt_keep_indents_on_empty_lines = false\r\nij_nbtt_space_after_colon = true\r\nij_nbtt_space_after_comma = true\r\nij_nbtt_space_before_colon = true\r\nij_nbtt_space_before_comma = false\r\nij_nbtt_spaces_within_brackets = false\r\nij_nbtt_spaces_within_parentheses = false\r\n\r\n[*.sass]\r\nij_sass_align_closing_brace_with_properties = false\r\nij_sass_blank_lines_around_nested_selector = 1\r\nij_sass_blank_lines_between_blocks = 1\r\nij_sass_brace_placement = 0\r\nij_sass_enforce_quotes_on_format = false\r\nij_sass_hex_color_long_format = false\r\nij_sass_hex_color_lower_case = false\r\nij_sass_hex_color_short_format = false\r\nij_sass_hex_color_upper_case = false\r\nij_sass_keep_blank_lines_in_code = 2\r\nij_sass_keep_indents_on_empty_lines = false\r\nij_sass_keep_single_line_blocks = false\r\nij_sass_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow\r\nij_sass_space_after_colon = true\r\nij_sass_space_before_opening_brace = true\r\nij_sass_use_double_quotes = true\r\nij_sass_value_alignment = 0\r\n\r\n[*.scss]\r\nij_scss_align_closing_brace_with_properties = false\r\nij_scss_blank_lines_around_nested_selector = 1\r\nij_scss_blank_lines_between_blocks = 1\r\nij_scss_brace_placement = 0\r\nij_scss_enforce_quotes_on_format = false\r\nij_scss_hex_color_long_format = false\r\nij_scss_hex_color_lower_case = false\r\nij_scss_hex_color_short_format = false\r\nij_scss_hex_color_upper_case = false\r\nij_scss_keep_blank_lines_in_code = 2\r\nij_scss_keep_indents_on_empty_lines = false\r\nij_scss_keep_single_line_blocks = false\r\nij_scss_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow\r\nij_scss_space_after_colon = true\r\nij_scss_space_before_opening_brace = true\r\nij_scss_use_double_quotes = true\r\nij_scss_value_alignment = 0\r\n\r\n[*.styl]\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_stylus_align_closing_brace_with_properties = false\r\nij_stylus_blank_lines_around_nested_selector = 1\r\nij_stylus_blank_lines_between_blocks = 1\r\nij_stylus_brace_placement = 0\r\nij_stylus_enforce_quotes_on_format = false\r\nij_stylus_hex_color_long_format = false\r\nij_stylus_hex_color_lower_case = false\r\nij_stylus_hex_color_short_format = false\r\nij_stylus_hex_color_upper_case = false\r\nij_stylus_keep_blank_lines_in_code = 2\r\nij_stylus_keep_indents_on_empty_lines = false\r\nij_stylus_keep_single_line_blocks = false\r\nij_stylus_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow\r\nij_stylus_space_after_colon = true\r\nij_stylus_space_before_opening_brace = true\r\nij_stylus_use_double_quotes = true\r\nij_stylus_value_alignment = 0\r\n\r\n[*.tikz]\r\nindent_size = 4\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_latex_keep_first_column_comment = true\r\nij_latex_keep_indents_on_empty_lines = false\r\nij_latex_line_comment_add_space = false\r\nij_latex_line_comment_at_first_column = true\r\nij_latex_wrap_long_lines = false\r\n\r\n[.editorconfig]\r\nij_editorconfig_align_group_field_declarations = false\r\nij_editorconfig_space_after_colon = false\r\nij_editorconfig_space_after_comma = true\r\nij_editorconfig_space_before_colon = false\r\nij_editorconfig_space_before_comma = false\r\nij_editorconfig_spaces_around_assignment_operators = true\r\n\r\n[{*.ant, *.bpmn, *.fxml, *.jhm, *.jnlp, *.jrxml, *.plan, *.pom, *.rng, *.tld, *.wadl, *.wsdd, *.wsdl, *.xjb, *.xml, *.xsd, *.xsl, *.xslt, *.xul}]\r\nij_continuation_indent_size = 2\r\nij_xml_align_attributes = false\r\nij_xml_align_text = false\r\nij_xml_attribute_wrap = normal\r\nij_xml_block_comment_at_first_column = true\r\nij_xml_keep_blank_lines = 2\r\nij_xml_keep_indents_on_empty_lines = false\r\nij_xml_keep_line_breaks = true\r\nij_xml_keep_line_breaks_in_text = true\r\nij_xml_keep_whitespaces = false\r\nij_xml_keep_whitespaces_around_cdata = preserve\r\nij_xml_keep_whitespaces_inside_cdata = false\r\nij_xml_line_comment_at_first_column = true\r\nij_xml_space_after_tag_name = false\r\nij_xml_space_around_equals_in_attribute = false\r\nij_xml_space_inside_empty_tag = false\r\nij_xml_text_wrap = normal\r\nij_xml_use_custom_settings = true\r\n\r\n[{*.as, *.es, *.js2}]\r\nindent_size = 4\r\nij_continuation_indent_size = 8\r\nij_actionscript_align_imports = false\r\nij_actionscript_align_multiline_array_initializer_expression = false\r\nij_actionscript_align_multiline_binary_operation = false\r\nij_actionscript_align_multiline_chained_methods = false\r\nij_actionscript_align_multiline_extends_list = false\r\nij_actionscript_align_multiline_for = false\r\nij_actionscript_align_multiline_parameters = false\r\nij_actionscript_align_multiline_parameters_in_calls = false\r\nij_actionscript_align_multiline_ternary_operation = false\r\nij_actionscript_align_object_properties = 0\r\nij_actionscript_align_union_types = false\r\nij_actionscript_align_var_statements = 0\r\nij_actionscript_array_initializer_new_line_after_left_brace = false\r\nij_actionscript_array_initializer_right_brace_on_new_line = false\r\nij_actionscript_array_initializer_wrap = normal\r\nij_actionscript_assignment_wrap = off\r\nij_actionscript_binary_operation_sign_on_next_line = true\r\nij_actionscript_binary_operation_wrap = normal\r\nij_actionscript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**\r\nij_actionscript_blank_lines_after_imports = 1\r\nij_actionscript_blank_lines_after_package = 0\r\nij_actionscript_blank_lines_around_function = 1\r\nij_actionscript_blank_lines_around_method = 1\r\nij_actionscript_blank_lines_before_imports = 1\r\nij_actionscript_blank_lines_before_package = 0\r\nij_actionscript_block_brace_style = end_of_line\r\nij_actionscript_call_parameters_new_line_after_left_paren = false\r\nij_actionscript_call_parameters_right_paren_on_new_line = false\r\nij_actionscript_call_parameters_wrap = normal\r\nij_actionscript_catch_on_new_line = false\r\nij_actionscript_chained_call_dot_on_new_line = true\r\nij_actionscript_class_brace_style = end_of_line\r\nij_actionscript_comma_on_new_line = false\r\nij_actionscript_do_while_brace_force = always\r\nij_actionscript_else_on_new_line = false\r\nij_actionscript_enforce_trailing_comma = keep\r\nij_actionscript_extends_keyword_wrap = off\r\nij_actionscript_extends_list_wrap = normal\r\nij_actionscript_field_prefix = _\r\nij_actionscript_file_name_style = relaxed\r\nij_actionscript_finally_on_new_line = false\r\nij_actionscript_for_brace_force = always\r\nij_actionscript_for_statement_new_line_after_left_paren = false\r\nij_actionscript_for_statement_right_paren_on_new_line = false\r\nij_actionscript_for_statement_wrap = normal\r\nij_actionscript_force_quote_style = false\r\nij_actionscript_force_semicolon_style = false\r\nij_actionscript_function_expression_brace_style = end_of_line\r\nij_actionscript_if_brace_force = always\r\nij_actionscript_import_merge_members = global\r\nij_actionscript_import_prefer_absolute_path = global\r\nij_actionscript_import_sort_members = true\r\nij_actionscript_import_sort_module_name = false\r\nij_actionscript_import_use_node_resolution = true\r\nij_actionscript_imports_wrap = on_every_item\r\nij_actionscript_indent_case_from_switch = true\r\nij_actionscript_indent_chained_calls = true\r\nij_actionscript_indent_package_children = 0\r\nij_actionscript_jsx_attribute_value = braces\r\nij_actionscript_keep_blank_lines_in_code = 1\r\nij_actionscript_keep_first_column_comment = true\r\nij_actionscript_keep_indents_on_empty_lines = false\r\nij_actionscript_keep_line_breaks = true\r\nij_actionscript_keep_simple_blocks_in_one_line = false\r\nij_actionscript_keep_simple_methods_in_one_line = false\r\nij_actionscript_line_comment_at_first_column = true\r\nij_actionscript_method_brace_style = end_of_line\r\nij_actionscript_method_call_chain_wrap = off\r\nij_actionscript_method_parameters_new_line_after_left_paren = false\r\nij_actionscript_method_parameters_right_paren_on_new_line = false\r\nij_actionscript_method_parameters_wrap = normal\r\nij_actionscript_object_literal_wrap = on_every_item\r\nij_actionscript_parentheses_expression_new_line_after_left_paren = false\r\nij_actionscript_parentheses_expression_right_paren_on_new_line = false\r\nij_actionscript_place_assignment_sign_on_next_line = false\r\nij_actionscript_prefer_as_type_cast = false\r\nij_actionscript_prefer_explicit_types_function_expression_returns = false\r\nij_actionscript_prefer_explicit_types_function_returns = false\r\nij_actionscript_prefer_explicit_types_vars_fields = false\r\nij_actionscript_prefer_parameters_wrap = false\r\nij_actionscript_reformat_c_style_comments = false\r\nij_actionscript_space_after_colon = true\r\nij_actionscript_space_after_comma = true\r\nij_actionscript_space_after_dots_in_rest_parameter = false\r\nij_actionscript_space_after_generator_mult = true\r\nij_actionscript_space_after_property_colon = true\r\nij_actionscript_space_after_quest = true\r\nij_actionscript_space_after_type_colon = false\r\nij_actionscript_space_after_unary_not = false\r\nij_actionscript_space_before_async_arrow_lparen = true\r\nij_actionscript_space_before_catch_keyword = true\r\nij_actionscript_space_before_catch_left_brace = true\r\nij_actionscript_space_before_catch_parentheses = true\r\nij_actionscript_space_before_class_lbrace = true\r\nij_actionscript_space_before_colon = true\r\nij_actionscript_space_before_comma = false\r\nij_actionscript_space_before_do_left_brace = true\r\nij_actionscript_space_before_else_keyword = true\r\nij_actionscript_space_before_else_left_brace = true\r\nij_actionscript_space_before_finally_keyword = true\r\nij_actionscript_space_before_finally_left_brace = true\r\nij_actionscript_space_before_for_left_brace = true\r\nij_actionscript_space_before_for_parentheses = true\r\nij_actionscript_space_before_for_semicolon = false\r\nij_actionscript_space_before_function_left_parenth = true\r\nij_actionscript_space_before_generator_mult = false\r\nij_actionscript_space_before_if_left_brace = true\r\nij_actionscript_space_before_if_parentheses = true\r\nij_actionscript_space_before_method_call_parentheses = false\r\nij_actionscript_space_before_method_left_brace = true\r\nij_actionscript_space_before_method_parentheses = false\r\nij_actionscript_space_before_property_colon = false\r\nij_actionscript_space_before_quest = true\r\nij_actionscript_space_before_switch_left_brace = true\r\nij_actionscript_space_before_switch_parentheses = true\r\nij_actionscript_space_before_try_left_brace = true\r\nij_actionscript_space_before_type_colon = false\r\nij_actionscript_space_before_unary_not = false\r\nij_actionscript_space_before_while_keyword = true\r\nij_actionscript_space_before_while_left_brace = true\r\nij_actionscript_space_before_while_parentheses = true\r\nij_actionscript_spaces_around_additive_operators = true\r\nij_actionscript_spaces_around_arrow_function_operator = true\r\nij_actionscript_spaces_around_assignment_operators = true\r\nij_actionscript_spaces_around_bitwise_operators = true\r\nij_actionscript_spaces_around_equality_operators = true\r\nij_actionscript_spaces_around_logical_operators = true\r\nij_actionscript_spaces_around_multiplicative_operators = true\r\nij_actionscript_spaces_around_relational_operators = true\r\nij_actionscript_spaces_around_shift_operators = true\r\nij_actionscript_spaces_around_unary_operator = false\r\nij_actionscript_spaces_within_array_initializer_brackets = false\r\nij_actionscript_spaces_within_brackets = false\r\nij_actionscript_spaces_within_catch_parentheses = false\r\nij_actionscript_spaces_within_for_parentheses = false\r\nij_actionscript_spaces_within_if_parentheses = false\r\nij_actionscript_spaces_within_imports = false\r\nij_actionscript_spaces_within_interpolation_expressions = false\r\nij_actionscript_spaces_within_method_call_parentheses = false\r\nij_actionscript_spaces_within_method_parentheses = false\r\nij_actionscript_spaces_within_object_literal_braces = false\r\nij_actionscript_spaces_within_object_type_braces = true\r\nij_actionscript_spaces_within_parentheses = false\r\nij_actionscript_spaces_within_switch_parentheses = false\r\nij_actionscript_spaces_within_type_assertion = false\r\nij_actionscript_spaces_within_union_types = true\r\nij_actionscript_spaces_within_while_parentheses = false\r\nij_actionscript_special_else_if_treatment = true\r\nij_actionscript_ternary_operation_signs_on_next_line = true\r\nij_actionscript_ternary_operation_wrap = normal\r\nij_actionscript_union_types_wrap = on_every_item\r\nij_actionscript_use_chained_calls_group_indents = false\r\nij_actionscript_use_double_quotes = true\r\nij_actionscript_use_explicit_js_extension = global\r\nij_actionscript_use_path_mapping = always\r\nij_actionscript_use_public_modifier = false\r\nij_actionscript_use_semicolon_after_statement = true\r\nij_actionscript_var_declaration_wrap = normal\r\nij_actionscript_while_brace_force = always\r\nij_actionscript_while_on_new_line = false\r\nij_actionscript_wrap_comments = false\r\n\r\n[{*.ats, *.ts}]\r\nij_typescript_align_imports = false\r\nij_typescript_align_multiline_array_initializer_expression = false\r\nij_typescript_align_multiline_binary_operation = false\r\nij_typescript_align_multiline_chained_methods = false\r\nij_typescript_align_multiline_extends_list = false\r\nij_typescript_align_multiline_for = true\r\nij_typescript_align_multiline_parameters = true\r\nij_typescript_align_multiline_parameters_in_calls = false\r\nij_typescript_align_multiline_ternary_operation = false\r\nij_typescript_align_object_properties = 0\r\nij_typescript_align_union_types = false\r\nij_typescript_align_var_statements = 0\r\nij_typescript_array_initializer_new_line_after_left_brace = false\r\nij_typescript_array_initializer_right_brace_on_new_line = false\r\nij_typescript_array_initializer_wrap = off\r\nij_typescript_assignment_wrap = off\r\nij_typescript_binary_operation_sign_on_next_line = false\r\nij_typescript_binary_operation_wrap = off\r\nij_typescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**\r\nij_typescript_blank_lines_after_imports = 1\r\nij_typescript_blank_lines_around_class = 1\r\nij_typescript_blank_lines_around_field = 0\r\nij_typescript_blank_lines_around_field_in_interface = 0\r\nij_typescript_blank_lines_around_function = 1\r\nij_typescript_blank_lines_around_method = 1\r\nij_typescript_blank_lines_around_method_in_interface = 1\r\nij_typescript_block_brace_style = end_of_line\r\nij_typescript_call_parameters_new_line_after_left_paren = false\r\nij_typescript_call_parameters_right_paren_on_new_line = false\r\nij_typescript_call_parameters_wrap = off\r\nij_typescript_catch_on_new_line = false\r\nij_typescript_chained_call_dot_on_new_line = true\r\nij_typescript_class_brace_style = end_of_line\r\nij_typescript_comma_on_new_line = false\r\nij_typescript_do_while_brace_force = never\r\nij_typescript_else_on_new_line = false\r\nij_typescript_enforce_trailing_comma = keep\r\nij_typescript_extends_keyword_wrap = off\r\nij_typescript_extends_list_wrap = off\r\nij_typescript_field_prefix = _\r\nij_typescript_file_name_style = relaxed\r\nij_typescript_finally_on_new_line = false\r\nij_typescript_for_brace_force = never\r\nij_typescript_for_statement_new_line_after_left_paren = false\r\nij_typescript_for_statement_right_paren_on_new_line = false\r\nij_typescript_for_statement_wrap = off\r\nij_typescript_force_quote_style = false\r\nij_typescript_force_semicolon_style = false\r\nij_typescript_function_expression_brace_style = end_of_line\r\nij_typescript_if_brace_force = never\r\nij_typescript_import_merge_members = global\r\nij_typescript_import_prefer_absolute_path = global\r\nij_typescript_import_sort_members = true\r\nij_typescript_import_sort_module_name = false\r\nij_typescript_import_use_node_resolution = true\r\nij_typescript_imports_wrap = on_every_item\r\nij_typescript_indent_case_from_switch = true\r\nij_typescript_indent_chained_calls = false\r\nij_typescript_indent_package_children = 0\r\nij_typescript_jsdoc_include_types = false\r\nij_typescript_jsx_attribute_value = braces\r\nij_typescript_keep_blank_lines_in_code = 2\r\nij_typescript_keep_first_column_comment = true\r\nij_typescript_keep_indents_on_empty_lines = false\r\nij_typescript_keep_line_breaks = true\r\nij_typescript_keep_simple_blocks_in_one_line = false\r\nij_typescript_keep_simple_methods_in_one_line = false\r\nij_typescript_line_comment_add_space = true\r\nij_typescript_line_comment_at_first_column = false\r\nij_typescript_method_brace_style = end_of_line\r\nij_typescript_method_call_chain_wrap = off\r\nij_typescript_method_parameters_new_line_after_left_paren = false\r\nij_typescript_method_parameters_right_paren_on_new_line = false\r\nij_typescript_method_parameters_wrap = off\r\nij_typescript_object_literal_wrap = on_every_item\r\nij_typescript_parentheses_expression_new_line_after_left_paren = false\r\nij_typescript_parentheses_expression_right_paren_on_new_line = false\r\nij_typescript_place_assignment_sign_on_next_line = false\r\nij_typescript_prefer_as_type_cast = false\r\nij_typescript_prefer_explicit_types_function_expression_returns = false\r\nij_typescript_prefer_explicit_types_function_returns = false\r\nij_typescript_prefer_explicit_types_vars_fields = false\r\nij_typescript_prefer_parameters_wrap = false\r\nij_typescript_reformat_c_style_comments = false\r\nij_typescript_space_after_colon = true\r\nij_typescript_space_after_comma = true\r\nij_typescript_space_after_dots_in_rest_parameter = false\r\nij_typescript_space_after_generator_mult = true\r\nij_typescript_space_after_property_colon = true\r\nij_typescript_space_after_quest = true\r\nij_typescript_space_after_type_colon = true\r\nij_typescript_space_after_unary_not = false\r\nij_typescript_space_before_async_arrow_lparen = true\r\nij_typescript_space_before_catch_keyword = true\r\nij_typescript_space_before_catch_left_brace = true\r\nij_typescript_space_before_catch_parentheses = true\r\nij_typescript_space_before_class_lbrace = true\r\nij_typescript_space_before_class_left_brace = true\r\nij_typescript_space_before_colon = true\r\nij_typescript_space_before_comma = false\r\nij_typescript_space_before_do_left_brace = true\r\nij_typescript_space_before_else_keyword = true\r\nij_typescript_space_before_else_left_brace = true\r\nij_typescript_space_before_finally_keyword = true\r\nij_typescript_space_before_finally_left_brace = true\r\nij_typescript_space_before_for_left_brace = true\r\nij_typescript_space_before_for_parentheses = true\r\nij_typescript_space_before_for_semicolon = false\r\nij_typescript_space_before_function_left_parenth = true\r\nij_typescript_space_before_generator_mult = false\r\nij_typescript_space_before_if_left_brace = true\r\nij_typescript_space_before_if_parentheses = true\r\nij_typescript_space_before_method_call_parentheses = false\r\nij_typescript_space_before_method_left_brace = true\r\nij_typescript_space_before_method_parentheses = false\r\nij_typescript_space_before_property_colon = false\r\nij_typescript_space_before_quest = true\r\nij_typescript_space_before_switch_left_brace = true\r\nij_typescript_space_before_switch_parentheses = true\r\nij_typescript_space_before_try_left_brace = true\r\nij_typescript_space_before_type_colon = false\r\nij_typescript_space_before_unary_not = false\r\nij_typescript_space_before_while_keyword = true\r\nij_typescript_space_before_while_left_brace = true\r\nij_typescript_space_before_while_parentheses = true\r\nij_typescript_spaces_around_additive_operators = true\r\nij_typescript_spaces_around_arrow_function_operator = true\r\nij_typescript_spaces_around_assignment_operators = true\r\nij_typescript_spaces_around_bitwise_operators = true\r\nij_typescript_spaces_around_equality_operators = true\r\nij_typescript_spaces_around_logical_operators = true\r\nij_typescript_spaces_around_multiplicative_operators = true\r\nij_typescript_spaces_around_relational_operators = true\r\nij_typescript_spaces_around_shift_operators = true\r\nij_typescript_spaces_around_unary_operator = false\r\nij_typescript_spaces_within_array_initializer_brackets = false\r\nij_typescript_spaces_within_brackets = false\r\nij_typescript_spaces_within_catch_parentheses = false\r\nij_typescript_spaces_within_for_parentheses = false\r\nij_typescript_spaces_within_if_parentheses = false\r\nij_typescript_spaces_within_imports = false\r\nij_typescript_spaces_within_interpolation_expressions = false\r\nij_typescript_spaces_within_method_call_parentheses = false\r\nij_typescript_spaces_within_method_parentheses = false\r\nij_typescript_spaces_within_object_literal_braces = false\r\nij_typescript_spaces_within_object_type_braces = true\r\nij_typescript_spaces_within_parentheses = false\r\nij_typescript_spaces_within_switch_parentheses = false\r\nij_typescript_spaces_within_type_assertion = false\r\nij_typescript_spaces_within_union_types = true\r\nij_typescript_spaces_within_while_parentheses = false\r\nij_typescript_special_else_if_treatment = true\r\nij_typescript_ternary_operation_signs_on_next_line = false\r\nij_typescript_ternary_operation_wrap = off\r\nij_typescript_union_types_wrap = on_every_item\r\nij_typescript_use_chained_calls_group_indents = false\r\nij_typescript_use_double_quotes = true\r\nij_typescript_use_explicit_js_extension = global\r\nij_typescript_use_path_mapping = always\r\nij_typescript_use_public_modifier = false\r\nij_typescript_use_semicolon_after_statement = true\r\nij_typescript_var_declaration_wrap = normal\r\nij_typescript_while_brace_force = never\r\nij_typescript_while_on_new_line = false\r\nij_typescript_wrap_comments = false\r\n\r\n[{*.cfc, *.cfm, *.cfml}]\r\nindent_size = 4\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_cfml_align_multiline_binary_operation = false\r\nij_cfml_align_multiline_for = true\r\nij_cfml_align_multiline_parameters = true\r\nij_cfml_align_multiline_parameters_in_calls = false\r\nij_cfml_align_multiline_ternary_operation = false\r\nij_cfml_assignment_wrap = off\r\nij_cfml_binary_operation_sign_on_next_line = false\r\nij_cfml_binary_operation_wrap = off\r\nij_cfml_block_brace_style = end_of_line\r\nij_cfml_call_parameters_new_line_after_left_paren = false\r\nij_cfml_call_parameters_right_paren_on_new_line = false\r\nij_cfml_call_parameters_wrap = off\r\nij_cfml_catch_on_new_line = false\r\nij_cfml_else_on_new_line = false\r\nij_cfml_for_statement_new_line_after_left_paren = false\r\nij_cfml_for_statement_right_paren_on_new_line = false\r\nij_cfml_for_statement_wrap = off\r\nij_cfml_keep_blank_lines_in_code = 2\r\nij_cfml_keep_first_column_comment = true\r\nij_cfml_keep_indents_on_empty_lines = false\r\nij_cfml_keep_line_breaks = true\r\nij_cfml_method_brace_style = next_line\r\nij_cfml_method_parameters_new_line_after_left_paren = false\r\nij_cfml_method_parameters_right_paren_on_new_line = false\r\nij_cfml_method_parameters_wrap = off\r\nij_cfml_parentheses_expression_new_line_after_left_paren = false\r\nij_cfml_parentheses_expression_right_paren_on_new_line = false\r\nij_cfml_place_assignment_sign_on_next_line = false\r\nij_cfml_space_after_colon = true\r\nij_cfml_space_after_comma = true\r\nij_cfml_space_after_for_semicolon = true\r\nij_cfml_space_after_quest = true\r\nij_cfml_space_before_catch_keyword = true\r\nij_cfml_space_before_catch_left_brace = true\r\nij_cfml_space_before_catch_parentheses = true\r\nij_cfml_space_before_colon = true\r\nij_cfml_space_before_comma = false\r\nij_cfml_space_before_else_keyword = true\r\nij_cfml_space_before_else_left_brace = true\r\nij_cfml_space_before_for_left_brace = true\r\nij_cfml_space_before_for_parentheses = true\r\nij_cfml_space_before_for_semicolon = false\r\nij_cfml_space_before_if_left_brace = true\r\nij_cfml_space_before_if_parentheses = true\r\nij_cfml_space_before_method_call_parentheses = false\r\nij_cfml_space_before_method_left_brace = true\r\nij_cfml_space_before_method_parentheses = false\r\nij_cfml_space_before_quest = true\r\nij_cfml_space_before_switch_left_brace = true\r\nij_cfml_space_before_switch_parentheses = true\r\nij_cfml_space_before_try_left_brace = true\r\nij_cfml_space_before_while_keyword = true\r\nij_cfml_space_before_while_left_brace = true\r\nij_cfml_space_before_while_parentheses = true\r\nij_cfml_spaces_around_additive_operators = true\r\nij_cfml_spaces_around_assignment_operators = true\r\nij_cfml_spaces_around_equality_operators = true\r\nij_cfml_spaces_around_logical_operators = true\r\nij_cfml_spaces_around_multiplicative_operators = true\r\nij_cfml_spaces_around_relational_operators = true\r\nij_cfml_spaces_around_unary_operator = false\r\nij_cfml_spaces_within_catch_parentheses = false\r\nij_cfml_spaces_within_for_parentheses = false\r\nij_cfml_spaces_within_if_parentheses = false\r\nij_cfml_spaces_within_method_call_parentheses = false\r\nij_cfml_spaces_within_method_parentheses = false\r\nij_cfml_spaces_within_switch_parentheses = false\r\nij_cfml_spaces_within_while_parentheses = false\r\nij_cfml_special_else_if_treatment = false\r\nij_cfml_ternary_operation_signs_on_next_line = false\r\nij_cfml_ternary_operation_wrap = off\r\nij_cfml_while_on_new_line = false\r\n\r\n[{*.cjs, *.js}]\r\nmax_line_length = 80\r\nij_javascript_align_imports = false\r\nij_javascript_align_multiline_array_initializer_expression = false\r\nij_javascript_align_multiline_binary_operation = false\r\nij_javascript_align_multiline_chained_methods = false\r\nij_javascript_align_multiline_extends_list = false\r\nij_javascript_align_multiline_for = false\r\nij_javascript_align_multiline_parameters = false\r\nij_javascript_align_multiline_parameters_in_calls = false\r\nij_javascript_align_multiline_ternary_operation = false\r\nij_javascript_align_object_properties = 0\r\nij_javascript_align_union_types = false\r\nij_javascript_align_var_statements = 0\r\nij_javascript_array_initializer_new_line_after_left_brace = false\r\nij_javascript_array_initializer_right_brace_on_new_line = false\r\nij_javascript_array_initializer_wrap = normal\r\nij_javascript_assignment_wrap = off\r\nij_javascript_binary_operation_sign_on_next_line = true\r\nij_javascript_binary_operation_wrap = normal\r\nij_javascript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**\r\nij_javascript_blank_lines_after_imports = 1\r\nij_javascript_blank_lines_around_class = 1\r\nij_javascript_blank_lines_around_field = 0\r\nij_javascript_blank_lines_around_function = 1\r\nij_javascript_blank_lines_around_method = 1\r\nij_javascript_block_brace_style = end_of_line\r\nij_javascript_call_parameters_new_line_after_left_paren = false\r\nij_javascript_call_parameters_right_paren_on_new_line = false\r\nij_javascript_call_parameters_wrap = normal\r\nij_javascript_catch_on_new_line = false\r\nij_javascript_chained_call_dot_on_new_line = true\r\nij_javascript_class_brace_style = end_of_line\r\nij_javascript_comma_on_new_line = false\r\nij_javascript_do_while_brace_force = always\r\nij_javascript_else_on_new_line = false\r\nij_javascript_enforce_trailing_comma = keep\r\nij_javascript_extends_keyword_wrap = off\r\nij_javascript_extends_list_wrap = off\r\nij_javascript_field_prefix = _\r\nij_javascript_file_name_style = relaxed\r\nij_javascript_finally_on_new_line = false\r\nij_javascript_for_brace_force = always\r\nij_javascript_for_statement_new_line_after_left_paren = false\r\nij_javascript_for_statement_right_paren_on_new_line = false\r\nij_javascript_for_statement_wrap = normal\r\nij_javascript_force_quote_style = false\r\nij_javascript_force_semicolon_style = false\r\nij_javascript_function_expression_brace_style = end_of_line\r\nij_javascript_if_brace_force = always\r\nij_javascript_import_merge_members = global\r\nij_javascript_import_prefer_absolute_path = global\r\nij_javascript_import_sort_members = true\r\nij_javascript_import_sort_module_name = false\r\nij_javascript_import_use_node_resolution = true\r\nij_javascript_imports_wrap = on_every_item\r\nij_javascript_indent_case_from_switch = true\r\nij_javascript_indent_chained_calls = false\r\nij_javascript_indent_package_children = 0\r\nij_javascript_jsx_attribute_value = braces\r\nij_javascript_keep_blank_lines_in_code = 1\r\nij_javascript_keep_first_column_comment = true\r\nij_javascript_keep_indents_on_empty_lines = false\r\nij_javascript_keep_line_breaks = true\r\nij_javascript_keep_simple_blocks_in_one_line = false\r\nij_javascript_keep_simple_methods_in_one_line = false\r\nij_javascript_line_comment_add_space = true\r\nij_javascript_line_comment_at_first_column = false\r\nij_javascript_method_brace_style = end_of_line\r\nij_javascript_method_call_chain_wrap = off\r\nij_javascript_method_parameters_new_line_after_left_paren = false\r\nij_javascript_method_parameters_right_paren_on_new_line = false\r\nij_javascript_method_parameters_wrap = normal\r\nij_javascript_object_literal_wrap = on_every_item\r\nij_javascript_parentheses_expression_new_line_after_left_paren = false\r\nij_javascript_parentheses_expression_right_paren_on_new_line = false\r\nij_javascript_place_assignment_sign_on_next_line = false\r\nij_javascript_prefer_as_type_cast = false\r\nij_javascript_prefer_explicit_types_function_expression_returns = false\r\nij_javascript_prefer_explicit_types_function_returns = false\r\nij_javascript_prefer_explicit_types_vars_fields = false\r\nij_javascript_prefer_parameters_wrap = false\r\nij_javascript_reformat_c_style_comments = false\r\nij_javascript_space_after_colon = true\r\nij_javascript_space_after_comma = true\r\nij_javascript_space_after_dots_in_rest_parameter = false\r\nij_javascript_space_after_generator_mult = true\r\nij_javascript_space_after_property_colon = true\r\nij_javascript_space_after_quest = true\r\nij_javascript_space_after_type_colon = true\r\nij_javascript_space_after_unary_not = false\r\nij_javascript_space_before_async_arrow_lparen = true\r\nij_javascript_space_before_catch_keyword = true\r\nij_javascript_space_before_catch_left_brace = true\r\nij_javascript_space_before_catch_parentheses = true\r\nij_javascript_space_before_class_lbrace = true\r\nij_javascript_space_before_class_left_brace = true\r\nij_javascript_space_before_colon = true\r\nij_javascript_space_before_comma = false\r\nij_javascript_space_before_do_left_brace = true\r\nij_javascript_space_before_else_keyword = true\r\nij_javascript_space_before_else_left_brace = true\r\nij_javascript_space_before_finally_keyword = true\r\nij_javascript_space_before_finally_left_brace = true\r\nij_javascript_space_before_for_left_brace = true\r\nij_javascript_space_before_for_parentheses = true\r\nij_javascript_space_before_for_semicolon = false\r\nij_javascript_space_before_function_left_parenth = true\r\nij_javascript_space_before_generator_mult = false\r\nij_javascript_space_before_if_left_brace = true\r\nij_javascript_space_before_if_parentheses = true\r\nij_javascript_space_before_method_call_parentheses = false\r\nij_javascript_space_before_method_left_brace = true\r\nij_javascript_space_before_method_parentheses = false\r\nij_javascript_space_before_property_colon = false\r\nij_javascript_space_before_quest = true\r\nij_javascript_space_before_switch_left_brace = true\r\nij_javascript_space_before_switch_parentheses = true\r\nij_javascript_space_before_try_left_brace = true\r\nij_javascript_space_before_type_colon = false\r\nij_javascript_space_before_unary_not = false\r\nij_javascript_space_before_while_keyword = true\r\nij_javascript_space_before_while_left_brace = true\r\nij_javascript_space_before_while_parentheses = true\r\nij_javascript_spaces_around_additive_operators = true\r\nij_javascript_spaces_around_arrow_function_operator = true\r\nij_javascript_spaces_around_assignment_operators = true\r\nij_javascript_spaces_around_bitwise_operators = true\r\nij_javascript_spaces_around_equality_operators = true\r\nij_javascript_spaces_around_logical_operators = true\r\nij_javascript_spaces_around_multiplicative_operators = true\r\nij_javascript_spaces_around_relational_operators = true\r\nij_javascript_spaces_around_shift_operators = true\r\nij_javascript_spaces_around_unary_operator = false\r\nij_javascript_spaces_within_array_initializer_brackets = false\r\nij_javascript_spaces_within_brackets = false\r\nij_javascript_spaces_within_catch_parentheses = false\r\nij_javascript_spaces_within_for_parentheses = false\r\nij_javascript_spaces_within_if_parentheses = false\r\nij_javascript_spaces_within_imports = false\r\nij_javascript_spaces_within_interpolation_expressions = false\r\nij_javascript_spaces_within_method_call_parentheses = false\r\nij_javascript_spaces_within_method_parentheses = false\r\nij_javascript_spaces_within_object_literal_braces = false\r\nij_javascript_spaces_within_object_type_braces = true\r\nij_javascript_spaces_within_parentheses = false\r\nij_javascript_spaces_within_switch_parentheses = false\r\nij_javascript_spaces_within_type_assertion = false\r\nij_javascript_spaces_within_union_types = true\r\nij_javascript_spaces_within_while_parentheses = false\r\nij_javascript_special_else_if_treatment = true\r\nij_javascript_ternary_operation_signs_on_next_line = true\r\nij_javascript_ternary_operation_wrap = normal\r\nij_javascript_union_types_wrap = on_every_item\r\nij_javascript_use_chained_calls_group_indents = false\r\nij_javascript_use_double_quotes = true\r\nij_javascript_use_explicit_js_extension = global\r\nij_javascript_use_path_mapping = always\r\nij_javascript_use_public_modifier = false\r\nij_javascript_use_semicolon_after_statement = true\r\nij_javascript_var_declaration_wrap = normal\r\nij_javascript_while_brace_force = always\r\nij_javascript_while_on_new_line = false\r\nij_javascript_wrap_comments = false\r\n\r\n[{*.cjsx, *.coffee}]\r\nij_continuation_indent_size = 2\r\nij_coffeescript_align_function_body = false\r\nij_coffeescript_align_imports = false\r\nij_coffeescript_align_multiline_array_initializer_expression = true\r\nij_coffeescript_align_multiline_parameters = true\r\nij_coffeescript_align_multiline_parameters_in_calls = false\r\nij_coffeescript_align_object_properties = 0\r\nij_coffeescript_align_union_types = false\r\nij_coffeescript_align_var_statements = 0\r\nij_coffeescript_array_initializer_new_line_after_left_brace = false\r\nij_coffeescript_array_initializer_right_brace_on_new_line = false\r\nij_coffeescript_array_initializer_wrap = normal\r\nij_coffeescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**\r\nij_coffeescript_blank_lines_around_function = 1\r\nij_coffeescript_call_parameters_new_line_after_left_paren = false\r\nij_coffeescript_call_parameters_right_paren_on_new_line = false\r\nij_coffeescript_call_parameters_wrap = normal\r\nij_coffeescript_chained_call_dot_on_new_line = true\r\nij_coffeescript_comma_on_new_line = false\r\nij_coffeescript_enforce_trailing_comma = keep\r\nij_coffeescript_field_prefix = _\r\nij_coffeescript_file_name_style = relaxed\r\nij_coffeescript_force_quote_style = false\r\nij_coffeescript_force_semicolon_style = false\r\nij_coffeescript_function_expression_brace_style = end_of_line\r\nij_coffeescript_import_merge_members = global\r\nij_coffeescript_import_prefer_absolute_path = global\r\nij_coffeescript_import_sort_members = true\r\nij_coffeescript_import_sort_module_name = false\r\nij_coffeescript_import_use_node_resolution = true\r\nij_coffeescript_imports_wrap = on_every_item\r\nij_coffeescript_indent_chained_calls = true\r\nij_coffeescript_indent_package_children = 0\r\nij_coffeescript_jsx_attribute_value = braces\r\nij_coffeescript_keep_blank_lines_in_code = 2\r\nij_coffeescript_keep_first_column_comment = true\r\nij_coffeescript_keep_indents_on_empty_lines = false\r\nij_coffeescript_keep_line_breaks = true\r\nij_coffeescript_keep_simple_methods_in_one_line = false\r\nij_coffeescript_method_parameters_new_line_after_left_paren = false\r\nij_coffeescript_method_parameters_right_paren_on_new_line = false\r\nij_coffeescript_method_parameters_wrap = off\r\nij_coffeescript_object_literal_wrap = on_every_item\r\nij_coffeescript_prefer_as_type_cast = false\r\nij_coffeescript_prefer_explicit_types_function_expression_returns = false\r\nij_coffeescript_prefer_explicit_types_function_returns = false\r\nij_coffeescript_prefer_explicit_types_vars_fields = false\r\nij_coffeescript_reformat_c_style_comments = false\r\nij_coffeescript_space_after_comma = true\r\nij_coffeescript_space_after_dots_in_rest_parameter = false\r\nij_coffeescript_space_after_generator_mult = true\r\nij_coffeescript_space_after_property_colon = true\r\nij_coffeescript_space_after_type_colon = true\r\nij_coffeescript_space_after_unary_not = false\r\nij_coffeescript_space_before_async_arrow_lparen = true\r\nij_coffeescript_space_before_class_lbrace = true\r\nij_coffeescript_space_before_comma = false\r\nij_coffeescript_space_before_function_left_parenth = true\r\nij_coffeescript_space_before_generator_mult = false\r\nij_coffeescript_space_before_property_colon = false\r\nij_coffeescript_space_before_type_colon = false\r\nij_coffeescript_space_before_unary_not = false\r\nij_coffeescript_spaces_around_additive_operators = true\r\nij_coffeescript_spaces_around_arrow_function_operator = true\r\nij_coffeescript_spaces_around_assignment_operators = true\r\nij_coffeescript_spaces_around_bitwise_operators = true\r\nij_coffeescript_spaces_around_equality_operators = true\r\nij_coffeescript_spaces_around_logical_operators = true\r\nij_coffeescript_spaces_around_multiplicative_operators = true\r\nij_coffeescript_spaces_around_relational_operators = true\r\nij_coffeescript_spaces_around_shift_operators = true\r\nij_coffeescript_spaces_around_unary_operator = false\r\nij_coffeescript_spaces_within_array_initializer_braces = false\r\nij_coffeescript_spaces_within_array_initializer_brackets = false\r\nij_coffeescript_spaces_within_imports = false\r\nij_coffeescript_spaces_within_index_brackets = false\r\nij_coffeescript_spaces_within_interpolation_expressions = false\r\nij_coffeescript_spaces_within_method_call_parentheses = false\r\nij_coffeescript_spaces_within_method_parentheses = false\r\nij_coffeescript_spaces_within_object_braces = false\r\nij_coffeescript_spaces_within_object_literal_braces = false\r\nij_coffeescript_spaces_within_object_type_braces = true\r\nij_coffeescript_spaces_within_range_brackets = false\r\nij_coffeescript_spaces_within_type_assertion = false\r\nij_coffeescript_spaces_within_union_types = true\r\nij_coffeescript_union_types_wrap = on_every_item\r\nij_coffeescript_use_chained_calls_group_indents = false\r\nij_coffeescript_use_double_quotes = true\r\nij_coffeescript_use_explicit_js_extension = global\r\nij_coffeescript_use_path_mapping = always\r\nij_coffeescript_use_public_modifier = false\r\nij_coffeescript_use_semicolon_after_statement = false\r\nij_coffeescript_var_declaration_wrap = normal\r\n\r\n[{*.ft, *.vm, *.vsl}]\r\nindent_size = 4\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_vtl_keep_indents_on_empty_lines = false\r\n\r\n[{*.gant, *.gradle, *.groovy, *.gson, *.gy}]\r\nindent_size = 4\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_groovy_align_group_field_declarations = false\r\nij_groovy_align_multiline_array_initializer_expression = false\r\nij_groovy_align_multiline_assignment = false\r\nij_groovy_align_multiline_binary_operation = false\r\nij_groovy_align_multiline_chained_methods = false\r\nij_groovy_align_multiline_extends_list = false\r\nij_groovy_align_multiline_for = true\r\nij_groovy_align_multiline_list_or_map = true\r\nij_groovy_align_multiline_method_parentheses = false\r\nij_groovy_align_multiline_parameters = true\r\nij_groovy_align_multiline_parameters_in_calls = false\r\nij_groovy_align_multiline_resources = true\r\nij_groovy_align_multiline_ternary_operation = false\r\nij_groovy_align_multiline_throws_list = false\r\nij_groovy_align_named_args_in_map = true\r\nij_groovy_align_throws_keyword = false\r\nij_groovy_array_initializer_new_line_after_left_brace = false\r\nij_groovy_array_initializer_right_brace_on_new_line = false\r\nij_groovy_array_initializer_wrap = off\r\nij_groovy_assert_statement_wrap = off\r\nij_groovy_assignment_wrap = off\r\nij_groovy_binary_operation_wrap = off\r\nij_groovy_blank_lines_after_class_header = 0\r\nij_groovy_blank_lines_after_imports = 1\r\nij_groovy_blank_lines_after_package = 1\r\nij_groovy_blank_lines_around_class = 1\r\nij_groovy_blank_lines_around_field = 0\r\nij_groovy_blank_lines_around_field_in_interface = 0\r\nij_groovy_blank_lines_around_method = 1\r\nij_groovy_blank_lines_around_method_in_interface = 1\r\nij_groovy_blank_lines_before_imports = 1\r\nij_groovy_blank_lines_before_method_body = 0\r\nij_groovy_blank_lines_before_package = 0\r\nij_groovy_block_brace_style = end_of_line\r\nij_groovy_block_comment_at_first_column = true\r\nij_groovy_call_parameters_new_line_after_left_paren = false\r\nij_groovy_call_parameters_right_paren_on_new_line = false\r\nij_groovy_call_parameters_wrap = off\r\nij_groovy_catch_on_new_line = false\r\nij_groovy_class_annotation_wrap = split_into_lines\r\nij_groovy_class_brace_style = end_of_line\r\nij_groovy_class_count_to_use_import_on_demand = 5\r\nij_groovy_do_while_brace_force = never\r\nij_groovy_else_on_new_line = false\r\nij_groovy_enum_constants_wrap = off\r\nij_groovy_extends_keyword_wrap = off\r\nij_groovy_extends_list_wrap = off\r\nij_groovy_field_annotation_wrap = split_into_lines\r\nij_groovy_finally_on_new_line = false\r\nij_groovy_for_brace_force = never\r\nij_groovy_for_statement_new_line_after_left_paren = false\r\nij_groovy_for_statement_right_paren_on_new_line = false\r\nij_groovy_for_statement_wrap = off\r\nij_groovy_if_brace_force = never\r\nij_groovy_import_annotation_wrap = 2\r\nij_groovy_indent_case_from_switch = true\r\nij_groovy_indent_label_blocks = true\r\nij_groovy_insert_inner_class_imports = false\r\nij_groovy_keep_blank_lines_before_right_brace = 2\r\nij_groovy_keep_blank_lines_in_code = 2\r\nij_groovy_keep_blank_lines_in_declarations = 2\r\nij_groovy_keep_control_statement_in_one_line = true\r\nij_groovy_keep_first_column_comment = true\r\nij_groovy_keep_indents_on_empty_lines = false\r\nij_groovy_keep_line_breaks = true\r\nij_groovy_keep_multiple_expressions_in_one_line = false\r\nij_groovy_keep_simple_blocks_in_one_line = false\r\nij_groovy_keep_simple_classes_in_one_line = true\r\nij_groovy_keep_simple_lambdas_in_one_line = true\r\nij_groovy_keep_simple_methods_in_one_line = true\r\nij_groovy_label_indent_absolute = false\r\nij_groovy_label_indent_size = 0\r\nij_groovy_lambda_brace_style = end_of_line\r\nij_groovy_layout_static_imports_separately = true\r\nij_groovy_line_comment_add_space = false\r\nij_groovy_line_comment_at_first_column = true\r\nij_groovy_method_annotation_wrap = split_into_lines\r\nij_groovy_method_brace_style = end_of_line\r\nij_groovy_method_call_chain_wrap = off\r\nij_groovy_method_parameters_new_line_after_left_paren = false\r\nij_groovy_method_parameters_right_paren_on_new_line = false\r\nij_groovy_method_parameters_wrap = off\r\nij_groovy_modifier_list_wrap = false\r\nij_groovy_names_count_to_use_import_on_demand = 3\r\nij_groovy_parameter_annotation_wrap = off\r\nij_groovy_parentheses_expression_new_line_after_left_paren = false\r\nij_groovy_parentheses_expression_right_paren_on_new_line = false\r\nij_groovy_prefer_parameters_wrap = false\r\nij_groovy_resource_list_new_line_after_left_paren = false\r\nij_groovy_resource_list_right_paren_on_new_line = false\r\nij_groovy_resource_list_wrap = off\r\nij_groovy_space_after_assert_separator = true\r\nij_groovy_space_after_colon = true\r\nij_groovy_space_after_comma = true\r\nij_groovy_space_after_comma_in_type_arguments = true\r\nij_groovy_space_after_for_semicolon = true\r\nij_groovy_space_after_quest = true\r\nij_groovy_space_after_type_cast = true\r\nij_groovy_space_before_annotation_parameter_list = false\r\nij_groovy_space_before_array_initializer_left_brace = false\r\nij_groovy_space_before_assert_separator = false\r\nij_groovy_space_before_catch_keyword = true\r\nij_groovy_space_before_catch_left_brace = true\r\nij_groovy_space_before_catch_parentheses = true\r\nij_groovy_space_before_class_left_brace = true\r\nij_groovy_space_before_closure_left_brace = true\r\nij_groovy_space_before_colon = true\r\nij_groovy_space_before_comma = false\r\nij_groovy_space_before_do_left_brace = true\r\nij_groovy_space_before_else_keyword = true\r\nij_groovy_space_before_else_left_brace = true\r\nij_groovy_space_before_finally_keyword = true\r\nij_groovy_space_before_finally_left_brace = true\r\nij_groovy_space_before_for_left_brace = true\r\nij_groovy_space_before_for_parentheses = true\r\nij_groovy_space_before_for_semicolon = false\r\nij_groovy_space_before_if_left_brace = true\r\nij_groovy_space_before_if_parentheses = true\r\nij_groovy_space_before_method_call_parentheses = false\r\nij_groovy_space_before_method_left_brace = true\r\nij_groovy_space_before_method_parentheses = false\r\nij_groovy_space_before_quest = true\r\nij_groovy_space_before_switch_left_brace = true\r\nij_groovy_space_before_switch_parentheses = true\r\nij_groovy_space_before_synchronized_left_brace = true\r\nij_groovy_space_before_synchronized_parentheses = true\r\nij_groovy_space_before_try_left_brace = true\r\nij_groovy_space_before_try_parentheses = true\r\nij_groovy_space_before_while_keyword = true\r\nij_groovy_space_before_while_left_brace = true\r\nij_groovy_space_before_while_parentheses = true\r\nij_groovy_space_in_named_argument = true\r\nij_groovy_space_in_named_argument_before_colon = false\r\nij_groovy_space_within_empty_array_initializer_braces = false\r\nij_groovy_space_within_empty_method_call_parentheses = false\r\nij_groovy_spaces_around_additive_operators = true\r\nij_groovy_spaces_around_assignment_operators = true\r\nij_groovy_spaces_around_bitwise_operators = true\r\nij_groovy_spaces_around_equality_operators = true\r\nij_groovy_spaces_around_lambda_arrow = true\r\nij_groovy_spaces_around_logical_operators = true\r\nij_groovy_spaces_around_multiplicative_operators = true\r\nij_groovy_spaces_around_regex_operators = true\r\nij_groovy_spaces_around_relational_operators = true\r\nij_groovy_spaces_around_shift_operators = true\r\nij_groovy_spaces_within_annotation_parentheses = false\r\nij_groovy_spaces_within_array_initializer_braces = false\r\nij_groovy_spaces_within_braces = true\r\nij_groovy_spaces_within_brackets = false\r\nij_groovy_spaces_within_cast_parentheses = false\r\nij_groovy_spaces_within_catch_parentheses = false\r\nij_groovy_spaces_within_for_parentheses = false\r\nij_groovy_spaces_within_gstring_injection_braces = false\r\nij_groovy_spaces_within_if_parentheses = false\r\nij_groovy_spaces_within_list_or_map = false\r\nij_groovy_spaces_within_method_call_parentheses = false\r\nij_groovy_spaces_within_method_parentheses = false\r\nij_groovy_spaces_within_parentheses = false\r\nij_groovy_spaces_within_switch_parentheses = false\r\nij_groovy_spaces_within_synchronized_parentheses = false\r\nij_groovy_spaces_within_try_parentheses = false\r\nij_groovy_spaces_within_tuple_expression = false\r\nij_groovy_spaces_within_while_parentheses = false\r\nij_groovy_special_else_if_treatment = true\r\nij_groovy_ternary_operation_wrap = off\r\nij_groovy_throws_keyword_wrap = off\r\nij_groovy_throws_list_wrap = off\r\nij_groovy_use_flying_geese_braces = false\r\nij_groovy_use_fq_class_names = false\r\nij_groovy_use_fq_class_names_in_javadoc = true\r\nij_groovy_use_relative_indents = false\r\nij_groovy_use_single_class_imports = true\r\nij_groovy_variable_annotation_wrap = off\r\nij_groovy_while_brace_force = never\r\nij_groovy_while_on_new_line = false\r\nij_groovy_wrap_long_lines = false\r\n\r\n[{*.gradle.kts, *.kt, *.kts, *.main.kts}]\r\nij_kotlin_align_in_columns_case_branch = false\r\nij_kotlin_align_multiline_binary_operation = false\r\nij_kotlin_align_multiline_extends_list = false\r\nij_kotlin_align_multiline_method_parentheses = false\r\nij_kotlin_align_multiline_parameters = true\r\nij_kotlin_align_multiline_parameters_in_calls = false\r\nij_kotlin_assignment_wrap = on_every_item\r\nij_kotlin_blank_lines_after_class_header = 0\r\nij_kotlin_blank_lines_around_block_when_branches = 0\r\nij_kotlin_block_comment_at_first_column = true\r\nij_kotlin_call_parameters_new_line_after_left_paren = true\r\nij_kotlin_call_parameters_right_paren_on_new_line = false\r\nij_kotlin_call_parameters_wrap = on_every_item\r\nij_kotlin_catch_on_new_line = false\r\nij_kotlin_class_annotation_wrap = split_into_lines\r\nij_kotlin_continuation_indent_for_chained_calls = true\r\nij_kotlin_continuation_indent_for_expression_bodies = true\r\nij_kotlin_continuation_indent_in_argument_lists = true\r\nij_kotlin_continuation_indent_in_elvis = true\r\nij_kotlin_continuation_indent_in_if_conditions = true\r\nij_kotlin_continuation_indent_in_parameter_lists = true\r\nij_kotlin_continuation_indent_in_supertype_lists = true\r\nij_kotlin_else_on_new_line = false\r\nij_kotlin_enum_constants_wrap = off\r\nij_kotlin_extends_list_wrap = on_every_item\r\nij_kotlin_field_annotation_wrap = split_into_lines\r\nij_kotlin_finally_on_new_line = false\r\nij_kotlin_if_rparen_on_new_line = false\r\nij_kotlin_import_nested_classes = false\r\nij_kotlin_insert_whitespaces_in_simple_one_line_method = true\r\nij_kotlin_keep_blank_lines_before_right_brace = 1\r\nij_kotlin_keep_blank_lines_in_code = 1\r\nij_kotlin_keep_blank_lines_in_declarations = 1\r\nij_kotlin_keep_first_column_comment = true\r\nij_kotlin_keep_indents_on_empty_lines = false\r\nij_kotlin_keep_line_breaks = true\r\nij_kotlin_lbrace_on_next_line = false\r\nij_kotlin_line_comment_add_space = false\r\nij_kotlin_line_comment_at_first_column = true\r\nij_kotlin_method_annotation_wrap = split_into_lines\r\nij_kotlin_method_call_chain_wrap = on_every_item\r\nij_kotlin_method_parameters_new_line_after_left_paren = true\r\nij_kotlin_method_parameters_right_paren_on_new_line = false\r\nij_kotlin_method_parameters_wrap = on_every_item\r\nij_kotlin_name_count_to_use_star_import = 5\r\nij_kotlin_name_count_to_use_star_import_for_members = 3\r\nij_kotlin_parameter_annotation_wrap = on_every_item\r\nij_kotlin_space_after_comma = true\r\nij_kotlin_space_after_extend_colon = true\r\nij_kotlin_space_after_type_colon = true\r\nij_kotlin_space_before_catch_parentheses = true\r\nij_kotlin_space_before_comma = false\r\nij_kotlin_space_before_extend_colon = true\r\nij_kotlin_space_before_for_parentheses = true\r\nij_kotlin_space_before_if_parentheses = true\r\nij_kotlin_space_before_lambda_arrow = true\r\nij_kotlin_space_before_type_colon = false\r\nij_kotlin_space_before_when_parentheses = true\r\nij_kotlin_space_before_while_parentheses = true\r\nij_kotlin_spaces_around_additive_operators = true\r\nij_kotlin_spaces_around_assignment_operators = true\r\nij_kotlin_spaces_around_equality_operators = true\r\nij_kotlin_spaces_around_function_type_arrow = true\r\nij_kotlin_spaces_around_logical_operators = true\r\nij_kotlin_spaces_around_multiplicative_operators = true\r\nij_kotlin_spaces_around_range = false\r\nij_kotlin_spaces_around_relational_operators = true\r\nij_kotlin_spaces_around_unary_operator = false\r\nij_kotlin_spaces_around_when_arrow = true\r\nij_kotlin_variable_annotation_wrap = off\r\nij_kotlin_while_on_new_line = false\r\nij_kotlin_wrap_elvis_expressions = 1\r\nij_kotlin_wrap_expression_body_functions = 0\r\nij_kotlin_wrap_first_method_in_call_chain = false\r\n\r\n[{*.htm, *.html, *.ng, *.sht, *.shtm, *.shtml}]\r\nij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3\r\nij_html_align_attributes = true\r\nij_html_align_text = false\r\nij_html_attribute_wrap = normal\r\nij_html_block_comment_at_first_column = true\r\nij_html_do_not_align_children_of_min_lines = 0\r\nij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p\r\nij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot\r\nij_html_enforce_quotes = false\r\nij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var\r\nij_html_keep_blank_lines = 2\r\nij_html_keep_indents_on_empty_lines = false\r\nij_html_keep_line_breaks = true\r\nij_html_keep_line_breaks_in_text = true\r\nij_html_keep_whitespaces = false\r\nij_html_keep_whitespaces_inside = span, pre, textarea\r\nij_html_line_comment_at_first_column = true\r\nij_html_new_line_after_last_attribute = never\r\nij_html_new_line_before_first_attribute = never\r\nij_html_quote_style = double\r\nij_html_remove_new_line_before_tags = br\r\nij_html_space_after_tag_name = false\r\nij_html_space_around_equality_in_attribute = false\r\nij_html_space_inside_empty_tag = false\r\nij_html_text_wrap = normal\r\n\r\n[{*.jsf, *.jsp, *.jspf, *.tag, *.tagf, *.xjsp}]\r\nindent_size = 4\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_jsp_jsp_prefer_comma_separated_import_list = false\r\nij_jsp_keep_indents_on_empty_lines = false\r\n\r\n[{*.jspx, *.tagx}]\r\nindent_size = 4\r\ntab_width = 4\r\nij_continuation_indent_size = 8\r\nij_jspx_keep_indents_on_empty_lines = false\r\n\r\n[{*.properties, spring.handlers, spring.schemas}]\r\nij_properties_align_group_field_declarations = false\r\nij_properties_keep_blank_lines = false\r\nij_properties_key_value_delimiter = equals\r\nij_properties_spaces_around_key_value_delimiter = false\r\n\r\n[{*.yaml, *.yml}]\r\nij_yaml_keep_indents_on_empty_lines = false\r\nij_yaml_keep_line_breaks = true\r\n"
  },
  {
    "path": ".gitignore",
    "content": "# Created by .ignore support plugin (hsz.mobi)\r\n### Maven template\r\ntarget/\r\npom.xml.tag\r\npom.xml.releaseBackup\r\npom.xml.versionsBackup\r\npom.xml.next\r\nrelease.properties\r\ndependency-reduced-pom.xml\r\nbuildNumber.properties\r\n.mvn/timing.properties\r\n# https://github.com/takari/maven-wrapper#usage-without-binary-jar\r\n.mvn/wrapper/maven-wrapper.jar\r\n\r\n### Linux template\r\n*~\r\n\r\n# temporary files which can be created if a process still has a handle open of a deleted file\r\n.fuse_hidden*\r\n\r\n# KDE directory preferences\r\n.directory\r\n\r\n# Linux trash folder which might appear on any partition or disk\r\n.Trash-*\r\n\r\n# .nfs files are created when an open file is removed but is still being accessed\r\n.nfs*\r\n\r\n### Windows template\r\n# Windows thumbnail cache files\r\nThumbs.db\r\nThumbs.db:encryptable\r\nehthumbs.db\r\nehthumbs_vista.db\r\n\r\n# Dump file\r\n*.stackdump\r\n\r\n# Folder config file\r\n[Dd]esktop.ini\r\n\r\n# Recycle Bin used on file shares\r\n$RECYCLE.BIN/\r\n\r\n# Windows Installer files\r\n*.cab\r\n*.msi\r\n*.msix\r\n*.msm\r\n*.msp\r\n\r\n# Windows shortcuts\r\n*.lnk\r\n\r\n### JetBrains template\r\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider\r\n# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839\r\n\r\n# User-specific stuff\r\n.idea/**/workspace.xml\r\n.idea/**/tasks.xml\r\n.idea/**/usage.statistics.xml\r\n.idea/**/dictionaries\r\n.idea/**/shelf\r\n.idea/**\r\n\r\n# Generated files\r\n.idea/**/contentModel.xml\r\n\r\n# Sensitive or high-churn files\r\n.idea/**/dataSources/\r\n.idea/**/dataSources.ids\r\n.idea/**/dataSources.local.xml\r\n.idea/**/sqlDataSources.xml\r\n.idea/**/dynamic.xml\r\n.idea/**/uiDesigner.xml\r\n.idea/**/dbnavigator.xml\r\n\r\n# Gradle\r\n.idea/**/gradle.xml\r\n.idea/**/libraries\r\n\r\n*.iml\r\n\r\n# Gradle and Maven with auto-import\r\n# When using Gradle or Maven with auto-import, you should exclude module files,\r\n# since they will be recreated, and may cause churn.  Uncomment if using\r\n# auto-import.\r\n# .idea/artifacts\r\n# .idea/compiler.xml\r\n# .idea/jarRepositories.xml\r\n# .idea/modules.xml\r\n# .idea/*.iml\r\n# .idea/modules\r\n# *.iml\r\n# *.ipr\r\n\r\n# CMake\r\ncmake-build-*/\r\n\r\n# Mongo Explorer plugin\r\n.idea/**/mongoSettings.xml\r\n\r\n# File-based project format\r\n*.iws\r\n\r\n# IntelliJ\r\nout/\r\n\r\n# mpeltonen/sbt-idea plugin\r\n.idea_modules/\r\n\r\n# JIRA plugin\r\natlassian-ide-plugin.xml\r\n\r\n# Cursive Clojure plugin\r\n.idea/replstate.xml\r\n\r\n# Crashlytics plugin (for Android Studio and IntelliJ)\r\ncom_crashlytics_export_strings.xml\r\ncrashlytics.properties\r\ncrashlytics-build.properties\r\nfabric.properties\r\n\r\n# Editor-based Rest Client\r\n.idea/httpRequests\r\n\r\n# Android studio 3.1+ serialized cache file\r\n.idea/caches/build_file_checksums.ser\r\n\r\n### macOS template\r\n# General\r\n.DS_Store\r\n.AppleDouble\r\n.LSOverride\r\n\r\n# Icon must end with two \\r\r\nIcon\r\n\r\n# Thumbnails\r\n._*\r\n\r\n# Files that might appear in the root of a volume\r\n.DocumentRevisions-V100\r\n.fseventsd\r\n.Spotlight-V100\r\n.TemporaryItems\r\n.Trashes\r\n.VolumeIcon.icns\r\n.com.apple.timemachine.donotpresent\r\n\r\n# Directories potentially created on remote AFP share\r\n.AppleDB\r\n.AppleDesktop\r\nNetwork Trash Folder\r\nTemporary Items\r\n.apdisk\r\n\r\n### Java template\r\n# Compiled class file\r\n*.class\r\n\r\n# Log file\r\n*.log\r\n\r\n# BlueJ files\r\n*.ctxt\r\n\r\n# Mobile Tools for Java (J2ME)\r\n.mtj.tmp/\r\n\r\n# Package Files #\r\n*.jar\r\n*.war\r\n*.nar\r\n*.ear\r\n*.zip\r\n*.tar.gz\r\n*.rar\r\n\r\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\r\nhs_err_pid*\r\n\r\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Simplix Softworks\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n  <img src=\"https://i.imgur.com/vmfZcvS.png\" />\n</p>\n\n\n# Cirrus\n[![Build Status](http://ci.exceptionflug.de/buildStatus/icon?job=Cirrus)](http://ci.exceptionflug.de/job/Cirrus/) [![JetBrains IntelliJ Plugins](https://img.shields.io/jetbrains/plugin/v/15194-cirrus-tooling)](https://plugins.jetbrains.com/plugin/15194-cirrus-tooling) [![Discord](https://img.shields.io/discord/752533664696369204?label=Discord)](https://discord.simplixsoft.com/) ![GitHub](https://img.shields.io/github/license/Exceptionflug/Protocolize)\n\nMenu Framework.\nCirrus enables you to develop platform-independent versatile graphical menus for Spigot, BungeeCord, and Velocity! The\ngoal of Cirrus is to aim for maximum compatibility. Cirrus had been tested on several well-known BungeeCord-Forks as\nwell on all Spigot versions beginning from 1.16.5 till the latest release. The first-ever way of creating menus for Velocity.\n\n# WIP\n\nCirrus is currently WIP. The documentation is invalid in parts. We will publish a stable version soon.\nSpigot & BungeeCord implementations will work, Velocity implementations are currently very experimental.\nWe aim to publish documentation & production ready versions in the coming month.\n\n## Version\nCurrent version is:\n- Stable: 2.0.0\n- Development: 2.1.0-SNAPHOT\n\n## PR\n\nIf you have any improvements regarding Cirrus feel free to create a PR. We are happy to review & merge it.\nKeep in mind that to use our codestyle as defined in .editorconfig.\n\n## Platforms\n\nOn Spigot Cirrus is fully independent of third party plugins. Protocolize is needed only only if Cirrus is used on\nproxies like BungeeCord or Velocity.\n\n- Spigot \n- BungeeCord\n- Velocity (WIP)\n\n## Supported Bukkit Versions\n\nDue to the changes in the API we only officially support 1.16.5-LATEST (which is 1.19 by the time this is written)\nSince Cirrus is designed to be mostly version independent, older versions will likely function as well but they are deprecated (so we won't attempt to resolve issues with these versions).\n\n## Tooling\n\nCirrus offers an IntelliJ plugin to enhance the usability of Cirrus. It provides a realtime preview while editing menu\nconfiguration files.\n\n[![JetBrains IntelliJ plugins](https://img.shields.io/jetbrains/plugin/d/15194-cirrus-tooling)](https://plugins.jetbrains.com/plugin/15194-cirrus-tooling)\n\n![Tooling](https://i.imgur.com/88pvZ8G.gif)\n\n## Requirements\n\n### Protocolize\n\nCirrus is powered by [Protocolize](https://github.com/Exceptionflug/protocolize). A protocol manipulation library by one\nof the Simplix Softworks founders, Exceptionflug. Protocolize enables you to do so much more on BungeeCord/Velocity!\n\n## Installation\n\nJust shade and relocate the platform module into your own plugin. Don't forget to call the `CirrusSpigot`\n, `CirrusBungeeCord` or `CirrusVelocity` init method.\n\n### More developer documentation\n\nCheck out the [wiki](https://github.com/Simplix-Softworks/Cirrus/wiki) for further information on how to use Cirrus in\nyour application.\n"
  },
  {
    "path": "cirrus-bungeecord/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <artifactId>cirrus-bungeecord</artifactId>\n\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <artifactId>cirrus</artifactId>\n        <groupId>dev.simplix.cirrus</groupId>\n        <version>2.0.0</version>\n    </parent>\n    <version>${cirrus.version}</version>\n\n    <dependencies>\n        <dependency>\n            <artifactId>cirrus-common</artifactId>\n            <groupId>dev.simplix.cirrus</groupId>\n            <scope>compile</scope>\n            <version>${cirrus.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>net.md-5</groupId>\n            <artifactId>bungeecord-api</artifactId>\n            <version>1.21-R0.1-SNAPSHOT</version>\n            <scope>provided</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>${project.name}-${project.version}</finalName>\n        <resources>\n            <resource>\n                <directory>src/main/resources</directory>\n                <filtering>true</filtering>\n            </resource>\n        </resources>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-shade-plugin</artifactId>\n                <version>3.0.0</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                    </execution>\n                </executions>\n                <configuration>\n                    <minimizeJar>false</minimizeJar>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <configuration>\n                    <source>8</source>\n                    <target>8</target>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-source-plugin</artifactId>\n                <version>3.0.1</version>\n                <executions>\n                    <execution>\n                        <id>attach-sources</id>\n                        <phase>deploy</phase>\n                        <goals>\n                            <goal>jar-no-fork</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-javadoc-plugin</artifactId>\n                <version>3.0.1</version>\n                <executions>\n                    <execution>\n                        <id>attach-javadocs</id>\n                        <goals>\n                            <goal>jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n</project>"
  },
  {
    "path": "cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/BungeeCordPlayerWrapper.java",
    "content": "package dev.simplix.cirrus.bungeecord;\r\n\r\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\r\nimport dev.simplix.protocolize.api.Protocolize;\r\nimport dev.simplix.protocolize.api.player.ProtocolizePlayer;\r\nimport lombok.NonNull;\r\nimport net.md_5.bungee.api.connection.ProxiedPlayer;\r\n\r\nimport java.util.UUID;\r\n\r\npublic class BungeeCordPlayerWrapper implements PlayerWrapper {\r\n\r\n    private final ProtocolizePlayer protocolizePlayer;\r\n    private final ProxiedPlayer handle;\r\n\r\n    public BungeeCordPlayerWrapper(@NonNull ProxiedPlayer handle) {\r\n        this.handle = handle;\r\n        this.protocolizePlayer = Protocolize.playerProvider().player(handle.getUniqueId());\r\n    }\r\n\r\n    @Override\r\n    public UUID uniqueId() {\r\n        return this.handle.getUniqueId();\r\n    }\r\n\r\n    @Override\r\n    public String name() {\r\n        return this.handle.getName();\r\n    }\r\n\r\n    @Override\r\n    public int protocolVersion() {\r\n        return this.protocolizePlayer.protocolVersion();\r\n    }\r\n\r\n    @Override\r\n    public void sendMessage(@NonNull String msg) {\r\n        this.handle.sendMessage(msg);\r\n    }\r\n\r\n    @Override\r\n    public void closeInventory() {\r\n        this.protocolizePlayer.closeInventory();\r\n    }\r\n\r\n    @Override\r\n    public boolean hasPermission(@NonNull String permission) {\r\n        return this.handle.hasPermission(permission);\r\n    }\r\n\r\n    @Override\r\n    public <T> T handle() {\r\n        return (T) this.handle;\r\n    }\r\n\r\n    public ProtocolizePlayer protocolizePlayer() {\r\n        return this.protocolizePlayer;\r\n    }\r\n}\r\n"
  },
  {
    "path": "cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/CirrusBungeeCord.java",
    "content": "package dev.simplix.cirrus.bungeecord;\n\nimport dev.simplix.cirrus.bungeecord.converters.ItemModelConverter;\nimport dev.simplix.cirrus.bungeecord.converters.ItemStackConverter;\nimport dev.simplix.cirrus.bungeecord.converters.PlayerConverter;\nimport dev.simplix.cirrus.bungeecord.converters.PlayerUniqueIdConverter;\nimport dev.simplix.cirrus.bungeecord.listeners.QuitListener;\nimport dev.simplix.cirrus.bungeecord.protocolize.ProtocolizeMenuBuilder;\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.common.effect.MenuAnimator;\nimport dev.simplix.cirrus.common.item.CirrusItem;\nimport dev.simplix.cirrus.common.menu.MenuBuilder;\nimport dev.simplix.protocolize.api.item.ItemStack;\nimport net.md_5.bungee.api.ProxyServer;\nimport net.md_5.bungee.api.connection.ProxiedPlayer;\nimport net.md_5.bungee.api.plugin.Plugin;\n\nimport java.util.UUID;\nimport java.util.concurrent.TimeUnit;\n\npublic class CirrusBungeeCord {\n\n    private static Plugin plugin;\n\n    static {\n        // Players\n        Converters.register(ProxiedPlayer.class, PlayerWrapper.class, new PlayerConverter());\n        Converters.register(UUID.class, PlayerWrapper.class, new PlayerUniqueIdConverter());\n\n        // Items\n        Converters.register(ItemStack.class, MenuItemWrapper.class, new ItemStackConverter());\n        Converters.register(CirrusItem.class, InventoryMenuItemWrapper.class, new ItemModelConverter());\n    }\n\n    public static void init(Plugin plugin) {\n        if (CirrusBungeeCord.plugin != null) {\n            return;\n        }\n        CirrusBungeeCord.plugin = plugin;\n        Cirrus.registerService(MenuBuilder.class, new ProtocolizeMenuBuilder());\n        ProxyServer.getInstance().getPluginManager().registerListener(plugin, new QuitListener());\n\n        ProxyServer.getInstance().getScheduler().schedule(plugin, () -> {\n            if (ProxyServer.getInstance().getOnlineCount() > 0 && !MenuAnimator.isEmpty()) {\n                MenuAnimator.updateAll();\n            }\n        }, 50 * 2, TimeUnit.MILLISECONDS);\n    }\n\n    public static Plugin plugin() {\n        if (plugin == null) {\n            throw new IllegalStateException(\"Cirrus is not initialized. Please call CirrusBungeeCord#init during onEnable.\");\n        } // ➤\n        return plugin;\n    }\n\n}\n"
  },
  {
    "path": "cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/converters/ItemModelConverter.java",
    "content": "package dev.simplix.cirrus.bungeecord.converters;\r\n\r\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\r\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\r\nimport dev.simplix.cirrus.common.converter.Converter;\r\nimport dev.simplix.cirrus.common.converter.Converters;\r\nimport dev.simplix.cirrus.common.item.CirrusItem;\r\nimport dev.simplix.protocolize.api.chat.ChatElement;\r\nimport dev.simplix.protocolize.api.item.ItemStack;\r\nimport org.jetbrains.annotations.NotNull;\r\nimport java.util.stream.Collectors;\r\n\r\npublic class ItemModelConverter implements Converter<CirrusItem, InventoryMenuItemWrapper> {\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper convert(@NotNull CirrusItem model) {\r\n        ItemStack itemStack = new ItemStack(model.itemType(), model.amount(), model.durability());\r\n        itemStack.nbtData(model.nbt());\r\n        itemStack.displayName(ChatElement.ofLegacyText(model.displayName()));\r\n        itemStack.lore(model.lore().stream().map(ChatElement::ofLegacyText).collect(Collectors.toList()));\r\n\r\n        return InventoryMenuItemWrapper.builder()\r\n                .handle(Converters.convert(itemStack, MenuItemWrapper.class))\r\n                .actionArguments(model.actionArguments())\r\n                .actionHandler(model.actionHandler())\r\n                .build();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/converters/ItemStackConverter.java",
    "content": "package dev.simplix.cirrus.bungeecord.converters;\r\n\r\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\r\nimport dev.simplix.cirrus.common.converter.Converter;\r\nimport dev.simplix.cirrus.common.item.ProtocolizeMenuItemWrapper;\r\nimport dev.simplix.protocolize.api.item.ItemStack;\r\nimport lombok.NonNull;\r\n\r\npublic class ItemStackConverter implements Converter<ItemStack, MenuItemWrapper> {\r\n\r\n    @Override\r\n    public MenuItemWrapper convert(@NonNull ItemStack itemStack) {\r\n        return new ProtocolizeMenuItemWrapper(itemStack);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/converters/PlayerConverter.java",
    "content": "package dev.simplix.cirrus.bungeecord.converters;\r\n\r\nimport dev.simplix.cirrus.bungeecord.BungeeCordPlayerWrapper;\r\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\r\nimport dev.simplix.cirrus.common.converter.Converter;\r\nimport lombok.NonNull;\r\nimport net.md_5.bungee.api.connection.ProxiedPlayer;\r\nimport org.jetbrains.annotations.NotNull;\r\n\r\npublic final class PlayerConverter implements Converter<ProxiedPlayer, PlayerWrapper> {\r\n\r\n    @Override\r\n    public PlayerWrapper convert(@NonNull @NotNull ProxiedPlayer proxiedPlayer) {\r\n        return new BungeeCordPlayerWrapper(proxiedPlayer);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/converters/PlayerUniqueIdConverter.java",
    "content": "package dev.simplix.cirrus.bungeecord.converters;\r\n\r\nimport dev.simplix.cirrus.bungeecord.BungeeCordPlayerWrapper;\r\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\r\nimport dev.simplix.cirrus.common.converter.Converter;\r\nimport lombok.NonNull;\r\nimport net.md_5.bungee.api.ProxyServer;\r\nimport net.md_5.bungee.api.connection.ProxiedPlayer;\r\n\r\nimport java.util.UUID;\r\n\r\npublic class PlayerUniqueIdConverter implements Converter<UUID, PlayerWrapper> {\r\n\r\n    @Override\r\n    public PlayerWrapper convert(@NonNull UUID uuid) {\r\n        ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid);\r\n        if (player == null) {\r\n            throw new IllegalArgumentException(\"Player \" + uuid + \" is offline\");\r\n        }\r\n        return new BungeeCordPlayerWrapper(player);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/listeners/QuitListener.java",
    "content": "package dev.simplix.cirrus.bungeecord.listeners;\n\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.menu.MenuBuilder;\nimport lombok.NonNull;\nimport net.md_5.bungee.api.event.PlayerDisconnectEvent;\nimport net.md_5.bungee.api.plugin.Listener;\nimport net.md_5.bungee.event.EventHandler;\n\npublic class QuitListener implements Listener {\n\n    @EventHandler\n    public void onQuit(@NonNull PlayerDisconnectEvent event) {\n        Cirrus.getService(MenuBuilder.class).destroyMenusOfPlayer(event.getPlayer().getUniqueId());\n    }\n\n}\n"
  },
  {
    "path": "cirrus-bungeecord/src/main/java/dev/simplix/cirrus/bungeecord/protocolize/ProtocolizeMenuBuilder.java",
    "content": "package dev.simplix.cirrus.bungeecord.protocolize;\r\n\r\nimport com.google.common.collect.Lists;\r\nimport com.google.common.collect.Sets;\r\nimport dev.simplix.cirrus.bungeecord.BungeeCordPlayerWrapper;\r\nimport dev.simplix.cirrus.common.Utils;\r\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\r\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\r\nimport dev.simplix.cirrus.common.container.Container;\r\nimport dev.simplix.cirrus.common.handler.ActionHandler;\r\nimport dev.simplix.cirrus.common.i18n.Replacer;\r\nimport dev.simplix.cirrus.common.menu.AbstractMenu;\r\nimport dev.simplix.cirrus.common.menu.Menu;\r\nimport dev.simplix.cirrus.common.menu.MenuBuilder;\r\nimport dev.simplix.cirrus.common.model.CallResult;\r\nimport dev.simplix.cirrus.common.model.Click;\r\nimport dev.simplix.protocolize.api.ClickType;\r\nimport dev.simplix.protocolize.api.chat.ChatElement;\r\nimport dev.simplix.protocolize.api.inventory.Inventory;\r\nimport dev.simplix.protocolize.api.item.BaseItemStack;\r\nimport dev.simplix.protocolize.api.item.ItemStack;\r\nimport dev.simplix.protocolize.api.player.ProtocolizePlayer;\r\nimport dev.simplix.protocolize.data.packets.OpenWindow;\r\nimport dev.simplix.protocolize.data.packets.WindowItems;\r\nimport lombok.NonNull;\r\nimport net.md_5.bungee.api.ProxyServer;\r\nimport net.md_5.bungee.api.chat.BaseComponent;\r\nimport net.md_5.bungee.api.chat.TextComponent;\r\nimport net.md_5.bungee.api.connection.ProxiedPlayer;\r\nimport net.md_5.bungee.chat.ComponentSerializer;\r\nimport org.jetbrains.annotations.Nullable;\r\n\r\nimport java.util.*;\r\nimport java.util.Map.Entry;\r\nimport java.util.stream.Collectors;\r\n\r\npublic class ProtocolizeMenuBuilder implements MenuBuilder {\r\n\r\n    private final Map<UUID, Map.Entry<Menu, Long>> buildMap = new LinkedHashMap<>();\r\n    private final Set<Menu> menus = Sets.newConcurrentHashSet();\r\n\r\n    @Override\r\n    public <T> T build(@Nullable T prebuild, @NonNull Menu menu) {\r\n        final Entry<Menu, Long> menuLongEntry = this.buildMap.get(menu.player().uniqueId());\r\n        if (menuLongEntry != null && !menuLongEntry.getKey().equals(menu)) {\r\n            menuLongEntry.getKey().handleClose(true);\r\n        }\r\n        if (!(menu instanceof AbstractMenu)) {\r\n            throw new IllegalArgumentException(\"This implementation can only build cirrus menus!\");\r\n        }\r\n        final boolean register = prebuild == null;\r\n        if (prebuild instanceof Inventory) {\r\n            String title = Replacer.of(menu.title()).replaceAll((Object[]) menu.replacements().get())\r\n                    .replacedMessageJoined();\r\n            final Inventory inventory = (Inventory) prebuild;\r\n            final BaseComponent[] component = TextComponent.fromLegacyText(title);\r\n            for (BaseComponent baseComponent : component) {\r\n                baseComponent.setItalic(false); // Wir kommen nicht aus Italien\r\n            }\r\n            if (!ComponentSerializer.toString((BaseComponent[]) inventory.title().asComponent())\r\n                    .equals(ComponentSerializer.toString(component)) ||\r\n                    inventory.type().getTypicalSize(menu.player().protocolVersion()) != menu\r\n                            .topContainer()\r\n                            .capacity()\r\n                    || inventory.type() != menu.inventoryType()) {\r\n                prebuild = (T) makeInv(menu);\r\n            }\r\n        } else {\r\n            prebuild = (T) makeInv(menu);\r\n        }\r\n        final Inventory inventory = (Inventory) prebuild;\r\n        buildContainer(inventory, menu.topContainer());\r\n        buildContainer(inventory, menu.bottomContainer());\r\n\r\n        this.buildMap.put(\r\n                menu.player().uniqueId(),\r\n                new AbstractMap.SimpleEntry<>(menu, System.currentTimeMillis()));\r\n        if (register) {\r\n            this.menus.add(menu);\r\n        }\r\n        open(menu.player(), inventory);\r\n        return prebuild;\r\n    }\r\n\r\n    private void buildContainer(@NonNull Inventory inventory, @NonNull Container container) {\r\n        for (int i = container.baseSlot(); i < container.baseSlot() + container.capacity(); i++) {\r\n            InventoryMenuItemWrapper item = container.itemMap().get(i);\r\n            BaseItemStack currentStack = inventory.item(i);\r\n            if (item == null) {\r\n                if (currentStack != null) {\r\n                    inventory.item(i, ItemStack.NO_DATA);\r\n                }\r\n            }\r\n\r\n            if (item != null) {\r\n                for (BaseComponent[] loreComponent : item.loreComponents()) {\r\n                    for (BaseComponent baseComponent : loreComponent) {\r\n//                        if (!baseComponent.isItalic()) {\r\n//                            baseComponent.setItalic(false);\r\n//                        }\r\n                    }\r\n                }\r\n\r\n                if (currentStack == null) {\r\n                    if (item.handle() == null) {\r\n                        ProxyServer.getInstance().getLogger()\r\n                                .severe(\"InventoryItem's ItemStackWrapper is null @ slot \" + i);\r\n                        continue;\r\n                    }\r\n                    inventory.item(i, item.handle());\r\n                } else {\r\n                    if (!currentStack.equals(item.handle())) {\r\n                        inventory.item(i, item.handle());\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private Inventory makeInv(@NonNull Menu menu) {\r\n        Inventory inventory = new Inventory(menu.inventoryType());\r\n        BaseComponent[] textComponent = TextComponent.fromLegacyText(Replacer.of(menu.title())\r\n                .replaceAll((Object[]) menu.replacements().get()).replacedMessageJoined());\r\n        for (BaseComponent component : textComponent) {\r\n            if (!component.isItalic()) {\r\n                component.setItalic(false); // Resolve client side behavior\r\n            }\r\n        }\r\n        inventory.title(ChatElement.of(textComponent));\r\n\r\n        inventory.onClose(inventoryClose -> {\r\n            Map.Entry<Menu, Long> lastBuild = lastBuildOfPlayer(inventoryClose.player().uniqueId());\r\n            if (((AbstractMenu) lastBuild.getKey()).internalId() == ((AbstractMenu) menu).internalId()\r\n                    && (System.currentTimeMillis() - lastBuild.getValue()) <= 55) {\r\n                return;\r\n            }\r\n            menu.handleClose((System.currentTimeMillis() - lastBuild.getValue()) <= 55);\r\n            invalidate(menu);\r\n        });\r\n\r\n        inventory.onClick(inventoryClick -> {\r\n            if (inventoryClick.clickType() == null) {\r\n                return;\r\n            }\r\n            if (inventoryClick.player() == null) {\r\n                return;\r\n            }\r\n            Inventory i = inventoryClick.inventory();\r\n            if (i == null) {\r\n                return;\r\n            }\r\n//            ProxyServer.getInstance().broadcast(\"Clicked inventory\");\r\n//            ProxyServer.getInstance().broadcast(\"Clicked menu: \" + menu.getClass().getSimpleName() + \" @ slot \" + inventoryClick.slot());\r\n            Container container;\r\n            if (inventoryClick.slot() > menu.topContainer().capacity() - 1) {\r\n                container = menu.bottomContainer();\r\n//                ProxyServer.getInstance().broadcast(\"Clicked bottom container\");\r\n            } else {\r\n                container = menu.topContainer();\r\n//                ProxyServer.getInstance().broadcast(\"Clicked top container\");\r\n            }\r\n            InventoryMenuItemWrapper item = container.get(inventoryClick.slot());\r\n            ClickType type = inventoryClick.clickType();\r\n            if (item == null) {\r\n//                ProxyServer.getInstance().broadcast(\"Clicked nothing\");\r\n                if (menu.customActionHandler() != null) {\r\n                    try {\r\n                        CallResult callResult = menu\r\n                                .customActionHandler()\r\n                                .handle(new Click(type, menu, null, inventoryClick.slot()));\r\n                        inventoryClick.cancelled(callResult == null || callResult == CallResult.DENY_GRABBING);\r\n                    } catch (Exception ex) {\r\n                        inventoryClick.cancelled(true);\r\n                        menu.handleException(null, ex);\r\n                    }\r\n                }\r\n                return;\r\n            }\r\n//            ProxyServer.getInstance().broadcast(\"Clicked \" + item.displayName());\r\n            ActionHandler actionHandler = menu.actionHandler(item.actionHandler());\r\n            if (actionHandler == null) {\r\n                inventoryClick.cancelled(true);\r\n                return;\r\n            }\r\n            try {\r\n                final CallResult callResult = actionHandler.handle(new Click(\r\n                        type,\r\n                        menu,\r\n                        item,\r\n                        inventoryClick.slot()));\r\n                inventoryClick.cancelled(callResult == null || callResult == CallResult.DENY_GRABBING);\r\n            } catch (final Exception ex) {\r\n                inventoryClick.cancelled(true);\r\n                menu.handleException(actionHandler, ex);\r\n            }\r\n        });\r\n\r\n        return inventory;\r\n    }\r\n\r\n    @Override\r\n    public <T> void open(\r\n            PlayerWrapper playerWrapper, T inventoryImpl) {\r\n        if (playerWrapper instanceof BungeeCordPlayerWrapper) {\r\n            final ProtocolizePlayer protocolizePlayer = ((BungeeCordPlayerWrapper) playerWrapper).protocolizePlayer();\r\n            final Inventory inventory = (Inventory) inventoryImpl;\r\n\r\n            boolean alreadyOpen = false;\r\n            int windowId = -1;\r\n            for (Integer id : protocolizePlayer.registeredInventories().keySet()) {\r\n                Inventory val = protocolizePlayer.registeredInventories().get(id);\r\n                if (val.type() == inventory.type() && val.title().equals(inventory.title())) {\r\n                    alreadyOpen = true;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            // Close all inventories if not opened\r\n            if (!alreadyOpen) {\r\n                protocolizePlayer.closeInventory();\r\n            }\r\n\r\n            if (protocolizePlayer.registeredInventories().containsValue(inventory)) {\r\n                for (Integer id : protocolizePlayer.registeredInventories().keySet()) {\r\n                    Inventory val = protocolizePlayer.registeredInventories().get(id);\r\n                    if (val == inventory) {\r\n                        windowId = id;\r\n                        break;\r\n                    }\r\n                }\r\n                if (windowId == -1) {\r\n                    windowId = protocolizePlayer.generateWindowId();\r\n                    protocolizePlayer.registerInventory(windowId, inventory);\r\n                }\r\n            } else {\r\n                windowId = protocolizePlayer.generateWindowId();\r\n                protocolizePlayer.registerInventory(windowId, inventory);\r\n            }\r\n\r\n            if (!alreadyOpen) {\r\n                protocolizePlayer.sendPacket(new OpenWindow(windowId, inventory.type(), inventory.title()));\r\n            }\r\n            int protocolVersion;\r\n            try {\r\n                protocolVersion = protocolizePlayer.protocolVersion();\r\n            } catch (Throwable t) {\r\n                protocolVersion = 47;\r\n            }\r\n            List<BaseItemStack> items = Lists.newArrayList(inventory.itemsIndexed(protocolVersion));\r\n            protocolizePlayer.sendPacket(new WindowItems((short) windowId, items, 0));\r\n        }\r\n    }\r\n\r\n    private void removeItalic(BaseComponent[] components) {\r\n        for (BaseComponent component : components) {\r\n            component.setItalic(false);\r\n        }\r\n    }\r\n\r\n    @Override\r\n    @Nullable\r\n    public Menu menuByHandle(Object handle) {\r\n        if (handle == null) {\r\n            return null;\r\n        }\r\n        for (final Menu menu : this.menus) {\r\n            if (menu.equals(handle)) {\r\n                return menu;\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    @Override\r\n    public void destroyMenusOfPlayer(@NonNull UUID uniqueId) {\r\n        this.menus.removeIf(\r\n                wrapper -> ((ProxiedPlayer) wrapper.player().handle()).getUniqueId().equals(uniqueId));\r\n        this.buildMap.remove(uniqueId);\r\n    }\r\n\r\n    @Override\r\n    public Entry<Menu, Long> lastBuildOfPlayer(@NonNull UUID uniqueId) {\r\n        return this.buildMap.get(uniqueId);\r\n    }\r\n\r\n    @Override\r\n    public void invalidate(@NonNull Menu menu) {\r\n        this.menus.remove(menu);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-bungeecord-example/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>dev.simplix.cirrus</groupId>\n        <artifactId>cirrus</artifactId>\n        <version>2.0.0</version>\n    </parent>\n\n    <groupId>dev.simplix.cirrus</groupId>\n    <artifactId>cirrus-bungeecord-example</artifactId>\n    <version>${cirrus.version}</version>\n\n    <dependencies>\n        <dependency>\n            <artifactId>cirrus-common</artifactId>\n            <groupId>dev.simplix.cirrus</groupId>\n            <scope>compile</scope>\n            <version>${cirrus.version}</version>\n        </dependency>\n        <dependency>\n            <artifactId>cirrus-bungeecord</artifactId>\n            <groupId>dev.simplix.cirrus</groupId>\n            <scope>compile</scope>\n            <version>${cirrus.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>net.md-5</groupId>\n            <artifactId>bungeecord-api</artifactId>\n            <version>1.21-R0.1-SNAPSHOT</version>\n            <scope>provided</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>${project.name}-${project.version}</finalName>\n        <resources>\n            <resource>\n                <directory>src/main/resources</directory>\n                <filtering>true</filtering>\n            </resource>\n        </resources>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-shade-plugin</artifactId>\n                <version>3.0.0</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <configuration>\n                    <source>8</source>\n                    <target>8</target>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n\n</project>"
  },
  {
    "path": "cirrus-bungeecord-example/src/main/java/dev/simplix/cirrus/bungeecord/example/CirrusExamplePlugin.java",
    "content": "package dev.simplix.cirrus.bungeecord.example;\n\nimport dev.simplix.cirrus.bungeecord.CirrusBungeeCord;\nimport dev.simplix.cirrus.bungeecord.example.commands.TestCommand;\nimport net.md_5.bungee.api.ProxyServer;\nimport net.md_5.bungee.api.plugin.Plugin;\n\npublic class CirrusExamplePlugin extends Plugin {\n\n    @Override\n    public void onEnable() {\n        CirrusBungeeCord.init(this);\n        ProxyServer.getInstance().getPluginManager().registerCommand(this, new TestCommand());\n    }\n\n}\n"
  },
  {
    "path": "cirrus-bungeecord-example/src/main/java/dev/simplix/cirrus/bungeecord/example/commands/TestCommand.java",
    "content": "package dev.simplix.cirrus.bungeecord.example.commands;\n\nimport dev.simplix.cirrus.bungeecord.example.menus.ExampleMenu;\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport net.md_5.bungee.api.CommandSender;\nimport net.md_5.bungee.api.connection.ProxiedPlayer;\nimport net.md_5.bungee.api.plugin.Command;\n\npublic class TestCommand extends Command {\n\n    public TestCommand() {\n        super(\"test\");\n    }\n\n    @Override\n    public void execute(CommandSender sender, String[] args) {\n        if (sender instanceof ProxiedPlayer) {\n            ProxiedPlayer proxy = (ProxiedPlayer) sender;\n            new ExampleMenu(Converters.convert(proxy, PlayerWrapper.class),\n                    Cirrus.configurationFactory().loadFile(\"plugins/Cirrus/example.json\")).open();\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-bungeecord-example/src/main/java/dev/simplix/cirrus/bungeecord/example/menus/ExampleMenu.java",
    "content": "package dev.simplix.cirrus.bungeecord.example.menus;\n\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.menu.AbstractConfigurableMenu;\nimport dev.simplix.cirrus.common.model.CallResult;\nimport dev.simplix.cirrus.common.configuration.MenuConfiguration;\n\nimport java.util.Locale;\n\npublic class ExampleMenu extends AbstractConfigurableMenu<MenuConfiguration> {\n\n    public ExampleMenu(PlayerWrapper player, MenuConfiguration configuration) {\n        super(player, configuration, Locale.ENGLISH);\n\n        registerActionHandler(\"tnt\", click -> {\n            topContainer().itemMap().remove(click.slot());\n            title(\"Hello, {viewer}\");\n            build();\n            player().sendMessage(\"It simply works :)\");\n            return CallResult.DENY_GRABBING;\n        });\n    }\n\n}\n"
  },
  {
    "path": "cirrus-bungeecord-example/src/main/java/dev/simplix/cirrus/bungeecord/example/menus/ExampleMultiPageMenu.java",
    "content": "package dev.simplix.cirrus.bungeecord.example.menus;\r\n\r\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\r\nimport dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;\r\nimport dev.simplix.cirrus.common.menus.MultiPageMenu;\r\nimport dev.simplix.cirrus.common.model.CallResult;\r\nimport dev.simplix.protocolize.api.Protocolize;\r\nimport dev.simplix.protocolize.api.item.ItemStack;\r\nimport dev.simplix.protocolize.api.providers.MappingProvider;\r\nimport dev.simplix.protocolize.data.ItemType;\r\n\r\nimport java.util.Collections;\r\nimport java.util.Locale;\r\n\r\npublic class ExampleMultiPageMenu extends MultiPageMenu {\r\n\r\n    private final MappingProvider mappingProvider = Protocolize.mappingProvider();\r\n\r\n    public ExampleMultiPageMenu(\r\n            PlayerWrapper player,\r\n            MultiPageMenuConfiguration configuration) {\r\n        super(player, configuration, Locale.ENGLISH);\r\n        registerMyActionHandlers();\r\n        addItems();\r\n    }\r\n\r\n    private void registerMyActionHandlers() {\r\n        registerActionHandler(\"test\", click -> {\r\n            player().sendMessage(\"This is \" + click.clickedItem().type().name());\r\n            return CallResult.DENY_GRABBING;\r\n        });\r\n    }\r\n\r\n    private void addItems() {\r\n        for (ItemType type : ItemType.values()) {\r\n            if (this.mappingProvider.mapping(type, player().protocolVersion()) != null) {\r\n                add(wrapItemStack(new ItemStack(type)), \"test\", Collections.emptyList());\r\n            }\r\n        }\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-bungeecord-example/src/main/resources/plugin.yml",
    "content": "name: CirrusExample\r\nauthor: Exceptionflug\r\nversion: 1.0\r\nmain: dev.simplix.cirrus.bungeecord.example.CirrusExamplePlugin\r\nsoftdepend:\r\n  - simplixcore\r\n\r\ncommands:\r\n  test:\r\n    description: hi"
  },
  {
    "path": "cirrus-common/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <artifactId>cirrus-common</artifactId>\n\n    <build>\n        <plugins>\n            <plugin>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <configuration>\n                    <source>8</source>\n                    <target>8</target>\n                </configuration>\n                <groupId>org.apache.maven.plugins</groupId>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-source-plugin</artifactId>\n                <version>3.0.1</version>\n                <executions>\n                    <execution>\n                        <id>attach-sources</id>\n                        <phase>deploy</phase>\n                        <goals>\n                            <goal>jar-no-fork</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-javadoc-plugin</artifactId>\n                <version>3.0.1</version>\n                <executions>\n                    <execution>\n                        <id>attach-javadocs</id>\n                        <goals>\n                            <goal>jar</goal>\n                        </goals>\n                        <configuration>\n                            <doclint>none</doclint>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n            <version>1.8.0-alpha2</version>\n            <scope>provided</scope>\n        </dependency>\n    </dependencies>\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <artifactId>cirrus</artifactId>\n        <groupId>dev.simplix.cirrus</groupId>\n        <version>2.0.0</version>\n    </parent>\n\n    <version>${cirrus.version}</version>\n\n</project>"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/Cirrus.java",
    "content": "package dev.simplix.cirrus.common;\n\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\nimport dev.simplix.cirrus.common.business.ConfigurationFactory;\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.config.JsonConfigurationFactory;\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.common.i18n.*;\nimport dev.simplix.cirrus.common.mojangson.TagDeserializer;\nimport dev.simplix.cirrus.common.mojangson.TagSerializer;\nimport net.querz.nbt.tag.CompoundTag;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class Cirrus {\n\n    private static final Map<Class<?>, Object> SERVICES = new ConcurrentHashMap<>();\n\n    public static Gson gson() {\n        return GSON;\n    }\n\n    private static final Gson GSON = new GsonBuilder()\n            .registerTypeAdapter(CompoundTag.class, new TagSerializer())\n            .registerTypeAdapter(CompoundTag.class, new TagDeserializer())\n            .registerTypeAdapter(LocalizedString.class, new LocalizedStringSerializer())\n            .registerTypeAdapter(LocalizedString.class, new LocalizedStringDeserializer())\n            .registerTypeAdapter(LocalizedStringList.class, new LocalizedStringListSerializer())\n            .registerTypeAdapter(LocalizedStringList.class, new LocalizedStringListDeserializer())\n            .setPrettyPrinting()\n            .create();\n\n    static {\n        Converters.register(\n                InventoryMenuItemWrapper.class, MenuItemWrapper.class,\n                (Converter<InventoryMenuItemWrapper, MenuItemWrapper>) InventoryMenuItemWrapper::wrapper);\n        registerService(ConfigurationFactory.class, new JsonConfigurationFactory(GSON));\n    }\n\n    /**\n     * This returns an instance of a registered service.\n     *\n     * @param type The registration type of the desired service\n     * @param <T>  The type of the service\n     * @return The instance of T or null if there is no service with this registration type\n     * @see Cirrus#registerService(Class, Object)\n     */\n    public static <T> T getService(Class<T> type) {\n        return (T) SERVICES.get(type);\n    }\n\n    /**\n     * This will map a given service instance to a given registration type.\n     *\n     * @param type     The registration type of the desired service\n     * @param instance An instance of the registration type\n     * @param <T>      The registration type\n     */\n    public static <T> void registerService(Class<T> type, T instance) {\n        SERVICES.put(type, instance);\n    }\n\n    public static ConfigurationFactory configurationFactory() {\n        return getService(ConfigurationFactory.class);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/Utils.java",
    "content": "package dev.simplix.cirrus.common;\n\nimport lombok.experimental.UtilityClass;\nimport net.md_5.bungee.api.chat.BaseComponent;\nimport net.querz.nbt.tag.*;\n\n@UtilityClass\npublic class Utils {\n    private static final String STEVE_TEXTURE = \"ewogICJ0aW1lc3RhbXAiIDogMTU5MTU3NDcyMzc4MywKICAicHJvZmlsZUlkIiA6ICI4NjY3YmE3MWI4NWE0MDA0YWY1NDQ1N2E5NzM0ZWVkNyIsCiAgInByb2ZpbGVOYW1lIiA6ICJTdGV2ZSIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS82ZDNiMDZjMzg1MDRmZmMwMjI5Yjk0OTIxNDdjNjlmY2Y1OWZkMmVkNzg4NWY3ODUwMjE1MmY3N2I0ZDUwZGUxIgogICAgfSwKICAgICJDQVBFIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS85NTNjYWM4Yjc3OWZlNDEzODNlNjc1ZWUyYjg2MDcxYTcxNjU4ZjIxODBmNTZmYmNlOGFhMzE1ZWE3MGUyZWQ2IgogICAgfQogIH0KfQ==\";\n\n    public void removeItalic(BaseComponent[] components) {\n        for (BaseComponent component : components) {\n            component.setItalic(false);\n        }\n    }\n\n    public static void hideNbtFlags(CompoundTag tag) {\n        tag.put(\"HideFlags\", new IntTag(127));\n    }\n\n    public static void glow(CompoundTag tag) {\n        hideNbtFlags(tag);\n\n        final ListTag<CompoundTag> enchantments = new ListTag<>(CompoundTag.class);\n        final ListTag<CompoundTag> enchs = new ListTag<>(CompoundTag.class);\n\n        final CompoundTag exampleEnchantment = new CompoundTag();\n\n        exampleEnchantment.put(\"id\", new StringTag(\"minecraft:efficiency\"));\n        exampleEnchantment.put(\"lvl\", new ShortTag((short) 1));\n\n        final CompoundTag exampleEnch = new CompoundTag();\n        exampleEnch.put(\"id\", new ShortTag((short) 1));\n        exampleEnch.put(\"lvl\", new ShortTag((short) 1));\n\n        enchantments.add(exampleEnchantment);\n        enchs.add(exampleEnch);\n\n        tag.put(\"ench\", enchs);\n        tag.put(\"Enchantments\", enchantments);\n    }\n\n    public static void texture(CompoundTag tag, String textureHash) {\n        if (!(tag.get(\"SkullOwner\") instanceof CompoundTag)) {\n            tag.put(\"SkullOwner\", new CompoundTag());\n        }\n\n        CompoundTag skullOwner = tag.getCompoundTag(\"SkullOwner\");\n\n        if (skullOwner == null) {\n            skullOwner = new CompoundTag();\n        }\n\n        skullOwner.put(\"Name\", new StringTag(textureHash));\n        CompoundTag properties = skullOwner.getCompoundTag(\"Properties\");\n        if (properties == null) {\n            properties = new CompoundTag();\n        }\n\n        CompoundTag texture = new CompoundTag();\n        texture.put(\n                \"Value\",\n                new StringTag(textureHash.isEmpty() ? STEVE_TEXTURE : textureHash));\n        ListTag<CompoundTag> textures = new ListTag<>(CompoundTag.class);\n        textures.add(texture);\n        properties.put(\"textures\", textures);\n        skullOwner.put(\"Properties\", properties);\n        tag.put(\"SkullOwner\", skullOwner);\n\n    }\n\n    public static int calculateSizeForContent(final int items) {\n        return (\n                items <= 9 ?\n                        9 * 1 : items <= 9 * 2 ? 9 * 2 : items <= 9 * 3 ? 9 * 3\n                        : items <= 9 * 4 ? 9 * 4 : 9 * 5) + 9;\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/business/ConfigurationFactory.java",
    "content": "package dev.simplix.cirrus.common.business;\n\nimport dev.simplix.cirrus.common.configuration.MenuConfiguration;\nimport dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;\nimport dev.simplix.cirrus.common.configuration.impl.SimpleMenuConfiguration;\nimport dev.simplix.cirrus.common.configuration.impl.SimpleMultiPageMenuConfiguration;\nimport lombok.NonNull;\n\npublic interface ConfigurationFactory {\n\n    default MenuConfiguration loadFile(@NonNull String file) {\n        return loadFile(file, SimpleMenuConfiguration.class);\n    }\n\n    default MenuConfiguration loadResource(@NonNull String resourcePath, @NonNull Class<?> caller) {\n        return loadResource(resourcePath, caller, SimpleMenuConfiguration.class);\n    }\n\n    default MultiPageMenuConfiguration loadFileForMultiPageMenu(@NonNull String file) {\n        return loadFile(file, SimpleMultiPageMenuConfiguration.class);\n    }\n\n    default MultiPageMenuConfiguration loadResourcesForMultiPageMenu(\n            @NonNull String resourcePath,\n            @NonNull Class<?> caller) {\n        return loadResource(resourcePath, caller, SimpleMultiPageMenuConfiguration.class);\n    }\n\n    <T extends MenuConfiguration> T loadFile(@NonNull String file, @NonNull Class<T> type);\n\n    <T extends MenuConfiguration> T loadResource(\n            @NonNull String resourcePath,\n            @NonNull Class<?> caller,\n            @NonNull Class<T> type);\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/business/DataInventoryMenuItemWrapper.java",
    "content": "package dev.simplix.cirrus.common.business;\n\nimport lombok.Getter;\nimport lombok.NonNull;\nimport lombok.ToString;\nimport lombok.experimental.Accessors;\n\nimport java.util.List;\n\n@Accessors(fluent = true)\n@Getter\n@ToString(callSuper = true)\npublic class DataInventoryMenuItemWrapper<T> extends InventoryMenuItemWrapper {\n\n    private final T data;\n\n    public DataInventoryMenuItemWrapper(\n            @NonNull MenuItemWrapper handle,\n            @NonNull String actionHandler,\n            @NonNull List<String> actionArguments, T data) {\n        super(handle, actionHandler, actionArguments);\n        this.data = data;\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/business/InventoryMenuItemWrapper.java",
    "content": "package dev.simplix.cirrus.common.business;\n\nimport dev.simplix.protocolize.data.ItemType;\nimport lombok.Builder;\nimport lombok.Getter;\nimport lombok.NonNull;\nimport lombok.Setter;\nimport lombok.experimental.Accessors;\nimport net.md_5.bungee.api.chat.BaseComponent;\nimport net.querz.nbt.tag.CompoundTag;\n\nimport java.util.List;\n\n@Accessors(fluent = true)\n@Builder\npublic class InventoryMenuItemWrapper implements MenuItemWrapper {\n\n    private final MenuItemWrapper handle;\n\n    @Getter\n    @Setter\n    private String actionHandler;\n    @Getter\n    @Setter\n    private List<String> actionArguments;\n\n    @Override\n    public String displayName() {\n        return this.handle.displayName();\n    }\n\n    @Override\n    public BaseComponent[] displayNameComponents() {\n        return this.handle.displayNameComponents();\n    }\n\n    @Override\n    public List<String> lore() {\n        return this.handle.lore();\n    }\n\n    @Override\n    public List<BaseComponent[]> loreComponents() {\n        return this.handle.loreComponents();\n    }\n\n    @Override\n    public ItemType type() {\n        return this.handle.type();\n    }\n\n    @Override\n    public CompoundTag nbt() {\n        return this.handle.nbt();\n    }\n\n    @Override\n    public int amount() {\n        return this.handle.amount();\n    }\n\n    @Override\n    public short durability() {\n        return this.handle.durability();\n    }\n\n    @Override\n    public void type(@NonNull ItemType type) {\n        this.handle.type(type);\n    }\n\n    @Override\n    public void displayName(@NonNull String displayName) {\n        this.handle.displayName(displayName);\n    }\n\n    @Override\n    public void displayNameComponents(@NonNull BaseComponent... baseComponents) {\n        this.handle.displayNameComponents(baseComponents);\n    }\n\n    @Override\n    public void lore(@NonNull List<String> lore) {\n        this.handle.lore(lore);\n    }\n\n    @Override\n    public void loreComponents(@NonNull List<BaseComponent[]> lore) {\n        this.handle.loreComponents(lore);\n    }\n\n    @Override\n    public void nbt(@NonNull CompoundTag tag) {\n        this.handle.nbt(tag);\n    }\n\n    @Override\n    public void amount(int amount) {\n        this.handle.amount(amount);\n    }\n\n    @Override\n    public void durability(short durability) {\n        this.handle.durability(durability);\n    }\n\n    @Override\n    public <T> T handle() {\n        return this.handle.handle();\n    }\n\n    public MenuItemWrapper wrapper() {\n        return this.handle;\n    }\n\n    @Override\n    public String toString() {\n        return \"InventoryItemWrapper{\" +\n                \"handle=\" + this.handle +\n                \", actionHandler='\" + this.actionHandler + '\\'' +\n                \", actionArguments=\" + this.actionArguments +\n                '}';\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/business/MenuItemWrapper.java",
    "content": "package dev.simplix.cirrus.common.business;\n\nimport dev.simplix.protocolize.data.ItemType;\nimport lombok.NonNull;\nimport net.md_5.bungee.api.chat.BaseComponent;\nimport net.querz.nbt.tag.CompoundTag;\n\nimport java.util.List;\n\n/**\n * An {@link MenuItemWrapper} provides uniform data access for items across different platforms.\n * Please be aware, that most of the given properties are immutable, so you have to set them using\n * their setter after you have done some changes.\n */\npublic interface MenuItemWrapper {\n\n    /**\n     * Returns the display name of an item as a string.\n     *\n     * @return display name\n     */\n    String displayName();\n\n    /**\n     * Returns the display name of an item as component array.\n     *\n     * @return display name\n     */\n    BaseComponent[] displayNameComponents();\n\n    /**\n     * The lore of the item as strings.\n     *\n     * @return lore\n     */\n    List<String> lore();\n\n    /**\n     * The lore of the item as component arrays.\n     *\n     * @return lore\n     */\n    List<BaseComponent[]> loreComponents();\n\n    /**\n     * The {@link ItemType} of the item.\n     *\n     * @return item type\n     */\n    ItemType type();\n\n    /**\n     * This returns a querz-nbt {@link CompoundTag} with the nbt information about this item. Please\n     * be aware, that the nbt data of spigot ItemStacks are immutable. So you have to call setNBT()\n     * after you changed the data to set them.\n     *\n     * @return nbt data\n     */\n    CompoundTag nbt();\n\n    /**\n     * Returns the amount of the stack\n     *\n     * @return amount\n     */\n    int amount();\n\n    /**\n     * Returns the durability of the item.\n     *\n     * @return\n     */\n    short durability();\n\n    /**\n     * Sets the mcc item type.\n     *\n     * @param type type to set\n     */\n    void type(@NonNull ItemType type);\n\n    /**\n     * Sets the display name of the item\n     *\n     * @param displayName name\n     */\n    void displayName(@NonNull String displayName);\n\n    /**\n     * Sets the display name of the item\n     *\n     * @param baseComponents name\n     */\n    void displayNameComponents(@NonNull BaseComponent... baseComponents);\n\n    /**\n     * Sets the lore of the item\n     *\n     * @param lore\n     */\n    void lore(List<String> lore);\n\n    /**\n     * Sets the lore of the item\n     *\n     * @param lore\n     */\n    void loreComponents(@NonNull List<BaseComponent[]> lore);\n\n    /**\n     * Sets the nbt data.\n     *\n     * @param tag nbt data\n     */\n    void nbt(@NonNull CompoundTag tag);\n\n    /**\n     * Sets the stack amount.\n     *\n     * @param amount amount\n     */\n    void amount(int amount);\n\n    /**\n     * Sets the durability.\n     * <br>#DUDELAVERITY\n     *\n     * @param durability durability\n     */\n    void durability(short durability);\n\n    /**\n     * Returns the handle of the wrapper\n     *\n     * @param <T> dyncast handle type\n     * @return the handle\n     */\n    <T> T handle();\n\n}"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/business/PlayerWrapper.java",
    "content": "package dev.simplix.cirrus.common.business;\n\nimport lombok.NonNull;\n\nimport java.util.UUID;\n\npublic interface PlayerWrapper {\n\n    void sendMessage(@NonNull String msg);\n\n    void closeInventory();\n\n    boolean hasPermission(@NonNull String permission);\n\n    UUID uniqueId();\n\n    String name();\n\n    int protocolVersion();\n\n    <T> T handle();\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/config/JsonConfigurationFactory.java",
    "content": "package dev.simplix.cirrus.common.config;\n\nimport com.google.common.io.ByteStreams;\nimport com.google.gson.Gson;\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.business.ConfigurationFactory;\nimport dev.simplix.cirrus.common.configuration.MenuConfiguration;\nimport lombok.NonNull;\n\nimport java.io.*;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.NoSuchFileException;\nimport java.util.Objects;\n\npublic class JsonConfigurationFactory implements ConfigurationFactory {\n\n    private final Gson gson;\n\n    public JsonConfigurationFactory(Gson gson) {\n        this.gson = gson;\n    }\n\n    @Override\n    public <T extends MenuConfiguration> T loadFile(\n            @NonNull String filename,\n            @NonNull Class<T> type) {\n        File file = new File(filename);\n        if (!file.exists()) {\n            if (file.getParentFile() != null) {\n                file.getParentFile().mkdirs();\n            }\n            copyResourceToFile(\"/cirrus/\" + type.getSimpleName() + \".json\", file);\n        }\n        try (\n                InputStreamReader reader = new InputStreamReader(\n                        Files.newInputStream(file.toPath()),\n                        StandardCharsets.UTF_8)) {\n            return this.gson.fromJson(reader, type);\n        } catch (IOException ioException) {\n            throw new RuntimeException(ioException);\n        }\n    }\n\n    @Override\n    public <T extends MenuConfiguration> T loadResource(\n            @NonNull String resourcePath,\n            @NonNull Class<?> caller,\n            @NonNull Class<T> type) {\n        try (InputStream stream = caller.getResourceAsStream(resourcePath)) {\n            if (stream == null) {\n                throw new NoSuchFileException(\"Unable to find resource \" + resourcePath);\n            }\n            String contents = new String(ByteStreams.toByteArray(stream), StandardCharsets.UTF_8);\n            return this.gson.fromJson(contents, type);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private void copyResourceToFile(@NonNull String resource, @NonNull File file) {\n        try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {\n            fileOutputStream.write(ByteStreams.toByteArray(\n                    Objects.requireNonNull(Cirrus.class.getResourceAsStream(resource), \"Inputstream is null\")));\n            fileOutputStream.flush();\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/configuration/MenuConfiguration.java",
    "content": "package dev.simplix.cirrus.common.configuration;\n\nimport com.google.common.base.Preconditions;\nimport dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;\nimport dev.simplix.cirrus.common.i18n.LocalizedString;\n\npublic interface MenuConfiguration {\n\n    default LocalizedItemStackModel forceBusinessItem(String keyword) {\n        return Preconditions.checkNotNull(\n                businessItems().get(keyword),\n                \"No business-item named '\" + keyword + \"' found\"\n        );\n    }\n\n    LocalizedString title();\n\n    dev.simplix.protocolize.data.inventory.InventoryType type();\n\n    LocalizedItemStackModel placeholderItem();\n\n    int[] reservedSlots();\n\n    LocalizedItemStackModel[] items();\n\n    java.util.Map<String, LocalizedItemStackModel> businessItems();\n\n    MenuConfiguration title(LocalizedString title);\n\n    MenuConfiguration type(dev.simplix.protocolize.data.inventory.InventoryType type);\n\n    MenuConfiguration placeholderItem(LocalizedItemStackModel placeholderItem);\n\n    MenuConfiguration reservedSlots(int[] reservedSlots);\n\n    MenuConfiguration items(LocalizedItemStackModel[] items);\n\n    MenuConfiguration businessItems(java.util.Map<String, LocalizedItemStackModel> businessItems);\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/configuration/MultiPageMenuConfiguration.java",
    "content": "package dev.simplix.cirrus.common.configuration;\n\nimport dev.simplix.cirrus.common.i18n.LocalizedString;\nimport dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;\n\npublic interface MultiPageMenuConfiguration extends MenuConfiguration {\n    LocalizedItemStackModel nextPageItem();\n\n    LocalizedItemStackModel previousPageItem();\n\n    MultiPageMenuConfiguration title(LocalizedString title);\n\n    MultiPageMenuConfiguration type(dev.simplix.protocolize.data.inventory.InventoryType type);\n\n    MultiPageMenuConfiguration placeholderItem(LocalizedItemStackModel placeholderItem);\n\n    MultiPageMenuConfiguration reservedSlots(int[] reservedSlots);\n\n    MultiPageMenuConfiguration items(LocalizedItemStackModel[] items);\n\n    MultiPageMenuConfiguration businessItems(java.util.Map<String, LocalizedItemStackModel> businessItems);\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/configuration/impl/SimpleMenuConfiguration.java",
    "content": "package dev.simplix.cirrus.common.configuration.impl;\n\nimport dev.simplix.cirrus.common.configuration.MenuConfiguration;\nimport dev.simplix.cirrus.common.i18n.LocalizedString;\nimport dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;\nimport dev.simplix.protocolize.data.inventory.InventoryType;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\nimport lombok.experimental.Accessors;\n\n@Data\n@Accessors(fluent = true)\n@NoArgsConstructor\npublic class SimpleMenuConfiguration implements MenuConfiguration {\n\n    private LocalizedString title;\n    private InventoryType type;\n    private LocalizedItemStackModel placeholderItem;\n    private int[] reservedSlots = new int[0];\n    private LocalizedItemStackModel[] items = new LocalizedItemStackModel[0];\n    private Map<String, LocalizedItemStackModel> businessItems = new HashMap<>();\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/configuration/impl/SimpleMultiPageMenuConfiguration.java",
    "content": "package dev.simplix.cirrus.common.configuration.impl;\n\nimport dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;\nimport dev.simplix.cirrus.common.i18n.LocalizedString;\nimport dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;\nimport dev.simplix.protocolize.data.inventory.InventoryType;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Builder;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\nimport lombok.experimental.Accessors;\n\n@Data\n@Builder\n@Accessors(fluent = true)\n@AllArgsConstructor\n@NoArgsConstructor\npublic class SimpleMultiPageMenuConfiguration implements MultiPageMenuConfiguration {\n\n    private LocalizedItemStackModel nextPageItem;\n    private LocalizedItemStackModel previousPageItem;\n    private LocalizedString title;\n    private InventoryType type;\n    private LocalizedItemStackModel placeholderItem;\n    private int[] reservedSlots = new int[0];\n    private LocalizedItemStackModel[] items = new LocalizedItemStackModel[0];\n    private Map<String, LocalizedItemStackModel> businessItems = new HashMap<>();\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/container/Container.java",
    "content": "package dev.simplix.cirrus.common.container;\n\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.common.item.CirrusItem;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * A container stores {@link InventoryMenuItemWrapper}s at a given slot position.\n */\npublic interface Container {\n\n    /**\n     * Returns a map collecting all items.\n     *\n     * @return The map\n     */\n    Map<Integer, InventoryMenuItemWrapper> itemMap();\n\n    /**\n     * Returns a set with slots that are marked as reserved\n     *\n     * @return The set\n     */\n    Set<Integer> reservedSlots();\n\n    /**\n     * Returns the maximum capacity of this container\n     *\n     * @return the maximum amount of items this container can hold\n     */\n    int capacity();\n\n    /**\n     * Returns the initial slot id of this container\n     *\n     * @return Initial slot id\n     */\n    int baseSlot();\n\n    /**\n     * @return the slot index of the next available empty slot or -1 if no slot is empty\n     */\n    int nextFreeSlot();\n\n    /**\n     * @return the slot index of the next available empty slot or -1 after the specified index\n     */\n    int nextFreeSlot(int i);\n\n    /**\n     * Sets an item into the next free slot. Free slots are slots where no item has been set and the\n     * slot is not marked as reserved.\n     *\n     * @param inventoryItemWrapper The item to set\n     */\n    default void add(InventoryMenuItemWrapper inventoryItemWrapper) {\n        set(nextFreeSlot(), inventoryItemWrapper);\n    }\n\n    /**\n     * Sets an item into the next free slot. Free slots are slots where no item has been set and the\n     * slot is not marked as reserved.\n     *\n     * @param menuItemWrapper The item stack to set\n     * @param actionHandler   The action handler which should be called on click\n     * @param actionArgs      the arguments for that click\n     */\n    default void add(\n            MenuItemWrapper menuItemWrapper,\n            String actionHandler,\n            List<String> actionArgs) {\n        set(nextFreeSlot(), InventoryMenuItemWrapper.builder()\n                .handle(menuItemWrapper)\n                .actionHandler(actionHandler)\n                .actionArguments(actionArgs)\n                .build());\n    }\n\n    /**\n     * Sets an item into the next free slot. Free slots are slots where no item has been set and the\n     * slot is not marked as reserved.\n     *\n     * @param model The item stack model\n     */\n    default void add(CirrusItem model) {\n        set(nextFreeSlot(), InventoryMenuItemWrapper.builder()\n                .handle(Converters.convert(model, InventoryMenuItemWrapper.class))\n                .actionHandler(model.actionHandler())\n                .actionArguments(model.actionArguments())\n                .build());\n    }\n\n    /**\n     * Sets an item into a given position in the container\n     *\n     * @param slot                 The slot the item will be located at\n     * @param inventoryItemWrapper The item stack wrapper\n     */\n    default void set(int slot, InventoryMenuItemWrapper inventoryItemWrapper) {\n        itemMap().put(slot, inventoryItemWrapper);\n    }\n\n    /**\n     * Sets an item into a given position in the container\n     *\n     * @param slot            The slot the item will be located at\n     * @param menuItemWrapper The item stack wrapper\n     * @param actionHandler   The handler that handles the click\n     * @param actionArgs      Arguments for the action handler\n     */\n    default void set(\n            int slot,\n            MenuItemWrapper menuItemWrapper,\n            String actionHandler,\n            List<String> actionArgs) {\n        set(slot, InventoryMenuItemWrapper.builder()\n                .handle(menuItemWrapper)\n                .actionHandler(actionHandler)\n                .actionArguments(actionArgs)\n                .build());\n    }\n\n    /**\n     * Sets an item into a given position in the container\n     *\n     * @param slot  The slot the item will be located at\n     * @param model The item stack model\n     */\n    default void set(int slot, CirrusItem model) {\n        set(slot, InventoryMenuItemWrapper.builder()\n                .handle(Converters.convert(model, InventoryMenuItemWrapper.class))\n                .actionHandler(model.actionHandler())\n                .actionArguments(model.actionArguments())\n                .build());\n    }\n\n    /**\n     * Returns the item stack from the given position\n     *\n     * @param slot slot\n     * @return item\n     */\n    default InventoryMenuItemWrapper get(int slot) {\n        return itemMap().get(slot);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/container/impl/ItemContainer.java",
    "content": "package dev.simplix.cirrus.common.container.impl;\n\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.container.Container;\nimport dev.simplix.cirrus.common.util.InventoryContentMap;\n\nimport java.util.HashSet;\nimport java.util.Map;\nimport java.util.Set;\n\nimport lombok.NonNull;\n\npublic class ItemContainer implements Container {\n\n    private final InventoryContentMap inventoryContentMap = new InventoryContentMap();\n    private final Set<Integer> reservedSlots = new HashSet<>();\n    private final int baseSlotIndex;\n    private final int capacity;\n\n    public ItemContainer(int baseSlotIndex, int capacity) {\n        this.baseSlotIndex = baseSlotIndex;\n        this.capacity = capacity;\n    }\n\n    @Override\n    public void set(int slot, @NonNull InventoryMenuItemWrapper inventoryItemWrapper) {\n        itemMap().put(slot + this.baseSlotIndex, inventoryItemWrapper);\n    }\n\n    @Override\n    public Map<Integer, InventoryMenuItemWrapper> itemMap() {\n        return this.inventoryContentMap;\n    }\n\n    @Override\n    public Set<Integer> reservedSlots() {\n        return this.reservedSlots;\n    }\n\n    @Override\n    public int capacity() {\n        return this.capacity;\n    }\n\n    @Override\n    public int baseSlot() {\n        return this.baseSlotIndex;\n    }\n\n    @Override\n    public int nextFreeSlot() {\n        for (int i = this.baseSlotIndex; i < this.capacity + this.baseSlotIndex; i++) {\n            if (!itemMap().containsKey(i) && !reservedSlots().contains(i)) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n    @Override\n    public int nextFreeSlot(int base) {\n        for (int i = base; i < this.capacity + this.baseSlotIndex; i++) {\n            if (!itemMap().containsKey(i) && !reservedSlots().contains(i)) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/converter/Converter.java",
    "content": "package dev.simplix.cirrus.common.converter;\n\nimport lombok.NonNull;\n\n/**\n * A converter is used to convert one object to another.\n *\n * @param <Source> The source type of the object\n * @param <Target> The target type ot the object\n */\npublic interface Converter<Source, Target> {\n\n    /**\n     * Converts a given source object to the target type.\n     *\n     * @param src The source object\n     * @return The target object\n     */\n    Target convert(@NonNull Source src);\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/converter/Converters.java",
    "content": "package dev.simplix.cirrus.common.converter;\n\nimport lombok.NonNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.AbstractMap.SimpleEntry;\nimport java.util.*;\nimport java.util.Map.Entry;\n\n/**\n * Central registration class for {@link Converter}s.\n */\n@SuppressWarnings(\"rawtypes\")\npublic final class Converters {\n\n    private static final Map<Entry<Class, Class>, Converter> CONVERTER_MAP = new HashMap<>();\n\n    private Converters() {\n    }\n\n    /**\n     * Converts a source object to a given type.\n     *\n     * @param source The source object to convert\n     * @param to     The target type class\n     * @param <T>    The target type\n     * @return An object instance of the target type\n     */\n    public static <T> T convert(@NonNull final Object source, @NonNull final Class<T> to) {\n        Converter converter = getConverter(source.getClass(), to);\n        if (converter == null) {\n            converter = getMultiConverter(source.getClass(), to);\n        }\n        if (converter == null) {\n            throw new NullPointerException(\"No converter available to convert \" + source\n                    .getClass()\n                    .getName() + \" to \" + to.getName());\n        }\n        return (T) converter.convert(source);\n    }\n\n    private static <S, T> Converter<S, T> getMultiConverter(\n            @NonNull final Class<S> source,\n            @NonNull final Class<T> to) {\n        final List<Converter> converters = new ArrayList<>();\n        findConversionRoute(converters, source, to);\n        if (converters.size() <= 1) {\n            return null;\n        }\n        return src -> {\n            Object out = src;\n            for (final Converter converter : converters) {\n                out = converter.convert(out);\n            }\n            return (T) out;\n        };\n    }\n\n    private static boolean findConversionRoute(\n            @NonNull final List<Converter> converters,\n            @NonNull final Class<?> source,\n            @NonNull final Class<?> to) {\n        for (final Entry<Class, Class> entry : CONVERTER_MAP.keySet()) {\n            if (entry.getKey().equals(source)) {\n                final List<Converter> list = new ArrayList<>();\n                if (buildRoute(list, entry, to)) {\n                    list.add(CONVERTER_MAP.get(entry));\n                    Collections.reverse(list);\n                    converters.addAll(list);\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    private static boolean buildRoute(\n            @NonNull final List<Converter> converters,\n            @NonNull final Map.Entry<Class, Class> entry,\n            @NonNull final Class<?> to) {\n        if (entry.getValue().equals(to)) {\n            return true;\n        }\n        for (final Entry<Class, Class> entry1 : CONVERTER_MAP.keySet()) {\n            if (entry1.getKey().equals(entry.getValue())) {\n                if (buildRoute(converters, entry1, to)) {\n                    converters.add(CONVERTER_MAP.get(entry1));\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Registers a {@link Converter} for a given type conversion.\n     *\n     * @param sourceType The source type\n     * @param targetType The target type\n     * @param converter  The convert instance\n     */\n    public static void register(\n            @NonNull final Class<?> sourceType,\n            @NonNull final Class targetType,\n            @NonNull final Converter converter) {\n        CONVERTER_MAP.put(new SimpleEntry<>(sourceType, targetType), converter);\n    }\n\n    /**\n     * Returns a registered converter\n     *\n     * @param sourceType The source type class\n     * @param targetType The target type class\n     * @param <S>        The source type\n     * @param <T>        The target type\n     * @return The converter instance or null if no such converter exists\n     */\n    @Nullable\n    public static <S, T> Converter<S, T> getConverter(\n            final Class<S> sourceType,\n            final Class<T> targetType) {\n        Converter converter = CONVERTER_MAP.get(new SimpleEntry<>(sourceType, targetType));\n        if (converter == null) {\n            for (Entry<Class, Class> entry : CONVERTER_MAP.keySet()) {\n                if (entry.getKey().isAssignableFrom(sourceType)) {\n                    if (entry.getValue().equals(targetType)) {\n                        return CONVERTER_MAP.get(entry);\n                    }\n                }\n            }\n        }\n        return converter;\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/AbstractChangingItemAnimation.java",
    "content": "package dev.simplix.cirrus.common.effect;\n\nimport dev.simplix.cirrus.common.item.CirrusItem;\n\npublic abstract class AbstractChangingItemAnimation extends AbstractMenuAnimation<CirrusItem> {\n\n    protected AbstractChangingItemAnimation(CirrusItem input, int effectLength) {\n        super(input, effectLength);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/AbstractMenuAnimation.java",
    "content": "package dev.simplix.cirrus.common.effect;\n\nimport com.google.common.base.Preconditions;\nimport com.google.common.collect.Iterators;\n\nimport java.util.Iterator;\n\npublic abstract class AbstractMenuAnimation<T> implements MenuAnimation<T> {\n    protected final T input;\n    protected final int effectLength;\n\n    private Iterator<T> iterator;\n\n    protected AbstractMenuAnimation(\n            T input,\n            int effectLength) {\n        this.input = Preconditions.checkNotNull(input, \"input must not be null\");\n        Preconditions.checkState(effectLength > 0, \"effectLength is not larger than 0\");\n        this.effectLength = effectLength;\n    }\n\n    @Override\n    public int effectLength() {\n        return this.effectLength;\n    }\n\n    @Override\n    public final T input() {\n        return this.input;\n    }\n\n    @Override\n    public final T next() {\n        if (this.iterator == null) {\n            this.iterator = Iterators.cycle(calculate());\n        }\n\n        return this.iterator.next();\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/Animated.java",
    "content": "package dev.simplix.cirrus.common.effect;\n\nimport dev.simplix.cirrus.common.menu.Menu;\n\npublic interface Animated extends Menu {\n    void update();\n\n    @Override\n    default void handleClose(boolean inventorySwitch) {\n        MenuAnimator.remove(this);\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/Animations.java",
    "content": "package dev.simplix.cirrus.common.effect;\n\nimport lombok.experimental.UtilityClass;\n\n@UtilityClass\npublic class Animations {\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/MenuAnimation.java",
    "content": "package dev.simplix.cirrus.common.effect;\n\nimport java.util.List;\n\npublic interface MenuAnimation<T> {\n\n    /**\n     * Duration of the effect in the menu in ticks\n     */\n    int effectLength();\n\n    /**\n     * Initial input of the effect\n     */\n    T input();\n\n    /**\n     * All calculated values for the effect\n     */\n    List<T> calculate();\n\n    /**\n     * Next effect frame. Usually calculated with an\n     * infinite iterable calculated with {@link MenuAnimation#calculate()}\n     * and created with {@link com.google.common.collect.Iterables#cycle(Object[])}\n     */\n    T next();\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/effect/MenuAnimator.java",
    "content": "package dev.simplix.cirrus.common.effect;\n\nimport lombok.NonNull;\nimport lombok.experimental.UtilityClass;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\n@UtilityClass\npublic class MenuAnimator {\n    private final List<Animated> menus = new LinkedList<>();\n\n    public boolean isEmpty() {\n        return menus.isEmpty();\n    }\n\n    public void register(@NonNull Animated menu) {\n        menus.add(menu);\n    }\n\n    public void remove(@NonNull Animated menu) {\n        menus.remove(menu);\n    }\n\n    public void updateAll() {\n        for (Animated menu : menus) {\n            menu.update();\n            menu.build();\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/effects/GradualColorChangeAnimation.java",
    "content": "package dev.simplix.cirrus.common.effects;\n\nimport com.google.common.base.Preconditions;\nimport dev.simplix.cirrus.common.effect.AbstractMenuAnimation;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Will generate: <a href=\"https://media3.giphy.com/media/bvuK2KpLTip6vtemxY/giphy.gif?cid=790b7611af638e257a5f310fdd6d3015bfb9ee3119298826&rid=giphy.gif&ct=g\">...</a>\n */\npublic class GradualColorChangeAnimation extends AbstractMenuAnimation<String> {\n\n    protected final String primaryColor;\n    protected final String secondaryColor;\n\n    protected boolean reverse = false;\n    protected int transitionCount = 0;\n\n    public GradualColorChangeAnimation(\n            String primaryColor,\n            String input) {\n        this(primaryColor, \"§f§l\", input, 2);\n    }\n\n    public GradualColorChangeAnimation(\n            String primaryColor,\n            String secondaryColor,\n            String input,\n            int effectLength) {\n        super(input, effectLength);\n        this.primaryColor = Preconditions.checkNotNull(primaryColor, \"primaryColor must not be null\");\n        this.secondaryColor = Preconditions.checkNotNull(secondaryColor, \"secondaryColor must not be null\");\n    }\n\n    public GradualColorChangeAnimation reversed() {\n        this.reverse = true;\n        return this;\n    }\n\n    public GradualColorChangeAnimation reverse(boolean reverse) {\n        this.reverse = reverse;\n        return this;\n    }\n\n    public GradualColorChangeAnimation transitionCount(int transitionCount) {\n        this.transitionCount = transitionCount;\n        return this;\n    }\n\n    public GradualColorChangeAnimation length(int length) {\n        return new GradualColorChangeAnimation(this.primaryColor, this.secondaryColor, this.input, length).reverse(this.reverse).transitionCount(this.transitionCount);\n    }\n\n    @Override\n    public List<String> calculate() {\n\n        final List<String> out = new ArrayList<>();\n        out.addAll(insertEffect(this.primaryColor, this.secondaryColor));\n        out.addAll(insertEffect(this.secondaryColor, this.primaryColor));\n\n        return out;\n    }\n\n    private List<String> insertEffect(String effectColor, String primaryColor) {\n        final List<String> out = new ArrayList<>();\n\n        if (this.reverse) {\n            for (int i = this.input.length() - 1; i >= 0; i--) {\n                out.addAll(Collections.nCopies(this.effectLength, addAtIndex(primaryColor + this.input, effectColor, i + primaryColor.length())));\n            }\n            if (this.transitionCount != 0) {\n                out.addAll(Collections.nCopies(this.transitionCount, effectColor + this.input));\n            }\n\n        } else {\n            for (int i = 0; i <= this.input.length(); i++) {\n                out.addAll(Collections.nCopies(this.effectLength, addAtIndex(primaryColor + this.input, effectColor, i + primaryColor.length())));\n            }\n            if (this.transitionCount != 0) {\n                out.addAll(Collections.nCopies(this.transitionCount, primaryColor + this.input));\n            }\n        }\n        return out;\n    }\n\n    private String addAtIndex(String str, String toAdd, int position) {\n        StringBuilder sb = new StringBuilder(str);\n        sb.insert(position, toAdd);\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/effects/RGBColorChangeAnimation.java",
    "content": "package dev.simplix.cirrus.common.effects;\n\nimport com.google.common.base.Preconditions;\nimport dev.simplix.cirrus.common.effect.AbstractMenuAnimation;\nimport dev.simplix.cirrus.common.util.ColorUtils;\nimport net.md_5.bungee.api.ChatColor;\n\nimport java.awt.*;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\n\npublic class RGBColorChangeAnimation extends AbstractMenuAnimation<String> {\n\n    private final List<Color> colors;\n    private String colorSuffix;\n    private double step;\n\n    private RGBColorChangeAnimation(\n            String input,\n            int effectLength,\n            double step,\n            String colorSuffix,\n            List<Color> colors\n    ) {\n        super(Preconditions.checkNotNull(input, \"input must not be null\"), effectLength);\n        this.step = step;\n        this.colors = Preconditions.checkNotNull(colors, \"colors must not be null\");\n        this.colorSuffix = Preconditions.checkNotNull(colorSuffix, \"colorAddon must not be null\");\n        Preconditions.checkState(colors.size() >= 2, \"At least 2 colors must be provided¥\");\n    }\n\n    public static RGBColorChangeAnimation fat(String input, Color... colors) {\n        return of(input, \"§l\", 2, 40, colors);\n    }\n\n    public static RGBColorChangeAnimation of(String input, String colorSuffix, int effectLength, double step, Color... colors) {\n        return new RGBColorChangeAnimation(input, effectLength, step, colorSuffix, Arrays.asList(colors));\n    }\n\n    public RGBColorChangeAnimation step(int step) {\n        this.step = step;\n        return this;\n    }\n\n    public RGBColorChangeAnimation colorSuffix(String colorSuffix) {\n        this.colorSuffix = colorSuffix;\n        return this;\n    }\n\n    @Override\n    public List<String> calculate() {\n        final List<String> out = new ArrayList<>();\n\n        for (int i = 0; i < this.colors.size(); i++) {\n            final Color color = this.colors.get(i);\n            final int index = (this.colors.size() == i + 1) ? 0 : (i + 1);\n            final Color color2 = this.colors.get(index);\n\n            out.addAll(Collections.nCopies(\n                    this.effectLength,\n                    ChatColor.of(color) + this.colorSuffix + this.input\n            ));\n\n            for (Color between : ColorUtils.colorsInBetween(color, color2, this.step)) {\n                out.addAll(\n                        Collections.nCopies(\n                                this.effectLength,\n                                ChatColor.of(between) + this.colorSuffix + this.input\n                        )\n                );\n            }\n        }\n\n        return out;\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/effects/SimpleChangingItemAnimation.java",
    "content": "package dev.simplix.cirrus.common.effects;\n\nimport dev.simplix.cirrus.common.effect.AbstractChangingItemAnimation;\nimport dev.simplix.cirrus.common.item.CirrusItem;\n\nimport java.util.List;\n\npublic class SimpleChangingItemAnimation extends AbstractChangingItemAnimation {\n    private final List<CirrusItem> values;\n\n    protected SimpleChangingItemAnimation(CirrusItem basis, List<CirrusItem> values, int effectLength) {\n        super(basis, effectLength);\n        this.values = values;\n    }\n\n    @Override\n    public List<CirrusItem> calculate() {\n        return this.values;\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/handler/ActionHandler.java",
    "content": "package dev.simplix.cirrus.common.handler;\n\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.model.CallResult;\nimport dev.simplix.cirrus.common.model.Click;\n\n/**\n * {@link ActionHandler}s are functions that get called when a click on an {@link\n * InventoryMenuItemWrapper} occurs.\n */\n@FunctionalInterface\npublic interface ActionHandler {\n\n    CallResult handle(Click click);\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/handler/AutoCancellingActionHandler.java",
    "content": "package dev.simplix.cirrus.common.handler;\n\nimport dev.simplix.cirrus.common.model.CallResult;\nimport dev.simplix.cirrus.common.model.Click;\n\n@FunctionalInterface\npublic interface AutoCancellingActionHandler extends ActionHandler {\n    @Override\n    default CallResult handle(Click click) {\n        onHandle(click);\n        return CallResult.DENY_GRABBING;\n    }\n\n    void onHandle(Click click);\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedItemStackModel.java",
    "content": "package dev.simplix.cirrus.common.i18n;\n\nimport dev.simplix.cirrus.common.Utils;\nimport dev.simplix.cirrus.common.item.CirrusItem;\nimport dev.simplix.protocolize.data.ItemType;\nimport lombok.*;\nimport lombok.experimental.Accessors;\nimport net.querz.nbt.tag.CompoundTag;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Locale;\n\n@Data\n@Builder\n@Accessors(fluent = true)\n@ToString\n@NoArgsConstructor\n@AllArgsConstructor\npublic class LocalizedItemStackModel {\n\n    @Builder.Default\n    private LocalizedString displayName = new LocalizedString(new HashMap<>());\n    @Builder.Default\n    private LocalizedStringList lore = new LocalizedStringList(new HashMap<>());\n    @Builder.Default\n    private ItemType itemType = ItemType.STONE;\n    @Builder.Default\n    private byte amount = 1;\n    @Builder.Default\n    private short durability = -1;\n    @Builder.Default\n    private String actionHandler = \"noAction\";\n    @Builder.Default\n    private List<String> actionArguments = Collections.emptyList();\n    @Builder.Default\n    private int[] slots = new int[0];\n    @Builder.Default\n    @NonNull\n    private CompoundTag nbt = new CompoundTag();\n\n    public LocalizedItemStackModel glow() {\n        Utils.glow(this.nbt);\n        return this;\n    }\n\n    public LocalizedItemStackModel texture(@NonNull String texture) {\n        Utils.texture(this.nbt, texture);\n        return this;\n    }\n\n    public CirrusItem localize(Locale locale, String... replacements) {\n        return Localizer.localize(\n                this,\n                locale,\n                replacements\n        );\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedString.java",
    "content": "package dev.simplix.cirrus.common.i18n;\n\nimport lombok.NonNull;\n\nimport java.util.HashMap;\nimport java.util.Locale;\nimport java.util.Map;\n\npublic class LocalizedString {\n\n    private final Map<String, String> translations = new HashMap<>();\n\n    public LocalizedString(@NonNull Map<String, String> stringMap) {\n        this.translations.putAll(stringMap);\n    }\n\n    /**\n     * @return The map with all translations\n     */\n    public Map<String, String> translations() {\n        return this.translations;\n    }\n\n    /**\n     * Returns the localized string for the given {@link Locale}. If the given locale is not\n     * available, it will return the first available translation. If there aren't any translations, it\n     * will return \"missigno.\"\n     *\n     * @param locale The desired locale\n     * @return the localized string or \"missigno.\"\n     */\n    public String translated(Locale locale) {\n        return this.translations.getOrDefault(\n                locale.getLanguage(),\n                this.translations.getOrDefault(\n                        this.translations.keySet().stream().findFirst().orElse(\"\"),\n                        \"missgno.\"));\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedStringDeserializer.java",
    "content": "package dev.simplix.cirrus.common.i18n;\n\nimport com.google.gson.JsonDeserializationContext;\nimport com.google.gson.JsonDeserializer;\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonParseException;\nimport com.google.gson.reflect.TypeToken;\nimport lombok.NonNull;\n\nimport java.lang.reflect.Type;\nimport java.util.Map;\n\npublic class LocalizedStringDeserializer implements JsonDeserializer<LocalizedString> {\n\n    @Override\n    public LocalizedString deserialize(\n            @NonNull JsonElement jsonElement,\n            @NonNull Type type,\n            @NonNull JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {\n        Map<String, String> stringMap = jsonDeserializationContext.deserialize(\n                jsonElement,\n                new TypeToken<Map<String, String>>() {\n                }.getType());\n        return new LocalizedString(stringMap);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedStringList.java",
    "content": "package dev.simplix.cirrus.common.i18n;\n\nimport lombok.NoArgsConstructor;\nimport lombok.NonNull;\n\nimport java.util.*;\n\n@NoArgsConstructor\npublic class LocalizedStringList {\n\n    private final Map<String, List<String>> translations = new HashMap<>();\n\n    public LocalizedStringList(@NonNull Map<String, List<String>> stringListMap) {\n        this.translations.putAll(stringListMap);\n    }\n\n    /**\n     * @return The map with all translations\n     */\n    public Map<String, List<String>> translations() {\n        return this.translations;\n    }\n\n\n    private final List<String> forceAdded = new ArrayList<>();\n\n    /**\n     * Returns the localized string list for the given {@link Locale}. If the given locale is not\n     * available, it will return the first available translation. If there aren't any translations, it\n     * will return an empty list.\n     *\n     * @param locale The desired locale\n     * @return the localized string list\n     */\n    public List<String> translated(@NonNull Locale locale) {\n        if (this.translations.isEmpty()) {\n            return Collections.emptyList();\n        }\n        String fallback = this.translations.keySet().iterator().next();\n        final List<String> out = new ArrayList<>(this.translations.getOrDefault(\n                locale.getLanguage(),\n                this.translations.getOrDefault(\n                        fallback,\n                        Collections.emptyList()))\n        );\n\n        out.addAll(this.forceAdded);\n        return out;\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedStringListDeserializer.java",
    "content": "package dev.simplix.cirrus.common.i18n;\n\nimport com.google.gson.JsonDeserializationContext;\nimport com.google.gson.JsonDeserializer;\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonParseException;\nimport com.google.gson.reflect.TypeToken;\nimport lombok.NonNull;\n\nimport java.lang.reflect.Type;\nimport java.util.List;\nimport java.util.Map;\n\npublic class LocalizedStringListDeserializer implements JsonDeserializer<LocalizedStringList> {\n\n    @Override\n    public LocalizedStringList deserialize(\n            @NonNull JsonElement jsonElement,\n            @NonNull Type type,\n            @NonNull JsonDeserializationContext jsonDeserializationContext)\n            throws JsonParseException {\n        Map<String, List<String>> stringListMap = jsonDeserializationContext.deserialize(\n                jsonElement,\n                new TypeToken<Map<String, List<String>>>() {\n                }.getType());\n        return new LocalizedStringList(stringListMap);\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedStringListSerializer.java",
    "content": "package dev.simplix.cirrus.common.i18n;\n\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonSerializationContext;\nimport com.google.gson.JsonSerializer;\nimport lombok.NonNull;\n\nimport java.lang.reflect.Type;\n\npublic class LocalizedStringListSerializer implements JsonSerializer<LocalizedStringList> {\n\n    @Override\n    public JsonElement serialize(\n            @NonNull LocalizedStringList localizedStringList,\n            @NonNull Type type,\n            @NonNull JsonSerializationContext jsonSerializationContext) {\n        return jsonSerializationContext.serialize(localizedStringList.translations());\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/LocalizedStringSerializer.java",
    "content": "package dev.simplix.cirrus.common.i18n;\n\nimport com.google.gson.JsonElement;\nimport com.google.gson.JsonSerializationContext;\nimport com.google.gson.JsonSerializer;\nimport lombok.NonNull;\n\nimport java.lang.reflect.Type;\n\npublic class LocalizedStringSerializer implements JsonSerializer<LocalizedString> {\n\n    @Override\n    public JsonElement serialize(\n            @NonNull LocalizedString localizedString,\n            @NonNull Type type,\n            @NonNull JsonSerializationContext jsonSerializationContext) {\n        return jsonSerializationContext.serialize(localizedString.translations());\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/Localizer.java",
    "content": "package dev.simplix.cirrus.common.i18n;\n\nimport dev.simplix.cirrus.common.item.CirrusItem;\nimport lombok.NonNull;\nimport net.querz.nbt.io.SNBTUtil;\nimport net.querz.nbt.tag.CompoundTag;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.io.IOException;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Locale;\n\npublic final class Localizer {\n\n    public static List<String> localize(\n            LocalizedStringList localizedStringList,\n            @NonNull Locale locale,\n            String... replacements) {\n        if (localizedStringList == null) {\n            return Collections.emptyList();\n        }\n        return Arrays.asList(Replacer.of(localizedStringList.translated(locale))\n                .replaceAll((Object[]) replacements).replacedMessage());\n    }\n\n    public static String localize(\n            LocalizedString localizedString,\n            @NonNull Locale locale,\n            String... replacements) {\n        if (localizedString == null) {\n            return \"\";\n        }\n        return Replacer\n                .of(localizedString.translated(locale))\n                .replaceAll((Object[]) replacements)\n                .replacedMessageJoined();\n    }\n\n    public static CirrusItem localize(\n            @NonNull LocalizedItemStackModel model,\n            @NonNull Locale locale,\n            @NonNull String... replacements) {\n        return CirrusItem.of(localize(model.displayName(), locale, replacements))\n                .actionArguments(Arrays.asList(Replacer\n                        .of(model.actionArguments() == null ? Collections.emptyList() : model.actionArguments())\n                        .replaceAll((Object[]) replacements)\n                        .replacedMessage()))\n                .actionHandler(model.actionHandler())\n                .amount(model.amount())\n                .durability(model.durability())\n                .itemType(model.itemType())\n                .lore(localize(model.lore(), locale, replacements))\n                .nbt(formatNbt(model.nbt(), replacements))\n                .slots(model.slots());\n    }\n\n    private static CompoundTag formatNbt(\n            @Nullable CompoundTag compoundTag,\n            @NonNull String... replacements) {\n        if (compoundTag == null) {\n            return null;\n        }\n        try {\n            String mojangson = SNBTUtil.toSNBT(compoundTag);\n            return (CompoundTag) SNBTUtil.fromSNBT(Replacer.of(mojangson)\n                    .replaceAll((Object[]) replacements).replacedMessageJoined());\n        } catch (IOException ioException) {\n            // Ignored\n        }\n        return compoundTag;\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/i18n/Replacer.java",
    "content": "package dev.simplix.cirrus.common.i18n;\n\nimport com.google.common.base.Preconditions;\nimport lombok.Getter;\nimport lombok.NonNull;\nimport lombok.experimental.Accessors;\nimport lombok.val;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n * This is a utility class for handy message replacements. Placeholders begin with { and are ending\n * with }\n * <br>\n * <b>Example:</b>\n * <br> {viewer}\n */\n@Getter\n@Accessors(fluent = true)\npublic final class Replacer {\n\n    public static final String DELIMITER = \"\\n\";\n    private final List<String> messages;\n\n    //Messages to replace\n    private final List<String> variables = new ArrayList<>();\n    private final List<Object> replacements = new ArrayList<>();\n\n    private Replacer(List<String> messages) {\n        // Cloning our messages\n        this.messages = new ArrayList<>(messages);\n    }\n\n    // ----------------------------------------------------------------------------------------------------\n    // Static Factory methods\n    // ----------------------------------------------------------------------------------------------------\n    public static Replacer of(@NonNull final String... messages) {\n        return new Replacer(Arrays.asList(messages));\n    }\n\n    public static Replacer of(@NonNull final List<String> messages) {\n        return new Replacer(messages);\n    }\n\n    public static Replacer ofMultilineString(@NonNull final String multilineString) {\n        return new Replacer(Arrays.asList(multilineString.split(DELIMITER)));\n    }\n\n    public final Replacer find(@NonNull final String... variables) {\n        this.variables.clear();\n        this.variables.addAll(Arrays.asList(variables));\n        return this;\n    }\n\n    public final Replacer replace(@NonNull final Object... replacements) {\n        this.replacements.clear();\n\n        this.replacements.addAll(Arrays.asList(replacements));\n        return this;\n    }\n\n    public Replacer set(final int index, @NonNull final String message) {\n        this.messages.set(index, message);\n        return this;\n    }\n\n    /**\n     * Replaces all variables with replacements.\n     *\n     * @param associativeArray Variable, Replacement, Variable, Replacement\n     */\n    public final Replacer replaceAll(@NonNull final Object... associativeArray) {\n        this.variables.clear();\n        this.replacements.clear();\n\n        //Even: Value\n        for (int i = 0; i < associativeArray.length; i++) {\n            if (i % 2 == 0) {\n                //Odd: Key\n                val raw = associativeArray[i];\n                Preconditions.checkState(\n                        raw instanceof String,\n                        \"Expected String at \" + raw + \", got \" + raw.getClass()\n                                .getSimpleName());\n                this.variables.add((String) raw);\n            } else {\n                this.replacements.add(associativeArray[i]);\n            }\n        }\n        return this;\n    }\n\n    /**\n     * Method to replace the registered Replacers.\n     */\n    public String[] replacedMessage() {\n        Preconditions.checkState(\n                this.replacements.size() == this.variables.size(),\n                \"Variables \" + this.variables.size()\n                        + \" != replacements \" + this.replacements.size(),\n                \"Variables: \" + this.variables.toString(),\n                \"Replacments: \" + this.replacements\n        );\n\n        // Join and replace as 1 message for maximum performance\n        String message = String.join(DELIMITER, this.messages);\n\n        for (int i = 0; i < this.variables.size(); i++) {\n            String found = this.variables.get(i);\n            { // Auto insert brackets\n                if (!found.startsWith(\"{\")) {\n                    found = \"{\" + found;\n                }\n\n                if (!found.endsWith(\"}\")) {\n                    found = found + \"}\";\n                }\n            }\n            final Object rep = i <= this.replacements.size() ? this.replacements.get(i) : null;\n\n            message = message.replace(found, rep == null ? \"\" : rep.toString());\n        }\n\n        return message.split(DELIMITER);\n    }\n\n    /**\n     * Same as {@link #replacedMessage()} but joined using {@link String#join(CharSequence,\n     * CharSequence...)} and the {@link #DELIMITER}\n     */\n    public String replacedMessageJoined() {\n        return String.join(DELIMITER, replacedMessage());\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/item/CirrusItem.java",
    "content": "package dev.simplix.cirrus.common.item;\n\nimport dev.simplix.cirrus.common.Utils;\nimport dev.simplix.cirrus.common.effect.AbstractMenuAnimation;\nimport dev.simplix.protocolize.data.ItemType;\nimport lombok.NonNull;\nimport lombok.experimental.Accessors;\nimport net.querz.nbt.tag.CompoundTag;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.function.Supplier;\n\n@Accessors(fluent = true)\npublic class CirrusItem {\n\n    @NonNull\n    private String displayName = \"Example-DisplayName\";\n    @Nullable\n    private AbstractMenuAnimation<String> titleEffect = null;\n    private List<String> lore = Collections.emptyList();\n    @Nullable\n    private Supplier<List<String>> loreSupplier = null;\n    private ItemType itemType = ItemType.STONE;\n    private byte amount = 1;\n    private short durability = -1;\n    private String actionHandler = \"noAction\";\n    private List<String> actionArguments = Collections.emptyList();\n    private int[] slots = new int[0];\n    @NonNull\n    private CompoundTag nbt;\n\n    private CirrusItem(@NonNull String displayName, @Nullable AbstractMenuAnimation<String> titleEffect, List<String> lore, @Nullable Supplier<List<String>> loreSupplier, ItemType itemType, byte amount, short durability, String actionHandler, List<String> actionArguments, int[] slots, @NonNull CompoundTag nbt) {\n        this.displayName = displayName;\n        this.titleEffect = titleEffect;\n        this.lore = lore;\n        this.loreSupplier = loreSupplier;\n        this.itemType = itemType;\n        this.amount = amount;\n        this.durability = durability;\n        this.actionHandler = actionHandler;\n        this.actionArguments = actionArguments;\n        this.slots = slots;\n        this.nbt = nbt;\n    }\n\n    private CirrusItem() {\n    }\n\n    // ----------------------------------------------------------------------------------------------------\n    // Instancing\n    // ----------------------------------------------------------------------------------------------------\n\n    public static CirrusItem of(String name, ItemType type) {\n        return new CirrusItem().displayName(name).itemType(type);\n    }\n\n    public static CirrusItem of(String name) {\n        return of(name, ItemType.STONE);\n    }\n\n    public static CirrusItem animated(AbstractMenuAnimation<String> effect, ItemType type) {\n        return new CirrusItem().itemType(type).titleEffect(effect);\n    }\n\n    public static CirrusItem animated(AbstractMenuAnimation<String> effect) {\n        return animated(effect, ItemType.STONE);\n    }\n\n    // ----------------------------------------------------------------------------------------------------\n    // Chained setters\n    // ----------------------------------------------------------------------------------------------------\n\n    public CirrusItem lore(String... lines) {\n        this.lore = Arrays.asList(lines);\n        return this;\n    }\n\n    public CirrusItem slot(int... slots) {\n        this.slots = slots;\n        return this;\n    }\n\n    public String displayNam() {\n        if (this.titleEffect != null) {\n            return this.titleEffect.next();\n        }\n        return this.displayName;\n    }\n\n    public CirrusItem glow() {\n        Utils.glow(this.nbt);\n        return this;\n    }\n\n    public CirrusItem texture(@NonNull String texture) {\n        Utils.texture(this.nbt, texture);\n        return this;\n    }\n\n    public CirrusItem copy() {\n        return new CirrusItem(\n                this.displayName,\n                this.titleEffect,\n                this.lore,\n                this.loreSupplier,\n                this.itemType,\n                this.amount,\n                this.durability,\n                this.actionHandler,\n                this.actionArguments,\n                this.slots,\n                this.nbt\n        );\n    }\n\n    public @NonNull String displayName() {\n        return this.displayName;\n    }\n\n    public @Nullable AbstractMenuAnimation<String> titleEffect() {\n        return this.titleEffect;\n    }\n\n    public List<String> lore() {\n        if (this.loreSupplier != null) {\n            return this.loreSupplier.get();\n        }\n        return this.lore;\n    }\n\n    public @Nullable Supplier<List<String>> loreSupplier() {\n        return this.loreSupplier;\n    }\n\n    public ItemType itemType() {\n        return this.itemType;\n    }\n\n    public byte amount() {\n        return this.amount;\n    }\n\n    public short durability() {\n        return this.durability;\n    }\n\n    public String actionHandler() {\n        return this.actionHandler;\n    }\n\n    public List<String> actionArguments() {\n        return this.actionArguments;\n    }\n\n    public int[] slots() {\n        return this.slots;\n    }\n\n    public @NonNull CompoundTag nbt() {\n        return this.nbt;\n    }\n\n    public CirrusItem displayName(@NonNull String displayName) {\n        this.displayName = displayName;\n        return this;\n    }\n\n    public CirrusItem titleEffect(@Nullable AbstractMenuAnimation<String> titleEffect) {\n        this.titleEffect = titleEffect;\n        return this;\n    }\n\n    public CirrusItem lore(List<String> lore) {\n        this.lore = lore;\n        return this;\n    }\n\n    public CirrusItem loreSupplier(@Nullable Supplier<List<String>> loreSupplier) {\n        this.loreSupplier = loreSupplier;\n        return this;\n    }\n\n    public CirrusItem itemType(ItemType itemType) {\n        this.itemType = itemType;\n        return this;\n    }\n\n    public CirrusItem amount(byte amount) {\n        this.amount = amount;\n        return this;\n    }\n\n    public CirrusItem durability(short durability) {\n        this.durability = durability;\n        return this;\n    }\n\n    public CirrusItem actionHandler(String actionHandler) {\n        this.actionHandler = actionHandler;\n        return this;\n    }\n\n    public CirrusItem actionArguments(List<String> actionArguments) {\n        this.actionArguments = actionArguments;\n        return this;\n    }\n\n    public CirrusItem slots(int[] slots) {\n        this.slots = slots;\n        return this;\n    }\n\n    public CirrusItem nbt(@NonNull CompoundTag nbt) {\n        this.nbt = nbt;\n        return this;\n    }\n\n    @Override\n    public boolean equals(final Object o) {\n        if (o == this) {\n            return true;\n        }\n        if (!(o instanceof CirrusItem)) {\n            return false;\n        }\n        final CirrusItem other = (CirrusItem) o;\n        if (!other.canEqual((Object) this)) {\n            return false;\n        }\n        final Object this$displayName = this.displayName();\n        final Object other$displayName = other.displayName();\n        if (this$displayName == null ? other$displayName != null : !this$displayName.equals(other$displayName)) {\n            return false;\n        }\n        final Object this$titleEffect = this.titleEffect();\n        final Object other$titleEffect = other.titleEffect();\n        if (this$titleEffect == null ? other$titleEffect != null : !this$titleEffect.equals(other$titleEffect)) {\n            return false;\n        }\n        final Object this$lore = this.lore();\n        final Object other$lore = other.lore();\n        if (this$lore == null ? other$lore != null : !this$lore.equals(other$lore)) {\n            return false;\n        }\n        final Object this$loreSupplier = this.loreSupplier();\n        final Object other$loreSupplier = other.loreSupplier();\n        if (this$loreSupplier == null ? other$loreSupplier != null : !this$loreSupplier.equals(other$loreSupplier)) {\n            return false;\n        }\n        final Object this$itemType = this.itemType();\n        final Object other$itemType = other.itemType();\n        if (this$itemType == null ? other$itemType != null : !this$itemType.equals(other$itemType)) {\n            return false;\n        }\n        if (this.amount() != other.amount()) {\n            return false;\n        }\n        if (this.durability() != other.durability()) {\n            return false;\n        }\n        final Object this$actionHandler = this.actionHandler();\n        final Object other$actionHandler = other.actionHandler();\n        if (this$actionHandler == null ? other$actionHandler != null : !this$actionHandler.equals(other$actionHandler)) {\n            return false;\n        }\n        final Object this$actionArguments = this.actionArguments();\n        final Object other$actionArguments = other.actionArguments();\n        if (this$actionArguments == null ? other$actionArguments != null : !this$actionArguments.equals(other$actionArguments)) {\n            return false;\n        }\n        if (!Arrays.equals(this.slots(), other.slots())) {\n            return false;\n        }\n        final Object this$nbt = this.nbt();\n        final Object other$nbt = other.nbt();\n        if (this$nbt == null ? other$nbt != null : !this$nbt.equals(other$nbt)) {\n            return false;\n        }\n        return true;\n    }\n\n    protected boolean canEqual(final Object other) {\n        return other instanceof CirrusItem;\n    }\n\n    @Override\n    public int hashCode() {\n        final int PRIME = 59;\n        int result = 1;\n        final Object $displayName = this.displayName();\n        result = result * PRIME + ($displayName == null ? 43 : $displayName.hashCode());\n        final Object $titleEffect = this.titleEffect();\n        result = result * PRIME + ($titleEffect == null ? 43 : $titleEffect.hashCode());\n        final Object $lore = this.lore();\n        result = result * PRIME + ($lore == null ? 43 : $lore.hashCode());\n        final Object $loreSupplier = this.loreSupplier();\n        result = result * PRIME + ($loreSupplier == null ? 43 : $loreSupplier.hashCode());\n        final Object $itemType = this.itemType();\n        result = result * PRIME + ($itemType == null ? 43 : $itemType.hashCode());\n        result = result * PRIME + this.amount();\n        result = result * PRIME + this.durability();\n        final Object $actionHandler = this.actionHandler();\n        result = result * PRIME + ($actionHandler == null ? 43 : $actionHandler.hashCode());\n        final Object $actionArguments = this.actionArguments();\n        result = result * PRIME + ($actionArguments == null ? 43 : $actionArguments.hashCode());\n        result = result * PRIME + Arrays.hashCode(this.slots());\n        final Object $nbt = this.nbt();\n        result = result * PRIME + ($nbt == null ? 43 : $nbt.hashCode());\n        return result;\n    }\n\n    @Override\n    public String toString() {\n        return \"CirrusItem(displayName=\" + this.displayName() + \", titleEffect=\" + this.titleEffect() + \", lore=\" + this.lore() + \", loreSupplier=\" + this.loreSupplier() + \", itemType=\" + this.itemType() + \", amount=\" + this.amount() + \", durability=\" + this.durability() + \", actionHandler=\" + this.actionHandler() + \", actionArguments=\" + this.actionArguments() + \", slots=\" + Arrays.toString(this.slots()) + \", nbt=\" + this.nbt() + \")\";\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/item/Items.java",
    "content": "package dev.simplix.cirrus.common.item;\n\nimport dev.simplix.cirrus.common.effects.RGBColorChangeAnimation;\nimport lombok.experimental.UtilityClass;\n\nimport java.awt.*;\n\n@UtilityClass\npublic class Items {\n\n    \n    public CirrusItem rgb(String displayName, Color... colors) {\n        return CirrusItem\n                .animated(RGBColorChangeAnimation.fat(displayName, colors));\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/item/ProtocolizeMenuItemWrapper.java",
    "content": "package dev.simplix.cirrus.common.item;\n\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.protocolize.api.chat.ChatElement;\nimport dev.simplix.protocolize.api.item.ItemStack;\nimport dev.simplix.protocolize.data.ItemType;\nimport lombok.NonNull;\nimport net.md_5.bungee.api.chat.BaseComponent;\nimport net.querz.nbt.tag.CompoundTag;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class ProtocolizeMenuItemWrapper implements MenuItemWrapper {\n\n    private final ItemStack itemStack;\n\n    public ProtocolizeMenuItemWrapper(ItemStack itemStack) {\n        this.itemStack = itemStack;\n    }\n\n    @Override\n    public String displayName() {\n        return this.itemStack.displayName().asLegacyText();\n    }\n\n    @Override\n    public BaseComponent[] displayNameComponents() {\n        return (BaseComponent[]) this.itemStack.displayName().asComponent();\n    }\n\n    @Override\n    public List<String> lore() {\n        return this.itemStack.lore().stream().map(ChatElement::asLegacyText).collect(Collectors.toList());\n    }\n\n    @Override\n    public List<BaseComponent[]> loreComponents() {\n        return (List<BaseComponent[]>) this.itemStack.lore().stream().map(ChatElement::asComponent).collect(Collectors.toList());\n    }\n\n    @Override\n    public ItemType type() {\n        return this.itemStack.itemType();\n    }\n\n    @Override\n    public CompoundTag nbt() {\n        return this.itemStack.nbtData();\n    }\n\n    @Override\n    public int amount() {\n        return this.itemStack.amount();\n    }\n\n    @Override\n    public short durability() {\n        return this.itemStack.durability();\n    }\n\n    @Override\n    public void type(@NonNull ItemType type) {\n        this.itemStack.itemType(type);\n    }\n\n    @Override\n    public void displayName(@NonNull String displayName) {\n        this.itemStack.displayName(ChatElement.ofLegacyText(displayName));\n    }\n\n    @Override\n    public void displayNameComponents(BaseComponent... baseComponents) {\n        this.itemStack.displayName(ChatElement.of(baseComponents));\n    }\n\n    @Override\n    public void lore(@NonNull List<String> lore) {\n        this.itemStack.lore(lore.stream().map(ChatElement::ofLegacyText).collect(Collectors.toList()));\n    }\n\n    @Override\n    public void loreComponents(@NonNull List<BaseComponent[]> lore) {\n        this.itemStack.lore(lore.stream().map(ChatElement::of).collect(Collectors.toList()));\n    }\n\n    @Override\n    public void nbt(@NonNull CompoundTag compoundTag) {\n        this.itemStack.nbtData(compoundTag);\n    }\n\n    @Override\n    public void amount(int amount) {\n        this.itemStack.amount((byte) amount);\n    }\n\n    @Override\n    public void durability(short durability) {\n        this.itemStack.durability(durability);\n    }\n\n    @Override\n    public <T> T handle() {\n        return (T) this.itemStack;\n    }\n\n    @Override\n    public String toString() {\n        return handle().toString();\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/menu/AbstractConfigurableMenu.java",
    "content": "package dev.simplix.cirrus.common.menu;\n\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.configuration.MenuConfiguration;\nimport dev.simplix.cirrus.common.handler.ActionHandler;\nimport dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;\nimport lombok.Getter;\nimport lombok.NonNull;\nimport lombok.experimental.Accessors;\n\nimport java.util.HashMap;\nimport java.util.Locale;\nimport java.util.Map;\n\n@Getter\n@Accessors(fluent = true)\npublic abstract class AbstractConfigurableMenu<T extends MenuConfiguration> extends AbstractMenu {\n\n    private final T configuration;\n\n    public AbstractConfigurableMenu(\n            @NonNull PlayerWrapper player,\n            @NonNull T configuration,\n            @NonNull Locale locale) {\n        this(player, configuration, locale, new HashMap<>());\n    }\n\n    public AbstractConfigurableMenu(\n            @NonNull PlayerWrapper player,\n            @NonNull T configuration,\n            @NonNull Locale locale,\n            @NonNull Map<String, ActionHandler> actionHandlerMap) {\n        super(player, configuration.type(), locale, actionHandlerMap);\n        title(configuration.title().translated(locale));\n        this.configuration = configuration;\n        applyItems();\n    }\n\n    @Override\n    protected void updateReplacements() {\n        super.updateReplacements();\n        topContainer().itemMap().clear();\n        bottomContainer().itemMap().clear();\n        topContainer().reservedSlots().clear();\n        bottomContainer().reservedSlots().clear();\n        applyItems();\n    }\n\n    private void applyItems() {\n        for (int slot : this.configuration.reservedSlots()) {\n            if (slot > topContainer().capacity() - 1) {\n                bottomContainer().reservedSlots().add(slot);\n            } else {\n                topContainer().reservedSlots().add(slot);\n            }\n        }\n\n        // Set placeholders\n        set(this.configuration.placeholderItem());\n\n        // Set other items\n        for (LocalizedItemStackModel model : this.configuration.items()) {\n            set(model);\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/menu/AbstractMenu.java",
    "content": "package dev.simplix.cirrus.common.menu;\n\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.container.Container;\nimport dev.simplix.cirrus.common.container.impl.ItemContainer;\nimport dev.simplix.cirrus.common.handler.ActionHandler;\nimport dev.simplix.cirrus.common.handler.AutoCancellingActionHandler;\nimport dev.simplix.cirrus.common.i18n.LocalizedItemStackModel;\nimport dev.simplix.cirrus.common.i18n.Localizer;\nimport dev.simplix.cirrus.common.i18n.Replacer;\nimport dev.simplix.cirrus.common.item.CirrusItem;\nimport dev.simplix.protocolize.data.inventory.InventoryType;\nimport lombok.Getter;\nimport lombok.NonNull;\nimport lombok.experimental.Accessors;\nimport lombok.extern.slf4j.Slf4j;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.HashMap;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.function.Supplier;\n\n@Getter\n@Accessors(fluent = true)\n@Slf4j\npublic abstract class AbstractMenu implements Menu {\n\n    private static final AtomicInteger ID_GENERATOR = new AtomicInteger();\n\n    private final Map<String, ActionHandler> actionHandlerMap;\n    private final MenuBuilder menuBuilder = Cirrus.getService(MenuBuilder.class);\n    private final Container topContainer;\n    private final Container bottomContainer;\n    private final InventoryType inventoryType;\n    private final Locale locale;\n    private final PlayerWrapper player;\n    private final int internalId = ID_GENERATOR.incrementAndGet();\n    private Supplier<String[]> replacements;\n    private ActionHandler customActionHandler;\n    private Object nativeInventory;\n    private String title;\n\n    public AbstractMenu(\n            @NonNull PlayerWrapper player,\n            @NonNull InventoryType inventoryType,\n            @NonNull Locale locale) {\n        this(player, inventoryType, locale, new HashMap<>());\n    }\n\n    public AbstractMenu(\n            @NonNull PlayerWrapper player,\n            @NonNull InventoryType inventoryType,\n            @NonNull Locale locale,\n            @NonNull Map<String, ActionHandler> actionHandlerMap) {\n        this.inventoryType = inventoryType;\n        this.locale = locale;\n        this.player = player;\n        this.replacements = () -> new String[]{\"viewer\", player.name()};\n        this.topContainer = new ItemContainer(0, inventoryType.getTypicalSize(player.protocolVersion()));\n        this.bottomContainer = new ItemContainer(\n                inventoryType.getTypicalSize(player.protocolVersion()),\n                4 * 9);\n        this.actionHandlerMap = actionHandlerMap;\n    }\n\n    @Override\n    public void registerActionHandler(@NonNull String name, @NonNull AutoCancellingActionHandler actionHandler) {\n        this.actionHandlerMap.put(name, actionHandler);\n    }\n\n    @Override\n    public void registerActionHandler(@NonNull String name, @NonNull ActionHandler actionHandler) {\n        this.actionHandlerMap.put(name, actionHandler);\n    }\n\n    @Override\n    @Nullable\n    public ActionHandler actionHandler(@NonNull String name) {\n        return this.actionHandlerMap.get(name);\n    }\n\n    @Override\n    public void customActionHandler(@NonNull ActionHandler actionHandler) {\n        this.customActionHandler = actionHandler;\n    }\n\n    @Override\n    public void title(@NonNull String title) {\n        this.title = title;\n    }\n\n    @Override\n    public String title() {\n        return Replacer.of(this.title).replaceAll((Object[]) replacements().get()).replacedMessageJoined();\n    }\n\n    @Override\n    public void replacements(@NonNull Supplier<String[]> replacements) {\n        this.replacements = replacements;\n        updateReplacements();\n    }\n\n    protected void updateReplacements() {\n    }\n\n    protected void nativeInventory(@NonNull Object nativeInventory) {\n        this.nativeInventory = nativeInventory;\n    }\n\n    @Override\n    public void build() {\n        if (menuBuilder() == null) {\n            return;\n        }\n        nativeInventory(menuBuilder().build(nativeInventory(), this));\n    }\n\n    @Override\n    public void open() {\n        build();\n        menuBuilder().open(this.player, nativeInventory());\n    }\n\n\n    protected int add(@NonNull LocalizedItemStackModel localizedItemStackModel) {\n        return add(localizedItemStackModel.localize(locale(), this.replacements.get()));\n    }\n\n    protected int add(@NonNull CirrusItem menuItem) {\n        int slot = topContainer().nextFreeSlot();\n        this.topContainer.set(slot, menuItem);\n        return slot;\n    }\n\n    protected int add(@NonNull InventoryMenuItemWrapper inventoryMenuItemWrapper) {\n        int slot = topContainer().nextFreeSlot();\n        this.topContainer.set(slot, inventoryMenuItemWrapper);\n        return slot;\n\n    }\n\n    protected void set(@NonNull LocalizedItemStackModel model) {\n        set(Localizer.localize(\n                model,\n                locale(),\n                replacements().get()));\n    }\n\n    protected void set(@NonNull CirrusItem model) {\n        for (int slot : model.slots()) {\n            if (slot > topContainer().capacity() - 1) {\n                bottomContainer().set(slot - bottomContainer().baseSlot(), model);\n            } else {\n                topContainer().set(slot, model);\n            }\n        }\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (o == null) {\n            return false;\n        }\n        if (o instanceof AbstractMenu) {\n            final AbstractMenu abstractMenu = (AbstractMenu) o;\n            return abstractMenu.internalId == this.internalId();\n        }\n\n        if (this == o) {\n            return true;\n        }\n        return o.equals(nativeInventory());\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(\n                this.actionHandlerMap,\n                this.topContainer,\n                this.bottomContainer,\n                this.inventoryType,\n                this.locale,\n                this.player,\n                this.internalId,\n                this.replacements,\n                this.customActionHandler,\n                this.nativeInventory,\n                this.title);\n    }\n\n    @Override\n    public void handleException(\n            @Nullable ActionHandler actionHandler, Throwable throwable) {\n        if (actionHandler == null) {\n            this.player.sendMessage(\n                    \"§cThere was a problem while running your menu. Please take a look at the console.\");\n            log.error(\n                    \"[Cirrus] Exception occurred while running menu \" + getClass().getName(),\n                    throwable);\n        } else {\n            this.player.sendMessage(\n                    \"§cThere was a problem while running your action handler. Please take a look at the console.\");\n            log.error(\"[Cirrus] Exception occurred while running action handler for menu \"\n                    + getClass().getName(), throwable);\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/menu/ErrorProne.java",
    "content": "package dev.simplix.cirrus.common.menu;\n\nimport dev.simplix.cirrus.common.handler.ActionHandler;\nimport dev.simplix.cirrus.common.util.SafeRunnable;\nimport lombok.NonNull;\nimport org.jetbrains.annotations.Nullable;\n\npublic interface ErrorProne {\n\n    default void handleException(@Nullable ActionHandler actionHandler, Throwable throwable) {\n    }\n\n    /**\n     * Executes error prone code that may throw a exception. When an exception is thrown, it will be\n     * delegated to the exception handler.\n     *\n     * @param runnable The runnable to run\n     */\n    default void errorProne(@NonNull SafeRunnable runnable) {\n        try {\n            runnable.run();\n        } catch (Throwable throwable) {\n            handleException(null, throwable);\n        }\n    }\n\n    /**\n     * Executes error prone code that may throw a exception. When an exception is thrown, it will be\n     * delegated to the exception handler.\n     *\n     * @param runnable        The runnable to run\n     * @param finallyRunnable Code that may run finally\n     */\n    default void errorProne(@NonNull SafeRunnable runnable, @NonNull Runnable finallyRunnable) {\n        try {\n            runnable.run();\n        } catch (Throwable throwable) {\n            handleException(null, throwable);\n        } finally {\n            finallyRunnable.run();\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/menu/Menu.java",
    "content": "package dev.simplix.cirrus.common.menu;\n\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.container.Container;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.common.handler.ActionHandler;\nimport dev.simplix.cirrus.common.handler.AutoCancellingActionHandler;\nimport dev.simplix.protocolize.data.inventory.InventoryType;\nimport lombok.NonNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.Locale;\nimport java.util.function.Supplier;\n\npublic interface Menu extends ErrorProne {\n\n    /**\n     * @return The inventory type\n     */\n    InventoryType inventoryType();\n\n    void registerActionHandler(@NonNull String name, @NonNull AutoCancellingActionHandler actionHandler);\n\n    /**\n     * Registers a new action handler\n     *\n     * @param name          the name\n     * @param actionHandler the action handler\n     */\n    void registerActionHandler(@NonNull String name, @NonNull ActionHandler actionHandler);\n\n    /**\n     * ActionHandler which handles clicks in empty space\n     *\n     * @param actionHandler the action handler\n     */\n    void customActionHandler(@NonNull ActionHandler actionHandler);\n\n    /**\n     * This opens the menu for the specified player\n     */\n    void open();\n\n    /**\n     * This builds the menu\n     */\n    void build();\n\n    /**\n     * ActionHandler which handles clicks in empty space\n     *\n     * @return The custom action handler\n     */\n    ActionHandler customActionHandler();\n\n    /**\n     * Returns an action handler by its name\n     *\n     * @param name the name of the desired action handler\n     * @return the action handler or null if not found\n     */\n    @Nullable\n    ActionHandler actionHandler(@NonNull String name);\n\n    /**\n     * Returns the {@link Container} for the upper inventory.\n     *\n     * @return container\n     */\n    Container topContainer();\n\n    /**\n     * Returns the {@link Container} for the lower inventory.\n     *\n     * @return container\n     */\n    Container bottomContainer();\n\n    /**\n     * Returns the title of the menu\n     *\n     * @return title string\n     */\n    String title();\n\n    /**\n     * Sets the title of the menu\n     *\n     * @param title title\n     */\n    void title(@NonNull String title);\n\n    /**\n     * @return The locale the menu is in\n     */\n    Locale locale();\n\n    /**\n     * Returns the owner of this menu. The current viewer.\n     *\n     * @return The player\n     */\n    PlayerWrapper player();\n\n    /**\n     * Returns a {@link Supplier} which returns a string array used for placeholder replacement.\n     *\n     * @return Supplier for string array\n     */\n    Supplier<String[]> replacements();\n\n    /**\n     * Sets a {@link Supplier} which returns a string array used for placeholder replacement.\n     *\n     * @param supplier supplier\n     */\n    void replacements(Supplier<String[]> supplier);\n\n    /**\n     * Called when leaving the current menu.\n     *\n     * @param inventorySwitch true if a new menu was built within the last 55ms\n     */\n    default void handleClose(boolean inventorySwitch) {\n    }\n\n    /**\n     * Converts an object into an ItemStackWrapper.\n     *\n     * @param object the object to convert\n     * @return the wrapper object\n     */\n    default MenuItemWrapper wrapItemStack(@NonNull Object object) {\n        return Converters.convert(object, MenuItemWrapper.class);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/menu/MenuBuilder.java",
    "content": "package dev.simplix.cirrus.common.menu;\n\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport lombok.NonNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.UUID;\n\npublic interface MenuBuilder {\n\n    <T> T build(@Nullable T prebuild, @NonNull Menu menu);\n\n    <T> void open(@NonNull PlayerWrapper playerWrapper, @NonNull T inventoryImpl);\n\n    @Nullable\n    Menu menuByHandle(@Nullable Object handle);\n\n    default Optional<Menu> findMenuByHandle(@Nullable Object handle) {\n        return Optional.ofNullable(menuByHandle(handle));\n    }\n\n    void destroyMenusOfPlayer(@NonNull UUID uniqueId);\n\n    Map.Entry<Menu, Long> lastBuildOfPlayer(@NonNull UUID uniqueId);\n\n    void invalidate(@NonNull Menu menu);\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/menus/AbstractBrowserMenu.java",
    "content": "package dev.simplix.cirrus.common.menus;\n\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;\nimport dev.simplix.cirrus.common.handler.ActionHandler;\nimport dev.simplix.cirrus.common.item.CirrusItem;\nimport dev.simplix.cirrus.common.model.Click;\nimport lombok.NonNull;\n\nimport java.util.*;\nimport java.util.Map.Entry;\n\npublic abstract class AbstractBrowserMenu<T> extends MultiPageMenu {\n    protected Map<Integer, T> slotValueMap = new HashMap<>();\n\n    protected Map<T, CirrusItem> out = new HashMap<>();\n\n    public AbstractBrowserMenu(\n            @NonNull PlayerWrapper player,\n            @NonNull MultiPageMenuConfiguration configuration,\n            @NonNull Locale locale) {\n        this(player, configuration, locale, new HashMap<>());\n    }\n\n    public AbstractBrowserMenu(\n            @NonNull PlayerWrapper player,\n            @NonNull MultiPageMenuConfiguration configuration,\n            @NonNull Locale locale, @NonNull Map<String, ActionHandler> actionHandlerMap) {\n        super(player, configuration, locale, actionHandlerMap);\n\n        registerActionHandler(\"click\", click -> {\n            final T value = this.slotValueMap.get(click.slot());\n            if (value == null) {\n                return;\n            }\n            click(click, value);\n        });\n    }\n\n    protected abstract void click(Click click, T value);\n\n    protected abstract List<T> values();\n\n    protected abstract CirrusItem map(T value);\n\n    protected Map<T, CirrusItem> mappedValues() {\n        if (this.out != null && !this.out.isEmpty()) {\n            return this.out;\n        }\n        this.out = new HashMap<>();\n        for (T value : values()) {\n            this.out.put(value, map(value));\n        }\n\n        return this.out;\n    }\n\n    protected void insert() {\n        for (Entry<T, CirrusItem> entry : mappedValues().entrySet()) {\n            final CirrusItem value = entry.getValue();\n            final Integer slot = add(value, \"click\", new ArrayList<>());\n            this.slotValueMap.put(slot, entry.getKey());\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/menus/MultiPageMenu.java",
    "content": "package dev.simplix.cirrus.common.menus;\n\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.configuration.MenuConfiguration;\nimport dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;\nimport dev.simplix.cirrus.common.container.Container;\nimport dev.simplix.cirrus.common.handler.ActionHandler;\nimport dev.simplix.cirrus.common.item.CirrusItem;\nimport dev.simplix.cirrus.common.menu.AbstractConfigurableMenu;\nimport dev.simplix.cirrus.common.menu.AbstractMenu;\nimport dev.simplix.cirrus.common.menu.Menu;\nimport dev.simplix.cirrus.common.menu.MenuBuilder;\nimport dev.simplix.cirrus.common.model.CallResult;\nimport lombok.Getter;\nimport lombok.NonNull;\nimport lombok.experimental.Accessors;\nimport lombok.extern.slf4j.Slf4j;\n\nimport java.util.*;\nimport java.util.function.Supplier;\n\n@Slf4j\n@Accessors(fluent = true)\npublic class MultiPageMenu extends AbstractMenu {\n\n    private final MenuBuilder menuBuilder = Cirrus.getService(MenuBuilder.class);\n    @Getter\n    private final List<Menu> pages = new LinkedList<>();\n    @Getter\n    private final MultiPageMenuConfiguration configuration;\n    private int currentPage = 1;\n\n    public MultiPageMenu(\n            @NonNull PlayerWrapper player,\n            @NonNull MultiPageMenuConfiguration configuration,\n            @NonNull Locale locale) {\n        this(player, configuration, locale, new HashMap<>());\n    }\n\n    public MultiPageMenu(\n            @NonNull PlayerWrapper player,\n            @NonNull MultiPageMenuConfiguration configuration,\n            @NonNull Locale locale,\n            @NonNull Map<String, ActionHandler> actionHandlerMap) {\n        super(player, configuration.type(), locale, actionHandlerMap);\n        this.configuration = configuration;\n        title(configuration.title().translated(locale));\n        this.pages.add(new PageMenu(player, configuration, locale));\n        registerActionHandlers();\n        configuration.nextPageItem().actionHandler(\"nextPage\");\n        configuration.previousPageItem().actionHandler(\"previousPage\");\n        Arrays\n                .stream(configuration.nextPageItem().slots())\n                .forEach(value -> topContainer().reservedSlots().add(value));\n        Arrays\n                .stream(configuration.previousPageItem().slots())\n                .forEach(value -> topContainer().reservedSlots().add(value));\n        replacements(() -> new String[]{\n                \"viewer\", player.name(),\n                \"page\", Integer.toString(this.currentPage),\n                \"pageCount\", Integer.toString(this.pages.size())});\n    }\n\n    private void registerActionHandlers() {\n        registerActionHandler(\"nextPage\", click -> {\n            if (this.currentPage == this.pages.size()) {\n                return CallResult.DENY_GRABBING;\n            }\n            this.currentPage++;\n            build();\n            return CallResult.DENY_GRABBING;\n        });\n        registerActionHandler(\"previousPage\", click -> {\n            if (this.currentPage == 1) {\n                return CallResult.DENY_GRABBING;\n            }\n            this.currentPage--;\n            build();\n            return CallResult.DENY_GRABBING;\n        });\n    }\n\n    @Override\n    public void build() {\n        currentPage().build();\n    }\n\n    @Override\n    public void open() {\n        currentPage(1);\n        currentPage().open();\n    }\n\n    @Override\n    public MenuBuilder menuBuilder() {\n        return this.menuBuilder;\n    }\n\n    @Override\n    public Container bottomContainer() {\n        return currentPage().bottomContainer();\n    }\n\n    @Override\n    public Container topContainer() {\n        return currentPage().topContainer();\n    }\n\n    public Menu currentPage() {\n        return this.pages.get(this.currentPage - 1);\n    }\n\n    public List<Menu> pages() {\n        return this.pages;\n    }\n\n    public int currentPageNumber() {\n        return this.currentPage;\n    }\n\n    public void currentPage(int page) {\n        this.currentPage = page;\n    }\n\n    public void newPage() {\n        this.pages.add(new PageMenu(player(), configuration(), locale()));\n        this.currentPage++;\n    }\n\n    public int add(@NonNull CirrusItem model, String actionHandler, List<String> arguments) {\n        return add(wrapItemStack(model), actionHandler, arguments);\n    }\n\n    @Override\n    public int add(@NonNull InventoryMenuItemWrapper inventoryItemWrapper) {\n        int slot = currentPage().topContainer().nextFreeSlot();\n        int oldPage = this.currentPage;\n        if (slot == -1) {\n            if (this.pages.size() > this.currentPage) {\n                this.currentPage = this.pages.size();\n                int out = this.add(inventoryItemWrapper);\n                currentPage(oldPage);\n                return out;\n            }\n            newPage();\n            if (currentPage().topContainer().nextFreeSlot() == -1) {\n                log.info(\"[Cirrus] Cannot add item to \"\n                        + MultiPageMenu.this.getClass().getSimpleName()\n                        + \": No space in new page!\");\n                currentPage(oldPage);\n                return -1;\n            }\n            this.add(inventoryItemWrapper);\n        } else {\n            currentPage().topContainer().set(slot, inventoryItemWrapper);\n        }\n        currentPage(oldPage);\n        return slot;\n    }\n\n    public int add(\n            @NonNull MenuItemWrapper menuItemWrapper,\n            @NonNull String actionHandler,\n            @NonNull List<String> actionArgs) {\n        int slot = currentPage().topContainer().nextFreeSlot();\n        int oldPage = this.currentPage;\n        if (slot == -1) {\n            if (this.pages.size() > this.currentPage) {\n                this.currentPage = this.pages.size();\n                int out = this.add(menuItemWrapper, actionHandler, actionArgs);\n                currentPage(oldPage);\n                return out;\n            }\n            newPage();\n            if (currentPage().topContainer().nextFreeSlot() == -1) {\n                log.info(\"[Cirrus] Cannot add item to \"\n                        + MultiPageMenu.this.getClass().getSimpleName()\n                        + \": No space in new page!\");\n                currentPage(oldPage);\n                return -1;\n            }\n            this.add(menuItemWrapper, actionHandler, actionArgs);\n        } else {\n            currentPage().topContainer().add(menuItemWrapper, actionHandler, actionArgs);\n        }\n        currentPage(oldPage);\n        return slot;\n    }\n\n    class PageMenu extends AbstractConfigurableMenu<MenuConfiguration> {\n\n        public PageMenu(\n                @NonNull PlayerWrapper player,\n                @NonNull MenuConfiguration configuration,\n                @NonNull Locale locale) {\n            super(player, configuration, locale);\n        }\n\n        @Override\n        public Supplier<String[]> replacements() {\n            return MultiPageMenu.this.replacements();\n        }\n\n        @Override\n        public String title() {\n            return MultiPageMenu.this.title();\n        }\n\n        @Override\n        public ActionHandler actionHandler(@NonNull String name) {\n            return MultiPageMenu.this.actionHandler(name);\n        }\n\n        @Override\n        protected void nativeInventory(@NonNull Object nativeInventory) {\n            MultiPageMenu.this.nativeInventory(nativeInventory);\n        }\n\n        @Override\n        public MenuBuilder menuBuilder() {\n            return MultiPageMenu.this.menuBuilder();\n        }\n\n        @Override\n        public void build() {\n            if (MultiPageMenu.this.currentPage > 1) {\n                set(MultiPageMenu.this.configuration().previousPageItem());\n            }\n            if (MultiPageMenu.this.pages.size() > MultiPageMenu.this.currentPage) {\n                set(MultiPageMenu.this.configuration().nextPageItem());\n            }\n            if (menuBuilder() == null) {\n                return;\n            }\n            nativeInventory(menuBuilder().build(nativeInventory(), MultiPageMenu.this));\n        }\n\n        @Override\n        public Object nativeInventory() {\n            return MultiPageMenu.this.nativeInventory();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/menus/SimpleMenu.java",
    "content": "package dev.simplix.cirrus.common.menus;\n\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.configuration.MenuConfiguration;\nimport dev.simplix.cirrus.common.handler.ActionHandler;\nimport dev.simplix.cirrus.common.menu.AbstractConfigurableMenu;\nimport lombok.NonNull;\n\nimport java.util.Locale;\nimport java.util.Map;\n\npublic class SimpleMenu extends AbstractConfigurableMenu<MenuConfiguration> {\n    public SimpleMenu(@NonNull PlayerWrapper player,\n                      @NonNull MenuConfiguration configuration,\n                      @NonNull Locale locale) {\n        super(player, configuration, locale);\n    }\n\n    public SimpleMenu(@NonNull PlayerWrapper player,\n                      @NonNull MenuConfiguration configuration,\n                      @NonNull Locale locale,\n                      @NonNull Map<String, ActionHandler> actionHandlerMap) {\n        super(player, configuration, locale, actionHandlerMap);\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/model/CallResult.java",
    "content": "package dev.simplix.cirrus.common.model;\n\npublic enum CallResult {\n\n    DENY_GRABBING, ALLOW_GRABBING\n\n}\n\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/model/Click.java",
    "content": "package dev.simplix.cirrus.common.model;\n\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.menu.Menu;\nimport dev.simplix.protocolize.api.ClickType;\nimport lombok.NonNull;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * A click contains information about a click performed on an {@link InventoryMenuItemWrapper}.\n */\npublic final class Click {\n\n    private final ClickType clickType;\n    private final Menu clickedMenu;\n    private final InventoryMenuItemWrapper clickedItem;\n    private final int slot;\n\n    public Click(\n            @NonNull ClickType clickType,\n            @NonNull Menu clickedMenu,\n            @Nullable InventoryMenuItemWrapper clickedItem,\n            int slot) {\n        this.clickType = clickType;\n        this.clickedMenu = clickedMenu;\n        this.clickedItem = clickedItem;\n        this.slot = slot;\n    }\n\n    public PlayerWrapper player() {\n        return this.clickedMenu.player();\n    }\n\n    public ClickType clickType() {\n        return this.clickType;\n    }\n\n    public Menu clickedMenu() {\n        return this.clickedMenu;\n    }\n    \n    public List<String> arguments() {\n        if (this.clickedItem != null) {\n            return this.clickedItem.actionArguments();\n        }\n        return new ArrayList<>();\n    }\n\n    public <T extends MenuItemWrapper> T clickedItem() {\n        return (T) this.clickedItem;\n    }\n\n    public int slot() {\n        return this.slot;\n    }\n\n}"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/mojangson/MojangsonScope.java",
    "content": "/*\r\n * Copyright (C) 2010 Google Inc.\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage dev.simplix.cirrus.common.mojangson;\r\n\r\n/**\r\n * Lexical scoping elements within a JSON reader or writer.\r\n *\r\n * @author Jesse Wilson\r\n * @since 1.6\r\n */\r\nfinal class MojangsonScope {\r\n\r\n    /**\r\n     * An array with no elements requires no separators or newlines before it is closed.\r\n     */\r\n    static final int EMPTY_ARRAY = 1;\r\n\r\n    /**\r\n     * A array with at least one value requires a comma and newline before the next element.\r\n     */\r\n    static final int NONEMPTY_ARRAY = 2;\r\n\r\n    /**\r\n     * An object with no name/value pairs requires no separators or newlines before it is closed.\r\n     */\r\n    static final int EMPTY_OBJECT = 3;\r\n\r\n    /**\r\n     * An object whose most recent element is a key. The next element must be a value.\r\n     */\r\n    static final int DANGLING_NAME = 4;\r\n\r\n    /**\r\n     * An object with at least one name/value pair requires a comma and newline before the next\r\n     * element.\r\n     */\r\n    static final int NONEMPTY_OBJECT = 5;\r\n\r\n    /**\r\n     * No object or array has been started.\r\n     */\r\n    static final int EMPTY_DOCUMENT = 6;\r\n\r\n    /**\r\n     * A document with at an array or object.\r\n     */\r\n    static final int NONEMPTY_DOCUMENT = 7;\r\n\r\n    /**\r\n     * A document that's been closed and cannot be accessed.\r\n     */\r\n    static final int CLOSED = 8;\r\n}\r\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/mojangson/MojangsonWriter.java",
    "content": "package dev.simplix.cirrus.common.mojangson;\n\nimport com.google.gson.stream.JsonWriter;\n\nimport java.io.IOException;\nimport java.io.Writer;\nimport java.util.Arrays;\n\n/**\n * A modified version of {@link JsonWriter} only using quotes when it is necessary. MojangsonWriter\n * is lenient by default.\n */\npublic class MojangsonWriter extends JsonWriter {\n\n    /*\n     * From RFC 7159, \"All Unicode characters may be placed within the\n     * quotation marks except for the characters that must be escaped:\n     * quotation mark, reverse solidus, and the control characters\n     * (U+0000 through U+001F).\"\n     *\n     * We also escape '\\u2028' and '\\u2029', which JavaScript interprets as\n     * newline characters. This prevents eval() from failing with a syntax\n     * error. http://code.google.com/p/google-gson/issues/detail?id=341\n     */\n    private static final String[] REPLACEMENT_CHARS;\n    private static final String[] HTML_SAFE_REPLACEMENT_CHARS;\n\n    static {\n        REPLACEMENT_CHARS = new String[128];\n        for (int i = 0; i <= 0x1f; i++) {\n            REPLACEMENT_CHARS[i] = String.format(\"\\\\u%04x\", (int) i);\n        }\n        REPLACEMENT_CHARS['\"'] = \"\\\\\\\"\";\n        REPLACEMENT_CHARS['\\\\'] = \"\\\\\\\\\";\n        REPLACEMENT_CHARS['\\t'] = \"\\\\t\";\n        REPLACEMENT_CHARS['\\b'] = \"\\\\b\";\n        REPLACEMENT_CHARS['\\n'] = \"\\\\n\";\n        REPLACEMENT_CHARS['\\r'] = \"\\\\r\";\n        REPLACEMENT_CHARS['\\f'] = \"\\\\f\";\n        HTML_SAFE_REPLACEMENT_CHARS = REPLACEMENT_CHARS.clone();\n        HTML_SAFE_REPLACEMENT_CHARS['<'] = \"\\\\u003c\";\n        HTML_SAFE_REPLACEMENT_CHARS['>'] = \"\\\\u003e\";\n        HTML_SAFE_REPLACEMENT_CHARS['&'] = \"\\\\u0026\";\n        HTML_SAFE_REPLACEMENT_CHARS['='] = \"\\\\u003d\";\n        HTML_SAFE_REPLACEMENT_CHARS['\\''] = \"\\\\u0027\";\n    }\n\n    /**\n     * The output data, containing at most one top-level array or object.\n     */\n    private final Writer out;\n\n    private int[] stack = new int[32];\n    private int stackSize = 0;\n    /**\n     * A string containing a full set of spaces for a single level of indentation, or null for no\n     * pretty printing.\n     */\n    private String indent;\n    /**\n     * The name/value separator; either \":\" or \": \".\n     */\n    private String separator = \":\";\n    private boolean lenient;\n    private boolean htmlSafe;\n    private String deferredName;\n    private boolean serializeNulls = true;\n\n    {\n        push(MojangsonScope.EMPTY_DOCUMENT);\n    }\n\n    /**\n     * Creates a new instance that writes a MOJANGSON-encoded stream to {@code out}. For best\n     * performance, ensure {@link Writer} is buffered; wrapping in {@link java.io.BufferedWriter\n     * BufferedWriter} if necessary.\n     */\n    public MojangsonWriter(Writer out) {\n        super(out);\n        if (out == null) {\n            throw new NullPointerException(\"out == null\");\n        }\n        this.out = out;\n        setLenient(true);\n    }\n\n    /**\n     * Begins encoding a new array. Each call to this method must be paired with a call to {@link\n     * #endArray}.\n     *\n     * @return this writer.\n     */\n    public MojangsonWriter beginArray() throws IOException {\n        writeDeferredName();\n        return open(MojangsonScope.EMPTY_ARRAY, '[');\n    }\n\n    /**\n     * Ends encoding the current array.\n     *\n     * @return this writer.\n     */\n    public MojangsonWriter endArray() throws IOException {\n        return close(MojangsonScope.EMPTY_ARRAY, MojangsonScope.NONEMPTY_ARRAY, ']');\n    }\n\n    /**\n     * Begins encoding a new object. Each call to this method must be paired with a call to {@link\n     * #endObject}.\n     *\n     * @return this writer.\n     */\n    public MojangsonWriter beginObject() throws IOException {\n        writeDeferredName();\n        return open(MojangsonScope.EMPTY_OBJECT, '{');\n    }\n\n    /**\n     * Ends encoding the current object.\n     *\n     * @return this writer.\n     */\n    public MojangsonWriter endObject() throws IOException {\n        return close(MojangsonScope.EMPTY_OBJECT, MojangsonScope.NONEMPTY_OBJECT, '}');\n    }\n\n    /**\n     * Enters a new scope by appending any necessary whitespace and the given bracket.\n     */\n    private MojangsonWriter open(int empty, char openBracket) throws IOException {\n        beforeValue();\n        push(empty);\n        out.write(openBracket);\n        return this;\n    }\n\n    /**\n     * Closes the current scope by appending any necessary whitespace and the given bracket.\n     */\n    private MojangsonWriter close(int empty, int nonempty, char closeBracket)\n            throws IOException {\n        int context = peek();\n        if (context != nonempty && context != empty) {\n            throw new IllegalStateException(\"Nesting problem.\");\n        }\n        if (deferredName != null) {\n            throw new IllegalStateException(\"Dangling name: \" + deferredName);\n        }\n\n        stackSize--;\n        if (context == nonempty) {\n            newline();\n        }\n        out.write(closeBracket);\n        return this;\n    }\n\n    private void push(int newTop) {\n        if (stackSize == stack.length) {\n            stack = Arrays.copyOf(stack, stackSize * 2);\n        }\n        stack[stackSize++] = newTop;\n    }\n\n    /**\n     * Returns the value on the top of the stack.\n     */\n    private int peek() {\n        if (stackSize == 0) {\n            throw new IllegalStateException(\"MojangsonWriter is closed.\");\n        }\n        return stack[stackSize - 1];\n    }\n\n    /**\n     * Replace the value on the top of the stack with the given value.\n     */\n    private void replaceTop(int topOfStack) {\n        stack[stackSize - 1] = topOfStack;\n    }\n\n    /**\n     * Encodes the property name.\n     *\n     * @param name the name of the forthcoming value. May not be null.\n     * @return this writer.\n     */\n    public MojangsonWriter name(String name) throws IOException {\n        if (name == null) {\n            throw new NullPointerException(\"name == null\");\n        }\n        if (deferredName != null) {\n            throw new IllegalStateException();\n        }\n        if (stackSize == 0) {\n            throw new IllegalStateException(\"MojangsonWriter is closed.\");\n        }\n        deferredName = name;\n        return this;\n    }\n\n    private void writeDeferredName() throws IOException {\n        if (deferredName != null) {\n            beforeName();\n            string(deferredName);\n            deferredName = null;\n        }\n    }\n\n    /**\n     * Encodes {@code value}.\n     *\n     * @param value the literal string value, or null to encode a null literal.\n     * @return this writer.\n     */\n    public MojangsonWriter value(String value) throws IOException {\n        if (value == null) {\n            return nullValue();\n        }\n        writeDeferredName();\n        beforeValue();\n        string(value);\n        return this;\n    }\n\n    /**\n     * Writes {@code value} directly to the writer without quoting or escaping.\n     *\n     * @param value the literal string value, or null to encode a null literal.\n     * @return this writer.\n     */\n    public MojangsonWriter jsonValue(String value) throws IOException {\n        if (value == null) {\n            return nullValue();\n        }\n        writeDeferredName();\n        beforeValue();\n        out.append(value);\n        return this;\n    }\n\n    /**\n     * Encodes {@code null}.\n     *\n     * @return this writer.\n     */\n    public MojangsonWriter nullValue() throws IOException {\n        if (deferredName != null) {\n            if (serializeNulls) {\n                writeDeferredName();\n            } else {\n                deferredName = null;\n                return this; // skip the name and the value\n            }\n        }\n        beforeValue();\n        out.write(\"null\");\n        return this;\n    }\n\n    /**\n     * Encodes {@code value}.\n     *\n     * @return this writer.\n     */\n    public MojangsonWriter value(boolean value) throws IOException {\n        writeDeferredName();\n        beforeValue();\n        out.write(value ? \"true\" : \"false\");\n        return this;\n    }\n\n    /**\n     * Encodes {@code value}.\n     *\n     * @return this writer.\n     */\n    public MojangsonWriter value(Boolean value) throws IOException {\n        if (value == null) {\n            return nullValue();\n        }\n        writeDeferredName();\n        beforeValue();\n        out.write(value ? \"true\" : \"false\");\n        return this;\n    }\n\n    /**\n     * Encodes {@code value}.\n     *\n     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or {@link\n     *              Double#isInfinite() infinities}.\n     * @return this writer.\n     */\n    public MojangsonWriter value(double value) throws IOException {\n        writeDeferredName();\n        if (!lenient && (Double.isNaN(value) || Double.isInfinite(value))) {\n            throw new IllegalArgumentException(\"Numeric values must be finite, but was \" + value);\n        }\n        beforeValue();\n        out.append(Double.toString(value));\n        return this;\n    }\n\n    /**\n     * Encodes {@code value}.\n     *\n     * @return this writer.\n     */\n    public MojangsonWriter value(long value) throws IOException {\n        writeDeferredName();\n        beforeValue();\n        out.write(Long.toString(value));\n        return this;\n    }\n\n    /**\n     * Encodes {@code value}.\n     *\n     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or {@link\n     *              Double#isInfinite() infinities}.\n     * @return this writer.\n     */\n    public MojangsonWriter value(Number value) throws IOException {\n        if (value == null) {\n            return nullValue();\n        }\n\n        writeDeferredName();\n        String string = value.toString();\n        if (!lenient\n                && (string.equals(\"-Infinity\") || string.equals(\"Infinity\") || string.equals(\"NaN\"))) {\n            throw new IllegalArgumentException(\"Numeric values must be finite, but was \" + value);\n        }\n        beforeValue();\n        out.append(string);\n        return this;\n    }\n\n    /**\n     * Ensures all buffered data is written to the underlying {@link Writer} and flushes that writer.\n     */\n    public void flush() throws IOException {\n        if (stackSize == 0) {\n            throw new IllegalStateException(\"MojangsonWriter is closed.\");\n        }\n        out.flush();\n    }\n\n    /**\n     * Flushes and closes this writer and the underlying {@link Writer}.\n     *\n     * @throws IOException if the JSON document is incomplete.\n     */\n    public void close() throws IOException {\n        out.close();\n\n        int size = stackSize;\n        if (size > 1 || size == 1 && stack[size - 1] != MojangsonScope.NONEMPTY_DOCUMENT) {\n            throw new IOException(\"Incomplete document\");\n        }\n        stackSize = 0;\n    }\n\n    private void newline() throws IOException {\n        if (indent == null) {\n            return;\n        }\n\n        out.write('\\n');\n        for (int i = 1, size = stackSize; i < size; i++) {\n            out.write(indent);\n        }\n    }\n\n    /**\n     * Inserts any necessary separators and whitespace before a name. Also adjusts the stack to expect\n     * the name's value.\n     */\n    private void beforeName() throws IOException {\n        int context = peek();\n        if (context == MojangsonScope.NONEMPTY_OBJECT) { // first in object\n            out.write(',');\n        } else if (context != MojangsonScope.EMPTY_OBJECT) { // not in an object!\n            throw new IllegalStateException(\"Nesting problem.\");\n        }\n        newline();\n        replaceTop(MojangsonScope.DANGLING_NAME);\n    }\n\n    /**\n     * Inserts any necessary separators and whitespace before a literal value, inline array, or inline\n     * object. Also adjusts the stack to expect either a closing bracket or another element.\n     */\n    @SuppressWarnings(\"fallthrough\")\n    private void beforeValue() throws IOException {\n        switch (peek()) {\n            case MojangsonScope.NONEMPTY_DOCUMENT:\n                if (!lenient) {\n                    throw new IllegalStateException(\n                            \"JSON must have only one top-level value.\");\n                }\n                // fall-through\n            case MojangsonScope.EMPTY_DOCUMENT: // first in document\n                replaceTop(MojangsonScope.NONEMPTY_DOCUMENT);\n                break;\n\n            case MojangsonScope.EMPTY_ARRAY: // first in array\n                replaceTop(MojangsonScope.NONEMPTY_ARRAY);\n                newline();\n                break;\n\n            case MojangsonScope.NONEMPTY_ARRAY: // another in array\n                out.append(',');\n                newline();\n                break;\n\n            case MojangsonScope.DANGLING_NAME: // value for name\n                out.append(separator);\n                replaceTop(MojangsonScope.NONEMPTY_OBJECT);\n                break;\n\n            default:\n                throw new IllegalStateException(\"Nesting problem.\");\n        }\n    }\n\n    private void string(String value) throws IOException {\n        boolean quotesNeeded = value.contains(\" \")\n                || value.isEmpty();\n        for (char c : value.toCharArray()) {\n            if (c > 0x7a || (c > 0x39 && c < 0x41) || c < 0x30 || (c > 0x5a && c < 0x61)) {\n                quotesNeeded = true;\n                break;\n            }\n        }\n        if (quotesNeeded) { // Mojangson uses lenient json\n            out.write('\\\"');\n        }\n        int last = 0;\n        int length = value.length();\n        if (last < length) {\n            out.write(value, last, length - last);\n        }\n        if (quotesNeeded) {\n            out.write('\\\"');\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/mojangson/TagDeserializer.java",
    "content": "package dev.simplix.cirrus.common.mojangson;\n\nimport com.google.gson.*;\nimport lombok.NonNull;\nimport lombok.extern.slf4j.Slf4j;\nimport net.querz.nbt.io.SNBTUtil;\nimport net.querz.nbt.tag.Tag;\n\nimport java.io.IOException;\nimport java.io.StringWriter;\nimport java.lang.reflect.Type;\n\n@Slf4j\npublic final class TagDeserializer implements JsonDeserializer<Tag<?>> {\n\n    private static final Gson GSON = new GsonBuilder().create();\n\n    @Override\n    public Tag<?> deserialize(\n            @NonNull JsonElement json,\n            @NonNull Type typeOfT,\n            @NonNull JsonDeserializationContext context)\n            throws JsonParseException {\n        if (!json.isJsonObject()) {\n            throw new IllegalArgumentException(\"Expected json object!\");\n        }\n        StringWriter stringWriter = new StringWriter();\n        try {\n            GSON.toJson(json, new MojangsonWriter(stringWriter));\n            return SNBTUtil.fromSNBT(stringWriter.toString());\n        } catch (IOException e) {\n            log.error(\"Something went wrong while parsing SNBT string: \" + stringWriter.toString());\n            throw new RuntimeException(e);\n        }\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/mojangson/TagSerializer.java",
    "content": "package dev.simplix.cirrus.common.mojangson;\r\n\r\nimport com.google.gson.JsonElement;\r\nimport com.google.gson.JsonParser;\r\nimport com.google.gson.JsonSerializationContext;\r\nimport com.google.gson.JsonSerializer;\r\nimport lombok.NonNull;\r\nimport net.querz.nbt.io.SNBTUtil;\r\nimport net.querz.nbt.tag.Tag;\r\n\r\nimport java.io.IOException;\r\nimport java.lang.reflect.Type;\r\n\r\npublic final class TagSerializer implements JsonSerializer<Tag<?>> {\r\n\r\n    @Override\r\n    public JsonElement serialize(\r\n            @NonNull Tag<?> src,\r\n            @NonNull Type typeOfSrc,\r\n            @NonNull JsonSerializationContext context) {\r\n        try {\r\n            String json = SNBTUtil.toSNBT(src);\r\n            return JsonParser.parseString(json);\r\n        } catch (IOException e) {\r\n            throw new RuntimeException(e);\r\n        }\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/util/ColorUtils.java",
    "content": "package dev.simplix.cirrus.common.util;\n\nimport lombok.experimental.UtilityClass;\n\nimport java.awt.*;\nimport java.util.ArrayList;\nimport java.util.List;\n\n@UtilityClass\npublic class ColorUtils {\n\n    public List<Color> colorsInBetween(final Color first, final Color second, final double step) {\n        final double diffBlue = (second.getBlue() - first.getBlue()) / step;\n        final double diffGreen = (second.getGreen() - first.getGreen()) / step;\n        final double diffRed = (second.getRed() - first.getRed()) / step;\n        final List<Color> list = new ArrayList<>();\n        for (int i = 1; i <= step; ++i) {\n            list.add(\n                    new Color(\n                            (int) Math.round(first.getRed() + diffRed * i),\n                            (int) Math.round(first.getGreen() + diffGreen * i),\n                            (int) Math.round(first.getBlue() + diffBlue * i)\n                    )\n            );\n        }\n\n        return list;\n    }\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/util/Colors.java",
    "content": "package dev.simplix.cirrus.common.util;\n\nimport lombok.experimental.UtilityClass;\n\nimport java.awt.*;\n\n@UtilityClass\npublic class Colors {\n    public final Color DARK_BLUE = new Color(0x0000AA);\n    public final Color DARK_GREEN = new Color(0x00AA00);\n    public final Color DARK_AQUA = new Color(0x00AAAA);\n    public final Color DARK_RED = new Color(0xAA0000);\n    public final Color DARK_PURPLE = new Color(0xAA00AA);\n    public final Color GOLD = new Color(0xFFAA00);\n    public final Color GRAY = new Color(0xAAAAAA);\n    public final Color DARK_GRAY = new Color(0x555555);\n    public final Color BLUE = new Color(0x5555FF);\n    public final Color GREEN = new Color(0x55FF55);\n    public final Color AQUA = new Color(0x55FFFF);\n    public final Color RED = new Color(0xFF5555);\n    public final Color LIGHT_PURPLE = new Color(0xFF55FF);\n    public final Color YELLOW = new Color(0xFFFF55);\n    public final Color WHITE = new Color(0xFFFFFF);\n}\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/util/InventoryContentMap.java",
    "content": "package dev.simplix.cirrus.common.util;\r\n\r\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\r\nimport lombok.NonNull;\r\nimport org.jetbrains.annotations.NotNull;\r\nimport org.jetbrains.annotations.Nullable;\r\n\r\nimport java.util.Collection;\r\nimport java.util.Map;\r\nimport java.util.Set;\r\nimport java.util.concurrent.ConcurrentHashMap;\r\nimport java.util.concurrent.ConcurrentMap;\r\nimport java.util.function.BiConsumer;\r\nimport java.util.function.BiFunction;\r\nimport java.util.function.Function;\r\n\r\npublic class InventoryContentMap implements ConcurrentMap<Integer, InventoryMenuItemWrapper> {\r\n\r\n    private final Map<Integer, InventoryMenuItemWrapper> value = new ConcurrentHashMap<>();\r\n\r\n    // Delegate methods\r\n\r\n    @Override\r\n    public int size() {\r\n        return this.value.size();\r\n    }\r\n\r\n    @Override\r\n    public boolean isEmpty() {\r\n        return this.value.isEmpty();\r\n    }\r\n\r\n    @Override\r\n    public boolean containsKey(@NonNull Object key) {\r\n        return this.value.containsKey(key);\r\n    }\r\n\r\n    @Override\r\n    public boolean containsValue(@NonNull Object value) {\r\n        return this.value.containsValue(value);\r\n    }\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper get(@NonNull Object key) {\r\n        return this.value.get(key);\r\n    }\r\n\r\n    @Nullable\r\n    @Override\r\n    public InventoryMenuItemWrapper put(@NonNull Integer key, @NonNull InventoryMenuItemWrapper value) {\r\n        return this.value.put(key, value);\r\n    }\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper remove(Object key) {\r\n        return this.value.remove(key);\r\n    }\r\n\r\n    @Override\r\n    public void putAll(@NotNull Map<? extends Integer, ? extends InventoryMenuItemWrapper> m) {\r\n        this.value.putAll(m);\r\n    }\r\n\r\n    @Override\r\n    public void clear() {\r\n        this.value.clear();\r\n    }\r\n\r\n    @NotNull\r\n    @Override\r\n    public Set<Integer> keySet() {\r\n        return this.value.keySet();\r\n    }\r\n\r\n    @NotNull\r\n    @Override\r\n    public Collection<InventoryMenuItemWrapper> values() {\r\n        return this.value.values();\r\n    }\r\n\r\n    @NotNull\r\n    @Override\r\n    public Set<Entry<Integer, InventoryMenuItemWrapper>> entrySet() {\r\n        return this.value.entrySet();\r\n    }\r\n\r\n    @Override\r\n    public boolean equals(Object obj) {\r\n        return this.value.equals(obj);\r\n    }\r\n\r\n    @Override\r\n    public int hashCode() {\r\n        return this.value.hashCode();\r\n    }\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper getOrDefault(Object key, InventoryMenuItemWrapper defaultValue) {\r\n        return this.value.getOrDefault(key, defaultValue);\r\n    }\r\n\r\n    @Override\r\n    public void forEach(BiConsumer<? super Integer, ? super InventoryMenuItemWrapper> action) {\r\n        this.value.forEach(action);\r\n    }\r\n\r\n    @Override\r\n    public void replaceAll(BiFunction<? super Integer, ? super InventoryMenuItemWrapper, ? extends InventoryMenuItemWrapper> function) {\r\n        this.value.replaceAll(function);\r\n    }\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper putIfAbsent(Integer key, InventoryMenuItemWrapper value) {\r\n        return this.value.putIfAbsent(key, value);\r\n    }\r\n\r\n    @Override\r\n    public boolean remove(Object key, Object value) {\r\n        return this.value.remove(key, value);\r\n    }\r\n\r\n    @Override\r\n    public boolean replace(\r\n            Integer key,\r\n            InventoryMenuItemWrapper oldValue,\r\n            InventoryMenuItemWrapper newValue) {\r\n        return this.value.replace(key, oldValue, newValue);\r\n    }\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper replace(Integer key, InventoryMenuItemWrapper value) {\r\n        return this.value.replace(key, value);\r\n    }\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper computeIfAbsent(\r\n            Integer key,\r\n            @NotNull Function<? super Integer, ? extends InventoryMenuItemWrapper> mappingFunction) {\r\n        return this.value.computeIfAbsent(key, mappingFunction);\r\n    }\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper computeIfPresent(\r\n            Integer key,\r\n            @NotNull BiFunction<? super Integer, ? super InventoryMenuItemWrapper, ? extends InventoryMenuItemWrapper> remappingFunction) {\r\n        return this.value.computeIfPresent(key, remappingFunction);\r\n    }\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper compute(\r\n            Integer key,\r\n            @NotNull BiFunction<? super Integer, ? super InventoryMenuItemWrapper, ? extends InventoryMenuItemWrapper> remappingFunction) {\r\n        return this.value.compute(key, remappingFunction);\r\n    }\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper merge(\r\n            Integer key,\r\n            @NotNull InventoryMenuItemWrapper value,\r\n            @NotNull BiFunction<? super InventoryMenuItemWrapper, ? super InventoryMenuItemWrapper, ? extends InventoryMenuItemWrapper> remappingFunction) {\r\n        return this.value.merge(key, value, remappingFunction);\r\n    }\r\n}\r\n"
  },
  {
    "path": "cirrus-common/src/main/java/dev/simplix/cirrus/common/util/SafeRunnable.java",
    "content": "package dev.simplix.cirrus.common.util;\n\npublic interface SafeRunnable {\n\n    void run() throws Throwable;\n\n}\n"
  },
  {
    "path": "cirrus-common/src/main/resources/cirrus/MenuConfiguration.json",
    "content": "{\r\n  \"title\": {\r\n    \"en\": \"§bCirrus Menu\",\r\n    \"de\": \"§bCirrus Menü\"\r\n  },\r\n  \"type\": \"GENERIC_9X4\",\r\n  \"placeholderItem\": {\r\n    \"itemType\": \"GRAY_STAINED_GLASS_PANE\",\r\n    \"displayName\": {\r\n      \"en\": \"§0\",\r\n      \"de\": \"§0\"\r\n    },\r\n    \"lore\": {\r\n      \"en\": [],\r\n      \"de\": []\r\n    },\r\n    \"amount\": 1,\r\n    \"slots\": [\r\n      0,\r\n      1,\r\n      2,\r\n      3,\r\n      4,\r\n      5,\r\n      6,\r\n      7,\r\n      8,\r\n      27,\r\n      28,\r\n      29,\r\n      30,\r\n      31,\r\n      32,\r\n      33,\r\n      34,\r\n      35\r\n    ]\r\n  },\r\n  \"reservedSlots\": [],\r\n  \"items\": [\r\n    {\r\n      \"itemType\": \"PLAYER_HEAD\",\r\n      \"displayName\": {\r\n        \"en\": \"§6Example Item\",\r\n        \"de\": \"§6Beispielitem\"\r\n      },\r\n      \"lore\": {\r\n        \"en\": [\r\n          \"§7Hello §6{viewer}§7,\",\r\n          \"§7this is an example item to show\",\r\n          \"§7how Cirrus menus and items are configured.\"\r\n        ],\r\n        \"de\": [\r\n          \"§7Hallo §6{viewer}§7,\",\r\n          \"§7das ist ein Beispiel, um zu zeigen\",\r\n          \"§7wie man Cirrus Menüs und Items konfiguriert.\"\r\n        ]\r\n      },\r\n      \"amount\": 1,\r\n      \"actionHandler\": \"noAction\",\r\n      \"actionArguments\": [],\r\n      \"slots\": [\r\n        13\r\n      ],\r\n      \"nbt\": {\r\n        \"SkullOwner\": \"Exceptionflug\"\r\n      }\r\n    }\r\n  ]\r\n}"
  },
  {
    "path": "cirrus-common/src/main/resources/cirrus/MultiPageMenuConfiguration.json",
    "content": "{\r\n  \"title\": {\r\n    \"en\": \"§bCirrus Menu {page} / {pageCount}\",\r\n    \"de\": \"§bCirrus Menü {page} / {pageCount}\"\r\n  },\r\n  \"type\": \"GENERIC_9X6\",\r\n  \"placeholderItem\": {\r\n    \"itemType\": \"GRAY_STAINED_GLASS_PANE\",\r\n    \"displayName\": {\r\n      \"en\": \"§0\",\r\n      \"de\": \"§0\"\r\n    },\r\n    \"lore\": {\r\n      \"en\": [],\r\n      \"de\": []\r\n    },\r\n    \"amount\": 1,\r\n    \"slots\": [\r\n      0,\r\n      1,\r\n      2,\r\n      3,\r\n      4,\r\n      5,\r\n      6,\r\n      7,\r\n      8,\r\n      9,\r\n      17,\r\n      18,\r\n      26,\r\n      27,\r\n      35,\r\n      36,\r\n      44,\r\n      45,\r\n      46,\r\n      47,\r\n      48,\r\n      49,\r\n      50,\r\n      51,\r\n      52,\r\n      53\r\n    ]\r\n  },\r\n  \"reservedSlots\": [],\r\n  \"nextPageItem\": {\r\n    \"itemType\": \"LIME_STAINED_GLASS_PANE\",\r\n    \"displayName\": {\r\n      \"en\": \"§aNext page\",\r\n      \"de\": \"§aNächste Seite\"\r\n    },\r\n    \"lore\": {\r\n      \"en\": [],\r\n      \"de\": []\r\n    },\r\n    \"amount\": 1,\r\n    \"slots\": [\r\n      17,\r\n      26,\r\n      35,\r\n      44\r\n    ]\r\n  },\r\n  \"previousPageItem\": {\r\n    \"itemType\": \"LIME_STAINED_GLASS_PANE\",\r\n    \"displayName\": {\r\n      \"en\": \"§cPrevious page\",\r\n      \"de\": \"§cVorherige Seite\"\r\n    },\r\n    \"lore\": {\r\n      \"en\": [],\r\n      \"de\": []\r\n    },\r\n    \"amount\": 1,\r\n    \"slots\": [\r\n      9,\r\n      18,\r\n      27,\r\n      36\r\n    ]\r\n  },\r\n  \"items\": []\r\n}"
  },
  {
    "path": "cirrus-common/src/test/java/dev/simplix/cirrus/common/tests/SnbtGsonTest.java",
    "content": "package dev.simplix.cirrus.common.tests;\r\n\r\nimport com.google.gson.Gson;\r\nimport com.google.gson.GsonBuilder;\r\nimport dev.simplix.cirrus.common.mojangson.TagDeserializer;\r\nimport dev.simplix.cirrus.common.mojangson.TagSerializer;\r\nimport net.querz.nbt.tag.CompoundTag;\r\nimport org.junit.jupiter.api.Assertions;\r\nimport org.junit.jupiter.api.Test;\r\n\r\npublic final class SnbtGsonTest {\r\n\r\n    private final Gson gson = new GsonBuilder()\r\n            .registerTypeAdapter(CompoundTag.class, new TagSerializer())\r\n            .registerTypeAdapter(CompoundTag.class, new TagDeserializer())\r\n            .create();\r\n\r\n//    @Test\r\n    public void test() {\r\n        CompoundTag display = new CompoundTag();\r\n        display.putInt(\"integer\", 134);\r\n        display.putBoolean(\"boolean\", true);\r\n        display.putFloat(\"float\", 24934.3F);\r\n        display.putDouble(\"double\", 9999.21348D);\r\n        display.putShort(\"short\", (short) 12);\r\n        display.putByte(\"byte\", (byte) 3);\r\n        display.putString(\"string\", \"This is a string\");\r\n\r\n        CompoundTag compoundTag = new CompoundTag();\r\n        compoundTag.put(\"display\", display);\r\n\r\n        String serialized = gson.toJson(compoundTag, CompoundTag.class);\r\n        CompoundTag deserialized = gson.fromJson(serialized, CompoundTag.class);\r\n\r\n        Assertions.assertEquals(compoundTag, deserialized);\r\n\r\n        System.out.println(\"Cirrus SNBT over Gson - OK\");\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-common/src/test/java/dev/simplix/cirrus/common/tests/SnbtTest.java",
    "content": "package dev.simplix.cirrus.common.tests;\r\n\r\nimport net.querz.nbt.io.SNBTUtil;\r\nimport net.querz.nbt.tag.CompoundTag;\r\nimport net.querz.nbt.tag.Tag;\r\nimport org.junit.jupiter.api.Assertions;\r\nimport org.junit.jupiter.api.Test;\r\n\r\nimport java.io.IOException;\r\n\r\npublic final class SnbtTest {\r\n\r\n    @Test\r\n    public void test() throws IOException {\r\n        CompoundTag display = new CompoundTag();\r\n        display.putInt(\"integer\", 134);\r\n        display.putBoolean(\"boolean\", true);\r\n        display.putFloat(\"float\", 24934.3F);\r\n        display.putDouble(\"double\", 9999.21348D);\r\n        display.putShort(\"short\", (short) 12);\r\n        display.putByte(\"byte\", (byte) 3);\r\n\r\n        CompoundTag compoundTag = new CompoundTag();\r\n        compoundTag.put(\"display\", display);\r\n\r\n        String mojangson = SNBTUtil.toSNBT(compoundTag);\r\n        Tag<?> after = SNBTUtil.fromSNBT(mojangson);\r\n\r\n        Assertions.assertEquals(compoundTag, after);\r\n        System.out.println(\"Querz SNBT - OK\");\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-spigot/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>dev.simplix.cirrus</groupId>\n        <artifactId>cirrus</artifactId>\n        <version>2.0.0</version>\n    </parent>\n\n    <artifactId>cirrus-spigot</artifactId>\n    <version>${cirrus.version}</version>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.spigotmc</groupId>\n            <artifactId>spigot-api</artifactId>\n            <version>1.19-R0.1-SNAPSHOT</version>\n            <scope>provided</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.spigotmc</groupId>\n            <artifactId>spigot-api</artifactId>\n            <version>1.8.8-R0.1-SNAPSHOT</version>\n            <scope>provided</scope>\n        </dependency>\n        <dependency>\n            <groupId>dev.simplix.cirrus</groupId>\n            <artifactId>cirrus-common</artifactId>\n            <version>${cirrus.version}</version>\n            <scope>compile</scope>\n        </dependency>\n        <dependency>\n            <groupId>dev.simplix.cirrus</groupId>\n            <artifactId>cirrus-spigot-modern</artifactId>\n            <version>${cirrus.version}</version>\n            <scope>compile</scope>\n        </dependency>\n        <dependency>\n            <groupId>dev.simplix</groupId>\n            <artifactId>protocolize-api</artifactId>\n            <version>2.1.0</version>\n            <scope>compile</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n            <version>1.8.0-alpha2</version>\n            <scope>provided</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>${project.name}-${project.version}</finalName>\n        <resources>\n            <resource>\n                <directory>src/main/resources</directory>\n                <filtering>true</filtering>\n            </resource>\n        </resources>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-shade-plugin</artifactId>\n                <version>3.0.0</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                    </execution>\n                </executions>\n                <configuration>\n                    <minimizeJar>false</minimizeJar>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <configuration>\n                    <source>8</source>\n                    <target>8</target>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-source-plugin</artifactId>\n                <version>3.0.1</version>\n                <executions>\n                    <execution>\n                        <id>attach-sources</id>\n                        <phase>deploy</phase>\n                        <goals>\n                            <goal>jar-no-fork</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-javadoc-plugin</artifactId>\n                <version>3.0.1</version>\n                <executions>\n                    <execution>\n                        <configuration>\n                            <doclint>none</doclint>\n                        </configuration>\n                        <id>attach-javadocs</id>\n                        <goals>\n                            <goal>jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n</project>"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/CirrusSpigot.java",
    "content": "package dev.simplix.cirrus.spigot;\n\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.common.effect.MenuAnimator;\nimport dev.simplix.cirrus.common.item.CirrusItem;\nimport dev.simplix.cirrus.common.item.ProtocolizeMenuItemWrapper;\nimport dev.simplix.cirrus.common.menu.MenuBuilder;\nimport dev.simplix.cirrus.spigot.converters.*;\nimport dev.simplix.cirrus.spigot.listener.InventoryListener;\nimport dev.simplix.cirrus.spigot.menubuilder.SpigotMenuBuilder;\nimport dev.simplix.cirrus.spigot.util.BungeeCordComponentConverterProvider;\nimport dev.simplix.cirrus.spigot.util.OtherModuleProvider;\nimport dev.simplix.cirrus.spigot.util.ReflectionClasses;\nimport dev.simplix.protocolize.api.Protocolize;\nimport dev.simplix.protocolize.api.item.ItemStack;\nimport dev.simplix.protocolize.api.providers.ComponentConverterProvider;\nimport dev.simplix.protocolize.api.providers.ModuleProvider;\nimport dev.simplix.protocolize.data.ItemType;\nimport dev.simplix.protocolize.data.inventory.InventoryType;\nimport lombok.extern.slf4j.Slf4j;\nimport net.querz.nbt.tag.CompoundTag;\nimport org.bukkit.Bukkit;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.inventory.ClickType;\nimport org.bukkit.material.MaterialData;\nimport org.bukkit.plugin.java.JavaPlugin;\n\nimport java.util.UUID;\n\n/**\n * Date: 18.09.2021\n *\n * @author Exceptionflug\n */\n@Slf4j\npublic class CirrusSpigot {\n\n    private static JavaPlugin plugin;\n\n    public static void init(JavaPlugin plugin) {\n        if (CirrusSpigot.plugin != null) {\n            return;\n        }\n        CirrusSpigot.plugin = plugin;\n        Cirrus.registerService(MenuBuilder.class, new SpigotMenuBuilder());\n        Bukkit.getPluginManager().registerEvents(new InventoryListener(), plugin);\n        Protocolize.registerService(ComponentConverterProvider.class, new BungeeCordComponentConverterProvider());\n        Protocolize.registerService(ModuleProvider.class, new OtherModuleProvider());\n        registerConverters();\n    }\n\n    private static void registerConverters() {\n        try {\n            // Players\n            Converters.register(\n                    Player.class,\n                    PlayerWrapper.class,\n                    new PlayerConverter());\n            Converters.register(UUID.class, PlayerWrapper.class, o -> Bukkit.getPlayer((UUID) o));\n\n            // Items\n            Converters.register( // Protocolize ----> Bukkit\n                    ItemStack.class,\n                    org.bukkit.inventory.ItemStack.class,\n                    new ProtocolizeItemStackConverter());\n            Converters.register( // Bukkit ----> Protocolize\n                    org.bukkit.inventory.ItemStack.class,\n                    ItemStack.class,\n                    new BukkitItemStackConverter());\n            Converters.register(\n                    ItemStack.class,\n                    MenuItemWrapper.class,\n                    o -> new ProtocolizeMenuItemWrapper(\n                            (dev.simplix.protocolize.api.item.ItemStack) o));\n            Converters.register(ItemType.class, MaterialData.class, new ItemTypeMaterialDataConverter());\n            Converters.register(MaterialData.class, ItemType.class, new MaterialDataItemTypeConverter());\n            Converters.register(\n                    CirrusItem.class,\n                    InventoryMenuItemWrapper.class,\n                    new ItemModelConverter());\n            Converters.register(\n                    InventoryType.class,\n                    org.bukkit.event.inventory.InventoryType.class,\n                    new SpigotInventoryTypeConverter());\n\n            Converters.register(\n                    ClickType.class,\n                    dev.simplix.protocolize.api.ClickType.class,\n                    new SpigotClickTypeConverter());\n\n            // NBT\n            Converters.register( // Querz ----> NMS\n                    CompoundTag.class,\n                    ReflectionClasses.nbtTagCompound(),\n                    new QuerzNbtNmsNbtConverter());\n            Converters.register( // NMS ----> Querz\n                    ReflectionClasses.nbtTagCompound(),\n                    CompoundTag.class,\n                    new NmsNbtQuerzNbtConverter());\n        } catch (Exception exception) {\n            log.error(\"Cannot register cirrus converters\", exception);\n        }\n\n\n        Bukkit.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, () -> {\n            if (!MenuAnimator.isEmpty()) {\n                MenuAnimator.updateAll();\n            }\n\n        }, 2, 2);\n    }\n\n    public static JavaPlugin plugin() {\n        if (plugin == null) {\n            throw new IllegalStateException(\"Cirrus is not initialized. Please call CirrusSpigot#init during onEnable.\");\n        }\n        return plugin;\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/SpigotPlayerWrapper.java",
    "content": "package dev.simplix.cirrus.spigot;\n\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.spigot.util.ProtocolVersionUtil;\nimport dev.simplix.cirrus.spigot.util.ProtocolVersions;\nimport lombok.NonNull;\nimport org.bukkit.entity.Player;\n\nimport java.util.UUID;\n\npublic class SpigotPlayerWrapper implements PlayerWrapper {\n\n    private final Player handle;\n\n    public SpigotPlayerWrapper(@NonNull Player handle) {\n        this.handle = handle;\n    }\n\n    @Override\n    public void sendMessage(@NonNull String msg) {\n        this.handle.sendMessage(msg);\n    }\n\n    @Override\n    public void closeInventory() {\n        this.handle.closeInventory();\n    }\n\n    @Override\n    public boolean hasPermission(@NonNull String permission) {\n        return this.handle.hasPermission(permission);\n    }\n\n    @Override\n    public UUID uniqueId() {\n        return this.handle.getUniqueId();\n    }\n\n    @Override\n    public String name() {\n        return this.handle.getName();\n    }\n\n    @Override\n    public <T> T handle() {\n        return (T) this.handle;\n    }\n\n    @Override\n    public int protocolVersion() {\n        return Math.min(ProtocolVersionUtil.serverProtocolVersion(), ProtocolVersions.MINECRAFT_1_17_1);\n    }\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/BukkitItemStackConverter.java",
    "content": "package dev.simplix.cirrus.spigot.converters;\n\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.spigot.util.ReflectionClasses;\nimport dev.simplix.cirrus.spigot.util.ReflectionUtil;\nimport dev.simplix.protocolize.data.ItemType;\nimport lombok.NonNull;\nimport net.querz.nbt.tag.CompoundTag;\nimport org.bukkit.inventory.ItemStack;\n\npublic class BukkitItemStackConverter implements Converter<ItemStack, dev.simplix.protocolize.api.item.ItemStack> {\n\n    private static Class<?> craftItemStackClass;\n    private static Class<?> itemStackNMSClass;\n\n    static {\n        try {\n            craftItemStackClass = ReflectionUtil.getClass(\"{obc}.inventory.CraftItemStack\");\n            itemStackNMSClass = ReflectionClasses.itemStackClass();\n        } catch (Exception exception) {\n            exception.printStackTrace();\n        }\n    }\n\n    @Override\n    public dev.simplix.protocolize.api.item.ItemStack convert(@NonNull ItemStack src) {\n        try {\n            dev.simplix.protocolize.api.item.ItemStack out = new dev.simplix.protocolize.api.item.ItemStack(\n                    Converters.convert(src.getData(), ItemType.class),\n                    src.getAmount(),\n                    src.getDurability());\n            Object handle = ReflectionUtil.fieldValue(craftItemStackClass, src, \"handle\");\n            out.nbtData(Converters.convert(\n                    itemStackNMSClass.getMethod(\"getTag\").invoke(handle),\n                    CompoundTag.class));\n            return out;\n        } catch (Throwable throwable) {\n            throwable.printStackTrace();\n            return null;\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/ItemModelConverter.java",
    "content": "package dev.simplix.cirrus.spigot.converters;\r\n\r\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\r\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\r\nimport dev.simplix.cirrus.common.converter.Converter;\r\nimport dev.simplix.cirrus.common.converter.Converters;\r\nimport dev.simplix.cirrus.common.item.CirrusItem;\r\nimport dev.simplix.protocolize.api.item.ItemStack;\r\nimport lombok.NonNull;\r\n\r\npublic class ItemModelConverter implements Converter<CirrusItem, InventoryMenuItemWrapper> {\r\n\r\n    @Override\r\n    public InventoryMenuItemWrapper convert(@NonNull CirrusItem model) {\r\n        ItemStack itemStack = new ItemStack(model.itemType(), model.amount(), model.durability());\r\n        itemStack.nbtData(model.nbt());\r\n        itemStack.displayName(model.displayName());\r\n        itemStack.lore(model.lore(), true);\r\n\r\n        return InventoryMenuItemWrapper.builder()\r\n                .handle(Converters.convert(itemStack, MenuItemWrapper.class))\r\n                .actionArguments(model.actionArguments())\r\n                .actionHandler(model.actionHandler())\r\n                .build();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/ItemTypeMaterialDataConverter.java",
    "content": "package dev.simplix.cirrus.spigot.converters;\n\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.spigot.util.ProtocolVersionUtil;\nimport dev.simplix.protocolize.api.Protocolize;\nimport dev.simplix.protocolize.api.mapping.ProtocolIdMapping;\nimport dev.simplix.protocolize.api.providers.MappingProvider;\nimport dev.simplix.protocolize.api.util.ProtocolVersions;\nimport dev.simplix.protocolize.data.ItemType;\nimport lombok.NonNull;\nimport org.bukkit.Material;\nimport org.bukkit.material.MaterialData;\n\npublic class ItemTypeMaterialDataConverter implements Converter<ItemType, MaterialData> {\n\n  private final MappingProvider mappingProvider = Protocolize.mappingProvider();\n\n  @Override\n  public MaterialData convert(@NonNull ItemType src) {\n    ProtocolIdMapping mapping = this.mappingProvider.mapping(src, ProtocolVersionUtil.serverProtocolVersion());\n    if (mapping==null) {\n      return null;\n    }\n    if (ProtocolVersionUtil.serverProtocolVersion() >= ProtocolVersions.MINECRAFT_1_13) {\n      return new MaterialData(Material.valueOf(src.name()));\n    }\n\n    return null;\n  }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/MaterialDataItemTypeConverter.java",
    "content": "package dev.simplix.cirrus.spigot.converters;\n\nimport com.google.common.collect.Multimap;\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.spigot.util.ProtocolVersionUtil;\nimport dev.simplix.protocolize.api.Protocolize;\nimport dev.simplix.protocolize.api.mapping.ProtocolIdMapping;\nimport dev.simplix.protocolize.api.providers.MappingProvider;\nimport dev.simplix.protocolize.api.util.ProtocolVersions;\nimport dev.simplix.protocolize.data.ItemType;\nimport dev.simplix.protocolize.data.mapping.LegacyItemProtocolIdMapping;\nimport lombok.NonNull;\nimport org.bukkit.material.MaterialData;\n\npublic class MaterialDataItemTypeConverter implements Converter<MaterialData, ItemType> {\n\n    private final MappingProvider mappingProvider = Protocolize.mappingProvider();\n\n    @Override\n    public ItemType convert(@NonNull MaterialData src) {\n        // Modern versioning\n        if (ProtocolVersionUtil.serverProtocolVersion() >= ProtocolVersions.MINECRAFT_1_14) {\n            return ItemType.valueOf(src.getItemType().name().replace(\"LEGACY_\", \"\"));\n        }\n\n        // Deprecated Legacy versioning\n        Multimap<ItemType, ProtocolIdMapping> mappings = this.mappingProvider.mappings(ItemType.class, ProtocolVersionUtil.serverProtocolVersion());\n        for (ItemType type : mappings.keySet()) {\n            for (ProtocolIdMapping mapping : mappings.get(type)) {\n                if (mapping instanceof LegacyItemProtocolIdMapping) {\n                    if (mapping.id() == src.getItemTypeId() && ((LegacyItemProtocolIdMapping) mapping).data() == src.getData()) {\n                        return type;\n                    }\n                }\n            }\n        }\n\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/NmsNbtQuerzNbtConverter.java",
    "content": "package dev.simplix.cirrus.spigot.converters;\n\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.spigot.util.ReflectionClasses;\nimport lombok.NonNull;\nimport net.querz.nbt.io.NBTInputStream;\nimport net.querz.nbt.tag.CompoundTag;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.lang.reflect.Method;\n\npublic class NmsNbtQuerzNbtConverter implements Converter<Object, CompoundTag> {\n\n    private static Method nbtCompressedStreamToolAMethod;\n\n    static {\n        try {\n            nbtCompressedStreamToolAMethod = ReflectionClasses.nbtCompressedStreamTools()\n                    .getMethod(\"a\", ReflectionClasses.nbtTagCompound(), OutputStream.class);\n        } catch (final Exception exception) {\n            exception.printStackTrace();\n        }\n    }\n\n    @Override\n    public CompoundTag convert(@NonNull Object src) {\n        byte[] data = null;\n        try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {\n            nbtCompressedStreamToolAMethod.invoke(null, src, byteArrayOutputStream);\n            data = byteArrayOutputStream.toByteArray();\n        } catch (final Exception exception) {\n            exception.printStackTrace();\n        }\n        try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data)) {\n            return (CompoundTag) new NBTInputStream(byteArrayInputStream).readTag(99).getTag();\n        } catch (final IOException ioException) {\n            ioException.printStackTrace();\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/PlayerConverter.java",
    "content": "package dev.simplix.cirrus.spigot.converters;\r\n\r\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\r\nimport dev.simplix.cirrus.common.converter.Converter;\r\nimport dev.simplix.cirrus.spigot.SpigotPlayerWrapper;\r\nimport lombok.NonNull;\r\nimport org.bukkit.entity.Player;\r\nimport org.jetbrains.annotations.NotNull;\r\n\r\npublic final class PlayerConverter implements Converter<Player, PlayerWrapper> {\r\n\r\n    @Override\r\n    public PlayerWrapper convert(@NonNull @NotNull Player proxiedPlayer) {\r\n        return new SpigotPlayerWrapper(proxiedPlayer);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/ProtocolizeItemStackConverter.java",
    "content": "package dev.simplix.cirrus.spigot.converters;\n\n\nimport com.mojang.authlib.GameProfile;\nimport com.mojang.authlib.properties.Property;\nimport dev.simplix.cirrus.common.Utils;\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.spigot.util.ProtocolVersionUtil;\nimport dev.simplix.cirrus.spigot.util.ReflectionClasses;\nimport dev.simplix.cirrus.spigot.util.ReflectionUtil;\nimport dev.simplix.protocolize.api.item.ItemStack;\nimport lombok.NonNull;\nimport net.md_5.bungee.api.chat.BaseComponent;\nimport net.md_5.bungee.api.chat.TextComponent;\nimport net.md_5.bungee.chat.ComponentSerializer;\nimport net.querz.nbt.tag.*;\nimport org.bukkit.Material;\nimport org.bukkit.inventory.ItemFlag;\nimport org.bukkit.inventory.meta.ItemMeta;\nimport org.bukkit.inventory.meta.SkullMeta;\nimport org.bukkit.material.MaterialData;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.List;\nimport java.util.UUID;\nimport java.util.stream.Collectors;\n\nimport static dev.simplix.protocolize.api.util.ProtocolVersions.MINECRAFT_1_13;\nimport static dev.simplix.protocolize.api.util.ProtocolVersions.MINECRAFT_1_14;\n\npublic class ProtocolizeItemStackConverter implements Converter<ItemStack, org.bukkit.inventory.ItemStack> {\n\n    private static Class<?> craftItemStackClass;\n    private static Class<?> nbtTagCompoundClass;\n    private static Class<?> itemStackNMSClass;\n    private static Method nmsCopyMethod;\n    private static Method bukkitCopyMethod;\n    private static Method setTagMethod;\n\n    static {\n        try {\n            craftItemStackClass = ReflectionUtil.getClass(\"{obc}.inventory.CraftItemStack\");\n            nbtTagCompoundClass = ReflectionClasses.nbtTagCompound();\n            itemStackNMSClass = ReflectionClasses.itemStackClass();\n            nmsCopyMethod = craftItemStackClass.getMethod(\n                    \"asNMSCopy\",\n                    org.bukkit.inventory.ItemStack.class);\n            bukkitCopyMethod = craftItemStackClass.getMethod(\"asBukkitCopy\", itemStackNMSClass);\n        } catch (Exception exception) {\n            exception.printStackTrace();\n        }\n    }\n\n    @Override\n    public org.bukkit.inventory.ItemStack convert(@NonNull ItemStack src) {\n        if (src.itemType() == null) {\n            return null;\n        }\n        if (src.itemType() == null) {\n            return new org.bukkit.inventory.ItemStack(Material.AIR);\n        }\n        MaterialData data = Converters.convert(src.itemType(), MaterialData.class);\n        org.bukkit.inventory.ItemStack out;\n        if (ProtocolVersionUtil.serverProtocolVersion() < MINECRAFT_1_13) {\n            out = new org.bukkit.inventory.ItemStack(\n                    data.getItemType(),\n                    src.amount(),\n                    src.durability(),\n                    data.getData());\n        } else {\n            out = new org.bukkit.inventory.ItemStack(\n                    data.getItemType(),\n                    src.amount(),\n                    src.durability());\n        }\n\n        if (src.nbtData() == null) {\n            src.nbtData(new CompoundTag());\n        }\n\n        String textureHashToInsert = null;\n\n        if (src.nbtData() != null) {\n            CompoundTag tag = src.nbtData();\n            if (tag.containsKey(\"SkullOwner\") && tag.get(\"SkullOwner\") instanceof CompoundTag) {\n\n                final CompoundTag skullOwnerTag = tag.getCompoundTag(\"SkullOwner\");\n                final Tag<?> propertiesRaw = skullOwnerTag.get(\"Properties\");\n\n\n                if (propertiesRaw instanceof CompoundTag) {\n                    try {\n                        final ListTag<CompoundTag> textures = (ListTag<CompoundTag>) ((CompoundTag) propertiesRaw)\n                                .getListTag(\"textures\");\n                        textureHashToInsert = textures.get(0).getString(\"Value\");\n                    } catch (final Exception ignored) {\n\n                    }\n                }\n            }\n        }\n\n        writeDataToNbt(src);\n\n        // Finalizing the itemstack by inserting nbt data & hiding attributes\n        try {\n            Object nmsItemStack = nmsCopyMethod.invoke(null, out);\n            if (src.nbtData() != null) {\n                try {\n\n                    Method setTag = method();\n                    ;\n                    final CompoundTag nbtTag = src.nbtData().clone();\n                    if (textureHashToInsert != null) {\n                        nbtTag.remove(\"SkullOwner\");\n                    }\n\n                    setTag.invoke(nmsItemStack, Converters.convert(nbtTag, nbtTagCompoundClass));\n                } catch (Throwable throwable) {\n                    throwable.printStackTrace();\n                }\n            }\n\n            final org.bukkit.inventory.ItemStack itemStackCopy = (org.bukkit.inventory.ItemStack) bukkitCopyMethod\n                    .invoke(null, nmsItemStack);\n\n            mutateMetaDataToHideAttributes(itemStackCopy);\n            if (textureHashToInsert == null) {\n                return itemStackCopy;\n            }\n\n            final SkullMeta meta = (SkullMeta) itemStackCopy.getItemMeta();\n            mutateItemMetaForTextureHash(meta, textureHashToInsert);\n            itemStackCopy.setItemMeta(meta);\n            return itemStackCopy;\n        } catch (final Exception exception) {\n            exception.printStackTrace(); // Setting nbt to nms item is also pain in the ass\n        }\n\n        return out;\n    }\n\n    private Method method() throws NoSuchMethodException {\n        if (setTagMethod != null) {\n            return setTagMethod;\n        }\n        Method setTag;\n        try {\n            setTag = itemStackNMSClass.getMethod(\"setTag\", nbtTagCompoundClass);\n        } catch (NoSuchMethodException e) {\n            setTag = itemStackNMSClass.getDeclaredMethod(\"setTagClone\", nbtTagCompoundClass);\n            setTag.setAccessible(true);\n        }\n        return setTagMethod = setTag;\n    }\n\n    private void mutateMetaDataToHideAttributes(org.bukkit.inventory.ItemStack out) {\n        try {\n            final ItemMeta itemMeta = out.getItemMeta();\n            itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);\n            itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);\n            itemMeta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);\n            itemMeta.addItemFlags(ItemFlag.HIDE_DESTROYS);\n            itemMeta.addItemFlags(ItemFlag.HIDE_PLACED_ON);\n            itemMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);\n\n            out.setItemMeta(itemMeta);\n        } catch (Throwable ignored) {\n        }\n    }\n\n    private GameProfile makeProfile(@NonNull String textureHash) {\n        // random uuid based on the textureHash string\n        UUID id = new UUID(\n                textureHash.substring(textureHash.length() - 20).hashCode(),\n                textureHash.substring(textureHash.length() - 10).hashCode()\n        );\n        GameProfile profile = new GameProfile(id, \"Player\");\n        profile.getProperties().put(\"textures\", new Property(\"textures\", textureHash));\n        return profile;\n    }\n\n    private void mutateItemMetaForTextureHash(SkullMeta meta, String textureHash) {\n        try {\n            Method metaSetProfileMethod = meta\n                    .getClass()\n                    .getDeclaredMethod(\"setProfile\", GameProfile.class);\n            metaSetProfileMethod.setAccessible(true);\n            metaSetProfileMethod.invoke(meta, makeProfile(textureHash));\n        } catch (NoSuchMethodException | IllegalAccessException |\n                 InvocationTargetException reflectiveOperationException) {\n            // if in an older API where there is no setProfile method,\n            // we set the profile field directly.\n            try {\n                Field profileField = meta.getClass().getDeclaredField(\"profile\");\n                profileField.setAccessible(true);\n                profileField.set(meta, makeProfile(textureHash));\n\n            } catch (NoSuchFieldException | IllegalAccessException exception) {\n                exception.printStackTrace();\n            }\n        }\n    }\n\n    private void writeDataToNbt(@NonNull ItemStack stack) {\n        if (stack.displayName() != null) {\n            if (ProtocolVersionUtil.serverProtocolVersion() >= MINECRAFT_1_13) {\n                stack.nbtData().put(\"Damage\", new IntTag(stack.durability()));\n                final BaseComponent[] baseComponents = stack.displayName();\n                Utils.removeItalic(baseComponents);\n                setDisplayNameTag(stack.nbtData(), ComponentSerializer.toString(baseComponents));\n            } else {\n                setDisplayNameTag(stack.nbtData(),\n                        TextComponent.toLegacyText(stack.displayName()));\n            }\n        }\n\n        if (stack.lore() != null) {\n            setLoreTag(stack.nbtData(),\n                    stack.lore(),\n                    ProtocolVersionUtil.serverProtocolVersion());\n        }\n    }\n\n    private void setDisplayNameTag(@NonNull CompoundTag nbtData, @NonNull String name) {\n        if (name == null) {\n            return;\n        }\n        CompoundTag display = (CompoundTag) nbtData.get(\"display\");\n        if (display == null) {\n            display = new CompoundTag();\n        }\n        final StringTag tag = new StringTag(name);\n        display.put(\"Name\", tag);\n        nbtData.put(\"display\", display);\n    }\n\n    private void setLoreTag(\n            @NonNull CompoundTag nbtData,\n            @NonNull List<BaseComponent[]> lore,\n            int protocolVersion) {\n        if (lore == null) {\n            return;\n        }\n        CompoundTag display = (CompoundTag) nbtData.get(\"display\");\n        if (display == null) {\n            display = new CompoundTag();\n        }\n        if (protocolVersion < MINECRAFT_1_14) {\n            final ListTag<StringTag> tag = new ListTag<>(StringTag.class);\n            tag.addAll(lore.stream().map(i -> new StringTag(TextComponent.toLegacyText(i))).collect(\n                    Collectors.toList()));\n            display.put(\"Lore\", tag);\n            nbtData.put(\"display\", display);\n        } else {\n            final ListTag<StringTag> tag = new ListTag<>(StringTag.class);\n            tag.addAll(lore.stream().map(components -> {\n                for (BaseComponent component : components) {\n                    if (!component.isItalic()) {\n                        component.setItalic(false);\n                    }\n                }\n                return new StringTag(ComponentSerializer.toString(components));\n            }).collect(Collectors.toList()));\n            display.put(\"Lore\", tag);\n            nbtData.put(\"display\", display);\n        }\n    }\n\n}"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/QuerzNbtNmsNbtConverter.java",
    "content": "package dev.simplix.cirrus.spigot.converters;\n\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.spigot.util.ReflectionClasses;\nimport lombok.NonNull;\nimport net.querz.nbt.io.NBTOutputStream;\nimport net.querz.nbt.tag.CompoundTag;\nimport org.jetbrains.annotations.NotNull;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.lang.reflect.Method;\nimport java.util.zip.GZIPOutputStream;\n\npublic class QuerzNbtNmsNbtConverter implements Converter<CompoundTag, Object> {\n\n    private static Method nbtCompressedStreamToolAMethod;\n\n    static {\n        try {\n            nbtCompressedStreamToolAMethod = ReflectionClasses\n                    .nbtCompressedStreamTools()\n                    .getMethod(\"a\", InputStream.class);\n        } catch (final Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    @Override\n    public Object convert(@NonNull @NotNull CompoundTag src) {\n        byte[] data = null;\n        try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {\n            GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);\n            new NBTOutputStream(gzipOutputStream).writeTag(src, 99);\n            gzipOutputStream.close();\n            data = byteArrayOutputStream.toByteArray();\n        } catch (IOException ioException) {\n            ioException.printStackTrace();\n        }\n        try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data)) {\n            return nbtCompressedStreamToolAMethod.invoke(null, byteArrayInputStream);\n        } catch (Exception exception) {\n            exception.printStackTrace();\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/SpigotClickTypeConverter.java",
    "content": "package dev.simplix.cirrus.spigot.converters;\n\nimport dev.simplix.cirrus.common.converter.Converter;\nimport lombok.NonNull;\nimport org.bukkit.event.inventory.ClickType;\nimport org.jetbrains.annotations.NotNull;\n\npublic class SpigotClickTypeConverter implements Converter<ClickType, dev.simplix.protocolize.api.ClickType> {\n\n    @Override\n    public dev.simplix.protocolize.api.ClickType convert(@NonNull @NotNull ClickType src) {\n        switch (src) {\n\n            case LEFT:\n                return dev.simplix.protocolize.api.ClickType.LEFT_CLICK;\n\n            case RIGHT:\n                return dev.simplix.protocolize.api.ClickType.RIGHT_CLICK;\n\n            case DROP:\n                return dev.simplix.protocolize.api.ClickType.DROP;\n\n            case MIDDLE:\n                return dev.simplix.protocolize.api.ClickType.CREATIVE_MIDDLE_CLICK;\n\n            case NUMBER_KEY:\n                return dev.simplix.protocolize.api.ClickType.NUMBER_BUTTON_1;\n\n            case SHIFT_LEFT:\n                return dev.simplix.protocolize.api.ClickType.SHIFT_LEFT_CLICK;\n\n            case SHIFT_RIGHT:\n                return dev.simplix.protocolize.api.ClickType.SHIFT_RIGHT_CLICK;\n\n            case CONTROL_DROP:\n                return dev.simplix.protocolize.api.ClickType.DROP_ALL;\n\n            case DOUBLE_CLICK:\n                return dev.simplix.protocolize.api.ClickType.DOUBLE_CLICK;\n\n            case WINDOW_BORDER_LEFT:\n                return dev.simplix.protocolize.api.ClickType.LEFT_CLICK_OUTSIDE_INVENTORY_HOLDING_NOTHING;\n\n            case WINDOW_BORDER_RIGHT:\n                return dev.simplix.protocolize.api.ClickType.RIGHT_CLICK_OUTSIDE_INVENTORY_HOLDING_NOTHING;\n\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/converters/SpigotInventoryTypeConverter.java",
    "content": "package dev.simplix.cirrus.spigot.converters;\r\n\r\nimport dev.simplix.cirrus.common.converter.Converter;\r\nimport dev.simplix.protocolize.data.inventory.InventoryType;\r\nimport lombok.NonNull;\r\n\r\npublic class SpigotInventoryTypeConverter implements Converter<InventoryType, org.bukkit.event.inventory.InventoryType> {\r\n\r\n    @Override\r\n    public org.bukkit.event.inventory.InventoryType convert(@NonNull InventoryType src) {\r\n        switch (src) {\r\n\r\n            case ANVIL:\r\n                return org.bukkit.event.inventory.InventoryType.ANVIL;\r\n\r\n            case BEACON:\r\n                return org.bukkit.event.inventory.InventoryType.BEACON;\r\n\r\n            case BREWING_STAND:\r\n                return org.bukkit.event.inventory.InventoryType.BREWING;\r\n\r\n            case CRAFTING:\r\n                return org.bukkit.event.inventory.InventoryType.WORKBENCH;\r\n\r\n            case GENERIC_3X3:\r\n                return org.bukkit.event.inventory.InventoryType.DISPENSER;\r\n\r\n            case ENCHANTMENT:\r\n                return org.bukkit.event.inventory.InventoryType.ENCHANTING;\r\n\r\n            case FURNACE:\r\n                return org.bukkit.event.inventory.InventoryType.FURNACE;\r\n\r\n            case HOPPER:\r\n                return org.bukkit.event.inventory.InventoryType.HOPPER;\r\n\r\n            case MERCHANT:\r\n                return org.bukkit.event.inventory.InventoryType.MERCHANT;\r\n\r\n        }\r\n        if (src.name().startsWith(\"GENERIC\")) {\r\n            return org.bukkit.event.inventory.InventoryType.CHEST;\r\n        }\r\n        return null;\r\n    }\r\n}\r\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/listener/InventoryListener.java",
    "content": "package dev.simplix.cirrus.spigot.listener;\n\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.container.Container;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.common.handler.ActionHandler;\nimport dev.simplix.cirrus.common.menu.AbstractMenu;\nimport dev.simplix.cirrus.common.menu.Menu;\nimport dev.simplix.cirrus.common.menu.MenuBuilder;\nimport dev.simplix.cirrus.common.model.CallResult;\nimport dev.simplix.cirrus.common.model.Click;\nimport lombok.extern.slf4j.Slf4j;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.EventHandler;\nimport org.bukkit.event.Listener;\nimport org.bukkit.event.inventory.ClickType;\nimport org.bukkit.event.inventory.InventoryClickEvent;\nimport org.bukkit.event.inventory.InventoryCloseEvent;\nimport org.bukkit.event.inventory.InventoryDragEvent;\nimport org.bukkit.event.player.PlayerQuitEvent;\nimport org.bukkit.inventory.InventoryView;\n\nimport java.util.Map;\n\n@Slf4j\npublic class InventoryListener implements Listener {\n\n    private final MenuBuilder menuBuilder = Cirrus.getService(MenuBuilder.class);\n\n    @EventHandler\n    public void onDrag(InventoryDragEvent event) {\n        InventoryView inventoryView = event.getWhoClicked().getOpenInventory();\n        if (event.getInventory() == null) {\n            return;\n        }\n\n        Menu menu = this.menuBuilder.menuByHandle(inventoryView);\n        if (menu == null) {\n            return;\n        }\n\n        event.setCancelled(true);\n    }\n\n    @EventHandler\n    public void onClick(InventoryClickEvent event) {\n        InventoryView inventoryView = event.getWhoClicked().getOpenInventory();\n        if (event.getClickedInventory() == null) {\n            return;\n        }\n//    Bukkit.broadcastMessage(\"Clicked inventoryView\");\n        Menu menu = this.menuBuilder.menuByHandle(inventoryView);\n        if (menu == null) {\n            return;\n        }\n//    Bukkit.broadcastMessage(\"Clicked menu: \"\n//                            + menu.getClass().getSimpleName()\n//                            + \" @ slot \"\n//                            + event.getSlot());\n        Container container;\n        if (event.getRawSlot() > menu.topContainer().capacity() - 1) {\n            container = menu.bottomContainer();\n//      Bukkit.broadcastMessage(\"Clicked bottom container\");\n        } else {\n            container = menu.topContainer();\n//      Bukkit.broadcastMessage(\"Clicked top container\");\n        }\n        InventoryMenuItemWrapper item = container.get(event.getRawSlot());\n        ClickType type = event.getClick();\n        if (item == null) {\n//      Bukkit.broadcastMessage(\"Clicked nothing\");\n            if (menu.customActionHandler() != null) {\n                try {\n                    CallResult callResult = menu\n                            .customActionHandler()\n                            .handle(new Click(Converters.convert(\n                                    type,\n                                    dev.simplix.protocolize.api.ClickType.class),\n                                    menu, null, event.getSlot()));\n                    event.setCancelled(callResult == null || callResult == CallResult.DENY_GRABBING);\n                } catch (Exception ex) {\n                    event.setCancelled(true);\n                    menu.handleException(null, ex);\n                }\n            }\n            return;\n        }\n//    Bukkit.broadcastMessage(\"Clicked \" + item.displayName());\n        ActionHandler actionHandler = menu.actionHandler(item.actionHandler());\n        if (actionHandler == null) {\n            event.setCancelled(true);\n            return;\n        }\n        try {\n            final CallResult callResult = actionHandler.handle(new Click(\n                    Converters.convert(type, dev.simplix.protocolize.api.ClickType.class),\n                    menu,\n                    item,\n                    event.getSlot()));\n            event.setCancelled(callResult == null || callResult == CallResult.DENY_GRABBING);\n        } catch (final Exception ex) {\n            event.setCancelled(true);\n            menu.handleException(actionHandler, ex);\n        }\n    }\n\n    @EventHandler\n    public void onQuit(PlayerQuitEvent event) {\n        this.menuBuilder.destroyMenusOfPlayer(event.getPlayer().getUniqueId());\n    }\n\n    @EventHandler\n    public void onClose(InventoryCloseEvent inventoryCloseEvent) {\n        InventoryView inventoryView = inventoryCloseEvent.getPlayer().getOpenInventory();\n        if (inventoryView == null) {\n            return;\n        }\n        Menu menu = this.menuBuilder.menuByHandle(inventoryView);\n        if (menu == null) {\n            return;\n        }\n        ((Player) inventoryCloseEvent.getPlayer()).updateInventory();\n        Map.Entry<Menu, Long> lastBuild = this.menuBuilder.lastBuildOfPlayer(inventoryCloseEvent.getPlayer().getUniqueId());\n        if (lastBuild == null) {\n            log.warn(\"[Cirrus] Exiting from unbuilt menu? Class = \"\n                    + menu.getClass().getName()\n                    + \", Player = \"\n                    + inventoryCloseEvent.getPlayer().getName());\n            menu.handleClose(false);\n            this.menuBuilder.invalidate(menu);\n            return;\n        }\n        if (((AbstractMenu) lastBuild.getKey()).internalId() == ((AbstractMenu) menu).internalId()\n                && (System.currentTimeMillis() - lastBuild.getValue()) <= 55) {\n            return;\n        }\n        menu.handleClose((System.currentTimeMillis() - lastBuild.getValue()) <= 55);\n        this.menuBuilder.invalidate(menu);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/menubuilder/SpigotMenuBuilder.java",
    "content": "package dev.simplix.cirrus.spigot.menubuilder;\n\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.container.Container;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.common.menu.Menu;\nimport dev.simplix.cirrus.common.menu.MenuBuilder;\nimport dev.simplix.cirrus.common.menus.MultiPageMenu;\nimport dev.simplix.cirrus.spigot.util.ProtocolVersionUtil;\nimport dev.simplix.cirrus.spigot.util.ReflectionUtil;\nimport dev.simplix.protocolize.api.util.ProtocolVersions;\nimport lombok.NonNull;\nimport lombok.extern.slf4j.Slf4j;\nimport org.bukkit.Bukkit;\nimport org.bukkit.entity.HumanEntity;\nimport org.bukkit.entity.Player;\nimport org.bukkit.event.inventory.InventoryType;\nimport org.bukkit.inventory.Inventory;\nimport org.bukkit.inventory.InventoryView;\nimport org.bukkit.inventory.ItemStack;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.lang.reflect.Constructor;\nimport java.util.*;\nimport java.util.Map.Entry;\n\n@Slf4j\npublic final class SpigotMenuBuilder implements MenuBuilder {\n\n    private static Constructor<?> modernInventoryViewConstructor;\n\n    static {\n        try {\n            if (ProtocolVersionUtil.serverProtocolVersion() > ProtocolVersions.MINECRAFT_1_13) {\n                Class<?> modernInventoryViewClass = SpigotMenuBuilder.class.getClassLoader()\n                        .loadClass(\"dev.simplix.cirrus.spigot.modern.ModernInventoryView\");\n                modernInventoryViewConstructor =\n                        modernInventoryViewClass.getConstructor(Menu.class, Inventory.class, Inventory.class);\n            }\n        } catch (ReflectiveOperationException exception) {\n            log.error(\"SpigotMenuBuilder won't work\", exception);\n        }\n    }\n\n    private final Map<UUID, Map.Entry<Menu, Long>> buildMap = new LinkedHashMap<>();\n    private final List<Menu> menus = new LinkedList<>();\n\n    @Override\n    public <T> T build(@Nullable T prebuild, @NonNull Menu menu) {\n        boolean reopen = false;\n        boolean register = prebuild == null;\n        if (prebuild instanceof InventoryView) {\n            InventoryView inventoryView = (InventoryView) prebuild;\n            if (!inventoryView.getTitle().equals(menu.title())\n                    || inventoryView.getTopInventory().getSize() != menu.inventoryType()\n                    .getTypicalSize(ProtocolVersionUtil.serverProtocolVersion())\n                    || inventoryView.getTopInventory().getType() != Converters\n                    .convert(menu.inventoryType(), org.bukkit.event.inventory.InventoryType.class)) {\n                prebuild = (T) makeView(menu);\n                reopen = true;\n            }\n        } else {\n            prebuild = (T) makeView(menu);\n        }\n        InventoryView view = (InventoryView) prebuild;\n        buildContainer(view.getTopInventory(), menu.topContainer(), false);\n//    buildContainer(view.getBottomInventory(), menu.bottomContainer(), true);\n        this.buildMap.put(\n                menu.player().uniqueId(),\n                new AbstractMap.SimpleEntry<>(menu, System.currentTimeMillis()));\n        if (register) {\n            this.menus.add(menu);\n        }\n        if (reopen || menu instanceof MultiPageMenu) {\n            open(menu.player(), prebuild);\n        }\n        return prebuild;\n    }\n\n    private void buildContainer(Inventory inventory, Container container, boolean bottom) {\n        for (int i = 0; i < container.capacity(); i++) {\n            InventoryMenuItemWrapper item = container.itemMap().get(i + container.baseSlot());\n            ItemStack currentStack = inventory.getItem(i);\n            if (item == null) {\n                if (currentStack != null) {\n                    if (bottom) {\n                        inventory.setItem(\n                                container.baseSlot() + container.capacity() - 1 - (\n                                        i\n                                                + container.baseSlot()),\n                                null);\n                    } else {\n                        inventory.setItem(i, null);\n                    }\n                }\n            }\n            if (item != null) {\n                ItemStack bukkitItemStack = Converters.convert(item.handle(), ItemStack.class);\n                if (currentStack == null) {\n                    if (item.handle() == null) {\n                        Bukkit.getLogger()\n                                .severe(\"InventoryItem's ItemStackWrapper is null @ slot \" + i);\n                        continue;\n                    }\n                    if (bottom) {\n                        inventory.setItem(\n                                container.baseSlot() + container.capacity() - 1 - (\n                                        i\n                                                + container.baseSlot()),\n                                bukkitItemStack);\n                    } else {\n                        inventory.setItem(i, bukkitItemStack);\n                    }\n                } else {\n                    if (!currentStack.equals(bukkitItemStack)) {\n                        if (bottom) {\n                            inventory.setItem(\n                                    container.baseSlot() + container.capacity() - 1 - (\n                                            i\n                                                    + container.baseSlot()),\n                                    bukkitItemStack);\n                        } else {\n                            inventory.setItem(i, bukkitItemStack);\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private static boolean isChest(dev.simplix.protocolize.data.inventory.InventoryType type) {\n        if (type == dev.simplix.protocolize.data.inventory.InventoryType.GENERIC_3X3) {\n            return false;\n        } else {\n            return type.name().startsWith(\"GENERIC\") || type.name().contains(\"CHEST\");\n        }\n    }\n\n    private InventoryView makeView(Menu menu) {\n        Inventory top;\n        if (isChest(menu.inventoryType())) {\n            top = Bukkit.createInventory(\n                    menu.player().handle(),\n                    menu.inventoryType().getTypicalSize(ProtocolVersionUtil.serverProtocolVersion()),\n                    menu.title());\n        } else {\n            top = Bukkit.createInventory(\n                    menu.player().handle(),\n                    Converters\n                            .convert(menu.inventoryType(), org.bukkit.event.inventory.InventoryType.class),\n                    menu.title());\n        }\n        Inventory bottom;\n        if (menu.bottomContainer().itemMap().isEmpty()) {\n            bottom = ((Player) menu.player().handle()).getInventory();\n        } else {\n            bottom = createPlayerInventory(menu.player().handle());\n        }\n        if (ProtocolVersionUtil.serverProtocolVersion() > ProtocolVersions.MINECRAFT_1_13) {\n            return modernView(menu, top, bottom);\n        } else {\n            return legacyView(menu, top, bottom);\n        }\n    }\n\n    private InventoryView modernView(Menu menu, Inventory top, Inventory bottom) {\n        // We need to construct this class using reflection since referencing this class in code\n        // would cause a VerifyError while loading the class on non-modern spigot versions.\n        try {\n            return (InventoryView) modernInventoryViewConstructor\n                    .newInstance(menu, top, bottom);\n        } catch (Exception e) {\n            log.error(\"Unable to construct ModernInventoryView\", e);\n        }\n        return null;\n    }\n\n    private InventoryView legacyView(Menu menu, Inventory top, Inventory bottom) {\n        return new InventoryView() {\n\n            private final Inventory topInventory = top;\n            private final Inventory bottomInventory = bottom;\n\n            @Override\n            public Inventory getTopInventory() {\n                return this.topInventory;\n            }\n\n            @Override\n            public Inventory getBottomInventory() {\n                return this.bottomInventory;\n            }\n\n            @Override\n            public HumanEntity getPlayer() {\n                return menu.player().handle();\n            }\n\n            @Override\n            public InventoryType getType() {\n                return Converters.convert(\n                        menu.inventoryType(),\n                        org.bukkit.event.inventory.InventoryType.class);\n            }\n        };\n    }\n\n    private Inventory createPlayerInventory(Player player) {\n        try {\n            Class<?> craftPlayerInventoryClass =\n                    ReflectionUtil.getClass(\"{obc}.inventory.CraftInventoryPlayer\");\n            Class<?> nmsPlayerInventoryClass =\n                    ReflectionUtil.getClass(\"{nms}.PlayerInventory\");\n            Class<?> nmsEntityHumanClass =\n                    ReflectionUtil.getClass(\"{nms}.EntityHuman\");\n            Constructor<?> nmsPlayerInventoryConstructor =\n                    nmsPlayerInventoryClass.getConstructor(nmsEntityHumanClass);\n            Object nmsPlayerInventory = nmsPlayerInventoryConstructor.newInstance(\n                    nmsEntityHumanClass.cast(ReflectionUtil.nmsPlayer(player)));\n            Constructor<?> craftPlayerInventoryConstructor =\n                    craftPlayerInventoryClass.getConstructor(nmsPlayerInventoryClass);\n            return (Inventory) craftPlayerInventoryConstructor.newInstance(nmsPlayerInventory);\n        } catch (ReflectiveOperationException exception) {\n            log.error(\"Cannot create player inventory\", exception);\n        }\n        return null;\n    }\n\n    @Override\n    public <T> void open(@NonNull PlayerWrapper playerWrapper, @NonNull T inventoryImpl) {\n        ((Player) playerWrapper.handle()).openInventory((InventoryView) inventoryImpl);\n    }\n\n    @Override\n    public Menu menuByHandle(Object handle) {\n        if (handle == null) {\n            return null;\n        }\n        for (final Menu menu : this.menus) {\n            if (menu.equals(handle)) {\n                return menu;\n            }\n        }\n        return null;\n    }\n\n    @Override\n    public void destroyMenusOfPlayer(@NonNull UUID uniqueId) {\n        this.menus.removeIf(\n                wrapper -> ((Player) wrapper.player().handle()).getUniqueId().equals(uniqueId));\n        this.buildMap.remove(uniqueId);\n    }\n\n    @Override\n    public Entry<Menu, Long> lastBuildOfPlayer(@NonNull UUID uniqueId) {\n        return this.buildMap.get(uniqueId);\n    }\n\n    @Override\n    public void invalidate(@NonNull Menu menu) {\n        this.menus.remove(menu);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/menus/SpigotMenu.java",
    "content": "package dev.simplix.cirrus.spigot.menus;\n\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.menu.Menu;\nimport dev.simplix.cirrus.spigot.util.SpigotItemsUtils;\nimport dev.simplix.protocolize.data.ItemType;\nimport lombok.NonNull;\nimport org.bukkit.Material;\nimport org.bukkit.inventory.ItemStack;\nimport org.bukkit.material.MaterialData;\n\npublic interface SpigotMenu extends Menu {\n\n    default ItemType typeFromMaterial(@NonNull MaterialData material) {\n        return SpigotItemsUtils.typeFromMaterial(material);\n    }\n\n    default ItemType typeFromMaterial(@NonNull Material material) {\n        return SpigotItemsUtils.typeFromMaterial(material);\n    }\n\n    default MenuItemWrapper wrapBukkitItemStack(@NonNull ItemStack itemStack) {\n        return SpigotItemsUtils.wrapBukkitItemStack(itemStack);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/BungeeCordComponentConverterProvider.java",
    "content": "package dev.simplix.cirrus.spigot.util;\n\nimport dev.simplix.protocolize.api.ComponentConverter;\nimport dev.simplix.protocolize.api.providers.ComponentConverterProvider;\nimport net.md_5.bungee.api.chat.BaseComponent;\nimport net.md_5.bungee.api.chat.TextComponent;\nimport net.md_5.bungee.chat.ComponentSerializer;\n\n/**\n * Date: 24.08.2021\n *\n * @author Exceptionflug\n */\npublic final class BungeeCordComponentConverterProvider implements ComponentConverterProvider {\n\n    @Override\n    public ComponentConverter<?> platformConverter() {\n        return BungeeCordComponentConverter.INSTANCE;\n    }\n\n    public static class BungeeCordComponentConverter implements ComponentConverter<BaseComponent[]> {\n\n        static BungeeCordComponentConverter INSTANCE = new BungeeCordComponentConverter();\n\n        private BungeeCordComponentConverter() {\n        }\n\n        @Override\n        public String toLegacyText(BaseComponent[] components) {\n            return new TextComponent(components).toLegacyText();\n        }\n\n        @Override\n        public String toJson(BaseComponent[] components) {\n            return ComponentSerializer.toString(components);\n        }\n\n        @Override\n        public BaseComponent[] fromLegacyText(String legacyText) {\n            return TextComponent.fromLegacyText(\"§r\" + legacyText);\n        }\n\n        @Override\n        public BaseComponent[] fromJson(String json) {\n            return ComponentSerializer.parse(json);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/OtherModuleProvider.java",
    "content": "package dev.simplix.cirrus.spigot.util;\n\nimport dev.simplix.protocolize.api.Platform;\nimport dev.simplix.protocolize.api.Protocolize;\nimport dev.simplix.protocolize.api.module.ProtocolizeModule;\nimport dev.simplix.protocolize.api.providers.ModuleProvider;\nimport lombok.Getter;\nimport lombok.experimental.Accessors;\nimport lombok.extern.slf4j.Slf4j;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\n/**\n * Date: 23.08.2021\n *\n * @author Exceptionflug\n */\n@Slf4j(topic = \"Protocolize\")\n@Getter\n@Accessors(fluent = true)\npublic final class OtherModuleProvider implements ModuleProvider {\n\n    private final List<ProtocolizeModule> modules = new ArrayList<>();\n\n    @Override\n    public void registerModule(ProtocolizeModule module) {\n        if (!supportedPlatform(module.supportedPlatforms())) {\n            log.warn(\"Won't register module \" + module.getClass().getName() + \": Only supports \" + Arrays.toString(module.supportedPlatforms()));\n            return;\n        }\n        modules.add(module);\n        enableModule(module);\n    }\n\n    @Override\n    public boolean moduleInstalled(String s) {\n        return this.modules.stream().map(module -> module.getClass().getSimpleName()).collect(Collectors.toList()).contains(s);\n    }\n\n    @Override\n    public ProtocolizeModule module(String s) {\n        return this.modules.stream().filter(module -> module.getClass().getSimpleName().equalsIgnoreCase(s)).findFirst().orElse(null);\n    }\n\n    private boolean supportedPlatform(Platform[] supportedPlatforms) {\n        for (Platform platform : supportedPlatforms) {\n            if (Protocolize.platform() == platform) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private void enableModule(ProtocolizeModule module) {\n        module.registerMappings(Protocolize.mappingProvider());\n        module.registerPackets(Protocolize.protocolRegistration());\n        log.info(\"Enabled module \" + module.getClass().getName());\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/ProtocolVersionUtil.java",
    "content": "package dev.simplix.cirrus.spigot.util;\n\nimport java.lang.reflect.Field;\n\nimport dev.simplix.protocolize.data.inventory.InventoryType;\nimport lombok.AccessLevel;\nimport lombok.RequiredArgsConstructor;\nimport lombok.extern.slf4j.Slf4j;\n\n@Slf4j\n@RequiredArgsConstructor(access = AccessLevel.PRIVATE)\npublic final class ProtocolVersionUtil {\n\n    private static int protocolVersion;\n\n    public static int serverProtocolVersion() {\n        if (protocolVersion == 0) {\n            protocolVersion = detectVersion();\n        }\n        return protocolVersion;\n    }\n\n    private static int detectVersion() {\n        String majorVersion = ReflectionUtil\n                .serverVersion()\n                .substring(1, ReflectionUtil.serverVersion().indexOf('_', 3));\n        try {\n            Field field = dev.simplix.cirrus.spigot.util.ProtocolVersions.class.getField(\"MINECRAFT_\" + majorVersion);\n            return field.getInt(null);\n        } catch (NoSuchFieldException e) {\n            throw new RuntimeException(\"Cirrus is not compatible with server version \"\n                    + ReflectionUtil.serverVersion());\n        } catch (IllegalAccessException e) {\n            log.error(\"[Cirrus] Unable to detect protocol version\", e);\n            return ProtocolVersions.MINECRAFT_1_8;\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/ProtocolVersions.java",
    "content": "package dev.simplix.cirrus.spigot.util;\n\npublic class ProtocolVersions {\n\n    public final static int MINECRAFT_1_8 = 47;\n    public final static int MINECRAFT_1_9 = 107;\n    public final static int MINECRAFT_1_9_1 = 108;\n    public final static int MINECRAFT_1_9_2 = 109;\n    public final static int MINECRAFT_1_9_3 = 110;\n    public final static int MINECRAFT_1_9_4 = MINECRAFT_1_9_3;\n    public final static int MINECRAFT_1_10 = 210;\n    public final static int MINECRAFT_1_11 = 315;\n    public final static int MINECRAFT_1_11_1 = 316;\n    public final static int MINECRAFT_1_11_2 = MINECRAFT_1_11_1;\n    public final static int MINECRAFT_1_12 = 335;\n    public final static int MINECRAFT_1_12_1 = 338;\n    public final static int MINECRAFT_1_12_2 = 340;\n    public final static int MINECRAFT_1_13 = 393;\n    public final static int MINECRAFT_1_13_1 = 401;\n    public final static int MINECRAFT_1_13_2 = 404;\n    public final static int MINECRAFT_1_14 = 477;\n    public final static int MINECRAFT_1_14_1 = 480;\n    public final static int MINECRAFT_1_14_2 = 485;\n    public final static int MINECRAFT_1_14_3 = 490;\n    public final static int MINECRAFT_1_14_4 = 498;\n    public final static int MINECRAFT_1_15 = 573;\n    public final static int MINECRAFT_1_15_1 = 575;\n    public final static int MINECRAFT_1_15_2 = 578;\n    public final static int MINECRAFT_1_16 = 735;\n    public final static int MINECRAFT_1_16_1 = 736;\n    public final static int MINECRAFT_1_16_2 = 751;\n    public final static int MINECRAFT_1_16_3 = 753;\n    public final static int MINECRAFT_1_16_4 = 754;\n    public final static int MINECRAFT_1_16_5 = MINECRAFT_1_16_4;\n    public final static int MINECRAFT_1_17 = 755;\n    public final static int MINECRAFT_1_17_1 = 756;\n    public final static int MINECRAFT_1_18 = 757;\n\n    public final static int MINECRAFT_LATEST = MINECRAFT_1_18;\n\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/ReflectionClasses.java",
    "content": "package dev.simplix.cirrus.spigot.util;\n\npublic class ReflectionClasses {\n\n    public static Class<?> itemStackClass() throws ClassNotFoundException {\n        if (ReflectionUtil.hasNewPackageStructure()) {\n            return ReflectionUtil\n                    .getClass(\"{nm}.world.item.ItemStack\");\n\n        } else {\n            return ReflectionUtil\n                    .getClass(\"{nms}.ItemStack\");\n        }\n    }\n\n    public static Class<?> nbtCompressedStreamTools() throws ClassNotFoundException {\n\n        if (ReflectionUtil.hasNewPackageStructure()) {\n            return ReflectionUtil\n                    .getClass(\"{nm}.nbt.NBTCompressedStreamTools\");\n\n        } else {\n            return ReflectionUtil\n                    .getClass(\"{nms}.NBTCompressedStreamTools\");\n        }\n    }\n\n    public static Class<?> nbtTagCompound() throws ClassNotFoundException {\n        if (ReflectionUtil.hasNewPackageStructure()) {\n            return ReflectionUtil\n                    .getClass(\"{nm}.nbt.NBTTagCompound\");\n\n        } else {\n            return ReflectionUtil\n                    .getClass(\"{nms}.NBTTagCompound\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/ReflectionUtil.java",
    "content": "package dev.simplix.cirrus.spigot.util;\n\nimport com.mojang.authlib.GameProfile;\nimport lombok.AccessLevel;\nimport lombok.NonNull;\nimport lombok.RequiredArgsConstructor;\nimport lombok.extern.slf4j.Slf4j;\nimport org.bukkit.Bukkit;\nimport org.bukkit.World;\nimport org.bukkit.entity.Player;\nimport org.bukkit.scoreboard.Scoreboard;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.AbstractMap;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n@Slf4j\n@RequiredArgsConstructor(access = AccessLevel.PRIVATE)\npublic final class ReflectionUtil {\n\n    private static final String EXCEPTION_OCCURRED = \"Exception occurred\";\n    private static final String GET_HANDLE = \"getHandle\";\n    private static final String PLAYER_CONNECTION = \"playerConnection\";\n    private static final String SEND_PACKET = \"sendPacket\";\n    private static final String NMS_PACKET = \"{nms}.Packet\";\n\n    private static final Map<Map.Entry<Class<?>, String>, Field> CACHED_FIELDS = new HashMap<>();\n    private static final Map<String, Class<?>> CACHED_CLASSES = new HashMap<>();\n\n    public static boolean hasNewPackageStructure() {\n        return ProtocolVersionUtil.serverProtocolVersion() >= ProtocolVersions.MINECRAFT_1_17;\n    }\n\n    public static Class<?> getClass(String classname) throws ClassNotFoundException {\n        String path = classname\n                .replace(\n                        \"{nm}\",\n                        \"net.minecraft\" + (\n                                hasNewPackageStructure()\n                                        ? \"\"\n                                        : \".\" + serverVersion()))\n                .replace(\n                        \"{nms}\",\n                        \"net.minecraft.server\" + (\n                                hasNewPackageStructure()\n                                        ? \"\"\n                                        : \".\" + serverVersion()))\n                .replace(\"{obc}\", \"org.bukkit.craftbukkit.\" + serverVersion());\n        Class<?> out = CACHED_CLASSES.get(path);\n\n        if (out == null) {\n            out = Class.forName(path);\n            CACHED_CLASSES.put(path, out);\n        }\n        return out;\n    }\n\n    public static String serverVersion() {\n        try {\n            return Bukkit.getServer().getClass().getPackage().getName().split(\"\\\\.\")[3];\n        } catch (Exception exception) {\n            return \"v1_17_1\";\n        }\n    }\n\n    public static GameProfile gameProfile(@NonNull Player player)\n            throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {\n        Object obcPlayer = obcPlayer(player);\n        Class<?> obcPlayerClass = obcPlayer.getClass();\n        return (GameProfile) obcPlayerClass.getMethod(\"getProfile\").invoke(player);\n    }\n\n    public static Object nmsPlayer(@NonNull Player player)\n            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {\n        Method getHandle = player.getClass().getMethod(GET_HANDLE);\n        return getHandle.invoke(player);\n    }\n\n    public static Object obcPlayer(@NonNull Player player)\n            throws ClassNotFoundException {\n        return getClass(\"{obc}.entity.CraftPlayer\").cast(player);\n    }\n\n    public static Object nmsWorld(@NonNull World world)\n            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {\n        Method getHandle = world.getClass().getMethod(GET_HANDLE);\n        return getHandle.invoke(world);\n    }\n\n    public static Object nmsScoreboard(@NonNull Scoreboard scoreboard)\n            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {\n        Method getHandle = scoreboard.getClass().getMethod(GET_HANDLE);\n        return getHandle.invoke(scoreboard);\n    }\n\n    public static Object fieldValue(@NonNull Object instance, @NonNull String fieldName)\n            throws IllegalAccessException {\n        final Map.Entry<Class<?>, String> key = new AbstractMap.SimpleEntry<>(\n                instance.getClass(),\n                fieldName);\n        final Field field = CACHED_FIELDS.computeIfAbsent(key, i -> {\n            try {\n                return instance.getClass().getDeclaredField(fieldName);\n            } catch (final NoSuchFieldException e) {\n                log.error(EXCEPTION_OCCURRED, e);\n            }\n            return null;\n        });\n        if (field == null) {\n            return null;\n        }\n        if (!field.isAccessible()) {\n            field.setAccessible(true);\n        }\n        return field.get(instance);\n    }\n\n    public static <T> T fieldValue(@NonNull Field field, @NonNull Object obj) {\n        try {\n            return (T) field.get(obj);\n        } catch (Exception exception) {\n            log.error(EXCEPTION_OCCURRED, exception);\n            return null;\n        }\n    }\n\n    public static Field field(@NonNull Class<?> clazz, @NonNull String fieldName)\n            throws NoSuchFieldException {\n        Field field = clazz.getDeclaredField(fieldName);\n        field.setAccessible(true);\n        return field;\n    }\n\n    public static void value(Object instance, String field, Object value) {\n        try {\n            Field f = instance.getClass().getDeclaredField(field);\n            f.setAccessible(true);\n            f.set(instance, value);\n        } catch (Exception exception) {\n            log.error(EXCEPTION_OCCURRED, exception);\n        }\n    }\n\n    public static void value(\n            @NonNull Class<?> clazz,\n            @NonNull Object instance,\n            @NonNull String field,\n            @NonNull Object value) {\n        try {\n            Field declaredField = clazz.getDeclaredField(field);\n            declaredField.setAccessible(true);\n            declaredField.set(instance, value);\n        } catch (Exception e) {\n            log.error(EXCEPTION_OCCURRED, e);\n        }\n    }\n\n    public static void valueSubclass(\n            @NonNull Class<?> clazz,\n            @NonNull Object instance,\n            @NonNull String field,\n            @NonNull Object value) {\n        try {\n            Field declaredField = clazz.getDeclaredField(field);\n            declaredField.setAccessible(true);\n            declaredField.set(instance, value);\n        } catch (Exception e) {\n            log.error(EXCEPTION_OCCURRED, e);\n        }\n    }\n\n    public static void sendAllPacket(@NonNull Object packet) throws ReflectiveOperationException {\n        for (Player p : Bukkit.getOnlinePlayers()) {\n            Object nmsPlayer = nmsPlayer(p);\n            Object connection = nmsPlayer.getClass().getField(PLAYER_CONNECTION).get(nmsPlayer);\n            connection\n                    .getClass()\n                    .getMethod(SEND_PACKET, ReflectionUtil.getClass(NMS_PACKET))\n                    .invoke(connection, packet);\n        }\n    }\n\n    public static void sendListPacket(@NonNull List<String> players, @NonNull Object packet) {\n        try {\n            for (String name : players) {\n                Object nmsPlayer = nmsPlayer(Bukkit.getPlayer(name));\n                Object connection = nmsPlayer.getClass().getField(PLAYER_CONNECTION).get(nmsPlayer);\n                connection\n                        .getClass()\n                        .getMethod(SEND_PACKET, ReflectionUtil.getClass(NMS_PACKET))\n                        .invoke(connection, packet);\n            }\n        } catch (Exception exception) {\n            log.error(EXCEPTION_OCCURRED, exception);\n        }\n    }\n\n    public static void sendPlayerPacket(@NonNull Player player, @NonNull Object packet)\n            throws ReflectiveOperationException {\n        Object nmsPlayer = nmsPlayer(player);\n        Object connection = nmsPlayer.getClass().getField(PLAYER_CONNECTION).get(nmsPlayer);\n        connection\n                .getClass()\n                .getMethod(SEND_PACKET, ReflectionUtil.getClass(NMS_PACKET))\n                .invoke(connection, packet);\n    }\n\n    public static void listFields(@NonNull Object object) {\n        log.info(object.getClass().getName() + \" contains \" + object\n                .getClass()\n                .getDeclaredFields().length + \" declared fields.\");\n        log.info(object.getClass().getName() + \" contains \" + object\n                .getClass()\n                .getDeclaredClasses().length + \" declared classes.\");\n        Field[] declaredFields = object.getClass().getDeclaredFields();\n        for (Field field : declaredFields) {\n            field.setAccessible(true);\n            try {\n                log.info(field.getName() + \" -> \" + field.get(object));\n            } catch (IllegalArgumentException | IllegalAccessException exception) {\n                log.error(EXCEPTION_OCCURRED, exception);\n            }\n        }\n    }\n\n    public static Object fieldValue(\n            @NonNull Class<?> superclass,\n            @NonNull Object instance,\n            @NonNull String fieldName)\n            throws IllegalAccessException, NoSuchFieldException {\n        Field field = superclass.getDeclaredField(fieldName);\n        field.setAccessible(true);\n        return field.get(instance);\n    }\n}\n"
  },
  {
    "path": "cirrus-spigot/src/main/java/dev/simplix/cirrus/spigot/util/SpigotItemsUtils.java",
    "content": "package dev.simplix.cirrus.spigot.util;\n\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.common.item.ProtocolizeMenuItemWrapper;\nimport dev.simplix.protocolize.data.ItemType;\nimport lombok.NonNull;\nimport lombok.experimental.UtilityClass;\nimport org.bukkit.Material;\nimport org.bukkit.inventory.ItemStack;\nimport org.bukkit.material.MaterialData;\n\n@UtilityClass\npublic class SpigotItemsUtils {\n\n    public ItemType typeFromMaterial(@NonNull MaterialData material) {\n        return Converters.convert(material, ItemType.class);\n    }\n\n    public ItemType typeFromMaterial(@NonNull Material material) {\n        return ItemType.valueOf(material.name());\n    }\n\n    public MenuItemWrapper wrapBukkitItemStack(@NonNull ItemStack itemStack) {\n        dev.simplix.protocolize.api.item.ItemStack protocolizeStack = Converters.convert(itemStack, dev.simplix.protocolize.api.item.ItemStack.class);\n        return new ProtocolizeMenuItemWrapper(protocolizeStack);\n    }\n}\n"
  },
  {
    "path": "cirrus-spigot-example/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>dev.simplix.cirrus</groupId>\n        <artifactId>cirrus</artifactId>\n        <version>2.0.0</version>\n    </parent>\n\n    <artifactId>cirrus-spigot-example</artifactId>\n    <version>${cirrus.version}</version>\n\n    <dependencies>\n        <dependency>\n            <artifactId>cirrus-common</artifactId>\n            <groupId>dev.simplix.cirrus</groupId>\n            <scope>compile</scope>\n            <version>${cirrus.version}</version>\n        </dependency>\n        <dependency>\n            <artifactId>cirrus-spigot</artifactId>\n            <groupId>dev.simplix.cirrus</groupId>\n            <scope>compile</scope>\n            <version>${cirrus.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.spigotmc</groupId>\n            <artifactId>spigot-api</artifactId>\n            <version>1.19-R0.1-SNAPSHOT</version>\n            <scope>provided</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>${project.name}-${project.version}</finalName>\n        <resources>\n            <resource>\n                <directory>src/main/resources</directory>\n                <filtering>true</filtering>\n            </resource>\n        </resources>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <configuration>\n                    <source>8</source>\n                    <target>8</target>\n                </configuration>\n            </plugin>\n            <plugin>\n                <artifactId>maven-shade-plugin</artifactId>\n                <version>3.2.4</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n</project>"
  },
  {
    "path": "cirrus-spigot-example/src/main/java/dev/simplix/cirrus/spigot/example/CirrusExamplePlugin.java",
    "content": "package dev.simplix.cirrus.spigot.example;\n\nimport dev.simplix.cirrus.spigot.CirrusSpigot;\nimport dev.simplix.cirrus.spigot.example.commands.TestCommandExecutor;\nimport org.bukkit.plugin.java.JavaPlugin;\n\npublic class CirrusExamplePlugin extends JavaPlugin {\n\n    @Override\n    public void onEnable() {\n        CirrusSpigot.init(this);\n        getCommand(\"test\").setExecutor(new TestCommandExecutor());\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot-example/src/main/java/dev/simplix/cirrus/spigot/example/commands/TestCommandExecutor.java",
    "content": "package dev.simplix.cirrus.spigot.example.commands;\n\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.configuration.impl.SimpleMultiPageMenuConfiguration;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.spigot.example.menus.ExampleMultiPageMenu;\nimport org.bukkit.command.Command;\nimport org.bukkit.command.CommandExecutor;\nimport org.bukkit.command.CommandSender;\nimport org.bukkit.entity.Player;\n\npublic class TestCommandExecutor implements CommandExecutor {\n\n    @Override\n    public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {\n        if (sender instanceof Player) {\n            Player player = (Player) sender;\n            final PlayerWrapper wrapper = Converters.getConverter(Player.class, PlayerWrapper.class).convert(player);\n            new ExampleMultiPageMenu(\n                    wrapper,\n                    Cirrus.configurationFactory().loadFile(\n                            \"plugins/Cirrus/example2.json\", SimpleMultiPageMenuConfiguration.class)).open();\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "cirrus-spigot-example/src/main/java/dev/simplix/cirrus/spigot/example/menus/ExampleMenu.java",
    "content": "package dev.simplix.cirrus.spigot.example.menus;\n\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.configuration.MenuConfiguration;\nimport dev.simplix.cirrus.common.effects.RGBColorChangeAnimation;\nimport dev.simplix.cirrus.common.item.CirrusItem;\nimport dev.simplix.cirrus.common.menu.AbstractConfigurableMenu;\nimport dev.simplix.cirrus.common.model.CallResult;\n\nimport java.awt.*;\nimport java.util.Locale;\n\npublic class ExampleMenu extends AbstractConfigurableMenu {\n\n    public ExampleMenu(PlayerWrapper player, MenuConfiguration configuration) {\n        super(player, configuration, Locale.ENGLISH);\n\n        registerActionHandler(\"tnt\", click -> {\n            topContainer().itemMap().remove(click.slot());\n            title(\"Hello, {viewer}\");\n            build();\n            player().sendMessage(\"It simply works :)\");\n            return CallResult.DENY_GRABBING;\n        });\n\n        set(configuration.businessItems().get(\"test\"));\n\n        set(CirrusItem.animated(RGBColorChangeAnimation.fat(\"test\", Color.green, Color.red)));\n\n        set(CirrusItem\n                .animated(RGBColorChangeAnimation.fat(\"test\", Color.green, Color.red))\n                .slot(1, 2, 3)\n                .glow()\n        );\n\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot-example/src/main/java/dev/simplix/cirrus/spigot/example/menus/ExampleMultiPageMenu.java",
    "content": "package dev.simplix.cirrus.spigot.example.menus;\n\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;\nimport dev.simplix.cirrus.common.menus.MultiPageMenu;\nimport dev.simplix.cirrus.common.model.CallResult;\nimport dev.simplix.protocolize.api.Protocolize;\nimport dev.simplix.protocolize.api.item.ItemStack;\nimport dev.simplix.protocolize.api.providers.MappingProvider;\nimport dev.simplix.protocolize.data.ItemType;\n\nimport java.util.Collections;\nimport java.util.Locale;\n\npublic class ExampleMultiPageMenu extends MultiPageMenu {\n\n    private final MappingProvider mappingProvider = Protocolize.mappingProvider();\n\n    public ExampleMultiPageMenu(\n            PlayerWrapper player,\n            MultiPageMenuConfiguration configuration) {\n        super(player, configuration, Locale.ENGLISH);\n        registerMyActionHandlers();\n        addItems();\n    }\n\n    private void registerMyActionHandlers() {\n        registerActionHandler(\"test\", click -> {\n            player().sendMessage(\"This is \" + click.clickedItem().type().name());\n            return CallResult.DENY_GRABBING;\n        });\n    }\n\n    private void addItems() {\n        for (ItemType type : ItemType.values()) {\n            if (this.mappingProvider.mapping(type, player().protocolVersion()) != null) {\n                add(wrapItemStack(new ItemStack(type)), \"test\", Collections.emptyList());\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "cirrus-spigot-example/src/main/resources/plugin.yml",
    "content": "name: CirrusExample\nauthor: Exceptionflug\nversion: 1.0\nmain: dev.simplix.cirrus.spigot.example.CirrusExamplePlugin\napi-version: 1.17\n\ncommands:\n  test:\n    description: Opens the test gui"
  },
  {
    "path": "cirrus-spigot-modern/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>dev.simplix.cirrus</groupId>\n        <artifactId>cirrus</artifactId>\n        <version>2.0.0</version>\n    </parent>\n\n    <artifactId>cirrus-spigot-modern</artifactId>\n    <version>${cirrus.version}</version>\n\n\n    <dependencies>\n        <dependency>\n            <groupId>org.spigotmc</groupId>\n            <artifactId>spigot-api</artifactId>\n            <version>1.19-R0.1-SNAPSHOT</version>\n            <scope>provided</scope>\n        </dependency>\n        <dependency>\n            <groupId>dev.simplix.cirrus</groupId>\n            <artifactId>cirrus-common</artifactId>\n            <version>${cirrus.version}</version>\n            <scope>provided</scope>\n        </dependency>\n    </dependencies>\n\n</project>"
  },
  {
    "path": "cirrus-spigot-modern/src/main/java/dev/simplix/cirrus/spigot/modern/ModernInventoryView.java",
    "content": "package dev.simplix.cirrus.spigot.modern;\n\nimport dev.simplix.cirrus.common.menu.Menu;\nimport lombok.NonNull;\nimport org.bukkit.entity.HumanEntity;\nimport org.bukkit.event.inventory.InventoryType;\nimport org.bukkit.inventory.Inventory;\nimport org.bukkit.inventory.InventoryView;\n\npublic final class ModernInventoryView extends InventoryView {\n\n    private final Menu menu;\n    private final Inventory top;\n    private final Inventory bottom;\n\n    public ModernInventoryView(\n            @NonNull Menu menu,\n            @NonNull Inventory top,\n            @NonNull Inventory bottom) {\n        this.menu = menu;\n        this.top = top;\n        this.bottom = bottom;\n    }\n\n    @Override\n    public Inventory getTopInventory() {\n        return top;\n    }\n\n    @Override\n    public Inventory getBottomInventory() {\n        return bottom;\n    }\n\n    @Override\n    public HumanEntity getPlayer() {\n        return menu.player().handle();\n    }\n\n    @Override\n    public InventoryType getType() {\n        return top.getType();\n    }\n\n    @Override\n    public String getTitle() {\n        return menu.title();\n    }\n\n}\n"
  },
  {
    "path": "cirrus-velocity/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <!--                <configuration>-->\n                <!--                    <source>11</source>-->\n                <!--                    <target>11</target>-->\n                <!--                </configuration>-->\n            </plugin>\n            <plugin>\n                <artifactId>maven-shade-plugin</artifactId>\n                <version>3.2.4</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n\n    <parent>\n        <groupId>dev.simplix.cirrus</groupId>\n        <artifactId>cirrus</artifactId>\n        <version>2.0.0</version>\n    </parent>\n\n    <artifactId>cirrus-velocity</artifactId>\n    <version>${cirrus.version}</version>\n\n    <properties>\n        <velocity.version>3.0.0</velocity.version>\n    </properties>\n\n    <dependencies>\n        <dependency>\n            <artifactId>cirrus-common</artifactId>\n            <groupId>dev.simplix.cirrus</groupId>\n            <scope>compile</scope>\n            <version>${cirrus.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.velocitypowered</groupId>\n            <artifactId>velocity-api</artifactId>\n            <version>${velocity.version}</version>\n            <scope>provided</scope>\n        </dependency>\n    </dependencies>\n\n</project>"
  },
  {
    "path": "cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/CirrusVelocity.java",
    "content": "package dev.simplix.cirrus.velocity;\n\nimport com.velocitypowered.api.proxy.Player;\nimport com.velocitypowered.api.proxy.ProxyServer;\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.common.effect.MenuAnimator;\nimport dev.simplix.cirrus.common.item.CirrusItem;\nimport dev.simplix.cirrus.common.menu.MenuBuilder;\nimport dev.simplix.cirrus.velocity.converters.ItemModelConverter;\nimport dev.simplix.cirrus.velocity.converters.ItemStackConverter;\nimport dev.simplix.cirrus.velocity.converters.PlayerConverter;\nimport dev.simplix.cirrus.velocity.converters.PlayerUniqueIdConverter;\nimport dev.simplix.cirrus.velocity.listener.QuitListener;\nimport dev.simplix.cirrus.velocity.protocolize.ProtocolizeMenuBuilder;\nimport dev.simplix.protocolize.api.item.ItemStack;\n\nimport java.util.UUID;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * Date: 18.09.2021\n *\n * @author Exceptionflug\n */\npublic class CirrusVelocity {\n\n    private static ProxyServer proxyServer;\n\n    public static void init(ProxyServer proxyServer, Object plugin) {\n        if (CirrusVelocity.proxyServer != null) {\n            return;\n        }\n        CirrusVelocity.proxyServer = proxyServer;\n        Cirrus.registerService(MenuBuilder.class, new ProtocolizeMenuBuilder());\n        proxyServer.getEventManager().register(plugin, new QuitListener());\n\n        // Players\n        Converters.register(Player.class, PlayerWrapper.class, new PlayerConverter());\n        Converters.register(UUID.class, PlayerWrapper.class, new PlayerUniqueIdConverter(proxyServer));\n\n        // Items\n        Converters.register(ItemStack.class, MenuItemWrapper.class, new ItemStackConverter());\n        Converters.register(CirrusItem.class, InventoryMenuItemWrapper.class, new ItemModelConverter());\n\n        proxyServer.getScheduler().buildTask(plugin, () -> {\n            if (proxyServer.getPlayerCount() > 0 && !MenuAnimator.isEmpty()) {\n                MenuAnimator.updateAll();\n            }\n        }).repeat(50 * 2, TimeUnit.MILLISECONDS).schedule();\n    }\n\n}\n"
  },
  {
    "path": "cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/VelocityPlayerWrapper.java",
    "content": "package dev.simplix.cirrus.velocity;\n\nimport com.velocitypowered.api.proxy.Player;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.protocolize.api.Protocolize;\nimport dev.simplix.protocolize.api.player.ProtocolizePlayer;\n\nimport java.util.UUID;\n\nimport lombok.NonNull;\nimport net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;\n\npublic class VelocityPlayerWrapper implements PlayerWrapper {\n\n    private final LegacyComponentSerializer legacyComponentSerializer = LegacyComponentSerializer.legacySection();\n    private final ProtocolizePlayer protocolizePlayer;\n    private final Player handle;\n\n    public VelocityPlayerWrapper(@NonNull Player handle) {\n        this.handle = handle;\n        this.protocolizePlayer = Protocolize.playerProvider().player(handle.getUniqueId());\n    }\n\n    @Override\n    public UUID uniqueId() {\n        return this.handle.getUniqueId();\n    }\n\n    @Override\n    public String name() {\n        return this.handle.getUsername();\n    }\n\n    @Override\n    public int protocolVersion() {\n        return this.protocolizePlayer.protocolVersion();\n    }\n\n    @Override\n    public void sendMessage(@NonNull String msg) {\n        this.handle.sendMessage(this.legacyComponentSerializer.deserialize(msg));\n    }\n\n    @Override\n    public void closeInventory() {\n        this.protocolizePlayer.closeInventory();\n    }\n\n    @Override\n    public boolean hasPermission(@NonNull String permission) {\n        return this.handle.hasPermission(permission);\n    }\n\n    @Override\n    public <T> T handle() {\n        return (T) this.handle;\n    }\n\n    public ProtocolizePlayer protocolizePlayer() {\n        return this.protocolizePlayer;\n    }\n}\n"
  },
  {
    "path": "cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/converters/ItemModelConverter.java",
    "content": "package dev.simplix.cirrus.velocity.converters;\n\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.common.item.CirrusItem;\nimport dev.simplix.protocolize.api.chat.ChatElement;\nimport dev.simplix.protocolize.api.item.ItemStack;\nimport org.jetbrains.annotations.NotNull;\nimport java.util.stream.Collectors;\n\npublic class ItemModelConverter implements Converter<CirrusItem, InventoryMenuItemWrapper> {\n\n    @Override\n    public InventoryMenuItemWrapper convert(@NotNull CirrusItem model) {\n        ItemStack itemStack = new ItemStack(model.itemType(), model.amount(), model.durability());\n        itemStack.nbtData(model.nbt());\n        itemStack.displayName(ChatElement.ofLegacyText(model.displayName()));\n        itemStack.lore(model.lore().stream().map(ChatElement::ofLegacyText).collect(Collectors.toList()));\n\n        return InventoryMenuItemWrapper.builder()\n                .handle(Converters.convert(itemStack, MenuItemWrapper.class))\n                .actionArguments(model.actionArguments())\n                .actionHandler(model.actionHandler())\n                .build();\n    }\n\n}\n"
  },
  {
    "path": "cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/converters/ItemStackConverter.java",
    "content": "package dev.simplix.cirrus.velocity.converters;\n\nimport dev.simplix.cirrus.common.business.MenuItemWrapper;\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.common.item.ProtocolizeMenuItemWrapper;\nimport dev.simplix.protocolize.api.item.ItemStack;\nimport lombok.NonNull;\n\npublic class ItemStackConverter implements Converter<ItemStack, MenuItemWrapper> {\n\n    @Override\n    public MenuItemWrapper convert(@NonNull ItemStack itemStack) {\n        return new ProtocolizeMenuItemWrapper(itemStack);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/converters/PlayerConverter.java",
    "content": "package dev.simplix.cirrus.velocity.converters;\n\nimport com.velocitypowered.api.proxy.Player;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.velocity.VelocityPlayerWrapper;\nimport lombok.NonNull;\n\npublic final class PlayerConverter implements Converter<Player, PlayerWrapper> {\n\n    @Override\n    public PlayerWrapper convert(@NonNull Player proxiedPlayer) {\n        return new VelocityPlayerWrapper(proxiedPlayer);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/converters/PlayerUniqueIdConverter.java",
    "content": "package dev.simplix.cirrus.velocity.converters;\n\nimport com.velocitypowered.api.proxy.ProxyServer;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.converter.Converter;\nimport dev.simplix.cirrus.velocity.VelocityPlayerWrapper;\n\nimport java.util.UUID;\n\nimport lombok.NonNull;\n\npublic class PlayerUniqueIdConverter implements Converter<UUID, PlayerWrapper> {\n\n    private final ProxyServer proxyServer;\n\n    public PlayerUniqueIdConverter(ProxyServer proxyServer) {\n        this.proxyServer = proxyServer;\n    }\n\n    @Override\n    public PlayerWrapper convert(@NonNull UUID uuid) {\n        return new VelocityPlayerWrapper(this.proxyServer.getPlayer(uuid)\n                .orElseThrow(() -> new IllegalArgumentException(\"Player \" + uuid + \" is offline\")));\n    }\n\n}\n"
  },
  {
    "path": "cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/listener/QuitListener.java",
    "content": "package dev.simplix.cirrus.velocity.listener;\n\nimport com.velocitypowered.api.event.Subscribe;\nimport com.velocitypowered.api.event.connection.DisconnectEvent;\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.menu.MenuBuilder;\n\n/**\n * Date: 18.09.2021\n *\n * @author Exceptionflug\n */\npublic class QuitListener {\n\n    private final MenuBuilder menuBuilder = Cirrus.getService(MenuBuilder.class);\n\n    @Subscribe\n    public void onQuit(DisconnectEvent event) {\n        this.menuBuilder.destroyMenusOfPlayer(event.getPlayer().getUniqueId());\n    }\n\n}\n"
  },
  {
    "path": "cirrus-velocity/src/main/java/dev/simplix/cirrus/velocity/protocolize/ProtocolizeMenuBuilder.java",
    "content": "package dev.simplix.cirrus.velocity.protocolize;\n\nimport com.google.common.collect.Sets;\nimport com.velocitypowered.api.proxy.Player;\nimport dev.simplix.cirrus.common.business.InventoryMenuItemWrapper;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.container.Container;\nimport dev.simplix.cirrus.common.handler.ActionHandler;\nimport dev.simplix.cirrus.common.i18n.Replacer;\nimport dev.simplix.cirrus.common.menu.AbstractMenu;\nimport dev.simplix.cirrus.common.menu.Menu;\nimport dev.simplix.cirrus.common.menu.MenuBuilder;\nimport dev.simplix.cirrus.common.model.CallResult;\nimport dev.simplix.cirrus.common.model.Click;\nimport dev.simplix.cirrus.velocity.VelocityPlayerWrapper;\nimport dev.simplix.protocolize.api.ClickType;\nimport dev.simplix.protocolize.api.chat.ChatElement;\nimport dev.simplix.protocolize.api.inventory.Inventory;\nimport dev.simplix.protocolize.api.item.BaseItemStack;\nimport dev.simplix.protocolize.api.item.ItemStack;\nimport lombok.NonNull;\nimport lombok.extern.slf4j.Slf4j;\nimport net.kyori.adventure.text.Component;\nimport net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;\nimport org.jetbrains.annotations.Nullable;\n\nimport java.util.*;\nimport java.util.Map.Entry;\n\n@Slf4j\npublic class ProtocolizeMenuBuilder implements MenuBuilder {\n\n    private final Map<UUID, Entry<Menu, Long>> buildMap = new LinkedHashMap<>();\n    private final Set<Menu> menus = Sets.newConcurrentHashSet();\n\n    @Override\n    public <T> T build(@Nullable T prebuild, @NonNull Menu menu) {\n        if (!(menu instanceof AbstractMenu)) {\n            throw new IllegalArgumentException(\"This implementation can only build cirrus menus!\");\n        }\n        final boolean register = prebuild == null;\n        if (prebuild instanceof Inventory) {\n            String title = Replacer.of(menu.title()).replaceAll((Object[]) menu.replacements().get())\n                    .replacedMessageJoined();\n            final Inventory inventory = (Inventory) prebuild;\n            if (!GsonComponentSerializer.gson().serialize((Component) inventory.title().asComponent())\n                    .equals(GsonComponentSerializer.gson().serialize(Component.text(title))) ||\n                    inventory.type().getTypicalSize(menu.player().protocolVersion()) != menu\n                            .topContainer()\n                            .capacity()\n                    || inventory.type() != menu.inventoryType()) {\n                prebuild = (T) makeInv(menu);\n            }\n        } else {\n            prebuild = (T) makeInv(menu);\n        }\n        final Inventory inventory = (Inventory) prebuild;\n        buildContainer(inventory, menu.topContainer());\n        buildContainer(inventory, menu.bottomContainer());\n\n        this.buildMap.put(\n                menu.player().uniqueId(),\n                new AbstractMap.SimpleEntry<>(menu, System.currentTimeMillis()));\n        if (register) {\n            this.menus.add(menu);\n        }\n        open(menu.player(), inventory);\n        return prebuild;\n    }\n\n    private void buildContainer(@NonNull Inventory inventory, @NonNull Container container) {\n        for (int i = container.baseSlot(); i < container.baseSlot() + container.capacity(); i++) {\n            InventoryMenuItemWrapper item = container.itemMap().get(i);\n            BaseItemStack currentStack = inventory.item(i);\n            if (item == null) {\n                if (currentStack != null) {\n                    inventory.item(i, ItemStack.NO_DATA);\n                }\n            }\n            if (item != null) {\n                if (currentStack == null) {\n                    if (item.handle() == null) {\n                        log.error(\"InventoryItem's ItemStackWrapper is null @ slot \" + i);\n                        continue;\n                    }\n                    inventory.item(i, item.handle());\n                } else {\n                    if (!currentStack.equals(item.handle())) {\n                        inventory.item(i, item.handle());\n                    }\n                }\n            }\n        }\n    }\n\n    private Inventory makeInv(@NonNull Menu menu) {\n        Inventory inventory = new Inventory(menu.inventoryType());\n        inventory.title(ChatElement.ofLegacyText(menu.title()));\n\n        inventory.onClose(inventoryClose -> {\n            Entry<Menu, Long> lastBuild = lastBuildOfPlayer(inventoryClose.player().uniqueId());\n            if (((AbstractMenu) lastBuild.getKey()).internalId() == ((AbstractMenu) menu).internalId()\n                    && (System.currentTimeMillis() - lastBuild.getValue()) <= 55) {\n                return;\n            }\n            menu.handleClose((System.currentTimeMillis() - lastBuild.getValue()) <= 55);\n            invalidate(menu);\n        });\n\n        inventory.onClick(inventoryClick -> {\n            if (inventoryClick.clickType() == null) {\n                return;\n            }\n            if (inventoryClick.player() == null) {\n                return;\n            }\n            Inventory i = inventoryClick.inventory();\n            if (i == null) {\n                return;\n            }\n//    ProxyServer.getInstance().broadcast(\"Clicked inventory\");\n//    ProxyServer.getInstance().broadcast(\"Clicked menu: \" + menu.getClass().getSimpleName() + \" @ slot \" + event.getSlot());\n            Container container;\n            if (inventoryClick.slot() > menu.topContainer().capacity() - 1) {\n                container = menu.bottomContainer();\n//      ProxyServer.getInstance().broadcast(\"Clicked bottom container\");\n            } else {\n                container = menu.topContainer();\n//      ProxyServer.getInstance().broadcast(\"Clicked top container\");\n            }\n            InventoryMenuItemWrapper item = container.get(inventoryClick.slot());\n            ClickType type = inventoryClick.clickType();\n            if (item == null) {\n//      ProxyServer.getInstance().broadcast(\"Clicked nothing\");\n                if (menu.customActionHandler() != null) {\n                    try {\n                        CallResult callResult = menu\n                                .customActionHandler()\n                                .handle(new Click(type, menu, null, inventoryClick.slot()));\n                        inventoryClick.cancelled(callResult == null || callResult == CallResult.DENY_GRABBING);\n                    } catch (Exception ex) {\n                        inventoryClick.cancelled(true);\n                        menu.handleException(null, ex);\n                    }\n                }\n                return;\n            }\n//    ProxyServer.getInstance().broadcast(\"Clicked \"+item.displayName());\n            ActionHandler actionHandler = menu.actionHandler(item.actionHandler());\n            if (actionHandler == null) {\n                inventoryClick.cancelled(true);\n                return;\n            }\n            try {\n                final CallResult callResult = actionHandler.handle(new Click(\n                        type,\n                        menu,\n                        item,\n                        inventoryClick.slot()));\n                inventoryClick.cancelled(callResult == null || callResult == CallResult.DENY_GRABBING);\n            } catch (final Exception ex) {\n                inventoryClick.cancelled(true);\n                menu.handleException(actionHandler, ex);\n            }\n        });\n\n        return inventory;\n    }\n\n    @Override\n    public <T> void open(\n            PlayerWrapper playerWrapper, T inventoryImpl) {\n        if (playerWrapper instanceof VelocityPlayerWrapper) {\n            ((VelocityPlayerWrapper) playerWrapper).protocolizePlayer().openInventory((Inventory) inventoryImpl);\n        }\n    }\n\n    @Override\n    @Nullable\n    public Menu menuByHandle(Object handle) {\n        if (handle == null) {\n            return null;\n        }\n        for (final Menu menu : this.menus) {\n            if (menu.equals(handle)) {\n                return menu;\n            }\n        }\n        return null;\n    }\n\n    @Override\n    public void destroyMenusOfPlayer(@NonNull UUID uniqueId) {\n        this.menus.removeIf(\n                wrapper -> ((Player) wrapper.player().handle()).getUniqueId().equals(uniqueId));\n        this.buildMap.remove(uniqueId);\n    }\n\n    @Override\n    public Entry<Menu, Long> lastBuildOfPlayer(@NonNull UUID uniqueId) {\n        return this.buildMap.get(uniqueId);\n    }\n\n    @Override\n    public void invalidate(@NonNull Menu menu) {\n        this.menus.remove(menu);\n    }\n\n}\n"
  },
  {
    "path": "cirrus-velocity-example/.gitignore",
    "content": "# User-specific stuff\n.idea/\n\n*.iml\n*.ipr\n*.iws\n\n# IntelliJ\nout/\n\n# Compiled class file\n*.class\n\n# Log file\n*.log\n\n# BlueJ files\n*.ctxt\n\n# Package Files #\n*.jar\n*.war\n*.nar\n*.ear\n*.zip\n*.tar.gz\n*.rar\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\n\n*~\n\n# temporary files which can be created if a process still has a handle open of a deleted file\n.fuse_hidden*\n\n# KDE directory preferences\n.directory\n\n# Linux trash folder which might appear on any partition or disk\n.Trash-*\n\n# .nfs files are created when an open file is removed but is still being accessed\n.nfs*\n\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n# Windows thumbnail cache files\nThumbs.db\nThumbs.db:encryptable\nehthumbs.db\nehthumbs_vista.db\n\n# Dump file\n*.stackdump\n\n# Folder config file\n[Dd]esktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msix\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\ntarget/\n\npom.xml.tag\npom.xml.releaseBackup\npom.xml.versionsBackup\npom.xml.next\n\nrelease.properties\ndependency-reduced-pom.xml\nbuildNumber.properties\n.mvn/timing.properties\n.mvn/wrapper/maven-wrapper.jar\n.flattened-pom.xml\n\n# Common working directory\nrun/\n"
  },
  {
    "path": "cirrus-velocity-example/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <parent>\n        <groupId>dev.simplix.cirrus</groupId>\n        <artifactId>cirrus</artifactId>\n        <version>2.0.0</version>\n    </parent>\n\n    <artifactId>cirrus-velocity-example</artifactId>\n    <version>${cirrus.version}</version>\n\n    <dependencies>\n        <dependency>\n            <artifactId>cirrus-common</artifactId>\n            <groupId>dev.simplix.cirrus</groupId>\n            <scope>compile</scope>\n            <version>${cirrus.version}</version>\n        </dependency>\n        <dependency>\n            <artifactId>cirrus-velocity</artifactId>\n            <groupId>dev.simplix.cirrus</groupId>\n            <scope>compile</scope>\n            <version>${cirrus.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.velocitypowered</groupId>\n            <artifactId>velocity-api</artifactId>\n            <version>3.0.0</version>\n            <scope>provided</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <finalName>${project.name}-${project.version}</finalName>\n        <resources>\n            <resource>\n                <directory>src/main/resources</directory>\n                <filtering>true</filtering>\n            </resource>\n        </resources>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-shade-plugin</artifactId>\n                <version>3.0.0</version>\n                <executions>\n                    <execution>\n                        <phase>package</phase>\n                        <goals>\n                            <goal>shade</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <configuration>\n                    <source>8</source>\n                    <target>8</target>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n\n</project>"
  },
  {
    "path": "cirrus-velocity-example/src/main/java/dev/simplix/cirrus/velocity/example/CirrusExamplePlugin.java",
    "content": "package dev.simplix.cirrus.velocity.example;\n\nimport com.google.inject.Inject;\nimport com.velocitypowered.api.command.CommandManager;\nimport com.velocitypowered.api.event.Subscribe;\nimport com.velocitypowered.api.event.proxy.ProxyInitializeEvent;\nimport com.velocitypowered.api.plugin.Plugin;\nimport com.velocitypowered.api.proxy.ProxyServer;\nimport dev.simplix.cirrus.velocity.CirrusVelocity;\nimport dev.simplix.cirrus.velocity.example.commands.TestCommand;\n\n@Plugin(\n        id = \"cirrusexample\",\n        name = \"CirrusExample\",\n        version = \"1.0\",\n        authors = \"Xefreh\"\n)\n\npublic class CirrusExamplePlugin {\n\n    private final ProxyServer proxyServer;\n    private final CommandManager commandManager;\n\n    @Inject\n    public CirrusExamplePlugin(ProxyServer proxyServer, CommandManager commandManager) {\n        this.proxyServer = proxyServer;\n        this.commandManager = commandManager;\n    }\n\n    @Subscribe\n    public void onProxyInitialization(ProxyInitializeEvent event) {\n        CirrusVelocity.init(proxyServer, this);\n        commandManager.register(\"test\", new TestCommand());\n    }\n\n\n}\n"
  },
  {
    "path": "cirrus-velocity-example/src/main/java/dev/simplix/cirrus/velocity/example/commands/TestCommand.java",
    "content": "package dev.simplix.cirrus.velocity.example.commands;\n\nimport com.velocitypowered.api.command.SimpleCommand;\nimport com.velocitypowered.api.proxy.Player;\nimport dev.simplix.cirrus.common.Cirrus;\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.converter.Converters;\nimport dev.simplix.cirrus.velocity.example.menus.ExampleMenu;\n\npublic class TestCommand implements SimpleCommand {\n\n    @Override\n    public void execute(Invocation invocation) {\n        if (invocation.source() instanceof Player) {\n            Player player = (Player) invocation.source();\n            new ExampleMenu(Converters.convert(player, PlayerWrapper.class),\n                    Cirrus.configurationFactory().loadFile(\"plugins/Cirrus/example.json\")).open();\n        }\n    }\n}\n"
  },
  {
    "path": "cirrus-velocity-example/src/main/java/dev/simplix/cirrus/velocity/example/menus/ExampleMenu.java",
    "content": "package dev.simplix.cirrus.velocity.example.menus;\n\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.configuration.MenuConfiguration;\nimport dev.simplix.cirrus.common.menus.SimpleMenu;\nimport dev.simplix.cirrus.common.model.CallResult;\n\nimport java.util.Locale;\n\npublic class ExampleMenu extends SimpleMenu {\n\n    public ExampleMenu(PlayerWrapper player, MenuConfiguration configuration) {\n        super(player, configuration, Locale.ENGLISH);\n\n        registerActionHandler(\"tnt\", click -> {\n            topContainer().itemMap().remove(click.slot());\n            title(\"Hello, {viewer}\");\n            build();\n            player().sendMessage(\"It simply works :)\");\n            return CallResult.DENY_GRABBING;\n        });\n    }\n\n}\n"
  },
  {
    "path": "cirrus-velocity-example/src/main/java/dev/simplix/cirrus/velocity/example/menus/ExampleMultiPageMenu.java",
    "content": "package dev.simplix.cirrus.velocity.example.menus;\n\nimport dev.simplix.cirrus.common.business.PlayerWrapper;\nimport dev.simplix.cirrus.common.configuration.MultiPageMenuConfiguration;\nimport dev.simplix.cirrus.common.menus.MultiPageMenu;\nimport dev.simplix.cirrus.common.model.CallResult;\nimport dev.simplix.protocolize.api.Protocolize;\nimport dev.simplix.protocolize.api.item.ItemStack;\nimport dev.simplix.protocolize.api.providers.MappingProvider;\nimport dev.simplix.protocolize.data.ItemType;\n\nimport java.util.Collections;\nimport java.util.Locale;\n\npublic class ExampleMultiPageMenu extends MultiPageMenu {\n\n    private final MappingProvider mappingProvider = Protocolize.mappingProvider();\n\n    public ExampleMultiPageMenu(\n            PlayerWrapper player,\n            MultiPageMenuConfiguration configuration) {\n        super(player, configuration, Locale.ENGLISH);\n        registerMyActionHandlers();\n        addItems();\n    }\n\n    private void registerMyActionHandlers() {\n        registerActionHandler(\"test\", click -> {\n            player().sendMessage(\"This is \" + click.clickedItem().type().name());\n            return CallResult.DENY_GRABBING;\n        });\n    }\n\n    private void addItems() {\n        for (ItemType type : ItemType.values()) {\n            if (this.mappingProvider.mapping(type, player().protocolVersion()) != null) {\n                add(wrapItemStack(new ItemStack(type)), \"test\", Collections.emptyList());\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <artifactId>cirrus</artifactId>\n    <groupId>dev.simplix.cirrus</groupId>\n    <modelVersion>4.0.0</modelVersion>\n    <packaging>pom</packaging>\n    <version>2.0.0</version> <!-- Static don't change -->\n\n    <properties>\n        <maven.compiler.source>8</maven.compiler.source>\n        <maven.compiler.target>8</maven.compiler.target>\n        <java.version>1.8</java.version>\n        <cirrus.version>2.0.0</cirrus.version>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n    </properties>\n\n    <dependencies>\n        <dependency>\n            <artifactId>protocolize-api</artifactId>\n            <groupId>dev.simplix</groupId>\n            <scope>provided</scope>\n            <version>2.4.1</version>\n        </dependency>\n        <dependency>\n            <groupId>org.jetbrains</groupId>\n            <artifactId>annotations</artifactId>\n            <version>23.0.0</version>\n            <scope>provided</scope>\n        </dependency>\n\n        <dependency>\n            <artifactId>lombok</artifactId>\n            <groupId>org.projectlombok</groupId>\n            <scope>provided</scope>\n            <version>1.18.22</version>\n        </dependency>\n        <dependency>\n            <artifactId>gson</artifactId>\n            <groupId>com.google.code.gson</groupId>\n            <scope>provided</scope>\n            <version>2.8.9</version>\n        </dependency>\n        <dependency>\n            <artifactId>bungeecord-chat</artifactId>\n            <groupId>net.md-5</groupId>\n            <scope>provided</scope>\n            <version>1.21-R0.1-SNAPSHOT</version>\n        </dependency>\n        <dependency>\n            <artifactId>junit-jupiter</artifactId>\n            <groupId>org.junit.jupiter</groupId>\n            <scope>test</scope>\n            <version>5.7.0-M1</version>\n        </dependency>\n        <dependency>\n            <groupId>com.mojang</groupId>\n            <artifactId>authlib</artifactId>\n            <version>1.5.21</version>\n            <scope>provided</scope>\n        </dependency>\n    </dependencies>\n\n    <modules>\n        <module>cirrus-common</module>\n        <module>cirrus-bungeecord</module>\n        <module>cirrus-velocity</module>\n        <module>cirrus-spigot</module>\n        <module>cirrus-spigot-modern</module>\n        <module>cirrus-bungeecord-example</module>\n        <module>cirrus-spigot-example</module>\n        <module>cirrus-velocity-example</module>\n    </modules>\n\n    <repositories>\n        <repository>\n            <id>jitpack.io</id>\n            <url>https://jitpack.io</url>\n        </repository>\n        <repository>\n            <id>simplixsoft-public</id>\n            <url>https://repo.simplix.dev/repository/simplixsoft-public/</url>\n        </repository>\n        <repository>\n            <id>exceptionflug</id>\n            <url>https://mvn.exceptionflug.de/repository/exceptionflug-public/</url>\n        </repository>\n        <repository>\n            <id>velocity</id>\n            <url>https://repo.velocitypowered.com/snapshots/</url>\n        </repository>\n        <repository>\n            <id>spigot-repo</id>\n            <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>\n        </repository>\n        <repository>\n            <id>minecraft-repo</id>\n            <url>https://libraries.minecraft.net/</url>\n        </repository>\n    </repositories>\n\n    <distributionManagement>\n        <repository>\n            <id>simplixsoft-public</id>\n            <url>https://repo.simplix.dev/repository/simplixsoft-public/</url>\n        </repository>\n        <snapshotRepository>\n            <id>simplixsoft-public</id>\n            <url>https://repo.simplix.dev/repository/simplixsoft-public/</url>\n        </snapshotRepository>\n    </distributionManagement>\n\n</project>"
  }
]