Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | /** * Utility helpers */ /** * Format bytes to human readable string */ function formatBytes(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } /** * Format number with commas */ function formatNumber(num) { return num.toLocaleString(); } /** * Get file extension from filename */ function getFileExtension(filename) { return filename.slice((filename.lastIndexOf('.') - 1 >>> 0) + 2); } /** * Check if path is hidden (starts with dot) */ function isHidden(filePath) { return filePath.split('/').some(part => part.startsWith('.')); } /** * Sanitize filename for safe usage */ function sanitizeFilename(filename) { return filename.replace(/[^a-z0-9]/gi, '_').toLowerCase(); } /** * Deep merge objects */ function deepMerge(target, source) { const output = Object.assign({}, target); if (isObject(target) && isObject(source)) { Object.keys(source).forEach(key => { if (isObject(source[key])) { if (!(key in target)) Object.assign(output, { [key]: source[key] }); else output[key] = deepMerge(target[key], source[key]); } else { Object.assign(output, { [key]: source[key] }); } }); } return output; } /** * Check if value is object */ function isObject(item) { return item && typeof item === 'object' && !Array.isArray(item); } /** * Debounce function */ function debounce(func, wait, immediate) { let timeout; return function executedFunction(...args) { const later = () => { timeout = null; if (!immediate) func(...args); }; const callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func(...args); }; } /** * Throttle function */ function throttle(func, limit) { let inThrottle; return function(...args) { if (!inThrottle) { func.apply(this, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } /** * Generate unique ID */ function generateId() { return Math.random().toString(36).substr(2, 9); } /** * Sleep for specified milliseconds */ function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } module.exports = { formatBytes, formatNumber, getFileExtension, isHidden, sanitizeFilename, deepMerge, isObject, debounce, throttle, generateId, sleep }; |