jason1i commited on
Commit
01fb2c4
Β·
verified Β·
1 Parent(s): a6a0d92

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +785 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Seo Analyzer Using Deepsite
3
- emoji: πŸ“Š
4
- colorFrom: gray
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: seo-analyzer-using-deepsite
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: blue
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,785 @@
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>SEO Analyzer Tool</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
8
+ <style>
9
+ :root {
10
+ --primary-color: #4a6fa5;
11
+ --secondary-color: #166088;
12
+ --accent-color: #4fc3f7;
13
+ --light-color: #f8f9fa;
14
+ --dark-color: #343a40;
15
+ --success-color: #28a745;
16
+ --warning-color: #ffc107;
17
+ --danger-color: #dc3545;
18
+ --border-radius: 8px;
19
+ --box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
20
+ }
21
+
22
+ * {
23
+ margin: 0;
24
+ padding: 0;
25
+ box-sizing: border-box;
26
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
27
+ }
28
+
29
+ body {
30
+ background-color: #f5f7fa;
31
+ color: var(--dark-color);
32
+ line-height: 1.6;
33
+ padding: 20px;
34
+ }
35
+
36
+ .container {
37
+ max-width: 1200px;
38
+ margin: 0 auto;
39
+ padding: 20px;
40
+ }
41
+
42
+ header {
43
+ text-align: center;
44
+ margin-bottom: 40px;
45
+ padding: 20px 0;
46
+ background-color: white;
47
+ border-radius: var(--border-radius);
48
+ box-shadow: var(--box-shadow);
49
+ }
50
+
51
+ h1 {
52
+ color: var(--primary-color);
53
+ margin-bottom: 10px;
54
+ font-weight: 700;
55
+ }
56
+
57
+ .tagline {
58
+ color: var(--secondary-color);
59
+ font-size: 1.2rem;
60
+ margin-bottom: 20px;
61
+ }
62
+
63
+ .analyzer-container {
64
+ display: flex;
65
+ flex-direction: column;
66
+ gap: 20px;
67
+ }
68
+
69
+ .input-section, .results-section {
70
+ background-color: white;
71
+ border-radius: var(--border-radius);
72
+ box-shadow: var(--box-shadow);
73
+ padding: 25px;
74
+ }
75
+
76
+ .input-section {
77
+ display: flex;
78
+ flex-direction: column;
79
+ gap: 15px;
80
+ }
81
+
82
+ .input-group {
83
+ display: flex;
84
+ flex-direction: column;
85
+ gap: 5px;
86
+ }
87
+
88
+ label {
89
+ font-weight: 600;
90
+ color: var(--secondary-color);
91
+ }
92
+
93
+ input[type="url"], textarea {
94
+ padding: 12px 15px;
95
+ border: 1px solid #ddd;
96
+ border-radius: var(--border-radius);
97
+ font-size: 1rem;
98
+ transition: all 0.3s;
99
+ }
100
+
101
+ input[type="url"]:focus, textarea:focus {
102
+ outline: none;
103
+ border-color: var(--accent-color);
104
+ box-shadow: 0 0 0 2px rgba(79, 195, 247, 0.2);
105
+ }
106
+
107
+ .button-group {
108
+ display: flex;
109
+ gap: 10px;
110
+ }
111
+
112
+ button {
113
+ padding: 12px 20px;
114
+ border: none;
115
+ border-radius: var(--border-radius);
116
+ font-size: 1rem;
117
+ font-weight: 600;
118
+ cursor: pointer;
119
+ transition: all 0.3s;
120
+ display: flex;
121
+ align-items: center;
122
+ gap: 8px;
123
+ }
124
+
125
+ .btn-primary {
126
+ background-color: var(--primary-color);
127
+ color: white;
128
+ }
129
+
130
+ .btn-primary:hover {
131
+ background-color: var(--secondary-color);
132
+ }
133
+
134
+ .btn-secondary {
135
+ background-color: var(--light-color);
136
+ color: var(--dark-color);
137
+ border: 1px solid #ddd;
138
+ }
139
+
140
+ .btn-secondary:hover {
141
+ background-color: #e9ecef;
142
+ }
143
+
144
+ .results-section {
145
+ display: none;
146
+ }
147
+
148
+ .results-header {
149
+ display: flex;
150
+ justify-content: space-between;
151
+ align-items: center;
152
+ margin-bottom: 20px;
153
+ padding-bottom: 15px;
154
+ border-bottom: 1px solid #eee;
155
+ }
156
+
157
+ .results-header h2 {
158
+ color: var(--primary-color);
159
+ }
160
+
161
+ .overall-score {
162
+ font-size: 1.5rem;
163
+ font-weight: 700;
164
+ color: white;
165
+ background-color: var(--primary-color);
166
+ padding: 8px 15px;
167
+ border-radius: var(--border-radius);
168
+ }
169
+
170
+ .results-content {
171
+ display: grid;
172
+ grid-template-columns: 1fr 1fr;
173
+ gap: 20px;
174
+ }
175
+
176
+ .result-card {
177
+ background-color: var(--light-color);
178
+ border-radius: var(--border-radius);
179
+ padding: 20px;
180
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
181
+ transition: transform 0.3s;
182
+ }
183
+
184
+ .result-card:hover {
185
+ transform: translateY(-5px);
186
+ }
187
+
188
+ .card-header {
189
+ display: flex;
190
+ justify-content: space-between;
191
+ align-items: center;
192
+ margin-bottom: 15px;
193
+ }
194
+
195
+ .card-title {
196
+ font-weight: 600;
197
+ color: var(--secondary-color);
198
+ display: flex;
199
+ align-items: center;
200
+ gap: 8px;
201
+ }
202
+
203
+ .card-icon {
204
+ font-size: 1.2rem;
205
+ }
206
+
207
+ .card-status {
208
+ padding: 4px 10px;
209
+ border-radius: 20px;
210
+ font-size: 0.8rem;
211
+ font-weight: 600;
212
+ }
213
+
214
+ .status-good {
215
+ background-color: rgba(40, 167, 69, 0.2);
216
+ color: var(--success-color);
217
+ }
218
+
219
+ .status-warning {
220
+ background-color: rgba(255, 193, 7, 0.2);
221
+ color: var(--warning-color);
222
+ }
223
+
224
+ .status-bad {
225
+ background-color: rgba(220, 53, 69, 0.2);
226
+ color: var(--danger-color);
227
+ }
228
+
229
+ .result-details {
230
+ margin-top: 10px;
231
+ color: #555;
232
+ font-size: 0.95rem;
233
+ }
234
+
235
+ .keyword-density-list {
236
+ list-style-type: none;
237
+ margin-top: 10px;
238
+ }
239
+
240
+ .keyword-density-list li {
241
+ display: flex;
242
+ justify-content: space-between;
243
+ padding: 5px 0;
244
+ border-bottom: 1px dashed #eee;
245
+ }
246
+
247
+ .progress-bar {
248
+ background-color: #e9ecef;
249
+ height: 10px;
250
+ border-radius: 5px;
251
+ margin-top: 15px;
252
+ overflow: hidden;
253
+ }
254
+
255
+ .progress-fill {
256
+ height: 100%;
257
+ background-color: var(--primary-color);
258
+ border-radius: 5px;
259
+ transition: width 0.5s;
260
+ }
261
+
262
+ .issues-list {
263
+ margin-top: 10px;
264
+ list-style-type: none;
265
+ }
266
+
267
+ .issues-list li {
268
+ padding: 5px 0;
269
+ display: flex;
270
+ align-items: flex-start;
271
+ gap: 8px;
272
+ }
273
+
274
+ .issue-icon {
275
+ color: var(--danger-color);
276
+ margin-top: 3px;
277
+ }
278
+
279
+ .toggle-details {
280
+ color: var(--accent-color);
281
+ cursor: pointer;
282
+ font-weight: 600;
283
+ margin-top: 10px;
284
+ display: inline-block;
285
+ }
286
+
287
+ .details-content {
288
+ display: none;
289
+ background-color: white;
290
+ padding: 15px;
291
+ margin-top: 10px;
292
+ border-radius: var(--border-radius);
293
+ border-left: 3px solid var(--accent-color);
294
+ font-family: monospace;
295
+ white-space: pre-wrap;
296
+ word-break: break-word;
297
+ max-height: 200px;
298
+ overflow-y: auto;
299
+ }
300
+
301
+ .active .details-content {
302
+ display: block;
303
+ }
304
+
305
+ footer {
306
+ text-align: center;
307
+ margin-top: 40px;
308
+ padding: 20px;
309
+ color: #666;
310
+ font-size: 0.9rem;
311
+ }
312
+
313
+ @media (max-width: 768px) {
314
+ .results-content {
315
+ grid-template-columns: 1fr;
316
+ }
317
+
318
+ .button-group {
319
+ flex-direction: column;
320
+ }
321
+ }
322
+
323
+ /* Loading spinner */
324
+ .loader {
325
+ display: none;
326
+ border: 4px solid rgba(0, 0, 0, 0.1);
327
+ border-radius: 50%;
328
+ border-top: 4px solid var(--primary-color);
329
+ width: 40px;
330
+ height: 40px;
331
+ animation: spin 1s linear infinite;
332
+ margin: 20px auto;
333
+ }
334
+
335
+ @keyframes spin {
336
+ 0% { transform: rotate(0deg); }
337
+ 100% { transform: rotate(360deg); }
338
+ }
339
+ </style>
340
+ </head>
341
+ <body>
342
+ <div class="container">
343
+ <header>
344
+ <h1><i class="fas fa-search"></i> SEO Analyzer Tool</h1>
345
+ <p class="tagline">Optimize your website's search engine performance with our comprehensive SEO analysis</p>
346
+ </header>
347
+
348
+ <div class="analyzer-container">
349
+ <div class="input-section">
350
+ <h2><i class="fas fa-chart-line"></i> Analyze Your Website</h2>
351
+ <p>Enter a URL or HTML content to analyze the SEO factors and get improvement suggestions.</p>
352
+
353
+ <div class="input-group">
354
+ <label for="url-input"><i class="fas fa-link"></i> Website URL</label>
355
+ <input type="url" id="url-input" placeholder="https://example.com" autocomplete="off">
356
+ </div>
357
+
358
+ <div class="input-group">
359
+ <label for="html-input"><i class="fas fa-code"></i> Or paste HTML content</label>
360
+ <textarea id="html-input" rows="8" placeholder="Paste your HTML content here..."></textarea>
361
+ </div>
362
+
363
+ <div class="input-group">
364
+ <label for="keywords-input"><i class="fas fa-key"></i> Target keywords (comma separated)</label>
365
+ <input type="text" id="keywords-input" placeholder="seo, analyzer, tool">
366
+ </div>
367
+
368
+ <div class="button-group">
369
+ <button class="btn-primary" id="analyze-btn">
370
+ <i class="fas fa-search"></i> Analyze SEO
371
+ </button>
372
+ <button class="btn-secondary" id="clear-btn">
373
+ <i class="fas fa-trash"></i> Clear
374
+ </button>
375
+ </div>
376
+ </div>
377
+
378
+ <div class="loader" id="loader"></div>
379
+
380
+ <div class="results-section" id="results-section">
381
+ <div class="results-header">
382
+ <h2><i class="fas fa-clipboard-check"></i> Analysis Results</h2>
383
+ <div class="overall-score" id="overall-score">0/100</div>
384
+ </div>
385
+
386
+ <div class="progress-bar">
387
+ <div class="progress-fill" id="score-progress" style="width: 0%"></div>
388
+ </div>
389
+
390
+ <div class="results-content" id="results-content">
391
+ <!-- Results will be populated here by JavaScript -->
392
+ </div>
393
+ </div>
394
+ </div>
395
+ </div>
396
+
397
+ <footer>
398
+ <p>&copy; 2023 SEO Analyzer Tool | Built with HTML, CSS & JavaScript</p>
399
+ </footer>
400
+
401
+ <script>
402
+ document.addEventListener('DOMContentLoaded', function() {
403
+ // DOM Elements
404
+ const urlInput = document.getElementById('url-input');
405
+ const htmlInput = document.getElementById('html-input');
406
+ const keywordsInput = document.getElementById('keywords-input');
407
+ const analyzeBtn = document.getElementById('analyze-btn');
408
+ const clearBtn = document.getElementById('clear-btn');
409
+ const resultsSection = document.getElementById('results-section');
410
+ const resultsContent = document.getElementById('results-content');
411
+ const overallScore = document.getElementById('overall-score');
412
+ const scoreProgress = document.getElementById('score-progress');
413
+ const loader = document.getElementById('loader');
414
+
415
+ // Event Listeners
416
+ analyzeBtn.addEventListener('click', analyzeSEO);
417
+ clearBtn.addEventListener('click', clearInputs);
418
+
419
+ // Toggle details visibility
420
+ document.addEventListener('click', function(e) {
421
+ if (e.target.classList.contains('toggle-details')) {
422
+ e.target.parentElement.classList.toggle('active');
423
+ }
424
+ });
425
+
426
+ // Analyze SEO function
427
+ function analyzeSEO() {
428
+ const url = urlInput.value.trim();
429
+ const html = htmlInput.value.trim();
430
+ const keywords = keywordsInput.value.trim();
431
+
432
+ if (!url && !html) {
433
+ alert('Please enter a URL or paste HTML content to analyze.');
434
+ return;
435
+ }
436
+
437
+ // Show loading spinner
438
+ loader.style.display = 'block';
439
+ resultsSection.style.display = 'none';
440
+
441
+ // Simulate analysis (in a real app, you'd fetch data from a server or API)
442
+ setTimeout(() => {
443
+ const analysisResults = performAnalysis(url, html, keywords);
444
+ displayResults(analysisResults);
445
+
446
+ // Hide loading spinner and show results
447
+ loader.style.display = 'none';
448
+ resultsSection.style.display = 'block';
449
+ }, 1500);
450
+ }
451
+
452
+ // Perform SEO analysis
453
+ function performAnalysis(url, html, keywords) {
454
+ // Parse keywords
455
+ const targetKeywords = keywords
456
+ ? keywords.split(',').map(k => k.trim().toLowerCase()).filter(k => k)
457
+ : [];
458
+
459
+ // For demo purposes, we'll simulate analysis results
460
+ // In a real app, you would parse the HTML and calculate these values
461
+ const hasTitle = Math.random() > 0.1;
462
+ const titleText = hasTitle ? 'SEO Analyzer Tool - Improve Your Search Rankings' : '';
463
+ const titleLength = hasTitle ? titleText.length : 0;
464
+
465
+ const hasMetaDescription = Math.random() > 0.2;
466
+ const metaDescriptionText = hasMetaDescription
467
+ ? 'Free SEO analyzer tool that checks your website for common SEO issues and provides improvement suggestions.'
468
+ : '';
469
+ const metaDescriptionLength = hasMetaDescription ? metaDescriptionText.length : 0;
470
+
471
+ const hasH1 = Math.random() > 0.1;
472
+ const h1Count = hasH1 ? 1 : 0;
473
+ const h1Text = hasH1 ? 'SEO Analyzer Tool' : '';
474
+
475
+ const h2Count = Math.floor(Math.random() * 4) + (hasH1 ? 1 : 0);
476
+ const imageCount = Math.floor(Math.random() * 10) + 3;
477
+ const imagesWithAlt = Math.floor(Math.random() * (imageCount - 2)) + 1;
478
+
479
+ const linksCount = Math.floor(Math.random() * 20) + 5;
480
+ const internalLinksCount = Math.floor(linksCount * 0.7);
481
+ const externalLinksCount = linksCount - internalLinksCount;
482
+
483
+ const wordCount = Math.floor(Math.random() * 1500) + 500;
484
+ const keywordDensity = {};
485
+
486
+ targetKeywords.forEach(keyword => {
487
+ const density = Math.random() * 2 + 0.5;
488
+ keywordDensity[keyword] = parseFloat(density.toFixed(1));
489
+ });
490
+
491
+ // Calculate overall score (0-100)
492
+ const scoreFactors = {
493
+ title: hasTitle ? 10 : 0,
494
+ titleLength: titleLength >= 30 && titleLength <= 60 ? 5 : 0,
495
+ metaDescription: hasMetaDescription ? 10 : 0,
496
+ metaDescriptionLength: metaDescriptionLength >= 70 && metaDescriptionLength <= 160 ? 5 : 0,
497
+ h1: h1Count === 1 ? 10 : 0,
498
+ h2: h2Count >= 2 ? 5 : 0,
499
+ images: imagesWithAlt / imageCount * 5,
500
+ internalLinks: internalLinksCount >= 5 ? 5 : 0,
501
+ keywords: Object.keys(keywordDensity).length > 0 ? 5 : 0,
502
+ keywordDensity: targetKeywords.length > 0 ? 10 : 0
503
+ };
504
+
505
+ let score = 0;
506
+ for (const factor in scoreFactors) {
507
+ score += scoreFactors[factor];
508
+ }
509
+ score = Math.floor(score);
510
+
511
+ return {
512
+ url,
513
+ score,
514
+ targetKeywords,
515
+ details: {
516
+ title: {
517
+ exists: hasTitle,
518
+ text: titleText,
519
+ length: titleLength,
520
+ status: titleLength >= 30 && titleLength <= 60 ? 'good' : titleLength > 60 ? 'too-long' : 'too-short'
521
+ },
522
+ metaDescription: {
523
+ exists: hasMetaDescription,
524
+ text: metaDescriptionText,
525
+ length: metaDescriptionLength,
526
+ status: metaDescriptionLength >= 70 && metaDescriptionLength <= 160 ? 'good' : metaDescriptionLength > 160 ? 'too-long' : 'too-short'
527
+ },
528
+ headings: {
529
+ h1: {
530
+ exists: hasH1,
531
+ count: h1Count,
532
+ text: h1Text
533
+ },
534
+ h2: {
535
+ count: h2Count
536
+ }
537
+ },
538
+ images: {
539
+ count: imageCount,
540
+ withAlt: imagesWithAlt
541
+ },
542
+ links: {
543
+ count: linksCount,
544
+ internal: internalLinksCount,
545
+ external: externalLinksCount
546
+ },
547
+ content: {
548
+ wordCount: wordCount
549
+ },
550
+ keywordDensity: keywordDensity
551
+ }
552
+ };
553
+ }
554
+
555
+ // Display analysis results
556
+ function displayResults(results) {
557
+ // Update overall score
558
+ overallScore.textContent = `${results.score}/100`;
559
+ scoreProgress.style.width = `${results.score}%`;
560
+
561
+ // Empty results container
562
+ resultsContent.innerHTML = '';
563
+
564
+ // Add meta tags card
565
+ addResultCard({
566
+ title: 'Meta Tags',
567
+ icon: 'fas fa-tags',
568
+ status: results.details.title.exists && results.details.metaDescription.exists ? 'good' :
569
+ !results.details.title.exists && !results.details.metaDescription.exists ? 'bad' : 'warning',
570
+ content: [
571
+ results.details.title.exists
572
+ ? `<p>Title tag: <strong>"${results.details.title.text}"</strong> (${results.details.title.length} chars)</p>
573
+ <p class="${results.details.title.status === 'good' ? 'status-good' : 'status-bad'}">
574
+ ${results.details.title.status === 'good' ? 'βœ“ Good length (30-60 characters)' :
575
+ results.details.title.status === 'too-long' ? 'βœ— Too long (over 60 characters)' : 'βœ— Too short (under 30 characters)'}
576
+ </p>`
577
+ : '<p class="status-bad">βœ— Missing title tag</p>',
578
+ results.details.metaDescription.exists
579
+ ? `<p>Meta description: <strong>"${results.details.metaDescription.text}"</strong> (${results.details.metaDescription.length} chars)</p>
580
+ <p class="${results.details.metaDescription.status === 'good' ? 'status-good' : 'status-bad'}">
581
+ ${results.details.metaDescription.status === 'good' ? 'βœ“ Good length (70-160 characters)' :
582
+ results.details.metaDescription.status === 'too-long' ? 'βœ— Too long (over 160 characters)' : 'βœ— Too short (under 70 characters)'}
583
+ </p>`
584
+ : '<p class="status-bad">βœ— Missing meta description</p>',
585
+ `<span class="toggle-details">Show/hide details</span>
586
+ <div class="details-content">
587
+ Title: ${results.details.title.exists ? results.details.title.text : 'Not found'}
588
+ \nMeta Description: ${results.details.metaDescription.exists ? results.details.metaDescription.text : 'Not found'}
589
+ </div>`
590
+ ].join('')
591
+ });
592
+
593
+ // Add headings card
594
+ addResultCard({
595
+ title: 'Headings',
596
+ icon: 'fas fa-heading',
597
+ status: results.details.headings.h1.exists && results.details.headings.h2.count >= 2 ? 'good' :
598
+ !results.details.headings.h1.exists ? 'bad' : 'warning',
599
+ content: [
600
+ results.details.headings.h1.exists
601
+ ? `<p>H1: <strong>"${results.details.headings.h1.text}"</strong> (1 found)</p>`
602
+ : '<p class="status-bad">βœ— No H1 heading found</p>',
603
+ `<p>H2: ${results.details.headings.h2.count} found</p>
604
+ <p class="${results.details.headings.h2.count >= 2 ? 'status-good' : 'status-warning'}">
605
+ ${results.details.headings.h2.count >= 2 ? 'βœ“ Good' : '⚠️ Consider adding more (2+ recommended)'}
606
+ </p>`,
607
+ `<span class="toggle-details">Show/hide details</span>
608
+ <div class="details-content">
609
+ H1 Count: ${results.details.headings.h1.exists ? '1' : '0'}
610
+ \nH2 Count: ${results.details.headings.h2.count}
611
+ </div>`
612
+ ].join('')
613
+ });
614
+
615
+ // Add images card
616
+ const imagesPercentage = Math.round((results.details.images.withAlt / results.details.images.count) * 100);
617
+ addResultCard({
618
+ title: 'Images',
619
+ icon: 'fas fa-images',
620
+ status: imagesPercentage >= 90 ? 'good' : imagesPercentage >= 50 ? 'warning' : 'bad',
621
+ content: [
622
+ `<p>Total images: ${results.details.images.count}</p>
623
+ <p>Images with alt text: ${results.details.images.withAlt} (${imagesPercentage}%)</p>
624
+ <p class="${imagesPercentage >= 90 ? 'status-good' : imagesPercentage >= 50 ? 'status-warning' : 'status-bad'}">
625
+ ${imagesPercentage >= 90 ? 'βœ“ Good' : imagesPercentage >= 50 ? '⚠️ Could be better' : 'βœ— Needs improvement'}
626
+ </p>`,
627
+ `<span class="toggle-details">Show/hide details</span>
628
+ <div class="details-content">
629
+ Total Images: ${results.details.images.count}
630
+ \nImages with Alt Text: ${results.details.images.withAlt}
631
+ </div>`
632
+ ].join('')
633
+ });
634
+
635
+ // Add links card
636
+ addResultCard({
637
+ title: 'Links',
638
+ icon: 'fas fa-link',
639
+ status: results.details.links.internal >= 5 ? 'good' : results.details.links.internal >= 2 ? 'warning' : 'bad',
640
+ content: [
641
+ `<p>Total links: ${results.details.links.count}</p>
642
+ <p>Internal links: ${results.details.links.internal}</p>
643
+ <p>External links: ${results.details.links.external}</p>
644
+ <p class="${results.details.links.internal >= 5 ? 'status-good' : results.details.links.internal >= 2 ? 'status-warning' : 'status-bad'}">
645
+ ${results.details.links.internal >= 5 ? 'βœ“ Good internal linking' :
646
+ results.details.links.internal >= 2 ? '⚠️ Could use more internal links' : 'βœ— Needs more internal links'}
647
+ </p>`,
648
+ `<span class="toggle-details">Show/hide details</span>
649
+ <div class="details-content">
650
+ Total Links: ${results.details.links.count}
651
+ \nInternal Links: ${results.details.links.internal}
652
+ \nExternal Links: ${results.details.links.external}
653
+ </div>`
654
+ ].join('')
655
+ });
656
+
657
+ // Add content card
658
+ addResultCard({
659
+ title: 'Content',
660
+ icon: 'fas fa-align-left',
661
+ status: results.details.content.wordCount >= 500 ? 'good' : results.details.content.wordCount >= 300 ? 'warning' : 'bad',
662
+ content: [
663
+ `<p>Word count: ${results.details.content.wordCount}</p>
664
+ <p class="${results.details.content.wordCount >= 500 ? 'status-good' :
665
+ results.details.content.wordCount >= 300 ? 'status-warning' : 'status-bad'}">
666
+ ${results.details.content.wordCount >= 500 ? 'βœ“ Good length' :
667
+ results.details.content.wordCount >= 300 ? '⚠️ Could be longer' : 'βœ— Too short (consider expanding)'}
668
+ </p>`
669
+ ].join('')
670
+ });
671
+
672
+ // Add keywords card only if keywords were provided
673
+ if (results.targetKeywords.length > 0) {
674
+ const keywordList = Object.entries(results.details.keywordDensity)
675
+ .map(([keyword, density]) =>
676
+ `<li>${keyword}: <strong>${density}%</strong> ${density >= 1 && density <= 2 ? 'βœ“' : '⚠️'}</li>`
677
+ ).join('');
678
+
679
+ addResultCard({
680
+ title: 'Keyword Density',
681
+ icon: 'fas fa-key',
682
+ status: 'good',
683
+ content: [
684
+ `<p>Target keywords analyzed:</p>
685
+ <ul class="keyword-density-list">${keywordList}</ul>
686
+ <p><small>Note: Ideal keyword density is typically 1-2% for each keyword.</small></p>`
687
+ ].join('')
688
+ });
689
+ }
690
+
691
+ // Add recommendations card
692
+ const recommendations = [];
693
+
694
+ if (!results.details.title.exists) {
695
+ recommendations.push('<li><i class="fas fa-exclamation-circle issue-icon"></i> Add a title tag</li>');
696
+ } else if (results.details.title.status !== 'good') {
697
+ recommendations.push(`<li><i class="fas fa-exclamation-circle issue-icon"></i> Optimize title length (${results.details.title.status.replace('-', ' ')})</li>`);
698
+ }
699
+
700
+ if (!results.details.metaDescription.exists) {
701
+ recommendations.push('<li><i class="fas fa-exclamation-circle issue-icon"></i> Add a meta description</li>');
702
+ } else if (results.details.metaDescription.status !== 'good') {
703
+ recommendations.push(`<li><i class="fas fa-exclamation-circle issue-icon"></i> Optimize meta description length (${results.details.metaDescription.status.replace('-', ' ')})</li>`);
704
+ }
705
+
706
+ if (!results.details.headings.h1.exists) {
707
+ recommendations.push('<li><i class="fas fa-exclamation-circle issue-icon"></i> Add a H1 heading</li>');
708
+ }
709
+
710
+ if (results.details.headings.h2.count < 2) {
711
+ recommendations.push('<li><i class="fas fa-exclamation-circle issue-icon"></i> Consider adding more H2 headings</li>');
712
+ }
713
+
714
+ if (Math.round((results.details.images.withAlt / results.details.images.count) * 100) < 90) {
715
+ recommendations.push('<li><i class="fas fa-exclamation-circle issue-icon"></i> Add alt text to more images</li>');
716
+ }
717
+
718
+ if (results.details.links.internal < 5) {
719
+ recommendations.push('<li><i class="fas fa-exclamation-circle issue-icon"></i> Add more internal links</li>');
720
+ }
721
+
722
+ if (results.details.content.wordCount < 500) {
723
+ recommendations.push('<li><i class="fas fa-exclamation-circle issue-icon"></i> Consider expanding your content</li>');
724
+ }
725
+
726
+ if (results.targetKeywords.length > 0) {
727
+ Object.entries(results.details.keywordDensity).forEach(([keyword, density]) => {
728
+ if (density < 1 || density > 2) {
729
+ recommendations.push(`<li><i class="fas fa-exclamation-circle issue-icon"></i> Adjust keyword density for "${keyword}" (${density}%)</li>`);
730
+ }
731
+ });
732
+ }
733
+
734
+ if (recommendations.length === 0) {
735
+ recommendations.push('<li><i class="fas fa-check-circle" style="color: var(--success-color)"></i> No major issues detected!</li>');
736
+ }
737
+
738
+ addResultCard({
739
+ title: 'Recommendations',
740
+ icon: 'fas fa-lightbulb',
741
+ status: recommendations.length > 1 ? 'warning' : 'good',
742
+ width: 'full',
743
+ content: [
744
+ `<ul class="issues-list">${recommendations.join('')}</ul>`
745
+ ].join('')
746
+ });
747
+ }
748
+
749
+ // Helper function to add a result card
750
+ function addResultCard(card) {
751
+ const cardElement = document.createElement('div');
752
+ cardElement.className = 'result-card';
753
+ if (card.width === 'full') {
754
+ cardElement.style.gridColumn = '1 / -1';
755
+ }
756
+
757
+ const statusText = card.status === 'good' ? 'Good' : card.status === 'warning' ? 'Needs Work' : 'Poor';
758
+ const statusClass = card.status === 'good' ? 'status-good' : card.status === 'warning' ? 'status-warning' : 'status-bad';
759
+
760
+ cardElement.innerHTML = `
761
+ <div class="card-header">
762
+ <h3 class="card-title">
763
+ <i class="${card.icon} card-icon"></i> ${card.title}
764
+ </h3>
765
+ <span class="card-status ${statusClass}">${statusText}</span>
766
+ </div>
767
+ <div class="result-details">
768
+ ${card.content}
769
+ </div>
770
+ `;
771
+
772
+ resultsContent.appendChild(cardElement);
773
+ }
774
+
775
+ // Clear inputs function
776
+ function clearInputs() {
777
+ urlInput.value = '';
778
+ htmlInput.value = '';
779
+ keywordsInput.value = '';
780
+ resultsSection.style.display = 'none';
781
+ }
782
+ });
783
+ </script>
784
+ <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 <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
785
+ </html>