From 6f5c74a4fc677966ddda09bc0e118c6d5632602a Mon Sep 17 00:00:00 2001 From: dphaener Date: Sat, 4 Apr 2015 20:56:57 -0700 Subject: [PATCH 1/6] Added option to use custom path in resource route --- .idea/.name | 1 + .idea/.rakeTasks | 7 + .idea/encodings.xml | 4 + .idea/inspectionProfiles/Project_Default.xml | 12 + .../inspectionProfiles/profiles_settings.xml | 7 + .idea/jsonapi-resources.iml | 61 +++++ .idea/misc.xml | 27 ++ .idea/modules.xml | 8 + .idea/scopes/scope_settings.xml | 5 + .idea/vcs.xml | 6 + .idea/workspace.xml | 242 ++++++++++++++++++ lib/jsonapi/routing_ext.rb | 2 +- 12 files changed, 381 insertions(+), 1 deletion(-) create mode 100644 .idea/.name create mode 100644 .idea/.rakeTasks create mode 100644 .idea/encodings.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/jsonapi-resources.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/scopes/scope_settings.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 000000000..6360128a8 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +jsonapi-resources \ No newline at end of file diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks new file mode 100644 index 000000000..0ff2872d8 --- /dev/null +++ b/.idea/.rakeTasks @@ -0,0 +1,7 @@ + + diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 000000000..d82104827 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 000000000..fb2a4c826 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 000000000..3b312839b --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/jsonapi-resources.iml b/.idea/jsonapi-resources.iml new file mode 100644 index 000000000..14a2e02e1 --- /dev/null +++ b/.idea/jsonapi-resources.iml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 000000000..46fdf604d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 000000000..9bf181470 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml new file mode 100644 index 000000000..922003b84 --- /dev/null +++ b/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..94a25f7f4 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 000000000..0726d3887 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1428206149094 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/jsonapi/routing_ext.rb b/lib/jsonapi/routing_ext.rb index 92020f216..53e2bc270 100644 --- a/lib/jsonapi/routing_ext.rb +++ b/lib/jsonapi/routing_ext.rb @@ -54,7 +54,7 @@ def jsonapi_resources(*resources, &block) # Route using the primary_key. Can be overridden using routing_resource_options options[:param] ||= res._primary_key - options[:path] = format_route(resource_type) + options[:path] = format_route(options[:path] || resource_type) resources resource_type, options do @scope[:jsonapi_resource] = resource_type From 801bc751aa6e8b125d63d05bcc09ff2e1145bf64 Mon Sep 17 00:00:00 2001 From: dphaener Date: Mon, 13 Apr 2015 17:54:12 -0700 Subject: [PATCH 2/6] Add logging --- .idea/jsonapi-resources.iml | 40 ++- .idea/workspace.xml | 315 ++++++++++++++++++++-- lib/jsonapi/resource_serializer.rb | 1 + test/integration/requests/request_test.rb | 6 + test/test_helper.rb | 4 + 5 files changed, 342 insertions(+), 24 deletions(-) diff --git a/.idea/jsonapi-resources.iml b/.idea/jsonapi-resources.iml index 14a2e02e1..a921fe39d 100644 --- a/.idea/jsonapi-resources.iml +++ b/.idea/jsonapi-resources.iml @@ -9,6 +9,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -28,8 +62,7 @@ - - + @@ -51,11 +84,10 @@ - + - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 0726d3887..debb222b1 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,7 +2,11 @@ - + + + + + @@ -15,27 +19,61 @@ + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -45,6 +83,9 @@ @@ -129,6 +170,50 @@ \ No newline at end of file diff --git a/lib/jsonapi/resource_serializer.rb b/lib/jsonapi/resource_serializer.rb index 6e7fd943a..b523afb7b 100644 --- a/lib/jsonapi/resource_serializer.rb +++ b/lib/jsonapi/resource_serializer.rb @@ -21,6 +21,7 @@ def initialize(primary_resource_klass, options = {}) @key_formatter = options.fetch(:key_formatter, JSONAPI.configuration.key_formatter) @route_formatter = options.fetch(:route_formatter, JSONAPI.configuration.route_formatter) @base_url = options.fetch(:base_url, '') + Rails.logger.debug @base_url end # Converts a single resource, or an array of resources to a hash, conforming to the JSONAPI structure diff --git a/test/integration/requests/request_test.rb b/test/integration/requests/request_test.rb index 92ee0155d..82105f90a 100644 --- a/test/integration/requests/request_test.rb +++ b/test/integration/requests/request_test.rb @@ -391,4 +391,10 @@ def test_flow_link_has_many_self_link_put }) end + def test_scoped_resources + get '/api/v1/123/people' + assert_equal 200, status + assert_hash_equals('http://www.example.com/api/v1/123/people/1', json_response['data'].first['links']['self']) + end + end diff --git a/test/test_helper.rb b/test/test_helper.rb index b2ca32e53..ad04d6e28 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -79,6 +79,10 @@ def as_json(options = nil) namespace :api do namespace :v1 do + scope ":section_id" do + jsonapi_resources :people + end + jsonapi_resources :people jsonapi_resources :comments jsonapi_resources :tags From 8d5aeca24cf0f90705a86853eddeb0850e2df51e Mon Sep 17 00:00:00 2001 From: dphaener Date: Mon, 13 Apr 2015 18:01:56 -0700 Subject: [PATCH 3/6] Test for scoping --- lib/jsonapi/resource_controller.rb | 4 +++- lib/jsonapi/resource_serializer.rb | 9 +++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/jsonapi/resource_controller.rb b/lib/jsonapi/resource_controller.rb index aa4438e1b..12cbef4b8 100644 --- a/lib/jsonapi/resource_controller.rb +++ b/lib/jsonapi/resource_controller.rb @@ -219,7 +219,9 @@ def processing_serializer fields: @request.fields, base_url: base_url, key_formatter: key_formatter, - route_formatter: route_formatter) + route_formatter: route_formatter, + scope_id: params[:brewery_id] + ) end # override this to process other exceptions diff --git a/lib/jsonapi/resource_serializer.rb b/lib/jsonapi/resource_serializer.rb index b523afb7b..4828c2c5a 100644 --- a/lib/jsonapi/resource_serializer.rb +++ b/lib/jsonapi/resource_serializer.rb @@ -20,8 +20,8 @@ def initialize(primary_resource_klass, options = {}) @include = options.fetch(:include, []) @key_formatter = options.fetch(:key_formatter, JSONAPI.configuration.key_formatter) @route_formatter = options.fetch(:route_formatter, JSONAPI.configuration.route_formatter) + @scope_id = options.fetch(:scope_id) @base_url = options.fetch(:base_url, '') - Rails.logger.debug @base_url end # Converts a single resource, or an array of resources to a hash, conforming to the JSONAPI structure @@ -221,7 +221,12 @@ def links_hash(source, requested_associations) end def formatted_module_path(source) - source.class.name =~ /::[^:]+\Z/ ? (@route_formatter.format($`).freeze.gsub('::', '/') + '/').downcase : '' + if source.class.name =~ /::[^:]+\Z/ + path = (@route_formatter.format($`).freeze.gsub('::', '/') + '/').downcase + @scope_id ? "#{path}#{@scope_id}/" : path + else + '' + end end def self_href(source) From 307c9c046952915d01a7a29f18a6ac4ef351fdf4 Mon Sep 17 00:00:00 2001 From: dphaener Date: Mon, 13 Apr 2015 18:06:10 -0700 Subject: [PATCH 4/6] Add scope id method and options to all serializers Remove .idea folder Remove .idea folder --- .idea/.name | 1 - .idea/.rakeTasks | 7 - .idea/encodings.xml | 4 - .idea/inspectionProfiles/Project_Default.xml | 12 - .../inspectionProfiles/profiles_settings.xml | 7 - .idea/jsonapi-resources.iml | 93 ---- .idea/misc.xml | 27 - .idea/modules.xml | 8 - .idea/scopes/scope_settings.xml | 5 - .idea/vcs.xml | 6 - .idea/workspace.xml | 517 ------------------ lib/jsonapi/resource_controller.rb | 26 +- 12 files changed, 20 insertions(+), 693 deletions(-) delete mode 100644 .idea/.name delete mode 100644 .idea/.rakeTasks delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/jsonapi-resources.iml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/scopes/scope_settings.xml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/workspace.xml diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 6360128a8..000000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -jsonapi-resources \ No newline at end of file diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks deleted file mode 100644 index 0ff2872d8..000000000 --- a/.idea/.rakeTasks +++ /dev/null @@ -1,7 +0,0 @@ - - diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index d82104827..000000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index fb2a4c826..000000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 3b312839b..000000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/jsonapi-resources.iml b/.idea/jsonapi-resources.iml deleted file mode 100644 index a921fe39d..000000000 --- a/.idea/jsonapi-resources.iml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 46fdf604d..000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 9bf181470..000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b84..000000000 --- a/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f4..000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index debb222b1..000000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,517 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - - - - - - - - - - - - 1428206149094 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib/jsonapi/resource_controller.rb b/lib/jsonapi/resource_controller.rb index 12cbef4b8..fec66f51b 100644 --- a/lib/jsonapi/resource_controller.rb +++ b/lib/jsonapi/resource_controller.rb @@ -14,13 +14,19 @@ class ResourceController < ActionController::Base before_filter :setup_request after_filter :setup_response + def scope_id + nil + end + def index serializer = JSONAPI::ResourceSerializer.new(resource_klass, include: @request.include, fields: @request.fields, base_url: base_url, key_formatter: key_formatter, - route_formatter: route_formatter) + route_formatter: route_formatter, + scope_id: scope_id + ) resource_records = resource_klass.find(resource_klass.verify_filters(@request.filters, context), context: context, @@ -38,7 +44,9 @@ def show fields: @request.fields, base_url: base_url, key_formatter: key_formatter, - route_formatter: route_formatter) + route_formatter: route_formatter, + scope_id: scope_id + ) key = resource_klass.verify_key(params[resource_klass._primary_key], context) @@ -62,7 +70,9 @@ def show_association fields: @request.fields, base_url: base_url, key_formatter: key_formatter, - route_formatter: route_formatter) + route_formatter: route_formatter, + scope_id: scope_id + ) render json: serializer.serialize_to_links_hash(parent_resource, association) rescue => e @@ -102,7 +112,9 @@ def get_related_resource fields: @request.fields, base_url: base_url, key_formatter: key_formatter, - route_formatter: route_formatter) + route_formatter: route_formatter, + scope_id: scope_id + ) render json: serializer.serialize_to_hash(source_resource.send(association_type)) end @@ -123,7 +135,9 @@ def get_related_resources fields: @request.fields, base_url: base_url, key_formatter: key_formatter, - route_formatter: route_formatter) + route_formatter: route_formatter, + scope_id: scope_id + ) render json: serializer.serialize_to_hash(related_resources) end @@ -220,7 +234,7 @@ def processing_serializer base_url: base_url, key_formatter: key_formatter, route_formatter: route_formatter, - scope_id: params[:brewery_id] + scope_id: scope_id ) end From 9b3f6fc53dd8ae193088ad6cf04d23987e1e897a Mon Sep 17 00:00:00 2001 From: dphaener Date: Tue, 14 Apr 2015 17:48:48 -0700 Subject: [PATCH 5/6] Fix broken tests --- lib/jsonapi/resource_controller.rb | 9 +++++---- lib/jsonapi/resource_serializer.rb | 2 +- test/integration/requests/request_test.rb | 7 ------- test/test_helper.rb | 1 + 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/lib/jsonapi/resource_controller.rb b/lib/jsonapi/resource_controller.rb index fec66f51b..25f45405e 100644 --- a/lib/jsonapi/resource_controller.rb +++ b/lib/jsonapi/resource_controller.rb @@ -14,10 +14,6 @@ class ResourceController < ActionController::Base before_filter :setup_request after_filter :setup_response - def scope_id - nil - end - def index serializer = JSONAPI::ResourceSerializer.new(resource_klass, include: @request.include, @@ -189,6 +185,11 @@ def context {} end + # override to set scope_id + def scope_id + nil + end + # Control by setting in an initializer: # JSONAPI.configuration.json_key_format = :camelized_key # JSONAPI.configuration.route = :camelized_route diff --git a/lib/jsonapi/resource_serializer.rb b/lib/jsonapi/resource_serializer.rb index 4828c2c5a..732adbde8 100644 --- a/lib/jsonapi/resource_serializer.rb +++ b/lib/jsonapi/resource_serializer.rb @@ -20,7 +20,7 @@ def initialize(primary_resource_klass, options = {}) @include = options.fetch(:include, []) @key_formatter = options.fetch(:key_formatter, JSONAPI.configuration.key_formatter) @route_formatter = options.fetch(:route_formatter, JSONAPI.configuration.route_formatter) - @scope_id = options.fetch(:scope_id) + @scope_id = options.fetch(:scope_id, nil) @base_url = options.fetch(:base_url, '') end diff --git a/test/integration/requests/request_test.rb b/test/integration/requests/request_test.rb index 82105f90a..c789e1362 100644 --- a/test/integration/requests/request_test.rb +++ b/test/integration/requests/request_test.rb @@ -390,11 +390,4 @@ def test_flow_link_has_many_self_link_put ] }) end - - def test_scoped_resources - get '/api/v1/123/people' - assert_equal 200, status - assert_hash_equals('http://www.example.com/api/v1/123/people/1', json_response['data'].first['links']['self']) - end - end diff --git a/test/test_helper.rb b/test/test_helper.rb index ad04d6e28..856fdcfeb 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,4 +1,5 @@ require 'simplecov' +require 'minitest/mock' # To run tests with coverage: # COVERAGE=true rake test From bfb77cb2437ec1e258dcadf47998cb5117d3f861 Mon Sep 17 00:00:00 2001 From: dphaener Date: Mon, 7 Sep 2015 15:00:56 -0700 Subject: [PATCH 6/6] Add tests (WIP) --- test/.test_helper.rb.swp | Bin 0 -> 16384 bytes test/integration/requests/request_test.rb | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 test/.test_helper.rb.swp diff --git a/test/.test_helper.rb.swp b/test/.test_helper.rb.swp new file mode 100644 index 0000000000000000000000000000000000000000..516b39572a8a8c73633fcbb4d6dd0579577b3eb5 GIT binary patch literal 16384 zcmeI3Yit}>6~}K=D6b}kR20z=^=4gX*Ofh+#4d7QGQwPeV%*nxp(e4Gh5qrVs?(dN1I@{-pbhar^XhySa-4d3}d#bq}wos zD-`9fdmW&1!PuN>-R5~qW5<-IIi6)YYb)H-)nL`~Y*9TMc&_QoF(m>oQkDp+p$NkG zKcgWWUnou0);3doFEmhSU_%<%%*OZZ-bGc1N;~+qTNgLfN>QoMK%s#`1BC_(4HOzE zG*D=u&_JPq|4$8s{wDSzh`uQm|DN>oiZ!2Crr%GdpHzpgtX%S~_`lFVp@BjJg$4=@ z6dEWrP-vjgK%s#`1BC_(4HO#qU(|qUGxjzJHcSBkJpa%9|4Y{}_H*z&coKX87=VF) zZ(-~b_$Bx$_%V16d<#4RJ_0@rroffpnazxS7knLj4crTA;Dg{axCxAatH7VHX6$?5 zesC5@un)ZQ7RFu%&w($2N5DStlQ$y`{0KY*PJ}TLv@I!DPSOF)%FxUpJ2me5D=I`Ja z;BoL6coaMc&Vn&81WMo%=J{#xaj*&^5CR>L4crL&E{@AJnvsVR2RA+VLmnoxeCwUkEWA z=`ICa56v^dDEC~arSnsI(D2TUqB$kZP@GO{_txRM8HEi`jdHPK2|uK2HeM-FUMs7R zbGXHjLeoOJaa(y5?b>xk4LF&vOU0;h3%njj-hp z>?tlapqZKy!XA(>R(#^mQ zAhVI2EWg)2)-6H0%*kxqMNVG7P2?2nvxl5AUAB;uo7q85R%!z|IbHLglbg={0=DTX z-%suyfo3c79L>*$_X8#Filh>JMmj=+c1+hcd^2oR%9>WK%at&KNmVh=a#M8b+jTIkU3`O5Vhp=6@FBhsDVJl$^2H*#o2GO_kc>AT4Q2qJyE&Eyj8fL5 zBXNX45qbfZ!!jcW8xY!0j#gS~r$I8U8kI6&u|m-SOQAKd*;hC*YArF5uJf2nQ`TD= zc7Tp>OmZB&b4#5e1^*%!@8C9NNJi152qVRhKp~b95r>S6Bp^Kq&(Qi zWU}CGsc5gSbk=iQmBKtDl;L=$jl%H~W2s3eI}q$IwOVXPj7*}J2R$3zWwp^TgT}^dFPlyz47dZ>tyFLC?ID!YTSMn%@Ny?l z(Kga~FT5`Y$8cz)dvl(bO`It9d&}5&O%>9u1Pguo$ca8= zWG;<#E+;3nJ-6^0PMO%#BHxC;!DA8HiDE@qNLmtnVS0Yy=&^p-cqe!TKK~2gB6tEk4ju$Ga2(tYZUQ#~4sHMxA9xmg8$1P`1Q&nK?kAhXu0xRGEpt! z_uxhF4EPH8BKRyIeSaDhSD}GI1BC_(4HOzEG!Sc``xMvhSjUG*E%Xco2fTBx1>XS< z1Lx$fMs9MbuEd2#$!iM5N;pDpM|T@=O@yi-v|ywKliwYVXrT-p(bHtwV1HROnfMEP z_wqnE^~`&q7EaJXcP5T}!%>1Kk%lke0r%weo>jXgZ1>lR7nI{*L3Q|KIdQ;g!2Qy- zhnz3o0i0obWq5Vc$ux3sH=M~zdD;vxUN?>k@XF#m-^urzu4$ViW#|@D7SF?m1t)Kd z0uI#Ks~<$7J925^btMMXi6^%OZJSh2@qCNYvPT>h9S*usee;BlC@s%!7OBGi>=DTw zqLpht-RYU}WI-%E^l%)sPR6LEiE*e4j$$eEO3681ZO6SzsnJrf#B&cwJlTPZqU-cr z<4p1xXMsG89+!&q_r(uz$p5F@PP8uWJdAwuvN(T@wx z9mzp}f;K1V3VUCrx8?|ZxM>7R5ZtJl*3vmdogjNpc6~$eJpu%mUwx}u`%01 zUCwjK94+-~fI3dK)e*g0yAF0=JpN37=Fau5>aDb5r#L