Fehler bei der Verarbeitung der Vorlage.
The following has evaluated to null or missing:
==> journalTool.getJournalArticleByResourcePrimKey(getterUtil.getLong(pdiJSON.classPK))  [in template "37703#37743#8258493" at line 651, column 111]

----
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 journalPDI = journalTool.getJ...  [in template "37703#37743#8258493" at line 651, column 89]
----
1<#-- Services --> 
2<#assign assetEntryLocalServiceUtil = serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService")/> 
3<#assign assetLinkLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetLinkLocalService")/> 
4<#assign journalArticleResourceServiceUtil = serviceLocator.findService("com.liferay.journal.service.JournalArticleResourceLocalService")/> 
5<#assign assetVocabularyLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetVocabularyLocalService") /> 
6<#assign assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService")> 
7<#assign ddmStructureLocalService = serviceLocator.findService("com.liferay.dynamic.data.mapping.service.DDMStructureLocalService")/> 
8 
9<#-- Reserved vbles --> 
10<#assign title = .vars['reserved-article-title'].data> 
11<#assign articleId=.vars["reserved-article-id"].data /> 
12<#assign description=.vars["reserved-article-description"].data /> 
13<#assign smallImageUrl=.vars["reserved-article-small-image-url"].data /> 
14<#assign date=.vars["reserved-article-display-date"].data /> 
15<#assign request = .vars['request']> 
16 
17<#-- Init --> 
18<#assign assetEntry = journalTool.getAssetEntryByArticleId(groupId, articleId)> 
19<#assign journalArticle = journalTool.getJournalArticleByAssetEntry(assetEntry)> 
20<#assign resourcePrimKey = journalArticle.getResourcePrimKey()> 
21<#assign articleURL = themeDisplay.getURLPortal()+themeDisplay.getURLCurrent()> 
22<#assign articleSocialBookmarks = themeDisplay.getThemeSetting("article-social-bookmarks")!> 
23<#assign layoutSetBannerPath = layoutTool.getLayoutSetBannerPath(groupId, themeDisplay.getLayout().isPrivateLayout())!> 
24<#assign articleMainImageThumbnail1 = dlTool.getThumbnail(smallImageUrl, "1", layoutSetBannerPath)! /> 
25<#assign articleMainImageThumbnail3 = dlTool.getThumbnail(smallImageUrl, "3", layoutSetBannerPath)! /> 
26<#assign articleMainImageThumbnail1 = dlTool.getThumbnail(smallImageUrl, "1")! /> 
27<#assign ddmStructureNameNormalize = "template-${friendlyURLNormalizerTool.normalize(journalArticle.getDDMStructure().getName(localeUtil.getDefault()))}" /> 
28<#assign group = themeDisplay.getScopeGroup()/> 
29 
30<#-- Settings --> 
31<#assign schema = "http://schema.org/Article"/> 
32<#assign ddmStructure = journalArticle.getDDMStructure() /> 
33<#assign structureId = "" /> 
34<#assign structureKey = "" /> 
35<#assign filterStructuresIds = ""/> 
36<#assign filterStructuresKeys = []> 
37<#assign filterStructures = []> 
38<#assign filterDDMStructures = []> 
39<#if validator.isNotNull(ddmStructure)> 
40	<#assign structureId = ddmStructure.getStructureId() /> 
41	<#assign structureKey = ddmStructure.getStructureKey()/> 
42	<#assign filterStructuresIdsKey = "${structureId}[filterStructuresIds]"/> 
43	<#assign filterStructuresIdsValue = group.getTypeSettingsProperty(filterStructuresIdsKey)!/> 
44	<#if validator.isNotNull(filterStructuresIdsValue)> 
45		<#assign filterStructuresIds = getterUtil.getLongValues(stringUtil.split(filterStructuresIdsValue))/> 
46		<#list filterStructuresIds as filterStructuresId> 
47			<#assign filterStructure = ddmStructureLocalService.fetchDDMStructure(filterStructuresId)/> 
48			<#if validator.isNotNull(filterStructure)> 
49				<#assign filterStructureKey = filterStructure.getStructureKey()/> 
50				<#assign filterStructuresKeys = filterStructuresKeys + [filterStructureKey] > 
51				<#assign filterDDMStructures = filterDDMStructures + [filterStructure] > 
52			</#if> 
53		</#list> 
54	</#if> 
55	<#assign schemaKey = "${ddmStructure.getStructureKey()}[schema]"/> 
56	<#assign schemaValue = group.getTypeSettingsProperty(schemaKey)!/> 
57	<#if validator.isNotNull(schemaValue)> 
58		<#assign schema = "${schemaValue}"/> 
59	</#if> 
60</#if> 
61 
62<#-- Vocabularies --> 
63<#assign concejosVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Concejos")! /> 
64<#assign modeVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Cicloturismo :: Temática/Modalidad")! /> 
65<#assign routeTypeVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Cicloturismo :: Tipo de Ruta")! /> 
66<#assign trackVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Cicloturismo :: Recorrido")! /> 
67<#assign tracksVocabulary = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Cicloturismo :: Recorridos")! /> 
68<#assign routeVocabularyIds = [modeVocabulary.getVocabularyId(), routeTypeVocabulary.getVocabularyId() , trackVocabulary.getVocabularyId(), tracksVocabulary.getVocabularyId()] /> 
69 
70<#-- Categories --> 
71<#assign concejos = journalTool.getCategories(groupId, articleId, ["Concejos"])/> 
72<#assign comarcas = journalTool.getCategoriesNames(groupId, articleId, locale, ["Comarcas"])/> 
73<#assign tipoRuta = journalTool.getCategoriesNames(groupId, articleId, locale, ["Cicloturismo :: Tipo de Ruta"])/> 
74<#assign modalidad = journalTool.getCategoriesNames(groupId, articleId, locale, ["Cicloturismo :: Temática/Modalidad"])/> 
75<#assign tipoRecorrido = journalTool.getCategoriesNames(groupId, articleId, locale, ["Cicloturismo :: Recorrido"])/> 
76<#assign tipoRecorridos = journalTool.getCategoriesNames(groupId, articleId, locale, ["Cicloturismo :: Recorridos"])/> 
77<#assign dificultad = journalTool.getCategories(groupId, articleId, ["Microsite :: Dificultad"])/> 
78<#assign duracion = journalTool.getCategoriesNames(groupId, articleId, locale, ["Cicloturismo :: Duración"])/> 
79<#assign routeTypesCategories = assetCategoryTool.getAssetCategoriesByVocabularyName(tracksVocabulary)! /> 
80 
81<#-- Build --> 
82<#assign numero = Numero.data> 
83<#assign routeTag = "rutacicloturismo${numero}"> 
84 
85<#assign portletId = portletTool.getPortletId(request)!/> 
86<#assign namespace = "_"+portletId+"_" /> 
87<#if Denominacion.data?has_content> 
88	<#assign title = Denominacion.data> 
89</#if> 
90<#assign markersServicesDDMStructureKeys = [] /> 
91 
92<#-- GPX --> 
93<#assign gpxRutaPath = ""/> 
94<#assign gpxRutaJSONObject = ""/> 
95<#assign gpxRoute = ""/> 
96<#assign gpxPOIRutaPath = ""/> 
97<#assign gpxPOIRutaJSONObject = ""/> 
98<#assign gpxPOIRoute = ""/> 
99 
100<#if validator.isNotNull(Documentos.GPXRuta.data) && Documentos.GPXRuta.getData()!=""> 
101	<#assign gpxRutaJSONStr = Documentos.GPXRuta.data! /> 
102	<#assign gpxRutaPath = dlTool.getPathByJSON(gpxRutaJSONStr, themeDisplay.getScopeGroupId())!/> 
103	<#assign gpxRutaJSONObject = jsonFactoryUtil.createJSONObject(Documentos.GPXRuta.data)! /> 
104	<#assign gpxRoute = gpxTool.parser(gpxRutaJSONObject.getLong("classPK"), "Parser", themeDisplay)! /> 
105	 
106</#if> 
107<#if validator.isNotNull(Documentos.GPXPOIRuta.data) && Documentos.GPXPOIRuta.getData()!=""> 
108	<#assign gpxPOIRutaJSONStr = Documentos.GPXPOIRuta.data! /> 
109	<#assign gpxPOIRutaPath = dlTool.getPathByJSON(gpxPOIRutaJSONStr, themeDisplay.getScopeGroupId())!/> 
110	<#assign gpxPOIRutaJSONObject = jsonFactoryUtil.createJSONObject(Documentos.GPXPOIRuta.data)! /> 
111	<#assign gpxPOIRoute = gpxTool.parser(gpxPOIRutaJSONObject.getLong("classPK"), "Parser", themeDisplay)! /> 
112</#if> 
113 
114 
115 
116 
117<#-- Near routes --> 
118<#assign gpxRoutes = [] /> 
119<#assign classTypeIds = [structureId]/> 
120<#assign routesNearJournalArticles = assetNearTool.getNearJournalArticles(themeDisplay.getScopeGroupId(), assetEntry.getEntryId(), 50.0, classTypeIds, 5, true, [])! /> 
121<#list routesNearJournalArticles as routeNearJournalArticle> 
122 
123	<#assign routeNearJournalArticleArticleId = routeNearJournalArticle.getArticleId()! > 
124	<#assign routeNearJournalArticleResourcePrimKey = routeNearJournalArticle.getResourcePrimKey()! > 
125	<#assign routeNearJournalArticleJSONObject = journalTool.contentXMLtoJSONObject(routeNearJournalArticle.getContentByLocale(locale), locale)/> 
126	<#assign routeNearJournalArticleEntryTitle = htmlUtil.escape(routeNearJournalArticle.getTitle(locale)) /> 
127	<#assign routeNearJournalArticleViewURL = journalTool.getDisplayPage(routeNearJournalArticle, themeDisplay, true) /> 
128	<#assign routeNearJournalArticleThumbnailPath = routeNearJournalArticle.getSmallImageURL()! /> 
129	<#assign routeNearJournalArticleThumbnail = dlTool.getThumbnail(routeNearJournalArticleThumbnailPath, "2", layoutSetBannerPath)! /> 
130 
131	<#-- Categories --> 
132	<#assign rutaCercanaTipoRuta = "" /> 
133	<#assign rutaCercanaModalidad = "" /> 
134	<#assign rutaCercanaTipoRecorrido = "" /> 
135	<#assign rutaCercanaTipoRecorridos = "" /> 
136	<#assign rutaCercanaColor = "000" /> 
137	<#assign journalArticleCategories = assetCategoryLocalService.getCategories("com.liferay.journal.model.JournalArticle", routeNearJournalArticleResourcePrimKey) /> 
138	<#list journalArticleCategories as journalArticleCategory> 
139 
140		<#assign vocabularyId = journalArticleCategory.getVocabularyId() /> 
141		<#assign level = 1 /> 
142		<#if validator.isNotNull(journalArticleCategory.getAncestors())> 
143			<#assign level = journalArticleCategory.getAncestors()?size + 1 /> 
144		</#if> 
145 
146		<#if vocabularyId == routeTypeVocabulary.getVocabularyId()> 
147			<#assign rutaCercanaTipoRuta = journalArticleCategory.getTitle(locale) /> 
148		</#if> 
149 
150		<#if vocabularyId == modeVocabulary.getVocabularyId()> 
151			<#assign rutaCercanaModalidad = journalArticleCategory.getTitle(locale) /> 
152		</#if> 
153 
154		<#if vocabularyId == trackVocabulary.getVocabularyId()> 
155			<#assign rutaCercanaTipoRecorrido = journalArticleCategory.getTitle(locale) /> 
156		</#if> 
157 
158		<#if vocabularyId == tracksVocabulary.getVocabularyId()> 
159			<#if level == 1> 
160				<#assign type = assetCategoryTool.getCategoryProperty(journalArticleCategory.getCategoryId(), "type") /> 
161				<#if type != "links"> 
162					<#assign rutaCercanaColor = assetCategoryTool.getCategoryProperty(journalArticleCategory.getCategoryId(), "color") /> 
163					<#assign rutaCercanaTipoRecorridos = journalArticleCategory.getTitle(locale) /> 
164				</#if> 
165			</#if> 
166		</#if> 
167		 
168	</#list> 
169	 
170	<#assign rutaCercanaIbp = routeNearJournalArticleJSONObject.getString("IBP")! /> 
171	<#assign rutaCercanaDistancia = routeNearJournalArticleJSONObject.getString("Distancia")! /> 
172	<#assign rutaCercanaInicio = routeNearJournalArticleJSONObject.getString("Inicio")! /> 
173	<#assign rutaCercanaFinalizacion = routeNearJournalArticleJSONObject.getString("Finalizacion")! /> 
174	<#assign rutaCercanaGpxRuta = routeNearJournalArticleJSONObject.getJSONObject("Documentos").getString("GPXRuta")! /> 
175	<#assign rutaCercanaGpxPOIRuta = routeNearJournalArticleJSONObject.getJSONObject("Documentos").getString("GPXPOIRuta")! /> 
176	<#assign rutaCercanaKmlRuta = routeNearJournalArticleJSONObject.getJSONObject("Documentos").getString("KMLRuta")! /> 
177	<#assign rutaCercanaDenominacion = routeNearJournalArticleJSONObject.getString("Denominacion")! /> 
178	<#if validator.isNotNull(rutaCercanaDenominacion)> 
179		<#assign routeNearJournalArticleEntryTitle = rutaCercanaDenominacion !/> 
180	</#if> 
181	 
182	<#assign rutaCercanaInicioFinalizacion = rutaCercanaInicio! /> 
183	<#if validator.isNotNull(rutaCercanaFinalizacion)> 
184		<#assign rutaCercanaInicioFinalizacion = rutaCercanaInicio + " - " + rutaCercanaFinalizacion !/> 
185	</#if> 
186	 
187	<#if validator.isNotNull(rutaCercanaGpxRuta)> 
188		<#assign gpxRutaJSONObject = jsonFactoryUtil.createJSONObject(rutaCercanaGpxRuta)! /> 
189		<#assign jsonGPX = gpxTool.parser(gpxRutaJSONObject.getLong("classPK"), "Parser", themeDisplay)! /> 
190			 
191		<#assign jsonGPX = jsonGPX.put("articleId", routeNearJournalArticleArticleId)! /> 
192		<#assign jsonGPX = jsonGPX.put("color", rutaCercanaColor)! /> 
193		<#assign jsonGPX = jsonGPX.put("url", routeNearJournalArticleViewURL)! /> 
194		<#assign jsonGPX = jsonGPX.put("title", routeNearJournalArticleEntryTitle)! /> 
195		<#assign jsonGPX = jsonGPX.put("image", routeNearJournalArticleThumbnail)! /> 
196		<#assign jsonGPX = jsonGPX.put("startEnd", rutaCercanaInicioFinalizacion)! /> 
197		<#assign jsonGPX = jsonGPX.put("routeTypes", rutaCercanaTipoRecorridos)! /> 
198		<#assign jsonGPX = jsonGPX.put("ibp", rutaCercanaIbp)! /> 
199		<#assign jsonGPX = jsonGPX.put("mode", rutaCercanaModalidad)! /> 
200		<#assign jsonGPX = jsonGPX.put("distance", rutaCercanaDistancia)! /> 
201		 
202		<#assign gpxRoutes = gpxRoutes + [jsonGPX] /> 
203	</#if> 
204	 
205</#list> 
206 
207<#-- ALT destacada --> 
208<#assign altImgDestacada = title /> 
209<#if AltImagenDestacada ??> 
210	<#if validator.isNotNull(AltImagenDestacada.getData())> 
211		<#assign altImgDestacada = AltImagenDestacada.getData() /> 
212	</#if> 
213</#if> 
214 
215<article class="template template-cicloturismo template-layout-map template-route template-${ddmStructureNameNormalize} position-relative" role="article" itemscope itemtype="http://schema.org/TravelAction"> 
216 
217	<div class="container"> 
218	<div class="row no-gutters"> 
219		<div class="col-md-5 col-12 col-sidebar"> 
220		 
221		<h2 class="article-title" itemprop="name">${title}</h2> 
222 
223		<div id="article-display-container" class="hide"> 
224			<button id="close-article-display" type="button" class="btn btn-light"> 
225				<span class="fas fa-times"><span class="hide-accessible">${languageUtil.get(locale, "close")}</span></span> 
226			</button> 
227			<div id="article-display"></div> 
228		</div> 
229 
230		<div id="search-container"> 
231 
232			<#if validator.isNotNull(description)> 
233				<div class="article-description" itemprop="description"> 
234					${htmlUtil.extractText(description)} 
235				</div> 
236			</#if> 
237		 
238			<#assign slideImagesCount = 0 /> 
239			<#assign slideImagesSize = Visualizador.Imagen.getSiblings()?size /> 
240			<#if  Visualizador.Imagen.getSiblings()?has_content || validator.isNotNull(smallImageUrl)> 
241				<div id="article-carousel" class="carousel slide carousel-fade carousel-article" data-ride="carousel" data-interval="5000"> 
242					<span aria-hidden="true" class="loading-animation loading-bg"></span> 
243					<div class="carousel-inner"> 
244						<#if validator.isNotNull(smallImageUrl)> 
245							<div class="carousel-item active aspect-ratio-bg-cover" style="background-image: url(${articleMainImageThumbnail3});"> 
246								<img class="hide" src="${articleMainImageThumbnail1}" alt="${altImgDestacada}" title="${altImgDestacada}"/> 
247							</div> 
248							<#assign slideImagesCount = slideImagesCount + 1 /> 
249						</#if> 
250						<#list 0..2 as item> 
251							<#if item < Visualizador.Imagen.getSiblings()?size > 
252								<#assign Slide = Visualizador.Imagen.getSiblings()[item]!/> 
253								<#if Slide?? && validator.isNotNull(Slide) && Slide.data?? && validator.isNotNull(Slide.data)> 
254 
255									<#assign slideThumbnail1 = dlTool.getThumbnailByJSON(Slide.data, "1")! /> 
256									<#assign slideThumbnail3 = dlTool.getThumbnailByJSON(Slide.data, "3")! /> 
257									<#assign slideTitle = "${languageUtil.get(request, 'image')} ${title}" /> 
258									<#assign slideAlt = slideTitle /> 
259									<#if Slide.TituloImagen?? && Slide.TituloImagen.data?has_content> 
260										<#assign slideTitle = Slide.TituloImagen.data />   
261										<#assign slideAlt = slideTitle /> 
262									</#if> 
263									<#if Slide.AltImagen?? && validator.isNotNull(Slide.AltImagen.getData())> 
264										<#assign slideAlt = Slide.AltImagen.getData() /> 
265									</#if> 
266								<#else> 
267									<#continue> 
268								</#if> 
269								<div class="carousel-item aspect-ratio-bg-cover" style="background-image: url(${slideThumbnail3});"> 
270									<img class="hide" src="${slideThumbnail1}" alt="${slideAlt}" title="${slideTitle}"/> 
271								</div> 
272								<#assign slideImagesCount = slideImagesCount + 1 /> 
273							</#if> 
274						</#list> 
275					</div> 
276					<a class="carousel-control-prev" href="#article-carousel" data-slide="prev"> 
277						<span class="carousel-control-prev-icon" aria-hidden="true"><!-- ${languageUtil.get(request, "previous")} --></span> 
278						<span class="hide-accessible">${languageUtil.get(request, "previous")}</span> 
279					</a> 
280					<a class="carousel-control-next" href="#article-carousel" data-slide="next"> 
281						<span class="carousel-control-next-icon" aria-hidden="true"><!-- ${languageUtil.get(request, "next")}--></span> 
282						<span class="hide-accessible">${languageUtil.get(request, "next")}</span> 
283					</a> 
284					<ol class="carousel-indicators d-none"> 
285						<#assign index = 0 /> 
286						<#list 1..slideImagesCount as item> 
287							<li data-target="#article-carousel" data-slide-to="${index}" <#if index==0> class="active"</#if>></li> 
288							<#assign index = index + 1 /> 
289						</#list> 
290					</ol> 
291				</div> 
292			</#if> 
293			 
294			<div class="article-data-wrapper"> 
295			<#if validator.isNotNull(concejos) || validator.isNotNull(Distancia.getData()) || validator.isNotNull(dificultad) || validator.isNotNull(DesnivelAcumulado.getData()) || validator.isNotNull(AltitudMaxima.getData()) 
296			|| validator.isNotNull(AltitudMaxima.getData()) || validator.isNotNull(AltitudMinima.getData()) || validator.isNotNull(IBP.getData()) || validator.isNotNull(tipoRuta) || validator.isNotNull(modalidad) 
297			|| validator.isNotNull(tipoRecorrido) || getterUtil.getBoolean(Transporte.Retorno.getData())> 
298					 
299					<#if validator.isNotNull(PoblacionesPrincipales.getData())> 
300						<ul class="article-list list-unstyled article-list-info"> 
301							<li class="article-list-item"> 
302								<span class="fas fa-map-marker-alt"> 
303									<span class="hide-accessible">${languageUtil.get(request,"address")}</span> 
304								</span>											 
305								<span class="field-wrapper" itemprop="address">						 
306									<span class="text d-block important">${PoblacionesPrincipales.getData()}</span> 
307									<#assign zoneNames = [] /> 
308									<#if concejos?size gt 0> 
309										<#list concejos as concejo> 
310											<#if concejo.getParentCategoryId() == 0> 
311												<#if !zoneNames?seq_contains("${concejo.getTitle(locale)}")> 
312													<#assign zoneNames = zoneNames + ["${concejo.getTitle(locale)}"]/> 
313												</#if> 
314											</#if> 
315										</#list> 
316										<#if validator.isNotNull(zoneNames)> 
317											<span class="text zones d-block">${zoneNames?join(", ")}</span> 
318										</#if> 
319									</#if> 
320								</span> 
321							</li> 
322						</ul> 
323					</#if> 
324				 
325					<div class="article-info-table"> 
326					<div class="article-info-table-row"> 
327						<div class="article-info-table-cell"> 
328						<ul class="article-list list-unstyled article-list-info"> 
329						<#if validator.isNotNull(Distancia.getData())> 
330							<li class="article-list-item"> 
331								<span class="fas fa-ruler-horizontal"> 
332									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-distancia")}</span> 
333								</span> 
334								<span class="field-wrapper"> 
335									<span class="field">${languageUtil.get(request, "infoasturias-distancia")}:</span>	 
336									<span class="text text-featured">${Distancia.getData()} kms</span> 
337								</span> 
338							</li> 
339						</#if> 
340						<#if validator.isNotNull(dificultad) && dificultad?has_content> 
341							<li class="article-list-item"> 
342								<span class="fas fa-layer-group"> 
343									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-dificultad")}</span> 
344								</span> 
345								<span class="field-wrapper"> 
346									<span class="field">${languageUtil.get(request, "infoasturias-dificultad")}:</span> 
347									<span class="text">${dificultad[0].getTitle(locale)}</span> 
348								</span> 
349							</li> 
350						</#if> 
351						<#if validator.isNotNull(DesnivelAcumulado.getData())> 
352							<li class="article-list-item"> 
353								<span class="fas fa-chart-line">	 
354									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-ascenso-acumulado")}</span> 
355								</span> 
356								<span class="field-wrapper"> 
357									<span class="field">${languageUtil.get(request, "infoasturias-route-ascenso-acumulado")}:</span> 
358									<span class="text">${DesnivelAcumulado.data} m</span> 
359								</span> 
360							</li> 
361						</#if> 
362						<#if validator.isNotNull(AltitudMaxima.getData())> 
363							<li class="article-list-item"> 
364								<span class="fas fa-ruler-vertical"> 
365									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-altitud-maxima")}</span> 
366								</span> 
367								<span class="field-wrapper"> 
368									<span class="field">${languageUtil.get(request, "infoasturias-route-altitud-maxima")}:</span> 
369									<span class="text">${AltitudMaxima.data} m</span> 
370								</span> 
371							</li> 
372						</#if> 
373						<#if validator.isNotNull(AltitudMinima.getData())> 
374							<li class="article-list-item"> 
375								<span class="fas fa-ruler-vertical"> 
376									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-altitud-minima")}</span> 
377								</span> 
378								<span class="field-wrapper"> 
379									<span class="field">${languageUtil.get(request, "infoasturias-route-altitud-minima")}:</span> 
380									<span class="text">${AltitudMinima.data} m</span> 
381								</span> 
382							</li> 
383						</#if> 
384						<#if validator.isNotNull(IBP.getData())> 
385							<li class="article-list-item"> 
386								<span class="fas fa-mountain"> 
387									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-ibp-index")}</span> 
388								</span> 
389								<span class="field-wrapper"> 
390									<span class="field">${languageUtil.get(request, "infoasturias-route-ibp-index")}:</span> 
391									<span class="text">${IBP.data}</span> 
392								</span> 
393							</li> 
394						</#if> 
395						</ul> 
396						</div> 
397						<div class="article-info-table-cell"> 
398							<ul class="article-list list-unstyled article-list-info"> 
399								<#if validator.isNotNull(tipoRecorridos)> 
400									<li class="article-list-item"> 
401										<span class="fas fa-bicycle"> 
402											<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-recorrido")}</span> 
403										</span> 
404										<span class="field-wrapper"> 
405											<span class="field">${tipoRecorridos}</span> 
406										</span> 
407									</li> 
408								</#if> 
409								<#if validator.isNotNull(modalidad)> 
410									<li class="article-list-item"> 
411										<span class="fas fa-bicycle"> 
412											<span class="hide-accessible">${modeVocabulary.getDescription(locale)}</span> 
413										</span> 
414										<span class="field-wrapper"> 
415											<span class="field">${modeVocabulary.getDescription(locale)}:</span> 
416											<span class="text">${modalidad}</span> 
417										</span> 
418									</li> 
419								</#if> 
420								<#if validator.isNotNull(tipoRecorrido)> 
421									<li class="article-list-item"> 
422										<span class="fas fa-route"> 
423											<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-tipo-recorrido")}</span> 
424										</span> 
425										<span class="field-wrapper"> 
426											<span class="field">${languageUtil.get(request, "infoasturias-route-tipo-recorrido")}:</span> 
427											<span class="text">${tipoRecorrido}</span> 
428										</span> 
429									</li> 
430								</#if> 
431								<li class="article-list-item"> 
432									<span class="fas fa-train"> 
433										<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-retorno-ferrocarril")}</span> 
434									</span> 
435									<span class="field-wrapper"> 
436									<span class="field">${languageUtil.get(request, "infoasturias-route-retorno-ferrocarril")}:</span> 
437									<#if getterUtil.getBoolean(Transporte.Retorno.getData())> 
438										<span class="text">${languageUtil.get(locale, "yes")}</span> 
439									<#else> 
440										<span class="text">${languageUtil.get(locale, "no")}</span> 
441									</#if> 
442									</span> 
443								</li> 
444								<#if validator.isNotNull(Transporte.Empresa.getData()) && getterUtil.getBoolean(Transporte.Retorno.getData())> 
445									<li class="article-list-item"> 
446										<span class="fas fa-train"> 
447											<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-retorno-ferrocarril")}</span> 
448										</span> 
449										<span class="field-wrapper"> 
450										<span class="field">${Transporte.Empresa.getData()} 
451											<#if validator.isNotNull(Transporte.WebInformativa.getData())> 
452												<#list Transporte.WebInformativa.getSiblings() as web> 
453													<a class="fas fa-external-link-alt" href="${web.getData()}" onclick="this.target='_blank'" title="${languageUtil.get(locale, 'go-to')} ${web.getData()}"> 
454														<span class="hide-accessible">${web.getData()}</span> 
455													</a> 
456												</#list> 
457											</#if> 
458										</span> 
459										</span> 
460									</li> 
461								</#if> 
462							</ul> 
463						</div> 
464					</div> 
465				 
466				<div class="article-info-table-row"> 
467					<div class="article-info-table-cell"> 
468					<ul class="article-list list-unstyled article-list-info"> 
469						<#if validator.isNotNull(Inicio.getData())> 
470							<li class="article-list-item"> 
471								<span class="fas fa-map-marker"> 
472									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-lugar-inicio")}</span> 
473								</span> 
474								<span class="field-wrapper"> 
475								<span class="field">${languageUtil.get(request, "infoasturias-route-lugar-inicio")}:</span> 
476									<span class="text">${Inicio.getData()}</span> 
477								</span> 
478							</li> 
479						</#if> 
480						<#if validator.isNotNull(Finalizacion.getData())> 
481							<li class="article-list-item"> 
482								<span class="fas fa-map-marker"> 
483									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-lugar-finalizacion")}</span> 
484								</span> 
485								<span class="field-wrapper"> 
486								<span class="field">${languageUtil.get(request, "infoasturias-route-lugar-finalizacion")}:</span> 
487									<span class="text">${Finalizacion.getData()}</span> 
488								</span> 
489							</li> 
490						</#if> 
491						<#if validator.isNotNull(duracion)> 
492							<li class="article-list-item"> 
493								<span class="fas fa-stopwatch"> 
494									<span class="hide-accessible">${languageUtil.get(request,"infoasturias-route-duracion-estimada")}</span> 
495								</span> 
496								<span class="field-wrapper"> 
497								<span class="field">${languageUtil.get(request, "infoasturias-route-duracion-estimada")}:</span> 
498									<span class="text">${duracion}</span> 
499								</span> 
500							</li> 
501						</#if> 
502						 
503					</ul> 
504					</div> 
505					<div class="article-info-table-cell"> 
506						<#if validator.isNotNull(Documentos.GPXRuta.getData()) || validator.isNotNull(Documentos.GPXPOIRuta.getData()) || validator.isNotNull(Documentos.KMLRuta.getData())> 
507							<ul class="article-list article-list-documents"> 
508								<#if validator.isNotNull(Documentos.GPXRuta.getData())> 
509									<li class="article-list-item"> 
510									<span class="field-wrapper"> 
511									<a class="btn btn-border btn-inline-block btn-thin" href="${Documentos.GPXRuta.getData()}" onclick="this.target='_blank'" title="${languageUtil.get(request, 'infoasturias-download')} GPX"> 
512										<i class="fas fa-file-download"><!--icon--></i> ${languageUtil.format(request, "infoasturias-route-format", "GPX")} 
513									</a> 
514									</span> 
515									</li> 
516								</#if> 
517								<#if validator.isNotNull(Documentos.GPXPOIRuta.getData())> 
518									<li class="article-list-item"> 
519									<span class="field-wrapper"> 
520									<a class="btn btn-border btn-inline-block btn-thin" href="${Documentos.GPXPOIRuta.getData()}" onclick="this.target='_blank'"  title="${languageUtil.get(request, 'infoasturias-download')} POI GPX"> 
521										<i class="fas fa-file-download"><!--icon--></i> ${languageUtil.format(request, "infoasturias-poi-format", "GPX") } 
522									</a> 
523									</span> 
524									</li> 
525								</#if> 
526								<#if validator.isNotNull(Documentos.KMLRuta.getData())> 
527									<li class="article-list-item"> 
528									<span class="field-wrapper"> 
529									<a class="btn btn-border btn-inline-block btn-thin" href="${Documentos.KMLRuta.getData()}" onclick="this.target='_blank'"  title="${languageUtil.get(request, 'infoasturias-download')} KML"> 
530										<i class="fas fa-file-download"><!--icon--></i>  ${languageUtil.format(request, "infoasturias-route-format", "KML")} 
531									</a> 
532									</span> 
533									</li> 
534								</#if> 
535							</ul> 
536						</#if> 
537					</div> 
538				</div> 
539			</#if> 
540 
541			</div> 
542			 
543			<div class="leaflet-elevation-wrapper" id="elevation-div-${articleId}"><!--Elevation--></div> 
544			 
545			</div> 
546			 
547			<#if validator.isNotNull(DescripcionCorta.getData()) || validator.isNotNull(DescripcionLarga.getData())> 
548				<div class="article-text-wrapper article-panel-wrapper article-panel-wrapper-white"> 
549 
550					<div class="article-social-bookmarks article-social-bookmarks-circle text-right"> 
551						<@liferay_social_bookmarks["bookmarks"] 
552							className="com.liferay.journal.model.JournalArticle" 
553							classPK=assetEntry.getEntryId() 
554							displayStyle="menu" 
555							target="_blank" 
556							title=title 
557							types=articleSocialBookmarks 
558							url="${articleURL}" 
559						/> 
560					</div> 
561 
562					<div class="article-text article-panel"> 
563 
564						<#if validator.isNotNull(DescripcionCorta.getData())> 
565							<div class="article-short-description">${DescripcionCorta.getData()}</div> 
566						</#if> 
567						<#if validator.isNotNull(DescripcionLarga.getData()) || validator.isNotNull(Observaciones.getData())> 
568							<div class="article-long-description-wrapper"> 
569							 
570								<#if validator.isNotNull(DescripcionLarga.getData())> 
571									<div class="article-long-description">${DescripcionLarga.getData()}</div> 
572								</#if> 
573 
574								<#if validator.isNotNull(Observaciones.getData())> 
575									<div class="article-observations">${Observaciones.getData()}</div> 
576								</#if> 
577							</div> 
578						</#if> 
579						 
580						<#assign slideImagesCount = slideImagesCount - 1 /> 
581						<#if slideImagesSize gt slideImagesCount > 
582							<#assign index = 0 /> 
583							<div id="article-carousel-round" class="carousel slide carousel-fade carousel-article" data-ride="carousel" data-interval="5000"> 
584								<span aria-hidden="true" class="loading-animation loading-bg"></span> 
585								<div class="carousel-inner"> 
586									<#list slideImagesCount..slideImagesSize-1 as item> 
587										<#assign Slide = Visualizador.Imagen.getSiblings()[item]/> 
588										<#assign slideThumbnail1 = dlTool.getThumbnailByJSON(Slide.data, "1")! /> 
589										<#assign slideThumbnail3 = dlTool.getThumbnailByJSON(Slide.data, "3")! /> 
590										<#assign slideTitle = "${languageUtil.get(request, 'image')} ${title}" /> 
591										<#assign slideAlt = slideTitle /> 
592										<#if Slide.TituloImagen.data?has_content> 
593											<#assign slideTitle = Slide.TituloImagen.data />   
594											<#assign slideAlt = slideTitle /> 
595										</#if> 
596										<#if Slide.AltImagen?? && validator.isNotNull(Slide.AltImagen.getData())> 
597											<#assign slideAlt = Slide.AltImagen.getData() /> 
598										</#if> 
599										<div class="carousel-item aspect-ratio-bg-cover <#if index==0> active</#if>" style="background-image: url(${slideThumbnail3});"> 
600											<img class="hide" src="${slideThumbnail1}" alt="${slideAlt}"  title="${slideTitle}"/> 
601										</div> 
602										<#assign index = index + 1 /> 
603									</#list> 
604								</div> 
605 
606								<#if (index>1)> 
607									<a class="carousel-control-prev" href="#article-carousel-round" data-slide="prev"> 
608										<span class="carousel-control-prev-icon" aria-hidden="true"><!-- ${languageUtil.get(request, "previous")} --></span> 
609										<span class="hide-accessible">${languageUtil.get(request, "previous")}</span> 
610									</a> 
611									<a class="carousel-control-next" href="#article-carousel-round" data-slide="next"> 
612										<span class="carousel-control-next-icon" aria-hidden="true"><!-- ${languageUtil.get(request, "next")}--></span> 
613										<span class="hide-accessible">${languageUtil.get(request, "next")}</span> 
614									</a> 
615									<ol class="carousel-indicators d-none"> 
616										<#assign index = 0 /> 
617										<#list slideImagesCount..slideImagesSize-1 as item> 
618											<li data-target="#article-carousel-round" data-slide-to="${index}" <#if index==0> class="active"</#if>></li> 
619											<#assign index = index + 1 /> 
620										</#list> 
621									</ol> 
622								</#if> 
623							</div> 
624						</#if> 
625					</div> 
626				</div> 
627			</#if> 
628			 
629			<#-- PDI -->		 
630			<#assign arrayPDIs = [] /> 
631			<#if  PDI.getSiblings()?has_content && validator.isNotNull(PDI.getSiblings()[0]) && (PDI.getSiblings()[0].JournalPDI.data?has_content || PDI.getSiblings()[0].TituloPDI.data?has_content)> 
632				<div class="article-panel-wrapper"> 
633					<div class="article-panel"> 
634						<h3 class="title-section">${languageUtil.get(request,'infoasturias-pois')}</h3> 
635						<div class="slide-wrapper"> 
636							<div id="slick-pdi" class="slick slick-slider"> 
637								<#assign pdiCount = 0 /> 
638								<#list PDI.getSiblings() as pdi> 
639									<#assign journalPDIComarcas = "" /> 
640									<#assign pdiJSONObject = "" /> 
641									<#assign pdiArticleId = "" /> 
642									<#assign pdiURL = "#" /> 
643									<#assign pdiTitle = "" /> 
644									<#assign pdiImgAlt = "" /> 
645									<#assign pdiImgTitle = "" /> 
646									<#assign pdiDescription = "" /> 
647									<#assign smallImageThumbnail2 = "" /> 
648									<#if validator.isNotNull(pdi.JournalPDI.getData()) || (validator.isNotNull(pdi.TituloPDI.getData()) && validator.isNotNull(pdi.TituloPDI.ImagenPDI.getData()))> 
649										<#if validator.isNotNull(pdi.JournalPDI.getData())> 
650											<#assign pdiJSON = pdi.JournalPDI.data?eval/> 
651											<#assign journalPDI = journalTool.getJournalArticleByResourcePrimKey(getterUtil.getLong(pdiJSON.classPK))/> 
652											<#if validator.isNotNull(journalPDI)> 
653												<#assign pdiAssetEntry = journalTool.getAssetEntryByArticleId(journalPDI.getGroupId(), journalPDI.getArticleId())/>  
654												<#if validator.isNotNull(pdiAssetEntry)> 
655													<#assign journalPDIComarcas = journalTool.getCategoriesNames(groupId, journalPDI.getArticleId(), locale, ["Comarcas"])/> 
656													<#assign pdiURL = assetPublisherTool.getAssetViewURL(renderRequest, renderResponse, pdiAssetEntry) /> 
657													<#assign smallImageThumbnail2 = dlTool.getThumbnail(journalPDI.getSmallImageURL(), "2", layoutSetBannerPath)! /> 
658													<#assign pdiArticleId = journalPDI.getArticleId() /> 
659													<#assign pdiId = journalPDI.getArticleId() /> 
660													<#assign pdiTitle = journalPDI.getTitle(locale)! /> 
661													<#assign pdiDescription = stringUtil.shorten(htmlUtil.extractText(journalPDI.getDescription(locale)), 150)! /> 
662													<#assign pdiCoordinates = journalTool.getJournalArticleField(groupId, journalPDI.getArticleId(), "Coordenadas")! /> 
663													 
664													<#assign pdiJSONObject = jsonFactoryUtil.createJSONObject()! /> 
665													<#assign pdiJSONObject = pdiJSONObject.put("articleId", journalPDI.getArticleId())! /> 
666													<#assign pdiJSONObject = pdiJSONObject.put("title", pdiTitle)! /> 
667													<#assign pdiJSONObject = pdiJSONObject.put("description", pdiDescription)! /> 
668													<#assign pdiJSONObject = pdiJSONObject.put("subtitle", journalPDIComarcas)! /> 
669													<#assign pdiJSONObject = pdiJSONObject.put("image", smallImageThumbnail2)! /> 
670													<#assign pdiJSONObject = pdiJSONObject.put("url", pdiURL)! /> 
671													<#assign pdiJSONObject = pdiJSONObject.put("coordinates", pdiCoordinates)! /> 
672													<#assign pdiJSONObject = pdiJSONObject.put("icon", "")! /> 
673													<#if pdi.IconFontAwesomePDI?? && validator.isNotNull(pdi.IconFontAwesomePDI.getData())> 
674														<#assign pdiJSONObject = pdiJSONObject.put("icon", pdi.IconFontAwesomePDI.getData())! /> 
675													</#if> 
676												</#if> 
677											</#if> 
678										<#elseif validator.isNotNull(pdi.TituloPDI.getData()) && validator.isNotNull(pdi.TituloPDI.ImagenPDI.getData())> 
679 
680											<#assign pdiId = pdiCount! /> 
681											<#assign pdiTitle = pdi.TituloPDI.getData()! /> 
682											<#assign pdiImgAlt = pdi.TituloPDI.getData()! /> 
683											<#assign pdiImgTitle = pdi.TituloPDI.getData()! /> 
684											<#assign pdiCoordinates = pdi.TituloPDI.CoordenadasPDI.getData()! /> 
685											<#assign smallImageThumbnail2 = dlTool.getThumbnail(pdi.TituloPDI.ImagenPDI.getData(), "2", layoutSetBannerPath)! /> 
686											<#if pdi.TituloPDI.ImagenPDI.TitleImagenPDI??> 
687												<#if validator.isNotNull(pdi.TituloPDI.ImagenPDI.TitleImagenPDI.getData())> 
688													<#assign pdiImgTitle = pdi.TituloPDI.ImagenPDI.TitleImagenPDI.getData()/> 
689												</#if> 
690											</#if> 
691											<#if pdi.TituloPDI.ImagenPDI.AltImagenPDI??> 
692												<#if validator.isNotNull(pdi.TituloPDI.ImagenPDI.AltImagenPDI.getData())> 
693													<#assign pdiImgAlt = pdi.TituloPDI.ImagenPDI.AltImagenPDI.getData()/> 
694												</#if> 
695											</#if> 
696											<#assign pdiJSONObject = jsonFactoryUtil.createJSONObject()! /> 
697											<#assign pdiJSONObject = pdiJSONObject.put("articleId", pdiId)! /> 
698											<#assign pdiJSONObject = pdiJSONObject.put("title", pdiTitle)! /> 
699											<#assign pdiJSONObject = pdiJSONObject.put("description", "")! /> 
700											<#assign pdiJSONObject = pdiJSONObject.put("subtitle", "")! /> 
701											<#assign pdiJSONObject = pdiJSONObject.put("image", smallImageThumbnail2)! /> 
702											<#assign pdiJSONObject = pdiJSONObject.put("url", "")! /> 
703											<#assign pdiJSONObject = pdiJSONObject.put("coordinates", pdiCoordinates)! /> 
704											<#assign pdiJSONObject = pdiJSONObject.put("icon", "")! /> 
705											<#if pdi.IconFontAwesomePDI?? && validator.isNotNull(pdi.IconFontAwesomePDI.getData())> 
706												<#assign pdiJSONObject = pdiJSONObject.put("icon", pdi.IconFontAwesomePDI.getData())! /> 
707											</#if> 
708										</#if> 
709										<#if validator.isNotNull(pdiJSONObject)> 
710											<#assign arrayPDIs = arrayPDIs + [pdiJSONObject] /> 
711										</#if> 
712 
713										<div class="slide"> 
714											<a class="card poi" href="${pdiURL}" data-articleid="${pdiArticleId}" data-id="poi-${pdiId}" title="${languageUtil.format(request, 'go-to-x', htmlUtil.escape(pdiTitle))}"> 
715												<span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3" style="background-image: url(${smallImageThumbnail2});"> 
716													<img class="hide-accessible" src="${smallImageThumbnail2}" alt="${pdiImgAlt}" /> 
717													<#if validator.isNotNull(pdiDescription)> 
718														<span class="card-hover"> 
719															<span class="card-hover-text" itemprop="description"> 
720																${pdiDescription} 
721															</span> 
722														</span> 
723													</#if> 
724												</span> 
725												<span class="card-body"> 
726													<span class="card-title">${pdiTitle}</span> 
727													<#if validator.isNotNull(journalPDIComarcas)> 
728														<span class="card-subtitle">${journalPDIComarcas}</span> 
729													</#if> 
730												</span> 
731											</a> 
732										</div> 
733										<#assign pdiCount = pdiCount + 1 /> 
734									</#if> 
735								</#list> 
736							</div> 
737						</div> 
738					</div> 
739				</div> 
740 
741				<script type="text/javascript"> 
742 
743					// bootstrap 4 breakpoints 
744					var breakpoint${namespace} = { 
745						// small screen / phone 
746						sm: 576, 
747						// medium screen / tablet 
748						md: 768, 
749						// large screen / desktop 
750						lg: 992, 
751						// extra large screen / wide desktop 
752						xl: 1200 
753					}; 
754 
755					// bootstrap 4 responsive multi column slick carousel 
756					$('#slick-pdi').slick({ 
757						autoplay: false, 
758						autoplaySpeed: 1000, 
759						draggable: true, 
760						pauseOnHover: false, 
761						infinite: false, 
762						dots: false, 
763						arrows: true, 
764						speed: 1000, 
765						mobileFirst: true, 
766						slidesToShow: 1, 
767						slidesToScroll: 1, 
768						centerMode: false, 
769						responsive: [{ 
770							breakpoint: breakpoint${namespace}.sm, 
771							settings: { 
772							slidesToShow: 1, 
773							slidesToScroll: 1 
774
775						}, 
776
777							breakpoint: breakpoint${namespace}.md, 
778							settings: { 
779							slidesToShow: 2, 
780							slidesToScroll: 1 
781
782						}, 
783
784							breakpoint: breakpoint${namespace}.lg, 
785							settings: { 
786							slidesToShow: 2, 
787							slidesToScroll: 1 
788
789						}, 
790
791							breakpoint: breakpoint${namespace}.xl, 
792							settings: { 
793							slidesToShow: 2, 
794							slidesToScroll: 1 
795
796
797
798					}); 
799				</script> 
800			</#if> 
801			 
802			<#-- Services --> 
803			<#assign servicesNearJournalArticles = [] /> 
804			<div id="services-panel" class="article-panel-wrapper article-panel-services hide"> 
805				<div class="article-panel"> 
806					<h3 class="title-section">${languageUtil.get(request,'infoasturias-route-services')}</h3> 
807					 
808					<div class="filter-categories mb-4"> 
809 
810						<#list filterDDMStructures as filterDDMStructure> 
811 
812							<#assign filterStructureCustomNameKey = "${filterDDMStructure.getStructureId()}[customName]"/> 
813							<#assign filterStructureCustomNameValue = group.getTypeSettingsProperty(filterStructureCustomNameKey)!/> 
814 
815							<#assign filterStructureKey = filterDDMStructure.getStructureKey()! /> 
816							<#assign filterStructureName = filterDDMStructure.getName(locale) /> 
817							<#assign filterStructureDescription = filterDDMStructure.getDescription(locale) /> 
818							 
819 
820							<#if validator.isNotNull(filterStructureDescription)> 
821								<#assign filterStructureName = filterStructureDescription! /> 
822							</#if> 
823 
824							<#if validator.isNotNull(filterStructureCustomNameValue)> 
825								<#assign filterStructureName = languageUtil.get(request, filterStructureCustomNameValue)! /> 
826							</#if> 
827 
828							<a class="button-vocabulary-structure btn btn-border btn-thin mb-1 disabled-service" href="#" id="button-vocabulary-structure-id-${filterStructureKey}" data-vocabulary-structure-id="${filterStructureKey}">${filterStructureName}</a> 
829 
830						</#list> 
831 
832					</div> 
833					 
834					<div id="services-entries-container" class="slide-wrapper lfr-spa-loading"> 
835						<div class="lfr-spa-loading-spinner" style="position: absolute;"></div> 
836						<ul class="slider slick slick-slider pl-0"></ul> 
837						<@liferay_aui["script"] use="aui-base"> 
838							$(function() { 
839								$(".slider").slick({ 
840									arrows: true, 
841									dots: false, 
842									slidesToShow: 2, 
843									slidesToScroll: 1, 
844									mobileFirst: false, 
845									centerMode: false, 
846									infinite: false, 
847									responsive: [{ 
848										breakpoint: breakpoint${namespace}.sm, 
849										settings: { 
850										slidesToShow: 1, 
851										slidesToScroll: 1 
852
853									}, 
854
855										breakpoint: breakpoint${namespace}.md, 
856										settings: { 
857										slidesToShow: 2, 
858										slidesToScroll: 1 
859
860									}, 
861
862										breakpoint: breakpoint${namespace}.lg, 
863										settings: { 
864										slidesToShow: 2, 
865										slidesToScroll: 1 
866
867									}, 
868
869										breakpoint: breakpoint${namespace}.xl, 
870										settings: { 
871										slidesToShow: 2, 
872										slidesToScroll: 1 
873
874
875
876								}); 
877							}); 
878						</@> 
879					</div> 
880				</div> 
881			</div> 
882			 
883			<#if validator.isNotNull(routesNearJournalArticles) && routesNearJournalArticles?size gt 0> 
884				<div class="article-panel-wrapper article-panel-wrapper-white template-routes"> 
885					<div class="article-panel"> 
886					<h3 class="title-section">${languageUtil.get(request,'infoasturias-routes-near-here')}</h3> 
887					<div class="slide-wrapper"> 
888						<div id="slick-near" class="slick slick-slider"> 
889							<#list routesNearJournalArticles as currentJournalArticle> 
890								<#assign viewURL = journalTool.getDisplayPage(currentJournalArticle, themeDisplay, true)/> 
891								<#assign smallImageThumbnail2 = dlTool.getThumbnail(currentJournalArticle.getSmallImageURL(), "2", layoutSetBannerPath)! /> 
892								<#assign routeTitle = currentJournalArticle.getTitle(locale)/> 
893								<#assign denominacion = journalTool.getJournalArticleField(currentJournalArticle.getGroupId(), currentJournalArticle.getArticleId(), "Denominacion", locale)/> 
894								<#assign assetEntry = journalTool.getAssetEntryByArticleId(groupId, articleId)> 
895								<#if validator.isNotNull(denominacion)> 
896									<#assign routeTitle = denominacion /> 
897								</#if> 
898								<div class="slide"> 
899									<a class="card route-near" data-id="route-near-${currentJournalArticle.getArticleId()}" href="${viewURL}" title="${languageUtil.format(request, 'go-to-x', routeTitle)}"> 
900										<span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3" style="background-image: url('${smallImageThumbnail2}');"> 
901											<img class="hide-accessible" src="${smallImageThumbnail2}" alt="${routeTitle}"> 
902											<#if validator.isNotNull(htmlUtil.extractText(currentJournalArticle.getDescription(locale)))> 
903												<span class="card-hover"> 
904													<span class="card-hover-text" itemprop="description"> 
905														${stringUtil.shorten(htmlUtil.extractText(currentJournalArticle.getDescription(locale)), 150)} 
906													</span> 
907												</span> 
908											</#if> 
909										</span> 
910										<span class="card-body"> 
911											<span class="card-title">${routeTitle}</span> 
912											<span class="card-subtitle"> 
913												<#-- <span class="d-block">${currentJournalArticle.getVersion()} Kms</span>--> 
914												<#assign currentJournalArticleConcejos = journalTool.getCategoriesNames(groupId, currentJournalArticle.getArticleId(), locale, ["Concejos"])/> 
915												<#if validator.isNotNull(currentJournalArticleConcejos)> 
916													<#assign currentJournalArticleConcejos = stringUtil.replace(currentJournalArticleConcejos,",",", ") /> 
917													<span class="d-block">${currentJournalArticleConcejos}</span> 
918												</#if> 
919											</span> 
920										</span> 
921									</a> 
922								</div> 
923							</#list> 
924						</div> 
925					</div> 
926					</div> 
927				</div> 
928 
929				<script type="text/javascript"> 
930 
931					// bootstrap 4 breakpoints 
932					var breakpoint${namespace} = { 
933						// small screen / phone 
934						sm: 576, 
935						// medium screen / tablet 
936						md: 768, 
937						// large screen / desktop 
938						lg: 992, 
939						// extra large screen / wide desktop 
940						xl: 1200 
941					}; 
942 
943					// bootstrap 4 responsive multi column slick carousel 
944					$('#slick-near').slick({ 
945						autoplay: false, 
946						autoplaySpeed: 1000, 
947						draggable: true, 
948						pauseOnHover: false, 
949						infinite: false, 
950						dots: false, 
951						arrows: true, 
952						speed: 1000, 
953						mobileFirst: true, 
954						slidesToShow: 1, 
955						slidesToScroll: 1, 
956						centerMode: false, 
957						responsive: [{ 
958							breakpoint: breakpoint${namespace}.sm, 
959							settings: { 
960							slidesToShow: 1, 
961							slidesToScroll: 1 
962
963						}, 
964
965							breakpoint: breakpoint${namespace}.md, 
966							settings: { 
967							slidesToShow: 2, 
968							slidesToScroll: 1 
969
970						}, 
971
972							breakpoint: breakpoint${namespace}.lg, 
973							settings: { 
974							slidesToShow: 2, 
975							slidesToScroll: 1 
976
977						}, 
978
979							breakpoint: breakpoint${namespace}.xl, 
980							settings: { 
981							slidesToShow: 2, 
982							slidesToScroll: 1 
983
984
985
986					}); 
987				</script> 
988			</#if> 
989			</div> 
990		</div> 
991		 
992		<div class="col-md-7 col-12 col-map d-md-inline-block d-none"> 
993			<div id="map" class="lfr-spa-loading"> 
994				<div class="lfr-spa-loading-spinner" style="position: absolute;"></div> 
995				 
996				<#if validator.isNotNull(filterStructuresIds)> 
997					<div id="map-filter" class="hide"> 
998						<div class="vocabularies"> 
999							<#list filterStructuresIds as filterStructuresId> 
1000								<#assign filterStructure = ddmStructureLocalService.fetchDDMStructure(filterStructuresId)/> 
1001								<#if validator.isNotNull(filterStructure)> 
1002									<#assign filterStructureKey = filterStructure.getStructureKey()/> 
1003										<#assign markersServicesDDMStructureKeys = arrayUtil.append(markersServicesDDMStructureKeys, filterStructureKey) /> 
1004										<#assign filterStructureFontAwesomeKey = "${filterStructure.getStructureId()}[fontAwesome]"/> 
1005										<#assign filterStructureFontAwesomeValue = group.getTypeSettingsProperty(filterStructureFontAwesomeKey)!/> 
1006										<#assign filterStructureVocabularyKey = "${filterStructure.getStructureId()}[vocabularyId]"/> 
1007										<#assign filterStructureVocabularyValue = getterUtil.getLong(group.getTypeSettingsProperty(filterStructureVocabularyKey))!/> 
1008										<#assign filterStructurevocabularyLevelCategoriesKey = "${filterStructure.getStructureId()}[vocabularyLevelCategories]"/> 
1009										<#assign filterStructurevocabularyLevelCategoriesValue = group.getTypeSettingsProperty(filterStructurevocabularyLevelCategoriesKey)!1/> 
1010										<#assign filterStructurevocabularyCategoryIdsKey = "${filterStructure.getStructureId()}[vocabularyCategoryIds]"/> 
1011										<#assign filterStructurevocabularyCategoryIdsValue = group.getTypeSettingsProperty(filterStructurevocabularyCategoryIdsKey)!/> 
1012										<#assign filterStructurevocabularyTagsKey = "${filterStructure.getStructureId()}[vocabularyTags]"/> 
1013										<#assign filterStructurevocabularyTagsValue = group.getTypeSettingsProperty(filterStructurevocabularyTagsKey)!/> 
1014										<#assign filterStructureCustomNameKey = "${filterStructure.getStructureId()}[customName]"/> 
1015										<#assign filterStructureCustomNameValue = group.getTypeSettingsProperty(filterStructureCustomNameKey)!/> 
1016										<#assign filterStructureStructureIdsKey = "${filterStructure.getStructureId()}[filterStructuresIds]"/> 
1017										<#assign filterStructureStructureIdsValues = group.getTypeSettingsProperty(filterStructureStructureIdsKey)!/> 
1018 
1019										<#assign filterStructureStructureKeys = [filterStructureKey]/> 
1020										<#if validator.isNotNull(filterStructureStructureIdsValues)> 
1021											<#list stringUtil.split(filterStructureStructureIdsValues) as filterStructureStructureIdsValue> 
1022												<#assign ddmStructure = ddmStructureLocalService.fetchDDMStructure(getterUtil.getLong(filterStructureStructureIdsValue))! /> 
1023												<#if validator.isNotNull(ddmStructure)> 
1024													<#assign filterStructureStructureKeys = filterStructureStructureKeys + [ddmStructure.getStructureKey()]/> 
1025												</#if> 
1026											</#list> 
1027										</#if> 
1028										 
1029										<#assign filterStructureJSONObject = jsonFactoryUtil.createJSONObject()> 
1030										<#assign filterStructureJSONObject = filterStructureJSONObject.put("structureId", filterStructuresId)! /> 
1031										<#assign filterStructureJSONObject = filterStructureJSONObject.put("structureKey", filterStructureKey)! /> 
1032										<#assign filterStructureJSONObject = filterStructureJSONObject.put("fontAwesome", filterStructureFontAwesomeValue)! /> 
1033										<#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyId", filterStructureVocabularyValue)! /> 
1034										<#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyLevelCategories", filterStructurevocabularyLevelCategoriesValue)! /> 
1035										<#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyCategoryIds", filterStructurevocabularyCategoryIdsValue)! /> 
1036										<#assign filterStructureJSONObject = filterStructureJSONObject.put("vocabularyTags", filterStructurevocabularyTagsValue)! /> 
1037										<#assign filterStructureJSONObject = filterStructureJSONObject.put("name", filterStructure.getName(locale))! /> 
1038										<#assign filterStructureJSONObject = filterStructureJSONObject.put("customName", filterStructureCustomNameValue)! /> 
1039										<#assign filterStructureJSONObject = filterStructureJSONObject.put("description", filterStructure.getDescription(locale))! /> 
1040										<#assign filterStructureJSONObject = filterStructureJSONObject.put("structureKeys", stringUtil.merge(filterStructureStructureKeys))! /> 
1041										<#assign filterStructures = filterStructures + [filterStructureJSONObject] /> 
1042 
1043									<#assign filterStructureName = filterStructure.getName(locale) /> 
1044									<#assign filterStructureDescription = filterStructure.getDescription(locale) /> 
1045									 
1046									<#if validator.isNotNull(filterStructureDescription)> 
1047										<#assign filterStructureName = filterStructureDescription! /> 
1048									</#if> 
1049 
1050									<#if validator.isNotNull(filterStructureCustomNameValue)> 
1051										<#assign filterStructureName = languageUtil.get(request, filterStructureCustomNameValue)! /> 
1052									</#if> 
1053									 
1054									<div class="vocabulary-wrapper disabled-service" title="${filterStructureName}" data-structurekey="${filterStructure.getStructureKey()}"> 
1055										<div class="vocabulary" id="vocabulary-structure-id-${filterStructure.getStructureKey()}" data-vocabulary-structure-id="${filterStructure.getStructureKey()}"> 
1056											<span class="icon ${filterStructureFontAwesomeValue}"><span class="hide-accessible">${filterStructureName}</span></span> 
1057										</div> 
1058										<#if validator.isNotNull(filterStructureVocabularyValue)> 
1059											<#assign filterStructureVocabulary = assetVocabularyLocalService.fetchAssetVocabulary(filterStructureVocabularyValue)! /> 
1060											<#assign filterStructureVocabularyCategories = assetCategoryTool.getAssetCategoriesByVocabulary(filterStructureVocabulary, getterUtil.getInteger(filterStructurevocabularyLevelCategoriesValue))! /> 
1061											<#if validator.isNotNull(filterStructureVocabularyCategories)> 
1062												<div class="categories"> 
1063													<#list filterStructureVocabularyCategories as filterStructureVocabularyCategory> 
1064														<div class="category"> 
1065															<input type="checkbox" name="category-${filterStructureVocabularyCategory.getCategoryId()}" id="category-${filterStructureVocabularyCategory.getCategoryId()}" data-id="${filterStructureVocabularyCategory.getCategoryId()}" /> 
1066															<label for="category-${filterStructureVocabularyCategory.getCategoryId()}">${filterStructureVocabularyCategory.getTitle(locale)}</label> 
1067														</div> 
1068													</#list> 
1069												</div> 
1070											</#if> 
1071										</#if> 
1072									</div> 
1073								</#if> 
1074							</#list> 
1075						</div> 
1076					</div> 
1077				</#if> 
1078			</div> 
1079		</div> 
1080	</div> 
1081	</div> 
1082	 
1083</article> 
1084 
1085<@liferay_aui["script"] use="aui-base, anim, aui-io-request, cookie"> 
1086 
1087	var mapZoom = ${getterUtil.getInteger(mapZoom, 12)};//MapZoom 
1088	var mapLat = ${getterUtil.getString(mapLat, "43.362597693870434")};//MapLat 
1089	var mapLng = ${getterUtil.getString(mapLng, "-5.846235457402242")};//MapLng 
1090	var osm = new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 
1091
1092			attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>' 
1093
1094	); 
1095	 
1096	var map = new L.map('map', {center: [${gpxRoute.get("centerLatLon")}], zoom: mapZoom, zoomControl: false, minZoom: 9, bounceAtZoomLimits: false, layers: [osm]}); 
1097	map.doubleClickZoom.disable(); 
1098	map.whenReady(function(){ 
1099		A.one('#map').removeClass('lfr-spa-loading'); 
1100	}); 
1101	 
1102	//Map Height 
1103	mapFullHeight(scroll=true, map); 
1104	 
1105	//FilterStructures 
1106	var fontAwesomeIconClassCSS = []; 
1107	<#list filterStructures as filterStructure> 
1108		fontAwesomeIconClassCSS['${filterStructure["structureKey"]}'] = { 
1109			cssClass:'${filterStructure["fontAwesome"]}',  
1110			vocabularyId: ${filterStructure["vocabularyId"]},  
1111			vocabularyLevelCategories: ${filterStructure["vocabularyLevelCategories"]}, 
1112			vocabularyTags: '${filterStructure["vocabularyTags"]}' 
1113		}; 
1114	</#list> 
1115	 
1116	//ServiceMarkers 
1117	var serviceMarkers = []; 
1118	var markersServicesGroups = {}; 
1119	var servicesContainer = A.one('#services-entries-container'); 
1120	var mapFilter = A.one('#map-filter'); 
1121	var servicesPanel = A.one('#services-panel'); 
1122	 
1123	Liferay.provide(window,'journalArticlesResourcesCount', function(deltaParam, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames){ 
1124		var url = '/o/asac-web-services/ws/journalArticlesResourcesCount'; 
1125		A.io.request(url, { 
1126			method: 'GET', 
1127			type: 'JSON', 
1128			data: { 
1129				companyId: ${companyId}, 
1130				groupId: ${groupId}, 
1131				structureKeys: structureKeys, 
1132				anyCategoryIds: assetAnyCategoryIds, 
1133				allCategoryIds: assetAllCategoryIds, 
1134				anyTagNames: anyTagNames, 
1135				allTagNames: allTagNames 
1136			}, 
1137			on: { 
1138				success: function() { 
1139					var count = this.get('responseData'); 
1140					if(count>deltaParam){ 
1141						var pages = Math.ceil(count/deltaParam); 
1142						for(var cur = 0; cur < pages; cur++){ 
1143							journalArticlesResources(cur, deltaParam, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, count); 
1144
1145					}else{ 
1146						var cur  = -1; 
1147						var delta  = -1; 
1148						journalArticlesResources(cur, deltaParam, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, count); 
1149
1150
1151
1152		}); 
1153	}); 
1154	 
1155	Liferay.provide(window,'journalArticlesResources', function(cur, delta, structureKeys, anyCategoryIds, allCategoryIds, anyTagNames, allTagNames, total){ 
1156		var structureKey = structureKeys.split(',')[0]; 
1157		var url = '/o/asac-web-services/ws/journalArticlesResources'; 
1158		A.io.request(url, { 
1159			method: 'GET', 
1160			type: 'JSON', 
1161			data: { 
1162				companyId: ${companyId}, 
1163				groupId: ${groupId}, 
1164				structureKeys: structureKeys, 
1165				anyCategoryIds: anyCategoryIds, 
1166				allCategoryIds: allCategoryIds, 
1167				anyTagNames: anyTagNames, 
1168				allTagNames: allTagNames, 
1169				cur: cur, 
1170				delta: delta, 
1171			}, 
1172			on: { 
1173				success: function() { 
1174					var vocabularyId = 0; 
1175					var points = JSON.parse(this.get('responseData')); 
1176					if(points && points.length>0){ 
1177						for(var index in points) { 
1178						 
1179							var point = points[index]; 
1180							var articleId = point.articleId; 
1181							var title = point.title; 
1182							var descriptionText = point.descriptionText; 
1183							var assetCategories = point.assetCategories; 
1184							var subTypeId = point.subTypeId; 
1185							var subTypeName = point.subTypeName; 
1186							var coordinates = point.coordinates; 
1187							var detailURL = point.detailURL; 
1188							var detailFullURL = point.detailFullURL; 
1189							if(detailFullURL!='') 
1190								detailURL = detailFullURL; 
1191							var image = point.image; 
1192							var imageThumbnail2 = point.imageThumbnail2; 
1193							var icon = fontAwesomeIconClassCSS[subTypeId].cssClass; 
1194							var vocabularyId = (vocabularyId==0) ? fontAwesomeIconClassCSS[structureKey].vocabularyId : vocabularyId; 
1195							var vocabularyLevelCategories = fontAwesomeIconClassCSS[subTypeId].vocabularyLevelCategories; 
1196							var concejosVocabularyId = ${concejosVocabulary.getVocabularyId()}; 
1197							 
1198							const fontAwesomeIcon = L.divIcon({ 
1199								className: 'marker-wrapper', 
1200								html: "<div class='marker-icon-blue'><i class='"+icon+"'><!-- icon--></i></div>", 
1201								iconSize: [26, 30], 
1202								iconAnchor: [13, 30] 
1203							}); 
1204 
1205							if(coordinates!=''){ 
1206								var latLng = coordinates.split(','); 
1207								if(!isNaN(latLng[0]) && !isNaN(latLng[1])){ 
1208									var pointGroup = ''; 
1209									var categoryTitle = ''; 
1210									var categoryConcejos = ''; 
1211									var categoryId = ''; 
1212									for(var assetCategoriesIndex in assetCategories) { 
1213										var assetCategory = assetCategories[assetCategoriesIndex]; 
1214 
1215										if(assetCategory && assetCategory.vocabularyId==concejosVocabularyId){ 
1216											if(categoryConcejos=='') 
1217												categoryConcejos = assetCategory.title; 
1218											else 
1219												categoryConcejos += ', ' + assetCategory.title; 
1220
1221 
1222										if(assetCategory && assetCategory.vocabularyId==vocabularyId){ 
1223											if(vocabularyLevelCategories && vocabularyLevelCategories>0){ 
1224												var level = assetCategory.level; 
1225												if(vocabularyLevelCategories==level){ 
1226													categoryId = assetCategory.categoryId; 
1227													categoryTitle = assetCategory.title; 
1228													if(markersServicesGroups && markersServicesGroups[categoryId]){ 
1229														pointGroup = markersServicesGroups[categoryId]; 
1230													}else{ 
1231														var pointGroup = L.markerClusterGroup({ 
1232															maxClusterRadius: 100, 
1233															showCoverageOnHover: false, 
1234															//zoomToBoundsOnClick: false, 
1235															//spiderfyOnMaxZoom: false, 
1236															iconCreateFunction: function(cluster) { 
1237																var childMarkers = cluster.getAllChildMarkers(); 
1238																var n = 0; 
1239																for (var i = 0; i < childMarkers.length; i++) { 
1240																	n += 1; 
1241
1242																return L.divIcon({ 
1243																	className: 'marker-wrapper', 
1244																	html: "<div class='marker-circle'>"+n+"</i></div>", 
1245																	iconSize: [26, 30], 
1246																	iconAnchor: [13, 5] 
1247																}); 
1248
1249														}); 
1250														markersServicesGroups[categoryId] = pointGroup; 
1251
1252
1253											}else{ 
1254												categoryId = assetCategory.categoryId; 
1255												categoryTitle = assetCategory.title; 
1256												if(markersServicesGroups && markersServicesGroups[categoryId]){ 
1257													pointGroup = markersServicesGroups[categoryId]; 
1258												}else{ 
1259													var pointGroup = L.markerClusterGroup({ 
1260														maxClusterRadius: 100, 
1261														showCoverageOnHover: false, 
1262														//zoomToBoundsOnClick: false, 
1263														//spiderfyOnMaxZoom: false, 
1264														iconCreateFunction: function(cluster) { 
1265															var childMarkers = cluster.getAllChildMarkers(); 
1266															var n = 0; 
1267															for (var i = 0; i < childMarkers.length; i++) { 
1268																n += 1; 
1269
1270															return L.divIcon({ 
1271																className: 'marker-wrapper', 
1272																html: "<div class='marker-circle'>"+n+"</i></div>", 
1273																iconSize: [26, 30], 
1274																iconAnchor: [13, 5] 
1275															}); 
1276
1277													}); 
1278													markersServicesGroups[categoryId] = pointGroup; 
1279
1280
1281
1282
1283								 
1284									var popupContentTemplate = '<a data-articleid="'+articleId+'" href="'+detailURL+'" class="popup popup-service">'+ 
1285									'<span class="popup-image-wrapper" style="background-image: url('+imageThumbnail2+');"><!-- image--></span>'+ 
1286									'<span class="popup-body">'+ 
1287									'<span class="popup-subtitle">'+categoryTitle+'</span>'+ 
1288									'<span class="popup-title">'+title+'</span>'+ 
1289									'<span class="popup-desciption">'+descriptionText+'</span>'+ 
1290									'</span>'+ 
1291									'</a>'; 
1292 
1293									var newNodeObject = A.Node.create(popupContentTemplate); 
1294									newNodeObject.on('click', function(event){ 
1295										event.preventDefault(); 
1296										var nodeArticleId = this.attr('data-articleid'); 
1297										${namespace}getArticleDisplay(nodeArticleId); 
1298									}); 
1299								 
1300									var marker = L.marker([latLng[0],latLng[1]],  
1301
1302											"icon": fontAwesomeIcon, 
1303											"title": title 
1304
1305									); 
1306									marker.articleId='service-'+articleId; 
1307									marker.bindPopup(newNodeObject.getDOMNode()); 
1308									marker.on('popupopen', function(e) { 
1309										map.panTo(this.getLatLng()); 
1310									}); 
1311									marker.on('popupclose', function(e) { 
1312										${namespace}closeArticleDisplay(); 
1313									}); 
1314									//markersServicesGroup.addLayer(marker); 
1315									if(pointGroup){ 
1316										pointGroup.addLayer(marker); 
1317
1318									 
1319									serviceMarkers.push(marker); 
1320 
1321									//CreateObject 
1322									var entry = A.Node.create('<div class="slide service-structure service-structure-'+subTypeId+' service-category-'+categoryId+'"></div>'); 
1323									var anchor = A.Node.create('<a onclick="event.preventDefault(); ${namespace}getArticleDisplay('+articleId+');" class="card service item-card" data-articleid="'+articleId+'" data-id="service-'+articleId+'" href="'+detailURL+'" title="'+title+'"></a>'); 
1324									var anchorImageWrapper = A.Node.create('<span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3" style="background-image: url('+imageThumbnail2+');"></span>'); 
1325									if(descriptionText!=''){ 
1326										var anchorImageWrapperHover = A.Node.create('<span class="card-hover"></span>'); 
1327										var anchorImageWrapperHoverDescription = A.Node.create('<span class="card-hover-text" itemprop="description">'+descriptionText+'</span>'); 
1328										anchorImageWrapperHover.append(anchorImageWrapperHoverDescription); 
1329										anchorImageWrapper.append(anchorImageWrapperHover); 
1330
1331									var anchorImage = A.Node.create('<img class="hide-accessible" src="'+imageThumbnail2+'" alt="'+title+'">'); 
1332									var anchorBody = A.Node.create('<span class="card-body"></span>'); 
1333									var anchorTitle = A.Node.create('<span class="card-title">'+title+'</span>'); 
1334									var anchorCategories = A.Node.create('<span class="card-categories">'+categoryTitle+'</span>'); 
1335									var anchorConcejos = A.Node.create('<span class="card-subtitle">'+categoryConcejos+'</span>'); 
1336									 
1337									anchorImageWrapper.append(anchorImage); 
1338									anchor.append(anchorImageWrapper); 
1339									anchorBody.append(anchorTitle); 
1340									anchorBody.append(anchorCategories); 
1341									anchorBody.append(anchorConcejos); 
1342									anchor.append(anchorBody); 
1343									 
1344									entry.append(anchor); 
1345									$('.slider').slick('slickAdd','<li class="service-structure-'+subTypeId+' service-category-'+categoryId+'">'+entry.outerHTML()+'</li>'); 
1346
1347
1348
1349 
1350						A.all('.card.service').each(function(item){ 
1351							item.on('mouseover', function(event){ 
1352								var articleId = item.getAttribute("data-id"); 
1353								${namespace}markerServicePopup(articleId, true); 
1354							}); 
1355							item.on('mouseout', function(event){ 
1356								var articleId = item.getAttribute("data-id"); 
1357								${namespace}markerServicePopup(articleId, false); 
1358							}); 
1359						}); 
1360 
1361						var vocabularyWrapper = A.one('.vocabulary-wrapper[data-structurekey="' + structureKey + '"]'); 
1362						var vocabularyButtonWrapper = A.one('.filter-categories .button-vocabulary-structure[data-vocabulary-structure-id="' + structureKey + '"]'); 
1363						if(vocabularyWrapper){ 
1364							vocabularyWrapper.addClass("selectable"); 
1365							vocabularyWrapper.one('.vocabulary').on('click', function(){ 
1366								${namespace}toggleMarkersServicesStructure(structureKey); 
1367							}); 
1368							vocabularyWrapper.removeClass("disabled-service"); 
1369							if(vocabularyButtonWrapper) 
1370								vocabularyButtonWrapper.removeClass("disabled-service"); 
1371
1372
1373 
1374					if(serviceMarkers && serviceMarkers.length>0){ 
1375						if(servicesPanel) 
1376							servicesPanel.show(); 
1377						if(mapFilter) 
1378							mapFilter.show(); 
1379
1380
1381
1382		}); 
1383	}); 
1384	 
1385	<#list filterStructures as filterStructure> 
1386	 
1387		var structureKeys = '${filterStructure["structureKeys"]}'; 
1388		var assetAnyCategoryIds = '${filterStructure["vocabularyCategoryIds"]}'; 
1389		var assetAllCategoryIds = ''; 
1390		var assetAnyTags = ''; 
1391		var assetAllTags = '${routeTag}'; 
1392		if('${filterStructure["vocabularyTags"]}'!='' && '${filterStructure["vocabularyTags"]}'!='1') 
1393			var assetAllTags = '${routeTag},${filterStructure["vocabularyTags"]}'; 
1394		var delta = 500; 
1395		journalArticlesResourcesCount(delta, structureKeys, assetAnyCategoryIds, assetAllCategoryIds, assetAnyTags, assetAllTags); 
1396		servicesContainer.removeClass('lfr-spa-loading'); 
1397		 
1398	</#list> 
1399 
1400	//Filter categories 
1401	//console.log(markersServicesGroups); 
1402	A.all('.categories input').each(function(item){ 
1403		item.on('click', function(){ 
1404 
1405			var categoryIds = []; 
1406			var categoryIdsCssClass = ''; 
1407			var vocabularyWrapper = item.ancestor('.vocabulary-wrapper'); 
1408			var vocabulary = vocabularyWrapper.one('.vocabulary'); 
1409			var categoryId = item.getAttribute('data-id'); 
1410			var structureId = vocabulary.getAttribute('data-vocabulary-structure-id'); 
1411			var button = A.one('#button-vocabulary-structure-id-'+structureId); 
1412			var pointsGroup = markersServicesGroups[categoryId]; 
1413			 
1414			if(pointsGroup){ 
1415				if(item.attr('checked')){ 
1416					map.addLayer(pointsGroup); 
1417				}else{ 
1418					map.removeLayer(pointsGroup); 
1419
1420
1421			if(item.attr('checked')){ 
1422				vocabularyWrapper.addClass('selected'); 
1423				button.addClass('selected'); 
1424			}else{ 
1425				var flag = true; 
1426				var categories = vocabularyWrapper.all('.categories input').each(function(index){ 
1427					if(index.attr('checked')) 
1428						flag = false; 
1429				}); 
1430				if(flag){ 
1431					vocabularyWrapper.removeClass('selected'); 
1432					button.removeClass('selected'); 
1433
1434
1435 
1436			A.all('.categories input').each(function(index){ 
1437				if(index.attr('checked')){ 
1438					var categoryId = index.getAttribute('data-id'); 
1439					categoryIds.push('.service-category-'+categoryId); 
1440
1441			}); 
1442 
1443			$(".slider").slick('slickUnfilter'); 
1444			categoryIdsCssClass = categoryIds.join(); 
1445			if(categoryIdsCssClass!='') 
1446				$(".slider").slick('slickFilter', categoryIdsCssClass); 
1447 
1448		}); 
1449	}); 
1450	 
1451	//Filter services 
1452	A.all('.button-vocabulary-structure').each(function(item){ 
1453		item.on('click', function(event){ 
1454			event.preventDefault(); 
1455			var structureId = item.attr('data-vocabulary-structure-id'); 
1456            if($(window).width() > 768) 
1457			    ${namespace}toggleMarkersServicesStructure(structureId); 
1458		}); 
1459	}); 
1460	 
1461	//Route 
1462	var routesPolylines = []; 
1463	var routesNearPolylinesGroup = L.layerGroup(); 
1464	const fontAwesomeRouteStartIcon = L.divIcon({ 
1465		className: 'marker-wrapper', 
1466		html: "<div class='marker-icon marker-icon-start marker-icon-start-min'><i class='fas fa-bicycle'><!-- icon--></i></div>", 
1467		iconSize: [26, 30], 
1468        iconAnchor: [13, 5] 
1469	}); 
1470	const fontAwesomeRouteEndIcon = L.divIcon({ 
1471		className: 'marker-wrapper', 
1472		html: "<div class='marker-icon marker-icon-end marker-icon-end-min'><i class='fas fa-bicycle'><!-- icon--></i></div>", 
1473		iconSize: [26, 30], 
1474        iconAnchor: [13, 30] 
1475	}); 
1476	const fontAwesomeRouteNearIcon = L.divIcon({ 
1477		className: 'marker-wrapper', 
1478		html: "<div class='marker-icon marker-icon-near marker-icon-near-min'><i class='fas fa-bicycle'><!-- icon--></i></div>", 
1479		iconSize: [26, 30], 
1480        iconAnchor: [13, 5] 
1481	}); 
1482	 
1483	<#if gpxRoute?has_content> 
1484		 
1485		<#assign gpxRoute = gpxRoute.put("articleId", articleId)! /> 
1486		<#assign gpxRoute = gpxRoute.put("color", "000")! /> 
1487		<#assign gpxRoute = gpxRoute.put("url", "")! /> 
1488		<#assign gpxRoute = gpxRoute.put("title", title)! /> 
1489		 
1490		var popupTextStartTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-start')}</span><span class="popup-title">${htmlUtil.escape(Inicio.getData())}</span></span></span>'; 
1491		var popupTextEndTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-end')}</span><span class="popup-title">${htmlUtil.escape(Finalizacion.getData())}</span></span></span>'; 
1492		 
1493		//Markers Route Start/End 
1494		var latLng = '${gpxRoute.get("coordinatesStart")}'; 
1495		latLng = latLng.replaceAll(' ', ''); 
1496		latLng = latLng.split(','); 
1497		var markerRouteStart = L.marker([latLng[0],latLng[1]], 
1498
1499				"icon": fontAwesomeRouteStartIcon, 
1500				"title": '${languageUtil.format(request, 'infoasturias-route-start-x', '${htmlUtil.escape(gpxRoute.get("title"))}')}' 
1501
1502		).bindPopup(popupTextStartTemplate).addTo(map); 
1503		var latLng = '${gpxRoute.get("coordinatesEnd")}'; 
1504		latLng = latLng.replaceAll(' ', ''); 
1505		latLng = latLng.split(','); 
1506		var markerRouteEnd = L.marker([latLng[0],latLng[1]],  
1507
1508				"icon": fontAwesomeRouteEndIcon, 
1509				"title": '${languageUtil.format(request, 'infoasturias-route-end-x', '${htmlUtil.escape(gpxRoute.get("title"))}')}' 
1510
1511		).bindPopup(popupTextEndTemplate).addTo(map); 
1512		 
1513		//POIs 
1514		var poiMarkers = []; 
1515		<#if arrayPDIs?has_content> 
1516			<#list arrayPDIs as arrayPDI> 
1517				var poiArticleId = '${arrayPDI.get("articleId")}'; 
1518				var latLng = '${arrayPDI.get("coordinates")}'; 
1519				var url = '${arrayPDI.get("url")}'; 
1520				var image = '${arrayPDI.get("image")}'; 
1521				var title = '${htmlUtil.escape(arrayPDI.get("title"))}'; 
1522				var description = '${htmlUtil.escape(arrayPDI.get("description"))}'; 
1523				var subtitle = '${htmlUtil.escape(arrayPDI.get("subtitle"))}'; 
1524				var icon = 'fas fa-info'; 
1525				<#if arrayPDI.get("icon")?has_content> 
1526					var icon = '${arrayPDI.get("icon")}'; 
1527				</#if> 
1528				if(latLng){ 
1529				 
1530					latLng = latLng.replaceAll(' ', ''); 
1531					latLng = latLng.split(','); 
1532					 
1533					var fontAwesomeRoutePOIIcon = L.divIcon({ 
1534						className: 'marker-wrapper', 
1535						html: "<div class='marker-icon marker-icon-poi marker-icon-poi-min'><i class='"+icon+"'><!-- icon--></i></div>", 
1536						iconSize: [26, 30], 
1537						iconAnchor: [13, 5] 
1538					}); 
1539					 
1540					var popupContentTemplate = '<a data-articleid="'+poiArticleId+'" href="'+url+'" class="popup popup-service">'+ 
1541							'<span class="popup-image-wrapper" style="background-image: url('+image+');"><img src="'+image+'"/></span>'+ 
1542							'<span class="popup-body">'+ 
1543							'<span class="popup-subtitle">'+subtitle+'</span>'+ 
1544							'<span class="popup-title">'+title+'</span>'+ 
1545							'<span class="popup-desciption">'+description+'</span>'+ 
1546							'</span>'+ 
1547							'</a>'; 
1548					 
1549					var newNodeObject = A.Node.create(popupContentTemplate); 
1550					newNodeObject.on('click', function(event){ 
1551						event.preventDefault(); 
1552						var nodeArticleId = this.attr('data-articleid'); 
1553						${namespace}getArticleDisplay(nodeArticleId); 
1554					}); 
1555 
1556					var marker = L.marker([latLng[0],latLng[1]], 
1557
1558							"icon": fontAwesomeRoutePOIIcon, 
1559							"title": title 
1560
1561					); 
1562					marker.articleId = 'poi-'+poiArticleId; 
1563					marker.bindPopup(newNodeObject.getDOMNode()).addTo(map); 
1564					marker.on('popupopen', function(e) { 
1565						map.panTo(this.getLatLng()); 
1566					}); 
1567					marker.getPopup().on('remove', function() { 
1568						${namespace}closeArticleDisplay(); 
1569					}); 
1570					 
1571					poiMarkers.push(marker); 
1572
1573			</#list> 
1574		</#if> 
1575		A.all('.card.poi').each(function(item){ 
1576			item.on('mouseover', function(event){ 
1577				var articleId = item.getAttribute("data-id"); 
1578				${namespace}markerPopup(articleId, true); 
1579			}); 
1580			item.on('mouseout', function(event){ 
1581				var articleId = item.getAttribute("data-id"); 
1582				${namespace}markerPopup(articleId, false); 
1583			}); 
1584		}); 
1585		 
1586		//RouteNears 
1587		routesNearPolylines = []; 
1588		<#list gpxRoutes as gpxRoute> 
1589			var polylinePopupHTML = '<a href="${gpxRoute.get("url")}" class="popup">'+ 
1590				'<span class="popup-image-wrapper" style="background-image: url(${gpxRoute.get("image")});"><img src="${gpxRoute.get("image")}"/>'+ 
1591				<#--'<span class="ribbon ribbon-circle"><span class="ribbon-text ">${gpxRoute.get("distance")}</span><span class="ribbon-text ribbon-text-meta">km</span></span>'+--> 
1592				'</span>'+ 
1593				'<span class="popup-body">'+ 
1594				'<span class="popup-title" style="color: #${gpxRoute.get("color")};">${htmlUtil.escape(gpxRoute.get("title"))}</span>'+ 
1595				'<span class="d-block"><span class="icon fas fa-map-marker-alt"><span class="hide-accessible">${languageUtil.get(request, "infoasturias-route-lugar-inicio-fin")}</span></span> <span class="value important text-uppercase">${htmlUtil.escape(gpxRoute.get("startEnd"))}</span></span>'+ 
1596				'<span class="d-block"><span class="icon fas fa-bicycle"><span class="hide-accessible">${languageUtil.get(request, "infoasturias-route-recorridos")}</span></span> <span class="value">${htmlUtil.escape(gpxRoute.get("routeTypes"))}</span></span>'+ 
1597				'<span class="d-block"><span class="icon fas fa-mountain"><span class="hide-accessible">${languageUtil.get(request, "infoasturias-route-ibp-index")}</span></span> <span class="important">IBP Index: </span> <span class="value">${gpxRoute.get("ibp")}</span></span>'+ 
1598				'<span class="d-block"><span class="icon fas fa-bicycle"><span class="hide-accessible">${languageUtil.get(request, "mode")}</span></span> <span class="value">${gpxRoute.get("mode")}</span></span>'+ 
1599				'</span>'+ 
1600				'</a>'; 
1601			var polyline = L.polyline(${gpxRoute.get("coordinates")}, {color: '#cacaca', opacity: 1, weight: 3, className: "bordered-polyline"}).bindPopup(polylinePopupHTML); 
1602			polyline.articleId = 'route-near-${gpxRoute.get("articleId")}'; 
1603			polyline.flag = true; 
1604			polyline.on('mouseover', function(e) { 
1605				var layer = e.target; 
1606				layer.setStyle({ 
1607					color: '#cacaca', 
1608					opacity: 1, 
1609					weight: 5 
1610				}); 
1611				layer.bringToFront(); 
1612			}); 
1613			polyline.on('mouseout', function(e) { 
1614				if(this.flag){ 
1615					var layer = e.target; 
1616					layer.setStyle({ 
1617						color: '#cacaca', 
1618						opacity: 0.9, 
1619						weight: 3 
1620					}); 
1621
1622			}); 
1623			polyline.on('click', function(e) { 
1624				var popup = this.getPopup(); 
1625				var layer = e.target; 
1626				layer.setStyle({ 
1627					color: '#cacaca', 
1628					opacity: 1, 
1629					weight: 5 
1630				}); 
1631				this.flag = false; 
1632				layer.bringToFront(); 
1633				popup.setLatLng(this.getCenter()); 
1634				popup.openPopup(); 
1635				map.setView(this.getCenter()); 
1636				var pixelesCenter = map.latLngToContainerPoint(this.getCenter()); 
1637				pixelesCenter.y -= map.getSize().y * 0.2; 
1638				var centerMap = map.containerPointToLatLng(pixelesCenter); 
1639				map.setView(centerMap); 
1640			}); 
1641			polyline.on('popupclose', function(e) { 
1642				var layer = e.target; 
1643				layer.setStyle({ 
1644					color: '#cacaca', 
1645					opacity: 0.9, 
1646					weight: 3 
1647				}); 
1648			}); 
1649			routesNearPolylines.push(polyline); 
1650 
1651			var popupTextStartTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-start')}</span><span class="popup-title">${htmlUtil.escape(gpxRoute.get("title"))}</span></span></span>'; 
1652			var popupTextEndTemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-subtitle">${languageUtil.get(request, 'infoasturias-route-end')}</span><span class="popup-title">${htmlUtil.escape(gpxRoute.get("title"))}</span></span></span>'; 
1653			 
1654			//Markers Route Near Start/End 
1655			var latLng = '${gpxRoute.get("coordinatesStart")}'; 
1656			latLng = latLng.replaceAll(' ', ''); 
1657			latLng = latLng.split(','); 
1658			var markerRouteStart = L.marker([latLng[0],latLng[1]], 
1659
1660					"icon": fontAwesomeRouteNearIcon, 
1661					"title": '${languageUtil.format(request, 'infoasturias-route-start-x', '${htmlUtil.escape(gpxRoute.get("title"))}')}' 
1662
1663			).bindPopup(popupTextStartTemplate).addTo(routesNearPolylinesGroup); 
1664			var latLng = '${gpxRoute.get("coordinatesEnd")}'; 
1665			latLng = latLng.replaceAll(' ', ''); 
1666			latLng = latLng.split(','); 
1667			var markerRouteEnd = L.marker([latLng[0],latLng[1]],  
1668
1669					"icon": fontAwesomeRouteNearIcon, 
1670					"title": '${languageUtil.format(request, 'infoasturias-route-end-x', '${htmlUtil.escape(gpxRoute.get("title"))}')}' 
1671
1672			).bindPopup(popupTextEndTemplate).addTo(routesNearPolylinesGroup); 
1673 
1674			routesNearPolylinesGroup.addLayer(polyline); 
1675 
1676		</#list> 
1677		//List 
1678		A.all('.route-near').each(function(item){ 
1679			item.on('mouseover', function(event){ 
1680				var articleId = item.getAttribute("data-id"); 
1681				${namespace}polylinePopup(articleId, true); 
1682			}); 
1683			item.on('mouseout', function(event){ 
1684				var articleId = item.getAttribute("data-id"); 
1685				${namespace}polylinePopup(articleId, false); 
1686			}); 
1687		}); 
1688 
1689		var gropedOverlayslehen = { 
1690			"${languageUtil.get(locale, "infoasturias-routes-near")}": routesNearPolylinesGroup 
1691
1692		var layerControl = L.control.layers('', gropedOverlayslehen, { 
1693			collapsed: false, 
1694			position:'topleft' 
1695		}); 
1696		layerControl.addTo(map); 
1697	 
1698	//Elevation 
1699 
1700	var elevation_options = { 
1701 
1702		// Default chart colors: theme lime-theme, magenta-theme, ... 
1703		theme: "custom-theme", 
1704		 
1705		useHeightIndicator: true,  
1706 
1707		// Chart container outside/inside map container 
1708		detached: true, 
1709 
1710		// if (detached), the elevation chart container 
1711		elevationDiv: "#elevation-div-${articleId}", 
1712 
1713		// if (!detached) autohide chart profile on chart mouseleave 
1714		autohide: false, 
1715 
1716		// if (!detached) initial state of chart profile control 
1717		collapsed: false, 
1718 
1719		// if (!detached) control position on one of map corners 
1720		position: "topright", 
1721 
1722		// Toggle close icon visibility 
1723		closeBtn: false, 
1724 
1725		// Autoupdate map center on chart mouseover. 
1726		followMarker: true, 
1727 
1728		// Autoupdate map bounds on chart update. 
1729		autofitBounds: false, 
1730 
1731		// Chart distance/elevation units. 
1732		imperial: false, 
1733 
1734		// [Lat, Long] vs [Long, Lat] points. (leaflet default: [Lat, Long]) 
1735		reverseCoords: false, 
1736 
1737		// Acceleration chart profile: true || "summary" || "disabled" || false 
1738		acceleration: false, 
1739 
1740		// Slope chart profile: true || "summary" || "disabled" || false 
1741		slope: false, 
1742 
1743		// Speed chart profile: true || "summary" || "disabled" || false 
1744		speed: false, 
1745 
1746		// Altitude chart profile: true || "summary" || "disabled" || false 
1747		altitude: true, 
1748 
1749		// Display time info: true || "summary" || false 
1750		time: false, 
1751 
1752		// Display distance info: true || "summary" || false 
1753		distance: true, 
1754 
1755		// Summary track info style: "inline" || "multiline" || false 
1756		summary: false, 
1757 
1758		// Download link: "link" || false || "modal" 
1759		downloadLink: false, 
1760 
1761		// Toggle chart ruler filter 
1762		ruler: true, 
1763 
1764		// Toggle chart legend filter 
1765		legend: false, 
1766 
1767		// Toggle "leaflet-almostover" integration 
1768		almostOver: true, 
1769 
1770		// Toggle "leaflet-distance-markers" integration 
1771		distanceMarkers: false, 
1772 
1773		// Toggle "leaflet-edgescale" integration 
1774		edgeScale: false, 
1775 
1776		// Toggle "leaflet-hotline" integration 
1777		hotline: true, 
1778 
1779		// Display track datetimes: true || false 
1780		timestamps: false, 
1781 
1782		// Display track waypoints: true || "markers" || "dots" || false 
1783		waypoints: true, 
1784 
1785		// Toggle custom waypoint icons: true || { associative array of <sym> tags } || false 
1786		wptIcons: false, 
1787 
1788		// Toggle waypoint labels: true || "markers" || "dots" || false 
1789		wptLabels: false, 
1790 
1791		// Render chart profiles as Canvas or SVG Paths 
1792		preferCanvas: false, 
1793 
1794		height: 200, 
1795	}; 
1796 
1797	var controlElevation = L.control.elevation(elevation_options).addTo(map); 
1798	controlElevation.load("${gpxRutaPath}"); 
1799 
1800	//Center 
1801	var polyline = L.polyline(${gpxRoute.get("coordinates")}); 
1802	map.fitBounds(polyline.getBounds()); 
1803 
1804	<#assign poiImages = { 
1805		"Beach": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/playa.png", 
1806		<#--"Bike Trail": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/rutaini-ew.png",--> 
1807		<#--"Bike Trail": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/rutaini-we.png",--> 
1808		<#--"Building": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/ciudad.png",--> 
1809		"City Hall": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/ferrocarril.png", 
1810		<#--"Civil": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/rutafin.png",--> 
1811		<#--"Flag, Green": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/ini-vv.png",--> 
1812		<#--"Flag, Red": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/fin-vv.png",--> 
1813		"Light": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/faro.png", 
1814		<#--"Navaid, Blue": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/cultural.png",--> 
1815		<#--"Navaid, Green": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/natural.png",--> 
1816		<#--"Navaid, Red": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/warning.png",--> 
1817		<#--"Residence": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/pueblo.png",--> 
1818		"Scenic Area": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/paisaje.png", 
1819		"Summit": "/o/turismo-asturias-theme/css/images/cicloturismo/pois/cumbre.png" 
1820	}> 
1821	<#assign poiFontAwesome = { 
1822		"": "fas fa-info", 
1823		"Beach": "fas fa-umbrella-beach", 
1824		<#--"Bike Trail": "",--> 
1825		<#--"Bike Trail": "",--> 
1826		<#--"Building": "",--> 
1827		"City Hall": "fas fa-train", 
1828		<#--"Civil": "",--> 
1829		<#--"Flag, Green": "",--> 
1830		<#--"Flag, Red": "",--> 
1831		"Light": "fas fa-monument", 
1832		<#--"Navaid, Blue": "",--> 
1833		<#--"Navaid, Green": "",--> 
1834		<#--"Navaid, Red": "",--> 
1835		<#--"Residence": "",--> 
1836		"Scenic Area": "fas fa-camera", 
1837		"Summit": "fas fa-mountain" 
1838	}> 
1839	 
1840	<#if validator.isNotNull(gpxPOIRoute)> 
1841		<#if gpxPOIRoute.has("wpts") && validator.isNotNull(gpxPOIRoute.has("wpts"))> 
1842			<#assign wptJSONArray = jsonFactoryUtil.createJSONArray(gpxPOIRoute.get("wpts"))! /> 
1843			<#list 0..wptJSONArray.length() as i> 
1844				<#assign wptJSONObject = wptJSONArray.get(i)! /> 
1845				<#if validator.isNotNull(wptJSONObject)> 
1846 
1847					<#assign wptName = wptJSONObject.get("name")! /> 
1848					<#assign wptSym = wptJSONObject.get("sym")! /> 
1849					<#assign wptLat = wptJSONObject.get("lat")! /> 
1850					<#assign wptLon = wptJSONObject.get("lon")! /> 
1851					<#assign wptEle = wptJSONObject.get("ele")! /> 
1852					<#assign wptSymImage = poiImages[wptSym]! /> 
1853					<#assign wptSymFontAwesome = poiFontAwesome[wptSym]! /> 
1854					<#if validator.isNotNull(wptSymFontAwesome)> 
1855 
1856						var divIcon = L.divIcon({ 
1857							className: 'marker-wrapper', 
1858							html: "<div class='marker-icon marker-icon-poi marker-icon-poi-min'><i class='${wptSymFontAwesome}'><!-- icon--></i></div>", 
1859							iconSize: [26, 30], 
1860							iconAnchor: [13, 30] 
1861						}); 
1862						var popupPOITemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-title">${htmlUtil.escape(wptName)}</span></span></span>'; 
1863						var marker = L.marker([${wptLat}, ${wptLon}],  
1864
1865								"icon": divIcon, 
1866								"title": '${htmlUtil.escape(wptName)}' 
1867
1868						).bindPopup(popupPOITemplate).addTo(map); 
1869						marker.on('popupopen', function(e) { 
1870							map.panTo(this.getLatLng()); 
1871						}); 
1872					</#if> 
1873				</#if> 
1874			</#list> 
1875		</#if> 
1876 
1877		<#-- TODO --> 
1878		<#assign dlFileEntryGPXPOI = dlTool.getDLFileEntryByPath(Documentos.GPXPOIRuta.data)!/> 
1879		<#if validator.isNotNull(dlFileEntryGPXPOI)> 
1880			<#assign document = saxReaderUtil.read(dlFileEntryGPXPOI.getContentStream())/> 
1881			<#assign root = document.getRootElement()/> 
1882			<#assign trks = root.elements("trk")!> 
1883			<#if validator.isNotNull(trks)> 
1884				<#list trks as trk> 
1885					<#assign trkName = trk.elementText("name")!> 
1886					<#assign trkseg = trk.element("trkseg")!> 
1887					<#if validator.isNotNull(trkseg)> 
1888						<#assign trkpts = trkseg.elements("trkpt")!> 
1889						<#if validator.isNotNull(trkpts)> 
1890							var trksegsLatLngs = []; 
1891							<#list trkpts as trkpt> 
1892								<#assign trksegLat = trkpt.attributeValue("lat")!> 
1893								<#assign trksegLon = trkpt.attributeValue("lon")!> 
1894								<#if validator.isNotNull(trksegLat) && validator.isNotNull(trksegLon)> 
1895									var trksegsLatLng = [${trksegLat}, ${trksegLon}]; 
1896									trksegsLatLngs.push(trksegsLatLng); 
1897								</#if> 
1898							</#list> 
1899							if(trksegsLatLngs.length>0){ 
1900								var popupGpxPOITemplate = '<span class="popup popup-service"><span class="popup-body"><span class="popup-title">${htmlUtil.escape(trkName)}</span></span></span>'; 
1901								var trkPolyline = L.polyline(trksegsLatLngs, {color: '#006db0', dashArray: '5, 10', lineCap: 'square', opacity: 1, weight: 5, className: "bordered-polyline-white"}).bindPopup(popupGpxPOITemplate).addTo(map); 
1902
1903						</#if> 
1904					</#if> 
1905				</#list> 
1906			</#if> 
1907		</#if> 
1908	</#if> 
1909	 
1910	//Functions 
1911	function ${namespace}markerPopup(articleId, hover){ 
1912		for (var i in poiMarkers){ 
1913			var marker = poiMarkers[i]; 
1914			var id = marker.articleId; 
1915			if (id == articleId){ 
1916				if(hover){ 
1917					marker.openPopup(); 
1918					map.panTo(marker.getLatLng()); 
1919				}else{ 
1920					//marker.closePopup(); 
1921
1922			}; 
1923
1924
1925	 
1926	function ${namespace}markerServicePopup(articleId, hover){ 
1927		for (var i in serviceMarkers){ 
1928			var marker = serviceMarkers[i]; 
1929			var id = marker.articleId; 
1930			if (id == articleId){ 
1931				if(hover){ 
1932					map.addLayer(marker); 
1933					marker.openPopup(); 
1934					map.panTo(marker.getLatLng()); 
1935				}else{ 
1936					//map.removeLayer(marker); 
1937					//marker.closePopup(); 
1938
1939			}; 
1940
1941
1942	 
1943	function ${namespace}polylinePopup(articleId, hover){ 
1944		for (var i in routesNearPolylines){ 
1945			var polyline = routesNearPolylines[i]; 
1946			if (map.hasLayer(routesNearPolylinesGroup)){ 
1947				var id = polyline.articleId; 
1948				if (id == articleId){ 
1949					if(hover){ 
1950						polyline.openPopup(); 
1951						polyline.setStyle({ 
1952							weight: 5, 
1953							opacity: 1 
1954						}); 
1955						map.panTo(polyline.getCenter()); 
1956						polyline.bringToFront(); 
1957					}else{ 
1958						polyline.setStyle({ 
1959							weight: 3, 
1960							opacity: 0.9 
1961						}); 
1962						polyline.closePopup(); 
1963
1964
1965
1966
1967
1968	 
1969	function ${namespace}toggleMarkersServicesStructure(structureId){ 
1970		 
1971		var item = A.one('#vocabulary-structure-id-'+structureId); 
1972		var button = A.one('#button-vocabulary-structure-id-'+structureId); 
1973		if(item){ 
1974			 
1975			var vocabularyWrapper = item.ancestor('.vocabulary-wrapper'); 
1976			if(!vocabularyWrapper.hasClass('selected')){ 
1977				vocabularyWrapper.all('.categories input').attr('checked',''); 
1978				vocabularyWrapper.all('.categories input').each(function(cat){ 
1979					cat.simulate('click'); 
1980				}); 
1981				vocabularyWrapper.addClass('selected'); 
1982				if(button){ 
1983					button.addClass('selected'); 
1984
1985			}else{ 
1986				vocabularyWrapper.all('.categories input').attr('checked','checked'); 
1987				vocabularyWrapper.all('.categories input').each(function(cat){ 
1988					cat.simulate('click'); 
1989				}); 
1990				vocabularyWrapper.removeClass('selected'); 
1991				if(button){ 
1992					button.removeClass('selected'); 
1993					var allNoSelectedButtons = true; 
1994					A.all('.button-vocabulary-structure').each(function(item){ 
1995						if(item.hasClass('selected')) 
1996							allNoSelectedButtons = false; 
1997					}); 
1998
1999
2000
2001
2002 
2003	Liferay.provide(window, '${namespace}closeArticleDisplay', function(){ 
2004		A.one("#article-display-container").hide('fadeOut'); 
2005		A.one("#search-container").show('fadeIn'); 
2006	}); 
2007 
2008	Liferay.provide(window, '${namespace}openArticleDisplay', function(){ 
2009		A.one("#search-container").hide(); 
2010		A.one("#article-display-container").show('fadeIn'); 
2011 
2012		//Map 
2013		var articleDisplayContainerMap = A.one("#article-display-container").one('.article-section-map script[type="text/javascript"]'); 
2014		if(articleDisplayContainerMap) 
2015			eval(articleDisplayContainerMap.html()); 
2016 
2017		//Scroll 
2018		var to = A.one('#article-display-container'); 
2019		if(to){ 
2020			var position = 100; 
2021			var toggleMap = A.one('#toggle-map'); 
2022			if(toggleMap && toggleMap.hasClass('active')){ 
2023				position = 0; 
2024				to = A.one('body'); 
2025
2026			var anim = new A.Anim({ 
2027				duration: 0.2, 
2028				node:  A.getWin(), 
2029				to: { 
2030					scroll: [0, to.getY() - position] 
2031
2032			}).run(); 
2033
2034	}); 
2035 
2036    Liferay.provide(window, '${namespace}getArticleDisplay', function(articleId){ 
2037	 
2038        var url = "${themeDisplay.getURLPortal()+themeDisplay.getLayout().getFriendlyURL(locale)}?p_p_id=${themeDisplay.getPortletDisplay().getId()}&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_resource_id=journalDisplayContent&p_p_cacheability=cacheLevelPage&_${themeDisplay.getPortletDisplay().getId()}_articleId="+articleId;	 
2039        A.io.request(url, { 
2040            method: 'GET', 
2041            type: 'HTML', 
2042            on: { 
2043                success: function() { 
2044                    var journalArticleContentDisplay = this.get('responseData'); 
2045                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("col-md-6", "col-12"); 
2046                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-wrapper", ""); 
2047                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-table", ""); 
2048                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-table-row", ""); 
2049                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info-table-cell", ""); 
2050                    journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-info", "article-info m-0 px-4 pt-4"); 
2051					//journalArticleContentDisplay = journalArticleContentDisplay.replaceAll("article-section-map", "article-section-map hide"); 
2052                    A.one("#article-display").html(journalArticleContentDisplay); 
2053                    ${namespace}openArticleDisplay(); 
2054
2055
2056        }); 
2057	}); 
2058		 
2059	</#if> 
2060 
2061	var closeArticleDisplayNode = A.one("#close-article-display"); 
2062	if(closeArticleDisplayNode){ 
2063		closeArticleDisplayNode.on('click', function(event) { 
2064			${namespace}closeArticleDisplay(); 
2065		}); 
2066
2067 
2068	A.all(".template-layout-map .item-card").each(function(item) { 
2069        item.on("click", function(event) { 
2070            event.preventDefault(); 
2071            var articleId = item.attr("data-articleid"); 
2072            ${namespace}getArticleDisplay(articleId); 
2073        }); 
2074    }); 
2075	 
2076	//Map Mobile Toggle 
2077	mapMobileToggle('${languageUtil.get(request, "infoasturias-abrir-mapa")}','${languageUtil.get(request, "infoasturias-cerrar-mapa")}', map, '.leaflet-elevation-wrapper'); 
2078	var toggleMap = A.one('#toggle-map'); 
2079	if(toggleMap){ 
2080		toggleMap.on('click', function(event){ 
2081			A.one('.template-layout-map').toggleClass('template-layout-map-mobile'); 
2082			A.one('#content').toggleClass('content-map-mobile'); 
2083			map.closePopup(); 
2084			if(this.hasClass('active')){ 
2085				${namespace}closeArticleDisplay(); 
2086				//Scroll 
2087				var to = A.one('body'); 
2088				if(to){ 
2089					var anim = new A.Anim({ 
2090						duration: 0.2, 
2091						node:  A.getWin(), 
2092						to: { 
2093							scroll: [0, to.getY()-100] 
2094
2095					}).run(); 
2096
2097
2098		}); 
2099
2100     
2101</@>