PageSourceSearch

https://willamettevalleymesh.net/js/wxalert.js?64983

js willamettevalleymesh.net collected 2026-10-05 18:43:21 UTC 4,339 bytes, 114 lines download raw bytes

1(function () {
2    const API_URL = "https://api.weather.gov/alerts/active?point=45.271,-122.946";
3
4    // Inject widget container and CSS
5    document.write(`
6        <style>
7            #weather-alert-widget {
8                display: none;
9                width: 100%;
10                max-width: 900px;
11                margin: auto;
12                font-family: Arial, sans-serif;
13            }
14            .alert-box {
15                font-size: 20px;
16                padding: 16px;
17                margin: 8px 0;
18                border-radius: 8px;
19                display: flex;
20                align-items: center;
21                justify-content: space-between;
22                width: 100%;
23                position: relative;
24                cursor: default;
25            }
26            .alert-box:hover .tooltip {
27                display: block;
28            }
29            .tooltip {
30                display: none;
31                position: absolute;
32                top: 110%;
33                left: 0;
34                background: #222;
35                color: #fff;
36                padding: 14px;
37                font-size: 16px;
38                border-radius: 8px;
39                z-index: 10;
40                width: 100%;
41                white-space: pre-wrap;
42                box-shadow: 0 4px 8px rgba(0,0,0,0.3);
43            }
44            .alert-icon {
45                font-size: 24px;
46                margin-right: 10px;
47            }
48            .arrow {
49                font-size: 24px;
50                padding-left: 20px;
51            }
52        </style>
53        <div id="weather-alert-widget"></div>
54    `);
55
56    async function fetchWeatherAlerts() {
57        try {
58            let response = await fetch(API_URL);
59            let data = await response.json();
60
61            const widget = document.getElementById("weather-alert-widget");
62            widget.innerHTML = "";
63
64            if (data.features.length === 0) {
65                widget.style.display = "none";
66                return;
67            }
68
69            let alertMap = new Map();
70            data.features.forEach(alert => {
71                let alertType = alert.properties.event;
72                let headline = alert.properties.headline;
73                let severity = alert.properties.severity;
74                let description = alert.properties.description || "No further details available.";
75                let issuedTime = new Date(alert.properties.sent);
76
77                if (!alertMap.has(alertType) || issuedTime > alertMap.get(alertType).issuedTime) {
78                    alertMap.set(alertType, { alertType, severity, headline, description, issuedTime });
79                }
80            });
81
82            const severityStyles = {
83                "Extreme": { bgColor: "darkred", fontColor: "white", icon: "🛑" },
84                "Severe": { bgColor: "red", fontColor: "white", icon: "⚠️" },
85                "Moderate": { bgColor: "orange", fontColor: "black", icon: "❗" },
86                "Minor": { bgColor: "blue", fontColor: "white", icon: "ℹ️" },
87                "Unknown": { bgColor: "gray", fontColor: "white", icon: "❓" }
88            };
89
90            let alertContent = "";
91            Array.from(alertMap.values()).slice(0, 3).forEach((alert, index) => {
92                const style = severityStyles[alert.severity] || severityStyles["Unknown"];
93                alertContent += `
94                    <div class="alert-box" style="background:${style.bgColor}; color:${style.fontColor};">
95                        <span><span class="alert-icon">${style.icon}</span><strong>${alert.alertType}</strong>: ${alert.headline}</span>
96                        <span class="arrow">ℹ️</span>
97                        <div class="tooltip">${alert.description}</div>
98                    </div>
99                `;
100            });
101
102            widget.innerHTML = alertContent;
103            widget.style.display = "block";
104
105        } catch (error) {
106            console.error("Error fetching alerts:", error);
107            const widget = document.getElementById("weather-alert-widget");
108            if (widget) widget.style.display = "none";
109        }
110    }
111
112    fetchWeatherAlerts();
113    setInterval(fetchWeatherAlerts, 300000);
114})();

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.