@meeovi/layer-lists 1.0.2

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 (47) hide show
  1. package/app/components/features/archived.vue +64 -0
  2. package/app/components/features/bookmarks.vue +64 -0
  3. package/app/components/features/lists.vue +61 -0
  4. package/app/components/features/starred.vue +64 -0
  5. package/app/components/lists/ListItemCard.vue +190 -0
  6. package/app/components/lists/add-bookmark.vue +52 -0
  7. package/app/components/lists/add-list-item.vue +88 -0
  8. package/app/components/lists/add-list.vue +57 -0
  9. package/app/components/lists/lists.vue +6 -0
  10. package/app/components/lists/listsettings.vue +145 -0
  11. package/app/components/lists/update-bookmark.vue +267 -0
  12. package/app/components/lists/update-list.vue +192 -0
  13. package/app/components/media/MediaPlayer.vue +302 -0
  14. package/app/components/partials/addtolist.vue +233 -0
  15. package/app/components/partials/createListBtn.vue +95 -0
  16. package/app/components/partials/listBtn.vue +35 -0
  17. package/app/components/related/list.vue +33 -0
  18. package/app/components/related/relatedlists.vue +43 -0
  19. package/app/components/tasks/TaskItem.vue +204 -0
  20. package/app/composables/bookmarks/createBookmark.js +30 -0
  21. package/app/composables/bookmarks/deleteBookmark.js +15 -0
  22. package/app/composables/bookmarks/updateBookmark.js +15 -0
  23. package/app/composables/config.ts +17 -0
  24. package/app/composables/content/uploadFiles.js +41 -0
  25. package/app/composables/globals/useDirectusForm.ts +1 -0
  26. package/app/composables/lists/createList.js +25 -0
  27. package/app/composables/lists/deleteList.js +14 -0
  28. package/app/composables/lists/updateList.js +20 -0
  29. package/app/composables/lists/useBookmarks.js +69 -0
  30. package/app/composables/lists/useLists.js +120 -0
  31. package/app/composables/lists/usePlaylist.js +64 -0
  32. package/app/composables/lists/useSaved.js +29 -0
  33. package/app/composables/lists/useTasks.js +86 -0
  34. package/app/composables/lists/useWishlist.js +51 -0
  35. package/app/composables/providers/atproto.ts +156 -0
  36. package/app/composables/providers/directus.ts +49 -0
  37. package/app/composables/providers/memory.ts +88 -0
  38. package/app/composables/registry.ts +13 -0
  39. package/app/composables/types.ts +35 -0
  40. package/app/composables/useLists.ts +20 -0
  41. package/app/composables/utils/transforms.ts +42 -0
  42. package/app/composables/utils/validation.ts +21 -0
  43. package/app/pages/lists/bookmark/[id].vue +76 -0
  44. package/app/pages/lists/index.vue +152 -0
  45. package/app/pages/lists/list/[...slug].vue +233 -0
  46. package/nuxt.config.ts +11 -0
  47. package/package.json +26 -0
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div>
3
+ <section data-bs-version="5.1" class="features4 start cid-v0Her0Ajsb" id="features04-1">
4
+ <div class="container">
5
+ <div class="row justify-content-center">
6
+ <div class="col-12 content-head">
7
+ <div class="mbr-section-head mb-5">
8
+ <h4 class="mbr-section-title mbr-fonts-style align-center mb-0 display-2">
9
+ <strong>My Archived Lists</strong>
10
+ </h4>
11
+
12
+ <div class="row">
13
+ <div class="item features-image col-12 col-md-6 col-lg-4" v-for="list in archived" :key="list.id">
14
+ <listCard :list="list" />
15
+ </div>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </section>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup>
26
+ import {
27
+ ref
28
+ } from 'vue'
29
+ import listCard from '~/components/related/list.vue'
30
+ import {
31
+ useUserStore
32
+ } from '#auth/app/stores/user'
33
+
34
+ const userStore = useUserStore()
35
+ const userDisplayName = computed(() => {
36
+ return userStore.user?.name || userStore.user?.username || 'User'
37
+ })
38
+
39
+ const model = ref(null)
40
+
41
+ const {
42
+ $directus,
43
+ $readItems
44
+ } = useNuxtApp()
45
+
46
+ const {
47
+ data: archived
48
+ } = await useAsyncData('archived', () => {
49
+ return $directus.request($readItems('lists', {
50
+ filter: {
51
+ user: {
52
+ _eq: userDisplayName.value,
53
+ },
54
+ status: {
55
+ _eq: "Archived",
56
+ }
57
+ },
58
+ }))
59
+ })
60
+
61
+ useHead({
62
+ title: 'My Archived Lists - Meeovi Tasks'
63
+ })
64
+ </script>
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div>
3
+ <section data-bs-version="5.1" class="features4 start cid-v0Her0Ajsb" id="features04-1">
4
+ <div class="container">
5
+ <div class="row justify-content-center">
6
+ <div class="col-12 content-head">
7
+ <div class="mbr-section-head mb-5">
8
+ <h4 class="mbr-section-title mbr-fonts-style align-center mb-0 display-2">
9
+ <strong>My Bookmarks</strong>
10
+ </h4>
11
+
12
+ <div class="row">
13
+ <div class="item features-image col-12 col-md-6 col-lg-4" v-for="bookmark in bookmarks" :key="bookmark.id">
14
+ <bookmarkCard :bookmark="bookmark" />
15
+ </div>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </section>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup>
26
+ import {
27
+ ref
28
+ } from 'vue'
29
+ import bookmarkCard from '~/components/related/bookmark.vue'
30
+ import {
31
+ useUserStore
32
+ } from '#auth/app/stores/user'
33
+
34
+ const userStore = useUserStore()
35
+ const userDisplayName = computed(() => {
36
+ return userStore.user?.name || userStore.user?.username || 'User'
37
+ })
38
+
39
+ const model = ref(null)
40
+
41
+ const {
42
+ $directus,
43
+ $readItems
44
+ } = useNuxtApp()
45
+
46
+ const {
47
+ data: bookmarks
48
+ } = await useAsyncData('bookmarks', () => {
49
+ return $directus.request($readItems('lists', {
50
+ filter: {
51
+ creator: {
52
+ _eq: userDisplayName.value,
53
+ },
54
+ type: {
55
+ _eq: "bookmark",
56
+ }
57
+ },
58
+ }))
59
+ })
60
+
61
+ useHead({
62
+ title: 'My Bookmarks Lists - Meeovi Tasks'
63
+ })
64
+ </script>
@@ -0,0 +1,61 @@
1
+ <template>
2
+ <div>
3
+ <section data-bs-version="5.1" class="features4 start cid-v0Her0Ajsb" id="features04-1">
4
+ <div class="container">
5
+ <div class="row justify-content-center">
6
+ <div class="col-12 content-head">
7
+ <div class="mbr-section-head mb-5">
8
+ <h4 class="mbr-section-title mbr-fonts-style align-center mb-0 display-2">
9
+ <strong>My Lists</strong>
10
+ </h4>
11
+
12
+ <div class="row">
13
+ <div class="item features-image col-12 col-md-6 col-lg-4" v-for="list in myLists" :key="list.id">
14
+ <listCard :list="list" />
15
+ </div>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </section>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup>
26
+ import {
27
+ ref
28
+ } from 'vue'
29
+ import listCard from '~/components/related/list.vue'
30
+ import {
31
+ useUserStore
32
+ } from '#auth/app/stores/user'
33
+
34
+ const userStore = useUserStore()
35
+ const userDisplayName = computed(() => {
36
+ return userStore.user?.name || userStore.user?.username || 'User'
37
+ })
38
+
39
+ const model = ref(null)
40
+
41
+ const {
42
+ $directus,
43
+ $readItems
44
+ } = useNuxtApp()
45
+
46
+ const {
47
+ data: myLists
48
+ } = await useAsyncData('myLists', () => {
49
+ return $directus.request($readItems('lists', {
50
+ filter: {
51
+ user: {
52
+ _eq: userDisplayName.value,
53
+ }
54
+ },
55
+ }))
56
+ })
57
+
58
+ useHead({
59
+ title: 'My Lists - Meeovi Tasks'
60
+ })
61
+ </script>
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div>
3
+ <section data-bs-version="5.1" class="features4 start cid-v0Her0Ajsb" id="features04-1">
4
+ <div class="container">
5
+ <div class="row justify-content-center">
6
+ <div class="col-12 content-head">
7
+ <div class="mbr-section-head mb-5">
8
+ <h4 class="mbr-section-title mbr-fonts-style align-center mb-0 display-2">
9
+ <strong>My Starred Lists</strong>
10
+ </h4>
11
+
12
+ <div class="row">
13
+ <div class="item features-image col-12 col-md-6 col-lg-4" v-for="list in starred" :key="list.id">
14
+ <listCard :list="list" />
15
+ </div>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </section>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup>
26
+ import {
27
+ ref
28
+ } from 'vue'
29
+ import listCard from '~/components/related/list.vue'
30
+ import {
31
+ useUserStore
32
+ } from '#auth/app/stores/user'
33
+
34
+ const userStore = useUserStore()
35
+ const userDisplayName = computed(() => {
36
+ return userStore.user?.name || userStore.user?.username || 'User'
37
+ })
38
+
39
+ const model = ref(null)
40
+
41
+ const {
42
+ $directus,
43
+ $readItems
44
+ } = useNuxtApp()
45
+
46
+ const {
47
+ data: starred
48
+ } = await useAsyncData('starred', () => {
49
+ return $directus.request($readItems('lists', {
50
+ filter: {
51
+ user: {
52
+ _eq: userDisplayName.value,
53
+ },
54
+ favorite: {
55
+ _eq: "yes",
56
+ }
57
+ },
58
+ }))
59
+ })
60
+
61
+ useHead({
62
+ title: 'My Starred Lists - Meeovi Tasks'
63
+ })
64
+ </script>
@@ -0,0 +1,190 @@
1
+ <template>
2
+ <v-card class="list-item-card" :class="`item-type-${item.content.type}`">
3
+ <!-- Media Item -->
4
+ <div v-if="item.content.type === 'media'">
5
+ <v-img
6
+ :src="item.content.thumbnail || '/default-media.png'"
7
+ height="200"
8
+ cover
9
+ >
10
+ <div class="d-flex align-end fill-height">
11
+ <v-chip color="primary" size="small" class="ma-2">
12
+ {{ item.content.media_type }}
13
+ </v-chip>
14
+ </div>
15
+ </v-img>
16
+
17
+ <v-card-title class="text-truncate">{{ item.content.title }}</v-card-title>
18
+ <v-card-subtitle v-if="item.content.metadata?.artist">
19
+ {{ item.content.metadata.artist }}
20
+ </v-card-subtitle>
21
+ </div>
22
+
23
+ <!-- Bookmark Item -->
24
+ <div v-else-if="item.content.type === 'bookmark'">
25
+ <v-card-title class="d-flex align-center">
26
+ <v-img
27
+ :src="item.content.favicon || '/default-favicon.png'"
28
+ width="16"
29
+ height="16"
30
+ class="me-2"
31
+ />
32
+ <span class="text-truncate">{{ item.content.title }}</span>
33
+ </v-card-title>
34
+
35
+ <v-card-text>
36
+ <p class="text-body-2 text-truncate">{{ item.content.description }}</p>
37
+ <div class="d-flex align-center mt-2">
38
+ <v-chip
39
+ v-for="tag in item.content.tags?.slice(0, 2)"
40
+ :key="tag"
41
+ size="x-small"
42
+ class="me-1"
43
+ >
44
+ {{ tag }}
45
+ </v-chip>
46
+ <v-chip
47
+ v-if="item.content.read"
48
+ color="success"
49
+ size="x-small"
50
+ variant="outlined"
51
+ >
52
+ Read
53
+ </v-chip>
54
+ </div>
55
+ </v-card-text>
56
+ </div>
57
+
58
+ <!-- Product/Wishlist Item -->
59
+ <div v-else-if="item.content.type === 'product'">
60
+ <v-img
61
+ :src="item.content.image || '/default-product.png'"
62
+ height="200"
63
+ cover
64
+ >
65
+ <div class="d-flex align-end fill-height">
66
+ <v-chip
67
+ :color="getPriorityColor(item.content.priority)"
68
+ size="small"
69
+ class="ma-2"
70
+ >
71
+ {{ item.content.priority }}
72
+ </v-chip>
73
+ </div>
74
+ </v-img>
75
+
76
+ <v-card-title class="text-truncate">{{ item.content.title }}</v-card-title>
77
+ <v-card-subtitle v-if="item.content.price">
78
+ ${{ item.content.price }}
79
+ </v-card-subtitle>
80
+ </div>
81
+
82
+ <!-- Default Item -->
83
+ <div v-else>
84
+ <v-img
85
+ v-if="item.content.image"
86
+ :src="item.content.image"
87
+ height="200"
88
+ cover
89
+ />
90
+
91
+ <v-card-title class="text-truncate">{{ item.content.title }}</v-card-title>
92
+ <v-card-text v-if="item.content.description">
93
+ <p class="text-body-2">{{ item.content.description }}</p>
94
+ </v-card-text>
95
+ </div>
96
+
97
+ <!-- Actions -->
98
+ <v-card-actions>
99
+ <v-btn
100
+ v-if="item.content.url"
101
+ :href="item.content.url"
102
+ target="_blank"
103
+ variant="text"
104
+ size="small"
105
+ prepend-icon="mdi-open-in-new"
106
+ >
107
+ Open
108
+ </v-btn>
109
+
110
+ <v-spacer />
111
+
112
+ <v-menu>
113
+ <template v-slot:activator="{ props }">
114
+ <v-btn
115
+ icon="mdi-dots-vertical"
116
+ variant="text"
117
+ size="small"
118
+ v-bind="props"
119
+ />
120
+ </template>
121
+
122
+ <v-list>
123
+ <v-list-item @click="$emit('edit', item)">
124
+ <template v-slot:prepend>
125
+ <v-icon icon="mdi-pencil" />
126
+ </template>
127
+ <v-list-item-title>Edit</v-list-item-title>
128
+ </v-list-item>
129
+
130
+ <v-divider />
131
+
132
+ <v-list-item @click="$emit('delete', item.id)" class="text-error">
133
+ <template v-slot:prepend>
134
+ <v-icon icon="mdi-delete" color="error" />
135
+ </template>
136
+ <v-list-item-title>Delete</v-list-item-title>
137
+ </v-list-item>
138
+ </v-list>
139
+ </v-menu>
140
+ </v-card-actions>
141
+ </v-card>
142
+ </template>
143
+
144
+ <script setup>
145
+ const props = defineProps({
146
+ item: {
147
+ type: Object,
148
+ required: true
149
+ },
150
+ listType: {
151
+ type: String,
152
+ required: true
153
+ }
154
+ })
155
+
156
+ const emit = defineEmits(['edit', 'delete'])
157
+
158
+ const getPriorityColor = (priority) => {
159
+ const colors = {
160
+ low: 'blue',
161
+ medium: 'orange',
162
+ high: 'red'
163
+ }
164
+ return colors[priority] || 'grey'
165
+ }
166
+ </script>
167
+
168
+ <style scoped>
169
+ .list-item-card {
170
+ height: 100%;
171
+ transition: all 0.2s ease;
172
+ }
173
+
174
+ .list-item-card:hover {
175
+ transform: translateY(-2px);
176
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
177
+ }
178
+
179
+ .item-type-media {
180
+ border-left: 4px solid rgb(var(--v-theme-purple));
181
+ }
182
+
183
+ .item-type-bookmark {
184
+ border-left: 4px solid rgb(var(--v-theme-orange));
185
+ }
186
+
187
+ .item-type-product {
188
+ border-left: 4px solid rgb(var(--v-theme-pink));
189
+ }
190
+ </style>
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <v-row justify="center">
3
+ <v-dialog v-model="dialog" :scrim="false" transition="dialog-bottom-transition">
4
+ <template v-slot:activator="{ props }">
5
+ <v-btn v-bind="props" class="rightAddBtn">
6
+ <v-icon start icon="fas:fa fa-plus"></v-icon>Create a Bookmark
7
+ </v-btn>
8
+ </template>
9
+ <v-card class="b-1">
10
+ <v-card-title>
11
+ <h3>Create New Bookmark</h3>
12
+ </v-card-title>
13
+
14
+ <v-card-text>
15
+ <div v-if="formError" class="error">{{ formError }}</div>
16
+ <div v-else-if="formSuccess" class="success">{{ formSuccess }}</div>
17
+ <form @submit.prevent="submitForm">
18
+ <DirectusFormElement v-for="field in websiteFields" :key="field.field" :field="field" v-model="form[field.field]" />
19
+ <v-btn type="submit">Submit</v-btn>
20
+ </form>
21
+ </v-card-text>
22
+ </v-card>
23
+ </v-dialog>
24
+ </v-row>
25
+ </template>
26
+
27
+ <script setup>
28
+ import { ref } from 'vue'
29
+ import DirectusFormElement from '#shared/app/components/ui/forms/DirectusFormElement.vue'
30
+ import { useDirectusForm } from '../../composables/globals/useDirectusForm'
31
+
32
+ const dialog = ref(false)
33
+ const { $directus, $readFieldsByCollection } = useNuxtApp()
34
+
35
+ const { data, error } = await useAsyncData('websites', async () => {
36
+ return $directus.request($readFieldsByCollection('websites'))
37
+ })
38
+
39
+ // guard against undefined/null data.value and empty arrays
40
+ if (error.value || data.value == null || (data.value?.length ?? 0) === 0) {
41
+ console.error(error)
42
+ throw createError({
43
+ statusCode: 404,
44
+ statusMessage: 'Bookmark not found'
45
+ })
46
+ }
47
+
48
+ const websiteFields = data
49
+
50
+ // use composable for form handling (validation, submit, provide context)
51
+ const { form, formError, formSuccess, submitForm } = useDirectusForm('websites', websiteFields, { clearOnSuccess: true, closeDialogRef: dialog })
52
+ </script>
@@ -0,0 +1,88 @@
1
+ <template>
2
+ <div>
3
+ <div v-if="list?.items?.length === 0" class="text-center py-8">
4
+ <v-icon size="64" color="grey-lighten-1">{{ getListIcon(list?.type) }}</v-icon>
5
+ <h3 class="text-h6 mt-4 mb-2">No items yet</h3>
6
+ <p class="text-body-2 text-medium-emphasis mb-4">
7
+ Add your first item to get started
8
+ </p>
9
+ <v-btn color="primary" @click="showAddDialog = true">
10
+ Add Item
11
+ </v-btn>
12
+ </div>
13
+
14
+ <div v-else>
15
+ <!-- Task Items -->
16
+ <div v-if="list?.type === 'tasks'">
17
+ <TaskItem v-for="item in list?.items" :key="item?.id" :task="item?.content"
18
+ @update="updateTask(item?.id, $event)" @edit="editItem(item)" @duplicate="duplicateItem(item)"
19
+ @delete="deleteItem(item?.id)" />
20
+ </div>
21
+
22
+ <!-- Other List Types -->
23
+ <v-row v-else>
24
+ <v-col v-for="item in list?.items" :key="item?.id" cols="12" sm="6" md="4" lg="3">
25
+ <ListItemCard :item="item" :list-type="list?.type" @edit="editItem(item)"
26
+ @delete="deleteItem(item?.id)" />
27
+ </v-col>
28
+ </v-row>
29
+ </div>
30
+ </div>
31
+ </template>
32
+
33
+ <script setup>
34
+ import {
35
+ ref,
36
+ computed
37
+ } from 'vue'
38
+ //import DirectusFormElement from '#shared/app/components/ui/forms/DirectusFormElement.vue'
39
+ import {
40
+ useDirectusForm
41
+ } from '../../composables/globals/useDirectusForm'
42
+ import ListItemCard from './ListItemCard.vue'
43
+
44
+ const props = defineProps({
45
+ modelValue: Boolean,
46
+ listType: String,
47
+ listId: String
48
+ })
49
+
50
+ const dialog = ref(false)
51
+ const {
52
+ $directus,
53
+ $readFieldsByCollection
54
+ } = useNuxtApp()
55
+
56
+ const {
57
+ data,
58
+ error
59
+ } = await useAsyncData('listItemsFields', async () => {
60
+ return $directus.request($readFieldsByCollection('list_items'))
61
+ })
62
+
63
+ // normalize response: Directus may return { data: [...] } or an array directly
64
+ const listItemFields = computed(() => {
65
+ const resp = data?.value
66
+ return resp?.data ?? resp ?? []
67
+ })
68
+
69
+ // guard against undefined/null and empty arrays
70
+ if (error.value || listItemFields.value == null || listItemFields.value.length === 0) {
71
+ console.error(error)
72
+ throw createError({
73
+ statusCode: 404,
74
+ statusMessage: 'List not found'
75
+ })
76
+ }
77
+
78
+ // use composable for form handling (validation, submit, provide context)
79
+ const {
80
+ form,
81
+ formError,
82
+ formSuccess,
83
+ submitForm
84
+ } = useDirectusForm('list_items', listItemFields, {
85
+ clearOnSuccess: true,
86
+ closeDialogRef: dialog
87
+ })
88
+ </script>
@@ -0,0 +1,57 @@
1
+ <template>
2
+ <v-row justify="center">
3
+ <v-dialog v-model="dialog" :scrim="false" transition="dialog-bottom-transition">
4
+ <template v-slot:activator="{ props }">
5
+ <v-btn v-bind="props" class="rightAddBtn">
6
+ <v-icon start icon="fas:fa fa-plus"></v-icon>Create a List
7
+ </v-btn>
8
+ </template>
9
+ <v-card class="b-1">
10
+ <v-card-title>
11
+ <h3>Create New List</h3>
12
+ </v-card-title>
13
+
14
+ <v-card-text>
15
+ <div v-if="formError" class="error">{{ formError }}</div>
16
+ <div v-else-if="formSuccess" class="success">{{ formSuccess }}</div>
17
+ <form @submit.prevent="submitForm">
18
+ <DirectusFormElement v-for="field in listFields" :key="field.field" :field="field" v-model="form[field.field]" />
19
+ <v-btn type="submit">Submit</v-btn>
20
+ </form>
21
+ </v-card-text>
22
+ </v-card>
23
+ </v-dialog>
24
+ </v-row>
25
+ </template>
26
+
27
+ <script setup>
28
+ import { ref, computed } from 'vue'
29
+ import DirectusFormElement from '#shared/app/components/ui/forms/DirectusFormElement.vue'
30
+ import { useDirectusForm } from '../../composables/globals/useDirectusForm'
31
+
32
+ const dialog = ref(false)
33
+ const { $directus, $readFieldsByCollection } = useNuxtApp()
34
+
35
+ const { data, error } = await useAsyncData('listsFields', async () => {
36
+ return $directus.request($readFieldsByCollection('lists'))
37
+ })
38
+
39
+ // normalize response: Directus may return { data: [...] } or an array directly
40
+ const listFields = computed(() => {
41
+ const resp = data?.value
42
+ return resp?.data ?? resp ?? []
43
+ })
44
+
45
+ // guard against undefined/null and empty arrays
46
+ if (error.value || listFields.value == null || listFields.value.length === 0) {
47
+ console.error(error)
48
+ throw createError({
49
+ statusCode: 404,
50
+ statusMessage: 'List not found'
51
+ })
52
+ }
53
+
54
+
55
+ // use composable for form handling (validation, submit, provide context)
56
+ const { form, formError, formSuccess, submitForm } = useDirectusForm('lists', listFields, { clearOnSuccess: true, closeDialogRef: dialog })
57
+ </script>
@@ -0,0 +1,6 @@
1
+ <template>
2
+ <div>Lists (stub)</div>
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ </script>