blacklight 6.0.2 → 6.1.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 +4 -4
- data/.rubocop.yml +6 -6
- data/.rubocop_todo.yml +448 -87
- data/.travis.yml +1 -1
- data/VERSION +1 -1
- data/app/controllers/concerns/blacklight/bookmarks.rb +8 -8
- data/app/controllers/concerns/blacklight/catalog.rb +5 -5
- data/app/controllers/concerns/blacklight/controller.rb +5 -5
- data/app/controllers/concerns/blacklight/saved_searches.rb +4 -2
- data/app/controllers/concerns/blacklight/search_context.rb +3 -0
- data/app/controllers/concerns/blacklight/token_based_user.rb +1 -1
- data/app/helpers/blacklight/blacklight_helper_behavior.rb +3 -3
- data/app/helpers/blacklight/catalog_helper_behavior.rb +20 -9
- data/app/helpers/blacklight/configuration_helper_behavior.rb +1 -1
- data/app/helpers/blacklight/deprecated_url_helper_behavior.rb +1 -1
- data/app/helpers/blacklight/facets_helper_behavior.rb +2 -2
- data/app/helpers/blacklight/hash_as_hidden_fields_helper_behavior.rb +1 -1
- data/app/helpers/blacklight/render_constraints_helper_behavior.rb +18 -8
- data/app/helpers/blacklight/render_partials_helper.rb +15 -3
- data/app/models/concerns/blacklight/configurable.rb +4 -8
- data/app/models/concerns/blacklight/document.rb +3 -3
- data/app/models/concerns/blacklight/document/dublin_core.rb +1 -1
- data/app/models/concerns/blacklight/document/extensions.rb +1 -1
- data/app/models/concerns/blacklight/user.rb +1 -1
- data/app/models/record_mailer.rb +6 -1
- data/app/models/search.rb +2 -2
- data/blacklight.gemspec +5 -2
- data/config/locales/blacklight.de.yml +1 -0
- data/config/locales/blacklight.en.yml +1 -0
- data/config/locales/blacklight.es.yml +1 -0
- data/config/locales/blacklight.fr.yml +1 -0
- data/config/locales/blacklight.it.yml +1 -0
- data/config/locales/blacklight.pt-BR.yml +1 -0
- data/lib/blacklight.rb +2 -2
- data/lib/blacklight/abstract_repository.rb +2 -2
- data/lib/blacklight/configuration/field.rb +1 -1
- data/lib/blacklight/configuration/search_field.rb +1 -1
- data/lib/blacklight/configuration/sort_field.rb +1 -1
- data/lib/blacklight/search_builder.rb +8 -4
- data/lib/blacklight/search_state.rb +3 -3
- data/lib/blacklight/solr/repository.rb +3 -3
- data/lib/blacklight/solr/request.rb +2 -2
- data/lib/blacklight/solr/response.rb +1 -1
- data/lib/blacklight/solr/response/spelling.rb +1 -1
- data/lib/blacklight/solr/search_builder_behavior.rb +7 -7
- data/lib/blacklight/utils.rb +5 -5
- data/lib/generators/blacklight/assets_generator.rb +1 -1
- data/lib/generators/blacklight/controller_generator.rb +13 -15
- data/lib/generators/blacklight/document_generator.rb +5 -4
- data/lib/generators/blacklight/install_generator.rb +24 -27
- data/lib/generators/blacklight/models_generator.rb +18 -16
- data/lib/generators/blacklight/search_builder_generator.rb +4 -4
- data/lib/generators/blacklight/solr4_generator.rb +14 -9
- data/lib/generators/blacklight/solr5_generator.rb +1 -1
- data/lib/generators/blacklight/templates/{blacklight.css.scss → blacklight.scss} +0 -0
- data/lib/generators/blacklight/templates/solr_document.rb +6 -8
- data/lib/generators/blacklight/test_support_generator.rb +5 -3
- data/lib/generators/blacklight/user_generator.rb +18 -12
- data/lib/railties/blacklight.rake +2 -2
- data/tasks/blacklight.rake +1 -3
- metadata +17 -10
- data/.rubocop_hound.yml +0 -1063
data/.travis.yml
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
6.0
|
1
|
+
6.1.0
|
@@ -34,7 +34,7 @@ module Blacklight::Bookmarks
|
|
34
34
|
# Blacklight uses #search_action_url to figure out the right URL for
|
35
35
|
# the global search box
|
36
36
|
def search_action_url *args
|
37
|
-
search_catalog_url
|
37
|
+
search_catalog_url(*args)
|
38
38
|
end
|
39
39
|
|
40
40
|
def index
|
@@ -70,11 +70,11 @@ module Blacklight::Bookmarks
|
|
70
70
|
# bookmark[title] and bookmark[document_id], but in that case #update
|
71
71
|
# is simpler.
|
72
72
|
def create
|
73
|
-
if params[:bookmarks]
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
@bookmarks = if params[:bookmarks]
|
74
|
+
params[:bookmarks]
|
75
|
+
else
|
76
|
+
[{ document_id: params[:id], document_type: blacklight_config.document_model.to_s }]
|
77
|
+
end
|
78
78
|
|
79
79
|
current_or_guest_user.save! unless current_or_guest_user.persisted?
|
80
80
|
|
@@ -85,9 +85,9 @@ module Blacklight::Bookmarks
|
|
85
85
|
if request.xhr?
|
86
86
|
success ? render(json: { bookmarks: { count: current_or_guest_user.bookmarks.count }}) : render(:text => "", :status => "500")
|
87
87
|
else
|
88
|
-
if @bookmarks.
|
88
|
+
if @bookmarks.any? && success
|
89
89
|
flash[:notice] = I18n.t('blacklight.bookmarks.add.success', :count => @bookmarks.length)
|
90
|
-
elsif @bookmarks.
|
90
|
+
elsif @bookmarks.any?
|
91
91
|
flash[:error] = I18n.t('blacklight.bookmarks.add.failure', :count => @bookmarks.length)
|
92
92
|
end
|
93
93
|
|
@@ -58,7 +58,7 @@ module Blacklight::Catalog
|
|
58
58
|
search_session['id'] = params[:search_id]
|
59
59
|
search_session['per_page'] = params[:per_page]
|
60
60
|
|
61
|
-
if params[:redirect] and (params[:redirect].starts_with?('/') or params[:redirect] =~ URI
|
61
|
+
if params[:redirect] and (params[:redirect].starts_with?('/') or params[:redirect] =~ URI.regexp)
|
62
62
|
path = URI.parse(params[:redirect]).path
|
63
63
|
redirect_to path, status: 303
|
64
64
|
else
|
@@ -141,11 +141,11 @@ module Blacklight::Catalog
|
|
141
141
|
format.send key do
|
142
142
|
case config
|
143
143
|
when false
|
144
|
-
raise ActionController::RoutingError
|
144
|
+
raise ActionController::RoutingError, 'Not Found'
|
145
145
|
when Hash
|
146
146
|
render config
|
147
147
|
when Proc
|
148
|
-
instance_exec
|
148
|
+
instance_exec(&config)
|
149
149
|
when Symbol, String
|
150
150
|
send config
|
151
151
|
else
|
@@ -173,7 +173,7 @@ module Blacklight::Catalog
|
|
173
173
|
if @response.export_formats.include? format_name
|
174
174
|
render_document_export_format format_name
|
175
175
|
else
|
176
|
-
raise ActionController::UnknownFormat
|
176
|
+
raise ActionController::UnknownFormat
|
177
177
|
end
|
178
178
|
end
|
179
179
|
end
|
@@ -192,7 +192,7 @@ module Blacklight::Catalog
|
|
192
192
|
# By default, any search action from a Blacklight::Catalog controller
|
193
193
|
# should use the current controller when constructing the route.
|
194
194
|
def search_action_url options = {}
|
195
|
-
raise "Options was not a hash (#{options.class}" unless options.is_a? Hash
|
195
|
+
raise ArgumentError, "Options was not a hash (#{options.class}" unless options.is_a? Hash
|
196
196
|
# We don't want to permit here because one of the options could be :only_path, which is an option, but not a parameter
|
197
197
|
# options.permit!
|
198
198
|
url_for(options.merge(action: 'index'))
|
@@ -81,7 +81,7 @@ module Blacklight::Controller
|
|
81
81
|
args.first[:only_path] = true
|
82
82
|
end
|
83
83
|
|
84
|
-
search_action_url
|
84
|
+
search_action_url(*args)
|
85
85
|
end
|
86
86
|
|
87
87
|
def search_facet_url options = {}
|
@@ -104,11 +104,11 @@ module Blacklight::Controller
|
|
104
104
|
def current_or_guest_user
|
105
105
|
if defined? super
|
106
106
|
super
|
107
|
-
|
108
|
-
current_user
|
107
|
+
elsif has_user_authentication_provider?
|
108
|
+
current_user
|
109
109
|
end
|
110
110
|
end
|
111
|
-
|
111
|
+
alias blacklight_current_or_guest_user current_or_guest_user
|
112
112
|
|
113
113
|
##
|
114
114
|
# We discard flash messages generated by the xhr requests to avoid
|
@@ -125,7 +125,7 @@ module Blacklight::Controller
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def require_user_authentication_provider
|
128
|
-
raise ActionController::RoutingError
|
128
|
+
raise ActionController::RoutingError, 'Not Found' unless has_user_authentication_provider?
|
129
129
|
end
|
130
130
|
|
131
131
|
##
|
@@ -32,11 +32,13 @@ module Blacklight
|
|
32
32
|
# Only dereferences the user rather than removing the item in case it
|
33
33
|
# is in the session[:history]
|
34
34
|
def forget
|
35
|
-
|
35
|
+
search = current_user.searches.find(params[:id])
|
36
|
+
|
37
|
+
if search.present?
|
36
38
|
search.user_id = nil
|
37
39
|
search.save
|
38
40
|
|
39
|
-
flash[:notice] =I18n.t('blacklight.saved_searches.remove.success')
|
41
|
+
flash[:notice] = I18n.t('blacklight.saved_searches.remove.success')
|
40
42
|
else
|
41
43
|
flash[:error] = I18n.t('blacklight.saved_searches.remove.failure')
|
42
44
|
end
|
@@ -21,6 +21,9 @@ module Blacklight::SearchContext
|
|
21
21
|
# sets up the session[:search] hash if it doesn't already exist
|
22
22
|
def search_session
|
23
23
|
session[:search] ||= {}
|
24
|
+
# Need to call the getter again. The value is mutated
|
25
|
+
# https://github.com/rails/rails/issues/23884
|
26
|
+
session[:search]
|
24
27
|
end
|
25
28
|
|
26
29
|
# The current search session
|
@@ -29,7 +29,7 @@ module Blacklight::TokenBasedUser
|
|
29
29
|
user_id, timestamp = message_encryptor.decrypt_and_verify(encrypted_user_id)
|
30
30
|
|
31
31
|
if timestamp < 1.hour.ago
|
32
|
-
raise Blacklight::Exceptions::ExpiredSessionToken
|
32
|
+
raise Blacklight::Exceptions::ExpiredSessionToken
|
33
33
|
end
|
34
34
|
|
35
35
|
user_id
|
@@ -111,7 +111,7 @@ module Blacklight::BlacklightHelperBehavior
|
|
111
111
|
# @param [Blacklight::Solr::Response] response
|
112
112
|
# @return [Boolean]
|
113
113
|
def should_show_spellcheck_suggestions? response
|
114
|
-
response.total <= spell_check_max and response.spelling.words.
|
114
|
+
response.total <= spell_check_max and response.spelling.words.any?
|
115
115
|
end
|
116
116
|
|
117
117
|
##
|
@@ -256,7 +256,7 @@ module Blacklight::BlacklightHelperBehavior
|
|
256
256
|
options = args.extract_options!
|
257
257
|
document = args.first
|
258
258
|
tag = options.fetch(:tag, :h4)
|
259
|
-
document
|
259
|
+
document ||= @document
|
260
260
|
|
261
261
|
content_tag(tag, presenter(document).document_heading, itemprop: "name")
|
262
262
|
end
|
@@ -307,7 +307,7 @@ module Blacklight::BlacklightHelperBehavior
|
|
307
307
|
def with_format(format, &block)
|
308
308
|
old_formats = formats
|
309
309
|
self.formats = [format]
|
310
|
-
|
310
|
+
yield
|
311
311
|
self.formats = old_formats
|
312
312
|
nil
|
313
313
|
end
|
@@ -45,9 +45,18 @@ module Blacklight::CatalogHelperBehavior
|
|
45
45
|
end
|
46
46
|
|
47
47
|
case collection.total_count
|
48
|
-
when 0
|
49
|
-
|
50
|
-
|
48
|
+
when 0
|
49
|
+
t('blacklight.search.pagination_info.no_items_found', :entry_name => entry_name ).html_safe
|
50
|
+
when 1
|
51
|
+
t('blacklight.search.pagination_info.single_item_found', :entry_name => entry_name).html_safe
|
52
|
+
else
|
53
|
+
t('blacklight.search.pagination_info.pages', :entry_name => entry_name,
|
54
|
+
:current_page => collection.current_page,
|
55
|
+
:num_pages => collection.total_pages,
|
56
|
+
:start_num => number_with_delimiter(collection.offset_value + 1),
|
57
|
+
:end_num => number_with_delimiter(end_num),
|
58
|
+
:total_num => number_with_delimiter(collection.total_count),
|
59
|
+
:count => collection.total_pages).html_safe
|
51
60
|
end
|
52
61
|
end
|
53
62
|
|
@@ -72,7 +81,9 @@ module Blacklight::CatalogHelperBehavior
|
|
72
81
|
# @see #page_entries_info
|
73
82
|
# @return [String]
|
74
83
|
def item_page_entry_info
|
75
|
-
t('blacklight.search.entry_pagination_info.other', :current => number_with_delimiter(search_session['counter']),
|
84
|
+
t('blacklight.search.entry_pagination_info.other', :current => number_with_delimiter(search_session['counter']),
|
85
|
+
:total => number_with_delimiter(search_session['total']),
|
86
|
+
:count => search_session['total'].to_i).html_safe
|
76
87
|
end
|
77
88
|
|
78
89
|
##
|
@@ -258,11 +269,11 @@ module Blacklight::CatalogHelperBehavior
|
|
258
269
|
if params['q'].present?
|
259
270
|
q_label = label_for_search_field(params[:search_field]) unless default_search_field && params[:search_field] == default_search_field[:key]
|
260
271
|
|
261
|
-
if q_label.present?
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
272
|
+
constraints += if q_label.present?
|
273
|
+
[t('blacklight.search.page_title.constraint', label: q_label, value: params['q'])]
|
274
|
+
else
|
275
|
+
[params['q']]
|
276
|
+
end
|
266
277
|
end
|
267
278
|
|
268
279
|
if params['f'].present?
|
@@ -14,7 +14,7 @@ module Blacklight
|
|
14
14
|
Deprecation.warn(Blacklight::DeprecatedUrlHelperBehavior, 'Use Blacklight::SearchState.new(source_params).params_for_search instead')
|
15
15
|
Blacklight::SearchState.new(args.first, blacklight_config).params_for_search(args.last)
|
16
16
|
else
|
17
|
-
raise ArgumentError
|
17
|
+
raise ArgumentError, "wrong number of arguments (#{args.length} for 0..2)"
|
18
18
|
end
|
19
19
|
end
|
20
20
|
deprecation_deprecate :params_for_search
|
@@ -38,10 +38,10 @@ module Blacklight::FacetsHelperBehavior
|
|
38
38
|
# @option options [Hash] :locals locals to pass to the partial
|
39
39
|
# @return [String]
|
40
40
|
def render_facet_limit(display_facet, options = {})
|
41
|
-
return
|
41
|
+
return unless should_render_facet?(display_facet)
|
42
42
|
options = options.dup
|
43
43
|
options[:partial] ||= facet_partial_name(display_facet)
|
44
|
-
options[:layout] ||= "facet_layout" unless options.
|
44
|
+
options[:layout] ||= "facet_layout" unless options.key?(:layout)
|
45
45
|
options[:locals] ||= {}
|
46
46
|
options[:locals][:field_name] ||= display_facet.name
|
47
47
|
options[:locals][:solr_field] ||= display_facet.name # deprecated
|
@@ -21,7 +21,7 @@ module Blacklight::HashAsHiddenFieldsHelperBehavior
|
|
21
21
|
|
22
22
|
hidden_fields = []
|
23
23
|
flatten_hash(hash).each do |name, value|
|
24
|
-
value =
|
24
|
+
value = Array.wrap(value)
|
25
25
|
value.each do |v|
|
26
26
|
hidden_fields << hidden_field_tag(name, v.to_s, :id => nil)
|
27
27
|
end
|
@@ -9,7 +9,7 @@ module Blacklight::RenderConstraintsHelperBehavior
|
|
9
9
|
|
10
10
|
##
|
11
11
|
# Check if the query has any constraints defined (a query, facet, etc)
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# @param [Hash] query parameters
|
14
14
|
# @return [Boolean]
|
15
15
|
def query_has_constraints?(localized_params = params)
|
@@ -29,19 +29,30 @@ module Blacklight::RenderConstraintsHelperBehavior
|
|
29
29
|
##
|
30
30
|
# Render the query constraints
|
31
31
|
#
|
32
|
-
# @param [
|
32
|
+
# @param [ActionController::Parameters] query parameters
|
33
33
|
# @return [String]
|
34
34
|
def render_constraints_query(localized_params = params)
|
35
35
|
# So simple don't need a view template, we can just do it here.
|
36
|
-
scope = localized_params.delete(:route_set) || self
|
37
36
|
return "".html_safe if localized_params[:q].blank?
|
38
37
|
|
39
|
-
options = localized_params.merge(:q=>nil, :action=>'index')
|
40
|
-
options.permit!
|
41
38
|
render_constraint_element(constraint_query_label(localized_params),
|
42
39
|
localized_params[:q],
|
43
40
|
classes: ["query"],
|
44
|
-
remove:
|
41
|
+
remove: remove_constraint_url(localized_params))
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Provide a url for removing a particular constraint. This can be overriden
|
46
|
+
# in the case that you want parameters other than the defaults to be removed
|
47
|
+
# (e.g. :search_field)
|
48
|
+
#
|
49
|
+
# @param [ActionController::Parameters] localized_params query parameters
|
50
|
+
# @return [String]
|
51
|
+
def remove_constraint_url(localized_params)
|
52
|
+
scope = localized_params.delete(:route_set) || self
|
53
|
+
options = localized_params.merge(q: nil, action: 'index')
|
54
|
+
options.permit!
|
55
|
+
scope.url_for(options)
|
45
56
|
end
|
46
57
|
|
47
58
|
##
|
@@ -92,7 +103,6 @@ module Blacklight::RenderConstraintsHelperBehavior
|
|
92
103
|
# @option options [Array<String>] :classes an array of classes to add to container span for constraint.
|
93
104
|
# @return [String]
|
94
105
|
def render_constraint_element(label, value, options = {})
|
95
|
-
render(:partial => "catalog/constraints_element", :locals => {:label => label, :value => value, :options => options})
|
106
|
+
render(:partial => "catalog/constraints_element", :locals => {:label => label, :value => value, :options => options})
|
96
107
|
end
|
97
|
-
|
98
108
|
end
|
@@ -87,7 +87,11 @@ module Blacklight::RenderPartialsHelper
|
|
87
87
|
# first, the legacy template names for backwards compatbility
|
88
88
|
# followed by the new, inheritable style
|
89
89
|
# finally, a controller-specific path for non-catalog subclasses
|
90
|
-
@document_index_path_templates ||= [
|
90
|
+
@document_index_path_templates ||= [
|
91
|
+
"document_%{index_view_type}",
|
92
|
+
"catalog/document_%{index_view_type}",
|
93
|
+
"catalog/document_list"
|
94
|
+
]
|
91
95
|
end
|
92
96
|
|
93
97
|
|
@@ -128,7 +132,7 @@ module Blacklight::RenderPartialsHelper
|
|
128
132
|
def document_partial_name(document, base_name = nil)
|
129
133
|
view_config = blacklight_config.view_config(:show)
|
130
134
|
|
131
|
-
display_type = if base_name and view_config.
|
135
|
+
display_type = if base_name and view_config.key? :"#{base_name}_display_type_field"
|
132
136
|
document[view_config[:"#{base_name}_display_type_field"]]
|
133
137
|
end
|
134
138
|
|
@@ -152,7 +156,15 @@ module Blacklight::RenderPartialsHelper
|
|
152
156
|
# first, the legacy template names for backwards compatbility
|
153
157
|
# followed by the new, inheritable style
|
154
158
|
# finally, a controller-specific path for non-catalog subclasses
|
155
|
-
@partial_path_templates ||= [
|
159
|
+
@partial_path_templates ||= [
|
160
|
+
"%{action_name}_%{index_view_type}_%{format}",
|
161
|
+
"%{action_name}_%{index_view_type}_default",
|
162
|
+
"%{action_name}_%{format}",
|
163
|
+
"%{action_name}_default",
|
164
|
+
"catalog/%{action_name}_%{format}",
|
165
|
+
"catalog/_%{action_name}_partials/%{format}",
|
166
|
+
"catalog/_%{action_name}_partials/default"
|
167
|
+
]
|
156
168
|
end
|
157
169
|
|
158
170
|
private
|
@@ -23,15 +23,11 @@ module Blacklight::Configurable
|
|
23
23
|
# object' that won't be automatically available to subclasses, that's why
|
24
24
|
# we lazy load to 'inherit' how we want.
|
25
25
|
def blacklight_config
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@blacklight_config = default_configuration
|
31
|
-
end
|
26
|
+
@blacklight_config ||= if superclass.respond_to?(:blacklight_config)
|
27
|
+
superclass.blacklight_config.deep_copy
|
28
|
+
else
|
29
|
+
default_configuration
|
32
30
|
end
|
33
|
-
|
34
|
-
return @blacklight_config
|
35
31
|
end
|
36
32
|
attr_writer :blacklight_config
|
37
33
|
|
@@ -86,18 +86,18 @@ module Blacklight::Document
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
89
|
-
|
89
|
+
alias has_field? has?
|
90
90
|
|
91
91
|
def key? k
|
92
92
|
_source.key? k
|
93
93
|
end
|
94
|
-
|
94
|
+
alias has_key? key?
|
95
95
|
|
96
96
|
def fetch key, *default
|
97
97
|
if key? key
|
98
98
|
self[key]
|
99
99
|
elsif default.empty? and !block_given?
|
100
|
-
raise KeyError
|
100
|
+
raise KeyError, "key not found \"#{key}\""
|
101
101
|
else
|
102
102
|
(yield(self) if block_given?) || default.first
|
103
103
|
end
|
@@ -26,7 +26,7 @@ module Blacklight::Document::DublinCore
|
|
26
26
|
'xmlns:oai_dc' => "http://www.openarchives.org/OAI/2.0/oai_dc/",
|
27
27
|
'xmlns:dc' => "http://purl.org/dc/elements/1.1/",
|
28
28
|
'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
|
29
|
-
'xsi:schemaLocation' => %
|
29
|
+
'xsi:schemaLocation' => %(http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd)) do
|
30
30
|
self.to_semantic_values.select { |field, values| dublin_core_field_name? field }.each do |field,values|
|
31
31
|
Array.wrap(values).each do |v|
|
32
32
|
xml.tag! "dc:#{field}", v
|
@@ -6,7 +6,7 @@
|
|
6
6
|
# extension can be registered with your document class, along with a block
|
7
7
|
# containing custom logic for which documents to apply the extension to.
|
8
8
|
#
|
9
|
-
# SolrDocument.use_extension(MyExtension) {|document| my_logic_on_document(document}
|
9
|
+
# SolrDocument.use_extension(MyExtension) { |document| my_logic_on_document(document) }
|
10
10
|
#
|
11
11
|
# MyExtension will be mixed-in (using ruby 'extend') only to those documents
|
12
12
|
# where the block results in true.
|