fredapi 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.travis.yml +10 -0
- data/Gemfile +6 -0
- data/LICENCE.md +20 -0
- data/README.md +0 -0
- data/bin/fredapi +2 -0
- data/fredapi.gemspec +26 -0
- data/lib/faraday/utils/utils.rb +24 -0
- data/lib/fredapi.rb +29 -0
- data/lib/fredapi/client.rb +41 -0
- data/lib/fredapi/client/category.rb +31 -0
- data/lib/fredapi/client/category/children.rb +23 -0
- data/lib/fredapi/client/category/related.rb +23 -0
- data/lib/fredapi/client/category/related_tags.rb +30 -0
- data/lib/fredapi/client/category/series.rb +30 -0
- data/lib/fredapi/client/category/tags.rb +30 -0
- data/lib/fredapi/client/related_tags.rb +27 -0
- data/lib/fredapi/client/release.rb +33 -0
- data/lib/fredapi/client/release/dates.rb +28 -0
- data/lib/fredapi/client/release/related_tags.rb +30 -0
- data/lib/fredapi/client/release/series.rb +30 -0
- data/lib/fredapi/client/release/sources.rb +23 -0
- data/lib/fredapi/client/release/tags.rb +30 -0
- data/lib/fredapi/client/releases.rb +29 -0
- data/lib/fredapi/client/releases/dates.rb +27 -0
- data/lib/fredapi/client/series.rb +37 -0
- data/lib/fredapi/client/series/categories.rb +23 -0
- data/lib/fredapi/client/series/observations.rb +33 -0
- data/lib/fredapi/client/series/release.rb +23 -0
- data/lib/fredapi/client/series/search.rb +38 -0
- data/lib/fredapi/client/series/search/related_tags.rb +32 -0
- data/lib/fredapi/client/series/search/tags.rb +32 -0
- data/lib/fredapi/client/series/tags.rb +25 -0
- data/lib/fredapi/client/series/updates.rb +26 -0
- data/lib/fredapi/client/series/vintage_dates.rb +27 -0
- data/lib/fredapi/client/source.rb +25 -0
- data/lib/fredapi/client/source/releases.rb +27 -0
- data/lib/fredapi/client/sources.rb +24 -0
- data/lib/fredapi/client/tags.rb +31 -0
- data/lib/fredapi/client/tags/series.rb +27 -0
- data/lib/fredapi/configuration.rb +45 -0
- data/lib/fredapi/connection.rb +32 -0
- data/lib/fredapi/request.rb +98 -0
- data/lib/fredapi/version.rb +3 -0
- data/spec/fredapi_spec.rb +23 -0
- data/spec/helper.rb +12 -0
- metadata +163 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b5596e71170989d7088e8cc9ee61de17b24d889f
|
4
|
+
data.tar.gz: 8f1990935e85719290d9732d7831e705af4671b8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 91bc6fd387cea90b9a5c4f9c8d1439a269597cbd2b953fa7995af8486cc645f3559c49539d7be9b33b19e21855cfba0bd9d94d21cb22913a4c8f2ea549b7fd48
|
7
|
+
data.tar.gz: 328390e5b6fc6f80b038710a25ea2c8d31d00fe5774685226f848bc77311d08f0865cdd14ce28378638f1de505239447c7290fba0b34ac368ff72a8775d22472
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENCE.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Jonathan Chrisp
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
File without changes
|
data/bin/fredapi
ADDED
data/fredapi.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/lib/fredapi/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'fredapi'
|
5
|
+
s.version = FREDAPI::VERSION
|
6
|
+
s.date = '2013-09-14'
|
7
|
+
s.summary = 'FRED API Ruby Wrapper'
|
8
|
+
s.description = 'A Ruby wrapper for the FRED API'
|
9
|
+
s.author = 'Jonathan Chrisp'
|
10
|
+
s.email = 'jonathan.chrisp@gmail.com'
|
11
|
+
s.license = 'MIT'
|
12
|
+
s.homepage = 'https://github.com/jonathanchrisp/fredapi'
|
13
|
+
s.required_ruby_version = ">= 1.9.2"
|
14
|
+
|
15
|
+
s.add_development_dependency 'rspec', '~> 2.13.0'
|
16
|
+
s.add_development_dependency 'pry', '~> 0.9.12.2'
|
17
|
+
|
18
|
+
s.add_runtime_dependency 'faraday', '~> 0.8.7'
|
19
|
+
s.add_runtime_dependency 'faraday_middleware', '~> 0.9.0'
|
20
|
+
s.add_runtime_dependency 'hashie', '~> 2.0.5'
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
25
|
+
s.require_paths = ['lib']
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
# TODO: Remove this patch once latest faraday rc has been released
|
4
|
+
# https://github.com/lostisland/faraday/issues/182#issuecomment-19518167
|
5
|
+
module Faraday
|
6
|
+
# Overriding Faraday::Utils module build_nested_query method
|
7
|
+
module Utils
|
8
|
+
def build_nested_query(value, prefix = nil)
|
9
|
+
case value
|
10
|
+
when Array
|
11
|
+
value.map { |v| build_nested_query(v, "#{prefix}") }.join("&")
|
12
|
+
when Hash
|
13
|
+
value.map { |k, v|
|
14
|
+
build_nested_query(v, prefix ? "#{prefix}#{escape(k)}" : escape(k))
|
15
|
+
}.join("&")
|
16
|
+
when NilClass
|
17
|
+
prefix
|
18
|
+
else
|
19
|
+
raise ArgumentError, "value must be a Hash" if prefix.nil?
|
20
|
+
"#{prefix}=#{escape(value)}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/fredapi.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'fredapi/version'
|
2
|
+
require 'fredapi/configuration'
|
3
|
+
require 'fredapi/client'
|
4
|
+
|
5
|
+
# FREDAPI namespace module
|
6
|
+
module FREDAPI
|
7
|
+
extend Configuration
|
8
|
+
class << self
|
9
|
+
|
10
|
+
# Alias for FREDAPI::Client.new
|
11
|
+
#
|
12
|
+
# @return [FREDAPI::Client]
|
13
|
+
def new opts={}
|
14
|
+
FREDAPI::Client.new opts
|
15
|
+
end
|
16
|
+
|
17
|
+
# Delegate to FREDAPI::Client.new
|
18
|
+
def method_missing method, *args, &block
|
19
|
+
return super unless new.respond_to? method
|
20
|
+
new.send method, *args, &block
|
21
|
+
end
|
22
|
+
|
23
|
+
# Check if method responds_to?
|
24
|
+
def respond_to? method, include_private=false
|
25
|
+
new.respond_to?(method, include_private) || super(method, include_private)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'fredapi/connection'
|
2
|
+
require 'fredapi/request'
|
3
|
+
|
4
|
+
require 'fredapi/client/category'
|
5
|
+
require 'fredapi/client/related_tags'
|
6
|
+
require 'fredapi/client/release'
|
7
|
+
require 'fredapi/client/releases'
|
8
|
+
require 'fredapi/client/series'
|
9
|
+
require 'fredapi/client/source'
|
10
|
+
require 'fredapi/client/sources'
|
11
|
+
require 'fredapi/client/tags'
|
12
|
+
|
13
|
+
module FREDAPI
|
14
|
+
# Client class to create FREDAPI instances
|
15
|
+
class Client
|
16
|
+
|
17
|
+
attr_accessor *Configuration::OPTION_KEYS
|
18
|
+
|
19
|
+
def initialize opts={}
|
20
|
+
# Merge opts
|
21
|
+
opts = FREDAPI.options.merge opts
|
22
|
+
|
23
|
+
# Create instance variables
|
24
|
+
Configuration::OPTION_KEYS.each do |k|
|
25
|
+
send "#{k}=", opts[k]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
include FREDAPI::Connection
|
30
|
+
include FREDAPI::Request
|
31
|
+
|
32
|
+
# API endpoints
|
33
|
+
include FREDAPI::Client::Category
|
34
|
+
include FREDAPI::Client::Release
|
35
|
+
include FREDAPI::Client::Releases
|
36
|
+
include FREDAPI::Client::Series
|
37
|
+
include FREDAPI::Client::Source
|
38
|
+
include FREDAPI::Client::Tags
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'fredapi/client/category/children'
|
2
|
+
require 'fredapi/client/category/related'
|
3
|
+
require 'fredapi/client/category/related_tags'
|
4
|
+
require 'fredapi/client/category/series'
|
5
|
+
require 'fredapi/client/category/tags'
|
6
|
+
|
7
|
+
module FREDAPI
|
8
|
+
class Client
|
9
|
+
# Category module for fred/category endpoint
|
10
|
+
module Category
|
11
|
+
|
12
|
+
# Get a category
|
13
|
+
#
|
14
|
+
# @param opts [Hash] options hash of parameters
|
15
|
+
# @option opts [Integer] api_key 32 character alpha-numeric lowercase string
|
16
|
+
# @option opts [String] file_type A key or file extension that indicates the type of file to send
|
17
|
+
# @option opts [Integer] category_id The id for a category
|
18
|
+
# @return [Hashie::Mash] Hash containing the results
|
19
|
+
def category opts={}
|
20
|
+
get "fred/category", opts
|
21
|
+
end
|
22
|
+
|
23
|
+
include FREDAPI::Client::Category::Children
|
24
|
+
include FREDAPI::Client::Category::Related
|
25
|
+
include FREDAPI::Client::Category::RelatedTags
|
26
|
+
include FREDAPI::Client::Category::Series
|
27
|
+
include FREDAPI::Client::Category::Tags
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module FREDAPI
|
2
|
+
class Client
|
3
|
+
module Category
|
4
|
+
# Category module for fred/category/children endpoint
|
5
|
+
module Children
|
6
|
+
|
7
|
+
# Get the child categories for a specified parent category
|
8
|
+
#
|
9
|
+
# @param opts [Hash] options hash of parameters
|
10
|
+
# @option opts [Integer] api_key 32 character alpha-numeric lowercase string
|
11
|
+
# @option opts [String] file_type A key or file extension that indicates the type of file to send
|
12
|
+
# @option opts [Integer] category_id The id for a category
|
13
|
+
# @option opts [String] realtime_start The start of the real-time period
|
14
|
+
# @option opts [String] realtime_end The end of the real-time period
|
15
|
+
# @return [Hashie::Mash] Hash containing the results
|
16
|
+
def category_children opts={}
|
17
|
+
get "fred/category/children", opts
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module FREDAPI
|
2
|
+
class Client
|
3
|
+
module Category
|
4
|
+
# Related module for fred/category/related endpoint
|
5
|
+
module Related
|
6
|
+
|
7
|
+
# Get the related categories for a category
|
8
|
+
#
|
9
|
+
# @param opts [Hash] options hash of parameters
|
10
|
+
# @option opts [Integer] api_key 32 character alpha-numeric lowercase string
|
11
|
+
# @option opts [String] file_type A key or file extension that indicates the type of file to send
|
12
|
+
# @option opts [Integer] category_id The id for a category
|
13
|
+
# @option opts [String] realtime_start The start of the real-time period
|
14
|
+
# @option opts [String] realtime_end The end of the real-time period
|
15
|
+
# @return [Hashie::Mash] Hash containing the results
|
16
|
+
def category_related opts={}
|
17
|
+
get "fred/category/related", opts
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module FREDAPI
|
2
|
+
class Client
|
3
|
+
module Category
|
4
|
+
# RelatedTags module for fred/category/related_tags endpoint
|
5
|
+
module RelatedTags
|
6
|
+
|
7
|
+
# Get the related tags for a category
|
8
|
+
#
|
9
|
+
# @param opts [Hash] options hash of parameters
|
10
|
+
# @option opts [Integer] api_key 32 character alpha-numeric lowercase string
|
11
|
+
# @option opts [String] file_type A key or file extension that indicates the type of file to send
|
12
|
+
# @option opts [Integer] category_id The id for a category
|
13
|
+
# @option opts [String] realtime_start The start of the real-time period
|
14
|
+
# @option opts [String] realtime_end The end of the real-time period
|
15
|
+
# @option opts [String] tag_names A semicolon delimited list of tags to find related tags for
|
16
|
+
# @option opts [String] tag_group_id A tag group id to filter tags by type
|
17
|
+
# @option opts [String] search_text The words to find matching tags with
|
18
|
+
# @option opts [Integer] limit The maximum number of results to return
|
19
|
+
# @option opts [Integer] offset Non-negative integer
|
20
|
+
# @option opts [String] order_by Order results by values of the specified attribute
|
21
|
+
# @option opts [String] sort_order Sort results is ascending or descending order for attribute values specified by order_by
|
22
|
+
# @return [Hashie::Mash] Hash containing the results
|
23
|
+
def category_related_tags opts={}
|
24
|
+
get "fred/category/related_tags", opts
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module FREDAPI
|
2
|
+
class Client
|
3
|
+
module Category
|
4
|
+
# Series module for fred/category/series endpoint
|
5
|
+
module Series
|
6
|
+
|
7
|
+
# Get the series in a category
|
8
|
+
#
|
9
|
+
# @param opts [Hash] options hash of parameters
|
10
|
+
# @option opts [Integer] api_key 32 character alpha-numeric lowercase string
|
11
|
+
# @option opts [String] file_type A key or file extension that indicates the type of file to send
|
12
|
+
# @option opts [Integer] category_id The id for a category
|
13
|
+
# @option opts [String] realtime_start The start of the real-time period
|
14
|
+
# @option opts [String] realtime_end The end of the real-time period
|
15
|
+
# @option opts [Integer] limit The maximum number of results to return
|
16
|
+
# @option opts [Integer] offset Non-negative integer
|
17
|
+
# @option opts [String] order_by Order results by values of the specified attribute
|
18
|
+
# @option opts [String] sort_order Sort results is ascending or descending order for attribute values specified by order_by
|
19
|
+
# @option opts [String] filter_variable The attribute to filter results by
|
20
|
+
# @option opts [String] filter_value The attribute to filter results by
|
21
|
+
# @option opts [String] tag_names A semicolon delimited list of tags to find related tags for
|
22
|
+
# @return [Hashie::Mash] Hash containing the results
|
23
|
+
def category_series opts={}
|
24
|
+
get "fred/category/series", opts
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module FREDAPI
|
2
|
+
class Client
|
3
|
+
module Category
|
4
|
+
# Tags module for fred/category/tags endpoint
|
5
|
+
module Tags
|
6
|
+
|
7
|
+
# Get the tags for a category
|
8
|
+
#
|
9
|
+
# @param opts [Hash] options hash of parameters
|
10
|
+
# @option opts [Integer] api_key 32 character alpha-numeric lowercase string
|
11
|
+
# @option opts [String] file_type A key or file extension that indicates the type of file to send
|
12
|
+
# @option opts [Integer] category_id The id for a category
|
13
|
+
# @option opts [String] realtime_start The start of the real-time period
|
14
|
+
# @option opts [String] realtime_end The end of the real-time period
|
15
|
+
# @option opts [String] tag_group_id A tag group id to filter tags by type
|
16
|
+
# @option opts [String] tag_names A semicolon delimited list of tags to find related tags for
|
17
|
+
# @option opts [String] search_text The words to find matching tags with
|
18
|
+
# @option opts [Integer] limit The maximum number of results to return
|
19
|
+
# @option opts [Integer] offset Non-negative integer
|
20
|
+
# @option opts [String] order_by Order results by values of the specified attribute
|
21
|
+
# @option opts [String] sort_order Sort results is ascending or descending order for attribute values specified by order_by
|
22
|
+
# @return [Hashie::Mash] Hash containing the results
|
23
|
+
def category_tags opts={}
|
24
|
+
get "fred/category/tags", opts
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module FREDAPI
|
2
|
+
class Client
|
3
|
+
# RelatedTags module for fred/related_tags endpoint
|
4
|
+
module RelatedTags
|
5
|
+
|
6
|
+
# Get the related tags for one or more tags
|
7
|
+
#
|
8
|
+
# @param opts [Hash] options hash of parameters
|
9
|
+
# @option opts [Integer] api_key 32 character alpha-numeric lowercase string
|
10
|
+
# @option opts [String] file_type A key or file extension that indicates the type of file to send
|
11
|
+
# @option opts [String] realtime_start The start of the real-time period
|
12
|
+
# @option opts [String] realtime_end The end of the real-time period
|
13
|
+
# @option opts [String] tag_group_id A tag group id to filter tags by type
|
14
|
+
# @option opts [String] tag_names A semicolon delimited list of tags to find related tags for
|
15
|
+
# @option opts [String] search_text The words to find matching tags with
|
16
|
+
# @option opts [Integer] limit The maximum number of results to return
|
17
|
+
# @option opts [Integer] offset Non-negative integer
|
18
|
+
# @option opts [String] order_by Order results by values of the specified attribute
|
19
|
+
# @option opts [String] sort_order Sort results is ascending or descending order for attribute values specified by order_by
|
20
|
+
# @return [Hashie::Mash] Hash containing the results
|
21
|
+
def related_tags opts={}
|
22
|
+
get "fred/related_tags", opts
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'fredapi/client/release/dates'
|
2
|
+
require 'fredapi/client/release/series'
|
3
|
+
require 'fredapi/client/release/sources'
|
4
|
+
require 'fredapi/client/release/tags'
|
5
|
+
require 'fredapi/client/release/related_tags'
|
6
|
+
|
7
|
+
module FREDAPI
|
8
|
+
class Client
|
9
|
+
# Release module for fred/release endpoint
|
10
|
+
module Release
|
11
|
+
|
12
|
+
# Get a release of economic data
|
13
|
+
#
|
14
|
+
# @param opts [Hash] options hash of parameters
|
15
|
+
# @option opts [Integer] api_key 32 character alpha-numeric lowercase string
|
16
|
+
# @option opts [String] file_type A key or file extension that indicates the type of file to send
|
17
|
+
# @option opts [Integer] release_id The id for a release
|
18
|
+
# @option opts [String] realtime_start The start of the real-time period
|
19
|
+
# @option opts [String] realtime_end The end of the real-time period
|
20
|
+
# @return [Hashie::Mash] Hash containing the results
|
21
|
+
def release opts={}
|
22
|
+
get "fred/release", opts
|
23
|
+
end
|
24
|
+
|
25
|
+
include FREDAPI::Client::Release::Dates
|
26
|
+
include FREDAPI::Client::Release::Series
|
27
|
+
include FREDAPI::Client::Release::Sources
|
28
|
+
include FREDAPI::Client::Release::Tags
|
29
|
+
include FREDAPI::Client::Release::RelatedTags
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module FREDAPI
|
2
|
+
class Client
|
3
|
+
module Release
|
4
|
+
# Dates module for fred/release/dates endpoint
|
5
|
+
module Dates
|
6
|
+
|
7
|
+
# Get release dates for all releases of economic data
|
8
|
+
#
|
9
|
+
# @param opts [Hash] options hash of parameters
|
10
|
+
# @option opts [Integer] api_key 32 character alpha-numeric lowercase string
|
11
|
+
# @option opts [String] file_type A key or file extension that indicates the type of file to send
|
12
|
+
# @option opts [Integer] release_id The id for a release
|
13
|
+
# @option opts [String] realtime_start The start of the real-time period
|
14
|
+
# @option opts [String] realtime_end The end of the real-time period
|
15
|
+
# @option opts [Integer] limit The maximum number of results to return
|
16
|
+
# @option opts [Integer] offset Non-negative integer
|
17
|
+
# @option opts [String] order_by Order results by values of the specified attribute
|
18
|
+
# @option opts [String] sort_order Sort results is ascending or descending order for attribute values specified by order_by
|
19
|
+
# @option opts [Integer] include_release_dates_with_no_data Determines whether release dates with no data available are returned.
|
20
|
+
# @return [Hashie::Mash] Hash containing the results
|
21
|
+
def release_dates opts={}
|
22
|
+
get "fred/release/dates", opts
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|