Welcome to WordPress. This is your first post. Edit or delete it, then start writing!
Welcome to WordPress. This is your first post. Edit or delete it, then start writing!
*/ (function() { 'use strict'; // ─── CONFIGURACIÓN ─────────────────────────────────────────────── const CONFIG = { maxWidthHeight: 1280, // px máximo (ancho o alto) quality: 0.78, // calidad JPEG (0-1). 0.78 = buen balance calidad/peso maxSizeKB: 700, // peso máximo por foto en KB minQuality: 0.45, // calidad mínima antes de reducir más la resolución }; // IDs de los campos de archivo del formulario CF7 const FILE_FIELDS = ['fotos', 'fotos1', 'fotos2', 'fotos3', 'fotos4']; // ─── ESTADO VISUAL ─────────────────────────────────────────────── function crearIndicador(input) { const existente = input.parentNode.querySelector('.compress-status'); if (existente) existente.remove(); const div = document.createElement('div'); div.className = 'compress-status'; div.style.cssText = ` font-size: 12px; margin-top: 4px; padding: 4px 8px; border-radius: 4px; display: none; `; input.parentNode.insertBefore(div, input.nextSibling); return div; } function mostrarEstado(div, texto, tipo) { const colores = { procesando: { bg: '#fff3cd', color: '#856404', border: '#ffc107' }, listo: { bg: '#d1e7dd', color: '#0f5132', border: '#198754' }, error: { bg: '#f8d7da', color: '#842029', border: '#dc3545' }, }; const c = colores[tipo] || colores.procesando; div.style.display = 'block'; div.style.background = c.bg; div.style.color = c.color; div.style.border = `1px solid ${c.border}`; div.textContent = texto; } // ─── NÚCLEO: COMPRESIÓN ────────────────────────────────────────── function comprimirImagen(file, callback) { // Solo imágenes if (!file.type.startsWith('image/')) { callback(file); return; } const reader = new FileReader(); reader.onload = function(e) { const img = new Image(); img.onload = function() { // Calcular nuevas dimensiones manteniendo aspecto let { width, height } = img; const maxDim = CONFIG.maxWidthHeight; if (width > maxDim || height > maxDim) { if (width > height) { height = Math.round((height * maxDim) / width); width = maxDim; } else { width = Math.round((width * maxDim) / height); height = maxDim; } } const canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0, width, height); // Comprimir iterativamente hasta cumplir maxSizeKB let quality = CONFIG.quality; let dataUrl, blob; function intentar() { dataUrl = canvas.toDataURL('image/jpeg', quality); const bytes = Math.round((dataUrl.length * 3) / 4); const kb = bytes / 1024; if (kb > CONFIG.maxSizeKB && quality > CONFIG.minQuality) { quality = Math.max(quality - 0.08, CONFIG.minQuality); intentar(); return; } // Convertir dataUrl a Blob y luego a File const byteStr = atob(dataUrl.split(',')[1]); const arr = new Uint8Array(byteStr.length); for (let i = 0; i < byteStr.length; i++) { arr[i] = byteStr.charCodeAt(i); } blob = new Blob([arr], { type: 'image/jpeg' }); const archivoComprimido = new File( [blob], file.name.replace(/\.[^.]+$/, '') + '_c.jpg', { type: 'image/jpeg', lastModified: Date.now() } ); callback(archivoComprimido, { originalKB: Math.round(file.size / 1024), finalKB: Math.round(blob.size / 1024), quality: Math.round(quality * 100), }); } intentar(); }; img.src = e.target.result; }; reader.readAsDataURL(file); } // ─── REEMPLAZAR ARCHIVO EN INPUT ───────────────────────────────── function reemplazarArchivo(input, nuevoArchivo) { try { const dt = new DataTransfer(); dt.items.add(nuevoArchivo); input.files = dt.files; } catch (e) { // DataTransfer no disponible en algunos browsers antiguos console.warn('No se pudo reemplazar el archivo automáticamente:', e); } } // ─── INICIALIZAR CAMPOS ────────────────────────────────────────── function inicializarCampo(input) { const indicador = crearIndicador(input); input.addEventListener('change', function() { const file = this.files[0]; if (!file) return; // Si no es imagen, no comprimir if (!file.type.startsWith('image/')) return; const originalKB = Math.round(file.size / 1024); // Si ya pesa menos de maxSizeKB, no hace falta comprimir if (originalKB <= CONFIG.maxSizeKB) { mostrarEstado(indicador, `✅ ${file.name} (${originalKB} KB) — listo`, 'listo'); return; } mostrarEstado(indicador, `⏳ Optimizando foto... (${originalKB} KB)`, 'procesando'); comprimirImagen(file, function(archivoComprimido, info) { if (info) { reemplazarArchivo(input, archivoComprimido); mostrarEstado( indicador, `✅ Optimizada: ${info.originalKB} KB → ${info.finalKB} KB (${Math.round((1 - info.finalKB / info.originalKB) * 100)}% menos)`, 'listo' ); } else { mostrarEstado(indicador, `✅ ${file.name} lista`, 'listo'); } }); }); } // ─── BUSCAR Y CONECTAR CAMPOS ──────────────────────────────────── function conectarCampos() { FILE_FIELDS.forEach(function(nombre) { // CF7 genera inputs con name igual al tag const inputs = document.querySelectorAll(`input[type="file"][name="${nombre}"]`); inputs.forEach(inicializarCampo); }); } // Esperar a que CF7 cargue el DOM if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', conectarCampos); } else { conectarCampos(); } // Por si el formulario está en una página con carga dinámica document.addEventListener('wpcf7mailsent', function() { // Limpiar indicadores después del envío exitoso document.querySelectorAll('.compress-status').forEach(function(el) { el.style.display = 'none'; }); }); })();
Found myself coming back to b29bar more than my local pub actually. The atmosphere here is so chill and the live dealers make you feel like you are right at the table. Payouts are always on time and the interface runs beautifully on my phone. Highly recommend it to anyone who wants a top notch experience. b29bar
Yo, BY88Club! Been hitting you guys up for a while now. Love the selection of games, and the payouts are pretty quick. Sometimes the site can be a bit laggy, but overall, it’s a solid place to try your luck. Definitely worth a shot! Check it out: by88club
I love how straightforward the wagering requirements are here. No shady tricks or sudden limit changes. The game selection keeps getting better with every month. Everyone needs to check out forobetapuesta if they want fair play forobetapuesta
The interface feels incredibly modern and every button is placed exactly where you expect it to be. I enjoy how quickly the platform processes deposits and the match odds update in real time. It is rare to find a site that balances speed with security so well. in99exch
Gday mates, I stumbled upon this site while browsing for a solid Aussie friendly casino and it did not disappoint. The payment options fit perfectly with our local banks and I got my winnings without any headache. The game library is huge and the live dealers keep things exciting. Definitely my go to for weekend sessions now. aubet88au
Yo! Having a good time while making money. I checked out funnybettingexchange and it’s good. Click the link: funnybettingexchange
I absolutely love how lively the community feels every time I log in and the game selection keeps things fresh without feeling repetitive. Transactions are handled with proper care and I always feel confident when placing my wagers. It is rare to find this kind of genuine entertainment value so I highly recommend taking it for a spin. mrbeatcasino
The name says it all when you actually use it. Every spin feels fair and the bonus structure is straightforward without hidden traps. I have been coming back weekly because it just makes gaming fun instead of frustrating. Give it a proper look if you want a stress free experience. my60win
Gave 33win8bet a try – pretty straightforward. Clean site and easy to figure out, good for beginners or anyone who wants no fuss gaming. Worth a look! Play now! 33win8bet
As someone who loves mobile gaming on the go this app delivers exactly what I need. The graphics are crisp and the bonuses actually match the promises they make. I keep coming back because it never gets old and the developers really listen to feedback. theekhai999apps
I have been searching for a trustworthy platform for ages and finally found my go to spot with inodds96. The odds are super fair and I love how quick the withdrawals are. Every time I log in it feels like a cozy chat with old mates who just happen to run a stellar casino. If you want smooth gaming without the headaches just give them a try. inodds96
Just signed up last night and honestly the whole login flow felt so easy. Finally a place where I can unwind after a long day without fighting with confusing menus. nustarphlogin