File size: 36,346 Bytes
51313c5
 
 
 
 
 
eef490f
51313c5
 
 
 
 
 
 
ec103a7
51313c5
 
 
ec103a7
 
 
 
 
51313c5
ec103a7
51313c5
 
 
 
 
 
 
ec103a7
 
51313c5
ec103a7
51313c5
 
 
 
ec103a7
51313c5
ec103a7
 
 
 
 
 
 
 
 
 
 
 
 
51313c5
ec103a7
 
 
 
 
 
 
 
51313c5
ec103a7
51313c5
 
ec103a7
 
51313c5
 
ec103a7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13fd935
 
 
 
 
 
 
ec103a7
 
51313c5
ec103a7
 
 
 
 
51313c5
 
ec103a7
 
 
51313c5
ec103a7
51313c5
 
ec103a7
51313c5
 
ec103a7
51313c5
 
ec103a7
 
 
 
51313c5
 
ec103a7
 
 
 
 
51313c5
 
13fd935
 
 
 
 
 
 
 
 
 
51313c5
03f831a
13fd935
03f831a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eef490f
 
51313c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b131270
 
 
 
 
51313c5
b131270
4f81e4c
51313c5
4f81e4c
51313c5
 
 
 
 
 
 
 
 
eef490f
51313c5
 
eef490f
51313c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec103a7
 
 
 
 
 
 
51313c5
ec103a7
eef490f
51313c5
8771866
51313c5
8771866
 
51313c5
 
 
 
 
8771866
 
 
 
 
51313c5
 
 
8771866
 
 
 
51313c5
 
eef490f
51313c5
 
 
 
 
 
 
4c88601
 
 
 
 
 
 
 
 
 
 
 
 
51313c5
4c88601
51313c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4f81e4c
bddafba
51313c5
 
 
 
 
 
bddafba
4f81e4c
b131270
 
 
 
 
 
 
 
 
 
 
 
 
4f81e4c
 
 
 
 
 
 
 
 
b131270
 
4f81e4c
 
 
 
 
bddafba
 
 
4c88601
bddafba
4f81e4c
 
51313c5
 
 
 
 
 
 
 
 
 
 
 
 
250219f
eef490f
250219f
4c88601
51313c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4c88601
51313c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eef490f
bddafba
51313c5
 
 
bddafba
250219f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bddafba
250219f
4c88601
bddafba
4c88601
51313c5
 
bddafba
 
 
 
 
51313c5
4c88601
03f831a
4c88601
 
 
 
 
 
 
 
 
 
03f831a
 
 
 
 
 
 
 
 
 
 
 
4c88601
 
 
 
 
 
03f831a
4c88601
03f831a
4c88601
 
 
 
 
 
 
 
03f831a
 
4c88601
 
 
03f831a
 
4c88601
03f831a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4c88601
 
03f831a
4c88601
03f831a
 
 
 
 
4c88601
 
03f831a
4c88601
 
 
 
 
 
 
 
 
 
03f831a
 
 
 
 
 
 
 
4c88601
03f831a
 
4c88601
03f831a
 
 
4c88601
 
03f831a
 
4c88601
03f831a
 
 
4c88601
03f831a
 
4c88601
 
03f831a
 
4c88601
250219f
 
 
 
 
 
 
 
 
 
 
 
 
 
03f831a
 
51313c5
250219f
 
 
 
 
 
 
 
 
 
51313c5
eef490f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Swiss Army Web Tools 🛠️</title>
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://unpkg.com/feather-icons"></script>
    <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/qrcode.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js"></script>
    <style>
        .tool-card {
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }
        .tool-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .tab-btn.active {
            border-bottom-color: #22d3ee;
            color: white;
        }
.tab-content {
            display: none;
        }
        .tab-content.active {
            display: block;
            animation: fadeIn 0.5s ease;
        }
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }
#qrCodeCanvas {
            transition: all 0.3s ease;
        }
        #bgRemoverPreview {
            max-width: 100%;
            max-height: 320px;
            display: none;
            border-radius: 1rem;
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
            border: 1px solid rgba(255,255,255,0.1);
        }
        ::selection {
            background: rgba(34, 211, 238, 0.2);
        }
        ::-webkit-scrollbar {
            width: 8px;
            height: 8px;
        }
        ::-webkit-scrollbar-track {
            background: rgba(31, 41, 55, 0.5);
        }
        ::-webkit-scrollbar-thumb {
            background: rgba(74, 222, 128, 0.5);
            border-radius: 4px;
        }
        ::-webkit-scrollbar-thumb:hover {
            background: rgba(74, 222, 128, 0.7);
        }
</style>
</head>
<body class="min-h-screen bg-gradient-to-br from-gray-900 to-gray-800">
    <div class="container mx-auto px-4 py-8">
        <header class="text-center mb-12">
            <h1 class="text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-cyan-400 to-blue-500 mb-3">Swiss Army Web Tools</h1>
            <p class="text-xl text-gray-300">All-in-one utility toolkit for your daily web needs</p>
        </header>

        <div class="bg-gray-800 rounded-2xl shadow-xl overflow-hidden max-w-5xl mx-auto border border-gray-700 backdrop-blur-sm bg-opacity-50">
            <div class="flex overflow-x-auto">
                <button class="tab-btn px-6 py-4 font-medium text-gray-300 hover:text-white border-b-2 border-transparent hover:border-cyan-400 transition-all" data-tab="qr">
                    <div class="flex items-center gap-2">
                        <i data-feather="qr-code" class="w-5 h-5"></i>
                        QR Generator
                    </div>
                </button>
                <button class="tab-btn px-6 py-4 font-medium text-gray-300 hover:text-white border-b-2 border-transparent hover:border-cyan-400 transition-all" data-tab="counter">
                    <div class="flex items-center gap-2">
                        <i data-feather="type" class="w-5 h-5"></i>
                        Text Counter
                    </div>
                </button>
                <button class="tab-btn px-6 py-4 font-medium text-gray-300 hover:text-white border-b-2 border-transparent hover:border-cyan-400 transition-all" data-tab="shortener">
                    <div class="flex items-center gap-2">
                        <i data-feather="link-2" class="w-5 h-5"></i>
                        Link Shortener
                    </div>
                </button>
                <button class="tab-btn px-6 py-4 font-medium text-gray-300 hover:text-white border-b-2 border-transparent hover:border-cyan-400 transition-all" data-tab="bgremover">
                    <div class="flex items-center gap-2">
                        <i data-feather="image" class="w-5 h-5"></i>
                        BG Remover
                    </div>
                </button>
                <button class="tab-btn px-6 py-4 font-medium text-gray-300 hover:text-white border-b-2 border-transparent hover:border-cyan-400 transition-all" data-tab="password">
                    <div class="flex items-center gap-2">
                        <i data-feather="key" class="w-5 h-5"></i>
                        Password Gen
                    </div>
                </button>
                <button class="tab-btn px-6 py-4 font-medium text-gray-300 hover:text-white border-b-2 border-transparent hover:border-cyan-400 transition-all" data-tab="llm">
                    <div class="flex items-center gap-2">
                        <i data-feather="message-square" class="w-5 h-5"></i>
                        AI Chat
                    </div>
                </button>
</div>
            <div class="p-8">
<!-- QR Code Generator -->
                <div id="qr" class="tab-content active">
                    <h2 class="text-3xl font-semibold text-white mb-6 flex items-center gap-3">
                        <i data-feather="qr-code" class="w-8 h-8 text-cyan-400"></i>
                        QR Code Generator
                    </h2>
<div class="flex flex-col md:flex-row gap-8">
                        <div class="flex-1">
                            <div class="mb-4">
                                <label for="qrText" class="block text-gray-300 mb-3">Enter text or URL</label>
                                <textarea id="qrText" rows="3" class="w-full px-4 py-3 bg-gray-700 border border-gray-600 rounded-xl focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-transparent text-white placeholder-gray-400" placeholder="Enter text or URL to generate QR code"></textarea>
</div>
                            <div class="flex gap-4">
                                <button id="generateQR" class="bg-gradient-to-r from-cyan-500 to-blue-600 hover:from-cyan-600 hover:to-blue-700 text-white px-6 py-3 rounded-xl flex items-center gap-2 shadow-lg hover:shadow-cyan-500/20 transition-all">
                                    <i data-feather="rotate-cw"></i> Generate
                                </button>
                                <button id="downloadQR" class="bg-gradient-to-r from-emerald-500 to-green-600 hover:from-emerald-600 hover:to-green-700 text-white px-6 py-3 rounded-xl flex items-center gap-2 shadow-lg hover:shadow-emerald-500/20 transition-all" disabled>
                                    <i data-feather="download"></i> Download
                                </button>
</div>
                        </div>
                        <div class="flex-1 flex flex-col items-center justify-center">
                            <div id="qrCodeContainer" class="bg-gray-700 p-6 rounded-2xl border border-gray-600 mb-4 flex items-center justify-center">
                                <div id="qrCodeCanvas" class="w-56 h-56 flex flex-col items-center justify-center text-gray-400">
                                    <i data-feather="image" class="w-16 h-16 mb-2 opacity-50"></i>
                                    <p class="text-center text-gray-400">QR Code will appear here</p>
                                </div>
                            </div>
                            <p class="text-sm text-gray-400 flex items-center justify-center gap-1">
                                <i data-feather="smartphone" class="w-4 h-4"></i>
                                Scan the QR code with your phone
                            </p>
</div>
                    </div>
                </div>
                <!-- LLM Chat -->
                <div id="llm" class="tab-content">
                    <div class="text-center py-12">
                        <h2 class="text-3xl font-semibold text-white mb-4">AI Chat Assistant</h2>
                        <p class="text-gray-300 mb-6">This tool opens in a new page for better experience.</p>
                        <a href="llm.html" class="bg-gradient-to-r from-cyan-500 to-blue-600 hover:from-cyan-600 hover:to-blue-700 text-white px-6 py-3 rounded-xl inline-flex items-center gap-2 shadow-lg hover:shadow-cyan-500/20 transition-all">
                            <i data-feather="message-square"></i> Open Chat
                        </a>
                    </div>
                </div>

                <!-- Password Generator -->
<div id="password" class="tab-content">
                    <h2 class="text-2xl font-semibold text-gray-800 mb-4">Password Generator</h2>
                    <div class="mb-4">
                        <div class="flex items-center gap-4 mb-4">
                            <div class="flex-1">
                                <label for="passwordLength" class="block text-gray-700 mb-2">Length (8-32)</label>
                                <input type="range" id="passwordLength" min="8" max="32" value="12" class="w-full">
                                <div class="flex justify-between">
                                    <span>8</span>
                                    <span id="lengthValue">12</span>
                                    <span>32</span>
                                </div>
                            </div>
                            <div class="flex-1 flex justify-center items-center">
                                <button id="generatePassword" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg flex items-center gap-2">
                                    <i data-feather="refresh-cw"></i> Generate
                                </button>
                            </div>
                        </div>
                        <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
                            <div class="bg-white p-4 rounded-lg shadow">
                                <label class="flex items-center gap-2">
                                    <input type="checkbox" id="uppercase" checked class="rounded text-indigo-600">
                                    <span>Uppercase (A-Z)</span>
                                </label>
                            </div>
                            <div class="bg-white p-4 rounded-lg shadow">
                                <label class="flex items-center gap-2">
                                    <input type="checkbox" id="lowercase" checked class="rounded text-indigo-600">
                                    <span>Lowercase (a-z)</span>
                                </label>
                            </div>
                            <div class="bg-white p-4 rounded-lg shadow">
                                <label class="flex items-center gap-2">
                                    <input type="checkbox" id="numbers" checked class="rounded text-indigo-600">
                                    <span>Numbers (0-9)</span>
                                </label>
                            </div>
                            <div class="bg-white p-4 rounded-lg shadow">
                                <label class="flex items-center gap-2">
                                    <input type="checkbox" id="symbols" checked class="rounded text-indigo-600">
                                    <span>Symbols (!@#$%)</span>
                                </label>
                            </div>
                        </div>
                        <div class="mb-4">
                            <label for="generatedPassword" class="block text-gray-700 mb-2">Generated Password</label>
                            <div class="flex gap-2">
                                <input type="text" id="generatedPassword" class="flex-1 px-3 py-2 border border-gray-300 rounded-lg bg-white" readonly>
                                <button id="copyPassword" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-3 py-2 rounded-lg flex items-center gap-1">
                                    <i data-feather="copy"></i>
                                </button>
                            </div>
                        </div>
                        <div class="bg-gray-100 p-4 rounded-lg">
                            <h3 class="text-lg font-medium text-gray-800 mb-2">Password Strength</h3>
                            <div class="flex items-center gap-2 mb-2">
                                <div id="strengthMeter" class="h-2 flex-1 bg-gray-300 rounded-full overflow-hidden">
                                    <div class="h-full bg-red-500 w-0" id="strengthBar"></div>
                                </div>
                                <span id="strengthText" class="text-sm font-medium">Weak</span>
                            </div>
                            <p class="text-sm text-gray-600" id="strengthFeedback">Use a longer password with more character types</p>
                        </div>
                    </div>
                </div>

                <!-- Text Counter -->
                <div id="counter" class="tab-content">
                    <h2 class="text-2xl font-semibold text-gray-800 mb-4">Text & Character Counter</h2>
                    <div class="mb-4">
                        <label for="textInput" class="block text-gray-700 mb-2">Enter your text</label>
                        <textarea id="textInput" rows="6" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="Type or paste your text here..."></textarea>
                    </div>
                    <div class="grid grid-cols-1 md:grid-cols-3 gap-4 bg-gray-100 p-4 rounded-lg">
                        <div class="bg-white p-4 rounded-lg shadow text-center">
                            <p class="text-sm text-gray-500">Characters</p>
                            <p id="charCount" class="text-3xl font-bold text-indigo-600">0</p>
                        </div>
                        <div class="bg-white p-4 rounded-lg shadow text-center">
                            <p class="text-sm text-gray-500">Words</p>
                            <p id="wordCount" class="text-3xl font-bold text-indigo-600">0</p>
                        </div>
                        <div class="bg-white p-4 rounded-lg shadow text-center">
                            <p class="text-sm text-gray-500">Sentences</p>
                            <p id="sentenceCount" class="text-3xl font-bold text-indigo-600">0</p>
                        </div>
                    </div>
                </div>

                <!-- Link Shortener -->
                <div id="shortener" class="tab-content">
                    <h2 class="text-2xl font-semibold text-gray-800 mb-4">Link Shortener</h2>
                    <div class="mb-4">
                        <label for="longUrl" class="block text-gray-700 mb-2">Enter long URL</label>
                        <input type="url" id="longUrl" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="https://example.com/very-long-url...">
                        <div class="mt-2">
                            <label for="customText" class="block text-gray-700 mb-2">Custom text (optional)</label>
                            <input type="text" id="customText" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="my-custom-text" maxlength="30">
                            <p class="text-xs text-gray-500 mt-1">Max 30 characters, letters and numbers only</p>
                        </div>
                    </div>
<button id="shortenBtn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg flex items-center gap-2 mb-4 hovered-element">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-scissors"><circle cx="6" cy="6" r="3"></circle><circle cx="6" cy="18" r="3"></circle><line x1="20" y1="4" x2="8.12" y2="15.88"></line><line x1="14.47" y1="14.48" x2="20" y2="20"></line><line x1="8.12" y1="8.12" x2="12" y2="12"></line></svg> Shorten URL
                    </button>
<div id="shortUrlResult" class="hidden bg-gray-100 p-4 rounded-lg">
                        <label class="block text-gray-700 mb-2">Short URL</label>
                        <div class="flex gap-2">
                            <input type="text" id="shortUrl" class="flex-1 px-3 py-2 border border-gray-300 rounded-lg bg-white" readonly>
                            <button id="copyShortUrl" class="bg-gray-200 hover:bg-gray-300 text-gray-800 px-3 py-2 rounded-lg flex items-center gap-1">
                                <i data-feather="copy"></i>
                            </button>
                        </div>
                    </div>
                </div>

                <!-- Background Remover -->
                <div id="bgremover" class="tab-content">
                    <h2 class="text-2xl font-semibold text-gray-800 mb-4">Background Remover</h2>
                    <div class="mb-4">
                        <label for="imageUpload" class="block text-gray-700 mb-2">Upload image</label>
                        <div class="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center cursor-pointer hover:border-indigo-400 transition" id="dropZone">
                            <input type="file" id="imageUpload" accept="image/*" class="hidden">
                            <div class="flex flex-col items-center justify-center">
                                <i data-feather="upload" class="w-10 h-10 text-gray-400 mb-2"></i>
                                <p class="text-gray-500">Drag & drop an image or click to browse</p>
                                <p class="text-sm text-gray-400 mt-1">Supports JPG, PNG (Max 5MB)</p>
                            </div>
                        </div>
                    </div>
                    <div class="flex justify-center mb-4">
                        <img id="bgRemoverPreview" alt="Preview" class="rounded-lg">
                    </div>
                    <button id="removeBgBtn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg flex items-center gap-2 mb-4 hidden">
                        <i data-feather="edit-3"></i> Remove Background
                    </button>
                    <div id="bgRemoverResult" class="hidden">
                        <div class="flex flex-col md:flex-row gap-4">
                            <div class="flex-1">
                                <p class="text-gray-700 mb-2">Original</p>
                                <img id="originalImage" src="" alt="Original" class="w-full rounded-lg border border-gray-200">
                            </div>
                            <div class="flex-1">
                                <p class="text-gray-700 mb-2">Background Removed</p>
                                <img id="processedImage" src="" alt="Processed" class="w-full rounded-lg border border-gray-200">
                            </div>
                        </div>
                        <div class="mt-4 flex justify-center">
                            <button id="downloadProcessed" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg flex items-center gap-2">
                                <i data-feather="download"></i> Download Result
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <footer class="mt-16 text-center text-gray-400 text-sm">
            <p class="flex items-center justify-center gap-1">
                Made with <i data-feather="heart" class="inline text-pink-500 w-4 h-4"></i> for the web
            </p>
            <p class="mt-2 text-xs text-gray-500">
                v1.0.0 · Swiss Army Web Tools
            </p>
        </footer>
</div>

    <script>
        // Tab switching
        document.querySelectorAll('.tab-btn').forEach(btn => {
            btn.addEventListener('click', function() {
                // Remove active classes from all buttons
                document.querySelectorAll('.tab-btn').forEach(t => {
                    t.classList.remove('border-indigo-600', 'text-indigo-600');
                    t.classList.add('text-gray-500');
                });
                
                // Add active classes to clicked button
                this.classList.add('border-indigo-600', 'text-indigo-600');
                this.classList.remove('text-gray-500');
                
                // Hide all tab contents
                document.querySelectorAll('.tab-content').forEach(tab => {
                    tab.classList.remove('active');
                });
                
                // Show the selected tab content
                const tabId = this.getAttribute('data-tab');
                document.getElementById(tabId).classList.add('active');
            });
        });
        // QR Code Generator
        document.getElementById('generateQR').addEventListener('click', () => {
            const text = document.getElementById('qrText').value.trim();
            if (!text) {
                alert('Please enter some text or URL');
                return;
            }

            try {
                const qr = qrcode(0, 'L');
                qr.addData(text);
                qr.make();
                
                const qrContainer = document.getElementById('qrCodeCanvas');
                qrContainer.innerHTML = qr.createImgTag(4, 0);
                qrContainer.querySelector('img').style.maxWidth = '100%';
                document.getElementById('downloadQR').disabled = false;
            } catch (e) {
                console.error('QR generation error:', e);
                alert('Failed to generate QR code. Please try different text.');
            }
        });
document.getElementById('downloadQR').addEventListener('click', () => {
            const qrImg = document.querySelector('#qrCodeCanvas img');
            if (!qrImg) {
                alert('Please generate a QR code first');
                return;
            }

            const link = document.createElement('a');
            link.download = 'qrcode.png';
            link.href = qrImg.src;
            link.click();
        });

        // Text Counter
        document.getElementById('textInput').addEventListener('input', () => {
            const text = document.getElementById('textInput').value;
            
            // Character count
            document.getElementById('charCount').textContent = text.length;
            
            // Word count
            const words = text.trim() ? text.trim().split(/\s+/).length : 0;
            document.getElementById('wordCount').textContent = words;
            
            // Sentence count (very basic)
            const sentences = text.trim() ? text.split(/[.!?]+/).filter(s => s.trim().length > 0).length : 0;
            document.getElementById('sentenceCount').textContent = sentences;
        });
        // Link Shortener using is.gd API as fallback
        document.getElementById('shortenBtn').addEventListener('click', async () => {
            const longUrl = document.getElementById('longUrl').value.trim();
            if (!longUrl) {
                alert('Please enter a URL');
                return;
            }

            try {
                // First try is.gd
                const customText = document.getElementById('customText').value.trim();
                let apiUrl = `https://is.gd/create.php?format=json&url=${encodeURIComponent(longUrl)}`;
                
                if (customText) {
                    if (!/^[a-zA-Z0-9-]+$/.test(customText)) {
                        alert('Custom text can only contain letters, numbers and hyphens');
                        return;
                    }
                    apiUrl += `&shorturl=${encodeURIComponent(customText)}`;
                }

                const isgdResponse = await fetch(apiUrl);
if (isgdResponse.ok) {
                    const isgdData = await isgdResponse.json();
                    if (isgdData.shorturl) {
                        document.getElementById('shortUrl').value = isgdData.shorturl;
                        document.getElementById('shortUrlResult').classList.remove('hidden');
                        return;
                    }
                }

                // Fallback to v.gd
                const vgdResponse = await fetch(apiUrl.replace('is.gd', 'v.gd'));
const vgdData = await vgdResponse.json();
                if (vgdResponse.ok && vgdData.shorturl) {
                    document.getElementById('shortUrl').value = vgdData.shorturl;
                } else {
                    throw new Error('Failed to shorten URL with both services');
                }
                document.getElementById('shortUrlResult').classList.remove('hidden');
            } catch (error) {
                console.error('Error shortening URL:', error);
                alert('Failed to shorten URL. Please try again later or use a different URL.');
            }
        });
document.getElementById('copyShortUrl').addEventListener('click', () => {
            const shortUrl = document.getElementById('shortUrl');
            shortUrl.select();
            document.execCommand('copy');
            
            const copyBtn = document.getElementById('copyShortUrl');
            copyBtn.innerHTML = '<i data-feather="check"></i>';
            feather.replace();
            
            setTimeout(() => {
                copyBtn.innerHTML = '<i data-feather="copy"></i>';
                feather.replace();
            }, 2000);
        });
        // Background Remover using Remove.bg API (demo mode with mock response)
        const dropZone = document.getElementById('dropZone');
const fileInput = document.getElementById('imageUpload');
        let currentFile = null;
        
        dropZone.addEventListener('click', () => fileInput.click());
        
        dropZone.addEventListener('dragover', (e) => {
            e.preventDefault();
            dropZone.classList.add('border-indigo-400');
        });
        
        dropZone.addEventListener('dragleave', () => {
            dropZone.classList.remove('border-indigo-400');
        });
        
        dropZone.addEventListener('drop', (e) => {
            e.preventDefault();
            dropZone.classList.remove('border-indigo-400');
            
            if (e.dataTransfer.files.length) {
                fileInput.files = e.dataTransfer.files;
                handleImageUpload(e.dataTransfer.files[0]);
            }
        });
        
        fileInput.addEventListener('change', (e) => {
            if (e.target.files.length) {
                handleImageUpload(e.target.files[0]);
            }
        });
        
        function handleImageUpload(file) {
            currentFile = file;
            if (!file.type.match('image.*')) {
                alert('Please upload an image file');
                return;
            }
            
            if (file.size > 5 * 1024 * 1024) {
                alert('File size should be less than 5MB');
                return;
            }
            
            const reader = new FileReader();
            reader.onload = (e) => {
                const preview = document.getElementById('bgRemoverPreview');
                preview.src = e.target.result;
                preview.style.display = 'block';
                document.getElementById('removeBgBtn').classList.remove('hidden');
            };
            reader.readAsDataURL(file);
        }

        document.getElementById('removeBgBtn').addEventListener('click', async () => {
            const preview = document.getElementById('bgRemoverPreview');
            const originalImg = document.getElementById('originalImage');
            const processedImg = document.getElementById('processedImage');
            try {
                // Show loading state
                const btn = document.getElementById('removeBgBtn');
                const originalText = btn.innerHTML;
                btn.innerHTML = '<i data-feather="loader"></i> Processing...';
                feather.replace();

                // In a real implementation, you would call the Remove.bg API here
                // For demo purposes, we'll simulate a successful response after 2 seconds
                setTimeout(() => {
                    originalImg.src = preview.src;
                    processedImg.src = preview.src.replace(/^data:image\/[^;]+/, 'data:image/png') + '&processed=true';
                    document.getElementById('bgRemoverResult').classList.remove('hidden');
                    btn.innerHTML = originalText;
                    feather.replace();
                }, 2000);
            } catch (error) {
console.error('Error removing background:', error);
                alert('Failed to process image. Please try again later.');
            }
});
        
        document.getElementById('downloadProcessed').addEventListener('click', () => {
            const processedImg = document.getElementById('processedImage');
            const link = document.createElement('a');
            link.download = 'background_removed.png';
            link.href = processedImg.src;
            link.click();
        });
        // Password Generator - improved with better character selection
        document.getElementById('passwordLength').addEventListener('input', function() {
            const length = this.value;
            document.getElementById('lengthValue').textContent = length;
            
            // Auto-adjust complexity for longer passwords
            if (length >= 16) {
                document.getElementById('symbols').checked = true;
                document.getElementById('uppercase').checked = true;
                document.getElementById('numbers').checked = true;
            }
});
        document.getElementById('generatePassword').addEventListener('click', function() {
            const length = document.getElementById('passwordLength').value;
            const uppercase = document.getElementById('uppercase').checked;
            const lowercase = document.getElementById('lowercase').checked;
            const numbers = document.getElementById('numbers').checked;
            const symbols = document.getElementById('symbols').checked;

            if (!uppercase && !lowercase && !numbers && !symbols) {
                alert('Please select at least one character type');
                return;
            }

            // Build character sets separately to ensure at least one of each selected type
            const charSets = [];
            if (uppercase) charSets.push('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
            if (lowercase) charSets.push('abcdefghijklmnopqrstuvwxyz');
            if (numbers) charSets.push('0123456789');
            if (symbols) charSets.push('!@#$%^&*()_+-=[]{}|;:,.<>?');

            // Ensure at least one character from each selected set
            let password = '';
            charSets.forEach(set => {
                password += set.charAt(Math.floor(Math.random() * set.length));
            });

            // Fill the rest of the password
            const allChars = charSets.join('');
            for (let i = password.length; i < length; i++) {
                password += allChars.charAt(Math.floor(Math.random() * allChars.length));
            }

            // Shuffle the password to mix the guaranteed characters
            password = password.split('').sort(() => 0.5 - Math.random()).join('');

            document.getElementById('generatedPassword').value = password;
            updatePasswordStrength(password);
});

        document.getElementById('copyPassword').addEventListener('click', function() {
            const password = document.getElementById('generatedPassword');
            password.select();
            document.execCommand('copy');
            
            const copyBtn = document.getElementById('copyPassword');
            copyBtn.innerHTML = '<i data-feather="check"></i>';
            feather.replace();
            
            setTimeout(() => {
                copyBtn.innerHTML = '<i data-feather="copy"></i>';
                feather.replace();
            }, 2000);
        });
        function updatePasswordStrength(password) {
            let strength = 0;
            const length = password.length;
            
            // Length score (max 50)
            strength += Math.min(length * 2, 50);
            
            // Character variety (max 50)
            const hasUpper = /[A-Z]/.test(password);
            const hasLower = /[a-z]/.test(password);
            const hasNumber = /[0-9]/.test(password);
            const hasSymbol = /[^A-Za-z0-9]/.test(password);
            
            const uniqueChars = new Set(password.split('')).size;
            strength += (uniqueChars / length) * 20; // Uniqueness bonus
            
            let typeCount = 0;
            if (hasUpper) typeCount++;
            if (hasLower) typeCount++;
            if (hasNumber) typeCount++;
            if (hasSymbol) typeCount++;
            
            strength += typeCount * 10;
            
            // Cap at 100
            strength = Math.min(strength, 100);
            
            // Update UI
            const strengthBar = document.getElementById('strengthBar');
            const strengthText = document.getElementById('strengthText');
            const strengthFeedback = document.getElementById('strengthFeedback');
            
            let color, text, feedback;
            
            if (strength < 40) {
                color = 'bg-red-500';
                text = 'Weak';
                feedback = 'Consider using a longer password (12+ chars) with more character types';
            } else if (strength < 70) {
                color = 'bg-yellow-500';
                text = 'Moderate';
                feedback = 'Good password. Adding symbols or length would improve it';
            } else if (strength < 85) {
                color = 'bg-blue-500';
                text = 'Strong';
                feedback = 'Great password!';
            } else {
                color = 'bg-green-500';
                text = 'Very Strong';
                feedback = 'Excellent password! Very secure!';
            }
            
            strengthBar.className = `h-full ${color}`;
            strengthBar.style.width = `${strength}%`;
            strengthText.textContent = text;
            strengthFeedback.textContent = feedback;
}
        // QR Code - Auto-generate when tab is selected
        document.querySelector('.tab-btn[data-tab="qr"]').addEventListener('click', () => {
            const qrText = document.getElementById('qrText').value.trim();
            if (qrText && !document.querySelector('#qrCodeCanvas img')) {
                document.getElementById('generateQR').click();
            }
        });

        // Password - Auto-generate first password on tab select
        document.querySelector('.tab-btn[data-tab="password"]').addEventListener('click', () => {
            if (!document.getElementById('generatedPassword').value) {
                document.getElementById('generatePassword').click();
            }
        });

        // Initialize feather icons
        feather.replace();

        // Add service worker for offline functionality
        if ('serviceWorker' in navigator) {
            window.addEventListener('load', () => {
                navigator.serviceWorker.register('/sw.js').catch(err => {
                    console.log('ServiceWorker registration failed: ', err);
                });
            });
        }
</script>
</body>
</html>