@eeacms/volto-hero-block 8.0.0 → 9.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.
package/CHANGELOG.md CHANGED
@@ -4,7 +4,19 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
- ### [8.0.0](https://github.com/eea/volto-hero-block/compare/7.1.0...8.0.0) - 28 July 2025
7
+ ### [9.0.0](https://github.com/eea/volto-hero-block/compare/8.0.0...9.0.0) - 27 March 2026
8
+
9
+ #### :rocket: New Features
10
+
11
+ - feat: Volto 18 support - refs #287700 [Alin Voinea - [`7ab8b04`](https://github.com/eea/volto-hero-block/commit/7ab8b04936147abf80d2ebbfce08137f9c66d00b)]
12
+
13
+ #### :house: Internal changes
14
+
15
+
16
+ #### :hammer_and_wrench: Others
17
+
18
+ - tests: Fix Sonar Qube tags - refs #297339 [Alin Voinea - [`b6ebf27`](https://github.com/eea/volto-hero-block/commit/b6ebf2720a72ef3ac1a5194d0c69d48c19e03630)]
19
+ ## [8.0.0](https://github.com/eea/volto-hero-block/compare/7.1.0...8.0.0) - 28 July 2025
8
20
 
9
21
  #### :house: Internal changes
10
22
 
package/DEVELOP.md CHANGED
@@ -26,21 +26,20 @@
26
26
 
27
27
  ### Or add @eeacms/volto-hero-block to your Volto project
28
28
 
29
- Before starting make sure your development environment is properly set. See [Volto Developer Documentation](https://docs.voltocms.com/getting-started/install/)
29
+ Before starting make sure your development environment is properly set. See the official Plone documentation for [creating a project with Cookieplone](https://6.docs.plone.org/install/create-project-cookieplone.html) and [installing an add-on in development mode in Volto 18 and 19](https://6.docs.plone.org/volto/development/add-ons/install-an-add-on-dev-18.html).
30
30
 
31
- 1. Make sure you have installed `yo`, `@plone/generator-volto` and `mrs-developer`
31
+ For new Volto 18+ projects, use Cookieplone. It includes `mrs-developer` by default.
32
32
 
33
- npm install -g yo @plone/generator-volto mrs-developer
33
+ 1. Create a new Volto project with Cookieplone
34
34
 
35
- 1. Create new volto app
36
-
37
- yo @plone/volto my-volto-project --addon @eeacms/volto-hero-block --skip-install
38
- cd my-volto-project
35
+ uvx cookieplone project
36
+ cd project-title
39
37
 
40
38
  1. Add the following to `mrs.developer.json`:
41
39
 
42
40
  {
43
41
  "volto-hero-block": {
42
+ "output": "packages",
44
43
  "url": "https://github.com/eea/volto-hero-block.git",
45
44
  "package": "@eeacms/volto-hero-block",
46
45
  "branch": "develop",
@@ -48,28 +47,31 @@ Before starting make sure your development environment is properly set. See [Vol
48
47
  }
49
48
  }
50
49
 
51
- 1. Install
50
+ 1. Add `@eeacms/volto-hero-block` to the `addons` key in your project `volto.config.js`
51
+
52
+ 1. Install or refresh the project setup
52
53
 
53
- make develop
54
- yarn
54
+ make install
55
55
 
56
- 1. Start backend
56
+ 1. Start backend in one terminal
57
57
 
58
- docker run --pull always -it --rm --name plone -p 8080:8080 -e SITE=Plone plone/plone-backend
58
+ make backend-start
59
59
 
60
- ...wait for backend to setup and start - `Ready to handle requests`:
60
+ ...wait for backend to setup and start, ending with `Ready to handle requests`
61
61
 
62
62
  ...you can also check http://localhost:8080/Plone
63
63
 
64
- 1. Start frontend
64
+ 1. Start frontend in a second terminal
65
65
 
66
- yarn start
66
+ make frontend-start
67
67
 
68
68
  1. Go to http://localhost:3000
69
69
 
70
70
  1. Happy hacking!
71
71
 
72
- cd src/addons/volto-hero-block/
72
+ cd packages/volto-hero-block
73
+
74
+ For legacy Volto 17 projects, keep using the yarn-based workflow from the Volto 17 documentation.
73
75
 
74
76
  ## Cypress
75
77
 
@@ -81,7 +83,7 @@ project where you added `volto-hero-block` to `mrs.developer.json`
81
83
  Go to:
82
84
 
83
85
  ```BASH
84
- cd src/addons/volto-hero-block/
86
+ cd packages/volto-hero-block/
85
87
  ```
86
88
 
87
89
  Start:
package/README.md CHANGED
@@ -3,16 +3,16 @@
3
3
  [![Releases](https://img.shields.io/github/v/release/eea/volto-hero-block)](https://github.com/eea/volto-hero-block/releases)
4
4
 
5
5
  [![Pipeline](https://ci.eionet.europa.eu/buildStatus/icon?job=volto-addons%2Fvolto-hero-block%2Fmaster&subject=master)](https://ci.eionet.europa.eu/view/Github/job/volto-addons/job/volto-hero-block/job/master/display/redirect)
6
- [![Lines of Code](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block-master&metric=ncloc)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block-master)
7
- [![Coverage](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block-master&metric=coverage)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block-master)
8
- [![Bugs](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block-master&metric=bugs)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block-master)
9
- [![Duplicated Lines (%)](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block-master&metric=duplicated_lines_density)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block-master)
6
+ [![Lines of Code](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block&metric=ncloc)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block)
7
+ [![Coverage](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block&metric=coverage)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block)
8
+ [![Bugs](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block&metric=bugs)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block)
9
+ [![Duplicated Lines (%)](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block&metric=duplicated_lines_density)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block)
10
10
 
11
11
  [![Pipeline](https://ci.eionet.europa.eu/buildStatus/icon?job=volto-addons%2Fvolto-hero-block%2Fdevelop&subject=develop)](https://ci.eionet.europa.eu/view/Github/job/volto-addons/job/volto-hero-block/job/develop/display/redirect)
12
- [![Lines of Code](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block-develop&metric=ncloc)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block-develop)
13
- [![Coverage](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block-develop&metric=coverage)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block-develop)
14
- [![Bugs](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block-develop&metric=bugs)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block-develop)
15
- [![Duplicated Lines (%)](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block-develop&metric=duplicated_lines_density)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block-develop)
12
+ [![Lines of Code](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block&branch=develop&metric=ncloc)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block&branch=develop)
13
+ [![Coverage](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block&branch=develop&metric=coverage)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block&branch=develop)
14
+ [![Bugs](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block&branch=develop&metric=bugs)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block&branch=develop)
15
+ [![Duplicated Lines (%)](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-hero-block&branch=develop&metric=duplicated_lines_density)](https://sonarqube.eea.europa.eu/dashboard?id=volto-hero-block&branch=develop)
16
16
 
17
17
  Enhanced Hero Block [Volto](https://github.com/plone/volto) add-on
18
18
 
@@ -22,6 +22,15 @@ Enhanced Hero Block [Volto](https://github.com/plone/volto) add-on
22
22
 
23
23
  ## Upgrade
24
24
 
25
+ ### Upgrading to 9.x
26
+
27
+ > This version requires `Volto >= 17.18` or `Volto 18+`. It removes the custom `EditBlockWrapper` usage in favor of Volto's built-in block chrome provided by `BlocksForm`.
28
+
29
+ #### Breaking changes
30
+
31
+ - **Removed `EditBlockWrapper` render prop from `BlocksForm`.** The `BlocksForm` children render prop that wrapped each inner block in `<EditBlockWrapper>` has been removed. `BlocksForm` now handles block chrome internally via Volto core's `EditBlockWrapper`. Any code that relied on the children render prop pattern in the hero block's `Edit` component will need to be updated.
32
+ - **`disableInnerButtons`** continues to work via the existing CSS rules in `edit.css` rather than the previously used `disabled` prop on `EditBlockWrapper`.
33
+
25
34
  ### Upgrading to 2.x
26
35
 
27
36
  This version requires: `@plone/volto >= 16.0.0.alpha.46` (schemaEnhancer / addStyling).
@@ -47,6 +56,11 @@ This is useful in case you have to add some sub titles or extra paragraphs insid
47
56
 
48
57
  Go to http://localhost:3000
49
58
 
59
+ `make start` now defaults to Volto 18. To run the same setup against Volto 17, use:
60
+
61
+ VOLTO_VERSION=17 make
62
+ VOLTO_VERSION=17 make start
63
+
50
64
  ### Add volto-hero-block to your Volto project
51
65
 
52
66
  1. Make sure you have a [Plone backend](https://plone.org/download) up-and-running at http://localhost:8080/Plone
@@ -60,30 +74,39 @@ Go to http://localhost:3000
60
74
  - If you already have a volto project, just update `package.json`:
61
75
 
62
76
  ```JSON
63
- "addons": [
64
- "@eeacms/volto-hero-block"
65
- ],
66
-
67
77
  "dependencies": {
68
78
  "@eeacms/volto-hero-block": "*"
69
79
  }
70
80
  ```
71
81
 
72
- - If not, create one:
82
+ and `volto.config.js`:
73
83
 
84
+ ```JavaScript
85
+ const addons = ['@eeacms/volto-hero-block'];
74
86
  ```
75
- npm install -g yo @plone/generator-volto
76
- yo @plone/volto my-volto-project --canary --addon @eeacms/volto-hero-block
77
- cd my-volto-project
87
+
88
+ - If not, create one with Cookieplone, as recommended by the official Plone documentation for Volto 18+:
89
+
90
+ ```
91
+ uvx cookieplone project
92
+ cd project-title
78
93
  ```
79
94
 
80
- 1. Install new add-ons and restart Volto:
95
+ 1. Install or update dependencies, then start the project:
81
96
 
82
97
  ```
83
- yarn
84
- yarn start
98
+ make install
85
99
  ```
86
100
 
101
+ For a Cookieplone project, start the backend and frontend in separate terminals:
102
+
103
+ ```
104
+ make backend-start
105
+ make frontend-start
106
+ ```
107
+
108
+ For a legacy Volto 17 project, install the package with `yarn` and restart the frontend as usual.
109
+
87
110
  1. Go to http://localhost:3000
88
111
 
89
112
  1. Happy editing!
@@ -15,7 +15,7 @@ services:
15
15
  args:
16
16
  ADDON_NAME: "${ADDON_NAME}"
17
17
  ADDON_PATH: "${ADDON_PATH}"
18
- VOLTO_VERSION: ${VOLTO_VERSION:-16}
18
+ VOLTO_VERSION: ${VOLTO_VERSION:-18-yarn}
19
19
  ports:
20
20
  - "3000:3000"
21
21
  - "3001:3001"
@@ -1,5 +1,24 @@
1
1
  require('dotenv').config({ path: __dirname + '/.env' });
2
2
 
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ // Volto 18 exposes @plone/volto-slate as a top-level package.
7
+ const voltoSlatePath = fs.existsSync(
8
+ path.join(
9
+ __dirname,
10
+ '..',
11
+ '..',
12
+ '..',
13
+ 'node_modules',
14
+ '@plone',
15
+ 'volto-slate',
16
+ 'src',
17
+ ),
18
+ )
19
+ ? '<rootDir>/node_modules/@plone/volto-slate/src'
20
+ : '<rootDir>/node_modules/@plone/volto/packages/volto-slate/src';
21
+
3
22
  module.exports = {
4
23
  testMatch: ['**/src/addons/**/?(*.)+(spec|test).[jt]s?(x)'],
5
24
  collectCoverageFrom: [
@@ -10,6 +29,8 @@ module.exports = {
10
29
  '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
11
30
  '@plone/volto/cypress': '<rootDir>/node_modules/@plone/volto/cypress',
12
31
  '@plone/volto/babel': '<rootDir>/node_modules/@plone/volto/babel',
32
+ '@plone/volto/helpers/FormValidation/validators':
33
+ '<rootDir>/src/addons/volto-hero-block/test-mocks/voltoFormValidationValidators.js',
13
34
  '@plone/volto/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
14
35
  '@package/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
15
36
  '@root/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
@@ -17,10 +38,8 @@ module.exports = {
17
38
  '@eeacms/search/(.*)$': '<rootDir>/src/addons/volto-searchlib/searchlib/$1',
18
39
  '@eeacms/search': '<rootDir>/src/addons/volto-searchlib/searchlib',
19
40
  '@eeacms/(.*?)/(.*)$': '<rootDir>/node_modules/@eeacms/$1/src/$2',
20
- '@plone/volto-slate$':
21
- '<rootDir>/node_modules/@plone/volto/packages/volto-slate/src',
22
- '@plone/volto-slate/(.*)$':
23
- '<rootDir>/node_modules/@plone/volto/packages/volto-slate/src/$1',
41
+ '@plone/volto-slate$': voltoSlatePath,
42
+ '@plone/volto-slate/(.*)$': `${voltoSlatePath}/$1`,
24
43
  '~/(.*)$': '<rootDir>/src/$1',
25
44
  'load-volto-addons':
26
45
  '<rootDir>/node_modules/@plone/volto/jest-addons-loader.js',
package/jest.setup.js CHANGED
@@ -1,16 +1,18 @@
1
1
  import { jest } from '@jest/globals';
2
2
  import configureStore from 'redux-mock-store';
3
3
  import thunk from 'redux-thunk';
4
- import { blocksConfig } from '@plone/volto/config/Blocks';
5
- import installSlate from '@plone/volto-slate/index';
6
4
 
7
5
  var mockSemanticComponents = jest.requireActual('semantic-ui-react');
8
- var mockComponents = jest.requireActual('@plone/volto/components');
9
- var config = jest.requireActual('@plone/volto/registry').default;
10
-
11
- config.blocks.blocksConfig = {
12
- ...blocksConfig,
13
- ...config.blocks.blocksConfig,
6
+ var config = {
7
+ blocks: {
8
+ blocksConfig: {},
9
+ },
10
+ settings: {
11
+ apiPath: 'http://localhost:3000',
12
+ slate: {
13
+ textblockExtensions: [],
14
+ },
15
+ },
14
16
  };
15
17
 
16
18
  jest.doMock('semantic-ui-react', () => ({
@@ -29,14 +31,23 @@ jest.doMock('semantic-ui-react', () => ({
29
31
  jest.doMock('@plone/volto/components', () => {
30
32
  return {
31
33
  __esModule: true,
32
- ...mockComponents,
33
34
  SidebarPortal: ({ children }) => <div id="sidebar">{children}</div>,
35
+ UniversalLink: ({ children, href = '', ...props }) => (
36
+ <a href={href} {...props}>
37
+ {children}
38
+ </a>
39
+ ),
40
+ RenderBlocks: () => <div />,
41
+ BlocksForm: ({ children }) =>
42
+ typeof children === 'function' ? children({}, <div />, {}) : children,
43
+ BlockDataForm: () => <div />,
34
44
  };
35
45
  });
36
46
 
37
- jest.doMock('@plone/volto/registry', () =>
38
- [installSlate].reduce((acc, apply) => apply(acc), config),
39
- );
47
+ jest.doMock('@plone/volto/registry', () => ({
48
+ __esModule: true,
49
+ default: config,
50
+ }));
40
51
 
41
52
  const mockStore = configureStore([thunk]);
42
53
 
@@ -11,4 +11,122 @@ msgstr ""
11
11
  "Content-Transfer-Encoding: \n"
12
12
  "Plural-Forms: \n"
13
13
 
14
+ #. Default: "A short hint that describes the expected value within this block"
15
+ #: components/Blocks/Hero/LayoutSchema
16
+ msgid "A short hint that describes the expected value within this block"
17
+ msgstr ""
18
+
19
+ #. Default: "Allow only the following blocks types"
20
+ #: components/Blocks/Hero/LayoutSchema
21
+ msgid "Allow only the following blocks types"
22
+ msgstr ""
23
+
24
+ #. Default: "Default"
25
+ #: components/Blocks/Hero/LayoutSchema
26
+ msgid "Default"
27
+ msgstr ""
28
+
29
+ #. Default: "Detailed expected value within this block"
30
+ #: components/Blocks/Hero/LayoutSchema
31
+ msgid "Detailed expected value within this block"
32
+ msgstr ""
33
+
34
+ #. Default: "Disable creation of new blocks after this block"
35
+ #: components/Blocks/Hero/LayoutSchema
36
+ msgid "Disable creation of new blocks after this block"
37
+ msgstr ""
38
+
39
+ #. Default: "Disable drag & drop on this block"
40
+ #: components/Blocks/Hero/LayoutSchema
41
+ msgid "Disable drag & drop on this block"
42
+ msgstr ""
43
+
44
+ #. Default: "Disable editing on hero block settings"
45
+ #: components/Blocks/Hero/LayoutSchema
46
+ msgid "Disable editing on hero block settings"
47
+ msgstr ""
48
+
49
+ #. Default: "Disable editing on hero titles"
50
+ #: components/Blocks/Hero/LayoutSchema
51
+ msgid "Disable editing on hero titles"
52
+ msgstr ""
53
+
54
+ #. Default: "Disable editing on this block"
55
+ #: components/Blocks/Hero/LayoutSchema
56
+ msgid "Disable editing on this block"
57
+ msgstr ""
58
+
59
+ #. Default: "Disable inner buttons"
60
+ #: components/Blocks/Hero/LayoutSchema
61
+ msgid "Disable inner buttons"
62
+ msgstr ""
63
+
64
+ #. Default: "Disable new blocks"
65
+ #: components/Blocks/Hero/LayoutSchema
66
+ msgid "Disable new blocks"
67
+ msgstr ""
68
+
69
+ #. Default: "Don't allow deletion of this block"
70
+ #: components/Blocks/Hero/LayoutSchema
71
+ msgid "Don't allow deletion of this block"
72
+ msgstr ""
14
73
 
74
+ #. Default: "Fixed layout"
75
+ #: components/Blocks/Hero/LayoutSchema
76
+ msgid "Fixed layout"
77
+ msgstr ""
78
+
79
+ #. Default: "Fixed layout, New panes (tabs) created by Editor within this block will be ignored"
80
+ #: components/Blocks/Hero/LayoutSchema
81
+ msgid "Fixed layout, New panes (tabs) created by Editor within this block will be ignored"
82
+ msgstr ""
83
+
84
+ #. Default: "Fixed position"
85
+ #: components/Blocks/Hero/LayoutSchema
86
+ msgid "Fixed position"
87
+ msgstr ""
88
+
89
+ #. Default: "Helper text"
90
+ #: components/Blocks/Hero/LayoutSchema
91
+ msgid "Helper text"
92
+ msgstr ""
93
+
94
+ #. Default: "Hero"
95
+ #: components/Blocks/Hero/index
96
+ msgid "Hero"
97
+ msgstr ""
98
+
99
+ #. Default: "Hero block settings"
100
+ #: components/Blocks/Hero/LayoutSchema
101
+ msgid "Hero block settings"
102
+ msgstr ""
103
+
104
+ #. Default: "Hide all block related buttons within this block"
105
+ #: components/Blocks/Hero/LayoutSchema
106
+ msgid "Hide all block related buttons within this block"
107
+ msgstr ""
108
+
109
+ #. Default: "Instructions"
110
+ #: components/Blocks/Hero/LayoutSchema
111
+ msgid "Instructions"
112
+ msgstr ""
113
+
114
+ #. Default: "Read-only"
115
+ #: components/Blocks/Hero/LayoutSchema
116
+ msgid "Read-only"
117
+ msgstr ""
118
+
119
+ #. Default: "Read-only settings"
120
+ #: components/Blocks/Hero/LayoutSchema
121
+ msgid "Read-only settings"
122
+ msgstr ""
123
+
124
+ #. Default: "Read-only titles"
125
+ #: components/Blocks/Hero/LayoutSchema
126
+ msgid "Read-only titles"
127
+ msgstr ""
128
+
129
+ #. Default: "Required"
130
+ #: components/Blocks/Hero/LayoutSchema
131
+ msgid "Required"
132
+ msgstr ""
@@ -11,4 +11,122 @@ msgstr ""
11
11
  "Content-Transfer-Encoding: \n"
12
12
  "Plural-Forms: \n"
13
13
 
14
+ #. Default: "A short hint that describes the expected value within this block"
15
+ #: components/Blocks/Hero/LayoutSchema
16
+ msgid "A short hint that describes the expected value within this block"
17
+ msgstr ""
18
+
19
+ #. Default: "Allow only the following blocks types"
20
+ #: components/Blocks/Hero/LayoutSchema
21
+ msgid "Allow only the following blocks types"
22
+ msgstr ""
23
+
24
+ #. Default: "Default"
25
+ #: components/Blocks/Hero/LayoutSchema
26
+ msgid "Default"
27
+ msgstr ""
28
+
29
+ #. Default: "Detailed expected value within this block"
30
+ #: components/Blocks/Hero/LayoutSchema
31
+ msgid "Detailed expected value within this block"
32
+ msgstr ""
33
+
34
+ #. Default: "Disable creation of new blocks after this block"
35
+ #: components/Blocks/Hero/LayoutSchema
36
+ msgid "Disable creation of new blocks after this block"
37
+ msgstr ""
38
+
39
+ #. Default: "Disable drag & drop on this block"
40
+ #: components/Blocks/Hero/LayoutSchema
41
+ msgid "Disable drag & drop on this block"
42
+ msgstr ""
43
+
44
+ #. Default: "Disable editing on hero block settings"
45
+ #: components/Blocks/Hero/LayoutSchema
46
+ msgid "Disable editing on hero block settings"
47
+ msgstr ""
48
+
49
+ #. Default: "Disable editing on hero titles"
50
+ #: components/Blocks/Hero/LayoutSchema
51
+ msgid "Disable editing on hero titles"
52
+ msgstr ""
53
+
54
+ #. Default: "Disable editing on this block"
55
+ #: components/Blocks/Hero/LayoutSchema
56
+ msgid "Disable editing on this block"
57
+ msgstr ""
58
+
59
+ #. Default: "Disable inner buttons"
60
+ #: components/Blocks/Hero/LayoutSchema
61
+ msgid "Disable inner buttons"
62
+ msgstr ""
63
+
64
+ #. Default: "Disable new blocks"
65
+ #: components/Blocks/Hero/LayoutSchema
66
+ msgid "Disable new blocks"
67
+ msgstr ""
68
+
69
+ #. Default: "Don't allow deletion of this block"
70
+ #: components/Blocks/Hero/LayoutSchema
71
+ msgid "Don't allow deletion of this block"
72
+ msgstr ""
14
73
 
74
+ #. Default: "Fixed layout"
75
+ #: components/Blocks/Hero/LayoutSchema
76
+ msgid "Fixed layout"
77
+ msgstr ""
78
+
79
+ #. Default: "Fixed layout, New panes (tabs) created by Editor within this block will be ignored"
80
+ #: components/Blocks/Hero/LayoutSchema
81
+ msgid "Fixed layout, New panes (tabs) created by Editor within this block will be ignored"
82
+ msgstr ""
83
+
84
+ #. Default: "Fixed position"
85
+ #: components/Blocks/Hero/LayoutSchema
86
+ msgid "Fixed position"
87
+ msgstr ""
88
+
89
+ #. Default: "Helper text"
90
+ #: components/Blocks/Hero/LayoutSchema
91
+ msgid "Helper text"
92
+ msgstr ""
93
+
94
+ #. Default: "Hero"
95
+ #: components/Blocks/Hero/index
96
+ msgid "Hero"
97
+ msgstr ""
98
+
99
+ #. Default: "Hero block settings"
100
+ #: components/Blocks/Hero/LayoutSchema
101
+ msgid "Hero block settings"
102
+ msgstr ""
103
+
104
+ #. Default: "Hide all block related buttons within this block"
105
+ #: components/Blocks/Hero/LayoutSchema
106
+ msgid "Hide all block related buttons within this block"
107
+ msgstr ""
108
+
109
+ #. Default: "Instructions"
110
+ #: components/Blocks/Hero/LayoutSchema
111
+ msgid "Instructions"
112
+ msgstr ""
113
+
114
+ #. Default: "Read-only"
115
+ #: components/Blocks/Hero/LayoutSchema
116
+ msgid "Read-only"
117
+ msgstr ""
118
+
119
+ #. Default: "Read-only settings"
120
+ #: components/Blocks/Hero/LayoutSchema
121
+ msgid "Read-only settings"
122
+ msgstr ""
123
+
124
+ #. Default: "Read-only titles"
125
+ #: components/Blocks/Hero/LayoutSchema
126
+ msgid "Read-only titles"
127
+ msgstr ""
128
+
129
+ #. Default: "Required"
130
+ #: components/Blocks/Hero/LayoutSchema
131
+ msgid "Required"
132
+ msgstr ""
@@ -11,4 +11,122 @@ msgstr ""
11
11
  "Content-Transfer-Encoding: \n"
12
12
  "Plural-Forms: \n"
13
13
 
14
+ #. Default: "A short hint that describes the expected value within this block"
15
+ #: components/Blocks/Hero/LayoutSchema
16
+ msgid "A short hint that describes the expected value within this block"
17
+ msgstr ""
18
+
19
+ #. Default: "Allow only the following blocks types"
20
+ #: components/Blocks/Hero/LayoutSchema
21
+ msgid "Allow only the following blocks types"
22
+ msgstr ""
23
+
24
+ #. Default: "Default"
25
+ #: components/Blocks/Hero/LayoutSchema
26
+ msgid "Default"
27
+ msgstr ""
28
+
29
+ #. Default: "Detailed expected value within this block"
30
+ #: components/Blocks/Hero/LayoutSchema
31
+ msgid "Detailed expected value within this block"
32
+ msgstr ""
33
+
34
+ #. Default: "Disable creation of new blocks after this block"
35
+ #: components/Blocks/Hero/LayoutSchema
36
+ msgid "Disable creation of new blocks after this block"
37
+ msgstr ""
38
+
39
+ #. Default: "Disable drag & drop on this block"
40
+ #: components/Blocks/Hero/LayoutSchema
41
+ msgid "Disable drag & drop on this block"
42
+ msgstr ""
43
+
44
+ #. Default: "Disable editing on hero block settings"
45
+ #: components/Blocks/Hero/LayoutSchema
46
+ msgid "Disable editing on hero block settings"
47
+ msgstr ""
48
+
49
+ #. Default: "Disable editing on hero titles"
50
+ #: components/Blocks/Hero/LayoutSchema
51
+ msgid "Disable editing on hero titles"
52
+ msgstr ""
53
+
54
+ #. Default: "Disable editing on this block"
55
+ #: components/Blocks/Hero/LayoutSchema
56
+ msgid "Disable editing on this block"
57
+ msgstr ""
58
+
59
+ #. Default: "Disable inner buttons"
60
+ #: components/Blocks/Hero/LayoutSchema
61
+ msgid "Disable inner buttons"
62
+ msgstr ""
63
+
64
+ #. Default: "Disable new blocks"
65
+ #: components/Blocks/Hero/LayoutSchema
66
+ msgid "Disable new blocks"
67
+ msgstr ""
68
+
69
+ #. Default: "Don't allow deletion of this block"
70
+ #: components/Blocks/Hero/LayoutSchema
71
+ msgid "Don't allow deletion of this block"
72
+ msgstr ""
14
73
 
74
+ #. Default: "Fixed layout"
75
+ #: components/Blocks/Hero/LayoutSchema
76
+ msgid "Fixed layout"
77
+ msgstr ""
78
+
79
+ #. Default: "Fixed layout, New panes (tabs) created by Editor within this block will be ignored"
80
+ #: components/Blocks/Hero/LayoutSchema
81
+ msgid "Fixed layout, New panes (tabs) created by Editor within this block will be ignored"
82
+ msgstr ""
83
+
84
+ #. Default: "Fixed position"
85
+ #: components/Blocks/Hero/LayoutSchema
86
+ msgid "Fixed position"
87
+ msgstr ""
88
+
89
+ #. Default: "Helper text"
90
+ #: components/Blocks/Hero/LayoutSchema
91
+ msgid "Helper text"
92
+ msgstr ""
93
+
94
+ #. Default: "Hero"
95
+ #: components/Blocks/Hero/index
96
+ msgid "Hero"
97
+ msgstr ""
98
+
99
+ #. Default: "Hero block settings"
100
+ #: components/Blocks/Hero/LayoutSchema
101
+ msgid "Hero block settings"
102
+ msgstr ""
103
+
104
+ #. Default: "Hide all block related buttons within this block"
105
+ #: components/Blocks/Hero/LayoutSchema
106
+ msgid "Hide all block related buttons within this block"
107
+ msgstr ""
108
+
109
+ #. Default: "Instructions"
110
+ #: components/Blocks/Hero/LayoutSchema
111
+ msgid "Instructions"
112
+ msgstr ""
113
+
114
+ #. Default: "Read-only"
115
+ #: components/Blocks/Hero/LayoutSchema
116
+ msgid "Read-only"
117
+ msgstr ""
118
+
119
+ #. Default: "Read-only settings"
120
+ #: components/Blocks/Hero/LayoutSchema
121
+ msgid "Read-only settings"
122
+ msgstr ""
123
+
124
+ #. Default: "Read-only titles"
125
+ #: components/Blocks/Hero/LayoutSchema
126
+ msgid "Read-only titles"
127
+ msgstr ""
128
+
129
+ #. Default: "Required"
130
+ #: components/Blocks/Hero/LayoutSchema
131
+ msgid "Required"
132
+ msgstr ""
@@ -11,4 +11,122 @@ msgstr ""
11
11
  "Content-Transfer-Encoding: \n"
12
12
  "Plural-Forms: \n"
13
13
 
14
+ #. Default: "A short hint that describes the expected value within this block"
15
+ #: components/Blocks/Hero/LayoutSchema
16
+ msgid "A short hint that describes the expected value within this block"
17
+ msgstr ""
18
+
19
+ #. Default: "Allow only the following blocks types"
20
+ #: components/Blocks/Hero/LayoutSchema
21
+ msgid "Allow only the following blocks types"
22
+ msgstr ""
23
+
24
+ #. Default: "Default"
25
+ #: components/Blocks/Hero/LayoutSchema
26
+ msgid "Default"
27
+ msgstr ""
28
+
29
+ #. Default: "Detailed expected value within this block"
30
+ #: components/Blocks/Hero/LayoutSchema
31
+ msgid "Detailed expected value within this block"
32
+ msgstr ""
33
+
34
+ #. Default: "Disable creation of new blocks after this block"
35
+ #: components/Blocks/Hero/LayoutSchema
36
+ msgid "Disable creation of new blocks after this block"
37
+ msgstr ""
38
+
39
+ #. Default: "Disable drag & drop on this block"
40
+ #: components/Blocks/Hero/LayoutSchema
41
+ msgid "Disable drag & drop on this block"
42
+ msgstr ""
43
+
44
+ #. Default: "Disable editing on hero block settings"
45
+ #: components/Blocks/Hero/LayoutSchema
46
+ msgid "Disable editing on hero block settings"
47
+ msgstr ""
48
+
49
+ #. Default: "Disable editing on hero titles"
50
+ #: components/Blocks/Hero/LayoutSchema
51
+ msgid "Disable editing on hero titles"
52
+ msgstr ""
53
+
54
+ #. Default: "Disable editing on this block"
55
+ #: components/Blocks/Hero/LayoutSchema
56
+ msgid "Disable editing on this block"
57
+ msgstr ""
58
+
59
+ #. Default: "Disable inner buttons"
60
+ #: components/Blocks/Hero/LayoutSchema
61
+ msgid "Disable inner buttons"
62
+ msgstr ""
63
+
64
+ #. Default: "Disable new blocks"
65
+ #: components/Blocks/Hero/LayoutSchema
66
+ msgid "Disable new blocks"
67
+ msgstr ""
68
+
69
+ #. Default: "Don't allow deletion of this block"
70
+ #: components/Blocks/Hero/LayoutSchema
71
+ msgid "Don't allow deletion of this block"
72
+ msgstr ""
14
73
 
74
+ #. Default: "Fixed layout"
75
+ #: components/Blocks/Hero/LayoutSchema
76
+ msgid "Fixed layout"
77
+ msgstr ""
78
+
79
+ #. Default: "Fixed layout, New panes (tabs) created by Editor within this block will be ignored"
80
+ #: components/Blocks/Hero/LayoutSchema
81
+ msgid "Fixed layout, New panes (tabs) created by Editor within this block will be ignored"
82
+ msgstr ""
83
+
84
+ #. Default: "Fixed position"
85
+ #: components/Blocks/Hero/LayoutSchema
86
+ msgid "Fixed position"
87
+ msgstr ""
88
+
89
+ #. Default: "Helper text"
90
+ #: components/Blocks/Hero/LayoutSchema
91
+ msgid "Helper text"
92
+ msgstr ""
93
+
94
+ #. Default: "Hero"
95
+ #: components/Blocks/Hero/index
96
+ msgid "Hero"
97
+ msgstr ""
98
+
99
+ #. Default: "Hero block settings"
100
+ #: components/Blocks/Hero/LayoutSchema
101
+ msgid "Hero block settings"
102
+ msgstr ""
103
+
104
+ #. Default: "Hide all block related buttons within this block"
105
+ #: components/Blocks/Hero/LayoutSchema
106
+ msgid "Hide all block related buttons within this block"
107
+ msgstr ""
108
+
109
+ #. Default: "Instructions"
110
+ #: components/Blocks/Hero/LayoutSchema
111
+ msgid "Instructions"
112
+ msgstr ""
113
+
114
+ #. Default: "Read-only"
115
+ #: components/Blocks/Hero/LayoutSchema
116
+ msgid "Read-only"
117
+ msgstr ""
118
+
119
+ #. Default: "Read-only settings"
120
+ #: components/Blocks/Hero/LayoutSchema
121
+ msgid "Read-only settings"
122
+ msgstr ""
123
+
124
+ #. Default: "Read-only titles"
125
+ #: components/Blocks/Hero/LayoutSchema
126
+ msgid "Read-only titles"
127
+ msgstr ""
128
+
129
+ #. Default: "Required"
130
+ #: components/Blocks/Hero/LayoutSchema
131
+ msgid "Required"
132
+ msgstr ""
package/locales/volto.pot CHANGED
@@ -1,16 +1,134 @@
1
1
  msgid ""
2
2
  msgstr ""
3
3
  "Project-Id-Version: Plone\n"
4
- "POT-Creation-Date: 2023-06-28T10:48:22.678Z\n"
4
+ "POT-Creation-Date: 2026-03-10T22:13:14.190Z\n"
5
5
  "Last-Translator: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
6
6
  "Language-Team: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
7
- "MIME-Version: 1.0\n"
8
7
  "Content-Type: text/plain; charset=utf-8\n"
9
8
  "Content-Transfer-Encoding: 8bit\n"
10
9
  "Plural-Forms: nplurals=1; plural=0;\n"
10
+ "MIME-Version: 1.0\n"
11
11
  "Language-Code: en\n"
12
12
  "Language-Name: English\n"
13
13
  "Preferred-Encodings: utf-8\n"
14
14
  "Domain: volto\n"
15
15
 
16
+ #. Default: "A short hint that describes the expected value within this block"
17
+ #: components/Blocks/Hero/LayoutSchema
18
+ msgid "A short hint that describes the expected value within this block"
19
+ msgstr ""
20
+
21
+ #. Default: "Allow only the following blocks types"
22
+ #: components/Blocks/Hero/LayoutSchema
23
+ msgid "Allow only the following blocks types"
24
+ msgstr ""
25
+
26
+ #. Default: "Default"
27
+ #: components/Blocks/Hero/LayoutSchema
28
+ msgid "Default"
29
+ msgstr ""
30
+
31
+ #. Default: "Detailed expected value within this block"
32
+ #: components/Blocks/Hero/LayoutSchema
33
+ msgid "Detailed expected value within this block"
34
+ msgstr ""
35
+
36
+ #. Default: "Disable creation of new blocks after this block"
37
+ #: components/Blocks/Hero/LayoutSchema
38
+ msgid "Disable creation of new blocks after this block"
39
+ msgstr ""
40
+
41
+ #. Default: "Disable drag & drop on this block"
42
+ #: components/Blocks/Hero/LayoutSchema
43
+ msgid "Disable drag & drop on this block"
44
+ msgstr ""
45
+
46
+ #. Default: "Disable editing on hero block settings"
47
+ #: components/Blocks/Hero/LayoutSchema
48
+ msgid "Disable editing on hero block settings"
49
+ msgstr ""
50
+
51
+ #. Default: "Disable editing on hero titles"
52
+ #: components/Blocks/Hero/LayoutSchema
53
+ msgid "Disable editing on hero titles"
54
+ msgstr ""
55
+
56
+ #. Default: "Disable editing on this block"
57
+ #: components/Blocks/Hero/LayoutSchema
58
+ msgid "Disable editing on this block"
59
+ msgstr ""
60
+
61
+ #. Default: "Disable inner buttons"
62
+ #: components/Blocks/Hero/LayoutSchema
63
+ msgid "Disable inner buttons"
64
+ msgstr ""
65
+
66
+ #. Default: "Disable new blocks"
67
+ #: components/Blocks/Hero/LayoutSchema
68
+ msgid "Disable new blocks"
69
+ msgstr ""
70
+
71
+ #. Default: "Don't allow deletion of this block"
72
+ #: components/Blocks/Hero/LayoutSchema
73
+ msgid "Don't allow deletion of this block"
74
+ msgstr ""
75
+
76
+ #. Default: "Fixed layout"
77
+ #: components/Blocks/Hero/LayoutSchema
78
+ msgid "Fixed layout"
79
+ msgstr ""
80
+
81
+ #. Default: "Fixed layout, New panes (tabs) created by Editor within this block will be ignored"
82
+ #: components/Blocks/Hero/LayoutSchema
83
+ msgid "Fixed layout, New panes (tabs) created by Editor within this block will be ignored"
84
+ msgstr ""
85
+
86
+ #. Default: "Fixed position"
87
+ #: components/Blocks/Hero/LayoutSchema
88
+ msgid "Fixed position"
89
+ msgstr ""
90
+
91
+ #. Default: "Helper text"
92
+ #: components/Blocks/Hero/LayoutSchema
93
+ msgid "Helper text"
94
+ msgstr ""
95
+
96
+ #. Default: "Hero"
97
+ #: components/Blocks/Hero/index
98
+ msgid "Hero"
99
+ msgstr ""
100
+
101
+ #. Default: "Hero block settings"
102
+ #: components/Blocks/Hero/LayoutSchema
103
+ msgid "Hero block settings"
104
+ msgstr ""
105
+
106
+ #. Default: "Hide all block related buttons within this block"
107
+ #: components/Blocks/Hero/LayoutSchema
108
+ msgid "Hide all block related buttons within this block"
109
+ msgstr ""
110
+
111
+ #. Default: "Instructions"
112
+ #: components/Blocks/Hero/LayoutSchema
113
+ msgid "Instructions"
114
+ msgstr ""
115
+
116
+ #. Default: "Read-only"
117
+ #: components/Blocks/Hero/LayoutSchema
118
+ msgid "Read-only"
119
+ msgstr ""
120
+
121
+ #. Default: "Read-only settings"
122
+ #: components/Blocks/Hero/LayoutSchema
123
+ msgid "Read-only settings"
124
+ msgstr ""
16
125
 
126
+ #. Default: "Read-only titles"
127
+ #: components/Blocks/Hero/LayoutSchema
128
+ msgid "Read-only titles"
129
+ msgstr ""
130
+
131
+ #. Default: "Required"
132
+ #: components/Blocks/Hero/LayoutSchema
133
+ msgid "Required"
134
+ msgstr ""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-hero-block",
3
- "version": "8.0.0",
3
+ "version": "9.0.0",
4
4
  "description": "@eeacms/volto-hero-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -4,7 +4,7 @@ import { Icon } from 'semantic-ui-react';
4
4
  import { Provider } from 'react-intl-redux';
5
5
  import configureStore from 'redux-mock-store';
6
6
  import config from '@plone/volto/registry';
7
- import '@testing-library/jest-dom/extend-expect';
7
+ import '@testing-library/jest-dom';
8
8
 
9
9
  import Copyright from './Copyright';
10
10
 
@@ -4,7 +4,6 @@ import isFunction from 'lodash/isFunction';
4
4
  import { Icon } from 'semantic-ui-react';
5
5
  import config from '@plone/volto/registry';
6
6
  import { BlocksForm } from '@plone/volto/components';
7
- import EditBlockWrapper from '@plone/volto/components/manage/Blocks/Block/EditBlockWrapper';
8
7
  import { v4 as uuid } from 'uuid';
9
8
  import '@eeacms/volto-hero-block/components/Blocks/Hero/edit.css';
10
9
 
@@ -140,17 +139,7 @@ export default function Edit(props) {
140
139
  }
141
140
  }}
142
141
  pathname={pathname}
143
- >
144
- {({ draginfo }, editBlock, blockProps) => (
145
- <EditBlockWrapper
146
- draginfo={draginfo}
147
- blockProps={blockProps}
148
- disabled={data.disableInnerButtons}
149
- >
150
- {editBlock}
151
- </EditBlockWrapper>
152
- )}
153
- </BlocksForm>
142
+ />
154
143
  </Hero.Text>
155
144
  <Hero.Meta {...data}>
156
145
  <Metadata {...data} />
@@ -5,7 +5,7 @@ import { IntlProvider } from 'react-intl';
5
5
  import configureStore from 'redux-mock-store';
6
6
  import Edit from './Edit';
7
7
  import config from '@plone/volto/registry';
8
- import '@testing-library/jest-dom/extend-expect';
8
+ import '@testing-library/jest-dom';
9
9
 
10
10
  // Mock uuid to avoid node:crypto import issues
11
11
  jest.mock('uuid', () => ({
@@ -19,12 +19,9 @@ const disconnect = jest.fn();
19
19
  jest.mock('@plone/volto/components', () => {
20
20
  return {
21
21
  __esModule: true,
22
- BlocksForm: ({ placeholder, children, onChange, onFocus }) => (
22
+ BlocksForm: ({ placeholder }) => (
23
23
  <div id="test">
24
24
  <div>{placeholder}</div>
25
- {typeof children === 'function'
26
- ? children({}, <div>Mock Edit Block</div>, {})
27
- : children}
28
25
  </div>
29
26
  ),
30
27
  SidebarPortal: ({ children }) => <div>{children}</div>,
@@ -33,15 +30,6 @@ jest.mock('@plone/volto/components', () => {
33
30
  RenderBlocks: () => <div></div>,
34
31
  };
35
32
  });
36
-
37
- jest.mock(
38
- '@plone/volto/components/manage/Blocks/Block/EditBlockWrapper',
39
- () => {
40
- return ({ children }) => (
41
- <div className="edit-block-wrapper">{children}</div>
42
- );
43
- },
44
- );
45
33
  jest.mock('react-router-dom', () => ({
46
34
  useLocation: jest.fn().mockReturnValue({
47
35
  pathname: '/test-jest',
@@ -3,7 +3,7 @@ import { render } from '@testing-library/react';
3
3
  import { Provider } from 'react-intl-redux';
4
4
  import configureStore from 'redux-mock-store';
5
5
  import config from '@plone/volto/registry';
6
- import '@testing-library/jest-dom/extend-expect';
6
+ import '@testing-library/jest-dom';
7
7
 
8
8
  import Hero from './Hero';
9
9
 
@@ -0,0 +1,20 @@
1
+ const noop = () => null;
2
+
3
+ module.exports = {
4
+ minLengthValidator: noop,
5
+ maxLengthValidator: noop,
6
+ urlValidator: noop,
7
+ emailValidator: noop,
8
+ isNumberValidator: noop,
9
+ maximumValidator: noop,
10
+ minimumValidator: noop,
11
+ isIntegerValidator: noop,
12
+ maxItemsValidator: noop,
13
+ minItemsValidator: noop,
14
+ hasUniqueItemsValidator: noop,
15
+ startEventDateRangeValidator: noop,
16
+ endEventDateRangeValidator: noop,
17
+ patternValidator: noop,
18
+ defaultLanguageControlPanelValidator: noop,
19
+ sizeValidator: noop,
20
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "paths": {
5
+ "@plone/volto/helpers/FormValidation/validators": [
6
+ "node_modules/@plone/volto/src/helpers/FormValidation/validators.ts"
7
+ ]
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,34 @@
1
+ declare module '@plone/volto/helpers/FormValidation/validators' {
2
+ export const minLengthValidator: (...args: any[]) => any;
3
+ export const maxLengthValidator: (...args: any[]) => any;
4
+ export const urlValidator: (...args: any[]) => any;
5
+ export const emailValidator: (...args: any[]) => any;
6
+ export const isNumberValidator: (...args: any[]) => any;
7
+ export const maximumValidator: (...args: any[]) => any;
8
+ export const minimumValidator: (...args: any[]) => any;
9
+ export const isIntegerValidator: (...args: any[]) => any;
10
+ export const maxItemsValidator: (...args: any[]) => any;
11
+ export const minItemsValidator: (...args: any[]) => any;
12
+ export const hasUniqueItemsValidator: (...args: any[]) => any;
13
+ export const startEventDateRangeValidator: (...args: any[]) => any;
14
+ export const endEventDateRangeValidator: (...args: any[]) => any;
15
+ export const patternValidator: (...args: any[]) => any;
16
+ export const defaultLanguageControlPanelValidator: (...args: any[]) => any;
17
+ export const sizeValidator: (...args: any[]) => any;
18
+ }
19
+
20
+ declare module 'react-router-hash-link' {
21
+ export const HashLink: any;
22
+ }
23
+
24
+ declare module '@plone/volto/helpers/Url/Url' {
25
+ export const flattenToAppURL: (...args: any[]) => any;
26
+ export const isInternalURL: (...args: any[]) => any;
27
+ export const getFieldURL: (...args: any[]) => any;
28
+ export const URLUtils: any;
29
+ }
30
+
31
+ declare module '@plone/volto/registry' {
32
+ const config: any;
33
+ export default config;
34
+ }