PageSourceSearch

https://naparbideak.com/js/funciones.js

js naparbideak.com collected 2026-09-27 12:41:32 UTC 9,452 bytes, 260 lines download raw bytes

1// ============================
2//   NAVEGACIÓN: CÓMO LLEGAR
3// ============================
4function abrirNavegador(lat, lon) {
5    lat = lat.toString().replace(",", ".");
6    lon = lon.toString().replace(",", ".");
7
8    const destino = `${lat},${lon}`;
9    const ua = navigator.userAgent;
10
11    // iPhone / iPad → Apple Maps app
12    if (/iPhone|iPad/.test(ua)) {
13        window.location.href = `maps://?daddr=${destino}`;
14        return;
15    }
16
17    // macOS → Apple Maps web
18    if (/Macintosh/.test(ua)) {
19        window.open(`https://maps.apple.com/?daddr=${destino}`, "_blank");
20        return;
21    }
22
23    // Android → Google Maps
24    if (/Android/.test(ua)) {
25        window.location.href = `https://www.google.com/maps/search/?api=1&query=${destino}`;
26        return;
27    }
28
29    // Escritorio
30    window.open(`https://www.google.com/maps/dir/?api=1&destination=${destino}`, "_blank");
31}
32
33
34
35
36function formatearMiles(num) {
37    return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
38}
39
40function formatearDecimal(num, decimales = 2) {
41    return Number(num).toFixed(decimales).replace(".", ",");
42}
43
44function capitalizar(texto) {
45    return texto.charAt(0).toUpperCase() + texto.slice(1).toLowerCase();
46}
47function formatearFecha(fechaIso) {
48    if (!fechaIso) return '';
49    const partes = fechaIso.split('-');
50    if (partes.length !== 3) return fechaIso;
51    return `${partes[2]}/${partes[1]}/${partes[0]}`;
52}
53function crearSlug(texto) {
54    return texto
55        .toLowerCase()
56        .normalize("NFD").replace(/[\u0300-\u036f]/g, "") // quitar acentos
57        .replace(/[^a-z0-9\s-]/g, "")                    // quitar símbolos
58        .trim()
59        .replace(/\s+/g, "-");                           // espacios → guiones
60}
61function existeImagen(url, callback) {
62    const img = new Image();
63    img.onload = () => callback(true);
64    img.onerror = () => callback(false);
65    img.src = url;
66}
67function getYear(fecha) {
68    if (!fecha) return "";
69    const d = new Date(fecha);
70    return isNaN(d.getTime()) ? "" : d.getFullYear();
71}
72
73
74function decidirContenidoWebcam(w) {
75
76    // ===============================
77    //  PROXY SOLO PARA HTTP INSEGURO
78    // ===============================
79    const necesitaProxy = url =>
80        url && url.startsWith("http://");
81
82    const proxificar = url =>
83        "/WebcamProxy/Stream?url=" + encodeURIComponent(url);
84
85
86    // ===============================
87    // 1) PRIORIDAD MÁXIMA: urlStream
88    // ===============================
89    if (w.urlStream) {
90
91        // A) Streams tipo player.php → visor externo
92        if (w.urlStream.includes("player.php")) {
93            return { tipo: "externo", url: w.urlStream };
94        }
95
96        // B) Streams reales (HLS/MP4) → NO PROXY
97        if (w.urlStream.endsWith(".m3u8") || w.urlStream.endsWith(".mp4")) {
98            return { tipo: "video", url: w.urlStream };
99        }
100
101        // C) MJPEG en urlStream → ***AQUÍ ES DONDE CAMBIAMOS SOLO ESTE CASO***
102        if (w.urlStream.includes("mjpg") || w.urlStream.includes("mjpeg")) {
103
104            // Si hay visor HTML → mejor usarlo (igual que antes)
105            if (w.urlPagina?.includes("viewer") ||
106                w.urlPagina?.includes("view.shtml") ||
107                w.urlPagina?.includes("player.php")) {
108
109                return { tipo: "externo", url: w.urlPagina };
110            }
111
112            // ***ÚNICO CAMBIO REAL***
113            // MJPEG HTTP → PROXY
114            // MJPEG HTTPS → DIRECTO
115            const finalUrl = necesitaProxy(w.urlStream)
116                ? proxificar(w.urlStream)
117                : w.urlStream;
118
119            return { tipo: "imagen", url: finalUrl };
120        }
121
122        // D) Cualquier otro stream → externo por seguridad
123        return { tipo: "externo", url: w.urlStream };
124    }
125
126
127    // ===============================
128    // 2) NO hay stream → usar urlImagen
129    // ***ESTO LO DEJO EXACTAMENTE COMO ESTABA***
130    // ===============================
131    if (w.urlImagen) {
132
133        // A) Imagen real con extensión
134        if (/\.(jpg|jpeg|png)$/i.test(w.urlImagen)) {
135
136            const finalUrl = necesitaProxy(w.urlImagen)
137                ? proxificar(w.urlImagen)
138                : w.urlImagen;
139
140            return { tipo: "imagen", url: finalUrl };
141        }
142
143        // B) MJPEG en urlImagen (NO TOCAMOS NADA)
144        if (w.urlImagen.includes("mjpg") || w.urlImagen.includes("mjpeg")) {
145
146            if (w.urlPagina?.includes("viewer") ||
147                w.urlPagina?.includes("view.shtml") ||
148                w.urlPagina?.includes("player.php")) {
149
150                return { tipo: "externo", url: w.urlPagina };
151            }
152
153            const finalUrl = necesitaProxy(w.urlImagen)
154                ? proxificar(w.urlImagen)
155                : w.urlImagen;
156
157            return { tipo: "imagen", url: finalUrl };
158        }
159
160        // C) Imagen sin extensión (cam.php, snapshot.cgi, etc.)
161        if (
162            w.urlImagen.includes(".php") ||
163            w.urlImagen.includes(".cgi") ||
164            w.urlImagen.includes("snapshot") ||
165            w.urlImagen.includes("capture") ||
166            w.urlImagen.includes("cam.")
167        ) {
168
169            const finalUrl = necesitaProxy(w.urlImagen)
170                ? proxificar(w.urlImagen)
171                : w.urlImagen;
172
173            return { tipo: "imagen", url: finalUrl };
174        }
175    }
176
177
178    // ===============================
179    // 3) Visores externos embebibles (iframe)
180    // ***SIN CAMBIOS***
181    // ===============================
182    if (w.urlPagina) {
183
184        if (w.urlPagina.includes("skaping.com")) {
185            return { tipo: "iframe", url: w.urlPagina };
186        }
187
188        if (w.urlPagina.includes("/embed") ||
189            w.urlPagina.includes("panomax.com") ||
190            w.urlPagina.includes("skylinewebcams.com")) {
191
192            return { tipo: "iframe", url: w.urlPagina };
193        }
194
195        return { tipo: "externo", url: w.urlPagina };
196    }
197
198
199    // ===============================
200    // 4) Nada válido → placeholder
201    // ===============================
202    return { tipo: "placeholder", url: null };
203}
204function textoNivelAludes(nivel) {
205    const estilos = {
206        titulo: "text-align:center; font-weight:bold; font-size:1.2em; margin-bottom:0.5em;",
207        fila: "text-align:left; background:#f7f7f7; padding:6px 10px; border-radius:4px; margin:4px 0;"
208    };
209
210    switch (nivel) {
211        case 1:
212            return `
213<div>
214    <div style="${estilos.titulo}">Riesgo Débil (1)</div>
215    <div style="${estilos.fila}">La nieve está <strong>bien asentada</strong> en general. Solo son posibles aludes espontáneos pequeños en muy pocas laderas extremadamente inclinadas.</div>
216    <div style="${estilos.fila}">Las condiciones son <strong>favorables</strong> para actividades en montaña, aunque siempre es necesaria una evaluación local del terreno.</div>
217</div>
218            `;
219        case 2:
220            return `
221<div>
222    <div style="${estilos.titulo}">Riesgo Limitado (2)</div>
223    <div style="${estilos.fila}">La nieve presenta <strong>inestabilidad moderada</strong> en algunas laderas inclinadas.</div>
224    <div style="${estilos.fila}">Son posibles desencadenamientos por <strong>sobrecarga fuerte</strong> y, en casos aislados, por sobrecarga débil.</div>
225    <div style="${estilos.fila}">Los aludes espontáneos suelen ser pequeños, aunque pueden darse aludes medianos en zonas muy concretas.</div>
226</div>
227            `;
228        case 3:
229            return `
230<div>
231    <div style="${estilos.titulo}">Riesgo Notable (3)</div>
232    <div style="${estilos.fila}">La nieve está <strong>inestable en muchas laderas</strong>. Es posible el desencadenamiento incluso con sobrecargas débiles.</div>
233    <div style="${estilos.fila}">Los aludes espontáneos pueden ser <strong>medianos o grandes</strong>.</div>
234    <div style="${estilos.fila}">Se requiere <strong>experiencia</strong> en evaluación del manto y elección muy cuidadosa del itinerario.</div>
235</div>
236            `;
237        case 4:
238            return `
239<div>
240    <div style="${estilos.titulo}">Riesgo Fuerte (4)</div>
241    <div style="${estilos.fila}">La nieve está <strong>muy inestable</strong> en la mayoría de laderas inclinadas.</div>
242    <div style="${estilos.fila}">Los aludes espontáneos son <strong>probables</strong>, incluso de gran tamaño.</div>
243    <div style="${estilos.fila}">El desencadenamiento es probable incluso con <strong>sobrecargas débiles</strong>. Las condiciones son peligrosas y se recomienda evitar terreno de aludes.</div>
244</div>
245            `;
246        case 5:
247            return `
248<div>
249    <div style="${estilos.titulo}">Riesgo Muy Fuerte (5)</div>
250    <div style="${estilos.fila}"><strong>Situación excepcional.</strong> La nieve está <strong>extremadamente inestable</strong> en prácticamente todas las laderas.</div>
251    <div style="${estilos.fila}">Los aludes espontáneos <strong>grandes y muy grandes</strong> son muy probables.</div>
252    <div style="${estilos.fila}">Las actividades en terreno de aludes deben <strong>evitarse por completo</strong>.</div>
253</div>
254            `;
255        default:
256            return "<p>
256Nivel de peligro no disponible.</p>";
257    }
258}
259
260

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.