diff --git a/public/app.js b/public/app.js
index 9392859..52f9794 100644
--- a/public/app.js
+++ b/public/app.js
@@ -1,19 +1,116 @@
// ========================================
-// SteelBase v7.5 - PROFESSIONAL EDITION
+// SteelBase v6.5 - PROFESSIONAL EDITION
// Plataforma Técnica Completa com Base de Materiais
// ========================================
-(function() {
- 'use strict';
+// In-memory data storage WITH localStorage for preferences
+const appState = {
+ history: [],
+ favorites: [],
+ budgetItems: [],
+ currentSection: 'cev',
+ currentTheme: 'dark', // 'dark' or 'light'
+ expertMode: false,
+ currentSidebarTab: 0
+};
-// Logger disponível globalmente (carregado antes em logger.js)
-// Usar window.Logger.info('mensagem') para logs controlados
+// User preferences (saved to localStorage)
+let userPreferences = {
+ theme: 'dark',
+ colorScheme: 'default', // default, blue, green, purple, orange
+ fontSize: 'medium', // small, medium, large, xlarge
+ fontFamily: 'default' // default, modern, classic, mono
+};
-// State e config disponíveis globalmente via script state.js (carregado antes)
-// Referências para uso local
-var appState = window.appState;
-var userPreferences = window.userPreferences;
-var adminConfig = window.adminConfig;
+// Load preferences from localStorage
+function loadPreferences() {
+ try {
+ const saved = localStorage.getItem('acoCalcPreferences');
+ if (saved) {
+ userPreferences = { ...userPreferences, ...JSON.parse(saved) };
+ }
+ } catch (e) {
+ console.warn('Não foi possível carregar preferências:', e);
+ }
+}
+
+// Save preferences to localStorage
+function savePreferences() {
+ try {
+ localStorage.setItem('acoCalcPreferences', JSON.stringify(userPreferences));
+ } catch (e) {
+ console.warn('Não foi possível salvar preferências:', e);
+ }
+}
+
+// Admin configuration (in-memory)
+const adminConfig = {
+ appName: 'SteelBase',
+ appSubtitle: 'Plataforma Técnica com Base de Dados de Materiais Brasileiros',
+ footerText: '© 2025 SteelBase v6.5 PROFESSIONAL EDITION - Plataforma Técnica com Base de Dados de Materiais Brasileiros',
+ themeDefault: 'escuro',
+ modeDefault: 'simples',
+ toolsVisibility: {
+ // Aços Estruturais
+ 'cev': true,
+ 'seletor': true,
+ 'equivalencias': false,
+ 'comparativo': false,
+ 'assistente-inteligente': true,
+ // Consumíveis de Soldagem
+ 'eletrodos': false,
+ 'arames': false,
+ 'fluxos': false,
+ 'gases': false,
+ // Fixadores
+ 'parafusos-catalogo': false,
+ 'porcas': false,
+ 'arruelas': false,
+ 'chumbadores': false,
+ // Tintas e Revestimentos
+ 'tintas-catalogo': false,
+ 'sistemas-pintura': false,
+ 'abrasivos': false,
+ 'granalha': false,
+ // Elementos Complementares
+ 'telhas': false,
+ 'paineis': false,
+ 'steel-deck': false,
+ 'perfis-formados': false,
+ // Catálogo de Perfis
+ 'cantoneiras': true,
+ 'barras-redondas': true,
+ 'tubos-circulares': true,
+ 'perfis-i': true,
+ 'perfis-w': true,
+ 'tubos-rhs': true,
+ 'chapas': true,
+ 'perfis-hp': true,
+ 'barras-roscadas': true,
+ 'barras-chatas': true,
+ // Conexões
+ 'parafusos': true,
+ 'layout': true,
+ 'parafuso-vs-solda': false,
+ // Soldagem
+ 'preaquecimento': true,
+ 'dureza': true,
+ 'charpy': true,
+ 'certificado': false,
+ 'ultrassom': false,
+ // Pintura
+ 'area-pintura': true,
+ 'consumo-tinta': true,
+ 'galvanizacao': false,
+ 'custo-pintura': true,
+ 'secagem': false,
+ 'inspecao-pintura': false,
+ // Orçamento
+ 'orcamento': true,
+ 'peso-rigging': false,
+ 'referencia': false
+ }
+};
// ========================================
// CSV MAPPING AND LOADING FUNCTIONS v6.6
@@ -334,6 +431,108 @@ function showSection(sectionId) {
}, 500);
}
+ // CÓDIGO ANTIGO REMOVIDO - mantido apenas para referência
+ if (false && sectionId === 'cantoneiras') {
+ console.log('🔧 Seção cantoneiras detectada - iniciando carregamento forçado');
+
+ // Tentar múltiplas vezes até conseguir
+ let tentativas = 0;
+ const maxTentativas = 10;
+
+ const tentarCarregar = async () => {
+ tentativas++;
+ console.log(`🔄 Tentativa ${tentativas}/${maxTentativas} de carregar cantoneiras`);
+
+ const tbody = document.getElementById('cantoneiras-tbody');
+
+ if (tbody) {
+ console.log('✅ Elemento tbody encontrado! Carregando dados...');
+
+ try {
+ // Carregar CSV diretamente
+ const response = await fetch('BD/perfis/cantoneiras_brasil_completo.csv');
+ if (!response.ok) {
+ throw new Error(`HTTP ${response.status}`);
+ }
+
+ const csvText = await response.text();
+ const linhas = csvText.trim().split('\n');
+
+ console.log(`📊 CSV carregado: ${linhas.length} linhas`);
+
+ const dados = [];
+ for (let i = 1; i < linhas.length; i++) {
+ const linha = linhas[i].trim();
+ if (!linha) continue;
+
+ const colunas = linha.split(',');
+ if (colunas.length >= 9) {
+ dados.push({
+ id: colunas[0].trim(),
+ nome: colunas[1].trim(),
+ lado_mm: parseFloat(colunas[2]),
+ espessura_mm: parseFloat(colunas[3]),
+ peso_kg_m: parseFloat(colunas[4]),
+ area_cm2: parseFloat(colunas[5]),
+ momento_inercia_cm4: parseFloat(colunas[6]),
+ raio_giracao_cm: parseFloat(colunas[7]),
+ tipo: colunas[8].trim()
+ });
+ }
+ }
+
+ console.log(`✅ Processados: ${dados.length} cantoneiras`);
+
+ // Exibir na tabela
+ tbody.innerHTML = dados.map(item => `
+
+ | ${item.nome} |
+ ${item.lado_mm} |
+ ${item.espessura_mm} |
+ ${item.peso_kg_m.toFixed(2)} |
+ ${item.area_cm2.toFixed(2)} |
+ ${item.momento_inercia_cm4.toFixed(2)} |
+ ${item.raio_giracao_cm.toFixed(2)} |
+ ${item.tipo} |
+ |
+
+ `).join('');
+
+ console.log('🎉 Tabela preenchida com sucesso!');
+
+ // Atualizar contador
+ const totalEl = document.getElementById('cant-total');
+ if (totalEl) {
+ totalEl.textContent = dados.length;
+ }
+
+ } catch (error) {
+ console.error('❌ Erro ao carregar CSV:', error);
+ tbody.innerHTML = `
+
+
+ ❌ Erro ao carregar dados: ${error.message}
+
+
+ |
+
+ `;
+ }
+ } else {
+ console.warn(`⚠️ Elemento tbody não encontrado (tentativa ${tentativas})`);
+
+ if (tentativas < maxTentativas) {
+ setTimeout(tentarCarregar, 300);
+ } else {
+ console.error('❌ Falha após todas as tentativas');
+ }
+ }
+ };
+
+ // Iniciar tentativas após um pequeno delay
+ setTimeout(tentarCarregar, 200);
+ }
+
// Add help button after content loads
setTimeout(() => {
if (sectionId === 'preaquecimento') {
@@ -893,37 +1092,14 @@ function analisarUltrassom() {
}
function calcularCustoTotal() {
- const areaInput = document.getElementById('custo-area');
- const regiaoInput = document.getElementById('custo-regiao');
- const tipoTintaInput = document.getElementById('custo-tipo-tinta');
- const custoMOInput = document.getElementById('custo-mo');
- const prodInput = document.getElementById('custo-prod');
- const volumeInput = document.getElementById('custo-volume');
-
- const area = parseFloat(areaInput?.value) || 0;
- const regiao = regiaoInput?.value || 'sudeste';
- const tipoTinta = tipoTintaInput?.value || 'padrao';
- const custoMO = parseFloat(custoMOInput?.value) || 85;
- const prod = parseFloat(prodInput?.value) || 5;
- const volume = parseFloat(volumeInput?.value) || 0;
- const incluirEPI = document.getElementById('custo-incluir-epi')?.checked || false;
- const incluirEquip = document.getElementById('custo-incluir-equip')?.checked || false;
-
- if (area <= 0 || isNaN(area)) {
- const resultEl = document.getElementById('custo-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Área inválida. Insira um valor maior que 0.
';
- return;
- }
- if (prod <= 0) {
- const resultEl = document.getElementById('custo-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Produtividade inválida. Insira um valor maior que 0.
';
- return;
- }
- if (volume < 0) {
- const resultEl = document.getElementById('custo-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Volume não pode ser negativo.
';
- return;
- }
+ const area = parseFloat(document.getElementById('custo-area').value) || 0;
+ const regiao = document.getElementById('custo-regiao').value;
+ const tipoTinta = document.getElementById('custo-tipo-tinta').value;
+ const custoMO = parseFloat(document.getElementById('custo-mo').value) || 85;
+ const prod = parseFloat(document.getElementById('custo-prod').value) || 5;
+ const volume = parseFloat(document.getElementById('custo-volume').value) || 0;
+ const incluirEPI = document.getElementById('custo-incluir-epi').checked;
+ const incluirEquip = document.getElementById('custo-incluir-equip').checked;
const precosTinta = {
sudeste: { padrao: 80, premium: 120, economica: 50 },
@@ -1025,31 +1201,10 @@ function calcularCustoTotal() {
}
function calcularSecagem() {
- const tipoInput = document.getElementById('sec-tipo');
- const tempInput = document.getElementById('sec-temp');
- const umidadeInput = document.getElementById('sec-umidade');
- const espessuraInput = document.getElementById('sec-espessura');
-
- const tipo = tipoInput?.value || 'epoxi';
- const temp = parseFloat(tempInput?.value) || 25;
- const umidade = parseFloat(umidadeInput?.value) || 60;
- const espessura = parseFloat(espessuraInput?.value) || 80;
-
- if (temp < -20 || temp > 300) {
- const resultEl = document.getElementById('sec-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Temperatura inválida. Use valores entre -20°C e 300°C.
';
- return;
- }
- if (umidade < 0 || umidade > 100) {
- const resultEl = document.getElementById('sec-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Umidade inválida. Use valores entre 0% e 100%.
';
- return;
- }
- if (espessura <= 0 || espessura > 1000) {
- const resultEl = document.getElementById('sec-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Espessura inválida. Use valores entre 1 e 1000 microns.
';
- return;
- }
+ const tipo = document.getElementById('sec-tipo').value;
+ const temp = parseFloat(document.getElementById('sec-temp').value) || 25;
+ const umidade = parseFloat(document.getElementById('sec-umidade').value) || 60;
+ const espessura = parseFloat(document.getElementById('sec-espessura').value) || 80;
const dadosTinta = {
epoxi: { tempIdeal: 25, umidadeMax: 85, tempoBase: 24, fatorEsp: 0.2 },
@@ -5039,28 +5194,14 @@ function getReferenciaContent() {
// CEV Calculation
function calcularCEV() {
- const getVal = (id) => parseFloat(document.getElementById(id)?.value) || 0;
-
- const C = getVal('cev-c');
- const Mn = getVal('cev-mn');
- const Cr = getVal('cev-cr');
- const Mo = getVal('cev-mo');
- const V = getVal('cev-v');
- const Ni = getVal('cev-ni');
- const Cu = getVal('cev-cu');
- const thickness = getVal('cev-thickness');
-
- if ([C, Mn, Cr, Mo, V, Ni, Cu].every(v => v === 0)) {
- const resultEl = document.getElementById('cev-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Preencha pelo menos um elemento de liga para calcular o CEV.
';
- return;
- }
-
- if (C < 0 || C > 2 || Mn < 0 || Mn > 5 || Cr < 0 || Cr > 30 || Mo < 0 || Mo > 5 || V < 0 || V > 5 || Ni < 0 || Ni > 5 || Cu < 0 || Cu > 5) {
- const resultEl = document.getElementById('cev-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Valores fora dos limites típicos para aços. Verifique os valores inseridos.
';
- return;
- }
+ const C = parseFloat(document.getElementById('cev-c').value) || 0;
+ const Mn = parseFloat(document.getElementById('cev-mn').value) || 0;
+ const Cr = parseFloat(document.getElementById('cev-cr').value) || 0;
+ const Mo = parseFloat(document.getElementById('cev-mo').value) || 0;
+ const V = parseFloat(document.getElementById('cev-v').value) || 0;
+ const Ni = parseFloat(document.getElementById('cev-ni').value) || 0;
+ const Cu = parseFloat(document.getElementById('cev-cu').value) || 0;
+ const thickness = parseFloat(document.getElementById('cev-thickness').value) || 0;
// IIW Formula
const CEV = C + Mn/6 + (Cr+Mo+V)/5 + (Ni+Cu)/15;
@@ -5922,37 +6063,11 @@ const steelBearing = {
// Tab 1: Cisalhamento (Shear)
function calcularCisalhamento() {
- const getVal = (id, fallback = 0) => {
- const el = document.getElementById(id);
- return el ? (id.includes('qty') || id.includes('planes') ? parseInt(el.value) : parseFloat(el.value)) : fallback;
- };
-
- const boltType = document.getElementById('bolt-type')?.value || 'a325';
- const d = getVal('bolt-d');
- const qty = getVal('bolt-qty', 1);
- const planes = getVal('bolt-planes', 1);
- const force = getVal('bolt-force');
-
- if (!d || d <= 0 || d > 36) {
- const resultEl = document.getElementById('bolt-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Diâmetro do parafuso inválido. Use valores entre 1mm e 36mm.
';
- return;
- }
- if (!boltDatabase[boltType]?.capacidade[d]) {
- const resultEl = document.getElementById('bolt-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Diâmetro não disponível para o tipo de parafuso selecionado.
';
- return;
- }
- if (qty < 1 || qty > 100) {
- const resultEl = document.getElementById('bolt-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Quantidade de parafusos inválida. Use valores entre 1 e 100.
';
- return;
- }
- if (!force || force <= 0) {
- const resultEl = document.getElementById('bolt-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Força aplicada inválida. Insira um valor maior que 0.
';
- return;
- }
+ const boltType = document.getElementById('bolt-type').value;
+ const d = parseFloat(document.getElementById('bolt-d').value);
+ const qty = parseInt(document.getElementById('bolt-qty').value);
+ const planes = parseInt(document.getElementById('bolt-planes').value);
+ const force = parseFloat(document.getElementById('bolt-force').value);
const bolt = boltDatabase[boltType];
const area = Math.PI * Math.pow(d / 2, 2);
@@ -7363,30 +7478,9 @@ function calcularEnergiaCompleta() {
}
function calcularPreaquecimento() {
- const getVal = (id, fallback = 0) => {
- const el = document.getElementById(id);
- return el ? parseFloat(el.value) : fallback;
- };
-
- const cev = getVal('preheat-cev');
- const thickness = getVal('preheat-thickness');
- const ambient = getVal('preheat-ambient', 20);
-
- if (cev < 0 || cev > 2) {
- const resultEl = document.getElementById('preheat-result');
- if (resultEl) resultEl.innerHTML = '⚠️ CEV inválido. Use valores entre 0 e 2.
';
- return;
- }
- if (thickness <= 0 || thickness > 300) {
- const resultEl = document.getElementById('preheat-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Espessura inválida. Use valores entre 1mm e 300mm.
';
- return;
- }
- if (ambient < -50 || ambient > 60) {
- const resultEl = document.getElementById('preheat-result');
- if (resultEl) resultEl.innerHTML = '⚠️ Temperatura ambiente inválida. Use valores entre -50°C e 60°C.
';
- return;
- }
+ const cev = parseFloat(document.getElementById('preheat-cev').value) || 0;
+ const thickness = parseFloat(document.getElementById('preheat-thickness').value) || 0;
+ const ambient = parseFloat(document.getElementById('preheat-ambient').value) || 20;
const preheatTemp = 50 + (cev * 100) + (thickness / 10 * 20) + ((20 - ambient) / 2);
const maxInterpass = preheatTemp + 100;
@@ -10963,4 +11057,4 @@ console.log('✅ SteelBase carregado com sucesso!');
});
// Removido: listener de fechamento do modal Admin legado
-})();
\ No newline at end of file
+});
\ No newline at end of file