En movimiento

Machine Learning, la tecnología que está revolucionando la distribución farmacéutica

Machine Learning, la tecnología que está revolucionando la distribución farmacéutica

El aprendizaje automático permite analizar grandes volúmenes de datos para anticipar la demanda de medicamentos y optimizar la logística farmacéutica.

Machine Learning, la tecnología que está revolucionando la distribución farmacéutica

Machine Learning, la tecnología que está revolucionando la distribución farmacéutica

El aprendizaje automático permite analizar grandes volúmenes de datos para anticipar la demanda de medicamentos y optimizar la logística farmacéutica.

distribucion

¿Cuál es el valor de la distribución farmacéutica de gama completa en la protección de la salud pública?

A través de las farmacias comunitarias, la distribución mayorista garantiza el acceso a la población de todos los medicamentos y productos sanitarios.

Blockchain o cómo conseguir una distribución farmacéutica más segura y transparente

Blockchain o cómo conseguir una distribución farmacéutica más segura y transparente

Esta tecnología se sigue extendiendo en el sector gracias a los beneficios que presenta; entre otros, destaca la mayor seguridad para el paciente y un mejor cumplimiento normativo.

seguridad-cadena-suministro

La colaboración, fundamental para garantizar la seguridad de la cadena de suministro de medicamentos frente a crisis

PharmaSupply 2025, organizada por la GIRP, apuntó a la necesidad de cooperar en todos los niveles: planificación conjunta, ciberseguridad y regulación armonizada.

Une erreur s'est produite lors du traitement du modèle.
The following has evaluated to null or missing:
==> renderer.getArticle  [in template "20155#20195#187080686" at line 14, column 59]

----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: #assign journalArticle = renderer.get...  [in template "20155#20195#187080686" at line 14, column 33]
----
1<#if entries?has_content> 
2	<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") /> 
3 
4	<#assign listaContenidos = [] /> 
5	<#assign listaRenderersContenidos = [] /> 
6	<#assign portletDisplay = themeDisplay.getPortletDisplay() /> 
7	<#assign portletId = portletDisplay.getId() /> 
8	<#assign templateKey = "110969" /> 
9		 
10		<div class="slickCarousel${portletId} CuadriculaWidth carouselCards"> 
11			<#list entries as curEntry> 
12				<#assign renderer = curEntry.getAssetRenderer() /> 
13				<#assign className = renderer.getClassName() />  
14				<#assign journalArticle = renderer.getArticle() /> 
15				<#assign listaContenidos = listaContenidos + [journalArticle] /> 
16				<#assign listaRenderersContenidos = listaRenderersContenidos + [renderer] /> 
17			</#list> 
18				 
19			<#list listaContenidos as contenido> 
20				<div class="slick-carousel-item">			 
21          ${journalArticleLocalService.getArticleContent(contenido, templateKey, "VIEW", locale.toString(), null, themeDisplay)}		 
22				</div> 
23			</#list> 
24		</div> 
25 
26	<script type="text/javascript"> 
27	    $(document).ready(function(){ 
28		    $(".slickCarousel${portletId}").slick({ 
29		    	dots: false, 
30					infinite: true, 
31					speed: 300, 
32					slidesToShow: 3, 
33					prevArrow: '<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button"><svg width="18" height="33" viewBox="0 0 18 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M16.3058 30.5373C16.7469 31.0237 16.7027 31.7689 16.2071 32.2017C15.7665 32.5865 15.1176 32.595 14.669 32.2505L14.511 32.1049L1.30393 17.5431C0.953945 17.1573 0.905707 16.6011 1.16181 16.1682L1.29022 15.991L14.4973 0.910537C14.9297 0.416751 15.6882 0.360467 16.1914 0.784824C16.6387 1.16203 16.7337 1.79203 16.4456 2.27418L16.3195 2.44727L3.79855 16.745L16.3058 30.5373Z" fill="#183657" stroke="#183657"/></svg></button>', 
34          nextArrow: '<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button"><svg width="16" height="33" viewBox="0 0 16 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.8499 16.0019C15.1587 16.3905 15.1933 16.9358 14.9558 17.3592L14.8373 17.5324L2.85008 32.0941C2.44541 32.5857 1.73961 32.6381 1.27364 32.2112C0.859439 31.8317 0.774151 31.2012 1.04453 30.7206L1.16264 30.5481L12.5252 16.745L1.1501 2.4364C0.797606 1.99294 0.807338 1.35616 1.14598 0.926309L1.28833 0.775596C1.70868 0.403731 2.3123 0.413998 2.71976 0.771254L2.86262 0.921421L14.8499 16.0019Z" fill="#183657" stroke="#183657"/></svg></button>', 
35                 
36					responsive: [ 
37
38					breakpoint: 600, 
39					settings: { 
40						slidesToShow: 2, 
41						slidesToScroll: 1, 
42						arrows: false, 
43						dots: true, 
44
45					}, 
46
47					breakpoint: 480, 
48					settings: { 
49						slidesToShow: 1, 
50						slidesToScroll: 1, 
51						arrows: false, 
52						dots: true, 
53
54
55
56		    }); 
57	    }); 
58    </script> 
59	</#if> 
Une erreur s'est produite lors du traitement du modèle.
The following has evaluated to null or missing:
==> renderer.getArticle  [in template "20155#20195#187080686" at line 14, column 59]

----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: #assign journalArticle = renderer.get...  [in template "20155#20195#187080686" at line 14, column 33]
----
1<#if entries?has_content> 
2	<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") /> 
3 
4	<#assign listaContenidos = [] /> 
5	<#assign listaRenderersContenidos = [] /> 
6	<#assign portletDisplay = themeDisplay.getPortletDisplay() /> 
7	<#assign portletId = portletDisplay.getId() /> 
8	<#assign templateKey = "110969" /> 
9		 
10		<div class="slickCarousel${portletId} CuadriculaWidth carouselCards"> 
11			<#list entries as curEntry> 
12				<#assign renderer = curEntry.getAssetRenderer() /> 
13				<#assign className = renderer.getClassName() />  
14				<#assign journalArticle = renderer.getArticle() /> 
15				<#assign listaContenidos = listaContenidos + [journalArticle] /> 
16				<#assign listaRenderersContenidos = listaRenderersContenidos + [renderer] /> 
17			</#list> 
18				 
19			<#list listaContenidos as contenido> 
20				<div class="slick-carousel-item">			 
21          ${journalArticleLocalService.getArticleContent(contenido, templateKey, "VIEW", locale.toString(), null, themeDisplay)}		 
22				</div> 
23			</#list> 
24		</div> 
25 
26	<script type="text/javascript"> 
27	    $(document).ready(function(){ 
28		    $(".slickCarousel${portletId}").slick({ 
29		    	dots: false, 
30					infinite: true, 
31					speed: 300, 
32					slidesToShow: 3, 
33					prevArrow: '<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button"><svg width="18" height="33" viewBox="0 0 18 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M16.3058 30.5373C16.7469 31.0237 16.7027 31.7689 16.2071 32.2017C15.7665 32.5865 15.1176 32.595 14.669 32.2505L14.511 32.1049L1.30393 17.5431C0.953945 17.1573 0.905707 16.6011 1.16181 16.1682L1.29022 15.991L14.4973 0.910537C14.9297 0.416751 15.6882 0.360467 16.1914 0.784824C16.6387 1.16203 16.7337 1.79203 16.4456 2.27418L16.3195 2.44727L3.79855 16.745L16.3058 30.5373Z" fill="#183657" stroke="#183657"/></svg></button>', 
34          nextArrow: '<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button"><svg width="16" height="33" viewBox="0 0 16 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.8499 16.0019C15.1587 16.3905 15.1933 16.9358 14.9558 17.3592L14.8373 17.5324L2.85008 32.0941C2.44541 32.5857 1.73961 32.6381 1.27364 32.2112C0.859439 31.8317 0.774151 31.2012 1.04453 30.7206L1.16264 30.5481L12.5252 16.745L1.1501 2.4364C0.797606 1.99294 0.807338 1.35616 1.14598 0.926309L1.28833 0.775596C1.70868 0.403731 2.3123 0.413998 2.71976 0.771254L2.86262 0.921421L14.8499 16.0019Z" fill="#183657" stroke="#183657"/></svg></button>', 
35                 
36					responsive: [ 
37
38					breakpoint: 600, 
39					settings: { 
40						slidesToShow: 2, 
41						slidesToScroll: 1, 
42						arrows: false, 
43						dots: true, 
44
45					}, 
46
47					breakpoint: 480, 
48					settings: { 
49						slidesToShow: 1, 
50						slidesToScroll: 1, 
51						arrows: false, 
52						dots: true, 
53
54
55
56		    }); 
57	    }); 
58    </script> 
59	</#if> 
Une erreur s'est produite lors du traitement du modèle.
The following has evaluated to null or missing:
==> renderer.getArticle  [in template "20155#20195#187080686" at line 14, column 59]

----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: #assign journalArticle = renderer.get...  [in template "20155#20195#187080686" at line 14, column 33]
----
1<#if entries?has_content> 
2	<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") /> 
3 
4	<#assign listaContenidos = [] /> 
5	<#assign listaRenderersContenidos = [] /> 
6	<#assign portletDisplay = themeDisplay.getPortletDisplay() /> 
7	<#assign portletId = portletDisplay.getId() /> 
8	<#assign templateKey = "110969" /> 
9		 
10		<div class="slickCarousel${portletId} CuadriculaWidth carouselCards"> 
11			<#list entries as curEntry> 
12				<#assign renderer = curEntry.getAssetRenderer() /> 
13				<#assign className = renderer.getClassName() />  
14				<#assign journalArticle = renderer.getArticle() /> 
15				<#assign listaContenidos = listaContenidos + [journalArticle] /> 
16				<#assign listaRenderersContenidos = listaRenderersContenidos + [renderer] /> 
17			</#list> 
18				 
19			<#list listaContenidos as contenido> 
20				<div class="slick-carousel-item">			 
21          ${journalArticleLocalService.getArticleContent(contenido, templateKey, "VIEW", locale.toString(), null, themeDisplay)}		 
22				</div> 
23			</#list> 
24		</div> 
25 
26	<script type="text/javascript"> 
27	    $(document).ready(function(){ 
28		    $(".slickCarousel${portletId}").slick({ 
29		    	dots: false, 
30					infinite: true, 
31					speed: 300, 
32					slidesToShow: 3, 
33					prevArrow: '<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button"><svg width="18" height="33" viewBox="0 0 18 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M16.3058 30.5373C16.7469 31.0237 16.7027 31.7689 16.2071 32.2017C15.7665 32.5865 15.1176 32.595 14.669 32.2505L14.511 32.1049L1.30393 17.5431C0.953945 17.1573 0.905707 16.6011 1.16181 16.1682L1.29022 15.991L14.4973 0.910537C14.9297 0.416751 15.6882 0.360467 16.1914 0.784824C16.6387 1.16203 16.7337 1.79203 16.4456 2.27418L16.3195 2.44727L3.79855 16.745L16.3058 30.5373Z" fill="#183657" stroke="#183657"/></svg></button>', 
34          nextArrow: '<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button"><svg width="16" height="33" viewBox="0 0 16 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.8499 16.0019C15.1587 16.3905 15.1933 16.9358 14.9558 17.3592L14.8373 17.5324L2.85008 32.0941C2.44541 32.5857 1.73961 32.6381 1.27364 32.2112C0.859439 31.8317 0.774151 31.2012 1.04453 30.7206L1.16264 30.5481L12.5252 16.745L1.1501 2.4364C0.797606 1.99294 0.807338 1.35616 1.14598 0.926309L1.28833 0.775596C1.70868 0.403731 2.3123 0.413998 2.71976 0.771254L2.86262 0.921421L14.8499 16.0019Z" fill="#183657" stroke="#183657"/></svg></button>', 
35                 
36					responsive: [ 
37
38					breakpoint: 600, 
39					settings: { 
40						slidesToShow: 2, 
41						slidesToScroll: 1, 
42						arrows: false, 
43						dots: true, 
44
45					}, 
46
47					breakpoint: 480, 
48					settings: { 
49						slidesToShow: 1, 
50						slidesToScroll: 1, 
51						arrows: false, 
52						dots: true, 
53
54
55
56		    }); 
57	    }); 
58    </script> 
59	</#if> 
Une erreur s'est produite lors du traitement du modèle.
The following has evaluated to null or missing:
==> renderer.getArticle  [in template "20155#20195#187080686" at line 14, column 59]

----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: #assign journalArticle = renderer.get...  [in template "20155#20195#187080686" at line 14, column 33]
----
1<#if entries?has_content> 
2	<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") /> 
3 
4	<#assign listaContenidos = [] /> 
5	<#assign listaRenderersContenidos = [] /> 
6	<#assign portletDisplay = themeDisplay.getPortletDisplay() /> 
7	<#assign portletId = portletDisplay.getId() /> 
8	<#assign templateKey = "110969" /> 
9		 
10		<div class="slickCarousel${portletId} CuadriculaWidth carouselCards"> 
11			<#list entries as curEntry> 
12				<#assign renderer = curEntry.getAssetRenderer() /> 
13				<#assign className = renderer.getClassName() />  
14				<#assign journalArticle = renderer.getArticle() /> 
15				<#assign listaContenidos = listaContenidos + [journalArticle] /> 
16				<#assign listaRenderersContenidos = listaRenderersContenidos + [renderer] /> 
17			</#list> 
18				 
19			<#list listaContenidos as contenido> 
20				<div class="slick-carousel-item">			 
21          ${journalArticleLocalService.getArticleContent(contenido, templateKey, "VIEW", locale.toString(), null, themeDisplay)}		 
22				</div> 
23			</#list> 
24		</div> 
25 
26	<script type="text/javascript"> 
27	    $(document).ready(function(){ 
28		    $(".slickCarousel${portletId}").slick({ 
29		    	dots: false, 
30					infinite: true, 
31					speed: 300, 
32					slidesToShow: 3, 
33					prevArrow: '<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button"><svg width="18" height="33" viewBox="0 0 18 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M16.3058 30.5373C16.7469 31.0237 16.7027 31.7689 16.2071 32.2017C15.7665 32.5865 15.1176 32.595 14.669 32.2505L14.511 32.1049L1.30393 17.5431C0.953945 17.1573 0.905707 16.6011 1.16181 16.1682L1.29022 15.991L14.4973 0.910537C14.9297 0.416751 15.6882 0.360467 16.1914 0.784824C16.6387 1.16203 16.7337 1.79203 16.4456 2.27418L16.3195 2.44727L3.79855 16.745L16.3058 30.5373Z" fill="#183657" stroke="#183657"/></svg></button>', 
34          nextArrow: '<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button"><svg width="16" height="33" viewBox="0 0 16 33" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.8499 16.0019C15.1587 16.3905 15.1933 16.9358 14.9558 17.3592L14.8373 17.5324L2.85008 32.0941C2.44541 32.5857 1.73961 32.6381 1.27364 32.2112C0.859439 31.8317 0.774151 31.2012 1.04453 30.7206L1.16264 30.5481L12.5252 16.745L1.1501 2.4364C0.797606 1.99294 0.807338 1.35616 1.14598 0.926309L1.28833 0.775596C1.70868 0.403731 2.3123 0.413998 2.71976 0.771254L2.86262 0.921421L14.8499 16.0019Z" fill="#183657" stroke="#183657"/></svg></button>', 
35                 
36					responsive: [ 
37
38					breakpoint: 600, 
39					settings: { 
40						slidesToShow: 2, 
41						slidesToScroll: 1, 
42						arrows: false, 
43						dots: true, 
44
45					}, 
46
47					breakpoint: 480, 
48					settings: { 
49						slidesToShow: 1, 
50						slidesToScroll: 1, 
51						arrows: false, 
52						dots: true, 
53
54
55
56		    }); 
57	    }); 
58    </script> 
59	</#if> 
Une erreur s'est produite lors du traitement du modèle.
Java method "com.sun.proxy.$Proxy868.getDDMStructure(long)" threw an exception when invoked on com.sun.proxy.$Proxy868 object "com.liferay.dynamic.data.mapping.service.impl.DDMStructureLocalServiceImpl@a96256e"; see cause exception in the Java stack trace.

----
FTL stack trace ("~" means nesting-related):
	- Failed at: #assign structure = ddmStructureLocal...  [in template "20155#20195#187096557" at line 527, column 1]
----
1<script src="https://maps.google.com/maps/api/js?v=3&libraries=geometry,places&key=AIzaSyCY8E-ymOZcQVzPlN0WREHafmMkAQmsHhY" async defer></script> 
2 
3<script type="text/javascript"> 
4	 
5	 
6     
7    window.onload = function() { 
8      // Se cargan las oficinas 
9      initLoad(); 
10      loadCentros(); 
11    }; 
12	 
13		$( document ).ready(function() { 
14      //console.log("cambia windows"); 
15      initLoad(); 
16			loadCentros(); 
17    }); 
18     
19    $( window ).resize(function() { 
20      //console.log("cambia windows"); 
21      initLoad(); 
22    }); 
23     
24    // Variable que guarda los datos de los centros 
25    var centros = []; 
26     
27    // Variable que guarda el html de los resultados encontrados 
28    var side_bar_html = ""; 
29 
30    // Array para guardar todos los marcadores 
31    var gmarkers = []; 
32    var gmarkersshow = []; 
33 
34    // Variables globales 
35    var map; 
36    var circle = null; 
37    var geocoder; 
38    var busquedaRealizada = false; 
39    var marker_you; 
40    var userMarker; 
41    var directionsService; 
42    var directionsDisplay; 
43    var infowindow; 
44    var defaultCoordinates = {lat: 40.4168508 ,lng:-3.7031067}; 
45     
46    // Variable global para saber si se tiene o no geolocalizacion 
47    var geoActive = true; 
48     
49    //Variable para guardar objeto scrollbar 
50    var scrollbar; 
51 
52    //Genera arrays de centros 
53    function addCentros (contador,nombre,direccion,latitud,longitud,enlace,telefono){ 
54        var entryLocation = [nombre,direccion,latitud,longitud,enlace,telefono]; 
55        centros[contador] = entryLocation; 
56
57 
58    //Funcion que muestra error por consola si no se puede utilizar la geolocalizacion del usuario 
59    function showError() { 
60        //console.log("Location can't be found"); 
61        geoActive = false; 
62         
63        if(directionsService == null || directionsService == "undefined"){ 
64            directionsService = new google.maps.DirectionsService(); 
65
66        if(directionsDisplay == null || directionsDisplay == "undefined"){ 
67            directionsDisplay = new google.maps.DirectionsRenderer(); 
68
69        if(infowindow == null || infowindow == "undefined"){ 
70            infowindow = new google.maps.InfoWindow({  
71                size: new google.maps.Size(150,50) 
72            }); 
73
74        map = new google.maps.Map(document.getElementById("map_canvas"), { 
75            zoom: 8, 
76            center: {lat: 40.4169473, lng: -3.7079059} 
77             
78        }); 
79         
80        // Crea evento para sacar infoWindows 
81        google.maps.event.addListener(map, 'click', function() { 
82            infowindow.close(); 
83        }); 
84     
85        // Funcion autocompletar para el campo de texto 
86        var autocomplete = new google.maps.places.Autocomplete(document.getElementById('address')); 
87        autocomplete.bindTo('bounds', map); 
88         
89        searchRadius(defaultCoordinates); 
90     
91        // Se hace focus en el campo de texto de la direccion una vez que todo este cargado 
92        $(".js_input_dir").select(); 
93
94     
95    // Funcion para crear marcadores 
96    function createMarker(latlng, name, html_infow, html_res, indice) { 
97        // Contenido del infoWindow 
98        var contentString = html_infow; 
99 
100        // Marcador 
101        var marker = new google.maps.Marker({ 
102            icon: '/o/mundo-farmaceutico-theme/images/icons/ovalado_rojo.png', 
103            position: latlng, 
104            title: name, 
105            //  zIndex: Math.round(latlng.lat()*-100000)<<5, 
106            zIndex: Math.round(latlng.lat*-100000)<<5, 
107            info: html_res, 
108            ind: indice 
109        }); 
110     
111        // Evento para lanzar la infoWdindows al hacer click sobre el marcador 
112        google.maps.event.addListener(marker, 'click', function() { 
113            infowindow.setContent(contentString);  
114            infowindow.open(map,marker); 
115        }); 
116         
117        // Guarda el marcador en el array global 
118        gmarkers.push(marker); 
119
120     
121    // Funcion initLoad 
122    function initLoad(){ 
123        //console.log("Entramos en la funcion del callback"); 
124        // INICIALIZACION 
125        geocoder = new google.maps.Geocoder(); 
126        if (navigator.geolocation) { 
127            var options = { 
128                enableHighAccuracy: true, 
129                maximumAge: 0 
130            }						 
131            navigator.geolocation.getCurrentPosition(initializeMaps, showError, options); 
132
133        else { 
134            //console.log("El navegador no soporta geolocalización"); 
135
136        // FIN INICIALIZACION 
137
138 
139    // Funcion ejecutada al CARGAR LA PáGINA 
140    function initializeMaps(userPosition) { 
141        // Define las opciones del mapa 
142        userMarker = userPosition; 
143 
144				var myOptions = { 
145            zoom: 8, 
146            center: new google.maps.LatLng(userPosition.coords.latitude, userPosition.coords.longitude), 
147            mapTypeControl: true, 
148            mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}, 
149            navigationControl: true, 
150            mapTypeId: google.maps.MapTypeId.ROADMAP 
151        }; 
152         
153        // Define el mapa 
154        map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 
155     
156        // Crea evento para sacar infoWindows 
157        google.maps.event.addListener(map, 'click', function() { 
158            infowindow.close(); 
159        }); 
160         
161        if(directionsService == null || directionsService == "undefined"){ 
162            directionsService = new google.maps.DirectionsService(); 
163
164        if(directionsDisplay == null || directionsDisplay == "undefined"){ 
165            directionsDisplay = new google.maps.DirectionsRenderer(); 
166
167        if(infowindow == null || infowindow == "undefined"){ 
168            infowindow = new google.maps.InfoWindow({  
169                size: new google.maps.Size(150,50) 
170            }); 
171
172     
173        // Funcion autocompletar para el campo de texto 
174        var autocomplete = new google.maps.places.Autocomplete(document.getElementById('address')); 
175        autocomplete.bindTo('bounds', map); 
176      
177        //se crea el marcador de posición del usuario 
178        //marcador = new google.maps.Marker({   
179        //    position: new google.maps.LatLng(userPosition.coords.latitude, userPosition.coords.longitude), 
180        //    icon: 'http://opendatacon.org/wp-content/uploads/2016/05/Farm-Fresh_star.png', 
181        //    title: "Usted está aquí", 
182        //    map: map 
183        //}); 
184         
185        searchRadius(); 
186 
187        // Se hace focus en el campo de texto de la direccion una vez que todo este cargado 
188        $(".js_input_dir").select(); 
189
190     
191    function searchRadius(coordinates){ 
192        //se saca la dirección del usuario según sus coordenadas (si no se encuentra se fija la puerta de sol como punto de partida) 
193        var userPosic = 'Plaza Puerta del Sol, 28013 Madrid'; 
194        var latlng; 
195         
196        if(coordinates != null){ 
197            latlng = coordinates; 
198        }else{ 
199            var input = (userMarker.coords.latitude+","+userMarker.coords.longitude); 
200            var latlngStr = input.split(',', 2); 
201            latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])}; 
202
203         
204        geocoder.geocode({'location': latlng}, function(results, status) { 
205            if (status === google.maps.GeocoderStatus.OK) { 
206                    //console.log(results[0].formatted_address); 
207                if (results[0]) { 
208                    userPosic = results[0].formatted_address; 
209                } else { 
210                    window.alert('No results found'); 
211
212            } else { 
213                window.alert('Geocoder failed due to: ' + status); 
214
215 
216            //se buscan los centros que estón a menos de 6km del usuario 
217            var searchAddress = userPosic; 
218            var radVal = 6; 
219            var radius = 600000; 
220            $(".rad_err_msg").hide(); 
221                if(searchAddress != null && searchAddress != ""){ 
222                    // Ejecutamos con timeOut de 200ms para evitar el queryLimit de google 
223                    setTimeout(function(){ 
224                        $(".div_lista").fadeIn(); 
225                        exe_code_address(searchAddress, radius); 
226                    }, 200); 
227
228        }); 
229         
230
231     
232    // Funcion para procesar los centros 
233    function loadCentros(){ 
234        // Para cada centro se genera un marcador y una infoWindow 
235        for(var i = 0; i < centros.length; i++){ 
236            var centroName = centros[i][0]; 
237            var centroAddress = centros[i][1]; 
238            var centroLatitud = centros[i][2]; 
239            var centroLongitud = centros[i][3]; 
240            var enlaceAWeb = centros[i][4]; 
241            var centroTlf = centros[i][5]; 
242 
243            var latlng = {lat: parseFloat(centroLatitud), lng: parseFloat(centroLongitud)}; 
244             
245            var urlCentro = ""; 
246            if("" != enlaceAWeb && null != enlaceAWeb){ 
247                urlCentro = '<div class="center_url">'+ 
248                            '<a class="btn btn-primary" href="'+ enlaceAWeb +'" target="_blank"> Sitio web </a>'+ 
249                        '</div>'; 
250
251             
252            var html_inf =  
253                '<div id="content_gmap">'+ 
254                    '<div class="center_data_wrapper" onclick="javascript:myclick({index})">'+ 
255                        '<div class="evo-form__text-info office_data">'+ 
256                            '<p class="center_title">'+centroName+'</p>'+ 
257                            '<p class="center_address">'+centroAddress+'</p>'+ 
258                            '<p class="center_tlf">'+centroTlf+'</p>'+ 
259                        '</div>'+ 
260                    '</div>'+ 
261                    //'<div class="howToGo">'+ 
262                    //    '<a class="btn btn-primary" href="javascript:void(0);" onclick="arriveTo(\'' + centroAddress + '\');"> Cómo llegar </a>'+ 
263                    //'</div>'+ 
264                    urlCentro + 
265                '</div>'; 
266                 
267           var html_res =  
268               '<div id="content_gmap">'+ 
269                    '<div class="center_data_wrapper" onclick="javascript:myclick({index})">'+ 
270                        '<div class="center_data">'+ 
271                            '<p class="center_title">'+centroName+'</p>'+ 
272                            '<p class="center_address">'+centroAddress+'</p>'+ 
273                            '<p class="center_tlf">'+centroTlf+'</p>'+ 
274                        '</div>'+ 
275                    '</div>'+ 
276                    //'<div class="howToGo">'+ 
277                    //    '<a class="btn btn-primary" href="javascript:void(0);" onclick="arriveTo(\'' + centroAddress + '\');"> Cómo llegar </a>'+ 
278                    //'</div>'+ 
279                    urlCentro + 
280                '</div>'; 
281            //Se crea el marcador en las coordenadas de los centros 
282            var marker = createMarker(latlng, centroName, html_inf, html_res, i); 
283
284
285 
286 
287    var marcador; 
288    // Funcion para atender la direccion introducida en el formulario 
289    function codeAddress() { 
290        //se crea el marcador de posición del usuario con datos por defecto 
291        var latitude = defaultCoordinates.lat; 
292        var longitude = defaultCoordinates.lng; 
293         
294        if(userMarker != undefined){ 
295            latitude = userMarker.coords.latitude; 
296            longitude = userMarker.coords.longitude; 
297
298         
299        marcador = new google.maps.Marker({   
300            position: new google.maps.LatLng(latitude, longitude), 
301            icon: "/o/mundo-farmaceutico-theme/images/icons/pin-position.png", 
302            title: "Usted está aquí", 
303            map: map 
304        }); 
305         
306        //Se resetea el "como llegar",las indicaciones y se cierran la infowindow que hubiese abierta 
307        if(directionsDisplay != null){ 
308            directionsDisplay.setMap(null); 
309
310        $("#map_indications").html(""); 
311          
312        if(infowindow)infowindow.close(); 
313        var searchAddress = $("#address").val(); 
314        var radVal = $("#radius").val(); 
315        var radius = parseInt($("#radius").val(), 10)*1000; 
316         
317        if(radVal > 0 && radVal <= 500){ 
318            $(".rad_err_msg").hide(); 
319            if(searchAddress != null && searchAddress != ""){ 
320                // Ejecutamos con timeOut de 200ms para evitar el queryLimit de google 
321                setTimeout(function(){ 
322                    $(".div_lista").fadeIn(); 
323                    exe_code_address(searchAddress, radius); 
324                }, 200); 
325
326        }else{ 
327            $(".rad_err_msg").show(); 
328
329
330     
331    function exe_code_address(searchAddress, radius){ 
332        //  Flag de busqueda realizada para evento del input de radio 
333        busquedaRealizada = true; 
334         
335        // El marcador de la posicion buscada se reinicia en cada busqueda 
336        if(marker_you != null){ 
337            marker_you.setMap(null); 
338
339         
340        // Se situa un marcador en el mapa con los datos recogidos 
341        geocoder.geocode({ 'address': searchAddress}, function(results, status) { 
342            if (status == google.maps.GeocoderStatus.OK) { 
343                map.setCenter(results[0].geometry.location); 
344                map.setZoom(8); 
345                var searchCenter = results[0].geometry.location; 
346                /* 
347                var searchAddressComponents = results[0].address_components; 
348                var searchPostalCode = ""; 
349                var searchCity = ""; 
350 
351                $.each(searchAddressComponents, function(){ 
352                    if(this.types[0]=="postal_code"){ 
353                        searchPostalCode=this.short_name; 
354                    } else if (this.types[0]=="locality"){ 
355                        searchCity = this.short_name; 
356
357                }); 
358 
359                // Codigo para enviar a analytics . si hay psotal code se enva CP, si no city 
360                var titleBusqueda=searchPostalCode; 
361                if (titleBusqueda == ""){ 
362                    titleBusqueda=searchCity; 
363
364                ga('send', 'event', 'tCuida', 'busqueda_farmacias', titleBusqueda,{ 'dimension1': 'tCuida' }); 
365                */ 
366                //...... 
367 
368                marker_you = new google.maps.Marker({ 
369                    map: map, 
370                    position: results[0].geometry.location, 
371                    icon: "/o/mundo-farmaceutico-theme/images/icons/pin-position.png", 
372                }); 
373                 
374                // Se crea un circulo con el radio provisto en el formulario 
375                if (circle) circle.setMap(null); 
376                circle = new google.maps.Circle({ 
377                    center:searchCenter, 
378                    radius: radius, 
379                    fillColor: "#999", 
380                    strokeWeight: 1, 
381                    fillOpacity: 0.2, 
382                    map: map 
383                }); 
384                 
385                // Se reinicia la lista de resultados 
386                side_bar_html = ""; 
387                gmarkersshow = []; 
388                 
389                var bounds = new google.maps.LatLngBounds(); 
390                var foundMarkers = 0; 
391                 
392                //Añadimos el marker del sitio buscado al bounds 
393                bounds.extend(marker_you.getPosition()); 
394                 
395                // Se pintan en la lista todos los resultados 
396                for(var i = 0; i < gmarkers.length; i++){ 
397                    if (google.maps.geometry.spherical.computeDistanceBetween(gmarkers[i].getPosition(),searchCenter) < radius) { 
398                        bounds.extend(gmarkers[i].getPosition()); //Se anade la posicion de todos los markers para expandir la vista y que salgan todos en el mapa 
399                        gmarkers[i].setMap(map); 
400                        var distanceToCenter = google.maps.geometry.spherical.computeDistanceBetween(gmarkers[i].getPosition(),searchCenter); 
401                        gmarkersshow.push({marker: gmarkers[i], dist: distanceToCenter}); 
402                        foundMarkers++; 
403                    }else{ 
404                        gmarkers[i].setMap(null); 
405
406
407                 
408                // Se ordena el array de maracadores visibles por distancia 
409                gmarkersshow = gmarkersshow.sort(function(a,b){return a.dist - b.dist;}); 
410                 
411                // Se pintan en la lista todos los resultados ordenados por distancia 
412                var distance; 
413                side_bar_html +='<div class="info_container">'; 
414                for(var i = 0; i < gmarkersshow.length; i++){ 
415                    distance = round((gmarkersshow[i].dist / 1000), 2); 
416                    side_bar_html += '<div class="info_fcia_side_bar div_side_bar_' + i + '">'; 
417                    side_bar_html += '<div class="info_fcia_distance"><span class="text-base">' + distance + ' km.</span></div>'; 
418                    side_bar_html += (gmarkersshow[i].marker.info).replace("{index}", i); 
419                    side_bar_html += '</div>'; 
420
421                side_bar_html +='</div>'; 
422                // Si hay resultados que cumplan el criterio del radio, se anaden a la lista 
423                if(foundMarkers > 0){ 
424                    if(foundMarkers == 1){ 
425                        side_bar_html = "<div class=\"titulosidebar\"><p class=\"title_results_gmaps\"><strong>" + foundMarkers + "</strong> resultado encontrado:</p></div>" + side_bar_html; 
426                    }else{ 
427                        side_bar_html = "<div class=\"titulosidebar\"><p class=\"title_results_gmaps\"><strong>" + foundMarkers + "</strong> resultados encontrados:</p></div>" + side_bar_html; 
428
429                }else{ 
430                    side_bar_html = "<div class=\"p_aviso_side_bar\"><p class=\"evo-form__text-info js_result_no_found\">No se han encontrado resultados. Por favor, busca en otro lugar o amplía el radio de búsqueda.</p></div>"; 
431
432 
433                // Coloca la lista en el sitio que le corresponde 
434                document.getElementById("side_bar").innerHTML = side_bar_html; 
435                if (foundMarkers > 0) { 
436                    map.fitBounds(bounds); 
437                } else{ 
438                    map.fitBounds(circle.getBounds()); 
439
440
441            $(".info_container").mCustomScrollbar({ 
442                axis:"y" 
443            }); 
444        }); 
445
446     
447    // Metodo para redondear a los decimales 
448    function round(value, decimals) { 
449        return Number(Math.round(value+'e'+decimals)+'e-'+decimals); 
450
451     
452    // Evento para lanzar la infoWindow al clickar sobre el marcador 
453    function myclick(i) { 
454        google.maps.event.trigger(gmarkersshow[i].marker, "click"); 
455
456     
457    //Funcion para utilizar la api de google maps de "cómo llegar" 
458    function arriveTo(address) { 
459        var request; 
460         
461        //eliminamos el marcador de la posición del usuario si se muestra 
462        if (marcador != null  && marcador!=""){ 
463            marcador.setMap(null); 
464
465         
466        //se saca la dirección del usuario según sus coordenadas (si no se encuentra se fija la puerta de sol como punto de partida) 
467        var userPosic = 'Plaza Puerta del Sol, 28013 Madrid'; 
468        var latlng; 
469         
470        if(userMarker == null){ 
471            latlng = defaultCoordinates; 
472        }else{ 
473            var input = (userMarker.coords.latitude+","+userMarker.coords.longitude); 
474            var latlngStr = input.split(',', 2); 
475            latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])}; 
476
477         
478        geocoder.geocode({'location': latlng}, function(results, status) { 
479            if (status === google.maps.GeocoderStatus.OK) { 
480                if (results[0]) { 
481                    userPosic = results[0].formatted_address; 
482                } else { 
483                    window.alert('No results found'); 
484
485            } else { 
486                window.alert('Geocoder failed due to: ' + status); 
487
488 
489            if(geoActive){ 
490                request = { 
491                    //origin: new google.maps.LatLng(userMarker.coords.latitude, userMarker.coords.longitude), 
492                    origin: userPosic, 
493                    destination: address, 
494                    travelMode: google.maps.TravelMode.DRIVING, 
495                    unitSystem: google.maps.UnitSystem.METRIC, 
496                    provideRouteAlternatives: true 
497                }; 
498            }else{ 
499                request = { 
500                    origin: userPosic, 
501                    destination: address, 
502                    travelMode: google.maps.TravelMode.DRIVING, 
503                    unitSystem: google.maps.UnitSystem.METRIC, 
504                    provideRouteAlternatives: true 
505                }; 
506
507     
508            directionsService.route(request, function(results, status) { 
509                if (status == google.maps.DirectionsStatus.OK) { 
510                    if (circle) circle.setMap(null); 
511                    if(infowindow)infowindow.close(); 
512                    directionsDisplay.setMap(map); 
513                    directionsDisplay.setPanel($("#map_indications").get(0)); 
514                    directionsDisplay.setDirections(results); 
515                } else { 
516                    //console.log("No existen rutas entre ambos puntos"); 
517
518            }); 
519        }); 
520
521</script> 
522 
523<#assign groupId = themeDisplay.getScopeGroupId()/> 
524<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")> 
525<#assign ddmStructureLocalService = serviceLocator.findService("com.liferay.dynamic.data.mapping.service.DDMStructureLocalService")> 
526<#assign structureID = 62817/>  
527<#assign structure = ddmStructureLocalService.getDDMStructure(structureID)/> 
528<#assign articulos = journalArticleLocalService.getStructureArticles(groupId, structure.getStructureKey())/> 
529 
530<#if articulos?has_content> 
531    <#assign contador = 0 /> 
532    <#list articulos as entry> 
533        <#assign docXml = saxReaderUtil.read(entry.getContent()) /> 
534        <#assign nombre = docXml.valueOf("//dynamic-element[@name='CampoDeTexto47225641']/dynamic-content/text()") /> 
535        <#assign direccion = docXml.valueOf("//dynamic-element[@name='CampoDeTexto93009852']/dynamic-content/text()") /> 
536        <#assign latitud = docXml.valueOf("//dynamic-element[@name='CampoDeTexto23083285']/dynamic-content/text()") /> 
537        <#assign longitud = docXml.valueOf("//dynamic-element[@name='CampoDeTexto36625583']/dynamic-content/text()") /> 
538        <#assign enlace = docXml.valueOf("//dynamic-element[@name='CampoDeTexto81864542']/dynamic-content/text()") /> 
539        <#assign telefono = docXml.valueOf("//dynamic-element[@name='CampoDeTexto87251178']/dynamic-content/text()") /> 
540        <script> 
541            addCentros('${contador}','${nombre}','${direccion}','${latitud}','${longitud}','${enlace}','${telefono}'); 
542        </script> 
543        <#assign contador = contador + 1 /> 
544    </#list> 
545</#if> 
546 
547<div class="tc-map"> 
548    <div class="tc-map-search-ctn"> 
549        <div class="wrapper-ajust"> 
550            <form class="form-inline form-map"> 
551                <div class="tc-form-control Direction"> 
552                    <label class="tc-map-label Direction__label" for="address"><span class="text-base">Dirección, CP o Provincia:</span></label> 
553                    <input class="Direction__input field form-control error-field" name="address" id="address" type="textbox" placeholder="Ej.: Calle Santa Engracia 31, 28010 Madrid"></input> 
554                </div> 
555                <div class="tc-form-control Radio"> 
556                    <label class="Radio__label tc-map-label" for="radius"><span class="text-base">Radio de búsqueda:</span></label> 
557                    <input class="Radio__input field form-control error-field field-small" name="radius" id="radius" type="number" min="1" step="1" value="50" placeholder="50"></input> 
558                    <span class="Radio__km tc-map-text-desc">Km.</span> 
559                </div> 
560                <button type="button" class="btnSearch btn btn-ico btn-primary" onclick="codeAddress();"> 
561                    <i class="btnSearch--icon icon-search"></i><span class="btnSearch--text">Buscar</span> 
562                </button> 
563                <span class="rad_err_msg">El radio debe estar comprendido entre 1 km y 500 km.</span> 
564            </form> 
565        </div> 
566    </div> 
567    <div class="wrapper-ajust"> 
568        <div class="tc-map-container"> 
569            <div id="map_canvas" class="tc-map-show"></div> 
570            <div class="div_lista"> 
571                <div id="side_bar" class="side_bar"> 
572                    <div class="p_aviso_side_bar"> 
573                        <p class="evo-form__text-info">Realice una búsqueda para mostrar un listado de resultados.</p> 
574                    </div> 
575                </div> 
576            </div> 
577            <div class="MoreOption">  
578                <button class="MoreOption__button" onclick="buttonUbicaciones()"> 
579                    Ver todas las ubicaciones 
580                    <svg width="13" height="10" viewBox="0 0 13 10" fill="none" xmlns="http://www.w3.org/2000/svg"> 
581                        <path d="M6.83301 1L10.833 5L6.83301 9" stroke="#183657" stroke-width="2" stroke-linecap="round"/> 
582                        <path d="M10.1663 5H2.83301" stroke="#183657" stroke-width="2"/> 
583                        <path d="M1.49984 5.0026C1.49984 4.63441 1.20136 4.33594 0.833171 4.33594C0.464981 4.33594 0.166504 4.63441 0.166504 5.0026C0.166504 5.37079 0.464981 5.66927 0.833171 5.66927C1.20136 5.66927 1.49984 5.37079 1.49984 5.0026Z" fill="#183657"/> 
584                    </svg> 
585                </button> 
586            </div> 
587        </div> 
588        <div id="map_indications" class="tc-map-indications"></div> 
589    </div> 
590</div>