From f93afc0d14b7c342d299966bdbbc813d951f3834 Mon Sep 17 00:00:00 2001 From: Syed Daanish Date: Sat, 31 Jan 2026 10:25:39 +0000 Subject: [PATCH] Make binary portable and other fixes --- Makefile | 14 +- TODO.md | 4 +- include/editor/completions.h | 5 +- include/editor/editor.h | 6 +- include/lsp/lsp.h | 1 + include/main.h | 2 + include/scripting/decl.h | 24 ++ include/scripting/libcrib.rb | 43 +- include/scripting/ruby_compiled.h | 629 +++++++++++++++++------------- include/ui/bar.h | 6 +- include/utils/utils.h | 1 - samples/ruby.rb | 1 + src/editor/completions.cc | 21 + src/editor/editor.cc | 3 + src/editor/events.cc | 2 - src/editor/indents.cc | 6 +- src/editor/renderer.cc | 19 +- src/lsp/handlers.cc | 1 + src/lsp/process.cc | 90 +++-- src/lsp/workers.cc | 2 +- src/main.cc | 26 +- src/scripting/bindings.cc | 10 + src/scripting/process.cc | 107 ++++- src/ui/bar.cc | 122 +++--- src/ui/completionbox.cc | 20 +- 25 files changed, 738 insertions(+), 427 deletions(-) diff --git a/Makefile b/Makefile index b6ed452..90727d6 100644 --- a/Makefile +++ b/Makefile @@ -13,24 +13,24 @@ GENERATED_HEADER := $(INCLUDE_DIR)/scripting/ruby_compiled.h CCACHE := ccache CXX := $(CCACHE) clang++ -CC := $(CCACHE) clang +CC := $(CCACHE) musl-clang CFLAGS_DEBUG :=\ -std=c++20 -Wall -Wextra \ - -O0 -fno-inline -gsplit-dwarf\ - -g -fno-omit-frame-pointer\ + -O0 -fno-inline -gsplit-dwarf \ + -g -fno-omit-frame-pointer \ -Wno-unused-command-line-argument \ + -fsanitize=address \ -I./include -I./libs CFLAGS_RELEASE :=\ - -static \ - -std=c++20 -O3 -march=native \ - -fno-rtti -fstrict-aliasing \ + -static --target=x86_64-linux-musl \ + -std=c++20 -O3 -march=x86-64 -mtune=generic \ + -fno-rtti \ -ffast-math -flto=thin \ -fvisibility=hidden \ -fomit-frame-pointer -DNDEBUG -s \ -mllvm -vectorize-loops \ - -fno-unwind-tables -fno-asynchronous-unwind-tables\ -Wno-unused-command-line-argument \ -I./include -I./libs diff --git a/TODO.md b/TODO.md index c177010..7b4c0c1 100644 --- a/TODO.md +++ b/TODO.md @@ -4,8 +4,10 @@ Copyright 2025 Syed Daanish ##### BTW Check each lsp with each of the features implemented +* [ ] Make a proper qeued system for bar contents from ruby +* [ ] Allow clipbaord setting & alpha in ini files +* [ ] Make warning before ctrl+q for saving * [ ] **LSP Bug:** Check why `fish-lsp` is behaving so off with completions filtering. -* [ ] **Critical Crash:** Fix bug where closing immediately while LSP is still loading hangs and then segfaults (especially on slow ones like fish-lsp where quick edits and exit can hang). * [ ] **Line move:** fix the move line functions to work without the calculations from folds as folds are removed. * [ ] **Editor Indentation Fix:** - Main : merger indentation with the parser for more accurate results. * [ ] Fix bug where enter at start of line with ending type crashes diff --git a/include/editor/completions.h b/include/editor/completions.h index c5157d2..9cdc3f4 100644 --- a/include/editor/completions.h +++ b/include/editor/completions.h @@ -27,9 +27,10 @@ struct CompletionSession { bool active = false; Coord hook; std::optional prefix; - uint8_t select = 0; + uint32_t select = 0; + uint32_t scroll = 0; std::vector items; - std::vector visible; + std::vector visible; bool complete = true; std::optional trigger_char; uint8_t trigger = 0; diff --git a/include/editor/editor.h b/include/editor/editor.h index 4b306c8..f9812af 100644 --- a/include/editor/editor.h +++ b/include/editor/editor.h @@ -17,11 +17,9 @@ #define WORD 1 #define LINE 2 -#define EXTRA_META 4 +#define EXTRA_META 2 #define INDENT_WIDTH 2 -// autocomplete lua// Bracket closing / tab on enter - struct Editor { std::string filename; std::string uri; @@ -31,7 +29,7 @@ struct Editor { uint32_t cursor_preffered; Coord selection; bool selection_active; - bool unix_eol; // false for windows + bool unix_eol; int selection_type; Coord position; Coord size; diff --git a/include/lsp/lsp.h b/include/lsp/lsp.h index c54056d..cf88c96 100644 --- a/include/lsp/lsp.h +++ b/include/lsp/lsp.h @@ -80,6 +80,7 @@ void lsp_worker(); std::shared_ptr get_or_init_lsp(std::string lsp_id); void clean_lsp(std::shared_ptr lsp, std::string lsp_id); void close_lsp(std::string lsp_id); +std::optional read_lsp_message(int fd); void open_editor(std::shared_ptr lsp, std::pair entry); diff --git a/include/main.h b/include/main.h index 589576f..cc94987 100644 --- a/include/main.h +++ b/include/main.h @@ -2,6 +2,7 @@ #define MAIN_H #include "pch.h" +#include "ui/bar.h" #define NORMAL 0 #define INSERT 1 @@ -13,5 +14,6 @@ extern std::atomic running; extern std::atomic mode; extern std::vector editors; extern uint8_t current_editor; +extern Bar bar; #endif diff --git a/include/scripting/decl.h b/include/scripting/decl.h index 70f957d..a981af5 100644 --- a/include/scripting/decl.h +++ b/include/scripting/decl.h @@ -7,6 +7,26 @@ extern std::unordered_map> custom_highlighters; +struct BarLight { + uint32_t start; + uint32_t end; + Highlight highlight; +}; + +struct BarLine { + std::string line; + std::vector highlights; + + Highlight get_highlight(uint32_t x) { + for (auto &hl : highlights) { + if (hl.start <= x && x <= hl.end) + return hl.highlight; + } + return {0xFFFFFF, 0, 0}; + } +}; + +void setup_ruby_bindings(mrb_state *mrb, RClass *C_module); void ruby_start(); void ruby_shutdown(); void load_theme(); @@ -17,5 +37,9 @@ mrb_value parse_custom(std::vector *tokens, mrb_value parser_block, const char *line, uint32_t len, mrb_value state, uint32_t c_line); bool custom_compare(mrb_value match_block, mrb_value state1, mrb_value state2); +BarLine bar_contents(uint8_t mode, std::string lang_name, uint32_t warnings, + std::string lsp_name, std::string filename, + std::string foldername, uint32_t line, uint32_t max_line, + uint32_t width); #endif diff --git a/include/scripting/libcrib.rb b/include/scripting/libcrib.rb index 27f49b1..b07bf98 100644 --- a/include/scripting/libcrib.rb +++ b/include/scripting/libcrib.rb @@ -262,11 +262,52 @@ module C @highlighters = {} @b_startup = nil @b_shutdown = nil + @b_bar = lambda do |info| + # mode, lang_name, warnings, lsp_name, filename, foldername, line, max_line, width + # puts info.inspect + mode_color = 0x82AAFF + mode_symbol = " " + case info[:mode] + when :normal + mode_color = 0x82AAFF + mode_symbol = " " + when :insert + mode_color = 0xFF8F40 + mode_symbol = "󱓧 " + when :select + mode_color = 0x9ADE7A + mode_symbol = "󱩧 " + when :runner + mode_color = 0xFFD700 + mode_symbol = " " + when :jumper + mode_color = 0xF29CC3 + mode_symbol = " " + end + lang_info = C.languages[info[:lang_name]] + filename = File.basename(info[:filename]) + starting = " #{mode_symbol} #{info[:mode].to_s.upcase}  #{lang_info[:symbol]}#{filename}" + highlights = [] + highlights << { fg: 0x0b0e14, bg: mode_color, flags: 1 << 1, start: 0, length: 10 } + highlights << { fg: mode_color, bg: 0x33363c, start: 10, length: 1 } + highlights << { fg: 0x33363c, bg: 0x24272d, start: 11, length: 1 } + highlights << { fg: lang_info[:color], bg: 0x24272d, start: 13, length: 2 } + highlights << { fg: 0xced4df, bg: 0x24272d, start: 15, length: filename.length } + highlights << { fg: 0x24272d, bg: 0x000000, start: 15 + filename.length, length: 1 } + return { + text: starting, + highlights: highlights + } + end class << self attr_accessor :theme, :lsp_config, :languages, :line_endings, :highlighters - attr_reader :b_startup, :b_shutdown, :b_extra_highlights + attr_reader :b_startup, :b_shutdown, :b_extra_highlights, :b_bar + + # def bar=(block) + # @b_bar = block + # end def startup(&block) @b_startup = block diff --git a/include/scripting/ruby_compiled.h b/include/scripting/ruby_compiled.h index 9f4288c..90b6a88 100644 --- a/include/scripting/ruby_compiled.h +++ b/include/scripting/ruby_compiled.h @@ -1,8 +1,8 @@ #pragma once constexpr unsigned char _tmp___crib_precompiled_mrb[] = { - 0x52, 0x49, 0x54, 0x45, 0x30, 0x33, 0x30, 0x30, 0x00, 0x00, 0x18, 0xa1, + 0x52, 0x49, 0x54, 0x45, 0x30, 0x33, 0x30, 0x30, 0x00, 0x00, 0x1c, 0x69, 0x4d, 0x41, 0x54, 0x5a, 0x30, 0x30, 0x30, 0x30, 0x49, 0x52, 0x45, 0x50, - 0x00, 0x00, 0x18, 0x13, 0x30, 0x33, 0x30, 0x30, 0x00, 0x00, 0x00, 0x34, + 0x00, 0x00, 0x1b, 0x81, 0x30, 0x33, 0x30, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x11, 0x01, 0x5d, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x11, 0x01, 0x5d, 0x01, 0x01, 0x5e, 0x01, 0x01, 0x38, 0x01, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, @@ -92,8 +92,8 @@ constexpr unsigned char _tmp___crib_precompiled_mrb[] = { 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x44, 0x4f, 0x4e, 0x45, 0x00, 0x00, 0x0e, 0x4b, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x4e, 0x4f, 0x54, 0x44, 0x4f, 0x4e, 0x45, 0x00, 0x00, 0x06, 0x66, 0x72, 0x65, 0x65, 0x7a, 0x65, - 0x00, 0x00, 0x00, 0x0f, 0x45, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x65, 0x51, 0x01, 0x00, 0x51, 0x02, 0x01, 0x51, + 0x00, 0x00, 0x00, 0x0f, 0x61, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x6f, 0x51, 0x01, 0x00, 0x51, 0x02, 0x01, 0x51, 0x03, 0x02, 0x51, 0x04, 0x03, 0x51, 0x05, 0x04, 0x51, 0x06, 0x05, 0x51, 0x07, 0x06, 0x51, 0x08, 0x07, 0x47, 0x02, 0x07, 0x51, 0x03, 0x08, 0x47, 0x04, 0x00, 0x51, 0x05, 0x09, 0x51, 0x06, 0x0a, 0x47, 0x06, 0x01, 0x51, @@ -250,281 +250,362 @@ constexpr unsigned char _tmp___crib_precompiled_mrb[] = { 0x01, 0x53, 0x01, 0x1c, 0x1a, 0x01, 0x46, 0x10, 0x01, 0x47, 0x1a, 0x01, 0x48, 0x53, 0x01, 0x00, 0x1a, 0x01, 0x49, 0x53, 0x01, 0x00, 0x1a, 0x01, 0x4a, 0x53, 0x01, 0x00, 0x1a, 0x01, 0x4b, 0x11, 0x01, 0x1a, 0x01, 0x4c, - 0x11, 0x01, 0x1a, 0x01, 0x4d, 0x12, 0x01, 0x62, 0x01, 0x5e, 0x01, 0x00, - 0x38, 0x01, 0x00, 0x6e, 0x00, 0x00, 0x06, 0x63, 0x6c, 0x61, 0x6e, 0x67, - 0x64, 0x00, 0x00, 0x00, 0x12, 0x2d, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x67, - 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x00, - 0x00, 0x00, 0x0c, 0x2d, 0x2d, 0x63, 0x6c, 0x61, 0x6e, 0x67, 0x2d, 0x74, - 0x69, 0x64, 0x79, 0x00, 0x00, 0x00, 0x1b, 0x2d, 0x2d, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x74, 0x79, 0x6c, - 0x65, 0x3d, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x00, 0x00, - 0x00, 0x18, 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2d, 0x69, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x6e, 0x65, 0x76, - 0x65, 0x72, 0x00, 0x00, 0x00, 0x14, 0x2d, 0x2d, 0x70, 0x63, 0x68, 0x2d, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x3d, 0x6d, 0x65, 0x6d, 0x6f, - 0x72, 0x79, 0x00, 0x00, 0x00, 0x12, 0x2d, 0x2d, 0x6c, 0x69, 0x6d, 0x69, - 0x74, 0x2d, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x3d, 0x35, 0x30, - 0x00, 0x00, 0x00, 0x0b, 0x2d, 0x2d, 0x6c, 0x6f, 0x67, 0x3d, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x08, 0x72, 0x75, 0x62, 0x79, 0x2d, - 0x6c, 0x73, 0x70, 0x00, 0x00, 0x00, 0x0a, 0x73, 0x6f, 0x6c, 0x61, 0x72, - 0x67, 0x72, 0x61, 0x70, 0x68, 0x00, 0x00, 0x00, 0x05, 0x73, 0x74, 0x64, - 0x69, 0x6f, 0x00, 0x00, 0x00, 0x14, 0x62, 0x61, 0x73, 0x68, 0x2d, 0x6c, - 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x00, 0x00, 0x00, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, - 0x00, 0x00, 0x1a, 0x76, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2d, 0x63, 0x73, - 0x73, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x07, 0x2d, 0x2d, 0x73, - 0x74, 0x64, 0x69, 0x6f, 0x00, 0x00, 0x00, 0x1b, 0x76, 0x73, 0x63, 0x6f, - 0x64, 0x65, 0x2d, 0x6a, 0x73, 0x6f, 0x6e, 0x2d, 0x6c, 0x61, 0x6e, 0x67, - 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, - 0x00, 0x00, 0x08, 0x66, 0x69, 0x73, 0x68, 0x2d, 0x6c, 0x73, 0x70, 0x00, - 0x00, 0x00, 0x05, 0x67, 0x6f, 0x70, 0x6c, 0x73, 0x00, 0x00, 0x00, 0x05, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x00, 0x00, 0x00, 0x17, 0x68, 0x61, 0x73, - 0x6b, 0x65, 0x6c, 0x6c, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, - 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x03, - 0x6c, 0x73, 0x70, 0x00, 0x00, 0x00, 0x15, 0x65, 0x6d, 0x6d, 0x65, 0x74, - 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x1a, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, - 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, - 0x00, 0x13, 0x6c, 0x75, 0x61, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, - 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, - 0x12, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x6c, 0x61, 0x6e, - 0x67, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x0d, 0x72, - 0x75, 0x73, 0x74, 0x2d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72, - 0x00, 0x00, 0x00, 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x68, - 0x65, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x08, 0x6d, 0x61, 0x72, 0x6b, - 0x73, 0x6d, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x00, 0x00, 0x00, 0x15, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x2d, - 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x05, 0x74, 0x61, 0x70, 0x6c, 0x6f, - 0x00, 0x00, 0x00, 0x14, 0x79, 0x61, 0x6d, 0x6c, 0x2d, 0x6c, 0x61, 0x6e, + 0x11, 0x01, 0x1a, 0x01, 0x4d, 0x57, 0x02, 0x00, 0x2e, 0x01, 0x4e, 0x00, + 0x1a, 0x01, 0x4f, 0x12, 0x01, 0x62, 0x01, 0x5e, 0x01, 0x01, 0x38, 0x01, + 0x00, 0x6e, 0x00, 0x00, 0x06, 0x63, 0x6c, 0x61, 0x6e, 0x67, 0x64, 0x00, + 0x00, 0x00, 0x12, 0x2d, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x00, 0x00, 0x00, + 0x0c, 0x2d, 0x2d, 0x63, 0x6c, 0x61, 0x6e, 0x67, 0x2d, 0x74, 0x69, 0x64, + 0x79, 0x00, 0x00, 0x00, 0x1b, 0x2d, 0x2d, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, + 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x00, 0x00, 0x00, 0x18, + 0x2d, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2d, 0x69, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x6e, 0x65, 0x76, 0x65, 0x72, + 0x00, 0x00, 0x00, 0x14, 0x2d, 0x2d, 0x70, 0x63, 0x68, 0x2d, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x3d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x00, 0x00, 0x00, 0x12, 0x2d, 0x2d, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2d, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x3d, 0x35, 0x30, 0x00, 0x00, + 0x00, 0x0b, 0x2d, 0x2d, 0x6c, 0x6f, 0x67, 0x3d, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0x08, 0x72, 0x75, 0x62, 0x79, 0x2d, 0x6c, 0x73, + 0x70, 0x00, 0x00, 0x00, 0x0a, 0x73, 0x6f, 0x6c, 0x61, 0x72, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x00, 0x00, 0x00, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6f, + 0x00, 0x00, 0x00, 0x14, 0x62, 0x61, 0x73, 0x68, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x00, 0x00, 0x00, 0x04, 0x73, 0x71, 0x6c, 0x73, 0x00, 0x00, 0x00, 0x14, - 0x6d, 0x61, 0x6b, 0x65, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x00, 0x00, 0x00, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x00, 0x00, + 0x1a, 0x76, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2d, 0x63, 0x73, 0x73, 0x2d, + 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x07, 0x2d, 0x2d, 0x73, 0x74, 0x64, + 0x69, 0x6f, 0x00, 0x00, 0x00, 0x1b, 0x76, 0x73, 0x63, 0x6f, 0x64, 0x65, + 0x2d, 0x6a, 0x73, 0x6f, 0x6e, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, + 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, + 0x08, 0x66, 0x69, 0x73, 0x68, 0x2d, 0x6c, 0x73, 0x70, 0x00, 0x00, 0x00, + 0x05, 0x67, 0x6f, 0x70, 0x6c, 0x73, 0x00, 0x00, 0x00, 0x05, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x00, 0x00, 0x00, 0x17, 0x68, 0x61, 0x73, 0x6b, 0x65, + 0x6c, 0x6c, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x03, 0x6c, 0x73, + 0x70, 0x00, 0x00, 0x00, 0x15, 0x65, 0x6d, 0x6d, 0x65, 0x74, 0x2d, 0x6c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x00, 0x00, 0x00, 0x1a, 0x74, 0x79, 0x70, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x13, - 0x73, 0x71, 0x6c, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, - 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x02, 0x75, - 0x70, 0x00, 0x00, 0x00, 0x08, 0x2d, 0x2d, 0x6d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x00, 0x00, 0x00, 0x04, 0xee, 0x98, 0x9e, 0x20, 0x00, 0x00, 0x00, - 0x01, 0x63, 0x00, 0x00, 0x00, 0x04, 0xee, 0x98, 0x9d, 0x20, 0x00, 0x00, - 0x00, 0x03, 0x63, 0x70, 0x70, 0x00, 0x00, 0x00, 0x02, 0x63, 0x63, 0x00, - 0x00, 0x00, 0x03, 0x63, 0x78, 0x78, 0x00, 0x00, 0x00, 0x04, 0xef, 0x83, - 0xbd, 0x20, 0x00, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x00, 0x03, 0x68, - 0x70, 0x70, 0x00, 0x00, 0x00, 0x04, 0xee, 0x9a, 0xb8, 0x20, 0x00, 0x00, - 0x00, 0x03, 0x63, 0x73, 0x73, 0x00, 0x00, 0x00, 0x04, 0xee, 0xb9, 0x81, - 0x20, 0x00, 0x00, 0x00, 0x04, 0x66, 0x69, 0x73, 0x68, 0x00, 0x00, 0x00, - 0x04, 0xee, 0x98, 0xa7, 0x20, 0x00, 0x00, 0x00, 0x02, 0x67, 0x6f, 0x00, - 0x00, 0x00, 0x03, 0x6d, 0x6f, 0x64, 0x00, 0x00, 0x00, 0x04, 0xee, 0x9d, - 0xb7, 0x20, 0x00, 0x00, 0x00, 0x02, 0x68, 0x73, 0x00, 0x00, 0x00, 0x03, - 0x6c, 0x68, 0x73, 0x00, 0x00, 0x00, 0x04, 0xef, 0x84, 0xa1, 0x20, 0x00, - 0x00, 0x00, 0x04, 0x68, 0x74, 0x6d, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x68, - 0x74, 0x6d, 0x00, 0x00, 0x00, 0x04, 0xef, 0x8b, 0xaf, 0x20, 0x00, 0x00, - 0x00, 0x02, 0x6a, 0x73, 0x00, 0x00, 0x00, 0x04, 0xee, 0x9a, 0x9d, 0x20, - 0x00, 0x00, 0x00, 0x02, 0x74, 0x73, 0x00, 0x00, 0x00, 0x02, 0x7b, 0x7d, - 0x00, 0x00, 0x00, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, - 0x6a, 0x73, 0x6f, 0x6e, 0x63, 0x00, 0x00, 0x00, 0x03, 0x65, 0x72, 0x62, - 0x00, 0x00, 0x00, 0x05, 0xf3, 0xb0, 0xa2, 0xb1, 0x20, 0x00, 0x00, 0x00, - 0x03, 0x6c, 0x75, 0x61, 0x00, 0x00, 0x00, 0x05, 0xf3, 0xb0, 0x8c, 0xa0, - 0x20, 0x00, 0x00, 0x00, 0x02, 0x70, 0x79, 0x00, 0x00, 0x00, 0x07, 0x70, - 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x00, 0x00, 0x00, 0x05, 0xf3, 0xb1, - 0x98, 0x97, 0x20, 0x00, 0x00, 0x00, 0x02, 0x72, 0x73, 0x00, 0x00, 0x00, - 0x05, 0xf3, 0xb0, 0x8c, 0x9f, 0x20, 0x00, 0x00, 0x00, 0x03, 0x70, 0x68, - 0x70, 0x00, 0x00, 0x00, 0x04, 0xee, 0xba, 0xab, 0x20, 0x00, 0x00, 0x00, - 0x02, 0x6d, 0x64, 0x00, 0x00, 0x00, 0x08, 0x6d, 0x61, 0x72, 0x6b, 0x64, - 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00, 0x04, 0xee, 0x98, 0x95, 0x20, 0x00, - 0x00, 0x00, 0x04, 0x63, 0x6f, 0x6e, 0x66, 0x00, 0x00, 0x00, 0x04, 0xee, - 0x9a, 0xb2, 0x20, 0x00, 0x00, 0x00, 0x04, 0x74, 0x6f, 0x6d, 0x6c, 0x00, - 0x00, 0x00, 0x03, 0x79, 0x6d, 0x6c, 0x00, 0x00, 0x00, 0x04, 0x79, 0x61, - 0x6d, 0x6c, 0x00, 0x00, 0x00, 0x04, 0xee, 0x99, 0x8d, 0x20, 0x00, 0x00, - 0x00, 0x03, 0x73, 0x71, 0x6c, 0x00, 0x00, 0x00, 0x04, 0xee, 0x99, 0xb3, - 0x20, 0x00, 0x00, 0x00, 0x08, 0x4d, 0x61, 0x6b, 0x65, 0x66, 0x69, 0x6c, - 0x65, 0x00, 0x00, 0x00, 0x08, 0x6d, 0x61, 0x6b, 0x65, 0x66, 0x69, 0x6c, - 0x65, 0x00, 0x00, 0x00, 0x04, 0xee, 0x99, 0x9f, 0x20, 0x00, 0x00, 0x00, - 0x02, 0x67, 0x64, 0x00, 0x00, 0x00, 0x04, 0xef, 0x80, 0xad, 0x20, 0x00, - 0x00, 0x00, 0x03, 0x6d, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x04, 0xee, 0x9c, - 0xa8, 0x20, 0x00, 0x00, 0x00, 0x04, 0x64, 0x69, 0x66, 0x66, 0x00, 0x00, - 0x00, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, 0x04, 0xee, - 0x99, 0x9d, 0x20, 0x00, 0x00, 0x00, 0x0d, 0x67, 0x69, 0x74, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x00, 0x00, 0x00, 0x09, - 0x67, 0x69, 0x74, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x00, 0x00, 0x00, - 0x02, 0x2e, 0x2a, 0x00, 0x00, 0x00, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, - 0x00, 0x00, 0x00, 0x03, 0x69, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x05, 0xf3, - 0xb0, 0xb4, 0xad, 0x20, 0x00, 0x00, 0x00, 0x02, 0x72, 0x62, 0x00, 0x00, - 0x00, 0x07, 0x47, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, - 0x04, 0xee, 0xaf, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x02, 0x73, 0x68, 0x00, - 0x00, 0x00, 0x0c, 0x62, 0x61, 0x73, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x06, 0x62, 0x61, 0x73, 0x68, 0x72, - 0x63, 0x00, 0x00, 0x4e, 0x00, 0x0b, 0x40, 0x6c, 0x73, 0x70, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x00, 0x00, 0x01, 0x63, 0x00, 0x00, 0x05, - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x06, 0x73, 0x79, 0x6d, 0x62, - 0x6f, 0x6c, 0x00, 0x00, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x03, 0x6c, 0x73, 0x70, 0x00, 0x00, 0x03, - 0x63, 0x70, 0x70, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x03, 0x63, 0x73, - 0x73, 0x00, 0x00, 0x04, 0x66, 0x69, 0x73, 0x68, 0x00, 0x00, 0x02, 0x67, - 0x6f, 0x00, 0x00, 0x05, 0x67, 0x6f, 0x6d, 0x6f, 0x64, 0x00, 0x00, 0x07, - 0x68, 0x61, 0x73, 0x6b, 0x65, 0x6c, 0x6c, 0x00, 0x00, 0x04, 0x68, 0x74, - 0x6d, 0x6c, 0x00, 0x00, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x00, 0x00, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x00, 0x00, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x00, - 0x00, 0x05, 0x6a, 0x73, 0x6f, 0x6e, 0x63, 0x00, 0x00, 0x03, 0x65, 0x72, - 0x62, 0x00, 0x00, 0x03, 0x6c, 0x75, 0x61, 0x00, 0x00, 0x06, 0x70, 0x79, - 0x74, 0x68, 0x6f, 0x6e, 0x00, 0x00, 0x04, 0x72, 0x75, 0x73, 0x74, 0x00, - 0x00, 0x03, 0x70, 0x68, 0x70, 0x00, 0x00, 0x08, 0x6d, 0x61, 0x72, 0x6b, - 0x64, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x05, 0x6e, 0x67, 0x69, 0x6e, 0x78, - 0x00, 0x00, 0x04, 0x74, 0x6f, 0x6d, 0x6c, 0x00, 0x00, 0x04, 0x79, 0x61, - 0x6d, 0x6c, 0x00, 0x00, 0x03, 0x73, 0x71, 0x6c, 0x00, 0x00, 0x04, 0x6d, - 0x61, 0x6b, 0x65, 0x00, 0x00, 0x08, 0x67, 0x64, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x00, 0x00, 0x03, 0x6d, 0x61, 0x6e, 0x00, 0x00, 0x04, 0x64, - 0x69, 0x66, 0x66, 0x00, 0x00, 0x0d, 0x67, 0x69, 0x74, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x00, 0x00, 0x09, 0x67, 0x69, - 0x74, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x00, 0x00, 0x05, 0x72, 0x65, - 0x67, 0x65, 0x78, 0x00, 0x00, 0x03, 0x69, 0x6e, 0x69, 0x00, 0x00, 0x04, - 0x72, 0x75, 0x62, 0x79, 0x00, 0x00, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x00, 0x00, 0x04, 0x62, 0x61, 0x73, 0x68, 0x00, - 0x00, 0x0a, 0x40, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, - 0x00, 0x00, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x00, - 0x02, 0x66, 0x67, 0x00, 0x00, 0x07, 0x73, 0x68, 0x65, 0x62, 0x61, 0x6e, - 0x67, 0x00, 0x00, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x00, 0x07, - 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x06, 0x69, 0x74, - 0x61, 0x6c, 0x69, 0x63, 0x00, 0x00, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x00, 0x00, 0x06, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x00, 0x00, - 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x00, 0x00, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x00, - 0x00, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x00, 0x00, 0x04, 0x74, - 0x72, 0x75, 0x65, 0x00, 0x00, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x00, - 0x00, 0x04, 0x63, 0x68, 0x61, 0x72, 0x00, 0x00, 0x07, 0x6b, 0x65, 0x79, - 0x77, 0x6f, 0x72, 0x64, 0x00, 0x00, 0x0f, 0x6b, 0x65, 0x79, 0x77, 0x6f, - 0x72, 0x64, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, - 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x08, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x74, 0x00, 0x00, 0x10, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, - 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x0e, - 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x67, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x00, 0x00, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x00, 0x00, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x00, - 0x00, 0x06, 0x62, 0x72, 0x61, 0x63, 0x65, 0x31, 0x00, 0x00, 0x06, 0x62, - 0x72, 0x61, 0x63, 0x65, 0x32, 0x00, 0x00, 0x06, 0x62, 0x72, 0x61, 0x63, - 0x65, 0x33, 0x00, 0x00, 0x06, 0x62, 0x72, 0x61, 0x63, 0x65, 0x34, 0x00, - 0x00, 0x06, 0x62, 0x72, 0x61, 0x63, 0x65, 0x35, 0x00, 0x00, 0x06, 0x40, - 0x74, 0x68, 0x65, 0x6d, 0x65, 0x00, 0x00, 0x09, 0x61, 0x75, 0x74, 0x6f, - 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x00, 0x00, 0x0d, 0x40, 0x6c, 0x69, 0x6e, - 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x00, 0x00, 0x0d, - 0x40, 0x6b, 0x65, 0x79, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, - 0x73, 0x00, 0x00, 0x0a, 0x40, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x69, 0x6e, - 0x64, 0x73, 0x00, 0x00, 0x0d, 0x40, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, - 0x67, 0x68, 0x74, 0x65, 0x72, 0x73, 0x00, 0x00, 0x0a, 0x40, 0x62, 0x5f, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x00, 0x00, 0x0b, 0x40, 0x62, - 0x5f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00, - 0x01, 0x10, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x42, 0x10, 0x02, 0x00, 0x10, 0x03, 0x01, 0x10, 0x04, 0x02, 0x10, - 0x05, 0x03, 0x10, 0x06, 0x04, 0x2d, 0x01, 0x05, 0x05, 0x10, 0x02, 0x06, - 0x10, 0x03, 0x07, 0x10, 0x04, 0x08, 0x2d, 0x01, 0x09, 0x03, 0x63, 0x01, - 0x58, 0x02, 0x00, 0x5f, 0x01, 0x0a, 0x63, 0x01, 0x58, 0x02, 0x01, 0x5f, - 0x01, 0x0b, 0x63, 0x01, 0x58, 0x02, 0x02, 0x5f, 0x01, 0x0c, 0x63, 0x01, - 0x58, 0x02, 0x03, 0x5f, 0x01, 0x0d, 0x38, 0x01, 0x00, 0x00, 0x00, 0x0e, - 0x00, 0x05, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x00, 0x00, 0x0a, 0x6c, 0x73, - 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x00, 0x00, 0x09, 0x6c, - 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x00, 0x00, 0x0c, 0x6c, - 0x69, 0x6e, 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x00, - 0x00, 0x0c, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x65, - 0x72, 0x73, 0x00, 0x00, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x5f, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x00, 0x00, 0x09, 0x62, 0x5f, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x00, 0x00, 0x0a, 0x62, 0x5f, 0x73, - 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x12, 0x62, 0x5f, - 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, - 0x67, 0x68, 0x74, 0x73, 0x00, 0x00, 0x0b, 0x61, 0x74, 0x74, 0x72, 0x5f, - 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x00, 0x00, 0x07, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x75, 0x70, 0x00, 0x00, 0x08, 0x73, 0x68, 0x75, 0x74, 0x64, - 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x10, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, + 0x6c, 0x75, 0x61, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x12, 0x70, + 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x0d, 0x72, 0x75, 0x73, + 0x74, 0x2d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x72, 0x00, 0x00, + 0x00, 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x68, 0x65, 0x6e, + 0x73, 0x65, 0x00, 0x00, 0x00, 0x08, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x6d, + 0x61, 0x6e, 0x00, 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x00, 0x00, 0x00, 0x15, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x2d, 0x6c, 0x61, + 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x00, 0x00, 0x00, 0x05, 0x74, 0x61, 0x70, 0x6c, 0x6f, 0x00, 0x00, + 0x00, 0x14, 0x79, 0x61, 0x6d, 0x6c, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, + 0x00, 0x04, 0x73, 0x71, 0x6c, 0x73, 0x00, 0x00, 0x00, 0x14, 0x6d, 0x61, + 0x6b, 0x65, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x13, 0x73, 0x71, + 0x6c, 0x2d, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2d, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x02, 0x75, 0x70, 0x00, + 0x00, 0x00, 0x08, 0x2d, 0x2d, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x00, + 0x00, 0x00, 0x04, 0xee, 0x98, 0x9e, 0x20, 0x00, 0x00, 0x00, 0x01, 0x63, + 0x00, 0x00, 0x00, 0x04, 0xee, 0x98, 0x9d, 0x20, 0x00, 0x00, 0x00, 0x03, + 0x63, 0x70, 0x70, 0x00, 0x00, 0x00, 0x02, 0x63, 0x63, 0x00, 0x00, 0x00, + 0x03, 0x63, 0x78, 0x78, 0x00, 0x00, 0x00, 0x04, 0xef, 0x83, 0xbd, 0x20, + 0x00, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x00, 0x03, 0x68, 0x70, 0x70, + 0x00, 0x00, 0x00, 0x04, 0xee, 0x9a, 0xb8, 0x20, 0x00, 0x00, 0x00, 0x03, + 0x63, 0x73, 0x73, 0x00, 0x00, 0x00, 0x04, 0xee, 0xb9, 0x81, 0x20, 0x00, + 0x00, 0x00, 0x04, 0x66, 0x69, 0x73, 0x68, 0x00, 0x00, 0x00, 0x04, 0xee, + 0x98, 0xa7, 0x20, 0x00, 0x00, 0x00, 0x02, 0x67, 0x6f, 0x00, 0x00, 0x00, + 0x03, 0x6d, 0x6f, 0x64, 0x00, 0x00, 0x00, 0x04, 0xee, 0x9d, 0xb7, 0x20, + 0x00, 0x00, 0x00, 0x02, 0x68, 0x73, 0x00, 0x00, 0x00, 0x03, 0x6c, 0x68, + 0x73, 0x00, 0x00, 0x00, 0x04, 0xef, 0x84, 0xa1, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x68, 0x74, 0x6d, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x68, 0x74, 0x6d, + 0x00, 0x00, 0x00, 0x04, 0xef, 0x8b, 0xaf, 0x20, 0x00, 0x00, 0x00, 0x02, + 0x6a, 0x73, 0x00, 0x00, 0x00, 0x04, 0xee, 0x9a, 0x9d, 0x20, 0x00, 0x00, + 0x00, 0x02, 0x74, 0x73, 0x00, 0x00, 0x00, 0x02, 0x7b, 0x7d, 0x00, 0x00, + 0x00, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, 0x6a, 0x73, + 0x6f, 0x6e, 0x63, 0x00, 0x00, 0x00, 0x03, 0x65, 0x72, 0x62, 0x00, 0x00, + 0x00, 0x05, 0xf3, 0xb0, 0xa2, 0xb1, 0x20, 0x00, 0x00, 0x00, 0x03, 0x6c, + 0x75, 0x61, 0x00, 0x00, 0x00, 0x05, 0xf3, 0xb0, 0x8c, 0xa0, 0x20, 0x00, + 0x00, 0x00, 0x02, 0x70, 0x79, 0x00, 0x00, 0x00, 0x07, 0x70, 0x79, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x00, 0x00, 0x00, 0x05, 0xf3, 0xb1, 0x98, 0x97, + 0x20, 0x00, 0x00, 0x00, 0x02, 0x72, 0x73, 0x00, 0x00, 0x00, 0x05, 0xf3, + 0xb0, 0x8c, 0x9f, 0x20, 0x00, 0x00, 0x00, 0x03, 0x70, 0x68, 0x70, 0x00, + 0x00, 0x00, 0x04, 0xee, 0xba, 0xab, 0x20, 0x00, 0x00, 0x00, 0x02, 0x6d, + 0x64, 0x00, 0x00, 0x00, 0x08, 0x6d, 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, + 0x6e, 0x00, 0x00, 0x00, 0x04, 0xee, 0x98, 0x95, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x63, 0x6f, 0x6e, 0x66, 0x00, 0x00, 0x00, 0x04, 0xee, 0x9a, 0xb2, + 0x20, 0x00, 0x00, 0x00, 0x04, 0x74, 0x6f, 0x6d, 0x6c, 0x00, 0x00, 0x00, + 0x03, 0x79, 0x6d, 0x6c, 0x00, 0x00, 0x00, 0x04, 0x79, 0x61, 0x6d, 0x6c, + 0x00, 0x00, 0x00, 0x04, 0xee, 0x99, 0x8d, 0x20, 0x00, 0x00, 0x00, 0x03, + 0x73, 0x71, 0x6c, 0x00, 0x00, 0x00, 0x04, 0xee, 0x99, 0xb3, 0x20, 0x00, + 0x00, 0x00, 0x08, 0x4d, 0x61, 0x6b, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x00, + 0x00, 0x00, 0x08, 0x6d, 0x61, 0x6b, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x00, + 0x00, 0x00, 0x04, 0xee, 0x99, 0x9f, 0x20, 0x00, 0x00, 0x00, 0x02, 0x67, + 0x64, 0x00, 0x00, 0x00, 0x04, 0xef, 0x80, 0xad, 0x20, 0x00, 0x00, 0x00, + 0x03, 0x6d, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x04, 0xee, 0x9c, 0xa8, 0x20, + 0x00, 0x00, 0x00, 0x04, 0x64, 0x69, 0x66, 0x66, 0x00, 0x00, 0x00, 0x05, + 0x70, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, 0x04, 0xee, 0x99, 0x9d, + 0x20, 0x00, 0x00, 0x00, 0x0d, 0x67, 0x69, 0x74, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x00, 0x00, 0x00, 0x09, 0x67, 0x69, + 0x74, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x00, 0x00, 0x00, 0x02, 0x2e, + 0x2a, 0x00, 0x00, 0x00, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x00, 0x00, + 0x00, 0x03, 0x69, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x05, 0xf3, 0xb0, 0xb4, + 0xad, 0x20, 0x00, 0x00, 0x00, 0x02, 0x72, 0x62, 0x00, 0x00, 0x00, 0x07, + 0x47, 0x65, 0x6d, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x04, 0xee, + 0xaf, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x02, 0x73, 0x68, 0x00, 0x00, 0x00, + 0x0c, 0x62, 0x61, 0x73, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x00, 0x00, 0x00, 0x06, 0x62, 0x61, 0x73, 0x68, 0x72, 0x63, 0x00, + 0x00, 0x50, 0x00, 0x0b, 0x40, 0x6c, 0x73, 0x70, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x00, 0x00, 0x01, 0x63, 0x00, 0x00, 0x05, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x00, 0x00, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x00, 0x00, 0x03, 0x6c, 0x73, 0x70, 0x00, 0x00, 0x03, 0x63, 0x70, + 0x70, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x03, 0x63, 0x73, 0x73, 0x00, + 0x00, 0x04, 0x66, 0x69, 0x73, 0x68, 0x00, 0x00, 0x02, 0x67, 0x6f, 0x00, + 0x00, 0x05, 0x67, 0x6f, 0x6d, 0x6f, 0x64, 0x00, 0x00, 0x07, 0x68, 0x61, + 0x73, 0x6b, 0x65, 0x6c, 0x6c, 0x00, 0x00, 0x04, 0x68, 0x74, 0x6d, 0x6c, + 0x00, 0x00, 0x0a, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x00, 0x00, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x00, 0x00, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x00, 0x00, 0x05, + 0x6a, 0x73, 0x6f, 0x6e, 0x63, 0x00, 0x00, 0x03, 0x65, 0x72, 0x62, 0x00, + 0x00, 0x03, 0x6c, 0x75, 0x61, 0x00, 0x00, 0x06, 0x70, 0x79, 0x74, 0x68, + 0x6f, 0x6e, 0x00, 0x00, 0x04, 0x72, 0x75, 0x73, 0x74, 0x00, 0x00, 0x03, + 0x70, 0x68, 0x70, 0x00, 0x00, 0x08, 0x6d, 0x61, 0x72, 0x6b, 0x64, 0x6f, + 0x77, 0x6e, 0x00, 0x00, 0x05, 0x6e, 0x67, 0x69, 0x6e, 0x78, 0x00, 0x00, + 0x04, 0x74, 0x6f, 0x6d, 0x6c, 0x00, 0x00, 0x04, 0x79, 0x61, 0x6d, 0x6c, + 0x00, 0x00, 0x03, 0x73, 0x71, 0x6c, 0x00, 0x00, 0x04, 0x6d, 0x61, 0x6b, + 0x65, 0x00, 0x00, 0x08, 0x67, 0x64, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x00, 0x00, 0x03, 0x6d, 0x61, 0x6e, 0x00, 0x00, 0x04, 0x64, 0x69, 0x66, + 0x66, 0x00, 0x00, 0x0d, 0x67, 0x69, 0x74, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x00, 0x00, 0x09, 0x67, 0x69, 0x74, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x00, 0x00, 0x05, 0x72, 0x65, 0x67, 0x65, + 0x78, 0x00, 0x00, 0x03, 0x69, 0x6e, 0x69, 0x00, 0x00, 0x04, 0x72, 0x75, + 0x62, 0x79, 0x00, 0x00, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x00, 0x00, 0x04, 0x62, 0x61, 0x73, 0x68, 0x00, 0x00, 0x0a, + 0x40, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x00, 0x00, + 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x02, 0x66, + 0x67, 0x00, 0x00, 0x07, 0x73, 0x68, 0x65, 0x62, 0x61, 0x6e, 0x67, 0x00, + 0x00, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x00, 0x07, 0x63, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x06, 0x69, 0x74, 0x61, 0x6c, + 0x69, 0x63, 0x00, 0x00, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, + 0x00, 0x06, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x00, 0x00, 0x0d, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x00, 0x00, 0x06, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x00, 0x00, 0x04, 0x74, 0x72, 0x75, + 0x65, 0x00, 0x00, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x00, 0x00, 0x04, + 0x63, 0x68, 0x61, 0x72, 0x00, 0x00, 0x07, 0x6b, 0x65, 0x79, 0x77, 0x6f, + 0x72, 0x64, 0x00, 0x00, 0x0f, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x08, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x08, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x00, 0x00, 0x10, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x0e, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x00, 0x00, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x00, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x00, 0x00, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x00, 0x00, 0x06, + 0x62, 0x72, 0x61, 0x63, 0x65, 0x31, 0x00, 0x00, 0x06, 0x62, 0x72, 0x61, + 0x63, 0x65, 0x32, 0x00, 0x00, 0x06, 0x62, 0x72, 0x61, 0x63, 0x65, 0x33, + 0x00, 0x00, 0x06, 0x62, 0x72, 0x61, 0x63, 0x65, 0x34, 0x00, 0x00, 0x06, + 0x62, 0x72, 0x61, 0x63, 0x65, 0x35, 0x00, 0x00, 0x06, 0x40, 0x74, 0x68, + 0x65, 0x6d, 0x65, 0x00, 0x00, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x75, + 0x6e, 0x69, 0x78, 0x00, 0x00, 0x0d, 0x40, 0x6c, 0x69, 0x6e, 0x65, 0x5f, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x00, 0x00, 0x0d, 0x40, 0x6b, + 0x65, 0x79, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x00, + 0x00, 0x0a, 0x40, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x73, + 0x00, 0x00, 0x0d, 0x40, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, + 0x74, 0x65, 0x72, 0x73, 0x00, 0x00, 0x0a, 0x40, 0x62, 0x5f, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x75, 0x70, 0x00, 0x00, 0x0b, 0x40, 0x62, 0x5f, 0x73, + 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x06, 0x6c, 0x61, + 0x6d, 0x62, 0x64, 0x61, 0x00, 0x00, 0x06, 0x40, 0x62, 0x5f, 0x62, 0x61, + 0x72, 0x00, 0x00, 0x00, 0x03, 0x47, 0x00, 0x09, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x17, 0x34, 0x04, 0x00, 0x00, 0x0f, 0x03, + 0x00, 0x82, 0xaa, 0xff, 0x51, 0x04, 0x00, 0x01, 0x09, 0x01, 0x10, 0x0a, + 0x00, 0x23, 0x09, 0x10, 0x0a, 0x01, 0x01, 0x0b, 0x09, 0x2f, 0x0a, 0x02, + 0x01, 0x26, 0x0a, 0x00, 0x03, 0x25, 0x00, 0x0c, 0x0f, 0x03, 0x00, 0x82, + 0xaa, 0xff, 0x51, 0x04, 0x01, 0x25, 0x00, 0x74, 0x10, 0x0a, 0x03, 0x01, + 0x0b, 0x09, 0x2f, 0x0a, 0x02, 0x01, 0x26, 0x0a, 0x00, 0x03, 0x25, 0x00, + 0x0c, 0x0f, 0x03, 0x00, 0xff, 0x8f, 0x40, 0x51, 0x04, 0x02, 0x25, 0x00, + 0x57, 0x10, 0x0a, 0x04, 0x01, 0x0b, 0x09, 0x2f, 0x0a, 0x02, 0x01, 0x26, + 0x0a, 0x00, 0x03, 0x25, 0x00, 0x0c, 0x0f, 0x03, 0x00, 0x9a, 0xde, 0x7a, + 0x51, 0x04, 0x03, 0x25, 0x00, 0x3a, 0x10, 0x0a, 0x05, 0x01, 0x0b, 0x09, + 0x2f, 0x0a, 0x02, 0x01, 0x26, 0x0a, 0x00, 0x03, 0x25, 0x00, 0x0c, 0x0f, + 0x03, 0x00, 0xff, 0xd7, 0x00, 0x51, 0x04, 0x04, 0x25, 0x00, 0x1d, 0x10, + 0x0a, 0x06, 0x01, 0x0b, 0x09, 0x2f, 0x0a, 0x02, 0x01, 0x26, 0x0a, 0x00, + 0x03, 0x25, 0x00, 0x0c, 0x0f, 0x03, 0x00, 0xf2, 0x9c, 0xc3, 0x51, 0x04, + 0x05, 0x25, 0x00, 0x00, 0x1d, 0x09, 0x07, 0x2f, 0x09, 0x08, 0x00, 0x01, + 0x0a, 0x01, 0x10, 0x0b, 0x09, 0x23, 0x0a, 0x23, 0x09, 0x01, 0x05, 0x09, + 0x1d, 0x09, 0x0a, 0x01, 0x0a, 0x01, 0x10, 0x0b, 0x0b, 0x23, 0x0a, 0x2f, + 0x09, 0x0c, 0x01, 0x01, 0x06, 0x09, 0x51, 0x09, 0x06, 0x01, 0x0a, 0x04, + 0x52, 0x09, 0x51, 0x0a, 0x06, 0x52, 0x09, 0x01, 0x0a, 0x01, 0x10, 0x0b, + 0x00, 0x23, 0x0a, 0x2f, 0x0a, 0x0d, 0x00, 0x2f, 0x0a, 0x0e, 0x00, 0x52, + 0x09, 0x51, 0x0a, 0x07, 0x52, 0x09, 0x01, 0x0a, 0x05, 0x10, 0x0b, 0x0f, + 0x23, 0x0a, 0x52, 0x09, 0x51, 0x0a, 0x08, 0x52, 0x09, 0x01, 0x0a, 0x06, + 0x52, 0x09, 0x51, 0x0a, 0x09, 0x52, 0x09, 0x01, 0x07, 0x09, 0x47, 0x08, + 0x00, 0x01, 0x09, 0x08, 0x10, 0x0a, 0x10, 0x0f, 0x0b, 0x00, 0x0b, 0x0e, + 0x14, 0x10, 0x0c, 0x11, 0x01, 0x0d, 0x03, 0x10, 0x0e, 0x12, 0x08, 0x0f, + 0x10, 0x10, 0x13, 0x06, 0x11, 0x10, 0x12, 0x14, 0x03, 0x13, 0x0a, 0x53, + 0x0a, 0x05, 0x2f, 0x09, 0x15, 0x01, 0x01, 0x09, 0x08, 0x10, 0x0a, 0x10, + 0x01, 0x0b, 0x03, 0x10, 0x0c, 0x11, 0x0f, 0x0d, 0x00, 0x33, 0x36, 0x3c, + 0x10, 0x0e, 0x13, 0x03, 0x0f, 0x0a, 0x10, 0x10, 0x14, 0x07, 0x11, 0x53, + 0x0a, 0x04, 0x2f, 0x09, 0x15, 0x01, 0x01, 0x09, 0x08, 0x10, 0x0a, 0x10, + 0x0f, 0x0b, 0x00, 0x33, 0x36, 0x3c, 0x10, 0x0c, 0x11, 0x0f, 0x0d, 0x00, + 0x24, 0x27, 0x2d, 0x10, 0x0e, 0x13, 0x03, 0x0f, 0x0b, 0x10, 0x10, 0x14, + 0x07, 0x11, 0x53, 0x0a, 0x04, 0x2f, 0x09, 0x15, 0x01, 0x01, 0x09, 0x08, + 0x10, 0x0a, 0x10, 0x01, 0x0b, 0x05, 0x10, 0x0c, 0x16, 0x23, 0x0b, 0x10, + 0x0c, 0x11, 0x0f, 0x0d, 0x00, 0x24, 0x27, 0x2d, 0x10, 0x0e, 0x13, 0x03, + 0x0f, 0x0d, 0x10, 0x10, 0x14, 0x08, 0x11, 0x53, 0x0a, 0x04, 0x2f, 0x09, + 0x15, 0x01, 0x01, 0x09, 0x08, 0x10, 0x0a, 0x10, 0x0f, 0x0b, 0x00, 0xce, + 0xd4, 0xdf, 0x10, 0x0c, 0x11, 0x0f, 0x0d, 0x00, 0x24, 0x27, 0x2d, 0x10, + 0x0e, 0x13, 0x03, 0x0f, 0x0f, 0x10, 0x10, 0x14, 0x01, 0x11, 0x06, 0x2f, + 0x11, 0x14, 0x00, 0x53, 0x0a, 0x04, 0x2f, 0x09, 0x15, 0x01, 0x01, 0x09, + 0x08, 0x10, 0x0a, 0x10, 0x0f, 0x0b, 0x00, 0x24, 0x27, 0x2d, 0x10, 0x0c, + 0x11, 0x06, 0x0d, 0x10, 0x0e, 0x13, 0x03, 0x0f, 0x0f, 0x01, 0x10, 0x06, + 0x2f, 0x10, 0x14, 0x00, 0x3c, 0x0f, 0x10, 0x10, 0x14, 0x07, 0x11, 0x53, + 0x0a, 0x04, 0x2f, 0x09, 0x15, 0x01, 0x10, 0x09, 0x17, 0x01, 0x0a, 0x07, + 0x10, 0x0b, 0x18, 0x01, 0x0c, 0x08, 0x53, 0x09, 0x02, 0x39, 0x09, 0x38, + 0x09, 0x00, 0x0a, 0x00, 0x00, 0x02, 0x20, 0x20, 0x00, 0x00, 0x00, 0x04, + 0xee, 0x99, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x05, 0xf3, 0xb1, 0x93, 0xa7, + 0x20, 0x00, 0x00, 0x00, 0x05, 0xf3, 0xb1, 0xa9, 0xa7, 0x20, 0x00, 0x00, + 0x00, 0x04, 0xef, 0x84, 0xa0, 0x20, 0x00, 0x00, 0x00, 0x04, 0xee, 0xba, + 0xa2, 0x20, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x08, 0x20, + 0xee, 0x82, 0xb4, 0xee, 0x82, 0xb4, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xee, 0x82, 0xb4, 0x00, 0x00, 0x19, 0x00, 0x04, 0x6d, + 0x6f, 0x64, 0x65, 0x00, 0x00, 0x06, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x00, 0x00, 0x03, 0x3d, 0x3d, 0x3d, 0x00, 0x00, 0x06, 0x69, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x00, 0x00, 0x06, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x00, 0x00, 0x06, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x00, 0x00, 0x06, + 0x6a, 0x75, 0x6d, 0x70, 0x65, 0x72, 0x00, 0x00, 0x01, 0x43, 0x00, 0x00, + 0x09, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x73, 0x00, 0x00, + 0x09, 0x6c, 0x61, 0x6e, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, + 0x04, 0x46, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x08, 0x66, 0x69, 0x6c, 0x65, + 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x08, 0x62, 0x61, 0x73, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x00, 0x00, 0x04, 0x74, 0x6f, 0x5f, 0x73, 0x00, 0x00, + 0x06, 0x75, 0x70, 0x63, 0x61, 0x73, 0x65, 0x00, 0x00, 0x06, 0x73, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x00, 0x00, 0x02, 0x66, 0x67, 0x00, 0x00, 0x02, + 0x62, 0x67, 0x00, 0x00, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x00, 0x00, + 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x00, 0x06, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x00, 0x00, 0x02, 0x3c, 0x3c, 0x00, 0x00, 0x05, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x04, 0x74, 0x65, 0x78, 0x74, 0x00, + 0x00, 0x0a, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x00, 0x00, 0x00, 0x01, 0x1b, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x45, 0x10, 0x02, 0x00, 0x10, 0x03, 0x01, 0x10, + 0x04, 0x02, 0x10, 0x05, 0x03, 0x10, 0x06, 0x04, 0x2d, 0x01, 0x05, 0x05, + 0x10, 0x02, 0x06, 0x10, 0x03, 0x07, 0x10, 0x04, 0x08, 0x10, 0x05, 0x09, + 0x2d, 0x01, 0x0a, 0x04, 0x63, 0x01, 0x58, 0x02, 0x00, 0x5f, 0x01, 0x0b, + 0x63, 0x01, 0x58, 0x02, 0x01, 0x5f, 0x01, 0x0c, 0x63, 0x01, 0x58, 0x02, + 0x02, 0x5f, 0x01, 0x0d, 0x63, 0x01, 0x58, 0x02, 0x03, 0x5f, 0x01, 0x0e, + 0x38, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x05, 0x74, 0x68, 0x65, 0x6d, + 0x65, 0x00, 0x00, 0x0a, 0x6c, 0x73, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x00, 0x00, 0x09, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x73, 0x00, 0x00, 0x0c, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x65, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x73, 0x00, 0x00, 0x0c, 0x68, 0x69, 0x67, 0x68, + 0x6c, 0x69, 0x67, 0x68, 0x74, 0x65, 0x72, 0x73, 0x00, 0x00, 0x0d, 0x61, + 0x74, 0x74, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, + 0x00, 0x00, 0x09, 0x62, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, + 0x00, 0x00, 0x0a, 0x62, 0x5f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, + 0x6e, 0x00, 0x00, 0x12, 0x62, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x00, 0x00, - 0x04, 0x62, 0x69, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x02, - 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x34, 0x00, - 0x00, 0x01, 0x01, 0x02, 0x01, 0x1a, 0x02, 0x00, 0x38, 0x02, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x0a, 0x40, 0x62, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x05, 0x62, 0x5f, 0x62, 0x61, 0x72, 0x00, 0x00, 0x0b, 0x61, 0x74, 0x74, + 0x72, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x00, 0x00, 0x07, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x00, 0x00, 0x08, 0x73, 0x68, 0x75, + 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x10, 0x65, 0x78, 0x74, 0x72, + 0x61, 0x5f, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x00, 0x00, 0x04, 0x62, 0x69, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x34, 0x00, 0x00, 0x01, 0x01, 0x02, 0x01, 0x1a, 0x02, 0x00, 0x38, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x40, 0x62, 0x5f, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x75, 0x70, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x02, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x34, 0x00, 0x00, + 0x01, 0x01, 0x02, 0x01, 0x1a, 0x02, 0x00, 0x38, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x0b, 0x40, 0x62, 0x5f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, + 0x77, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x34, 0x00, 0x00, 0x01, 0x01, 0x02, 0x01, 0x1a, 0x02, 0x00, 0x38, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x0b, 0x40, 0x62, 0x5f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x34, 0x00, 0x00, 0x01, 0x01, 0x02, 0x01, - 0x1a, 0x02, 0x00, 0x38, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x13, 0x40, - 0x62, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x68, 0x69, 0x67, 0x68, - 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x00, 0x00, 0x00, 0x01, 0x43, 0x00, - 0x07, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x34, - 0x04, 0x40, 0x01, 0x25, 0x00, 0x06, 0x25, 0x00, 0x05, 0x25, 0x00, 0x04, - 0x11, 0x02, 0x11, 0x03, 0x01, 0x07, 0x01, 0x1d, 0x08, 0x00, 0x2f, 0x07, - 0x01, 0x01, 0x26, 0x07, 0x00, 0x07, 0x01, 0x07, 0x01, 0x48, 0x01, 0x07, - 0x01, 0x01, 0x07, 0x02, 0x28, 0x07, 0x00, 0x03, 0x25, 0x00, 0x33, 0x12, - 0x05, 0x1d, 0x07, 0x02, 0x2f, 0x07, 0x03, 0x00, 0x01, 0x06, 0x07, 0x01, - 0x07, 0x06, 0x10, 0x08, 0x04, 0x57, 0x09, 0x00, 0x30, 0x07, 0x05, 0x01, - 0x2d, 0x07, 0x06, 0x00, 0x27, 0x07, 0x00, 0x0d, 0x01, 0x07, 0x06, 0x01, - 0x08, 0x04, 0x30, 0x07, 0x07, 0x00, 0x25, 0x00, 0x02, 0x11, 0x07, 0x25, - 0x00, 0x5c, 0x2d, 0x07, 0x06, 0x00, 0x27, 0x07, 0x00, 0x22, 0x01, 0x07, - 0x02, 0x1d, 0x08, 0x00, 0x2f, 0x07, 0x01, 0x01, 0x26, 0x07, 0x00, 0x07, - 0x01, 0x07, 0x02, 0x48, 0x02, 0x07, 0x01, 0x01, 0x07, 0x01, 0x57, 0x08, - 0x01, 0x30, 0x07, 0x08, 0x00, 0x25, 0x00, 0x32, 0x01, 0x07, 0x03, 0x1d, - 0x08, 0x09, 0x2f, 0x07, 0x01, 0x01, 0x27, 0x07, 0x00, 0x22, 0x01, 0x07, - 0x02, 0x1d, 0x08, 0x00, 0x2f, 0x07, 0x01, 0x01, 0x26, 0x07, 0x00, 0x07, - 0x01, 0x07, 0x02, 0x48, 0x02, 0x07, 0x01, 0x01, 0x07, 0x01, 0x57, 0x08, - 0x02, 0x30, 0x07, 0x08, 0x00, 0x25, 0x00, 0x02, 0x11, 0x07, 0x38, 0x07, - 0x00, 0x00, 0x00, 0x0a, 0x00, 0x05, 0x41, 0x72, 0x72, 0x61, 0x79, 0x00, - 0x00, 0x05, 0x69, 0x73, 0x5f, 0x61, 0x3f, 0x00, 0x00, 0x06, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x00, 0x00, 0x03, 0x6e, 0x65, 0x77, 0x00, 0x00, - 0x03, 0x73, 0x65, 0x74, 0x00, 0x00, 0x17, 0x64, 0x65, 0x66, 0x69, 0x6e, - 0x65, 0x5f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x74, 0x6f, 0x6e, 0x5f, - 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x00, 0x00, 0x0c, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x5f, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x3f, 0x00, 0x00, 0x0d, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x65, 0x78, 0x65, - 0x63, 0x00, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, 0x00, 0x00, 0x06, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x04, - 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x34, 0x04, - 0x20, 0x01, 0x25, 0x00, 0x03, 0x25, 0x00, 0x02, 0x11, 0x02, 0x21, 0x04, - 0x05, 0x00, 0x21, 0x05, 0x01, 0x00, 0x01, 0x06, 0x01, 0x01, 0x07, 0x02, - 0x01, 0x08, 0x03, 0x30, 0x04, 0x00, 0x03, 0x38, 0x04, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x04, 0x62, 0x69, 0x6e, 0x64, 0x00, 0x00, 0x00, 0x00, 0x2c, - 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x34, 0x04, 0x00, 0x00, 0x21, 0x03, 0x02, 0x00, 0x57, 0x04, 0x00, 0x30, - 0x03, 0x00, 0x00, 0x38, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x65, - 0x61, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x03, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x34, 0x04, 0x00, 0x00, - 0x19, 0x03, 0x00, 0x21, 0x04, 0x01, 0x00, 0x01, 0x05, 0x03, 0x01, 0x06, - 0x04, 0x2f, 0x05, 0x01, 0x01, 0x26, 0x05, 0x00, 0x07, 0x53, 0x05, 0x00, - 0x2f, 0x03, 0x02, 0x02, 0x19, 0x03, 0x00, 0x21, 0x04, 0x01, 0x00, 0x23, - 0x03, 0x01, 0x04, 0x01, 0x01, 0x05, 0x03, 0x01, 0x06, 0x04, 0x2f, 0x05, - 0x01, 0x01, 0x26, 0x05, 0x00, 0x07, 0x47, 0x05, 0x00, 0x2f, 0x03, 0x02, - 0x02, 0x19, 0x03, 0x00, 0x21, 0x04, 0x01, 0x00, 0x23, 0x03, 0x01, 0x04, - 0x01, 0x23, 0x03, 0x21, 0x04, 0x04, 0x01, 0x2f, 0x03, 0x03, 0x01, 0x38, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0d, 0x40, 0x6b, 0x65, 0x79, 0x5f, - 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x02, 0x5b, - 0x5d, 0x00, 0x00, 0x03, 0x5b, 0x5d, 0x3d, 0x00, 0x00, 0x02, 0x3c, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x34, 0x04, 0x00, 0x00, 0x21, 0x03, 0x02, - 0x00, 0x57, 0x04, 0x00, 0x30, 0x03, 0x00, 0x00, 0x38, 0x03, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, - 0x8a, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x59, 0x34, 0x04, 0x00, 0x00, 0x19, 0x03, 0x00, 0x21, 0x04, 0x01, 0x00, - 0x01, 0x05, 0x03, 0x01, 0x06, 0x04, 0x2f, 0x05, 0x01, 0x01, 0x26, 0x05, - 0x00, 0x07, 0x53, 0x05, 0x00, 0x2f, 0x03, 0x02, 0x02, 0x19, 0x03, 0x00, - 0x21, 0x04, 0x01, 0x00, 0x23, 0x03, 0x01, 0x04, 0x01, 0x01, 0x05, 0x03, - 0x01, 0x06, 0x04, 0x2f, 0x05, 0x01, 0x01, 0x26, 0x05, 0x00, 0x07, 0x47, + 0x13, 0x40, 0x62, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x68, 0x69, + 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x00, 0x00, 0x00, 0x01, + 0x43, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc1, 0x34, 0x04, 0x40, 0x01, 0x25, 0x00, 0x06, 0x25, 0x00, 0x05, 0x25, + 0x00, 0x04, 0x11, 0x02, 0x11, 0x03, 0x01, 0x07, 0x01, 0x1d, 0x08, 0x00, + 0x2f, 0x07, 0x01, 0x01, 0x26, 0x07, 0x00, 0x07, 0x01, 0x07, 0x01, 0x48, + 0x01, 0x07, 0x01, 0x01, 0x07, 0x02, 0x28, 0x07, 0x00, 0x03, 0x25, 0x00, + 0x33, 0x12, 0x05, 0x1d, 0x07, 0x02, 0x2f, 0x07, 0x03, 0x00, 0x01, 0x06, + 0x07, 0x01, 0x07, 0x06, 0x10, 0x08, 0x04, 0x57, 0x09, 0x00, 0x30, 0x07, + 0x05, 0x01, 0x2d, 0x07, 0x06, 0x00, 0x27, 0x07, 0x00, 0x0d, 0x01, 0x07, + 0x06, 0x01, 0x08, 0x04, 0x30, 0x07, 0x07, 0x00, 0x25, 0x00, 0x02, 0x11, + 0x07, 0x25, 0x00, 0x5c, 0x2d, 0x07, 0x06, 0x00, 0x27, 0x07, 0x00, 0x22, + 0x01, 0x07, 0x02, 0x1d, 0x08, 0x00, 0x2f, 0x07, 0x01, 0x01, 0x26, 0x07, + 0x00, 0x07, 0x01, 0x07, 0x02, 0x48, 0x02, 0x07, 0x01, 0x01, 0x07, 0x01, + 0x57, 0x08, 0x01, 0x30, 0x07, 0x08, 0x00, 0x25, 0x00, 0x32, 0x01, 0x07, + 0x03, 0x1d, 0x08, 0x09, 0x2f, 0x07, 0x01, 0x01, 0x27, 0x07, 0x00, 0x22, + 0x01, 0x07, 0x02, 0x1d, 0x08, 0x00, 0x2f, 0x07, 0x01, 0x01, 0x26, 0x07, + 0x00, 0x07, 0x01, 0x07, 0x02, 0x48, 0x02, 0x07, 0x01, 0x01, 0x07, 0x01, + 0x57, 0x08, 0x02, 0x30, 0x07, 0x08, 0x00, 0x25, 0x00, 0x02, 0x11, 0x07, + 0x38, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x05, 0x41, 0x72, 0x72, 0x61, + 0x79, 0x00, 0x00, 0x05, 0x69, 0x73, 0x5f, 0x61, 0x3f, 0x00, 0x00, 0x06, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x00, 0x00, 0x03, 0x6e, 0x65, 0x77, + 0x00, 0x00, 0x03, 0x73, 0x65, 0x74, 0x00, 0x00, 0x17, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x65, 0x5f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x74, 0x6f, + 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x00, 0x00, 0x0c, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x3f, 0x00, + 0x00, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x65, + 0x78, 0x65, 0x63, 0x00, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, 0x00, 0x00, + 0x06, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x3e, + 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, + 0x34, 0x04, 0x20, 0x01, 0x25, 0x00, 0x03, 0x25, 0x00, 0x02, 0x11, 0x02, + 0x21, 0x04, 0x05, 0x00, 0x21, 0x05, 0x01, 0x00, 0x01, 0x06, 0x01, 0x01, + 0x07, 0x02, 0x01, 0x08, 0x03, 0x30, 0x04, 0x00, 0x03, 0x38, 0x04, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x62, 0x69, 0x6e, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x2c, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x34, 0x04, 0x00, 0x00, 0x21, 0x03, 0x02, 0x00, 0x57, 0x04, + 0x00, 0x30, 0x03, 0x00, 0x00, 0x38, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x04, 0x65, 0x61, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x03, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x34, 0x04, + 0x00, 0x00, 0x19, 0x03, 0x00, 0x21, 0x04, 0x01, 0x00, 0x01, 0x05, 0x03, + 0x01, 0x06, 0x04, 0x2f, 0x05, 0x01, 0x01, 0x26, 0x05, 0x00, 0x07, 0x53, 0x05, 0x00, 0x2f, 0x03, 0x02, 0x02, 0x19, 0x03, 0x00, 0x21, 0x04, 0x01, - 0x00, 0x23, 0x03, 0x01, 0x04, 0x01, 0x23, 0x03, 0x21, 0x04, 0x03, 0x01, - 0x2f, 0x03, 0x03, 0x01, 0x38, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0a, - 0x40, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x73, 0x00, 0x00, + 0x00, 0x23, 0x03, 0x01, 0x04, 0x01, 0x01, 0x05, 0x03, 0x01, 0x06, 0x04, + 0x2f, 0x05, 0x01, 0x01, 0x26, 0x05, 0x00, 0x07, 0x47, 0x05, 0x00, 0x2f, + 0x03, 0x02, 0x02, 0x19, 0x03, 0x00, 0x21, 0x04, 0x01, 0x00, 0x23, 0x03, + 0x01, 0x04, 0x01, 0x23, 0x03, 0x21, 0x04, 0x04, 0x01, 0x2f, 0x03, 0x03, + 0x01, 0x38, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0d, 0x40, 0x6b, 0x65, + 0x79, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x02, 0x5b, 0x5d, 0x00, 0x00, 0x03, 0x5b, 0x5d, 0x3d, 0x00, 0x00, 0x02, - 0x3c, 0x3c, 0x00, 0x4c, 0x56, 0x41, 0x52, 0x00, 0x00, 0x00, 0x72, 0x00, - 0x00, 0x00, 0x0b, 0x00, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x00, 0x05, - 0x6d, 0x6f, 0x64, 0x65, 0x73, 0x00, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x00, - 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x03, 0x61, 0x70, 0x70, - 0x00, 0x03, 0x64, 0x73, 0x6c, 0x00, 0x01, 0x6b, 0x00, 0x03, 0x61, 0x63, - 0x74, 0x00, 0x03, 0x62, 0x6c, 0x6b, 0x00, 0x04, 0x6d, 0x6f, 0x64, 0x65, - 0x00, 0x03, 0x6b, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x00, - 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0xff, 0xff, 0x00, 0x0a, 0xff, - 0xff, 0x00, 0x09, 0xff, 0xff, 0x00, 0x0a, 0xff, 0xff, 0x45, 0x4e, 0x44, - 0x00, 0x00, 0x00, 0x00, 0x08 + 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x03, 0x00, 0x05, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x34, 0x04, 0x00, 0x00, 0x21, + 0x03, 0x02, 0x00, 0x57, 0x04, 0x00, 0x30, 0x03, 0x00, 0x00, 0x38, 0x03, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x65, 0x61, 0x63, 0x68, 0x00, 0x00, + 0x00, 0x00, 0x8a, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x59, 0x34, 0x04, 0x00, 0x00, 0x19, 0x03, 0x00, 0x21, 0x04, + 0x01, 0x00, 0x01, 0x05, 0x03, 0x01, 0x06, 0x04, 0x2f, 0x05, 0x01, 0x01, + 0x26, 0x05, 0x00, 0x07, 0x53, 0x05, 0x00, 0x2f, 0x03, 0x02, 0x02, 0x19, + 0x03, 0x00, 0x21, 0x04, 0x01, 0x00, 0x23, 0x03, 0x01, 0x04, 0x01, 0x01, + 0x05, 0x03, 0x01, 0x06, 0x04, 0x2f, 0x05, 0x01, 0x01, 0x26, 0x05, 0x00, + 0x07, 0x47, 0x05, 0x00, 0x2f, 0x03, 0x02, 0x02, 0x19, 0x03, 0x00, 0x21, + 0x04, 0x01, 0x00, 0x23, 0x03, 0x01, 0x04, 0x01, 0x23, 0x03, 0x21, 0x04, + 0x03, 0x01, 0x2f, 0x03, 0x03, 0x01, 0x38, 0x03, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x0a, 0x40, 0x6b, 0x65, 0x79, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x73, + 0x00, 0x00, 0x02, 0x5b, 0x5d, 0x00, 0x00, 0x03, 0x5b, 0x5d, 0x3d, 0x00, + 0x00, 0x02, 0x3c, 0x3c, 0x00, 0x4c, 0x56, 0x41, 0x52, 0x00, 0x00, 0x00, + 0xcc, 0x00, 0x00, 0x00, 0x12, 0x00, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x00, + 0x0a, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, + 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x00, 0x09, 0x6c, 0x61, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x00, + 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x08, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x00, 0x0a, 0x68, 0x69, 0x67, + 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x00, 0x05, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x00, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x73, 0x00, 0x04, 0x6b, + 0x65, 0x79, 0x73, 0x00, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x03, 0x61, 0x70, 0x70, 0x00, 0x03, 0x64, 0x73, 0x6c, 0x00, 0x01, 0x6b, + 0x00, 0x03, 0x61, 0x63, 0x74, 0x00, 0x03, 0x62, 0x6c, 0x6b, 0x00, 0x04, + 0x6d, 0x6f, 0x64, 0x65, 0x00, 0x03, 0x6b, 0x65, 0x79, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, + 0x0a, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, + 0x0f, 0x00, 0x10, 0xff, 0xff, 0x00, 0x11, 0xff, 0xff, 0x00, 0x10, 0xff, + 0xff, 0x00, 0x11, 0xff, 0xff, 0x45, 0x4e, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x08 }; -constexpr unsigned int _tmp___crib_precompiled_mrb_len = 6305; +constexpr unsigned int _tmp___crib_precompiled_mrb_len = 7273; diff --git a/include/ui/bar.h b/include/ui/bar.h index d5a4b5f..29d935a 100644 --- a/include/ui/bar.h +++ b/include/ui/bar.h @@ -8,9 +8,13 @@ struct Bar { Coord screen; std::string command = ""; + std::string log_line = ""; uint32_t cursor = 0; + BarLine bar_line; + std::mutex mtx; - Bar(Coord screen) : screen(screen) {} + void init(Coord screen) { this->screen = screen; } + void work(); void render(); void handle(KeyEvent event); void log(std::string message); diff --git a/include/utils/utils.h b/include/utils/utils.h index 7973424..a0d39c0 100644 --- a/include/utils/utils.h +++ b/include/utils/utils.h @@ -102,7 +102,6 @@ struct Language { std::string name; std::string lsp_name; uint32_t color; - std::string symbol = "󱓧 "; }; struct LSP { diff --git a/samples/ruby.rb b/samples/ruby.rb index 3603dc7..9f86f8c 100644 --- a/samples/ruby.rb +++ b/samples/ruby.rb @@ -89,6 +89,7 @@ BASH puts multi + # Arrays mixing everything mixed = [ '🐍 Ruby + Python? sacrilege! 🐍', diff --git a/src/editor/completions.cc b/src/editor/completions.cc index 5872c43..2dd4e7a 100644 --- a/src/editor/completions.cc +++ b/src/editor/completions.cc @@ -25,6 +25,23 @@ inline static std::string completion_prefix(Editor *editor) { return prefix; } +inline static void completion_adjust_scroll(CompletionSession &s) { + if (s.visible.empty()) + return; + int vi = -1; + for (size_t i = 0; i < s.visible.size(); i++) + if (s.visible[i] == s.select) { + vi = (int)i; + break; + } + if (vi < 0) + return; + if ((uint32_t)vi < s.scroll) + s.scroll = vi; + else if ((uint32_t)vi >= s.scroll + 8) + s.scroll = vi - 7; +} + void completion_filter(Editor *editor) { auto &session = editor->completion; std::string prefix = completion_prefix(editor); @@ -44,6 +61,8 @@ void completion_filter(Editor *editor) { session.select) == session.visible.end()) session.select = session.visible[0]; session.box.hidden = false; + session.scroll = 0; + completion_adjust_scroll(session); session.box.render_update(); } @@ -417,6 +436,7 @@ void complete_next(Editor *editor) { vi = (vi + 1) % s.visible.size(); s.select = s.visible[vi]; completion_resolve_doc(editor); + completion_adjust_scroll(editor->completion); editor->completion.box.render_update(); } @@ -431,6 +451,7 @@ void complete_prev(Editor *editor) { vi = (vi + s.visible.size() - 1) % s.visible.size(); s.select = s.visible[vi]; completion_resolve_doc(editor); + completion_adjust_scroll(editor->completion); editor->completion.box.render_update(); } diff --git a/src/editor/editor.cc b/src/editor/editor.cc index 509092a..daeded4 100644 --- a/src/editor/editor.cc +++ b/src/editor/editor.cc @@ -1,6 +1,7 @@ #include "editor/editor.h" #include "editor/decl.h" #include "lsp/lsp.h" +#include "main.h" #include "syntax/langs.h" #include "utils/utils.h" @@ -77,6 +78,8 @@ void save_file(Editor *editor) { } out.close(); free(str); + bar.log("Written " + std::to_string(char_count) + " bytes to " + + editor->filename); if (editor->lsp) { json save_msg = {{"jsonrpc", "2.0"}, {"method", "textDocument/didSave"}, diff --git a/src/editor/events.cc b/src/editor/events.cc index 63093e3..39c1615 100644 --- a/src/editor/events.cc +++ b/src/editor/events.cc @@ -232,6 +232,4 @@ void handle_editor_event(Editor *editor, KeyEvent event) { if (old_mode == mode || mode != INSERT) handle_completion(editor, event); ensure_scroll(editor); - if ((event.key_type == KEY_CHAR || event.key_type == KEY_PASTE) && event.c) - free(event.c); } diff --git a/src/editor/indents.cc b/src/editor/indents.cc index f689878..3c6301b 100644 --- a/src/editor/indents.cc +++ b/src/editor/indents.cc @@ -218,8 +218,8 @@ void IndentationEngine::insert_new_line(Coord cursor) { if (is_end_full != kLangtoBlockEndsFull.end()) for (auto end : is_end_full->second) if (end == trim(line)) { - cursor.col = - set_indent(cursor.row, (int64_t)indent_expected(cursor.row) - 1); + cursor.col = set_indent( + cursor.row, (int64_t)indent_expected(cursor.row) - (int64_t)1); end_matched = true; break; } @@ -286,7 +286,7 @@ void IndentationEngine::insert_new_line(Coord cursor) { (indent == 1 ? std::string(c_indent, '\t') : std::string(c_indent * indent, ' ')) + ending; - else if (ending_valid) + else if (ending_valid && c_indent) c_indent--; } auto is_end_set = kLangtoBlockStartsEnd.find(editor->lang.name); diff --git a/src/editor/renderer.cc b/src/editor/renderer.cc index 8f37bb8..c2b903c 100644 --- a/src/editor/renderer.cc +++ b/src/editor/renderer.cc @@ -11,7 +11,7 @@ void render_editor(Editor *editor) { uint32_t numlen = EXTRA_META + static_cast(std::log10(editor->root->line_count + 1)); uint32_t render_width = editor->size.col - numlen; - uint32_t render_x = editor->position.col + numlen; + uint32_t render_x = editor->position.col + numlen + 1; std::vector> v; for (size_t i = 0; i < 94; ++i) if (editor->hooks[i] != 0) @@ -146,16 +146,14 @@ void render_editor(Editor *editor) { update(editor->position.row + rendered_rows, editor->position.col, hook, 0xAAAAAA, 0, 0); char buf[16]; - int len = - snprintf(buf, sizeof(buf), "%*u ", numlen - 3, line_index + 1); + int len = snprintf(buf, sizeof(buf), "%*u ", numlen, line_index + 1); uint32_t num_color = editor->cursor.row == line_index ? 0xFFFFFF : 0x555555; for (int i = 0; i < len; i++) - update(editor->position.row + rendered_rows, - editor->position.col + i + 2, (char[2]){buf[i], 0}, num_color, - 0, 0); + update(editor->position.row + rendered_rows, editor->position.col + i, + (char[2]){buf[i], 0}, num_color, 0, 0); } else { - for (uint32_t i = 0; i < numlen; i++) + for (uint32_t i = 0; i < numlen + 1; i++) update(editor->position.row + rendered_rows, editor->position.col + i, " ", 0, 0, 0); } @@ -349,13 +347,12 @@ void render_editor(Editor *editor) { update(editor->position.row + rendered_rows, editor->position.col, hook, 0xAAAAAA, 0, 0); char buf[16]; - int len = snprintf(buf, sizeof(buf), "%*u ", numlen - 3, line_index + 1); + int len = snprintf(buf, sizeof(buf), "%*u ", numlen, line_index + 1); uint32_t num_color = editor->cursor.row == line_index ? 0xFFFFFF : 0x555555; for (int i = 0; i < len; i++) - update(editor->position.row + rendered_rows, - editor->position.col + i + 2, (char[2]){buf[i], 0}, num_color, 0, - 0); + update(editor->position.row + rendered_rows, editor->position.col + i, + (char[2]){buf[i], 0}, num_color, 0, 0); if (editor->cursor.row == line_index) { cursor.row = editor->position.row + rendered_rows; cursor.col = render_x; diff --git a/src/lsp/handlers.cc b/src/lsp/handlers.cc index 555f1de..28e5b86 100644 --- a/src/lsp/handlers.cc +++ b/src/lsp/handlers.cc @@ -1,4 +1,5 @@ #include "lsp/lsp.h" +#include "main.h" Queue lsp_open_queue; diff --git a/src/lsp/process.cc b/src/lsp/process.cc index 4351d4f..84e98cd 100644 --- a/src/lsp/process.cc +++ b/src/lsp/process.cc @@ -155,40 +155,78 @@ std::shared_ptr get_or_init_lsp(std::string lsp_id) { } void close_lsp(std::string lsp_id) { - std::shared_lock active_lsps_lock(active_lsps_mtx); - auto it = active_lsps.find(lsp_id); - if (it == active_lsps.end()) + std::shared_ptr lsp; + { + std::shared_lock lock(active_lsps_mtx); + auto it = active_lsps.find(lsp_id); + if (it == active_lsps.end()) + return; + lsp = it->second; + } + if (!lsp || lsp->pid == -1 || lsp->exited) return; - std::shared_ptr lsp = it->second; - active_lsps_lock.unlock(); lsp->exited = true; lsp->initialized = false; - LSPPending *shutdown_pending = new LSPPending(); - shutdown_pending->method = "shutdown"; - shutdown_pending->callback = [lsp](Editor *, std::string, json) { - json exit = {{"jsonrpc", "2.0"}, {"method", "exit"}}; - lsp_send(lsp, exit, nullptr); + auto send_raw = [&](const json &msg) { + std::string payload = msg.dump(); + std::string header = + "Content-Length: " + std::to_string(payload.size()) + "\r\n\r\n"; + std::string out = header + payload; + const char *ptr = out.data(); + size_t remaining = out.size(); + while (remaining > 0) { + ssize_t n = write(lsp->stdin_fd, ptr, remaining); + if (n <= 0) { + if (errno == EINTR) + continue; + break; + } + ptr += n; + remaining -= n; + } }; - json shutdown = {{"jsonrpc", "2.0"}, {"method", "shutdown"}}; - lsp_send(lsp, shutdown, shutdown_pending); - std::thread t([lsp, lsp_id] { - std::this_thread::sleep_for(100ms); - std::unique_lock active_lsps_lock(active_lsps_mtx); - std::unique_lock lock(lsp->mtx); - if (lsp->pid != -1 && kill(lsp->pid, 0) == 0) - kill(lsp->pid, SIGKILL); + json shutdown = {{"jsonrpc", "2.0"}, {"id", 1}, {"method", "shutdown"}}; + send_raw(shutdown); + { + pollfd pfd{lsp->stdout_fd, POLLIN, 0}; + int timeout_ms = 300; + if (poll(&pfd, 1, timeout_ms) > 0) { + auto msg = read_lsp_message(lsp->stdout_fd); + (void)msg; + } + } + json exit_msg = {{"jsonrpc", "2.0"}, {"method", "exit"}}; + send_raw(exit_msg); + const int max_wait_ms = 500; + int waited = 0; + while (waited < max_wait_ms) { + int status; + pid_t res = waitpid(lsp->pid, &status, WNOHANG); + if (res == lsp->pid) + break; + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + waited += 10; + } + if (kill(lsp->pid, 0) == 0) { + kill(lsp->pid, SIGKILL); waitpid(lsp->pid, nullptr, 0); - close(lsp->stdin_fd); - close(lsp->stdout_fd); + } + close(lsp->stdin_fd); + close(lsp->stdout_fd); + { + std::unique_lock lock(lsp->mtx); for (auto &kv : lsp->pending) delete kv.second; - for (auto &editor : lsp->editors) { - std::unique_lock editor_lock(editor->lsp_mtx); - editor->lsp = nullptr; - } + lsp->pending.clear(); + } + for (auto &editor : lsp->editors) { + std::unique_lock editor_lock(editor->lsp_mtx); + editor->lsp = nullptr; + } + { + std::unique_lock lock(active_lsps_mtx); active_lsps.erase(lsp_id); - }); - t.detach(); + } } void clean_lsp(std::shared_ptr lsp, std::string lsp_id) { diff --git a/src/lsp/workers.cc b/src/lsp/workers.cc index 382f1cb..2362bc3 100644 --- a/src/lsp/workers.cc +++ b/src/lsp/workers.cc @@ -16,7 +16,7 @@ void lsp_send(std::shared_ptr lsp, json message, lsp->outbox.push(message); } -static std::optional read_lsp_message(int fd) { +std::optional read_lsp_message(int fd) { std::string header; char c; while (true) { diff --git a/src/main.cc b/src/main.cc index 0405c1f..3a90298 100644 --- a/src/main.cc +++ b/src/main.cc @@ -9,6 +9,7 @@ std::atomic running{true}; Queue event_queue; std::vector editors; +Bar bar; uint8_t current_editor = 0; std::atomic mode = NORMAL; @@ -36,7 +37,7 @@ inline uint8_t index_of(Editor *ed) { return 0; } -void input_listener(Bar bar) { +void input_listener() { while (running) { KeyEvent event = throttle(1ms, read_key); if (event.key_type == KEY_NONE) @@ -53,7 +54,6 @@ void input_listener(Bar bar) { if (target) { if (event.mouse_state == PRESS) current_editor = index_of(target); - event.mouse_x -= target->position.col; event.mouse_y -= target->position.row; handle_editor_event(target, event); @@ -64,9 +64,11 @@ void input_listener(Bar bar) { } else { bar.handle(event); } + if ((event.key_type == KEY_CHAR || event.key_type == KEY_PASTE) && event.c) + free(event.c); render: - render_editor(editors[current_editor]); bar.render(); + render_editor(editors[current_editor]); throttle(4ms, render); } } @@ -82,7 +84,7 @@ int main(int argc, char *argv[]) { uint8_t eol = read_line_endings(); Editor *editor = new_editor(filename, {0, 0}, {screen.row - 2, screen.col}, eol); - Bar bar(screen); + bar.init(screen); if (!editor) { end_screen(); @@ -93,11 +95,13 @@ int main(int argc, char *argv[]) { editors.push_back(editor); current_editor = editors.size() - 1; - std::thread input_thread(input_listener, bar); + std::thread input_thread(input_listener); std::thread lsp_thread(background_lsp); - while (running) + while (running) { throttle(16ms, editor_worker, editors[current_editor]); + bar.work(); + } if (input_thread.joinable()) input_thread.join(); @@ -110,16 +114,6 @@ int main(int argc, char *argv[]) { for (auto editor : editors) free_editor(editor); - std::unique_lock lk(active_lsps_mtx); - lk.unlock(); - while (true) { - lk.lock(); - if (active_lsps.empty()) - break; - lk.unlock(); - throttle(16ms, lsp_worker); - } - ruby_shutdown(); return 0; diff --git a/src/scripting/bindings.cc b/src/scripting/bindings.cc index e69de29..93b3afe 100644 --- a/src/scripting/bindings.cc +++ b/src/scripting/bindings.cc @@ -0,0 +1,10 @@ +#include "main.h" +#include "scripting/decl.h" + +mrb_value get_mode(mrb_state *mrb, mrb_value self) { + return mrb_fixnum_value(mode); +} + +void setup_ruby_bindings(mrb_state *mrb, RClass *C_module) { + mrb_define_module_function(mrb, C_module, "mode", get_mode, MRB_ARGS_NONE()); +} diff --git a/src/scripting/process.cc b/src/scripting/process.cc index 09075ed..88b40b9 100644 --- a/src/scripting/process.cc +++ b/src/scripting/process.cc @@ -1,6 +1,8 @@ +#include "main.h" #include "scripting/decl.h" #include "scripting/ruby_compiled.h" #include "utils/utils.h" +#include std::unordered_map> custom_highlighters; @@ -18,7 +20,6 @@ struct R_ThemeEntry { struct R_Language { std::string name; uint32_t color = 0xFFFFFF; - std::string symbol; std::vector extensions; std::vector filenames; std::string lsp_command; // link to LSP by name @@ -26,12 +27,10 @@ struct R_Language { mrb_state *mrb = nullptr; RClass *C_module; -std::mutex ruby_mutex; namespace fs = std::filesystem; void ruby_start() { - std::lock_guard lock(ruby_mutex); mrb = mrb_open(); if (!mrb) { fprintf(stderr, "Failed to init mruby\n"); @@ -55,6 +54,8 @@ void ruby_start() { candidates.emplace_back(exe_dir / "../config/main.rb"); candidates.emplace_back(exe_dir / "../config/crib.rb"); mrb_load_irep(mrb, _tmp___crib_precompiled_mrb); + C_module = mrb_module_get(mrb, "C"); + setup_ruby_bindings(mrb, C_module); for (const auto &p : candidates) { if (fs::exists(p)) { FILE *f = fopen(p.string().c_str(), "r"); @@ -67,14 +68,99 @@ void ruby_start() { break; } } - C_module = mrb_module_get(mrb, "C"); mrb_value mod_val = mrb_obj_value(C_module); mrb_value block = mrb_funcall(mrb, mod_val, "b_startup", 0); mrb_funcall(mrb, block, "call", 0); } +inline static std::vector +convert_highlights(mrb_state *mrb, mrb_value highlights_val) { + std::vector result; + if (!mrb_array_p(highlights_val)) + return result; + mrb_int len = RARRAY_LEN(highlights_val); + for (mrb_int i = 0; i < len; i++) { + mrb_value item = mrb_ary_ref(mrb, highlights_val, i); + if (!mrb_hash_p(item)) + continue; + auto get_sym = [&](const char *name) { + return mrb_symbol_value(mrb_intern_cstr(mrb, name)); + }; + mrb_value fg_v = mrb_hash_get(mrb, item, get_sym("fg")); + mrb_value bg_v = mrb_hash_get(mrb, item, get_sym("bg")); + mrb_value flags_v = mrb_hash_get(mrb, item, get_sym("flags")); + mrb_value start_v = mrb_hash_get(mrb, item, get_sym("start")); + mrb_value length_v = mrb_hash_get(mrb, item, get_sym("length")); + BarLight bl{}; + if (!mrb_nil_p(fg_v)) + bl.highlight.fg = (uint32_t)mrb_fixnum(fg_v); + if (!mrb_nil_p(bg_v)) + bl.highlight.bg = (uint32_t)mrb_fixnum(bg_v); + if (!mrb_nil_p(flags_v)) + bl.highlight.flags = (uint32_t)mrb_fixnum(flags_v); + uint32_t start = !mrb_nil_p(start_v) ? (uint32_t)mrb_fixnum(start_v) : 0; + uint32_t length = !mrb_nil_p(length_v) ? (uint32_t)mrb_fixnum(length_v) : 0; + bl.start = start; + bl.end = start + length; + result.push_back(bl); + } + return result; +} + +BarLine bar_contents(uint8_t mode, std::string lang_name, uint32_t warnings, + std::string lsp_name, std::string filename, + std::string foldername, uint32_t line, uint32_t max_line, + uint32_t width) { + BarLine bar_line; + mrb_value info = mrb_hash_new(mrb); + mrb_value key_mode = mrb_symbol_value(mrb_intern_cstr(mrb, "mode")); + mrb_value val_mode; + switch (mode) { + case NORMAL: + val_mode = mrb_symbol_value(mrb_intern_cstr(mrb, "normal")); + break; + case INSERT: + val_mode = mrb_symbol_value(mrb_intern_cstr(mrb, "insert")); + break; + case SELECT: + val_mode = mrb_symbol_value(mrb_intern_cstr(mrb, "select")); + break; + case RUNNER: + val_mode = mrb_symbol_value(mrb_intern_cstr(mrb, "runner")); + break; + case JUMPER: + val_mode = mrb_symbol_value(mrb_intern_cstr(mrb, "jumper")); + break; + } + mrb_hash_set(mrb, info, key_mode, val_mode); + mrb_value key_lang_name = mrb_symbol_value(mrb_intern_cstr(mrb, "lang_name")); + mrb_value val_lang_name = + mrb_symbol_value(mrb_intern_cstr(mrb, lang_name.c_str())); + mrb_hash_set(mrb, info, key_lang_name, val_lang_name); + mrb_value key_filename = mrb_symbol_value(mrb_intern_cstr(mrb, "filename")); + mrb_value val_filename = + mrb_str_new(mrb, filename.c_str(), filename.length()); + mrb_hash_set(mrb, info, key_filename, val_filename); + mrb_value key_width = mrb_symbol_value(mrb_intern_cstr(mrb, "width")); + mrb_value val_width = mrb_fixnum_value(width); + mrb_hash_set(mrb, info, key_width, val_width); + mrb_value mod_val = mrb_obj_value(C_module); + mrb_value block = mrb_funcall(mrb, mod_val, "b_bar", 0); + mrb_value val_line = mrb_funcall(mrb, block, "call", 1, info); + if (mrb->exc) + exit(1); + mrb_value text_val = mrb_hash_get( + mrb, val_line, mrb_symbol_value(mrb_intern_cstr(mrb, "text"))); + const char *ptr = RSTRING_PTR(text_val); + mrb_int len = RSTRING_LEN(text_val); + bar_line.line = std::string(ptr, len); + mrb_value highlights_val = mrb_hash_get( + mrb, val_line, mrb_symbol_value(mrb_intern_cstr(mrb, "highlights"))); + bar_line.highlights = convert_highlights(mrb, highlights_val); + return bar_line; +} + void ruby_shutdown() { - std::lock_guard lock(ruby_mutex); if (C_module == nullptr) return; mrb_value mod_val = mrb_obj_value(C_module); @@ -99,7 +185,6 @@ std::vector array_to_vector(mrb_value ary) { } void load_custom_highlighters() { - std::lock_guard lock(ruby_mutex); if (!C_module) return; mrb_value mod_val = mrb_obj_value((struct RObject *)C_module); @@ -127,7 +212,6 @@ void load_custom_highlighters() { } bool custom_compare(mrb_value match_block, mrb_value state1, mrb_value state2) { - std::lock_guard lock(ruby_mutex); if (mrb_type(match_block) != MRB_TT_PROC) return false; mrb_value ret = mrb_funcall(mrb, match_block, "call", 2, state1, state2); @@ -137,7 +221,6 @@ bool custom_compare(mrb_value match_block, mrb_value state1, mrb_value state2) { mrb_value parse_custom(std::vector *tokens, mrb_value parser_block, const char *line, uint32_t len, mrb_value state, uint32_t c_line) { - std::lock_guard lock(ruby_mutex); tokens->clear(); if (mrb_nil_p(parser_block)) return mrb_nil_value(); @@ -168,7 +251,6 @@ mrb_value parse_custom(std::vector *tokens, mrb_value parser_block, } static std::vector read_theme() { - std::lock_guard lock(ruby_mutex); std::vector result; if (!C_module) return result; @@ -307,8 +389,6 @@ std::vector read_languages() { lang.name = std::string(RSTRING_PTR(key), RSTRING_LEN(key)); mrb_value fg = mrb_hash_get(mrb, val_hash, mrb_symbol_value(mrb_intern_lit(mrb, "color"))); - mrb_value symbol = mrb_hash_get( - mrb, val_hash, mrb_symbol_value(mrb_intern_lit(mrb, "symbol"))); mrb_value extensions = mrb_hash_get( mrb, val_hash, mrb_symbol_value(mrb_intern_lit(mrb, "extensions"))); mrb_value filenames = mrb_hash_get( @@ -317,8 +397,6 @@ std::vector read_languages() { mrb_symbol_value(mrb_intern_lit(mrb, "lsp"))); if (!mrb_nil_p(fg)) lang.color = (uint32_t)mrb_fixnum(fg); - if (!mrb_nil_p(symbol)) - lang.symbol = std::string(RSTRING_PTR(symbol), RSTRING_LEN(symbol)); lang.extensions = array_to_vector(extensions); if (!mrb_nil_p(filenames)) lang.filenames = array_to_vector(filenames); @@ -330,7 +408,6 @@ std::vector read_languages() { } void load_languages_info() { - std::lock_guard lock(ruby_mutex); auto langs = read_languages(); auto lsps_t = read_lsps(); languages.clear(); @@ -339,7 +416,6 @@ void load_languages_info() { l.name = lang.name; l.color = lang.color; l.lsp_name = lang.lsp_command; - l.symbol = lang.symbol; languages[lang.name] = l; for (auto &ext : lang.extensions) language_extensions[ext] = lang.name; @@ -352,7 +428,6 @@ void load_languages_info() { } uint8_t read_line_endings() { - std::lock_guard lock(ruby_mutex); if (!C_module) return 1; mrb_value mod_val = mrb_obj_value((struct RObject *)C_module); diff --git a/src/ui/bar.cc b/src/ui/bar.cc index e8b2539..447d8db 100644 --- a/src/ui/bar.cc +++ b/src/ui/bar.cc @@ -1,66 +1,59 @@ #include "ui/bar.h" #include "io/sysio.h" +#include "lsp/lsp.h" #include "main.h" +#include "syntax/decl.h" + +void Bar::work() { + std::lock_guard lock(mtx); + Editor *editor = editors[current_editor]; + bar_line = + bar_contents(mode, editor->lang.name, editor->warnings.size(), + editor->lsp ? editor->lsp->lsp->command : "", + editor->filename, editor->filename, editor->cursor.row + 1, + editor->root->line_count + 1, screen.col); +} + +void Bar::log(std::string message) { + std::lock_guard lock(mtx); + log_line = message; +} void Bar::render() { - Editor *editor = editors[current_editor]; + std::lock_guard lock(mtx); + USING(LSPInstance); uint32_t row = screen.row - 2; - uint32_t col = 0; uint32_t width = screen.col; - UNUSED(width); - uint32_t color = 0; - uint32_t black = 0x0b0e14; - uint32_t grey = 0x33363c; - uint32_t dark_grey = 0x24272d; - uint32_t name_color = 0xced4df; - uint32_t lang_color = editor->lang.color; - const char *symbol = "󱓧 "; - const char *name = "EDITOR"; - switch (mode) { - case NORMAL: - color = 0x82AAFF; - symbol = " "; - name = "NORMAL"; - break; - case INSERT: - color = 0xFF8F40; - symbol = "󱓧 "; - name = "INSERT"; - break; - case SELECT: - color = 0x9ADE7A; - symbol = "󱩧 "; - name = "SELECT"; - break; - case RUNNER: - color = 0xFFD700; - symbol = " "; - name = "RUNNER"; - break; - case JUMPER: - color = 0xF29CC3; - symbol = " "; - name = "JUMPER"; - break; + std::string &line = bar_line.line; + uint32_t i = 0; + uint32_t col = 0; + while (i < line.length()) { + uint32_t cluster_len = + grapheme_next_character_break_utf8(line.c_str() + i, line.length() - i); + std::string cluster = line.substr(i, cluster_len); + int width = display_width(cluster.c_str(), cluster_len); + Highlight highlight = bar_line.get_highlight(col); + update(row, col, cluster.c_str(), highlight.fg, highlight.bg, + highlight.flags); + col += width; + i += cluster_len; + for (int w = 1; w < width; w++) + update(row, col - w, "\x1b", highlight.fg, highlight.bg, highlight.flags); } - update(row, col, " ", black, color, CF_BOLD); - update(row, ++col, symbol, black, color, CF_BOLD); - update(row, ++col, "\x1b", black, color, CF_BOLD); - update(row, ++col, " ", black, color, CF_BOLD); - for (uint32_t i = 0; i < 6; i++) - update(row, ++col, {name[i], 0}, black, color, CF_BOLD); - update(row, ++col, " ", black, color, CF_BOLD); - update(row, ++col, "◗", color, grey, CF_BOLD); - update(row, ++col, "◗", grey, dark_grey, CF_BOLD); - update(row, ++col, " ", name_color, dark_grey, CF_BOLD); - update(row, ++col, editor->lang.symbol, lang_color, dark_grey, 0); - update(row, ++col, "\x1b", lang_color, dark_grey, 0); - update(row, ++col, " ", name_color, dark_grey, CF_BOLD); - std::string filename = filename_from_path(editor->filename); - for (uint32_t i = 0; i < filename.length(); i++) - update(row, ++col, {filename[i], 0}, name_color, dark_grey, CF_BOLD); - update(row, ++col, " ", name_color, dark_grey, CF_BOLD); - update(row, ++col, "◗", dark_grey, 1, CF_BOLD); + while (col < width) + update(row, col++, " ", 0, 0, 0); + col = 0; + row++; + if (mode == RUNNER) { + update(row, col++, ":", 0xFFFFFF, 0, 0); + for (char c : command) + update(row, col++, (char[2]){c, 0}, 0xFFFFFF, 0, 0); + } else { + for (char c : log_line) + update(row, col++, (char[2]){c, 0}, 0xFFFFFF, 0, 0); + } + while (col < width) + update(row, col++, " ", 0, 0, 0); } void Bar::handle(KeyEvent event) { @@ -68,11 +61,26 @@ void Bar::handle(KeyEvent event) { if (event.c[0] == 0x1B) { mode = NORMAL; } else if (event.c[0] == '\n' || event.c[0] == '\r') { - // execute command while stripping starting `[:;]` + command = trim(command); + if (command == "w") { + save_file(editors[current_editor]); + } else if (command == "q") { + running = false; + } else if (command == "wq") { + save_file(editors[current_editor]); + running = false; + } mode = NORMAL; command = ""; } else if (isprint((unsigned char)(event.c[0]))) { - } else if (event.c[0] == 0x7F || event.c[0] == 0x08) { // backspace + command += event.c[0]; + } else if (event.c[0] == 0x7F || event.c[0] == 0x08) { + if (command.length() > 0) { + command = command.substr(0, command.length() - 1); + } else { + mode = NORMAL; + command = ""; + } } } else if (event.key_type == KEY_SPECIAL) { switch (event.special_key) { diff --git a/src/ui/completionbox.cc b/src/ui/completionbox.cc index bcb147a..be39ae7 100644 --- a/src/ui/completionbox.cc +++ b/src/ui/completionbox.cc @@ -71,7 +71,9 @@ void CompletionBox::render_update() { uint32_t max_label_len = 0; uint32_t max_detail_len = 0; uint32_t max_kind_len = 0; - for (auto i : session->visible) { + for (uint32_t x = session->scroll; + x < session->scroll + 8 && x < session->visible.size(); x++) { + uint32_t i = session->visible[x]; if (i >= session->items.size()) continue; auto &item = session->items[i]; @@ -81,7 +83,9 @@ void CompletionBox::render_update() { max_kind_len = MAX(max_kind_len, (uint32_t)item_kind_name(item.kind).size()); } - size.row = session->visible.size() + 2; + uint32_t total = session->visible.size(); + uint32_t rows = MIN(total, 8); + size.row = rows + 2; size.col = 2 + 2 + max_label_len + 1 + max_detail_len + 2 + max_kind_len + 1; cells.assign(size.row * size.col, {" ", 0, 0, 0, 0, 0}); auto set = [&](uint32_t r, uint32_t c, const char *text, uint32_t fg, @@ -95,8 +99,10 @@ void CompletionBox::render_update() { for (uint32_t c = 1; c < size.col - 1; c++) set(0, c, "─", border_fg, 0, 0); set(0, size.col - 1, "┐", border_fg, 0, 0); - for (uint32_t row_idx = 0; row_idx < session->visible.size(); row_idx++) { - uint32_t r = row_idx + 1; + uint32_t start = session->scroll; + uint32_t end = MIN(start + 8, session->visible.size()); + for (uint32_t row_idx = start; row_idx < end; row_idx++) { + uint32_t r = (row_idx - start) + 1; auto &item = session->items[session->visible[row_idx]]; uint32_t bg = (session->visible[row_idx] == session->select) ? sel_bg : 1; uint32_t fg = 0xFFFFFF; @@ -130,6 +136,12 @@ void CompletionBox::render_update() { for (uint32_t c = 1; c < size.col - 1; c++) set(bottom, c, "─", border_fg, 0, 0); set(bottom, size.col - 1, "┘", border_fg, 0, 0); + if (session->visible.size() > 8) { + std::string info = std::to_string(start + 1) + "-" + std::to_string(end) + + "/" + std::to_string(session->visible.size()); + for (size_t i = 0; i < info.size() && i < size.col - 2; i++) + set(bottom, 1 + i, (char[2]){info[i], 0}, border_fg, 0, 0); + } } void CompletionBox::render(Coord pos) {