From af757cfdaa0b8979cae5a977af73ed519e31465f Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 15 May 2024 03:34:52 -0400 Subject: [PATCH] Began working on a proper default theme Going with dark mode at first, I'll also be making a lightmode, but I want to have a post-processing shader for tonemapping the app screen's tone by the user before doing so. --- Readme.md | 1 + code/app_screen.odin | 218 ++++++++---------- code/colors.odin | 27 +++ code/engine_api.odin | 14 +- code/grime_linked_list.odin | 19 +- code/grime_stack.odin | 2 +- code/grime_virtual_arena.odin | 2 +- code/tick_render.odin | 2 +- code/tick_update.odin | 2 +- code/ui_box.odin | 22 +- code/ui_floating.odin | 94 ++++---- code/ui_layout_compute.odin | 4 +- code/ui_layout_widget.odin | 19 +- code/ui_theme.odin | 138 ++++++++++- code/ui_widgets.odin | 26 ++- .../assets/sectr_host_2024-05-15_03-32-36.png | Bin 0 -> 29209 bytes scripts/build.ps1 | 12 +- 17 files changed, 380 insertions(+), 222 deletions(-) create mode 100644 docs/assets/sectr_host_2024-05-15_03-32-36.png diff --git a/Readme.md b/Readme.md index b3dcea2..1b219ec 100644 --- a/Readme.md +++ b/Readme.md @@ -59,3 +59,4 @@ They'll be elaborated in their own documentation ![img](docs/assets/sectr_host_2024-05-04_12-29-39.png) ![img](docs/assets/Code_2024-05-04_12-55-53.png) ![img](docs/assets/sectr_host_2024-05-11_22-34-15.png) +![img](docs/assets/sectr_host_2024-05-15_03-32-36.png) diff --git a/code/app_screen.odin b/code/app_screen.odin index 34f2fc8..e7a8809 100644 --- a/code/app_screen.odin +++ b/code/app_screen.odin @@ -21,7 +21,7 @@ UI_ScreenState :: struct settings_menu : struct { pos, size, min_size : Vec2, - vb_container : UI_VBox, + container : UI_Widget, is_open : b32, is_maximized : b32, }, @@ -42,7 +42,7 @@ ui_screen_tick :: proc() { ui_floating_manager_end() } -ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 ) +ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 = false ) { profile("App Menu Bar") fmt :: str_fmt_alloc @@ -52,41 +52,17 @@ ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 ) { using state := get_state(); using screen_ui.menu_bar - ui_layout( UI_Layout { - flags = {.Fixed_Position_X, .Fixed_Position_Y, .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center}, - // anchor = range2({0.5, 0.5}, {0.5, 0.5} ), - alignment = { 0.5, 0.5 }, - border_width = 1.0, - font_size = 12, - // pos = {}, - pos = pos, - size = range2( size, {}), - }) - ui_style( UI_Style { - bg_color = { 0, 0, 0, 30 }, - border_color = { 0, 0, 0, 200 }, - font = default_font, - text_color = Color_White, - }) + ui_theme_app_menu_bar_default() container = ui_hbox( .Left_To_Right, "Menu Bar" ) + { + using container + layout.flags = {.Fixed_Position_X, .Fixed_Position_Y, .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center} + layout.pos = pos + layout.size = range2( size, {}) + text = str_intern("menu_bar") + } - ui_layout( UI_Layout { - flags = {}, - anchor = {}, - alignment = { 0.0, 0.0 }, - text_alignment = {0.5, 0.5}, - border_width = 1.0, - font_size = 12, - }) - style_theme := to_ui_style_combo({ - bg_color = Color_Frame_Disabled, - font = default_font, - text_color = Color_White, - }) - style_theme.hot.bg_color = Color_Blue - style_theme.active.bg_color = Color_Frame_Select - ui_style(style_theme) - + ui_theme_btn_default() move_box := ui_button("Move Box"); { using move_box @@ -94,22 +70,26 @@ ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 ) pos += input.mouse.delta should_raise = true } - layout.anchor.ratio.x = 0.2 + layout.anchor.ratio.x = 0.4 } spacer := ui_spacer("Menu Bar: Move Spacer") spacer.layout.flags |= {.Fixed_Width} - spacer.layout.size.min.x = 50 + spacer.layout.size.min.x = 30 + // TODO(Ed): Implement an external composition for theme interpolation using the settings btn settings_btn.widget = ui_button("Settings Btn") - settings_btn.text = str_intern("Settings") - settings_btn.layout.flags = { - // .Scale_Width_By_Height_Ratio, - .Fixed_Width - } - settings_btn.layout.size.min.x = 100 - if settings_btn.pressed { - screen_ui.settings_menu.is_open = true + { + using settings_btn + text = str_intern("Settings") + layout.flags = { + // .Scale_Width_By_Height_Ratio, + .Fixed_Width + } + layout.size.min.x = 100 + if pressed { + screen_ui.settings_menu.is_open = true + } } spacer = ui_spacer("Menu Bar: End Spacer") @@ -118,46 +98,44 @@ ui_screen_menu_bar :: proc( captures : rawptr = nil ) -> (should_raise : b32 ) return } -ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b32) +ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b32 = false) { profile("Settings Menu") using state := get_state() using state.screen_ui - if ! settings_menu.is_open do return false + if ! settings_menu.is_open do return using settings_menu if size.x < min_size.x do size.x = min_size.x if size.y < min_size.y do size.y = min_size.y - resize_box_base := ui_widget("Settings Menu Wrapper", {}) + container = ui_widget("Settings Menu", {}) { - using resize_box_base - layout.flags = { .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center, .Fixed_Position_X, .Fixed_Position_Y } - layout.pos = pos - layout.alignment = { 0.5, 0.5 } - layout.size = range2( size, {}) - style.bg_color = Color_3D_BG + using container + layout.flags = { .Fixed_Width, .Fixed_Height, .Origin_At_Anchor_Center, .Fixed_Position_X, .Fixed_Position_Y } + layout.alignment = { 0.5, 0.5 } + // style.bg_color = Color_3D_BG + style.border_color = { 0, 0, 0, 200 } + layout.border_width = 1.0 + layout.pos = pos + layout.size = range2( size, {}) } - ui_parent(resize_box_base) + ui_parent(container) if settings_menu.is_maximized { - using resize_box_base + using container layout.flags = {.Origin_At_Anchor_Center } layout.pos = {} } - ui_resizable_handles( & resize_box_base, & pos, & size) + should_raise |= ui_resizable_handles( & container, & pos, & size) - vb_container = ui_vbox_begin( .Top_To_Bottom, "Settings Menu", {.Mouse_Clickable}, compute_layout = true) + vbox := ui_vbox_begin( .Top_To_Bottom, "Settings Menu: VBox", {.Mouse_Clickable}, compute_layout = true) { - { - using vb_container - flags = {} - style.bg_color = Color_BG_Panel_Translucent - } - ui_parent(vb_container) + vbox.style.bg_color = Color_BG_Panel_Translucent + ui_parent(vbox) ui_layout( UI_Layout { - font_size = 16, - alignment = {0, 0}, + // font_size = 16, + // alignment = {0, 1}, }) ui_style( UI_Style { bg_color = Color_Transparent, @@ -165,19 +143,16 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b text_color = Color_White, }) ui_style_ref().hot.bg_color = Color_Blue - frame_bar : UI_HBox - frame_bar = ui_hbox_begin(.Left_To_Right, "Settings Menu: Frame Bar", { .Mouse_Clickable, .Focusable, .Click_To_Focus }) + frame_bar := ui_hbox_begin(.Left_To_Right, "Settings Menu: Frame Bar", { .Mouse_Clickable, .Focusable, .Click_To_Focus }) { frame_bar.style.bg_color = Color_BG_Panel frame_bar.layout.flags = {.Fixed_Height} frame_bar.layout.size.min.y = 50 - frame_bar.layout.anchor.ratio.y = 0.25 + // frame_bar.layout.anchor.ratio.y = 0.8 ui_parent(frame_bar) ui_layout( UI_Layout { - font_size = 16, - // alignment = {1, 0}, - // anchor = range2({}, {}) + font_size = 18, }) title := ui_text("Settings Menu: Title", str_intern("Settings Menu"), {.Disabled}) { @@ -187,6 +162,10 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b layout.anchor.ratio.x = 1.0 } + ui_layout( UI_Layout { + font_size = 16, + }) + ui_style(ui_style_peek()) style := ui_style_ref() style.default.bg_color = Color_Black @@ -228,65 +207,70 @@ ui_screen_settings_menu :: proc( captures : rawptr = nil ) -> ( should_raise : b should_raise = true } - ui_style( UI_Style { - bg_color = Color_Red, - font = default_font, - text_color = Color_White, - }) - // Populate settings with values from config (hardcoded for now) + ui_layout(UI_Layout { + flags = { + // .Origin_At_Anchor_Center, + // .Fixed_Height, + }, + // pos = {0, 50}, + // size = range2({100, 100},{}), + // alignment = {0,0}, + }) + ui_style( UI_Style { + // bg_color = Color_GreyRed + }) + drop_down_bar := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config drop_down_bar", {.Mouse_Clickable}) { - ui_layout(UI_Layout { - flags = { - // .Origin_At_Anchor_Center, - // .Fixed_Height, - }, - // pos = {0, 50}, - // size = range2({100, 100},{}), - // alignment = {0,0}, - }) - ui_style( UI_Style { - bg_color = Color_GreyRed - }) + drop_down_bar.layout.anchor.ratio.y = 0.1 { - drop_down_bar := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config drop_down_bar", {.Mouse_Clickable}) - drop_down_bar.layout.anchor.ratio.y = 1.0 - // drop_down_bar.style.bg_color = Color_Red - - ui_parent(drop_down_bar) - btn := ui_button("pls") - btn.text = str_intern("Config") - btn.style.font = default_font - btn.layout.font_size = 32 - btn.layout.size.min.y = 50 - btn.layout.text_alignment = { 0.5, 0.5 } - btn.layout.flags = {.Fixed_Width, .Size_To_Text} - // btn.layout.size.min = {50, 0} - btn.style.bg_color = Color_Green - ui_hbox_end(drop_down_bar, compute_layout = false) + using drop_down_bar + text = str_intern("drop_down_bar") + style.bg_color = { 55, 55, 55, 100 } + style.font = default_font + style.text_color = Color_White + layout.flags = {.Fixed_Height} + layout.font_size = 12 + layout.text_alignment = {1, 0} + layout.size.min.y = 35 } + ui_parent(drop_down_bar) - // ui_layout(UI_Layout { - - // }) - // ui_style( UI_Style { - - // }) - // res_width_hbox := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config.resolution_width: hbox", {}) - // ui_parent(res_width_hbox) + btn := ui_text("pls", str_intern("Lets figure this out...")) + { + using btn + text = str_intern("Config") + style.font = default_font + style.text_color = Color_White + layout.flags = {.Origin_At_Anchor_Center} + layout.alignment = {0.5, 0.25} // ??? (Wtf is this alignment) + layout.anchor.ratio.x = 1.0 + layout.font_size = 12 + layout.margins = {0,0, 15, 0} + layout.size.min.y = 35 + } + ui_hbox_end(drop_down_bar, compute_layout = false) + ui_box_compute_layout(btn) } + // ui_layout(UI_Layout { + + // }) + // ui_style( UI_Style { + + // }) + // res_width_hbox := ui_hbox_begin(.Left_To_Right, "settings_menu.vbox: config.resolution_width: hbox", {}) + // ui_parent(res_width_hbox) + // ui_layout_ref().default.flags = {.Fixed_Width, .Fixed_Height, .Fixed_Position_Y} // ui_layout_ref().default.size.min = {50, 50} spacer := ui_spacer("Settings Menu: Spacer") - // spacer.style.bg_color = Color_Red spacer.layout.anchor.ratio.y = 1.0 // spacer.layout.flags = {.Origin_At_Anchor_Center} // spacer.layout.alignment = {0.5, 0.5} + // spacer.style.bg_color = Color_Red - // ui_box_compute_layout(spacer) - ui_vbox_end(vb_container, compute_layout = false ) - // ui_box_compute_layout(spacer) + ui_vbox_end(vbox, compute_layout = true ) } return } diff --git a/code/colors.odin b/code/colors.odin index f1d1ba4..1e0b8cc 100644 --- a/code/colors.odin +++ b/code/colors.odin @@ -27,3 +27,30 @@ Color_3D_BG :: Color { 188, 182 , 170, 255 } Color_Debug_UI_Padding_Bounds :: Color { 40, 195, 170, 160 } Color_Debug_UI_Content_Bounds :: Color { 170, 120, 240, 160 } + +// TODO(Ed): The entire rendering pass should be post-processed by a tone curve configurable for the user +// This is how you properly support any tonality of light or dark themes and not have it be base don the monitors raw output. + +// Dark Theme + +// Brightest value limited to (text is the only exception): +Color_ThmDark_BrightLimit :: Color {230, 230, 230, 255} +// Darkness value limited to (text is the only exception): +Color_ThmDark_DarkLimit :: Color {10, 10, 10, 255} + + +Color_ThmDark_BG :: Color {33, 33, 33, 255} + +Color_ThmDark_Border_Default :: Color { 64, 64, 64, 255} + +Color_ThmDark_Btn_BG_Default :: Color { 40, 40, 40, 255} +Color_ThmDark_Btn_BG_Hot :: Color { 60, 60, 70, 255} +Color_ThmDark_Btn_BG_Active :: Color { 90, 100, 130, 255} + +Color_ThmDark_Text_Default :: Color {120, 117, 115, 255} +Color_ThmDark_Text_Hot :: Color {180, 180, 180, 255} +Color_ThmDark_Text_Active :: Color {240, 240, 240, 255} + +// Light Theme + +// LightTheme_BG :: Color { 120, 120, 120, 255 } \ No newline at end of file diff --git a/code/engine_api.odin b/code/engine_api.odin index f812dfb..3d45657 100644 --- a/code/engine_api.odin +++ b/code/engine_api.odin @@ -171,7 +171,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem // Setup the screen ui state { ui_startup( & screen_ui.base, cache_allocator = persistent_slab_allocator() ) - ui_floating_startup( & screen_ui.floating, persistent_slab_allocator(), 16 * Kilobyte, 16 * Kilobyte, "screen ui floating manager" ) + ui_floating_startup( & screen_ui.floating, persistent_slab_allocator(), 1 * Kilobyte, 1 * Kilobyte, "screen ui floating manager" ) using screen_ui menu_bar.pos = { -60, 0 } @@ -277,7 +277,7 @@ reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem, slab_reload( persistent_slab, persistent_allocator() ) - hmap_chained_reload( font_provider_data.font_cache, persistent_slab_allocator()) + hmap_chained_reload( font_provider_data.font_cache, persistent_allocator()) slab_reload( string_cache.slab, persistent_allocator() ) zpl_hmap_reload( & string_cache.table, persistent_slab_allocator()) @@ -318,9 +318,9 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32 rl.PollInputEvents() - debug.draw_ui_box_bounds_points = true - debug.draw_UI_padding_bounds = true - debug.draw_ui_content_bounds = true + debug.draw_ui_box_bounds_points = false + debug.draw_UI_padding_bounds = false + debug.draw_ui_content_bounds = false should_close = update( host_delta_time ) render() @@ -331,8 +331,8 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32 // Timing { // profile("Client tick timing processing") - // config.engine_refresh_hz = uint(monitor_refresh_hz) - config.engine_refresh_hz = 6 + config.engine_refresh_hz = uint(monitor_refresh_hz) + // config.engine_refresh_hz = 6 frametime_target_ms = 1.0 / f64(config.engine_refresh_hz) * S_To_MS sub_ms_granularity_required := frametime_target_ms <= Frametime_High_Perf_Threshold_MS diff --git a/code/grime_linked_list.odin b/code/grime_linked_list.odin index d576fcc..ff0828a 100644 --- a/code/grime_linked_list.odin +++ b/code/grime_linked_list.odin @@ -128,7 +128,7 @@ dll_pop_back :: #force_inline proc "contextless" ( current_ptr : ^(^ ($ Type)) ) } } -dll_full_insert_raw :: proc "contextless" ( null : ^($ Type), parent, pos, node : ^Type ) +dll_full_insert_raw :: proc "contextless" ( null : ^($ Type), parent : ^$ParentType, pos, node : ^Type ) { if parent.first == null { parent.first = node @@ -161,7 +161,7 @@ dll_full_insert_raw :: proc "contextless" ( null : ^($ Type), parent, pos, node } } -dll_full_pop :: proc "contextless" ( node, parent : ^$Type ) { +dll_full_pop :: proc "contextless" ( node : ^$NodeType, parent : ^$ParentType ) { if node == nil { return } @@ -171,20 +171,19 @@ dll_full_pop :: proc "contextless" ( node, parent : ^$Type ) { if parent.last == node { parent.last = node.prev } - if parent.first == parent.last { - parent.last = nil - } - if node.prev != nil { - node.prev.next = nil + prev := node.prev + next := node.next + if prev != nil { + prev.next = next node.prev = nil } - if node.next != nil { - node.next.prev = nil + if next != nil { + next.prev = prev node.next = nil } } -dll_full_push_back :: proc "contextless" ( parent, node : ^ $Type, null : ^Type ) { +dll_full_push_back :: proc "contextless" ( parent : ^$ParentType, node : ^$Type, null : ^Type ) { dll_full_insert_raw( null, parent, parent.last, node ) } diff --git a/code/grime_stack.odin b/code/grime_stack.odin index 1088941..88f79ac 100644 --- a/code/grime_stack.odin +++ b/code/grime_stack.odin @@ -185,7 +185,7 @@ stack_allocator_proc :: proc( alignment : int, old_memory : rawptr, old_size : int, - location : SourceCodeLocation = #caller_location + // location : SourceCodeLocation = #caller_location ) -> ([]byte, AllocatorError) { stack := StackAllocator { cast( ^StackAllocatorBase) allocator_data } diff --git a/code/grime_virtual_arena.odin b/code/grime_virtual_arena.odin index d942480..3ae40bc 100644 --- a/code/grime_virtual_arena.odin +++ b/code/grime_virtual_arena.odin @@ -196,7 +196,7 @@ varena_allocator_proc :: proc( alignment : int, old_memory : rawptr, old_size : int, - location : SourceCodeLocation = #caller_location + // location : SourceCodeLocation = #caller_location ) -> ( data : []byte, alloc_error : AllocatorError) { arena := cast( ^VArena) allocator_data diff --git a/code/tick_render.odin b/code/tick_render.odin index eff7fa3..3090dc5 100644 --- a/code/tick_render.odin +++ b/code/tick_render.odin @@ -32,7 +32,7 @@ render :: proc() render_mode_3d() rl.BeginDrawing() - rl.ClearBackground( Color_BG ) + rl.ClearBackground( Color_ThmDark_BG ) render_mode_2d_workspace() render_mode_screenspace() diff --git a/code/tick_update.odin b/code/tick_update.odin index b818637..cc02763 100644 --- a/code/tick_update.odin +++ b/code/tick_update.odin @@ -240,7 +240,7 @@ update :: proc( delta_time : f64 ) -> b32 // test_draggable() // test_text_box() // test_parenting( & default_layout, & frame_style_default ) - test_whitespace_ast( & default_layout, & frame_style_default ) + // test_whitespace_ast( & default_layout, & frame_style_default ) } //endregion Workspace Imgui Tick diff --git a/code/ui_box.odin b/code/ui_box.odin index aa0a3df..13288ac 100644 --- a/code/ui_box.odin +++ b/code/ui_box.odin @@ -87,8 +87,6 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box) key := ui_key_from_string( label ) - links_perserved : DLL_NodeFull( UI_Box ) - curr_box : (^ UI_Box) prev_box := zpl_hmap_get( prev_cache, cast(u64) key ) { @@ -119,15 +117,17 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box) // Clear non-persistent data curr_box.computed.fresh = false - curr_box.links = links_perserved + curr_box.links = {} curr_box.num_children = 0 // If there is a parent, setup the relevant references parent := stack_peek( & parent_stack ) if parent != nil { - dll_full_push_back( parent, curr_box, nil ) - when false + when false { + dll_full_push_back( parent, curr_box, nil ) + } + else { // | // v @@ -160,8 +160,6 @@ ui_box_make :: proc( flags : UI_BoxFlags, label : string ) -> (^ UI_Box) ui_box_tranverse_next :: proc "contextless" ( box : ^ UI_Box ) -> (^ UI_Box) { - parent := box.parent - // Check to make sure parent is present on the screen, if its not don't bother. // If current has children, do them first using state := get_state() @@ -179,6 +177,16 @@ ui_box_tranverse_next :: proc "contextless" ( box : ^ UI_Box ) -> (^ UI_Box) // There is no more adjacent nodes if box.parent != nil { + parent := box.parent + // Attempt to find a parent with a next, otherwise we just return a parent with nil + for ; parent.parent != nil; + { + if parent.next != nil { + break + } + parent = parent.parent + } + // Lift back up to parent, and set it to its next. return parent.next } diff --git a/code/ui_floating.odin b/code/ui_floating.odin index 7060401..84483d6 100644 --- a/code/ui_floating.odin +++ b/code/ui_floating.odin @@ -100,7 +100,7 @@ ui_floating_build :: proc() lookup := hmap_chained_get( tracked, transmute(u64) key ) // Check if entry is already present - if lookup != nil && lookup.prev != nil && lookup.next != nil { + if lookup != nil && (lookup.next != nil || lookup == last) { lookup.captures = to_enqueue.captures lookup.builder = to_enqueue.builder lookup.queued = true @@ -115,30 +115,36 @@ ui_floating_build :: proc() ensure(false, "Failed to allocate entry to hashtable") continue } - lookup.queued = true } else { lookup.captures = to_enqueue.captures lookup.builder = to_enqueue.builder - lookup.queued = true - continue } - + lookup.queued = true if first == nil { first = lookup last = lookup continue } - last.next = lookup - last = lookup + if first == last { + last = lookup + last.prev = first + first.next = last + continue + } + last.next = lookup + lookup.prev = last + last = lookup } array_clear(build_queue) + to_raise : ^UI_Floating for entry := first; entry != nil; entry = entry.next { - using entry - if ! queued + if ! entry.queued { + ensure(false, "There should be no queue failures yet") + if entry == first { first = entry.next @@ -162,39 +168,45 @@ ui_floating_build :: proc() entry.next = nil } - if builder( captures ) && entry != last + if entry.builder( entry.captures ) && entry != last && to_raise == nil { - PopEntry: - { - if first == nil { - first = entry - last = entry - break PopEntry - } - if entry == first - { - first = entry.next - entry.next = nil - break PopEntry - } - if entry == last - { - last = last.prev - last.prev = nil - entry.prev = nil - break PopEntry - } - - left := entry.prev - right := entry.next - - left.next = right - right.prev = left - } - - last.next = entry - last = entry + to_raise = entry } - queued = false + entry.queued = false + } + if to_raise != nil + { + dll_full_pop( to_raise, floating ) + dll_full_push_back( floating, to_raise, nil ) + // PopEntry: + // { + // if first == nil { + // first = to_raise + // last = to_raise + // break PopEntry + // } + // if to_raise == first + // { + // first = to_raise.next + // to_raise.next.prev = nil + // break PopEntry + // } + // if to_raise == last + // { + // // Do nothing no need to modify order + // return + // } + + // left := to_raise.prev + // right := to_raise.next + + // left.next = right + // right.prev = left + // } + + // last.next = to_raise + // to_raise.prev = last + // last.next = nil + // last = to_raise } } diff --git a/code/ui_layout_compute.odin b/code/ui_layout_compute.odin index 903b8e2..d68a1cb 100644 --- a/code/ui_layout_compute.odin +++ b/code/ui_layout_compute.odin @@ -170,8 +170,8 @@ ui_box_compute_layout_children :: proc( box : ^UI_Box ) { for current := box.first; current != nil; current = ui_box_tranverse_next( current ) { - // if current == box do return - // if current.computed.fresh do continue + if current == box do return + if current.computed.fresh do continue ui_box_compute_layout( current ) } } diff --git a/code/ui_layout_widget.odin b/code/ui_layout_widget.odin index 540e438..4d5a986 100644 --- a/code/ui_layout_widget.odin +++ b/code/ui_layout_widget.odin @@ -44,9 +44,9 @@ ui_layout_children_horizontally :: proc( container : ^UI_Box, direction : UI_Lay { using child.layout if ! (.Fixed_Width in flags) { - size.min.x = anchor.ratio.x * (1 / total_stretch_ratio) * avail_flex_space + size.min.x = anchor.ratio.x * (1 / total_stretch_ratio) * avail_flex_space - child.layout.margins.left - child.layout.margins.right } - flags |= {.Fixed_Width} + flags |= {.Fixed_Width} } space_used : f32 = 0.0 @@ -56,20 +56,16 @@ ui_layout_children_horizontally :: proc( container : ^UI_Box, direction : UI_Lay allocate_space(child, total_stretch_ratio, avail_flex_space) using child.layout anchor = range2({0, 0}, {0, 0}) - // alignment = { 0, 0 }// - hbox.layout.alignment pos.x = space_used - space_used += size.min.x - // size.min.y = container.computed.content.max.y - container.computed.content.min.y + space_used += size.min.x + child.layout.margins.left + child.layout.margins.right } case .Left_To_Right: for child := container.first; child != nil; child = child.next { allocate_space(child, total_stretch_ratio, avail_flex_space) using child.layout anchor = range2({0, 0}, {0, 0}) - // alignment = { 0, 0 } pos.x = space_used - space_used += size.min.x - // size.min.y = container.computed.content.max.y - container.computed.content.min.y + space_used += size.min.x + child.layout.margins.left + child.layout.margins.right } } } @@ -114,18 +110,19 @@ ui_layout_children_vertically :: proc( container : ^UI_Box, direction : UI_Layou { using child.layout if ! (.Fixed_Height in flags) { - size.min.y = anchor.ratio.y * (1 / total_stretch_ratio) * avail_flex_space + size.min.y = (anchor.ratio.y * (1 / total_stretch_ratio) * avail_flex_space) } flags |= {.Fixed_Height} } space_used : f32 = 0.0 - switch direction { + switch direction + { case .Bottom_To_Top: for child := container.last; child != nil; child = child.prev { allocate_space(child, total_stretch_ratio, avail_flex_space) using child.layout - anchor = range2({0, 0}, {0, 0}) + anchor = range2({0,0}, {0, 0}) // alignment = {0, 0} pos.y = -space_used space_used += size.min.y diff --git a/code/ui_theme.odin b/code/ui_theme.odin index 1790c41..beb7c0c 100644 --- a/code/ui_theme.odin +++ b/code/ui_theme.odin @@ -42,13 +42,141 @@ UI Themes: Comprise of UI_Box's layout & style Provides presets for themes and their interface for manipulating the combo stacks in UI_State in pairs */ +// TODO(Ed): Eventually this will have a configuration wizard, and we'll save the presets -UI_Theme_Btn_Default :: UI_Theme { +/* +UI_Theme_Template :: UI_Theme { + UI_Layout { + flags = {}, + anchor = Range2{{},{}}, + alignment = {}, + text_alignment = {}, + font_size = {}, + margins = {}, + padding = {}, + border_width = {}, + pos = {}, + size = Range2{{},{}} + }, + UI_Style { + bg_color = {}, + corner_radii = {}, + blur_size = 0, + font = {}, + text_color = {}, + cursor = 0, + } +} +*/ +@(deferred_none = ui_theme_pop) +ui_theme_app_menu_bar_default :: proc() +{ + @static theme : UI_Theme + // @static loaded : b32 = false + // if true && ! loaded + // { + layout := UI_Layout { + flags = {}, + anchor = range2({},{}), + alignment = {0.5, 0.5}, + text_alignment = {0.0, 1.5}, + font_size = 12, + margins = {0, 0, 0, 0}, + padding = {0, 0, 0, 0}, + border_width = 0.6, + pos = {0, 0}, + size = range2({},{}) + } + style := UI_Style { + bg_color = Color_ThmDark_BG, + border_color = Color_ThmDark_Border_Default, + corner_radii = {}, + blur_size = 0, + font = get_state().default_font, + text_color = Color_ThmDark_Text_Default, + cursor = {}, + } + + // loaded = true + layout_combo := to_ui_layout_combo(layout) + style_combo := to_ui_style_combo(style) + { + using layout_combo.hot + using style_combo.hot + bg_color = Color_ThmDark_Btn_BG_Hot + text_color = Color_ThmDark_Text_Hot + } + { + using layout_combo.active + using style_combo.active + bg_color = Color_ThmDark_Btn_BG_Active + text_color = Color_ThmDark_Text_Active + } + + theme = UI_Theme { + layout_combo, style_combo + } + // } + + + ui_layout_push(theme.layout) + ui_style_push(theme.style) } -@(deferred_none = ui_layout_pop) -ui_theme_btn_default :: #force_inline proc() { - ui_layout_push(UI_Theme_Btn_Default.layout) - ui_style_push(UI_Theme_Btn_Default.style) +@(deferred_none = ui_theme_pop) +ui_theme_btn_default :: proc() +{ + @static theme : UI_Theme + // @static loaded : b32 = false + // if true && ! loaded + // { + layout := UI_Layout { + flags = {}, + anchor = range2({},{}), + alignment = {0, 0}, + text_alignment = {0.5, 0.5}, + font_size = 16, + margins = {0, 0, 0, 0}, + padding = {0, 0, 0, 0}, + border_width = 1, + pos = {0, 0}, + size = range2({},{}) + } + style := UI_Style { + bg_color = Color_ThmDark_Btn_BG_Default, + border_color = Color_ThmDark_Border_Default, + corner_radii = {}, + blur_size = 0, + font = get_state().default_font, + text_color = Color_ThmDark_Text_Default, + cursor = {}, + } + + // loaded = true + layout_combo := to_ui_layout_combo(layout) + style_combo := to_ui_style_combo(style) + { + using layout_combo.hot + using style_combo.hot + bg_color = Color_ThmDark_Btn_BG_Hot + text_color = Color_ThmDark_Text_Hot + margins = {2, 2, 2, 2} + } + { + using layout_combo.active + using style_combo.active + bg_color = Color_ThmDark_Btn_BG_Active + text_color = Color_ThmDark_Text_Active + margins = {2, 2, 2, 2} + } + + theme = UI_Theme { + layout_combo, style_combo + } + // } + + + ui_layout_push(theme.layout) + ui_style_push(theme.style) } diff --git a/code/ui_widgets.odin b/code/ui_widgets.odin index 8068d81..8331afe 100644 --- a/code/ui_widgets.odin +++ b/code/ui_widgets.odin @@ -165,7 +165,7 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2, corner_tl := true, corner_br := true, corner_bl := true, - compute_layout := true) + compute_layout := true) -> (drag_signal : b32) { profile(#procedure) handle_left : UI_Widget @@ -259,15 +259,15 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2, target_alignment : Vec2, pos : ^Vec2, size : ^Vec2, - alignment : ^Vec2, ) + alignment : ^Vec2, ) -> b32 { ui := get_state().ui_context - if ui.last_pressed_key != handle.key { return } + if ui.last_pressed_key != handle.key { return false } size_delta := size_delta pos_adjust := size^ * (alignment^ - target_alignment) - @static was_dragging := false + @static was_dragging : b32 = false using handle if active @@ -287,21 +287,23 @@ ui_resizable_handles :: proc( parent : ^UI_Widget, pos : ^Vec2, size : ^Vec2, alignment^ = target_alignment was_dragging = false } + return was_dragging } delta := get_state().input.mouse.delta alignment := & parent.layout.alignment - if right do process_handle_drag( & handle_right, { 1, 0 }, delta, {0, 0}, pos, size, alignment ) - if left do process_handle_drag( & handle_left, { -1, 0 }, delta, {1, 0}, pos, size, alignment ) - if top do process_handle_drag( & handle_top, { 0, 1 }, delta, {0, 0}, pos, size, alignment ) - if bottom do process_handle_drag( & handle_bottom, { 0, -1 }, delta, {0, 1}, pos, size, alignment ) - if corner_tr do process_handle_drag( & handle_corner_tr, { 1, 1 }, delta, {0, 0}, pos, size, alignment ) - if corner_tl do process_handle_drag( & handle_corner_tl, { -1, 1 }, delta, {1, 0}, pos, size, alignment ) - if corner_br do process_handle_drag( & handle_corner_br, { 1, -1 }, delta, {0, 1}, pos, size, alignment ) - if corner_bl do process_handle_drag( & handle_corner_bl, { -1, -1 }, delta, {1, 1}, pos, size, alignment ) + if right do drag_signal |= process_handle_drag( & handle_right, { 1, 0 }, delta, {0, 0}, pos, size, alignment ) + if left do drag_signal |= process_handle_drag( & handle_left, { -1, 0 }, delta, {1, 0}, pos, size, alignment ) + if top do drag_signal |= process_handle_drag( & handle_top, { 0, 1 }, delta, {0, 0}, pos, size, alignment ) + if bottom do drag_signal |= process_handle_drag( & handle_bottom, { 0, -1 }, delta, {0, 1}, pos, size, alignment ) + if corner_tr do drag_signal |= process_handle_drag( & handle_corner_tr, { 1, 1 }, delta, {0, 0}, pos, size, alignment ) + if corner_tl do drag_signal |= process_handle_drag( & handle_corner_tl, { -1, 1 }, delta, {1, 0}, pos, size, alignment ) + if corner_br do drag_signal |= process_handle_drag( & handle_corner_br, { 1, -1 }, delta, {0, 1}, pos, size, alignment ) + if corner_bl do drag_signal |= process_handle_drag( & handle_corner_bl, { -1, -1 }, delta, {1, 1}, pos, size, alignment ) ui_box_compute_layout(parent) + return } #endregion("Resizable") diff --git a/docs/assets/sectr_host_2024-05-15_03-32-36.png b/docs/assets/sectr_host_2024-05-15_03-32-36.png new file mode 100644 index 0000000000000000000000000000000000000000..024156087068b727da15d366affb816341b69f53 GIT binary patch literal 29209 zcmd?RcT|(<);1n=00ps(BBKcCIEspZQU{Q#$S5s}5-AB5iqt3}L;?W>u?z|hNSC50 z#XzF8kU)YRk*b7H0z{-IkN^Qf63Xumo^#&socFxzJ?r=1x4x{!g0!dH&)(N{?Q8Fc zdr$`(1-YGa5C}x!)E_6#LLh6|5XhPv>tw(yGd4T4z%MD(SsN<|p=H-Nc=D5vrM)Et z@+wh&@sc!nzW&-DE+`0O<2%WZR6VlD69TzTICaAE+zrHJ-}>rvA8sy3CEM*U_wrs& z9!hIUJ$3FJ)Z&EYUpR&E3kshO9mu=hX?NuN&(|z1e|viO&p)Go?u8yb^t9;P&x)H3 zH(PIe@Qc#64<~GrMJ&?Go_71WP_ET^77v%x`p)RQ&m=c|TyQSiIDCT4v;5dIx|=_U z%gn&do4?mnGi+|E89$4{7OECFr6CyO?F1dv{zR6S>;A_Wat7+nJ&%^eBZck@%Baa+ zBah5LZ@XiDK7Hw^reTz}L17dbQE0if`99t!-9zDPggL6ITeqnrh>G{gC@$Q&;`Gu+nmk>kRBC4LpA~TX?CTR$>^Y25`6yU~{H$=OSHRGbGZ)TTT3DeU^a zZKmT?p+k04_4UDtx`yCV-H@@ik}|8)rmD{juUjEey`Q))UhiZ>4MwxSYUAx1i;sEW zj$&D@Mx(os+3pe39}0Y0bHYZ4E7~0z#lkOD$!J$YOcX7U5oa~Z#oOliyy~>(h+0n7 zMY%GjCs_jQ2s8IL(&$xlS3;Z7_WZ$X%;{+rpI1x1*}YdnW~ko2+e|h}KDIw?Iy*N% zP@Pi|#9fYH9v&LY(H9t27PM-Y{=&Kw{5~X7m|(4!-6#-`n>eJTm90D*F!x2CJU87T zb+>-con4oA8U_XI)Vq2yaw=9WJxWZ9YAn+&f=P$O&92=PbcKTE`4cE3GUbam&yRF; z_Ukasmp4ET_1JjKbfmm3&21!=IFcJXE87x?#`S}Y=6cdb2*kpkSs}DXvC3qdOB#uK zfy^rX@X1P8C^Ty7CM!cWjTIQQJZXhuQ3dISq=4z5b&%-O-{i->yKRR+@~WuSmy(Uf zhn(!%3+$UQG=6rrWnbm9mCN6|`%^%AfXz=DPd`i6)#QYa<%FOyte4aJytk0(fR4bM zrQ_S(Nz~t1!LN$AM(5u8LvF>e)FDMCel9S>1zyyO*gG-SwL%vL$HihSA+HH9#2+dP z>J})I`-G{eKQ)~`8~8b)1$8xvYDK>-nn_voeKqCmycm@D&J|g}vm?W?+z z^KQ~@w{JtXAl(S&0jpwitCcze=*1M5}a17=8bl^y(rW=*{Q}l)R%hv5GQAQEW z_15TwqhSfYB&ocRMS_%tFaXNCU%%7}OKtOq@|N57 z;+t+iK&H!&nq4hG2%^bX`-4%_G2-TmEUvCLt-2u~e8seUc&@WlzzT15N7p+!AGBQR z_uAx5HKKX>^-x9)JSWQu^YNl5v^dpUn!>QdA4z7C_&KvV>U%?_cVkx6tZNO|x<+yk zrz{u6<_j3)1?_Wb&f}I#11aZkiZyk)NhZy=Sci|+H`AIQ9}#RveO0K_=P;=5iY=_8 z#Jc6o;TTbGc+P>Hbj9?j#X-~Z5h67xlA-h57&9YGC2GOAk(G$T7I<0eL2GX4p93)# zOBM_FJm7Vh%2(#3=HP{@t@)=-)F6;UaWfCskclnp^>u}7!UAuF95gD@cB8$OnbRHZ z^GTr2Y}cJA<1{~P98KSY^6t)~P4-RXMZVjs(QNN%dO@!Uua9f$y53I-KCfP6o4M&H zOBJ(*Z^tj(bppH6r<#+fl3n3XA5#arvTU-1C%vhyvZ6fNMdyiiiZ)eWC5%T7colTs z-!W2{=BT@tKskc9?nC41=DNe1R5-lD#hjY{yAe`udoIi+1^9N(5ZpBf8p6&*JEV?Q zeHE{%%IY)@GR17MT-i?|>ICj}DM0s%8iF+oXFR*V?Y-^ULB@^!ZryGiNvhSl`db=m zn7gn!^|XTdU7H!*3-^&Y2qd~EZ^Kp;R7t7LU*nl=w%|3kS%R{L*PhGe$`(Q42x%((K^Pw?;dg6 zh+XB;mABkq6J-~Ii|UM6oVFQxx5?~)Ns;5eOl>g8AJ>kXboO}#O|KiZCtgGoCzC_Ev!C*6b%7+_SSFTzG#i~WBsvJH+R zb9~JYVK`$Rq>|s#(9BZ^Xj|=Dau#O5lx5Jn{Md6!7P|82=i21Pp&3mO3Q*;Q9hee@ z?+wS2pBZZox?wQFseH%gL_tr@#m%t3#QEMvx3rTDmP-X6NZoDOt!p=x>S?Hk(GPn} z|KTiLR94D*Km_!&)nr&EN{OEA1$l^n+&1ZEkcOmQIRD*9YHCoRVgZL<5TtabCdG=F zyojr7Nv`#cPtX+vWY!d^e=A*T+aN7{KOm2YM)3mU!I|gTo1zyNaI(;Qr#G^T!q`0n zoJdEgEcCwkvMW2SeP||bfgv6Ja9SX5vG3QSwHBVA6&MY}wgb$Q&x;*LfoS}G94Z^_ z3RSjj3)F2OJsxzU?E)g<5u2ND%&9@+%cFMhkLZ`$ZT1ryQY5Xv^r0(IyMg4Mgv<^W zR=I6`QM1G@;W0{EmT#s{g~>)QY^F=?UemEYtpSab)68|dlbIGlO^#?>1Bn*h%-aaL ziN80M+Iuny>2lC3<8J~D^vuDk$Y8ZoG%wpT*>lO_O*eVJfMaoy ziJp;c(?VZ`{-T`9E>X@O65f7|xi8t7SBxkzYVpb{xxdT;ACvsGZk?ryUuTEz9xO4I@yH(Q ziab(%Q^X4cgWLinY_4<_qaYGg<6CAAH{7db23oEH@4rXwE2 z%w^I&u@~F_ZQZ7;7iq$)Tltlp8)q4uU+QR2iiLNS1*FEMmqNl#q1tw}i?s0Xw3c(MZCq!pv;}fh$Btcm}bqOYeNVh-LP*D`NCf_GlrBA$@Pfkd2pD{J=&n zEd|P^^Hj1{Vx)dtEjBqgma^E)-k;%&wpWtNX)$lTdUe^$^*9o~$4>uPO9mwa z{h~@ZmzJ4HBqG_R+Sar@LXc?1nEXUoQ?u#io&`0f3FLC&G)!}peVeef3}aF!OovuN z><6H^Uac<%``hS?7oi0tSVki;v#ExtJT+#D5)zPp+aEVLR}c;o-h$n6M7s5b?$1>)ILwk zTYlh^nU3u1>{^70vn?0ZMtR8PanX|Q96Oc39m!-E(9g3vQoeg=1zm0Rpvr_;T8xfX z!A?{2bEG_2UG)B)58cvEKxM)DL}Lk$2t2u5Hez`tyCzq-JcSFeEknA*VJd&ocp1*Y z@9}_kE^*9%|Bl}tXdiV2-k!}rUtcWMzm1_U5(yFmF1A{??;}mXGzHXYahK(Hn&Bl6 z{vq-b;ZjjL7 zE{O5JW;lve3ksmkvu}oqY{Xt_xs*>z$^j0hvh=}k<~1T&LL-bg2qmAq>zFE*Bw7(v zJ?F+#@@P(Y6CBg$g`MBPUlFBhx@Ce=qFehn8aA(B*R|JDBYCkKXBdiQE6YMRnp_}? zM-@~>pe^pc*h-J;x~$DidK|VZ)0M6raFr&!;Sev%Ie#;3Tx$MHP?+0b{3j(kI&qQJ z$Lw01`t~9Zu6Va&(v=R>&ZOn+!9He0SmFWV!9Q!&D92fY5Z zwmeJkx}{LW9BcvF7@nwV+LRL>IX7HzDtUjw^}&w?ZloZCDMNooQwXo$)QQLFz&30@ zVNXJ``b#dndTW=d*Wh3nC>mahIZyw&SjU$>hIdY^5NkZ^dR5eq;hr7SPd>iU==}yY zv);$o-mdrN_L9B7y}p@Y%(}kaBsJo67(B#%Ni?T>M=kP(a~LjkSvZ=-TAn9)vvBd| z28Vp##7K|yqFO84N&Q%SHU=G66~=EiWVXJc3i{oGp`%pmeXkPFG>$vuJcCT+P!Y-% zlPgBMSC-=&FcF8G{Bc2KrxHZ4%~$PPAj>V{$kQK{o8`4@FB$~)c&2K>{UWF1Jv`Y3 z4%vSFQ7bsz$i*AwUX9yL`kow@b;C@5P-1R>zt1)`JZ zQn%)!Gx<8hz5>`EudXz#E>O+XTlwZpegCG3?()D*x4-1u_)x40aqyXg^OXB4CX8c( zUet()Lp0oUY$`ef9Jm(qZeO(2+9rP@HPvYJZ0*AL_)t@-&u|E?llKstU*X&Skv4*j zg2SH#a?4v=7&_APXJd_dn$hk+azGB*#c$VadY*>xbAu@U-f=dq1O_={5zv-*Gi>UO zEOo&8jg!>*cDXI(-pyt0>=yj?fkv&GCcDSKe@QJxPuxL!|} zuQS7qnDy+AZjU`560DO(xeEwgd(J{{ptLbJhbsMzt7?-bl0m`r(nIneaXBBY&h>x74*# zM=f&UiKaF>YglGZwA{bu(@6lAd25C_A}zV>y*3HG&)xfK3hgp3yG6q}*`F1E^=?YP zRM?SO5{2GlG3;l$INR>n+?1gksF8c1?YEk;!XF1MOxVXFn+Or*VqP69VQrqT3g21@ z?pf&n9o=w#4E<%c?aA>#4XV~}2X-HtAfq`NXr&bZ8O@H7Gh0nq6tutct$69a+X~8= ziDsftRRx^#yv|@?MOD?(15=ghVMwXpex%=r7z)Kpy>XikJsZ=Me$>E|-9LUdhO#Es zRW;Fs`@8Pt_jfmRF2VeCiqgvJtRm{qj`gar{P+6};KY-p<}$Cwrpiu4)_68_E76u< zMT~blIjVDG>LP#Y-KH!Kp+?IIkxLbGYev4sZmMd>;TSH2?AmqYlksWB?%Y>L|8eC@#z?>+>g8f0t7>qyGszd}7S(MxbNtrGsr0F3Uk; z`9=HVolDD}^geh&xY-q=MzSiCxz=9c`V?PNXEmc@OGClnPde>laeWvT&U><_a-@{h zUpCN$wsjCwhMd6FwqEl z!?{b7a=?kin*Y{_ma-8P`tP=g3+;^2imNKVxxPb03uGEF;qdl`!k-qVK(Ja%xP1q9 zG2MTMmf*TG_Wgw?T4T*whOM`{GNA!caSI90dr>g?FfPAbv1c}&G!%>$Qm&d~-Q8cc zsp%?=jc8~WwC$ae3oM6z(i(n+)qieQOM=iOml2{kkbWiM)!y>avt*=@eYV=^2#go! zR^!Jh@*)QqE$a)Un~94RSp(OD7;9Q)q# zCK7;ied}*Z&BEe`Mu7bE13rzx)onHv^j_goI0U%N@AB4-shX2xT_UURcv-*GnM~P= zgm8n%BpDU@Zd3vxU3Fy}@jhNpgp`p+1Ud z#|KN>{}{*8ABAt*32oO)c>PZ_x>1;Fd)A^3pzUOS_v{UQg|SXx;@VMja)~x_ep$hQ zGLFX%7D&n0Qz%?x7Es4lNA$7SgGCS^OAwVc*WIh1_z!A`Hw?c7aM zUv%4AO$F{II8G_4N7(BXtRK+Tc3;)hSeNKC%+Z|~QKSRl8fuD2%6V>%;kt___-A9W z2Xn)ga@gdho$g0mHs7@U!U7HYXe5I>!TMtH3K+8eoRzD zRt0olE;I=lyU5X^EnH^KRC_l3%ycbE{UZgBo&uJ^QGn+<%7#G|nh&(8vq=gHFL*tb z_&$aTruUND?mL^*f*Lyx6;BpBXeMQ<{(dd5G#TiVewo5jH&W)A{FAGvl!AO6Ej9nw z4Q@G9Zb_>Mb}GvtaKh)bseMGFqE7gH0IFeMn&$`{DnN%}yyPaH%gkNQ6~4Ms-;;`) z6x@_mJp!Cwrk670ko@Y(w?DO(M~y#E>q$KxH|d!MKXdKOH3qI~li5O^K-FD(YaG^I z<3v-Yexn24gy{N8yJkX1_xkq}ZdKShKjq)_O50Z2j&JJrwNa7}xwP9QwIV_|1CPO? z=kI*(_-EpP9~KQIJ5Kmq?XL|hIFEM*HjR13Fl`t&8~#)t)^J^wewpAiVh+N#s{Sr= z!`q-fImsl0zr zLCd>R`M<@2g@hjx)f?$ng75L#nMbdD>^f2+zHYmoEw{n%)iG}MVAI_#dv%iFG5!*U zFyDPjDSO*9pw9wpUisa>mm#RQFBsDQe>PxkJrWvo6-=tvJ`|vz*3Lk%tvSR8&VC^X#^{1MBzq@zh z;{8nL^v;VYawC9sUe~KD-rZXret#26#_%DBw*JUZ?IMk5MI0Ul&5<-^%GdY)jB#}i*lgce!Q1l?o#gkz@^eJMPWGTgb)b2 zwtgf*{wIp;g?2gXjy|hwZzRajVxJ zD96a*l4$B}fb0)Y^G$bGvl!k}v=$P*q4H;n^BlMYm^6{q>{z80ye-QRiO3f) zwlmcZIT@{evrkd3(YLCYl{_>kMMZ(mS6 z8SCKtt>jtXQAmnRLZj)%;s&WfH0Ak1xCz_pRJReZ?AmPOGNx2yc5R0R$8|eZ}>&LBISuW8r z4J{29aQmG@J>bdv?d=9XKCmYR^)-Q{zY0XFciJfe?5^vAIgmu~&mC*}%6%N$^KBC0 z3DzFao=Sh8!nse?ma#J3j2kdw{W%3t2bir5|3?)N2xHn+UGt}a-FtudQ_=hDvs0mz z{i>yCiO65#7Rv#+#fcof|5w?4m>RD(!1M= zrB3nFx~<2qY}a)4bbAj1)PZ@HMf9j^qQni!vz0s|UIi|BlzH9@M0ZY8D8){NnF3Z6 z>%N+Ke?WKH2M5ep+ZzV_#z34m(Bt0o6Wt@i(Og4tHU_dPArDJA09N6M(J8QU%p=5L zQ*}4-*}nWlGrz**0ffwkUoLtO&$in3qIwm(*0UkenX3xR%5>pd?8qZ0hlWE=n^izA zW;;XSm44^H7)#HAAnx`>PdjsFz0%;$!AkQHmZqnkxD6b0nSU#<-39H-vs@dlB{!JK zI9lZ8(Kz-CC`of%Y?OZan4sccs5qg99eZMzeHc!m-(K;|X#Xc@+_SoJz@UUcZ#tMv z>XicwEzv>GEl-rU>cBsBG~*-^wUP|YjuGA8p&LMUt(xOWs)9y+xE+vQgh@&wyp#oa z?lE~;#3^Sh(rprUWt`v7{>*xAt7K9-NEv$?KT$EyA1}dPPL+l&;UT3_@*N!~p`E(}v}p@Zcj$WG zFYUw)N_IZcpmU~Cz(m#sN-j3Qg&sQ+rgAoFra^tAdN4tE@5%e0+UENxl9Sx93TVG5 zq^B~6`_5FGj-+3is91w{EsK|I+#D=_pg)OH<{#Pe*vK2;oJ%8!1-aRsRCph&Pt+n2 zy9u^yS^GHpQ*N|D1_b5T2a>*&M3dxT-u_jd-koiNsY?F1>sLxn8sJFUgPOpmz z5W**sFA<)5x*tpt`hRk@iDexes|lJ;K&UC4C=~P1{uaR%VU^q{0Ab!>IbAs0o=Q!J zSYBaP1%~Ds+pF6Y%0hN4NHAjVp=#KOMw%5`-(DPC`kft_>y~S)Ib@?6=IM=igNXe$ zeiYd-9MXy_YYf+dSN~x~YrYO&k%Dw(OO|c-PPwmgBfuA^YP}0f3#%*<=d9lZu_#%6 z?-0A65I)sv%sJd%7qt?jISPTizx%^1`ymYT5MP!!SO$eipnd%ojfF>`A<>joMtyq~ zYVhC~_av04!HyvWjqhP;6OKrzI`hf#JKmpXU4;o`NyuO2r8kLerC?$_A4C{{AtbiYD}H?FwI|@>-1=KCAec}AFJ*g#mj#IKp&`< zF^bnn)B1UQ8VCHDQQ-{a;hI%$%FiQwD;}3HR*6TQ86Kg@#d>4Q6kXaUnWWZZhwLw% z=RdDVXa(~9uzU3pUCdEPgP*nK}>z+u}(u5kG8e=x?o<_=I)O|e5bq%qKkt`%2b*^+@nLmtg7 zS$U_ne9@H@G+C;BCns=Kg}O(AfO(X-YJ{AUnFD~?%|OEpB^FqV2`}A*Tm7yCRQQY< z3SjvT_uz(op`u!Ti!P}**tS4Rt@3f?>=&D`Tq@#fl;2Gry*N3WQJ3k+C{Bq4S+xq8 zY`Suv_=3GW!v=Il}jgBqNwtFv34P;P$ zn?$|6wcf>xa_x!D_mp;%*YM~w7u7)@MECyT57Yb&C8i!R_{jURqjz1V>R`=f$thWW?RN zql!J?lokS3!3VClnYyfO5b&}->9Dpmi0ZGaJbG!{@Qh37Sd3TPHns>65CwY2eN6aP z%cZgWL<1nqSX#sE?F8<3O5T&#i@?NTZfWZ%t$oyKX9;Is<0r(3#=hiFk{?IRG}O>J zmF*uM0bjCfWANzbb+jy zjgU*==pzMbA;v+GhJuyBkl;o=Z@yKP5p7>dtuLw1LglZSVH3j~u+ zBZ9gWYBmfC!(cFGaV?f|(r7de+3_MJ(A4qvSb~a)cLAD<)$FZpS^Bg$v7#O8DDgcD zJ6;e{uNgvFkBv|hri($QeX>OP!vr*9l*4u=xM$2^_5B%#bti!v!WpD+O|VNHF}b_w z#B+dc|ByHX7I9~wFb&F@Tnb!$E$O5dtdm>m-37x?vSXO`NE6il#8Rx+yk%2f6<@H;F7e|i#Woeot_R#+e7Lwv@LBYc*qy) z5jLLK|J+@wLxEN>Xn%X!YV_JW1;Z}+J(QP60g2j?tMdrHrTOtvJJang-I(ptH|tfy zn`kg{>_l;6t!qzZf=oFIjg82x!fWv-h-eEEpD`l?H~W8Dv;@I4$BNBfmZdOpiK&aZW>m8PBq@v zg>t)+9U*qQfp>^@!oTvj)QYp30mg_^sDCYe*1v!-O4*zg{?{A$Gw77VMxD{I-`(*P z%E&0gpX%AU_*)-}$C)8?9w){#g9s7KwGjG7Nt6`9woNz!t%iiJOQNo4|A|Np*17?K z_(|*x$nM<~AL=8UK`F?g)#v}(SB;j-m-?t@k%in{*7MBrvmWI}@!pqrPOdFb+_^zp zSgi}T^P}v_uP-0p;=c2dU7~IK-Zv4A9orPFs;++dwWdyDR+|-+O8OpN{-1%aLtGI< zSACb}c1QC-wY>$XYl6G}+d@o_yC6$PQtkd{$}F`>AdB>N z8U$QDnW&nbQOBc+C#w1)f`6JY}4al;*ltT#m^l;BeHm3ho z>3ckkST#rBg6wI&)dtwEwKup?GlLRAr!E5#@mYL-+DdF|cKgRMIE#e*(JYVy>7YXB z39gLPM$~pm3WTZ%f2^c=F?Ygr9U^>Eza5koB{OH6b4*Q;zvP-=2u7Te@>*cB(YO6= zHI}$FJOkS_t;#)ApH|{>E-d;-3GiA{0u&HHlckDDc{}^@fwC?3#Dz31_{4Gq`s`Hz zwjxmLPlT{&xIm>yn7T1(da&Ln#mF@hoLd2g*WWL)qHp~+oaWJjZ9YM~=Q<5?Ei}h) zBcuoovJ`UYehmNC`mF&L&W$f!%Q`CE;qT4G6S^jCk5iq}W>ri=yPW+FKai8lWKh2cy{rbsLTZJ1rGwh__gg|;WBXIK(koj*mh0l1zRXb6&5YK;k4la3*_7{(&);k8WZe(uID$#7zcO)#6ZQ!;S`u% zCjlNPluTU8UPVdO*(9otOp;ht!$Ex!+k%u1U%1Fab}mZ*w&osQ3&i!aWQVf)1pvHV zQoX=Jmy{5(P2+Fhf__Q)$wz9S+?k{i8N4B5;eoc5Ibu|0ePKA?dT%%00p5>(Wl7p3 z>FmrO4Lp{k0D&?k$3{OcJn2i^C><*8<^iWIjW44yo5FX3WfyGZrcShYY~88vcTR)2 z0|Jpumq;FKR{dcKdi>iL4%u=m!uu zk!J3JgBJs99&)a;C9gk2a>4gO*NFgumVeeG&Um_*fu_FdyK(OCWnXkqAr1)tU$bs950bguB?v4F0ZeX0-RsiY?nGEx^Y zt0k-DY0z?D@SBrcRbhBS4vhA9_1p)#TXs0OQ#z_O#C+h^)+W&$s7-OBplgGPl~I_e zH7Oj@+0&LkXtum?g_%hRQ$h0jspY9(UU6LJ8yNFeyfd!^j)~1q8DnQq1oz(Sl5Uxq zlbMS;Hg$Pw;N7J72rz7QuYG%Mm+ksdJjY4vK6!A4O8U_9r0e<`i+!sS%JNU?Ibda{ zgXTp&;CvPDId(@?-1%X-#CRob1GlPxSEaR?4l-qw)D0-(lR!UGB1U&h8kppvB-@GE zu+eOvAo6gk9X#+%{7csliWhKmo%1A2 ziLQ7+c9UvAp<;}4scTB*vc#QUm>w+u94Z?}mdIn(#2EM191k4qV8}-MOueH-n&^c> z^gm>AM=A{`&Qwq~nD}}K@d-51Cc{eHNG*@UMluRO?U7*&kASXYgxuMv(sX>2>7(N0 z)oX(k&J6eeO+=&4U_$Ki&pnj3Z9Fz*VM64JK&97OQW%(h_aD}{tZ0SLN*%qg(OcJmlFC3hdt%Sj9CEVx?hSL z)N|7Z6HHpFR85}$)O{I!_HYr0HsuL%Zk+oUpTwqgOs*I7cwUl05mm;XX%O^NglA*0 zToAy|e*`cPiuM}UR8UPvLtQWZA^1f-t>fY)_Mh2@nJP(_9AfVjcPs)2zLFo;G60lw z6?{PP2GGgStEC6!9#C>?=~69vzh`lJw08bxKiXO1qH9tYJp8#t@H)jLu0Q`W&x33U z7v%bH3q?m^VrPv2-!$3zL#shO_AA~j*NRss$0oj2RDqQwQ!y7P5+Su!3XS20=-pAV$=f6 z0_Lvf%bktCe}f>&?X_Y2B%V<}{Lk#;@YA7G?Uc6!gbx@^i(K?f6S#u~$-J>bPl_7) z%f@@8qZzKGm=s$#z7VqKnSs{W`>7p2Mfa?N^lPnF zhS1el!TUzB^76sL$Cq1xBV+Q-?aB5?h()vHdVn8#@S{am&WaQ(K2E%Ovbgj59i8-aZf6Vb_6_uS zZ+`^e9+b6dWv#l+-_X9kw?a*y+P8*k7jkN3#Epg*5KoLJk0+LBjOt&{RjM}~-hI&H z_d~P&+fBA-+t}kkKmPc^(b0S<`DD&8Eo$d(Xzcd=jeg}?EKYGSjy7x5KC0;g%L>^w zyv%)`GA}4<8`Yg><+CHq@cC`x93sJZMRptIh|?I-XjRia)pm|kZFRm+`(u8*z1|I$ zhKQK9E{|No@+DrZO$K?ipi>`rk0R+1ULOma1daG2-`?t1nC@U-li}Mx_vzAZOkd`M z8H21id8JGs6R>IcQ^p^IX?g5M5_bLAt3YfOMb#1mY#gQ1lGbd8n^vD1FIq3kj*@X3`gN^YQxx3_{u?1g6<2#o}(-L!H ziS=FM{9i#?8d(qoyoQlYQ46t}bxZTiN!>~Ra>65lb8b0h9a}CM>%1~Q$!tEQo;?IF zC`b{9pBv-59IUhPHP7``#IpDu=LIVemjB3S{*or-MwS?YK%zh(HNGEy(iJ^0iqG*+u7+)?6&uZ_iPq|gF9Kp)J-iyaj4Mq0@;MKK&H zuM)rJ12Rg?Owx`{X~b-NP9HwI*;qJ~j5!Ev90o;e!0xt1V9sTCdk4}_9pnYt%gkBT z*%-1S%9oa4H#X=ODTyPT-}266w)&vA{nrBRk6TWyFuegvLjq|5MgX#AO(x6xy}=&s?7 znxu4~B(*s?eM*QMZz3%_rq&nC_bWXr`ZCSyG&b7!!P=s>=C*(eXZE_>h=6_+AwLXoT;g z64x&{YrZwE|BibcqTDK~5w7wh`7D;x>J~qQDu(FsVkor54XVew95n6{T`LdyF9C?i zTrEu|H_BPnEe>lppRrN#a??@+UL7x3^!3q(K~XT5;tV3ZGt`z*@s>u>13uo((8%xa z?|F-6$1~S9Jn9Vb5jtRmKrIULDx91C>nuvz7b_bJYMAw&!ewfFnIVuUS2_q+9E=7ntvZ!z`*vOLrXx!5kiW8>Z9o5A#sFIM9=CPMKlwn1^Cty?KzE#X z@$wzd7y<)sLM^4!zlCiC8xq(Fa$m?7yuIyuF{DNGYoWk#n9M9XC0uixgZp;X%!P>7 zdqJh$%Dw(^$G(p7_!>l1rL%v)8dltWD>}Ata)0COj_XQiLLSqi2f~qjmH5agy6v#K zx$s^#4F5uFO|ha5Inq@UtAt)A4&Jd4GXe-OA^kAq1P{cBB{-rHP{~Xq_c(tQpV01?p5bnEN~ct-eTzI_hyx}r=9If9Y9=J64#qAe@RvEY_L&!u2=0=W~YRn6^(~({E~JF zcgZ2tWgb)(3B$mbY`$gI;adY#bVEsQDsR{6VvRU6ZNF~2)bTax2_BY*gyHAf(a&k5 zN<}&-w)x^q!;>vW~ILKaOS8=7Are|iZF1YPzKPJZiyN~oqP-tU+TNXsE7~<_b zUQ{~T5KFmHXpbtsWOb~SD(I!>+l{wB@S9{P;zH4nhs`YCtkOm}JmL56>%{A{?KQ3r zh59hUI4ELjV=rSQvqWQ;@kaVA!-&ZA9R#~LWsC|Km~ z#aKS?3U?d35aL*DrY$<`+bb(@K}Q0_+PO4#BY8M(n?$dShQnt~p76g|`0d17)@KDY z(3hAy-7J+T!D~^0bimoxxtlzoj(qHPk?GeD=J03q-6_WV?Q7g({A|f}HgRUTDO2I+ zvRezE3GG%HS<%G20o>WT&qMd%EUC9+wU>9tUE`#gWZ;d7-MmJn&R-Fuv`6ktqr;3# zrzoi?I>qF`L)zy3HMMD{HTTnItU|V&fSY!d@9Eyx2@hy9=##$dUa4{@Y1@$y%M-CY zMe&;4XW@%{T#H=CIQq+ID@KG(41Oy}{XvJ&kXax7wx z7IsChQs(I~UxZ_1;vqNOf{Mg<{)fT`fBa)c%W_Kg0sQ@{d#a-#_sXm=BWh0grXoV8~ixgMr7bnC*WvxZaxn zcx81&5xn!yGmHN(yzocqadBvWuw+>*us@-ng-%posU4O)jh$WB^x78_$c;#J zI#AU(JI*_|3@}ik;lx_Zi*2%O&h#qH7oJp5b}nsy;g>CwF%!Efh@0JFW7#)ZV;M`V zYOgr8wVe>CEJg+kQ#D=FfmxjeD&@`!UtG0s*R{G5tYlXZOH(Wr8)9g)VdvG`yN-74 zG8*#nwy4X^bWkzrqAZ(F`peAoe6WIvODky3;~R_D3mkcff-846j*R7>^!c2uIrO|D zH5dDJ{YW7Wn}s;fH20o3lOg|8wh3Bql3A&LJj$RegwwOHytd$uni2i}uE=LQOoMMJ za0#pT6usPPX&NlYzN3OIQW*WpetA4F!?im3QuzCqdv#0u>mR749dvX^Q>G_#5={Lb z8I9!;UAdLScN+tJ6L#wBI2AAi?G9#N^uQeFuAZ_u$p}lqe{EM7g9Y=A0gYtWN{sPa zy`YF_xVp(hwd`~)?IQKGFZ1YKna+)otbVFpr&e~k>jW5;*{GJ9A-R_aGVy1gDjAGS z_q91L3a`5e@Fv0-ivONYWA(+wF1s)@bMw#$Z&!|F)@nXy;nMLtU1dwk`ZGVx?bYQ= zz8?+WLf@OFU4(a7OHncPuAoLO-L+h+!vQlaYh`CinuF%b$By`CL?oC8#RM9`NCGn| zwnry!@yy=a8J26sS#Q?Lb^$^fJXaXV`F@j|;TW`fSW}8I*f=Jt)wKL%sP=v%Ye~Rxi>UIQ?$C@#dYihMIf-eXFmg2amKsH$0`u;)<3QJPJ|l@VR=Pc@>u zHq-YOKz^ltgKLpAS&@ED!MWUDHp{TWx5alQf*ZFXbIOvhLxnLIa&J|HxY)h{=Lg0H z3F|Dl;_n4lwuq+zM&?ECEwZtbIuY@v#y!Z5wnQ%&GSi=we^3-o=EY|vSWnc0HeR&o zL7wVS>CMy9ykK&maNa2^3EVBLt@o5WOw$fB-u_C>9PE#67=wMk&EmaMZR2p&Fw-&c zG}oz})^?YYCZ<)7Uw9u0{wn~ah_#Nr#R;;-V@fNHnTj;8JVrb3X2)UQqR=n??h-+I9Hm!c*q$bt`QpUe9o1Zq=|UsWyT z#TI5ICrGRITBgzT`}XqG9l9eIls_eVo%+BYzPtD2hyoim;+{?Z{fO7+IB?fMWOi|` zzJC?Cze87t?^+cuSk4eSIc8riaIDkQB|6V(!A0I9c#Z$y!d1}i-AfsApXHVMJ!Lkj z{#EQ`J3n0y1`E{;0`4o+2O<1SigK}Rn4l>))HQU9Vf_;tgW;zkur6Te<@%t*OR7}l zGT#Zb==7D^vU>#|?CXD>9|TZmv2+ren7-!j!v6^!JxV+Awx#1+)pJt7zmyO&KUBF< zD22R`{K=C!?nJFv(ZRw+q%*V=Hx6?@TEAh3&gXvlC}81mfBvL6ROp!N8&orC07j9X z>l>Hh{)1f6w-khG!zp@OLpz>E&NS3@d6A#>?Vy{W*EWkZ^r>xdq;82)oM|<6(0st~AAx1N%Qm+{ zEgt0#Zgy&+*-btNvSgu=5e?PGyb){>LD;5 zQsyJk3il0tzrtdhi#6&JmMEN&42i>Nra^<^!^y!cB}0|JGlAQx2z+(+zv1o`bkX^~ z${XS$eM%SV(_G1%RjaYKvxn9LE8?5UB(I&n@CY^B9xrp_P*Yn|7w4`2v{hxze+T7P zaQX4FY=vvHU(5|n!#C=!mEBn0*E81}!kVev^G{KIJ@Mc1#Rav4kMZHP6so@`2A$kW zy+bqj53=(=W0|k*iNxCU{~*%;$`Ma@C?@^y7`FFoyX3y7ODl67qsjl##}i|)3a2 z*qGDi-V0Pe{2fmiwBt50*b?`=nSV%#b!RGV&1um&&(v5Hhx@!UGwH(nfTeaDtmf{y zH7xQI?=f|c-&>caOSNf&!v-`kuMdG(Sp#U&eh4`wI(3^rRDl$p{w~gzlscC|lj%@; zr27%a7WGE(9C9lzZ{xWmg5<|wMiD%{1ZqOXCZ&&a$1h0K+*@#O8GFalX8M^^w7F8G z6y#whZ)N*M4EWUC!^r=yy)zAK>e~8vv~{SUXq`pHY8??GC?KF9RHT(rD2X5e6_FV% z5GY|%xel#@0}2LYR3j1+xRNj=5Y$>N5D*Lj!l)u334;P5Kumbojzg{YeV(`X(>uXO zl5@^J`|Pv!8h-zknWC%(qQ53nvrUm@NH;En4q)iakeN}-3K%O zm-|%=(;?6{pgxC8)^a=T)mBnmxN=v-=U1Rn6rn~HB6F^6v`4ZSE&wMl2z1TZ<@!%w zb!Xj(8>~OGJJ+%QCvTU|a_w}^&}X;9Oqwa&89uTNgh4u}B9EL7q?QqYEJ?rTW_(HI z;-N;j3*;!-c$nzAUBaa$PCQT;+YF&3zc)zYG#6mC1p=G8G`o5lA4XZRIcrjTRJkBU^puaSoE8P)zF?K zaDgG^3zZ!;h`B(DaA)W#Mga*LdviY2Mh5I~vrY{m^t5E8$>-?stJ(rzBqe~*tHAuY z(!dYD$2Dvu>aSY#ZoOzwe0UT}!#8KHne;UY%4UC&Er%{HR0~)w!t<^&#Z$yveJMuz z(c&Q3RxhKX6!48+^5NUYH87h4xp*lUPKx}p?*{<$OT^kPh(SpL`Lh+3b*Sv!!^=4-QIO2`0 z9xa=Y8V|{(1IY-iULMkTh&+Cnp~1Y~9?Y}q8mz=k;sURT#9Zajk>?poHuDJ?9q0rWlKyNqvvM? z`MMFrA7HkAg-pt>I(UlUMwH#vcrZ%@)u<6o9#S?R24}~A4t;!Tmj4^!%62+|&DHkS zug4to)=1lO=wu3R@#~i%dmZ=C{?MRu4*oiI806LY!p_SUnp$a*BV=&vD=mRovw|{P z)%vuE!=RE*aO?tjcndnwKzTx6|mC~d+we6HtG!nfN&QxvLC zF=c_Y-e}@&5F(+I;4DuQpx{%n9J-s0R2B&xa1}oLE5f|Uw^K=*wqld;VRw~h!ppem zhLW>7E+?-Hk3=bC17fy}D>7}9a3nj~T%b{^fE_%9_!=bmmrB!GPHSc&{Tw-rfZ?4g zd8ys``jm^uxWFShw7_2nnnpaKs_G>z?Y&ttAmU)nBS#z!_m(6# zM7|bw^>+c??5dg-AH(S>K@c@6-dj2r*KMM2X$3VVTZ2fQ0AYBq*-TjxZphB%H@oU{ z>2cS<5Ngd5j+fe=8%N@wMGn*UT{Q-EKkEAs;zV?nHZ}APhn7hR;qxp@y<2qUZ`3Ag zeRF120c@pRN)l@WV7_JIwaUcBJJ>|*aK)V)=E=qmvYp$#fPyz>2m{XbTiIyZZ^&wo zkcqqQI8eDZDu&!)+TaoX@O3Yqwiu6>r5XoL$jD*LY!ypij}f!QWU)i^)&>1+wcv}z z6VPEH2UzoWQ`H(i{4Lnr7Y_C&t+k15A}VJ?_9+4lM}LdhdDNN#BB^s*ot5x`k$0%+ zsj9d%Acb<=`3ni|{w}W73vVt=CkUdXeI9I$YN-S%|9v-Xa7VG6*iM2g4b zo1n-@Si~$S8>~)o&R4QAjL#Xii-q!pU>?4PPx@%>J78a%=JT~O~jMgq~XiC7< z-7UE(3UxLiL>tBvI|om>ILaE`j>>xlZRoZphMz?1u8$Th!zSSz1IfUn1?3OQrB&+< zL#~-aDOT7dm$L_wBmm2WuoGzx(T^9(<3;O{dr(baeU03MY+AYzXk)@5C(dXDD&2Pp z-zX@t>K5(@^T?PGZBoK7iOdA5gB78bpG~6=ly^ol&a-G>V+3uaGz1s|XwhaZ;)KhJ z`o*NGA9H&YOWZ$xzRpvPdj&=uU8^ zLk8RQ)=vcVd^{cWvV898M&5Uz=CUGul1sxS1t;t@?EUqbxE>?l*v<6tJe^r%0CHXD z$F_t$J2Aso5~jgRH;JjM{GND{1h8-4J>O+N3IYFNe&eLkT}}*cTQ+RZLX2M>X(gPsYUA^Q67`7y3e|K~GEivG`JoMc8Z$ee8-G)9>*}O{Z0rFTTIsTQG0w zl3oEXVdC`}<89HSV30tx5idB+Dy3T9ctmwsyxMQ>=v|I8r$&ALIZf}3yn&)@Gkk*$& z9S{GBr_*pmNHk_o&kI`fK&7Xye7S(>Loou}D5D8Qyb|10%v_dmI?=BK*quVxz=gI% zmBN)@QKamJ2Jw|~P@)Y{b!hw%Qy*q z=$}XZ$#zp|*F&1TMwH}0=lRaKU}qr*w@F((tB17#>RDmx7@wNLz*JXyC-M1xyu_2g z*q_fHJDhuHWB09NbZILy795W!TqsJldDz&RD@SA$UONnI4eL15i?>c{c-y3FxY3N6 zP3=#U_oVrThVE=N847&x)%wQHGFe}MM@7YRrPAu0Y_}gJL9uT+vKSREsL=-Qa@`%e zU-vf$G}}gY@bMlM{Jl{Ge!Ft)C_TKE&m_b=C?JjC`=8()KQEJdasg3pR?D{Ja z3zBR$R^GgIzatQ%pOOK-c~WNgZT4g4 zFR9ejoZKHcHOUsVCU5Zw|Cg1&kK|{&FQ7*fNjQ>!v1b@9G1rCR+Sgv#2Y~-OFPOG2 zhIDJ6#TewPE|J@#CuDv$CqQH8t}!FM{}Y$}y&Ju=3>w-rKc@7!)Ilk}sRuP#VLPPs*;nxn!gV4_ni&MY+VQc#!(E7T|Yh}*o3Iz<7+PLctK->7S{JT z2coH}OtW*^ogj#h1EqG{7(X`(sV#ge7gR?h?-E3<&GlpI^rF@IB@ae(9P@pP)p=$Z z!m8~Z=eMH1R8a0Wdfzqwpvh$RcAIrE_N zLG=|MC)%KYTSKNM%yIQBa0EbX-N#6X?jn0=BdxH>hlK@$mH^qg1;Cq(R&a!l4YZw)sx>@v(IzDTL&cQ{aW6v zXlHj&4e5ehq5twHCYB8+G!(E}0<3yJuJdy`S%x6_RKTv#xBKbdwoLm( zVPKigKOuu+YSs`6k=fd+m^L3ppur^YQ9KO^#085#h|HKHIW(9-5qS+6U@O7!|1D_49 zact%vkWAOyn&vCOQHRpx!|NgGpsH#On(zR>mLjeE^YuiV)J70sQk-q>f=1N*s1cqc z>uTnhifh4Fhu$o6hS=@0YDHEftn+FJ`DK(&N<`*qo4~N0DQ-wK7RJoG0Nvc;roE_$ z$OWm|I|~EZqvNM_-)2t}RCP}$GFP+1mToz?i?a5>ww<0es|-_|@txnDRxamuR}{8K zG~*M85cYSG{@B4fY1_u3@3}9dg47~=;+@#(iO3D6vR(6$z zP7mVUHMcS)jC-`##71Kpk3v z#Nw0FrXRgJs64dyqqXX>sJ{?3yat1**z?J^6g%Tz_o@%6#D8;(n>-ABjQ`U!san^J z^5U01`cMDrr$Aa7vr6N`egdiIzvtde9`?Qt@u$Z(IVF=*@?XaVldEKMl}xUZ$sGq} zaz7>uCXK?RQJ6Fe|38d^mFry$=KD%Xv{D`$K^*Y+@Bf0yf7>BvXAAwBLUqFRJf9KJ z(19F`1xbA~!&mUMxAsNe2&GmYTdJhEt>dg((1i0qvXyVn>!Mla$IN-7`K96@;U1J5 z?eC&;fx-S=gR`001!&v@X@0)hxw)SmCuWfmQdAe<< z6ldSn=M8iVk{WPP;W+=Xiln7|Lr&q2oYL7MMh@baFt&Pim+2RypahmQ5IGR8nWc6x zhBcM#RNox(>ga$YWX&F(pANJ(@SC%Fulkp5x0c+bve^$2Q%y4bkl<; F{{#1?apC{~ literal 0 HcmV?d00001 diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 7954386..7cad078 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -167,10 +167,10 @@ push-location $path_root $build_args += $flag_output_path + $module_dll $build_args += ($flag_collection + $pkg_collection_thirdparty) # $build_args += $flag_micro_architecture_native - $build_args += $flag_use_separate_modules - $build_args += $flag_thread_count + $CoreCount_Physical - $build_args += $flag_optimize_none - # $build_args += $flag_optimize_minimal + # $build_args += $flag_use_separate_modules + # $build_args += $flag_thread_count + $CoreCount_Physical + # $build_args += $flag_optimize_none + $build_args += $flag_optimize_minimal # $build_args += $flag_optimize_speed # $build_args += $falg_optimize_aggressive $build_args += $flag_debug @@ -249,8 +249,8 @@ push-location $path_root $build_args += $flag_output_path + $executable $build_args += ($flag_collection + $pkg_collection_thirdparty) # $build_args += $flag_micro_architecture_native - $build_args += $flag_use_separate_modules - $build_args += $flag_thread_count + $CoreCount_Physical + # $build_args += $flag_use_separate_modules + # $build_args += $flag_thread_count + $CoreCount_Physical $build_args += $flag_optimize_none # $build_args += $flag_optimize_minimal # $build_args += $flag_optimize_speed