blob: 9e4fb5f72a934393e5c9abe967fb2941b5bc0d05 [file] [log] [blame]
Earl Lee2e463fb2025-04-17 11:22:22 -07001/**
2 * Escapes HTML special characters in a string
3 */
Autoformatter81eacc42025-04-30 18:10:50 +00004export function escapeHTML(str: string): string {
Earl Lee2e463fb2025-04-17 11:22:22 -07005 return str
6 .replace(/&/g, "&")
7 .replace(/</g, "&lt;")
8 .replace(/>/g, "&gt;")
9 .replace(/"/g, "&quot;")
10 .replace(/'/g, "&#039;");
11}
12
13/**
14 * Formats a number with locale-specific formatting
15 */
16export function formatNumber(
17 num: number | null | undefined,
18 defaultValue: string = "0",
19): string {
20 if (num === undefined || num === null) return defaultValue;
21 try {
22 return num.toLocaleString();
philip.zeyliger26bc6592025-06-30 20:15:30 -070023 } catch {
Earl Lee2e463fb2025-04-17 11:22:22 -070024 return String(num);
25 }
26}
27
28/**
29 * Generates a consistent color based on an ID string
30 */
31export function generateColorFromId(id: string | null | undefined): string {
32 if (!id) return "#7c7c7c"; // Default color for null/undefined
33
34 // Generate a hash from the ID
35 let hash = 0;
36 for (let i = 0; i < id.length; i++) {
37 hash = id.charCodeAt(i) + ((hash << 5) - hash);
38 }
39
40 // Convert hash to a hex color
41 let color = "#";
42 for (let i = 0; i < 3; i++) {
43 // Generate more muted colors by using only part of the range
44 // and adding a base value to avoid very dark colors
Sean McCullough71941bd2025-04-18 13:31:48 -070045 const value = (hash >> (i * 8)) & 0xff;
Earl Lee2e463fb2025-04-17 11:22:22 -070046 const scaledValue = Math.floor(100 + (value * 100) / 255); // Range 100-200 for more muted colors
47 color += scaledValue.toString(16).padStart(2, "0");
48 }
49 return color;
50}