decidim-forms 0.22.0 → 0.23.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/admin/decidim_forms_manifest.css +3 -0
  3. data/app/assets/config/decidim_forms_manifest.css +1 -0
  4. data/app/assets/javascripts/decidim/forms/admin/auto_select_options_from_url.component.js.es6 +40 -0
  5. data/app/assets/javascripts/decidim/forms/admin/forms.js.es6 +181 -25
  6. data/app/assets/javascripts/decidim/forms/autosortable_checkboxes.component.js.es6 +54 -34
  7. data/app/assets/javascripts/decidim/forms/display_conditions.component.js.es6 +204 -0
  8. data/app/assets/javascripts/decidim/forms/forms.js.es6 +8 -1
  9. data/app/assets/stylesheets/decidim/forms/questionnaire-answers-pdf.scss +69 -0
  10. data/app/commands/decidim/forms/admin/update_questionnaire.rb +25 -1
  11. data/app/commands/decidim/forms/answer_questionnaire.rb +1 -1
  12. data/app/controllers/decidim/forms/admin/concerns/has_questionnaire.rb +47 -1
  13. data/app/controllers/decidim/forms/admin/concerns/has_questionnaire_answers.rb +97 -0
  14. data/app/forms/decidim/forms/admin/display_condition_form.rb +100 -0
  15. data/app/forms/decidim/forms/admin/question_form.rb +1 -0
  16. data/app/forms/decidim/forms/answer_form.rb +15 -0
  17. data/app/helpers/decidim/forms/admin/application_helper.rb +21 -0
  18. data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_pagination_helper.rb +49 -0
  19. data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_url_helper.rb +40 -0
  20. data/app/helpers/decidim/forms/admin/questionnaire_answers_helper.rb +27 -0
  21. data/app/jobs/decidim/forms/export_questionnaire_answers_job.rb +19 -0
  22. data/app/models/decidim/forms/answer.rb +0 -3
  23. data/app/models/decidim/forms/answer_option.rb +14 -0
  24. data/app/models/decidim/forms/display_condition.rb +51 -0
  25. data/app/models/decidim/forms/question.rb +34 -0
  26. data/app/models/decidim/forms/question_matrix_row.rb +3 -0
  27. data/app/models/decidim/forms/questionnaire.rb +11 -1
  28. data/app/presenters/decidim/forms/admin/questionnaire_answer_presenter.rb +43 -0
  29. data/app/presenters/decidim/forms/admin/questionnaire_participant_presenter.rb +60 -0
  30. data/app/presenters/decidim/forms/answer_option_presenter.rb +20 -0
  31. data/app/presenters/decidim/forms/question_presenter.rb +16 -0
  32. data/app/queries/decidim/forms/questionnaire_participant.rb +35 -0
  33. data/app/queries/decidim/forms/questionnaire_participants.rb +43 -0
  34. data/app/views/decidim/forms/admin/questionnaires/_display_condition.html.erb +88 -0
  35. data/app/views/decidim/forms/admin/questionnaires/_display_condition_template.html.erb +7 -0
  36. data/app/views/decidim/forms/admin/questionnaires/_form.html.erb +30 -4
  37. data/app/views/decidim/forms/admin/questionnaires/_question.html.erb +19 -3
  38. data/app/views/decidim/forms/admin/questionnaires/answers/export/_answer.html.erb +31 -0
  39. data/app/views/decidim/forms/admin/questionnaires/answers/export/pdf.html.erb +13 -0
  40. data/app/views/decidim/forms/admin/questionnaires/answers/index.html.erb +53 -0
  41. data/app/views/decidim/forms/admin/questionnaires/answers/show.html.erb +48 -0
  42. data/app/views/decidim/forms/admin/questionnaires/edit.html.erb +9 -5
  43. data/app/views/decidim/forms/questionnaires/_answer.html.erb +1 -1
  44. data/app/views/decidim/forms/questionnaires/show.html.erb +22 -2
  45. data/app/views/layouts/decidim/forms/admin/questionnaires/questionnaire_answers.html.erb +12 -0
  46. data/config/initializers/wicked_pdf.rb +25 -0
  47. data/config/locales/am-ET.yml +1 -0
  48. data/config/locales/ar.yml +0 -1
  49. data/config/locales/bg-BG.yml +0 -2
  50. data/config/locales/bg.yml +14 -0
  51. data/config/locales/ca.yml +56 -4
  52. data/config/locales/cs.yml +54 -2
  53. data/config/locales/da.yml +1 -0
  54. data/config/locales/de.yml +51 -1
  55. data/config/locales/el.yml +0 -2
  56. data/config/locales/en.yml +54 -2
  57. data/config/locales/eo.yml +1 -0
  58. data/config/locales/es-MX.yml +53 -1
  59. data/config/locales/es-PY.yml +53 -1
  60. data/config/locales/es.yml +54 -2
  61. data/config/locales/et.yml +1 -0
  62. data/config/locales/eu.yml +0 -1
  63. data/config/locales/fi-plain.yml +53 -1
  64. data/config/locales/fi.yml +53 -1
  65. data/config/locales/fr-CA.yml +54 -2
  66. data/config/locales/fr.yml +54 -2
  67. data/config/locales/gl.yml +0 -1
  68. data/config/locales/hr.yml +1 -0
  69. data/config/locales/hu.yml +0 -2
  70. data/config/locales/id-ID.yml +0 -1
  71. data/config/locales/is.yml +1 -0
  72. data/config/locales/it.yml +53 -1
  73. data/config/locales/ja-JP.yml +51 -1
  74. data/config/locales/ja.yml +170 -0
  75. data/config/locales/ko-KR.yml +1 -0
  76. data/config/locales/ko.yml +1 -0
  77. data/config/locales/lt.yml +1 -0
  78. data/config/locales/{lv-LV.yml → lv.yml} +0 -1
  79. data/config/locales/mt.yml +1 -0
  80. data/config/locales/nl.yml +59 -7
  81. data/config/locales/no.yml +47 -2
  82. data/config/locales/om-ET.yml +1 -0
  83. data/config/locales/pl.yml +52 -3
  84. data/config/locales/pt-BR.yml +0 -1
  85. data/config/locales/pt.yml +51 -2
  86. data/config/locales/ro-RO.yml +51 -2
  87. data/config/locales/ru.yml +0 -1
  88. data/config/locales/sk.yml +0 -2
  89. data/config/locales/sl.yml +7 -0
  90. data/config/locales/so-SO.yml +1 -0
  91. data/config/locales/sv.yml +51 -2
  92. data/config/locales/ti-ER.yml +1 -0
  93. data/config/locales/tr-TR.yml +0 -1
  94. data/config/locales/vi-VN.yml +1 -0
  95. data/config/locales/vi.yml +1 -0
  96. data/config/locales/zh-CN.yml +172 -0
  97. data/config/locales/zh-TW.yml +1 -0
  98. data/db/migrate/20200130194123_create_decidim_forms_display_conditions.rb +20 -0
  99. data/lib/decidim/exporters/form_pdf.rb +33 -0
  100. data/lib/decidim/exporters/form_pdf_controller_helper.rb +11 -0
  101. data/lib/decidim/forms.rb +5 -0
  102. data/lib/decidim/forms/admin_engine.rb +1 -1
  103. data/lib/decidim/forms/test.rb +6 -0
  104. data/lib/decidim/forms/test/factories.rb +30 -0
  105. data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +619 -38
  106. data/lib/decidim/forms/test/shared_examples/manage_questionnaire_answers.rb +108 -0
  107. data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +21 -894
  108. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_display_conditions.rb +179 -0
  109. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_questions.rb +463 -0
  110. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_display_conditions.rb +93 -0
  111. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_questions.rb +461 -0
  112. data/lib/decidim/forms/version.rb +1 -1
  113. metadata +91 -11
@@ -0,0 +1 @@
1
+ so:
@@ -25,11 +25,47 @@ sv:
25
25
  description: Beskrivning
26
26
  tos: Användarvillkor
27
27
  questionnaires:
28
+ actions:
29
+ back: Tillbaka till frågor
30
+ show: Visa svar
28
31
  answer_option:
29
32
  answer_option: Svarsalternativ
30
33
  free_text: Fritext
31
34
  remove: Ta bort
32
35
  statement: Påstående
36
+ answers:
37
+ actions:
38
+ back: Tillbaka till svar
39
+ export: Exportera
40
+ show: Visa svar
41
+ empty: Inga svar ännu
42
+ export:
43
+ answer:
44
+ title: 'Svar #%{number}'
45
+ export_response:
46
+ title: Undersökning_användare_svar_%{token}
47
+ index:
48
+ title: "%{total} svar totalt"
49
+ show:
50
+ title: 'Svar #%{number}'
51
+ display_condition:
52
+ answer_option: Svarsalternativ
53
+ condition_question: Fråga
54
+ condition_type: Skick
55
+ condition_types:
56
+ answered: Besvarad
57
+ equal: Lika
58
+ match: Inkluderar text
59
+ not_answered: Ej besvarad
60
+ not_equal: Inte lika
61
+ condition_value: Inkluderad text
62
+ display_condition: Visa villkor
63
+ mandatory: Detta villkor måste uppfyllas alltid oavsett status för andra villkor
64
+ remove: Radera
65
+ save_warning: Kom ihåg att spara formuläret innan du konfigurerar visningsvillkor
66
+ select_answer_option: Välj svarsalternativ
67
+ select_condition_question: Välj en fråga
68
+ select_condition_type: Välj en villkorstyp
33
69
  edit:
34
70
  save: Spara
35
71
  title: Redigera frågeformulär
@@ -39,12 +75,17 @@ sv:
39
75
  already_answered_warning: Frågeformuläret har redan besvarats av vissa användare så du inte kan ändra dess frågor.
40
76
  collapse: Komprimera alla frågor
41
77
  expand: Expandera alla frågor
78
+ preview: Förhandsgranska
79
+ title: Redigera formulär
80
+ unpublished_warning: Formuläret är inte publicerat. Du kan ändra dess frågor, men det kommer att ta bort aktuella svar.
42
81
  matrix_row:
43
82
  matrix_row: Rad
44
83
  remove: Ta bort
45
84
  statement: Påstående
46
85
  question:
47
86
  add_answer_option: Lägg till svarsalternativ
87
+ add_display_condition: Lägg till visningsvillkor
88
+ add_display_condition_info: Spara formuläret för att konfigurera visningsvillkor
48
89
  add_matrix_row: Lägg till rad
49
90
  any: Någon
50
91
  collapse: Komprimera
@@ -62,7 +103,6 @@ sv:
62
103
  up: Upp
63
104
  update:
64
105
  invalid: Det gick inte att spara formuläret.
65
- success: Formuläret har sparats.
66
106
  errors:
67
107
  answer:
68
108
  body: Kroppen kan inte vara to
@@ -104,6 +144,11 @@ sv:
104
144
  questionnaire_for_private_users:
105
145
  body: Formuläret är endast tillgängligt för privata användare
106
146
  title: Formuläret är stängt
147
+ questionnaire_js_disabled:
148
+ body: Vissa av formulärens funktioner kommer att inaktiveras. För att förbättra din upplevelse, vänligen aktivera JavaScript i din webbläsare.
149
+ title: JavaScript är inaktiverat
150
+ questionnaire_not_published:
151
+ body: Detta formulär är ännu inte publicerat.
107
152
  tos_agreement: Genom att delta godkänner du användarvillkoren
108
153
  step_navigation:
109
154
  show:
@@ -112,9 +157,13 @@ sv:
112
157
  continue: Fortsätt
113
158
  submit: Skicka in
114
159
  user_answers_serializer:
160
+ body: Svar
161
+ completion: Slutförande
115
162
  created_at: Besvarad
116
163
  id: Svars-ID
117
- ip_hash: Ip-hash
164
+ ip_hash: IP Hash
165
+ question: Fråga
118
166
  registered: Registrerad
167
+ session_token: Identifierare för användare
119
168
  unregistered: Ej registrerad
120
169
  user_status: Användarstatus
@@ -0,0 +1 @@
1
+ ti:
@@ -47,7 +47,6 @@ tr:
47
47
  up: yukarı
48
48
  update:
49
49
  invalid: Formu kaydederken bir sorun oluştu.
50
- success: Formlar başarıyla kaydedildi.
51
50
  errors:
52
51
  answer:
53
52
  body: Vücut boş olamaz
@@ -0,0 +1 @@
1
+ vi:
@@ -0,0 +1 @@
1
+ vi:
@@ -0,0 +1,172 @@
1
+ zh-CN:
2
+ activemodel:
3
+ attributes:
4
+ answer:
5
+ body: 答案
6
+ choices: 选择
7
+ selected_choices: 选定的选择
8
+ question:
9
+ max_choices: 选择的最大数量
10
+ question_type: 类型
11
+ questionnaire_question:
12
+ mandatory: Mandatory
13
+ errors:
14
+ models:
15
+ answer:
16
+ attributes:
17
+ choices:
18
+ missing: 不完成
19
+ too_many: 太多了
20
+ questionnaire:
21
+ request_invalid: 处理请求时出错。请再试一次
22
+ decidim:
23
+ forms:
24
+ admin:
25
+ models:
26
+ components:
27
+ description: 描述
28
+ tos: 服务条款
29
+ questionnaires:
30
+ actions:
31
+ back: 返回问题
32
+ show: 显示回复
33
+ answer_option:
34
+ answer_option: 答案选项
35
+ free_text: 免费文本
36
+ remove: 删除
37
+ statement: 声明
38
+ answers:
39
+ actions:
40
+ back: 回到回应
41
+ export: 导出
42
+ show: 显示答案
43
+ empty: 尚无答案
44
+ export:
45
+ answer:
46
+ title: '回复 #%{number}'
47
+ export_response:
48
+ title: survey_user_answers_%{token}
49
+ index:
50
+ title: "%{total} 个回复总数"
51
+ show:
52
+ title: '答案 #%{number}'
53
+ display_condition:
54
+ answer_option: 答案选项
55
+ condition_question: 问
56
+ condition_type: 条件
57
+ condition_types:
58
+ answered: 已回答
59
+ equal: 等于
60
+ match: 包含文本
61
+ not_answered: 未回答
62
+ not_equal: 不等于
63
+ condition_value: 包含文本
64
+ display_condition: 显示条件
65
+ mandatory: 无论其他条件的状况如何,总是需要满足这个条件
66
+ remove: 删除
67
+ save_warning: 在配置显示条件之前记住保存表单
68
+ select_answer_option: 选择答案选项
69
+ select_condition_question: 选择一个问题
70
+ select_condition_type: 选择一个条件类型
71
+ edit:
72
+ save: 保存
73
+ title: 编辑问题单
74
+ form:
75
+ add_question: 添加问题
76
+ add_separator: 添加分隔符
77
+ already_answered_warning: 某些用户已经回答了表单,因此您不能修改其问题。
78
+ collapse: 收起所有问题
79
+ expand: 展开所有问题
80
+ preview: 预览
81
+ title: 编辑表单
82
+ unpublished_warning: 表单未发布。您可以修改它的问题,但这样做将删除当前答案。
83
+ matrix_row:
84
+ matrix_row: 行
85
+ remove: 删除
86
+ statement: 声明
87
+ question:
88
+ add_answer_option: 添加答案选项
89
+ add_display_condition: 添加显示条件
90
+ add_display_condition_info: 保存表单以配置显示条件
91
+ add_matrix_row: 添加行
92
+ any: 任何
93
+ collapse: 收起
94
+ description: 描述
95
+ down: 向下
96
+ expand: 扩展
97
+ question: 问
98
+ remove: 删除
99
+ statement: 声明
100
+ up: 上移
101
+ separator:
102
+ down: 向下
103
+ remove: 删除
104
+ separator: 分隔符
105
+ up: 上移
106
+ update:
107
+ invalid: 保存表单时出错。
108
+ success: 表单保存成功。
109
+ errors:
110
+ answer:
111
+ body: 主体不能为空
112
+ files:
113
+ extension_whitelist: '接受的格式:'
114
+ images:
115
+ dimensions: "%{width} x %{height} px"
116
+ dimensions_info: '这张图片将是:'
117
+ processors:
118
+ resize_and_pad: 缩放并填充到
119
+ resize_to_fit: 调整到适合的
120
+ question_types:
121
+ long_answer: 长答案
122
+ matrix_multiple: 矩阵(多选项)
123
+ matrix_single: 矩阵(单选项)
124
+ multiple_option: 多选项
125
+ short_answer: 简短答案
126
+ single_option: 单个选项
127
+ sorting: 排序中
128
+ questionnaires:
129
+ answer:
130
+ invalid: 回答表单时出现问题。
131
+ max_choices_alert: 选择了太多选项
132
+ success: 表单回答成功。
133
+ question:
134
+ max_choices: '最大选择数: %{n}'
135
+ show:
136
+ answer_questionnaire:
137
+ anonymous_user_message: <a href="%{sign_in_link}">使用您的帐户</a> 或 <a href="%{sign_up_link}">注册</a> 以回答表单。
138
+ title: 回答表单
139
+ current_step: 步骤 %{step}
140
+ of_total_steps: '%{total_steps}'
141
+ questionnaire_answered:
142
+ body: 您已经回答过这个表单。
143
+ title: 已经回答
144
+ questionnaire_closed:
145
+ body: 表格已关闭,无法解答。
146
+ title: 表单已关闭
147
+ questionnaire_for_private_users:
148
+ body: 表单仅供私人用户使用
149
+ title: 表单已关闭
150
+ questionnaire_js_disabled:
151
+ body: 此表单的一些功能将被禁用。为了改善您的体验,请在您的浏览器中启用 JavaScript。
152
+ title: JavaScript 已禁用
153
+ questionnaire_not_published:
154
+ body: 此表单尚未发布。
155
+ tos_agreement: 通过参与您接受其服务条款
156
+ step_navigation:
157
+ show:
158
+ are_you_sure: 此操作不能撤消,您将无法编辑您的答案。您确定吗?
159
+ back: 后退
160
+ continue: 继续
161
+ submit: 提交
162
+ user_answers_serializer:
163
+ body: 答案
164
+ completion: 完成
165
+ created_at: 回答于
166
+ id: 答案 ID
167
+ ip_hash: IP哈希
168
+ question: 问
169
+ registered: 已注册
170
+ session_token: 用户标识符
171
+ unregistered: 未注册
172
+ user_status: 用户状态
@@ -0,0 +1 @@
1
+ zh-TW:
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateDecidimFormsDisplayConditions < ActiveRecord::Migration[5.1]
4
+ def up
5
+ create_table :decidim_forms_display_conditions do |t|
6
+ t.bigint :decidim_question_id, index: { name: "decidim_forms_display_condition_question" }, null: false
7
+ t.bigint :decidim_condition_question_id, index: { name: "decidim_forms_display_condition_condition_question" }, null: false
8
+ t.bigint :decidim_answer_option_id, index: { name: "decidim_forms_display_condition_answer_option" }
9
+ t.integer :condition_type, default: 0, null: false
10
+ t.jsonb :condition_value
11
+ t.boolean :mandatory, default: false
12
+
13
+ t.timestamps
14
+ end
15
+ end
16
+
17
+ def down
18
+ drop_table :decidim_forms_display_conditions
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "wicked_pdf"
4
+
5
+ module Decidim
6
+ module Exporters
7
+ # Inherits from abstract PDF exporter. This class is used to set
8
+ # the parameters used to create a PDF when exporting Survey Answers.
9
+ #
10
+ class FormPDF < PDF
11
+ # i18n-tasks-use t('decidim.admin.exports.formats.FormPDF')
12
+
13
+ def controller
14
+ @controller ||= FormPDFControllerHelper.new
15
+ end
16
+
17
+ def template
18
+ "decidim/forms/admin/questionnaires/answers/export/pdf.html.erb"
19
+ end
20
+
21
+ def layout
22
+ "decidim/forms/admin/questionnaires/questionnaire_answers.html.erb"
23
+ end
24
+
25
+ def locals
26
+ {
27
+ questionnaire: collection.first.first.questionnaire,
28
+ collection: collection.map { |answer| Decidim::Forms::Admin::QuestionnaireParticipantPresenter.new(participant: answer.first) }
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Exporters
5
+ # A dummy controller to render views while exporting questionnaires
6
+ class FormPDFControllerHelper < ActionController::Base
7
+ helper Decidim::TranslationsHelper
8
+ helper Decidim::Forms::Admin::QuestionnaireAnswersHelper
9
+ end
10
+ end
11
+ end
@@ -11,4 +11,9 @@ module Decidim
11
11
  autoload :UserAnswersSerializer, "decidim/forms/user_answers_serializer"
12
12
  autoload :DataPortabilityUserAnswersSerializer, "decidim/forms/data_portability_user_answers_serializer"
13
13
  end
14
+
15
+ module Exporters
16
+ autoload :FormPDF, "decidim/exporters/form_pdf"
17
+ autoload :FormPDFControllerHelper, "decidim/exporters/form_pdf_controller_helper"
18
+ end
14
19
  end
@@ -10,7 +10,7 @@ module Decidim
10
10
  paths["lib/tasks"] = nil
11
11
 
12
12
  initializer "decidim_forms.admin_assets" do |app|
13
- app.config.assets.precompile += %w(admin/decidim_forms_manifest.js)
13
+ app.config.assets.precompile += %w(admin/decidim_forms_manifest.js admin/decidim_forms_manifest.css)
14
14
  end
15
15
 
16
16
  def load_seed
@@ -2,3 +2,9 @@
2
2
 
3
3
  require "decidim/forms/test/shared_examples/has_questionnaire"
4
4
  require "decidim/forms/test/shared_examples/manage_questionnaires"
5
+ require "decidim/forms/test/shared_examples/manage_questionnaire_answers"
6
+
7
+ if defined? Decidim::Templates
8
+ require "decidim/templates/test/shared_examples/uses_questionnaire_templates"
9
+ require "decidim/templates/test/factories"
10
+ end
@@ -23,6 +23,12 @@ FactoryBot.define do
23
23
  qs
24
24
  end
25
25
  end
26
+
27
+ trait :empty do
28
+ title { {} }
29
+ description { {} }
30
+ tos { {} }
31
+ end
26
32
  end
27
33
 
28
34
  factory :questionnaire_question, class: "Decidim::Forms::Question" do
@@ -67,6 +73,12 @@ FactoryBot.define do
67
73
  end
68
74
  end
69
75
 
76
+ trait :conditioned do
77
+ display_conditions do
78
+ Array.new(3).collect { build(:display_condition) }
79
+ end
80
+ end
81
+
70
82
  trait :separator do
71
83
  question_type { :separator }
72
84
  end
@@ -77,6 +89,7 @@ FactoryBot.define do
77
89
  questionnaire
78
90
  question { create(:questionnaire_question, questionnaire: questionnaire) }
79
91
  user { create(:user, organization: questionnaire.questionnaire_for.organization) }
92
+ session_token { Digest::MD5.hexdigest(user.id.to_s) }
80
93
  end
81
94
 
82
95
  factory :answer_option, class: "Decidim::Forms::AnswerOption" do
@@ -96,4 +109,21 @@ FactoryBot.define do
96
109
  body { generate_localized_title }
97
110
  position { 0 }
98
111
  end
112
+
113
+ factory :display_condition, class: "Decidim::Forms::DisplayCondition" do
114
+ condition_question { create(:questionnaire_question) }
115
+ question { create(:questionnaire_question, position: 1) }
116
+ condition_type { :answered }
117
+ mandatory { true }
118
+
119
+ trait :equal do
120
+ condition_type { :equal }
121
+ answer_option { create(:answer_option, question: condition_question) }
122
+ end
123
+
124
+ trait :match do
125
+ condition_type { :match }
126
+ condition_value { generate_localized_title }
127
+ end
128
+ end
99
129
  end