bulet123 commited on
Commit
2062ba8
·
verified ·
1 Parent(s): 3c72c54

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +1026 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Scraper 1 1
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: scraper-1-1
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,1026 @@
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>AI Web Scraper with Comparison</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
+ .gradient-bg {
11
+ background: linear-gradient(135deg, #6e8efb, #a777e3);
12
+ }
13
+ .result-container {
14
+ transition: all 0.3s ease;
15
+ }
16
+ .loader {
17
+ border-top-color: #3498db;
18
+ -webkit-animation: spinner 1.5s linear infinite;
19
+ animation: spinner 1.5s linear infinite;
20
+ }
21
+ @-webkit-keyframes spinner {
22
+ 0% { -webkit-transform: rotate(0deg); }
23
+ 100% { -webkit-transform: rotate(360deg); }
24
+ }
25
+ @keyframes spinner {
26
+ 0% { transform: rotate(0deg); }
27
+ 100% { transform: rotate(360deg); }
28
+ }
29
+ .storage-item {
30
+ transition: all 0.2s ease;
31
+ }
32
+ .storage-item:hover {
33
+ transform: translateY(-2px);
34
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
35
+ }
36
+ .compare-highlight {
37
+ background-color: rgba(255, 255, 0, 0.3);
38
+ border-left: 3px solid #f59e0b;
39
+ }
40
+ .compare-content-box {
41
+ position: relative;
42
+ }
43
+ .compare-content-box::after {
44
+ content: "";
45
+ position: absolute;
46
+ bottom: 0;
47
+ left: 0;
48
+ right: 0;
49
+ height: 20px;
50
+ background: linear-gradient(to bottom, rgba(249, 250, 251, 0), rgba(249, 250, 251, 1));
51
+ pointer-events: none;
52
+ }
53
+ </style>
54
+ </head>
55
+ <body class="min-h-screen gradient-bg">
56
+ <div class="container mx-auto px-4 py-12">
57
+ <div class="max-w-6xl mx-auto">
58
+ <!-- Header -->
59
+ <div class="text-center mb-12">
60
+ <h1 class="text-4xl font-bold text-white mb-2">AI Web Scraper Pro</h1>
61
+ <p class="text-xl text-white opacity-80">Extract, analyze and compare website data with AI</p>
62
+ </div>
63
+
64
+ <!-- Tabs -->
65
+ <div class="flex mb-6 bg-white rounded-lg shadow-md overflow-hidden max-w-2xl mx-auto">
66
+ <button id="scrape-tab" class="flex-1 py-3 px-4 font-medium text-center border-b-2 border-purple-600 text-purple-600 focus:outline-none">
67
+ <i class="fas fa-globe mr-2"></i>Scrape
68
+ </button>
69
+ <button id="compare-tab" class="flex-1 py-3 px-4 font-medium text-center text-gray-500 hover:text-gray-700 focus:outline-none">
70
+ <i class="fas fa-exchange-alt mr-2"></i>Compare
71
+ </button>
72
+ <button id="storage-tab" class="flex-1 py-3 px-4 font-medium text-center text-gray-500 hover:text-gray-700 focus:outline-none">
73
+ <i class="fas fa-database mr-2"></i>Storage
74
+ </button>
75
+ </div>
76
+
77
+ <!-- Main Card -->
78
+ <div class="bg-white rounded-xl shadow-2xl overflow-hidden">
79
+ <!-- Scrape Tab Content -->
80
+ <div id="scrape-content" class="tab-content">
81
+ <!-- Input Section -->
82
+ <div class="p-8">
83
+ <div class="mb-6">
84
+ <label for="url" class="block text-gray-700 font-medium mb-2">
85
+ <i class="fas fa-globe mr-2"></i>Website URL
86
+ </label>
87
+ <div class="flex">
88
+ <input type="url" id="url" placeholder="https://example.com"
89
+ class="flex-grow px-4 py-3 border border-gray-300 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-purple-500">
90
+ <button id="scrape-btn" class="bg-purple-600 hover:bg-purple-700 text-white px-6 py-3 rounded-r-lg transition duration-200">
91
+ <i class="fas fa-search mr-2"></i>Scrape
92
+ </button>
93
+ </div>
94
+ </div>
95
+
96
+ <div id="query-section" class="hidden">
97
+ <div class="mb-6">
98
+ <label for="query" class="block text-gray-700 font-medium mb-2">
99
+ <i class="fas fa-robot mr-2"></i>Ask AI About This Website
100
+ </label>
101
+ <div class="flex">
102
+ <input type="text" id="query" placeholder="What products do they sell? How much do they cost?"
103
+ class="flex-grow px-4 py-3 border border-gray-300 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-purple-500">
104
+ <button id="ask-btn" class="bg-purple-600 hover:bg-purple-700 text-white px-6 py-3 rounded-r-lg transition duration-200">
105
+ <i class="fas fa-paper-plane mr-2"></i>Ask
106
+ </button>
107
+ </div>
108
+ </div>
109
+ <div class="flex justify-end mb-4">
110
+ <button id="save-btn" class="text-purple-600 hover:text-purple-800 font-medium">
111
+ <i class="fas fa-save mr-1"></i> Save to Storage
112
+ </button>
113
+ </div>
114
+ </div>
115
+ </div>
116
+
117
+ <!-- Results Section -->
118
+ <div id="results" class="border-t border-gray-200 p-8">
119
+ <div id="initial-state" class="text-center py-12">
120
+ <i class="fas fa-search text-gray-300 text-5xl mb-4"></i>
121
+ <h3 class="text-xl text-gray-500 font-medium">Enter a website URL to begin scraping</h3>
122
+ </div>
123
+
124
+ <div id="loading-state" class="hidden text-center py-12">
125
+ <div class="loader ease-linear rounded-full border-4 border-t-4 border-gray-200 h-12 w-12 mx-auto mb-4"></div>
126
+ <h3 class="text-xl text-gray-700 font-medium">Analyzing website...</h3>
127
+ </div>
128
+
129
+ <div id="scraped-content" class="hidden">
130
+ <div class="flex justify-between items-center mb-6">
131
+ <h3 class="text-xl font-semibold text-gray-800">Scraped Results</h3>
132
+ <span id="website-url" class="text-sm text-gray-500 bg-gray-100 px-3 py-1 rounded-full"></span>
133
+ </div>
134
+
135
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
136
+ <div class="bg-gray-50 p-4 rounded-lg">
137
+ <div class="text-purple-600 mb-2">
138
+ <i class="fas fa-file-alt"></i>
139
+ </div>
140
+ <h4 class="font-medium text-gray-700">Pages Found</h4>
141
+ <p id="page-count" class="text-2xl font-bold text-gray-900">0</p>
142
+ </div>
143
+ <div class="bg-gray-50 p-4 rounded-lg">
144
+ <div class="text-purple-600 mb-2">
145
+ <i class="fas fa-image"></i>
146
+ </div>
147
+ <h4 class="font-medium text-gray-700">Images Found</h4>
148
+ <p id="image-count" class="text-2xl font-bold text-gray-900">0</p>
149
+ </div>
150
+ <div class="bg-gray-50 p-4 rounded-lg">
151
+ <div class="text-purple-600 mb-2">
152
+ <i class="fas fa-link"></i>
153
+ </div>
154
+ <h4 class="font-medium text-gray-700">Links Found</h4>
155
+ <p id="link-count" class="text-2xl font-bold text-gray-900">0</p>
156
+ </div>
157
+ </div>
158
+
159
+ <div class="mb-8">
160
+ <h4 class="font-medium text-gray-700 mb-2">Page Content Preview</h4>
161
+ <div id="content-preview" class="bg-gray-50 p-4 rounded-lg max-h-60 overflow-y-auto text-gray-700">
162
+ <!-- Content will be inserted here -->
163
+ </div>
164
+ </div>
165
+ </div>
166
+
167
+ <div id="ai-response" class="hidden mt-8">
168
+ <div class="flex justify-between items-center mb-4">
169
+ <h3 class="text-xl font-semibold text-gray-800">AI Analysis</h3>
170
+ <span class="text-sm text-purple-600 bg-purple-100 px-3 py-1 rounded-full">
171
+ <i class="fas fa-robot mr-1"></i> AI Response
172
+ </span>
173
+ </div>
174
+ <div class="bg-purple-50 border-l-4 border-purple-500 p-4 rounded-r-lg">
175
+ <div id="ai-response-content" class="text-gray-700">
176
+ <!-- AI response will be inserted here -->
177
+ </div>
178
+ </div>
179
+ </div>
180
+ </div>
181
+ </div>
182
+
183
+ <!-- Compare Tab Content -->
184
+ <div id="compare-content" class="tab-content hidden">
185
+ <div class="p-8">
186
+ <div class="mb-8">
187
+ <h3 class="text-xl font-bold text-gray-800 mb-4"><i class="fas fa-exchange-alt mr-2"></i>Compare Websites</h3>
188
+ <p class="text-gray-600 mb-4">Select two websites from your storage to compare their content.</p>
189
+
190
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
191
+ <div>
192
+ <label class="block text-gray-700 font-medium mb-2">First Website</label>
193
+ <select id="compare-url-1" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500">
194
+ <option value="">Select a website</option>
195
+ </select>
196
+ </div>
197
+ <div>
198
+ <label class="block text-gray-700 font-medium mb-2">Second Website</label>
199
+ <select id="compare-url-2" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500">
200
+ <option value="">Select a website</option>
201
+ </select>
202
+ </div>
203
+ </div>
204
+
205
+ <div class="flex justify-between">
206
+ <button id="compare-btn" class="bg-purple-600 hover:bg-purple-700 text-white px-6 py-3 rounded-lg transition duration-200">
207
+ <i class="fas fa-balance-scale-left mr-2"></i>Compare Websites
208
+ </button>
209
+ <button id="clear-comparison-btn" class="text-gray-500 hover:text-gray-700 font-medium">
210
+ <i class="fas fa-trash-alt mr-1"></i> Clear Comparison
211
+ </button>
212
+ </div>
213
+ </div>
214
+
215
+ <div id="comparison-results" class="hidden">
216
+ <h4 class="text-lg font-semibold text-gray-800 mb-3">Comparison Results</h4>
217
+ <div class="overflow-x-auto">
218
+ <table class="min-w-full bg-white rounded-lg overflow-hidden">
219
+ <thead class="bg-gray-100">
220
+ <tr>
221
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Metric</th>
222
+ <th id="compare-site-1-header" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Site 1</th>
223
+ <th id="compare-site-2-header" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Site 2</th>
224
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Difference</th>
225
+ </tr>
226
+ </thead>
227
+ <tbody class="divide-y divide-gray-200">
228
+ <tr>
229
+ <td class="px-6 py-4 whitespace-nowrap font-medium text-gray-900">Page Count</td>
230
+ <td id="compare-page-count-1" class="px-6 py-4 whitespace-nowrap">0</td>
231
+ <td id="compare-page-count-2" class="px-6 py-4 whitespace-nowrap">0</td>
232
+ <td id="compare-page-diff" class="px-6 py-4 whitespace-nowrap">0</td>
233
+ </tr>
234
+ <tr>
235
+ <td class="px-6 py-4 whitespace-nowrap font-medium text-gray-900">Image Count</td>
236
+ <td id="compare-image-count-1" class="px-6 py-4 whitespace-nowrap">0</td>
237
+ <td id="compare-image-count-2" class="px-6 py-4 whitespace-nowrap">0</td>
238
+ <td id="compare-image-diff" class="px-6 py-4 whitespace-nowrap">0</td>
239
+ </tr>
240
+ <tr>
241
+ <td class="px-6 py-4 whitespace-nowrap font-medium text-gray-900">Link Count</td>
242
+ <td id="compare-link-count-1" class="px-6 py-4 whitespace-nowrap">0</td>
243
+ <td id="compare-link-count-2" class="px-6 py-4 whitespace-nowrap">0</td>
244
+ <td id="compare-link-diff" class="px-6 py-4 whitespace-nowrap">0</td>
245
+ </tr>
246
+ </tbody>
247
+ </table>
248
+ </div>
249
+
250
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mt-8">
251
+ <div class="compare-content-box">
252
+ <h5 id="compare-site-1-title" class="text-md font-semibold mb-2">Site 1 Content</h5>
253
+ <div id="compare-content-1" class="bg-gray-50 p-4 rounded-lg h-64 overflow-y-auto text-gray-700 border-l-2 border-blue-500">
254
+ <!-- Content for site 1 will be inserted here -->
255
+ </div>
256
+ </div>
257
+ <div class="compare-content-box">
258
+ <h5 id="compare-site-2-title" class="text-md font-semibold mb-2">Site 2 Content</h5>
259
+ <div id="compare-content-2" class="bg-gray-50 p-4 rounded-lg h-64 overflow-y-auto text-gray-700 border-l-2 border-green-500">
260
+ <!-- Content for site 2 will be inserted here -->
261
+ </div>
262
+ </div>
263
+ </div>
264
+
265
+ <div class="mt-8">
266
+ <h5 class="text-md font-semibold mb-3">AI Comparison Analysis</h5>
267
+
268
+ <div class="mb-6">
269
+ <label for="comparison-query" class="block text-gray-700 font-medium mb-2">
270
+ <i class="fas fa-question-circle mr-2"></i>Ask a Specific Comparison Question
271
+ </label>
272
+ <div class="flex">
273
+ <input type="text" id="comparison-query" placeholder="Which site has better prices? Which has more detailed product descriptions?"
274
+ class="flex-grow px-4 py-3 border border-gray-300 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-purple-500">
275
+ <button id="ask-comparison-btn" class="bg-purple-600 hover:bg-purple-700 text-white px-6 py-3 rounded-r-lg transition duration-200">
276
+ <i class="fas fa-robot mr-2"></i>Ask
277
+ </button>
278
+ </div>
279
+ <p class="text-xs text-gray-500 mt-1">Example: "Which site has cheaper prices for similar products?" or "Compare the product descriptions quality"</p>
280
+ </div>
281
+
282
+ <div id="ai-comparison-response" class="bg-purple-50 border-l-4 border-purple-500 p-4 rounded-r-lg hidden">
283
+ <div id="ai-comparison-content" class="text-gray-700">
284
+ <!-- AI comparison response will be inserted here -->
285
+ </div>
286
+ </div>
287
+
288
+ <button id="ai-compare-btn" class="mt-4 bg-purple-600 hover:bg-purple-700 text-white px-6 py-2 rounded-lg transition duration-200">
289
+ <i class="fas fa-balance-scale mr-2"></i>Get Standard AI Comparison Summary
290
+ </button>
291
+ </div>
292
+ </div>
293
+ </div>
294
+ </div>
295
+
296
+ <!-- Storage Tab Content -->
297
+ <div id="storage-content" class="tab-content hidden">
298
+ <div class="p-8">
299
+ <div class="mb-8">
300
+ <h3 class="text-xl font-bold text-gray-800 mb-4"><i class="fas fa-database mr-2"></i>Saved Websites</h3>
301
+
302
+ <div class="relative">
303
+ <input type="text" id="storage-search" placeholder="Search saved websites..."
304
+ class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 pl-10">
305
+ <i class="fas fa-search absolute left-3 top-4 text-gray-400"></i>
306
+ </div>
307
+ </div>
308
+
309
+ <div id="storage-list" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
310
+ <!-- Saved items will be inserted here -->
311
+ </div>
312
+
313
+ <div id="empty-storage" class="text-center py-12">
314
+ <i class="fas fa-database text-gray-300 text-5xl mb-4"></i>
315
+ <h3 class="text-xl text-gray-500 font-medium">No websites saved yet</h3>
316
+ <p class="text-gray-400 mt-2">Save websites from the Scrape tab to view them here</p>
317
+ </div>
318
+ </div>
319
+ </div>
320
+ </div>
321
+
322
+ <!-- Footer -->
323
+ <div class="text-center mt-8 text-white opacity-70 text-sm">
324
+ <p>AI Web Scraper Pro - Extract, analyze and compare website data with artificial intelligence</p>
325
+ </div>
326
+ </div>
327
+ </div>
328
+
329
+ <script>
330
+ document.addEventListener('DOMContentLoaded', function() {
331
+ // DOM Elements
332
+ const scrapeBtn = document.getElementById('scrape-btn');
333
+ const askBtn = document.getElementById('ask-btn');
334
+ const saveBtn = document.getElementById('save-btn');
335
+ const urlInput = document.getElementById('url');
336
+ const queryInput = document.getElementById('query');
337
+ const initialState = document.getElementById('initial-state');
338
+ const loadingState = document.getElementById('loading-state');
339
+ const scrapedContent = document.getElementById('scraped-content');
340
+ const querySection = document.getElementById('query-section');
341
+ const aiResponse = document.getElementById('ai-response');
342
+ const websiteUrl = document.getElementById('website-url');
343
+ const pageCount = document.getElementById('page-count');
344
+ const imageCount = document.getElementById('image-count');
345
+ const linkCount = document.getElementById('link-count');
346
+ const contentPreview = document.getElementById('content-preview');
347
+ const aiResponseContent = document.getElementById('ai-response-content');
348
+
349
+ // Tab elements
350
+ const scrapeTab = document.getElementById('scrape-tab');
351
+ const compareTab = document.getElementById('compare-tab');
352
+ const storageTab = document.getElementById('storage-tab');
353
+ const scrapeContent = document.getElementById('scrape-content');
354
+ const compareContent = document.getElementById('compare-content');
355
+ const storageContent = document.getElementById('storage-content');
356
+
357
+ // Compare elements
358
+ const compareUrl1 = document.getElementById('compare-url-1');
359
+ const compareUrl2 = document.getElementById('compare-url-2');
360
+ const compareBtn = document.getElementById('compare-btn');
361
+ const clearComparisonBtn = document.getElementById('clear-comparison-btn');
362
+ const comparisonResults = document.getElementById('comparison-results');
363
+ const compareSite1Header = document.getElementById('compare-site-1-header');
364
+ const compareSite2Header = document.getElementById('compare-site-2-header');
365
+ const comparePageCount1 = document.getElementById('compare-page-count-1');
366
+ const comparePageCount2 = document.getElementById('compare-page-count-2');
367
+ const comparePageDiff = document.getElementById('compare-page-diff');
368
+ const compareImageCount1 = document.getElementById('compare-image-count-1');
369
+ const compareImageCount2 = document.getElementById('compare-image-count-2');
370
+ const compareImageDiff = document.getElementById('compare-image-diff');
371
+ const compareLinkCount1 = document.getElementById('compare-link-count-1');
372
+ const compareLinkCount2 = document.getElementById('compare-link-count-2');
373
+ const compareLinkDiff = document.getElementById('compare-link-diff');
374
+ const compareSite1Title = document.getElementById('compare-site-1-title');
375
+ const compareSite2Title = document.getElementById('compare-site-2-title');
376
+ const compareContent1 = document.getElementById('compare-content-1');
377
+ const compareContent2 = document.getElementById('compare-content-2');
378
+ const aiCompareBtn = document.getElementById('ai-compare-btn');
379
+ const aiComparisonResponse = document.getElementById('ai-comparison-response');
380
+ const aiComparisonContent = document.getElementById('ai-comparison-content');
381
+ const comparisonQuery = document.getElementById('comparison-query');
382
+ const askComparisonBtn = document.getElementById('ask-comparison-btn');
383
+
384
+ // Storage elements
385
+ const storageSearch = document.getElementById('storage-search');
386
+ const storageList = document.getElementById('storage-list');
387
+ const emptyStorage = document.getElementById('empty-storage');
388
+
389
+ // Current scraped data
390
+ let currentScrapedData = null;
391
+ let comparedItem1 = null;
392
+ let comparedItem2 = null;
393
+
394
+ // Initialize tabs
395
+ function initTabs() {
396
+ scrapeTab.addEventListener('click', function() {
397
+ showTab('scrape');
398
+ });
399
+
400
+ compareTab.addEventListener('click', function() {
401
+ showTab('compare');
402
+ updateCompareDropdowns();
403
+ });
404
+
405
+ storageTab.addEventListener('click', function() {
406
+ showTab('storage');
407
+ loadStorage();
408
+ });
409
+
410
+ showTab('scrape');
411
+ }
412
+
413
+ function showTab(tabName) {
414
+ // Reset tab styling
415
+ scrapeTab.classList.remove('border-purple-600', 'text-purple-600');
416
+ scrapeTab.classList.add('text-gray-500', 'hover:text-gray-700');
417
+ compareTab.classList.remove('border-purple-600', 'text-purple-600');
418
+ compareTab.classList.add('text-gray-500', 'hover:text-gray-700');
419
+ storageTab.classList.remove('border-purple-600', 'text-purple-600');
420
+ storageTab.classList.add('text-gray-500', 'hover:text-gray-700');
421
+
422
+ // Hide all content
423
+ scrapeContent.classList.add('hidden');
424
+ compareContent.classList.add('hidden');
425
+ storageContent.classList.add('hidden');
426
+
427
+ // Show selected tab
428
+ switch(tabName) {
429
+ case 'scrape':
430
+ scrapeTab.classList.add('border-purple-600', 'text-purple-600');
431
+ scrapeTab.classList.remove('text-gray-500', 'hover:text-gray-700');
432
+ scrapeContent.classList.remove('hidden');
433
+ break;
434
+ case 'compare':
435
+ compareTab.classList.add('border-purple-600', 'text-purple-600');
436
+ compareTab.classList.remove('text-gray-500', 'hover:text-gray-700');
437
+ compareContent.classList.remove('hidden');
438
+ break;
439
+ case 'storage':
440
+ storageTab.classList.add('border-purple-600', 'text-purple-600');
441
+ storageTab.classList.remove('text-gray-500', 'hover:text-gray-700');
442
+ storageContent.classList.remove('hidden');
443
+ break;
444
+ }
445
+ }
446
+
447
+ // Mock scraping function (in a real app, this would call a backend service)
448
+ function scrapeWebsite(url) {
449
+ return new Promise((resolve) => {
450
+ // Simulate API call delay
451
+ setTimeout(() => {
452
+ // Mock data
453
+ const mockData = {
454
+ url: url,
455
+ pageCount: Math.floor(Math.random() * 50) + 5,
456
+ imageCount: Math.floor(Math.random() * 100) + 10,
457
+ linkCount: Math.floor(Math.random() * 200) + 20,
458
+ content: `This is a simulated preview of content from ${url}. In a real implementation, this would show actual content scraped from the website. The AI web scraper would analyze the structure and content of the page to extract meaningful information based on your queries.
459
+
460
+ Example content that might be found:
461
+ - Product listings with prices
462
+ - Article text and headings
463
+ - Contact information
464
+ - Navigation structure
465
+ - Metadata and SEO information
466
+
467
+ The AI can then answer questions about this content, summarize it, or extract specific information you're interested in.`,
468
+ timestamp: new Date().toISOString(),
469
+ id: generateId()
470
+ };
471
+ resolve(mockData);
472
+ }, 2000);
473
+ });
474
+ }
475
+
476
+ // Mock AI query function
477
+ function queryAI(url, question) {
478
+ return new Promise((resolve) => {
479
+ // Simulate API call delay
480
+ setTimeout(() => {
481
+ // Mock responses based on question
482
+ let response = "";
483
+ if (question.toLowerCase().includes("product") || question.toLowerCase().includes("sell")) {
484
+ response = `Based on my analysis of ${url}, the website appears to sell various products. While I can't see actual products in this demo, a real implementation would extract product names, descriptions, prices, and other relevant details.`;
485
+ } else if (question.toLowerCase().includes("contact") || question.toLowerCase().includes("address")) {
486
+ response = `The contact information for ${url} would typically be found in the footer or a dedicated 'Contact Us' page. A real implementation would extract phone numbers, email addresses, physical addresses, and contact forms.`;
487
+ } else if (question.toLowerCase().includes("price") || question.toLowerCase().includes("cost")) {
488
+ response = `Price information would be extracted from product pages on ${url}. In this demo, I can't see actual prices, but a real implementation would identify and list all pricing information with currency symbols.`;
489
+ } else if (question.toLowerCase().includes("seo") || question.toLowerCase().includes("optimization")) {
490
+ response = `SEO analysis would examine meta tags, headings, alt attributes, and content structure. For ${url}, this would help determine how well optimized the site is for search engines.`;
491
+ } else {
492
+ response = `I've analyzed ${url} and found it contains various types of content. For more specific information, please ask about particular elements like products, services, contact information, or other details you're interested in.`;
493
+ }
494
+ resolve(response);
495
+ }, 1500);
496
+ });
497
+ }
498
+
499
+ // Mock AI comparison function
500
+ function compareWebsitesAI(url1, url2) {
501
+ return new Promise((resolve) => {
502
+ // Simulate API call delay
503
+ setTimeout(() => {
504
+ const response = `AI comparison analysis between ${url1} and ${url2}:
505
+
506
+ 1. Content Volume: ${url1} appears to have more extensive content based on word count and section diversity.
507
+
508
+ 2. SEO Optimization: Both sites use basic SEO practices, but ${url2} has more comprehensive meta descriptions and alt tags.
509
+
510
+ 3. Navigation Structure: ${url1} has a simpler navigation with clear categories, while ${url2} offers more depth but can be confusing.
511
+
512
+ 4. Visual Elements: ${url2} uses more images and visual content compared to ${url1}.
513
+
514
+ 5. Call-to-Action: ${url1} has more prominent and strategically placed call-to-action buttons.
515
+
516
+ In summary, while both sites serve their purpose, ${url1} might provide a better user experience for quick information access, while ${url2} offers more detailed content for engaged visitors.`;
517
+ resolve(response);
518
+ }, 2000);
519
+ });
520
+ }
521
+
522
+ // Mock specific comparison question function
523
+ function askSpecificComparison(item1, item2, question) {
524
+ return new Promise((resolve) => {
525
+ // Simulate API call delay
526
+ setTimeout(() => {
527
+ let response = "";
528
+
529
+ // Custom responses based on question type
530
+ if (question.toLowerCase().includes("price") || question.toLowerCase().includes("cost")) {
531
+ response = `Comparing prices between ${item1.url} and ${item2.url}:
532
+
533
+ - ${item1.url} generally offers more competitive pricing on similar products
534
+ - ${item2.url} tends to have higher base prices but offers more bundles and discounts
535
+ - The average price difference for comparable items is approximately 15-20% lower on ${item1.url}
536
+ - ${item2.url} provides better value in premium product categories
537
+
538
+ Would you like me to identify specific products with the largest price differences?`;
539
+ }
540
+ else if (question.toLowerCase().includes("description") || question.toLowerCase().includes("detail")) {
541
+ response = `Comparing product descriptions between ${item1.url} and ${item2.url}:
542
+
543
+ 1. Detail Level:
544
+ - ${item2.url} provides 20-30% more detailed product descriptions
545
+ - ${item1.url} focuses on concise, bullet-pointed information
546
+
547
+ 2. Technical Specifications:
548
+ - ${item2.url} includes technical specs for 85% of products
549
+ - ${item1.url} includes them for only 60% of products
550
+
551
+ 3. Media Integration:
552
+ - Both sites include product images
553
+ - ${item2.url} offers more 360° views and demo videos
554
+
555
+ Overall, ${item2.url} provides more comprehensive product information, while ${item1.url} offers a quicker overview.`;
556
+ }
557
+ else if (question.toLowerCase().includes("quality") || question.toLowerCase().includes("information")) {
558
+ response = `Content quality comparison between ${item1.url} and ${item2.url}:
559
+
560
+ - Accuracy: Both sites maintain high factual accuracy (98% vs 95%)
561
+ - Readability: ${item1.url} scores higher on readability metrics (Grade 8 vs Grade 10)
562
+ - Completeness: ${item2.url} covers more aspects per topic
563
+ - Freshness: ${item1.url} updates content more frequently
564
+ - Trust Signals: ${item2.url} has more citations and references
565
+
566
+ For quick information, ${item1.url} is better. For in-depth research, ${item2.url} is superior.`;
567
+ }
568
+ else if (question.toLowerCase().includes("better") || question.toLowerCase().includes("recommend")) {
569
+ const betterSite = Math.random() > 0.5 ? item1.url : item2.url;
570
+ const reason = Math.random() > 0.5 ? "due to its more competitive pricing structure" :
571
+ "because of its more comprehensive product information";
572
+
573
+ response = `Based on your comparison criteria and website analysis, I would recommend ${betterSite} ${reason}.
574
+
575
+ Key factors in this recommendation:
576
+ - ${betterSite} scores higher on ${Math.random() > 0.5 ? "user experience metrics" : "content completeness"}
577
+ - The ${betterSite === item1.url ? item2.url : item1.url} performs better in ${Math.random() > 0.5 ? "visual presentation" : "technical details"} if that's important to you
578
+ - Customer reviews averaged ${Math.floor(Math.random() * 20) + 80}% positive for ${betterSite} versus ${Math.floor(Math.random() * 20) + 70}% for the other`;
579
+ }
580
+ else {
581
+ response = `Comparing ${item1.url} and ${item2.url} based on your question "${question}":
582
+
583
+ - Both sites address this topic, but with different approaches
584
+ - ${item1.url} focuses more on ${Math.random() > 0.5 ? "practical applications" : "theoretical foundations"}
585
+ - ${item2.url} provides ${Math.floor(Math.random() * 5) + 3} specific examples where ${item1.url} offers ${Math.floor(Math.random() * 3) + 1}
586
+ - The depth of coverage is ${Math.random() > 0.5 ? "greater on " + item2.url : "more balanced on " + item1.url}
587
+
588
+ For more specific insights, you might ask about particular aspects like pricing, features, or support options.`;
589
+ }
590
+
591
+ resolve(response);
592
+ }, 2000);
593
+ });
594
+ }
595
+
596
+ // Generate unique ID for saved items
597
+ function generateId() {
598
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
599
+ const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
600
+ return v.toString(16);
601
+ });
602
+ }
603
+
604
+ // Load and save scraped data to localStorage
605
+ function saveToStorage(data) {
606
+ let scrapedData = JSON.parse(localStorage.getItem('scrapedData')) || [];
607
+ const existingIndex = scrapedData.findIndex(item => item.url === data.url);
608
+
609
+ if (existingIndex !== -1) {
610
+ // Update existing entry
611
+ scrapedData[existingIndex] = data;
612
+ } else {
613
+ // Add new entry
614
+ scrapedData.push(data);
615
+ }
616
+
617
+ localStorage.setItem('scrapedData', JSON.stringify(scrapedData));
618
+ return true;
619
+ }
620
+
621
+ function loadStorage() {
622
+ const scrapedData = JSON.parse(localStorage.getItem('scrapedData')) || [];
623
+
624
+ if (scrapedData.length === 0) {
625
+ emptyStorage.classList.remove('hidden');
626
+ storageList.classList.add('hidden');
627
+ return;
628
+ }
629
+
630
+ emptyStorage.classList.add('hidden');
631
+ storageList.classList.remove('hidden');
632
+ storageList.innerHTML = '';
633
+
634
+ // Filter by search term if any
635
+ const searchTerm = storageSearch.value.toLowerCase();
636
+ const filteredData = searchTerm ?
637
+ scrapedData.filter(item =>
638
+ item.url.toLowerCase().includes(searchTerm) ||
639
+ (item.content && item.content.toLowerCase().includes(searchTerm))
640
+ ) : scrapedData;
641
+
642
+ if (filteredData.length === 0) {
643
+ storageList.innerHTML = '<div class="col-span-3 text-center py-8 text-gray-500">No results found matching your search</div>';
644
+ return;
645
+ }
646
+
647
+ filteredData.forEach(item => {
648
+ const storageItem = document.createElement('div');
649
+ storageItem.className = 'storage-item bg-gray-50 rounded-lg p-4 shadow-sm hover:shadow-md cursor-pointer';
650
+ storageItem.innerHTML = `
651
+ <div class="flex justify-between items-start mb-2">
652
+ <h4 class="font-medium text-gray-800 truncate">${item.url}</h4>
653
+ <span class="text-xs text-gray-500">${new Date(item.timestamp).toLocaleDateString()}</span>
654
+ </div>
655
+ <p class="text-sm text-gray-600 mb-3 line-clamp-2">${item.content.substring(0, 150)}...</p>
656
+ <div class="flex justify-between text-xs text-gray-500">
657
+ <span><i class="fas fa-file-alt mr-1"></i> ${item.pageCount} pages</span>
658
+ <span><i class="fas fa-image mr-1"></i> ${item.imageCount} images</span>
659
+ <span><i class="fas fa-link mr-1"></i> ${item.linkCount} links</span>
660
+ </div>
661
+ <div class="flex justify-end mt-3 space-x-2">
662
+ <button class="load-btn text-purple-600 hover:text-purple-800 text-sm" data-id="${item.id}">
663
+ <i class="fas fa-eye mr-1"></i> View
664
+ </button>
665
+ <button class="delete-btn text-red-600 hover:text-red-800 text-sm" data-id="${item.id}">
666
+ <i class="fas fa-trash-alt mr-1"></i> Delete
667
+ </button>
668
+ </div>
669
+ `;
670
+ storageList.appendChild(storageItem);
671
+ });
672
+
673
+ // Add event listeners to buttons
674
+ document.querySelectorAll('.load-btn').forEach(btn => {
675
+ btn.addEventListener('click', function(e) {
676
+ e.stopPropagation();
677
+ const id = this.getAttribute('data-id');
678
+ loadFromStorage(id);
679
+ showTab('scrape');
680
+ });
681
+ });
682
+
683
+ document.querySelectorAll('.delete-btn').forEach(btn => {
684
+ btn.addEventListener('click', function(e) {
685
+ e.stopPropagation();
686
+ const id = this.getAttribute('data-id');
687
+ deleteFromStorage(id);
688
+ });
689
+ });
690
+
691
+ // Add click event to load full item
692
+ document.querySelectorAll('.storage-item').forEach(item => {
693
+ item.addEventListener('click', function() {
694
+ const id = this.querySelector('.load-btn').getAttribute('data-id');
695
+ loadFromStorage(id);
696
+ showTab('scrape');
697
+ });
698
+ });
699
+ }
700
+
701
+ function loadFromStorage(id) {
702
+ const scrapedData = JSON.parse(localStorage.getItem('scrapedData')) || [];
703
+ const item = scrapedData.find(item => item.id === id);
704
+
705
+ if (item) {
706
+ currentScrapedData = item;
707
+
708
+ // Update UI with stored data
709
+ urlInput.value = item.url;
710
+ websiteUrl.textContent = item.url;
711
+ pageCount.textContent = item.pageCount;
712
+ imageCount.textContent = item.imageCount;
713
+ linkCount.textContent = item.linkCount;
714
+ contentPreview.textContent = item.content;
715
+
716
+ // Show results and query section
717
+ initialState.classList.add('hidden');
718
+ loadingState.classList.add('hidden');
719
+ scrapedContent.classList.remove('hidden');
720
+ querySection.classList.remove('hidden');
721
+ aiResponse.classList.add('hidden');
722
+ }
723
+ }
724
+
725
+ function deleteFromStorage(id) {
726
+ if (confirm('Are you sure you want to delete this saved website?')) {
727
+ let scrapedData = JSON.parse(localStorage.getItem('scrapedData')) || [];
728
+ scrapedData = scrapedData.filter(item => item.id !== id);
729
+ localStorage.setItem('scrapedData', JSON.stringify(scrapedData));
730
+ loadStorage();
731
+ }
732
+ }
733
+
734
+ // Update compare dropdowns with saved websites
735
+ function updateCompareDropdowns() {
736
+ const scrapedData = JSON.parse(localStorage.getItem('scrapedData')) || [];
737
+
738
+ compareUrl1.innerHTML = '<option value="">Select a website</option>';
739
+ compareUrl2.innerHTML = '<option value="">Select a website</option>';
740
+
741
+ scrapedData.forEach(item => {
742
+ const option1 = document.createElement('option');
743
+ option1.value = item.id;
744
+ option1.textContent = item.url;
745
+ compareUrl1.appendChild(option1);
746
+
747
+ const option2 = document.createElement('option');
748
+ option2.value = item.id;
749
+ option2.textContent = item.url;
750
+ compareUrl2.appendChild(option2);
751
+ });
752
+ }
753
+
754
+ // Compare two websites
755
+ function compareWebsites() {
756
+ const id1 = compareUrl1.value;
757
+ const id2 = compareUrl2.value;
758
+
759
+ if (!id1 || !id2) {
760
+ alert('Please select two websites to compare');
761
+ return;
762
+ }
763
+
764
+ if (id1 === id2) {
765
+ alert('Please select two different websites to compare');
766
+ return;
767
+ }
768
+
769
+ const scrapedData = JSON.parse(localStorage.getItem('scrapedData')) || [];
770
+ comparedItem1 = scrapedData.find(item => item.id === id1);
771
+ comparedItem2 = scrapedData.find(item => item.id === id2);
772
+
773
+ if (!comparedItem1 || !comparedItem2) {
774
+ alert('Error loading website data. Please try again.');
775
+ return;
776
+ }
777
+
778
+ // Update UI with comparison data
779
+ compareSite1Header.textContent = comparedItem1.url;
780
+ compareSite2Header.textContent = comparedItem2.url;
781
+ compareSite1Title.textContent = comparedItem1.url;
782
+ compareSite2Title.textContent = comparedItem2.url;
783
+
784
+ comparePageCount1.textContent = comparedItem1.pageCount;
785
+ comparePageCount2.textContent = comparedItem2.pageCount;
786
+ comparePageDiff.textContent = Math.abs(comparedItem1.pageCount - comparedItem2.pageCount);
787
+
788
+ compareImageCount1.textContent = comparedItem1.imageCount;
789
+ compareImageCount2.textContent = comparedItem2.imageCount;
790
+ compareImageDiff.textContent = Math.abs(comparedItem1.imageCount - comparedItem2.imageCount);
791
+
792
+ compareLinkCount1.textContent = comparedItem1.linkCount;
793
+ compareLinkCount2.textContent = comparedItem2.linkCount;
794
+ compareLinkDiff.textContent = Math.abs(comparedItem1.linkCount - comparedItem2.linkCount);
795
+
796
+ compareContent1.textContent = comparedItem1.content.substring(0, 500) + (comparedItem1.content.length > 500 ? '...' : '');
797
+ compareContent2.textContent = comparedItem2.content.substring(0, 500) + (comparedItem2.content.length > 500 ? '...' : '');
798
+
799
+ // Highlight differences
800
+ highlightDifferences(comparePageCount1, comparePageCount2, comparePageDiff);
801
+ highlightDifferences(compareImageCount1, compareImageCount2, compareImageDiff);
802
+ highlightDifferences(compareLinkCount1, compareLinkCount2, compareLinkDiff);
803
+
804
+ // Show results
805
+ comparisonResults.classList.remove('hidden');
806
+ aiComparisonResponse.classList.add('hidden');
807
+ }
808
+
809
+ function highlightDifferences(el1, el2, diffEl) {
810
+ const val1 = parseInt(el1.textContent);
811
+ const val2 = parseInt(el2.textContent);
812
+
813
+ if (val1 > val2) {
814
+ el1.classList.add('font-bold', 'text-green-600');
815
+ el2.classList.remove('font-bold', 'text-green-600');
816
+ diffEl.classList.add('font-bold', 'text-green-600');
817
+ } else if (val2 > val1) {
818
+ el2.classList.add('font-bold', 'text-green-600');
819
+ el1.classList.remove('font-bold', 'text-green-600');
820
+ diffEl.classList.add('font-bold', 'text-green-600');
821
+ } else {
822
+ el1.classList.remove('font-bold', 'text-green-600');
823
+ el2.classList.remove('font-bold', 'text-green-600');
824
+ diffEl.classList.remove('font-bold', 'text-green-600');
825
+ }
826
+ }
827
+
828
+ // Clear comparison
829
+ function clearComparison() {
830
+ compareUrl1.value = '';
831
+ compareUrl2.value = '';
832
+ comparisonResults.classList.add('hidden');
833
+ aiComparisonResponse.classList.add('hidden');
834
+ comparedItem1 = null;
835
+ comparedItem2 = null;
836
+ }
837
+
838
+ // Handle specific comparison questions
839
+ function askComparisonQuestion() {
840
+ const question = comparisonQuery.value.trim();
841
+
842
+ if (!question) {
843
+ alert('Please enter a comparison question');
844
+ return;
845
+ }
846
+
847
+ if (!comparedItem1 || !comparedItem2) {
848
+ alert('Please select and compare two websites first');
849
+ return;
850
+ }
851
+
852
+ // Show loading in AI response area
853
+ aiComparisonContent.innerHTML = '<div class="flex items-center"><div class="loader ease-linear rounded-full border-2 border-t-2 border-purple-500 h-4 w-4 mr-2"></div> <span>AI is analyzing your question...</span></div>';
854
+ aiComparisonResponse.classList.remove('hidden');
855
+
856
+ // Simulate API call for specific comparison
857
+ askSpecificComparison(comparedItem1, comparedItem2, question)
858
+ .then(response => {
859
+ aiComparisonContent.innerHTML = response;
860
+ })
861
+ .catch(error => {
862
+ console.error('Comparison error:', error);
863
+ aiComparisonContent.innerHTML = 'Error processing your comparison question. Please try again.';
864
+ });
865
+ }
866
+
867
+ // Initialize event listeners
868
+ function initEventListeners() {
869
+ // Scrape button click handler
870
+ scrapeBtn.addEventListener('click', async function() {
871
+ const url = urlInput.value.trim();
872
+
873
+ if (!url) {
874
+ alert('Please enter a valid URL');
875
+ return;
876
+ }
877
+
878
+ // Show loading state
879
+ initialState.classList.add('hidden');
880
+ loadingState.classList.remove('hidden');
881
+ scrapedContent.classList.add('hidden');
882
+ aiResponse.classList.add('hidden');
883
+
884
+ try {
885
+ // Simulate scraping
886
+ const data = await scrapeWebsite(url);
887
+ currentScrapedData = data;
888
+
889
+ // Update UI with scraped data
890
+ websiteUrl.textContent = data.url;
891
+ pageCount.textContent = data.pageCount;
892
+ imageCount.textContent = data.imageCount;
893
+ linkCount.textContent = data.linkCount;
894
+ contentPreview.textContent = data.content;
895
+
896
+ // Show results
897
+ loadingState.classList.add('hidden');
898
+ scrapedContent.classList.remove('hidden');
899
+ querySection.classList.remove('hidden');
900
+ } catch (error) {
901
+ console.error('Scraping error:', error);
902
+ loadingState.classList.add('hidden');
903
+ initialState.classList.remove('hidden');
904
+ alert('Error scraping website. Please try again.');
905
+ }
906
+ });
907
+
908
+ // Ask button click handler
909
+ askBtn.addEventListener('click', async function() {
910
+ const question = queryInput.value.trim();
911
+ const url = urlInput.value.trim();
912
+
913
+ if (!question) {
914
+ alert('Please enter a question');
915
+ return;
916
+ }
917
+
918
+ if (!url) {
919
+ alert('Please scrape a website first');
920
+ return;
921
+ }
922
+
923
+ // Show loading in AI response area
924
+ aiResponseContent.innerHTML = '<div class="flex items-center"><div class="loader ease-linear rounded-full border-2 border-t-2 border-purple-500 h-4 w-4 mr-2"></div> <span>AI is thinking...</span></div>';
925
+ aiResponse.classList.remove('hidden');
926
+
927
+ try {
928
+ // Simulate AI query
929
+ const response = await queryAI(url, question);
930
+
931
+ // Update UI with AI response
932
+ aiResponseContent.innerHTML = response;
933
+ } catch (error) {
934
+ console.error('AI query error:', error);
935
+ aiResponseContent.innerHTML = 'Error getting AI response. Please try again.';
936
+ }
937
+ });
938
+
939
+ // Save button click handler
940
+ saveBtn.addEventListener('click', function() {
941
+ if (!currentScrapedData) {
942
+ alert('No website data to save. Please scrape a website first.');
943
+ return;
944
+ }
945
+
946
+ const success = saveToStorage(currentScrapedData);
947
+ if (success) {
948
+ alert('Website data saved successfully!');
949
+ } else {
950
+ alert('Error saving website data. Please try again.');
951
+ }
952
+ });
953
+
954
+ // Compare button click handler
955
+ compareBtn.addEventListener('click', compareWebsites);
956
+
957
+ // Clear comparison button click handler
958
+ clearComparisonBtn.addEventListener('click', clearComparison);
959
+
960
+ // AI comparison button click handler
961
+ aiCompareBtn.addEventListener('click', async function() {
962
+ if (!comparedItem1 || !comparedItem2) {
963
+ alert('Please select and compare two websites first');
964
+ return;
965
+ }
966
+
967
+ // Show loading in AI response area
968
+ aiComparisonContent.innerHTML = '<div class="flex items-center"><div class="loader ease-linear rounded-full border-2 border-t-2 border-purple-500 h-4 w-4 mr-2"></div> <span>AI is analyzing the comparison...</span></div>';
969
+ aiComparisonResponse.classList.remove('hidden');
970
+
971
+ try {
972
+ // Simulate AI comparison
973
+ const response = await compareWebsitesAI(comparedItem1.url, comparedItem2.url);
974
+
975
+ // Update UI with AI comparison response
976
+ aiComparisonContent.innerHTML = response;
977
+ } catch (error) {
978
+ console.error('AI comparison error:', error);
979
+ aiComparisonContent.innerHTML = 'Error getting AI comparison. Please try again.';
980
+ }
981
+ });
982
+
983
+ // Ask specific comparison question
984
+ askComparisonBtn.addEventListener('click', askComparisonQuestion);
985
+ comparisonQuery.addEventListener('keypress', function(e) {
986
+ if (e.key === 'Enter') {
987
+ askComparisonQuestion();
988
+ }
989
+ });
990
+
991
+ // Storage search handler
992
+ storageSearch.addEventListener('input', function() {
993
+ loadStorage();
994
+ });
995
+
996
+ // Allow pressing Enter in input fields
997
+ urlInput.addEventListener('keypress', function(e) {
998
+ if (e.key === 'Enter') {
999
+ scrapeBtn.click();
1000
+ }
1001
+ });
1002
+
1003
+ queryInput.addEventListener('keypress', function(e) {
1004
+ if (e.key === 'Enter') {
1005
+ askBtn.click();
1006
+ }
1007
+ });
1008
+
1009
+ storageSearch.addEventListener('keypress', function(e) {
1010
+ if (e.key === 'Enter') {
1011
+ loadStorage();
1012
+ }
1013
+ });
1014
+ }
1015
+
1016
+ // Initialize the app
1017
+ function init() {
1018
+ initTabs();
1019
+ initEventListeners();
1020
+ }
1021
+
1022
+ init();
1023
+ });
1024
+ </script>
1025
+ <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=bulet123/scraper-1-1" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body>
1026
+ </html>