@ckeditor/ckeditor5-template 38.1.0 → 38.1.1

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/src/template.d.ts CHANGED
@@ -1,115 +1,115 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
- */
5
- /**
6
- * @module template/template
7
- * @publicApi
8
- */
9
- import { Plugin } from 'ckeditor5/src/core';
10
- import TemplateEditing from './templateediting';
11
- import TemplateUI from './templateui';
12
- /**
13
- * The template feature.
14
- *
15
- * For a detailed overview, check the {@glink features/template Content templates} feature guide.
16
- */
17
- export default class Template extends Plugin {
18
- /**
19
- * @inheritDoc
20
- */
21
- static get requires(): readonly [typeof TemplateEditing, typeof TemplateUI];
22
- /**
23
- * @inheritDoc
24
- */
25
- static get pluginName(): "Template";
26
- }
27
- /**
28
- * The configuration of the template feature.
29
- *
30
- * ```ts
31
- * ClassicEditor
32
- * .create( {
33
- * template: ... // Template feature configuration.
34
- * } )
35
- * .then( ... )
36
- * .catch( ... );
37
- *```
38
- * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
39
- */
40
- export interface TemplateConfig {
41
- /**
42
- * A list of all template definitions to be displayed in the `'insertTemplate'` UI dropdown.
43
- *
44
- * An example configuration:
45
- *
46
- * ```json
47
- * {
48
- * template: {
49
- * definitions: [
50
- * {
51
- * title: 'Issue acknowledgement (plain text)',
52
- * data: 'Dear customer, thank you for your report! The issue is currently being worked on by our development team.'
53
- * },
54
- * {
55
- * title: 'Signature (multi-line)',
56
- * data: '<p><b>Jane Doe</b></p><p>Marketing Specialist at <a href="https://example.com>Example.com</a></p>',
57
- * description: 'Author signature with the link to the website.'
58
- * },
59
- * {
60
- * title: 'Example table',
61
- * data: '<table><tr><td>Cell #1</td><td></td></tr><tr><td></td><td>Cell #2</td></tr></table>',
62
- * icon: '<svg viewBox="0 0 45 45" xmlns="http://www.w3.org/2000/svg">...</svg>',
63
- * description: 'This template inserts a table.'
64
- * },
65
- * {
66
- * title: 'Insert userAgent data',
67
- * data: navigator.userAgent
68
- * },
69
- * {
70
- * title: 'Insert translate to English link (function)',
71
- * data: () => '<a href="' + location.href + '/en" title="Translate to English">Translate to English</a>'
72
- * },
73
- * // ...
74
- * ]
75
- * }
76
- * }
77
- * ```
78
- */
79
- definitions?: Array<TemplateDefinition>;
80
- }
81
- /**
82
- * An object describing a single template definition.
83
- *
84
- * ```json
85
- * {
86
- * // Mandatory fields:
87
- * title: 'Example template',
88
- * data: '<table><tr><td>Cell #1</td><td></td></tr><tr><td></td><td>Cell #2</td></tr></table>',
89
- *
90
- * // Optional configuration:
91
- * icon: '<svg viewBox="0 0 45 45" xmlns="http://www.w3.org/2000/svg">...</svg>',
92
- * description: 'This template inserts a table.'
93
- * }
94
- * ```
95
- */
96
- export type TemplateDefinition = {
97
- /**
98
- * The title of the template.
99
- */
100
- title: string;
101
- /**
102
- * An HTML string to be inserted into the document or a callback function that returns an HTML string
103
- * to be inserted into the document when the template is selected.
104
- */
105
- data: () => string | string;
106
- /**
107
- * An optional SVG string representing the icon of the template. The default size of the icon is 45x45 pixels.
108
- * Be sure to set the correct `viewBox` attribute in the icon source. If not provided, a generic icon will be used instead.
109
- */
110
- icon?: string;
111
- /**
112
- * An optional long description of the template presented to the users.
113
- */
114
- description?: string;
115
- };
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module template/template
7
+ * @publicApi
8
+ */
9
+ import { Plugin } from 'ckeditor5/src/core';
10
+ import TemplateEditing from './templateediting';
11
+ import TemplateUI from './templateui';
12
+ /**
13
+ * The template feature.
14
+ *
15
+ * For a detailed overview, check the {@glink features/template Content templates} feature guide.
16
+ */
17
+ export default class Template extends Plugin {
18
+ /**
19
+ * @inheritDoc
20
+ */
21
+ static get requires(): readonly [typeof TemplateEditing, typeof TemplateUI];
22
+ /**
23
+ * @inheritDoc
24
+ */
25
+ static get pluginName(): "Template";
26
+ }
27
+ /**
28
+ * The configuration of the template feature.
29
+ *
30
+ * ```ts
31
+ * ClassicEditor
32
+ * .create( {
33
+ * template: ... // Template feature configuration.
34
+ * } )
35
+ * .then( ... )
36
+ * .catch( ... );
37
+ *```
38
+ * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
39
+ */
40
+ export interface TemplateConfig {
41
+ /**
42
+ * A list of all template definitions to be displayed in the `'insertTemplate'` UI dropdown.
43
+ *
44
+ * An example configuration:
45
+ *
46
+ * ```json
47
+ * {
48
+ * template: {
49
+ * definitions: [
50
+ * {
51
+ * title: 'Issue acknowledgement (plain text)',
52
+ * data: 'Dear customer, thank you for your report! The issue is currently being worked on by our development team.'
53
+ * },
54
+ * {
55
+ * title: 'Signature (multi-line)',
56
+ * data: '<p><b>Jane Doe</b></p><p>Marketing Specialist at <a href="https://example.com>Example.com</a></p>',
57
+ * description: 'Author signature with the link to the website.'
58
+ * },
59
+ * {
60
+ * title: 'Example table',
61
+ * data: '<table><tr><td>Cell #1</td><td></td></tr><tr><td></td><td>Cell #2</td></tr></table>',
62
+ * icon: '<svg viewBox="0 0 45 45" xmlns="http://www.w3.org/2000/svg">...</svg>',
63
+ * description: 'This template inserts a table.'
64
+ * },
65
+ * {
66
+ * title: 'Insert userAgent data',
67
+ * data: navigator.userAgent
68
+ * },
69
+ * {
70
+ * title: 'Insert translate to English link (function)',
71
+ * data: () => '<a href="' + location.href + '/en" title="Translate to English">Translate to English</a>'
72
+ * },
73
+ * // ...
74
+ * ]
75
+ * }
76
+ * }
77
+ * ```
78
+ */
79
+ definitions?: Array<TemplateDefinition>;
80
+ }
81
+ /**
82
+ * An object describing a single template definition.
83
+ *
84
+ * ```json
85
+ * {
86
+ * // Mandatory fields:
87
+ * title: 'Example template',
88
+ * data: '<table><tr><td>Cell #1</td><td></td></tr><tr><td></td><td>Cell #2</td></tr></table>',
89
+ *
90
+ * // Optional configuration:
91
+ * icon: '<svg viewBox="0 0 45 45" xmlns="http://www.w3.org/2000/svg">...</svg>',
92
+ * description: 'This template inserts a table.'
93
+ * }
94
+ * ```
95
+ */
96
+ export type TemplateDefinition = {
97
+ /**
98
+ * The title of the template.
99
+ */
100
+ title: string;
101
+ /**
102
+ * An HTML string to be inserted into the document or a callback function that returns an HTML string
103
+ * to be inserted into the document when the template is selected.
104
+ */
105
+ data: () => string | string;
106
+ /**
107
+ * An optional SVG string representing the icon of the template. The default size of the icon is 45x45 pixels.
108
+ * Be sure to set the correct `viewBox` attribute in the icon source. If not provided, a generic icon will be used instead.
109
+ */
110
+ icon?: string;
111
+ /**
112
+ * An optional long description of the template presented to the users.
113
+ */
114
+ description?: string;
115
+ };
package/src/template.js CHANGED
@@ -20,4 +20,4 @@
20
20
  *
21
21
  *
22
22
  */
23
- var _0x4a42=['pluginName','Template'];(function(_0x425919,_0x4a4294){var _0x58c4c5=function(_0x3a466c){while(--_0x3a466c){_0x425919['push'](_0x425919['shift']());}};_0x58c4c5(++_0x4a4294);}(_0x4a42,0x17a));var _0x58c4=function(_0x425919,_0x4a4294){_0x425919=_0x425919-0x0;var _0x58c4c5=_0x4a42[_0x425919];return _0x58c4c5;};import{Plugin as _0x57abe4}from'ckeditor5/src/core';import _0x1267d8 from'./templateediting';import _0x38a4d8 from'./templateui';export default class o extends _0x57abe4{static get['requires'](){return[_0x1267d8,_0x38a4d8];}static get[_0x58c4('0x0')](){return _0x58c4('0x1');}}
23
+ var _0x5aa7=['requires','pluginName'];(function(_0x38d479,_0x5aa7ab){var _0x3e5be0=function(_0x1a4bf7){while(--_0x1a4bf7){_0x38d479['push'](_0x38d479['shift']());}};_0x3e5be0(++_0x5aa7ab);}(_0x5aa7,0x152));var _0x3e5b=function(_0x38d479,_0x5aa7ab){_0x38d479=_0x38d479-0x0;var _0x3e5be0=_0x5aa7[_0x38d479];return _0x3e5be0;};import{Plugin as _0x2518bb}from'ckeditor5/src/core';import _0x329a49 from'./templateediting';import _0x53807f from'./templateui';export default class o extends _0x2518bb{static get[_0x3e5b('0x0')](){return[_0x329a49,_0x53807f];}static get[_0x3e5b('0x1')](){return'Template';}}
@@ -1,23 +1,23 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
- */
5
- /**
6
- * @module template/templatecommand
7
- * @publicApi
8
- */
9
- import { Command } from 'ckeditor5/src/core';
10
- /**
11
- * The template command.
12
- *
13
- * Inserts a template into the editor content.
14
- */
15
- export default class TemplateCommand extends Command {
16
- /**
17
- * Inserts the template data at the position of the selection.
18
- *
19
- * @fires execute
20
- * @param templateData Template data should be a raw HTML string or a function that returns one.
21
- */
22
- execute(templateData: string | Function): void;
23
- }
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module template/templatecommand
7
+ * @publicApi
8
+ */
9
+ import { Command } from 'ckeditor5/src/core';
10
+ /**
11
+ * The template command.
12
+ *
13
+ * Inserts a template into the editor content.
14
+ */
15
+ export default class TemplateCommand extends Command {
16
+ /**
17
+ * Inserts the template data at the position of the selection.
18
+ *
19
+ * @fires execute
20
+ * @param templateData Template data should be a raw HTML string or a function that returns one.
21
+ */
22
+ execute(templateData: string | Function): void;
23
+ }
@@ -20,4 +20,4 @@
20
20
  *
21
21
  *
22
22
  */
23
- const _0x3f67=['editor','data','htmlProcessor','insertContent','function','toView','toModel','string'];(function(_0x5a5263,_0x3f67f2){const _0x1dc491=function(_0x56cd21){while(--_0x56cd21){_0x5a5263['push'](_0x5a5263['shift']());}};_0x1dc491(++_0x3f67f2);}(_0x3f67,0x1df));const _0x1dc4=function(_0x5a5263,_0x3f67f2){_0x5a5263=_0x5a5263-0x0;let _0x1dc491=_0x3f67[_0x5a5263];return _0x1dc491;};import{Command as _0x2bde36}from'ckeditor5/src/core';export default class c extends _0x2bde36{['execute'](_0x23e597){const {model:_0x52e816}=this[_0x1dc4('0x1')];let _0x9d145d;switch(typeof _0x23e597){case _0x1dc4('0x0'):_0x9d145d=_0x23e597;break;case _0x1dc4('0x5'):_0x9d145d=_0x23e597();}'string'==typeof _0x9d145d&&_0x52e816['change'](()=>{const _0x1aa8c6=this[_0x1dc4('0x1')][_0x1dc4('0x2')][_0x1dc4('0x3')][_0x1dc4('0x6')](_0x9d145d),_0xa31f74=this[_0x1dc4('0x1')][_0x1dc4('0x2')][_0x1dc4('0x7')](_0x1aa8c6);_0x52e816[_0x1dc4('0x4')](_0xa31f74);});}}
23
+ const _0x35f5=['toModel','insertContent','change','htmlProcessor','editor','string','toView','execute','data','function'];(function(_0x480526,_0x35f5f9){const _0x5bf33d=function(_0x2fa3e5){while(--_0x2fa3e5){_0x480526['push'](_0x480526['shift']());}};_0x5bf33d(++_0x35f5f9);}(_0x35f5,0x192));const _0x5bf3=function(_0x480526,_0x35f5f9){_0x480526=_0x480526-0x0;let _0x5bf33d=_0x35f5[_0x480526];return _0x5bf33d;};import{Command as _0x14c676}from'ckeditor5/src/core';export default class c extends _0x14c676{[_0x5bf3('0x5')](_0x1eccbb){const {model:_0x4a8255}=this[_0x5bf3('0x2')];let _0x545043;switch(typeof _0x1eccbb){case _0x5bf3('0x3'):_0x545043=_0x1eccbb;break;case _0x5bf3('0x7'):_0x545043=_0x1eccbb();}_0x5bf3('0x3')==typeof _0x545043&&_0x4a8255[_0x5bf3('0x0')](()=>{const _0x1d22ba=this[_0x5bf3('0x2')][_0x5bf3('0x6')][_0x5bf3('0x1')][_0x5bf3('0x4')](_0x545043),_0x217943=this[_0x5bf3('0x2')][_0x5bf3('0x6')][_0x5bf3('0x8')](_0x1d22ba);_0x4a8255[_0x5bf3('0x9')](_0x217943);});}}
@@ -1,30 +1,30 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
- */
5
- /**
6
- * @module template/templateediting
7
- */
8
- import { Plugin, type Editor } from 'ckeditor5/src/core';
9
- /**
10
- * The template editing plugin.
11
- */
12
- export default class TemplateEditing extends Plugin {
13
- licenseKey: string;
14
- /**
15
- * @inheritDoc
16
- */
17
- static get pluginName(): "TemplateEditing";
18
- /**
19
- * @inheritDoc
20
- */
21
- constructor(editor: Editor);
22
- /**
23
- * @inheritDoc
24
- */
25
- init(): void;
26
- /**
27
- * @inheritDoc
28
- */
29
- destroy(): void;
30
- }
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module template/templateediting
7
+ */
8
+ import { Plugin, type Editor } from 'ckeditor5/src/core';
9
+ /**
10
+ * The template editing plugin.
11
+ */
12
+ export default class TemplateEditing extends Plugin {
13
+ licenseKey: string;
14
+ /**
15
+ * @inheritDoc
16
+ */
17
+ static get pluginName(): "TemplateEditing";
18
+ /**
19
+ * @inheritDoc
20
+ */
21
+ constructor(editor: Editor);
22
+ /**
23
+ * @inheritDoc
24
+ */
25
+ init(): void;
26
+ /**
27
+ * @inheritDoc
28
+ */
29
+ destroy(): void;
30
+ }
@@ -20,4 +20,4 @@
20
20
  *
21
21
  *
22
22
  */
23
- const _0x2f32=['get','templateLicenseKeyTrialLimit:operations','info','add','templateLicenseKeyValid','init','licenseKey','templateLicenseKeyTrial','commands','template-trial-license-key-reached-limit-changes','templateLicenseKeyInvalid','pluginName','You\x20are\x20using\x20the\x20trial\x20version\x20of\x20CKEditor\x205\x20template\x20plugin\x20with\x20limited\x20usage.\x20Make\x20sure\x20you\x20will\x20not\x20use\x20it\x20in\x20the\x20production\x20environment.','destroy','insertTemplate','config','editor','_licenseKeyCheckInterval'];(function(_0x21c6bd,_0x2f32e5){const _0x487dbd=function(_0x12a2c1){while(--_0x12a2c1){_0x21c6bd['push'](_0x21c6bd['shift']());}};_0x487dbd(++_0x2f32e5);}(_0x2f32,0xf1));const _0x487d=function(_0x21c6bd,_0x2f32e5){_0x21c6bd=_0x21c6bd-0x0;let _0x487dbd=_0x2f32[_0x21c6bd];return _0x487dbd;};import{Plugin as _0x179d17}from'ckeditor5/src/core';import{CKEditorError as _0xe12638}from'ckeditor5/src/utils';import _0x3eb1ff from'./templatecommand';export default class i extends _0x179d17{static get[_0x487d('0x4')](){return'TemplateEditing';}constructor(_0x12846a){super(_0x12846a),this[_0x487d('0xa')]=null;}[_0x487d('0x10')](){const {editor:_0x2cf66c}=this;_0x2cf66c[_0x487d('0x1')][_0x487d('0xe')](_0x487d('0x7'),new _0x3eb1ff(_0x2cf66c)),this[_0x487d('0x11')]=_0x2cf66c[_0x487d('0x8')][_0x487d('0xb')](_0x487d('0x11'));const _0x503f38=this[_0x487d('0x9')];this[_0x487d('0xa')]=setInterval(()=>{let _0x314e14;for(const _0x202313 in _0x503f38){const _0xeb9c82=_0x202313,_0x3298f9=_0x503f38[_0xeb9c82];if(_0x487d('0x0')===_0x3298f9||_0x487d('0x3')===_0x3298f9||_0x487d('0xf')===_0x3298f9||_0x487d('0xc')===_0x3298f9){delete _0x503f38[_0xeb9c82],_0x314e14=_0x3298f9;break;}}if('templateLicenseKeyInvalid'===_0x314e14)throw clearInterval(this[_0x487d('0xa')]),new _0xe12638('template-invalid-license-key',null);if('templateLicenseKeyTrial'===_0x314e14&&console[_0x487d('0xd')](_0x487d('0x5')),_0x487d('0xc')===_0x314e14)throw clearInterval(this[_0x487d('0xa')]),new _0xe12638(_0x487d('0x2'),null);'templateLicenseKeyValid'===_0x314e14&&clearInterval(this[_0x487d('0xa')]);},0x3e8);}[_0x487d('0x6')](){this[_0x487d('0xa')]&&clearInterval(this['_licenseKeyCheckInterval']);}}
23
+ const _0x3cb5=['template-trial-license-key-reached-limit-changes','TemplateEditing','init','You\x20are\x20using\x20the\x20trial\x20version\x20of\x20CKEditor\x205\x20template\x20plugin\x20with\x20limited\x20usage.\x20Make\x20sure\x20you\x20will\x20not\x20use\x20it\x20in\x20the\x20production\x20environment.','pluginName','info','templateLicenseKeyTrialLimit:operations','templateLicenseKeyTrial','templateLicenseKeyInvalid','templateLicenseKeyValid','config','destroy','template-invalid-license-key','_licenseKeyCheckInterval','commands','insertTemplate'];(function(_0x3da780,_0x3cb5f8){const _0x274837=function(_0x4cb3fd){while(--_0x4cb3fd){_0x3da780['push'](_0x3da780['shift']());}};_0x274837(++_0x3cb5f8);}(_0x3cb5,0x167));const _0x2748=function(_0x3da780,_0x3cb5f8){_0x3da780=_0x3da780-0x0;let _0x274837=_0x3cb5[_0x3da780];return _0x274837;};import{Plugin as _0x22794f}from'ckeditor5/src/core';import{CKEditorError as _0x9066e8}from'ckeditor5/src/utils';import _0x34927b from'./templatecommand';export default class i extends _0x22794f{static get[_0x2748('0xd')](){return _0x2748('0xa');}constructor(_0x569ebf){super(_0x569ebf),this[_0x2748('0x6')]=null;}[_0x2748('0xb')](){const {editor:_0x191448}=this;_0x191448[_0x2748('0x7')]['add'](_0x2748('0x8'),new _0x34927b(_0x191448)),this['licenseKey']=_0x191448[_0x2748('0x3')]['get']('licenseKey');const _0x4a62d7=this['editor'];this[_0x2748('0x6')]=setInterval(()=>{let _0x23d835;for(const _0x8bdf08 in _0x4a62d7){const _0x447c78=_0x8bdf08,_0x59487c=_0x4a62d7[_0x447c78];if(_0x2748('0x0')===_0x59487c||_0x2748('0x1')===_0x59487c||_0x2748('0x2')===_0x59487c||_0x2748('0xf')===_0x59487c){delete _0x4a62d7[_0x447c78],_0x23d835=_0x59487c;break;}}if('templateLicenseKeyInvalid'===_0x23d835)throw clearInterval(this[_0x2748('0x6')]),new _0x9066e8(_0x2748('0x5'),null);if(_0x2748('0x0')===_0x23d835&&console[_0x2748('0xe')](_0x2748('0xc')),_0x2748('0xf')===_0x23d835)throw clearInterval(this[_0x2748('0x6')]),new _0x9066e8(_0x2748('0x9'),null);_0x2748('0x2')===_0x23d835&&clearInterval(this[_0x2748('0x6')]);},0x3e8);}[_0x2748('0x4')](){this[_0x2748('0x6')]&&clearInterval(this[_0x2748('0x6')]);}}
@@ -1,29 +1,29 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
- */
5
- /**
6
- * @module template/templateui
7
- */
8
- import { Plugin } from 'ckeditor5/src/core';
9
- import '../theme/template.css';
10
- /**
11
- * The UI plugin of the template feature.
12
- *
13
- * It registers the `'insertTemplate'` UI dropdown in the editor's {@link module:ui/componentfactory~ComponentFactory component factory}
14
- * that displays a list of templates and allows to insert them into the editor content.
15
- */
16
- export default class TemplateUI extends Plugin {
17
- /**
18
- * @inheritDoc
19
- */
20
- static get pluginName(): "TemplateUI";
21
- /**
22
- * @inheritDoc
23
- */
24
- init(): void;
25
- /**
26
- * @inheritDoc
27
- */
28
- afterInit(): void;
29
- }
1
+ /**
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ /**
6
+ * @module template/templateui
7
+ */
8
+ import { Plugin } from 'ckeditor5/src/core';
9
+ import '../theme/template.css';
10
+ /**
11
+ * The UI plugin of the template feature.
12
+ *
13
+ * It registers the `'insertTemplate'` UI dropdown in the editor's {@link module:ui/componentfactory~ComponentFactory component factory}
14
+ * that displays a list of templates and allows to insert them into the editor content.
15
+ */
16
+ export default class TemplateUI extends Plugin {
17
+ /**
18
+ * @inheritDoc
19
+ */
20
+ static get pluginName(): "TemplateUI";
21
+ /**
22
+ * @inheritDoc
23
+ */
24
+ init(): void;
25
+ /**
26
+ * @inheritDoc
27
+ */
28
+ afterInit(): void;
29
+ }