1/** 2 * BP Portal Shared Utilities 3 * Provides common functions for parts-proposal.js and machine-configurator.js 4 * Loaded as a standard script (not module) in WordPress environment 5 */ 6 7(function() { 8 'use strict'; 9 10 window.BPUtilities = window.BPUtilities || {}; 11 12 /** 13 * Format a number as USD currency. 14 */ 15 window.BPUtilities.fmt_currency = function(n) { 16 if (typeof n !== 'number') n = parseFloat(n) || 0; 17 return new Intl.NumberFormat('en-US', { 18 style: 'currency', 19 currency: 'USD', 20 minimumFractionDigits: 2, 21 maximumFractionDigits: 2 22 }).format(n); 23 }; 24 25 /** 26 * Escape HTML special characters. 27 */ 28 window.BPUtilities.esc = function(v) { 29 const map = { 30 '&': '&', 31 '<': '<', 32 '>': '>', 33 '"': '"', 34 "'": ''' 35 }; 36 return String(v).replace(/[&<>"']/g, c => map[c]); 37 }; 38 39 /** 40 * Simple debounce utility. 41 */ 42 window.BPUtilities.debounce = function(fn, delay) { 43 let timeoutId; 44 return function(...args) { 45 clearTimeout(timeoutId); 46 timeoutId = setTimeout(() => fn(...args), delay); 47 }; 48 }; 49 50 /** 51 * Fire a portal AJAX action with proper error handling. 52 */ 53 window.BPUtilities.fetch_ajax = async function(action, params) { 54 try { 55 const res = await fetch(bpProposal.ajaxUrl, { 56 method: 'POST', 57 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 58 body: new URLSearchParams({ 59 action, 60 nonce: bpProposal.nonce, 61 ...params 62 }) 63 }); 64 65 if (!res.ok) { 66 throw new Error(`HTTP ${res.status}: ${res.statusText}`); 67 } 68 69 const json = await res.json(); 70 if (!json.success) { 71 throw new Error(json.data?.message || json.data || 'Request failed.'); 72 } 73 74 return json.data; 75 } catch (e) { 76 console.error(`AJAX error (${action}):`, e); 77 throw e; 78 } 79 }; 80})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.