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
PH678vip is legit, guys. I had a great experience. Good variety of games. I would recommend checking them out. ph678vip
Phlarologin, easy peasy to log in. No issues there! Sometimes I forget my password, but the reset is quick. Wish there was two-factor authentication for extra security. But hey, all good so far! Go to phlarologin.
I have tried quite a few betting apps over the years and this one actually delivers on its promises. Navigation is intuitive deposits show up instantly and cashing out is never delayed. The daily free bets keep me engaged and the whole system feels very transparent 678betapp
Playing here has been such a refreshing change from other platforms I have tested. Everything runs without lag and I appreciate how transparent they are about their terms. You can truly relax and focus on the fun while they handle the rest behind the scenes. clmrbetcasino
Yo, win222login is legit! Been using it for a while now. Super easy to get started and hey, a win is a win y’know Check it out here win222login
Being in the islands I always look for a spot that understands our pace and this platform really gets it. The games are vibrant, the support is kind, and cashing out never feels like a puzzle. I am so glad I stumbled upon this community. ph777publogin.ph
Everything about my experience here has been positive from start to finish. The live dealer games feel incredibly immersive and the chat features make it feel like I am sitting right at the table. Security is top notch and I always feel completely safe placing my bets. I will definitely be coming back for more. trbetasus