Boobs00 commited on
Commit
c844a46
·
verified ·
1 Parent(s): 307c30e

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +6 -4
  2. index.html +1572 -19
  3. prompts.txt +0 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Plugin Library
3
- emoji: 👁
4
- colorFrom: green
5
  colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: plugin-library
3
+ emoji: 🐳
4
+ colorFrom: pink
5
  colorTo: yellow
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,1572 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Hermit Dev Tools Pro - Ultimate Plugin Ecosystem</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
9
+ <script>
10
+ tailwind.config = {
11
+ darkMode: 'class',
12
+ theme: {
13
+ extend: {
14
+ colors: {
15
+ 'hermit-blue': '#2563eb',
16
+ 'hermit-purple': '#7c3aed',
17
+ 'hermit-pink': '#ec4899',
18
+ 'hermit-dark': '#1e293b',
19
+ 'hermit-light': '#f8fafc',
20
+ 'hermit-teal': '#0d9488',
21
+ 'hermit-orange': '#ea580c',
22
+ },
23
+ fontFamily: {
24
+ 'sans': ['Inter', 'ui-sans-serif', 'system-ui'],
25
+ 'mono': ['Fira Code', 'ui-monospace', 'SFMono-Regular'],
26
+ },
27
+ animation: {
28
+ 'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
29
+ 'bounce-slow': 'bounce 2s infinite',
30
+ 'spin-slow': 'spin 3s linear infinite',
31
+ }
32
+ }
33
+ }
34
+ }
35
+ </script>
36
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
37
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Fira+Code:wght@400;500&display=swap">
38
+ <style>
39
+ :root {
40
+ --hermit-accent: #2563eb;
41
+ --hermit-secondary: #7c3aed;
42
+ --hermit-danger: #dc2626;
43
+ --hermit-success: #16a34a;
44
+ --hermit-warning: #d97706;
45
+ }
46
+
47
+ body {
48
+ font-family: 'Inter', sans-serif;
49
+ background-color: #f8fafc;
50
+ color: #1e293b;
51
+ transition: all 0.3s ease;
52
+ }
53
+
54
+ .dark-mode {
55
+ background-color: #0f172a;
56
+ color: #f8fafc;
57
+ }
58
+
59
+ .code-font {
60
+ font-family: 'Fira Code', monospace;
61
+ font-feature-settings: 'calt' 1;
62
+ }
63
+
64
+ /* Plugin Card Enhancements */
65
+ .plugin-card {
66
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
67
+ border: 1px solid #e2e8f0;
68
+ position: relative;
69
+ overflow: hidden;
70
+ background: linear-gradient(145deg, #ffffff, #f8fafc);
71
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
72
+ }
73
+
74
+ .dark-mode .plugin-card {
75
+ background: linear-gradient(145deg, #1e293b, #0f172a);
76
+ border-color: #334155;
77
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.2);
78
+ }
79
+
80
+ .plugin-card:hover {
81
+ transform: translateY(-5px);
82
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
83
+ border-color: var(--hermit-accent);
84
+ }
85
+
86
+ .plugin-card::before {
87
+ content: '';
88
+ position: absolute;
89
+ top: 0;
90
+ left: 0;
91
+ width: 4px;
92
+ height: 0;
93
+ background: linear-gradient(to bottom, var(--hermit-accent), var(--hermit-purple));
94
+ transition: height 0.3s ease;
95
+ }
96
+
97
+ .plugin-card:hover::before {
98
+ height: 100%;
99
+ }
100
+
101
+ /* Star Rating */
102
+ .star-rating {
103
+ color: #fbbf24;
104
+ }
105
+
106
+ .star-rating .empty {
107
+ color: #e2e8f0;
108
+ }
109
+
110
+ .dark-mode .star-rating .empty {
111
+ color: #334155;
112
+ }
113
+
114
+ /* Tabs */
115
+ .tab-active {
116
+ border-bottom: 3px solid var(--hermit-accent);
117
+ color: var(--hermit-accent);
118
+ font-weight: 600;
119
+ }
120
+
121
+ /* Badges */
122
+ .plugin-badge {
123
+ position: absolute;
124
+ top: -8px;
125
+ right: -8px;
126
+ width: 24px;
127
+ height: 24px;
128
+ border-radius: 50%;
129
+ display: flex;
130
+ align-items: center;
131
+ justify-content: center;
132
+ font-size: 12px;
133
+ font-weight: 600;
134
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
135
+ z-index: 10;
136
+ }
137
+
138
+ /* Dropdown */
139
+ .dropdown-content {
140
+ display: none;
141
+ position: absolute;
142
+ right: 0;
143
+ min-width: 200px;
144
+ z-index: 50;
145
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
146
+ border-radius: 0.5rem;
147
+ background-color: white;
148
+ }
149
+
150
+ .dark-mode .dropdown-content {
151
+ background-color: #1e293b;
152
+ border: 1px solid #334155;
153
+ }
154
+
155
+ .dropdown:hover .dropdown-content {
156
+ display: block;
157
+ animation: fadeIn 0.2s ease-out;
158
+ }
159
+
160
+ /* Progress Bar */
161
+ .progress-bar {
162
+ height: 6px;
163
+ border-radius: 3px;
164
+ background-color: #e5e7eb;
165
+ }
166
+
167
+ .dark-mode .progress-bar {
168
+ background-color: #334155;
169
+ }
170
+
171
+ .progress-fill {
172
+ height: 100%;
173
+ border-radius: 3px;
174
+ background: linear-gradient(to right, var(--hermit-accent), var(--hermit-purple));
175
+ transition: width 0.3s ease;
176
+ }
177
+
178
+ /* Loading Skeletons */
179
+ .skeleton {
180
+ animation: pulse 2s infinite;
181
+ background-color: #e5e7eb;
182
+ border-radius: 4px;
183
+ }
184
+
185
+ .dark-mode .skeleton {
186
+ background-color: #334155;
187
+ }
188
+
189
+ /* Tags */
190
+ .tag {
191
+ transition: all 0.2s ease;
192
+ font-size: 0.75rem;
193
+ padding: 0.25rem 0.5rem;
194
+ border-radius: 9999px;
195
+ }
196
+
197
+ .tag:hover {
198
+ transform: scale(1.05);
199
+ }
200
+
201
+ /* Modals */
202
+ .modal-overlay {
203
+ background-color: rgba(0, 0, 0, 0.5);
204
+ backdrop-filter: blur(5px);
205
+ }
206
+
207
+ .modal-content {
208
+ animation: modalFadeIn 0.3s ease-out;
209
+ max-height: 90vh;
210
+ overflow-y: auto;
211
+ }
212
+
213
+ /* Plugin Icons */
214
+ .plugin-icon {
215
+ transition: all 0.3s ease;
216
+ width: 48px;
217
+ height: 48px;
218
+ display: flex;
219
+ align-items: center;
220
+ justify-content: center;
221
+ border-radius: 12px;
222
+ background: linear-gradient(135deg, rgba(37, 99, 235, 0.1), rgba(124, 58, 237, 0.1));
223
+ }
224
+
225
+ .dark-mode .plugin-icon {
226
+ background: linear-gradient(135deg, rgba(37, 99, 235, 0.2), rgba(124, 58, 237, 0.2));
227
+ }
228
+
229
+ .plugin-card:hover .plugin-icon {
230
+ transform: rotate(10deg) scale(1.1);
231
+ }
232
+
233
+ /* Search Input */
234
+ .search-input {
235
+ transition: all 0.3s ease;
236
+ background-color: white;
237
+ }
238
+
239
+ .dark-mode .search-input {
240
+ background-color: #1e293b;
241
+ border-color: #334155;
242
+ color: #f8fafc;
243
+ }
244
+
245
+ .search-input:focus {
246
+ box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
247
+ }
248
+
249
+ /* Buttons */
250
+ .install-btn {
251
+ position: relative;
252
+ overflow: hidden;
253
+ transition: all 0.3s ease;
254
+ }
255
+
256
+ .install-btn::after {
257
+ content: '';
258
+ position: absolute;
259
+ top: 50%;
260
+ left: 50%;
261
+ width: 5px;
262
+ height: 5px;
263
+ background: rgba(255, 255, 255, 0.5);
264
+ opacity: 0;
265
+ border-radius: 100%;
266
+ transform: scale(1, 1) translate(-50%, -50%);
267
+ transform-origin: 50% 50%;
268
+ }
269
+
270
+ .install-btn:focus:not(:active)::after {
271
+ animation: ripple 1s ease-out;
272
+ }
273
+
274
+ /* Notifications */
275
+ .notification-badge {
276
+ animation: ping 2s cubic-bezier(0, 0, 0.2, 1) infinite;
277
+ }
278
+
279
+ /* Sidebar */
280
+ .sidebar {
281
+ transition: all 0.3s ease;
282
+ }
283
+
284
+ .sidebar-item {
285
+ transition: all 0.2s ease;
286
+ border-radius: 0.375rem;
287
+ }
288
+
289
+ .sidebar-item:hover {
290
+ background-color: rgba(37, 99, 235, 0.1);
291
+ }
292
+
293
+ .sidebar-item.active {
294
+ background-color: rgba(37, 99, 235, 0.1);
295
+ border-left: 3px solid var(--hermit-accent);
296
+ }
297
+
298
+ /* Animations */
299
+ @keyframes fadeIn {
300
+ from { opacity: 0; transform: translateY(-10px); }
301
+ to { opacity: 1; transform: translateY(0); }
302
+ }
303
+
304
+ @keyframes modalFadeIn {
305
+ from { opacity: 0; transform: translateY(20px); }
306
+ to { opacity: 1; transform: translateY(0); }
307
+ }
308
+
309
+ @keyframes ripple {
310
+ 0% {
311
+ transform: scale(0, 0);
312
+ opacity: 0.5;
313
+ }
314
+ 100% {
315
+ transform: scale(20, 20);
316
+ opacity: 0;
317
+ }
318
+ }
319
+
320
+ @keyframes ping {
321
+ 75%, 100% {
322
+ transform: scale(1.2);
323
+ opacity: 0;
324
+ }
325
+ }
326
+
327
+ @keyframes pulse {
328
+ 0%, 100% { opacity: 1; }
329
+ 50% { opacity: 0.5; }
330
+ }
331
+
332
+ /* Custom Scrollbar */
333
+ ::-webkit-scrollbar {
334
+ width: 8px;
335
+ height: 8px;
336
+ }
337
+
338
+ ::-webkit-scrollbar-track {
339
+ background: #f1f5f9;
340
+ }
341
+
342
+ ::-webkit-scrollbar-thumb {
343
+ background: #cbd5e1;
344
+ border-radius: 4px;
345
+ }
346
+
347
+ .dark-mode ::-webkit-scrollbar-track {
348
+ background: #1e293b;
349
+ }
350
+
351
+ .dark-mode ::-webkit-scrollbar-thumb {
352
+ background: #475569;
353
+ }
354
+
355
+ /* Tooltips */
356
+ .tooltip {
357
+ position: relative;
358
+ }
359
+
360
+ .tooltip .tooltip-text {
361
+ visibility: hidden;
362
+ width: 120px;
363
+ background-color: #1e293b;
364
+ color: #fff;
365
+ text-align: center;
366
+ border-radius: 6px;
367
+ padding: 5px;
368
+ position: absolute;
369
+ z-index: 1;
370
+ bottom: 125%;
371
+ left: 50%;
372
+ margin-left: -60px;
373
+ opacity: 0;
374
+ transition: opacity 0.3s;
375
+ }
376
+
377
+ .tooltip .tooltip-text::after {
378
+ content: "";
379
+ position: absolute;
380
+ top: 100%;
381
+ left: 50%;
382
+ margin-left: -5px;
383
+ border-width: 5px;
384
+ border-style: solid;
385
+ border-color: #1e293b transparent transparent transparent;
386
+ }
387
+
388
+ .tooltip:hover .tooltip-text {
389
+ visibility: visible;
390
+ opacity: 1;
391
+ }
392
+
393
+ /* Code Block Styling */
394
+ .code-block {
395
+ background-color: #f8fafc;
396
+ border-radius: 0.5rem;
397
+ padding: 1rem;
398
+ font-family: 'Fira Code', monospace;
399
+ font-size: 0.875rem;
400
+ overflow-x: auto;
401
+ }
402
+
403
+ .dark-mode .code-block {
404
+ background-color: #1e293b;
405
+ border: 1px solid #334155;
406
+ }
407
+
408
+ /* Toast Notifications */
409
+ .toast {
410
+ position: fixed;
411
+ bottom: 20px;
412
+ right: 20px;
413
+ padding: 1rem;
414
+ border-radius: 0.5rem;
415
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
416
+ z-index: 100;
417
+ display: flex;
418
+ align-items: center;
419
+ transform: translateX(150%);
420
+ transition: transform 0.3s ease;
421
+ }
422
+
423
+ .toast.show {
424
+ transform: translateX(0);
425
+ }
426
+
427
+ .toast.success {
428
+ background-color: #16a34a;
429
+ color: white;
430
+ }
431
+
432
+ .toast.error {
433
+ background-color: #dc2626;
434
+ color: white;
435
+ }
436
+
437
+ .toast.warning {
438
+ background-color: #d97706;
439
+ color: white;
440
+ }
441
+
442
+ .toast.info {
443
+ background-color: #2563eb;
444
+ color: white;
445
+ }
446
+
447
+ /* Responsive Grid */
448
+ .plugin-grid {
449
+ display: grid;
450
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
451
+ gap: 1.5rem;
452
+ }
453
+
454
+ /* Loading Spinner */
455
+ .spinner {
456
+ animation: spin-slow 2s linear infinite;
457
+ }
458
+
459
+ /* Error Boundary */
460
+ .error-boundary {
461
+ border: 1px solid var(--hermit-danger);
462
+ border-radius: 0.5rem;
463
+ padding: 1rem;
464
+ background-color: rgba(220, 38, 38, 0.1);
465
+ }
466
+
467
+ .dark-mode .error-boundary {
468
+ background-color: rgba(220, 38, 38, 0.2);
469
+ }
470
+
471
+ /* Empty State */
472
+ .empty-state {
473
+ display: flex;
474
+ flex-direction: column;
475
+ align-items: center;
476
+ justify-content: center;
477
+ padding: 2rem;
478
+ text-align: center;
479
+ }
480
+
481
+ /* Context Menu */
482
+ .context-menu {
483
+ position: absolute;
484
+ z-index: 100;
485
+ background-color: white;
486
+ border-radius: 0.5rem;
487
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
488
+ padding: 0.5rem 0;
489
+ min-width: 200px;
490
+ display: none;
491
+ }
492
+
493
+ .dark-mode .context-menu {
494
+ background-color: #1e293b;
495
+ border: 1px solid #334155;
496
+ }
497
+
498
+ .context-menu-item {
499
+ padding: 0.5rem 1rem;
500
+ cursor: pointer;
501
+ transition: all 0.2s ease;
502
+ }
503
+
504
+ .context-menu-item:hover {
505
+ background-color: rgba(37, 99, 235, 0.1);
506
+ }
507
+
508
+ .dark-mode .context-menu-item:hover {
509
+ background-color: rgba(37, 99, 235, 0.2);
510
+ }
511
+
512
+ /* Tour Highlight */
513
+ .tour-highlight {
514
+ position: relative;
515
+ z-index: 999;
516
+ box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.5);
517
+ border-radius: 0.5rem;
518
+ animation: pulse-slow 2s infinite;
519
+ }
520
+
521
+ /* Plugin Health Indicator */
522
+ .health-indicator {
523
+ width: 10px;
524
+ height: 10px;
525
+ border-radius: 50%;
526
+ display: inline-block;
527
+ margin-right: 0.5rem;
528
+ }
529
+
530
+ .health-excellent {
531
+ background-color: #16a34a;
532
+ box-shadow: 0 0 5px #16a34a;
533
+ }
534
+
535
+ .health-good {
536
+ background-color: #65a30d;
537
+ box-shadow: 0 0 5px #65a30d;
538
+ }
539
+
540
+ .health-fair {
541
+ background-color: #d97706;
542
+ box-shadow: 0 0 5px #d97706;
543
+ }
544
+
545
+ .health-poor {
546
+ background-color: #dc2626;
547
+ box-shadow: 0 0 5px #dc2626;
548
+ }
549
+
550
+ /* Version Badge */
551
+ .version-badge {
552
+ font-size: 0.75rem;
553
+ padding: 0.25rem 0.5rem;
554
+ border-radius: 9999px;
555
+ background-color: rgba(37, 99, 235, 0.1);
556
+ color: var(--hermit-accent);
557
+ }
558
+
559
+ .dark-mode .version-badge {
560
+ background-color: rgba(37, 99, 235, 0.2);
561
+ }
562
+
563
+ /* Dependency Tree */
564
+ .dependency-tree {
565
+ border-left: 2px solid #e2e8f0;
566
+ padding-left: 1rem;
567
+ margin-left: 1rem;
568
+ }
569
+
570
+ .dark-mode .dependency-tree {
571
+ border-left-color: #334155;
572
+ }
573
+
574
+ .dependency-item {
575
+ position: relative;
576
+ padding-left: 1.5rem;
577
+ margin-bottom: 0.5rem;
578
+ }
579
+
580
+ .dependency-item::before {
581
+ content: '';
582
+ position: absolute;
583
+ left: 0;
584
+ top: 50%;
585
+ width: 1rem;
586
+ height: 2px;
587
+ background-color: #e2e8f0;
588
+ }
589
+
590
+ .dark-mode .dependency-item::before {
591
+ background-color: #334155;
592
+ }
593
+
594
+ /* Plugin Comparison */
595
+ .comparison-table {
596
+ width: 100%;
597
+ border-collapse: collapse;
598
+ }
599
+
600
+ .comparison-table th, .comparison-table td {
601
+ padding: 0.75rem;
602
+ text-align: left;
603
+ border-bottom: 1px solid #e2e8f0;
604
+ }
605
+
606
+ .dark-mode .comparison-table th, .dark-mode .comparison-table td {
607
+ border-bottom-color: #334155;
608
+ }
609
+
610
+ .comparison-table tr:last-child td {
611
+ border-bottom: none;
612
+ }
613
+
614
+ /* Plugin Stats */
615
+ .stats-card {
616
+ background-color: white;
617
+ border-radius: 0.5rem;
618
+ padding: 1rem;
619
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
620
+ }
621
+
622
+ .dark-mode .stats-card {
623
+ background-color: #1e293b;
624
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
625
+ }
626
+
627
+ /* Responsive Adjustments */
628
+ @media (max-width: 768px) {
629
+ .plugin-grid {
630
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
631
+ }
632
+
633
+ .sidebar {
634
+ transform: translateX(-100%);
635
+ position: fixed;
636
+ top: 0;
637
+ left: 0;
638
+ height: 100vh;
639
+ z-index: 40;
640
+ background-color: white;
641
+ }
642
+
643
+ .dark-mode .sidebar {
644
+ background-color: #1e293b;
645
+ }
646
+
647
+ .sidebar.open {
648
+ transform: translateX(0);
649
+ }
650
+
651
+ .mobile-menu-button {
652
+ display: block;
653
+ }
654
+ }
655
+ </style>
656
+ </head>
657
+ <body class="bg-gray-50 dark:bg-gray-900 transition-colors duration-300">
658
+ <!-- Toast Notification Container -->
659
+ <div id="toast-container"></div>
660
+
661
+ <!-- Mobile Menu Button (hidden on desktop) -->
662
+ <button id="mobile-menu-button" class="md:hidden fixed top-4 left-4 z-50 p-2 rounded-full bg-white dark:bg-gray-800 shadow-lg">
663
+ <i class="fas fa-bars text-gray-800 dark:text-gray-200"></i>
664
+ </button>
665
+
666
+ <!-- Main Container -->
667
+ <div class="flex min-h-screen">
668
+ <!-- Sidebar Navigation -->
669
+ <aside id="sidebar" class="sidebar w-64 bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 p-4 hidden md:block">
670
+ <div class="flex items-center justify-between mb-8">
671
+ <div class="flex items-center space-x-2">
672
+ <div class="w-8 h-8 rounded-full bg-hermit-blue flex items-center justify-center">
673
+ <i class="fas fa-code text-white"></i>
674
+ </div>
675
+ <span class="text-xl font-bold text-gray-800 dark:text-gray-200">Hermit Pro</span>
676
+ </div>
677
+ <button id="dark-mode-toggle" class="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700">
678
+ <i class="fas fa-moon text-gray-600 dark:text-yellow-300"></i>
679
+ </button>
680
+ </div>
681
+
682
+ <div class="mb-6">
683
+ <div class="relative">
684
+ <input type="text" placeholder="Search plugins..." class="search-input w-full pl-10 pr-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-2 focus:ring-hermit-blue focus:border-transparent bg-white dark:bg-gray-700 text-gray-800 dark:text-gray-200">
685
+ <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
686
+ </div>
687
+ </div>
688
+
689
+ <nav>
690
+ <ul class="space-y-1">
691
+ <li>
692
+ <a href="#" class="sidebar-item active flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-800 dark:text-gray-200">
693
+ <i class="fas fa-box-open mr-3 text-gray-500 dark:text-gray-400"></i>
694
+ Plugin Library
695
+ </a>
696
+ </li>
697
+ <li>
698
+ <a href="#" class="sidebar-item flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-200">
699
+ <i class="fas fa-cube mr-3 text-gray-500 dark:text-gray-400"></i>
700
+ My Plugins
701
+ </a>
702
+ </li>
703
+ <li>
704
+ <a href="#" class="sidebar-item flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-200">
705
+ <i class="fas fa-cloud-download-alt mr-3 text-gray-500 dark:text-gray-400"></i>
706
+ Updates
707
+ <span class="ml-auto px-2 py-0.5 rounded-full text-xs font-medium bg-hermit-blue text-white">3</span>
708
+ </a>
709
+ </li>
710
+ <li>
711
+ <a href="#" class="sidebar-item flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-200">
712
+ <i class="fas fa-star mr-3 text-gray-500 dark:text-gray-400"></i>
713
+ Favorites
714
+ </a>
715
+ </li>
716
+ <li>
717
+ <a href="#" class="sidebar-item flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-200">
718
+ <i class="fas fa-chart-line mr-3 text-gray-500 dark:text-gray-400"></i>
719
+ Analytics
720
+ </a>
721
+ </li>
722
+ <li>
723
+ <a href="#" class="sidebar-item flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-200">
724
+ <i class="fas fa-cog mr-3 text-gray-500 dark:text-gray-400"></i>
725
+ Settings
726
+ </a>
727
+ </li>
728
+ </ul>
729
+ </nav>
730
+
731
+ <div class="mt-8 pt-4 border-t border-gray-200 dark:border-gray-700">
732
+ <h3 class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-2">Categories</h3>
733
+ <ul class="space-y-1">
734
+ <li>
735
+ <a href="#" class="flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-200">
736
+ <span class="w-2 h-2 mr-3 rounded-full bg-hermit-blue"></span>
737
+ All Plugins
738
+ </a>
739
+ </li>
740
+ <li>
741
+ <a href="#" class="flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-200">
742
+ <span class="w-2 h-2 mr-3 rounded-full bg-hermit-purple"></span>
743
+ UI Components
744
+ </a>
745
+ </li>
746
+ <li>
747
+ <a href="#" class="flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-200">
748
+ <span class="w-2 h-2 mr-3 rounded-full bg-hermit-pink"></span>
749
+ Utilities
750
+ </a>
751
+ </li>
752
+ <li>
753
+ <a href="#" class="flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-200">
754
+ <span class="w-2 h-2 mr-3 rounded-full bg-hermit-teal"></span>
755
+ Integrations
756
+ </a>
757
+ </li>
758
+ <li>
759
+ <a href="#" class="flex items-center px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-200">
760
+ <span class="w-2 h-2 mr-3 rounded-full bg-hermit-orange"></span>
761
+ Developer Tools
762
+ </a>
763
+ </li>
764
+ </ul>
765
+ </div>
766
+ </aside>
767
+
768
+ <!-- Main Content -->
769
+ <main class="flex-1 p-6">
770
+ <!-- Header -->
771
+ <header class="mb-8">
772
+ <div class="flex justify-between items-center mb-6">
773
+ <h1 class="text-2xl font-bold text-gray-800 dark:text-gray-200">Plugin Library</h1>
774
+ <div class="flex space-x-4">
775
+ <button id="new-plugin-btn" class="px-4 py-2 bg-hermit-blue text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center">
776
+ <i class="fas fa-plus mr-2"></i> New Plugin
777
+ </button>
778
+ <div class="dropdown relative">
779
+ <button class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors flex items-center">
780
+ <i class="fas fa-sliders-h mr-2"></i> Filters
781
+ </button>
782
+ <div class="dropdown-content mt-2 p-2">
783
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 rounded">Most Popular</a>
784
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 rounded">Recently Added</a>
785
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 rounded">Highest Rated</a>
786
+ <a href="#" class="block px-4 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 rounded">Verified Only</a>
787
+ </div>
788
+ </div>
789
+ </div>
790
+ </div>
791
+
792
+ <div class="flex border-b border-gray-200 dark:border-gray-700">
793
+ <button class="tab-active px-4 py-2 text-sm font-medium">All</button>
794
+ <button class="px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200">Installed</button>
795
+ <button class="px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200">Updates</button>
796
+ <button class="px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200">Beta</button>
797
+ </div>
798
+ </header>
799
+
800
+ <!-- Stats Overview -->
801
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8">
802
+ <div class="stats-card">
803
+ <div class="flex items-center">
804
+ <div class="p-3 rounded-full bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-300 mr-4">
805
+ <i class="fas fa-box-open"></i>
806
+ </div>
807
+ <div>
808
+ <p class="text-sm text-gray-500 dark:text-gray-400">Total Plugins</p>
809
+ <p class="text-2xl font-bold text-gray-800 dark:text-gray-200">1,248</p>
810
+ </div>
811
+ </div>
812
+ </div>
813
+ <div class="stats-card">
814
+ <div class="flex items-center">
815
+ <div class="p-3 rounded-full bg-green-100 dark:bg-green-900 text-green-600 dark:text-green-300 mr-4">
816
+ <i class="fas fa-download"></i>
817
+ </div>
818
+ <div>
819
+ <p class="text-sm text-gray-500 dark:text-gray-400">Installed</p>
820
+ <p class="text-2xl font-bold text-gray-800 dark:text-gray-200">24</p>
821
+ </div>
822
+ </div>
823
+ </div>
824
+ <div class="stats-card">
825
+ <div class="flex items-center">
826
+ <div class="p-3 rounded-full bg-purple-100 dark:bg-purple-900 text-purple-600 dark:text-purple-300 mr-4">
827
+ <i class="fas fa-sync-alt"></i>
828
+ </div>
829
+ <div>
830
+ <p class="text-sm text-gray-500 dark:text-gray-400">Updates</p>
831
+ <p class="text-2xl font-bold text-gray-800 dark:text-gray-200">3</p>
832
+ </div>
833
+ </div>
834
+ </div>
835
+ <div class="stats-card">
836
+ <div class="flex items-center">
837
+ <div class="p-3 rounded-full bg-yellow-100 dark:bg-yellow-900 text-yellow-600 dark:text-yellow-300 mr-4">
838
+ <i class="fas fa-star"></i>
839
+ </div>
840
+ <div>
841
+ <p class="text-sm text-gray-500 dark:text-gray-400">Favorites</p>
842
+ <p class="text-2xl font-bold text-gray-800 dark:text-gray-200">8</p>
843
+ </div>
844
+ </div>
845
+ </div>
846
+ </div>
847
+
848
+ <!-- Plugin Grid -->
849
+ <div class="plugin-grid" id="plugin-container">
850
+ <!-- Plugin cards will be dynamically loaded here -->
851
+ </div>
852
+
853
+ <!-- Loading State -->
854
+ <div id="loading-state" class="flex flex-col items-center justify-center py-12">
855
+ <div class="spinner w-12 h-12 border-4 border-hermit-blue border-t-transparent rounded-full mb-4"></div>
856
+ <p class="text-gray-600 dark:text-gray-400">Loading plugins...</p>
857
+ </div>
858
+
859
+ <!-- Empty State -->
860
+ <div id="empty-state" class="empty-state hidden">
861
+ <div class="w-24 h-24 bg-gray-100 dark:bg-gray-700 rounded-full flex items-center justify-center mb-4">
862
+ <i class="fas fa-box-open text-3xl text-gray-400"></i>
863
+ </div>
864
+ <h3 class="text-xl font-medium text-gray-800 dark:text-gray-200 mb-2">No plugins found</h3>
865
+ <p class="text-gray-600 dark:text-gray-400 mb-6">Try adjusting your search or filters</p>
866
+ <button class="px-4 py-2 bg-hermit-blue text-white rounded-lg hover:bg-blue-700 transition-colors">
867
+ Reset Filters
868
+ </button>
869
+ </div>
870
+
871
+ <!-- Pagination -->
872
+ <div class="flex justify-between items-center mt-8">
873
+ <button class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50" disabled>
874
+ Previous
875
+ </button>
876
+ <div class="flex space-x-1">
877
+ <button class="w-10 h-10 rounded-lg bg-hermit-blue text-white">1</button>
878
+ <button class="w-10 h-10 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors">2</button>
879
+ <button class="w-10 h-10 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors">3</button>
880
+ <span class="flex items-center px-2">...</span>
881
+ <button class="w-10 h-10 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors">8</button>
882
+ </div>
883
+ <button class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
884
+ Next
885
+ </button>
886
+ </div>
887
+ </main>
888
+ </div>
889
+
890
+ <!-- Plugin Details Modal -->
891
+ <div id="plugin-modal" class="fixed inset-0 z-50 hidden">
892
+ <div class="modal-overlay absolute inset-0"></div>
893
+ <div class="flex items-center justify-center min-h-screen">
894
+ <div class="modal-content bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-4xl mx-4">
895
+ <!-- Modal content will be dynamically loaded here -->
896
+ </div>
897
+ </div>
898
+ </div>
899
+
900
+ <!-- New Plugin Modal -->
901
+ <div id="new-plugin-modal" class="fixed inset-0 z-50 hidden">
902
+ <div class="modal-overlay absolute inset-0"></div>
903
+ <div class="flex items-center justify-center min-h-screen">
904
+ <div class="modal-content bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-2xl mx-4">
905
+ <div class="p-6">
906
+ <div class="flex justify-between items-center mb-4">
907
+ <h3 class="text-xl font-bold text-gray-800 dark:text-gray-200">Create New Plugin</h3>
908
+ <button id="close-new-plugin-modal" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
909
+ <i class="fas fa-times"></i>
910
+ </button>
911
+ </div>
912
+
913
+ <div class="space-y-4">
914
+ <div>
915
+ <label for="plugin-name" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Plugin Name</label>
916
+ <input type="text" id="plugin-name" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-hermit-blue focus:border-transparent bg-white dark:bg-gray-700 text-gray-800 dark:text-gray-200">
917
+ </div>
918
+
919
+ <div>
920
+ <label for="plugin-description" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Description</label>
921
+ <textarea id="plugin-description" rows="3" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-hermit-blue focus:border-transparent bg-white dark:bg-gray-700 text-gray-800 dark:text-gray-200"></textarea>
922
+ </div>
923
+
924
+ <div>
925
+ <label for="plugin-category" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Category</label>
926
+ <select id="plugin-category" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-hermit-blue focus:border-transparent bg-white dark:bg-gray-700 text-gray-800 dark:text-gray-200">
927
+ <option value="ui">UI Components</option>
928
+ <option value="utility">Utilities</option>
929
+ <option value="integration">Integrations</option>
930
+ <option value="dev">Developer Tools</option>
931
+ </select>
932
+ </div>
933
+
934
+ <div>
935
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Visibility</label>
936
+ <div class="flex space-x-4">
937
+ <label class="inline-flex items-center">
938
+ <input type="radio" name="visibility" value="public" checked class="h-4 w-4 text-hermit-blue focus:ring-hermit-blue border-gray-300 dark:border-gray-600">
939
+ <span class="ml-2 text-gray-700 dark:text-gray-300">Public</span>
940
+ </label>
941
+ <label class="inline-flex items-center">
942
+ <input type="radio" name="visibility" value="private" class="h-4 w-4 text-hermit-blue focus:ring-hermit-blue border-gray-300 dark:border-gray-600">
943
+ <span class="ml-2 text-gray-700 dark:text-gray-300">Private</span>
944
+ </label>
945
+ </div>
946
+ </div>
947
+
948
+ <div class="pt-4 border-t border-gray-200 dark:border-gray-700">
949
+ <div class="flex justify-end space-x-3">
950
+ <button id="cancel-new-plugin" class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
951
+ Cancel
952
+ </button>
953
+ <button id="create-plugin" class="px-4 py-2 bg-hermit-blue text-white rounded-lg hover:bg-blue-700 transition-colors">
954
+ Create Plugin
955
+ </button>
956
+ </div>
957
+ </div>
958
+ </div>
959
+ </div>
960
+ </div>
961
+ </div>
962
+ </div>
963
+
964
+ <!-- Error Boundary (hidden by default) -->
965
+ <div id="error-boundary" class="error-boundary fixed bottom-4 left-4 max-w-md p-4 hidden">
966
+ <div class="flex items-start">
967
+ <div class="flex-shrink-0">
968
+ <i class="fas fa-exclamation-triangle text-hermit-danger"></i>
969
+ </div>
970
+ <div class="ml-3">
971
+ <h3 class="text-sm font-medium text-gray-800 dark:text-gray-200">Something went wrong</h3>
972
+ <div class="mt-2 text-sm text-gray-700 dark:text-gray-300">
973
+ <p id="error-message">Failed to load plugins. Please try again later.</p>
974
+ </div>
975
+ <div class="mt-4">
976
+ <button id="retry-button" class="text-sm font-medium text-hermit-blue hover:text-blue-700 dark:hover:text-blue-500">
977
+ Retry
978
+ </button>
979
+ </div>
980
+ </div>
981
+ </div>
982
+ </div>
983
+
984
+ <script>
985
+ // Global state
986
+ const state = {
987
+ darkMode: localStorage.getItem('darkMode') === 'true',
988
+ plugins: [],
989
+ filteredPlugins: [],
990
+ currentPage: 1,
991
+ pluginsPerPage: 12,
992
+ selectedPlugin: null,
993
+ isLoading: true,
994
+ error: null
995
+ };
996
+
997
+ // DOM Elements
998
+ const elements = {
999
+ body: document.body,
1000
+ darkModeToggle: document.getElementById('dark-mode-toggle'),
1001
+ mobileMenuButton: document.getElementById('mobile-menu-button'),
1002
+ sidebar: document.getElementById('sidebar'),
1003
+ pluginContainer: document.getElementById('plugin-container'),
1004
+ loadingState: document.getElementById('loading-state'),
1005
+ emptyState: document.getElementById('empty-state'),
1006
+ pluginModal: document.getElementById('plugin-modal'),
1007
+ newPluginBtn: document.getElementById('new-plugin-btn'),
1008
+ newPluginModal: document.getElementById('new-plugin-modal'),
1009
+ closeNewPluginModal: document.getElementById('close-new-plugin-modal'),
1010
+ cancelNewPlugin: document.getElementById('cancel-new-plugin'),
1011
+ createPlugin: document.getElementById('create-plugin'),
1012
+ errorBoundary: document.getElementById('error-boundary'),
1013
+ errorMessage: document.getElementById('error-message'),
1014
+ retryButton: document.getElementById('retry-button'),
1015
+ toastContainer: document.getElementById('toast-container')
1016
+ };
1017
+
1018
+ // Initialize the app
1019
+ function init() {
1020
+ setupEventListeners();
1021
+ applyDarkMode();
1022
+ fetchPlugins();
1023
+ }
1024
+
1025
+ // Set up event listeners
1026
+ function setupEventListeners() {
1027
+ // Dark mode toggle
1028
+ elements.darkModeToggle.addEventListener('click', toggleDarkMode);
1029
+
1030
+ // Mobile menu toggle
1031
+ elements.mobileMenuButton.addEventListener('click', toggleMobileMenu);
1032
+
1033
+ // New plugin modal
1034
+ elements.newPluginBtn.addEventListener('click', () => {
1035
+ elements.newPluginModal.classList.remove('hidden');
1036
+ });
1037
+
1038
+ elements.closeNewPluginModal.addEventListener('click', () => {
1039
+ elements.newPluginModal.classList.add('hidden');
1040
+ });
1041
+
1042
+ elements.cancelNewPlugin.addEventListener('click', () => {
1043
+ elements.newPluginModal.classList.add('hidden');
1044
+ });
1045
+
1046
+ // Create plugin
1047
+ elements.createPlugin.addEventListener('click', createNewPlugin);
1048
+
1049
+ // Error retry
1050
+ elements.retryButton.addEventListener('click', fetchPlugins);
1051
+
1052
+ // Close modals when clicking outside
1053
+ document.addEventListener('click', (e) => {
1054
+ if (e.target === elements.pluginModal) {
1055
+ elements.pluginModal.classList.add('hidden');
1056
+ }
1057
+ if (e.target === elements.newPluginModal) {
1058
+ elements.newPluginModal.classList.add('hidden');
1059
+ }
1060
+ });
1061
+ }
1062
+
1063
+ // Toggle dark mode
1064
+ function toggleDarkMode() {
1065
+ state.darkMode = !state.darkMode;
1066
+ localStorage.setItem('darkMode', state.darkMode);
1067
+ applyDarkMode();
1068
+ }
1069
+
1070
+ // Apply dark mode styles
1071
+ function applyDarkMode() {
1072
+ if (state.darkMode) {
1073
+ elements.body.classList.add('dark-mode');
1074
+ elements.darkModeToggle.innerHTML = '<i class="fas fa-sun text-yellow-300"></i>';
1075
+ } else {
1076
+ elements.body.classList.remove('dark-mode');
1077
+ elements.darkModeToggle.innerHTML = '<i class="fas fa-moon text-gray-600"></i>';
1078
+ }
1079
+ }
1080
+
1081
+ // Toggle mobile menu
1082
+ function toggleMobileMenu() {
1083
+ elements.sidebar.classList.toggle('open');
1084
+ }
1085
+
1086
+ // Fetch plugins from API
1087
+ function fetchPlugins() {
1088
+ state.isLoading = true;
1089
+ state.error = null;
1090
+
1091
+ // Show loading state
1092
+ elements.loadingState.classList.remove('hidden');
1093
+ elements.emptyState.classList.add('hidden');
1094
+ elements.errorBoundary.classList.add('hidden');
1095
+
1096
+ // Simulate API call with timeout
1097
+ setTimeout(() => {
1098
+ try {
1099
+ // In a real app, this would be an actual API call
1100
+ // axios.get('/api/plugins')
1101
+ // .then(response => {
1102
+ // state.plugins = response.data;
1103
+ // renderPlugins();
1104
+ // })
1105
+ // .catch(error => {
1106
+ // handleError(error);
1107
+ // });
1108
+
1109
+ // Mock data for demonstration
1110
+ state.plugins = generateMockPlugins();
1111
+ renderPlugins();
1112
+ } catch (error) {
1113
+ handleError(error);
1114
+ }
1115
+ }, 1000);
1116
+ }
1117
+
1118
+ // Render plugins to the DOM
1119
+ function renderPlugins() {
1120
+ state.isLoading = false;
1121
+ elements.loadingState.classList.add('hidden');
1122
+
1123
+ if (state.plugins.length === 0) {
1124
+ elements.emptyState.classList.remove('hidden');
1125
+ return;
1126
+ }
1127
+
1128
+ elements.pluginContainer.innerHTML = '';
1129
+
1130
+ // Calculate pagination
1131
+ const startIndex = (state.currentPage - 1) * state.pluginsPerPage;
1132
+ const endIndex = startIndex + state.pluginsPerPage;
1133
+ const paginatedPlugins = state.plugins.slice(startIndex, endIndex);
1134
+
1135
+ paginatedPlugins.forEach(plugin => {
1136
+ const pluginCard = createPluginCard(plugin);
1137
+ elements.pluginContainer.appendChild(pluginCard);
1138
+ });
1139
+ }
1140
+
1141
+ // Create a plugin card element
1142
+ function createPluginCard(plugin) {
1143
+ const card = document.createElement('div');
1144
+ card.className = 'plugin-card bg-white dark:bg-gray-800 rounded-lg p-5 hover:shadow-lg transition-all duration-300';
1145
+ card.dataset.id = plugin.id;
1146
+
1147
+ // Add click event to open modal
1148
+ card.addEventListener('click', () => {
1149
+ openPluginModal(plugin);
1150
+ });
1151
+
1152
+ // Badge for featured plugins
1153
+ const badge = plugin.featured ?
1154
+ `<div class="plugin-badge bg-hermit-pink text-white">
1155
+ <i class="fas fa-star"></i>
1156
+ </div>` : '';
1157
+
1158
+ // Rating stars
1159
+ const stars = Array(5).fill('')
1160
+ .map((_, i) =>
1161
+ i < Math.floor(plugin.rating) ?
1162
+ `<i class="fas fa-star"></i>` :
1163
+ (i < plugin.rating ? `<i class="fas fa-star-half-alt"></i>` : `<i class="far fa-star empty"></i>`)
1164
+ ).join('');
1165
+
1166
+ // Tags
1167
+ const tags = plugin.tags.map(tag =>
1168
+ `<span class="tag inline-block bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200 mr-2 mb-2 px-2 py-1 rounded-full text-xs">
1169
+ ${tag}
1170
+ </span>`
1171
+ ).join('');
1172
+
1173
+ card.innerHTML = `
1174
+ ${badge}
1175
+ <div class="flex items-start mb-4">
1176
+ <div class="plugin-icon mr-4">
1177
+ <i class="${plugin.icon} text-hermit-blue text-xl"></i>
1178
+ </div>
1179
+ <div class="flex-1">
1180
+ <div class="flex justify-between items-start">
1181
+ <h3 class="font-bold text-lg text-gray-800 dark:text-gray-200">${plugin.name}</h3>
1182
+ <span class="version-badge">v${plugin.version}</span>
1183
+ </div>
1184
+ <p class="text-sm text-gray-600 dark:text-gray-400 mt-1">${plugin.author}</p>
1185
+ </div>
1186
+ </div>
1187
+ <p class="text-gray-700 dark:text-gray-300 text-sm mb-4">${plugin.description}</p>
1188
+ <div class="flex items-center justify-between mb-4">
1189
+ <div class="star-rating text-sm">
1190
+ ${stars}
1191
+ <span class="ml-1 text-gray-600 dark:text-gray-400">(${plugin.rating.toFixed(1)})</span>
1192
+ </div>
1193
+ <span class="text-xs text-gray-500 dark:text-gray-400">${plugin.downloads.toLocaleString()} installs</span>
1194
+ </div>
1195
+ <div class="mb-4">
1196
+ ${tags}
1197
+ </div>
1198
+ <button class="install-btn w-full py-2 bg-hermit-blue text-white rounded-lg hover:bg-blue-700 transition-colors">
1199
+ ${plugin.installed ? 'Update' : 'Install'}
1200
+ </button>
1201
+ `;
1202
+
1203
+ return card;
1204
+ }
1205
+
1206
+ // Open plugin modal
1207
+ function openPluginModal(plugin) {
1208
+ state.selectedPlugin = plugin;
1209
+
1210
+ // In a real app, we might fetch more detailed plugin info here
1211
+ const modalContent = `
1212
+ <div class="p-6">
1213
+ <div class="flex justify-between items-start mb-6">
1214
+ <div class="flex items-start">
1215
+ <div class="plugin-icon mr-4">
1216
+ <i class="${plugin.icon} text-hermit-blue text-2xl"></i>
1217
+ </div>
1218
+ <div>
1219
+ <h3 class="text-xl font-bold text-gray-800 dark:text-gray-200">${plugin.name}</h3>
1220
+ <p class="text-sm text-gray-600 dark:text-gray-400">by ${plugin.author}</p>
1221
+ </div>
1222
+ </div>
1223
+ <button id="close-plugin-modal" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
1224
+ <i class="fas fa-times"></i>
1225
+ </button>
1226
+ </div>
1227
+
1228
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
1229
+ <div class="md:col-span-2">
1230
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-4 mb-4">
1231
+ <h4 class="font-medium text-gray-800 dark:text-gray-200 mb-2">Description</h4>
1232
+ <p class="text-gray-700 dark:text-gray-300">${plugin.description}</p>
1233
+ </div>
1234
+
1235
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-4 mb-4">
1236
+ <h4 class="font-medium text-gray-800 dark:text-gray-200 mb-2">Features</h4>
1237
+ <ul class="list-disc pl-5 text-gray-700 dark:text-gray-300 space-y-1">
1238
+ ${plugin.features.map(feature => `<li>${feature}</li>`).join('')}
1239
+ </ul>
1240
+ </div>
1241
+
1242
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-4">
1243
+ <h4 class="font-medium text-gray-800 dark:text-gray-200 mb-2">Installation</h4>
1244
+ <div class="code-block mb-2">
1245
+ <code>npm install ${plugin.packageName}</code>
1246
+ </div>
1247
+ <div class="code-block">
1248
+ <code>yarn add ${plugin.packageName}</code>
1249
+ </div>
1250
+ </div>
1251
+ </div>
1252
+
1253
+ <div>
1254
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-4 mb-4">
1255
+ <div class="flex items-center justify-between mb-2">
1256
+ <h4 class="font-medium text-gray-800 dark:text-gray-200">Details</h4>
1257
+ <span class="version-badge">v${plugin.version}</span>
1258
+ </div>
1259
+
1260
+ <div class="space-y-3">
1261
+ <div>
1262
+ <p class="text-xs text-gray-500 dark:text-gray-400 mb-1">Category</p>
1263
+ <p class="text-sm text-gray-700 dark:text-gray-300">${plugin.category}</p>
1264
+ </div>
1265
+
1266
+ <div>
1267
+ <p class="text-xs text-gray-500 dark:text-gray-400 mb-1">Last Updated</p>
1268
+ <p class="text-sm text-gray-700 dark:text-gray-300">${plugin.lastUpdated}</p>
1269
+ </div>
1270
+
1271
+ <div>
1272
+ <p class="text-xs text-gray-500 dark:text-gray-400 mb-1">License</p>
1273
+ <p class="text-sm text-gray-700 dark:text-gray-300">${plugin.license}</p>
1274
+ </div>
1275
+
1276
+ <div>
1277
+ <p class="text-xs text-gray-500 dark:text-gray-400 mb-1">Compatibility</p>
1278
+ <p class="text-sm text-gray-700 dark:text-gray-300">${plugin.compatibility}</p>
1279
+ </div>
1280
+
1281
+ <div>
1282
+ <p class="text-xs text-gray-500 dark:text-gray-400 mb-1">Dependencies</p>
1283
+ <div class="dependency-tree">
1284
+ ${plugin.dependencies.map(dep => `
1285
+ <div class="dependency-item">
1286
+ <span class="text-sm text-gray-700 dark:text-gray-300">${dep}</span>
1287
+ </div>
1288
+ `).join('')}
1289
+ </div>
1290
+ </div>
1291
+ </div>
1292
+ </div>
1293
+
1294
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-4 mb-4">
1295
+ <h4 class="font-medium text-gray-800 dark:text-gray-200 mb-3">Stats</h4>
1296
+
1297
+ <div class="space-y-3">
1298
+ <div>
1299
+ <div class="flex justify-between text-sm mb-1">
1300
+ <span class="text-gray-700 dark:text-gray-300">Downloads</span>
1301
+ <span class="text-gray-600 dark:text-gray-400">${plugin.downloads.toLocaleString()}</span>
1302
+ </div>
1303
+ <div class="progress-bar">
1304
+ <div class="progress-fill" style="width: ${Math.min(100, plugin.downloads / 10000 * 100)}%"></div>
1305
+ </div>
1306
+ </div>
1307
+
1308
+ <div>
1309
+ <div class="flex justify-between text-sm mb-1">
1310
+ <span class="text-gray-700 dark:text-gray-300">Rating</span>
1311
+ <span class="text-gray-600 dark:text-gray-400">${plugin.rating.toFixed(1)}/5</span>
1312
+ </div>
1313
+ <div class="progress-bar">
1314
+ <div class="progress-fill" style="width: ${plugin.rating / 5 * 100}%"></div>
1315
+ </div>
1316
+ </div>
1317
+
1318
+ <div>
1319
+ <div class="flex justify-between text-sm mb-1">
1320
+ <span class="text-gray-700 dark:text-gray-300">Health</span>
1321
+ <span class="flex items-center">
1322
+ <span class="health-indicator health-${plugin.health} mr-1"></span>
1323
+ <span class="text-gray-600 dark:text-gray-400 capitalize">${plugin.health}</span>
1324
+ </span>
1325
+ </div>
1326
+ <div class="progress-bar">
1327
+ <div class="progress-fill" style="width: ${plugin.health === 'excellent' ? 100 : plugin.health === 'good' ? 75 : plugin.health === 'fair' ? 50 : 25}%"></div>
1328
+ </div>
1329
+ </div>
1330
+ </div>
1331
+ </div>
1332
+
1333
+ <button class="w-full py-2 bg-hermit-blue text-white rounded-lg hover:bg-blue-700 transition-colors mb-3">
1334
+ ${plugin.installed ? 'Update Plugin' : 'Install Plugin'}
1335
+ </button>
1336
+
1337
+ <button class="w-full py-2 border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors flex items-center justify-center">
1338
+ <i class="far fa-star mr-2"></i> Add to Favorites
1339
+ </button>
1340
+ </div>
1341
+ </div>
1342
+
1343
+ <div class="border-t border-gray-200 dark:border-gray-700 pt-4">
1344
+ <h4 class="font-medium text-gray-800 dark:text-gray-200 mb-3">Reviews</h4>
1345
+
1346
+ <div class="space-y-4">
1347
+ ${plugin.reviews.slice(0, 3).map(review => `
1348
+ <div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-4">
1349
+ <div class="flex justify-between mb-2">
1350
+ <div class="flex items-center">
1351
+ <div class="star-rating text-sm mr-2">
1352
+ ${Array(5).fill('')
1353
+ .map((_, i) =>
1354
+ i < review.rating ?
1355
+ `<i class="fas fa-star"></i>` :
1356
+ `<i class="far fa-star empty"></i>`
1357
+ ).join('')}
1358
+ </div>
1359
+ <span class="text-sm font-medium text-gray-800 dark:text-gray-200">${review.user}</span>
1360
+ </div>
1361
+ <span class="text-xs text-gray-500 dark:text-gray-400">${review.date}</span>
1362
+ </div>
1363
+ <p class="text-sm text-gray-700 dark:text-gray-300">${review.comment}</p>
1364
+ </div>
1365
+ `).join('')}
1366
+
1367
+ <button class="text-sm text-hermit-blue hover:text-blue-700 dark:hover:text-blue-500">
1368
+ View all ${plugin.reviews.length} reviews
1369
+ </button>
1370
+ </div>
1371
+ </div>
1372
+ </div>
1373
+ `;
1374
+
1375
+ elements.pluginModal.querySelector('.modal-content').innerHTML = modalContent;
1376
+ elements.pluginModal.classList.remove('hidden');
1377
+
1378
+ // Add event listener to close button
1379
+ document.getElementById('close-plugin-modal').addEventListener('click', () => {
1380
+ elements.pluginModal.classList.add('hidden');
1381
+ });
1382
+ }
1383
+
1384
+ // Create new plugin
1385
+ function createNewPlugin() {
1386
+ const name = document.getElementById('plugin-name').value.trim();
1387
+ const description = document.getElementById('plugin-description').value.trim();
1388
+ const category = document.getElementById('plugin-category').value;
1389
+ const visibility = document.querySelector('input[name="visibility"]:checked').value;
1390
+
1391
+ if (!name) {
1392
+ showToast('Plugin name is required', 'error');
1393
+ return;
1394
+ }
1395
+
1396
+ // Simulate API call
1397
+ setTimeout(() => {
1398
+ showToast('Plugin created successfully!', 'success');
1399
+ elements.newPluginModal.classList.add('hidden');
1400
+
1401
+ // Reset form
1402
+ document.getElementById('plugin-name').value = '';
1403
+ document.getElementById('plugin-description').value = '';
1404
+
1405
+ // In a real app, we would add the new plugin to the list
1406
+ // and refresh the view
1407
+ }, 1000);
1408
+ }
1409
+
1410
+ // Handle errors
1411
+ function handleError(error) {
1412
+ state.isLoading = false;
1413
+ state.error = error;
1414
+
1415
+ elements.loadingState.classList.add('hidden');
1416
+ elements.errorBoundary.classList.remove('hidden');
1417
+ elements.errorMessage.textContent = error.message || 'Failed to load plugins. Please try again later.';
1418
+
1419
+ console.error('Error:', error);
1420
+ }
1421
+
1422
+ // Show toast notification
1423
+ function showToast(message, type = 'info') {
1424
+ const toast = document.createElement('div');
1425
+ toast.className = `toast ${type}`;
1426
+ toast.innerHTML = `
1427
+ <i class="fas ${type === 'success' ? 'fa-check-circle' : type === 'error' ? 'fa-exclamation-circle' : type === 'warning' ? 'fa-exclamation-triangle' : 'fa-info-circle'} mr-2"></i>
1428
+ ${message}
1429
+ `;
1430
+
1431
+ elements.toastContainer.appendChild(toast);
1432
+
1433
+ // Show toast
1434
+ setTimeout(() => {
1435
+ toast.classList.add('show');
1436
+ }, 10);
1437
+
1438
+ // Hide after delay
1439
+ setTimeout(() => {
1440
+ toast.classList.remove('show');
1441
+
1442
+ // Remove after animation
1443
+ setTimeout(() => {
1444
+ toast.remove();
1445
+ }, 300);
1446
+ }, 3000);
1447
+ }
1448
+
1449
+ // Generate mock plugins for demonstration
1450
+ function generateMockPlugins() {
1451
+ const categories = ['UI Components', 'Utilities', 'Integrations', 'Developer Tools'];
1452
+ const icons = [
1453
+ 'fas fa-palette',
1454
+ 'fas fa-cube',
1455
+ 'fas fa-plug',
1456
+ 'fas fa-code',
1457
+ 'fas fa-chart-bar',
1458
+ 'fas fa-database',
1459
+ 'fas fa-server',
1460
+ 'fas fa-mobile-alt'
1461
+ ];
1462
+
1463
+ const plugins = [];
1464
+
1465
+ for (let i = 1; i <= 24; i++) {
1466
+ const category = categories[Math.floor(Math.random() * categories.length)];
1467
+ const icon = icons[Math.floor(Math.random() * icons.length)];
1468
+ const rating = (Math.random() * 2 + 3).toFixed(1);
1469
+ const downloads = Math.floor(Math.random() * 100000);
1470
+ const version = `${Math.floor(Math.random() * 5)}.${Math.floor(Math.random() * 10)}.${Math.floor(Math.random() * 10)}`;
1471
+ const featured = Math.random() > 0.7;
1472
+ const installed = Math.random() > 0.8;
1473
+
1474
+ const healthLevels = ['excellent', 'good', 'fair', 'poor'];
1475
+ const health = healthLevels[Math.floor(Math.random() * healthLevels.length)];
1476
+
1477
+ const tags = [];
1478
+ const tagCount = Math.floor(Math.random() * 3) + 1;
1479
+ const possibleTags = ['React', 'Vue', 'Angular', 'JavaScript', 'TypeScript', 'CSS', 'HTML', 'Node.js', 'Frontend', 'Backend'];
1480
+
1481
+ for (let j = 0; j < tagCount; j++) {
1482
+ const randomTag = possibleTags[Math.floor(Math.random() * possibleTags.length)];
1483
+ if (!tags.includes(randomTag)) {
1484
+ tags.push(randomTag);
1485
+ }
1486
+ }
1487
+
1488
+ const features = [];
1489
+ const featureCount = Math.floor(Math.random() * 3) + 2;
1490
+ const possibleFeatures = [
1491
+ 'Easy to integrate',
1492
+ 'Fully customizable',
1493
+ 'Responsive design',
1494
+ 'Lightweight',
1495
+ 'High performance',
1496
+ 'TypeScript support',
1497
+ 'Well documented',
1498
+ 'Accessible',
1499
+ 'SEO friendly'
1500
+ ];
1501
+
1502
+ for (let j = 0; j < featureCount; j++) {
1503
+ const randomFeature = possibleFeatures[Math.floor(Math.random() * possibleFeatures.length)];
1504
+ if (!features.includes(randomFeature)) {
1505
+ features.push(randomFeature);
1506
+ }
1507
+ }
1508
+
1509
+ const dependencies = [];
1510
+ const depCount = Math.floor(Math.random() * 3);
1511
+ const possibleDeps = ['react', 'vue', 'lodash', 'axios', 'moment', 'date-fns', 'tailwindcss'];
1512
+
1513
+ for (let j = 0; j < depCount; j++) {
1514
+ const randomDep = possibleDeps[Math.floor(Math.random() * possibleDeps.length)];
1515
+ if (!dependencies.includes(randomDep)) {
1516
+ dependencies.push(randomDep);
1517
+ }
1518
+ }
1519
+
1520
+ const reviews = [];
1521
+ const reviewCount = Math.floor(Math.random() * 5) + 1;
1522
+ const possibleUsers = ['devUser123', 'codeMaster', 'webWizard', 'jsNinja', 'reactPro'];
1523
+ const possibleComments = [
1524
+ 'Great plugin, saved me hours of work!',
1525
+ 'Easy to use and well documented.',
1526
+ 'Had some issues with compatibility.',
1527
+ 'Works perfectly for my needs.',
1528
+ 'Could use more customization options.',
1529
+ 'The best plugin for this purpose!'
1530
+ ];
1531
+
1532
+ for (let j = 0; j < reviewCount; j++) {
1533
+ reviews.push({
1534
+ user: possibleUsers[Math.floor(Math.random() * possibleUsers.length)],
1535
+ rating: Math.floor(Math.random() * 5) + 1,
1536
+ comment: possibleComments[Math.floor(Math.random() * possibleComments.length)],
1537
+ date: `${Math.floor(Math.random() * 12) + 1} months ago`
1538
+ });
1539
+ }
1540
+
1541
+ plugins.push({
1542
+ id: i,
1543
+ name: `${category.split(' ')[0]} Plugin ${i}`,
1544
+ description: `A powerful ${category.toLowerCase()} plugin that helps you ${['build better interfaces', 'write cleaner code', 'integrate with third-party services', 'optimize your workflow'][categories.indexOf(category)]}.`,
1545
+ author: `Plugin Author ${i}`,
1546
+ version: version,
1547
+ rating: parseFloat(rating),
1548
+ downloads: downloads,
1549
+ category: category,
1550
+ icon: icon,
1551
+ tags: tags,
1552
+ featured: featured,
1553
+ installed: installed,
1554
+ packageName: `hermit-${category.toLowerCase().replace(' ', '-')}-plugin-${i}`,
1555
+ lastUpdated: `${Math.floor(Math.random() * 12) + 1} days ago`,
1556
+ license: ['MIT', 'Apache 2.0', 'GPL 3.0'][Math.floor(Math.random() * 3)],
1557
+ compatibility: ['React 16+', 'Vue 2/3', 'Angular 9+', 'All modern browsers'][Math.floor(Math.random() * 4)],
1558
+ health: health,
1559
+ features: features,
1560
+ dependencies: dependencies,
1561
+ reviews: reviews
1562
+ });
1563
+ }
1564
+
1565
+ return plugins;
1566
+ }
1567
+
1568
+ // Initialize the app when DOM is loaded
1569
+ document.addEventListener('DOMContentLoaded', init);
1570
+ </script>
1571
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Boobs00/plugin-library" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
1572
+ </html>
prompts.txt ADDED
File without changes