JarlJarle commited on
Commit
e8e64be
·
verified ·
1 Parent(s): 51608bd

undefined - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +476 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Stampexpert
3
- emoji: 📚
4
- colorFrom: purple
5
- colorTo: pink
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: stampexpert
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: gray
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,476 @@
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>Expert Stamp Recognizer</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .stamp-card {
11
+ transition: all 0.3s ease;
12
+ transform-style: preserve-3d;
13
+ }
14
+ .stamp-card:hover {
15
+ transform: translateY(-5px) scale(1.02);
16
+ box-shadow: 0 10px 20px rgba(0,0,0,0.2);
17
+ }
18
+ .rarity-common {
19
+ border-left: 4px solid #4ade80;
20
+ }
21
+ .rarity-uncommon {
22
+ border-left: 4px solid #60a5fa;
23
+ }
24
+ .rarity-rare {
25
+ border-left: 4px solid #a78bfa;
26
+ }
27
+ .rarity-ultra-rare {
28
+ border-left: 4px solid #f472b6;
29
+ }
30
+ .rarity-legendary {
31
+ border-left: 4px solid #f59e0b;
32
+ }
33
+ #previewImage {
34
+ max-height: 300px;
35
+ object-fit: contain;
36
+ }
37
+ .loading-spinner {
38
+ animation: spin 1s linear infinite;
39
+ }
40
+ @keyframes spin {
41
+ 0% { transform: rotate(0deg); }
42
+ 100% { transform: rotate(360deg); }
43
+ }
44
+ </style>
45
+ </head>
46
+ <body class="bg-gray-100 min-h-screen">
47
+ <div class="container mx-auto px-4 py-8">
48
+ <!-- Header -->
49
+ <header class="text-center mb-12">
50
+ <h1 class="text-4xl md:text-5xl font-bold text-blue-800 mb-4">Expert Stamp Recognizer</h1>
51
+ <p class="text-lg text-gray-600 max-w-2xl mx-auto">
52
+ Identify and catalog stamps from around the world with our advanced recognition system.
53
+ Discover rarity, origin, and historical significance of your stamp collection.
54
+ </p>
55
+ </header>
56
+
57
+ <!-- Main Content -->
58
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
59
+ <!-- Upload Section -->
60
+ <div class="lg:col-span-1 bg-white rounded-xl shadow-md p-6">
61
+ <h2 class="text-2xl font-semibold text-gray-800 mb-6">Upload Your Stamp</h2>
62
+
63
+ <div class="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center mb-6" id="dropZone">
64
+ <div id="uploadArea">
65
+ <i class="fas fa-stamp text-5xl text-blue-500 mb-4"></i>
66
+ <p class="text-gray-500 mb-4">Drag & drop your stamp image here</p>
67
+ <p class="text-sm text-gray-400 mb-4">or</p>
68
+ <input type="file" id="stampUpload" accept="image/*" class="hidden">
69
+ <label for="stampUpload" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg cursor-pointer transition">
70
+ Browse Files
71
+ </label>
72
+ </div>
73
+
74
+ <div id="previewArea" class="hidden">
75
+ <img id="previewImage" src="" alt="Stamp Preview" class="w-full mb-4">
76
+ <button id="analyzeBtn" class="bg-green-600 hover:bg-green-700 text-white px-6 py-2 rounded-lg transition">
77
+ Analyze Stamp
78
+ </button>
79
+ <button id="cancelBtn" class="ml-2 bg-gray-200 hover:bg-gray-300 text-gray-700 px-6 py-2 rounded-lg transition">
80
+ Cancel
81
+ </button>
82
+ </div>
83
+ </div>
84
+
85
+ <div id="loadingIndicator" class="hidden text-center py-8">
86
+ <i class="fas fa-circle-notch loading-spinner text-4xl text-blue-500 mb-4"></i>
87
+ <p class="text-gray-600">Analyzing your stamp...</p>
88
+ </div>
89
+ </div>
90
+
91
+ <!-- Results Section -->
92
+ <div class="lg:col-span-2">
93
+ <div id="resultsContainer" class="hidden bg-white rounded-xl shadow-md p-6">
94
+ <h2 class="text-2xl font-semibold text-gray-800 mb-6">Stamp Analysis Results</h2>
95
+
96
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
97
+ <div class="bg-gray-50 p-4 rounded-lg">
98
+ <h3 class="font-medium text-gray-700 mb-2">Basic Information</h3>
99
+ <div class="space-y-2">
100
+ <p><span class="font-medium">Country:</span> <span id="country">-</span></p>
101
+ <p><span class="font-medium">Year Issued:</span> <span id="year">-</span></p>
102
+ <p><span class="font-medium">Denomination:</span> <span id="denomination">-</span></p>
103
+ <p><span class="font-medium">Catalog Number:</span> <span id="catalogNumber">-</span></p>
104
+ </div>
105
+ </div>
106
+
107
+ <div class="bg-gray-50 p-4 rounded-lg">
108
+ <h3 class="font-medium text-gray-700 mb-2">Rarity & Value</h3>
109
+ <div class="space-y-2">
110
+ <p><span class="font-medium">Rarity:</span> <span id="rarity" class="px-2 py-1 rounded-full text-xs font-medium">-</span></p>
111
+ <p><span class="font-medium">Condition:</span> <span id="condition">-</span></p>
112
+ <p><span class="font-medium">Estimated Value:</span> <span id="value">-</span></p>
113
+ </div>
114
+ </div>
115
+ </div>
116
+
117
+ <div class="mb-6">
118
+ <h3 class="font-medium text-gray-700 mb-2">Historical Context</h3>
119
+ <p id="description" class="text-gray-600">No description available.</p>
120
+ </div>
121
+
122
+ <div class="flex justify-between items-center">
123
+ <button id="saveBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg transition">
124
+ <i class="fas fa-save mr-2"></i> Save to Collection
125
+ </button>
126
+ <button id="newAnalysisBtn" class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-6 py-2 rounded-lg transition">
127
+ <i class="fas fa-redo mr-2"></i> Analyze Another
128
+ </button>
129
+ </div>
130
+ </div>
131
+
132
+ <!-- Stamp Collection -->
133
+ <div id="collectionContainer" class="mt-8">
134
+ <div class="flex justify-between items-center mb-6">
135
+ <h2 class="text-2xl font-semibold text-gray-800">Your Stamp Collection</h2>
136
+ <div class="flex space-x-2">
137
+ <select id="filterCountry" class="border rounded-lg px-3 py-2 text-sm">
138
+ <option value="">All Countries</option>
139
+ <option value="USA">USA</option>
140
+ <option value="UK">UK</option>
141
+ <option value="France">France</option>
142
+ <option value="Germany">Germany</option>
143
+ <option value="Japan">Japan</option>
144
+ </select>
145
+ <select id="filterRarity" class="border rounded-lg px-3 py-2 text-sm">
146
+ <option value="">All Rarities</option>
147
+ <option value="common">Common</option>
148
+ <option value="uncommon">Uncommon</option>
149
+ <option value="rare">Rare</option>
150
+ <option value="ultra-rare">Ultra Rare</option>
151
+ <option value="legendary">Legendary</option>
152
+ </select>
153
+ </div>
154
+ </div>
155
+
156
+ <div id="emptyCollection" class="text-center py-12 bg-white rounded-xl shadow">
157
+ <i class="fas fa-stamp text-4xl text-gray-300 mb-4"></i>
158
+ <p class="text-gray-500">Your collection is empty. Upload a stamp to get started!</p>
159
+ </div>
160
+
161
+ <div id="stampCollection" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 hidden">
162
+ <!-- Stamp cards will be added here dynamically -->
163
+ </div>
164
+ </div>
165
+ </div>
166
+ </div>
167
+ </div>
168
+
169
+ <script>
170
+ document.addEventListener('DOMContentLoaded', function() {
171
+ // DOM Elements
172
+ const dropZone = document.getElementById('dropZone');
173
+ const uploadArea = document.getElementById('uploadArea');
174
+ const previewArea = document.getElementById('previewArea');
175
+ const stampUpload = document.getElementById('stampUpload');
176
+ const previewImage = document.getElementById('previewImage');
177
+ const analyzeBtn = document.getElementById('analyzeBtn');
178
+ const cancelBtn = document.getElementById('cancelBtn');
179
+ const loadingIndicator = document.getElementById('loadingIndicator');
180
+ const resultsContainer = document.getElementById('resultsContainer');
181
+ const collectionContainer = document.getElementById('collectionContainer');
182
+ const emptyCollection = document.getElementById('emptyCollection');
183
+ const stampCollection = document.getElementById('stampCollection');
184
+ const saveBtn = document.getElementById('saveBtn');
185
+ const newAnalysisBtn = document.getElementById('newAnalysisBtn');
186
+ const filterCountry = document.getElementById('filterCountry');
187
+ const filterRarity = document.getElementById('filterRarity');
188
+
189
+ // Sample database of stamps (in a real app, this would be from an API)
190
+ const stampDatabase = {
191
+ "usa-1": {
192
+ id: "usa-1",
193
+ country: "USA",
194
+ year: "1918",
195
+ denomination: "24¢",
196
+ catalogNumber: "Scott #518",
197
+ rarity: "rare",
198
+ condition: "Very Fine",
199
+ value: "$1,200 - $1,800",
200
+ description: "The famous 'Inverted Jenny' stamp, featuring an upside-down image of a Curtiss JN-4 airplane. Only 100 of these error stamps are known to exist.",
201
+ image: "https://upload.wikimedia.org/wikipedia/commons/thumb/8/87/US_Inverted_Jenny_24c_1918_issue.jpg/320px-US_Inverted_Jenny_24c_1918_issue.jpg"
202
+ },
203
+ "uk-1": {
204
+ id: "uk-1",
205
+ country: "UK",
206
+ year: "1840",
207
+ denomination: "1d",
208
+ catalogNumber: "SG #1",
209
+ rarity: "uncommon",
210
+ condition: "Fine",
211
+ value: "$500 - $800",
212
+ description: "The Penny Black, the world's first adhesive postage stamp used in a public postal system.",
213
+ image: "https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Penny_black.jpg/320px-Penny_black.jpg"
214
+ },
215
+ "france-1": {
216
+ id: "france-1",
217
+ country: "France",
218
+ year: "1849",
219
+ denomination: "1F",
220
+ catalogNumber: "Y&T #1",
221
+ rarity: "common",
222
+ condition: "Good",
223
+ value: "$50 - $100",
224
+ description: "First stamp of France, featuring the profile of Ceres, the Roman goddess of agriculture.",
225
+ image: "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Ceres_1F_1849.jpg/320px-Ceres_1F_1849.jpg"
226
+ },
227
+ "germany-1": {
228
+ id: "germany-1",
229
+ country: "Germany",
230
+ year: "1872",
231
+ denomination: "3gr",
232
+ catalogNumber: "Michel #1",
233
+ rarity: "ultra-rare",
234
+ condition: "Extra Fine",
235
+ value: "$3,000 - $5,000",
236
+ description: "Early German Empire stamp featuring the Reichsadler (Imperial Eagle). Rare in unused condition.",
237
+ image: "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/Deutsches_Reich_1872_3_Groschen.jpg/320px-Deutsches_Reich_1872_3_Groschen.jpg"
238
+ },
239
+ "japan-1": {
240
+ id: "japan-1",
241
+ country: "Japan",
242
+ year: "1871",
243
+ denomination: "500m",
244
+ catalogNumber: "Sakura #1",
245
+ rarity: "legendary",
246
+ condition: "Superb",
247
+ value: "$10,000+",
248
+ description: "The first postage stamp of Japan, featuring a dragon design. Extremely rare in mint condition.",
249
+ image: "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Japan_1871_500_mon_dragon_stamp.jpg/320px-Japan_1871_500_mon_dragon_stamp.jpg"
250
+ }
251
+ };
252
+
253
+ // User's collection
254
+ let userCollection = [];
255
+
256
+ // Drag and drop functionality
257
+ ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
258
+ dropZone.addEventListener(eventName, preventDefaults, false);
259
+ });
260
+
261
+ function preventDefaults(e) {
262
+ e.preventDefault();
263
+ e.stopPropagation();
264
+ }
265
+
266
+ ['dragenter', 'dragover'].forEach(eventName => {
267
+ dropZone.addEventListener(eventName, highlight, false);
268
+ });
269
+
270
+ ['dragleave', 'drop'].forEach(eventName => {
271
+ dropZone.addEventListener(eventName, unhighlight, false);
272
+ });
273
+
274
+ function highlight() {
275
+ dropZone.classList.add('border-blue-500', 'bg-blue-50');
276
+ }
277
+
278
+ function unhighlight() {
279
+ dropZone.classList.remove('border-blue-500', 'bg-blue-50');
280
+ }
281
+
282
+ dropZone.addEventListener('drop', handleDrop, false);
283
+
284
+ function handleDrop(e) {
285
+ const dt = e.dataTransfer;
286
+ const files = dt.files;
287
+ handleFiles(files);
288
+ }
289
+
290
+ // File input change
291
+ stampUpload.addEventListener('change', function() {
292
+ if (this.files.length) {
293
+ handleFiles(this.files);
294
+ }
295
+ });
296
+
297
+ function handleFiles(files) {
298
+ const file = files[0];
299
+ if (file.type.match('image.*')) {
300
+ const reader = new FileReader();
301
+ reader.onload = function(e) {
302
+ previewImage.src = e.target.result;
303
+ uploadArea.classList.add('hidden');
304
+ previewArea.classList.remove('hidden');
305
+ };
306
+ reader.readAsDataURL(file);
307
+ } else {
308
+ alert('Please upload an image file.');
309
+ }
310
+ }
311
+
312
+ // Cancel button
313
+ cancelBtn.addEventListener('click', function() {
314
+ previewImage.src = '';
315
+ uploadArea.classList.remove('hidden');
316
+ previewArea.classList.add('hidden');
317
+ stampUpload.value = '';
318
+ });
319
+
320
+ // Analyze button
321
+ analyzeBtn.addEventListener('click', function() {
322
+ previewArea.classList.add('hidden');
323
+ loadingIndicator.classList.remove('hidden');
324
+
325
+ // Simulate API call with timeout
326
+ setTimeout(function() {
327
+ loadingIndicator.classList.add('hidden');
328
+ showRandomStampResult();
329
+ }, 2000);
330
+ });
331
+
332
+ // Show a random stamp result (simulating recognition)
333
+ function showRandomStampResult() {
334
+ const stampKeys = Object.keys(stampDatabase);
335
+ const randomKey = stampKeys[Math.floor(Math.random() * stampKeys.length)];
336
+ const stamp = stampDatabase[randomKey];
337
+
338
+ document.getElementById('country').textContent = stamp.country;
339
+ document.getElementById('year').textContent = stamp.year;
340
+ document.getElementById('denomination').textContent = stamp.denomination;
341
+ document.getElementById('catalogNumber').textContent = stamp.catalogNumber;
342
+
343
+ const rarityElement = document.getElementById('rarity');
344
+ rarityElement.textContent = stamp.rarity.charAt(0).toUpperCase() + stamp.rarity.slice(1);
345
+ rarityElement.className = 'px-2 py-1 rounded-full text-xs font-medium ' + getRarityClass(stamp.rarity);
346
+
347
+ document.getElementById('condition').textContent = stamp.condition;
348
+ document.getElementById('value').textContent = stamp.value;
349
+ document.getElementById('description').textContent = stamp.description;
350
+
351
+ resultsContainer.classList.remove('hidden');
352
+ }
353
+
354
+ function getRarityClass(rarity) {
355
+ const classes = {
356
+ 'common': 'bg-green-100 text-green-800',
357
+ 'uncommon': 'bg-blue-100 text-blue-800',
358
+ 'rare': 'bg-purple-100 text-purple-800',
359
+ 'ultra-rare': 'bg-pink-100 text-pink-800',
360
+ 'legendary': 'bg-yellow-100 text-yellow-800'
361
+ };
362
+ return classes[rarity] || 'bg-gray-100 text-gray-800';
363
+ }
364
+
365
+ // Save to collection
366
+ saveBtn.addEventListener('click', function() {
367
+ const stampKeys = Object.keys(stampDatabase);
368
+ const randomKey = stampKeys[Math.floor(Math.random() * stampKeys.length)];
369
+ const stamp = JSON.parse(JSON.stringify(stampDatabase[randomKey])); // Deep copy
370
+
371
+ // Add unique ID and timestamp
372
+ stamp.userId = 'user-' + Date.now();
373
+ stamp.addedDate = new Date().toISOString();
374
+
375
+ userCollection.push(stamp);
376
+ updateCollectionDisplay();
377
+ resultsContainer.classList.add('hidden');
378
+ uploadArea.classList.remove('hidden');
379
+ previewArea.classList.add('hidden');
380
+
381
+ // Show success message
382
+ const alert = document.createElement('div');
383
+ alert.className = 'fixed top-4 right-4 bg-green-500 text-white px-4 py-2 rounded-lg shadow-lg flex items-center';
384
+ alert.innerHTML = `
385
+ <i class="fas fa-check-circle mr-2"></i>
386
+ <span>Stamp added to your collection!</span>
387
+ `;
388
+ document.body.appendChild(alert);
389
+ setTimeout(() => {
390
+ alert.remove();
391
+ }, 3000);
392
+ });
393
+
394
+ // New analysis button
395
+ newAnalysisBtn.addEventListener('click', function() {
396
+ resultsContainer.classList.add('hidden');
397
+ uploadArea.classList.remove('hidden');
398
+ previewArea.classList.add('hidden');
399
+ stampUpload.value = '';
400
+ });
401
+
402
+ // Update collection display
403
+ function updateCollectionDisplay() {
404
+ if (userCollection.length === 0) {
405
+ emptyCollection.classList.remove('hidden');
406
+ stampCollection.classList.add('hidden');
407
+ return;
408
+ }
409
+
410
+ emptyCollection.classList.add('hidden');
411
+ stampCollection.classList.remove('hidden');
412
+
413
+ // Filter collection
414
+ const countryFilter = filterCountry.value.toLowerCase();
415
+ const rarityFilter = filterRarity.value.toLowerCase();
416
+
417
+ const filteredCollection = userCollection.filter(stamp => {
418
+ return (countryFilter === '' || stamp.country.toLowerCase().includes(countryFilter)) &&
419
+ (rarityFilter === '' || stamp.rarity === rarityFilter);
420
+ });
421
+
422
+ // Clear current display
423
+ stampCollection.innerHTML = '';
424
+
425
+ // Add filtered stamps
426
+ filteredCollection.forEach(stamp => {
427
+ const stampCard = document.createElement('div');
428
+ stampCard.className = `stamp-card bg-white rounded-lg shadow overflow-hidden ${getRarityBorderClass(stamp.rarity)}`;
429
+ stampCard.innerHTML = `
430
+ <div class="p-4">
431
+ <div class="flex justify-between items-start mb-2">
432
+ <div>
433
+ <h3 class="font-semibold text-lg">${stamp.country} ${stamp.denomination}</h3>
434
+ <p class="text-sm text-gray-500">${stamp.year} • ${stamp.catalogNumber}</p>
435
+ </div>
436
+ <span class="${getRarityClass(stamp.rarity)} px-2 py-1 rounded-full text-xs font-medium">
437
+ ${stamp.rarity.charAt(0).toUpperCase() + stamp.rarity.slice(1)}
438
+ </span>
439
+ </div>
440
+ <img src="${stamp.image}" alt="${stamp.country} stamp" class="w-full h-32 object-contain mb-3">
441
+ <div class="flex justify-between items-center text-sm">
442
+ <span class="font-medium">${stamp.value}</span>
443
+ <span class="text-gray-500">${stamp.condition}</span>
444
+ </div>
445
+ </div>
446
+ <div class="bg-gray-50 px-4 py-2 flex justify-between items-center border-t">
447
+ <span class="text-xs text-gray-500">Added: ${new Date(stamp.addedDate).toLocaleDateString()}</span>
448
+ <button class="text-red-500 hover:text-red-700 text-sm" onclick="removeStamp('${stamp.userId}')">
449
+ <i class="fas fa-trash-alt"></i>
450
+ </button>
451
+ </div>
452
+ `;
453
+ stampCollection.appendChild(stampCard);
454
+ });
455
+ }
456
+
457
+ function getRarityBorderClass(rarity) {
458
+ return `rarity-${rarity.split(' ').join('-')}`;
459
+ }
460
+
461
+ // Filter change handlers
462
+ filterCountry.addEventListener('change', updateCollectionDisplay);
463
+ filterRarity.addEventListener('change', updateCollectionDisplay);
464
+
465
+ // Global function to remove stamp
466
+ window.removeStamp = function(userId) {
467
+ userCollection = userCollection.filter(stamp => stamp.userId !== userId);
468
+ updateCollectionDisplay();
469
+ };
470
+
471
+ // Initialize
472
+ updateCollectionDisplay();
473
+ });
474
+ </script>
475
+ <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=JarlJarle/stampexpert" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
476
+ </html>