1import { Engine as JSLiteEngine } from "../../vendor/jslite.esm.js"; 2 3let formatSize = function(bytes) { 4 if (bytes == 0) { return "0.00 B"; } 5 let e = Math.floor(Math.log(bytes) / Math.log(1024)); 6 return ((bytes / Math.pow(1024, e)).toFixed(2) + ' ' + ' KMGTP'.charAt(e) + 'B').replace('.00', ''); 7} 8 9let formatNumber = function(num, round = 2) { 10 return (new Intl.NumberFormat(navigator.language, { style: 'decimal', maximumFractionDigits: round})).format(num); 11} 12 13let formatDuration = function(time) { 14 // Hours, minutes and seconds 15 let hrs = ~~(time / 3600); 16 let mins = ~~((time % 3600) / 60); 17 let secs = ~~time % 60; 18 19 // Output like "1:01" or "4:03:59" or "123:03:59" 20 let ret = ''; 21 22 if (hrs > 0) { 23 ret += `${hrs}:${(mins < 10 ? '0' : '')}`; 24 } 25 26 ret += `${mins}:${(secs < 10 ? '0' : '')}`; 27 ret += `${secs}`; 28 return ret; 29} 30 31let isNumeric = function(n) { return !isNaN(parseFloat(n)) && isFinite(n); } 32 33let on = function(element, name, delegate, fn) { 34 35 if (!fn) { 36 element.addEventListener(name, arguments[2]); 37 } else { 38 element.addEventListener(name, function(e) { 39 40 let target = e.target; 41 42 while (target !== element) { 43 44 if (!target) { 45 break; 46 } 47 48 if (target.matches(delegate)) { 49 return fn.apply(target, arguments); 50 } 51 52 target = target.parentNode; 53 } 54 }); 55 } 56 57 return element; 58}; 59 60let toKebabCase = function(str) { 61 return str.replace(/([a-z])([A-Z])/g, '$1-$2').replace(/\s+/g, '-').toLowerCase(); 62}; 63 64let copyText = function(text, cb) { 65 let inp = document.createElement('textarea'); 66 document.body.appendChild(inp) 67 inp.value = text 68 inp.select(); 69 try { document.execCommand('copy', false); } catch (e) { } 70 inp.remove(); 71 if (cb) cb(); 72} 73 74let interpolateEngine = new JSLiteEngine(); 75 76let interpolate = function(str, params) { 77 const source = `return \`${str}\`;`; 78 return interpolateEngine.run(interpolateEngine.compile(source), Object.assign({}, params)); 79} 80 81let uuid = function() { 82 83 if (typeof(crypto) !== 'undefined' && typeof(crypto.randomUUID) === 'function') { 84 return crypto.randomUUID(); 85 } 86 87 return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => 88 (c ^ (typeof(crypto) !== 'undefined' && typeof(crypto.getRandomValues) === 'function' ? crypto.getRandomValues(new Uint8Array(1))[0] : Math.floor(Math.random() * 255)) & 15 >> c / 4).toString(16) 89 ); 90} 91 92let nanoid = function(size = 10) { 93 94 const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 95 let id = ''; 96 97 if (typeof(crypto) !== 'undefined' && typeof(crypto.getRandomValues) === 'function') { 98 const bytes = new Uint8Array(size); 99 crypto.getRandomValues(bytes); 100 for (let i = 0; i < size; i++) id += alphabet[bytes[i] % alphabet.length]; 101 return id; 102 } 103 104 for (let i = 0; i < size; i++) id += alphabet.charAt(Math.floor(Math.random() * alphabet.length)); 105 return id; 106} 107 108 109let truncate = function(text, length, clamp = '...') { 110 let content = text || ''; 111 return content.length > length ? content.slice(0, length) + clamp : content; 112}; 113 114let stripTags = function(input, allowed) { 115 116 if (Array.isArray(allowed)) { 117 let tags = ''; 118 allowed.forEach(tag => tags += `<${tag}>`); 119 allowed = tags; 120 } 121 122 // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>) 123 allowed = (((allowed || '') + '').toLowerCase().match(/<[a-z][a-z0-9\-]*>/g) || []).join(''); 124 const tags = /<\/?([a-z0-9\-]*)\b[^>]*>?/gi; 125 const commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi; 126 let after = input; 127 128 after = (after.substring(after.length - 1) === '<') ? after.substring(0, after.length - 1) : after; 129 130 while (true) { 131 const before = after 132 after = before.replace(commentsAndPhpTags, '').replace(tags, ($0, $1) => { 133 return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '' 134 }); 135 if (before === after) { 136 return after 137 } 138 } 139}; 140 141let base64encode = function(str) { 142 return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) =>
142 String.fromCharCode('0x' + p1))); 143}; 144 145let base64decode = function(str) { 146 return decodeURIComponent(atob(str).split('').map((c) => { 147 return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) 148 }).join('')); 149}; 150 151let escape = function(html) { 152 return String(html) 153 .replace(/&/g, "&") 154 .replace(/</g, "<") 155 .replace(/>/g, ">") 156 .replace(/"/g, """) 157 .replace(/'/g, "'"); 158}; 159 160export default { 161 base64encode, 162 base64decode, 163 copyText, 164 escape, 165 formatSize, 166 formatDuration, 167 formatNumber, 168 interpolate, 169 isNumeric, 170 nanoid, 171 on, 172 toKebabCase, 173 uuid, 174 truncate, 175 stripTags 176}
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.