@necrolab/dashboard 0.4.3

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 (240) hide show
  1. package/.claude/settings.local.json +45 -0
  2. package/.eslintrc.js +24 -0
  3. package/.prettierignore +1 -0
  4. package/.prettierrc +10 -0
  5. package/.vscode/extensions.json +3 -0
  6. package/ICONS.md +21 -0
  7. package/README.md +65 -0
  8. package/backend/api.js +430 -0
  9. package/backend/auth.js +62 -0
  10. package/backend/batching.js +43 -0
  11. package/backend/endpoints.js +343 -0
  12. package/backend/index.js +23 -0
  13. package/backend/mock-data.js +66 -0
  14. package/backend/mock-src/classes/logger.js +112 -0
  15. package/backend/mock-src/classes/utils.js +42 -0
  16. package/backend/mock-src/ticketmaster.js +92 -0
  17. package/backend/validator.js +62 -0
  18. package/config/configs.json +20 -0
  19. package/config/filter.json +3 -0
  20. package/config/presale.csv +3 -0
  21. package/config/proxies.txt +6 -0
  22. package/config/used-codes.json +4 -0
  23. package/index.html +114 -0
  24. package/index.js +2 -0
  25. package/jsconfig.json +16 -0
  26. package/package.json +48 -0
  27. package/postcss.config.js +6 -0
  28. package/postinstall.js +9 -0
  29. package/public/android-chrome-192x192.png +0 -0
  30. package/public/android-chrome-512x512.png +0 -0
  31. package/public/apple-touch-icon.png +0 -0
  32. package/public/favicon-16x16.png +0 -0
  33. package/public/favicon-32x32.png +0 -0
  34. package/public/favicon.ico +0 -0
  35. package/public/flags/ae.svg +1 -0
  36. package/public/flags/at.svg +1 -0
  37. package/public/flags/au.svg +1 -0
  38. package/public/flags/be.svg +1 -0
  39. package/public/flags/ch.svg +1 -0
  40. package/public/flags/cz.svg +1 -0
  41. package/public/flags/de.svg +1 -0
  42. package/public/flags/dk.svg +1 -0
  43. package/public/flags/es.svg +1 -0
  44. package/public/flags/nl.svg +1 -0
  45. package/public/flags/no.svg +1 -0
  46. package/public/flags/nz.svg +1 -0
  47. package/public/flags/pl.svg +1 -0
  48. package/public/flags/se.svg +1 -0
  49. package/public/flags/uk.svg +1 -0
  50. package/public/flags/us.svg +1 -0
  51. package/public/img/award.svg +3 -0
  52. package/public/img/background.svg +14 -0
  53. package/public/img/bag_w.svg +12 -0
  54. package/public/img/banks/amex.svg +4 -0
  55. package/public/img/banks/mastercard.svg +4 -0
  56. package/public/img/banks/visa.svg +4 -0
  57. package/public/img/camera.svg +3 -0
  58. package/public/img/close.svg +3 -0
  59. package/public/img/controls/disable.svg +5 -0
  60. package/public/img/controls/enable.svg +5 -0
  61. package/public/img/groups.svg +3 -0
  62. package/public/img/hand.svg +3 -0
  63. package/public/img/key.svg +3 -0
  64. package/public/img/logo.png +0 -0
  65. package/public/img/logo_icon.png +0 -0
  66. package/public/img/logo_icon_2.png +0 -0
  67. package/public/img/logo_trans.png +0 -0
  68. package/public/img/loyalty.svg +3 -0
  69. package/public/img/mail.svg +3 -0
  70. package/public/img/pencil.svg +3 -0
  71. package/public/img/profile.svg +4 -0
  72. package/public/img/reload.svg +3 -0
  73. package/public/img/sandclock.svg +25 -0
  74. package/public/img/save.svg +5 -0
  75. package/public/img/savings.svg +3 -0
  76. package/public/img/scanner.svg +3 -0
  77. package/public/img/sell.svg +3 -0
  78. package/public/img/shield.svg +3 -0
  79. package/public/img/ski.svg +3 -0
  80. package/public/img/stadium.svg +8 -0
  81. package/public/img/stadium_w.svg +8 -0
  82. package/public/img/timer.svg +3 -0
  83. package/public/manifest.json +27 -0
  84. package/public/robots.txt +2 -0
  85. package/run +10 -0
  86. package/src/App.vue +307 -0
  87. package/src/assets/css/_input.scss +197 -0
  88. package/src/assets/css/main.scss +269 -0
  89. package/src/assets/css/tailwind.css +3 -0
  90. package/src/assets/img/award.svg +3 -0
  91. package/src/assets/img/background.svg +11 -0
  92. package/src/assets/img/camera.svg +3 -0
  93. package/src/assets/img/close.svg +3 -0
  94. package/src/assets/img/eyes/closed.svg +13 -0
  95. package/src/assets/img/eyes/open.svg +12 -0
  96. package/src/assets/img/groups.svg +3 -0
  97. package/src/assets/img/hand.svg +3 -0
  98. package/src/assets/img/key.svg +3 -0
  99. package/src/assets/img/logo.png +0 -0
  100. package/src/assets/img/logo_icon.png +0 -0
  101. package/src/assets/img/logo_icon_2.png +0 -0
  102. package/src/assets/img/logo_trans.png +0 -0
  103. package/src/assets/img/loyalty.svg +3 -0
  104. package/src/assets/img/mail.svg +3 -0
  105. package/src/assets/img/pencil.svg +3 -0
  106. package/src/assets/img/reload.svg +3 -0
  107. package/src/assets/img/savings.svg +3 -0
  108. package/src/assets/img/scanner.svg +3 -0
  109. package/src/assets/img/sell.svg +3 -0
  110. package/src/assets/img/shield.svg +3 -0
  111. package/src/assets/img/ski.svg +3 -0
  112. package/src/assets/img/square_check.svg +5 -0
  113. package/src/assets/img/square_uncheck.svg +5 -0
  114. package/src/assets/img/stadium.svg +8 -0
  115. package/src/assets/img/timer.svg +3 -0
  116. package/src/assets/img/wildcard.svg +7 -0
  117. package/src/components/Auth/LoginForm.vue +48 -0
  118. package/src/components/Editors/Account/Account.vue +119 -0
  119. package/src/components/Editors/Account/AccountCreator.vue +147 -0
  120. package/src/components/Editors/Account/AccountView.vue +87 -0
  121. package/src/components/Editors/Account/CreateAccount.vue +106 -0
  122. package/src/components/Editors/Profile/CreateProfile.vue +321 -0
  123. package/src/components/Editors/Profile/Profile.vue +142 -0
  124. package/src/components/Editors/Profile/ProfileCountryChooser.vue +75 -0
  125. package/src/components/Editors/Profile/ProfileView.vue +96 -0
  126. package/src/components/Editors/TagLabel.vue +16 -0
  127. package/src/components/Editors/TagToggle.vue +41 -0
  128. package/src/components/Filter/Filter.vue +409 -0
  129. package/src/components/Filter/FilterPreview.vue +236 -0
  130. package/src/components/Filter/PriceSortToggle.vue +105 -0
  131. package/src/components/Table/Header.vue +5 -0
  132. package/src/components/Table/Row.vue +5 -0
  133. package/src/components/Table/Table.vue +14 -0
  134. package/src/components/Table/index.js +4 -0
  135. package/src/components/Tasks/CheckStock.vue +62 -0
  136. package/src/components/Tasks/Controls/DesktopControls.vue +73 -0
  137. package/src/components/Tasks/Controls/MobileControls.vue +32 -0
  138. package/src/components/Tasks/Controls/index.js +3 -0
  139. package/src/components/Tasks/CreateTaskAXS.vue +339 -0
  140. package/src/components/Tasks/CreateTaskTM.vue +459 -0
  141. package/src/components/Tasks/MassEdit.vue +50 -0
  142. package/src/components/Tasks/QuickSettings.vue +167 -0
  143. package/src/components/Tasks/ScrapeVenue.vue +42 -0
  144. package/src/components/Tasks/Stats.vue +66 -0
  145. package/src/components/Tasks/Task.vue +296 -0
  146. package/src/components/Tasks/TaskLabel.vue +20 -0
  147. package/src/components/Tasks/TaskView.vue +126 -0
  148. package/src/components/Tasks/Utilities.vue +33 -0
  149. package/src/components/icons/Award.vue +8 -0
  150. package/src/components/icons/Bag.vue +8 -0
  151. package/src/components/icons/BagWhite.vue +8 -0
  152. package/src/components/icons/Box.vue +8 -0
  153. package/src/components/icons/Camera.vue +8 -0
  154. package/src/components/icons/Cart.vue +8 -0
  155. package/src/components/icons/Check.vue +5 -0
  156. package/src/components/icons/Checkmark.vue +11 -0
  157. package/src/components/icons/Click.vue +8 -0
  158. package/src/components/icons/Close.vue +21 -0
  159. package/src/components/icons/CloseX.vue +5 -0
  160. package/src/components/icons/Console.vue +13 -0
  161. package/src/components/icons/Down.vue +8 -0
  162. package/src/components/icons/Edit.vue +13 -0
  163. package/src/components/icons/Event.vue +8 -0
  164. package/src/components/icons/Expand.vue +8 -0
  165. package/src/components/icons/Filter.vue +13 -0
  166. package/src/components/icons/Gear.vue +8 -0
  167. package/src/components/icons/Group.vue +8 -0
  168. package/src/components/icons/Hand.vue +8 -0
  169. package/src/components/icons/Key.vue +21 -0
  170. package/src/components/icons/Logout.vue +13 -0
  171. package/src/components/icons/Loyalty.vue +8 -0
  172. package/src/components/icons/Mail.vue +8 -0
  173. package/src/components/icons/Menu.vue +8 -0
  174. package/src/components/icons/Pause.vue +5 -0
  175. package/src/components/icons/Pencil.vue +21 -0
  176. package/src/components/icons/Play.vue +8 -0
  177. package/src/components/icons/Plus.vue +8 -0
  178. package/src/components/icons/Profile.vue +18 -0
  179. package/src/components/icons/Reload.vue +7 -0
  180. package/src/components/icons/Sandclock.vue +33 -0
  181. package/src/components/icons/Savings.vue +8 -0
  182. package/src/components/icons/Scanner.vue +8 -0
  183. package/src/components/icons/Scrape.vue +8 -0
  184. package/src/components/icons/Sell.vue +21 -0
  185. package/src/components/icons/Shield.vue +8 -0
  186. package/src/components/icons/Shrink.vue +8 -0
  187. package/src/components/icons/Ski.vue +8 -0
  188. package/src/components/icons/Spinner.vue +42 -0
  189. package/src/components/icons/SquareCheck.vue +18 -0
  190. package/src/components/icons/SquareUncheck.vue +18 -0
  191. package/src/components/icons/Stadium.vue +13 -0
  192. package/src/components/icons/StadiumWhite.vue +13 -0
  193. package/src/components/icons/Status.vue +8 -0
  194. package/src/components/icons/Tag.vue +8 -0
  195. package/src/components/icons/Tasks.vue +13 -0
  196. package/src/components/icons/Ticket.vue +8 -0
  197. package/src/components/icons/Timer.vue +8 -0
  198. package/src/components/icons/Trash.vue +8 -0
  199. package/src/components/icons/Up.vue +10 -0
  200. package/src/components/icons/Wildcard.vue +18 -0
  201. package/src/components/icons/index.js +111 -0
  202. package/src/components/ui/Modal.vue +61 -0
  203. package/src/components/ui/Navbar.vue +207 -0
  204. package/src/components/ui/ReconnectIndicator.vue +90 -0
  205. package/src/components/ui/Splash.vue +24 -0
  206. package/src/components/ui/controls/CountryChooser.vue +87 -0
  207. package/src/components/ui/controls/EyeToggle.vue +11 -0
  208. package/src/components/ui/controls/atomic/Checkbox.vue +28 -0
  209. package/src/components/ui/controls/atomic/Dropdown.vue +138 -0
  210. package/src/components/ui/controls/atomic/LoadingButton.vue +45 -0
  211. package/src/components/ui/controls/atomic/MultiDropdown.vue +262 -0
  212. package/src/components/ui/controls/atomic/Switch.vue +84 -0
  213. package/src/libs/Filter.js +593 -0
  214. package/src/libs/ansii.js +565 -0
  215. package/src/libs/panzoom.js +1413 -0
  216. package/src/main.js +23 -0
  217. package/src/registerServiceWorker.js +32 -0
  218. package/src/router/index.js +65 -0
  219. package/src/stores/cities.json +1 -0
  220. package/src/stores/connection.js +399 -0
  221. package/src/stores/countries.js +88 -0
  222. package/src/stores/logger.js +103 -0
  223. package/src/stores/requests.js +88 -0
  224. package/src/stores/sampleData.js +1034 -0
  225. package/src/stores/ui.js +584 -0
  226. package/src/stores/utils.js +554 -0
  227. package/src/types/index.js +42 -0
  228. package/src/utils/debug.js +1 -0
  229. package/src/views/Accounts.vue +191 -0
  230. package/src/views/Console.vue +224 -0
  231. package/src/views/Editor.vue +785 -0
  232. package/src/views/FilterBuilder.vue +785 -0
  233. package/src/views/Login.vue +27 -0
  234. package/src/views/Profiles.vue +209 -0
  235. package/src/views/Tasks.vue +157 -0
  236. package/static/offline.html +184 -0
  237. package/tailwind.config.js +57 -0
  238. package/vite.config.js +63 -0
  239. package/vue.config.js +32 -0
  240. package/workbox-config.js +66 -0
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <Modal>
3
+ <template #header> Scrape Venue <ScrapeIcon class="ml-4" /></template>
4
+ <!-- Event ID -->
5
+ <div class="input-wrapper mt-7 mb-4">
6
+ <label class="label-override mb-2">Event ID or URL <StadiumIcon /></label>
7
+ <div class="input-default required">
8
+ <input
9
+ :placeholder="!isEU(ui.currentCountry.siteId) ? '102PDA9125510GYU' : '529171'"
10
+ v-model="eventId"
11
+ />
12
+ </div>
13
+ </div>
14
+ <button
15
+ class="btn-action ml-auto"
16
+ @click="done()"
17
+ >
18
+ Scrape Venue <ScrapeIcon />
19
+ </button>
20
+ </Modal>
21
+ </template>
22
+ <style lang="scss" scoped>
23
+ .input-wrapper {
24
+ label {
25
+ @apply flex;
26
+ }
27
+ }
28
+ </style>
29
+ <script setup>
30
+ import Modal from "@/components/ui/Modal.vue";
31
+ import { StadiumIcon, ScrapeIcon } from "@/components/icons";
32
+ import { useUIStore } from "@/stores/ui";
33
+ import { ref } from "vue";
34
+ import { isEU } from "@/stores/utils";
35
+
36
+ const ui = useUIStore();
37
+ const eventId = ref("");
38
+ function done() {
39
+ ui.toggleModal("");
40
+ ui.scrapeVenue(eventId.value);
41
+ }
42
+ </script>
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <div class="flex text-white font-bold lg:gap-5 gap-1" v-if="show" :key="key">
3
+ <div
4
+ v-if="ui.queueStats.total"
5
+ class="bg-dark-500 mb-5 text-sm rounded-lg lg:p-2 p-1 lg:gap-3 gap-2 flex justify-between"
6
+ >
7
+ <h2 class="font-bold text-sm flex items-center gap-1 scale-100">
8
+ <img width="14px" src="@/assets/img/wildcard.svg" />Total MQM
9
+ </h2>
10
+ <span class="text-light-400 text-sm font-black flex justify-center">{{ ui.queueStats.total }} </span>
11
+ </div>
12
+ <div
13
+ v-if="ui.queueStats.queued"
14
+ class="bg-dark-500 mb-5 text-sm rounded-lg lg:p-2 p-1 lg:gap-3 gap-2 flex justify-between"
15
+ >
16
+ <h2 class="font-bold text-sm flex items-center gap-1"><SkiIcon />Queued</h2>
17
+ <span class="text-light-400 text-sm font-black flex justify-center">{{ ui.queueStats.queued }} </span>
18
+ </div>
19
+ <div
20
+ v-if="ui.queueStats.sleeping"
21
+ class="bg-dark-500 mb-5 text-sm rounded-lg lg:p-2 p-1 lg:gap-3 gap-2 flex justify-between"
22
+ >
23
+ <h2 class="font-bold text-sm flex items-center gap-1"><TimerIcon />Sleeping</h2>
24
+ <span class="text-light-400 text-sm font-black flex justify-center">{{ ui.queueStats.sleeping }} </span>
25
+ </div>
26
+ <div
27
+ v-if="ui.queueStats.nextQueuePasses.length > 0"
28
+ class="bg-dark-500 mb-5 rounded-lg text-sm flex justify-between lg:p-2 p-1 lg:gap-3 gap-2"
29
+ >
30
+ <h2 class="font-bold flex text-sm items-center gap-1">
31
+ <CartIcon /><span class="sm:block hidden">Next Passes</span>
32
+ <span class="sm:hidden block">Pass</span>
33
+ </h2>
34
+ <span class="text-light-400 text-sm font-black">{{
35
+ ui.queueStats.nextQueuePasses.slice(0, queuePassAmount).join(", ")
36
+ }}</span>
37
+ </div>
38
+ <!-- <div
39
+ v-if="ui.queueStats.carts"
40
+ class="bg-dark-500 mb-5 text-sm rounded-lg lg:p-2 p-1 lg:gap-3 gap-2 flex justify-between"
41
+ >
42
+ <h2 class="font-bold text-sm flex items-center gap-1"><CartIcon />Carts</h2>
43
+ <span class="text-light-400 text-sm font-black flex justify-center">{{ ui.queueStats.sleeping }} </span>
44
+ </div> -->
45
+ </div>
46
+ </template>
47
+
48
+ <script setup>
49
+ import { SkiIcon, TimerIcon, CartIcon } from "@/components/icons";
50
+ import { useUIStore } from "@/stores/ui";
51
+ import { ref } from "vue";
52
+
53
+ const ui = useUIStore();
54
+
55
+ const getQueuePassAmount = (width) => {
56
+ if (width > 1024) return 8;
57
+ if (width > 640) return 3;
58
+ return 1;
59
+ };
60
+
61
+ let show = ref(true);
62
+ let key = ref(0);
63
+ let queuePassAmount = ref(getQueuePassAmount(window.innerWidth));
64
+
65
+ window.addEventListener("resize", () => (queuePassAmount.value = getQueuePassAmount(window.innerWidth)));
66
+ </script>
@@ -0,0 +1,296 @@
1
+ <template>
2
+ {{ console.log(task) }}
3
+ <Row
4
+ class="relative text-white grid-cols-12 gap-2"
5
+ @click="ui.setOpenContextMenu('')"
6
+ @click.right.prevent="ui.setOpenContextMenu('')"
7
+ >
8
+ <div class="block md:hidden absolute left-1 top-0">
9
+ <h4 class="text-xs task-id text-white">
10
+ {{ props.task.taskId }}
11
+ </h4>
12
+ </div>
13
+ <div class="col-span-1 lg:col-span-2 flex">
14
+ <Checkbox
15
+ class="ml-0 mr-4"
16
+ :toggled="props.task.selected"
17
+ @valueUpdate="ui.toggleTaskSelected(props.task.taskId)"
18
+ />
19
+ <h4 class="task-id-alt mx-auto hidden md:block text-white" @click="copy(props.task.eventId)">
20
+ {{ props.task.eventId }}
21
+ </h4>
22
+ </div>
23
+ <div class="col-span-2 hidden md:block">
24
+ <h4 class="text-white">{{ props.task.quantity }}</h4>
25
+ </div>
26
+ <div class="col-span-2">
27
+ <h4 class="text-white">
28
+ <span v-if="!props.task.reservedTicketsList">-</span>
29
+ <div v-else>
30
+ <div v-for="l in props.task.reservedTicketsList.split(' | ')" :key="l">
31
+ <span v-if="!!l.trim()">{{ l.trim() }}</span>
32
+ </div>
33
+ </div>
34
+ <span
35
+ class="ml-1 font-bold"
36
+ :class="{
37
+ 'text-red-400': props.task._timeLeftString === '00:00' || props.task._timeLeftString === 'No Cartholds'
38
+ }"
39
+ >
40
+ {{ props.task._timeLeftString !== "00:00" ? props.task._timeLeftString : "Expired" }}
41
+ </span>
42
+ </h4>
43
+ </div>
44
+ <div class="col-span-6 md:col-span-4 lg:col-span-3 text-center justify-center">
45
+ <div class="flex md:gap-x-2 rounded-2xl w-fit shadow-3xl mx-auto items-center justify-center bg-dark-600">
46
+ <!-- Status circle -->
47
+ <div
48
+ class="status-indicator mx-1 md:ml-3 ml-2"
49
+ :class="colorToClass(
50
+ props.task.active || props.task.status.toLowerCase() === 'idle'
51
+ ? props.task.statusColor
52
+ : 'red'
53
+ )"
54
+ ></div>
55
+ <!-- Actual status -->
56
+ <span class="font-bold text-sm p-1 md:mr-3 mr-2 truncate uppercase">{{
57
+ truncate(props.task.status, statusTruncateLength)
58
+ }}</span>
59
+ </div>
60
+ </div>
61
+ <div class="col-span-2 flex">
62
+ <ul class="task-buttons">
63
+ <li>
64
+ <button v-if="task.active" @click="ui.stopTask(task.taskId)">
65
+ <PauseIcon />
66
+ </button>
67
+ <button v-else @click="ui.startTask(task.taskId)">
68
+ <PlayIcon />
69
+ </button>
70
+ </li>
71
+ <li v-if="task.status?.toLowerCase().includes('waiting') && props.task._timeLeftString !== '00:00'">
72
+ <button @click="ui.continueTask(task.taskId, 'autocheckout')">
73
+ <BagWhiteIcon />
74
+ </button>
75
+ </li>
76
+ <li v-if="task.status?.toLowerCase().includes('waiting')">
77
+ <button @click="ui.continueTask(task.taskId, 'change_reservation')">
78
+ <EditIcon />
79
+ </button>
80
+ </li>
81
+ <li>
82
+ <button @click="ui.deleteTask(task.taskId)">
83
+ <TrashIcon />
84
+ </button>
85
+ </li>
86
+ <li class="text-xl -mt-2" @click.right.prevent="window.setTimeout(() => ui.setOpenContextMenu(task.taskId), 10)">
87
+ <button class="mt-1" @click="props.task.isExpanded = !props.task.isExpanded">
88
+ <span>{{ props.task.isExpanded ? "-" : "+" }}</span>
89
+ </button>
90
+ </li>
91
+ </ul>
92
+ </div>
93
+ <div class="hidden md:block col-span-1 absolute right-5 top-4 lg:flex items-center justify-center">
94
+ <h4 class="text-center text-xs task-id text-white">
95
+ {{ props.task.taskId }}
96
+ </h4>
97
+ </div>
98
+ <transition name="fade">
99
+ <div
100
+ class="col-span-12 flex flex-wrap gap-x-4 gap-y-4 lg:gap-x-10 pt-8 pb-2 xl:justify-around will-change-auto"
101
+ v-if="props.task.isExpanded"
102
+ >
103
+
104
+ <!-- Details -->
105
+ <TaskLabel
106
+ class="md:hidden"
107
+ image="stadium_w"
108
+ :text="props.task.eventId"
109
+ @click="copy(props.task.eventId)"
110
+ />
111
+
112
+ <TaskLabel class="md:hidden" image="bag_w" :text="props.task.quantity" />
113
+ <TaskLabel
114
+ v-if="props.task.email"
115
+ image="mail"
116
+ :text="props.task.email"
117
+ @click="copy(props.task.email)"
118
+ />
119
+ <TaskLabel
120
+ v-if="props.task.password"
121
+ image="key"
122
+ :text="props.task.password"
123
+ @click="copy(props.task.password)"
124
+ />
125
+ <TaskLabel v-if="!props.task.email && !props.task.password" image="mail" text="No account chosen yet" />
126
+ <TaskLabel v-if="props.task.profileName" image="profile" :text="props.task.profileName" />
127
+ <TaskLabel image="camera" :text="props.task.proxy" @click="copy(props.task.proxy)" />
128
+ <TaskLabel image="timer" :text="props.task.smartTimer ? 'On' : 'Off'" />
129
+ <TaskLabel image="groups" :text="props.task.loginAfterCart ? 'On' : 'Off'" />
130
+ <TaskLabel image="hand" :text="props.task.manual ? 'On' : 'Off'" />
131
+ <TaskLabel image="savings" :text="props.task.doNotPay ? 'On' : 'Off'" />
132
+ <TaskLabel image="loyalty" :text="props.task.presaleMode ? 'On' : 'Off'" />
133
+ <TaskLabel image="ski" :text="props.task.quickQueue ? 'On' : 'Off'" />
134
+ <TaskLabel image="scanner" :text="props.task.accountTag" />
135
+ <TaskLabel image="sell" :text="props.task.profileTags.join(', ')" />
136
+ <TaskLabel
137
+ v-if="props.task.presaleCode"
138
+ @click="copy(props.task.presaleCode)"
139
+ image="pencil"
140
+ :text="props.task.presaleCode"
141
+ />
142
+
143
+ <TaskLabel v-if="props.task.eventName" image="stadium_w" :text="props.task.eventName" />
144
+ <TaskLabel v-if="props.task.eventVenue" image="stadium_w" :text="props.task.eventVenue" />
145
+ <TaskLabel
146
+ v-if="props.task.eventLocalDate"
147
+ image="stadium_w"
148
+ :text="formatDate(props.task.eventLocalDate)"
149
+ />
150
+ <TaskLabel image="sandclock" :text="props.task.agedAccount ? 'On' : 'Off'" />
151
+ </div>
152
+ </transition>
153
+
154
+ <!-- Context menu -->
155
+
156
+ <div class="absolute -bottom-1.5 right-5">
157
+ <transition name="fade">
158
+ <div
159
+ v-if="ui.openContextMenu === task.taskId"
160
+ class="bg-light-300 text-white w-42 grid grid-cols-1 p-1 gap-1 z-50 rounded-lg shadow-xl relative"
161
+ >
162
+ <button class="btn-primary" @click="openInNewTab(`${ui.currentCountry.url}/event/${task.eventId}`)">
163
+ Open Event
164
+ </button>
165
+ <button v-if="task.openerLink" class="btn-primary" @click="openInBrowser(false)">
166
+ Open in browser (proxy)
167
+ </button>
168
+ <button v-if="task.openerLink" class="btn-primary" @click="openInBrowser(true)">
169
+ Open in browser (debug)
170
+ </button>
171
+ </div>
172
+ </transition>
173
+ </div>
174
+ </Row>
175
+ </template>
176
+ <style lang="scss" scoped>
177
+ h4 {
178
+ @apply text-center;
179
+ }
180
+
181
+ .task-buttons {
182
+ @apply flex mx-auto gap-x-2;
183
+
184
+ button {
185
+ @apply p-1 rounded transition-colors hover:bg-dark-500;
186
+ }
187
+
188
+ svg {
189
+ @apply w-4 h-4;
190
+ }
191
+
192
+ img {
193
+ @apply w-4 h-4;
194
+ }
195
+ }
196
+
197
+ @media (max-width: 1024px) {
198
+ h4 {
199
+ font-size: 10px;
200
+ }
201
+
202
+ .task-buttons {
203
+ @apply gap-x-1;
204
+ }
205
+
206
+ .task-id {
207
+ font-size: 6px;
208
+ }
209
+
210
+ .task-id-alt {
211
+ font-size: 7px;
212
+ }
213
+ }
214
+ </style>
215
+
216
+ <script setup>
217
+ /// <reference path="@/types/index.js" />
218
+
219
+ import { Row } from "@/components/Table";
220
+ import { PlayIcon, TrashIcon, BagWhiteIcon, PauseIcon, EditIcon } from "@/components/icons";
221
+ import Checkbox from "@/components/ui/controls/atomic/Checkbox.vue";
222
+ import { useUIStore } from "@/stores/ui";
223
+ import TaskLabel from "@/components/Tasks/TaskLabel.vue";
224
+ import { ref } from "vue";
225
+
226
+ const ui = useUIStore();
227
+
228
+ /** @type {{ task: Task }} */
229
+ const props = defineProps({
230
+ task: { type: Object }
231
+ });
232
+
233
+ const copy = (txt) => {
234
+ if (!txt) return;
235
+ navigator.clipboard.writeText(txt);
236
+ ui.showSuccess("Copied text");
237
+ };
238
+
239
+ const colorMapping = new Map();
240
+ colorMapping.set("green", "bg-green-400");
241
+ colorMapping.set("red", "bg-red-400");
242
+ colorMapping.set("error", "bg-red-400");
243
+ colorMapping.set("success", "bg-green-400");
244
+ const colorToClass = (color) => {
245
+ return colorMapping.get(color) || "bg-white";
246
+ };
247
+
248
+ const truncate = (text, after) => {
249
+ if (text?.length <= after || after === -1) return text;
250
+ return text?.substring(0, after) + "...";
251
+ };
252
+
253
+ const openInBrowser = (debug) => {
254
+ if (!props.task.openerLink) return;
255
+ ui.showSuccess(`Opening in browser ${debug ? "(debug)" : ""}`);
256
+ const input = props.task.openerLink;
257
+ const data = JSON.parse(atob(input.split("://")[1]));
258
+ data.config.debug = debug;
259
+ const out = "necro://" + btoa(JSON.stringify(data));
260
+ openInNewTab(out);
261
+ };
262
+
263
+ const formatDate = (date) => {
264
+ if (!date) return "-";
265
+ const d = new Date(date);
266
+ const iso = d.toISOString();
267
+ const [year, month, day] = iso.substring(0, 10).split("-");
268
+ const time = iso.substring(11, 16);
269
+ const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
270
+ const dayName = dayNames[d.getUTCDay()];
271
+ const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
272
+ const monthName = monthNames[parseInt(month) - 1];
273
+ return `${dayName} ${monthName} ${parseInt(day)} ${year} ${time}`;
274
+ };
275
+
276
+ const openInNewTab = (href) => {
277
+ if (!href) return;
278
+ ui.logger.Info("Opening", href);
279
+ Object.assign(document.createElement("a"), {
280
+ target: "_blank",
281
+ rel: "noopener noreferrer",
282
+ href: href
283
+ }).click();
284
+ };
285
+
286
+ const getMaxStatusLength = (width) => {
287
+ if (width > 1279) return -1;
288
+ if (width > 767) return 25;
289
+ if (width > 639) return 30;
290
+ if (width > 540) return 18;
291
+ return 13;
292
+ };
293
+
294
+ let statusTruncateLength = ref(getMaxStatusLength(window.innerWidth));
295
+ window.addEventListener("resize", () => (statusTruncateLength.value = getMaxStatusLength(window.innerWidth)));
296
+ </script>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <div class="flex rounded-2xl gap-x-2 w-fit shadow-3xl mx-auto items-center justify-center bg-dark-600">
3
+ <img class="ml-3" v-if="logo" :src="logo" />
4
+ <div v-else class="ml-3"></div>
5
+ <span class="font-bold p-2 truncate mr-3">{{ text }}</span>
6
+ </div>
7
+ </template>
8
+
9
+ <script setup>
10
+ import { ref } from "vue";
11
+
12
+ const props = defineProps({
13
+ image: { type: String },
14
+ text: { type: String }
15
+ });
16
+
17
+ const logo = ref(`/img/${props.image}.svg`);
18
+ if (!props.image) logo.value = "";
19
+ const text = ref(props.text);
20
+ </script>
@@ -0,0 +1,126 @@
1
+ <template>
2
+ <Table>
3
+ <Header class="text-center grid-cols-12 gap-2">
4
+ <div class="col-span-1 lg:col-span-2 flex">
5
+ <Checkbox class="mr-3" :toggled="ui.mainCheckbox.tasks" @valueUpdate="ui.toggleMainCheckbox('tasks')" />
6
+ <div class="mx-auto hidden md:flex items-center" @click="ui.toggleSort('eventId')">
7
+ <EventIcon class="ipadlg:mr-3" />
8
+ <h4 class="hidden ipadlg:flex">Event</h4>
9
+ <DownIcon v-if="ui.sortData.sortBy === 'eventId' && !ui.sortData.reversed" class="ml-1" />
10
+ <UpIcon v-if="ui.sortData.sortBy === 'eventId' && ui.sortData.reversed" class="ml-1" />
11
+ </div>
12
+ </div>
13
+ <div class="col-span-2 items-center justify-center hidden md:flex" v-once>
14
+ <CartIcon class="mr-0 ipadlg:mr-3" />
15
+
16
+ <h4 class="hidden ipadlg:flex">Quantity</h4>
17
+ </div>
18
+ <div class="col-span-2 flex-center" v-once>
19
+ <TicketIcon class="mr-0 ipadlg:mr-3" />
20
+ <h4 class="hidden ipadlg:flex">Tickets</h4>
21
+ </div>
22
+ <div
23
+ class="col-span-6 md:col-span-4 lg:col-span-3 flex-center"
24
+ @click="ui.toggleSort('status')"
25
+ >
26
+ <StatusIcon class="mr-0 ipadlg:mr-3" />
27
+ <h4 class="hidden ipadlg:flex">Status</h4>
28
+ <DownIcon v-if="ui.sortData.sortBy === 'status' && !ui.sortData.reversed" class="ml-1" />
29
+ <UpIcon v-if="ui.sortData.sortBy === 'status' && ui.sortData.reversed" class="ml-1" />
30
+ </div>
31
+ <div class="col-span-2 flex-center" v-once>
32
+ <ClickIcon class="mr-0 ipadlg:mr-3" />
33
+ <h4 class="hidden ipadlg:flex">Actions</h4>
34
+ </div>
35
+ <div class="absolute right-5 hidden md:flex items-center top-3,5" @click="ui.toggleSort('taskId')">
36
+ <h4 class="">ID</h4>
37
+ <DownIcon v-if="ui.sortData.sortBy === 'taskId' && !ui.sortData.reversed" class="ml-1" />
38
+ <UpIcon v-if="ui.sortData.sortBy === 'taskId' && ui.sortData.reversed" class="ml-1" />
39
+ </div>
40
+ </Header>
41
+ <div
42
+ class="flex flex-col divide-y-2 divide-border overflow-y-auto hidden-scrollbars overflow-x-hidden stop-pan max-h-big tasks-table-height"
43
+ >
44
+ <div v-for="(task, i) in getTasksInOrder()" :key="i">
45
+ <Task :task="task" :class="[i % 2 == 1 ? 'bg-dark-500' : 'bg-dark-550']" />
46
+ </div>
47
+ <div
48
+ v-if="getTasksInOrder().length === 0"
49
+ class="flex justify-center text-light-400 py-2 bg-dark-500 border-b-2 border-border"
50
+ >
51
+ <span v-if="ui.queueStats.total === 0"> No tasks yet.</span>
52
+ <span v-else>{{ ui.queueStats.total }} hidden task{{ ui.queueStats.total === 1 ? "" : "s" }}</span>
53
+ </div>
54
+ </div>
55
+ </Table>
56
+ </template>
57
+ <style lang="scss" scoped>
58
+ h4 {
59
+ @apply text-white;
60
+ }
61
+
62
+ .stop-pan {
63
+ touch-action: pan-y pan-up pan-down;
64
+ }
65
+
66
+ .tasks-table-height {
67
+ max-height: 33rem !important;
68
+ }
69
+
70
+ @media only screen and (min-device-width: 768px) and (max-device-width: 1366px) and (orientation: landscape) and (-webkit-min-device-pixel-ratio: 2) {
71
+ .tasks-table-height {
72
+ max-height: 45vh !important;
73
+ }
74
+ }
75
+
76
+ @media only screen and (min-device-width: 768px) and (max-device-width: 1366px) and (orientation: portrait) and (-webkit-min-device-pixel-ratio: 2) {
77
+ .tasks-table-height {
78
+ max-height: 58vh !important;
79
+ }
80
+ }
81
+ </style>
82
+ <script setup>
83
+ import { Table, Header } from "@/components/Table";
84
+ import { EventIcon, CartIcon, TicketIcon, StatusIcon, ClickIcon, DownIcon, UpIcon } from "@/components/icons";
85
+ import Task from "./Task.vue";
86
+ import Checkbox from "@/components/ui/controls/atomic/Checkbox.vue";
87
+ import { useUIStore } from "@/stores/ui";
88
+
89
+ const props = defineProps({
90
+ tasks: { type: Object }
91
+ });
92
+
93
+ const shouldTaskShow = (task) => {
94
+ if (ui.taskFilter === "All") return true;
95
+ else if (ui.taskFilter === "Checkout") return task.expirationTime || task.noCartholds;
96
+ else return true;
97
+ };
98
+
99
+ const ui = useUIStore();
100
+
101
+ const siteIdEdgeCases = {
102
+ LN_US: ["TM_US"],
103
+ TM_CA: ["TM_US"],
104
+ TM_IE: ["TM_UK"],
105
+ TM_NZ: ["TM_AU"]
106
+ };
107
+
108
+ const getTasksInOrder = () => {
109
+ let out = [];
110
+ ui.taskIdOrder.forEach((id) => {
111
+ if (props.tasks[id] && !props.tasks[id]?.hidden) {
112
+ const task = props.tasks[id];
113
+
114
+ if (
115
+ task.siteId !== ui.currentCountry.siteId &&
116
+ !siteIdEdgeCases[task.siteId]?.includes(ui.currentCountry.siteId)
117
+ )
118
+ return;
119
+ if (ui.currentEvent && task.eventId !== ui.currentEvent) return;
120
+ if (!shouldTaskShow(task)) return;
121
+ out.push(task);
122
+ }
123
+ });
124
+ return out;
125
+ };
126
+ </script>
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div class="grid grid-cols-1 gap-3 lg:grid-cols-1" v-once v-if="ui.currentModule == 'TM'">
3
+ <div class="lg:justify-self-end">
4
+ <h4 class="hidden lg:block text-white opacity-40 uppercase font-medium">Utils</h4>
5
+ <div class="flex gap-3">
6
+ <button class="button-default active:opacity-50 w-44" @click="ui.toggleModal('scrape-venue')">
7
+ <ScrapeIcon />
8
+ Scrape Venue
9
+ </button>
10
+ <button class="button-default w-44" @click="ui.toggleModal('check-stock')">
11
+ <BoxIcon />Check Stock
12
+ </button>
13
+ <!-- Mobile Label -->
14
+ </div>
15
+ <h4 class="text-white opacity-40 uppercase font-medium block lg:hidden">Utils</h4>
16
+ </div>
17
+ </div>
18
+ </template>
19
+ <script setup>
20
+ import { BoxIcon, ScrapeIcon, CameraIcon, GroupIcon } from "@/components/icons";
21
+ import { useUIStore } from "@/stores/ui";
22
+
23
+ const ui = useUIStore();
24
+ </script>
25
+ <style lang="scss" scoped>
26
+ button {
27
+ height: 50px;
28
+ @apply bg-dark-400 text-xs flex items-center justify-center gap-x-2 border border-light-300 hover:border-light-400;
29
+ }
30
+ h4 {
31
+ font-size: 12px;
32
+ }
33
+ </style>
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <svg width="8" height="16" viewBox="0 0 8 16" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <path
4
+ d="M0.25 0.5H7.75V6.3875C7.75 6.675 7.6875 6.93125 7.5625 7.15625C7.4375 7.38125 7.2625 7.5625 7.0375 7.7L4.375 9.275L4.9 11H7.75L5.425 12.65L6.325 15.5L4 13.7375L1.675 15.5L2.575 12.65L0.25 11H3.1L3.625 9.275L0.9625 7.7C0.7375 7.5625 0.5625 7.38125 0.4375 7.15625C0.3125 6.93125 0.25 6.675 0.25 6.3875V0.5ZM1.75 2V6.3875L3.25 7.2875V2H1.75ZM6.25 2H4.75V7.2875L6.25 6.3875V2Z"
5
+ fill="white"
6
+ />
7
+ </svg>
8
+ </template>
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <svg width="15" height="18" viewBox="0 0 15 18" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <path
4
+ d="M1.95833 17.4167C1.52292 17.4167 1.15004 17.2618 0.839708 16.952C0.529903 16.6416 0.375 16.2688 0.375 15.8334V6.33335C0.375 5.89794 0.529903 5.52533 0.839708 5.21552C1.15004 4.90519 1.52292 4.75002 1.95833 4.75002H3.54167C3.54167 3.65488 3.92774 2.72124 4.69988 1.9491C5.47149 1.17749 6.40486 0.791687 7.5 0.791687C8.59514 0.791687 9.52878 1.17749 10.3009 1.9491C11.0725 2.72124 11.4583 3.65488 11.4583 4.75002H13.0417C13.4771 4.75002 13.85 4.90519 14.1603 5.21552C14.4701 5.52533 14.625 5.89794 14.625 6.33335V15.8334C14.625 16.2688 14.4701 16.6416 14.1603 16.952C13.85 17.2618 13.4771 17.4167 13.0417 17.4167H1.95833ZM1.95833 15.8334H13.0417V6.33335H1.95833V15.8334ZM7.5 11.0834C8.59514 11.0834 9.52878 10.6973 10.3009 9.92515C11.0725 9.15353 11.4583 8.22016 11.4583 7.12502H9.875C9.875 7.78474 9.6441 8.34551 9.18229 8.80731C8.72049 9.26912 8.15972 9.50002 7.5 9.50002C6.84028 9.50002 6.27951 9.26912 5.81771 8.80731C5.3559 8.34551 5.125 7.78474 5.125 7.12502H3.54167C3.54167 8.22016 3.92774 9.15353 4.69988 9.92515C5.47149 10.6973 6.40486 11.0834 7.5 11.0834ZM5.125 4.75002H9.875C9.875 4.0903 9.6441 3.52953 9.18229 3.06773C8.72049 2.60592 8.15972 2.37502 7.5 2.37502C6.84028 2.37502 6.27951 2.60592 5.81771 3.06773C5.3559 3.52953 5.125 4.0903 5.125 4.75002Z"
5
+ fill="#6E7084"
6
+ />
7
+ </svg>
8
+ </template>
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <svg width="15" height="18" viewBox="0 0 15 18" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <path
4
+ d="M1.95833 17.4167C1.52292 17.4167 1.15004 17.2618 0.839708 16.952C0.529903 16.6416 0.375 16.2688 0.375 15.8334V6.33335C0.375 5.89794 0.529903 5.52533 0.839708 5.21552C1.15004 4.90519 1.52292 4.75002 1.95833 4.75002H3.54167C3.54167 3.65488 3.92774 2.72124 4.69988 1.9491C5.47149 1.17749 6.40486 0.791687 7.5 0.791687C8.59514 0.791687 9.52878 1.17749 10.3009 1.9491C11.0725 2.72124 11.4583 3.65488 11.4583 4.75002H13.0417C13.4771 4.75002 13.85 4.90519 14.1603 5.21552C14.4701 5.52533 14.625 5.89794 14.625 6.33335V15.8334C14.625 16.2688 14.4701 16.6416 14.1603 16.952C13.85 17.2618 13.4771 17.4167 13.0417 17.4167H1.95833ZM1.95833 15.8334H13.0417V6.33335H1.95833V15.8334ZM7.5 11.0834C8.59514 11.0834 9.52878 10.6973 10.3009 9.92515C11.0725 9.15353 11.4583 8.22016 11.4583 7.12502H9.875C9.875 7.78474 9.6441 8.34551 9.18229 8.80731C8.72049 9.26912 8.15972 9.50002 7.5 9.50002C6.84028 9.50002 6.27951 9.26912 5.81771 8.80731C5.3559 8.34551 5.125 7.78474 5.125 7.12502H3.54167C3.54167 8.22016 3.92774 9.15353 4.69988 9.92515C5.47149 10.6973 6.40486 11.0834 7.5 11.0834ZM5.125 4.75002H9.875C9.875 4.0903 9.6441 3.52953 9.18229 3.06773C8.72049 2.60592 8.15972 2.37502 7.5 2.37502C6.84028 2.37502 6.27951 2.60592 5.81771 3.06773C5.3559 3.52953 5.125 4.0903 5.125 4.75002Z"
5
+ fill="#ffffff"
6
+ />
7
+ </svg>
8
+ </template>
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <path
4
+ d="M1.25 14V5.525C1.0375 5.3875 0.8595 5.2125 0.716 5C0.572 4.7875 0.5 4.5375 0.5 4.25V2C0.5 1.5875 0.647 1.23425 0.941 0.94025C1.2345 0.64675 1.5875 0.5 2 0.5H14C14.4125 0.5 14.7658 0.64675 15.0598 0.94025C15.3533 1.23425 15.5 1.5875 15.5 2V4.25C15.5 4.5375 15.428 4.7875 15.284 5C15.1405 5.2125 14.9625 5.3875 14.75 5.525V14C14.75 14.4125 14.6033 14.7658 14.3098 15.0598C14.0158 15.3533 13.6625 15.5 13.25 15.5H2.75C2.3375 15.5 1.98425 15.3533 1.69025 15.0598C1.39675 14.7658 1.25 14.4125 1.25 14ZM2.75 5.75V14H13.25V5.75H2.75ZM14 4.25V2H2V4.25H14ZM5.75 9.5H10.25V8H5.75V9.5Z"
5
+ fill="white"
6
+ />
7
+ </svg>
8
+ </template>
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <path
4
+ d="M7.55 5.75H13.55C13.2125 4.8875 12.697 4.14675 12.0035 3.52775C11.3095 2.90925 10.5125 2.475 9.6125 2.225L7.55 5.75ZM5.825 7.25L8.825 2.075C8.6875 2.05 8.55 2.03125 8.4125 2.01875C8.275 2.00625 8.1375 2 8 2C7.175 2 6.40625 2.15625 5.69375 2.46875C4.98125 2.78125 4.35 3.2 3.8 3.725L5.825 7.25ZM2.1875 9.5H6.275L3.275 4.325C2.875 4.8375 2.5625 5.40325 2.3375 6.02225C2.1125 6.64075 2 7.3 2 8C2 8.2625 2.0155 8.5155 2.0465 8.759C2.078 9.003 2.125 9.25 2.1875 9.5ZM6.3875 13.775L8.4125 10.25H2.45C2.7875 11.1125 3.30325 11.853 3.99725 12.4715C4.69075 13.0905 5.4875 13.525 6.3875 13.775ZM8 14C8.825 14 9.59375 13.8437 10.3062 13.5312C11.0187 13.2188 11.65 12.8 12.2 12.275L10.175 8.75L7.175 13.925C7.3125 13.95 7.447 13.9688 7.5785 13.9813C7.7095 13.9938 7.85 14 8 14ZM12.725 11.675C13.125 11.1625 13.4375 10.5968 13.6625 9.97775C13.8875 9.35925 14 8.7 14 8C14 7.7375 13.9845 7.4845 13.9535 7.241C13.922 6.997 13.875 6.75 13.8125 6.5H9.725L12.725 11.675ZM8 15.5C6.975 15.5 6.00625 15.303 5.09375 14.909C4.18125 14.5155 3.3845 13.978 2.7035 13.2965C2.022 12.6155 1.4845 11.8188 1.091 10.9062C0.697 9.99375 0.5 9.025 0.5 8C0.5 6.9625 0.697 5.99075 1.091 5.08475C1.4845 4.17825 2.022 3.3845 2.7035 2.7035C3.3845 2.022 4.18125 1.48425 5.09375 1.09025C6.00625 0.69675 6.975 0.5 8 0.5C9.0375 0.5 10.0093 0.69675 10.9153 1.09025C11.8218 1.48425 12.6155 2.022 13.2965 2.7035C13.978 3.3845 14.5155 4.17825 14.909 5.08475C15.303 5.99075 15.5 6.9625 15.5 8C15.5 9.025 15.303 9.99375 14.909 10.9062C14.5155 11.8188 13.978 12.6155 13.2965 13.2965C12.6155 13.978 11.8218 14.5155 10.9153 14.909C10.0093 15.303 9.0375 15.5 8 15.5Z"
5
+ fill="white"
6
+ />
7
+ </svg>
8
+ </template>
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <path
4
+ d="M6.125 18.25C5.64375 18.25 5.23192 18.0788 4.8895 17.7364C4.5465 17.3934 4.375 16.9813 4.375 16.5C4.375 16.0187 4.5465 15.6066 4.8895 15.2636C5.23192 14.9212 5.64375 14.75 6.125 14.75C6.60625 14.75 7.01808 14.9212 7.3605 15.2636C7.7035 15.6066 7.875 16.0187 7.875 16.5C7.875 16.9813 7.7035 17.3934 7.3605 17.7364C7.01808 18.0788 6.60625 18.25 6.125 18.25ZM14.875 18.25C14.3937 18.25 13.9819 18.0788 13.6395 17.7364C13.2965 17.3934 13.125 16.9813 13.125 16.5C13.125 16.0187 13.2965 15.6066 13.6395 15.2636C13.9819 14.9212 14.3937 14.75 14.875 14.75C15.3563 14.75 15.7684 14.9212 16.1114 15.2636C16.4538 15.6066 16.625 16.0187 16.625 16.5C16.625 16.9813 16.4538 17.3934 16.1114 17.7364C15.7684 18.0788 15.3563 18.25 14.875 18.25ZM5.38125 4.25L7.48125 8.625H13.6062L16.0125 4.25H5.38125ZM4.55 2.5H17.4563C17.7917 2.5 18.0469 2.64933 18.2219 2.948C18.3969 3.24725 18.4042 3.55 18.2437 3.85625L15.1375 9.45625C14.9771 9.74792 14.7618 9.97396 14.4918 10.1344C14.2223 10.2948 13.9271 10.375 13.6062 10.375H7.0875L6.125 12.125H16.625V13.875H6.125C5.46875 13.875 4.97292 13.5868 4.6375 13.0105C4.30208 12.4347 4.2875 11.8625 4.59375 11.2937L5.775 9.15L2.625 2.5H0.875V0.75H3.71875L4.55 2.5Z"
5
+ fill="white"
6
+ />
7
+ </svg>
8
+ </template>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <svg class="w-4 h-4" viewBox="0 0 24 24" fill="currentColor">
3
+ <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z"/>
4
+ </svg>
5
+ </template>