blacklight 6.0.0.pre3 → 6.0.0.pre4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/VERSION +1 -1
- data/app/controllers/bookmarks_controller.rb +0 -1
- data/app/controllers/catalog_controller.rb +0 -1
- data/app/controllers/concerns/blacklight/base.rb +0 -1
- data/app/controllers/concerns/blacklight/bookmarks.rb +0 -1
- data/app/controllers/concerns/blacklight/catalog.rb +6 -38
- data/app/controllers/concerns/blacklight/controller.rb +0 -2
- data/app/controllers/concerns/blacklight/search_fields.rb +0 -1
- data/app/controllers/concerns/blacklight/search_helper.rb +0 -5
- data/app/{models → controllers}/concerns/blacklight/token_based_user.rb +6 -10
- data/app/controllers/saved_searches_controller.rb +0 -1
- data/app/controllers/search_history_controller.rb +0 -1
- data/app/helpers/blacklight/blacklight_helper_behavior.rb +0 -4
- data/app/helpers/blacklight/catalog_helper_behavior.rb +3 -2
- data/app/helpers/blacklight/hash_as_hidden_fields_helper_behavior.rb +0 -1
- data/app/helpers/blacklight/layout_helper_behavior.rb +8 -0
- data/app/helpers/blacklight/render_constraints_helper_behavior.rb +0 -1
- data/app/helpers/blacklight/render_partials_helper.rb +1 -6
- data/app/helpers/blacklight/search_history_constraints_helper_behavior.rb +0 -1
- data/app/helpers/blacklight/url_helper_behavior.rb +1 -6
- data/app/models/blacklight/solr/facet_paginator.rb +0 -1
- data/app/models/bookmark.rb +0 -1
- data/app/models/concerns/blacklight/configurable.rb +0 -1
- data/app/models/concerns/blacklight/document/cache_key.rb +0 -1
- data/app/models/concerns/blacklight/document/email.rb +0 -1
- data/app/models/concerns/blacklight/document/sms.rb +0 -1
- data/app/models/concerns/blacklight/solr/document.rb +0 -7
- data/app/models/concerns/blacklight/user.rb +0 -1
- data/app/models/record_mailer.rb +0 -1
- data/app/models/search.rb +0 -6
- data/app/presenters/blacklight/document_presenter.rb +3 -17
- data/app/presenters/blacklight/json_presenter.rb +41 -0
- data/app/views/catalog/_document.html.erb +1 -1
- data/app/views/catalog/_document_default.atom.builder +2 -4
- data/app/views/catalog/facet.json.jbuilder +3 -0
- data/app/views/catalog/index.atom.builder +1 -1
- data/app/views/catalog/index.json.jbuilder +6 -0
- data/app/views/layouts/blacklight.html.erb +1 -1
- data/app/views/shared/_header_navbar.html.erb +2 -2
- data/blacklight.gemspec +9 -4
- data/db/migrate/20140202020201_create_searches.rb +1 -2
- data/db/migrate/20140202020202_create_bookmarks.rb +1 -2
- data/db/migrate/20140320000000_add_polymorphic_type_to_bookmarks.rb +0 -1
- data/lib/blacklight.rb +0 -10
- data/lib/blacklight/configuration.rb +0 -1
- data/lib/blacklight/engine.rb +0 -8
- data/lib/blacklight/exceptions.rb +0 -1
- data/lib/blacklight/routes.rb +0 -1
- data/lib/blacklight/version.rb +0 -1
- data/lib/generators/blacklight/assets_generator.rb +0 -1
- data/lib/generators/blacklight/install_generator.rb +8 -14
- data/lib/generators/blacklight/solr4_generator.rb +27 -0
- data/lib/generators/blacklight/solr5_generator.rb +21 -0
- data/lib/generators/blacklight/templates/alternate_controller.rb +0 -1
- data/lib/generators/blacklight/templates/catalog_controller.rb +3 -4
- data/lib/generators/blacklight/templates/solr_document.rb +0 -1
- data/lib/generators/blacklight/test_support_generator.rb +0 -1
- data/lib/railties/blacklight.rake +0 -7
- data/provision.sh +11 -1
- data/spec/controllers/blacklight/search_helper_spec.rb +0 -1
- data/spec/controllers/bookmarks_controller_spec.rb +26 -1
- data/spec/controllers/catalog_controller_spec.rb +8 -35
- data/spec/features/facets_spec.rb +0 -1
- data/spec/features/record_view_spec.rb +0 -1
- data/spec/features/search_context_spec.rb +0 -2
- data/spec/features/search_formats_spec.rb +0 -2
- data/spec/features/search_pagination_spec.rb +0 -2
- data/spec/features/search_results_spec.rb +0 -2
- data/spec/features/search_spec.rb +0 -2
- data/spec/helpers/blacklight_helper_spec.rb +3 -12
- data/spec/helpers/catalog_helper_spec.rb +8 -0
- data/spec/helpers/layout_helper_spec.rb +7 -0
- data/spec/helpers/url_helper_spec.rb +0 -7
- data/spec/lib/tasks/blacklight_task_spec.rb +0 -1
- data/spec/models/record_mailer_spec.rb +1 -3
- data/spec/models/search_spec.rb +1 -2
- data/spec/models/solr_document_spec.rb +22 -24
- data/spec/presenters/document_presenter_spec.rb +28 -6
- data/spec/spec_helper.rb +0 -1
- data/spec/views/catalog/_document.html.erb_spec.rb +20 -3
- data/spec/views/catalog/_sort_and_per_page.html.erb_spec.rb +2 -2
- data/spec/views/catalog/facet.json.jbuilder_spec.rb +9 -0
- data/spec/views/catalog/index.json.jbuilder_spec.rb +30 -0
- metadata +15 -15
- data/app/models/concerns/blacklight/solr/document/dublin_core.rb +0 -7
- data/app/models/concerns/blacklight/solr/document/email.rb +0 -7
- data/app/models/concerns/blacklight/solr/document/export.rb +0 -7
- data/app/models/concerns/blacklight/solr/document/extensions.rb +0 -8
- data/app/models/concerns/blacklight/solr/document/schema_org.rb +0 -7
- data/app/models/concerns/blacklight/solr/document/sms.rb +0 -7
- data/app/views/catalog/email_sent.html.erb +0 -2
- data/app/views/catalog/sms_sent.html.erb +0 -2
- data/lib/blacklight/configuration/solr_field.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de33efb7e9513e4348986f8e64b4f2cfec107802
|
4
|
+
data.tar.gz: 74ac4159ee1072f93f3f54b8115e14d501d68773
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f23fb77ae90ed8cbb00a6461643a4e3da47771ce25d02a717944722fe239b8d045d73206305e499d2b282f7cd6913eff624707c91adfba2721f83cd6ac37d1f9
|
7
|
+
data.tar.gz: 4c752134df04876f6bcc9831fe03071df4a7976657a5a15780226a02bc76d1b4ca5d77ab59d5b0f6c5e9cc67f8475ff0478a4f45643fd70312e414e51ff480b8
|
data/README.md
CHANGED
@@ -34,11 +34,11 @@ rails generate blacklight:install
|
|
34
34
|
|
35
35
|
## Dependencies
|
36
36
|
|
37
|
-
* ruby
|
37
|
+
* ruby v2.0 or higher
|
38
38
|
* git
|
39
39
|
* access to a command prompt on the machine to install
|
40
40
|
|
41
|
-
In addition, you must have the Bundler and Rails 4.
|
41
|
+
In addition, you must have the Bundler and Rails 4.1 (or greater) gems installed. Other gem dependencies are defined in the blacklight.gemspec file and will be automatically loaded by Bundler.
|
42
42
|
|
43
43
|
## Configuring Apache Solr
|
44
44
|
You'll also want some information about how Blacklight expects [Apache Solr](http://lucene.apache.org/solr ) to run, which you can find in [README_SOLR](https://github.com/projectblacklight/blacklight/wiki/README_SOLR)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
6.0.0.
|
1
|
+
6.0.0.pre4
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module Blacklight::Catalog
|
3
2
|
extend ActiveSupport::Concern
|
4
3
|
|
@@ -13,7 +12,7 @@ module Blacklight::Catalog
|
|
13
12
|
|
14
13
|
helper Blacklight::Facet
|
15
14
|
|
16
|
-
# When an action raises Blacklight::Exceptions::RecordNotFound, handle
|
15
|
+
# When an action raises Blacklight::Exceptions::RecordNotFound, handle
|
17
16
|
# the exception appropriately.
|
18
17
|
rescue_from Blacklight::Exceptions::RecordNotFound, with: :invalid_document_id_error
|
19
18
|
|
@@ -29,9 +28,11 @@ module Blacklight::Catalog
|
|
29
28
|
format.rss { render :layout => false }
|
30
29
|
format.atom { render :layout => false }
|
31
30
|
format.json do
|
32
|
-
|
31
|
+
@presenter = Blacklight::JsonPresenter.new(@response,
|
32
|
+
@document_list,
|
33
|
+
facets_from_request,
|
34
|
+
blacklight_config)
|
33
35
|
end
|
34
|
-
|
35
36
|
additional_response_formats(format)
|
36
37
|
document_export_formats(format)
|
37
38
|
end
|
@@ -76,7 +77,7 @@ module Blacklight::Catalog
|
|
76
77
|
respond_to do |format|
|
77
78
|
# Draw the facet selector for users who have javascript disabled:
|
78
79
|
format.html
|
79
|
-
format.json
|
80
|
+
format.json
|
80
81
|
|
81
82
|
# Draw the partial for the "more" facet modal window:
|
82
83
|
format.js { render :layout => false }
|
@@ -184,26 +185,6 @@ module Blacklight::Catalog
|
|
184
185
|
render text: @response.documents.map { |x| x.export_as(format_name) if x.exports_as? format_name }.compact.join("\n"), layout: false
|
185
186
|
end
|
186
187
|
|
187
|
-
# override this method to change the JSON response from #index
|
188
|
-
def render_search_results_as_json
|
189
|
-
{response: {docs: @document_list, facets: search_facets_as_json, pages: pagination_info(@response)}}
|
190
|
-
end
|
191
|
-
|
192
|
-
def search_facets_as_json
|
193
|
-
facets_from_request.as_json.each do |f|
|
194
|
-
f.delete "options"
|
195
|
-
f["label"] = facet_configuration_for_field(f["name"]).label
|
196
|
-
f["items"] = f["items"].as_json.each do |i|
|
197
|
-
i['label'] ||= i['value']
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
# override this method to change the JSON response from #facet
|
203
|
-
def render_facet_list_as_json
|
204
|
-
{response: {facets: @pagination }}
|
205
|
-
end
|
206
|
-
|
207
188
|
# Overrides the Blacklight::Controller provided #search_action_url.
|
208
189
|
# By default, any search action from a Blacklight::Catalog controller
|
209
190
|
# should use the current controller when constructing the route.
|
@@ -211,19 +192,6 @@ module Blacklight::Catalog
|
|
211
192
|
url_for(options.merge(:action => 'index'))
|
212
193
|
end
|
213
194
|
|
214
|
-
# extract the pagination info from the response object
|
215
|
-
def pagination_info response
|
216
|
-
h = {}
|
217
|
-
|
218
|
-
[:current_page, :next_page, :prev_page, :total_pages,
|
219
|
-
:limit_value, :offset_value, :total_count,
|
220
|
-
:first_page?, :last_page?].each do |k|
|
221
|
-
h[k] = response.send(k)
|
222
|
-
end
|
223
|
-
|
224
|
-
h
|
225
|
-
end
|
226
|
-
|
227
195
|
# Email Action (this will render the appropriate view on GET requests and process the form and send the email on POST requests)
|
228
196
|
def email_action documents
|
229
197
|
mail = RecordMailer.email_record(documents, {:to => params[:to], :message => params[:message]}, url_options)
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
# SearchHelper is a controller layer mixin. It is in the controller scope: request params, session etc.
|
3
2
|
#
|
4
3
|
# NOTE: Be careful when creating variables here as they may be overriding something that already exists.
|
@@ -79,10 +78,6 @@ module Blacklight::SearchHelper
|
|
79
78
|
if id.is_a? Array
|
80
79
|
fetch_many(id, params, extra_controller_params)
|
81
80
|
else
|
82
|
-
if id.nil?
|
83
|
-
Deprecation.warn Blacklight::SearchHelper, "Calling #fetch without an explicit id argument is deprecated and will be removed in Blacklight 6.0"
|
84
|
-
id ||= params[:id]
|
85
|
-
end
|
86
81
|
fetch_one(id, extra_controller_params)
|
87
82
|
end
|
88
83
|
end
|
@@ -36,21 +36,17 @@ module Blacklight::TokenBasedUser
|
|
36
36
|
|
37
37
|
# Used for #export action with encrypted user_id, available
|
38
38
|
# as a helper method for views.
|
39
|
-
def encrypt_user_id(user_id)
|
40
|
-
|
39
|
+
def encrypt_user_id(user_id, current_time = nil)
|
40
|
+
current_time ||= Time.zone.now
|
41
|
+
message_encryptor.encrypt_and_sign([user_id, current_time])
|
41
42
|
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
# When we drop support for Rails 3, we can just use the AS::KeyGenerator
|
46
|
-
# directly instead of this helper.
|
47
|
-
def export_secret_token salt
|
48
|
-
OpenSSL::PKCS5.pbkdf2_hmac_sha1(Blacklight.secret_key, salt, 1000, 64)
|
44
|
+
def export_secret_token
|
45
|
+
ActiveSupport::KeyGenerator.new(Rails.application.secrets.secret_key_base).generate_key('encrypted user session key')
|
49
46
|
end
|
50
47
|
|
51
48
|
def message_encryptor
|
52
|
-
|
53
|
-
ActiveSupport::MessageEncryptor.new(derived_secret)
|
49
|
+
ActiveSupport::MessageEncryptor.new(export_secret_token)
|
54
50
|
end
|
55
51
|
|
56
52
|
end
|
@@ -1,8 +1,4 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
# -*- coding: utf-8 -*-
|
3
|
-
#
|
4
1
|
# Methods added to this helper will be available to all templates in the hosting application
|
5
|
-
#
|
6
2
|
module Blacklight::BlacklightHelperBehavior
|
7
3
|
include BlacklightUrlHelper
|
8
4
|
include BlacklightConfigurationHelper
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
module Blacklight::CatalogHelperBehavior
|
3
2
|
|
4
3
|
##
|
@@ -179,7 +178,9 @@ module Blacklight::CatalogHelperBehavior
|
|
179
178
|
value = if blacklight_config.view_config(document_index_view_type).thumbnail_method
|
180
179
|
send(blacklight_config.view_config(document_index_view_type).thumbnail_method, document, image_options)
|
181
180
|
elsif blacklight_config.view_config(document_index_view_type).thumbnail_field
|
182
|
-
|
181
|
+
url = thumbnail_url(document)
|
182
|
+
|
183
|
+
image_tag url, image_options if url.present?
|
183
184
|
end
|
184
185
|
|
185
186
|
if value
|
@@ -30,5 +30,13 @@ module Blacklight
|
|
30
30
|
def sidebar_classes
|
31
31
|
'col-md-3 col-sm-4'
|
32
32
|
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Class used for specifying main layout container classes. Can be
|
36
|
+
# overwritten to return 'container-fluid' for Bootstrap full-width layout
|
37
|
+
# @return [String]
|
38
|
+
def container_classes
|
39
|
+
'container'
|
40
|
+
end
|
33
41
|
end
|
34
42
|
end
|
@@ -39,12 +39,7 @@ module Blacklight::RenderPartialsHelper
|
|
39
39
|
# @param [String] base name for the partial
|
40
40
|
# @param [Hash] locales to pass through to the partials
|
41
41
|
def render_document_partial(doc, base_name, locals = {})
|
42
|
-
format =
|
43
|
-
Deprecation.warn self, "The #document_partial_name with a single argument is deprecated. Update your override to include a second argument for the 'base name'"
|
44
|
-
document_partial_name(doc)
|
45
|
-
else
|
46
|
-
document_partial_name(doc, base_name)
|
47
|
-
end
|
42
|
+
format = document_partial_name(doc, base_name)
|
48
43
|
|
49
44
|
view_type = document_index_view_type
|
50
45
|
template = cached_view ['show', view_type, base_name, format].join('_') do
|
@@ -12,17 +12,12 @@ module Blacklight::UrlHelperBehavior
|
|
12
12
|
end
|
13
13
|
|
14
14
|
# link_to_document(doc, 'VIEW', :counter => 3)
|
15
|
-
# link_to_document(doc, :label=>'VIEW', :counter => 3)
|
16
15
|
# Use the catalog_path RESTful route to create a link to the show page for a specific item.
|
17
16
|
# catalog_path accepts a HashWithIndifferentAccess object. The solr query params are stored in the session,
|
18
17
|
# so we only need the +counter+ param here. We also need to know if we are viewing to document as part of search results.
|
19
18
|
def link_to_document(doc, field_or_opts = nil, opts={:counter => nil})
|
20
19
|
if field_or_opts.is_a? Hash
|
21
20
|
opts = field_or_opts
|
22
|
-
if opts[:label]
|
23
|
-
Deprecation.warn self, "The second argument to link_to_document should now be the label."
|
24
|
-
field = opts.delete(:label)
|
25
|
-
end
|
26
21
|
else
|
27
22
|
field = field_or_opts
|
28
23
|
end
|
@@ -151,7 +146,7 @@ module Blacklight::UrlHelperBehavior
|
|
151
146
|
|
152
147
|
# Get url parameters to a search within a grouped result set
|
153
148
|
#
|
154
|
-
# @param [Blacklight::
|
149
|
+
# @param [Blacklight::Solr::Response::Group]
|
155
150
|
# @return [Hash]
|
156
151
|
def add_group_facet_params_and_redirect group
|
157
152
|
search_state.add_facet_params_and_redirect(group.field, group.key)
|
data/app/models/bookmark.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
require 'rsolr'
|
3
2
|
##
|
4
3
|
##
|
@@ -16,12 +15,6 @@ require 'rsolr'
|
|
16
15
|
#
|
17
16
|
|
18
17
|
module Blacklight::Solr::Document
|
19
|
-
autoload :SchemaOrg, 'blacklight/solr/document/schema_org'
|
20
|
-
autoload :DublinCore, 'blacklight/solr/document/dublin_core'
|
21
|
-
autoload :Email, 'blacklight/solr/document/email'
|
22
|
-
autoload :Sms, 'blacklight/solr/document/sms'
|
23
|
-
autoload :Extensions, 'blacklight/solr/document/extensions'
|
24
|
-
autoload :Export, 'blacklight/solr/document/export'
|
25
18
|
autoload :MoreLikeThis, 'blacklight/solr/document/more_like_this'
|
26
19
|
|
27
20
|
extend ActiveSupport::Concern
|
data/app/models/record_mailer.rb
CHANGED
data/app/models/search.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
1
|
class Search < ActiveRecord::Base
|
3
2
|
|
4
3
|
belongs_to :user
|
@@ -9,11 +8,6 @@ class Search < ActiveRecord::Base
|
|
9
8
|
attr_accessible :query_params
|
10
9
|
end
|
11
10
|
|
12
|
-
unless respond_to?(:none)
|
13
|
-
# polyfill
|
14
|
-
scope :none, -> { where(id: nil).where("id IS NOT ?", nil) }
|
15
|
-
end
|
16
|
-
|
17
11
|
# A Search instance is considered a saved search if it has a user_id.
|
18
12
|
def saved?
|
19
13
|
self.user_id?
|
@@ -99,29 +99,15 @@ module Blacklight
|
|
99
99
|
options = {}
|
100
100
|
options = field_config.separator_options if field_config && field_config.separator_options
|
101
101
|
|
102
|
-
if field_config && field_config.separator
|
103
|
-
Deprecation.warn(self.class, 'The field configuration #separator is deprecated. Use #separator_options instead')
|
104
|
-
options[:words_connector] ||= field_config.separator
|
105
|
-
options[:two_words_connector] ||= field_config.separator
|
106
|
-
options[:last_word_connector] ||= field_config.separator
|
107
|
-
end
|
108
|
-
|
109
102
|
values.map { |x| html_escape(x) }.to_sentence(options).html_safe
|
110
103
|
end
|
111
104
|
|
112
105
|
##
|
113
106
|
# Render the document index heading
|
114
107
|
#
|
115
|
-
# @param [Hash] opts (Deprecated)
|
116
|
-
# @option opts [Symbol] :label Render the given field from the document
|
117
|
-
# @option opts [Proc] :label Evaluate the given proc
|
118
|
-
# @option opts [String] :label Render the given string
|
119
108
|
# @param [Symbol, Proc, String] field Render the given field or evaluate the proc or render the given string
|
120
|
-
|
121
|
-
|
122
|
-
Deprecation.warn DocumentPresenter, "Calling render_document_index_label with a hash is deprecated"
|
123
|
-
field = field[:label]
|
124
|
-
end
|
109
|
+
# @param [Hash] opts
|
110
|
+
def render_document_index_label(field, opts = {})
|
125
111
|
label = case field
|
126
112
|
when Symbol
|
127
113
|
@document[field]
|
@@ -211,7 +197,7 @@ module Blacklight
|
|
211
197
|
# rendering values
|
212
198
|
case
|
213
199
|
when (field_config and field_config.helper_method)
|
214
|
-
@controller.send(field_config.helper_method, options.merge(:
|
200
|
+
@controller.send(field_config.helper_method, options.merge(document: @document, field: field, config: field_config, value: value))
|
215
201
|
when (field_config and field_config.link_to_search)
|
216
202
|
link_field = if field_config.link_to_search === true
|
217
203
|
field_config.key
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Blacklight
|
2
|
+
class JsonPresenter
|
3
|
+
include Blacklight::Facet
|
4
|
+
|
5
|
+
# @param [Solr::Response] response raw solr response.
|
6
|
+
# @param [Array<SolrDocument>] documents a list of documents
|
7
|
+
# @param [Array] facets list of facets
|
8
|
+
def initialize(response, documents, facets, blacklight_config)
|
9
|
+
@response = response
|
10
|
+
@documents = documents
|
11
|
+
@facets = facets
|
12
|
+
@blacklight_config = blacklight_config
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :documents, :blacklight_config
|
16
|
+
|
17
|
+
def search_facets_as_json
|
18
|
+
@facets.as_json.each do |f|
|
19
|
+
f.delete "options"
|
20
|
+
f["label"] = facet_configuration_for_field(f["name"]).label
|
21
|
+
f["items"] = f["items"].as_json.each do |i|
|
22
|
+
i['label'] ||= i['value']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
# extract the pagination info from the response object
|
29
|
+
def pagination_info
|
30
|
+
h = {}
|
31
|
+
|
32
|
+
[:current_page, :next_page, :prev_page, :total_pages,
|
33
|
+
:limit_value, :offset_value, :total_count,
|
34
|
+
:first_page?, :last_page?].each do |k|
|
35
|
+
h[k] = @response.send(k)
|
36
|
+
end
|
37
|
+
|
38
|
+
h
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|