Files
SteelBase/public/app.js

11060 lines
543 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ========================================
// SteelBase v6.5 - PROFESSIONAL EDITION
// Plataforma Técnica Completa com Base de Materiais
// ========================================
// In-memory data storage WITH localStorage for preferences
const appState = {
history: [],
favorites: [],
budgetItems: [],
currentSection: 'cev',
currentTheme: 'dark', // 'dark' or 'light'
expertMode: false,
currentSidebarTab: 0
};
// 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
};
// 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
// ========================================
const csvMapping = {
'perfil_w': 'BD/perfis/perfis_w_brasil_completo.csv',
'perfil_i': 'BD/perfis/perfis_i_brasil_completo.csv',
'perfil_hp': 'BD/perfis/perfis_hp_brasil_completo.csv',
'cantoneira': 'BD/perfis/cantoneiras_brasil_completo.csv',
'tubo_circ': 'BD/perfis/tubos_circulares_brasil_completo.csv',
'tubo_rhs': 'BD/perfis/tubos_rhs_brasil_completo.csv',
'chapa': 'BD/perfis/chapas_brasil_completo.csv',
'barra': 'BD/perfis/barras_brasil_completo.csv',
'barra_chata': 'BD/perfis/barras_chatas_brasil_completo.csv',
'barra_roscada': 'BD/perfis/barras_roscadas_brasil_completo.csv'
};
// Function to load CSV
async function carregarCSV(tipoMaterial) {
const caminhoCSV = csvMapping[tipoMaterial];
if (!caminhoCSV) {
console.warn('Tipo de material não mapeado:', tipoMaterial);
return [];
}
try {
const response = await fetch(caminhoCSV);
if (!response.ok) {
throw new Error(`Erro ao carregar ${caminhoCSV}: ${response.status}`);
}
const csvText = await response.text();
return parseCSV(csvText);
} catch (error) {
console.error('Erro ao carregar CSV:', error);
// Return fallback data from materialsDatabase
return getFallbackData(tipoMaterial);
}
}
// Function to parse CSV
function parseCSV(csvText) {
const lines = csvText.trim().split('\n');
if (lines.length === 0) return [];
const headers = lines[0].split(',').map(h => h.trim());
const dados = [];
for (let i = 1; i < lines.length; i++) {
const obj = {};
const currentLine = lines[i].split(',');
for (let j = 0; j < headers.length; j++) {
obj[headers[j]] = currentLine[j] ? currentLine[j].trim() : '';
}
dados.push(obj);
}
return dados;
}
// Fallback to in-memory data if CSV fails
function getFallbackData(tipoMaterial) {
const typeMap = {
'perfil_w': 'perfis_w',
'perfil_i': 'perfis_i',
'perfil_hp': 'perfis_hp',
'cantoneira': 'cantoneiras',
'tubo_circ': 'tubos_circulares',
'tubo_rhs': 'tubos_retangulares',
'chapa': 'chapas',
'barra': 'barras',
'eletrodo': 'consumiveis',
'parafuso': 'parafusos',
'tinta': 'consumiveis'
};
const dbKey = typeMap[tipoMaterial];
return materialsDatabase[dbKey] || [];
}
// ========================================
// COMPREHENSIVE MATERIALS DATABASE
// ========================================
const materialsDatabase = {
perfis_w: [
{id: 'w150_13', nome: 'W150×13', altura: 150, aba: 100, peso: 13, tipo: 'Perfil W', unidade: 'm'},
{id: 'w150_18', nome: 'W150×18', altura: 150, aba: 100, peso: 18, tipo: 'Perfil W', unidade: 'm'},
{id: 'w200_15', nome: 'W200×15', altura: 200, aba: 100, peso: 15, tipo: 'Perfil W', unidade: 'm'},
{id: 'w200_22', nome: 'W200×22', altura: 200, aba: 100, peso: 22, tipo: 'Perfil W', unidade: 'm'},
{id: 'w200_31', nome: 'W200×31', altura: 200, aba: 100, peso: 31, tipo: 'Perfil W', unidade: 'm'},
{id: 'w250_25', nome: 'W250×25', altura: 254, aba: 203, peso: 25, tipo: 'Perfil W', unidade: 'm'},
{id: 'w250_32', nome: 'W250×32', altura: 254, aba: 203, peso: 32, tipo: 'Perfil W', unidade: 'm'},
{id: 'w250_38', nome: 'W250×38', altura: 254, aba: 203, peso: 38, tipo: 'Perfil W', unidade: 'm'},
{id: 'w310_24', nome: 'W310×24', altura: 307, aba: 200, peso: 24, tipo: 'Perfil W', unidade: 'm'},
{id: 'w310_33', nome: 'W310×33', altura: 307, aba: 203, peso: 33, tipo: 'Perfil W', unidade: 'm'},
{id: 'w310_39', nome: 'W310×39', altura: 307, aba: 203, peso: 39, tipo: 'Perfil W', unidade: 'm'},
{id: 'w310_52', nome: 'W310×52', altura: 307, aba: 205, peso: 52, tipo: 'Perfil W', unidade: 'm'},
{id: 'w310_67', nome: 'W310×67', altura: 310, aba: 306, peso: 67, tipo: 'Perfil W', unidade: 'm'},
{id: 'w360_44', nome: 'W360×44', altura: 355, aba: 203, peso: 44, tipo: 'Perfil W', unidade: 'm'},
{id: 'w360_51', nome: 'W360×51', altura: 357, aba: 204, peso: 51, tipo: 'Perfil W', unidade: 'm'},
{id: 'w360_72', nome: 'W360×72', altura: 361, aba: 206, peso: 72, tipo: 'Perfil W', unidade: 'm'},
{id: 'w410_60', nome: 'W410×60', altura: 410, aba: 205, peso: 60, tipo: 'Perfil W', unidade: 'm'},
{id: 'w410_85', nome: 'W410×85', altura: 414, aba: 209, peso: 85, tipo: 'Perfil W', unidade: 'm'},
{id: 'w500_84', nome: 'W500×84', altura: 510, aba: 210, peso: 84, tipo: 'Perfil W', unidade: 'm'},
{id: 'w610_101', nome: 'W610×101', altura: 615, aba: 210, peso: 101, tipo: 'Perfil W', unidade: 'm'}
],
perfis_i: [
{id: 'ipe_100', nome: 'IPE 100', altura: 100, aba: 55, peso: 8.1, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_120', nome: 'IPE 120', altura: 120, aba: 64, peso: 10.4, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_140', nome: 'IPE 140', altura: 140, aba: 73, peso: 12.9, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_160', nome: 'IPE 160', altura: 160, aba: 82, peso: 15.8, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_180', nome: 'IPE 180', altura: 180, aba: 91, peso: 18.8, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_200', nome: 'IPE 200', altura: 200, aba: 100, peso: 22.4, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_240', nome: 'IPE 240', altura: 240, aba: 120, peso: 30.7, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_300', nome: 'IPE 300', altura: 300, aba: 150, peso: 42.2, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_360', nome: 'IPE 360', altura: 360, aba: 170, peso: 57.1, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_400', nome: 'IPE 400', altura: 400, aba: 180, peso: 66.3, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_500', nome: 'IPE 500', altura: 500, aba: 200, peso: 90.7, tipo: 'Perfil I', unidade: 'm'},
{id: 'ipe_600', nome: 'IPE 600', altura: 600, aba: 220, peso: 122, tipo: 'Perfil I', unidade: 'm'}
],
perfis_hp: [
{id: 'hp200_53', nome: 'HP200×53', altura: 203, aba: 203, peso: 53, tipo: 'Perfil HP', unidade: 'm'},
{id: 'hp250_63', nome: 'HP250×63', altura: 254, aba: 254, peso: 63, tipo: 'Perfil HP', unidade: 'm'},
{id: 'hp310_79', nome: 'HP310×79', altura: 310, aba: 310, peso: 79, tipo: 'Perfil HP', unidade: 'm'},
{id: 'hp360_102', nome: 'HP360×102', altura: 362, aba: 362, peso: 102, tipo: 'Perfil HP', unidade: 'm'}
],
cantoneiras: [
{id: 'l50_50_5', nome: 'L50×50×5', lado: 50, esp: 5, peso: 3.75, tipo: 'Cantoneira', unidade: 'm'},
{id: 'l50_50_6', nome: 'L50×50×6', lado: 50, esp: 6, peso: 4.50, tipo: 'Cantoneira', unidade: 'm'},
{id: 'l63_63_6', nome: 'L63×63×6', lado: 63, esp: 6, peso: 5.80, tipo: 'Cantoneira', unidade: 'm'},
{id: 'l75_75_8', nome: 'L75×75×8', lado: 75, esp: 8, peso: 9.1, tipo: 'Cantoneira', unidade: 'm'},
{id: 'l100_100_10', nome: 'L100×100×10', lado: 100, esp: 10, peso: 15.0, tipo: 'Cantoneira', unidade: 'm'},
{id: 'l100_100_12', nome: 'L100×100×12', lado: 100, esp: 12, peso: 17.8, tipo: 'Cantoneira', unidade: 'm'},
{id: 'l125_125_12', nome: 'L125×125×12', lado: 125, esp: 12, peso: 22.4, tipo: 'Cantoneira', unidade: 'm'},
{id: 'l150_150_12', nome: 'L150×150×12', lado: 150, esp: 12, peso: 26.8, tipo: 'Cantoneira', unidade: 'm'},
{id: 'l150_150_15', nome: 'L150×150×15', lado: 150, esp: 15, peso: 32.8, tipo: 'Cantoneira', unidade: 'm'}
],
tubos_circulares: [
{id: 'tubo_50_2', nome: 'Ø50×2.0', diametro: 50, esp: 2.0, peso: 2.45, tipo: 'Tubo Circular', unidade: 'm'},
{id: 'tubo_60_2', nome: 'Ø60×2.0', diametro: 60, esp: 2.0, peso: 2.95, tipo: 'Tubo Circular', unidade: 'm'},
{id: 'tubo_76_25', nome: 'Ø76×2.5', diametro: 76, esp: 2.5, peso: 4.65, tipo: 'Tubo Circular', unidade: 'm'},
{id: 'tubo_80_3', nome: 'Ø80×3.0', diametro: 80, esp: 3.0, peso: 5.85, tipo: 'Tubo Circular', unidade: 'm'},
{id: 'tubo_100_3', nome: 'Ø100×3.0', diametro: 100, esp: 3.0, peso: 7.35, tipo: 'Tubo Circular', unidade: 'm'},
{id: 'tubo_100_4', nome: 'Ø100×4.0', diametro: 100, esp: 4.0, peso: 9.65, tipo: 'Tubo Circular', unidade: 'm'},
{id: 'tubo_120_4', nome: 'Ø120×4.0', diametro: 120, esp: 4.0, peso: 11.70, tipo: 'Tubo Circular', unidade: 'm'},
{id: 'tubo_150_5', nome: 'Ø150×5.0', diametro: 150, esp: 5.0, peso: 18.20, tipo: 'Tubo Circular', unidade: 'm'},
{id: 'tubo_200_4', nome: 'Ø200×4.0', diametro: 200, esp: 4.0, peso: 19.60, tipo: 'Tubo Circular', unidade: 'm'}
],
tubos_retangulares: [
{id: 'rhs_100_100_4', nome: '100×100×4', largura: 100, altura: 100, esp: 4, peso: 15.0, tipo: 'Tubo RHS', unidade: 'm'},
{id: 'rhs_100_100_5', nome: '100×100×5', largura: 100, altura: 100, esp: 5, peso: 18.5, tipo: 'Tubo RHS', unidade: 'm'},
{id: 'rhs_120_80_5', nome: '120×80×5', largura: 120, altura: 80, esp: 5, peso: 18.7, tipo: 'Tubo RHS', unidade: 'm'},
{id: 'rhs_150_100_5', nome: '150×100×5', largura: 150, altura: 100, esp: 5, peso: 22.0, tipo: 'Tubo RHS', unidade: 'm'},
{id: 'rhs_150_150_5', nome: '150×150×5', largura: 150, altura: 150, esp: 5, peso: 27.8, tipo: 'Tubo RHS', unidade: 'm'},
{id: 'rhs_150_150_6', nome: '150×150×6', largura: 150, altura: 150, esp: 6, peso: 33.1, tipo: 'Tubo RHS', unidade: 'm'},
{id: 'rhs_200_100_6', nome: '200×100×6', largura: 200, altura: 100, esp: 6, peso: 30.6, tipo: 'Tubo RHS', unidade: 'm'},
{id: 'rhs_200_200_6', nome: '200×200×6', largura: 200, altura: 200, esp: 6, peso: 43.8, tipo: 'Tubo RHS', unidade: 'm'},
{id: 'rhs_200_200_8', nome: '200×200×8', largura: 200, altura: 200, esp: 8, peso: 57.8, tipo: 'Tubo RHS', unidade: 'm'}
],
chapas: [
{id: 'chapa_475', nome: 'CHAPA 4.75mm', esp: 4.75, formato: '2500×1250', peso_m2: 37.3, tipo: 'Chapa', unidade: 'm²'},
{id: 'chapa_635', nome: 'CHAPA 6.35mm', esp: 6.35, formato: '2500×1250', peso_m2: 49.8, tipo: 'Chapa', unidade: 'm²'},
{id: 'chapa_95', nome: 'CHAPA 9.5mm', esp: 9.5, formato: '2500×1250', peso_m2: 74.6, tipo: 'Chapa', unidade: 'm²'},
{id: 'chapa_127', nome: 'CHAPA 12.7mm', esp: 12.7, formato: '2500×1250', peso_m2: 99.7, tipo: 'Chapa', unidade: 'm²'},
{id: 'chapa_159', nome: 'CHAPA 15.9mm', esp: 15.9, formato: '2500×1250', peso_m2: 124.8, tipo: 'Chapa', unidade: 'm²'},
{id: 'chapa_191', nome: 'CHAPA 19.1mm', esp: 19.1, formato: '2500×1250', peso_m2: 150.0, tipo: 'Chapa', unidade: 'm²'},
{id: 'chapa_254', nome: 'CHAPA 25.4mm', esp: 25.4, formato: '2000×1000', peso_m2: 199.4, tipo: 'Chapa', unidade: 'm²'}
],
barras: [
{id: 'barra_8', nome: 'Ø8mm', diametro: 8, peso: 0.395, tipo: 'Barra Redonda', unidade: 'm'},
{id: 'barra_10', nome: 'Ø10mm', diametro: 10, peso: 0.616, tipo: 'Barra Redonda', unidade: 'm'},
{id: 'barra_12', nome: 'Ø12mm', diametro: 12, peso: 0.888, tipo: 'Barra Redonda', unidade: 'm'},
{id: 'barra_16', nome: 'Ø16mm', diametro: 16, peso: 1.580, tipo: 'Barra Redonda', unidade: 'm'},
{id: 'barra_20', nome: 'Ø20mm', diametro: 20, peso: 2.466, tipo: 'Barra Redonda', unidade: 'm'},
{id: 'barra_25', nome: 'Ø25mm', diametro: 25, peso: 3.852, tipo: 'Barra Redonda', unidade: 'm'},
{id: 'barra_32', nome: 'Ø32mm', diametro: 32, peso: 6.313, tipo: 'Barra Redonda', unidade: 'm'}
],
consumiveis: [
{id: 'e7018', nome: 'E7018 (Eletrodo)', peso_kg: 1, custo_kg: 45, tipo: 'Consumível', unidade: 'kg'},
{id: 'e6013', nome: 'E6013 (Eletrodo)', peso_kg: 1, custo_kg: 28, tipo: 'Consumível', unidade: 'kg'},
{id: 'e8018', nome: 'E8018 (Eletrodo)', peso_kg: 1, custo_kg: 65, tipo: 'Consumível', unidade: 'kg'},
{id: 'er70s6', nome: 'ER70S-6 (MIG)', peso_kg: 1, custo_kg: 32, tipo: 'Consumível', unidade: 'kg'},
{id: 'tinta_c3', nome: 'TINTA C3 Epóxi', custo_l: 80, tipo: 'Consumível', unidade: 'L'},
{id: 'tinta_c4', nome: 'TINTA C4 Epóxi+PU', custo_l: 120, tipo: 'Consumível', unidade: 'L'},
{id: 'tinta_c5', nome: 'TINTA C5 Zinc-Rich', custo_l: 150, tipo: 'Consumível', unidade: 'L'},
{id: 'fundo_zinc', nome: 'FUNDO Zinc-Rich', custo_l: 60, tipo: 'Consumível', unidade: 'L'}
],
parafusos: [
{id: 'para_a325_m12', nome: 'Parafuso A325 M12', custo_un: 0.85, tipo: 'Parafuso', unidade: 'un'},
{id: 'para_a325_m16', nome: 'Parafuso A325 M16', custo_un: 1.20, tipo: 'Parafuso', unidade: 'un'},
{id: 'para_a325_m20', nome: 'Parafuso A325 M20', custo_un: 1.80, tipo: 'Parafuso', unidade: 'un'},
{id: 'para_a490_m16', nome: 'Parafuso A490 M16', custo_un: 2.50, tipo: 'Parafuso', unidade: 'un'},
{id: 'porca_m12', nome: 'Porca M12', custo_un: 0.15, tipo: 'Parafuso', unidade: 'un'},
{id: 'porca_m16', nome: 'Porca M16', custo_un: 0.25, tipo: 'Parafuso', unidade: 'un'},
{id: 'arruela', nome: 'Arruela DIN 125', custo_un: 0.08, tipo: 'Parafuso', unidade: 'un'}
]
};
const regionalPricing = {
sudeste: {
perfil_w: 7.50,
perfil_i: 7.50,
perfil_hp: 7.50,
cantoneira: 7.50,
tubo_circ: 8.00,
tubo_rhs: 8.50,
chapa: 7.80,
barra: 7.50
},
sul: {
perfil_w: 7.20,
perfil_i: 7.20,
perfil_hp: 7.20,
cantoneira: 7.20,
tubo_circ: 7.80,
tubo_rhs: 8.20,
chapa: 7.50,
barra: 7.20
},
nordeste: {
perfil_w: 8.00,
perfil_i: 8.00,
perfil_hp: 8.00,
cantoneira: 8.00,
tubo_circ: 8.50,
tubo_rhs: 9.00,
chapa: 8.20,
barra: 8.00
},
centrooeste: {
perfil_w: 7.70,
perfil_i: 7.70,
perfil_hp: 7.70,
cantoneira: 7.70,
tubo_circ: 8.30,
tubo_rhs: 8.70,
chapa: 8.00,
barra: 7.70
}
};
// Steel database
const steelDatabase = {
a36: { nome: 'ASTM A36', fy: 250, fu: 400, elong: 20, cev: 0.41, charpy: 27, temp: -20, custo: 100, soldabilidade: '⭐⭐⭐⭐⭐', equiv: ['EN S235JR', 'JIS SS400'] },
a572: { nome: 'ASTM A572 Gr.50', fy: 345, fu: 450, elong: 18, cev: 0.45, charpy: 27, temp: -20, custo: 115, soldabilidade: '⭐⭐⭐⭐', equiv: ['EN S355J2', 'JIS SM490'] },
a588: { nome: 'ASTM A588', fy: 345, fu: 485, elong: 19, cev: 0.50, charpy: 27, temp: -20, custo: 125, soldabilidade: '⭐⭐⭐', equiv: ['EN S355K2G3', 'API 2H'] },
a992: { nome: 'ASTM A992', fy: 345, fu: 450, elong: 21, cev: 0.45, charpy: 27, temp: -20, custo: 118, soldabilidade: '⭐⭐⭐⭐', equiv: ['EN S355J2'] },
s235: { nome: 'EN S235JR', fy: 235, fu: 360, elong: 26, cev: 0.38, charpy: 27, temp: -20, custo: 100, soldabilidade: '⭐⭐⭐⭐⭐', equiv: ['ASTM A36', 'JIS SS400'] },
s355: { nome: 'EN S355J2', fy: 355, fu: 490, elong: 22, cev: 0.50, charpy: 27, temp: -20, custo: 115, soldabilidade: '⭐⭐⭐⭐', equiv: ['ASTM A572', 'API 2H'] },
s460: { nome: 'EN S460', fy: 460, fu: 540, elong: 17, cev: 0.55, charpy: 27, temp: -20, custo: 140, soldabilidade: '⭐⭐⭐', equiv: ['ASTM A514'] },
ar350: { nome: 'NBR AR350', fy: 345, fu: 450, elong: 18, cev: 0.45, charpy: 27, temp: -20, custo: 115, soldabilidade: '⭐⭐⭐⭐', equiv: ['ASTM A572', 'EN S355J2'] }
};
// Regional pricing
const regionalPrices = {
sudeste: { a36: 2800, a572: 3100, solda: 65, pintura: 40, galv: 180 },
sul: { a36: 2700, a572: 3000, solda: 60, pintura: 38, galv: 175 },
nordeste: { a36: 3000, a572: 3300, solda: 70, pintura: 42, galv: 190 },
centrooeste: { a36: 2900, a572: 3200, solda: 68, pintura: 41, galv: 185 }
};
// Normative requirements
const certRequirements = {
astm_a36: ['fy ≥ 250 MPa', 'fu 400-550 MPa', 'Alongamento ≥ 20%', 'C ≤ 0.25%', 'Mn ≤ 1.20%'],
astm_a572: ['fy ≥ 345 MPa', 'fu 450-620 MPa', 'Alongamento ≥ 18%', 'CEV ≤ 0.55%'],
en_s235: ['fy ≥ 235 MPa', 'fu 360-510 MPa', 'Alongamento ≥ 26%'],
en_s355: ['fy ≥ 355 MPa', 'fu 470-630 MPa', 'Alongamento ≥ 22%', 'Charpy 27J @ -20°C'],
nbr_ar350: ['fy ≥ 345 MPa', 'fu ≥ 450 MPa', 'Alongamento ≥ 18%', 'C ≤ 0.15%']
};
let currentChart = null;
// ========================================
// NAVIGATION & UI FUNCTIONS
// ========================================
function switchSidebarTab(index) {
document.querySelectorAll('.sidebar-tab').forEach((tab, i) => {
tab.classList.toggle('active', i === index);
});
document.querySelectorAll('.sidebar-content').forEach((content, i) => {
content.classList.toggle('active', i === index);
});
appState.currentSidebarTab = index;
}
function showSection(sectionId) {
appState.currentSection = sectionId;
// Update sidebar active state
document.querySelectorAll('.sidebar-item').forEach(item => {
item.classList.toggle('active', item.dataset.section === sectionId);
});
// Load section content
loadSectionContent(sectionId);
// Carregar dados específicos para catálogo de perfis
// SOLUÇÃO DEFINITIVA: Usar a função que funciona!
if (sectionId === 'cantoneiras') {
console.log('🔧 Seção cantoneiras detectada - carregando automaticamente');
// Aguardar o DOM estar pronto e chamar a função que funciona
setTimeout(() => {
if (typeof forcarCarregamentoCantoneiras === 'function') {
console.log('✅ Chamando forcarCarregamentoCantoneiras automaticamente');
forcarCarregamentoCantoneiras();
} else {
console.error('❌ Função forcarCarregamentoCantoneiras não encontrada');
}
}, 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 => `
<tr>
<td><strong>${item.nome}</strong></td>
<td>${item.lado_mm}</td>
<td>${item.espessura_mm}</td>
<td>${item.peso_kg_m.toFixed(2)}</td>
<td>${item.area_cm2.toFixed(2)}</td>
<td>${item.momento_inercia_cm4.toFixed(2)}</td>
<td>${item.raio_giracao_cm.toFixed(2)}</td>
<td><span class="badge badge-info">${item.tipo}</span></td>
<td><button class="btn btn-sm btn-primary">👁️ Ver</button></td>
</tr>
`).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 = `
<tr>
<td colspan="9" style="text-align: center; padding: 20px; color: #ef4444;">
❌ Erro ao carregar dados: ${error.message}
<br><br>
<button class="btn btn-primary" onclick="location.reload()">🔄 Recarregar</button>
</td>
</tr>
`;
}
} 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') {
addHelpButton('preaquecimento');
} else if (sectionId === 'parafusos') {
addHelpButton('parafusos-cisalhamento');
} else {
addHelpButton(sectionId);
}
}, 200);
}
function loadSectionContent(sectionId) {
const content = document.getElementById('main-content');
const sections = {
'cev': getCEVContent(),
'seletor': getSeletorContent(),
'equivalencias': getEquivalenciasContent(),
'comparativo': getComparativoContent(),
// Assistente Inteligente
'assistente-inteligente': getAssistenteInteligenteContent(),
// Catálogo de Perfis
'cantoneiras': typeof getCantoneirasContent === 'function' ? getCantoneirasContent() : '<p>Carregando cantoneiras...</p>',
'barras-redondas': typeof getBarrasRedondasContent === 'function' ? getBarrasRedondasContent() : '<p>Em desenvolvimento</p>',
'tubos-circulares': typeof getTubosCircularesContent === 'function' ? getTubosCircularesContent() : '<p>Em desenvolvimento</p>',
'perfis-i': typeof getPerfisIContent === 'function' ? getPerfisIContent() : '<p>Em desenvolvimento</p>',
'perfis-w': typeof getPerfisWContent === 'function' ? getPerfisWContent() : '<p>Em desenvolvimento</p>',
'tubos-rhs': typeof getTubosRHSContent === 'function' ? getTubosRHSContent() : '<p>Em desenvolvimento</p>',
'chapas': typeof getChapasContent === 'function' ? getChapasContent() : '<p>Em desenvolvimento</p>',
'perfis-hp': typeof getPerfisHPContent === 'function' ? getPerfisHPContent() : '<p>Em desenvolvimento</p>',
'barras-roscadas': typeof getBarrasRoscadasContent === 'function' ? getBarrasRoscadasContent() : '<p>Em desenvolvimento</p>',
'barras-chatas': typeof getBarrasChatasContent === 'function' ? getBarrasChatasContent() : '<p>Em desenvolvimento</p>',
// Conexões
'parafusos': getParafusosContent(),
'layout': getLayoutContent(),
'parafuso-vs-solda': getParafusoVsSoldaContent(),
// Soldagem
'preaquecimento': getPreaquecimentoContent(),
'solda-filete': getSoldaFileteContent(),
'energia-soldagem': getEnergiaSoldagemContent(),
'consumo-eletrodos': getConsumoEletrodosContent(),
// Ensaios
'dureza': getDurezaContent(),
'charpy': getCharpyContent(),
'certificado': getCertificadoContent(),
'ultrassom': getUltrassomContent(),
// Pintura
'area-pintura': getAreaPinturaContent(),
'consumo-tinta': getConsumoTintaContent(),
'galvanizacao': getGalvanizacaoContent(),
'custo-pintura': getCustoPinturaContent(),
'secagem': getSecagemContent(),
'inspecao-pintura': getInspecaoPinturaContent(),
// Orçamento
'orcamento': getOrcamentoContent(),
'peso-rigging': getPesoRiggingContent(),
'referencia': getReferenciaContent()
};
content.innerHTML = sections[sectionId] || '<p>Seção não encontrada</p>';
}
function toggleTheme() {
appState.currentTheme = appState.currentTheme === 'dark' ? 'light' : 'dark';
userPreferences.theme = appState.currentTheme;
savePreferences();
applyTheme();
}
function applyTheme() {
// Apply theme
document.documentElement.setAttribute('data-theme', appState.currentTheme);
document.documentElement.setAttribute('data-color-scheme', appState.currentTheme);
const btn = document.getElementById('theme-toggle');
if (btn) {
btn.textContent = appState.currentTheme === 'dark' ? '☀️ Claro' : '🌙 Escuro';
btn.classList.toggle('light', appState.currentTheme === 'light');
}
}
// Apply all user preferences
function applyUserPreferences() {
// Apply theme
appState.currentTheme = userPreferences.theme;
applyTheme();
// Apply color scheme
document.documentElement.setAttribute('data-color-scheme-variant', userPreferences.colorScheme);
// Apply font size
document.documentElement.setAttribute('data-font-size', userPreferences.fontSize);
// Apply font family
document.documentElement.setAttribute('data-font-family', userPreferences.fontFamily);
}
function toggleExpertMode() {
appState.expertMode = !appState.expertMode;
document.documentElement.classList.toggle('expert-mode', appState.expertMode);
const btn = document.getElementById('expert-toggle');
if (btn) {
btn.textContent = appState.expertMode ? '🔬 Expert' : '🎯 Simples';
btn.classList.toggle('active', appState.expertMode);
}
filterToolsByMode();
}
function filterToolsByMode() {
console.log('🔍 Filtrando ferramentas por modo...');
const allItems = document.querySelectorAll('.sidebar-item');
allItems.forEach(item => {
const sectionId = item.dataset.section;
if (appState.expertMode) {
// Expert mode: show all tools
item.classList.remove('hidden');
} else {
// Simple mode: show only selected tools
const isVisible = adminConfig.toolsVisibility[sectionId];
if (isVisible) {
item.classList.remove('hidden');
} else {
item.classList.add('hidden');
}
}
});
// FIRST: Reset all subcategories to closed state
resetSubcategoriesToClosedState();
// THEN: Initialize sidebar expansion (respects manual state)
initializeSidebarExpansion();
}
/**
* Reset all subcategories to closed state initially
* This ensures consistent starting state
*/
function resetSubcategoriesToClosedState() {
console.log('🔄 Resetando subcategorias para estado fechado...');
const subcategories = document.querySelectorAll('.sidebar-subcategory');
const categories = document.querySelectorAll('.sidebar-category');
// Close all subcategories first
subcategories.forEach(subcategory => {
const icon = subcategory.querySelector('.category-icon');
const title = subcategory.querySelector('.subcategory-title')?.textContent || 'Subcategoria';
subcategory.classList.remove('expanded');
if (icon) {
icon.style.transform = 'rotate(0deg)';
icon.textContent = '▶';
}
console.log(`❌ Fechando: ${title} (ícone: ▶)`);
});
// Close all categories
categories.forEach(category => {
const icon = category.querySelector('.category-icon');
const title = category.querySelector('.category-title')?.textContent || 'Categoria';
category.classList.remove('expanded');
if (icon) {
icon.style.transform = 'rotate(0deg)';
icon.textContent = '▶';
}
console.log(`❌ Fechando categoria: ${title} (ícone: ▶)`);
});
}
/**
* Debug function to test accordion functionality
*/
function debugAccordion() {
console.log('🐛 DEBUG ACCORDION - Estado atual:');
const subcategories = document.querySelectorAll('.sidebar-subcategory');
subcategories.forEach((sub, index) => {
const title = sub.querySelector('.subcategory-title')?.textContent || `Subcategoria ${index}`;
const isExpanded = sub.classList.contains('expanded');
const manuallyCollapsed = sub.getAttribute('data-manually-collapsed') === 'true';
const visibleItems = sub.querySelectorAll('.sidebar-item:not(.hidden)').length;
console.log(`📂 ${title}:`);
console.log(` - Expandido: ${isExpanded}`);
console.log(` - Manualmente fechado: ${manuallyCollapsed}`);
console.log(` - Itens visíveis: ${visibleItems}`);
});
}
// Adicionar função global para debug
window.debugAccordion = debugAccordion;
/**
* Initialize sidebar expansion - CORRIGINDO ÍCONES E ESTADO
* Expands subcategories and UPDATES ICONS correctly
*/
function initializeSidebarExpansion() {
console.log('🔧 Inicializando sidebar: estado padrão FECHADO (mobile e desktop)');
// SUBCATEGORIAS: sempre iniciar FECHADAS
const subcategories = document.querySelectorAll('.sidebar-subcategory');
subcategories.forEach(subcategory => {
subcategory.classList.remove('expanded');
const icon = subcategory.querySelector('.category-icon');
const content = subcategory.querySelector('.sidebar-subcategory-content');
if (icon) {
icon.style.transform = 'rotate(0deg)';
icon.textContent = '▶';
}
if (content) {
content.style.maxHeight = '';
content.style.opacity = '';
content.style.visibility = '';
}
});
// CATEGORIAS: sempre iniciar FECHADAS
const categories = document.querySelectorAll('.sidebar-category');
categories.forEach(category => {
category.classList.remove('expanded');
const icon = category.querySelector('.category-icon');
const content = category.querySelector('.sidebar-category-content');
if (icon) {
icon.style.transform = 'rotate(0deg)';
icon.textContent = '▶';
}
if (content) {
content.style.maxHeight = '';
content.style.opacity = '';
content.style.visibility = '';
}
});
}
function toggleFavorite(event, sectionId) {
event.stopPropagation();
const starBtn = event.target;
const favIndex = appState.favorites.indexOf(sectionId);
if (favIndex > -1) {
appState.favorites.splice(favIndex, 1);
starBtn.textContent = '☆';
starBtn.classList.remove('active');
} else {
appState.favorites.push(sectionId);
starBtn.textContent = '★';
starBtn.classList.add('active');
}
}
/**
* Toggle category expansion in sidebar - CORRIGINDO ÍCONES
* @param {HTMLElement} header - Category header element
* @param {Event} event - Click event
*/
function toggleCategory(header, event) {
if (event) {
event.stopPropagation();
event.preventDefault();
}
console.log('🔄 toggleCategory chamado');
const category = header.parentElement;
const isExpanded = category.classList.contains('expanded');
const categoryTitle = header.querySelector('.category-title, .subcategory-title')?.textContent || 'Categoria';
const icon = header.querySelector('.category-icon');
const content = header.nextElementSibling; // Works for both category and subcategory content
console.log(`📂 Categoria: ${categoryTitle}`);
console.log(`📊 Estado atual: ${isExpanded ? 'EXPANDIDO (▼)' : 'FECHADO (▶)'}`);
if (isExpanded) {
// FECHAR
category.classList.remove('expanded');
category.setAttribute('data-manually-collapsed', 'true');
if (icon) {
icon.style.transform = 'rotate(0deg)';
icon.textContent = '▶';
}
// Clear any inline styles to let CSS handle transitions
if (content) {
content.style.maxHeight = '';
content.style.opacity = '';
content.style.visibility = '';
}
console.log('❌ FECHANDO categoria (ícone: ▶)');
} else {
// ABRIR
category.classList.add('expanded');
category.removeAttribute('data-manually-collapsed');
if (icon) {
icon.style.transform = 'rotate(90deg)';
icon.textContent = '▼';
}
// Ensure inline styles are cleared so CSS expanded state applies cleanly
if (content) {
content.style.maxHeight = '';
content.style.opacity = '';
content.style.visibility = '';
}
console.log('✅ ABRINDO categoria (ícone: ▼)');
}
}
function addToHistory(title, details) {
const historyItem = {
id: Date.now(),
title: title,
details: details,
date: new Date().toLocaleString('pt-BR')
};
appState.history.unshift(historyItem);
if (appState.history.length > 100) {
appState.history = appState.history.slice(0, 100);
}
}
function openHistoryModal() {
const modal = document.getElementById('history-modal');
const list = document.getElementById('history-list');
if (appState.history.length === 0) {
list.innerHTML = '<p style="text-align: center; color: var(--color-text-secondary);">Nenhum cálculo no histórico</p>';
} else {
list.innerHTML = appState.history.map(item => `
<div class="history-item">
<div style="font-weight: 600; margin-bottom: 4px;">${item.title}</div>
<div style="font-size: 12px; color: var(--color-text-secondary);">${item.date}</div>
<p style="margin-top: 8px; font-size: 14px;">${item.details}</p>
</div>
`).join('');
}
modal.classList.add('active');
}
function closeHistoryModal() {
document.getElementById('history-modal').classList.remove('active');
}
function openFavoritesModal() {
const modal = document.getElementById('favorites-modal');
const list = document.getElementById('favorites-list');
if (appState.favorites.length === 0) {
list.innerHTML = '<p style="text-align: center; color: var(--color-text-secondary);">Nenhuma seção favoritada</p>';
} else {
list.innerHTML = appState.favorites.map(sectionId => `
<div class="favorite-item" style="cursor: pointer;" onclick="showSection('${sectionId}'); closeFavoritesModal();">
<strong>${getSectionName(sectionId)}</strong>
</div>
`).join('');
}
modal.classList.add('active');
}
function closeFavoritesModal() {
document.getElementById('favorites-modal').classList.remove('active');
}
function updateUtFields() {
const type = document.getElementById('ut-type').value;
const diameterGroup = document.getElementById('ut-diameter-group');
const qtyGroup = document.getElementById('ut-qty-group');
const lengthGroup = document.getElementById('ut-length-group');
if (type === 'porosidade') {
diameterGroup.style.display = 'block';
qtyGroup.style.display = 'block';
lengthGroup.style.display = 'block';
} else if (type === 'trinca' || type === 'falta-fusao' || type === 'falta-penetracao') {
diameterGroup.style.display = 'none';
qtyGroup.style.display = 'none';
lengthGroup.style.display = 'block';
} else {
diameterGroup.style.display = 'block';
qtyGroup.style.display = 'block';
lengthGroup.style.display = 'block';
}
}
function analisarUltrassom() {
const norm = document.getElementById('ut-norm').value;
const type = document.getElementById('ut-type').value;
const location = document.getElementById('ut-location').value;
const diameter = parseFloat(document.getElementById('ut-diameter').value) || 0;
const qty = parseInt(document.getElementById('ut-qty').value) || 0;
const length = parseFloat(document.getElementById('ut-length').value) || 0;
const depth = parseFloat(document.getElementById('ut-depth').value) || 0;
const thickness = parseFloat(document.getElementById('ut-thickness').value) || 0;
let maxDiameter = 3;
let maxQtyIn25mm = 5;
let maxDepth = thickness / 4;
let status = '✅ ACEITA';
let alertClass = 'alert-success';
let reasoning = [];
if (norm === 'aws') {
maxDiameter = 3;
maxQtyIn25mm = 5;
} else if (norm === 'asme') {
maxDiameter = 4;
maxQtyIn25mm = 6;
} else {
maxDiameter = 3.5;
maxQtyIn25mm = 5;
}
if (type === 'porosidade') {
const totalLength = qty * diameter;
const allowedInSpan = 25 * 0.36;
if (diameter > maxDiameter) {
status = '❌ REJEITA';
alertClass = 'alert-error';
reasoning.push(`Diâmetro ${diameter}mm > máximo ${maxDiameter}mm`);
}
if (qty > maxQtyIn25mm) {
status = '❌ REJEITA';
alertClass = 'alert-error';
reasoning.push(`Quantidade ${qty} > máximo ${maxQtyIn25mm} poros em 25mm`);
}
if (totalLength > allowedInSpan) {
status = '⚠️ ANÁLISE';
if (alertClass !== 'alert-error') alertClass = 'alert-warning';
reasoning.push(`Comprimento total ${totalLength.toFixed(1)}mm > permitido ${allowedInSpan.toFixed(1)}mm`);
}
if (depth > maxDepth) {
status = '❌ REJEITA';
alertClass = 'alert-error';
reasoning.push(`Profundidade ${depth}mm > máximo ${maxDepth.toFixed(1)}mm (esp/4)`);
}
if (status === '✅ ACEITA') {
reasoning.push(`Diâmetro ${diameter}mm ≤ ${maxDiameter}mm ✓`);
reasoning.push(`Quantidade ${qty}${maxQtyIn25mm} em 25mm ✓`);
reasoning.push(`Comprimento total ${totalLength.toFixed(1)}mm ≤ ${allowedInSpan.toFixed(1)}mm ✓`);
reasoning.push(`Profundidade ${depth}mm ≤ ${maxDepth.toFixed(1)}mm ✓`);
}
} else if (type === 'trinca') {
status = '❌ REJEITA';
alertClass = 'alert-error';
reasoning.push('Trincas não são permitidas em nenhuma norma');
reasoning.push('Ação requerida: Remover completamente a solda e refazer');
} else if (type === 'falta-fusao' || type === 'falta-penetracao') {
if (length > 25) {
status = '❌ REJEITA';
alertClass = 'alert-error';
reasoning.push(`Comprimento ${length}mm > máximo 25mm`);
} else if (length > 10) {
status = '⚠️ ANÁLISE';
alertClass = 'alert-warning';
reasoning.push(`Comprimento ${length}mm requer análise de engenharia`);
} else {
status = '✅ ACEITA';
reasoning.push(`Comprimento ${length}mm ≤ 10mm (aceitável) ✓`);
}
}
const normName = norm === 'aws' ? 'AWS D1.1' : norm === 'asme' ? 'ASME Sec VIII' : 'DNV-GL';
const typeName = {
'porosidade': 'Porosidade',
'inclusao': 'Inclusão de Escória',
'falta-fusao': 'Falta de Fusão',
'falta-penetracao': 'Falta de Penetração',
'trinca': 'Trinca',
'mordedura': 'Mordedura'
}[type];
document.getElementById('ut-result').innerHTML = `
<div class="result-box" style="background: var(--color-bg-1); border-left: 4px solid var(--color-primary);">
<div class="result-title">🏥 INTERPRETAÇÃO ULTRASSOM - RESULTADO</div>
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>NORMA APLICADA:</strong> ${normName}<br>
<strong>Descontinuidade:</strong> ${typeName}<br>
<strong>Localização:</strong> ${location.charAt(0).toUpperCase() + location.slice(1)}
</div>
${type === 'porosidade' ? `
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px;">
<strong>DADOS DA DESCONTINUIDADE:</strong><br>
• Diâmetro: ${diameter} mm<br>
• Quantidade: ${qty} poros<br>
• Tamanho Total: ${(qty * diameter).toFixed(1)} mm<br>
• Profundidade: ${depth} mm<br>
• Espessura Chapa: ${thickness} mm
</div>
<div style="padding: 16px; background: var(--color-bg-2); border-radius: 8px; margin-bottom: 16px;">
<strong>CRITÉRIO ${normName}:</strong><br>
<strong>Porosidade Isolada:</strong><br>
• Diâmetro máximo: ${maxDiameter} mm<br>
• Quantidade máxima: ${maxQtyIn25mm} poros em 25mm<br>
• Comprimento total permitido: ${(25 * 0.36).toFixed(1)} mm em 25mm<br>
• Profundidade máxima: ${maxDepth.toFixed(1)} mm (espessura/4)
</div>
` : type === 'trinca' ? `
<div style="padding: 16px; background: var(--color-bg-4); border-radius: 8px; margin-bottom: 16px; border: 2px solid var(--color-error);">
<strong>⚠️ DESCONTINUIDADE CRÍTICA:</strong><br>
Trincas são defeitos graves que comprometem a integridade estrutural.<br>
Nenhuma norma permite trincas de qualquer tamanho.
</div>
` : `
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px;">
<strong>DADOS:</strong><br>
• Comprimento: ${length} mm<br>
• Profundidade: ${depth} mm<br>
• Espessura: ${thickness} mm
</div>
`}
<div style="padding: 16px; background: var(--color-bg-3); border-radius: 8px; margin-bottom: 16px;">
<strong>📊 ANÁLISE:</strong><br>
${reasoning.map(r => `${r}`).join('<br>')}
</div>
<div class="alert ${alertClass}">
<strong>RESULTADO: ${status}</strong><br>
${status === '✅ ACEITA' ? 'Descontinuidade dentro dos limites permitidos. A solda está APROVADA para serviço.' :
status === '❌ REJEITA' ? 'Descontinuidade excede limites. REPROVAR a solda e realizar retrabalho.' :
'Descontinuidade requer análise de engenharia detalhada antes da aprovação.'}
</div>
${status === '❌ REJEITA' ? `
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-6); border-radius: 8px;">
<strong>🔧 OPÇÕES DE REPARO:</strong><br>
1. <strong>Retrabalho Total:</strong> Remover completamente a solda defeituosa e refazer<br>
2. <strong>Retoque Local:</strong> Escarear o defeito e preencher com nova solda<br>
3. <strong>Análise de Risco:</strong> Para casos não-críticos, avaliar se pode ser aceito com ressalvas
</div>
` : ''}
</div>
`;
addToHistory('Ultrassom', `${typeName}, ${status}`);
}
function calcularCustoTotal() {
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 },
sul: { padrao: 75, premium: 115, economica: 48 },
nordeste: { padrao: 85, premium: 125, economica: 52 },
centrooeste: { padrao: 82, premium: 122, economica: 51 }
};
const precoLitro = precosTinta[regiao][tipoTinta];
const custoMaterial = volume * precoLitro;
const horasTotais = area / prod;
const custoMaoObra = horasTotais * custoMO;
const custoEPI = incluirEPI ? 500 : 0;
const custoEquip = incluirEquip ? 800 : 0;
const subtotal = custoMaterial + custoMaoObra + custoEPI + custoEquip;
const margem = subtotal * 0.10;
const total = subtotal + margem;
const custoPorM2 = total / area;
const regiaoNome = {
sudeste: 'Sudeste',
sul: 'Sul',
nordeste: 'Nordeste',
centrooeste: 'Centro-Oeste'
}[regiao];
const tintaNome = {
padrao: 'Padrão Industrial',
premium: 'Premium',
economica: 'Econômica'
}[tipoTinta];
document.getElementById('custo-result').innerHTML = `
<div class="result-box" style="background: var(--color-bg-2); border-left: 4px solid var(--color-warning);">
<div class="result-title">💰 CUSTO TOTAL - RESULTADO</div>
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>PARÂMETROS:</strong><br>
Área: ${area} m²<br>
Região: ${regiaoNome}<br>
Tinta: ${tintaNome} (R$ ${precoLitro}/L)<br>
Volume: ${volume} L
</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Custo Material (Tinta)</div>
<div class="result-value">R$ ${custoMaterial.toFixed(2)}</div>
</div>
<div class="result-item">
<div class="result-label">Custo Mão de Obra</div>
<div class="result-value">R$ ${custoMaoObra.toFixed(2)}</div>
</div>
${incluirEPI ? `
<div class="result-item">
<div class="result-label">EPI e Consumíveis</div>
<div class="result-value">R$ ${custoEPI.toFixed(2)}</div>
</div>
` : ''}
${incluirEquip ? `
<div class="result-item">
<div class="result-label">Aluguel Equipamentos</div>
<div class="result-value">R$ ${custoEquip.toFixed(2)}</div>
</div>
` : ''}
</div>
<div style="margin-top: 20px; padding: 20px; background: var(--color-bg-3); border-radius: 12px; border: 2px solid var(--color-success);">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
<div>
<strong>Subtotal:</strong><br>
<span style="font-size: 20px;">R$ ${subtotal.toFixed(2)}</span>
</div>
<div>
<strong>Margem (10%):</strong><br>
<span style="font-size: 20px;">R$ ${margem.toFixed(2)}</span>
</div>
</div>
<hr style="margin: 16px 0; border: 1px solid var(--color-border);">
<div style="text-align: center;">
<strong style="font-size: 18px;">TOTAL GERAL:</strong><br>
<span style="font-size: 32px; color: var(--color-success); font-weight: bold;">R$ ${total.toFixed(2)}</span><br>
<span style="color: var(--color-text-secondary);">(Custo por m²: R$ ${custoPorM2.toFixed(2)}/m²)</span>
</div>
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>📊 BREAKDOWN DETALHADO:</strong><br>
• Horas totais: ${horasTotais.toFixed(1)} h (${area}m² ÷ ${prod}m²/h)<br>
• Custo/hora MO: R$ ${custoMO}/h<br>
• Produtividade: ${prod} m²/h<br>
• Tempo estimado: ${Math.ceil(horasTotais / 8)} dias (8h/dia)
</div>
</div>
`;
addToHistory('Custo Pintura', `${area}m², R$ ${total.toFixed(2)}`);
}
function calcularSecagem() {
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 },
poliuretano: { tempIdeal: 20, umidadeMax: 80, tempoBase: 16, fatorEsp: 0.15 },
alquidica: { tempIdeal: 25, umidadeMax: 75, tempoBase: 48, fatorEsp: 0.3 },
acrilica: { tempIdeal: 23, umidadeMax: 70, tempoBase: 12, fatorEsp: 0.1 }
};
const dados = dadosTinta[tipo];
const fatorTemp = 1 + ((dados.tempIdeal - temp) * 0.05);
const fatorUmid = umidade > dados.umidadeMax ? 1.3 : 1.0;
const fatorEsp = 1 + ((espessura - 80) / 80 * dados.fatorEsp);
const tempoToque = dados.tempoBase * 0.25 * fatorTemp * fatorUmid * fatorEsp;
const tempoManipulacao = dados.tempoBase * 0.5 * fatorTemp * fatorUmid * fatorEsp;
const tempoProximaDemao = dados.tempoBase * fatorTemp * fatorUmid * fatorEsp;
const tempoCuraTotal = dados.tempoBase * 3 * fatorTemp * fatorUmid * fatorEsp;
let alertas = [];
let alertClass = 'alert-success';
if (temp < 5) {
alertas.push('⚠️ Temperatura muito baixa (< 5°C) - NÃO APLICAR');
alertClass = 'alert-error';
} else if (temp < 10) {
alertas.push('⚠️ Temperatura baixa - Tempo de secagem significativamente aumentado');
alertClass = 'alert-warning';
}
if (umidade > dados.umidadeMax) {
alertas.push(`⚠️ Umidade acima do máximo (${dados.umidadeMax}%) - Risco de defeitos`);
alertClass = 'alert-error';
} else if (umidade > dados.umidadeMax - 10) {
alertas.push(`⚠️ Umidade próxima do limite - Monitorar condições`);
if (alertClass !== 'alert-error') alertClass = 'alert-warning';
}
if (temp > 40) {
alertas.push('⚠️ Temperatura muito alta - Risco de secagem rápida e defeitos');
if (alertClass !== 'alert-error') alertClass = 'alert-warning';
}
if (alertas.length === 0) {
alertas.push('✅ Condições ideais para aplicação');
}
const tipoNome = {
epoxi: 'Epóxi (2 componentes)',
poliuretano: 'Poliuretano (PU)',
alquidica: 'Alquídica',
acrilica: 'Acrílica'
}[tipo];
document.getElementById('sec-result').innerHTML = `
<div class="result-box" style="background: var(--color-bg-5); border-left: 4px solid #a855f7;">
<div class="result-title">⏱️ TEMPO DE SECAGEM - RESULTADO</div>
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>TIPO DE TINTA:</strong> ${tipoNome}<br>
<strong>Temperatura:</strong> ${temp}°C<br>
<strong>Umidade Relativa:</strong> ${umidade}%<br>
<strong>Espessura:</strong> ${espessura} μm
</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Secagem ao Toque</div>
<div class="result-value">${Math.round(tempoToque)} h</div>
</div>
<div class="result-item">
<div class="result-label">Manipulação</div>
<div class="result-value">${Math.round(tempoManipulacao)} h</div>
</div>
<div class="result-item">
<div class="result-label">Próxima Demão</div>
<div class="result-value">${Math.round(tempoProximaDemao)} h</div>
</div>
<div class="result-item">
<div class="result-label">Cura Total</div>
<div class="result-value">${Math.round(tempoCuraTotal / 24)} dias</div>
</div>
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">
<strong>📊 FATORES DE CORREÇÃO APLICADOS:</strong><br>
• Fator Temperatura: ${fatorTemp.toFixed(2)}×<br>
• Fator Umidade: ${fatorUmid.toFixed(2)}×<br>
• Fator Espessura: ${fatorEsp.toFixed(2)}×<br>
• Tempo Base (${tipoNome}): ${dados.tempoBase}h
</div>
<div class="alert ${alertClass}" style="margin-top: 16px;">
<strong>ALERTAS E RECOMENDAÇÕES:</strong><br>
${alertas.map(a => `${a}`).join('<br>')}
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>💡 DICAS PARA MELHORAR CONDIÇÕES:</strong><br>
${temp < 15 ? '• Aumentar temperatura do ambiente com aquecedores<br>' : ''}
${umidade > 75 ? '• Usar desumidificadores ou melhorar ventilação<br>' : ''}
• Aplicar em horários de menor umidade (meio-dia)<br>
• Evitar aplicação com orvalho ou chuva prevista<br>
• Proteger superfície de contaminação durante secagem
</div>
</div>
`;
addToHistory('Tempo Secagem', `${tipoNome}, ${Math.round(tempoProximaDemao)}h`);
}
function gerarRelatorioInspecao() {
const checks = [];
for (let i = 1; i <= 8; i++) {
const checkbox = document.getElementById(`insp-${i}`);
checks.push({
id: i,
checked: checkbox.checked,
label: checkbox.nextElementSibling.textContent
});
}
const totalChecked = checks.filter(c => c.checked).length;
const percentApproved = (totalChecked / checks.length) * 100;
let status = '';
let alertClass = '';
let recommendation = '';
if (percentApproved === 100) {
status = '✅ APROVADO';
alertClass = 'alert-success';
recommendation = 'Todos os critérios foram atendidos. Pintura aprovada para aceitação final.';
} else if (percentApproved >= 75) {
status = '⚠️ APROVADO COM RESSALVAS';
alertClass = 'alert-warning';
recommendation = 'Maioria dos critérios atendidos. Verificar itens pendentes antes da liberação final.';
} else {
status = '❌ REPROVADO';
alertClass = 'alert-error';
recommendation = 'Vários critérios não atendidos. Realizar correções antes de aprovar.';
}
const uncheckedItems = checks.filter(c => !c.checked);
document.getElementById('insp-result').innerHTML = `
<div class="result-box" style="background: var(--color-bg-1); border-left: 4px solid var(--color-primary);">
<div class="result-title">📋 RELATÓRIO DE INSPEÇÃO</div>
<div style="margin-bottom: 20px; padding: 20px; background: var(--color-surface); border-radius: 12px; text-align: center;">
<div style="font-size: 48px; margin-bottom: 10px;">${Math.round(percentApproved)}%</div>
<div style="font-size: 18px; font-weight: bold;">${totalChecked} de ${checks.length} critérios aprovados</div>
</div>
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px;">
<strong>ITENS VERIFICADOS:</strong><br><br>
${checks.map(c => `
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 8px;">
<span style="font-size: 20px;">${c.checked ? '✅' : '❌'}</span>
<span style="${c.checked ? '' : 'color: var(--color-error); font-weight: bold;'}">${c.label}</span>
</div>
`).join('')}
</div>
${uncheckedItems.length > 0 ? `
<div style="padding: 16px; background: var(--color-bg-4); border-radius: 8px; margin-bottom: 16px; border: 2px solid var(--color-error);">
<strong>⚠️ ITENS NÃO CONFORMES (${uncheckedItems.length}):</strong><br><br>
${uncheckedItems.map((item, idx) => `${idx + 1}. ${item.label}`).join('<br>')}
</div>
` : ''}
<div class="alert ${alertClass}">
<strong>STATUS: ${status}</strong><br>
${recommendation}
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-3); border-radius: 8px;">
<strong>📝 AÇÕES CORRETIVAS SUGERIDAS:</strong><br>
${uncheckedItems.length > 0 ? `
${uncheckedItems.map((item, idx) => {
let action = '';
if (item.id === 1) action = 'Realizar nova preparação com grau Sa 2½';
else if (item.id === 2) action = 'Limpar superfície com solvente adequado';
else if (item.id === 3) action = 'Aplicar demão adicional para atingir DFT especificado';
else if (item.id === 4) action = 'Melhorar técnica de aplicação ou preparação';
else if (item.id === 5) action = 'Aplicar retoque ou nova demão';
else if (item.id === 6) action = 'Aplicar nova demão nas áreas descobertas';
else if (item.id === 7) action = 'Remover defeitos e reaplicar';
else if (item.id === 8) action = 'Aguardar tempo de cura adequado';
return `${idx + 1}. ${action}`;
}).join('<br>')}
` : 'Nenhuma ação corretiva necessária ✓'}
</div>
<div style="margin-top: 20px; text-align: center;">
<strong>Data da Inspeção:</strong> ${new Date().toLocaleDateString('pt-BR')}<br>
<strong>Norma de Referência:</strong> ISO 12944
</div>
</div>
`;
addToHistory('Inspeção Pintura', `${percentApproved.toFixed(0)}% aprovado, ${status}`);
}
function getSectionName(sectionId) {
const names = {
'cev': 'CEV Avançado',
'seletor': 'Seletor de Aço',
'equivalencias': 'Equivalências',
'comparativo': 'Comparativo',
'parafusos': 'Ligações Parafusadas',
'layout': 'Layout de Furação',
'parafuso-vs-solda': 'Parafuso vs Solda',
'preaquecimento': 'Pré-Aquecimento',
'solda-filete': 'Solda Filete',
'energia-soldagem': 'Energia de Soldagem',
'consumo-eletrodos': 'Consumo de Eletrodos',
'dureza': 'Dureza',
'charpy': 'Charpy',
'certificado': 'Certificado',
'ultrassom': 'Ultrassom',
'area-pintura': 'Área de Pintura',
'consumo-tinta': 'Consumo de Tinta',
'galvanizacao': 'Galvanização',
'custo-pintura': 'Custo Pintura',
'secagem': 'Secagem',
'inspecao-pintura': 'Inspeção',
'orcamento': 'Orçamento',
'peso-rigging': 'Peso & Rigging',
'referencia': 'Referência'
};
return names[sectionId] || sectionId;
}
// ========================================
// SECTION CONTENT GENERATORS
// ========================================
function getCEVContent() {
return `
<div class="section-header">
<div class="section-title">🔬 CEV Avançado (IIW + Pcm)</div>
<div class="section-description">Cálculo do Carbono Equivalente para avaliação de soldabilidade segundo IIW e Pcm</div>
</div>
<div class="card">
<div class="card-title">Composição Química (%)</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Carbono (C)</label>
<input type="number" class="form-control" id="cev-c" step="0.01" value="0.20">
</div>
<div class="form-group">
<label class="form-label">Manganês (Mn)</label>
<input type="number" class="form-control" id="cev-mn" step="0.01" value="1.00">
</div>
<div class="form-group">
<label class="form-label">Cromo (Cr)</label>
<input type="number" class="form-control" id="cev-cr" step="0.01" value="0.10">
</div>
<div class="form-group">
<label class="form-label">Molibdênio (Mo)</label>
<input type="number" class="form-control" id="cev-mo" step="0.01" value="0.05">
</div>
<div class="form-group">
<label class="form-label">Vanádio (V)</label>
<input type="number" class="form-control" id="cev-v" step="0.01" value="0.03">
</div>
<div class="form-group">
<label class="form-label">Níquel (Ni)</label>
<input type="number" class="form-control" id="cev-ni" step="0.01" value="0.10">
</div>
<div class="form-group">
<label class="form-label">Cobre (Cu)</label>
<input type="number" class="form-control" id="cev-cu" step="0.01" value="0.10">
</div>
<div class="form-group expert-only">
<label class="form-label">Silício (Si)</label>
<input type="number" class="form-control" id="cev-si" step="0.01" value="0.25">
</div>
</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Espessura (mm)</label>
<input type="number" class="form-control" id="cev-thickness" step="1" value="25">
</div>
<div class="form-group expert-only">
<label class="form-label">Temperatura Ambiente (°C)</label>
<input type="number" class="form-control" id="cev-temp" step="1" value="20">
</div>
<div class="form-group expert-only">
<label class="form-label">Fórmula</label>
<select class="form-control" id="cev-formula">
<option value="iw">IIW (Padrão)</option>
<option value="pcm">Pcm (Alta resistência)</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="calcularCEV()">🔬 Calcular CEV</button>
</div>
<div id="cev-result"></div>
`;
}
function getSeletorContent() {
return `
<div class="section-header">
<div class="section-title">🎯 Seletor de Aço Inteligente</div>
<div class="section-description">Selecione o aço ideal baseado em critérios técnicos</div>
</div>
<div class="card">
<div class="card-title">Critérios de Seleção</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Aplicação</label>
<select class="form-control" id="sel-app">
<option value="edificio">Edifício</option>
<option value="ponte">Ponte</option>
<option value="offshore">Offshore</option>
<option value="industrial">Industrial</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Temperatura de Serviço (°C)</label>
<input type="number" class="form-control" id="sel-temp" value="20">
</div>
<div class="form-group">
<label class="form-label">Resistência Mínima (MPa)</label>
<input type="number" class="form-control" id="sel-fy" value="250">
</div>
<div class="form-group">
<label class="form-label">Soldabilidade</label>
<select class="form-control" id="sel-weld">
<option value="any">Qualquer</option>
<option value="excellent">Excelente</option>
<option value="good">Boa</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="selecionarAco()">🎯 Buscar Aços</button>
</div>
<div id="seletor-result"></div>
`;
}
function getEquivalenciasContent() {
return `
<div class="section-header">
<div class="section-title">📊 Equivalências Internacionais</div>
<div class="section-description">Tabela de equivalências entre normas ASTM, EN, JIS, NBR</div>
</div>
<div class="card">
<div class="card-title">Selecionar Aço</div>
<div class="form-group">
<label class="form-label">Aço de Referência</label>
<select class="form-control" id="equiv-steel" onchange="mostrarEquivalencias()">
<option value="a36">ASTM A36</option>
<option value="a572">ASTM A572 Gr.50</option>
<option value="a588">ASTM A588</option>
<option value="s235">EN S235JR</option>
<option value="s355">EN S355J2</option>
<option value="ar350">NBR AR350</option>
</select>
</div>
</div>
<div id="equiv-result"></div>
`;
}
function getComparativoContent() {
return `
<div class="section-header">
<div class="section-title">📈 Comparativo de Aços</div>
<div class="section-description">Comparação visual de propriedades mecânicas</div>
</div>
<div class="card">
<div class="card-title">Selecionar Aços para Comparação</div>
<div class="checkbox-group">
<label class="checkbox-item">
<input type="checkbox" value="a36" checked> A36
</label>
<label class="checkbox-item">
<input type="checkbox" value="a572" checked> A572
</label>
<label class="checkbox-item">
<input type="checkbox" value="a588"> A588
</label>
<label class="checkbox-item">
<input type="checkbox" value="s235"> S235
</label>
<label class="checkbox-item">
<input type="checkbox" value="s355"> S355
</label>
<label class="checkbox-item">
<input type="checkbox" value="s460"> S460
</label>
</div>
<div class="form-group">
<label class="form-label">Tipo de Visualização</label>
<select class="form-control" id="chart-type" style="max-width: 300px;">
<option value="resistance">Resistência (fy vs fu)</option>
<option value="ductility">Ductilidade</option>
<option value="table">Tabela Comparativa</option>
</select>
</div>
<button class="btn btn-primary" onclick="gerarGraficoComparativo()">📊 Gerar Comparação</button>
</div>
<div id="chart-result"></div>
`;
}
// Assistente Inteligente - Integrated Recommendation System
function getAssistenteInteligenteContent() {
return `
<div class="section-header">
<div class="section-title">🤖 Assistente Inteligente de Seleção</div>
<div class="section-description">Recomendação integrada: Aço + Soldagem + Pintura baseada em relacionamentos técnicos</div>
</div>
<div class="card" style="background: var(--color-bg-1); border: 2px solid var(--color-primary);">
<div class="card-title">🎯 Seleção de Requisitos</div>
<p style="color: var(--color-text-secondary); margin-bottom: 16px;">
Informe os requisitos do projeto e receba recomendações técnicas completas
</p>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Aço Estrutural</label>
<select class="form-control" id="ai-steel" onchange="updateAIRecommendations()">
<option value="">-- Selecione o aço --</option>
<option value="ASTM A36">ASTM A36 - Construção civil leve</option>
<option value="ASTM A572 Gr.50">ASTM A572 Gr.50 - Estruturas médias/pesadas</option>
<option value="ASTM A572 Gr.60">ASTM A572 Gr.60 - Estruturas muito pesadas</option>
<option value="ASTM A588">ASTM A588 - Cor-Ten (sem pintura)</option>
<option value="ASTM A992">ASTM A992 - Perfis modernos</option>
<option value="ASTM A106">ASTM A106 - Tubulações alta pressão</option>
<option value="ASTM A709 Gr.50">ASTM A709 Gr.50 - Pontes</option>
<option value="EN S235JR">EN S235JR - Construção Europa</option>
<option value="EN S275">EN S275 - Estruturas médias Europa</option>
<option value="EN S355J2">EN S355J2 - Estruturas pesadas Europa</option>
<option value="EN S460">EN S460 - Alta resistência Europa</option>
<option value="NBR 7007 MR250">NBR 7007 MR250 - Brasil (equiv. A36)</option>
<option value="NBR 7007 AR290">NBR 7007 AR290 - Brasil média resist.</option>
<option value="NBR 7007 AR345">NBR 7007 AR345 - Brasil alta resist.</option>
<option value="ASTM A304">ASTM A304 (SS304) - Inox</option>
<option value="ASTM A316">ASTM A316 (SS316) - Inox marinho</option>
<option value="ABS Grade A">ABS Grade A - Naval mercante</option>
<option value="ABS Grade B">ABS Grade B - Naval reforçado</option>
<option value="ABS Grade AH36">ABS Grade AH36 - Naval alta resist.</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Ambiente Corrosivo</label>
<select class="form-control" id="ai-environment" onchange="updateAIRecommendations()">
<option value="">-- Selecione o ambiente --</option>
<option value="C2">C2 - Urbano (baixa corrosão)</option>
<option value="C3">C3 - Industrial/Costeiro</option>
<option value="C4">C4 - Marinho/Industrial severo</option>
<option value="C5">C5 - Offshore/Extremo</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="generateAIRecommendation()" style="width: 100%;">
🤖 Gerar Recomendação Completa
</button>
</div>
<div id="ai-recommendations"></div>
`;
}
// ========================================
// NEW MATERIAL SECTIONS - PLACEHOLDERS
// ========================================
// CONSUMÍVEIS DE SOLDAGEM
function getEletrodosContent() {
return `<div class="section-header"><div class="section-title">⚡ Eletrodos Revestidos</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Catálogo de eletrodos revestidos (SMAW)</p></div>`;
}
function getAramesContent() {
return `<div class="section-header"><div class="section-title">🌀 Arames Sólidos/Tubulares</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Catálogo de arames para GMAW/FCAW</p></div>`;
}
function getFluxosContent() {
return `<div class="section-header"><div class="section-title">💨 Fluxos para SAW</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Catálogo de fluxos para soldagem ao arco submerso</p></div>`;
}
function getGasesContent() {
return `<div class="section-header"><div class="section-title">🌫️ Gases de Proteção</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Gases e misturas para soldagem</p></div>`;
}
// FIXADORES
function getParafusosCatalogoContent() {
return `<div class="section-header"><div class="section-title">🔩 Catálogo de Parafusos</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Especificações técnicas de parafusos</p></div>`;
}
function getPorcasContent() {
return `<div class="section-header"><div class="section-title">🔸 Porcas</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Catálogo de porcas</p></div>`;
}
function getArruelasContent() {
return `<div class="section-header"><div class="section-title">⭕ Arruelas</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Catálogo de arruelas</p></div>`;
}
function getChumbadoresContent() {
return `<div class="section-header"><div class="section-title">🔗 Chumbadores/Ancoragens</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Sistemas de ancoragem</p></div>`;
}
// TINTAS E REVESTIMENTOS
function getTintasCatalogoContent() {
return `<div class="section-header"><div class="section-title">🎨 Catálogo de Tintas</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Especificações técnicas de tintas</p></div>`;
}
function getSistemasPinturaContent() {
return `<div class="section-header"><div class="section-title">🖌️ Sistemas de Pintura</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Sistemas completos por ambiente</p></div>`;
}
function getAbrasivosContent() {
return `<div class="section-header"><div class="section-title">💎 Abrasivos para Jateamento</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Tipos de abrasivos e aplicações</p></div>`;
}
function getGranalhaContent() {
return `<div class="section-header"><div class="section-title">🔘 Granalha Metálica</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Granalha de aço para jateamento</p></div>`;
}
// ELEMENTOS COMPLEMENTARES
function getTelhasContent() {
return `<div class="section-header"><div class="section-title">🏠 Telhas Metálicas</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Especificações de telhas metálicas</p></div>`;
}
function getPaineisContent() {
return `<div class="section-header"><div class="section-title">🧱 Painéis Sanduíche</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Painéis termoacústicos</p></div>`;
}
function getSteelDeckContent() {
return `<div class="section-header"><div class="section-title">📐 Steel Deck</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Lajes mistas com steel deck</p></div>`;
}
function getPerfisFormadosContent() {
return `<div class="section-header"><div class="section-title">🔲 Perfis Formados a Frio</div></div>
<div class="card"><p>🚧 Seção em desenvolvimento - Light steel framing</p></div>`;
}
// ========================================
// CATÁLOGO DE PERFIS - FUNÇÕES DE CONTEÚDO
// ========================================
function getTubosRHSContent() {
return `
<div class="section-header">
<div class="section-title">▭ Tubos RHS (Retangulares)</div>
<div class="section-description">Catálogo completo de tubos retangulares estruturais</div>
</div>
<div class="tabs-container">
<div class="tabs-nav">
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">📊 Tabela Técnica</button>
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">📋 Especificações</button>
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">🏭 Fabricantes</button>
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">💰 Preços 2025</button>
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">🔧 Aplicações</button>
</div>
<!-- Tab 1: Tabela Técnica -->
<div class="tab-content active" id="tab-0">
<div class="card" style="background: var(--color-bg-1);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<div>
<h3 style="margin: 0; color: var(--color-primary);">📊 Tubos RHS Disponíveis</h3>
<p style="margin: 8px 0 0 0; color: var(--color-text-secondary);">
Total: <strong id="tubos_rhs-total">-</strong> perfis
</p>
</div>
<button class="btn btn-primary" onclick="forcarCarregamentoTubosRhs()">
🔄 Recarregar Dados
</button>
</div>
<div style="overflow-x: auto;">
<table class="data-table">
<thead>
<tr>
<th>Designação</th>
<th>Largura (mm)</th>
<th>Altura (mm)</th>
<th>Espessura (mm)</th>
<th>Peso (kg/m)</th>
<th>Área (cm²)</th>
<th>Categoria</th>
<th>Ações</th>
</tr>
</thead>
<tbody id="tubos_rhs-tbody">
<tr>
<td colspan="8" style="text-align: center; padding: 40px;">
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
<div style="font-size: 18px; font-weight: bold;">Carregando tubos RHS...</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tab 2: Especificações -->
<div class="tab-content" id="tab-1">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">📋 Especificações Técnicas Completas</h3>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">🔧 Descrição Geral</h4>
<p><strong>Tubos estruturais retangulares/quadrados sem costura e soldados</strong></p>
<p>Perfis estruturais versáteis amplamente utilizados em construção civil, naval e industrial. Fabricados por soldagem ou sem costura, apresentam excelente relação resistência/peso e simetria estrutural.</p>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📏 Faixa de Dimensões</h4>
<ul>
<li><strong>Dimensões:</strong> 50×50×2mm a 250×250×8mm</li>
<li><strong>Espessura:</strong> 2mm a 8mm</li>
<li><strong>Quantidade de modelos:</strong> 35 perfis diferentes</li>
</ul>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Distribuição dos Modelos</h4>
<table class="data-table">
<thead>
<tr>
<th>Categoria</th>
<th>Dimensões</th>
<th>Quantidade</th>
<th>Aplicações Típicas</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="badge badge-info">Pequeno</span></td>
<td>50×50 - 60×60</td>
<td>4 modelos</td>
<td>Estruturas leves, suportes</td>
</tr>
<tr>
<td><span class="badge badge-info">Médio</span></td>
<td>75 - 100</td>
<td>5 modelos</td>
<td>Treliças, galpões pequenos</td>
</tr>
<tr>
<td><span class="badge badge-warning">Grande</span></td>
<td>120 - 150</td>
<td>7 modelos</td>
<td>Estruturas médias, torres</td>
</tr>
<tr>
<td><span class="badge badge-warning">Muito Grande</span></td>
<td>150 - 200</td>
<td>10 modelos</td>
<td>Estruturas críticas, pontes</td>
</tr>
<tr>
<td><span class="badge badge-danger">Massivo</span></td>
<td>200 - 250</td>
<td>9 modelos</td>
<td>Estruturas offshore, navais</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">🔬 Qualidades Disponíveis (SAE)</h4>
<table class="data-table">
<thead>
<tr>
<th>Qualidade</th>
<th>Fy (MPa)</th>
<th>Fu (MPa)</th>
<th>Aplicação</th>
</tr>
</thead>
<tbody>
<tr>
<td>SAE 1008-1015</td>
<td>210</td>
<td>400</td>
<td>Básica - estruturas leves</td>
</tr>
<tr>
<td>SAE 1020-1025</td>
<td>235</td>
<td>420</td>
<td>Média - estruturas gerais</td>
</tr>
<tr>
<td>SAE 1035-1045</td>
<td>280</td>
<td>520</td>
<td>Alta - estruturas pesadas</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tab 3: Fabricantes -->
<div class="tab-content" id="tab-2">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🏭 Fabricantes no Brasil</h3>
<table class="data-table">
<thead>
<tr>
<th>Fabricante</th>
<th>Localização</th>
<th>Gama de Produtos</th>
<th>Especialidade</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Gerdau</strong></td>
<td>Múltiplas plantas</td>
<td>Completa</td>
<td>Principal fornecedor nacional</td>
</tr>
<tr>
<td><strong>CSN</strong></td>
<td>Volta Redonda (RJ)</td>
<td>Média a Grande</td>
<td>Séries pesadas</td>
</tr>
<tr>
<td><strong>Usiminas</strong></td>
<td>Ipatinga (MG)</td>
<td>Pequena a Média</td>
<td>Qualidades especiais</td>
</tr>
<tr>
<td><strong>Tupy</strong></td>
<td>Joinville (SC)</td>
<td>Média</td>
<td>Tubos especiais</td>
</tr>
<tr>
<td><strong>Vallourec</strong></td>
<td>Múltiplas</td>
<td>Pequena</td>
<td>Tubos sem costura</td>
</tr>
<tr>
<td><strong>Confab</strong></td>
<td>Pindamonhangaba (SP)</td>
<td>Média a Grande</td>
<td>Tubos industriais</td>
</tr>
</tbody>
</table>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">📦 Comprimentos Comerciais</h4>
<p><strong>Padrão:</strong> 6m, 9m, 12m, 13.5m</p>
<p><strong>Especiais:</strong> Sob consulta</p>
</div>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">⏱️ Prazos de Entrega</h4>
<ul>
<li><strong>Estoque:</strong> 3-5 dias</li>
<li><strong>Sob encomenda:</strong> 7-12 dias</li>
<li><strong>Especiais:</strong> 15-25 dias</li>
</ul>
</div>
</div>
</div>
<!-- Tab 4: Preços 2025 -->
<div class="tab-content" id="tab-3">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">💰 Preços 2025</h3>
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
<strong>⚠️ Preços de Referência:</strong> Valores médios de mercado. Consulte fornecedores para cotação atualizada.
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">💵 Faixa de Preços</h4>
<p><strong>Preço base:</strong> R$ 4,50 - R$ 10,00 por kg</p>
<p><strong>Variação por região:</strong> ±10-15%</p>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Fatores de Preço</h4>
<table class="data-table">
<thead>
<tr>
<th>Situação</th>
<th>Variação</th>
<th>Observação</th>
</tr>
</thead>
<tbody>
<tr>
<td>Modelos pequenos (50-75mm)</td>
<td><span class="badge badge-danger">+15%</span></td>
<td>Menor demanda</td>
</tr>
<tr>
<td>Modelos assimétricos</td>
<td><span class="badge badge-warning">+10%</span></td>
<td>Produção especial</td>
</tr>
<tr>
<td>Paredes finas</td>
<td><span class="badge badge-warning">+5%</span></td>
<td>Processo delicado</td>
</tr>
<tr>
<td>Quantidade >20 toneladas</td>
<td><span class="badge badge-success">-15%</span></td>
<td>Desconto por volume</td>
</tr>
<tr>
<td>Corte customizado</td>
<td><span class="badge badge-warning">+taxa</span></td>
<td>Serviço adicional</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📋 Normas Aplicáveis</h4>
<ul>
<li><strong>ABNT NBR 6591</strong> - Tubos de aço carbono para usos comuns</li>
<li><strong>ASTM A500</strong> - Tubos estruturais formados a frio</li>
<li><strong>EN 10210-1</strong> - Perfis estruturais acabados a quente</li>
<li><strong>API 5L</strong> - Tubos para transporte (aplicável)</li>
</ul>
</div>
</div>
</div>
<!-- Tab 5: Aplicações -->
<div class="tab-content" id="tab-4">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🔧 Aplicações Principais</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🏗️ Construção Civil</h4>
<ul>
<li>Torres e antenas</li>
<li>Estruturas simétricas</li>
<li>Colunas estruturais</li>
<li>Treliças espaciais</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">⚓ Estruturas Marítimas</h4>
<ul>
<li>Plataformas offshore</li>
<li>Estruturas portuárias</li>
<li>Suportes subaquáticos</li>
<li>Estruturas navais</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🏭 Industrial</h4>
<ul>
<li>Suportes de equipamentos</li>
<li>Estruturas de máquinas</li>
<li>Plataformas industriais</li>
<li>Chassis e estruturas</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🌉 Infraestrutura</h4>
<ul>
<li>Pontes e viadutos</li>
<li>Passarelas</li>
<li>Estruturas de contenção</li>
<li>Suportes de sinalização</li>
</ul>
</div>
</div>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">✅ Recomendações de Uso</h4>
<ul>
<li>✓ Resistência à torção superior a perfis abertos</li>
<li>✓ Simetria facilita ligações e cálculos</li>
<li>✓ Teste de pressão 100% em modelos maiores</li>
<li>✓ Costura visível (sem costura sob pedido premium)</li>
<li>✓ Tolerância dimensional ±1mm</li>
<li>✓ Soldagem com E7018 ou GMAW recomendada</li>
<li>✓ Verificar flambagem em ambos os eixos</li>
</ul>
</div>
</div>
</div>
</div>
`;
}
function getChapasContent() {
return `
<div class="section-header">
<div class="section-title">📄 Chapas de Aço</div>
<div class="section-description">Catálogo completo de chapas estruturais</div>
</div>
<div class="tabs-container">
<div class="tabs-nav">
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">📊 Tabela Técnica</button>
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">📋 Especificações</button>
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">🏭 Fabricantes</button>
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">💰 Preços 2025</button>
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">🔧 Aplicações</button>
</div>
<!-- Tab 1: Tabela Técnica -->
<div class="tab-content active" id="tab-0">
<div class="card" style="background: var(--color-bg-1);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<div>
<h3 style="margin: 0; color: var(--color-primary);">📊 Chapas Disponíveis</h3>
<p style="margin: 8px 0 0 0; color: var(--color-text-secondary);">
Total: <strong id="chapas-total">-</strong> espessuras
</p>
</div>
<button class="btn btn-primary" onclick="forcarCarregamentoChapas()">
🔄 Recarregar Dados
</button>
</div>
<div style="overflow-x: auto;">
<table class="data-table">
<thead>
<tr>
<th>Designação</th>
<th>Espessura (mm)</th>
<th>Peso (kg/m²)</th>
<th>Categoria</th>
<th>Ações</th>
</tr>
</thead>
<tbody id="chapas-tbody">
<tr>
<td colspan="5" style="text-align: center; padding: 40px;">
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
<div style="font-size: 18px; font-weight: bold;">Carregando chapas...</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tab 2: Especificações -->
<div class="tab-content" id="tab-1">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">📋 Especificações Técnicas Completas</h3>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">🔧 Descrição Geral</h4>
<p><strong>Chapas de aço carbono laminadas a quente</strong></p>
<p>Produtos planos de aço carbono laminados a quente, utilizados em estruturas soldadas, equipamentos industriais e componentes estruturais. Disponíveis em diversos formatos e espessuras.</p>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📏 Faixa de Dimensões</h4>
<ul>
<li><strong>Espessura:</strong> 3.2mm a 50.8mm</li>
<li><strong>Formatos:</strong> 2500×1250mm a 2000×1000mm</li>
<li><strong>Peso:</strong> 25.12 kg/m² a 399.40 kg/m²</li>
<li><strong>Quantidade de modelos:</strong> 16 espessuras diferentes</li>
</ul>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Distribuição dos Modelos</h4>
<table class="data-table">
<thead>
<tr>
<th>Categoria</th>
<th>Espessura</th>
<th>Quantidade</th>
<th>Aplicações Típicas</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="badge badge-info">Fina</span></td>
<td>3.2 - 4.75mm</td>
<td>1 modelo</td>
<td>Chapas decorativas, revestimentos</td>
</tr>
<tr>
<td><span class="badge badge-info">Média</span></td>
<td>6.35 - 9.5mm</td>
<td>3 modelos</td>
<td>Estruturas gerais, tanques</td>
</tr>
<tr>
<td><span class="badge badge-warning">Grossa</span></td>
<td>12.7 - 25.4mm</td>
<td>4 modelos</td>
<td>Estruturas críticas, bases</td>
</tr>
<tr>
<td><span class="badge badge-warning">Muito Grossa</span></td>
<td>31.75 - 44.5mm</td>
<td>4 modelos</td>
<td>Offshore, equipamentos pesados</td>
</tr>
<tr>
<td><span class="badge badge-danger">Ultra Grossa</span></td>
<td>38.1 - 50.8mm</td>
<td>4 modelos</td>
<td>Aplicações extremas, blindagem</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">🔬 Qualidades Disponíveis (SAE)</h4>
<table class="data-table">
<thead>
<tr>
<th>Qualidade</th>
<th>Fy (MPa)</th>
<th>Fu (MPa)</th>
<th>Aplicação</th>
</tr>
</thead>
<tbody>
<tr>
<td>SAE 1008-1025</td>
<td>210-235</td>
<td>400-420</td>
<td>Básica - estruturas gerais</td>
</tr>
<tr>
<td>SAE 1035-1055</td>
<td>280-340</td>
<td>490-580</td>
<td>Média - estruturas críticas</td>
</tr>
<tr>
<td>SAE 1080-1100</td>
<td>385-445</td>
<td>630-700</td>
<td>Alta - aplicações extremas</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tab 3: Fabricantes -->
<div class="tab-content" id="tab-2">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🏭 Fabricantes no Brasil</h3>
<table class="data-table">
<thead>
<tr>
<th>Fabricante</th>
<th>Localização</th>
<th>Gama de Produtos</th>
<th>Especialidade</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>CSN</strong></td>
<td>Volta Redonda (RJ)</td>
<td>Completa</td>
<td>Principal fornecedor nacional</td>
</tr>
<tr>
<td><strong>Gerdau</strong></td>
<td>Múltiplas plantas</td>
<td>Média a Grossa</td>
<td>Chapas estruturais</td>
</tr>
<tr>
<td><strong>Usiminas</strong></td>
<td>Ipatinga (MG)</td>
<td>Fina a Média</td>
<td>Qualidades especiais</td>
</tr>
<tr>
<td><strong>Vallourec</strong></td>
<td>Múltiplas</td>
<td>Grossa a Ultra</td>
<td>Chapas especiais</td>
</tr>
<tr>
<td><strong>Arcelor Mittal</strong></td>
<td>Tubarão (ES)</td>
<td>Completa</td>
<td>Exportação e mercado interno</td>
</tr>
<tr>
<td><strong>Confab</strong></td>
<td>Pindamonhangaba (SP)</td>
<td>Média a Grossa</td>
<td>Caldeiraria</td>
</tr>
</tbody>
</table>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">📦 Formatos Comerciais</h4>
<p><strong>Padrão:</strong> Formatos conforme espessura</p>
<p><strong>Customizado:</strong> Corte sob pedido</p>
</div>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">⏱️ Prazos de Entrega</h4>
<ul>
<li><strong>Estoque:</strong> 5-10 dias</li>
<li><strong>Sob encomenda:</strong> 15-25 dias</li>
<li><strong>Especiais:</strong> 30-45 dias</li>
</ul>
</div>
</div>
</div>
<!-- Tab 4: Preços 2025 -->
<div class="tab-content" id="tab-3">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">💰 Preços 2025</h3>
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
<strong>⚠️ Preços de Referência:</strong> Valores médios de mercado. Consulte fornecedores para cotação atualizada.
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">💵 Faixa de Preços</h4>
<p><strong>Preço base:</strong> R$ 3,00 - R$ 9,00 por kg</p>
<p><strong>Variação por região:</strong> ±10-15%</p>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Fatores de Preço</h4>
<table class="data-table">
<thead>
<tr>
<th>Situação</th>
<th>Variação</th>
<th>Observação</th>
</tr>
</thead>
<tbody>
<tr>
<td>Espessura >40mm</td>
<td><span class="badge badge-danger">+20%</span></td>
<td>Produção especial</td>
</tr>
<tr>
<td>Espessura <5mm</td>
<td><span class="badge badge-danger">+25%</span></td>
<td>Processo delicado</td>
</tr>
<tr>
<td>Corte customizado</td>
<td><span class="badge badge-warning">+10%</span></td>
<td>Serviço adicional</td>
</tr>
<tr>
<td>Quantidade >50 toneladas</td>
<td><span class="badge badge-success">-20%</span></td>
<td>Desconto por volume</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📋 Normas Aplicáveis</h4>
<ul>
<li><strong>ABNT NBR 5007</strong> - Chapas grossas de aço carbono</li>
<li><strong>ASTM A36</strong> - Aço estrutural carbono</li>
<li><strong>EN 10025-2</strong> - Produtos laminados a quente</li>
<li><strong>DIN 17102</strong> - Chapas e tiras de aço</li>
</ul>
</div>
</div>
</div>
<!-- Tab 5: Aplicações -->
<div class="tab-content" id="tab-4">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🔧 Aplicações Principais</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🏗️ Estruturas Soldadas</h4>
<ul>
<li>Vigas e colunas compostas</li>
<li>Estruturas de edifícios</li>
<li>Pontes e viadutos</li>
<li>Galpões industriais</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🏭 Equipamentos Industriais</h4>
<ul>
<li>Recipientes sob pressão</li>
<li>Tanques e reservatórios</li>
<li>Caldeiras</li>
<li>Vasos de processo</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">⚓ Estruturas Marítimas</h4>
<ul>
<li>Plataformas offshore</li>
<li>Cascos de navios</li>
<li>Estruturas portuárias</li>
<li>Componentes navais</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🛡️ Proteção e Blindagem</h4>
<ul>
<li>Blindagem balística</li>
<li>Proteção de equipamentos</li>
<li>Bases e fundações</li>
<li>Estruturas de contenção</li>
</ul>
</div>
</div>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">✅ Recomendações de Uso</h4>
<ul>
<li>✓ Soldabilidade garantida para todas as espessuras</li>
<li>✓ Identificação por tinta conforme norma</li>
<li>✓ Escalas de laminação visíveis (acabamento padrão)</li>
<li>✓ Filme de óleo de proteção contra corrosão</li>
<li>✓ Tolerância de espessura ±5%</li>
<li>✓ Soldagem com E7018 ou E8018 recomendada</li>
<li>✓ Pré-aquecimento necessário para espessuras >25mm</li>
</ul>
</div>
</div>
</div>
</div>
`;
}
function getPerfisHPContent() {
return `
<div class="section-header">
<div class="section-title">🏛️ Perfis HP (Heavy Pile - Estacas)</div>
<div class="section-description">Catálogo completo de perfis HP para fundações profundas</div>
</div>
<div class="tabs-container">
<div class="tabs-nav">
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">📊 Tabela Técnica</button>
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">📋 Especificações</button>
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">🏭 Fabricantes</button>
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">💰 Preços 2025</button>
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">🔧 Aplicações</button>
</div>
<!-- Tab 1: Tabela Técnica -->
<div class="tab-content active" id="tab-0">
<div class="card" style="background: var(--color-bg-1);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<div>
<h3 style="margin: 0; color: var(--color-primary);">📊 Perfis HP Disponíveis</h3>
<p style="margin: 8px 0 0 0; color: var(--color-text-secondary);">
Total: <strong id="perfis_hp-total">-</strong> perfis
</p>
</div>
<button class="btn btn-primary" onclick="forcarCarregamentoPerfisHp()">
🔄 Recarregar Dados
</button>
</div>
<div style="overflow-x: auto;">
<table class="data-table">
<thead>
<tr>
<th>Designação</th>
<th>Altura (mm)</th>
<th>Largura (mm)</th>
<th>Esp. Alma (mm)</th>
<th>Esp. Mesa (mm)</th>
<th>Peso (kg/m)</th>
<th>Área (cm²)</th>
<th>Categoria</th>
<th>Ações</th>
</tr>
</thead>
<tbody id="perfis_hp-tbody">
<tr>
<td colspan="9" style="text-align: center; padding: 40px;">
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
<div style="font-size: 18px; font-weight: bold;">Carregando perfis HP...</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tab 2: Especificações -->
<div class="tab-content" id="tab-1">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">📋 Especificações Técnicas Completas</h3>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">🔧 Descrição Geral</h4>
<p><strong>Perfis em H laminados a quente especializados em estacas (Heavy Pile)</strong></p>
<p>Perfis estruturais robustos projetados especificamente para fundações profundas e estacas cravadas. Apresentam seção H com abas e alma de espessuras similares, garantindo excelente resistência à compressão axial e cravação.</p>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📏 Faixa de Dimensões</h4>
<ul>
<li><strong>Dimensões:</strong> HP100 a HP350</li>
<li><strong>Peso:</strong> 20.0 kg/m a 132.0 kg/m</li>
<li><strong>Quantidade de modelos:</strong> 19 perfis diferentes</li>
</ul>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Distribuição dos Modelos</h4>
<table class="data-table">
<thead>
<tr>
<th>Categoria</th>
<th>Dimensões</th>
<th>Quantidade</th>
<th>Aplicações Típicas</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="badge badge-info">Pequeno</span></td>
<td>HP100</td>
<td>2 modelos</td>
<td>Estacas leves, contenções</td>
</tr>
<tr>
<td><span class="badge badge-info">Médio</span></td>
<td>HP125-HP150</td>
<td>3 modelos</td>
<td>Fundações medianas</td>
</tr>
<tr>
<td><span class="badge badge-warning">Grande</span></td>
<td>HP200</td>
<td>5 modelos</td>
<td>Fundações pesadas</td>
</tr>
<tr>
<td><span class="badge badge-warning">Muito Grande</span></td>
<td>HP250-HP300</td>
<td>5 modelos</td>
<td>Estruturas críticas</td>
</tr>
<tr>
<td><span class="badge badge-danger">Massivo</span></td>
<td>HP350</td>
<td>4 modelos</td>
<td>Offshore, portos</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">🔬 Qualidades Disponíveis (SAE)</h4>
<table class="data-table">
<thead>
<tr>
<th>Qualidade</th>
<th>Fy (MPa)</th>
<th>Fu (MPa)</th>
<th>Aplicação</th>
</tr>
</thead>
<tbody>
<tr>
<td>SAE 1020-1045</td>
<td>235-280</td>
<td>420-490</td>
<td>Médio-alto - fundações gerais</td>
</tr>
<tr>
<td>SAE 1050-1100</td>
<td>340-445</td>
<td>580-700</td>
<td>Muito alto - cravação pesada</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tab 3: Fabricantes -->
<div class="tab-content" id="tab-2">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🏭 Fabricantes no Brasil</h3>
<table class="data-table">
<thead>
<tr>
<th>Fabricante</th>
<th>Localização</th>
<th>Gama de Produtos</th>
<th>Especialidade</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Usiminas</strong></td>
<td>Ipatinga (MG)</td>
<td>Completa</td>
<td>Principal fornecedor nacional</td>
</tr>
<tr>
<td><strong>Gerdau</strong></td>
<td>Múltiplas plantas</td>
<td>Média a Grande</td>
<td>Parceria com Usiminas</td>
</tr>
<tr>
<td><strong>Vallourec</strong></td>
<td>Múltiplas</td>
<td>Grande a Massivo</td>
<td>Perfis especiais</td>
</tr>
</tbody>
</table>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">📦 Comprimentos Comerciais</h4>
<p><strong>Padrão:</strong> 6m, 9m, 12m, 13.5m</p>
<p><strong>Especiais:</strong> Até 18m sob consulta</p>
</div>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">⏱️ Prazos de Entrega</h4>
<ul>
<li><strong>Estoque:</strong> 2-5 dias</li>
<li><strong>Sob encomenda:</strong> 10-20 dias</li>
<li><strong>Especiais:</strong> 20-30 dias</li>
</ul>
</div>
</div>
</div>
<!-- Tab 4: Preços 2025 -->
<div class="tab-content" id="tab-3">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">💰 Preços 2025</h3>
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
<strong>⚠️ Preços de Referência:</strong> Valores médios de mercado. Consulte fornecedores para cotação atualizada.
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">💵 Faixa de Preços</h4>
<p><strong>Preço base:</strong> R$ 5,00 - R$ 12,00 por kg</p>
<p><strong>Variação por região:</strong> ±10-15%</p>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Fatores de Preço</h4>
<table class="data-table">
<thead>
<tr>
<th>Situação</th>
<th>Variação</th>
<th>Observação</th>
</tr>
</thead>
<tbody>
<tr>
<td>HP100</td>
<td><span class="badge badge-success">-10%</span></td>
<td>Mais comum</td>
</tr>
<tr>
<td>HP350</td>
<td><span class="badge badge-danger">+25%</span></td>
<td>Produção especial</td>
</tr>
<tr>
<td>Com cravação</td>
<td><span class="badge badge-warning">+5%</span></td>
<td>Serviço adicional</td>
</tr>
<tr>
<td>Quantidade >30 toneladas</td>
<td><span class="badge badge-success">-15%</span></td>
<td>Desconto por volume</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📋 Normas Aplicáveis</h4>
<ul>
<li><strong>ASTM A588</strong> - Aço estrutural alta resistência</li>
<li><strong>ASTM A992</strong> - Perfis estruturais</li>
<li><strong>ISO 5148</strong> - Equivalente internacional</li>
<li><strong>EN 10025</strong> - Produtos laminados a quente</li>
</ul>
</div>
</div>
</div>
<!-- Tab 5: Aplicações -->
<div class="tab-content" id="tab-4">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🔧 Aplicações Principais</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🏗️ Fundações Profundas</h4>
<ul>
<li>Estacas cravadas</li>
<li>Fundações de edifícios</li>
<li>Contenções de solo</li>
<li>Muros de arrimo</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">⚓ Estruturas Marítimas</h4>
<ul>
<li>Plataformas offshore</li>
<li>Estruturas portuárias</li>
<li>Píeres e atracadouros</li>
<li>Fundações subaquáticas</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🌉 Infraestrutura</h4>
<ul>
<li>Fundações de pontes</li>
<li>Viadutos</li>
<li>Estruturas geotécnicas</li>
<li>Suportes estruturais</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🏭 Industrial</h4>
<ul>
<li>Fundações de equipamentos</li>
<li>Estruturas pesadas</li>
<li>Suportes de máquinas</li>
<li>Bases de torres</li>
</ul>
</div>
</div>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">✅ Recomendações de Uso</h4>
<ul>
<li>✓ Compressão axial muito alta</li>
<li>✓ Excelente para flambagem lateral</li>
<li>✓ Emendas soldadas certificadas obrigatórias</li>
<li>✓ Teste de carga incluído em projetos críticos</li>
<li>✓ Seção robusta com simetria total</li>
<li>✓ Resistência à cravação garantida</li>
<li>✓ Soldagem com E8018 ou E9018 recomendada</li>
</ul>
</div>
</div>
</div>
</div>
`;
}
function getBarrasRoscadasContent() {
return `
<div class="section-header">
<div class="section-title">🔩 Barras Roscadas</div>
<div class="section-description">Catálogo completo de barras roscadas estruturais (Métrica e UNC)</div>
</div>
<div class="tabs-container">
<div class="tabs-nav">
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">📊 Tabela Técnica</button>
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">📋 Especificações</button>
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">🏭 Fabricantes</button>
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">💰 Preços 2025</button>
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">🔧 Aplicações</button>
</div>
<!-- Tab 1: Tabela Técnica -->
<div class="tab-content active" id="tab-0">
<div class="card" style="background: var(--color-bg-1);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<div>
<h3 style="margin: 0; color: var(--color-primary);">📊 Barras Roscadas Disponíveis</h3>
<p style="margin: 8px 0 0 0; color: var(--color-text-secondary);">
Total: <strong id="barras_roscadas-total">-</strong> diâmetros
</p>
</div>
<button class="btn btn-primary" onclick="forcarCarregamentoBarrasRoscadas()">
🔄 Recarregar Dados
</button>
</div>
<div style="overflow-x: auto;">
<table class="data-table">
<thead>
<tr>
<th>Designação</th>
<th>Diâmetro (mm)</th>
<th>Passo (mm)</th>
<th>Peso (kg/m)</th>
<th>Área (cm²)</th>
<th>Categoria</th>
<th>Ações</th>
</tr>
</thead>
<tbody id="barras_roscadas-tbody">
<tr>
<td colspan="7" style="text-align: center; padding: 40px;">
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
<div style="font-size: 18px; font-weight: bold;">Carregando barras roscadas...</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tab 2: Especificações -->
<div class="tab-content" id="tab-1">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">📋 Especificações Técnicas Completas</h3>
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
<strong>⚠️ IMPORTANTE:</strong> Barras Métricas e UNC NÃO são compatíveis! Verifique sempre o tipo de rosca.
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">🔧 Descrição Geral</h4>
<p><strong>Barras de aço carbono com rosca contínua (métrica e UNC)</strong></p>
<p>Barras roscadas utilizadas em fundações, ancoragens e sistemas de fixação. Disponíveis em padrão métrico (ISO) e UNC (americano).</p>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📏 Faixa de Dimensões</h4>
<ul>
<li><strong>Métrica:</strong> M10 a M64 (19 modelos)</li>
<li><strong>UNC:</strong> 3/8"-16 a 2"-4.5 (19 modelos)</li>
<li><strong>Total:</strong> 38 modelos</li>
<li><strong>Peso:</strong> 0.617 kg/m a 25.130 kg/m</li>
</ul>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Distribuição dos Modelos</h4>
<table class="data-table">
<thead>
<tr>
<th>Tipo</th>
<th>Categoria</th>
<th>Dimensões</th>
<th>Quantidade</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="4"><strong>Métrica</strong></td>
<td><span class="badge badge-info">Pequeno</span></td>
<td>M10-M12</td>
<td>4 modelos</td>
</tr>
<tr>
<td><span class="badge badge-info">Médio</span></td>
<td>M16-M20</td>
<td>6 modelos</td>
</tr>
<tr>
<td><span class="badge badge-warning">Grande</span></td>
<td>M24-M48</td>
<td>5 modelos</td>
</tr>
<tr>
<td><span class="badge badge-danger">Muito Grande</span></td>
<td>M48-M64</td>
<td>4 modelos</td>
</tr>
<tr>
<td rowspan="4"><strong>UNC</strong></td>
<td><span class="badge badge-info">Pequeno</span></td>
<td>3/8"-1/2"</td>
<td>4 modelos</td>
</tr>
<tr>
<td><span class="badge badge-info">Médio</span></td>
<td>5/8"-1"</td>
<td>6 modelos</td>
</tr>
<tr>
<td><span class="badge badge-warning">Grande</span></td>
<td>1 1/4"-1 1/2"</td>
<td>5 modelos</td>
</tr>
<tr>
<td><span class="badge badge-danger">Muito Grande</span></td>
<td>1 5/8"-2"</td>
<td>4 modelos</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">🔬 Qualidades Disponíveis (SAE)</h4>
<table class="data-table">
<thead>
<tr>
<th>Qualidade</th>
<th>Fy (MPa)</th>
<th>Fu (MPa)</th>
<th>Aplicação</th>
</tr>
</thead>
<tbody>
<tr>
<td>SAE 1008-1015</td>
<td>210</td>
<td>400</td>
<td>Básica - fundações leves</td>
</tr>
<tr>
<td>SAE 1020-1045</td>
<td>235-280</td>
<td>420-490</td>
<td>Média - fundações gerais</td>
</tr>
<tr>
<td>SAE 1050-1100</td>
<td>340-445</td>
<td>580-700</td>
<td>Alta - aplicações críticas</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tab 3: Fabricantes -->
<div class="tab-content" id="tab-2">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🏭 Fabricantes no Brasil</h3>
<h4 style="color: var(--color-primary); margin-top: 24px;">Barras Métricas</h4>
<table class="data-table">
<thead>
<tr>
<th>Fabricante</th>
<th>Localização</th>
<th>Gama de Produtos</th>
<th>Especialidade</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Confab</strong></td>
<td>Pindamonhangaba (SP)</td>
<td>Completa</td>
<td>Principal fornecedor nacional</td>
</tr>
<tr>
<td><strong>Gerdau</strong></td>
<td>Múltiplas plantas</td>
<td>Média a Grande</td>
<td>Barras estruturais</td>
</tr>
<tr>
<td><strong>Tecel</strong></td>
<td>São Paulo (SP)</td>
<td>Pequena a Média</td>
<td>Distribuição</td>
</tr>
</tbody>
</table>
<h4 style="color: var(--color-primary); margin-top: 24px;">Barras UNC</h4>
<table class="data-table">
<thead>
<tr>
<th>Origem</th>
<th>Disponibilidade</th>
<th>Observação</th>
</tr>
</thead>
<tbody>
<tr>
<td>Fornecedores especializados</td>
<td>Estoque distribuído</td>
<td>Importação direta EUA</td>
</tr>
</tbody>
</table>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">📦 Comprimentos Comerciais</h4>
<p><strong>Padrão:</strong> 1m, 3m, 6m, 9m, 12m</p>
</div>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">⏱️ Prazos de Entrega</h4>
<ul>
<li><strong>Métrica estoque:</strong> 1-3 dias</li>
<li><strong>Métrica encomenda:</strong> 5-10 dias</li>
<li><strong>UNC importada:</strong> 15-30 dias</li>
</ul>
</div>
</div>
</div>
<!-- Tab 4: Preços 2025 -->
<div class="tab-content" id="tab-3">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">💰 Preços 2025</h3>
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
<strong>⚠️ Preços de Referência:</strong> Valores médios de mercado. UNC tem premium de 30-50% sobre Métrica.
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">💵 Faixa de Preços</h4>
<p><strong>Métrica:</strong> R$ 5,00 - R$ 15,00 por kg</p>
<p><strong>UNC:</strong> R$ 6,50 - R$ 22,50 por kg (premium +30-50%)</p>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Fatores de Preço - Métrica</h4>
<table class="data-table">
<thead>
<tr>
<th>Situação</th>
<th>Variação</th>
<th>Observação</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pequenas (M10-M12)</td>
<td><span class="badge badge-success">-5%</span></td>
<td>Mais comuns</td>
</tr>
<tr>
<td>Grandes (M48+)</td>
<td><span class="badge badge-success">-5-10%</span></td>
<td>Volume maior</td>
</tr>
<tr>
<td>Quantidade >2 toneladas</td>
<td><span class="badge badge-success">-10%</span></td>
<td>Desconto por volume</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Fatores de Preço - UNC</h4>
<table class="data-table">
<thead>
<tr>
<th>Situação</th>
<th>Variação</th>
<th>Observação</th>
</tr>
</thead>
<tbody>
<tr>
<td>Premium vs Métrica</td>
<td><span class="badge badge-danger">+30-50%</span></td>
<td>Importação</td>
</tr>
<tr>
<td>Quantidade >1 tonelada</td>
<td><span class="badge badge-success">-5%</span></td>
<td>Desconto limitado</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📋 Normas Aplicáveis</h4>
<ul>
<li><strong>ABNT NBR 5629</strong> - Barras roscadas (Brasil)</li>
<li><strong>ISO 8839</strong> - Rosca métrica</li>
<li><strong>ANSI B1.1</strong> - Rosca UNC</li>
<li><strong>ASTM F568</strong> - Parafusos e barras</li>
</ul>
</div>
</div>
</div>
<!-- Tab 5: Aplicações -->
<div class="tab-content" id="tab-4">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🔧 Aplicações Principais</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🏗️ Fundações</h4>
<ul>
<li>Fundações de edifícios</li>
<li>Ancoragem de estruturas</li>
<li>Pernos de fundação</li>
<li>Chumbadores</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🌍 Geotecnia</h4>
<ul>
<li>Estacas raiz</li>
<li>Tirantes</li>
<li>Ancoragens de solo</li>
<li>Contenções</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">⚓ Estruturas Offshore</h4>
<ul>
<li>Plataformas</li>
<li>Ancoragens marinhas</li>
<li>Estruturas subaquáticas</li>
<li>Fixações críticas</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🏭 Industrial</h4>
<ul>
<li>Equipamentos industriais</li>
<li>Sistemas de protensão</li>
<li>Fixações de máquinas</li>
<li>Estruturas pesadas</li>
</ul>
</div>
</div>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">✅ Recomendações de Uso</h4>
<ul>
<li>⚠️ <strong>CRÍTICO:</strong> Métrica e UNC NÃO são compatíveis</li>
<li>✓ Porcas métricas ISO para barras Métricas</li>
<li>✓ Porcas UNC para barras UNC</li>
<li>✓ Compatibilidade de rosca obrigatória</li>
<li>✓ Identificação por tinta na barra</li>
<li>✓ Verificar qualidade do aço antes da instalação</li>
<li>✓ Proteção anticorrosiva em ambientes agressivos</li>
</ul>
</div>
</div>
</div>
</div>
`;
}
function getBarrasChatassContent() {
return `
<div class="section-header">
<div class="section-title">▬ Barras Chatas</div>
<div class="section-description">Catálogo completo de barras chatas estruturais</div>
</div>
<div class="tabs-container">
<div class="tabs-nav">
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">📊 Tabela Técnica</button>
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">📋 Especificações</button>
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">🏭 Fabricantes</button>
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">💰 Preços 2025</button>
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">🔧 Aplicações</button>
</div>
<!-- Tab 1: Tabela Técnica -->
<div class="tab-content active" id="tab-0">
<div class="card" style="background: var(--color-bg-1);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<div>
<h3 style="margin: 0; color: var(--color-primary);">📊 Barras Chatas Disponíveis</h3>
<p style="margin: 8px 0 0 0; color: var(--color-text-secondary);">
Total: <strong id="barras_chatas-total">-</strong> perfis
</p>
</div>
<button class="btn btn-primary" onclick="forcarCarregamentoBarrasChatas()">
🔄 Recarregar Dados
</button>
</div>
<div style="overflow-x: auto;">
<table class="data-table">
<thead>
<tr>
<th>Designação</th>
<th>Largura (mm)</th>
<th>Espessura (mm)</th>
<th>Peso (kg/m)</th>
<th>Área (cm²)</th>
<th>Categoria</th>
<th>Ações</th>
</tr>
</thead>
<tbody id="barras_chatas-tbody">
<tr>
<td colspan="7" style="text-align: center; padding: 40px;">
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
<div style="font-size: 18px; font-weight: bold;">Carregando barras chatas...</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tab 2: Especificações -->
<div class="tab-content" id="tab-1">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">📋 Especificações Técnicas Completas</h3>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">🔧 Descrição Geral</h4>
<p><strong>Barras de aço laminadas a quente com seção retangular (Largura >> Espessura)</strong></p>
<p>Perfis planos versáteis utilizados em estruturas, suportes e componentes soldados. Caracterizados pela relação largura/espessura elevada.</p>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📏 Faixa de Dimensões</h4>
<ul>
<li><strong>Dimensões:</strong> 12.7×3.2mm a 127×22.2mm</li>
<li><strong>Peso:</strong> 0.309 kg/m a 21.68 kg/m</li>
<li><strong>Quantidade de modelos:</strong> 31 perfis diferentes</li>
</ul>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Distribuição dos Modelos</h4>
<table class="data-table">
<thead>
<tr>
<th>Categoria</th>
<th>Largura</th>
<th>Quantidade</th>
<th>Aplicações Típicas</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="badge badge-info">Pequeno</span></td>
<td>12.7-25.4mm</td>
<td>9 modelos</td>
<td>Estruturas leves, suportes</td>
</tr>
<tr>
<td><span class="badge badge-info">Médio</span></td>
<td>31-50.8mm</td>
<td>6 modelos</td>
<td>Estruturas medianas</td>
</tr>
<tr>
<td><span class="badge badge-warning">Grande</span></td>
<td>50.8-76.2mm</td>
<td>4 modelos</td>
<td>Estruturas pesadas</td>
</tr>
<tr>
<td><span class="badge badge-warning">Muito Grande</span></td>
<td>76.2-127mm</td>
<td>6 modelos</td>
<td>Estruturas críticas</td>
</tr>
<tr>
<td><span class="badge badge-danger">Massivo</span></td>
<td>101-127mm</td>
<td>6 modelos</td>
<td>Offshore, industrial</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">🔬 Qualidades Disponíveis (SAE)</h4>
<table class="data-table">
<thead>
<tr>
<th>Qualidade</th>
<th>Fy (MPa)</th>
<th>Fu (MPa)</th>
<th>Aplicação</th>
</tr>
</thead>
<tbody>
<tr>
<td>SAE 1008-1015</td>
<td>210</td>
<td>400</td>
<td>Básica - estruturas leves</td>
</tr>
<tr>
<td>SAE 1020-1045</td>
<td>235-280</td>
<td>420-490</td>
<td>Alta - estruturas pesadas</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Tab 3: Fabricantes -->
<div class="tab-content" id="tab-2">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🏭 Fabricantes no Brasil</h3>
<table class="data-table">
<thead>
<tr>
<th>Fabricante</th>
<th>Localização</th>
<th>Gama de Produtos</th>
<th>Especialidade</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Gerdau</strong></td>
<td>Múltiplas plantas</td>
<td>Completa</td>
<td>Principal fornecedor nacional</td>
</tr>
<tr>
<td><strong>CSN</strong></td>
<td>Volta Redonda (RJ)</td>
<td>Média a Grande</td>
<td>Barras pesadas</td>
</tr>
<tr>
<td><strong>Confab</strong></td>
<td>Pindamonhangaba (SP)</td>
<td>Pequena a Média</td>
<td>Distribuição</td>
</tr>
<tr>
<td><strong>Tecel</strong></td>
<td>São Paulo (SP)</td>
<td>Pequena</td>
<td>Corte e distribuição</td>
</tr>
<tr>
<td><strong>Fornecedores regionais</strong></td>
<td>Diversos</td>
<td>Variada</td>
<td>Distribuição local</td>
</tr>
</tbody>
</table>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">📦 Comprimentos Comerciais</h4>
<p><strong>Padrão:</strong> 3m, 6m, 9m, 12m</p>
</div>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">⏱️ Prazos de Entrega</h4>
<ul>
<li><strong>Estoque:</strong> 2-4 dias</li>
<li><strong>Sob encomenda:</strong> 7-12 dias</li>
<li><strong>Especiais:</strong> 15-20 dias</li>
</ul>
</div>
</div>
</div>
<!-- Tab 4: Preços 2025 -->
<div class="tab-content" id="tab-3">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">💰 Preços 2025</h3>
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
<strong>⚠️ Preços de Referência:</strong> Valores médios de mercado. Consulte fornecedores para cotação atualizada.
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">💵 Faixa de Preços</h4>
<p><strong>Preço base:</strong> R$ 4,50 - R$ 8,50 por kg</p>
<p><strong>Variação por região:</strong> ±10-15%</p>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📊 Fatores de Preço</h4>
<table class="data-table">
<thead>
<tr>
<th>Situação</th>
<th>Variação</th>
<th>Observação</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pequenas (até 50mm)</td>
<td><span class="badge badge-warning">+10%</span></td>
<td>Menor demanda</td>
</tr>
<tr>
<td>Grandes (101-127mm)</td>
<td><span class="badge badge-success">-5%</span></td>
<td>Volume maior</td>
</tr>
<tr>
<td>Corte customizado</td>
<td><span class="badge badge-warning">+taxa</span></td>
<td>Serviço adicional</td>
</tr>
<tr>
<td>Furação em CNC</td>
<td><span class="badge badge-warning">+taxa</span></td>
<td>Serviço adicional</td>
</tr>
<tr>
<td>Quantidade >5 toneladas</td>
<td><span class="badge badge-success">-10%</span></td>
<td>Desconto por volume</td>
</tr>
</tbody>
</table>
</div>
<div style="margin-bottom: 24px;">
<h4 style="color: var(--color-primary);">📋 Normas Aplicáveis</h4>
<ul>
<li><strong>ABNT NBR 5005</strong> - Barras chatas de aço</li>
<li><strong>ASTM A36</strong> - Aço estrutural carbono</li>
<li><strong>DIN 17100</strong> - Aços para construção</li>
<li><strong>EN 10025-2</strong> - Produtos laminados a quente</li>
</ul>
</div>
</div>
</div>
<!-- Tab 5: Aplicações -->
<div class="tab-content" id="tab-4">
<div class="card" style="background: var(--color-bg-1);">
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🔧 Aplicações Principais</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🏗️ Estruturas</h4>
<ul>
<li>Suportes de máquinas</li>
<li>Estruturas de edifícios</li>
<li>Eixos estruturais</li>
<li>Componentes soldados</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🏭 Industrial</h4>
<ul>
<li>Plataformas industriais</li>
<li>Elementos de fixação</li>
<li>Suportes de equipamentos</li>
<li>Estruturas de máquinas</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">⚓ Offshore</h4>
<ul>
<li>Estruturas offshore</li>
<li>Plataformas marítimas</li>
<li>Componentes navais</li>
<li>Fixações críticas</li>
</ul>
</div>
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
<h4 style="color: var(--color-primary);">🔧 Mecânica</h4>
<ul>
<li>Eixos e pernos</li>
<li>Suportes mecânicos</li>
<li>Componentes usinados</li>
<li>Estruturas de chassis</li>
</ul>
</div>
</div>
<div style="margin-top: 24px;">
<h4 style="color: var(--color-primary);">✅ Recomendações de Uso</h4>
<ul>
<li>✓ Fácil furação com brocas padrão</li>
<li>✓ Soldagem simples com E7018</li>
<li>✓ Flexibilidade em projeto</li>
<li>✓ Acabamento rugoso escamoso (padrão)</li>
<li>✓ Embalagem em feixes 200-500kg</li>
<li>✓ Verificar planicidade antes da soldagem</li>
<li>✓ Proteção anticorrosiva recomendada</li>
</ul>
</div>
</div>
</div>
</div>
`;
}
function getParafusosContent() {
return `
<div class="section-header">
<div class="section-title">🔩 Ligações Parafusadas - 5 Abas Completas</div>
<div class="section-description">Dimensionamento completo de conexões parafusadas</div>
</div>
<div class="tabs-container">
<div class="tabs-nav">
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">1⃣ Cisalhamento</button>
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">2⃣ Esmagamento</button>
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">3⃣ Bloco</button>
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">4⃣ Layout</button>
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">5⃣ vs Solda</button>
</div>
<!-- Tab 1: Cisalhamento -->
<div class="tab-content active" id="tab-0">
<div class="card" style="background: var(--color-bg-1);">
<div class="card-title">📐 Dimensionamento de Parafusos ao Cisalhamento</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Calcula a resistência ao cisalhamento de parafusos individuais e totais</p>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Tipo de Parafuso</label>
<select class="form-control" id="bolt-type">
<option value="a325">A325 (fy = 400 MPa)</option>
<option value="a490">A490 (fy = 565 MPa)</option>
<option value="iso88">ISO 8.8 (fy = 640 MPa)</option>
<option value="iso109">ISO 10.9 (fy = 900 MPa)</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Diâmetro (mm)</label>
<select class="form-control" id="bolt-d">
<option value="12">12</option>
<option value="16">16</option>
<option value="20" selected>20</option>
<option value="24">24</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Quantidade</label>
<input type="number" class="form-control" id="bolt-qty" step="1" value="4" min="1" max="100">
</div>
<div class="form-group">
<label class="form-label">Planos de Corte</label>
<select class="form-control" id="bolt-planes">
<option value="1">1</option>
<option value="2" selected>2</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Força Aplicada (kN)</label>
<input type="number" class="form-control" id="bolt-force" step="1" value="200">
</div>
</div>
<button class="btn btn-primary" onclick="calcularCisalhamento()">🔧 Calcular Cisalhamento</button>
</div>
<div id="bolt-shear-result"></div>
</div>
<!-- Tab 2: Esmagamento -->
<div class="tab-content" id="tab-1">
<div class="card" style="background: var(--color-bg-3);">
<div class="card-title">🔨 Verificação de Esmagamento (Bearing)</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Calcula a resistência ao esmagamento da chapa</p>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Diâmetro Parafuso (mm)</label>
<select class="form-control" id="bear-d">
<option value="12">12</option>
<option value="16" selected>16</option>
<option value="20">20</option>
<option value="24">24</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Espessura da Chapa (mm)</label>
<input type="number" class="form-control" id="bear-thickness" step="1" value="10">
</div>
<div class="form-group">
<label class="form-label">Quantidade de Parafusos</label>
<input type="number" class="form-control" id="bear-qty" step="1" value="4">
</div>
<div class="form-group">
<label class="form-label">Tipo de Aço da Chapa</label>
<select class="form-control" id="bear-steel">
<option value="a36">A36 (fy=250, fu=400 MPa)</option>
<option value="a572" selected>A572 (fy=345, fu=450 MPa)</option>
<option value="s235">S235 (fy=235, fu=360 MPa)</option>
<option value="s355">S355 (fy=355, fu=490 MPa)</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Distância de Borda (mm)</label>
<input type="number" class="form-control" id="bear-edge" step="1" value="40">
</div>
<div class="form-group">
<label class="form-label">Espaçamento entre Furos (mm)</label>
<input type="number" class="form-control" id="bear-spacing" step="1" value="75">
</div>
</div>
<button class="btn btn-primary" onclick="calcularEsmagamento()">🔧 Calcular Esmagamento</button>
</div>
<div id="bolt-bearing-result"></div>
</div>
<!-- Tab 3: Ruptura Bloco -->
<div class="tab-content" id="tab-2">
<div class="card" style="background: var(--color-bg-6);">
<div class="card-title">⚠️ Ruptura em Bloco de Cisalhamento</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Verifica ruptura por bloco segundo AISC 360-16</p>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Diâmetro Parafuso (mm)</label>
<select class="form-control" id="block-d">
<option value="12">12</option>
<option value="16" selected>16</option>
<option value="20">20</option>
<option value="24">24</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Quantidade Horizontal</label>
<input type="number" class="form-control" id="block-h-qty" step="1" value="2">
</div>
<div class="form-group">
<label class="form-label">Quantidade Vertical</label>
<input type="number" class="form-control" id="block-v-qty" step="1" value="2">
</div>
<div class="form-group">
<label class="form-label">Espaçamento Horizontal (mm)</label>
<input type="number" class="form-control" id="block-h-space" step="1" value="75">
</div>
<div class="form-group">
<label class="form-label">Distância Borda Esquerda (mm)</label>
<input type="number" class="form-control" id="block-edge-left" step="1" value="40">
</div>
<div class="form-group">
<label class="form-label">Distância Borda Topo (mm)</label>
<input type="number" class="form-control" id="block-edge-top" step="1" value="40">
</div>
<div class="form-group">
<label class="form-label">Distância Borda Direita (mm)</label>
<input type="number" class="form-control" id="block-edge-right" step="1" value="40">
</div>
<div class="form-group">
<label class="form-label">Espessura (mm)</label>
<input type="number" class="form-control" id="block-thickness" step="1" value="10">
</div>
<div class="form-group">
<label class="form-label">Aço</label>
<select class="form-control" id="block-steel">
<option value="a36">A36 (fu=400 MPa)</option>
<option value="a572" selected>A572 (fu=450 MPa)</option>
<option value="s235">S235 (fu=360 MPa)</option>
<option value="s355">S355 (fu=490 MPa)</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Força (kN)</label>
<input type="number" class="form-control" id="block-force" step="1" value="200">
</div>
</div>
<button class="btn btn-primary" onclick="calcularBlocoRuptura()">🔧 Calcular Bloco</button>
</div>
<div id="bolt-block-result"></div>
</div>
<!-- Tab 4: Layout de Furação -->
<div class="tab-content" id="tab-3">
<div class="card" style="background: var(--color-bg-5);">
<div class="card-title">📐 Verificação de Layout de Furação</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Verifica conformidade com NBR 8800 e AISC 360</p>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Diâmetro Parafuso (mm)</label>
<select class="form-control" id="layout2-d">
<option value="12">12</option>
<option value="16" selected>16</option>
<option value="20">20</option>
<option value="24">24</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Borda Esquerda (mm)</label>
<input type="number" class="form-control" id="layout2-edge-left" step="1" value="40">
</div>
<div class="form-group">
<label class="form-label">Borda Direita (mm)</label>
<input type="number" class="form-control" id="layout2-edge-right" step="1" value="40">
</div>
<div class="form-group">
<label class="form-label">Borda Topo (mm)</label>
<input type="number" class="form-control" id="layout2-edge-top" step="1" value="40">
</div>
<div class="form-group">
<label class="form-label">Borda Base (mm)</label>
<input type="number" class="form-control" id="layout2-edge-bottom" step="1" value="40">
</div>
<div class="form-group">
<label class="form-label">Espaçamento Horizontal (mm)</label>
<input type="number" class="form-control" id="layout2-h-space" step="1" value="75">
</div>
<div class="form-group">
<label class="form-label">Espaçamento Vertical (mm)</label>
<input type="number" class="form-control" id="layout2-v-space" step="1" value="75">
</div>
<div class="form-group">
<label class="form-label">Espessura Chapa (mm)</label>
<input type="number" class="form-control" id="layout2-thickness" step="1" value="10">
</div>
</div>
<button class="btn btn-primary" onclick="verificarLayoutCompleto()">✓ Verificar Conformidade</button>
</div>
<div id="layout-full-result"></div>
</div>
<!-- Tab 5: Parafuso vs Solda -->
<div class="tab-content" id="tab-4">
<div class="card" style="background: var(--color-bg-4);">
<div class="card-title">⚖️ Comparação: Parafuso vs Solda</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Compara alternativas de conexão com análise de custos</p>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Força a Transmitir (kN)</label>
<input type="number" class="form-control" id="comp2-force" step="1" value="200">
</div>
<div class="form-group">
<label class="form-label">Comprimento Disponível (mm)</label>
<input type="number" class="form-control" id="comp2-length" step="1" value="300">
</div>
<div class="form-group">
<label class="form-label">Tipo Aço Base</label>
<select class="form-control" id="comp2-steel">
<option value="a36">A36 (fy=250 MPa)</option>
<option value="a572" selected>A572 (fy=345 MPa)</option>
<option value="s355">S355 (fy=355 MPa)</option>
</select>
</div>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 20px 0;">
<div style="padding: 16px; background: var(--color-bg-1); border-radius: 12px;">
<h4 style="margin-bottom: 12px; color: var(--color-primary);">🔩 Opção Parafuso</h4>
<div class="form-group">
<label class="form-label">Tipo</label>
<select class="form-control" id="comp2-bolt-type">
<option value="a325" selected>A325</option>
<option value="a490">A490</option>
<option value="iso88">ISO 8.8</option>
<option value="iso109">ISO 10.9</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Diâmetro (mm)</label>
<select class="form-control" id="comp2-bolt-d">
<option value="12">12</option>
<option value="16" selected>16</option>
<option value="20">20</option>
<option value="24">24</option>
</select>
</div>
</div>
<div style="padding: 16px; background: var(--color-bg-6); border-radius: 12px;">
<h4 style="margin-bottom: 12px; color: var(--color-warning);">🔥 Opção Solda</h4>
<div class="form-group">
<label class="form-label">Tipo Eletrodo</label>
<select class="form-control" id="comp2-electrode">
<option value="e6010">E6010</option>
<option value="e7018" selected>E7018</option>
<option value="e8018">E8018</option>
</select>
</div>
</div>
</div>
<button class="btn btn-primary" onclick="compararParafusoSoldaCompleto()">🔄 Gerar Comparação Completa</button>
</div>
<div id="comparison-full-result"></div>
</div>
</div>
`;
}
function getLayoutContent() {
return `
<div class="section-header">
<div class="section-title">🎯 Layout de Furação (NBR 8800)</div>
<div class="section-description">Verificação de distâncias e espaçamentos</div>
</div>
<div class="card">
<div class="card-title">Parâmetros de Layout</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Diâmetro Parafuso (mm)</label>
<input type="number" class="form-control" id="layout-d" step="1" value="20">
</div>
<div class="form-group">
<label class="form-label">Distância de Borda (mm)</label>
<input type="number" class="form-control" id="layout-edge" step="1" value="40">
</div>
<div class="form-group">
<label class="form-label">Espaçamento entre Furos (mm)</label>
<input type="number" class="form-control" id="layout-spacing" step="1" value="60">
</div>
<div class="form-group expert-only">
<label class="form-label">Espessura Chapa (mm)</label>
<input type="number" class="form-control" id="layout-thickness" step="1" value="10">
</div>
</div>
<button class="btn btn-primary" onclick="verificarLayout()">✓ Verificar Conformidade</button>
</div>
<div id="layout-result"></div>
`;
}
function getParafusoVsSoldaContent() {
return `
<div class="section-header">
<div class="section-title">⚙️ Comparação: Parafuso vs Solda</div>
<div class="section-description">Análise comparativa de soluções de ligação</div>
</div>
<div class="card">
<div class="card-title">Parâmetros da Ligação</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Força a Transmitir (kN)</label>
<input type="number" class="form-control" id="comp-force" step="1" value="150">
</div>
<div class="form-group">
<label class="form-label">Comprimento Disponível (mm)</label>
<input type="number" class="form-control" id="comp-length" step="1" value="400">
</div>
<div class="form-group">
<label class="form-label">Aço Base (fy MPa)</label>
<input type="number" class="form-control" id="comp-fy" step="1" value="345">
</div>
</div>
<button class="btn btn-primary" onclick="compararParafusoSolda()">⚙️ Comparar Soluções</button>
</div>
<div id="comparison-result"></div>
`;
}
function getPreaquecimentoContent() {
return `
<div class="section-header">
<div class="section-title">🔥 SOLDAGEM - Sistema Completo</div>
<div class="section-description">Dimensionamento completo de soldagem com 6 ferramentas integradas</div>
</div>
<!-- Seletor Global de Processo e Consumível -->
<div class="card" style="background: var(--color-bg-2); border: 2px solid var(--color-primary);">
<div class="card-title">⚙️ SELEÇÃO DE PROCESSO E CONSUMÍVEL</div>
<p style="color: var(--color-text-secondary); margin-bottom: 16px;">Selecione o processo e consumível que será usado em todas as ferramentas abaixo</p>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Processo de Soldagem</label>
<select class="form-control" id="weld-process" onchange="updateWeldingProcess()">
<option value="smaw" selected>SMAW (Eletrodo Revestido)</option>
<option value="gmaw">GMAW (MIG/MAG)</option>
<option value="fcaw">FCAW (Arame Tubular)</option>
<option value="gtaw">GTAW (TIG)</option>
<option value="saw">SAW (Soldagem Submersa)</option>
<option value="esw">ESW (Soldagem por Escória)</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Consumível / Eletrodo</label>
<select class="form-control" id="weld-electrode" onchange="updateWeldingElectrode()">
<option value="e7018" selected>E7018 (AWS) - Básico</option>
<option value="e6013">E6013 (AWS) - Rutílico</option>
<option value="e8018">E8018 (AWS) - Básico Alta Resistência</option>
<option value="e7016">E7016 (AWS) - Básico</option>
<option value="e8016">E8016 (AWS) - Básico</option>
<option value="er70s2">ER70S-2 (MIG)</option>
<option value="er70s6">ER70S-6 (MIG)</option>
<option value="er4043">ER4043 (TIG - Al)</option>
<option value="er5356">ER5356 (TIG - Al)</option>
</select>
</div>
</div>
<button class="btn btn-success" onclick="applyToAllTabs()" style="margin-top: 16px;">✅ Atualizar Todas as Abas</button>
<button class="btn btn-secondary" onclick="showElectrodeProperties()" style="margin-top: 16px;">📋 Mostrar Propriedades do Consumível</button>
</div>
<div id="electrode-properties"></div>
<!-- 6 Abas de Soldagem -->
<div class="tabs-container">
<div class="tabs-nav">
<button class="tab-btn active" onclick="switchWeldTab(0)">🌡️ Pré-Aquecimento</button>
<button class="tab-btn" onclick="switchWeldTab(1)">⚡ Filete</button>
<button class="tab-btn" onclick="switchWeldTab(2)">🔥 Energia</button>
<button class="tab-btn" onclick="switchWeldTab(3)">📊 Consumo</button>
<button class="tab-btn" onclick="switchWeldTab(4)">🔄 Sequência</button>
<button class="tab-btn" onclick="switchWeldTab(5)">📋 Padrões</button>
</div>
<!-- ABA 1: Pré-Aquecimento -->
<div class="tab-content active" id="weld-tab-0">
<div class="card" style="background: var(--color-bg-1);">
<div class="card-title">🌡️ Pré-Aquecimento AWS D1.1</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Calcula temperatura mínima de pré-aquecimento</p>
<div style="padding: 12px; background: var(--color-surface); border-radius: 8px; margin-bottom: 20px;">
<strong>Processo Selecionado:</strong> <span id="preheat-process-display">SMAW (E7018)</span>
</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Carbono Equivalente (CEV)</label>
<input type="number" class="form-control" id="preheat-cev" step="0.01" value="0.45">
<small style="color: var(--color-text-secondary);">Ou calcule na seção Materiais</small>
</div>
<div class="form-group">
<label class="form-label">Espessura da Junta (mm)</label>
<input type="number" class="form-control" id="preheat-thickness" step="1" value="25">
</div>
<div class="form-group">
<label class="form-label">Temperatura Ambiente (°C)</label>
<input type="number" class="form-control" id="preheat-ambient" step="1" value="15">
</div>
<div class="form-group">
<label class="form-label">Tipo de Junta</label>
<select class="form-control" id="preheat-joint">
<option value="filete">Filete</option>
<option value="topo">Topo</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Restrição da Junta</label>
<select class="form-control" id="preheat-restraint">
<option value="1.0">Não Restrita</option>
<option value="1.1">Parcialmente Restrita</option>
<option value="1.2" selected>Totalmente Restrita</option>
</select>
</div>
</div>
<div style="margin: 20px 0;">
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
<input type="checkbox" id="preheat-interpass" style="width: 18px; height: 18px;">
<span>Calcular Temperatura Interpass (entre passes)</span>
</label>
</div>
<button class="btn btn-primary" onclick="calcularPreaquecimentoCompleto()">🔥 Calcular Pré-Aquecimento</button>
</div>
<div id="preheat-result"></div>
</div>
<!-- ABA 2: Dimensionamento de Filete -->
<div class="tab-content" id="weld-tab-1">
<div class="card" style="background: var(--color-bg-3);">
<div class="card-title">⚡ Dimensionamento de Soldas de Filete</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Calcula perna necessária e número de passes</p>
<div style="padding: 12px; background: var(--color-surface); border-radius: 8px; margin-bottom: 20px;">
<strong>Processo:</strong> <span id="filete-process-display">SMAW (E7018)</span>
</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Força a Transmitir (kN)</label>
<input type="number" class="form-control" id="filete-force" step="1" value="250">
</div>
<div class="form-group">
<label class="form-label">Comprimento Disponível (mm)</label>
<input type="number" class="form-control" id="filete-length" step="1" value="400">
</div>
<div class="form-group">
<label class="form-label">Tipo de Junta</label>
<select class="form-control" id="filete-joint">
<option value="1">Filete Simples</option>
<option value="2" selected>Filete Duplo</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Tipo de Aço Base</label>
<select class="form-control" id="filete-steel">
<option value="250">A36 (250 MPa)</option>
<option value="345" selected>A572 (345 MPa)</option>
<option value="235">S235 (235 MPa)</option>
<option value="355">S355 (355 MPa)</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Posição Soldagem</label>
<select class="form-control" id="filete-position">
<option value="1.0" selected>Plana (1F)</option>
<option value="0.9">Horizontal (2F)</option>
<option value="0.8">Vertical (3F)</option>
<option value="0.7">Sobrecabeça (4F)</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="calcularFileteCompleto()">⚡ Calcular Filete</button>
</div>
<div id="filete-result"></div>
</div>
<!-- ABA 3: Energia de Soldagem -->
<div class="tab-content" id="weld-tab-2">
<div class="card" style="background: var(--color-bg-6);">
<div class="card-title">🔥 Energia de Soldagem (Heat Input)</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Controla aporte de calor para evitar fragilização</p>
<div style="padding: 12px; background: var(--color-surface); border-radius: 8px; margin-bottom: 20px;">
<strong>Processo:</strong> <span id="hi-process-display">SMAW (E7018)</span>
</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Voltagem (V)</label>
<input type="number" class="form-control" id="hi-voltage" step="1" value="26">
</div>
<div class="form-group">
<label class="form-label">Corrente (A)</label>
<input type="number" class="form-control" id="hi-current" step="1" value="140">
</div>
<div class="form-group">
<label class="form-label">Velocidade Soldagem (cm/min)</label>
<input type="number" class="form-control" id="hi-speed" step="1" value="25">
</div>
<div class="form-group">
<label class="form-label">Eficiência de Arco</label>
<input type="number" class="form-control" id="hi-efficiency" step="0.01" value="0.75">
</div>
<div class="form-group">
<label class="form-label">Tipo de Aço (para análise)</label>
<select class="form-control" id="hi-steel">
<option value="a36">A36 (1.5-3.0 kJ/mm)</option>
<option value="a572" selected>A572 (1.0-2.5 kJ/mm)</option>
<option value="s355">S355 (0.8-2.0 kJ/mm)</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="calcularEnergiaCompleta()">🔥 Calcular Energia</button>
<button class="btn btn-secondary" onclick="verificarLimitesAco()" style="margin-left: 10px;">📊 Verificar Limites por Aço</button>
</div>
<div id="hi-result"></div>
</div>
<!-- ABA 4: Consumo de Eletrodos -->
<div class="tab-content" id="weld-tab-3">
<div class="card" style="background: var(--color-bg-5);">
<div class="card-title">📊 Consumo de Eletrodos e Consumíveis</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Calcula quantidade e custo de eletrodos necessários</p>
<div style="padding: 12px; background: var(--color-surface); border-radius: 8px; margin-bottom: 20px;">
<strong>Eletrodo:</strong> <span id="consumo-electrode-display">E7018</span>
</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Perna da Solda (mm)</label>
<input type="number" class="form-control" id="consumo-leg" step="1" value="6">
</div>
<div class="form-group">
<label class="form-label">Comprimento Total (m)</label>
<input type="number" class="form-control" id="consumo-length" step="0.1" value="10">
</div>
<div class="form-group">
<label class="form-label">Perdas/Respingos (%)</label>
<input type="number" class="form-control" id="consumo-loss" step="1" value="15">
</div>
<div class="form-group">
<label class="form-label">Porcentagem de Sucata (%)</label>
<input type="number" class="form-control" id="consumo-scrap" step="1" value="5">
</div>
</div>
<button class="btn btn-primary" onclick="calcularConsumoCompleto()">📊 Calcular Consumo</button>
<button class="btn btn-secondary" onclick="gerarOrcamentoConsumiveis()" style="margin-left: 10px;">💰 Gerar Orçamento</button>
</div>
<div id="consumo-result"></div>
</div>
<!-- ABA 5: Sequência de Soldagem -->
<div class="tab-content" id="weld-tab-4">
<div class="card" style="background: var(--color-bg-7);">
<div class="card-title">🔄 Sequência de Soldagem para Minimizar Distorções</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Padrões de deposição e passes</p>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Tipo de Junta</label>
<select class="form-control" id="seq-joint">
<option value="filete" selected>Filete Duplo</option>
<option value="topo">Topo</option>
<option value="angular">Angular</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Comprimento Total (mm)</label>
<input type="number" class="form-control" id="seq-length" step="1" value="400">
</div>
<div class="form-group">
<label class="form-label">Perna (mm)</label>
<input type="number" class="form-control" id="seq-leg" step="1" value="3">
</div>
<div class="form-group">
<label class="form-label">Número de Passes</label>
<input type="number" class="form-control" id="seq-passes" step="1" value="2">
</div>
<div class="form-group">
<label class="form-label">Padrão de Deposição</label>
<select class="form-control" id="seq-pattern">
<option value="skip" selected>Skip Welding (Recomendado)</option>
<option value="backstep">Backstep Welding</option>
<option value="pulsed">Pulsado</option>
<option value="continuous">Contínuo</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="gerarDiagramaSequencia()">📐 Gerar Diagrama de Sequência</button>
<button class="btn btn-secondary" onclick="visualizarDistorcoes()" style="margin-left: 10px;">📊 Visualizar Distorções Esperadas</button>
</div>
<div id="sequencia-result"></div>
</div>
<!-- ABA 6: Padrões de Solda -->
<div class="tab-content" id="weld-tab-5">
<div class="card" style="background: var(--color-bg-8);">
<div class="card-title">📋 Padrões de Solda Recomendados por Aplicação</div>
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Seleção de padrão otimizado para sua aplicação</p>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Aplicação / Estrutura</label>
<select class="form-control" id="padrao-app">
<option value="edificio" selected>Edifício de Múltiplos Andares</option>
<option value="ponte">Ponte Rodoviária</option>
<option value="industrial">Estrutura Industrial</option>
<option value="tubulacao">Tubulação de Pressão</option>
<option value="equipamento">Equipamento Mecânico</option>
<option value="offshore">Marinha/Offshore</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Criticidade</label>
<select class="form-control" id="padrao-criticality">
<option value="baixa">Baixa (Cargas Estáticas)</option>
<option value="media" selected>Média (Fadiga Baixa)</option>
<option value="alta">Alta (Fadiga/Impacto)</option>
<option value="critica">Crítica (Pressão/Temperatura)</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Ambiente Serviço</label>
<select class="form-control" id="padrao-env">
<option value="interno">Interno Seco</option>
<option value="externo" selected>Externo Temperado</option>
<option value="agressivo">Externo Agressivo / Marinho</option>
<option value="baixatemp">Baixas Temperaturas (-20°C)</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="buscarPadraoIdeal()">🔍 Buscar Padrão Ideal</button>
</div>
<div id="padrao-result"></div>
</div>
</div>
`;
}
function getSoldaFileteContent() {
return `
<div class="section-header">
<div class="section-title">⚡ Dimensionamento de Solda de Filete</div>
<div class="section-description">Cálculo da perna necessária segundo NBR 8800</div>
</div>
<div class="card">
<div class="card-title">Dados da Solda</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Força (kN)</label>
<input type="number" class="form-control" id="weld-force" step="1" value="100">
</div>
<div class="form-group">
<label class="form-label">Comprimento Total (mm)</label>
<input type="number" class="form-control" id="weld-length" step="1" value="500">
</div>
<div class="form-group">
<label class="form-label">Aço Base (fy MPa)</label>
<input type="number" class="form-control" id="weld-fy" step="1" value="345">
</div>
<div class="form-group expert-only">
<label class="form-label">Posição de Soldagem</label>
<select class="form-control" id="weld-position">
<option value="1.0">Plana</option>
<option value="0.9">Horizontal</option>
<option value="0.85">Vertical</option>
<option value="0.8">Sobrecabeça</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="calcularSoldaFilete()">⚡ Dimensionar Solda</button>
</div>
<div id="weld-result"></div>
`;
}
function getEnergiaSoldagemContent() {
return `
<div class="section-header">
<div class="section-title">🔥 Energia de Soldagem (Heat Input)</div>
<div class="section-description">Controle de energia para evitar fragilização da ZTA</div>
</div>
<div class="card">
<div class="card-title">Parâmetros de Soldagem</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Voltagem (V)</label>
<input type="number" class="form-control" id="hi-voltage" step="1" value="25">
</div>
<div class="form-group">
<label class="form-label">Corrente (A)</label>
<input type="number" class="form-control" id="hi-current" step="1" value="150">
</div>
<div class="form-group">
<label class="form-label">Velocidade (cm/min)</label>
<input type="number" class="form-control" id="hi-speed" step="1" value="20">
</div>
<div class="form-group expert-only">
<label class="form-label">Eficiência (%)</label>
<input type="number" class="form-control" id="hi-efficiency" step="1" value="85">
</div>
</div>
<button class="btn btn-primary" onclick="calcularEnergiaS oldagem()">🔥 Calcular Energia</button>
</div>
<div id="hi-result"></div>
`;
}
function getConsumoEletrodosContent() {
return `
<div class="section-header">
<div class="section-title">📊 Consumo de Eletrodos</div>
<div class="section-description">Estimativa de consumo com perdas</div>
</div>
<div class="card">
<div class="card-title">Dados da Solda</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Perna da Solda (mm)</label>
<input type="number" class="form-control" id="elec-leg" step="1" value="6">
</div>
<div class="form-group">
<label class="form-label">Comprimento Total (m)</label>
<input type="number" class="form-control" id="elec-length" step="0.1" value="10">
</div>
<div class="form-group">
<label class="form-label">Tipo de Eletrodo</label>
<select class="form-control" id="elec-type">
<option value="1.15">E6010</option>
<option value="1.10" selected>E7018</option>
<option value="1.12">E8018</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Perdas (%)</label>
<input type="number" class="form-control" id="elec-loss" step="1" value="15">
</div>
</div>
<button class="btn btn-primary" onclick="calcularConsumoEletrodos()">📊 Calcular Consumo</button>
</div>
<div id="elec-result"></div>
`;
}
function getDurezaContent() {
return `
<div class="section-header">
<div class="section-title">🔨 Conversor de Dureza</div>
<div class="section-description">Conversão entre escalas HB, HRC, HV</div>
</div>
<div class="card">
<div class="card-title">Digite em Qualquer Campo</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Brinell (HB)</label>
<input type="number" class="form-control" id="hard-hb" step="1" value="200" oninput="converterDureza('hb')">
</div>
<div class="form-group">
<label class="form-label">Rockwell C (HRC)</label>
<input type="number" class="form-control" id="hard-hrc" step="0.1" oninput="converterDureza('hrc')">
</div>
<div class="form-group">
<label class="form-label">Vickers (HV)</label>
<input type="number" class="form-control" id="hard-hv" step="1" oninput="converterDureza('hv')">
</div>
</div>
</div>
<div id="hardness-result"></div>
`;
}
function getCharpyContent() {
return `
<div class="section-header">
<div class="section-title">📉 Análise de Charpy</div>
<div class="section-description">Curva de transição dúctil-frágil</div>
</div>
<div class="card">
<div class="card-title">Insira até 4 Pares Temperatura/Energia</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Temp 1 (°C)</label>
<input type="number" class="form-control" id="charpy-t1" step="1" value="20">
</div>
<div class="form-group">
<label class="form-label">Energia 1 (J)</label>
<input type="number" class="form-control" id="charpy-e1" step="1" value="80">
</div>
<div class="form-group">
<label class="form-label">Temp 2 (°C)</label>
<input type="number" class="form-control" id="charpy-t2" step="1" value="0">
</div>
<div class="form-group">
<label class="form-label">Energia 2 (J)</label>
<input type="number" class="form-control" id="charpy-e2" step="1" value="50">
</div>
<div class="form-group">
<label class="form-label">Temp 3 (°C)</label>
<input type="number" class="form-control" id="charpy-t3" step="1" value="-20">
</div>
<div class="form-group">
<label class="form-label">Energia 3 (J)</label>
<input type="number" class="form-control" id="charpy-e3" step="1" value="30">
</div>
<div class="form-group">
<label class="form-label">Temp 4 (°C)</label>
<input type="number" class="form-control" id="charpy-t4" step="1" value="-40">
</div>
<div class="form-group">
<label class="form-label">Energia 4 (J)</label>
<input type="number" class="form-control" id="charpy-e4" step="1" value="15">
</div>
</div>
<button class="btn btn-primary" onclick="analisarCharpy()">📉 Gerar Curva</button>
</div>
<div id="charpy-result"></div>
`;
}
function getUltrassomContent() {
return `
<div class="section-header">
<div class="section-title">🏥 Interpretação de Ultrassom</div>
<div class="section-description">Classificação de descontinuidades segundo AWS/ASME</div>
</div>
<div class="card">
<div class="card-title">Parâmetros da Descontinuidade</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Norma de Avaliação</label>
<select class="form-control" id="ut-norm">
<option value="aws">AWS D1.1</option>
<option value="asme">ASME Section VIII Div 1</option>
<option value="dnv">DNV-GL</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Tipo de Descontinuidade</label>
<select class="form-control" id="ut-type" onchange="updateUtFields()">
<option value="porosidade">Porosidade</option>
<option value="inclusao">Inclusão de Escória</option>
<option value="falta-fusao">Falta de Fusão</option>
<option value="falta-penetracao">Falta de Penetração</option>
<option value="trinca">Trinca</option>
<option value="mordedura">Mordedura</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Localização</label>
<select class="form-control" id="ut-location">
<option value="raiz">Raiz</option>
<option value="passes">Passes Intermediários</option>
<option value="enchimento">Enchimento</option>
<option value="acabamento">Acabamento</option>
</select>
</div>
<div class="form-group" id="ut-diameter-group">
<label class="form-label">Diâmetro (mm)</label>
<input type="number" class="form-control" id="ut-diameter" step="0.1" value="2.5">
</div>
<div class="form-group" id="ut-qty-group">
<label class="form-label">Quantidade</label>
<input type="number" class="form-control" id="ut-qty" step="1" value="3">
</div>
<div class="form-group" id="ut-length-group">
<label class="form-label">Comprimento Total (mm)</label>
<input type="number" class="form-control" id="ut-length" step="0.1" value="25">
</div>
<div class="form-group">
<label class="form-label">Profundidade (mm)</label>
<input type="number" class="form-control" id="ut-depth" step="0.1" value="1.2">
</div>
<div class="form-group">
<label class="form-label">Espessura da Chapa (mm)</label>
<input type="number" class="form-control" id="ut-thickness" step="1" value="10">
</div>
</div>
<button class="btn btn-primary" onclick="analisarUltrassom()">🔍 Analisar Conforme Norma</button>
</div>
<div id="ut-result"></div>
`;
}
function getCertificadoContent() {
return `
<div class="section-header">
<div class="section-title">📋 Checklist de Certificado</div>
<div class="section-description">Verificação de conformidade com normas</div>
</div>
<div class="card">
<div class="card-title">Selecionar Norma</div>
<div class="form-group">
<label class="form-label">Norma de Referência</label>
<select class="form-control" id="cert-norm" onchange="gerarChecklistCertificado()">
<option value="astm_a36">ASTM A36</option>
<option value="astm_a572">ASTM A572 Gr.50</option>
<option value="en_s235">EN S235JR</option>
<option value="en_s355">EN S355J2</option>
<option value="nbr_ar350">NBR AR350</option>
</select>
</div>
</div>
<div id="cert-result"></div>
`;
}
function getAreaPinturaContent() {
return `
<div class="section-header">
<div class="section-title">📐 Cálculo de Área de Pintura</div>
<div class="section-description">Área total de superfície a pintar</div>
</div>
<div class="card">
<div class="card-title">Tipo de Produto</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Tipo</label>
<select class="form-control" id="paint-type" onchange="updatePaintFields()">
<option value="chapa">Chapa</option>
<option value="perfilW">Perfil W</option>
<option value="tubo">Tubo Circular</option>
<option value="rhs">Tubo Retangular (RHS)</option>
</select>
</div>
<div class="form-group" id="paint-field1">
<label class="form-label" id="paint-label1">Comprimento (mm)</label>
<input type="number" class="form-control" id="paint-dim1" step="1" value="6000">
</div>
<div class="form-group" id="paint-field2">
<label class="form-label" id="paint-label2">Largura (mm)</label>
<input type="number" class="form-control" id="paint-dim2" step="1" value="1000">
</div>
<div class="form-group" id="paint-field3" style="display:none;">
<label class="form-label" id="paint-label3">Altura (mm)</label>
<input type="number" class="form-control" id="paint-dim3" step="1" value="300">
</div>
<div class="form-group">
<label class="form-label">Quantidade</label>
<input type="number" class="form-control" id="paint-qty" step="1" value="1">
</div>
</div>
<button class="btn btn-primary" onclick="calcularAreaPintura()">📐 Calcular Área</button>
</div>
<div id="paint-area-result"></div>
`;
}
function getConsumoTintaContent() {
return `
<div class="section-header">
<div class="section-title">🎯 Consumo de Tinta</div>
<div class="section-description">Cálculo de volume e custo</div>
</div>
<div class="card">
<div class="card-title">Parâmetros de Pintura</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Área Total (m²)</label>
<input type="number" class="form-control" id="tinta-area" step="0.1" value="50">
</div>
<div class="form-group">
<label class="form-label">DFT Desejado (μm)</label>
<input type="number" class="form-control" id="tinta-dft" step="1" value="160">
</div>
<div class="form-group">
<label class="form-label">% Sólidos</label>
<input type="number" class="form-control" id="tinta-solids" step="1" value="65">
</div>
<div class="form-group">
<label class="form-label">% Perdas</label>
<input type="number" class="form-control" id="tinta-loss" step="1" value="25">
</div>
<div class="form-group">
<label class="form-label">Número de Demãos</label>
<input type="number" class="form-control" id="tinta-coats" step="1" value="2">
</div>
<div class="form-group">
<label class="form-label">Custo/Litro (R$)</label>
<input type="number" class="form-control" id="tinta-cost" step="0.01" value="80.00">
</div>
</div>
<button class="btn btn-primary" onclick="calcularConsumoTinta()">🎯 Calcular Consumo</button>
</div>
<div id="tinta-result"></div>
`;
}
function getCustoPinturaContent() {
return `
<div class="section-header">
<div class="section-title">💰 Custo Total de Pintura</div>
<div class="section-description">Análise completa de custos com mão de obra e materiais</div>
</div>
<div class="card">
<div class="card-title">Parâmetros de Custos</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Área Total (m²)</label>
<input type="number" class="form-control" id="custo-area" step="0.1" value="50">
</div>
<div class="form-group">
<label class="form-label">Região do Brasil</label>
<select class="form-control" id="custo-regiao">
<option value="sudeste">Sudeste (SP/RJ/MG)</option>
<option value="sul">Sul (RS/SC/PR)</option>
<option value="nordeste">Nordeste (CE/PE/BA)</option>
<option value="centrooeste">Centro-Oeste (DF/GO/MS)</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Tipo de Tinta</label>
<select class="form-control" id="custo-tipo-tinta">
<option value="padrao">Padrão Industrial</option>
<option value="premium">Premium (Maior Durabilidade)</option>
<option value="economica">Econômica (Budget)</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Custo Mão de Obra (R$/hora)</label>
<input type="number" class="form-control" id="custo-mo" step="1" value="85">
</div>
<div class="form-group">
<label class="form-label">Produtividade (m²/hora)</label>
<input type="number" class="form-control" id="custo-prod" step="0.1" value="5">
</div>
<div class="form-group">
<label class="form-label">Volume de Tinta (L)</label>
<input type="number" class="form-control" id="custo-volume" step="0.1" value="100">
</div>
</div>
<div style="margin: 20px 0;">
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
<input type="checkbox" id="custo-incluir-epi" checked style="width: 18px; height: 18px;">
<span>Incluir EPI e Materiais Consumíveis</span>
</label>
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; margin-top: 8px;">
<input type="checkbox" id="custo-incluir-equip" style="width: 18px; height: 18px;">
<span>Incluir Aluguel de Equipamentos</span>
</label>
</div>
<button class="btn btn-primary" onclick="calcularCustoTotal()">💵 Calcular Custo Final</button>
</div>
<div id="custo-result"></div>
`;
}
function getSecagemContent() {
return `
<div class="section-header">
<div class="section-title">⏱️ Tempo de Secagem</div>
<div class="section-description">Estimativa de tempo com análise de condições ambientais</div>
</div>
<div class="card">
<div class="card-title">Condições de Aplicação</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Tipo de Tinta</label>
<select class="form-control" id="sec-tipo">
<option value="epoxi">Epóxi</option>
<option value="poliuretano">Poliuretano (PU)</option>
<option value="alquidica">Alquídica</option>
<option value="acrilica">Acrílica</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Temperatura (°C)</label>
<input type="number" class="form-control" id="sec-temp" step="1" value="25">
</div>
<div class="form-group">
<label class="form-label">Umidade Relativa (%)</label>
<input type="number" class="form-control" id="sec-umidade" step="1" value="60">
</div>
<div class="form-group">
<label class="form-label">Espessura Aplicada (μm)</label>
<input type="number" class="form-control" id="sec-espessura" step="10" value="80">
</div>
</div>
<button class="btn btn-primary" onclick="calcularSecagem()">⏱️ Calcular Tempo</button>
</div>
<div id="sec-result"></div>
`;
}
function getInspecaoPinturaContent() {
return `
<div class="section-header">
<div class="section-title">✔️ Inspeção de Qualidade de Pintura</div>
<div class="section-description">Checklist profissional conforme ISO 12944</div>
</div>
<div class="card">
<div class="card-title">Checklist de Inspeção</div>
<div style="display: flex; flex-direction: column; gap: 12px; margin: 20px 0;">
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
<input type="checkbox" id="insp-1" style="width: 20px; height: 20px;">
<span><strong>Preparação de Superfície (ISO 8501):</strong> Grau de limpeza adequado (Sa 2½ mínimo)</span>
</label>
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
<input type="checkbox" id="insp-2" style="width: 20px; height: 20px;">
<span><strong>Limpeza:</strong> Superfície livre de pó, óleo, ferrugem e contaminantes</span>
</label>
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
<input type="checkbox" id="insp-3" style="width: 20px; height: 20px;">
<span><strong>Medição DFT:</strong> Espessura de película seca conforme especificação</span>
</label>
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
<input type="checkbox" id="insp-4" style="width: 20px; height: 20px;">
<span><strong>Teste de Aderência (ISO 2409):</strong> Cross-cut test aprovado</span>
</label>
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
<input type="checkbox" id="insp-5" style="width: 20px; height: 20px;">
<span><strong>Aspecto Visual:</strong> Cor, brilho e textura uniformes</span>
</label>
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
<input type="checkbox" id="insp-6" style="width: 20px; height: 20px;">
<span><strong>Uniformidade de Cobertura:</strong> Sem áreas descobertas ou falhas</span>
</label>
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
<input type="checkbox" id="insp-7" style="width: 20px; height: 20px;">
<span><strong>Ausência de Defeitos:</strong> Sem bolhas, rachaduras, escorrimentos ou crateras</span>
</label>
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
<input type="checkbox" id="insp-8" style="width: 20px; height: 20px;">
<span><strong>Tempo de Cura:</strong> Intervalo entre demãos e cura final adequados</span>
</label>
</div>
<button class="btn btn-primary" onclick="gerarRelatorioInspecao()">📋 Gerar Relatório</button>
</div>
<div id="insp-result"></div>
`;
}
function getGalvanizacaoContent() {
return `
<div class="section-header">
<div class="section-title">🛡️ Galvanização a Quente</div>
<div class="section-description">Espessura mínima e vida útil</div>
</div>
<div class="card">
<div class="card-title">Parâmetros de Galvanização</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Ambiente</label>
<select class="form-control" id="galv-env">
<option value="interno">Interno (C1)</option>
<option value="urbano">Urbano (C2/C3)</option>
<option value="marinho" selected>Marinho (C4/C5)</option>
<option value="industrial">Industrial (C4)</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Área a Galvanizar (m²)</label>
<input type="number" class="form-control" id="galv-area" step="0.1" value="100">
</div>
<div class="form-group">
<label class="form-label">Espessura Desejada (μm)</label>
<input type="number" class="form-control" id="galv-thickness" step="1" value="85">
</div>
<div class="form-group expert-only">
<label class="form-label">Vida Útil Desejada (anos)</label>
<input type="number" class="form-control" id="galv-life" step="1" value="20">
</div>
</div>
<button class="btn btn-primary" onclick="calcularGalvanizacao()">🛡️ Calcular</button>
</div>
<div id="galv-result"></div>
`;
}
function getOrcamentoContent() {
return `
<div class="section-header">
<div class="section-title">💵 Orçamento Detalhado v6.5</div>
<div class="section-description">Gerenciador completo com base de dados integrada de materiais</div>
</div>
<div style="padding: 20px; background: var(--color-bg-8); border-radius: 12px; border: 2px solid var(--color-primary); margin-bottom: 20px;">
<h3 style="margin-bottom: 12px; color: var(--color-primary);">🎉 NOVIDADE v6.5: Base de Dados Completa de Materiais!</h3>
<p style="margin-bottom: 12px;">Agora você pode selecionar materiais de um banco de dados com <strong>100+ produtos do mercado brasileiro</strong> (Gerdau, Usiminas):</p>
<ul style="margin-left: 20px; margin-bottom: 12px;">
<li>✅ Perfis W, I (IPE), HP - Pesos automáticos</li>
<li>✅ Cantoneiras, Tubos Circulares e RHS</li>
<li>✅ Chapas, Barras, Eletrodos, Tintas, Parafusos</li>
<li>✅ Preços regionais (Sudeste, Sul, Nordeste, Centro-Oeste)</li>
<li>✅ Cálculo automático de preço unitário baseado em peso e região</li>
</ul>
<button class="btn btn-primary" onclick="carregarOrcamentoExemplo()" style="margin-right: 10px;">📦 Carregar Orçamento Exemplo</button>
<button class="btn btn-secondary" onclick="alert('📖 TUTORIAL:\n\n1. Selecione a Região (preços ajustam automaticamente)\n2. Escolha Categoria: Material, Serviço, Consumível ou Indireto\n3. Selecione Tipo de Produto (ex: Perfil W)\n4. Escolha Especificação da lista (ex: W250×38)\n5. Preço e peso preenchem automaticamente!\n6. Digite quantidade e adicione\n\nSimples assim! 🚀')">📖 Como Usar</button>
</div>
<div class="card" style="background: var(--color-bg-1); border: 2px solid var(--color-primary);">
<div class="card-title">🌍 Configuração Regional</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Região do Brasil</label>
<select class="form-control" id="budget-region" onchange="updateRegionalPricing()">
<option value="sudeste" selected>Sudeste (SP/RJ/MG)</option>
<option value="sul">Sul (RS/SC/PR)</option>
<option value="nordeste">Nordeste (CE/PE/BA)</option>
<option value="centrooeste">Centro-Oeste (DF/GO/MS)</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Data do Orçamento</label>
<input type="date" class="form-control" id="budget-date" value="2025-11-07">
</div>
<div class="form-group">
<label class="form-label">Nome do Projeto</label>
<input type="text" class="form-control" id="budget-project" placeholder="Ex: Estrutura Galpão Industrial">
</div>
</div>
</div>
<div class="card">
<div class="card-title">✎ Adicionar Item ao Orçamento</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Categoria</label>
<select class="form-control" id="budget-category" onchange="updateBudgetTypeOptions()">
<option value="material">Material</option>
<option value="servico">Serviço</option>
<option value="consumivel">Consumível</option>
<option value="indireto">Indireto</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Tipo de Produto</label>
<select class="form-control" id="budget-type" onchange="updateBudgetSpecOptions()">
<option value="perfil_w">Perfil W</option>
<option value="perfil_i">Perfil I (IPE)</option>
<option value="perfil_hp">Perfil HP</option>
<option value="cantoneira">Cantoneira</option>
<option value="tubo_circ">Tubo Circular</option>
<option value="tubo_rhs">Tubo Retangular (RHS)</option>
<option value="chapa">Chapa</option>
<option value="barra">Barra Redonda</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Especificação (Produto)</label>
<select class="form-control" id="budget-spec" onchange="autoFillBudgetData()">
<option value="">Selecione...</option>
</select>
</div>
</div>
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; margin: 16px 0; display: none;" id="product-info-display">
<strong>📋 Informações do Produto:</strong><br>
<span id="product-details"></span>
</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Quantidade</label>
<input type="number" class="form-control" id="budget-qty" step="0.01" value="1" oninput="updateBudgetTotal()">
</div>
<div class="form-group">
<label class="form-label">Unidade</label>
<input type="text" class="form-control" id="budget-unit" value="m" readonly style="background: var(--color-secondary);">
</div>
<div class="form-group">
<label class="form-label">Preço Unitário (R$)</label>
<input type="number" class="form-control" id="budget-price" step="0.01" value="0" readonly style="background: var(--color-bg-3); font-weight: bold;">
</div>
<div class="form-group">
<label class="form-label">Total (R$)</label>
<input type="text" class="form-control" id="budget-item-total" value="R$ 0.00" readonly style="background: var(--color-bg-1); font-weight: bold; font-size: 16px;">
</div>
</div>
<button class="btn btn-success" onclick="adicionarItemOrcamentoV2()" style="width: 100%; padding: 16px; font-size: 16px;"> Adicionar ao Orçamento</button>
</div>
<div class="card">
<div class="card-title">📋 Itens do Orçamento</div>
<div class="table-container">
<table id="budget-table" style="font-size: 13px;">
<thead>
<tr style="background: var(--color-primary); color: var(--color-btn-primary-text);">
<th style="padding: 12px;">#</th>
<th>Categoria</th>
<th>Especificação</th>
<th>Qtd</th>
<th>Un</th>
<th>Preço Unit.</th>
<th>Valor Total</th>
<th>Ações</th>
</tr>
</thead>
<tbody id="budget-tbody">
<tr>
<td colspan="8" style="text-align: center; color: var(--color-text-secondary); padding: 24px;">Nenhum item adicionado</td>
</tr>
</tbody>
</table>
</div>
<div class="form-group" style="margin-top: 20px; max-width: 300px;">
<label class="form-label">BDI / Margem (%)</label>
<input type="number" class="form-control" id="budget-bdi" step="0.1" value="25" onchange="atualizarTotalOrcamentoV2()" style="font-size: 16px; font-weight: bold;">
</div>
<div id="budget-total"></div>
</div>
`;
}
function getPesoRiggingContent() {
return `
<div class="section-header">
<div class="section-title">⚖️ Peso &amp; Plano de Rigging</div>
<div class="section-description">Cálculo de peso e dimensionamento de içamento</div>
</div>
<div class="card">
<div class="card-title">Cálculo de Peso</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Tipo</label>
<select class="form-control" id="weight-type" onchange="updateWeightFields()">
<option value="perfilW">Perfil W</option>
<option value="chapa">Chapa</option>
<option value="tubo">Tubo Circular</option>
<option value="barra">Barra Redonda</option>
</select>
</div>
<div class="form-group" id="weight-field1">
<label class="form-label" id="weight-label1">Altura (mm)</label>
<input type="number" class="form-control" id="weight-dim1" step="1" value="300">
</div>
<div class="form-group" id="weight-field2">
<label class="form-label" id="weight-label2">Comprimento (m)</label>
<input type="number" class="form-control" id="weight-dim2" step="0.1" value="6">
</div>
<div class="form-group" id="weight-field3" style="display:none;">
<label class="form-label" id="weight-label3">Largura (mm)</label>
<input type="number" class="form-control" id="weight-dim3" step="1" value="1000">
</div>
<div class="form-group" id="weight-field4" style="display:none;">
<label class="form-label" id="weight-label4">Espessura (mm)</label>
<input type="number" class="form-control" id="weight-dim4" step="0.1" value="10">
</div>
</div>
<button class="btn btn-primary" onclick="calcularPeso()">⚖️ Calcular Peso</button>
</div>
<div id="weight-result"></div>
<div class="card">
<div class="card-title">Dimensionamento de Rigging</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Peso Total (kg)</label>
<input type="number" class="form-control" id="rigging-weight" step="1" value="1000">
</div>
<div class="form-group">
<label class="form-label">Pontos de Içamento</label>
<select class="form-control" id="rigging-points">
<option value="2" selected>2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Ângulo</label>
<select class="form-control" id="rigging-angle">
<option value="90">90°</option>
<option value="75">75°</option>
<option value="60" selected>60°</option>
<option value="45">45°</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Fator de Segurança</label>
<input type="number" class="form-control" id="rigging-fs" step="0.1" value="4">
</div>
</div>
<button class="btn btn-primary" onclick="calcularRigging()">🏗️ Calcular Rigging</button>
</div>
<div id="rigging-result"></div>
`;
}
function getReferenciaContent() {
return `
<div class="section-header">
<div class="section-title">📖 Referência Técnica</div>
<div class="section-description">Banco de dados completo de aços e sistemas</div>
</div>
<div class="card">
<div class="card-title">Aços Estruturais</div>
<div class="table-container">
<table>
<thead>
<tr>
<th>Designação</th>
<th>fy (MPa)</th>
<th>fu (MPa)</th>
<th>Along. (%)</th>
<th>CEV</th>
<th>Soldabilidade</th>
<th>Aplicação</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>ASTM A36</strong></td>
<td>250</td>
<td>400</td>
<td>20</td>
<td>0.41</td>
<td>⭐⭐⭐⭐⭐</td>
<td>Estruturas gerais</td>
</tr>
<tr>
<td><strong>ASTM A572 Gr.50</strong></td>
<td>345</td>
<td>450</td>
<td>18</td>
<td>0.45</td>
<td>⭐⭐⭐⭐</td>
<td>Edifícios, pontes</td>
</tr>
<tr>
<td><strong>ASTM A588</strong></td>
<td>345</td>
<td>485</td>
<td>19</td>
<td>0.50</td>
<td>⭐⭐⭐</td>
<td>Weathering</td>
</tr>
<tr>
<td><strong>EN S235JR</strong></td>
<td>235</td>
<td>360</td>
<td>26</td>
<td>0.38</td>
<td>⭐⭐⭐⭐⭐</td>
<td>Estruturas gerais</td>
</tr>
<tr>
<td><strong>EN S355J2</strong></td>
<td>355</td>
<td>490</td>
<td>22</td>
<td>0.50</td>
<td>⭐⭐⭐⭐</td>
<td>Pontes, pesadas</td>
</tr>
<tr>
<td><strong>NBR AR350</strong></td>
<td>345</td>
<td>450</td>
<td>18</td>
<td>0.45</td>
<td>⭐⭐⭐⭐</td>
<td>Construção civil</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card">
<div class="card-title">Sistemas de Pintura ISO 12944</div>
<div class="table-container">
<table>
<thead>
<tr>
<th>Classe</th>
<th>Ambiente</th>
<th>DFT (μm)</th>
<th>Sistema</th>
<th>Vida Útil</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>C1</strong></td>
<td>Interior seco</td>
<td>80</td>
<td>Monocomponente</td>
<td>5-10 anos</td>
</tr>
<tr>
<td><strong>C2</strong></td>
<td>Interior úmido</td>
<td>120</td>
<td>Epóxi 2c</td>
<td>5-10 anos</td>
</tr>
<tr>
<td><strong>C3</strong></td>
<td>Exterior médio</td>
<td>160</td>
<td>Epóxi + PU</td>
<td>10-15 anos</td>
</tr>
<tr>
<td><strong>C4</strong></td>
<td>Exterior agressivo</td>
<td>200</td>
<td>Epóxi alicíclico + PU</td>
<td>15-20 anos</td>
</tr>
<tr>
<td><strong>C5</strong></td>
<td>Marinho</td>
<td>250</td>
<td>Epóxi zinc-rich + PU</td>
<td>20+ anos</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="card">
<div class="card-title">Normas de Referência</div>
<ul style="list-style-type: none; padding: 0;">
<li style="padding: 12px; background: var(--color-bg-1); margin-bottom: 8px; border-radius: 8px;">
<strong>AWS D1.1/D1.1M</strong> - Soldagem de estruturas de aço
</li>
<li style="padding: 12px; background: var(--color-bg-2); margin-bottom: 8px; border-radius: 8px;">
<strong>NBR 8800:2008</strong> - Projeto de estruturas de aço de edifícios
</li>
<li style="padding: 12px; background: var(--color-bg-3); margin-bottom: 8px; border-radius: 8px;">
<strong>EN 1993-1-8</strong> - Design of connections
</li>
<li style="padding: 12px; background: var(--color-bg-4); margin-bottom: 8px; border-radius: 8px;">
<strong>ISO 12944</strong> - Proteção de estruturas de aço com tinta
</li>
<li style="padding: 12px; background: var(--color-bg-5); margin-bottom: 8px; border-radius: 8px;">
<strong>ASTM A123</strong> - Galvanização a quente
</li>
</ul>
</div>
`;
}
// ========================================
// CALCULATION FUNCTIONS
// ========================================
// CEV Calculation
function calcularCEV() {
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;
// Interpretation
let stars = '';
let interpretation = '';
let alertClass = '';
if (CEV < 0.40) {
stars = '⭐⭐⭐⭐⭐';
interpretation = 'Excelente soldabilidade - Sem pré-aquecimento até 50mm';
alertClass = 'alert-success';
} else if (CEV < 0.50) {
stars = '⭐⭐⭐⭐';
interpretation = 'Boa soldabilidade - Pré-aquecimento recomendado acima de 25mm';
alertClass = 'alert-success';
} else if (CEV < 0.60) {
stars = '⭐⭐⭐';
interpretation = 'Soldabilidade média - Pré-aquecimento essencial acima de 15mm';
alertClass = 'alert-warning';
} else if (CEV < 0.70) {
stars = '⭐⭐';
interpretation = 'Soldabilidade difícil - Pré-aquecimento obrigatório, considerar PWHT';
alertClass = 'alert-warning';
} else {
stars = '⭐';
interpretation = 'Soldabilidade muito difícil - Procedimento especial necessário';
alertClass = 'alert-error';
}
// Preheat temperature (AWS D1.1)
const tempAmb = parseFloat(document.getElementById('cev-temp')?.value) || 20;
const preheatTemp = 50 + (CEV * 50) + (thickness / 10 * 20) + ((20 - tempAmb) / 2);
const result = document.getElementById('cev-result');
result.innerHTML = `
<div class="result-box">
<div class="result-title">Resultado do Cálculo CEV (IIW)</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">CEV</div>
<div class="result-value">${CEV.toFixed(3)}</div>
</div>
<div class="result-item">
<div class="result-label">Avaliação</div>
<div class="result-value" style="font-size: 28px;">${stars}</div>
</div>
<div class="result-item">
<div class="result-label">Pré-aquecimento Mínimo</div>
<div class="result-value">${Math.round(preheatTemp)}°C</div>
</div>
</div>
<div class="alert ${alertClass}" style="margin-top: 16px;">
<strong>${interpretation}</strong>
</div>
<div class="expert-only" style="margin-top: 16px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">
<strong>Fórmula IIW:</strong> CEV = C + Mn/6 + (Cr+Mo+V)/5 + (Ni+Cu)/15<br>
<strong>Normas aplicáveis:</strong> AWS D1.1, NBR 16239, EN 1011-2
</div>
</div>
`;
addToHistory('CEV Avançado', `CEV = ${CEV.toFixed(3)}, Pré-aquecimento = ${Math.round(preheatTemp)}°C`);
}
// Steel Selector
function selecionarAco() {
const fyMin = parseFloat(document.getElementById('sel-fy').value) || 0;
const weldReq = document.getElementById('sel-weld').value;
const steels = Object.values(steelDatabase).filter(steel => {
if (steel.fy < fyMin) return false;
if (weldReq === 'excellent' && steel.cev > 0.45) return false;
if (weldReq === 'good' && steel.cev > 0.55) return false;
return true;
});
if (steels.length === 0) {
document.getElementById('seletor-result').innerHTML = `
<div class="alert alert-warning">
Nenhum aço encontrado com os critérios especificados
</div>
`;
return;
}
const result = steels.map(steel => `
<div class="steel-card">
<h3 style="color: var(--color-primary); margin-bottom: 12px;">${steel.nome}</h3>
<div class="result-grid">
<div class="result-item">
<div class="result-label">fy</div>
<div class="result-value" style="font-size: 20px;">${steel.fy} MPa</div>
</div>
<div class="result-item">
<div class="result-label">fu</div>
<div class="result-value" style="font-size: 20px;">${steel.fu} MPa</div>
</div>
<div class="result-item">
<div class="result-label">Alongamento</div>
<div class="result-value" style="font-size: 20px;">${steel.elong}%</div>
</div>
<div class="result-item">
<div class="result-label">CEV</div>
<div class="result-value" style="font-size: 20px;">${steel.cev}</div>
</div>
</div>
<p style="margin-top: 12px;"><strong>Soldabilidade:</strong> ${steel.soldabilidade}</p>
<p><strong>Equivalentes:</strong> ${steel.equiv.join(', ')}</p>
<p><strong>Custo relativo:</strong> ${steel.custo}%</p>
</div>
`).join('');
document.getElementById('seletor-result').innerHTML = `
<div class="card">
<div class="card-title">Aços Recomendados (${steels.length})</div>
${result}
</div>
`;
addToHistory('Seletor de Aço', `${steels.length} aços encontrados com fy ≥ ${fyMin} MPa`);
}
// Equivalencias
function mostrarEquivalencias() {
const steelSelect = document.getElementById('equiv-steel');
const resultDiv = document.getElementById('equiv-result');
// Verificar se os elementos existem antes de continuar
if (!steelSelect || !resultDiv) return;
const steelId = steelSelect.value;
const steel = steelDatabase[steelId];
if (!steel) return;
document.getElementById('equiv-result').innerHTML = `
<div class="card">
<div class="card-title">Equivalências para ${steel.nome}</div>
<div class="table-container">
<table>
<thead>
<tr>
<th>Norma</th>
<th>Designação</th>
<th>fy (MPa)</th>
<th>fu (MPa)</th>
<th>Along. (%)</th>
<th>CEV</th>
</tr>
</thead>
<tbody>
<tr style="background: var(--color-bg-1);">
<td><strong>Base</strong></td>
<td><strong>${steel.nome}</strong></td>
<td><strong>${steel.fy}</strong></td>
<td><strong>${steel.fu}</strong></td>
<td><strong>${steel.elong}</strong></td>
<td><strong>${steel.cev}</strong></td>
</tr>
${steel.equiv.map(eq => {
const eqSteel = Object.values(steelDatabase).find(s => s.nome === eq);
if (!eqSteel) return '';
return `
<tr>
<td>${eq.includes('ASTM') ? 'ASTM' : eq.includes('EN') ? 'EN' : eq.includes('NBR') ? 'NBR' : 'JIS'}</td>
<td>${eqSteel.nome}</td>
<td>${eqSteel.fy}</td>
<td>${eqSteel.fu}</td>
<td>${eqSteel.elong}</td>
<td>${eqSteel.cev}</td>
</tr>
`;
}).join('')}
</tbody>
</table>
</div>
</div>
`;
}
// Comparative Chart
function gerarGraficoComparativo() {
const checkboxes = document.querySelectorAll('.checkbox-group input:checked');
const selectedSteels = Array.from(checkboxes).map(cb => cb.value);
const chartType = document.getElementById('chart-type').value;
if (selectedSteels.length === 0) {
alert('Selecione pelo menos um aço');
return;
}
if (chartType === 'table') {
let tableHtml = `
<div class="card">
<div class="card-title">Tabela Comparativa</div>
<div class="table-container">
<table>
<thead>
<tr>
<th>Aço</th>
<th>fy (MPa)</th>
<th>fu (MPa)</th>
<th>Along. (%)</th>
<th>CEV</th>
<th>Soldabilidade</th>
<th>Custo</th>
</tr>
</thead>
<tbody>
`;
selectedSteels.forEach(steelId => {
const steel = steelDatabase[steelId];
if (steel) {
tableHtml += `
<tr>
<td><strong>${steel.nome}</strong></td>
<td>${steel.fy}</td>
<td>${steel.fu}</td>
<td>${steel.elong}</td>
<td>${steel.cev}</td>
<td>${steel.soldabilidade}</td>
<td>${steel.custo}%</td>
</tr>
`;
}
});
tableHtml += `
</tbody>
</table>
</div>
</div>
`;
document.getElementById('chart-result').innerHTML = tableHtml;
} else {
document.getElementById('chart-result').innerHTML = `
<div class="card">
<div class="card-title">Gráfico Comparativo</div>
<div class="chart-container">
<canvas id="comparison-chart"></canvas>
</div>
</div>
`;
if (currentChart) {
currentChart.destroy();
}
const ctx = document.getElementById('comparison-chart').getContext('2d');
const colors = ['#1FB8CD', '#FFC185', '#B4413C', '#ECEBD5', '#5D878F', '#DB4545'];
if (chartType === 'resistance') {
currentChart = new Chart(ctx, {
type: 'bar',
data: {
labels: selectedSteels.map(s => steelDatabase[s]?.nome || s),
datasets: [
{
label: 'fy (MPa)',
data: selectedSteels.map(s => steelDatabase[s]?.fy || 0),
backgroundColor: colors[0]
},
{
label: 'fu (MPa)',
data: selectedSteels.map(s => steelDatabase[s]?.fu || 0),
backgroundColor: colors[1]
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: 'Comparação de Resistência'
}
}
}
});
} else if (chartType === 'ductility') {
currentChart = new Chart(ctx, {
type: 'line',
data: {
labels: selectedSteels.map(s => steelDatabase[s]?.nome || s),
datasets: [{
label: 'Alongamento (%)',
data: selectedSteels.map(s => steelDatabase[s]?.elong || 0),
borderColor: colors[2],
backgroundColor: colors[2] + '40',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: 'Comparação de Ductilidade'
}
}
}
});
}
}
addToHistory('Gráficos Comparativos', `Comparação de ${selectedSteels.length} aços`);
}
// ========================================
// ASSISTENTE INTELIGENTE - AI RECOMMENDATIONS
// ========================================
/**
* Update AI recommendations based on current selections
*/
function updateAIRecommendations() {
const steel = document.getElementById('ai-steel')?.value;
const environment = document.getElementById('ai-environment')?.value;
if (!steel || !environment) {
document.getElementById('ai-recommendations').innerHTML = '';
return;
}
// Show preview
document.getElementById('ai-recommendations').innerHTML = `
<div class="card" style="background: var(--color-bg-2); border-left: 4px solid var(--color-primary);">
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 12px;">
<span style="font-size: 24px;">⚡</span>
<div>
<h4 style="margin: 0;">Pré-visualização</h4>
<p style="margin: 0; font-size: 13px; color: var(--color-text-secondary);">Clique em "Gerar Recomendação" para ver detalhes completos</p>
</div>
</div>
<div style="display: flex; gap: 20px; font-size: 14px;">
<div><strong>Aço:</strong> ${steel}</div>
<div><strong>Ambiente:</strong> ${environment}</div>
</div>
</div>
`;
}
/**
* Generate complete AI recommendation
*/
async function generateAIRecommendation() {
const steel = document.getElementById('ai-steel')?.value;
const environment = document.getElementById('ai-environment')?.value;
if (!steel || !environment) {
alert('⚠️ Selecione o aço e o ambiente antes de gerar a recomendação!');
return;
}
const resultsDiv = document.getElementById('ai-recommendations');
// Show loading
resultsDiv.innerHTML = `
<div class="card" style="text-align: center; padding: 40px;">
<div style="font-size: 48px; margin-bottom: 16px;">🤖</div>
<h3>Analisando requisitos...</h3>
<p style="color: var(--color-text-secondary);">Cruzando dados de aço, soldagem e pintura</p>
<div style="margin-top: 20px;">
<div style="display: inline-block; width: 200px; height: 4px; background: var(--color-bg-3); border-radius: 2px; overflow: hidden;">
<div style="width: 100%; height: 100%; background: var(--color-primary); animation: loading 1.5s ease-in-out infinite;"></div>
</div>
</div>
</div>
`;
try {
// Import and use the relationships module
const {
loadRelationships,
getCompleteRecommendation,
formatWeldingRecommendation,
formatPaintingRecommendation
} = await import('./js/utils/material-relationships.js');
// Ensure relationships are loaded
await loadRelationships();
// Get recommendation
const recommendation = getCompleteRecommendation(steel, environment);
// Generate results HTML
let html = `
<div class="card" style="background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-hover) 100%); color: white; margin-bottom: 20px;">
<div style="display: flex; align-items: center; gap: 16px; margin-bottom: 16px;">
<span style="font-size: 48px;">🤖</span>
<div>
<h2 style="margin: 0; font-size: 24px;">Recomendação Inteligente</h2>
<p style="margin: 0; opacity: 0.9;">Baseada em relacionamentos técnicos da base de dados</p>
</div>
</div>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-top: 20px;">
<div style="background: rgba(255,255,255,0.1); padding: 16px; border-radius: 8px;">
<div style="font-size: 20px; margin-bottom: 8px;">🏗️</div>
<div style="font-weight: bold;">Aço Selecionado</div>
<div style="opacity: 0.9;">${steel}</div>
</div>
<div style="background: rgba(255,255,255,0.1); padding: 16px; border-radius: 8px;">
<div style="font-size: 20px; margin-bottom: 8px;">🌊</div>
<div style="font-weight: bold;">Ambiente</div>
<div style="opacity: 0.9;">${environment}</div>
</div>
<div style="background: rgba(255,255,255,0.1); padding: 16px; border-radius: 8px;">
<div style="font-size: 20px; margin-bottom: 8px;">${recommendation.hasWelding ? '✅' : '❌'}</div>
<div style="font-weight: bold;">Soldagem</div>
<div style="opacity: 0.9;">${recommendation.hasWelding ? 'Disponível' : 'Não encontrada'}</div>
</div>
<div style="background: rgba(255,255,255,0.1); padding: 16px; border-radius: 8px;">
<div style="font-size: 20px; margin-bottom: 8px;">${recommendation.hasPainting ? '✅' : '❌'}</div>
<div style="font-weight: bold;">Pintura</div>
<div style="opacity: 0.9;">${recommendation.hasPainting ? 'Disponível' : 'Não encontrada'}</div>
</div>
</div>
<div style="margin-top: 20px; padding: 16px; background: rgba(255,255,255,0.1); border-radius: 8px;">
<div style="font-weight: bold; margin-bottom: 8px;">📊 Status da Recomendação</div>
<div style="display: flex; align-items: center; gap: 8px;">
<div style="font-size: 24px;">${recommendation.isComplete ? '🎯' : '⚠️'}</div>
<div>
${recommendation.isComplete
? 'Recomendação completa disponível!'
: 'Recomendação parcial - alguns dados podem estar indisponíveis'}
</div>
</div>
</div>
</div>
`;
// Add welding recommendation
html += formatWeldingRecommendation(recommendation.welding);
// Add painting recommendation
html += formatPaintingRecommendation(recommendation.painting);
// Add action buttons
html += `
<div class="card" style="background: var(--color-bg-4); text-align: center;">
<h4 style="margin-bottom: 16px;">🚀 Próximos Passos</h4>
<div style="display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;">
<button class="btn btn-primary" onclick="showSection('preaquecimento')">
🔥 Calcular Pré-aquecimento
</button>
<button class="btn btn-primary" onclick="showSection('area-pintura')">
🎨 Calcular Área de Pintura
</button>
<button class="btn btn-secondary" onclick="exportAIRecommendation()">
📄 Exportar Relatório
</button>
</div>
</div>
`;
resultsDiv.innerHTML = html;
// Add to history
addToHistory('Assistente IA', `${steel} + ${environment}`);
} catch (error) {
console.error('Erro ao gerar recomendação:', error);
resultsDiv.innerHTML = `
<div class="card" style="background: var(--color-bg-4); border-left: 4px solid var(--color-error);">
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 12px;">
<span style="font-size: 32px;">❌</span>
<div>
<h4 style="margin: 0; color: var(--color-error);">Erro ao Gerar Recomendação</h4>
<p style="margin: 0; font-size: 13px; color: var(--color-text-secondary);">Não foi possível carregar os dados de relacionamento</p>
</div>
</div>
<p style="margin-bottom: 16px;">Possíveis causas:</p>
<ul style="margin-bottom: 16px;">
<li>Arquivos CSV de relacionamento não encontrados</li>
<li>Erro de rede ao carregar dados</li>
<li>Formato de dados incompatível</li>
</ul>
<p style="font-size: 13px; color: var(--color-text-secondary);">Erro: ${error.message}</p>
<button class="btn btn-primary" onclick="location.reload()">🔄 Recarregar Página</button>
</div>
`;
}
}
/**
* Export AI recommendation as PDF report
*/
async function exportAIRecommendation() {
const steel = document.getElementById('ai-steel')?.value;
const environment = document.getElementById('ai-environment')?.value;
if (!steel || !environment) {
alert('⚠️ Gere uma recomendação primeiro!');
return;
}
// Show loading toast
const loadingToast = document.createElement('div');
loadingToast.textContent = '⏳ Gerando PDF...';
loadingToast.style.cssText = `
position: fixed;
bottom: 24px;
right: 24px;
padding: 16px 24px;
background: var(--color-primary);
color: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 10000;
font-size: 14px;
font-weight: 500;
`;
document.body.appendChild(loadingToast);
try {
// Get recommendation data from the module
const {
loadRelationships,
getCompleteRecommendation
} = await import('./js/utils/material-relationships.js');
await loadRelationships();
const recommendation = getCompleteRecommendation(steel, environment);
console.log('📊 Dados da recomendação:', recommendation);
// Extract data with correct field names
const w = recommendation.welding || {};
const p = recommendation.painting || {};
// Generate HTML for PDF
const htmlContent = `
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Relatório de Recomendação</title>
<style>
@page { size: A4; margin: 1.5cm; }
body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #ffffff; color: #333; line-height: 1.35; font-size: 10pt; }
.container { width: 100%; max-width: 100%; margin: 0; padding: 0; background-color: #ffffff; }
h1 { text-align: center; color: #0d47a1; border-bottom: 2px solid #0d47a1; padding-bottom: 5px; margin-bottom: 15px; font-size: 16pt; }
h2 { font-size: 13pt; color: #1565c0; border-bottom: 1px solid #eee; padding-bottom: 4px; margin-top: 15px; margin-bottom: 10px; page-break-after: avoid; }
h3 { font-size: 11pt; color: #333; margin-top: 10px; margin-bottom: 5px; page-break-after: avoid; }
.data-group { background-color: #fdfdfd; border: 1px solid #eaeaea; border-radius: 5px; padding: 10px; margin-bottom: 10px; page-break-inside: avoid; }
.data-item { display: flex; flex-wrap: wrap; margin-bottom: 4px; padding-bottom: 4px; border-bottom: 1px dashed #f0f0f0; }
.data-item:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }
.data-label { font-weight: bold; color: #555; flex-basis: 180px; flex-grow: 0; }
.data-value { flex-basis: 300px; flex-grow: 1; color: #222; }
.paint-table { width: 100%; border-collapse: collapse; margin-top: 5px; table-layout: fixed; page-break-inside: avoid; }
.paint-table th, .paint-table td { border: 1px solid #ccc; padding: 5px; text-align: left; vertical-align: top; }
.paint-table th { background-color: #e3f2fd; color: #0d47a1; font-size: 9pt; text-transform: uppercase; text-align: center; }
.paint-table td strong { font-size: 10pt; color: #333; display: block; margin-bottom: 2px; }
.paint-table td span { font-size: 8pt; color: #666; display: block; }
.observations { background-color: #fffde7; border: 1px solid #fff9c4; border-left: 5px solid #fbc02d; padding: 8px 12px; margin-top: 10px; border-radius: 5px; font-style: italic; page-break-inside: avoid; }
.observations .data-label { font-weight: bold; color: #665c1e; }
.header-info { text-align: center; color: #666; font-size: 9pt; margin-bottom: 20px; }
</style>
</head>
<body>
<div class="container">
<h1>Relatório de Recomendação Inteligente</h1>
<div class="header-info">
SteelBase v7.5 | Data: ${new Date().toLocaleDateString('pt-BR')} | Hora: ${new Date().toLocaleTimeString('pt-BR')}
</div>
<!-- Seção 1: Seleção de Requisitos -->
<h2>Seleção de Requisitos</h2>
<div class="data-group">
<div class="data-item">
<span class="data-label">Aço Estrutural:</span>
<span class="data-value">${steel}</span>
</div>
<div class="data-item">
<span class="data-label">Ambiente Corrosivo:</span>
<span class="data-value">${environment}</span>
</div>
</div>
<!-- Seção 2: Resumo da Recomendação -->
<h2>Resumo da Recomendação</h2>
<div class="data-group">
<div class="data-item">
<span class="data-label">Aço Selecionado:</span>
<span class="data-value">${steel}</span>
</div>
<div class="data-item">
<span class="data-label">Ambiente:</span>
<span class="data-value">${environment}</span>
</div>
<div class="data-item">
<span class="data-label">Soldagem:</span>
<span class="data-value">${recommendation.hasWelding ? 'Disponível' : 'Não encontrada'}</span>
</div>
<div class="data-item">
<span class="data-label">Pintura:</span>
<span class="data-value">${recommendation.hasPainting ? 'Disponível' : 'Não encontrada'}</span>
</div>
<div class="data-item">
<span class="data-label">Status:</span>
<span class="data-value" style="color: ${recommendation.isComplete ? '#2e7d32' : '#f57c00'}; font-weight: bold;">
${recommendation.isComplete ? 'Recomendação completa disponível!' : 'Recomendação parcial'}
</span>
</div>
</div>
<!-- Seção 3: Soldagem Recomendada -->
${w && Object.keys(w).length > 0 ? `
<h2>Soldagem Recomendada</h2>
<div class="data-group">
<h3>Processos</h3>
${w.Processo_Soldagem_1 ? `
<div class="data-item">
<span class="data-label">Processo 1:</span>
<span class="data-value">${w.Processo_Soldagem_1} (Eletrodo: ${w.Eletrodo_1 || 'N/A'})</span>
</div>` : ''}
${w.Processo_Soldagem_2 ? `
<div class="data-item">
<span class="data-label">Processo 2:</span>
<span class="data-value">${w.Processo_Soldagem_2} (Arame: ${w.Arame_2 || 'N/A'}, Gás: ${w['Gás_Proteção'] || 'N/A'})</span>
</div>` : ''}
${w.Processo_Soldagem_3 ? `
<div class="data-item">
<span class="data-label">Processo 3:</span>
<span class="data-value">${w.Processo_Soldagem_3} (Arame/Fluxo: ${w.Arame_Fluxo_3 || 'N/A'})</span>
</div>` : ''}
<h3>Parâmetros e Normas</h3>
${w.CEV ? `
<div class="data-item">
<span class="data-label">CEV:</span>
<span class="data-value">${w.CEV}</span>
</div>` : ''}
${w['Pré_Aquecimento'] ? `
<div class="data-item">
<span class="data-label">Pré-aquecimento:</span>
<span class="data-value">${w['Pré_Aquecimento']}</span>
</div>` : ''}
${w.Norma_Soldagem ? `
<div class="data-item">
<span class="data-label">Norma:</span>
<span class="data-value">${w.Norma_Soldagem}</span>
</div>` : ''}
${w.Ensaios_NDT ? `
<div class="data-item">
<span class="data-label">Ensaios:</span>
<span class="data-value">${w.Ensaios_NDT}</span>
</div>` : ''}
${w['Observações'] ? `
<div class="observations">
<div class="data-item">
<span class="data-label">Observações:</span>
<span class="data-value">${w['Observações']}</span>
</div>
</div>` : ''}
</div>
` : '<h2>Soldagem Recomendada</h2><div class="data-group"><p>Dados de soldagem não disponíveis para este aço.</p></div>'}
<!-- Seção 4: Pintura Recomendada -->
${p && Object.keys(p).length > 0 ? `
<h2>Pintura Recomendada</h2>
<div class="data-group">
<h3>Condições e Preparação</h3>
${p.Ambiente_Corrosivo ? `
<div class="data-item">
<span class="data-label">Ambiente:</span>
<span class="data-value">${p.Ambiente_Corrosivo}</span>
</div>` : ''}
${p['Vida_Útil_Esperada'] ? `
<div class="data-item">
<span class="data-label">Vida útil:</span>
<span class="data-value">${p['Vida_Útil_Esperada']}</span>
</div>` : ''}
${p['Preparação_Superfície'] ? `
<div class="data-item">
<span class="data-label">Preparação:</span>
<span class="data-value">${p['Preparação_Superfície']}</span>
</div>` : ''}
${p.Rugosidade ? `
<div class="data-item">
<span class="data-label">Rugosidade:</span>
<span class="data-value">${p.Rugosidade}</span>
</div>` : ''}
${p.DFT_Total ? `
<div class="data-item">
<span class="data-label">DFT Total:</span>
<span class="data-value">${p.DFT_Total}</span>
</div>` : ''}
${p['Custo_Estimado_$/m²'] ? `
<div class="data-item">
<span class="data-label">Custo Estimado:</span>
<span class="data-value">${p['Custo_Estimado_$/m²']}</span>
</div>` : ''}
<h3>Sistema de Pintura (3 camadas)</h3>
<table class="paint-table">
<thead>
<tr>
<th>PRIMER</th>
<th>INTERMEDIÁRIA</th>
<th>ACABAMENTO</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<strong>${p.Primer || 'N/A'}</strong><br>
<span>${p.DFT_Primer || 'N/A'}</span><br>
<span style="font-size: 7pt;">${p.Primer_Descrição || ''}</span>
</td>
<td>
<strong>${p['Intermediária'] || 'N/A'}</strong><br>
<span>${p['DFT_Intermediária'] || 'N/A'}</span><br>
<span style="font-size: 7pt;">${p['Intermediária_Descrição'] || ''}</span>
</td>
<td>
<strong>${p.Acabamento || 'N/A'}</strong><br>
<span>${p.DFT_Acabamento || 'N/A'}</span><br>
<span style="font-size: 7pt;">${p['Acabamento_Descrição'] || ''}</span>
</td>
</tr>
</tbody>
</table>
<h3 style="margin-top: 10px;">Normas e Ensaios</h3>
${p.Norma_Pintura ? `
<div class="data-item">
<span class="data-label">Norma:</span>
<span class="data-value">${p.Norma_Pintura}</span>
</div>` : ''}
${p.Ensaios_Qualidade ? `
<div class="data-item">
<span class="data-label">Ensaios:</span>
<span class="data-value">${p.Ensaios_Qualidade}</span>
</div>` : ''}
${p['Observações'] ? `
<div class="observations">
<div class="data-item">
<span class="data-label">Observações:</span>
<span class="data-value">${p['Observações']}</span>
</div>
</div>` : ''}
</div>
` : '<h2>Pintura Recomendada</h2><div class="data-group"><p>Dados de pintura não disponíveis para este aço/ambiente.</p></div>'}
<!-- Rodapé -->
<div style="margin-top: 30px; padding-top: 10px; border-top: 1px solid #ccc; text-align: center; font-size: 8pt; color: #666;">
<p>Relatório gerado automaticamente pelo SteelBase v7.5</p>
<p>Este relatório é baseado em dados técnicos da base de conhecimento</p>
</div>
</div>
</body>
</html>
`;
// Create a hidden iframe to print
const printFrame = document.createElement('iframe');
printFrame.style.position = 'fixed';
printFrame.style.right = '0';
printFrame.style.bottom = '0';
printFrame.style.width = '0';
printFrame.style.height = '0';
printFrame.style.border = '0';
document.body.appendChild(printFrame);
const doc = printFrame.contentWindow.document;
doc.open();
// Inserir logotipo se configurado
const cfg = window.adminConfigManager ? window.adminConfigManager.getConfig() : null;
let logoBlock = '';
if (cfg && cfg.branding && cfg.branding.logo) {
logoBlock = `<div style="text-align:center; margin-bottom: 8px;"><img src="${cfg.branding.logo}" alt="Logo" style="max-height:48px; object-fit:contain;"></div>`;
}
const htmlWithLogo = htmlContent.replace('<h1>Relatório de Recomendação Inteligente</h1>', `${logoBlock}<h1>Relatório de Recomendação Inteligente</h1>`);
doc.write(htmlWithLogo);
doc.close();
// Wait for content to load
await new Promise(resolve => setTimeout(resolve, 500));
// Trigger print dialog (user can save as PDF)
printFrame.contentWindow.print();
// Clean up
setTimeout(() => {
document.body.removeChild(printFrame);
}, 1000);
// Remove loading toast
loadingToast.remove();
// Show success message
const toast = document.createElement('div');
toast.textContent = '📄 Relatório pronto! Use "Salvar como PDF" na janela de impressão';
toast.style.cssText = `
position: fixed;
bottom: 24px;
right: 24px;
padding: 16px 24px;
background: var(--color-success);
color: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 10000;
font-size: 14px;
font-weight: 500;
`;
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 5000);
} catch (error) {
console.error('Erro ao gerar PDF:', error);
loadingToast.remove();
alert('❌ Erro ao gerar PDF. Verifique o console para mais detalhes.');
}
}
// Tab switching function
function switchTab(tabIndex) {
document.querySelectorAll('.tab-btn').forEach((btn, i) => {
btn.classList.toggle('active', i === tabIndex);
});
document.querySelectorAll('.tab-content').forEach((content, i) => {
content.classList.toggle('active', i === tabIndex);
});
// Update help button for the active tab (for parafusos section)
const tabIds = ['parafusos-cisalhamento', 'parafusos-esmagamento', 'parafusos-bloco', 'layout', 'parafuso-vs-solda'];
if (tabIds[tabIndex]) {
addHelpButton(tabIds[tabIndex]);
}
}
// Bolt database with capacities
const boltDatabase = {
a325: {fy: 400, fu: 635, capacidade: {12: 5.2, 16: 9.2, 20: 14.4, 24: 20.7}, custo: 8},
a490: {fy: 565, fu: 895, capacidade: {12: 7.3, 16: 13.0, 20: 20.3, 24: 29.2}, custo: 15},
iso88: {fy: 640, fu: 800, capacidade: {12: 6.1, 16: 10.8, 20: 16.8, 24: 24.2}, custo: 5},
iso109: {fy: 900, fu: 1000, capacidade: {12: 8.7, 16: 15.5, 20: 24.2, 24: 34.8}, custo: 20}
};
const steelBearing = {
a36: {fy: 250, fu: 400},
a572: {fy: 345, fu: 450},
s235: {fy: 235, fu: 360},
s355: {fy: 355, fu: 490}
};
// Tab 1: Cisalhamento (Shear)
function calcularCisalhamento() {
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);
const Fv = bolt.capacidade[d] * planes;
const capacity = Fv * qty;
const utilization = (force / capacity) * 100;
let alertClass = 'alert-success';
let status = '✅ ATENDE';
let recommendation = 'Capacidade adequada para a força aplicada';
if (utilization > 100) {
alertClass = 'alert-error';
status = '⚠️ NÃO ATENDE (Insuficiente)';
const qtyNeeded = Math.ceil(force / Fv);
recommendation = `Aumentar para ${qtyNeeded} parafusos ou usar tipo mais resistente`;
} else if (utilization > 85) {
alertClass = 'alert-warning';
status = '⚠️ ATENÇÃO (Utilização elevada)';
recommendation = 'Considere aumentar a quantidade de parafusos';
}
// Alternativas
let alternatives = '';
Object.keys(boltDatabase).forEach(type => {
if (type !== boltType) {
const altCap = boltDatabase[type].capacidade[d] * planes * qty;
const altUtil = (force / altCap) * 100;
if (altUtil < 100) {
alternatives += `<li>• ${qty} parafusos ${type.toUpperCase()}${altCap.toFixed(1)} kN ✅</li>`;
}
}
});
// Reference table
const refTable = `
<table style="width: 100%; margin-top: 20px; font-size: 12px;">
<thead>
<tr style="background: var(--color-primary); color: white;">
<th style="padding: 8px;">Tipo</th>
<th>Ø12</th>
<th>Ø16</th>
<th>Ø20</th>
<th>Ø24</th>
</tr>
</thead>
<tbody>
<tr><td><strong>A325</strong></td><td>5.2</td><td>9.2</td><td>14.4</td><td>20.7</td></tr>
<tr><td><strong>A490</strong></td><td>7.3</td><td>13.0</td><td>20.3</td><td>29.2</td></tr>
<tr><td><strong>ISO88</strong></td><td>6.1</td><td>10.8</td><td>16.8</td><td>24.2</td></tr>
<tr><td><strong>ISO109</strong></td><td>8.7</td><td>15.5</td><td>24.2</td><td>34.8</td></tr>
</tbody>
</table>
`;
document.getElementById('bolt-shear-result').innerHTML = `
<div class="result-box" style="background: var(--color-bg-1); border-left: 4px solid var(--color-primary);">
<div class="result-title">✅ CISALHAMENTO - RESULTADO</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Capacidade por Parafuso</div>
<div class="result-value">${Fv.toFixed(1)} kN</div>
</div>
<div class="result-item">
<div class="result-label">Capacidade Total (${qty}×${boltType.toUpperCase()})</div>
<div class="result-value">${capacity.toFixed(1)} kN</div>
</div>
<div class="result-item">
<div class="result-label">Força Aplicada</div>
<div class="result-value">${force.toFixed(1)} kN</div>
</div>
<div class="result-item">
<div class="result-label">Utilização</div>
<div class="result-value" style="color: ${utilization > 100 ? 'var(--color-error)' : utilization > 85 ? 'var(--color-warning)' : 'var(--color-success)'}">${utilization.toFixed(0)}%</div>
</div>
</div>
<div class="alert ${alertClass}" style="margin-top: 16px;">
<strong>STATUS: ${status}</strong><br>
Recomendação: ${recommendation}
</div>
${alternatives ? `
<div style="margin-top: 16px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>Alternativas Sugeridas:</strong>
<ul style="margin: 8px 0 0 20px;">${alternatives}</ul>
</div>
` : ''}
<div style="margin-top: 20px;">
<strong>Tabela de Referência (kN por parafuso, plano simples):</strong>
${refTable}
</div>
</div>
`;
addToHistory('Cisalhamento', `${qty} parafusos Ø${d}mm ${boltType.toUpperCase()}, Util: ${utilization.toFixed(0)}%`);
}
// Tab 2: Esmagamento (Bearing)
function calcularEsmagamento() {
const d = parseFloat(document.getElementById('bear-d').value);
const thickness = parseFloat(document.getElementById('bear-thickness').value);
const qty = parseInt(document.getElementById('bear-qty').value);
const steelType = document.getElementById('bear-steel').value;
const edge = parseFloat(document.getElementById('bear-edge').value);
const spacing = parseFloat(document.getElementById('bear-spacing').value);
const steel = steelBearing[steelType];
const fu = steel.fu;
// Location factor
let factor = 1.0;
if (edge < 1.5 * d) {
factor = 0.7;
}
// Bearing capacity
const Abc = d * thickness;
const Fb = 1.2 * fu * d * thickness * factor / 1000;
const FbTotal = Fb * qty;
// Compare with shear (assuming A325 Ø16)
const shearCap = 9.2 * 2 * qty;
const critical = FbTotal < shearCap ? 'ESMAGAMENTO' : 'CISALHAMENTO';
let status = '✅ OK';
let alertClass = 'alert-success';
let recommendation = 'Capacidade de esmagamento adequada';
if (factor < 1.0) {
alertClass = 'alert-warning';
status = '⚠️ ATENÇÃO';
recommendation = 'Distância de borda reduzida (fator 0.7 aplicado)';
}
document.getElementById('bolt-bearing-result').innerHTML = `
<div class="result-box" style="background: var(--color-bg-3); border-left: 4px solid #16a34a;">
<div class="result-title">✅ ESMAGAMENTO - RESULTADO</div>
<div style="margin-bottom: 20px;">
<p><strong>Espessura da Chapa:</strong> ${thickness} mm</p>
<p><strong>Diâmetro Parafuso:</strong> ${d} mm</p>
<p><strong>Aço da Chapa:</strong> ${steelType.toUpperCase()} (fu=${fu} MPa)</p>
</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Área de Contato</div>
<div class="result-value">${Abc.toFixed(0)} mm²</div>
</div>
<div class="result-item">
<div class="result-label">Fator Localização</div>
<div class="result-value">${factor.toFixed(1)} ${factor === 1.0 ? '✓' : '⚠️'}</div>
</div>
<div class="result-item">
<div class="result-label">Capacidade por Parafuso</div>
<div class="result-value">${Fb.toFixed(1)} kN</div>
</div>
<div class="result-item">
<div class="result-label">Capacidade Total (${qty} un)</div>
<div class="result-value">${FbTotal.toFixed(1)} kN</div>
</div>
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>Verificação contra Cisalhamento:</strong><br>
Cisalhamento: ${shearCap.toFixed(1)} kN<br>
Esmagamento: ${FbTotal.toFixed(1)} kN<br>
<strong style="color: var(--color-warning);">CONTROLA O ${critical}</strong>
</div>
<div class="alert ${alertClass}" style="margin-top: 16px;">
<strong>STATUS: ${status}</strong><br>
${recommendation}
</div>
</div>
`;
addToHistory('Esmagamento', `Ø${d}mm, esp=${thickness}mm, Cap=${FbTotal.toFixed(1)}kN`);
}
// Tab 3: Ruptura em Bloco
function calcularBlocoRuptura() {
const d = parseFloat(document.getElementById('block-d').value);
const hQty = parseInt(document.getElementById('block-h-qty').value);
const vQty = parseInt(document.getElementById('block-v-qty').value);
const hSpace = parseFloat(document.getElementById('block-h-space').value);
const edgeLeft = parseFloat(document.getElementById('block-edge-left').value);
const edgeTop = parseFloat(document.getElementById('block-edge-top').value);
const edgeRight = parseFloat(document.getElementById('block-edge-right').value);
const thickness = parseFloat(document.getElementById('block-thickness').value);
const steelType = document.getElementById('block-steel').value;
const force = parseFloat(document.getElementById('block-force').value);
const steel = steelBearing[steelType];
const fu = steel.fu;
const dHole = d + 2;
// Net tension area
const Ant = (edgeLeft + edgeRight) * thickness - (1 * dHole * thickness);
// Net shear area (vertical length)
const vertLength = (vQty - 1) * hSpace;
const Agv = vertLength * thickness - ((vQty - 1) * dHole * thickness);
// Block shear capacity (AISC 360-16)
const Rbs = (0.6 * fu * Agv + 0.3 * fu * Ant) / 1000;
const utilization = (force / Rbs) * 100;
let status = '✅ ATENDE';
let alertClass = 'alert-success';
let recommendation = 'Resistência ao bloco adequada';
if (utilization > 100) {
alertClass = 'alert-error';
status = '⚠️ NÃO ATENDE';
recommendation = 'Aumentar distância de borda ou espessura da chapa';
} else if (utilization > 85) {
alertClass = 'alert-warning';
status = '⚠️ ATENÇÃO';
recommendation = 'Utilização elevada, considere reforço';
}
document.getElementById('bolt-block-result').innerHTML = `
<div class="result-box" style="background: var(--color-bg-6); border-left: 4px solid var(--color-warning);">
<div class="result-title">✅ RUPTURA EM BLOCO - RESULTADO</div>
<div style="margin-bottom: 20px;">
<p><strong>Área Líquida Tração (Ant):</strong> ${Ant.toFixed(0)} mm²</p>
<p><strong>Área Líquida Cisalhamento (Agv):</strong> ${Agv.toFixed(0)} mm²</p>
</div>
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; margin-bottom: 16px;">
<strong>Resistência Ruptura (AISC 360-16):</strong><br>
Rbs = 0.6×fu×Agv + 0.3×fu×Ant<br>
Rbs = 0.6×${fu}×${Agv.toFixed(0)} + 0.3×${fu}×${Ant.toFixed(0)}<br>
Rbs = ${(0.6 * fu * Agv / 1000).toFixed(1)} + ${(0.3 * fu * Ant / 1000).toFixed(1)} = <strong>${Rbs.toFixed(1)} kN</strong>
</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Resistência Bloco</div>
<div class="result-value">${Rbs.toFixed(1)} kN</div>
</div>
<div class="result-item">
<div class="result-label">Força Aplicada</div>
<div class="result-value">${force.toFixed(1)} kN</div>
</div>
<div class="result-item">
<div class="result-label">Utilização</div>
<div class="result-value" style="color: ${utilization > 100 ? 'var(--color-error)' : utilization > 85 ? 'var(--color-warning)' : 'var(--color-success)'}">${utilization.toFixed(0)}%</div>
</div>
</div>
<div class="alert ${alertClass}" style="margin-top: 16px;">
<strong>STATUS: ${status}</strong><br>
${recommendation}
</div>
</div>
`;
addToHistory('Bloco Ruptura', `Rbs=${Rbs.toFixed(1)}kN, Util=${utilization.toFixed(0)}%`);
}
// Tab 4: Layout de Furação Completo
function verificarLayoutCompleto() {
const d = parseFloat(document.getElementById('layout2-d').value);
const edgeLeft = parseFloat(document.getElementById('layout2-edge-left').value);
const edgeRight = parseFloat(document.getElementById('layout2-edge-right').value);
const edgeTop = parseFloat(document.getElementById('layout2-edge-top').value);
const edgeBottom = parseFloat(document.getElementById('layout2-edge-bottom').value);
const hSpace = parseFloat(document.getElementById('layout2-h-space').value);
const vSpace = parseFloat(document.getElementById('layout2-v-space').value);
const thickness = parseFloat(document.getElementById('layout2-thickness').value);
// NBR 8800 limits
const minEdge = 1.5 * d;
const maxEdge = Math.min(12 * thickness, 150);
const minSpacing = 2.67 * d;
const maxSpacing = 300;
// Check each parameter
const checks = [
{name: 'Esquerda', value: edgeLeft, min: minEdge, max: maxEdge},
{name: 'Direita', value: edgeRight, min: minEdge, max: maxEdge},
{name: 'Topo', value: edgeTop, min: minEdge, max: maxEdge},
{name: 'Base', value: edgeBottom, min: minEdge, max: maxEdge},
{name: 'Horizontal', value: hSpace, min: minSpacing, max: maxSpacing, isSpacing: true},
{name: 'Vertical', value: vSpace, min: minSpacing, max: maxSpacing, isSpacing: true}
];
let allConform = true;
let checksList = '';
checks.forEach(check => {
let status = '✅ CONFORME';
let statusClass = 'color: var(--color-success);';
let detail = `(mín ${check.min.toFixed(1)}mm)`;
if (check.value < check.min) {
status = '❌ ABAIXO DO MÍNIMO';
statusClass = 'color: var(--color-error);';
detail = `(mín ${check.min.toFixed(1)}mm)`;
allConform = false;
} else if (check.value > check.max) {
status = '⚠️ ACIMA DO MÁXIMO';
statusClass = 'color: var(--color-warning);';
detail = `(máx ${check.max.toFixed(0)}mm)`;
allConform = false;
} else if (!check.isSpacing) {
detail = `(${check.min.toFixed(1)}-${check.max.toFixed(0)}mm)`;
} else {
detail = `(${check.min.toFixed(1)}-${check.max}mm)`;
}
checksList += `
<tr style="border-bottom: 1px solid var(--color-border);">
<td style="padding: 10px;"><strong>${check.name}</strong></td>
<td style="padding: 10px;">${check.value} mm</td>
<td style="padding: 10px; ${statusClass}">${status}</td>
<td style="padding: 10px; color: var(--color-text-secondary);">${detail}</td>
</tr>
`;
});
// Simple layout drawing
const drawing = `
<div style="margin-top: 20px; padding: 20px; background: var(--color-surface); border-radius: 12px; font-family: monospace;">
<div style="text-align: center; margin-bottom: 16px;"><strong>DESENHO DE LAYOUT</strong></div>
<pre style="background: var(--color-background); padding: 16px; border-radius: 8px; overflow-x: auto;">
┌───────────────────────┐
${edgeTop} ${edgeTop} ${edgeTop}
│ ●─────●─────● │ ${edgeRight}
│ │ ${hSpace}${hSpace} │ │
│ ●─────●─────● │ ${vSpace}
│ │ │ │ │
│ ●─────●─────● │ ${vSpace}
${edgeLeft} ${edgeLeft} ${edgeLeft}
└───────────────────────┘
${edgeBottom} ${edgeBottom} ${edgeBottom}
</pre>
</div>
`;
document.getElementById('layout-full-result').innerHTML = `
<div class="result-box" style="background: var(--color-bg-5); border-left: 4px solid #a855f7;">
<div class="result-title">✅ LAYOUT DE FURAÇÃO - VERIFICAÇÃO</div>
<div style="margin-bottom: 20px;">
<p><strong>Diâmetro do Parafuso:</strong> ${d} mm</p>
<p><strong>Espessura da Chapa:</strong> ${thickness} mm</p>
</div>
<table style="width: 100%; border-collapse: collapse;">
<thead>
<tr style="background: var(--color-primary); color: white;">
<th style="padding: 10px; text-align: left;">Parâmetro</th>
<th style="padding: 10px; text-align: left;">Valor</th>
<th style="padding: 10px; text-align: left;">Status</th>
<th style="padding: 10px; text-align: left;">Limites NBR 8800</th>
</tr>
</thead>
<tbody>
${checksList}
</tbody>
</table>
<div class="alert ${allConform ? 'alert-success' : 'alert-error'}" style="margin-top: 20px;">
<strong>${allConform ? '✅ 100% CONFORME COM NBR 8800' : '⚠️ AJUSTES NECESSÁRIOS'}</strong><br>
${allConform ? 'Todos os parâmetros estão dentro dos limites normativos' : 'Alguns parâmetros precisam ser ajustados'}
</div>
${drawing}
</div>
`;
addToHistory('Layout Furação', `Ø${d}mm, ${allConform ? 'CONFORME' : 'NÃO CONFORME'}`);
}
function verificarLayout() {
const d = parseFloat(document.getElementById('layout-d').value) || 20;
const edge = parseFloat(document.getElementById('layout-edge').value) || 0;
const spacing = parseFloat(document.getElementById('layout-spacing').value) || 0;
const minEdge = 1.5 * d;
const maxEdge = 12 * 10;
const minSpacing = 2.67 * d;
const maxSpacing = 300;
let edgeStatus = '✅ Conforme';
let edgeClass = 'alert-success';
if (edge < minEdge) {
edgeStatus = `❌ Abaixo do mínimo (${minEdge.toFixed(1)}mm)`;
edgeClass = 'alert-error';
} else if (edge > maxEdge) {
edgeStatus = `⚠️ Acima do máximo (${maxEdge}mm)`;
edgeClass = 'alert-warning';
}
let spacingStatus = '✅ Conforme';
let spacingClass = 'alert-success';
if (spacing < minSpacing) {
spacingStatus = `❌ Abaixo do mínimo (${minSpacing.toFixed(1)}mm)`;
spacingClass = 'alert-error';
} else if (spacing > maxSpacing) {
spacingStatus = `⚠️ Acima do máximo (${maxSpacing}mm)`;
spacingClass = 'alert-warning';
}
document.getElementById('layout-result').innerHTML = `
<div class="card">
<div class="card-title">Verificação NBR 8800</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Dist. Borda Mín</div>
<div class="result-value" style="font-size: 18px;">${minEdge.toFixed(1)} mm</div>
</div>
<div class="result-item">
<div class="result-label">Dist. Borda Máx</div>
<div class="result-value" style="font-size: 18px;">${maxEdge} mm</div>
</div>
<div class="result-item">
<div class="result-label">Espaç. Mínimo</div>
<div class="result-value" style="font-size: 18px;">${minSpacing.toFixed(1)} mm</div>
</div>
<div class="result-item">
<div class="result-label">Espaç. Máximo</div>
<div class="result-value" style="font-size: 18px;">${maxSpacing} mm</div>
</div>
</div>
<div class="alert ${edgeClass}" style="margin-top: 16px;">
<strong>Distância de Borda: ${edgeStatus}</strong>
</div>
<div class="alert ${spacingClass}">
<strong>Espaçamento: ${spacingStatus}</strong>
</div>
</div>
`;
addToHistory('Layout de Furação', `Ø${d}mm, Borda: ${edge}mm, Espaç: ${spacing}mm`);
}
// Tab 5: Parafuso vs Solda Completo
function compararParafusoSoldaCompleto() {
const force = parseFloat(document.getElementById('comp2-force').value);
const length = parseFloat(document.getElementById('comp2-length').value);
const steelType = document.getElementById('comp2-steel').value;
const boltType = document.getElementById('comp2-bolt-type').value;
const boltD = parseFloat(document.getElementById('comp2-bolt-d').value);
const steel = steelBearing[steelType];
const bolt = boltDatabase[boltType];
// BOLT SOLUTION
const boltCapacity = bolt.capacidade[boltD] * 2; // 2 planes
const boltQty = Math.ceil(force / boltCapacity);
const boltTotalCap = boltCapacity * boltQty;
const boltMaterialCost = boltQty * bolt.custo;
const boltTimeMin = boltQty * 5;
const boltLaborCost = (boltTimeMin / 60) * 30;
const boltTotalCost = boltMaterialCost + boltLaborCost;
// WELD SOLUTION
const fyWeld = steel.fy * 0.6;
const weldLeg = (force * 1000) / (0.707 * length * 0.65 * fyWeld);
const weldLegRounded = Math.max(Math.ceil(weldLeg), 5);
const weldVolume = (weldLegRounded * weldLegRounded * 0.5 * length) / 1000; // cm³
const weldMass = (weldVolume / 1000) * 7.85; // kg
const electrodeKg = weldMass * 1.15 * 1.15; // losses
const electrodeCost = electrodeKg * 45;
const weldTimeMin = (length / 1000) * 30; // ~30 min per meter
const weldLaborCost = (weldTimeMin / 60) * 60;
const weldTotalCost = electrodeCost + weldLaborCost;
const weldCapacity = (0.707 * weldLegRounded * length * 0.65 * fyWeld) / 1000;
// Comparison
const cheaper = boltTotalCost < weldTotalCost ? 'PARAFUSO' : 'SOLDA';
const savings = Math.abs(boltTotalCost - weldTotalCost);
const timeSaved = Math.abs(boltTimeMin - weldTimeMin);
// Chart data
setTimeout(() => {
if (currentChart) currentChart.destroy();
const ctx = document.getElementById('comparison-chart').getContext('2d');
currentChart = new Chart(ctx, {
type: 'scatter',
data: {
datasets: [
{
label: 'Parafuso',
data: [{x: boltTimeMin, y: boltTotalCost}],
backgroundColor: '#16a34a',
pointRadius: 10,
pointHoverRadius: 12
},
{
label: 'Solda',
data: [{x: weldTimeMin, y: weldTotalCost}],
backgroundColor: '#ea580c',
pointRadius: 10,
pointHoverRadius: 12
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: 'Custo vs Tempo de Instalação'
},
legend: {
display: true,
position: 'top'
}
},
scales: {
x: {
title: {
display: true,
text: 'Tempo (minutos)'
}
},
y: {
title: {
display: true,
text: 'Custo (R$)'
}
}
}
}
});
}, 100);
document.getElementById('comparison-full-result').innerHTML = `
<div class="result-box" style="background: var(--color-bg-4); border-left: 4px solid var(--color-error);">
<div class="result-title">⚖️ COMPARAÇÃO: PARAFUSO vs SOLDA</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 20px 0;">
<div style="padding: 20px; background: var(--color-bg-1); border-radius: 12px; border: 2px solid var(--color-success);">
<h3 style="color: var(--color-success); margin-bottom: 16px;">🔩 PARAFUSO</h3>
<table style="width: 100%; font-size: 14px;">
<tr><td><strong>Tipo:</strong></td><td>${boltType.toUpperCase()} Ø${boltD}mm</td></tr>
<tr><td><strong>Quantidade:</strong></td><td>${boltQty} un</td></tr>
<tr><td><strong>Capacidade:</strong></td><td>${boltTotalCap.toFixed(1)} kN</td></tr>
<tr style="height: 10px;"></tr>
<tr style="background: var(--color-surface);"><td><strong>Custo Material:</strong></td><td>R$ ${boltMaterialCost.toFixed(2)}</td></tr>
<tr style="background: var(--color-surface);"><td><strong>Custo Mão de Obra:</strong></td><td>R$ ${boltLaborCost.toFixed(2)}</td></tr>
<tr><td><strong>Tempo Instalação:</strong></td><td>${boltTimeMin} min</td></tr>
<tr style="height: 10px;"></tr>
<tr style="background: var(--color-success); color: white;"><td><strong>CUSTO TOTAL:</strong></td><td><strong>R$ ${boltTotalCost.toFixed(2)}</strong></td></tr>
</table>
<div style="margin-top: 16px; padding: 12px; background: var(--color-surface); border-radius: 8px;">
<strong>Vantagens:</strong><br>
✅ Mais rápido<br>
✅ Reversível<br>
✅ Inspeção visual simples
</div>
</div>
<div style="padding: 20px; background: var(--color-bg-6); border-radius: 12px; border: 2px solid var(--color-warning);">
<h3 style="color: var(--color-warning); margin-bottom: 16px;">🔥 SOLDA</h3>
<table style="width: 100%; font-size: 14px;">
<tr><td><strong>Tipo:</strong></td><td>Filete</td></tr>
<tr><td><strong>Perna:</strong></td><td>${weldLegRounded} mm</td></tr>
<tr><td><strong>Comprimento:</strong></td><td>${length} mm</td></tr>
<tr style="height: 10px;"></tr>
<tr style="background: var(--color-surface);"><td><strong>Custo Material:</strong></td><td>R$ ${electrodeCost.toFixed(2)}</td></tr>
<tr style="background: var(--color-surface);"><td><strong>Custo Mão de Obra:</strong></td><td>R$ ${weldLaborCost.toFixed(2)}</td></tr>
<tr><td><strong>Tempo Soldagem:</strong></td><td>${Math.round(weldTimeMin)} min</td></tr>
<tr style="height: 10px;"></tr>
<tr style="background: var(--color-warning); color: white;"><td><strong>CUSTO TOTAL:</strong></td><td><strong>R$ ${weldTotalCost.toFixed(2)}</strong></td></tr>
</table>
<div style="margin-top: 16px; padding: 12px; background: var(--color-surface); border-radius: 8px;">
<strong>Vantagens:</strong><br>
✅ Maior rigidez<br>
✅ Melhor aparência<br>
✅ Distribuição de tensões
</div>
</div>
</div>
<div class="alert alert-success" style="margin-top: 20px;">
<strong>⭐ RECOMENDAÇÃO: ${cheaper}</strong><br>
Economia de R$ ${savings.toFixed(2)} | ${Math.abs(timeSaved).toFixed(0)} min ${boltTimeMin < weldTimeMin ? 'mais rápido' : 'mais lento'}
</div>
<div style="margin-top: 20px;">
<strong>📊 Gráfico Comparativo:</strong>
<div class="chart-container" style="height: 300px; margin-top: 10px;">
<canvas id="comparison-chart"></canvas>
</div>
</div>
</div>
`;
addToHistory('Parafuso vs Solda', `${cheaper} mais econômico (R$${savings.toFixed(2)})`);
// Add button to send recommended option to budget
const resultDiv = document.getElementById('comparison-full-result');
const existingButton = resultDiv.querySelector('.add-to-budget-btn');
if (!existingButton && cheaper === 'PARAFUSO') {
const button = document.createElement('button');
button.className = 'btn btn-success add-to-budget-btn';
button.style.marginTop = '16px';
button.textContent = '💰 Adicionar Parafusos ao Orçamento';
button.onclick = () => addBoltsToOrcamento(boltQty, boltType, boltD);
resultDiv.querySelector('.result-box').appendChild(button);
}
}
function addBoltsToOrcamento(qty, type, diameter) {
showSection('orcamento');
setTimeout(() => {
document.getElementById('budget-category').value = 'consumivel';
updateBudgetTypeOptions();
setTimeout(() => {
document.getElementById('budget-type').value = 'parafusos';
updateBudgetSpecOptions();
setTimeout(() => {
document.getElementById('budget-qty').value = qty;
updateBudgetTotal();
alert(`✅ Parafusos transferidos!\n\n${qty} parafusos ${type.toUpperCase()} M${diameter}\n\nSelecione na lista e adicione.`);
}, 200);
}, 200);
}, 300);
}
function compararParafusoSolda() {
const force = parseFloat(document.getElementById('comp-force').value) || 0;
const length = parseFloat(document.getElementById('comp-length').value) || 0;
const fy = parseFloat(document.getElementById('comp-fy').value) || 345;
const boltCapacity = 60;
const boltQty = Math.ceil(force / boltCapacity);
const boltCost = boltQty * 15;
const fyWeld = fy * 0.6;
const weldLeg = (force * 1000) / (0.707 * length * 0.65 * fyWeld);
const weldLegRounded = Math.ceil(weldLeg);
const weldCost = (weldLegRounded * length / 1000) * 25;
document.getElementById('comparison-result').innerHTML = `
<div class="card">
<div class="card-title">Comparação de Soluções</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
<div style="background: var(--color-bg-1); padding: 20px; border-radius: 12px;">
<h3 style="color: var(--color-primary); margin-bottom: 16px;">🔩 Solução Parafusada</h3>
<p><strong>Tipo:</strong> A325 Ø20mm</p>
<p><strong>Quantidade:</strong> ${boltQty} parafusos</p>
<p><strong>Capacidade:</strong> ${(boltQty * boltCapacity).toFixed(1)} kN</p>
<p><strong>Custo estimado:</strong> R$ ${boltCost.toFixed(2)}</p>
<p><strong>Vantagens:</strong> Desmontável, inspeção visual</p>
<p><strong>Desvantagens:</strong> Maior tempo de instalação</p>
</div>
<div style="background: var(--color-bg-2); padding: 20px; border-radius: 12px;">
<h3 style="color: var(--color-warning); margin-bottom: 16px;">🔥 Solução Soldada</h3>
<p><strong>Tipo:</strong> Solda de filete</p>
<p><strong>Perna:</strong> ${weldLegRounded} mm</p>
<p><strong>Comprimento:</strong> ${length} mm</p>
<p><strong>Custo estimado:</strong> R$ ${weldCost.toFixed(2)}</p>
<p><strong>Vantagens:</strong> Melhor rigidez, econômica</p>
<p><strong>Desvantagens:</strong> Permanente, requer qualificação</p>
</div>
</div>
<div class="alert alert-success" style="margin-top: 20px;">
<strong>Recomendação:</strong> ${weldCost < boltCost ? 'Solda de filete é mais econômica' : 'Parafusos mais econômicos'}
</div>
</div>
`;
addToHistory('Parafuso vs Solda', `${boltQty} parafusos vs solda ${weldLegRounded}mm`);
}
// ========================================
// WELDING PROCESS TO CONSUMABLES MAPPING
// ========================================
const processoConsumiveisMap = {
smaw: {
nome: 'SMAW (Eletrodo Revestido)',
consumiveis: ['e7018', 'e6013', 'e8018', 'e7016', 'e8016'],
defaultConsumivel: 'e7018'
},
gmaw: {
nome: 'GMAW (MIG/MAG)',
consumiveis: ['er70s2', 'er70s6'],
defaultConsumivel: 'er70s6'
},
fcaw: {
nome: 'FCAW (Arame Tubular)',
consumiveis: ['er70s2', 'er70s6'],
defaultConsumivel: 'er70s6'
},
gtaw: {
nome: 'GTAW (TIG)',
consumiveis: ['er70s2', 'er70s6', 'er4043', 'er5356'],
defaultConsumivel: 'er70s2'
},
saw: {
nome: 'SAW (Soldagem Submersa)',
consumiveis: ['er70s2', 'er70s6'],
defaultConsumivel: 'er70s6'
},
esw: {
nome: 'ESW (Soldagem por Escória)',
consumiveis: ['er70s2', 'er70s6'],
defaultConsumivel: 'er70s6'
}
};
// ========================================
// WELDING DATABASE
// ========================================
const weldingElectrodes = {
e7018: {
nome: 'E7018',
tipo: 'Básico',
processo: 'SMAW',
resistencia_tracao_min: 485,
resistencia_tracao_max: 620,
limite_escoamento: 345,
alongamento: 17,
charpy: 47,
posicoes: 'Todas (1F, 2F, 3F, 4F)',
corrente_min: 100,
corrente_max: 180,
voltagem_min: 24,
voltagem_max: 28,
rendimento: 0.68,
taxa_deposicao: 3.5,
custo_kg: 45,
diametros: [2.0, 2.4, 3.2, 4.0]
},
e6013: {
nome: 'E6013',
tipo: 'Rutílico',
processo: 'SMAW',
resistencia_tracao_min: 420,
resistencia_tracao_max: 550,
limite_escoamento: 300,
alongamento: 22,
charpy: 27,
posicoes: 'Todas',
corrente_min: 70,
corrente_max: 140,
voltagem_min: 22,
voltagem_max: 26,
rendimento: 0.62,
taxa_deposicao: 2.8,
custo_kg: 28,
diametros: [2.0, 2.4, 3.2, 4.0]
},
e8018: {
nome: 'E8018',
tipo: 'Básico Alta Resistência',
processo: 'SMAW',
resistencia_tracao_min: 550,
resistencia_tracao_max: 680,
limite_escoamento: 450,
alongamento: 15,
charpy: 68,
posicoes: 'Todas',
corrente_min: 120,
corrente_max: 200,
voltagem_min: 26,
voltagem_max: 30,
rendimento: 0.72,
taxa_deposicao: 4.2,
custo_kg: 65,
diametros: [2.4, 3.2, 4.0, 5.0]
},
e7016: {
nome: 'E7016',
tipo: 'Básico',
processo: 'SMAW',
resistencia_tracao_min: 485,
resistencia_tracao_max: 620,
limite_escoamento: 345,
alongamento: 17,
charpy: 47,
posicoes: 'Todas',
corrente_min: 90,
corrente_max: 170,
voltagem_min: 24,
voltagem_max: 28,
rendimento: 0.65,
taxa_deposicao: 3.2,
custo_kg: 38,
diametros: [2.0, 2.4, 3.2, 4.0]
},
e8016: {
nome: 'E8016',
tipo: 'Básico',
processo: 'SMAW',
resistencia_tracao_min: 550,
resistencia_tracao_max: 680,
limite_escoamento: 450,
alongamento: 15,
charpy: 54,
posicoes: 'Todas',
corrente_min: 110,
corrente_max: 190,
voltagem_min: 26,
voltagem_max: 30,
rendimento: 0.68,
taxa_deposicao: 3.8,
custo_kg: 58,
diametros: [2.4, 3.2, 4.0, 5.0]
},
er70s2: {
nome: 'ER70S-2',
tipo: 'MIG',
processo: 'GMAW',
resistencia_tracao_min: 490,
resistencia_tracao_max: 550,
limite_escoamento: 400,
alongamento: 22,
charpy: 27,
posicoes: 'Todas',
corrente_min: 150,
corrente_max: 250,
voltagem_min: 22,
voltagem_max: 28,
rendimento: 0.88,
taxa_deposicao: 5.5,
custo_kg: 35,
diametros: [0.8, 1.0, 1.2, 1.6]
},
er70s6: {
nome: 'ER70S-6',
tipo: 'MIG',
processo: 'GMAW',
resistencia_tracao_min: 490,
resistencia_tracao_max: 550,
limite_escoamento: 400,
alongamento: 22,
charpy: 27,
posicoes: 'Todas',
corrente_min: 150,
corrente_max: 250,
voltagem_min: 22,
voltagem_max: 28,
rendimento: 0.90,
taxa_deposicao: 6.0,
custo_kg: 32,
diametros: [0.8, 1.0, 1.2, 1.6]
},
er4043: {
nome: 'ER4043',
tipo: 'TIG - Alumínio',
processo: 'GTAW',
resistencia_tracao_min: 145,
resistencia_tracao_max: 185,
limite_escoamento: 70,
alongamento: 10,
charpy: 0,
posicoes: 'Todas',
corrente_min: 80,
corrente_max: 180,
voltagem_min: 10,
voltagem_max: 15,
rendimento: 0.95,
taxa_deposicao: 1.8,
custo_kg: 120,
diametros: [1.6, 2.0, 2.4, 3.2]
},
er5356: {
nome: 'ER5356',
tipo: 'TIG - Alumínio',
processo: 'GTAW',
resistencia_tracao_min: 290,
resistencia_tracao_max: 345,
limite_escoamento: 150,
alongamento: 12,
charpy: 0,
posicoes: 'Todas',
corrente_min: 90,
corrente_max: 200,
voltagem_min: 10,
voltagem_max: 15,
rendimento: 0.92,
taxa_deposicao: 2.2,
custo_kg: 135,
diametros: [1.6, 2.0, 2.4, 3.2]
}
};
const weldingProcesses = {
smaw: { nome: 'SMAW (Eletrodo Revestido)', ajuste_temp: 20 },
gmaw: { nome: 'GMAW (MIG/MAG)', ajuste_temp: 10 },
fcaw: { nome: 'FCAW (Arame Tubular)', ajuste_temp: 15 },
gtaw: { nome: 'GTAW (TIG)', ajuste_temp: 0 },
saw: { nome: 'SAW (Soldagem Submersa)', ajuste_temp: 25 },
esw: { nome: 'ESW (Soldagem por Escória)', ajuste_temp: 30 }
};
let currentWeldProcess = 'smaw';
let currentWeldElectrode = 'e7018';
// ========================================
// WELDING FUNCTIONS
// ========================================
function updateWeldingProcess() {
currentWeldProcess = document.getElementById('weld-process').value;
updateElectrodeOptions();
// Auto-update all tabs display after process change
const processName = weldingProcesses[currentWeldProcess]?.nome || 'SMAW';
const electrodeName = weldingElectrodes[currentWeldElectrode]?.nome || 'E7018';
const display = `${processName} (${electrodeName})`;
document.getElementById('preheat-process-display').textContent = display;
document.getElementById('filete-process-display').textContent = display;
document.getElementById('hi-process-display').textContent = display;
document.getElementById('consumo-electrode-display').textContent = electrodeName;
}
function updateWeldingElectrode() {
currentWeldElectrode = document.getElementById('weld-electrode').value;
}
function updateElectrodeOptions() {
const select = document.getElementById('weld-electrode');
const process = currentWeldProcess;
// Get valid consumables for this process
const processData = processoConsumiveisMap[process];
if (!processData) {
select.innerHTML = '<option value="e7018">E7018 (Padrão)</option>';
currentWeldElectrode = 'e7018';
return;
}
// Build options only with valid consumables
let options = '';
processData.consumiveis.forEach(consumivelId => {
const elec = weldingElectrodes[consumivelId];
if (elec) {
options += `<option value="${consumivelId}">${elec.nome} - ${elec.tipo}</option>`;
}
});
select.innerHTML = options || '<option value="e7018">E7018 (Padrão)</option>';
// Set default consumable for this process
select.value = processData.defaultConsumivel;
currentWeldElectrode = select.value;
// Update electrode display in consumption tab
const electrodeName = weldingElectrodes[currentWeldElectrode]?.nome || 'E7018';
document.getElementById('consumo-electrode-display').textContent = electrodeName;
}
function applyToAllTabs() {
const processName = weldingProcesses[currentWeldProcess]?.nome || 'SMAW';
const electrodeName = weldingElectrodes[currentWeldElectrode]?.nome || 'E7018';
const display = `${processName} (${electrodeName})`;
document.getElementById('preheat-process-display').textContent = display;
document.getElementById('filete-process-display').textContent = display;
document.getElementById('hi-process-display').textContent = display;
document.getElementById('consumo-electrode-display').textContent = electrodeName;
alert(`✅ Processo e consumível atualizados em todas as abas!\n\n${display}`);
}
function showElectrodeProperties() {
const elec = weldingElectrodes[currentWeldElectrode];
if (!elec) return;
const html = `
<div class="card" style="background: var(--color-bg-3); margin-top: 20px;">
<div class="card-title">📋 Propriedades do ${elec.nome}</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Resistência Tração</div>
<div class="result-value" style="font-size: 18px;">${elec.resistencia_tracao_min}-${elec.resistencia_tracao_max} MPa</div>
</div>
<div class="result-item">
<div class="result-label">Limite Escoamento</div>
<div class="result-value" style="font-size: 18px;">≥ ${elec.limite_escoamento} MPa</div>
</div>
<div class="result-item">
<div class="result-label">Alongamento</div>
<div class="result-value" style="font-size: 18px;">≥ ${elec.alongamento}%</div>
</div>
<div class="result-item">
<div class="result-label">Charpy (-20°C)</div>
<div class="result-value" style="font-size: 18px;">${elec.charpy > 0 ? '≥ ' + elec.charpy + ' J' : 'N/A'}</div>
</div>
<div class="result-item">
<div class="result-label">Corrente Recomendada</div>
<div class="result-value" style="font-size: 18px;">${elec.corrente_min}-${elec.corrente_max} A</div>
</div>
<div class="result-item">
<div class="result-label">Voltagem</div>
<div class="result-value" style="font-size: 18px;">${elec.voltagem_min}-${elec.voltagem_max} V</div>
</div>
<div class="result-item">
<div class="result-label">Rendimento de Deposição</div>
<div class="result-value" style="font-size: 18px;">${(elec.rendimento * 100).toFixed(0)}%</div>
</div>
<div class="result-item">
<div class="result-label">Custo</div>
<div class="result-value" style="font-size: 18px;">R$ ${elec.custo_kg}/kg</div>
</div>
</div>
<div style="margin-top: 16px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<p><strong>Tipo de Revestimento:</strong> ${elec.tipo}</p>
<p><strong>Posição Soldagem:</strong> ${elec.posicoes}</p>
<p><strong>Taxa de Deposição:</strong> ${elec.taxa_deposicao} kg/h</p>
<p><strong>Diâmetros Comerciais:</strong> ${elec.diametros.join(', ')} mm</p>
</div>
</div>
`;
document.getElementById('electrode-properties').innerHTML = html;
}
function switchWeldTab(index) {
document.querySelectorAll('.tabs-nav .tab-btn').forEach((btn, i) => {
if (btn.textContent.includes('Pré-Aquecimento') || btn.textContent.includes('Filete') ||
btn.textContent.includes('Energia') || btn.textContent.includes('Consumo') ||
btn.textContent.includes('Sequência') || btn.textContent.includes('Padrões')) {
btn.classList.toggle('active', i === index);
}
});
for (let i = 0; i < 6; i++) {
const tab = document.getElementById(`weld-tab-${i}`);
if (tab) {
tab.classList.toggle('active', i === index);
}
}
// Update help button for the active tab
const tabIds = ['preaquecimento', 'filete', 'energia', 'consumo-eletrodo', 'sequencia-soldagem', 'padroes-soldagem'];
addHelpButton(tabIds[index]);
}
function calcularPreaquecimentoCompleto() {
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 restraint = parseFloat(document.getElementById('preheat-restraint').value) || 1.0;
const calcInterpass = document.getElementById('preheat-interpass').checked;
const processAdjust = weldingProcesses[currentWeldProcess]?.ajuste_temp || 0;
// AWS D1.1 Formula
const cevFactor = cev * 50;
const thicknessFactor = (thickness / 10) * 20;
const ambientFactor = (20 - ambient) / 2;
let preheatTemp = 50 + cevFactor + thicknessFactor + ambientFactor + processAdjust;
preheatTemp = preheatTemp * restraint;
const interpassTemp = preheatTemp + 25;
const maxInterpass = 200;
let cevClass = '';
let cevInterpretation = '';
if (cev < 0.40) {
cevClass = 'Baixo';
cevInterpretation = 'Excelente soldabilidade';
} else if (cev < 0.50) {
cevClass = 'Médio';
cevInterpretation = 'Boa soldabilidade com cuidados';
} else if (cev < 0.60) {
cevClass = 'Alto';
cevInterpretation = 'Soldabilidade moderada';
} else {
cevClass = 'Crítico';
cevInterpretation = 'Requer procedimento especial';
}
let thicknessClass = thickness > 50 ? 'Crítica' : thickness > 25 ? 'Alta' : 'Normal';
const html = `
<div class="result-box" style="background: var(--color-bg-1); border-left: 4px solid var(--color-warning);">
<div class="result-title">🔥 PRÉ-AQUECIMENTO AWS D1.1 - RESULTADO</div>
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>DADOS RESUMIDOS:</strong><br>
Processo: ${weldingProcesses[currentWeldProcess].nome}<br>
Consumível: ${weldingElectrodes[currentWeldElectrode].nome}<br>
CEV: ${cev.toFixed(2)} (${cevClass} - ${cevInterpretation})<br>
Espessura: ${thickness} mm (${thicknessClass})<br>
Ambiente: ${ambient}°C<br>
Restrição: ${restraint === 1.0 ? 'Não restrita' : restraint === 1.1 ? 'Parcial' : 'Total'}
</div>
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px;">
<strong>CÁLCULOS:</strong><br>
CEV Factor: ${cev.toFixed(2)} × 50 = ${cevFactor.toFixed(1)}°C<br>
Esp Factor: (${thickness}/10) × 20 = ${thicknessFactor.toFixed(1)}°C<br>
Amb Factor: (20 - ${ambient}) / 2 = ${ambientFactor.toFixed(1)}°C<br>
Processo Adj: +${processAdjust}°C (${currentWeldProcess.toUpperCase()})<br>
Restrição: ×${restraint} = Multiplica por ${restraint}
</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">PRÉ-AQUECIMENTO MÍNIMO</div>
<div class="result-value">${Math.round(preheatTemp)}°C</div>
</div>
${calcInterpass ? `
<div class="result-item">
<div class="result-label">INTERPASS (entre passes)</div>
<div class="result-value">${Math.round(interpassTemp)}°C</div>
</div>
<div class="result-item">
<div class="result-label">Temperatura Máxima</div>
<div class="result-value">${maxInterpass}°C</div>
</div>
` : ''}
</div>
<div class="alert alert-warning" style="margin-top: 20px;">
<strong>⚠️ RECOMENDAÇÕES CRÍTICAS:</strong><br>
1. Pré-aqueça todo o acesso de soldagem (min 75mm da junta)<br>
${calcInterpass ? `2. Manter interpass entre ${Math.round(preheatTemp)}-${Math.round(interpassTemp)}°C<br>` : ''}
${calcInterpass ? `3. Não exceder ${maxInterpass}°C (risco de fragilização ZTA)<br>` : ''}
${calcInterpass ? '4' : '2'}. Usar termômetro de contato ou pirômetro<br>
${calcInterpass ? '5' : '3'}. ${thickness > 50 || cev > 0.60 ? 'PWHT (Tratamento Térmico Pós) RECOMENDADO' : 'Considerar PWHT para maior confiabilidade'}
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">
<strong>📊 TABELA AWS D1.1 REFERÊNCIA:</strong>
<table style="width: 100%; margin-top: 12px; font-size: 12px;">
<thead>
<tr style="background: var(--color-primary); color: white;">
<th style="padding: 8px;">Espessura</th>
<th>CEV < 0.40</th>
<th>CEV 0.40-0.60</th>
<th>CEV > 0.60</th>
</tr>
</thead>
<tbody>
<tr><td style="padding: 8px;">< 12mm</td><td>Não req.</td><td>50°C</td><td>100°C</td></tr>
<tr style="background: ${thickness >= 12 && thickness < 25 ? 'var(--color-bg-3)' : ''};"><td style="padding: 8px;">12-25mm</td><td>50°C</td><td>100°C</td><td>150°C</td></tr>
<tr style="background: ${thickness >= 25 && thickness < 50 ? 'var(--color-bg-3)' : ''};"><td style="padding: 8px;">25-50mm</td><td>50°C</td><td>100°C</td><td>165°C</td></tr>
<tr style="background: ${thickness >= 50 ? 'var(--color-bg-3)' : ''};"><td style="padding: 8px;">> 50mm</td><td>100°C</td><td>150°C</td><td>225°C</td></tr>
</tbody>
</table>
</div>
</div>
`;
document.getElementById('preheat-result').innerHTML = html;
addToHistory('Pré-Aquecimento', `${Math.round(preheatTemp)}°C (CEV=${cev.toFixed(2)}, esp=${thickness}mm)`);
}
function calcularFileteCompleto() {
const force = parseFloat(document.getElementById('filete-force').value) || 0;
const length = parseFloat(document.getElementById('filete-length').value) || 0;
const jointType = parseInt(document.getElementById('filete-joint').value) || 1;
const fy = parseFloat(document.getElementById('filete-steel').value) || 345;
const positionFactor = parseFloat(document.getElementById('filete-position').value) || 1.0;
const elec = weldingElectrodes[currentWeldElectrode];
// Weld capacity calculation
const fyWeld = fy * 0.6;
const legTheoretical = (force * 1000) / (0.707 * length * jointType * 0.65 * fyWeld * positionFactor);
const legCommercial = Math.max(Math.ceil(legTheoretical), 3);
const throat = legCommercial * 0.707;
// Number of passes
let passes = 1;
let maxDiameter = 3.25;
if (legCommercial <= 5) {
passes = 1;
maxDiameter = 3.25;
} else if (legCommercial <= 8) {
passes = 2;
maxDiameter = 4.0;
} else {
passes = Math.ceil(legCommercial / 4);
maxDiameter = 4.0;
}
// Real capacity
const realCapacity = (0.707 * legCommercial * length * jointType * 0.65 * fyWeld * positionFactor) / 1000;
const safetyMargin = realCapacity - force;
const utilization = (force / realCapacity) * 100;
// Time and consumption estimate
const timePerPass = (length / 1000) * 30; // 30 min/m
const totalTime = timePerPass * passes;
const volume = (legCommercial * legCommercial * 0.5 * length * jointType) / 1000; // cm³
const mass = (volume / 1000) * 7.85; // kg
const consumption = mass / elec.rendimento * 1.15; // with losses
const positionName = positionFactor === 1.0 ? 'Plana (1F)' : positionFactor === 0.9 ? 'Horizontal (2F)' : positionFactor === 0.8 ? 'Vertical (3F)' : 'Sobrecabeça (4F)';
let status = '✅ VIÁVEL';
let alertClass = 'alert-success';
if (utilization > 100) {
status = '❌ INSUFICIENTE';
alertClass = 'alert-error';
} else if (utilization > 85) {
status = '⚠️ ATENÇÃO';
alertClass = 'alert-warning';
}
const html = `
<div class="result-box" style="background: var(--color-bg-3); border-left: 4px solid var(--color-success);">
<div class="result-title">⚡ DIMENSIONAMENTO DE FILETE - RESULTADO</div>
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>DADOS:</strong><br>
Processo: ${weldingProcesses[currentWeldProcess].nome}<br>
Eletrodo: ${elec.nome}<br>
Força: ${force} kN | Comprimento: ${length} mm<br>
Aço Base: fy = ${fy} MPa<br>
Junta: ${jointType === 1 ? 'Filete Simples' : 'Filete Duplo'} | Posição: ${positionName}
</div>
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px; font-family: var(--font-family-mono); font-size: 13px;">
<strong>CÁLCULO:</strong><br>
Fv unitário = 0.707 × perna × comp × 0.65 × fy / 1000<br>
Fv = 0.707 × perna × ${length} × 0.65 × ${fy}/1000<br>
Fv = ${(0.707 * length * 0.65 * fy / 1000).toFixed(2)} × perna (kN)<br><br>
Para ${jointType} filete(s): ${jointType} × Fv = ${(jointType * 0.707 * length * 0.65 * fy / 1000).toFixed(2)} × perna<br><br>
Perna necessária: ${force} / ${(jointType * 0.707 * length * 0.65 * fy / 1000).toFixed(2)} = ${legTheoretical.toFixed(2)} mm
</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Perna Teórica</div>
<div class="result-value">${legTheoretical.toFixed(2)} mm</div>
</div>
<div class="result-item">
<div class="result-label">Perna Comercial</div>
<div class="result-value" style="color: var(--color-success);">${legCommercial} mm</div>
</div>
<div class="result-item">
<div class="result-label">Capacidade Real</div>
<div class="result-value">${realCapacity.toFixed(1)} kN</div>
</div>
<div class="result-item">
<div class="result-label">Margem de Segurança</div>
<div class="result-value">${safetyMargin.toFixed(1)} kN (${((realCapacity/force - 1) * 100).toFixed(0)}%)</div>
</div>
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-1); border-radius: 8px;">
<strong>⚙️ DIMENSIONAMENTO DE PASSES:</strong><br>
Eletrodo Máximo: ${maxDiameter}mm (para ${passes} passa${passes > 1 ? 's' : ''})
</div>
<div style="margin-top: 16px; padding: 16px; background: var(--color-surface); border-radius: 8px; border: 2px solid var(--color-primary);">
<strong>OPÇÃO ${passes === 1 ? 'RECOMENDADA' : '1'}: ${passes} PASSA${passes > 1 ? 'S' : ''}:</strong><br>
Perna: ${passes === 1 ? legCommercial : passes + '×' + Math.ceil(legCommercial/passes)} mm (diâmetro ${maxDiameter}mm)<br>
Corrente: ${elec.corrente_min}-${elec.corrente_max} A<br>
Tempo: ${Math.round(totalTime)} min<br>
Consumo: ${consumption.toFixed(2)} kg<br>
${status === '✅ VIÁVEL' ? '✅ VIÁVEL (Margem de ' + ((realCapacity/force - 1) * 100).toFixed(0) + '%)' : status}
</div>
${passes === 1 && legCommercial >= 5 ? `
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-6); border-radius: 8px;">
<strong>OPÇÃO 2: 2 PASSES (Maior Confiabilidade):</strong><br>
Perna: 2×${Math.ceil(legCommercial/2)} = ${legCommercial} mm<br>
Corrente: ${elec.corrente_min} A × 2<br>
Tempo: ${Math.round(totalTime * 2)} min<br>
Consumo: ${(consumption * 2).toFixed(2)} kg<br>
✅ RECOMENDADO (Maior qualidade e resistência)
</div>
` : ''}
<div class="alert ${alertClass}" style="margin-top: 20px;">
<strong>RECOMENDAÇÕES:</strong><br>
- ${elec.nome} é ${elec.tipo === 'Básico' ? 'excelente' : 'adequado'} para essa aplicação<br>
- ${passes > 1 ? 'Usar ' + passes + ' passes garante melhor qualidade' : 'Soldagem em 1 passa é viável'}<br>
- Manter interpass 150°C (vindo da Aba Pré-Aquecimento)<br>
- Utilização: ${utilization.toFixed(1)}% ${status}
</div>
</div>
`;
document.getElementById('filete-result').innerHTML = html;
addToHistory('Filete', `Perna ${legCommercial}mm, ${passes} passe(s), ${force}kN`);
}
function calcularEnergiaCompleta() {
const voltage = parseFloat(document.getElementById('hi-voltage').value) || 0;
const current = parseFloat(document.getElementById('hi-current').value) || 0;
const speed = parseFloat(document.getElementById('hi-speed').value) || 0;
const efficiency = parseFloat(document.getElementById('hi-efficiency').value) || 0.75;
const steelType = document.getElementById('hi-steel').value;
// Heat Input calculation
const heatInput = (voltage * current * 60 * efficiency) / (speed * 1000);
const steelLimits = {
'a36': { min: 1.5, max: 3.0, name: 'A36' },
'a572': { min: 1.0, max: 2.5, name: 'A572' },
's355': { min: 0.8, max: 2.0, name: 'S355' }
};
const limits = steelLimits[steelType];
let hiStatus = '';
let alertClass = '';
let recommendations = [];
if (heatInput < limits.min) {
hiStatus = 'BAIXO';
alertClass = 'alert-warning';
recommendations.push('Aumentar corrente ou reduzir velocidade');
recommendations.push('Risco de falta de fusão ou trincas a frio');
} else if (heatInput <= limits.max) {
hiStatus = 'ADEQUADO ✅';
alertClass = 'alert-success';
recommendations.push('Energia dentro da faixa recomendada');
recommendations.push('Manter os parâmetros atuais');
} else {
hiStatus = 'MUITO ALTO ⚠️';
alertClass = 'alert-error';
const newSpeed = Math.ceil((voltage * current * 60 * efficiency) / (limits.max * 1000));
const newCurrent = Math.ceil((limits.max * 1000 * speed) / (voltage * 60 * efficiency));
recommendations.push('AUMENTAR VELOCIDADE para ' + newSpeed + ' cm/min → HI = ' + limits.max.toFixed(2) + ' kJ/mm ✅');
recommendations.push('OU REDUZIR CORRENTE para ' + newCurrent + ' A → HI = ' + limits.max.toFixed(2) + ' kJ/mm ✅');
recommendations.push('OPÇÃO 3: Usar processo GMAW (mais eficiente) → HI ≈ ' + (heatInput * 0.6).toFixed(2) + ' kJ/mm ✅');
}
const html = `
<div class="result-box" style="background: var(--color-bg-6); border-left: 4px solid var(--color-warning);">
<div class="result-title">🔥 ENERGIA DE SOLDAGEM - RESULTADO</div>
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>PARÂMETROS:</strong><br>
Voltagem: ${voltage} V<br>
Corrente: ${current} A<br>
Velocidade: ${speed} cm/min<br>
Eficiência: ${(efficiency * 100).toFixed(0)}%
</div>
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px; font-family: var(--font-family-mono); font-size: 13px;">
<strong>CÁLCULO:</strong><br>
HI = (V × I × 60 × η) / (v × 1000)<br>
HI = (${voltage} × ${current} × 60 × ${efficiency}) / (${speed} × 1000)<br>
HI = ${(voltage * current * 60 * efficiency).toFixed(1)} / ${speed * 1000} = ${heatInput.toFixed(2)} kJ/mm
</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Energia de Soldagem</div>
<div class="result-value" style="color: ${heatInput <= limits.max && heatInput >= limits.min ? 'var(--color-success)' : 'var(--color-error)'}">${heatInput.toFixed(2)} kJ/mm</div>
</div>
<div class="result-item">
<div class="result-label">Classificação</div>
<div class="result-value" style="font-size: 20px;">${hiStatus}</div>
</div>
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">
<strong>⚠️ ANÁLISE POR TIPO DE AÇO:</strong>
<table style="width: 100%; margin-top: 12px; font-size: 13px;">
<thead>
<tr style="background: var(--color-primary); color: white;">
<th style="padding: 8px;">Aço</th>
<th>Ideal (kJ/mm)</th>
<th>Valor</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr style="background: ${steelType === 'a36' ? 'var(--color-bg-3)' : ''};">
<td style="padding: 8px;">A36</td>
<td>1.5-3.0</td>
<td>${heatInput.toFixed(2)}</td>
<td>${heatInput >= 1.5 && heatInput <= 3.0 ? '✅ OK' : heatInput > 3.0 ? '❌ ALTO' : '⚠️ BAIXO'}</td>
</tr>
<tr style="background: ${steelType === 'a572' ? 'var(--color-bg-3)' : ''};">
<td style="padding: 8px;">A572</td>
<td>1.0-2.5</td>
<td>${heatInput.toFixed(2)}</td>
<td>${heatInput >= 1.0 && heatInput <= 2.5 ? '✅ OK' : heatInput > 2.5 ? '❌ ALTO' : '⚠️ BAIXO'}</td>
</tr>
<tr style="background: ${steelType === 's355' ? 'var(--color-bg-3)' : ''};">
<td style="padding: 8px;">S355</td>
<td>0.8-2.0</td>
<td>${heatInput.toFixed(2)}</td>
<td>${heatInput >= 0.8 && heatInput <= 2.0 ? '✅ OK' : heatInput > 2.0 ? '❌ CRÍTICO' : '⚠️ BAIXO'}</td>
</tr>
</tbody>
</table>
</div>
${heatInput > limits.max ? `
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-4); border-radius: 8px; border: 2px solid var(--color-error);">
<strong>⚠️ RISCOS:</strong><br>
1. Aquecimento excessivo da ZTA<br>
2. Possível fragilização por alívio<br>
3. Risco de trincas pelo resfriamento rápido<br>
4. Redução de tenacidade
</div>
` : ''}
<div class="alert ${alertClass}" style="margin-top: 20px;">
<strong>✅ RECOMENDAÇÕES:</strong><br>
${recommendations.map((rec, i) => `${i + 1}. ${rec}`).join('<br>')}
</div>
<div style="margin-top: 16px; padding: 12px; background: var(--color-surface); border-radius: 8px; text-align: center;">
<strong>🔧 CALCULADORA INTERATIVA:</strong><br>
<small>Teste diferentes velocidades/correntes acima para encontrar HI ideal!</small>
</div>
</div>
`;
document.getElementById('hi-result').innerHTML = html;
addToHistory('Energia Soldagem', `HI=${heatInput.toFixed(2)} kJ/mm (${hiStatus})`);
}
function calcularPreaquecimento() {
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;
let pwhtRecommendation = '';
if (thickness > 50 || cev > 0.60) {
pwhtRecommendation = '⚠️ PWHT (Tratamento Térmico Pós-Soldagem) recomendado';
} else {
pwhtRecommendation = '✅ PWHT não obrigatório';
}
document.getElementById('preheat-result').innerHTML = `
<div class="result-box">
<div class="result-title">Temperatura de Pré-Aquecimento (AWS D1.1)</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Temp. Mínima</div>
<div class="result-value">${Math.round(preheatTemp)}°C</div>
</div>
<div class="result-item">
<div class="result-label">Temp. Interpasse Máx</div>
<div class="result-value">${Math.round(maxInterpass)}°C</div>
</div>
</div>
<div class="alert alert-warning" style="margin-top: 16px;">
<strong>${pwhtRecommendation}</strong>
</div>
</div>
`;
addToHistory('Pré-Aquecimento', `CEV=${cev}, esp=${thickness}mm → ${Math.round(preheatTemp)}°C`);
}
function calcularConsumoCompleto() {
const leg = parseFloat(document.getElementById('consumo-leg').value) || 0;
const length = parseFloat(document.getElementById('consumo-length').value) || 0;
const loss = parseFloat(document.getElementById('consumo-loss').value) || 15;
const scrap = parseFloat(document.getElementById('consumo-scrap').value) || 5;
const elec = weldingElectrodes[currentWeldElectrode];
// Volume calculation
const throat = leg * 0.707;
const volumeCm3 = (throat * leg * length * 1000 * 0.5) / 1000;
const massKg = (volumeCm3 / 1000000) * 7850;
// Consumption with efficiency
const massConsumable = massKg / elec.rendimento;
const lossKg = massConsumable * (loss / 100);
const scrapKg = massConsumable * (scrap / 100);
const totalKg = massConsumable + lossKg + scrapKg;
// Time estimation
const timeHours = totalKg / elec.taxa_deposicao;
const timeMin = timeHours * 60;
// Cost
const costMaterial = totalKg * elec.custo_kg;
const costLabor = timeHours * 60; // R$ 60/h average
const costTotal = costMaterial + costLabor;
// Compare with other electrodes
let comparisons = [];
Object.keys(weldingElectrodes).forEach(key => {
const e = weldingElectrodes[key];
if (e.processo === 'SMAW' && key !== currentWeldElectrode) {
const altMass = massKg / e.rendimento * (1 + loss/100) * (1 + scrap/100);
const altTime = (altMass / e.taxa_deposicao) * 60;
const altCost = altMass * e.custo_kg + (altTime / 60) * 60;
comparisons.push({
name: e.nome,
mass: altMass,
time: altTime,
cost: altCost
});
}
});
const html = `
<div class="result-box" style="background: var(--color-bg-5); border-left: 4px solid #a855f7;">
<div class="result-title">📊 CONSUMO DE ELETRODOS - RESULTADO</div>
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>CONSUMÍVEL SELECIONADO:</strong><br>
Eletrodo ${elec.nome} (AWS A5.1)<br>
Rendimento: ${(elec.rendimento * 100).toFixed(0)}%<br>
Taxa Deposição: ${elec.taxa_deposicao} kg/h<br>
Custo: R$ ${elec.custo_kg}/kg
</div>
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px; font-family: var(--font-family-mono); font-size: 13px;">
<strong>CÁLCULOS:</strong><br>
Volume de Solda: ${volumeCm3.toFixed(0)} mm³<br>
Massa Teórica: ${massKg.toFixed(3)} kg<br>
Fator Rendimento: ${(elec.rendimento * 100).toFixed(0)}% = ÷${elec.rendimento.toFixed(2)}<br>
Massa Consumível: ${massKg.toFixed(3)} ÷ ${elec.rendimento.toFixed(2)} = ${massConsumable.toFixed(3)} kg<br><br>
Perdas (Respingos): ${loss}% × ${massConsumable.toFixed(3)} = ${lossKg.toFixed(4)}kg<br>
Sucata (Pontas): ${scrap}% × ${massConsumable.toFixed(3)} = ${scrapKg.toFixed(4)}kg<br><br>
TOTAL NECESSÁRIO: ${totalKg.toFixed(4)} kg
</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Consumo de Eletrodo</div>
<div class="result-value">${(totalKg * 1000).toFixed(0)} g (${totalKg.toFixed(3)} kg)</div>
</div>
<div class="result-item">
<div class="result-label">Caixas de 5kg</div>
<div class="result-value">${Math.ceil(totalKg / 5)} caixa${Math.ceil(totalKg / 5) > 1 ? 's' : ''}</div>
</div>
<div class="result-item">
<div class="result-label">Custo Total Material</div>
<div class="result-value">R$ ${costMaterial.toFixed(2)}</div>
</div>
<div class="result-item">
<div class="result-label">Tempo de Soldagem</div>
<div class="result-value">${Math.round(timeMin)} min</div>
</div>
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">
<strong>📊 COMPARAÇÃO DE ELETRODOS PARA MESMO TRABALHO:</strong>
<table style="width: 100%; margin-top: 12px; font-size: 13px;">
<thead>
<tr style="background: var(--color-primary); color: white;">
<th style="padding: 8px;">Eletrodo</th>
<th>Consumo</th>
<th>Custo</th>
<th>Tempo</th>
</tr>
</thead>
<tbody>
<tr style="background: var(--color-bg-3);">
<td style="padding: 8px;"><strong>${elec.nome}</strong></td>
<td>${totalKg.toFixed(3)}kg</td>
<td>R$ ${costTotal.toFixed(2)}</td>
<td>${Math.round(timeMin)} min</td>
</tr>
${comparisons.map(c => `
<tr>
<td style="padding: 8px;">${c.name}</td>
<td>${c.mass.toFixed(3)}kg</td>
<td>R$ ${c.cost.toFixed(2)} ${c.cost < costTotal ? '✅' : ''}</td>
<td>${Math.round(c.time)} min ${c.time < timeMin ? '✅' : ''}</td>
</tr>
`).join('')}
</tbody>
</table>
</div>
<div class="alert alert-success" style="margin-top: 20px;">
<strong>✅ RECOMENDAÇÃO:</strong><br>
${comparisons.length > 0 && comparisons[0].cost < costTotal ?
`${comparisons[0].name} é mais barato (${((1 - comparisons[0].cost/costTotal) * 100).toFixed(0)}% economia!)` :
`${elec.nome} é a melhor opção considerando custo e qualidade`}
</div>
</div>
`;
document.getElementById('consumo-result').innerHTML = html;
addToHistory('Consumo Eletrodos', `${totalKg.toFixed(3)}kg ${elec.nome} para ${length}m`);
// Add button to send to budget
const resultDiv = document.getElementById('consumo-result');
const existingButton = resultDiv.querySelector('.add-to-budget-btn');
if (!existingButton) {
const button = document.createElement('button');
button.className = 'btn btn-success add-to-budget-btn';
button.style.marginTop = '16px';
button.textContent = '💰 Adicionar ao Orçamento';
button.onclick = () => addConsumoToOrcamento(totalKg, elec.nome, elec.custo_kg);
resultDiv.querySelector('.result-box').appendChild(button);
}
}
function addConsumoToOrcamento(kg, electrodeNome, custoKg) {
// Switch to orcamento section
showSection('orcamento');
setTimeout(() => {
document.getElementById('budget-category').value = 'consumivel';
updateBudgetTypeOptions();
setTimeout(() => {
document.getElementById('budget-type').value = 'consumiveis';
updateBudgetSpecOptions();
setTimeout(() => {
// Find matching electrode
const electrodeId = electrodeNome.toLowerCase().replace(/[^a-z0-9]/g, '').substring(0, 6);
const specSelect = document.getElementById('budget-spec');
const option = Array.from(specSelect.options).find(opt => opt.value.includes(electrodeId));
if (option) {
specSelect.value = option.value;
autoFillBudgetData();
}
document.getElementById('budget-qty').value = kg.toFixed(2);
updateBudgetTotal();
alert(`✅ Eletrodo transferido para Orçamento!\n\n${electrodeNome}: ${kg.toFixed(2)} kg\n\nClique em Adicionar.`);
}, 200);
}, 200);
}, 300);
}
function gerarDiagramaSequencia() {
const jointType = document.getElementById('seq-joint').value;
const length = parseFloat(document.getElementById('seq-length').value) || 0;
const leg = parseFloat(document.getElementById('seq-leg').value) || 0;
const passes = parseInt(document.getElementById('seq-passes').value) || 1;
const pattern = document.getElementById('seq-pattern').value;
let patternName = '';
let distortionReduction = 0;
let description = '';
switch(pattern) {
case 'skip':
patternName = 'Skip Welding';
distortionReduction = 80;
description = 'Soldagem alternada em segmentos';
break;
case 'backstep':
patternName = 'Backstep Welding';
distortionReduction = 60;
description = 'Soldagem em segmentos na direção oposta';
break;
case 'pulsed':
patternName = 'Pulsado';
distortionReduction = 50;
description = 'Corrente pulsada para controle térmico';
break;
case 'continuous':
patternName = 'Contínuo';
distortionReduction = 0;
description = 'Soldagem contínua sem paradas';
break;
}
const timePerPass = (length / 1000) * 30;
const totalTime = timePerPass * passes;
const skipDiagram = `
<pre style="background: var(--color-surface); padding: 16px; border-radius: 8px; overflow-x: auto; font-size: 11px;">
VISTA SUPERIOR (Plano Vertical):
LADO ESQUERDO (1º Lado):
┌──────────────────────────────┐
│ PASSA 1 (1ª Metade): │
│ ━━━ ━━━ ━━━ ━━━ (Skip) │
│ 1 2 3 4 5 6 7 8 │ ${length}mm
│ [${Math.round(length/8)}mm segmentos, ${Math.round(length/8)}mm espaços] │
│ │
│ PASSA 2 (2ª Metade): │
│ ━━━ ━━━ ━━━ ━━━ (Reverso) │
│ 16 15 14 13 12 11 10 9 │
│ [Preenchimento dos espaços] │
│ │
│ RESULTADO: Distorção mínima ✅ │
└──────────────────────────────┘
LADO DIREITO: [Sequência idêntica]
</pre>
`;
const html = `
<div class="result-box" style="background: var(--color-bg-7); border-left: 4px solid #ec4899;">
<div class="result-title">📐 SEQUÊNCIA DE SOLDAGEM - PLANO VISUAL</div>
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>JUNTA:</strong> ${jointType === 'filete' ? 'Filete Duplo' : jointType === 'topo' ? 'Topo' : 'Angular'} (${length}mm × ${leg}mm × ${passes} passa${passes > 1 ? 's' : ''})<br>
<strong>PADRÃO:</strong> ${patternName} (${description})<br>
<strong>PROCESSO:</strong> ${weldingProcesses[currentWeldProcess].nome}
</div>
${pattern === 'skip' ? skipDiagram : `
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; text-align: center;">
<strong>Padrão ${patternName}</strong><br>
<p style="margin-top: 12px; color: var(--color-text-secondary);">${description}</p>
</div>
`}
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-1); border-radius: 8px;">
<strong>⏱️ CRONOGRAMA:</strong><br>
Sequência 1º Lado: ${Math.round(totalTime)} min<br>
Sequência 2º Lado: ${Math.round(totalTime)} min<br>
Tempo Total: ${Math.round(totalTime * 2)} min (com pausas)
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-6); border-radius: 8px;">
<strong>📊 ANÁLISE DE DISTORÇÃO:</strong><br><br>
<strong>Método ${patternName}:</strong><br>
- Distorção Angular Esperada: ±${pattern === 'continuous' ? '2.5' : '0.5'}°<br>
- Distorção Longitudinal: ±${pattern === 'continuous' ? '8' : '2'}mm<br>
- Avaliação: ${distortionReduction > 60 ? 'EXCELENTE ✅' : distortionReduction > 40 ? 'BOA ✅' : 'NÃO RECOMENDADO ⚠️'}<br><br>
${pattern !== 'continuous' ? `
<strong>vs Método Contínuo (sem otimização):</strong><br>
- Distorção Angular: ±2.5° ⚠️<br>
- Distorção Longitudinal: ±8mm ⚠️<br>
- Avaliação: NÃO RECOMENDADO<br><br>
` : ''}
<strong>✅ VANTAGENS ${patternName.toUpperCase()}:</strong><br>
1. Reduz distorções em ${distortionReduction}%<br>
2. Controla melhor a temperatura<br>
3. Facilita inspeção entre passes<br>
4. Reduz stress residual
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px; border: 2px solid var(--color-primary);">
<strong>🔧 INSTRUÇÕES PARA SOLDADOR:</strong><br>
1. Marcar posições com giz (0, ${Math.round(length/8)}, ${Math.round(length/4)}...)<br>
2. Soldar segmentos 1-8 (1ª passa)<br>
3. Aguardar resfriamento (espaços resfriem)<br>
4. Soldar segmentos 9-16 (preencher vazios)<br>
5. Controlar temperatura: 150-200°C (interpass)<br>
6. Inspeção visual entre passes
</div>
</div>
`;
document.getElementById('sequencia-result').innerHTML = html;
addToHistory('Sequência Soldagem', `${patternName}, ${length}mm, ${passes} passes`);
}
function buscarPadraoIdeal() {
const app = document.getElementById('padrao-app').value;
const criticality = document.getElementById('padrao-criticality').value;
const env = document.getElementById('padrao-env').value;
let standardClass = 'B';
let electrode = 'E7018';
let passes = 2;
let leg = 4;
let preheat = 100;
let inspection = 'Visual 100% + Ultrassom 10%';
let costIndex = 140;
if (criticality === 'baixa') {
standardClass = 'A';
electrode = 'E6013';
passes = 1;
leg = 3;
preheat = 60;
inspection = 'Visual 100%';
costIndex = 100;
} else if (criticality === 'critica' || app === 'ponte' || app === 'offshore') {
standardClass = 'C';
electrode = 'E8018';
passes = 3;
leg = 6;
preheat = 125;
inspection = 'Visual 100% + UT 100% + RT 20%';
costIndex = 200;
}
const elec = weldingElectrodes[electrode.toLowerCase()];
const consumptionPerMeter = (leg * leg * 0.5 * 1000) / 1000000 * 7.85 / elec.rendimento * 1.2;
const timePerMeter = (consumptionPerMeter / elec.taxa_deposicao) * 60;
const costPerMeter = consumptionPerMeter * elec.custo_kg + (timePerMeter / 60) * 60;
const html = `
<div class="result-box" style="background: var(--color-bg-8); border-left: 4px solid #06b6d4;">
<div class="result-title">📋 PADRÕES DE SOLDA POR APLICAÇÃO</div>
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
<strong>APLICAÇÃO:</strong> ${app === 'edificio' ? 'Edifício Múltiplos Andares' : app === 'ponte' ? 'Ponte Rodoviária' : app === 'industrial' ? 'Estrutura Industrial' : app === 'tubulacao' ? 'Tubulação de Pressão' : app === 'equipamento' ? 'Equipamento Mecânico' : 'Marinha/Offshore'}<br>
<strong>Criticidade:</strong> ${criticality === 'baixa' ? 'Baixa' : criticality === 'media' ? 'Média' : criticality === 'alta' ? 'Alta' : 'Crítica'} | <strong>Ambiente:</strong> ${env === 'interno' ? 'Interno Seco' : env === 'externo' ? 'Externo Temperado' : env === 'agressivo' ? 'Agressivo/Marinho' : 'Baixas Temperaturas'}<br>
<strong>Norma:</strong> AISC 360-16, AWS D1.1
</div>
<div style="padding: 20px; background: ${standardClass === 'A' ? 'var(--color-bg-2)' : standardClass === 'B' ? 'var(--color-bg-1)' : 'var(--color-bg-6)'}; border-radius: 12px; border: 2px solid var(--color-primary);">
<h3 style="color: var(--color-primary); margin-bottom: 16px;">✅ PADRÃO RECOMENDADO: Classe ${standardClass}</h3>
<strong>Processo:</strong> ${weldingProcesses[currentWeldProcess].nome}<br>
<strong>Eletrodo:</strong> ${electrode} (${elec.tipo})<br>
<strong>Processo Secundário:</strong> ${standardClass === 'C' ? 'SAW (se volume alto)' : 'SMAW padrão'}<br><br>
<strong>ESPECIFICAÇÃO:</strong><br>
• Número de Passes: ${passes}<br>
• Perna Filete: ${leg} mm<br>
• Pré-aquecimento: ${preheat}°C<br>
• Interpass: 150-200°C<br>
• Velocidade: 20-30 cm/min<br>
• Posição: Plana e Horizontal preferida<br>
• Inspeção: ${inspection}<br><br>
<strong>CONSUMO POR METRO LINEAR:</strong><br>
• Eletrodos: ${consumptionPerMeter.toFixed(2)} kg<br>
• Tempo: ${Math.round(timePerMeter)} min/m<br>
• Custo: R$ ${costPerMeter.toFixed(2)}/m (material + mão de obra)<br><br>
<strong>QUALIDADE ESPERADA:</strong><br>
✓ Resistência à tração: >${elec.resistencia_tracao_min} MPa<br>
✓ Alongamento: >${elec.alongamento}%<br>
✓ Charpy (-20°C): >${elec.charpy} J<br>
✓ Dureza ZTA: <260 HV<br><br>
<strong>⚠️ RESTRIÇÕES:</strong><br>
• Não usar em posição overhead sem suporte<br>
• Temperatura mínima: ${env === 'baixatemp' ? '-20' : '-10'}°C<br>
• Não esticar além de 2x o comprimento
</div>
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-5); border-radius: 8px;">
<strong>📊 ALTERNATIVAS:</strong><br><br>
${standardClass !== 'A' ? `
<strong>⭐ OPÇÃO INFERIOR (Economia):</strong><br>
PADRÃO: Classe A (Soldagem Econômica)<br>
Eletrodo: E6013 (mais barato)<br>
Passes: 1 | Perna: 3mm<br>
Custo: R$ ${(costPerMeter * 0.56).toFixed(2)}/m (${((1 - 0.56) * 100).toFixed(0)}% menos)<br>
⚠️ Tenacidade reduzida - Use em estruturas baixas<br><br>
` : ''}
${standardClass !== 'C' ? `
<strong>🏆 OPÇÃO PREMIUM (Máxima Qualidade):</strong><br>
PADRÃO: Classe C (Soldagem Crítica)<br>
Eletrodo: E8018 (maior tenacidade)<br>
Passes: 3-4 | Perna: 6mm<br>
Processo: SAW (qualidade automática)<br>
Inspeção: Visual 100% + UT 100% + RT 20%<br>
Custo: R$ ${(costPerMeter * 1.89).toFixed(2)}/m (${((1.89 - 1) * 100).toFixed(0)}% mais)<br>
✅ Máxima confiabilidade - Use em pontes/crítico
` : ''}
</div>
</div>
`;
document.getElementById('padrao-result').innerHTML = html;
addToHistory('Padrões Solda', `Classe ${standardClass}, ${electrode}, ${app}`);
}
function calcularSoldaFilete() {
const force = parseFloat(document.getElementById('weld-force').value) || 0;
const length = parseFloat(document.getElementById('weld-length').value) || 0;
const fy = parseFloat(document.getElementById('weld-fy').value) || 345;
const fyWeld = fy * 0.6;
const leg = (force * 1000) / (0.707 * length * 0.65 * fyWeld);
const throat = leg * 0.707;
const legCommercial = Math.ceil(leg);
const passes = legCommercial <= 5 ? 1 : legCommercial <= 8 ? 2 : 3;
document.getElementById('weld-result').innerHTML = `
<div class="result-box">
<div class="result-title">Dimensionamento da Solda de Filete</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Perna Calculada</div>
<div class="result-value">${leg.toFixed(2)} mm</div>
</div>
<div class="result-item">
<div class="result-label">Perna Adotada</div>
<div class="result-value">${legCommercial} mm</div>
</div>
<div class="result-item">
<div class="result-label">Garganta Efetiva</div>
<div class="result-value">${throat.toFixed(2)} mm</div>
</div>
<div class="result-item">
<div class="result-label">Número de Passes</div>
<div class="result-value">${passes}</div>
</div>
</div>
<div class="alert alert-success" style="margin-top: 16px;">
<strong>Eletrodo recomendado:</strong> E${Math.round(fy * 1.15)} (resistência compatível com o aço base)
</div>
</div>
`;
addToHistory('Solda de Filete', `Perna ${legCommercial}mm, ${passes} passe(s)`);
}
function calcularEnergiaSoldagem() {
const voltage = parseFloat(document.getElementById('hi-voltage').value) || 0;
const current = parseFloat(document.getElementById('hi-current').value) || 0;
const speed = parseFloat(document.getElementById('hi-speed').value) || 0;
const heatInput = (voltage * current * 60) / (speed * 1000);
let interpretation = '';
let alertClass = '';
if (heatInput < 1.0) {
interpretation = 'Energia baixa - Risco de falta de fusão ou trincas a frio';
alertClass = 'alert-warning';
} else if (heatInput <= 2.0) {
interpretation = 'Energia adequada - Dentro da faixa recomendada';
alertClass = 'alert-success';
} else {
interpretation = 'Energia alta - Risco de fragilização da ZTA e distorção';
alertClass = 'alert-error';
}
document.getElementById('hi-result').innerHTML = `
<div class="result-box">
<div class="result-title">Energia de Soldagem (Heat Input)</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Energia</div>
<div class="result-value">${heatInput.toFixed(2)} kJ/mm</div>
</div>
</div>
<div class="alert ${alertClass}" style="margin-top: 16px;">
<strong>${interpretation}</strong>
</div>
</div>
`;
addToHistory('Energia de Soldagem', `HI = ${heatInput.toFixed(2)} kJ/mm`);
}
function calcularConsumoEletrodos() {
const leg = parseFloat(document.getElementById('elec-leg').value) || 0;
const length = parseFloat(document.getElementById('elec-length').value) || 0;
const factor = parseFloat(document.getElementById('elec-type').value) || 1.10;
const loss = parseFloat(document.getElementById('elec-loss').value) || 15;
const throat = leg * 0.707;
const volume = throat * leg * length * 1000;
const mass = (volume / 1000000) * 7850 / 1000;
const consumption = mass * factor * (1 + loss / 100);
document.getElementById('elec-result').innerHTML = `
<div class="result-box">
<div class="result-title">Consumo de Eletrodos</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Volume de Solda</div>
<div class="result-value">${(volume / 1000).toFixed(1)} cm³</div>
</div>
<div class="result-item">
<div class="result-label">Massa de Solda</div>
<div class="result-value">${mass.toFixed(2)} kg</div>
</div>
<div class="result-item">
<div class="result-label">Consumo Total</div>
<div class="result-value">${consumption.toFixed(2)} kg</div>
</div>
</div>
</div>
`;
addToHistory('Consumo de Eletrodos', `${consumption.toFixed(2)} kg para ${length}m de solda`);
}
function converterDureza(source) {
let HB = 0;
if (source === 'hb') {
HB = parseFloat(document.getElementById('hard-hb').value) || 0;
} else if (source === 'hrc') {
const HRC = parseFloat(document.getElementById('hard-hrc').value) || 0;
HB = (HRC + 9.8) / 0.0338;
document.getElementById('hard-hb').value = Math.round(HB);
} else if (source === 'hv') {
const HV = parseFloat(document.getElementById('hard-hv').value) || 0;
HB = HV / 0.95;
document.getElementById('hard-hb').value = Math.round(HB);
}
if (HB === 0) return;
const HRC = HB * 0.0338 - 9.8;
const HV = HB * 0.95;
const fu = HB * 10;
const fy = fu * 0.7;
if (source !== 'hrc') document.getElementById('hard-hrc').value = HRC.toFixed(1);
if (source !== 'hv') document.getElementById('hard-hv').value = Math.round(HV);
document.getElementById('hardness-result').innerHTML = `
<div class="result-box">
<div class="result-title">Conversão de Dureza</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">HB (Brinell)</div>
<div class="result-value">${Math.round(HB)}</div>
</div>
<div class="result-item">
<div class="result-label">HRC (Rockwell C)</div>
<div class="result-value">${HRC.toFixed(1)}</div>
</div>
<div class="result-item">
<div class="result-label">HV (Vickers)</div>
<div class="result-value">${Math.round(HV)}</div>
</div>
</div>
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-6); border-radius: 8px;">
<strong>Estimativa de Resistência:</strong><br>
fu ≈ ${fu.toFixed(0)} MPa<br>
fy ≈ ${fy.toFixed(0)} MPa (aproximado)
</div>
</div>
`;
}
function analisarCharpy() {
const temps = [
parseFloat(document.getElementById('charpy-t1').value),
parseFloat(document.getElementById('charpy-t2').value),
parseFloat(document.getElementById('charpy-t3').value),
parseFloat(document.getElementById('charpy-t4').value)
];
const energies = [
parseFloat(document.getElementById('charpy-e1').value),
parseFloat(document.getElementById('charpy-e2').value),
parseFloat(document.getElementById('charpy-e3').value),
parseFloat(document.getElementById('charpy-e4').value)
];
const validPoints = temps.map((t, i) => ({ temp: t, energy: energies[i] }))
.filter(p => !isNaN(p.temp) && !isNaN(p.energy))
.sort((a, b) => a.temp - b.temp);
if (validPoints.length < 2) {
alert('Insira pelo menos 2 pontos válidos');
return;
}
let ttdf = null;
for (let i = 0; i < validPoints.length - 1; i++) {
if ((validPoints[i].energy >= 27 && validPoints[i+1].energy < 27) ||
(validPoints[i].energy < 27 && validPoints[i+1].energy >= 27)) {
const t1 = validPoints[i].temp;
const e1 = validPoints[i].energy;
const t2 = validPoints[i+1].temp;
const e2 = validPoints[i+1].energy;
ttdf = t1 + (27 - e1) * (t2 - t1) / (e2 - e1);
break;
}
}
document.getElementById('charpy-result').innerHTML = `
<div class="card">
<div class="card-title">Curva de Transição Dúctil-Frágil</div>
<div class="chart-container">
<canvas id="charpy-chart"></canvas>
</div>
${ttdf !== null ? `
<div class="alert alert-success" style="margin-top: 16px;">
<strong>TTDF (Temperatura de Transição):</strong> ${ttdf.toFixed(1)}°C<br>
Temperatura onde a energia de impacto = 27J
</div>
` : `
<div class="alert alert-warning" style="margin-top: 16px;">
<strong>Não foi possível calcular TTDF</strong><br>
A curva não intercepta 27J no intervalo medido
</div>
`}
</div>
`;
if (currentChart) {
currentChart.destroy();
}
const ctx = document.getElementById('charpy-chart').getContext('2d');
currentChart = new Chart(ctx, {
type: 'line',
data: {
labels: validPoints.map(p => p.temp + '°C'),
datasets: [{
label: 'Energia (J)',
data: validPoints.map(p => p.energy),
borderColor: '#1FB8CD',
backgroundColor: '#1FB8CD40',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: 'Curva de Transição Charpy'
}
},
scales: {
y: {
title: {
display: true,
text: 'Energia (J)'
}
},
x: {
title: {
display: true,
text: 'Temperatura (°C)'
}
}
}
}
});
addToHistory('Análise Charpy', `${validPoints.length} pontos, TTDF = ${ttdf ? ttdf.toFixed(1) : 'N/A'}°C`);
}
function gerarChecklistCertificado() {
const normSelect = document.getElementById('cert-norm');
const resultDiv = document.getElementById('cert-result');
// Verificar se os elementos existem
if (!normSelect || !resultDiv) return;
const norm = normSelect.value;
const requirements = certRequirements[norm] || [];
resultDiv.innerHTML = `
<div class="card">
<div class="card-title">Checklist de Requisitos - ${norm.toUpperCase().replace('_', ' ')}</div>
${requirements.map((req, index) => `
<div style="padding: 12px; background: var(--color-background); border-radius: 8px; margin-bottom: 8px; display: flex; align-items: center; gap: 12px;">
<input type="checkbox" id="req-${index}" style="width: 20px; height: 20px; cursor: pointer;">
<label for="req-${index}" style="cursor: pointer; flex: 1;">${req}</label>
</div>
`).join('')}
</div>
`;
}
function updatePaintFields() {
const typeSelect = document.getElementById('paint-type');
const field3 = document.getElementById('paint-field3');
const label1 = document.getElementById('paint-label1');
const label2 = document.getElementById('paint-label2');
// Verificar se os elementos existem
if (!typeSelect || !field3 || !label1 || !label2) return;
const type = typeSelect.value;
if (type === 'chapa') {
label1.textContent = 'Comprimento (mm)';
label2.textContent = 'Largura (mm)';
field3.style.display = 'none';
} else if (type === 'perfilW') {
label1.textContent = 'Comprimento (mm)';
label2.textContent = 'Altura (mm)';
field3.style.display = 'none';
} else if (type === 'tubo') {
label1.textContent = 'Comprimento (mm)';
label2.textContent = 'Diâmetro (mm)';
field3.style.display = 'none';
} else if (type === 'rhs') {
const label3 = document.getElementById('paint-label3');
label1.textContent = 'Comprimento (mm)';
label2.textContent = 'Largura (mm)';
if (label3) label3.textContent = 'Altura (mm)';
field3.style.display = 'block';
}
}
function calcularAreaPintura() {
const type = document.getElementById('paint-type').value;
const dim1 = parseFloat(document.getElementById('paint-dim1').value) || 0;
const dim2 = parseFloat(document.getElementById('paint-dim2').value) || 0;
const dim3 = parseFloat(document.getElementById('paint-dim3').value) || 0;
const qty = parseInt(document.getElementById('paint-qty').value) || 1;
let area = 0;
if (type === 'chapa') {
area = (dim1 * dim2 * 2) / 1000000;
} else if (type === 'perfilW') {
const perimeter = dim2 * 3.5;
area = (perimeter * dim1) / 1000000;
} else if (type === 'tubo') {
area = (Math.PI * dim2 * dim1) / 1000000;
} else if (type === 'rhs') {
const perimeter = 2 * (dim2 + dim3);
area = (perimeter * dim1) / 1000000;
}
const totalArea = area * qty;
document.getElementById('paint-area-result').innerHTML = `
<div class="result-box">
<div class="result-title">Área de Pintura</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Área Unitária</div>
<div class="result-value">${area.toFixed(2)} m²</div>
</div>
<div class="result-item">
<div class="result-label">Área Total</div>
<div class="result-value">${totalArea.toFixed(2)} m²</div>
</div>
</div>
</div>
`;
document.getElementById('tinta-area').value = totalArea.toFixed(2);
addToHistory('Área de Pintura', `${totalArea.toFixed(2)}m² (${qty} unidades)`);
// Add button to send to budget
const resultDiv = document.getElementById('paint-area-result');
const existingButton = resultDiv.querySelector('.add-to-budget-btn');
if (!existingButton) {
const button = document.createElement('button');
button.className = 'btn btn-success add-to-budget-btn';
button.style.marginTop = '16px';
button.textContent = '💰 Adicionar ao Orçamento';
button.onclick = () => addAreaPinturaToOrcamento(totalArea, type, dim1, dim2);
resultDiv.querySelector('.result-box').appendChild(button);
}
}
function addAreaPinturaToOrcamento(area, type, dim1, dim2) {
// Switch to orcamento section
showSection('orcamento');
// Set values
setTimeout(() => {
document.getElementById('budget-category').value = 'servico';
updateBudgetTypeOptions();
setTimeout(() => {
const qtyInput = document.getElementById('budget-qty');
const priceInput = document.getElementById('budget-price');
const unitInput = document.getElementById('budget-unit');
qtyInput.value = area.toFixed(2);
unitInput.value = 'm²';
priceInput.value = '40.00';
priceInput.removeAttribute('readonly');
priceInput.style.background = 'var(--color-surface)';
updateBudgetTotal();
alert(`✅ Dados transferidos para Orçamento!\n\nÁrea: ${area.toFixed(2)}\n\nAjuste o preço e clique em Adicionar.`);
}, 200);
}, 300);
}
function calcularConsumoTinta() {
const area = parseFloat(document.getElementById('tinta-area').value) || 0;
const dft = parseFloat(document.getElementById('tinta-dft').value) || 0;
const solids = parseFloat(document.getElementById('tinta-solids').value) || 0;
const loss = parseFloat(document.getElementById('tinta-loss').value) || 0;
const coats = parseInt(document.getElementById('tinta-coats').value) || 1;
const cost = parseFloat(document.getElementById('tinta-cost').value) || 0;
const volumeTheoretical = (dft * area) / (1000 * (solids / 100));
const volumeWithLoss = volumeTheoretical / (1 - loss / 100);
const volumePerCoat = volumeWithLoss;
const volumeTotal = volumePerCoat * coats;
const totalCost = volumeTotal * cost;
document.getElementById('tinta-result').innerHTML = `
<div class="result-box">
<div class="result-title">Consumo de Tinta</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Volume Teórico</div>
<div class="result-value">${volumeTheoretical.toFixed(2)} L</div>
</div>
<div class="result-item">
<div class="result-label">Volume por Demão</div>
<div class="result-value">${volumePerCoat.toFixed(2)} L</div>
</div>
<div class="result-item">
<div class="result-label">Volume Total</div>
<div class="result-value">${volumeTotal.toFixed(2)} L</div>
</div>
<div class="result-item">
<div class="result-label">Custo Total</div>
<div class="result-value">R$ ${totalCost.toFixed(2)}</div>
</div>
</div>
</div>
`;
addToHistory('Consumo de Tinta', `${volumeTotal.toFixed(2)}L para ${area}`);
}
function calcularGalvanizacao() {
const env = document.getElementById('galv-env').value;
const area = parseFloat(document.getElementById('galv-area').value) || 0;
const thickness = parseFloat(document.getElementById('galv-thickness').value) || 85;
const corrosionRate = {
'interno': 0.5,
'urbano': 1.5,
'marinho': 3.0,
'industrial': 2.5
};
const rate = corrosionRate[env] || 1.5;
const lifeYears = thickness / rate;
const zincDensity = 7140;
const zincMass = (area * thickness / 1000) * (zincDensity / 1000000);
const zincCost = zincMass * 12;
document.getElementById('galv-result').innerHTML = `
<div class="result-box">
<div class="result-title">Galvanização a Quente</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Taxa de Corrosão</div>
<div class="result-value">${rate.toFixed(1)} μm/ano</div>
</div>
<div class="result-item">
<div class="result-label">Vida Útil Estimada</div>
<div class="result-value">${lifeYears.toFixed(0)} anos</div>
</div>
<div class="result-item">
<div class="result-label">Consumo de Zinco</div>
<div class="result-value">${zincMass.toFixed(2)} kg</div>
</div>
<div class="result-item">
<div class="result-label">Custo Estimado</div>
<div class="result-value">R$ ${(zincCost + area * 180).toFixed(2)}</div>
</div>
</div>
<div class="alert alert-success" style="margin-top: 16px;">
<strong>Normas aplicáveis:</strong> ASTM A123, ISO 1461, NBR 6323
</div>
</div>
`;
addToHistory('Galvanização', `${area}m², ${thickness}μm → ${lifeYears.toFixed(0)} anos`);
}
function adicionarItemOrcamento() {
const type = document.getElementById('budget-type').value;
const spec = document.getElementById('budget-spec').value;
const qty = parseFloat(document.getElementById('budget-qty').value) || 0;
const unit = document.getElementById('budget-unit').value;
const price = parseFloat(document.getElementById('budget-price').value) || 0;
if (!spec || qty <= 0 || price <= 0) {
alert('Preencha todos os campos corretamente');
return;
}
const item = {
id: Date.now(),
type: type,
spec: spec,
qty: qty,
unit: unit,
price: price,
total: qty * price
};
appState.budgetItems.push(item);
atualizarTabelaOrcamento();
document.getElementById('budget-spec').value = '';
document.getElementById('budget-qty').value = '1';
document.getElementById('budget-price').value = '0';
}
function removerItemOrcamento(id) {
appState.budgetItems = appState.budgetItems.filter(item => item.id !== id);
atualizarTabelaOrcamento();
}
function atualizarTabelaOrcamentoV2() {
const tbody = document.getElementById('budget-tbody');
if (appState.budgetItems.length === 0) {
tbody.innerHTML = '<tr><td colspan="8" style="text-align: center; color: var(--color-text-secondary);">Nenhum item adicionado</td></tr>';
} else {
// Group by category
const grouped = {
material: [],
servico: [],
consumivel: [],
indireto: []
};
appState.budgetItems.forEach(item => {
grouped[item.category].push(item);
});
let html = '';
let itemNumber = 1;
Object.keys(grouped).forEach(cat => {
if (grouped[cat].length > 0) {
const catName = {
material: 'MATERIAIS',
servico: 'SERVIÇOS',
consumivel: 'CONSUMÍVEIS',
indireto: 'INDIRETOS'
}[cat];
html += `<tr style="background: var(--color-primary); color: var(--color-btn-primary-text); font-weight: bold;">
<td colspan="8" style="padding: 12px;">📁 ${catName}</td>
</tr>`;
grouped[cat].forEach(item => {
html += `
<tr style="border-bottom: 1px solid var(--color-border);">
<td style="padding: 10px;">${itemNumber++}</td>
<td>${item.category.toUpperCase()}</td>
<td><strong>${item.spec}</strong></td>
<td>${item.qty.toFixed(2)}</td>
<td>${item.unit}</td>
<td>R$ ${item.price.toFixed(2)}</td>
<td style="font-weight: bold; color: var(--color-success);">R$ ${item.total.toFixed(2)}</td>
<td><button class="btn btn-secondary" style="padding: 6px 12px; font-size: 12px;" onclick="removerItemOrcamento(${item.id})">🗑️</button></td>
</tr>
`;
});
}
});
tbody.innerHTML = html;
}
atualizarTotalOrcamentoV2();
}
function atualizarTabelaOrcamento() {
// Legacy function - redirect to new version
atualizarTabelaOrcamentoV2();
}
function atualizarTotalOrcamentoV2() {
// Calculate subtotals by category
const grouped = {
material: 0,
servico: 0,
consumivel: 0,
indireto: 0
};
appState.budgetItems.forEach(item => {
grouped[item.category] += item.total;
});
const subtotal = Object.values(grouped).reduce((sum, val) => sum + val, 0);
const bdi = parseFloat(document.getElementById('budget-bdi').value) || 25;
const bdiValue = subtotal * (bdi / 100);
const total = subtotal + bdiValue;
const resultDiv = document.getElementById('budget-total');
resultDiv.innerHTML = `
<div class="result-box" style="background: var(--color-bg-3); border-left: 4px solid var(--color-success);">
<div class="result-title">📊 RESUMO FINANCEIRO</div>
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; margin-bottom: 16px;">
<strong>Subtotais por Categoria:</strong><br><br>
${grouped.material > 0 ? `<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>📦 Materiais:</span>
<strong>R$ ${grouped.material.toFixed(2)}</strong>
</div>` : ''}
${grouped.servico > 0 ? `<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>🔧 Serviços:</span>
<strong>R$ ${grouped.servico.toFixed(2)}</strong>
</div>` : ''}
${grouped.consumivel > 0 ? `<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>🧰 Consumíveis:</span>
<strong>R$ ${grouped.consumivel.toFixed(2)}</strong>
</div>` : ''}
${grouped.indireto > 0 ? `<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>💼 Indiretos:</span>
<strong>R$ ${grouped.indireto.toFixed(2)}</strong>
</div>` : ''}
<hr style="margin: 12px 0; border: 1px solid var(--color-border);">
<div style="display: flex; justify-content: space-between; font-size: 16px;">
<span><strong>Subtotal Geral:</strong></span>
<strong style="color: var(--color-primary);">R$ ${subtotal.toFixed(2)}</strong>
</div>
</div>
<div style="padding: 16px; background: var(--color-bg-2); border-radius: 8px; margin-bottom: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>BDI (${bdi}%):</span>
<strong>R$ ${bdiValue.toFixed(2)}</strong>
</div>
</div>
<div style="padding: 24px; background: var(--color-bg-3); border-radius: 12px; border: 3px solid var(--color-success); text-align: center;">
<div style="font-size: 14px; color: var(--color-text-secondary); margin-bottom: 8px;">TOTAL DO ORÇAMENTO</div>
<div style="font-size: 42px; font-weight: bold; color: var(--color-success);">R$ ${total.toFixed(2)}</div>
</div>
<div style="margin-top: 20px; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;">
<button class="btn btn-primary" onclick="gerarAnaliseDetalhada()" style="padding: 12px 24px;">📊 Análise Detalhada</button>
<button class="btn btn-primary" onclick="gerarPDFOrcamento()" style="padding: 12px 24px;">📄 Gerar PDF</button>
<button class="btn btn-success" onclick="salvarOrcamento()" style="padding: 12px 24px;">💾 Salvar Orçamento</button>
<button class="btn btn-secondary" onclick="limparOrcamento()" style="padding: 12px 24px;">🗑️ Limpar Tudo</button>
</div>
</div>
`;
}
function atualizarTotalOrcamento() {
// Legacy function - redirect to new version
atualizarTotalOrcamentoV2();
}
function gerarPDFOrcamento() {
const project = document.getElementById('budget-project').value || 'Projeto Sem Nome';
const date = document.getElementById('budget-date').value || '2025-11-07';
const region = document.getElementById('budget-region').value;
alert(`📄 Gerando PDF do Orçamento:\n\nProjeto: ${project}\nData: ${date}\nRegião: ${region}\n\nTotal de Itens: ${appState.budgetItems.length}\n\nEm ambiente real, isto geraria um PDF profissional.`);
addToHistory('PDF Orçamento', `${project} - ${appState.budgetItems.length} itens`);
}
function salvarOrcamento() {
const project = document.getElementById('budget-project').value || 'Projeto Sem Nome';
alert(`💾 Orçamento "${project}" salvo com sucesso!\n\nTotal: R$ ${appState.budgetItems.reduce((sum, item) => sum + item.total, 0).toFixed(2)}`);
addToHistory('Orçamento Salvo', project);
}
function limparOrcamento() {
if (confirm('⚠️ Deseja realmente limpar todo o orçamento?')) {
appState.budgetItems = [];
atualizarTabelaOrcamentoV2();
alert('✅ Orçamento limpo!');
}
}
function gerarAnaliseDetalhada() {
if (appState.budgetItems.length === 0) {
alert('⚠️ Adicione itens ao orçamento primeiro!');
return;
}
// Calculate by category
const grouped = {
material: 0,
servico: 0,
consumivel: 0,
indireto: 0
};
appState.budgetItems.forEach(item => {
grouped[item.category] += item.total;
});
const subtotal = Object.values(grouped).reduce((sum, val) => sum + val, 0);
const bdi = parseFloat(document.getElementById('budget-bdi').value) || 25;
const total = subtotal * (1 + bdi / 100);
// Percentages
const percMaterial = (grouped.material / subtotal) * 100;
const percServico = (grouped.servico / subtotal) * 100;
const percConsumivel = (grouped.consumivel / subtotal) * 100;
const percIndireto = (grouped.indireto / subtotal) * 100;
// Estimate project area (rough estimate)
const estimatedArea = 1500; // m²
const costPerM2 = total / estimatedArea;
// Timeline estimate
const weeks = Math.ceil(appState.budgetItems.length / 2) + 2;
const html = `
<div style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); z-index: 2000; display: flex; align-items: center; justify-content: center; padding: 20px;" onclick="this.remove()">
<div style="background: var(--color-surface); border-radius: 16px; padding: 32px; max-width: 900px; max-height: 90vh; overflow-y: auto; box-shadow: var(--shadow-lg);" onclick="event.stopPropagation()">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px;">
<h2 style="color: var(--color-primary); font-size: 28px;">📊 ANÁLISE DETALHADA DO ORÇAMENTO</h2>
<button onclick="this.closest('div[style*=fixed]').remove()" style="background: none; border: none; font-size: 32px; cursor: pointer; color: var(--color-text-secondary);">×</button>
</div>
<div style="padding: 20px; background: var(--color-bg-1); border-radius: 12px; margin-bottom: 20px;">
<h3 style="margin-bottom: 16px; color: var(--color-primary);">Composição por Categoria</h3>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
${grouped.material > 0 ? `<div style="padding: 12px; background: var(--color-surface); border-radius: 8px;">
<div style="font-size: 12px; color: var(--color-text-secondary);">Materiais</div>
<div style="font-size: 24px; font-weight: bold; color: var(--color-success);">${percMaterial.toFixed(0)}%</div>
<div style="font-size: 14px;">R$ ${grouped.material.toFixed(2)}</div>
</div>` : ''}
${grouped.servico > 0 ? `<div style="padding: 12px; background: var(--color-surface); border-radius: 8px;">
<div style="font-size: 12px; color: var(--color-text-secondary);">Serviços</div>
<div style="font-size: 24px; font-weight: bold; color: var(--color-warning);">${percServico.toFixed(0)}%</div>
<div style="font-size: 14px;">R$ ${grouped.servico.toFixed(2)}</div>
</div>` : ''}
${grouped.consumivel > 0 ? `<div style="padding: 12px; background: var(--color-surface); border-radius: 8px;">
<div style="font-size: 12px; color: var(--color-text-secondary);">Consumíveis</div>
<div style="font-size: 24px; font-weight: bold; color: var(--color-info);">${percConsumivel.toFixed(0)}%</div>
<div style="font-size: 14px;">R$ ${grouped.consumivel.toFixed(2)}</div>
</div>` : ''}
${grouped.indireto > 0 ? `<div style="padding: 12px; background: var(--color-surface); border-radius: 8px;">
<div style="font-size: 12px; color: var(--color-text-secondary);">Indiretos</div>
<div style="font-size: 24px; font-weight: bold; color: var(--color-text);">${percIndireto.toFixed(0)}%</div>
<div style="font-size: 14px;">R$ ${grouped.indireto.toFixed(2)}</div>
</div>` : ''}
</div>
</div>
<div style="padding: 20px; background: var(--color-bg-3); border-radius: 12px; margin-bottom: 20px;">
<h3 style="margin-bottom: 16px; color: var(--color-success);">Custo por Área</h3>
<p>Considerando área estimada de <strong>${estimatedArea} m²</strong>:</p>
<div style="font-size: 32px; font-weight: bold; color: var(--color-success); margin: 12px 0;">R$ ${costPerM2.toFixed(2)}/m²</div>
<p style="font-size: 12px; color: var(--color-text-secondary);">Este valor é uma média estimada baseada no orçamento total</p>
</div>
<div style="padding: 20px; background: var(--color-bg-6); border-radius: 12px; margin-bottom: 20px;">
<h3 style="margin-bottom: 16px; color: var(--color-warning);">Cronograma Estimado</h3>
<ul style="list-style: none; padding: 0;">
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">✅ Semana 1: Fornecimento de Materiais</li>
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">✅ Semana 2-${Math.min(weeks-2, 3)}: Fabricação</li>
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">✅ Semana ${Math.min(weeks-1, 4)}-${weeks}: Montagem e Soldagem</li>
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">✅ Semana ${weeks+1}: Pintura e Acabamento</li>
<li style="padding: 8px 0;">✅ Semana ${weeks+2}: Inspeção Final</li>
</ul>
<p style="margin-top: 12px; font-weight: bold;">Prazo Total Estimado: ${weeks+2} semanas</p>
</div>
<div style="padding: 20px; background: var(--color-bg-5); border-radius: 12px;">
<h3 style="margin-bottom: 16px; color: #a855f7;">Fornecedores Envolvidos</h3>
<ul style="list-style: none; padding: 0;">
${grouped.material > 0 ? '<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">🏭 <strong>Gerdau/Usiminas</strong> - Perfis e Chapas</li>' : ''}
${grouped.consumivel > 0 && appState.budgetItems.some(i => i.spec.includes('E70') || i.spec.includes('E60')) ? '<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">🔥 <strong>Esab/Lincoln</strong> - Eletrodos</li>' : ''}
${grouped.consumivel > 0 && appState.budgetItems.some(i => i.spec.includes('TINTA')) ? '<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">🎨 <strong>Sherwin-Williams/Coral</strong> - Tintas</li>' : ''}
${grouped.consumivel > 0 && appState.budgetItems.some(i => i.spec.includes('Parafuso')) ? '<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">🔩 <strong>Distribuidores Locais</strong> - Parafusos</li>' : ''}
${grouped.servico > 0 ? '<li style="padding: 8px 0;">👷 <strong>Mão de Obra Especializada</strong> - Soldadores e Montadores</li>' : ''}
</ul>
</div>
<div style="text-align: center; margin-top: 24px;">
<button class="btn btn-primary" onclick="this.closest('div[style*=fixed]').remove()" style="padding: 12px 32px;">Fechar Análise</button>
</div>
</div>
</div>
`;
document.body.insertAdjacentHTML('beforeend', html);
addToHistory('Análise Orçamento', `${appState.budgetItems.length} itens, R$ ${total.toFixed(2)}`);
}
function carregarOrcamentoExemplo() {
if (appState.budgetItems.length > 0) {
if (!confirm('Já existem itens no orçamento. Deseja substituí-los com o exemplo?')) {
return;
}
}
// Clear existing items
appState.budgetItems = [];
// Example budget items
const exampleItems = [
{id: Date.now() + 1, category: 'material', type: 'perfil_w', spec: 'W250×38', qty: 50, unit: 'm', price: 285, total: 14250},
{id: Date.now() + 2, category: 'material', type: 'chapa', spec: 'CHAPA 9.5mm', qty: 200, unit: 'm²', price: 74.6, total: 14920},
{id: Date.now() + 3, category: 'material', type: 'cantoneira', spec: 'L100×100×10', qty: 80, unit: 'm', price: 112.5, total: 9000},
{id: Date.now() + 4, category: 'consumivel', type: 'consumiveis', spec: 'E7018 (Eletrodo)', qty: 50, unit: 'kg', price: 45, total: 2250},
{id: Date.now() + 5, category: 'consumivel', type: 'consumiveis', spec: 'TINTA C3 Epóxi', qty: 100, unit: 'L', price: 80, total: 8000},
{id: Date.now() + 6, category: 'consumivel', type: 'parafusos', spec: 'Parafuso A325 M16', qty: 200, unit: 'un', price: 1.20, total: 240},
{id: Date.now() + 7, category: 'servico', type: 'servico_custom', spec: 'Soldagem', qty: 1000, unit: 'h', price: 65, total: 65000},
{id: Date.now() + 8, category: 'servico', type: 'servico_custom', spec: 'Pintura', qty: 500, unit: 'm²', price: 40, total: 20000},
{id: Date.now() + 9, category: 'indireto', type: 'indireto_custom', spec: 'Transporte', qty: 1, unit: 'un', price: 5000, total: 5000},
{id: Date.now() + 10, category: 'indireto', type: 'indireto_custom', spec: 'EPI e Segurança', qty: 1, unit: 'un', price: 2000, total: 2000}
];
appState.budgetItems = exampleItems;
atualizarTabelaOrcamentoV2();
alert('✅ Orçamento exemplo carregado com sucesso!\n\n10 itens adicionados\nTotal: R$ 140.660,00');
}
function updateWeightFields() {
const typeSelect = document.getElementById('weight-type');
const field3 = document.getElementById('weight-field3');
const field4 = document.getElementById('weight-field4');
const label1 = document.getElementById('weight-label1');
const label2 = document.getElementById('weight-label2');
const label3 = document.getElementById('weight-label3');
// Verificar se os elementos existem
if (!typeSelect || !field3 || !field4 || !label1 || !label2) return;
const type = typeSelect.value;
if (type === 'perfilW') {
label1.textContent = 'Altura (mm)';
label2.textContent = 'Comprimento (m)';
field3.style.display = 'none';
field4.style.display = 'none';
} else if (type === 'chapa') {
label1.textContent = 'Largura (mm)';
label2.textContent = 'Altura (mm)';
if (label3) label3.textContent = 'Espessura (mm)';
field3.style.display = 'block';
field4.style.display = 'none';
} else if (type === 'tubo') {
label1.textContent = 'Diâmetro Externo (mm)';
label2.textContent = 'Comprimento (m)';
if (label3) label3.textContent = 'Espessura Parede (mm)';
field3.style.display = 'block';
field4.style.display = 'none';
} else if (type === 'barra') {
label1.textContent = 'Diâmetro (mm)';
label2.textContent = 'Comprimento (m)';
field3.style.display = 'none';
field4.style.display = 'none';
}
}
function calcularPeso() {
const type = document.getElementById('weight-type').value;
const dim1 = parseFloat(document.getElementById('weight-dim1').value) || 0;
const dim2 = parseFloat(document.getElementById('weight-dim2').value) || 0;
const dim3 = parseFloat(document.getElementById('weight-dim3').value) || 0;
let weight = 0;
if (type === 'perfilW') {
weight = (dim1 / 100) * 31.8 * dim2;
} else if (type === 'chapa') {
weight = (dim1 / 1000) * (dim2 / 1000) * (dim3 / 1000) * 7850;
} else if (type === 'tubo') {
const dExt = dim1;
const dInt = dExt - 2 * dim3;
const area = Math.PI * (Math.pow(dExt/2, 2) - Math.pow(dInt/2, 2));
weight = area / 1000000 * dim2 * 7850;
} else if (type === 'barra') {
const area = Math.PI * Math.pow(dim1/2, 2);
weight = area / 1000000 * dim2 * 7850;
}
document.getElementById('weight-result').innerHTML = `
<div class="result-box">
<div class="result-title">Cálculo de Peso</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Peso Total</div>
<div class="result-value">${weight.toFixed(2)} kg</div>
</div>
</div>
</div>
`;
document.getElementById('rigging-weight').value = weight.toFixed(0);
addToHistory('Cálculo de Peso', `${weight.toFixed(2)}kg`);
}
function calcularRigging() {
const weight = parseFloat(document.getElementById('rigging-weight').value) || 0;
const points = parseInt(document.getElementById('rigging-points').value) || 2;
const angle = parseInt(document.getElementById('rigging-angle').value) || 60;
const fs = parseFloat(document.getElementById('rigging-fs').value) || 4;
const angleRad = angle * Math.PI / 180;
const forcePerCable = (weight * 9.81 / 1000) / (points * Math.cos(angleRad)) * fs;
const cableSteelCapacity = 21;
const chainCapacity = 15;
const syntheticCapacity = 12;
let recommendation = '';
let alertClass = 'alert-success';
if (forcePerCable <= syntheticCapacity) {
recommendation = '✅ Cabo sintético (12 kN)';
} else if (forcePerCable <= chainCapacity) {
recommendation = '✅ Corrente grau 80 (15 kN)';
} else if (forcePerCable <= cableSteelCapacity) {
recommendation = '⚠️ Cabo de aço (21 kN)';
alertClass = 'alert-warning';
} else {
recommendation = '❌ Requer cabo especial ou mais pontos de içamento';
alertClass = 'alert-error';
}
document.getElementById('rigging-result').innerHTML = `
<div class="result-box">
<div class="result-title">Plano de Rigging</div>
<div class="result-grid">
<div class="result-item">
<div class="result-label">Força por Cabo</div>
<div class="result-value">${forcePerCable.toFixed(1)} kN</div>
</div>
<div class="result-item">
<div class="result-label">Ângulo</div>
<div class="result-value">${angle}°</div>
</div>
<div class="result-item">
<div class="result-label">Fator Segurança</div>
<div class="result-value">${fs}</div>
</div>
</div>
<div class="alert ${alertClass}" style="margin-top: 16px;">
<strong>Recomendação: ${recommendation}</strong>
</div>
</div>
`;
addToHistory('Rigging', `${weight}kg, ${points} pontos, ${angle}° → ${forcePerCable.toFixed(1)}kN/cabo`);
}
// ========================================
// BUDGET v6.6 FUNCTIONS WITH CSV INTEGRATION
// ========================================
function updateBudgetTypeOptions() {
const category = document.getElementById('budget-category').value;
const typeSelect = document.getElementById('budget-type');
let options = '<option value="">Selecione...</option>';
if (category === 'material') {
options += '<option value="perfil_w">Perfil W</option>';
options += '<option value="perfil_i">Perfil I (IPE)</option>';
options += '<option value="perfil_hp">Perfil HP</option>';
options += '<option value="cantoneira">Cantoneira</option>';
options += '<option value="tubo_circ">Tubo Circular</option>';
options += '<option value="tubo_rhs">Tubo Retangular (RHS)</option>';
options += '<option value="chapa">Chapa</option>';
options += '<option value="barra">Barra Redonda</option>';
} else if (category === 'consumivel') {
options += '<option value="eletrodo">Eletrodos</option>';
options += '<option value="parafuso">Parafusos</option>';
options += '<option value="tinta">Tintas</option>';
} else if (category === 'servico') {
options += '<option value="servico_custom">Serviço Customizado</option>';
} else if (category === 'indireto') {
options += '<option value="indireto_custom">Custo Indireto</option>';
}
typeSelect.innerHTML = options;
updateBudgetSpecOptions();
}
async function updateBudgetSpecOptions() {
const type = document.getElementById('budget-type').value;
const specSelect = document.getElementById('budget-spec');
const productInfo = document.getElementById('product-info-display');
specSelect.innerHTML = '<option value="">Selecione...</option>';
productInfo.style.display = 'none';
if (!type || type.includes('custom')) {
return;
}
// Show loading state
specSelect.innerHTML = '<option value="">Carregando...</option>';
// Load data from CSV
const dados = await carregarCSV(type);
specSelect.innerHTML = '<option value="">Selecione...</option>';
dados.forEach(item => {
const option = document.createElement('option');
option.value = item.id;
option.textContent = item.nome;
option.dataset.itemData = JSON.stringify(item);
specSelect.appendChild(option);
});
if (dados.length === 0) {
specSelect.innerHTML = '<option value="">Nenhum item encontrado</option>';
}
}
function autoFillBudgetData() {
const specSelect = document.getElementById('budget-spec');
const selectedOption = specSelect.options[specSelect.selectedIndex];
if (!selectedOption || !selectedOption.value) {
document.getElementById('product-info-display').style.display = 'none';
return;
}
const itemData = JSON.parse(selectedOption.dataset.itemData || '{}');
const type = document.getElementById('budget-type').value;
const region = document.getElementById('budget-region').value;
// Display product info
const productDetails = document.getElementById('product-details');
const productInfo = document.getElementById('product-info-display');
let detailsHtml = `<strong>${itemData.nome}</strong><br>`;
if (itemData.peso_kg_m) {
detailsHtml += `Peso: ${itemData.peso_kg_m} kg/m<br>`;
}
if (itemData.altura_mm) {
detailsHtml += `Altura: ${itemData.altura_mm} mm<br>`;
}
if (itemData.diametro_mm) {
detailsHtml += `Diâmetro: ${itemData.diametro_mm} mm<br>`;
}
if (itemData.espessura_mm) {
detailsHtml += `Espessura: ${itemData.espessura_mm} mm<br>`;
}
productDetails.innerHTML = detailsHtml;
productInfo.style.display = 'block';
// Auto-fill unit
const unitInput = document.getElementById('budget-unit');
unitInput.value = itemData.unidade || 'm';
// Calculate and fill price
const priceInput = document.getElementById('budget-price');
let price = 0;
if (itemData.custo_kg) {
price = parseFloat(itemData.custo_kg);
} else if (itemData.custo_unitario_r) {
price = parseFloat(itemData.custo_unitario_r);
} else if (itemData.custo_litro_r) {
price = parseFloat(itemData.custo_litro_r);
} else if (itemData.peso_kg_m && regionalPricing[region]) {
const categoryKey = type.replace('perfil_', '').replace('tubo_', '');
const pricePerKg = regionalPricing[region][type] || regionalPricing[region][categoryKey] || 7.5;
price = parseFloat(itemData.peso_kg_m) * pricePerKg;
}
priceInput.value = price.toFixed(2);
priceInput.removeAttribute('readonly');
priceInput.style.background = 'var(--color-surface)';
updateBudgetTotal();
}
function updateBudgetTotal() {
const qty = parseFloat(document.getElementById('budget-qty').value) || 0;
const price = parseFloat(document.getElementById('budget-price').value) || 0;
const total = qty * price;
document.getElementById('budget-item-total').value = `R$ ${total.toFixed(2)}`;
}
function adicionarItemOrcamentoV2() {
const category = document.getElementById('budget-category').value;
const type = document.getElementById('budget-type').value;
const specSelect = document.getElementById('budget-spec');
const spec = specSelect.options[specSelect.selectedIndex]?.text || 'Item Customizado';
const qty = parseFloat(document.getElementById('budget-qty').value) || 0;
const unit = document.getElementById('budget-unit').value;
const price = parseFloat(document.getElementById('budget-price').value) || 0;
if (!type || qty <= 0 || price <= 0) {
alert('⚠️ Preencha todos os campos corretamente:\n\n- Tipo de Produto\n- Quantidade > 0\n- Preço > 0');
return;
}
const item = {
id: Date.now(),
category: category,
type: type,
spec: spec,
qty: qty,
unit: unit,
price: price,
total: qty * price
};
appState.budgetItems.push(item);
atualizarTabelaOrcamentoV2();
// Clear form
document.getElementById('budget-spec').value = '';
document.getElementById('budget-qty').value = '1';
document.getElementById('budget-price').value = '0';
document.getElementById('product-info-display').style.display = 'none';
alert('✅ Item adicionado ao orçamento com sucesso!');
}
function updateRegionalPricing() {
// Trigger price recalculation when region changes
const specSelect = document.getElementById('budget-spec');
if (specSelect && specSelect.value) {
autoFillBudgetData();
}
}
// Initialize budget on load
function initializeBudget() {
if (document.getElementById('budget-region')) {
updateBudgetTypeOptions();
updateBudgetSpecOptions();
}
}
// Removido: funções de modal Admin legado (openAdminModal/closeAdminModal)
// Preview functions for customization
function previewColorScheme(scheme) {
userPreferences.colorScheme = scheme;
applyUserPreferences();
savePreferences();
}
function previewFontSize(size) {
userPreferences.fontSize = size;
applyUserPreferences();
savePreferences();
}
function previewFontFamily(family) {
userPreferences.fontFamily = family;
applyUserPreferences();
savePreferences();
}
// Load admin preferences into form
function loadAdminPreferences() {
const colorScheme = document.getElementById('adminColorScheme');
const fontSize = document.getElementById('adminFontSize');
const fontFamily = document.getElementById('adminFontFamily');
const themeDefault = document.getElementById('adminThemeDefault');
const modeDefault = document.getElementById('adminModeDefault');
if (colorScheme) colorScheme.value = userPreferences.colorScheme;
if (fontSize) fontSize.value = userPreferences.fontSize;
if (fontFamily) fontFamily.value = userPreferences.fontFamily;
if (themeDefault) themeDefault.value = userPreferences.theme === 'dark' ? 'escuro' : 'claro';
if (modeDefault) modeDefault.value = appState.expertMode ? 'expert' : 'simples';
}
// Save admin preferences when form changes
function saveAdminPreferences() {
const themeDefault = document.getElementById('adminThemeDefault');
const modeDefault = document.getElementById('adminModeDefault');
if (themeDefault) {
const newTheme = themeDefault.value === 'escuro' ? 'dark' : 'light';
if (newTheme !== userPreferences.theme) {
userPreferences.theme = newTheme;
appState.currentTheme = newTheme;
applyTheme();
savePreferences();
}
}
if (modeDefault) {
const newMode = modeDefault.value === 'expert';
if (newMode !== appState.expertMode) {
appState.expertMode = newMode;
filterToolsByMode();
}
}
}
// Removido: saveAdminConfig legado. Configuração agora é gerenciada por AdminConfigManager
// Removido: resetAdminDefaults legado. Reset é feito via AdminConfigManager.resetConfig()
function applyAdminConfig() {
// Update branding elements
const logoEl = document.getElementById('appLogo');
const subtitleEl = document.getElementById('appSubtitle');
const footerEl = document.getElementById('appFooter');
if (logoEl) {
if (adminConfig?.branding?.logo) {
logoEl.innerHTML = `<img src="${adminConfig.branding.logo}" alt="Logo" class="app-logo-img">`;
} else {
logoEl.textContent = '🏗️ ' + adminConfig.appName;
}
}
if (subtitleEl) subtitleEl.textContent = adminConfig.appSubtitle;
if (footerEl) {
const p = footerEl.querySelector('p');
if (p) p.textContent = adminConfig.footerText;
}
// Update page title
document.title = '🏗️ ' + adminConfig.appName + ' - Plataforma Técnica';
// Apply theme
if (adminConfig.themeDefault === 'escuro') {
appState.currentTheme = 'dark';
} else {
appState.currentTheme = 'light';
}
applyTheme();
// Apply mode
if (adminConfig.modeDefault === 'expert' && !appState.expertMode) {
toggleExpertMode();
} else if (adminConfig.modeDefault === 'simples' && appState.expertMode) {
toggleExpertMode();
}
// Filter tools
filterToolsByMode();
}
// ========================================
// HELP SYSTEM & USER MANUAL
// ========================================
let currentHelpSection = null;
const ajudaDatabase = {
cev: {
titulo: '⛗️ CEV Avançado (IIW + Pcm)',
oQueE: 'CEV (Carbono Equivalente) é um valor calculado que representa a capacidade de endurecimento de um aço durante a soldagem. Valores mais altos indicam maior dificuldade de soldagem e maior risco de trincas.',
paraQueServe: 'Determinar a dificuldade de soldagem de um aço e recomendar: temperatura de pré-aquecimento necessária, velocidade de soldagem, tipo de eletrodo apropriado e necessidade de PWHT (tratamento térmico pós-soldagem).',
quandoUsar: 'Sempre que for soldar um aço estrutural ou de alta resistência para verificar a soldabilidade e determinar os cuidados necessários antes de iniciar o processo.',
avisos: [
'CEV é apenas um indicador - sempre consulte o fabricante do aço',
'Valores altos (>0.55) requerem rigoroso controle de processo',
'Não substitui ensaios de qualidade na prática',
'Considere ambiente, espessura e restrição da junta'
],
campos: [
{ nome: 'Carbono (C)', unidade: '%', significado: 'Elemento principal que aumenta dureza e reduz ductilidade', intervalo: '0.15-0.35', dica: 'Valores mais altos = mais difícil soldar' },
{ nome: 'Manganês (Mn)', unidade: '%', significado: 'Aumenta resistência e temperabilidade', intervalo: '0.80-1.50', dica: 'Fator multiplicador do carbono' },
{ nome: 'Cromo (Cr)', unidade: '%', significado: 'Aumenta resistência à corrosão e dureza', intervalo: '0.05-0.20', dica: 'Elemento de liga menor' },
{ nome: 'Molibdênio (Mo)', unidade: '%', significado: 'Aumenta temperabilidade', intervalo: '0.02-0.10', dica: 'Forte efeito na temperabilidade' },
{ nome: 'Vanádio (V)', unidade: '%', significado: 'Aumenta resistência e dureza', intervalo: '0.02-0.05', dica: 'Elemento de liga menor' },
{ nome: 'Níquel (Ni)', unidade: '%', significado: 'Aumenta tenacidade e resistência ao impacto', intervalo: '0.05-0.15', dica: 'Melhora ductilidade' },
{ nome: 'Cobre (Cu)', unidade: '%', significado: 'Aumenta resistência à corrosão atmosférica', intervalo: '0.05-0.15', dica: 'Residual do processo' },
{ nome: 'Espessura', unidade: 'mm', significado: 'Quanto mais espesso, maior resfriamento = maior dureza', intervalo: '10-50', dica: 'Chapa mais espessa = maior pré-aquecimento' }
],
resultados: '<h4>CEV IIW (Instituto Internacional de Soldagem)</h4><p><strong>Fórmula:</strong> CEV = C + (Mn/6) + (Cr+Mo+V)/5 + (Ni+Cu)/15</p><p><strong>Interpretação:</strong></p><ul><li>&lt;0.35: Excelente soldabilidade, sem pré-aquecimento</li><li>0.35-0.45: Boa soldabilidade, considerar pré-aquecimento</li><li>0.45-0.55: Soldabilidade moderada, pré-aquecimento necessário</li><li>&gt;0.55: Soldabilidade difícil, controle rigoroso necessário</li></ul>',
referencias: [
{ titulo: 'IIW - Classification of high strength weld metals', ano: 1988, url: 'https://www.iiw.net' },
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020, url: 'https://www.aws.org' },
{ titulo: 'NBR 16239 - Soldagem de Aços', ano: 2013 }
],
manualRelacionado: ['aco_introducao', 'cev_entendimento', 'preaquecimento_guia']
},
preaquecimento: {
titulo: '🔥 Pré-Aquecimento AWS D1.1',
oQueE: 'Pré-aquecimento é o processo de elevar a temperatura do material base antes da soldagem para reduzir a taxa de resfriamento e aumentar a ductilidade, prevenindo trincas.',
paraQueServe: 'Prevenir trincas por resfriamento rápido em aços com alto CEV ou em seções espessas, controlando a formação de estruturas metastabiláveis como martensita.',
quandoUsar: 'Quando o CEV > 0.35, temperatura ambiente < 5°C, espessura > 20mm, ou conforme especificação do projeto.',
avisos: [
'Aplicar pré-aquecimento de forma uniforme em toda a zona afetada pelo calor',
'Medir com termômetro de contato para garantir temperatura correta',
'Manter interpass durante toda a soldagem',
'Não exceder 200°C de temperatura máxima'
],
campos: [
{ nome: 'CEV', unidade: '-', significado: 'Carbono Equivalente do aço', intervalo: '0.2-0.8', dica: 'Calcule com a ferramenta CEV Avançado' },
{ nome: 'Espessura', unidade: 'mm', significado: 'Espessura da chapa ou seção', intervalo: '5-100', dica: 'Seções maiores exigem mais pré-aq' },
{ nome: 'Temperatura Ambiente', unidade: '°C', significado: 'Temperatura do local de soldagem', intervalo: '-10 a 40', dica: 'Frio aumenta necessidade de pré-aq' },
{ nome: 'Tipo de Junta', unidade: '-', significado: 'Configuração da junta', intervalo: 'Simples/Dupla', dica: 'Junta dupla restringe mais' },
{ nome: 'Restrição', unidade: '-', significado: 'Liberdade de movimento do material', intervalo: 'Baixa/Média/Alta', dica: 'Maior restrição = mais pré-aq' }
],
resultados: '<h4>Temperatura de Pré-aquecimento</h4><p><strong>Fórmula AWS D1.1:</strong> T_preaq = 50 + (CEV × 50) + (Espessura/10 × 20)</p><p><strong>Interpass:</strong> Temperatura entre passes: Pré-aq + 25°C (máximo 200°C)</p>',
referencias: [
{ titulo: 'AWS D1.1 - Structural Welding Code - Steel', ano: 2020, url: 'https://www.aws.org' },
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 }
],
manualRelacionado: ['cev_entendimento', 'soldagem_introducao', 'preaquecimento_guia']
},
parafusos: {
titulo: '🔩 Ligações Parafusadas',
oQueE: 'Ligações parafusadas são conexões mecânicas que utilizam parafusos de alta resistência para transmitir forças entre elementos estruturais.',
paraQueServe: 'Dimensionar conexões seguras e verificar capacidade ao cisalhamento, esmagamento e ruptura em bloco conforme NBR 8800 e AISC 360.',
quandoUsar: 'Quando necessitar de conexões desmontáveis, rápida montagem em campo, ou quando soldagem não é viável.',
avisos: [
'Verificar todos os modos de falha: cisalhamento, esmagamento e bloco',
'Respeitar distâncias mínimas de borda (1.5d)',
'Espaçamento mínimo entre furos (2.67d)',
'Usar torque adequado na instalação'
],
campos: [
{ nome: 'Tipo de Parafuso', unidade: '-', significado: 'Classe de resistência (A325, A490, ISO 8.8, ISO 10.9)', intervalo: 'A325/A490', dica: 'A325 é padrão para estruturas' },
{ nome: 'Diâmetro', unidade: 'mm', significado: 'Diâmetro nominal do parafuso', intervalo: '12-24', dica: 'Diâmetros maiores = maior capacidade' },
{ nome: 'Quantidade', unidade: 'un', significado: 'Número de parafusos na ligação', intervalo: '1-20', dica: 'Distribua uniformemente' },
{ nome: 'Planos de Corte', unidade: '-', significado: 'Quantidade de interfaces cisalhadas', intervalo: '1-2', dica: '2 planos dobra a capacidade' },
{ nome: 'Força Aplicada', unidade: 'kN', significado: 'Força total a ser transmitida', intervalo: '10-500', dica: 'Força de cálculo (fatorada)' }
],
resultados: '<h4>Capacidade ao Cisalhamento</h4><p><strong>Fórmula:</strong> Fv = 0.6 × fy × A × n_planos</p><p>Verifica se capacidade total &gt; força aplicada</p><h4>Verificações Adicionais</h4><ul><li>Esmagamento da chapa</li><li>Ruptura em bloco de cisalhamento</li><li>Distâncias mínimas NBR 8800</li></ul>',
referencias: [
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 },
{ titulo: 'AISC 360-16 - Specification for Structural Steel Buildings', ano: 2016, url: 'https://www.aisc.org' }
],
manualRelacionado: ['parafusos_basico', 'cisalhamento_analise']
},
'consumo-tinta': {
titulo: '🎯 Consumo de Tinta',
oQueE: 'Consumo de tinta é o volume total (em litros) de tinta necessária para pintar uma área com determinada espessura seca (DFT).',
paraQueServe: 'Calcular a quantidade de tinta para orçamentos e planejar compras de material, considerando perdas e número de demãos.',
quandoUsar: 'Sempre na fase inicial de planejamento de um projeto de pintura, após calcular a área total a pintar.',
avisos: [
'Não esqueça de adicionar perda de 15-25% por respingos e cantos',
'DFT mínimo garante durabilidade adequada',
'Cada demão requer intervalo mínimo antes da próxima',
'Verifique % de sólidos na ficha técnica da tinta'
],
campos: [
{ nome: 'Área Total', unidade: 'm²', significado: 'Área a pintar', intervalo: '10-10000', dica: 'Use ferramenta de cálculo de área antes' },
{ nome: 'DFT', unidade: 'μm', significado: 'Dry Film Thickness - Espessura da película seca', intervalo: '80-250', dica: 'Confira norma ISO 12944 para sua aplicação' },
{ nome: '% Sólidos', unidade: '%', significado: 'Percentual de sólidos na tinta', intervalo: '30-95', dica: 'Tipicamente 60% para epóxis' },
{ nome: 'Número de Demãos', unidade: '-', significado: 'Quantas camadas serão aplicadas', intervalo: '1-4', dica: 'Mais camadas = melhor proteção' },
{ nome: 'Perdas', unidade: '%', significado: 'Percentual de perda por respingos e cantos', intervalo: '5-25', dica: 'Tipicamente 15%' }
],
resultados: '<h4>Cálculo do Volume</h4><p><strong>V_teórico = (DFT × Área) / (1000 × % Sólidos)</strong></p><p><strong>V_com_perdas = V_teórico / (1 - % Perdas)</strong></p><p><strong>V_total = V_com_perdas × Número de Demãos</strong></p>',
referencias: [
{ titulo: 'ISO 12944 - Paints and Coatings - Corrosion Protection', ano: 2018, url: 'https://www.iso.org' },
{ titulo: 'ASTM D3276 - Standard Practice for Paint Application', ano: 2021 }
],
manualRelacionado: ['pintura_introducao', 'iso12944']
},
dureza: {
titulo: '🔨 Conversor de Dureza',
oQueE: 'Conversor que transforma valores entre diferentes escalas de dureza (Brinell, Rockwell C e Vickers) usando correlações normativas.',
paraQueServe: 'Permitir comparação de valores de dureza medidos em diferentes escalas e estimar propriedades mecânicas do material.',
quandoUsar: 'Quando tiver medida em uma escala e precisar converter para outra, ou quando quiser estimar resistência a partir da dureza.',
avisos: [
'Conversões são aproximadas, use como referência',
'Para aços carbonos, conversões são mais precisas',
'HRC só é válido para HB > 200',
'Estimativas de resistência são aproximadas'
],
campos: [
{ nome: 'Brinell (HB)', unidade: 'HB', significado: 'Dureza Brinell - teste com esfera', intervalo: '100-650', dica: 'Mais comum em certificados' },
{ nome: 'Rockwell C (HRC)', unidade: 'HRC', significado: 'Dureza Rockwell C - teste com cone de diamante', intervalo: '20-70', dica: 'Comum em ferramentas' },
{ nome: 'Vickers (HV)', unidade: 'HV', significado: 'Dureza Vickers - teste com pirâmide', intervalo: '100-1000', dica: 'Versátil para todos os materiais' }
],
resultados: '<h4>Conversões</h4><p><strong>HRC = HB × 0.0338 - 9.8</strong></p><p><strong>HV = HB × 0.95</strong></p><h4>Estimativa de Resistência</h4><p><strong>fu ≈ HB × 10 MPa</strong></p>',
referencias: [
{ titulo: 'ASTM E140 - Hardness Conversion Tables', ano: 2019 },
{ titulo: 'ISO 18265 - Conversion of hardness values', ano: 2013 }
],
manualRelacionado: ['ensaios_introducao', 'dureza_escalas']
},
charpy: {
titulo: '📉 Análise de Charpy',
oQueE: 'Análise que gera a curva de transição dúctil-frágil a partir de ensaios de impacto Charpy em diferentes temperaturas.',
paraQueServe: 'Determinar a temperatura de transição dúctil-frágil (TTDF) e avaliar se o material é adequado para serviço em baixas temperaturas.',
quandoUsar: 'Para estruturas que operam em baixas temperaturas, estruturas offshore, pontes em regiões frias, ou quando especificado em projeto.',
avisos: [
'Insira pelo menos 2 pontos temperatura/energia',
'Ideal: 4 pontos cobrindo ampla faixa de temperatura',
'TTDF ideal deve ser menor que temperatura de serviço',
'Energia mínima 27J @ temperatura de projeto'
],
campos: [
{ nome: 'Temperatura', unidade: '°C', significado: 'Temperatura do ensaio Charpy', intervalo: '-60 a +40', dica: 'Cubra ampla faixa de temperatura' },
{ nome: 'Energia', unidade: 'J', significado: 'Energia absorvida no impacto', intervalo: '5-150', dica: 'Valores altos = mais tenáz' }
],
resultados: '<h4>Curva de Transição</h4><p>Gráfico mostra como energia absorvida varia com temperatura</p><p><strong>TTDF (27J):</strong> Temperatura onde energia = 27J</p><p>Material é dúctil acima da TTDF e frágil abaixo</p>',
referencias: [
{ titulo: 'ASTM E23 - Standard Test Methods for Notched Bar Impact Testing', ano: 2018, url: 'https://www.astm.org' },
{ titulo: 'ISO 148-1 - Charpy pendulum impact test', ano: 2016 }
],
manualRelacionado: ['ensaios_introducao', 'impacto_charpy']
},
orcamento: {
titulo: '💵 Orçamento Detalhado',
oQueE: 'Sistema completo de orçamento com base de dados integrada de materiais brasileiros (100+ produtos) e preços regionais.',
paraQueServe: 'Criar orçamentos detalhados de projetos de estruturas metálicas com materiais, serviços, consumíveis e custos indiretos.',
quandoUsar: 'Na fase de proposta comercial ou planejamento de compras de um projeto estrutural.',
avisos: [
'Selecione a região correta (preços variam)',
'BDI/Margem deve cobrir custos indiretos e lucro',
'Verifique preços atualizados com fornecedores',
'Adicione itens indiretos (transporte, EPI, etc)'
],
campos: [
{ nome: 'Categoria', unidade: '-', significado: 'Tipo do item (Material, Serviço, Consumível, Indireto)', intervalo: '4 opções', dica: 'Organize por categoria' },
{ nome: 'Tipo de Produto', unidade: '-', significado: 'Categoria específica (Perfil W, Chapa, Eletrodo, etc)', intervalo: '15+ tipos', dica: 'Define lista de produtos' },
{ nome: 'Especificação', unidade: '-', significado: 'Produto específico do banco de dados', intervalo: '100+ produtos', dica: 'Preço preenche automaticamente' },
{ nome: 'Quantidade', unidade: 'variável', significado: 'Quantidade do item', intervalo: '> 0', dica: 'Use unidade correta (m, kg, un, m²)' },
{ nome: 'BDI / Margem', unidade: '%', significado: 'Margem de lucro e custos indiretos', intervalo: '15-35', dica: 'Tipicamente 25%' }
],
resultados: '<h4>Cálculo de Total</h4><p><strong>Subtotal = ∑(Quantidade × Preço Unitário)</strong></p><p><strong>BDI = Subtotal × (% BDI)</strong></p><p><strong>TOTAL = Subtotal + BDI</strong></p>',
referencias: [
{ titulo: 'SINAPI - Sistema Nacional de Pesquisa de Custos', url: 'https://www.caixa.gov.br' },
{ titulo: 'Tabela Gerdau - Preços de Aços', ano: 2025 }
],
manualRelacionado: ['orcamento_basico', 'bdi_margem']
},
seletor: {
titulo: '🎯 Seletor de Aço Inteligente',
oQueE: 'Ferramenta que recomenda o aço estrutural mais adequado com base nos requisitos do projeto (carga, ambiente, soldabilidade).',
paraQueServe: 'Auxiliar na escolha do aço correto considerando resistência mecânica, ambiente corrosivo, custo e disponibilidade.',
quandoUsar: 'Na fase inicial de projeto, ao especificar materiais para estruturas metálicas.',
avisos: [
'Considere sempre o ambiente de exposição (C1-C5)',
'Verifique disponibilidade regional do aço',
'Consulte fornecedores para preços atualizados',
'CEV alto requer cuidados especiais na soldagem'
],
campos: [
{ nome: 'Resistência Requerida', unidade: 'MPa', significado: 'Limite de escoamento mínimo necessário', intervalo: '200-500', dica: 'Conforme cálculo estrutural' },
{ nome: 'Ambiente', unidade: '-', significado: 'Categoria de corrosividade ISO 12944', intervalo: 'C1-C5', dica: 'C1=interior, C5=marinho' },
{ nome: 'Soldabilidade', unidade: '-', significado: 'Facilidade de soldagem desejada', intervalo: 'Fácil/Moderada/Difícil', dica: 'Fácil para obra de campo' },
{ nome: 'Custo', unidade: '-', significado: 'Prioridade de custo', intervalo: 'Baixo/Médio/Alto', dica: 'Baixo = A36, Alto = aços especiais' }
],
resultados: '<h4>Recomendação</h4><p>Sistema analisa requisitos e sugere aços compatíveis com propriedades, custo relativo e observações.</p>',
referencias: [
{ titulo: 'ASTM A36/A572 - Structural Steel Specifications', ano: 2019 },
{ titulo: 'EN 10025 - Hot rolled products of structural steels', ano: 2019 }
],
manualRelacionado: ['aco_introducao', 'acos_estruturais']
},
equivalencias: {
titulo: '📊 Equivalências Internacionais',
oQueE: 'Tabela de equivalências entre normas de aços estruturais (ASTM, EN, JIS, NBR) com base em propriedades mecânicas.',
paraQueServe: 'Identificar aços equivalentes quando especificação original não está disponível ou para comparação entre normas.',
quandoUsar: 'Ao trabalhar com projetos internacionais ou quando precisar substituir um aço por equivalente de outra norma.',
avisos: [
'Equivalências são aproximadas, não exatas',
'Sempre verifique composição química',
'Consulte engenheiro para aplicações críticas',
'Propriedades mecânicas podem variar ligeiramente'
],
campos: [
{ nome: 'Norma Origem', unidade: '-', significado: 'Norma do aço especificado', intervalo: 'ASTM/EN/JIS/NBR', dica: 'Norma do projeto original' },
{ nome: 'Designação', unidade: '-', significado: 'Código do aço na norma origem', intervalo: 'A36/S235/SS400', dica: 'Conforme certificado' }
],
resultados: '<h4>Aços Equivalentes</h4><p>Lista de aços equivalentes em outras normas com propriedades mecânicas comparativas.</p>',
referencias: [
{ titulo: 'ISO 4952 - Structural steel - Comparison of grades', ano: 2006 },
{ titulo: 'Worldwide Guide to Equivalent Irons and Steels', ano: 2006 }
],
manualRelacionado: ['equivalencias_normas', 'acos_estruturais']
},
comparativo: {
titulo: '📈 Comparativo de Aços',
oQueE: 'Ferramenta que compara lado a lado as propriedades de diferentes aços estruturais.',
paraQueServe: 'Facilitar a escolha entre opções de aços mostrando diferenças em resistência, soldabilidade, custo e aplicações.',
quandoUsar: 'Quando tiver múltiplas opções de aço e precisar decidir qual é mais adequado para o projeto.',
avisos: [
'Compare aços de mesma categoria (estrutural com estrutural)',
'Considere não apenas resistência, mas também soldabilidade',
'Custo pode variar significativamente por região',
'Disponibilidade é fator crítico no Brasil'
],
campos: [
{ nome: 'Aço 1', unidade: '-', significado: 'Primeiro aço para comparação', intervalo: 'Lista de aços', dica: 'Selecione da base de dados' },
{ nome: 'Aço 2', unidade: '-', significado: 'Segundo aço para comparação', intervalo: 'Lista de aços', dica: 'Selecione da base de dados' },
{ nome: 'Aço 3', unidade: '-', significado: 'Terceiro aço (opcional)', intervalo: 'Lista de aços', dica: 'Opcional' }
],
resultados: '<h4>Tabela Comparativa</h4><p>Mostra fy, fu, alongamento, CEV, tenacidade, custo relativo e aplicações típicas.</p>',
referencias: [
{ titulo: 'AISC Steel Construction Manual', ano: 2017 },
{ titulo: 'Gerdau - Catálogo de Produtos', ano: 2025 }
],
manualRelacionado: ['aco_introducao', 'acos_estruturais']
},
layout: {
titulo: '🎯 Layout de Furação',
oQueE: 'Verificador de distâncias mínimas e máximas para furos de parafusos conforme NBR 8800 e AISC 360.',
paraQueServe: 'Garantir que o layout de furação atende requisitos normativos de distância de borda e espaçamento entre furos.',
quandoUsar: 'Ao detalhar conexões parafusadas, antes de executar furação em chapas e perfis.',
avisos: [
'Distância mínima de borda: 1.5 × diâmetro',
'Distância máxima de borda: 12 × espessura',
'Espaçamento mínimo entre furos: 2.67 × diâmetro',
'Espaçamento máximo: 300 mm ou 24 × espessura'
],
campos: [
{ nome: 'Diâmetro Parafuso', unidade: 'mm', significado: 'Diâmetro nominal do parafuso', intervalo: '12-30', dica: 'Diâmetro do furo = d + 2mm' },
{ nome: 'Distância Borda', unidade: 'mm', significado: 'Distância do centro do furo até borda', intervalo: '20-150', dica: 'Mínimo 1.5d' },
{ nome: 'Espaçamento', unidade: 'mm', significado: 'Distância entre centros de furos', intervalo: '30-300', dica: 'Mínimo 2.67d' },
{ nome: 'Espessura Chapa', unidade: 'mm', significado: 'Espessura do material furado', intervalo: '5-50', dica: 'Afeta distância máxima' }
],
resultados: '<h4>Verificação NBR 8800</h4><p>Indica se layout está conforme, com valores mínimos e máximos permitidos.</p>',
referencias: [
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 },
{ titulo: 'AISC 360-16 - Specification for Structural Steel Buildings', ano: 2016 }
],
manualRelacionado: ['parafusos_basico', 'layout_furacao']
},
'parafuso-vs-solda': {
titulo: '⚙️ Parafuso vs Solda',
oQueE: 'Comparador técnico e econômico entre soluções parafusadas e soldadas para conexões estruturais.',
paraQueServe: 'Auxiliar na decisão entre parafusar ou soldar, considerando capacidade, custo, prazo e manutenibilidade.',
quandoUsar: 'Na fase de projeto de conexões, ao avaliar alternativas de ligação.',
avisos: [
'Parafusos permitem desmontagem, soldas são permanentes',
'Soldagem requer qualificação e inspeção rigorosa',
'Parafusos são mais rápidos em campo',
'Custo varia conforme região e disponibilidade'
],
campos: [
{ nome: 'Força a Transmitir', unidade: 'kN', significado: 'Esforço total na conexão', intervalo: '10-500', dica: 'Força de cálculo (fatorada)' },
{ nome: 'Comprimento Conexão', unidade: 'mm', significado: 'Extensão da ligação', intervalo: '100-2000', dica: 'Comprimento disponível' },
{ nome: 'Tipo Aço', unidade: '-', significado: 'Material base', intervalo: 'A36/A572', dica: 'Afeta resistência da solda' }
],
resultados: '<h4>Comparação</h4><p>Mostra solução parafusada (quantidade, tipo) vs soldada (perna, comprimento) com custos estimados.</p>',
referencias: [
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020 },
{ titulo: 'AISC Design Guide 21 - Welded Connections', ano: 2006 }
],
manualRelacionado: ['parafusos_basico', 'soldagem_introducao']
},
certificado: {
titulo: '📋 Checklist Certificado',
oQueE: 'Lista de verificação para análise de certificados de qualidade de materiais (Mill Test Report).',
paraQueServe: 'Garantir que certificados de aço atendem requisitos normativos e de projeto.',
quandoUsar: 'Ao receber materiais, antes de liberar para fabricação.',
avisos: [
'Verifique correspondência entre lote e certificado',
'Confirme que propriedades atendem especificação',
'Análise química deve estar dentro dos limites',
'Certificado tipo 3.1 requer laboratório independente'
],
campos: [
{ nome: 'Norma Especificada', unidade: '-', significado: 'Norma do material no projeto', intervalo: 'ASTM/EN/NBR', dica: 'Conforme projeto' },
{ nome: 'Tipo Certificado', unidade: '-', significado: 'Classificação EN 10204', intervalo: '2.1/2.2/3.1/3.2', dica: '3.1 é mais rigoroso' }
],
resultados: '<h4>Checklist</h4><p>Lista de itens obrigatórios a verificar no certificado com status de conformidade.</p>',
referencias: [
{ titulo: 'EN 10204 - Metallic products - Types of inspection documents', ano: 2004 },
{ titulo: 'ASTM A6 - General Requirements for Rolled Steel', ano: 2019 }
],
manualRelacionado: ['aco_introducao', 'ensaios_introducao']
},
ultrassom: {
titulo: '🏥 Interpretação Ultrassom',
oQueE: 'Ferramenta para interpretar resultados de ensaios ultrassônicos (UT) em soldas conforme AWS D1.1.',
paraQueServe: 'Avaliar se descontinuidades detectadas por UT são aceitáveis ou requerem reparo.',
quandoUsar: 'Após ensaio ultrassônico, para determinar aceitação ou rejeição de soldas.',
avisos: [
'Trincas nunca são aceitáveis',
'Porosidade tem limites de tamanho e quantidade',
'Falta de fusão é defeito crítico',
'Sempre consulte norma específica do projeto'
],
campos: [
{ nome: 'Tipo Descontinuidade', unidade: '-', significado: 'Natureza do defeito', intervalo: 'Poro/Trinca/Fusão', dica: 'Conforme laudo UT' },
{ nome: 'Tamanho', unidade: 'mm', significado: 'Dimensão da descontinuidade', intervalo: '0.5-10', dica: 'Maior dimensão' },
{ nome: 'Quantidade', unidade: 'un', significado: 'Número de descontinuidades', intervalo: '1-20', dica: 'Em área de 25mm' },
{ nome: 'Localização', unidade: '-', significado: 'Posição na solda', intervalo: 'Raiz/Face/Meio', dica: 'Conforme laudo' }
],
resultados: '<h4>Avaliação AWS D1.1</h4><p>Indica se defeito é aceitável, requer análise de engenharia ou deve ser reparado.</p>',
referencias: [
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020 },
{ titulo: 'ASME Sec V - Nondestructive Examination', ano: 2019 }
],
manualRelacionado: ['ensaios_introducao', 'soldagem_introducao']
},
'area-pintura': {
titulo: '📐 Cálculo de Área',
oQueE: 'Calculadora de área superficial para diferentes tipos de perfis e elementos estruturais.',
paraQueServe: 'Determinar área total a pintar para cálculo de consumo de tinta e custo.',
quandoUsar: 'Antes de orçar pintura, para quantificar área de aplicação.',
avisos: [
'Considere todas as faces expostas',
'Perfis têm área maior que aparentam',
'Não esqueça de somar áreas internas',
'Use resultado para ferramenta Consumo de Tinta'
],
campos: [
{ nome: 'Tipo Elemento', unidade: '-', significado: 'Geometria do elemento', intervalo: 'Chapa/Perfil/Tubo', dica: 'Define cálculo de área' },
{ nome: 'Dimensões', unidade: 'mm', significado: 'Medidas do elemento', intervalo: 'Variável', dica: 'Conforme tipo selecionado' },
{ nome: 'Quantidade', unidade: 'un', significado: 'Número de elementos', intervalo: '1-1000', dica: 'Total de peças iguais' }
],
resultados: '<h4>Área Total</h4><p>Área superficial em m² considerando todas as faces expostas.</p>',
referencias: [
{ titulo: 'ISO 8501-1 - Preparation of steel substrates', ano: 2007 },
{ titulo: 'Gerdau - Tabela de Perfis', ano: 2025 }
],
manualRelacionado: ['pintura_introducao']
},
galvanizacao: {
titulo: '🛡️ Galvanização',
oQueE: 'Calculadora de espessura de camada de zinco e vida útil esperada para galvanização por imersão a quente.',
paraQueServe: 'Especificar galvanização adequada e estimar durabilidade conforme ambiente de exposição.',
quandoUsar: 'Ao especificar proteção anticorrosiva por galvanização.',
avisos: [
'Espessura mínima conforme NBR 6323',
'Ambiente marinho requer camadas mais espessas',
'Galvanização + pintura (duplex) aumenta vida útil',
'Verifique se geometria permite imersão'
],
campos: [
{ nome: 'Ambiente', unidade: '-', significado: 'Categoria de exposição', intervalo: 'C1-C5', dica: 'Conforme ISO 12944' },
{ nome: 'Área Total', unidade: 'm²', significado: 'Área a galvanizar', intervalo: '1-10000', dica: 'Use ferramenta Área' },
{ nome: 'Espessura Zinco', unidade: 'μm', significado: 'Camada de zinco especificada', intervalo: '45-150', dica: 'Mínimo 85μm para C3' }
],
resultados: '<h4>Vida Útil Estimada</h4><p>Anos de proteção esperados conforme ambiente e espessura de zinco.</p>',
referencias: [
{ titulo: 'NBR 6323 - Galvanização por imersão a quente', ano: 2020 },
{ titulo: 'ASTM A123 - Zinc Coating on Iron and Steel', ano: 2017 }
],
manualRelacionado: ['pintura_introducao', 'iso12944']
},
'custo-pintura': {
titulo: '💰 Custo Total',
oQueE: 'Calculadora de custo completo de pintura incluindo material, mão de obra e preparação de superfície.',
paraQueServe: 'Orçar serviços de pintura com todos os custos envolvidos.',
quandoUsar: 'Na elaboração de propostas comerciais ou planejamento de custos.',
avisos: [
'Inclua custo de preparação de superfície',
'Mão de obra varia por região',
'Considere acesso e altura (andaimes)',
'Adicione margem para imprevistos (10-15%)'
],
campos: [
{ nome: 'Área Total', unidade: 'm²', significado: 'Área a pintar', intervalo: '10-10000', dica: 'Use ferramenta Área' },
{ nome: 'Sistema Pintura', unidade: '-', significado: 'Esquema de pintura', intervalo: 'C2/C3/C4/C5', dica: 'Conforme ISO 12944' },
{ nome: 'Preparação', unidade: '-', significado: 'Tipo de preparo', intervalo: 'Manual/Jato', dica: 'Jato é mais caro' },
{ nome: 'Região', unidade: '-', significado: 'Localização da obra', intervalo: 'SE/S/NE/CO', dica: 'Afeta preços' }
],
resultados: '<h4>Custo Total</h4><p>Discrimina custos de material, preparação, aplicação e total geral.</p>',
referencias: [
{ titulo: 'SINAPI - Tabela de Preços', ano: 2025 },
{ titulo: 'ISO 12944 - Paints and varnishes', ano: 2018 }
],
manualRelacionado: ['pintura_introducao', 'orcamento_basico']
},
secagem: {
titulo: '⏱️ Tempo de Secagem',
oQueE: 'Calculadora de tempos de secagem e intervalos entre demãos para diferentes tipos de tinta.',
paraQueServe: 'Planejar cronograma de pintura respeitando tempos mínimos e máximos entre camadas.',
quandoUsar: 'Ao programar atividades de pintura em obra.',
avisos: [
'Temperatura e umidade afetam secagem',
'Respeite tempo mínimo entre demãos',
'Tempo máximo evita perda de aderência',
'Ventilação acelera secagem'
],
campos: [
{ nome: 'Tipo Tinta', unidade: '-', significado: 'Resina da tinta', intervalo: 'Epóxi/PU/Alquídica', dica: 'Conforme ficha técnica' },
{ nome: 'Temperatura', unidade: '°C', significado: 'Temperatura ambiente', intervalo: '5-40', dica: 'Temperatura no local' },
{ nome: 'Umidade', unidade: '%', significado: 'Umidade relativa', intervalo: '40-85', dica: 'Máximo 85% para PU' },
{ nome: 'Espessura', unidade: 'μm', significado: 'DFT aplicado', intervalo: '50-200', dica: 'Camadas espessas demoram mais' }
],
resultados: '<h4>Tempos de Secagem</h4><p>Ao toque, manuseio, próxima demão e cura total.</p>',
referencias: [
{ titulo: 'ISO 9117 - Paints - Drying tests', ano: 2009 },
{ titulo: 'ASTM D1640 - Drying of Organic Coatings', ano: 2014 }
],
manualRelacionado: ['pintura_introducao']
},
'inspecao-pintura': {
titulo: '✔️ Inspeção de Qualidade',
oQueE: 'Checklist de inspeção de pintura conforme ISO 12944 e NBR 15239.',
paraQueServe: 'Verificar qualidade da pintura aplicada e identificar não-conformidades.',
quandoUsar: 'Durante e após aplicação de pintura, antes de liberação final.',
avisos: [
'Inspecione cada camada antes da próxima',
'Meça DFT em múltiplos pontos',
'Verifique aderência por amostragem',
'Documente com fotos'
],
campos: [
{ nome: 'Etapa', unidade: '-', significado: 'Fase da inspeção', intervalo: 'Preparo/Aplicação/Final', dica: 'Cada etapa tem checklist' },
{ nome: 'DFT Medido', unidade: 'μm', significado: 'Espessura medida', intervalo: '50-300', dica: 'Média de 5 pontos' },
{ nome: 'DFT Especificado', unidade: 'μm', significado: 'Espessura requerida', intervalo: '50-300', dica: 'Conforme projeto' }
],
resultados: '<h4>Status Inspeção</h4><p>Indica conformidade e lista não-conformidades encontradas.</p>',
referencias: [
{ titulo: 'ISO 12944-7 - Execution and supervision', ano: 2017 },
{ titulo: 'NBR 15239 - Pintura industrial', ano: 2005 }
],
manualRelacionado: ['pintura_introducao', 'iso12944']
},
'peso-rigging': {
titulo: '⚖️ Peso e Rigging',
oQueE: 'Calculadora de peso de elementos estruturais e planejamento de içamento (rigging).',
paraQueServe: 'Determinar peso para transporte e especificar equipamentos de elevação adequados.',
quandoUsar: 'No planejamento de logística, transporte e montagem.',
avisos: [
'Adicione margem de segurança (15-25%)',
'Considere peso de acessórios (lingas, ganchos)',
'Verifique capacidade do guindaste',
'Identifique centro de gravidade'
],
campos: [
{ nome: 'Tipo Elemento', unidade: '-', significado: 'Categoria do elemento', intervalo: 'Perfil/Chapa/Tubo', dica: 'Define cálculo de peso' },
{ nome: 'Dimensões', unidade: 'mm', significado: 'Medidas do elemento', intervalo: 'Variável', dica: 'Conforme tipo' },
{ nome: 'Material', unidade: '-', significado: 'Tipo de aço', intervalo: 'A36/A572/Inox', dica: 'Densidade varia' },
{ nome: 'Quantidade', unidade: 'un', significado: 'Número de elementos', intervalo: '1-1000', dica: 'Total de peças' }
],
resultados: '<h4>Peso e Rigging</h4><p>Peso total, capacidade mínima de guindaste e recomendações de içamento.</p>',
referencias: [
{ titulo: 'NR-12 - Segurança em Máquinas', ano: 2019 },
{ titulo: 'ASME B30.20 - Below-the-Hook Lifting Devices', ano: 2018 }
],
manualRelacionado: ['orcamento_basico']
},
referencia: {
titulo: '📖 Referência Técnica',
oQueE: 'Biblioteca de referências técnicas, normas, tabelas e fórmulas para consulta rápida.',
paraQueServe: 'Acesso rápido a informações técnicas essenciais durante projeto e execução.',
quandoUsar: 'Sempre que precisar consultar dados técnicos, propriedades de materiais ou requisitos normativos.',
avisos: [
'Sempre consulte norma original para aplicações críticas',
'Dados são para referência, não substituem projeto',
'Verifique edição atualizada das normas',
'Propriedades podem variar por fornecedor'
],
campos: [
{ nome: 'Categoria', unidade: '-', significado: 'Tipo de referência', intervalo: 'Normas/Tabelas/Fórmulas', dica: 'Selecione categoria' },
{ nome: 'Assunto', unidade: '-', significado: 'Tema específico', intervalo: 'Variável', dica: 'Conforme categoria' }
],
resultados: '<h4>Informação Técnica</h4><p>Dados, tabelas, fórmulas e referências normativas relevantes.</p>',
referencias: [
{ titulo: 'AISC Steel Construction Manual', ano: 2017 },
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020 },
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 }
],
manualRelacionado: ['aco_introducao', 'parafusos_basico', 'soldagem_introducao']
},
// ABAS DE SOLDAGEM
filete: {
titulo: '⚡ Dimensionamento de Soldas de Filete',
oQueE: 'Solda de filete é uma solda de seção triangular que une duas superfícies aproximadamente perpendiculares. É o tipo mais comum de solda estrutural.',
paraQueServe: 'Calcular a perna necessária da solda de filete para transmitir uma força específica, considerando o processo de soldagem e o número de passes necessários.',
quandoUsar: 'Em ligações de vigas a pilares, cantoneiras, reforços, e qualquer conexão onde as peças formam um ângulo (geralmente 90°).',
avisos: [
'Perna mínima: 3mm para chapas até 6mm, 5mm para chapas de 6-12mm',
'Perna máxima: espessura da chapa mais fina',
'Considerar acessibilidade para soldagem',
'Verificar distorção em soldas longas'
],
campos: [
{ nome: 'Força a Transmitir', unidade: 'kN', significado: 'Carga que a solda deve suportar', intervalo: '10-500', dica: 'Obtenha do cálculo estrutural' },
{ nome: 'Comprimento da Solda', unidade: 'mm', significado: 'Extensão total da solda', intervalo: '50-1000', dica: 'Perímetro da conexão' },
{ nome: 'Tipo de Eletrodo', unidade: '-', significado: 'Resistência do metal de adição', intervalo: 'E60-E100', dica: 'E7018 é o mais comum' },
{ nome: 'Número de Lados', unidade: '-', significado: 'Solda em um ou ambos os lados', intervalo: '1-2', dica: '2 lados dobra a capacidade' }
],
resultados: '<h4>Perna Necessária</h4><p><strong>Fórmula:</strong> a = F / (0.707 × L × f_w × n)</p><p>Onde: a=perna, F=força, L=comprimento, f_w=tensão admissível, n=número de lados</p>',
referencias: [
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020, url: 'https://www.aws.org' },
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 }
],
manualRelacionado: ['soldagem_introducao', 'eletrodos_tipos', 'preaquecimento_guia']
},
energia: {
titulo: '🔥 Energia de Soldagem (Heat Input)',
oQueE: 'Energia de soldagem (heat input) é a quantidade de energia térmica transferida para o material base por unidade de comprimento de solda.',
paraQueServe: 'Controlar a taxa de resfriamento da solda para evitar formação de estruturas frágeis (martensita) e garantir propriedades mecânicas adequadas.',
quandoUsar: 'Em aços de alta resistência, seções espessas, ou quando especificado em procedimento de soldagem (WPS).',
avisos: [
'Heat input muito alto: grão grosseiro, perda de resistência',
'Heat input muito baixo: resfriamento rápido, trincas',
'Medir tensão e corrente reais durante soldagem',
'Considerar eficiência do processo (η)'
],
campos: [
{ nome: 'Voltagem', unidade: 'V', significado: 'Tensão elétrica do arco', intervalo: '20-35', dica: 'Ler no equipamento durante soldagem' },
{ nome: 'Corrente', unidade: 'A', significado: 'Corrente elétrica do arco', intervalo: '80-300', dica: 'Ajustar conforme diâmetro do eletrodo' },
{ nome: 'Velocidade', unidade: 'cm/min', significado: 'Velocidade de avanço da soldagem', intervalo: '10-40', dica: 'Medir tempo para soldar 10cm' },
{ nome: 'Eficiência', unidade: '%', significado: 'Eficiência térmica do processo', intervalo: '60-90', dica: 'SMAW=60%, GMAW=80%, SAW=90%' }
],
resultados: '<h4>Heat Input</h4><p><strong>Fórmula:</strong> HI = (V × I × 60 × η) / (1000 × v)</p><p>Resultado em kJ/mm. Típico: 0.5-2.5 kJ/mm</p>',
referencias: [
{ titulo: 'AWS D1.1 - Heat Input Requirements', ano: 2020 },
{ titulo: 'ISO 17663 - Welding Heat Input', ano: 2009 }
],
manualRelacionado: ['soldagem_introducao', 'preaquecimento_guia', 'cev_entendimento']
},
'consumo-eletrodo': {
titulo: '📊 Consumo de Eletrodos',
oQueE: 'Cálculo da quantidade de eletrodos necessários para executar uma determinada quantidade de soldagem, considerando perdas e eficiência.',
paraQueServe: 'Estimar custos de materiais de soldagem e planejar compras para o projeto.',
quandoUsar: 'Na fase de orçamento e planejamento de projetos com soldagem.',
avisos: [
'Considerar perdas por pontas (15-20%)',
'Considerar respingos e escória (10-15%)',
'Adicionar margem de segurança (10%)',
'Variar conforme habilidade do soldador'
],
campos: [
{ nome: 'Volume de Solda', unidade: 'cm³', significado: 'Volume total de metal depositado', intervalo: '10-10000', dica: 'Calcule: comprimento × área da seção' },
{ nome: 'Diâmetro Eletrodo', unidade: 'mm', significado: 'Diâmetro do eletrodo usado', intervalo: '2.5-5.0', dica: '3.25mm é o mais comum' },
{ nome: 'Eficiência', unidade: '%', significado: 'Aproveitamento do eletrodo', intervalo: '50-70', dica: '60% é típico para SMAW' },
{ nome: 'Densidade', unidade: 'g/cm³', significado: 'Densidade do metal de solda', intervalo: '7.8-7.9', dica: 'Aço: 7.85 g/cm³' }
],
resultados: '<h4>Consumo de Eletrodos</h4><p><strong>Fórmula:</strong> Peso = Volume × Densidade / Eficiência</p><p>Resultado em kg de eletrodos necessários</p>',
referencias: [
{ titulo: 'AWS Welding Handbook - Consumables', ano: 2020 },
{ titulo: 'Guia de Consumo de Eletrodos', ano: 2018 }
],
manualRelacionado: ['soldagem_introducao', 'eletrodos_tipos', 'orcamento_basico']
},
'sequencia-soldagem': {
titulo: '🔄 Sequência de Soldagem',
oQueE: 'Ordem e direção em que os cordões de solda são depositados para minimizar distorções e tensões residuais.',
paraQueServe: 'Planejar a execução da soldagem para reduzir empenamento, controlar distorções e garantir qualidade dimensional.',
quandoUsar: 'Em estruturas com múltiplas soldas, chapas finas, ou quando tolerâncias dimensionais são críticas.',
avisos: [
'Soldar do centro para as extremidades reduz distorção',
'Alternar lados em soldas simétricas',
'Evitar concentração de calor em uma região',
'Usar gabaritos para peças críticas'
],
campos: [
{ nome: 'Tipo de Estrutura', unidade: '-', significado: 'Configuração da peça', intervalo: 'Viga/Pilar/Chapa', dica: 'Define estratégia de soldagem' },
{ nome: 'Número de Soldas', unidade: '-', significado: 'Quantidade de cordões', intervalo: '2-20', dica: 'Mais soldas = mais planejamento' },
{ nome: 'Espessura', unidade: 'mm', significado: 'Espessura do material', intervalo: '3-50', dica: 'Chapas finas distorcem mais' },
{ nome: 'Restrição', unidade: '-', significado: 'Liberdade de movimento', intervalo: 'Livre/Restrita', dica: 'Restrita gera mais tensões' }
],
resultados: '<h4>Recomendações de Sequência</h4><p>Baseado nas entradas, o sistema sugere a melhor ordem de soldagem e técnicas para minimizar distorções.</p>',
referencias: [
{ titulo: 'AWS D1.1 - Welding Sequence', ano: 2020 },
{ titulo: 'Distortion Control in Welding', ano: 2015 }
],
manualRelacionado: ['soldagem_introducao', 'sequencia_soldagem', 'preaquecimento_guia']
},
'padroes-soldagem': {
titulo: '📋 Padrões e Normas de Soldagem',
oQueE: 'Referências normativas e requisitos técnicos para soldagem estrutural conforme AWS, ASME, NBR e outras normas.',
paraQueServe: 'Consultar requisitos normativos, símbolos de soldagem, qualificação de procedimentos e inspeção.',
quandoUsar: 'Durante elaboração de WPS, qualificação de soldadores, inspeção e controle de qualidade.',
avisos: [
'Sempre consultar a norma aplicável ao projeto',
'Verificar edição e ano da norma',
'Considerar requisitos do cliente',
'Documentar todos os procedimentos'
],
campos: [
{ nome: 'Norma Aplicável', unidade: '-', significado: 'Código de soldagem do projeto', intervalo: 'AWS/ASME/NBR', dica: 'Definido no projeto' },
{ nome: 'Tipo de Estrutura', unidade: '-', significado: 'Aplicação da soldagem', intervalo: 'Edifício/Ponte/Vaso', dica: 'Define requisitos específicos' },
{ nome: 'Categoria', unidade: '-', significado: 'Criticidade da junta', intervalo: 'A/B/C/D', dica: 'A é mais crítica' }
],
resultados: '<h4>Requisitos Normativos</h4><p>Consulta de requisitos específicos da norma selecionada, incluindo qualificação, inspeção e aceitação.</p>',
referencias: [
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020 },
{ titulo: 'ASME Section IX - Welding Qualifications', ano: 2021 },
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 }
],
manualRelacionado: ['soldagem_introducao', 'eletrodos_tipos', 'ensaios_introducao']
},
// ABAS DE PARAFUSOS/CONEXÕES
'parafusos-cisalhamento': {
titulo: '🔩 Parafusos ao Cisalhamento',
oQueE: 'Verificação da resistência de parafusos quando submetidos a forças cortantes (cisalhamento) perpendiculares ao eixo do parafuso.',
paraQueServe: 'Dimensionar o número e diâmetro de parafusos necessários para resistir a uma força cortante específica.',
quandoUsar: 'Em ligações onde a força é perpendicular ao eixo dos parafusos (maioria das ligações estruturais).',
avisos: [
'Verificar número de planos de corte (simples ou duplo)',
'Usar parafusos de alta resistência (A325/A490)',
'Considerar rosca no plano de corte (reduz capacidade)',
'Aplicar fator de segurança adequado'
],
campos: [
{ nome: 'Tipo de Parafuso', unidade: '-', significado: 'Classe de resistência', intervalo: 'A325/A490/ISO', dica: 'A325 é o mais comum' },
{ nome: 'Diâmetro', unidade: 'mm', significado: 'Diâmetro nominal do parafuso', intervalo: '12-24', dica: '20mm (3/4") é típico' },
{ nome: 'Quantidade', unidade: '-', significado: 'Número de parafusos', intervalo: '2-20', dica: 'Mínimo 2 por conexão' },
{ nome: 'Planos de Corte', unidade: '-', significado: 'Superfícies de cisalhamento', intervalo: '1-2', dica: '2 planos dobra capacidade' },
{ nome: 'Força Aplicada', unidade: 'kN', significado: 'Carga de projeto', intervalo: '10-500', dica: 'Do cálculo estrutural' }
],
resultados: '<h4>Resistência ao Cisalhamento</h4><p><strong>Fórmula:</strong> V_r = n × m × 0.50 × F_u × A_b</p><p>Onde: n=quantidade, m=planos, F_u=resistência, A_b=área</p>',
referencias: [
{ titulo: 'NBR 8800 - Ligações Parafusadas', ano: 2008 },
{ titulo: 'AISC 360 - Specification for Structural Steel Buildings', ano: 2016 }
],
manualRelacionado: ['parafusos_basico', 'cisalhamento_analise', 'layout_furacao']
},
'parafusos-esmagamento': {
titulo: '🔨 Esmagamento de Chapas (Bearing)',
oQueE: 'Verificação da resistência da chapa ao esmagamento (bearing) causado pela pressão do parafuso contra a parede do furo.',
paraQueServe: 'Garantir que a chapa não será esmagada ou deformada excessivamente pela pressão dos parafusos.',
quandoUsar: 'Sempre em conjunto com verificação ao cisalhamento, especialmente em chapas finas ou aços de menor resistência.',
avisos: [
'Distância de borda mínima: 1.5d',
'Espaçamento mínimo entre furos: 2.67d',
'Chapas finas são mais críticas',
'Verificar rasgamento da borda'
],
campos: [
{ nome: 'Diâmetro Parafuso', unidade: 'mm', significado: 'Diâmetro do parafuso', intervalo: '12-24', dica: 'Mesmo da verificação ao cisalhamento' },
{ nome: 'Espessura Chapa', unidade: 'mm', significado: 'Espessura do material', intervalo: '5-25', dica: 'Chapas finas são críticas' },
{ nome: 'Quantidade', unidade: '-', significado: 'Número de parafusos', intervalo: '2-20', dica: 'Distribuir carga uniformemente' },
{ nome: 'Tipo de Aço', unidade: '-', significado: 'Resistência do material', intervalo: 'A36/A572/S355', dica: 'Afeta capacidade de esmagamento' },
{ nome: 'Distância de Borda', unidade: 'mm', significado: 'Distância do furo à borda', intervalo: '20-100', dica: 'Mínimo 1.5 × diâmetro' },
{ nome: 'Espaçamento', unidade: 'mm', significado: 'Distância entre furos', intervalo: '40-150', dica: 'Mínimo 2.67 × diâmetro' }
],
resultados: '<h4>Resistência ao Esmagamento</h4><p><strong>Fórmula:</strong> R_b = 2.4 × d × t × F_u</p><p>Onde: d=diâmetro, t=espessura, F_u=resistência última</p>',
referencias: [
{ titulo: 'NBR 8800 - Ligações Parafusadas', ano: 2008 },
{ titulo: 'AISC 360 - Bearing Strength', ano: 2016 }
],
manualRelacionado: ['parafusos_basico', 'layout_furacao', 'acos_estruturais']
},
'parafusos-bloco': {
titulo: '⚠️ Ruptura em Bloco de Cisalhamento',
oQueE: 'Modo de falha onde um bloco de material se destaca da chapa por combinação de cisalhamento e tração ao longo de um caminho definido pelos furos.',
paraQueServe: 'Verificar se a chapa tem resistência suficiente para evitar ruptura em bloco, especialmente em ligações com múltiplos parafusos.',
quandoUsar: 'Em ligações com 3 ou mais parafusos em linha, cantoneiras, e conexões de extremidade.',
avisos: [
'Crítico em cantoneiras e chapas de extremidade',
'Aumentar distância de borda se necessário',
'Considerar ambos os modos: cisalhamento e tração',
'Usar furos padrão (não oversized)'
],
campos: [
{ nome: 'Diâmetro Parafuso', unidade: 'mm', significado: 'Diâmetro dos parafusos', intervalo: '12-24', dica: 'Afeta área líquida' },
{ nome: 'Quantidade Horizontal', unidade: '-', significado: 'Parafusos na direção da força', intervalo: '2-6', dica: 'Mais parafusos = maior risco' },
{ nome: 'Quantidade Vertical', unidade: '-', significado: 'Parafusos perpendiculares', intervalo: '1-4', dica: 'Afeta área de cisalhamento' },
{ nome: 'Espaçamento', unidade: 'mm', significado: 'Distância entre furos', intervalo: '50-100', dica: 'Típico: 3d' },
{ nome: 'Distância de Borda', unidade: 'mm', significado: 'Distância à borda livre', intervalo: '25-75', dica: 'Crítico para tração' },
{ nome: 'Espessura', unidade: 'mm', significado: 'Espessura da chapa', intervalo: '6-20', dica: 'Afeta área resistente' },
{ nome: 'Tipo de Aço', unidade: '-', significado: 'Resistência do material', intervalo: 'A36/A572', dica: 'Define F_u e F_y' }
],
resultados: '<h4>Resistência à Ruptura em Bloco</h4><p><strong>Fórmula AISC:</strong> R_bs = 0.6×F_u×A_nv + U_bs×F_u×A_nt</p><p>Onde: A_nv=área líquida cisalhamento, A_nt=área líquida tração</p>',
referencias: [
{ titulo: 'AISC 360 - Block Shear Rupture', ano: 2016 },
{ titulo: 'NBR 8800 - Ruptura em Bloco', ano: 2008 }
],
manualRelacionado: ['parafusos_basico', 'cisalhamento_analise', 'layout_furacao']
}
};
const manualConteudo = {
aco_introducao: {
titulo: '📦 Introdução aos Aços',
secao: 'MATERIAIS',
conteudo: `
<h2>O que é um Aço?</h2>
<p>Aço é uma liga de ferro e carbono, com teor de carbono entre 0.04% e 2%, que oferece propriedades superiores ao ferro puro em termos de resistência, dureza e ductilidade.</p>
<h3>Classificação dos Aços</h3>
<ul>
<li><strong>Aços Simples (Carbono):</strong> Apenas Fe + C, sem elementos de liga adicionados</li>
<li><strong>Aços Ligados:</strong> Contêm Mn, Cr, Mo, V, Ni, etc para melhorar propriedades</li>
<li><strong>Aços Inoxidáveis:</strong> Alto teor de Cr (>10%), excelente resistência à corrosão</li>
<li><strong>Aços Estruturais:</strong> Otimizados para uso em estruturas (edifícios, pontes, etc)</li>
</ul>
<h3>Propriedades Principais</h3>
<table class="propriedades-tabela">
<tr><th>Propriedade</th><th>Definição</th><th>Unidade</th></tr>
<tr><td>Resistência à Tração (fu)</td><td>Máxima tensão que o aço aguenta</td><td>MPa</td></tr>
<tr><td>Limite de Escoamento (fy)</td><td>Tensão a partir da qual começa deformação permanente</td><td>MPa</td></tr>
<tr><td>Alongamento</td><td>Quanto o aço se alonga antes de quebrar</td><td>%</td></tr>
<tr><td>Dureza</td><td>Resistência ao risco/deformação superficial</td><td>HB, HRC</td></tr>
<tr><td>Tenacidade</td><td>Capacidade de absorver impactos sem quebrar</td><td>J (Joules)</td></tr>
</table>
<h3>Aços Estruturais Mais Comuns</h3>
<table>
<tr><th>Norma</th><th>Designação</th><th>fy (MPa)</th><th>fu (MPa)</th><th>Aplicação</th></tr>
<tr><td>ASTM</td><td>A36</td><td>250</td><td>400-550</td><td>Uso geral, estruturas comuns</td></tr>
<tr><td>ASTM</td><td>A572 Gr.50</td><td>345</td><td>450-620</td><td>Estruturas de alta resistência</td></tr>
<tr><td>EN</td><td>S235</td><td>235</td><td>360-510</td><td>Estruturas gerais (Europa)</td></tr>
<tr><td>EN</td><td>S355</td><td>355</td><td>510-680</td><td>Estruturas exigentes (Europa)</td></tr>
</table>
`
},
cev_entendimento: {
titulo: '⛗️ Entendendo Carbono Equivalente',
secao: 'MATERIAIS',
conteudo: `
<h2>O que é CEV?</h2>
<p>Carbono Equivalente (CEV) é um valor calculado que representa a "capacidade de endurecimento" de um aço durante a soldagem. Quanto maior o CEV, mais difícil é soldar.</p>
<h3>Por que CEV importa?</h3>
<p>Durante a soldagem, o material próximo à solda esfria muito rapidamente (taxa de resfriamento). Aços com alto CEV endurecem muito durante este resfriamento rápido, podendo desenvolver trincas.</p>
<h3>Fórmulas de CEV</h3>
<div class="formulas-container">
<h4>CEV IIW (Internacional)</h4>
<p><strong>CEV = C + (Mn/6) + (Cr+Mo+V)/5 + (Ni+Cu)/15</strong></p>
</div>
<h3>Interpretação de Valores</h3>
<table class="tabela-interpretacao">
<tr><th>CEV</th><th>Soldabilidade</th><th>Recomendação</th></tr>
<tr><td>&lt;0.35</td><td style="background: #4caf50; color: white">Excelente</td><td>Nenhuma restrição, soldagem direta</td></tr>
<tr><td>0.35-0.45</td><td style="background: #ffc107; color: black">Boa</td><td>Considerar pré-aquecimento</td></tr>
<tr><td>0.45-0.55</td><td style="background: #ff9800; color: white">Moderada</td><td>Pré-aquecimento necessário</td></tr>
<tr><td>&gt;0.55</td><td style="background: #f44336; color: white">Difícil</td><td>Controle rigoroso + especialista</td></tr>
</table>
<h3>Exemplos Práticos</h3>
<div class="exemplos-box">
<p><strong>Exemplo 1: A36</strong></p>
<p>C=0.20, Mn=0.95, Cr=0.10, Mo=0, V=0, Ni=0, Cu=0</p>
<p>CEV = 0.20 + (0.95/6) + 0 = <strong>0.36</strong> (Soldável)</p>
</div>
`
},
preaquecimento_guia: {
titulo: '🌡️ Guia Completo de Pré-Aquecimento',
secao: 'SOLDAGEM',
conteudo: `
<h2>O que é Pré-Aquecimento?</h2>
<p>Pré-aquecimento é o processo de elevar a temperatura do material base (e zona ao redor) ANTES de iniciar a soldagem.</p>
<h3>Por que Pré-aquecer?</h3>
<p>Durante a soldagem, o material próximo à solda esfria muito rapidamente. Este resfriamento rápido pode causar:</p>
<ul>
<li>📉 Aumento de dureza excessiva</li>
<li>🔨 Formação de estrutura frágil (martensita)</li>
<li>⚠️ Risco de trincas (especialmente em aços com alto CEV)</li>
</ul>
<p>Pré-aquecimento <strong>reduz a taxa de resfriamento</strong>, permitindo transformação metalúrgica adequada.</p>
<h3>Quando Usar?</h3>
<table>
<tr><th>Situação</th><th>CEV</th><th>Recomendação</th></tr>
<tr><td>Aço simples + espessura fina</td><td>&lt;0.35</td><td>❌ Não necessário</td></tr>
<tr><td>Aço estrutural comum</td><td>0.35-0.45</td><td>⚠️ Considerar</td></tr>
<tr><td>Aço de alta resistência</td><td>0.45-0.55</td><td>✅ Necessário</td></tr>
<tr><td>Aço muito ligado</td><td>&gt;0.55</td><td>🔴 Crítico</td></tr>
</table>
<h3>Instruções Práticas</h3>
<ol>
<li><strong>Medir:</strong> Use termômetro de contato em vários pontos</li>
<li><strong>Aquecer:</strong> Maçarico, resistência, forno - qualquer método vale</li>
<li><strong>Verificar:</strong> Confirme temperatura antes de soldar</li>
<li><strong>Manter:</strong> Mantenha interpass durante toda soldagem</li>
<li><strong>Esfriar:</strong> Deixe esfriar lentamente (não molhe bruscamente!)</li>
</ol>
`
},
soldagem_introducao: {
titulo: '🔥 Introdução à Soldagem',
secao: 'SOLDAGEM',
conteudo: `
<h2>O que é Soldagem?</h2>
<p>Soldagem é um processo de união de materiais metálicos por fusão, onde as peças são aquecidas até o ponto de fusão, permitindo que se fundam e formem uma junta única e contínua.</p>
<h3>Processos de Soldagem Principais</h3>
<ul>
<li><strong>SMAW (Eletrodo Revestido):</strong> Processo manual mais comum</li>
<li><strong>GMAW (MIG/MAG):</strong> Soldagem com arame contínuo e gás de proteção</li>
<li><strong>GTAW (TIG):</strong> Alta qualidade, ideal para aços inoxidáveis</li>
<li><strong>FCAW:</strong> Arame tubular, produtivo</li>
</ul>
<h3>Fatores Críticos</h3>
<p>Para uma boa solda, considere:</p>
<ol>
<li>Limpeza da superfície</li>
<li>Pré-aquecimento adequado</li>
<li>Velocidade de soldagem controlada</li>
<li>Energia de soldagem (Heat Input) apropriada</li>
<li>Proteção gasosa eficaz</li>
</ol>
`
}
};
const manualNavStructure = {
'MATERIAIS': ['aco_introducao', 'cev_entendimento', 'equivalencias_normas', 'acos_estruturais'],
'CONEXÕES': ['parafusos_basico', 'cisalhamento_analise', 'layout_furacao'],
'SOLDAGEM': ['soldagem_introducao', 'preaquecimento_guia', 'eletrodos_tipos', 'sequencia_soldagem'],
'ENSAIOS': ['ensaios_introducao', 'dureza_escalas', 'impacto_charpy'],
'PINTURA': ['pintura_introducao', 'iso12944', 'preparo_superficie'],
'ORÇAMENTO': ['orcamento_basico', 'bdi_margem', 'precos_mercado']
};
// Add more manual content
manualConteudo.parafusos_basico = {
titulo: '🔩 Introdução a Parafusos',
secao: 'CONEXÕES',
conteudo: `
<h2>O que são Parafusos Estruturais?</h2>
<p>Parafusos estruturais são elementos de fixação de alta resistência projetados para transmitir forças entre componentes de estruturas metálicas.</p>
<h3>Tipos Principais</h3>
<table>
<tr><th>Tipo</th><th>fy (MPa)</th><th>fu (MPa)</th><th>Aplicação</th></tr>
<tr><td><strong>ASTM A325</strong></td><td>400</td><td>635</td><td>Estruturas gerais (padrão)</td></tr>
<tr><td><strong>ASTM A490</strong></td><td>565</td><td>895</td><td>Alta resistência</td></tr>
<tr><td><strong>ISO 8.8</strong></td><td>640</td><td>800</td><td>Padrão métrico</td></tr>
<tr><td><strong>ISO 10.9</strong></td><td>900</td><td>1000</td><td>Máxima resistência</td></tr>
</table>
<h3>Componentes da Ligação</h3>
<ul>
<li><strong>Parafuso:</strong> Elemento principal com rosca</li>
<li><strong>Porca:</strong> Elemento de fixação roscado</li>
<li><strong>Arruela:</strong> Distribui tensão e protege superfície</li>
</ul>
<h3>Modos de Falha</h3>
<ol>
<li><strong>Cisalhamento do Parafuso:</strong> Ruptura do corpo do parafuso</li>
<li><strong>Esmagamento da Chapa:</strong> Deformação da chapa no furo</li>
<li><strong>Ruptura em Bloco:</strong> Ruptura de seção da chapa</li>
<li><strong>Tração:</strong> Ruptura do parafuso por tração</li>
</ol>
`
};
manualConteudo.cisalhamento_analise = {
titulo: '🔧 Análise de Cisalhamento',
secao: 'CONEXÕES',
conteudo: `
<h2>Cisalhamento em Parafusos</h2>
<p>O cisalhamento é o modo de falha mais comum em ligações parafusadas, onde o parafuso é cortado transversalmente pela força aplicada.</p>
<h3>Fórmula de Verificação</h3>
<div class="formulas-container">
<p><strong>Fv = 0.6 × fy × A × n</strong></p>
<p>Onde:</p>
<ul>
<li>Fv = Resistência ao cisalhamento (kN)</li>
<li>fy = Limite de escoamento do parafuso (MPa)</li>
<li>A = Área do parafuso (mm²)</li>
<li>n = Número de planos de corte (1 ou 2)</li>
</ul>
</div>
<h3>Planos de Corte</h3>
<p><strong>Plano Simples (n=1):</strong> Parafuso cortado em um ponto</p>
<p><strong>Plano Duplo (n=2):</strong> Parafuso cortado em dois pontos - DOBRA a capacidade!</p>
<h3>Exemplo Prático</h3>
<div class="exemplos-box">
<p><strong>Parafuso A325 Ø16mm</strong></p>
<p>fy = 400 MPa, A = π(16/2)² = 201 mm²</p>
<p><strong>Plano Simples:</strong> Fv = 0.6 × 400 × 201 / 1000 = 48.2 kN</p>
<p><strong>Plano Duplo:</strong> Fv = 48.2 × 2 = 96.4 kN ✅</p>
</div>
`
};
manualConteudo.pintura_introducao = {
titulo: '🎨 Introdução à Pintura Industrial',
secao: 'PINTURA',
conteudo: `
<h2>Sistemas de Pintura</h2>
<p>Pintura industrial é um sistema de proteção anticorrosiva composto por múltiplas camadas (demãos) que protegem o aço contra degradação.</p>
<h3>Componentes do Sistema</h3>
<ol>
<li><strong>Fundo (Primer):</strong> Primeira camada, aderência e proteção</li>
<li><strong>Intermediário:</strong> Aumenta espessura e proteção</li>
<li><strong>Acabamento:</strong> Proteção UV e estética</li>
</ol>
<h3>Tipos de Tinta</h3>
<table>
<tr><th>Tipo</th><th>Características</th><th>Aplicação</th></tr>
<tr><td><strong>Epóxi</strong></td><td>Excelente adesão, química</td><td>Fundo e intermediário</td></tr>
<tr><td><strong>Poliuretano</strong></td><td>Resistência UV, brilho</td><td>Acabamento</td></tr>
<tr><td><strong>Alquídica</strong></td><td>Econômica, secagem lenta</td><td>Ambientes leves</td></tr>
<tr><td><strong>Zinc-Rich</strong></td><td>Proteção galvânica</td><td>Ambientes agressivos</td></tr>
</table>
`
};
manualConteudo.iso12944 = {
titulo: '🎯 ISO 12944 - Classificação de Ambientes',
secao: 'PINTURA',
conteudo: `
<h2>ISO 12944 - Padrão Internacional</h2>
<p>ISO 12944 classifica ambientes de corrosividade e especifica sistemas de pintura adequados para cada categoria.</p>
<h3>Categorias de Corrosividade</h3>
<table>
<tr><th>Classe</th><th>Ambiente</th><th>DFT Mín (μm)</th><th>Vida Útil</th></tr>
<tr><td><strong>C1</strong></td><td>Interior seco (escritório)</td><td>80</td><td>5-10 anos</td></tr>
<tr><td><strong>C2</strong></td><td>Interior úmido (ginásio)</td><td>120</td><td>5-10 anos</td></tr>
<tr><td><strong>C3</strong></td><td>Exterior urbano/costeiro</td><td>160</td><td>10-15 anos</td></tr>
<tr><td><strong>C4</strong></td><td>Industrial/marinho moderado</td><td>200</td><td>15-20 anos</td></tr>
<tr><td><strong>C5</strong></td><td>Marinho agressivo/offshore</td><td>250</td><td>20+ anos</td></tr>
</table>
<h3>Sistemas Recomendados por Categoria</h3>
<div class="exemplos-box">
<p><strong>C3 (Padrão Indústria):</strong></p>
<ul>
<li>Fundo: Epóxi 60μm</li>
<li>Intermediário: Epóxi 60μm</li>
<li>Acabamento: Poliuretano 40μm</li>
<li><strong>Total: 160μm</strong></li>
</ul>
</div>
`
};
manualConteudo.orcamento_basico = {
titulo: '💰 Conceitos Básicos de Orçamento',
secao: 'ORÇAMENTO',
conteudo: `
<h2>Estrutura de um Orçamento</h2>
<p>Orçamento é a estimativa detalhada de todos os custos envolvidos em um projeto.</p>
<h3>Categorias de Custos</h3>
<ol>
<li><strong>Materiais:</strong> Perfis, chapas, parafusos</li>
<li><strong>Serviços:</strong> Mão de obra especializada</li>
<li><strong>Consumíveis:</strong> Eletrodos, tintas, gases</li>
<li><strong>Indiretos:</strong> Transporte, EPI, aluguel de equipamentos</li>
</ol>
<h3>Como Calcular Preço de Materiais</h3>
<p>Para perfis e chapas: <strong>Preço = Peso × Preço/kg</strong></p>
<p>Preços variam por região do Brasil:</p>
<ul>
<li>Sudeste: R$ 7.50/kg (referência)</li>
<li>Sul: R$ 7.20/kg (mais barato)</li>
<li>Nordeste: R$ 8.00/kg</li>
<li>Centro-Oeste: R$ 7.70/kg</li>
</ul>
`
};
manualConteudo.bdi_margem = {
titulo: '📊 BDI e Margem de Lucro',
secao: 'ORÇAMENTO',
conteudo: `
<h2>O que é BDI?</h2>
<p>BDI (Benefícios e Despesas Indiretas) é um percentual aplicado sobre os custos diretos para cobrir:</p>
<h3>Componentes do BDI</h3>
<ul>
<li><strong>Administração Central:</strong> Escritório, contabilidade (5-8%)</li>
<li><strong>Lucro:</strong> Margem de lucro da empresa (8-15%)</li>
<li><strong>Impostos:</strong> ISS, PIS, COFINS (5-10%)</li>
<li><strong>Riscos:</strong> Contingência para imprevistos (2-5%)</li>
</ul>
<h3>BDI Típico por Tipo de Obra</h3>
<table>
<tr><th>Tipo de Obra</th><th>BDI Típico</th></tr>
<tr><td>Pequenas estruturas</td><td>20-25%</td></tr>
<tr><td>Edifícios comerciais</td><td>25-30%</td></tr>
<tr><td>Pontes e obras públicas</td><td>25-28%</td></tr>
<tr><td>Offshore e projetos complexos</td><td>30-35%</td></tr>
</table>
<h3>Exemplo de Cálculo</h3>
<div class="exemplos-box">
<p><strong>Custos Diretos:</strong> R$ 100.000,00</p>
<p><strong>BDI:</strong> 25%</p>
<p><strong>Valor BDI:</strong> R$ 100.000 × 0.25 = R$ 25.000,00</p>
<p><strong>TOTAL:</strong> R$ 125.000,00</p>
</div>
`
};
manualConteudo.ensaios_introducao = {
titulo: '✅ Introdução a Ensaios',
secao: 'ENSAIOS',
conteudo: `
<h2>Por que Ensaiar?</h2>
<p>Ensaios são testes realizados em materiais e soldas para verificar conformidade com especificações e normas.</p>
<h3>Tipos de Ensaios</h3>
<h4>Ensaios Destrutivos</h4>
<ul>
<li><strong>Tração:</strong> Mede fy, fu e alongamento</li>
<li><strong>Dureza:</strong> Mede resistência à penetração</li>
<li><strong>Charpy:</strong> Mede tenacidade ao impacto</li>
<li><strong>Dobramento:</strong> Verifica ductilidade da solda</li>
</ul>
<h4>Ensaios Não Destrutivos (END)</h4>
<ul>
<li><strong>Ultrassom (UT):</strong> Detecta defeitos internos</li>
<li><strong>Radiografia (RT):</strong> Imagem de defeitos</li>
<li><strong>Partículas Magnéticas (MT):</strong> Defeitos superficiais</li>
<li><strong>Líquido Penetrante (PT):</strong> Trincas superficiais</li>
</ul>
`
};
manualConteudo.dureza_escalas = {
titulo: '🔨 Escalas de Dureza',
secao: 'ENSAIOS',
conteudo: `
<h2>Escalas de Dureza</h2>
<p>Dureza mede a resistência de um material à deformação permanente por indentação.</p>
<h3>Brinell (HB)</h3>
<p><strong>Método:</strong> Esfera de aço ou tungstênio pressionada na superfície</p>
<p><strong>Faixa:</strong> 100-650 HB</p>
<p><strong>Aplicação:</strong> Aços estruturais, ferro fundido</p>
<h3>Rockwell C (HRC)</h3>
<p><strong>Método:</strong> Cone de diamante</p>
<p><strong>Faixa:</strong> 20-70 HRC</p>
<p><strong>Aplicação:</strong> Aços temperados, ferramentas</p>
<h3>Vickers (HV)</h3>
<p><strong>Método:</strong> Pirâmide de diamante</p>
<p><strong>Faixa:</strong> 100-1000+ HV</p>
<p><strong>Aplicação:</strong> Universal, todos os materiais</p>
<h3>Correlação com Resistência</h3>
<p>Para aços carbono:</p>
<p><strong>fu (MPa) ≈ HB × 10</strong></p>
<div class="exemplos-box">
<p>HB 250 → fu ≈ 2500 MPa</p>
</div>
`
};
manualConteudo.impacto_charpy = {
titulo: '📉 Ensaio de Impacto Charpy',
secao: 'ENSAIOS',
conteudo: `
<h2>O que é o Ensaio Charpy?</h2>
<p>Ensaio que mede a energia absorvida por um corpo de prova entalhado ao ser rompido por um pêndulo.</p>
<h3>Por que é Importante?</h3>
<p>Materiais podem se comportar de forma <strong>dúctil</strong> (absorvem energia) ou <strong>frágil</strong> (quebram subitamente) dependendo da temperatura.</p>
<h3>Temperatura de Transição (TTDF)</h3>
<p>Temperatura onde o material muda de comportamento dúctil para frágil.</p>
<p><strong>Critério comum:</strong> TTDF = temperatura onde energia = 27J</p>
<h3>Requisitos por Aplicação</h3>
<table>
<tr><th>Aplicação</th><th>Energia Mín</th><th>Temperatura</th></tr>
<tr><td>Estruturas internas</td><td>27J</td><td>0°C</td></tr>
<tr><td>Estruturas externas</td><td>27J</td><td>-20°C</td></tr>
<tr><td>Offshore/Ártico</td><td>40J</td><td>-40°C</td></tr>
</table>
`
};
manualConteudo.layout_furacao = {
titulo: '📍 Layout de Furação',
secao: 'CONEXÕES',
conteudo: `
<h2>Distâncias e Espaçamentos</h2>
<p>NBR 8800 e AISC 360 estabelecem limites para garantir resistência adequada.</p>
<h3>Distância de Borda</h3>
<p><strong>Mínimo:</strong> 1.5d (evita ruptura da borda)</p>
<p><strong>Máximo:</strong> 12t ou 150mm (evita empenamento)</p>
<h3>Espaçamento entre Furos</h3>
<p><strong>Mínimo:</strong> 2.67d (evita interferência de tensões)</p>
<p><strong>Máximo:</strong> 300mm (evita correlação local)</p>
<h3>Exemplo</h3>
<div class="exemplos-box">
<p><strong>Parafuso Ø20mm, Chapa 10mm</strong></p>
<p>Mínimo borda: 1.5 × 20 = 30mm</p>
<p>Máximo borda: 12 × 10 = 120mm</p>
<p>Mínimo espaçamento: 2.67 × 20 = 53.4mm</p>
</div>
`
};
manualConteudo.eletrodos_tipos = {
titulo: '🔥 Tipos de Eletrodos',
secao: 'SOLDAGEM',
conteudo: `
<h2>Eletrodos Revestidos (SMAW)</h2>
<p>Eletrodo revestido é composto por alma metálica + revestimento que gera escória protetora e gás.</p>
<h3>Classificação AWS</h3>
<table>
<tr><th>Eletrodo</th><th>Revestimento</th><th>Resistência</th><th>Aplicação</th></tr>
<tr><td><strong>E6013</strong></td><td>Rutílico</td><td>420 MPa</td><td>Geral, fácil</td></tr>
<tr><td><strong>E7018</strong></td><td>Básico</td><td>485 MPa</td><td>Estrutural (padrão)</td></tr>
<tr><td><strong>E8018</strong></td><td>Básico</td><td>550 MPa</td><td>Alta resistência</td></tr>
</table>
<h3>Vantagens do Básico (E7018)</h3>
<ul>
<li>✅ Baixo hidrogênio (previne trincas)</li>
<li>✅ Alta tenacidade (Charpy 47J)</li>
<li>✅ Excelente para estruturas críticas</li>
</ul>
`
};
manualConteudo.sequencia_soldagem = {
titulo: '🔄 Sequência de Soldagem',
secao: 'SOLDAGEM',
conteudo: `
<h2>Por que Sequência Importa?</h2>
<p>A ordem de deposição da solda afeta diretamente as distorções e tensões residuais na estrutura.</p>
<h3>Padrões de Soldagem</h3>
<h4>1. Skip Welding (Recomendado)</h4>
<p>Solda em segmentos alternados, deixando espaços que são preenchidos depois.</p>
<p><strong>Vantagem:</strong> Reduz distorções em 80%</p>
<h4>2. Backstep Welding</h4>
<p>Soldagem em segmentos curtos na direção oposta ao avanço geral.</p>
<p><strong>Vantagem:</strong> Reduz distorções em 60%</p>
<h4>3. Contínuo (Não Recomendado)</h4>
<p>Soldagem contínua sem paradas.</p>
<p><strong>Desvantagem:</strong> Máxima distorção</p>
`
};
manualConteudo.equivalencias_normas = {
titulo: '🌍 Equivalências Internacionais',
secao: 'MATERIAIS',
conteudo: `
<h2>Por que Equivalências?</h2>
<p>Projetos internacionais podem especificar aços de diferentes normas. Conhecer equivalências permite substituição adequada.</p>
<h3>Principais Equivalências</h3>
<table>
<tr><th>ASTM</th><th>EN</th><th>JIS</th><th>NBR</th></tr>
<tr><td>A36</td><td>S235JR</td><td>SS400</td><td>-</td></tr>
<tr><td>A572 Gr.50</td><td>S355J2</td><td>SM490</td><td>AR350</td></tr>
<tr><td>A588</td><td>S355K2G3</td><td>-</td><td>-</td></tr>
</table>
<h3>⚠️ Cuidados na Substituição</h3>
<ul>
<li>Verificar composição química</li>
<li>Confirmar propriedades mecânicas</li>
<li>Checar soldabilidade (CEV)</li>
<li>Validar com engenheiro responsável</li>
</ul>
`
};
manualConteudo.acos_estruturais = {
titulo: '🏭 Aços Estruturais Comuns',
secao: 'MATERIAIS',
conteudo: `
<h2>Aços Mais Usados no Brasil</h2>
<h3>ASTM A36 - O "Trabalhador"</h3>
<p><strong>Propriedades:</strong> fy=250 MPa, fu=400 MPa</p>
<p><strong>Aplicação:</strong> Estruturas gerais, baixa responsabilidade</p>
<p><strong>Vantagens:</strong> Barato, muito soldável, disponível</p>
<h3>ASTM A572 Gr.50 - O "Profissional"</h3>
<p><strong>Propriedades:</strong> fy=345 MPa, fu=450 MPa</p>
<p><strong>Aplicação:</strong> Edifícios altos, pontes, estruturas pesadas</p>
<p><strong>Vantagens:</strong> Ótima relação custo/benefício</p>
<h3>EN S355J2 - O "Europeu"</h3>
<p><strong>Propriedades:</strong> fy=355 MPa, fu=490 MPa</p>
<p><strong>Aplicação:</strong> Projetos internacionais</p>
<p><strong>Vantagens:</strong> Boa tenacidade, amplamente especificado</p>
`
};
manualConteudo.preparo_superficie = {
titulo: '🧹 Preparação de Superfície',
secao: 'PINTURA',
conteudo: `
<h2>A Preparação É Fundamental!</h2>
<p>90% dos problemas de pintura vem de preparação inadequada da superfície.</p>
<h3>Graus de Limpeza ISO 8501-1</h3>
<table>
<tr><th>Grau</th><th>Descrição</th><th>Uso</th></tr>
<tr><td><strong>Sa 1</strong></td><td>Jateamento ligeiro</td><td>Não recomendado</td></tr>
<tr><td><strong>Sa 2</strong></td><td>Jateamento comercial</td><td>Ambientes leves</td></tr>
<tr><td><strong>Sa 2½</strong></td><td>Jateamento ao metal quase branco</td><td><strong>Padrão indústria</strong></td></tr>
<tr><td><strong>Sa 3</strong></td><td>Jateamento ao metal branco</td><td>Ambientes severos</td></tr>
</table>
<h3>Métodos de Preparação</h3>
<ul>
<li><strong>Jateamento Abrasivo:</strong> Método mais eficaz</li>
<li><strong>Lixamento Mecânico:</strong> Para pequenas áreas</li>
<li><strong>Escovamento:</strong> Manutenção apenas</li>
<li><strong>Desengraxe:</strong> Sempre necessário</li>
</ul>
`
};
manualConteudo.precos_mercado = {
titulo: '💲 Preços do Mercado Brasileiro',
secao: 'ORÇAMENTO',
conteudo: `
<h2>Preços Médios 2025</h2>
<p>Valores de referência para orçamentos (sujeitos a variação).</p>
<h3>Aços Estruturais</h3>
<table>
<tr><th>Região</th><th>A36 (R$/kg)</th><th>A572 (R$/kg)</th></tr>
<tr><td>Sudeste (SP/RJ)</td><td>7.50</td><td>8.50</td></tr>
<tr><td>Sul (RS/SC/PR)</td><td>7.20</td><td>8.20</td></tr>
<tr><td>Nordeste</td><td>8.00</td><td>9.00</td></tr>
<tr><td>Centro-Oeste</td><td>7.70</td><td>8.70</td></tr>
</table>
<h3>Serviços</h3>
<ul>
<li><strong>Soldagem:</strong> R$ 60-70/h (soldador qualificado)</li>
<li><strong>Pintura:</strong> R$ 35-45/m²</li>
<li><strong>Montagem:</strong> R$ 50-65/h</li>
</ul>
<h3>Consumíveis</h3>
<ul>
<li><strong>E7018:</strong> R$ 45/kg</li>
<li><strong>Tinta Epóxi C3:</strong> R$ 80/L</li>
<li><strong>Parafuso A325 M16:</strong> R$ 1.20/un</li>
</ul>
`
};
function addHelpButton(sectionId) {
const mainContent = document.getElementById('main-content');
if (!mainContent) return;
const existingBtn = mainContent.querySelector('.btn-help');
if (existingBtn) existingBtn.remove();
if (ajudaDatabase[sectionId]) {
const btnHelp = document.createElement('button');
btnHelp.className = 'btn-help';
btnHelp.textContent = '❓';
btnHelp.onclick = () => openAjudaModal(sectionId);
btnHelp.title = 'Clique para ajuda';
mainContent.style.position = 'relative';
mainContent.appendChild(btnHelp);
}
}
function openAjudaModal(sectionId) {
currentHelpSection = sectionId;
const ajuda = ajudaDatabase[sectionId];
if (!ajuda) return;
document.getElementById('ajudaTitulo').textContent = ajuda.titulo;
// Tab 0: Explicação
document.getElementById('help-tab-0').innerHTML = `
<div class="ajuda-secao">
<h3>O que é?</h3>
<p>${ajuda.oQueE}</p>
</div>
<div class="ajuda-secao">
<h3>Para que serve?</h3>
<p>${ajuda.paraQueServe}</p>
</div>
<div class="ajuda-secao">
<h3>Quando usar?</h3>
<p>${ajuda.quandoUsar}</p>
</div>
<div class="ajuda-secao">
<h3>⚠️ Avisos Importantes</h3>
<ul>${ajuda.avisos.map(a => `<li>${a}</li>`).join('')}</ul>
</div>
`;
// Tab 1: Campos
document.getElementById('help-tab-1').innerHTML = `
<table class="tabela-campos">
<thead>
<tr>
<th>Campo</th>
<th>Unidade</th>
<th>Significado</th>
<th>Intervalo Típico</th>
<th>Dica</th>
</tr>
</thead>
<tbody>
${ajuda.campos.map(c => `
<tr>
<td><strong>${c.nome}</strong></td>
<td>${c.unidade}</td>
<td>${c.significado}</td>
<td>${c.intervalo}</td>
<td>${c.dica}</td>
</tr>
`).join('')}
</tbody>
</table>
`;
// Tab 2: Resultados
document.getElementById('help-tab-2').innerHTML = `
<div class="ajuda-secao">
<h3>O que significam os resultados?</h3>
${ajuda.resultados}
</div>
`;
// Tab 3: Referências
document.getElementById('help-tab-3').innerHTML = `
<div class="ajuda-secao">
<h3>📚 Referências Bibliográficas</h3>
<div class="referencias-list">
${ajuda.referencias.map(r => `
<div class="referencia-item">
<strong>${r.titulo}</strong><br>
${r.ano ? `Ano: ${r.ano}<br>` : ''}
${r.url ? `<a href="${r.url}" target="_blank">${r.url}</a>` : ''}
</div>
`).join('')}
</div>
<h3>📖 Leia também no Manual</h3>
<ul class="manual-links">
${ajuda.manualRelacionado.map(tema => {
const conteudo = manualConteudo[tema];
return conteudo ? `<li><a href="#" onclick="abrirManualNoTema('${tema}'); return false;">${conteudo.titulo}</a></li>` : '';
}).join('')}
</ul>
</div>
`;
document.getElementById('modalAjuda').classList.add('active');
}
function closeAjudaModal() {
document.getElementById('modalAjuda').classList.remove('active');
// Clear search when closing
document.getElementById('helpSearch').value = '';
}
// Global search index - all tools and tabs
const globalSearchIndex = [
// MATERIAIS
{ id: 'cev', title: 'CEV Avançado', category: 'MATERIAIS', icon: '⚗️', description: 'Cálculo de Carbono Equivalente (IIW + Pcm)', keywords: ['carbono', 'equivalente', 'soldabilidade', 'cev', 'pcm'] },
{ id: 'seletor', title: 'Seletor de Aço', category: 'MATERIAIS', icon: '🔍', description: 'Selecione o aço ideal para seu projeto', keywords: ['aço', 'material', 'seleção', 'astm', 'nbr'] },
{ id: 'equivalencias', title: 'Equivalências', category: 'MATERIAIS', icon: '🔄', description: 'Equivalências entre normas ASTM, EN, NBR', keywords: ['equivalência', 'norma', 'conversão', 'astm', 'en', 'nbr'] },
{ id: 'comparativo', title: 'Comparativo', category: 'MATERIAIS', icon: '⚖️', description: 'Compare propriedades de diferentes aços', keywords: ['comparar', 'propriedades', 'resistência'] },
// CONEXÕES - Main
{ id: 'parafusos', title: 'Ligações Parafusadas', category: 'CONEXÕES', icon: '🔩', description: 'Sistema completo de dimensionamento de parafusos', keywords: ['parafuso', 'conexão', 'ligação', 'bolt'] },
{ id: 'parafusos-cisalhamento', title: 'Cisalhamento de Parafusos', category: 'CONEXÕES', icon: '🔩', description: 'Resistência ao cisalhamento de parafusos', keywords: ['cisalhamento', 'shear', 'cortante', 'parafuso'], path: 'parafusos > Aba 1', tabIndex: 0 },
{ id: 'parafusos-esmagamento', title: 'Esmagamento (Bearing)', category: 'CONEXÕES', icon: '🔨', description: 'Verificação de esmagamento da chapa', keywords: ['esmagamento', 'bearing', 'chapa'], path: 'parafusos > Aba 2', tabIndex: 1 },
{ id: 'parafusos-bloco', title: 'Ruptura em Bloco', category: 'CONEXÕES', icon: '⚠️', description: 'Verificação de ruptura em bloco', keywords: ['bloco', 'ruptura', 'block', 'shear'], path: 'parafusos > Aba 3', tabIndex: 2 },
{ id: 'layout', title: 'Layout de Furação', category: 'CONEXÕES', icon: '📐', description: 'Dimensionamento de layout de furos', keywords: ['layout', 'furação', 'furo', 'espaçamento'], path: 'parafusos > Aba 4', tabIndex: 3 },
{ id: 'parafuso-vs-solda', title: 'Parafuso vs Solda', category: 'CONEXÕES', icon: '⚖️', description: 'Comparação econômica parafuso vs solda', keywords: ['comparação', 'custo', 'economia'], path: 'parafusos > Aba 5', tabIndex: 4 },
// SOLDAGEM - Main
{ id: 'preaquecimento', title: 'Pré-Aquecimento', category: 'SOLDAGEM', icon: '🌡️', description: 'Cálculo de temperatura de pré-aquecimento AWS D1.1', keywords: ['pré-aquecimento', 'preaquecimento', 'temperatura', 'preheat'], path: 'soldagem > Aba 1', tabIndex: 0 },
{ id: 'filete', title: 'Soldas de Filete', category: 'SOLDAGEM', icon: '⚡', description: 'Dimensionamento de soldas de filete', keywords: ['filete', 'fillet', 'perna', 'solda'], path: 'soldagem > Aba 2', tabIndex: 1 },
{ id: 'energia', title: 'Energia de Soldagem', category: 'SOLDAGEM', icon: '🔥', description: 'Cálculo de Heat Input', keywords: ['energia', 'heat', 'input', 'calor'], path: 'soldagem > Aba 3', tabIndex: 2 },
{ id: 'consumo-eletrodo', title: 'Consumo de Eletrodos', category: 'SOLDAGEM', icon: '📊', description: 'Cálculo de consumo de eletrodos', keywords: ['consumo', 'eletrodo', 'quantidade'], path: 'soldagem > Aba 4', tabIndex: 3 },
{ id: 'sequencia-soldagem', title: 'Sequência de Soldagem', category: 'SOLDAGEM', icon: '🔄', description: 'Planejamento de sequência de soldagem', keywords: ['sequência', 'ordem', 'distorção'], path: 'soldagem > Aba 5', tabIndex: 4 },
{ id: 'padroes-soldagem', title: 'Padrões e Normas', category: 'SOLDAGEM', icon: '📋', description: 'Normas e requisitos de soldagem', keywords: ['norma', 'padrão', 'aws', 'asme'], path: 'soldagem > Aba 6', tabIndex: 5 },
// ENSAIOS
{ id: 'dureza', title: 'Conversão de Dureza', category: 'ENSAIOS', icon: '💎', description: 'Conversão entre escalas de dureza', keywords: ['dureza', 'hardness', 'rockwell', 'brinell', 'vickers'] },
{ id: 'charpy', title: 'Ensaio Charpy', category: 'ENSAIOS', icon: '🔨', description: 'Análise de tenacidade ao impacto', keywords: ['charpy', 'impacto', 'tenacidade', 'energia'] },
{ id: 'certificado', title: 'Checklist de Certificado', category: 'ENSAIOS', icon: '📜', description: 'Verificação de certificados de qualidade', keywords: ['certificado', 'qualidade', 'inspeção'] },
{ id: 'ultrassom', title: 'Ultrassom', category: 'ENSAIOS', icon: '📡', description: 'Interpretação de ensaios ultrassônicos', keywords: ['ultrassom', 'us', 'ensaio', 'não destrutivo'] },
// PINTURA
{ id: 'area-pintura', title: 'Área de Pintura', category: 'PINTURA', icon: '📏', description: 'Cálculo de área para pintura', keywords: ['área', 'superfície', 'pintura'] },
{ id: 'consumo-tinta', title: 'Consumo de Tinta', category: 'PINTURA', icon: '🎨', description: 'Cálculo de consumo de tinta', keywords: ['consumo', 'tinta', 'quantidade', 'litros'] },
{ id: 'galvanizacao', title: 'Galvanização', category: 'PINTURA', icon: '⚡', description: 'Análise de galvanização', keywords: ['galvanização', 'zinco', 'proteção'] },
{ id: 'custo-pintura', title: 'Custo de Pintura', category: 'PINTURA', icon: '💰', description: 'Estimativa de custos de pintura', keywords: ['custo', 'preço', 'orçamento', 'pintura'] },
{ id: 'secagem', title: 'Tempo de Secagem', category: 'PINTURA', icon: '⏱️', description: 'Cálculo de tempo de secagem', keywords: ['secagem', 'tempo', 'cura'] },
{ id: 'inspecao-pintura', title: 'Inspeção de Pintura', category: 'PINTURA', icon: '🔍', description: 'Checklist de inspeção de pintura', keywords: ['inspeção', 'qualidade', 'verificação'] },
// ORÇAMENTO
{ id: 'orcamento', title: 'Orçamento Detalhado', category: 'ORÇAMENTO', icon: '💼', description: 'Orçamento completo de estruturas', keywords: ['orçamento', 'custo', 'preço', 'budget'] },
{ id: 'peso-rigging', title: 'Peso e Rigging', category: 'ORÇAMENTO', icon: '⚖️', description: 'Cálculo de peso e içamento', keywords: ['peso', 'rigging', 'içamento', 'transporte'] },
{ id: 'referencia', title: 'Referências Técnicas', category: 'ORÇAMENTO', icon: '📚', description: 'Biblioteca de referências técnicas', keywords: ['referência', 'manual', 'documentação'] }
];
// Open global search modal
function openGlobalSearchModal() {
document.getElementById('globalSearchModal').classList.add('active');
document.getElementById('globalSearchInput').value = '';
document.getElementById('globalSearchResults').innerHTML = `
<p style="color: var(--color-text-secondary); text-align: center; padding: 40px;">
Digite algo para começar a buscar...
</p>
`;
setTimeout(() => document.getElementById('globalSearchInput').focus(), 100);
}
// Close global search modal
function closeGlobalSearchModal() {
document.getElementById('globalSearchModal').classList.remove('active');
}
// Search tools globally
function buscarFerramentasGlobal() {
const searchTerm = document.getElementById('globalSearchInput').value.toLowerCase().trim();
const resultsContainer = document.getElementById('globalSearchResults');
if (!searchTerm) {
resultsContainer.innerHTML = `
<p style="color: var(--color-text-secondary); text-align: center; padding: 40px;">
Digite algo para começar a buscar...
</p>
`;
return;
}
// Search in index
const results = globalSearchIndex.filter(item => {
const titleMatch = item.title.toLowerCase().includes(searchTerm);
const descMatch = item.description.toLowerCase().includes(searchTerm);
const keywordMatch = item.keywords.some(k => k.includes(searchTerm));
const categoryMatch = item.category.toLowerCase().includes(searchTerm);
return titleMatch || descMatch || keywordMatch || categoryMatch;
});
if (results.length === 0) {
resultsContainer.innerHTML = `
<div class="no-results">
<div class="no-results-icon">🔍</div>
<p><strong>Nenhum resultado encontrado</strong></p>
<p>Tente buscar por: "solda", "parafuso", "charpy", "pintura", etc.</p>
</div>
`;
return;
}
// Display results
resultsContainer.innerHTML = results.map(item => {
const highlightedTitle = item.title.replace(new RegExp(`(${searchTerm})`, 'gi'), '<mark class="highlight">$1</mark>');
const highlightedDesc = item.description.replace(new RegExp(`(${searchTerm})`, 'gi'), '<mark class="highlight">$1</mark>');
return `
<div class="search-result-item" onclick="navegarParaFerramenta('${item.id}', ${item.tabIndex || 'null'})">
<div class="search-result-item-header">
<span class="search-result-item-icon">${item.icon}</span>
<span class="search-result-item-title">${highlightedTitle}</span>
<span class="search-result-item-category">${item.category}</span>
</div>
<div class="search-result-item-description">${highlightedDesc}</div>
${item.path ? `<div class="search-result-item-path">📍 ${item.path}</div>` : ''}
</div>
`;
}).join('');
}
// Navigate to a specific tool/tab
function navegarParaFerramenta(toolId, tabIndex) {
closeGlobalSearchModal();
// Determine which section to show
let sectionId = toolId;
// Handle tabs within sections
if (toolId.startsWith('parafusos-')) {
sectionId = 'parafusos';
} else if (['filete', 'energia', 'consumo-eletrodo', 'sequencia-soldagem', 'padroes-soldagem'].includes(toolId)) {
sectionId = 'preaquecimento'; // SOLDAGEM section
}
// Show the section
showSection(sectionId);
// Switch to specific tab if needed
setTimeout(() => {
if (tabIndex !== null && tabIndex !== undefined) {
if (sectionId === 'parafusos') {
switchTab(tabIndex);
} else if (sectionId === 'preaquecimento') {
switchWeldTab(tabIndex);
}
}
// Scroll to top
window.scrollTo({ top: 0, behavior: 'smooth' });
}, 200);
}
// Filter help content based on search
function filtrarConteudoAjuda() {
const searchTerm = document.getElementById('helpSearch').value.toLowerCase();
const activeTab = document.querySelector('.help-tab-content.active');
if (!activeTab || !searchTerm) {
// Remove all highlights if search is empty
if (activeTab) {
const content = activeTab.innerHTML;
activeTab.innerHTML = content.replace(/<mark class="highlight">(.*?)<\/mark>/g, '$1');
}
return;
}
// Get original content without highlights
const ajuda = ajudaDatabase[currentHelpSection];
if (!ajuda) return;
// Re-render current tab with highlights
const activeTabIndex = Array.from(document.querySelectorAll('.help-tab-content')).indexOf(activeTab);
// Helper function to highlight text
const highlightText = (text) => {
if (!searchTerm) return text;
const regex = new RegExp(`(${searchTerm})`, 'gi');
return text.replace(regex, '<mark class="highlight">$1</mark>');
};
if (activeTabIndex === 0) {
// Tab 0: Explicação
activeTab.innerHTML = `
<div class="ajuda-secao">
<h3>O que é?</h3>
<p>${highlightText(ajuda.oQueE)}</p>
</div>
<div class="ajuda-secao">
<h3>Para que serve?</h3>
<p>${highlightText(ajuda.paraQueServe)}</p>
</div>
<div class="ajuda-secao">
<h3>Quando usar?</h3>
<p>${highlightText(ajuda.quandoUsar)}</p>
</div>
<div class="ajuda-secao">
<h3>⚠️ Avisos Importantes</h3>
<ul>${ajuda.avisos.map(a => `<li>${highlightText(a)}</li>`).join('')}</ul>
</div>
`;
} else if (activeTabIndex === 1) {
// Tab 1: Campos
activeTab.innerHTML = `
<table class="tabela-campos">
<thead>
<tr>
<th>Campo</th>
<th>Unidade</th>
<th>Significado</th>
<th>Intervalo Típico</th>
<th>Dica</th>
</tr>
</thead>
<tbody>
${ajuda.campos.map(c => `
<tr>
<td><strong>${highlightText(c.nome)}</strong></td>
<td>${highlightText(c.unidade)}</td>
<td>${highlightText(c.significado)}</td>
<td>${highlightText(c.intervalo)}</td>
<td>${highlightText(c.dica)}</td>
</tr>
`).join('')}
</tbody>
</table>
`;
} else if (activeTabIndex === 2) {
// Tab 2: Resultados
activeTab.innerHTML = `
<div class="ajuda-secao">
<h3>O que significam os resultados?</h3>
${highlightText(ajuda.resultados)}
</div>
`;
} else if (activeTabIndex === 3) {
// Tab 3: Referências
activeTab.innerHTML = `
<div class="ajuda-secao">
<h3>📚 Referências Bibliográficas</h3>
<div class="referencias-list">
${ajuda.referencias.map(r => `
<div class="referencia-item">
<strong>${highlightText(r.titulo)}</strong><br>
${r.ano ? `Ano: ${r.ano}<br>` : ''}
${r.url ? `<a href="${r.url}" target="_blank">${r.url}</a>` : ''}
</div>
`).join('')}
</div>
<h3>📖 Leia também no Manual</h3>
<ul class="manual-links">
${ajuda.manualRelacionado.map(tema => {
const conteudo = manualConteudo[tema];
return conteudo ? `<li><a href="#" onclick="abrirManualNoTema('${tema}'); return false;">${highlightText(conteudo.titulo)}</a></li>` : '';
}).join('')}
</ul>
</div>
`;
}
}
function switchHelpTab(index) {
document.querySelectorAll('.help-tab-btn').forEach((btn, i) => {
btn.classList.toggle('active', i === index);
});
document.querySelectorAll('.help-tab-content').forEach((content, i) => {
content.classList.toggle('active', i === index);
});
}
function abrirManualRelacionado() {
if (currentHelpSection && ajudaDatabase[currentHelpSection]) {
const temas = ajudaDatabase[currentHelpSection].manualRelacionado;
if (temas && temas.length > 0) {
closeAjudaModal();
abrirManualNoTema(temas[0]);
}
}
}
function openManualUsuario() {
carregarManualNav();
abrirManualNoTema('aco_introducao');
document.getElementById('modalManual').classList.add('active');
}
function closeManualModal() {
document.getElementById('modalManual').classList.remove('active');
}
function carregarManualNav() {
const nav = document.getElementById('manualNav');
let html = '';
Object.keys(manualNavStructure).forEach(secao => {
html += `
<div class="manual-secao">
<button class="manual-secao-btn" onclick="toggleManualSecao(this)">
${secao}
</button>
<div class="manual-items">
${manualNavStructure[secao].map(tema => {
const conteudo = manualConteudo[tema];
return conteudo ? `
<button class="manual-item" onclick="abrirManualNoTema('${tema}')">
${conteudo.titulo}
</button>
` : '';
}).join('')}
</div>
</div>
`;
});
nav.innerHTML = html;
}
function toggleManualSecao(btn) {
const items = btn.nextElementSibling;
items.classList.toggle('active');
}
function abrirManualNoTema(temaId) {
const conteudo = manualConteudo[temaId];
if (!conteudo) return;
document.getElementById('manualConteudo').innerHTML = `
<h2>${conteudo.titulo}</h2>
<div class="manual-secao-badge" style="display: inline-block; background: var(--color-primary); color: var(--color-btn-primary-text); padding: 4px 12px; border-radius: 4px; font-size: 12px; margin-bottom: 20px;">
${conteudo.secao}
</div>
${conteudo.conteudo}
`;
// Mark active item
document.querySelectorAll('.manual-item').forEach(item => {
item.classList.remove('active');
});
const activeBtn = Array.from(document.querySelectorAll('.manual-item')).find(btn =>
btn.textContent.includes(conteudo.titulo)
);
if (activeBtn) {
activeBtn.classList.add('active');
// Open parent section
const items = activeBtn.parentElement;
if (items) items.classList.add('active');
}
document.getElementById('modalManual').classList.add('active');
// Scroll to top
document.querySelector('.manual-content').scrollTop = 0;
}
function buscarNoManual() {
const searchTerm = document.getElementById('manualSearch').value.toLowerCase();
const items = document.querySelectorAll('.manual-item');
items.forEach(item => {
const text = item.textContent.toLowerCase();
if (text.includes(searchTerm)) {
item.style.display = 'block';
} else {
item.style.display = 'none';
}
});
}
document.addEventListener('DOMContentLoaded', function() {
console.log('🚀 SteelBase v7.5 - Inicializando...');
try {
// Load admin config from localStorage
try {
const savedConfig = localStorage.getItem('acoCalcProAdminConfig');
if (savedConfig) {
const parsed = JSON.parse(savedConfig);
// Merge configurations, but keep new default values for missing keys
// This ensures new tools added to the code are visible by default
if (parsed.toolsVisibility) {
// Merge toolsVisibility: keep saved values but add new defaults
Object.keys(adminConfig.toolsVisibility).forEach(key => {
if (parsed.toolsVisibility[key] === undefined) {
// New tool not in saved config, keep default
parsed.toolsVisibility[key] = adminConfig.toolsVisibility[key];
}
});
}
Object.assign(adminConfig, parsed);
// FORCE UPDATE: Ensure catalog items are visible (v7.5 update)
const catalogoItems = ['cantoneiras', 'barras-redondas', 'tubos-circulares', 'perfis-i', 'perfis-w', 'tubos-rhs', 'chapas', 'perfis-hp', 'barras-roscadas', 'barras-chatas'];
catalogoItems.forEach(item => {
adminConfig.toolsVisibility[item] = true;
});
// Save updated config back to localStorage
localStorage.setItem('acoCalcProAdminConfig', JSON.stringify(adminConfig));
console.log('✅ Configurações do Admin carregadas e atualizadas');
}
} catch (error) {
console.warn('⚠️ Erro ao carregar configurações do Admin:', error);
}
// Apply admin config
if (typeof applyAdminConfig === 'function') {
applyAdminConfig();
}
// Load preferences first
if (typeof loadPreferences === 'function') {
loadPreferences();
}
if (typeof applyUserPreferences === 'function') {
applyUserPreferences();
}
// Initialize app
showSection('cev');
// Initialize optional functions safely
if (typeof mostrarEquivalencias === 'function') {
mostrarEquivalencias();
}
if (typeof gerarChecklistCertificado === 'function') {
gerarChecklistCertificado();
}
if (typeof updatePaintFields === 'function') {
updatePaintFields();
}
if (typeof updateWeightFields === 'function') {
updateWeightFields();
}
// Apply admin config and filter (no forced expansion)
applyAdminConfig();
// Debug: verificar configuração do catálogo
console.log('📋 Verificando configuração do Catálogo de Perfis:');
const catalogoItems = ['cantoneiras', 'barras-redondas', 'tubos-circulares', 'perfis-i', 'perfis-w', 'tubos-rhs', 'chapas', 'perfis-hp', 'barras-roscadas', 'barras-chatas'];
catalogoItems.forEach(item => {
const isVisible = adminConfig.toolsVisibility[item];
console.log(` ${item}: ${isVisible ? '✅ visível' : '❌ escondido'}`);
});
filterToolsByMode();
// Initialize sidebar expansion based on visibility and manual state
initializeSidebarExpansion();
addHelpButton('cev');
console.log('✅ SteelBase carregado com sucesso!');
} catch (error) {
console.error('❌ Erro na inicialização:', error);
} finally {
// Remove loading screen after initialization
setTimeout(() => {
const loadingScreen = document.getElementById('app-loading');
if (loadingScreen) {
loadingScreen.style.opacity = '0';
loadingScreen.style.transition = 'opacity 0.3s ease';
setTimeout(() => loadingScreen.remove(), 300);
}
}, 500);
}
// Initialize budget when switching to orcamento section
const observer = new MutationObserver(() => {
if (appState.currentSection === 'orcamento') {
setTimeout(initializeBudget, 100);
}
});
// Removido: listener de fechamento do modal Admin legado
});