v1.0.40
- corregido el HTTP 500 al iniciar la conexión con Google Drive: se restauran googleDriveStateFile(), googleDriveCrearEstadoOAuth() y googleDriveConsumirEstadoOAuth(), ausentes en 1.0.39
- el state OAuth vuelve a ser criptográficamente aleatorio, temporal (10 minutos), de un solo uso y validado con hash_equals; un state incorrecto no invalida la autorización legítima pendiente
- restaurado googleDriveError(), también ausente, para evitar errores fatales durante canje de código, refresh token y peticiones a Google Drive; conserva diagnóstico HTTP/OAuth/cURL sin volcar respuestas completas
- actualización de versión a 1.0.40 sin modificar el motor FTP, streaming directo, proveedor Local ni núcleo del actualizador

v1.0.39
- el encabezado de la tabla de resultados adopta el azul principal del tema en lugar del azul oscuro/navy anterior
- actualización de versión a 1.0.39 sin modificar el motor de respaldos ni el núcleo del actualizador

v1.0.38
- eliminado del bloque "Estado general de la descarga" el contador lateral de correctos/errores; esos totales siguen disponibles en las tarjetas de resumen
- actualización de versión a 1.0.38 sin modificar el motor de descargas ni el núcleo del sistema de actualizaciones

v1.0.37
- las tarjetas de sitios con fallo muestran únicamente "Error de conexión"; el diagnóstico técnico completo se conserva en el log
- los textos de los toggles de Configuración bajan a 11 px y los interruptores se compactan a 32x18 px
- los resultados exitosos guardados por versiones anteriores que todavía dicen "FTP → Google Drive completado" se normalizan visualmente a "Respaldo completado" sin modificar el job histórico
- actualización de versión a 1.0.37 sin modificar el núcleo del sistema de actualizaciones

v1.0.36
- en la cuadrícula de sitios con novedades, el texto pasa de "backup(s) encontrado" a "respaldo(s) encontrado(s)"
- en el detalle de transferencias exitosas el resultado se simplifica a "Respaldo completado", incluyendo los casos de sesión reanudada
- actualización de versión a 1.0.36 sin modificar el núcleo del actualizador ni el motor de transferencias

v1.0.35
- el toggle de tema pierde el borde exterior y adapta sus iconos: negro en modo claro y blanco en modo oscuro
- el centro de actualizaciones simplifica su resumen quitando Repositorio y Última disponible, con acabado visual coherente en claro y oscuro
- los toggles y sus etiquetas se compactan en el área de Configuración y en las tarjetas de sitios FTP
- TRACE EXTREMO pasa a mostrarse como Log tanto en la tarjeta de configuración como en la ventana de depuración

v1.0.34 - 2026-09-20
- encabezado principal convertido en sticky para permanecer visible al desplazarse tanto en Configuración como en el panel principal, conservando los mismos controles y comportamiento
- TRACE EXTREMO se apila inmediatamente debajo de Destino de los respaldos en la columna izquierda; Ajustes generales permanece en la columna derecha, eliminando el hueco vertical provocado por el grid anterior
- modo claro actualizado con la paleta visual de referencia: #0F172A para texto/encabezados, #475569/#64748B para secundarios, #1D4ED8 para acciones activas y #F8FAFC/#F1F5F9/#FFFFFF para superficies
- switches, controles segmentados, botones primarios, foco, progreso y encabezados de tabla del modo claro se armonizan con la nueva paleta; los estados semánticos de éxito/error se conservan
- cambios limitados a interfaz, versión y changelog; no se modifica el motor FTP, Google Drive, OAuth, worker, streaming, descargas Local, cifrado ni endpoints de backend

v1.0.33 - 2026-09-20
- reorganización exclusivamente estética de Configuración: Modo de conexión FTP y Sitios FTP comparten una sola tarjeta, conservando sin cambios las fichas, campos, distribución y comportamiento de cada sitio
- Destino de los respaldos, Ajustes generales y TRACE EXTREMO se organizan en una cuadrícula de dos columnas en escritorio, con adaptación a una columna en ventanas estrechas
- Guardar configuración se mueve al encabezado junto al engranaje y solo aparece dentro de Configuración; permanece atenuado/deshabilitado hasta detectar un cambio real en los campos configurables
- eliminado el texto inferior del candado/AES de la interfaz sin modificar el cifrado real de settings.enc ni la clave de instalación
- Actualizaciones deja de ocupar una tarjeta dentro de Configuración: nuevo icono junto al engranaje abre un modal amplio con estado, búsqueda, instalación e historial/rollback completos
- el icono de actualizaciones y Guardar configuración desaparecen al volver al panel principal; no se modifican FTP, Google Drive, worker, streaming, descargas Local ni endpoints de backend

v1.0.32 - 2026-09-20
- corregido el bloqueo en 0.00 GB del streaming FTP → Google Drive observado en Windows/MAMP: el motor directo deja de usar el wrapper ftp:// de PHP como fuente de CURLOPT_INFILE
- nuevo puente libcurl curl_multi de dos conexiones: una conexión cURL FTP/FTPS produce bytes y la sesión resumable HTTPS de Google Drive los consume simultáneamente mediante un buffer acotado de 16 MiB
- backpressure real con CURL_WRITEFUNC_PAUSE/CURL_READFUNC_PAUSE: si Drive va más lento se pausa FTP y si FTP va más lento se pausa la subida, evitando staging completo, crecimiento de RAM y bloqueos del wrapper FTP de PHP
- el FTP del puente usa modo pasivo de libcurl, EPSV/PASV, credenciales fuera de la URL y REST mediante CURLOPT_RESUME_FROM_LARGE para continuar exactamente desde el offset confirmado por Drive
- añadido watchdog de inactividad al puente: una transferencia sin progreso ya no puede quedar indefinidamente en estado ejecutando a 0 bytes; se aborta el intento, se consulta el offset confirmado y se reintenta de forma controlada
- se conserva la verificación TLS estricta y la cadena de candidatos CA de v1.0.31; no se desactiva SSL ni se requiere modificar php.ini para el funcionamiento normal
- se conserva el worker independiente en segundo plano y el proveedor Local no cambia

v1.0.31 - 2026-09-20
- corregida de raíz la compatibilidad TLS de Google Drive en localhost Windows: iRaffe combina su cacert.pem con las autoridades raíz realmente confiadas por Windows (CurrentUser\Root y LocalMachine\Root) cuando PHP/libcurl con OpenSSL no puede usar directamente el almacén nativo
- el almacén combinado se genera automáticamente y se guarda en config/runtime_ca, protegido junto con la configuración; no requiere editar php.ini, instalar certificados manualmente ni desactivar validaciones SSL
- macOS puede incorporar las autoridades de los keychains del sistema cuando PHP/libcurl no expone una CA utilizable; Linux/hosting mantiene prioridad por la CA configurada por PHP/OpenSSL y añade rutas estándar de Debian/Ubuntu, RHEL/CentOS/Alma/Rocky y FreeBSD
- el streaming FTP → Google Drive ya no fuerza el cacert.pem incluido por encima del trust store de la plataforma: usa el mismo orden de CA probado por el cliente OAuth/API y reintenta de forma segura únicamente si el handshake falla antes de enviar bytes
- la verificación TLS sigue estricta: CURLOPT_SSL_VERIFYPEER=true y CURLOPT_SSL_VERIFYHOST=2; no se aceptan certificados autofirmados ni se introduce un modo inseguro
- la solución funciona tanto en localhost como en servidor/hosting y no obliga a mover iRaffe al hosting; el proveedor Local, FTP local, segundo plano y reanudación por offset permanecen sin cambios

v1.0.30 - 2026-09-20
- corregido el cURL 60 del nuevo streaming FTP → Google Drive en Windows: todas las conexiones HTTPS a Google mantienen verificación TLS estricta y pueden recuperar automáticamente con el bundle CA incluido cuando php.ini/OpenSSL apuntan a una cadena existente pero inválida u obsoleta
- el PUT directo de varios GB prioriza el bundle CA incluido por iRaffe y suma el almacén nativo del sistema cuando libcurl lo soporta; nunca se desactiva CURLOPT_SSL_VERIFYPEER ni la validación de hostname
- las peticiones normales de OAuth/Drive prueban de forma controlada los almacenes CA disponibles únicamente cuando el handshake falla con error 60, evitando pedir al usuario que vuelva a autenticarse por un problema de certificados local
- añadido preflight de Google Drive antes de procesar la cola: valida autorización, TLS y carpeta seleccionada antes de abrir los FTP; si falla, el trabajo termina una sola vez con estado ERROR en lugar de generar el mismo error para cada archivo
- si durante una transferencia aparece un error global de TLS/OAuth/Drive, el worker detiene la cola de Google Drive y deja los archivos restantes como no iniciados; no continúa produciendo errores repetidos
- corregido el progreso global: un archivo que falla a 0 bytes ya no se contabiliza como si sus GB completos hubieran sido transferidos
- se conserva el streaming directo FTP → Google Drive, la reanudación por offset confirmado, el worker independiente en segundo plano y la visualización de tamaños en GB
- el proveedor Local conserva su flujo de descarga/reanudación existente; los cambios de preflight y corte global solo se activan con storage_provider=google_drive

v1.0.29 - 2026-09-20
- Google Drive cambia a transferencia directa FTP → Drive: el worker ya no descarga primero el respaldo completo a staging local.
- la subida usa una sesión resumable de Google Drive y alimenta una única solicitud PUT directamente desde el stream FTP para maximizar throughput y reducir esperas/uso de disco.
- si la conexión se corta, se consulta el offset realmente confirmado por Drive y el FTP se reabre con REST exactamente desde ese byte; no se vuelve al inicio salvo que la sesión resumable de Google haya vencido.
- el proceso continúa en el worker PHP independiente aunque se cierre la pestaña o el navegador; el estado queda en job.json y se recupera al volver a abrir la aplicación.
- la interfaz de progreso expresa tamaños exclusivamente en GB (global, archivo actual y barra por fila), manteniendo internamente los cálculos en bytes.
- el proveedor Local conserva su flujo probado y no usa el nuevo motor de streaming de Google Drive.

v1.0.28 - 2026-09-20
- Google Drive: consentimiento OAuth solo en la primera conexión; cambiar/seleccionar carpeta reutiliza la autorización persistente.
- conexión de Google Drive persistente en la interfaz: mientras exista refresh_token cifrado, Conectar con Google se oculta y la app muestra Conexión guardada
- el botón de carpeta ya no se confunde con la conexión: ahora abre un flujo único Elegir / crear carpeta
- nuevo cuadro para seleccionar una carpeta existente mediante el selector oficial de Google o crear una carpeta nueva sin volver a autenticar
- creación de carpeta nueva en Mi unidad o dentro de la carpeta actual autorizada; la carpeta creada queda seleccionada automáticamente como destino
- el refresh_token existente se conserva cuando Google devuelve un nuevo access_token sin emitir otro refresh_token
- sin cambios en el proveedor Local, Finder/Explorer, FTP ni la lógica de descargas locales

v1.0.27 - 2026-09-20
- corregido el fallo OAuth en PHP/cURL de Windows que devolvía "SSL certificate problem: unable to get local issuer certificate" al canjear el código de Google
- añadida resolución automática de CA: configuración PHP/OpenSSL cuando existe y bundle de autoridades raíz incluido como fallback para instalaciones Windows/MAMP sin cadena de confianza configurada
- la verificación TLS permanece estrictamente activa (peer + hostname); no se desactiva SSL ni se aceptan certificados autofirmados para Google
- el mismo CA fallback se aplica tanto al cliente cURL como al fallback de streams PHP
- se mantiene intacto el flujo Local y la integración OAuth/Drive de v1.0.26

v1.0.26 - 2026-09-20
- simplificada la configuración inicial de Google Drive con un asistente de una sola vez dentro de la propia interfaz
- añadido botón dedicado "Guardar acceso Google" para guardar Client ID/Secret sin validar ni modificar FTP, destino local u otros ajustes de producción
- la conexión OAuth ya no ejecuta un guardado global de configuración; puede autorizar Google aunque existan campos FTP/local pendientes de edición
- cuando OAuth ya está configurado, los campos técnicos se pliegan automáticamente y el flujo normal queda reducido a "Conectar con Google", seleccionar/crear carpeta y ejecutar el backup
- si cambia el Client ID o Client Secret, se invalidan de forma segura los tokens y la carpeta asociada para evitar reutilizar una autorización de otra aplicación
- mantenido el permiso drive.file y el Google Picker oficial para seleccionar carpetas sin Finder ni Explorer
- actualizada la guía GOOGLE_DRIVE_SETUP.txt con el flujo exacto para Google Auth Platform y las URI de redirección de cada instalación
- se conserva sin cambios el proveedor Local y todas las correcciones de reanudación FTP/ZIP de las versiones anteriores

v1.0.25 - 2026-09-20
- añadido Google Drive como destino alternativo de respaldos, totalmente separado del almacenamiento local existente para no alterar el flujo estable de Windows/macOS
- autenticación Google mediante OAuth 2.0 en el navegador; la aplicación nunca solicita ni almacena la contraseña de la cuenta Google
- soporte del permiso limitado drive.file y almacenamiento cifrado de Client Secret, refresh token y access token dentro del sistema de configuración existente
- selector de carpeta existente mediante Google Picker y posibilidad de crear una nueva carpeta raíz directamente en Mi unidad; la configuración conserva el folder_id real y no rutas locales
- las carpetas por sitio/subsitio se crean o reutilizan automáticamente bajo la carpeta raíz elegida en Google Drive
- añadidas subidas reanudables en bloques de 8 MiB para backups grandes, con recuperación de sesión y continuación desde el offset confirmado por Google
- el archivo descargado desde FTP se mantiene únicamente como staging temporal; se elimina después de que Drive confirma la carga completa y se conserva cuando Drive falla para evitar volver a descargar gigas desde FTP
- si Drive ya contiene un archivo con el mismo nombre y tamaño dentro de la carpeta destino, el worker lo omite sin volver a descargarlo desde FTP
- Google Drive funciona por API y navegador: no requiere Google Drive Desktop, no monta unidades y no usa Finder ni Explorer para seleccionar la carpeta remota
- el modo Google Drive desactiva limpieza destructiva/remota en esta primera versión; el modo Local conserva su comportamiento anterior
- añadidos endpoints dedicados api/google_drive.php y api/google_oauth_callback.php, módulo includes/google_drive.php y guía GOOGLE_DRIVE_SETUP.txt
- compatibilidad sin dependencia obligatoria de mbstring; el cliente HTTP usa cURL cuando está disponible y streams PHP como fallback

v1.0.24 - 2026-09-20
- Corregido falso positivo que marcaba ZIP válidos como "ZIP inválido o corrupto" después de una transferencia FTP completa.
- La integridad de transporte ahora se decide por coincidencia exacta entre SIZE remoto y tamaño local; ZipArchive/CHECKCONS queda solo como diagnóstico no destructivo.
- Un resultado inconcluso de ZipArchive ya no borra el backup descargado, no fuerza redescarga y no convierte el item en error.
- Copias locales heredadas con tamaño remoto/local exacto ya no se eliminan por limitaciones de ZipArchive, ZIP64 o archivos multipart.
- Descarga directa, worker y descarga por navegador aplican la misma política para evitar falsos positivos entre rutas de descarga.
- Corregida también la validación JavaScript de carpetas locales en macOS/navegador: una inspección ZIP no concluyente ya no borra ni vuelve a poner como pendiente un archivo cuyo tamaño coincide exactamente con el remoto.

v1.0.23 - 2026-09-20
- corregida la reanudación FTP: un reintento ya no puede truncar el .part y volver a descargar desde cero un archivo de varios GB; la escritura usa stream local con fseek + ftp_nb_fget y conserva exactamente el offset existente
- si el servidor FTP rechaza REST/reanudación, el parcial se conserva intacto y ese intento termina con error controlado; nunca se descartan gigas ya descargados para reiniciar silenciosamente el mismo archivo
- si un .part del job ya tiene exactamente el tamaño remoto, se promueve y valida directamente sin ejecutar otro RETR ni volver a descargar el archivo
- eliminada la segunda descarga completa automática cuando un ZIP termina pero falla validación: el elemento se marca como error y el worker continúa con el siguiente archivo
- el porcentaje de un archivo o trabajo activo usa floor y queda limitado a 99%; el 100% solo aparece después de que el archivo/trabajo haya terminado y sido validado
- se mantiene el aislamiento por job de locks y parciales introducido en v1.0.22, junto con las protecciones contra workers huérfanos

v1.0.22 - 2026-09-20
- eliminado el bloqueo global de workers que podía dejar la aplicación inutilizable aunque job.json ya no tuviera un trabajo activo
- cada trabajo usa desde ahora su propio flock de ejecución; un PHP huérfano de una versión anterior no puede impedir el inicio de un job nuevo
- cada job descarga a un archivo temporal .part.<job_id> independiente, evitando que un worker antiguo y uno nuevo escriban sobre el mismo parcial
- añadido control final antes del rename: si el worker perdió la propiedad lógica del job durante una espera de red, descarta su parcial y nunca publica un archivo final
- los locks por job se liberan y limpian también mediante shutdown handler ante terminaciones anómalas de PHP
- el lock global heredado de v1.0.21 se detecta únicamente para TRACE y se aísla automáticamente; ya no requiere esperar ni reiniciar Apache/MAMP
- los errores de arranque del worker se muestran en el banner de estado y ya no mediante alert() bloqueante del navegador
- se mantienen la reanudación FTP, timeout de E/S, rollback transaccional, sincronización del updater y compatibilidad Windows/macOS de v1.0.21

v1.0.21 - 2026-09-20
- corregido el bloqueo de descargas grandes que podía dejar config/job.lock.run retenido cuando ftp_nb_continue permanecía esperando durante minutos u horas cerca del final de un archivo
- separado el timeout de inactividad de E/S del tiempo total de descarga: cada operación FTP devuelve control al worker como máximo en 45 segundos, mientras archivos de varios GB pueden seguir descargándose y reanudarse sin límite artificial del tamaño total
- las transferencias sin avance fuerzan reconexión y continúan desde el archivo .part en lugar de dejar el worker colgado
- el estado del trabajo considera el flock real del worker además del heartbeat, evitando falsos estados "interrumpido" mientras el proceso todavía existe
- job_start ya no crea un segundo trabajo si el worker anterior todavía posee el lock de ejecución
- los workers actualizan job.json únicamente si el id del trabajo sigue coincidiendo; un worker antiguo nunca puede sobrescribir un trabajo nuevo
- el worker adquiere job.lock.run antes de publicar su marca de arranque, eliminando falsos positivos de worker iniciado
- mantenidas las correcciones v1.0.20 de rollback transaccional y sincronización del estado del actualizador

v1.0.20 - 2026-09-20
- rollback automático transaccional corregido: si una instalación falla después de introducir archivos nuevos, esos archivos se eliminan al restaurar el snapshot anterior y no quedan residuos de la versión fallida
- sincronización del estado automático corregida: installed_version y latest_version se actualizan con la versión realmente instalada después de una actualización manual
- al cargar la aplicación o consultar el estado del updater se autocorrige cualquier update_auto_state.json heredado que haya quedado atrasado respecto a includes/version.php
- añadido núcleo de actualizador versionado v1.0.20 para evolucionar el updater sin reemplazar en caliente los archivos protegidos de v1.0.19
- el frontend v1.0.20 usa api/updater_v1020.php; instalaciones nuevas conservan alias compatibles y las actualizadas desde v1.0.19 mantienen intacto su núcleo protegido anterior
- TRACE EXTREMO reconoce también el endpoint versionado del actualizador
- sin cambios funcionales en FTP, escaneo, retención, descarga de respaldos ni selección de carpetas de Windows/macOS

v1.0.19 - 2026-09-20
- corregido el fallo por el que la descarga se quedaba en "pendiente" para siempre: el lanzamiento del worker ya no se da por bueno solo porque se abriera el socket
- job_start.php espera y confirma la marca de arranque real del worker antes de responder; si no arranca, devuelve el motivo exacto en vez de un ok falso
- api/worker.php escribe su marca de arranque (arranque, pid, latido) nada más autorizarse, antes del bloqueo, para que ningún fallo posterior deje el trabajo mudo
- si otro proceso retiene config/job.lock.run sin latido, el trabajo pasa a error con instrucciones en pantalla; si el otro worker sigue vivo, el duplicado se retira en silencio como antes
- respaldo CLI reescrito con proc_open (popen como segunda opción) y salida a NUL/dev-null: funciona en Windows 10/11 con start /B y en macOS/Linux sin dejar la conexión de Apache colgada
- detección del binario de PHP ampliada: MAMP, Homebrew (Intel y Apple Silicon), MacPorts, sistema, XAMPP, Laragon y WAMP
- el lanzamiento HTTP usa stream_socket_client, acepta certificados locales autofirmados, comprueba la escritura completa de la petición y no cierra el socket de golpe (algunos Apache descartaban la petición antes de ejecutar worker.php)
- las salidas por trabajo inexistente o clave inválida quedan registradas en el error_log del servidor
- la interfaz muestra el estado real del trabajo cuando Iniciar falla, con el mensaje del servidor
- sin cambios en FTP, escaneo, retención, validación de ZIP, conciliación macOS, updater protegido ni flujo de Windows

v1.0.17 - 2026-09-20
- macOS híbrido corregido de extremo a extremo: DirectoryHandle cuando existe; ruta local real de PHP cuando el navegador solo entrega FileList
- el selector fallback de macOS ahora enlaza la carpeta elegida con su ruta POSIX real usando huella de archivos y Spotlight/rutas habituales, sin adivinar por nombre
- scan.php ya no anula siempre directorio_local en macOS; usa local_mode=server o local_mode=browser según la capacidad real disponible
- cuando macOS usa ruta local real, PHP compara nombre/tamaño/ZIP/manifiesto, elimina copias inválidas y el worker vuelve a descargarlas con el mismo nombre sin crear duplicados (1)
- el modo servidor se reutiliza también para descargar en macOS cuando la carpeta quedó resuelta y escribible
- si la carpeta no puede resolverse con seguridad, la aplicación no finge capacidad de borrado: conserva el modo navegador y lo deja explícito en TRACE
- Windows conserva IFileOpenDialog, comparación local PHP, worker, reanudación, validación y limpieza sin cambios de arquitectura
- TRACE EXTREMO registra el modo local efectivo (server/browser), resolución de carpeta y cada decisión de sincronización

v1.0.16
- corregida la validación de Guardar configuración en macOS: ya no exige directorio_local porque el destino puede ser un permiso del navegador sin ruta POSIX visible para PHP
- la carpeta elegida mediante el fallback nativo de Safari/Firefox/Brave sin File System Access se conserva después de guardar configuración durante la sesión actual y sigue disponible para comparar los respaldos locales
- el selector con DirectoryHandle sigue persistiendo el permiso en IndexedDB y ahora limpia cualquier selección fallback anterior para evitar estados ambiguos
- en macOS Iniciar se bloquea de forma segura si no existe un DirectoryHandle autorizado ni un FileList de carpeta activo; así no se marcan todos los respaldos remotos como nuevos por falta de acceso local
- el TRACE EXTREMO registra explícitamente cuando el escaneo se bloquea por no tener acceso a la carpeta local
- se mantienen sin cambios funcionales FTP, retención, updater protegido y flujo de Windows

v1.0.15
- añadido TRACE EXTREMO correlacionado de extremo a extremo con session_id, request_id, secuencia, timestamp UTC, tiempos, PID y memoria actual/pico por evento
- el mismo interruptor de Depuración activa ahora el nivel máximo: trace, debug, info, warn, error y fatal
- el panel del navegador conserva hasta 25.000 eventos y registra entorno del navegador, plataforma, viewport, red, peticiones, respuestas, polling, conciliación macOS y descargas binarias
- cada petición TRACE propaga debug_session al backend para unir en una sola sesión navegador, API, PHP, FTP y workers
- añadido registro persistente NDJSON en logs/debug, con rotación por segmentos de 50 MiB y limpieza de trazas de más de 14 días
- añadido botón TRACE para descargar el registro persistente completo del servidor correspondiente a la sesión activa
- redacción profunda de contraseñas, tokens, secretos, Authorization, cookies y credenciales embebidas en querystrings/texto antes de guardar o mostrar eventos
- instrumentadas decisiones de sincronización archivo por archivo: rutas, tamaños, mtimes, manifiesto, ZIP, SHA-256, omitir/pendiente, eliminación y motivo exacto
- instrumentadas conexiones FTP, métodos de listado, cache hits, metadatos, retención, reintentos, offsets de reanudación, progreso y validación de transferencias
- el worker hereda la sesión TRACE del trabajo para que la descarga en segundo plano quede correlacionada aunque el navegador se cierre
- añadida captura de errores PHP incluidos warnings suprimidos, notices, deprecated y fatales, además de errores y promesas rechazadas de JavaScript
- el updater estable protegido permanece intacto; sus solicitudes/respuestas se trazan desde el navegador y debug_log activa compatibilidad de trazado básico sin reemplazar el núcleo protegido
- se conservan sin cambios funcionales la conciliación real de macOS, el selector de destino, la lógica de archivos corruptos, el escaneo FTP, la retención y el flujo de Windows

v1.0.14
- macOS compara realmente los respaldos remotos contra la carpeta elegida mediante el DirectoryHandle del navegador antes de marcarlos como nuevos
- Safari/Firefox también comparan los archivos seleccionados mediante el FileList del selector de carpeta; si una copia es inválida queda pendiente para reemplazarla al guardar
- se reconocen copias válidas tanto en la raíz de la carpeta elegida como en subcarpetas por sitio para conservar compatibilidad con respaldos anteriores
- archivos locales vacíos, de tamaño distinto o ZIP estructuralmente corruptos se eliminan y permanecen pendientes para descargarse de nuevo
- el resumen, las fichas por sitio y el contador de pendientes se recalculan después de la comparación local real en macOS
- la comparación se repite al reconstruir la pantalla desde el último escaneo, evitando falsos "nuevos" después de recargar
- tras cada descarga en macOS se valida la copia escrita; si falla se elimina y se repite una descarga completa una vez
- se conserva sin cambios el escaneo FTP, la retención, el updater y el flujo de Windows

v1.0.13
- corregido el modo macOS para que vuelva a mostrarse el campo Directorio local de destino con el botón Examinar...
- eliminadas reglas CSS heredadas de v1.0.11 que ocultaban por error el selector de directorio en macOS
- se mantiene el selector nativo del navegador en macOS y el flujo existente de Windows

v1.0.12
- restaurado el selector de directorio de descarga en macOS; ya no se sustituye por una tarjeta informativa
- en macOS Chromium/Brave/Edge se usa el selector nativo del navegador con permiso de escritura y el destino se conserva en IndexedDB
- Safari/Firefox usan su selector nativo de directorios como fallback y el cuadro Guardar como del navegador para la escritura final
- si una copia local existente es inválida, vacía, corrupta o deja de coincidir con el remoto, se elimina y vuelve a quedar pendiente
- un ZIP heredado del mismo tamaño ya no se acepta automáticamente: se valida antes de crear el baseline
- si una descarga termina corrupta o con tamaño incorrecto, la copia se elimina y se realiza un segundo ciclo completo de descarga desde FTP
- las descargas gestionadas por el navegador en macOS se validan en un temporal antes de entregarse; si el temporal es inválido se borra y se vuelve a descargar

v1.0.11
- macOS descarga los respaldos mediante el navegador con Content-Disposition attachment, usando el diálogo nativo de guardado del navegador
- macOS ya no exige ni muestra un directorio_local para poder descargar
- Windows conserva el flujo de descarga local y su selector moderno de carpetas
- la configuración guarda client_platform para preservar una ruta de Windows cuando la app se usa desde macOS
- añadido endpoint api/browser_download.php para transmitir cada backup FTP directamente al navegador sin guardarlo primero en una ruta local del servidor

v1.0.10
- macOS ya no abre Finder, AppleScript ni una app temporal al escoger el directorio de descarga
- en macOS el botón Examinar abre directamente el explorador de carpetas dentro de iRaffe, sin salir del navegador
- macOS inicia el explorador interno en /Users cuando todavía no hay una carpeta configurada
- Linux mantiene el explorador interno y Windows conserva el selector moderno IFileOpenDialog
- la detección de plataforma decide el selector antes de hacer ninguna llamada externa, para que la apertura sea inmediata y fluida

v1.0.9
- corregido fallo de v1.0.8 que impedía Iniciar cuando la ruta local pertenecía a otro sistema operativo
- Iniciar vuelve a escanear los FTP aunque todavía no haya una carpeta local válida para el sistema actual
- sin carpeta local válida se omite solo la comparación local; el descubrimiento remoto sigue funcionando
- Descargar permanece bloqueado hasta seleccionar una carpeta válida para Windows/macOS/Linux
- una ruta de otro sistema operativo ya no se borra de la configuración cifrada al abrir la aplicación
- get_config oculta temporalmente la ruta incompatible en la interfaz sin destruirla

v1.0.8
- detección explícita del sistema operativo real: Windows, macOS o Linux
- las rutas heredadas de otro sistema operativo se descartan automáticamente (por ejemplo C:\... en macOS)
- el explorador interno de macOS inicia en / cuando no hay una ruta POSIX válida
- selector nativo de macOS reforzado con una applet GUI temporal vía LaunchServices y fallback a osascript
- el selector de Windows mantiene IFileOpenDialog moderno
- la respuesta de depuración informa plataforma, selector utilizado y ruta de fallback

v1.0.7
- Windows ahora usa el selector moderno nativo de carpetas basado en IFileOpenDialog/FOS_PICKFOLDERS
- eliminado FolderBrowserDialog/WinForms del selector de directorios en Windows
- se conserva Finder nativo en macOS y el explorador interno como fallback
- el selector moderno respeta la carpeta inicial, permite crear carpetas y valida acceso de escritura

v1.0.6
- añadido selector nativo de carpetas en macOS mediante Finder/osascript
- el botón Examinar intenta primero el selector nativo en Windows y macOS y usa el explorador interno como fallback
- el campo de directorio local ya no está limitado visualmente a Windows y permite rutas POSIX de macOS/Linux
- la creación de carpetas respeta reglas de nombres Windows o POSIX según el sistema operativo
- en instalaciones nuevas sobre macOS/Linux ya no se propone C:\backups_diarios como ruta predeterminada
- se informa si MAMP/PHP no tiene permiso de escritura sobre la carpeta elegida

v1.0.5
- eliminado el icono delante del nombre iRaffe FTP Backups
- en modo claro la rueda de configuración ahora se muestra sin círculo ni fondo alrededor
- en modo claro los botones activos y el control segmentado usan azul con tipografía blanca
- refinados botones secundarios claros para mantener fondo blanco y lectura limpia

v1.0.4
- refinado el modo claro con una paleta más equilibrada y menos agresiva sobre fondo blanco
- suavizados los botones principales/secundarios y el control segmentado en tema claro
- la rueda de configuración en modo claro ahora usa líneas oscuras y fondo neutro, sin burbuja azul sólida
- ajustado el encabezado, el badge de marca y los componentes claros para un aspecto más limpio y profesional

iRaffe FTP Backups — Cambios

v1.0.3
- Eliminado el botón Resumen: el panel principal vuelve a ser la vista base de la aplicación.
- Configuración pasa a abrirse desde un botón de rueda dentada en la cabecera.
- Añadido selector de tema claro/oscuro con sol y luna; la preferencia queda guardada en el navegador.
- Añadido modo claro completo mediante variables visuales para fondo, paneles, formularios, tablas, modales y estados.
- Al salir se elimina el historial visible de la sesión: last_scan.json se descarta y job.json terminado se elimina inmediatamente.
- Si se sale durante una descarga, el trabajo se oculta de inmediato, se cancela y el worker elimina job.json al finalizar.
- Se conservan las correcciones FTP/DNS, validación y rendimiento de las versiones anteriores.

v1.0.2
- Corregidos falsos positivos de DNS en conexiones FTP.
- La aplicación ya no usa gethostbyname() como barrera previa ni cancela una conexión antes de probar el FTP real.
- ftp_connect()/ftp_ssl_connect() se ejecutan primero; solo si fallan se hace diagnóstico DNS.
- El diagnóstico posterior distingue entre host no resuelto y host resuelto con FTP/puerto inaccesible.
- Eliminado el mensaje engañoso que afirmaba que el dominio podía no existir sin haber intentado la conexión FTP.
- Se conservan las mejoras de rendimiento y validación de backups de v1.0.1.

v1.0.1
- Corregida la lentitud del primer escaneo tras migrar: los backups heredados ya no calculan SHA-256 completo durante la exploración.
- Los backups existentes se registran mediante un baseline ligero con tamaño remoto/local y mtimes remoto/local.
- Si un archivo heredado cambia localmente después del baseline, deja de considerarse sincronizado y se vuelve a validar/descargar.
- Los archivos descargados por la aplicación siguen registrándose con SHA-256 completo después de una descarga verificada.
- Se mantiene intacto el auto-descubrimiento de WordPress, incluidos WordPress anidados y múltiples carpetas wp-content/backups.

v1.0.0
- Nueva línea de versionado 1.0.x.
- Actualizaciones automáticas desde https://carlosraffe.sensatoweb.com/actualizaciones/ibackup/info.php.
- Comprobación automática al abrir la aplicación y antes de la tarea programada de backup.
- Descarga y validación de actualización por tamaño, SHA-256, estructura ZIP y versión interna.
- Snapshot automático antes de cada actualización.
- Rollback automático si falla una instalación.
- Restauración manual de versiones anteriores desde Configuración > Actualizaciones.
- Un rollback manual pausa la actualización automática para no deshacer la restauración.
- Copia limpia de código v1.7.0 disponible como primer rollback, sin configuración ni credenciales.
- Validación de backups remotos/locales por tipo de archivo, tamaño remoto y manifiesto de sincronización.
- SHA-256 local persistente para detectar copias locales alteradas o corruptas.
- MLSD/RAWLIST priorizados sobre NLIST para reducir falsos positivos.

v1.0.1 - hotfix de actualización en Windows/MAMP
- Corregido el fallo "No se pudo activar api/update.php" al actualizar desde v1.0.0.
- Se reemplaza el updater autorreemplazable por un núcleo estable: api/updater.php + includes/updater_core.php.
- El núcleo estable queda protegido para que futuras actualizaciones no intenten sobrescribir archivos que están ejecutándose.
- Se mantiene la mejora de rendimiento del baseline de backups heredados sin SHA-256 masivo durante el escaneo.
