hancock_cms_faq 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +55 -0
- data/Rakefile +1 -0
- data/app/assets/javascripts/hancock/faq.coffee +6 -0
- data/app/assets/javascripts/hancock/faq/form.coffee +9 -0
- data/app/assets/javascripts/hancock/faq/init.coffee +2 -0
- data/app/assets/stylesheets/hancock/faq.sass +0 -0
- data/app/controllers/concerns/hancock/faq/decorators/categories.rb +17 -0
- data/app/controllers/concerns/hancock/faq/decorators/questions.rb +71 -0
- data/app/controllers/hancock/faq/categories_controller.rb +7 -0
- data/app/controllers/hancock/faq/questions_controller.rb +7 -0
- data/app/models/concerns/hancock/faq/decorators/category.rb +36 -0
- data/app/models/concerns/hancock/faq/decorators/question.rb +48 -0
- data/app/models/hancock/faq/category.rb +11 -0
- data/app/models/hancock/faq/question.rb +11 -0
- data/app/views/hancock/faq/categories/index.html.slim +10 -0
- data/app/views/hancock/faq/categories/show.html.slim +8 -0
- data/app/views/hancock/faq/questions/_fields.html.slim +11 -0
- data/app/views/hancock/faq/questions/_fields_with_settings.html.slim +20 -0
- data/app/views/hancock/faq/questions/_form.html.slim +66 -0
- data/app/views/hancock/faq/questions/_form_with_wrapper.html.slim +2 -0
- data/app/views/hancock/faq/questions/_question_block.html.slim +33 -0
- data/app/views/hancock/faq/questions/_simple_captcha.html.slim +16 -0
- data/app/views/hancock/faq/questions/_success.html.slim +3 -0
- data/app/views/hancock/faq/questions/create.html.slim +1 -0
- data/app/views/hancock/faq/questions/index.html.slim +11 -0
- data/app/views/hancock/faq/questions/new.html.slim +6 -0
- data/app/views/hancock/faq/questions/show.html.slim +8 -0
- data/app/views/hancock/faq/questions/update_captcha.html.slim +16 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/config/locales/hancock.faq.ru.yml +64 -0
- data/hancock_cms_faq.gemspec +36 -0
- data/lib/generators/hancock/faq/config/config_generator.rb +13 -0
- data/lib/generators/hancock/faq/config/templates/hancock_faq.erb +23 -0
- data/lib/generators/hancock/faq/controllers/all_generator.rb +28 -0
- data/lib/generators/hancock/faq/controllers/category_generator.rb +43 -0
- data/lib/generators/hancock/faq/controllers/decorators_generator.rb +24 -0
- data/lib/generators/hancock/faq/controllers/question_generator.rb +43 -0
- data/lib/generators/hancock/faq/controllers/templates/categories_controller.erb +10 -0
- data/lib/generators/hancock/faq/controllers/templates/questions_controller.erb +10 -0
- data/lib/generators/hancock/faq/models/all_generator.rb +28 -0
- data/lib/generators/hancock/faq/models/category_generator.rb +43 -0
- data/lib/generators/hancock/faq/models/decorators_generator.rb +24 -0
- data/lib/generators/hancock/faq/models/question_generator.rb +34 -0
- data/lib/generators/hancock/faq/models/templates/category.erb +36 -0
- data/lib/generators/hancock/faq/models/templates/question.erb +37 -0
- data/lib/hancock/faq/admin.rb +6 -0
- data/lib/hancock/faq/admin/category.rb +128 -0
- data/lib/hancock/faq/admin/question.rb +104 -0
- data/lib/hancock/faq/configuration.rb +53 -0
- data/lib/hancock/faq/controllers/categories.rb +88 -0
- data/lib/hancock/faq/controllers/questions.rb +174 -0
- data/lib/hancock/faq/engine.rb +7 -0
- data/lib/hancock/faq/models/category.rb +50 -0
- data/lib/hancock/faq/models/mongoid/category.rb +33 -0
- data/lib/hancock/faq/models/mongoid/question.rb +72 -0
- data/lib/hancock/faq/models/question.rb +85 -0
- data/lib/hancock/faq/routes.rb +83 -0
- data/lib/hancock/faq/version.rb +5 -0
- data/lib/hancock_cms_faq.rb +31 -0
- data/release.sh +6 -0
- metadata +159 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
module Hancock::Faq
|
2
|
+
include Hancock::PluginConfiguration
|
3
|
+
|
4
|
+
def self.config_class
|
5
|
+
Configuration
|
6
|
+
end
|
7
|
+
|
8
|
+
class Configuration
|
9
|
+
attr_accessor :author_name_required
|
10
|
+
|
11
|
+
attr_accessor :default_answer_author_name
|
12
|
+
|
13
|
+
attr_accessor :captcha
|
14
|
+
attr_accessor :captcha_error_message
|
15
|
+
|
16
|
+
attr_accessor :recaptcha_support
|
17
|
+
attr_accessor :simple_captcha_support
|
18
|
+
|
19
|
+
attr_accessor :seo_support
|
20
|
+
attr_accessor :cache_support
|
21
|
+
|
22
|
+
attr_accessor :breadcrumbs_on_rails_support
|
23
|
+
|
24
|
+
attr_accessor :localize
|
25
|
+
|
26
|
+
attr_accessor :model_settings_support
|
27
|
+
attr_accessor :user_abilities_support
|
28
|
+
attr_accessor :ra_comments_support
|
29
|
+
|
30
|
+
def initialize
|
31
|
+
@author_name_required = true
|
32
|
+
|
33
|
+
@default_answer_author_name = "Администрация сайта"
|
34
|
+
|
35
|
+
@captcha_error_message = "Код с картинки введен неверно"
|
36
|
+
|
37
|
+
@recaptcha_support = !!defined?(Recaptcha)
|
38
|
+
@simple_captcha_support = !!defined?(SimpleCaptcha)
|
39
|
+
@captcha = @recaptcha_support || @simple_captcha_support
|
40
|
+
|
41
|
+
@seo_support = !!defined?(Hancock::Seo)
|
42
|
+
@cache_support = !!defined?(Hancock::Cache)
|
43
|
+
|
44
|
+
@breadcrumbs_on_rails_support = !!defined?(BreadcrumbsOnRails)
|
45
|
+
|
46
|
+
@localize = Hancock.config.localize
|
47
|
+
|
48
|
+
@model_settings_support = !!defined?(RailsAdminModelSettings)
|
49
|
+
@user_abilities_support = !!defined?(RailsAdminUserAbilities)
|
50
|
+
@ra_comments_support = !!defined?(RailsAdminComments)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Hancock::Faq
|
2
|
+
module Controllers
|
3
|
+
module Categories
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
|
8
|
+
def index
|
9
|
+
@categories = category_class.enabled.sorted.page(params[:page]).per(per_page)
|
10
|
+
@root_categories = category_class.enabled.roots.sorted.all
|
11
|
+
# index_crumbs
|
12
|
+
end
|
13
|
+
|
14
|
+
def show
|
15
|
+
@category = category_class.enabled.find(params[:id])
|
16
|
+
if !@category.text_slug.blank? and @category.text_slug != params[:id]
|
17
|
+
redirect_to hancock_faq_category_path(@category), status_code: 301
|
18
|
+
return
|
19
|
+
end
|
20
|
+
@seo_parent_page = find_seo_page(hancock_faq_categories_path)
|
21
|
+
|
22
|
+
@children = @category.children.enabled.sorted.all
|
23
|
+
@questions = @category.questions.enabled.sorted.all.page(params[:page]).per(questions_per_page)
|
24
|
+
|
25
|
+
# index_crumbs
|
26
|
+
# category_crumbs
|
27
|
+
end
|
28
|
+
|
29
|
+
def page_title
|
30
|
+
if @category
|
31
|
+
@category.page_title
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def category_class
|
39
|
+
Hancock::Faq::Category
|
40
|
+
end
|
41
|
+
def question_class
|
42
|
+
Hancock::Faq::Question
|
43
|
+
end
|
44
|
+
|
45
|
+
def per_page
|
46
|
+
10
|
47
|
+
end
|
48
|
+
def questions_per_page
|
49
|
+
10
|
50
|
+
end
|
51
|
+
|
52
|
+
# def index_crumbs
|
53
|
+
# if @seo_parent_page
|
54
|
+
# catalog_title = Settings.ns('breadcrumbs').catalog_title(default: "Каталог", label: "'Каталог' в breadcrumbs")
|
55
|
+
# _crumb = catalog_title
|
56
|
+
# _crumb = @seo_parent_page.name if _crumb.blank?
|
57
|
+
# _crumb = @seo_parent_page.title if _crumb.blank?
|
58
|
+
# _crumb = @seo_parent_page.h1 if _crumb.blank?
|
59
|
+
# add_crumb _crumb, @seo_parent_page.fullpath
|
60
|
+
# else
|
61
|
+
# catalog_title = Settings.ns('breadcrumbs').catalog_title(default: "Каталог", label: "'Каталог' в breadcrumbs")
|
62
|
+
# _crumb = catalog_title
|
63
|
+
# add_crumb _crumb, item_categories_path
|
64
|
+
# end
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# def category_crumbs
|
68
|
+
# if @item_category
|
69
|
+
# _parent = @item_category.parent
|
70
|
+
# if _parent
|
71
|
+
# _crumb = _parent.name if _crumb.blank?
|
72
|
+
# _crumb = _parent.title if _crumb.blank?
|
73
|
+
# _crumb = _parent.h1 if _crumb.blank?
|
74
|
+
# add_crumb _crumb, item_category_path(_parent)
|
75
|
+
# _crumb = nil
|
76
|
+
# end
|
77
|
+
# _crumb = @item_category.name if _crumb.blank?
|
78
|
+
# _crumb = @item_category.title if _crumb.blank?
|
79
|
+
# _crumb = @item_category.h1 if _crumb.blank?
|
80
|
+
# add_crumb _crumb, item_category_path(@item_category)
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
module Hancock::Faq
|
2
|
+
module Controllers
|
3
|
+
module Questions
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
|
8
|
+
helper_method :hancock_faq_update_captcha_path
|
9
|
+
|
10
|
+
def index
|
11
|
+
if Hancock::Faq.config.breadcrumbs_on_rails_support
|
12
|
+
add_breadcrumb I18n.t('hancock.breadcrumbs.faq'), :hancock_faq_path
|
13
|
+
end
|
14
|
+
|
15
|
+
@questions = question_class.enabled.sorted.page(params[:page]).per(per_page)
|
16
|
+
# index_crumbs
|
17
|
+
after_initialize
|
18
|
+
render locals: locals unless xhr_checker
|
19
|
+
end
|
20
|
+
|
21
|
+
def show
|
22
|
+
if Hancock::Faq.config.breadcrumbs_on_rails_support
|
23
|
+
add_breadcrumb I18n.t('hancock.breadcrumbs.faq'), :hancock_faq_path
|
24
|
+
end
|
25
|
+
|
26
|
+
@question = question_class.enabled.find(params[:id])
|
27
|
+
if !@question.text_slug.blank? and @question.text_slug != params[:id]
|
28
|
+
redirect_to hancock_faq_question_path(@question), status_code: 301
|
29
|
+
return
|
30
|
+
end
|
31
|
+
@parent_seo_page = find_seo_page(hancock_faq_categories_path) if @seo_page.blank?
|
32
|
+
# item_crumbs
|
33
|
+
end
|
34
|
+
|
35
|
+
def page_title
|
36
|
+
if @question
|
37
|
+
@question.page_title
|
38
|
+
else
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def create
|
44
|
+
@question = question_class.new(question_params)
|
45
|
+
|
46
|
+
if Hancock::Faq.config.captcha
|
47
|
+
if Hancock::Faq.config.recaptcha_support
|
48
|
+
if verify_recaptcha
|
49
|
+
meth = :save
|
50
|
+
else
|
51
|
+
meth = :valid?
|
52
|
+
@recaptcha_error = I18n.t('hancock.errors.faq.recaptcha')
|
53
|
+
end
|
54
|
+
|
55
|
+
elsif Hancock::Faq.config.simple_captcha_support
|
56
|
+
meth = :save_with_captcha
|
57
|
+
|
58
|
+
else
|
59
|
+
meth = :save
|
60
|
+
end
|
61
|
+
else
|
62
|
+
meth = :save
|
63
|
+
end
|
64
|
+
|
65
|
+
if @question.send(meth)
|
66
|
+
after_create
|
67
|
+
if request.xhr? && process_ajax
|
68
|
+
ajax_success
|
69
|
+
else
|
70
|
+
redirect_after_done
|
71
|
+
end
|
72
|
+
else
|
73
|
+
render_faq_error
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def update_captcha
|
78
|
+
render layout: false
|
79
|
+
end
|
80
|
+
|
81
|
+
def hancock_faq_question_update_captcha_path
|
82
|
+
url_for(action: :update_captcha, time: Time.new.to_i, only_path: true)
|
83
|
+
end
|
84
|
+
def is_cache_fields
|
85
|
+
cache_fields?
|
86
|
+
end
|
87
|
+
def cache_fields?
|
88
|
+
['new', 'index'].include? action_name
|
89
|
+
end
|
90
|
+
def cache_key
|
91
|
+
'hancock_faq_question_fields'.freeze
|
92
|
+
end
|
93
|
+
def fields_partial
|
94
|
+
"hancock/faq/questions/#{(Hancock::Faq.config.model_settings_support ? 'fields' : 'fields_with_settings')}".freeze
|
95
|
+
end
|
96
|
+
def settings_scope
|
97
|
+
if Hancock::Faq.config.model_settings_support
|
98
|
+
question_class.settings
|
99
|
+
elsif defined?(Settings)
|
100
|
+
Settings.ns('FAQ')
|
101
|
+
else
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
def recaptcha_options
|
106
|
+
{}
|
107
|
+
end
|
108
|
+
def locals
|
109
|
+
{
|
110
|
+
is_cache_fields: is_cache_fields,
|
111
|
+
cache_key: cache_key,
|
112
|
+
fields_partial: fields_partial,
|
113
|
+
settings_scope: settings_scope,
|
114
|
+
recaptcha_options: recaptcha_options
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
def render_faq_error
|
120
|
+
if request.xhr? && process_ajax
|
121
|
+
render partial: form_partial, status: 422
|
122
|
+
# render json: {errors: @contact_message.errors}, status: 422
|
123
|
+
else
|
124
|
+
flash.now[:alert] = @question.errors.full_messages.join("\n")
|
125
|
+
render action: Hancock::Faq.configuration.recreate_contact_message_action, status: 422
|
126
|
+
end
|
127
|
+
end
|
128
|
+
def process_ajax
|
129
|
+
true
|
130
|
+
end
|
131
|
+
def ajax_success
|
132
|
+
render partial: success_partial
|
133
|
+
# render json: {ok: true}
|
134
|
+
end
|
135
|
+
def redirect_after_done
|
136
|
+
redirect_to action: :sent
|
137
|
+
end
|
138
|
+
def xhr_checker
|
139
|
+
if request.xhr?
|
140
|
+
render layout: false, locals: locals
|
141
|
+
return true
|
142
|
+
end
|
143
|
+
end
|
144
|
+
def after_initialize
|
145
|
+
end
|
146
|
+
def after_create
|
147
|
+
# overrideable hook for updating message
|
148
|
+
end
|
149
|
+
def form_partial
|
150
|
+
"hancock/faq/questions/form"
|
151
|
+
end
|
152
|
+
def success_partial
|
153
|
+
"hancock/faq/questions/success"
|
154
|
+
end
|
155
|
+
def question_params
|
156
|
+
params[:hancock_faq_question].permit(:question_text, :author_name, :author_email, :captcha, :captcha_key)
|
157
|
+
end
|
158
|
+
|
159
|
+
def category_class
|
160
|
+
Hancock::Faq::Category
|
161
|
+
end
|
162
|
+
def question_class
|
163
|
+
Hancock::Faq::Question
|
164
|
+
end
|
165
|
+
|
166
|
+
def per_page
|
167
|
+
10
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Hancock::Faq
|
2
|
+
module Models
|
3
|
+
module Category
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Hancock::Model
|
6
|
+
include Hancock::Enableable
|
7
|
+
|
8
|
+
if Hancock::Faq.config.seo_support
|
9
|
+
include Hancock::Seo::Seoable
|
10
|
+
include Hancock::Seo::SitemapDataField
|
11
|
+
end
|
12
|
+
include ManualSlug
|
13
|
+
|
14
|
+
if Hancock::Pages.config.cache_support
|
15
|
+
include Hancock::Cache::Cacheable
|
16
|
+
end
|
17
|
+
|
18
|
+
include Hancock::Faq.orm_specific('Category')
|
19
|
+
|
20
|
+
included do
|
21
|
+
if Hancock::Feedback.config.model_settings_support
|
22
|
+
include RailsAdminModelSettings::ModelSettingable
|
23
|
+
end
|
24
|
+
|
25
|
+
manual_slug :name
|
26
|
+
|
27
|
+
def self.manager_can_add_actions
|
28
|
+
ret = [:nested_set]
|
29
|
+
ret << :model_settings if Hancock::Faq.config.model_settings_support
|
30
|
+
# ret << :model_accesses if Hancock::Faq.config.user_abilities_support
|
31
|
+
ret << :hancock_touch if Hancock::Faq.config.cache_support
|
32
|
+
ret += [:comments, :model_comments] if Hancock::Faq.config.ra_comments_support
|
33
|
+
ret.freeze
|
34
|
+
end
|
35
|
+
def self.rails_admin_add_visible_actions
|
36
|
+
ret = [:nested_set]
|
37
|
+
ret << :model_settings if Hancock::Faq.config.model_settings_support
|
38
|
+
ret << :model_accesses if Hancock::Faq.config.user_abilities_support
|
39
|
+
ret << :hancock_touch if Hancock::Faq.config.cache_support
|
40
|
+
ret += [:comments, :model_comments] if Hancock::Faq.config.ra_comments_support
|
41
|
+
ret.freeze
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def question_class
|
46
|
+
Hancock::Faq::Question
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Hancock::Faq
|
2
|
+
module Models
|
3
|
+
module Mongoid
|
4
|
+
module Category
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
include Hancock::HtmlField
|
8
|
+
|
9
|
+
included do
|
10
|
+
index({enabled: 1, lft: 1}, {background: true})
|
11
|
+
index({parent_id: 1}, {background: true})
|
12
|
+
|
13
|
+
field :name, type: String, localize: Hancock::Faq.configuration.localize
|
14
|
+
|
15
|
+
acts_as_nested_set
|
16
|
+
scope :sorted, -> { order_by([:lft, :asc]) }
|
17
|
+
|
18
|
+
hancock_cms_html_field :excerpt, type: String, localize: Hancock::Faq.configuration.localize, default: ""
|
19
|
+
hancock_cms_html_field :content, type: String, localize: Hancock::Faq.configuration.localize, default: ""
|
20
|
+
end
|
21
|
+
|
22
|
+
def questions
|
23
|
+
question_class.in(category_ids: self.id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def all_questions
|
27
|
+
question_class.any_in(category_ids: self.and_descendants.map(&:id))
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Hancock::Faq
|
2
|
+
module Models
|
3
|
+
module Mongoid
|
4
|
+
module Question
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
include Hancock::HtmlField
|
8
|
+
|
9
|
+
included do
|
10
|
+
index({main_category_id: 1}, {background: true})
|
11
|
+
index({enabled: 1, lft: 1}, {background: true})
|
12
|
+
index({category_ids: 1}, {background: true})
|
13
|
+
index({answered: 1, answered_time: 1}, {background: true})
|
14
|
+
index({created_at: 1}, {background: true})
|
15
|
+
|
16
|
+
field :question_text
|
17
|
+
hancock_cms_html_field :question_text_after_editing, localize: Hancock::Faq.configuration.localize
|
18
|
+
field :author_name
|
19
|
+
field :author_name_text_after_editing, localize: Hancock::Faq.configuration.localize
|
20
|
+
field :author_email
|
21
|
+
|
22
|
+
field :answered, type: Boolean, default: false
|
23
|
+
hancock_cms_html_field :answer_text, localize: Hancock::Faq.configuration.localize
|
24
|
+
field :answered_time, type: Time
|
25
|
+
field :answer_author_name, default: Hancock::Faq.configuration.default_answer_author_name
|
26
|
+
|
27
|
+
has_and_belongs_to_many :categories, class_name: "Hancock::Faq::Category", inverse_of: nil
|
28
|
+
|
29
|
+
acts_as_nested_set
|
30
|
+
scope :sorted, -> { order_by([:lft, :asc]) }
|
31
|
+
|
32
|
+
scope :after_now, -> { where(:created_at.lt => Time.now) }
|
33
|
+
scope :by_date, -> { desc(:created_at) }
|
34
|
+
scope :by_answered_date, -> { desc(:answered_time) }
|
35
|
+
scope :answered, -> { where(answered: true) }
|
36
|
+
scope :not_answered, -> { where(answered: false) }
|
37
|
+
|
38
|
+
scope :recent, ->(count = 5) { enabled.after_now.by_date.limit(count) }
|
39
|
+
|
40
|
+
|
41
|
+
def category
|
42
|
+
self.categories.enabled.sorted.first
|
43
|
+
end
|
44
|
+
|
45
|
+
def question_text_output
|
46
|
+
self.question_text_after_editing.blank? ? self.question_text : self.question_text_after_editing
|
47
|
+
end
|
48
|
+
|
49
|
+
def author_name_output
|
50
|
+
self.author_name_text_after_editing.blank? ? self.author_name : self.author_name_text_after_editing
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
if Hancock.rails5?
|
55
|
+
if relations.has_key?("updater") and defined?(::Mongoid::History)
|
56
|
+
belongs_to :updater, class_name: ::Mongoid::History.modifier_class_name, optional: true, validate: false
|
57
|
+
_validators.delete(:updater)
|
58
|
+
_validate_callbacks.each do |callback|
|
59
|
+
if callback.raw_filter.respond_to?(:attributes) and callback.raw_filter.attributes.include?(:updater)
|
60
|
+
_validate_callbacks.delete(callback)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|