PageSourceSearch

https://radiobrasileirissima.com.br/assets/js/utils.js?v=tjmed4

js radiobrasileirissima.com.br collected 2026-10-08 10:18:19 UTC 18,027 bytes, 434 lines download raw bytes

1// Theme strings when the theme provides them, Portuguese defaults otherwise
2function T(key){
3	var fallback = { 'with': 'com', no_program: 'Nenhum programa disponível no momento', online_now: 'Online agora', no_host: 'Nenhum locutor está online neste momento' };
4	return (window.BRAS_T && window.BRAS_T[key]) || fallback[key] || '';
5}
6
7let ajaxify = new ReqBras({ elements: '#pContent', selector: 'a:not(.ext-link)', scrolltop: true, forms: false, prefetchoff: true, memoryoff: true, inlineskip: '' });
8window.addEventListener('pronto.request', () => {
9  NProgress.start();
10});
11window.addEventListener('pronto.render', () => {
12	renderGoogleReCaptcha();
13	renderMap();
14  NProgress.done();
15
16  const currentURL = window.location.pathname;
17    const pathParts = currentURL.split('/').filter(Boolean);
18    const pageName = pathParts[pathParts.length - 1] || 'home';
19    
20    
21    
22const sliderModule = document.querySelector('.modules .module-21');
23
24if (sliderModule) {
25  if (pageName !== 'home') {
26    sliderModule.classList.add('hideSlider');
27  } else {
28    sliderModule.classList.remove('hideSlider');
29  }
30}
31
32
33});
34window.addEventListener('pronto.error', () => {
35  NProgress.done(true);
36});
37
38
39document.addEventListener('pronto.load', function () {
40    if (typeof renderMap === 'function') {
41        renderMap();
42    }
43});
44
45// The router fires pronto.load while booting, before this file finishes: on a
46// direct hit the map only draws from here
47document.addEventListener('DOMContentLoaded', function () {
48    if (typeof renderMap === 'function') {
49        renderMap();
50    }
51});
52
53var MAP_CONTAINERS = {};
54var GRECAPTCHA_CONTAINERS = GRECAPTCHA_CONTAINERS || {};
55
56function renderGoogleReCaptcha() {
57  // Verifica se o grecaptcha está disponível
58  if (typeof grecaptcha !== 'undefined' && typeof grecaptcha.render !== 'undefined') {
59    var recaptchaContainers = document.querySelectorAll('.g-recaptcha-container:not(.recaptcha-initialized)');
60
61    if (recaptchaContainers.length > 0) {
62      recaptchaContainers.forEach(function(container) {
63        // Obtém o ID único do captcha do atributo data-captcha-id
64        var captchaId = container.dataset.captchaId;
65
66        // Marcar o container como inicializado para evitar renderizações duplicadas
67        container.classList.add('recaptcha-initialized');
68
69        // Renderiza o reCAPTCHA no container
70        var renderedCaptchaId = grecaptcha.render(container, {
71          sitekey: G_RECAPTCHA_KEY,  // Chave do reCAPTCHA
72          'expired-callback': function() {
73            // Reseta o reCAPTCHA quando ele expirar
74            if (typeof GRECAPTCHA_CONTAINERS[captchaId] !== 'undefined') {
75              grecaptcha.reset(GRECAPTCHA_CONTAINERS[captchaId]);
76            }
77          },
78          'callback': function(response) {
79            // Pode adicionar lógica aqui para o callback
80            console.log('reCAPTCHA respondido para o captcha ID:', captchaId);
81          }
82        });
83
84        // Armazenar a instância do reCAPTCHA usando o data-captcha-id como chave
85        GRECAPTCHA_CONTAINERS[captchaId] = renderedCaptchaId;
86      });
87    }
88  }
89}
90
91function contentCheck(limitField,limit){
92	 if (limitField.value.length > (limit ? limit : 250)) {
93        limitField.value = limitField.value.substring(0, (limit ? limit : 250));
94    }
95}
96
97function renderMap() {
98    var mapsContainers = document.querySelectorAll('.map-container');
99
100    if (mapsContainers.length > 0) {
101        mapsContainers.forEach(function (mapContainer, mapIndex) {
102            // Two entry points call this: a second run would stack maps
103            if (mapContainer.dataset.mapReady) { return; }
104            mapContainer.dataset.mapReady = '1';
105
106            var mapId = mapContainer.dataset.mapId || mapIndex;
107            var centerLatLng = mapContainer.dataset.centerLatLng;
108            var zoom = parseInt(mapContainer.dataset.zoom, 10) || 14;
109            var useMarker = ['1', 'true'].indexOf(String(mapContainer.dataset.useMarker)) !== -1;
110            var displayDirectionsSelector = mapContainer.dataset.displayDirectionsSelector;
111
112            var lat = NaN;
113            var lng = NaN;
114
115            if (centerLatLng) {
116                var latLng = centerLatLng.split(',');
117
118                lat = parseFloat(String(latLng[0]).trim());
119                lng = parseFloat(String(latLng[1]).trim());
120            }
121
122            if (isNaN(lat) || isNaN(lng)) {
123                lat = -14.2392976;
124                lng = -53.1805017;
125                zoom = 4;
126                useMarker = false;
127            }
128
129            var initCoordinate = ol.proj.fromLonLat([lng, lat]);
130            var markers = [];
131
132            if (useMarker) {
133                markers.push(new ol.Feature(new ol.geom.Point(initCoordinate)));
134            }
135
136            var vectorSource = new ol.source.Vector({
137                features: markers,
138            });
139
140            var map = new ol.Map({
141                layers: [
142                    new ol.layer.Tile({
143                        source: new ol.source.OSM({
144                            attributions: '<span style="font-size: 12px;">&#169; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors.</span>',
145                        }),
146                    }),
147                    new ol.layer.Vector({
148                        source: vectorSource,
149                        style: new ol.style.Style({
150                            image: new ol.style.Icon({
151                                anchor: [18, 48],
152                                anchorXUnits: 'pixels',
153                                anchorYUnits: 'pixels',
154                                src: '/assets/img/marker-pin-single-user.png',
155                            }),
156                        }),
157                    }),
158                ],
159                target: mapContainer,
160                view: new ol.View({
161                    center: initCoordinate,
162                    zoom: zoom,
163                }),
164                interactions: ol.interaction.defaults({
165                    mouseWheelZoom: false,
166                }),
167            });
168
169            if (displayDirectionsSelector) {
170                document.querySelectorAll(displayDirectionsSelector + ' form').forEach(function (form) {
171                    form.addEventListener('submit', function (e) {
172                        e.stopPropagation();
173                        e.preventDefault();
174
175                        var field = form.querySelector('input[type=text]');
176                        var origin = (field ? field.value : '').replace(/\//g, ' ').trim().replace(/\s+/g, ' ');
177                        var originLocation = encodeURIComponent(origin).replace(/%20/g, '+');
178
179                        if (originLocation.length) {
180                            window.open('https://www.google.com/maps/dir/' + originLocation + '/' + centerLatLng, '_blank');
181                        }
182                    });
183                });
184            }
185
186            MAP_CONTAINERS[mapId] = {
187                map: map,
188                markersSource: vectorSource,
189            };
190        });
191    }
192}
193
194// Modules that refresh on their own: one endpoint, the markup goes to every
195// copy of the module on the page
196function brasFill(selector, html) {
197	document.querySelectorAll(selector).forEach(function (el) { el.innerHTML = html; });
198}
199
200function brasFetch(url, type, done) {
201	fetch(url, { credentials: 'same-origin' })
202		.then(function (response) { return response.ok ? (type === 'json' ? response.json() : response.text()) : null; })
203		.then(function (data) { if (data !== null) done(data); })
204		.catch(function () {});
205}
206
207// On air and host on air read the same answer: asking twice per page meant
208// two round trips for the same row
209var brasOnairWait = null;
210
211function brasOnair(id, done){
212	if(!brasOnairWait){
213		brasOnairWait = fetch("/current-data/" + id, { credentials: 'same-origin' })
214			.then(function (response) { return response.ok ? response.json() : null; })
215			.catch(function () { return null; });
216
217		setTimeout(function () { brasOnairWait = null; }, 30000);
218	}
219
220	brasOnairWait.then(function (data) { if (data) done(data); });
221}
222
223function getOnairData(id){
224	brasOnair(id, function(data){
225		brasFill('.onAir', (data.current.program ? '<div class="d-flex align-items-center mt-2"> <div class="flex-shrink-0"> <img src="'+(data.current.program_img ? data.current.program_img : (data.current.user_img ? data.current.user_img : '/assets/img/noavatar.jpg'))+'" class="current-img rounded" style="max-height: 80px; max-width: 80px"> </div> <div class="flex-grow-1 overflow-hidden ms-2"> <small>'+data.current.start_time+' - '+data.current.end_time+'</small> <h6 class="mb-0 mt-0 text-nowrap text-truncate fw-bold color2">'+data.current.program+'</h6> '+(data.current.user ? '<p class="text-nowrap text-truncate mb-0 color2"><small>' + T('with') + '</small> '+data.current.user+'</p>' : '')+' </div> </div>' : '<div class="mt-3 text-center bg-block rounded p-2">' + T('no_program') + '</div>'));
226	});
227}
228
229function getLocData(id){
230	brasOnair(id, function(data){
231		brasFill('.locOnline', (data.current.user ? '<div class="d-flex align-items-center mt-3"> <div class="flex-shrink-0"><div class="outer-circle border-broadcaster"> <div class="inner-circle color1"><img class="loc-img" src="'+(data.current.user_img ? data.current.user_img : '/assets/img/noavatar.jpg')+'"></div></div></div><div class="flex-grow-1 ms-2"><p class="mb-0 color3">' + T('online_now') + '</p><h5 class="mb-0 color2 ">'+data.current.user+'</h5></div></div>' : '<div class="mt-3 text-center bg-block rounded p-2">' + T('no_host') + '</div>'));
232	});
233}
234
235// Studio camera. It used to ride on Clappr, half a megabyte loaded through
236// three script tags printed inside the module: on a router navigation those
237// tags stop blocking, so the init ran before the library existed and the box
238// stayed empty. The stream is video only, so a muted <video> is enough, with
239// hls.js brought in only where the browser cannot read the playlist by itself.
240var brasHlsReady = null;
241
242function brasHlsLib() {
243	if (brasHlsReady) { return brasHlsReady; }
244
245	brasHlsReady = new Promise(function (done, fail) {
246		if (window.Hls) { done(); return; }
247
248		var tag = document.createElement("script");
249
250		tag.src = "/assets/js/hls.min.js";
251		tag.onload = done;
252		tag.onerror = fail;
253		document.head.appendChild(tag);
254	});
255
256	return brasHlsReady;
257}
258
259// Play, stop and fullscreen over the picture. The native controls would bring
260// a volume slider along, and this stream carries no sound at all.
261function brasCameraControls(box, video) {
262	var bar = document.createElement("div");
263	var play = document.createElement("button");
264	var full = document.createElement("button");
265
266	var icons = {
267		play: '<svg viewBox="0 0 24 24" aria-hidden="true">
267<path fill="currentColor" d="M8 5v14l11-7z"/></svg>',
268		stop: '<svg viewBox="0 0 24 24" aria-hidden="true"><rect fill="currentColor" x="5" y="5" width="14" height="14" rx="3"/></svg>',
269		full: '<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>'
270	};
271
272	bar.className = "camera-ctrl";
273	play.type = "button";
274	play.className = "camera-ctrl__btn";
275	full.type = "button";
276	full.className = "camera-ctrl__btn";
277	full.innerHTML = icons.full;
278	full.setAttribute("aria-label", T("cam_full") || "Tela cheia");
279
280	function paint() {
281		var on = !video.paused;
282
283		play.innerHTML = (on ? icons.stop : icons.play);
284		play.setAttribute("aria-label", (on ? T("cam_stop") : T("cam_play")) || "");
285		box.classList.toggle("is-playing", on);
286	}
287
288	play.addEventListener("click", function () {
289		if (video.paused) { video.play().catch(function () {}); return; }
290
291		video.pause();
292	});
293
294	full.addEventListener("click", function () {
295		var target = box.parentElement || box;
296
297		if (document.fullscreenElement) { document.exitFullscreen(); return; }
298		if (target.requestFullscreen) { target.requestFullscreen().catch(function () {}); }
299	});
300
301	video.addEventListener("play", paint);
302	video.addEventListener("pause", paint);
303
304	bar.appendChild(play);
305	bar.appendChild(full);
306	box.appendChild(bar);
307	paint();
308}
309
310function brasCamera(port, target) {
311	var box = document.getElementById(target);
312
313	if (!box || box.dataset.ready) { return; }
314
315	box.dataset.ready = "1";
316
317	var url = "https://brascam.brascast.com/brascam/" + port + "/playlist.m3u8";
318	var video = document.createElement("video");
319
320	video.className = "camera-video";
321	video.muted = true;
322	video.defaultMuted = true;
323	video.autoplay = true;
324	video.playsInline = true;
325	video.setAttribute("playsinline", "");
326	video.setAttribute("muted", "");
327	video.poster = "/assets/img/camera-online-bg.png";
328
329	box.appendChild(video);
330	brasCameraControls(box, video);
331
332	// Chrome answers "maybe" to a playlist it cannot actually read, so native
333	// playback is only trusted where the library has nothing to offer, which in
334	// practice means Safari and iOS
335
336	function nativo() {
337		if (!video.canPlayType("application/vnd.apple.mpegurl")) { box.dataset.ready = ""; return; }
338
339		video.src = url;
340		video.play().catch(function () {});
341	}
342
343	brasHlsLib().then(function () {
344		if (!window.Hls || !Hls.isSupported()) { nativo(); return; }
345
346		// Default settings hold three segments before the first frame, which on a
347		// studio camera is a long wait staring at the poster. One segment is
348		// enough to start, and the buffer stays short so it keeps up with live.
349		var hls = new Hls({
350			liveDurationInfinity: true,
351			liveSyncDurationCount: 1,
352			maxBufferLength: 6,
353			backBufferLength: 30,
354			manifestLoadingMaxRetry: 6,
355			levelLoadingMaxRetry: 6,
356			fragLoadingMaxRetry: 6
357		});
358
359		hls.loadSource(url);
360		hls.attachMedia(video);
361		hls.on(Hls.Events.MANIFEST_PARSED, function () { video.play().catch(function () {}); });
362
363		// The camera comes and goes: a broken pipe is picked up again instead of
364		// leaving the poster there forever
365		hls.on(Hls.Events.ERROR, function (event, data) {
366			if (!data.fatal) { return; }
367
368			if (data.type === Hls.ErrorTypes.MEDIA_ERROR) { hls.recoverMediaError(); return; }
369			if (data.type === Hls.ErrorTypes.NETWORK_ERROR) { window.setTimeout(function () { hls.startLoad(); }, 3000); return; }
370
371			hls.destroy();
372			box.dataset.ready = "";
373		});
374	}).catch(nativo);
375}
376
377function getHistory(limit = null){
378	brasFetch("/history"+(limit ? '/'+limit : ''), 'html', function(data){
379		brasFill('.module-23 .played-list', data);
380	});
381}
382
383
384var docCookies = {
385    getItem: function (sKey) {
386        if (!sKey) { return null; }
387        return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
388    },
389    setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
390        if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
391        var sExpires = "";
392        if (vEnd) {
393            switch (vEnd.constructor) {
394                case Number:
395                    sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
396                    break;
397                case String:
398                    sExpires = "; expires=" + vEnd;
399                    break;
400                case Date:
401                    sExpires = "; expires=" + vEnd.toUTCString();
402                    break;
403            }
404        }
405        document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
406        return true;
407    },
408    removeItem: function (sKey, sPath, sDomain) {
409        if (!this.hasItem(sKey)) { return false; }
410        document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
411        return true;
412    },
413    hasItem: function (sKey) {
414        if (!sKey) { return false; }
415        return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
416    },
417    keys: function () {
418        var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
419        for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
420        return aKeys;
421    }
422};
423document.addEventListener("DOMContentLoaded", function () { document.body.addEventListener("click", function(event) { if (event.target.closest(".
423navbar-toggler")) { const navbarCollapse = document.querySelector(".navbar-collapse"); if (navbarCollapse) { if (!navbarCollapse.classList.contains("show")) { navbarCollapse.classList.add("show"); } else { navbarCollapse.classList.remove("show"); } } } }); 
424
425 const toggleButton = document.querySelector('.navbar-togPost');
426    const menuList = document.getElementById('menuList');
427
428    if (toggleButton && menuList) {
429        toggleButton.addEventListener('click', function () {
430            menuList.classList.toggle('d-none'); // mostra ou esconde
431        });
432    }  
433
434var cookieAlert = document.querySelector("#cookie-banner-lgpd"); if (cookieAlert) { cookieAlert.offsetHeight; var acceptCookies = document.querySelector(".button-accept-terms"); acceptCookies.addEventListener("click", function () { docCookies.setItem('cookie_consent', (new Date()).getTime()); cookieAlert.classList.remove("d-flex"); cookieAlert.classList.add("d-none"); }); } });

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.