From 9db28e0daa891a212885b8e7bed733620f9711c3 Mon Sep 17 00:00:00 2001 From: Maksym H Date: Fri, 4 Aug 2023 14:33:33 +0300 Subject: [PATCH] MainMenu improvements and cleanup (#141) Co-authored-by: luk3yx (cherry picked from commit 75452a9e9abe14deaf80cd696b056f708cf4f0fb) --- builtin/fstk/tabview.lua | 241 +++++++++--------- builtin/mainmenu/dlg_contentstore.lua | 3 +- builtin/mainmenu/dlg_version_info.lua | 2 + builtin/mainmenu/init.lua | 40 ++- builtin/mainmenu/tab_content.lua | 9 +- builtin/mainmenu/tab_local.lua | 6 +- builtin/mainmenu/tab_local_default.lua | 54 +--- builtin/mainmenu/tab_online.lua | 1 + src/gui/guiFormSpecMenu.cpp | 2 +- src/gui/guiHyperText.cpp | 3 +- src/gui/guiHyperText.h | 3 +- textures/base/pack/gui/bg_darken.png | Bin 0 -> 172 bytes textures/base/pack/gui/content_menu.png | Bin 0 -> 822 bytes textures/base/pack/gui/content_menu_hover.png | Bin 0 -> 812 bytes .../base/pack/gui/content_menu_selected.png | Bin 0 -> 812 bytes textures/base/pack/gui/side_menu_darken.png | Bin 0 -> 152 bytes textures/base/pack/switch_local.png | Bin 816 -> 0 bytes textures/base/pack/switch_local_default.png | Bin 1875 -> 1756 bytes .../base/pack/switch_local_default_hover.png | Bin 1889 -> 1714 bytes textures/base/pack/switch_local_hover.png | Bin 810 -> 0 bytes 20 files changed, 174 insertions(+), 190 deletions(-) create mode 100644 textures/base/pack/gui/bg_darken.png create mode 100644 textures/base/pack/gui/content_menu.png create mode 100644 textures/base/pack/gui/content_menu_hover.png create mode 100644 textures/base/pack/gui/content_menu_selected.png create mode 100644 textures/base/pack/gui/side_menu_darken.png delete mode 100644 textures/base/pack/switch_local.png delete mode 100644 textures/base/pack/switch_local_hover.png diff --git a/builtin/fstk/tabview.lua b/builtin/fstk/tabview.lua index 899916a17..136607155 100644 --- a/builtin/fstk/tabview.lua +++ b/builtin/fstk/tabview.lua @@ -26,6 +26,9 @@ -- element.getFormspec() returns formspec of tabview -- -------------------------------------------------------------------------------- +local fmt = string.format +local tconcat = table.concat + -------------------------------------------------------------------------------- local function add_tab(self,tab) assert(tab.size == nil or (type(tab.size) == table and @@ -78,78 +81,149 @@ end -------------------------------------------------------------------------------- local tpath = defaulttexturedir_esc .. "gui" .. DIR_DELIM_esc -local function get_side_menu(self, selected_tab) - if #self.side_buttons == 0 then return "" end +local function add_side_menu(self, fs, selected_tab, x, fs_h, darken) + if #self.side_buttons == 0 then return end - local side_menu_h = #self.side_buttons * 1.2 + 0.2 - local bg_y = 2.35 - side_menu_h / 2 - local fs = { - "background9[12.13,", bg_y, ";0.9,", side_menu_h, ";", tpath, - "side_menu.png;false;30]" - } + local side_menu_h = #self.side_buttons * 1.41 + 0.14 + local bg_y = fs_h / 2 - side_menu_h / 2 + fs[#fs + 1] = fmt("image[%s,%s;1.15,%s;%sside_menu.png;30]", x, bg_y, side_menu_h, tpath) for i, btn in ipairs(self.side_buttons) do - local y = bg_y - 1.15 + 1.2 * i + local y = bg_y - 1.31 + 1.41 * i if i > 1 then - fs[#fs + 1] = "image[12.15," .. y - 0.04 .. ";0.9,0.06;" .. - tpath .. "side_menu_divider.png]" + fs[#fs + 1] = fmt("image[%s,%s;0.9,0.06;%sside_menu_divider.png]", x + 0.1, y - 0.06, tpath) end local btn_name = self.name .. "_side_" .. i - fs[#fs + 1] = "style[" .. btn_name .. ";bgimg=" + fs[#fs + 1] = fmt("style[%s;bgimg=", btn_name) - local texture_prefix = btn.texture_prefix or btn.tab_name - if btn.tab_name and btn.tab_name == selected_tab then + local tab_name = btn.tab_name or btn.tab_name_selected + local texture_prefix = btn.texture_prefix or tab_name + if tab_name and tab_name == selected_tab then fs[#fs + 1] = btn.texture_selected or tpath .. texture_prefix .. "_menu_selected.png" else fs[#fs + 1] = btn.texture or tpath .. texture_prefix .. "_menu.png" fs[#fs + 1] = ";bgimg_hovered=" - fs[#fs + 1] = btn.texture_hover or tpath .. texture_prefix .. "_menu_hover.png]" + fs[#fs + 1] = btn.texture_hover or tpath .. texture_prefix .. "_menu_hover.png" end fs[#fs + 1] = "]" - fs[#fs + 1] = "image_button[12.1," .. y .. ";1,1.3;;" .. btn_name .. ";;true;false]" - fs[#fs + 1] = "tooltip[" .. btn_name .. ";" .. btn.tooltip .. "]" + fs[#fs + 1] = fmt("image_button[%s,%s;1,1.35;;%s;;true;false]", x + 0.09, y, btn_name) + fs[#fs + 1] = fmt("tooltip[%s;%s]", btn_name, btn.tooltip) end - return table.concat(fs) + if darken then + fs[#fs + 1] = fmt("style[cancel;bgimg=%sside_menu_darken.png;bgimg_middle=30]", tpath) + fs[#fs + 1] = fmt("image_button[%s,%s;1.15,%s;;cancel;;true;false]", x, bg_y, side_menu_h) + + -- Reset "cancel" button styling + fs[#fs + 1] = "style[cancel;bgimg=;bgimg_middle=]" + end end -local function get_formspec(self) - local formspec = "" - - if not self.hidden and (self.parent == nil or not self.parent.hidden) then - local name = self.tablist[self.last_tab_index].name - - if self.parent == nil then - local tsize = self.tablist[self.last_tab_index].tabsize or - {width=self.width, height=self.height} - formspec = formspec .. - string.format("size[%f,%f,%s]",tsize.width + 2,tsize.height + 1, - dump(self.fixed_size)) .. - "bgcolor[#0000]" .. - "listcolors[#000;#000;#000;#dff6f5;#302c2e]" .. - "container[1,1]" .. - "background9[-0.2,-1.26;" .. tsize.width + 0.4 .. "," .. - tsize.height + 1.75 .. ";" .. defaulttexturedir_esc .. - "bg_common.png;false;40]" .. - get_side_menu(self, name) - end - - -- formspec = formspec .. self:tab_header() - formspec = formspec .. self:button_header() .. - self.tablist[self.last_tab_index].get_formspec( - self, - name, - self.tablist[self.last_tab_index].tabdata, - self.tablist[self.last_tab_index].tabsize - ) - - if self.parent == nil then - formspec = formspec .. "container_end[]" +-------------------------------------------------------------------------------- +local function add_button_header(self, fs, fs_w) + local visible_tabs = {} + for _, tab in ipairs(self.tablist) do + if not tab.hidden and tab.caption ~= "" then + visible_tabs[#visible_tabs + 1] = tab end end - return formspec + + local x = 1.5 + local w = (fs_w - 0.53) / #visible_tabs + for i = 1, #visible_tabs do + local caption = visible_tabs[i].caption + local side = i == 1 and "left" or (i < #visible_tabs and "middle" or "right") + local btn_name = self.name .. "_" .. i + if i == math.abs(self.last_tab_index) then + side = side .. "_pressed" + end + + fs[#fs + 1] = btn_style(btn_name, side) + fs[#fs + 1] = fmt("style[%s;content_offset=0;font_size=+1]", btn_name) + fs[#fs + 1] = fmt("image_button[%s,0.25;%s,0.9;;%s;%s;true;false]", + x, w + 0.03, btn_name, caption) + x = x + w + end +end + +-------------------------------------------------------------------------------- +local function get_formspec(self, popup_w, popup_h, popup_fs) + if (self.hidden or (self.parent and self.parent.hidden)) and not popup_fs then + return "" + end + + local fs = {} + + local current_tab = self.tablist[self.last_tab_index] + local content, prepend_override = current_tab.get_formspec(self, + current_tab.name, current_tab.tabdata, current_tab.size) + local real_coords = current_tab.formspec_version and current_tab.formspec_version > 1 + local w, h + if prepend_override then + fs[#fs + 1] = prepend_override + elseif not self.parent then + fs[#fs + 1] = "formspec_version[4]" + + local s = current_tab.tabsize or self + w, h = s.width, s.height + if not real_coords then + w = w * 1.25 + 0.6 + h = h * 1.15 + 0.9 + end + fs[#fs + 1] = fmt("size[%s,%s]", w + 2.5, h + 1.15) + + -- Background + fs[#fs + 1] = "bgcolor[;neither]" + fs[#fs + 1] = "listcolors[#000;#000;#000;#dff6f5;#302c2e]" + fs[#fs + 1] = fmt("background9[1.25,0;%s,%s;%sbg_common.png;false;32]", + w, h + 1.15, defaulttexturedir) + + add_button_header(self, fs, w) + + -- This container isn't ideal for real_coordinates formspecs but + -- keeps compatibility with existing code + fs[#fs + 1] = "container[1,1]" + fs[#fs + 1] = "real_coordinates[false]" + end + + fs[#fs + 1] = content + + if not prepend_override and not self.parent then + -- Make sure that real_coordinates is enabled + fs[#fs + 1] = "real_coordinates[true]" + fs[#fs + 1] = "container_end[]" + + -- Darken background + if popup_fs then + -- This styling gets reset in add_side_menu + fs[#fs + 1] = fmt("style[cancel;bgimg=%sbg_darken.png;bgimg_middle=32]", tpath) + fs[#fs + 1] = fmt("image_button[1.25,0;%s,%s;;cancel;;false;false]", + w, h + 1.15) + end + + -- Add the side menu after the darkened background + add_side_menu(self, fs, current_tab.name, w + 1.175, h + 1.15, popup_fs) + + -- Draw the popup + if popup_fs then + fs[#fs + 1] = fmt("container[%s,%s]", (w + 2.5 - popup_w) / 2, + (h + 1.15 - popup_h) / 2) + fs[#fs + 1] = fmt("style[popup_bg;bgimg=%sbg_common.png;bgimg_middle=32]", + defaulttexturedir) + fs[#fs + 1] = fmt("image_button[0,0;%s,%s;;popup_bg;;false;false]", + popup_w, popup_h) + fs[#fs + 1] = popup_fs + fs[#fs + 1] = "container_end[]" + end + + -- Disable real_coordinates again in case there are other UI elements + -- (like the game switcher in buttonbar.lua) + fs[#fs + 1] = "real_coordinates[false]" + end + + return tconcat(fs) end local set_tab_by_name @@ -207,69 +281,6 @@ local function handle_events(self,event) return false end - --------------------------------------------------------------------------------- ---[[local function tab_header(self) - - local captions = {} - for i = 1, #self.tablist do - captions[i] = self.tablist[i].caption - end - - local toadd = table.concat(captions, ",") - return string.format("tabheader[%f,%f;%s;%s;%i;true;false]", - self.header_x, self.header_y, self.name, toadd, - math.max(self.last_tab_index, 1)) -end]] - - --------------------------------------------------------------------------------- -local function button_header(self) - local visible_tabs = {} --- local btn_widths = {} --- local total_width = 0 - for i, tab in ipairs(self.tablist) do - if not tab.hidden and tab.caption ~= "" then - visible_tabs[#visible_tabs + 1] = tab - - -- local w = math.max(utf8.len(core.get_translated_string(tab.caption)), 10) - -- btn_widths[#visible_tabs] = w - -- total_width = total_width + w - end - end - - local toadd = "" --- local coords_per_char = 12 / total_width - - -- The formspec is 15.4875 "real" coordinates wide - -- local x = (12.39 - total_width) / 2 - 0.3 - local x = -0.1 - local w = 12 / #visible_tabs - for i = 1, #visible_tabs do - local caption = visible_tabs[i].caption - -- local w = btn_widths[i] * coords_per_char - local side = "middle" - if i == 1 then - side = "left" - elseif i == #visible_tabs then - side = "right" - end - local btn_name = self.name .. "_" .. i - if i == math.abs(self.last_tab_index) then - side = side .. "_pressed" - end - - toadd = toadd .. - btn_style(btn_name, side) .. - "style[" .. btn_name .. ";content_offset=0]" .. - "image_button[" .. x .. ",-1.1;" .. w + 0.22 .. ",0.9;;" .. - btn_name .. ";" .. caption .. ";true;false]" - x = x + w - end - - return toadd -end - -------------------------------------------------------------------------------- local function switch_to_tab(self, index) --first call on_change for tab to leave @@ -387,8 +398,6 @@ local tabview_metatable = { set_fixed_size = function(self,state) self.fixed_size = state end, add_side_button = add_side_button, --- tab_header = tab_header, - button_header = button_header, handle_tab_buttons = handle_tab_buttons } diff --git a/builtin/mainmenu/dlg_contentstore.lua b/builtin/mainmenu/dlg_contentstore.lua index 415256fc5..c10b039f7 100644 --- a/builtin/mainmenu/dlg_contentstore.lua +++ b/builtin/mainmenu/dlg_contentstore.lua @@ -457,7 +457,8 @@ local confirm_overwrite = {} function confirm_overwrite.get_formspec() local package = confirm_overwrite.package - return "size[11.5,4.5]" .. + return "size[11.5,4.5]bgcolor[#0000]" .. + "background9[0,0;0,0;" .. defaulttexturedir_esc .. "bg_common.png;true;40]" .. "label[2,2;" .. fgettext("\"$1\" already exists. Would you like to overwrite it?", package.name) .. "]".. btn_style("install", "red") .. diff --git a/builtin/mainmenu/dlg_version_info.lua b/builtin/mainmenu/dlg_version_info.lua index 330151057..ff9a1cf18 100644 --- a/builtin/mainmenu/dlg_version_info.lua +++ b/builtin/mainmenu/dlg_version_info.lua @@ -47,6 +47,7 @@ local function version_info_formspec(data) image[4.9,0;2.5,2.5;%slogo.png] style[msg;content_offset=0] image_button[1,2;10,0.8;;msg;%s;false;false] + %s hypertext[1.3,2.6;10,2;;
%s
] %s button[2,4.5;4,0.8;version_check_remind;%s] @@ -55,6 +56,7 @@ local function version_info_formspec(data) ]]):format( defaulttexturedir_esc, esc(data.title), + scrollbar_style("hypertext", true), esc(changes), btn_style("version_check_remind", "yellow"), fgettext("Cancel"), diff --git a/builtin/mainmenu/init.lua b/builtin/mainmenu/init.lua index 8920f6ee4..69dd10ef4 100644 --- a/builtin/mainmenu/init.lua +++ b/builtin/mainmenu/init.lua @@ -74,7 +74,7 @@ local func = loadfile(basepath .. DIR_DELIM .. "hosting" .. DIR_DELIM .. "init.l -------------------------------------------------------------------------------- local function main_event_handler(tabview, event) - if event == "MenuQuit" then + if event == "MenuQuit" and PLATFORM ~= "iOS" then core.close() end return true @@ -111,6 +111,33 @@ function menudata.init_tabs() -- Create main tabview local tv_main = tabview_create("maintab", {x = 12, y = 5.4}, {x = 0.1, y = 0}) + tv_main:add_side_button({ + tooltip = fgettext("Browse online content"), + tab_name_selected = "content", + is_open_cdb = true, + on_click = function(this) + if #pkgmgr.games > 1 or (pkgmgr.games[1] and pkgmgr.games[1].id ~= "default") then + this:set_tab("content") + else + local dialog = create_store_dlg() + dialog:set_parent(this) + this:hide() + dialog:show() + end + end, + }) + + tv_main:add_side_button({ + tooltip = fgettext("Settings"), + tab_name = "settings", + }) + + tv_main:add_side_button({ + tooltip = fgettext("Credits"), + tab_name = "credits", + texture_prefix = "authors" + }) + for i = 1, #pkgmgr.games do if pkgmgr.games[i].id == "default" then tv_main:add(tabs.local_default_game) @@ -152,17 +179,6 @@ function menudata.init_tabs() end end - tv_main:add_side_button({ - tooltip = fgettext("Settings"), - tab_name = "settings", - }) - - tv_main:add_side_button({ - tooltip = fgettext("Credits"), - tab_name = "credits", - texture_prefix = "authors" - }) - ui.set_default("maintab") check_new_version() diff --git a/builtin/mainmenu/tab_content.lua b/builtin/mainmenu/tab_content.lua index 0ee815257..5380dba7b 100644 --- a/builtin/mainmenu/tab_content.lua +++ b/builtin/mainmenu/tab_content.lua @@ -99,10 +99,13 @@ local function get_formspec(tabview, name, tabdata) desc = info.description end + local pkg_name = selected_pkg.name + pkg_name = (pkg_name:sub(1, 1)):upper() .. pkg_name:sub(2) + retval = retval .. "image[5.5,0;3,2;" .. core.formspec_escape(modscreenshot) .. "]" .. "image[5.5,0;3,2;" .. defaulttexturedir_esc .. "gui" .. DIR_DELIM_esc .. "cdb_img_corners.png;15]" .. - "label[8.25,0.6;" .. core.formspec_escape(selected_pkg.name) .. "]" .. + "label[8.25,0.6;" .. core.formspec_escape(pkg_name) .. "]" .. "background9[5.6,2.3;6.2,2.4;" .. defaulttexturedir_esc .. "desc_bg.png;false;32]" if selected_pkg.type == "mod" then @@ -150,8 +153,8 @@ local function get_formspec(tabview, name, tabdata) end end - retval = retval .. "textarea[5.85,2.2;6.35,2.9;;" .. - fgettext("Information:") .. ";" .. desc .. "]" + retval = retval .. scrollbar_style("textarea", true) .. + "textarea[5.83,2.23;6.33,2.89;;" .. fgettext("Information:") .. ";" .. desc .. "]" if core.may_modify_path(selected_pkg.path) then retval = retval .. diff --git a/builtin/mainmenu/tab_local.lua b/builtin/mainmenu/tab_local.lua index f3f1c58fe..e76df9658 100644 --- a/builtin/mainmenu/tab_local.lua +++ b/builtin/mainmenu/tab_local.lua @@ -159,7 +159,9 @@ local function get_formspec(_, _, tab_data) btn_style("switch_local_default") .. "style[switch_local_default;fgimg=" .. defaulttexturedir_esc .. "switch_local_default.png;fgimg_hovered=" .. defaulttexturedir_esc .. "switch_local_default_hover.png;padding=" .. (is_high_dpi() and -42 or -30) .. "]" .. - "image_button[10.6,-0.1;1.5,1.5;;switch_local_default;;true;false]" + "real_coordinates[true]" .. + "image_button[13.98,0.31;1.6,1.6;;switch_local_default;;true;false]" .. + "real_coordinates[false]" end local enable_server = core.settings:get_bool("enable_server") @@ -310,7 +312,7 @@ local function main_button_handler(this, fields, name, tab_data) world.name ~= "" then local index = menudata.worldlist:get_raw_index(selected) local game = pkgmgr.find_by_gameid(world.gameid) - local delete_world_dlg = create_delete_world_dlg(world.name, index, game.name) + local delete_world_dlg = create_delete_world_dlg(world.name, index, game and game.name or world.gameid) delete_world_dlg:set_parent(this) this:hide() delete_world_dlg:show() diff --git a/builtin/mainmenu/tab_local_default.lua b/builtin/mainmenu/tab_local_default.lua index b33e20893..cba0d5685 100644 --- a/builtin/mainmenu/tab_local_default.lua +++ b/builtin/mainmenu/tab_local_default.lua @@ -17,14 +17,6 @@ local small_screen = (PLATFORM == "Android" or PLATFORM == "iOS") and not core.settings:get_bool("device_is_tablet") -local default_worlds = { - {name = "World 1", mg_name = "v7p", seed = "15823438331521897617"}, - {name = "World 2", mg_name = "v7p", seed = "1841722166046826822"}, - {name = "World 3", mg_name = "v7p", seed = "CC"}, - {name = "World 4", mg_name = "valleys", seed = "8572"}, - {name = "World 5 Flat", mg_name = "flat", seed = "2"} -} - local function menu_render_worldlist() local retval = {} @@ -48,46 +40,7 @@ local function menu_render_worldlist() return table.concat(retval, ",") end -local function create_default_worlds() - if #menudata.worldlist:get_list() > 0 then return end - - local _, gameindex = pkgmgr.find_by_gameid("default") - if not gameindex or gameindex == 0 then return end - - -- Preserve the old map seed and mapgen values - local old_map_seed = core.settings:get("fixed_map_seed") - local old_mapgen = core.settings:get("mg_name") - - -- Create the worlds - for _, world in ipairs(default_worlds) do - core.settings:set("fixed_map_seed", world.seed) - core.settings:set("mg_name", world.mg_name) - core.create_world(world.name, gameindex) - end - - -- Restore the old values - if old_map_seed then - core.settings:set("fixed_map_seed", old_map_seed) - else - core.settings:remove("fixed_map_seed") - end - if old_mapgen then - core.settings:set("mg_name", old_mapgen) - else - core.settings:remove("mg_name") - end - - menudata.worldlist:refresh() -end - -local checked_worlds = false local function get_formspec(this) - -- Only check the worlds once (on restart) - if not checked_worlds then - create_default_worlds() - end - checked_worlds = true - local index = filterlist.get_current_index(menudata.worldlist, tonumber(core.settings:get("mainmenu_last_selected_world"))) if not index or index < 1 then @@ -130,12 +83,7 @@ local function get_formspec(this) "tableoptions[background=#0000;border=false]" .. "tablecolumns[" .. image_column(fgettext("Creative mode")) .. ";text]" .. scrollbar_style("sp_worlds") .. - "table[0,0;6.28,4.64;sp_worlds;" .. menu_render_worldlist() .. ";" .. index .. "]" .. - - btn_style("switch_local") .. - "style[switch_local;fgimg=" .. defaulttexturedir_esc .. "switch_local.png;fgimg_hovered=" .. - defaulttexturedir_esc .. "switch_local_hover.png;padding=" .. (is_high_dpi() and -42 or -30) .. "]" .. - "image_button[10.6,-0.1;1.5,1.5;;switch_local;;true;false]" + "table[0,0;6.28,4.64;sp_worlds;" .. menu_render_worldlist() .. ";" .. index .. "]" local enable_server = core.settings:get_bool("enable_server") if enable_server then diff --git a/builtin/mainmenu/tab_online.lua b/builtin/mainmenu/tab_online.lua index 410230741..297292ffb 100644 --- a/builtin/mainmenu/tab_online.lua +++ b/builtin/mainmenu/tab_online.lua @@ -94,6 +94,7 @@ local function get_formspec(tabview, name, tabdata) end if selected.description then retval = retval .. + scrollbar_style("textarea", true) .. "textarea[7.5,2.2;4.8,3;;" .. esc((gamedata.serverdescription or ""), true) .. ";]" end end diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 81d8b5d4e..cdcdc57be 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -1862,7 +1862,7 @@ void GUIFormSpecMenu::parseHyperText(parserData *data, const std::string &elemen spec.sound = style.get(StyleSpec::Property::SOUND, ""); GUIHyperText *e = new GUIHyperText(spec.flabel.c_str(), Environment, - data->current_parent, spec.fid, rect, m_client, m_tsrc); + data->current_parent, spec.fid, rect, m_client, m_tsrc, style); e->drop(); m_fields.push_back(spec); diff --git a/src/gui/guiHyperText.cpp b/src/gui/guiHyperText.cpp index 7763ae1a2..8b480c512 100644 --- a/src/gui/guiHyperText.cpp +++ b/src/gui/guiHyperText.cpp @@ -997,7 +997,7 @@ void TextDrawer::draw(const core::rect &clip_rect, //! constructor GUIHyperText::GUIHyperText(const wchar_t *text, IGUIEnvironment *environment, IGUIElement *parent, s32 id, const core::rect &rectangle, - Client *client, ISimpleTextureSource *tsrc) : + Client *client, ISimpleTextureSource *tsrc, const StyleSpec &style) : IGUIElement(EGUIET_ELEMENT, environment, parent, id, rectangle), m_client(client), m_vscrollbar(nullptr), m_drawer(text, client, environment, tsrc), m_text_scrollpos(0, 0) @@ -1019,6 +1019,7 @@ GUIHyperText::GUIHyperText(const wchar_t *text, IGUIEnvironment *environment, m_vscrollbar = new GUIScrollBar(Environment, this, -1, rect, false, true); m_vscrollbar->setVisible(false); + m_vscrollbar->setStyle(style, tsrc); } //! destructor diff --git a/src/gui/guiHyperText.h b/src/gui/guiHyperText.h index 368912e53..d167f2952 100644 --- a/src/gui/guiHyperText.h +++ b/src/gui/guiHyperText.h @@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once #include "config.h" // for USE_FREETYPE +#include "StyleSpec.h" using namespace irr; @@ -201,7 +202,7 @@ public: GUIHyperText(const wchar_t *text, gui::IGUIEnvironment *environment, gui::IGUIElement *parent, s32 id, const core::rect &rectangle, Client *client, - ISimpleTextureSource *tsrc); + ISimpleTextureSource *tsrc, const StyleSpec &style); //! destructor virtual ~GUIHyperText(); diff --git a/textures/base/pack/gui/bg_darken.png b/textures/base/pack/gui/bg_darken.png new file mode 100644 index 0000000000000000000000000000000000000000..3ea1408c0eca70c2bd399ff848155027cb82d5c8 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K585o&?RN5XZRUpL{;1l8sq=8^*`p)w}im4>X zFW80QQJcFZkQeOf;uunK>+P+JoDB{luh7Z{Fw0Ucj*S{Y`3H} zE1Es_a=f##c%AU<;EHB#{yu#skfA{E?Nj^Oo%?5e5C8qIc){Pe3Wn^NN^kXLr_KXO Ndb;|#taD0e0sx(7IIREx literal 0 HcmV?d00001 diff --git a/textures/base/pack/gui/content_menu.png b/textures/base/pack/gui/content_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..90d45e51be891e1702750efc53bb4b8bf2fb6dbc GIT binary patch literal 822 zcmV-61Ihe}P)+9=GOiZ73 zb)cZ2wxy-zi2%oU0K$!p*UinX+5Zk?y$4mR3jhEB0d!JMQvg8b*k%9#0+UHZK~#8N z?b7FN+fWRKVe<^l;hoX@ztEB&B~x~IEVM=c=`B(N0r-fbbNK)5?d^Sj{^L9<0#((v z8}naZ_$e4&*K+Tl4+E7}_-MDDZ;rEq09}Ew=i8^ZLRsjSS^F8>9j0#bPullppvy3L zJKQ07C+#Jh9|lL@xe0=M(i@1|GB3jA=MEDD|D^p*40dE5!o}GELgA!5&4wt;Jm0}v zqMPibuYw>DFfW3$1UH}56=2A`FX$5Mldi)Xz>sMOcFEF7ol8m(^pg3Jf6}M$1}1RB zkegbns;X9`mF%Ri!eZe0SmV2C8j=Eq5OTX@Cv^xm@OTj#M63jffe#4;PWmGea7jee ze1p&>C@^rBm^c)(zo-ycm?H$hh+-i%@<*LvVS|H%_`4x2PM5ZBZtm{xV`F2u-v7>s zA?TMOzp=5ahli}Jtje66+|$!7c*Y$kEB*ig00DGTPE!Ct=GbNc00N9jL_t(|UhUH9 zZsRZvh0)RK-PyXn|BDWE*;!nNP~e03@-02mrXp4-0HR%i=rp4Hb_-C-W)`bpPSjnw-%)^@l- zsGf91IzNu3fVmk${iJV+c+2w;-pd_k3e}UYZ!pB+ya?}=9g@&EsZ5IjCC~E?#S+7; zCw&!wK;S%uVhKr4S_;X)yb9$K+mmkN6TpyZ3VO-bNsCLeB=C~vQRAfB(i5m4jib4A zD8|?k>5-na5MWTixCj@?B4?d*rqAg~D})&7;~`v9RuqQ>xFQfdX%Pfo5?Om;T*5j5 zZs-c3mHtOLM}Y()phPPQ-Z>@gR*X?g1di7+}g{3?KlQAAz(0fi4R?gb+yHz1cegg3xt&2h``hZxIFnvyMU+ z;z3mjz#IiI6>yQ#6_@Dq=2vh~+p9~A)1+W%CQ;;pW@!jAb{3ec<0tgin5njtg3n1Z9 zB0_vEs6e317`u?5aN71H7yu1J2o?xvDsaASWMP^@ynJ-*$9#bo3YJr$R~pd+PxJ0000i%@<*LvVS|H%_`4x2PM5ZBZtm{xV`F2u-v7>s zA?TMOzp=5ahli}Jtje66+|$!7c*Y$kEB*ig00DGTPE!Ct=GbNc00N9jL_t(|UhUH9 zZsRZvh0)RK-PyXn|BDWE*;!nNP~e03@-02mrXp4-0HR%i=rp4Hb_-C-W)`bpPSjnw-%)^@l- zsGf91IzNu3fVmk${iJV+c+2w;-pd_k3e}UYZ!pB+ya?}=9g@&EsZ5IjCC~E?#S+7; zCw&!wK;S%uVhKr4S_;X)yb9$K+mmkN6TpyZ3VO-bNsCLeB=C~vQRAfB(i5m4jib4A zD8|?k>5-na5MWTixCj@?B4?d*rqAg~D})&7;~`v9RuqQ>xFQfdX%Pfo5?Om;T*5j5 zZs-c3mHtOLM}Y()phPPQ-Z>@gR*X?g1di7+}g{3?KlQAAz(0fi4R?gb+yHz1cegg3xt&2h``hZxIFnvyMU+ z;z3mjz#IiI6>yQ#6_@Dq=2vh~+p9~A)1+W%CQ;;pW@!jAb{3ec<0tgin5njtg3n1Z9 zB0_vEs6e317`u?5aN71H7yu1J2o?xvDsaASWMP^@ynJ-*$9#bo3YJr$R~pd+PxJ0000@jRu?6^qxB_V)Sem}`Jdk243Gxee zVR+Q$ZVBYsd%8G=R4`t>WXOBKfrsVbWS#>P&d5&{URw26;Y1j7!sMIlnI%7{DM^WR tNL*OJ@FP{#p_#FIu|xCTjp{ay(QN$Z0w@O1TaS?83{1OR!cELs2n literal 0 HcmV?d00001 diff --git a/textures/base/pack/switch_local.png b/textures/base/pack/switch_local.png deleted file mode 100644 index a7ee82b0a936b6a063e073e985d0f28dc3b167c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 816 zcmV-01JC@4P)c*45qiuG#k+W0RQnUt65o(N=k5Wa1Atv>+9=GOiZ73 zb)cZ2wxy-zi2%oU0K$!p*UinX+5Zk?y{SQjxBvhE0d!JMQvg8b*k%9#0*y&TK~#8N z?UGlH+dvQncOqj@+T{Bm)cxjZ)D*Wp3&VfLmPiR8P&LhlUXJ|m{{C;e&`6{-j&1$p zgSYKZ(6$SHfIryi(6C|s7sn&1@y zYnwAreOZivXafS~Hg7YyRULuL*9is&tZmLWB;=+pfr~Lg3E0~dSrUj;9Xl{ammq<#0OY9!l+uT#e*MP7rU7tZp zDYG#G-R2=s6FeP5eD;0sfOp>eZmj4wjlyj%ha=DzoLnA=`36wnHjf~{B?9OAPZk6( zm-w$h3J^^6kK{#x%>tm`C=dpM_gZlKz#!|NG+@xpOQ0{8>Yi^ffM%cz)cM}& zP@jRKQ;sph|JwkkfS*!|<;gfsD8TPpK15GH*8rCw1t7nn`(^3EV623If*tU8 zoM#}%bdmrGMVGh+i~#^A$RM6hr|9ShaZwIl3s%69tO1e9Js{YD>Sv+>jExTu2rL*r z@_P8M2oM0l6;NmdfcgnYAc0u)c0hFo*5b2p#wNMUO)vso)&Pm?`UtEg5Vn9XjH(3< z;JG&n@Ym>lamlvX0nGSRxJm*3l|IB;Fak~jrI4Qr)xV21knKPzXuzRxzRyoK`py{v z$m9_SaXp{aXJHfUfb&2L5(rU!veCB!AUq`;3J2dg_+|ip2t4kd;DfM(wg!|=1Emm; z)Pnj(A%Ied=}6Ro<)hHKjRgiydo%zYzMYT)iS!i>sBR`|U|p|!)-}>sy`6~k6$Vsq uCD7R75!jY)H-OtAu5Gs~%FBPw55ECJ*+8KN!RfdF0000Kpira6^A(+-JL+fYb>ctA6ZBhG#^ z1Zx?d=`TP5bSTD^5J%$-)lsgbsLI+bT8sc|c% zWGAs+Ct_3}OaK4?0d!JMQvg8b*k%9#1(Ws?H~+AACUs#lysEak^leA z7sg$e&c0eXn}4%H|NVJV`emH>7mAcbgXM>clycEZ#?9~pMM?nHOv;@AcuLKE_7mW%zyC^e%QIV1cTy=)#;=Px!ZTEZ{ch{h?Fk%AYK$>l5XJ_Y= zM?-ol5Q>;KT{&0C1eK@D$-tbH?>VRh=5nvV(W?+^gvhH)VwT6qCLUC(&DyVgg zJtR5H%E6*?GZx0g*W0~Wvf84$Z?7t(+S*~S0h6c#)ImgmsF({|q+2sW$$nAyvAwL2 zF800dK{VNCd-Ebptng_8vj`?OX4AHvy{M2bmw#6G3k}OS97GmnU^dAaFf$F9-BDvy zZPa>ecp|v6i=|VvYjwn1O7Ebqi<@WSrmU;Ej5<5k7}hJn^+D}F8RfYhI|u{ebGP7N zZ%H>s=YTM*`x4TV_kXb~rN_Lnj4jL?ljH$W<@8c zBmpEdw5}E!a1O8z@z5Xutk+r=Yf4HX_&wq=I3XT+scSAv*EKeCK-;-~7_CR#Zlu;G z=R!#*CyP8UC9AB+UPu9?Zkz+A&K+ZD(SO~joshYq>ZB}q-Hb4bw#92}DYF7S;D`Sw zAa#}i?)C<=^-hS@cDsHb&QdX;lDVvMS<{8XJKwlJfV+^ou8qz8?Hxdt6+#$8E?QS9 zLdeP(I6W0bu?E*;)4c<(ezXv}(Y8}}pL&n51SoZ0kx#G5Ez4X>IK4Opcvzx+{C^Da z6L3r+`8FQ97@r(2HwZv&OQS1Qk^lj~$9j3d!UjicTYYn?? zUGe~O?+oZ~ytCeZ1i1bIIF5I5io?-PQ|tynZ#@7Y6oxxwKLh&V#k=lw?q@(Zruf

T-vO-8 zXZ`H@^xscF=cjNuJO%5*U3zq#b=df^-K-FS{4$#3t#%K;@_(@wpr5$& zMHskjm&6THEuCp%ZGv$v3DIMRaQW^oNX7FlEas|Z62H89&Y@mR4wS3 z)fW{O+`(#vrb54fKHzAVn%$~5_(~g3UaA%_vB%(q;tGX(CYsDfY=WD?_{Wwj-nf}p z{7~?kShA|V!jO5#lhDE>z<=b%eXyJ8Qumd&sU&u2r54a8MAbQ9qMaln27>6EYxn#8 z&Cpz;1t>UKNi_!l3v5VYMoume=13%@f}X}<7!GE*GeJj1)F~5U?CVFLDR`RaBn&Q~ z3dJNkXAw2Qako1g?wS*7uiynyZg{OgOlhI0AcZ<$LS11$w!`7bU4QfB@m&)Dn8{^V z;g!OvBKI(9WIExzUzuQk=uSm!E*cf$r2al$DRhn?+@-ugCk#yO&<=yw@~U~W z2NyAE`K|}QbEv@&VMcC(;n?PszWd7|Is4>~=N8P?`G-C|Ijf%yf<*XfBNhB-#?!>Z9dzMRy1+?00000NkvXXu0mjfmzPGU delta 1861 zcmV-L2fFy&4bu*gBYy#aP)t-s|NsBh-S!}75F>FBCUy}eauYeS87PGmB4`mPd=eZ` z4k?ZlE}j-3Sq=aI04a+UER_`}dJ+Hs|Nr-hBW)2fq!%@+7yt1rD1#F6rU3uXB`8r1 zCP)k>P7NqY3@Ka=AxsS}K3n^m{CRGk1Jqs#o5GipGBY$5HErAj=m=zi{3MhFI zsbMx5LJTX06E1iX8957~Mj&!A7Z*JYel-~_eiC{!7%Gkw-JL;>Ivc%WD1tW|Bx(^b zj1;F!Ah1&Wo`kh# zEi;1?-kd&$Ie!{5brNqb7pqJmx?3n_G8E{uP{wdBjy@dGo>K!$K)druvZWF>=DACpKSnOY;pi8to5Pp(`g z#BVNiHWz$38OnSzmQf$ophU=+RK+=uumAV0AzD7rD@qc5!RCk0K=eeLUU!n_(cLg9bQA(80`9!^{sbWPaTrEl@ z<;lr|r+=izC+LI?3gp0m!JQIenf!-|XN`~O)@EEl1hf_@gvN`MPyH8(500-b*c{Q- zte_f#_g0@Tc%CRfpf?SG6=qQ<0xFU+aeD`^CCYc|%v@C>5fO=mQVY?0X2o*1+dbNN zf5DinR_|5wG@qG>sS&YOggM6YnV)!1!DJa|I)4OaYXOleQH+2w=D9{KpYc5Lc7U=( z3M7bB0g!WKVF2%|idYh^fRuQ5!R(9T>2#u?8brJbNbt3U1SOae3g^r6Y2nSl;n+GS zLbAO`?*TY4pXYUw4YmR5jl88+fYqX z6Cy;|eh@dd(>V0w+4QvVdcdBaPwU!s`(=p{Y9X+4>QpM0vqcVwb^}ouuKRRRBbeX}UZxscYcluQ_Wsw=lNwpT&o9aeVeCtTsrJJC=KluT z*p6H%#3NvYK^(lo*au71k%$l=3Q3T1*5zFG`u#eC!O)Dx%BsnN0G_8gi5m|pjDL7! z7(|dl6y+E{ZJU|;RNKIne%3K&@iS+DOVW_WPgW3P5C#}dQj&v^s*t_8n%5buxphC# z8=IeAiN>SV?iUE6EX$t6Syu7I{}>369o3tUtoyG2*FdAe*0y;)5n|fyvPP7UG>*dz z3!r#W6g#`Pa<->CwFaYo=e#@EI)AkG)suyMI)xnaoMagd@}nd5sAx7{+F{w-bH^w8 zyTQA^433ZYwRdjckIkot4apZp+F&e?gXoksl=;+r(|mcR_h#qkYir;2{~GM?550HZ zUzEL(1Z$W3AV&-JLxfj+B%pNd$nr{Mvq5EXfVT0JP?oQwQcW zx#b+z)`G1CjVuSdE7h)YO?sJ`nfKSz3dhTI%e%ifW0XA9_FXYeJIol&8NLQcm;`gO z7^M3hG`l<7;Cb(Z=g&q)$A6-t0T~8VUH#L6gd_>*!6xXM7HnrdKD0m7zsVWFff&+Z*R}0b*TNLE9zGR%lN z2}Deg3Xzi_=p4xW=y;q&bwz!(O&)4z4tGW>11FG1-w`7*Ib0kaU;0@v-yw1}_0LQY zm8h4&p)d;}Q9ivqzJIb33r}Kz8NoqCuOtAGICw-BAX@#J&ySC-t*vX}iJ=mf&eSXa zB5}-s5a|)VuH-m#uMXgRX;nCBbDAJg89}Kw}!ThwTZy-T9~u+vlFgF%fdUm zd!e;3y0n%BMAIau&iT{&dgJ3d={nO|5wJj!miZXX@( z3@y(u@2}l_;omu4Iyt=EC&#ktw?Xy)+&kX@6=N9t3H3VC00000NkvXXu0mjfm$hj0 diff --git a/textures/base/pack/switch_local_default_hover.png b/textures/base/pack/switch_local_default_hover.png index fc599d1b8b910890db40dfb219a4fc5d5c2e65ff..3fde564a114706a88192f89bba702ff899e41d4c 100644 GIT binary patch delta 1699 zcmV;U23+~!4zdl9BYyzEP)t-s|NsB$@cb%>6)~O{D0~w|&mKFz93^KFFq0N6Tn{s- z7&fvQ00030|NsB|qyPFfQItXY!vO#0EiY>kDpL+GV-PTR5;KDn96}7mbwEYE9KdHS z!&xYhI~}J)A@8k0d!JMQvg8b*k%9#1)xbpK~#7F+|fsZV<8ZO;VG#AS>ccec13(M=Oh7RR7oTq@r@jd zbCVN#Yeh^EU(9pDNG2eWy?4Odd!Oc2ISr^aDO2jpcDLK#nj0VHMBWfxt=Ueyr?#^{ zOm`da<+5pkq-m>qhsa*W_O^eRcr&loEsdN2mN;puxqoo~2g{oa5yzBTYrx8@XgL9- z=oHo+Je%0QemDV1jn%{5vIN-xIkY{UPUq!uA)XFUv&)ghL|T;s#?Zv9-nX~?^43CJ zu44d_Nbo+N6!s9vYH`3@+pQzun103*%wPUs=+Cft!Onk_Q-occ&g4 z5#InLB7Z~7KG@k$1(*m&M`RLq-=$qSM<7mw&j2D71n&}Z_Gc{P`zN1aa%-V+S58Mb z;R}G7$VfCsKk0u*f;%^TrhcDIhyh*&o4-o{KuMTc6~2c64ZgqE3c298vq;>LI2AV9 z6FvhvGd7GWnQK6KaI6b?a>_2sy+I^oqVwNx5`TVFqtQw+(5v)4^yZzC7~K)qy=zxi zQo)1wginBrRQM7PQzoeJB(X+76fm|ML$_N+6dGBXZk|K%C?@L%Woc`cm5b4X|9*wpd74%|^CjLRgCST|EP=7OkzXH?`If3TrVdLIUy0YcPl~39+gfbD5@g{T;BqS==sf z9Mfk;XvrYi_ZX0YD7ye7GaapBZf?Ec9%L|19v!m^3q=y~1^n7rDvqty zb~yhT@OX0#!0PFt#V{C(+!rOmAwOT$G=H(Bak`ATJ-6%C8Q^*OcyqhmzPvs?*BT=Q z%bDFz6AWqT`#R6?7Gb@$>zh5`@23=&H#e*8-OcOc?V=%!DkT{q4|s`Up<;FZJy&_} z+W+RubJ=YphQjGZ=9RlmN7w}@fLI|ItB~5nRI%Uxt+EoMnai8rbM*WB=1|*VeSa%( zUyuwfGMg~3x8ajn8IRc~ufLqVE)B{@)b-24R3U8YKt%AMKoRT|EifXmdfR?dFGG0r z=ym|}w5!6$TY+cy1WBBgIe{t*)?rJrj8>?>o_$@0u!NJM5FJA$T+R_JE0>M{<6zkdpVZC&t@p9)Z!!TNO)a@Up!atHu4d$lP|s`)4= zDfr0WJ)3N*C{a_>tdR)aaulKfQFu1nbQgY-k)H|_2oc!@48`?3fe1vI>la;DPPGU4 z$Tt%K39VUUHb&0hzkByK5((w{#c(;)rg%x=J>M7XlnGS9ogD?^Z5wh=)x=6qyZ~a8_BfUiE(1>*TtqBWi#9i z^QR>vUeStN?hC$EHgWei5`_=Eww_rPS!r|JmXm0H$;g+XR3<6EsX+Ikac{8&Js7Am zDjEPRkH_PWhUyy6sF7@ElYjrK2eanaKg1WtXbN$D}v+keVeU}Mdj8rI8E^f3U39C6@LV;-^1Ds%T*b( z{HA(Zp*8Yr_^6O%zzFMPj?6qPx7!$F7Otvf%>@6&76O?g>N=Hy*>v0UVw>IACH?N} zcFgO@%48pWGn`HV8UfFL=)zAV9%&WZi{Kmt;154JOoV{W!*Dt;dihh29$7TBI1T6H thd=%7(mj;|f9c@|Lma{XN(%nJ&kqwbzz;pyBH91|002ovPDHLkV1gR~FMa?3 delta 1875 zcmV-Z2dwzA4dD)uBYy#aP)t-s|NsBm;rBgzFF%7YL5MI@zBfdbGCq7TM2#^yXDvmY zGD)j6J8dl?At6PYGDo5_LyIu~|NsB^mp_0oPO~*rv^M|pM?{k`O|Lcdu_6D}K}2UP zL0~IHWGh5rD@1H8KVvLEVJkshD@1iIKUgb7Xe>r?EkR{0MSpxRMSw3tX)Hi&EktT8 zNOmqkVk|_4F-UqYKXooZaxOShD?wx{Ns%#8r8GBBDn*DeK4mPnc2GB3D@cwpHd8CD zUOj?JHIPv`O{p`CO*Y}GTAfun#&$$YoH9$KGqPemx@kebZbI9gQn+V7)sRi*vRscF}7nq!*E3Fy=TpXNu60a*Q;)JOftl` ztDI#!z>`n5Xh4x$IkAIA!gWK0R5jzge!qxWmV*&5KLMo@T*(Mt`zrKh~{Zyq94%gAiQ+0004W zQchCzu{?}Ef%*^fNdFK0L z`_X@Xf6O=P28{U@9j!$)=4*9Fm~o!VS0#)Q7Vio`W}=iRU+|fFRa3=^P`Fx@NXm_k z$ItkTMt{-?dnk|t1NPm32+QOT6VDr;(5=n5fB@YYQj9$>QatAIpbOH5FLxqDc?ET0wL4oqir=R`=l zgY+JNBSWr8py~fa`f&5v%9yy)ijfXxwVKKy`t?= zO;Qsg1n3@!Th9;IN6Ys3v$M0+OwQX7pcVov1E*54Bp-=HX4Cb_#opHb z<<1#k@XI^^y!@M}@Q0e|nREy=Q^zuH*`7)L?z{ve*R(Z)0psP-A-Y|tAb zbhm%FQ>$eR;2E~5hn5jVVXk<7zKbfOQk#`2{ti6<1&qgi%o*!*O7gpB&^_`skaj%T z`Z7s_kmS!F&Tk2BH>Oh|zW4tE{eFdW#`&ySy1gK%?mD308oH@L7!VRS=YJ>$@RW;$ z55&M+EW~(>h2YKREg}@vVW>s5&!!DYxZEb^w9P84Eyh1S@bWj%VtmEN7>fnth*YWw zLh`QqiUQY5@+~=Uwl}=GI8W%e027>vYKyh23qjj>L`x+c)()Yz{@Q+7@W{=?0QCEc zqDA5MXOwYn)QP2Yz0T-lNqpuDZ-%2%{d++9`C6|Pe7z5xa~?%91ny!o>HXNgsJ!W@UqJoS z0po!@2xWxbZkJ4s#@Y`v6LG2)^)r0E3Sa;U5Hd7fLzw58wapnFYJY#}O3~K2zUfb89G|!4s2f?}yG}Z+W{J07{M0brxM?kQ1LAj7%36XC@9ObI@h?db_eT z2j1Jmg~gT8RP$!*_R-OCYh_{aWc%g|zdK%D8Qt!aV@vhhp!&V@kFQ74DvQq{7v}%~ N002ovPDHLkV1nvTeysoi diff --git a/textures/base/pack/switch_local_hover.png b/textures/base/pack/switch_local_hover.png deleted file mode 100644 index a16f958c556537d78dec5a77ef1fa58c3cb8acb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 810 zcmV+_1J(SAP)i%@<+CAZk=IagM)+kyCJKGhrhA0xZeNn?(Sn_ zV=PXWtgNi)mm$uGAUk!8UE?HRo9q;Iu5(2JZ+M*PI#E zm!%0n+Yqp>c}C$}bq<``4K@VKYtCm*(8D?cCu0Ky>}!%t364}9H)vMC3G|u@relku zBhaou=rx-F60B>WUE$@L3f4!0WCWTcw%2Tq2oR7Xx+nHE_h5Yu5X<5&1Cw(eq%ksj z%|oCjFda)=2+sr`LU3b6uh|wTf#Dpu08gL5kom!&fNLJ%0FDSenLt+Xf&6!d3J@&x zA1MR`fCuoq1t5VKf)@Nfu+jM^4H&q2iQ>~o^$-x)m~OyD(aFII^oZ~K0re#SUF4J! z`+pn27EH=HC;Vj`Cn~^qJs;!6A8J63Km~@rqwDx}GzW&EYyieej3}6aQ1IA*NcqYE z5TR3C0`>wxHW(1NUa!fEAIl4gK?_#E3xft&1|>k)0r9J=0d7YAkpXBq%jdif|CI;? znCJl)Isr!g%uoQ|33@-Ex&&7EQn>LYp@%zR1l*tjA+75(up$ue5x*kdWE-GDXbbSy z6ariUD;NRV@wM=v0{aj6Bx=D3cnY8ZSqsH4Vhs#-00j+rF5JrgMHS!sHUL?824Y%o zH}xTtZU-=)K%oX=D!vBbn*k=iBs>+4zW4CI3D5)?R}%7vxI=6WC{6qyPW_