kklljj commited on
Commit
5acdab1
·
verified ·
1 Parent(s): 0cd8702

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +306 -66
index.html CHANGED
@@ -3,10 +3,20 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>代码文件夹查看器</title>
7
  <style>
8
- body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; background: #f9f9f9; color: #333; }
9
- h1 { text-align: center; color: #2c3e50; }
 
 
 
 
 
 
 
 
 
 
10
  .drop-zone {
11
  border: 3px dashed #3498db;
12
  border-radius: 10px;
@@ -18,52 +28,164 @@
18
  cursor: pointer;
19
  }
20
  .drop-zone:hover, .drop-zone.dragover { background: #eaf6ff; border-color: #2980b9; }
21
- .drop-zone p { margin: 0; font-size: 18px; color: #7f8c8d; }
 
22
  .btn {
23
  display: inline-block;
24
- margin-top: 10px;
25
- padding: 10px 20px;
26
  background: #3498db;
27
  color: white;
28
  border: none;
29
  border-radius: 5px;
30
  cursor: pointer;
31
  font-size: 16px;
 
32
  }
33
  .btn:hover { background: #2980b9; }
 
 
 
 
 
34
  #file-input { display: none; }
35
 
36
- .code-container { background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
37
- .file-block { margin-bottom: 30px; border-bottom: 1px solid #eee; padding-bottom: 20px; }
38
- .file-path { font-family: monospace; background: #eee; padding: 5px 10px; border-radius: 4px; color: #d35400; font-weight: bold; display: block; margin-bottom: 10px; }
39
- pre { background: #282c34; color: #abb2bf; padding: 15px; border-radius: 5px; overflow-x: auto; max-height: 600px; }
40
- code { font-family: "Consolas", "Monaco", monospace; }
41
- .error { color: red; font-weight: bold; }
42
- .loading { color: #3498db; font-weight: bold; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  </style>
44
  </head>
45
  <body>
46
 
47
- <h1>📂 代码文件夹查看器 (纯前端版)</h1>
 
48
 
49
  <div class="drop-zone" id="drop-zone">
50
- <p>将文件夹拖拽到这里</p>
51
- <p style="font-size: 14px; margin-top: 10px;">或点击按钮选择文件夹</p>
52
  <button class="btn" onclick="document.getElementById('file-input').click()">选择文件夹</button>
53
- <!-- webkitdirectory 允许选择文件夹 -->
54
  <input type="file" id="file-input" webkitdirectory multiple>
55
  </div>
56
 
57
- <div id="status" style="text-align: center; margin-bottom: 20px;"></div>
 
 
 
 
 
 
 
58
  <div class="code-container" id="output"></div>
 
 
59
 
60
  <script>
61
  const dropZone = document.getElementById('drop-zone');
62
  const fileInput = document.getElementById('file-input');
63
  const output = document.getElementById('output');
64
  const status = document.getElementById('status');
 
 
 
 
 
65
 
66
- // 防止默认行为
67
  ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
68
  dropZone.addEventListener(eventName, preventDefaults, false);
69
  });
@@ -73,7 +195,6 @@
73
  e.stopPropagation();
74
  }
75
 
76
- // 高亮效果
77
  ['dragenter', 'dragover'].forEach(eventName => {
78
  dropZone.addEventListener(eventName, () => dropZone.classList.add('dragover'), false);
79
  });
@@ -81,17 +202,14 @@
81
  dropZone.addEventListener(eventName, () => dropZone.classList.remove('dragover'), false);
82
  });
83
 
84
- // 处理 dropping
85
  dropZone.addEventListener('drop', handleDrop, false);
86
- // 处理 input 选择
87
  fileInput.addEventListener('change', handleFiles, false);
88
 
89
  function handleDrop(e) {
90
  const dt = e.dataTransfer;
91
  const items = dt.items;
92
 
93
- if (items && items.length > 0) {
94
- // 尝试通过 webkitGetAsEntry 获取文件夹结构
95
  let entries = [];
96
  for (let i = 0; i < items.length; i++) {
97
  if (items[i].webkitGetAsEntry) {
@@ -103,8 +221,7 @@
103
  return;
104
  }
105
  }
106
- // fallback 到 files
107
- handleFiles(e);
108
  }
109
 
110
  function handleFiles(e) {
@@ -112,102 +229,225 @@
112
  processFiles(files);
113
  }
114
 
115
- // 处理 Entry (文件夹结构)
116
  function processEntries(entries) {
117
- output.innerHTML = '';
118
- status.innerHTML = '<span class="loading">正在读取文件夹结构...</span>';
119
- let fileData = [];
120
 
121
  function readEntry(entry, path) {
122
  if (entry.isFile) {
123
  entry.file(function(file) {
124
- fileData.push({ file: file, path: path + file.name });
125
  checkComplete();
126
  });
127
  } else if (entry.isDirectory) {
128
  let dirReader = entry.createReader();
129
- dirReader.readEntries(function(entries) {
130
- if (entries.length > 0) {
131
- entries.forEach(e => readEntry(e, path + entry.name + '/'));
132
- // 注意:readEntries 可能需要多次调用才能读完所有文件,简单起见这里假设一次读完
133
- // 对于深层目录可能需要递归调用 readEntries,此处简化处理
134
- checkComplete();
135
- } else {
136
- checkComplete();
137
  }
 
138
  });
 
 
139
  }
140
  }
141
 
142
- let pending = entries.length;
143
  function checkComplete() {
144
  pending--;
145
  if (pending <= 0) {
146
- // 稍微延迟以确保所有文件都推入数组
147
- setTimeout(() => renderFiles(fileData), 100);
 
 
148
  }
149
  }
150
 
151
  entries.forEach(e => readEntry(e, ''));
152
  }
153
 
154
- // 处理 Files (当文件夹 API 不可用时)
155
  function processFiles(files) {
156
- output.innerHTML = '';
157
- status.innerHTML = '<span class="loading">正在处理 ' + files.length + ' 个文件...</span>';
158
- let fileData = [];
159
  for (let i = 0; i < files.length; i++) {
160
- // 利用 webkitRelativePath 获取路径
161
  let path = files[i].webkitRelativePath || files[i].name;
162
- fileData.push({ file: files[i], path: path });
163
  }
164
- renderFiles(fileData);
 
 
 
 
 
 
 
165
  }
166
 
167
  function renderFiles(fileData) {
168
  output.innerHTML = '';
169
- status.innerHTML = '';
170
 
171
- if (fileData.length === 0) {
172
- status.innerHTML = '<span class="error">未检测到文件</span>';
 
173
  return;
174
  }
175
 
176
- // 排序
177
- fileData.sort((a, b) => a.path.localeCompare(b.path));
178
-
179
- fileData.forEach(item => {
180
- if (isBinary(item.path)) {
181
- // 跳过二进制文件
182
- return;
183
- }
184
 
 
185
  const reader = new FileReader();
186
  reader.onload = function(e) {
187
  const content = e.target.result;
188
  const block = document.createElement('div');
189
  block.className = 'file-block';
190
 
 
 
 
191
  const pathLabel = document.createElement('span');
192
  pathLabel.className = 'file-path';
193
- pathLabel.textContent = '📄 路径:' + item.path;
 
 
 
 
 
 
 
 
194
 
195
  const pre = document.createElement('pre');
196
  const code = document.createElement('code');
197
  code.textContent = content;
198
-
199
  pre.appendChild(code);
200
- block.appendChild(pathLabel);
 
201
  block.appendChild(pre);
202
  output.appendChild(block);
203
  };
 
 
 
204
  reader.readAsText(item.file);
205
  });
206
  }
207
 
208
- function isBinary(filename) {
209
- const binaryExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.ico', '.pdf', '.zip', '.exe', '.dll', '.so', '.dylib', '.woff', '.woff2', '.ttf', '.eot'];
210
- return binaryExtensions.some(ext => filename.toLowerCase().endsWith(ext));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  }
212
  </script>
213
  </body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>代码文件夹查看器 - 一键复制</title>
7
  <style>
8
+ * { box-sizing: border-box; }
9
+ body {
10
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
11
+ max-width: 1200px;
12
+ margin: 0 auto;
13
+ padding: 20px;
14
+ background: #f9f9f9;
15
+ color: #333;
16
+ }
17
+ h1 { text-align: center; color: #2c3e50; margin-bottom: 10px; }
18
+ .subtitle { text-align: center; color: #7f8c8d; margin-bottom: 30px; }
19
+
20
  .drop-zone {
21
  border: 3px dashed #3498db;
22
  border-radius: 10px;
 
28
  cursor: pointer;
29
  }
30
  .drop-zone:hover, .drop-zone.dragover { background: #eaf6ff; border-color: #2980b9; }
31
+ .drop-zone p { margin: 5px 0; font-size: 16px; color: #7f8c8d; }
32
+
33
  .btn {
34
  display: inline-block;
35
+ margin: 10px 5px;
36
+ padding: 12px 24px;
37
  background: #3498db;
38
  color: white;
39
  border: none;
40
  border-radius: 5px;
41
  cursor: pointer;
42
  font-size: 16px;
43
+ transition: background 0.3s;
44
  }
45
  .btn:hover { background: #2980b9; }
46
+ .btn-success { background: #27ae60; }
47
+ .btn-success:hover { background: #219a52; }
48
+ .btn-copy { background: #e67e22; }
49
+ .btn-copy:hover { background: #d35400; }
50
+
51
  #file-input { display: none; }
52
 
53
+ .action-bar {
54
+ text-align: center;
55
+ margin: 20px 0;
56
+ padding: 15px;
57
+ background: #fff;
58
+ border-radius: 8px;
59
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
60
+ display: none;
61
+ }
62
+
63
+ .code-container {
64
+ background: #fff;
65
+ padding: 20px;
66
+ border-radius: 8px;
67
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
68
+ }
69
+
70
+ .file-block {
71
+ margin-bottom: 30px;
72
+ border: 1px solid #eee;
73
+ border-radius: 5px;
74
+ overflow: hidden;
75
+ }
76
+
77
+ .file-header {
78
+ background: #f5f5f5;
79
+ padding: 10px 15px;
80
+ display: flex;
81
+ justify-content: space-between;
82
+ align-items: center;
83
+ border-bottom: 1px solid #eee;
84
+ }
85
+
86
+ .file-path {
87
+ font-family: monospace;
88
+ color: #d35400;
89
+ font-weight: bold;
90
+ font-size: 14px;
91
+ }
92
+
93
+ .copy-btn-small {
94
+ padding: 5px 12px;
95
+ font-size: 12px;
96
+ background: #3498db;
97
+ color: white;
98
+ border: none;
99
+ border-radius: 3px;
100
+ cursor: pointer;
101
+ }
102
+ .copy-btn-small:hover { background: #2980b9; }
103
+
104
+ pre {
105
+ background: #282c34;
106
+ color: #abb2bf;
107
+ padding: 15px;
108
+ margin: 0;
109
+ overflow-x: auto;
110
+ max-height: 500px;
111
+ white-space: pre-wrap;
112
+ word-wrap: break-word;
113
+ }
114
+ code { font-family: "Consolas", "Monaco", monospace; font-size: 13px; }
115
+
116
+ .status {
117
+ text-align: center;
118
+ margin: 15px 0;
119
+ padding: 10px;
120
+ border-radius: 5px;
121
+ }
122
+ .status.loading { color: #3498db; background: #eaf6ff; }
123
+ .status.success { color: #27ae60; background: #e8f8f0; }
124
+ .status.error { color: #e74c3c; background: #fdedec; }
125
+
126
+ .file-count {
127
+ text-align: center;
128
+ margin: 10px 0;
129
+ color: #7f8c8d;
130
+ }
131
+
132
+ #toast {
133
+ position: fixed;
134
+ top: 20px;
135
+ left: 50%;
136
+ transform: translateX(-50%);
137
+ background: #27ae60;
138
+ color: white;
139
+ padding: 15px 30px;
140
+ border-radius: 5px;
141
+ box-shadow: 0 4px 15px rgba(0,0,0,0.2);
142
+ z-index: 1000;
143
+ display: none;
144
+ animation: slideDown 0.3s ease;
145
+ }
146
+
147
+ @keyframes slideDown {
148
+ from { opacity: 0; transform: translateX(-50%) translateY(-20px); }
149
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
150
+ }
151
  </style>
152
  </head>
153
  <body>
154
 
155
+ <h1>📂 代码文件夹查看器</h1>
156
+ <p class="subtitle">拖入文件夹 → 查看代码 → 一键复制全部</p>
157
 
158
  <div class="drop-zone" id="drop-zone">
159
+ <p style="font-size: 18px; font-weight: bold;">📁 将文件夹拖拽到这里</p>
160
+ <p>或点击下方按钮选择文件夹</p>
161
  <button class="btn" onclick="document.getElementById('file-input').click()">选择文件夹</button>
 
162
  <input type="file" id="file-input" webkitdirectory multiple>
163
  </div>
164
 
165
+ <div id="status" class="status" style="display: none;"></div>
166
+
167
+ <div class="action-bar" id="action-bar">
168
+ <button class="btn btn-copy" onclick="copyAll()">📋 一键复制全部代码</button>
169
+ <button class="btn" onclick="downloadAll()">💾 下载为 TXT 文件</button>
170
+ <p class="file-count" id="file-count"></p>
171
+ </div>
172
+
173
  <div class="code-container" id="output"></div>
174
+
175
+ <div id="toast">✅ 复制成功!</div>
176
 
177
  <script>
178
  const dropZone = document.getElementById('drop-zone');
179
  const fileInput = document.getElementById('file-input');
180
  const output = document.getElementById('output');
181
  const status = document.getElementById('status');
182
+ const actionBar = document.getElementById('action-bar');
183
+ const fileCountEl = document.getElementById('file-count');
184
+ const toast = document.getElementById('toast');
185
+
186
+ let allFileData = [];
187
 
188
+ // 拖拽事件
189
  ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
190
  dropZone.addEventListener(eventName, preventDefaults, false);
191
  });
 
195
  e.stopPropagation();
196
  }
197
 
 
198
  ['dragenter', 'dragover'].forEach(eventName => {
199
  dropZone.addEventListener(eventName, () => dropZone.classList.add('dragover'), false);
200
  });
 
202
  dropZone.addEventListener(eventName, () => dropZone.classList.remove('dragover'), false);
203
  });
204
 
 
205
  dropZone.addEventListener('drop', handleDrop, false);
 
206
  fileInput.addEventListener('change', handleFiles, false);
207
 
208
  function handleDrop(e) {
209
  const dt = e.dataTransfer;
210
  const items = dt.items;
211
 
212
+ if (items && items.length > 0 && items[0].webkitGetAsEntry) {
 
213
  let entries = [];
214
  for (let i = 0; i < items.length; i++) {
215
  if (items[i].webkitGetAsEntry) {
 
221
  return;
222
  }
223
  }
224
+ handleFiles(e);
 
225
  }
226
 
227
  function handleFiles(e) {
 
229
  processFiles(files);
230
  }
231
 
 
232
  function processEntries(entries) {
233
+ showStatus('正在读取文件夹结构...', 'loading');
234
+ allFileData = [];
235
+ let pending = entries.length;
236
 
237
  function readEntry(entry, path) {
238
  if (entry.isFile) {
239
  entry.file(function(file) {
240
+ allFileData.push({ file: file, path: path + file.name });
241
  checkComplete();
242
  });
243
  } else if (entry.isDirectory) {
244
  let dirReader = entry.createReader();
245
+ dirReader.readEntries(function(subEntries) {
246
+ if (subEntries.length > 0) {
247
+ subEntries.forEach(e => readEntry(e, path + entry.name + '/'));
 
 
 
 
 
248
  }
249
+ checkComplete();
250
  });
251
+ } else {
252
+ checkComplete();
253
  }
254
  }
255
 
 
256
  function checkComplete() {
257
  pending--;
258
  if (pending <= 0) {
259
+ setTimeout(() => {
260
+ allFileData.sort((a, b) => a.path.localeCompare(b.path));
261
+ renderFiles(allFileData);
262
+ }, 200);
263
  }
264
  }
265
 
266
  entries.forEach(e => readEntry(e, ''));
267
  }
268
 
 
269
  function processFiles(files) {
270
+ showStatus(`正在处理 ${files.length} 个文件...`, 'loading');
271
+ allFileData = [];
272
+
273
  for (let i = 0; i < files.length; i++) {
 
274
  let path = files[i].webkitRelativePath || files[i].name;
275
+ allFileData.push({ file: files[i], path: path });
276
  }
277
+
278
+ allFileData.sort((a, b) => a.path.localeCompare(b.path));
279
+ renderFiles(allFileData);
280
+ }
281
+
282
+ function isBinary(filename) {
283
+ const binaryExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.ico', '.pdf', '.zip', '.exe', '.dll', '.so', '.dylib', '.woff', '.woff2', '.ttf', '.eot', '.svg', '.mp3', '.mp4', '.avi', '.mov'];
284
+ return binaryExtensions.some(ext => filename.toLowerCase().endsWith(ext));
285
  }
286
 
287
  function renderFiles(fileData) {
288
  output.innerHTML = '';
289
+ allFileData = fileData.filter(item => !isBinary(item.path));
290
 
291
+ if (allFileData.length === 0) {
292
+ showStatus(' 未检测到可读取的代码文件(已过滤图片和二进制文件)', 'error');
293
+ actionBar.style.display = 'none';
294
  return;
295
  }
296
 
297
+ showStatus(`✅ 共找到 ${allFileData.length} 个代码文件`, 'success');
298
+ fileCountEl.textContent = `已加载 ${allFileData.length} 个文件`;
299
+ actionBar.style.display = 'block';
 
 
 
 
 
300
 
301
+ allFileData.forEach((item, index) => {
302
  const reader = new FileReader();
303
  reader.onload = function(e) {
304
  const content = e.target.result;
305
  const block = document.createElement('div');
306
  block.className = 'file-block';
307
 
308
+ const header = document.createElement('div');
309
+ header.className = 'file-header';
310
+
311
  const pathLabel = document.createElement('span');
312
  pathLabel.className = 'file-path';
313
+ pathLabel.textContent = '📄 ' + item.path;
314
+
315
+ const copyBtn = document.createElement('button');
316
+ copyBtn.className = 'copy-btn-small';
317
+ copyBtn.textContent = '📋 复制此文件';
318
+ copyBtn.onclick = () => copySingle(content, item.path);
319
+
320
+ header.appendChild(pathLabel);
321
+ header.appendChild(copyBtn);
322
 
323
  const pre = document.createElement('pre');
324
  const code = document.createElement('code');
325
  code.textContent = content;
 
326
  pre.appendChild(code);
327
+
328
+ block.appendChild(header);
329
  block.appendChild(pre);
330
  output.appendChild(block);
331
  };
332
+ reader.onerror = function() {
333
+ showStatus(`❌ 读取失败:${item.path}`, 'error');
334
+ };
335
  reader.readAsText(item.file);
336
  });
337
  }
338
 
339
+ function showStatus(msg, type) {
340
+ status.textContent = msg;
341
+ status.className = 'status ' + type;
342
+ status.style.display = 'block';
343
+ }
344
+
345
+ function showToast(msg) {
346
+ toast.textContent = msg;
347
+ toast.style.display = 'block';
348
+ setTimeout(() => { toast.style.display = 'none'; }, 2000);
349
+ }
350
+
351
+ function copySingle(content, path) {
352
+ const text = `文件路径:${path}\n\n${content}`;
353
+ navigator.clipboard.writeText(text).then(() => {
354
+ showToast('✅ 单个文件已复制!');
355
+ }).catch(() => {
356
+ showToast('❌ 复制失败');
357
+ });
358
+ }
359
+
360
+ function copyAll() {
361
+ if (allFileData.length === 0) {
362
+ showToast('❌ 没有可复制的内容');
363
+ return;
364
+ }
365
+
366
+ showStatus('🔄 正在准备复制...', 'loading');
367
+
368
+ let fullText = '';
369
+ let processedCount = 0;
370
+
371
+ function processFile(index) {
372
+ if (index >= allFileData.length) {
373
+ navigator.clipboard.writeText(fullText).then(() => {
374
+ showStatus(`✅ 已复制全部 ${allFileData.length} 个文件!`, 'success');
375
+ showToast('✅ 全部代码已复制到剪贴板!');
376
+ }).catch(() => {
377
+ showStatus('❌ 复制失败,请手动选择复制', 'error');
378
+ showToast('❌ 复制失败');
379
+ });
380
+ return;
381
+ }
382
+
383
+ const item = allFileData[index];
384
+ const reader = new FileReader();
385
+ reader.onload = function(e) {
386
+ fullText += `════════════════════════════════════════\n`;
387
+ fullText += `文件路径:${item.path}\n`;
388
+ fullText += `════════════════════════════════════════\n\n`;
389
+ fullText += `${e.target.result}\n\n\n`;
390
+ processedCount++;
391
+ showStatus(`🔄 正在准备复制... (${processedCount}/${allFileData.length})`, 'loading');
392
+ processFile(index + 1);
393
+ };
394
+ reader.onerror = function() {
395
+ processedCount++;
396
+ processFile(index + 1);
397
+ };
398
+ reader.readAsText(item.file);
399
+ }
400
+
401
+ processFile(0);
402
+ }
403
+
404
+ function downloadAll() {
405
+ if (allFileData.length === 0) {
406
+ showToast('❌ 没有可下载的内容');
407
+ return;
408
+ }
409
+
410
+ showStatus('🔄 正在生成文件...', 'loading');
411
+
412
+ let fullText = '';
413
+ let processedCount = 0;
414
+
415
+ function processFile(index) {
416
+ if (index >= allFileData.length) {
417
+ const blob = new Blob([fullText], { type: 'text/plain;charset=utf-8' });
418
+ const url = URL.createObjectURL(blob);
419
+ const a = document.createElement('a');
420
+ a.href = url;
421
+ a.download = '全部代码.txt';
422
+ document.body.appendChild(a);
423
+ a.click();
424
+ document.body.removeChild(a);
425
+ URL.revokeObjectURL(url);
426
+
427
+ showStatus(`✅ 已下载全部 ${allFileData.length} 个文件!`, 'success');
428
+ showToast('✅ 文件已下载!');
429
+ return;
430
+ }
431
+
432
+ const item = allFileData[index];
433
+ const reader = new FileReader();
434
+ reader.onload = function(e) {
435
+ fullText += `════════════════════════════════════════\n`;
436
+ fullText += `文件路径:${item.path}\n`;
437
+ fullText += `══════════════���═════════════════════════\n\n`;
438
+ fullText += `${e.target.result}\n\n\n`;
439
+ processedCount++;
440
+ showStatus(`🔄 正在生成文件... (${processedCount}/${allFileData.length})`, 'loading');
441
+ processFile(index + 1);
442
+ };
443
+ reader.onerror = function() {
444
+ processedCount++;
445
+ processFile(index + 1);
446
+ };
447
+ reader.readAsText(item.file);
448
+ }
449
+
450
+ processFile(0);
451
  }
452
  </script>
453
  </body>