From 9792fd56998d6aca0f95c82a3660038e8881b864 Mon Sep 17 00:00:00 2001 From: SamSeed-Softwire <63662292+SamSeed-Softwire@users.noreply.github.com> Date: Mon, 13 Mar 2023 16:13:11 +0000 Subject: [PATCH 01/20] fix: resave 2023 CSV as not UTF-8 (#1411) --- config/rent_range_data/2023.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/rent_range_data/2023.csv b/config/rent_range_data/2023.csv index 08775d4a4..5a0d9858f 100644 --- a/config/rent_range_data/2023.csv +++ b/config/rent_range_data/2023.csv @@ -1,4 +1,4 @@ -ranges_rent_id,lettype,la,beds,soft_min,soft_max,hard_min,hard_max +ranges_rent_id,lettype,la,beds,soft_min,soft_max,hard_min,hard_max 1,1,E07000223,1,57.21,123.09,25.84,176.15 327,1,E07000223,2,71.06,146.43,25.84,186.77 653,1,E07000223,3,81.2,161.3,25.84,203.75 From 95449682c14caa5212d3e31edfe477dcfac2a923 Mon Sep 17 00:00:00 2001 From: SamSeed-Softwire <63662292+SamSeed-Softwire@users.noreply.github.com> Date: Mon, 13 Mar 2023 16:37:36 +0000 Subject: [PATCH 02/20] CLDC-1820 Update reason for leaving domestic abuse answer options (non-renewal only) (#1391) * feat: change domestic abuse answer opts * test: add test for reason question --- app/models/form/lettings/questions/reason.rb | 7 +- .../form/lettings/questions/reason_spec.rb | 158 ++++++++++++++++++ 2 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 spec/models/form/lettings/questions/reason_spec.rb diff --git a/app/models/form/lettings/questions/reason.rb b/app/models/form/lettings/questions/reason.rb index 2f46fae35..ef8fbcd0d 100644 --- a/app/models/form/lettings/questions/reason.rb +++ b/app/models/form/lettings/questions/reason.rb @@ -58,8 +58,11 @@ class Form::Lettings::Questions::Reason < ::Form::Question "17" => { "value" => "To move nearer to work", }, - "7" => { - "value" => "Domestic abuse", + "48" => { + "value" => "Domestic abuse - previously joint tenancy with partner", + }, + "49" => { + "value" => "Domestic abuse - other", }, "31" => { "value" => "Hate crime", diff --git a/spec/models/form/lettings/questions/reason_spec.rb b/spec/models/form/lettings/questions/reason_spec.rb new file mode 100644 index 000000000..24d28fd4b --- /dev/null +++ b/spec/models/form/lettings/questions/reason_spec.rb @@ -0,0 +1,158 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::Reason, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("reason") + end + + it "has the correct header" do + expect(question.header).to eq("What is the tenant’s main reason for the household leaving their last settled home?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Reason for leaving last settled home") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "has the correct check_answers_card_number" do + expect(question.check_answers_card_number).to eq(0) + end + + it "has the correct hint" do + expect(question.hint_text).to eq("The tenant’s ‘last settled home’ is their last long-standing home. For tenants who were in temporary accommodation or sleeping rough, their last settled home is where they were living previously.") + end + + it "has the correct conditional_for" do + expect(question.conditional_for).to eq({ "reasonother" => [20] }) + end + + it "is not marked as derived" do + expect(question).not_to be_derived + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "40" => { + "value" => "End of assured shorthold tenancy (no fault)", + }, + "41" => { + "value" => "End of assured shorthold tenancy (eviction or tenant at fault)", + }, + "42" => { + "value" => "End of fixed term tenancy (no fault)", + }, + "43" => { + "value" => "End of fixed term tenancy (eviction or tenant at fault)", + }, + "1" => { + "value" => "Permanently decanted from another property owned by this landlord", + }, + "46" => { + "value" => "Discharged from long-stay hospital or similar institution", + }, + "45" => { + "value" => "Discharged from prison", + }, + "2" => { + "value" => "Left home country as a refugee", + }, + "4" => { + "value" => "Loss of tied accommodation", + }, + "9" => { + "value" => "Asked to leave by family or friends", + }, + "44" => { + "value" => "Death of household member in last settled accommodation", + }, + "8" => { + "value" => "Relationship breakdown (non-violent) with partner", + }, + "16" => { + "value" => "To move nearer to family, friends or school", + }, + "17" => { + "value" => "To move nearer to work", + }, + "48" => { + "value" => "Domestic abuse - previously joint tenancy with partner", + }, + "49" => { + "value" => "Domestic abuse - other", + }, + "31" => { + "value" => "Hate crime", + }, + "10" => { + "value" => "Racial harassment", + }, + "11" => { + "value" => "Other problems with neighbours", + }, + "35" => { + "value" => "Couldn’t afford fees attached to renewing the tenancy", + }, + "36" => { + "value" => "Couldn’t afford increase in rent", + }, + "38" => { + "value" => "Couldn’t afford rent or mortgage (employment)", + }, + "37" => { + "value" => "Couldn’t afford rent or mortgage (welfare reforms)", + }, + "39" => { + "value" => "Couldn’t afford rent or mortgage (other)", + }, + "34" => { + "value" => "Repossession", + }, + "12" => { + "value" => "Property unsuitable because of overcrowding", + }, + "13" => { + "value" => "Property unsuitable because of ill health or disability", + }, + "14" => { + "value" => "Property unsuitable because of poor condition", + }, + "18" => { + "value" => "To move to accommodation with support", + }, + "19" => { + "value" => "To move to independent accommodation", + }, + "30" => { + "value" => "Under occupation (no incentive)", + }, + "29" => { + "value" => "Under occupation (offered incentive to downsize)", + }, + "20" => { + "value" => "Other", + }, + "47" => { + "value" => "Tenant prefers not to say", + }, + "divider" => { + "value" => true, + }, + "28" => { + "value" => "Don’t know", + }, + }) + end +end From 285b8ec61f8234807accc5f8ae70c8d93d6709f0 Mon Sep 17 00:00:00 2001 From: Arthur Campbell <51094020+arfacamble@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:35:27 +0000 Subject: [PATCH 03/20] CLDC-1808 add previous tenure question for buyer two (#1354) * create and run migration for new columns related to buyer two previous tenure * a little refactoring for readability * create new pages, questions, associated tests and a couple of boolean methods on sales log for depends_on readability * add new pages to subsection and amend tests to reflect this change * make new pages only visible for new collection year, rename filesamend tests * some copy changes and alterations of readability after code review --- .../sales/pages/buyer2_live_in_property.rb | 6 +-- .../form/sales/pages/buyer2_living_in.rb | 11 +++++ .../buyer2_previous_housing_situation.rb | 11 +++++ .../form/sales/questions/buyer2_living_in.rb | 17 +++++++ .../sales/questions/previous_tenure_buyer2.rb | 23 +++++++++ .../sales/subsections/household_situation.rb | 12 ++++- app/models/sales_log.rb | 12 +++++ ...20230224083552_add_columns_to_sales_log.rb | 8 +++ db/schema.rb | 2 + .../pages/buyer2_live_in_property_spec.rb | 6 +-- .../form/sales/pages/buyer2_living_in_spec.rb | 31 ++++++++++++ .../buyer2_previous_housing_situation_spec.rb | 31 ++++++++++++ .../sales/questions/buyer2_living_in_spec.rb | 43 ++++++++++++++++ .../questions/previous_tenure_buyer2_spec.rb | 49 +++++++++++++++++++ .../subsections/household_situation_spec.rb | 45 ++++++++++++----- 15 files changed, 287 insertions(+), 20 deletions(-) create mode 100644 app/models/form/sales/pages/buyer2_living_in.rb create mode 100644 app/models/form/sales/pages/buyer2_previous_housing_situation.rb create mode 100644 app/models/form/sales/questions/buyer2_living_in.rb create mode 100644 app/models/form/sales/questions/previous_tenure_buyer2.rb create mode 100644 db/migrate/20230224083552_add_columns_to_sales_log.rb create mode 100644 spec/models/form/sales/pages/buyer2_living_in_spec.rb create mode 100644 spec/models/form/sales/pages/buyer2_previous_housing_situation_spec.rb create mode 100644 spec/models/form/sales/questions/buyer2_living_in_spec.rb create mode 100644 spec/models/form/sales/questions/previous_tenure_buyer2_spec.rb diff --git a/app/models/form/sales/pages/buyer2_live_in_property.rb b/app/models/form/sales/pages/buyer2_live_in_property.rb index 9ba67080b..3c0ce7b3b 100644 --- a/app/models/form/sales/pages/buyer2_live_in_property.rb +++ b/app/models/form/sales/pages/buyer2_live_in_property.rb @@ -4,12 +4,12 @@ class Form::Sales::Pages::Buyer2LiveInProperty < ::Form::Page @id = "buyer_2_live_in_property" @depends_on = [ { - "jointpur" => 1, + "joint_purchase?" => true, "privacynotice" => 1, }, { - "jointpur" => 1, - "noint" => 1, + "joint_purchase?" => true, + "buyer_not_interviewed?" => true, }, ] end diff --git a/app/models/form/sales/pages/buyer2_living_in.rb b/app/models/form/sales/pages/buyer2_living_in.rb new file mode 100644 index 000000000..b8d32ffdc --- /dev/null +++ b/app/models/form/sales/pages/buyer2_living_in.rb @@ -0,0 +1,11 @@ +class Form::Sales::Pages::Buyer2LivingIn < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "buyer_2_living_in" + @depends_on = [{ "buyer_two_will_live_in_property?" => true }] + end + + def questions + @questions = [Form::Sales::Questions::Buyer2LivingIn.new(nil, nil, self)] + end +end diff --git a/app/models/form/sales/pages/buyer2_previous_housing_situation.rb b/app/models/form/sales/pages/buyer2_previous_housing_situation.rb new file mode 100644 index 000000000..c6a511243 --- /dev/null +++ b/app/models/form/sales/pages/buyer2_previous_housing_situation.rb @@ -0,0 +1,11 @@ +class Form::Sales::Pages::Buyer2PreviousHousingSituation < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "buyer_2_previous_housing_situation" + @depends_on = [{ "buyer_two_not_already_living_in_property?" => true }] + end + + def questions + @questions = [Form::Sales::Questions::PreviousTenureBuyer2.new(nil, nil, self)] + end +end diff --git a/app/models/form/sales/questions/buyer2_living_in.rb b/app/models/form/sales/questions/buyer2_living_in.rb new file mode 100644 index 000000000..1494e61a2 --- /dev/null +++ b/app/models/form/sales/questions/buyer2_living_in.rb @@ -0,0 +1,17 @@ +class Form::Sales::Questions::Buyer2LivingIn < ::Form::Question + def initialize(id, hsh, page) + super + @id = "buy2living" + @check_answer_label = "Buyer 2 living at the same address" + @header = "At the time of purchase, was buyer 2 living at the same address as buyer 1?" + @type = "radio" + @hint_text = "" + @answer_options = ANSWER_OPTIONS + end + + ANSWER_OPTIONS = { + "1" => { "value" => "Yes" }, + "2" => { "value" => "No" }, + "3" => { "value" => "Don't know" }, + }.freeze +end diff --git a/app/models/form/sales/questions/previous_tenure_buyer2.rb b/app/models/form/sales/questions/previous_tenure_buyer2.rb new file mode 100644 index 000000000..6de2ed8c5 --- /dev/null +++ b/app/models/form/sales/questions/previous_tenure_buyer2.rb @@ -0,0 +1,23 @@ +class Form::Sales::Questions::PreviousTenureBuyer2 < ::Form::Question + def initialize(id, hsh, page) + super + @id = "prevtenbuy2" + @check_answer_label = "Buyer 2’s previous tenure" + @header = "What was buyer 2’s previous tenure?" + @type = "radio" + @hint_text = "" + @answer_options = ANSWER_OPTIONS + end + + ANSWER_OPTIONS = { + "1" => { "value" => "Local Authority" }, + "2" => { "value" => "Private registered provider or housing association tenant" }, + "3" => { "value" => "Private tenant" }, + "5" => { "value" => "Owner occupier" }, + "4" => { "value" => "Tied home or renting with job" }, + "6" => { "value" => "Living with family or friends" }, + "7" => { "value" => "Temporary accomodation" }, + "9" => { "value" => "Other" }, + "0" => { "value" => "Don't know" }, + }.freeze +end diff --git a/app/models/form/sales/subsections/household_situation.rb b/app/models/form/sales/subsections/household_situation.rb index a9d9306d6..225b1ae43 100644 --- a/app/models/form/sales/subsections/household_situation.rb +++ b/app/models/form/sales/subsections/household_situation.rb @@ -12,6 +12,16 @@ class Form::Sales::Subsections::HouseholdSituation < ::Form::Subsection Form::Sales::Pages::LastAccommodation.new(nil, nil, self), Form::Sales::Pages::LastAccommodationLa.new(nil, nil, self), Form::Sales::Pages::BuyersOrganisations.new(nil, nil, self), - ] + buyer_2_situation_pages, + ].flatten.compact + end + + def buyer_2_situation_pages + if form.start_date.year >= 2023 + [ + Form::Sales::Pages::Buyer2LivingIn.new(nil, nil, self), + Form::Sales::Pages::Buyer2PreviousHousingSituation.new(nil, nil, self), + ] + end end end diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 90f130c04..e15b9c610 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -151,6 +151,14 @@ class SalesLog < Log inc1mort == 1 end + def buyer_two_will_live_in_property? + buy2livein == 1 + end + + def buyer_two_not_already_living_in_property? + buy2living == 2 + end + def income2_used_for_mortgage? inc2mort == 1 end @@ -250,6 +258,10 @@ class SalesLog < Log jointpur == 2 end + def buyer_not_interviewed? + noint == 1 + end + def old_persons_shared_ownership? type == 24 end diff --git a/db/migrate/20230224083552_add_columns_to_sales_log.rb b/db/migrate/20230224083552_add_columns_to_sales_log.rb new file mode 100644 index 000000000..f4fbc91df --- /dev/null +++ b/db/migrate/20230224083552_add_columns_to_sales_log.rb @@ -0,0 +1,8 @@ +class AddColumnsToSalesLog < ActiveRecord::Migration[7.0] + def change + change_table :sales_logs, bulk: true do |t| + t.column :buy2living, :integer + t.column :prevtenbuy2, :integer + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 3b26fde33..385d565c7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -543,6 +543,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_08_101826) do t.integer "proplen_asked" t.string "old_id" t.integer "pregblank" + t.integer "buy2living" + t.integer "prevtenbuy2" t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id" t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id" t.index ["old_id"], name: "index_sales_logs_on_old_id", unique: true diff --git a/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb b/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb index 258e37462..555e78927 100644 --- a/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb +++ b/spec/models/form/sales/pages/buyer2_live_in_property_spec.rb @@ -30,12 +30,12 @@ RSpec.describe Form::Sales::Pages::Buyer2LiveInProperty, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq([ { - "jointpur" => 1, + "joint_purchase?" => true, "privacynotice" => 1, }, { - "jointpur" => 1, - "noint" => 1, + "joint_purchase?" => true, + "buyer_not_interviewed?" => true, }, ]) end diff --git a/spec/models/form/sales/pages/buyer2_living_in_spec.rb b/spec/models/form/sales/pages/buyer2_living_in_spec.rb new file mode 100644 index 000000000..9bfef1ff4 --- /dev/null +++ b/spec/models/form/sales/pages/buyer2_living_in_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::Buyer2LivingIn, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[buy2living]) + end + + it "has the correct id" do + expect(page.id).to eq("buyer_2_living_in") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "buyer_two_will_live_in_property?" => true }]) + end +end diff --git a/spec/models/form/sales/pages/buyer2_previous_housing_situation_spec.rb b/spec/models/form/sales/pages/buyer2_previous_housing_situation_spec.rb new file mode 100644 index 000000000..ac5611a8f --- /dev/null +++ b/spec/models/form/sales/pages/buyer2_previous_housing_situation_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::Buyer2PreviousHousingSituation, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[prevtenbuy2]) + end + + it "has the correct id" do + expect(page.id).to eq("buyer_2_previous_housing_situation") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "buyer_two_not_already_living_in_property?" => true }]) + end +end diff --git a/spec/models/form/sales/questions/buyer2_living_in_spec.rb b/spec/models/form/sales/questions/buyer2_living_in_spec.rb new file mode 100644 index 000000000..4fca65f3f --- /dev/null +++ b/spec/models/form/sales/questions/buyer2_living_in_spec.rb @@ -0,0 +1,43 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::Buyer2LivingIn, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq page + end + + it "has the correct id" do + expect(question.id).to eq "buy2living" + end + + it "has the correct header" do + expect(question.header).to eq "At the time of purchase, was buyer 2 living at the same address as buyer 1?" + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq "Buyer 2 living at the same address" + end + + it "has the correct type" do + expect(question.type).to eq "radio" + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq "" + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "1" => { "value" => "Yes" }, + "2" => { "value" => "No" }, + "3" => { "value" => "Don't know" }, + }) + end +end diff --git a/spec/models/form/sales/questions/previous_tenure_buyer2_spec.rb b/spec/models/form/sales/questions/previous_tenure_buyer2_spec.rb new file mode 100644 index 000000000..1ab7a86de --- /dev/null +++ b/spec/models/form/sales/questions/previous_tenure_buyer2_spec.rb @@ -0,0 +1,49 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::PreviousTenureBuyer2, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("prevtenbuy2") + end + + it "has the correct header" do + expect(question.header).to eq("What was buyer 2’s previous tenure?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Buyer 2’s previous tenure") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("") + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "1" => { "value" => "Local Authority" }, + "2" => { "value" => "Private registered provider or housing association tenant" }, + "3" => { "value" => "Private tenant" }, + "5" => { "value" => "Owner occupier" }, + "4" => { "value" => "Tied home or renting with job" }, + "6" => { "value" => "Living with family or friends" }, + "7" => { "value" => "Temporary accomodation" }, + "9" => { "value" => "Other" }, + "0" => { "value" => "Don't know" }, + }) + end +end diff --git a/spec/models/form/sales/subsections/household_situation_spec.rb b/spec/models/form/sales/subsections/household_situation_spec.rb index e88dda99f..10898b27c 100644 --- a/spec/models/form/sales/subsections/household_situation_spec.rb +++ b/spec/models/form/sales/subsections/household_situation_spec.rb @@ -1,25 +1,44 @@ require "rails_helper" RSpec.describe Form::Sales::Subsections::HouseholdSituation, type: :model do - subject(:household_characteristics) { described_class.new(subsection_id, subsection_definition, section) } + subject(:household_characteristics) { described_class.new(nil, nil, section) } - let(:subsection_id) { nil } - let(:subsection_definition) { nil } - let(:section) { instance_double(Form::Sales::Sections::Household) } + let(:start_date) { Time.utc(2023, 4, 1) } + let(:form) { instance_double(Form, start_date:) } + let(:section) { instance_double(Form::Sales::Sections::Household, form:) } it "has correct section" do expect(household_characteristics.section).to eq(section) end - it "has correct pages" do - expect(household_characteristics.pages.map(&:id)).to eq( - %w[ - buyer1_previous_tenure - last_accommodation - last_accommodation_la - buyers_organisations - ], - ) + context "when the log belongs to the 22/23 collection" do + let(:start_date) { Time.utc(2022, 4, 1) } + + it "has correct pages" do + expect(household_characteristics.pages.map(&:id)).to eq( + %w[ + buyer1_previous_tenure + last_accommodation + last_accommodation_la + buyers_organisations + ], + ) + end + end + + context "when the log belongs to the 23/24 collection" do + it "has correct pages" do + expect(household_characteristics.pages.map(&:id)).to eq( + %w[ + buyer1_previous_tenure + last_accommodation + last_accommodation_la + buyers_organisations + buyer_2_living_in + buyer_2_previous_housing_situation + ], + ) + end end it "has the correct id" do From 92fdc0fff1a35e3e6574ee293e7fde10d5dfd2d7 Mon Sep 17 00:00:00 2001 From: Arthur Campbell <51094020+arfacamble@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:36:09 +0000 Subject: [PATCH 04/20] CLDC-1816 add hint text to tenancy type options (#1341) * add hint text to several options on tenancy type, rename question class and a few others to make them pascal case and write test files for all changed questions * update some depends on for readability and write test files for page classes * change the condition to avoid conflicts with 2034 and cover that ticket in this one * also add hints to other tenancy question --- .../lettings/pages/starter_tenancy_type.rb | 6 +- .../form/lettings/pages/tenancy_length.rb | 4 +- .../form/lettings/pages/tenancy_type.rb | 6 +- .../lettings/questions/starter_tenancy.rb | 22 ------- .../questions/starter_tenancy_type.rb | 37 +++++++++++ app/models/form/lettings/questions/tenancy.rb | 22 ------- .../{tenancylength.rb => tenancy_length.rb} | 2 +- .../{tenancyother.rb => tenancy_other.rb} | 2 +- .../form/lettings/questions/tenancy_type.rb | 37 +++++++++++ app/models/lettings_log.rb | 8 +++ .../pages/starter_tenancy_type_spec.rb | 31 +++++++++ .../lettings/pages/tenancy_length_spec.rb | 31 +++++++++ .../form/lettings/pages/tenancy_type_spec.rb | 31 +++++++++ .../lettings/questions/tenancy_length_spec.rb | 44 +++++++++++++ .../lettings/questions/tenancy_other_spec.rb | 35 ++++++++++ .../lettings/questions/tenancy_type_spec.rb | 65 +++++++++++++++++++ 16 files changed, 329 insertions(+), 54 deletions(-) delete mode 100644 app/models/form/lettings/questions/starter_tenancy.rb create mode 100644 app/models/form/lettings/questions/starter_tenancy_type.rb delete mode 100644 app/models/form/lettings/questions/tenancy.rb rename app/models/form/lettings/questions/{tenancylength.rb => tenancy_length.rb} (86%) rename app/models/form/lettings/questions/{tenancyother.rb => tenancy_other.rb} (78%) create mode 100644 app/models/form/lettings/questions/tenancy_type.rb create mode 100644 spec/models/form/lettings/pages/starter_tenancy_type_spec.rb create mode 100644 spec/models/form/lettings/pages/tenancy_length_spec.rb create mode 100644 spec/models/form/lettings/pages/tenancy_type_spec.rb create mode 100644 spec/models/form/lettings/questions/tenancy_length_spec.rb create mode 100644 spec/models/form/lettings/questions/tenancy_other_spec.rb create mode 100644 spec/models/form/lettings/questions/tenancy_type_spec.rb diff --git a/app/models/form/lettings/pages/starter_tenancy_type.rb b/app/models/form/lettings/pages/starter_tenancy_type.rb index c488b7b17..fe147bc77 100644 --- a/app/models/form/lettings/pages/starter_tenancy_type.rb +++ b/app/models/form/lettings/pages/starter_tenancy_type.rb @@ -2,13 +2,13 @@ class Form::Lettings::Pages::StarterTenancyType < ::Form::Page def initialize(id, hsh, subsection) super @id = "starter_tenancy_type" - @depends_on = [{ "startertenancy" => 1 }] + @depends_on = [{ "starter_tenancy?" => true }] end def questions @questions ||= [ - Form::Lettings::Questions::StarterTenancy.new(nil, nil, self), - Form::Lettings::Questions::Tenancyother.new(nil, nil, self), + Form::Lettings::Questions::StarterTenancyType.new(nil, nil, self), + Form::Lettings::Questions::TenancyOther.new(nil, nil, self), ] end end diff --git a/app/models/form/lettings/pages/tenancy_length.rb b/app/models/form/lettings/pages/tenancy_length.rb index 943ea2bc9..cb533dcf9 100644 --- a/app/models/form/lettings/pages/tenancy_length.rb +++ b/app/models/form/lettings/pages/tenancy_length.rb @@ -2,10 +2,10 @@ class Form::Lettings::Pages::TenancyLength < ::Form::Page def initialize(id, hsh, subsection) super @id = "tenancy_length" - @depends_on = [{ "tenancy" => 4 }, { "tenancy" => 6 }, { "tenancy" => 3 }] + @depends_on = [{ "tenancy_type_fixed_term?" => true }] end def questions - @questions ||= [Form::Lettings::Questions::Tenancylength.new(nil, nil, self)] + @questions ||= [Form::Lettings::Questions::TenancyLength.new(nil, nil, self)] end end diff --git a/app/models/form/lettings/pages/tenancy_type.rb b/app/models/form/lettings/pages/tenancy_type.rb index 8ee6c3bbc..c15f6f27a 100644 --- a/app/models/form/lettings/pages/tenancy_type.rb +++ b/app/models/form/lettings/pages/tenancy_type.rb @@ -2,13 +2,13 @@ class Form::Lettings::Pages::TenancyType < ::Form::Page def initialize(id, hsh, subsection) super @id = "tenancy_type" - @depends_on = [{ "startertenancy" => 2 }] + @depends_on = [{ "starter_tenancy?" => false }] end def questions @questions ||= [ - Form::Lettings::Questions::Tenancy.new(nil, nil, self), - Form::Lettings::Questions::Tenancyother.new(nil, nil, self), + Form::Lettings::Questions::TenancyType.new(nil, nil, self), + Form::Lettings::Questions::TenancyOther.new(nil, nil, self), ] end end diff --git a/app/models/form/lettings/questions/starter_tenancy.rb b/app/models/form/lettings/questions/starter_tenancy.rb deleted file mode 100644 index 9e489c129..000000000 --- a/app/models/form/lettings/questions/starter_tenancy.rb +++ /dev/null @@ -1,22 +0,0 @@ -class Form::Lettings::Questions::StarterTenancy < ::Form::Question - def initialize(id, hsh, page) - super - @id = "tenancy" - @check_answer_label = "Type of main tenancy after the starter period has ended?" - @header = "What is the type of tenancy after the starter period has ended?" - @type = "radio" - @check_answers_card_number = 0 - @hint_text = "This is also known as an ‘introductory period’." - @answer_options = ANSWER_OPTIONS - @conditional_for = { "tenancyother" => [3] } - end - - ANSWER_OPTIONS = { - "4" => { "value" => "Assured Shorthold Tenancy (AST) – Fixed term" }, - "6" => { "value" => "Secure – fixed term" }, - "2" => { "value" => "Assured – lifetime" }, - "7" => { "value" => "Secure – lifetime" }, - "5" => { "value" => "Licence agreement" }, - "3" => { "value" => "Other" }, - }.freeze -end diff --git a/app/models/form/lettings/questions/starter_tenancy_type.rb b/app/models/form/lettings/questions/starter_tenancy_type.rb new file mode 100644 index 000000000..13fa20ef6 --- /dev/null +++ b/app/models/form/lettings/questions/starter_tenancy_type.rb @@ -0,0 +1,37 @@ +class Form::Lettings::Questions::StarterTenancyType < ::Form::Question + def initialize(id, hsh, page) + super + @id = "tenancy" + @check_answer_label = "Type of main tenancy after the starter period has ended?" + @header = "What is the type of tenancy after the starter period has ended?" + @type = "radio" + @check_answers_card_number = 0 + @hint_text = "This is also known as an ‘introductory period’." + @answer_options = ANSWER_OPTIONS + @conditional_for = { "tenancyother" => [3] } + end + + ANSWER_OPTIONS = { + "4" => { + "value" => "Assured Shorthold Tenancy (AST) – Fixed term", + "hint" => "Mostly housing associations provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "6" => { + "value" => "Secure – fixed term", + "hint" => "Mostly local authorities provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "2" => { + "value" => "Assured – lifetime", + }, + "7" => { + "value" => "Secure – lifetime", + }, + "5" => { + "value" => "Licence agreement", + "hint" => "Licence agreements are mostly used for Supported Housing and work on a rolling basis.", + }, + "3" => { + "value" => "Other", + }, + }.freeze +end diff --git a/app/models/form/lettings/questions/tenancy.rb b/app/models/form/lettings/questions/tenancy.rb deleted file mode 100644 index 06a8d4fce..000000000 --- a/app/models/form/lettings/questions/tenancy.rb +++ /dev/null @@ -1,22 +0,0 @@ -class Form::Lettings::Questions::Tenancy < ::Form::Question - def initialize(id, hsh, page) - super - @id = "tenancy" - @check_answer_label = "Type of main tenancy" - @header = "What is the type of tenancy?" - @type = "radio" - @check_answers_card_number = 0 - @hint_text = "" - @answer_options = ANSWER_OPTIONS - @conditional_for = { "tenancyother" => [3] } - end - - ANSWER_OPTIONS = { - "4" => { "value" => "Assured Shorthold Tenancy (AST) – Fixed term" }, - "6" => { "value" => "Secure – fixed term" }, - "2" => { "value" => "Assured – lifetime" }, - "7" => { "value" => "Secure – lifetime" }, - "5" => { "value" => "Licence agreement" }, - "3" => { "value" => "Other" }, - }.freeze -end diff --git a/app/models/form/lettings/questions/tenancylength.rb b/app/models/form/lettings/questions/tenancy_length.rb similarity index 86% rename from app/models/form/lettings/questions/tenancylength.rb rename to app/models/form/lettings/questions/tenancy_length.rb index 426a95669..0a8088c51 100644 --- a/app/models/form/lettings/questions/tenancylength.rb +++ b/app/models/form/lettings/questions/tenancy_length.rb @@ -1,4 +1,4 @@ -class Form::Lettings::Questions::Tenancylength < ::Form::Question +class Form::Lettings::Questions::TenancyLength < ::Form::Question def initialize(id, hsh, page) super @id = "tenancylength" diff --git a/app/models/form/lettings/questions/tenancyother.rb b/app/models/form/lettings/questions/tenancy_other.rb similarity index 78% rename from app/models/form/lettings/questions/tenancyother.rb rename to app/models/form/lettings/questions/tenancy_other.rb index 468d592aa..6eea47ac8 100644 --- a/app/models/form/lettings/questions/tenancyother.rb +++ b/app/models/form/lettings/questions/tenancy_other.rb @@ -1,4 +1,4 @@ -class Form::Lettings::Questions::Tenancyother < ::Form::Question +class Form::Lettings::Questions::TenancyOther < ::Form::Question def initialize(id, hsh, page) super @id = "tenancyother" diff --git a/app/models/form/lettings/questions/tenancy_type.rb b/app/models/form/lettings/questions/tenancy_type.rb new file mode 100644 index 000000000..c05b4349d --- /dev/null +++ b/app/models/form/lettings/questions/tenancy_type.rb @@ -0,0 +1,37 @@ +class Form::Lettings::Questions::TenancyType < ::Form::Question + def initialize(id, hsh, page) + super + @id = "tenancy" + @check_answer_label = "Type of main tenancy" + @header = "What is the type of tenancy?" + @type = "radio" + @check_answers_card_number = 0 + @hint_text = "" + @answer_options = ANSWER_OPTIONS + @conditional_for = { "tenancyother" => [3] } + end + + ANSWER_OPTIONS = { + "4" => { + "value" => "Assured Shorthold Tenancy (AST) – Fixed term", + "hint" => "Mostly housing associations provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "6" => { + "value" => "Secure – fixed term", + "hint" => "Mostly local authorities provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "2" => { + "value" => "Assured – lifetime", + }, + "7" => { + "value" => "Secure – lifetime", + }, + "5" => { + "value" => "Licence agreement", + "hint" => "Licence agreements are mostly used for Supported Housing and work on a rolling basis.", + }, + "3" => { + "value" => "Other", + }, + }.freeze +end diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 6491c100f..108cb1be1 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -195,6 +195,14 @@ class LettingsLog < Log renewal == 1 end + def starter_tenancy? + startertenancy == 1 + end + + def tenancy_type_fixed_term? + [4, 6].include? tenancy + end + def is_general_needs? # 1: General Needs needstype == 1 diff --git a/spec/models/form/lettings/pages/starter_tenancy_type_spec.rb b/spec/models/form/lettings/pages/starter_tenancy_type_spec.rb new file mode 100644 index 000000000..795dee561 --- /dev/null +++ b/spec/models/form/lettings/pages/starter_tenancy_type_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::StarterTenancyType, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[tenancy tenancyother]) + end + + it "has the correct id" do + expect(page.id).to eq("starter_tenancy_type") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has the correct depends_on" do + expect(page.depends_on).to eq([{ "starter_tenancy?" => true }]) + end +end diff --git a/spec/models/form/lettings/pages/tenancy_length_spec.rb b/spec/models/form/lettings/pages/tenancy_length_spec.rb new file mode 100644 index 000000000..d4ea920ae --- /dev/null +++ b/spec/models/form/lettings/pages/tenancy_length_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::TenancyLength, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq subsection + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq %w[tenancylength] + end + + it "has the correct id" do + expect(page.id).to eq "tenancy_length" + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has the correct depends_on" do + expect(page.depends_on).to eq [{ "tenancy_type_fixed_term?" => true }] + end +end diff --git a/spec/models/form/lettings/pages/tenancy_type_spec.rb b/spec/models/form/lettings/pages/tenancy_type_spec.rb new file mode 100644 index 000000000..ef772e85e --- /dev/null +++ b/spec/models/form/lettings/pages/tenancy_type_spec.rb @@ -0,0 +1,31 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::TenancyType, type: :model do + subject(:page) { described_class.new(nil, nil, subsection) } + + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq %w[tenancy tenancyother] + end + + it "has the correct id" do + expect(page.id).to eq "tenancy_type" + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has the correct depends_on" do + expect(page.depends_on).to eq [{ "starter_tenancy?" => false }] + end +end diff --git a/spec/models/form/lettings/questions/tenancy_length_spec.rb b/spec/models/form/lettings/questions/tenancy_length_spec.rb new file mode 100644 index 000000000..8eea52a81 --- /dev/null +++ b/spec/models/form/lettings/questions/tenancy_length_spec.rb @@ -0,0 +1,44 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::TenancyLength, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("tenancylength") + end + + it "has the correct header" do + expect(question.header).to eq("What is the length of the fixed-term tenancy to the nearest year?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Length of fixed-term tenancy") + end + + it "has the correct type" do + expect(question.type).to eq("numeric") + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("Don’t include the starter or introductory period.") + end + + it "has the correct minimum and maximum" do + expect(question.min).to eq 0 + expect(question.max).to eq 150 + end + + it "has the correct step" do + expect(question.step).to eq 1 + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end +end diff --git a/spec/models/form/lettings/questions/tenancy_other_spec.rb b/spec/models/form/lettings/questions/tenancy_other_spec.rb new file mode 100644 index 000000000..58a656e57 --- /dev/null +++ b/spec/models/form/lettings/questions/tenancy_other_spec.rb @@ -0,0 +1,35 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::TenancyOther, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("tenancyother") + end + + it "has the correct header" do + expect(question.header).to eq("Please state the tenancy type") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("") + end + + it "has the correct type" do + expect(question.type).to eq("text") + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end +end diff --git a/spec/models/form/lettings/questions/tenancy_type_spec.rb b/spec/models/form/lettings/questions/tenancy_type_spec.rb new file mode 100644 index 000000000..8fd8a50f0 --- /dev/null +++ b/spec/models/form/lettings/questions/tenancy_type_spec.rb @@ -0,0 +1,65 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::TenancyType, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("tenancy") + end + + it "has the correct header" do + expect(question.header).to eq("What is the type of tenancy?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Type of main tenancy") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("") + end + + it "has the correct conditional_for" do + expect(question.conditional_for).to eq({ "tenancyother" => [3] }) + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "4" => { + "value" => "Assured Shorthold Tenancy (AST) – Fixed term", + "hint" => "Mostly housing associations provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "6" => { + "value" => "Secure – fixed term", + "hint" => "Mostly local authorities provide these. Fixed term tenancies are intended to be for a set amount of time up to 20 years.", + }, + "2" => { + "value" => "Assured – lifetime", + }, + "7" => { + "value" => "Secure – lifetime", + }, + "5" => { + "value" => "Licence agreement", + "hint" => "Licence agreements are mostly used for Supported Housing and work on a rolling basis.", + }, + "3" => { + "value" => "Other", + }, + }) + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end +end From 2b51add7011ff6e2a7d82dc22c18148256a60a78 Mon Sep 17 00:00:00 2001 From: Arthur Campbell <51094020+arfacamble@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:36:43 +0000 Subject: [PATCH 05/20] add new answer options to nationality, rename question, write test file (#1339) --- .../lettings/pages/lead_tenant_nationality.rb | 2 +- .../questions/{national.rb => nationality.rb} | 6 ++- .../lettings/questions/nationality_spec.rb | 48 +++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) rename app/models/form/lettings/questions/{national.rb => nationality.rb} (78%) create mode 100644 spec/models/form/lettings/questions/nationality_spec.rb diff --git a/app/models/form/lettings/pages/lead_tenant_nationality.rb b/app/models/form/lettings/pages/lead_tenant_nationality.rb index ae67b1e32..09a25286c 100644 --- a/app/models/form/lettings/pages/lead_tenant_nationality.rb +++ b/app/models/form/lettings/pages/lead_tenant_nationality.rb @@ -6,6 +6,6 @@ class Form::Lettings::Pages::LeadTenantNationality < ::Form::Page end def questions - @questions ||= [Form::Lettings::Questions::National.new(nil, nil, self)] + @questions ||= [Form::Lettings::Questions::Nationality.new(nil, nil, self)] end end diff --git a/app/models/form/lettings/questions/national.rb b/app/models/form/lettings/questions/nationality.rb similarity index 78% rename from app/models/form/lettings/questions/national.rb rename to app/models/form/lettings/questions/nationality.rb index 0bfe198e0..019c8a4fa 100644 --- a/app/models/form/lettings/questions/national.rb +++ b/app/models/form/lettings/questions/nationality.rb @@ -1,9 +1,9 @@ -class Form::Lettings::Questions::National < ::Form::Question +class Form::Lettings::Questions::Nationality < ::Form::Question def initialize(id, hsh, page) super @id = "national" @check_answer_label = "Lead tenant’s nationality" - @header = "What is the lead tenant’s nationality?" + @header = "What is the nationality of the lead tenant?" @type = "radio" @check_answers_card_number = 1 @hint_text = "The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest." @@ -14,6 +14,8 @@ class Form::Lettings::Questions::National < ::Form::Question "18" => { "value" => "United Kingdom" }, "17" => { "value" => "Republic of Ireland" }, "19" => { "value" => "European Economic Area (EEA) country, excluding Ireland" }, + "20" => { "value" => "Afghanistan" }, + "21" => { "value" => "Ukraine" }, "12" => { "value" => "Other" }, "divider" => true, "13" => { "value" => "Tenant prefers not to say" }, diff --git a/spec/models/form/lettings/questions/nationality_spec.rb b/spec/models/form/lettings/questions/nationality_spec.rb new file mode 100644 index 000000000..d0eaeb69b --- /dev/null +++ b/spec/models/form/lettings/questions/nationality_spec.rb @@ -0,0 +1,48 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Questions::Nationality, type: :model do + subject(:question) { described_class.new(nil, nil, page) } + + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("national") + end + + it "has the correct header" do + expect(question.header).to eq("What is the nationality of the lead tenant?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Lead tenant’s nationality") + end + + it "has the correct type" do + expect(question.type).to eq("radio") + end + + it "has the correct hint_text" do + expect(question.hint_text).to eq("The lead tenant is the person in the household who does the most paid work. If several people do the same paid work, the lead tenant is whoever is the oldest.") + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "18" => { "value" => "United Kingdom" }, + "17" => { "value" => "Republic of Ireland" }, + "19" => { "value" => "European Economic Area (EEA) country, excluding Ireland" }, + "20" => { "value" => "Afghanistan" }, + "21" => { "value" => "Ukraine" }, + "12" => { "value" => "Other" }, + "divider" => true, + "13" => { "value" => "Tenant prefers not to say" }, + }) + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end +end From 4916049e18449fa2b1ecd42951c9456d3a46dd56 Mon Sep 17 00:00:00 2001 From: Arthur Campbell <51094020+arfacamble@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:37:21 +0000 Subject: [PATCH 06/20] CLDC-2014 remove text field for buyer 1 nationality other (#1388) * remove question no longer needed and associated test file * amend page and the other question in that page that determined whether the deleted question should be shown update associated test files * createa a migration to remove the column for the deleted question * update test broken by changes * fix test broken by changes --- app/models/form/sales/pages/nationality1.rb | 7 +--- .../form/sales/questions/nationality1.rb | 10 ----- .../sales/questions/other_nationality1.rb | 10 ----- .../imports/sales_logs_import_service.rb | 1 - ...43_remove_othernational_from_sales_logs.rb | 5 +++ db/schema.rb | 1 - .../form/conditional_questions_spec.rb | 12 +++--- .../form/sales/pages/nationality1_spec.rb | 12 +++--- .../form/sales/questions/nationality1_spec.rb | 30 +++++--------- .../questions/other_nationality1_spec.rb | 41 ------------------- 10 files changed, 28 insertions(+), 101 deletions(-) delete mode 100644 app/models/form/sales/questions/other_nationality1.rb create mode 100644 db/migrate/20230307111943_remove_othernational_from_sales_logs.rb delete mode 100644 spec/models/form/sales/questions/other_nationality1_spec.rb diff --git a/app/models/form/sales/pages/nationality1.rb b/app/models/form/sales/pages/nationality1.rb index 96723e857..8db4a64ea 100644 --- a/app/models/form/sales/pages/nationality1.rb +++ b/app/models/form/sales/pages/nationality1.rb @@ -7,15 +7,12 @@ class Form::Sales::Pages::Nationality1 < ::Form::Page "privacynotice" => 1, }, { - "noint" => 1, + "buyer_not_interviewed?" => true, }, ] end def questions - @questions ||= [ - Form::Sales::Questions::Nationality1.new(nil, nil, self), - Form::Sales::Questions::OtherNationality1.new(nil, nil, self), - ] + @questions ||= [Form::Sales::Questions::Nationality1.new(nil, nil, self)] end end diff --git a/app/models/form/sales/questions/nationality1.rb b/app/models/form/sales/questions/nationality1.rb index 53e9edc5f..765489f27 100644 --- a/app/models/form/sales/questions/nationality1.rb +++ b/app/models/form/sales/questions/nationality1.rb @@ -7,16 +7,6 @@ class Form::Sales::Questions::Nationality1 < ::Form::Question @type = "radio" @hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." @answer_options = ANSWER_OPTIONS - @conditional_for = { - "othernational" => [12], - } - @hidden_in_check_answers = { - "depends_on" => [ - { - "national" => 12, - }, - ], - } @check_answers_card_number = 1 @inferred_check_answers_value = [{ "condition" => { diff --git a/app/models/form/sales/questions/other_nationality1.rb b/app/models/form/sales/questions/other_nationality1.rb deleted file mode 100644 index 3eb6a48d7..000000000 --- a/app/models/form/sales/questions/other_nationality1.rb +++ /dev/null @@ -1,10 +0,0 @@ -class Form::Sales::Questions::OtherNationality1 < ::Form::Question - def initialize(id, hsh, page) - super - @id = "othernational" - @check_answer_label = "Buyer 1’s nationality" - @header = "Nationality" - @type = "text" - @check_answers_card_number = 1 - end -end diff --git a/app/services/imports/sales_logs_import_service.rb b/app/services/imports/sales_logs_import_service.rb index ed127bff2..577e37e5f 100644 --- a/app/services/imports/sales_logs_import_service.rb +++ b/app/services/imports/sales_logs_import_service.rb @@ -54,7 +54,6 @@ module Imports attributes["details_known_#{index}"] = details_known(index, attributes) end attributes["national"] = unsafe_string_as_integer(xml_doc, "P1Nat") - attributes["othernational"] = nil attributes["ethnic"] = unsafe_string_as_integer(xml_doc, "P1Eth") attributes["ethnic_group"] = ethnic_group(attributes["ethnic"]) attributes["buy1livein"] = unsafe_string_as_integer(xml_doc, "LiveInBuyer1") diff --git a/db/migrate/20230307111943_remove_othernational_from_sales_logs.rb b/db/migrate/20230307111943_remove_othernational_from_sales_logs.rb new file mode 100644 index 000000000..534962773 --- /dev/null +++ b/db/migrate/20230307111943_remove_othernational_from_sales_logs.rb @@ -0,0 +1,5 @@ +class RemoveOthernationalFromSalesLogs < ActiveRecord::Migration[7.0] + def change + remove_column :sales_logs, :othernational, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 385d565c7..bea2209c3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -403,7 +403,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_08_101826) do t.integer "age1_known" t.string "sex1" t.integer "national" - t.string "othernational" t.integer "ethnic" t.integer "ethnic_group" t.integer "buy1livein" diff --git a/spec/features/form/conditional_questions_spec.rb b/spec/features/form/conditional_questions_spec.rb index 4fc9387da..52d8886e0 100644 --- a/spec/features/form/conditional_questions_spec.rb +++ b/spec/features/form/conditional_questions_spec.rb @@ -54,13 +54,13 @@ RSpec.describe "Form Conditional Questions" do end it "gets cleared if the conditional question is hidden after editing the answer" do - sales_log.update!(national: 12, othernational: "other") - visit("/sales-logs/#{sales_log.id}/buyer-1-nationality") - expect(page).to have_field("sales-log-othernational-field", with: "other") + sales_log.update!(age1_known: 0, age1: 50) + visit("/sales-logs/#{sales_log.id}/buyer-1-age") + expect(page).to have_field("sales-log-age1-field", with: 50) - choose("sales-log-national-18-field", allow_label_click: true) - choose("sales-log-national-12-field", allow_label_click: true) - expect(page).to have_field("sales-log-othernational-field", with: "") + choose("sales-log-age1-known-1-field", allow_label_click: true) + choose("sales-log-age1-known-0-field", allow_label_click: true) + expect(page).to have_field("sales-log-age1-field", with: "") end end end diff --git a/spec/models/form/sales/pages/nationality1_spec.rb b/spec/models/form/sales/pages/nationality1_spec.rb index da5a5f802..37b58a89f 100644 --- a/spec/models/form/sales/pages/nationality1_spec.rb +++ b/spec/models/form/sales/pages/nationality1_spec.rb @@ -1,22 +1,20 @@ require "rails_helper" RSpec.describe Form::Sales::Pages::Nationality1, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } + subject(:page) { described_class.new(nil, nil, subsection) } - let(:page_id) { nil } - let(:page_definition) { nil } let(:subsection) { instance_double(Form::Subsection) } it "has correct subsection" do - expect(page.subsection).to eq(subsection) + expect(page.subsection).to be subsection end it "has correct questions" do - expect(page.questions.map(&:id)).to eq(%w[national othernational]) + expect(page.questions.map(&:id)).to eq %w[national] end it "has the correct id" do - expect(page.id).to eq("buyer_1_nationality") + expect(page.id).to eq "buyer_1_nationality" end it "has the correct header" do @@ -28,6 +26,6 @@ RSpec.describe Form::Sales::Pages::Nationality1, type: :model do end it "has correct depends_on" do - expect(page.depends_on).to eq([{ "privacynotice" => 1 }, { "noint" => 1 }]) + expect(page.depends_on).to eq [{ "privacynotice" => 1 }, { "buyer_not_interviewed?" => true }] end end diff --git a/spec/models/form/sales/questions/nationality1_spec.rb b/spec/models/form/sales/questions/nationality1_spec.rb index 18f659e86..4b8816dbf 100644 --- a/spec/models/form/sales/questions/nationality1_spec.rb +++ b/spec/models/form/sales/questions/nationality1_spec.rb @@ -1,30 +1,28 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::Nationality1, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } + subject(:question) { described_class.new(nil, nil, page) } - let(:question_id) { nil } - let(:question_definition) { nil } let(:page) { instance_double(Form::Page) } it "has correct page" do - expect(question.page).to eq(page) + expect(question.page).to be page end it "has the correct id" do - expect(question.id).to eq("national") + expect(question.id).to eq "national" end it "has the correct header" do - expect(question.header).to eq("What is buyer 1’s nationality?") + expect(question.header).to eq "What is buyer 1’s nationality?" end it "has the correct check_answer_label" do - expect(question.check_answer_label).to eq("Buyer 1’s nationality") + expect(question.check_answer_label).to eq "Buyer 1’s nationality" end it "has the correct type" do - expect(question.type).to eq("radio") + expect(question.type).to eq "radio" end it "is not marked as derived" do @@ -32,7 +30,7 @@ RSpec.describe Form::Sales::Questions::Nationality1, type: :model do end it "has the correct hint" do - expect(question.hint_text).to eq("Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest.") + expect(question.hint_text).to eq "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest." end it "has the correct answer_options" do @@ -46,23 +44,15 @@ RSpec.describe Form::Sales::Questions::Nationality1, type: :model do end it "has correct conditional for" do - expect(question.conditional_for).to eq({ - "othernational" => [12], - }) + expect(question.conditional_for).to be_nil end it "has correct hidden in check answers" do - expect(question.hidden_in_check_answers).to eq({ - "depends_on" => [ - { - "national" => 12, - }, - ], - }) + expect(question.hidden_in_check_answers).to be_nil end it "has the correct check_answers_card_number" do - expect(question.check_answers_card_number).to eq(1) + expect(question.check_answers_card_number).to be 1 end it "has the correct inferred_check_answers_value" do diff --git a/spec/models/form/sales/questions/other_nationality1_spec.rb b/spec/models/form/sales/questions/other_nationality1_spec.rb deleted file mode 100644 index c3faa73dc..000000000 --- a/spec/models/form/sales/questions/other_nationality1_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -require "rails_helper" - -RSpec.describe Form::Sales::Questions::OtherNationality1, type: :model do - subject(:question) { described_class.new(question_id, question_definition, page) } - - let(:question_id) { nil } - let(:question_definition) { nil } - let(:page) { instance_double(Form::Page) } - - it "has correct page" do - expect(question.page).to eq(page) - end - - it "has the correct id" do - expect(question.id).to eq("othernational") - end - - it "has the correct header" do - expect(question.header).to eq("Nationality") - end - - it "has the correct check_answer_label" do - expect(question.check_answer_label).to eq("Buyer 1’s nationality") - end - - it "has the correct type" do - expect(question.type).to eq("text") - end - - it "is not marked as derived" do - expect(question.derived?).to be false - end - - it "has the correct hint" do - expect(question.hint_text).to be_nil - end - - it "has the correct check_answers_card_number" do - expect(question.check_answers_card_number).to eq(1) - end -end From 48c4b458133f0f5edf2a27297339ab50d53cbd2b Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Tue, 14 Mar 2023 08:07:22 +0000 Subject: [PATCH 07/20] CLDC-1886 Add sales paper form download (#1408) * Add sales paper form download * Rename download path * Add 22/23 sales log download --- app/controllers/start_controller.rb | 16 ++++++++++++++++ .../layouts/_collection_resources.html.erb | 18 ++++++++++++++++++ config/routes.rb | 2 ++ public/files/2022_23_sales_paper_form.pdf | Bin 0 -> 394585 bytes public/files/2023_24_sales_paper_form.pdf | Bin 0 -> 421367 bytes 5 files changed, 36 insertions(+) create mode 100644 public/files/2022_23_sales_paper_form.pdf create mode 100644 public/files/2023_24_sales_paper_form.pdf diff --git a/app/controllers/start_controller.rb b/app/controllers/start_controller.rb index d09934cbc..a31251c11 100644 --- a/app/controllers/start_controller.rb +++ b/app/controllers/start_controller.rb @@ -4,4 +4,20 @@ class StartController < ApplicationController redirect_to(lettings_logs_path) end end + + def download_23_24_sales_form + send_file( + Rails.root.join("public/files/2023_24_sales_paper_form.pdf"), + filename: "2023-24 Sales paper form.pdf", + type: "application/pdf", + ) + end + + def download_22_23_sales_form + send_file( + Rails.root.join("public/files/2022_23_sales_paper_form.pdf"), + filename: "2022-23 Sales paper form.pdf", + type: "application/pdf", + ) + end end diff --git a/app/views/layouts/_collection_resources.html.erb b/app/views/layouts/_collection_resources.html.erb index 726cd1a86..289c0c7f1 100644 --- a/app/views/layouts/_collection_resources.html.erb +++ b/app/views/layouts/_collection_resources.html.erb @@ -19,4 +19,22 @@ metadata: "PDF, 654 KB, 4 pages", }, ]) %> + +
q)Q7_+bn0S~xN`F<{qkFU zkCZarm!F0EPKKHBe73qpY8u+ip8+=`7IRId(NLw|HvV!#Gr(QMV^aI6I;su-7?Xh1 zYO?x{l&yMP&)zs{-c;(2>4&lYOFpjAO_c1kIT-OSZH~3$ano50LVNL0&1JaMmvu(5 zQZs~3zLj%@Q5V}pUPkPGA3?+O58dxPwzV<(zYgdcWzY>s%5=Syt9e5bp&~R?x6Wp! z78J3g9ayH~uVh@8@hvlu^@h=5o$EbHwT0cw{=1xLTlv%VuPT|^ zpV?48a28NyLmaH&%D+-=eYht_Q+Xug&o)W>#eH~A 3IRgAp6sD;_ZuDP@b9q%$0CV-T31OfPGXN|8Iv zTi{^|J#A0dnn?nB8K}asxpKWVfKb)}{s}8l4ZU42>kE%yLy64eLJgB=95F(-A7Q=& zO;PS~e&)6iOlX!UNw6HkQh0K#>fZPW`^40Nv?V9#(XPPOJ?HNSxba#PSiD_Yri|+k zG!w%?<;k5G 5+w5 Yun)k`+P=iaCSsuFh`OuVemoU(bc-w(jntYz@K6Uk1 z={vrFIiidP6HJ72X?^5+ZoXSRy{}2&I&xBR-=>U4mE(1})q>&BKnWr|>j;8D4Q-X! z9H;-F$ME>xoI_6nSD$~cEb)F;{s^!29xTyNI&b1hDEb2s)~%Pbc9ht?3889jA62!U zJQ+WI@L^lawe7B9cygw51*d)W+ax-Cnov%>_q~j?LF^dMsh;9+#%6N2FMa3OA=J}y zlH~#-NGia -_wx CBW1bl_Nv_Brc^(a+NvrU*qaug@q4uBDUEvlFHp*{)!1H|=26=UUgi%Xg3I-2 zGznAUMOpC5sLs=Hl22Xqlckx#nZ{-+tI_%sChFF(#T#)(ZwR~OlHO0RCZL9KuGNxs zEZQfK8Lz0{DW@6hdsTJ~mu^sSbqm)-+pz-FU$FqW`M&%)#6&&s=_V=NR$9N@0+(;J z*&O_Us T+^Q*h5WG3b! zieNzEIw!1w7M7HA_DHCl>CV8;SL*FPTvlP*>kpE1 Ywm7d%jJ@O=B-vAgUZ0X5dBIAT&tgWX0{uaQl(HQ5reC FbJv{zsDkM7mm?@TYDW;?1k zm{mS`&(;*@`J@zmF>Qgq(H8qbsni8#jFzu8P!Sh^Y2(dBZ_KX%( {ftmHhqVgu*^`d`HpM1QcvP?)GlMaVh+SmPFOk*Aq=yJ8Ak6Vd!n1@AS}!O9pM; zk4TFS`zq{XInbTh0VyAiKF{JG7su$9LTa55itaYy#XGtU=nkl#&@pvkt=hPv>?t zH8*Rz#*50TYD$K 2i_ukMC+KZrvDnWN@03R=+x0b>x}oCKy!Ec+l{u=H KjHMMwA#1HH%Qz;M@XAtGRFA2y5A`#!<``RSAvZ#Z%U9ia1jWk-L;?mzLfMIZtNR z%B&n>b!}n(NjHuZt+YR>6E0;H- B!1+|dHuD|tA$bCrK7UI=oSb17li_~X# zUl09MHjV0F!ep6^(%bxAiq`~lo5&jkXPPR7$l|ibawiMm@culk(O0ppPi#RgIrg(( zAxHk)9-eoe?S}i3&X#xKQ0zKqmzwPqQ>2US&&+5fN!FBi2p2maG~GUu9mqrPY4@b( zXJD{=Zrk`}EwREMj1r`k?#Z4NmCITpfuDcBhpcvm{he{)_FIltcImvAE{it99ieh% z?vHK-OT4-DeZo?G{>xeg!ziSBeu{8fXPabDB;KQIzbVGL=yjlT@RF?evu#$Nh&vN! z=7x9lJZe=ScLLj8bXgiyW_&}BCa*V^mdt*>)m0&-)4PG{b>OLco}+J|VxA<>RG}cv z%%e1Z%P+IpnS*|W2L;DIcwpXp63?ka-4)YIuyN9@>P!2wy>ahre5*lSo _vpmPw21ZbDt31x5D-6qUazfkZ@5YoIw}V z&ts&}!(fz~`SJ=y8%yD(T4@eb_(KbX*!p!yKx(~EuMFaq|0!re(Sj&Im7AfGeNIw` znmpu UmQ)O0OV zL~w9%-Nd}DO0!S%uKr^ApjIsW<;%09V*+gPbd%5P{1P!}c!A71183LbTG?+yMV=jA zk0BJ_5WE#GcAqHv40Jz0?t*C6@H-I`utSWoE3cDzTPT+F?c({e?j34b^2P6D^$W|o z*mv&VH)mJoddc+(loltygDSf(^;u8+mdU+qbs+=yj3xTb@?f{ZO8XT!&LY~vFrp&w z)U*_iy+ujO%3%;MoG=%W>kZm`NGDS;X)(qz@QKNc2loAIs-*p *FT3w1-qwDRS{N!%2bzhYQR1@*XG3fyC1;T(~2(D~`NW2E!xz zAn#=M;M2Yli_RNaJ2rBjrn;Vk?>`CNv%M2Ix{YQA^KufnV{Gz9xqtF SyM{}Q=hNo3iG?`G79kv!E!?UJ~Za+Pu#fQAn009F^=9?eMU)-G`ior zr$T(4EW=<@!qJK?W2g;yhH;AbxH`?oSwoawe{}<)3R>Lq9rosa@KBY2LL+R^jvyn* zL{p6Q>XU4{57gV~v_kmon !5WyR`5J;Y@+mK3zV-59
`W-8 zSne~8(VVtcO-B|dy$?$dI6G)HNiCvVo|WU|?D{H7(9yThDOJt2eET!C-`clfW$Cf| z>^oCi7!Hpe+mjbyHtF1WW&~$<%tzZEoUx%Yb!P?-y&t`fO_pvcWjgA9{2)aH)>Ia2 zG^Lumi8-axJErT%9+E+bs3@M!W25OFIEZBmTDLDz<=HA?l9JfGE;$e!p|+)z=0`Pf zFzXR~gS0`T1N4ft{7~{CWhYy~>)lp}AI7#(6m?w0-0T)e2rqkbM9 UokaXJGVp^P`@+ zcOXM9-Q$gDseGZS=}*ngHCIIJOB|%ZWAH2#%lHt#^e9!9>;zMXeUZA=!YzZvGR?aI zT@`g*pMu*YUQ^z4t>x3OVq{EXU~FRkM6%$k2qM!?EY#4qXMg=Uh}YW?*@JGpv7>kcshVGc&U~v_X zQzmwf7P4d)Pv(O@v;r?AZH4Y(QW~^Vlk}xnEKhJO@VsLv3H@dfYX8c3lgx5n^(oCK z+l-U&SO)2g+ 9|ld#-b!3&$=e2Fqb<5Qs8pUGjFc?MX?1DAx#x&u}=04u33PiY9fAVHls zdY0p5@Vb>&sE1^ZHD8Ugj|1O;4!fr($*OEkbdu|YFItcmeA6$Ew8S!zbtaZSA1`oV z 8TS|n2=iOGuH@bGCGr}FhkT|v0Z$0 z{@zfjA1a%3Z?HGe#r^n6k;C1VJJ^yToc99;8Ayv9rLDD_6gcmd8j=sXFWz~qrJ&Di zv{!g`Cmzf;y=68$ v}4#6RGZtvf0?da#LcOwcPnQi7=d*`x%Uc_v5Cky4tHjWhI(;(>pr9S&> z1doLV&E7r9{lL~TPRc$jw9j)@q&27+G$WL}CHabuWn5uIZr873#;r>8%ai-sLnnNn zS5W1zg0rJ$j|mx{eN6fOy%pZaR&F`i|N8s8XDx;FYH}-nQn iecB;7L> z$73j&(Ih% OPY_H=4uU9N$XNCysRo+!5!Vl#x~+8d}1~Z)x7x9c#2QK`Wq` zTqKe#`HWyg{{Ld^Ex_Ukns(6;2!tR(gIj{LxCB^&ySoHi2p%9f!6iU&cXxMpcMa|k zg6kr|?at==&vXBK?z!ilXQ8LNtGlYYr{1pFnwj3umu|7|X%9fAdWuh^4*7Qw40|gj zE0U9w-8P>|{jLQT|BFxjWU<6wWHC}g+e_xc%9n&z@<1AzKVyx3>h!fzBe`g0n2QvS zT0Lh -s0*cs6a3Hk;K#n_4|${8E8)9Mv>F;`cA;F0WbLKg~OF z<{??k&i>K-SrnMfBjM8dnl}7xrsB*@eq2K-Bw*ksjw-+pb0y!!S3MU8w6mvBa-m+P zDX~(33#jm!b$~Y$7nqXCV0q Qn!zDG--6!)!mBPhEE0!}wt&vaj;=RFL(7c~V;#$iVjNz@cDne1t) zgXioEkDzf$NR=`&d@XyeMF{l=&&7`6#z}r5;l!V(nox}ELchR(YzsW7)Zn2yvX;aO z4F#YZ7TW+XIR&6wRHVFehavJ=a~%HR6GdQZQ^F0l>swCBYTS$QFtXz|!wqA(r< &rE)Lrv&d75d*bU}jw_VsL)lZ^PH&FEV+(|9qIM91u$gzncE{^Jp52Cv*ep zQARTRRVA|T{I$N}G2Vy>Zi|rBH}!cHvZO ~xx4+f71GXCBKSpMJ#zCs*iN^jhrj45Rl&DvgZVU=+ts@(cw`xz$W zrfyzJ3Y5}EtUrFWLc*?6P5j>n5H9yRR+Zh3k4s{~c5c+U>&%nlCGWPt4Ysugv|1T> z(Z^^P#$S6%fe4;KyygI*Nw{OC!JNp_6iZsJ;nd`%lz3HD%ks%xSZ&(&Ceb6Gn(q>V zFF1}@ddKo9{3qOI)U8#Hf&<32ty7R=XpMa-e5&qSa}-msRNp)Yo1%}3(Sgb@wcq-d z{!;I`xM`=;e2Md@zh>f0&M#h<&FDz1NQ_a Vn0qayBVq( zqmI6 +L^G5qoGzOvpxqBR`52A9kglX$@ zk}S#6=i^|X@x7bR`L{k1#yQL30e1SOK2d*o `~0 BdRa!v9=qguydlTim5h?K7>w{1ijYXRB-XIs`?lu00l)k#;sw7t z*=R%+FNB|I2;M%gC^EM*HL02)f!^FRaZ ecq z^QNlR4fM<9#xs5i{PSis-;GA{ozisp!w21=eci)&P>Fb+4CB^i$mvqRyO+zK%4J z^-I(j6uldM|Eup9|3}-Dv9q)D{P)`pE5LV*qee7$0sTn x~=6;*B#tAy;dH-W_9#DXaCpM;gOn-PLXd9y`0*O~ib*yMNe?AdW>5 zo!p0CxjlqOcu7|@iX=_?R&qmj>cK6bVx3MA4)W*L+Y{-}i(;iWa%7sD_)= _OO`-qLVo5u?K z{exGL ykc z0*K*f;2Q2c3+_b1!tAPcy-~6f!j%$lG$E0e)Dn>3!`&B#-}hemM`esQpt+d{&8ohV zBV|7P5mMGTRi)2+XL+RE5cE;8NtvSC{y-{G1OZ`>kg6|K_!!)IwS7nMO&;B$IA2XQ z3^BHH6%Jb7biMDQ%qR1%XnV2JvPb+7A64#CA>RC=t !W~P$E>(p(3Vpg#Ihc$PS2C9kKzr?*>`Z&> zEt}v%K8;+DH zL5dEXe|9piMLjdo zFYcpp#0J_XWKz2>cI+gI0Oen6YXk!L183OBU$ja&Y9zDB<3b~hQ8y)`-j$p7OUh%( z&6BeF!l6Qx;-NTn?GebD?XoN%6K}L_Vx*j_u^>pFg%NS}PWV{YJC-w)J2`0Iep|<< zdZ%Qz^YQp2moGt0)mN~3uu_PvDMr><`8Ij-01~^1RsrAK2d6>TwuVpqI_w+xKQ7;L z*6EkI&LVJi+K2?n(LUQ%M5vs}eaG_YQekm9wN%N)?TUM#p`b!7^rw+}RoT$O_zVu6 zAB%8QK7QM=qo%eD<-S_VZ?p5?@gv~aXTU7^nW!lVXK&I?qGZ%5$<9`c%XZ6!88_g} z<^M%nDRYTMx~7{7XJcp8y53s(f?V3jFrVnuDw+*zVluR1IJ3ISa9QO-kmVrhPVN1n z>YKb&O|BRl?ad;Dm6Q94_c3=AqOw(Mtj!WJo)nbHD&^S7+>1x$&hD~W6cUGaYxTy0 z%+>*VRMY&OT5>Wn_1<#6Zg8UkMRI%8BE_;kLyzN6wRGb>D;#f->KaP$_$@qJEg`+C z%V$^vZ|9QCo=*30%g$v2B9-7W%qKa2PMEOSM8*d6d?UIwQW%SB3oHnI5Gj=r_ryJH zjdE5#U^y?#9(9pz7nd_?h+PMTo+92KmR+=1!R4TT-Fh7dN{=Z&a&7$mxOwQzDP`b) zWwLQ+)_rRt|6 mxC6*auK z&(_VWg!|&>Gr-zc_O?;%=6oCNMZ>`f{MzR2#Hw3gHc3$M$;PG-;^X*Q2N5SX$0+W{ zM|B)M=m2e>(vQG0b_GcnHPSqUIUElcon2Q!((4cDF#~`$=Z%0iq}M73Q3K*ibn+#Z zm +@Pw!a2YN3Z3NF$BJ62I5X zQXq81tw!Wb=}*=fY`+qA68OV2SpG%##}V7ytHG0k8TdtUCFGNu*EFbFifB!{WlLmP z<6@i)GjF|GY3`YC-VfvBFka9^c*c2Z`HG)fO=>gWJHe-aSf`)iJYf{p&0Mn<{xs^Q zrxZJc8T5!NwQ7No&!}LJQ+nh1!(#>9vFv_xw`zmSBW%G0VXAV~= AASygA4v_YLoc`CA dj|C_u%$xWd}gVa6rco`+$z|fQ};5;!68ZWk-Fa#4)QY zy()LKn?KED{ONApyO+&%Os=s@&uNt=c@I{GE>TQ>n?$!b->2CvhH G#CN zd%oSg{-yiP_#iHGQq{hN3SInxq51e%luwm-T*rK)rj5xEvc$d|!&~I`EC=v*{O)+w znTU$FrZTy9!&a?dRi+qzfTB$I9l>GFFOrtE?gPgIKWW#uCq)Gb(Yu^_TwhE(E?zNG zmeh@SwUmfw8l@;KvK$cjMCg5}Bs)vR)EsCwK>!ed@ADYz8Y-Am7|2HGBdmy}(Romc zRa`~A{#G+W2iTA2Y9X%HdVPf%3unE6M|dakyY=h5AE-IGUFz8&g|$oi9uC3 rAS{=+<(vKP*V#XpNR=A$#kc!=S&s zF-xK +E>rx00U+vlYt~q%+imBXhCgPlzQN`|uf9T=N zPCC974gQ9t@*972m4$DANUd`TH=i_LZq?fZcxe7fZTCe>xFd4qeU|I#8DBR=CzFT{ z(h=K|ZD+p*v4Esus19!Zy29AGJUP`^$Gi*1SmTIcpeyNXS`tu)87<4`tLIPU(Rug@ zGS#ImL+6t+@sB0rQN|>PSXx&imyin=KM^CXfJXUv<689UK-qC|hEU!7Mt-6-0r7Rj z(a% okeNOdXVGbH}W {Re@IGncnDM-=jfR z`neVIig^$dO?g?x $i`_yj=n0VNEXGX&Ole!VusJ)PzK1=cIFESoJ!%&qq|Oh!NyTThT7%M~5?8s#x=> zm@Jm{;pa8mf;oOb*Qtj>6#Gw%0r@|~NGaU*f8a3wAYh$7VR (;08#dLi3#q|cc2^MoQWq`yDCxUF_+W`*APGv4AvZS+`d zHtaTNF|G1fx;%akDUdB{!3sM5J|)gK26DtqA2-zfQIMpF#-SNliKvi+p|NR>QwFE- zIGP_%izS0O?A5pvdG)nm4I$51(3BtAw$tiBk?nNf7a}nxF&+T#GDBbNRksk3{iX(7 zQj8V3;>eT1q|hu-{Kf}Mg}Us9$(l0@SG0&=^|t@5=B&%wb$;Rph!}2gUqFzwq|WM` zuB}5V6>7haU7l>Pf#P_DYN>=qcP#gcpw0c-*Y~Wfq4{mqm*}2YJO_sFzK?{pfJ>); z-Z#mc8~F~CMsVjHbP-Drp)Khbxejvdiyo#e^q8~s$Z^Noq~nv??KayxR^?3xH6#4c z=8q*{MwGLLyos-%_0AffcfT^l2}$wA-nn4&mc!e% T>#hB6Z<#Uur8 ^WJLtYCWbn^jc-FS+L<2{D4UNav|{ekQ!+ZKDRFHJ+k8NqmMEc9Xd~q z$GAD_%$2{a^wuaysphKQYI&Ww%ATVA*}(1YIt&_RC(CbX?RICH7W#SsVHI1MiB%UH zdd?aJCFa@QyBEz|NDm|(H{gq!VvRbXAm_ G%0V7F`tZ&7Tg2cK z>`O*o>NSDYwNI;S?t>}Loap6Vm7hGCk6oIMD?CR|onOXPv(9^n=-%%)EGvbY!|{D4 zzjd#Oxc5LBaF(c>yTV#)a|&yTh)X-9V!WO3@4d9% PIChKq6^pY(r_fh;# z9N)#n?Z=%d{)QQqN$rFR*R@`cd6+pjcw$o_PN)2gM4BnVO>C%V`4H5W8F-npsk>#$ zaC+L8fLY)k!Mfw}YW{=$J~6Gc291pSlgyNUfV%`brUS{=PyNwI5AEU^i>S-)Hiro4 zv(iIHeZdNU&i)CHn&g8eoSnO=fbG_lEAl+E2@}Tpf<%+wb=$`s=?qauZ7sd7BkfO( z9S@w<&G;_O@giQs{*TOUdqtD%?q@g>U%y{6oE{gFagGj*w6z;>!A%zIq{(RL7De~hYj|br+osC&1de)J#n<64Dt0v6VrLOedyLQ~>ghy9 zplU!maN-}YY9@MbePa05O?c??hri-_E7GT|^3&_PYk@kR87QQPEb;Cxz^`$g=;Qb$ zPJm|2&0WQ^z*F_39yHXkQ1MZaBxUsZKJRL|HtpH-u2FYhUtoRBJ#=|jz?G=9fZ=H4 z9LM^xc5V*OUJV&)@e#!)!d24=nlOH6HdIX6j__ cO;@)eKno1 zd*b0Se?m9+e(f;b0Y?apbe7hQvsnCQss7?>xvU-g_-=lAVx2L&U7_%>AM1dBmulck z3fOA5iX5mpGic*c?!N9HLiFz%}#!~BVHw= zzfZeoGxp*=c^(<)v$fA%a*@t>P1kfMmPC3PRBT(G(&$HzsKTw%${6vuwrRI++Q4-C zyIotaeu25C$^W&9ms!kYK)QI#^)NIM19wj$SUHGMR7smfOFX3l)Sk*WB^ZOsF);qy zyyJomWH$bD$}c~BRv^zb9#7Elt~gY4r+A}wL+u!I3CC@u$Uqt~-v}a2ouA8^moEF6 zCC{onpgUGpR?1KsOC>td43hn2g4^IdJa$szV5ca1el-Nh6C@7yiegO%wr$U_MEL}v z${HEI4-0Z-tA%94x{Fd%M<+@ez7Il%#}1uFfX9}VWnnSs??s`;PlP~xgOIVXx6Hdc z0RpNl3#-r A1jwsvx7Wgl>wY&UK3y|BnHC9^njGfRP5}R49PAiN;5ttqQImO zCTG22QH2Yj?^Jz-UtAdxgzYDWzx7v*K!gZl0iVkyXaOI<)%goCHH{afJu@ ?6675^E!uDX{(>XQHrd3gGaHSiR*1=dHga@Y z^qeD#PwpQ-R4eZyv|mf!^-Vovqk`#6-0$d(*j<`>US2Jr5QYUHDW>QF|dxyW*$+m)`!LlQigW%F1s^_ ztZD`^eyLN0h _NH1Bv&wbXV~zJw|5mNFK@D zngv1sFGiaj0Hc$o(|z@r&}{_&ivj6XD>5Gav8z|ztPbtX$M6mh`S??_{DS scNljU*D^JGiaaegw5E9N8Lrp5Lvq9oypY%1_Ep)*D^9MU1fT-gec{Uc75_R{=>R z8JA|!Oj@^9gQ-QI9;K9Mt9lCeaD!>xQIaZD+fyT>ePcOtnUw9ISvqWkOr~sMOty?8 zt(jQUZIXs@CCSsC8mkgUDqD !7>} z1wo8nd;nUo&_aIEpdzv)c0ykCpoZc>egT;u$f#KOTgW{x5aIDrA(h@j@FEJYP*^PO z8F5%NVRQsUI8^Ibhy~tV`|YnxFB!R48-8nhp0XF)XXA?VyGYg6+{Fi)1lLp93;Rw- z{^p?MhQ~_vMVODVVb8S}-s%uecE-n5ixeMp&zmBrYw`x30=9!wVS)_4>UJouqzy hcM$9#X1R|nN3YtapeVcT24Hknt%=QuEU bnA@K?4E6QQOke2kf32qI|G zn*#WG1fY##Hry0VXehS$4)TXhzcHAQOfiviJGGcmZ1HoyC_V!bj(@8BZ&@%BG6oai z%R*SZZ704dh1zH1AtF*HMv_xVHFZY9Mk&Gs8G2Q#lR5J0T~j9|-Y+{i8Q8dUbp(fB zF*HFK@hk^lrPy@^=m6+YJ gT^B?wyPREK9FGmu zdOU54=UI3bQeKCA{-gg*VEqK}fd`NCmuHeIWM{U|VYcVjXSv?)sA 9++efdFFloM%< z4Qwq?K4Hi7Hp5Y$>%ea(5j|FAW<$Dg-DBHTKFC!^A!KUELo`W3_N8P5zn+VS`9t(h z0?1SMG@m>GMgGjmD%I}5bung~LCi&@B1LDP{;c)TUqqCfX0rMS6w}A11&SGBBLGdu zsejhWw<-!VNwSO|GEAb5H#d|@rm9m|s%6mv4Vg&2lliO}A4f$18ZwmPl1bJKru-bA zMg@=zrJjvjP^*a>3}_pnDmMtojMFw72sH{PEbJkr(f1t*@p8&9Zq`SI8I|69TW|zN z=OM?}PgM_3S?6(qWu`%LRkgiSSTauWh3%qMqBWvbxs`v1vAVGOu*RZ$qh}Hj;%R}8 zWc=&+(%M2$Q{2)KXcD9Zk^%*R%!y=@AyU}v(bT4ta-)(b?7AoZf4+0nbp#P;Iej(_ zdS_~c>Tbk!Gl?LO{98ih!3-?0BwdK>xv5k*&|h(cJ=}VMGAW?07qfoCO* | z7~T`*7G=R}-c_1%PErevbpN>pMpzfRMIYeCj}6 sG cpG9Cns$7daD_AoDI4*5^#eVLNp{QD_o{m%y@zhSIy(Wjg-+I!AP zilLD(?q;y6A%H>82|$JeCJd`@N~3w!p+8590Y`vC0IOq*8v!=1VcW>?A2!7Cn~Eeq zkGNkC2!Vkr$#4-n;&qaNxXng8;`#8+VcYSPD!jI2`Oho|JHyU8_u(|_XIo%W_klR* zcWm~ll;kKT_kjfH_e+wA_RVhRVg9VG`_R8z;B@x^=k+s@QAvT`(7z(%{| ZnSyY#Z01KrkNs|E_uFud^|K=|)4xe `M?Sln6mX05;=OdPP z|E%lldp+$n=s$a`La(7B!?wcw743&l6Z7l(UJJ(;&-Y=DkDmKyp8GE8_WjWQM$)#k zhwmfTI(*;4uUxJUDRCYCE)Mu!oa_zn4(RFa-bY+VOkB^J-tvxlkfyz=)YH>9?P;BM z*438}KCn$&6n^+nb5T|c!Qt| L?#HVc z;&rQzl8x~|_tG^Q@sIH`bu~ay0pw=5h%JKxvU;)#$zbc7qLfhql~uZ{#pi1#8=5EQ z(Zy3FL>U{H2Lri$tz?KfgIo#d7}lF(48V*Gh_Q;YQuLB4m?|3h_s`S#hZQp*&22X_ z4Kf5iCP9!P>6qbYZKm1re~9Xh9*lOX%0-UnVEtfjAwJa`y2U@esYe?wQNz7|=~!=O zCmvA9#K-y+rL`l0{b1%xCU>55{9wk=rG66z%mbIFF)$0A%zlqLE^?k-0AhaF5$A4Z z694>g{eISA%2$nc`+u0`f(OzznE2u*vO!lOjQG#E-7WeoV6Q(;)2bC-uzVRd5YW(z zF+L?}PK*NV`wl<@Eeu+*&`fuvW5A|^nnFP+GTZ;bQMa=uj2I2z4j@vlQ^1V>b^DK^ zc8=Ku>ia2G{denGFdkC{>Pm9gc}4BDGYKs)R{!+5K_780gkjAOn&|<6`X7TXXT^5- zf3ufY@wa$CRHB5N*3-U54%&D{qS3xN Qxg65%~@x@+i;Y1 zx_g8d2I8*gBns`DUCs{}>{D-9KRhb_JG9*Zu&~_*@2iv){!ERc==MGcWS??|Re1)s z{}s8)Ls>uDhJh;v+W2o8G47^fpf`WhGW4&n;Y@$Idzj!t!JE!^oD#Dx-yY68c5->4 zW&AE4h_jC#&b2dN$BPCI&z|;g+wV#}3p&zMCzaPeVIM9tnIfO?q!XVF?zP={e6mx3 zh9BhWs#B=&Wkmn QLwJK&ogzJMf*4?yU4W z?Zenp9*G>b`xSLiqZl$_TK31;MC~HH=82-7_;Jv>`p{Pw@2J^m-r326Y6hjnbA)Pf z!EvY@#pzSkVNjaYk>%4EvOZ_mI3*bSsI<}z*NJ)|31S+ZM&(3t7qx0+>YIk_M7_8; zKCUjTzOcxcVDtqbB0I$|Xc-Rlqfa`&c9L{@?S$i`w?F}Wbir#+c#s#_cl!kYtKiIk z+bQk;`|UaoHtzrSvs{uvmOx q0+`RCdcUpIQVw*8MthheZ7q}pFsykd@05&IC zX_-;YaJ!EC>oMW#akA!?{&p=Q>VEEG{=Vse>?CV<_+yzUI&-l-OfPUz?f%e9oKhi5dv6`YsYRnbeG9uo)vcm61QKB z|I!?hr152krr*08_UB}G9lE7`_kdFAt-JZnU!M$>#H&dMwe}BN_Y55dR)JH#HSuf7HtRlesf*TH#lTJuLqcjC|Bvh21Tm{@qUWRxgX>h_WU| zEt2?X3s*aOp%1@h1e_w*QxnrEj}7)v7K9Ys>(>4`w5LJ>dt8}83Xoc^yX29<E z__kO2k8V?@0>vpuv6U)p&eFT`>|otj`(5(-Ra8M~Q%yh};et8DG$<{qiJi?^e0O|s zWwGnTzLLEg$PuK0QS40(PDZPM;%jiu5vZm{Et2Hu2&M>uv8i9$E2no0v%Te5PH~kb zvAR@8OZ3$wGoOE}Ay-Jd%yu$xOF7Cb2gRuVp^W2|8k1K}h?(h;vapFxPRmuMDe8q~ z2~%^aXv}-12yLUq({eFsnxMB@UwJ`t7I=X z7BC-CSlXarypbC5wCi2al{eKv@tpF_sNJHGJ13Z@%&?VP_;)xyjd8k>`rwI`&fY?Q z6nfFrcO>B$Lvj{F?Q)V_+4OZ$Vd)&!0_a_xLCoruFuhXuo5t#Hs3POM`T72ELZjmb zx-Rg1b8&HZ? @A}9{FCy#Ne_y2C_{|8P taJlbePoZ z{9B^2f#r@Jcf$+k3 j%z$B=n<)x6G0ggh6piAvf?aSy?=RF2)c}5r5)BJ za6~T`^@qez*_cW5>d+w*Rwqcc#*uipkwfyRLW~R0#L6mCI=?6yPdAUbSz6CQiD>H= zBE`~gvKm*-eVK~81ij1Y+B%^?uGf=@Sxe+vL`D`rh?mHPh$z4QP_)9RK>JfC)XD|< z3LnUoX(UUFiY?vm_jSfk1plu4C}5rU{@ssJ^cDx<_MGr=L{VHpRXA1LNHsVWT${p| zzVzfJFAM2AOJ26Zl6rdY!k2;c-o-#7*p0A(f!NW?D^d%mO7y!9PLHUv4o;Ma{FcwR z^5V4?5fF;`$wh7kU(MBvQQmdW=R1%1-KujA(TqPr5Y`1ql!$E10Ij^u;0w7rzy28U znBic-wDOKNSLT)bpBY#uw*qb8>tU_$7A+~(?1R68SuQW0-Xvyo{r-iBVRagz^$8VD zqrusN;#z6CQ?wS)Mz9X ~n~FTKb{dtxp587HrD zIj#CBzYL8WR+YKrU5b{t !ZTbCouRGj#bv9K@7{0U??7vR( zAC)k;Hq98(^IBOT!Vwu&570@E{~2mZSLfxRaTnZ{2-cm}@mpPu3;w~P{8Xy!DbSgl z+G+G=#xpk-RrU=$H5Ggdlm}ub2Jv*^7!ok1vp49}F`>9n(nJDCG0{F!6rH)05M>iO zs+Wf-<#;re_`tK}aLaUF>U8jll#pm2x!LoohS*!mg7#ZBmct&OH>A oMN4QG7+^Gcs-U%6`ZrGVk)i4ic{!UxlmmEllw~p!M93y4f<75Z zP8cmFl4$lC6YVUULXRU-6kdx%k&Oih5tRzQhx4E(3*W KE+lG$)_yYK#W2{a=Q zMnnhbXc&_(aM8X`+9XAEBeJ|FRAe(4rUw1b3=|UafHs0yXhxHQ0^^Lmo=kNlop JU%9jEjG{^hzJp9`;Ze3X2VevlEaiZ&Gw-rEF{pR z!dBn+Q)4qw;;;!stTwwTD79ASHJDY k)zz<{68xKu(^5*iQ zOtm7sbnbHh>pQ(e_dQM`mBV1q<9Bn-Q>`X7Uv>R;Vx-!>?9blCFTUvDTiVKCyC>Kj z8*dpE-pQ$ixrzz_>m!d~3KJ0#CWTFr{+ie&fo2AeKE2Vja&xBclN0GaA$+<9wP7ey zVk~x|?DA4XEMVsbow-Jk>rY6s<*!GX6?~WoG(#IwTe%@j|NmG3c)g%TPBel{_q!h* zTk#K>e{V+}y|c;m{ki2-jvjztG7nCP1orY5#Ci!BzCk3VNVJw8apV^6p#p#mppp+j z1BcKQs??AwT^c FLxJfq@R`MA3x<+rjQS*SW4@EuTD)xcZP-uoc2w-5l| zlAXf;LHBR(A|w;!#5{YM&=>4)Mqjgpbn+vy0Pj!0N_;H#yYUN%CJ2d9$bj+3`z(U` z&>>f_?xAw9y0@czm6U|a7k+Bzgr$EuHHW^k1P2gjQ)qEKsHlHr@SswEmM-<|u7}w? zMK*;j2W3cr>|~?}2PF(I7}SKqq9Uzkfp} zM7>FG3^dJ-2FRZ^VLUYANkL4sNVCik#EjGY 1F?a*hD!8aqPDaK9+^juZLMd02!k2(j33U;3YT|Md2x7f~W{FV1fp- zeW(dFNfxlM>$m(ESq(shw6GwmOM;~R5VE#Qw>sigFd{IlK*U&>xNx(~KtxFxCutZ@ zEe;#e%?YpTXTuIslihWNiTO*Nhr?^ y9NYau2mCP{IBRosFBIe0%1W5wCA&@Cx+CB{c1JN65{wH)7pw zqA6bmo_0<*3jb{5Sn$)padYabUg3H?dfY62*IKfzY>h+fnhG#97pZK;W0z@pBjfrT zK} TQ` (<;2%?)k6ytY*ADmUk~(oQIhH&paw1 zQbFpI^F@Dt hajoB}HfqNUi zv30wh
zrJ z4OU1VDcZGr6VJYs8n^vmqnfroW6xvGL{pX8%XS;i$eAGHp^@-V&UC5E*#2eKS@ss) z3O9@CF--S>sKtz_1)6wHqSF3l$yxR$+#jlWN%CQxbpxF5F)-*H>JB84?nuMVEC@2F zeOMxuy^c#FoN15K$UpT2gyLi5_r9qiza6ywMS?VJn@NncWD7(QHn _dA8f zFz(O?oq-5sYRrpVFxD2Bd|l|Aq_OcsmOIjvGZ6FWa|R-i!?4^EkkDLLw}3!#(9T(% z=5(12SnTnVBoZokBhNzvH)t;flRycRz{kaUyHMeBqhN3=Iot;dfys%5{!+)J&meq} z-5nb2j ITA*KMnxVKBpvR>u|S#MuP1>w!oUf+sgJ$TRKdf3IC;rS;=e1 z{U#j?CcLVncKB`BkdDDX=Tj0@SU*3g;QfC(Z-Tv^TAp V+B{sj-+c|$(Ju4=^IA+%>o{EIn-kNFpv z!4FLZKwOwj;+=5g|8|atIR$s11{ftVY*9NUr2K;e#9XARc2a98uwLAt$xC{XBYry- z$Hg?MSmLjv=4Vs$VB gds z&Or8jho-e{nh`CrYnq%v_YV>-ySu>|C0Y)jLds1hM?g=-IJ%?R|H|?;d%aWGG8&-A zJ$^DAFG5ARv^)uIJ*~R}qiL=4{|tww#=(#WJVJLOnG(D`11d1&K^a*#6nF;q7>aQ( z$oOAHLH^tC2LErOApg@t|FH>j<=gd`{=3e&gr=vU*(^zmSEOKq?{ERjpKOo rq1M`uV2FO;fboKFUq#77p4+7G!bOb}sYK&^I0k&V8*2u) z)%~$b!gb`u*^$C-QibdBBi(x_e#ZFj`FmA6G+D0G~&u>jHcmW%f_5G#`*(Z(p zy~+Nf=%u=h))sZlKUf9osiWJf+A#{lq&el#j9nF`3{UsH^9Rc6$*_yGa9gZfeoHIY zi?NCNFpFXAV%N!8r!Y^WF1z+=Ggb)_?tIjyKy_o&B;1iwO_L!ulz5lexKAUkO>3o~ z8WW&a7IZO+b>CeLDg%xD8LkG=#~ZsC2jwJahbJ0>XI;fw+_ZIb!y)6r*x%wfJ-5Ga zYrNC&G*&ugC_xc8%E??k`&y9i33|{;EgEC!pmPgt<`vMs1#BT0SP=7X2qp}XPiU8T zLmUbw4W~h2nuJxgK|thJLGr?9n1X3w3PFa*ILXvJ<#22`dQ+Cs%Rc${D9|h*&iK1N zGc>H{9?>=C_1}8J+kpKsE{iwe+xuFGU2K8QxgoqZezzn%c$39PpdW?=GdhSo2||^q zIi &;)j0yhgAaW-7Xd)UCXv8a3xm&)s!)kEx8>w*zZA0QGt7OyjfFSMvV~&bo zYXCWH4PbFcT66Afhu;AIf diOE_pCQNz>s6J?fdc=Y(Z;Vn^vg=Km&??BRvzp32E_A{4{8>aUoQvr{14b{4p zwYpWcx|O9N>@r|tndZ!o!PcCf1V_=^u^S;4<#}pDAS=9oe+j^og<4De!z&~sP6t-A z-BW!@FJwUlwG&Djrsmi{H2)|0xB*R4Di-k?&%C!1DW4cihs(Vgr39gzS55LM{#i{N z0DNFQ*fI6Z2zxnpQ4_XYbIv|C5txA~@WIpI4<1fOrU~ny7OKU&A1Qs)DzIa6U#2N* zp%!W{TPf^pHb2-eoQe3T=x7BfnVf=p`pZ6R*`*>2P6SQ!OX#K yc^wu7cnUt?lp@d-BTmEt(#8G8bArVmx2y>{m$ zBNj|GuH`1TI%5Y-2krx{Fn`!QYi2Pwu~3>`m9%4b33HFb&a(I6$m>-b;2oG}1bn6W zI_o*iSDur|!YpIqmCR8vl~Wg%1oPW9hoz!5;w64hw4> 2Pn zZ_opvoiMjV?mhsV*3tiX$$umH4gh3fnXh|WlRw&yMP?T!XdCQMGN~HQ`=XUVzHrdF z66QAnBd-OV?ElROaK?f#og$%-a}uLI034%sOf|{>jl;}8$c**^b4m+y$YwC-in{J| z{m)$k?7ZEPw!nMs7l6%@OXMV_-ws|&ABqGY*Qw2a?oqb #`d$;te^;2)-4UAc+>En(eKkC44Z@aRuBQ#q77#8)@=C>w%D(z3N6*2VP3 zNvS%dmuVazV7JgNh_N~=jqB Ji%~&{~;d }3MA4USV{=ASYyHbS+JO2!T<7CcHp0Q|B`Gd(?0IS`S&k=P!0-hW7(POoreMvZcpB z*9;iFBm;7ToC>Qg$!G*7Bf*(?P(jesw@(3M&Y9RRL+}pSFQfAoXae;4R~%H>Ins7a zOFP9zV09K6Up=6~_k6iaLoU#DK*Q9(yzO}MUku0}5F+43gT2W7N2=Veh )x2xr5YVT;|nMQF1xM zTZ8#wL{x*+azLA)A?o*Tj7AmUh}giR* ljVVY4l0@=QyuN1H!hOU1On_6qb1>I+ zxgOz8ic0KI!$IQqWh-gbSsKE~q50Xire5$ir>0)`cAf1v1R1
9Bs4uo0RkF{i;;N?7gSQ;L<3wblv%)?-3kdA#iTJ zqXBTN4_?UNGmSWCz=@pRQRBg!i&BP(rExFLfI2#uzFVDJ+rYA~8n?&kf>J8f%Fwcj zM#|7K#`I8h$a?RGOeo{Wyt=-a0CRK3<=zE0mFV6@AR(AeipE#LGLdfoB`UZ;Ju;UV zZJ9rFUkPk-znwpmZf7}L<5+C;@oyL1ml0iatFv5#&!0!s3AA^lvr`%EsR+s`$K!e% zqggc0{i$Det21hEN>?{U8})Os*XzVnvez$G`8(&2E|~PkmrO7Hk?N_fjc2r{F*u=I zN%L!pL3PI3l{Z|GN(A2uW5XGIU6l$28`#qzbiebde3bwk>(^>6(?k~0tZc3dxs3Gd z;k2~*%oF41Dqq>t@h#ak6{9jHN*fg7q)K-c;v`Dn3deLF1#x(VIiww#C_|`UnJ9mc zH3@`36OwRRrMi-E5~X~SVwsn1Sz>%S=`3M%4B_|?oJ2{3K%7*`u0S9M;~_uiiW4ef za6!uw@$!O}Qa;`Vr&XfM1t(F$$K_x52;WOuOVU?6N|Jt{d0LjRZrOc~H{v;+9K(3Y z2u{^=*}oVME>Lz`9!!@P@>j?Lt%$cHgohuuZcxjeqU@mW%d3;^pxpd|WQV%yR6}ec~IHdQ?cJbDaR!X4iC#o5-=T z<=1 0TZu769ERZQj!i+A-On!Pj#3yMY!A9o9=9kOBfg~?EeuC5@ zr0h#W=Mx!Q851igB@Lk*D50B-;(+FQG|J85xxN4~>egPr8~+boQaY283L|>k<6y&= zYEga1$SJ!07x9g}-M(jK3Z?M}9%Eac?-turem1cx8VRy0mfB|A*(M@nsXWDRwP+Xe zdO}Rh4H&g3jQpc;<<;@E2q^lZ;(E}7Bmb4EjQS#1k0h}^q~L2=OGM)X%MI_RYNET} zSRZ5_&5lpAwLWXgaA8)DMo`)UiBW)qCuM(x-)$5#2OLKAP&B6}WeS-iT!T?u)VAjg z-%6C4!W?q+>Mx{%P!MNs-G2$EGD@Ndva24AG{TSO7Qy-=*^N4cm;B +uP`v!yN_46T*(dcTtl)eQ3fhcB??wEq0=S z&ut9zvKfn)?_mQpJ?vEeu00@kD{TJ+*7&Nxa^*Lc-g$&PnjXom zVWMz)g lz`b@|D{`_tuhE)H_W22baG4SL0ZnMqJ#pMWt7y-j^a~b){wLm&!-2^8ns7b33}Tyl8? z&)yXFtH+(HoehjNm+jV;eEWK+TeMo80}{XgQ(fU_iX5}|$hKQ}RJIo!eotO?fyjts zbgLnqXIThLvKQtS$dWp2BXF+t_2T$QbDve<5{LVmtL&S(e|mCq6=Cc@MiBxd|9CmG zOR8a%5PmD&9gOW-dRmh>!5d2g@81PaUuwVlc=wrm8K-+l2qWpO9vyuJECl$j!m*7` z1~aDD+w6mwS#_~{FEzr_gv|MVYVv_z -q}Fa z?t`oQgO}Phoe`Xsbxb##N;ili+LuPpW}K8}2)1%~&gS^qFZ?Sl!iD`D2~ucV4`-<= zml>tCb(f7=O<5PkL|pI0El`sbx^L+jB= nc3fxSNj zkpMqv*Ns%_kV?DDzM{G>pCv6za8jz>kCB|d;rLZO=1yBka8PX8b{&hOvzQg_lPB#^ zC&l7-j$d!-aq1)tIETo1^%W z5$m*egya(~QQ#z%5meK1;<|f4m=sP}F3E)W;+yM?{p#*1x-pzB%Kbji9&;?$)ouoA zE_vFLarvR9E)bWYR ;3b zfdV1nT>p+bhlC(O5a18^ulSx0bPyOA1cpGsh`)l-!Tue*krN3;fe=sx6i&wp1*1U_ z7!r)2gTPTx5H}iuqyuxKxj|^)58`)JM_|kwLg T?X@=AQ%Kv>Iv zj7}=5{8y06f5+UT`z3z)ze7<1_g&TNDmvdE&EZm3=T--E0}Ta2TOuJ)5E76)L=yp1 zN5GLFC>Rb!Y9b-(NEj4^;6|d6nkc9`5&{FkpkNe46AfI(jRe8bXc$xz2q35qN5MgG z6y!?cS05xC20~xSPZNyb{*?(D0p&(&g3$ l5)GswK-_RJ7_JFHbE^Zr3)B@jL;)EBHzAPRP)$G^)RBK>h}484q3Q^r z#xMjNh0=tgz(8ZTL2w{G9&mP5XBZj;h9Qw)O&B){NJE2wh?GF~FbGgdD9};_42jl+ z!Qp^pfYPp10ICT?00nZxKyVlwhSY>}L)GCxfp9=2;hMmaI?yl>6oNoPG~qyja3m50 z1Ij>a!qGrw{!T-HfiyG(gaDcc1;h+fhXPlEq1*@*a0av-0tZ3iKv+_sR_X{a1cZhl zfSMtYC^{rJpzDB`5O63AOos$t2@M58p&>x~kr0Ub-)WjiI9MHpMgjswLeRh&&_-@F z2nhsU&;*3^tIN S9OJe;J^{k zo&UN{6AS@51BT)Tp&)=1fm(n;Fd)wAl@l@o4ulAWLg6qv1Og61K~daDIs_B~f&rqw zN`|38+*f)AM q1F2JQp&=I<|oQxses0tSWz5(NmHo9^lu=qEslz<`gIIs^>|rX8Tc zbbwldU?`w5bSOYwz`w=`7=hxZ1O9-42@M5;T&Xs23g`kD0p!RHs0~mv6c9!ji~ xX6V%+DC}}O5yPZ;!wXOTIusQ)! zitHq1IU$;i4Ezwu1$|I-%!wcqeXD$GoQLlV(;%@IFCL3^Sueew%=WUP9pgz44}8?v zljgl?k43&im{3{mz18Nr*)d^WST{Oh{u)a6@~)lGqt=X0<90m!8I9p|@msV(6Q67s z#UmP055JMSj5gaVHmAC5CS6WnDhH5r<*g$by!Z>18|83=J;c_+x)$YWe_{x4{qSh8 zmz4KdXkl4cJ-%f^AnW_WOPP1Z*O-a-ET^Zd^Zc+(2SeD~LU84} jJ{KIv#_Jo4*=5rx+TuX6s-4wioAa -C1~iCj^MpK$jY^ zJM}5I Rbr)VOkRr&~0@fYPfJD+upKOOp$8b`D5yWPSQip(J2 zzi|q6BeWEntfkoIpE)96^?m+E1?!EVNu+4Mkh_O*4Vfib`GVfddyiu l_5t2$g_5Cg78DG$;{-HZo zmZDXIv0Rji;eMKkr(EgJH1YWX`f1!}+YhGw`9ED_Ue)qVWy14umnHm;in~qpIt(Is zC}F~!>?=Qafm6balbsnXv@G!qfEBMIm_sV|-hSs@Sqv8*pi4X;gpuI+Ye98~TYgYS zHopPgVwLpUbHMhPnf`%}@W#(`rHs(6Ou9VHE%J)Q;8PoTy)Q#kE61&q6O5!JfJ@jo zW-(y(?G13aNZxgiyjegoV4c>Pj=X)h#NgWK$s2e7>x>ujZ)P3dJi6}I=c_j1j!*6X zwgTf!#0k^=hjL)o^qb?HXZ8xmXARfY7#kxG@21sBac?4TjK41a#{A4lA#WXv%>DM$ zIj&oaHBB$no5?DDy=SPu&Ik~nKMtv9Vw@&L{Ydfaj%dW3x)I}kjY)t?#`&7}rL>M{ zq|UBv0O_=jGSX$6rNvPEF0c2^w39%cLX6akmh5!=(l@k$IF*6G9f*nf0lXiE*qur4 zHUwU_ zPv0!BQ@T;>q|UnioT2%f`;T-S(4zPEAEn3b^tT_V`cTW{kqPhcC;DNX<$2h^O1PO{ zk`tGxgpn%Yejl0P5I15}R3pNRQcocyvePx7?QA?JOx|85?s3hF^P^KZ(4YHkigkQ5 zI5_b1#MGmCE@H;aqvz?S>qa!sw}ViHNWks7zkx;4;(R_m~DM6_y>wmSMErsf@_uZ_CSz zy;U`A Mc+^RDa=Hc;mvA(9cxmZVB)T*Om>4?Xqk6UI^iPl zv=O6rD1TP!b*-6eF7Ba3&riM*K$Wd`48u4>3*;j1jGFkvKkIC3;?=#Tc2B8NlcGy8 z?TU9(ljmXlc$4woH6nWw^1JIe-I?+ef%n$7wy1=&m)T4_ft5dGThp%ILjeDgQpC19 z--KFcwTF<>$GgN5ryWwv)Q+V$XD=%~;2)$WlKE?;tUl;J&u-Q!j(MK`B;)LQ!^>%8 z>vqj b8%fr%i;lz<(IOOtQksO|0E8(Q40wRE+c|iG4mIm zn3CW2IrCe?K3f uHE5zqhvl$-RfFVJre)fCv>!Ua5yYF;j0H!7K!zDG_{1yd{4T5IMTR z&T41E+HNp1OYLdaiRZcYNUqI_kd|OzHgQ;vK;_)3xSM!hnugayYaUZqdrr1qm!F|* zJmp>0iC%L0+@}u6_Vv+niwybRiZcz06$SDN$8hx`p8}~Kh_-)|MbwFW*W{g2x|K}3 zVjSi>4rMJ518(g}$UB@s*dCeoRh62Ljl61n_>i9^ID)24)}v3na)ji3@7t?O)oY)s zov>js@3`P$Cd_?dp)IM;bw!k-jMq)xmbTCY`-|L(-{+$_9U>f5^-oeXe~r1Vv~YVP zkUh?&vP}*9HcUe(2qS_?7@totc2TX8?ySeIt4t!n-*=3)z=*y!@m9gdcTKn|VrB80 zUlMLB4WII+_(qb(6|)2|z;YVWwN+R*up+^_4zsIVo#(Xv+5WG)q=|EE4bSr#n>AFE z*f*ZjJlzSBdarPpmQq)}F nU=bpIZ4)nSwf(&7YG3FmE+w1n3620~LO5`P$$0=R; zI@?ktF=1~-4B=i2ybn!hemr>K*H|KlmzCo{KqIg0SG6g*h_Oxj;ncxvBKN&Mt~~F{ z&%Le7nqjdGbs@$cspC;d`^iUo(>3XdNKvDR{-1VL<+sBZE|}~l;Itbo4~BauAJ29% zy?*^%IU0Aea?xiI(@^2`VYu{Kz3mxvREdQ}={sqv%#%l(o;O%3JR*rBSvc@?)OtEm zHm<@y&A*y%TlExq` 5A`llA-b$vVzvUSDa%Ke(Z!9|Je#lgjbUSamc>gMDy8d zx$WKlA?l+?yWDiL>~j6rVyn;V_Gj>uEsH(=P~w+jynBm@7)#A$p%vp5xY|F>T(@Sr zrCN+SM2+Iwq`)NVERp{AC2^c?#2(n<;t>Sr^BFE=Jwzfp R6Zet^sLh&<0&UJ1}?uN6bXSXAwxST^vr;&vpl!va{6@3;e9p&UI2<@UkeII}E zkQ&Twu7-{PQ|y!z2n}!+9^|T#6@MA$ HZ^VUCfrE&j3f{&8~xl z4ZlqSBdIS!*T!{v$YZ0pvGA`~_~Ir%G8 zO1PyhU{*PH7E2{QtPEl{960f7jtqVnL@~=BhPfDR$aE&nqwE7Eieg)jS1!F*_yA#7 zHQj8>gG_blU1-bKo_ORbo6J uWy-N+EXDTY$CAkohc0|4gpU z0u!+ezvBy%BvAB%!U2 H(qUd{{nSiK?<=x`rlPwz`A zS@zVl8XAw(Vwt5qCd>EC`*PNJS}AJ+wOE $9%wKiPEDV9lJ zYig~P+2`W0*eW8GbjQh&s(H%KvKw4vw9XNo4UdhuR)i{k@vw gK| zKH;Ga+X4E9S>&8q*32$%(}SXDpP=2RtT?bm6U>Oxxi7b=Et!3Lv!=r0TINWKiuvNZ ztwl6!YgWi0x}#5pUM!dJ_4){;hE-g uUi-+&c7R`;<|>&wb5qkNw0 zYJ%)+-#lCI-x$4nSo%QaMYIM*!F~P_&*Okp3hz4`2AB-yVmgN)^XIg=j|g5R;X*Lc z-` c;xMo*B9sd_K)(rj0KpeIVSUL=)$6+kiPk_U&r9H+NlQYWb-Dh?hvjt9pNN7-E5N zJ1%B%7M48J_sx4GhcCB2sG(8c7Iu+Q5zj07u+wXI0FD9baE(gmC}5V2hCPv0qRl0m z!h5>DDOZ>n6{xFZ?eqY2hbWc}H@|ppr`(vYK$&3xYsSipJV>RK;l+T%DW7k&ZhYjs zv@cu_-OSoATyeW|C@L2PsPh_WtohxmQv*ta*%Na%2%M#*J?(|hXD~@s %E#$XI TU{UK_zKC0E+F zh*37~col2y{8_q4+gi&BVkxvKr6Btl!8Lz_BU=u{5Ye00da)fBUA8vD+4g}(<9Jny zy^piq |)xzuOw>mE>$(cv)egFmS5A!NNA$VaA;rEJK0;T zxAlUQtJ$oe(ON& -Es9+O+@+zKk{Pbfu$ zV`Ah!5Q)t;>l7I5O;Wj9hbdvb`(k00K!42KM5mn58No-!;pMZ>FWn=j%XMRtw)F{( zhQl_51O804COD9lLI|rGV<+R3LC?j$FSy&L5f`eRgmn6{*l!T7=N!u%hOXdcTHnTe ztZiteA||gSE$iWI8#Le8lar6@`M^n%F8%!;xJ=X8ZR}>tz($fjl6OzfV7MKrH(~#E zaO1Qr={>)C@rvkadk|X|sLD)d>ToGQlEb?uAqua)?(859iGAGY%NWrcfKnBjmHc#s zLzudnwz`$COHS>w`%H6qFkiQ%&DJqkrqtF292@A)6x9%WpK-g9X+cQO-iC`g>@!1f zE7 nXKe+bLuuO2a%>p`zeM z_+y3Zv6Ub8V_L^LQbZKlvNpTYjX3;Oz)5$uZ`JZJ;GZV@h{WNwo;Vng;x9{%`SjBn zcL~a8&-#kbK?S>hx?p?RymlKrv;LV6n`~=ipD*0sP~Z}vDccgU% I131B9`y!xEQf4yve)d9sOS0pC{tOvn4=%7-_eL)gT?~O8T=oq>0uODaC2$ zVH_rv(RcLJpxj@-*~|`H6g)a;J{ )xP!3f{M` zcNJJh@nY9jwmY71)~NURxAMhLTS{B%?0&OVR(QQ@>W&xoiFK6jqX=W;V^xQOCb|nq z)Z^Ns_km*-p`825wi{Sl9le3BY5r(L$llWKqo7#q!C9AZ;_#-}Wyh+PK|KeCoFCOM zzRye&CqY(QYg-18QM8d#ZAaxkN%g6Rxvm1B_($E*BF2&rXhRS1ZEI-cRm~X{9#1~h z^$uy&TA1M^CjUZQLqO3i$~x7~yZYRAwo#zETIa*CgWidg!_xOe&HQ-Y8XPg{tnGUp zs4S)%eXe$+1uW^Q2c2cN-I5NL82b5y9pyLr$AmA>YQlA_`FW4Ucs0bxBxxutrS0&~ z-%xGnMZO_iv3=7pq>vXElRzLB`pD8-+0Q%cb)b&Fd77QzD@}gWU4G5Oi?0)*`A}{0 z^hfq~?yb`A9czp7rGp*wCys^&XT~JSMAqWMsd5L1&vpRh4|fn3yOX0HrQuO_)7_Rg z 6`ncs^(>(w AcU7ZL!tldqmh% zp~atRWG9iwi{8$*Q@F1y_PhJ;M?{`%Ze$Cyem<)(JubZW_F~kH`FJL2>e`rQbXnBy z`Uf)edO7dF7inLZR#s{zYZMX}v`3N9Hbl$jglqSvD~8)PdI3Q?d_*7e2HcIl^4DFKIpO6pk)eYD#`E zpE}MTx@^U}f77Z`z7V+AB-)^V(QJ>%kk<-#!p&Z|oE#!RJ4St94YV^QAiR?&98z6Y zyPZqYsqapmS$vPWQ|(z_;l%4qxvj_p!X5I}qr9SK_GjTPBL{IrXP;;ejs2d17{q-S z>Xee#b4ip!AF86?t$R3qYEZr^b5@%!4Sq2Jo7!x4lMp|$%f0w<^emNB<-+@IRyxi< zk@731^?y&w5m(IP4^l4ji(&so$^k6xXrXKOkDwd{(6}ow2Kx`3{EycQ{|&VMv5@~w zqID(v{}IswSRX*dfo9TO@o4}dLIE%fkfy)c@)aommp#KT=moyAcDSPCa5NwxFc`Su zHzfxM>lJ?nO1}CaVGw}hUh(MPn4BBH-H0nbc!kLUICTXE5x+4xa3uoB0^r|Qm>htl zXcX$|>=!1#BCNmg+FvjcfazD191i3TfNp?&Ur}-d7zETDxaSuohXUy9isk>N GKT}4^!M2nGXFd6HwJ`&fTUjn2ax%du>e4@ zVZV_%z_y`)n6HRAfEcfkE`SpMCgwmZAONubi ThC>gn)n|xB)7DMa&@p_xyF|FJcbh-d`pwzlb>;fZga{ zRtdj|IUF!^_@z+4^#BDB(<^lW$^&}hx72 ^_N3gA)1 z---aR^ecD{Mbkk6fd5;N082-xqk+5u&<))C?}WdPfL!2!ApuZrz*d3#imzXNU_iHB zi4pnMJhz#a%oJNvjn#>!p-n_7_Y%uqCZb>KJCcpON#)+T{V;r5>E^3!7YCAm8DeSD< zrrsaQg{bAK?xUr`ct&!KBO{3Zt&kpH3CV#aD_M|@eiv+2T&ujFAe`}NcQ(U2@Zuu; zyl~zHmE~5ng0(BLlun7WDJ@8ADtOA5+GAqEsP}2=;D*lzR~`V!YhsfKL*8r<%i-UA z!i*6}x4h(Q%Ia$@1hTbHzvHT!(6iwqq`}V>ydg6qxaN87bXwK*lp@gESEjDq->J`v zry=jdzz#uYf9y?VekID*gJrxU_OjjKv)kS?*Gj{DtIbmc(^^TTF82iaD5)f0EPrGX zX-O2K(Gf&Q=;n-TW=L>JwW=Epa+)uNd7bk!kh=pLO}J`WrjNBJ2*$ZYx5Hq8=~p zJ(eTibe{9_+%pg#+Ro5M`<#E8db#zm^!)~ *DZMHL7iI+m1 Y^eAoSSd%76!(Hs#k0ZuLUVhk&78Zl4cJ#!=m?Xrnqh<5K6 zlEc0fv>F!Pk6vnN|9e<=< R*0$uR3$xn}6EKA2-_-dY$-G4NoZxF()JXV&x*b zsKws)tM4P-)hx0)rk$r6pA&s0yYz_oHrgMJ%!j nM|FgoTJ4bw z!3sPtY`f+a@yLrF(I9s5&U%4fk_&Te*EcrHEq6L|e~99aM8|X|WXoiOx^m^?7uExv zgJuH1hxv-&wra@Ue5-Z0;9jB3`;pLyLP>iG2~&yCcPb@M-l~Y+r+*KM-JgsQN*i-N zO*YP0-NN-g;>#GLdU^Uzj;w;;vEGN0(;P{8bS$n-bkkS3e?3wTtJ(hia5U#uhiU5( znKjc-%l%ZY(>9ylL4gQ2#-H5;o#Xoxv-9p>92o918e4yE&ufo+ke#EZK$b7?tf5JU zKlLQ!uyfXr^jYA~8(P^U+`0Gk71_ete0rI|#Nlmv6>6fNEr^_@!m@Z#6>)TIAf+!f zku4`?^cU}1R(DXZ6?R%(gIi)hk15+mGh3_luI{av`MWi4t|*(|31jnp$25)op|aB1 z>0_m~K%&>Txr2`p5%5jRvE0v3+4)1gtSe+bjF>I>!p6}h$sKQwU8s_@#yKyTwc5xu zd{x=62}{Zp4YC@(XdcEkXz*C8>uO0yw tIU+Jot zTR3R1k^XGRFpugW*UA$k^J~J%lSA5 `#nXkh1yeXY8}{@ab>g4AX*whA^U`;o&o3CLF^n8~Q3031b@; z@r7Q|y5lzXQlf=Mt_jmd+umRF2saLzMTbe? >Lo4Ma*1l3%_shi67Semi|J3_v!|0h- zARy^Emheu*0;GF{xl>N~=Dngy6#b3X_^GgnkSByQ-y$Om^4PhKDAa=Cl=pL&Go
2_=9Gl;} z?rLe`(7tFjQbdPs)S8;skq6r~9hm -dD$r^7alvJ9n8izN@p{}C(o-yWtgJ-8d z{0!+ 2$KrF-BoF- zqg>g#deaVTe_u}X6i?`v-tWmNH9wYB*-y2t?VPiuEF2xrczrv}%$_Qhxz^4aswimH zOKy0ct0&+aY-87ZK1@hlZM4WPKsg>tyXvg$=T`1)$x5wgH<1k!c;+D+=CdrMNbUEV zvEqCC9ksl@zVKU`n3*K5cphi #4bxU`j2%{=HGC+;h~chxGyuX!zpr>z=lm6uqk4C{iZZypAhG{6h0 zl{fr$o(7FFJc>Vd$0U?ty8eUoz2kLBRfDzXL@JMQ2bByl4GQv1mZ6tvf(o&lPwBy? zv8QuO#f7rD_MES%)Hhzy>;_UK%%cz9jM02CHIEOc++3zj#reP^Sk2-Yd10w(KPJ-4 zDG+*)YHhj-;skvx%5dv qhcdKo_aPg~+Y zyjA{MiGhKA17I=?h9mwoAO{00YGC>QZ~Jj1@C6z$c>T+M9R7#>I1Dg~g##;lG#w}8 zUzgDVdmO;t6|hqU?8pCAz@PTxfMNN6S&WJP-WAJR>sdQkOIur6bN;`!#$aGA3grfN zLa6_+Ci}xzPX~7yDU; z{PryA95I+{1N3OxzOU|R%D(TX3)GtI)-_Q Lg2(X^LfY2m#8O*pjP$Xl?yiSA?gpc9=SGc(<7^Sd;`EMO3AUY-M _k4Xar@+f)u2O-t)qmkmNReRFhO6A9#pYDXt%XjBXVH2Brx|#0muroA$ z%nG_?dX1ZQg85BCmddK>4WqhAVmi5N7wtLMzUc4(uN)PN5i~L2kh~L`nH=gp@2_B( zk%s+DHQ+TXZM69z nG!^~h+HRQ^ z@IsW5Q%0$87DtHpt8AEDgBmo_vj#}o2;V=Rf3VUv)q=;#X%{v}OzlBf)C(^4^+*pf z@w%>j{H1nKlTmqtel+ko$|94-#zADmN155x&ub%Ti6SHbc;z>T!NQAfUT0}q8ftFq z7_w*S^m~bWw+3W)DQ}5LEH7T@$1*-SVQqb4rVB5? u;pvtoM0(Ew0 zO?0MLg~m{~jphfB{l?(;Uv}U2V-+uOl#{=qhC8Zg^Hh_k_YU~ThY#}*Y~C!^E+dJ) zUQe%z^X9q0vh%$d>S*k ChTU+g2iJb7HiD2A-Bj^SRwnnaiD!q<~>6fZr0W>B|Ygv%3ZlClp` zopo7D>D$o@>5CVFHETHKVY%;mo><)EG*`fh8Ffi0Fm_u=qAAtlr669T!aHaSVHx2* ze8>IWb56VA(JSwRcdyeFYL67dMg|QTC+SQW(-pzCZp;yifkdqj;5U^^>lSn7*zWa% zEs{|!0vxRiI5yWfWJ**v#;cynfb=Vk)#Vj##-m@AsK!#f9yO5-HyA9y51yv!dPh&8 zS&+7RF%u|m?o8lbxyk0Xu#=1Rasj>mcJ7eW``l2FmlVuU%vEW*E!peu%e+_Gk#Lyp zGVAg#bJp;6(HBFsVv4gv0>=i0ik)nC^aUM~xBn>IS+j=bypS2p{DPq0=^paK+Z~G} zRJXS9HpeiMSie64F<#*2SuSH-PF2P^EFu(~wqm)Wg3on}TKxcNdpT3LG_!a=lk2Sg zdznBH%`IM!;=Z%b%h`Mfp^V^fuC^OnEm_M8m P6y1oA8%)y73Keows#Y`hr>q8jnCq;j@UJi6bk_>dHm4_P@!F6|b zXlC}~ZuB%~ }bbyo*>Y0f(S+~_?>DvCIJ zamJlP)^;l=q;=5}*Y%+ {;RR+NvcK=}WW1H{a>LFhex
E2MMrX9`3hFAVO zx69EYjFIiQ(J@joH?!`JiWs-&BNv6!XYc!84UZ*|RGD{w+}kAk@G 42a;5Ob5MCpwenKf83A^!jA)h~M5 SluE8I!jFgcoz-dK z{-IA4K}ya9HfB0a^P{hj5q{QZKMb*ukr!#M>rD-KuNA=CWQ5HgtZ8PnB&^Tg% {ma)PB256X4*x4o%c3U+1<~QZfjR7@#H^%R4 z%&1mtRG)unWGgY06u{~w%#3O}&%I|c*z;|a*+^|L(Y#1W&79S8-oCD3mM0|MdtbI} z*Okw`zW@8!-U)C2p68a8{#}L)@<&e~d{x fLcuj)