{"id":60,"date":"2025-10-08T21:48:17","date_gmt":"2025-10-08T21:48:17","guid":{"rendered":"https:\/\/coleta.envionacional.com.br\/?page_id=60"},"modified":"2025-10-15T15:31:08","modified_gmt":"2025-10-15T15:31:08","slug":"coleta","status":"publish","type":"page","link":"https:\/\/coleta.envionacional.com.br\/","title":{"rendered":"coleta"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"60\" class=\"elementor elementor-60\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e4b2b1f e-flex e-con-boxed e-con e-parent\" data-id=\"e4b2b1f\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-edce0ed elementor-widget elementor-widget-html\" data-id=\"edce0ed\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"pt-BR\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>Scanner de Etiquetas - Amazon<\/title>\r\n    \r\n    <!-- \r\n        Instru\u00e7\u00f5es de Uso e Teste:\r\n        1.  Permiss\u00f5es da C\u00e2mera: Ao abrir este arquivo, o navegador solicitar\u00e1 permiss\u00e3o para usar a c\u00e2mera.\r\n            \u00c9 necess\u00e1rio aceitar para que a fun\u00e7\u00e3o de scanner funcione.\r\n        2.  Execu\u00e7\u00e3o Local: Este arquivo pode ser aberto diretamente no navegador. Para o funcionamento correto\r\n            do Firebase, as configura\u00e7\u00f5es do projeto precisam ser fornecidas no script abaixo.\r\n        3.  Depend\u00eancias: Todas as bibliotecas necess\u00e1rias (TailwindCSS, jsPDF, html5-qrcode, Tesseract.js, Firebase) \r\n            s\u00e3o carregadas via CDN, ent\u00e3o uma conex\u00e3o com a internet \u00e9 necess\u00e1ria.\r\n        4.  Dados: Os dados de \"Scanear Coleta\" s\u00e3o salvos no Firebase. Os dados de \"Retorno de Encomenda\"\r\n            s\u00e3o salvos no LocalStorage do navegador e enviados para um webhook.\r\n    -->\r\n\r\n    <!-- Tailwind CSS para estiliza\u00e7\u00e3o r\u00e1pida e responsiva -->\r\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\r\n    \r\n    <!-- Bibliotecas de terceiros para funcionalidades -->\r\n    <script src=\"https:\/\/unpkg.com\/html5-qrcode@2.3.8\/html5-qrcode.min.js\"><\/script>\r\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jspdf\/2.5.1\/jspdf.umd.min.js\"><\/script>\r\n    <!-- ATUALIZADO: Vers\u00e3o do Tesseract.js para a mais recente e est\u00e1vel -->\r\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/tesseract.js@5.1.0\/dist\/tesseract.min.js\"><\/script>\r\n\r\n    <style>\r\n        \/* Estilos personalizados *\/\r\n        body {\r\n            -webkit-font-smoothing: antialiased;\r\n            -moz-osx-font-smoothing: grayscale;\r\n        }\r\n\r\n        \/* Ajustes para mobile *\/\r\n        @media (max-width: 768px) {\r\n            .container {\r\n                padding: 8px !important;\r\n            }\r\n            \r\n            .space-y-6 > :not([hidden]) ~ :not([hidden]) {\r\n                margin-top: 1rem !important;\r\n            }\r\n            \r\n            .p-4 {\r\n                padding: 0.75rem !important;\r\n            }\r\n            \r\n            .text-2xl {\r\n                font-size: 1.25rem !important;\r\n            }\r\n            \r\n            input, button, textarea {\r\n                font-size: 16px !important; \/* Previne zoom autom\u00e1tico no iOS *\/\r\n            }\r\n        }\r\n\r\n        #reader {\r\n            border: 2px solid #e5e7eb;\r\n            border-radius: 0.5rem;\r\n            overflow: hidden;\r\n            width: 100% !important;\r\n            height: auto !important;\r\n            min-height: 300px;\r\n        }\r\n        \r\n        #reader video {\r\n            width: 100% !important;\r\n            height: auto !important;\r\n            object-fit: cover;\r\n        }\r\n\r\n        \/* Anima\u00e7\u00f5es de feedback para escaneamento *\/\r\n        .scan-feedback-flash {\r\n            position: fixed;\r\n            top: 0;\r\n            left: 0;\r\n            width: 100vw;\r\n            height: 100vh;\r\n            background-color: rgba(255, 255, 255, 0.8);\r\n            z-index: 9998;\r\n            animation: fadeOut 0.4s forwards;\r\n            pointer-events: none;\r\n        }\r\n\r\n        .scan-code-overlay {\r\n            position: fixed;\r\n            top: 50%;\r\n            left: 50%;\r\n            transform: translate(-50%, -50%);\r\n            background-color: rgba(0, 0, 0, 0.8);\r\n            color: #22c55e;\r\n            padding: 1rem 2rem;\r\n            border-radius: 0.5rem;\r\n            font-family: monospace;\r\n            font-size: 1.5rem;\r\n            font-weight: bold;\r\n            z-index: 9999;\r\n            animation: fadeInOut 1.5s forwards;\r\n            pointer-events: none;\r\n            text-align: center;\r\n            max-width: 90vw;\r\n            overflow: hidden;\r\n            text-overflow: ellipsis;\r\n            white-space: nowrap;\r\n        }\r\n        \r\n        \/* Overlay da c\u00e2mera OCR *\/\r\n        .camera-container {\r\n            position: relative;\r\n            width: 100%;\r\n        }\r\n        \r\n        .camera-overlay {\r\n            position: absolute;\r\n            top: 0;\r\n            left: 0;\r\n            width: 100%;\r\n            height: 100%;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            pointer-events: none;\r\n        }\r\n        \r\n        .overlay-guide {\r\n            width: 90%;\r\n            height: 70%;\r\n            border: 3px dashed rgba(255, 255, 255, 0.7);\r\n            border-radius: 12px;\r\n            box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.5);\r\n        }\r\n\r\n        @keyframes fadeOut {\r\n            from { opacity: 1; }\r\n            to { opacity: 0; }\r\n        }\r\n\r\n        @keyframes fadeInOut {\r\n            0% { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }\r\n            20% { opacity: 1; transform: translate(-50%, -50%) scale(1); }\r\n            80% { opacity: 1; transform: translate(-50%, -50%) scale(1); }\r\n            100% { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body class=\"bg-gray-100 text-gray-800 font-sans\">\r\n\r\n    <div class=\"container mx-auto max-w-4xl p-4 space-y-6\">\r\n        \r\n        <!-- Tela de Login -->\r\n        <div id=\"login-screen\" class=\"min-h-screen flex items-center justify-center bg-gray-50\">\r\n            <div class=\"max-w-md w-full space-y-8\">\r\n                <div class=\"text-center\">\r\n                    <h2 class=\"mt-6 text-3xl font-extrabold text-gray-900\">\r\n                        Scanner Amazon\r\n                    <\/h2>\r\n                    <p class=\"mt-2 text-sm text-gray-600\">\r\n                        Fa\u00e7a login para acessar o painel\r\n                    <\/p>\r\n                    <div class=\"mt-4 p-4 bg-blue-50 rounded-lg\">\r\n                        <h3 class=\"text-sm font-medium text-blue-900 mb-2\">Sistema H\u00edbrido Online\/Offline:<\/h3>\r\n                        <ul class=\"text-xs text-blue-800 space-y-1\">\r\n                            <li><strong>Login:<\/strong> Use qualquer email e senha<\/li>\r\n                            <li><strong>Novo usu\u00e1rio?<\/strong> Clique em \"Criar Conta\"<\/li>\r\n                            <li><strong>Funciona sem internet:<\/strong> Dados salvos localmente<\/li>\r\n                            <li><strong>Sincroniza\u00e7\u00e3o:<\/strong> Autom\u00e1tica quando Firebase dispon\u00edvel<\/li>\r\n                        <\/ul>\r\n                        <p class=\"text-xs text-blue-600 mt-2\">\r\n                            \u2705 Sistema inteligente que funciona mesmo sem permiss\u00f5es Firebase\r\n                        <\/p>\r\n                    <\/div>\r\n                        <\/p>\r\n                    <\/div>\r\n                <\/div>\r\n                <form class=\"mt-8 space-y-6\" id=\"login-form\">\r\n                    <div class=\"space-y-4\">\r\n                        <div>\r\n                            <label for=\"email\" class=\"block text-sm font-medium text-gray-700\">\r\n                                Email\r\n                            <\/label>\r\n                            <input id=\"email\" name=\"email\" type=\"email\" required \r\n                                   class=\"appearance-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm\" \r\n                                   placeholder=\"Digite seu email\">\r\n                        <\/div>\r\n                        <div>\r\n                            <label for=\"password\" class=\"block text-sm font-medium text-gray-700\">\r\n                                Senha\r\n                            <\/label>\r\n                            <input id=\"password\" name=\"password\" type=\"password\" required \r\n                                   class=\"appearance-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm\" \r\n                                   placeholder=\"Digite sua senha\">\r\n                        <\/div>\r\n                    <\/div>\r\n                    <div class=\"flex gap-2\">\r\n                        <button type=\"submit\" \r\n                                class=\"group relative flex-1 flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500\">\r\n                            Entrar\r\n                        <\/button>\r\n                        <button type=\"button\" id=\"create-account-btn\"\r\n                                class=\"group relative flex-1 flex justify-center py-2 px-4 border border-blue-600 text-sm font-medium rounded-md text-blue-600 bg-white hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500\">\r\n                            Criar Conta\r\n                        <\/button>\r\n                    <\/div>\r\n                    <div id=\"login-error\" class=\"text-red-600 text-sm text-center hidden\">\r\n                        Usu\u00e1rio ou senha incorretos\r\n                    <\/div>\r\n                <\/form>\r\n            <\/div>\r\n        <\/div>\r\n\r\n        <!-- Conte\u00fado Principal (inicialmente oculto) -->\r\n        <div id=\"main-app\" class=\"hidden\">\r\n            <header class=\"text-center bg-white p-4 rounded-lg shadow\">\r\n                <div class=\"flex justify-between items-center\">\r\n                    <h1 class=\"text-2xl md:text-3xl font-bold text-blue-600\">Scanner Amazon<\/h1>\r\n                    <div class=\"flex items-center gap-4\">\r\n                        <div class=\"text-right\">\r\n                            <span id=\"current-user\" class=\"text-sm font-medium text-gray-700\"><\/span>\r\n                            <div id=\"session-info\" class=\"text-xs text-gray-500\"><\/div>\r\n                        <\/div>\r\n                        <button id=\"logout-btn\" class=\"bg-red-500 hover:bg-red-600 text-white px-3 py-1 rounded text-sm transition-colors\">\r\n                            Sair\r\n                        <\/button>\r\n                    <\/div>\r\n                <\/div>\r\n                <p class=\"text-gray-600 mt-1 text-sm md:text-base\">Escaneie e gerencie c\u00f3digos<\/p>\r\n                <div class=\"flex items-center justify-center gap-2 mt-2\">\r\n                    <p id=\"auth-status\" class=\"text-xs text-gray-400\">Conectando ao servi\u00e7o de dados...<\/p>\r\n                    <div id=\"connection-indicator\" class=\"w-2 h-2 rounded-full bg-gray-400\"><\/div>\r\n                <\/div>\r\n\r\n                <!-- Sele\u00e7\u00e3o de Modo -->\r\n                <div class=\"flex justify-center gap-4 mt-4\">\r\n                    <button id=\"scan-mode-btn\" class=\"flex-1 max-w-[200px] bg-blue-500 text-white py-3 px-4 rounded-lg font-bold hover:bg-blue-600 active\">\r\n                        Scanear Coleta Amazon\r\n                    <\/button>\r\n                    <button id=\"return-mode-btn\" class=\"flex-1 max-w-[200px] bg-gray-200 text-gray-700 py-3 px-4 rounded-lg font-bold hover:bg-gray-300\">\r\n                        Retorno de Encomenda\r\n                    <\/button>\r\n                <\/div>\r\n            <\/header>\r\n\r\n        <!-- Conte\u00fado do Modo de Retorno -->\r\n        <div id=\"return-mode\" style=\"display: none;\">\r\n            <div class=\"bg-white p-4 rounded-lg shadow space-y-4 mt-6\">\r\n                <h2 class=\"text-xl font-semibold border-b pb-2\">Registrar Retorno com OCR<\/h2>\r\n                \r\n                <!-- Captura \/ Upload -->\r\n                <div class=\"space-y-2\">\r\n                    <h3 class=\"font-medium text-gray-700\">1. Capturar Etiqueta<\/h3>\r\n                    <div class=\"flex flex-col sm:flex-row gap-2\">\r\n                        <button id=\"start-ocr-camera-btn\" class=\"flex-1 bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded-lg transition-colors\">\r\n                            Fotografar Etiqueta\r\n                        <\/button>\r\n                        <input type=\"file\" id=\"upload-ocr-image-btn\" class=\"hidden\" accept=\"image\/*\">\r\n                        <label for=\"upload-ocr-image-btn\" class=\"flex-1 text-center bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-lg transition-colors cursor-pointer\">\r\n                            Enviar Imagem\r\n                        <\/label>\r\n                    <\/div>\r\n                    <div class=\"camera-container mt-2\">\r\n                        <video id=\"ocr-camera\" class=\"w-full rounded-lg border-2 border-gray-300\" style=\"display: none;\"><\/video>\r\n                        <div id=\"camera-overlay\" class=\"camera-overlay\" style=\"display: none;\">\r\n                            <div class=\"overlay-guide\"><\/div>\r\n                        <\/div>\r\n                    <\/div>\r\n                    <button id=\"capture-ocr-btn\" class=\"w-full bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-lg transition-colors hidden mt-2\">\r\n                        Capturar Foto\r\n                    <\/button>\r\n                <\/div>\r\n\r\n                <!-- OCR Progress -->\r\n                 <div id=\"ocr-progress-section\" class=\"space-y-2 border-t pt-4 hidden\">\r\n                    <h3 class=\"font-medium text-gray-700\">2. Lendo Etiqueta...<\/h3>\r\n                    <div id=\"ocr-progress\" class=\"w-full bg-gray-200 rounded-full h-2.5\">\r\n                        <div id=\"ocr-progress-bar\" class=\"bg-blue-600 h-2.5 rounded-full\" style=\"width: 0%\"><\/div>\r\n                    <\/div>\r\n                    <p id=\"ocr-status\" class=\"text-sm text-center text-gray-500\"><\/p>\r\n                <\/div>\r\n\r\n                <!-- Formul\u00e1rio de Revis\u00e3o e Retorno -->\r\n                <div id=\"review-form\" class=\"space-y-4 border-t pt-4 hidden\">\r\n                    <h3 class=\"font-medium text-gray-700\">3. Revise os Dados e Salve<\/h3>\r\n                    <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n                        <div>\r\n                            <label for=\"field-tracking-code\" class=\"block text-sm font-medium text-gray-700\">C\u00f3d. Rastreio<\/label>\r\n                            <input type=\"text\" id=\"field-tracking-code\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                        <\/div>\r\n                         <div>\r\n                            <label for=\"field-cep\" class=\"block text-sm font-medium text-gray-700\">CEP<\/label>\r\n                            <input type=\"text\" id=\"field-cep\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                        <\/div>\r\n                         <div>\r\n                            <label for=\"field-phone\" class=\"block text-sm font-medium text-gray-700\">Telefone<\/label>\r\n                            <input type=\"text\" id=\"field-phone\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                        <\/div>\r\n                        <div>\r\n                            <label for=\"return-product\" class=\"block text-sm font-medium text-gray-700\">Nome do Produto<\/label>\r\n                            <input type=\"text\" id=\"return-product\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                        <\/div>\r\n                        <div>\r\n                            <label for=\"return-quantity\" class=\"block text-sm font-medium text-gray-700\">Quantidade<\/label>\r\n                            <input type=\"number\" id=\"return-quantity\" min=\"1\" value=\"1\" class=\"mt-1 w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                        <\/div>\r\n                    <\/div>\r\n                    <div>\r\n                        <label for=\"ocr-result\" class=\"block text-sm font-medium text-gray-700\">Texto Completo Extra\u00eddo<\/label>\r\n                        <textarea id=\"ocr-result\" rows=\"6\" class=\"w-full mt-1 p-2 border border-gray-300 rounded-lg bg-gray-50\" placeholder=\"O texto completo da etiqueta aparecer\u00e1 aqui...\"><\/textarea>\r\n                    <\/div>\r\n                    <button id=\"save-ocr-return-btn\" class=\"w-full bg-green-500 hover:bg-green-600 text-white font-bold py-3 px-4 rounded-lg transition-colors text-lg\">\r\n                        Salvar Retorno\r\n                    <\/button>\r\n                <\/div>\r\n            <\/div>\r\n\r\n            <!-- Lista de Retornos -->\r\n            <div class=\"mt-6 bg-white p-4 rounded-lg shadow\">\r\n                <div class=\"flex justify-between items-center border-b pb-2\">\r\n                    <h3 class=\"text-lg font-semibold\">Hist\u00f3rico de Retornos (<span id=\"return-count\">0<\/span>)<\/h3>\r\n                    <div class=\"flex gap-2\">\r\n                        <span id=\"user-stats\" class=\"text-sm text-gray-600 mr-2\"><\/span>\r\n                        <button id=\"export-local-btn\" class=\"bg-gray-200 hover:bg-gray-300 text-gray-800 text-sm font-bold py-2 px-3 rounded-lg transition-colors\">\r\n                            Exportar Local\r\n                        <\/button>\r\n                    <\/div>\r\n                <\/div>\r\n                <div class=\"overflow-x-auto mt-4\">\r\n                    <table class=\"min-w-full divide-y divide-gray-200\">\r\n                        <thead class=\"bg-gray-50\">\r\n                            <tr>\r\n                                <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Data\/Hora<\/th>\r\n                                <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Produto<\/th>\r\n                                <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">C\u00f3d. Rastreio<\/th>\r\n                                <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Qtd<\/th>\r\n                                <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">Usu\u00e1rio<\/th>\r\n                            <\/tr>\r\n                        <\/thead>\r\n                        <tbody id=\"local-returns-history\" class=\"bg-white divide-y divide-gray-200\">\r\n                            <!-- Items ser\u00e3o inseridos aqui -->\r\n                        <\/tbody>\r\n                    <\/table>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n\r\n        <\/div> <!-- Fim do main-app -->\r\n\r\n        <!-- Se\u00e7\u00e3o do Scanner e A\u00e7\u00f5es -->\r\n        <main class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\r\n            \r\n            <!-- Coluna da Esquerda: Scanner e Entrada Manual -->\r\n            <div class=\"bg-white p-4 rounded-lg shadow space-y-4\">\r\n                <h2 class=\"text-xl font-semibold border-b pb-2\">Escanear C\u00f3digo<\/h2>\r\n                <div id=\"reader\" class=\"w-full\"><\/div>\r\n                <div id=\"camera-status\" class=\"text-center text-sm text-gray-500 min-h-[20px]\"><\/div>\r\n                <div class=\"flex justify-center gap-2\">\r\n                    <button id=\"start-camera-btn\" class=\"w-full bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded-lg transition-colors\">\r\n                        Iniciar C\u00e2mera\r\n                    <\/button>\r\n                    <button id=\"stop-camera-btn\" class=\"w-full bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded-lg transition-colors hidden\">\r\n                        Parar C\u00e2mera\r\n                    <\/button>\r\n                <\/div>\r\n                \r\n                <div class=\"border-t pt-4 space-y-2\">\r\n                    <label for=\"manual-input\" class=\"font-semibold\">Ou insira manualmente:<\/label>\r\n                    <div class=\"flex gap-2\">\r\n                        <input type=\"text\" id=\"manual-input\" placeholder=\"C\u00f3digo alfanum\u00e9rico\" class=\"flex-grow w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                        <button id=\"manual-add-btn\" class=\"bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-lg transition-colors\">Adicionar<\/button>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n\r\n            <!-- Coluna da Direita: Exporta\u00e7\u00e3o -->\r\n            <div class=\"bg-white p-4 rounded-lg shadow space-y-4\">\r\n                <h2 class=\"text-xl font-semibold border-b pb-2\">Exportar Relat\u00f3rio (PDF)<\/h2>\r\n\r\n                <button id=\"finish-collection-btn\" class=\"w-full bg-green-500 hover:bg-green-600 text-white font-bold py-3 px-4 rounded-lg transition-colors text-lg mb-4\">\r\n                    Finalizar Coleta\r\n                <\/button>\r\n\r\n                <!-- Modal de Finaliza\u00e7\u00e3o -->\r\n                <div id=\"finish-modal\" class=\"fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50\">\r\n                    <div class=\"bg-white rounded-lg p-6 max-w-lg w-full mx-4 space-y-4\">\r\n                        <h3 class=\"text-xl font-bold border-b pb-2\">Finalizar Coleta<\/h3>\r\n                        \r\n                        <div class=\"space-y-2\">\r\n                            <label for=\"cpf-input\" class=\"font-semibold\">CPF do Coletor <span class=\"text-red-500\">*<\/span><\/label>\r\n                            <input type=\"text\" id=\"cpf-input\" placeholder=\"000.000.000-00\" class=\"w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                        <\/div>\r\n                        \r\n                        <div class=\"space-y-2\">\r\n                            <label for=\"collector-name\" class=\"font-semibold\">Nome do Coletor <span class=\"text-red-500\">*<\/span><\/label>\r\n                            <input type=\"text\" id=\"collector-name\" placeholder=\"Digite o nome completo\" class=\"w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                        <\/div>\r\n\r\n                        <div class=\"flex items-center space-x-2 border-t pt-4\">\r\n                            <input type=\"checkbox\" id=\"force-export-check\" class=\"h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500\">\r\n                            <label for=\"force-export-check\" class=\"text-sm text-gray-700\">For\u00e7ar exporta\u00e7\u00e3o (sem assinatura\/CPF)<\/label>\r\n                        <\/div>\r\n\r\n                        <div class=\"flex gap-2 mt-4\">\r\n                            <button id=\"modal-cancel-btn\" class=\"w-full bg-gray-500 hover:bg-gray-600 text-white font-bold py-2 px-4 rounded-lg transition-colors\">\r\n                                Cancelar\r\n                            <\/button>\r\n                            <button id=\"export-pdf-btn\" class=\"w-full bg-green-500 hover:bg-green-600 text-white font-bold py-3 px-4 rounded-lg transition-colors flex items-center justify-center gap-2\">\r\n                                <span>\ufffd<\/span>\r\n                                <span>Finalizar e Enviar<\/span>\r\n                            <\/button>\r\n                        <\/div>\r\n                        <div class=\"mt-2\">\r\n                            <!-- Bot\u00e3o removido - WhatsApp substitu\u00eddo por webhook -->\r\n                                <span>\ufffd<\/span>\r\n                            <p class=\"text-xs text-center text-gray-500\">\r\n                                Gera PDF + Envia automaticamente para: n8n.zapnacional.com.br\r\n                            <\/p>\r\n                        <\/div>\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <p class=\"text-xs text-center text-gray-500 pt-2\">\r\n                    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"16\" height=\"16\" viewBox=\"0-0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"inline-block mr-1\"><path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"><\/path><\/svg>\r\n                    Dados salvos na nuvem com seguran\u00e7a.\r\n                <\/p>\r\n            <\/div>\r\n\r\n        <\/main>\r\n\r\n        <!-- Se\u00e7\u00e3o do Hist\u00f3rico -->\r\n        <section class=\"bg-white p-4 rounded-lg shadow\">\r\n            <div class=\"flex flex-col md:flex-row justify-between items-center gap-4 border-b pb-3 mb-3\">\r\n                <h2 class=\"text-xl font-semibold\">Hist\u00f3rico de Leituras (<span id=\"scan-count\">0<\/span>)<\/h2>\r\n                <div class=\"flex items-center gap-2\">\r\n                    <button id=\"clear-history-btn\" class=\"bg-gray-200 hover:bg-red-200 text-red-700 text-sm font-bold py-2 px-3 rounded-lg transition-colors\">\r\n                        Limpar Hist\u00f3rico\r\n                    <\/button>\r\n                <\/div>\r\n            <\/div>\r\n            \r\n            <!-- Filtros -->\r\n            <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-4 items-end\">\r\n                <div class=\"w-full\">\r\n                    <label for=\"search-input\" class=\"text-sm font-medium\">Buscar C\u00f3digo:<\/label>\r\n                    <input type=\"text\" id=\"search-input\" placeholder=\"Pesquisar...\" class=\"w-full mt-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                <\/div>\r\n                <div>\r\n                    <label for=\"start-date\" class=\"text-sm font-medium\">Data In\u00edcio:<\/label>\r\n                    <input type=\"date\" id=\"start-date\" class=\"w-full mt-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                <\/div>\r\n                <div>\r\n                    <label for=\"end-date\" class=\"text-sm font-medium\">Data Fim:<\/label>\r\n                    <input type=\"date\" id=\"end-date\" class=\"w-full mt-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\">\r\n                <\/div>\r\n                <div class=\"flex gap-2\">\r\n                    <button id=\"filter-today-btn\" class=\"w-full bg-blue-100 hover:bg-blue-200 text-blue-800 font-bold py-2 px-4 rounded-lg transition-colors\">Hoje<\/button>\r\n                    <button id=\"clear-filter-btn\" class=\"w-full bg-gray-100 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded-lg transition-colors\">Limpar<\/button>\r\n                <\/div>\r\n                \r\n                <!-- Controles de Arquivamento e Exporta\u00e7\u00e3o -->\r\n                <div class=\"border-t pt-4 mt-4\">\r\n                    <h4 class=\"text-sm font-medium text-gray-700 mb-3\">Arquivamento e Exporta\u00e7\u00e3o<\/h4>\r\n                    <div class=\"space-y-2\">\r\n                        <div class=\"flex gap-2\">\r\n                            <button id=\"archive-filtered-btn\" class=\"flex-1 bg-orange-100 hover:bg-orange-200 text-orange-800 font-bold py-2 px-4 rounded-lg transition-colors text-sm\">\r\n                                \ud83d\udcc1 Arquivar Filtradas\r\n                            <\/button>\r\n                            <button id=\"export-filtered-pdf-btn\" class=\"flex-1 bg-red-100 hover:bg-red-200 text-red-800 font-bold py-2 px-4 rounded-lg transition-colors text-sm\">\r\n                                \ud83d\udcc4 PDF Filtradas\r\n                            <\/button>\r\n                        <\/div>\r\n                        <div class=\"flex gap-2\">\r\n                            <button id=\"export-all-pdf-btn\" class=\"flex-1 bg-green-100 hover:bg-green-200 text-green-800 font-bold py-2 px-4 rounded-lg transition-colors text-sm\">\r\n                                \ud83d\udcca PDF Completo\r\n                            <\/button>\r\n                            <button id=\"view-archived-btn\" class=\"flex-1 bg-gray-100 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded-lg transition-colors text-sm\">\r\n                                \ud83d\uddc3\ufe0f Ver Arquivados\r\n                            <\/button>\r\n                        <\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n\r\n            <!-- Lista de C\u00f3digos -->\r\n            <div id=\"scanned-codes-list\" class=\"space-y-2 max-h-[50vh] overflow-y-auto pr-2\">\r\n                <!-- Itens ser\u00e3o inseridos aqui via JS -->\r\n                <p id=\"empty-list-msg\" class=\"text-center text-gray-500 py-8\">Nenhum c\u00f3digo escaneado ainda.<\/p>\r\n            <\/div>\r\n        <\/section>\r\n\r\n    <\/div>\r\n\r\n    <!-- Feedback visual para o scan -->\r\n    <div id=\"scan-feedback\" class=\"\"><\/div>\r\n    \r\n    <!-- Som de Beep (Base64 para n\u00e3o precisar de arquivo externo) -->\r\n    <audio id=\"beep-sound\" src=\"data:audio\/wav;base64,UklGRl9vT19XQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YU0AAAAA\/\/8\/A\/8E\/vf+b\/5\/\/h\/+b\/3A\/j\/9wP1\/\/ED9AP5\/\/bj+3P6d\/sD+Kf5d\/kr+VP5G\/oj+if7w\/kb\/Q\/9z\/3f\/cv+E\/4T\/gf+L\/3z\/dP9a\/z\/+S\/9U\/1v\/V\/9T\/2n\/eP95\/3H\/df92\/3X\/cv9w\/3T\/eP95\/3v\/hP+L\/4z\/kP+V\/5f\/mP+b\/53\/nP+d\/5r\/l\/+T\/4j\/gv95\/2z\/Vv9L\/z7\/Nv8r\/yP\/G\/8T\/wz\/B\/8A\/vX+yv60\/qX+mP6c\/pz+ov6u\/rX+u\/7C\/7j\/wP\/G\/8z\/0f\/U\/9f\/2f\/b\/9z\/3f\/d\/9z\/2f\/V\/9D\/zP\/F\/8D\/uv+x\/6b\/oP+a\/5T\/j\/+C\/3f\/a\/9T\/0X\/Ov8p\/x\/\/Dv8D\/+\/+v\/6i\/pr+nP6j\/qr+s\/67\/sP\/uv\/C\/8f\/z\/\/U\/9j\/3P\/g\/+L\/5P\/m\/+f\/6P\/p\/+j\/6P\/n\/+b\/5P\/i\/+B\/2\/\/U\/83\/xf+8\/63\/pP+c\/5T\/i\/+D\/3v\/bP9W\/0f\/P\/81\/yv\/IP8Y\/xP\/Dv8I\/wH\/AP8B\/wb\/C\/8R\/xX\/Gf8f\/yP\/K\/8x\/zf\/P\/9D\/0f\/S\/9Q\/1t\/Uv9T\/1L\/T\/9N\/0r\/R\/9B\/z3\/Of8v\/yj\/Jf8d\/xT\/Cf8A\/u\/+t\/6g\/pf+mP6f\/qL+q\/6w\/rX+u\/7B\/7n\/w\/\/I\/9H\/1v\/b\/9\/\/4v\/k\/+f\/6v\/t\/\/D\/8f\/z\/\/T\/9f\/2\/\/b\/9v\/1\/\/P\/8P\/u\/+n\/5v\/j\/+B\/2\/\/W\/9H\/yv\/D\/7r\/sf+o\/5z\/lP+G\/3b\/Z\/9R\/0L\/N\/8n\/xn\/DP8A\/7H+nv6d\/qH+qf6y\/rr+w\/+6\/8H\/yP\/R\/9f\/3P\/g\/+P\/5v\/p\/+z\/8P\/y\/\/X\/9v\/3\/\/f\/9v\/0\/\/L\/7v\/p\/+f\/5P\/h\/9z\/1v\/Q\/8n\/wv+7\/7L\/qf+g\/5v\/lP+M\/4f\/gP+B\/4L\/hf+I\/4r\/jP+Q\/5P\/l\/+Z\/5v\/nf+f\/6D\/oP+f\/53\/mv+V\/4\/\/hv9\/\/2v\/U\/9F\/zr\/Kf8c\/wv\/9v60\/qH+mv6d\/qH+q\/6y\/rv+xf+8\/8H\/yP\/S\/9f\/3f\/h\/+T\/5\/\/q\/+3\/8P\/y\/\/X\/9v\/3\/\/f\/9\/\/3\/\/b\/9f\/z\/\/D\/7v\/r\/+j\/5\/\/l\/+P\/4P\/c\/9j\/1P\/R\/8z\/yP\/G\/8P\/wv\/B\/8L\/xP\/G\/8n\/zP\/P\/9H\/0\/\/U\/9X\/1\/\/Z\/9r\/3P\/e\/9\/\/4P\/h\/+H\/4P\/f\/93\/2v\/X\/9T\/0f\/M\/8j\/xP+9\/7P\/pv+a\/4z\/ff9m\/1L\/Qf82\/yf\/F\/8J\/+\/\/sP+j\/5\/\"><\/audio>\r\n\r\n\r\n    <script type=\"module\">\r\n        \/\/ --- IMPORTS DO FIREBASE ---\r\n        import { initializeApp } from \"https:\/\/www.gstatic.com\/firebasejs\/11.6.1\/firebase-app.js\";\r\n        import { getAuth, signInWithEmailAndPassword, createUserWithEmailAndPassword, signOut, onAuthStateChanged, updateProfile } from \"https:\/\/www.gstatic.com\/firebasejs\/11.6.1\/firebase-auth.js\";\r\n        import { getFirestore, collection, addDoc, onSnapshot, query, doc, deleteDoc, writeBatch, getDocs, orderBy, where, setDoc } from \"https:\/\/www.gstatic.com\/firebasejs\/11.6.1\/firebase-firestore.js\";\r\n\r\n        document.addEventListener('DOMContentLoaded', function() {\r\n            \/\/ --- ELEMENTOS DO DOM ---\r\n            const loginScreen = document.getElementById('login-screen');\r\n            const mainApp = document.getElementById('main-app');\r\n            const loginForm = document.getElementById('login-form');\r\n            const loginError = document.getElementById('login-error');\r\n            const currentUserSpan = document.getElementById('current-user');\r\n            const logoutBtn = document.getElementById('logout-btn');\r\n            const createAccountBtn = document.getElementById('create-account-btn');\r\n            \r\n            const readerDiv = document.getElementById('reader');\r\n            const cameraStatus = document.getElementById('camera-status');\r\n            const startCameraBtn = document.getElementById('start-camera-btn');\r\n            const stopCameraBtn = document.getElementById('stop-camera-btn');\r\n            const manualInput = document.getElementById('manual-input');\r\n            const manualAddBtn = document.getElementById('manual-add-btn');\r\n            const cpfInput = document.getElementById('cpf-input');\r\n            const forceExportCheck = document.getElementById('force-export-check');\r\n            const exportPdfBtn = document.getElementById('export-pdf-btn');\r\n            const scanCountSpan = document.getElementById('scan-count');\r\n            const clearHistoryBtn = document.getElementById('clear-history-btn');\r\n            const searchInput = document.getElementById('search-input');\r\n            const startDateInput = document.getElementById('start-date');\r\n            const endDateInput = document.getElementById('end-date');\r\n            const filterTodayBtn = document.getElementById('filter-today-btn');\r\n            const clearFilterBtn = document.getElementById('clear-filter-btn');\r\n            const scannedCodesList = document.getElementById('scanned-codes-list');\r\n            const scanFeedback = document.getElementById('scan-feedback');\r\n            const beepSound = document.getElementById('beep-sound');\r\n            const authStatus = document.getElementById('auth-status');\r\n\r\n            \/\/ Elementos de arquivamento e exporta\u00e7\u00e3o\r\n            const archiveFilteredBtn = document.getElementById('archive-filtered-btn');\r\n            const exportFilteredPdfBtn = document.getElementById('export-filtered-pdf-btn');\r\n            const exportAllPdfBtn = document.getElementById('export-all-pdf-btn');\r\n            const viewArchivedBtn = document.getElementById('view-archived-btn');\r\n\r\n            \/\/ --- ELEMENTOS DO MODO DE RETORNO (OCR) ---\r\n            const startOcrCameraBtn = document.getElementById('start-ocr-camera-btn');\r\n            const uploadOcrImageInput = document.getElementById('upload-ocr-image-btn');\r\n            const ocrCameraVideo = document.getElementById('ocr-camera');\r\n            const ocrCameraOverlay = document.getElementById('camera-overlay');\r\n            const captureOcrBtn = document.getElementById('capture-ocr-btn');\r\n            const ocrProgressSection = document.getElementById('ocr-progress-section');\r\n            const ocrProgressBar = document.getElementById('ocr-progress-bar');\r\n            const ocrStatusP = document.getElementById('ocr-status');\r\n            const reviewForm = document.getElementById('review-form');\r\n            const ocrResultTextarea = document.getElementById('ocr-result');\r\n            const returnProductInput = document.getElementById('return-product');\r\n            const returnQuantityInput = document.getElementById('return-quantity');\r\n            const saveOcrReturnBtn = document.getElementById('save-ocr-return-btn');\r\n            const exportLocalBtn = document.getElementById('export-local-btn');\r\n            const localReturnsHistoryTable = document.getElementById('local-returns-history');\r\n\r\n\r\n            \/\/ --- ESTADO DA APLICA\u00c7\u00c3O ---\r\n            let currentUser = null;\r\n            let firebaseUser = null;\r\n            let codes = [];\r\n            let lastScannedCode = null;\r\n            let lastScanTime = 0;\r\n            const DUPLICATE_TIMEOUT = 3000;\r\n            let html5QrCode = null;\r\n            let unsubscribeFromFirestore = null;\r\n            let currentMode = 'scan'; \/\/ 'scan' ou 'return'\r\n            let ocrStream = null;\r\n            const WEBHOOK_URL = 'https:\/\/n8n.zapnacional.com.br\/webhook-test\/09a47025-8cbb-412c-bb39-7824e3a72a44';\r\n\r\n            \/\/ --- CONFIGURA\u00c7\u00c3O FIREBASE ---\r\n            const firebaseConfig = {\r\n                apiKey: \"AIzaSyALGpFQhozwLyl1TQ_B_xYSVHX0HJOCIJ0\",\r\n                authDomain: \"coleta-d060e.firebaseapp.com\",\r\n                projectId: \"coleta-d060e\",\r\n                storageBucket: \"coleta-d060e.firebasestorage.app\",\r\n                messagingSenderId: \"793652809237\",\r\n                appId: \"1:793652809237:web:44dab696be77636040c81c\",\r\n                measurementId: \"G-JLMSHS2D96\"\r\n            };\r\n\r\n            \/\/ Inicializar Firebase\r\n            const app = initializeApp(firebaseConfig);\r\n            const auth = getAuth(app);\r\n            const db = getFirestore(app);\r\n            let userId = null;\r\n\r\n            \/\/ Fun\u00e7\u00e3o para extrair informa\u00e7\u00f5es da etiqueta\r\n            const extractLabelInfo = (code) => {\r\n                const info = {\r\n                    rawText: code,\r\n                    trackingNumber: '',\r\n                    orderNumber: '',\r\n                    customerName: '',\r\n                    address: '',\r\n                    postalCode: '',\r\n                    city: '',\r\n                    state: '',\r\n                    extraInfo: []\r\n                };\r\n\r\n                try {\r\n                    \/\/ Express\u00f5es regulares para identificar diferentes partes da etiqueta\r\n                    const patterns = {\r\n                        trackingNumber: \/[A-Z]{2}\\d{9}[A-Z]{2}|TBA[0-9]{12}\/i,\r\n                        orderNumber: \/\\b\\d{3}[-\\s]?\\d{7}[-\\s]?\\d{7}\\b|\\b\\d{19}\\b\/,\r\n                        postalCode: \/\\b\\d{5}-?\\d{3}\\b\/,\r\n                        state: \/\\b(AC|AL|AP|AM|BA|CE|DF|ES|GO|MA|MT|MS|MG|PA|PB|PR|PE|PI|RJ|RN|RS|RO|RR|SC|SP|SE|TO)\\b\/i\r\n                    };\r\n\r\n                    const trackingMatch = code.match(patterns.trackingNumber);\r\n                    if (trackingMatch) info.trackingNumber = trackingMatch[0];\r\n                    const orderMatch = code.match(patterns.orderNumber);\r\n                    if (orderMatch) info.orderNumber = orderMatch[0];\r\n                    const postalMatch = code.match(patterns.postalCode);\r\n                    if (postalMatch) info.postalCode = postalMatch[0];\r\n                    const stateMatch = code.match(patterns.state);\r\n                    if (stateMatch) info.state = stateMatch[0].toUpperCase();\r\n\r\n                    const lines = code.split(\/[\\n\\r]+\/);\r\n                    lines.forEach((line, index) => {\r\n                        const cleanLine = line.replace(\/[0-9!@#$%^&*(),.?\":{}|<>]\/g, '').trim();\r\n                        if (cleanLine.length > 3 && !\/^(Amazon|AMAZON)\/i.test(cleanLine)) {\r\n                            if (!info.customerName) {\r\n                                info.customerName = cleanLine;\r\n                            } else if (!info.address && cleanLine.length > 10) {\r\n                                info.address = cleanLine;\r\n                            } else {\r\n                                info.extraInfo.push(cleanLine);\r\n                            }\r\n                        }\r\n                    });\r\n\r\n                    if (info.state && info.address) {\r\n                        const cityMatch = info.address.match(new RegExp(`([\\\\w\\\\s]+)\\\\s*[-,]?\\\\s*${info.state}`, 'i'));\r\n                        if (cityMatch) {\r\n                            info.city = cityMatch[1].trim();\r\n                        }\r\n                    }\r\n                } catch (error) {\r\n                    console.error('Erro ao extrair informa\u00e7\u00f5es da etiqueta:', error);\r\n                }\r\n\r\n                return info;\r\n            };\r\n\r\n            \/\/ --- FUN\u00c7\u00d5ES DE AUTENTICA\u00c7\u00c3O FIREBASE ---\r\n            function setupAuthListener() {\r\n                updateConnectionStatus('connecting', 'Conectando ao Firebase...');\r\n                \r\n                onAuthStateChanged(auth, (user) => {\r\n                    if (user) {\r\n                        \/\/ Usu\u00e1rio logado\r\n                        firebaseUser = user;\r\n                        currentUser = user.email;\r\n                        userId = user.uid;\r\n                        \r\n                        updateConnectionStatus('online', `Conectado: ${user.email}`);\r\n                        showMainApp();\r\n                        setupFirestoreListener();\r\n                        initializeScanner();\r\n                    } else {\r\n                        \/\/ Usu\u00e1rio deslogado\r\n                        firebaseUser = null;\r\n                        currentUser = null;\r\n                        userId = null;\r\n                        \r\n                        updateConnectionStatus('offline', 'Desconectado - Fa\u00e7a login');\r\n                        showLoginScreen();\r\n                        \r\n                        if (unsubscribeFromFirestore) {\r\n                            unsubscribeFromFirestore();\r\n                        }\r\n                    }\r\n                });\r\n            }\r\n\r\n            async function loginWithEmail(email, password) {\r\n                try {\r\n                    updateConnectionStatus('connecting', 'Autenticando...');\r\n                    \r\n                    \/\/ Verificar se Firebase est\u00e1 dispon\u00edvel\r\n                    if (!auth) {\r\n                        throw new Error('Firebase n\u00e3o inicializado');\r\n                    }\r\n\r\n                    await signInWithEmailAndPassword(auth, email, password);\r\n                    return { success: true };\r\n                } catch (error) {\r\n                    console.error('Erro no login Firebase:', error);\r\n                    \r\n                    \/\/ Se for erro de permiss\u00e3o, tentar modo offline\r\n                    if (error.code === 'permission-denied' || \r\n                        error.message.includes('Missing or insufficient permissions') ||\r\n                        error.code === 'unavailable') {\r\n                        \r\n                        console.log('Tentando modo offline devido a erro de permiss\u00e3o');\r\n                        return await loginOffline(email, password);\r\n                    }\r\n                    \r\n                    let message = 'Erro no login';\r\n                    \r\n                    switch (error.code) {\r\n                        case 'auth\/user-not-found':\r\n                            message = 'Usu\u00e1rio n\u00e3o encontrado';\r\n                            break;\r\n                        case 'auth\/wrong-password':\r\n                            message = 'Senha incorreta';\r\n                            break;\r\n                        case 'auth\/invalid-email':\r\n                            message = 'Email inv\u00e1lido';\r\n                            break;\r\n                        case 'auth\/user-disabled':\r\n                            message = 'Usu\u00e1rio desabilitado';\r\n                            break;\r\n                        case 'auth\/too-many-requests':\r\n                            message = 'Muitas tentativas. Tente novamente mais tarde';\r\n                            break;\r\n                        default:\r\n                            message = error.message;\r\n                    }\r\n                    \r\n                    return { success: false, error: message };\r\n                }\r\n            }\r\n\r\n            \/\/ Login offline como fallback\r\n            async function loginOffline(email, password) {\r\n                try {\r\n                    \/\/ Verificar credenciais locais\r\n                    const localUsers = JSON.parse(localStorage.getItem('localUsers') || '{}');\r\n                    \r\n                    if (localUsers[email] && localUsers[email] === password) {\r\n                        currentUser = email;\r\n                        userId = `offline_${btoa(email)}`; \/\/ ID \u00fanico para modo offline\r\n                        \r\n                        updateConnectionStatus('warning', `Modo offline: ${email}`);\r\n                        showMainApp();\r\n                        loadLocalData();\r\n                        \r\n                        return { success: true };\r\n                    } else {\r\n                        \/\/ Se n\u00e3o existir, criar usu\u00e1rio local automaticamente\r\n                        localUsers[email] = password;\r\n                        localStorage.setItem('localUsers', JSON.stringify(localUsers));\r\n                        \r\n                        currentUser = email;\r\n                        userId = `offline_${btoa(email)}`;\r\n                        \r\n                        updateConnectionStatus('warning', `Modo offline: ${email} (conta criada localmente)`);\r\n                        showMainApp();\r\n                        loadLocalData();\r\n                        \r\n                        return { success: true };\r\n                    }\r\n                } catch (error) {\r\n                    return { success: false, error: 'Erro no modo offline: ' + error.message };\r\n                }\r\n            }\r\n\r\n            async function createAccount(email, password) {\r\n                try {\r\n                    updateConnectionStatus('connecting', 'Criando conta...');\r\n                    \r\n                    if (!auth || !db) {\r\n                        throw new Error('Firebase n\u00e3o inicializado');\r\n                    }\r\n\r\n                    const userCredential = await createUserWithEmailAndPassword(auth, email, password);\r\n                    \r\n                    \/\/ Criar perfil inicial do usu\u00e1rio no Firestore\r\n                    await setDoc(doc(db, 'users', userCredential.user.uid), {\r\n                        email: email,\r\n                        createdAt: new Date().toISOString(),\r\n                        profile: {\r\n                            displayName: email.split('@')[0],\r\n                            role: 'user'\r\n                        }\r\n                    });\r\n                    \r\n                    return { success: true };\r\n                } catch (error) {\r\n                    console.error('Erro ao criar conta Firebase:', error);\r\n                    \r\n                    \/\/ Se for erro de permiss\u00e3o, criar conta offline\r\n                    if (error.code === 'permission-denied' || \r\n                        error.message.includes('Missing or insufficient permissions') ||\r\n                        error.code === 'unavailable') {\r\n                        \r\n                        console.log('Criando conta offline devido a erro de permiss\u00e3o');\r\n                        return await createAccountOffline(email, password);\r\n                    }\r\n                    \r\n                    let message = 'Erro ao criar conta';\r\n                    \r\n                    switch (error.code) {\r\n                        case 'auth\/email-already-in-use':\r\n                            message = 'Email j\u00e1 est\u00e1 em uso';\r\n                            break;\r\n                        case 'auth\/invalid-email':\r\n                            message = 'Email inv\u00e1lido';\r\n                            break;\r\n                        case 'auth\/weak-password':\r\n                            message = 'Senha muito fraca (m\u00ednimo 6 caracteres)';\r\n                            break;\r\n                        default:\r\n                            message = error.message;\r\n                    }\r\n                    \r\n                    return { success: false, error: message };\r\n                }\r\n            }\r\n\r\n            \/\/ Criar conta offline como fallback\r\n            async function createAccountOffline(email, password) {\r\n                try {\r\n                    const localUsers = JSON.parse(localStorage.getItem('localUsers') || '{}');\r\n                    \r\n                    if (localUsers[email]) {\r\n                        return { success: false, error: 'Email j\u00e1 est\u00e1 em uso (modo offline)' };\r\n                    }\r\n                    \r\n                    \/\/ Criar conta local\r\n                    localUsers[email] = password;\r\n                    localStorage.setItem('localUsers', JSON.stringify(localUsers));\r\n                    \r\n                    currentUser = email;\r\n                    userId = `offline_${btoa(email)}`;\r\n                    \r\n                    updateConnectionStatus('warning', `Conta criada (modo offline): ${email}`);\r\n                    showMainApp();\r\n                    loadLocalData();\r\n                    \r\n                    return { success: true };\r\n                } catch (error) {\r\n                    return { success: false, error: 'Erro ao criar conta offline: ' + error.message };\r\n                }\r\n            }\r\n\r\n            \/\/ Fun\u00e7\u00e3o para lidar com erros de Firestore\r\n            function handleFirestoreError(error, operation = 'opera\u00e7\u00e3o') {\r\n                console.error(`Erro Firestore (${operation}):`, error);\r\n                \r\n                if (error.code === 'permission-denied' || \r\n                    error.message.includes('Missing or insufficient permissions')) {\r\n                    \r\n                    updateConnectionStatus('warning', 'Permiss\u00f5es Firebase insuficientes - modo offline ativo');\r\n                    console.log('Switching to offline mode due to permission error');\r\n                    return true; \/\/ Indica que deve usar modo offline\r\n                }\r\n                \r\n                if (error.code === 'unavailable') {\r\n                    updateConnectionStatus('warning', 'Firebase indispon\u00edvel - modo offline ativo');\r\n                    return true;\r\n                }\r\n                \r\n                return false; \/\/ N\u00e3o \u00e9 erro de permiss\u00e3o\/conectividade\r\n            }\r\n\r\n            \/\/ Fun\u00e7\u00e3o segura para salvar dados (com fallback offline)\r\n            async function saveToFirestore(data) {\r\n                try {\r\n                    if (!db || !userId || userId.startsWith('offline_')) {\r\n                        throw new Error('Modo offline ativo');\r\n                    }\r\n\r\n                    const docRef = doc(collection(db, `users\/${userId}\/scannedCodes`));\r\n                    await setDoc(docRef, data);\r\n                    \r\n                    console.log('Dados salvos no Firestore:', docRef.id);\r\n                    return true;\r\n                } catch (error) {\r\n                    if (handleFirestoreError(error, 'salvar dados')) {\r\n                        \/\/ Fallback para localStorage\r\n                        saveToLocalStorage(data);\r\n                        return true;\r\n                    }\r\n                    \r\n                    console.error('Erro ao salvar no Firestore:', error);\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            \/\/ Fun\u00e7\u00e3o para salvar no localStorage como fallback\r\n            function saveToLocalStorage(data) {\r\n                try {\r\n                    const localKey = `scanHistory_${currentUser || 'anonymous'}`;\r\n                    const existingData = JSON.parse(localStorage.getItem(localKey) || '[]');\r\n                    existingData.push(data);\r\n                    localStorage.setItem(localKey, JSON.stringify(existingData));\r\n                    console.log('Dados salvos localmente');\r\n                } catch (error) {\r\n                    console.error('Erro ao salvar localmente:', error);\r\n                }\r\n            }\r\n\r\n            async function logout() {\r\n                try {\r\n                    await signOut(auth);\r\n                    updateConnectionStatus('offline', 'Desconectado');\r\n                } catch (error) {\r\n                    console.error('Erro no logout:', error);\r\n                }\r\n            }\r\n\r\n            function showLoginScreen() {\r\n                loginScreen.classList.remove('hidden');\r\n                mainApp.classList.add('hidden');\r\n                loginError.classList.add('hidden');\r\n                document.getElementById('email').value = '';\r\n                document.getElementById('password').value = '';\r\n            }\r\n\r\n            function showMainApp() {\r\n                loginScreen.classList.add('hidden');\r\n                mainApp.classList.remove('hidden');\r\n                \r\n                currentUserSpan.textContent = currentUser;\r\n                const sessionInfo = document.getElementById('session-info');\r\n                sessionInfo.textContent = `Logado: ${new Date().toLocaleString('pt-BR')}`;\r\n                \r\n                createAutoBackup();\r\n            }\r\n\r\n            function showLoginError(message, type = 'error') {\r\n                const loginError = document.getElementById('login-error');\r\n                loginError.textContent = message;\r\n                loginError.classList.remove('hidden', 'text-red-600', 'text-green-600');\r\n                \r\n                if (type === 'success') {\r\n                    loginError.classList.add('text-green-600');\r\n                } else {\r\n                    loginError.classList.add('text-red-600');\r\n                }\r\n                \r\n                \/\/ Auto-hide ap\u00f3s 5 segundos\r\n                setTimeout(() => {\r\n                    loginError.classList.add('hidden');\r\n                }, 5000);\r\n            }\r\n\r\n            function createAutoBackup() {\r\n                try {\r\n                    const backupData = {\r\n                        user: currentUser,\r\n                        timestamp: new Date().toISOString(),\r\n                        scanHistory: codes || [],\r\n                        returnHistory: []\r\n                    };\r\n\r\n                    const userReturnKey = `ocrReturnsHistory_${currentUser}`;\r\n                    const userReturns = localStorage.getItem(userReturnKey);\r\n                    if (userReturns) {\r\n                        backupData.returnHistory = JSON.parse(userReturns);\r\n                    }\r\n\r\n                    const backupKey = `backup_${currentUser}_${new Date().toISOString().split('T')[0]}`;\r\n                    localStorage.setItem(backupKey, JSON.stringify(backupData));\r\n\r\n                    cleanOldBackups();\r\n                } catch (error) {\r\n                    console.warn('Erro ao criar backup autom\u00e1tico:', error);\r\n                }\r\n            }\r\n\r\n            function cleanOldBackups() {\r\n                try {\r\n                    const keys = Object.keys(localStorage);\r\n                    const backupKeys = keys.filter(key => key.startsWith(`backup_${currentUser}_`));\r\n                    const cutoffDate = new Date();\r\n                    cutoffDate.setDate(cutoffDate.getDate() - 7);\r\n                    const cutoffStr = cutoffDate.toISOString().split('T')[0];\r\n\r\n                    backupKeys.forEach(key => {\r\n                        const dateStr = key.split('_').pop();\r\n                        if (dateStr < cutoffStr) {\r\n                            localStorage.removeItem(key);\r\n                        }\r\n                    });\r\n                } catch (error) {\r\n                    console.warn('Erro ao limpar backups antigos:', error);\r\n                }\r\n            }\r\n\r\n            \/\/ --- INICIALIZA\u00c7\u00c3O ---\r\n            function init() {\r\n                setupAuthListener();\r\n                setupEventListeners();\r\n            }\r\n\r\n            const initializeFirebase = async () => {\r\n                const firebaseConfig = {\r\n                    apiKey: \"AIzaSyALGpFQhozwLyl1TQ_B_xYSVHX0HJOCIJ0\",\r\n                    authDomain: \"coleta-d060e.firebaseapp.com\",\r\n                    projectId: \"coleta-d060e\",\r\n                    storageBucket: \"coleta-d060e.firebasestorage.app\",\r\n                    messagingSenderId: \"793652809237\",\r\n                    appId: \"1:793652809237:web:44dab696be77636040c81c\",\r\n                    measurementId: \"G-JLMSHS2D96\"\r\n                };\r\n\r\n                const authStatus = document.getElementById('auth-status');\r\n                updateConnectionStatus('connecting', 'Conectando ao Firebase...');\r\n\r\n                if (!firebaseConfig.apiKey || !firebaseConfig.appId) {\r\n                    updateConnectionStatus('error', 'Firebase n\u00e3o configurado - Usando modo offline');\r\n                    initializeOfflineMode();\r\n                    return;\r\n                }\r\n\r\n                try {\r\n                    const app = initializeApp(firebaseConfig);\r\n                    db = getFirestore(app);\r\n                    auth = getAuth(app);\r\n                    \r\n                    onAuthStateChanged(auth, user => {\r\n                        if (user) {\r\n                            userId = `${currentUser}_${user.uid}`;\r\n                            updateConnectionStatus('online', `Firebase conectado - Usu\u00e1rio: ${currentUser}`);\r\n                            setupFirestoreListener();\r\n                            initializeScanner();\r\n                        } else {\r\n                            updateConnectionStatus('connecting', 'Autenticando...');\r\n                            userId = null;\r\n                            if (unsubscribeFromFirestore) unsubscribeFromFirestore();\r\n                            loadLocalData();\r\n                        }\r\n                    });\r\n\r\n                    await signInAnonymously(auth);\r\n\r\n                } catch (error) {\r\n                    console.error(\"Erro na inicializa\u00e7\u00e3o do Firebase:\", error);\r\n                    updateConnectionStatus('warning', 'Firebase indispon\u00edvel - Modo offline ativo');\r\n                    initializeOfflineMode();\r\n                }\r\n            };\r\n\r\n            function initializeOfflineMode() {\r\n                console.log('Iniciando modo offline');\r\n                userId = `offline_${currentUser}_${Date.now()}`;\r\n                \r\n                updateConnectionStatus('offline', `Modo offline - Usu\u00e1rio: ${currentUser}`);\r\n                \r\n                loadLocalData();\r\n                initializeScanner();\r\n            }\r\n\r\n            function updateConnectionStatus(status, message) {\r\n                const authStatus = document.getElementById('auth-status');\r\n                const indicator = document.getElementById('connection-indicator');\r\n                \r\n                authStatus.textContent = message;\r\n                \r\n                \/\/ Remover todas as classes de cor\r\n                authStatus.classList.remove('text-red-500', 'text-green-600', 'text-yellow-600', 'text-blue-600', 'text-gray-400');\r\n                indicator.classList.remove('bg-red-500', 'bg-green-500', 'bg-yellow-500', 'bg-blue-500', 'bg-gray-400');\r\n                \r\n                switch(status) {\r\n                    case 'online':\r\n                        authStatus.classList.add('text-green-600');\r\n                        indicator.classList.add('bg-green-500');\r\n                        break;\r\n                    case 'offline':\r\n                        authStatus.classList.add('text-blue-600');\r\n                        indicator.classList.add('bg-blue-500');\r\n                        break;\r\n                    case 'error':\r\n                        authStatus.classList.add('text-red-500');\r\n                        indicator.classList.add('bg-red-500');\r\n                        break;\r\n                    case 'warning':\r\n                        authStatus.classList.add('text-yellow-600');\r\n                        indicator.classList.add('bg-yellow-500');\r\n                        break;\r\n                    default:\r\n                        authStatus.classList.add('text-gray-400');\r\n                        indicator.classList.add('bg-gray-400');\r\n                }\r\n            }\r\n\r\n            function loadLocalData() {\r\n                try {\r\n                    const localKey = `scanHistory_${currentUser}`;\r\n                    const localData = localStorage.getItem(localKey);\r\n                    \r\n                    if (localData) {\r\n                        codes = JSON.parse(localData);\r\n                        console.log(`Carregados ${codes.length} c\u00f3digos do armazenamento local`);\r\n                    } else {\r\n                        codes = [];\r\n                    }\r\n                    \r\n                    applyFiltersAndRender();\r\n                } catch (error) {\r\n                    console.error('Erro ao carregar dados locais:', error);\r\n                    codes = [];\r\n                    applyFiltersAndRender();\r\n                }\r\n            }\r\n\r\n            function initializeScanner() {\r\n                html5QrCode = new Html5Qrcode(\"reader\");\r\n                \r\n                const returnMode = document.getElementById('return-mode');\r\n                const scanContent = document.querySelectorAll('main')[0];\r\n                if (returnMode) returnMode.style.display = 'none';\r\n                if (scanContent) scanContent.style.display = 'grid';\r\n                \r\n                const scanModeBtn = document.getElementById('scan-mode-btn');\r\n                const returnModeBtn = document.getElementById('return-mode-btn');\r\n                if (scanModeBtn) {\r\n                    scanModeBtn.classList.add('bg-blue-500', 'text-white');\r\n                    scanModeBtn.classList.remove('bg-gray-200', 'text-gray-700');\r\n                }\r\n                if (returnModeBtn) {\r\n                    returnModeBtn.classList.add('bg-gray-200', 'text-gray-700');\r\n                    returnModeBtn.classList.remove('bg-blue-500', 'text-white');\r\n                }\r\n            }\r\n\r\n            const setupFirestoreListener = () => {\r\n                if (!userId || !db) return;\r\n                if (unsubscribeFromFirestore) unsubscribeFromFirestore();\r\n\r\n                try {\r\n                    const codesCollectionPath = `\/users\/${userId}\/scannedCodes`;\r\n                    const q = query(collection(db, codesCollectionPath), orderBy('timestamp', 'desc'));\r\n\r\n                    unsubscribeFromFirestore = onSnapshot(q, (querySnapshot) => {\r\n                        const firestoreCodes = [];\r\n                        querySnapshot.forEach((doc) => {\r\n                            firestoreCodes.push({ id: doc.id, ...doc.data() });\r\n                        });\r\n                        codes = firestoreCodes;\r\n                        applyFiltersAndRender();\r\n                        saveToLocalStorage(); \/\/ Backup local dos dados do Firebase\r\n                    }, (error) => {\r\n                        console.warn(\"Erro ao ouvir mudan\u00e7as no Firestore:\", error);\r\n                        const authStatus = document.getElementById('auth-status');\r\n                        authStatus.textContent = 'Firebase offline - Usando dados locais';\r\n                        authStatus.classList.add('text-yellow-600');\r\n                        \r\n                        \/\/ Fallback para dados locais\r\n                        loadLocalData();\r\n                    });\r\n                } catch (error) {\r\n                    console.warn(\"Erro ao configurar listener do Firestore:\", error);\r\n                    loadLocalData();\r\n                }\r\n            };\r\n            \r\n            \/\/ --- L\u00d3GICA DE MANIPULA\u00c7\u00c3O DE C\u00d3DIGOS (SCANNER) ---\r\n            const addCode = async (code, source) => {\r\n                if (!userId) {\r\n                    alert(\"Aguarde a inicializa\u00e7\u00e3o para adicionar c\u00f3digos.\");\r\n                    return;\r\n                }\r\n                const now = Date.now();\r\n                if (code === lastScannedCode && (now - lastScanTime) < DUPLICATE_TIMEOUT) {\r\n                    console.log(\"C\u00f3digo duplicado ignorado:\", code);\r\n                    return;\r\n                }\r\n                lastScannedCode = code;\r\n                lastScanTime = now;\r\n                \r\n                beepSound.currentTime = 0;\r\n                beepSound.play();\r\n                \r\n                scanFeedback.className = 'scan-feedback-flash';\r\n                setTimeout(() => { scanFeedback.className = ''; }, 400);\r\n\r\n                const labelInfo = extractLabelInfo(code);\r\n                \r\n                const overlay = document.createElement('div');\r\n                overlay.className = 'scan-code-overlay';\r\n                overlay.textContent = labelInfo.trackingNumber || code;\r\n                document.body.appendChild(overlay);\r\n                setTimeout(() => overlay.remove(), 1500);\r\n\r\n                const newCode = {\r\n                    id: `${userId}_${now}`, \/\/ ID \u00fanico\r\n                    text: code,\r\n                    timestamp: now,\r\n                    source: source,\r\n                    status: 'pending',\r\n                    scanTime: new Date().toLocaleTimeString('pt-BR'),\r\n                    scanDate: new Date().toLocaleDateString('pt-BR'),\r\n                    user: currentUser,\r\n                    ...labelInfo\r\n                };\r\n\r\n                \/\/ Adicionar ao array local primeiro\r\n                codes.unshift(newCode);\r\n                applyFiltersAndRender();\r\n\r\n                \/\/ Salvar no localStorage\r\n                saveToLocalStorage();\r\n\r\n                \/\/ Tentar salvar no Firebase com fallback\r\n                await saveToFirestore(newCode);\r\n            };\r\n\r\n            function saveToLocalStorage() {\r\n                try {\r\n                    const localKey = `scanHistory_${currentUser}`;\r\n                    localStorage.setItem(localKey, JSON.stringify(codes));\r\n                    console.log(`${codes.length} c\u00f3digos salvos localmente`);\r\n                } catch (error) {\r\n                    console.error(\"Erro ao salvar no localStorage:\", error);\r\n                }\r\n            }\r\n\r\n            const deleteCode = async (id) => {\r\n                if (!userId) return;\r\n                \r\n                \/\/ Remover do array local\r\n                codes = codes.filter(code => code.id !== id);\r\n                applyFiltersAndRender();\r\n                saveToLocalStorage();\r\n                \r\n                \/\/ Tentar deletar do Firebase se dispon\u00edvel\r\n                if (db && auth) {\r\n                    try {\r\n                        const docPath = `\/users\/${userId}\/scannedCodes\/${id}`;\r\n                        await deleteDoc(doc(db, docPath));\r\n                        console.log(\"C\u00f3digo removido do Firebase\");\r\n                    } catch (error) {\r\n                        console.warn(\"Erro ao deletar do Firebase (funcionando offline):\", error);\r\n                    }\r\n                }\r\n            };\r\n\r\n            const clearHistory = async () => {\r\n                if (!userId) return;\r\n                \r\n                \/\/ Limpar do array local\r\n                codes = [];\r\n                applyFiltersAndRender();\r\n                saveToLocalStorage();\r\n                \r\n                \/\/ Tentar limpar do Firebase se dispon\u00edvel\r\n                if (db && auth) {\r\n                    try {\r\n                        const codesCollectionPath = `\/users\/${userId}\/scannedCodes`;\r\n                        const codesCollectionRef = collection(db, codesCollectionPath);\r\n                        \r\n                        const querySnapshot = await getDocs(codesCollectionRef);\r\n                        if (!querySnapshot.empty) {\r\n                            const batch = writeBatch(db);\r\n                            querySnapshot.forEach(doc => {\r\n                                batch.delete(doc.ref);\r\n                            });\r\n                            await batch.commit();\r\n                            console.log(\"Hist\u00f3rico limpo no Firebase\");\r\n                        }\r\n                    } catch (error) {\r\n                        console.warn(\"Erro ao limpar hist\u00f3rico no Firebase (funcionando offline):\", error);\r\n                    }\r\n                }\r\n            };\r\n            \r\n            \/\/ --- RENDERIZA\u00c7\u00c3O E FILTROS (SCANNER) ---\r\n            const renderList = (codesToRender = codes) => {\r\n                scannedCodesList.innerHTML = '';\r\n                scanCountSpan.textContent = codes.length;\r\n\r\n                if (codesToRender.length === 0) {\r\n                    scannedCodesList.innerHTML = `<p class=\"text-center text-gray-500 py-8\">${codes.length > 0 ? 'Nenhum resultado para os filtros.' : 'Nenhum c\u00f3digo escaneado.'}<\/p>`;\r\n                    return;\r\n                }\r\n\r\n                let counter = 1;\r\n                codesToRender.forEach(code => {\r\n                    const listItem = document.createElement('div');\r\n                    listItem.className = 'flex items-center justify-between p-3 bg-gray-50 rounded-lg border';\r\n                    const date = new Date(code.timestamp);\r\n                    const formattedDate = `${date.toLocaleDateString('pt-BR')} ${date.toLocaleTimeString('pt-BR')}`;\r\n                    const sourceIcon = code.source === 'camera' \r\n                        ? '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"inline-block text-blue-500\"><path d=\"M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z\"><\/path><circle cx=\"12\" cy=\"13\" r=\"3\"><\/circle><\/svg>'\r\n                        : '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"inline-block text-green-500\"><path d=\"M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z\"><\/path><\/svg>';\r\n                    \r\n                    listItem.innerHTML = `\r\n                        <div class=\"flex items-center gap-3 flex-grow\">\r\n                            <span class=\"text-lg font-bold text-blue-600 min-w-[24px]\">${counter}.<\/span>\r\n                            <div class=\"flex-grow\">\r\n                                <div class=\"flex justify-between items-start\">\r\n                                    <p class=\"font-mono font-bold text-gray-900\">${code.trackingNumber || code.text}<\/p>\r\n                                    <span class=\"text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded\">${code.orderNumber || 'Sem pedido'}<\/span>\r\n                                <\/div>\r\n                                ${code.customerName ? `<p class=\"text-sm text-gray-700 mt-1\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"inline mr-1\"><path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"><\/path><circle cx=\"12\" cy=\"7\" r=\"4\"><\/circle><\/svg>${code.customerName}<\/p>` : ''}\r\n                                ${code.address ? `<p class=\"text-sm text-gray-600\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"inline mr-1\"><path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\"><\/path><circle cx=\"12\" cy=\"10\" r=\"3\"><\/circle><\/svg>${code.address}<\/p>` : ''}\r\n                                <div class=\"flex gap-2 mt-1\">\r\n                                    ${code.city ? `<span class=\"text-xs bg-gray-100 text-gray-600 px-2 py-1 rounded\">${code.city}<\/span>` : ''}\r\n                                    ${code.state ? `<span class=\"text-xs bg-gray-100 text-gray-600 px-2 py-1 rounded\">${code.state}<\/span>` : ''}\r\n                                    ${code.postalCode ? `<span class=\"text-xs bg-gray-100 text-gray-600 px-2 py-1 rounded\">${code.postalCode}<\/span>` : ''}\r\n                                <\/div>\r\n                                <p class=\"text-xs text-gray-500 mt-1\">${formattedDate} <span title=\"Origem: ${code.source}\">${sourceIcon}<\/span><\/p>\r\n                            <\/div>\r\n                        <\/div>\r\n                        <button data-id=\"${code.id}\" class=\"delete-btn ml-4 text-gray-400 hover:text-red-500 transition-colors p-2\">\r\n                            <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"><\/polyline><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"><\/path><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"><\/line><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"><\/line><\/svg>\r\n                        <\/button>\r\n                    `;\r\n                    counter++;\r\n                    scannedCodesList.appendChild(listItem);\r\n                });\r\n\r\n                document.querySelectorAll('.delete-btn').forEach(btn => {\r\n                    btn.addEventListener('click', (e) => {\r\n                        const id = e.currentTarget.getAttribute('data-id');\r\n                        deleteCode(id);\r\n                    });\r\n                });\r\n            };\r\n            \r\n            const applyFiltersAndRender = () => {\r\n                const searchTerm = searchInput.value.toLowerCase();\r\n                const startDate = startDateInput.value ? new Date(startDateInput.value).setHours(0, 0, 0, 0) : null;\r\n                const endDate = endDateInput.value ? new Date(endDateInput.value).setHours(23, 59, 59, 999) : null;\r\n\r\n                const filteredCodes = codes.filter(code => {\r\n                    const codeTimestamp = code.timestamp;\r\n                    const searchableFields = [code.text, code.trackingNumber, code.orderNumber, code.customerName, code.address, code.city, code.state, code.postalCode, ...(code.extraInfo || [])].filter(Boolean);\r\n                    const matchesSearch = searchTerm === '' || searchableFields.some(field => field.toLowerCase().includes(searchTerm));\r\n                    const matchesStartDate = !startDate || codeTimestamp >= startDate;\r\n                    const matchesEndDate = !endDate || codeTimestamp <= endDate;\r\n                    return matchesSearch && matchesStartDate && matchesEndDate;\r\n                });\r\n                renderList(filteredCodes);\r\n            };\r\n\r\n            \/\/ --- L\u00d3GICA DO SCANNER E PDF ---\r\n            const onScanSuccess = (decodedText, decodedResult) => addCode(decodedText, 'camera');\r\n            const onScanFailure = (error) => {};\r\n            const startCamera = () => {\r\n                cameraStatus.textContent = \"Iniciando c\u00e2mera...\";\r\n                const isMobile = window.innerWidth <= 768;\r\n                const config = {\r\n                    fps: 10,\r\n                    qrbox: isMobile ? { width: Math.min(250, window.innerWidth - 50), height: Math.min(250, window.innerWidth - 50) } : { width: 250, height: 250 },\r\n                    aspectRatio: isMobile ? 1.7777778 : undefined\r\n                };\r\n                html5QrCode.start({ facingMode: \"environment\" }, config, onScanSuccess, onScanFailure)\r\n                    .then(() => {\r\n                        cameraStatus.textContent = \"C\u00e2mera ativa. Aponte para um c\u00f3digo.\";\r\n                        startCameraBtn.classList.add('hidden');\r\n                        stopCameraBtn.classList.remove('hidden');\r\n                    }).catch(err => {\r\n                        cameraStatus.textContent = `Erro ao iniciar c\u00e2mera: ${err}`;\r\n                        alert(\"N\u00e3o foi poss\u00edvel acessar a c\u00e2mera. Verifique as permiss\u00f5es do navegador.\");\r\n                    });\r\n            };\r\n            const stopCamera = () => {\r\n                html5QrCode.stop().then(() => {\r\n                    cameraStatus.textContent = \"C\u00e2mera parada.\";\r\n                    startCameraBtn.classList.remove('hidden');\r\n                    stopCameraBtn.classList.add('hidden');\r\n                }).catch(err => {\r\n                    cameraStatus.textContent = \"C\u00e2mera j\u00e1 estava parada.\";\r\n                    startCameraBtn.classList.remove('hidden');\r\n                    stopCameraBtn.classList.add('hidden');\r\n                });\r\n            };\r\n            const exportPDF = () => {\r\n                if (!forceExportCheck.checked) {\r\n                    const cpf = cpfInput.value;\r\n                    if (!cpf || !\/^\\d{3}\\.\\d{3}\\.\\d{3}-\\d{2}$\/.test(cpf)) {\r\n                        alert(\"Por favor, insira um CPF v\u00e1lido no formato 000.000.000-00.\");\r\n                        return false;\r\n                    }\r\n                    const collectorName = document.getElementById('collector-name').value.trim();\r\n                    if (!collectorName) {\r\n                        alert(\"Por favor, digite o nome do coletor.\");\r\n                        return false;\r\n                    }\r\n                }\r\n                const filteredCodes = getFilteredCodes().filter(code => code.status === 'pending');\r\n                if (filteredCodes.length === 0) {\r\n                    alert(\"N\u00e3o h\u00e1 c\u00f3digos pendentes para exportar.\");\r\n                    return false;\r\n                }\r\n                const { jsPDF } = window.jspdf;\r\n                const doc = new jsPDF();\r\n                const headerText = \"Envio de encomenda Amazon dos seguintes codigo de rastreio\";\r\n                const dateTime = new Date().toLocaleString('pt-BR');\r\n                \r\n                doc.setFontSize(14);\r\n                doc.text(headerText, 10, 15);\r\n                doc.text(`Total de encomendas: ${filteredCodes.length}`, 10, 25);\r\n                doc.text(`Data\/Hora da Finaliza\u00e7\u00e3o: ${dateTime}`, 10, 35);\r\n                \r\n                doc.setFontSize(10);\r\n                let y = 45;\r\n                let counter = 1;\r\n                filteredCodes.forEach(code => {\r\n                    if (y > 280) { doc.addPage(); y = 15; }\r\n                    doc.text(`${counter}. ${code.text}`, 15, y);\r\n                    doc.text(`Hor\u00e1rio do Scan: ${code.scanTime}`, 120, y);\r\n                    y += 7;\r\n                    counter++;\r\n                });\r\n                y += 10;\r\n                if (y > 240) { doc.addPage(); y = 20; }\r\n                const today = new Date();\r\n                const formattedDate = today.toLocaleDateString('pt-BR');\r\n                const collectorName = document.getElementById('collector-name').value.trim();\r\n                doc.text(\"Nome do Coletor: \" + collectorName, 15, y + 25);\r\n                doc.text(`CPF: ${cpfInput.value || 'N\u00e3o informado'}`, 100, y + 25);\r\n                doc.text(`Data: ${formattedDate}`, 100, y + 30);\r\n                const start = startDateInput.value ? startDateInput.value.replace(\/-\/g, '') : 'inicio';\r\n                const end = endDateInput.value ? endDateInput.value.replace(\/-\/g, '') : 'fim';\r\n                const filename = `envio_amazon_${start}_to_${end}.pdf`;\r\n                \r\n                \/\/ Gerar PDF como base64 para envio via webhook\r\n                const pdfBase64 = doc.output('datauristring').split(',')[1];\r\n                \r\n                \/\/ Salvar PDF localmente tamb\u00e9m\r\n                doc.save(filename);\r\n\r\n                \/\/ Enviar dados para o webhook (incluindo o PDF)\r\n                try {\r\n                    const cpf = cpfInput.value;\r\n                    \r\n                    \/\/ Aguardar um momento para garantir que o PDF foi salvo, depois enviar\r\n                    setTimeout(async () => {\r\n                        console.log('Iniciando processo de envio para webhook...');\r\n                        \r\n                        \/\/ Teste opcional de conectividade (n\u00e3o bloqueia o envio)\r\n                        const isConnected = await testWebhookConnection();\r\n                        if (!isConnected) {\r\n                            console.warn('Teste de conectividade falhou, mas tentando envio mesmo assim...');\r\n                        }\r\n                        \r\n                        \/\/ Enviar dados\r\n                        await sendToWebhook(filename, filteredCodes, collectorName, cpf, pdfBase64);\r\n                    }, 1500);\r\n                } catch (error) {\r\n                    console.error('Erro no processo de envio:', error);\r\n                    alert(`PDF gerado com sucesso, mas houve erro no processo de envio.\\n\\nErro: ${error.message}\\n\\nO arquivo foi salvo localmente. Tente novamente.`);\r\n                }\r\n                \r\n                return true;\r\n            };\r\n            const getFilteredCodes = () => {\r\n                const searchTerm = searchInput.value.toLowerCase();\r\n                const startDate = startDateInput.value ? new Date(startDateInput.value).setHours(0, 0, 0, 0) : null;\r\n                const endDate = endDateInput.value ? new Date(endDateInput.value).setHours(23, 59, 59, 999) : null;\r\n                return codes.filter(code => {\r\n                    const codeTimestamp = code.timestamp;\r\n                    const matchesSearch = code.text.toLowerCase().includes(searchTerm);\r\n                    const matchesStartDate = !startDate || codeTimestamp >= startDate;\r\n                    const matchesEndDate = !endDate || codeTimestamp <= endDate;\r\n                    return matchesSearch && matchesStartDate && matchesEndDate;\r\n                });\r\n            }\r\n\r\n            \/\/ --- FUN\u00c7\u00d5ES DE ARQUIVAMENTO E EXPORTA\u00c7\u00c3O ---\r\n            \r\n            \/\/ Arquivar c\u00f3digos filtrados\r\n            const archiveFilteredCodes = async () => {\r\n                const filteredCodes = getFilteredCodes();\r\n                if (filteredCodes.length === 0) {\r\n                    alert(\"Nenhum c\u00f3digo para arquivar com os filtros atuais.\");\r\n                    return;\r\n                }\r\n\r\n                const confirmMessage = `Arquivar ${filteredCodes.length} c\u00f3digo(s) filtrado(s)?\\n\\nEles ser\u00e3o movidos para o arquivo e n\u00e3o aparecer\u00e3o mais na lista principal.`;\r\n                if (!confirm(confirmMessage)) return;\r\n\r\n                try {\r\n                    const archiveDate = new Date().toISOString();\r\n                    const archivedCodes = filteredCodes.map(code => ({\r\n                        ...code,\r\n                        status: 'archived',\r\n                        archivedAt: archiveDate,\r\n                        archiveNote: `Arquivado em ${new Date().toLocaleDateString('pt-BR')} \u00e0s ${new Date().toLocaleTimeString('pt-BR')}`\r\n                    }));\r\n\r\n                    \/\/ Salvar c\u00f3digos arquivados\r\n                    const archiveKey = `archived_${currentUser || 'anonymous'}_${Date.now()}`;\r\n                    localStorage.setItem(archiveKey, JSON.stringify(archivedCodes));\r\n\r\n                    \/\/ Remover c\u00f3digos arquivados da lista principal\r\n                    const archivedIds = filteredCodes.map(code => code.id);\r\n                    codes = codes.filter(code => !archivedIds.includes(code.id));\r\n\r\n                    \/\/ Atualizar Firebase se dispon\u00edvel\r\n                    if (db && userId && !userId.startsWith('offline_')) {\r\n                        for (const code of archivedCodes) {\r\n                            await saveToFirestore({...code, status: 'archived'});\r\n                        }\r\n                    }\r\n\r\n                    saveToLocalStorage();\r\n                    applyFiltersAndRender();\r\n                    \r\n                    alert(`${filteredCodes.length} c\u00f3digo(s) arquivado(s) com sucesso!`);\r\n                } catch (error) {\r\n                    console.error('Erro ao arquivar c\u00f3digos:', error);\r\n                    alert('Erro ao arquivar c\u00f3digos. Tente novamente.');\r\n                }\r\n            };\r\n\r\n            \/\/ Exportar c\u00f3digos filtrados para PDF\r\n            const exportFilteredToPDF = () => {\r\n                const filteredCodes = getFilteredCodes();\r\n                if (filteredCodes.length === 0) {\r\n                    alert(\"Nenhum c\u00f3digo para exportar com os filtros atuais.\");\r\n                    return;\r\n                }\r\n\r\n                const { jsPDF } = window.jspdf;\r\n                const doc = new jsPDF();\r\n                \r\n                \/\/ Cabe\u00e7alho\r\n                doc.setFontSize(16);\r\n                doc.text(\"Relat\u00f3rio de C\u00f3digos Escaneados (Filtrados)\", 10, 15);\r\n                \r\n                doc.setFontSize(12);\r\n                const dateTime = new Date().toLocaleString('pt-BR');\r\n                doc.text(`Data\/Hora da Exporta\u00e7\u00e3o: ${dateTime}`, 10, 25);\r\n                doc.text(`Total de c\u00f3digos: ${filteredCodes.length}`, 10, 35);\r\n                doc.text(`Usu\u00e1rio: ${currentUser || 'An\u00f4nimo'}`, 10, 45);\r\n\r\n                \/\/ Filtros aplicados\r\n                doc.setFontSize(10);\r\n                let y = 55;\r\n                doc.text(\"Filtros aplicados:\", 10, y);\r\n                y += 7;\r\n                if (searchInput.value) {\r\n                    doc.text(`\u2022 Busca: ${searchInput.value}`, 15, y);\r\n                    y += 5;\r\n                }\r\n                if (startDateInput.value) {\r\n                    doc.text(`\u2022 Data in\u00edcio: ${new Date(startDateInput.value).toLocaleDateString('pt-BR')}`, 15, y);\r\n                    y += 5;\r\n                }\r\n                if (endDateInput.value) {\r\n                    doc.text(`\u2022 Data fim: ${new Date(endDateInput.value).toLocaleDateString('pt-BR')}`, 15, y);\r\n                    y += 5;\r\n                }\r\n                \r\n                y += 10;\r\n                \r\n                \/\/ Lista de c\u00f3digos\r\n                doc.setFontSize(12);\r\n                doc.text(\"Lista de C\u00f3digos:\", 10, y);\r\n                y += 10;\r\n\r\n                doc.setFontSize(9);\r\n                let counter = 1;\r\n                \r\n                filteredCodes.forEach(code => {\r\n                    if (y > 280) { \r\n                        doc.addPage(); \r\n                        y = 15; \r\n                    }\r\n                    \r\n                    doc.text(`${counter}. ${code.text}`, 10, y);\r\n                    doc.text(`${code.scanDate} ${code.scanTime}`, 120, y);\r\n                    doc.text(code.source || 'N\/A', 180, y);\r\n                    \r\n                    y += 6;\r\n                    \r\n                    \/\/ Informa\u00e7\u00f5es adicionais se dispon\u00edveis\r\n                    if (code.trackingNumber) {\r\n                        doc.text(`   Rastreio: ${code.trackingNumber}`, 15, y);\r\n                        y += 4;\r\n                    }\r\n                    if (code.customerName) {\r\n                        doc.text(`   Cliente: ${code.customerName}`, 15, y);\r\n                        y += 4;\r\n                    }\r\n                    \r\n                    y += 2;\r\n                    counter++;\r\n                });\r\n\r\n                \/\/ Rodap\u00e9\r\n                if (y > 250) { \r\n                    doc.addPage(); \r\n                    y = 15; \r\n                }\r\n                y += 10;\r\n                doc.setFontSize(8);\r\n                doc.text(`Relat\u00f3rio gerado pelo Scanner Amazon - ${dateTime}`, 10, y);\r\n\r\n                \/\/ Nome do arquivo\r\n                const startStr = startDateInput.value ? startDateInput.value.replace(\/-\/g, '') : 'inicio';\r\n                const endStr = endDateInput.value ? endDateInput.value.replace(\/-\/g, '') : 'fim';\r\n                const filename = `relatorio_filtrado_${startStr}_a_${endStr}.pdf`;\r\n                \r\n                doc.save(filename);\r\n                alert(`Relat\u00f3rio PDF exportado: ${filename}`);\r\n            };\r\n\r\n            \/\/ Exportar todos os c\u00f3digos para PDF\r\n            const exportAllToPDF = () => {\r\n                if (codes.length === 0) {\r\n                    alert(\"Nenhum c\u00f3digo para exportar.\");\r\n                    return;\r\n                }\r\n\r\n                const { jsPDF } = window.jspdf;\r\n                const doc = new jsPDF();\r\n                \r\n                \/\/ Cabe\u00e7alho\r\n                doc.setFontSize(16);\r\n                doc.text(\"Relat\u00f3rio Completo de C\u00f3digos Escaneados\", 10, 15);\r\n                \r\n                doc.setFontSize(12);\r\n                const dateTime = new Date().toLocaleString('pt-BR');\r\n                doc.text(`Data\/Hora da Exporta\u00e7\u00e3o: ${dateTime}`, 10, 25);\r\n                doc.text(`Total de c\u00f3digos: ${codes.length}`, 10, 35);\r\n                doc.text(`Usu\u00e1rio: ${currentUser || 'An\u00f4nimo'}`, 10, 45);\r\n\r\n                \/\/ Estat\u00edsticas\r\n                const pendingCount = codes.filter(c => c.status === 'pending').length;\r\n                const archivedCount = codes.filter(c => c.status === 'archived').length;\r\n                \r\n                doc.setFontSize(10);\r\n                doc.text(`\u2022 Pendentes: ${pendingCount}`, 15, 55);\r\n                doc.text(`\u2022 Arquivados: ${archivedCount}`, 15, 62);\r\n                \r\n                let y = 75;\r\n                \r\n                \/\/ Lista de c\u00f3digos\r\n                doc.setFontSize(12);\r\n                doc.text(\"Lista Completa de C\u00f3digos:\", 10, y);\r\n                y += 10;\r\n\r\n                doc.setFontSize(9);\r\n                let counter = 1;\r\n                \r\n                codes.forEach(code => {\r\n                    if (y > 280) { \r\n                        doc.addPage(); \r\n                        y = 15; \r\n                    }\r\n                    \r\n                    const statusIcon = code.status === 'archived' ? '\ud83d\udcc1' : '\ud83d\udce6';\r\n                    doc.text(`${counter}. ${statusIcon} ${code.text}`, 10, y);\r\n                    doc.text(`${code.scanDate} ${code.scanTime}`, 120, y);\r\n                    doc.text(code.source || 'manual', 180, y);\r\n                    \r\n                    y += 6;\r\n                    counter++;\r\n                });\r\n\r\n                \/\/ Rodap\u00e9\r\n                if (y > 250) { \r\n                    doc.addPage(); \r\n                    y = 15; \r\n                }\r\n                y += 10;\r\n                doc.setFontSize(8);\r\n                doc.text(`Relat\u00f3rio completo gerado pelo Scanner Amazon - ${dateTime}`, 10, y);\r\n\r\n                const filename = `relatorio_completo_${new Date().toISOString().split('T')[0].replace(\/-\/g, '')}.pdf`;\r\n                doc.save(filename);\r\n                alert(`Relat\u00f3rio completo exportado: ${filename}`);\r\n            };\r\n\r\n            \/\/ Visualizar c\u00f3digos arquivados\r\n            const viewArchivedCodes = () => {\r\n                try {\r\n                    const archivedKeys = Object.keys(localStorage).filter(key => \r\n                        key.startsWith(`archived_${currentUser || 'anonymous'}_`)\r\n                    );\r\n\r\n                    if (archivedKeys.length === 0) {\r\n                        alert(\"Nenhum c\u00f3digo arquivado encontrado.\");\r\n                        return;\r\n                    }\r\n\r\n                    let allArchived = [];\r\n                    archivedKeys.forEach(key => {\r\n                        const archived = JSON.parse(localStorage.getItem(key) || '[]');\r\n                        allArchived = allArchived.concat(archived);\r\n                    });\r\n\r\n                    if (allArchived.length === 0) {\r\n                        alert(\"Nenhum c\u00f3digo arquivado encontrado.\");\r\n                        return;\r\n                    }\r\n\r\n                    \/\/ Criar modal para exibir c\u00f3digos arquivados\r\n                    const modal = document.createElement('div');\r\n                    modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50';\r\n                    modal.innerHTML = `\r\n                        <div class=\"bg-white rounded-lg p-6 max-w-4xl max-h-96 overflow-y-auto m-4\">\r\n                            <div class=\"flex justify-between items-center mb-4\">\r\n                                <h3 class=\"text-lg font-bold\">C\u00f3digos Arquivados (${allArchived.length})<\/h3>\r\n                                <button id=\"close-archived-modal\" class=\"text-gray-500 hover:text-gray-700 text-xl\">&times;<\/button>\r\n                            <\/div>\r\n                            <div class=\"space-y-2 max-h-64 overflow-y-auto\">\r\n                                ${allArchived.map((code, index) => `\r\n                                    <div class=\"border p-3 rounded bg-gray-50\">\r\n                                        <div class=\"flex justify-between\">\r\n                                            <span class=\"font-mono text-sm\">${code.text}<\/span>\r\n                                            <span class=\"text-xs text-gray-500\">${code.scanDate} ${code.scanTime}<\/span>\r\n                                        <\/div>\r\n                                        <div class=\"text-xs text-gray-600 mt-1\">\r\n                                            ${code.archiveNote || 'Arquivado'}\r\n                                        <\/div>\r\n                                    <\/div>\r\n                                `).join('')}\r\n                            <\/div>\r\n                            <div class=\"mt-4 flex gap-2\">\r\n                                <button id=\"export-archived-pdf\" class=\"bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600\">\r\n                                    Exportar PDF\r\n                                <\/button>\r\n                                <button id=\"restore-archived\" class=\"bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600\">\r\n                                    Restaurar Todos\r\n                                <\/button>\r\n                                <button id=\"delete-archived\" class=\"bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600\">\r\n                                    Excluir Permanentemente\r\n                                <\/button>\r\n                            <\/div>\r\n                        <\/div>\r\n                    `;\r\n\r\n                    document.body.appendChild(modal);\r\n\r\n                    \/\/ Event listeners do modal\r\n                    document.getElementById('close-archived-modal').onclick = () => modal.remove();\r\n                    modal.onclick = (e) => { if (e.target === modal) modal.remove(); };\r\n\r\n                    document.getElementById('export-archived-pdf').onclick = () => {\r\n                        exportArchivedToPDF(allArchived);\r\n                        modal.remove();\r\n                    };\r\n\r\n                    document.getElementById('restore-archived').onclick = () => {\r\n                        if (confirm(`Restaurar todos os ${allArchived.length} c\u00f3digos arquivados?`)) {\r\n                            restoreArchivedCodes(allArchived, archivedKeys);\r\n                            modal.remove();\r\n                        }\r\n                    };\r\n\r\n                    document.getElementById('delete-archived').onclick = () => {\r\n                        if (confirm(`ATEN\u00c7\u00c3O: Excluir permanentemente todos os ${allArchived.length} c\u00f3digos arquivados?\\n\\nEsta a\u00e7\u00e3o n\u00e3o pode ser desfeita!`)) {\r\n                            deleteArchivedCodes(archivedKeys);\r\n                            modal.remove();\r\n                        }\r\n                    };\r\n\r\n                } catch (error) {\r\n                    console.error('Erro ao visualizar arquivados:', error);\r\n                    alert('Erro ao carregar c\u00f3digos arquivados.');\r\n                }\r\n            };\r\n\r\n            \/\/ Exportar c\u00f3digos arquivados para PDF\r\n            const exportArchivedToPDF = (archivedCodes) => {\r\n                const { jsPDF } = window.jspdf;\r\n                const doc = new jsPDF();\r\n                \r\n                doc.setFontSize(16);\r\n                doc.text(\"Relat\u00f3rio de C\u00f3digos Arquivados\", 10, 15);\r\n                \r\n                doc.setFontSize(12);\r\n                const dateTime = new Date().toLocaleString('pt-BR');\r\n                doc.text(`Data\/Hora da Exporta\u00e7\u00e3o: ${dateTime}`, 10, 25);\r\n                doc.text(`Total de c\u00f3digos arquivados: ${archivedCodes.length}`, 10, 35);\r\n                doc.text(`Usu\u00e1rio: ${currentUser || 'An\u00f4nimo'}`, 10, 45);\r\n\r\n                let y = 60;\r\n                doc.setFontSize(9);\r\n                let counter = 1;\r\n                \r\n                archivedCodes.forEach(code => {\r\n                    if (y > 280) { \r\n                        doc.addPage(); \r\n                        y = 15; \r\n                    }\r\n                    \r\n                    doc.text(`${counter}. \ud83d\udcc1 ${code.text}`, 10, y);\r\n                    doc.text(`${code.scanDate} ${code.scanTime}`, 120, y);\r\n                    y += 6;\r\n                    if (code.archiveNote) {\r\n                        doc.text(`   ${code.archiveNote}`, 15, y);\r\n                        y += 4;\r\n                    }\r\n                    y += 2;\r\n                    counter++;\r\n                });\r\n\r\n                const filename = `codigos_arquivados_${new Date().toISOString().split('T')[0].replace(\/-\/g, '')}.pdf`;\r\n                doc.save(filename);\r\n                alert(`Relat\u00f3rio de arquivados exportado: ${filename}`);\r\n            };\r\n\r\n            \/\/ Restaurar c\u00f3digos arquivados\r\n            const restoreArchivedCodes = (archivedCodes, archiveKeys) => {\r\n                try {\r\n                    \/\/ Restaurar c\u00f3digos para a lista principal\r\n                    const restoredCodes = archivedCodes.map(code => ({\r\n                        ...code,\r\n                        status: 'pending',\r\n                        restoredAt: new Date().toISOString()\r\n                    }));\r\n\r\n                    codes = codes.concat(restoredCodes);\r\n                    saveToLocalStorage();\r\n                    applyFiltersAndRender();\r\n\r\n                    \/\/ Remover dos arquivos\r\n                    archiveKeys.forEach(key => localStorage.removeItem(key));\r\n\r\n                    alert(`${archivedCodes.length} c\u00f3digo(s) restaurado(s) com sucesso!`);\r\n                } catch (error) {\r\n                    console.error('Erro ao restaurar c\u00f3digos:', error);\r\n                    alert('Erro ao restaurar c\u00f3digos.');\r\n                }\r\n            };\r\n\r\n            \/\/ Excluir c\u00f3digos arquivados permanentemente\r\n            const deleteArchivedCodes = (archiveKeys) => {\r\n                try {\r\n                    archiveKeys.forEach(key => localStorage.removeItem(key));\r\n                    alert('C\u00f3digos arquivados exclu\u00eddos permanentemente.');\r\n                } catch (error) {\r\n                    console.error('Erro ao excluir c\u00f3digos arquivados:', error);\r\n                    alert('Erro ao excluir c\u00f3digos arquivados.');\r\n                }\r\n            };\r\n\r\n            \/\/ --- FUN\u00c7\u00c3O DE RETRY COM BACKOFF ---\r\n            const retryWithBackoff = async (fn, maxRetries = 3, baseDelay = 1000) => {\r\n                for (let attempt = 1; attempt <= maxRetries; attempt++) {\r\n                    try {\r\n                        console.log(`Tentativa ${attempt}\/${maxRetries} de envio...`);\r\n                        return await fn();\r\n                    } catch (error) {\r\n                        console.warn(`Tentativa ${attempt} falhou:`, error.message);\r\n                        \r\n                        if (attempt === maxRetries) {\r\n                            throw error; \/\/ \u00daltima tentativa, rejeitar\r\n                        }\r\n                        \r\n                        \/\/ Verificar se \u00e9 um erro que vale a pena tentar novamente\r\n                        const retryableErrors = [\r\n                            'Failed to fetch',\r\n                            'NetworkError',\r\n                            'Timeout',\r\n                            'aborted',\r\n                            '500',\r\n                            '502',\r\n                            '503',\r\n                            '504',\r\n                            'ECONNRESET',\r\n                            'ENOTFOUND'\r\n                        ];\r\n                        \r\n                        const isRetryable = retryableErrors.some(err => \r\n                            error.message.includes(err) || error.name.includes(err)\r\n                        );\r\n                        \r\n                        if (!isRetryable) {\r\n                            console.log('Erro n\u00e3o \u00e9 recuper\u00e1vel, n\u00e3o tentando novamente');\r\n                            throw error;\r\n                        }\r\n                        \r\n                        \/\/ Delay exponencial: 1s, 2s, 4s...\r\n                        const delay = baseDelay * Math.pow(2, attempt - 1);\r\n                        console.log(`Aguardando ${delay}ms antes da pr\u00f3xima tentativa...`);\r\n                        await new Promise(resolve => setTimeout(resolve, delay));\r\n                    }\r\n                }\r\n            };\r\n\r\n            \/\/ --- FUN\u00c7\u00c3O DE VALIDA\u00c7\u00c3O DE DADOS ---\r\n            const validateDataForWebhook = (filteredCodes, collectorName, cpf, pdfBase64) => {\r\n                const errors = [];\r\n                \r\n                if (!filteredCodes || !Array.isArray(filteredCodes) || filteredCodes.length === 0) {\r\n                    errors.push('Nenhum c\u00f3digo encontrado para envio');\r\n                }\r\n                \r\n                if (!collectorName || collectorName.trim().length === 0) {\r\n                    errors.push('Nome do coletor n\u00e3o informado');\r\n                }\r\n                \r\n                if (!cpf || cpf.trim().length === 0) {\r\n                    errors.push('CPF n\u00e3o informado');\r\n                }\r\n                \r\n                if (!pdfBase64 || pdfBase64.length === 0) {\r\n                    errors.push('Arquivo PDF n\u00e3o foi gerado corretamente');\r\n                }\r\n                \r\n                \/\/ Validar se os c\u00f3digos t\u00eam conte\u00fado v\u00e1lido\r\n                const invalidCodes = filteredCodes.filter(code => !code.text || code.text.trim().length === 0);\r\n                if (invalidCodes.length > 0) {\r\n                    errors.push(`${invalidCodes.length} c\u00f3digo(s) sem conte\u00fado v\u00e1lido`);\r\n                }\r\n                \r\n                return errors;\r\n            };\r\n\r\n            \/\/ --- FUN\u00c7\u00c3O DE TESTE DE CONECTIVIDADE MELHORADA ---\r\n            const testWebhookConnection = async () => {\r\n                try {\r\n                    const testUrl = 'https:\/\/n8n.zapnacional.com.br\/webhook-test\/09a47025-8cbb-412c-bb39-7824e3a72a44';\r\n                    console.log('Testando conectividade com webhook...');\r\n                    \r\n                    \/\/ M\u00faltiplos testes para verificar conectividade\r\n                    const tests = [\r\n                        \/\/ Teste 1: Ping simples ao dom\u00ednio\r\n                        async () => {\r\n                            const controller = new AbortController();\r\n                            const timeoutId = setTimeout(() => controller.abort(), 3000);\r\n                            \r\n                            try {\r\n                                const response = await fetch('https:\/\/n8n.zapnacional.com.br\/webhook-test\/09a47025-8cbb-412c-bb39-7824e3a72a44', {\r\n                                    method: 'HEAD',\r\n                                    mode: 'no-cors',\r\n                                    signal: controller.signal\r\n                                });\r\n                                clearTimeout(timeoutId);\r\n                                return true;\r\n                            } catch (error) {\r\n                                clearTimeout(timeoutId);\r\n                                return false;\r\n                            }\r\n                        },\r\n                        \r\n                        \/\/ Teste 2: Teste do endpoint espec\u00edfico\r\n                        async () => {\r\n                            const controller = new AbortController();\r\n                            const timeoutId = setTimeout(() => controller.abort(), 5000);\r\n                            \r\n                            try {\r\n                                const response = await fetch(testUrl, {\r\n                                    method: 'OPTIONS',\r\n                                    signal: controller.signal\r\n                                });\r\n                                clearTimeout(timeoutId);\r\n                                console.log('Teste endpoint - Status:', response.status);\r\n                                return response.status < 500; \/\/ Aceita at\u00e9 erros 4xx\r\n                            } catch (error) {\r\n                                clearTimeout(timeoutId);\r\n                                return false;\r\n                            }\r\n                        }\r\n                    ];\r\n                    \r\n                    \/\/ Executar testes em sequ\u00eancia\r\n                    for (const test of tests) {\r\n                        const result = await test();\r\n                        if (result) {\r\n                            console.log('Teste de conectividade passou');\r\n                            return true;\r\n                        }\r\n                    }\r\n                    \r\n                    console.warn('Todos os testes de conectividade falharam');\r\n                    return false;\r\n                    \r\n                } catch (error) {\r\n                    console.warn('Erro no teste de conectividade:', error.message);\r\n                    return false;\r\n                }\r\n            };\r\n\r\n            \/\/ --- FUN\u00c7\u00c3O DE REQUISI\u00c7\u00c3O HTTP ROBUSTA ---\r\n            const makeWebhookRequest = async (url, payload, timeoutMs = 45000) => {\r\n                const controller = new AbortController();\r\n                const timeoutId = setTimeout(() => {\r\n                    console.log('Timeout atingido, cancelando requisi\u00e7\u00e3o...');\r\n                    controller.abort();\r\n                }, timeoutMs);\r\n                \r\n                try {\r\n                    \/\/ Configurar headers robustos\r\n                    const headers = {\r\n                        'Content-Type': 'application\/json',\r\n                        'Accept': 'application\/json, text\/plain, *\/*',\r\n                        'User-Agent': 'Scanner-Amazon\/1.0',\r\n                        'Cache-Control': 'no-cache',\r\n                        'Pragma': 'no-cache'\r\n                    };\r\n                    \r\n                    \/\/ Adicionar headers extras para CORS e conectividade\r\n                    if (window.location.protocol === 'https:') {\r\n                        headers['X-Requested-With'] = 'XMLHttpRequest';\r\n                    }\r\n                    \r\n                    console.log('Fazendo requisi\u00e7\u00e3o para:', url);\r\n                    console.log('Headers:', headers);\r\n                    console.log('Payload size:', JSON.stringify(payload).length, 'chars');\r\n                    \r\n                    const response = await fetch(url, {\r\n                        method: 'POST',\r\n                        headers: headers,\r\n                        body: JSON.stringify(payload),\r\n                        signal: controller.signal,\r\n                        mode: 'cors',\r\n                        credentials: 'omit',\r\n                        redirect: 'follow'\r\n                    });\r\n                    \r\n                    clearTimeout(timeoutId);\r\n                    \r\n                    console.log('Resposta recebida:', {\r\n                        status: response.status,\r\n                        statusText: response.statusText,\r\n                        headers: Object.fromEntries(response.headers.entries()),\r\n                        url: response.url\r\n                    });\r\n                    \r\n                    \/\/ Tentar ler a resposta de forma robusta\r\n                    let responseData = '';\r\n                    try {\r\n                        responseData = await response.text();\r\n                        console.log('Conte\u00fado da resposta:', responseData);\r\n                    } catch (readError) {\r\n                        console.warn('Erro ao ler resposta:', readError.message);\r\n                        responseData = 'Erro ao ler resposta do servidor';\r\n                    }\r\n                    \r\n                    if (!response.ok) {\r\n                        throw new Error(`HTTP ${response.status}: ${response.statusText}${responseData ? '\\nDetalhes: ' + responseData : ''}`);\r\n                    }\r\n                    \r\n                    return { success: true, data: responseData, status: response.status };\r\n                    \r\n                } catch (error) {\r\n                    clearTimeout(timeoutId);\r\n                    \r\n                    if (error.name === 'AbortError') {\r\n                        throw new Error(`Timeout: Servidor n\u00e3o respondeu em ${timeoutMs\/1000} segundos`);\r\n                    }\r\n                    \r\n                    \/\/ Enriquecer erro com mais informa\u00e7\u00f5es\r\n                    if (error.message.includes('Failed to fetch')) {\r\n                        throw new Error('Erro de rede: N\u00e3o foi poss\u00edvel conectar ao servidor. Verifique sua conex\u00e3o com a internet.');\r\n                    }\r\n                    \r\n                    if (error.message.includes('NetworkError')) {\r\n                        throw new Error('Erro de rede: Problema de conectividade ou CORS.');\r\n                    }\r\n                    \r\n                    throw error;\r\n                }\r\n            };\r\n\r\n            \/\/ --- FUN\u00c7\u00c3O PARA ENVIO WEBHOOK ---\r\n            const sendToWebhook = async (pdfFilename, filteredCodes, collectorName, cpf, pdfBase64) => {\r\n                try {\r\n                    \/\/ Validar dados antes do envio\r\n                    const validationErrors = validateDataForWebhook(filteredCodes, collectorName, cpf, pdfBase64);\r\n                    if (validationErrors.length > 0) {\r\n                        throw new Error(`Dados inv\u00e1lidos:\\n\u2022 ${validationErrors.join('\\n\u2022 ')}`);\r\n                    }\r\n\r\n                    const webhookUrl = 'https:\/\/n8n.zapnacional.com.br\/webhook-test\/09a47025-8cbb-412c-bb39-7824e3a72a44';\r\n                    const dateTime = new Date().toLocaleString('pt-BR');\r\n                    \r\n                    \/\/ Verificar conectividade b\u00e1sica\r\n                    if (!navigator.onLine) {\r\n                        throw new Error('Sem conex\u00e3o com a internet. Verifique sua conex\u00e3o e tente novamente.');\r\n                    }\r\n                    \r\n                    console.log('Iniciando envio para webhook...', webhookUrl);\r\n                    \r\n                    \/\/ Preparar dados dos c\u00f3digos\r\n                    const codesData = filteredCodes.map(code => ({\r\n                        codigo: code.text || '',\r\n                        trackingNumber: code.trackingNumber || '',\r\n                        orderNumber: code.orderNumber || '',\r\n                        customerName: code.customerName || '',\r\n                        address: code.address || '',\r\n                        city: code.city || '',\r\n                        state: code.state || '',\r\n                        postalCode: code.postalCode || '',\r\n                        scanTime: code.scanTime || '',\r\n                        scanDate: code.scanDate || ''\r\n                    }));\r\n                    \r\n                    \/\/ Verificar tamanho do PDF (limite de ~5MB para melhor compatibilidade)\r\n                    const pdfSizeBytes = Math.round(pdfBase64.length * 0.75);\r\n                    const maxSizeBytes = 5 * 1024 * 1024; \/\/ 5MB para ser mais conservativo\r\n                    \r\n                    \/\/ Criar payload para o webhook\r\n                    const basePayload = {\r\n                        tipo: 'finalizacao_coleta',\r\n                        dados: {\r\n                            resumo: {\r\n                                totalCodigos: filteredCodes.length,\r\n                                dataHoraFinalizacao: dateTime,\r\n                                coletor: collectorName || 'N\u00e3o informado',\r\n                                cpf: cpf || 'N\u00e3o informado',\r\n                                arquivoPdf: pdfFilename,\r\n                                usuario: currentUser || 'An\u00f4nimo'\r\n                            },\r\n                            codigos: codesData,\r\n                            metadata: {\r\n                                sistemaOrigem: 'Scanner Amazon',\r\n                                versao: '1.0',\r\n                                timestamp: new Date().toISOString(),\r\n                                userAgent: navigator.userAgent,\r\n                                url: window.location.href\r\n                            }\r\n                        }\r\n                    };\r\n\r\n                    let payloadToSend;\r\n                    let pdfIncluded = false;\r\n                    \r\n                    if (pdfSizeBytes <= maxSizeBytes) {\r\n                        \/\/ PDF pequeno - incluir no payload\r\n                        payloadToSend = {\r\n                            ...basePayload,\r\n                            dados: {\r\n                                ...basePayload.dados,\r\n                                arquivo: {\r\n                                    nome: pdfFilename,\r\n                                    tipo: 'application\/pdf',\r\n                                    tamanho: pdfSizeBytes,\r\n                                    base64: pdfBase64\r\n                                }\r\n                            }\r\n                        };\r\n                        pdfIncluded = true;\r\n                        console.log('PDF inclu\u00eddo no payload (tamanho:', pdfSizeBytes, 'bytes)');\r\n                    } else {\r\n                        \/\/ PDF muito grande - enviar apenas metadados\r\n                        payloadToSend = {\r\n                            ...basePayload,\r\n                            dados: {\r\n                                ...basePayload.dados,\r\n                                arquivo: {\r\n                                    nome: pdfFilename,\r\n                                    tipo: 'application\/pdf',\r\n                                    tamanho: pdfSizeBytes,\r\n                                    observacao: `Arquivo muito grande (${Math.round(pdfSizeBytes\/1024\/1024)}MB) - salvo apenas localmente`\r\n                                }\r\n                            }\r\n                        };\r\n                        console.warn('PDF muito grande para envio via JSON. Enviando apenas metadados.');\r\n                    }\r\n                    \r\n                    console.log('Payload preparado - C\u00f3digos:', filteredCodes.length, '| PDF inclu\u00eddo:', pdfIncluded);\r\n                    \r\n                    \/\/ Usar fun\u00e7\u00e3o robusta com retry para enviar dados\r\n                    const response = await retryWithBackoff(async () => {\r\n                        return await makeWebhookRequest(webhookUrl, payloadToSend);\r\n                    }, 3);\r\n                    \r\n                    console.log('Resposta do webhook:', response);\r\n                    \r\n                    \/\/ Mostrar mensagem de sucesso\r\n                        const pdfStatusMsg = pdfIncluded \r\n                            ? `\ud83d\udcc4 PDF enviado via webhook: ${pdfFilename}\\n\ufffd Arquivo salvo localmente tamb\u00e9m`\r\n                            : `\ud83d\udcc4 PDF salvo localmente: ${pdfFilename}\\n\ufffd (Arquivo muito grande para envio via webhook)`;\r\n                            \r\n                        alert(`\u2705 Coleta finalizada com sucesso!\\n\\n` +\r\n                              `\ud83d\udccb Dados enviados para o sistema:\\n` +\r\n                              `\u2022 Total de c\u00f3digos: ${filteredCodes.length}\\n` +\r\n                              `\u2022 Coletor: ${collectorName}\\n` +\r\n                              `\u2022 Data\/Hora: ${dateTime}\\n\\n` +\r\n                              pdfStatusMsg);\r\n                        \r\n                        return true;\r\n                        \r\n                } catch (error) {\r\n                    console.error('Erro detalhado ao enviar para webhook:', {\r\n                        message: error.message,\r\n                        stack: error.stack,\r\n                        name: error.name,\r\n                        webhookUrl: 'https:\/\/n8n.zapnacional.com.br\/webhook-test\/09a47025-8cbb-412c-bb39-7824e3a72a44',\r\n                        timestamp: new Date().toISOString()\r\n                    });\r\n                    \r\n                    \/\/ Determinar tipo de erro para mensagem mais espec\u00edfica\r\n                    let errorMessage = 'Erro desconhecido';\r\n                    let errorDetails = '';\r\n                    \r\n                    if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {\r\n                        errorMessage = 'Erro de conectividade';\r\n                        errorDetails = 'Verifique sua conex\u00e3o com a internet e tente novamente.';\r\n                    } else if (error.message.includes('Timeout')) {\r\n                        errorMessage = 'Timeout de conex\u00e3o';\r\n                        errorDetails = 'O servidor demorou muito para responder. Tente novamente.';\r\n                    } else if (error.message.includes('404')) {\r\n                        errorMessage = 'Endpoint n\u00e3o encontrado';\r\n                        errorDetails = 'O sistema de destino pode estar em manuten\u00e7\u00e3o.';\r\n                    } else if (error.message.includes('500') || error.message.includes('502') || error.message.includes('503')) {\r\n                        errorMessage = 'Erro no servidor de destino';\r\n                        errorDetails = 'O sistema de destino est\u00e1 com problemas. Tente novamente em alguns minutos.';\r\n                    } else if (error.message.includes('401') || error.message.includes('403')) {\r\n                        errorMessage = 'Erro de autoriza\u00e7\u00e3o';\r\n                        errorDetails = 'Problema de permiss\u00f5es no sistema de destino.';\r\n                    } else if (error.message.includes('Dados inv\u00e1lidos') || error.message.includes('PDF n\u00e3o foi gerado')) {\r\n                        errorMessage = 'Erro nos dados';\r\n                        errorDetails = error.message;\r\n                    } else {\r\n                        errorMessage = 'Erro no envio';\r\n                        errorDetails = error.message || 'Detalhes n\u00e3o dispon\u00edveis';\r\n                    }\r\n                    \r\n                    \/\/ Mostrar erro detalhado para o usu\u00e1rio\r\n                    alert(`\u274c ${errorMessage}\\n\\n` +\r\n                          `${errorDetails}\\n\\n` +\r\n                          `\ud83d\udcc4 PDF salvo localmente: ${pdfFilename}\\n` +\r\n                          `\ud83d\udcbe Dados preservados no dispositivo\\n` +\r\n                          `\ud83d\udce4 O arquivo n\u00e3o foi enviado via webhook\\n\\n` +\r\n                          `\ud83d\udd04 Voc\u00ea pode tentar novamente ou entrar em contato com o suporte.\\n\\n` +\r\n                          `\ud83d\udd27 C\u00f3digo do erro: ${error.name || 'UNKNOWN'}`);\r\n                    \r\n                    return false;\r\n                }\r\n            };\r\n\r\n             \/\/ --- FUN\u00c7\u00d5ES DO MODO DE RETORNO (OCR) ---\r\n            const preprocessImage = (imageSrc) => {\r\n                return new Promise((resolve) => {\r\n                    const img = new Image();\r\n                    img.onload = () => {\r\n                        const canvas = document.createElement('canvas');\r\n                        const ctx = canvas.getContext('2d');\r\n                        canvas.width = img.width;\r\n                        canvas.height = img.height;\r\n                        \/\/ Aplicar pr\u00e9-processamento: escala de cinza e contraste\r\n                        ctx.filter = 'grayscale(1) contrast(1.5)';\r\n                        ctx.drawImage(img, 0, 0);\r\n                        resolve(canvas.toDataURL('image\/jpeg', 0.95));\r\n                    };\r\n                    img.src = imageSrc;\r\n                });\r\n            };\r\n            \r\n            const parseOcrText = (text) => {\r\n                const fields = {\r\n                    tracking_code: '',\r\n                    cep: '',\r\n                    phone: ''\r\n                };\r\n                \r\n                const patterns = {\r\n                    tracking_code: \/[A-Z]{2}\\d{9}[A-Z]{2}|TBA[0-9]{12}\/i,\r\n                    cep: \/\\b\\d{5}-?\\d{3}\\b\/,\r\n                    phone: \/\\(?\\d{2}\\)?\\s?\\d{4,5}-?\\d{4}\/\r\n                };\r\n                \r\n                const trackingMatch = text.match(patterns.tracking_code);\r\n                if (trackingMatch) fields.tracking_code = trackingMatch[0];\r\n                \r\n                const cepMatch = text.match(patterns.cep);\r\n                if (cepMatch) fields.cep = cepMatch[0];\r\n\r\n                const phoneMatch = text.match(patterns.phone);\r\n                if (phoneMatch) fields.phone = phoneMatch[0];\r\n\r\n                return fields;\r\n            };\r\n\r\n            const processImageForOCR = async (imageSrc) => {\r\n                reviewForm.classList.add('hidden');\r\n                ocrProgressSection.classList.remove('hidden');\r\n                ocrStatusP.textContent = 'Pr\u00e9-processando imagem...';\r\n                ocrProgressBar.style.width = '0%';\r\n\r\n                try {\r\n                    const processedImageSrc = await preprocessImage(imageSrc);\r\n\r\n                    const worker = await Tesseract.createWorker('por', 1, {\r\n                        logger: m => {\r\n                            if (m.status === 'recognizing text') {\r\n                                const progress = Math.round(m.progress * 100);\r\n                                ocrStatusP.textContent = `Lendo etiqueta... ${progress}%`;\r\n                                ocrProgressBar.style.width = `${progress}%`;\r\n                            }\r\n                        },\r\n                    });\r\n                    \r\n                    const { data: { text } } = await worker.recognize(processedImageSrc);\r\n                    \r\n                    \/\/ Exibir texto e campos parseados\r\n                    ocrResultTextarea.value = text;\r\n                    const parsedFields = parseOcrText(text);\r\n                    document.getElementById('field-tracking-code').value = parsedFields.tracking_code;\r\n                    document.getElementById('field-cep').value = parsedFields.cep;\r\n                    document.getElementById('field-phone').value = parsedFields.phone;\r\n\r\n                    ocrStatusP.textContent = 'Leitura conclu\u00edda. Revise os dados abaixo.';\r\n                    reviewForm.classList.remove('hidden');\r\n                    \r\n                    await worker.terminate();\r\n                } catch (error) {\r\n                    console.error('Erro no OCR:', error);\r\n                    ocrStatusP.textContent = 'Falha ao ler a etiqueta. Tente novamente.';\r\n                    const errorMessage = error ? (error.message || String(error)) : 'Erro desconhecido';\r\n                    alert('Erro no OCR: ' + errorMessage);\r\n                } finally {\r\n                    setTimeout(() => {\r\n                        ocrProgressSection.classList.add('hidden');\r\n                    }, 3000);\r\n                }\r\n            };\r\n\r\n            const startOcrCamera = async () => {\r\n                try {\r\n                    ocrStream = await navigator.mediaDevices.getUserMedia({ \r\n                        video: { \r\n                            facingMode: 'environment',\r\n                            width: { ideal: 1920 },\r\n                            height: { ideal: 1080 }\r\n                        } \r\n                    });\r\n                    \r\n                    ocrCameraVideo.srcObject = ocrStream;\r\n                    ocrCameraVideo.style.display = 'block';\r\n                    ocrCameraOverlay.style.display = 'flex';\r\n                    ocrCameraVideo.play();\r\n                    \r\n                    startOcrCameraBtn.classList.add('hidden');\r\n                    captureOcrBtn.classList.remove('hidden');\r\n                } catch (err) {\r\n                    console.error('Erro ao iniciar c\u00e2mera para OCR:', err);\r\n                    alert('N\u00e3o foi poss\u00edvel acessar a c\u00e2mera. Verifique as permiss\u00f5es.');\r\n                }\r\n            };\r\n\r\n            const stopOcrCamera = () => {\r\n                if (ocrStream) {\r\n                    ocrStream.getTracks().forEach(track => track.stop());\r\n                    ocrStream = null;\r\n                }\r\n                ocrCameraVideo.style.display = 'none';\r\n                ocrCameraOverlay.style.display = 'none';\r\n                startOcrCameraBtn.classList.remove('hidden');\r\n                captureOcrBtn.classList.add('hidden');\r\n            };\r\n\r\n            const captureOcrPhoto = () => {\r\n                const canvas = document.createElement('canvas');\r\n                const context = canvas.getContext('2d');\r\n\r\n                canvas.width = ocrCameraVideo.videoWidth;\r\n                canvas.height = ocrCameraVideo.videoHeight;\r\n                \r\n                context.drawImage(ocrCameraVideo, 0, 0, canvas.width, canvas.height);\r\n                \r\n                const imageDataUrl = canvas.toDataURL('image\/jpeg', 0.95);\r\n                \r\n                stopOcrCamera();\r\n                processImageForOCR(imageDataUrl);\r\n            };\r\n\r\n            const saveOcrReturn = async () => {\r\n                const nomeProduto = returnProductInput.value.trim();\r\n                const quantidade = parseInt(returnQuantityInput.value) || 1;\r\n\r\n                if (!nomeProduto) {\r\n                    alert('Por favor, informe o nome do produto.');\r\n                    return;\r\n                }\r\n                \r\n                const record = {\r\n                    id: `${currentUser}_${Date.now()}`, \/\/ ID \u00fanico baseado no usu\u00e1rio\r\n                    usuario: currentUser, \/\/ Registrar qual usu\u00e1rio fez o scan\r\n                    raw_text: ocrResultTextarea.value.trim(),\r\n                    fields: {\r\n                        tracking_code: document.getElementById('field-tracking-code').value,\r\n                        cep: document.getElementById('field-cep').value,\r\n                        phone: document.getElementById('field-phone').value,\r\n                    },\r\n                    nomeProduto,\r\n                    quantidade,\r\n                    dataHora: new Date().toISOString()\r\n                };\r\n\r\n                \/\/ Salvar localmente com chave espec\u00edfica do usu\u00e1rio\r\n                try {\r\n                    const storageKey = `ocrReturnsHistory_${currentUser}`;\r\n                    let history = JSON.parse(localStorage.getItem(storageKey)) || [];\r\n                    history.unshift(record);\r\n                    localStorage.setItem(storageKey, JSON.stringify(history));\r\n                    \r\n                    \/\/ Tamb\u00e9m manter um hist\u00f3rico geral para backup\r\n                    let generalHistory = JSON.parse(localStorage.getItem('ocrReturnsHistory_all')) || [];\r\n                    generalHistory.unshift(record);\r\n                    localStorage.setItem('ocrReturnsHistory_all', JSON.stringify(generalHistory));\r\n                    \r\n                    renderLocalHistoryTable();\r\n                } catch (error) {\r\n                    console.error('Erro ao salvar no localStorage:', error);\r\n                    alert('N\u00e3o foi poss\u00edvel salvar o registro localmente.');\r\n                }\r\n\r\n                \/\/ Enviar para webhook\r\n                try {\r\n                    const response = await fetch(WEBHOOK_URL, {\r\n                        method: 'POST',\r\n                        headers: { 'Content-Type': 'application\/json' },\r\n                        body: JSON.stringify({\r\n                            scan_id: record.id,\r\n                            user_id: currentUser,\r\n                            fields: record.fields,\r\n                            raw_text: record.raw_text,\r\n                            nome_produto: record.nomeProduto,\r\n                            quantidade: record.quantidade,\r\n                            data_hora: record.dataHora\r\n                        }),\r\n                    });\r\n                    if (!response.ok) throw new Error(`Webhook respondeu com status ${response.status}`);\r\n                    alert('Etiqueta salva e enviada com sucesso!');\r\n                } catch (error) {\r\n                    console.error('Erro ao enviar para o webhook:', error);\r\n                    alert(`O registro foi salvo localmente, mas falhou ao enviar para o servidor. Erro: ${error.message}`);\r\n                }\r\n\r\n                \/\/ Limpar formul\u00e1rio\r\n                reviewForm.classList.add('hidden');\r\n                ocrResultTextarea.value = '';\r\n                returnProductInput.value = '';\r\n                returnQuantityInput.value = '1';\r\n                document.getElementById('field-tracking-code').value = '';\r\n                document.getElementById('field-cep').value = '';\r\n                document.getElementById('field-phone').value = '';\r\n                ocrStatusP.textContent = '';\r\n            };\r\n\r\n            const renderLocalHistoryTable = () => {\r\n                const storageKey = currentUser ? `ocrReturnsHistory_${currentUser}` : 'ocrReturnsHistory_all';\r\n                const history = JSON.parse(localStorage.getItem(storageKey)) || [];\r\n                localReturnsHistoryTable.innerHTML = '';\r\n                \r\n                \/\/ Atualizar estat\u00edsticas\r\n                document.getElementById('return-count').textContent = history.length;\r\n                const userStatsElement = document.getElementById('user-stats');\r\n                if (currentUser) {\r\n                    const totalQuantity = history.reduce((sum, record) => sum + (record.quantidade || 0), 0);\r\n                    userStatsElement.textContent = `Total itens: ${totalQuantity}`;\r\n                } else {\r\n                    userStatsElement.textContent = '';\r\n                }\r\n\r\n                if (history.length === 0) {\r\n                    localReturnsHistoryTable.innerHTML = '<tr><td colspan=\"5\" class=\"text-center text-gray-500 py-4\">Nenhum retorno salvo para este usu\u00e1rio.<\/td><\/tr>';\r\n                    return;\r\n                }\r\n\r\n                history.forEach(record => {\r\n                    const row = document.createElement('tr');\r\n                    const formattedDate = new Date(record.dataHora).toLocaleString('pt-BR');\r\n                    \r\n                    row.innerHTML = `\r\n                        <td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">${formattedDate}<\/td>\r\n                        <td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-900\">${record.nomeProduto}<\/td>\r\n                        <td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">${record.fields.tracking_code || 'N\/A'}<\/td>\r\n                        <td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">${record.quantidade}<\/td>\r\n                        <td class=\"px-6 py-4 whitespace-nowrap text-sm text-gray-400\">${record.usuario || 'N\/A'}<\/td>\r\n                    `;\r\n                    localReturnsHistoryTable.appendChild(row);\r\n                });\r\n            };\r\n\r\n            const exportLocalHistory = () => {\r\n                const storageKey = currentUser ? `ocrReturnsHistory_${currentUser}` : 'ocrReturnsHistory_all';\r\n                const history = localStorage.getItem(storageKey) || '[]';\r\n                const blob = new Blob([history], { type: 'application\/json' });\r\n                const url = URL.createObjectURL(blob);\r\n                const a = document.createElement('a');\r\n                a.href = url;\r\n                const fileName = currentUser \r\n                    ? `historico_retornos_${currentUser}_${new Date().toISOString().split('T')[0]}.json`\r\n                    : `historico_retornos_todos_${new Date().toISOString().split('T')[0]}.json`;\r\n                a.download = fileName;\r\n                document.body.appendChild(a);\r\n                a.click();\r\n                document.body.removeChild(a);\r\n                URL.revokeObjectURL(url);\r\n            };\r\n\r\n            const switchMode = (mode) => {\r\n                currentMode = mode;\r\n                const scanModeBtn = document.getElementById('scan-mode-btn');\r\n                const returnModeBtn = document.getElementById('return-mode-btn');\r\n                const returnModeDiv = document.getElementById('return-mode');\r\n                const scanContent = document.querySelectorAll('main')[0];\r\n                const historySection = document.querySelector('section.bg-white');\r\n\r\n                if (mode === 'return') {\r\n                    if (scanContent) scanContent.style.display = 'none';\r\n                    if (historySection) historySection.style.display = 'none';\r\n                    if (returnModeDiv) returnModeDiv.style.display = 'block';\r\n                    \r\n                    if (scanModeBtn) {\r\n                        scanModeBtn.classList.remove('bg-blue-500', 'text-white');\r\n                        scanModeBtn.classList.add('bg-gray-200', 'text-gray-700');\r\n                    }\r\n                    if (returnModeBtn) {\r\n                        returnModeBtn.classList.remove('bg-gray-200', 'text-gray-700');\r\n                        returnModeBtn.classList.add('bg-blue-500', 'text-white');\r\n                    }\r\n                    renderLocalHistoryTable();\r\n                } else {\r\n                    if (scanContent) scanContent.style.display = 'grid';\r\n                    if (historySection) historySection.style.display = 'block';\r\n                    if (returnModeDiv) returnModeDiv.style.display = 'none';\r\n                    \r\n                    if (scanModeBtn) {\r\n                        scanModeBtn.classList.add('bg-blue-500', 'text-white');\r\n                        scanModeBtn.classList.remove('bg-gray-200', 'text-gray-700');\r\n                    }\r\n                    if (returnModeBtn) {\r\n                        returnModeBtn.classList.add('bg-gray-200', 'text-gray-700');\r\n                        returnModeBtn.classList.remove('bg-blue-500', 'text-white');\r\n                    }\r\n                    if (ocrStream) stopOcrCamera();\r\n                }\r\n            };\r\n\r\n            const setupEventListeners = () => {\r\n                \/\/ Listeners de Login Firebase\r\n                loginForm.addEventListener('submit', async (e) => {\r\n                    e.preventDefault();\r\n                    const email = document.getElementById('email').value.trim();\r\n                    const password = document.getElementById('password').value;\r\n                    \r\n                    if (!email || !password) {\r\n                        showLoginError('Por favor, preencha todos os campos');\r\n                        return;\r\n                    }\r\n                    \r\n                    const result = await loginWithEmail(email, password);\r\n                    if (result.success) {\r\n                        loginError.classList.add('hidden');\r\n                    } else {\r\n                        showLoginError(result.error);\r\n                    }\r\n                });\r\n\r\n                createAccountBtn.addEventListener('click', async () => {\r\n                    const email = document.getElementById('email').value.trim();\r\n                    const password = document.getElementById('password').value;\r\n                    \r\n                    if (!email || !password) {\r\n                        showLoginError('Por favor, preencha todos os campos');\r\n                        return;\r\n                    }\r\n                    \r\n                    if (password.length < 6) {\r\n                        showLoginError('A senha deve ter pelo menos 6 caracteres');\r\n                        return;\r\n                    }\r\n                    \r\n                    const result = await createAccount(email, password);\r\n                    if (result.success) {\r\n                        showLoginError('Conta criada com sucesso! Voc\u00ea foi logado automaticamente.', 'success');\r\n                    } else {\r\n                        showLoginError(result.error);\r\n                    }\r\n                });\r\n\r\n                logoutBtn.addEventListener('click', () => {\r\n                    if (confirm('Deseja realmente sair?')) {\r\n                        logout();\r\n                    }\r\n                });\r\n\r\n                \/\/ Listeners do modo Scanner\r\n                startCameraBtn.addEventListener('click', startCamera);\r\n                stopCameraBtn.addEventListener('click', stopCamera);\r\n                manualAddBtn.addEventListener('click', () => {\r\n                    const code = manualInput.value.trim();\r\n                    if (code) { addCode(code, 'manual'); manualInput.value = ''; }\r\n                });\r\n                manualInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') manualAddBtn.click(); });\r\n\r\n                \/\/ Listeners de troca de modo\r\n                document.getElementById('scan-mode-btn').addEventListener('click', () => switchMode('scan'));\r\n                document.getElementById('return-mode-btn').addEventListener('click', () => switchMode('return'));\r\n                \r\n                \/\/ Listeners do modo Retorno (OCR)\r\n                startOcrCameraBtn.addEventListener('click', startOcrCamera);\r\n                captureOcrBtn.addEventListener('click', captureOcrPhoto);\r\n                uploadOcrImageInput.addEventListener('change', (event) => {\r\n                    const file = event.target.files[0];\r\n                    if (file) {\r\n                        const reader = new FileReader();\r\n                        reader.onload = (e) => processImageForOCR(e.target.result);\r\n                        reader.readAsDataURL(file);\r\n                    }\r\n                });\r\n                saveOcrReturnBtn.addEventListener('click', saveOcrReturn);\r\n                exportLocalBtn.addEventListener('click', exportLocalHistory);\r\n                \r\n                \/\/ Modal handlers\r\n                const finishModal = document.getElementById('finish-modal');\r\n                document.getElementById('finish-collection-btn').addEventListener('click', () => {\r\n                    finishModal.classList.remove('hidden');\r\n                    finishModal.classList.add('flex');\r\n                    cpfInput.value = '';\r\n                    document.getElementById('collector-name').value = '';\r\n                    forceExportCheck.checked = false;\r\n                });\r\n                \r\n                document.getElementById('modal-cancel-btn').addEventListener('click', () => {\r\n                    finishModal.classList.add('hidden');\r\n                    finishModal.classList.remove('flex');\r\n                });\r\n                \r\n                finishModal.addEventListener('click', (e) => {\r\n                    if (e.target === finishModal) {\r\n                        finishModal.classList.add('hidden');\r\n                        finishModal.classList.remove('flex');\r\n                    }\r\n                });\r\n                \r\n                exportPdfBtn.addEventListener('click', async () => {\r\n                    if (exportPDF()) {\r\n                        const finishTime = new Date().toLocaleTimeString('pt-BR');\r\n                        const finishDate = new Date().toLocaleDateString('pt-BR');\r\n                        \r\n                        \/\/ Atualizar Firebase se dispon\u00edvel\r\n                        try {\r\n                            if (db && userId && !userId.startsWith('offline_')) {\r\n                                const batch = writeBatch(db);\r\n                                const codesCollectionPath = `\/users\/${userId}\/scannedCodes`;\r\n                                const pendingCodes = await getDocs(\r\n                                    query(collection(db, codesCollectionPath), where(\"status\", \"==\", \"pending\"))\r\n                                );\r\n                                \r\n                                pendingCodes.forEach(doc => {\r\n                                    batch.update(doc.ref, {\r\n                                        status: 'archived',\r\n                                        finishTime,\r\n                                        finishDate,\r\n                                        collectorCPF: cpfInput.value || 'N\u00e3o informado'\r\n                                    });\r\n                                });\r\n                                \r\n                                await batch.commit();\r\n                            }\r\n                        } catch (error) {\r\n                            console.error('Erro ao atualizar Firebase:', error);\r\n                        }\r\n                        \r\n                        finishModal.classList.add('hidden');\r\n                        finishModal.classList.remove('flex');\r\n                        \r\n                        \/\/ Mostrar mensagem de sucesso\r\n                        setTimeout(() => {\r\n                            alert('\u2705 Coleta finalizada!\\n\\n\ud83d\ude80 Dados sendo enviados para o sistema automaticamente.');\r\n                        }, 500);\r\n                    }\r\n                });\r\n\r\n                \/\/ Event listener removido - funcionalidade integrada ao bot\u00e3o \"Finalizar e Enviar\"\r\n                \/*\r\n                exportAndWhatsappBtn.addEventListener('click', async () => {\r\n                    if (exportPDFAndSendToWhatsApp()) {\r\n                        const finishTime = new Date().toLocaleTimeString('pt-BR');\r\n                        const finishDate = new Date().toLocaleDateString('pt-BR');\r\n                        \r\n                        \/\/ Atualizar Firebase se dispon\u00edvel\r\n                        try {\r\n                            if (db && userId && !userId.startsWith('offline_')) {\r\n                                const batch = writeBatch(db);\r\n                                const codesCollectionPath = `\/users\/${userId}\/scannedCodes`;\r\n                                const pendingCodes = await getDocs(\r\n                                    query(collection(db, codesCollectionPath), where(\"status\", \"==\", \"pending\"))\r\n                                );\r\n                                \r\n                                pendingCodes.forEach(doc => {\r\n                                    batch.update(doc.ref, {\r\n                                        status: 'archived',\r\n                                        finishTime,\r\n                                        finishDate,\r\n                                        collectorCPF: cpfInput.value || 'N\u00e3o informado'\r\n                                    });\r\n                                });\r\n                                \r\n                                await batch.commit();\r\n                            }\r\n                        } catch (error) {\r\n                            console.error('Erro ao atualizar Firebase:', error);\r\n                        }\r\n                        \r\n                        finishModal.classList.add('hidden');\r\n                        finishModal.classList.remove('flex');\r\n                        \r\n                        \/\/ Mostrar mensagem de sucesso\r\n                        setTimeout(() => {\r\n                            alert('\u2705 Coleta finalizada!\\n\\n\ufffd Dados sendo enviados para o sistema automaticamente.');\r\n                        }, 500);\r\n                    }\r\n                });\r\n                *\/\r\n\r\n                \/\/ Listeners gerais\r\n                clearHistoryBtn.addEventListener('click', () => {\r\n                    if (currentMode === 'scan') {\r\n                        if(confirm('Deseja apagar o hist\u00f3rico de coletas no Firebase para este usu\u00e1rio?')) clearHistory();\r\n                    } else {\r\n                        const message = currentUser \r\n                            ? `Deseja apagar o hist\u00f3rico de retornos do usu\u00e1rio \"${currentUser}\"? Esta a\u00e7\u00e3o n\u00e3o pode ser desfeita.`\r\n                            : 'Deseja apagar todo o hist\u00f3rico de retornos locais? Esta a\u00e7\u00e3o n\u00e3o pode ser desfeita.';\r\n                        if (confirm(message)) {\r\n                            const storageKey = currentUser ? `ocrReturnsHistory_${currentUser}` : 'ocrReturnsHistory_all';\r\n                            localStorage.removeItem(storageKey);\r\n                            renderLocalHistoryTable();\r\n                        }\r\n                    }\r\n                });\r\n                [searchInput, startDateInput, endDateInput].forEach(el => el.addEventListener('input', applyFiltersAndRender));\r\n                filterTodayBtn.addEventListener('click', () => {\r\n                    const today = new Date().toISOString().split('T')[0];\r\n                    startDateInput.value = today;\r\n                    endDateInput.value = today;\r\n                    applyFiltersAndRender();\r\n                });\r\n                clearFilterBtn.addEventListener('click', () => {\r\n                    searchInput.value = ''; startDateInput.value = ''; endDateInput.value = '';\r\n                    applyFiltersAndRender();\r\n                });\r\n\r\n                \/\/ Event listeners para arquivamento e exporta\u00e7\u00e3o\r\n                archiveFilteredBtn.addEventListener('click', archiveFilteredCodes);\r\n                exportFilteredPdfBtn.addEventListener('click', exportFilteredToPDF);\r\n                exportAllPdfBtn.addEventListener('click', exportAllToPDF);\r\n                viewArchivedBtn.addEventListener('click', viewArchivedCodes);\r\n\r\n                cpfInput.addEventListener('input', (e) => {\r\n                    let value = e.target.value.replace(\/\\D\/g, '');\r\n                    value = value.replace(\/(\\d{3})(\\d)\/, '$1.$2');\r\n                    value = value.replace(\/(\\d{3})(\\d)\/, '$1.$2');\r\n                    value = value.replace(\/(\\d{3})(\\d{1,2})$\/, '$1-$2');\r\n                    e.target.value = value;\r\n                });\r\n            }\r\n\r\n            \/\/ Inicia a aplica\u00e7\u00e3o\r\n            init();\r\n        });\r\n    <\/script>\r\n\r\n<\/body>\r\n<\/html>\r\n\"\r\n\r\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Scanner de Etiquetas &#8211; Amazon Scanner Amazon Fa\u00e7a login para acessar o painel Sistema H\u00edbrido Online\/Offline: Login: Use qualquer email e senha Novo usu\u00e1rio? Clique em &#8220;Criar Conta&#8221; Funciona sem internet: Dados salvos localmente Sincroniza\u00e7\u00e3o: Autom\u00e1tica quando Firebase dispon\u00edvel \u2705 Sistema inteligente que funciona mesmo sem permiss\u00f5es Firebase Email Senha Entrar Criar Conta Usu\u00e1rio ou [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-60","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/coleta.envionacional.com.br\/index.php\/wp-json\/wp\/v2\/pages\/60","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coleta.envionacional.com.br\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/coleta.envionacional.com.br\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/coleta.envionacional.com.br\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coleta.envionacional.com.br\/index.php\/wp-json\/wp\/v2\/comments?post=60"}],"version-history":[{"count":115,"href":"https:\/\/coleta.envionacional.com.br\/index.php\/wp-json\/wp\/v2\/pages\/60\/revisions"}],"predecessor-version":[{"id":180,"href":"https:\/\/coleta.envionacional.com.br\/index.php\/wp-json\/wp\/v2\/pages\/60\/revisions\/180"}],"wp:attachment":[{"href":"https:\/\/coleta.envionacional.com.br\/index.php\/wp-json\/wp\/v2\/media?parent=60"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}