bootstrap3_helper 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/MIT-LICENSE +20 -0
- data/README.md +149 -0
- data/Rakefile +34 -0
- data/lib/bootstrap3_helper/accordion.rb +174 -0
- data/lib/bootstrap3_helper/accordion_group.rb +88 -0
- data/lib/bootstrap3_helper/alert.rb +88 -0
- data/lib/bootstrap3_helper/callout.rb +55 -0
- data/lib/bootstrap3_helper/component.rb +93 -0
- data/lib/bootstrap3_helper/panel.rb +107 -0
- data/lib/bootstrap3_helper/railtie.rb +10 -0
- data/lib/bootstrap3_helper/tabs/content.rb +67 -0
- data/lib/bootstrap3_helper/tabs/dropdown.rb +77 -0
- data/lib/bootstrap3_helper/tabs/menu.rb +101 -0
- data/lib/bootstrap3_helper/tabs.rb +103 -0
- data/lib/bootstrap3_helper/version.rb +3 -0
- data/lib/bootstrap3_helper.rb +219 -0
- data/lib/tasks/bootstrap3_helper_tasks.rake +4 -0
- metadata +145 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
# @root
|
2
|
+
#
|
3
|
+
#
|
4
|
+
module Bootstrap3Helper
|
5
|
+
# @description
|
6
|
+
# - This super class is meant to contain commonly used methods that
|
7
|
+
# all sub classes can leverage.
|
8
|
+
#
|
9
|
+
# @note
|
10
|
+
# - Every component that inherits from this class, needs to call the parent
|
11
|
+
# initialization method! In order to properly render erb blocks within the
|
12
|
+
# proper context, we need the template. The only way to get this, is to pass
|
13
|
+
# in the template.
|
14
|
+
#
|
15
|
+
# @note
|
16
|
+
# - the `context` mentioned above, refers to the context of `@template` and
|
17
|
+
# not to be confused with `@context` that can be found in the sub classes.
|
18
|
+
# `@context` refers to the Bootstrap class context of the component.
|
19
|
+
#
|
20
|
+
class Component
|
21
|
+
# @description
|
22
|
+
# - Used to ensure that the helpers always have the propert context for
|
23
|
+
# rendering and bindings.
|
24
|
+
#
|
25
|
+
# @param [Class] template - the context of the bindings
|
26
|
+
#
|
27
|
+
def initialize(template)
|
28
|
+
@template = template
|
29
|
+
end
|
30
|
+
|
31
|
+
# @description
|
32
|
+
# - Used to pass all context of content_tag to the template. This ensures
|
33
|
+
# proper template binding of variables and methods!
|
34
|
+
#
|
35
|
+
# @return [String]
|
36
|
+
#
|
37
|
+
def content_tag(
|
38
|
+
name,
|
39
|
+
content_or_options_with_block = nil,
|
40
|
+
options = nil,
|
41
|
+
escape = true,
|
42
|
+
&block
|
43
|
+
)
|
44
|
+
@template.content_tag(
|
45
|
+
name,
|
46
|
+
content_or_options_with_block,
|
47
|
+
options,
|
48
|
+
escape,
|
49
|
+
&block
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
# @description
|
54
|
+
# - Used to pass all concat references to the template. This ensures proper
|
55
|
+
# binding. Concat adds a String to the template Output buffer. Useful when
|
56
|
+
# trying to add a String with no block.
|
57
|
+
#
|
58
|
+
# @params [String] text
|
59
|
+
#
|
60
|
+
def concat(text)
|
61
|
+
@template.concat(text)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @description
|
65
|
+
# - Used to parse method arguments. If the first argument is
|
66
|
+
# a Hash, then it is assumed that the user left off the bootstrap
|
67
|
+
# contectual class. So we will assign it to `default` and
|
68
|
+
# return the Hash to be used as options.
|
69
|
+
#
|
70
|
+
# @params [Hash|NilClass|String|Symbol] *args
|
71
|
+
# @return [Array]
|
72
|
+
#
|
73
|
+
def parse_arguments(*args)
|
74
|
+
first, second = *args
|
75
|
+
case first
|
76
|
+
when Hash, NilClass
|
77
|
+
['default', first || second]
|
78
|
+
when Symbol, String
|
79
|
+
[first, second]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# @description
|
84
|
+
# - Used to generate a (hopefully) unique ID for DOM elements. Used as a
|
85
|
+
# fallback if the user doesn't specify one.
|
86
|
+
#
|
87
|
+
# @return [String]
|
88
|
+
#
|
89
|
+
def uuid
|
90
|
+
(0...10).map { rand(65..90).chr }.join
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# @root
|
2
|
+
#
|
3
|
+
#
|
4
|
+
module Bootstrap3Helper
|
5
|
+
# @description
|
6
|
+
# - Used to rapidly build Bootstrap Panel Components.
|
7
|
+
#
|
8
|
+
# <code>
|
9
|
+
# <%= panel_helper class: 'panel-primary' do |p| %>
|
10
|
+
# <%= p.header { "Some Title" }
|
11
|
+
# <%= p.body class: 'custom-class', id: 'custom-id' do %>
|
12
|
+
# //HTML or Ruby code here...
|
13
|
+
# <% end %>
|
14
|
+
# <%= p.footer do %>
|
15
|
+
# //HTML or Ruby
|
16
|
+
# <% end %>
|
17
|
+
# <% end %>
|
18
|
+
# </code>
|
19
|
+
#
|
20
|
+
class Panel < Component
|
21
|
+
# @description
|
22
|
+
# - Creates a new Panel object.
|
23
|
+
#
|
24
|
+
# @param [Class] template - Template in which your are binding too.
|
25
|
+
# @param [NilClass|String|Symbol|Hash] - Bootstrap class context, or options hash.
|
26
|
+
# @param [Hash] opts
|
27
|
+
# <code>
|
28
|
+
# opts = {
|
29
|
+
# id: [String|NilClass] - The ID, if you want one, for the element.
|
30
|
+
# class: [String|NilClass] - Custom class for the element.
|
31
|
+
# }
|
32
|
+
# </code>
|
33
|
+
# @return [Panel]
|
34
|
+
#
|
35
|
+
def initialize(template, context_or_options = nil, opts = {})
|
36
|
+
super(template)
|
37
|
+
@context, args = parse_arguments(context_or_options, opts)
|
38
|
+
|
39
|
+
@id = args.fetch(:id, '')
|
40
|
+
@class = args.fetch(:class, '')
|
41
|
+
@data = args.fetch(:data, nil)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @description
|
45
|
+
# - Used to generate the header component for the panel.
|
46
|
+
#
|
47
|
+
# @param [Hash] args
|
48
|
+
#
|
49
|
+
def header(args = {})
|
50
|
+
id = args.fetch(:id, '')
|
51
|
+
klass = args.fetch(:class, '')
|
52
|
+
@header = content_tag(:div, id: id, class: 'panel-heading ' + klass) do
|
53
|
+
content_tag(:h3, class: 'panel-title') { yield if block_given? }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# @description
|
58
|
+
# - Used to generate the body component for the panel.
|
59
|
+
#
|
60
|
+
# @param [Hash] args
|
61
|
+
#
|
62
|
+
def body(args = {})
|
63
|
+
id = args.fetch(:id, '')
|
64
|
+
klass = args.fetch(:class, '')
|
65
|
+
@body = content_tag(:div, id: id, class: 'panel-body ' + klass) do
|
66
|
+
yield if block_given?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# @description
|
71
|
+
# - Used to generate the footer component for the panel.
|
72
|
+
#
|
73
|
+
# @param [Hash] args
|
74
|
+
#
|
75
|
+
def footer(args = {})
|
76
|
+
id = args.fetch(:id, '')
|
77
|
+
klass = args.fetch(:class, '')
|
78
|
+
@footer = content_tag(:div, id: id, class: 'panel-footer ' + klass) do
|
79
|
+
yield if block_given?
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# @description
|
84
|
+
# - Used to render the html for the entire panel object.
|
85
|
+
#
|
86
|
+
# @return [String]
|
87
|
+
#
|
88
|
+
def to_s
|
89
|
+
content = content_tag :div, id: @id, class: container_classes, data: @data do
|
90
|
+
@header + @body + @footer
|
91
|
+
end
|
92
|
+
|
93
|
+
content
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
# @description
|
99
|
+
# - Used to get the container css classes.
|
100
|
+
#
|
101
|
+
# @return [String]
|
102
|
+
#
|
103
|
+
def container_classes
|
104
|
+
"panel panel-#{@context} #{@class}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# @description
|
2
|
+
# - Root Object
|
3
|
+
#
|
4
|
+
module Bootstrap3Helper
|
5
|
+
class Tabs
|
6
|
+
# @description
|
7
|
+
# - Used to rapidly generated Bootstrap Tabs Content Components.
|
8
|
+
#
|
9
|
+
class Content < Component
|
10
|
+
# @description
|
11
|
+
# - Creates a new Tabs::Menu object.
|
12
|
+
#
|
13
|
+
# @param [Class] template - Template in which your are binding too.
|
14
|
+
# @param [Hash] args
|
15
|
+
# <code>
|
16
|
+
# args = {
|
17
|
+
# id: [String|nilClass] - The ID, if you want one, for the parent container
|
18
|
+
# class: [String|nilClass] - Custom class for the parent container
|
19
|
+
# }
|
20
|
+
# </code>
|
21
|
+
#
|
22
|
+
def initialize(template, args = {})
|
23
|
+
super(template)
|
24
|
+
|
25
|
+
@id = args.fetch(:id, nil)
|
26
|
+
@class = args.fetch(:class, '')
|
27
|
+
@items = []
|
28
|
+
end
|
29
|
+
|
30
|
+
# @description
|
31
|
+
# - Adds a new tabe-pane item to the object.
|
32
|
+
#
|
33
|
+
# @param [String|Symbol] name - Used to link to the nav menu item.
|
34
|
+
# @param [Hash] args
|
35
|
+
# <code>
|
36
|
+
# args = {
|
37
|
+
# class: [String|nilClass] - Custom class for the div element
|
38
|
+
# data: [Hash] - Any data attributes you wish to assign to div element.
|
39
|
+
# }
|
40
|
+
# </code>
|
41
|
+
#
|
42
|
+
def item(name, args = {})
|
43
|
+
data = args.fetch(:data, nil)
|
44
|
+
klass = args.fetch(:class, '')
|
45
|
+
|
46
|
+
content = content_tag :div, id: name, class: 'tab-pane ' + klass, data: data, role: 'tabpanel' do
|
47
|
+
yield if block_given?
|
48
|
+
end
|
49
|
+
|
50
|
+
@items.push(content)
|
51
|
+
end
|
52
|
+
|
53
|
+
# @description
|
54
|
+
# - Used to render out the object as HTML
|
55
|
+
#
|
56
|
+
# @return [String]
|
57
|
+
#
|
58
|
+
def to_s
|
59
|
+
html = content_tag :div, id: @id, class: 'tab-content' + @class do
|
60
|
+
@items.collect(&:to_s).join.html_safe
|
61
|
+
end
|
62
|
+
|
63
|
+
html
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# @description
|
2
|
+
# - Root Object
|
3
|
+
#
|
4
|
+
module Bootstrap3Helper
|
5
|
+
class Tabs
|
6
|
+
# @description
|
7
|
+
# - Used to rapidly build dropdown menus for Bootstrap tabs.
|
8
|
+
#
|
9
|
+
# <code>
|
10
|
+
# <% menu.dropdown 'Testing Dropdown' do |dropdown| %>
|
11
|
+
# <%= dropdown.item(:testing5 ) { 'Testing 5' } %>
|
12
|
+
# <%= dropdown.item(:testing6 ) { 'Testing 6' } %>
|
13
|
+
# <%= dropdown.item(:testing7 ) { 'Testing 7' } %>
|
14
|
+
# <% end %>
|
15
|
+
# </code>
|
16
|
+
#
|
17
|
+
class Dropdown < Component
|
18
|
+
# @description
|
19
|
+
# - Creates a new Tabs::Dropdown object.
|
20
|
+
#
|
21
|
+
# @param [Class] template - Template in which your are binding too.
|
22
|
+
#
|
23
|
+
def initialize(template, name = '')
|
24
|
+
super(template)
|
25
|
+
|
26
|
+
@name = name
|
27
|
+
@items = []
|
28
|
+
end
|
29
|
+
|
30
|
+
# @description
|
31
|
+
# - Adds a new item to the dropdown object.
|
32
|
+
#
|
33
|
+
# @note
|
34
|
+
# - You can opt out of passing in a block and the li will use the name attribute
|
35
|
+
# for the menu item.
|
36
|
+
#
|
37
|
+
# @param [String|Symbol] name - Used to link nav li to tab-content
|
38
|
+
# @param [Hash] args
|
39
|
+
# <code>
|
40
|
+
# args = {
|
41
|
+
# id: [String|Symbol] - Custom ID for li element.
|
42
|
+
# class: [String|nilClass] - Custom class for the li element
|
43
|
+
# data: [Hash] - Any data attributes you wish to assign to li element.
|
44
|
+
# }
|
45
|
+
# </code>
|
46
|
+
#
|
47
|
+
def item(name, args = {})
|
48
|
+
id = args.fetch(:id, nil)
|
49
|
+
klass = args.fetch(:class, '')
|
50
|
+
data = args.fetch(:data, nil)
|
51
|
+
|
52
|
+
li = content_tag :li, id: id, class: klass, data: data do
|
53
|
+
content_tag :a, href: "##{name}", role: 'tab', data: { toggle: 'tab' }, aria: { controls: name, expanded: false } do
|
54
|
+
block_given? ? yield : name.to_s.titleize
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
@items.push(li)
|
59
|
+
end
|
60
|
+
|
61
|
+
# @description
|
62
|
+
# - Used to render out the object and get the HTML representation.
|
63
|
+
#
|
64
|
+
# @return [String]
|
65
|
+
#
|
66
|
+
def to_s
|
67
|
+
content = content_tag :a, @name, href: '#', class: 'dropdown-toggle', data: { toggle: 'dropdown' }, aria: { expanded: false }
|
68
|
+
|
69
|
+
content += content_tag :ul, id: @id, class: 'dropdown-menu ' do
|
70
|
+
@items.collect(&:to_s).join.html_safe
|
71
|
+
end
|
72
|
+
|
73
|
+
content
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# @description
|
2
|
+
# - Root Object
|
3
|
+
#
|
4
|
+
module Bootstrap3Helper
|
5
|
+
class Tabs
|
6
|
+
# @description
|
7
|
+
# - Used to rapidly generated Bootstrap Tabs Menu Components.
|
8
|
+
#
|
9
|
+
# <code>
|
10
|
+
# <% menu.item(:testing3) { ' Testing 3' } %>
|
11
|
+
# </code>
|
12
|
+
#
|
13
|
+
class Menu < Component
|
14
|
+
# @description
|
15
|
+
# - Creates a new Tabs::Menu object.
|
16
|
+
#
|
17
|
+
# @param [Class] template - Template in which your are binding too.
|
18
|
+
# @param [Hash] args
|
19
|
+
# <code>
|
20
|
+
# args = {
|
21
|
+
# type: [String|Symbol] - Used to tell the helper which tab version - :tabs|:pills
|
22
|
+
# id: [String|nilClass] - The ID, if you want one, for the parent container
|
23
|
+
# class: [String|nilClass] - Custom class for the parent container
|
24
|
+
# }
|
25
|
+
# </code>
|
26
|
+
#
|
27
|
+
def initialize(template, args = {})
|
28
|
+
super(template)
|
29
|
+
|
30
|
+
@id = args.fetch(:id, nil)
|
31
|
+
@class = args.fetch(:class, '')
|
32
|
+
@type = args.fetch(:type, :tabs)
|
33
|
+
@items = []
|
34
|
+
end
|
35
|
+
|
36
|
+
# @description
|
37
|
+
# - Adds a new menu item to the object.
|
38
|
+
#
|
39
|
+
# @note
|
40
|
+
# - You can opt out of passing in a block and the li will use the name attribute
|
41
|
+
# for the menu item.
|
42
|
+
#
|
43
|
+
# @param [String|Symbol] name - Used to link nav li to tab-content
|
44
|
+
# @param [Hash] args
|
45
|
+
# <code>
|
46
|
+
# args = {
|
47
|
+
# id: [String|Symbol] - Custom ID for li element.
|
48
|
+
# class: [String|nilClass] - Custom class for the li element
|
49
|
+
# data: [Hash] - Any data attributes you wish to assign to li element.
|
50
|
+
# }
|
51
|
+
# </code>
|
52
|
+
#
|
53
|
+
def item(name, args = {})
|
54
|
+
id = args.fetch(:id, nil)
|
55
|
+
data = args.fetch(:data, nil)
|
56
|
+
klass = args.fetch(:class, '')
|
57
|
+
|
58
|
+
li = content_tag :li, id: id, class: klass, data: data, role: 'presentation' do
|
59
|
+
content_tag :a, href: "##{name}", data: { toggle: 'tab' }, aria: { controls: '' } do
|
60
|
+
block_given? ? yield : name.to_s.titleize
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
@items.push(li)
|
65
|
+
end
|
66
|
+
|
67
|
+
# @description
|
68
|
+
# - Used to create menu items that are Dropdowns
|
69
|
+
#
|
70
|
+
# @param [String|Symbol] name -
|
71
|
+
#
|
72
|
+
def dropdown(name, args = {})
|
73
|
+
id = args.fetch(:id, nil)
|
74
|
+
data = args.fetch(:data, nil)
|
75
|
+
klass = args.fetch(:class, '')
|
76
|
+
|
77
|
+
dropdown = Tabs::Dropdown.new(@template, name)
|
78
|
+
yield dropdown if block_given?
|
79
|
+
|
80
|
+
content = content_tag :li, id: id, class: 'dropdown' + klass, data: data do
|
81
|
+
dropdown.to_s
|
82
|
+
end
|
83
|
+
|
84
|
+
@items.push(content)
|
85
|
+
end
|
86
|
+
|
87
|
+
# @description
|
88
|
+
# - Used to render out the contents of the menu.
|
89
|
+
#
|
90
|
+
# @return [String]
|
91
|
+
#
|
92
|
+
def to_s
|
93
|
+
html = content_tag :ul, id: @id, class: "nav nav-#{@type} " + @class, role: 'tablist' do
|
94
|
+
@items.collect(&:to_s).join.html_safe
|
95
|
+
end
|
96
|
+
|
97
|
+
html
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# @root
|
2
|
+
#
|
3
|
+
#
|
4
|
+
module Bootstrap3Helper
|
5
|
+
# @description
|
6
|
+
# - Used to rapidly generated Bootstrap Tabs Components.
|
7
|
+
#
|
8
|
+
# @note
|
9
|
+
# - On menu items - you can pass in either symbol or string for the link. If
|
10
|
+
# you pass in a block, it will use the block for the title of the li. If no
|
11
|
+
# block is present, then it will titleize the symbol or string.
|
12
|
+
#
|
13
|
+
# Tabs::Menu will respond to <code>item</code> and <code>dropdown</code>
|
14
|
+
# Each method will yield the corresponding component, either a Tabs::Menu
|
15
|
+
# or a Tabs::Dropdown.
|
16
|
+
#
|
17
|
+
# <code>
|
18
|
+
# <%= tabs_helper type: :pills do |menu, content| %>
|
19
|
+
# <% menu.item(:testing1, class: 'active') { ' Testing 1' } %>
|
20
|
+
# <% menu.item :testing2 %>
|
21
|
+
# <% menu.item(:testing3) { ' Testing 3' } %>
|
22
|
+
# <% menu.dropdown 'Testing Dropdown' do |dropdown| %>
|
23
|
+
# <%= dropdown.item(:testing5 ) { 'Testing 5' } %>
|
24
|
+
# <%= dropdown.item(:testing6 ) { 'Testing 6' } %>
|
25
|
+
# <%= dropdown.item(:testing7 ) { 'Testing 7' } %>
|
26
|
+
# <% end %>
|
27
|
+
#
|
28
|
+
# <% content.item :testing1, class: 'active' do %>
|
29
|
+
# Testing 1 content
|
30
|
+
# <% end %>
|
31
|
+
# <% content.item :testing2 do %>
|
32
|
+
# Testing 2 content
|
33
|
+
# <% end %>
|
34
|
+
# <% content.item :testing3 do %>
|
35
|
+
# Testing 3 content
|
36
|
+
# <% end %>
|
37
|
+
# <% content.item :testing5 do %>
|
38
|
+
# Testing 5 content
|
39
|
+
# <% end %>
|
40
|
+
# <% content.item :testing6 do %>
|
41
|
+
# Testing 6 content
|
42
|
+
# <% end %>
|
43
|
+
# <% content.item :testing7 do %>
|
44
|
+
# Testing 7 content
|
45
|
+
# <% end %>
|
46
|
+
# <% end %>
|
47
|
+
# </code>
|
48
|
+
class Tabs < Component
|
49
|
+
# @description
|
50
|
+
# - Creates a new Tabs object.
|
51
|
+
#
|
52
|
+
# @param [Class] template - Template in which your are binding too.
|
53
|
+
# @param [Hash] args
|
54
|
+
# <code>
|
55
|
+
# args = {
|
56
|
+
# type: [String|Symbol] - Used to tell the helper which tab version - :tabs|:pills
|
57
|
+
# id: [String|nilClass] - The ID, if you want one, for the parent container
|
58
|
+
# class: [String|nilClass] - Custom class for the parent container
|
59
|
+
# }
|
60
|
+
# </code>
|
61
|
+
#
|
62
|
+
def initialize(template, args = {})
|
63
|
+
super(template)
|
64
|
+
@type = args.fetch(:type, :tabs)
|
65
|
+
@id = args.fetch(:id, nil)
|
66
|
+
@class = args.fetch(:class, '')
|
67
|
+
|
68
|
+
@tab_menu = Tabs::Menu.new(@template, type: @type)
|
69
|
+
@tab_content = Tabs::Content.new(@template)
|
70
|
+
end
|
71
|
+
|
72
|
+
# @description
|
73
|
+
# - Allows you access the Tabs::Menu object.
|
74
|
+
#
|
75
|
+
# @return [Tabs::Menu]
|
76
|
+
#
|
77
|
+
def menu
|
78
|
+
@tab_menu
|
79
|
+
end
|
80
|
+
|
81
|
+
# @description
|
82
|
+
# - Allows you to access the Tabs::Content object
|
83
|
+
#
|
84
|
+
# @return [Tabs::Content]
|
85
|
+
#
|
86
|
+
def content
|
87
|
+
@tab_content
|
88
|
+
end
|
89
|
+
|
90
|
+
# @description
|
91
|
+
# - Used to render out the HTML of the Tabs Object
|
92
|
+
#
|
93
|
+
# @return [String]
|
94
|
+
#
|
95
|
+
def to_s
|
96
|
+
html = content_tag :div, id: @id, class: @class do
|
97
|
+
menu.to_s + content.to_s
|
98
|
+
end
|
99
|
+
|
100
|
+
html
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|