pax_global_header00006660000000000000000000000064147762165620014532gustar00rootroot0000000000000052 comment=11c034454bf993812476947a9cd29aeb67b7596f reform-tools-1.71/000077500000000000000000000000001477621656200141125ustar00rootroot00000000000000reform-tools-1.71/.clang-format000066400000000000000000000545361477621656200165020ustar00rootroot00000000000000# SPDX-License-Identifier: GPL-2.0 # # clang-format configuration file. Intended for clang-format >= 11. # # For more information, see: # # Documentation/dev-tools/clang-format.rst # https://clang.llvm.org/docs/ClangFormat.html # https://clang.llvm.org/docs/ClangFormatStyleOptions.html # --- AccessModifierOffset: -4 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false AlignEscapedNewlines: Left AlignOperands: true AlignTrailingComments: false AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: false BinPackArguments: true BinPackParameters: true BraceWrapping: AfterClass: false AfterControlStatement: false AfterEnum: false AfterFunction: true AfterNamespace: true AfterObjCDeclaration: false AfterStruct: false AfterUnion: false AfterExternBlock: false BeforeCatch: false BeforeElse: false IndentBraces: false SplitEmptyFunction: true SplitEmptyRecord: true SplitEmptyNamespace: true BreakBeforeBinaryOperators: None BreakBeforeBraces: Custom BreakBeforeInheritanceComma: false BreakBeforeTernaryOperators: false BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeComma BreakAfterJavaFieldAnnotations: false BreakStringLiterals: false ColumnLimit: 80 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerIndentWidth: 8 ContinuationIndentWidth: 8 Cpp11BracedListStyle: false DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: false # Taken from: # git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ tools/ \ # | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \ # | LC_ALL=C sort -u ForEachMacros: - '__ata_qc_for_each' - '__bio_for_each_bvec' - '__bio_for_each_segment' - '__evlist__for_each_entry' - '__evlist__for_each_entry_continue' - '__evlist__for_each_entry_from' - '__evlist__for_each_entry_reverse' - '__evlist__for_each_entry_safe' - '__for_each_mem_range' - '__for_each_mem_range_rev' - '__for_each_thread' - '__hlist_for_each_rcu' - '__map__for_each_symbol_by_name' - '__pci_bus_for_each_res0' - '__pci_bus_for_each_res1' - '__pci_dev_for_each_res0' - '__pci_dev_for_each_res1' - '__perf_evlist__for_each_entry' - '__perf_evlist__for_each_entry_reverse' - '__perf_evlist__for_each_entry_safe' - '__rq_for_each_bio' - '__shost_for_each_device' - '__sym_for_each' - 'apei_estatus_for_each_section' - 'ata_for_each_dev' - 'ata_for_each_link' - 'ata_qc_for_each' - 'ata_qc_for_each_raw' - 'ata_qc_for_each_with_internal' - 'ax25_for_each' - 'ax25_uid_for_each' - 'bio_for_each_bvec' - 'bio_for_each_bvec_all' - 'bio_for_each_folio_all' - 'bio_for_each_integrity_vec' - 'bio_for_each_segment' - 'bio_for_each_segment_all' - 'bio_list_for_each' - 'bip_for_each_vec' - 'bond_for_each_slave' - 'bond_for_each_slave_rcu' - 'bpf_for_each' - 'bpf_for_each_reg_in_vstate' - 'bpf_for_each_reg_in_vstate_mask' - 'bpf_for_each_spilled_reg' - 'bpf_object__for_each_map' - 'bpf_object__for_each_program' - 'btree_for_each_safe128' - 'btree_for_each_safe32' - 'btree_for_each_safe64' - 'btree_for_each_safel' - 'card_for_each_dev' - 'cgroup_taskset_for_each' - 'cgroup_taskset_for_each_leader' - 'cpu_aggr_map__for_each_idx' - 'cpufreq_for_each_efficient_entry_idx' - 'cpufreq_for_each_entry' - 'cpufreq_for_each_entry_idx' - 'cpufreq_for_each_valid_entry' - 'cpufreq_for_each_valid_entry_idx' - 'css_for_each_child' - 'css_for_each_descendant_post' - 'css_for_each_descendant_pre' - 'damon_for_each_region' - 'damon_for_each_region_from' - 'damon_for_each_region_safe' - 'damon_for_each_scheme' - 'damon_for_each_scheme_safe' - 'damon_for_each_target' - 'damon_for_each_target_safe' - 'damos_for_each_filter' - 'damos_for_each_filter_safe' - 'damos_for_each_quota_goal' - 'damos_for_each_quota_goal_safe' - 'data__for_each_file' - 'data__for_each_file_new' - 'data__for_each_file_start' - 'device_for_each_child_node' - 'device_for_each_child_node_scoped' - 'dma_fence_array_for_each' - 'dma_fence_chain_for_each' - 'dma_fence_unwrap_for_each' - 'dma_resv_for_each_fence' - 'dma_resv_for_each_fence_unlocked' - 'do_for_each_ftrace_op' - 'drm_atomic_crtc_for_each_plane' - 'drm_atomic_crtc_state_for_each_plane' - 'drm_atomic_crtc_state_for_each_plane_state' - 'drm_atomic_for_each_plane_damage' - 'drm_client_for_each_connector_iter' - 'drm_client_for_each_modeset' - 'drm_connector_for_each_possible_encoder' - 'drm_exec_for_each_locked_object' - 'drm_exec_for_each_locked_object_reverse' - 'drm_for_each_bridge_in_chain' - 'drm_for_each_connector_iter' - 'drm_for_each_crtc' - 'drm_for_each_crtc_reverse' - 'drm_for_each_encoder' - 'drm_for_each_encoder_mask' - 'drm_for_each_fb' - 'drm_for_each_legacy_plane' - 'drm_for_each_plane' - 'drm_for_each_plane_mask' - 'drm_for_each_privobj' - 'drm_gem_for_each_gpuvm_bo' - 'drm_gem_for_each_gpuvm_bo_safe' - 'drm_gpuva_for_each_op' - 'drm_gpuva_for_each_op_from_reverse' - 'drm_gpuva_for_each_op_reverse' - 'drm_gpuva_for_each_op_safe' - 'drm_gpuvm_bo_for_each_va' - 'drm_gpuvm_bo_for_each_va_safe' - 'drm_gpuvm_for_each_va' - 'drm_gpuvm_for_each_va_range' - 'drm_gpuvm_for_each_va_range_safe' - 'drm_gpuvm_for_each_va_safe' - 'drm_mm_for_each_hole' - 'drm_mm_for_each_node' - 'drm_mm_for_each_node_in_range' - 'drm_mm_for_each_node_safe' - 'dsa_switch_for_each_available_port' - 'dsa_switch_for_each_cpu_port' - 'dsa_switch_for_each_cpu_port_continue_reverse' - 'dsa_switch_for_each_port' - 'dsa_switch_for_each_port_continue_reverse' - 'dsa_switch_for_each_port_safe' - 'dsa_switch_for_each_user_port' - 'dsa_switch_for_each_user_port_continue_reverse' - 'dsa_tree_for_each_cpu_port' - 'dsa_tree_for_each_user_port' - 'dsa_tree_for_each_user_port_continue_reverse' - 'dso__for_each_symbol' - 'elf_hash_for_each_possible' - 'elf_symtab__for_each_symbol' - 'evlist__for_each_cpu' - 'evlist__for_each_entry' - 'evlist__for_each_entry_continue' - 'evlist__for_each_entry_from' - 'evlist__for_each_entry_reverse' - 'evlist__for_each_entry_safe' - 'flow_action_for_each' - 'for_each_acpi_consumer_dev' - 'for_each_acpi_dev_match' - 'for_each_active_dev_scope' - 'for_each_active_drhd_unit' - 'for_each_active_iommu' - 'for_each_active_route' - 'for_each_aggr_pgid' - 'for_each_and_bit' - 'for_each_andnot_bit' - 'for_each_available_child_of_node' - 'for_each_available_child_of_node_scoped' - 'for_each_bench' - 'for_each_bio' - 'for_each_board_func_rsrc' - 'for_each_btf_ext_rec' - 'for_each_btf_ext_sec' - 'for_each_bvec' - 'for_each_card_auxs' - 'for_each_card_auxs_safe' - 'for_each_card_components' - 'for_each_card_dapms' - 'for_each_card_pre_auxs' - 'for_each_card_prelinks' - 'for_each_card_rtds' - 'for_each_card_rtds_safe' - 'for_each_card_widgets' - 'for_each_card_widgets_safe' - 'for_each_cgroup_storage_type' - 'for_each_child_of_node' - 'for_each_child_of_node_scoped' - 'for_each_clear_bit' - 'for_each_clear_bit_from' - 'for_each_clear_bitrange' - 'for_each_clear_bitrange_from' - 'for_each_cmd' - 'for_each_cmsghdr' - 'for_each_collection' - 'for_each_comp_order' - 'for_each_compatible_node' - 'for_each_component_dais' - 'for_each_component_dais_safe' - 'for_each_conduit' - 'for_each_console' - 'for_each_console_srcu' - 'for_each_cpu' - 'for_each_cpu_and' - 'for_each_cpu_andnot' - 'for_each_cpu_from' - 'for_each_cpu_or' - 'for_each_cpu_wrap' - 'for_each_dapm_widgets' - 'for_each_dedup_cand' - 'for_each_dev_addr' - 'for_each_dev_scope' - 'for_each_dma_cap_mask' - 'for_each_dpcm_be' - 'for_each_dpcm_be_rollback' - 'for_each_dpcm_be_safe' - 'for_each_dpcm_fe' - 'for_each_drhd_unit' - 'for_each_dss_dev' - 'for_each_efi_memory_desc' - 'for_each_efi_memory_desc_in_map' - 'for_each_element' - 'for_each_element_extid' - 'for_each_element_id' - 'for_each_enabled_cpu' - 'for_each_endpoint_of_node' - 'for_each_event' - 'for_each_event_tps' - 'for_each_evictable_lru' - 'for_each_fib6_node_rt_rcu' - 'for_each_fib6_walker_rt' - 'for_each_file_lock' - 'for_each_free_mem_pfn_range_in_zone_from' - 'for_each_free_mem_range' - 'for_each_free_mem_range_reverse' - 'for_each_func_rsrc' - 'for_each_gpiochip_node' - 'for_each_group_evsel' - 'for_each_group_evsel_head' - 'for_each_group_member' - 'for_each_group_member_head' - 'for_each_hstate' - 'for_each_hwgpio' - 'for_each_if' - 'for_each_inject_fn' - 'for_each_insn' - 'for_each_insn_op_loc' - 'for_each_insn_prefix' - 'for_each_intid' - 'for_each_iommu' - 'for_each_ip_tunnel_rcu' - 'for_each_irq_nr' - 'for_each_lang' - 'for_each_link_ch_maps' - 'for_each_link_codecs' - 'for_each_link_cpus' - 'for_each_link_platforms' - 'for_each_lru' - 'for_each_matching_node' - 'for_each_matching_node_and_match' - 'for_each_media_entity_data_link' - 'for_each_mem_pfn_range' - 'for_each_mem_range' - 'for_each_mem_range_rev' - 'for_each_mem_region' - 'for_each_member' - 'for_each_memory' - 'for_each_migratetype_order' - 'for_each_missing_reg' - 'for_each_mle_subelement' - 'for_each_mod_mem_type' - 'for_each_net' - 'for_each_net_continue_reverse' - 'for_each_net_rcu' - 'for_each_netdev' - 'for_each_netdev_continue' - 'for_each_netdev_continue_rcu' - 'for_each_netdev_continue_reverse' - 'for_each_netdev_dump' - 'for_each_netdev_feature' - 'for_each_netdev_in_bond_rcu' - 'for_each_netdev_rcu' - 'for_each_netdev_reverse' - 'for_each_netdev_safe' - 'for_each_new_connector_in_state' - 'for_each_new_crtc_in_state' - 'for_each_new_mst_mgr_in_state' - 'for_each_new_plane_in_state' - 'for_each_new_plane_in_state_reverse' - 'for_each_new_private_obj_in_state' - 'for_each_new_reg' - 'for_each_nhlt_endpoint' - 'for_each_nhlt_endpoint_fmtcfg' - 'for_each_nhlt_fmtcfg' - 'for_each_node' - 'for_each_node_by_name' - 'for_each_node_by_type' - 'for_each_node_mask' - 'for_each_node_state' - 'for_each_node_with_cpus' - 'for_each_node_with_property' - 'for_each_nonreserved_multicast_dest_pgid' - 'for_each_numa_hop_mask' - 'for_each_of_allnodes' - 'for_each_of_allnodes_from' - 'for_each_of_cpu_node' - 'for_each_of_pci_range' - 'for_each_old_connector_in_state' - 'for_each_old_crtc_in_state' - 'for_each_old_mst_mgr_in_state' - 'for_each_old_plane_in_state' - 'for_each_old_private_obj_in_state' - 'for_each_oldnew_connector_in_state' - 'for_each_oldnew_crtc_in_state' - 'for_each_oldnew_mst_mgr_in_state' - 'for_each_oldnew_plane_in_state' - 'for_each_oldnew_plane_in_state_reverse' - 'for_each_oldnew_private_obj_in_state' - 'for_each_online_cpu' - 'for_each_online_node' - 'for_each_online_pgdat' - 'for_each_or_bit' - 'for_each_path' - 'for_each_pci_bridge' - 'for_each_pci_dev' - 'for_each_pcm_streams' - 'for_each_physmem_range' - 'for_each_populated_zone' - 'for_each_possible_cpu' - 'for_each_present_blessed_reg' - 'for_each_present_cpu' - 'for_each_prime_number' - 'for_each_prime_number_from' - 'for_each_probe_cache_entry' - 'for_each_process' - 'for_each_process_thread' - 'for_each_prop_codec_conf' - 'for_each_prop_dai_codec' - 'for_each_prop_dai_cpu' - 'for_each_prop_dlc_codecs' - 'for_each_prop_dlc_cpus' - 'for_each_prop_dlc_platforms' - 'for_each_property_of_node' - 'for_each_reg' - 'for_each_reg_filtered' - 'for_each_reloc' - 'for_each_reloc_from' - 'for_each_requested_gpio' - 'for_each_requested_gpio_in_range' - 'for_each_reserved_child_of_node' - 'for_each_reserved_mem_range' - 'for_each_reserved_mem_region' - 'for_each_rtd_ch_maps' - 'for_each_rtd_codec_dais' - 'for_each_rtd_components' - 'for_each_rtd_cpu_dais' - 'for_each_rtd_dais' - 'for_each_rtd_dais_reverse' - 'for_each_sband_iftype_data' - 'for_each_script' - 'for_each_sec' - 'for_each_set_bit' - 'for_each_set_bit_from' - 'for_each_set_bit_wrap' - 'for_each_set_bitrange' - 'for_each_set_bitrange_from' - 'for_each_set_clump8' - 'for_each_sg' - 'for_each_sg_dma_page' - 'for_each_sg_page' - 'for_each_sgtable_dma_page' - 'for_each_sgtable_dma_sg' - 'for_each_sgtable_page' - 'for_each_sgtable_sg' - 'for_each_sibling_event' - 'for_each_sta_active_link' - 'for_each_subelement' - 'for_each_subelement_extid' - 'for_each_subelement_id' - 'for_each_sublist' - 'for_each_subsystem' - 'for_each_supported_activate_fn' - 'for_each_supported_inject_fn' - 'for_each_sym' - 'for_each_test' - 'for_each_thread' - 'for_each_token' - 'for_each_unicast_dest_pgid' - 'for_each_valid_link' - 'for_each_vif_active_link' - 'for_each_vma' - 'for_each_vma_range' - 'for_each_vsi' - 'for_each_wakeup_source' - 'for_each_zone' - 'for_each_zone_zonelist' - 'for_each_zone_zonelist_nodemask' - 'func_for_each_insn' - 'fwnode_for_each_available_child_node' - 'fwnode_for_each_child_node' - 'fwnode_for_each_parent_node' - 'fwnode_graph_for_each_endpoint' - 'gadget_for_each_ep' - 'genradix_for_each' - 'genradix_for_each_from' - 'genradix_for_each_reverse' - 'hash_for_each' - 'hash_for_each_possible' - 'hash_for_each_possible_rcu' - 'hash_for_each_possible_rcu_notrace' - 'hash_for_each_possible_safe' - 'hash_for_each_rcu' - 'hash_for_each_safe' - 'hashmap__for_each_entry' - 'hashmap__for_each_entry_safe' - 'hashmap__for_each_key_entry' - 'hashmap__for_each_key_entry_safe' - 'hctx_for_each_ctx' - 'hists__for_each_format' - 'hists__for_each_sort_list' - 'hlist_bl_for_each_entry' - 'hlist_bl_for_each_entry_rcu' - 'hlist_bl_for_each_entry_safe' - 'hlist_for_each' - 'hlist_for_each_entry' - 'hlist_for_each_entry_continue' - 'hlist_for_each_entry_continue_rcu' - 'hlist_for_each_entry_continue_rcu_bh' - 'hlist_for_each_entry_from' - 'hlist_for_each_entry_from_rcu' - 'hlist_for_each_entry_rcu' - 'hlist_for_each_entry_rcu_bh' - 'hlist_for_each_entry_rcu_notrace' - 'hlist_for_each_entry_safe' - 'hlist_for_each_entry_srcu' - 'hlist_for_each_safe' - 'hlist_nulls_for_each_entry' - 'hlist_nulls_for_each_entry_from' - 'hlist_nulls_for_each_entry_rcu' - 'hlist_nulls_for_each_entry_safe' - 'i3c_bus_for_each_i2cdev' - 'i3c_bus_for_each_i3cdev' - 'idr_for_each_entry' - 'idr_for_each_entry_continue' - 'idr_for_each_entry_continue_ul' - 'idr_for_each_entry_ul' - 'in_dev_for_each_ifa_rcu' - 'in_dev_for_each_ifa_rtnl' - 'inet_bind_bucket_for_each' - 'interval_tree_for_each_span' - 'intlist__for_each_entry' - 'intlist__for_each_entry_safe' - 'kcore_copy__for_each_phdr' - 'key_for_each' - 'key_for_each_safe' - 'klp_for_each_func' - 'klp_for_each_func_safe' - 'klp_for_each_func_static' - 'klp_for_each_object' - 'klp_for_each_object_safe' - 'klp_for_each_object_static' - 'kunit_suite_for_each_test_case' - 'kvm_for_each_memslot' - 'kvm_for_each_memslot_in_gfn_range' - 'kvm_for_each_vcpu' - 'libbpf_nla_for_each_attr' - 'list_for_each' - 'list_for_each_codec' - 'list_for_each_codec_safe' - 'list_for_each_continue' - 'list_for_each_entry' - 'list_for_each_entry_continue' - 'list_for_each_entry_continue_rcu' - 'list_for_each_entry_continue_reverse' - 'list_for_each_entry_from' - 'list_for_each_entry_from_rcu' - 'list_for_each_entry_from_reverse' - 'list_for_each_entry_lockless' - 'list_for_each_entry_rcu' - 'list_for_each_entry_reverse' - 'list_for_each_entry_safe' - 'list_for_each_entry_safe_continue' - 'list_for_each_entry_safe_from' - 'list_for_each_entry_safe_reverse' - 'list_for_each_entry_srcu' - 'list_for_each_from' - 'list_for_each_prev' - 'list_for_each_prev_safe' - 'list_for_each_rcu' - 'list_for_each_reverse' - 'list_for_each_safe' - 'llist_for_each' - 'llist_for_each_entry' - 'llist_for_each_entry_safe' - 'llist_for_each_safe' - 'lwq_for_each_safe' - 'map__for_each_symbol' - 'map__for_each_symbol_by_name' - 'mas_for_each' - 'mci_for_each_dimm' - 'media_device_for_each_entity' - 'media_device_for_each_intf' - 'media_device_for_each_link' - 'media_device_for_each_pad' - 'media_entity_for_each_pad' - 'media_pipeline_for_each_entity' - 'media_pipeline_for_each_pad' - 'mlx5_lag_for_each_peer_mdev' - 'msi_domain_for_each_desc' - 'msi_for_each_desc' - 'mt_for_each' - 'nanddev_io_for_each_page' - 'netdev_for_each_lower_dev' - 'netdev_for_each_lower_private' - 'netdev_for_each_lower_private_rcu' - 'netdev_for_each_mc_addr' - 'netdev_for_each_synced_mc_addr' - 'netdev_for_each_synced_uc_addr' - 'netdev_for_each_uc_addr' - 'netdev_for_each_upper_dev_rcu' - 'netdev_hw_addr_list_for_each' - 'nft_rule_for_each_expr' - 'nla_for_each_attr' - 'nla_for_each_attr_type' - 'nla_for_each_nested' - 'nla_for_each_nested_type' - 'nlmsg_for_each_attr' - 'nlmsg_for_each_msg' - 'nr_neigh_for_each' - 'nr_neigh_for_each_safe' - 'nr_node_for_each' - 'nr_node_for_each_safe' - 'of_for_each_phandle' - 'of_property_for_each_string' - 'of_property_for_each_u32' - 'pci_bus_for_each_resource' - 'pci_dev_for_each_resource' - 'pcl_for_each_chunk' - 'pcl_for_each_segment' - 'pcm_for_each_format' - 'perf_config_items__for_each_entry' - 'perf_config_sections__for_each_entry' - 'perf_config_set__for_each_entry' - 'perf_cpu_map__for_each_cpu' - 'perf_cpu_map__for_each_cpu_skip_any' - 'perf_cpu_map__for_each_idx' - 'perf_evlist__for_each_entry' - 'perf_evlist__for_each_entry_reverse' - 'perf_evlist__for_each_entry_safe' - 'perf_evlist__for_each_evsel' - 'perf_evlist__for_each_mmap' - 'perf_hpp_list__for_each_format' - 'perf_hpp_list__for_each_format_safe' - 'perf_hpp_list__for_each_sort_list' - 'perf_hpp_list__for_each_sort_list_safe' - 'perf_tool_event__for_each_event' - 'plist_for_each' - 'plist_for_each_continue' - 'plist_for_each_entry' - 'plist_for_each_entry_continue' - 'plist_for_each_entry_safe' - 'plist_for_each_safe' - 'pnp_for_each_card' - 'pnp_for_each_dev' - 'protocol_for_each_card' - 'protocol_for_each_dev' - 'queue_for_each_hw_ctx' - 'radix_tree_for_each_slot' - 'radix_tree_for_each_tagged' - 'rb_for_each' - 'rbtree_postorder_for_each_entry_safe' - 'rdma_for_each_block' - 'rdma_for_each_port' - 'rdma_umem_for_each_dma_block' - 'resort_rb__for_each_entry' - 'resource_list_for_each_entry' - 'resource_list_for_each_entry_safe' - 'rhl_for_each_entry_rcu' - 'rhl_for_each_rcu' - 'rht_for_each' - 'rht_for_each_entry' - 'rht_for_each_entry_from' - 'rht_for_each_entry_rcu' - 'rht_for_each_entry_rcu_from' - 'rht_for_each_entry_safe' - 'rht_for_each_from' - 'rht_for_each_rcu' - 'rht_for_each_rcu_from' - 'rq_for_each_bvec' - 'rq_for_each_segment' - 'rq_list_for_each' - 'rq_list_for_each_safe' - 'sample_read_group__for_each' - 'scsi_for_each_prot_sg' - 'scsi_for_each_sg' - 'sctp_for_each_hentry' - 'sctp_skb_for_each' - 'sec_for_each_insn' - 'sec_for_each_insn_continue' - 'sec_for_each_insn_from' - 'sec_for_each_sym' - 'shdma_for_each_chan' - 'shost_for_each_device' - 'sk_for_each' - 'sk_for_each_bound' - 'sk_for_each_entry_offset_rcu' - 'sk_for_each_from' - 'sk_for_each_rcu' - 'sk_for_each_safe' - 'sk_nulls_for_each' - 'sk_nulls_for_each_from' - 'sk_nulls_for_each_rcu' - 'snd_array_for_each' - 'snd_pcm_group_for_each_entry' - 'snd_soc_dapm_widget_for_each_path' - 'snd_soc_dapm_widget_for_each_path_safe' - 'snd_soc_dapm_widget_for_each_sink_path' - 'snd_soc_dapm_widget_for_each_source_path' - 'sparsebit_for_each_set_range' - 'strlist__for_each_entry' - 'strlist__for_each_entry_safe' - 'sym_for_each_insn' - 'sym_for_each_insn_continue_reverse' - 'symbols__for_each_entry' - 'tb_property_for_each' - 'tcf_act_for_each_action' - 'tcf_exts_for_each_action' - 'ttm_resource_manager_for_each_res' - 'udp_portaddr_for_each_entry' - 'udp_portaddr_for_each_entry_rcu' - 'usb_hub_for_each_child' - 'v4l2_device_for_each_subdev' - 'v4l2_m2m_for_each_dst_buf' - 'v4l2_m2m_for_each_dst_buf_safe' - 'v4l2_m2m_for_each_src_buf' - 'v4l2_m2m_for_each_src_buf_safe' - 'virtio_device_for_each_vq' - 'while_for_each_ftrace_op' - 'xa_for_each' - 'xa_for_each_marked' - 'xa_for_each_range' - 'xa_for_each_start' - 'xas_for_each' - 'xas_for_each_conflict' - 'xas_for_each_marked' - 'xbc_array_for_each_value' - 'xbc_for_each_key_value' - 'xbc_node_for_each_array_value' - 'xbc_node_for_each_child' - 'xbc_node_for_each_key_value' - 'xbc_node_for_each_subkey' - 'ynl_attr_for_each' - 'ynl_attr_for_each_nested' - 'ynl_attr_for_each_payload' - 'zorro_for_each_dev' IncludeBlocks: Preserve IncludeCategories: - Regex: '.*' Priority: 1 IncludeIsMainRegex: '(Test)?$' IndentCaseLabels: false IndentGotoLabels: false IndentPPDirectives: None IndentWidth: 8 IndentWrappedFunctionNames: false JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: false MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: None ObjCBinPackProtocolList: Auto ObjCBlockIndentWidth: 8 ObjCSpaceAfterProperty: true ObjCSpaceBeforeProtocolList: true # Taken from git's rules PenaltyBreakAssignment: 10 PenaltyBreakBeforeFirstCallParameter: 30 PenaltyBreakComment: 10 PenaltyBreakFirstLessLess: 0 PenaltyBreakString: 10 PenaltyExcessCharacter: 100 PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Right ReflowComments: false SortIncludes: false SortUsingDeclarations: false SpaceAfterCStyleCast: false SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true SpaceBeforeCtorInitializerColon: true SpaceBeforeInheritanceColon: true SpaceBeforeParens: ControlStatementsExceptForEachMacros SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: false SpacesInContainerLiterals: false SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Cpp03 TabWidth: 8 UseTab: Always ... reform-tools-1.71/.gitlab-ci.yml000066400000000000000000000004001477621656200165400ustar00rootroot00000000000000image: debian:bookworm-slim build: script: | set -x apt-get update -o Acquire::AllowReleaseInfoChange=true -o quiet::ReleaseInfoChange=true apt-get --no-install-recommends --yes install make clang-format black shfmt shellcheck make lint reform-tools-1.71/CHANGELOG.md000066400000000000000000000727061477621656200157370ustar00rootroot000000000000001.71 (2025-04-11) ================= * `bin/reform-boot-config`: - use `lsblk` to check whether partition is a LUKS device - check whether block device exists before mounting - print what is still mounted on `/boot` - print the name of the platform instead of calling everything 'MNT Reform' - use old fstab entry to decide where the old `/boot` was mounted from instead of `findmnt` output - add `--no-copy-old-boot` switch for `reform-flash-rescue` * `bin/reform-check`: - check meta-packages instead of carrying a long list of dependencies - small cosmetic fixes * `bin/reform-flash-rescue`: - use `--keyring` and `--fingerprint` for `bmaptool` when copying from reform.debian.net - add `--mirror` argument * `bin/reform-emmc-bootstrap`: use `lsblk` to check whether partition is a LUKS device 1.70 (2025-04-05) ================= * `bin/reform-boot-config`: - set `EMMC` variable default to `false` - create a partition table on the device with future `/boot` if partition does not exist yet - if `/boot` is still mounted somewhere, output what the mountpoint is - do not suggest to reboot if the current system is running from SD-card and configured `/boot` on `eMMC` - explain what the script is not able to do and refer to `reform-emmc-bootstrap` - try to open a LUKS device if there are no partitions on the SSD - more annotations whether a device is the SD-card or eMMC - print extra warning for imx8mq - make `lsblk` failures non-fatal (ignore if the block device does not exist) * `bin/reform-check`: - do not print version of `linux-image-mnt-reform-arm64` if it is not installed - print an error if `linux-image-mnt-reform-arm64` and/or `linux-headers-mnt-reform-arm64` are not installed - print an error if `reform-qcacld2` is not installed with the mntre.com mirror or installed with the reform.debian.net mirror - explain what the effect of `reform2_lpc` not being loaded is - suggest fixing an outdated line in `~/.profile` which attempts to cat `/etc/reform-root-help` or `/etc/reform-help` * `bin/reform-emmc-bootstrap`: - error out if root partition does not have `/dev`, `/sys` or `/proc` - print out where the root filesystem was assumed to be located * `bin/reform-setup-encrypted-disk`: add device short-hands `sd`, `ssd`, `emmc` and `usb` * `bin/reform-setup-encrypted-nvme`: print migration to `reform-setup-encrypted-disk` in all cases * `lpc/reform2_lpc.c`: provide `POWER_SUPPLY_PROP_PRESENT` with a constant value of `1` * `bin/reform-help`: add `reform-migrate`, `reform-flash-uboot`, `reform-emmc-bootstrap` and `reform-flash-rescue` 1.69 (2025-03-10) ================= * Add SPDX license information * Add `README.md` * move all tools from `/usr/sbin` to `/usr/bin` * rename `reform-setup-encrypted-nvme` -> `reform-setup-encrypted-disk` * `bin/reform-setup-encrypted-disk`: - allow setting up eMMC or SD-card with LUKS - `-h` does not take arguments - move superuser check above check for installed commands - support `EMMC_USE=warn` * `bin/reform-migrate`: - device agnostic `--help` output - use getopts for command line parsing - support `EMMC_USE=warn` * `bin/reform-boot-config`: - device agnostic `--help` output - support `EMMC_USE=warn` * `bin/reform-flash-uboot`: - new `--image` option for custom flash.bin - device agnostic `--help` output - proper cli parsing with getopts - allow flashing to devices other than SD or eMMC * `bin/reform-emmc-bootstrap`: - print unknown option for any option other than --help - expect rootfs mountpoint to be `/dev/reformvg/root` instead of `/dev/mapper/reformvg-root` - do not attempt re-mounting root partition if it's already mounted as `/` - check if partition is in use before mounting it - `/dev/sda` partitions are `sda1` and `sda2` and not `sdap1` and `sdap2` - do not run `reform-flash-uboot` with `--force` - create a second partition on eMMC as expected by `reform-check` * `bin/reform-check`: - replace `ntp`,`ntpdate` with `ntpsec`,`ntpsec-ntpdate` - add `--offline` switch * `bin/reform-display-config`: - drop workaround for #1091979 in favour of patching u-boot-menu * `bin/reform-flash-rescue`: - support `EMMC_USE=warn` * `machines/MNT Reform 2.conf`: add cryptomgr.notests loglevel=3 * `machines/MNT * with BPI-CM4 Module.conf`: set EMMC_USE=warn * `Makefile`: - install man pages - install systemd service files 1.68 (2025-02-18) ================= * bin/reform-check: make output more verbose * lpc/reform2_lpc.c: support linux 6.13 * sbin/reform-setup-encrypted-nvme: fix manually passing path to /dev/nvme0n1 1.67 (2025-02-12) ================= * run `lsblk` with `--nodeps` where appropriate * `machines/MNT Pocket Reform with RCORE RK3588 Module.conf`: update `BOOTARGS` with `fbcon=font:TER16x32` * `sbin/reform-boot-config`: - delete the contents of the old `/boot` - add `--force` option to proceed without user interaction * `sbin/reform-setup-encrypted-nvme`: add `--force` option to run `reform-migrate` and put `/boot` on eMMC if allowed * `sbin/reform-display-config`: always write out `/etc/u-boot-menu/conf.d/reform.conf` * `bin/reform-check`: - be more verbose in error messages - make sure that `/etc/u-boot-menu/conf.d/reform.conf` exists with the right contents 1.66 (2025-02-03) ================= * Replace remaining uses of blkid by lsblk. Thanks to Chris Hofstaedtler * machines/* with i.MX8MP Module.conf: update to u-boot 2025-01-12 * Makefile: install files in /usr/sbin with 755 * sbin/reform-emmc-bootstrap: only run reform-flash-uboot if EMMC_BOOT != false * sbin/reform-emmc-bootstrap: - allow execution when actual root is on nvme - ensure emmc is not being used 1.65 (2025-01-11) ================= * machines/* with BPI-CM4 Module.conf: update u-boot to 2024-12-23 * add reform-emmc-bootstrap * sbin/reform-flash-uboot: - restore support for --offline switch - instead of finding the end of the first free space, find the beginning of the first partition - add --force * sbin/reform-boot-config: - reset MOUNTROOT after umounting, so that the right partition gets mounted afterward - make sure that OLDMOUNTBOOT actually is a mount point as a sanity check - run mountpoint with --quiet - do not update, but create the initramfs * sbin/reform-setup-encrypted-nvme: fix incorrectly placed double quote * install usr/lib/sddm/sddm.conf.d/10-wayland.conf to make sddm use wayland by default instead of Xorg * add x-initrd.attach to /etc/crypttab * move 99-reform.rules -> 99-reform-audio.rules * imx8mq: replace writing 'enabled' to /sys path in reform-hw-setup and reform-standby by udev rule * Makefile: - let help2man error out in case of problems - expect all tools to start with reform- prefix * reform-mcu-tool: allow USBErrorPipe on reset 1.64 (2024-12-06) ================= * add Makefile * add CHANGELOG.md * sbin/reform-flash-uboot: do not download anything if flash.bin is up-to-date * bin/reform-check: - synchronize with reform-system-image:mkimage.sh - warn about reform-qcacld2 on bookworm - improve modprobe.d/reform.conf wording * bin/reform-compstat: use read_time instead of read_bytes to determine disk activity percent * make everything shellcheck-clean * reform-flash-uboot: require using shorthands * add dracut/20-pocket-reform.conf * reform2_lpc: add backlight support for pocket reform display v2 * reform2_lpc: convert camelCase to conform to kernel coding style 1.63 (2024-11-20) ================= * kernel/zz-reform-tools: turn error messages into warnings, they are not fatal * machines/* with RCORE RK3588 Module.conf: set EMMC_BOOT=warn * sbin/reform-flash-uboot: add support for rk3588 eMMC which is not using the boot0 partition for u-boot * bin/reform-compstat: - add copyright header - add --percpu - use four six-per-em space U+2006 characters to create an empty box - let 98% CPU utilization already print the full bar * Add reform-mcu-tool 1.62 (2024-11-18) ================= * lpc/reform2_lpc.c: fixup ifdef 1.61 (2024-11-14) ================= * sbin/reform-hw-setup: print error if gpiod is too old * new script: reform-handbook * machines/* with RCORE RK3588 Module.conf: update u-boot to 2024-11-13b * machines/* with i.MX8MP Module.conf: update u-boot to 2024-11-14 * lpc/reform2_lpc.c: add abs_diff implementation for linux (<< 6.6) 1.60 (2024-11-06) ================= * machines: make EMMC_BOOT a tri-state option * move MNT icon font to reform-branding package * Add postinst script to set font on upgrade * Do not set hardcoded terminal font 1.59 (2024-10-30) ================= * debian/reform-tools.postinst: do not remove the world-readable bit from files in /etc/skel. The bash package also installs files into /etc/skel with mode 644 1.58 (2024-10-30) ================= * bin/reform-check: add more checks for wrong permissions in /etc * Revert "initramfs: Load font early on Pocket Reform" * Clean up old /etc/modprobe.d/reform.conf conffile 1.57 (2024-10-29) ================= * fix permission 666 -> 644 for reform apt sources.list files * machines/* with RCORE RK3588 Module.conf: set EMMC_USE=true because even when u-boot was borked, rk3588 will prefer u-boot from sd-card if present * bin/reform-check: check for wrong permissions of apt sources.list * sbin/reform-{boot-config,migrate}: check if $BOOTPART exists before starting to operate 1.56 (2024-10-24) ================= * reform-hw-setup: add eth reset workaround and audio setup for rk3588 1.55 (2024-10-11) ================= * reform2_lpc: Run through clang-format using the Linux config * reform2_lpc: Set battery technology to Unknown * reform2_lpc: Detect battery reading glitches * reformat shell scripts with shfmt * machines/*RK3588 Module.conf: update to 2024-10-11b 1.54 (2024-10-08) ================= * bump rk3588 u-boot to 2024-10-08 * add missing dependency of reform-wallpaper as Recommends * initramfs: Load font early on Pocket Reform * reform-hw-setup: fixup a311d ethernet re-probing 1.53 (2024-09-06) ================= * sbin/reform-flash-uboot: fix functionality that running without arguments just updates /boot/flash.bin * kernel/zz-reform-tools: - make sure /usr/lib/linux-image-* exists - print error if there was no dtb found - print warning for irregular dtb paths * install /usr/share/glib-2.0/schemas/20_reform.gschema.override setting the default theme and font * add libexec/reform-tools/reform-wallpaper.py 1.52 (2024-08-22) ================= * sbin/reform-hw-setup: do not run init_qca9377_wifi if qcacld2 is already loaded * sbin/reform-hw-setup: run insmod with -f or otherwise it will fail with 'Invalid module format' even if the version is correct 1.51 (2024-08-22) ================= * kernel/zz-reform-tools: fix variable name mode -> action * sbin/reform-hw-setup: make init_qca9377_wifi failing non-fatal 1.50 (2024-08-22) ================= * Add Recommends on bmap-tools * machines/MNT * with RCORE RK3588 Module.conf: bump u-boot version * add /usr/share/kernel/postinst.d/zz-reform-tools * sbin/reform-flash-uboot (Thanks to deianara) - fix typo MMC_BOOT -> EMMC_BOOT. - run parted with --script. * sbin/reform-display-config: support for u-boot-menu * sbin/reform-hw-setup: - run with set -e - prefix messages with type indicator - add support for pocket reform and reform next with rk3588 * sbin/reform-hw-setup: Change how the qcacld2 driver is loaded. Try to load exact match otherwise try every other available option 1.49 (2024-08-09) ================= * initramfs-tools/hooks/reform: add rk3588 for next and pocket * add machines/MNT Pocket Reform with RCORE RK3588 Module.conf * reform-check: stop warning about missing policykit-1 * reform-check: stop warning about missing /etc/modprobe.d/reform.conf 1.48 (2024-08-07) ================= * sbin/reform-flash-uboot: allow flashing to emmc on platforms with SD_BOOT set to false * disallow flashing u-boot to emmc on i.MX8MP to avoid accidentally soft-bricking it * The u-boot offset for i.MX8MP is zero bytes * remove reform-synaptic * add .gitlab-ci.yml 1.47 (2024-08-02) ================= * stop shipping files in /etc * move modprobe.d/reform.conf from /etc to /usr/lib * bin/reform-check: - fix deprecated kernel detection - respect xz-compressed dkms kernel modules * add machine/*.conf files for RCORE RK3588 1.46 (2024-08-01) ================= * add --help output and man pages for all tools * replace Iosevka Term font with JetBrains Mono Regular * Stop shipping the following files: - /etc/reform-help - /etc/reform-desktop-help - /etc/reform-root-help - /sbin/reform-init - /usr/bin/reform-desktop-help * machines/MNT Reform 2.conf: update to u-boot 2024-07-19 * machines/MNT * with BPI-CM4 Module.conf: u-boot 2024-08-01 (nvme support) * instead of explicitly running foot, run x-terminal-emulator which defaults to foot in the system images. Change the default terminal by running $ sudo update-alternatives --config x-terminal-emulator * bin/reform-check: - download uboot with dtbpath prefix - do not fail script if u-boot cannot be downloaded - allow --mirror=reform.debian.net - fix FLASHBIN_OFFSET computation - update package list * bin/reform-compstat: format with black * bin/reform-help: point out that reform-display-config is only for imx8mq * sbin/reform-flash-rescue - use bmaptool if available - resize root partition to fill remaining space on emmc * sbin/reform-boot-config: do not offer unmounting /boot twice * flash-kernel: put markers around preboot.d and ubootenv.d snippets * only inform about the dip-switch position on imx8mq * systemd/*.service: add Documentation field * add "sudo" to root commands in reform-help * Rename battery under /sys from 8xlifepo4 to BAT0 1.45 (2024-06-30) ================= * reform-hw-setup: a311d: rebind wifi sdio after booting to make sure it works * a311d: disable wifi powersaving to make wifi more reliable * sbin/reform-boot-config: add missing space * place default-wifi-powersave-off.conf into /usr/lib/NetworkManager/conf.d/ * machines/*.conf: update u-boot tags and hashes for reform with imx8mq, a311d and ls1028a * sbin/reform-flash-uboot: download flash.bin by dtb basename 1.44 (2024-06-10) ================= * imx8mp: add missing initramfs drivers; fixes display, pcie and usb in initramfs * sbin/reform-setup-encrypted-nvme: make /boot on eMMC the default for reform-boot-config * sbin/reform-boot-config: allow interactive umount * initramfs-tools/scripts/reform: run 'dmesg -n 7' in the initramfs on ls1028 as workaround for dwc3 unreliability * sbin/reform-setup-encrypted-nvme: if reform-boot-config fails, print steps how to re-run it 1.43 (2024-06-03) ================= * reform-check: adjustments for new kernel flavour mnt-reform-arm64 in 6.8 * machines: on imx8mp, mmc is mmcblk2 and sd is mmcblk0 * sbin/reform-hw-setup: adjust for different /sys path in linux 6.8 * sbin/reform-hw-setup: add loglevel=7 workaround for dwc3 module on ls1028a 1.42 (2024-05-07) ================= * reform-setup-cleanup.sh and reform-setup-sway-config are now shipped by reform-setup-wizard * imx8mp machines: add u-boot sha1 and tag * machines: add BOOTARGS * reform-check: check for abnormalities in kernel cmdline 1.41 (2024-05-06) ================= * etc/profile.d/reform.sh: remove harmful QT_QPA_PLATFORM=wayland and outdated ETNA_MESA_DEBUG=nir 1.40 (2024-04-17) ================= * wayfire: allow brightness ctrl also by super+f1/f2 1.39 (2024-04-16) ================= * sbin/reform-flash-uboot: fixup MMCDEV -> DEV_MMC * bin/reform-check: print additional information about the current system * machines/*: introduce SD_BOOT which is false on i.MX8MP * reform-hw-setup: add loader for qca9377 wifi on imx8mp platforms * firefox syspref.js: remove ads on new tab page * modprobe: block ath10k_sdio for imx8mp * reform-tray: include reform-help in reform-desktop-help * reform-hw-setup: add audio init for pocket reform 1.38 (2024-03-24) ================= * libexec/reform-tools/reform-tray.py: make GUI utilities optional * bin/reform-check: more reform2_lpc.ko and linux-headers package check * sway+wayfire: properly rotate and scale the pocket reform display * sway+wayfire: use hyper f1/f2 for brightness, use percentages, use 10% steps * refactor reform-hw-setup a bit and set big console font on pocket reform 1.37 (2024-03-20) ================= * install /usr/share/reform-setup-wizard/cleanup.d/reform-setup-cleanup.sh * install /usr/share/reform-setup-wizard/reform-setup-sway-config 1.36 (2024-03-19) ================= * reform-tray: update icon to view-more-symbolic (3 dots) * waybar: add mnt logo, add tooltip and instructions for launcher, fix battery icons * reform-tray: change icon, reorder menu to be more logical, open handbook on 'Help' * sbin/reform-hw-setup: do not run with set -e 1.35 (2024-03-19) ================= * Add support for four new setups: - MNT Pocket Reform with i.MX8MP Module - MNT Pocket Reform with BPI-CM4 Module - MNT Reform 2 with i.MX8MP Module - MNT Reform 2 with RCORE RK3588 Module * bin/reform-check: check if reform2_lpc is loaded * bin/reform-check: check whether dtb and symlinks to it are set up correctly * bin/reform-check: instruct to run 'apt update' first * sbin/reform-boot-config: do not fail if /boot is not mounted * sbin/reform-boot-config: make --help output dependent on the platform * sbin/reform-flash-uboot: forbid flashing u-boot to emmc on A311D and LS1028A * sbin/reform-migrate: give approximate numbers that have to be copied * initramfs-tools/hooks/reform: warn instead of error if platform unknown * initramfs-tools/scripts/reform: disable manual modprobing * flash-kernel/ubootenv.d/00reform2_ubootenv, u-boot-menu/reform.conf: set loglevel=3 * remove X11 settings for etnaviv -- this removes /etc/X11/xorg.conf as well as /usr/share/X11/xorg.conf.d/10-reform-etnaviv.conf 1.34 (2024-01-02) ================= * etc/skel/.config/sway/config: replace dmps on/off with brightnessctl --save and brightnessctl --restore * reform-hw-setup: add comment explaining a311d amixer settings * reform-boot-config: fix /boot message for a311d * reform-boot-config: allow unmount /boot after prompt if current system is rescue sd-card * reform-boot-config: remove the rescue system disk label if necessary * reform-flash-uboot: inform about the DIP switch on imx8mq * reform-check: support for reform.debian.net * reform-flash-rescue: support for flashing reform.d.n images to emmc * stop installing /usr/lib/systemd/system-shutdown/reform-poweroff now that the reform-lpc module does the right thing * use symlinks to install systemd services to let dh_installsystemd choose whether to install into /lib or into /usr/lib * etc/reform-help: instruct to run reform-config with sudo * lpc/reform2_lpc.c: send poweroff * skel: fix qt5 icon theme and dialogs for KDE * skel: prevent autostarting of waybar, blueman, pasystray, lxpolkit in non-wlroots DEs * skel: don't set QT_QPA_PLATFORMTHEME as it interferes with KDE * skel: set adwaita cursor theme for gtk apps in sway and wayfire 1.33 (2023-10-16) ================= * bin/reform-check: support skipping the first X bytes of flash.bin when comparing * add multiplatform support in sysimage-v4 * move remaining scripts from bash to posix shell * sbin/reform-setup-encrypted-nvme: compute swap space depending on total memory * update to latest u-boot 2023-10-10 on all platforms * set cma=512M on imx and cma=512M@3G on ls1028a 1.32 (2023-10-10) ================= * do not restart reform-sleep.service on upgrades * sbin/reform-standby: make 'Device or resource busy' and 'No such device' non-fatal * run wrap-and-sort -astb * update to u-boot 2023-10-10 * sbin/reform-flash-uboot: skip checks on disks without a partition table * install /usr/share/u-boot-menu/conf.d/reform.conf respecting ${bootargs} 1.31 (2023-10-04) ================= * bin/reform-check: - warn about /etc/flash-kernel/preboot.d/00reform2_preboot and /etc/flash-kernel/ubootenv.d/00reform2_ubootenv - allow /etc/flash-kernel/machine to not exist on platforms other than imx8mq - update default content of /etc/default/flash-kernel - update list of packages from sysimage-v4 - make checking for latest u-boot platform dependant - warn about missing non-free-firmware on a311d * flash-kernel/ubootenv.d/00reform2_ubootenv: - respect ${bootargs} again - put console=tty1 at the end of the cmdline to make sure that luks passphrase prompt shows up there and not on the serial line * stop installing /usr/share/u-boot-menu/conf.d/reform.conf as it does not allow for platform specific settings -- use /etc/default/u-boot instead 1.30 (2023-09-28) ================= * reform-hw-setup: a311d: reload ethernet modules to complete phy reset * Update 00reform2_ubootenv * reform-tray: add missing dependencies, change reboot/poweroff to systemctl * flash-kernel/uboot: add missing reform board variant 1.29 (2023-09-24) ================= * flash-kernel/ubootenv.d/00reform2_ubootenv: set bootargs for each platform 1.28 (2023-09-23) ================= * initramfs-tools/hooks/reform: also support 'MNT Reform 2 HDMI' * flash-kernel: first stab at setting cpu specific kernel command lines in ubootenv * initramfs-tools: add missing modules for ls1028a display * reform-hw-setup: add LS1028A usb workaround and default scaling_governor 1.27 (2023-09-21) ================= * copy /boot/ls1028a-mhdpfw.bin into initramfs * sbin/reform-flash-rescue: check all partitions of /dev/mmcblk0 * let reform-tools activate update-initramfs and flash-kernel triggers * sbin/reform-migrate: check whether partition for /boot is mounted before proceeding 1.26 (2023-09-11) ================= * sbin/reform-flash-rescue: change disk labels after dd 1.25 (2023-07-12) ================= * updates for sysimage-v4 - switch default sway terminal to foot and include a nice foot config - sway: modernize config, switch to wofi - update reform-help - update waybar config - add wallpaper - add default wayfire.ini - update reform-flash-rescue's image download URL - update reform-desktop-help content - skel: add configs for gtk3, qt5ct, dunst * let imx8mq specific tools exit early on the wrong platform * add a311d support to reform-hw-setup * install /usr/share/initramfs-tools/modules.d/reform.conf replacing /etc/initramfs-tools/modules * new script: reform-synaptic * add dependency on parted needed by reform-flash-uboot * add Protected: yes to make it really hard to remove * add --help option to reform-flash-uboot 1.24 (2023-07-11) ================= * sbin/reform-flash-uboot: adjust checksum for u-boot 2023-07-04 1.23 (2023-06-13) ================= * reform2-lpc-dkms: add missing header for linux 6.4 1.22 (2023-07-04) ================= * bump uboot version to 2023-07-04 1.21 (2023-05-30) ================= * reform-check: check for old /etc/flash-kernel/preboot.d/00reform2_preboot overwriting /usr/share/flash-kernel/preboot.d/00reform2_preboot 1.20 (2023-04-08) ================= * add reform-flash-uboot 1.19 (2023-02-18) ================= * reform2-lpc-dkms.dkms: AUTOINSTALL="yes" 1.18 (2023-01-27) ================= * install /usr/share/u-boot-menu/conf.d/reform.conf 1.17 (2023-01-27) ================= * bump uboot version to 2023-01-25 1.16 (2022-12-18) ================= * add reform-check utility * etc/profile.d/reform.sh: remove call to unicode_start as its functionality is provided automatically by console-setup * etc/motd-rescue: adjust message to not specifically talk about eMMC, SDcard or NVMe anymore * etc/motd: use reform-tools date in message * etc/profile.d/reform.sh: export MOZ_ENABLE_WAYLAND and _JAVA_AWT_WM_NONREPARENTING * sbin/reform-flash-rescue: check all mmcblk0 partitions in a loop before proceeding * sbin/reform-migrate: expand usage message * sbin/reform-setup-encrypted-nvme: mount to tmpdir instead of /mnt * sbin/reform-migrate: mount to tmpdir instead of /mnt 1.15 (2022-12-03) ================= * rework reform-boot-config - support all combinations of: * new root partition is already monted as / * new root partition lives elsewhere * new /boot partition is the same as the already configured one * new /boot is already mounted * new /boot device doesn't exist - error out if anything is still mounted that shouldn't be mounted - only mount when necessary - only use chroot if new root device is not / - use traps to always unmount everything and clean tmpfiles upon failure - consult /etc/fstab of new root for location of old /boot - copy over contents of old /boot to new one if necessary 1.14 (2022-11-06) ================= * Disable the raid456 kernel module to prevent losing wm8960audio 1.13 (2022-11-06) ================= * install flash-kernel boot scripts to /usr/share instead of /etc * flash-kernel/preboot.d/00reform2_preboot: even if ${fdtfile} is set, use dtb-${fk_kvers} if it exists 1.12 (2022-10-12) ================= * install /usr/share/initramfs-tools/scripts/init-top/reform as a temporary workaround to mxsfb producing a blank screen on roughly 50% of boots 1.11 (2022-09-13) ================= * reform-{boot-config,setup-encrypted-nvme}: add more cleanup code to exit traps and be verbose about script failure * reform-boot-config: allow messing up the currently running system by using an interactive prompt 1.10 (2022-09-12) ================= * add reform2-lpc-dkms package with the reform2_lpc module 1.9 (2022-09-07) ================ * install /usr/share/X11/xorg.conf.d/10-reform-etnaviv.conf 1.8 (2022-07-09) ================ * etc/skel/.config/mpv/mpv.conf: set maximum resolution of ytdl to 1080p * sway: fix KDE cursor appearing in sway * sbin/reform-{flash-rescue,boot-config,migrate,display-config, setup-encrypted-nvme}: check if devices are in use before proceeding * sbin/reform-boot-config: allow passing the device name explicitly * sbin/reform-migrate: add --emmc option * sbin/reform-{boot-config,display-config,migrate}: inform about the DIP switch if --emmc option is used * sbin/reform-setup-encrypted-nvme: replicate what reform-migrate does to avoid modifying the currently running system and ask whether /boot should be on emmc or sd-card * sbin/reform-{boot,display}-config: output meaningful error if /dev/mmcblk0p1 is missing * sbin/reform-{boot,display}-config: inform about the DIP switch always * sbin/reform-{display-config,migrate,setup-encrypted-nvme}: umount in a shell trap 1.7 (2022-06-17) ================ * sbin/reform-flash-rescue: download from main branch instead of old sysimage-v3 1.6 (2022-06-08) ================ * add etc/skel/.local/bin/kde for KDE Plasma desktop with wayland 1.5 (2022-04-22) ================ * sbin/reform-boot-config: add option to boot with rootfs on eMMC and document ROOTPART envvar * sbin/reform-flash-rescue: extend from one-liner to interactive flasher and downloader to eMMC 1.4 (2022-03-30) ================ * sbin/reform-migrate: reuse reform-boot-config to reduce code duplication * sbin/reform-setup-encrypted-nvme: use same crypttab options as debian-installer * sbin/reform-setup-encrypted-nvme: offer to run write resume, crypttab and fstab and run reform-migrate * sbin/reform-boot-config,reform-migrate: do not overwrite swap settings * sbin/reform-display-config: use findmnt instead of grepping mount output * sbin/reform-boot-config: allow operating on rootfs other than the currently running one * sbin/reform-migrate: use here-document to prevent globbing and word splitting of $TARGET * sbin/reform-migrate: prefixing with x is no longer necessary since bash 2.0 released in 1996 * sbin/reform-migrate: abort early if something is mounted on /mnt already * sbin/reform-migrate: add instructions how to partition NVMe 1.3 (2022-03-30) ================ * waybar/config: pass arguments to reform-compstat * remove reform-connman-gtk 1.2 (2022-02-20) ================ * rename etc/motd -> etc/motd-full to avoid conflict with existing /etc/motd * reform-hw-setup: some bits got lost when moving from reform-system-image to reform-tools * choose our pulse profile set when udev finds wm8960audio * enable systemd services after installation * fixup scripts to work with sysimage-v3 1.1 (2022-02-20) ================ * Initial release for sysimage-v3 reform-tools-1.71/LICENSE.txt000066400000000000000000001045151477621656200157430ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . reform-tools-1.71/Makefile000066400000000000000000000150471477621656200155610ustar00rootroot00000000000000#!/usr/bin/make -f # SPDX-License-Identifier: GPL-3.0+ # Copyright 2024-2025 Johannes Schauer Marin Rodrigues SHELL = /bin/sh INSTALL = /usr/bin/install INSTALLDATA = /usr/bin/install -m 644 prefix = /usr datadir = $(prefix)/share bindir = $(prefix)/bin libexecdir = $(prefix)/libexec libdir = $(prefix)/lib statedir = /var BINPROGS=$(wildcard bin/*) MAN1=$(patsubst bin/%,man/%.1,$(BINPROGS)) .PHONY: all all: $(MAN1) man/%.1: bin/% set -e; \ mkdir -p man; \ tool2whatis () { case $${1#reform-} in \ boot-config) echo "choose rootfs to boot from" ;; \ chat) echo "chat on #mnt-reform" ;; \ check) echo "check your setup" ;; \ compstat) echo "system statistics for waybar" ;; \ config) echo "select keyboard and timezone" ;; \ display-config) echo "select single/dual display" ;; \ emmc-bootstrap) echo "set up /boot on emmc for / on nvme" ;; \ flash-rescue) echo "flash rescue image to eMMC" ;; \ flash-uboot) echo "download and flash u-boot" ;; \ handbook) echo "show Reform Handbook" ;; \ help) echo "help with MNT Reform" ;; \ hw-setup) echo "perform hardware tweaks" ;; \ migrate) echo "copy rootfs to device" ;; \ mcu-tool) echo "manage microcontrollers" ;; \ pavucontrol) echo "kill and restart pavucontrol" ;; \ setup-encrypted-disk) echo "setup encrypted disk" ;; \ setup-encrypted-nvme) echo "use setup-encrypted-disk" ;; \ standby) echo "suspend/wakeup tweaks" ;; \ *) echo "unknown tool: $$1" 2>&1; exit 1 ;; \ esac; }; \ whatis="$$(tool2whatis "$*")"; \ version=$$(head -c4 CHANGELOG.md); \ case $$version in 1.[0-9][0-9]) : ;; *) echo invalid;exit 1;; esac; \ env "PATH=./bin:$$PATH" help2man \ --section=1 \ --name="$$whatis" \ --no-info --version-string="$$version" \ --no-discard-stderr "$*" \ --output="$@"; \ .PHONY: install install: $(MAN1) $(INSTALL) -d $(DESTDIR)$(libdir)/NetworkManager/conf.d $(INSTALLDATA) -t $(DESTDIR)$(libdir)/NetworkManager/conf.d NetworkManager/default-wifi-powersave-off.conf $(INSTALL) -d $(DESTDIR)$(libdir)/udev/rules.d $(INSTALLDATA) -t $(DESTDIR)$(libdir)/udev/rules.d audio/99-reform-audio.rules $(INSTALLDATA) -t $(DESTDIR)$(libdir)/udev/rules.d udev/reform-ttymxc-wakeup.rules $(INSTALL) -d $(DESTDIR)$(datadir)/pulseaudio/alsa-mixer/paths $(INSTALLDATA) -t $(DESTDIR)$(datadir)/pulseaudio/alsa-mixer/paths audio/analog-input-reform.conf $(INSTALL) -d $(DESTDIR)$(statedir)/lib/alsa $(INSTALLDATA) -t $(DESTDIR)$(statedir)/lib/alsa audio/asound.state $(INSTALL) -d $(DESTDIR)$(datadir)/pulseaudio/alsa-mixer/profile-sets $(INSTALLDATA) -t $(DESTDIR)$(datadir)/pulseaudio/alsa-mixer/profile-sets audio/reform.conf $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -t $(DESTDIR)$(bindir) $(BINPROGS) $(INSTALL) -d $(DESTDIR)$(datadir)/flash-kernel/preboot.d $(INSTALLDATA) -t $(DESTDIR)$(datadir)/flash-kernel/preboot.d flash-kernel/preboot.d/00reform2_preboot $(INSTALL) -d $(DESTDIR)$(datadir)/flash-kernel/ubootenv.d $(INSTALLDATA) -t $(DESTDIR)$(datadir)/flash-kernel/ubootenv.d flash-kernel/ubootenv.d/00reform2_ubootenv $(INSTALL) -d $(DESTDIR)$(datadir)/initramfs-tools/hooks $(INSTALL) -t $(DESTDIR)$(datadir)/initramfs-tools/hooks initramfs-tools/hooks/reform $(INSTALL) -d $(DESTDIR)$(datadir)/initramfs-tools/modules.d $(INSTALLDATA) -t $(DESTDIR)$(datadir)/initramfs-tools/modules.d initramfs-tools/reform.conf $(INSTALL) -d $(DESTDIR)$(datadir)/initramfs-tools/scripts/init-top $(INSTALL) -t $(DESTDIR)$(datadir)/initramfs-tools/scripts/init-top initramfs-tools/scripts/reform $(INSTALL) -d $(DESTDIR)$(datadir)/kernel/postinst.d $(INSTALL) -t $(DESTDIR)$(datadir)/kernel/postinst.d kernel/zz-reform-tools $(INSTALL) -d $(DESTDIR)$(libexecdir)/reform-tools $(INSTALL) -t $(DESTDIR)$(libexecdir)/reform-tools libexec/reform-tools/reform-tray.py $(INSTALL) -t $(DESTDIR)$(libexecdir)/reform-tools libexec/reform-tools/reform-wallpaper.py $(INSTALL) -d $(DESTDIR)$(datadir)/reform-tools/machines $(INSTALLDATA) -t $(DESTDIR)$(datadir)/reform-tools/machines machines/* $(INSTALL) -d $(DESTDIR)$(libdir)/modprobe.d $(INSTALLDATA) -t $(DESTDIR)$(libdir)/modprobe.d modprobe.d/reform.conf $(INSTALL) -d $(DESTDIR)$(datadir)/glib-2.0/schemas $(INSTALLDATA) -t $(DESTDIR)$(datadir)/glib-2.0/schemas schemas/20_reform.gschema.override $(INSTALL) -d $(DESTDIR)$(datadir)/backgrounds $(INSTALLDATA) -t $(DESTDIR)$(datadir)/backgrounds share/backgrounds/reform-mountains.jpg $(INSTALL) -d $(DESTDIR)$(libdir)/systemd/sleep.conf.d $(INSTALLDATA) -t $(DESTDIR)$(libdir)/systemd/sleep.conf.d systemd/reform-sleep.conf $(INSTALL) -d $(DESTDIR)$(libdir)/systemd/system $(INSTALLDATA) -t $(DESTDIR)$(libdir)/systemd/system systemd/reform-hw-setup.service systemd/reform-sleep.service $(INSTALL) -d $(DESTDIR)$(datadir)/u-boot-menu/conf.d $(INSTALLDATA) -t $(DESTDIR)$(datadir)/u-boot-menu/conf.d u-boot-menu/reform.conf $(INSTALL) -d $(DESTDIR)$(libdir)/dracut/dracut.conf.d $(INSTALLDATA) -t $(DESTDIR)$(libdir)/dracut/dracut.conf.d dracut/20-pocket-reform.conf $(INSTALL) -d $(DESTDIR)$(libdir)/sddm/sddm.conf.d $(INSTALLDATA) -t $(DESTDIR)$(libdir)/sddm/sddm.conf.d sddm/10-wayland.conf $(INSTALL) -d $(DESTDIR)$(datadir)/man/man1 $(INSTALLDATA) -t $(DESTDIR)$(datadir)/man/man1 $(MAN1) .PHONY: clean clean: rm -f man/*.1 .PHONY: lint lint: clang-format lpc/reform2_lpc.c | diff -u lpc/reform2_lpc.c - shfmt --posix --simplify --binary-next-line --case-indent --indent 2 --diff \ bin kernel/* initramfs-tools/*/* flash-kernel/*/* black --check --diff bin/reform-compstat libexec/reform-tools/reform-tray.py libexec/reform-tools/reform-wallpaper.py black --line-length 120 --check --diff bin/reform-mcu-tool shellcheck bin/* kernel/* initramfs-tools/*/* flash-kernel/*/* reform-tools-1.71/NetworkManager/000077500000000000000000000000001477621656200170365ustar00rootroot00000000000000reform-tools-1.71/NetworkManager/default-wifi-powersave-off.conf000066400000000000000000000000411477621656200250410ustar00rootroot00000000000000[connection] wifi.powersave = 2 reform-tools-1.71/README.md000066400000000000000000000027311477621656200153740ustar00rootroot00000000000000reform-tools ============ This package contains a collection of scripts and configuration files for GNU/Linux operating systems running on the MNT Reform, MNT Pocket Reform and MNT Reform Next with i.MX8MQ, i.MX8MPlus, Banana PI CM4, LS1028A or RK3588 processor modules. It contains system utilities to manage your installation as well as configuration files for initramfs, flash-kernel, pulseaudio, alsa, u-boot-menu, udev and NetworkManager. reform2-lpc-dkms ---------------- The reform2_lpc kernel module allows for interaction with the NXP LPC11U24 Cortex-M0 MCU system controller in the Reform 2 open hardware laptop. It controls an analog monitor chip for the eight battery cells as well as the charger. It is connected to the Processor Module via SPI, and has GPIO lines to the main power rail switchers in the system. It has a UART (SYSCTL) that the keyboard can talk to directly for issuing power on/off commands and battery status queries. The reform2_lpc module provides battery status information and is necessary to completely shut down the system when powering it off via userspace. License ------- Copyright 2020-2025 Lukas F. Hartmann Copyright 2022-2025 Johannes Schauer Marin Rodrigues Unless otherwise stated, reform-tools can be redistributed and/or modified under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. reform-tools-1.71/audio/000077500000000000000000000000001477621656200152135ustar00rootroot00000000000000reform-tools-1.71/audio/99-reform-audio.rules000066400000000000000000000001631477621656200211170ustar00rootroot00000000000000ACTION=="add", SUBSYSTEM=="sound", KERNEL=="card*", ATTRS{id}=="wm8960audio", ENV{PULSE_PROFILE_SET}="reform.conf" reform-tools-1.71/audio/analog-input-reform.conf000066400000000000000000000036401477621656200217530ustar00rootroot00000000000000# This file is part of PulseAudio. # # PulseAudio is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation; either version 2.1 of the # License, or (at your option) any later version. # # PulseAudio is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with PulseAudio; if not, see . ; Analog input path for MNT Reform, which has a headset mic input ; that is only on the left channel (mono). [General] priority = 100 [Element Capture] switch = mute volume = ignore [Element Mic] required-absent = any [Element Mic Boost] required-absent = any [Element Dock Mic] required-absent = any [Element Dock Mic Boost] required-absent = any [Element Front Mic] required-absent = any [Element Front Mic Boost] required-absent = any [Element Int Mic] required-absent = any [Element Int Mic Boost] required-absent = any [Element Internal Mic] required-absent = any [Element Internal Mic Boost] required-absent = any [Element Rear Mic] required-absent = any [Element Rear Mic Boost] required-absent = any [Element Headset] required-absent = any [Element Headset Mic] required-absent = any [Element Headset Mic Boost] required-absent = any [Element Headphone Mic] required-absent = any [Element Headphone Mic Boost] required-absent = any [Element Line] required-absent = any [Element Line Boost] required-absent = any [Element Aux] required-absent = any [Element Video] required-absent = any [Element Mic/Line] required-absent = any [Element TV Tuner] required-absent = any [Element FM] required-absent = any .include analog-input.conf.common reform-tools-1.71/audio/asound.state000066400000000000000000000245531477621656200175570ustar00rootroot00000000000000state.wm8960audio { control.1 { iface MIXER name 'Capture Volume' value.0 39 value.1 39 comment { access 'read write' type INTEGER count 2 range '0 - 63' dbmin -1725 dbmax 3000 dbvalue.0 1200 dbvalue.1 1200 } } control.2 { iface MIXER name 'Capture Volume ZC Switch' value.0 0 value.1 0 comment { access 'read write' type INTEGER count 2 range '0 - 1' } } control.3 { iface MIXER name 'Capture Switch' value.0 true value.1 true comment { access 'read write' type BOOLEAN count 2 } } control.4 { iface MIXER name 'Left Input Boost Mixer LINPUT3 Volume' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 7' dbmin -9999999 dbmax 600 dbvalue.0 -9999999 } } control.5 { iface MIXER name 'Left Input Boost Mixer LINPUT2 Volume' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 7' dbmin -9999999 dbmax 600 dbvalue.0 -9999999 } } control.6 { iface MIXER name 'Right Input Boost Mixer RINPUT3 Volume' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 7' dbmin -9999999 dbmax 600 dbvalue.0 -9999999 } } control.7 { iface MIXER name 'Right Input Boost Mixer RINPUT2 Volume' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 7' dbmin -9999999 dbmax 600 dbvalue.0 -9999999 } } control.8 { iface MIXER name 'Right Input Boost Mixer RINPUT1 Volume' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 3' dbmin 0 dbmax 2900 dbvalue.0 0 } } control.9 { iface MIXER name 'Left Input Boost Mixer LINPUT1 Volume' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 3' dbmin 0 dbmax 2900 dbvalue.0 0 } } control.10 { iface MIXER name 'Playback Volume' value.0 215 value.1 215 comment { access 'read write' type INTEGER count 2 range '0 - 255' dbmin -9999999 dbmax 0 dbvalue.0 -2000 dbvalue.1 -2000 } } control.11 { iface MIXER name 'Headphone Playback Volume' value.0 0 value.1 0 comment { access 'read write' type INTEGER count 2 range '0 - 127' dbmin -9999999 dbmax 600 dbvalue.0 -9999999 dbvalue.1 -9999999 } } control.12 { iface MIXER name 'Headphone Playback ZC Switch' value.0 false value.1 false comment { access 'read write' type BOOLEAN count 2 } } control.13 { iface MIXER name 'Speaker Playback Volume' value.0 101 value.1 101 comment { access 'read write' type INTEGER count 2 range '0 - 127' dbmin -9999999 dbmax 600 dbvalue.0 -2000 dbvalue.1 -2000 } } control.14 { iface MIXER name 'Speaker Playback ZC Switch' value.0 false value.1 false comment { access 'read write' type BOOLEAN count 2 } } control.15 { iface MIXER name 'Speaker DC Volume' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 5' } } control.16 { iface MIXER name 'Speaker AC Volume' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 5' } } control.17 { iface MIXER name 'PCM Playback -6dB Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.18 { iface MIXER name 'ADC Polarity' value 'No Inversion' comment { access 'read write' type ENUMERATED count 1 item.0 'No Inversion' item.1 'Left Inverted' item.2 'Right Inverted' item.3 'Stereo Inversion' } } control.19 { iface MIXER name 'ADC High Pass Filter Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.20 { iface MIXER name 'DAC Polarity' value 'No Inversion' comment { access 'read write' type ENUMERATED count 1 item.0 'No Inversion' item.1 'Left Inverted' item.2 'Right Inverted' item.3 'Stereo Inversion' } } control.21 { iface MIXER name 'DAC Deemphasis Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.22 { iface MIXER name 'DAC Slope' value true comment { access 'read write' type BOOLEAN count 1 } } control.23 { iface MIXER name '3D Filter Upper Cut-Off' value High comment { access 'read write' type ENUMERATED count 1 item.0 High item.1 Low } } control.24 { iface MIXER name '3D Filter Lower Cut-Off' value Low comment { access 'read write' type ENUMERATED count 1 item.0 Low item.1 High } } control.25 { iface MIXER name '3D Volume' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 15' } } control.26 { iface MIXER name '3D Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.27 { iface MIXER name 'ALC Function' value Off comment { access 'read write' type ENUMERATED count 1 item.0 Off item.1 Right item.2 Left item.3 Stereo } } control.28 { iface MIXER name 'ALC Max Gain' value 7 comment { access 'read write' type INTEGER count 1 range '0 - 7' } } control.29 { iface MIXER name 'ALC Target' value 4 comment { access 'read write' type INTEGER count 1 range '0 - 15' } } control.30 { iface MIXER name 'ALC Min Gain' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 7' } } control.31 { iface MIXER name 'ALC Hold Time' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 15' } } control.32 { iface MIXER name 'ALC Mode' value ALC comment { access 'read write' type ENUMERATED count 1 item.0 ALC item.1 Limiter } } control.33 { iface MIXER name 'ALC Decay' value 3 comment { access 'read write' type INTEGER count 1 range '0 - 15' } } control.34 { iface MIXER name 'ALC Attack' value 2 comment { access 'read write' type INTEGER count 1 range '0 - 15' } } control.35 { iface MIXER name 'Noise Gate Threshold' value 0 comment { access 'read write' type INTEGER count 1 range '0 - 31' } } control.36 { iface MIXER name 'Noise Gate Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.37 { iface MIXER name 'ADC PCM Capture Volume' value.0 195 value.1 195 comment { access 'read write' type INTEGER count 2 range '0 - 255' dbmin -9999999 dbmax 3000 dbvalue.0 0 dbvalue.1 0 } } control.38 { iface MIXER name 'Left Output Mixer Boost Bypass Volume' value 2 comment { access 'read write' type INTEGER count 1 range '0 - 7' dbmin -2100 dbmax 0 dbvalue.0 -1500 } } control.39 { iface MIXER name 'Left Output Mixer LINPUT3 Volume' value 2 comment { access 'read write' type INTEGER count 1 range '0 - 7' dbmin -2100 dbmax 0 dbvalue.0 -1500 } } control.40 { iface MIXER name 'Right Output Mixer Boost Bypass Volume' value 2 comment { access 'read write' type INTEGER count 1 range '0 - 7' dbmin -2100 dbmax 0 dbvalue.0 -1500 } } control.41 { iface MIXER name 'Right Output Mixer RINPUT3 Volume' value 2 comment { access 'read write' type INTEGER count 1 range '0 - 7' dbmin -2100 dbmax 0 dbvalue.0 -1500 } } control.42 { iface MIXER name 'ADC Data Output Select' value 'Left Data = Left ADC; Right Data = Right ADC' comment { access 'read write' type ENUMERATED count 1 item.0 'Left Data = Left ADC; Right Data = Right ADC' item.1 'Left Data = Left ADC; Right Data = Left ADC' item.2 'Left Data = Right ADC; Right Data = Right ADC' item.3 'Left Data = Right ADC; Right Data = Left ADC' } } control.43 { iface MIXER name 'DAC Mono Mix' value Stereo comment { access 'read write' type ENUMERATED count 1 item.0 Stereo item.1 Mono } } control.44 { iface MIXER name 'Left Boost Mixer LINPUT2 Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.45 { iface MIXER name 'Left Boost Mixer LINPUT3 Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.46 { iface MIXER name 'Left Boost Mixer LINPUT1 Switch' value true comment { access 'read write' type BOOLEAN count 1 } } control.47 { iface MIXER name 'Right Boost Mixer RINPUT2 Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.48 { iface MIXER name 'Right Boost Mixer RINPUT3 Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.49 { iface MIXER name 'Right Boost Mixer RINPUT1 Switch' value true comment { access 'read write' type BOOLEAN count 1 } } control.50 { iface MIXER name 'Left Input Mixer Boost Switch' value true comment { access 'read write' type BOOLEAN count 1 } } control.51 { iface MIXER name 'Right Input Mixer Boost Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.52 { iface MIXER name 'Left Output Mixer PCM Playback Switch' value true comment { access 'read write' type BOOLEAN count 1 } } control.53 { iface MIXER name 'Left Output Mixer LINPUT3 Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.54 { iface MIXER name 'Left Output Mixer Boost Bypass Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.55 { iface MIXER name 'Right Output Mixer PCM Playback Switch' value true comment { access 'read write' type BOOLEAN count 1 } } control.56 { iface MIXER name 'Right Output Mixer RINPUT3 Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.57 { iface MIXER name 'Right Output Mixer Boost Bypass Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.58 { iface MIXER name 'Mono Output Mixer Left Switch' value false comment { access 'read write' type BOOLEAN count 1 } } control.59 { iface MIXER name 'Mono Output Mixer Right Switch' value false comment { access 'read write' type BOOLEAN count 1 } } } reform-tools-1.71/audio/reform.conf000066400000000000000000000007661477621656200173650ustar00rootroot00000000000000[General] auto-profiles = yes [Mapping stereo-out] device-strings = hw:%f fallback = yes channel-map = left,right paths-output = analog-output analog-output-speaker analog-output-headphones direction = output priority = 1 [Mapping headset-mono-in] device-strings = hw:%f fallback = yes channel-map = mono paths-input = analog-input-reform direction = input priority = 1 [Profile output:stereo-out+input:mono-in] description = MNT Reform output-mappings = stereo-out input-mappings = headset-mono-in reform-tools-1.71/bin/000077500000000000000000000000001477621656200146625ustar00rootroot00000000000000reform-tools-1.71/bin/reform-boot-config000077500000000000000000000512731477621656200203160ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2020-2023 Lukas F. Hartmann # Copyright 2022-2025 Johannes Schauer Marin Rodrigues # # uboot on either emmc or the sd-card (as decided by the position of the DIP # switch) will load the kernel and initramfs from the first /boot partiton # where it finds a valid boot.scr (or extlinux.conf). It will attempt to find # a boot.scr on the first partition of the sd-card first and then will try # the first partition on emmc. # # This script sets up the first partition on the sd-card or emmc (as decided # by whether the --emmc option was passed or not) such that the initramfs on # that partition will load the correct rootfs. The rootfs can either reside on # the sd-card, emmc, ssd/nvme, sata or a usb mass storage device. # # The initramfs is tightly tied to the rootfs and the kernel version because it # is generated from the contents of the rootfs and contains the kernel modules # that must fit the correct kernel version. The choice of rootfs stored inside # the initramfs is derived from the settings of /etc/fstab in the rootfs. set -eu usage() { echo "Usage: " >&2 echo " reform-boot-config [--emmc] sd # rootfs on SD card (default)" >&2 echo " reform-boot-config [--emmc] ssd # rootfs on SSD or NVMe" >&2 echo " reform-boot-config [--emmc] usb # rootfs on USB storage device" >&2 echo " reform-boot-config [--emmc] emmc # rootfs on eMMC" >&2 echo " reform-boot-config [--emmc] /dev/... # custom rootfs device" >&2 echo "" >&2 echo "Adjust /etc/fstab of the given root file system and regenerate the" >&2 echo "initramfs in /boot on eMMC or SD-card (as indicated by the --emmc" >&2 echo "switch) to boot that rootfs." >&2 echo "" >&2 echo "Options:" >&2 echo " --emmc Record boot preference in /boot partition on eMMC instead of SD-card." >&2 echo " --no-copy-old-boot Do not copy contents from old /boot partition to new /boot." >&2 echo "" >&2 echo "Instead of using the short-hands sd, ssd, usb or emmc," >&2 echo "you can choose another root partition by passing" >&2 echo "the absolute device path starting with /dev/ explicitly." >&2 echo "For example, to boot a rootfs on an LVM volume with /boot" >&2 echo "on eMMC, run:" >&2 echo "" >&2 echo " reform-boot-config --emmc /dev/reformvg/root" >&2 echo "" >&2 echo "Note: The Debian kernel package installs files into /boot. Thus, the" >&2 echo "selected partition for /boot must already contain the kernel image" >&2 echo "belonging to the Debian kernel package installed in the selected" >&2 echo "rootfs. This script will not attempt to re-install the Debian kernel" >&2 echo "package to re-populate an empty or non-matching /boot partition." >&2 echo "" >&2 echo "To re-create a /boot partition on eMMC from scratch, use" >&2 echo "reform-emmc-bootstrap." >&2 echo "" >&2 echo "If 'ssd' was chosen as the root file system and there are no" >&2 echo "partitions on the SSD, this script will attempt to open the SSD" >&2 echo "as a LUKS device and assume a setup created by" >&2 echo "reform-setup-encrypted-disk." >&2 } maybe_umount() { what="$1" if [ "$FORCE" = true ]; then echo "Unmounting without user interaction because of --force" response="y" else printf "Should this script run 'umount %s' for you? [y/N] " "$what" read -r response fi if [ "$response" != "y" ]; then echo "I: Not unmounting as requested." >&2 return 1 else echo "I: Unmounting $what..." ret=0 umount "$what" || ret=$? if [ "$ret" -eq 0 ]; then echo "I: Unmounting $what successful." >&2 return 0 else echo "E: Tried to unmount $what but failed." >&2 return 1 fi fi } FORCE=false EMMC=false COPY_OLDBOOT=true while getopts :h-: OPTCHAR; do case "$OPTCHAR" in h) usage exit 0 ;; -) case "$OPTARG" in help) usage exit 0 ;; force) FORCE=true ;; emmc) EMMC=true ;; no-copy-old-boot) COPY_OLDBOOT=false ;; *) echo "E: unrecognized option: --$OPTARG" >&2 exit 1 ;; esac ;; :) echo "E: missing argument for -$OPTARG" >&2 exit 1 ;; '?') echo "E: unrecognized option -$OPTARG" >&2 exit 1 ;; *) echo "E: error parsing options" >&2 exit 1 ;; esac done shift "$((OPTIND - 1))" if [ "$#" -ne 1 ]; then echo "E: invalid number of arguments" >&2 usage exit 1 fi ARGV1="$1" if [ "$(id -u)" -ne 0 ]; then echo "reform-boot-config has to be run as root / using sudo." >&2 exit 1 fi # shellcheck source=/dev/null if [ -e "./machines/$(cat /proc/device-tree/model).conf" ]; then . "./machines/$(cat /proc/device-tree/model).conf" elif [ -e "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" ]; then . "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" else echo "E: unable to find config for $(cat /proc/device-tree/model)" >&2 exit 1 fi if [ "$EMMC" = true ]; then case $EMMC_USE in false) echo "E: writing to eMMC not supported on $(cat /proc/device-tree/model)" >&2 exit 1 ;; warn) echo "W: Using eMMC on $(cat /proc/device-tree/model) is not without risk." >&2 echo "W: For example, flashing the wrong u-boot or if the flashing process goes wrong, it is" >&2 echo "W: possible to soft-brick your board. Restoring it might need some extra hardware." >&2 echo "W: Please only proceed if you are sure that the benefits outweigh the risks for you." >&2 if [ "$FORCE" = true ]; then echo "Proceeding without user interaction because of --force" >&2 response="y" else printf "Are you sure you want to proceed? [y/N] " read -r response fi if [ "$response" != "y" ]; then echo "Exiting." exit fi ;; esac BOOTPART="$DEV_MMC" HUMAN_BOOT="eMMC" else BOOTPART="$DEV_SD" HUMAN_BOOT="SD-card" fi # Try opening with an exclusive write lock to check whether a device is still # opened by consumers like device-mapper, raid or luks, to name some examples. # reform-emmc-bootstrap does the same thing (could share code?) get_exclusive_write_lock() { ret=0 python3 - "$1" <&2 echo "W: This script can create a new partition table on $HUMAN_BOOT for you." >&2 echo "WARNING: doing so will destroy the contents of your $HUMAN_BOOT." >&2 if [ "$FORCE" = true ]; then echo "I: Proceeding without user interaction because of --force" >&2 response="y" else printf "Are you sure you want to proceed? [y/N] " read -r response fi if [ "$response" != "y" ]; then echo "Exiting." exit fi if ! get_exclusive_write_lock "/dev/${BOOTPART}"; then echo "E: device /dev/${BOOTPART} ($HUMAN_BOOT) is still in use" >&2 exit 1 fi # reform-emmc-bootstrap does the same thing (could share code?) parted --script --machine "/dev/$BOOTPART" "mklabel msdos" # create two partitions as expected by reform-check (but we only format /boot) # make /boot as big as mkimage.sh would parted --script --machine "/dev/$BOOTPART" "mkpart primary ext4 16MiB $((16 + 488))MiB" parted --script --machine "/dev/$BOOTPART" "mkpart primary ext4 $((16 + 488))MiB 100%" udevadm settle partprobe "/dev/$BOOTPART" mkfs.ext4 -F "/dev/${BOOTPART}p1" fi BOOTPART="${BOOTPART}p1" if [ ! -b "/dev/$BOOTPART" ]; then echo "/dev/$BOOTPART is not a block device" >&2 exit 1 fi case $ARGV1 in sd) ROOTPART="${DEV_SD}p2" ;; nvme | ssd) if [ "$DEV_SSD" = "sda" ]; then ROOTPART="${DEV_SSD}1" else ROOTPART="${DEV_SSD}p1" fi if [ ! -e "/dev/$ROOTPART" ]; then echo "W: First partition on SSD (/dev/$ROOTPART) does not exist." >&2 if [ "$(lsblk --nodeps --noheadings --output=FSTYPE "/dev/${DEV_SSD}")" = "crypto_LUKS" ]; then echo "I: Assuming full disk encryption with LUKS on /dev/reformvg/root" >&2 ROOTPART="reformvg/root" else echo "E: Your SSD at /dev/${DEV_SSD} does not seem to be a LUKS device" >&2 exit 1 fi fi ;; usb) ROOTPART="${DEV_USB}1" ;; emmc) ROOTPART="${DEV_MMC}p2" ;; /dev/*) if [ ! -b "$1" ]; then echo "there is no block device called $1" >&2 exit 1 fi ROOTPART="$1" ;; *) usage exit 1 ;; esac echo "This script selects your preferred boot medium. It writes your choice to the file /etc/fstab" echo ROOTPART="${ROOTPART#/dev/}" # POSIX shell only has a single array: $@ # Instead of storing the list of directories that need to be unmounted or # removed in a string separated by whitespaces (and thus not supporting # whitespace characters in path names) we use $@ to store that list. # We push each new entry to the beginning of the list so that we can use # shift to pop the first entry. cleanup() { : "${TMPDIR:=/tmp}" for dir; do # $dir is either a device that has to be unmounted or an empty # temporary directory that used to be a mountpoint echo "cleaning up $dir" >&2 ret=0 if [ -d "$dir" ]; then # special handling for /dev, /sys and /proc case "$dir" in */dev | */sys | */proc) umount "$dir" || ret=$? ;; *) rmdir "$dir" || ret=$? ;; esac else umount "$dir" || ret=$? fi if [ "$ret" != 0 ]; then echo "cleaning up $dir failed" >&2 fi # remove this item from $@ shift done if [ "${MOUNTROOT-}" = "/" ]; then ret=0 mount /boot || ret=$? if [ "$ret" != 0 ]; then echo "mounting /boot failed" >&2 fi fi if [ "${MOUNTROOT-}" != "/" ] && [ "$ROOTPART" = "reformvg/root" ] && [ "$ARGV1" != "/dev/reformvg/root" ]; then if [ -e /dev/reformvg ]; then vgchange -an reformvg fi if [ -e /dev/mapper/reform_crypt ]; then cryptsetup luksClose reform_crypt fi fi echo reform-boot-config FAILED to run >&2 } set -- trap 'cleanup "$@"' EXIT INT TERM # check if rootfs is already mounted somewhere that is not / if [ -b "/dev/$ROOTPART" ]; then MOUNTROOT="$(lsblk --noheadings --output=MOUNTPOINT "/dev/$ROOTPART" || :)" if [ "$MOUNTROOT" != "" ] && [ "$MOUNTROOT" != "/" ]; then echo "/dev/$ROOTPART is still mounted on $MOUNTROOT." >&2 if ! maybe_umount "/dev/$ROOTPART"; then echo "Please unmount before running this script" >&2 exit 1 fi MOUNTROOT= fi else # if /dev/$ROOTPART is not a block device, then it can also not be mounted anywhere MOUNTROOT= fi # If reformvg/root was chosen as the rootfs (either explicitly or implicitly # because there are no partitions on the SSD), attempt opening the SSD as a # LUKS device, except if either # - it is already mounted as the current rootfs or # - the user explicitly selected /dev/reformvg/root as the rootfs in which # case we assume it is already unlocked by the user if [ "$MOUNTROOT" != "/" ] && [ "$ROOTPART" = "reformvg/root" ] && [ "$ARGV1" != "/dev/reformvg/root" ]; then if [ "$(lsblk --nodeps --noheadings --output=FSTYPE "/dev/${DEV_SSD}")" != "crypto_LUKS" ]; then echo "W: SSD (/dev/${DEV_SSD}) does not look like a LUKS device" >&2 fi cryptsetup luksOpen "/dev/${DEV_SSD}" reform_crypt vgchange -ay reformvg fi # mount the desired root partition somewhere if it isn't mounted yet if [ "$MOUNTROOT" = "" ]; then if [ ! -e "/dev/$ROOTPART" ]; then echo "E: root partition (/dev/$ROOTPART) does not exist" >&2 exit 1 fi MOUNTROOT="$(mktemp --tmpdir --directory reform-boot-config.XXXXXXXXXX)" set -- "/dev/$ROOTPART" "$MOUNTROOT" "$@" mount "/dev/$ROOTPART" "$MOUNTROOT" fi if [ ! -d "$MOUNTROOT/boot" ]; then echo "the rootfs does not contain a /boot directory" >&2 exit 1 fi # check if the new boot is still mounted somewhere MOUNT_BOOT="$(lsblk --noheadings --output=MOUNTPOINT "/dev/$BOOTPART" || :)" if [ -n "$MOUNT_BOOT" ]; then echo "W: /dev/$BOOTPART ($HUMAN_BOOT) is still mounted on $MOUNT_BOOT, which means that it is" >&2 echo "probably used by the currently running system and that replacing" >&2 echo "its contents might make the currently running system unbootable." if [ "$(lsblk --noheadings --output=MOUNTPOINT "/dev/$BOOTPART")" != "/boot" ]; then echo "W: /dev/$BOOTPART ($HUMAN_BOOT) was expected to be mounted at /boot, but was found be" >&2 echo "W: mounted at $(lsblk --noheadings --output=MOUNTPOINT "/dev/$BOOTPART")" >&2 fi if ! maybe_umount "/dev/$BOOTPART"; then echo "Please unmount before running this script" >&2 exit 1 fi fi # check that the new mountpoint for /boot is empty if mountpoint --quiet "$MOUNTROOT/boot"; then echo "Something ($(findmnt --noheadings --evaluate --mountpoint "$MOUNTROOT/boot" --output SOURCE)) is still mounted on $MOUNTROOT/boot." >&2 if ! maybe_umount "$MOUNTROOT/boot"; then echo "Please unmount before running this script" >&2 exit 1 fi fi # mount the new boot partition set -- "/dev/$BOOTPART" "$@" mount "/dev/$BOOTPART" "$MOUNTROOT/boot" if [ "$COPY_OLDBOOT" = true ]; then # find the device that was mounted as /boot according to the /etc/fstab in the # given rootfs OLDBOOTPART="$(LIBMOUNT_FSTAB="$MOUNTROOT/etc/fstab" findmnt --fstab --noheadings --evaluate --mountpoint /boot --output SOURCE || :)" if [ -z "$OLDBOOTPART" ]; then echo "cannot find /boot device referenced by /etc/fstab in rootfs at /dev/$ROOTPART" >&2 exit 1 fi if [ ! -e "$OLDBOOTPART" ]; then echo "/boot device $OLDBOOTPART from /etc/fstab in /dev/$ROOTPART doesn't exist" >&2 exit 1 fi case $OLDBOOTPART in "/dev/${DEV_SD}"*) HUMAN_OLDBOOT="SD-card" ;; "/dev/${DEV_MMC}"*) HUMAN_OLDBOOT="eMMC" ;; *) HUMAN_OLDBOOT="unknown" ;; esac if [ "$OLDBOOTPART" = "/dev/$BOOTPART" ]; then echo "the /boot partition /dev/$BOOTPART ($HUMAN_BOOT) referenced by the rootfs at /dev/$ROOTPART remains the same" >&2 else echo "This script will copy the contents from the old /boot partition" >&2 echo "$OLDBOOTPART ($HUMAN_OLDBOOT) to the new /boot partition $BOOTPART ($HUMAN_BOOT) and delete all" >&2 echo "files from the latter that were not present in the former." >&2 if [ "$FORCE" = true ]; then echo "Proceeding without user interaction because of --force" >&2 response="y" else echo "Are you sure that you want to remove the contents of $BOOTPART ($HUMAN_BOOT)" >&2 printf "and replace it with the contents of %s? [y/N] " "$OLDBOOTPART ($HUMAN_OLDBOOT)" >&2 read -r response fi if [ "$response" != "y" ]; then echo "I: Not overwriting the contents of $BOOTPART ($HUMAN_BOOT) as requested." >&2 exit 1 fi # copy the contents of the old /boot to the new /boot OLDMOUNTBOOT="$(lsblk --nodeps --noheadings --output=MOUNTPOINT "$OLDBOOTPART")" needumount="no" if [ "$OLDMOUNTBOOT" = "" ]; then OLDMOUNTBOOT="$(mktemp --tmpdir --directory reform-boot-config.XXXXXXXXXX)" set -- "$OLDBOOTPART" "$OLDMOUNTBOOT" "$@" mount "$OLDBOOTPART" "$OLDMOUNTBOOT" needumount="yes" fi # sanity check if ! mountpoint --quiet "$OLDMOUNTBOOT"; then echo "E: expected $OLDBOOTPART ($HUMAN_OLDBOOT) mounted on $OLDMOUNTBOOT but nothing mounted there" >&2 exit 1 fi rsync --archive --one-file-system --hard-links --acls --xattrs --whole-file \ --sparse --numeric-ids --delete-delay "$OLDMOUNTBOOT/" "$MOUNTROOT/boot" if [ "$needumount" = "yes" ]; then [ "$1" = "$OLDBOOTPART" ] && shift && umount "$OLDBOOTPART" [ "$1" = "$OLDMOUNTBOOT" ] && shift && rmdir "$OLDMOUNTBOOT" fi fi fi if LIBMOUNT_FSTAB="$MOUNTROOT/etc/fstab" findmnt --fstab --noheadings --source "/dev/$ROOTPART" --mountpoint "/" >/dev/null \ && LIBMOUNT_FSTAB="$MOUNTROOT/etc/fstab" findmnt --fstab --noheadings --source "/dev/$BOOTPART" --mountpoint "/boot" >/dev/null; then echo "/etc/fstab already contains the correct entries" >&2 else echo "commenting original /etc/fstab contents" >&2 SWAP= if LIBMOUNT_FSTAB="$MOUNTROOT/etc/fstab" findmnt --fstab --types swap >/dev/null; then SWAP="$(LIBMOUNT_FSTAB="$MOUNTROOT/etc/fstab" findmnt --noheadings --fstab --types swap --output SOURCE,TARGET,FSTYPE,OPTIONS,FREQ,PASSNO)" fi sed -i -e 's/^/#/' "$MOUNTROOT/etc/fstab" cat <>"$MOUNTROOT/etc/fstab" /dev/$ROOTPART / auto errors=remount-ro 0 1 /dev/$BOOTPART /boot auto errors=remount-ro 0 1 END if [ -n "$SWAP" ]; then echo "$SWAP" >>"$MOUNTROOT/etc/fstab" fi fi if [ "$MOUNTROOT" = "/" ]; then update-initramfs -u else set -- "$MOUNTROOT/proc" "$MOUNTROOT/sys" "$MOUNTROOT/dev" "$@" mount -o bind /dev "$MOUNTROOT/dev" mount -t sysfs sys "$MOUNTROOT/sys" mount -t proc proc "$MOUNTROOT/proc" # We do not run update-initramfs with -u as that will attempt to update an # existing initramfs and /boot may already contain an initramfs for a kernel # version that we do not have. # FIXME: this will fail if /boot contains a kernel that is newer than the # latest kernel the system has installed, see #1092765 chroot "$MOUNTROOT" update-initramfs -c -k all [ "$1" = "$MOUNTROOT/proc" ] && shift && umount "$MOUNTROOT/proc" [ "$1" = "$MOUNTROOT/sys" ] && shift && umount "$MOUNTROOT/sys" [ "$1" = "$MOUNTROOT/dev" ] && shift && umount "$MOUNTROOT/dev" fi # unmount /boot partition [ "$1" = "/dev/$BOOTPART" ] && shift && umount "/dev/$BOOTPART" # unmount the root partition if necessary if [ "$MOUNTROOT" != "/" ]; then [ "$1" = "/dev/$ROOTPART" ] && shift && umount "/dev/$ROOTPART" [ "$1" = "$MOUNTROOT" ] && shift && rmdir "$MOUNTROOT" fi # make sure that the cleanup array is empty now [ $# -eq 0 ] trap - EXIT INT TERM if [ "$MOUNTROOT" != "/" ] && [ "$ROOTPART" = "reformvg/root" ] && [ "$ARGV1" != "/dev/reformvg/root" ]; then vgchange -an reformvg cryptsetup luksClose reform_crypt fi # make sure that the new boot partition does not still have the reformsdboot # or reformemmcboot labels in case it used to be the /boot partition from a # rescue system on sd-card or emmc, respectively case "$BOOTPART" in "${DEV_SD}p1") if [ "$(lsblk --nodeps --noheadings --output=LABEL "/dev/$BOOTPART")" = "reformsdboot" ]; then e2label "/dev/$BOOTPART" "" fi ;; "${DEV_MMC}p1") if [ "$(lsblk --nodeps --noheadings --output=LABEL "/dev/$BOOTPART")" = "reformemmcboot" ]; then e2label "/dev/$BOOTPART" "" fi ;; esac # since /boot had to be unmounted before running this script, make sure to # mount it again if [ "$MOUNTROOT" = "/" ]; then mount /boot fi # Maybe the human platform name should be part of the machine/*.conf if it is # used more than just here. case "$(cat /proc/device-tree/model)" in "MNT Pocket Reform with "*) PLATFORM_HUMAN="MNT Pocket Reform" ;; "MNT Reform Next with "*) PLATFORM_HUMAN="MNT Reform Next" ;; "MNT Reform 2" | "MNT Reform 2 HDMI") PLATFORM_HUMAN="Reform 2" ;; "MNT "*) PLATFORM_HUMAN="MNT Reform (unknown)" ;; esac if [ "$EMMC" = true ] && [ -n "${OLDBOOTPART-}" ]; then echo "Your /boot partition is on emmc (/dev/$BOOTPART)." >&2 # If the current system runs on SD-card and the user set up /boot on eMMC # then they need to remove the SD-card before booting again or otherwise # u-boot will prefer /boot from this system. case $OLDBOOTPART in "/dev/${DEV_SD}"*) echo "I: u-boot will prefer the first partition on SD-card over the first partition on eMMC" >&2 echo "I: Your current system has its /boot mounted from SD-card." >&2 echo "I: You requested to configure a new /boot on eMMC" >&2 echo "I: Instead of just rebooting, power off the system." >&2 echo "I: Then remove the SD-card." >&2 echo "I: Lastly, power the system on again." >&2 echo "I: Power off your ${PLATFORM_HUMAN} by running 'systemctl poweroff'." >&2 case "$(cat /proc/device-tree/model)" in "MNT Reform 2" | "MNT Reform 2 HDMI") echo "I: WARNING: If you have the DIP switch on your i.MX8MQ set to load u-boot" >&2 echo "I: from SD-card instead of eMMC, you cannot boot the system without" >&2 echo "I: an SD-card inserted. In that case, either:" >&2 echo "I: a) mv /boot/boot.scr /boot/boot.scr.bak" >&2 echo "I: b) or put in a different SD-card with u-boot but without /boot/boot.scr" >&2 ;; esac ;; *) echo "I: Reboot your ${PLATFORM_HUMAN} by running 'systemctl reboot'." >&2 ;; esac else echo "Your /boot partition is on your SD-Card (/dev/$BOOTPART)." >&2 echo "I: Reboot your ${PLATFORM_HUMAN} by running 'systemctl reboot'." >&2 fi reform-tools-1.71/bin/reform-chat000077500000000000000000000012411477621656200170150ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2020-2022 Lukas F. Hartmann # Copyright 2022-2025 Johannes Schauer Marin Rodrigues set -eu usage() { echo "Join the #mnt-reform chat room on irc.libera.chat" >&2 echo "under a random pseudonym" >&2 echo >&2 echo "Usage: $0 [--help]" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 } if [ "$#" -gt 0 ]; then if [ "$1" != "--help" ]; then echo "E: too many arguments" >&2 usage exit 1 fi usage exit 0 fi exec irc -c '#mnt-reform' -p 6697 "reform$(shuf -i 0-32767 -n 1)" SSLIRC/irc.libera.chat reform-tools-1.71/bin/reform-check000077500000000000000000000765341477621656200171740ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2022-2025 Johannes Schauer Marin Rodrigues # # This script checks the integrity of your MNT reform setup. It is meant for # two main use-cases: # # 1. somebody has a problem with their reform and to debug the problem it # would be useful to know how their system differs from the default # 2. somebody installed their system several months ago and now wants to find # out which things have since been added or changed in the defaults that # they might want to apply to their running setup as well # # Running this script as non-root will give you a diff between the files in # /etc/skel and those in your $HOME. Running this script as root performs the # system-wide checks. # # shellcheck disable=SC2059 set -eu usage() { echo "This script checks the integrity of your MNT reform setup. It is meant for" >&2 echo "two main use-cases:" >&2 echo >&2 echo " 1. somebody has a problem with their reform and to debug the problem it" >&2 echo " would be useful to know how their system differs from the default" >&2 echo " 2. somebody installed their system several months ago and now wants to find" >&2 echo " out which things have since been added or changed in the defaults that" >&2 echo " they might want to apply to their running setup as well" >&2 echo >&2 echo "Running this script as non-root will give you a diff between the files in" >&2 # shellcheck disable=SC2016 echo '/etc/skel and those in your $HOME. Running this script as root performs the' >&2 echo "system-wide checks." >&2 echo >&2 echo "Usage: $0 [--help] [--mirror={mntre.com,reform.debian.net}] [--offline]" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 echo " --mirror=MIRROR Force MIRROR, either mntre.com or reform.debian.net" >&2 echo " --offline Disable all checks that require an internet connection" >&2 echo " and a filled apt cache." >&2 } nth_arg() { shift "$1" printf "%s" "$1" } OFFLINE= MIRROR="mntre.com" while getopts :h-: OPTCHAR; do case "$OPTCHAR" in h) usage exit 0 ;; -) case "$OPTARG" in help) usage exit 0 ;; offline) OFFLINE=yes ;; mirror) if [ "$OPTIND" -gt "$#" ]; then echo "E: missing argument for --mirror" >&2 exit 1 fi MIRROR="$(nth_arg "$OPTIND" "$@")" OPTIND=$((OPTIND + 1)) ;; mirror=*) MIRROR="${OPTARG#*=}" ;; *) echo "E: unrecognized option: --$OPTARG" >&2 exit 1 ;; esac ;; :) echo "E: missing argument for -$OPTARG" >&2 exit 1 ;; '?') echo "E: unrecognized option -$OPTARG" >&2 exit 1 ;; *) echo "E: error parsing options" >&2 exit 1 ;; esac done shift "$((OPTIND - 1))" if [ "$#" -gt 0 ]; then usage exit 1 fi if [ "$MIRROR" != "mntre.com" ] && [ "$MIRROR" != "reform.debian.net" ]; then echo "E: invalid value for --mirror: $MIRROR -- only mntre.com and reform.debian.net are supported" >&2 exit 1 fi if [ "$(id -u)" -ne 0 ]; then # check several versions of ~/.profile that older versions of reform-system-image placed into /etc/skel # shellcheck disable=SC2016 if grep --silent -F 'if [ $(whoami) == "root" ]; then cat /etc/reform-root-help; elif [ -z $WAYLAND_DISPLAY ]; then cat /etc/reform-help; fi' ~/.profile \ || grep --silent -F 'if [ $(whoami) = "root" ]; then cat /etc/reform-root-help; elif [ -z $WAYLAND_DISPLAY ]; then cat /etc/reform-help; fi' ~/.profile \ || grep --silent -F 'if [ "$(whoami)" = "root" ]; then cat /etc/reform-root-help; elif [ -z "$WAYLAND_DISPLAY" ]; then cat /etc/reform-help; fi' ~/.profile; then echo "E: Your ~/.profile contains an outdated line that attempts to print /etc/reform-root-help or /etc/reform-help." >&2 echo "E: Consider replacing it with this version:" >&2 echo 'if [ "$(whoami)" = "root" ]; then reform-help --root; elif [ -z "$WAYLAND_DISPLAY" ]; then reform-help; fi' >&2 fi for path in $(cd /etc/skel && find . -type f); do if [ ! -e "$HOME/$path" ]; then echo "W: $path doesn't exist in current \$HOME" >&2 elif ! cmp --quiet "/etc/skel/$path" "$HOME/$path"; then echo "W: local version of $path has modifications:" >&2 diff -u "/etc/skel/$path" "$HOME/$path" || true fi done echo "I: Running reform-check as the normal user only diffs your current" # shellcheck disable=SC2016 echo 'I: configuration in your $HOME against the contents in /etc/skel.' echo "I: To run a system-wide check, run this script as the root user." exit 0 fi if [ -z "$MIRROR" ] && grep --silent '^URIs: https://reform.debian.net/debian/\?$' /etc/apt/sources.list.d/reform*.sources 2>/dev/null; then echo "I: reform.debian.net is configured as a mirror in /etc/apt/sources.list.d" >&2 echo "I: Assuming reform.debian.net stable mirror for this script" >&2 echo "I: If this is incorrect, you can set the mirror to its default by re-running this script with --mirror=mntre.com" MIRROR="reform.debian.net" fi if [ -z "$MIRROR" ]; then MIRROR="mntre.com" fi if [ -z "$(apt-get indextargets)" ] && [ "$OFFLINE" != "yes" ]; then echo "E: reform-check needs a populated apt cache for some of its operation." >&2 echo "E: re-run with --offline (disabling some checks) or choose to run 'apt update' now." >&2 printf "Should reform-check run 'apt update' for you? [y/N]" >&2 read -r response if [ "$response" != "y" ]; then echo "Exiting." exit 1 fi apt-get update --error-on=any fi # shellcheck source=/dev/null if [ -e "./machines/$(cat /proc/device-tree/model).conf" ]; then . "./machines/$(cat /proc/device-tree/model).conf" elif [ -e "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" ]; then . "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" else echo "E: unable to find config for $(cat /proc/device-tree/model)" >&2 exit 1 fi echo "I: Contents of /proc/device-tree/model: $(cat /proc/device-tree/model)" >&2 echo "I: \`uname -a\` output: $(uname -a)" >&2 if dpkg-query --showformat '${db:Status-Status}\n' --show "linux-image-mnt-reform-arm64" 2>/dev/null | grep -q '^installed$'; then echo "I: Version of linux-image-mnt-reform-arm64: $(dpkg-query --show --showformat '${Version}' linux-image-mnt-reform-arm64)" >&2 else # The error message below is not quite correct. dpkg *will* tell us a version # even when a package was removed (but not purged). But showing a version # for a removed package is misleading the reader of the reform-check output # into believing that the package is actually installed (or why else would # it show the version of the package?). Thus, when the package is not # installed, we forcefully do not show the version even though we could. echo "E: Cannot get version of linux-image-mnt-reform-arm64 as it is not installed" >&2 fi echo "I: Version of reform-tools: $(dpkg-query --show --showformat '${Version}' reform-tools)" >&2 HUMAN_ROOT= case $(findmnt --noheadings --evaluate --mountpoint / --output SOURCE) in "/dev/reformvg/root") pv_device="$(pvdisplay --noheadings --select vgname=reformvg --columns --options pv_name)" pv_device="${pv_device# }" # remove whitespace prefix if [ "$pv_device" = "/dev/mapper/reform_crypt" ]; then luks_disk="$(lsblk --json -o PATH,PKNAME | jq -r '.blockdevices[] | select(.path == "/dev/mapper/reform_crypt") | .pkname')" if [ "$luks_disk" = "${DEV_SSD}" ]; then HUMAN_ROOT="LVM vg 'reformvg' on LUKS device 'reform_crypt' on SSD" else echo "W: reform_crypt LUKS device on unusual disk: /dev/$luks_disk" >&2 fi else echo "W: LVM volume group reformvg on unexpected partition: $pv_device" >&2 fi ;; "/dev/${DEV_MMC}"*) HUMAN_ROOT="eMMC" ;; "/dev/${DEV_SD}"*) HUMAN_ROOT="SD-card" ;; "/dev/${DEV_SSD}"*) HUMAN_ROOT="SSD" ;; esac echo "I: Mount source of /: $(findmnt --noheadings --evaluate --mountpoint / --output SOURCE) (${HUMAN_ROOT:-n.a.})" >&2 HUMAN_BOOT= case $(findmnt --noheadings --evaluate --mountpoint /boot --output SOURCE) in "/dev/${DEV_MMC}"*) HUMAN_BOOT="eMMC" ;; "/dev/${DEV_SD}"*) HUMAN_BOOT="SD-card" ;; esac echo "I: Mount source of /boot: $(findmnt --noheadings --evaluate --mountpoint /boot --output SOURCE) (${HUMAN_BOOT})" >&2 if [ ! -e "/etc/flash-kernel/machine" ]; then # /etc/flash-kernel/machine not existing is only a potential problem # on imx8mq case "$(cat /proc/device-tree/model)" in "MNT Reform 2" | "MNT Reform 2 HDMI") echo "W: /etc/flash-kernel/machine does not exist" >&2 ;; esac fi if [ ! -e "/proc/device-tree/model" ]; then echo "E: /proc/device-tree/model does not exist" >&2 fi if [ -e "/etc/flash-kernel/machine" ] && [ -e "/proc/device-tree/model" ] && [ "$(cat /proc/device-tree/model)" != "$(cat /etc/flash-kernel/machine)" ]; then echo "E: your currently loaded dtb is not the one referenced by flash-kernel" >&2 echo "E: contents of /proc/device-tree/model: $(cat /proc/device-tree/model)" >&2 echo "E: contents of /etc/flash-kernel/machine: $(cat /etc/flash-kernel/machine)" >&2 fi case "$MIRROR" in mntre.com) aptprefcontent="Package: *\nPin: release n=reform, l=reform\nPin-Priority: 990\n" ;; reform.debian.net) aptprefcontent="Package: *\nPin: origin \"reform.debian.net\"\nPin-Priority: 999\n" ;; esac if [ ! -e /etc/apt/preferences.d/reform.pref ]; then echo "E: /etc/apt/preferences.d/reform.pref doesn't exist" >&2 echo "E: you should not install packages on this system unless you know what you are doing" >&2 echo "E: /etc/apt/preferences.d/reform.pref should contain the following lines:" >&2 printf "$aptprefcontent" >&2 else if ! printf "$aptprefcontent" | cmp --quiet - /etc/apt/preferences.d/reform.pref; then echo "W: unexpected content in /etc/apt/preferences.d/reform.pref:" >&2 printf "$aptprefcontent" | diff -u - /etc/apt/preferences.d/reform.pref || true echo "W: you should not install packages on this system unless you know what you are doing" >&2 fi fi for META in reform-desktop-full reform-desktop-minimal; do # if meta package is installed, we don't need to check its Depends RELATIONS="Recommends Suggests" if ! dpkg-query --showformat '${db:Status-Status}\n' --show "$META" 2>/dev/null | grep -q '^installed$'; then echo "W: MNT Reform Desktop meta-package is not installed: $META" >&2 RELATIONS="Depends $RELATIONS" fi for REL in $RELATIONS; do for PKG in $(dpkg-query --show --showformat '${'"$REL"'}' "$META"); do PKG="${PKG%%,}" # strip potentially trailing comma if ! dpkg-query --showformat '${db:Status-Status}\n' --show "$PKG" 2>/dev/null | grep -q '^installed$'; then echo "W: $REL of $META is not installed: $PKG" >&2 fi done done done if [ -z "$(findmnt --fstab --noheadings --evaluate --mountpoint / --output SOURCE)" ]; then echo "E: your /etc/fstab does not have an entry for /" >&2 echo "E: your / device probably is: $(findmnt --noheadings --evaluate --mountpoint / --output SOURCE)" >&2 echo "E: add this to your /etc/fstab:" >&2 echo "$(findmnt --noheadings --evaluate --mountpoint / --output SOURCE) / auto errors=remount-ro 0 1" >&2 fi if [ -z "$(findmnt --fstab --noheadings --evaluate --mountpoint /boot --output SOURCE)" ]; then echo "E: your /etc/fstab does not have an entry for /boot" >&2 if [ "$EMMC_BOOT" = true ]; then echo "E: for eMMC booting, add:" >&2 echo "/dev/${DEV_MMC}p1 /boot auto errors=remount-ro 0 1" >&2 fi if [ "$SD_BOOT" = true ]; then echo "E: for SD-Card booting, add:" >&2 echo "/dev/${DEV_SD}p1 /boot auto errors=remount-ro 0 1" >&2 fi fi if ! mountpoint --quiet /boot; then echo "E: your /boot has nothing mounted on it -- fix your /etc/fstab" >&2 fi if [ "$EMMC_USE" = true ] && [ ! -e "/dev/${DEV_MMC}p2" ]; then echo "W: /dev/${DEV_MMC}p2 doesn't exist." >&2 echo "W: To update your eMMC to sysimage-v4 you can run reform-flash-rescue" >&2 echo "W: Only run reform-flash-rescue if you intend a factory-reset of your eMMC" >&2 echo "W: Do not use reform-flash-rescue if you boot from eMMC because this will overwrite your /boot partition" >&2 fi if [ ! -e /etc/flash-kernel/machine ]; then # /etc/flash-kernel/machine not existing is only a potential problem # on imx8mq case "$(cat /proc/device-tree/model)" in "MNT Reform 2" | "MNT Reform 2 HDMI") echo "E: /etc/flash-kernel/machine doesn't exist" >&2 echo "E: It should contain either 'MNT Reform 2' (for single display) or 'MNT Reform 2 HDMI' (for dual display)." >&2 echo "E: You can run reform-display-config as root to create a working version." >&2 ;; esac else case "$(cat /etc/flash-kernel/machine)" in "MNT Reform 2") : ;; "MNT Reform 2 HDMI") : ;; "MNT Reform 2 with BPI-CM4 Module") echo "W: /etc/flash-kernel/machine is not needed on A311D. Consider removing it." >&2 ;; "MNT Reform 2 with LS1028A Module") echo "W: /etc/flash-kernel/machine is not needed on LS1028A. Consider removing it." >&2 ;; *) echo "E: unexpected content in /etc/flash-kernel/machine" >&2 ;; esac fi flashkerneldefaultcontent="LINUX_KERNEL_CMDLINE=\"\"\nLINUX_KERNEL_CMDLINE_DEFAULTS=\"\"\n" if [ ! -e /etc/default/flash-kernel ]; then echo "E: /etc/default/flash-kernel doesn't exist" >&2 echo "E: /etc/default/flash-kernel should contain the following lines:" >&2 printf "$flashkerneldefaultcontent" >&2 else if ! printf "$flashkerneldefaultcontent" | cmp --quiet - /etc/default/flash-kernel; then echo "W: unexpected content in /etc/default/flash-kernel:" >&2 printf "$flashkerneldefaultcontent" | diff -u - /etc/default/flash-kernel || true fi fi if [ -e /etc/flash-kernel/preboot.d/00reform2_preboot ]; then if printf "# place here any u-boot commands to be executed before boot\n" | cmp --quiet - /etc/flash-kernel/preboot.d/00reform2_preboot; then echo "E: /etc/flash-kernel/preboot.d/00reform2_preboot contains default content overriding /usr/share/flash-kernel/preboot.d/00reform2_preboot" >&2 echo "E: consider deleting /etc/flash-kernel/preboot.d/00reform2_preboot in favour of /usr/share/flash-kernel/preboot.d/00reform2_preboot" >&2 else echo "W: your custom /etc/flash-kernel/preboot.d/00reform2_preboot is overriding /usr/share/flash-kernel/preboot.d/00reform2_preboot" >&2 fi fi if [ -e /etc/flash-kernel/ubootenv.d/00reform2_ubootenv ]; then if printf '# setenv bootpart "1"\n# setenv prefix "/"\n# setenv kernel_addr_r "0x40480000"\n# setenv fdt_addr_r "0x50000000"\n# setenv ramdisk_addr_r "0x51000000"\n' | cmp --quiet - /etc/flash-kernel/ubootenv.d/00reform2_ubootenv; then echo "E: /etc/flash-kernel/ubootenv.d/00reform2_ubootenv contains default content overriding /usr/share/flash-kernel/ubootenv.d/00reform2_ubootenv" >&2 echo "E: consider deleting /etc/flash-kernel/ubootenv.d/00reform2_ubootenv in favour of /usr/share/flash-kernel/ubootenv.d/00reform2_ubootenv" >&2 else echo "W: your custom /etc/flash-kernel/ubootenv.d/00reform2_ubootenv is overriding /usr/share/flash-kernel/ubootenv.d/00reform2_ubootenv" fi fi initramfstoolsmodulescontent="pwm_imx27\nnwl-dsi\nti-sn65dsi86\nimx-dcss\npanel-edp\nmux-mmio\nmxsfb\nusbhid\nimx8mq-interconnect\n" if [ -e /etc/initramfs-tools/modules ] && printf "$initramfstoolsmodulescontent" | cmp --quiet - /etc/initramfs-tools/modules; then echo "W: /etc/initramfs-tools/modules contains default content superseded by /usr/share/initramfs-tools/modules.d/reform.conf" >&2 echo "W: consider restoring /etc/initramfs-tools/modules to its original state by running:" >&2 echo "sed '/^###/d' /usr/share/initramfs-tools/modules | sudo tee /etc/initramfs-tools/modules" >&2 fi if [ ! -e /etc/motd ]; then echo "I: /etc/motd does not exist" >&2 elif [ ! -L /etc/motd ]; then echo "I: /etc/motd does not exist" >&2 elif [ "$(readlink /etc/motd)" != "motd-rescue" ] && [ "$(readlink /etc/motd)" != "motd-full" ]; then echo "I: /etc/motd does neither point to motd-rescue nor to motd-full" >&2 fi if grep --quiet '^root::' /etc/shadow; then echo "E: root account has no password (maybe run passwd -l root)" >&2 fi if [ ! -e /etc/skel/.profile ]; then echo "E: /etc/skel/.profile doesn't exist" >&2 echo "E: install the package bash to create it" >&2 else # shellcheck disable=SC2016 skelprofilecontent='if [ "$(whoami)" = "root" ]; then reform-help --root; elif [ -z "$WAYLAND_DISPLAY" ]; then reform-help; fi' if [ "$(tail -1 /etc/skel/.profile)" != "$skelprofilecontent" ]; then echo "E: unexpected last line in /etc/skel/.profile, should be:" >&2 echo "$skelprofilecontent" >&2 fi fi if [ -n "$(dpkg --verify reform-tools)" ]; then echo "I: the following files differ from how they are shipped by reform-tools (ignore /var/lib/alsa/asound.state):" >&2 dpkg --verify reform-tools fi if dpkg-query --showformat '${db:Status-Status}\n' --show "linux-image-arm64" 2>/dev/null | grep -q '^installed$'; then case "$MIRROR" in mntre.com) if ! apt-cache policy linux-image-arm64 | grep --quiet mntre.com; then echo "E: the linux-image-arm64 package cannot come from the MNT repos" >&2 fi ;; reform.debian.net) if ! apt-cache policy linux-image-arm64 | grep --quiet /reform.debian.net/; then echo "E: the linux-image-arm64 package cannot come from the reform.debian.net repos" >&2 fi ;; *) echo "invalid mirror: $MIRROR" >&2 exit 1 ;; esac echo "W: The deprecated meta-package linux-image-arm64 is installed." >&2 if dpkg-query --showformat '${db:Status-Status}\n' --show "linux-image-mnt-reform-arm64" 2>/dev/null | grep -q '^installed$'; then echo "W: Since the new meta-package linux-image-mnt-reform-arm64 is installed," >&2 echo "W: the old meta-package linux-image-arm64 should be removed." >&2 else echo "W: Please install the new meta-package linux-image-mnt-reform-arm64" >&2 echo "W: and remove the old meta-package linux-image-arm64." >&2 fi if ! dpkg-query --showformat '${Version}' --show linux-image-arm64 | grep --quiet reform; then echo "E: the currently installed package linux-image-arm64 does not come with Reform patches" >&2 fi fi if dpkg-query --showformat '${db:Status-Status}\n' --show "linux-image-mnt-reform-arm64" 2>/dev/null | grep -q '^installed$'; then case "$MIRROR" in mntre.com) if ! apt-cache policy linux-image-mnt-reform-arm64 | grep --quiet mntre.com; then echo "E: the linux-image-mnt-reform-arm64 package cannot come from the MNT repos" >&2 fi ;; reform.debian.net) if ! apt-cache policy linux-image-mnt-reform-arm64 | grep --quiet /reform.debian.net/; then echo "E: the linux-image-mnt-reform-arm64 package cannot come from the reform.debian.net repos" >&2 fi ;; *) echo "invalid mirror: $MIRROR" >&2 exit 1 ;; esac else echo "E: linux-image-mnt-reform-arm64 is not installed" >&2 fi if ! dpkg-query --showformat '${db:Status-Status}\n' --show "linux-headers-mnt-reform-arm64" 2>/dev/null | grep -q '^installed$'; then echo "E: linux-headers-mnt-reform-arm64 is not installed -- cannot compile reform2_lpc module" >&2 fi for file in /boot/initrd.img-*-reform2-arm64 /boot/vmlinuz-*-reform2-arm64; do if [ ! -e "$file" ]; then continue fi echo "I: file from deprecated kernel flavour found: $file" >&2 done for file in /boot/initrd.img-*-mnt-reform-arm64 /boot/vmlinuz-*-mnt-reform-arm64; do suffix="${file##/boot/}" suffix="${suffix##initrd.img-}" suffix="${suffix##vmlinuz-}" if ! dpkg-query --showformat '${db:Status-Status}\n' --show "linux-image-$suffix" 2>/dev/null | grep -q '^installed$'; then echo "I: $file does not belong to any installed kernel package" >&2 fi done if ! dpkg-query --showformat '${db:Status-Status}\n' --show "linux-image-$(uname -r)" 2>/dev/null | grep -q '^installed$'; then echo "E: the currently running kernel is not installed as a package" >&2 fi if ! uname --kernel-version | grep --quiet --fixed-strings " $(dpkg-query --show --showformat '${Version}' linux-image-mnt-reform-arm64) "; then echo "E: the currently running kernel is not the one provided by linux-image-mnt-reform-arm64" >&2 fi if [ "$MIRROR" = "reform.debian.net" ] && dpkg-query --showformat '${db:Status-Status}\n' --show "reform-qcacld2" 2>/dev/null | grep -q '^installed$'; then echo "E: Having reform-qcacld2 on a system configured to use packages for Debian stable from reform.debian.net will attempt installing the kernel package from the MNT repositories in the kernel postinstallation hook" >&2 echo "W: Consider replacing reform-qcacld2 with ezurio-qcacld-2.0-dkms for Debian stable and stable-backports kernels from reform.debian.net" >&2 fi if [ "$MIRROR" = "mntre.com" ] && ! dpkg-query --showformat '${db:Status-Status}\n' --show "reform-qcacld2" 2>/dev/null | grep -q '^installed$'; then case "$(cat /proc/device-tree/model)" in "MNT Pocket Reform with i.MX8MP Module.conf") echo "E: For the official MNT Debian on Pocket Reform with i.MX8MP, the reform-qcacld2 package needs to be installed for working wifi" >&2 ;; esac fi if [ ! -e /boot/boot.scr ]; then echo "E: /boot/boot.scr doesn't exist" >&2 echo "E: run 'sudo flash-kernel' to create it" >&2 elif ! grep --quiet "setenv fk_kvers '$(uname -r)'" /boot/boot.scr; then echo "E: /boot/boot.scr doesn't reference the currently running kernel" >&2 fi if [ ! -e "/boot/vmlinuz-$(uname -r)" ]; then echo "E: no vmlinuz in /boot for the currently running kernel" >&2 fi if [ ! -e "/boot/initrd.img-$(uname -r)" ]; then echo "E: no initrd.img in /boot for the currently running kernel" >&2 fi if [ ! -e "/boot/dtb-$(uname -r)" ]; then echo "E: no dtb-* symlink for the currently running kernel" >&2 echo "E: run 'sudo flash-kernel' to create it" >&2 elif [ ! -e "/boot/dtbs/$(uname -r)/$DTBPATH" ]; then echo "E: device tree file $DTBPATH is missing from /boot/dtbs" >&2 elif [ "$(readlink "/boot/dtb-$(uname -r)")" != "dtbs/$(uname -r)/$DTBPATH" ]; then echo "E: /boot/dtb-$(uname -r) symlink does not reference dtbs/$(uname -r)/$DTBPATH but: $(readlink "/boot/dtb-$(uname -r)")" >&2 fi if [ -e "/etc/modprobe.d/reform.conf" ]; then if cmp --quiet "/usr/lib/modprobe.d/reform.conf" "/etc/modprobe.d/reform.conf"; then echo "W: Your /etc/modprobe.d/reform.conf is identical to /usr/lib/modprobe.d/reform.conf" >&2 echo "W: The reform.conf in /etc overrides the file in /usr which is shipped by the reform-tools package." >&2 echo "W: You can thus safely delete your /etc/modprobe.d/reform.conf in favour of the copy shipped by reform-tools in /usr." >&2 else echo "W: your custom /etc/modprobe.d/reform.conf overrides /usr/lib/modprobe.d/reform.conf" >&2 fi fi if [ -e /proc/modules ] && ! grep --quiet '^reform2_lpc ' /proc/modules; then echo "E: reform2_lpc is not loaded (battery status information will be missing)" >&2 fi if [ ! -e "/usr/lib/modules/$(uname -r)/updates/dkms/reform2_lpc.ko" ] \ && [ ! -e "/usr/lib/modules/$(uname -r)/updates/dkms/reform2_lpc.ko.xz" ]; then echo "E: /usr/lib/modules/$(uname -r)/updates/dkms/reform2_lpc.ko{.xz} does not exist" >&2 fi worddiff() { for word in $1; do case $2 in "$word" | "$word "* | *" $word" | *" $word "*) : ;; *) echo "$word" ;; esac done } if [ "$(tr ' ' '\n' &2 worddiff "$(cat /proc/cmdline)" "$BOOTARGS" | sed 's/^/ + /' >&2 fi if [ -n "$(worddiff "$BOOTARGS" "$(cat /proc/cmdline)")" ]; then echo "I: kernel boot parameters which are the default but your system doesn't use them:" >&2 worddiff "$BOOTARGS" "$(cat /proc/cmdline)" | sed 's/^/ - /' >&2 fi fi if [ "$(tr ' ' '\n' &2 echo "W: This could lead to the luks password prompt being printed to serial instead of your screen." >&2 fi if ! dpkg-query --showformat '${db:Status-Status}\n' --show "linux-headers-$(uname -r)" 2>/dev/null | grep -q '^installed$'; then echo "E: the linux header package linux-headers-$(uname -r) for the currently running kernel is not installed" >&2 fi for f in mntre reform_bookworm reform_bookworm-backports; do file="/etc/apt/sources.list.d/${f}.sources" if [ ! -e "$file" ]; then continue fi if [ "$(stat -c %a "$file")" != 666 ]; then # nothing to do continue fi echo "E: $file has insecure permissions 0666, consider a chmod 644" >&2 done for f in . firefox firefox/syspref.js motd-full motd-rescue profile.d profile.d/reform.sh profile.d/reform-setup.sh; do file="/etc/$f" if [ ! -e "$file" ]; then continue fi # only process world-writable files if [ -z "$(find "$file" -maxdepth 0 \( \! -type l \) -perm /o+w)" ]; then continue fi echo "E: $file has insecure permissions (it is world-writable)" >&2 done if [ -e /etc/skel ] && [ "$(stat -c %a /etc/skel)" = "777" ]; then echo "E: /etc/skel has insecure permissions 0777, consider a chmod -R g-w,o-rw" >&2 fi if [ -n "$(find /etc \( \! -type l \) -perm /o+w)" ]; then echo "E: the following files in /etc are world-writable, consider removing world-writable permissions:" >&2 find /etc \( \! -type l \) -perm /o+w >&2 fi if [ -n "$(find /root \( \! -type l \) -perm /o+w)" ]; then echo "E: the following files in /root are world-writable, consider removing world-writable permissions:" >&2 find /root \( \! -type l \) -perm /o+w >&2 fi case "$(cat /proc/device-tree/model)" in "MNT Reform 2" | "MNT Reform 2 HDMI") if [ ! -e /etc/u-boot-menu/conf.d ]; then echo "W: /etc/u-boot-menu/conf.d does not exist -- create it by running reform-display-config" >&2 fi if [ ! -e /etc/u-boot-menu/conf.d/reform.conf ]; then echo "W: /etc/u-boot-menu/conf.d/reform.conf does not exist -- create it by running reform-display-config" >&2 else case "$(cat /proc/device-tree/model)" in "MNT Reform 2") reformconfcontent="# the content of this file is auto-generated by reform-display-config\nU_BOOT_FDT=/freescale/imx8mq-mnt-reform2.dtb\n" ;; "MNT Reform 2 HDMI") reformconfcontent="# the content of this file is auto-generated by reform-display-config\nU_BOOT_FDT=/freescale/imx8mq-mnt-reform2-hdmi.dtb\n" ;; esac if ! printf "$reformconfcontent" | cmp --quiet - /etc/u-boot-menu/conf.d/reform.conf; then echo "W: unexpected content in /etc/u-boot-menu/conf.d/reform.conf:" >&2 printf "$reformconfcontent" | diff -u - /etc/u-boot-menu/conf.d/reform.conf || true echo "W: re-run reform-display-config for the corrent content" >&2 fi fi ;; esac if [ "$OFFLINE" = "yes" ]; then echo "I: skipping the remaining checks because --offline was used" >&2 else # shellcheck disable=SC2016 case "$MIRROR" in mntre.com) if [ "$(apt-get indextargets 'Created-By: Packages' 'Repo-URI: https://mntre.com/reform-debian-repo/' --format '$(RELEASE)')" != reform ]; then echo "E: the reform repository is not known to apt" >&2 echo "E: add the following line to your /etc/apt/sources.list to fix this" >&2 echo "deb [arch=arm64 trusted=yes] https://mntre.com/reform-debian-repo reform main" >&2 fi case "$(apt-get indextargets 'Created-By: Packages' 'Repo-URI: https://reform.debian.net/debian/' --format '$(RELEASE)')" in bookworm*) echo "E: you have the reform.debian.net repository enabled while also using the mntre.com mirror. Consider choosing one or the other but not both." >&2 ;; esac ;; reform.debian.net) case "$(apt-get indextargets 'Created-By: Packages' 'Repo-URI: https://reform.debian.net/debian/' --format '$(RELEASE)')" in bookworm*) : ;; *) echo "E: the reform.debian.net repository is not known to apt" >&2 ;; esac if [ "$(apt-get indextargets 'Created-By: Packages' 'Repo-URI: https://mntre.com/reform-debian-repo/' --format '$(RELEASE)')" = reform ]; then echo "E: you have the mntre.com repository enabled while also using the reform.debian.net mirror. Consider choosing one or the other but not both." >&2 fi ;; *) echo "invalid mirror: $MIRROR" >&2 exit 1 ;; esac # on a311d we need non-free-firmware # shellcheck disable=SC2016 if [ "$NEED_NONFREE" = true ] && ! apt-get indextargets 'Created-By: Packages' 'Origin: Debian' 'Repo-URI: http://deb.debian.org/debian/' --format '$(COMPONENT)' | sort -u | grep --silent non-free-firmware; then echo "W: you do not have non-free-firmware enabled" >&2 echo "W: this is required to install non-free firmware blobs that are required for platforms like Banana Pi A311D" >&2 echo "W: you can add a line like this to your /etc/apt/sources.list:" >&2 echo "deb http://deb.debian.org/debian unstable non-free-firmware" >&2 fi ubooturl="https://source.mnt.re/reform/${UBOOT_PROJECT}/-/jobs/artifacts/${UBOOT_TAG}/raw/$(basename "$DTBPATH" .dtb)-flash.bin?job=build" ubootbin=$(mktemp) ret=0 /usr/lib/apt/apt-helper download-file "$ubooturl" "$ubootbin" "SHA1:$UBOOT_SHA1" >/dev/null || ret=$? if [ "$ret" != 0 ]; then echo "E: download of $ubooturl failed" >&2 else if [ ! -e /boot/flash.bin ]; then echo "W: /boot/flash.bin doesn't exist" >&2 echo "W: You can download the latest version by running as root:" >&2 echo "reform-flash-uboot" >&2 elif ! cmp --quiet /boot/flash.bin "$ubootbin"; then echo "W: /boot/flash.bin is not the latest uboot" >&2 echo "W: You can update it to the latest version by running as root:" >&2 echo "reform-flash-uboot" >&2 fi ubootsize=$(stat --format=%s "$ubootbin") if [ "$EMMC_BOOT" = true ]; then if cmp --quiet --bytes="$((ubootsize - FLASHBIN_OFFSET))" "--ignore-initial=$FLASHBIN_OFFSET:$UBOOT_OFFSET" "$ubootbin" "/dev/${DEV_MMC}boot0" 2>/dev/null; then echo "I: eMMC contains the latest u-boot version ${UBOOT_TAG}" >&2 else echo "W: eMMC does not contain latest uboot" >&2 echo "W: You can update it to the latest version by running as root:" >&2 echo "reform-flash-uboot emmc" >&2 fi fi if [ "$SD_BOOT" = true ] && [ -e "/dev/$DEV_SD" ]; then if cmp --quiet --bytes="$((ubootsize - FLASHBIN_OFFSET))" --ignore-initial="$FLASHBIN_OFFSET:$UBOOT_OFFSET" "$ubootbin" "/dev/$DEV_SD" 2>/dev/null; then echo "I: SD-card contains the latest u-boot version ${UBOOT_TAG}" >&2 else echo "W: SD-Card does not contain latest uboot" >&2 echo "W: You can update it to the latest version by running as root:" >&2 echo "reform-flash-uboot sd" >&2 fi fi fi rm "$ubootbin" case "$(cat /proc/device-tree/model)" in "MNT Reform 2 with LS1028A Module") mhdpfwbin=$(mktemp) /usr/lib/apt/apt-helper download-file \ "https://source.mnt.re/reform/reform-ls1028a-uboot/-/raw/main/ls1028a-mhdpfw.bin" \ "$mhdpfwbin" "SHA1:fa96b9aa59d7c1e9e6ee1c0375d0bcc8f8e5b78c" >/dev/null if [ ! -e /boot/ls1028a-mhdpfw.bin ]; then echo "W: /boot/ls1028a-mhdpfw.bin doesn't exist" >&2 echo "W: You can download the latest version by running as root:" >&2 echo "reform-flash-uboot" >&2 elif ! cmp --quiet /boot/ls1028a-mhdpfw.bin "$mhdpfwbin"; then echo "W: /boot/ls1028a-mhdpfw.bin is not the latest uboot" >&2 echo "W: You can update it to the latest version by running as root:" >&2 echo "reform-flash-uboot" >&2 fi rm "$mhdpfwbin" ;; esac fi reform-tools-1.71/bin/reform-compstat000077500000000000000000000067551477621656200177470ustar00rootroot00000000000000#!/usr/bin/python3 # SPDX-License-Identifier: GPL-3.0+ # Copyright 2022-2022 Lukas F. Hartmann # Copyright 2024-2025 Johannes Schauer Marin Rodrigues # # Do not run shellcheck on this file # shellcheck disable=SC1071 import time, psutil, sys, getopt def draw_bar(val, maxval): if val < 0: return "    " bars = ["    ", "▁", "▁", "▂", "▂", "▃", "▄", "▅", "▆", "▆", "▇", "█"] return bars[int((len(bars) - 1) * min(max(0, val / maxval), 1))] def draw_chart(lst, maxval): chart = "" l = len(lst) for x in range(l): chart += draw_bar(lst[l - x - 1], maxval) return chart def history_insert(lst, item, depth): lst.insert(0, item) if len(lst) > depth: lst.pop() return lst def usage(): print( "Visualize CPU usage and disk read/writes as text using box-drawing characters.", file=sys.stderr, ) print(file=sys.stderr) print( "Usage: compstat -d -i ", file=sys.stderr, ) print(file=sys.stderr) print("Options:", file=sys.stderr) print(" --help Display this help text and exit.", file=sys.stderr) print(" -d NUM Set number of bars to NUM.", file=sys.stderr) print(" -i SECS Set the update interval to SEC seconds.", file=sys.stderr) print(" --percpu Display the CPU utilization per CPU core.", file=sys.stderr) def main(argv): depth = 5 interval = 0.3 percpu = False try: opts, args = getopt.getopt(argv, "hd:i:", longopts=["percpu", "help"]) except getopt.GetoptError as e: print(f"E: {e.msg}", file=sys.stderr) print(file=sys.stderr) usage() sys.exit(2) for opt, arg in opts: if opt == "-d": depth = int(arg) elif opt == "-i": interval = float(arg) elif opt == "--percpu": percpu = True elif opt in ["-h", "--help"]: usage() exit() if percpu: cpu_history = {i: [] for i in range(psutil.cpu_count())} else: cpu_history = [] read_history = [] write_history = [] ldisk_activity = psutil.disk_io_counters() while True: cpu_usage = psutil.cpu_percent(percpu=percpu) disk_activity = psutil.disk_io_counters() if percpu: for i, cpu in enumerate(cpu_usage): history_insert(cpu_history[i], cpu, depth) else: history_insert(cpu_history, cpu_usage, depth) history_insert( read_history, max(0, disk_activity.read_time - ldisk_activity.read_time) / (interval * 1000), depth, ) history_insert( write_history, max(0, disk_activity.write_time - ldisk_activity.write_time) / (interval * 1000), depth, ) print( "CPU " + ( ( "".join( draw_chart(cpu_history[i], 98.0) for i in range(psutil.cpu_count()) ) ) if percpu else draw_chart(cpu_history, 98.0) ) + " R/W " + draw_chart(read_history, 0.98) + " " + draw_chart(write_history, 0.98), flush=True, ) ldisk_activity = disk_activity time.sleep(interval) main(sys.argv[1:]) reform-tools-1.71/bin/reform-config000077500000000000000000000013421477621656200173450ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2020-2022 Lukas F. Hartmann # Copyright 2022-2025 Johannes Schauer Marin Rodrigues set -eu usage() { echo "Run dpkg-reconfigure for keyboard-configuration and tzdata under sudo" >&2 echo "to configure the keyboard layout and timezone." >&2 echo >&2 echo "Usage: $0 [--help]" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 } if [ "$#" -gt 0 ]; then if [ "$1" != "--help" ]; then echo "E: too many arguments" >&2 usage exit 1 fi usage exit 0 fi sudo dpkg-reconfigure keyboard-configuration sudo systemctl restart console-setup sudo dpkg-reconfigure tzdata reform-tools-1.71/bin/reform-display-config000077500000000000000000000064541477621656200210210ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2020-2023 Lukas F. Hartmann # Copyright 2022-2025 Johannes Schauer Marin Rodrigues set -e usage() { echo "On the i.MX8MQ, choose whether to use the single or dual display device tree" >&2 echo "by writing the correct value into /etc/flash-kernel/machine and re-generating" >&2 echo "the initramfs and running flash-kernel." >&2 echo >&2 echo "Usage: $0 [--help] [--emmc] dual|single" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 echo " --emmc Record choice on /boot on eMMC." >&2 } if [ "$#" -gt 0 ] && [ "$1" = "--help" ]; then usage exit 0 fi if [ "$(id -u)" -ne 0 ]; then echo "reform-display-config has to be run as root / using sudo." exit fi case "$(cat /proc/device-tree/model)" in "MNT Reform 2" | "MNT Reform 2 HDMI") : ;; *) echo "Sorry, reform-display-config is only supported on MNT Reform 2 with i.MX8MQ processor module." exit 1 ;; esac CHOICE="$1" BOOTPART="mmcblk1p1" BOOTDISK="SD card" if [ "--emmc" = "$1" ]; then CHOICE="$2" BOOTPART="mmcblk0p1" BOOTDISK="eMMC" if [ ! -b "/dev/mmcblk0p1" ]; then echo "/dev/mmcblk0p1 doesn't exist -- run reform-flash-rescue" >&2 exit 1 fi fi # even if u-boot-menu is not installed, create the config file so that once it # is installed, it will immediately work without having to re-run # reform-display-config mkdir -p "/etc/u-boot-menu/conf.d/" case "$CHOICE" in dual) echo "MNT Reform 2 HDMI" >/etc/flash-kernel/machine cat </etc/u-boot-menu/conf.d/reform.conf # the content of this file is auto-generated by reform-display-config U_BOOT_FDT=/freescale/imx8mq-mnt-reform2-hdmi.dtb END ;; single) echo "MNT Reform 2" >/etc/flash-kernel/machine cat </etc/u-boot-menu/conf.d/reform.conf # the content of this file is auto-generated by reform-display-config U_BOOT_FDT=/freescale/imx8mq-mnt-reform2.dtb END ;; *) echo "Usage: " echo " reform-display-config dual Select dual-display support (internal + HDMI)." echo " reform-display-config single Select only internal display (turns off HDMI)." echo " reform-display-config --emmc dual|single Record choice on eMMC." exit ;; esac if ! findmnt --noheadings --source /dev/$BOOTPART --mountpoint /boot >/dev/null; then echo "Assuming boot files are on $BOOTDISK, but your system doesn't have it mounted." >&2 echo "Mounting /dev/$BOOTPART on /boot." >&2 if mountpoint --quiet /boot; then echo "/boot already has something mounted on it" >&2 exit 1 fi if [ -n "$(lsblk --noheadings --output=MOUNTPOINT /dev/$BOOTPART)" ]; then echo "/dev/$BOOTPART is still in use" >&2 exit 1 fi trap "umount /boot" EXIT INT TERM mount /dev/$BOOTPART /boot fi if command -v flash-kernel >/dev/null; then flash-kernel fi if command -v u-boot-update >/dev/null; then u-boot-update fi if [ "--emmc" = "$1" ]; then echo "Your /boot partition is on emmc (/dev/$BOOTPART)." >&2 else echo "Your /boot partition is on your SD-Card (/dev/$BOOTPART)." >&2 fi echo "Restart MNT Reform (type: reboot) after saving your work to activate the changes." # exit trap will automatically unmount /boot if necessary once the script exits reform-tools-1.71/bin/reform-emmc-bootstrap000077500000000000000000000217441477621656200210440ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2025 Johannes Schauer Marin Rodrigues set -eu usage() { echo "Set up eMMC with a /boot partition which loads the OS from the SSD." >&2 echo "This tool is usually run from a rescue system on an SD-card to" >&2 echo "migrate a system from one SoM to another." >&2 echo "WARNING: this tool will erase the contents of your eMMC." >&2 echo >&2 echo "Usage: $0 [--help]" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 echo >&2 echo "This utility is not able to create a working /boot partition on" >&2 echo "eMMC for arbitrary installations. It currently understands" >&2 echo >&2 echo " - single partition on SSD with the rootfs" >&2 echo " - two partitions on SSD, one with the rootfs the other swap" >&2 echo " - the luks/lvm setup created by reform-setup-encrypted-disk" >&2 } is_current_root() { FSTAB_ROOT="$(findmnt --fstab --noheadings --evaluate --mountpoint / --output SOURCE)" [ "${1}" = "${FSTAB_ROOT}" ] } if [ "$#" -gt 0 ]; then case $1 in --help) usage exit 0 ;; *) echo "E: unknown option: $1" >&2 ;; esac fi # shellcheck source=/dev/null if [ -e "./machines/$(cat /proc/device-tree/model).conf" ]; then . "./machines/$(cat /proc/device-tree/model).conf" elif [ -e "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" ]; then . "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" else echo "E: unable to find config for $(cat /proc/device-tree/model)" >&2 exit 1 fi cleanup() { if [ -n "$MOUNTROOT" ]; then if mountpoint --quiet "$MOUNTROOT"; then umount --recursive "$MOUNTROOT" fi rmdir "$MOUNTROOT" fi if ! is_current_root /dev/reformvg/root; then if [ -e /dev/reformvg ]; then vgchange -an reformvg fi if [ -e /dev/mapper/reform_crypt ]; then cryptsetup luksClose reform_crypt fi fi } main() { ROOTPART="$1" trap cleanup EXIT INT TERM MOUNTROOT="$(lsblk --noheadings --output=MOUNTPOINT "$ROOTPART")" if [ -z "$MOUNTROOT" ]; then if ! get_exclusive_write_lock "$ROOTPART"; then echo "E: device $ROOTPART is still in use" >&2 exit 1 fi MOUNTROOT="$(mktemp --tmpdir --directory reform-emmc-bootstrap.XXXXXXXXXX)" mount "$ROOTPART" "$MOUNTROOT" for dir in dev sys proc; do if [ ! -d "$MOUNTROOT/$dir" ]; then echo "E: The directory '$dir' does not exist in the filesystem on $ROOTPART" >&2 exit 1 fi done mount -o bind /dev "$MOUNTROOT/dev/" mount -t sysfs sys "$MOUNTROOT/sys/" mount -t proc proc "$MOUNTROOT/proc/" elif [ -n "$MOUNTROOT" ]; then if [ "$MOUNTROOT" = "/" ]; then if mountpoint --quiet "/boot"; then echo "E: /boot still has something mounted on it" >&2 exit 1 fi else echo "E: $ROOTPART is still being mounted on $MOUNTROOT -- umount before proceeding" >&2 exit 1 fi fi # comment out old /etc/fstab sed -e 's/^/#/' "$MOUNTROOT/etc/fstab" >"$MOUNTROOT/etc/fstab.new" # write new mountpoints cat <>"$MOUNTROOT/etc/fstab.new" $ROOTPART / auto errors=remount-ro 0 1 /dev/${DEV_MMC}p1 /boot auto errors=remount-ro 0 1 END cat </dev/null; then echo "I: No kernel package installed." >&2 printf "Do you want this script to install linux-image-mnt-reform-arm64 for you? [y/N] " read -r response if [ "$response" != "y" ]; then echo "E: no kernel packages installed, exiting." >&2 exit 1 fi chroot "$MOUNTROOT" apt-get install --yes linux-image-mnt-reform-arm64 else # upgrade linux-image-mnt-reform-arm64 in case that the installed kernel is # not downloadable anymore chroot "$MOUNTROOT" apt-get install --yes --only-upgrade linux-image-mnt-reform-arm64 fi # also regenerate everything for other installed kernel packages chroot "$MOUNTROOT" dpkg-query --search '/boot/vmlinuz*' | sed 's/:.*//' | while read -r pkg; do # if a package cannot be downloaded, apt will still exit # successfully chroot "$MOUNTROOT" apt-get install --yes --reinstall "$pkg" done if [ -z "$(find "$MOUNTROOT/boot" -name 'vmlinuz-*')" ]; then echo "E: no kernel images were installed into /boot" >&2 exit 1 fi if [ "$MOUNTROOT" != "/" ]; then umount "$MOUNTROOT" --recursive else # if we are working on /, unmount /boot as that is required for reform-boot-config umount /boot fi reform-boot-config --emmc "$ROOTPART" trap - EXIT INT TERM } # eMMC device is being used (case 1): mount points are known, show them. Includes swap. if [ -n "$(lsblk --noheadings --output=MOUNTPOINT "/dev/${DEV_MMC}")" ]; then echo "E: eMMC has the following mounted volumes, unmount them before running this tool" >&2 lsblk --noheadings --output=MOUNTPOINT "/dev/${DEV_MMC}" | xargs --no-run-if-empty -I '{}' echo "E: {}" >&2 exit 1 fi # eMMC device is being used (case 2): there are not file systems directly mounted on the block device # but it is opened by consumers like device-mapper, raid or luks, to name some examples. In this situation # it is not trivial to locate the consumer. # reform-boot-config does the same thing (could share code?) get_exclusive_write_lock() { ret=0 python3 - "$1" <&2 exit 1 fi MOUNTROOT= disk_label=$(parted --json "/dev/${DEV_SSD}" print 2>/dev/null | jq --raw-output '.disk.label') case $disk_label in msdos | gpt) num_parts=$(parted --json "/dev/${DEV_SSD}" print 2>/dev/null | jq '.disk.partitions | length') DEV_SSD_BASE="$DEV_SSD" if [ "$DEV_SSD" != "sda" ]; then DEV_SSD_BASE="${DEV_SSD}p" fi case $num_parts in 1) echo "I: assuming root file system on /dev/${DEV_SSD_BASE}1" >&2 main "/dev/${DEV_SSD_BASE}1" ;; 2) # assume one partition to be swap and the other to be the rootfs part1type=$(lsblk --nodeps --noheadings --output=FSTYPE "/dev/${DEV_SSD_BASE}1") part2type=$(lsblk --nodeps --noheadings --output=FSTYPE "/dev/${DEV_SSD_BASE}2") case "${part1type}_${part2type}" in swap_ext4) echo "I: assuming root file system on /dev/${DEV_SSD_BASE}2" >&2 main "/dev/${DEV_SSD_BASE}2" ;; ext4_swap) echo "I: assuming root file system on /dev/${DEV_SSD_BASE}1" >&2 main "/dev/${DEV_SSD_BASE}1" ;; *) echo "E: no support for partitions other than one swap and one ext4" >&2 exit 1 ;; esac ;; *) echo "E: more than 2 partitions not implemented yet" >&2 exit 1 ;; esac ;; unknown) echo "I: no partition table found trying to open LUKS device" >&2 if ! is_current_root /dev/reformvg/root; then if [ "$(lsblk --nodeps --noheadings --output=FSTYPE "/dev/${DEV_SSD}")" != "crypto_LUKS" ]; then echo "W: SSD (/dev/${DEV_SSD}) does not look like a LUKS device" >&2 fi cryptsetup luksOpen "/dev/${DEV_SSD}" reform_crypt vgchange -ay reformvg fi main /dev/reformvg/root if ! is_current_root /dev/reformvg/root; then vgchange -an reformvg cryptsetup luksClose reform_crypt fi ;; *) ;; esac if [ "$EMMC_BOOT" != false ]; then reform-flash-uboot emmc fi reform-tools-1.71/bin/reform-flash-rescue000077500000000000000000000171341477621656200204670ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2022-2025 Johannes Schauer Marin Rodrigues # Copyright 2023 Lukas F. Hartmann set -eu usage() { echo "Download and flash the latest sysimage-v4 to eMMC." >&2 echo "Calls reform-flash-uboot to install u-boot on eMMC, grows the root" >&2 echo "filesystem and adjusts filesystem labels." >&2 echo "Calls reform-boot-config to set up /boot on eMMC to load the rootfs from eMMC." >&2 echo >&2 echo "Usage: $0 [--help] [--mirror={mntre.com,reform.debian.net}]" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 echo " --mirror=MIRROR Force MIRROR, either mntre.com (default) or reform.debian.net" >&2 } if [ "$#" -gt 1 ]; then echo "E: incorrect number of arguments" >&2 exit 1 fi if [ "$#" -gt 0 ] && [ "$1" = "--help" ]; then usage exit 0 fi MIRROR="mntre.com" if [ "$#" -gt 0 ]; then case $1 in --mirror=mntre.com) MIRROR="mntre.com" ;; --mirror=reform.debian.net) MIRROR="reform.debian.net" ;; *) echo "E: invalid argument for --mirror" >&2 exit 1 ;; esac fi # shellcheck source=/dev/null if [ -e "./machines/$(cat /proc/device-tree/model).conf" ]; then . "./machines/$(cat /proc/device-tree/model).conf" elif [ -e "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" ]; then . "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" else echo "E: unable to find config for $(cat /proc/device-tree/model)" >&2 exit 1 fi case $EMMC_USE in false) echo "E: writing to eMMC not supported on $(cat /proc/device-tree/model)" >&2 exit 1 ;; warn) echo "W: Using eMMC on $(cat /proc/device-tree/model) is not without risk." >&2 echo "W: For example, flashing the wrong u-boot or if the flashing process goes wrong, it is" >&2 echo "W: possible to soft-brick your board. Restoring it might need some extra hardware." >&2 echo "W: Please only proceed if you are sure that the benefits outweigh the risks for you." >&2 printf "Are you sure you want to proceed? [y/N] " read -r response if [ "$response" != "y" ]; then echo "Exiting." exit fi ;; esac if [ "$EMMC_BOOT" != false ]; then if [ "$EMMC_BOOT" = warn ]; then echo "W: Flashing u-boot to eMMC on $(cat /proc/device-tree/model) is not without risk." >&2 echo "W: If you flash the wrong u-boot or if the flashing process goes wrong, it is" >&2 echo "W: possible to soft-brick your board. Restoring it might need some extra hardware." >&2 echo "W: Please only proceed if you are sure that the benefits outweigh the risks for you." >&2 printf "Are you sure you want to proceed? [y/N] " read -r response if [ "$response" != "y" ]; then echo "Exiting." exit fi fi if [ ! -e "/sys/class/block/${DEV_MMC}boot0/force_ro" ]; then echo "/sys/class/block/${DEV_MMC}boot0/force_ro doesn't exist" >&2 exit 1 fi if [ ! -w "/sys/class/block/${DEV_MMC}boot0/force_ro" ]; then echo "/sys/class/block/${DEV_MMC}boot0/force_ro is not writable" >&2 exit 1 fi if [ ! -e /boot/flash.bin ]; then echo "/boot/flash.bin doesn't exist" >&2 exit 1 fi for p in $(lsblk --list --noheadings --output=NAME "/dev/$DEV_MMC") "${DEV_MMC}boot0" "${DEV_MMC}boot1"; do [ -b "/dev/$p" ] || continue if [ -n "$(lsblk --nodeps --noheadings --output=MOUNTPOINT "/dev/$p")" ]; then echo "/dev/$p is still in use" >&2 exit 1 fi done echo "WARNING: This overwrites the bootloader on the eMMC rescue disk with the" >&2 echo "backup stored as /boot/flash.bin!" >&2 printf "Are you sure you want to proceed? [y/N] " read -r response if [ "$response" != "y" ]; then echo "Exiting." exit fi reform-flash-uboot --offline emmc echo "Bootloader was successfully written to /dev/${DEV_MMC}boot0." >&2 echo "" >&2 fi echo "Do you want to download and install the latest sysimage-v4 to eMMC as well?" >&2 echo "This step needs a working internet connection and either wget or curl installed." >&2 echo "" >&2 echo "WARNING: This overwrites partitions on eMMC, deleting all data." >&2 printf "Are you sure you want to proceed? [y/N] " read -r response if [ "$response" != "y" ]; then echo "Exiting." exit fi if [ "$MIRROR" = "mntre.com" ]; then URL="https://source.mnt.re/reform/reform-system-image/-/jobs/artifacts/main/raw/${SYSIMAGE}.img.gz?job=build" DECOMPRESSOR=gzip if grep --silent '^URIs: https://reform.debian.net/debian/\?$' /etc/apt/sources.list.d/reform*.sources 2>/dev/null; then echo "The current system image is configured to use the Debian stable mirror from" >&2 echo "reform.debian.net. Do you want to flash the system image from reform.debian.net" >&2 echo 'to your eMMC? If you answer anything but "y", the official MNT system image will' >&2 echo "be downloaded and written to eMMC instead." >&2 printf "Do you want to download and use the rescue system image from reform.debian.net? [y/N] " read -r response if [ "$response" = "y" ]; then # no need to use the backports kernel because a311d is not # allowed to write to emmc anyways URL="https://reform.debian.net/images/${SYSIMAGE}.img.xz" DECOMPRESSOR=xz fi fi elif [ "$MIRROR" = "reform.debian.net" ]; then URL="https://reform.debian.net/images/${SYSIMAGE}.img.xz" DECOMPRESSOR=xz else echo "E: unsupported value for --mirror: $MIRROR" >&2 exit 1 fi echo "Downloading $URL..." # flash with bmaptool if available and use dd otherwise if command -v bmaptool >/dev/null 2>&1; then case $URL in https://reform.debian.net/images/*) # force gpg signature verification when downloading from reform.d.n bmaptool copy \ --fingerprint 3AC6EB840FA5CE3FF31BAD80EF93221F8A44FEB2 \ --keyring /usr/share/keyrings/debian-keyring.gpg \ "$URL" "/dev/$DEV_MMC" ;; *) bmaptool copy "$URL" "/dev/$DEV_MMC" ;; esac else { if curl --version >/dev/null; then curl --silent --location "$URL" elif wget --version >/dev/null; then wget --quiet --output-document=- "$URL" else echo "need curl or wget" >&2 exit 1 fi } | "$DECOMPRESSOR" --decompress --to-stdout | dd of="/dev/$DEV_MMC" status=progress fi partprobe "/dev/$DEV_MMC" # resize the second partition to fill the emmc parted --script --machine "/dev/$DEV_MMC" resizepart 2 100% partprobe "/dev/$DEV_MMC" sync # resize the filesystem e2fsck -fy "/dev/${DEV_MMC}p2" resize2fs -p "/dev/${DEV_MMC}p2" e2fsck -fy "/dev/${DEV_MMC}p2" # overwrite the partition label e2label "/dev/${DEV_MMC}p1" reformemmcboot e2label "/dev/${DEV_MMC}p2" reformemmcroot # The rescue system image that we downloaded and wrote to the eMMC above is # configured to use the rootfs on the SD-Card but we want the initramfs on eMMC # to boot the rootfs on eMMC and not the rootfs from SD-Card. Use # reform-boot-config to update the /etc/fstab and initramfs to use the eMMC # # We use --no-copy-old-boot because by flashing the system image, the new /boot # partition already has the correct contents and we don't want to use the /boot # partition of the current system as that one might be wildly different. reform-boot-config --no-copy-old-boot --emmc emmc case "$(cat /proc/device-tree/model)" in "MNT Reform 2" | "MNT Reform 2 HDMI") echo "If the SoM dip switch is turned off and no SD-Card is present, your" >&2 echo "system will now boot from eMMC and load the rootfs from there as well." >&2 echo "If you want to boot from eMMC but load the rootfs from elsewhere, run" >&2 echo "reform-boot-config with the --emmc switch." >&2 ;; esac reform-tools-1.71/bin/reform-flash-uboot000077500000000000000000000203501477621656200203230ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2023-2025 Johannes Schauer Marin Rodrigues set -eu usage() { echo "Usage: " >&2 echo " reform-flash-uboot [--offline] [--force] [DEVICE...]" >&2 echo >&2 echo "Download and flash u-boot for the current platform to DEVICE. Unless" >&2 echo "the --offline option is given, download latest u-boot to /boot/flash.bin." >&2 echo "If one or more DEVICE is given, flash /boot/flash.bin with the correct" >&2 echo "offset to DEVICE. The short-hands 'sd' and 'emmc' can be used to flash" >&2 echo "u-boot to the SD-card or eMMC, respectively." >&2 echo >&2 echo "Options:" >&2 echo " DEVICE Block device to flash or short-hands 'sd' or 'emmc'" >&2 echo " -h, --help Display this help and exit." >&2 echo " -i, --image Custom image (default: /boot/flash.bin). Implies --offline." >&2 echo " --offline Do not download latest u-boot to /boot/flash.bin." >&2 echo " -f, --force No user interaction and flash to devices marked as 'warn'" >&2 echo "" >&2 } nth_arg() { shift "$1" printf "%s" "$1" } OFFLINE= FORCE= IMAGE= while getopts :hfi:-: OPTCHAR; do case "$OPTCHAR" in h) usage exit 0 ;; f) FORCE=yes ;; i) IMAGE="$OPTARG" ;; -) case "$OPTARG" in help) usage exit 0 ;; force) FORCE=yes ;; image) if [ "$OPTIND" -gt "$#" ]; then echo "E: missing argument for --image" >&2 exit 1 fi IMAGE="$(nth_arg "$OPTIND" "$@")" OPTIND=$((OPTIND + 1)) OFFLINE=yes ;; image=*) IMAGE="${OPTARG#*=}" OFFLINE=yes ;; offline) OFFLINE=yes ;; *) echo "E: unrecognized option: --$OPTARG" >&2 exit 1 ;; esac ;; ':') echo "E: missing argument for -$OPTARG" >&2 exit 1 ;; '?') echo "E: unrecognized option -$OPTARG" >&2 exit 1 ;; *) echo "E: error parsing options" >&2 exit 1 ;; esac done shift "$((OPTIND - 1))" if [ "$(id -u)" -ne 0 ]; then echo "reform-flash-uboot has to be run as root / using sudo." exit 1 fi # shellcheck source=/dev/null if [ -e "./machines/$(cat /proc/device-tree/model).conf" ]; then . "./machines/$(cat /proc/device-tree/model).conf" elif [ -e "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" ]; then . "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" else echo "E: unable to find config for $(cat /proc/device-tree/model)" >&2 exit 1 fi for dev in "$@"; do case $dev in emmc | "/dev/${DEV_MMC}"*) if [ "$EMMC_BOOT" = false ]; then echo "E: writing uboot to eMMC not supported on $(cat /proc/device-tree/model)" >&2 exit 1 fi ;; sd | "/dev/${DEV_SD}"*) if [ "$SD_BOOT" = false ]; then echo "E: writing uboot to SD-Card not supported on $(cat /proc/device-tree/model)" >&2 exit 1 fi ;; esac done if [ "$OFFLINE" != "yes" ]; then if echo "$UBOOT_SHA1 /boot/flash.bin" | sha1sum --strict --check >/dev/null 2>&1; then echo "/boot/flash.bin is up-to-date -- not downloading it again" >&2 else echo "Downloading uboot to /boot/flash.bin and comparing checksum" >&2 ubooturl="https://source.mnt.re/reform/${UBOOT_PROJECT}/-/jobs/artifacts/${UBOOT_TAG}/raw/$(basename "$DTBPATH" .dtb)-flash.bin?job=build" /usr/lib/apt/apt-helper -oAPT::Sandbox::User=root download-file "$ubooturl" "/boot/flash.bin" "SHA1:$UBOOT_SHA1" fi # download mhdpfw.bin on ls1028a case "$(cat /proc/device-tree/model)" in "MNT Reform 2 with LS1028A Module") if echo "fa96b9aa59d7c1e9e6ee1c0375d0bcc8f8e5b78c /boot/ls1028a-mhdpfw.bin"; then echo "/boot/ls1028a-mhdpfw.bin is up-to-date -- not downloading it again" >&2 else echo "Downloading LS1028A MHDP firmware to /boot/ls1028a-mhdpfw.bin and comparing checksum" >&2 /usr/lib/apt/apt-helper -oAPT::Sandbox::User=root download-file \ "https://source.mnt.re/reform/reform-ls1028a-uboot/-/raw/main/ls1028a-mhdpfw.bin" \ "/boot/ls1028a-mhdpfw.bin" \ "SHA1:fa96b9aa59d7c1e9e6ee1c0375d0bcc8f8e5b78c" fi ;; esac fi if [ "$#" -eq 0 ]; then echo "No device unto which to flash uboot provided. Exiting." >&2 exit 0 fi if [ -z "$IMAGE" ]; then if ! echo "$UBOOT_SHA1 /boot/flash.bin" | sha1sum --strict --check >/dev/null 2>&1; then echo "Incorrect checksum for /boot/flash.bin" >&2 echo "Either flash a custom image with --image, or run without --offline to download the latest uboot version" >&2 exit 1 fi IMAGE="/boot/flash.bin" fi if [ ! -e "$IMAGE" ]; then echo "E: $IMAGE does not exist" >&2 exit 1 fi ubootsize=$(stat --format=%s "$IMAGE") # check if there is enough free space at the beginning of the disk for dev in "$@"; do case $dev in emmc | "/dev/${DEV_MMC}"*) if [ "$DEV_MMC_BOOT0" = true ]; then # there are no partitions on boot0, so no need to check here continue else realdev=/dev/${DEV_MMC} fi ;; sd) realdev=/dev/${DEV_SD} ;; *) realdev="$dev" ;; esac disk_label=$(parted --json --script "$realdev" unit B print 2>/dev/null | jq --raw-output '.disk.label') # no further tests for disks without a partition table if [ "$disk_label" = "unknown" ]; then echo "I: no partition table found on $realdev" >&2 continue fi num_parts=$(parted --json --script "$realdev" unit B print | jq --raw-output '.disk.partitions | length') if [ "$num_parts" -eq 0 ]; then echo "I: no partition was found on $realdev" >&2 continue fi firstpartstart=$(parted --json --script "$realdev" unit B print | jq --raw-output '.disk.partitions[0].start') # strip off trailing B firstpartstart=${firstpartstart%B} if [ "$((UBOOT_OFFSET - FLASHBIN_OFFSET + ubootsize))" -ge "$firstpartstart" ]; then echo "the first partition on $realdev starts at $firstpartstart and would be overwritten by uboot" >&2 echo "make sure that the first $((UBOOT_OFFSET - FLASHBIN_OFFSET + ubootsize)) bytes are free on $realdev" >&2 exit 1 fi done if [ "$EMMC_BOOT" = warn ] && [ "$FORCE" != "yes" ]; then for dev in "$@"; do case $dev in emmc | "/dev/${DEV_MMC}"*) echo "W: Flashing u-boot to eMMC on $(cat /proc/device-tree/model) is not without risk." >&2 echo "W: If you flash the wrong u-boot or if the flashing process goes wrong, it is" >&2 echo "W: possible to soft-brick your board. Restoring it might need some extra hardware." >&2 echo "W: Please only proceed if you are sure that the benefits outweigh the risks for you." >&2 printf "Are you sure you want to proceed? [y/N] " read -r response if [ "$response" != "y" ]; then echo "Exiting." exit fi break ;; esac done fi # do the flashing for dev in "$@"; do case $dev in emmc | "/dev/${DEV_MMC}"*) if [ "$DEV_MMC_BOOT0" = true ]; then realdev=/dev/${DEV_MMC}boot0 else realdev=/dev/${DEV_MMC} fi ;; sd) realdev=/dev/${DEV_SD} ;; *) realdev="$dev" ;; esac echo "Writing $IMAGE to $realdev" >&2 case $dev in emmc | "/dev/${DEV_MMC}"*) if [ "$DEV_MMC_BOOT0" = true ]; then echo 0 >"/sys/class/block/${DEV_MMC}boot0/force_ro" fi ;; esac dd if="$IMAGE" of="$realdev" bs=512 seek="$((UBOOT_OFFSET / 512))" skip="$((FLASHBIN_OFFSET / 512))" case $dev in emmc | "/dev/${DEV_MMC}"*) if [ "$DEV_MMC_BOOT0" = true ]; then echo 1 >"/sys/class/block/${DEV_MMC}boot0/force_ro" fi ;; esac done # inform about the DIP switch position only on imx8mq case "$(cat /proc/device-tree/model)" in "MNT Reform 2" | "MNT Reform 2 HDMI") for dev in "$@"; do case $dev in emmc | "/dev/${DEV_MMC}"*) echo "For the i.MX8MQ to load u-boot from MMC, make sure" >&2 echo "that your DIP switch is set to OFF." >&2 continue ;; sd | "/dev/${DEV_SD}"*) echo "For the i.MX8MQ to load u-boot from SD-Card, make sure" >&2 echo "that your DIP switch is set to ON." >&2 continue ;; esac done ;; esac reform-tools-1.71/bin/reform-handbook000077500000000000000000000012711477621656200176660ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2023 Lukas F. Hartmann # Copyright 2024 Johannes Schauer Marin Rodrigues set -eu usage() { echo "Open the MNT Reform handbook in a browser" >&2 echo >&2 echo "Usage: $0 [--help]" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 } if [ $# -gt 0 ]; then if [ "$1" != "--help" ]; then echo "E: too many arguments" >&2 usage exit 1 fi usage exit 0 fi if [ -z ${DISPLAY+x} ]; then # not running under X/wayland set -- elinks else set -- xdg-open fi set -- "$@" /usr/share/doc/reform-handbook/html/index.html exec "$@" reform-tools-1.71/bin/reform-help000077500000000000000000000124701477621656200170340ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2020-2022 Lukas F. Hartmann # Copyright 2022-2025 Johannes Schauer Marin Rodrigues set -eu usage() { echo "Prints help text for how to use the MNT Reform." >&2 echo >&2 echo "Usage: $0 [--desktop,--root]" >&2 echo >&2 echo "Options:" >&2 echo " --desktop Print the MNT Reform desktop help text." >&2 echo " --root Print the MNT Reform root shell help text." >&2 } reform_help() { cat <<'END' Some useful commands to explore the system: Learn more about a command: man name-of-command Move around: ls, cd, cd .. Start a graphical environment: wayfire (overlapping windows, traditional) sway (tiling windows, advanced) See all running processes: htop See system services: systemctl Analyze disk usage: ncdu / List hardware/peripherals: lsblk lsusb lspci ip a View this message again: reform-help END case "$(cat /proc/device-tree/model)" in "MNT Pocket Reform with "*) cat <<'END' Read the Operator Handbook: pocket-reform-handbook (press % to fix contrast, Q to quit) END ;; *) cat <<'END' Read the Operator Handbook: reform-handbook (press % to fix contrast, Q to quit) END ;; esac cat <<'END' Set keyboard layout and timezone: sudo reform-config Chat in Reform community: reform-chat Select boot device: sudo reform-boot-config END case "$(cat /proc/device-tree/model)" in "MNT Reform 2" | "MNT Reform 2 HDMI") cat <<'END' Select display configuration: sudo reform-display-config # imx8mq only END ;; esac cat <<'END' Set up full disk encryption: sudo reform-setup-encrypted-disk Migrate system to a partition: sudo reform-migrate Flash latest u-boot: sudo reform-flash-uboot Re-initialize eMMC from scratch sudo reform-emmc-bootstrap Flash rescue system to eMMC sudo reform-flash-rescue Update / install software: sudo apt update apt search keyword sudo apt install package View a text file: less filename Edit a text file: micro filename Log out: exit Most programs can be quit with Ctrl+C, Q, or Ctrl+Q. Exit the chat with /quit. END } reform_root_help() { cat <<'END' You are logged in as root. This account can change anything in the system. To use the graphical environment sway, create a normal user account by entering: adduser your-name Afterwards, to be able to become root by using sudo, enter: adduser your-name sudo Then, log out using exit and log in as your-name. To read the MNT Reform Operator Handbook, enter: END case "$(cat /proc/device-tree/model)" in "MNT Pocket Reform with "*) cat <<'END' pocket-reform-handbook # (in the browser, press % # to fix contrast, Q to quit) END ;; *) cat <<'END' reform-handbook # (in the browser, press % # to fix contrast, Q to quit) END ;; esac } reform_desktop_help() { cat /etc/motd cat <<'END' Welcome to the MNT Reform desktop. Useful keyboard shortcuts (SUPER is the MNT logo key): SUPER ENTER Open a terminal SUPER ESC Close active window SUPER D Find and launch programs SUPER F1 Decrease backlight brightness SUPER F2 Decrease backlight brightness SUPER SHIFT S Take screenshot (in ~/Pictures) SUPER SHIFT X Take screenshot of an area SUPER 1 … Go to workspace 1 - 9 SUPER 9 To move the active window to a workspace, press the same combination, but together with SHIFT. Only on wayfire: SUPER ←/→ Tile window to left or right SUPER ↑/↓ (Un)maximize window SUPER TAB Overview of all windows ALT TAB Cycle through windows Customize the sway or wayfire configuration: micro ~/.config/sway/config micro ~/.config/wayfire/config To learn more about the command line, enter: reform-help END case "$(cat /proc/device-tree/model)" in "MNT Pocket Reform with "*) cat <<'END' Read the MNT Pocket Reform handbook in a browser: pocket-reform-handbook END ;; *) cat <<'END' Read the MNT Reform handbook in a browser: reform-handbook END ;; esac echo reform_help } if [ "$#" -eq "0" ]; then reform_help exit elif [ "$#" -gt "1" ]; then echo "too many arguments" >&2 usage exit 1 fi case "$1" in --help) usage ;; --desktop) reform_desktop_help ;; --root) reform_root_help ;; *) echo "unknown option: $1" >&2 usage exit 1 ;; esac reform-tools-1.71/bin/reform-hw-setup000077500000000000000000000141621477621656200176600ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2021-2024 Lukas F. Hartmann # Copyright 2022-2025 Johannes Schauer Marin Rodrigues set -eu usage() { echo "Hardware setup specific to your MNT Reform platform." >&2 echo "Usually run by /lib/systemd/system/reform-hw-setup.service" >&2 echo >&2 echo "Usage: $0 [--help]" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 } if [ "$#" -gt 0 ]; then if [ "$1" != "--help" ]; then echo "E: too many arguments" >&2 usage exit 1 fi usage exit 0 fi if [ "$(id -u)" -ne 0 ]; then echo "reform-hw-setup has to be run as root / using sudo and is usually run by /lib/systemd/system/reform-hw-setup.service" >&2 exit 1 fi init_a311d() { # A311D sound controls # without setting these, there is no UCM profile and messages like this are produced: # no backend DAIs enabled for fe.dai-link-0, possibly missing ALSA mixer-based routing or UCM profile amixer -c 0 sset 'FRDDR_A SINK 1 SEL' 'OUT 1' amixer -c 0 sset 'FRDDR_A SRC 1 EN' 'on' amixer -c 0 sset 'TDMOUT_B SRC SEL' 'IN 0' amixer -c 0 sset 'TDMIN_B SRC SEL' 'IN 1' amixer -c 0 sset 'TODDR_A SRC SEL' 'IN 1' # Workaround for ethernet PHY reset problem for m in dwmac_meson8b dwmac_generic stmmac_platform stmmac mdio_mux_meson_g12a mdio_mux pcs_xpcs mdio_devres of_mdio; do grep --quiet "^$m " /proc/modules || continue rmmod "$m" done sleep 0.5 modprobe mdio_mux_meson_g12a modprobe dwmac_meson8b # Workaround for SDIO wifi not loading echo ffe03000.mmc >/sys/class/mmc_host/mmc2/device/driver/unbind echo ffe03000.mmc >/sys/bus/platform/drivers/meson-gx-mmc/bind } init_rk3588() { # shellcheck disable=SC2043 for m in dwmac_rk; do grep --quiet "^$m " /proc/modules || continue rmmod "$m" done # manual ethernet phy reset gpioset -c 3 -t 100ms,100ms,0ms 23=1 \ || echo "E: gpioset for phy reset failed (requires gpiod >= 2.0)" >&2 sleep 0.5 modprobe dwmac_rk } init_wm8960() { # Fix WM8960 being too quiet amixer -c 0 sset Playback 255 amixer -c 0 sset 'Left Output Mixer PCM' on amixer -c 0 sset 'Right Output Mixer PCM' on # This switch in WM8960 needs to be on for the headset mic input to work amixer -c 0 sset 'Left Input Mixer Boost' on } init_tlv320aic3100() { # Set up speaker on MNT Pocket Reform amixer -c 0 sset 'Speaker Driver' on amixer -c 0 sset 'Output Left From Left DAC' on amixer -c 0 sset 'Output Right From Right DAC' on amixer -c 0 sset 'Speaker Analog' 127 amixer -c 0 sset 'DAC' 127 amixer -c 0 sset 'HP Analog' 127 amixer -c 0 sset 'HP Driver' on amixer -c 0 sset 'HP Left' on amixer -c 0 sset 'HP Right' on } init_qca9377_wifi() { if test -e /proc/modules && grep --quiet '^qcacld2 ' /proc/modules; then echo "I: Module qcacld2 is already loaded" >&2 return 0 fi # load out-of-tree Wi-Fi driver KERNVER_EXACT=$(dpkg-query --show --showformat '${Version}' "linux-image-$(uname -r)") modprobe cfg80211 # without "-f", insmod will fail with "Invalid module format" even though # the kernel version matches echo "I: Try to load exact match wifi driver: ${KERNVER_EXACT}" >&2 if [ -f "/opt/reform-qcacld2/qcacld2-${KERNVER_EXACT}.ko" ]; then echo "I: Found exact match for kernel ${KERNVER_EXACT}" >&2 if insmod -f "/opt/reform-qcacld2/qcacld2-${KERNVER_EXACT}.ko"; then echo "I: Successfully loaded exact match driver" >&2 return 0 else echo "W: Failed to load exact match driver. Try other available driver" >&2 fi fi # Find other potential qcacld2 drivers potential_drivers=$(find /opt/reform-qcacld2/qcacld2-*.ko -maxdepth 1 -type f -print0 | sort -Vzr) # Try to load available drivers, starting with the highest version number, until one works for driver in $potential_drivers; do echo "I: Attempting to load wifi driver: $driver" >&2 if insmod -f "$driver"; then echo "I: Successfully loaded driver: $driver" >&2 return 0 else echo "W: Failed to load driver: $driver, trying next" >&2 fi done echo "E: Failed to load any compatible qcacld2 driver" >&2 return 1 } case "$(cat /proc/device-tree/model)" in "MNT Reform 2" | "MNT Reform 2 HDMI") # Workaround for WM8960 sometimes not coming out of reset if [ ! -e /sys/bus/i2c/drivers/wm8960/2-001a ]; then echo 2-001a >/sys/bus/i2c/drivers/wm8960/bind fi test -e /sys/bus/i2c/drivers/wm8960/2-001a init_wm8960 ;; "MNT Reform 2 with BPI-CM4 Module") # Workaround for WM8960 sometimes not coming out of reset if [ ! -e /sys/bus/i2c/drivers/wm8960/1-001a ]; then echo 1-001a >/sys/bus/i2c/drivers/wm8960/bind fi test -e /sys/bus/i2c/drivers/wm8960/1-001a init_a311d init_wm8960 ;; "MNT Reform 2 with LS1028A Module") # Workaround for a DWC3 USB Controller regression # Assert USB hub reset gpioset 2 13=0 # Reload DWC3 module rmmod dwc3 modprobe dwc3 # Deassert USB hub reset gpioset 2 13=1 # Select "ondemand" CPU frequency scaling governor echo ondemand >/sys/devices/system/cpu/cpufreq/policy0/scaling_governor # the functionality of the dwc3 module depends on the loglevel # loglevel=3 makes usb not work # loglevel=7 makes usb work most of the time # https://community.mnt.re/t/no-keyboard-input-with-ls1028-board-and-latest-image/1994/13 dmesg -n 7 ;; "MNT Pocket Reform with i.MX8MP Module") init_qca9377_wifi || echo "W: init_qca9377_wifi failed" >&2 init_tlv320aic3100 ;; "MNT Pocket Reform with BPI-CM4 Module") init_a311d init_tlv320aic3100 ;; "MNT Reform 2 with i.MX8MP Module") init_wm8960 init_qca9377_wifi || echo "W: init_qca9377_wifi failed" >&2 ;; "MNT Reform 2 with RCORE RK3588 Module") init_rk3588 init_wm8960 ;; "MNT Pocket Reform with RCORE RK3588 Module") init_rk3588 init_tlv320aic3100 ;; "MNT Reform Next with RCORE RK3588 Module") init_rk3588 init_tlv320aic3100 ;; *) echo "E: Your platform $(cat /proc/device-tree/model) is not supported by reform-tools" >&2 exit 1 ;; esac reform-tools-1.71/bin/reform-mcu-tool000077500000000000000000000175621477621656200176520ustar00rootroot00000000000000#!/usr/bin/python3 # Copyright 2024 Chris Hofstaedtler # SPDX-License-Identifier: GPL-3.0+ # # Use `black --line-length 120 bin/reform-mcu-tool` to reformat. # # Installation # # Install `python3-usb1` as a pre-requisite. No other dependencies should be necessary. # # Do not run shellcheck on this file # shellcheck disable=SC1071 _DOC = """ Tool to interact with Microcontrollers used by MNT Research in Reform projects. It can currently talk to the pocket sysctl firmware, and to the RP2040 bootrom. """ _EPILOG = """ Example usage: To reboot the pocket sysctl into the bootrom: $ sudo reform-mcu-tool bootsel pocket-sysctl-1.0 To reset the RP2040 bootrom back into the application: $ sudo reform-mcu-tool reset rp2040-boot """ import argparse import struct import sys try: import usb1 except ModuleNotFoundError as except_inst: raise RuntimeError('Library "usb1" not found, please install python3-usb1') from except_inst USB_VID_PIDCODES = 0x1209 USB_VID_RASPBERRY = 0x2E8A USB_PID_MNT_POCKET_REFORM_INPUT_10 = 0x6D06 USB_PID_MNT_POCKET_REFORM_SYSCTL_10 = 0x6D07 USB_PID_RASPBERRY_RP2040_BOOT = 0x0003 USB_PID_RASPBERRY_RP2350_BOOT = 0x000F IS_APP = 0b0000_0001 IS_RP_BOOTROM = 0b0000_0010 MCU_TYPES = { "pocket-input-1.0": (USB_VID_PIDCODES, USB_PID_MNT_POCKET_REFORM_INPUT_10, IS_APP), "pocket-sysctl-1.0": (USB_VID_PIDCODES, USB_PID_MNT_POCKET_REFORM_SYSCTL_10, IS_APP), "rp2040-boot": (USB_VID_RASPBERRY, USB_PID_RASPBERRY_RP2040_BOOT, IS_RP_BOOTROM), "rp2350-boot": (USB_VID_RASPBERRY, USB_PID_RASPBERRY_RP2350_BOOT, IS_RP_BOOTROM), } RESET_INTERFACE_SUBCLASS = 0 RESET_INTERFACE_PROTOCOL = 1 RESET_REQUEST_BOOTSEL = 1 RESET_REQUEST_FLASH = 2 PICOBOOT_MAGIC = 0x431FD10B PC_REBOOT = 0x2 PICOBOOT_IF_RESET = 0x41 def device_reset(handle: usb1.USBDeviceHandle, reset_interface: int, reset_request: int): handle.claimInterface(reset_interface) try: handle.controlWrite( usb1.TYPE_CLASS | usb1.RECIPIENT_INTERFACE, reset_request, 0, reset_interface, b"", timeout=2000 ) except (usb1.USBErrorIO, usb1.USBErrorPipe): pass # Expected. MCU has reset and vanishes from USB. Exact error appears to be timing/fw-dependent. else: handle.releaseInterface(reset_interface) def picoboot_reset(handle: usb1.USBDeviceHandle, picoboot_interface: usb1.USBInterfaceSetting): handle.claimInterface(picoboot_interface.getNumber()) out_address = picoboot_interface[0].getAddress() handle.clearHalt(out_address) in_address = picoboot_interface[1].getAddress() handle.clearHalt(in_address) pc = 0 sp = 0 delay_ms = 500 reboot_cmd = struct.pack(" int | None: for setting in device.iterSettings(): if ( setting.getClass() == 0xFF and setting.getSubClass() == RESET_INTERFACE_SUBCLASS and setting.getProtocol() == RESET_INTERFACE_PROTOCOL and setting.getNumEndpoints() == 0 ): return setting.getNumber() return None def find_picoboot_interface(device: usb1.USBDevice) -> usb1.USBInterfaceSetting | None: for setting in device.iterSettings(): out_address = setting[0].getAddress() in_address = setting[1].getAddress() if ( setting.getClass() == 0xFF and setting.getNumEndpoints() == 2 and out_address & 0x80 == 0 and in_address & 0x80 == 0x80 ): return setting return None def action_bootsel(args, device: usb1.USBDevice): target_flags = MCU_TYPES[args.target][2] if target_flags & IS_RP_BOOTROM: print("E: Device is already in bootrom.") return 2 if (reset_interface := find_reset_interface(device)) is None: print("E: Could not find Reset USB Interface.") return 1 serial_number = device.getSerialNumber() print(f"I: Resetting device with serial {serial_number} into BOOTSEL") handle = device.open() device_reset(handle, reset_interface, RESET_REQUEST_BOOTSEL) print(f"I: You may now use: $ picotool info --ser {serial_number}") return 0 def action_reset(args, device: usb1.USBDevice): target_flags = MCU_TYPES[args.target][2] if target_flags & IS_APP: if (reset_interface := find_reset_interface(device)) is None: print("E: Could not find Reset USB Interface.") return 1 print(f"I: Resetting device") handle = device.open() device_reset(handle, reset_interface, RESET_REQUEST_FLASH) elif target_flags & IS_RP_BOOTROM: if (reset_interface := find_picoboot_interface(device)) is None: print("E: Could not find PICOBOOT USB Interface.") return 1 print(f"I: Resetting bootrom into application") handle = device.open() picoboot_reset(handle, reset_interface) return 0 def action_list(args, usb_context: usb1.USBContext): for device in usb_context.getDeviceIterator(skip_on_error=True): vid = device.getVendorID() pid = device.getProductID() for mcu_name, (mcu_vid, mcu_pid, flags) in MCU_TYPES.items(): if (vid, pid) == (mcu_vid, mcu_pid): print( f"Target {mcu_name} ID {vid:04x}:{pid:04x} Serial# {device.getSerialNumber()} " f"USB bus {device.getBusNumber()} address {device.getDeviceAddress()}" ) break return 0 def parse_args(): parser = argparse.ArgumentParser( prog="reform-mcu-tool", description=_DOC, epilog=_EPILOG, formatter_class=argparse.RawTextHelpFormatter ) subparsers = parser.add_subparsers(help="Action to execute") parser_bootsel = subparsers.add_parser("bootsel", help="Reboot MCU into BOOTSEL mode") parser_bootsel.set_defaults(func=action_bootsel) parser_bootsel.add_argument( "target", choices=MCU_TYPES.keys(), metavar="TARGET", help=f"Target device to operate on. Choices: {', '.join(MCU_TYPES.keys())}", ) parser_reset = subparsers.add_parser("reset", help="Reboot MCU into application mode") parser_reset.set_defaults(func=action_reset) parser_reset.add_argument( "target", choices=MCU_TYPES.keys(), metavar="TARGET", help=f"Target device to operate on. Choices: {', '.join(MCU_TYPES.keys())}", ) parser_list = subparsers.add_parser("list", help="List USB devices matching known VID/PIDs") parser_list.set_defaults(func=action_list) args = parser.parse_args() if "func" not in args: parser.print_help() parser.exit() return args def run(args, usb_context: usb1.USBContext) -> int: if "target" in args: (vid, pid, _) = MCU_TYPES[args.target] device = usb_context.getByVendorIDAndProductID(vid, pid, skip_on_error=True) if not device: print(f"E: USB device with Vendor-ID {vid} Product-ID {pid} not found.") return 1 print( f"I: Found {device.getManufacturer()} {device.getProduct()} " f"on bus {device.getBusNumber()} address {device.getDeviceAddress()}" ) return args.func(args, device) else: return args.func(args, usb_context) def main() -> int: args = parse_args() with usb1.USBContext() as usb_context: return run(args, usb_context) if __name__ == "__main__": sys.exit(main()) reform-tools-1.71/bin/reform-migrate000077500000000000000000000145121477621656200175330ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2021-2023 Lukas F. Hartmann # Copyright 2022-2024 Johannes Schauer Marin Rodrigues set -eu usage() { echo "Usage:" >&2 echo " reform-migrate [--emmc] TARGET" >&2 echo "" >&2 echo "Mounts TARGET and copies the currently running system to it using rsync. This will" >&2 echo "overwrite all existing files in TARGET. At the end, reform-boot-config is run and" >&2 echo "will set up the first partition of the SD-card or eMMC (depending on the --emmc" >&2 echo "option) to load your newly copied rootfs and adjust /etc/fstab of TARGET accordingly." >&2 echo "" >&2 echo "Options:" >&2 echo "" >&2 echo " -h, --help Show this help message and exit." >&2 echo " --emmc Record boot preference on eMMC instead of SD card." >&2 echo >&2 echo "This script does not set up partitions for you. If you would like to configure" >&2 echo "full disk encryption and set up partitions accordingly automatically, consider" >&2 echo "using the reform-setup-encrypted-disk tool instead of reform-migrate." >&2 echo "" >&2 echo "Examples:" >&2 echo "" >&2 echo " reform-migrate --emmc /dev/nvme0n1p1" >&2 echo " Mounts the first partition of an NVMe disk and mirrors your system to it." >&2 echo " Configures booting from the first partition on eMMC." >&2 echo "" >&2 echo " reform-migrate /dev/mapper/crypt" >&2 echo " Mounts encrypted disk 'crypt' and mirrors your system to it." >&2 echo " The disk has to be unlocked first with: cryptsetup luksOpen /dev/nvme0n1p1 crypt" >&2 echo " Configures booting from the first partition on the SD-card as --emmc option is missing." >&2 } EMMC="" while getopts :h-: OPTCHAR; do case "$OPTCHAR" in h) usage exit 0 ;; -) case "$OPTARG" in help) usage exit 0 ;; emmc) EMMC="--emmc" ;; *) echo "E: unrecognized option: --$OPTARG" >&2 exit 1 ;; esac ;; :) echo "E: missing argument for -$OPTARG" >&2 exit 1 ;; '?') echo "E: unrecognized option -$OPTARG" >&2 exit 1 ;; *) echo "E: error parsing options" >&2 exit 1 ;; esac done shift "$((OPTIND - 1))" if [ "$#" -eq 1 ]; then TARGET="$1" else echo "E: invalid number of arguments" >&2 usage exit 1 fi # shellcheck source=/dev/null if [ -e "./machines/$(cat /proc/device-tree/model).conf" ]; then . "./machines/$(cat /proc/device-tree/model).conf" elif [ -e "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" ]; then . "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" else echo "E: unable to find config for $(cat /proc/device-tree/model)" >&2 exit 1 fi if [ -n "$EMMC" ]; then case $EMMC_USE in false) echo "E: writing to eMMC not supported on $(cat /proc/device-tree/model)" >&2 exit 1 ;; warn) echo "W: Using eMMC on $(cat /proc/device-tree/model) is not without risk." >&2 echo "W: For example, flashing the wrong u-boot or if the flashing process goes wrong, it is" >&2 echo "W: possible to soft-brick your board. Restoring it might need some extra hardware." >&2 echo "W: Please only proceed if you are sure that the benefits outweigh the risks for you." >&2 printf "Are you sure you want to proceed? [y/N] " read -r response if [ "$response" != "y" ]; then echo "Exiting." exit fi ;; esac fi BOOTPART="${DEV_SD}p1" HUMAN_BOOT="SD-card" if [ -n "$EMMC" ]; then BOOTPART="${DEV_MMC}p1" HUMAN_BOOT="eMMC" fi if [ ! -e "$TARGET" ]; then echo "Error: The partition $TARGET does not exist." exit fi if [ -n "$(lsblk --noheadings --output=MOUNTPOINT "$TARGET")" ]; then echo "$TARGET is still in use" >&2 exit 1 fi if [ ! -e "/dev/$BOOTPART" ]; then echo "/dev/$BOOTPART does not exist" >&2 exit 1 fi if [ ! -b "/dev/$BOOTPART" ]; then echo "/dev/$BOOTPART is not a block device" >&2 exit 1 fi # check if the new boot is still mounted somewhere MOUNT_BOOT="$(lsblk --noheadings --output=MOUNTPOINT "/dev/$BOOTPART")" if [ -n "$MOUNT_BOOT" ]; then echo "E: /dev/$BOOTPART ($HUMAN_BOOT) is still mounted on $MOUNT_BOOT." >&2 echo "Please unmount before running this script" >&2 exit 1 fi if [ "$(id -u)" -ne 0 ]; then echo "reform-boot-config has to be run as root / using sudo." >&2 exit 1 fi echo "" echo "This script can copy your current OS and files to a different disk, such as an SSD installed in MNT Reform." echo "" echo "Warning: This will overwrite files on the target partition. Make sure you know what you're doing!" echo "" echo "Before using this script, your target partition has to be formatted. You can use the gnome-disks program for that." echo "gnome-disks can also help you set up an encrypted disk. You can also run the following commands for one single" echo "partition on NVMe:" echo "" echo ' parted /dev/nvme0n1 "mklabel msdos"' echo ' parted /dev/nvme0n1 "mkpart primary ext4 4MiB -1"' echo " mkfs.ext4 /dev/nvme0n1p1" echo "" echo "You can also setup full disk encryption by running reform-setup-encrypted-disk" echo "" # FIXME: mkimage.sh in reform-system-image could write out the exact values into a known location echo "Running rsync to copy approximately 3G of data in about 210k files..." >&2 command -v "rsync" >/dev/null 2>&1 || { echo >&2 'Please install "rsync" using: apt install rsync' exit 1 } echo "Trying to mount $TARGET... (if this fails, format the disk/partition as explained above)" MOUNTPOINT="$(mktemp --tmpdir --directory reform-migrate.XXXXXXXXXX)" trap 'umount $MOUNTPOINT' EXIT INT TERM mount "$TARGET" "$MOUNTPOINT" echo "Target partition successfully mounted. The next step will copy all your files over to the target, overwriting existing files in the process." echo "" printf "Are you sure you want to proceed? [y/N] " read -r response if [ "$response" != "y" ]; then echo "Exiting." umount "$MOUNTPOINT" trap - EXIT INT TERM exit fi echo "Starting the copy. This can take a while." rsync -axHAWXS --numeric-ids --info=progress2 / "$MOUNTPOINT" echo "Files copied." umount "$MOUNTPOINT" trap - EXIT INT TERM echo "$TARGET unmounted." echo "Running reform-boot-config..." reform-boot-config $EMMC "$TARGET" reform-tools-1.71/bin/reform-pavucontrol000077500000000000000000000011031477621656200204470ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2020-2022 Lukas F. Hartmann # Copyright 2022-2025 Johannes Schauer Marin Rodrigues set -eu usage() { echo "Kill any pavucontrol process and re-exec it." >&2 echo >&2 echo "Usage: $0 [--help]" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 } if [ "$#" -gt 0 ]; then if [ "$1" != "--help" ]; then echo "E: too many arguments" >&2 usage exit 1 fi usage exit 0 fi pkill 'pavucontrol$' exec pavucontrol reform-tools-1.71/bin/reform-setup-encrypted-disk000077500000000000000000000300161477621656200221630ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2022-2025 Johannes Schauer Marin Rodrigues set -eu usage() { echo "Set up a disk with LUKS encryption containing LVM2 volumes for" >&2 echo "swap and the rootfs. Offers to run reform-migrate and " >&2 echo "reform-boot-config to set up the initramfs in /boot on the first" >&2 echo "partition of the eMMC or SD-card to load the rootfs from the " >&2 echo "encrypted disk." >&2 echo >&2 echo "Usage: $0 [--help] [DEVICE_PATH]" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 echo " --force Avoid user interaction: run reform-migrate and" >&2 echo " put /boot on eMMC if allowed. Requires passphrase" >&2 echo " on standard input." >&2 echo >&2 echo "Arguments:" >&2 echo " [DEVICE_PATH] Disk, partition or regular file to set up with " >&2 echo " LUKS and LVM. If this argument is missing, defaults" >&2 echo " to the SSD." >&2 echo " If the eMMC device is provided, it will be" >&2 echo " partitioned with the first partition for /boot and" >&2 echo " the second partition for LUKS&LVM." >&2 echo " The shorthands ssd, emmc, sd and usb can be used" >&2 echo " to install to the SSD, the eMMC, the SD card or" >&2 echo " to a USB drive respectively." >&2 echo " To copy to a file of the same name as one of the" >&2 echo " shorthands, prefix the filename with a dot and" >&2 echo " and a slash for a relative path." >&2 echo >&2 echo "Example 1:" >&2 echo "When booted from SD-card set up the first partition on eMMC as /boot" >&2 echo "and set up the SSD with LUKS. Set up LVM inside LUKS with" >&2 echo "one volume for swap and the other for the root file system. Copy" >&2 echo "the current system to /dev/reformvg/root:" >&2 echo >&2 echo " $0" >&2 echo >&2 echo "Example 2:" >&2 echo "When booted from SD-card, set up eMMC with two partitions, the first" >&2 echo "one for /boot and the second for LUKS. Set up LVM inside LUKS with" >&2 echo "one volume for swap and the other for the root file system. Copy" >&2 echo "the current system to /dev/reformvg/root. Suppress any interactivity" >&2 echo "by using --force and obtain the LUKS passphrase from standard input." >&2 echo >&2 echo " echo hunter2 | $0 --force emmc" >&2 echo >&2 } FORCE=false while getopts :h-: OPTCHAR; do case "$OPTCHAR" in h) usage exit 0 ;; -) case "$OPTARG" in help) usage exit 0 ;; force) FORCE=true ;; *) echo "E: unrecognized option: --$OPTARG" >&2 exit 1 ;; esac ;; :) echo "E: missing argument for -$OPTARG" >&2 exit 1 ;; '?') echo "E: unrecognized option -$OPTARG" >&2 exit 1 ;; *) echo "E: error parsing options" >&2 exit 1 ;; esac done shift "$((OPTIND - 1))" if [ "$(id -u)" -ne 0 ]; then echo "reform-setup-encrypted-disk has to be run as root / using sudo." exit fi DEVICE_PATH= if [ "$#" -eq 1 ]; then DEVICE_PATH="$1" elif [ "$#" -gt 1 ]; then echo "E: invalid number of arguments" >&2 usage exit 1 fi command -v "cryptsetup" >/dev/null 2>&1 || { echo >&2 'Please install "cryptsetup" using: apt install cryptsetup' exit 1 } command -v "lvchange" >/dev/null 2>&1 || { echo >&2 'Please install "lvm2" using: apt install lvm2' exit 1 } command -v "mkfs.ext4" >/dev/null 2>&1 || { echo >&2 'Please install "e2fsprogs" using: apt install e2fsprogs' exit 1 } # shellcheck source=/dev/null if [ -e "./machines/$(cat /proc/device-tree/model).conf" ]; then . "./machines/$(cat /proc/device-tree/model).conf" elif [ -e "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" ]; then . "/usr/share/reform-tools/machines/$(cat /proc/device-tree/model).conf" else echo "E: unable to find config for $(cat /proc/device-tree/model)" >&2 exit 1 fi if [ -z "$DEVICE_PATH" ]; then DEVICE_PATH="/dev/$DEV_SSD" fi case $DEVICE_PATH in "/dev/$DEV_MMC"*) case $EMMC_USE in false) echo "E: writing to eMMC not supported on $(cat /proc/device-tree/model)" >&2 exit 1 ;; warn) echo "W: Using eMMC on $(cat /proc/device-tree/model) is not without risk." >&2 echo "W: For example, flashing the wrong u-boot or if the flashing process goes wrong, it is" >&2 echo "W: possible to soft-brick your board. Restoring it might need some extra hardware." >&2 echo "W: Please only proceed if you are sure that the benefits outweigh the risks for you." >&2 if [ "$FORCE" = true ]; then echo "Proceeding without user interaction because of --force" response="y" else printf "Are you sure you want to proceed? [y/N] " read -r response fi if [ "$response" != "y" ]; then echo "Exiting." exit fi ;; esac ;; esac case $DEVICE_PATH in sd) DEVICE_PATH="/dev/${DEV_SD}" ;; ssd) DEVICE_PATH="/dev/${DEV_SSD}" ;; emmc) DEVICE_PATH="/dev/${DEV_MMC}" ;; usb) DEVICE_PATH="/dev/${DEV_USB}" ;; esac if [ -b "$DEVICE_PATH" ]; then case $DEVICE_PATH in /dev/sda*) HUMAN="SATA SSD" ;; /dev/nvme0n1*) HUMAN="NVMe SSD" ;; "/dev/$DEV_MMC"*) HUMAN="eMMC" ;; "/dev/$DEV_SD"*) HUMAN="SD card" ;; *) HUMAN="SSD" ;; esac echo "This will ERASE ALL DATA from your $HUMAN." echo "" if [ "$FORCE" = true ]; then echo "Proceeding without user interaction because of --force" response="y" else printf "Are you sure you want to proceed? [y/N] " read -r response fi if [ "$response" != "y" ]; then echo "Exiting." exit fi elif [ -f "$DEVICE_PATH" ]; then # plain file -- do nothing HUMAN="reguar file" else echo "E: $DEVICE_PATH is neither block device nor regular file" >&2 exit 1 fi cleanupvg() { vgchange -an reformvg; } cleanupluks() { cryptsetup luksClose reform_crypt; } error() { echo "$0 FAILED to run" >&2; } trap error EXIT INT TERM if [ ! -f "$DEVICE_PATH" ] && [ -n "$(lsblk --noheadings --output=MOUNTPOINT "$DEVICE_PATH")" ]; then echo "$DEVICE_PATH is still in use" >&2 exit 1 fi # If the user chose eMMC or SD-card as the target device, then it has to be # partitioned first so that the unencrypted /boot partition can be in front # of the luks partition. Users who do not want this behaviour can manually # partition their eMMC or SD-card. case $DEVICE_PATH in "/dev/$DEV_MMC" | "/dev/$DEV_SD") # Space in MB which needs to be kept empty for u-boot before the first # partition starts. Biggest requirement comes from rk3588 which expects # u-boot at an offset of 8 MiB and a 4 MiB trust (ATF, OP-TEE) # partition after that. So the first partition can only start at byte # 16777216 or 16 MiB: https://opensource.rock-chips.com/wiki_Partitions MAX_UBOOT=16 BOOTSIZE=488 /sbin/parted --script --machine "$DEVICE_PATH" "mklabel msdos" /sbin/parted --script --machine "$DEVICE_PATH" "mkpart primary ext4 ${MAX_UBOOT}MiB $((BOOTSIZE + MAX_UBOOT))MiB" /sbin/parted --script --machine "$DEVICE_PATH" "mkpart primary $((BOOTSIZE + MAX_UBOOT))MiB 100%" mkfs.ext4 "${DEVICE_PATH}p1" case $DEVICE_PATH in "/dev/$DEV_MMC") DEVICE_PATH="/dev/${DEV_MMC}p2" ;; "/dev/$DEV_SD") DEVICE_PATH="/dev/${DEV_SD}p2" ;; esac ;; esac # /proc/meminfo contains the sizes in kibibytes mem="$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)" case "$mem" in *[!0123456789]* | 0?* | "") echo "E: unable to acquire total memory from /proc/meminfo" >&2 exit 1 ;; esac # convert memory size to gigabytes, rounding up mem="$(awk 'BEGIN {printf("%.f",'"$mem"'/1024/1024+0.5)}')" # minimum swap size is 4G if [ "$mem" -lt 4 ]; then mem=4 fi if [ -f "$DEVICE_PATH" ]; then disksize="$(stat -c %s "$DEVICE_PATH")" else disksize=$(lsblk --nodeps --bytes --noheadings --output=SIZE "$DEVICE_PATH" | head -1) case "$disksize" in *[!0123456789]* | 0?* | "") echo "E: unable to acquire disk size of $DEVICE_PATH" >&2 exit 1 ;; esac fi # convert disk size to gigabytes, rounding down disksize="$((disksize / 1024 / 1024 / 1024))" case $DEVICE_PATH in "/dev/$DEV_MMC"* | "/dev/$DEV_SD"*) : # do not limit swap size for eMMC and SD-card ;; *) # maximum swap size is 5% of disk size if [ "$mem" -gt "$((disksize * 5 / 100))" ]; then mem="$((disksize * 5 / 100))" fi ;; esac if [ "$mem" -le 1 ]; then echo "E: your disk is too small for swap" >&2 exit 1 fi if [ "$FORCE" = true ]; then read -r PASSPHRASE printf "%s" "$PASSPHRASE" | cryptsetup luksFormat "$DEVICE_PATH" "-" else cryptsetup luksFormat "$DEVICE_PATH" fi trap "cleanupluks; error" EXIT INT TERM if [ "$FORCE" = true ]; then printf "%s" "$PASSPHRASE" | cryptsetup luksOpen --key-file=- "$DEVICE_PATH" reform_crypt else cryptsetup luksOpen "$DEVICE_PATH" reform_crypt fi pvcreate /dev/mapper/reform_crypt vgcreate reformvg /dev/mapper/reform_crypt trap "cleanupvg; cleanupluks; error" EXIT INT TERM lvcreate --name swap --size "${mem}G" reformvg mkswap /dev/reformvg/swap lvcreate --name root --extents 100%FREE reformvg mkfs.ext4 /dev/reformvg/root SWAPUUID=$(lsblk --nodeps --noheadings --output=UUID /dev/reformvg/swap) CRYPTUUID=$(cryptsetup luksUUID "$DEVICE_PATH") echo "" if [ "$FORCE" = true ]; then echo "Running reform-migrate because of --force" response="y" else printf "The encrypted %s is now set up. Do you want me to run reform-migrate now as well? [y/N] " "$HUMAN" read -r response fi if [ "$response" != "y" ]; then echo "If you want to migrate this system to $HUMAN you can now run:" echo "" echo "echo RESUME=UUID=$SWAPUUID > /etc/initramfs-tools/conf.d/resume" echo "echo reform_crypt UUID=$CRYPTUUID none luks,discard,x-initrd.attach > /etc/crypttab" echo "echo UUID=$SWAPUUID none swap sw 0 0 >> /etc/fstab" echo "cryptsetup luksOpen $DEVICE_PATH reform_crypt" echo "vgchange -ay reformvg" echo "reform-migrate /dev/reformvg/root" echo "vgchange -an reformvg" echo "cryptsetup luksClose reform_crypt" else # we are not really running reform-migrate but imitate what it does # instead because we want to write out some files after the rsync but # before running reform-boot-config ROOTMNT="$(mktemp --tmpdir --directory reform-setup-encrypted-disk.XXXXXXXXXX)" trap 'umount $ROOTMNT; cleanupvg; cleanupluks; error' EXIT INT TERM mount /dev/reformvg/root "$ROOTMNT" rsync -axHAWXS --numeric-ids --info=progress2 / "$ROOTMNT" echo "RESUME=UUID=$SWAPUUID" >"$ROOTMNT/etc/initramfs-tools/conf.d/resume" echo "reform_crypt UUID=$CRYPTUUID none luks,discard,x-initrd.attach" >"$ROOTMNT/etc/crypttab" echo "UUID=$SWAPUUID none swap sw 0 0" >>"$ROOTMNT/etc/fstab" trap "cleanupvg; cleanupluks; error" EXIT INT TERM umount "$ROOTMNT" emmc_flag= if [ "$EMMC_USE" != false ]; then if [ "$FORCE" = true ]; then echo "Placing /boot on eMMC because of --force" emmc_flag="--emmc" else printf "Your /boot partition will be on eMMC by default. Do you want it on the SD-Card instead? [y/N] " read -r response if [ "$response" != "y" ]; then emmc_flag="--emmc" fi fi fi ret=0 if [ "$FORCE" = true ]; then reform-boot-config --force $emmc_flag /dev/reformvg/root || ret=$? else reform-boot-config $emmc_flag /dev/reformvg/root || ret=$? fi if [ "$ret" -ne 0 ]; then echo "reform-boot-config failed. To re-run it manually, perform the following steps:" >&2 echo " $ cryptsetup luksOpen \"$DEVICE_PATH\" reform_crypt" >&2 echo " $ vgchange -ay reformvg" >&2 echo " $ reform-boot-config $emmc_flag /dev/reformvg/root" >&2 echo " $ vgchange -an reformvg" >&2 echo " $ cryptsetup luksClose reform_crypt" >&2 exit "$ret" fi fi trap "cleanupluks; error" EXIT INT TERM cleanupvg trap "error" EXIT INT TERM cleanupluks trap - EXIT INT TERM echo "You can now reboot into your encrypted System." reform-tools-1.71/bin/reform-setup-encrypted-nvme000077500000000000000000000005241477621656200221770ustar00rootroot00000000000000#!/bin/sh set -eu echo "reform-setup-encrypted-nvme got renamed to reform-setup-encrypted-disk" >&2 echo "use reform-setup-encrypted-disk instead" if [ "$#" -eq "0" ]; then exit fi if [ "$#" -gt "1" ]; then echo "E: too many arguments" >&2 exit 1 fi if [ "$1" != "--help" ]; then echo "E: unknown argument: $1" >&2 exit 1 fi reform-tools-1.71/bin/reform-standby000077500000000000000000000037631477621656200175550ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-2.0+ # Copyright 2021-2023 Lukas F. Hartmann # Copyright 2022-2025 Johannes Schauer Marin Rodrigues # # MNT Reform Standby Handler (For i.MX8MQ) # Thanks to ruff for contributions set -eu usage() { echo "i.MX8MQ specific setup before suspend and after wakeup." >&2 echo "This script is called by the reform-sleep.service systemd service." >&2 echo "Do not call this script manually from the terminal but use" >&2 echo "systemctl suspend instead." >&2 echo >&2 echo "Usage: $0 [--help] suspend|resume" >&2 echo >&2 echo "Options:" >&2 echo " --help Display this help and exit." >&2 } if [ "$#" -gt 0 ] && [ "$1" = "--help" ]; then usage exit 0 fi if [ "$(id -u)" -ne 0 ]; then echo "reform-standby has to be run as root / using sudo." exit fi case "$(cat /proc/device-tree/model)" in "MNT Reform 2" | "MNT Reform 2 HDMI") : ;; *) echo "Sorry, reform-standby is only supported on MNT Reform 2 with i.MX8MQ processor module." exit ;; esac wifi_off() { echo 1 >/sys/class/pci_bus/0000:01/device/remove } wifi_on() { echo 1 >/sys/class/pci_bus/0000:00/rescan sleep 1 } hantro_off() { # with 5.18, hantro_vpu hangs on resume rmmod hantro_vpu } hantro_on() { modprobe hantro_vpu } kbd_backlight_off() { for d in /dev/hidraw*; do printf "xLITE0" >"$d" done } kbd_backlight_on() { for d in /dev/hidraw*; do printf "xLITE6" >"$d" done } hid_bind() { echo 0003:03EB:2041.0002 >/sys/bus/hid/drivers/hid-generic/bind || : echo 0003:03EB:2042.0001 >/sys/bus/hid/drivers/hid-generic/bind || : } hid_unbind() { echo 0003:03EB:2041.0002 >/sys/bus/hid/drivers/hid-generic/unbind || : echo 0003:03EB:2042.0001 >/sys/bus/hid/drivers/hid-generic/unbind || : } case $1 in suspend) wifi_off hantro_off kbd_backlight_off hid_unbind ;; resume) kbd_backlight_on wifi_on hantro_on hid_bind ;; *) usage exit 1 ;; esac reform-tools-1.71/dracut/000077500000000000000000000000001477621656200153745ustar00rootroot00000000000000reform-tools-1.71/dracut/20-pocket-reform.conf000066400000000000000000000002241477621656200212350ustar00rootroot00000000000000force_drivers+=" pwm_imx27 nwl-dsi ti-sn65dsi86 imx-dcss panel-edp mux-mmio mxsfb usbhid imx8mq-interconnect " omit_drivers+=" imx8m-ddrc raid456 " reform-tools-1.71/flash-kernel/000077500000000000000000000000001477621656200164655ustar00rootroot00000000000000reform-tools-1.71/flash-kernel/preboot.d/000077500000000000000000000000001477621656200203615ustar00rootroot00000000000000reform-tools-1.71/flash-kernel/preboot.d/00reform2_preboot000066400000000000000000000015721477621656200235570ustar00rootroot00000000000000#shellcheck shell=sh disable=SC2086,SC2154 ######### BEGIN /usr/share/flash-kernel/preboot.d/00reform2_preboot ########### # We need to set ${fdtfile} in uboot to select a default dtb for boot mediums # that are supposed to boot on multiple devices like the Debian installer. # # But if ${fdtfile} is set, then bootscr.uboot-generic will use that instead of # the dtb-${fk_kvers} symlink maintained by flash-kernel which will point to # either the normal or the hdmi dtb for the reform. # # This preboot script overwrites ${fdtpath} such that even when ${fdtfile} is # set to a reasonable default, u-boot will still use dtb-${fk_kvers} if it # exists -- which it does after running flash-kernel. if test -e ${devtype} ${devnum}:${partition} ${prefix}dtb-${fk_kvers}; then setenv fdtpath dtb-${fk_kvers} fi ########## END /usr/share/flash-kernel/preboot.d/00reform2_preboot ############ reform-tools-1.71/flash-kernel/ubootenv.d/000077500000000000000000000000001477621656200205505ustar00rootroot00000000000000reform-tools-1.71/flash-kernel/ubootenv.d/00reform2_ubootenv000066400000000000000000000034231477621656200241320ustar00rootroot00000000000000# shellcheck shell=sh ######### BEGIN /usr/share/flash-kernel/ubootenv.d/00reform2_ubootenv ######### # Default bootargs for Linux are set here and can be overwritten using # LINUX_KERNEL_CMDLINE in /etc/default/flash-kernel or by setting ${bootargs} # in u-boot itself via the setenv command. # shellcheck disable=SC2154 setenv bootargs "ro no_console_suspend cryptomgr.notests loglevel=3 ${bootargs}" # Board-specific bootargs cannot be overwritten by above methods. If you # really need to overwrite below lines, create # /etc/flash-kernel/ubootenv.d/00reform2_ubootenv and fill it with what you # would like to replace the contents of this file with. # # This block is only needed for boards which might still run with an older # version of u-boot and thus might not yet set ${bootargs} correctly. # shellcheck disable=SC2154 if test "${board}" = "nitrogen8m_som"; then setenv bootargs "${bootargs} console=ttymxc0,115200 cma=512M pci=nomsi" elif test "${board}" = "MNT Reform 2.0"; then # some imx8mq Reforms have this board value setenv bootargs "${bootargs} console=ttymxc0,115200 cma=512M pci=nomsi" elif test "${board}" = "u200"; then # amlogic internal name for a311d dev board setenv bootargs "${bootargs} console=ttyAML0,115200 pci=pcie_bus_perf libata.force=noncq nvme_core.default_ps_max_latency_us=0" elif test "${board}" = "ls1028a"; then setenv bootargs "${bootargs} console=ttyS0,115200 cma=512M@3G iommu.passthrough=1 arm-smmu.disable_bypass=0" fi # console=tty1 needs to go at the end of the kernel cmdline because the luks # passphrase prompt will show up on the last console which must not be the # serial terminal but the tty displayed to the screen setenv bootargs "${bootargs} console=tty1" ########## END /usr/share/flash-kernel/ubootenv.d/00reform2_ubootenv ########## reform-tools-1.71/initramfs-tools/000077500000000000000000000000001477621656200172445ustar00rootroot00000000000000reform-tools-1.71/initramfs-tools/hooks/000077500000000000000000000000001477621656200203675ustar00rootroot00000000000000reform-tools-1.71/initramfs-tools/hooks/reform000077500000000000000000000031761477621656200216160ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2023-2025 Johannes Schauer Marin Rodrigues set -e PREREQ="" prereqs() { echo "$PREREQ"; } case $1 in prereqs) prereqs exit 0 ;; esac # shellcheck disable=SC1091 . /usr/share/initramfs-tools/hook-functions MACHINE= if [ -e /etc/flash-kernel/machine ]; then MACHINE=$(cat /etc/flash-kernel/machine) elif [ -e /proc/device-tree/model ]; then MACHINE=$(cat /proc/device-tree/model) fi # The switch below creates device-specific initramfs depending on the platform # that update-initramfs is run on. For the system images, we would like to # create identical images that work on all boards. Thus, if you change anything # below, make sure to also adjust the respective initramfs hook in the # reform-system-image repository. case $MACHINE in "MNT Reform 2") : ;; "MNT Reform 2 HDMI") : ;; "MNT Reform 2 with BPI-CM4 Module") : ;; "MNT Reform 2 with LS1028A Module") # shellcheck disable=SC2154 [ "${verbose}" = "y" ] && echo "Adding firmware ls1028a-mhdpfw.bin" copy_file firmware /boot/ls1028a-mhdpfw.bin /lib/firmware # shellcheck disable=SC2154 [ "${verbose}" = "y" ] && echo "Adding /usr/bin/dmesg" copy_exec /usr/bin/dmesg ;; "MNT Reform 2 with RCORE RK3588 Module") : ;; "MNT Pocket Reform with i.MX8MP Module") : ;; "MNT Pocket Reform with BPI-CM4 Module") : ;; "MNT Pocket Reform with RCORE RK3588 Module") : ;; "MNT Reform Next with RCORE RK3588 Module") : ;; "") echo "W: unable to deduce target machine for reform initramfs-hook" >&2 ;; *) echo "W: unsupported machine: $MACHINE" >&2 ;; esac reform-tools-1.71/initramfs-tools/reform.conf000066400000000000000000000010551477621656200214060ustar00rootroot00000000000000# imx8mq-mnt-reform2 pwm_imx27 nwl-dsi ti-sn65dsi86 imx-dcss panel-edp mux-mmio mxsfb usbhid imx8mq-interconnect # meson-g12b-bananapi-cm4-mnt-reform2 meson_dw_hdmi meson_dw_mipi_dsi meson_canvas meson_drm dw_hdmi_i2s_audio dw_mipi_dsi meson_dw_mipi_dsi meson_vdec ao_cec_g12a panfrost snd_soc_meson_g12a_tohdmimix dw_hdmi_i2s_audio cec snd_soc_hdmi_codec snd_soc_meson_codec_glue snd_soc_meson_axg_toddr snd_pcm snd display_connector # ls1028a cdns_mhdp_imx cdns_mhdp_drmcore mali_dp # imx8mp-mnt-reform/pocket-reform governor_userspace cpufreq_dt imx_bus reform-tools-1.71/initramfs-tools/scripts/000077500000000000000000000000001477621656200207335ustar00rootroot00000000000000reform-tools-1.71/initramfs-tools/scripts/reform000077500000000000000000000011201477621656200221450ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2023-2025 Johannes Schauer Marin Rodrigues case $1 in prereqs) exit 0 ;; esac # shellcheck disable=SC1091 . /scripts/functions MACHINE= if [ -e /etc/flash-kernel/machine ]; then MACHINE=$(cat /etc/flash-kernel/machine) elif [ -e /proc/device-tree/model ]; then MACHINE=$(cat /proc/device-tree/model) fi case $MACHINE in "MNT Reform 2 with LS1028A Module") # https://source.mnt.re/reform/reform-debian-packages/-/issues/5 dmesg -n 7 || echo "E: failed to set kernel loglevel" >&2 ;; esac reform-tools-1.71/kernel/000077500000000000000000000000001477621656200153725ustar00rootroot00000000000000reform-tools-1.71/kernel/zz-reform-tools000077500000000000000000000036001477621656200204100ustar00rootroot00000000000000#!/bin/sh # SPDX-License-Identifier: GPL-3.0+ # Copyright 2024-2025 Johannes Schauer Marin Rodrigues # # Populate /boot with all known dtbs. # The flash-kernel package is still needed to provide the /boot/dtb-$(uname -r) # symlink. That symlink is needed on platforms that do not set the `${fdtfile}` # u-boot environment variable. set -e self="$0" version="$1" # shellcheck disable=SC2034 image_path="$2" # shellcheck disable=SC2086 set -- $DEB_MAINT_PARAMS # strip single quotes from beginning and end action="${1#\'}" action="${action%\'}" set -u install_dtbs() { for CONF in /usr/share/reform-tools/machines/*.conf; do # shellcheck disable=SC1090 . "$CONF" if [ ! -d "/usr/lib/linux-image-$version" ]; then echo "W: /usr/lib/linux-image-$version does not exist -- skipping..." >&2 continue fi dtb=$(find "/usr/lib/linux-image-$version" -wholename "*/$DTBPATH" 2>/dev/null | head -n 1) if [ -z "$dtb" ]; then echo "W: no dtb for $DTBPATH in /usr/lib/linux-image-$version -- skipping..." >&2 continue elif [ ! -f "$dtb" ]; then echo "W: $dtb does not exist -- skipping..." >&2 continue fi if [ ! -e "/usr/lib/linux-image-$version/$DTBPATH" ]; then echo "W: irregular dtb path: $dtb" >&2 fi mkdir -p "/boot/dtbs/$version/$(dirname "$DTBPATH")" cp "$dtb" "/boot/dtbs/$version/$DTBPATH" done } remove_dtbs() { for CONF in /usr/share/reform-tools/machines/*.conf; do # shellcheck disable=SC1090 . "$CONF" rm -f "/boot/dtbs/$version/$DTBPATH" || : done rmdir --ignore-fail-on-non-empty "/boot/dtbs/$version" } case "$self:$action" in # Only run on postinst configure and postrm remove, to avoid wasting # time by calling this script multiple times on upgrade and removal. */postinst.d/*:configure) install_dtbs ;; */postrm.d/*:remove) remove_dtbs ;; *) exit 0 ;; esac reform-tools-1.71/libexec/000077500000000000000000000000001477621656200155255ustar00rootroot00000000000000reform-tools-1.71/libexec/reform-tools/000077500000000000000000000000001477621656200201555ustar00rootroot00000000000000reform-tools-1.71/libexec/reform-tools/reform-tray.py000077500000000000000000000066741477621656200230160ustar00rootroot00000000000000#!/usr/bin/env python3 # Copyright 2023 - 2024 Lukas F. Hartmann # Copyright 2024 Johannes Schauer Marin Rodrigues # SPDX-License-Identifier: GPL-3.0+ import signal import os import subprocess import gi import shutil gi.require_version("Gtk", "3.0") gi.require_version("Notify", "0.7") gi.require_version("AyatanaAppIndicator3", "0.1") from gi.repository import Gtk from gi.repository import Gdk from gi.repository import Notify from gi.repository import AyatanaAppIndicator3 as AppIndicator3 APPID = "reform-tray" ICON = "view-more-symbolic" def handle_exit_item(question, command): dialog = Gtk.MessageDialog( flags=0, message_type=Gtk.MessageType.WARNING, text=question, ) dialog.format_secondary_text("Make sure to save your work first.") dialog.add_buttons( Gtk.STOCK_OK, Gtk.ResponseType.OK, Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, ) response = dialog.run() if response == Gtk.ResponseType.OK: subprocess.run(command) dialog.destroy() class MenuItem(Gtk.ImageMenuItem): def __init__(self, label, icon, args, exitmsg=None): Gtk.ImageMenuItem.__init__(self, label=label, visible=True) self.img = Gtk.Image() self.img.set_from_icon_name(icon, -1) self.set_image(self.img) self.set_always_show_image(True) if exitmsg: self.action = lambda _: handle_exit_item(exitmsg, args) else: self.action = lambda _: subprocess.run(args) self.connect("activate", self.action) if not shutil.which(args[0]): self.set_sensitive(False) menuitems = [ MenuItem( "Help", "help-about-symbolic", ["x-terminal-emulator", "bash", "-c", "reform-help --desktop; bash"], None, ), MenuItem( "High Brightness", "weather-clear-symbolic", ["brightnessctl", "set", "100%"], None, ), MenuItem( "Low Brightness", "weather-clear-night-symbolic", ["brightnessctl", "set", "10%"], None, ), MenuItem("Terminal", "utilities-terminal-symbolic", ["x-terminal-emulator"], None), MenuItem("File Manager", "folder-symbolic", ["thunar", os.environ["HOME"]], None), MenuItem( "System Monitor", "utilities-system-monitor-symbolic", ["gnome-system-monitor"], None, ), MenuItem( "Logout", "system-log-out-symbolic", ["pkill", "(wayfire|sway)"], "Are you sure you want to exit the desktop session?", ), MenuItem( "Reboot", "system-restart-symbolic", ["systemctl", "reboot"], "Are you sure you want to reboot the computer?", ), MenuItem( "Shutdown", "system-shutdown-symbolic", ["systemctl", "poweroff"], "Are you sure you want to shut down the computer?", ), ] class TrayIcon: def __init__(self, appid, icon, menuitems): self.menu = Gtk.Menu() for mi in menuitems: self.menu.append(mi) self.ind = AppIndicator3.Indicator.new( appid, icon, AppIndicator3.IndicatorCategory.HARDWARE ) self.ind.set_status(AppIndicator3.IndicatorStatus.ACTIVE) self.ind.set_secondary_activate_target(mi) self.ind.set_menu(self.menu) signal.signal(signal.SIGINT, signal.SIG_DFL) icon = TrayIcon(APPID, ICON, menuitems) Notify.init(APPID) Gtk.main() reform-tools-1.71/libexec/reform-tools/reform-wallpaper.py000077500000000000000000000140541477621656200240150ustar00rootroot00000000000000#!/usr/bin/env python3 # Copyright 2024 Johannes Schauer Marin Rodrigues # SPDX-License-Identifier: MIT # inspired by https://gitlab.com/carbonOS/gde/gde-background import gi gi.require_version("Gtk", "3.0") gi.require_version("GtkLayerShell", "0.1") gi.require_version("GDesktopEnums", "3.0") from gi.repository import Gtk, Gdk, GtkLayerShell, GDesktopEnums, Gio, GdkPixbuf, GLib class BackgroundWindow(Gtk.Window): def __init__(self): super().__init__() self.set_decorated(False) self.set_title("reform-wallpaper") self._pixbuf = GdkPixbuf.Pixbuf.new( GdkPixbuf.Colorspace.RGB, False, 8, 200, 200 ) self._file_monitor = None self.connect("draw", self._draw_cb) self.connect("size-allocate", self._size_allocate_cb) GtkLayerShell.init_for_window(self) GtkLayerShell.set_exclusive_zone(self, -1) GtkLayerShell.set_layer(self, GtkLayerShell.Layer.BACKGROUND) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.LEFT, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.RIGHT, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.TOP, True) GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.BOTTOM, True) self._settings = Gio.Settings(schema_id="org.gnome.desktop.background") self._settings.connect("changed", self._settings_changed_cb) def _settings_changed_cb(self, settings, key): if key in [ "picture-uri", "primary-color", "picture-options", "picture-opacity", ]: self._size_allocate_cb(self, self.get_size()) def _draw_cb(self, widget, ctx): ctx.save() ctx.scale(1.0 / self.get_scale_factor(), 1.0 / self.get_scale_factor()) Gdk.cairo_set_source_pixbuf(ctx, self._pixbuf, 0, 0) ctx.paint() ctx.restore() return True def _size_allocate_cb(self, widget, rect): self._pixbuf = GdkPixbuf.Pixbuf.new( GdkPixbuf.Colorspace.RGB, False, 8, rect.width * self.get_scale_factor(), rect.height * self.get_scale_factor(), ) fill_color = Gdk.RGBA() if fill_color.parse(self._settings.get_string("primary-color")): self._pixbuf.fill( ( (int(fill_color.red * 0xFF)) << 24 | (int(fill_color.green * 0xFF)) << 16 | (int(fill_color.blue * 0xFF)) << 8 ) + 0xFF ) else: # if parsing the value failed, fill with the default color from # /usr/share/glib-2.0/schemas/org.gnome.desktop.background.gschema.xml self._pixbuf.fill(0x023C88FF) alpha = 255.0 * (self._settings.get_int("picture-opacity") / 100.0) if alpha == 0: self.queue_draw() return bg_mode = self._settings.get_enum("picture-options") match bg_mode: case GDesktopEnums.BackgroundStyle.NONE: self.queue_draw() return case GDesktopEnums.BackgroundStyle.SCALED: pass case GDesktopEnums.BackgroundStyle.ZOOM: pass case _: print("W: background style not supported:", bg_mode) path = self._settings.get_string("picture-uri") scheme = GLib.uri_parse_scheme(path) if scheme == "file": path = GLib.filename_from_uri(path)[0] else: print(f"W: scheme {scheme} not supported") if path.endswith(".xml"): print("W: GNOME timed wallpaper xml not supported") if self._file_monitor is not None: self._file_monitor.cancel() self._file_monitor = None try: self._file_monitor = Gio.File.new_for_path(path).monitor( Gio.FileMonitorFlags.NONE ) self._file_monitor.connect( "changed", lambda a, b, c, d: self._size_allocate_cb(self, self.get_size()), ) except Exception as e: print(f"E: attaching the file monitor failed with: {e}") img = GdkPixbuf.Pixbuf.new_from_file(path) ratio_w = self._pixbuf.get_width() / img.get_width() ratio_h = self._pixbuf.get_height() / img.get_height() if bg_mode == GDesktopEnums.BackgroundStyle.SCALED: ratio = ratio_w if ratio_w < ratio_h else ratio_h else: ratio = ratio_w if ratio_w > ratio_h else ratio_h final_width = ratio * img.get_width() final_height = ratio * img.get_height() off_x = (self._pixbuf.get_width() - final_width) / 2 off_y = (self._pixbuf.get_height() - final_height) / 2 if bg_mode == GDesktopEnums.BackgroundStyle.SCALED: img.composite( self._pixbuf, off_x, off_y, final_width, final_height, off_x, off_y, ratio, ratio, GdkPixbuf.InterpType.BILINEAR, alpha, ) else: img.composite( self._pixbuf, 0, 0, self._pixbuf.get_width(), self._pixbuf.get_height(), off_x, off_y, ratio, ratio, GdkPixbuf.InterpType.BILINEAR, alpha, ) self.queue_draw() def create_window(monitor): win = BackgroundWindow() GtkLayerShell.set_monitor(win, monitor) setattr(monitor, "reform-wallpaper", win) win.show_all() def destroy_window(monitor): getattr(monitor, "reform-wallpaper").destroy() if __name__ == "__main__": display = Gdk.Display.get_default() for i in range(display.get_n_monitors()): create_window(display.get_monitor(i)) display.connect("monitor_added", create_window) display.connect("monitor_removed", destroy_window) Gtk.main() reform-tools-1.71/lpc/000077500000000000000000000000001477621656200146705ustar00rootroot00000000000000reform-tools-1.71/lpc/Makefile000066400000000000000000000002631477621656200163310ustar00rootroot00000000000000obj-m := reform2_lpc.o KERNEL_DIR = /lib/modules/$(shell uname -r)/build all: $(MAKE) -C "$(KERNEL_DIR)" M="$(PWD)" modules clean: $(MAKE) -C "$(KERNEL_DIR)" M="$(PWD)" clean reform-tools-1.71/lpc/reform2_lpc.c000066400000000000000000000354731477621656200172620ustar00rootroot00000000000000/* * SPDX-License-Identifier: GPL-2.0 * Copyright 2022 nanocodebug * Copyright 2023 Michael Fincham * Copyright 2024 Michal Suchánek * Copyright 2024 Lukas F. Hartmann * Copyright 2023-2025 Johannes Schauer Marin Rodrigues */ #include #include #include #include #include #include #include #include #include #include /* abs_diff was only added to math.h in linux 6.6 */ #ifndef abs_diff #define abs_diff(a, b) \ ({ \ typeof(a) __a = (a); \ typeof(b) __b = (b); \ (void)(&__a == &__b); \ __a > __b ? (__a - __b) : (__b - __a); \ }) #endif static int lpc_probe(struct spi_device *spi); static void lpc_remove(struct spi_device *spi); static void lpc_power_off(void); static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t show_cells(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t show_firmware(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t show_capacity(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t lpc_command(struct device *dev, char command, uint8_t arg1, uint8_t *response); static int get_bat_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val); #define VOL_JUMP 1000000 #define CAP_JUMP 1000000 #define CUR_JUMP 1000000 typedef struct lpc_driver_data { struct spi_device *spi; struct power_supply *bat; struct mutex lock; int last_batt_cap; int last_batt_vol; int last_batt_cur; struct backlight_device *backlight; } lpc_driver_data; static DEVICE_ATTR(status, 0444, show_status, NULL); static DEVICE_ATTR(cells, 0444, show_cells, NULL); static DEVICE_ATTR(firmware, 0444, show_firmware, NULL); static DEVICE_ATTR(capacity, 0444, show_capacity, NULL); static struct spi_board_info g_spi_board_info = { .modalias = "reform2_lpc", .max_speed_hz = 400000, .bus_num = 0, .chip_select = 0, .mode = SPI_MODE_1, }; static enum power_supply_property bat_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CHARGE_FULL, POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_CHARGE_EMPTY, POWER_SUPPLY_PROP_PRESENT, }; static struct power_supply_desc bat_desc = { .name = "BAT0", .properties = bat_props, .num_properties = ARRAY_SIZE(bat_props), .get_property = get_bat_property, .type = POWER_SUPPLY_TYPE_BATTERY, }; static struct power_supply_config psy_cfg = {}; static struct device *poweroff_device; static int bl_get_brightness(struct backlight_device *bl) { u16 brightness = bl->props.brightness; return brightness & 0x7f; } static int bl_update_status(struct backlight_device *bl) { struct lpc_driver_data *data = (struct lpc_driver_data *)bl_get_data(bl); uint8_t buffer[8]; lpc_command(&data->spi->dev, 'b', bl->props.brightness, buffer); return 0; } static const struct backlight_ops lpc_bl_ops = { .update_status = bl_update_status, .get_brightness = bl_get_brightness, }; static struct backlight_device *lpc_create_backlight(struct device *dev, void *data) { struct backlight_properties props; memset(&props, 0, sizeof(props)); props.type = BACKLIGHT_RAW; props.brightness = 100; props.max_brightness = 100; return devm_backlight_device_register(dev, "mnt_pocket_reform_backlight", dev, data, &lpc_bl_ops, &props); } int (*__mnt_pocket_reform_get_panel_version)(void); static int lpc_probe(struct spi_device *spi) { struct lpc_driver_data *data; int ret; printk(KERN_INFO "%s: probing ...\n", "reform2_lpc"); spi->max_speed_hz = g_spi_board_info.max_speed_hz; spi->mode = g_spi_board_info.mode; spi->bits_per_word = 8; ret = spi_setup(spi); if (ret) { printk(KERN_ERR "%s: spi_setup failed\n", __func__); return -ENODEV; } data = kzalloc(sizeof(struct lpc_driver_data), GFP_KERNEL); if (data == NULL) { printk(KERN_ERR "%s: kzalloc failed\n", __func__); return -ENOMEM; } data->spi = spi; mutex_init(&data->lock); spi_set_drvdata(spi, data); ret = device_create_file(&spi->dev, &dev_attr_status); if (ret) { printk(KERN_ERR "%s: device_create_file failed\n", __func__); } ret = device_create_file(&spi->dev, &dev_attr_cells); if (ret) { printk(KERN_ERR "%s: device_create_file failed\n", __func__); } ret = device_create_file(&spi->dev, &dev_attr_firmware); if (ret) { printk(KERN_ERR "%s: device_create_file failed\n", __func__); } ret = device_create_file(&spi->dev, &dev_attr_capacity); if (ret) { printk(KERN_ERR "%s: device_create_file failed\n", __func__); } psy_cfg.of_node = spi->dev.of_node; psy_cfg.drv_data = data; #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) psy_cfg.no_wakeup_source = true; data->bat = power_supply_register(&spi->dev, &bat_desc, &psy_cfg); #else data->bat = power_supply_register_no_ws(&spi->dev, &bat_desc, &psy_cfg); #endif if (IS_ERR(data->bat)) { printk(KERN_ERR "%s: power_supply_register_no_ws failed\n", __func__); return PTR_ERR(data->bat); } // this overwrites something else that has already claimed pm_power_off on reform2 but it'll do for now poweroff_device = &spi->dev; pm_power_off = lpc_power_off; /* for MNT Pocket Reform with Display Version 2, the system controller has to control the backlight directly via PWM, but it must not do that on other versions of the display. */ __mnt_pocket_reform_get_panel_version = (void *)__symbol_get("mnt_pocket_reform_get_panel_version"); if (__mnt_pocket_reform_get_panel_version && __mnt_pocket_reform_get_panel_version() == 2) { printk(KERN_INFO "%s: enabling backlight control for MNT Pocket Reform with Display Version 2.\n", __func__); data->backlight = lpc_create_backlight(&spi->dev, data); if (IS_ERR(data->backlight)) { printk(KERN_ERR "%s: lpc_create_backlight failed\n", __func__); } } return ret; } static void lpc_remove(struct spi_device *spi) { struct lpc_driver_data *data = (struct lpc_driver_data *)spi_get_drvdata(spi); printk(KERN_INFO "%s: removing ... \n", "reform2_lpc"); device_remove_file(&spi->dev, &dev_attr_status); device_remove_file(&spi->dev, &dev_attr_firmware); device_remove_file(&spi->dev, &dev_attr_cells); device_remove_file(&spi->dev, &dev_attr_capacity); power_supply_unregister(data->bat); if (pm_power_off == &lpc_power_off) { pm_power_off = NULL; } kfree(data); } static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf) { uint8_t buffer[8]; int16_t voltage; int16_t amps; uint8_t percentage; uint8_t status; int ret = 0; ret = lpc_command(dev, 'q', 0, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); } voltage = (int16_t)buffer[0] | ((int16_t)buffer[1] << 8); amps = (int16_t)buffer[2] | ((int16_t)buffer[3] << 8); percentage = buffer[4]; status = buffer[5]; return snprintf(buf, PAGE_SIZE, "%d.%d %d.%d %2d%% %d", voltage / 1000, voltage % 1000, amps / 1000, abs(amps % 1000), percentage, status); } static ssize_t show_cells(struct device *dev, struct device_attribute *attr, char *buf) { uint8_t buffer[8]; uint16_t cells[8]; ssize_t wroteChars = 0; int ret = 0; ret = lpc_command(dev, 'v', 0, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); } for (uint8_t s = 0; s < 4; s++) { cells[s] = buffer[s * 2] | buffer[(s * 2) + 1] << 8; } ret = lpc_command(dev, 'v', 1, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); } for (uint8_t s = 0; s < 4; s++) { cells[s + 4] = buffer[s * 2] | buffer[(s * 2) + 1] << 8; } for (uint8_t s = 0; s < 8; s++) { ret = snprintf(buf + wroteChars, PAGE_SIZE - wroteChars, "%d.%d ", cells[s] / 1000, cells[s] % 1000); if (ret != -1) { wroteChars += ret; } } // drop the trailing whitespace if (wroteChars > 0) { wroteChars--; } return wroteChars; } static ssize_t show_firmware(struct device *dev, struct device_attribute *attr, char *buf) { uint8_t str1[9]; uint8_t str2[9]; uint8_t str3[9]; int ret = 0; ret = lpc_command(dev, 'f', 0, str1); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); } ret = lpc_command(dev, 'f', 1, str2); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); } ret = lpc_command(dev, 'f', 2, str3); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); } str1[8] = '\0'; str2[8] = '\0'; str3[8] = '\0'; return snprintf(buf, PAGE_SIZE, "%s %s %s", str1, str2, str3); } static ssize_t show_capacity(struct device *dev, struct device_attribute *attr, char *buf) { uint8_t buffer[8]; int ret = 0; uint16_t cap_accu_mah, cap_min_mah, cap_max_mah; ret = lpc_command(dev, 'c', 0, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); } cap_accu_mah = buffer[0] | (buffer[1] << 8); cap_min_mah = buffer[2] | (buffer[3] << 8); cap_max_mah = buffer[4] | (buffer[5] << 8); return snprintf(buf, PAGE_SIZE, "%d %d %d", cap_accu_mah, cap_min_mah, cap_max_mah); } static ssize_t lpc_command(struct device *dev, char command, uint8_t arg1, uint8_t *responseBuffer) { struct lpc_driver_data *data = (struct lpc_driver_data *)dev_get_drvdata(dev); uint8_t commandBuffer[4] = { 0xB5, command, arg1, 0x0 }; int ret = 0; mutex_lock(&data->lock); ret = spi_write(data->spi, commandBuffer, 4); if (ret) { printk(KERN_INFO "%s: spi_write failed\n", __func__); } msleep(50); ret = spi_read(data->spi, responseBuffer, 8); if (ret) { printk(KERN_INFO "%s: spi_read failed\n", __func__); } msleep(50); mutex_unlock(&data->lock); return ret; } static void lpc_power_off(void) { int ret = 0; uint8_t buffer[8]; ret = lpc_command(poweroff_device, 'p', 1, buffer); } static int get_bat_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { int ret = 0; uint8_t buffer[8]; struct lpc_driver_data *data; struct device *dev; int16_t amp; data = (struct lpc_driver_data *)power_supply_get_drvdata(psy); dev = &(data->spi->dev); switch (psp) { case POWER_SUPPLY_PROP_STATUS: val->intval = POWER_SUPPLY_STATUS_UNKNOWN; ret = lpc_command(dev, 'q', 0, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); } amp = (int16_t)buffer[2] | ((int16_t)buffer[3] << 8); if (amp < 0) { val->intval = POWER_SUPPLY_STATUS_CHARGING; } else if (amp == 0) { if (buffer[4] == 100) { val->intval = POWER_SUPPLY_STATUS_FULL; } else { val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; } } else { val->intval = POWER_SUPPLY_STATUS_DISCHARGING; } break; case POWER_SUPPLY_PROP_TECHNOLOGY: val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: ret = lpc_command(dev, 'q', 0, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); ret = -EINVAL; } val->intval = (buffer[0] | buffer[1] << 8) * 1000; if (data->last_batt_vol && (abs_diff(val->intval, data->last_batt_vol) > VOL_JUMP)) { printk(KERN_INFO "%s: Voltage jump from %i to %i\n", __func__, data->last_batt_vol, val->intval); val->intval = data->last_batt_vol + (val->intval > data->last_batt_vol ? VOL_JUMP : -VOL_JUMP); printk(KERN_INFO "%s: Clamping to %i\n", __func__, val->intval); } data->last_batt_vol = val->intval; break; case POWER_SUPPLY_PROP_CURRENT_NOW: ret = lpc_command(dev, 'q', 0, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); ret = -EINVAL; } amp = (int16_t)buffer[2] | ((int16_t)buffer[3] << 8); // negative current, battery is charging // reporting a negative value is out of spec if (amp < 0) { amp = 0; } val->intval = amp * 1000; if (data->last_batt_cur && (abs_diff(val->intval, data->last_batt_cur) > CUR_JUMP)) { printk(KERN_INFO "%s: Current jump from %i to %i\n", __func__, data->last_batt_cur, val->intval); val->intval = data->last_batt_cur + (val->intval > data->last_batt_cur ? CUR_JUMP : -CUR_JUMP); printk(KERN_INFO "%s: Clamping to %i\n", __func__, val->intval); } data->last_batt_cur = val->intval; break; case POWER_SUPPLY_PROP_CAPACITY: ret = lpc_command(dev, 'q', 0, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); ret = -EINVAL; } val->intval = buffer[4]; break; case POWER_SUPPLY_PROP_CHARGE_FULL: case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: ret = lpc_command(dev, 'c', 0, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); ret = -EINVAL; } val->intval = (buffer[4] | buffer[5] << 8) * 1000; break; case POWER_SUPPLY_PROP_CHARGE_NOW: ret = lpc_command(dev, 'c', 0, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); ret = -EINVAL; } val->intval = (buffer[0] | buffer[1] << 8) * 1000; if (data->last_batt_cap && (abs_diff(val->intval, data->last_batt_cap) > CAP_JUMP)) { printk(KERN_INFO "%s: Charge jump from %i to %i\n", __func__, data->last_batt_cap, val->intval); val->intval = data->last_batt_cap + (val->intval > data->last_batt_cap ? CAP_JUMP : -CAP_JUMP); printk(KERN_INFO "%s: Clamping to %i\n", __func__, val->intval); } data->last_batt_cap = val->intval; break; case POWER_SUPPLY_PROP_CHARGE_EMPTY: ret = lpc_command(dev, 'c', 0, buffer); if (ret) { printk(KERN_INFO "%s: lpc_command failed\n", __func__); ret = -EINVAL; } val->intval = (buffer[2] | buffer[3] << 8) * 1000; break; case POWER_SUPPLY_PROP_PRESENT: val->intval = 1; break; default: val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; ret = -EINVAL; break; } return ret; } static const struct of_device_id of_tis_spi_match[] = { { .compatible = "mntre,lpc11u24", .data = 0 }, {} }; MODULE_DEVICE_TABLE(of, of_tis_spi_match); static struct spi_device_id g_spi_dev_id_list[] = { { "lpc11u24", 0 }, {}, }; MODULE_DEVICE_TABLE(spi, g_spi_dev_id_list); static struct spi_driver g_spi_driver = { .probe = lpc_probe, .remove = lpc_remove, .driver = { .of_match_table = of_match_ptr(of_tis_spi_match), .owner = THIS_MODULE, .name = "reform2_lpc", }, .id_table = g_spi_dev_id_list, }; module_spi_driver(g_spi_driver); MODULE_DESCRIPTION("Reform 2 LPC Driver"); MODULE_LICENSE("GPL"); reform-tools-1.71/machines/000077500000000000000000000000001477621656200157015ustar00rootroot00000000000000reform-tools-1.71/machines/MNT Pocket Reform with BPI-CM4 Module.conf000066400000000000000000000016021477621656200247440ustar00rootroot00000000000000# name of the system image file produced by reform-system-image SYSIMAGE="pocket-reform-system-a311d" DTBPATH="amlogic/meson-g12b-bananapi-cm4-mnt-pocket-reform.dtb" # flashing the reform-system-image to emmc also flashes u-boot which might # soft-brick the module if something goes wrong EMMC_USE=warn EMMC_BOOT=warn SD_BOOT=true # name of devices in /dev DEV_MMC="mmcblk1" DEV_MMC_BOOT0=true DEV_SD="mmcblk0" DEV_SSD="nvme0n1" DEV_USB="sda" # the current u-boot hashes from source.mnt.re UBOOT_SHA1="ae53c420713e4eeb976959a07a90739963f07da7" UBOOT_PROJECT="reform-a311d-uboot" UBOOT_TAG="2024-12-23" UBOOT_OFFSET=512 FLASHBIN_OFFSET=512 # non-free-firmware is required for firmware-realtek NEED_NONFREE=true BOOTARGS="ro no_console_suspend cryptomgr.notests loglevel=3 console=ttyAML0,115200 pci=pcie_bus_perf libata.force=noncq nvme_core.default_ps_max_latency_us=0 console=tty1 fbcon=rotate:3" reform-tools-1.71/machines/MNT Pocket Reform with RCORE RK3588 Module.conf000066400000000000000000000015761477621656200254620ustar00rootroot00000000000000# name of the system image file produced by reform-system-image SYSIMAGE="pocket-reform-system-rk3588" DTBPATH="rockchip/rk3588-mnt-pocket-reform.dtb" # flashing the reform-system-image to emmc also flashes u-boot which might # soft-brick the module if something goes wrong EMMC_USE=true EMMC_BOOT=warn SD_BOOT=true # name of devices in /dev DEV_MMC="mmcblk0" DEV_MMC_BOOT0=false DEV_SD="mmcblk1" DEV_SSD="nvme0n1" DEV_USB="sda" # the current u-boot hashes from source.mnt.re UBOOT_SHA1="0b8c4d7ef564d79981941a972f6e8569cad3ecdf" UBOOT_PROJECT="reform-rk3588-uboot" UBOOT_TAG="2024-11-13b" # idbloader.img is expected at an offset of 32768 bytes and u-boot follows 8355840 bytes after UBOOT_OFFSET=32768 FLASHBIN_OFFSET=0 NEED_NONFREE=false BOOTARGS="ro no_console_suspend cryptomgr.notests loglevel=3 clk_ignore_unused cma=256M swiotlb=65535 fbcon=rotate:3 fbcon=font:TER16x32 console=tty1" reform-tools-1.71/machines/MNT Pocket Reform with i.MX8MP Module.conf000066400000000000000000000017121477621656200250530ustar00rootroot00000000000000# name of the system image file produced by reform-system-image SYSIMAGE="pocket-reform-system-imx8mp" DTBPATH="freescale/imx8mp-mnt-pocket-reform.dtb" EMMC_USE=true EMMC_BOOT=warn # prevent writing u-boot to sd-card because a) the imx8mplus will only read it # from emmc anyways and b) because UBOOT_OFFSET=0 would overwrite the MBR on it SD_BOOT=false # name of devices in /dev DEV_MMC="mmcblk2" DEV_MMC_BOOT0=true DEV_SD="mmcblk0" DEV_SSD="nvme0n1" DEV_USB="sda" # the current u-boot hashes from source.mnt.re UBOOT_SHA1="c643569afa1cc6f60015980bd5a73b7bd6329303" UBOOT_PROJECT="reform-imx8mp-uboot" UBOOT_TAG="2025-01-12" # when flashing to SD-card, the correct offset is 33792 # an offset of zero would overwrite the MBR UBOOT_OFFSET=0 FLASHBIN_OFFSET=0 NEED_NONFREE=false BOOTARGS="ro no_console_suspend cryptomgr.notests loglevel=3 pci=pcie_bus_perf nvme_core.default_ps_max_latency_us=0 console=tty1 fbcon=rotate:3 fbcon=font:TER16x32 cma=256MB console=ttymxc1" reform-tools-1.71/machines/MNT Reform 2 HDMI.conf000066400000000000000000000011661477621656200212510ustar00rootroot00000000000000# empty SYSIMAGE variable because no system image is produced for # this machine SYSIMAGE="" DTBPATH="freescale/imx8mq-mnt-reform2-hdmi.dtb" EMMC_USE=true EMMC_BOOT=true SD_BOOT=true # name of devices in /dev DEV_MMC="mmcblk0" DEV_MMC_BOOT0=true DEV_SD="mmcblk1" DEV_SSD="nvme0n1" DEV_USB="sda" # the current u-boot hashes from source.mnt.re UBOOT_SHA1="60ecf649038ebd92bfb6676bdf746daa30825dbf" UBOOT_PROJECT="reform-boundary-uboot" UBOOT_TAG="2024-07-19" UBOOT_OFFSET=33792 FLASHBIN_OFFSET=0 NEED_NONFREE=false BOOTARGS="ro no_console_suspend cryptomgr.notests loglevel=3 console=ttymxc0,115200 cma=512M pci=nomsi console=tty1" reform-tools-1.71/machines/MNT Reform 2 with BPI-CM4 Module.conf000066400000000000000000000015461477621656200236670ustar00rootroot00000000000000# name of the system image file produced by reform-system-image SYSIMAGE="reform-system-a311d" DTBPATH="amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dtb" # flashing the reform-system-image to emmc also flashes u-boot which might # soft-brick the module if something goes wrong EMMC_USE=warn EMMC_BOOT=warn SD_BOOT=true # name of devices in /dev DEV_MMC="mmcblk1" DEV_MMC_BOOT0=true DEV_SD="mmcblk0" DEV_SSD="nvme0n1" DEV_USB="sda" # the current u-boot hashes from source.mnt.re UBOOT_SHA1="5072104b5b888620eb6431eac72309e55db270af" UBOOT_PROJECT="reform-a311d-uboot" UBOOT_TAG="2024-12-23" UBOOT_OFFSET=512 FLASHBIN_OFFSET=512 # non-free-firmware is required for firmware-realtek NEED_NONFREE=true BOOTARGS="ro no_console_suspend cryptomgr.notests loglevel=3 console=ttyAML0,115200 pci=pcie_bus_perf libata.force=noncq nvme_core.default_ps_max_latency_us=0 console=tty1" reform-tools-1.71/machines/MNT Reform 2 with LS1028A Module.conf000066400000000000000000000012331477621656200236170ustar00rootroot00000000000000# name of the system image file produced by reform-system-image SYSIMAGE="reform-system-ls1028a" DTBPATH="freescale/fsl-ls1028a-mnt-reform2.dtb" EMMC_USE=true EMMC_BOOT=false SD_BOOT=true # name of devices in /dev DEV_MMC="mmcblk1" DEV_MMC_BOOT0=false DEV_SD="mmcblk0" DEV_SSD="sda" DEV_USB="sdb" # the current u-boot hashes from source.mnt.re UBOOT_SHA1="beda0bc7586667b30ca26e3b7464d48bf5f43745" UBOOT_PROJECT="reform-ls1028a-uboot" UBOOT_TAG="2024-06-30" UBOOT_OFFSET=4096 FLASHBIN_OFFSET=0 NEED_NONFREE=false BOOTARGS="ro no_console_suspend cryptomgr.notests loglevel=3 console=ttyS0,115200 cma=512M@3G iommu.passthrough=1 arm-smmu.disable_bypass=0 console=tty1" reform-tools-1.71/machines/MNT Reform 2 with RCORE RK3588 Module.conf000066400000000000000000000015161477621656200243700ustar00rootroot00000000000000# name of the system image file produced by reform-system-image SYSIMAGE="reform-system-rk3588" DTBPATH="rockchip/rk3588-mnt-reform2.dtb" # flashing the reform-system-image to emmc also flashes u-boot which might # soft-brick the module if something goes wrong EMMC_USE=true EMMC_BOOT=warn SD_BOOT=true # name of devices in /dev DEV_MMC="mmcblk0" DEV_MMC_BOOT0=false DEV_SD="mmcblk1" DEV_SSD="nvme0n1" DEV_USB="sda" # the current u-boot hashes from source.mnt.re UBOOT_SHA1="4d597f4028120c7c35c4267c9c9bb7d409741d55" UBOOT_PROJECT="reform-rk3588-uboot" UBOOT_TAG="2024-11-13b" # idbloader.img is expected at an offset of 32768 bytes and u-boot follows 8355840 bytes after UBOOT_OFFSET=32768 FLASHBIN_OFFSET=0 NEED_NONFREE=false BOOTARGS="ro no_console_suspend cryptomgr.notests loglevel=3 clk_ignore_unused cma=256M swiotlb=65535 console=tty1" reform-tools-1.71/machines/MNT Reform 2 with i.MX8MP Module.conf000066400000000000000000000016121477621656200237660ustar00rootroot00000000000000# name of the system image file produced by reform-system-image SYSIMAGE="reform-system-imx8mp" DTBPATH="freescale/imx8mp-mnt-reform2.dtb" EMMC_USE=true EMMC_BOOT=warn # prevent writing u-boot to sd-card because a) the imx8mplus will only read it # from emmc anyways and b) because UBOOT_OFFSET=0 would overwrite the MBR on it SD_BOOT=false # name of devices in /dev DEV_MMC="mmcblk2" DEV_MMC_BOOT0=true DEV_SD="mmcblk0" DEV_SSD="nvme0n1" DEV_USB="sda" # the current u-boot hashes from source.mnt.re UBOOT_SHA1="50f46fd2ea917e15165586c63b925b6a5f7103b6" UBOOT_PROJECT="reform-imx8mp-uboot" UBOOT_TAG="2025-01-12" # when flashing to SD-card, the correct offset is 33792 # an offset of zero would overwrite the MBR UBOOT_OFFSET=0 FLASHBIN_OFFSET=0 NEED_NONFREE=false BOOTARGS="ro no_console_suspend cryptomgr.notests loglevel=3 pci=pcie_bus_perf nvme_core.default_ps_max_latency_us=0 console=tty1 cma=256MB" reform-tools-1.71/machines/MNT Reform 2.conf000066400000000000000000000011641477621656200205450ustar00rootroot00000000000000# name of the system image file produced by reform-system-image SYSIMAGE="reform-system-imx8mq" DTBPATH="freescale/imx8mq-mnt-reform2.dtb" EMMC_USE=true EMMC_BOOT=true SD_BOOT=true # name of devices in /dev DEV_MMC="mmcblk0" DEV_MMC_BOOT0=true DEV_SD="mmcblk1" DEV_SSD="nvme0n1" DEV_USB="sda" # the current u-boot hashes from source.mnt.re UBOOT_SHA1="60ecf649038ebd92bfb6676bdf746daa30825dbf" UBOOT_PROJECT="reform-boundary-uboot" UBOOT_TAG="2024-07-19" UBOOT_OFFSET=33792 FLASHBIN_OFFSET=0 NEED_NONFREE=false BOOTARGS="ro no_console_suspend cryptomgr.notests loglevel=3 console=ttymxc0,115200 cma=512M pci=nomsi console=tty1" reform-tools-1.71/machines/MNT Reform Next with RCORE RK3588 Module.conf000066400000000000000000000015271477621656200251470ustar00rootroot00000000000000# name of the system image file produced by reform-system-image SYSIMAGE="reform-next-system-rk3588" DTBPATH="rockchip/rk3588-mnt-reform-next.dtb" # flashing the reform-system-image to emmc also flashes u-boot which might # soft-brick the module if something goes wrong EMMC_USE=true EMMC_BOOT=warn SD_BOOT=true # name of devices in /dev DEV_MMC="mmcblk0" DEV_MMC_BOOT0=false DEV_SD="mmcblk1" DEV_SSD="nvme0n1" DEV_USB="sda" # the current u-boot hashes from source.mnt.re UBOOT_SHA1="e99c53a0c6490fc9b8c361d0d09516de968b607a" UBOOT_PROJECT="reform-rk3588-uboot" UBOOT_TAG="2024-11-13b" # idbloader.img is expected at an offset of 32768 bytes and u-boot follows 8355840 bytes after UBOOT_OFFSET=32768 FLASHBIN_OFFSET=0 NEED_NONFREE=false BOOTARGS="ro no_console_suspend cryptomgr.notests loglevel=3 clk_ignore_unused cma=256M swiotlb=65535 console=tty1" reform-tools-1.71/modprobe.d/000077500000000000000000000000001477621656200161435ustar00rootroot00000000000000reform-tools-1.71/modprobe.d/reform.conf000066400000000000000000000016351477621656200203110ustar00rootroot00000000000000# otherwise kernels built with CONFIG_ARM_IMX8M_DDRC_DEVFREQ=m will result in # a system that locks up early during boot blacklist imx8m-ddrc # Installing the mdadm package disables the wm8960audio sound card with these # errors on dmesg: # fsl-sai 308b0000.sai: Missing dma channel for stream: 0 # fsl-sai 308b0000.sai: ASoC: error at snd_soc_pcm_component_new on 308b0000.sai: -22 # fsl-asoc-card sound: ASoC: can't create pcm HiFi :-22 # fsl-asoc-card sound: error -EINVAL: snd_soc_register_card failed # fsl-asoc-card: probe of sound failed with error -22 # It is not clear why this happens and the proper solution needs more # investigation. Until then, disabling the raid456 module will restore audio # at the cost of disabling raid. blacklist raid456 # the i.MX8MPlus module has QCA9377 SDIO wifi which is incompatible with atk10k # currently. we're using the qcacld2 driver instead. blacklist ath10k_sdio reform-tools-1.71/schemas/000077500000000000000000000000001477621656200155355ustar00rootroot00000000000000reform-tools-1.71/schemas/20_reform.gschema.override000066400000000000000000000014221477621656200224760ustar00rootroot00000000000000# This file is named 20_reform.gschema.override so that it has a higher # priority than 10_gsettings-desktop-schemas.gschema.override which also # sets monospace-font-name. # # These defaults avoid having to call gsettings in sway config which would # override user choices every time sway starts unless the user changes the # sway config itself. [org.gnome.desktop.interface] icon-theme = 'Papirus-Dark' font-name = 'Inter Medium 11' monospace-font-name = 'JetBrains Mono 11' gtk-theme = 'Adwaita-dark' cursor-theme = 'Adwaita' color-scheme = 'prefer-dark' [org.gnome.gedit.preferences.editor] scheme = 'cobalt' [org.gnome.desktop.background] picture-options = 'zoom' picture-uri = 'file:///usr/share/backgrounds/reform-mountains.jpg' primary-color = '#000000' picture-opacity = 100 reform-tools-1.71/sddm/000077500000000000000000000000001477621656200150415ustar00rootroot00000000000000reform-tools-1.71/sddm/10-wayland.conf000066400000000000000000000003661477621656200175720ustar00rootroot00000000000000# https://wiki.archlinux.org/title/SDDM#KDE_Plasma_/_KWin [General] DisplayServer=wayland GreeterEnvironment=QT_WAYLAND_SHELL_INTEGRATION=layer-shell [Wayland] CompositorCommand=kwin_wayland --drm --no-lockscreen --no-global-shortcuts --locale1 reform-tools-1.71/share/000077500000000000000000000000001477621656200152145ustar00rootroot00000000000000reform-tools-1.71/share/backgrounds/000077500000000000000000000000001477621656200175165ustar00rootroot00000000000000reform-tools-1.71/share/backgrounds/reform-mountains.jpg000066400000000000000000020424401477621656200235330ustar00rootroot00000000000000        8" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?.$p$<,ã}j0^]JՑ1d'zPw|S=Y%0/}ǜ|BTo}W))m[_sehW=׎VMG([>\̧SJHxitycǒmǷ'_:^'Cz چmK,?}fp_]g^39R;}Ad"nu׿ר*+h!<).W %nFw+/W|AwRm-?;iw=c?=ҫ4e>ɨ~97}wInc|GxNJVK)ċ(^Mj dszzx5|%c<0dV"μ?ֶ`|؞={Ht&#QRh&Kgk5;kt[XR]i_#uiY̾h@GXL4‚UoKH09SFVA:8NRF9v>n -E~Ϩ !e:yf52rn{5FJգ6=$GCPY w;ϯ oZjo01n/Ѩ/q 'fS]f^L2>-3T5=&-۾Gt==#U":vZ -dsqU$m*#Ϸh~OJ t6J.@ѽ[ C#}_t/Bޥ0:_7GSǡq3=7FY$?u}cm[H~xY.mۥ[D|آ1MfZ4_iAyIbNDϨ ⯬;vdl2!erC=k>K) qrɄy}ELgme65aMhi7%caW{m&vr yܧ!> ٵL}mDZ5mVĭtfυvc qd/y$j;#e^\<%#]>򎢺b:mu?쟭KHVğj+&0;̒sqMelEr:ۈΠ&-y\oFU-[l5ţ|rֶ5Vkx/Xycy̨As+եZKЭ1KV~{<t?W؟/m>ܱΈ,BOzSWF\ !~KڱOB+۾xQFffRr?ß^OLX=~|Q#X.jVLp8zW|)iMytRɏ^Z]l(HuWt@2)su5eU-e wjNсzܘnlM<n^*i`#oH: ִtZUOoPzZ]rNlm6꺻eؽ͹Is]{R[/dj_a]yeެFǛ'ir 9EjѦ 0_ME;d~USЄ7k };QM ۳F= $V4o"E?*kHhG*ᐎQvb>d?WRwME q{Ҕn5+K⍞h<㨡|.uѽ1~V[r@4fO~`XGش3 7=ƽ'|#≇m W`-YSȓ >ojx;Qfi Nde{mA|>q/#F ^N`z8@9 5dcn#ֶo-bϹm7_ӭ.o!WMH{cŪizW4^f?ZKN{DZ/p{\W࣫iЧ洞PcD|a+Vz / EsU۟7ص.[;2?Uu{iSgt_hOԼ#c-H6B03@<~Be4Fi4tV4}7p rיLj~<ؼlZdrku ,}2N%ԨuPLM4QgQ;{}E}g^ꛝ6G0Y25/KY/1u {~ FVzuZvi,Ӥއiks) _J=w&}^RlSRh #[^97, IkFL(N)wkSʰz\7oy3Dyxk7-[P7$^e[ee$r Vrw*:0xoY-X-{{^P>d:ϥuSxM֝nmdX<*:h2wzeˤY&4]2v1oy¾c6FGVGRU##ֿOMe548CҾ^Xk'5 ^wĉ&d Ts zdNEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPu—w;3G O Esuw<7gNG*hL՝<#V5߂5Bgm+" ?Zˎ{å|h*!Ϲ{2S9o6c-Bck uԀRZ#ofdWu|K9Lj usw fp>dA+M~mFY!sڔu{963 ^Ɨ>w/ܪcgV̨JV'+Lpι||/ZG:Y "Yt {)nG aGF~kk:})j^TV% rn !ᤏߞWך_O3@#~6jL\^sѵ'͌NO\?+3;Eҭ93xsz&~FVݔ aֺ}sG[#ܬrz+E2?v>^#Bzmu-v25KbeaZ2ÃAUO m55¤gU[r, p6ZPhn_Qo-"ǭzu!#F?+ {]JZNJ..9+n_jK 廆9;_b>)%mbN~GV Oq_ |omZ_ e0N |QmmTikaUX֮q PwG%/R̥LarGj埼GG{g%U-|Ayk3}X-sߊd*3{3[xH_6&_|XEݽ`e3;hi3֩?3Еk´BM [pz}oCr 9*˟5D+³^' 3jҹ3oP'~xIKȘOҾA+ k$XW}Esn$Re`skqgL_20 ϭh 5nTsjCĶ֮4f!q~ry1磯V3 j?øbľdާ'ƾC?CJsd##k \?% ?(8yyIe RA AOk:JͷGQE!EP\_-f]|EH7)Ï»J}Xa$zwGP~#uʾ, 繆= 5𕗃4,l͏I;|$o$VW$OE>ά2cJn|H!ck:)aEIR9⻿*K ,pQU|gdKKib %q^856WgϺ7lYKr=>ڴg:^;LIk#|ɏ!?={VI鷗InCg`㌞׷3Iؕ1eUmNUsܒ7|Wc)\k"Y8?ϵjv1($kPt#2[ 꽛[&2a: Hfd8CR#SlDGjԐGG֤ܗ|\q ytļ=hpޢw?H!{Vs&T*a63L(𜏙GnPZT)s/c^/w\b WpY@~RLlT|,[_F%qdM6@ύ|5G:h^&Bj#ױ~" 1N/-'^d){c^7x IhC쐕wž@I[nF?D4:E (ΏfK_Є/9%ljQѝ[U`z} zυ02+'[o:QgMݓjCK/.CK}9r!㨨#Sv [x^K[9Iib}TԷ5qQEk[G80Pd59ԑg(csSPOцUB=EV҈]o)IW;NPixH\žY!.KjܬO uIIke}umQw;d<,rվҴ"ռAkô퓪=20&# ǷR;mmMj_h8unr_0(yluJH~nezZOj~]V" zմ(~%/q^oxvk;,{EnWrE2jc˝xY .vykZl/T{c+ ney;O-` `ֱV."нΊ9xOQ^}I"MfX/yl9 Qcih]#Q=EuI{ I:`w-ʔwX(T}k/F2 =b>U,=>OA-EZMԌw'e 4E3]X`ƣB~#i3$wu$4n29R+㟍M߅u ^m=f{{E=r>M["oN|А²I[Jh9@.1׿!tYB;K$]͑ߠweJox&(KD2x纜{zT 4-Bz6i_.oEJ~1W]JY!+H ĺއRA8VW|X"i7$Sp$.(7eaAE|3Y~^4ۂlO ڹ>m沍[ ;粛Zv= m*~,{ˣ\w JZkp <=֚g--.ȉ]'d&꾞SRKyEʩWd>zƛ}GlǽsӮeCW.=ݳl1Zu.#]J{z{{֐z-3 Ԛ)g+WL{r6,X_|\-s'_96 jMf2+!bMhd[E,/#d|H~Szo"׭c1#zuJ Pǐ ?ZLJ6\dq\ҍ͓~9Ȗˠ~*N=ߵr%h/m)ud-{n.`J;cF Y`<`f9UWKnYnىYF8uNǮ@Y\We*!\m7f>B6K` hV\k2(Cc+m5.!p-qdgO]H(KMZKF/v/cTiޛyx,BGm[jրE.h?RΛ.]#w xSrޠ2/,~䯺J__>[?rD=>ݏz^Q.uk[Y'헎tŎDۣqЁm,p^R´׼G&M Av@㚫sԵi{s `>ָ^U`76n Wt}.Sg>{ `A=+/úCuyٟ a" 0ڋi\qfT[mqaTt&_0nt>Ybdc{5mueʹTit2Y=l2 k& -^Ӯִ+|LZ[Omh[P//Mf|S^_'O+mщ>Ŀ |@MW-ܛyc|SEy 7rX$4 kȼ;Xm1\#l{{+W5"*NOnʢItgUΝrr/R}cZ{x~8;N&n;  8=5: o39ʑڼ*,*ؑq[k+>VmxJ"s돭x:/sʓuKx` ;r01Xgc3iZ웭䷾ ZخKKKndW:T#//6./ڡE ğ2Z+ZA2 _H%/m}ᇯ^_> xvcFI.DrdZ?)cFwѐ4QEjHQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQES+mA"Euʪ , GPk3Z,j~GSE&JW1zm`՘4:U0 rߊ6{;t}H Xg::#I/?m&<3Iy{'nzg7ƚ:k2lPe=xKKDV:}sHJlJ".#Wrc2>VQ'mCǕ;R,Wl>>Z:|,>^M}3/i(b!\^jcRa'arU_8Ǣ_Y}w~ӐAJw扴%^[wi-G]NC%ܒxwtx_L]/މҾs)ZK;[\F}O^6yC[ʢ5#}ɬOZF@Oqֵծc;[CW~x:\ڮ vRWCa[dpHݟC_J$W}˙QtV$1k*~W5js=ܡJ--#Gae"kTԭ.mIEy<$3Fp:*嗊cd(US5FJk&MIR?ukz $rH7(NXdev=wÚ-5nߨ=+G^8$`x ;硯zIk4Hp趑a^_]'Q^R!LhWW#^R#ܾ$wA-oR%02&QD 5{km#Yް'$ ue 'eXb|$[#0#c}F5qo\"wNx'U 8I] ?|[~OoS,BPcν LGaiqk&r#B2=0yϠa'1|IuXS\j^+581>= sԳ{@QKm$d'vq9]J%G4B6yv K vh*sW%KͨڝN/=?_ʽ I<'qxC4Xv99$`[#i{Y^OE>V9$N3IGCI*Ob<_iֽ/Ŗ0{ml9ž߇OʼŽtq5ST߶Ebo"sy֪Yc(yd9 Jc "\ žxz=u|WGc {v댩 Ll<hLlvJf-2sZZeCcHGA(R$klnm8=kxwSc[g?:z~DuC.YH*GqPs ںxa Dɶ'W3.z!<'')1ߎ4H%::i`)+C\2:-Oi%\[xzHTmI#׽?ZG~-'iX# e6qOYNϙQH>}qNy-& sFЊWGH|sGj IYp0 c ̎}oNjwf\jZwLE(%Q 0'.4.whH΍n:g+ kNO6fBp~[@5+5Z?z ~4xjrCCYqcVǠ$״E_0r @?+]kvjxw?i(~d>?*xkv=R ]h櫲foHՓ?޾0iZhҁitٵ J~=G_%Y\}xDԾl!g)$x(pTAԅɄ~^Zj@*ˊ=euͧ+apc[o _fL:yAko⯂#g"Ľfty]Wu-p+;Z190K5ǽ|T!еV1J=Q%4vbv4!6pL$ruc3]pr+PU3wN՞.g5"F`2j(m)qqqk/[uTg 'p6 n@˸;mnVol2Yv0#S,|.n@̲:7pi)!y󕘬rNzTh幰fP??s~Ԁ c=}[&2#YqG4yxts78+Mn;n 98#Iuv[YTzT^ :z9Xۢ#֑Kvɓ{#/HE +T ˛7RnRI]͝ }XOYRy![s(;],G$v+vi5$b%,(zqY!nE`;H?+ Njƭ~tI'vx5WReTEbY Ri —Wg)+ykOtbkWdjtIKuh>!{Js0<4DW+iCݐ^xɍ~>ξռ9l[b(G)^.%$ l ?rGO$ᑣJH+ GPi|TFIK.{w+Ӻ!ES>{ r5lEsrG,DIxHm;NqR;~r ҳYOaQAlK18NX.iň2eH@WNP$W!:zWG0 ;X0@沖"垕moop KTHqSY,;pB ձM#U/Óބ [fF>t>i[Fs7s\dqά!uU٘`Z'8^jx9NWqP9ttIwgW¡X}*E8Eo0:7K{>9$sK= ֬Kν9^;G!@ˡQt!RLxY>gNKC3?ҮE"̥!(Nj&]|硩'OcR$p2;(=Sd^⢸{ d^Z1<wNV]AEJ ]lM՘m7/8ר \!ow+#mɨstxUdd=[F7˟+\DhH'${\xw᫣{jN.Oh&tݪYjK#qhZn?w' }|ӮxR YCv8?κ%fѮ>bXga}RZJpZ6Cģ{ VYmVF!uړ0_ڼGΞ<0 ;zk2O;_ zr0k  @m'5'uKTnqWxGƑkj/~'̵=5xS0$GZ?eq?re~ubT!]EAsTk <%$zx=28%Hkpg#, tB_&g =Uжўumק0v\)Ev5 +\2OXkQ6L~! ZĚ8gkdttl/Z#K58: y?+&rg79z#.MuGa7XFJ=GOa-(nVXzcZMLKWކ^,-VAeA0= 83MŔ=^vx7M34+cZZŌA71/ޱ#b]:9*O[%G@ÂhӥQq^;+O~N?髯[k n)+zÐ[]l~Yv[%HMA|yhЃ@m x`h~)qc+1g x>z)nծdy??cc]'hǿt|]ͨ D\(%?$ݰu kITZ8N$U$ҲMyQb,hd( (+WuxMf١}mF{TZϦݫrteUel#m ԀJ޲ԶI0wogEF,5ZOn`%٩[ěfp{*/r;LZĻl%Vv"h"93C<OqU"%|Jl56H$GO{L|2i߫^Lc3c*z2|3HMs?w5 y+#CǚP&m:m$W;驱mBcGV~:5m3KLPxFsPGj5]&KiQ0wi(.tm*m1qnEf+5}pG48kdў*Ky3ydzi 'Ӥ{4xaqlpN뮗5ETδ~swR+ׇ Ju"-u=ʓ?3#9ٗ~ ;mvI+H,G4*Hmv?LnC)ߛyVt -ۏ^,q@f5;( KiX)27Q5m'VVyW^zmn((Xju}eQy}OױcԼ%i=%͋j0,UJoOƼVYꖃ.XA^~: GU|,v:.gq$RYݫfZRlfطOx?ҝKGh6pqW7"ݙxlg)"Fiq'Fa>ajdzW@:㯇)ZKe'H`xI~^K-v`4<* ۑ */gSYjZzk-փ=/~ ~5 -O!ӵ:S@}T{W-%ElCꦾ]4sX\d=~Z)K+(AU?`Ú e4kJIo!SNz?*|AҴ,Rn|؊,u뜩-C6Ri FyO_Z[y^UO֟u PIew)?[F} .QVm&Bn,5 YlmؤLY!EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP(g6} Ga[Πc\Y[ϥyd{y?T>"%RK̓)yF_c||%m[Gsz0=kγvzl𦻥Ow7bEW`LRBWeڿj:t1ՍjPȚWšzomA1eҿ_/`MNŕ*AVC_ -<)YdWjd[u*0?0_n4Pu!T2<Dl#8{<"}wd}Lc}iq5>jo=pTנ0BbIfyMEƮI-Ogύ^LvY홼. WKo%]b+úxsTnԬcyP9 ĖOi%]gEsmRk^Y X\[ p ?2=`k: on p~2jm 4u:o |T-Rt7\w"knn8be&U"(wdOKobKh%Kz ^z>YcxG䕓|?Zw i,e쭴nMiSۜW? m%HIس4[aq܊ϊ?>CA/M>|ɘsu8Wxt7—$(Q,YN?tQRKZ)=Yk O;BY,K88<=q^ /cL6ZD(}1q޼^"Ų\vf쁓\x܏qq^0JWgIi-Xu5ܠy 9T.b;Ut=S\dR[A=ifMJHԂ?EEY([-@skN5he1G=@Rb_F74Be=OJc`#G'g9F<F<ԶEz%ymu]}eCS_Jnvߥt^T9NĴuǂ@c(^'ir[̻$Gҽzsmkf%KzZO e*O0}EGɭc$D/9uɪB!L sczb>b &c=|vխ>Hq*0 #]<19JcozWe#5eD\yy>(x°[eq (F}͍#P}Ϸ$- `UԩNc^gMލ,zp4Q$r|Ϡ=+;-JIgDz!P0?\>$/-['AG??6NfͫϜ M+4RךrGy?L3F;m2.r+Lk0çunA]Fl׫$Ĵv=S^2u[MkNr.O̙D$?_o|wMN:d{ _n~X۱gOxi7rK9tָjC_oƟ"IBҔGz?hq>RZhkLHD#Zh&}غ.GMJZ9^bKl}hQ\( >x~sYC$r/;gAMÇPk=+8c}+IkbEKgwT=U_— %&ۛY #/|7DZb8W@jO쿥x'jWڝM8& dcz#^- 2Hd}']&k?w%s2ivXXWub9$W絎ŹrsȫNT%gX][ȬUiM MU*85ٴ `fjcQr9)XjKUxCӮAb:mN{yjkBx M%1eO1mwkm}|$ Sx?ʳ)cIbl93k wg$*|1wMq^ &U-ywSPH0}GzC-p ?zy}QM@,#/R2L:ƪ[or^ԇjE~0 í 0-%_iU|o5H5F{Qjwφ*{}p )^ƁI]\Vo[8[4;E^=רuZo!J` 9Z7?"O&] #iDïTǰi%z?eQz+6WK4D9e/ŨWgB z?^ףⲪ踖.QjFei]#[Vu>e#n[O>A{}x9#) ''Bz;NԠB2 / W^5,lKqXy5w=~ކ{VEMهC@77:IZ4ՂnQ~%!z'5!d8o=?\NCwh}>jjG]ȖWҽƐ/bt#ƚ3Zp{0#}|I¤T=&Dr~7s?`5$3˟. / $7GvL!|;7kbũU2HUރo~+nt/@cXul;_G־~_>%oNDλcok{mK8^+ 'cq X\>oZo6Zc5;Ğ'ms,m7ryy[\i<׎Veg*5OW'f{v *X- \oJ.^ z3jpEao+$qdd}$-:l ּ;h&<{7tύ>t!Aw=8=8 9* g "SZ&Eڦ3$:v Ԃ9~B }+EU.$ǿEx/tn#!A{\W:Mޘs^%m|0:RwԨ^"qk9<"Ubpͷ j>x^̲O 2@ӯOwFt+y& .>] +C7#F5Ŋ#c!HS{fz?bMCD&v NHbh,;.~`\W_m9T\ƆeI-–U 2@Xem;V6עPe"@=)찌l,LV|SV y`PC}r+fZHbb=>v5,9|a!GS < tکj5OZZ?%]W҉y,QJD cj;GVݴ r)VGgl:6FAJ#1Ck[D`:WEhehXfD  rqݢ6K#r#i{ QW!֟3NK]V# z*--fkxF|ўǸKI,'V哵 P>lԾkUZs_qe}NdcF$r}+>#"4zj}ɵ04R^dnGZ:Cpk)Kr}x#޼%K*~5'Yֳ`a8x5Boog-#FXl8B9![mu+9!h4)11|`:W߲fXǫY)"?R0 \~SKEmbO)Y"aVe9#6ωhQ*6z _6b^7G 1WVFU}AOc;XJ(@sK@Q@Q@Q@Q@Q@Q@Q@UC#|D#WN.G`j/y3AtS̻+e^fu-ɧ3%͜2 w`{i)QEQEQEQEQEQEQEQEQEP$VfǠ<.n1qGpSKi!9S`ӽzW#x }R-_}դ hKGkʗ$?J(a4p:@NFDm>-.l-~=?_oT;|a^Ml"[ jO}8ċ$|iid?}{_!lOjZ. c} C,mXc~a_d`:Q> J<x(t4衠a]5ĺlo&Ts,7L+@F޼Aι1H9lޢ>RiW6wlm{mlU7ef${7KVhtJj$z,q|ӡ65ϯ|{R9u4vvs ӌG,m_~wߊz<h 'ݣcǨzKXFOf/~ O/LV Xg$GI߅?6{1)8’=+K_'Ilչ䧱3KKO^b>--S/t߈7q7G,##T5Nu +K>Q?N?H/&B^;Xc9P_4W?.--ᔼ6O=7_ IT=I&}|y9㶼oCF~6_</eI|E|Pg;C+_z6{^,}Sk[G5> TEHH$*~RW<9]?SJiC/>[u9K]5nnv3ŚLj+i /B* u*,2)FevCjKm I{զ!i [qc׬V0:6kVeud㊅!K0mw!qSLKڤ=}kCMDWifAGjxMa@OR2#XTlN?z^> G NT,֋a,@Z+*{+ `'9:Vy$*z Jd :ԭ@tUkocMGz$Om=}kWWщBLНNM϶Տ`=׿WYO2O`CUPlaqPF8kS\6;sbx9㏭BС3d x'ڴm㕓ְ~5jJ.-ub84429"Djj"kuwC66?3< U$}6G]L vn05w+'JYmT~NmO/vt}@Z3Lr;]TDF?rhqlОTU'eWzӎb\zU,2#2HđƬS,8j@LaQ/ 1R|;J)w1Mi4]It%-={STQÌ>$~Ui|Ekj-6u3(0ÂN[v|qx ~2ˤ'WcqXn&ljZ({{Ҟ=muntQ󌎹N~+Μ9Ys#32;[5qoI-"=:ͼ z7|*?ti ey-@Jua/^ rl8'S^vAvY#nrZ9lnMC`i~|<\S#uQjD /Sv/Z\i8vO '?LP:f"Drs.qs;bcSh.R11dy^12?=+-mUղՋƱ95w*=SZ_BZ|wS~ 3iveV%5o& >X6{ ݤkw"u5= >_$+\ɻydU<}0{_j~TI}eGN,@^@)]wD5ah~˾wDq9z,' gBgBA5%.c庲$DZ\W *;tSb/-%,3Bs:D29 jx.|]~}(O`}WVq@:_[É,fA}k'VՊ$vҴtMyf2+VN~]x.#o2S 2+0Tҽ;þ)o6۪~`YN c\k^0cx"xPIiϊ5+Uijv{+>/>[c1|WXG45iAt$ѵM,1)b{h:.\LA 2ã`Ǩ5Z 'l t[s$Hynnf0^Ċ8%>?Z s P@:V+6AwS L98>%=_o^Y>s08U[qpJ'8Z|f WГ"M:!!jH1ZAr=k>^DO&zkŖޘ5֌A"ij䓼f+/L2= k8EW U  w'dɛ5$$' 5ZKe^ GCB8@ce}WӼUm摉b?QqDr''wI܋XIa WoCZ^۴%WςB$5MH0N-Iy=WuXcMA?/c/_Us)+0Z5hc V<>.ʻ^YOFxZG#=3p*kIcp V}{\5.G%'ψ!#VOۘt.فL'jݦAcunw#ƴoD:gnb?MOJ=BxeQq݈V4#W\m3 8>cpv˸CO6Mtno*R#m(r{~T)>W=[}W7ދ+s-eAww;׳|ǥ|_w֎Fn |~56zGm&h IP@a_5Sf#e[ yl{G5x\kfɖ. ot =L~~ ~1kZr[ 8_. u|WcVZF$F-NJ|!eLzvoQ#%%15D%$| c5 frn+t"~ׯ}cSY]0Nd+g|S6iդDpNUcLc|qW+Cc c焟g)M}=q\jGxd n8n!3i#B߾&LԎf[oxonB$!?uXM UDl^qC4{Ʉ0,' <|5$V Z+վ!Ol2I޸kuYZl>m+_[6qlP=k{G֥`(î;{N>{wep@'¯xSyA'7jv8k~ =ym.~:[#U?&xS:&"ҼՐݥ}kF[ndo0̯qi8X}5~!дXғewnNLvn8a~>/^u)%t]<ܲH?P~^? ik7<p<ܧOSoY]Qdں0N9 )BM)Z!m|CAa2\.3jջǃsmaKῴkrl1U0}x5ta%gcT-!5OU#(L.%Bz6\ڰs%l"0>/5f@S a*N1Z=ޜ5?[VwV%Y~Tծ[nky ʲ&rɚ71"CP(cږjhvKAp0"k̾!|3]m; ",u Ap`EI|x5+5UC6۫׌9-[Ҽic).>jyHa0E=VzEauu04s#$9!8'va32`jBRYI!_m) =ijPX<.dLwaOAd|]OeXZ` p W8W9;דYXWqZws)0!wsrkoY?F]2H/7B `kh5ok:ω> VFaJ@E\edKZ<'|'7qo-AX-2@K930>zWV]Ղ(EPEPE?}>KO!@Yp{M\79 ⟎ఽqw4'n>Rwv%Ǡ5~d}wPP3TI|F;>~=i1H]Y;OP9' IBOZɷG|Ne݅ŒeY%Ojυ \}DѴ"vB$QnWU-Ȏ*I}+(hMnPhȍA8xQt? þ|2GJԹ±ڟ:R70QEK◼Jkh jT ފV*;~+l`fX溺d2Iy<{s~U4:6!gqj/xKMv.sn24N> E8j&~`\Kgs53#ATu_çskq)]1-CIךRwW2 (Q@Q@Q@Q@Q@Q@Q@Q@Kdu 2zỳ15'Mr\Qz_e1cixvqækoSQ59_S.f;ʑVZ9QRJ)wb'LHw+n Zpx톥k9HʷvKGad9:dkrolF Ƿd՝w?n@@%[zW~? RIlʽ>gW|%Lđ{_O u6NX|=FR?338gNWFV?/l%є m6tpscz?ᇎ5 tus->WIǯ^>Lk=kJ]hϴ;O U@߹V^Um=,WmX!-]BI :eF+[vz'[LKkmZ N?z8坌+άڣEf + zxX*K9\Jo~y k?j,b9ܹ"rYeUz,oZ Nڲm$gY4le1 J5[2'A:PJO<1z" 1=vO{X NwWݳ8+k@'M;렺yVFYIp%{'w_dInJirZ^\#OojupG͞`M^~֦z -ӽ@=]sqޒ`^ڄWeħg<VSҳ3 :Uѥ{H-v krI5c9ȮH,`nU u?H-S"Ǥx<>c۞̕CӓYwdkN|]7걃J|1~v8*<~o<6dCXr#^E;ĺ'qk!0n9@x}$Wc'85'X0eh̗`u z\ˀ$|:^o{xlV038iK@Fs: ~ܵ؜W`iᘅϧLڀ>1=o_s*ڜ`oQߚˍ]K7,#zRK)K1; hk պ*ش >o,zV|,oj hOZ# 9VdSyQ)r(O]WyL؍Nj7 i#- =yh 0ñ_ߺݝӦFEI .5 vңȓ#Һ^6zc 33@Qm`&i h²gP;rrT)6!C^?5{CdA܋t5\6eW;V%waZRI@5gPɹ;KvF8V >as?ȪP}[s;*Xo)Tۅ3J G)"H&svϤ?fkN _R>iENCYNEx|1RV+*p?&K~Ȕ}͏xF5=Vz߉m۝ RQfpz0e'~;o냍?Y31%rёjI>O4Sp=UКK`gx@lB6W>lXPO  b߇Ᾱ.,@{=ju{265{̟] Ɯ3B2;|^;!#j^o)mf/$1w$w)ہ[SʟUw}sKw. #ǿkF)AD'ޫ]1Xy5,gڲ׌|$w6;ف`~&YAQxE%JˎFh\^rrI1 F<29I#y>>U.j'Z;(E*T t1WlBR[yu)-r8 EX>2zP#a<C[~\ߎ|9>xA+"Oc> Jck=I_5_}FL.\pXd".z RMmmHK%B'-SⲼC;z$nn6AAEysxSE> osNzG.D:FK9{>ezνV]zE5-nk!4l$0z[|J˨٥ƣ+/ 3׎ z߇oBK7PA̽=S}R2>eziX#RB%{-lO)xwz~x6 6kKUGF|#̞/tYQ6чui-֌MRѮu9W 6İfQTϷ־sG*IlvgE7`A+b=/PSk:A&Hm(O9|Q&mqk5W o`8'i|i2ZBnc_n_8SB?j; AxcɱVh1\+_IisXX}abZT72A9_n:΋4zHw|`Hh㥈Lo5jʷ(߇c)6A$Q &'yiz#2$_iy>4i1n/'Sk;Xg!5UWiӻ/h>K5 H,pfydP!][qaZ'o[R<:wIS7 zl.T-?@= Oη${,uC/K.ѦbArx 7֭ǡ?e{ǁ-e:}ԄC|~Nz}q_e}.b ׀] ]vKMVnm{3gۼ}9;~[Jc:jZd쮤87̴fN>V}Nu(z{ޟ (vKW7T`WsO޴NcrR#捻U~柃#CcYm4%W?~#rދ1a**$ZVȵ"0R8 p$fٝ@+|OEEڿҮdFLM}U_[gK9LWK@} }n^X}[ `Oƙ`kǕQOgwV+:3MkmE=o$G9[ ~jp|=y^^Z4$A֌Zȼ'0Hq;} fzW hvOuo'vSD:ْ kA(W#p~a=_N,mB/ sEdbGg)$k[w֒y7ߍ03X#zKAș}]z5-ϔV@#U$~w"fD9aV~g3j=2-m߿IM'-$QF0?,V-v\\֚i(VBTOPqivW&ZǤVp`A~S]ҵ%#v/\MwkfF,zoś+lIHum#P6'qTvl}gZ7i"]v 963ױ|%okֶΚAsB}^?oYOqTd{vkpJ=aR]:9c/\dBOM S? FT5x_o~"}(uoRC[~u__yP KrdsY}'hQ0n@=+Z׋k7 ?wN)hX4gR=xnZ~ ՖFf9y%@֖iZlO4갨XƏ}zPҠʍt\\|se=FY99z4GCZTk2ZC|xc^QqIfb +Sro橢xpek7KKv7j|WҖ]DY //j#(UG}Ik?`:}c 'bj~kymqf& ,PG@" =tz&Kop]CcSv[&zj+Q| ߯|u~_C mƅ63[N@+ԁz_UЭu3lGSF5k3CvtMdlnqT&Xn5j~00UǷJfھu`dwk"+Ît55K+7i_X@)ZQG FPg9ic ~~47zqO^c3 KOE&{iqwr?zq5"A3*Ei K UsIj+#؏][i } @;6Fa'V+hk֚y$6aD@݂ 1|/{;=-^+m8 FF>18䓜\Yw1\z8NtAr#ud[:M)wxZ?ݴd ռMmk5[|zx#=@k- '9dēH1R0ŇoQLmZ;Y/ɼ ><.5+m v!146Y-}BKJQ.G duN9R3ou}?R}.F[7R7:qUOkzZ]].HG$=88+{;Vmj)9e9#޽ŢԗQq*n O4{%mɱHq5{eqc亗@'S^Q>26wVť 3w?'3tڵ2\+,>;sۋ{J9U̵Wv!T2d?KMSE-qk;3mZ<ӹHjot#1a$5L.`ǿҺN֏6i&rs LnJ*[i;Lܰ k>r'fNڭYꍼ ze >4+_5 k-ORr@>Iu_|D&W:>hַp.xt?ħ־ߍŽ>"ϸ>zתx;,7eKZ<9qʟQ:GMszz}V n\+ω[RA ARQ2kς5o2h~}k!Rs8SHuZ c29 [u3G>t5YABR`jp q7|]o:}ۼ/m6noQ[c췞or/_-oOclgw)W̊Q!nGz$&} è \6@nV傓uNծIgxȃITSMG-.Yʧ -xgTEg^mɓz zU. exqq,i0N8үX\3P +L7:uWRXw&㦞9m.bn_q*821Bvbjzf 3WYa'p[Zemu$[^c iCSVrsjNsʃ\\]ܤ|:{vL7?w::8j͔ps/H5];veM绁"-3D!ѝ}}1W .eלto8l8jٮi>t3ƺnؿp368$_A~MC?m0vAak.JL5?4{ï[x:~hц#^jV `0izĞŏG5>srUGD%8|yXdKWHsrg~dvěOG%` x| zAKg8_8¾4=?b3 y cqUG/w9gk-IdDϨ}{_lWEƟQYz|bG?|Nѻ#GRC+ {*М%H9}AJNu{ż 6$4Rm۵SqRWmAu>ǂ=s\NJmM ) Kc NjilsQk!:wݛXdJ 0Lrc3[7o3 e#a g{c;v xN$hz ڳY {oc>zW:wUCf q u?5.x3R[s K&ݫPT sl|5Oq!RܞUI!%c"!$I9"-5Y<ڹ|XYё3]f 8Orb=?s8/[;X[LF 3DGQ\ti|2cvVI6HJQ,qp@?tǷwj"lt;?'zu庋eFa8Ul4_Z} f B9+QgqqOy4Fԓ_[xr]Ke쀬/&zn6?CWy_If,,w;'12=;g=km+=mB*;Mu}MNwjFFkS$rX_=Sw}*0"+Z40h̜dh'0LJ$%- =]N]?P`JD`= ;˗ƀ9 =kºtۨ<~k\q9lkSC[18AuF2:cΛ2iSq#M›Ӛq*'4nZ͑}W{F]cR'9ӷW|.4o岐O#$q:b{~f^.\y߿ocWYMy$cuYo''ްth3R;PňF 6j:kywj8ݕ}C~iu? J4?F%B}wZ_A׶6ڤ-P0N:}k2 0kŴ<(t& B*hp|Wjv]K:tle9;}3>ZM9foy嫶c=xnCKT(IU!fq?%F%B e\My)IG}i IπyqZuS 6 ꆫYEŴ9vo aRChk󭏗 ꝍY.lV́r>pNavaށ^'}緹\C?y:;$K0cWkr7^U[=zHnbWWNGOG3v$I\+t=@ob+&j_03OܝZ{j(F2Tx{҆#j ^DHJkJ+4`n? "CZS2`9a@Ρ4K3\c<$TO!zθ[=Bk9F VkϨd-U{ސ4ynwH2Oø kuqa[K;)֧NֆLF9;:qEswze<Ǚm_?|go4[BdHkkK}G՝_Dl%hљԌȫY.7Gvd[yRV- w\j7{ 줊KC)+ϑqھQO=4 t+KTg{h/G1TEz?Yj4ȍ'&"HWyf>A?{R`͵F:T2[;XdYerQ=R>W9mVd't<?ʾ)Rh_V^AJLw2pRr?y =*嬂ʘn㺟qګèC![UPFd%PGFz2N2Bvzƨ,Q*<[V}i قQxV :{e:rؒ=jKSw-&5TgWy ŵ76ۡđ`־R&I T|z'exMJx#B_$ıů9󓁌{".,Uz(_zKOٴ=Hhkw W=vy7tX]IZ ~ПakWtd!R.ɲxǖoӊuDӵ"k{ ʴrF7OR9\rJjjbf$dxfޛG,P Of⽟7{퉌M2ZL_+o LOJ"ԕN W~ Ǧ^=o^N=; qa@{ǚُ5o ڷJw9` pI\>_"Ouǖ/hݘ}:nZ^+=Vq}_ 515"I3'p1FEw>wjvnųh;W# zsb+kRVk!'SУ##ֺ/|eWFdKdo 8 g r/ůCk7Ķ so"\@oN}}foqJ2K3^I` a5i#W ~Jx7"f\nzQ\Xj^{P&b/4$%YI85,ͥ|LMOG" Xf 8~jԳfeN}Rj<c?m.Yg;9У"05qjv7Rj~f?ydxC烃}yr&_>3: i:n$m=cGC4f?(4J8E2 x{ei9NƩ?x:F#6T8#r_A pp3ZLKCH9DH GCEV, 'yTq]UxկȺ̨W|ڴR6-8Eh+c92ˎAU_]mv2l{LV!Im\] %YbTڧ-4Q3,=j~yQXEl 8kPOBhSԢw tOҺjxA5vգ |H5? Ѿ&Ieݺz~56K9U,v$:#MZ/߱h_jĤRk:` znt5h%kw*Aq+ZNwlo?ʹO|*?Qt)cϏ)==^_[U3kѡ m+l8k5Ηf- ;]ǘ=v q"~ xN[cAvu'͠ 9a<֪m+"ySw<&#f#ٌR s>*:iWqkZl,_) 2?ϡuem&()&B;< ڞ<=y q<Թ#߶kxR&:5'f}!_մ{[ ژIqUqXwm5SpŸE4{tU(ISrAFq_MgYyY'z?AX8ѤZ $ֳj,^Vڎ-ϱ+?_׵ \m jIbm=Gt7wĭmag-:9lzs\H5['$Z 3[)=+ xZQٮ-f+i96Ё{q_[x:ޓu{ie"V }x5&i=kzvi)oA A\Fa?###WL Pta{W¾xHff;l,هc 4?r'΢`~窰O}-; `~/sxM!6aXK:5F kñeS_lac]vܧ<#:ռ), [JO]0A7C^~#OHTA_XW6oh^-kus յ?׸a׎Ћm:߄c7[uŷ3b33=nI|({֞[x˛N__?:ړIZ#pc_@Z $2+ k9EM3?Hnmȇ Uf+XgkxV) Sڎ9QMQ b}Ip~35)Rax'#/ كd˨.=ˈK4ҳ|ھR}:[hbc([Tzq"X"<{sr9 tZjW Z]+si7=GW񕶖M9Mm67\իǬZ,,2N:84̞|X\=^'&>#G:Ic5V|7ic?;'Dt8Xie|ՎX#a{8+ݵ::Fxľ.$e-`*=e?|Cj%̧lF0aPG?ƝZLzgl$8S>khhZkpPySIf BF XI3I;#/.i:ǭcMg, '=5O|3(uiA9d$8_!ZZ\[y`.q*{Wm7hnt(~W8YhLew>>*a.lX@?u{i{ N 7 1U౗6:*n zz@+xn[;O6m)T:Bzlne>Rm$ ؎?7IԋG.;y#݆? low>D4Рit VB189e##ҦRs#>x+HeO)8,A+o2~(h¾&pqC/N5Lw]grV)BU_J?%80x\rS=l4l֥A=1{cھkm_ZxI#ȥ瓍FLvqgkgic~?r>-LՊ˥DtFy7TZRqnW6PqU6anz^Cj/|[tv jΓ{u ?,WE"ϧC^]gVv+<@k:?spA\Tn-'׵Y&Z|Z\yWǭfO3ޟk6ST˸u2z&iF'V5tRGp7p}j[Hgq\8@11mڹ=9 $V8`A5afqZh9=G{rA:䝮qҼ[ J5z62rQ\_֒L. f]ac1`v'vf5+B d}랿K 0 xD^JтsztU QJշkayqBL9#ƝSA1WD"1I+X1EL㹮y+3drFG0xV89#`j{O#Ve31Tc}O w/֟Jrzdqu^ŞhۆV Ђ==+T1L%f-ovNOF:~m[ X<)ZSiKpqrvLCNCzyߠJJeV 7ەaTn|Fr*H;9YfuᅰPU2,dM#9{nC ! Hp6~sDWt5w!LPz&`͜|=IǨQޘvWɌ M}1nxw#z0Q$B&A vY=G\Tт0|D]+W`P4U7HD8!^c6r=og8W ?NV(GˑP FSʲ_ʒ(:+Is-UtV?L]\jmɴ )Wԗg~WvrK(~~rq^+|IKl@1~FƹtmNVv}O1>}os լ$mЫ_|y|6$t *wW0`_[q=% K`DmD eY׏*+>fGQyƟJktDFw "rJ GPpGC^Zm;/x{&<Kxe&cljSĖmuW>r+qD-W\ӈ{tB8c^=LŝLhߩ`֮^2JZXU;U., ~ҙi:.wG]ZʞMJ+H ?5BKl1LPQLD8L=nrZ-y;\_ʸ_$oET1>+1I&J<^BOoƽHTtY` c%x\ֳ "-N"o },>#WCz ])W!NdҼ_c >9&H.Y8XW|KS3}fTgvk`4"wVpNzڱmɚ[hk1b2.cf:5n<$-ےrkՌ1]vWuI ,Q3~nF$$t$t6 hE*`Vo/Z+1Ϯ:U۟?J c ]hG9*.r ռ}usb۬Drnd8$ӵPz|[A% KE 7J,p3ǧLFep] Cz1vX 5Najg#88*oQ|iw`akCjc@܊{ {IO>^g]N+yMON0𲎸<N+ȦX1A c 浴}]-B ~` pzبФ}>>-驫i=⥈LzoNA+G'^!{Xm5lS J5[5O|~2њ3>&kim=r_x53iAY*y#98a^ V=.-NZ#@O!O+0kb[п;v^F^)Wr3ҴtG/o,>ͮ 5Xr?kg|k*=xmb~'ST=aRR?JX5cDJf+RbH1HyhZxL%)"Bo fӥϑ>2>޾*|;c&m?Qe@G=Tz˕(o岕-7.A^T~xV qҾzZFf"zC^߇WkЅE%#PqwBVPCw}X]Ą6kό|m琋g}?=hjl2Fk>G̵7[9^/u:v;m^>܁&2Twk`{V]ͼ Oo"QޝNϭ|xZuq$oaBv}+nTN'hD|EU&>KxfZAN3Wq'mGjj/ixW[g+[ϩ"!5Qw\9}}d$J}Pk𮲷P!oiK Q鞔X=c^yj1%ŭ`?B=wŏÉ}CBDwb#)KVi-ߔ?s÷WvsK$Fãu[)Ȗj-*\yN8O?xii 򋐙bpG+8c/z;*;rjuʶ zQo91W= ^xkPk[87UuҰs۾*{gx63܉e mGjm/ybrz־ ^ )HS'q+χ?m|Co4U c'ub $ܯ*-XnT8&Vl sǧU-u͌zW#H/smڔ_kb?h]XfoR83NݻZ->HMo ]\@98sgskcu˦K³VОֳΖ?Z=WuH9YAA3>q?ixlhx{q;WYqWq=lW|$c:W1_RJ{n־IhG;G/k; _x_ҼE >a$g*F38\ƋxJ6թ7M,w0J3* פ{h0*ȥ#{>+KVHmTO΃*.;^v Q8MȰbe@qӞzWz턆R!Gᕁ{h;5 h_GRnlYl?wZ|Sj\ymNC<ʱFcp0UM-4>t6q=>w"ǻ_ŶmxYi5y?zd_n.MHTrT@鞿5x_ZԱܮ(?Zv@? |i'ian;V}˽/X͞j\i,X:6rUJӴh L -=W^ ^o pރwo.0WGF@57(kE O5=-"o.[?Yr^#8$aK>t&>eڰ5O fzք:֡qm ֜ڥ27Ua\]5E}2f;@]OFVo0ScY᾵>k-ޒCK[ăVF2*U<Q~34OZ߷wC8] y&uȿݐZOkRߧ).6YPJCǏ.{95 8RF/x'_΍m8`GQ 5+đ}>^y>&|#zD״u*Q8HG)f?'4Y;_9ueQT&ڧxkC̀n'G˩RƓ 9z9~~iĽ5rXk߉ǥk<= EI!m'cYJjevx)&  |;դhk=1_@VQV 9Q }kNn#1G4W<2O.2x )^=KB59tn COY%ào(0#U~e @IԄecܐz+i$쌹GE6ٯ~|Vl+#3G~#mZꖑmen9\U 3G+᨝wcjwYS= }85Mm%ōͩڼʾli-y Y}X~8 YX\M=Mݺ ^' M}t$G_ |O esh\=?K=bգ'<>Z7ὗ lR|`\V-v&jC8|N+:H0o|=uF8y=è#¹қI l8y 4I4Ō{"C+{nF/cv_5=Ru^<+0[_C[5/fm^r% `~deЌ9*XjrΒNV9x׸AK(Q~`pG`tQou%}QޕDk O ?ƾ|Ym~]V|1oľ Ⱦ$oCX:}TAba27C\:|u XceiPMs-qp~ٻփdlW±,mV&e+ɐ,b885.<[DP>i.Tr1\c'k){ZG!\uSL,ۏ6v_ȵRua*dwQ^Or[[ii'ݹ q_ K5B:;nUW8 Eˡ! ~p"1]R1> TmCC$>eFv[h-ا[)p *-˸\YT6z]Ɲx[ۻ-$QL#*X>N-JWMYKgt\>e|{ci+Ox7WsͨOuK]А8Asڽo <=O <:֨Pi˕2(zx]l> ԵY]z= e̓л_s]?:%*YfHApN=k4[[ '5|9&e2QFX{'oeON<1&m&iyl;i͋<gZWȵ)7iWY>b+Ǽ]UZUsuockGqe$GOv;b~uekݳiѵ`ǂu2)#8i(^OޫP  |]J%ށ!d#=SċES((((((K[,!pC߈FӵH-txV]Q=OL/dr ϨFkẎB{kM61}A\U7;=\YiMͧ9XqWx&Ao,q?lIYIx?Lm\ S ( ٭!Wc/ީ1ky%c=W%|??mɞ?ڼD[INv?"#־gxEΨ~?5c}3{kf_*y A϶q^sNzuS㇂/Yjg;D|FyI"Vwӳ;jvi2=ݠ(H,5S(g`}XWccHIUp^)bL{ r*yBr5-G_Z7PhG[ɕ篭dfJ>x~c5^j"Xs\&8uGA\޽Lu|tV $sGڍHD|#,~Ԉ%r0N(Iڭ7)'̧֭Y.bRǑPӤ WT8?el&S·5q:5g~lwk .!z8Z$|áSY2ɲs:,"XJw'<EFVa09XCo97#bYF}kbX#F_)w6 珯z;lA"\Ap@cgZ$ QZs6C6z9 rў|ҥV6FwC+=M H5e'cc.:~EHK17Y~(z|Sax>[[Q"( 5[d euҪ8P_ ~z`!z=+w6xT Aʸ_K%-z[vjYz p1Qay#TV1 AnA5"4r[57|IWDCEz }אxwRTLW02 "owԭ n<%USb[w>E۫CZɼspT| c=~s9T2++g\ξeqcmtѕPq? r~Zƨa\[W7uJ2i<@Dom.` ר g_þu}"UysnB?t#>k#|/>wijk讠p =OA.58- D 4su%es[CfsFI_Fy}bY;q&z澔BIo-5azׅ -m.A w$8 x>/wz[(.)ùCWU;*閚"Yq1;m㷿@y<q֜ei[S5Z2g)fC$!:Â$ԮP ?=!.1rI[ce7˼=)>$w3G ypHֳ,.Odv#U>lY3vvf"l")Q`L2TuJ0ubWҰ` 4'JϴHF}?[a.˶{bY7-d\' Z0E:#F&ֵYpV$?*O^ER oOҸEڄ&YZNG%E\gsm"g5g#Y^Ơ}o)&e;=uo-dr32!:Sqh/r. p0nGzG*:j+K!PڏXBHjRc[Ucuے^;J˿b7 4n-yZ:SFSHHI-Fg~RDItW,| 7J …lC2ͩDQi o`Ҵhp(I]W])ӥ< t2O*}#t7Zgtv8ZwD4wĚmR5\(*PI\GZW>"KIxdFSr>F?QWEO|7w1uh.ݐvoZfw6Qn碜~5c.ǐ,\ufW/58VE#d:J>ckw:.+D!cSOPgk ;mnko[C+e I  +~kR[hڝ?=yCO^[x% l㷖? 5E)!?fq1 ~=:Tl-dFB{S~ϙMQri#lkv[BB=EW} 9d|ݫǧ}vDAy 'q{ H`O?4:n )Esm3YBܷh}S wJ"H7Ҿ?j؋ڂRcג|`=&YhҶ p_WomLи)mDÐEt0]:Ԃ0zW͟>=\_kx^uCz$ݓo}k~j)ܴHC()Hcх?5JzSl|[a7Ob|߂7O6R~t=չ XxGO! {{˔F/Ŀ6kuۃkǿڶN|][-5_O˿jig>E8a} yG>Wpw 0 ]mHrrJٟfK/XK{KYW/]Bn皗XWi$tdv2suּ;Ρ/mǓqsE+z3MFFwSˣ=BN(J|a};j=.F`{aԿՐ0a^g-nN%5u!;HV'Z>ې·/1ִy#|rƄ}+믆.K9ʏLgD&L~`ywѯ|#\Dm.]yF9Uvp='<5`qE|&6 ZHpe?bއv]ި^XJ..K] 2& xw0h>jcnXoZaI,r6CW|ũ(bǛiLt?Ƨ+LWIvaSF΄SwF 0֐W"fۗJGO1?8U2> tݣbblz g_7QZ]2Y8K?T?>Uth F=&VL6n޿ZbؾC-_xF;jkTě55'D^+IPDYlXWtZR.cUSX^F-ʖuP>\]^$gd(܀|kpzYjq̿h% W1xVMi#!9 ?΄5lF2*kmkk߼K8H2>ZcMJSc2\Ekӯ~%htӴpȃ!ۻ1.ME|M/yHR5¨kWhӉ a\O|c׎9 =k94}&+U0>n_JdVcO&hz8#W`ui-buEq`_x|e>zBz%d󭳉O!s̾-~ÿ >&i shAق:llA~:hAxh˰j"C$K$ Ѱ!dN٪1Z]jQien y⦎MIq^o7&J*o~lTnެ*/ pWoao}mA]~u&OmmI۾HyΏ{j(][ ZY]3 "\}ϊռ+_^[|.SЃ_FT[YJ#aCϦk𥎿2E@.>G?l,|b+yE$vҽC&x`$}O_^'}+SK@$UEptK/!-%r<#޽wt /\aVv_ȞtvrY4m] dYXe<qʾ(|eShwl;cE:v(`˱Rcoh^gW-$H MuhGUt^xwUhcGXS{-B+DY\.SE8|5? ǻJK(otNEtB}$e(G:;ӯ:][m?6d+8hϪZnB}N$B#Ee:߃_hWґk!ųVtZKDi[ގGktAG r1ۚQ4:{i ;8e~+ƸKydţs?~?:1u:mpzn_/A~2JX4?e?R?ӟِJ?iWM9 FZRՠ?/[~lIJqT?> uoxb:팱OKV.pr~Њљ^ڟP:̞Eͳ",eO'D'ڼ1x*{;t|hQ1~mmoԬ֒r)aqymUid/4ᓸ>W7[͑ta^d}x;> 宴-HgNk7e&-NBn±jƛr4ږ]MeO=yBp Kk>:Cyho` $>a+9|U`0ɰէĐ\Ǿ%qy_Zw<]IHm;oHccH㟼OC^ |=5"ɱ=a>ޞձx+G"|)YpEg/s-M RK[$1s?A c7F\4:mĖV NU*{W } kNw"XkiΤ?k&/WN>MJe;MXX5D)9FKMXuOkELKrUnu/ ڨ`Cj/ ZW66(am|p/)]i7k'bvZ[i{6F7FÐ5~#k>pJ̍<*޼`<^i] x~$p!mqz y .$UnOlb2|lߎZx~m|MeFSH;n6O'?Ckp0Y㟮0}3ͧrֺ!RzZi)t.4o"לkLVK8МVIc ;hdt]̫H\l|7+sBKpr|ZmXᨩ.f{{d :ATt((((+-ulFHeO#WGT+=X)2Пl:-B]J=L"KFY?>>]o ^ɲFMr89KY#;ck Oݸ_j7Kv=/mG\ۋX tVվ3Y3?cN Ĥ{|38<LzyedWZ&ؤc#z}GsIlkQƟJ|ScKc#j6&2;ȣּ,*n75Yy=>M0/]sہk㟏_&.ڪXHb'N~쌧 jWhXfR=TwPH 4WW>GP';]{jk:R J\FݛpjHz0/XȌhe=]FiB|v߆~%xE IDym>AzԖq,C4sيEQxZ{v+V]fP1NSǭuҥsNwl LUs'k֝<*S&VT,ΌK#qYћ rnD&v"^ A}=+:F1cPX]!*$#Saܭo795i3nᡔ`Syd28yc:4|jFJmvM}jŕFl5_~S>RۀQHgA AaLQ؜`W=ex`=V?KE5!m\<J[#޸|1nir9#=;WG5tIQҕg21z֌ uGkVc/5uZL sZ ]ڴM]H9PаpIS޷eV@6LrVdPm*+[O1||V[tǯC*HʰMr[VtA:֊%d v5FEe8#fŻrHO'I@<0Woi& '̸*;^#61`"LE[tme,HQ\ղ.Jt^JV_*LqMIE (T}ɑSԊI$Q(x?욎ͭ<1OQI=4! imxOҴn#]+Ջ I@Q`CєE}n##޺i"!m܀V9}cX cX |9~mڻ!yPiirA:5Oew>2З~-3e(2[Sh/sev&lP`uɮ/TGSSo5W}Im'ߍa$7Zk:oTF+l>${"f C]ԷJ@rF6wKhsqw $sZh$} -* tj[LHc*8v^4J(z*ƅm1[$IzJ?.0 ]Fe(ISA΢_͌}j~4 /0p1TwbvW; I &S?zf{XI5mK?t H9Tx$ '~5ߚcc!T57b/;Ⳡ3mSNJZX-cC}ܔU{c%-ysTggrRqja^?5|ʃ?Z>qtC(K~|?: iKi{ W7qGs%pS`Q5 xʵ"΅&AprAlniěq?pәSb3>x*yMpE9=  Vc5'Z& _Zcv(~Q}=jinx<Bv1n= ,u5W<$G<9=qz|WRdCTʺ~c>#4Ƨh7t`K7̙ }\W4݄>&ӯk-(B1`vH>Jk^H+̇ 3Pߋe{fD" @t8=3hQHFl70cc.ќS-J>IHvr? T~o$(ʦ-[SlpOi`m'$l«fI-b=/Zu̇m69©|V]Ky =@bGEcyeLaEu?ω<#k7Lx;`Uup xRCβ6g?J{dd8e"Y_B_NXGL 9^;6p̻0=WxNAϭz=&,8(3{י0#Rs]1VɻBoa ? Fqi zoOm28' q֌NsL(GJXI%+cJiL(7ž69T#ǟ>x?P};QC50>ξWOKO="XO=\eLs4Guyc9C?^])OpDHIn ּC/û_b%6moW=~ ZC'%畲9p?zvY#^rʚ }1ϨZ:eυ=.V "9yez:+ '8>jrt@mPZuE'>/>h9GڄY{}.KNأ*@^[bIيspNڊ~5Yqk0Mgw#xj3aב0$)rH$ 28d#[k#W$ؐanZCMh[^d~RA{3ebԑ,jfܕǜw\-ޜ\ve2QI[xOT*|qZ6xdx~YIٞkgUK uKעHf%\ a/KBmĿ:[OnʛLOh,-&qP33_u;cqc 𵶍sL R%mX =G`=+լW(Pq(ȶsKK{_*j+~'į$6~ 2*7{Qq\k~?-WVӯZ+haٟ:`ֶO ۛ}r`z`v֚ЗfBIWäM]$pÚt?`Ya"崂X6@PCwGzi|uE{kxB͔ο\26dV̈́2D?Br) hY7g|6}"[zV0ynyܪB}} H| u5dg;lSw|eQ]ܲզwDz"}FGآ@ ݏI]23~-xE[N~o鄹fRVO x*^G0ϥzO}x-gKG1\]g ?^3U:] SV7"6ʷ 5_f]imaã`b;״]x?x"-B8vo&cZG]Jߥ;Ij,uX|7u>+XhdZR Ic#+"T8{HGj@x&e60eF8c_|;tZ7M *J)- 5If˩lsݣ7*:Ok܆yAJ@=} rwNRA;VXj4/O kX|1ZȂhc(9Vx}ԈwbH2޼ϋjrFp?v$lל~߳xq1.dg=}>:!?#)GD֣xu_2WVR ڇ%8Yafr 1ܲzѳ} Dj%{CդbT{Y>Yj6`@xaMu|,5H/m[1;` xbXga]2o1qsg:3¹g28/hyO) d\C'}38Q`-/!C5}A־M"·u 4^gz,*zwjOƾ~ CGw } } }z0I[^+ ^0HZ - !Ug^VqUk[maoTc7iGf'z3%Xԇ1\(:jƋS-n̖(NZ#=&uRw -+p e,3]zSa&ۑ[Zq+ 8Iܓdޒv- lEe] pAåp5ׇ~!^OT K5(¤f%|WXֈŁ%W=?Vt"N&[=9р6~Tc|ANmFFXfغ߶0Tgߞw;zœRzG9#^3Ř|_kzZ.,7yR 毰 zWY7]xo0MkR(| ګ94K}L bbe&MAui4-ϖFW{~'|ʾ8mKIIJH$HVChZ<(QEQMwOssXik,א.s*:hNo-aY&ʫdڪ]NʥcnGU.4KdE*Y,O<Ї6JN;O>kPA61h2pU?_etT>u߄m@-7/һ_4}gN]OKζ.K.;Q_j76ΘZ4,#oCqr .X[&.-Y~gs[>2QM."Fˈ_Wf1yş獇'r+~(z_ i<-#4y2{mo9sV]]Z(t?7Ieק=RkRGxM/YBr3=km$~EƤڗ9ܝӷҼBvzƞpmm}~{9s۱w|.,ncwN oc׶h,'-@x"xA܀O YI_?rzz>a;4]n)}vQKoM=~}_IG<-+ef\7O\Nwejgwl.K Z;i(7nh $g}kdڴ[Q(\r3zzS-MN\FS\b6iE8%u4m\y|՟sUp RodzuNHȢ#9kV|;ÀqKnLR8JаED[n=jg rOO^b8=YH0,@`"R l?'`_aVBe8*Lڸ'VE :[5^xzm <ޠtm#5Cs snI# |{ϴ_0s!7\گJ1~Ufn}OaQ>SWֶ4%OʝDaH'>h[+Bs-3n $u<x?Wr+spv1Z+wh]Xy=@5l6R:ynl9dNTמ M; 'WyXF?^[F{-h[CsF={0LpsZ,',$F {I UvI%gW.!e`qA5$8;TET5X@d1rr/o9W0k×E$VpuRy- wW%EBnNƺۻHa[nItAՉky{zUͫi-E#G"NTv_1P?wZ;_Ŀl`UIG {s.ȊOBG+t ׳kI 'kr;KsmpO*ø(c\jݗS(["!F:Vv8]|VkZ3+дbNdR%syy+ҮDꄒojӟ ^+*3_+~ܾkmGþ*15?2R>]zMn-eM^-M_o|o𽾵H:[[ (#!\w/t{ 3o:&Vꭜj`JJc?OszV-!L<:4Kt4w XaF b \4O6j{[6:`: qyA2kaB:k-Jj )8jmm5ܢ0+8sYJmRg'YwHwǗF{U[7c׺#[ Irx`I=+qoWܟV#,m.#RK^G9>J鸃ڛry7+oG?^iХ (5;˱Rqz.SsX9~f*nt! ==Ѐ'ޱ6Y0*wX(\FGZs֫}mQܞ$hc#,業~+PA~5ZHed [rǹkc}QkGNֱPaXёkkld,=*XYW 7Kφ-' 6vֽHn)~GPkQJJ֬u~ ,z85NC`ܦM)sZoTҾGÿtF!j66/_~MXXk}|O#YYt5OsA*$X_~ߵL_gHs9ksf[Oe6Ur..2R )<7j5(4@. "k h\sQ_!x:=m7I'لOsY_@E"C \7<[_6Kj\Z??]Ne> Aϕn{|[iEI>'l^{}??Qmۯb=%_P};Stc>%-㌲ٖ<1lpwtuTH€*ZB*g+dhy-eu^S(nX\*{:kOj^ S(m[" vOcXTM}5ke2 k_[xHs9FOR}rͣOa\N#XSy~k) d8_Im3U0{G8q2mfoCwujےW3XHeO≆>B-KB7l!Ɍ#vSM໎")z5=#ź|w,rAHOB&lŖ:to7t7JY/pܲFps),CyZ]N\yQGw oo)+J6bM!T`t5؞ƗzγGz9tɲT`:OL:u__/Hѯm# p~UiRP]]yʓWӺџ7o{FRToBA?k2< {bZhãK mՕW7Q1WďtYZH2#FkKūWaM˾ ʷWcx&Kie‘c\4p1^~Ҡ7, L.} ?[x[V}0%;sl5/eţps"Qwc17 xϭ}IO#Obn4S=LM?6w=s@hC@<^s=kuXw-$t潯E4{`;zO٤zմ v!dl5օ$RaJ rG9SNq^㏋W|X[Zj6Pd09&o; g,* ẞ^Vm [/ff[6c0;r{G}pR&K娽9l{5:]v׆QW}Iy s[8n@ǿϊrW$? v%.aJܶt D@3^Uxm ?^}MuWs.q`e,]qH8}}+żļc{y>qg+\Uk$o%`֧P34!xC=u!Q!=Bx{h<=5IMv/!JhY+t,3d6,oخ`࿈)x+- .2݁kXFf7 :U`B3dʸmu9{SM=Ohdp~EM7V'7tli>D^#\]1(.3{ucW }i*AmhW@#-/FMWe#SZ"( {#ٻ}+];T׊,r#ЃЌ>|o4ݮ6'(os^ۨ6rcM}Gb::~wx5Vz Ŀ?h/lp#0byS_7>OE-c]GA:JCSuIh˗vo_u9H+H>񝍭 $ 3oqU) t䧌llm[kvVއXYxkK-|Gb ˑ2=G4?WU\?4Yvyo[ߵ'1]bBpfA~)4Mɼ++ª#y١7w U7RdַO.EnDˏ׏θQC:\_p 3z~yYt,/Şgi3ɳy ?~Ӥ{j#$_#wN~DZ`=k C'o^1]GȖ۸dB0HǨ>kz*ׅ[3Z1oעK2m#͡2ج \Y1qh=H{JU#f9 ZOdWP꧸sYtٸH#a8IL3zK&e`}zkڼO~?C"[xL8/|Kv&&qkpco_ ~$\[\%'E\ҍF<ͬ]O4v6og+CGI;^]D_&֓oMaH;]n?| Vx.!Uߌ_ze *$1t=W=嶇:sH ŻkcoѾ"KnW$s>Mrms#ҶWD/uٛ$Ӯ!g?}}y-? [^\$?xΖQ@GOSC5=عy8lZ͸1ʼ2SXwqo3ޡy ǜCկ 4rI$Ҵ-2=Rɘ~hP%Vż$WN-GeWXT^˦HTb'ʹ$QtẊT<؃8Gݙz7q_'YhK$x'fđ*Jp>y4o k~Moa$1jgdP"bO#q$5] vZ Ԙ=ՒP<osRGZ6u8Rao2ݡ@_cbG|vU4qhn{CջŒ<ZxIOHZ7дiv6}lPBJ?lR[Яl,WiX!Op9Ə?;8R;:LN7psFMgZ k:bDv 0N;^Sum;^2[Ew;<6 =\7? k4ZQ 騶a3 ʅ][n}{xnú3Dh%w*k]$Z3K|9A{k)HN<돡J_-5 V}+[4 ]A ?Qyc"8~{sj i$/`!8޽-;?ٮ{om-8;ּ^#>~blsm_T|z^ N u63%}3eK ]xAc׵ 540W;ܓu|jI+18asIE3ÿBK⼏UӦhz! }#6_2{[xOC=?u>S޼ -'Ka xvWV {vI]Fu- ]YNU~gQwF^o42[JJ8!׮8yğiw,_oq{sHOY}@WV6I6z}A`A#nJ&fz\ϥ 3!1ƻNx@)TBW|hxH1ӌԺ=ϱA#kRмAэZ{ҳД tJJi7Bۀq<3$,S1អp{Ciw,>}#ޱ5%R3jqw5+1x+ƶPKp>!{?^EP^R. ?.~WǨOxϏ~^|2d5i-,H[zgáZ?Z c-_Ҕ@s^ƭ ?_ znbr``x 3ݣyeܘe-HYy\q]'xMoCp͎7zw+~}[Kduv/m&IOb:Mx5\IExn<'SQ,NrT`pk'w|%>C>[ kŌr,G%Zm;ȷͱqcI"N0L˶_>CUnI W MIZD*YWcsYt3+tFsW9*ޥٹW^AMN?9Tr70yr9QF1\ ֥܄B!@]c2iR8c$ɽx;TߩE4330tĒV1iT=9j(~!,"LӸr#f_)$ך赛2A>[k7kb/XGbUsA\ލq-+|8Vv?һi9sbE]Fɓ>i^/~e+A}g>lWSMnL9A z&GADXpqV)@ s A5,hs{hN$S֬C'28UY>r@79UD780CfL jѶn-Fp{z9q6ҬX\˩Goz9]j<՛I&@ E G 3Ft[R۵.v $oW[QUo!a {lƠl,>hcS &d+oyv8'XԓPo OA]uߘo!h|rjԋ]}\XIkuC'lb=EIs^-nrt/`mx&e%&?f} SlV*!|ݸ# x_ |>˝m?˃J&e_&Ea$S+i2_ |7;M*VSTN9u?ug-cyρ|m&i 9QBOƽ+x663c(l(>'Ҿo5Fx 5? LY['J&L2>9]SJ:1I4i!ľ0V}<4 e^H N$$hM}4/F')n%\a ~yW;Lq<àJ謮Ys#rsrkZlhd7ѽ-8 wVzt`.3=c)e@yz_IB*=X՜]z4]}An@IX47JHM7sZA,a5d11v\Mm/Ho8)(Qd^w3ҕUԷ\*'&fMG ~GT0;F ,Zhnvy~jr9sW%vTYy =s[W{V5|i>9?^|7ehJxbRu]GȮ⑭& *0 +f|vwkgխ욀G*Ԏ~JqQw4NǨx37%4fpGp$yk;@.RKzmcjAg1hOӨ<;[Yh6I! X{|7A]]+VmT׵cӧiZ[r01 >edjk>gsqዕ %[٩Zڠ8{5o*H}- pGUχ^5u guLH*ko{ne۽KR8le[5ϳIw0E'^78NE"҈v~ѵz/}6_fgxk> >M]Yx#>>FCʑVOM $lN.zky:9;K𬷚}2\ZJˀx?B0x GF uVmO 2G+5?q4{1J瓁>]ͫ3#7n|HP{J&9eJ&Loa!lWĚ]nyxךߊMHS0u8sEu6Ĝ ]Nz HڪAPIK.g_$5hw =?l]˗+W|'ec94RV=7}&9M 3d[W6WQ@FՆA4cSl/}}XKA9~K+O_Cޢ/- [CQ"[-»+}=OUa+4M,q^Egڥπ?h?ٓZ-5fGƠ@I%}hmo@e7:{-c[Wa-:{ "CL!^x[x:)o> {Kf:?Q#,ez'ֿ~*hӮ-d IǸez[԰JƾgCéV)0O^JtYfH5(o"YadC)"-Y4<$q@zg>[KRxdR\g5oįf=gFy /l}W-ϵTtm^H.#Y#pC+ *'e__4opoۀ&?{c| @_,|O91ח~i(h#;O{oߋ=˔:Kُ jE[; /;8\bdB}EpzDsO˧^Ō폺?Y?^;Am*ftCO)Zxn!1L{}&xOoxI w1J20A~5WanQ_kk:tw2|z0B|ȦF5eѐTY_x=bBk:\k1g ˜Wx[>k4=ug+%W7Wo^M+SŮn>R2G/bbL,*H )JW>ɂ_|$OVAYS#ݎGÁ j&˘F H$ֶ/OAuqITZScXTmG7 /{l#{KKq`TCY> E,s~xñUi3Z/LH=GAx]5\!]MŶ` זG4:VeW ŃķC!۞A}!AoQ:oO-'޵oi-h$d]ɰe9y0k I|W4jSv `ZHC=0ꠏBj|z{xJAHDf݁$袾,h'1@@l׊nfMx U88`̯uKg%Afn!ݯli)t.` V}515yijz% yw¯xNͮ"y- a2>kԼheu1_chc6KrSܜƱᗇW[wN>u,6CEKY/iOE$ 1zh^*O,ṵCZփ(CnR{Yƃ%'f V4bɧ7xVݤЮ[2n`zZ61_MaoR[yr25a^j\X@ ¥T~K`p*rz+m z^ Y FOoB#Y=KsuϨ>G1'kbNkt9+8YءMNyM #53W~Su8WiᏋLJmI-vb%APϧum?Mf Hsߎ+X>lf)jTC|^6v#F5x~T/4ehhba BzGm hI [_5=Hjnѓhq/(GCZko ۻO~?xF3םi-ލbӍH~W$3^ּ2-mFhBtuxE[ %EgV
?zVS?tj4ٮ"> m-9M M6!nFw3Yɭx"`=Hæ5emRYc9U^܊M=ffy6<1枚;witݙĊ q_'H$9 },'"^XiH'E}2>NPw;=1hK\+lYuFpT;alI*OC"u\>e֥ʛ@Nml-={ OwsjךyHϸG6~Ẹ O氕9GmM:K\jp-c#3id;q\siOj2@\&_ uv<|zӡ|e <_l!Q Owac ӌf(  %/YfU@ М3yG|Qo9Qviߏ?%wr\rpR@;gПZխXCvZx<屜9~R{0fY^t$7+\ք.b=ǥFc111( ;[ۊ`?QJbdd>+dXD zEx,n9#ʬisX^Cuk#q F_Z~~OJ_BGuٰGz;rHlKyy2V<᷏|jV [Q 賨}}_L.=7׋(8Ę SQj= ƿ |5ͽZ67ڡf;92=HZj>cWoWQo k{*QO o:eXBq/"ssUńth?zr_>YQ2F{*hU7h#$ ԙql?4k b13P&l,xWū-ޑ#[QGq^g?g+)!؊u :ھ "^YCy56?ZMԗ^GM%qkvmoR}{d=9Z)XA,uW*[ Z_F1fXz p3{sMjF +vus5q4ͯI}?Wˎy~bW|XCsOxY-]Y"=c~+xcQ:^א.7cb{;>:)ȖQ,hXn|im^2;Ȗx ?uQOџ m῎|36- #c}I[CsP1cJ?矷oyUƏG aR%ܸESJHWnjlnQC'1]xQMԐ%t+)0\| ٣|cSJ"@))XNMZyǦt^N</Bٮ/r۾O ꞇC.]Y 0=WM߃&5Y#Ew +<?kZ.n1s#5C{K1:ǵ$Y\=j=:X m GToG_֒fw۸'aNMk.r~MGjLo?c]3SQqݯs˂1QW_mcCu@&2{~ YEiW#ts/ *xDZ>;w^Q\1f? `+CTd|X[xfzhʀ[vtg}6"835~XG"IdLW0B=ҳ|sݍƃ|7[Fk 43h:ڝ1Nq]|g,3"][\)Y#ak̬#WH|8?C]6>"+~ROJrt_>#_| m;xf9`Oqǥ}ɢֺ մ,2ee+ sJ&=^eWFݝOb5_5k&ɴnqiC\]M>ִU;.#)}"kWvdnx9Ƕk BB$р!5|H4ҙTn^d'bm>Xt}K#&r8C|5-n9Ki~it[͎=OB0ýYtm&I$)43Q5t5EE( p l|5{=g@cfb*}㱯~#3M|?so>l ܉uV>֚.84;Jkٟ),aO\;pum>/7ƚ=ܓV2FVCaRMT=/ХigWlght$nԜ񽿃- [٬wg sU>`mxal|YnubCʡމez=k?^'=kq0$rޟ?Lפ|SLlmhLʰ9}߭;M[CvdF-\ 0pAa|vnv|aK,zb\$n=^'e\ H>ǨOՙZ_yѫ+ދ5= ]8g?}Gv@br;Vq隝b)V/Q֬Sو;T58Kڏ$@~~>Yžy2֕B$2aA[)CĶê2oT?,{ׂ J]kQ۹֌ƷQ(_OqjJ(J,e׆H!bhCXZ1֋NR}Y ]s^~gѱןxL#s՝ѮyC=yz?w-k0͏g8aT(uy8A)]V^P#H_;v4-׏Z<31ߝmc.iF sW azusƸAQ]Qj|C*Zn?^8haP'| @}&43-t4CUxCZ[O.ԙ[YnzU^jftU;NP+*Gx~4ĺ|wQE,r/NpA4](1psIh~+x&?Z@ WN;5 m_1_ǯz n21JԚDw^&N6rLI9nt Xp0A3C[\aCbRU留"*cimmEҵ.|0Kt XǓ&TڴІ^ Km^3hle7: DO~p^>Mj\z뇈beM8?5G_ |;eƇvCN W#3lJG˯xT9K+,{Ma噴۴ki2;z{Ns[)ZcTˀ}k֕ GKkİ ,F;OX^3yϥ]n1HtKbi.&VXh?yIzcIk=.f꜎9=֢{F]_pLuB$ (<UyAڬJMw(`7qPƈ h7ej .xaݻu#f_ˁ{*Uq\ϔ#eL_oO6WF6q"o3=9[Lh/!j-VrCntJfVBQ<՛-6yÀ~r[ϯJ'1ܫ>ΌHH d*y^ܠw={VH1z{xs=P#VӵsD1+ w$r2O_oa^}*,NJڎ=KiL0k-KTr 8 OztqzڤfffV{ǭZ pGVv*xxs~WҀ:H+Ldžj[9s^G)qA D3B.ۜȟg ^err=*(]lTy Z:3Z܍2ױTV`zzV30 ګgo[ZܥX.;R\zP.O՛;n?A=JK{vʤ Czh[>[VMUԭ`0Ylm_Y$zSk\_I˗ `<♬nQԐ+Եҭ؞%#ޚz NŚ[I(ĸ*]}.5csWgХ<=)@mEu:d5e sR85_23&4eWOԚ#ʓPWaKQm"tH#dx:{hFA8}ECs)W llui-p 'rѵVz_9G5=4Gp%p+5k$+p ,Yo7qQ%̆5km3JE-FИXϡ k K mS1VV(}K<|_o=:S8 Cל_]@F w/ Es\p6%#ɴ Lz؊߳_lu5oxG p@+kiy ʟ!J/xhE+$I"pyVSӅ3/ğ0~uR0&~\A>𡇓+c_RƇT8ѵn %V5TN222=?eoWFҮr U5R5c!88;xWZUmz*-Hoh7wm5ԩMIYo9i崶sXpVT؆xT@__[|BteP 5y_$tů'-v:uƷ:8r0x7NcEĉ,Y!8[1*+宑 xĒ Wk2ڡO#φ>~,hLb6[ؐ'>7 $cx>dl_*=$webPO[kErdR;eԚuu}zkq[U\2?XwWMqaF#j5 ?ꘀA9JPjZ|qKm_OL`Y!qOq}+?ߴoȭuj>g 7WH!+ ʟ7-dGc咺~GiҶ&lӚ+'M3K>eF'qھYDUI*G5hO?I]>=ϕ.WN~'x^OiGu>{i:o]Z.>=픠%{_mie먕Әr  :׊|[mq UXt\ ͹Ԅu_iFV?O̖Z<YmnBgb R~P}W6>5l-R Ajp^X,lldΌ +~W|LJތdU^=Y/ 3|Եo<6~|IYYG^kHIkMNKe1i>4x/OtoO(jꁺ0k<{7=Am^{h[nqf' +ȵi 3oeկH9P8ɶ|pCWd4FQ %:r+Ӽa}g}uoo؉"t)r:CGo]X[{j egNu;+2 bOE?@d\5/OM[bزOƾ^KVW 2y'fLd::ύJb+b |ڑ#~5iKd${_˸ wvl$/+=M$bܞ;#Nۭ|ۡ^x{TN`-t#u܆{g^ݏ|.]?̸:+05?+hê<+_ 63R~k9[?{߄>&+a_~W~x ]R;l ۻEnK>Ԃ !YA|%VVYUeXѼH!k4Nu V&*ePAA3e^DLj/_5kx)QY (_Bن/8) KIwm|`wZIϠ>xh>" >WMZjq$kL=G4J\ki8do)Z|YDm):]wͳCm=\@Φt}Y$|!s&eQl2^i4wЫD֎BdSЂ?CV);2|`@F{O ám&`v :gk]cEK`W |ul%dm䤊92k<6ڶ޼&5|.s~"]2}6e YgfzРzJ,|AԖF;nQ^|XL0cPPZ}<XoG=~9;R6hOXPho`>27r·˚w4- t?}Ѕw2z椣ԼHȉUѼqnH㵚!vDnoR@~}źm~W? ^=fEw|{0=A" nNP~AG~p"vPVs;W̞4ִɲ]Fۄ U\C ?ZgI/ F[7mܓԉMEyY8+Zj36 Е +翃_Zo6*Fc*{Mthiq]۸M="qqz+&oH!gsI,Ϫt(uvK)Χrm oiI~ Cr|=VmldiJÞWDW`%Ҍ=ǿi]\e?}rEeb)WxjnEݬxA5#P2vWpG֤ܸ pTikqrI9؊DBI,e_'Z >.Yuslnw L+d|y"h?~>4++]vNm/Be`C7mեԶ<p'2VgZI%{zÿvj<,v9kϤyIӶȬWd8`]ŗ>.eAFs5i$R(p?f{I#k{2-f\=0XY;O4>HF3 y[NыND'WQ5i'Ԑ+I${yѳqt%6{][k>KboٓڻzNX\ړjI.p}rq3e U%KL-Xʯpx@?2ps%m՛5+`3L4lN@* yB6<;UÑzՈg 0=*)-p#'i8>mq'iC"^JNk9pMfHr֩Ѻ֯?3?@Ҫ$!ڮA#Pz0p}Ef6!Ϲ*JQ*+uȦBʱ хVh>tmr8g*WL ?GAT<{U{%YÐGj$Y}GJc8 9V,8\CCI,f$Jbb'UcnXXm]hٝpbwyM;,Me9]3P3)cnpߡ5=[\As$+"`}_ 7*DMP`{.#O4DYcȊ~&huߊ!$&==S}~8C=+h!攝ȧ ?/utӵ7(ڷ_NZƉ=mXhrz0"x7'/V2nN~x$$ @\' >)ao.^w,x?lۮwS8#tQߞ+ xEƍ_c8$CX?w_D=.L*7oC_ cI3jL9\7I=v?G ?'nqm$B?ޅ{C^W<: +ɂokl8Q̲no Xg˟~jտ*ЃilG wcZӵ_B>d_V@ueY"da?~ ZO:6ZrӺ!jx{fU^C5]-d4o ۤLZ1ͽ'WUxS^/%xl"a",{˽9~:E'<؎kMk4u_ y:C)Л ߶mnm\OBz#i-1o!l\פ;۞^IMZĺ}₣_OFU#XIAp z+߃fXo'don .bhn!b9wZd)^bw!U7Xu= ַVZ!=ǽp~,QqK+ѵ%_0M[Q-3gW{h%Bx\uF+ /TTY#pǭ~uxEim-:AoڜA+pwTX9{8QHmaգZ1} s5L_^ _[b.^OáW H CIִehg gΉ\֫/уbx{٦%v$ćo@uw<9O|9. I٤="N:`9ȯ\Pxgoc{-E_N=HFP}f/Bn|R V6ә1NG0~&}-|d ھ?h_=hÒItj9 ē漫 _'x#Z7:qg1a !> {M+CfcdA-Uׄ]PIyVG8=y^v3-${ۚfE"޹v>GK-~o!+(n7GצcY} @lOL+x$Nw 6by:jH]Q`Nx`}(:UH~?\mIm+*l'TN]se>B|@C֫1f]>cӮǶKVDwEB DZ?Zmuo(`~S: #:7iwaGpHulnQ- vAC# W(؎ S˥r߄_]eNVT<)5:Wvm>7J:el5RR/ ^Ov3RKKW=A랜[cwӮMoyk!U>k(7N\VAL%ZTo/r* =S&C>uAczcF8u 7o t)ivZ򯊾>aXnb %ۜ!$8 #;DŽAMBɥK[g"{V^@!=k6Zv=2|xvc̷*SuCh;t_J:F8[ռFe]x^RH5 _B|S12_Q]PJ2Ύ^eHW rB;cj(h䍋-{F>*x n$r>bu:oʑSlcpCq~뺜n[)Z_|g וF`=#R"lNc5|Aw[-ym,¯ΠVǙl~>Ƣ:)$YY0txdG<9\X-) tݞ_yεsYAEk%iׯo; BYqҴ4岓 ͝Pnư!-wsc/+JYI-n:gR]Q-:4976{O}v`1[wo,!,J7![zr??P&XI"6 GpGBG8o><ȑ TpkOjևw:`T M\']B!u^7Լ7ynxfKqj͘D0Xt"=ƢƇsY4ۼ|c'i c4 >X6sߊmnۧS;p|_Vj1-lܽF'ڹ۴jKz{m8@]'Ą_niύF?.h,?3Oy,&cN4xoaWɑ7Equ#nxzK?;w!T䮙6v4]9ɦ".a[|?O{f)ΈB}AIn_OPpvK䵕+E/*kӎk4tnT2@fhj®2Qߊcb1qLN158hoC@9^}Pj0̰哟z"$3; la1H:4Gxkn̙"HW6_ W0L0zҒ40 .~eR{y,"T=UoiCLe &wکxN0حb+桖zu[XO-.U?$^@^g#'א_kwEZo KcMѾWgOI|H̎[9$Fjl|9) mpݍbk_5IAj .b)<1]>fuMf{VLM.$!~fV[n$ݱ0~5>vO,ܐp>lJW\O|']>mo!Va![u5oxk)l~ic^Y6+.QlWRE|įGQm7vx䏨>J?]P?rH?m6ytۆ;XՓ➳ndxLڶ_0y;F(M%"=X{7ih7P;Z!18qajy> hxr_/"cv5oÞ Cӎ!O-p!8bM} 73jrOKyOI>Tf$ -b$폙ՏF$tt:в2gɱļʊС< kwiqs6850_K O*) @a5hw:[X%f8 eA9`K{Iy&CScv`t`z׼h_hI%6 UhyX @8\1Q.w10?Z|G{K[9w>yžG8YYğܷ$Nz}F|/y&yEVD'G߃#&WzCÉ]Ǚ g852ռ֒9>C}$dVM&/c/@ϵiF+Mv̕ݭ2׷_hUOI&Lg=i|6' O$f}V5rМgWxh~"kk9\*toS85jzdW,sGj/aC2" [_ g!?ѷ#k.V"Ru0?lu淅E-Plyu. $j-5eQ%=k+ֲU)K&zZ4EϬ~z9au6Qy$KoS=_c' %scr,A ~Vi:WP XU=EzoZenĶ2 0zW4_Ugm{CwO} $0ޕ?߂ӵ0I:tw"l OFW~54ܛyTϨ!QN'ldE ֵs bm{h2ۓ#P֬eEܬ -Jn%XڞNvL"jԃ1WWƅ=7Y[~ɩGif9}}p,?%xz^a'>-n,($C= ]5P epAMT _s6$dլݺFQǽci)ĊnlJz@e)k?ĩ#}mn[qթ_r9NW>P z Mn25Ϋ^ OauiN]_|_s,WHk{Ri(9M+YKR܆}íAfd4G 2+(Zu-9}!ֽHQڳlr9 wv^6e5uJx}kf~ _62e1v :7ֽ;QWDLs!n)- 4V$]8aM03lt[yrqڰ.`W9juMV95{:/}C]M|}Tv4CoK,ywh Iϧ1S4i1 봁ԛ@WOԖ+\:I^Qھ/#Oc>xi}I aE 8}kپeNuXw۲3;*ΙI1ӧ^);ڿtG5ͼܮfkž'hZs+|?kC? <ˤZS$፹ʱ{뚥_j^uO6& eJ7USm\Wy[H[r~Y| M?>tJ:7u>Cc{xZ䴖+gi5r"}g>gޓn6ݳU o,xY\LO&1ް621xF{Ȣhed“k[ٗzϥzXY7^Ƿ~xS <[E>E(9s?OZbR~~>ˬ\CU`Ha5x>!{7"DFpIv;!rOc_8|cR<#\5֒Ou/%:ٳoEL)x}4'URx3~-x_WVMbMMiBpÍ{ Ǐƾg>7PL{Ci } d@V8}+JYxM+4r|5BK嗓Sg-Mzӏũ}_oۭK~%[&0fouN?Fߴ/!ʖn7vdc衸o 5\ ? 2x*rA,4nIn}^ԿV-6OFzs_~Ԃ|s-y%;ߴs0#Q#\BCiu?IGTB _rykR%e2foB=~Z&Kd”3r 2'8VRJQML@잾nKflv7ub20jl2 2C |S`yw|=z/U2}8~g'CoIIkOHβys 9+Ԁz({ /5ّ"zZ scC `p} pÐ{ C*9duA*9 ya.sQd?:BKNJW z_cL f1IyNPڧLD֯y6/"_ 0֝ ~)J{L>րH={TFxʷQiI&̇=*B<= qV[/wF \jשn%Q+fL5?z_$6@~~x"ÚqBBR$WԔzOifb$Hgy^0|Ѥn7K+R?HOMtj}i8aqH|㍿nץ}sо+h`oӯWaꇣTԧ(|n'S%6<+iD 2Esl&ܧb8g֚=1]A:eܮw_ 5Yu"i/.$-ڹz=N2lf~&mK(̍Z|K_d7oz]X@ԣ%G%>蚾6R8ilSҼE5RA$U-`==޾[F;MWCbxWU̗^"##2Z? /[=JVuPՔr|3C !Gjsg51L$e ºfK=NO>zתYj6 Ƴj| 2e/ ')LN?~OP|[< xB۲ C v^66MJ0\./ލ2Py5ğuI-izi2drC\ψ<)sm^A cC}]{ZvcV0MҤdi MWj4+͆чpkMXr4rr#G!8"jN˿MxI/$"+_[?v#zK[൹Sqʏ@GY/#V 6D+ymmL\ ֝ʰ@kxNHQ7"6؋Pex xÚdY.a;dF:VK1MfGE+yLZL?}sZe?iXP7՜1?y+PC[Iuc,?CGoo¯hw[Cuctv~)a=ƹ ?4tt $תeh$pALnVHFWMc髺c^`rzc躒2wN&˔ 9_UlU5/Dstoc޲b*۳S]&{ r՟VSDSSFMZ}:\|zWz~c] ;VX\G%V׶᥵AÏ;׸|3'nb,%F0{pxa$S_ßxwzM۬ٞ \o9nKۛ9H9ʞEn+ӵG`:5DtRfoʻFfCgEB[pVذԴn!kŕ9kWm3WIc&1'8}>;Hi?O\We᛿%WiIïb$S]ʠH0F0CVb$O/P/ƥn"+<,f;mF(fG&&Jv ZeGN $ztF ,' w=MoNR]܌6aizX\I4Kv[ݩwC*i*x{iP\gݐ6!vخq=<%egw,ՏmzM!oկah!S*Qr3N`kI#M v<ғǚ+dӁ1-Nx 0xmY ٷdU=*Y++&6'V9] KH;L'fIlͶf c蚷rc6>{Q,r12.f?}pZN^rCCWK و)rۇ#uZ-:qm)B{?/)}lZIs `N>=4{|rc';w~}ҡlגPEmxRNS?yNun߇ox¾/U]3ʻn:>{g͞3t}EO6m>\ִNucʈh܌ jDm!jƧbSrqکwd̄O-ĊS֞wnQ?:t6JH!?*N3t#c19T,[\zi#]B֗XpNxv1FmYF.8Q\bz\G%k))~lv`lrU֓)ڦfz7?=@1w6OC,呤a;R]m5" v.m9y^SӜ +lօ}i\qfGxrߚn}`Z-N9!"I+vF**1)f$h]FjM>fym1ڥʿy94CAߔn!nخ(H 13z֩"!oN%O zA>cnvVDq48Z:abou'\g*%R1W_zuWvhū KIҥb\{:mG6FW/mͼ c]PJ@{?5ԭRq`>li>T޼!K{x&}|7^˨x:R,s*"S\&K^q#s[&nk't>Mhc4iE9{{ףxfM;da0%m!wynhHɹGT͍ՑOݷ@j̲ۏ1K7_/qZ؏\Җmy^!k%Qpx9F{ 3Krʱ8#qҵAye UFӃڰX(ťZ$f XwS}}ȸf)r r#U#o.Rm'tXK:8H?VՏkT)=fYΛIhx2.x?:wb<-{6麱&?1+勥dT 26r;?w (^6LIpU 2iŚ'gsKn{wG=$x=|1[ZӢ&$.'Ꮱ> KONRw-< _&th:A{Mw\5N;J)w)_gF q~44}_Jso=߅u,g!)g+^my 'BkeVGog=P, >!i_c-j$t.?}x~a4Kqbtc;=ƍMݔ# ^\ҼOqw'5Fғvyo;}N0qX{W w6U3Ƚ}jZj1ס1^A,&Vn~2+~#x4b ֜2B˴sc;_~ηG?%,"ukX$Oܭ8Kw7B׈yZ|Ez, i 6~`F6AZCT`厳a\RO;W|PMh$ʎK1V' z.u3x.-sA UAݮO^V~t7¶vG9r͑ر$:VAyK>YU*NEzG/M\HNvLr{W=S\ JT`7c|cqT7Nf23*9 ?~;!S]r ƓЗ]?%: cvbrOb nc|G_CA C-@g=7Jm{li#~еZw }_In&2@el *ߎ,-5bźاAmoWub6ry^ޥyK ZvPxԏ$#ҥjWA̚;3/Ü~UxPIǖ2գj* N+μGgN~nkFe&؁ϭRmcjN\9P[K)B4 dA9+_J̄[9 ;s].hh 1ORT#ڠtҖIK񞅺U*I%%#qIzt6|w#OEv5@cH}[In@ERPp'Ř.!<=*֝RP.rGR3>`!Cɧj0nSúGg?񅥬Zyom7ƿ0`^n-$nRKtc@:CA*mҾe|hRDK~|)_~Ze-:O/0[N|MhzVQ⤹|S5wWֶĉ OOZ:gq%2Fd@U=5NIFw=/~:<5W3z=?Ÿqi^(E?Oq㡮K֥)6ђXGJtԽM{XK\"s;WAo J /R|;;v99?}_|s-0GiƝ7 /׀OC@5:z}/W?-szIwt}*~i:k,VSEi'wx.Fsqm3QPI"p \7@eWNsydJ:5t i]Y"]>Sn9Ց|>uSW'h[\}uQѫCF`K=E06R9G*Լa%{Z3BX+C/Fi5qL 5.kJ/GbH\`qNGJM!lrk&\w6F C= 4 ۽k4NY\d05~"Rmoŧ҉'}QQݡ|Ջ[cR0A)a ?-%ʁS{n%:2sA0uwTltiЎGqZ񍗍mŶ=GTʿ~Ǭ&e @8uoj7W3+D@gޣҿU::_-p'+΋Pre^[SI=Q!i,ݕpUNVoJMSJ r-N#o.Mz5p:|?.dC샕aki~x1E'+*M:tlIa ׮SRc=Kx2v9#sE4H *}pJ|%JE7^Ox=GaMb]vI^pV\qra&@:- ºm'8 3Ӄϭzw roxQ$%`VP3?+M/W%fwt=FDNCd{S(Z߈%>+ yE*7L 5?Y㽂tISW%ψ ~n&?:g>TB]wė֬CKJ8P鴋R}Zoo%7R'ˏkǼs}NeHedA,lrA~isneնlZ~xN4wSI-,$ z@/ ܤ7{tПryp[ nnDܣ$оFÃך2yM?5v[R/12RIŽx-}_us{4ʢXEJ0G +>H-gEf<٢@HO2x$Us >gcAi|*s^KvwɷPBIǵ{/#Go2IqpWͳ0@p:u3h/VF<_Ez^ !*zxg罷Oݲ Ri_񿈾#\^ ^sq,Vֱ9Z8)u_zXђ-3Q4.A_ܞc)jnInX '>)@:߿|uQ֡q ms mP}~Kldm^8tH* d+3ſ5Z o}^ mwk#Hrvx#wնPCq։FQ`*I rż VP*z=FDޥH'Eؑ>.$\y"ajΙDϾ=iBN'ҤQ#`3Sڣʹ{SbE@Q<8R],_U]Lils#_HG|ΘC_ u3IqeHaW#}Hv\K=PM/t\j Z (%mdmgQ_~UЮaAGLzUWT!4VKņ=8eoAcG޹Z^|CKm]ܯ :%`rqw]>%e)d`F xowLo__ֻ|+K\xN$t(sWПc:ןnմxw0_3v}O_C8ڹԧ򯯼 ~ŬoֳEzj:}_^\K 7=wB Њ̂QĽsú?8$lz\.c7ıv>q^m|K7 ~dG) MSXҵ8Q9$Җw2(=I|M<)&ِ5~sm9?)Cִp3jMr;zh;RB62K{gyi }W8)/OkO~-4+[ d7/tV|xWz9WxᎫM>c ܒsMr_>!j>վrZ Ү؊[$e@!'ch>?Ↄ.o F{0^%ozauFb=$^?g:LJٯco1zQzи4Z~)Tap%On̿QM;W?KZZu絓ú}[1^Ƒ1͎zwY ާwuĶ);.!-ԑ=j|UŬ&SX! dKg=>gxo#C^kKCM׌-b\\[/N쇦:L~[чq^ݢMzF6hqd=zͫ{'x#`^K%==J[+VkK [2Up}_xCZk-IAjEo/5*$~!%[]^%;䎻yQ۸:FdT|usq )?yxø[LKFaJO_s—.wśExb:Nݎx\ʾul:#V7:_#221_޸m1[Oާmnm-0Ҭ|QǸÚy,G$RC2:Vl$1 t%﷓\;\Xc! >OȲG/k'ުi:h'xM"W Ցi^xUYKXHۤE>uy`$9>eÆ;sQ;%B;\jŤj_ ( $'4yZi3ټ7~!JXG^Oj^)[u1C׬Kkj/5b"9 jvh-I1*Y3kWsZcpv~ZxWA=usʶl7901ćOO>г0F^[$z4/t$qjZ>e|瑏wkUyyIMA ;Oɗ=Ǩ]]zvAemSтAڽOw<Zt xsE,O&$$|j [U,Yc*}kEѓkrS$eKt8+->te$ElZ^tMBy}~c^~ %G U0|Ce?ڡqە p~ߌV΃,c-ԋ $ v_~~n I,L!Eg_jYZg.5vGU4OWԴ+{h]lݟzy}Ysֱ44ö'>[}>{@un/Td bAOgeh ac5g ʀ8ҫjk/CS1I3+ԣ֬ʼl>e=KkH^ A#j=:˼@<i4;"FGV]I:|p6YjPcll@UwENNч~R]}Be?7#i&E``8G]uOWqzDkd r3؞һ 7W>5k  hc#a`ΰɡ$[ 돸ݤǽd'#%۹f T=kMZ:\>S0>2bc;} pVͶc6)mDž浺;2k!b:F꒛a$q\t8#Rahv haOk4CiH#gW5-5wiy>fUnx-r#ݓި mj:96˕p܎F99x!i(͉VwiX[Nx5>$DXdخ_Zf4md7qPյw>/VtlAO@{)3[vz[yKRñ) p? S vQwQZFWq-XjZm1R- }1#燑 gx{5T՘GW 4}T Ƞ}5]0z*a"8`ˇ^h#EL 2Zr1NcS\z\S94sTJ01TnWq˴dS+6 ,?d=ZBI+ӥ('Jضcg' ԹFB2u=[vu>l= 9t ֥؈P1Jȣ#h]Fqc.в8㚱 ]wrk{)G0Y〙r6d9c&d g8Sj RLv0|Q/鞢'(C+$5;VIOyNdlo>_+WG=yl-.&_ݷO鉲9_{tnsVeARC;s4\7;VNvk!}܎pѕ2IO* -3UbXnR2:o!]yǨHvXV q^!# F!,'Oj7̤Q@qk;Z5x{lӫg +j?GN ap91wkygFF&u"rG޽?MiHMp5&+h@Ֆ<;5.-u>5]"1(9%k5lnVOJ@ՙV)ln>XIEEƲ~zctGa9 =*Œ2~muʱ'wBI Y򳌉Xz]׼ Q-h $a#+In/ Zl궑[KRM"9^3泲*7< <&,4m[P@3Y0GB+4?\/4nbidȌcɮ_x׆eMBI,5(D*pA : ~~:d6 ;ȏχ쏛'˺<+-[}f ,0|U6s_c~>=k_xOVIV#} {@¾:::ɀU޷v{>(BEq8 (rHkr GnO$*k=f1|+#_[jv1fU6̃+7.f'>T{ǟ6+*k+s^K6ľWKoi4w0"+l|1|7MhH\f+Qd~طXf90q]ȴ2w9{-B8P89^8Ե$Ay+y׈4%9bCJZemDnؔp)5Gixgf]Irw[c.@az~zQ)48F>sj6)TGdr4* vdVfIqjȫ>reyH9AOCFjRCCdm=XQ?%ې-X &Yy?hO2|~5m7N ?0+~k.%*9 @8$*%nt[xԀ0ÑE2[e.m^Z_j2L%#%8?kYgmʇ8ʹ|C ڇrwW}İy9`E:Aqdžni|rPr{UTN.)ܴ]:YOP034nvug+/3]uh区~|J8ez>|:x ZMFC=A|=?s|9X|NR;tcОTuSɟ O WazgCoK`JI~x`Ԣ7t~ɪB쭎 k\˶PjZJV߱>lgscūx}<5֌7ZcSՓOo¾qKbg>խeOvvָtVH۵-5 s.?u>5G<;\bC#k΍<~Ήdܡu>.:[^9W8L8s̕.Wt~i®E]B?h?n4cģПZ.cVV"ٝђ,H5j:cvz遨gx+L\2G߄֮u(I@!{#d_+ 3$m](ٽ(+)m_*קPY}EjZҧvq ?U^O$ ՟m>VEqEp^1g=GBm™bӃb$ 5G22E! ʧYWVMܵޕd [+~xЛ:g~YO>wsfܢfhGKǩt}r?1|D_o߈<<$5㏇>4WR~8>7/Cۏݯ_iZ_(8gOCkĒXhZ1k"ЎƿEu Q"0A>6|+5<%fQִ[dJ=Q[WymsVa lgR?qVӵW:J6pPUmcvo"}kyxgdOPI8X^#ӽҮ4YudRx`2l${e۞ b_a;vrJp-'@?.Q3N'_Q^]o3JP0a߽\wpȻ%WFld'чewʻdEџ_º3յ{[6b1ֵ}_N iԯ@̤l;TCvR-:EivKǦqNV({[T?-FN< '\Ovmvkgv-'84ӵ8$RN䓞qz :Ohi:񄒟}ǧWZ~ YmKցZ0Щ ϗ<?.|ŇVI_A97ÚUΎoF]LmX29Ouω2xjA 2Y#DY#|}v-1|+g.~':/R rJ{΁7fMB]YQEĻ|ܼ` cڼIk\?λhZFOM7HpY!RHQݾlC|B K1 qv-u=Կo %0Ǚ>座5MAx eWRtT?Zԛ7iԒ wH֗-y{hKAVF[;UYJkUa7 vJn=[㙋Ļ{T_1JB>3=29ܻvvJqZ#D\r:Ҳ彺ԩ" z1 #ڭ4k:|~b$X #Rxl}i*l{Ƒ!;g9BdԨoJݭ'ӥIEԼyc])qmI r[ 4_<#Z_xyث r=_Aeo (* Z742V# YiE1Q@Q@]u]v?J2FA@Ȟ +?gorm[K<ⅶ}5KxPJ[Hxt ߿ַ~(|]UXq ;$d>:ݑ5si'[K ƅ3Ya5(;[Ҙi76!e $M~Y|b'H$nYL0_ϠM\dSq-ag̞9ufk+5FZbWt5-CšvC_gA8Q)}Ey}6;9yٗ;g#9jI}g( mRb+Vih?}i8h;*Ɓ>n׆?t9xTAk? -D֭F2(WZ urP}ŚRkeF:GGz=cAƐ <u^/.@N?^uѾ˪A[Wxܳ\Mhnn^^Zh x F}Z2qїчZ\7DuMKnmףd?(cϡ<;A[IkqaHddgץPR!tD$ Y v9wz%} bq9Wʿ_Qۭ|siw䶹0#6K'O<iZ_)=*)3Śhmo!/~1zy'6܁־W/pX_Dr~ů[lL:G׸s K]yfZ-[Mp>$w ɮ[df)( Op+tt:ew+)5}G= i%mQ (17-+\F礃{S4}VO N.lb3,~?jέ/3TW#Epsī؏cT5tRd~;3j ۓ qP1gp5pcNwǧҹhZb"HE&K9OHxHl jĚzE+~_o޴b<::ᕆ+?/^v'ij5Z>ۨUHmoٹ5jZDrUZК5֬WE_4 H!EfVeäiƱigs c$Vs_EK6sh'q 0e}0!#k޾Z:2dr>+  Z׍jN&GRv6!{AZ+,}^w'm,uؑ ?&vi#AھMo ַ3B_cD%ήD+:cڷ0~f>;{U[̚ڋyBx>CGi9p7!䰭5/QzN xĖz>w}< `ks|oGeoQNI,d*zuk4١2tK+`v ?T1KBև߶Q;jIgvjOE^O :P-eA'֯|tm7V%T\FJ`Ony>Շ-ѹլ js*Q,&n~25-kQT;ZCnʥ ;uKCr.c\:1}G^ͯ|B+c'죀}E @gǩY"| c}H!Cc<5fIԭ!l Gq]48gkvB5隵PNՓǡmJm+YFnT_δŎy0KrY"sA8\c*++x>($e>٦ݼTB NiPXH0H >XQ[+MSۨ*ld8`#5|tͩ_ۚ#\G"CGC7$vMb5xUK 3?Zmi >0zktKY2=?\ݵs i\4W>Qz==ˇu@ya޸-Uhed sI iwV 늛iaߦȧV _1H;qװ9H]Ԋ#E[6 FAk fQ)i~棕tEi1 Oþ3-88[u lpo4tV E黾)щϴ[xL.랟QZ!VwD?H?)k* M<8Wi5F63#i;}_v&nw=tS8pqS9`pj诤]3*b2zwڳ"K/rԏ]L/Z*ȂS>Һ4ed'UnƩno=U..ʓGc:6AS]VYf2I1$5>T]Э$ 1ij b=n5x"3kdwV q܌Onσf.Rw{W{QWig{_I>}f[>:Ң+NE&n2ww)q|m1$!q/5_c5C|4X6F+HC6;_%Κ|y{zJNk+d`ϥt.@. 2Ŭ5$S@ IkOxmk+gwЊ$2nA[#O1̸3: '7v͸9M;j+\2*|Vnxo(M3p\<ִ`q:2GQ;="G yeǀGcYR6/=o!7N+|_jV.@C2z<\uԥ'@dǭt8Դ$0fS=÷Uω<0ZKޟs~En9?"x}==Ox`}k~$6U4^|5D[zF}9+ F˩wW={Ϳ|/yJ]GӮލ#"WOҵI⹏Ȼs/،/ SuVؐ/Dx~*|u鵽+TyNZ߮;==+Ƴ>o B=kU4%US*-!V=J{Y(.ZZ<~#H),ppV@>`>ZGKN ) ~5S%'U`y k> ZHmL2чY> DWSGsfWs\Ѻ9z:x+{;A?yׂuU; }k/v6^4мAMU|Gly 5NO៌t=N3դX|.xaZYÖHkMOqm%̌#c:9Z|%I),!m@< υ^(ψ^RE1+C>iM&h9M}Q $dtjxŏox]uj/sFk>/Ɨr{[c!20zW=~?|Gmq;P`YxF>AѵCK[ّ34Vit-ώ ! XMn,?QW3; [En o"ǹ3^k6jolc}axVFxZ2AEnqVJLkV$-6 "=Wo)d]+2|Ӏ@,7v$zWmX!MIo޹l^Ƿ]~{.m(NA8\QJdMҕF,ǜXc sʞW.TrEVҬj 3P=I5l %Y$Eb*Jc@~n{'^bW9sPv6Ah ʒ`.ő|?Ե+?2CҴIѮF5kazi 7vHq$D|*mqA8wrHڕb8\ ! ųڹWEYK|ŹVlh央ׯiһ#^<?"kRP'Xr"Uwaxpi 對H5^ۨo TD?u +2 t8eHJ ⧵'5 Y61dy4kXeKd#\-=Bpp eG2N5x?ʢ%0kG*gIwMhv7>[0WKlC cj\:T2^&Yl%ptjDBdhdSă y֗!fLŖko~D7硧b:>u(O:!cbxs7K<s ''KAݻ˳Ϥ>G!F;} {?s? E/1q|Ѻ9;ץK WVr}ꌡtg'& |nѮƺ}Us[ 0u(4GjjATCYgz ]0_,<+Ku\$zQ_KY_lfwFJJ,@Io/V`£tQB-Rbʇts!ãv VԖqX\z)w q\ꖒZ^DC @IqkPc(`{wǃ I%N"ԛe=M#,8ȼ @y`s=TZG/4YqC($βu_ j1Sli:rUl^A? $fɮ~9K 3j,;`Úqj֝ *R>*znk;_5AH>Pk~hA3T@?|-]7[;mA->ߗtk,:\[ʻD9WcՔq,8V!t_=X>KjNZ?uiDxgƟ nftx 5J=SQh _av5% ouc"[V|]SK ź.]4YԅGRRxB5[}u>nf@GF]F7KNe9.l~r{:.$wz|+4ͅ:hnXjF9 [^ex3K+)mT9끷OO߈%5EQrD޾[᫟%ZdH1$ zw'VZX\ rGU'?R_ KK:_:$?^l4++ݳ` 8 C{t4w\J_ƾNռn:שA3y|6#G?,!{ ^Bpvt ?=G*eNID֗6 Gun8?CI ox{Ha{;oxKw{fѥ%' '-i{e(ǖU#,?W[kSYݗ*|H+`WXOd1] ͧ=T}W3ĭ/8bjeGi%߈@(q*H1_Rӧf@pG6r _6Rx:MJZP=<]]Q@Q@Q@Q@cpAÚu|O+Nb9{@QHk>u|#r5͏ =>V$_Q]ef< &I0M|6|whX4Btwଃ޼+MkQ3R-f}T_ߋW ZHL 9h_to^T+CA_4Ts sYiCCt/u[7- EFIG|It <)XǗ s? CPK&]-r2#_Qa:yQmW95=:Xc}xTe+Y_\9d_AJOm K>nO'1&c\ x(+>YOy?Zh|5?S GtSfS^&cžsa>ԆTǀ-7h^lc߭yqҪGwHqBz5Eǜ1\tfcy\:dSNFݳhZ:[ #$223:sgwA-no#u}Qڽ~\K%+FO߁ٙ<5⨤37@_ЎD׃|Rzmfipy_? x_$wQ706az_:~H.\8q?s/oʻM7W:0lJ؈58Gn=Gi[F _coᛕ sw=9$PG[}fmVcă=f"c23v??UUϥhW 2Ge0n."J;C%ͿmuUnZ9t{z>+i؏Wp{y {$Qyw*vViCES\67L|{4Vf“yMRVoE9Vg޺{u>kS泾Cđ=_^RhFzM>c9Q+g;??xvRiqIjJ>چ#< JHi?P 3`{b[{z^)]چVʼ;ú߆u<ᇦ}}+믄?Njcu.R<ȣ+9GTI=όo]II,OsZ$?uzY4whW4cO |;wjZ|zK07"=zWFeu}F[yUTH;yZB\RZ7 =kuzWxħO0co,}*sPVϗWXuyf@Sjr^5$]%W3,vI%ǡUʭq_[&caoBOZr,yʥеEĒ-4$^p dP^18?}+;4=qmԦm഻L5R4gRy#[XU@ar>O$rnI+~ ~:n˦A )URO!(1y3|[ܲ)##*TIcVEU^U!0:qpV_6ZO|FӭMEt le?)<0s\w]:v3.DG $_uqW=-v)^ ̊TIVPZwz4YD GS?׈|J¤.5j"IX$`˜kV ɤ H-xNrl\dp2z)n8 h sдEqOviHad9"H$S:*Ms$qU#%{:Q..#Z\J#"]ѵDү&;m9C0-W Te =/Eu pZې9=hZu=&.+=Wz8B|֗pr;jk91E6ye= tYӵ9뎥3kG9a+fģr05j3iwrDۆGR ǥ /2";0@n.!$y]:BPpʚYIQ $cFݷ邭>v`0v?![xM6##еe0 2=+kOKkl{K}+x kr@C]6EqD*)Ǹ?M̸~\ ҾA7-cҕǘccExN9S]-'k6fPKX^ZNDyĝ-*VhNsj^IΧ!= \3* Ԯls3W42aЃI1B09NշmNdQB7B>Ԭ[j2.Ż|?0&;ss^i_#621۽~^}3RF={N1JASB]Pr8QV[խ1(ʚ:F6҉ &˝gR6I{ͬRzƢ zL;6L ?ݓrdty d{WDXR0{ZXI^mméYTi t*$(\ZV7O޹  ˨xzkacwuo >`;?DeЩ#uK@:5qJfm;|L< ֌X(Fd$^k*Ũ = \p[,+}]L?#q.Q5\@`q";{U1UnY+̉x|dP} sc1cɀI} Mt#ظ#h_eFp}xvM>~5̻eK:&;{mZFyŏ=CƵ6Ȯ>rܘ'<}G8>N֖ڵōեմ-Bq׃JkyM+Qƥ{f/&Ͷ'^̧#x/Ě^h{rx5<??{_[ i1(4s2 :/ȏ?G XEk%˱>~4h_:bcD}\}[~Mjs%5cU퇈4D>Fery|g {2=ǽs^~׵ #،ưz#otr9KmY<%۲J>u57ze&HSn<g$L|5LèL}24%@&k{VU8R7 ,c34`!=r<{t{޵x|=Zpۛn`Q >lnckw bErqרÒ_-'K"_Guߜ܆cUGe#bq~n5 V0ƫ{}*o̮^t^T?̣­(`!SLmuH+ݚ[gӇzzKSI6&1*m2tgc9I۬,I_.%k]I<̏]]0=_F9H#?Ŏkա֥KwAuIUF/q"B)0k8;l[= &QhDNJƶ>2J<_\ެSA HW \dJ9+9-]ODz֞P%yU0;u{A|\:Մ}m ԫpk6ae+K_`BĩI"hة\ W hoh \f9,nNE >V"12:dJ)Z[g|o6=ILzuX$:U23QX 'Z<~;OCVwpњYKU ^ CJ nVX1F}R ttI={c|&<)--/a"vws~B\k54j}6TEԟGwzqgy]@d ĸw=QfļA~"LĔpzW?hi #֩c Mv^ƺ-Ć"!dɚ009 aւ +VGMÁt>ۿ!oXtVeSAY<>ϤkX8SBݳv^Ip NG5Q3pg햠`_YWǟ; A(ԐIKׯN;Օϡ.ppvg|db@hYr)ՑC~Y#hP0"'z6 m5F-Gv}c}bS"7";]_OQQZ3NC:ȵ<5K[o!ym՗h/"m63BױzӰy$˂sZτ̑!m!@RUutR[ U/gQ%tpsTPPEcTcث0Ȭ?T[W$~dF.hPdu;[@U?&bs=W(z֜x>xg=њ%H# eO$s zV>I_kFymCGG/\s+> Q\Zti:qϨ]B<- }G^/z“,w M '\0oҴYgpW]H* l־?Cm]6T@{\@9'Ru?ND|?zXc} UE0M ;G+fMִǸ% -iPɓacv5kIr~k<%ί;y(E['G[]Z[ cu QH>@k N펂n^mQKھ[`.fZw0s܇X[b\ Z1J".zCYEunrf ó6f2GQzV[ꖫ=HӨ>Rw,ESQҭ5{v'ajEpY-5?gOަH6~E{=dx}fS(W +ƣӾ Ӽuq+٨<_F#- ã꧸M񧄡mff$̰HmOe8Ox*Z}1=z{7=?7]AīaPGrhet/sJxF/-B-u>/u^os7s6>>i徭'Z_6 TT5jGo iH8taєaם_X_Q]#Z&ky=@aoQOqQ~^>lu8vǡ^x|ad4u7ju_ eJR&-恻IO~=Wu3t{ᏈV3G"5wV]CMaywZ5og6&d_ S?uhCݱ fҴkhYAW˺IÞ8χyhLI pjoX]S!QeUaLt*8- 0Lf_x#IG[n!>1q]|'OXf^$V?]:mD,REJ#y}#Դ{Mo4S ߛ=A?{~"nIl4UtI>eP=T '|t%OK=2zawX孼U?5{rpnޤz7~{׾c6՚ȬޙqxoI  &q e^񿣏_ֳ-n7pS4LOnqzv=ƾ m@TU&91ǵ|⟆r ͬ1 d{exsE#qо C܅,.lsg涗2x#0k𷈵 7 ܒ:#.ٮ ?q[8?Ʒ;q}R04OT4ϵ4bmm'ĈyI=+⯊v>4n'k[@Ck>x"}7U$XO)S`ِȮ{ÿ'ڳZj0Gr>젍2qϾ}k8.YXj#Kuo:͇(v}?R:%ה~{O>sx`iIhG'ҨjZ,}G(EzBo_dž|CI6~z;nO k[ hbWH¾4&~-.6pz_[x#xUwIɑ? )Iɜ5ς_zv>(UA^!֡jAse+A4Dp@k iJ +|rk^%e򦐡—1[浦Z\vN"gv.zwi/u[ue=qYK#Q“hMyHWG}u.a1m"Z2/Q\6n"~-58Z V1Ls޺gAyy\sYM6dch*2\cg@= z#҂'f.Ix~=^3S2}+ cݿºwM{ -fMq^A!9ZK}L2)Ul8!=xլD$ny|"x8aӟvQ)7ΠTĚ=`'ӓUӒxic\)|MFIW;^zTzF%vkM38=pqZ$ҿ7r#~T{VIppyv<{mFSA\*={ p~rr [QL T+Egn>nvAeٳDNS>2'SV0<i:IiD;X`#;<楴įo?Β0c=jbo<zk#F ~|nwjI:NUcר5erx U"yIh+&1Hq!'JZ jaxK{[v֫'ps∅i!C5/k7%yt6`$V`~T:͐ CIi*ӱ']ꇘmh8F[&)޽H}tZVD4m})+pHѶGEh]ylJHXVҔmCP-;{{օ[XgRՊN T_>kO_ m{i6l/qPkTN8UmZ~sF-.xfa,p8ߚ7ϡ1O0[!={YZ+3qW=.Vd@sl+<c'=tkmN}c[ y@Iwh;{o ,tm5,9VV=)Y|Yy~ު2s1So4ru}* ̏C14I<]g3V=F k Hh Q.?ՖA?*M:ݍS]/,<9Sd{U: etO#O> gUOSXi?cxpǵb\̨ҁObr9_T 8uEILWQ(uj] TcQ_ A״]qc'̠}2G^]\U!kYDH:^@G/C=g߄?F?\<6N8tHs팢X%e9[Iht R: _{W麜woMdW T<zm?Y'@t'Y]Kn|) ?)=2?U}ciq;Ϭl%/T:bF3ؓ^_)u):믘\} 3oՠRtMM/xb~~%9&'2HAwcl0t$jw>դe,7lH'7_}s+ܴxok.եsEWi^2XRn(dR?bú[Eb@u9,i 8{ /j/.5 .v;e ܧv|Rtz5-5Y~끂ýmGC*_FWxbB& 1̹lR`S![WV断xh$y?׎xSSD:>=ǧ5_5x/<_;*Z)fX\)m_EJGBڶ OY#@8A8ָE,W,tEp|~=z_ɩh:}׆/3vdWZ'زfRYA܄r9⎯g?Yj.GMk-Dz7$]բ I.cY~<|t0.sÞ7 EZ;S};=*O1{ԧFs`ņpGVބFZ㏍:+F.+Gcɯ< 1>t|;]g@_xz[Q$9?ZSqOZu8Z;w(cZӼ2WDe^: ZTԦxdDZ 5Ms-˶xU*۶00{WF.4Ki-$D{m *|u5z_2>4ɌjV1?$;pV扔d#o oѾ˭[HԠM d_??g|58 +UIO@l 3_Ie 3ijޟŨg2D;yuf:OtYѯc#$r!+njEwƢ~XSuۆ;WMySFdHiǬ}GO[7\1]fQqzF ,C Ց4S)+ոUf0xH)D[Edt=ʔ'kHD[3+)ړGt[W_@,?ǵy͌ZL>W@4)Fyñg}Ϧ~/βKŞ| x7{nC=Lx w?_a J/[u),۪vo>h'S[sWx燾!hw>7W3\|Gi;/F;ҌCz̵-* ̶`T \ՓF2ձ 2uSI,t<=\##zJ5n{@'ve\[4mFw^=+O+֯~~4oW ۜt[+m%Fsz4_P?p8q?^mn Z9dW ֎l'Bj~H'3GO_rx7zgtoۤE*z{C^]JnSR:píIY1xLpkW!{zsW 8ur/;qQmPsύm|c;DE̖ܰMhNON V8Io>Clzyl? s:k#QO |A8%-5P1oz;gUZ ȦYT29J sw?h}u*>i"0k[Km{u UԎƤbcE[eI֜OQ j aM1 #?CTWpÚQtj0#V.(cM\y=A\W4Yts>a|*{zQׯPsMiV@Fib}.IοчcWkP]ruẽ3W%]MF6%} rzFWUI^n- ?^@Ek(Hrjye}m5~ lk̵˩gI-I;xOEN73QQcm_~IjzC#XKIO c<W&=&SC>x'? N>s}^~|!/ᖷW:g-0O{s/ozWNjjsqqw[ŖuEMcޝiۋg7l7v=IN!ިp0u2nMzRy&‘TZ%۠.2} J6i8?!S]} .0T);:Ep;a9sRބ=)Jn|CȣcÒiVy-\[mʜFAŽu?ӭCV-;4QE"(((((((((((4424SFۑ`m]j.Y3 GώTWq][Ha#=Z#_ ޻7 M;[]HPNC|Y:@zWvݫ4 Z/>}J?ׁC'n?xǧ唏LӮ^O"6^2j/7 Yisj2jCO {׫h.н $vFE.w~־b!il49qxm$``ax:sxOP֑)%mf `To@ӜWU89WSRtn*B =R)Lr MtEYѵ_-m Ko!@acLO<7ׅ[Gs'Rf3?UA`մ!r>`L/E5CV,M>Dfl/_1~xZ0lI0+{xrMv88{Y;kPټ=b}m5G"@㣡yևϺ`ilV ˖7'2D}}EI=#T.~c;:OYPe0rZ]ϔGuV[wd+7O䃆*x]yS)%]YdGVԢU'Y=+lrpcZ٭bhˑNUt>J{OٶcZ[y&0x EZRjz;dP>,WxY-<]hڷ?c~_I ~fdq O ;sPet9iǙc8io֚<͠[ok5lSâO5W16~hS'!u5or y8daџx{WMO~YTjմ|}yKK߸ac$Z;T^݈5-&>KP.\Qj73+0 q4]r5kEW])u8n=qoh֗JL4zZ tILRcOڍ:XXYRY.Qw<Ъ9 p1ZB7gٮ=u*yp, 9Xv{U>pJ%tmbEMg"Z%RyJOs.i5 =\Iq.3OP M,Pa Dn ?b%//[R{';F'8n#[{ W_۞fYNml#XV[ǒ  =;ѻF۝v|. rNk;UR[i|rtT9E4RWe7eK&ѫw.4u"K ԐEmhUeطn}b#[m!ѳ~^?.E@z%d*2<, KP Doj%%>`yosZVQhF]HawҤݙ3LyzVm\V;j0j\) 2\ǯ [] Hl<$_Ϩn͍1/s\_znS5X8R@O,]x=O*{Rյ9?/-~x%Wm>7xÑ$ucՂ}$1_gn-ᘬS&~V#3$V_ZU֧O%  27Ms2JϞ[qmJ6g4+:OQ}dGK"<|S2 ҹi'M&@4|v3zr[Aڮp}c]`l`wֵֹ4Mͩ;"B-Iy ^ 1ɹ N&J*P5ah=&FSgJ-$MUu*k4q sĘH\|VQZ +r+$bdsWۯ@IuLq <6bZ5,{xF19ې(h\`2sY>#ܥYE(ݸ{ڭ{v9Wڣbd/OjӺ,rzVYcx!#Һrd' Pm[y{+? \ CxviѦU~º:JC;Z Tۥ njc#+̯a:~а>[r1^ S)]A?s2ӼThzZ3Nt"H%j=HɌm'{ҭ^kR]ٕX=$e9NN Im ?vǯҹmV[hڬsUnb@{vrA Lh2k-FTG֩;mz;7RÆ^ig0 ;Uտ;iKQ> SEk^Fݏ""wI3ȼOQRY]0*ǿg{؉nQjuҰҺi[ʣZ LRpAE-v=V2JαkG>4[1?ʺKyR2+#ĚB^AcԵCWS|k#nbl7ciY5ɗ哎;ҡFo;]I ?#7aFH{%ʸ1tc§Ğ< FHSBjćI[SZ|^[s{dS6 Чa4|W2P}AZ~xM!bj*gv8hFcּ֬_C;OQKV2j.=zg/C&IZ\6.8aEv, )74>rp mCZƏ͍V&kY^1VwVfMYL1>~~yR՞I!RC #ϵuq1NfUomΪi&.g? o x'ӯ>68!OpGQ^}xO "p 9 Dr { ^ Z"SU{0|'_tW7ZBz6:=G\SvԬ!I\rHEx~|6u'մ72S9?Ŵ|)~j7&pN|O*= u9Ҽ_K3[.AB{wqz{=~XgWMQNἝ^)Hkp:Ϳ =B]4Mc^x/9X?eݑ=ּW 3Yh77O /n g];\w0:tX.>\cJ; MXOpzQT[GSD3s~kos_jMcREuT( 2ϞzVH%ty.l@ tmQcY{u;mHBs<csɤho>a!s@~|/|/m5|W*9UKDLi9SÞ7eH%z}+-Z"F|?CׁxBm,#go?Ҹ-BB- l 0GRqD$ oi^;WRī-mۉ"oF^dbW|Ÿ,d .Ϥ:>|j|pF~IXt#ھIF V _y-M=ן(NN5u_iڌ' Ob+N|z5~M[ϋ:h)ݿh/+ǞT:elABhE~]t0'Vǒܧrcſ$CmќRjxI]%B l89I&۔# O2no֪8qS{㹍pUO{;vx=B%#U-K18+9A2Ԭz]"\QxkǠfm0G! K.k;&1HHav5ztsdo:qz1Yx-!QW.@$}qDd*Q!Ue}&D1VH VSє> zZV}8p%1*QZ^qPMw w׊CpIى^⾳STXr N$ߎ_,2h$EvZEs!'u)+1/¿Z'Mnl' r d8&#m[VoCPA>.dM)3n9KPݔ8'ц:eoo&C/jfo fW#u#ŷԿۓfn}hhiz=ާkkh2$Eok> z^ Fum_oZÿ>,_iҧmvqs=dA^z-톯kEy"7E'v?J[h7z={ _x3cǞ о r]/[)dc*{|}Vm v%C;{ќe G5>7e_8_7zIg19>23GeBjOeCV>Xӥm- IldqkW]9 3wlo@}݊,kns~.Te|=,qGJGԧ ,ob"ua0=xK2qkroynt5ڼwzW1yKw=3X2I^p'̶f^GКn C8'׽6H _Ċ25I@ |k&.zSwtmyM:zg,w`anZUci2q}+XT0׃֤bKFِu: бQܟPjHpGZui:K[n#c]ymG'F\ma޵|3k"ovMuG1qj 8.q=v~|iCTqa'''[t U4}@I ڷ[t7B5!ohþ>`&-OC,JH p?sZ?.מ)Ѵ{()#90b_o߆ַ]Izb0e1Iè־}G 4h6ݘPjl>þCеMNh>U_ܪ)ꌎ|?wo}w=Z/sҝ1`>1}'u4xV^yj<;}oXڍ2:W~!|!A1C}r4R9GwQUk+{ [K[uC[+\F9qpI+i..ᣞ2>;e7i׺]:|tbFA^/]MBo-%9ct-$dM4xzYqHI}>S,%?=8͛8j~tm'ξMeZZiڴPlcXd_Oq\^xBY$qgp,Ts}C޳(z:ԴD,K4G#z-nz,R8$Kܰ^}+|S= (vyݏJ\!uz{ȍƾ][F-6} |%Γu-rBvŮn :͔אU]ta[ҝ7GmqWn:~c(D2ORx>њ6`t:׳ V3EFht [vRϦ!KWZ)R6Ҳг*DnTu=j=f_9T x~o62iӜ0<ޮ%Mj m0E. % C.Ӟw_qnSQϿ-&+][,n_XcWoMlT7b)=q^!|yu?CO4qqG6=@ds.t.bqvgĉ%##Pq-#>╺ mO9 1ؚ%(0,̭WdRNaf pMUek:1&QA"'M݁x#u;2c{?s9dss,iZ,xn# p3*tSy>3dq12+-'?!c{ԭ3BgUJp{ ws:ú! hw X^QH@~$n1zPc<>ke/4,Y !Xz6uH#d:\).Xb4눥vECk}{NG:fx 2Qq2%"IB^w7ӿ\['7cc}grLVfņn 9vjJ60:kmyK, d?]/]̀I>!c7!0jW89vrr]EЎj߆ķVsɈèE|T\d2xS_,aϔc;)9:fiW.e]|ݛVRy. G[9&|XLLdWlmxgfF]NKi g }vIE 0taȮ_쬿4gG4m8^}Y7 Ċ<,p̣VnhΚ!o2-}G^k\g7@S0s֭@ Ș,䚪n&J;GAַ|Kbހw'1g%D""RFGdSv<ߡSЊn'x#OZF^${v26tCS6p$(C) 5j)H3ǔ`?:Y$@{? "?cPQƆA+}sl->"H)2Q`X2'8-SLp ONJMNj5U!ޜ\"eqcC:])VEBvgsR+*c8+naNP]]|ԓ`c8q0 b Mms-28ϿH'Ixdz0%eމ zЅHeo֪&&Uc=ҧR8Ksa\yoxFoZ"#?`:jTu?݆vkr|Տ)nm@6H oCUtC^z҄#._Jԧl㱭5)8?Ŋ!(YqԏZ- $4nQ,^Li"x5X2a+p=nHfw.mMŤ`^{B9NԜf0z(?xv5[>vau P{s.&EֽIy湣zSC1i2YOֲ5\ F=CZFl 9?ʤR)>h;OqIG^ ȣ<-&e=xzE|NqzHf-߂u:MGCϊ kX ǜ{0rS.hTcQ1UsEQg 8R՘tu~!ҧy,5+^B5=>fܾ_g~PsLWa {8oa%qW#:P^[goOg$Rf:5᳷J\rdw +{Wiz@UC}+D[2pPg֤f[, O]ٖ͝p9W)F-F~ե럴-bHX_J4nskv >ƺm4Ghmk0Pm񦟹_ֲ<7 q#5F[3i;-o*C|dK L݊+gҺ/:}59Qv5hwi"Iݩh%] #u4F]vIr.+f'Y\qc_k*O]I+rq *px5^)6IZQY[mix] ݟk΢" `N@K$t }NFZ|i;v ]}S#P{Swc3C*v8=w5MB$ÁNzgCx|KO$,ު{Se(~Vǥc;=h4n'I1O^W!_@qv4彜6'Qu2_G^޼߅0@-&m*KL)oB[?r#%$oI6>=5񗇢`/3Pk-J?2jdA**sc;3|"iCn|?3[>_>mZwäз _u[3%E mu3YJbipݹ#5w,xQ.u+7ܕ&}1<&/2 qnyR=Ys]zGa=geuhu_y|vsh-HӖ ]x$۹l\[+fWxeeVΓ!WcoeIy#z opʫ Tt&hʖfqY)QK1Tt&>eM[xVPbHy9+_u?(+iehK" s=@޻9ӾTkuI]F#U(OW%st=bo'=>Z嫇xU/пLZoug̓y-,]ɄgzWMlN`A~x[Oxo^ջ}{׈_Γj}gAlWf=:>:I7*vJ0}i`֮'XPsʻY9z4)scbd@,3 kI!+): Jxڣbn U*5x!YJ0d^q!VloZwILg{ԴӱG/;{,IoҺ^ķ6n$2>ᅞ'hFYOZ!3Y5MЦNџslqN$f3ZvYlG?20V=FOM5Vܨ:Hu=#3>,9%ޡ?x xA#l4mWz,rDxBJ ?<9⫯]`?2 ߀<!<=RR l7eosZ FOi yh?j; IoK$fDpɒ{?zN>dzp0 h+,⽰%EFVKmx$\WjE,+*p9I @&Qox*C6Ĕ+ߡIxsVgziMOL8?t0t6؛"aY|{gҟa⦝otz92hr_#j ;&Q̟zĔjIDCtAERt Z0UgӦXvK˔<nEsrv5 #U&MF.-g~.eӺڱdF󭔘 P\fAUn^1ޚvуWfỳbcOR 1%>JP(1WLq%Ĝ`UY10i3mhz{NZ(hdisuW?֋~i%)#r0!}kbkb,{#k5-nDA=1<Ϊ[?E1Kl&M.dѐ5QrBʳ͵̶l< N&Z5OcX?1oaȜzq^{h2imVR~]պdxOY:Wq~kv''Rm")g[F',9SԱ)b{Mi3 ZyjfӀ̷6 zOk;w.B 7vp>NUYS?۬A{qKL= 1SE`}sшK@`PaFFN_H*;p8aEHG̽ׄŲ]F3m|"H5Nf6en{TIS=zl">'i1`ʕYmȎ(u5=$2bRUS;o/|)_tM5s{wOnݽZEBֲP6$v#}AL塳ԥA3Nc =,fkkemӳruz7jco۵c;$Ako.,wS{x׿ׯ|wӴtRFű Sj5+ (EpH vRz?cp m I%xui%iv綔rk[<>,ѿکvbFF &W]Lm~^Y ϥ\+7ь,zQ]#CB֗>Y#~9UX#|.S: zUыJ-ݜdeYr=f}gN"K}G|$¾"gЯ|ߘ_jo EWM&}'{vw:Ήnj8[8_IT#v5ݛGoTq7Wܿ>7}\C ]{Vorsn?v.:Q^uacii,!1q؃=ōw˦'/{99IGNGc9~|`>"X (7|<+9qסqz5?}c}mȪukh}p+{\@!QhO־&u [sWl ų夷EyPKoVhb0I}QW_Ƈ6616Xm=)-4ZFB1xUԓ+x*=:_ubD?g>h`Aܼn:#s].ˈqfc̳o}#=}kejUX!ii7 ݱ5k:eއ{%m{ٔI`)!ܩv$ʋRYHy?}5Ywک@I8RhQ,z;5#[O j)Fc7;ަSQ)F.m<w*F*]eV89 +YXЦmT!^#5ė~4‘i72fDpuӌMqǭEf g}{4,$s,:onj} ᆯ64쵇J? NkI7k3zVےN{˨o33TuxˆWÑTi1Q*7( K!G y,Ev/2 b+JMM&ǧX!:ci"H1$סq)3gJ4,67r}iIjPQ\ˢjv1 w=ؔ U7eQ=ʒ.7`݈j\7#kO `ҹ=GOh?x4y{i[m9cd#j4'͘O5EpmpO'Vo,di43<75b}:_C5kbӐ]iyX;(ȟÎ@dH$3֚kI PI#Њ|4GͰgonz/'NϧE&%)8k쓾nV_CMc5 /ZX%[UyDx<;Y3xkY[{ Wnt,k"LTG?;3Hf sM"[tVlcp89~Sk?(]dn1YOqM+<7HoHغE9 6!Fubk:coR=ƂS=Z^I~8T6.&<\OFÜb#3u-1nRYWp8~9z Z:f8$ 鷮Ǽ*qvƵlgjb0kMVT2q;=>Z.|: SFꬳr ϭWk9Æ;XCZ;/;>`d&kd_^}o, 2eAL%_Gmx@E? 8 ?s]=3{W6T9[Z{*]4nGp7!|l?_JVenjcX`G]:,#"smH6heB+&0GVx2a]AX:tٚ)b7wSҶ&} 1?&[=M1P _^ƪ6B{m0sPEks53sUOd >rUZhAu$2ke2bq3^aqb}@11=+Bá_ixd_CL K;һN9s[)rfp3\-hdSj#z$WkG=E*bX ޥ֡Z̃sXm#) 9C;2Ef_p=6 HFpy;V cN2G T+iV5`#1kI[ʝֹ5DY74,py+JZP:r0r3V4 N)pCjhln+dQWcuwqیISq|ɊJ7( O*GjёCLTLy`kfB0';cݏ_LUyRu !Ns{¿tK1n,mߕrz+puo-扄ñ3ѤecxHs?5DnqL2#?bO/ ziCOj~n UmčSh D1QtA-쯂kgo7_ $YM0hsă:9Eg5 ./W?D?hOᦡv Љ? _|7+21R?J# [[Y#NAd-sot;rtkwjD?s~\:fռ e!q4GfKdw<}zW#Ox'-.Col7WCwwesυ;q^JhB(40&dZ/fC_Rә6" A=)GocQyk:-Ή:t1ǧ׎-ԙ.+Jz7^1,8Xz$]S>UmK?ĉ}.>nFFPVu9#m[+mFTaqMgpv6TSI*BoCUet?3}km&*#0sk񦫩xrP0ڲ<}t/ϘT3ؓԥq_]98|?wu\zǀ2עXR!=vr>+'KƯͣaF!qQ9#Hf6v'I6ҵD]F?g؅ ||2#iuo.qHF7x>կu/G ۱c޼Rⷊ>[ucI)OD6ufN>|ɹ8/kz>o{.q ceJշ|[#"auvgA14va'esn-omS\ĊOq؟¼|K'Y 9-u>exXl?1i)XAwG>#!".~H= gvQz]|.K9B"2G+>Lj@7nPGA(cԞՅkZ[;`Y,yoa٤cg ?L-+rJ=85Vq^2쓨#}i࿍Z^#/d_ GLVOf]+zl!]|5h3. >C[IrX-ǩ]|iG4sħxt=u:L[{Y! F`\Hgs+پǰz-c+p'@\}SZu/>6Z0r;Qxʹ}o[0n<zU(m x+WISŻDr^gQ_:MbV&?Cړ~-Լ#Dд.%V+$Dt ((W>g_# [xٯT`N*OQ{lVwXB9GEVE~,42@U =\I>0K.M.'F:~Nn䑬⦹|H {= pwزf߳zfi]5{kX̞OI3+&uVqΥw$ ;dT1YWjGH!¹2[7 ?O:_Nc9=l!KEDZk|85[F0 r:`A9Z5.i#ݰqGޱt~El`eʌ?J @" ,? {VW3qH~l+zm28ǯQq$fW424n=Gi𗏴[-88'kŘezgҢO6u*TjC?veߧҾ 8_XC}4k$n6 5q7@') 0^+iO3 .~{?zjڣ |P~۠1l,FC=u2w?.PI4l2d>o[Jֈj/B^yDp3=ǯ珥LmQJWx\x i`~mJ١kMB 9e]89~x5j[%HÞ=osk?Z5 0ݵn2;NJ.̙qdm%)0OFiaD;p?Z_xY&M2[9.3s+KVbyֻsLb# ݢ!ɬM>?2$@9mt6גe)n۲hïIzж6?'^ ݔeZTz4϶'x6<CJC)}h裣}*;Y71;4}c'{em}qZ6>*Va 2s}PKB̬z+pGz͍W X :kBR;Ђ}53-O,+{ gҮ`[V<*1g$[j]"waWt{VFD=@9qRVeFN/CW杯X7Vr >k~F_-d*pNJ"3,5-QKg#np9W_Q޺jhr #9c^mN&|_|C2麶MGF܂:W '$6WvlFޝ.QWц~a~񷄴cY(bxf-1A Ɵ :M5ķptI)+%>1y3$QD溏x_Kqm;, P$+& h.Uї :=k4d:8kzQAAEPEPEPEPEPEP]MItf9=ul2e } TTx]MūJۀA9_U+_JePwT+I8'lK0CLמHi[BTHR8^biRIip.&d'qR&3~o#L"Q50 6A{+-+kXUF MWRFv=γ]p0?Sf<h=h)Qp֘]ZhFIMj桡p+7}=~z3 ç ?VD;l!>Q^[k2$BB3Y"́DJ|O -Ms Hñ>XyvZ5;a?y_MkǪi c;8@NЉړ.$}akxh2 K1S!<x jVؾ2# t?ϯ\9`R0½&%ɀ?fӋ+}^$N~ 瞞s'FgΟ\Co^ \xz4-8 ?7MVh͵pfDZIE O>J?s'<>S[iQ(}zڶehipX&$`G\%X6'O]̹^RVwGksCZSp ?UDq;V#{v<ל6~)|&sʾZu?#t[C%^zt45asI$5)Q8ȩjzo}O%2Iml_u7t_X^[](̱7B[$`pk4=G2SMBE/nǏz3պ8/|, ]e )'lwx{qߵ'JҜ2(IT4N\#Sۃ#>)[ZKA֣%++7uxƱCžm=M[K }6+&^WgeAxЌGtql0&jzD WWDPMt\ަMXMV[y?u4L>WOOz.kcIg L{ƾnD|rE{W/^m:-#?uǡ+jRgExF]ƒNgW<yMj[)δy(rz0ior{Ow]ogs g*A ⾦?jMA-|/[KAۿ)a|w%,Bh&ܟfx` _^_4,`֭H/wՀ` AڼR5/ekWjΚD+*_qּOsmsm A7r=W~cX촛AvR7$Ϯ^WitN}˂tzO"'<4_<2XGp|6@8$?J_ґj m]E4@շ41<d[㸇X-,NͭϨZ "\%'R/W{e w*9kḆٖlI_OLSi隆9F{HI$2W˾!fM%k9#ޕ)KfsKtg]F}p{rHLa=$bp=F9%C),|#3^cHCwZÖs1l>Ҵi;vߊO_+]Ue*\J!Kfh tOZ KzgU*5E0+v(4Z3EgNю3`~PE+أO.$^QNGWvxg[ktcl8_Ii&ymi#?O.߇m"(FcpUQRG>l9s.P,nq{zU5+0ĿyB*#zZdiqv(O1.Z-?R\}d#{Q: $wjo8@!RƎB˔8<GZچ]IFe~'+ӱ#ヌ3{w׵e|ޘʿlxH++m?r#`3D ѹU3{b$FaL Rє73ƛ5ZƚQֺ R" %%nq.#u9#+ Oo2\Ue$`?x{RTA :ȝaֶv-bv;CvoJ+Uvńvo z^$dTGi|lMҼdVt8;O_z/K2fIpG^::OcZ>r1}d+tƟv"F\sy>^vVsORhi̗smFFKFJRVo/P1en uHmu7| H#|Ai:Ar9_SƱ#Eeeg::}Aqlt>g5Cxe4hLnd4gǨV,uf|k==SJ%߻|m؜ooCk'X|moz4La,+s p@a {浥h< 5;>"TA|#i|Uh< gk5*N[Վ_ZW1Њ/GŤ$7[LǙckBfQi R\t>׆u8cFN2yEfw{ iǿ?ƾW?S_ pI9xv+|~%>}>#t~{ h3DlW$޽=ֺ#5K.>Wy>E3ڷx{*ƕm]@x?i&Td?oO߅c8> ~[[R&+f[qQOLWG2Վ9K PP(-EnJ6>NYfÝ&d!xV1Q+GIv3d:s+~|e<,il Uz8|,iq4:'U<۽!=YOLBn[JkC%%]8֠qv#ij֗&>Zc[1I`u5THA^Jf,ߒbSU}oOn$8sY'_36lwV5s\1 w4 -/[ה [SRǪ>ܕ8#8jJH_ST+[d=U@a$09>0^k6\w qٿƹ jp4&ӺI3/L־-WMx."1J;)Eo[]V5{I}E~R 5&cYA}Ezjl}:A qXzUi*=?[|z׼4,H`ׅ~ߵ%`H$K=h($_EA2refw)+|=֓N5g!:r:٭ͅw7tlxSM-p{2W>-E3\IO_je=IKOCPEy/:GtkV֡ACGOZQE2[J@OW+uunA IKst[OKi.#[ݨ>jҼhZ_w/ֻGΏ6Gyi'OfS+O_AzgӼkffSəCQ0A*\`rk?$0Eoږf_D:ŏ,cR U汔\w4M=)d2NɈS)zI295lử!C #;1NV="}\ܹǵl2#Ȥ3Pʤyoԁ޼g:.bQ[״Er* VC@ƿ?fsλt|Z6`eqo|dsQxKǶ~#H"# ǻoT'؍gEӵ2K֭`Ӯܠtl Aڿ+]x0q.eԗu-;ѝ3q=gwua2Y:K?)(5o =?=}}=lkZ-펣kȹYz ~&xwdzڨ3,c!:mQkğnjHb|9[|2{:%=>]ҿ =oH{=JA+>şZ_JER, [;ȀDrO\qmF&Fmc^⟇%rTkUΝ_57BXl1X᭯bm SóȮzNAk3IƇ+nOHw +-9I[k7YsZlE~$wjG(C4c";;wzbX4ctgjI"6*>Pe]+`ՕM?6;zWŭãݎ,DC("CV;EV]GڔS y`?k?|]lX\.ۋG3zCE1 !K?cl:XmuLgשpkösc$ J)ExׇYM&]sJ\ڷ>դ|5j [\۫;#xgKKrBImUO!1ޟOJϞP=(;iv w=MYF9{1s7 &M{xO-S9}gO4)+&~W4nU } %}r>&5M#XȻw9G_#ߥ|O&u77+"dn:2R!QEX((((sF"}0od~4Pwipo, 2 E#y#4 E<+pҌ+qoZ8m2pJOLt%Z%Dm3l񼏻a[3C#H '#1^ /0*&F;Oڥ REZE<4~a<+ińsiso,6BWpa\6׿Ҿ/BI%%FO҇m3m)k֡3,|}f..luN;=f2u$?JO2n$2,NRX[A$Ed_|'y7+SA/}>֡$z7<1 l"E!Rf9 JM_DGVA~^?O/=4rYuO[ЃC:'*/p{jx^hw&=l~W^z?2jJ [ (H[b)\%uݕI(OWpK\Y܄'xyYfR&=_[xo3iҬWsW5wF1BpGwПqx2\ozo \G,r 6~m#<7>W[y$Z]><y +kg@OC׌ئ_XO"c rAٿoñݗf'&=n+KkpDSɌS g]{a5Ko*F:㡮s^ŭڂoU5xsTTqYY@>UC*zndTyƍѓIi_Ce|IZf8w ];]siŭZ͌0>7R,B7v唁QVB<[q^iu ^,~FZiu M%nYn,[tu+mx~yiϟ/'>5̈́מE;33=*Eu1oSHz.REe=ZCӮUX-lyc{dkO!%OB=G]piJb ",`}JS Dǜ ɻY |liqrɭwu$? GgsI ̋qS?2?b־x9`|E,\|IETB^sH&21?t=ˌv?X|)|2FTۓy?_ е k}Q.;6 :ǯxkÃGGrl#ʤ.?JO~$/_ӵ'[]f\ %f>x> ~ͷWxP:Kmc;BPFctzhioOLd?:g=kPBIv | ɶ\V!QM^[d}mx%/α%'w4[ BrcGG^>&3uvw Ock_m_Km*- ʼe]O^ڇo ~אZntOJo4[ 2PѰ p9sNcX:֫ke'v^a;{sej|1lTyczqx߈xΈn [2?xQq+G>.tV {b@7֛Z]Ϡ5O ui QԐ89^}. @Vh \UӼZ_6! =Ε4z`rKGaOc[dqtUb_gֺ?C+~|[Z^u%wkLf{-KQ]N3;E3g]su66CuRvtۖQ9xzPJWCՙh]ׄ)4\Ԏ) b:DG9 -|{V\ ޣ7!F,wϖηm)'#V;Rc;8M-+F:+"P1Ee$Y:f,,d'=^ O3n4(IaTM.Fik{gT_mxeo*@ #D.Íc=q/aQ`cY@l` ʽsxKᖷ!R>x%d+n ͺ^[?0&Uy={<GC5)_O-]e$1QYXvb}^; x6V2x1U59`MT/ٯ~?kgiRe-!Ǘ!Q:_kAqi"͔)qڳjۖ=@GkrB+k]gQgtq Apv}kL~/$uX,GUuW:^A{+Ive=w-xf2#26s׷P2NjȾ\+IAoG%n5gps$Oz\WxOZݐ`p{CE$v;7DvfӀi<'_Z5AwCnA|>FI;tG— kezXrO銗>`9aC?7,/u[GMW23]阝dsѰa3Ƽ4_x"nٍ#k?KosoMCI@m1O o;4ǤjQ])agpopjԙ6GxCu_[5Ʀ&@0K)*ss]ß+!QPd|"Wի͠}ѵ Z.vY7#qXw㶕{ogYHg:#A1 㧥hInKg $;V7o$͵~6k믍̈́xBInLlWˇQm{׏Q V;[ $x5h9 xZWip=׭\x]6E#: 2>xd`C)LR+Ec潟/m'Vr+{򥔩sz+Ⱦ&~W_ 2ɣ#=wP BR<*dkyO3ae#p=ǭj\dC11t7 ?+rhA8CX5 99V_}p;38 Ķi[m{iՍipа`/ضeW km:HXӑ;Ptֲm)/8'±KỈINXn?AU]CM%\BhxMYb :ְCb< +%E#q_ƻ8]8\@2GfQ1 r$C=m1cҺ V'hLKP:Thd?`wJ-ҙo+G RIhAunz}F7}.'#j$X.6T jmugqM;;&~Ȥah{U[ip88I_X9~eu\}Ҹ.}6*H(II2:xHְ'M/WTRb$=Gz,> $Xwb=TPO暕tH89# }UUmlHFtz=ο>v>[= a’x{Rɷ9j/J zUǂ.vҨFXr95v =IBr}i(Up9q@k>T]{ҳ)gS<טC)ºf1Xm$ZjZCӿi_Khě5 ,ʖZAu\G9}@Z\_g>ed82C~?Ia M58S|{W{ 1g7 N #̝7:/kMu>&i<KAYLǃU[c ñ:}! n{r=ǽb/٤xBO 7G4r_ӬiͣKpҽϧ1x7tk=w7VkC x\O&uν:k"<{kբCki JGyގXc>e?Zքw"x1ޮ|O"l>\A"՗e~J࠽\s* _OL־:σ5IJGs۟qqøzjZC,,Tkە2zB\i]ZrOb()g{v}$Et7q\NvcDmv J;~HSH<VrKg?{g/Z$V6`RBsҼ {7gWEșWг~~W_OzSJ@IPrWڇK|H6~imb6~uNJ]Nԓ?LGՋxm+]AU)/fڽ!v)"23R7iin//%(xڳfV>&K+oGiӕyb\y0돪X֏k{k29W|@Yx zxIj&iMؑwt]?گ,P(vX?Qk?'4^"5+KS(8kĵֵHL\FyڥOJN;h&fLjZB|<ǖ[XȠdk |E. 0@F|/z᫝92/"tk( 0e'Vڷ1*Aѧi6%Q1:WcTK!K/6Qǿ?z,SWuH/t$)?C'oA{e!'t[йw=W/|隖V&`,dnXw?l֥ui1F~xLZe1& s|F5ܺs*xno$cJmx9I?'=f=~\?N=ZͥtucpzÎ5 (JZnCFWK"kzvG 5efW_ȯ,d$йVSE{= Z#>'mmlV#8=|kXS=5Bm~H,gK{Ujց W4uF?x|ԴhP3zw ,$?'}C!o=&>3 LvJ5 n:Onr׺nCbLdWY37jxM"+7C0Q K@x$2۷ Aֶ&ўpD`%>hZs ޗw(17W$mW'Q \qt5h,!}y֯GNH{E4a*{$^ǏB |/Ὲ~x4YAu&7Qk51xcjpk<9T">>%\ ԁqB6۷ ۟( 4+ k~3|>BrSo\ 5{da~ P{Tb26#u5,My7cx0x*N``===34<^a~I=;5PO xm 5Lݽ=GG&\Jq#=2P[+4xKul2CE}>~M^,9C~ٽM%>hz5zsF6,čiĤ黣SM IY#qTRM\X]΅%e b+-Y^v\IX{,6 ݕM2דR3SZ.|\0}ovKaZ?1=k+ǻ0$kq7[Jr~U 0pAe[?6+KdrޣIKIMjŸ#J 93дАv yWşoϤ붳X@^)k)~ iN5 nJ6?o(4 W40~ !2[Kͥ9}L}t>?~%j w\\:}MGk>kyV\O:wĈN5hSy$oCJPq;8u˔t>ڐ#XZ k Oԧ7Y۟-L alŸʭFCqzVn}ȫLg1КCye tn0}똃Wm&M+W}LÝ5C0uex]>C"C#tu>ǿZ>b%xᆋ^'<c0}s[ө̥e_OjiUVΛ_|`|o5ͶmFx1N3d{go[ƎLl2RCzW:/4-v /7\ñ7|[ko7w`Is{V?E;҅9#'+T{*w>ӴjK;#ABO6_M!Qpc9_^q^;k1mQ:煞?f!H\mi[I$Dg)d|8851ܣ=Wx:ȭu[rHqY2/%\``?~|B|CJaKd5>6[BEx$}:V{@x$ΓqiKHdMf G$Ҿulye= l߳u}?cM.rfv8h08q؊>7;3ǚ$׶ ܣ2`SOJW"?60  L9[̄OC_~xXk2x~T> r,fgU~d [%0tmU"Õ5h#EjcVk/Nok^xSÖWvؚ@\?7ҾLA9n4Y5$f&RH79n6y_obɽ_Di0[$Z*-q\h<։LpŲqoOif >9g?{9$uwb6yQđ0":\jRVGQ_JwF6זxk=մvȸDRwe>+3qxjե=}S:gڠ)gji l um2pkmƃtWKh7Td'jO Q𿋉]Sd;ipCw, +CCPow[vS1_LXx5 A~k_ ӵXBkkO#y 34Z>j txva_a3#ּzL~ɨ*do1fmX($((((FPC ڶ-}uڥv 8f{ǽb ++#u;Pi5p= 4SΦAHĚD6V=}7@דWanWO=GC89ɬ[hfˠ^r*#D'=kCIJ+@nCڲ5N&"#BWfG}(LaC[.h3%ޗzC|[kwk_"U?"Z>#ထGgTgY|y6IoYFA3Z9eWwxDffU8o̖wIp2Sqw+BRCvWF>sad7Ҥ5xWN c^7z !Ԕ'685&M?ZWԴ̏.@߾=zUxR[e[Up&?ݐz5#eHdpp1?oQ^%Xߣ}+{^yWצxCzap\tԵa} {UkPmKS `?Z&Ȍwǧ{ͬ70SFBy= yrŮ웒1_#GKtSM[) WƏ{YuQ2o3pߺ^Q=?F[>VU9cEz}mp>x{W{SM}̋ȟL7|`RZIːG^gzx#__x6Xy_㌬Wsvp>꽽}~De/isGHTՙN.a- ͽ11V1;vIS},ֱWW.qFmE^{IWa#=kUC!OIe(IhNCa[C x+M\D8 ySėe{{nxÓk۠2:]OOch6Iݏ=.Ȯ%x.ppGz -tE*-͎^#ܡve>hVjǎh 5o[OM y`.qwGNj '"u9;fox69/J+FŤP=okK*{Q4ae<(K#/ 8E$;`gXּ=sxH|myp&++]wusedB-gt>kna2yw<_ydIk, ?^[{k2W ~o-abyl#֗cAjGY$3Asg}Fm+[)đSЂ0A5:nxaȯ=ia+V+dCޭ>h[?|i }ˀ>xC=rx÷f &Io(#2s|[x&&V17B79W/f$堌aʰA<>v ?h?-hoiMN,,zÂxkoFK[_hخG /<©uSZ _hsO+@ zh?=$=qf%_G(zuu=d^` ~_ZjVpêHZtwy]C81"[^-nu+)v3SO5ޯEᶆ5L+gcE)J`+'-j VmY[p~cWxG)<;]il>{[Uq꼊o!m&{dQsP6#OYc}xmVyP-VR99Hw7X ^&~puOن˫d\Gz!'-o##/5C/dNF[~>#n|A n$G_\Qnv)xF#E2˦²wJD9=-L}A^D >kb>ͨFl)+s@u#JNg%H]՚ykK ;LfIm:G8NzWjD<#=@+w]AuZӪO; 1~4ڽ#EiTF\GPI|WLR]#w^3ۏ {ZGl@ISkorkVPI־.p9aA)O5{I6#;& zK %.q5' շ)8=Tuɫ#=>`Oj1ҒQ I%y☍ySPZex؉PKy37-n?#R^=͹?Ti[˅>E+N1gg[ܙ:?AZlb`:g֓ EZ'K ¾;!whrGqWр),cIo!^BVV%y>? nTLwUu\GLTU؂]sƯtN _[# (?# ǧ5sb?y Þ& ,?J˘vsA˨Cw̾wc. ҸVW\f4kVayGyu0gq;=6}jT]f확Qc( iMeVyp$8݌ްtJ*EkWZlHX]bjve^iMjk<$]>,%ݳکzJ]ZnoD^$Zb(jGi[M~GOqצrh:\@y!ܸۤȳ-[U/#G]D-(x>ƻ#SŞ1gk%a6o(U !϶$:]9wHǥ;VdNey`~(,QoQчcp8#֤o# #|}Sx䑜Qz kzܑ)̧d9{i5):}}tk/_c[auX㛄9-uCLˌfBtʓcƳ|Q| (gb\Tu!OJ̈ 2ԑ*55pa+s nzTZm6i\}{սEee8#uxr$"Nws][ܭckPCkwK|^ximWuaFo I|p=(d_,Vzjx3yۙ-SѷC2/h"k|W(X(#܄EҼ}̗4N3BxIEis36Y yUtV$_LU2} QrG,thh7Td-T6M GJ!+>\+ $9'{/O [I~NjAsS$ +H<e9O ~,7܂7 )YT_B6$-GW֟= ^J~g͏:zOkїE͙1'#Zv/a98IᐎAV RpzIy~0" _`Fv9emzq޾Xl|iWLpQdSʸ >LJu/?] cOwas/Gn}E|÷d6}+?%1╗j;z&U╢ua":aa+{MRM6Px5^P3%w>u{_a x6YN=9ĎkO:]i-V< _L|A<4yᾫ>dž`_C(M_LW~\ʛMtw __Bau]68 գf¶x=i 2jJ] .~awJ Fȹ#JIJ/sn_hL5.v,$ l5~їĺB(=f yTkdͻz}3{=J/Ěz 2. )?gyx|Ik8^=Kz4uCӴ,0*c_ NTm; oEuo|.WRc A1{~-n[Fh#a@i.5ie9.6Ilt]YJf{WM[Ft&>WQ }.[$DgʉI;Z/If!<. zշker WW4yS,֩x~ȮkK##>d~vbjcւ|$p>n/hl/WM_+j#3T[E I,VYmx" |I+OOsɮ{Xx$1ך[3)>Klh3Nx"pD 0]t=I>hgt.U?Vdž5v[L0|@;n\줮}9a/7#]Zߞ>_\x+㞂t~G$ez cڐ蒣k|U%7Z[/ pEq3>c!?\ۯj>_ ~+|K|%*kpŰ8z(~k.<@x'oh?] i?+$?֦imX4NT޵y 5|Ac8?#1ʿF0~8~)Os]I]ڭίGIʤ7tvFO42ܒDYOb' %ozjkc~e )dO㾝kN}H:W _2?ޮH< iutqp~F47ASyzק|;xO]!2HIA;q\2MԔ|xmK{NuAХy 򇨯mSHgT,:. #ѺHǑ_'iYif&hǹԴz2\Zj|^GCWh0\z׍;f1J9Pi#݂:Iմ$ϰ|&&xU+{ݍ*z~cs\?z~Ǜ>5I֟:^8WٺNB}^E'x>}dY*9=f:4o!_H 3Ҽ]1wW2jđ,rpGzY~ֳ$`AԐ^'|];B]" @Y>Ǹ֖RWks_4b[=jkzDaԩ?*/gVE\$J[>Znĉsgp qY64|Cvെm’sCk w@y+ݭ|c%ͬs_h>'&c '⽗/&K"Ino4T`{׾KjOQڽHխdWO8ڤ% 8e&ӯ$kJgPq< /ߕbxgM[fO5v l_ĺΓ*uݤc=}G~z5Mxkn:݌rqoP}|/>#%߇>-5&BaTWԁЎG|kfl0;בdxmOt}6_>Un$ ] -UKarrQ8d' V>|K<~MIssvxfcG5T𭍢^7;a)-<~"a,-h֒@9"J8;c]ҫyCP[EUo5Cc$0 ퟋ<3O &~բ|dtIi?xqoש7|.Vsތ,0cGȇ*"SS?|[7/m(YC pG=O7Ŀ3ºD#@| =h~<Ymn,4IJgE4p1rq^r|gms3|$qXB3W9 [M5PW,vely?#wiuxd6W/]`fX ( +K3/ \~U>8hPiw0]XCz%G*JFsξz[[jidxD.Ps|?7OôG΅O 1Q(I 9#^yrkt;v>kASb{iDדDR؆+Q_|,6#2%,+:e gOԅT#b|Ҕ"gZ0ҭw) d}{~˹' 6sְf|4oۍZO:(s"}\Fy7ʟ~ iz㠬J:Ȭx_Mvsjֱ\.׊A{5r`}81S@π>8Ծj-sٟc戞&:C+k7T,:+9,.u=AoOUZcVr\ٯsl==G>37PA0G+RB(((($9]N XxROr4dRjzIܧ5Ջ^A}05SGIagx嬛IY{ӧ}o)ʓ&玕 Y?Y #ӊL -nqOi^랽2M+v0αo[2Ƿ]5_DIbA `ڣgє桱V)s G~U.#q@V/R+޽qѩY&"nw [l4 WKbY@#g8]G{~(M~xo?t?Z{:HDhڤdd$0aY jmtsoFՏ=C+ T~ u~Gc̪?sx d'n3]hbH'B+|7Gqc$) Ykk>yz=M0J+6Rg3@dНG&nǬm d^*Լ-y-ъG"E!p}+jrZhC"Xz)>\sƶr[!I |`/̳=JH~&xHZDyGxiRnm2@d^8,u&Iȣ% +?@m<xssWF+1qptbG _*MŸaa+ǀGz9 ne)l:W+ugk~-gCCi&C曪 Sw`R^@,ޥn5CA\ld$σ8fp_K@ ޝ+Q aJø>j&źuI{fJt1ҳ2+̖͟8:Ǹxdz՚W| JPA-A:;ynzE jһ1K3*ݣ0@f<rϧHH]=+W_$BDs+Ci짡ǵ0hcx{&[0F[9?֡X- *.BڕPhxJf;v${4ASish t9pn,@U.5gvYc*@Uy2Ygÿmօγdl$xn?S\}%{/}gv=s\0nr-|!zs|:F@$msl 08Ǩzo Ekv[!k4u}TjDlZ$ǜMi,[s*FH?T&9`\h}$eIMSѽov=vƕiq_)mu"K{gڎ5}VZ@mn:Wi,yiVLpp=Y mcUR gk3Mٿ'+Z\IQQ~p9sSMBkG׭T-ch݇^f#ɪ_.S':,4}c5;_-S;Gecַ;[~u_dF*}A~ ~x`ObFul(5Aiv#bD qh9qȯQ mmxM{I,I {3qN3|_cHXKySytK kTцl$9L{OqnZi/agmk~^Ӕ*Dc~PzּM:v@b$}9湍u9Yૄ5BK)DLg(z|DZ$+<)Zf$+*U>}]ī?VQ~qNFdP7|\}SJh,F ?2aJ̖#ȷd[>6Fe1_ǵzhM.d~kgݏ_Qu/ƕuHXOx*y^6ьp 1JA$;ovl7#whMa$dRϚb𞯧-ͥyNxVFr+?GUY8d1ߎ+_"<9k$]:J?0?)|}/]]`}Y?.2s1V{$oŻ}hd\\ac~|gqƍ¤>I !9+Z] ePvi'O5{ӴNY,YU34N7?hKmIit=:g_Z:׈k$ZK4eXgy /}qg7]7L3&q]Hn5 .\1Ң.Akx%p#]5Aa-pȁ<=GkJ gYxbQӛ{ۼ P~WZVB>BK!2܌w|Ec]ڬ浻` EC#?5lIQ̖Ұ;al'['9݋7d#*}q\׊MG[gȸY'ŶAXcoKX>u%NH sM7"ӤW|2> J#qs@a֭KY+m*~-0"L>b~#ZIrSwn;y#<u-a},/ x#z'l唼~_to NNBA&# ^R~` +B-"樒*E!OJӵO/F~kIï'=+Dy:zP!ӯL0ð4ֳ7H*qW;m0C"ĥP4cݹKnG*OQRhWeCV5<{Hf[VI2NOjt(r gr-/br~W=kjM^`qʱFGe{T[jOiI8Mg)K)pM; ^([>XpZ%/+QuYpm+իkV%@<Vnl~ONƹy/kIo*lJ5 L yƯgXH?u.:=)&m .VF@^ c˨ikzpBm=EME,emvP}~nlgMJOv5Sx;Ht^OK?sj$&Qrjo,vOf1Ik/*;W$-i>[<вwUu=HL=}Ǝg;0B?Qcz} x8 790FD$)]&|ҀUzk>]0]Z3R{UJ4v:6VV6Dc po]9`; b «OlQeE E{*?z`h>"ouލ؃?θWO/dH@S~,Vvtƹ7!qvq/F6c<+?u=s_x+̒7?}{o]7բ?_g|%友<C&1=U:u( YmБ15t|YbgI-ws |Oc૫)}Vl}ۊЌsԄ uh0hbjڴw{qo&0HjA~^I=BJX;ˁAnnV#Y+[×/gw3VBT,:*Cǯx狼 wKK܌'Vm&n/QF N8*~)X̺s<:{{|Pɣxvs<~} [pH>޸:7|)̿{edSwSE|o x&z$;o}L3ck沞9<Q"C.?_]GynmK׆HprP /|F! ᾕZ{AF7ZƉHoxJT~J>yq_0|k56ᖓ_A־/oQ,ռ6̵şC(;PR݉g;zՔ"D WgW}c" nF{hSW>>˧E%BB=kӧV5rA`B8tZ7^ܪK/P=YZ~7 +T}NǬZcm0UѰT)uW"yft0?|~ZOԤtNQi.9 &qƹgJ񝏥~'~ǞI?mܹكI[G1+? i^%fӯ%_ =YMh$oA7o|{GeZ܃ tRpU~F13z[K], t^\(rFy_]\?Z>x)abQчP ngLqўr0?Q֗J-zGcA<75u1yi634e$EU %OJZ?jc 0>tYs7ݑyV܆`ynFoEpEF\Z$% U&K'ӖE"Q+%t|Vtn-߽&љ01OnDI$M) zuW%,ʇQSVcqwG힅 Ŗ'PRE9 =A93sxBh4O3O1C^zZU]{c:Ibl+̝7)#=CÿTqo@?@w&}PwEs^ wamuDil[E 'O^o B!Xn6?xJLl⾲v3.A_i_ͮxOtE˼ 7Oj:5GZIOG1qqb>i#Cqj)TfL`*sĩa|^[?.P!Ñ4)j|1&Nk[Ÿv/Xu_/Od<$OC_1j'74_A>t>]0 E5tRmhϭLC޴t/"jd?uƼ>̖5݇fQׯ*i)It$Y;V5GZz5$R둰/|2V~]l3C} eG'o[:=ѹ5=G~㤀`kCt?Iu26 ],S~ #𷋥cy۞_jh?ٻO4Cd-ލ6M&D}R}&d?% б8+k¾,̆IVU8ށ\e(>h$[Lo' cȥ]pT̞ܒckO lԭߒ$*} |-3g [sLբ"uX8ppEzp9% C|{s=~A)}22KReX̿=/Ykc#(t:l[R1t5e)ixӯBZ, Yۥr֤(Ӛ٘_"m}/~-9ע&`, 7& ց4marT<{Aӿ /QWllڭ9@7p~׆x.-:cl\nmp9XS4S>Bߋt9aVݘGk~(|2_iyk! c md1JotxVIa5Yu_ƭtG̠0;*y<ׇ~ѾO櫦Aw>]7P\e}IJ9zp1[{W&ɳ #[}RKW 󑴂cM}|LĚ)IdІF%p>|{q]/5M,h0==+P扊+?d^+hK5?h<3jEuHUm@ e9$ҨxGͭ~#eC,Dk׋6;AhyRp<'ǠdZt)YyM%tϻt7C>myp\[#bYr?|:4)gKJS//vݓUn`[w[kƅr+ndY h?f}#*ϩ"-D2 C\ž)fm+Z.OFS+qCr~_4fmDu@Ǻ7<ⴌ%4W\|'2NP] {NQL(((]'|HrE6g;ab=_Ts!xaE&BB1ܣOjkvbZ1C]$WTSGFK.Wgz *hЎ+]1pvl#`n9OV"q |,t~qiO& 6` BH#x஽y[|MUlŪ`_޺xE&P?-g{ЏEuؾ"w"Z}$9ds8ܛ)$ywg]6-KIf^% 5gtx.-eY/ܱBG 2}?5ea,s[[ NkwP.D1 !#¹?ox̡n~6=\#GERcOƍ{{[{AHҮ$Nqߩ+\B'Hܒ=-9%|9/nx&Y{8?`%އkd[MV?h1M.Wk=R.ߖF6ihm@SiXU{-n:W.PF])'N:>jVwf\ɶ@= b}|7jVz^kT !NpsSZ"O";x2 m-lqWJz35 v14zƋȇ灔) .㾅@s}@Ɩy_[^Lgdcr!7tS8s^8Z8N[ybR#z?QBpq?3K\hiз\vm$3@e#M[-i襀MBBz}{?4tm1ܘpµO[-XS)"uSK!ieYT7ZnmO<%ŒT:+yHjZW>ΉpB.`@( ϭajzgROjm3[ *v\q׏Z? m:+yN;#ЏJ]_m['ڜ\ny]슾@t}~8Խœ[(ϖ ;V_8Kk;H[K~lvu惆C˖sI^3p"OCYb[ ѷ~5qYB濢b϶pnQzCL9brZVx%<>:+{n#?pinFGWPaNr}qYf[:̶͕,wv?ׂ9#ZG1ǡ5/VF>JgEBCpjK!q"'IP(jOg8 ;WCopg}, ͜cGZ I|cz4zp`y kVye /Ete8~je2TԻ(ntm:Wdh# N}`l#{WQɽr>C^p X8#nG'p!rȸ\i!vg+nN'?]]^.!Q^IkK%/Q=k9Kҗ\ )[HN}Mlɟ2.7˃$J>@>0ʱ{vq,nTk¿/YiNVD"w^O'$=3kz%Z/ٿg7r}RBlDz|!a&mFڿSҋ%׈V(2:_dͶ m9xkR/a@C/g>wm/ kGoW׺{&E;1[؊W.^>؋!w a#O+˜c}%<<4DaQ#;5/#E.dzxBюlj ?֭Vn,Q]¶+g#y%g|1 iu=TAՓz]l Jњ;gʜAP=nrXҾ3q!VG?ZJgKMbק.D\_P!t닋T5ţ8m@)/;O~}wL}BMTd"ǜ$s# ԌύZm׀;]F4-]Zu;`FW##ҾY7gvgi^Q2+ʫn_1jEԈlLN2=H]֚soXVWdlwOgڽYĬ \7^Cf}>Y _X-$0f\8^85oDJ7|U>s[u?JO[Ö߲g" Ly.{ӂ;`Gxyǿ5'FefJA9d늞VcTRͼdS{-"1JT"l/G+$Fjk 93ffˑBsz7",nՙwE;2>Y7>#qYDuܬ25M3GpM^S aFv8&T1u(r՛Ŵau!q,ݏ]r>똦V }G,`t3Ҷp(~VI.;xkOh #t+R'@Wӭ3V < u  IE6f l1iFu⺘_k$k}hmr?w!U*FNns^iɩ29ܞk%H 4g T5^ncD)&v\ҮCr99Pyz=Ai-&U10WޚoN3 gs&t׌pgH;r?CP]ԬVE?Q_M) OL8OD̓$'qSƗv:6yW 2pGhāfNA#MKRܑK zW?_tcf`򟡪;12s=U?~jQHve!cdjw vڃ; N#Z@F1۱H$s+$v4a[OuM*GG'ڲn3B@U_u+LjjxCJ8(~gU(nΞY~m2pB;՗T9 :6}+lq'z|}kbU1&x#%aN 9࡬i im(H;jf68<zotq=?“yZNrٸ"IGD:yfL}kk2(3 uϱꮎl}Z-OYf~LtH{E*5Vi]PG$ޥ&r[ HbB"7Ȕz8ZwNF;W"?5il%m'Ӟ?*۟:-8N{ZC9-kMN=Uk莣kŃ4|:޻K4w`WRM6wp@/B/W|`ӏZӺSpd\t\ү@qrIL0ǵ1O+Pf!T䞇4֕.YPJahhl<zZr_ҹ ):6;l0A5Rk ײFF${Δ^ Z<q[fkM͉eGW5m.M.aЊjnq'͑£Jڜ~J7+!+dCVg9mr+#t:q \ Ab)w> p"'jf|n1=TjIV>hV8]v?zI4}{Q[UyƦ eҸǒ7.jh!v$X$eޕ_U#SŻs+4 @k/H $@+q"?C4M~ƺy/d~+W֍o6eMN(BxI}k$iw' 0G+w=AZq? tIBJ5B\ /Ay{׺iWk=u-!'t>޲˚0Xi+Px!3D8+0PkHMVR |&bHWɸ$%a s K KuTwGB? uKiGI&ˢ_N.8ohHJ`׊ 70F } [÷d:H'XrécG 3CH=2=ǽU9㦇ksXȇ(O|CjuOSw62?tjZAce%mפ~="Xn4VѶӑU-^f=SG/AI;_P7kE4XLG;z? v )8_c]τ;-z Ԫ31^jMo 5cֺ#hV{jp[, {~]JXٯbh;ftR¼XLdi< JƛZO]myq:{_WĈ|J<^6[u zWOaKT ?,eΓ+/Mi"a*8z M14b6]1I5>R/ Fu=F+kWk&O|?ygŭ^#ɥn{ ^zi9n㻃S+x ˠ'Sb<_S֯9)n ׫-zk6L_M2m7VaUq_)RuMxhͪ |gQ9kB TMvg;NA^?R;mFO2.aXGk.cl׹ռɦkV4rg{+kFz;n}i $NF!U  `9^Clz"~S= }Xe挟~iDrς4͋};-4_X5A^(,-:Дp5xFUF2{ЛNƿg:X ,v/~׵yro#)~˺g}gW/6)ڬ{D'tZH`Aӡh[$'[4PS,3!GSA[ۨcF,L61yսjѸsȯ U{v?7OJв^9G!Y8 )X@e3D==^/_ i Cnl';jEprvq]ksn7!@02=逋,Wqqҩ]ZIhO5fH0K)CpWa})Rf,T3ۍ$0PkI?2 )+1&֨[[ß;ԝl$-^ֻA5▿^{YH $^ø/>;I4ƿlyuh=ּ\5[ps֔FP?J6>`ex̗:d|,ޭz -fm$OmxGPAcҿSþ=ZeմqE\#Fo=O->hR޶-1!ctm[:͵`GVo5E\-Lԯ@ԯ-"߃se&^p>һ -ޗr&sbv7tZmb`1ižZYw-iyx``bH$#޶#f3ضX'?OJsLɖxK;x8e?Wx#֎\nx[k'=PRtgkuSS+nXYC)ZbJH6J:PQ,qH0"=3#RKo j=J[1| ~ ji@*$_ښvx[?N3 &ɄlrLo!~u󞫢WKewbKyЫ/kfh.#9 (ןx?t55Ex[?nuҮ㤵G<'m¥Z[RP7׸|ƙ?Z޽`խRm.+aG|C5x!俳chG$_>=ӵ%gwY49Q*uƺWe*n>bmԼ;ykN9 c g9tK᧊ZulXqnO[}t#͈y_O5HuH0#pʕ;?Ltۻ6N.|<_:o[0TR;}+o޵xdM{@4[R[&5 )=GO4 ɪivd Y<q!9Cݙ>qu2XBlH6ݎ >ȥ[8!\f|Jڴ$b\۫3FA0 Xc=+S>Х=(^9Zr;4.P>h*-5 (,&P$=x2D>dcsZ-jz*9Ba9"kmB%E$*QQ.SI֢KA&7`s"w3]ƫ\IwkDlaz/dD6$GZS\L[K2_];KOA-/D2jS4s(>"'49̶:±c]c!r'σ;EoٷAl,υVy =7Wm!L[sħ2O+kʭzN{Қ"n Aonmݰ޽ou<3$$WReJ?XZ|]KB Fd )<@篿|LojI{4r~ KjMTHW Q+\=k8Qqf$vOSO>߸$ך~^1kfA,1Ϙ'FYQ=!UX6ak;'usdwn;>MnTf]ҷgXmaC+j:ue5ռwV)I`C#=koƄ.5%ޜ2i|>Goۗ*z5Td㰚aҊ7m׼/vz/=yGe~|q{eq]ku 0I!J0= tJFmX)URF=MP'KkvZJq#~􀼂;dcoƶj!?yZ'w`ܯPϛh@=fNmo4 @?M=QE0'oଇc7fz~ZaaByٟW@ 5_Ŝr,OYJ=P_G/ }AĨ 9|[A!Fy{}tmX'o*YEflK3ʒ3 G"!~ʏ\zW]J$(o^s-7VK9R0 I +\goެ|qxr{?Ls(mFŤxiSQو?c>O[9yӮm,saTڧB,#Pm'!7=j 0Hk{flᑻC5IK9ؐu=W]iP_*kMϝ.9tO0$nst={vv7a+whtߥxw ŲY]!sG wy?zPykf1_ckfJZ_/mkv)m岾>cpqZiKR&,>e?ƙCjniפțOEq^$/bw}Ǧ+ntk.KF&Xv7N? d1RmX/@BZy%3#ɷ=y<M?:ts%QzkB ˏ1N}zwߋw5c4iMsuRܨNߚ.gK]T~Y{Y"a>F99>|{e6;yLi֟4o,wcTd.zzW_[utqlMӐ9>g+Ǻ?}?Ro5ӥ{wZ]N,h2qs_FjS [р~c\p|92$˵aFesT-G|!v˖%2}P+%ضr:h=ǵz4x~{k>ߤǃ4?3H=X'fi?*Kٴ"snXz=i[ bOPEk z(v8Y.h@ e%^"m5$4`O1>CSs2ǻ$5̖4:_٠H>x+FNk.FT{])c}8~KXteiXDBP[XJ&<ڟQxE44؃}kҴ?Vlm|Al-k(wĿً6X}opC^C_?gwh L7;>ep8ϿMVq5?O4NZP'l'!|!lœc׵zRtGRO:w g'־\M;^uY4<2[K*䍼Gpv9T}g|L,,Я;A} ]ιg\^k˾h?nuc[w.@LdnKWM=Ĉ#=iu mv [y7HwOK#w5ӴcufUo'\oa2*EG!{s:^[ٴ[eB`` sx#Ws5+:8۴pEy֯yxIQ$q(ꮃZ{N-$Mi#(aRoQ7c?>&]._t_Wv:pڮ;dȗ͹+E[C+r+#wV ;w5MO/8-vVPk&c),ޢSKwg*|mOok^o-)$o8_@Kbw,v#b?4ӭC)#8<B+o\Y[W}sNC%iA@s9*$Ԯ{}࿊I/D(|eEޱJ~Hj8-:&hWlb8׌ÿb֭ ],]L #(lu׫ĺiTzkKt'usuc_6&*隂hKwƱk`犚6:}ʶH~֢mѲ˒GǸ[[q}edF0r0;Wr1+uht}>V6L Z%[c0)i-78Kr}gFA!j}pH$rf V}(+8?c+at;Z2JrT`Mb[=Ȯ[^җt,OºN.ɍoijjSLe$-eOCۚo -i$s2)' `uRG0IHC$u;YqcZ91=V]C7"R͍qңDɜaӾk#l,y8 uuVE܌`{ffC_QVfhn0.pGOҹ"M4M޺l( oơnKS2cC\^2v4}0~ݕU`Շ}InfQx~yX1Vׇ]e'&91omϏ=]r>PxuҞt:,;Bb:si2 O*[rO̱ '#Zâiè0*w[0\tE hNUrEy懮KJ(ORn٣ "t#Q^j-4triF"Qgx^T u*m?:f2yRo;H:v";I^¬2QQ#⺶ n>QIJ$A+WEZ\Dxq{Nc vC F%º.-I9YHĺ}'qrxzܖ : ?#W37Kg>xlRRT&">n@jZ %T'Ju9~57͎#|3ֶ~L/2-;mg-~+~%_ @ռ%$v_mWj~$T'ck)K.o싹Ӿd}MqWw~U)[O.>kHZʸ@ Y|7S9\W?֚lrq~샨wWßW/46ڜG ej+{蒿o1L3rFc<럲þ%G|$=3~xEq/J <9Z떧IY$.?E#[y8w2z5#ЊC&7 m0pޤt'Qt'G/=b KTiZӯs nz05Ɠz-ohmWk源\LK4rRNM~xxᮽg$Prw;\WJX:牊8uvK &qWѢs/5u83MÁ^ _Ug&Gڼbz-ӏe"R4}Z Z\tu0}־1EkyBmP't,D-eQ6OZh"iK}/I#׏6lml[D#=_Uh޺^]A5ő)b9@2u\%Փa7i'>T;JַX =JW!%9 z8qᛲc *ut+6gԾbTw8i?u5WΝ3sfKy~hmQD[M,Q֓dM |t?zѾ%{ts H8/bgzƳx[_;angNy _%N9/2*3O𮳪xB0 } Kr1++\ǖiE|;a X}kp2A\Ԕ4akB}[?su,-:)RCz |DI_O4ڶj/H}*gyqKť]Ҿ㹴 !5  ־n-k>"n^M!޾Y?txn\\uGkOVGov@Džc zT7aW:֗ HRЃ^i+mMe+Q(4Rϣ+ s\(nE5GZzFoZŬ4M*zVi2{3ᦓQgcmhKoQxW~ xd[]GDsڂb@ ;2 H{\.'#w =F tS(itԏUIn=A5޾1$ͩx>6$,cw5Z]D9k) ץ j8fUhduIקӔ21kKPu=A Y>21M;# ^^HDSAAvtoFC!Nƺe w?J3xǟ պ\Țg vxe"ӼA`D.ObAp޾+4}j{ ol.dImWt?:cFo{e8 O=wFh~e*znS?../nIQjƝ¾dA7)#N Qknn* w ([6Q^U4t#{ ?QلStkW>&}ׅdۜg&2u㡭R^/9GoZt{S@Ht&EK{E4Cgؤ+ GSіhlK}EEqInIA״utb0zw7ص+rC$L#IA?v7:uhvu׮bORFik-72Xɧ!&?ֺ-]2YBhXB;Y*cPK'1=KGp[k̖$9{'k:J,:rcj xd'>`Q_P߶>my|2X(Wo Wzm$~V'|m@Р+4g=ՇPGν8CCZjڌj7o/O-wᆶflbl*1NCwZ/=m'\KY9V7fF k >J G&fEp~1y7YMxQԴ_Yߡ+{g$AU5ts MMVD|2ьMà?^[f\I:RT1°Z5RL Tlʱ;]ͻT{}:WxWǚ_muѷЊ+ط+DSU'Vw_,G=f>q(֭+Gƾ}w1ZDy[^խ%V2PՋLؚ.JT0ܼr.0 OF:r4Ew V>ZmHuuqkμC[cImX弯^dnzCW0J ?j^ƚ >s-փn4U2Os{O {XBS=b$mk Hՙl;p0 ֶISw?5M+Eq DY%B=޴V yo}xlfI}W^߭|㯅:!iwL#ˤ޾k5cSpq9/Ttb;9qqGLWc=k+O_Pޡ])ȫup}zۭ}%:l4mN>Յx*y}5o-AegS@?GC^kM/;1'>  $NrO=ljZIܿҸ: %nRr{k-cG[427 ~" Zk]ɗz#};9 zM8OHեc)yAieӭI˥KvB͇*p=9t d-/ἷ-$\"յɗq.Y1愢1ԛFƛioC u?i/4mtX42c.W NKI/0=%m.Y n/tnľ[,Z׾[ޮx`yk4^1K(lu9#!܃^xr.#}$( V {>2UO?gώy4]VDod[Gٝp98]?dմ{XN2߃}+;=z_:B9+u>+Z p9-{`'q]?;30u>0:vau] %z~rM]kp}Ms:4j[dV\n\OL|<7OS;'9tp=zCYq##d#ЯJ6c,x3A1%8IּizA:6|IRaG{uDU'/o_C[p}R='"o_֠zZ΁*UXW / X;'G|9 i:*mcaIAGLdzvsՎH#9LB[ İ?W?uc4QmfkS+X$\Ղqo6"ӡnY`丷' n5#=~Zo|PZnpQTuզ5XS򿩏QOĢ>s޿uڳCk<>|~Yn?ڧp5u5.ckQ?#N=LWC(Rne^z?."6vqٿkN$4HU?G_-P>t-%uc@%b7~>՛r;XiH$HZOtMEV [ғĞJ o22DVNSFox}MdVat~3T󂬀3+g<@r~^J;9l%ە۸iwx|O}]1B~'k<v҉"~޿/t=a_O ~|_:]崫̬xt%X_^𕏶άHʸW#U)}ONca{i0?2nH#C[$8taExY? {Xjp2Xӗ,5й [A'+=V-2}Pb+OWj&SЁ5=gUFvH=q_>x̸/~Lt)dW.oi^ZIuuu!D#"M>@3N wN\ۇnz^O]xvm7l灏sdjws(ӔFLz/Hxl]J/ ~z2>H4?,1\[N6[J=}ߎ_5֑y^2|֧?,ur!u#W[6>2kyEx/}G wAK\Go5Aݧ fK_ɨiǗʓ=^/kw,ݬi|u8uw"PO( 5kŷ:l59={0#"ëOt}gZrYbe8{Sj{ƉPwTBlO'6:j躋Xݴ♣^a{{|SFpk>>DW";QqÏfNqvbS􏂾1\ ze%#+澕yⅵ6d1ɟ3#<_':nDo(q%~x-wE<@cB Aʢiv8}ͧ@ %^ y~ {+K q8L=_5^׵+eP_>OfrPd9_#ֺMF[ ˟kV"ܶLiG}SXO8UFV铊x&7R_H i.; {Am94+7\=\, N7AlqS|MO ;Z4Yӡye˴%? ߈uG[xe35XR1gx,j UFqF;`~iZ6s33d!'_?ɣ/4˻;>1q_b{Ǝ-K93aܾ$@O[=:x_C+9EKr~n 'Oqgq=ΣcZCGWn,;)#cQtnn-e;O ZCw~^|aCB~kkcrǨ_?~t>x-o(fVc;=H?Q[*$G'T|]+f&(8 %} 671@7LḆV `W0#xvyՁ9u#WOi_|#$6PFYB/8DJ-~4K,rr}kCKsm!G!韎S]u=7DcF}jo*>W#w&-/u4 AЀ2GjO~zfb#=2c_v/}+Sc¥x#?/Zœbi` oCxPi?ؑZmn#4+ _cTU}RCxJK|Z7f8?kG[6Q3+*v֢weܩoWo#jp@zJԋ -ksyZ&gYs#XG+GPXQ]W;kO G"XV[ {JP[}+^k%r-wI$tmaPT c] I9u&ڝH\J#8#V#a0zRZ1V/#Km vHp*6&rێEt~ʡ< $8}%:B\>x>h#ռɩiWQ )" \ sM&x/GmFS pX6v>%hP7R Ȗ?.SШLxmSW}qi 8{gҺOTq4RƱOux`n#Mō;Cc (1HBy VE/~e)d\z1#CZު݈dXsD ֤ޙQ6닫aLdL弞S?09WSmKFag?,7 uQ̉osѵmr·u;ewXk6;FN+nV+_KQҹonO._OcU$m\X [FsksM?^*I=ꮋ/}+,Gtdg@@ "Tgʒ`z}9v璬}EfcdBˁ޳tkƆ_G g54@<.9Hƚ%bxw^OX%3ZK9[i7ֹgwapBF0WĒ3W|">U{isޭxk6DF2Vlr}:Ri}n@u67ufW s}çkI@IGO=_<Qm*vUC|G_$C=ǥ&B-//)yBYcMqze5?oDR7F(>j2NlI5p:2fhll\|˞J@M Xw [Ⱦj}Ee=*|u*Hh`rvx^;Gp{βp:=c]ZH\‚GQfk .wg5I HY/!$NIY7:3\2P`Hs؂-$-;Bc>^PimRK2<³.s@~&Mٝ5ŝ#TQZhT5k>-԰ɨG$r9{ӕL?y1޸7<+sg.ɟFj/.noIo#ϚXp0~d!̐D@Լs(eFح7(xhwR8|:7OÐW H8=9Jbybs= gt\sғRavR6?=jρo=O<;[:6ń28 BIXnpk2E;N{ 08 oG-/,S7x?j6O _W+% T~2]}ߴzi=-Y[YQş¨5h%dr0@泜UKJ=JpYFOĽOl'(ʇu*A, F:*emEM2OxaEnzKb~Rs-^wc#fWkW+F})C$~"=m_4Ȝ]D{G }Z;mEEb6Whǒ@~`֕EԐAYwoH ˓;[wqoNv%ķ-w^dnRAî~z0;~w,ݨ5kX4C8e5-5EN<}tfdc@@x5pwCLjC"?zg|;jvNu 99,nygzzU>"<|O5&[&"j6W~`aY^7G}#ǚSG>Όxʸݑ^x"К<ƇPfw=85||#yn<ɜq۶My{?fQӬݭW$8vk"myv-ڳC~eEјs*3C#4OW- 2d ݲk+$c{> |G4^EO2ܹ{S;v85^1Eé.|UF:lcv|e?Ѱxܶ ӚO ՕoeheD{Tb .95).5 C{䙕vIأO֢>,PSX9aeͳ\} y"U+k~:]ROkKx6BPlkC?o jx{⦒Ԙpj7Y]P'=`5&#i< 2+RhdYbq]C {Lu߶cE} zg"Q sjI.Y԰[Z "ʾ>8Xx ^c M qn+"+;:-uXȒ1SQ@=x{½PI`U&\j#'t )+3 |Aèff"+؁19Grd5i&9auʟ¾9'j>y? Y]:gףNќO~U=qZ6O _JydF`R| cъgOWZGa<촍~Q Ǫ涗  6<֌jr:a(hc|?Y$-%fl.P}ұ>( K;~ w0)v=|T8v -A+9&kJG[7sIou Tè NFՋ_mC~+ip"!L (_1odOG=vBJ0q8+-Y2o~é UtErJ?j*Z؋_cjO͚Z#Wtr;/L>/+;NpA ^ilZa"y ?os Sk4Pk|;VMojHRA5upe< R}kQđ7nrpOjM C(+O8F#"HQW'b,`VLTzgR1d&=X]ߌ$tn7cEMNjVW=cүbʿu=v5KOK]7^T.3ݣ?ƿNGp+GV{ܨ¿c]߅|SyỨ KlѸ \ݙH~Z1ܨTpџ>ٰCo;a R GE?=q_Yi~!1u>!ϥ֒vS.#zvjh\E33.$Í;tGp)L>Wnۉ8:WaaCP)H-eo,ѿ4[!p$. 9k)I(vM/_Ws,P~[[V$ou׿dՍ7=ƭ;Ď7!cze#C_^Y[](I t9V<2 u} \tBzz)w>.6FOz&tޝZ?KC lIat9pΠ5t0CEez\4S *zCW'i>V<$4nV\^6p9tծ#*~M' q[&-o-ed}}> Nn6H 48Ĭq/YxI㇌}g'e]gߡhT|>jIdXHea{KM_ڔ[K,?cW;V99Apv4`n=^ ӼSZjKKa< k*&iX,AT99bG7/< ȷ';O(z&?enpr={lϭkcͮKyD=~uc;b\)83VN> uXMn1ʏr*7cyE|oj &tQ|8ֽ¿n(բU`y&"~GSga\m9]T)zkvS^Lv᭧G}akuw3\2 ɣLed`} _TY%5u8#C_Ż<+]麪9hrcu'/8#:' V+JC q@޾!/]|5XCpΒTʯK%9kgh\[0C?sNMwS߇:Ƈ4v!Dt[BW grq}I58xΉS~-͍T {s޽B l0$N+ ;Dy[y> Xд^ irnc ˹w5)Q͌YNFqPwS[Ȃ32D@}j> q%-ϔpcR9B ?O댵ef%@ Z,u(JP2U$ۈsiOtϯqPeC@%ƒ3MVi`S?uԑ:s8+ ցu$peYk0ʰw\imƎ\e+u]6 b/.trE8xϨ?ҸGZk|RxvTs% =uᩅ7t,y@4P\[XH>HGzzeneik0b-_ i 1Tq?z [c)rF2v:nvi)UAo$SuֺQ]F"A\ejRg5_3k"KC0l"`r'PӃ(<ŮtBt> ?n'Bތ0}J$9 Y{)stgK } 4]dMsVGv{Q\[G&7N42'~=\DťCrǠ5Z &}!DrFC(aSI$z=*sq\ΚlMG>; Wq^i7<װº^ծ3ݷ N-?s,#i>,FYm WvT[8.Ri[[q)~W~WR:tjoMpEAwXu8Q |3urhD9T ҽZj;,LA^kVv;7>*׼syWXxc& z&OiC^'t[B-HLVW@n1$xp2=|5|wuP-ƘMNTFB?y_Tӵ<&]!~V!}Q<è[]B ݈;Ob1f?k m7кuSq\rF^p@? >)5[ U%"-#rdG==$?}yo.20#Nb߉iz꫌̚T\UN6Ϛ{krڍƗC7q4nve` ~x'Q/$J r}@Zχ:kװ,pInGɪLL%}+> }IAOLM;>qCP%ȒC`P~b` 5_ٓwoehZȠ M.]ƣ}W%erSik!w+Wffmn].- %)i7Kr$^p @[zW6r2)8cRH MR9h$|V#\p=kxI֣O*3y玭! fCOrq|ujgW' $~9U$;p˅\n6i{64u&4 ˇO&}{i<1\o|P 8|Om{?:Iyd8_ tJ'_{V"좔cN%e\ R| Jڗǣs"1Ӟ+ڛ}ܗ%ѵ1 }:x- =q;E@WƟ g]Ý6!IF 1UE.kMd`xB_kf#wDžI9kͿtgkR[[{6-G]*Yx'} 6F[.MQV ̛UQn)wh}1vR_\ T7WP -$RA=Fqj_jw7u]Q#v\'RqW?~4xV[(Tma,O; sv.ROx#~8ՠd!NPkkY 5e{nswo6s[A^;ߴ3ڬ=yڳdD 9'=GjQ`%}#X*d{Vy9tj Q$,s;V+HxW\>NzRIfBg;rƹG2x KLeC]T&3;⥺[{mNUQE619e8&,&@ʂW=qV-w1*VH?CE\STp=}kO;Y#e$e8F Ojгv7~-`2 Y: AUAY˩ 8]EH db[6K0213G2y,AO:sj I*G8$VFaʍi#<-/Xy8 ==6t~*3B>s}?TWtcmԚ[x-~&xDr+ nIWD-'%kF 2xGO ѮerYQzƛAV^NmXdn-D+q]y,wzwkp~qeSѿ*9m":dN7!ܓnHh&^pʳt˯HG'6zZP6'%}?U< CwCRƍ]ELV8N#Ҳu)_xy3Bdp ep$Á/T`?Zһ>x#օ3au #q z{JyD (Oj߇h@=됱-qn`'e#^>unxv"Ʒ (O|f7|z3KNMq"V|I ]-Ўd-6±_ƹ,He=knWIUƸ[9/THoC㼵LTڵx3ֹ8ٴGc{ab9#i@B%X ;riW[wVތIa ;pzUE)aqPm:6gzf?8.bay"]6 80xϽtr|d޵يNFprzwJβN1RHk "|ʼ;ůi͆Yԭt=M:8cP@~pg%hC.ܼ?֫xT5}&?ZiF̉Er"jn[f<`Z&,)7q[KEu'!.>eZ+3OMimU6Vo{G%{Z&=fɂH?<տq{@@cJ14l {E'^5(Hn3Y'NV7MM\SE5}p-gٸeY0tYGSВC-YxFkhß0'\¼㢭݇53D/giZk:Mf(YpLW߳!Ges& OI ~>򎓩iiZ~KC.=Wwj#݇A(Av=i:+UU26J"4۶vL~Xzz/7dr(Ӏ |]<+|Y|U )e4\|jn%g/G_9#A|3u_@H-ԻC7Q5mMwšͭ"'jphtx z$$pO u971Pr^/ٵfB<_9xkZ%-!kJ v#9} qS[Om;V9`g|37%%J\]Op)$:v-XٴHr >FjZi@X[̇dJ6mWXŢ(у)*unq3G¦OHx3sr>㷅>/q(nUAbx"FTp:-:[N 9F ãpjd*`jyÍgoߙjRL-9J<7KO3[In̺}*̿)"_Z'"D;N׌ASns]_GxZtQ?.w1:ACьW'%YyzK ,9悻 'ZM,gYЁMy|R|%"O?,dl+_nn `WLI.MS?1yO}8Դ_ i3]KCYl*־.-A]HuH.4mJ6W(>Y=W ㍞!ӼGcOn{g j}Ϡ"YsK5w C( -_pݹYblDPC/?)-t`;z^?Q/zZjv|G1J=U:JzW-xLVAUC+yCG1%-zܐFd7P}#;(em'Q{³{uDmǕr' ZذN-%&ҰMn<%+sc?vUMrrˑ$}K<6eTNo,1oҿxycLgf۫FzniW |~Uiܖ.~SsϭLrNO~ 5qV[rjgZ̆%j#m~^v 䍑NvPk.֬yir)+4hj&HBwѫ\鲝l»kkmCTގ[]fGr2kj !+m[z[lu"|wZU[H{e3[vY> vҒvW=SLԛNn2vjgE| Ni5 fxt>uΜO?q^$P#"C}cQY?^<AǪ7۷ n_u:LJ !L9IǷo=|W+M'v繍ykͫElvBsڙ{O_J6ڭy?g,']43\Tm?> C s5A1J=[f;T+Z,|CϧV^Nde +v>R^M8?Ǿ #TCk9㯧5iw5G'f"U!"52q \]JY_^aZ&mp~qVӵk ޝU)jn} Y^dZw*F{rrW^ eKdVa |֓D\ٱL>{5uZih_#fCYRrQ} Utë.SLG{WCEP9Nƽ.;/s=]Zf<$H=-12j4}V٠A$gZfevM֘GSCҀ3= ~r}R}*bZ۸9>,0&A^/+o-.2wFFM8$dWǟ|uoxOOẑ+H{+ES[qAd澿мH@\68 zCWIl+XmdSꧨ>ⴄevLjɟ@ ~+RZjE;~"=%~H=Cxaa-tN1C+sg#9E"W/ kDU􀌕.%$3s wpx~L"疑N\lw<ҧP q^־'Yx>ڼ+{u1pI*Ɖq2X(6VFC]I4[<J㸨<3o3T9:ZVq\}DZ(B<҆M{_G/Y|⋆O;z{>Pv[G43$Ȼ`"$.8]؉NFJ g9,IZ) }Ӗp2~_‰QU}Frh?Nu8Hng=m"m a28^sO10\Xmi= zv@=֝E{k!cI$?L?ZG(]/8)T84MffqppNZ&V2[{|g+Z5΅}6}RX~`eKッb֧u ;ZUdgk/x@T.>]ŬH$QױUot3\ yFkm^=qF0\qҺ+C=M]kA~%iKwL&9SҼLH.4BU?=Gޠn lf)+]'⥄qM Q>)?=gZ-(s |+Ǽ{Ri#.QӱWY]O\K@b w,3Xz7:A|?ܯ`Of>&Yk A#nAG}+S:|͸zZo}#RkDw~0A 5pB2f3]%ќ46vWiQI 4NAsڲl|zei;%9s55tdvZ"n`2l\o4e69S"-2x{NEV`<x+$7>dݚͼ$|G5lZ3E^݈J1Oظ}^׍,:^vÑM;+n`#;# G WI3 w3i,s[I=FYsսfF{ y,1 g =kG-%IchQ]PC1s1ПYmS=.Rq)Q mQЮBu>b"!{~U[|CៅxkS4ch-F{Xy{|A#W$zBIX__B}9n zi5M:akR#˜H7ׯh܇ݗQ==:sÿ/xu~_1$1z5XSHv.\,ggQ^vW&)!eqIt/ï~a16>xjZ/pfx,WX0e = r@]9gGm 9VRrů?E~$U`nr{7*Ɵ/_.5Eoe{u y|~ ]*a4Wu5]?w~s )GKigǓ;|oiN Y)Q]n Hrx~ٚHLQqpr?}x[UWxMm"a {\[-jg"8˲(;gƦ25Oiz4.VC^i&Ymlmga1I7~:⇹&դb&фؤdq_<h-Ir#Ԛ?);i2nn]d$ #߳=7L)v27dnzB,Ⱋ%%rm~, |d/.s\2?!Zb~_ട M+XTI f)Cg$r:W.?jn ̃YzAjZHjqҰGfna"CYsٿ4K.FX@?y{W<+%rjz¼%X-<5B|KkMC–1Dq ~l={FQ  \E[>Y]VWI@xlu7Up:( #N+h+ӵ?;a[e~! O}kڞ< ܉lytۡn<֙q +g -ֿΒI-Ѭ1\#$csx?u9 ͉n~mT|fŜ t"?ړg|3wd$]6ZGĻux'5Eȸ4쐳|]2I$G e?^\b@9+HtDk/`sгҭ!XxAޱu};캗i'?Nҳ A9!5'·> Ơ}đ&rb Zg 0n'=ڲE\sp*/hZIsoGe9 OMb%hy}X^x*[kn#?i.˓ qVa4D=> u b6u&G R7;7W<Ѣ3GQrֽ_#$F5ß;OqZA2ZI P t}+:IVr6H9޼%[)rEs,d9+ks\AwG1GZvT J#,T6s/Mt!Td1Hg:B#'Ƒe. .0~~;YwVvAa*W#ýGz'Iビ^(F`8l=*Lj!]srᕻzսv΍gU9U2a{a&+m<>TvRP^xV,,Q88Mh"+1U[Qmt85dv.^((W#]a'ҹm;P{Ke8]DwKrD!XíKf.fa!?>?gEt1:g޺DHVrZ&3,IFݴ2~dUejh|DuF}qڴ䕞$d@;C.`Idq}kQ̷2 :kibոpjӲb3Ф[dȽ=0h YMlaV-ͳYrnxF=PgOs\`VI[pAi 0q\CH̀bhJ0JAGޟ=DiOen E=vG_^PB#'D~Tϴ?e~UtRGnj;!d;vep{vv[+Vr`dtI cW$[5u9T'k5 =mRH#kc!.1!z}q\7.m/Fivu}!u.tsր$GڛgQ9+ky=e*Rt0O Rp˞wVGygR-p2c Blwp6𺈒#øYlE!z tYPfjZ&tFm4$<8H9 g$Ј^@Ly* sLpqzHLCP[3G_.#C$s0[}+4\i>G=_TiD;.8 6$O-(g2gBW|}W8}~xQknD -ͱःLv>+QW}BK^yP:Aq./:MoJ$%2 q\|w9cEw^,䚵Mсه:zkGG>P{Pיbӎ{vSvgQ Usīamm糩QZ|jiΝ R /Q\rkzӹmu g # _qR7qVHinWqM 7# yhB>? Dn@w?߅E ŬI[M'Exe8 8jG 0UOmA*_`W=pּC[]/Ib\;WB5} Ms2XmA;Nk綖K9%"X\/ F(骎ْ>-\9n_ ^lGҾoZ׵+y!"H ϽufּeF;`}k'-~Ϛ QRzBZ3֐h^!01[i>Ur;8WҾ od06`n&THޮw1G+cP[Kefea^UcOmf 3+Ea.i(6\ǭQjK{Bax`ݼ70c]t^+;WkHKq\Cf~_b c=t%M`61#8W*N[>-.h$qS^RK֭.kV&uz ֡JuK;TREF%ՕK)*x"Qnar#kb|S3qg7T5+l71 { [=RU$7$zק?m5;[ۨ` rA1H76d ʍ7ct#Rn60%T9ϡ5A jPSے*}썣+"#5k| 6O=ux?U|SxLPүw$8u#+u]$M80ki u"͙l0}뎦KX»ZH~Wff'hxc O|=/;VeCqב"8e# כ(GldlȬ4ֶhSOoy_5&ԔV6T'~oZ{dr9Ql7Ξ^i< 9š_,5{o_J>h3|'#j,l??kfPUy`늨b\S>)uV4NI/,#mi@`۞C_Dxo]cb5+fKbp}V$|h 6,cbj'eGXME Yca<{ўۑw>֚)]VMdЛџx3;hӟocf9l-uAO_pvr_AմRH@ |W=][ +]_l~+g4[>04+:uї3+OK*Q}>vWKWq!R?ϭ`jK`FqUԷ9GtknZVx?S'oZd÷fk9^^ Q'~R^?] >R}}9@ ~#Y6arX)ҭ 9;8#0:+d8^Ǡ&|:PN=6 #c+F LX]^P΋K#k/k?\J &)H_ZfCYJ=Q}K:H6Ut?J4]zD0-n4+/[0p/ڼJ|']*,mj Et B?n^=%+V P2;׋]h$rU>jŵ ___5!l}0%9a#O2E%?}jV7w[L& W86}yhI?OeH oXi߾|)1ۡJ/ VH,"V_0ѮòMk', ^^ufZw<b[`6F~ hH¯|5k6/e{F8>-S^)2 ֱ㡜~k^8bTS޺ ٰ^ };3!7:W } WHI̼Buh4NHk &_CՉks:0[gew48F9ھE!:^࿉g"AtInQǣ ELY,XE6 m"UF-pT%yq Hړ/81:dhz֕[+ '3ҭyo$ƳC !x]}ᛕ`P} z=oZw[iZ, װ~|V7s_%lZ9Wkz]0tlD}?}k ĚB,OC]li%Ÿ|_jȌa6?m]%ޏ ^^4,Hvx\(d'I^`;NT{㹮2n@S'ҡϠ,i @nh~P?_J`֣KKDwx#'ں~&2%3ItB'$WB9aljGsN5E$L9q~E%GiQGrq_W6%fbymw5'ݙj@6)&1l"Jcګ[A%1=k'#΋}^ xBf$? blŘtQp}z\G~=q 2@5%\ ?xƣw;WޟO~b{[̠Q] kk`LJQ^]=T]>kwq2`7G^=DRӕC)=G91'$2G(l^I Ph:f촻$Y?'׶ztg'[tMz: 7.JutIv`{i\xiF {OczHM s/ kbnUn`qErttn1.9iTuB\WZ߇Mz,Cr9GІwoZ4zP;e>׀|Ad7UE*>hH2>wrW<(I}j a!fL;e.y-S2#bsyR+LݘXx#ҶQ*U$dGzZeԐ2#jRy8xڸ>5lciҿY'qZKdE|x_gmS߃sW腴@A pZTއ¾[f&!"[^,qÏ_ۉmNq۽v&|k_OmdZqW7 i60G_|:o5kq5珈V]F~t\`Zkc!tRQxjýƢזRBu^?*&x) =>j~#9kwO(}GoqI[pbe9Տ̞{ֽ43~4C[8(9ʽm39ԭn+;MY&7C+c9ע|/|-0Beeo&s5L xW&.iG.z'|nԮ%Pgk/ϩTFH!K.z}e?Ҽƿ΍ >2*a\|CEP5Oc?5['^ ,?>լoB>Xr7=WnzzGzŦQm~&|4{ ciX1aU6/>u5Ѿ֌{g/X\ޝAGq?yqKyNrtA#`Jǥ]+lȗty.6.qnl0ӕ9ֽ{[{eŒ_@(Occ-I4{0vvAWnV$'=\%})`g=K'r7t7RQK?/d]ջb1k:KIFEJve<=oq8ڲu6 `<]-i_C.XOc\6.5F8$fkEykr˻]txO*81^hFՙV\Ŧ]݁tŤ3i`I ԌU}FZ2 {qgI2q‘*\ñ~IlJq}Cg|{{WK)OeB/"aZ{ ϙ 8\}j %&{|.>R1]&t HI Z , qW}j=.׎Ъ'*l;u Q,#J&@$ߡ8R0U4t$wd,nhMPGEMcC6$"Oi7Η^[GlTӎQms<mOm`I̙?lgf:ǵ⹈L9O^%BҤEC䉉=6" ͎HHzZ֥DY[irAmyFP@~VHaNx8ڸX-{Cm(E!><74%Q+qwQ^z"I$|ўGZ=ZawfG] qXhF|0?q1PxT1:n3ȫWRs.d짱=V@,&&QӀ}Z嵋I4ە 6AZŮ|ح`rG犦J9-X<8oMt~`$@<ȺUm٦Ocnƍ:f)~Qʰji& *2,/78 mH=ifVh1mK>*+> d\yWYqlΤ?z4p;#ێln<ܣop:}EMY%=k堕FI {c2A~m%8'?tUY1"2C+>1wiv+i#1ʞk\BNLGOzڈ #U\Z36z9FFp}=(fAvFͻ?\1~BY%9#19o .}npݭ ;P7,{>^ӃR7S_1(Pw}#UU-+`ڠf]&6y+-lAja/mdRYUF0vJUlRF{VΙ3IS$cGz5 2/9:`vpyaf~Aax 쏆 ӽn>bxݟN2džx'=Fyj<{謮|tcdz±4B3p*ͬC G+=!4,0(d w%s!޻1=izbq *$!nq1yD8wcx]0SW'f`I+ϴ߱P>zN$aٔM@("GH~f$oWK ׅidm7`O׭"S]-,w'GmVd5(hM;weD<7Nx[ֵ1]Cܟ׺c^SE ;`Sk5BIy܄u ZǙ]>;>_♭Nc׎74vnRGe:Gj!䵬@ye'ٮW=q--aQ@纅ýf`xNP1oiw7ZF]> ci_x3Rg:vfN ufAGFx/4fyd^I:}*K*a&5TL,Id! F2y~8|Y xS( B8 G\3Uk ķ}([#},NެH'Gz?YB[6qpv{jJ:~0(ګں"/klo-PyHeWUP1׵g]ZGǧ0<>S "Oز8d r }e{f$#5ѼL]AP?3S&{fFגz6 Pi|mJv2QR:gޭǸrVT_<\KQ7ã{Gڻ_ y\З1,rWȯ$ct*-L%rӌ*3qi|V,/Q#氺!%۳q^ ȹ  w5ђ>_@|"|M!L) %c{7Fy6P'm 9׌7֐ utgEJ@ $!Tnhdhhhr; idBZ_m|eԼA!`/AR:%k{O_ }s50GO&f%eʹOhOQZ)_I4X.^UN FXUA Ҕ9ݍ|?2\_IҽK Yj; MQS4mJ'PUL  ĸnt-̇*{MMg*mQRS]Lm1}>O6`pz 8W zxҥhl۹ @Aܿ)5``M 捀yvH;ո.Y2%I4l6G?ޠ [[lY慺z{ҊhhOFGֹ䓀5*%}CRImFFX2ZՒ8h?qwFCnX_rvY%&r%Ēk3Av\sXH^"'< } vQAٽ^Ys\[\t|~U;b.vExMo2;= y6>ˍ,kkN }_LM!m}cw%_r3O~~'[xtECK6#>ֿ84ol8~?lTΛ*8U!ՐsFndQxT7zxK"W~K2<Tċ%J{}h k:iפW>ώ5h>+͒M7Wkpk4bYIYx9|>Ӽinpmuy#> +ַ.~^XXkg%V0]5tmqkϠf?Z=4+߱K'*˴*XWwAms2RBן|V+黮M?p& BpG^Dbp圼g]L76׊ cBm;3[Ǟ~M;\畑C} sA}GQ_so*{Rk*>*i~-vC+-5u`UO%ͷX38it WY[JFs:栺f\94V KaKu"2W{uH Ü+F[7bZ/oZᾂ7Hpb)rx5~_^,+]ǩh U_?ƣR?/lĢD#@q)2P_z9"+)e  6am"]ucpe1Î<.gfWM[(m5hfC&Owd63_g5}:-GJyTHIATisTUwH{4܁]pΝ2ɴSè5RNǡh:oqg{6ف%5wY(ꧭOx>ԼGi̾)|A}ʟF:W]㷸aC7> 'CCTe2BHU+PdCL #oZk~?zt33U{-*6j/lDsSoJY[o>MjZp\>+;  aUTd[!=I?qk#}φ1y&QAoU=>VҢ7}5=Y=G~z!HӮB?GfZI>%wjaXMe2˔FVE̶W <lak>Fޙ&YA4rm[r+_}%<$ef ΃IDfn6XH{1:}=A oϡ_}*¬ sOּIq^9ʄаu9Ur'%)Da{"_qElx#]~r/VcOvqc^]಼Oe;:,5/Diky RU#gVsTjJ>뎆WūZ!uNv $O+d_?qVZwHl`8Ww& Ũr?CCA puCk|@r'j>З6:{^b`F2ϣ)~#Ҹ& l _Jӟ, -㇑q5%W\B%.c9 W|%sQtӂ O\-r3Z? ~1i^;LL{ExpOR\ff=2>@ ZuokV/If):YfBZȇzxޱt_\XKg>9[8)k5&gٿ >+M/dkS0WHU ܤ_xWq ,)pqVNoy-@z84tFW=oS?:E4}^jnF2?1{Ca]iZd_k\McxSj0el^y)"{M&~XΤ[k:\F ]s"{2@  ݀ ?35ڄvpnpCFGu89_ |K{™QWȧ8wڷ$G>)kk!Z>+gYAUEV=+.4ۘe ]r$zki+2ֵt",oú\JC0w$mQcZ,K r:::Cs&tv|nws{U;Ƿז`a99XyOS9tk(nc{qXUqوw #lvmV6` Քk."#B7#=GHUx@Rv̽A2`)ۋbRٜ*?qu-"2ݻWd 4 jKkإ];a5i-,y3$z]54rYm{l=+>j_<ѥO kϼMi{kSʕ7j WlVD}y%t'G:#$֓\E: bek2u+#~|| ^8T> j=M"C :V-6-I\r)YXV ^;⍏,O+ź\tk$DH>\dV(//}W?J6K:ylr\tacʧ.&ieRBۅd]6em-̈́QJ;5*zn 7y;U%L*sH<.g#ym1֯QhTֵ>B=+H1I?ҮI!m[R #Hf!KчB?D d*Gap.8kawl 1ri=3TTe*sƻh#|` cE-֜'"rpGҋ_hK:n.P=S1խ2vU$T'ۊϱXv4Nrk>ek"E Wh:ÒshZū LRX8G-m)n2rHXw+reGfS*[+g\C$dm$3E m[a}h0U8l0\dg׽25U󥍜N:ck7x#v5Ztxk*y8\280ܧ4pD6n  V,ksj4Ɠi-xlF 3xpM4&Tѵ]j$6r@I>MԴ"T9R=)v>hۇhSY#%J0Q\[$m EdV366>ʹ9KgYOCڶ|s]8s{c†u){ ɇ%TVw ԒXryk#FU 3bʤS®nUԯ'8qX\ Ā}=[F #CWD1$_2Y( р'gxg^A9N˘Hr{IFr%?eOjڲaud81\|qT%dOZ6ڜrOl8,(mIC& U]JuVCīgЊkrqyUF'SUI=*J9F o:qdKnL9ZL-U]ye^3ZFi3cgp#rh~V\[O_jũ #;Ԭ;Ecc6N1GBzF ]BFT~IT&XDr! Ƕ;=DW6h,W!ڥ]!bQ' exFQ3ID(R((]y8xU@11~Ҽ+ouQn|В=OZxGkabV <αOdif;}oG\" ꦾt< w:Cr$bF׿{`hpz^:$EHFyGRÐW_ݝϭw7ؙȟ0m5 f1 ÿZW@`,ۘƺ9tegcou α#`*{XzCμO5 WRJL|tN޽+CE/ot9Qz{(Qi\(boR@z]n?WM'v;pxwWbHT!}jd_QWWkZ}ǃ 2mҵ(8ȷNc~;6rۆO&XL_BjS9'y4}@[sUT:σ/Kq,]$fg2l؁ڽ TӠY]lא)(ؑ~>#&8-ˏһoNGb=J_|m[s7sk43o5kWfK\BA8q+/6^u|e EmzlUi8Iʯ\}<=WmwS$S۸`WzWY.e)+3+mn尣<φ0Vlm '{5%.n!(a᳻=Ǡ Mm ;߹W4SQ@V'=\DX$Pqm8Dk #,p ,խcX,f-$0UQܒzWE|[;v;;_|N@:Q2ձx/QӹD\XuZ$*Te2vȿU<ץG2jH|G{]Ewgs-D*W?ns>M":Ξ0kdtoכS vB'2s\Oß慪Cv07!e< q4ӳ:j^ HiM^E $&~Ͷ˪xUH->}8^ Wxpr)j,7FS},.PtʷG_6I_wI20S=mOQRIw 5q~6h8;{KK1?#c+Owxڶnauu>Xw)|(z%wuD S˕sZ\ Tdj/ǞG]@ZxͮQnV__cdGu ^;WچiA&ACa_;|U'ZMs =5lOqkT6w~R"o)hZ܂nT\d~䶓k[k8R0^ճi±݄G^knc{wVav>~G mxe[+<*Bg+smG7=žS[؊-bR[{k;|:\G<5iQwUUOHjc6?s!APiT8l{Ӕ iH;3dçֱm_,=5 |`Om} xɭD̜<%۵ʸx>)Tax# ^.xŭz!IEz'ci!g=6?$T~ bO5ECL{ln Vy} K1ef(>?]߀j-3Q2j~fo,h}nnUS}`~T}=3],Q"[̝SI% Nڣt? :|v>euר5_? %_2Ő$Nȿu?Q؊ #FxpM;^T̖>wgQWJNTRsׁ=Xc xlw_[II<X_5YVUpL2Ϧ;|Wj*F\*'⥹ ޣ]Y9lmE* k>|Spke+ztD_CmEW=+|5MUEm%oj0cN{cOS8z\-!}!𕾯nVH{7q_??XCr~Y ^.! $e=EbLoᦤ&{4gj,SY3[_ Z|/q;X|d'ƺ\-EOxoo_牖 N5J]ջ+\zC;Ocz ޝwCD]ӗ~kɦ]e"TY'}-PЛ]ڑRkZ4|>P7Ѓȭ#.Rd|yR\0VQZ'C:Ͷ\n laH p^e\?^"k h+pAt:tDr0;}? xߴW?.?0UuuKmV܄V?.2JIGO:a$zMd2S>#ھ|? /hw@ECq/r +9[GXWgQ2ڳItF)ƣ'J~7N>D~0<=zf߄>0,cp O YA\_IHCwM&2j0/8Oׯ $7>]ͦ$V$Cꇸ$%cF>kk6ix28;GF2Q]l}d<+Hwlh>?+8X2 !f3p?=O -Fã+sԂ8G֬IIa~6b*򯎿Zo <=OWTs$p:&tmg"he #}Sx$H;!) `88_4|w{̒#.ӷ޵'rG+(܍~4ˏZy?z_zYLDdp皭>ċr7\r=_f/xpA۹'О٭KmJ+:y"J,@9 =~̓KpDd=p;p?$CpܯY=|quxo K脒",~e'=@mCH-#]YKHe܏0<\ t5Yj~fxs?¨WI;Z zޱ-ZaMڍMbeVucYp,s7͏R2fhYI<Է x"6B`F;o6,%u16M@|c;e ׫[ȪٙG<TuK6txdTNYa5=2r>6I'Gj+6`tc8j˿ҭ2yOc*PHɦZ5 H~AoKˌWqCǯVK-w2s}"ZHHmKDzd]rF~jW؇Ufm#縯`ӧ`]td`בOt^DzN䜎>|YmVޔ /CHoֱ}1!Us #w4l bc.匐LaN٬OY7+Ү2On5c6Oj,<fIVd9wV-cb9ÏTukSs֋M }vwO,H0 Dp\syVdϕ'q]]Z#0teGw.vHKA0=okֵ5;_B ,`܊惴<&4V1 #񨬥qڸ$UAu#?a42Z\i ';$Nz9qukhFqǥ!icz$ezOܫߠĘIq_جs>dc20k n"JJQO״Eӥ2C;eiL$kg$ëd<5lWfԎZ/|.kFBO3zGp[oMHPGX,m~%OMe#{Ѵh'dM E ?8JL <S%KG!rǽvMؽ)ïu>g4v}lvNӥ]5SeqM%'85H|Mb Kǧ\p%eg^@nk;OI=E4Oʟ׊ƾf6Ĺͭ+-$I$(;w~,ۭ%QQһm{~T8=ju$0x5Ҧ1qks.]g6ʌqc=+Sݷ خO6|wZ7ibcv?2*߉a[Sգ!޹Vo鷬Z wB8*Ð~ZKs6z'|s^kq;N@k'\,cq㡫m2G񟆵zۃa۹f0+X7t/ek>܉<>`Cώc=qkOb{y I5`sm Xg|H?|WhqԼz܃XՊ3ZrQM o"f eTUõ~._:U`e-H5}a{jxqi-Md tCOhb>iA^Yg˜fi^ה|VCxn㗈MI}ZR0/# δэ1I + V2eVş[-'[6HKY1[{x灹x}ScivGoxgU{ j:BPĒ5=?xn^V}&-Ī_pAmԀjkY>XNs3^ZIS9+}9ټ Ȥ" U-H\ wԣ-nhԢzçඋ㟇r_jLt!BN Wh|2S 4o:5Kh ?s,;L^,orA'5WNax÷I#ǐz0=9BgSQy>]njO ^7]g+$.T=DZ /js,~kJ׾dBn? ?k<)]ƚ\:AZJ2nψjk}Zk/9OfC ~Do]Q8Qvm>~<{כS(Q- Qc;$H2U:04i @ɭSMc|z!+"95_?ӍhɊueuNZ-[a/4Z,s,@<^Z3"o׼⿂fYumNEIv}+Ҽ Ӫ ymP'u Xx١I=9^ Vwqz{׼A47q) XȡЌi'as?>'Y v'CײC:4L~ប%ٵ0ېsqj0{eExg߆Mel.n\X8ޣG=J.c;|IKNA+]qaZޞi(g=T4xyX˃ʻR97EXNv+Nյo1i7<{?RBTO[>wkY܊NIokkE Np鮑 b<,d_W~{[:"Ȓ>#2C_Aw}:3WW-qTVzo*JG^T2݋-::ȣ޹n DR1Mꁴ3i["/W6N|z8n r|7ZX1M$K{o㍧%~S hOɏ_c':υcR,m"dLu{)l㺵vRea/MBcdc J@|[jmce͘ObsۯּJZO7[R1} ~>>hiZ>[|E/_z3[HǬOrj [kҼU` "&F˨dĿ #cfhgݏU]>@aws#TBF}9?Xao3ۿ"z~6|1Xkh,Tk3$nʽ€I{>I}/w?T(̄z)3 YbIЫ :On!gWC:P%7/jۗNkՔnɿ wH=T#^ZV[^BȥdPaU[kܣ|}WveD6;_Rk> Y/tGݖw1ۭX,WkZ%n[#{Sy~ Zx\ ċ4E[X`O߯l)2EyƟ ?.-1eY1iryqj9 {mbxɴ}qG\+?75'`Үi!O?^ӮKw7''茶j-mH5\hWDݹX{uhT S 3{&XYqrʘ` # |M$Y,?Ȝ#,N8K܄"6z-,sԉAsgLKQZZhH"F5~9,sݣ9-̷|^W.s ~0XJ$Oʗ9ǡڱIoPNLS; \?hyK-ZgC׾yG$[J;} H`.^ة}T=מGaQ'SX68^ VʹlsLcɕz*SLd:43 il͋'Dlʣ6OcKz?W>uLVzBG_un }$-J& ʟfUv@n`}q^Q_|DHRWqXxCGèZ=O㟭{ukZ]wr)4x6;{Uú?_-|\OI5 ֎"kPP}_[3 9zzRY] ڲݗU8' :kG-}\ǎ 1^h9=ѧ;n-孜#z|S<3VԬPӡz|OX]jmfA[,2knam:?rEۿjbɇ[޽4_Jljs>aHxzůڟVwC0k{}CxnCVlzÿ4 =+ᇯ}-xM:Ha6d75ƍ-OGx#a࿈5(-fk[VSчuaV4R>ϕQ`u] uXQo"i=2ہ 6G+#t,l<GV$We_PM>M]ςO^=zTf_4hd,0>ֹ_/:V<?PkVI.5S﷦W?uA2ziuw6-4Q裯5x'>yr yz 5Yh"/{`\c'^M|?[;ĚV&Z\K!c緧9#.|aq@eմm"6[`@kg^4𕞧-˫C5HSS$\_^ <%e[j%%ahvl.3^xZ~E Uĺ~ѧ]U!f10G ! qM$\ dIm^R5+Uh?bAT#'d(={E@"$m5UiTu*ynx~.Vl4'$桢=Pc{Jmލ:]I%¾|8ϵslEuZHN{\]7"3gqV{-;cf]̣]ul/aP0>jzn@hܐ2_%_T>ԕӸݚ9Vsa ŧ\w\8>EwrAEf3O|CSY#lRzx]6nwDs `@̭t}k&JLX;C`vn;U-txqtt>d:wcZnɛeżeĈ@϶F9C\k]F9F}k1Y$ y?=+{i/$=?Spp}-7i o'!.c6ag1̍Z#BvH8-Kw:F{f6"z+TC:ț%u9+SiltrTs`9[9LjZ#¢tQȸ֫ZKpso΃zj5C[%kwAOk'dg^nm ȃzZWդw{K h:֙mu ;a\ʐyQyyZd|=Gkôz5NLt:]=d29IבUm&Q!Ad=;&h\sGi"]\&W*ޯn+ ӭC4B[ည7zjC=;y޴3ck^]># fZM[FIP]A9UqN~7;v&n:71u5Z^l-$;Xc7\] ^ƆY%\yW6@'\ֹ}nu˨i;ukd::{({51͗N8qRL6KGہx'_VFPd^tǭt ЖJ9]&F18$lhy]".`3eیrcTӠC!OB9Z[6kiEQfe-K/?8IGΡnGGYQM&vr=  h[jm%wf7F략hYP"s ZfC :CCLe՝-vd#Wc6SGgK lTl=kI|?{εf!sZt KV9?*KBٴ['|v01a|혤ǰ=jDbeIg^ZSͅcwOBrXIm":->IZNwWc,\`@+= xn 0L|zW_7u(2`,3Wtf[E"Qͳ̾xhZ#m ^5k:C!^v9c^;.=ơBaňH{S[?wvEq_z넹ф;j}#v{OPG\}+˼v688Z{oDditr@3z"8`2 )( HI\~B!,o¢ZkjT9Rk^ SH״|9Sٲ{_x_`?Xj '{ibt,=PW~͞F7tc@  |0-S^Ffֵ|{ᖦU$SІ;$R9iPk ?z6UxSKtBȮr~b=qZuOzg ^7#w٤'r uBt낙Eי,DlTdgk3\˙[M]]zeJsFAn] \+ 6}OYu;@|tk/s, xoN>Ťa5o-%{\>,KV>-j:,On#.=c`4>Tdpk,RR`!ٹƩM^9P3OҢRZ=P&C9Kx #Q7fs&vš#T>5?V).07N[sh+ wSDr\ZbprЃk TZ5G09/_7ĺAҡٿ1_}|3_z:"6ܝB}#ԥ*{vjgc>iM sO2Ud<`~<໹W|ɣdm9{wk##j' SMgxOUm#XM#ַuǪ{ [DBTsj׋xOhm9#a5!7g .Ȼn?颎x~ Uh'T}bY =|Wk .y w(ʏOnʇ'A #"E9`?zk$ކa|⿆so&Vx'푎ҼVH| ҵhW]}߆z}ܚP2\iD?oc|a|e3O#pF8 JKna(#W&>ϊųdYhcz^$>bPnuڝGAnXn!9 WG#([x(#t|bj7^FF99S\5-f-Q3䶨\ܒ³,cZSHz~ sVsTt f>ee8"r֩0Ԛo*FKLcއZnR9a7כ(34FL"Ld5)tw.q|>]7mcc{?؇{ 0abՍ7+YމW2[6/Jo>ZC 4SiWS 4RGzq|kZ|k^u-!2{qQwdRbe#G<]`\ Qצg4Է34gtR7߉c|0ie#l'dc| KaZc}x'2=+r;;rO3wW_dVʛy8ă;ONGV\aB;ϥzO_mbJxdzQOռ3kiq _Ku_HFSwv[pr7B=~NC*"qcS<<:uBZ96u17ӝ^g,W!0T Z `bie Faø4 %>i騘 ҪD<%]Ç=jFkEs6yzS6؍+_rd+p3W-uq)|= xŚ;ugoE P`{ڴ.MZ $[!k-ǐm=]8x]g ,BcЧTI7Ir>? )2 M sd s^;⌔L8-dMk=7GmV_HUˉ zpO7Юc}ޛ(߼94x` Lv857:r|ZVv/I˸}kxf4Ү0Q&/W΅{"Cԗ[Bc}֢mWWӦUYei0L2Z@H$b|?ǂIF<˘g֗~!73jbf8Xa Jrq֍q{rX=x$eJ=w~ \$F)u؇Oiz{/?Q}:I R;WѾ-ƕ:r1 dՙIFqbH[ra\8/Accd?.W jEpY0Tra7uS] ɞ͜wKaH :6@( qi-xaWm54BO׳-cKҼa`tn+n[9:|/}ࡶRѺG~FdvY@zbܡ(A'5VKP@Cd?cz|X|>8[,'OzX=gwpqJ1 %o+4{%#Ea5\c?^= 4f1FrݫDa*\*jd8!Ww~ؘpxWOd$+㡠gƱPti<3÷ C`^0}Aҽ^Ӽef~Fќs 4'q+,yE}bݾciw aԾCr+_گ#,mNeEއ?*:׽x}G1T} +#wvw!; qJ9S֐+2\ݒdc"v5L}ېH$tO=k>F<GB-3;6x4;,fI#,A:VRi~tv&{[UnŢjIej d\dv-|ckIA`5 f>̖HdžH'[+Q47 `"+IMI)O[Z$C%JDOqF++^֬.-PrylW~$vr8\>MEӜk#6LHv=v+Kڮci}iowm!ܩqtؐkjSNLJY<XIGU11m30fh%, ያkO'$[9㝭lWz3[N)Ǩ{hԡxOޏ8e>"GRxͬ2h^)7"8ȥcxXCr܎Ew+)Myf;bQó>ZWQi>3& OMB*GSjK $򮾣޼Zǂ.t)Ɏ$S쿣z7~J?>OԛNV ^1, O/X8&ωu٥p WVt~Z[ž9>%iYK \i dWHS.4k$)SO`=>]Q_ nž_]օůR]*\>ѧ6\[H7G2 x<~} r~ME;n[PsIhvQԨ:MT܋uG-an`pA>|] ՔfkPp%#{|6^3E~#gNn⹶& ))J<ޣNwb l1#Qх2{#$9Jn,vڑW?*n׮jRZLbɊeê1\55NT-Xe*9םۀ4VLJ/,t1ʒ/FG֭>)bvC 2_| ]Z@6>x߈>ii$m^<}&&|#i}{n{'/zW6-AZUϩ[F Vrx=1f'Ŀ uVPNO{O@OcfWREr [YS{ץj>gX'ζu ʞ2}5)C@5e9ӷ=j"ݗ3}aN[/?e}%8xt|IG伻ͭ͡,@VS!SC78<ͽ&.dO3U#[/n.ӏfߛQy'''==+G$%+4wN`hm.Va kmC/bT ֿNbm( x.xtZ5bɳ]ע篸\nn="D$d:Kgowm(3)yt'㲲 m%ڀU?j({ahŭKRAa#ާ9#nm!n{eb("TGק9U}^H'zȪWqws '݁#8Ju˧wMizG2HOIb\u$%M`2ɆGUBz0ԯtTD;\ֲW~+(9f,㿷[C[|=+_љcwGIN͚ޑn#`nm$s8n8{b{EiiVK$OgPcr`>[o5+W<0cOc5|ȴj>Yy0koRi}[[r΅^28#c_1nLrSWL?>޸ YAxs[ƳOR5 ǻ#m7Wx#Q }SN,v^$(QP~?uFjŧ<++]©98?vu˙cH'wcq= p RIY %rpGu\Yۥ^W܉zgῈX4̃*Kޮ ;ynڳmU\ya?kuF [8ڭVkm#A#q_2|psxj^dvU }A(Sյ9CG\a,b?85Sڇ|+xZ~էg_zw+6v;ݘʤU'Eܖk}E+L "3[׾Nk0@ 5|>ThnfFFCN#amA㷕^+;ןJm='LVb#}i|q-^ Ƣӯ Ũ^2#an]y26 pߧ*73i MT Yո@DEy J6zq֬423vY\o0 VKw 6G*GzS >GZ`f iFO ;[mwvnN OX\DlpTeO5f??7;{↮:Z-BRAF+IU^Ae!m G$DK:>n%]K\cqk0WA$Gwk㉣8Wv5^i7[̅YQjObo$H'! 7R Fx?{'V?iFT) }JKA*r S[Gi&Dt?r@<:J*@&\.tPJ\nN)X d\Η8Pzqz)˟PIjzݪɍm'1X7*EqpFza*}#ߎ՛4g&h5*8`|$]z3r1Ҧ4f+vQK-Lًb9bGǧtm :z/kQ,nZQFzk`.B&dex/ZkI nxpD~'b)>B~.Gm'uc|ode(3溭CdvomcVy2g]M79gס):6 uUݫuCVDtq|fRw5Z:NJGmvŭntgº-ӃP)SԜ]G$ф.uE czM h+?ϥpZ|s;p F7=\z2)f0(h.ܭŴ$l;NI| -:ŐI 34yz?ڀj6ɱ~ݥق)WB }7PsEIَt?Kgk4Ϧ<ybYK鞵vzUAAx}`]--eF?zDŽePijg~ʖW/%^ܑWot^ظukNֵu="Kk8f;+~Z]2?үFR|)TIYETQ@7mlX޾W\/zaR{WKr8*cQJȐyanxAǽvѭʹdrU#2 q~A)):W4BD1VdƻC]wХ`i7` "ӖHhG@DmfJ7XgƿqJK)OdlL>.bթY\)))LWx-':o<=5-JkIHU Hc?h~>VXbzyƣ-8VF.~RqOitn':& gZklv?Z#_J_ o܄U5<}ssQ*yPu_)?=}k<3ǕzG5Gc= Z};wuJXZ7hLn 0TҝXWRG+5o> 4MFL&r}G=w)7} c},K]"kV?(}GҾ5KMf -'POGSЂ8"2GR/F}%6vK@\{y0GF1ҼOwe࿍PCk|D@ߤ޸ ǿ$N}@m>..M5t4z)߹6sm.qОk/?H`99]I- ZiO]AH=sP5o9=*xl]Z"MI%m庫VjE w ԏJ):l\s֯i0UP_-+ZĻr( 0)ÃӶo}ciW}Zs2Jsj̍mvIŻ#Khc|Gmi:;!$ >u-1',YDw g*5Enr-$އҢx90FGMU=ądB/Cz]w'"N%+FA^E}EͻZ~5j2a"u͠uҾaD3~lInB5)8; ^1oiWkZ<;fGw=+0HpkKg_ٜqa6Zq˞C)FWdHmHqN91#2 Sס G,`k0i޵lX5?"D7<v;;7z7}Gӿi4>#.3b{MJԔvC_h-˴`O^Ǫ5==L$ oeP:~?.xZڄh&#|pέЩйf_4tV[d UScnZOk[VR9 ?8ϸ|G:mʻc煏·Zpp4wZUYR(aYwOڏoͥ_n̳A\O =Gco~7]E%Q>~"|(Z5t2_HKmCЃk ٓ()|OaڠD]>k_ uRu9V1·?oJTcu=VU睭sr\*kzddQGp +*0D0AVG j{=K68cV߅K.ZnJȫՋIb8BORy6uN[o4kH6V6:t.4`3: ~^A?/±}}Wr@oԚCC޵q4/ot +랕s25m9?Mi68 +EjA'b; @9sֽB4-CExRY9̻0sQ@_= ;Dž|I.w3qqnJJQ0k9Ci_i^o2i*/FqWמ mtnHDsk"w|fL%aهcgړ\C|R#N_V}֢Q ;gw7:=ʺ3!S^|or|3o@Msq2ۃ"ncP%Ɨp2Tv5+=Ae\7nZrw)GHU@CcݥV1 ꇷfƲ:YzV-_s=X <`a]f9(:UjQݵGEIsfdYZl8>1AKR16K@nlDU'^r*U23׫Q@$cprn㨮~[4-.QWan·5W5K x̝-e?doA\Ԅz$>#k[? `qFs_š7,䱝JH:4O.#g(t 㭶64moX)Aܿq ڝV:Ղʦ45vhHנ_bѺH%Y9(W}jmggzPI+ iTnY Ǿ*m,Z=H-X_{QYDW?=?^39Q߬@!%*k 5fkXgiq$:ZV 29T4NL^!>UuS;Cú$ϛyhǡZ#ĺ%巈4IXe8KzcDZGFt'}Q㯄6>!=6<0+57x{ı4uҐ&A}3I} eAU?J7',w ] p~)EFSWCOY|TJ[M]"VmUS^5K[XtoZhpkN8ܧWϋuj:>Yk6ס{1}]LOrU~#J MMs5qY-;㟆SYhf(C5<\d~|i\m J0\C'c\~+i>Is]=ޕ)FU1Ůcͮn@O k:OɦjCOmWm^|ghm{k=qּVMWφM?Xo.e5v>[:mV2iILR eq,8MSJ-._?/2=W >,$ CrIimoSu [n =#!:縮vSɍa*Ō&MxwExrd=7Pq[u >C#~0X4ӵ\f )xGc$c$SMG,uǖr~fA/nw& ȸ<ʸ5jDWj̀o+ӽb>5|q^}Ds5!@ϗ"@1+<3gHj2Z1q܏C_Q; 7 <,p}j'sğ忺rpX -B8}xW4{FQ' =~ |?5[鯠iڼfGMp~ǿt$-:O-ԑ$JWwW>"mK M][\DJȟ0x⽛7wƺ=t)L!U@e$O?Y0$IpH ƻ=:[dԬ˻{lmYXgn 9`Zlk<]def4D_: ͺI+Oޓ=Z\P+,cQGq$$3إΘPqھKyߍ&{_ᛔ}=vVkos  `~^iZԤ;B"P^܎pn_x:b$d>:(f.z`xNMv{mNN=QT@7z@]߅?i,;mjbg*_/|^Fi5DqhU$ M~ ׶Zp_2J%*R}e{K$2ĸ߇ƥQu9cGj{\ zogw$.wWpk> ֑'r,.m{].ܝ>⠠DHbx%+{R>9~yiu3@v0eOq#"RN"hU&* S.<%}oCS2ݬ_)sHԞxOLWM|Ps6:ߌ gCEsiq9Sr r=j'tKWG7ssҽ STWNCϷ~;`_u pDIH5䟵OVRBI*GƵ݈QGˣ_rwLzF|8@o4ܽđJ #}0jM: 2fIeIeEw6,\ݖ9S#*q3|Q6s'JUgkw_!'_z-^/+b%:{_y*wO[efHW],$T1& Q}iKsoB=>%BOxQЯ "r }Eye[RY.EŊrgc0UӦȫ}4r:kqA'z7ܔ۰?^C:Bp%S[ ~{& 8Rx'{ ;K&KIG*~_J>rv7oYNvŭ3`'cF?:;<\%8nխ7} 愘/#2?tVKg60d[01FF?4۳o)YxmaZy0eH~as.tX]=En+ zթ3:gr}VH[-%\U;^ 6L[K`POL m y؛~I8mH#+p([?6zY[f =jߪ]dmv7ns3YzޜH ĈsOzpx,8n1TW RY|nvZO2b8ڤu?/p1aع3IBsߵEsyoa`crWoE?J,x{ڳK*7 3EnrKé8ȧnbk:c~Tځ\`O񫚥6;>AEfe7@cjsW?'6c?=֮zن_.FWAwil͟-~\ɥ^#9-Ib:?u^XoL")@iru1ص$xۂr ZVVB>`QӚ$f cu{cS{SJPiw*<OL{>IR_|Љ7qAbQ Wz}OJ0ӯ$[S I 0> Se~;jFR{Z0:aߝ|ߨ=ω M?BQ/3o5!> I3gbXu/]-!BHQ&#m.}Ft(Uw;1}qZZ&RϮʇX.`02{qzמ7ɳ<>zS۰Īw _>ݾ] .`*B?=GJT/;kZMep7:$gc:kVdI"|P֑lʮL"[w=Xw{+5H?u .n;W~ >Tir;Fd>'Mf}A i]̏fV6䃏\K;v @\3Gs.t ~+$Q`ETQ$+ǐ0j<$p} YE ol-s#s ڳ/⵺ wuÇ#?5|ks \+ߊWTb־X @ʃ ulxsir~Np|-z-/tj?Io"t8l>ߦc7Pzt=fV-WyLLH͕tgH-V r*8_Ğ7 Ks^O)ɕY sP֗CER4 ( FPUe#PGIfOұehIz3^}g򌣌}='JfV8JNu<] U<&J0O$Y3fFtd skVW9SQ#;~%<]eWF=q6 MڪitCuX=zYId ,RKj6IUB1gs" D͕'?"H 39jV3Ef79 _7)7.f43Mp!܏WRLPn#Vޙx$#"\E+, ;mx~lo~cͥkrg9{r{ל?6ledL7sGyP,~ŲF/ mZhXgJֶhz杩|jN k\uxGOZBSkT`_/}*R5l}Ao*n2#~ݾ& |K.\¿}CS9k9ӌդ];ⷆ>(^`bHYO*}uE~*x/:5MRMO≾We_o -}m:V-$[J}&3UTv²F}E7t_뱡w#v#dV3tInGJ1J|Adg9O5ו"!POaxPpZ%Mf>Ewi:*cB`)2}ɓC\PGvoch8e+x<Kۼ\W9(ԕ/mq<ؿ }7c-?ϊ򯈟g'-MwmyTtG !Ὴ>\{ռ?3e8aߥshg4MEgҧ8aNjmhRЌ?3j6O ҺV]uʹ4RJ`˜nu]1m|}<8o^ց: NbQ wFjZu9b]6)uv#Y<3JX+K\}HZ<~iC)a<k 'd,CʵG$H<]>B*RgS^Gjs:ʻdQ$g\%o@0Ҷ(hʰ6>ձf7̄m⻌F*{a`SzU;FbUz ݠ|8S& qȦb:XG:eC[d̄?x=CКֶ ca)j\mI0#[<)_2rTh"rQگ^8/j1=e%߸[(%Qz@:}WVos HثqWmݩ0.Ue'•ai~zW+ۮ[=66l=i3Exszm5&Rѵuwqo ~>mGN.2CȮ?Ǐ|ށ~fӝ'A7{ pUçt:W.W|grTڪHpNS7㵤pN/JpsaKGziٝ)7RPÃs97ɺQ @k!oP{Q;3TI:0e-MKPtr/A,GkK ^MCO?͖_ޠў4^ E{AG gOo{׊Yj#% 3+_!<պkOͫno:`dm+Đ>BvH&C?)O׊u=sXw.+]#xǵqO!t.?pmfEᏠݞūn!$n |>#-k8{oҍs|=Kii <.;uSGcIŠM3kL?/^%I0(``F:wV@ēdl˨ܽHi:X@>xW.^d&AĖ۪:x7=<S&t@HM"ʞ= &== iKgБ㑑Iuk|#QB6 4Qgׯ~|D|w̽LU({{]1bZŬ7q~)ST{q%b9A?*8ZrN.1Y,κj`Tjjy`NҬϩInxڪr8IDAޖ$vJ;wD `B:qKiuqPD9vZt~d 9.:S eBЁ] *0Pv?CO8cqiWˑ1MN%q) K:+ڇd:cR'rE(XI 7}u_rX4ֆG@![ HŠdYxQj_]TI- ރC-At(*s)쁇Ζܱ3[|uhKg V$^z`2daЊ @ٻiF W~>9?տ\v5@a85Q]Ȏlè>sG[r($wNp>xޮuJaȤ%n z{—NѦyJe' :efs٫-|~% {og?Q]ޑ|^'jP}GZi଑ qUl50Oxe6;=֎6\0 2 )LGT4@"xfgFl&b`,_v#ߵpwv*:7F^kEMB )m29c=u5K"Go- B=Sq]ZdG JϓC|]nh1`vH3dzRՌ"(I{J2{W23UMvM6]~)Ik?6nJ" {#ޟJj7VBzkV9lрU5ucX膜}AffRFw :K|yضүn gq+an2~_)jQ yK( 9^,gaq a+Kֿ 9I:^~&~5 qˢ?Н̐;|)%}+>Shxz?-Ü|M$n=ts?|Bv~զN`\C1ۿ{iV\[L*As]4Xj6Lx~Dr+$2ھ<7ğy<p?qZpUNtXFOGzoNa,ҾKDݘގ?w_>'yr1g}ڰ^Zx!k>wi2W9WxZ^ {hd_!Wֶz+iVdnYuK:Fi&YT|t9&ϒ崽 *ѹ7?{OwO:7f[<ѓգ/~x:ͺkzT2yqdٿQ\~_~nł)}CO?Z%]Oi?SnwF}>ʾe4O!/AgWq/3\o}f݅oλiZ buS&~;g*Sэo;[ÍcƦ%ı? {M$&9S5x:q yb&dӋG(SY"7G XC^y%ᐐaS~kڣ*Il_ěhR*2B {ហqA%炥z n&QPM<rs_1xNiea-W?_GhHڑ^e-\{~5QVNڒ޺R7RZ#S\bgƝDh!Emjbg۞y. QlF;ՅOOz2zw6 "ѷ }ǨL>,w#Ԣ6\@Sn]~|H5j ġ(ÌX_-7;_]c*[l}s=3de=O-$LCkAmoV#d8`=~mMh;BH'a3ڲJ$r)z0nAh-C|e;]R,g凢<ii3k:+eHV;zzRkiOky ̼+Wy >v V#d0OC-n64ְ Ys,ʃj{ʽW4M}3FFF?3?:=0j:R6SP0{kƚk>Ķ0ܯ`7cPjCE 814wz N{Α;]zQn-'\ޠ[I*\&#|wh4Wg%0Z_zf=7,Isr4vgc1A(]pkT>biSҴa.E<'e-#7N -< nb36pOilפjI[&u5'Toni*OY^X[ 4Yw~MA(iGtB(j vFʼ2YiծI ?[PʤzSemrk×/+OdvT4s6;iTiU #&7ac#+K+8ӚyoK]jj׾[C!Q Ny9.֭h7` 8`sֺi;{ޥC6= 9ڼu/rk`а=21VׂVM/Z,dBxR^kq *][9܏hIqZ7)*#<O/N(wZF==?YZ^Y.P*8?qk.c' 7S1F[[5,RZXV;UqPy @Hx=րҭzxĻltWsZ=OsZ}?RC$J,Y~գSdd$Zu+&>s~I|ȁ#%N\#t'f,lSdnQ=LN`q\4K!$&J]s鍮==)mn|N73manW=Ma>Sd=}VDIo60܂;ҝ%6[iVv >YCX%AWֽ@Ę]vuhj 楥ʣqRږf3uSo!7ʸ*sp!%׷أѮ|ƥlp<:g붃Kc+kvspwCַPf?{w+t)wC!M;Q`U9$SP·tK`*J:oMPѕJܾwqSLwk, wI"ZE*9q,'ʵՎ:xldP-wwve͑rwo] p  sʉnd;bWP\tFn llu4m3'=OҭDV%Ȥ hcX~^=<7%9 $:Wugֳh hZ z& N X#n~|yc>{qguAso#E,mN?K˸㶒3b{W7KO|Sk|8"o$;zU j\-p[q+:[=y C jx=d1W/a[ ~ҴKN"c\z}*Wwq-)GkٔEEPEPYz߇5؀Jʣ8eZSNڡ5}8ռ9y[XW*Ȭ1F!c>ƽhF"_hMm(^ZK'>-%3,G^AW\}PNH~U&Fs}jF#h_܌>ѣ^ņjl|}+=%c+هV-'>#S-|\ިf$w3ڪj6ofGA#0^8cq׊-rA.Q-o!,U :Mn^@ZϽzT^xoOu_24?_¹g6L1MAnQOA WD!WPF# ҊZ:+>9xOWb ׼+k'q*Q޺iG<_X\Sp$r;a*yگjE֋pbM9 =H]]FBx*Tޢd#h VIEx{lWEVɰ'q_xt/V4*PG/K;Q.⺳йWSZhhZP+BTKYWTk홨n_HQr:_ux⎍:+Y]ѸdqW:r$wq:b9B;k%fhW|g Nb# `*qQnAGQ@މ>K@]',ju2 mp[h{3Kw(i Ցye<Ѯg /q\R+ g_z[?|Ltwv,nz>3ׇxNƽsZ&mnOxt9JPT"fI˘oWM?"i!V/S\rxԕуM(N ն0 >)Dg@#҃֏~QCAsu{mM>Sspj䶩sV(k;.%^?ҵ=5m,4^bt6u0u`,٢d\έɭ VT{} v꼑$Қxt˶~uZ+d߸))4 H[6HwK J;){kIW?Ҡ6|98DZΆ{WVޞ2Aw:VY$mkuc8l۹$q_^ZZ ɉtG>ԝJCOa:jKSXͣM|wŨi7jVRXX0{cX2^xrImֿ'~,m0A&]e##ӏ=iPV.M;s!zW:n\fz$ ߥ_M;|\*xeP¹CNʹ*á{V^55ͧRS,~ u#x>tm.Oo|v>¾3%Vq(!|E4ʮx ֵqyjsK'}ĕ9> {¹W>IJɦjM&^с¾0NHwW½ⶒ-uXLWqmg TdMuE|G|qh^Kg?0޺~aZ3%ƚ$Ůj {bk诅lmo ém\,OCDmV_FzpzViueMc2Akd6x4ҳ,muq$2r8xۆCEj[%ggӷy){it򗃙퓤_Qֿ/Z^2_܏Ci۰z7n~fO^Z,retg;[DZ"qwmۇIaʰ= Oj`ax?a:jzCHK,qv^2I ğ~"SyXrYWO=?C_x5\/o^m'Ėm{Ȱ1$nC i:2efH;@V9zo=߳E*-as.;q^_!f^d.X dMR0RA6d#ڠq4L!GIbyqZc(ǡ4OY\Jo~mkF& tLEw{k}=1C~5<,kt=STOڭja$p$RA;YVV81+\ӵ&GnI'w_j{Z,d0i-,S Ƿ{fѵm2]bԐIE7 ==x6a'WF(r"3HE5 4,>4Ǫ  Ě6afc[0@Y:̟ljmɯxA. 2C.BO1t?1B]K÷1y֎@zV2Fn\ *tqj0VOCڴGrf'rIѫM\;U+u<;UX%\Epw2Zin;֨kF#=T2 #+`E 9^i]$GGҘ${ Ʉve]OAwk'ٯWʽمEPO]tUnټr&amAN$VnëBFCX~[]G3Z7A:O B2Kp 6#m$1}JI(zt58V<=Gǥyб>ӟ29$ Zu$+#9ǭndgȤ9s֟m/ɳww#wjı ~ Op˘$qO}'jW1Fr$cTԬ3#:WQJ1 <; 6W^M ȽчpzXN4OxIȵ>Pw I8xZ$2,)Au#zZӯ/)M2F Zz?ǐݏԞ>W2mzm:S/ 6:_ _6ybFFݍ~x/Я7@'_fS؃b+-Ktk2@δ$~EuSe_ 1B6w<#_NE/mY? {n+t}u'iLL#e1>QZ5ufJ}Q~*^̭LLU/(I2p뜞 k[; }FUNv0ס-E{yjŐ ^ 2p?á=+wGZlBJ4g=g#:[);sg?":W'S&SKom/1QӺvF'/ox=X4?bwEGQʟU<~6cv|\?Ol{K宬mob8aץCulm;y̧!!ӚC%ugMrʨZ5~ojZ,KnU]z{}JV=p Gj/_/tJec']?OuE5a?"犾 1^>kf>w _? Mzڕe9x=qZ>1Դh-4_'\[#ycЄzaD_xoxFFXp v>+ξG"ʰYCqBΓGe]1^WS%}CNžP}fV.=QZ~xFDI3EpdL_+~Te:i+}'V8ul#ҡ9h_ʹLW)M_}yF8.?:O^G,gW|Btsl4˟?1J;z#lt\;Vk״"Ss/ u_ۣ)Xskjh`CKГ]{zxt5 ſ2!Xz2*7sgKMtu(T(#o$^\.qӶ{j7wghd MzKӭc#ҫWtr`Wl2)ӵvյ25bE^0#ԥ߄k{)3E+3A5/Ù!O${%\pۿ8xxȹ-J C/g?>#|14Rg!'?AE3[.^iZ[Z')"v aVm-* Fc>JS㯃-~ xFź&ۛhdR>|kHO'*v5McGBTGm=}S5ւx+K= \t$zxE2 r:_~5OHf]= TDHm=A?p)u섚2y+-K4-9:u[=Yo :_ұ4/ 7mkncbH0+ᏃW-OMNOkG,Sy>`_c__xgUtH#6~FkM_KKei紹a:Q.=|91qiٲkW[4WQjn|;ol$sOfJqFhZyW G1k/5[*$Qkhi&1 b)=0I)=@͉ ۗ!ϭ;ڐEk` *Ix5UюawnM#6Z]Ww 光m8@![;SvTyq$x~s"೗? j2 +\\c{g<"ubVL;|஁XּE{VXHcdW_/ |JE+7ˬ3 gWEVտgYؓnK1>f_U"+>ͧXks˧[H/*Li^#đJJ>b9~Gqs<*DR9`ޟ=\@]$x鑥B7^G=9df[^έ4cڽNdn*gq`c#/ѧ[-}-Lv&vߏNZ;إťm&v3'Lg~4})k53Gts*T@EyugTX`v`WeVcU05eQtS`Y$v>JACdLz2nQ%F@<{-:Er\''Z Fd#9UYM&1؄<ܽAwn 9$U"YF69Bp@sokrP'үYY~o.lZ=%zd\>[X=W-my>tdԙH-\`mT̡3-6˒_8ܝVG$dz1PeYFÂx5 Ð^3xl$u >0F_M.g`#}k!O`˖+^>B_r>V\VB@<m8k`*/q@iG+߼Az+Vq\pq[,m&LJϸE2{0(c+N9P1Je}x-T#[% i_V|)$N䞘ǭh t#(ޞLS8X9TfzU)4q(=k܍x ڲ1 ܀Q]FuH+"r+t0Ξ\~/h&9,EMFvG]D֑A4Crj{)fK+NyqT5-F2(ѨW$ s"KVm4N斟4w*2H\r7uo6I|ȾK~Rp_XZ+xu<&> >DfR]M;mRK7E$?pJO,H^jI7.y]m/\ݔ)XvmTU+5yE㻄2WV'tDj®ޫ֭^:.m/aM'C6bBVTᅳ4e.`(NY+slqn5REU\`5[Z[b%7$:U&x"6Y'pͺi:( ܷ%$#oU% -s 4thA?yͅ۹5ʄXsҟᅵZ_6#a9M*[>xh rpG|o0|YVŖaXp*|?_~? ~)zk% #_jʟqvM]j~[QEQ@Q@Q@A{i TOEq{}O{-wlAKkqmou5j g}_Do@w^eWΗ۝.X἗7?oqQ!>w%mcF<)6d{ zy!g]E|M"}2J&>4Vŵ20p~4;K-ޥnF6·W =(&|S/5Ztϗ/ގA8"Ky$3׾ۯ'v%y;nO};?g/ϯ|4We[H@g6|+rʓ'RWqPxj RKXL ݠ:{ mb&)$R!VR;y]eܒWЎd0ukEζ'N4"Y6kІlC!G ַcgҳnZv;S13gJ9hwc%̲#Bں W_x~[PI.7ofV 2utWϷ?vE ʜl#=QrnmUnaGQEjFD\a(\*r0j99?Jع |VdW2En9LYwcV6${fFN t#֡hLnY2=FzҔhK.~>9{s+drJX{FĤgԒD0lJ{Q.2B:jZ*YjqΘVO=xmFI6Ok 08#nW[KYث9M=b_rZjyO$F+A\ez-2[f)w>?m<}f|7YuD,IxTw,;:'md煮@e0zgG/'Z\iZ⹁:7?^4?׎z]3S''Hdo W HY#s=c?}0HЎƸ[G}t/Xu7YWxA`x cgbq%w C!ޑ?i#=r:_tae2bf_ӯE>OOA3o=⯀z^[ )1Lʽڏ)s%{QYUwѝ c5Wv)I C#؃_5|Cu?]Iw%ы,] w}3ҾhVAX9:w8go[xZ_*3%Xkѫr y_ozOW]kڢ_l _^G{ml̖P;GqMkF{nxᆕBMu/]WpȲF*r@ F|+泹}Bz#r+>=ͳW2K6GPA⼋ ,+4!#.62Aׯ|m|OjY 5 P3/}~_ʼpp9ԕцƌ&KB'$Nk;hn0Fyn[nS=jdp\0>EylI=:h,."o $?2*>A.yԆS]Vڽ"Ҥrޅv9O{p "V׮S'F|J\uKo\Jkyh7 &\akXOtys# P=IM|Q{œjjR+ی,m1ٓWA5߆*\S{w>|)=nbQBV:s%VƱw>`hE!D1Pvt}TO+脑\~_Z=j> 7fGC~J1zhϤ_ fӸ Eez;hϿYڑY Dz+ XolgK9:IeX֒NH4M43Zִ"&:{ 3w 5h$2[#(܁d:͸\08t̳a6@Ey¿f2ba#UnYK48),.`Z@iKooZ42(6Wṵ1>+EͣKmJ1\FaxZ\F&- 9`hh\mdqGq^"L'wy(eC*=pvco/P>A|9]Dwh7̵dd}؟^BZY;s_Z֗1LSXQYOn)t h^q]4݌mKh/s27vuz^i<@0ǹ5#I$~R!|=(h cn0OX~;F~- p#E¹vlw_>$_ ^K MxRA3sA"2kу9^-شwdv>gz>|}F5/ ]6щ?Þ{ǥjP y^ ޠ,2 =)ǣ*.[+\E㿇 K8f6 AW-րdF^*tZ+<]F  E&ƺi7$Ex*+O~N ̃Y^vtoM+pWg9Ul}k^o}o,2JÅ>> XRq_YN/tѶ~bv>DΟ~p۲|=5EXpHd+;ڜ^+kYwuϭQti4M g1r9zVҟ,[Qmv?Լ/:nw4sȣ8[_[ xwMD*s b-ǠQm.7^mŅ;wc-$C#<+#YI;Rt1t'&\29euZoeqPڜsѹ͐s*"yrG$##Pj.WrZG~"ִ kBXiS4* W*9מ?Mqkm'];Q_' KkhD+庲`ZO?(4X͏9b ;tq\Ir[G7q1^}+#WG|?kV'ϳpsÏj[t/m'8AELIoNBM;wmi, <HR3böק@K@7[\)_t[֝_(̷3}_#Uxf~Oh߾?CMxCo',r,p\v+ͼ;;7,FGc"t(7ieuğ̼waYf]OֲOC9z~*_J#pkCF'ඟLĀlx]Q1nا}?Reh?h`3=q#!3Þ0W7irC*Sm `kG%s31&'*=ic_:fZHfY6#!_Ns2 {L7+ }03 ^x${Ӗ=WÐw5wv5oDkKgGIBOECmo%<Fd(nާ6IXֻ};KE,mrryY5!d_'S{wOS'մXCZ0nUdO|*X]6'kiYɽ+;[_/3}㻝O}E9fϳHW: 0'9⹋KYlOU4 P_CWe 2 2kbfkg[aۊ|?kɁ=AԗS7j۴GpIh,iTrÓQ Ӕ9S>rϽ14A&7?\iSP6qDfʡ8+T%&1tZu7~e9K7CqU5kcu >|e}C`׾EҶ>W]7bc@Ҽdhdx(ys4[sn?*Q}%芫eG 95sҖ9||Ҧ?i^O_TN\l)[J(̼K{l ^dc^OZn6xCedݺfiӼMC+"aYHI[*`zȳӤ@Ppx5buI~"u[+lֺ}c;GR1&3zw:+67"pAX<$ture ,܇;7m1!rƬcm="NU 6O901\5hidp:fRjs7vwlŕr9$Pjpam8QYmyWj~VMhj!/-#{0c#,w*V#?x{~nL]mnT)$[?*L'Pz-&&RtpW*nyG9V[pbT,rpDp23z2x@9Tbvz `o q#lg=mk:leQ#JJ co-wv)PȤ)+2wTr\+9F`IMIiVxrH'QUݡӨ7V=Y{bFEuH<л < ~xNu -$KWmVpnx1Hw5Tbϸ?Rr؄dck,WmRyQWY9aUVoţ`wlzWe{+j3!V'<{d5wneҝr ^4e;YXOٹ_B95i^hW?U$Mpx=7iVtcsn%{΁65;NZ'?57mV(uCYv-]4Y\?ȁ?[&:jϢjr4 k>tOhʱ,_:+`oKὛOAuo"L)Ve$fʿ jo2a<ɉJRHs  .xASc޲w?>hY>/>a ~WzדWBjJ膬Mc\$tU^"`·Y\an`z_suB[+n-YuBοF:vl%=Qo/a A:_~Sk~0CB6xK~V/*+CoBOu}sTRe{a8ɚFэN(DQEQEQEQExI ]z8?]qwBi5fxׇ-1eWRDڕ넷Fq׹[:jJLޭ*+.>U;g~u$~#4RUfӋxᩭ_mń&@1MKFݿp\Q?Q^,Ibs2GWL+8#tVT<h:=Ət\)(ᇨ hWG#va[ qKFi>ǥu^>4]BK+ qЊ_ퟤxO4mi߸ǡ>9Ӱ$qXT %MciEpd09pîE~_ ^)Y"a׃ȯ<ZX+[w G$?t?~hZӵ__ļGj#ZѼOk&Rx 'ˑIhg_U=ZTs-ag|mX&\[\&DN_4uIV/'e>D'Cq񀒂)Y-\}ǥ{,Sh rSP)(7|Gu_[/mp?8/^?;ƻa-ҭ)ƩiA ?}kg}-Z턚CR;/=6xۼgoO/"$ m'kWn3{5<[l<%r'\ʸ^_$.kx)B zQf9%.HنFO̵1ӱ m5PO85AÂ;?ʛbNǫXv aaʲuCu^i,㕮O$Iѷh~)aB:X.8I-*8犵c&8MCL@\c 35jN)tg+XHQ/͆K_1Vm.|ތJmaSb7x*:D#G'ޙ3[ێ1J:,X`ҏ4/Q-8lu5<3֦R<`XtV(e?Fr;I4jOJ>994dФkvqQx sU#Qd FCLe =kVL֛1 E@(ٿD7H ?k[},P Ȝ$zsZV#(ea՜rԬXb 4ڿ fzf a_ծS^< X?|7W&M8*J勜d\~x/n4SJHé`Er8rj~MDii<"/L:hgx?2`x,?Ϳ!EBIfLBnJħܓg'XYğ 51ujrA(e<_zrCA*:H*/ęo.u[N֣d˷{8=QN5'jg|cZ0#/7P׽iB{x.$"c84tI 1) Aхdmf͜WV=+G P&zV{ױ,R+YC(,|2O7׭}n%G]~*>R 2nw@oh1CxvL:0F_cpr:_|t|Sz 2ew2 G|OFboSN  ~uxAԕnrGQX#.^n]#p{J}5pFx>D~o_ʛ}l9CjND\R20jm}3XZ=vZ,ی{#3Z6lVtbdzNqzM$rR\}Nجeܮѹ(4ki 1> >ѧ$|/9>0Cn1Q' `GAC#~|`+\ܴȒBW>WmC^#񆚩ۼt0c͹rJ+kg(݉|Y~QY; NEb@8aqY~Im:H6xX)B xHn 3HY#JޛY5MS[CXL12f'. } |u|IZY/] -FD7^JھƳu>j6k? Ҷf1ǸkQD 91Ht64bߺhY8cX| SDWs9 FyOc_^7mτuI#h켌oFҾ|8.T -KtV=G)KCɺIP8?^tЩǙžcҵtktG}~:nͣoDFO³T>RrJv9=;L[.L0= ,7ǂ5hi'׺KlnlksθִS _T2]hәT) 㧀|n{F(fTXױcR3sPMWqIi[E"u>_ke3S8*ǵp>Bwmԥ&GEc׶*q6Kj(JqF[z׸.[]'}Gx\B![mV | k̚vD'p{CXѹ#9Uz $kEׇ!Cz>gV z'{5/5·+f>V{*éZ&.wPg}GZWka3/kZƻ ClIonۗ"kִ_xI}'[ vCS^y`ڟk/"wQ G9O12u>сVhQqRyy緽}+WV z\#GQ𧅒Yb 27QkwOi\iʔ!YagQQXRۉ41KCԼyFZk2zC]퟈EI}dbY?>${k;5#+Ϫ֍^'UkxUT6g2#fTV7̆ж{ xNh"x iv1-u;8װƺ]6v\aq\%`eKlHSa]5[1)c@2Kk vP>oFt߇!w #Ҽ1xkF}{dAm##J㢝] Νh݇<`o!m#x<-Mj[_,c?u1ڻ OSj:_Q$vlƸPdbpN'5|]nS5gFo ^x) 7nUv/rH\凯^ {7ccrX)U 5g߅>eӡlyxf.̬0Fv Y< M×cYc&3)Y8T>m۔K[M8Ay\G\`u t !p}ݬnƮDV9'ה:3whdX-F's'zkH@a8*;ݒ]W*rq #d)GJ6̌'ƴeOqS=ˤ n3Aexؠ#M7+&8Ϧk[|֖*8T(7+$XU'R饉$^޸ .n[t"mʷ] 30BhFFq5aڰMV;NOfOλOֺ1z4 |Ӟrdunl?!#]7;Ӥ^[2!0nDaK"zsH7)9" =jE:. [ITjсa?٥Wٞ9WAlLmڹ3F9=6a"oA0V)bHG!sҸ7#VQ xWݒXppzaUCd!;'`9:Ʀ.j裦\Gym%˄-)JkHfrB:IĽBЎlƠc=]V AsPRU 2c}+rX|eI*s}?³hִQUkc-SHtO#Dn-ɹ2wTfǩF˄#p3Iy re <פx+Z_@R cq,VZ׉N+KLoF ?Q\NJ~ZA ּ2HGz@C\'o&No&Wx} }~񕼞LfvC?Vmd੫CE sZʾU@;OqFtRLIGPZG1g<&g+"ޠK?.IȮj]* T;mP~c>Ց-3+ߚkqٴWk.Y`gaV^#h_ %qts }ܯ6tHdoqRAߩG2}$.*U⫽wVCm7LsC_*be{ǿ5YuyimllrTxzQS%+=Ni4+1 ܕ}xwbJg+5_oYܖMsM;1I:d__VWP>mİIֳRC|3kR4ibe1##5|p}%,'cKdrtzfT`-O=S z*Ğ44rOȞQ*;Yߕ!4#xE(JuHOO%xh6(x +'ZС׮k10P?<֝ӶM'ZOMCn~gVhQ@Š(((((((((XW0;\gE0dFh$ak^> E ZmY-(0(((%ӣE])y}Ms:qhV;<5k $1AჂASǾ+[҅FP.s^Zgҡ۱FPqԒYj|lq0kGr;TN9S銴Oz92;~eazֿ|e8֢|5M\xa^=c: >ƟmpLiy4ƛZ?>Cmx5KvO޾գX:ʺ+|p+۾~)C,uxqp G3sҼʸ[k^H_~yyO%yrB}z^0ʟҼѝ]k4D tʝҍ1GINF2֒?G_#֞k'~Qd-߰d%d20O Z?/̟ʲ|S]T9ytSOC[i#'bv>mB!'V|E+S'Z1z2a4j~$X%Ko:d?Cҽ#h9% csT#RL| :>| rB4,Z:[xWH1ӏ~4餏.PÐz/,H}+WS:m8z:W 2eτu={OQ8W _Z j!֓(o~W G$5r|Tk#Dsݍt~$[kMg&xg_t#XCaЬF:͝'Ď˙ac 1^[$, oNG7Z{Vñ1ϥg(_TRsּ*b&Hy#kc{C[3E4L'3W\E$M{ԩI}QUE@-{~5.E ͸sZ%>xLp3}*Zm#:[*0pzzw|Ia;mẀ"=Tjkf'>! 5N͢~F׊K9"̪捽ywe Sĭ>~X$/ sUgy#p횝ܩ[I{Ht!v4BG_ΩKCJԞ% b$0Uv [<"Er Dj#g?_-OnxwN)OgZܮU\<ⴎ3T Drz.4ܕ;QiG!.OO^5͹#Q= yFC)?ұF˺VWbG+і-χ!fӁEE|l1#oCVՕ#p~YzIZHZT~7<7☖06gYD}G?[UKz,._2C ]{~"/8iIE=GJ~<og\P<|Uh.|QoS}5q WWU?|?Y&]ZC/^x `?7%F̹Tmo@N1Jּ/l粺 :t *G xcZyVi1M7O ј3$jqfF2#5rZIEқV@,r>t5}@稪mkfaSUW O%9x˯bT:zox&H)SgGFFM:Ua ݧU"!\OөI,t\ahdw'- Ə| d[[dŎLKD=3:-,H%k|k=/mfʊҪcqygSoqO !==ua8?d~\@+ b&"A;v䷧5i5`9<7޺kIͤ.Z6' Ji46Up;׻&^j I'$G;6:eOS_?ռ y< ޹f9^ )6 O M>fZ"IP~Y"F$nA]ׄOgK| ׬[="p+8Ϙ0@b`qWVQEt{L$VG<} ȏֺdt,W [00H*?rFyGj=GJ͔h#JDøvbD[_JRVц+GEBzMZ2H#3RcVA#J]?^\hlhAGO&uOZ xGo~ZxQ΢ ?Ҷ9 w~ zWqл\?f_h2t9DmtBѝ^Ygu(FTO^7t6pt1f"ePN մ49-.}3]_ßkLnwm $O#r5_ >>^,Kaѵ~-ev>c Ea?%fPqӑمxf[|2ԡ[涕9&Ly)})⯅v_M=` +isߴ/iF i1rݾ5}a_x(e&P#L'L$h]G,nom9cWk{=?p v5ӲCFHIzz~R60E*}i֭E (dW>;N}hrZdKG?BM:d ctWj<VV%{XlDDMhS\$ Ϩ+,g:/NgSO8x 2XVa"с2g«6@5o q-!S:k/Xx\:tb >/gy6ݖ '$c5K~oj\h2>39W<󯉾5lEJL.zZ9{jrd ~f/|=8qX+|s,:2$R:.ac,2 jfr'EU#51-<;kʶqK(- л]%ZVydWlʅ:ogk^c/yCN7WE{o<(A8+l~Ƕj5ojzFr܉Fè ~ͱr^x@+-yi en1J]c^+f딸*A$#9tՅfeCо{kyq`vki)7>gLO>X$ qC {?Ïom:>ցEճIc{ɣD+t|ПjEּ-6i59 BlgW_6c(TBǮ0jXt,) <`R36vZ91" =+WD|B2Xe1W~?4#G6oe[!N OBo\imU8 kMRZjqn LUi~!kz@(l-s!g70)Nvv7KurݟC?sg $ٕ<`tV]m2y_@Z.RW: xuZI;t*{,2Nr*U@Rs֬R GCfebhG}sZݺE*͎_ZRWW;|jo&Ϩ]DKI Jq^M^ '$YN}x\w,yЏU(>2fxu[=M[PJ`E0+H-E"%zIB|xg,(щ=F8Rtbnq@zXw5 z:uwncOrGXRs鎕beH};{-'vF v݇Cumn1iIʾohhWj' +*dˆ9-d"Sk+X"D >.̖m`g1㵶F|O#9SOjZpU,GUqV'=Azhs^$~z&qVV<06?u屾 &^Y<.U;U޵37}J6Hïp{lLRã)SI]6 ץk\KɌ7L W,cK#*j[E P`* h m?Qmِ! pGl<|9ka$qcZ5H+B1{Yvz]11^ Zm>:4ny r76ĸu%-[*\ 3YTiį Ze,AhҴٿVxBǦS Fܠ{_ gΦ.dnpP'"H[Ǩ+9hR|Vz[HOUs]٤0wT$$zz.S} EDob 'Wqqn I3\浣 ~j۷ cT4B+g>x7Ed8q^gYL<;Y,mmx.#!8*ޢGM/XMVrr Hҹjp>g*MW!#pIc+MCOү%#Jpkk@%,St#?E tƸ?yn{I vуGSKYd1tn+r((((((((((((((((* ͭlsi;7<v[Lm&GaIkéB<Ug˙3]gCq4a*^3Vz[h= _"j A!O|+]rP{RMdDBE cQji Ɠ궱O 2KVVs_?i|;Դ=߼rK5]>ښ2D,&ScЅXmh$C# aEp[QdylMbIy9[S 6gnE2LS5,3Es=˲h{V+# 'KYL֡P,::ҳ\i>(,/?uoO[Ch^uW/1_%x W MZ9"a{_}#Z{|N&#wFIx7DtQLwG 7VJ*=ڴ9YmBFr"V>fwq߿"h 59ۚմ Վryk {~h9Kd5 1ҝ7C޾-wq6`A)m VЛ̉E}󧏾Ƭllp3XuuBhۅn_Zo<=KA]#p\.#ߌ_.NX+!Kݞ&ǀjW:KW2BOҥxSoCWソ;<9! wȍ )֧K+sޘ\ƣbAf[ȬZwGYT#݇rN>Y{0+KO{YXbjZiZeu KWm v9dUmӎzg῏ѭŜIxeVAG( \s_32Oc^k_xb_A۹<7~¿z?Ļ5nv\dа kw P\ZcZH \tyGs>j1%S܎ǵC֥k!2n WCfb{W|?3㴾?,ZG}OA^mv#95N.49+=X!\t>&HX<`OF%ܻ/ԫ /Pk -etY/F_RU j*5= VUXK/J0ϵ;zža%Ŵw,sInF*H TÂ0AA`uK_ sn}Aȫ""#x־忙LBAf U3k2E/339`ǒHƺ|Or*8~.\p_*׸t~{u~ڄvkjma?4f:]O.m+>1_ iI6NAfѿl}{(H˃!TQ^aϏ(W{wbIbRB:塌7_:$7EHca^u-"d9/lL&ܢ.aDOQWU8,f2w3l^Zw.b8NHJԼewy N9QG1s <u]W٧3mgaָ#>Oڤ3(Rw(~UO{quRBߏZݬ\ >WbUA#1QW雛N<ƌ'ҥ"2%0c<qYXbL9WGm';OޏN}*ź@Y9c?OQ^2AӸ'o]H Ihv|͌21>lW% nXr$ lƟtZ[jZ> A(#[ ;If#޿G?ź5wv +A޿<lvr-ouhB26 W ~-|,{w o< WZr0 2~E牾Cڸ>[3p{ye: ➑ j༵#۱İ7ueB|[;sc4N 2yjFVJߺռ9wl2M=Ƭ;R3RxZEi5r1q(ZHG$z7+ukf[{hmx@9[+Y+ fc_|=iDܸw%bDSv?+x+xnCs)Ec]/>{FWΐ&r."BP?6C+GvB?5AxlnL,#FvJ1> c~ x[J5{;:=ؓUXnpA?νK%ݥ(69`_@ҾCo_O5mNH>lQ y㿭JCg_ |QҦQY1?[O :g;XDg-QXTp_O7^ {-#͎e࣎}w^<Hᄷئ|+OmP&xs2}WK37 #f8ּWGgk4,Hl9 \pO4ߎ)BYx佰'nι_l-M+].0Gb9&V:5c u0!jGs'LHV v'u(cbz.;ձ}R %ą@$I'u7[/t1Z)qdZZnfTm>auĬ~H7n#T~jz=eʶ[$5[ ѷU\ogV东"@}zVͧdY"xY[He9]pqZ]HQpjPT3 B+7.tTwfEÎkYkΡ/\[Ten]ϧfO|[go\բ-.8iO<,/" ]1 sqV15Ν6w턇hmѺs__g!8]1q2\&g=!x}ӞAygHu OW~z lj4X51OUGR#}r+&L= Óxk M-sKrzT<?iZƕnwUC68?t{^q/ZV[gHuwMMN[6"^.0Ysw#7R94ֆuJͳa T:y77W&xs OmŬlvFND:ÏJ__|1ͩBwؒZk'<<|oI~!鷏Qyo /⾅ښ-ۃԏ]f9x%Nƚ^xLi̱4'rV^>p}_gf'Ύo2E XiW,Ms^ψoa ]ÃZv^|߳8 INbl{=gޡ[ ȏKџ1:۵p^u  |_$z}kҮRcVva@ɑ㼈g+>/|0oikӕWXr7mub.-GR#:"z@^"x|$_O~+O[+*];Ytrd/p{qБ׊jMk3Ee]SAnIPx<_9|T4_1h$z6ɜ s3KYaiZib@H#H޹]x͎Eg)";V Jx2צy`B?y׏k$G8*kKiDl{r;nR?5RZ wi2e$xc\,MıbuVOlfuC؊u1,,xL7F W<w6m8ʌ{V_>6èȕ\SG\fh@ (Lew@'ymjH͒8и`pFvW8OsBUޤkf-d'#oa V# T\$SUs?-V72RhUȷLUlgI8>}تPڬXn²FwQX*1'Zjȸ@;{շX]O=<0@/\mY$ʓ mi/i2|b{i8V'ƴ6TYd95ddBV(uRg#Pr= L^@ 8ܭ*ud$Hc Ymmu%C_Ixg)'Jg)+@LáiMPVp[#g_B–^hZK.$Is{¤cmOK?lnz;?9##nNua{l0F: b {—eBFUY,>cduK[l;O;+r >MR[DŬ_:蛕QZ>ԡIDw9AtMψ[8 Ρym=ɗZӣ1G5ZJ:fnxYf"6AT{|ƹ0-,xc$ld\f3NMXUؗ~ėH3f4=v2(UƬiQ IIZZkYAG3Nõ 8Uճ{Ï!63j^t Ʌ69U|HtiOI;AkҗhՎvݮķJN82(G+!ѷݓEQVo][Aq- vXVF!@ֹ+,P޲4  KfvuRvv-s3GH/˙ޞWqapЩ^J7~A`ʖm}%~Yv#mt')A#F}9{i{ht$ ~*+_ɤxJ-[\H3B][:?Z撶_/x[uim މuq$yl ,AYU#8*)ax-]8(]a W?fw>#&K 2ec_qH14|EVąQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@P`.w BH_=lvSxoFjq Ҵ*z(9TwqC-H =*m8$'?կ;1k~w ׺tW$ -lY6ާ ?W\FF*θ^u^qRRRHe Un{*SVn0:Xn= i0IY!B9+ÿ%=K7S,w+Qi֓} ՝Ķp:7#VoDgIT=嚶dOKCCLGm+ E{9<"ȡ.Gr8?+ZtI׼8?z(ǽuFc+KpzB;jk>M[s2G=ϳcЩxҼǿX ѿ}"@N'!]mlLIvZC~< ޽Γ,jT޷6S^ҵe>ïч"U;v<''k"i[^ݦ궬4w.ׅz:OY]WCOvKO}sX#ᏌF&l%`/cӃ(j/?gytn5nKnGoǦ+.4{;kXʞHٻ)|lӼFm;5 5˜䉽O kw t_(Ѱ5]j0(ˎ 5;On֬&<ʯiX8I6cq=)M mlKgryQПoz8pѲtzY9(YF}+*@!бWB:zIAcԴI+Fkg֑rCPzW[]JtjUuUubs^W;[[y{qCpT}`tƯI^&{ea5ɷߡ|M"ec/cqkg90;İrgчz.i^&Fcr;ВzF<e0K]г}ٗR|v+oPM/2o:|'Ў?^//q/YSe|Yx%CSkspA̻v>_QڶG"" $3ԬwIS\6.oṯWbcn >JYZ%=K^µ?о*Zk4duH_QmV9CFes;V2ʓnxHRs{V}ۈpv zרmgEvq= =C9S-ٖXFa~vKkŗ]wF-YI_^zQrA$c›})DMTGd|G$Rm`sut_eع=Y\ڴvWr5J$V4G]鸉{";{֜\٭F%bݕ8hW'9n(OI+j wPOlw/篵pzslo&L{Cc޻-!y[:,ofWs dg$Gd[z%'Ļp2޹_xvMABOqǥ}kw xH^KI0K 7˟P[5>,}/lI^i2 YU߁54j+&kiE|$ SH:8:V|s/ZL wECE.F]uєSyc ǣ hs>LuWn$-o'.,X ~ ~z'ūX,tDΰ lg*ЮO;_]YNTL+q\kӼO-ue<?uq  ]HfHب܀pO3_#|^?⺏n0O=z6Kٿ )Bی~Vw6NĘ~xGz!$l +^mDϯ-jEdd99-xokPӡ0F1nڠ$a~&eaojڭamisRڭ7k$CJ^ X6E #/ȯ4|8׾GYǩYZKMJ2bw'gy}▣)g7uPDw7pюHT^9Wt7 x$FGz˷c*b/x+Fot\qv? |i rEt-Vnw58?g:ݴw0.\|6̞H55M0iHbV 'k6k=5;?Kucq'mSF-DczC?τ6g̶o;?O!=׆uɬ/릆O23_ִ>U429>?ڳO^E?yy"3w{LΟ)RCB\ޥmwVkkC#֐uO t4d@ BJ/n=F͌0 q8'v5ZmߐFrԊ괽Gcmbx>l'<{;zU_,Tjr-p ^UMYfҧ ][g>>x;KUNtC} S=Jk[#M1.1z⼓S {0 s ߡ-Y5-IuRP;+)"H2)r0L~5'0RcHއWxM:DMo!Wb:qߑ\?4;"$ڇf`v]?_G:@Դ+㗇/P&:@꧱M[T-Fҵk[+P w׽qOɠ]-Ikg~y_~$i~"};QY6m?e> +&we[+Μ1Z/}rw3o~G^e?YBdc|hˁz,Yg(WSq(0ȄT5ľVR2PE޺YŶ4ٟ) l:|KߎGs#k Kc|pi6E_7.Nt;Xc-_GkY(O 8!^#0*Vw7TȒy>IݐoG<=2ꑐ7,>jĢ)0Z+;,*}>xbohww桫s 7O*3l *ĀZHt+K,? +Ay]/a8@=;KUԘe^k64zLq&h*t֮WWR?1\e2xAheRsJl&_yӧ|-~NRMzUiO?w,ne?u85͖I|%{*acٗ#}k6B_x9{ؗǾ aa\ԩ?++!{/K%ЫPJɹ75]Mo}nvM0M_ĺ$5[ jY yszϿ6Hh^❠>NK}n S؎\w&EkkKEX!'^To`zk$WS'$4W>^kUp|P #acW# l|nB=)Xt$U>mއ?/Ipp?էaxD2/Uoo"V1 rAN}=_qMKy\Zyr ^Eu1= =+6ęv>kOirяzJ4/%Nyq[QZi!zaG8P{iЕxfB=6<ëi_HİK)/<4]2a78=^פ'T| -mYP_PGAa+чEVQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ vorC'&'Zܙr/&K=ջ Â>&A)d~9W yؙ>e:.fE' V86wD%O.x?z2mvJ<^:JFcaT5-6dVGR,; xC2)& ,K6[LⳞV W ҥOe]I!lm'+i44Eds*DCj鬮RH'pZW,i28X<JWn"2*(r \ UXu{\Gr3}&H7OJ"8=)'akKn %_K{UㅣdKF?$Z\nDwVyUqҢtUjC__ cSƫENiI>>?ZKVWag%Q@ZEw*V*FA?~l-6Ŝ>Wv{dT$Xx.2UA\Gx ?m"#e"-NȈb>a+ڨuݯ5QEKGO/&ǟ~EdЊV8 wB[*Uc+̵\|8\eo^oq^?u^L!>X3_X[>=3dj_ =n)Mw.7ɪX*%2yψ_t_$[y1X|1f7ZTtMz{0k]?ĶUJG*x"cF|;kk)'a^+h:UG,o:7R ~j~!$G\W|@7[%sPak)&a:7Oϝ3W=LgIXҷ>$DR`~ӿWMm$32RDFGr0>7o/p'Ѯ۱̺|oWjï'H-ar񷯤C_xw7:Sw;Hƽ_DerIe'ȇ؊7toy?> 7-Z2L!nOc꧑6⋝1!QW+ wÒh>/_<\@{0_6|F$~ m2j& 8IX~Euө,095snk˸y 0`G_S|6H&WNu>q-=u?pk'x?* Z&+ Akn.K=O9~> --GyàF|?=%PmJ֭dʻa؃_~+ksQV>5>3Ut_ %GjU|6~ljC`sUd9}zD[·sJVKq MOC1) GQ#B;M,EʕaTTҥ"9{ֶluhea\]6ʪ zxwṇCQBo2V^E`h"2:WBХ۶ɻo4`krn rZyVb`sU嶷jt p p2sr!۞ލFrn?uHm<^;?ZWk y5*?|~NxNiٲAۅ9zVrJm_i 4 Fx-u!yVCϦkm?2 GՑp1qCx9&;V9s__?-m7⛵]UTGm9=߿ׯJ,D<W#~T秭b6"w]8#59͂]|s+EX]Rɉi{Zt􋈃pTm.`G9+O᭤8z+mf9[/slqg5N ȭ y~q*+RG 3$pxXncTXLQczTt`3cc<^1U/u f,S{VnIӶk4 Ͱ7NmOBޕ2v^cKS7PLR"0ԞhZ|er+k!h͸r?AָmoM%H JRi5}aV>IPFO:ӭ!]˒Oz4mtٸbco_d`JdR]ým4moD}^tמ63g>7֠oWh%{;");†3S?AE3EOʝzsy6uT⽖@rGp>;qˁ38]ZpyZij#Ե)&O)$q?;}s\\u[$B)xk}).-r3cÏKiqai7~] W+ AuMomi#pD`]Ds\szٛƿv?(8?ǍSMaG¾M'Pw<ęKmgI.8YWАyKl׶7ʈ5Y MnrTY2]N"݁\Ɵ9Q\rj{,mSkITyAentP#'sD=G+s|L*uzH$s{{";u9m MxNF,X n? \U+OGl}f-IZHh75A0 Ӡ2{5Ri$$~#8_K>iSٽGzkyx,D{+AԎ6_7On|z\')~[Komﲸb_b35}s柊5wMJltȣ}Hyf~aOnw;Ǚ2g,rzȫhJWHaT=AkVd<]|̲'oM<2O#6߄9=X{/w0ޥs.⺝ᶓRf&)Uj?! dڥp_B| "L]ݺUx{DYl-e`i~%Mѷr?ԣ|)i-5PΨ T18W4f=F.#=[)M|GPjTkq*bgc } kh^&Bw~(H{?@y[wbcN~ )DVv fLp=;V7k2FGLx#xPɏP㷵p5NMݎ?|{ԨFA/`?|ogNX&aK=*nUpSҽӍyNNudž--,!0B+ kԴH$@k5@FNMr=`1-Vz= [)%d8-Ƽc^&cR$R9rC=U%p-5~ @(SV̺,3F{)#-! [ 2q\Y0x5kEo01E7Tk;saR2sk'{%ٛ=*+kt|Ѩ9IjkVo2u`@)YXw; fcAǮ3kJ*/Du7?Eua-:vv%*U9ҡOIvB`8LiXYU(s5q!JcCWEI!,uҜSفϵKmpH]ܾpsPC5$獍!u bO+fh$,yj"aFg)lT¥cM:Z{=WxeKze5+ ҎNGh O5v:V\mpd?0*L/IF+i7XOQVbZ)% J4`"H!p1QX`%ʠ$>ئئ7Q'si֞L@W=lR=J߁uؙ#&Zǽr^7oyO~U/w+ucܑU,>g h.a3q=U%/r #&oTkY2ppqү@ir~Oj_g/v~c,dQWЕ{ *jΚ>7Ui  sUo8pt8 dV{^ژ#XtXkTa[ +*\$w H|Sɒ԰{5Ru ʼc֙]doAN֫v@Hc߷P{+52<0!3ʮW#{QlRGH GT4 >V#qX^Re-MvuiaF>Oqj}Q y'ˌu9^w(*43_[eY<R+\QQ+VHn1LG\-$Ic?Ľ}ὧŏd3@Jx|75$Msu,-գ/maJA%fbڴ9+}m^0k5|V[ԴE$ o<^AqX:5{1c <[RJ9$Imu75KH T+ݎ QXzZЄs7i8H+ ZZfC3RpoPR6;We,9֯F4j#ɳs2Ik. 6Qm#Za`FQ_QRCЂI\UFw4Ijh^Fh"hQQ>|Dq:Mt?:~lj,0qNjQ;Oq'~s^io.[jp`C<:p~b>x<|lfo/{+_?t$s]NL痏U_J'Pk9wVڤ1)-}fV݅Zxa{.PC?}-Ļ)#֢B$_?qGL~(| mTjKf :hy<9kwḢWy'KFQ vލIbH]_[FYA澚pOrb=wF%~W3Y#Pt`),2F+|9hmJc1oZ~|W=6ė>O)afV-X稢Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@5[l&x>y}ͤR$C^\Hu=ߞO^vs#bJ_9d%[.Oh;#m篨Zǜ~ة; Sk, ᩤdrLM;~ ꤷ2P!x?g(eΛ]k~=~dx־Csm tqEyS32SWGm]cWqi0̴vnʓ8?5ۑo[,rZ7vPqo*xPЃ^suSwᗒH'tScG_M Mor`TWk=KGM.L>އzZ6G1q^F׆UFVzSN$NJmE'z5*C} E4i,N0Gִ_iiEEc}W}?kUJ>d(\z~i46c Ïjsš5?60=X :zhFcMJs< -H9q)^o}iGFMxn#tՓPboZ['/4/=_L3mg@;?&H@=>QҔ6ߴC94[MO#fin%%f~QjZEƕ{=弖9I#menL)_qE>6G+6m5E=_ǟ 5߇Zk{BI"9LRUnνZucU[883s?C96=6OZgve^G<Һ JRHSS*]b8ϣ:/|0<91ȋ:޳4 k\qz0j&+*C޳|O]+WlRV4G෈*PMiAҾIƖik+8kGj Ox5rBb9<C񅆩4[ZM3Q#ު?Yԧ̮\eϷ!9~* qͽxSC_|S7|ZpMoO:o+޴[Ŵ#Y{W /!_?z։~>/W)*!+JtQOSK[PK.h\Bs^ͤ5avx?zϔO93^euu9\lNfV9 ;Vj zWcwkHXזBNnikM4zpE^ҵt IJw桌4rqgIٞ64:IK5e 0kcݱ͏=3^wdJJս^L~*ZWOYѾ+Gg`^i@ &"o)`>m Er;{6 y#=+šԖYO8C[TiGnIty`G7zTACW47:D~(~!ѶڵuX~c:Ţjmͪ;!*s?Z.UrS5tOA/-z2AYMu{0X\5NYler&V JВy|o>=do J7 s'VvAbHmкrKvy][@#A}߇u yPGqJ`2xz&f$s׹ Ljw!0A伬*qܑ֭Q|@u k66|z( rFx&E:V-xr$R8 ι;\tc{i*ȷGHr_ƨC g"(?WCali3 qXҨV!eq;ub~p2k ˦MCدy>$Ni(Q ap> 4#[fo7t_9vwn{5֐WkG:'m͎_池Mɸ|ꇦ?_r yW<[v".MIY^N$8']uXRMhF@ Wcdٵb:sjBmΕ"^>A9^oC_}" RC޹`^e>-(uk3\0P}wOЧ/6 =X5sIf*Q]Jz#nӑ~ -5[f ~/6-:HdaWJ23jib/xi77Ҹ ǥjwǗ'QzRE#?g"W)?}kӍMFaAz xOԣ$4R ?PkE"5u Ś#~'Ⱥ$<'7#;B?Ѥotw?k^\my[!P߸L( ~)KW➈l5l|]yӡVN=.y&ؤra`޵o^;:Xd(>J־k`T)zM0e3@i[Gf$ @95+.ŝ.YT0ݎsZM$_Zt&cCǸah&kb8 W+%_OGEMF2R[]>MgQe 5'Ȓ8ʾ d I4߶~s7Eo.~1+w|Ukkqf%*"JҾM4/.c/vbXX|рC6g޾Qԡg2fij}{tXsq2T2@f@Tۺ3ֽ+gGc d0rTpUb|F:sҡՑyO4`{ar.4@b >\}zEcbhӛLeAmSLٛ*>[wo emNMe< 6/m5`9HUFD2`WEi7`fCNhO8Zb&̄ ʽ 2yVSmYF1d~}%4[I1&KLx= w6p2ָ5T7uu Ұ V }S)"yzSNAaTؖbha1_Ҫqjm\OܲnT[׭!^ocԎHn\aъ==AF*2rk۞7.2oR3R0؁Y9@?yDC&ޟw;r秸.-S6>zk t9?_I+n;UeXex[Iv7yȫoq<7\Ss89PHpyʱ `cyfN@O8.ZR+< NL D}@Jg1CTzI2~ }]mUfI&Yb;uk+k74=,ex'ոJ}"i2Ƶ"ޠGX=8_,2Yr`fYWSKZbaӞҽ>d~Wϡ* 6T@vΒmxG#~K/kPH2D0=ϵq r wvO.EEʰnEbV Kb3 KBOл].vdctDޟ@EFq# IuhPnG^ˢPݬWq7.SQwVڌ9Jۊv&yc|{n]L' s85wF;,Y-gnsjzn&#Kp X3ϡz;wrՇextFcgt#,|nR<֬PiP#VܫUjCZFhSH%n-f9ʒ( ZOaӿS󪩸-Szzw$de@ U.Zr@`qڤ8 H:u(9_JV4G\G*xgQ-g#ǖz|ԿlhMk_L|A @XFd`W#E}=~ 4Q>\ eB@?an|[huBO]،=qWsY5̦cs ‘08 "ZG{?xJ k500r ?ZCXbt=MLaMD}ԟkI_#c^NSk6 sN>NvCصm#W3cQMBϥz? 8 П3wGq@}GB: vR@~in5JVdSE0}j$d*?#F 2T}I9 `7qW{;1o1o,R$! n2IeSj Im1*A?Ȋm1eӞlMw>\ $m<6Y~\f^$t;e#].4rJ!AՓdZURanնH`d aӎh(R^HEA~+Gb<48$6 m:qMX֭m>T2D`n-4Z =!lpF@p <*pSgzV|UQ?v)a7bzZ,pfp(:53ojV88[־n&3ݳ2 ÏǸY~sͷfSt=Z[Q?_|Yjv9{MKMխ:}E|+|I 6.L<|ģapZ>:F?|. (`eQ}Gn?|B (6׈~xV{=]ƒ(1V`b+|>s`Of݁ȳ7OG.Dǿ? ?=?|=*/bT- = \ҵON|sLtZzy+QZkze^o#JP$|Q7}i4YajKH@qJ⯃5QeVW |@ND%̵!QZ((((((((((((+|x5l%ɯBZjay:jLʤ9yHSذz*֩Ϧ\N=EA5ѸUW)+ǒqvd c_0X玪m¢j_@QfC\rik(DؓW'@jThTLɑϱX)nk'ξk!*7!U\k.Փu@rcrҵqjW{xF=ס6]Ws/uפx2P2+`QJe$u^r늬nYeO#HP:x4&#w b|d7#ymnXFdy5篮j܊yY}E+r { #{'v7(ߡ:A56pA{{-?~j8$֮ъ]ا\Ww&*94nNGWogM\\h.#q]ӎ/C8_tZjJ25+Fmk/|xqW3hnSt~W_fJymnq$S^6 9ZCxwkakQcPzוWOBg~# nȞ:qWui$f##8 לRqBJs,-e8I@'qM].o|<;I&M>L系Q}GQRaՆFA8of4哅Ϩ#hLv>`^i-=e71rNo?-ܶ1ILUq5MPХנh׍?x+7B*u({2ո%޸5i_oUͤnmxg%5-GB}L+~ Ep F!Tטs&}Ei~_ eslutЏO|_oj^otRl1A1^PWYd8ⶡuj?&]."9>_9)u*K_M0WGCR9fO+a׽XJ}+Stւ@qQ" a[x RkYڣHȩa!;z;7d^Ai$p,=2; Cx9^:VRi塞1=27Cż$ ʣ}zVx$᝟YbRF_t6Bڹ;\vz VXfq*/Yދ翚=Xto5 *ݎɻdc=}kҮEy:nJ%g*].nFۣjE4%&_>+xnp -9eaЏv"SI _$,uSk_![[I.i[L,'ӦYgc3مq Z:TNr7(yqFpں[Nfwf#e^ֹh({tmcW\eTZ6z'wXWQ]9_lU쯝d`zbV?hgz_LJ۹f|- 3`w4hLZE'"Od2ҫ58tx,JcvsRRRL*(>5r@ w'wc}.?LX:Z=l dMJk"@X*;eKG8 Ӆe=2s=)! 0.>Ygʖ/FY~+] dLy#*wmry Nq֚Qcw/Nk/q2 zt?O5D|a.YsX /dVzӣ*u6:R3/ A VSôg) sڽ+ßFm"P~-,!&>fpO\e{W͖ѴUsc5%׼.#u @6iUw). 1^7RVXң$󝾭=k[mf}Ba]idշ; u$Ʈ1h n^A+MA )8a@*F8)!*'i"θc[4Ξh\,nf$dxץ}iW@]x`E?{?JH{y _5Ʃo,TJvW'mepݩH+&-4>}մOm䲽rA0}ܼ ެF{;ǺcrG j0ϩ&d;0{RqkqRZ3K l_j֖uv}jϗJiZo?xYO#ϴ[+"1\ⱬүVWd`cc8=菆_b[j%%#J5[xZu4[kKБ M*?l{_"(=}_Wiq< Ă?𩡴KcЩcY92хК7aIڰc3>-]+NS3DC7ONߍyƧs]ko`OT QoF^OG'`JiZOB>=5ȴO4vB"V8,޸WGo\TC;GvOb~Zjwv^[uSUpJ pTsu>*ӎ`QS*R?Q\Q0⵿26khȭ$b/}g}-ρ#74;A-E|K]J2el#{mm$Ve0:̣Mvw6W1B!ZkK}fA75䖮~fkм I5i)4Gof;EILYC1޼?V OA'VV dAWJUH>jYA ) ƑLKveA O\x#XItwOE'gx,׭׉XUd1_j]\%֗!rc=}+E#7!~=ՍE[85L;hمdhRٰy w߉1W[\$ҁrFz0 _<_o^AgVSr2̻{'9_bGj+L>xͽc1\gHwGOX[^+Is}RsݏV3J-ݵ^|p[VrŘʻ^ ևdip>v& !œ6>könӵXI,'Ɲ 0=nY@ߕ09r,jFX fIsPzM*CАGjE d#!<ru`P?y?w9ړچʼ/7B߈#?xq*w’Oc׵/KS(Nv~SXLaxMԼ!)i?.޲-5m.I7ۿ! 8V-#VU.#J.~e]FX|+HhKэp2n@xT]f۸,ܰ<椲'*GBj5gQMa1ΪH#(2P)I 2[@ZZek|9/JûY^B9ݞgLjL) EIU`W5s#i;\x9WߵQ-ݐx+B{i, >i܏^bsepWw xS]!$l7PJ̶t*z~Yũٽ6Oc+L$rcJr3uPքumMNUTN#5;(Yd]þzkH}>庲ǽrJ6錮fREɓ}i6ǖ"J88$U+n RE=20k.2m9*)=JX ~n^GF$.r[=s^MƸpdYW ٞ3^6+_Lյh04iq'Bvwu/=5e{B+K6HWuE4k,l0QA+OXuT؞cy!b~aVoovmpƽcXKcr=d?Z൏C%2H2<鞑q{n@eEfeGVmid=+?vl5[021S+ Hp 㑏Jb<]:`kGƲɤN~W̐=qZ:͗`\$}zhImˎ7t{DH©=T676׫|ul.G~G⺖;؞ \EZf+U'Ru_pa{jqXzR-q#&h^'jrk4C.lET}OGr_إՎF}EI}`fHYy%F8iiFk)+L?@Ɵ-o˓0O}X) N$ouR?l| l'~9< 61Wk@|2@NjO Wr7GǭgejQ }qCt7H]\z: q+KF/<*B\ls։Y GOk%fG+4xs;vPDna+h6±^#1J:>tcnakCN3 MbHHx4lbH#I"u*F=ԖpH Jv儩/Nď\3} X,o=ϥMsvh\Iv7 ڱ6/fh[H {E*2Avqڧmxo'-H,GvcjxBfxcPvQ~_&B"E_ۈW+-N9ys"q4y¿^xzinFu :gf΄kWlXQ427Pv+^#;+ߎ#I@,Qw0Iuqi)7>hs31Z>%̹?5ſٖZ5Mw/#M>1?+rpq_A.:ގȲgj8)cGwnmV9L.q7i]rXqS~};Vϵ]yݪyv)9EZlьr* G8дsDpҴML#xPqH "zsZ@A#fOh$'0CVI!z8y($a^H~RK/O45Ybv)[Gy;ȪKd6w֌_OqYז$|PTZȷ1o^Ң2k.wu9*zbC SZzҮ VpsZSGʘ`N#V6jĝ1ȩGa<+'`h޵p_VudHe8 zBe!B}KvWdB ׳>/j5c <#7kA6: ,ncNA:Q|֧{u }ֳ^hw 8c^uO؃0C-džOʁ?cV|OR eu/r?{^ȚΫ`scpVF>RMٿJW/OeCu7z}J7#%DxK㮌.tKs/C㟄<\sׇ`o-H|O~Ǻ<>8#w![8[DZcR*ZYml~ w1u}4#O| <):ռ=[l񘣑bE?ߧҾT$' r5(35-m+O]'NFUר AW=CV'2C,_Cu 36̺~df?U}r=LnlluX2˂q=RN~|#3¼<> Y$ t5dz>ŕ '^؛sk-kGdYbJ ƚM¿D,6W/;=S=Gנx7٥XoA,km'?nt[;?2̧hO6x eYkE- p{c^IP*Eɾ?='#+>~XqEqNg3?'T&3ϧ )S꧱+-Uٹv6 xI񕨖Z@>x[CEmor"pU-sO<=Jp^%?qt }On4b.c<|OBѿ3h]esZ_t?ҸOh?=Ŷ"FHۋV1WU*Ξc>mzZ` óV΃ytU$%q[0xm%n|M1]X c}Ey 4R0k8*`~%(mJ,4k?ZmYd0=MpZ։q\tluf{\Iy5zZ"$TEi?SmnCJ,&xNF1ֽA;ǖiַݝenI>}klj~xE\]YY_W=>HIeJ>hFC[$`5i3ґ"?~3:"Ȗ?_C^|]X;7( #𮈻 @TuW6W4Q^8'?&)XNFHaޯFNzQ\MҦ7j1pWn Uz<\-͹qIhRb[F018\q*㰻[bpj# >ɱw̍1]6Avor|yڹ3 d{SpK, Lr:=gND G9+}?F.N{OZ JSRԓlre%u;=OBӼVK6V0]̲P{գGNrly;iv>}v?_JϽ2ߐ"*=_;^^d@ 铂ÐcYy R W4Y_==ժjV gIO $<Ԭ))#;u![J,&d_6G&y#W+mH~5Tnt6D<\m4UA$ Ux)+r!6Kc-f7[77ۭl 'a+o i1k]:2+\B$7:QךFσ>iuKl"ˋ*|uҴ[/dFZb8.ES+a4oxFRD@Jw*'ּK7uIt{ILz-0qȼ%S7zѶ͚F̑1QU9\cԗ2,woݠ=jKX@Uv隽u #޶F[98=j+Br bN2hkVn!t3).o;i=:xU;MR%mh7wUmsO(|[Fzق9ᶚ2?24'w# \j۲'wH"7x)(XV\&Xw3后JuL-~J2orGJFi[khM\/nb2N.Dg%URU1oҵ<1.WyC"=9EЛ]x $B+H0ۈx*Yܙd|s:+nf#Ru 4{QC8b-_qcOLb3Z!> @ Zy=9S6Sڼխ#_3ʓvwΨd«C/9R3 wHYYOl}\Ɖ5_.W<.ƣ;S9$WXj6Q]JmwHIʩ8@z-2+[-M2IGǙw(;/osZӢdQc6.k۶.^9=}'N} թ؁DNIbZMyqXˊI6]o+#%y;44gqy@GL'5g 4!GEG׼k!.Ы6=kj APeUĀz޸'.hɽMҴH@9*=Uwȵ?& $%F#z6Bn.wusn> xu6}"ቑ>x=ZOm͔w^NFjit}M&n tddf HUfT&x~`rGJ|=k B+[I ,Cv9ue+h. hʱGVɴJK07 xpt+pz5M5Zʘ'a\zNşFȲDl8 +|[4/qD*WS.N ;;v>=.\A0y_zH]Ns xn䈅r9*/CNERx?~ /+^Rm-,Rmuz}I3\H]^ yO\jD瀩IC.[^ZiHw*λtrBs/͎=9sִ,"kh3"xSndI)i84<"H8]*% D<8W3nnm?0r)Uoh/iaf-w&WYݒpǜSRnweͰ4 Jπ{mYI3^yhhr2~Z@71A\u ֌ꌓǕ;JK9{Ws9}nwtl/#n$#znz=΋M]ΠK \MZM3a#O8#.N0i~d;`*5(fY\di"~<ȾF?^ִ0{T_{~sHw0Nk;Thg]Az˓*E>g(`p XlC8Y}H%45ULUF*'SǸ=%Bi] Vn'f6qQVkB&o =E]{Vt4clfG}vLVEݥS܎3ֵf؃>xL2tu}!/O*r!`*#OFF{Zh:ŔT)Gf$Uy3^˪k0zЯ)Q71a(.o#vI ۚд6tI[U`Ӵ>}Row?A^omD~`./Lgo&(6fcWLޙk>|\1 EixkiwmZ,`:i mׂElZ׃~ɭwZ\ECZAddE!EPP[ )MsWַ:EG:5Fdv;q]e!CY1pd93K. 9Rm*у!T7P(?\T[Ej!"QF*9.US{iIJ8VoGSWQĬp?$~Y?Ker')P[ޮ準A- r#(fFG96(dAD%'n:gUq~zZIJ9GH"PKUOVD7LV;;o*L5>6$cW->@/V_`zҼ͋Έr@ƾҬ` k\]xI,>돡5-捩GOn=PG9c+4f֦dd>n 欲 2ު\а~azȔ~&"uxs 2/T3xu>|Ok/}ǧ+:㿂wv.wk^Yro-';3G8U8Q`}+jT8c]|օov!Fek:o{;Yx;RQ qyK["@0O\Z,L66 pEso&C @Fa?>,\|˝Jj~n R>ECΎʳ 6h{{\}*+QjKe ?ϞdOCy>8K"nڐ F~iS)nRL 9;seǩrSr2[4y 3=1W v=Z'  jdQ"}AOdiTu hgB$FSʰG|k^kʟJC#Śryɀ;34},bՠ tY!T>hSFCᕻzPQEvQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@tj"!y8~=:J1#szag%q׸=y2=ˉ9SٗWB4yW̶e,dv @fidq޺1܁1Io?d ?  da38 |>x,+[y=*\,By\k*nQXpA>|lG-+\dRv<7޼XƢI .cqڜব2qwG$axJ,XeYzU8Bx^'U?Юui[ z{OK s9Q|Qўq|L[VCxOA^ݐ+r^7[:%/rA '>e&[EdRk&Ǩ,J `$YS_ַcïjE5zzs8>__4zzvènO5cYGrpXz2~zqB}͸5K*Tv )\t=8^.sgΑ rqqo 弐\DC * PA!k{ጛq.䖞zy(mGAo׀Hċn#<9/J[:6sk"?vDA )Ư]icHA+ve=_b.f7cKGo_,Ee8ɶOu=a>]rWn|_{+"G{ÃGz+mA:ˤ {~|WE֝}lcv^n ksnuBGΝZjsgq.2FY^$}@ua޾7 x%˽ tW?h Nm\4.},n$ǀo2nLD9ZV֎[Ĭ~Sqog٘Hm}A}WmGSWFY/1$cчPF}5>TsS<^KbO\êC 89}9_vz&:)'OVݖΣv>W^UYǩCDi@ćc>ߞ|ʞ^gzutZ [ѓK{1޼K901v0B2W8ڶy\{)OkcX@1zTɌU6ŅTpA>6aW |9S}+>;^ [N>SQI֦ UR60>X=t#H:RQGCZ'r+g8l;`Z9εh8<SyyV$ҟ-bƻ"[6Iܥz"mR2qWmBl|lVXמfe^#f՘G)sں]:In@KČ2M *GoP}k܏zrB;umd+#` +Ϯly 2i$|֖x!]vr}* 6MȻa=u5g)hk . B^ج5*_B [ٳٽGם]YI>&[c$Y7:ygu;JG}<54wwE&,/4[[>F_[fs@{sv%#j"as)Xz?XZ)ymb'ʼSU}oX}E[%y[ !m g?+7S-֏q.G9 e]OBr}Q1dnO$'o Cۘ" R4G?ʣ@{W?|;}Vn則>#xU[FpKmQ5̊,IIF*Xz^ۗ>Z1L+ճ6їv!G R,? u9iB) O'ڬZ2g1t%OtbX.lz #y27$`5{1xlf)Ql$G@O^V54C]YZxL.MJ- $xH󜃻zht%qҴ=G GF7;th$\[o=j3{,n^EJ֔փm緦+b)^ ckL +&"py4)0q h zQ7Bi;f>X`s'ƴ.⺰bdSzz^}NDL)g#k0ԎWAo;FJQUfk;1T^ki ,u? ڼFW6gp^fi$OZݶ2I- -9Yw9nV3K +gڣm G|.-޽^d8=^Hg cH^TȹG#4gsÖgPٯ4E1ҽ[!xzÎϥhڽBh Lďы֌RItyOOWgۓe) d}?{ln ]OB~Wu%$P {WO kovR9{z}+ƒ=l$%eSz2룴,cMkkW|%.wcZ(/$.K} |wFG ^ #)1O~N³Lv8k_xI[k ' ]Oķ56?7X%OCs]hMNݐnOּZFPZђUXg2OQ>iI4SQs18e'_#א4Yd&& >㡯R5>?Ko{;]x3Ҿx|C> G5otN:B朚?1xBk &kgHdW^&nYvbNpNsZn|˴'"!3 S:Kxl@?.=4RnG>QryL *զ r):סΎNSKy%FO@kf†H` >kǾ;A5Qu'ڱkl\i.<5TC, ++wg#“ېz~D׾#mE$FqG^ZI-:Hʸ/ r7?rʳFNfpʪp#Pq$c]C@-qÁԑמNJȹApчހھNƇEc@jF,m T-޿CO=X^[FBH# rJGB8Is` b֩C_FVXͧ#UnHAaՆ,y%ǁV c+YQ]i]]Yڃ+jebN\Q?XWqzT? 涎J́ۑMF,Y,q*Y}1:Jp$U ,iWq?/1@I6r3U,bPU9!* $Luyd fF |2eU~`x8 Sp g ->0HLlj7'Ҫ"RFA!\=MU]ai=d\!<-EV|8#GDB)|Wsڴ؍V$-VjȻQMGDg?{ܠu㨪nDySOqY FIkp ?xZFcHjFS܎wX JoÚٮLBJqkk2H/oSߵy vYcUy zSqo*xx'S]ܐ?#W7-6QKq?g |#/t*81_Km<EyZoܓd˷19W @lezHj6 s fԭxч߿Pq]L6`9oSNKKtkkҹj3?[۳ΐ(g_-ӍO\UH˶(S99e;z>hexi 2ʜ[rBOu5:2{Q]|59ZpLNX2H\OL:\n ( (9-m c8o3C\ `>U_uK="9GmγR. F:rx#?DZW֍\2#tNilţFN?J%mP>R SKUF9!#WFf"#0,@"8E;ƽᯋ#ҵ3QXHXu2`Ai %rд}F>?xCN񎜾sZEխ 񇼏YPJ^@| s^3|MfV,#-e#OƼ~G7[ k3tIS?APBrƖ q8pw.p=?Ҫkowj`O8hc#˖=})/G"̉(WLOTp6!洭!Y{pPTڬh/ țc瞼:o5w#cJ(xg:g5ZIKy4 ݶUzJFZ3LṱmIIUB8ooz'yuݦM(Ǡ5^jU(j_4[ 7Avxlqmřx3\BHUn뚖vv+6b==*֙)*ބU L*cҫ1@v+ Wh]P@]n՚Gk֮ᾁA84tKKB&:OwҫϣOU#zΚwtfPވ)H 椑qܚ<@jG%y\LR6z6s֧O4ؑ,Gqֱn!e>'u5bPX}I;:RӵKeU ¡'RZOyR]f;YFx簨#烕 `?JЈ ­-=ƚKٺ5waa|kк)&!nA5pPL$̞"|rXd`'ZMM8xzw^gR;]QY-^x{O _ts8Ϛߗ>cW8`L0XpsZũ39'\e z4GVZVۙ#f Or6uϹOHǯ־ruž3Kiq%,NQ!YΚyYp?Z=ŪZ V߁yv7ae^'6|ZI qqԞ6vĤs^ KZOu|E|Bϥ+MV.xY= {>1x3 _x,}R}c~?߆zII<)WE PA_2Z/X.\S#[*J'ĝck+yv^#q?}ע'^72 SuSIz,c-M"t1E>{/SuKMkrx|Z#yb۞Yu$񬗆M&\?4&%;3iwEel7'KW#q6>)k+_$O+i|1+HyO :no-meWE:=g ꏏu]X   k:m.[ o@yF>һo 5jBSh$ݾ"LRc#Nҽs)Ǎ4m2V{Tc/m#[JI-m8YKZǜ|佻};< A}$% 7ѺW#᷍ ilg%ql}1^7{xė^muAs` +J|Cu̷=խd~3ҼCetֲ?1Ar}V_a4y‰5ka=OývWm#^xs? uf[ud`=JN~I$_GxӼMskNcտ淅WmќStzGį %ݧڇ zZ]gM W:].a)2pOG_C_b_x/[?QX2ߎ  xo -(TElQҺ)N)i~c8gz[gE.kPpP3+M|h_TlWEPŞ? O9rqy2)gpd;yǽi\B9G @GB{{U#umDRdFV-BG !QWVO,p6).>G_`!IoLuq6ۑΡONVU#C #UA{֫]QF]y-8jhQOcFCH d61L`6[^69|I(}G"mrW|IŨ[5KH"MΘ߹DO1C\O{`^&!\z֗mmrxȼI;VďlhA5/>6c 5 ;wےRrSkk,!]NqjqLNY*qR(=,s~gc?[{Ճ}.r3$??X4{xDd/bP>^;?N,ח[h_)~x%I5U,A=:u'<"tf9?*<7_ZdP$lX{h,uwVҟ3X  $̧-b=;㇊ E ܄FH&uJ{AYfݑݫ -x^A(GPAjy4\/&8bsI>^<ۏ~"xgR-7TmbZ4DS OZϹR 0U]~U2w*6ZQ:yXPHZՐf'`T֯/ ԡB-ZPoz7#:Vԗc5zBuZWc-\Tu~<`>9՗՛R܍?܌}xnCc÷ks{qr҅~4;u-~yR dGR\KֻN?vV3ۑ.p3*z -"% =v0TG8H-*Nk^[qVg*ޞrc|6x_d䜨 F+EPӶu}˙d_g&8KY\Zhmæ;>iЁ6o$jvdz5#tgvML|yoκL.PhfI,kc/$dA=^WHly>CrAyL9՜1aZ!5OYkxVI'[Iocku%oV}YBNNYXH>ĸ.5=FeT'}=9tzG'Ҵ$BeqU;ԒBT>%bV,aBsq +Rr57u5ft-Rmڝ6s̋_Ghz k? ʞU QLҼL,'8=+<| d}UG7갓`yhq"c|}m E!} )en>'IT3WG+ };Y[I%-T)9\-\_S閭[4kvê60j*ßSԫ2"udַRf->np:VLK.Fw*=[1"e^ R{˹2nKx@I[jƯW&d%vx9g>t, f9MG歼-ƙ+'i#=՗Ҁ.К j+e׃ҹ!B9CvzW"N;{;]N|bD$H998jngk[kw%JFJ٬T _Pzzo^qWeK)yVXtWA# 4 ^sUZ Xv$d%P2fhjnP5PqIC(B@1n#ܘ&'9Q$W1_Rʿ拯mç"pLϞ ++k|uhvιizM̱jΝ^˃J1iX:|1ZZ±GcT WkzߊqM2ռFF8w=kn6v-CkniKFG,v)lV[E$;ycY6 _>wc| 3Wtήc<47vC4ϻio9]{M%XOsG,Wp|~Q'0=VEtq#\|w Ɖ{k_vg˴TE "MٚFJJPq56|F<2/-T@$%>=+guZZD؟y+ox3mA,VIc+cʍ+OPO1^៍t KUl=듟u砪9=.in{׋xž5;I#u Hk*.ΉN{0&A6zgn&{G1I9'Gk }pIR7#S\{["FF?ƺPid +l.ۄ_Oq`j@H8ȭMkr;$m>. 7`;_~T2p:S#dll t`0k;]`63Z}&,0V%(Rz2֦Oc e9]U. ;g*5դAg[kW ܡk'cVQ1F?ֽkQ>$gzs_oY?4Y-;MG wdžzӚMXwv5u/kGeԐ+Fzm)qm3Dހ=+Jo,Eh'3,}oOZ> "jT0!vO؉w:k-#W}R1MB×^noEUp}i:[wvν7F[1NhtҚ|W<[ő}L'fd?I[l\W+%WI(lYsHM3i5&QxH# Q޲M"o=N-bͣ*uR9wC H[]mh߅IK1( Wf>N3T +[4Lo{"jƈѼFfO4T`F-IeMAJsU~0i6B4IȶLG\}QS= ^uw_jq p RS_JҲx*S)?>'aX-n>@C$VB/aiP _jݒ }hvNޮWAn@ަZꆈ"uَ%^PЎCyU.ѭKk d+W 'чƒzYN EBUl5]E"@'q!sncpA#=Ty$2YG5 J7;zDn #^)ŚTMŹSRmݻC2^oRkMncaϵ\PXm<Y Y1?07mzX\J$~~:Vn<~Lr ~RjLSxw[LoX|,_V9zA ĞEeFԗ2B\WK B.`c\}9Vl}K^*B^"s s9]|Na+ݿ}/6cAʼ\pw=|%AxO6nY2y_ EZwEWaQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEVgi3GF8dVӳ ~n|f%^pî^2E/$ 2&0=[슡;$ҭ=dVZ*4MApIKڈKuHAsdum\mUv)BU<~+ MJ7p%cG"4bŸX26Hǽ>D$#QˎƜV:pi&m&h?ҭ-I$bC90} ?L|H?6#QY<{y?3Z`% Ur?{RF?PR@IXc\>sGsNGf~YQh'"^5)Cm.E׌ՏI;^9o߉Ci!! ?ubHϪ0O̚|{>kTdJ=ھ@zԣҮ5tKOtώxQ>3_cP*<z#Z7Ǚ~TR[B܇}>>;sn.t˩£\<a+Jiٝ)TcKo&'^yVaU9CopA+.L}v~)P&RwLZ&᷍n-mt\Oetß^"ThE7eqkhy 1UfJ݉qa+;2%.߳o$G1?jVE~]Zj#͵r#_\-|Ye -jKKH/md^ãpk|[lfoκ\nO`LkխVT0 U٬cM𶫩\Y}7:T9 GM*][01k/x7FΑ.i6rReSꧪq|'`'mSɬk>1?_n2i~ kuj9k 3ɤIkԃgw;_'~/ u{Wegz 9I8t>(iiDl tWWc{p_Ziͧkqohξ[4 k+|M㏅ %,ɍzר+=ޚ=7~gIe!'_2Aw=cӜgǍ7|Deʘe+pOךI$Q$,~SnQ]f "(Ki5_vqcXڞs\BPx +jD@ںYnD7Nk:w %v==*֓Tw]ϊiibn++- ; AqҚjJM[s4uTm)duu <;lԖCŎEp~w\pvTרV(򃅷Qz$ Ie֬'j AKbYF5Y+;Lx$.NUbJ$mN@8=#QnExX}̎N tCYH-'zfh] >JB ccKHRxՃx'kbR3k 1 Y1Uy0N&:u9*܇A6B#MTI#5 ρ= I4n!=5cixN ynRnk:Wh<#9H9=IAc#2JѯŤ!_$DT`1ӵp>%|[O,Z%#:d$¾MaFynąH"-\uǮx*}z>&v_,\\;.$uHxoxZ$_6@ /eJ~־Z[\Y}%sr[ F9˾.9[yY$;5ti83-J6` 0P $P~c0um BJW ~Z$^"<,dh`mg(9ga`hcϵ]Xci0n3f.TPwg$Fծ{ayR9`\Uƣh2AꦿB4~ac,֒X;*sOI-]4*OtƬ9u1Rآ?ġNx VDOrΰa2rG{ți~b,A8;]GWA07mgwy:['aLFAHڈWM[C{E8S[qT8zҲ?[iqЊ_-=kyOKqXG'ޒKxry=f Y'g4\Ve{mY6\H8PNGLw &ZPs;R̞j{V|Tz/KySӬU7䆹8nx Nִ)gU{l۠OTnW͓G/26דȯgxsFh6n-#B@N=;%I/ꎈ5eDVܜOc!}2[9H%܇G'lE|kyluMi+zZ29Gtb"p&XGrT Մ.N##lp1%#yUFNlS;wdHUK)ALeF9n\ݤl SGRzdzR696nEz$ \tPҹz{\I_G5FVV%S 8]EC9V!*kC+mT#5ɿj5 %w\ް#! OK;m72Hl ;Q5΍},ک[FeFKzG"/Fռ7 ͬ D(zdK+9S&*rw:x+#߇;}moxY#svMlT*O8ҹ}GCXEͷF֬5ʻ23rgw0#=8Q[\NL<962 !*2*LuүRinFĖѱc7s;inosm盻uUlaZ5l =;*.'=MZaD-N{h HP ;5zXxr  nPpnn$ɑD#f:%](*N1Px>k'w4 繋W;ILe\& +z,'g̬p^t$r c^G4 U1΋'I{yb֥}sأz,VZ$7deYu[cNFxє9[ 9JR>yᆯ4vcO?|hնY}E!{3_rEtSJn2T)Ilʲg?7ڒ B6OҼ[xLo}C 0\sj J /SAJHx 犨qw&PMXZ:u{m 8ǩjK=!lkşDž|ko=h0DdǻԞGA+~mw6_ Z[iG Mkgj!ӓϮ+!t9~F97l2ʜ06;y#l6N0ANVNG{n$Gm('GI23qjَ2pqqx$i0fA2ïGvF~_jg:ZNr8?Ҷ3-%ӦC -sV7:k).8xZ\ =8VGwP|mCNxȑ }}*fUtbFX^'dw-{Kdʑ,8Dt"nB{đ$n`54oSMHubCF'>3tiW8VnZ~ex,nW< s0gwF|)]j4KhA v {iX@2Hƾ1M+I=45 ,8A[35b2'=s~2qq^O&m呿88|٣jV;Yz}*aXxS K±x?srѿ3L:7Zk2POY> ;bi6Y [/z`$eUU5ϋ|xW̬B$R)N}|35[آ$27c .>?|8wzIٴj1>R;::0AA}Svsè^$sK19aǠ{W~՟ "v \p_*Jr>NVY>mOO*J+KT><-<=o٨AQI'#؊]U'A8`OZ?sN`02-ɆP3M;8;x vKՄ6Ɏ# bEy`sG\:1c9&Ϣ~x8G.gDmg5#5o_ \|:iw)_% y*88?uB+sSoKBu}/m_c/Oo݇m cBZj(Ğ~q|RCo":vjw[œ ƒQ޽Vz3ޢ?_q_~ ~Kcë^{q ;Xo闐\ +w"jS7iPsdѱ߃Փ֚oMku c)A`+@;pDv?#>(᮲mGetFL͏G^1W(j" r"L`0I {~5RO+]V[k#JXfք86ǷeKTWSx}o۟*CG^>+錯ٲN#ec>7Ut}+~ #C[^!P}1dH?+x1 +đ2E2C{^j_[Vcxs^ne,%:u6V-ءC2!X'7~.Gܯ'~SX>֑8ey4R+uSs »o4[-Qu(W_nX%nRd9 =Ez*WWG#Vњ>̺I2[ߜr_vvYdV%|TOT]Ù[ bKc2ϔSU}-<ՈY$>w>(Ĉ#9}5hOѼn+>Qk=n. ƳIf9Uqp.,$)%8^sk \ũ1ʎ;yThBLyu-ٙsH5OnXqXEӳ5DMB JKC&92szHƒ7cZ7E#*R9 BbjmmLZ6m۠bq\d'8OFyQwm_%>i9HV(Z'd?4v~?CU{Hn l2uS t'h&yRq\niٖw9x;;HEO '<GMiF6;EnTѾ] ʅ%8[sTt^PqIV'ֽKWjF I.K@=qzg|=_k4 `q"r{G"x_@_𭏇.#yeT1mvW#~ 6-D*Ɓ̂`O?c]훫.ÖS5Ok-|C̔7fz>,🀾BgZYiPrysܕBM(mBƃ<'O'+/ vJbkp3V,O쏦+[a`YBI $\(xiY4 ٟ[xkV5Ii# $6IJTwWRk6XrrH^2M6UkniJ kH0ߎM?zQx{6A!ѾlU=,A|Q k[L7sU # $D6FeLLlq"+dq{p߻gҴ 5q:xy[Ty 7r>$&E 83Oj9գ@;UmvJ+ymï`}Eݚ/=\JGr3(U 8 V$ϧJR }}jxdޥ3j9p C85- ۂ6+V9Ұ5_k+(-C3Vi9Rr>{N6)Ys;ʮ}}<:/K{`pvQ_Zl՝ r7$nj}&h !s#^Ƞ:Oͧݹ)T?N=>/[h'͚=~]0Yr=#s>H>/j}سՀtBʧqW^iAhk3I¢?'Mki-+$3)pAkma}.yW⭓sfsؗ ѻ}+Oj 嫘QH{Ь-78*Sq&.Uv桹.069 ,I;DP͞wq]MsK\]n9c:w w(F Sv 6)᩟Pdۜo?¹倞?:.AcAn^FO>I]z Z9glV" _R3[}Nvmls]nxh;u WWܤoOjyyrNN }FkzNyYao{`nP2s;1/8)e'{0--;fy%;/_Exd&9KXu JC{q?@|z)p)T2j#l#g&OI5g`[Lk=:I-i2]clqqO^+}ɤ,q<n֊E!jʅd¸)}7T2y7")x8Zem<2jn}kxxwZܬa3^!)`rпr#tia5m^X,Rge>,{#5@'`tghf8 y6rC;?oJoЋŞ17$pVGU8/%.s5_tdx?s26ڀ Nt ciebxg'nsjhouh!V ==hӾ_iOcp"yr8 r$2EHXr6-Ha2};mlϸE@sGr.Yx+Euo%fUNQ|{V\sӼK ;y b8I_ sSD6Zs(|ο<.&񪴄(( }oFP8&bR]?LIa *&]Lq+>»QSd+h]ՖF>qzի*Q=C s"žzK@ۤVY9!M>I[!<E4jۂ:-0?9lo:_sK4)- 2y8S^oj~0ԖJqK*W|us/Om,Ŷ>+]*84kH^i_Wb՜|.~2i4Q^g\—6Xwv=ȭڏ#uK#BXE/w$ GVvq>ׯƱ# 嗹ᓸwVN\ƪ +:"})*iSEs,طo][tB'D_G-g웮Nb7Ee-) x>֦`knڮ1Hb]9ֱu^3yaa#~1S^t>e~QwfяM ` D1zTh"qQrH$J(ɶ²nf=qъnVR3qMbJ9=~Pj6Gڰf=JH/ӵJ q,3^զG]A",{󁏭|Oky=02ҾoM.-&:V+tth Zn7띾Ф&='?o![%Jڠtܹ '},s!X.,لI#= S:2!Lh$B ʎ:tyȎX5cchZfe"Nv!+Cxn;E`p$~$Ѭ FRx=aiܮKKYZ'Oq@U)/ /at\B 8?Q\͎HZ@$bmTw[wew-']jߖ#Jϴ3\aK&E]͚ / bEGSiq k ,^ϯjۃŗ ?M -Z/;ֵ=L6 -n:xNgPuKr߇J^{#[햙g2A7grIa  3"Ɩ!AR*鳷|C[I %RDdbŹ-,t-t>е#TE'q?)+t9$bX1^r}ĵbMQ];K FڶUWR{ @`A5`7:S|v?poO{׆g/>'[$oq| 出+chk]A.Jmga!wz?ђ>d4iIk; :py^VWI%T%Ԛ5i $(F{fWdW1jbȭe#69Rw}|]}ot=j jZcchW'Փ^ᯉ> I%sF '_ҹoĿ |O!=HwMFlhsŬ͇|rh&Oޟ ڒ'ngЊQ ;ھag-'|1[>>hQyj&f1=kX;R$EW*8zywGZ^=?p~pGҼÿ|D4z^H~XO;t⾘?cꍫich啤`YFZFfbI{ƽ7"pRAkۼuJRr{Ua^ºV Ac?[b>|מ]2* qfvK[ p@<5|H6ޕs3tR8a3^kjM_shQlj'Ef{iIc8xQ|-zd/-HO# k|]o.d3yOEGOMBaҦz;t6EyY~E$.rFǽo"0Cv$coP?x xzީG9hɔȸ;GW.m0Zf<~^a!_C5ג!\m5Ӭuh&ԗt[Kg3{UVzpU0խ4yMo˞sI ^\ڳC #9jƏ70SzVB<zKwpGNuֹika+@]]wZBΧk(>ұf䨢 ((((((((((((((((֯yMܙ9SNډ0s+S7U=`_e_i'!X#(d+s:A1i$g#^#qTa΄8M$9Pڦh5yhIbFRg@ޡS% ְmGړy4oL}Skezt7O׽_x A4?*\s ~UԯXI<hS7O = 1|UpRJ֤nFAf)GT6Hc#^*g֠V! խ3S'&aXۏ?#qڦM$kqati1dwхdh_'tq5> d hFoMcG<1 g麌ͭO8y늤Ћ)r('ivLYӜuӵ!;6{խ_OW $\ #IE`E(~TYx]U'#mR{ތ92wZ[R]n ?ݪt~<>#JUuxrĞeφ SiWחes$P6#JA纖٭|%cxHhTSuz51~ѿ>3rxp"70# l:`M傤UrGֲt`Z*[,5߅oǃ$貁0UOo>jYLoI7:L|d{cHv4)GO?z.$2fSA>\垦mGC |iF^ i Onތ85M9ƿ[y mg}d#є?kPhEx.E Ϧkέp:e-j5d'ϣn·ְ ֹoxvچ1t3ۃ(5ɱ|/ίXnfb-o~WoGWs;-ŻW^5Uah4k W+qgpe?Cʰ=_ yu?7OXԏ>h <$5 zKsQO&7{}⥇lPoXo|}E~^Ѝ(0FgA85 (?O6Wҥ $?Wgf;pg>t2 MIdEq~%9Z#r_xÚh r[^o_ws΋ir%s.t&PFYﷻ[wݾz7gx=;n^Vi"vW4ֻܓGuےɓg(D݈>;״SڼVʸkAƉ}9 Wg6F| FZ3}Etҫ-ShZo#涓MluHY>ǽp^.}xQ{+1H3Aꦠe$I?<Ͻw8kr[FT4uѸӦ%A֩]ש"` 6fMR^=Zp*2׊vxԬtin3 @3WWZFʺr=֖+6oEw_hK/ctaTy{u[RyzjSoۅ?#u7Us2Bd+?J1)աnCSOTz%lefCOS+SvWq$Ji#jƹ:0\/BpOz}&"kO_qY=YjjK,ilVI8r=`W5c}j 8{]Fod% Mѣ=xK'Iu|oY/f6nF0F弢ҟaLop8mwjSZsR -ƺxmT,:OֺK ya,“ޙ *ݘ5xo;;m҆,1ϭ5̃V\5ÄT3Oǖs\c4|b|sj'D7W&eY#A'<'UῈ6SM$cd~YSWhTާS.ᩡcI,@3]|C&LFۭnx:Obf"?f6k~ j^!גMY]̥@gx"C"+0j|i XXٛxfE',6}몛'z9G>3w]\]im n quo ^M_C6g90<3mT]Om1_$'ϯzo)WYy,eQf1?g&6eBw ~S뿵/4Vqͬ^9P05 Wq\[hr=b|F'Q"mc zΚNiڍK@Al?*9^֙-"G][=5tDdO{26>a~.m.Hxkq$R ԫP}E%;j>Kq~`) SYXW>KIHr{VtbbĘ] Ţ%̐5FWD^9ƢD'wqNHIs$A:zQs|xV\=9dj@ i8>iw+ۙO kː95c-e;X{UO#䎕"* %9WO?AW>yru|>rj(JJ^ZMm$,XݎG8+鿂գgcc>ιcWI#7 Q{.} d>:k~:Ӿ)clנR-^Ɏ"]+V@חF"+XtϱJO ^:$]Fs콿 9RΕ8ZG>-Mr}+[8XvenOcYb Xr~QEύ #R֚H SOw]eEyh/OT?uѬ+u9*StߑcrzsN{{yS Pxf9mfct=~Z붐JgZfz~i7Obfyq8Lt `ONk5 f =Vig#^8s #sPQI[h'Rq K?ӂ:9kWq[\Ax a>+dN&+wд:ئ6֝NKn PnU ; :Nirفk={<-,&y-%ߪԔvifcu Y{W,~Jv8T݌Q_6qc/{e=ݶT O!Ldd:漏)VKxTȹa䑜Shm[d%GJ4ۃn.pSmx-:Qy "6{{WѺgfA `>c|V[C#+n! _R1ǯ=B4潏R^?3p+&E-Ϧ&4ȿ0GX0׍4].2qp'/q+.APWGtjVU~^ZeM JVιOR|unjwqhLJ. O'$╯0U'J6;fΔuV1}qV uݤN4I \CT\G*cm8 g-;\ƎB:.;5Scis奻i |&ƸΊndw?|ǭ.[ikι-eʺ~k2+tH{hPU]x/Z}CNK]Ey[(RνgeM=Φfac*f73߁xnzsW> >X1Nw\/o_c\SxQ go>'ddcW]ϚNGԎT%E ETT[z ȰjvDi\mv?1pzⷎ2%: zw.:Ҩ|ۄ$PxaCv \pNdsQw~FR L-nWS$Ke&4,@!ډ覒xO<}QFF븰4(T& [7Bę\G4! *W_$d G*:^oXn}jւ9Xc%tZџe#:WtAq֩ݵάV[a܌N6kma K4a7O>;5)MHu>Gk& fUqZs7k3ns5ћy9ЉT{sßxwRS}VX-jOx/C?j!=ҭV՝)I㏃z/uXu sO}"Dx}j4Ou3j77-5ù'@ZhՋjzUB+Bka~ɿ# )Z%i.B?bo ~mA&a!3w#.t_ޫԏP*_> QT&M; /$(>dcަiݏUċpdz涮GdUHe5巽^L3.8J*Cسx_ʾ9m8nCq*}}5'KnYw"CwaEy. SNERЗmψ>k/so(+==x1pηq޽þ O$Cm5۷ڐYT8 :^u¶Bv^f5>gmKO s/Ugxž(,{xF(s8H xkMKO,WsD6+IJJSH'58`}iӸZ4^)6Ȭ7wI1֕ukch"׎ہ"0'ҾԴO ʪ.>yq# vRMu+&I(u'xQx/Oe TF2I1X_4=SƢoy3qvHѥUukh=mۃ'dzTqכa1d?oK-ʳ*6Jms ʷ]Ա$rj-qiͥx J''"WO%O_?j? W{msj;D<`0G~qӆCX-𭧉gO ܛO^;D+[w ;F#5WׇMcߔƽo~kZX|#$0kRN?'tc"k7{NǬ[ܖc16IbVS}q]bqʪx^nw:?/J.хmj0HW8Yֺׅ͈H&DJQɞ*k"1v17aDӴb+K OBOtG( Gּ~ fR;j'T5ʟ+x5E$ƐŲ8Z5[+Ԓ)y0(W,z^JOѬ潼 `BISЛjRĺM.|Z5@t'B5KC'/)m XNk@YF+dIiwqd6?oJe85dx8*6GZןhr#|}H؂p{ZԍU}kh\AVoz+RBYzXdT5 ϭ6hnE&5^9B_֙=3i#.,\J2ƁfQ$grT/QE&rvFӕaOkZJ A5=Ͳlw+9 A7qwEo;;6-^LqYq6N`^7|C0KVn޶.[ۗ=;VD+feq]F|cP+TP3'54Ou9 *jw'+FEG3.ƦfVx rYP;g[èI%P?'9_׺eyx<1?m~%[Ghj#2Q<۝K,s߻f܏a\.ͬ~9"T~N۵3]E1,1F" ;sxoYf6gy V#MEFBH7[u2ecIavD!АTrZ&Cl_sRIe4jXLB1Z܃{!mῈ뇗M?M}cA}o qm2& )AW^yd?tt?p'@Y$}_)#\GmԸDk;mfSLpmGp9׵zO/>G~^ an'oȽ9 _4iB˞ߖ+ٝꏓ?hٮ_.{ r>f'=}OڦCυ Xṁ+<8'uSȯ#LӠ,lJX沐 奈%j)'[.{ˆe EvI?ڿi&#Ďz98k:Uϩjx_ƒ;KhO >J# B;yRhdS2WB?e}j:,;zJ=tt^Rw⹥6RL!ޙ"K⾱vR#Vgi,_ծ!x纴F% }뮃79ꮶ1 6!W޸ *gxZ6CW: {V!@ $afsCaoƳp85|r(!9hi>%$H 4.|ՊI ZD?OQϨ8n `A VWV;x,X$O*O[in-`KxǯְtBGF CC3ʩ)8H~>AnK[n-Z9Q6z5>7m>y- O0r[ip݅UĪwU${ +LRnKf/[m,UQڜz{Օ1H[xl+,rW:XĀZ%} =s@j¬6ncp SQwm_ jvmre@7tt^ ZD yUM l v[ͦ_nZ+k7ŚSǘ5 ʲ">9c-+J&;N>e9^x5~_ _Z[jA2*<,,x~x5Ԡθ}N"K@gLی,I!Hף}W"$t70H z?]wO>q%֙[>l+/G^1<5|FO7q0V#Bnjb78iKPxcxLӮ/];M3.HP~_Gj hƷusqJ>sJiwϦ\?*18u#5G]btvQ`YMK. j~ 9QIhߡ#G&QhFV6}v1y%,5]Q7z^"4KmD?N ,b/$ay@a=*Xx%2813ZF[ǣZ}x)_|R;ӶEg=ǣWѿ}z[?/VJ[B;q?w|8 vI"&f{L༏RpqkHIb%aǺ~Z6}EiDñN<{T$s659*)k~fedCsi#a`bTd}+2INN; |wZ%;YH#7)XZ\?:4u^ BG̐WqLJ./$2 62k9B9ўak,u(!'FW8# BFSҵMlcW2Kr M&3#ցp9~#F6(HV)p/ZO,/C!O%{ Z˕GKk>IKâ~Mg(=#'O,WEѦrשx>;dJOΏflJ=uq dpFYOȖ6#rS;Hz-lh=YAҸ_Jܣ&6;~uGRY`)vjkkE({{Ÿ'fq~nW:V9nTBGl֭ǀaV[&q?Ph&wzۙno./8{ֱ% +[pU];$`}+=?x..ode&"A815x]ηjm.yKl#Ʉz~).V|X%\ꗛZB0rH=ko5 ɯx]BK4+hM:!@g_@j &48RPWPmyX8^>iv\$3"42psc*&)n| [*r{ހL:װzk8k=*ai+ֽ3۵ &)$O& sj:DM1lMR%Ǚ 2jWqdy=zgwEs>j~ ac2G.܀8޽kx.3 A@Udrwc[[ :q]f0$d5LCa@O|њg ͖EschPb[0$Wq]I k5Sks?~~BsZ1jj&)!kϥx37̃p=kյmz8uNNMX4q[5뺤7[zS G*7pJSyIRQi)VKʵvWAZ O[KxIDQY$џ9:`5 V{ iXH+=!~z_iT,aY_c\-1OUGA/h'$y}^o:ރZ6et>=u գmCOJ:lS.9U&ЙZF^ u=5-if[9pVB5ύ6b>gYt徣=띏o]D jY#rl2@> ֱ/7>~j^qb+cr9+Ru=T?xGJǃvmyyt|eR= ׵}6yQ']1婛82H1RE1l]KK%AZr:ֶԆ]8Qz4 g')M@%aerﰿU7Iʏs GN;V-sկt+W |p=տxNF* :MЁ0kd4#h`:{W9jnW1^ ~=!nۄF$+tdqzS|W98-1/yP[TI_@5mؓ!0*յ%$Ψ钲1\pܬ'iWYKӠa}\kzs=ȷI ]IVe\#UYytw==qyMo2cGW]KIǭm 4wpupk!z_lߕFmֵqɻabեwZڔʥ8 0E>+A0E%Z)F^?ZswopmkWwu.y2TR`ꚶ%ՕTp  ui^j.Ӝ^^,7Ӽ7N^'T#P1 AҔ(/q2I9f';xCR#$bCę#N|PRP].[,<۶geo>&$4WV=h>%XifGsp?}+iW}%5 wpHGjៃb-ơtdҬ& E?~P彀>wE-[PppbО[jx9uva$lQqW7;[+r=öjvbrHSEV,(GPXXK;=Nш¯&yΘh#\j-?Gс''52zؤf[8cCZ6y5vM S(k2:\})ֺsP~!/?t/]PoK+Ț)ca+pk 㧁 |]\e$M7pku)?(~=26VRd|67Qi=x5t2"J1޼*g6  8/ƒ99!zPj@Hpp\OJlu#DrqX:?ZH!AB]]D[^G( dltPOK? -y4lHcq:Yu  .勓Ju#i`y;#-'*%C\Zx"L_|2>:=}+õGz}}:Y[8k YTi%o9BLgI}%57`FW<G\W4O#qE~C"6RA5oK'K[`裦?ZG5i}OU˵8IGA[g| ujZ]ZJbJl8 rO]#c )OEm@.Ix`'+@^K}!Xv^kD^E60$T2?|Wp6V^4L%2:bm"d21sX =qkяdGSaOG@ [5kWWD`H$ӥTQ6 5 m-_E3ԉ(0=U%i&X.|e]]":ϧz]u9nԬqd_jIr-{g@ WM`4,fZ d=AhJ((((((((((((((((((d,n2H5tk*FQ+93z[R jSUͫĐ/r*V&6rWںcᮕ$Dr4_Z]<+F|+bWSM;$J4rZo4Vi%C%ib<~>YM@܁#{u*ԑ)Rxr˱V?&M`3WBoOjdQqvb7,% gQݔe>pJ@C˿{RbX\b{Sd0&3d%Z$\Zm8>j%hƅYP`rjx't|g[dPk3Bn;j}raX c9Cn b)a8 <9H}{ֶ nQPKs֬4N-i;{=sV=̶l?jX ؊4Ad;}~;jmϧJqlq^kQ91ں)c >VMh-V4yC!+SEHdFN7}*ݠpJe-eN emYjM G_g/<܉Nٸ ~5j0cbѶr PZФĥ\.޹j۶&BeVʕ3zА6mVmB{譲.c+9K}jҘ$=UЋlHd 4 sGn]nfͅCTK!F8<8sB Zyjs,_$pV&еƟ(FYqD/?mxrݮ|ɵ/捛pԵarρ|w|8"մ J]6#$^с}~# }/[XG&=t=]mAepP2Ta=jRU搨~z="K V-BQe>kۭ=B2j:<%;tz^+7gLΔUi7/ٹ_x&+CTo㼁uuכ:s;c8?4u-.bןj:YV ;to?Q-5̓Z/ʗ^㲿C־74[M!cjm}xKJ<W>[7Оq+|=)ݺ*6"rq沖HCGsp]7K~W{j{?k 58U#0}G}=kZWv71]J7$0e#+#Iօ.\< {7_!{rM嬹hk)ROX)?GC86èE]\pbVT\~xYf66A}JPOPQZ>ApI$eX횓žxck$X0@Pz櫈械J}W$kh\> \Le8x"zUox[Pܮq+$WMvT7BFygv_jrzNg_hZ~m4}"R'2;Tkq I]ms&j ZI"Ğme.^O1ǒ}ŭ[wnM7×SSΊ>0:dݍ7Q('5:3kx gAiʒ ϵ{miQL6ڜQ~gxB]i-t#]nE h'H=^o)'ԮJ5+Qda3>3hDq<|0>pXB+8_S'It?;o<77fI ~5x-NۼE}wW^mK9O},:G%26_CZ G[Yn8Bkn#` E5{W-ͽs х$vAv8~w?ɼUj`DwV_QMjꍼݳZ_G_ IOcfnX5@S՛b4>fMx#ґ`#EPIo|W?fmVKԯe^GB@\k;IM.mn& '5/Ž'W֡Z2ǢI#iYp=}McEnv zkG$L} HZZOD:ұ4k u&`O0íįʴfQS%ͺM==*ȣſh]?Gy!XOڇp>oθkK&m|AbC3ևKSxc#&ޠV LڄKmQqJ|O1Drr)z>;4=#` ')` j-c}e#$>OQ؊o5Р~e8ޮT2O){{D!26oWW#%f(;^TuIt:~s]GcNP~$/4p=+;T c "טk> ~Zo4ndr IvKO[_nʳkbsuX4*ŹkT̟ybODo:/S\>'49C5ƒ9Y7d{+XG2 ?J-m|ֲH:bx7CMf'0d8uB!zcd |}j Ciݑ1Sڡ[g { CDžCih޾~s0q=nVB#Ð}#ݐfG\P%?cs  p߁u>G}IzūQ U;MVLe'4c $ln2y3,>ŦF=^+nRD:ވӕ8c̵'Nɼ7{,;Y~h_0' g=ueo-Γ :j21Ie?#_d6 qx↟gYS#l(8`i=ʏ蚏 Y bktXo|\1b:־?Vt`md V3}k nXEw\璳 T*qsUcn>åNeRP' eeȫ$ͽa\qMhr, 3u+q@Q]Rϵx? +-(Y©^K?>;!2k%&͡y*:ں/t=J9bˌp+))x]Om..9 j I=k7Xjv10Eq~.Z[xryt!a\Z:2CFpzw5NkiygЌ 5AwWW*{^ĐI,,VEg R3ޭi29@ukg_QdZ 5%C.Fzc+3}C 8ֲirAnž}͌&=~#k~Ec,1$jݗYK"o-KޣsZM. 5M*qT(>o}O<-fXǷEv-OPjg +__h|lcu+׊QshF#*@㡯ln5[L=/S43ۜLʧTzqћ'}>_ZiZéѷn}=a WYQ$Z!aeGތ ՗><=Q-cF >/*ɒ8.Nt\yOOʼI~x#-'u.9^v ՟cwF+,p^ /-Z; F;N?٭}TdޗeEKiQ`kWwSM2[6A8xe"QoxzSG_ء(oWR nX$?2WkIFX>=KZ{my!5mۋbꇱd{@i«M;/!ĎrM|BZ R"dr̷ךt|ZXˏ2L QR$7++XfjMܨepx@Q24ꗺCVA"_v>3𕆨Il?EYU+;pTV}$U3Ʈ\_XqJ ?xlj>=5h@..ٮJ^~|/-<<eł$SJ̥>^~.s9^)Tč cWKZn3E[A$πt&Xb3 53ZKj΋.wґEq[ kN[2Aޝ ّwhAd7H`׸qGrF Q4>SnlJ"h||IFIw4X$#1yBIoLMx>SzBXtYn~+RX;O\֚2 "bH rznv AԤR~#zdqޖ9ʀz!FW8h\zcJS#;\W*x8kg? uu-ut')"uErZ19%F;vdsєZ#/;ύVii&827V='_LfF=3ıO&:n=kjWz-7vwZ*ár }4~6!k_ x;]D;me{,{㿛W*o ~ cRÞ*߅i*;2S8ľkAGr;<@U k?n7CwMR'Ow`f `nwƸk2[9İ$w+/UDўhn//KHyZ~KOA}9隩v{տ4_B]&H[l)2dsRRI;?i}=^ۤxPY&Vc;<#/f:XN}OӾ/x66z(֛8|h=Ur}|[ [(zϭ}ao})$ndk ٛFJJ蟥2XeE8sYr#X|=nmWdV k4K xwvhk=j;ѲY[gaV5YR$Z0D,y O;_uVbGEn""#:O#Rkj3s(kCHRhnY~S]$#o>!6NԮ5762ZXԜpx{wOeǓnuz/-?qx5aF: /> b9lORv=$N@=ӯ:܉Fm^BBwAʅAb '/$[YGu~MJjc$~S޽5&qY&w+*.r٦\|$DevOsWk%xϻy_Z] n~ޞ#tKΗ1-<Ȝg z6um'+)kF D=는bX(u(TΟpBy|s·k%Yp &8oCXwf߆L[|dHYnsGju&/v/hYKu?ڻk\0:z&tq<4KRw^kŵ2x+ᛠ]#?-Ǚ ~G3kG\jIx7c zWlc֝"]}cxVЭ'+7n+]o Kaq+Cn%*z {~IǗB;)K_ $ drxp97qg 1$z ^Pb'Ͳ,Ϸ ?G7,EkMڟ f'?u5G& VD#!W7o[Kif3/Uھl&6>̦AkE/鷡>>[Qџ[76ьmfR"t) ~;UԣrFT׻ 藌q΍$[n`?J|/o+>͚ɭtrcQ d~> ,%YV_n߇$ju="E` w05vҍVO `<yޭš"r*E q] xr}BM[]`1p?RxP#X2PÏ֎AcdD$%Q} NJ{$\pGB1QxrӢ[KS)@@c 2pЎj!GTE1q~xq\5wLyz=IȖzYiw6]j.g!Hqk*xk ?1V! *Q5þ"!P2q:nK4 ٧Ycp32^Ӧ: -XY"bOf;vү,)myqWt|ku~P@Z] Pz58n;3Cj~wt-u{5֭ T6p{ׇ5m!ħ׹k)míZn᱓czּGĽ[Ǟbm A'q׊on9]Gq7,Юߘ'~ksa mlB*~ GY3*(G^ο"ڊ_vtxa+Y OARc=}A]ZtV`>V#;R{sVńn"CV 'rZ.4$xqj早@b9gv>V4E%D q)!:[T\c;TOҘcʣí[aԾxMu8nByeF,c=2Q]@鱶;m ;7sKhH@V5 ,1%J[ xI3i7{7rӚ=#TkxB>e?bu葶x.RqsoxǺv1z|5_iM"{k|=d!j;#=?WwƖW_?yfdNzwkyZ;6aHP~n6֧ڶ 5̍xR>Fg^2'5Qkx=I9~EP}+Tl^'ݐov52)&z1)NoJskb"lFzҡI0,eqEybD˘>,[[m|H21#FP]Bѕu#IS]|R, ;2HԳhBq@bCsƬ"X9Ք>`Pjs*FwǂApї(@(|ytM1My(Uy E/0́Vn2v_|F$ FӕXqךٙSR9e89JXg޲C2rG'KQᤍY|+fLΊ88'C9GO]]˹"͉/sғJRi"; _Ζ hՅ[yl xkKgPI#!WՍ6iH0bo=qY>ţtBm&cЩ@Kvȥmo(r0Ì4:t@CS#?ғY"_[y#?tR6/Cw K2㠬[k15& Yv88ϥn쵉3mLBnN9W2Gq`v8^s2[FNO+}FY F=j.G &EU8ȖfKdd3v>-/R&, [/zA1x78K$!ק|+2(nb6yҲouWyEҷ("7ךtqMƆ(Kao'5WU)c97!܋fgGEekr=‹75lo&m@%ͿTQ0:!y'yLsأ`s^%xw[O7K\|w.gtgvZ&|h>qNw4x$q68ʯ+NO|}-_&{Lp5}285ZW7&giؿ!$}S^(4qWVGa >d2z41,瓊;[uHWQPķnK !prs銩b{5 h|؏\<1}oKeYl69ꧭigY}GWyb78&6sqa+jhiֿ-E2i[\lu{ŗ*[X2:i[ r_qG.,H\O$-|_M +7e$&a%sEΗ]Jmي>;xWO1^ }N= <޻)%p3W6BcU{+=}jNh?l.4֙4f#Q!˶6a8 j/|8?vqhv]ԯ͐G^GZ3T.%~ǒ؋qyeo |>W?ߥx?k +~&kw7iQY[njwawH"N ;?ſU1! h1@wm;LDzg"> 멤Z}4v7sG>`!>cQO'rrxWvZMo ̭繂5]87_LbߵuKkf7̾ ~3ʜIu>Vkɼ1syOu5N!T#?Ʋ!]x UKc :ɫ_MNqMfm7M u, ϖ彀&`mmnm60 aIͪ^,TJ(< d+_|q[w> DV֮aL 5[{4]drE? ZV8BVK8zRx;L:ϦIp{ykcSl"b[_gnG>5DpKD:zcƓ]JZQ|{=X3 #$7+n"Wea@d֦< h|>xV3{j2gU=:?ZwR&m,C*E+}z]V^ RB3ns(2 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( Yѫۉ_Gˎ7tSMjاݣ:q#^xVW3BD_QklnwPC^:jNqwF ([ڬ,J8ZG39)Ҫ*Ojn-gS%#TJ6);w 㠫fP3@T {CfRaS*##-K1B1"szmaifQG?J&"l:oJZ.-`z1ݍ8ǭHp5R ؑ3KRYf{b@Iǽi_޹ՙZ"$A#*l3ܦU/Y6bN{U<Ҳ. lNʷuqPdk8N^>^N]#`{6yb `tj #hҟE՗\j,'Ҫ">EчcN X)m +>Kf;*z6ٟ̾vm|5)fԼ61/==^1vJ|Q M{A" S{େRN/-r2 Ӭx]=:(5h?޾j5)ylUӦ.-AS7ehx%c/X𗓤k-̍oq\gj?>n,w #ʽ9x񢹉sr>n+SyRjͶH$pz85hI8ڶȹ_PåF&SW>?)."kX|Cc OcrnbLdVpk[]n9-Opzz׼4H%}8ЎZٸhnW:j<;M5Μl_l,AaKU(<-^fF,e?'÷|Cnh)ު/DӮ𰵛cRS!$(\AS >49J ]&`b%3Q7%ʟQ^'i?Z}u`$Dǂ0kыjKs!4wts&;7ww2:崒 w> 6kiYO+^Z"Efp ^V] f )luTAwW@Xy4;rMZhbvJzW/zM>-MRp4mvm oZoS9)ֹG<{-Ŧr5+󅙼8$3?xMV *䕒EF)bn9濴k|6o I5uxB̹ʶ yqɣ-_W:!q$MFs3uq:~[[xPIHaW9]<{ore4(?N)Y OK/>$(S}*.BUMpv稦:jjWS"W.XbO5:.ocUCS9s]уLCZK4 {Xk#$${xK:{Uhn QeAsS3 )j|My}~#-V}kWh ,Akr'ut0ⲽ5=^\'cNjӝOz{bWhEypAj[i# Sݎ2^\V=1O'ޅ])TbIpY \Kmposᑁe#rXV@$U,:M?Ce|?oom%,׃w,>>p+{h'63~D|&]R@QN~x؎ڿ^4;^- Ϧq Xr?C^=z^^GN|׎;#iw:} sgr9b~MĒdJL@H6>pL><WskpT2:7:΅bږ}'6dRtbq;\ϊG|;e>hF0Japc\iu>6EZq+3EV>~>^:6-Xb!V?0X{=]^'춗6K Z(1Hg؞N*whoma1E~Hi^,KH;Hx_]EE|.-/xD)S̵WEt OJa.cm^EOWkZJeUmn}޾xu?_ʜ2F^4(nk)lt> 8Vq 0%Y#Y4˭6gIi+ dgޯAw=l ~ טFp,?⽿ ƅ{#G[yȮ⯉n<˨щ.EPo>i$ -7-tw3^q@[F. ;j<#wt2~"ZA쌓Qnsmn~"qbj.$yxc6-}?8Go!r' ҷVͷstOGu:€OvAxUa~: a&5`}itz>'ҳqi{S& dɧ}+5vm{s{]kh23YLz5;k)`I&)NpGꉖ\H`;SRY+;P_^E PI MxGzהHjrFa=!kHU8וjZԺfl 35iJeep}zUWԕ;35 .)j >¯k+4Gt+~*i30+0مYvjjWB[*s*԰{<ŸϡW|H4-:Ԋ9mwF]T_$ F91ђ;5K]ͲpVՋyGZX 6%S"\~U2xO]c0EqZsO)c狯^iӉZ9?GcUaþ;^go.^[mx{ +KE5r&!|]:f$1]>qi(!mҒ9 ATM7^Yt?v$]-V=yn˥L1 LA]6kvVꐨUXÇQ5&x:tvȾ.%x\Gڲv8M2)-K,ں ݝZPᕻbxš{e ЮzyH&y7hrx=G?4x7~?qTC)apxohKl >c]߀U & e#<zg5-6G/`=I" PUmjKH' 1E,Y] ԌX";@"1l,wFW5w!h_fZS} bD %Ӧ<-SdH>`!T3|Co.O:m"hpfV<6=uKǗP¾#E2-*Es{}־$er>+9h9o|7̞WinU"pUE]Ie/,]GMjrpPxO s q0k/Ke Zoj` ¯IzzMYkZYGY:m%; ;VN_ȒWi޺M%>mBB-FhMkMU*$P62:c\T7^'W*hQЊih\D' iY]_Ë%qkzҥkvWD3jY%6n9\g5ͦTwP-2exu8: 4rοų>R28N۱LYJGl`.Z+}G֫HN@2.zYdS6u'ѿ+؛7e"KIPrK+rhdԋ4_mY(lIW[oM_t; #<>5im`9buIR]&H r8e֮n2Y RNItWkZe$8 VH2AF^p{ /~)#[{iFS~5vw)+Q3, [a5x@Ȼmr09v-tb0b kHG-Y> 5{ۣ[⾕.a"I11Tgp=W9vg %j$wk|%$Vmqn9Q']jy'=F>h&PR!S \I$WNҽ+*:/}kż/▵Y0Uz&(F$s5H2V:+2 KFd8tJ8nƣFٹ$8NKՎO,-I\ztUpOR>hgL+7$L_q|"\ u! T,$I۞PAM=qdm,dD1Q?´yY2V|6!=N|o+/<[uSo>e@X8Z_ien+Vv:~ _z@O%[Y.\⹜Y۵o\>%ʱG?;zԾƲj"n:7p`8?>q^IYEY=kd9'Ʒ3Du 9EŶցdW659ʉ]@ +6- _||;P?M62;7/o~&1!+sM{u 'lȬK8 m%r|#o>|1#wA>-ӷ5NjL]?T%mȑP<ø>VѶK,%s cI^4Ig$L-jH6cz4oi92c$޳uy^-cZhZuDiQˆ8R9>7lگb&";OqW-^ZlVS ǒܗ0H]KRҨP\ci#< ئf\r=oޮx[^Ğ'v7VRCl^ׄ*xgM2ZJͤqLw*X k6t7mka}!x@A=fD} 8Vʄ89cI%s;E>EYThYnT޽9ly3. u%$]֫S5 1vjwفo.Nac[p=@vȇlRx 0Њ&#B`&TOaN5RG) n*SlpN88>jX@-1(J=i0.VNjK!A{ErctZk8*#gMh%G֬m(c2XgHe r tjwe׌ޣZ j:7ci@sךyQꝵ\?)O魑׃==44v$)ތOZK&烳ZKi77S)kGpF7HRCHjyl[̅ț];Nu**pt +1V^"x#>\sSDKwS<z2Q!@Wކ2ˇ+ *r3(zy Dxa n29SRj5Cckej-Wx wZFpO%_PͧObH94VQ-N.orev{+Q.DwD2>R=Kj-0ݧ;3{sY/d(#l?TdH$5@a8km";K6FEӨk6[f^w!ھJ 6[rOt>W_m}F+mΖ$z.#sJ 3jkD aREp?O8>=i. e"cCVSG#!:Zu ^{;I'<ѿO]h]sᦥjA>&(z1=GzGŞg)` r}W϶$}a}קԨ>YjjsjXd*ޟhᣑїSk>9~Ͼ"1mN钱.>TU?G5cbgZ덞:SwăӸ[k0vYprlVٝ.x+??eO::hSc; ǩ3d&=iPIlYk6J`pr+mc\O(vIlЃ[&㱓J[!y0mK y p }R(܁sOs ?^R2mDIm@6&ROR56q .r?SJdIȖ<z\¿)5KeDmk/ (|[ J)yO,BƿJ)>PF=[x1pn$뎿ί!pk;M;RyX`*EץY F6|PC.I͵̀\#1lv==+S?ݫpYc^>rr>Z v09P+|W>#K9C)R qU{M|JӓqbqdcҾPִQFfL(_~ =ybp66) y7gKѽm,ٖ6ďj }]TM=w&ӭQ T )v@OA].BI+ξ+1A0cg!439ԎI2e>kuj47y(OFS@Z&`~CJC|Mpv a+{ʤdqihϧ</nFOX $UO̲yʾI#Ƣ+/i1]pXֽ:{5WTea\s/\8/Rs%_Zoݤ$PEgE-X( J~pI5\\[^Z/~϶i|:Y4;g'p m牮 H`٨GKXS޺pO64yң#${{Ҹy֫OqFzvϐ>#osXKjC0?.~uW2=:[y+YWk zko,7$4g3 =ۏz:=V[$ksF)ɬ-Gb]¤ބ#Ԭyrqꮿֺeimcou!Yzl>:mE 0x$%2Q޷G¶{ː3[w̗ A!V"Q<)\)5nu8 g,?X߅}F&g/ME~J[+6vZ.6w%̤w>ֻ#\Pspجawq!=O5eEonnZge f;rFGJBa>䍘өZ+p}EsZXb`ʲYy+Ѯ./M ^/+<3|[xC+gX lG*FIxn4i 2g'RK9.n-oo&Ig2>0;DQk ~M6G+5k6zͥ`o )/z|$̸w F ӟ~#~cjF!7s0ޟ_Ρ7Jg"Cdi(!C}0s&)lP}O = >\4-JKidެB 8=uIRI{ ~.lf7,<zvhڳ^a""c<5>uH4ml:>.狞ngpz{<}1]|cuasݴ9ᗣC)I&w$WQ=E0i4NMT\һoSu԰3BiuԄʲ$gzH/"Qb#]YR@3lћV F{8F UWO!܄@=3V4Ǒ.|+'WӞĨaI.k~ f8#=0Q'.mG;3)]L"1[@k7qjmym3%8 zWEWQaLp6κc!% 0AL.Xeڼ޽7Ot|ܛ0{Q+{a5[p12Op,P*Z\:$Q}i /ڬݔH+fu ;v7~E#4>qZ+}̍UJ\@I.zVsdȐrz a)Pz^+ѥf{s3Wg6O\WYM 8_jHZN{w9ڲ-^V¿SZmmIi#IA }sȬw6\ :Rw2NrX9?WWۢ[Da Z2Mk| ki^E1m[QvЬt;XG&zm71xMWSjqrBxIDAQ]Inu duV5s';z֍$b򺚵Y/ȈCĽNs$hm]ݍZO`qZF2NLvךˍ3]u>4.qn**.vz?[,$N=W0 l&App F}Hn:YXRz?ƻHo|gןM4DcKraXZ_ev3c 9¶FٷR3޸(v+r4r/f2QI_.`˻9 f2[ df1H285[W]y;Oeh_6jZx ֶ^W  =8 /f/.# :¶FK|ğ+V G5poA<Tu%vRH S>}WxֺՔ؈#0x7_8Y[$QC ]4CQ&2fݪxL̚*2w>m~(y=p{Q]Gůk/Zi$rclu9] ^si9VFq_Oco[h~)SJ\WXwzuVJox៛yvvh `]x=3x|RFILNZ8H0r#Ka['78^1_싫W'fqxb-t/%ń=F+>ݏOD##ۍ^5ZVF<0(3=k{ e&7O`GRpk%(!@ z\߈5 s`+&i$i=(6S"(6[~+1p S?ZDv‘}j ګOuxDg] JH=u]=Qkh#$Co1~2P{ h!4ֈU>p-a[ՔvX@KR)D*O=F9Skqү ve؍+ILU(X1pi% 4QIq9WտϪNyRgZ[jd upGVNAe#hUIS{ %Κ!+z5 ,AR)Ku^{YRFyj%35ۭ kBy=+!gc3$g1?0)v m'##+r^q$)JηbXDjY t3/RNL0u^⏁>&mGkkO2=_J&hz8GCpxy'LdqY))l[MnG2`)+tzAU۞i[=0ː2[چ 988lo"v+\w.1]$O9Fie7_fJ]Օ²ƥoGYb>\@O)BO1W}^k [? 1x}b՞tdv>=|T֋-{AypF<~+C_>#ho/VpJ<æ8 1?ToOJiU|95^ 7w}pj0˭>@Gf?oj+ˣ}:wǞP)hh>3.5 [jk4( ]񟼾w5C⏅j#Ƈ@tC S_Ѯ y,Yr |}jJ>ipa7LQr3_l#|[#Ko$EfilR]vWq+_>Fj[1ӆ% RJ98rQWg>6x~&🂼"ԣ{fE/(r0 HixĞA񢥝läAO%9p;z+"joxKԵ/kg͚}II,}ϵ{Woğ ϘmomGpE&tA>cF!ioYD;Ԑ^?`d~u2h3i046HfVRqБqW!]N[ F[ I&G|"h4 Z[- f˨Gop6#5ˮh!皆ŭKXjo*̹<]Z C2%ҹ/&_[v}b=A>&|2߇bmXl"*[lpIT="W>)! !OntۍU}'5i1tgb|ٵi;KId^1joa~k/dmֲ36AN1cE0aOcZ2K$vib#*Rk@Ӻ=ٺMH.1޼v9Tlg6 mlbN2'IHDq 5(A;鋗R(`Awi9җ8qoWkER<ɵ{90$2MFXt-^ YGˢu `ːW ľyyYn)+(lDq=-ilC#fA;y?Vvvo|NҷnR2NmeEv x-nyW{JrGVvFrՙ7'8~'4P8=L@YlH%Onj糞H5͕dڌΆ&1mパҽF3k:"THu!>.4x\e~e|u[ZZJqq`c_:wj:,ﭼV‡(Ǐּ"UA<-Ϳ-E|?0k+Y΋IP4yGQ?ҥiY'u5]?Cr@F1B1*Oο_7[bGԵ[5\$Wo+g}/gE-O̖ሊ"B6O]3J3KԊH[tՉ:.@qs{uAM [EZױ[;AjOZ@E\.p)raxeCosβ? A]<5F z;Ll 2TXdܹ P#?KxmGÐB. eՂ[ۧҾ'|7ysa{֒]J~_)ԇ9}_𧤺nbI߁kO:>W6hmd"HtaW xnIl)FYm0 w<~Gӟy<[D.Ңɹ6(%~>ɣj5XIpjb94-Cܛ!.]j˟ pOZ|M3Gӈ"7^,<5Wi ?P񆱨4Z[XkmDT!?#5(t=RBZÿֳi u?AۻهC_Jxᧅ5h 8d$*[Bzs+kz >2IW~_7ByN?F񉾸oZ ,b9ǪUu٧P-goq8%>clv܃5ZE%m&q} TA֤uoI>9Ca8ny+h"{tk%N QՁYo?vT_F'z.inƼZ:$al#uۃ}ǵmT"9-W[o!ܪV=@ $aHXMN 7U=9~c\t"+,2p 5sa$|GzvbRD4\Euv\n k7tZ㱱y `yX}Wq]OF/7j:i8[>`b#q-8^ mȥK 4g_p{cR5]2:cyGr2Trv#LCat@|tx?#e!TuF*jSciN}pٳyNyXGn|=uc'o4`&C~~jF4} mpju +Iӧu< Dox@M>Qsgo)S~A5eFIqܺ}jc jYlDdY.%O:zMp"$j \ѢA"vۻ'J!5cN[[j\: 9?I wVP >^SZ.AnVgoijۅNk}YhLb#▖,Dܧ5{IxnDM ӅYܴ͍BKa3\jK3;k9ȔiYɁvQkJ?`  }h-Fcrxn0j95yNl9.J̖1vİ鏘~hX值r!Uڷ |ig8)7!=0z4'Ⱦe ?xzV1N|c2tbRi([8udXoHں r~Ql%,c|RܱUl‘ ݏjL6q;` P;ڱusiU`G#G cф (d^7UI9W:J麅-0`('$Z*վhOn$aq=mnmRL_5c=pg% 4ԉw,fnO}*^dw}s[dյ)흊ȿu\֯]Zm2&np4Ԯr_-d5FNd W}iF0Giu_qj޻3ÚցZ"pA<^G [L*C]%.c7e[kw[7$j`n\FlGGm]h K<,+G{֧;XbTqqcWv*ݘݒ8o+wH+Z6YSpE)v:qzWu?ÿY,uLZ[0,gpke5|gss,PE1 8>wl&WW3vsp1쏛5>~ZT n~sB%F`9zuQ[N|nOlTvy.gFyrI&++̄Gnozk.Q#q8;>%23)y\j>9&cdc,y6'𶡨\ryd^cH= 7Vk=hѬ,JWl|P5ԕ۹hx?>,4>1zf G p@G]⯄POvf_i-g}^?oUHO^%@q%nכ[6O)fUbZNہdVi;Q*ڱ7U˨3Kjʩ_^7_cE5]KI1 a\_8v~!6a1U  ޞz#Xajh"$y{Pd.wܰ֡_:za :F2P̒c@ڍ zgJ3tcүDcdD%slLr@}sYKYu_lZ3ArVԩ|wzκӢBp= 'Pi6AFzN?#PV׾Ia$>xFg"~:U=g?Oo'QxqhWgA;Ybkz/ xZe6?+uat -èσV~?rlǎI^茓V]ӘZ:{y~?Q_~ >:x/Mݦˋ;V19D9q_9g-Ѫxu厓t!d{x~Z1Jì `p}2#t*~8kGL϶;R+cT6H ,` E&@FGqڭ\XAYNFY9[ˑ튋5{m4W l -|sm{E6tm){v,BW|>.#xλ[%M56+4DU ?i4r?Np߁i;KI W[_X_n]|J@#si~y h+T NJbա@,uz3\sxFIiu WRUҽsx_&ԽmӼFO<;vߎm̶ǯ )ynyV+ԴΤ }b?/oTYkŖ2ʃ֫8={i޺Zaլ⹅g}k0~ْoͥ'I}WѺr>5y4k kG}ܤf7t~\k)kk 0e9{n)u{}/ydO v{ƟrK"s{㞕3ÿi![=Ays2yUhʞT7>Ft;8QWuoE+JO_j}qo UT,xYIycr9K +d~b~Udӹm&5ռsiJX#GY3,< ~}~!t\سk Admu"񧼑1=Y~=6Y,p y#K/KV}38"+t"5ݜs" W})Y/VxVCHvr3@/>>y.ws\FYg|[ _f}#E֠Ooy%ݸo U$Z^ߪx|_]m;y(LC<o1my-Dϒ [MVw0~.#K#| YmޘϼU$W]~~5ԧyb2# }0k y7(oYW lTܱquFsxZ™,挐?C\u(>? x lj6b{ێu?GPdW$rW2\9TWBXd޵SԞ^]QEQE\K |xŠiQ5sk6KYdky2( ~kߵ i @. ʼ:5 nm>r'^zҵO} Z򹠞5-K*Y@uڟ]5Xm-Z'u?Xj)w27#.a33M@ž-+w'(A'fZ溑d pk6wGfk~tOq.<ɿu_+u\~=xWž׼?=ƥ nu9`".X gVsְl]Kգ- Y+IA2@#+'P$~^{ו]~? |+h3Ks4-*-k0lasr0SY~xVɳ)wGb>s#8Q{خeKGGopR5;<;YXP=@*=уp.7c#v>C*M F O/k=͸,ܼv凚x8qMݑ^%ٯnNv;aI OZOڛፕO_%eU$σ6#޻WZ_nb5;]Wc^7q^cZ;!-rpʨ Ө}EuPVFu I/ +y`CkF[ 2W-+t8/~2Аr ]Lk׏lDD9teVe\1]ĺGWZ[xM,yQ,8 ;r8ss4gTQ aVE}jx#JVh^:3wk ^Aui<\1l<09πthV^YB3|҆A)nOca57Ϙx&+Ꮗ& NOO4M'Σ|Ex;:XՙFe QK)G, > { &N^)ׇm}u^PV1ru z.jG?>Y8ѓ^4\:?@m"iM,i馽NP~\'[/AoO2^kki k'=qgxC% ˚)[#_U~ ޚS޲"(=}8kFi'h[c|XU%̮c7gbތMFky$l:Dr]xn{`H0U䃞+tYZnBџwQĚIH$¶֤.ǘ@c! TRV"P&cm: FjIǵu)]rcFKp2Ü-4ۭ9ĶX=+Piٻn9~gW%l)7hO&h<[.cO[^{#YfR$Ao feqPIm8xHc̷ kً2Rcac7 Օ!EG=_$ s{c c9Z#mVIvS6.4ƍ-FnG~*G5SCVVUeer`psYث]ezΛig 2<a#RBG}4@)<7qC| ?S]*#WG;-`8Wa޹nll7C㓏]uEZ(K~PAZL 99 .g"4Q`γBCAsүKf Q}Ebk(#)eYktϭ:-BL\gkKBjT֬% HG]߅m7%QA3XڅMky:-$aE^yљZ>ߍYt19)9鸫9mrȮwQ[c$j[?ZTf4b3ON*-E@u"9 Rzt$g幷N~֚Jnln䓌ִ e"rk) qjEݳؑF~nM?kw$1cCfgzb\ݛ@e9 춍P*-ebԎ]?|Zz<*?x[F[-WDuOO56KHY#zWC[ǮZZ%eIl4~8xc7-c~-VмlVF>@JRr[3XM5g47Ncf pp dnWZ3v1,tcKm# ӚޝmRzK_e˖@>W ިsxkO Y]R*v}˜iF J,ќOZi-ѐ'?OC ʠjƺ+F +hyu8~%Kvmgpu zø{=F$mя=Ij_Mʱ䪖GsYY=FHʞVc`H] ƶ#e?4{U9,8aFݣbXzsQ+6\nvVz`ʄ|?5}[|l x g?ξ64])aXzWMnt`F\[V4&$*ABCV ?tq:oòwJmc? {o iQir먹4>d. r>ܨc^xr:KX-xe 5i=_)^& [}*YKhB`Es[sL']f-Y%3&i5SGϏZmk(I3 ?fM*@V-mlTFJT!A= |wy{7l4B 2ЎK=Nڊ(((((((((((((((((((((((((('e]wZ+ɹ~e}3هOo t15-O#1n$5hxyk8#{zõ<Wt&8\1$f8q4=z@pȭL'u]ÜZ84;x>'Bz R<{Tث*y\{F02MYpZWh d"Ue'j5U)͌ }:Sc_J,i&'=N3_ӯȪH;QY0PWm6lLВўHksY- p~>xx#V=LD3W#>[G řT۰DD*Ep9YWsk¿^mJb< 8V-<$+z%|(I7qRҒ-;j^֟Z_gχWPHɷvekuk/~U%&}A1_ CX^k^_jeݙ9hz0ⲧ߳ ~~?l5`8O ;T_u_w[~GOğ66;sXO8#޾ #xaT|i3ƟaǮ+π?65-ncycתȤpErB_#Q\aUʑ}=i&L`W/سDjh?]Y>>nw~xxEm 3Z69CsA=vOZ!`N`޴'֔JT`+R uHm[w|?uӆ#8R4v]݂:TmLh& ZkzZ6O :=wEK;85>zu7Z˺ A2Cċw+GPxsyFa~V=4&Й},y$)v f'hbW]zzVܮߞ th$^ jІv}+eݕ5+U+(8 OˏCT8 W.4Ni݆H8AxZƃq_Y3bŬFw9>Ym}ʵsf{2Oӱ8o@u(s~I7<> ǽy ;X4h3*㜎9G" )g2)eϧzOq.ӕ.qLv>r, Sӊ} LǍxNT4c5⯇iou&E?Wt8=N{{嬗zzpW@Y@1WڟSeҏBp%7I zԦsl}#X.^۬&_+ 6UO;s g^[Vpۡ;$+~ Ь"Ӵk6hA|B}@SNk96[i. ھ_ּ}q⎭"hXCm3^WյkbGu43]1m]_nwƸ@eǷһj)-'6)۷b5LygvJkhn1Mꮠֱf&keKܤcvph)m2fPz2 K/!f}\E2i+c%Z6*[>[dnm}kBkۅkux<^axj;-,B,i w4x\Cpl{\Σ˃"|~"-Fq wHO]%ZSwqקj;~кkiZx^X)0F:ɯ4m}`d^1vz֝+gЉ.cۉ5$co0H ?ƻDmE߂8_q֘ /999#m8ݙZᯈz·Q:mpIIPcy,)vb}lMy}B#—9}k=K{RX̙\>`ݳU+76iEvA#xOR=kt^O[v1q,J|:m[E:vPۄ'{JΕ)7ʜլTլZeHO' j- PG93ֽuu :+ Sj]Ƽ)[NKTD,Ep|ƊC_ VZW=SEixN,t BlaK9iqך}132h]^:s\IKhSɧ-W dF=Gz&+ApK#=Ju~jiC%L$'9 [fӏMI/n20=tT}Ez}~{]k㕡yYXzAoOplBn!Ha;`06e?|fK2%n_uȚu/$/[ϯ]o4G^fi Exƍq5@rQ<ھ&Dlđbnɱ]?OKbM`!Vljt WyY:,`W:EFzt8-5UMgN@ĉay/mF@ IHYr{g{G[?`uS΋<$ҕ|}a躱e8xJ `eƎ;KoF-}eSOԮcWm/䋄X+ŖVv-I 6lAڭBTN ߳w$ -܏+?'bĖSj6zl`n]B25[_殖:)l槝'ŸFVk°y=k>c }P?XA6ڭdHuMþhnH-)R{iMcO TLdf= fca}{ǍN<.#T\dӵ nEMi<=EyW+ V`#Kl x4F2"s漪bX2SXEw/wlhaR̞G_(-+"~sFMpW?mPXtfP'?+0u)% sP/O60Z|pF=x-V%еc#iWh(5K&'M3OҸ#m'PuFm_]vKADF0FGB=2_iϴ\tgU2x$}=Nk$֤ x㊿}x?..`R)G?^j2TӦ6d>Uc( Q~'K2k ?,툉v-fB_:߉|Svm =zbBzi Ӽ~&ʷAE а`t瑁oRkA$lǒoZ;{jC.JȽk: 2I6!OU/K3ȯ-F[L 9-ՏCCKfZ4c Yҁ*2k]zma!ukCzo*R=zԻ b/ Xf# $Ԟܼc] H8BGC蔝g-p!eiDA^QҦIHUIS3Qm45<0rqȫP]4{6Zk[ud@;pjW.=֋=&+ch'eWKi0.i1IV/SGNlDF8<j!#r*s'8d뚹\[B`r9&h׷o-n ڴI6*8꣑[V+,`nՌesHGkV"7\b*W/rGݫxΚ8<+ JۿvG=*ml} m@#~U3 RJ$$Шß1ՍVsWѰWeF`P h'ԟ^᛿ xGզpȐb2>2+Qc#^Р|606П|0ϸ5v.RFr.Q.C4 I6 Db}NIۺ3|2si򥄗WxFG5I<3?XnMtg$GM9R2?#+'Pui6¹uonkeFZG~Sq.Kpuo*52j@RN[ qZ %S.]ZȤnOBHa%5L2{¬g7 #Tc̙<ʶ{3$N2BTV¿~ 뚇 d&v ;)!T fO}7 =?}_V|IÈ7yy%>f9B"qJVrG3O-uoG#IV;^5^%晬:u }~.d}+T28?y/u- !1m3pƻ[Oc ,gV{Kq11dg}AWuБ. Q 2?*oFRYat/8owӚYveׇo:č[1=W,=˧a[9ϟ7@޿27 wh$ &2yZ1-Rq&E|uWmqQ@Qh.$; >_,eP 'hL^c /㡮˞Cp=+V  FҢVJv){sY4ZgU|)7]]iI#,=ko$Fbɴ F ys֦ګ}s6z$uVnA}?ZUQ # E~\y#(Bf|fχ%7cu/\0Ś­gorAx asjCrRS꾇5~BX{G{ &=qwl-cF4Y͏*?.qqhRLMzF\G nkg%pGGOŘ/.̭(?eÏd8>ԞjJ񗇅ݼpM '\fϢc/4c$'vhrw?ޮ[շ2ؚ1IQbxC_<ZA$t58/=^5O|CeFO'K:0exă޾ 1x xɚ <^9xmoZL'#+JӴ'/`e1,n :8X+{MӜ Kc=aWɞp}1_lkP8_Wmu|X#3VT.GQE@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEV+]X4otypZޢn.M&%Ѯ|1aj!pڽ^Rh.bYc=oq^kO OMCk&=wӭͤ)сOH+>+Iʱ=v ~K,ops`6suvag'dsj{ q`N]Q||9<bVog|:2+H+Q4Y⯇$֚r2r3\r9_\YcEiop>wh^+mSkrK$OTGҢ-&\5O'oCk>[WˌЎk5̚_ٴ۸*[qTocGCkWFD01Zr=.zTg>d8GUYQ\Ih8'+k`ۂ?_Mgn2{sU;އ2UU1.kͫY - <:q?Zbg 5کX\`!ԌʖDGQntR-kB>xq5%eI=I &3>x~),&Պ\qy}<~t_-m݃=GQ?;`Ǩ־߆>;k?"t!tO|ڰ/{3J~gpw/_Ul)-mJ3uaAᯏ5HDkʏh^w uWՙ؝V_)̓hw&zWǷ6YNtHe# 9_ f|ck]7oOcJ}z~KzoOͅVBmE_N]'_$U7_{ILW C0G~Gp+BsV_Q޽$ԕ՝<!!:TgtLuY@9B2R~KssE%˜IEsXZ2DgK$.t>A`x+X/s5)Q{"_ = Oy` qV%ͱ#4O`ĝAw/֕]ʌZ>~Fwa<]HQ`Lm3V{M =z)b<*5BÎ,kQ̃ 3,1[ k?ai ۽aKYOOn3Ym~sY8FZ}QĿ>3:,>.'$6򛍧&\pck櫏_0qy4fCBv-I=U94ud&:1 u$ަ7/.2pr'1Z,]#@dy'Xd',LB3:џ߂< oxxǓ*Fw\9_|C#{S/ xd^_[D262NޜOJ𧇄~EzQ2[>x8~*xRն4g;2c nj /5$ .6k̥U6wNNQF|_ӍBc4X``8ZZOZ@j3D?/~2'Z:s%}M{z3-khS*W2ܜ淩:qV8/RּixG$QK+; >gGǏ$G4evSddk) k \my2y~|$6Gu [?'[쵛4e-$#q^q4ŷڏotOX49= )ݭ6"$u'nOְ(aQ@Q@Q@Q@Q@Q@?ĝ$\Eot"FRG^i>?t$6E0UA5𵶕mݘt &֌=?*$֌'y~g<Ud8XdaMv kEgjz^ya>ިˣ3rڟ- ?ۻӮWeX29 >c??3$G#?dE[ #;i.sĐJ&6%k"RB9R*m,O_6#2Ry5i@@8۞RAy8<X'8#'kz֢X"¡9? ^-ԛ'S"{P-d9!E \}aJ82zwNśkּAjp /@ ).k_]Z̯ul#I |v)\j"OD̊yq^ ̚L}C !K~h%҇N: ʹ'OSxwBѪ_6mlMaku7v8" ~lW9d-<»/ x=Wͅv%ʜxP*m7osK1^a)P1a\mpI`Ewz܉?V3q:K\ì[]JօN3E&xN[_ xDe.|5Wt &Sm&V=Xq2I[ڤֱ6BxAοB][xrX0R@_kfWe!gpD@_s'}$Pw΋^)Cǟ&[OY[ioZyq9bϐj}km6at` 1@XOڗx䚔!HFԧGSsWķ7S_Brq_,wKF1KXp#2d9eSS5𳞬zaK5Ȏx>]T,7EtjQ=KOG`S| l_Fs8 k-ިپ׬epcbt9U}WKMZnF$4u_,q}zWH&1j>_&ג%u+L:r@{;k,Csn'Bt=W`Bx#YpdW\cD-5qz|yR)oH_S֬xlUa6l" I>hhѾABp۸ǥP+/ t=}F0b}3U(Nd J=[zI=Ū$nKD0zի[DxIk}#P'.Zr5ד\vAu՞E['sw>$ӷUmv=1[zF;%$(パY1c)~@9O>ljS3 PݺTu_CSo;*ăJGF>_zsZuHq !:0FOm N{p T̖' As]Xȸ#g\RSRgsʐrj{)xIouϵbbi~W_*}轺g<`̍ p:=GMIR گrR n) ;xW/|Ԑ@>u;OӽPx$r*7qAx vyRcLCmI*n<AlTR'~=Aܽ};\Ut!!H;XJC\n e )1Ss1^"ؑHϧY/j$%}U+t^,:LoġuVnj$;{QqXc s]tfV@qCk[^ےzz'xm;W_dfs#h]Nya=8N/"3~m# @Y.5o%- O#h5 Ŝ6(H( >'꿳gonkXTK98e."27;h}cծcy`^u;{dg F6 z5>MY#Y?[bRXrzWޏ'Nִչ5VXeSv eֵ;gD*sI=Φi[oYO@6\]gχ^K G̅<-X񓒣>⾫7f!L.rs[J1Jɷf{v裚WWnb:d`-^MQb1J_=]_k@lH{ .{75m-K5?:K^CjȐd'Tw'W^&fw&{3f>#kڟ65KUGUnUQ0B=I{xdUcC+k Hcs]Okox{Q y:(h&^Z8]WPeV贡0 F6Ś݊=$Ύ 6ѻ?WLO$ʝ>q;ZTdAA?&M)|O6ҲKnhK8,~4nVuM$0oOz4&s7KZcF}B=+#S]*uه=AWnC~"jzÏhi?UZh$}נi_LَZƾhx^sOq&~ s!R:ƺ?AZhqK)2 ;*hY? 3)jϲxDV* xWޛ_IAҟHz+z߅yO$iZ #zT6W<'~!c]S (jGT+FZ3ۍ1_ ʟAh`c-ti"ʊC)w#88Cƿ@eIzKS} i J {0_\r[\%[2d>Sˆ%IN+|W*1{ mO9w_Q]>Y5 &$Go⻡Z3YSv%lv0IP3ofjMS&2GjF[2PgG`K'#t}jGZ0$PAYoC~4 /84u`[˟LpN5RM,yN^&h|NUV\V:u$3@C$6V _.`f:+J;-cIb+$/zc/v&tvd'ǨD 6 &tkZ,ڜIjwD2{}=W,Ej4~܆'yr"\`[kK7"^!Wvj,H# SkPpvgTd0I>=6 ȝrѺWbgMqx,ɮi. #=ӟc_rZ|Z!$ܮtrpb硬/>EkEbc[1?=U:gsvHdFY=>Ć߳>*KiG˨Y9o5ğksዸ5Qȷr!O>[)єvsq\iW5ÚƛYanevhٹϪ&vR8UAnګ`nNV)X.RqY=+p(^h mx5+G5%!OL1{S_;$3TQ*c5Y % ނηvjVw@> O~¢MǑD- J%p)ⵊGˑ |}ned:TZAү7ԯhVy.*yk=VY\/9;TrO5iWcB|{q]>_.lI!YubӶ薅d|+֗<#@m8~U@RwB?IYpy*"1<t_ϱs?ڻz_O]5[]B%+pO5%M=qyjׯ12Go ?8i%i0W5Mj+(-'T6\9|+F^ШK]o<&u]G5,ԢG\+=JɳnVV ֣N,nu^] W%ʏԿbTKa76n0gN>_5ax~]c:ո.]4f=}E} yH 5]-7DÒqO?i|s>:]ŖJBϡV~k+:PI>(QE ((((((* HdU 0}z(w G"'X4W͌yɭ/?w7?qXڽ&⤎ 8ɦSմs/d9 OJjA:%U;nֱfcqX淡&Bz^$k4Xu`>okn& zx~_Vcum<0?jR)lTix<5}`FFJnI'{EI-mH$F Y֟)pp)0a~AWE2:pdƤkS± M;8Pd\HOJq w(Gx#Ҿ5.@2y}k|Ikqfy)Ǟ#OV#ަe=%H֥"k&YX2W(3-5,`F|Px^%p}1Z=GQ9>>~ x4aVwr&3=B^z~5lAq+Kxה3Fq}nЦټ{_Oκ$d>kyS`>W 2OJ;xke4T`qZ?3rJ6v:"W=dG>=_սzX`ֹ)[kl"F9'΀hsL b=T84sYn`G(O5'"ĽuʟfqHd7meM>h Q*޼ieIJvme+iZun0j V9wZWk尕a֠}}_״0n% 8evl~nR#tO쑃׃S*S&-_wG'˟OjB(x=4^w<:<`W^x-fkD8"}CU2\G_KpSp9ڼcN?J_R@d:r)#jiB/1E-fGm!%q~ھlSa%pYO8=%Mcss476cGbľ;yX1_A;{Tj}r 0-If6h0SSuk9M6FHA5Oo#,)Cʷ5u- =S<߈:=BwQp vwHmg585K3Ȼ'y2695mNfnϔǟV!/[mG$M-ʷkEl{7y;)Fm Gj$Y?l0{|6NAnƩGTKw"]2Z@N>b;`6y9 r޵O_IF?/F*;f*bne`]z:6⯥Ѷ>Sd0qY>cqk]/z~6:݌W6f]ȭ6an0`'[ *͍{Wai$Wdy@+-ᒤ:"m"8پB09U-E:*KTGR@l}umc x97SWJkn qMFXzMfn'pj[ r9Mɀ+9cJYͬ9RzZDsqnmw<*~&tvپkx 7GC?j]!`h|G=n#imV`kT7 wdov>>֡w_ƞnX\$@;G[s{f|;\\Zek2tUN 3iQ\Z\W~ԾE޵cjd4UN?rs_).7v6Di1eoebL$J6r҉ď:>X%#H^@[׏|umVyuu> i$m҆?  ,OAuoYsi.cF")5j(JZ׷װúasDk3xTimo8;Lsow 7daJ[XwZƖ֮FanXnv>色HTWPxMrmv^)|!CK(. djw,,^,p=}fxcJjv 5dI>'l`NJ^hoجo)[}I96GTa͹{S@-mҽ>;h H#cj="mּ{?Ǵn[CgY/9\̐r{v^mއeQ~uK"idHlpk< (5 Y""dF(r2ڶ|#kF]I ,Vk٥IźDs@d?ZJTs&󽇉#&N'550,;v#ֽc F7ǃW/x湊Z;uFy+돯J. JHM⿞ɧ\"2q#ۨ=_K.,dh_wp{=bOX]J5 U6Ƚ޸_QlI&`s*ӏ(j5-]<:k|GN #i1_O=q;T(?: jsG'ͼq>.׎S"#)Px;N΢I0y6uHlbi[is}ផm.$@e X=gᶌ%߄4ۅhby>9%WzFGQZ((((((((((((((((((((((((((((*[bHU(#12f^el =Gj#YQ:0R2}<=ޟW{Q]'IkX]_c>/K\i ̈8GlW#VUtw)ȯ{+.U7Bʺ?"+Mxiڬe12l>j¶IAiNJG xϦkH|!Zl--sGS_exgĭ[!aW;3RsT,H'&E(X֧\i28i]xV5̷Z,c-rЎQێGi_=kG;\#'`=IeϯCֻ)W#+(PFچ[Syl~*CúƝMϲ[ykP$.I?)Gsbݞ$=Tpjp =k5NH䎢6 OJ,+cK۞2:ҝms6|`' [zڔ%y:ƞ[)3(ܔ'PW/[6hfdϡ[jx^K+wdx;5OY}+*DF CM;D7eROOq^G S m+ڼ"HZFz+,ܝS()+15)*d!%_=wޏc=6kDFpAAG"%t\4w6IiqnWBU9>"Ju4 yv {θgAbtƪ{Qx[cs yn5qo*qM36qcw,8h| sZf~ *(zqY7?&fVsi!]B=3f/#nͲŌ_!囟s''WĻ/~tzKˈ9nR?5`:cpGE| v[E8ۆ=}EzY<^>рqdec.~nUs dz,8}('Ah;O#LQQ.۔1fAwzoKLyRS$ >ǭ '2U(19 Sש:-AMA,GĈ˻)wqQ<@9ǘSnSƮjnl-69q6ܢq8%[\I0#rA^W0`[ush1a4 cYV`Ӊb6FFEVS&ڇ(݂'Yȫ}WѰ[ RyyCݕ_JK0j s"{Ԓ=?W}փy=c,) |b6sWnoz{?3MxevLޞ<.dwӨՎO?ǥ5Ԇp@k?'XvGޒ&1_E|<_x[XtG n.'l<0QCkUAzYtĉ$ =Cȯ;4:lZw|/wjP:6CNrO ¾!?c_>/k?=.nfb1?Ǟuqӵ}eA Vv#tu;\QKe3Cdtxl7\Os7aV>(~*WEIoiG.lU2vv^3цζ˘㍤ F <~ϥv3Z\<6ӡH]HzU:( +?h_:g?2iEas os[f 2y'tgQE(((((((״hr>3/Í^yJHc9@WQVҲ!7vyE $- g5cJIڰk^]7lvCcbEDP@R(򕝡 H'ްo/f ޡ+jV`)]6!*վiˍzKX1OpF'yvnJơc,?)+95LDQOkʞ&Q2,"['k[r=:b#G$>²n$IS۱m鋶6ksXY2}Oȭ ‰̛Ak<56kd]Ѱ{=kl#Y.yZ-. d? 隃m,І թo-25F,,K'JsBĮ>?urIg3Pq=>-?w^W;ve7<6pzN/+?O{V?DڒYNqM}Ev>n~oymV{P6`cXN%*Oa\WEg$d +/i#Ӂo:ii@\rqSL>ѼW,L29f[.dռ0 L8ǘ1nz_\ZZoq-`jKO4>yDi c|סYjp s|.T3|~xM1-5jQEu|˞?ʒLJZA2\HwW|-7^J>g1_Fi햳hVQZq-04:8YfQ_6%ǩb\]X@FE>b;}k3Ci)o_-xnͬەrlvǃ|cdMF6=3 nتQI)8pՉWN@xN>5?i`e4EFRW#o~&o.?نh!6 {^ C~Ŏ{Y6LAd pq_g+֏)ev@\w\.fΟX問P>Sֱ(ZG)y&Fr1"dx5.#?rOOƾ-'[BuMѰa C8&kd\'#AzUM۩˩ǂ|fIjɷԅsⳓUVRB *+Uw\(.Tyu9B'@upztqVbbbT:rdrq36.'Pю04DE6cR<&aG$Q$@`Ғ&j: ʔTӢ$Y{NI ~u5)f26x(l lk)*FQGP2;V:Twyrq1c+H~Ga\*orzfT:LLW-K/Zܜ,FyfFGpݿZFE˞]*G(83E]T`cv>lJ:)^83ORNZϚ4˙θ AQIqG,0<k;S>g)Tv~e%k>[mgG$YAAm;IE\+g sU-~)1ʆAF@>T~~4Ͷ6dzne#v?$~#z?EBL#Or~+~οlu(.ޞ=^36َrB8ɯ Z1gi7q_iQ "m xb&A$ّ{{'Fil(԰Y:d}k 3vZk*p #b;`2t#;ҚqR>egBF&7#x#ֹzsÞǵmJ\LhЅ^+ gZRIcc$q_EjEn[3aSІ? #$7Oj\ j(t:Ujs3tZ9#s7.>~ҸwN-wFLLYmdܳnߑkKԡ"xdȸ$JܭmjyE嬖2W.ٙz']/akݵ8YIN).c_Rf-'@Bk' n3]HmcRoi?1Sh \u׵G+߳i|FSȾF!a?1U~)RfKXv88ٻo kF wξTp`}AZwHfķ1}~?.utrμ#,#U-.n\GӠ;'a;9.uB(s¯~*xLtc(}x2_ιfRV\3qϷ>ԴaGw"#S9=F+oxek[U g|_㾪n c:1ϵ}WolnNXz%oh#/CL.,qAJyqd2b+wCۖŽF@x=׾$ZiFVZz^-GDyuZ 3~6bc<k>igP\iv y/ecLڸi:nŸ6}H^-յo\\zܟjv.jqR4<)?ν'E'Ɲ6R[ wOֵELgF /Y^mv7u+:uVWԽϰP.ubBNNP'z9X6U*ZT|(5\c_!YXש,29@Iy^;MQ]faEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP&~#4*>@zz"G*׼2R`޼źi)k/@uҗ7jvW7 lGyi1uIQj?ڢyir޸ZŲ˙0GA_[o^ԕd ~R;#^"~tej Z9Z>Het ^!*6\Fr(~2~ӧխ˪F`Gb4{fu=q٪١h7~z_i$."xeG;+juOtŶ@ң;szxc >VO Q%ots{?-͇'˘|8?NY}jDqҝnYNBq8?oWVD1 :8n4{~T|=Jޯ ģm͙$Ph͋{Ze[|ѓz xݣ`T{C? C+_O׌jjf_E@c[=@v#} '7xOGN?Oƪ,bY\,p1G5[ "xުÑ^< bӼS "GiQg `dK& žT"P ReS*q@?L >9 ΕC?} !o]5gC<|9%g<+vd2yc=n?g+bqSj_mZ_xYIl.Hyvg/=>̩ʓu7rSVKA7 q#<޾9h3%;tF[s^p;zW#G hBT sSWG$"= 4sM| z HFr;h<<0표b\#HU } VͦF]"ژVuT{FX8 qȩ`N?#UY0ihVܹ+M"4|QeO>1P:c \g˨VV)yF 3z.6ʷ LaeV&0zas(scޙ-:uk+ yh]VcBp#ק5w'm3l/HM- >g*u3!xߡ{Id6#3ZF-lͷ$ w>5$1H l./5I"3جj[f!}bM&{y_|֡|Gj$Zn4i.,RP! ŇooA<ІO-ej: !U)X$.Tn쏹QzR#)7ч\Ov"raklU8le<j:jGMxyӁ1P`}jmZ5MJXyqg#r}UEe%nlҴq~fC=Ic}э?>(Lȥߴ@ӴS^Ub?|;d`W%[SAh<:{$[xء o}̐_o]}1\F2,0XdW&sj0cV`_A'^36<`C#/=zIWx7x\ih'td:~+ہo(- TEWƱmRy/yQӚ<+DSTN^ ®p}F4G&sg+SQ[Җi4pY_|-uxCc ^ ~fl,kO{AXcHV60i|`HW%Zлmb?"%2ǩ?iM%(`ǯ5x%+-.2"23֘rߝ--䶳`情r0H8 f]gm>{}cOmd%&!8sI b0S=zZŗS^Ч\+s|C 8./Z 5 5_ 0wis&x@xe# {b2W{O/YGֶy%E8B][c``F`}+oWL`DX~EZV4@i*ywwk*mbO=ΞgGt]\>F^C"S-%r{lq棳+_zyiq_bz=eHq]Oފh^P[jnGCۃr؝%~mr, &y88B777r9˻gSwLJ|c<1`h`cHD#N[?-L Fe]KQj,cGj-Kvw_;꺮gz' S[SeiNLXNj7[(ޕo\(:31\G[J59vݎLkaUiIkr$r vP\+*eq.pm r>j~J9uq1\lYby3*']krjv(^MImlwVyXt5tkf0Yz]&玵ӡz 52'TzeضҴr9%}(MLeQuIcS^B7ݣV}xPM 䣾8I &v @UdSihw5圚+ZdHW;1^ubŠ#6|i?]_g:V2HI%_l{W՟/O~M#b"r i9RAqN7錭2J18/~ ]cTifX !pr H緕eTʲAxny77 }f)$|fѰݒ2JOx:fcȝ>՛[j Ȅ+'>WzE H1+5%?O"Tʘ pz`k|oJ̱-ׇ-L} |־knn%w,z=ga ֑[S 0G9h7M8Mhq kEc")]tOO|e]闐-<6Zv d?U x;]R˻Q,kU)i|1>?x]i"v~.~S[3;|n,+d*|F*Â*յIn#RKi~#x~0ֵXԓ$yUforG[*0zDb2yS}ZК%l"PeA{U?R.ehFy֓>XWP8Yqly7g~丹>n`sW:G/ ӧ^ex H<*Kt|bYw'OuCfʈ^g_nX@9vH"4;X}}+N$A_+sT/Z,D,KKUtѦ7!c#=5M?Hjɑ L 4ռSqbk + :ӀD%Tgigֹb6쎏Gy}&8,C!+Shڍ d `;_[xNkx妏z+9V߳AXOsT*H=8X,{ub}v`EșRE\85i99p8'׎i%cT?Gq Dp@=~G_׉gastuI9P}^ Ab&BI!GA_x+iv;xn9،ƾe>(ӵF"+3*H]Q[QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE =sLѱ+JiT&k%C*)jDžuuVO)xHL5;  >kXRoO%sak9c?9 n}|hW:Y`~̷5N/?:y)^\Cqr=<觬OɈdhW^0GQZlrNvx5:C~l&14r)ãA9kЌ5(JtoEF?$c-'RğOjs$߼^ Nb,88ޥui#i<x;X÷COCcTb'ՊZ4hnUYO٦0xpn?J֭ QҵlmlApzP;dK(}S7A hRRD<:^+rrOCm27x:"#_sI]u㵱}v& 7 ==OJIH[)>GqCSk^ e+9EO*2ܫY>evTM:0UZz>(V}P~t{}* X}NT_XzR0jSsg+N=9?FNq֨+n޼0OZгԼѳ KzY$R"+`7} ?w(UI"TҨ46̡HncR.ʈ7?- !NU6? ֲ'*{Բ+>4 YP})z N=k"0ԂrqW-g1jx&쳑n@UPm`D?34Nr3/ժS$2\H@UQrlE#o 庙 tKqE9Q,.m9omk{#I=I55ҰQEQEplHT1r?EkiKocU%cqǜWcq|nUá9K+upZXZlݽȚ~Q'5ϩKhZCtΞ`q̒>gnn9"XF#Ft?n5bbn8nv5Vw);ujFXf chʜG,OrO5*)k7G_&2];buf5緞 {ç7Mba$?fߑ׺R^FiE{I5mBYcSsɬԅ-M/ZKxs%)bz >%\4>DV0xvf8/G|yUQ=ؚVW bdc5KS7LZ^e E929&47rNEekj8x^/m{xj%htĔ`m2~ 7-c Ǧ6:zْ\}2?\~iv#یI^RK(JpT#5R\V+]M$kk'w̲BWe@ oBľ m%HGS"g_Nj-W&e=?5φZwo#aV&YcDz{v5+;'ŷ);X» $Wp+ɭ?/VyPՑ-59ta%cNdp2x5|&vqD$"JIX1Ztצ -R2"`eb J5f3txSg|[C]VK*z^a}F*3{WڔpC(2<4fAltz[mX2ad_Ȋo:jx+IWYlmD2+c85v<#+y$9yG>y9SwBTՙ_8MOXyl=ȯ Lդ7GN `"W&.bxFqlP̹ u+viu1NCۋKE 3¸^@Gs-Uj܌~W,1_:P56^G(km̝:RY$#ʆ>|B-s+38'* Ǧ_\Cptg'v+CN38OBVBJ$ckоkV;N}veA4g.jn4949QEk)WI%%!tym=Q)^mR]Ar\6YMQ_CQLbF#¹f$| 'q_goᯟXC>^亷c9kb5:71C#XQNjlB\7!.'Y00Fx>=Q=ilYd@PU8Бf [ qcb E`@M"X?7W(\ɍUb <ߝUD,[<lL\+r;]wsX\ Mv9P6EvVpCp^x:GR3CqmXF֡RԎVڟhg‘٬)%k&0UW~nn. sR>J$Ӂ ON{ |I<Y,?O"E-ʶM Xo"=GT9@<=ϭY4]{J4NF?z6{ffī9]hj7e :iZƗx֧]FܟWtkw4̗3'`35i9鵈__Rj+d6I|?xkŗqͥ7o1 W W ey!y(pFAy~@|?bm(}*2O_2Xl!n#:]§2>m_7>*%P"XʔA 1x/DKiWޤuυ7 Ztmmz1N!JEMDO%/F8 q]P'јIJ,ц\0A-ʲEp0v'V'W~떖ptWd-L1]:b-$-Lc9k=`+[,pOƑD%S{JXnjks@NRw i|L8ZQ!n 8 \kC"ѡ3n7wPxx8#89+(j7pFFgG8}g\ #IulWfltS:=Ǚl!̀UOFKaa0$Hi$3(ܾ]%`) :`-uφDOdϹ_j^jj6X_[- ۽ [XB;ڸ߳ς4X~!JŨ~/ٲ=t2Ŗ$LVA׭uzFc`Ic85d_{ȟorɶkOE{:JX^X[5u)+5=F8*$uWο,Tү,dpOo"(;=Qݼ.L-`IN;.Cy!{⺌yKuԆڝ18} o:)$ۺ w0Z6cq5KPeOӧQˌw IΤ9=[1,Ȼ]w)Ϩ~/?s9 \ZBOr_F2GI gY) uaN9jVSWGT=İJ6n=̂((((((((((((((((((((lj[=6$칍IciY.W !'*]1mn :W=cO Ff̭fvaY5F畧$)=~^1o-2]j$9\3۰+xn2w2xSV-ӧ\Fd T2 3?&(t}^v 8zǐW]vk<i[XFRP;7c p6WڶxL!ERV55u[߅:fa/dpV<ʽzNqj暶gAMLzï룵i|Ko7v4 5<'Ny`[ LQբ[m^-\ Mz>kYORפd1ZŜ%=N^ƈM$2܁$G2c#b1a4VisԐR 5$v]Y :ec##_mBG)sOPu_ucMy$^Y[^ʙEs'{|\+!0ymPAi.hU@lg~+sq",Tr *'SaoXy|P|q/."W9|{;,7l?nު\XwMs/V_o@*M[jvEAȿt7{zxzP*-#ge~0dC>rZ|DNykl~k |u*<}3٬!ce̒#k̠=B4QIN{_PXh$s^$HO;#ȼ74c=fv]ѳ`ǹ~U%΍y?e|[^h.ln哓﷎ֱ5^dдi-x19}99Eh kerPڽ_zJvRZ5;i] ؎W'ͼ!)t𚂨cq$08G047ցI"#Pߵ|k!{ Ip R'}O]|[ w״ VK|(=9$iz-2BI!Ij[x~kDħk:{ׇu/_ hdh7 ^#垯ruE+yk1` #[ͧik3!/YKeL)=z' IsOVAC 3kƵ+2R)voVUsv N;|؇S( UDZ\۠ D tWEHT ʢnc W[nR> ̽bc>G¾FeIWmb x\[ zm?yO#shlNUT t2I=]9b;;K)l!2@H@ǀ5涏>q%xel0Ak< {[[K]N8-k{6r twoR)1SO K1գk~9_$˔.|xd%=}(2v4 252@_q]3SCE]*>$Cgzfۀd֋roƽs6bwo*#|c~:y5֣]L#;I'$:з(q{ =<#sjJ@ތˊ2oݥ7P~ׯ'#&9ZI!p#i~ػ|-ӈݜp5RY\rA_4ﴟm&!=ޝ& qr~ۋ6VކKB6X=4SΓ})=,RY%<TuGoΟc}*!ʪp-,".9Jɹ|IJ`zmGAerF@֝lK#exe@1ֵBy'߽(uEKJh ,;UFb%NzZRG5reaӒ˪(z[4H3:/\W sn.RX~eY !^c̉q (N;jʹLQ#ֺkQgˋ/*gBz$'f~\#;Ԟ${cP{,b:u[w!Tzy|併ڰԞ}뾰9"-cNӮ:PR}[٧ouhrw;}Nkh\7Q;l6{}@q oBG'*/|Cּ!i1QK7wFh &tڕM5fy8,YrkwN gK°ȧs"l ^FG8_'ӦknU{".vwp_ Bv s9Lw902{S5 ա&gH#,@SOTKoas1Y*uymyfT꯷#NXE61فU~)}'º|þP D=]3=k|Gm+Q6.֊Px=f6аjm(;@kNql sX1W-+u;.!}1G9 on:U? [9^ n*[=eR8f]&r {o5/tlbJy>ySmbG]zzb:.N9=p+ekƗDe&&nKa5쿲,"iM!$ ?Z櫬Z6Gχ[8=0p涠4t9 2+;ezTک\횕GcHfw|=H5;TMC G>&~6q}B8Վ~ɨgvE3_^;zPؗ-˯OI,zl6#ݷǻ\ e616x ~⛣LF`FA<70޵up. BWڛQ R(x=2(L?CR ҵIܡ^()m㟏'^^x'On&ud}P] moSԢyDR="~FZ,ڏ5mmC݃ѯGh%]iӃtѲ=O'wW9IWʟx{QP\,R_q(ߟOg^f Z4o%`~UQߵ~x?pg?i3Cy,& N?ur=}xb#=%|DI;OnZi77m ğ4c ~5օoSԭ%b2`~Nɘ:eKyJAqZvl2`뎟-/XҤ|mc!C>i=4M^,'˂??:!hq^X:+(((((((((((((((((((((&YOsE,*Ya/כ]m`+C) zO]e )zU&KW8 {˻R(Tm_kn{R>d+g#>ձoؗ{fnH΃izm!.zP#҇~rZnֺ|#n~خOZNgwY#q^i?<3Yjzj^]̢9@IA )<Ν:K,о&FsCџr㦋ah|Me}"Fe'3֟maޛa.[ˑ[h,623_'|3G_ŤBu|˹y) 73/ ݕ칲nvpx#3њ#M?ý"DY1#i זxDot8`pryaW}j&ke`|0fbN}wQԥWrZ 31~8ŒBd=Ok6'{AErfhIrqj̱WO8G'f:e|:X 8T StwIYBfIXάK'=GDrm/:tgJ17#!du#4 IaB3izޚ֟#k& i F,ߵ_b%auχuȬCq'4,VL =k 04:1*[G? ־%yL[ ѩA$qq:tQmI4LV>aLur*Y’OnLm8\tgO`}VVAB*8a\׋eM5\x~#i Ex;y2kb"9[zWA[ NS(=;oiat1X_V"]|0#mⴖ2$ Fk5]KLav;+YF2)BD4kdi<<=qOuo4H1 kw>x#l+(Xrg{q"Yל*4y[^#v۫`[0pQ Xb[=oBgEir8^QCv.b3B",@`[<jn{[{fU1N^2ҩ>ĴvH& 0 ۝F(>OJ>ҹفXW$qZ-Z]MǖU9`Mh[OFmzY@.Wsթ1 1֥̥ 9#׏LhrDW sWA]g%qk>;..-x֗@CJ/lfrв|?_+ lGRpe$g1&?Jm7V3.~P{ ޹7]!lUxҭˮӶNGX@XW~dV힙q _1 1avԴ h;9#z%5F֧J2դ)108-TkRC`01kxdgo>@8#die\P՘Ӻ1u7+/p+wVO1*wÑkΜ+_; 79#J"_2I,URpfspG1$s xaiÌ5eyR$W6 ^OD9dn]}ُIN?x)K{w e]Z›[%mg!/!8m9Wɹbl~c|2|w]8j(-3_%ύm[x㺙:"v>W>mM.\/-D):Fקc$ F巁GUo䦼H{D/%g-B sk bGPOI1~C3E {*[x>m&?y;N3܀3^K#DP^NgǑ,8D dOzqRP{rMdx>q oi 0 1]p¬j{[zk:%O%\utM7PtKpvڤ̦WV٬l*Q[:Dl  0}%f[4zq\ok'kI Wp0:&%HXA6ݬn@pW4G>&څ#w_zVҵ ZN#s këmyxQ&c;6~Lq*mqF2_¹'M=boqk\ʒ,q]uO˸Zb#mEM^;T|&#:H#g?Z9E])zR.CVme;GJTb5[R+;c=|ooCӁmlD)J{ UOOEo^…z,~;\Cv6V^z@WЧҦ#'q[k֫Һ(jJ= *5p5oNDc#!HH+o8g$w'$y,EFJ5/UNJ@ +J[?y81){y%PrjEp 9 O*Y(7MQտO15ψ[u QrPHc^LjtR[+o%VR̟ZkAUE]ؖyմ;j~&|oƽ ǨC]1k&szBA?Ϳq~ZM6-_F~u|bUJ:Fڂbo@ê7 yI<ʻч/$W$jE? Oף7RR*[NMoL^Zĺ=Bx*+KR)?\%tJסsfFJQԟQNȆ3rx6YNU.O*M8i1IAv5Pq\WA/ g$ygpÏ23G)$v?~RݏX́V_Nk8td xEe,r@+~>?hOY͜o_E7nn8?ҹ?ڿHE^j,$?!XttbJc^#[ծ ާs,s ;׷h甞Ҿ*xN֯&'N {uڍ6(8) # _0_^8?ʭΎmأEPXQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEŴWQ@{ȺM>da:nT?P4wJ7Fz kxfitVWR>+|%=A9#k4IN.ejyֻOYpPKGI{;X+}PE!ȯkԿiU>YhZ1-[Q-gzu/D5*IlvCH<9En쇗d*hv>׵g.#{+!nF gbp8 s> m6Yu Ԟc#p1>Zr}AO5FW?$B+/|=HZLKaQzM|ObQjmݼ^EV/?S} 5~յ8P}n?n3+4Mȯd הҾ??n?봟Κݡt?Kf_ F'R:G$#ebv g{E5ZNy_eYW +;A ӭ PGk ʡy"*,3uy[177Qm?UT0Wb*sY7?EyF8J誏);F8#7ST:<mI$`5`)S=+5-2FA<^ @sֺ ?Ҽ/{-4&u /6zv,Q9 T+}kGg{OZM[h̒ZZ?_]A u2,o'g"; Q~ٻre;JER/WQ?P`E[,r~U'VNᶸ-JnlsWMy/{#;@󭌘!`OOkd~!oal|8Sv{VЍMǺE4?*a5SK蒒q{V@}|U^Y$823|{ץПO/딟 |@ tߞ rCMj]']0A*׃+[E< oV3qA+mُt51Gz̿ژ\g]0Ҥ3z^vpU l˹q\GmܧBqҹՌj+6E~C1Uuw: #ٸ`K|۱=TO'S]Js>7S!4}Z>x @PN˖hmlkI ~?ʭXo?ƲR..欖ƄI.21\.ض215}:ǏW$TNI3wnoZ<5^+ЈDAǓXWk:5t7 1osۗ74M ~iMxtAyv KƿUk4&.q?)J}Yt@* YWGJԿ+{][Կʻ̷*Z`/xSKxlь0QVJ|9CVE}T 6ix ȥ~Y!YMbrB|Gj/h'Qn.:w~l+om=|?ʹ8 jOOze. ۣd!r=OX -b'YEԫYuQ~v O#kҭT֠b