@srcker/editor-vue-next 1.0.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.
Files changed (95) hide show
  1. package/.vscode/extensions.json +3 -0
  2. package/README.md +50 -0
  3. package/index.html +13 -0
  4. package/index.ts +11 -0
  5. package/jsconfig.json +8 -0
  6. package/package.json +69 -0
  7. package/public/favicon.ico +0 -0
  8. package/src/App.vue +9 -0
  9. package/src/App.vue.js +17 -0
  10. package/src/Button/BackgroundButton.vue +331 -0
  11. package/src/Button/BackgroundButton.vue.js +243 -0
  12. package/src/Button/BlockQuoteButton.vue +26 -0
  13. package/src/Button/BlockQuoteButton.vue.js +56 -0
  14. package/src/Button/BoldButton.vue +29 -0
  15. package/src/Button/BoldButton.vue.js +56 -0
  16. package/src/Button/BulletListButton.vue +114 -0
  17. package/src/Button/BulletListButton.vue.js +147 -0
  18. package/src/Button/CodeBlockButton.vue +28 -0
  19. package/src/Button/CodeBlockButton.vue.js +56 -0
  20. package/src/Button/CodeButton.vue +30 -0
  21. package/src/Button/CodeButton.vue.js +56 -0
  22. package/src/Button/FontSizeButton.vue +85 -0
  23. package/src/Button/FontSizeButton.vue.js +131 -0
  24. package/src/Button/FormatButton.vue +25 -0
  25. package/src/Button/FormatButton.vue.js +54 -0
  26. package/src/Button/HeadingButton.vue +103 -0
  27. package/src/Button/HeadingButton.vue.js +164 -0
  28. package/src/Button/ImageUploadButton.vue +93 -0
  29. package/src/Button/ImageUploadButton.vue.js +123 -0
  30. package/src/Button/IndentLeftButton.vue +25 -0
  31. package/src/Button/IndentLeftButton.vue.js +54 -0
  32. package/src/Button/IndentRightButton.vue +29 -0
  33. package/src/Button/IndentRightButton.vue.js +54 -0
  34. package/src/Button/ItalicButton.vue +29 -0
  35. package/src/Button/ItalicButton.vue.js +56 -0
  36. package/src/Button/LineHeightButton.vue +88 -0
  37. package/src/Button/LineHeightButton.vue.js +131 -0
  38. package/src/Button/LinkButton.vue +44 -0
  39. package/src/Button/LinkButton.vue.js +69 -0
  40. package/src/Button/OrderedListButton.vue +121 -0
  41. package/src/Button/OrderedListButton.vue.js +146 -0
  42. package/src/Button/RedoButton.vue +29 -0
  43. package/src/Button/RedoButton.vue.js +55 -0
  44. package/src/Button/StrikeButton.vue +30 -0
  45. package/src/Button/StrikeButton.vue.js +56 -0
  46. package/src/Button/SubscriptButton.vue +29 -0
  47. package/src/Button/SubscriptButton.vue.js +56 -0
  48. package/src/Button/SuperscriptButton.vue +29 -0
  49. package/src/Button/SuperscriptButton.vue.js +56 -0
  50. package/src/Button/TextAlignCenterButton.vue +26 -0
  51. package/src/Button/TextAlignCenterButton.vue.js +56 -0
  52. package/src/Button/TextAlignLeftButton.vue +26 -0
  53. package/src/Button/TextAlignLeftButton.vue.js +56 -0
  54. package/src/Button/TextAlignRightButton.vue +26 -0
  55. package/src/Button/TextAlignRightButton.vue.js +56 -0
  56. package/src/Button/TextColorButton.vue +329 -0
  57. package/src/Button/TextColorButton.vue.js +243 -0
  58. package/src/Button/ThemeButton.vue +34 -0
  59. package/src/Button/ThemeButton.vue.js +63 -0
  60. package/src/Button/UnderLineButton.vue +29 -0
  61. package/src/Button/UnderLineButton.vue.js +56 -0
  62. package/src/Button/UndoButton.vue +29 -0
  63. package/src/Button/UndoButton.vue.js +55 -0
  64. package/src/Components/IconArrow.vue +16 -0
  65. package/src/Components/IconArrow.vue.js +30 -0
  66. package/src/Components/IconCheck.vue +40 -0
  67. package/src/Components/IconCheck.vue.js +59 -0
  68. package/src/EditorToolbar.vue +150 -0
  69. package/src/EditorToolbar.vue.js +306 -0
  70. package/src/Extensions/BulletListStyle.js +19 -0
  71. package/src/Extensions/BulletListStyle.ts +24 -0
  72. package/src/Extensions/FontSize.js +27 -0
  73. package/src/Extensions/FontSize.ts +37 -0
  74. package/src/Extensions/Indent.js +58 -0
  75. package/src/Extensions/Indent.ts +73 -0
  76. package/src/Extensions/OrderedListStyle.js +19 -0
  77. package/src/Extensions/OrderedListStyle.ts +24 -0
  78. package/src/Extensions/UploadImage.js +18 -0
  79. package/src/Extensions/UploadImage.ts +22 -0
  80. package/src/Extensions/shims.d.ts +26 -0
  81. package/src/RichEditor.vue +191 -0
  82. package/src/RichEditor.vue.js +199 -0
  83. package/src/env.d.ts +7 -0
  84. package/src/index.js +6 -0
  85. package/src/index.ts +11 -0
  86. package/src/main.js +4 -0
  87. package/src/main.ts +7 -0
  88. package/src/styles/style.scss +196 -0
  89. package/src/styles/theme.css +28 -0
  90. package/src/styles/variables.css +158 -0
  91. package/src/styles/variables.scss +175 -0
  92. package/src/types.js +1 -0
  93. package/src/types.ts +7 -0
  94. package/tsconfig.json +17 -0
  95. package/vite.config.ts +29 -0
@@ -0,0 +1,56 @@
1
+ const props = defineProps({
2
+ editor: {
3
+ type: Object,
4
+ required: true
5
+ }
6
+ });
7
+ const __VLS_ctx = {
8
+ ...{},
9
+ ...{},
10
+ ...{},
11
+ };
12
+ let __VLS_components;
13
+ let __VLS_intrinsics;
14
+ let __VLS_directives;
15
+ __VLS_asFunctionalElement1(__VLS_intrinsics.button, __VLS_intrinsics.button)({
16
+ ...{ onClick: (...[$event]) => {
17
+ __VLS_ctx.editor.chain().focus().toggleUnderline().run();
18
+ // @ts-ignore
19
+ [editor,];
20
+ } },
21
+ ...{ class: "icon-button" },
22
+ ...{ class: ({ 'active': __VLS_ctx.editor.isActive('underline') }) },
23
+ });
24
+ /** @type {__VLS_StyleScopedClasses['icon-button']} */ ;
25
+ /** @type {__VLS_StyleScopedClasses['active']} */ ;
26
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
27
+ ...{ class: "icon" },
28
+ });
29
+ /** @type {__VLS_StyleScopedClasses['icon']} */ ;
30
+ __VLS_asFunctionalElement1(__VLS_intrinsics.svg, __VLS_intrinsics.svg)({
31
+ xmlns: "http://www.w3.org/2000/svg",
32
+ viewBox: "0 0 512 512",
33
+ });
34
+ __VLS_asFunctionalElement1(__VLS_intrinsics.path)({
35
+ fill: "currentColor",
36
+ stroke: "currentColor",
37
+ 'stroke-width': "4",
38
+ 'stroke-linecap': "round",
39
+ 'stroke-linejoin': "round",
40
+ d: "M0 32C0 14.3 14.3 0 32 0L96 0c17.7 0 32 14.3 32 32S113.7 64 96 64l0 160c0 53 43 96 96 96s96-43 96-96l0-160c-17.7 0-32-14.3-32-32S270.3 0 288 0l64 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l0 160c0 88.4-71.6 160-160 160S32 312.4 32 224L32 64C14.3 64 0 49.7 0 32zM0 480c0-17.7 14.3-32 32-32l320 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 512c-17.7 0-32-14.3-32-32z",
41
+ });
42
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
43
+ ...{ class: "tips" },
44
+ });
45
+ /** @type {__VLS_StyleScopedClasses['tips']} */ ;
46
+ // @ts-ignore
47
+ [editor,];
48
+ const __VLS_export = (await import('vue')).defineComponent({
49
+ props: {
50
+ editor: {
51
+ type: Object,
52
+ required: true
53
+ }
54
+ },
55
+ });
56
+ export default {};
@@ -0,0 +1,29 @@
1
+ <template>
2
+ <button
3
+ class="icon-button"
4
+ :disabled="!editor.can().undo()"
5
+ @click="editor.chain().focus().undo().run()" >
6
+
7
+ <div class="icon">
8
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
9
+ <path fill="currentColor" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M24 192l144 0c9.7 0 18.5-5.8 22.2-14.8s1.7-19.3-5.2-26.2l-46.7-46.7c75.3-58.6 184.3-53.3 253.5 15.9 75 75 75 196.5 0 271.5s-196.5 75-271.5 0c-10.2-10.2-19-21.3-26.4-33-9.5-14.9-29.3-19.3-44.2-9.8s-19.3 29.3-9.8 44.2C49.7 408.7 61.4 423.5 75 437 175 537 337 537 437 437S537 175 437 75C342.8-19.3 193.3-24.7 92.7 58.8L41 7C34.1 .2 23.8-1.9 14.8 1.8S0 14.3 0 24L0 168c0 13.3 10.7 24 24 24z"/>
10
+ </svg>
11
+ </div>
12
+
13
+ <div class="tips">撤销</div>
14
+ </button>
15
+ </template>
16
+
17
+
18
+ <script setup>
19
+
20
+
21
+ const props = defineProps({
22
+ editor: {
23
+ type: Object,
24
+ required: true
25
+ }
26
+ })
27
+ </script>
28
+
29
+
@@ -0,0 +1,55 @@
1
+ const props = defineProps({
2
+ editor: {
3
+ type: Object,
4
+ required: true
5
+ }
6
+ });
7
+ const __VLS_ctx = {
8
+ ...{},
9
+ ...{},
10
+ ...{},
11
+ };
12
+ let __VLS_components;
13
+ let __VLS_intrinsics;
14
+ let __VLS_directives;
15
+ __VLS_asFunctionalElement1(__VLS_intrinsics.button, __VLS_intrinsics.button)({
16
+ ...{ onClick: (...[$event]) => {
17
+ __VLS_ctx.editor.chain().focus().undo().run();
18
+ // @ts-ignore
19
+ [editor,];
20
+ } },
21
+ ...{ class: "icon-button" },
22
+ disabled: (!__VLS_ctx.editor.can().undo()),
23
+ });
24
+ /** @type {__VLS_StyleScopedClasses['icon-button']} */ ;
25
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
26
+ ...{ class: "icon" },
27
+ });
28
+ /** @type {__VLS_StyleScopedClasses['icon']} */ ;
29
+ __VLS_asFunctionalElement1(__VLS_intrinsics.svg, __VLS_intrinsics.svg)({
30
+ xmlns: "http://www.w3.org/2000/svg",
31
+ viewBox: "0 0 512 512",
32
+ });
33
+ __VLS_asFunctionalElement1(__VLS_intrinsics.path)({
34
+ fill: "currentColor",
35
+ stroke: "currentColor",
36
+ 'stroke-width': "4",
37
+ 'stroke-linecap': "round",
38
+ 'stroke-linejoin': "round",
39
+ d: "M24 192l144 0c9.7 0 18.5-5.8 22.2-14.8s1.7-19.3-5.2-26.2l-46.7-46.7c75.3-58.6 184.3-53.3 253.5 15.9 75 75 75 196.5 0 271.5s-196.5 75-271.5 0c-10.2-10.2-19-21.3-26.4-33-9.5-14.9-29.3-19.3-44.2-9.8s-19.3 29.3-9.8 44.2C49.7 408.7 61.4 423.5 75 437 175 537 337 537 437 437S537 175 437 75C342.8-19.3 193.3-24.7 92.7 58.8L41 7C34.1 .2 23.8-1.9 14.8 1.8S0 14.3 0 24L0 168c0 13.3 10.7 24 24 24z",
40
+ });
41
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
42
+ ...{ class: "tips" },
43
+ });
44
+ /** @type {__VLS_StyleScopedClasses['tips']} */ ;
45
+ // @ts-ignore
46
+ [editor,];
47
+ const __VLS_export = (await import('vue')).defineComponent({
48
+ props: {
49
+ editor: {
50
+ type: Object,
51
+ required: true
52
+ }
53
+ },
54
+ });
55
+ export default {};
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
3
+ <path d="M434.8 70.1c14.3 10.4 17.5 30.4 7.1 44.7l-256 352c-5.5 7.6-14 12.3-23.4 13.1s-18.5-2.7-25.1-9.3l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l101.5 101.5 234-321.7c10.4-14.3 30.4-17.5 44.7-7.1z"/>
4
+ </svg>
5
+ </template>
6
+
7
+ <script setup>
8
+ const props = defineProps({
9
+ editor: {
10
+ type: Object,
11
+ required: true
12
+ }
13
+ })
14
+
15
+
16
+ </script>
@@ -0,0 +1,30 @@
1
+ const props = defineProps({
2
+ editor: {
3
+ type: Object,
4
+ required: true
5
+ }
6
+ });
7
+ const __VLS_ctx = {
8
+ ...{},
9
+ ...{},
10
+ ...{},
11
+ };
12
+ let __VLS_components;
13
+ let __VLS_intrinsics;
14
+ let __VLS_directives;
15
+ __VLS_asFunctionalElement1(__VLS_intrinsics.svg, __VLS_intrinsics.svg)({
16
+ xmlns: "http://www.w3.org/2000/svg",
17
+ viewBox: "0 0 448 512",
18
+ });
19
+ __VLS_asFunctionalElement1(__VLS_intrinsics.path)({
20
+ d: "M434.8 70.1c14.3 10.4 17.5 30.4 7.1 44.7l-256 352c-5.5 7.6-14 12.3-23.4 13.1s-18.5-2.7-25.1-9.3l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l101.5 101.5 234-321.7c10.4-14.3 30.4-17.5 44.7-7.1z",
21
+ });
22
+ const __VLS_export = (await import('vue')).defineComponent({
23
+ props: {
24
+ editor: {
25
+ type: Object,
26
+ required: true
27
+ }
28
+ },
29
+ });
30
+ export default {};
@@ -0,0 +1,40 @@
1
+ <template>
2
+
3
+ <div class="icon" :style="{color: color}">
4
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" :height="size">
5
+ <path fill="currentColor" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M434.8 70.1c14.3 10.4 17.5 30.4 7.1 44.7l-256 352c-5.5 7.6-14 12.3-23.4 13.1s-18.5-2.7-25.1-9.3l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l101.5 101.5 234-321.7c10.4-14.3 30.4-17.5 44.7-7.1z"/>
6
+ </svg>
7
+ </div>
8
+
9
+ </template>
10
+
11
+ <script setup>
12
+ const props = defineProps({
13
+ editor: {
14
+ type: Object,
15
+ required: true
16
+ },
17
+ color: {
18
+ type: String,
19
+ default: '#888'
20
+ },
21
+ size: {
22
+ type: Number,
23
+ default: 12
24
+ },
25
+ })
26
+ </script>
27
+
28
+
29
+ <style lang="scss" scoped>
30
+
31
+ .icon{
32
+ display: inline-flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ svg{
36
+ height: 14px;
37
+ }
38
+ }
39
+
40
+ </style>
@@ -0,0 +1,59 @@
1
+ const props = defineProps({
2
+ editor: {
3
+ type: Object,
4
+ required: true
5
+ },
6
+ color: {
7
+ type: String,
8
+ default: '#888'
9
+ },
10
+ size: {
11
+ type: Number,
12
+ default: 12
13
+ },
14
+ });
15
+ const __VLS_ctx = {
16
+ ...{},
17
+ ...{},
18
+ ...{},
19
+ };
20
+ let __VLS_components;
21
+ let __VLS_intrinsics;
22
+ let __VLS_directives;
23
+ __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({
24
+ ...{ class: "icon" },
25
+ ...{ style: ({ color: __VLS_ctx.color }) },
26
+ });
27
+ /** @type {__VLS_StyleScopedClasses['icon']} */ ;
28
+ __VLS_asFunctionalElement1(__VLS_intrinsics.svg, __VLS_intrinsics.svg)({
29
+ xmlns: "http://www.w3.org/2000/svg",
30
+ viewBox: "0 0 448 512",
31
+ height: (__VLS_ctx.size),
32
+ });
33
+ __VLS_asFunctionalElement1(__VLS_intrinsics.path)({
34
+ fill: "currentColor",
35
+ stroke: "currentColor",
36
+ 'stroke-width': "4",
37
+ 'stroke-linecap': "round",
38
+ 'stroke-linejoin': "round",
39
+ d: "M434.8 70.1c14.3 10.4 17.5 30.4 7.1 44.7l-256 352c-5.5 7.6-14 12.3-23.4 13.1s-18.5-2.7-25.1-9.3l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l101.5 101.5 234-321.7c10.4-14.3 30.4-17.5 44.7-7.1z",
40
+ });
41
+ // @ts-ignore
42
+ [color, size,];
43
+ const __VLS_export = (await import('vue')).defineComponent({
44
+ props: {
45
+ editor: {
46
+ type: Object,
47
+ required: true
48
+ },
49
+ color: {
50
+ type: String,
51
+ default: '#888'
52
+ },
53
+ size: {
54
+ type: Number,
55
+ default: 12
56
+ },
57
+ },
58
+ });
59
+ export default {};
@@ -0,0 +1,150 @@
1
+ <template>
2
+
3
+ <div class="toolbar" v-if="editor" @click.stop>
4
+
5
+ <div class="group">
6
+ <UndoButton :editor="editor" />
7
+ <RedoButton :editor="editor" />
8
+ <FormatButton :editor="editor" />
9
+ </div>
10
+
11
+ <div class="group">
12
+ <HeadingButton :editor="editor" />
13
+ <FontSizeButton :editor="editor" />
14
+ <LineHeightButton :editor="editor" />
15
+ </div>
16
+
17
+ <div class="group">
18
+ <!-- 常用 -->
19
+ <BoldButton :editor="editor" />
20
+ <ItalicButton :editor="editor" />
21
+ <UnderLineButton :editor="editor" />
22
+ <StrikeButton :editor="editor" />
23
+ <IndentRightButton :editor="editor" />
24
+ <IndentLeftButton :editor="editor" />
25
+ <TextColorButton :editor="editor" />
26
+ <BackgroundButton :editor="editor" />
27
+ <BlockQuoteButton :editor="editor" />
28
+ </div>
29
+
30
+ <div class="group">
31
+ <!-- 列表 -->
32
+ <BulletListButton :editor="editor" />
33
+ <OrderedListButton :editor="editor" />
34
+ </div>
35
+
36
+ <div class="group">
37
+ <!-- 对齐 -->
38
+ <TextAlignLeftButton :editor="editor" />
39
+ <TextAlignCenterButton :editor="editor" />
40
+ <TextAlignRightButton :editor="editor" />
41
+ <SubscriptButton :editor="editor" />
42
+ <SuperscriptButton :editor="editor" />
43
+ </div>
44
+
45
+ <div class="group">
46
+ <LinkButton :editor="editor" />
47
+ <CodeButton :editor="editor" />
48
+ <CodeBlockButton :editor="editor" />
49
+ <ImageUploadButton :editor="editor" :uploadImage="uploadImage" />
50
+ </div>
51
+
52
+ <div class="group">
53
+ <ThemeButton :theme="theme" @toggle-theme="()=>emit('toggle-theme')" />
54
+ </div>
55
+ </div>
56
+
57
+ </template>
58
+
59
+
60
+
61
+ <script setup lang="ts">
62
+ import type { Editor } from '@tiptap/core'
63
+ import UndoButton from './Button/UndoButton.vue'
64
+ import RedoButton from './Button/RedoButton.vue'
65
+ import FormatButton from './Button/FormatButton.vue'
66
+ import HeadingButton from './Button/HeadingButton.vue'
67
+ import FontSizeButton from './Button/FontSizeButton.vue'
68
+ import BoldButton from './Button/BoldButton.vue'
69
+ import ItalicButton from './Button/ItalicButton.vue'
70
+ import UnderLineButton from './Button/UnderLineButton.vue'
71
+ import StrikeButton from './Button/StrikeButton.vue'
72
+ import CodeButton from './Button/CodeButton.vue'
73
+ import CodeBlockButton from './Button/CodeBlockButton.vue'
74
+ import IndentLeftButton from './Button/IndentLeftButton.vue'
75
+ import IndentRightButton from './Button/IndentRightButton.vue'
76
+ import TextAlignLeftButton from './Button/TextAlignLeftButton.vue'
77
+ import TextAlignCenterButton from './Button/TextAlignCenterButton.vue'
78
+ import TextAlignRightButton from './Button/TextAlignRightButton.vue'
79
+ import BlockQuoteButton from './Button/BlockQuoteButton.vue'
80
+ import LinkButton from './Button/LinkButton.vue'
81
+ import LineHeightButton from './Button/LineHeightButton.vue'
82
+ import ImageUploadButton from './Button/ImageUploadButton.vue'
83
+ import TextColorButton from './Button/TextColorButton.vue'
84
+ import BackgroundButton from './Button/BackgroundButton.vue'
85
+ import SubscriptButton from './Button/SubscriptButton.vue'
86
+ import SuperscriptButton from './Button/SuperscriptButton.vue'
87
+ import BulletListButton from './Button/BulletListButton.vue'
88
+ import OrderedListButton from './Button/OrderedListButton.vue'
89
+
90
+ import { UploadImageResult } from 'src/types';
91
+ import ThemeButton from './Button/ThemeButton.vue'
92
+
93
+ defineProps<{
94
+ theme: 'light' | 'dark'
95
+ editor: Editor
96
+ uploadImage: (file: File) => Promise<UploadImageResult>
97
+ }>()
98
+
99
+
100
+ const emit = defineEmits<{
101
+ (e: 'toggle-theme'): void
102
+ }>()
103
+
104
+
105
+ </script>
106
+
107
+
108
+ <style lang="scss" scoped>
109
+
110
+ .toolbar {
111
+
112
+ background: var(--background);
113
+ padding: 5px;
114
+ display: flex;
115
+ flex-wrap: wrap;
116
+ align-items: center;
117
+ gap: 0 5px;
118
+ user-select: none;
119
+ position: relative;
120
+ border-bottom: 1px solid var(--border-color);
121
+
122
+
123
+ .group {
124
+ display: flex;
125
+ align-items: center;
126
+ gap: 0 5px;
127
+ padding: 0 5px;
128
+ position: relative;
129
+
130
+ &::after{
131
+ content: ' ';
132
+ width: 1px;
133
+ height: 20px;
134
+ position: absolute;
135
+ right: 0px;
136
+ top: 50%;
137
+ transform: translateY(-50%);
138
+ background: var(--border-color);
139
+ }
140
+
141
+ &:last-child {
142
+ &::after{
143
+ width: 0;
144
+ content: '';
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ </style>