// ========================================
// AÇO CALC PRO v6.5 - PROFESSIONAL EDITION
// Plataforma Técnica Completa com Base de Materiais
// ========================================
// In-memory data storage (no localStorage - using JavaScript objects)
const appState = {
history: [],
favorites: [],
budgetItems: [],
currentSection: 'cev',
currentTheme: 'dark', // 'dark' or 'light'
expertMode: false,
currentSidebarTab: 0
};
// Admin configuration (in-memory)
const adminConfig = {
appName: 'AÇO CALC PRO',
appSubtitle: 'Plataforma Técnica com Base de Dados de Materiais Brasileiros',
footerText: '© 2025 AÇO CALC PRO v6.5 PROFESSIONAL EDITION - Plataforma Técnica com Base de Dados de Materiais Brasileiros',
themeDefault: 'escuro',
modeDefault: 'simples',
toolsVisibility: {
'cev': true,
'seletor': true,
'equivalencias': false,
'comparativo': false,
'parafusos': true,
'layout': true,
'parafuso-vs-solda': false,
'preaquecimento': true,
'dureza': true,
'charpy': true,
'certificado': false,
'ultrassom': false,
'area-pintura': true,
'consumo-tinta': true,
'galvanizacao': false,
'custo-pintura': true,
'secagem': false,
'inspecao-pintura': false,
'orcamento': true,
'peso-rigging': false,
'referencia': false
}
};
// ========================================
// CSV MAPPING AND LOADING FUNCTIONS v6.6
// ========================================
const csvMapping = {
'perfil_w': 'csv_dados/perfis_w.csv',
'perfil_i': 'csv_dados/perfis_i.csv',
'perfil_hp': 'csv_dados/perfis_hp.csv',
'cantoneira': 'csv_dados/cantoneiras.csv',
'tubo_circ': 'csv_dados/tubos_circulares.csv',
'tubo_rhs': 'csv_dados/tubos_rhs.csv',
'chapa': 'csv_dados/chapas.csv',
'barra': 'csv_dados/barras.csv',
'eletrodo': 'csv_dados/eletrodos.csv',
'parafuso': 'csv_dados/parafusos.csv',
'tinta': 'csv_dados/tintas.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);
// Add help button after content loads
setTimeout(() => addHelpButton(sectionId), 100);
}
function loadSectionContent(sectionId) {
const content = document.getElementById('main-content');
const sections = {
'cev': getCEVContent(),
'seletor': getSeletorContent(),
'equivalencias': getEquivalenciasContent(),
'comparativo': getComparativoContent(),
'parafusos': getParafusosContent(),
'layout': getLayoutContent(),
'parafuso-vs-solda': getParafusoVsSoldaContent(),
'preaquecimento': getPreaquecimentoContent(),
'solda-filete': getSoldaFileteContent(),
'energia-soldagem': getEnergiaSoldagemContent(),
'consumo-eletrodos': getConsumoEletrodosContent(),
'dureza': getDurezaContent(),
'charpy': getCharpyContent(),
'certificado': getCertificadoContent(),
'ultrassom': getUltrassomContent(),
'area-pintura': getAreaPinturaContent(),
'consumo-tinta': getConsumoTintaContent(),
'galvanizacao': getGalvanizacaoContent(),
'custo-pintura': getCustoPinturaContent(),
'secagem': getSecagemContent(),
'inspecao-pintura': getInspecaoPinturaContent(),
'orcamento': getOrcamentoContent(),
'peso-rigging': getPesoRiggingContent(),
'referencia': getReferenciaContent()
};
content.innerHTML = sections[sectionId] || '
Seção não encontrada
';
}
function toggleTheme() {
appState.currentTheme = appState.currentTheme === 'dark' ? 'light' : 'dark';
applyTheme();
}
function applyTheme() {
document.documentElement.setAttribute('data-theme', appState.currentTheme);
const btn = document.getElementById('theme-toggle');
if (btn) {
btn.textContent = appState.currentTheme === 'dark' ? '☀️ Claro' : '🌙 Escuro';
btn.classList.toggle('light', appState.currentTheme === 'light');
}
}
function toggleExpertMode() {
appState.expertMode = !appState.expertMode;
document.documentElement.classList.toggle('expert-mode', appState.expertMode);
const btn = document.getElementById('expert-toggle');
btn.textContent = appState.expertMode ? '🔬 Expert' : '🎯 Simples';
btn.classList.toggle('active', appState.expertMode);
filterToolsByMode();
}
function filterToolsByMode() {
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');
}
}
});
}
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');
}
}
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 = 'Nenhum cálculo no histórico
';
} else {
list.innerHTML = appState.history.map(item => `
${item.title}
${item.date}
${item.details}
`).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 = 'Nenhuma seção favoritada
';
} else {
list.innerHTML = appState.favorites.map(sectionId => `
${getSectionName(sectionId)}
`).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 = `
🏥 INTERPRETAÇÃO ULTRASSOM - RESULTADO
NORMA APLICADA: ${normName}
Descontinuidade: ${typeName}
Localização: ${location.charAt(0).toUpperCase() + location.slice(1)}
${type === 'porosidade' ? `
DADOS DA DESCONTINUIDADE:
• Diâmetro: ${diameter} mm
• Quantidade: ${qty} poros
• Tamanho Total: ${(qty * diameter).toFixed(1)} mm
• Profundidade: ${depth} mm
• Espessura Chapa: ${thickness} mm
CRITÉRIO ${normName}:
Porosidade Isolada:
• Diâmetro máximo: ${maxDiameter} mm
• Quantidade máxima: ${maxQtyIn25mm} poros em 25mm
• Comprimento total permitido: ${(25 * 0.36).toFixed(1)} mm em 25mm
• Profundidade máxima: ${maxDepth.toFixed(1)} mm (espessura/4)
` : type === 'trinca' ? `
⚠️ DESCONTINUIDADE CRÍTICA:
Trincas são defeitos graves que comprometem a integridade estrutural.
Nenhuma norma permite trincas de qualquer tamanho.
` : `
DADOS:
• Comprimento: ${length} mm
• Profundidade: ${depth} mm
• Espessura: ${thickness} mm
`}
📊 ANÁLISE:
${reasoning.map(r => `• ${r}`).join(' ')}
RESULTADO: ${status}
${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.'}
${status === '❌ REJEITA' ? `
🔧 OPÇÕES DE REPARO:
1. Retrabalho Total: Remover completamente a solda defeituosa e refazer
2. Retoque Local: Escarear o defeito e preencher com nova solda
3. Análise de Risco: Para casos não-críticos, avaliar se pode ser aceito com ressalvas
` : ''}
`;
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 = `
💰 CUSTO TOTAL - RESULTADO
PARÂMETROS:
Área: ${area} m²
Região: ${regiaoNome}
Tinta: ${tintaNome} (R$ ${precoLitro}/L)
Volume: ${volume} L
Custo Material (Tinta)
R$ ${custoMaterial.toFixed(2)}
Custo Mão de Obra
R$ ${custoMaoObra.toFixed(2)}
${incluirEPI ? `
EPI e Consumíveis
R$ ${custoEPI.toFixed(2)}
` : ''}
${incluirEquip ? `
Aluguel Equipamentos
R$ ${custoEquip.toFixed(2)}
` : ''}
Subtotal:
R$ ${subtotal.toFixed(2)}
Margem (10%):
R$ ${margem.toFixed(2)}
TOTAL GERAL:
R$ ${total.toFixed(2)}
(Custo por m²: R$ ${custoPorM2.toFixed(2)}/m²)
📊 BREAKDOWN DETALHADO:
• Horas totais: ${horasTotais.toFixed(1)} h (${area}m² ÷ ${prod}m²/h)
• Custo/hora MO: R$ ${custoMO}/h
• Produtividade: ${prod} m²/h
• Tempo estimado: ${Math.ceil(horasTotais / 8)} dias (8h/dia)
`;
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 = `
⏱️ TEMPO DE SECAGEM - RESULTADO
TIPO DE TINTA: ${tipoNome}
Temperatura: ${temp}°C
Umidade Relativa: ${umidade}%
Espessura: ${espessura} μm
Secagem ao Toque
${Math.round(tempoToque)} h
Manipulação
${Math.round(tempoManipulacao)} h
Próxima Demão
${Math.round(tempoProximaDemao)} h
Cura Total
${Math.round(tempoCuraTotal / 24)} dias
📊 FATORES DE CORREÇÃO APLICADOS:
• Fator Temperatura: ${fatorTemp.toFixed(2)}×
• Fator Umidade: ${fatorUmid.toFixed(2)}×
• Fator Espessura: ${fatorEsp.toFixed(2)}×
• Tempo Base (${tipoNome}): ${dados.tempoBase}h
ALERTAS E RECOMENDAÇÕES:
${alertas.map(a => `${a}`).join(' ')}
💡 DICAS PARA MELHORAR CONDIÇÕES:
${temp < 15 ? '• Aumentar temperatura do ambiente com aquecedores ' : ''}
${umidade > 75 ? '• Usar desumidificadores ou melhorar ventilação ' : ''}
• Aplicar em horários de menor umidade (meio-dia)
• Evitar aplicação com orvalho ou chuva prevista
• Proteger superfície de contaminação durante secagem
`;
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 = `
📋 RELATÓRIO DE INSPEÇÃO
${Math.round(percentApproved)}%
${totalChecked} de ${checks.length} critérios aprovados
ITENS VERIFICADOS:
${checks.map(c => `
${c.checked ? '✅' : '❌'}
${c.label}
`).join('')}
${uncheckedItems.length > 0 ? `
⚠️ ITENS NÃO CONFORMES (${uncheckedItems.length}):
${uncheckedItems.map((item, idx) => `${idx + 1}. ${item.label}`).join(' ')}
` : ''}
STATUS: ${status}
${recommendation}
📝 AÇÕES CORRETIVAS SUGERIDAS:
${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(' ')}
` : 'Nenhuma ação corretiva necessária ✓'}
Data da Inspeção: ${new Date().toLocaleDateString('pt-BR')}
Norma de Referência: ISO 12944
`;
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 `
Composição Química (%)
🔬 Calcular CEV
`;
}
function getSeletorContent() {
return `
Critérios de Seleção
🎯 Buscar Aços
`;
}
function getEquivalenciasContent() {
return `
Selecionar Aço
Aço de Referência
ASTM A36
ASTM A572 Gr.50
ASTM A588
EN S235JR
EN S355J2
NBR AR350
`;
}
function getComparativoContent() {
return `
`;
}
function getParafusosContent() {
return `
1️⃣ Cisalhamento
2️⃣ Esmagamento
3️⃣ Bloco
4️⃣ Layout
5️⃣ vs Solda
📐 Dimensionamento de Parafusos ao Cisalhamento
Calcula a resistência ao cisalhamento de parafusos individuais e totais
🔧 Calcular Cisalhamento
🔨 Verificação de Esmagamento (Bearing)
Calcula a resistência ao esmagamento da chapa
🔧 Calcular Esmagamento
⚠️ Ruptura em Bloco de Cisalhamento
Verifica ruptura por bloco segundo AISC 360-16
🔧 Calcular Bloco
📐 Verificação de Layout de Furação
Verifica conformidade com NBR 8800 e AISC 360
✓ Verificar Conformidade
⚖️ Comparação: Parafuso vs Solda
Compara alternativas de conexão com análise de custos
🔩 Opção Parafuso
Tipo
A325
A490
ISO 8.8
ISO 10.9
Diâmetro (mm)
12
16
20
24
🔥 Opção Solda
Tipo Eletrodo
E6010
E7018
E8018
🔄 Gerar Comparação Completa
`;
}
function getLayoutContent() {
return `
Parâmetros de Layout
✓ Verificar Conformidade
`;
}
function getParafusoVsSoldaContent() {
return `
Parâmetros da Ligação
⚙️ Comparar Soluções
`;
}
function getPreaquecimentoContent() {
return `
⚙️ SELEÇÃO DE PROCESSO E CONSUMÍVEL
Selecione o processo e consumível que será usado em todas as ferramentas abaixo
✅ Atualizar Todas as Abas
📋 Mostrar Propriedades do Consumível
🌡️ Pré-Aquecimento
⚡ Filete
🔥 Energia
📊 Consumo
🔄 Sequência
📋 Padrões
🌡️ Pré-Aquecimento AWS D1.1
Calcula temperatura mínima de pré-aquecimento
Processo Selecionado: SMAW (E7018)
Calcular Temperatura Interpass (entre passes)
🔥 Calcular Pré-Aquecimento
⚡ Dimensionamento de Soldas de Filete
Calcula perna necessária e número de passes
Processo: SMAW (E7018)
⚡ Calcular Filete
🔥 Energia de Soldagem (Heat Input)
Controla aporte de calor para evitar fragilização
Processo: SMAW (E7018)
🔥 Calcular Energia
📊 Verificar Limites por Aço
📊 Consumo de Eletrodos e Consumíveis
Calcula quantidade e custo de eletrodos necessários
Eletrodo: E7018
📊 Calcular Consumo
💰 Gerar Orçamento
🔄 Sequência de Soldagem para Minimizar Distorções
Padrões de deposição e passes
📐 Gerar Diagrama de Sequência
📊 Visualizar Distorções Esperadas
📋 Padrões de Solda Recomendados por Aplicação
Seleção de padrão otimizado para sua aplicação
🔍 Buscar Padrão Ideal
`;
}
function getSoldaFileteContent() {
return `
Dados da Solda
⚡ Dimensionar Solda
`;
}
function getEnergiaSoldagemContent() {
return `
Parâmetros de Soldagem
🔥 Calcular Energia
`;
}
function getConsumoEletrodosContent() {
return `
Dados da Solda
📊 Calcular Consumo
`;
}
function getDurezaContent() {
return `
`;
}
function getCharpyContent() {
return `
Insira até 4 Pares Temperatura/Energia
📉 Gerar Curva
`;
}
function getUltrassomContent() {
return `
Parâmetros da Descontinuidade
🔍 Analisar Conforme Norma
`;
}
function getCertificadoContent() {
return `
Selecionar Norma
Norma de Referência
ASTM A36
ASTM A572 Gr.50
EN S235JR
EN S355J2
NBR AR350
`;
}
function getAreaPinturaContent() {
return `
Tipo de Produto
📐 Calcular Área
`;
}
function getConsumoTintaContent() {
return `
Parâmetros de Pintura
🎯 Calcular Consumo
`;
}
function getCustoPinturaContent() {
return `
`;
}
function getSecagemContent() {
return `
Condições de Aplicação
⏱️ Calcular Tempo
`;
}
function getInspecaoPinturaContent() {
return `
`;
}
function getGalvanizacaoContent() {
return `
Parâmetros de Galvanização
🛡️ Calcular
`;
}
function getOrcamentoContent() {
return `
🎉 NOVIDADE v6.5: Base de Dados Completa de Materiais!
Agora você pode selecionar materiais de um banco de dados com 100+ produtos do mercado brasileiro (Gerdau, Usiminas):
✅ Perfis W, I (IPE), HP - Pesos automáticos
✅ Cantoneiras, Tubos Circulares e RHS
✅ Chapas, Barras, Eletrodos, Tintas, Parafusos
✅ Preços regionais (Sudeste, Sul, Nordeste, Centro-Oeste)
✅ Cálculo automático de preço unitário baseado em peso e região
📦 Carregar Orçamento Exemplo
📖 Como Usar
✎ Adicionar Item ao Orçamento
📋 Informações do Produto:
➕ Adicionar ao Orçamento
📋 Itens do Orçamento
#
Categoria
Especificação
Qtd
Un
Preço Unit.
Valor Total
Ações
Nenhum item adicionado
BDI / Margem (%)
`;
}
function getPesoRiggingContent() {
return `
Cálculo de Peso
⚖️ Calcular Peso
Dimensionamento de Rigging
🏗️ Calcular Rigging
`;
}
function getReferenciaContent() {
return `
Aços Estruturais
Designação
fy (MPa)
fu (MPa)
Along. (%)
CEV
Soldabilidade
Aplicação
ASTM A36
250
400
20
0.41
⭐⭐⭐⭐⭐
Estruturas gerais
ASTM A572 Gr.50
345
450
18
0.45
⭐⭐⭐⭐
Edifícios, pontes
ASTM A588
345
485
19
0.50
⭐⭐⭐
Weathering
EN S235JR
235
360
26
0.38
⭐⭐⭐⭐⭐
Estruturas gerais
EN S355J2
355
490
22
0.50
⭐⭐⭐⭐
Pontes, pesadas
NBR AR350
345
450
18
0.45
⭐⭐⭐⭐
Construção civil
Sistemas de Pintura ISO 12944
Classe
Ambiente
DFT (μm)
Sistema
Vida Útil
C1
Interior seco
80
Monocomponente
5-10 anos
C2
Interior úmido
120
Epóxi 2c
5-10 anos
C3
Exterior médio
160
Epóxi + PU
10-15 anos
C4
Exterior agressivo
200
Epóxi alicíclico + PU
15-20 anos
C5
Marinho
250
Epóxi zinc-rich + PU
20+ anos
Normas de Referência
AWS D1.1/D1.1M - Soldagem de estruturas de aço
NBR 8800:2008 - Projeto de estruturas de aço de edifícios
EN 1993-1-8 - Design of connections
ISO 12944 - Proteção de estruturas de aço com tinta
ASTM A123 - Galvanização a quente
`;
}
// ========================================
// 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 = `
Resultado do Cálculo CEV (IIW)
Pré-aquecimento Mínimo
${Math.round(preheatTemp)}°C
${interpretation}
Fórmula IIW: CEV = C + Mn/6 + (Cr+Mo+V)/5 + (Ni+Cu)/15
Normas aplicáveis: AWS D1.1, NBR 16239, EN 1011-2
`;
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 = `
Nenhum aço encontrado com os critérios especificados
`;
return;
}
const result = steels.map(steel => `
${steel.nome}
Alongamento
${steel.elong}%
Soldabilidade: ${steel.soldabilidade}
Equivalentes: ${steel.equiv.join(', ')}
Custo relativo: ${steel.custo}%
`).join('');
document.getElementById('seletor-result').innerHTML = `
Aços Recomendados (${steels.length})
${result}
`;
addToHistory('Seletor de Aço', `${steels.length} aços encontrados com fy ≥ ${fyMin} MPa`);
}
// Equivalencias
function mostrarEquivalencias() {
const steelId = document.getElementById('equiv-steel').value;
const steel = steelDatabase[steelId];
if (!steel) return;
document.getElementById('equiv-result').innerHTML = `
Equivalências para ${steel.nome}
Norma
Designação
fy (MPa)
fu (MPa)
Along. (%)
CEV
Base
${steel.nome}
${steel.fy}
${steel.fu}
${steel.elong}
${steel.cev}
${steel.equiv.map(eq => {
const eqSteel = Object.values(steelDatabase).find(s => s.nome === eq);
if (!eqSteel) return '';
return `
${eq.includes('ASTM') ? 'ASTM' : eq.includes('EN') ? 'EN' : eq.includes('NBR') ? 'NBR' : 'JIS'}
${eqSteel.nome}
${eqSteel.fy}
${eqSteel.fu}
${eqSteel.elong}
${eqSteel.cev}
`;
}).join('')}
`;
}
// 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 = `
Tabela Comparativa
Aço
fy (MPa)
fu (MPa)
Along. (%)
CEV
Soldabilidade
Custo
`;
selectedSteels.forEach(steelId => {
const steel = steelDatabase[steelId];
if (steel) {
tableHtml += `
${steel.nome}
${steel.fy}
${steel.fu}
${steel.elong}
${steel.cev}
${steel.soldabilidade}
${steel.custo}%
`;
}
});
tableHtml += `
`;
document.getElementById('chart-result').innerHTML = tableHtml;
} else {
document.getElementById('chart-result').innerHTML = `
`;
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`);
}
// 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);
});
}
// 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 += `• ${qty} parafusos ${type.toUpperCase()} → ${altCap.toFixed(1)} kN ✅ `;
}
}
});
// Reference table
const refTable = `
Tipo
Ø12
Ø16
Ø20
Ø24
A325 5.2 9.2 14.4 20.7
A490 7.3 13.0 20.3 29.2
ISO88 6.1 10.8 16.8 24.2
ISO109 8.7 15.5 24.2 34.8
`;
document.getElementById('bolt-shear-result').innerHTML = `
✅ CISALHAMENTO - RESULTADO
Capacidade por Parafuso
${Fv.toFixed(1)} kN
Capacidade Total (${qty}×${boltType.toUpperCase()})
${capacity.toFixed(1)} kN
Força Aplicada
${force.toFixed(1)} kN
Utilização
${utilization.toFixed(0)}%
STATUS: ${status}
Recomendação: ${recommendation}
${alternatives ? `
` : ''}
Tabela de Referência (kN por parafuso, plano simples):
${refTable}
`;
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 = `
✅ ESMAGAMENTO - RESULTADO
Espessura da Chapa: ${thickness} mm
Diâmetro Parafuso: ${d} mm
Aço da Chapa: ${steelType.toUpperCase()} (fu=${fu} MPa)
Área de Contato
${Abc.toFixed(0)} mm²
Fator Localização
${factor.toFixed(1)} ${factor === 1.0 ? '✓' : '⚠️'}
Capacidade por Parafuso
${Fb.toFixed(1)} kN
Capacidade Total (${qty} un)
${FbTotal.toFixed(1)} kN
Verificação contra Cisalhamento:
Cisalhamento: ${shearCap.toFixed(1)} kN
Esmagamento: ${FbTotal.toFixed(1)} kN
CONTROLA O ${critical}
STATUS: ${status}
${recommendation}
`;
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 = `
✅ RUPTURA EM BLOCO - RESULTADO
Área Líquida Tração (Ant): ${Ant.toFixed(0)} mm²
Área Líquida Cisalhamento (Agv): ${Agv.toFixed(0)} mm²
Resistência Ruptura (AISC 360-16):
Rbs = 0.6×fu×Agv + 0.3×fu×Ant
Rbs = 0.6×${fu}×${Agv.toFixed(0)} + 0.3×${fu}×${Ant.toFixed(0)}
Rbs = ${(0.6 * fu * Agv / 1000).toFixed(1)} + ${(0.3 * fu * Ant / 1000).toFixed(1)} = ${Rbs.toFixed(1)} kN
Resistência Bloco
${Rbs.toFixed(1)} kN
Força Aplicada
${force.toFixed(1)} kN
Utilização
${utilization.toFixed(0)}%
STATUS: ${status}
${recommendation}
`;
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 += `
${check.name}
${check.value} mm
${status}
${detail}
`;
});
// Simple layout drawing
const drawing = `
DESENHO DE LAYOUT
┌───────────────────────┐
│ ${edgeTop} ${edgeTop} ${edgeTop} │
│ ●─────●─────● │ ${edgeRight}
│ │ ${hSpace} │ ${hSpace} │ │
│ ●─────●─────● │ ${vSpace}
│ │ │ │ │
│ ●─────●─────● │ ${vSpace}
│ ${edgeLeft} ${edgeLeft} ${edgeLeft} │
└───────────────────────┘
${edgeBottom} ${edgeBottom} ${edgeBottom}
`;
document.getElementById('layout-full-result').innerHTML = `
✅ LAYOUT DE FURAÇÃO - VERIFICAÇÃO
Diâmetro do Parafuso: ${d} mm
Espessura da Chapa: ${thickness} mm
Parâmetro
Valor
Status
Limites NBR 8800
${checksList}
${allConform ? '✅ 100% CONFORME COM NBR 8800' : '⚠️ AJUSTES NECESSÁRIOS'}
${allConform ? 'Todos os parâmetros estão dentro dos limites normativos' : 'Alguns parâmetros precisam ser ajustados'}
${drawing}
`;
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 = `
Verificação NBR 8800
Dist. Borda Mín
${minEdge.toFixed(1)} mm
Dist. Borda Máx
${maxEdge} mm
Espaç. Mínimo
${minSpacing.toFixed(1)} mm
Espaç. Máximo
${maxSpacing} mm
Distância de Borda: ${edgeStatus}
Espaçamento: ${spacingStatus}
`;
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 = `
⚖️ COMPARAÇÃO: PARAFUSO vs SOLDA
🔩 PARAFUSO
Tipo: ${boltType.toUpperCase()} Ø${boltD}mm
Quantidade: ${boltQty} un
Capacidade: ${boltTotalCap.toFixed(1)} kN
Custo Material: R$ ${boltMaterialCost.toFixed(2)}
Custo Mão de Obra: R$ ${boltLaborCost.toFixed(2)}
Tempo Instalação: ${boltTimeMin} min
CUSTO TOTAL: R$ ${boltTotalCost.toFixed(2)}
Vantagens:
✅ Mais rápido
✅ Reversível
✅ Inspeção visual simples
🔥 SOLDA
Tipo: Filete
Perna: ${weldLegRounded} mm
Comprimento: ${length} mm
Custo Material: R$ ${electrodeCost.toFixed(2)}
Custo Mão de Obra: R$ ${weldLaborCost.toFixed(2)}
Tempo Soldagem: ${Math.round(weldTimeMin)} min
CUSTO TOTAL: R$ ${weldTotalCost.toFixed(2)}
Vantagens:
✅ Maior rigidez
✅ Melhor aparência
✅ Distribuição de tensões
⭐ RECOMENDAÇÃO: ${cheaper}
Economia de R$ ${savings.toFixed(2)} | ${Math.abs(timeSaved).toFixed(0)} min ${boltTimeMin < weldTimeMin ? 'mais rápido' : 'mais lento'}
`;
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 = `
Comparação de Soluções
🔩 Solução Parafusada
Tipo: A325 Ø20mm
Quantidade: ${boltQty} parafusos
Capacidade: ${(boltQty * boltCapacity).toFixed(1)} kN
Custo estimado: R$ ${boltCost.toFixed(2)}
Vantagens: Desmontável, inspeção visual
Desvantagens: Maior tempo de instalação
🔥 Solução Soldada
Tipo: Solda de filete
Perna: ${weldLegRounded} mm
Comprimento: ${length} mm
Custo estimado: R$ ${weldCost.toFixed(2)}
Vantagens: Melhor rigidez, econômica
Desvantagens: Permanente, requer qualificação
Recomendação: ${weldCost < boltCost ? 'Solda de filete é mais econômica' : 'Parafusos mais econômicos'}
`;
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 = 'E7018 (Padrão) ';
currentWeldElectrode = 'e7018';
return;
}
// Build options only with valid consumables
let options = '';
processData.consumiveis.forEach(consumivelId => {
const elec = weldingElectrodes[consumivelId];
if (elec) {
options += `${elec.nome} - ${elec.tipo} `;
}
});
select.innerHTML = options || 'E7018 (Padrão) ';
// 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 = `
📋 Propriedades do ${elec.nome}
Resistência Tração
${elec.resistencia_tracao_min}-${elec.resistencia_tracao_max} MPa
Limite Escoamento
≥ ${elec.limite_escoamento} MPa
Alongamento
≥ ${elec.alongamento}%
Charpy (-20°C)
${elec.charpy > 0 ? '≥ ' + elec.charpy + ' J' : 'N/A'}
Corrente Recomendada
${elec.corrente_min}-${elec.corrente_max} A
Voltagem
${elec.voltagem_min}-${elec.voltagem_max} V
Rendimento de Deposição
${(elec.rendimento * 100).toFixed(0)}%
Custo
R$ ${elec.custo_kg}/kg
Tipo de Revestimento: ${elec.tipo}
Posição Soldagem: ${elec.posicoes}
Taxa de Deposição: ${elec.taxa_deposicao} kg/h
Diâmetros Comerciais: ${elec.diametros.join(', ')} mm
`;
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);
}
}
}
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 = `
🔥 PRÉ-AQUECIMENTO AWS D1.1 - RESULTADO
DADOS RESUMIDOS:
Processo: ${weldingProcesses[currentWeldProcess].nome}
Consumível: ${weldingElectrodes[currentWeldElectrode].nome}
CEV: ${cev.toFixed(2)} (${cevClass} - ${cevInterpretation})
Espessura: ${thickness} mm (${thicknessClass})
Ambiente: ${ambient}°C
Restrição: ${restraint === 1.0 ? 'Não restrita' : restraint === 1.1 ? 'Parcial' : 'Total'}
CÁLCULOS:
CEV Factor: ${cev.toFixed(2)} × 50 = ${cevFactor.toFixed(1)}°C
Esp Factor: (${thickness}/10) × 20 = ${thicknessFactor.toFixed(1)}°C
Amb Factor: (20 - ${ambient}) / 2 = ${ambientFactor.toFixed(1)}°C
Processo Adj: +${processAdjust}°C (${currentWeldProcess.toUpperCase()})
Restrição: ×${restraint} = Multiplica por ${restraint}
PRÉ-AQUECIMENTO MÍNIMO
${Math.round(preheatTemp)}°C
${calcInterpass ? `
INTERPASS (entre passes)
${Math.round(interpassTemp)}°C
Temperatura Máxima
${maxInterpass}°C
` : ''}
⚠️ RECOMENDAÇÕES CRÍTICAS:
1. Pré-aqueça todo o acesso de soldagem (min 75mm da junta)
${calcInterpass ? `2. Manter interpass entre ${Math.round(preheatTemp)}-${Math.round(interpassTemp)}°C ` : ''}
${calcInterpass ? `3. Não exceder ${maxInterpass}°C (risco de fragilização ZTA) ` : ''}
${calcInterpass ? '4' : '2'}. Usar termômetro de contato ou pirômetro
${calcInterpass ? '5' : '3'}. ${thickness > 50 || cev > 0.60 ? 'PWHT (Tratamento Térmico Pós) RECOMENDADO' : 'Considerar PWHT para maior confiabilidade'}
📊 TABELA AWS D1.1 REFERÊNCIA:
Espessura
CEV < 0.40
CEV 0.40-0.60
CEV > 0.60
< 12mm Não req. 50°C 100°C
12-25mm 50°C 100°C 150°C
25-50mm 50°C 100°C 165°C
> 50mm 100°C 150°C 225°C
`;
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 = `
⚡ DIMENSIONAMENTO DE FILETE - RESULTADO
DADOS:
Processo: ${weldingProcesses[currentWeldProcess].nome}
Eletrodo: ${elec.nome}
Força: ${force} kN | Comprimento: ${length} mm
Aço Base: fy = ${fy} MPa
Junta: ${jointType === 1 ? 'Filete Simples' : 'Filete Duplo'} | Posição: ${positionName}
CÁLCULO:
Fv unitário = 0.707 × perna × comp × 0.65 × fy / 1000
Fv = 0.707 × perna × ${length} × 0.65 × ${fy}/1000
Fv = ${(0.707 * length * 0.65 * fy / 1000).toFixed(2)} × perna (kN)
Para ${jointType} filete(s): ${jointType} × Fv = ${(jointType * 0.707 * length * 0.65 * fy / 1000).toFixed(2)} × perna
Perna necessária: ${force} / ${(jointType * 0.707 * length * 0.65 * fy / 1000).toFixed(2)} = ${legTheoretical.toFixed(2)} mm
Perna Teórica
${legTheoretical.toFixed(2)} mm
Perna Comercial
${legCommercial} mm
Capacidade Real
${realCapacity.toFixed(1)} kN
Margem de Segurança
${safetyMargin.toFixed(1)} kN (${((realCapacity/force - 1) * 100).toFixed(0)}%)
⚙️ DIMENSIONAMENTO DE PASSES:
Eletrodo Máximo: ${maxDiameter}mm (para ${passes} passa${passes > 1 ? 's' : ''})
OPÇÃO ${passes === 1 ? 'RECOMENDADA' : '1'}: ${passes} PASSA${passes > 1 ? 'S' : ''}:
Perna: ${passes === 1 ? legCommercial : passes + '×' + Math.ceil(legCommercial/passes)} mm (diâmetro ${maxDiameter}mm)
Corrente: ${elec.corrente_min}-${elec.corrente_max} A
Tempo: ${Math.round(totalTime)} min
Consumo: ${consumption.toFixed(2)} kg
${status === '✅ VIÁVEL' ? '✅ VIÁVEL (Margem de ' + ((realCapacity/force - 1) * 100).toFixed(0) + '%)' : status}
${passes === 1 && legCommercial >= 5 ? `
OPÇÃO 2: 2 PASSES (Maior Confiabilidade):
Perna: 2×${Math.ceil(legCommercial/2)} = ${legCommercial} mm
Corrente: ${elec.corrente_min} A × 2
Tempo: ${Math.round(totalTime * 2)} min
Consumo: ${(consumption * 2).toFixed(2)} kg
✅ RECOMENDADO (Maior qualidade e resistência)
` : ''}
RECOMENDAÇÕES:
- ${elec.nome} é ${elec.tipo === 'Básico' ? 'excelente' : 'adequado'} para essa aplicação
- ${passes > 1 ? 'Usar ' + passes + ' passes garante melhor qualidade' : 'Soldagem em 1 passa é viável'}
- Manter interpass 150°C (vindo da Aba Pré-Aquecimento)
- Utilização: ${utilization.toFixed(1)}% ${status}
`;
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 = `
🔥 ENERGIA DE SOLDAGEM - RESULTADO
PARÂMETROS:
Voltagem: ${voltage} V
Corrente: ${current} A
Velocidade: ${speed} cm/min
Eficiência: ${(efficiency * 100).toFixed(0)}%
CÁLCULO:
HI = (V × I × 60 × η) / (v × 1000)
HI = (${voltage} × ${current} × 60 × ${efficiency}) / (${speed} × 1000)
HI = ${(voltage * current * 60 * efficiency).toFixed(1)} / ${speed * 1000} = ${heatInput.toFixed(2)} kJ/mm
Energia de Soldagem
${heatInput.toFixed(2)} kJ/mm
Classificação
${hiStatus}
⚠️ ANÁLISE POR TIPO DE AÇO:
Aço
Ideal (kJ/mm)
Valor
Status
A36
1.5-3.0
${heatInput.toFixed(2)}
${heatInput >= 1.5 && heatInput <= 3.0 ? '✅ OK' : heatInput > 3.0 ? '❌ ALTO' : '⚠️ BAIXO'}
A572
1.0-2.5
${heatInput.toFixed(2)}
${heatInput >= 1.0 && heatInput <= 2.5 ? '✅ OK' : heatInput > 2.5 ? '❌ ALTO' : '⚠️ BAIXO'}
S355
0.8-2.0
${heatInput.toFixed(2)}
${heatInput >= 0.8 && heatInput <= 2.0 ? '✅ OK' : heatInput > 2.0 ? '❌ CRÍTICO' : '⚠️ BAIXO'}
${heatInput > limits.max ? `
⚠️ RISCOS:
1. Aquecimento excessivo da ZTA
2. Possível fragilização por alívio
3. Risco de trincas pelo resfriamento rápido
4. Redução de tenacidade
` : ''}
✅ RECOMENDAÇÕES:
${recommendations.map((rec, i) => `${i + 1}. ${rec}`).join(' ')}
🔧 CALCULADORA INTERATIVA:
Teste diferentes velocidades/correntes acima para encontrar HI ideal!
`;
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 = `
Temperatura de Pré-Aquecimento (AWS D1.1)
Temp. Mínima
${Math.round(preheatTemp)}°C
Temp. Interpasse Máx
${Math.round(maxInterpass)}°C
${pwhtRecommendation}
`;
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 = `
📊 CONSUMO DE ELETRODOS - RESULTADO
CONSUMÍVEL SELECIONADO:
Eletrodo ${elec.nome} (AWS A5.1)
Rendimento: ${(elec.rendimento * 100).toFixed(0)}%
Taxa Deposição: ${elec.taxa_deposicao} kg/h
Custo: R$ ${elec.custo_kg}/kg
CÁLCULOS:
Volume de Solda: ${volumeCm3.toFixed(0)} mm³
Massa Teórica: ${massKg.toFixed(3)} kg
Fator Rendimento: ${(elec.rendimento * 100).toFixed(0)}% = ÷${elec.rendimento.toFixed(2)}
Massa Consumível: ${massKg.toFixed(3)} ÷ ${elec.rendimento.toFixed(2)} = ${massConsumable.toFixed(3)} kg
Perdas (Respingos): ${loss}% × ${massConsumable.toFixed(3)} = ${lossKg.toFixed(4)}kg
Sucata (Pontas): ${scrap}% × ${massConsumable.toFixed(3)} = ${scrapKg.toFixed(4)}kg
TOTAL NECESSÁRIO: ${totalKg.toFixed(4)} kg
Consumo de Eletrodo
${(totalKg * 1000).toFixed(0)} g (${totalKg.toFixed(3)} kg)
Caixas de 5kg
${Math.ceil(totalKg / 5)} caixa${Math.ceil(totalKg / 5) > 1 ? 's' : ''}
Custo Total Material
R$ ${costMaterial.toFixed(2)}
Tempo de Soldagem
${Math.round(timeMin)} min
📊 COMPARAÇÃO DE ELETRODOS PARA MESMO TRABALHO:
Eletrodo
Consumo
Custo
Tempo
${elec.nome}
${totalKg.toFixed(3)}kg
R$ ${costTotal.toFixed(2)}
${Math.round(timeMin)} min
${comparisons.map(c => `
${c.name}
${c.mass.toFixed(3)}kg
R$ ${c.cost.toFixed(2)} ${c.cost < costTotal ? '✅' : ''}
${Math.round(c.time)} min ${c.time < timeMin ? '✅' : ''}
`).join('')}
✅ RECOMENDAÇÃO:
${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`}
`;
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 = `
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]
`;
const html = `
📐 SEQUÊNCIA DE SOLDAGEM - PLANO VISUAL
JUNTA: ${jointType === 'filete' ? 'Filete Duplo' : jointType === 'topo' ? 'Topo' : 'Angular'} (${length}mm × ${leg}mm × ${passes} passa${passes > 1 ? 's' : ''})
PADRÃO: ${patternName} (${description})
PROCESSO: ${weldingProcesses[currentWeldProcess].nome}
${pattern === 'skip' ? skipDiagram : `
Padrão ${patternName}
${description}
`}
⏱️ CRONOGRAMA:
Sequência 1º Lado: ${Math.round(totalTime)} min
Sequência 2º Lado: ${Math.round(totalTime)} min
Tempo Total: ${Math.round(totalTime * 2)} min (com pausas)
📊 ANÁLISE DE DISTORÇÃO:
Método ${patternName}:
- Distorção Angular Esperada: ±${pattern === 'continuous' ? '2.5' : '0.5'}°
- Distorção Longitudinal: ±${pattern === 'continuous' ? '8' : '2'}mm
- Avaliação: ${distortionReduction > 60 ? 'EXCELENTE ✅' : distortionReduction > 40 ? 'BOA ✅' : 'NÃO RECOMENDADO ⚠️'}
${pattern !== 'continuous' ? `
vs Método Contínuo (sem otimização):
- Distorção Angular: ±2.5° ⚠️
- Distorção Longitudinal: ±8mm ⚠️
- Avaliação: NÃO RECOMENDADO
` : ''}
✅ VANTAGENS ${patternName.toUpperCase()}:
1. Reduz distorções em ${distortionReduction}%
2. Controla melhor a temperatura
3. Facilita inspeção entre passes
4. Reduz stress residual
🔧 INSTRUÇÕES PARA SOLDADOR:
1. Marcar posições com giz (0, ${Math.round(length/8)}, ${Math.round(length/4)}...)
2. Soldar segmentos 1-8 (1ª passa)
3. Aguardar resfriamento (espaços resfriem)
4. Soldar segmentos 9-16 (preencher vazios)
5. Controlar temperatura: 150-200°C (interpass)
6. Inspeção visual entre passes
`;
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 = `
📋 PADRÕES DE SOLDA POR APLICAÇÃO
APLICAÇÃO: ${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'}
Criticidade: ${criticality === 'baixa' ? 'Baixa' : criticality === 'media' ? 'Média' : criticality === 'alta' ? 'Alta' : 'Crítica'} | Ambiente: ${env === 'interno' ? 'Interno Seco' : env === 'externo' ? 'Externo Temperado' : env === 'agressivo' ? 'Agressivo/Marinho' : 'Baixas Temperaturas'}
Norma: AISC 360-16, AWS D1.1
✅ PADRÃO RECOMENDADO: Classe ${standardClass}
Processo: ${weldingProcesses[currentWeldProcess].nome}
Eletrodo: ${electrode} (${elec.tipo})
Processo Secundário: ${standardClass === 'C' ? 'SAW (se volume alto)' : 'SMAW padrão'}
ESPECIFICAÇÃO:
• Número de Passes: ${passes}
• Perna Filete: ${leg} mm
• Pré-aquecimento: ${preheat}°C
• Interpass: 150-200°C
• Velocidade: 20-30 cm/min
• Posição: Plana e Horizontal preferida
• Inspeção: ${inspection}
CONSUMO POR METRO LINEAR:
• Eletrodos: ${consumptionPerMeter.toFixed(2)} kg
• Tempo: ${Math.round(timePerMeter)} min/m
• Custo: R$ ${costPerMeter.toFixed(2)}/m (material + mão de obra)
QUALIDADE ESPERADA:
✓ Resistência à tração: >${elec.resistencia_tracao_min} MPa
✓ Alongamento: >${elec.alongamento}%
✓ Charpy (-20°C): >${elec.charpy} J
✓ Dureza ZTA: <260 HV
⚠️ RESTRIÇÕES:
• Não usar em posição overhead sem suporte
• Temperatura mínima: ${env === 'baixatemp' ? '-20' : '-10'}°C
• Não esticar além de 2x o comprimento
📊 ALTERNATIVAS:
${standardClass !== 'A' ? `
⭐ OPÇÃO INFERIOR (Economia):
PADRÃO: Classe A (Soldagem Econômica)
Eletrodo: E6013 (mais barato)
Passes: 1 | Perna: 3mm
Custo: R$ ${(costPerMeter * 0.56).toFixed(2)}/m (${((1 - 0.56) * 100).toFixed(0)}% menos)
⚠️ Tenacidade reduzida - Use em estruturas baixas
` : ''}
${standardClass !== 'C' ? `
🏆 OPÇÃO PREMIUM (Máxima Qualidade):
PADRÃO: Classe C (Soldagem Crítica)
Eletrodo: E8018 (maior tenacidade)
Passes: 3-4 | Perna: 6mm
Processo: SAW (qualidade automática)
Inspeção: Visual 100% + UT 100% + RT 20%
Custo: R$ ${(costPerMeter * 1.89).toFixed(2)}/m (${((1.89 - 1) * 100).toFixed(0)}% mais)
✅ Máxima confiabilidade - Use em pontes/crítico
` : ''}
`;
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 = `
Dimensionamento da Solda de Filete
Perna Calculada
${leg.toFixed(2)} mm
Perna Adotada
${legCommercial} mm
Garganta Efetiva
${throat.toFixed(2)} mm
Número de Passes
${passes}
Eletrodo recomendado: E${Math.round(fy * 1.15)} (resistência compatível com o aço base)
`;
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 = `
Energia de Soldagem (Heat Input)
Energia
${heatInput.toFixed(2)} kJ/mm
${interpretation}
`;
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 = `
Consumo de Eletrodos
Volume de Solda
${(volume / 1000).toFixed(1)} cm³
Massa de Solda
${mass.toFixed(2)} kg
Consumo Total
${consumption.toFixed(2)} kg
`;
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 = `
Conversão de Dureza
HB (Brinell)
${Math.round(HB)}
HRC (Rockwell C)
${HRC.toFixed(1)}
HV (Vickers)
${Math.round(HV)}
Estimativa de Resistência:
fu ≈ ${fu.toFixed(0)} MPa
fy ≈ ${fy.toFixed(0)} MPa (aproximado)
`;
}
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 = `
Curva de Transição Dúctil-Frágil
${ttdf !== null ? `
TTDF (Temperatura de Transição): ${ttdf.toFixed(1)}°C
Temperatura onde a energia de impacto = 27J
` : `
Não foi possível calcular TTDF
A curva não intercepta 27J no intervalo medido
`}
`;
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 norm = document.getElementById('cert-norm').value;
const requirements = certRequirements[norm] || [];
document.getElementById('cert-result').innerHTML = `
Checklist de Requisitos - ${norm.toUpperCase().replace('_', ' ')}
${requirements.map((req, index) => `
${req}
`).join('')}
`;
}
function updatePaintFields() {
const type = document.getElementById('paint-type').value;
const field3 = document.getElementById('paint-field3');
if (type === 'chapa') {
document.getElementById('paint-label1').textContent = 'Comprimento (mm)';
document.getElementById('paint-label2').textContent = 'Largura (mm)';
field3.style.display = 'none';
} else if (type === 'perfilW') {
document.getElementById('paint-label1').textContent = 'Comprimento (mm)';
document.getElementById('paint-label2').textContent = 'Altura (mm)';
field3.style.display = 'none';
} else if (type === 'tubo') {
document.getElementById('paint-label1').textContent = 'Comprimento (mm)';
document.getElementById('paint-label2').textContent = 'Diâmetro (mm)';
field3.style.display = 'none';
} else if (type === 'rhs') {
document.getElementById('paint-label1').textContent = 'Comprimento (mm)';
document.getElementById('paint-label2').textContent = 'Largura (mm)';
document.getElementById('paint-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 = `
Área de Pintura
Área Unitária
${area.toFixed(2)} m²
Área Total
${totalArea.toFixed(2)} m²
`;
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)} m²\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 = `
Consumo de Tinta
Volume Teórico
${volumeTheoretical.toFixed(2)} L
Volume por Demão
${volumePerCoat.toFixed(2)} L
Volume Total
${volumeTotal.toFixed(2)} L
Custo Total
R$ ${totalCost.toFixed(2)}
`;
addToHistory('Consumo de Tinta', `${volumeTotal.toFixed(2)}L para ${area}m²`);
}
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 = `
Galvanização a Quente
Taxa de Corrosão
${rate.toFixed(1)} μm/ano
Vida Útil Estimada
${lifeYears.toFixed(0)} anos
Consumo de Zinco
${zincMass.toFixed(2)} kg
Custo Estimado
R$ ${(zincCost + area * 180).toFixed(2)}
Normas aplicáveis: ASTM A123, ISO 1461, NBR 6323
`;
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 = 'Nenhum item adicionado ';
} 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 += `
📁 ${catName}
`;
grouped[cat].forEach(item => {
html += `
${itemNumber++}
${item.category.toUpperCase()}
${item.spec}
${item.qty.toFixed(2)}
${item.unit}
R$ ${item.price.toFixed(2)}
R$ ${item.total.toFixed(2)}
🗑️
`;
});
}
});
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 = `
📊 RESUMO FINANCEIRO
Subtotais por Categoria:
${grouped.material > 0 ? `
📦 Materiais:
R$ ${grouped.material.toFixed(2)}
` : ''}
${grouped.servico > 0 ? `
🔧 Serviços:
R$ ${grouped.servico.toFixed(2)}
` : ''}
${grouped.consumivel > 0 ? `
🧰 Consumíveis:
R$ ${grouped.consumivel.toFixed(2)}
` : ''}
${grouped.indireto > 0 ? `
💼 Indiretos:
R$ ${grouped.indireto.toFixed(2)}
` : ''}
Subtotal Geral:
R$ ${subtotal.toFixed(2)}
BDI (${bdi}%):
R$ ${bdiValue.toFixed(2)}
TOTAL DO ORÇAMENTO
R$ ${total.toFixed(2)}
📊 Análise Detalhada
📄 Gerar PDF
💾 Salvar Orçamento
🗑️ Limpar Tudo
`;
}
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 = `
📊 ANÁLISE DETALHADA DO ORÇAMENTO
×
Composição por Categoria
${grouped.material > 0 ? `
Materiais
${percMaterial.toFixed(0)}%
R$ ${grouped.material.toFixed(2)}
` : ''}
${grouped.servico > 0 ? `
Serviços
${percServico.toFixed(0)}%
R$ ${grouped.servico.toFixed(2)}
` : ''}
${grouped.consumivel > 0 ? `
Consumíveis
${percConsumivel.toFixed(0)}%
R$ ${grouped.consumivel.toFixed(2)}
` : ''}
${grouped.indireto > 0 ? `
Indiretos
${percIndireto.toFixed(0)}%
R$ ${grouped.indireto.toFixed(2)}
` : ''}
Custo por Área
Considerando área estimada de ${estimatedArea} m² :
R$ ${costPerM2.toFixed(2)}/m²
Este valor é uma média estimada baseada no orçamento total
Cronograma Estimado
✅ Semana 1: Fornecimento de Materiais
✅ Semana 2-${Math.min(weeks-2, 3)}: Fabricação
✅ Semana ${Math.min(weeks-1, 4)}-${weeks}: Montagem e Soldagem
✅ Semana ${weeks+1}: Pintura e Acabamento
✅ Semana ${weeks+2}: Inspeção Final
Prazo Total Estimado: ${weeks+2} semanas
Fornecedores Envolvidos
${grouped.material > 0 ? '🏭 Gerdau/Usiminas - Perfis e Chapas ' : ''}
${grouped.consumivel > 0 && appState.budgetItems.some(i => i.spec.includes('E70') || i.spec.includes('E60')) ? '🔥 Esab/Lincoln - Eletrodos ' : ''}
${grouped.consumivel > 0 && appState.budgetItems.some(i => i.spec.includes('TINTA')) ? '🎨 Sherwin-Williams/Coral - Tintas ' : ''}
${grouped.consumivel > 0 && appState.budgetItems.some(i => i.spec.includes('Parafuso')) ? '🔩 Distribuidores Locais - Parafusos ' : ''}
${grouped.servico > 0 ? '👷 Mão de Obra Especializada - Soldadores e Montadores ' : ''}
Fechar Análise
`;
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 type = document.getElementById('weight-type').value;
const field3 = document.getElementById('weight-field3');
const field4 = document.getElementById('weight-field4');
if (type === 'perfilW') {
document.getElementById('weight-label1').textContent = 'Altura (mm)';
document.getElementById('weight-label2').textContent = 'Comprimento (m)';
field3.style.display = 'none';
field4.style.display = 'none';
} else if (type === 'chapa') {
document.getElementById('weight-label1').textContent = 'Largura (mm)';
document.getElementById('weight-label2').textContent = 'Altura (mm)';
document.getElementById('weight-label3').textContent = 'Espessura (mm)';
field3.style.display = 'block';
field4.style.display = 'none';
} else if (type === 'tubo') {
document.getElementById('weight-label1').textContent = 'Diâmetro Externo (mm)';
document.getElementById('weight-label2').textContent = 'Comprimento (m)';
document.getElementById('weight-label3').textContent = 'Espessura Parede (mm)';
field3.style.display = 'block';
field4.style.display = 'none';
} else if (type === 'barra') {
document.getElementById('weight-label1').textContent = 'Diâmetro (mm)';
document.getElementById('weight-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 = `
Cálculo de Peso
Peso Total
${weight.toFixed(2)} kg
`;
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 = `
Plano de Rigging
Força por Cabo
${forcePerCable.toFixed(1)} kN
Recomendação: ${recommendation}
`;
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 = 'Selecione... ';
if (category === 'material') {
options += 'Perfil W ';
options += 'Perfil I (IPE) ';
options += 'Perfil HP ';
options += 'Cantoneira ';
options += 'Tubo Circular ';
options += 'Tubo Retangular (RHS) ';
options += 'Chapa ';
options += 'Barra Redonda ';
} else if (category === 'consumivel') {
options += 'Eletrodos ';
options += 'Parafusos ';
options += 'Tintas ';
} else if (category === 'servico') {
options += 'Serviço Customizado ';
} else if (category === 'indireto') {
options += 'Custo Indireto ';
}
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 = 'Selecione... ';
productInfo.style.display = 'none';
if (!type || type.includes('custom')) {
return;
}
// Show loading state
specSelect.innerHTML = 'Carregando... ';
// Load data from CSV
const dados = await carregarCSV(type);
specSelect.innerHTML = 'Selecione... ';
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 = 'Nenhum item encontrado ';
}
}
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 = `${itemData.nome} `;
if (itemData.peso_kg_m) {
detailsHtml += `Peso: ${itemData.peso_kg_m} kg/m `;
}
if (itemData.altura_mm) {
detailsHtml += `Altura: ${itemData.altura_mm} mm `;
}
if (itemData.diametro_mm) {
detailsHtml += `Diâmetro: ${itemData.diametro_mm} mm `;
}
if (itemData.espessura_mm) {
detailsHtml += `Espessura: ${itemData.espessura_mm} mm `;
}
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();
}
}
// Admin Modal Functions
function openAdminModal() {
const modal = document.getElementById('adminModal');
modal.classList.add('active');
// Load current config
document.getElementById('adminAppName').value = adminConfig.appName;
document.getElementById('adminAppSubtitle').value = adminConfig.appSubtitle;
document.getElementById('adminFooterText').value = adminConfig.footerText;
document.getElementById('adminThemeDefault').value = adminConfig.themeDefault;
document.getElementById('adminModeDefault').value = adminConfig.modeDefault;
// Set tool checkboxes
document.querySelectorAll('.admin-tools-grid input[type="checkbox"]').forEach(input => {
const sectionId = input.value;
input.checked = adminConfig.toolsVisibility[sectionId] || false;
});
}
function closeAdminModal() {
document.getElementById('adminModal').classList.remove('active');
}
function saveAdminConfig() {
// Save branding
adminConfig.appName = document.getElementById('adminAppName').value;
adminConfig.appSubtitle = document.getElementById('adminAppSubtitle').value;
adminConfig.footerText = document.getElementById('adminFooterText').value;
adminConfig.themeDefault = document.getElementById('adminThemeDefault').value;
adminConfig.modeDefault = document.getElementById('adminModeDefault').value;
// Save tools visibility
document.querySelectorAll('.admin-tools-grid input[type="checkbox"]').forEach(input => {
const sectionId = input.value;
adminConfig.toolsVisibility[sectionId] = input.checked;
});
// Apply changes
applyAdminConfig();
closeAdminModal();
alert('✅ Configurações salvas com sucesso!');
}
function resetAdminDefaults() {
if (confirm('⚠️ Deseja restaurar todas as configurações padrão?')) {
adminConfig.appName = 'AÇO CALC PRO';
adminConfig.appSubtitle = 'Plataforma Técnica com Base de Dados de Materiais Brasileiros';
adminConfig.footerText = '© 2025 AÇO CALC PRO v6.5 PROFESSIONAL EDITION - Plataforma Técnica com Base de Dados de Materiais Brasileiros';
adminConfig.themeDefault = 'escuro';
adminConfig.modeDefault = 'simples';
// Reset visibility to defaults
Object.keys(adminConfig.toolsVisibility).forEach(key => {
adminConfig.toolsVisibility[key] = ['cev', 'seletor', 'parafusos', 'layout', 'preaquecimento', 'dureza', 'charpy', 'area-pintura', 'consumo-tinta', 'custo-pintura', 'orcamento'].includes(key);
});
applyAdminConfig();
openAdminModal(); // Refresh modal
alert('✅ Configurações restauradas!');
}
}
function applyAdminConfig() {
// Update branding elements
const logoEl = document.getElementById('appLogo');
const subtitleEl = document.getElementById('appSubtitle');
const footerEl = document.getElementById('appFooter');
if (logoEl) logoEl.textContent = '🏗️ ' + adminConfig.appName;
if (subtitleEl) subtitleEl.textContent = adminConfig.appSubtitle;
if (footerEl) footerEl.querySelector('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: 'CEV IIW (Instituto Internacional de Soldagem) Fórmula: CEV = C + (Mn/6) + (Cr+Mo+V)/5 + (Ni+Cu)/15
Interpretação:
<0.35: Excelente soldabilidade, sem pré-aquecimento 0.35-0.45: Boa soldabilidade, considerar pré-aquecimento 0.45-0.55: Soldabilidade moderada, pré-aquecimento necessário >0.55: Soldabilidade difícil, controle rigoroso necessário ',
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: 'Temperatura de Pré-aquecimento Fórmula AWS D1.1: T_preaq = 50 + (CEV × 50) + (Espessura/10 × 20)
Interpass: Temperatura entre passes: Pré-aq + 25°C (máximo 200°C)
',
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: 'Capacidade ao Cisalhamento Fórmula: Fv = 0.6 × fy × A × n_planos
Verifica se capacidade total > força aplicada
Verificações Adicionais Esmagamento da chapa Ruptura em bloco de cisalhamento Distâncias mínimas NBR 8800 ',
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: 'Cálculo do Volume V_teórico = (DFT × Área) / (1000 × % Sólidos)
V_com_perdas = V_teórico / (1 - % Perdas)
V_total = V_com_perdas × Número de Demãos
',
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: 'Conversões HRC = HB × 0.0338 - 9.8
HV = HB × 0.95
Estimativa de Resistência fu ≈ HB × 10 MPa
',
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: 'Curva de Transição Gráfico mostra como energia absorvida varia com temperatura
TTDF (27J): Temperatura onde energia = 27J
Material é dúctil acima da TTDF e frágil abaixo
',
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: 'Cálculo de Total Subtotal = ∑(Quantidade × Preço Unitário)
BDI = Subtotal × (% BDI)
TOTAL = Subtotal + BDI
',
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']
}
};
const manualConteudo = {
aco_introducao: {
titulo: '📦 Introdução aos Aços',
secao: 'MATERIAIS',
conteudo: `
O que é um Aço?
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.
Classificação dos Aços
Aços Simples (Carbono): Apenas Fe + C, sem elementos de liga adicionados
Aços Ligados: Contêm Mn, Cr, Mo, V, Ni, etc para melhorar propriedades
Aços Inoxidáveis: Alto teor de Cr (>10%), excelente resistência à corrosão
Aços Estruturais: Otimizados para uso em estruturas (edifícios, pontes, etc)
Propriedades Principais
Propriedade Definição Unidade
Resistência à Tração (fu) Máxima tensão que o aço aguenta MPa
Limite de Escoamento (fy) Tensão a partir da qual começa deformação permanente MPa
Alongamento Quanto o aço se alonga antes de quebrar %
Dureza Resistência ao risco/deformação superficial HB, HRC
Tenacidade Capacidade de absorver impactos sem quebrar J (Joules)
Aços Estruturais Mais Comuns
Norma Designação fy (MPa) fu (MPa) Aplicação
ASTM A36 250 400-550 Uso geral, estruturas comuns
ASTM A572 Gr.50 345 450-620 Estruturas de alta resistência
EN S235 235 360-510 Estruturas gerais (Europa)
EN S355 355 510-680 Estruturas exigentes (Europa)
`
},
cev_entendimento: {
titulo: '⛗️ Entendendo Carbono Equivalente',
secao: 'MATERIAIS',
conteudo: `
O que é CEV?
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.
Por que CEV importa?
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.
Fórmulas de CEV
Interpretação de Valores
CEV Soldabilidade Recomendação
<0.35 Excelente Nenhuma restrição, soldagem direta
0.35-0.45 Boa Considerar pré-aquecimento
0.45-0.55 Moderada Pré-aquecimento necessário
>0.55 Difícil Controle rigoroso + especialista
Exemplos Práticos
Exemplo 1: A36
C=0.20, Mn=0.95, Cr=0.10, Mo=0, V=0, Ni=0, Cu=0
CEV = 0.20 + (0.95/6) + 0 = 0.36 (Soldável)
`
},
preaquecimento_guia: {
titulo: '🌡️ Guia Completo de Pré-Aquecimento',
secao: 'SOLDAGEM',
conteudo: `
O que é Pré-Aquecimento?
Pré-aquecimento é o processo de elevar a temperatura do material base (e zona ao redor) ANTES de iniciar a soldagem.
Por que Pré-aquecer?
Durante a soldagem, o material próximo à solda esfria muito rapidamente. Este resfriamento rápido pode causar:
📉 Aumento de dureza excessiva
🔨 Formação de estrutura frágil (martensita)
⚠️ Risco de trincas (especialmente em aços com alto CEV)
Pré-aquecimento reduz a taxa de resfriamento , permitindo transformação metalúrgica adequada.
Quando Usar?
Situação CEV Recomendação
Aço simples + espessura fina <0.35 ❌ Não necessário
Aço estrutural comum 0.35-0.45 ⚠️ Considerar
Aço de alta resistência 0.45-0.55 ✅ Necessário
Aço muito ligado >0.55 🔴 Crítico
Instruções Práticas
Medir: Use termômetro de contato em vários pontos
Aquecer: Maçarico, resistência, forno - qualquer método vale
Verificar: Confirme temperatura antes de soldar
Manter: Mantenha interpass durante toda soldagem
Esfriar: Deixe esfriar lentamente (não molhe bruscamente!)
`
},
soldagem_introducao: {
titulo: '🔥 Introdução à Soldagem',
secao: 'SOLDAGEM',
conteudo: `
O que é Soldagem?
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.
Processos de Soldagem Principais
SMAW (Eletrodo Revestido): Processo manual mais comum
GMAW (MIG/MAG): Soldagem com arame contínuo e gás de proteção
GTAW (TIG): Alta qualidade, ideal para aços inoxidáveis
FCAW: Arame tubular, produtivo
Fatores Críticos
Para uma boa solda, considere:
Limpeza da superfície
Pré-aquecimento adequado
Velocidade de soldagem controlada
Energia de soldagem (Heat Input) apropriada
Proteção gasosa eficaz
`
}
};
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: `
O que são Parafusos Estruturais?
Parafusos estruturais são elementos de fixação de alta resistência projetados para transmitir forças entre componentes de estruturas metálicas.
Tipos Principais
Tipo fy (MPa) fu (MPa) Aplicação
ASTM A325 400 635 Estruturas gerais (padrão)
ASTM A490 565 895 Alta resistência
ISO 8.8 640 800 Padrão métrico
ISO 10.9 900 1000 Máxima resistência
Componentes da Ligação
Parafuso: Elemento principal com rosca
Porca: Elemento de fixação roscado
Arruela: Distribui tensão e protege superfície
Modos de Falha
Cisalhamento do Parafuso: Ruptura do corpo do parafuso
Esmagamento da Chapa: Deformação da chapa no furo
Ruptura em Bloco: Ruptura de seção da chapa
Tração: Ruptura do parafuso por tração
`
};
manualConteudo.cisalhamento_analise = {
titulo: '🔧 Análise de Cisalhamento',
secao: 'CONEXÕES',
conteudo: `
Cisalhamento em Parafusos
O cisalhamento é o modo de falha mais comum em ligações parafusadas, onde o parafuso é cortado transversalmente pela força aplicada.
Fórmula de Verificação
Planos de Corte
Plano Simples (n=1): Parafuso cortado em um ponto
Plano Duplo (n=2): Parafuso cortado em dois pontos - DOBRA a capacidade!
Exemplo Prático
Parafuso A325 Ø16mm
fy = 400 MPa, A = π(16/2)² = 201 mm²
Plano Simples: Fv = 0.6 × 400 × 201 / 1000 = 48.2 kN
Plano Duplo: Fv = 48.2 × 2 = 96.4 kN ✅
`
};
manualConteudo.pintura_introducao = {
titulo: '🎨 Introdução à Pintura Industrial',
secao: 'PINTURA',
conteudo: `
Sistemas de Pintura
Pintura industrial é um sistema de proteção anticorrosiva composto por múltiplas camadas (demãos) que protegem o aço contra degradação.
Componentes do Sistema
Fundo (Primer): Primeira camada, aderência e proteção
Intermediário: Aumenta espessura e proteção
Acabamento: Proteção UV e estética
Tipos de Tinta
Tipo Características Aplicação
Epóxi Excelente adesão, química Fundo e intermediário
Poliuretano Resistência UV, brilho Acabamento
Alquídica Econômica, secagem lenta Ambientes leves
Zinc-Rich Proteção galvânica Ambientes agressivos
`
};
manualConteudo.iso12944 = {
titulo: '🎯 ISO 12944 - Classificação de Ambientes',
secao: 'PINTURA',
conteudo: `
ISO 12944 - Padrão Internacional
ISO 12944 classifica ambientes de corrosividade e especifica sistemas de pintura adequados para cada categoria.
Categorias de Corrosividade
Classe Ambiente DFT Mín (μm) Vida Útil
C1 Interior seco (escritório) 80 5-10 anos
C2 Interior úmido (ginásio) 120 5-10 anos
C3 Exterior urbano/costeiro 160 10-15 anos
C4 Industrial/marinho moderado 200 15-20 anos
C5 Marinho agressivo/offshore 250 20+ anos
Sistemas Recomendados por Categoria
C3 (Padrão Indústria):
Fundo: Epóxi 60μm
Intermediário: Epóxi 60μm
Acabamento: Poliuretano 40μm
Total: 160μm
`
};
manualConteudo.orcamento_basico = {
titulo: '💰 Conceitos Básicos de Orçamento',
secao: 'ORÇAMENTO',
conteudo: `
Estrutura de um Orçamento
Orçamento é a estimativa detalhada de todos os custos envolvidos em um projeto.
Categorias de Custos
Materiais: Perfis, chapas, parafusos
Serviços: Mão de obra especializada
Consumíveis: Eletrodos, tintas, gases
Indiretos: Transporte, EPI, aluguel de equipamentos
Como Calcular Preço de Materiais
Para perfis e chapas: Preço = Peso × Preço/kg
Preços variam por região do Brasil:
Sudeste: R$ 7.50/kg (referência)
Sul: R$ 7.20/kg (mais barato)
Nordeste: R$ 8.00/kg
Centro-Oeste: R$ 7.70/kg
`
};
manualConteudo.bdi_margem = {
titulo: '📊 BDI e Margem de Lucro',
secao: 'ORÇAMENTO',
conteudo: `
O que é BDI?
BDI (Benefícios e Despesas Indiretas) é um percentual aplicado sobre os custos diretos para cobrir:
Componentes do BDI
Administração Central: Escritório, contabilidade (5-8%)
Lucro: Margem de lucro da empresa (8-15%)
Impostos: ISS, PIS, COFINS (5-10%)
Riscos: Contingência para imprevistos (2-5%)
BDI Típico por Tipo de Obra
Tipo de Obra BDI Típico
Pequenas estruturas 20-25%
Edifícios comerciais 25-30%
Pontes e obras públicas 25-28%
Offshore e projetos complexos 30-35%
Exemplo de Cálculo
Custos Diretos: R$ 100.000,00
BDI: 25%
Valor BDI: R$ 100.000 × 0.25 = R$ 25.000,00
TOTAL: R$ 125.000,00
`
};
manualConteudo.ensaios_introducao = {
titulo: '✅ Introdução a Ensaios',
secao: 'ENSAIOS',
conteudo: `
Por que Ensaiar?
Ensaios são testes realizados em materiais e soldas para verificar conformidade com especificações e normas.
Tipos de Ensaios
Ensaios Destrutivos
Tração: Mede fy, fu e alongamento
Dureza: Mede resistência à penetração
Charpy: Mede tenacidade ao impacto
Dobramento: Verifica ductilidade da solda
Ensaios Não Destrutivos (END)
Ultrassom (UT): Detecta defeitos internos
Radiografia (RT): Imagem de defeitos
Partículas Magnéticas (MT): Defeitos superficiais
Líquido Penetrante (PT): Trincas superficiais
`
};
manualConteudo.dureza_escalas = {
titulo: '🔨 Escalas de Dureza',
secao: 'ENSAIOS',
conteudo: `
Escalas de Dureza
Dureza mede a resistência de um material à deformação permanente por indentação.
Brinell (HB)
Método: Esfera de aço ou tungstênio pressionada na superfície
Faixa: 100-650 HB
Aplicação: Aços estruturais, ferro fundido
Rockwell C (HRC)
Método: Cone de diamante
Faixa: 20-70 HRC
Aplicação: Aços temperados, ferramentas
Vickers (HV)
Método: Pirâmide de diamante
Faixa: 100-1000+ HV
Aplicação: Universal, todos os materiais
Correlação com Resistência
Para aços carbono:
fu (MPa) ≈ HB × 10
`
};
manualConteudo.impacto_charpy = {
titulo: '📉 Ensaio de Impacto Charpy',
secao: 'ENSAIOS',
conteudo: `
O que é o Ensaio Charpy?
Ensaio que mede a energia absorvida por um corpo de prova entalhado ao ser rompido por um pêndulo.
Por que é Importante?
Materiais podem se comportar de forma dúctil (absorvem energia) ou frágil (quebram subitamente) dependendo da temperatura.
Temperatura de Transição (TTDF)
Temperatura onde o material muda de comportamento dúctil para frágil.
Critério comum: TTDF = temperatura onde energia = 27J
Requisitos por Aplicação
Aplicação Energia Mín Temperatura
Estruturas internas 27J 0°C
Estruturas externas 27J -20°C
Offshore/Ártico 40J -40°C
`
};
manualConteudo.layout_furacao = {
titulo: '📍 Layout de Furação',
secao: 'CONEXÕES',
conteudo: `
Distâncias e Espaçamentos
NBR 8800 e AISC 360 estabelecem limites para garantir resistência adequada.
Distância de Borda
Mínimo: 1.5d (evita ruptura da borda)
Máximo: 12t ou 150mm (evita empenamento)
Espaçamento entre Furos
Mínimo: 2.67d (evita interferência de tensões)
Máximo: 300mm (evita correlação local)
Exemplo
Parafuso Ø20mm, Chapa 10mm
Mínimo borda: 1.5 × 20 = 30mm
Máximo borda: 12 × 10 = 120mm
Mínimo espaçamento: 2.67 × 20 = 53.4mm
`
};
manualConteudo.eletrodos_tipos = {
titulo: '🔥 Tipos de Eletrodos',
secao: 'SOLDAGEM',
conteudo: `
Eletrodos Revestidos (SMAW)
Eletrodo revestido é composto por alma metálica + revestimento que gera escória protetora e gás.
Classificação AWS
Eletrodo Revestimento Resistência Aplicação
E6013 Rutílico 420 MPa Geral, fácil
E7018 Básico 485 MPa Estrutural (padrão)
E8018 Básico 550 MPa Alta resistência
Vantagens do Básico (E7018)
✅ Baixo hidrogênio (previne trincas)
✅ Alta tenacidade (Charpy 47J)
✅ Excelente para estruturas críticas
`
};
manualConteudo.sequencia_soldagem = {
titulo: '🔄 Sequência de Soldagem',
secao: 'SOLDAGEM',
conteudo: `
Por que Sequência Importa?
A ordem de deposição da solda afeta diretamente as distorções e tensões residuais na estrutura.
Padrões de Soldagem
1. Skip Welding (Recomendado)
Solda em segmentos alternados, deixando espaços que são preenchidos depois.
Vantagem: Reduz distorções em 80%
2. Backstep Welding
Soldagem em segmentos curtos na direção oposta ao avanço geral.
Vantagem: Reduz distorções em 60%
3. Contínuo (Não Recomendado)
Soldagem contínua sem paradas.
Desvantagem: Máxima distorção
`
};
manualConteudo.equivalencias_normas = {
titulo: '🌍 Equivalências Internacionais',
secao: 'MATERIAIS',
conteudo: `
Por que Equivalências?
Projetos internacionais podem especificar aços de diferentes normas. Conhecer equivalências permite substituição adequada.
Principais Equivalências
ASTM EN JIS NBR
A36 S235JR SS400 -
A572 Gr.50 S355J2 SM490 AR350
A588 S355K2G3 - -
⚠️ Cuidados na Substituição
Verificar composição química
Confirmar propriedades mecânicas
Checar soldabilidade (CEV)
Validar com engenheiro responsável
`
};
manualConteudo.acos_estruturais = {
titulo: '🏭 Aços Estruturais Comuns',
secao: 'MATERIAIS',
conteudo: `
Aços Mais Usados no Brasil
ASTM A36 - O "Trabalhador"
Propriedades: fy=250 MPa, fu=400 MPa
Aplicação: Estruturas gerais, baixa responsabilidade
Vantagens: Barato, muito soldável, disponível
ASTM A572 Gr.50 - O "Profissional"
Propriedades: fy=345 MPa, fu=450 MPa
Aplicação: Edifícios altos, pontes, estruturas pesadas
Vantagens: Ótima relação custo/benefício
EN S355J2 - O "Europeu"
Propriedades: fy=355 MPa, fu=490 MPa
Aplicação: Projetos internacionais
Vantagens: Boa tenacidade, amplamente especificado
`
};
manualConteudo.preparo_superficie = {
titulo: '🧹 Preparação de Superfície',
secao: 'PINTURA',
conteudo: `
A Preparação É Fundamental!
90% dos problemas de pintura vem de preparação inadequada da superfície.
Graus de Limpeza ISO 8501-1
Grau Descrição Uso
Sa 1 Jateamento ligeiro Não recomendado
Sa 2 Jateamento comercial Ambientes leves
Sa 2½ Jateamento ao metal quase branco Padrão indústria
Sa 3 Jateamento ao metal branco Ambientes severos
Métodos de Preparação
Jateamento Abrasivo: Método mais eficaz
Lixamento Mecânico: Para pequenas áreas
Escovamento: Manutenção apenas
Desengraxe: Sempre necessário
`
};
manualConteudo.precos_mercado = {
titulo: '💲 Preços do Mercado Brasileiro',
secao: 'ORÇAMENTO',
conteudo: `
Preços Médios 2025
Valores de referência para orçamentos (sujeitos a variação).
Aços Estruturais
Região A36 (R$/kg) A572 (R$/kg)
Sudeste (SP/RJ) 7.50 8.50
Sul (RS/SC/PR) 7.20 8.20
Nordeste 8.00 9.00
Centro-Oeste 7.70 8.70
Serviços
Soldagem: R$ 60-70/h (soldador qualificado)
Pintura: R$ 35-45/m²
Montagem: R$ 50-65/h
Consumíveis
E7018: R$ 45/kg
Tinta Epóxi C3: R$ 80/L
Parafuso A325 M16: R$ 1.20/un
`
};
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 = `
Para que serve?
${ajuda.paraQueServe}
Quando usar?
${ajuda.quandoUsar}
⚠️ Avisos Importantes
${ajuda.avisos.map(a => `${a} `).join('')}
`;
// Tab 1: Campos
document.getElementById('help-tab-1').innerHTML = `
Campo
Unidade
Significado
Intervalo Típico
Dica
${ajuda.campos.map(c => `
${c.nome}
${c.unidade}
${c.significado}
${c.intervalo}
${c.dica}
`).join('')}
`;
// Tab 2: Resultados
document.getElementById('help-tab-2').innerHTML = `
O que significam os resultados?
${ajuda.resultados}
`;
// Tab 3: Referências
document.getElementById('help-tab-3').innerHTML = `
📚 Referências Bibliográficas
${ajuda.referencias.map(r => `
${r.titulo}
${r.ano ? `Ano: ${r.ano}
` : ''}
${r.url ? `
${r.url} ` : ''}
`).join('')}
📖 Leia também no Manual
${ajuda.manualRelacionado.map(tema => {
const conteudo = manualConteudo[tema];
return conteudo ? `${conteudo.titulo} ` : '';
}).join('')}
`;
document.getElementById('modalAjuda').classList.add('active');
}
function closeAjudaModal() {
document.getElementById('modalAjuda').classList.remove('active');
}
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 += `
${secao}
${manualNavStructure[secao].map(tema => {
const conteudo = manualConteudo[tema];
return conteudo ? `
• ${conteudo.titulo}
` : '';
}).join('')}
`;
});
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 = `
${conteudo.titulo}
${conteudo.secao}
${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() {
showSection('cev');
mostrarEquivalencias();
gerarChecklistCertificado();
updatePaintFields();
updateWeightFields();
applyAdminConfig();
filterToolsByMode();
addHelpButton('cev');
// Initialize budget when switching to orcamento section
const observer = new MutationObserver(() => {
if (appState.currentSection === 'orcamento') {
setTimeout(initializeBudget, 100);
}
});
// Close admin modal on outside click
const adminModal = document.getElementById('adminModal');
if (adminModal) {
adminModal.addEventListener('click', function(e) {
if (e.target === adminModal) {
closeAdminModal();
}
});
}
});