dkdeploy-typo3-cms 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rubocop.yml +23 -0
  4. data/.travis.yml +12 -0
  5. data/Berksfile +3 -0
  6. data/Berksfile.lock +66 -0
  7. data/CHANGELOG.md +12 -0
  8. data/CONTRIBUTORS.md +16 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE +7 -0
  11. data/README.md +87 -0
  12. data/Rakefile +1 -0
  13. data/Vagrantfile +62 -0
  14. data/assets/dkdeploy-logo.png +0 -0
  15. data/config/vm/cookbooks/dkdeploy-typo3-cms/metadata.rb +12 -0
  16. data/config/vm/cookbooks/dkdeploy-typo3-cms/recipes/default.rb +71 -0
  17. data/dkdeploy-typo3-cms.gemspec +29 -0
  18. data/features/advanced_typo3.feature +156 -0
  19. data/features/caretaker_key_management.feature +36 -0
  20. data/features/clear_cache_on_rollback.feature +17 -0
  21. data/features/cli.feature +61 -0
  22. data/features/step_definitions/mysql.rb +75 -0
  23. data/features/step_definitions/typo3.rb +16 -0
  24. data/features/support/env.rb +11 -0
  25. data/features/typo3.feature +100 -0
  26. data/features/typoscript_upload_and_merge_config.feature +128 -0
  27. data/features/typoscript_upload_and_merge_pagets.feature +128 -0
  28. data/features/typoscript_upload_and_merge_userts.feature +128 -0
  29. data/features/update_database.feature +23 -0
  30. data/lib/capistrano/dkdeploy/typo3_cms.rb +37 -0
  31. data/lib/dkdeploy/typo3/cms.rb +1 -0
  32. data/lib/dkdeploy/typo3/cms/dsl.rb +27 -0
  33. data/lib/dkdeploy/typo3/cms/helpers/cli.rb +165 -0
  34. data/lib/dkdeploy/typo3/cms/helpers/erb.rb +25 -0
  35. data/lib/dkdeploy/typo3/cms/i18n.rb +111 -0
  36. data/lib/dkdeploy/typo3/cms/tasks/cache.rake +18 -0
  37. data/lib/dkdeploy/typo3/cms/tasks/caretaker_key_management.rake +60 -0
  38. data/lib/dkdeploy/typo3/cms/tasks/cli.rake +45 -0
  39. data/lib/dkdeploy/typo3/cms/tasks/typo3.rake +272 -0
  40. data/lib/dkdeploy/typo3/cms/tasks/typoscript.rake +288 -0
  41. data/lib/dkdeploy/typo3/cms/version.rb +16 -0
  42. data/spec/fixtures/application/Capfile +8 -0
  43. data/spec/fixtures/application/Gemfile +3 -0
  44. data/spec/fixtures/application/config/deploy.rb +8 -0
  45. data/spec/fixtures/application/config/deploy/dev.rb +41 -0
  46. data/spec/fixtures/application/htdocs/.hidden/.gitkeep +0 -0
  47. data/spec/fixtures/application/htdocs/catalog/index.html +1 -0
  48. data/spec/fixtures/application/htdocs/composer.json +24 -0
  49. data/spec/fixtures/application/htdocs/typo3/cli_dispatch.phpsh +2 -0
  50. data/spec/fixtures/application/htdocs/typo3conf/AdditionalConfiguration.php +3 -0
  51. data/spec/fixtures/application/htdocs/typo3conf/LocalConfiguration.php +28 -0
  52. data/spec/fixtures/application/htdocs/typo3conf/PackageStates.php +358 -0
  53. data/spec/fixtures/application/vendor/composer.phar +0 -0
  54. data/spec/fixtures/capistrano/configuration/additional_configuration_for_server.rb +1 -0
  55. data/spec/fixtures/capistrano/configuration/cli_break_after_one_run_in_release_path.rb +14 -0
  56. data/spec/fixtures/capistrano/configuration/cli_break_after_three_runs_in_release_path.rb +14 -0
  57. data/spec/fixtures/capistrano/configuration/cli_test_tasks.rb +19 -0
  58. data/spec/fixtures/capistrano/configuration/cli_test_tasks_with_path.rb +15 -0
  59. data/vendor/AdditionalConfiguration.php.erb +57 -0
  60. data/vendor/create_caretaker_instance_keys.php.erb +18 -0
  61. metadata +222 -0
@@ -0,0 +1,16 @@
1
+ module Dkdeploy
2
+ module Typo3
3
+ module Cms
4
+ # Class for version number
5
+ class Version
6
+ MAJOR = 7
7
+ MINOR = 0
8
+ PATCH = 0
9
+
10
+ def self.to_s
11
+ [MAJOR, MINOR, PATCH].join('.')
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ # Load DSL and Setup Up Stages
2
+ require 'capistrano/setup'
3
+
4
+ # Includes default deployment tasks
5
+ require 'capistrano/deploy'
6
+
7
+ # Includes dkdeploy deployment tasks
8
+ require 'capistrano/dkdeploy/typo3_cms'
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'dkdeploy-typo3-cms', path: '../../'
@@ -0,0 +1,8 @@
1
+ set :application, 'dkdeploy_app'
2
+ set :composer_default_arguments, fetch(:composer_default_arguments) + ['-d=htdocs/']
3
+
4
+ SSHKit.config.command_map.prefix[:compass].push 'bundle exec'
5
+ SSHKit.config.command_map.prefix[:chown].push 'sudo'
6
+ SSHKit.config.command_map.prefix[:chgrp].push 'sudo'
7
+ SSHKit.config.command_map.prefix[:chmod].push 'sudo'
8
+ SSHKit.config.command_map[:composer] = 'vendor/composer.phar'
@@ -0,0 +1,41 @@
1
+ set :deploy_to, '/var/www/dkdeploy'
2
+ server 'dkdeploy-typo3-cms.dev', roles: %w(web app backend), primary: true
3
+
4
+ # no ssh compression on the dev stage
5
+ set :ssh_options, {
6
+ compression: 'none'
7
+ }
8
+
9
+ ssh_key_files = Dir.glob(File.join(Dir.getwd, '..', '..', '.vagrant', 'machines', '**', 'virtualbox', 'private_key'))
10
+ unless ssh_key_files.empty?
11
+ # Define generated ssh key files
12
+ set :ssh_options, fetch(:ssh_options).merge(
13
+ {
14
+ user: 'vagrant',
15
+ keys: ssh_key_files
16
+ }
17
+ )
18
+ end
19
+
20
+ set :typoscript_userts_file, 'UserTS.txt'
21
+ set :typoscript_pagets_file, 'PageTS.txt'
22
+ set :typoscript_config_file, 'config.txt'
23
+
24
+ set :copy_source, 'htdocs'
25
+ set :copy_exclude, %w(
26
+ Gemfile*
27
+ .hidden
28
+ **/.hidden
29
+ )
30
+
31
+ # custom file access properties
32
+ set :custom_file_access, {
33
+ app: {
34
+ catalog: {
35
+ owner: 'test-user',
36
+ group: 'test-group',
37
+ mode: 'a+rwx,o-wx',
38
+ recursive: true
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "dkdeploy/typo3-cms-test-application",
3
+ "description": "Test application for dkdeploy-typo3-cms.",
4
+ "config": {
5
+ "bin-dir": "bin"
6
+ },
7
+ "repositories": [
8
+ {
9
+ "type": "composer",
10
+ "url": "https://composer.typo3.org/"
11
+ }
12
+ ],
13
+ "require": {
14
+ "typo3/cms": "7.6.15",
15
+ "typo3-ter/realurl": "2.1.5",
16
+ "helhum/typo3-console": "4.1.2"
17
+ },
18
+ "extra": {
19
+ "helhum/typo3-console":{
20
+ "install-binary": false,
21
+ "install-extension-dummy": false
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,2 @@
1
+ <?php
2
+ echo "TYPO3_COMPOSER_AUTOLOAD=" . getenv("TYPO3_COMPOSER_AUTOLOAD");
@@ -0,0 +1,3 @@
1
+ <?php
2
+
3
+ putenv('TYPO3_DISABLE_CORE_UPDATER=1');
@@ -0,0 +1,28 @@
1
+ <?php
2
+ return [
3
+ 'BE' => [
4
+ 'createGroup' => 'www-data',
5
+ 'fileCreateMask' => '0664',
6
+ 'folderCreateMask' => '0775',
7
+ 'forceCharset' => 'utf-8',
8
+ 'loginSecurityLevel' => 'normal',
9
+ 'maxFileSize' => '65536',
10
+ ],
11
+ 'EXT' => [
12
+ 'allowLocalInstall' => '0',
13
+ 'extConf' => [],
14
+ ],
15
+ 'FE' => [
16
+ 'loginSecurityLevel' => 'normal',
17
+ ],
18
+ 'SYS' => [
19
+ 'ddmmyy' => 'd.m.y',
20
+ 'devIPmask' => '*',
21
+ 'phpTimeZone' => 'Europe/Berlin',
22
+ 'setDBinit' => 'SET NAMES utf8;',
23
+ 'sitename' => 'dkdeploy dev',
24
+ 'systemLog' => 'error_log,,0',
25
+ 't3lib_cs_convMethod' => 'mbstring',
26
+ 't3lib_cs_utils' => 'mbstring',
27
+ ],
28
+ ];
@@ -0,0 +1,358 @@
1
+ <?php
2
+ # PackageStates.php
3
+
4
+ # This file is maintained by TYPO3's package management. Although you can edit it
5
+ # manually, you should rather use the extension manager for maintaining packages.
6
+ # This file will be regenerated automatically if it doesn't exist. Deleting this file
7
+ # should, however, never become necessary if you use the package commands.
8
+
9
+ return [
10
+ 'packages' => [
11
+ 'core' => [
12
+ 'manifestPath' => '',
13
+ 'composerName' => 'typo3/cms-core',
14
+ 'state' => 'active',
15
+ 'packagePath' => 'typo3/sysext/core/',
16
+ 'classesPath' => 'Classes/',
17
+ 'suggestions' => [],
18
+ ],
19
+ 'about' => [
20
+ 'manifestPath' => '',
21
+ 'composerName' => 'typo3/cms-about',
22
+ 'state' => 'active',
23
+ 'packagePath' => 'typo3/sysext/about/',
24
+ 'classesPath' => 'Classes/',
25
+ 'suggestions' => [],
26
+ ],
27
+ 'aboutmodules' => [
28
+ 'manifestPath' => '',
29
+ 'composerName' => 'typo3/cms-aboutmodules',
30
+ 'state' => 'active',
31
+ 'packagePath' => 'typo3/sysext/aboutmodules/',
32
+ 'classesPath' => 'Classes/',
33
+ 'suggestions' => [],
34
+ ],
35
+ 'backend' => [
36
+ 'manifestPath' => '',
37
+ 'composerName' => 'typo3/cms-backend',
38
+ 'state' => 'active',
39
+ 'packagePath' => 'typo3/sysext/backend/',
40
+ 'classesPath' => 'Classes/',
41
+ 'suggestions' => [],
42
+ ],
43
+ 'belog' => [
44
+ 'manifestPath' => '',
45
+ 'composerName' => 'typo3/cms-belog',
46
+ 'state' => 'active',
47
+ 'packagePath' => 'typo3/sysext/belog/',
48
+ 'classesPath' => 'Classes/',
49
+ 'suggestions' => [],
50
+ ],
51
+ 'beuser' => [
52
+ 'manifestPath' => '',
53
+ 'composerName' => 'typo3/cms-beuser',
54
+ 'state' => 'active',
55
+ 'packagePath' => 'typo3/sysext/beuser/',
56
+ 'classesPath' => 'Classes/',
57
+ 'suggestions' => [],
58
+ ],
59
+ 'context_help' => [
60
+ 'manifestPath' => '',
61
+ 'composerName' => 'typo3/cms-context-help',
62
+ 'state' => 'active',
63
+ 'packagePath' => 'typo3/sysext/context_help/',
64
+ 'classesPath' => 'Classes/',
65
+ 'suggestions' => [],
66
+ ],
67
+ 'cshmanual' => [
68
+ 'manifestPath' => '',
69
+ 'composerName' => 'typo3/cms-cshmanual',
70
+ 'state' => 'active',
71
+ 'packagePath' => 'typo3/sysext/cshmanual/',
72
+ 'classesPath' => 'Classes/',
73
+ 'suggestions' => [],
74
+ ],
75
+ 'css_styled_content' => [
76
+ 'manifestPath' => '',
77
+ 'composerName' => 'typo3/cms-css-styled-content',
78
+ 'state' => 'active',
79
+ 'packagePath' => 'typo3/sysext/css_styled_content/',
80
+ 'classesPath' => 'Classes/',
81
+ 'suggestions' => [],
82
+ ],
83
+ 'extbase' => [
84
+ 'manifestPath' => '',
85
+ 'composerName' => 'typo3/cms-extbase',
86
+ 'state' => 'active',
87
+ 'packagePath' => 'typo3/sysext/extbase/',
88
+ 'classesPath' => 'Classes/',
89
+ 'suggestions' => [],
90
+ ],
91
+ 'fluid' => [
92
+ 'manifestPath' => '',
93
+ 'composerName' => 'typo3/cms-fluid',
94
+ 'state' => 'active',
95
+ 'packagePath' => 'typo3/sysext/fluid/',
96
+ 'classesPath' => 'Classes/',
97
+ 'suggestions' => [],
98
+ ],
99
+ 'documentation' => [
100
+ 'manifestPath' => '',
101
+ 'composerName' => 'typo3/cms-documentation',
102
+ 'state' => 'active',
103
+ 'packagePath' => 'typo3/sysext/documentation/',
104
+ 'classesPath' => 'Classes/',
105
+ 'suggestions' => [],
106
+ ],
107
+ 'felogin' => [
108
+ 'manifestPath' => '',
109
+ 'composerName' => 'typo3/cms-felogin',
110
+ 'state' => 'active',
111
+ 'packagePath' => 'typo3/sysext/felogin/',
112
+ 'classesPath' => 'Classes/',
113
+ 'suggestions' => [],
114
+ ],
115
+ 'filelist' => [
116
+ 'manifestPath' => '',
117
+ 'composerName' => 'typo3/cms-filelist',
118
+ 'state' => 'active',
119
+ 'packagePath' => 'typo3/sysext/filelist/',
120
+ 'classesPath' => 'Classes/',
121
+ 'suggestions' => [],
122
+ ],
123
+ 'filemetadata' => [
124
+ 'manifestPath' => '',
125
+ 'composerName' => 'typo3/cms-filemetadata',
126
+ 'state' => 'active',
127
+ 'packagePath' => 'typo3/sysext/filemetadata/',
128
+ 'classesPath' => 'Classes/',
129
+ 'suggestions' => [],
130
+ ],
131
+ 'form' => [
132
+ 'manifestPath' => '',
133
+ 'composerName' => 'typo3/cms-form',
134
+ 'state' => 'active',
135
+ 'packagePath' => 'typo3/sysext/form/',
136
+ 'classesPath' => 'Classes/',
137
+ 'suggestions' => [],
138
+ ],
139
+ 'frontend' => [
140
+ 'manifestPath' => '',
141
+ 'composerName' => 'typo3/cms-frontend',
142
+ 'state' => 'active',
143
+ 'packagePath' => 'typo3/sysext/frontend/',
144
+ 'classesPath' => 'Classes/',
145
+ 'suggestions' => [],
146
+ ],
147
+ 'impexp' => [
148
+ 'manifestPath' => '',
149
+ 'composerName' => 'typo3/cms-impexp',
150
+ 'state' => 'active',
151
+ 'packagePath' => 'typo3/sysext/impexp/',
152
+ 'classesPath' => 'Classes/',
153
+ 'suggestions' => [],
154
+ ],
155
+ 'info' => [
156
+ 'manifestPath' => '',
157
+ 'composerName' => 'typo3/cms-info',
158
+ 'state' => 'active',
159
+ 'packagePath' => 'typo3/sysext/info/',
160
+ 'classesPath' => 'Classes/',
161
+ 'suggestions' => [],
162
+ ],
163
+ 'info_pagetsconfig' => [
164
+ 'manifestPath' => '',
165
+ 'composerName' => 'typo3/cms-info-pagetsconfig',
166
+ 'state' => 'active',
167
+ 'packagePath' => 'typo3/sysext/info_pagetsconfig/',
168
+ 'classesPath' => 'Classes/',
169
+ 'suggestions' => [],
170
+ ],
171
+ 'install' => [
172
+ 'manifestPath' => '',
173
+ 'composerName' => 'typo3/cms-install',
174
+ 'state' => 'active',
175
+ 'packagePath' => 'typo3/sysext/install/',
176
+ 'classesPath' => 'Classes/',
177
+ 'suggestions' => [],
178
+ ],
179
+ 'extensionmanager' => [
180
+ 'manifestPath' => '',
181
+ 'composerName' => 'typo3/cms-extensionmanager',
182
+ 'state' => 'active',
183
+ 'packagePath' => 'typo3/sysext/extensionmanager/',
184
+ 'classesPath' => 'Classes/',
185
+ 'suggestions' => [],
186
+ ],
187
+ 'lang' => [
188
+ 'manifestPath' => '',
189
+ 'composerName' => 'typo3/cms-lang',
190
+ 'state' => 'active',
191
+ 'packagePath' => 'typo3/sysext/lang/',
192
+ 'classesPath' => 'Classes/',
193
+ 'suggestions' => [],
194
+ ],
195
+ 'lowlevel' => [
196
+ 'manifestPath' => '',
197
+ 'composerName' => 'typo3/cms-lowlevel',
198
+ 'state' => 'active',
199
+ 'packagePath' => 'typo3/sysext/lowlevel/',
200
+ 'classesPath' => 'Classes/',
201
+ 'suggestions' => [],
202
+ ],
203
+ 'recordlist' => [
204
+ 'manifestPath' => '',
205
+ 'composerName' => 'typo3/cms-recordlist',
206
+ 'state' => 'active',
207
+ 'packagePath' => 'typo3/sysext/recordlist/',
208
+ 'classesPath' => 'Classes/',
209
+ 'suggestions' => [],
210
+ ],
211
+ 'reports' => [
212
+ 'manifestPath' => '',
213
+ 'composerName' => 'typo3/cms-reports',
214
+ 'state' => 'active',
215
+ 'packagePath' => 'typo3/sysext/reports/',
216
+ 'classesPath' => 'Classes/',
217
+ 'suggestions' => [],
218
+ ],
219
+ 'setup' => [
220
+ 'manifestPath' => '',
221
+ 'composerName' => 'typo3/cms-setup',
222
+ 'state' => 'active',
223
+ 'packagePath' => 'typo3/sysext/setup/',
224
+ 'classesPath' => 'Classes/',
225
+ 'suggestions' => [],
226
+ ],
227
+ 'rtehtmlarea' => [
228
+ 'manifestPath' => '',
229
+ 'composerName' => 'typo3/cms-rtehtmlarea',
230
+ 'state' => 'active',
231
+ 'packagePath' => 'typo3/sysext/rtehtmlarea/',
232
+ 'classesPath' => 'Classes/',
233
+ 'suggestions' => [
234
+ 'setup',
235
+ ],
236
+ ],
237
+ 'rsaauth' => [
238
+ 'manifestPath' => '',
239
+ 'composerName' => 'typo3/cms-rsaauth',
240
+ 'state' => 'active',
241
+ 'packagePath' => 'typo3/sysext/rsaauth/',
242
+ 'classesPath' => 'Classes/',
243
+ 'suggestions' => [],
244
+ ],
245
+ 'saltedpasswords' => [
246
+ 'manifestPath' => '',
247
+ 'composerName' => 'typo3/cms-saltedpasswords',
248
+ 'state' => 'active',
249
+ 'packagePath' => 'typo3/sysext/saltedpasswords/',
250
+ 'classesPath' => 'Classes/',
251
+ 'suggestions' => [
252
+ 'rsaauth',
253
+ ],
254
+ ],
255
+ 'scheduler' => [
256
+ 'manifestPath' => '',
257
+ 'composerName' => 'typo3/cms-scheduler',
258
+ 'state' => 'active',
259
+ 'packagePath' => 'typo3/sysext/scheduler/',
260
+ 'classesPath' => 'Classes/',
261
+ 'suggestions' => [],
262
+ ],
263
+ 'sv' => [
264
+ 'manifestPath' => '',
265
+ 'composerName' => 'typo3/cms-sv',
266
+ 'state' => 'active',
267
+ 'packagePath' => 'typo3/sysext/sv/',
268
+ 'classesPath' => 'Classes/',
269
+ 'suggestions' => [],
270
+ ],
271
+ 'sys_note' => [
272
+ 'manifestPath' => '',
273
+ 'composerName' => 'typo3/cms-sys-note',
274
+ 'state' => 'active',
275
+ 'packagePath' => 'typo3/sysext/sys_note/',
276
+ 'classesPath' => 'Classes/',
277
+ 'suggestions' => [],
278
+ ],
279
+ 't3editor' => [
280
+ 'manifestPath' => '',
281
+ 'composerName' => 'typo3/cms-t3editor',
282
+ 'state' => 'active',
283
+ 'packagePath' => 'typo3/sysext/t3editor/',
284
+ 'classesPath' => 'Classes/',
285
+ 'suggestions' => [],
286
+ ],
287
+ 't3skin' => [
288
+ 'manifestPath' => '',
289
+ 'composerName' => 'typo3/cms-t3skin',
290
+ 'state' => 'active',
291
+ 'packagePath' => 'typo3/sysext/t3skin/',
292
+ 'classesPath' => 'Classes/',
293
+ 'suggestions' => [],
294
+ ],
295
+ 'tstemplate' => [
296
+ 'manifestPath' => '',
297
+ 'composerName' => 'typo3/cms-tstemplate',
298
+ 'state' => 'active',
299
+ 'packagePath' => 'typo3/sysext/tstemplate/',
300
+ 'classesPath' => 'Classes/',
301
+ 'suggestions' => [],
302
+ ],
303
+ 'version' => [
304
+ 'manifestPath' => '',
305
+ 'composerName' => 'typo3/cms-version',
306
+ 'state' => 'inactive',
307
+ 'packagePath' => 'typo3/sysext/version/',
308
+ 'classesPath' => 'Classes/',
309
+ 'suggestions' => [],
310
+ ],
311
+ 'viewpage' => [
312
+ 'manifestPath' => '',
313
+ 'composerName' => 'typo3/cms-viewpage',
314
+ 'state' => 'active',
315
+ 'packagePath' => 'typo3/sysext/viewpage/',
316
+ 'classesPath' => 'Classes/',
317
+ 'suggestions' => [],
318
+ ],
319
+ 'func' => [
320
+ 'manifestPath' => '',
321
+ 'composerName' => 'typo3/cms-func',
322
+ 'state' => 'active',
323
+ 'packagePath' => 'typo3/sysext/func/',
324
+ 'classesPath' => 'Classes/',
325
+ 'suggestions' => [],
326
+ ],
327
+ 'wizard_crpages' => [
328
+ 'manifestPath' => '',
329
+ 'composerName' => 'typo3/cms-wizard-crpages',
330
+ 'state' => 'active',
331
+ 'packagePath' => 'typo3/sysext/wizard_crpages/',
332
+ 'classesPath' => 'Classes/',
333
+ 'suggestions' => [],
334
+ ],
335
+ 'wizard_sortpages' => [
336
+ 'manifestPath' => '',
337
+ 'composerName' => 'typo3/cms-wizard-sortpages',
338
+ 'state' => 'active',
339
+ 'packagePath' => 'typo3/sysext/wizard_sortpages/',
340
+ 'classesPath' => 'Classes/',
341
+ 'suggestions' => [],
342
+ ],
343
+ 'workspaces' => [
344
+ 'manifestPath' => '',
345
+ 'composerName' => 'typo3/cms-workspaces',
346
+ 'state' => 'inactive',
347
+ 'packagePath' => 'typo3/sysext/workspaces/',
348
+ 'classesPath' => 'Classes/',
349
+ 'suggestions' => [],
350
+ ],
351
+ 'realurl' => [
352
+ 'state' => 'active',
353
+ 'packagePath' => 'typo3conf/ext/realurl/',
354
+ 'classesPath' => 'Classes/',
355
+ ],
356
+ ],
357
+ 'version' => 4,
358
+ ];