|
|
<!DOCTYPE html> |
|
|
<html lang="fa" dir="rtl"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>آلفا QR کد | ساخت و خواندن</title> |
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css"> |
|
|
<style> |
|
|
|
|
|
:root { |
|
|
--app-font: 'Vazirmatn', sans-serif; |
|
|
--app-bg: #F8F9FC; |
|
|
--panel-bg: #FFFFFF; |
|
|
--panel-border: #EAEFF7; |
|
|
--input-bg: #F6F8FB; |
|
|
--input-border: #E1E7EF; |
|
|
--text-primary: #1A202C; |
|
|
--text-secondary: #626F86; |
|
|
--text-tertiary: #8A94A6; |
|
|
--accent-primary: #4A6CFA; |
|
|
--accent-primary-hover: #3553D6; |
|
|
--accent-primary-glow: rgba(74, 108, 250, 0.25); |
|
|
--accent-secondary: #0FD4A8; |
|
|
--accent-secondary-hover: #0DA986; |
|
|
--accent-secondary-glow: rgba(15, 212, 168, 0.2); |
|
|
--shadow-sm: 0 1px 2px 0 rgba(26, 32, 44, 0.03); |
|
|
--shadow-md: 0 4px 6px -1px rgba(26, 32, 44, 0.05), 0 2px 4px -2px rgba(26, 32, 44, 0.04); |
|
|
--shadow-lg: 0 10px 15px -3px rgba(26, 32, 44, 0.06), 0 4px 6px -4px rgba(26, 32, 44, 0.05); |
|
|
--shadow-xl: 0 20px 25px -5px rgba(26, 32, 44, 0.07), 0 8px 10px -6px rgba(26, 32, 44, 0.05); |
|
|
--radius-card: 24px; |
|
|
--radius-btn: 14px; |
|
|
--radius-input: 12px; |
|
|
--transition-smooth: all 0.35s cubic-bezier(0.4, 0, 0.2, 1); |
|
|
} |
|
|
|
|
|
|
|
|
* { |
|
|
margin: 0; |
|
|
padding: 0; |
|
|
box-sizing: border-box; |
|
|
} |
|
|
|
|
|
body { |
|
|
font-family: var(--app-font); |
|
|
background-color: var(--app-bg); |
|
|
color: var(--text-primary); |
|
|
min-height: 100vh; |
|
|
overflow-x: hidden; |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: flex-start; |
|
|
padding: 2.5rem 1rem; |
|
|
background-image: radial-gradient(var(--text-tertiary) 0.5px, transparent 0.5px); |
|
|
background-size: 20px 20px; |
|
|
background-position: -10px -10px; |
|
|
} |
|
|
|
|
|
.container { |
|
|
max-width: 480px; |
|
|
width: 100%; |
|
|
margin: 0 auto; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
} |
|
|
|
|
|
|
|
|
.header { |
|
|
text-align: center; |
|
|
padding: 1rem 0 2rem; |
|
|
} |
|
|
|
|
|
.logo { |
|
|
font-size: 3rem; |
|
|
margin-bottom: 10px; |
|
|
filter: drop-shadow(0 4px 8px rgba(0,0,0,0.1)); |
|
|
} |
|
|
|
|
|
.title { |
|
|
font-size: 2.2rem; |
|
|
font-weight: 900; |
|
|
margin-bottom: 0.8rem; |
|
|
background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary)); |
|
|
-webkit-background-clip: text; |
|
|
-webkit-text-fill-color: transparent; |
|
|
letter-spacing: -1px; |
|
|
} |
|
|
|
|
|
.subtitle { |
|
|
font-size: 1rem; |
|
|
color: var(--text-secondary); |
|
|
opacity: 0.9; |
|
|
} |
|
|
|
|
|
|
|
|
.tabs { |
|
|
display: flex; |
|
|
background: var(--input-bg); |
|
|
border-radius: var(--radius-btn); |
|
|
padding: 6px; |
|
|
margin-bottom: 20px; |
|
|
border: 1px solid var(--panel-border); |
|
|
} |
|
|
|
|
|
.tab { |
|
|
flex: 1; |
|
|
padding: 12px; |
|
|
text-align: center; |
|
|
border-radius: 10px; |
|
|
cursor: pointer; |
|
|
transition: var(--transition-smooth); |
|
|
font-weight: 600; |
|
|
font-size: 0.9rem; |
|
|
color: var(--text-secondary); |
|
|
} |
|
|
|
|
|
.tab.active { |
|
|
background: var(--panel-bg); |
|
|
color: var(--text-primary); |
|
|
transform: translateY(-2px); |
|
|
box-shadow: var(--shadow-lg); |
|
|
} |
|
|
|
|
|
|
|
|
.card { |
|
|
background: var(--panel-bg); |
|
|
border-radius: var(--radius-card); |
|
|
padding: 30px; |
|
|
border: 1px solid var(--panel-border); |
|
|
box-shadow: var(--shadow-xl); |
|
|
flex: 1; |
|
|
display: none; |
|
|
flex-direction: column; |
|
|
} |
|
|
|
|
|
.tab-content.active { |
|
|
display: flex; |
|
|
} |
|
|
|
|
|
.form-group { |
|
|
margin-bottom: 25px; |
|
|
} |
|
|
|
|
|
.label { |
|
|
display: block; |
|
|
margin-bottom: 12px; |
|
|
font-size: 1rem; |
|
|
font-weight: 700; |
|
|
color: var(--text-primary); |
|
|
} |
|
|
|
|
|
|
|
|
.input { |
|
|
width: 100%; |
|
|
padding: 15px; |
|
|
border: 1px solid var(--input-border); |
|
|
border-radius: var(--radius-input); |
|
|
background: var(--input-bg); |
|
|
color: var(--text-primary); |
|
|
font-size: 1rem; |
|
|
font-family: var(--app-font); |
|
|
min-height: 120px; |
|
|
resize: vertical; |
|
|
outline: none; |
|
|
transition: var(--transition-smooth); |
|
|
box-shadow: var(--shadow-sm) inset; |
|
|
} |
|
|
|
|
|
.input:focus { |
|
|
background: var(--panel-bg); |
|
|
border-color: var(--accent-primary); |
|
|
box-shadow: 0 0 0 3px var(--accent-primary-glow), var(--shadow-sm) inset; |
|
|
} |
|
|
|
|
|
.file-upload { |
|
|
position: relative; |
|
|
background: var(--input-bg); |
|
|
border: 2px dashed var(--input-border); |
|
|
border-radius: var(--radius-input); |
|
|
padding: 30px 20px; |
|
|
text-align: center; |
|
|
cursor: pointer; |
|
|
transition: var(--transition-smooth); |
|
|
min-height: 140px; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
} |
|
|
|
|
|
.file-upload.has-preview { |
|
|
padding: 10px; |
|
|
border-style: solid; |
|
|
border-color: var(--accent-primary); |
|
|
} |
|
|
|
|
|
.file-upload:hover, .file-upload.drag-over { |
|
|
background: white; |
|
|
border-color: var(--accent-primary); |
|
|
box-shadow: 0 0 15px var(--accent-primary-glow); |
|
|
transform: translateY(-2px); |
|
|
} |
|
|
|
|
|
.file-upload input { |
|
|
position: absolute; |
|
|
left: -9999px; |
|
|
} |
|
|
|
|
|
.file-upload img { |
|
|
max-width: 100%; |
|
|
max-height: 120px; |
|
|
height: auto; |
|
|
border-radius: 8px; |
|
|
object-fit: contain; |
|
|
} |
|
|
|
|
|
.upload-icon { |
|
|
font-size: 2.5rem; |
|
|
margin-bottom: 10px; |
|
|
color: var(--accent-primary); |
|
|
} |
|
|
|
|
|
.upload-text { |
|
|
color: var(--text-secondary); |
|
|
font-size: 0.9rem; |
|
|
font-weight: 500; |
|
|
} |
|
|
|
|
|
|
|
|
.btn { |
|
|
width: 100%; |
|
|
padding: 16px; |
|
|
border: none; |
|
|
border-radius: var(--radius-btn); |
|
|
font-size: 1.1rem; |
|
|
font-weight: 700; |
|
|
cursor: pointer; |
|
|
margin-top: auto; |
|
|
transition: var(--transition-smooth); |
|
|
background: linear-gradient(95deg, var(--accent-secondary) 0%, var(--accent-primary) 100%); |
|
|
color: white; |
|
|
box-shadow: 0 6px 12px -3px var(--accent-primary-glow), 0 6px 12px -3px var(--accent-secondary-glow); |
|
|
} |
|
|
|
|
|
.btn:hover:not(:disabled) { |
|
|
transform: translateY(-5px) scale(1.02); |
|
|
box-shadow: 0 8px 20px -4px var(--accent-primary-glow), 0 8px 20px -4px var(--accent-secondary-glow); |
|
|
} |
|
|
|
|
|
.btn:disabled { |
|
|
background: var(--text-tertiary); |
|
|
color: var(--text-secondary); |
|
|
cursor: not-allowed; |
|
|
transform: none; |
|
|
box-shadow: none; |
|
|
} |
|
|
|
|
|
.btn:active:not(:disabled) { |
|
|
transform: translateY(0); |
|
|
} |
|
|
|
|
|
|
|
|
.result { |
|
|
flex: 1; |
|
|
background: var(--input-bg); |
|
|
border: 2px dashed var(--input-border); |
|
|
border-radius: var(--radius-card); |
|
|
padding: 20px; |
|
|
min-height: 150px; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
text-align: center; |
|
|
margin-bottom: 25px; |
|
|
box-shadow: var(--shadow-sm) inset; |
|
|
} |
|
|
|
|
|
.result-empty { |
|
|
color: var(--text-secondary); |
|
|
font-style: italic; |
|
|
} |
|
|
|
|
|
.result img { |
|
|
max-width: 100%; |
|
|
height: auto; |
|
|
border-radius: var(--radius-input); |
|
|
background: white; |
|
|
padding: 10px; |
|
|
box-shadow: var(--shadow-lg); |
|
|
animation: zoomIn 0.4s ease; |
|
|
border: 1px solid var(--panel-border); |
|
|
} |
|
|
|
|
|
.result-text-wrapper { |
|
|
width: 100%; |
|
|
background: var(--panel-bg); |
|
|
border: 1px solid var(--panel-border); |
|
|
border-radius: var(--radius-input); |
|
|
padding: 12px 18px; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: space-between; |
|
|
animation: slideUp 0.4s ease; |
|
|
box-shadow: var(--shadow-md); |
|
|
} |
|
|
.result-text { |
|
|
flex-grow: 1; |
|
|
margin-left: 10px; |
|
|
word-break: break-all; |
|
|
line-height: 1.6; |
|
|
text-align: right; |
|
|
color: var(--text-primary); |
|
|
font-weight: 500; |
|
|
} |
|
|
|
|
|
.copy-btn { |
|
|
background: var(--accent-primary); |
|
|
color: white; |
|
|
border: none; |
|
|
border-radius: 8px; |
|
|
padding: 8px 14px; |
|
|
font-family: var(--app-font); |
|
|
font-weight: 600; |
|
|
cursor: pointer; |
|
|
transition: var(--transition-smooth); |
|
|
flex-shrink: 0; |
|
|
font-size: 0.9rem; |
|
|
box-shadow: var(--shadow-sm); |
|
|
} |
|
|
.copy-btn:hover { |
|
|
background: var(--accent-primary-hover); |
|
|
transform: scale(1.05); |
|
|
} |
|
|
.copy-btn.copied { |
|
|
background-color: var(--accent-secondary); |
|
|
transform: scale(1.05); |
|
|
} |
|
|
|
|
|
|
|
|
.loader { |
|
|
width: 40px; |
|
|
height: 40px; |
|
|
border: 4px solid var(--input-border); |
|
|
border-top: 4px solid var(--accent-primary); |
|
|
border-radius: 50%; |
|
|
animation: spin 1s linear infinite; |
|
|
} |
|
|
|
|
|
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } |
|
|
@keyframes zoomIn { from { opacity: 0; transform: scale(0.8); } to { opacity: 1; transform: scale(1); } } |
|
|
@keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } |
|
|
|
|
|
.icon { |
|
|
display: inline-block; |
|
|
margin-left: 8px; |
|
|
vertical-align: middle; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="container"> |
|
|
<div class="header"> |
|
|
<div class="logo">📱</div> |
|
|
<h1 class="title">ساخت Qr Code آلفا</h1> |
|
|
<p class="subtitle">ساخت و خواندن آسان کیوآر کد</p> |
|
|
</div> |
|
|
|
|
|
<div class="tabs"> |
|
|
<div class="tab active" data-tab="generate"><span class="icon">➕</span>ساخت</div> |
|
|
<div class="tab" data-tab="read"><span class="icon">👁️</span>خواندن</div> |
|
|
</div> |
|
|
|
|
|
<div class="card tab-content active" id="generate-content"> |
|
|
<div class="form-group"> |
|
|
<label class="label">متن یا لینک خود را بنویسید:</label> |
|
|
<textarea id="text-input" class="input" placeholder="مثال: https://google.com یا سلام دنیا"></textarea> |
|
|
</div> |
|
|
<div class="result" id="qr-result"> |
|
|
<div id="generate-loader" class="loader" style="display: none;"></div> |
|
|
<div id="qr-display"><span class="result-empty">QR کد شما اینجا ظاهر میشود</span></div> |
|
|
</div> |
|
|
<button id="generate-btn" class="btn"><span class="icon">✨</span>ساخت QR کد</button> |
|
|
</div> |
|
|
|
|
|
<div class="card tab-content" id="read-content"> |
|
|
<div class="form-group"> |
|
|
<label class="label">تصویر QR کد را انتخاب کنید:</label> |
|
|
<div class="file-upload" onclick="document.getElementById('file-input').click()"> |
|
|
<input type="file" id="file-input" accept="image/*"> |
|
|
<div class="upload-content"> |
|
|
<div class="upload-icon">📷</div> |
|
|
<div class="upload-text">انتخاب تصویر</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="result" id="read-result"> |
|
|
<div id="read-loader" class="loader" style="display: none;"></div> |
|
|
<div id="decoded-text"><span class="result-empty">نتیجه اینجا نمایش داده میشود</span></div> |
|
|
</div> |
|
|
<button id="read-btn" class="btn"><span class="icon">🔍</span>خواندن QR کد</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
|
|
|
const SPACE_URL = "https://cultrix-qrcode-read-generate.hf.space"; |
|
|
|
|
|
const tabs = document.querySelectorAll('.tab'); |
|
|
const tabContents = document.querySelectorAll('.tab-content'); |
|
|
const generateBtn = document.getElementById('generate-btn'); |
|
|
const readBtn = document.getElementById('read-btn'); |
|
|
const textInput = document.getElementById('text-input'); |
|
|
const fileInput = document.getElementById('file-input'); |
|
|
const qrDisplay = document.getElementById('qr-display'); |
|
|
const decodedText = document.getElementById('decoded-text'); |
|
|
const generateLoader = document.getElementById('generate-loader'); |
|
|
const readLoader = document.getElementById('read-loader'); |
|
|
const fileUpload = document.querySelector('.file-upload'); |
|
|
const uploadContent = document.querySelector('.upload-content'); |
|
|
|
|
|
function copyToClipboard(button, text) { |
|
|
if (button.classList.contains('copied')) return; |
|
|
|
|
|
navigator.clipboard.writeText(text).then(() => { |
|
|
const originalText = button.innerHTML; |
|
|
button.innerHTML = '✓ کپی شد'; |
|
|
button.classList.add('copied'); |
|
|
button.disabled = true; |
|
|
|
|
|
setTimeout(() => { |
|
|
button.innerHTML = originalText; |
|
|
button.classList.remove('copied'); |
|
|
button.disabled = false; |
|
|
}, 2000); |
|
|
}).catch(err => { |
|
|
console.error('Failed to copy text: ', err); |
|
|
alert('کپی کردن با خطا مواجه شد.'); |
|
|
}); |
|
|
} |
|
|
|
|
|
tabs.forEach(tab => { |
|
|
tab.addEventListener('click', () => { |
|
|
tabs.forEach(t => t.classList.remove('active')); |
|
|
tabContents.forEach(tc => tc.classList.remove('active')); |
|
|
tab.classList.add('active'); |
|
|
document.getElementById(tab.getAttribute('data-tab') + '-content').classList.add('active'); |
|
|
}); |
|
|
}); |
|
|
|
|
|
fileInput.addEventListener('change', () => { |
|
|
const file = fileInput.files[0]; |
|
|
if (file) { |
|
|
if (file.type.startsWith('image/')) { |
|
|
const reader = new FileReader(); |
|
|
reader.onload = function(e) { |
|
|
const previewImage = document.createElement('img'); |
|
|
previewImage.src = e.target.result; |
|
|
uploadContent.style.display = 'none'; |
|
|
if(fileUpload.querySelector('img')) fileUpload.querySelector('img').remove(); |
|
|
fileUpload.appendChild(previewImage); |
|
|
fileUpload.classList.add('has-preview'); |
|
|
} |
|
|
reader.readAsDataURL(file); |
|
|
} else { |
|
|
alert('لطفا یک فایل تصویری انتخاب کنید.'); |
|
|
fileInput.value = ''; |
|
|
} |
|
|
} else { |
|
|
if(fileUpload.querySelector('img')) fileUpload.querySelector('img').remove(); |
|
|
uploadContent.style.display = 'block'; |
|
|
uploadContent.querySelector('.upload-icon').textContent = '📷'; |
|
|
uploadContent.querySelector('.upload-text').textContent = 'انتخاب تصویر'; |
|
|
fileUpload.classList.remove('has-preview'); |
|
|
} |
|
|
}); |
|
|
|
|
|
const generateSessionHash = () => Math.random().toString(36).substring(2, 15); |
|
|
|
|
|
const listenForData = (sessionHash, onResult, onError, onFinally) => { |
|
|
const eventSource = new EventSource(`${SPACE_URL}/gradio_api/queue/data?session_hash=${sessionHash}`); |
|
|
eventSource.onmessage = (event) => { |
|
|
const data = JSON.parse(event.data); |
|
|
if (data.msg === "process_completed") { |
|
|
eventSource.close(); |
|
|
if (data.output.error) onError(data.output.error); |
|
|
else onResult(data.output.data); |
|
|
onFinally(); |
|
|
} else if (data.msg === "process_failed") { |
|
|
eventSource.close(); |
|
|
onError("پردازش با خطا مواجه شد."); |
|
|
onFinally(); |
|
|
} |
|
|
}; |
|
|
eventSource.onerror = (err) => { |
|
|
eventSource.close(); |
|
|
onError("خطا در ارتباط با سرور."); |
|
|
onFinally(); |
|
|
}; |
|
|
}; |
|
|
|
|
|
generateBtn.addEventListener('click', async () => { |
|
|
const text = textInput.value.trim(); |
|
|
if (!text) return alert("لطفاً متنی را وارد کنید."); |
|
|
generateLoader.style.display = 'block'; |
|
|
qrDisplay.innerHTML = ''; |
|
|
generateBtn.disabled = true; |
|
|
try { |
|
|
const sessionHash = generateSessionHash(); |
|
|
const res = await fetch(`${SPACE_URL}/gradio_api/queue/join`, { |
|
|
method: 'POST', |
|
|
headers: { 'Content-Type': 'application/json' }, |
|
|
body: JSON.stringify({ fn_index: 0, data: [text], session_hash: sessionHash }) |
|
|
}); |
|
|
if (!res.ok) throw new Error('خطا در ارسال درخواست'); |
|
|
listenForData(sessionHash, |
|
|
(result) => qrDisplay.innerHTML = (result && result[0]) ? result[0] : '<span class="result-empty">خطا در ساخت</span>', |
|
|
(error) => { alert(`خطا: ${error}`); qrDisplay.innerHTML = '<span class="result-empty">خطا</span>'; }, |
|
|
() => { generateLoader.style.display = 'none'; generateBtn.disabled = false; } |
|
|
); |
|
|
} catch (error) { |
|
|
alert(`خطا: ${error.message}`); |
|
|
qrDisplay.innerHTML = '<span class="result-empty">خطا در ساخت</span>'; |
|
|
generateLoader.style.display = 'none'; |
|
|
generateBtn.disabled = false; |
|
|
} |
|
|
}); |
|
|
|
|
|
readBtn.addEventListener('click', async () => { |
|
|
const file = fileInput.files[0]; |
|
|
if (!file) return alert("لطفاً یک تصویر انتخاب کنید."); |
|
|
if (!file.type.startsWith('image/')) return alert("لطفاً یک فایل تصویری انتخاب کنید."); |
|
|
|
|
|
readLoader.style.display = 'block'; |
|
|
decodedText.innerHTML = ''; |
|
|
readBtn.disabled = true; |
|
|
try { |
|
|
const formData = new FormData(); |
|
|
formData.append('files', file); |
|
|
const uploadRes = await fetch(`${SPACE_URL}/gradio_api/upload`, { method: 'POST', body: formData }); |
|
|
if (!uploadRes.ok) throw new Error('خطا در آپلود فایل'); |
|
|
const [serverFilePath] = await uploadRes.json(); |
|
|
const fileData = { path: serverFilePath, url: `${SPACE_URL}/gradio_api/file=${serverFilePath}`, orig_name: file.name }; |
|
|
|
|
|
const sessionHash = generateSessionHash(); |
|
|
const joinRes = await fetch(`${SPACE_URL}/gradio_api/queue/join`, { |
|
|
method: 'POST', |
|
|
headers: { 'Content-Type': 'application/json' }, |
|
|
body: JSON.stringify({ fn_index: 1, data: [fileData], session_hash: sessionHash }) |
|
|
}); |
|
|
if (!joinRes.ok) throw new Error('خطا در پردازش'); |
|
|
|
|
|
listenForData(sessionHash, |
|
|
(result) => { |
|
|
const textToCopy = result[0]; |
|
|
const escapedText = textToCopy.replace(/'/g, "\\'").replace(/"/g, '"'); |
|
|
decodedText.innerHTML = ` |
|
|
<div class="result-text-wrapper"> |
|
|
<span class="result-text">📝 ${textToCopy}</span> |
|
|
<button class="copy-btn" onclick="copyToClipboard(this, '${escapedText}')">کپی</button> |
|
|
</div>`; |
|
|
}, |
|
|
(error) => { alert(`خطا: ${error}`); decodedText.innerHTML = '<span class="result-empty">خطا در خواندن</span>'; }, |
|
|
() => { readLoader.style.display = 'none'; readBtn.disabled = false; } |
|
|
); |
|
|
} catch (error) { |
|
|
alert(`خطا: ${error.message}`); |
|
|
decodedText.innerHTML = '<span class="result-empty">خطا در پردازش</span>'; |
|
|
readLoader.style.display = 'none'; |
|
|
readBtn.disabled = false; |
|
|
} |
|
|
}); |
|
|
|
|
|
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { |
|
|
fileUpload.addEventListener(eventName, e => { e.preventDefault(); e.stopPropagation(); }); |
|
|
}); |
|
|
['dragenter', 'dragover'].forEach(eventName => { |
|
|
fileUpload.addEventListener(eventName, () => fileUpload.classList.add('drag-over')); |
|
|
}); |
|
|
['dragleave', 'drop'].forEach(eventName => { |
|
|
fileUpload.addEventListener(eventName, () => fileUpload.classList.remove('drag-over')); |
|
|
}); |
|
|
fileUpload.addEventListener('drop', e => { |
|
|
if (e.dataTransfer.files.length > 0) { |
|
|
fileInput.files = e.dataTransfer.files; |
|
|
fileInput.dispatchEvent(new Event('change')); |
|
|
} |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |