seamess 0.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.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +166 -0
  4. data/Rakefile +24 -0
  5. data/app/assets/config/seamess_manifest.js +2 -0
  6. data/app/assets/javascripts/seamess/application.js +13 -0
  7. data/app/assets/javascripts/seamess/manager.js +6 -0
  8. data/app/assets/stylesheets/seamess/manager.sass +2 -0
  9. data/app/assets/stylesheets/seamess/partials/footer.sass +7 -0
  10. data/app/assets/stylesheets/seamess/partials/layouts.sass +19 -0
  11. data/app/assets/stylesheets/seamess/partials/manager.sass +48 -0
  12. data/app/assets/stylesheets/seamess/partials/masthead.sass +27 -0
  13. data/app/assets/stylesheets/seamess/partials/shared.sass +5 -0
  14. data/app/assets/stylesheets/seamess/partials/variables.sass +2 -0
  15. data/app/assets/stylesheets/seamess/seamess.sass +1 -0
  16. data/app/controllers/seamess/application_controller.rb +5 -0
  17. data/app/controllers/seamess/manager/base_controller.rb +5 -0
  18. data/app/controllers/seamess/manager/dashboard_controller.rb +4 -0
  19. data/app/controllers/seamess/manager/pages_controller.rb +52 -0
  20. data/app/controllers/seamess/pages_controller.rb +10 -0
  21. data/app/helpers/seamess/application_helper.rb +4 -0
  22. data/app/jobs/seamess/application_job.rb +4 -0
  23. data/app/mailers/seamess/application_mailer.rb +6 -0
  24. data/app/models/seamess/application_record.rb +5 -0
  25. data/app/models/seamess/page.rb +16 -0
  26. data/app/views/layouts/seamess/application.html.haml +16 -0
  27. data/app/views/layouts/seamess/columnar.html.haml +3 -0
  28. data/app/views/layouts/seamess/fluid.html.haml +3 -0
  29. data/app/views/layouts/seamess/manager.html.haml +19 -0
  30. data/app/views/layouts/seamess/pages.html.haml +5 -0
  31. data/app/views/seamess/common/_after_head.html.haml +3 -0
  32. data/app/views/seamess/common/_after_yield.html.haml +7 -0
  33. data/app/views/seamess/common/_before_yield.html.haml +5 -0
  34. data/app/views/seamess/common/_callouts.html.haml +1 -0
  35. data/app/views/seamess/common/_drip.html.haml +13 -0
  36. data/app/views/seamess/common/_facebook_pixel.html.haml +13 -0
  37. data/app/views/seamess/common/_footer.html.haml +1 -0
  38. data/app/views/seamess/common/_google_analytics.html.haml +10 -0
  39. data/app/views/seamess/common/_head.html.haml +12 -0
  40. data/app/views/seamess/common/_javascripts.html.haml +3 -0
  41. data/app/views/seamess/common/_manager_sidebar.html.haml +13 -0
  42. data/app/views/seamess/common/_navbar.html.haml +18 -0
  43. data/app/views/seamess/manager/dashboard/dashboard.html.haml +1 -0
  44. data/app/views/seamess/manager/pages/_form.html.haml +8 -0
  45. data/app/views/seamess/manager/pages/edit.html.haml +4 -0
  46. data/app/views/seamess/manager/pages/index.html.haml +21 -0
  47. data/app/views/seamess/manager/pages/new.html.haml +3 -0
  48. data/app/views/seamess/pages/show.html.haml +2 -0
  49. data/app/views/seamess/pages/styles.html.haml +50 -0
  50. data/config/initializers/simple_form.rb +209 -0
  51. data/config/routes.rb +14 -0
  52. data/db/migrate/20170827174002_create_seamess_pages.rb +10 -0
  53. data/db/migrate/20170829085602_change_seamess_pages_slug_to_nullable.rb +9 -0
  54. data/db/seeds.rb +25 -0
  55. data/lib/seamess.rb +14 -0
  56. data/lib/seamess/engine.rb +9 -0
  57. data/lib/seamess/version.rb +3 -0
  58. data/lib/tasks/seamess_tasks.rake +4 -0
  59. metadata +269 -0
@@ -0,0 +1,10 @@
1
+ class Seamess::PagesController < ApplicationController
2
+ layout "seamess/pages"
3
+
4
+ def show
5
+ @page = Seamess::Page.for_slug_or_404(params[:slug] || "")
6
+ end
7
+
8
+ def styles
9
+ end
10
+ end
@@ -0,0 +1,4 @@
1
+ module Seamess
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Seamess
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Seamess
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Seamess
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ class Seamess::Page < ApplicationRecord
2
+ validates :title, presence: true
3
+ validates :slug, uniqueness: true, format: { with: /\A(?!\/)/, message: "must not begin with a slash" }
4
+
5
+ scope :for_manager_index, -> { order(slug: :asc) }
6
+
7
+ class << self
8
+ def for_slug_or_404(slug)
9
+ for_slug(slug) || for_slug('404')
10
+ end
11
+
12
+ def for_slug(slug)
13
+ find_by(slug: slug)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ !!! 5
2
+ %html{lang: :en}
3
+ %head= render partial: "seamess/common/head"
4
+
5
+ = area :after_head do
6
+ = render partial: "seamess/common/after_head"
7
+
8
+ %body{class: "#{area :body_classes, "application"}" }
9
+ = area :before_yield do
10
+ = render partial: "seamess/common/before_yield"
11
+
12
+ %main{role: "main"}= yield
13
+
14
+ = area :after_yield do
15
+ = render partial: "seamess/common/after_yield"
16
+
@@ -0,0 +1,3 @@
1
+ = extends :application do
2
+ = replace :body_classes, "columnar"
3
+ = yield
@@ -0,0 +1,3 @@
1
+ = extends :application do
2
+ = replace :body_classes, "fluid"
3
+ = yield
@@ -0,0 +1,19 @@
1
+ = extends :'layouts/seamess/fluid' do
2
+ = append :body_classes, " admin"
3
+
4
+ = replace :stylesheets do
5
+ = stylesheet_link_tag 'manager', media: 'all'
6
+
7
+ = replace :before_yield do
8
+ = render partial: "seamess/common/navbar"
9
+
10
+ .sidebar-container
11
+ = area :sidebar do
12
+ = render partial: "seamess/common/manager_sidebar"
13
+
14
+ .content
15
+ = render partial: "seamess/common/callouts"
16
+ = yield
17
+
18
+ = replace :after_yield do
19
+ = javascript_include_tag :'seamess/manager'
@@ -0,0 +1,5 @@
1
+ = extends :'layouts/seamess/columnar' do
2
+ = append :body_classes, " pages"
3
+
4
+ .content
5
+ .text= yield
@@ -0,0 +1,3 @@
1
+ - if Rails.env.production? && ENV.fetch('FACEBOOK_PIXEL_ID', nil)
2
+ :javascript
3
+ fbq('track', 'ViewContent')
@@ -0,0 +1,7 @@
1
+ = area :before_footer
2
+
3
+ = area :footer do
4
+ %footer= render partial: "seamess/common/footer"
5
+
6
+ = area :after_footer do
7
+ = render partial: "seamess/common/javascripts"
@@ -0,0 +1,5 @@
1
+ = area :navbar do
2
+ = render partial: "seamess/common/navbar"
3
+
4
+ = area :callouts do
5
+ = render partial: "seamess/common/callouts"
@@ -0,0 +1 @@
1
+ = flash_messages
@@ -0,0 +1,13 @@
1
+ - if Rails.env.production? && (key = ENV.fetch('DRIP_ACCOUNT_KEY', nil))
2
+ :javascript
3
+ var _dcq = _dcq || [];
4
+ var _dcs = _dcs || {};
5
+ _dcs.account = '#{key}';
6
+
7
+ (function() {
8
+ var dc = document.createElement('script');
9
+ dc.type = 'text/javascript'; dc.async = true;
10
+ dc.src = '//tag.getdrip.com/#{key}.js';
11
+ var s = document.getElementsByTagName('script')[0];
12
+ s.parentNode.insertBefore(dc, s);
13
+ })();
@@ -0,0 +1,13 @@
1
+ - if Rails.env.production? && (pixel_id = ENV.fetch('FACEBOOK_PIXEL_ID', nil))
2
+ :javascript
3
+ !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
4
+ n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
5
+ n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
6
+ t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
7
+ document,'script','https://connect.facebook.net/en_US/fbevents.js');
8
+
9
+ fbq('init', '#{pixel_id}');
10
+ fbq('track', 'PageView');
11
+
12
+ %noscript
13
+ %img(height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=#{pixel_id}&ev=PageView&noscript=1")
@@ -0,0 +1 @@
1
+ &copy; #{Time.now.year} #{ENV.fetch('COPYRIGHT')}. All rights reserved.
@@ -0,0 +1,10 @@
1
+ - if Rails.env.production? && (key = ENV.fetch('GOOGLE_ANALYTICS_KEY', nil))
2
+ :javascript
3
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
4
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
5
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
6
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
7
+
8
+ ga('create', '#{key}', 'auto');
9
+ ga('require', 'linkid');
10
+ ga('send', 'pageview');
@@ -0,0 +1,12 @@
1
+ %title= area :title, ENV.fetch('SITE_TITLE')
2
+
3
+ = area :meta do
4
+ = csrf_meta_tags
5
+ %meta(charset="utf-8")
6
+ %meta(name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no")
7
+
8
+ = area :stylesheets do
9
+ = stylesheet_link_tag 'application', media: 'all'
10
+
11
+ = area :bottom_of_head do
12
+ = render partial: "seamess/common/facebook_pixel"
@@ -0,0 +1,3 @@
1
+ = javascript_include_tag :application
2
+ = render partial: "seamess/common/drip"
3
+ = render partial: "seamess/common/google_analytics"
@@ -0,0 +1,13 @@
1
+ %nav
2
+ %ul.nav.nav-pills.flex-column
3
+ %li.nav-item= bootstrap_link_to "Dashboard", seamess.manager_dashboard_path, active: :exclusive
4
+ %li.nav-item
5
+ = bootstrap_link_to "Pages", "javascript:;", data: { toggle: "collapse", target: "#menu-pages-content"}, aria: { expanded: false, controls: "menu-pages-content" }
6
+
7
+ #menu-pages-content.collapse
8
+ %ul.nav.nav-pills.flex-column
9
+ %li.nav-item= bootstrap_link_to "All Pages", seamess.manager_pages_path
10
+ %li.nav-item= bootstrap_link_to "New Page", seamess.new_manager_page_path
11
+
12
+ %li.nav-item= bootstrap_link_to "Sign out [#{current_admin.email}]", main_app.destroy_admin_session_path, method: :delete
13
+
@@ -0,0 +1,18 @@
1
+ %header.masthead
2
+ %nav
3
+ %button.navbar-toggler{ type: :button,
4
+ data: { toggle: :collapse, target: "#navbar-contents" },
5
+ aria: { controls: "navbar-contents", expanded: "false", label: "Toggle navigation" } }
6
+
7
+ %span.navbar-toggler-icon
8
+
9
+ #navbar-contents
10
+ = area :nav_brand do
11
+ = link_to ENV.fetch('SITE_TITLE'), seamess.root_url, class: "navbar-brand"
12
+
13
+ = area :navbar_contents do
14
+ %ul.navbar-nav
15
+ - if admin_signed_in?
16
+ = bootstrap_link_to "Admin", seamess.manager_root_path
17
+ %li.nav-item= bootstrap_link_to "Home", main_app.root_url
18
+
@@ -0,0 +1,8 @@
1
+ = simple_form_for [seamess, :manager, @page] do |f|
2
+ = f.input :slug, hint: "The path at which the post should be found. Should <strong>not</strong> start with <code>/</code>, but can end with it, i.e. <code>my-page/</code>".html_safe
3
+ = f.input :title, hint: "Used internally. If you want the title in the body, include the title in the body."
4
+ = f.input :body, as: :text, hint: "Markdown is accepted.", input_html: { rows: 14 }
5
+
6
+ .actions
7
+ = link_to "Cancel", seamess.manager_pages_path, class: 'btn btn-secondary'
8
+ = f.submit class: 'btn btn-primary'
@@ -0,0 +1,4 @@
1
+ %h1 Editing "#{@page.title}"
2
+
3
+ = render "form"
4
+
@@ -0,0 +1,21 @@
1
+ %h1 All Pages
2
+
3
+ .controls.mb-2
4
+ = link_to "New Page", seamess.new_manager_page_path, class: 'btn btn-primary btn-lg'
5
+
6
+ %table.table.table-striped.table-responsive
7
+ %thead
8
+ %th Slug
9
+ %th Title
10
+ %th Actions
11
+
12
+ %tbody
13
+ - @pages.each do |page|
14
+ %tr
15
+ %td= page.slug
16
+ %td= link_to page.title, seamess.manager_page_path(page)
17
+ %td
18
+ = link_to "Edit", seamess.edit_manager_page_path(page)
19
+ |
20
+ = link_to "Destroy", seamess.manager_page_path(page), method: :destroy, data: {confirm: "Are you sure you wish to delete this page?" }
21
+
@@ -0,0 +1,3 @@
1
+ %h1 New Page
2
+
3
+ = render "form"
@@ -0,0 +1,2 @@
1
+ :markdown
2
+ #{raw @page.body}
@@ -0,0 +1,50 @@
1
+ - %w(alert-success alert-danger alert-warning alert-info).each do |klass|
2
+ .alert.fade.show{class: klass, data: {closable: true}}
3
+ Nyah, see?!
4
+ %button.close{data: { dismiss: 'alert' }} &times;
5
+
6
+
7
+ :markdown
8
+ # Header 1
9
+
10
+ lorem ipsum dolor sit amet [consectutur adipiscing elit](/).
11
+
12
+ -----
13
+
14
+
15
+ ## Header 2
16
+
17
+ lorem ipsum dolor sit amet
18
+
19
+ - thing 1
20
+ - thing 2
21
+ - thing 3
22
+ - thing 4
23
+
24
+ ### Header 3
25
+
26
+ lorem ipsum dolor sit amet
27
+
28
+ 1. thing
29
+ 2. thing
30
+ 3. thing
31
+ 4. thing
32
+
33
+ #### Header 4
34
+
35
+ lorem ipsum dolor sit amet
36
+
37
+ ##### Header 5
38
+
39
+ lorem ipsum dolor sit amet
40
+
41
+ ###### Header 6
42
+
43
+ lorem ipsum dolor sit amet
44
+
45
+
46
+ ## Styles
47
+
48
+ - %w(primary secondary success danger warning info light dark).each do |t|
49
+ %button.btn{class: "btn-#{t}"}= t
50
+
@@ -0,0 +1,209 @@
1
+ require_dependency "simple_form"
2
+
3
+ SimpleForm.setup do |config|
4
+ config.error_notification_class = 'alert alert-danger'
5
+ config.button_class = 'btn btn-primary'
6
+ config.boolean_label_class = nil
7
+
8
+ config.wrappers :vertical_form, tag: 'div', class: 'form-group' do |b|
9
+ b.use :html5
10
+ b.use :placeholder
11
+ b.optional :maxlength
12
+ b.optional :minlength
13
+ b.optional :pattern
14
+ b.optional :min_max
15
+ b.optional :readonly
16
+
17
+ b.use :label, class: 'col-form-label' do
18
+
19
+ end
20
+ b.use :input, class: 'form-control'
21
+ b.use :error, wrap_with: {tag: 'span', class: 'form-control-feedback'}
22
+ b.use :hint, wrap_with: {tag: 'small', class: 'form-text text-muted'}
23
+ end
24
+
25
+ config.wrappers :vertical_file_input, tag: 'div', class: 'form-group' do |b|
26
+ b.use :html5
27
+ b.use :placeholder
28
+ b.optional :maxlength
29
+ b.optional :minlength
30
+ b.optional :readonly
31
+
32
+ b.use :label, class: 'col-form-label'
33
+ b.use :input
34
+ b.use :error, wrap_with: {tag: 'span', class: 'form-control-feedback'}
35
+ b.use :hint, wrap_with: {tag: 'p', class: 'form-text text-muted'}
36
+ end
37
+
38
+ config.wrappers :vertical_boolean, tag: 'div', class: 'form-group' do |b|
39
+ b.use :html5
40
+ b.optional :readonly
41
+
42
+ b.wrapper tag: 'div', class: 'checkbox' do |ba|
43
+ ba.use :label_input
44
+ end
45
+
46
+ b.use :error, wrap_with: {tag: 'span', class: 'form-control-feedback'}
47
+ b.use :hint, wrap_with: {tag: 'p', class: 'form-text text-muted'}
48
+ end
49
+
50
+ config.wrappers :vertical_radio_and_checkboxes, tag: 'div', class: 'form-group' do |b|
51
+ b.use :html5
52
+ b.optional :readonly
53
+
54
+ b.use :label, class: 'col-form-label'
55
+ b.use :input
56
+ b.use :error, wrap_with: {tag: 'span', class: 'form-control-feedback'}
57
+ b.use :hint, wrap_with: {tag: 'p', class: 'form-text text-muted'}
58
+ end
59
+
60
+ config.wrappers :horizontal_form, tag: 'div', class: 'form-group row' do |b|
61
+ b.use :html5
62
+ b.use :placeholder
63
+ b.optional :maxlength
64
+ b.optional :minlength
65
+ b.optional :pattern
66
+ b.optional :min_max
67
+ b.optional :readonly
68
+
69
+ b.use :label, class: 'col-md-3 col-form-label'
70
+ b.wrapper tag: 'div', class: 'col-md-9' do |ba|
71
+ ba.use :input, class: 'form-control'
72
+ ba.use :error, wrap_with: {tag: 'span', class: 'form-control-feedback'}
73
+ ba.use :hint, wrap_with: {tag: 'p', class: 'form-text text-muted'}
74
+ end
75
+ end
76
+
77
+ config.wrappers :horizontal_file_input, tag: 'div', class: 'form-group row' do |b|
78
+ b.use :html5
79
+ b.use :placeholder
80
+ b.optional :maxlength
81
+ b.optional :minlength
82
+ b.optional :readonly
83
+ b.use :label, class: 'col-md-3 col-form-label'
84
+
85
+ b.wrapper tag: 'div', class: 'col-md-9' do |ba|
86
+ ba.use :input
87
+ ba.use :error, wrap_with: {tag: 'span', class: 'form-control-feedback'}
88
+ ba.use :hint, wrap_with: {tag: 'p', class: 'form-text text-muted'}
89
+ end
90
+ end
91
+
92
+ config.wrappers :horizontal_boolean, tag: 'div', class: 'form-group row' do |b|
93
+ b.use :html5
94
+ b.optional :readonly
95
+
96
+ b.wrapper tag: 'div', class: 'offset-md-3 col-md-9' do |wr|
97
+ wr.wrapper tag: 'div', class: '' do |ba|
98
+ ba.use :label_input
99
+ end
100
+
101
+ wr.use :error, wrap_with: {tag: 'span', class: 'form-control-feedback'}
102
+ wr.use :hint, wrap_with: {tag: 'p', class: 'form-text text-muted'}
103
+ end
104
+ end
105
+
106
+ config.wrappers :horizontal_radio_and_checkboxes, tag: 'div', class: 'form-group row' do |b|
107
+ b.use :html5
108
+ b.optional :readonly
109
+
110
+ b.use :label, class: 'col-md-3 col-form-label'
111
+ b.wrapper tag: 'div', class: 'col-md-9' do |ba|
112
+ ba.use :input
113
+ ba.use :error, wrap_with: {tag: 'span', class: 'form-control-feedback'}
114
+ ba.use :hint, wrap_with: {tag: 'p', class: 'form-text text-muted'}
115
+ end
116
+ end
117
+
118
+ config.wrappers :inline_form, tag: 'div', class: 'form-group' do |b|
119
+ b.use :html5
120
+ b.use :placeholder
121
+ b.optional :maxlength
122
+ b.optional :minlength
123
+ b.optional :pattern
124
+ b.optional :min_max
125
+ b.optional :readonly
126
+
127
+ b.use :label, class: 'sr-only'
128
+ b.use :input, class: 'form-control'
129
+ b.use :error, wrap_with: {tag: 'span', class: 'form-control-feedback'}
130
+ b.use :hint, wrap_with: {tag: 'p', class: 'form-text text-muted'}
131
+ end
132
+
133
+ config.wrappers :multi_select, tag: 'div', class: 'form-group' do |b|
134
+ b.use :html5
135
+ b.optional :readonly
136
+
137
+ b.use :label, class: 'col-form-label'
138
+ b.wrapper tag: 'div', class: 'form-inline' do |ba|
139
+ ba.use :input, class: 'form-control'
140
+ ba.use :error, wrap_with: {tag: 'span', class: 'form-control-feedback'}
141
+ ba.use :hint, wrap_with: {tag: 'p', class: 'form-text text-muted'}
142
+ end
143
+ end
144
+
145
+
146
+ config.default_wrapper = :vertical_form
147
+ config.wrapper_mappings = {
148
+ check_boxes: :vertical_radio_and_checkboxes,
149
+ radio_buttons: :vertical_radio_and_checkboxes,
150
+ file: :vertical_file_input,
151
+ boolean: :vertical_boolean,
152
+ datetime: :multi_select,
153
+ date: :multi_select,
154
+ time: :multi_select
155
+ }
156
+ end
157
+
158
+ # SimpleForm::ActionViewExtensions::FormHelper.class_eval do
159
+ #
160
+ # private
161
+ #
162
+ # def simple_form_css_class(record, options)
163
+ # html_options = options[:html]
164
+ # as = options[:as]
165
+ #
166
+ # if html_options.key?(:class)
167
+ # html_options[:class]
168
+ # elsif record.is_a?(String) || record.is_a?(Symbol)
169
+ # as || record
170
+ # else
171
+ # form_css_class_from_record(record, as)
172
+ # end
173
+ # end
174
+ #
175
+ # def form_css_class_from_record(record, as)
176
+ # classes = []
177
+ #
178
+ # record = record.last if record.is_a?(Array)
179
+ # action = record.respond_to?(:persisted?) && record.persisted? ? :edit : :new
180
+ # classes << as ? "#{action}_#{as}" : dom_class(record, action)
181
+ #
182
+ # classes << 'was-validated' if record.errors.any?
183
+ #
184
+ # classes.join(' ')
185
+ # end
186
+ # end
187
+
188
+ SimpleForm::Inputs::Base.class_eval do
189
+ # We just need the ability to pass a block on the `use` function
190
+ # then we save it on the Leaf class to be able to call it
191
+ def merge_wrapper_options(options, wrapper_options)
192
+ if wrapper_options
193
+ wrapper_options.merge(options) do |key, oldval, newval|
194
+ case key.to_s
195
+ when 'class'
196
+ classes = Array(oldval) + Array(newval)
197
+ classes << 'is-invalid' if has_errors?
198
+ classes
199
+ when 'data', 'aria'
200
+ oldval.merge(newval)
201
+ else
202
+ newval
203
+ end
204
+ end
205
+ else
206
+ options
207
+ end
208
+ end
209
+ end