Si è verificato un errore nell'elaborarazione del modello.
Java method "as.asac.template.tools.DLToolImpl.getDLFileEntryByPath(String)" threw an exception when invoked on as.asac.template.tools.DLToolImpl object "as.asac.template.tools.DLToolImpl@2b663b5e"; see cause exception in the Java stack trace.

----
FTL stack trace ("~" means nesting-related):
	- Failed at: #assign dlFileEntry = dlTool.getDLFil...  [in template "37703#37743#1558463" at line 243, column 81]
----
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 assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService") /> 
6<#assign assetVocabularyLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetVocabularyLocalService") /> 
7 
8<#-- Reserved vbles --> 
9<#assign title = .vars['reserved-article-title'].data> 
10<#assign articleId=.vars["reserved-article-id"].data /> 
11<#assign description=.vars["reserved-article-description"].data /> 
12<#assign smallImageUrl=.vars["reserved-article-small-image-url"].data /> 
13<#assign date=.vars["reserved-article-display-date"].data /> 
14<#assign request = .vars['request']> 
15 
16<#-- Init --> 
17<#assign assetEntry = journalTool.getAssetEntryByArticleId(groupId, articleId)> 
18<#assign journalArticle = journalTool.getJournalArticleByAssetEntry(assetEntry)> 
19<#assign articleURL = themeDisplay.getURLPortal()+themeDisplay.getURLCurrent()> 
20<#assign articleSocialBookmarks = themeDisplay.getThemeSetting("article-social-bookmarks")!> 
21<#assign layoutSetBannerPath = layoutTool.getLayoutSetBannerPath(groupId, themeDisplay.getLayout().isPrivateLayout())!> 
22<#assign articleMainImageThumbnail3 = dlTool.getThumbnail(smallImageUrl, "3", layoutSetBannerPath)! /> 
23<#assign articleMainImageThumbnail1 = dlTool.getThumbnail(smallImageUrl, "1")! /> 
24 
25<#assign ddmStructureNameNormalize = "template-${friendlyURLNormalizerTool.normalize(journalArticle.getDDMStructure().getName(localeUtil.getDefault()))}" /> 
26 
27<#function sanitizeURL url> 
28	<#if !url?has_content> 
29		<#return "" /> 
30	</#if> 
31	<#assign urlTrimmed = url?trim /> 
32	<#if urlTrimmed?starts_with("javascript:") || urlTrimmed?starts_with("data:") || urlTrimmed?starts_with("vbscript:")> 
33		<#return "" /> 
34	</#if> 
35	<#return htmlUtil.escapeHREF(urlTrimmed) /> 
36</#function> 
37 
38<#function isExternalURL url> 
39	<#if !url?has_content> 
40		<#return false /> 
41	</#if> 
42	<#assign portalURLlc = themeDisplay.getPortalURL()?lower_case /> 
43	<#assign urlLC = url?lower_case /> 
44	<#assign isHttp = urlLC?starts_with("http://") || urlLC?starts_with("https://") /> 
45	<#assign isInternal = (url?starts_with("/")) || (isHttp && urlLC?starts_with(portalURLlc)) /> 
46	<#return isHttp && !isInternal /> 
47</#function> 
48 
49<#-- Build --> 
50<#if Nombre.data?has_content> 
51	<#assign title = Nombre.data> 
52</#if> 
53<#assign altImgDestacada = title /> 
54<#if AltImagenDestacada ??> 
55	<#if validator.isNotNull(AltImagenDestacada.getData())> 
56		<#assign altImgDestacada = AltImagenDestacada.getData() /> 
57	</#if> 
58</#if> 
59<#assign articleMainImageThumbnail3Safe = sanitizeURL(articleMainImageThumbnail3) /> 
60<#assign articleMainImageThumbnail1Safe = sanitizeURL(articleMainImageThumbnail1) /> 
61 
62<#-- Validaciones de TAB --> 
63<#assign limitacionPeso = (AsturiasMascotas.LimitacionPeso.data)!"" /> 
64<#assign NumeroMaximoPersona = (AsturiasMascotas.NumeroMaximoPersona.data)!"" /> 
65<#assign NumeroMaximoInterior = (AsturiasMascotas.NumeroMaximoInterior.data)!"" /> 
66<#assign AccesoInterior = (AsturiasMascotas.AccesoInterior.data)!"" /> 
67<#assign admitePPP = (AsturiasMascotas.AdmitePPP.data)!"" /> 
68<#assign AccesoTerraza = (AsturiasMascotas.AccesoTerraza.data)!"" /> 
69<#assign otrasMascotas = (AsturiasMascotas.OtrasMascotas.data)!"" /> 
70<#assign otrosAnimales = (AsturiasMascotas.OtrosAnimales.data)!"" /> 
71<#assign detalleNormas = (AsturiasMascotas.DetalleNormas.data)!"" /> 
72 
73<#assign hasIconos = limitacionPeso?has_content || NumeroMaximoPersona?has_content || NumeroMaximoInterior?has_content || AccesoInterior?has_content /> 
74<#assign hasNormas = admitePPP?has_content || AccesoTerraza?has_content || otrasMascotas?has_content || detalleNormas?has_content /> 
75 
76<article class="template ${ddmStructureNameNormalize}"> 
77	<header class="article-header-wrapper row no-gutters"> 
78		<div class="article-header-container article-header-container-static"> 
79			<div class="container"> 
80				<div class="row no-gutters"> 
81					<div class="col-md-6"> 
82						<div class="article-image" style="background-image: url('${sanitizeURL(articleMainImageThumbnail3Safe)}')" role="img" aria-label="${altImgDestacada}"> 
83							<img class="hide-accessible" src="${sanitizeURL(articleMainImageThumbnail3Safe)}" alt=""/> 
84						</div> 
85					</div> 
86					<div class="article-info-wrapper col-md-6"> 
87						<div class="article-info"> 
88							<h2 class="article-title">${title}</h2> 
89							<div class="article-list-wrapper">					 
90								<ul class="article-list list-unstyled article-list-info"> 
91									<li class="article-list-item mb-4"> 
92										<span class="fas fa-map-marker-alt" aria-hidden="true"></span> 
93										<span class="hide-accessible">${languageUtil.get(request,"location")}</span> 
94										<span class="field-wrapper"> 
95											<#if Contacto.Concejo?? && Contacto.Concejo.data?has_content> 
96												<span class="important">${Contacto.Concejo.data}</span> 
97											</#if> 
98											<#if Contacto.Zona?? && Contacto.Zona.data?has_content> 
99												<span class="text d-block">${Contacto.Zona.data}</span> 
100											</#if> 
101										</span> 
102									</li> 
103									<#if Contacto.Direccion?? && Contacto.Direccion.data?has_content || Contacto.CP?? && Contacto.CP.data?has_content || Contacto.Localidad?? && Contacto.Localidad.data?has_content> 
104										<li class="article-list-item"> 
105											<span class="far fa-address-card" aria-hidden="true"></span> 
106											<span class="hide-accessible">${languageUtil.get(request,"address")}</span> 
107											<span class="field-wrapper"> 
108												<span class="field">${languageUtil.get(request, "address")}:</span> 
109												<span class="text">${(Contacto.Direccion.data)!}</span><span aria-hidden="true"> ■ </span> 
110												<span class="text">${(Contacto.CP.data)!} - ${(Contacto.Localidad.data)!}</span> 
111											</span> 
112										</li> 
113									</#if> 
114									 
115									<#if Contacto.Telefono?? && Contacto.Telefono.data?has_content>									 
116										<li class="article-list-item"> 
117											<span class="fas fa-phone-alt" aria-hidden="true"></span> 
118											<span class="hide-accessible">${languageUtil.get(request, "phone")}</span> 
119											<span class="field-wrapper"> 
120												<span class="field">${languageUtil.get(request, "phone")}:</span> 
121												<#list Contacto.Telefono.getSiblings() as telephone> 
122													<#if telephone.data?has_content> 
123														<#assign rawTelefono = telephone.data?trim /> 
124														<#assign cleanTelefono = rawTelefono?replace("\\(.*?\\)", "", "r") /> 
125														<#assign numberTelefono = cleanTelefono?replace("[^0-9]", "", "r") /> 
126														<#assign numberLength = numberTelefono?length /> 
127														<#if numberLength == 9> 
128															<#assign hrefNumber = "+34${numberTelefono}" /> 
129														<#else> 
130															<#assign hrefNumber = numberTelefono /> 
131														</#if> 
132														<span class="text"> 
133															<a href="tel:${htmlUtil.escapeHREF(hrefNumber)}" aria-label="${languageUtil.format(request, 'call', rawTelefono)}"> 
134																${rawTelefono} 
135															</a> 
136															<#if !telephone?is_last><span aria-hidden="true"> | </span></#if> 
137														</span> 
138													</#if> 
139												</#list> 
140											</span> 
141										</li> 
142									</#if> 
143 
144									<#if Contacto.Email?? && Contacto.Email.data?has_content> 
145										<li class="article-list-item"> 
146											<span class="far fa-envelope" aria-hidden="true"></span> 
147											<span class="hide-accessible">${languageUtil.get(request,"email")}</span> 
148											<span class="field-wrapper"> 
149												<span class="field">${languageUtil.get(request, "email")}:</span> 
150												<span class="text"> 
151													<#list Contacto.Email.getSiblings() as Item> 
152														<#if Item.data?trim?has_content> 
153															<#assign emailAddress = Item.data?trim /> 
154															<a href="mailto:${htmlUtil.escapeHREF(emailAddress)}" aria-label="${languageUtil.format(request,'email-to', emailAddress)}"> 
155																${emailAddress} 
156															</a> 
157															<#if Item_has_next>, </#if> 
158														</#if> 
159													</#list> 
160												</span> 
161											</span> 
162										</li> 
163									</#if> 
164 
165									<#if Contacto.Web?? && Contacto.Web.getSiblings()?has_content> 
166										<#assign hasValidURL = false /> 
167										<#list Contacto.Web.getSiblings() as web> 
168											<#if web.data?trim?has_content> 
169												<#assign linkURL = web.data?trim /> 
170												<#if !linkURL?starts_with("javascript:") && !linkURL?starts_with("data:") && !linkURL?starts_with("vbscript:")> 
171													<#assign hasValidURL = true /> 
172													<#break> 
173												</#if> 
174											</#if> 
175										</#list> 
176										<#if hasValidURL> 
177											<li class="article-list-item web"> 
178												<span class="fas fa-link" aria-hidden="true"></span> 
179												<span class="field-wrapper d-inline-flex flex-wrap align-items-center"> 
180													<span class="field mr-1">${languageUtil.get(request, "site")}:</span> 
181													<#assign webCount = 0 /> 
182													<#list Contacto.Web.getSiblings() as web> 
183														<#if web.data?trim?has_content> 
184															<#assign linkURL = web.data?trim /> 
185															<#if !linkURL?starts_with("javascript:") && !linkURL?starts_with("data:") && !linkURL?starts_with("vbscript:")> 
186																<#assign webCount = webCount + 1 /> 
187															</#if> 
188														</#if> 
189													</#list> 
190													<#assign validIndex = 0 /> 
191													<#list Contacto.Web.getSiblings() as web> 
192														<#if web.data?trim?has_content> 
193															<#assign linkURL = web.data?trim /> 
194															<#if !linkURL?starts_with("javascript:") && !linkURL?starts_with("data:") && !linkURL?starts_with("vbscript:")> 
195																<#if !stringUtil.startsWith(linkURL, "http://") && !stringUtil.startsWith(linkURL, "https://")> 
196																	<#assign linkURL = "https://${linkURL}" /> 
197																</#if> 
198																<#assign validIndex = validIndex + 1 /> 
199																<#assign linkNumber = validIndex /> 
200																<a href="${htmlUtil.escapeHREF(linkURL)}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.get(request, 'site')} ${linkNumber} - ${htmlUtil.escape(title)} ${languageUtil.get(request, 'opens-new-window')}" class="text d-inline-flex align-items-center text-nowrap"> 
201																	<#if webCount gt 1> 
202																		${languageUtil.get(request, "visit")} ${linkNumber} 
203																	<#else> 
204																		${languageUtil.get(request, "visit")} 
205																	</#if> 
206																	<span class="fas fa-external-link-alt ml-1 font-size-08" aria-hidden="true"></span> 
207																</a> 
208																<#if validIndex lt webCount> 
209																	<span class="mx-2 text-muted" aria-hidden="true">|</span> 
210																</#if> 
211															</#if> 
212														</#if> 
213													</#list> 
214												</span> 
215											</li> 
216										</#if> 
217									</#if>	 
218									 
219									<#if Informacion.Horario?? && Informacion.Horario.data?has_content || Informacion.Tarifas?? && Informacion.Tarifas.data?has_content> 
220										<li class="article-list-item web"> 
221											<span class="fas fa-clock" aria-hidden="true"></span> 
222											<span class="field-wrapper"> 
223												<span class="field">${languageUtil.get(request, "infoasturias-horarios-y-tarifas")}:</span> 
224												<span class="text"> 
225													<#-- [A2] tabindex="0" eliminado: <a href> es focusable nativo --> 
226													<a href="#tabContent2" class="internal-tab-link" data-tab-heading="tabHeading2" data-tab-content="tabContent2" aria-label="${languageUtil.get(request, 'infoasturias-horarios-y-tarifas')}"> 
227														${languageUtil.get(request, "view")} 
228														<span class="fas fa-caret-right ml-1 font-size-08" aria-hidden="true"></span> 
229													</a> 
230												</span> 
231											</span> 
232										</li> 
233									</#if> 
234									<#if Informacion.Visit?? && Informacion.Visit.data?has_content> 
235										<li class="article-list-item web"> 
236											<span class="fas fa-door-open" aria-hidden="true"></span> 
237											<span class="field-wrapper"> 
238												<span class="field">${Informacion.Visit.data}</span> 
239											</span> 
240										</li> 
241									</#if>		 
242									<#if Descargas?? && Descargas.Archivo?? && Descargas.Archivo.data?has_content> 
243										<#assign dlFileEntry = dlTool.getDLFileEntryByPath(Descargas.Archivo.data) /> 
244										<#if (dlFileEntry)!?has_content> 
245											<#assign ext = dlFileEntry.getExtension()! /> 
246											<li class="article-list-item document document-${htmlUtil.escape(ext)}"> 
247												<span class="fas fa-file" aria-hidden="true"></span> 
248												<span class="hide-accessible">${languageUtil.get(request,"related-documents")}</span> 
249												<span class="field-wrapper"> 
250													<span class="field">${languageUtil.get(request, "related-documents")}:</span> 
251													<span class="text"> 
252														<#list Descargas.Archivo.getSiblings() as Item> 
253															<#if Item.data?has_content> 
254																<#assign dlFileEntry = dlTool.getDLFileEntryByPath(Item.data) /> 
255																<#if validator.isNotNull(dlFileEntry)> 
256																	<#assign downloadURL = sanitizeURL("/documents/${groupId}/${dlFileEntry.getUuid()}") /> 
257																	<#assign fileSize = dlFileEntry.getSize() /> 
258																	<#assign fileSizeKB = (fileSize / 1024)?round /> 
259																	<#assign fileExt = dlFileEntry.getExtension()?upper_case /> 
260																	<#if Item.ArchivoTitulo.data?has_content> 
261																		<#assign fileName = Item.ArchivoTitulo.data /> 
262																	<#else> 
263																		<#assign fileName = dlFileEntry.getTitle() /> 
264																	</#if> 
265																	<#assign downloadLabel = languageUtil.get(request, 'download') /> 
266																	<#assign formatLabel = languageUtil.get(request, 'format') /> 
267																	<#assign sizeLabel = languageUtil.get(request, 'size') /> 
268																	<#assign kbLabel = languageUtil.get(request, 'kb') /> 
269																	<#assign ariaLabelText = "${downloadLabel} ${fileName}, ${formatLabel} ${fileExt}, ${sizeLabel} ${fileSizeKB} ${kbLabel}" /> 
270																	<a href="${downloadURL}" download aria-label="${ariaLabelText}"> 
271																		${fileName} 
272																		<span class="file-info" aria-hidden="true"> 
273																			(${fileExt}, ${fileSizeKB} KB) 
274																		</span> 
275																		<span class="fas fa-download ml-1" aria-hidden="true"></span> 
276																	</a> 
277																	<#if Item_has_next>, </#if> 
278																</#if> 
279															</#if> 
280														</#list> 
281													</span> 
282												</span>		 
283											</li> 
284										</#if> 
285									</#if> 
286								</ul> 
287							</div> 
288							<#-- [A5] Condición de redes sociales: TikTok unificado (verificar nombre exacto del campo DDM) --> 
289							<#if (RedesSociales.Facebook.data)!?has_content || (RedesSociales.Twitter.data)!?has_content || (RedesSociales.Instagram.data)!?has_content || (RedesSociales.Youtube.data)!?has_content || (RedesSociales.TikTok.data)!?has_content || (RedesSociales.Pinterest.data)!?has_content || (RedesSociales.Rss.data)!?has_content || (RedesSociales.OtrosCanales.NombreCanal.data)!?has_content> 
290								<div class="article-socials-wrapper mt-4"> 
291									<div class="socials-wrapper"> 
292										<div class="socials"> 
293											<ul class="list-inline items socials"> 
294												<#if RedesSociales.Facebook.data?has_content> 
295													<#assign linkURLRaw = RedesSociales.Facebook.data?trim /> 
296													<#if !linkURLRaw?starts_with("http://") && !linkURLRaw?starts_with("https://")> 
297														<#assign linkURLRaw = "https://${linkURLRaw}" /> 
298													</#if> 
299													<#assign linkURL = sanitizeURL(linkURLRaw) /> 
300													<#if linkURL?has_content> 
301														<li class="list-inline-item item facebook"> 
302															<a href="${linkURL}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.format(request,'go-to-x','Facebook')} ${languageUtil.get(request,'opens-new-window')}"> 
303																<span class="fab fa-facebook-f" aria-hidden="true"></span> 
304																<span class="hide-accessible">${languageUtil.format(request,'go-to-x','Facebook')}</span> 
305															</a> 
306														</li> 
307													</#if> 
308												</#if> 
309												<#if RedesSociales.Twitter.data?has_content> 
310													<#assign linkURLRaw = RedesSociales.Twitter.data?trim /> 
311													<#if !linkURLRaw?starts_with("http://") && !linkURLRaw?starts_with("https://")> 
312														<#assign linkURLRaw = "https://${linkURLRaw}" /> 
313													</#if> 
314													<#assign linkURL = sanitizeURL(linkURLRaw) /> 
315													<#if linkURL?has_content> 
316														<li class="list-inline-item item twitter"> 
317															<a href="${linkURL}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.format(request,'go-to-x','X (Twitter)')} ${languageUtil.get(request,'opens-new-window')}"> 
318																<span class="fa-brands fa-x-twitter" aria-hidden="true"></span> 
319																<span class="hide-accessible">${languageUtil.format(request,'go-to-x','X (Twitter)')}</span> 
320															</a> 
321														</li> 
322													</#if> 
323												</#if> 
324												<#if RedesSociales.Instagram.data?has_content> 
325													<#assign linkURLRaw = RedesSociales.Instagram.data?trim /> 
326													<#if !linkURLRaw?starts_with("http://") && !linkURLRaw?starts_with("https://")> 
327														<#assign linkURLRaw = "https://${linkURLRaw}" /> 
328													</#if> 
329													<#assign linkURL = sanitizeURL(linkURLRaw) /> 
330													<#if linkURL?has_content> 
331														<li class="list-inline-item item instagram"> 
332															<a href="${linkURL}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.format(request,'go-to-x','Instagram')} ${languageUtil.get(request,'opens-new-window')}"> 
333																<span class="fab fa-instagram" aria-hidden="true"></span> 
334																<span class="hide-accessible">${languageUtil.format(request,'go-to-x','Instagram')}</span> 
335															</a> 
336														</li> 
337													</#if> 
338												</#if> 
339												<#if RedesSociales.Youtube.data?has_content> 
340													<#assign linkURLRaw = RedesSociales.Youtube.data?trim /> 
341													<#if !linkURLRaw?starts_with("http://") && !linkURLRaw?starts_with("https://")> 
342														<#assign linkURLRaw = "https://${linkURLRaw}" /> 
343													</#if> 
344													<#assign linkURL = sanitizeURL(linkURLRaw) /> 
345													<#if linkURL?has_content> 
346														<li class="list-inline-item item youtube"> 
347															<a href="${linkURL}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.format(request,'go-to-x','YouTube')} ${languageUtil.get(request,'opens-new-window')}"> 
348																<span class="fab fa-youtube" aria-hidden="true"></span> 
349																<span class="hide-accessible">${languageUtil.format(request,'go-to-x','YouTube')}</span> 
350															</a> 
351														</li> 
352													</#if> 
353												</#if> 
354												<#-- [A5] TikTok: nombre unificado a TikTok en renderizado y condición --> 
355												<#if (RedesSociales.TikTok.data)!?has_content> 
356													<#assign linkURLRaw = RedesSociales.TikTok.data?trim /> 
357													<#if !linkURLRaw?starts_with("http://") && !linkURLRaw?starts_with("https://")> 
358														<#assign linkURLRaw = "https://${linkURLRaw}" /> 
359													</#if> 
360													<#assign linkURL = sanitizeURL(linkURLRaw) /> 
361													<#if linkURL?has_content> 
362														<li class="list-inline-item item tiktok"> 
363															<a href="${linkURL}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.format(request,'go-to-x','TikTok')} ${languageUtil.get(request,'opens-new-window')}"> 
364																<span class="fab fa-tiktok" aria-hidden="true"></span> 
365																<span class="hide-accessible">${languageUtil.format(request,'go-to-x','TikTok')}</span> 
366															</a> 
367														</li> 
368													</#if> 
369												</#if> 
370												<#if RedesSociales.Pinterest.data?has_content> 
371													<#assign linkURLRaw = RedesSociales.Pinterest.data?trim /> 
372													<#if !linkURLRaw?starts_with("http://") && !linkURLRaw?starts_with("https://")> 
373														<#assign linkURLRaw = "https://${linkURLRaw}" /> 
374													</#if> 
375													<#assign linkURL = sanitizeURL(linkURLRaw) /> 
376													<#if linkURL?has_content> 
377														<li class="list-inline-item item pinterest"> 
378															<a href="${linkURL}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.format(request,'go-to-x','Pinterest')} ${languageUtil.get(request,'opens-new-window')}"> 
379																<span class="fab fa-pinterest-p" aria-hidden="true"></span> 
380																<span class="hide-accessible">${languageUtil.format(request,'go-to-x','Pinterest')}</span> 
381															</a> 
382														</li> 
383													</#if> 
384												</#if> 
385												<#if RedesSociales.Rss.data?has_content> 
386													<#assign linkURLRaw = RedesSociales.Rss.data?trim /> 
387													<#if !linkURLRaw?starts_with("http://") && !linkURLRaw?starts_with("https://")> 
388														<#assign linkURLRaw = "https://${linkURLRaw}" /> 
389													</#if> 
390													<#assign linkURL = sanitizeURL(linkURLRaw) /> 
391													<#if linkURL?has_content> 
392														<li class="list-inline-item item rss"> 
393															<a href="${linkURL}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.format(request,'go-to-x','RSS')} ${languageUtil.get(request,'opens-new-window')}"> 
394																<span class="fas fa-rss" aria-hidden="true"></span> 
395																<span class="hide-accessible">${languageUtil.format(request,'go-to-x','RSS')}</span> 
396															</a> 
397														</li> 
398													</#if> 
399												</#if> 
400												<#if RedesSociales.OtrosCanales.NombreCanal??> 
401													<#list RedesSociales.OtrosCanales.NombreCanal.getSiblings() as Canal> 
402														<#if Canal.CanalUrl.data?trim?has_content && Canal.data?trim?has_content> 
403															<#assign linkURLRaw = Canal.CanalUrl.data?trim /> 
404															<#assign canalName = Canal.data?trim /> 
405															<#if !linkURLRaw?starts_with("http://") && !linkURLRaw?starts_with("https://")> 
406																<#assign linkURLRaw = "https://${linkURLRaw}" /> 
407															</#if> 
408															<#assign linkURL = sanitizeURL(linkURLRaw) /> 
409															<#if linkURL?has_content> 
410																<li class="list-inline-item item other-channel"> 
411																	<a href="${linkURL}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.format(request,'go-to-x', canalName)} ${languageUtil.get(request,'opens-new-window')}"> 
412																		<span class="fas fa-share-alt" aria-hidden="true"></span> 
413																		<span class="hide-accessible">${languageUtil.format(request,'go-to-x', canalName)}</span> 
414																	</a> 
415																</li> 
416															</#if> 
417														</#if> 
418													</#list> 
419												</#if> 
420											</ul> 
421										</div> 
422									</div> 
423								</div> 
424							</#if>							 
425						</div> 
426					</div> 
427				</div> 
428			</div> 
429		</div>  
430	</header> 
431	 
432	<div class="sheet sheet-lg"> 
433		<div class="article-section">		 
434			<#if (Informacion.Titulo.data)!?has_content> 
435				<div class="article-great"> 
436					${Informacion.Titulo.data} 
437				</div>	 
438			</#if> 
439			<#if Contenido?? && Contenido.getSiblings()?has_content> 
440				<#list Contenido.getSiblings() as Item> 
441					<#assign tituloData = (Item.ContenidoTitulo.data)!"" /> 
442					<#assign textoData = (Item.ContenidoTexto.data)!"" /> 
443					<#assign imagenData = (Item.ContenidoTexto.ContentImagen.data)!"" /> 
444					<#if tituloData?has_content || textoData?has_content || imagenData?has_content> 
445						<#assign tipoHeading = (Item.ContenidoTitulo.headingTipo.data)!"" /> 
446						<#assign cIndex = Item?index + 1 /> 
447						<section class="article-section-content" aria-label="${languageUtil.get(request, 'content-section')} ${cIndex}"> 
448							<#if themeDisplay.isSignedIn()> 
449								<aside class="portlet-msg-info infoparrafo" role="note" aria-label="${languageUtil.get(request, 'only-administrators-can-use-this-portlet')}"> 
450									<p class="text-center mb-0"> 
451										<span class="fas fa-file-signature font-size-10 mr-2" aria-hidden="true"></span> 
452										<#assign cIndex = Item?index + 1 /> 
453										<strong class="important mr-5">Contenido<#if Item?index gt 0> ${cIndex}</#if></strong> 
454										<span class="d-inline font-size-09 mt-2"> 
455											<span class="fas fa-info-circle mr-1" aria-hidden="true"></span> 
456											Información visible únicamente para usuarios logueados 
457										</span> 
458									</p> 
459								</aside> 
460							</#if> 
461							<#if tituloData?has_content> 
462								<#if tipoHeading == "h2"> 
463									<h2 class="h3 text-center mt-6 mb-5"> 
464										${tituloData} 
465									</h2> 
466								<#elseif tipoHeading == "h3"> 
467									<h3 class="h3 font-weight-semi-bold mt-6 mb-4"> 
468										${tituloData} 
469									</h3> 
470								<#elseif tipoHeading == "h4"> 
471									<h4 class="h4 font-weight-semi-bold mt-6 mb-4"> 
472										${tituloData} 
473									</h4> 
474								<#else> 
475									<div class="h4 font-weight-normal mt-6 mb-4"> 
476										${tituloData} 
477									</div> 
478								</#if> 
479							</#if> 
480							<div class="article-section-info"> 
481								<#if Item.ContenidoTexto?? && Item.ContenidoTexto.getSiblings()?has_content> 
482									<#list Item.ContenidoTexto.getSiblings() as secc> 
483										<#assign seccionTexto = (secc.data)!"" /> 
484										<#if seccionTexto?has_content> 
485											${seccionTexto} 
486										</#if> 
487										<#assign imagenPath = (secc.ContentImagen.data)!"" /> 
488										<#if imagenPath?has_content> 
489											<#assign imagenURL = sanitizeURL(dlTool.getThumbnail(imagenPath, '3')) /> 
490											<#if imagenURL?has_content> 
491												<#assign imgAlt = (secc.ContentImagen.AltImage.data)!"" /> 
492												<#assign imgTitle = (secc.ContentImagen.TitleImage.data)!"" /> 
493												<#assign imgPie = (secc.ContentImagen.PieImage.data)!"" /> 
494												<#assign altText = imgAlt /> 
495												<#if !altText?has_content && imgTitle?has_content> 
496													<#assign altText = imgTitle /> 
497												</#if> 
498												<#if !altText?has_content && imgPie?has_content> 
499													<#assign altText = htmlUtil.extractText(imgPie)?trim /> 
500												</#if> 
501												<#if !altText?has_content> 
502													<#assign altText = "${languageUtil.get(request, 'image')} ${cIndex}" /> 
503												</#if> 
504												<div class="article-section-image-wrapper"> 
505													<div class="article-section-image"> 
506														<img src="${imagenURL}" class="rounded" alt="${htmlUtil.escape(altText)}" <#if imgTitle?has_content>title="${htmlUtil.escape(imgTitle)}"</#if> loading="lazy" /> 
507														<#if imgPie?has_content> 
508															<div class="article-section-image-footer"> 
509																${imgPie} 
510															</div> 
511														</#if> 
512													</div> 
513												</div> 
514											</#if> 
515										</#if> 
516									</#list> 
517								</#if> 
518							</div> 
519						</section> 
520					</#if> 
521				</#list> 
522			</#if> 
523		</div> 
524		 
525		<#assign hasTab1 = (Informacion.Texto?? && Informacion.Texto.data?has_content) /> 
526		<#assign hasTab2 = (Informacion.Horario?? && Informacion.Horario.data?has_content) || (Informacion.Tarifas?? && Informacion.Tarifas.data?has_content) /> 
527		<#assign hasTab3 = Reservas?? && ((Reservas.CompraEntradas?? && Reservas.CompraEntradas.data?has_content) || (Reservas.ReservasPhone?? && Reservas.ReservasPhone.data?has_content) || (Reservas.ReservasEmail?? && Reservas.ReservasEmail.data?has_content) || (Reservas.ReservasWhatsapp?? && Reservas.ReservasWhatsapp.data?has_content)) /> 
528		<#assign hasTab4 = (AsturiasMascotas?? && AsturiasMascotas.LimitacionPeso?? && AsturiasMascotas.LimitacionPeso.data?has_content) /> 
529		<#assign hasTab5 = Geolocalizacion.Coordenadas.data?has_content> 
530		<#assign showFirstTab = true> 
531		<div class="article-accordion accordion"> 
532			<#if Visualizador.Slide.getData()?has_content> 
533				<h3 class="h3">${languageUtil.get(locale,"model.resource.com.liferay.portlet.imagegallery")}</h3>			 
534				<div class="slick article-slick article-section <#if Visualizador.Slide.getSiblings()?size==1>hide</#if>"> 
535					<#list Visualizador.Slide.getSiblings() as Slide> 
536						<#if validator.isNotNull(Slide.getData()) || validator.isNotNull(Slide.SlideUrl.getData())> 
537							<#assign slideThumbnail3 = dlTool.getThumbnailByJSON(Slide.data, "3")! /> 
538							<#assign slideThumbnail2Raw = dlTool.getThumbnailByJSON(Slide.data, "2")! /> 
539							<#assign slidePathRaw = dlTool.getPathByJSON(Slide.data, themeDisplay.getScopeGroupId())! /> 
540							<#assign slideUrlRaw = Slide.SlideUrl.data /> 
541							<#if slideUrlRaw?has_content> 
542								<#assign slideTitleRaw = "${languageUtil.get(request, 'video')} ${Slide?index}" /> 
543								<#if Slide.SlideTitulo.data?has_content> 
544									<#assign slideTitleRaw = Slide.SlideTitulo.data />   
545								</#if> 
546								<#assign slideUrl = stringUtil.replace(slideUrlRaw, 'watch?v=', 'embed/') /> 
547								<#assign slideThumbnail2Raw = stringUtil.replace(slideUrl, 'www', 'img') /> 
548								<#assign slideThumbnail2Raw = stringUtil.replace(slideThumbnail2Raw, 'embed', 'vi') /> 
549								<#assign slideThumbnail2Raw = '${slideThumbnail2Raw}/mqdefault.jpg' /> 
550								<#if slideUrl?contains("vimeo")> 
551									<#assign slideUrl = stringUtil.replace(slideUrl, 'http://vimeo.com/', 'https://player.vimeo.com/video/') /> 
552									<#assign slideVimeoId = stringUtil.extractLast(slideUrl, 'https://player.vimeo.com/video/') /> 
553									<#if slideVimeoId?has_content> 
554										<#assign slideVimeoJsonPath = 'http://vimeo.com/api/v2/video/${slideVimeoId}.json' /> 
555										<#assign slideVimeoJsonContent = getUrlContent.getContent(slideVimeoJsonPath)! /> 
556										<#if slideVimeoJsonContent?has_content> 
557											<#assign slideVimeoJsonArray = jsonFactoryUtil.createJSONArray(slideVimeoJsonContent) /> 
558											<#assign slideVimeoJsonItem = slideVimeoJsonArray.get(0) /> 
559											<#assign slideThumbnail2Raw = slideVimeoJsonItem.thumbnail_medium /> 
560										</#if> 
561									</#if> 
562								</#if> 
563								<#assign slideUrlSafe = sanitizeURL(slideUrl) /> 
564								<#assign slideThumbnail2Safe = sanitizeURL(slideThumbnail2Raw) /> 
565								<#assign slideTitle = htmlUtil.escape(slideTitleRaw) /> 
566								<#assign slideTitleJS = htmlUtil.escape(slideTitleRaw?js_string) /> 
567								<#assign slideUrlJS   = htmlUtil.escape(slideUrlSafe?js_string) /> 
568								<#if slideUrlSafe?has_content && slideThumbnail2Safe?has_content> 
569									<div id="slide-${Slide?index}" class="slide"> 
570										<#-- [A2] tabindex="0" eliminado 
571										     [A8] onkeydown añadido: <a role="button"> requiere 
572										          activación con Espacio además de Enter --> 
573										<a class="card card-simple card-video" 
574										   href="#" 
575										   role="button" 
576										   onclick="event.preventDefault(); showDialogIframe('${slideUrlJS}', '${slideTitleJS}', 800, 600, 'videoPopup', 'videoPopupIframe'); return false;" 
577										   onkeydown="if(event.key==='Enter'||event.key===' '){event.preventDefault();showDialogIframe('${slideUrlJS}','${slideTitleJS}',800,600,'videoPopup','videoPopupIframe');}" 
578										   aria-label="${languageUtil.format(request, 'open-video-x', slideTitle)}"> 
579											<span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3" style="background-image: url('${slideThumbnail2Safe}')" role="img" aria-label="${slideTitle}"> 
580												<img class="hide-accessible" src="${slideThumbnail2Safe}" alt="" /> 
581											</span> 
582										</a> 
583									</div> 
584								</#if> 
585							<#else> 
586								<#assign slideTitleRaw = "${languageUtil.get(request, 'image')} ${Slide?index}" /> 
587								<#if Slide.SlideTitulo.data?has_content> 
588									<#assign slideTitleRaw = Slide.SlideTitulo.data />   
589								</#if> 
590								<#assign slideAltRaw = slideTitleRaw />									 
591								<#if Slide.ImagenAlt??>							 
592									<#if Slide.ImagenAlt.data?has_content> 
593										<#assign slideAltRaw = Slide.ImagenAlt.data />   
594									</#if> 
595								</#if> 
596								<#assign slidePath = sanitizeURL(slidePathRaw) /> 
597								<#assign slideThumbnail2Safe = sanitizeURL(slideThumbnail2Raw) /> 
598								<#assign slideTitle = htmlUtil.escape(slideTitleRaw) /> 
599								<#assign slideAlt = htmlUtil.escape(slideAltRaw) /> 
600								<#if slidePath?has_content && slideThumbnail2Safe?has_content> 
601									<div class="slide"> 
602										<a class="card card-simple lightbox" href="${slidePath}" title="${slideTitle}" aria-label="${languageUtil.format(request, 'view-image-x', slideTitle)}"> 
603											<span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3" style="background-image: url('${slideThumbnail2Safe}')" role="img" aria-label="${slideAlt}"> 
604												<img class="hide-accessible" src="${slideThumbnail2Safe}" alt="" /> 
605											</span> 
606										</a> 
607									</div> 
608								</#if> 
609							</#if> 
610						</#if> 
611					</#list> 
612				</div> 
613			</#if> 
614		 
615			<#if hasTab1> 
616				<div id="tab1" class="article-section accordion-item"> 
617					<a href="#tabContent1" id="tabHeading1" class="tab <#if !showFirstTab>collapsed</#if>" role="button" aria-expanded="${showFirstTab?c}" aria-controls="tabContent1" data-toggle="liferay-collapse"> 
618						<h3 class="h3 accordion-header">${languageUtil.get(request,'info')}</h3> 
619					</a> 
620					<div id="tabContent1" class="article-section-content article-section-info accordion-collapse collapse <#if showFirstTab>show</#if>" role="region" aria-labelledby="tabHeading1"> 
621						<#if (Informacion.Texto.data)!?has_content> 
622							${Informacion.Texto.data} 
623						</#if> 
624						<#if (Informacion.FechaDeConstruccion.data)!?has_content> 
625							<span class="field">${languageUtil.get(request, "infoasturias-fecha-de-construccion")}:</span> 
626							<span class="text">${Informacion.FechaDeConstruccion.data}</span> 
627						</#if> 
628					</div> 
629				</div> 
630				<#assign showFirstTab = false> 
631			</#if> 
632 
633			<#if hasTab2> 
634				<div id="tab2" class="article-section accordion-item"> 
635					<a href="#tabContent2" id="tabHeading2" class="tab <#if !showFirstTab>collapsed</#if>" role="button" aria-expanded="${showFirstTab?c}" aria-controls="tabContent2" data-toggle="liferay-collapse"> 
636						<h3 class="h3 accordion-header">${languageUtil.get(request,'infoasturias-horarios-y-tarifas')}</h3> 
637					</a> 
638					<div id="tabContent2" class="article-section-content article-section-color article-section-background accordion-collapse collapse <#if showFirstTab>show</#if>" role="region" aria-labelledby="tabHeading2"> 
639						<#if Informacion.Horario.data?has_content> 
640							<div class="mb-1 font-weight-semi-bold text-success"> 
641								<span class="far fa-clock mr-2 color-green" aria-hidden="true"></span> 
642								${languageUtil.get(request,'infoasturias-horario')}: 
643							</div> 
644							<div class="mb-4">${Informacion.Horario.data}</div> 
645						</#if> 
646						<#if Informacion.Tarifas.data?has_content> 
647							<div class="mb-1 font-weight-semi-bold text-success"> 
648								<span class="fas fa-coins mr-2 color-green" aria-hidden="true"></span> 
649								${languageUtil.get(request,'infoasturias-tarifas')}: 
650							</div>						 
651							<div>${Informacion.Tarifas.data}</div> 
652						</#if> 
653						<#if Informacion.Horario.data?has_content || Informacion.Tarifas.data?has_content> 
654							<#assign hasWeb = Contacto.Web.data?trim?has_content /> 
655							<#assign hasTelefono = Contacto.Telefono.data?trim?has_content /> 
656							<#if hasWeb || hasTelefono> 
657								<div class="mt-4 font-size-09 font-italic"> 
658									<#if hasWeb> 
659										${languageUtil.get(request, 'infoasturias-horarios-web')}									   
660										<#assign siteURLRaw = Contacto.Web.data?trim /> 
661										<#if !siteURLRaw?starts_with("http://") && !siteURLRaw?starts_with("https://")> 
662											<#assign siteURLRaw = "https://${siteURLRaw}" /> 
663										</#if> 
664										<#assign siteURL = sanitizeURL(siteURLRaw) /> 
665										<#if siteURL?has_content> 
666											<#assign isExternal = isExternalURL(siteURL) /> 
667											<a href="${siteURL}" <#if isExternal>target="_blank" rel="noopener noreferrer"</#if> aria-label="${languageUtil.get(request, 'site')} - ${title} <#if isExternal>${languageUtil.get(request, 'opens-new-window')}</#if>"> 
668												${languageUtil.get(request,'visit')} 
669												<#if isExternal> 
670													<span class="fas fa-external-link-alt ml-1 font-size-08" aria-hidden="true"></span> 
671												</#if> 
672											</a> 
673										</#if> 
674									<#elseif hasTelefono> 
675										${languageUtil.get(request, 'infoasturias-horarios-telefono')} 
676										<#list Contacto.Telefono.getSiblings() as telephone> 
677											<#assign rawTelefono = telephone.data /> 
678											<#assign cleanTelefono = rawTelefono?replace("\\(.*?\\)", "", "r") /> 
679											<#assign numberTelefono = cleanTelefono?replace("[^0-9]", "", "r") /> 
680											<#assign numberLength = numberTelefono?length /> 
681											<#if numberLength == 9> 
682											  <#assign hrefNumber = "+34${numberTelefono}" /> 
683											<#else> 
684											  <#assign hrefNumber = numberTelefono /> 
685											</#if> 
686											<span class="text"> 
687												<a href="tel:${hrefNumber}">${rawTelefono}</a> 
688												<#if !telephone?is_last><span aria-hidden="true"> | </span></#if> 
689											</span> 
690										</#list>										 
691									</#if> 
692								</div> 
693							</#if> 
694						</#if> 
695					</div> 
696				</div> 
697				<#assign showFirstTab = false> 
698			</#if> 
699 
700			<#if hasTab3> 
701				<#if (Reservas.CompraEntradas?? && Reservas.CompraEntradas.data?has_content) || (Reservas.ReservasPhone?? && Reservas.ReservasPhone.data?has_content) || (Reservas.ReservasEmail?? && Reservas.ReservasEmail.data?has_content) || (Reservas.ReservasWhatsapp?? && Reservas.ReservasWhatsapp.data?has_content)> 
702					<div id="tab3" class="article-section accordion-item"> 
703						<a href="#tabContent3" id="tabHeading3" class="tab <#if !showFirstTab>collapsed</#if>" role="button" aria-expanded="${showFirstTab?c}" aria-controls="tabContent3" data-toggle="liferay-collapse"> 
704							<h3 class="h3 accordion-header">${languageUtil.get(request,'booking-action')}</h3> 
705						</a> 
706						<div id="tabContent3" class="article-section-content article-section-color article-section-background accordion-collapse collapse <#if showFirstTab>show</#if>" aria-labelledby="tabHeading3" role="region"> 
707							<#if Reservas.CompraEntradas.data?has_content> 
708								<#assign compraURL = sanitizeURL(Reservas.CompraEntradas.data?trim) /> 
709								<#if compraURL?has_content> 
710									<div class="text-center"> 
711										<a class="btn btn-primary mb-3" href="${compraURL}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.get(request,'infoasturias-compra-entradas')} ${languageUtil.get(request,'opens-new-window')}"> 
712											<span class="fas fa-ticket-alt mr-2" aria-hidden="true"></span> 
713											${languageUtil.get(request,'infoasturias-compra-entradas')} 
714										</a> 
715									</div> 
716								</#if> 
717							</#if> 
718							<#if Reservas.ReservasPhone.data?has_content> 
719								<#assign rawTelefono = Reservas.ReservasPhone.data?trim /> 
720								<#assign cleanTelefono = rawTelefono?replace("\\(.*?\\)", "", "r") /> 
721								<#assign numberTelefono = cleanTelefono?replace("[^0-9]", "", "r") /> 
722								<#assign numberLength = numberTelefono?length /> 
723								<#if numberLength == 9> 
724									<#assign hrefNumber = "+34${numberTelefono}" /> 
725								<#else> 
726									<#assign hrefNumber = numberTelefono /> 
727								</#if> 
728								<div class="text-center"> 
729									<a class="btn btn-primary mb-3" href="tel:${htmlUtil.escapeHREF(hrefNumber)}" aria-label="${languageUtil.format(request,'call', rawTelefono)}"> 
730										<span class="fas fa-phone-alt mr-2" aria-hidden="true"></span> 
731										${languageUtil.get(request,'infoasturias-telefono')} 
732									</a> 
733								</div> 
734							</#if> 
735							<#if Reservas.ReservasEmail.data?has_content> 
736								<#assign emailAddress = Reservas.ReservasEmail.data?trim /> 
737								<div class="text-center"> 
738									<a class="btn btn-primary mb-3" href="mailto:${htmlUtil.escapeHREF(emailAddress)}" aria-label="${languageUtil.format(request,'email-to', emailAddress)}"> 
739										<span class="fas fa-envelope mr-2" aria-hidden="true"></span> 
740										${languageUtil.get(request,'infoasturias-email')} 
741									</a> 
742								</div> 
743							</#if> 
744							<#if Reservas.ReservasWhatsapp.data?has_content> 
745								<#assign rawWhatsapp = Reservas.ReservasWhatsapp.data?trim /> 
746								<#assign cleanWhatsapp = rawWhatsapp?replace("[^0-9]", "", "r") /> 
747								<#if cleanWhatsapp?has_content> 
748									<#assign whatsappURL = "https://wa.me/34${cleanWhatsapp}" /> 
749									<#assign whatsappURLSafe = sanitizeURL(whatsappURL) /> 
750									<#if whatsappURLSafe?has_content> 
751										<div class="text-center"> 
752											<a class="btn btn-primary mb-3" href="${whatsappURLSafe}" target="_blank" rel="noopener noreferrer" aria-label="${languageUtil.format(request,'go-to-x', rawWhatsapp)} ${languageUtil.get(request,'opens-new-window')}"> 
753											  <span class="fab fa-whatsapp mr-2" aria-hidden="true"></span> 
754											  Whatsapp 
755											</a> 
756										</div> 
757									</#if> 
758								</#if> 
759							</#if> 
760						</div> 
761					</div> 
762				</#if> 
763				<#assign showFirstTab = false /> 
764			</#if> 
765 
766			<#if hasTab4> 
767				<div id="tab4" class="article-section accordion-item"> 
768					<a href="#tabContent4" id="tabHeading4" class="tab <#if !showFirstTab>collapsed</#if>" role="button" aria-expanded="${showFirstTab?c}" aria-controls="tabContent4" data-toggle="liferay-collapse"> 
769						<h3 class="h3 accordion-header">${languageUtil.get(request,'infoasturias-info-mascotas')}</h3> 
770					</a> 
771					<div id="tabContent4" class="article-section-content article-section-color article-section-background accordion-collapse collapse <#if showFirstTab>show</#if>" aria-labelledby="tabHeading4" role="region"> 
772						<#if hasIconos> 
773							<div class="list-iconos mb-3 d-flex flex-wrap justify-content-center"> 
774								<#if limitacionPeso?has_content> 
775									<div class="col-xl-2 col-sm-6 col-12 text-center mb-4 icono"> 
776										<#assign imgArray = assetCategoryTool.getImagesByVocabularyCategoryName(groupId, "Mascotas", "Limitación de tamaño") /> 
777										<#if imgArray?has_content && imgArray[0]?has_content> 
778											<div> 
779												<img src="${imgArray[0]}" alt="${languageUtil.get(request,'infoasturias-mascotas-peso')}" loading="lazy"> 
780												<span class="value">${limitacionPeso}</span> 
781											</div> 
782											<span class="text-value">${languageUtil.get(request,'infoasturias-mascotas-peso')}</span> 
783										</#if> 
784									</div> 
785								</#if> 
786								<#if NumeroMaximoPersona?has_content> 
787									<div class="col-xl-2 col-sm-6 col-12 text-center mb-4 icono"> 
788										<#assign imgArray = assetCategoryTool.getImagesByVocabularyCategoryName(groupId, "Mascotas", "Número máximo de perros por persona") /> 
789										<#if imgArray?has_content && imgArray[0]?has_content> 
790											<div> 
791												<img src="${imgArray[0]}" alt="${languageUtil.get(request,'infoasturias-mascotas-maximo-persona')}" loading="lazy"> 
792												<span class="value-icono">${NumeroMaximoPersona}</span> 
793											</div> 
794											<span class="text-value">${languageUtil.get(request,'infoasturias-mascotas-maximo-persona')}</span> 
795										</#if> 
796									</div> 
797								</#if> 
798								<#if NumeroMaximoInterior?has_content> 
799									<div class="col-xl-2 col-sm-6 col-12 text-center mb-4 icono"> 
800										<#assign imgArray = assetCategoryTool.getImagesByVocabularyCategoryName(groupId, "Mascotas", "Cupo máximo de perros en el interior") /> 
801										<#if imgArray?has_content && imgArray[0]?has_content> 
802											<div> 
803												<img src="${imgArray[0]}" alt="${languageUtil.get(request,'infoasturias-maximo-interior')}" loading="lazy"> 
804												<span class="value-icono">${NumeroMaximoInterior}</span> 
805											</div> 
806											<span class="text-value">${languageUtil.get(request,'infoasturias-maximo-interior')}</span> 
807										</#if> 
808									</div> 
809								</#if> 
810								<#if AccesoInterior?has_content> 
811									<div class="col-xl-2 col-sm-6 col-12 text-center mb-4 icono"> 
812										<#if AccesoInterior == "Si"> 
813											<#assign imgArray = assetCategoryTool.getImagesByVocabularyCategoryName(groupId, "Mascotas", "Accesso al interior") /> 
814											<#if imgArray?has_content && imgArray[0]?has_content> 
815												<div><img src="${imgArray[0]}" alt="${languageUtil.get(request,'infoasturias-mascotas-material')}" loading="lazy"></div> 
816												<span class="text-value">${languageUtil.get(request,'infoasturias-mascotas-interior')}</span> 
817											</#if> 
818										<#else> 
819											<#assign imgArray = assetCategoryTool.getImagesByVocabularyCategoryName(groupId, "Mascotas", "Sin acceso interior") /> 
820											<#if imgArray?has_content && imgArray[0]?has_content> 
821												<div><img src="${imgArray[0]}" alt="${languageUtil.get(request,'infoasturias-mascotas-no-material')}" loading="lazy"></div> 
822												<span class="text-value">${languageUtil.get(request,'infoasturias-mascotas-no-interior')}</span> 
823											</#if> 
824										</#if> 
825									</div> 
826								</#if> 
827							</div> 
828						</#if> 
829						<#if hasNormas> 
830							<div class="article-info-table mb-2"> 
831								<div class="normas-mascotas"> 
832									<h4 class="mb-4 text-success text-center article-info-border"> 
833										${languageUtil.get(request,'infoasturias-normas-mascotas')} 
834									</h4> 
835									<ul class="list-unstyled" role="list"> 
836										<#if admitePPP?has_content> 
837											<li class="d-flex align-items-start mb-2"> 
838												<span class="fas fa-paw text-success mr-2 mt-1 flex-shrink-0" aria-hidden="true"></span> 
839												<span class="text-rule"> 
840													<#if admitePPP == "Si"> 
841														${languageUtil.get(request,'infoasturias-mascotas-ppp')}. 
842													<#else> 
843														${languageUtil.get(request,'infoasturias-mascotas-no-ppp')}. 
844													</#if> 
845												</span> 
846											</li> 
847										</#if> 
848										<#if AccesoTerraza?has_content> 
849											<li class="d-flex align-items-start mb-2"> 
850												<span class="fas fa-paw text-success mr-2 mt-1 flex-shrink-0" aria-hidden="true"></span> 
851												<span class="text-rule"> 
852													<#if AccesoTerraza == "Si"> 
853														${languageUtil.get(request,'infoasturias-mascotas-terraza')}. 
854													<#else> 
855														${languageUtil.get(request,'infoasturias-mascotas-no-terraza')}. 
856													</#if> 
857												</span> 
858											</li> 
859										</#if>										 
860										<#if otrasMascotas?has_content> 
861											<li class="d-flex align-items-start mb-2"> 
862												<span class="fas fa-paw text-success mr-2 mt-1 flex-shrink-0" aria-hidden="true"></span> 
863												<span class="text-rule"> 
864													<#if otrasMascotas == "Si"> 
865														${languageUtil.get(request,'infoasturias-otras-mascotas')}: 
866														<#if otrosAnimales?has_content> 
867															<strong>${otrosAnimales}</strong> 
868														</#if> 
869													<#else> 
870														${languageUtil.get(request,'infoasturias-no-otras-mascotas')}. 
871													</#if> 
872												</span> 
873											</li> 
874										</#if> 
875										<#if detalleNormas?has_content> 
876											<#assign normasParagraphs = detalleNormas?split('</p>') /> 
877											<#list normasParagraphs as parrafo> 
878												<#if parrafo?trim?has_content> 
879													<#assign cleanParrafo = parrafo?replace('<p>', '')?replace('<p[^>]*>', '', 'r')?trim /> 
880													<#if cleanParrafo?has_content> 
881														<li class="d-flex align-items-start mb-2"> 
882															<span class="fas fa-paw text-success mr-2 mt-1 flex-shrink-0" aria-hidden="true"></span> 
883															<span class="text-rule">${cleanParrafo}</span> 
884														</li> 
885													</#if> 
886												</#if> 
887											</#list> 
888										</#if>									 
889									</ul> 
890								</div> 
891							</div> 
892						</#if> 
893					</div> 
894					<#assign showFirstTab = false> 
895				</div> 
896			</#if> 
897 
898			<#if hasTab5> 
899				<#assign coordenadas = stringUtil.split(Geolocalizacion.Coordenadas.data) /> 
900				<#assign latRaw = (coordenadas?size > 0)?then(coordenadas[0]?trim, "") /> 
901				<#assign lngRaw = (coordenadas?size > 1)?then(coordenadas[1]?trim, "") /> 
902				<#assign coordsValid = latRaw?matches("^-?\\d{1,3}(\\.\\d+)?$") && lngRaw?matches("^-?\\d{1,3}(\\.\\d+)?$") /> 
903				<div id="tab5" class="article-section article-section-map accordion-item"> 
904					<a href="#tabContent5" id="tabHeading5" class="tab <#if !showFirstTab>collapsed</#if>" role="button" aria-expanded="${showFirstTab?c}" aria-controls="tabContent5" data-toggle="liferay-collapse"> 
905						<h3 class="h3 accordion-header">${languageUtil.get(request,'infoasturias-how-to-get')}</h3> 
906					</a> 
907					<div id="tabContent5" class="article-section-content accordion-collapse collapse <#if showFirstTab>show</#if>" aria-labelledby="tabHeading5" role="region"> 
908						<div id="article-map-wrapper-${articleId}" class="article-map-wrapper">  
909							<div id="article-map-content-${articleId}" style="width: 100%; height: 500px; z-index:1" role="application" aria-label="${languageUtil.format(request,'infoasturias-mapa-de', title)}"><!-- MAP --></div> 
910							<div class="hide-accessible" aria-live="polite"> 
911								<p>${languageUtil.get(request,'first-name')}: ${title}</p> 
912								<p>GPS: ${Geolocalizacion.Coordenadas.data}</p> 
913								<#if (Contacto.Direccion.data)?has_content || ((Contacto.CP.data)?has_content) || ((Contacto.Localidad.data)?has_content)> 
914									<p>${languageUtil.get(request,'address')}: ${((Contacto.Direccion.data)!)?js_string} ■ ${((Contacto.CP.data)!)?js_string} - ${((Contacto.Localidad.data)!)?js_string}</p> 
915								</#if> 
916							</div>								 
917							<div class="article-map-form">  
918								<div class="name important">${title}</div> 
919								<div class="gps"><span class="label">GPS:</span> <span class="value important">${Geolocalizacion.Coordenadas.data}</span></div> 
920								<form action="https://maps.google.es/maps" method="get" target="_blank" 
921								      aria-label="${languageUtil.get(request,'infoasturias-como-llegar')}"> 
922									<input type="hidden" name="daddr" value="${latRaw},${lngRaw}"> 
923									<label for="saddrText"> 
924										<span class="label">${languageUtil.get(request,'infoasturias-from')}: </span> 
925									</label> 
926									<input class="form-control" type="text" maxlength="40" name="saddrText" id="saddrText" value="" placeholder="${languageUtil.get(request,'infoasturias-insert-from')}"> 
927									<input type="hidden" name="saddr" id="saddr" aria-hidden="true"> 
928									<button class="btn btn-text" type="submit"> 
929										${languageUtil.get(request,'infoasturias-como-llegar')} 
930										<span aria-hidden="true"> »</span> 
931										<span class="hide-accessible">${languageUtil.get(request,'opens-new-window')}</span> 
932									</button> 
933								</form> 
934							</div> 
935						</div> 
936						<script src="/o/turismo-asturias-theme/js/leaflet/leaflet.js"></script> 
937						<script type="text/javascript"> 
938							AUI().ready('aui-base', function(A){ 
939								<#if coordsValid> 
940								var lat  = ${latRaw}, 
941									lng  = ${lngRaw}, 
942									zoom = 16; 
943								var mapContent = new L.map('article-map-content-${articleId}', {center: [lat, lng], zoom: zoom}); 
944 
945								var defaultIconTheme = '/o/turismo-asturias-theme/css/images/icons/mark-box.png'; 
946								var defaultIcon = L.icon({ 
947									iconUrl: defaultIconTheme, 
948									iconSize:     [36, 53], 
949									iconAnchor:   [18, 53], 
950									iconShadow:   [0,0], 
951									popupAnchor:  [0, -30] 
952								}); 
953								var marker = L.marker([lat, lng], {icon: defaultIcon}).addTo(mapContent); 
954								 
955								var contentString = '<div class="row">'; 
956								contentString += '<div class="col-12">'; 
957								contentString += '<div class="h4">${htmlUtil.escape(title)}</div>'; 
958								contentString += '</div>'; 
959								contentString += '</div>'; 
960								 
961								contentString += '<div class="row">'; 
962								contentString += '<div class="col-12">'; 
963								<#if validator.isNotNull(articleMainImageThumbnail1Safe)> 
964									contentString += '<img class="pull-right mb-2 ml-2" src="${articleMainImageThumbnail1Safe}" alt="${htmlUtil.escape(title)}"/>'; 
965								</#if> 
966								contentString += '<dl class="mb-0">'; 
967								<#if (Contacto.Direccion.data)?has_content || ((Contacto.CP.data)?has_content) || ((Contacto.Localidad.data)?has_content)> 
968									<#assign popupDir = htmlUtil.escape(((Contacto.Direccion.data)!)?js_string) /> 
969									<#assign popupCP  = htmlUtil.escape(((Contacto.CP.data)!)?js_string) /> 
970									<#assign popupLoc = htmlUtil.escape(((Contacto.Localidad.data)!)?js_string) /> 
971									contentString += '<dt class="important">${languageUtil.get(request,"address")}</dt>'; 
972									contentString += '<dd>${popupDir}<br>${popupCP} - ${popupLoc}</dd>'; 
973								</#if> 
974								<#if Contacto.Telefono.data?has_content> 
975									contentString += '<dt class="important">${languageUtil.get(request,"phone")}</dt>'; 
976									contentString += '<dd>${htmlUtil.escape(Contacto.Telefono.data?js_string)}</dd>'; 
977								</#if> 
978								<#if Contacto.Email.getData()?has_content> 
979									contentString += '<dt class="important">${languageUtil.get(request,"email")}</dt>'; 
980									<#list Contacto.Email.getSiblings() as Item> 
981										<#if Item.data?trim?has_content> 
982											<#assign emailHREF  = htmlUtil.escape(Item.data?trim?js_string) /> 
983											<#assign emailLabel = htmlUtil.escape(Item.data?trim?js_string) /> 
984											contentString += '<dd><a href="mailto:${emailHREF}">${emailLabel}</a></dd>'; 
985										</#if> 
986									</#list> 
987								</#if> 
988								<#if Contacto.Web.data?has_content> 
989									<#assign popupWebRaw = Contacto.Web.data?trim /> 
990									<#if !popupWebRaw?starts_with("http://") && !popupWebRaw?starts_with("https://")> 
991										<#assign popupWebRaw = "https://${popupWebRaw}" /> 
992									</#if> 
993									<#assign popupWebURL = sanitizeURL(popupWebRaw) /> 
994									<#if popupWebURL?has_content> 
995										<#assign popupWebHREF  = htmlUtil.escape(popupWebURL?js_string) /> 
996										<#assign popupWebLabel = htmlUtil.escape(Contacto.Web.data?trim?js_string) /> 
997										contentString += '<dt class="important">${languageUtil.get(request,"site")}</dt>'; 
998										contentString += '<dd><a href="${popupWebHREF}" rel="noopener noreferrer">${popupWebLabel}</a></dd>'; 
999									</#if> 
1000								</#if> 
1001								contentString += '</dl>'; 
1002								contentString += '</div>'; 
1003								contentString += '</div>'; 
1004								<#if description?has_content> 
1005									<#assign descriptionClean = description?replace("\n", "", "r")?replace("\r", "", "r") /> 
1006									contentString += '<div class="row"><div class="col-12">${htmlUtil.escapeJS(descriptionClean)}</div></div>'; 
1007								</#if> 
1008								marker.bindPopup(contentString); 
1009 
1010								marker.on('popupopen', function() { 
1011									var popupEl = document.querySelector('#article-map-content-${articleId} .leaflet-popup-content'); 
1012									if (popupEl) { 
1013										popupEl.setAttribute('tabindex', '-1'); 
1014										popupEl.focus(); 
1015
1016								}); 
1017 
1018								L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 
1019									attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors.' 
1020								}).addTo(mapContent); 
1021								<#else> 
1022								console.warn('Coordenadas no válidas para artículo ${articleId}'); 
1023								</#if> 
1024							}); // AUI.ready 
1025						</script> 
1026					</div> 
1027				</div> 
1028				<#assign showFirstTab = false> 
1029			</#if>		 
1030		</div> 
1031		<#if (Informacion.Observaciones.data)!?has_content || (Contacto.MasInformacion.data)!?has_content> 
1032			<div class="article-border"> 
1033				<#if (Informacion.Observaciones.data)!?has_content> 
1034					<div class="observations mb-3"> 
1035						${Informacion.Observaciones.data} 
1036					</div> 
1037				</#if> 
1038				<#if (Contacto.MasInformacion.data)!?has_content> 
1039					<div class="more-info"> 
1040						<#list Contacto.MasInformacion.getSiblings() as Item> 
1041							<#if Item.data?trim?has_content> 
1042								<#assign itemData = Item.data?trim /> 
1043								<#if itemData?matches("^https?://.*") || itemData?starts_with("//")> 
1044									<#assign itemURL = itemData /> 
1045									<#if itemURL?starts_with("//")> 
1046										<#assign itemURL = "https:${itemURL}" /> 
1047									</#if> 
1048									<#assign itemURLSafe = sanitizeURL(itemURL) /> 
1049									<#if itemURLSafe?has_content> 
1050										<#assign isExternal = isExternalURL(itemURLSafe) /> 
1051										<div class="mb-2"> 
1052											<a class="link" href="${itemURLSafe}" <#if isExternal>target="_blank" rel="noopener noreferrer"</#if> aria-label="${languageUtil.format(request,'visit-link-x', itemData)} <#if isExternal>${languageUtil.get(request,'opens-new-window')}</#if>"> 
1053												<#-- [S6] itemData texto plano → htmlUtil.escape como texto visible --> 
1054												${htmlUtil.escape(itemData)} 
1055												<#if isExternal> 
1056													<span class="fas fa-external-link-alt ml-1" aria-hidden="true"></span> 
1057												</#if> 
1058											</a> 
1059										</div> 
1060									</#if> 
1061								<#else> 
1062									<div class="mb-2"> 
1063										<span>${htmlUtil.escape(itemData)}</span> 
1064									</div> 
1065								</#if> 
1066							</#if> 
1067						</#list> 
1068					</div> 
1069				</#if> 
1070			</div> 
1071		</#if> 
1072	</div>	 
1073			 
1074	<#-- Related Articles --> 
1075	<#assign relatedJournalArticles = assetTool.getRelatedJournalArticlesApproved(assetEntry) /> 
1076	<#if validator.isNotNull(relatedJournalArticles) && relatedJournalArticles?size gt 0> 
1077		<div class="article-related portlet-background-grey-container"> 
1078			<div class="container"> 
1079				<h3 class="title-section">${languageUtil.get(request,'related-assets')}</h3> 
1080				<div class="slick article-related-slick"> 
1081					<#list relatedJournalArticles as currentJournalArticle> 
1082						<#assign viewURLRaw = journalTool.getDisplayPage(currentJournalArticle, themeDisplay, true) /> 
1083						<#assign viewURL = sanitizeURL(viewURLRaw) /> 
1084						<#assign articleTitle = currentJournalArticle.getTitle(locale) /> 
1085						<#assign smallImageURLRaw = currentJournalArticle.getSmallImageURL() /> 
1086						<#assign smallImageURL = sanitizeURL(smallImageURLRaw) /> 
1087						<#if viewURL?has_content && smallImageURL?has_content && articleTitle?has_content> 
1088							<div class="slide"> 
1089								<a class="card background card-background-9-14" href="${viewURL}" aria-label="${languageUtil.format(request, 'go-to-x', articleTitle)}"> 
1090									<span class="d-block image-wrapper aspect-ratio-bg-cover" style="background-image: url('${smallImageURL}')" role="img" aria-label="${articleTitle}"> 
1091										<img class="hide-accessible" src="${smallImageURL}" alt="" /> 
1092										<span class="card-body"> 
1093											<span class="card-title">${articleTitle}</span> 
1094										</span> 
1095									</span> 
1096								</a> 
1097							</div> 
1098						</#if> 
1099					</#list> 
1100				</div> 
1101			</div> 
1102		</div> 
1103	</#if> 
1104	 
1105	<#-- Nearby Articles --> 
1106	<#assign classTypeIds = [] /> 
1107	<#assign assetsNearJournalArticles = assetNearTool.getNearJournalArticles(themeDisplay.getScopeGroupId(), assetEntry.getEntryId(), 50.0, classTypeIds, 25)! /> 
1108	<#if validator.isNotNull(assetsNearJournalArticles) && assetsNearJournalArticles?size gt 0> 
1109		<div class="article-nearby portlet-container-margin"> 
1110			<div class="container"> 
1111				<div class="article-nearby-container"> 
1112					<h3 class="title-section">${languageUtil.get(request,'infoasturias-near-here')}</h3> 
1113					<div class="slick article-nearby-slick"> 
1114						<#list assetsNearJournalArticles as currentJournalArticle> 
1115							<#assign viewURLRaw = journalTool.getDisplayPage(currentJournalArticle, themeDisplay, true) /> 
1116							<#assign viewURL = sanitizeURL(viewURLRaw) /> 
1117							<#assign articleTitle = currentJournalArticle.getTitle(locale) /> 
1118							<#assign articleDescriptionRaw = currentJournalArticle.getDescription(locale) /> 
1119							<#assign articleDescription = htmlUtil.escape(articleDescriptionRaw) /> 
1120							<#assign smallImageURLRaw = currentJournalArticle.getSmallImageURL() /> 
1121							<#assign smallImageURL = sanitizeURL(smallImageURLRaw) /> 
1122							<#assign distanceKm = currentJournalArticle.getVersion() /> 
1123							<#assign categoriesNamesRaw = journalTool.getCategoriesNames(groupId, currentJournalArticle.getArticleId(), locale, ["Concejos"]) /> 
1124							<#assign categoriesNames = htmlUtil.escape(categoriesNamesRaw) /> 
1125							 
1126							<#if viewURL?has_content && smallImageURL?has_content && articleTitle?has_content> 
1127								<div class="slide"> 
1128									<a class="card" href="${viewURL}" aria-label="${languageUtil.format(request, 'go-to-x', articleTitle)}"> 
1129										<span class="d-block image-wrapper aspect-ratio-bg-cover aspect-ratio-4-to-3" style="background-image: url('${smallImageURL}')" role="img" aria-label="${articleTitle}"> 
1130											<img class="hide-accessible" src="${smallImageURL}" alt="" />					 
1131											<#if articleDescriptionRaw?has_content> 
1132												<span class="card-hover"> 
1133													<span class="card-text">${articleDescription}</span> 
1134												</span> 
1135											</#if> 
1136										</span> 
1137										<span class="card-body"> 
1138											<span class="card-title">${articleTitle}</span> 
1139											<span class="card-subtitle"> 
1140												<span class="d-block"> 
1141													<span class="sr-only">${languageUtil.get(request, 'distance')}: </span> 
1142													${distanceKm} ${languageUtil.get(request, 'km')} 
1143												</span> 
1144												<#if categoriesNames?has_content> 
1145													<span class="d-block">${categoriesNames}</span> 
1146												</#if> 
1147											</span> 
1148										</span> 
1149									</a> 
1150								</div> 
1151							</#if> 
1152						</#list> 
1153					</div> 
1154				</div> 
1155			</div> 
1156		</div> 
1157	</#if> 
1158</article> 
1159<#assign vocabCultura = assetVocabularyLocalService.fetchGroupVocabulary(groupId, "Cultura")! /> 
1160<#assign schemaTypes = ["CivicStructure", "TouristAttraction"] /> 
1161<#if vocabCultura?has_content> 
1162	<#assign categoriasCultura = assetCategoryLocalService.getVocabularyCategories(vocabCultura.getVocabularyId(), -1, -1, null) /> 
1163	<#assign categoriaPadre = "" /> 
1164	<#list categoriasCultura as cat> 
1165		<#if cat.getName() == "Museos y espacios culturales"> 
1166			<#assign categoriaPadre = cat /> 
1167			<#break> 
1168		</#if> 
1169	</#list> 
1170	<#if categoriaPadre?has_content> 
1171		<#assign categoriasArticulo = assetCategoryLocalService.getCategories("com.liferay.journal.model.JournalArticle", journalArticle.resourcePrimKey ) /> 
1172		<#list categoriasArticulo as cat> 
1173			<#if cat.getVocabularyId() == vocabCultura.getVocabularyId() && cat.getParentCategoryId() == categoriaPadre.getCategoryId()> 
1174				<#assign nombreCategoria = cat.getName() /> 
1175				<#if nombreCategoria == "Museos" || nombreCategoria == "Colecciones Museográficas"> 
1176					<#assign schemaTypes = ["Museum", "LocalBusiness", "TouristAttraction"] /> 
1177					<#break> 
1178				<#elseif nombreCategoria == "Castros y espacios arqueológicos"> 
1179					<#assign schemaTypes = ["ArchaeologicalSite", "LocalBusiness", "TouristAttraction"] /> 
1180					<#break> 
1181				<#elseif nombreCategoria == "Conjuntos etnográficos"> 
1182					<#assign schemaTypes = ["LandmarksOrHistoricalBuildings", "LocalBusiness", "TouristAttraction"] /> 
1183					<#break> 
1184				<#elseif nombreCategoria == "Centros de interpretación"> 
1185					<#assign schemaTypes = ["VisitorCenter", "LocalBusiness", "TouristAttraction"] /> 
1186					<#break> 
1187				<#elseif nombreCategoria == "Otros espacios culturales"> 
1188					<#assign schemaTypes = ["CivicStructure", "LocalBusiness", "TouristAttraction"] /> 
1189					<#break> 
1190				</#if> 
1191			</#if> 
1192		</#list> 
1193	</#if> 
1194</#if> 
1195<script type="application/ld+json"> 
1196
1197	"@context": "https://schema.org", 
1198	"@type": [ 
1199	  <#list schemaTypes as t>"${t}"<#if t_has_next>,</#if></#list> 
1200	], 
1201	"@id": "${articleURL}", 
1202	"name": "${title?json_string}", 
1203	"url": "${articleURL}" 
1204	<#if articleMainImageThumbnail3Safe?has_content> 
1205		,"image": [ 
1206			"${themeDisplay.getPortalURL()}${articleMainImageThumbnail3Safe}" 
1207			<#if Visualizador.Slide.getData()?has_content> 
1208				<#list Visualizador.Slide.getSiblings() as Slide> 
1209					<#if validator.isNotNull(Slide.getData()) && !Slide.SlideUrl.getData()?has_content> 
1210						<#assign slidePathRaw = dlTool.getPathByJSON(Slide.data, themeDisplay.getScopeGroupId())! /> 
1211						<#assign slidePath = sanitizeURL(slidePathRaw) /> 
1212						<#if slidePath?has_content> 
1213							,"${themeDisplay.getPortalURL()}${slidePath}" 
1214						</#if> 
1215					</#if> 
1216				</#list> 
1217			</#if> 
1218
1219	</#if> 
1220	<#if Informacion.Texto?? && Informacion.Texto.data?has_content> 
1221		<#assign cleanDesc = htmlUtil.extractText(Informacion.Texto.data)?trim /> 
1222		<#if cleanDesc?has_content> 
1223			,"description": "${cleanDesc?json_string}" 
1224		</#if> 
1225	</#if> 
1226	<#if Contacto.Direccion?? && Contacto.Direccion.data?has_content || Contacto.CP?? && Contacto.CP.data?has_content || Contacto.Localidad?? && Contacto.Localidad.data?has_content || Contacto.Concejo?? && Contacto.Concejo.data?has_content> 
1227		,"address": { 
1228			"@type": "PostalAddress" 
1229			<#if Contacto.Direccion?? && Contacto.Direccion.data?has_content> 
1230				,"streetAddress": "${Contacto.Direccion.data?json_string}" 
1231			</#if> 
1232			<#if Contacto.CP?? && Contacto.CP.data?has_content> 
1233				,"postalCode": "${(Contacto.CP.data)!}" 
1234			</#if> 
1235			<#if Contacto.Localidad?? && Contacto.Localidad.data?has_content> 
1236				<#assign cleanLoc = htmlUtil.extractText(Contacto.Localidad.data)?trim /> 
1237				,"addressLocality": "${cleanLoc?json_string}" 
1238			</#if> 
1239			<#if (Contacto.Concejo.data)!?has_content> 
1240				,"addressRegion": "${Contacto.Concejo.data?json_string}" 
1241			</#if> 
1242			,"addressCountry": "ES" 
1243
1244	</#if> 
1245	<#if Geolocalizacion.Coordenadas?? && Geolocalizacion.Coordenadas.data?has_content> 
1246		<#assign coordenadas = stringUtil.split(Geolocalizacion.Coordenadas.data) /> 
1247		,"geo": { 
1248			"@type": "GeoCoordinates", 
1249			"latitude": "${coordenadas[0]}", 
1250			"longitude": "${coordenadas[1]}" 
1251
1252	</#if> 
1253	<#if Contacto.Telefono?? && Contacto.Telefono.data?has_content> 
1254		,"telephone": [ 
1255			<#assign phoneList = [] /> 
1256			<#list Contacto.Telefono.getSiblings() as telephone> 
1257				<#if telephone.data?has_content> 
1258					<#assign rawTelefono = telephone.data?trim /> 
1259					<#assign cleanTelefono = rawTelefono?replace("\\(.*?\\)", "", "r") /> 
1260					<#assign numberTelefono = cleanTelefono?replace("[^0-9]", "", "r") /> 
1261					<#if numberTelefono?length == 9> 
1262						<#assign phoneList = phoneList + ["+34${numberTelefono}"] /> 
1263					<#elseif numberTelefono?has_content> 
1264						<#assign phoneList = phoneList + [numberTelefono] /> 
1265					</#if> 
1266				</#if> 
1267			</#list> 
1268			<#if phoneList?has_content> 
1269				<#list phoneList as phone> 
1270					"${phone?json_string}"<#if phone_has_next>,</#if> 
1271				</#list> 
1272			</#if> 
1273
1274	</#if> 
1275	<#if Contacto.Email?? && Contacto.Email.data?has_content> 
1276		,"email": [ 
1277			<#assign emailList = [] /> 
1278			<#list Contacto.Email.getSiblings() as Item> 
1279				<#if Item.data?trim?has_content> 
1280					<#assign emailList = emailList + [Item.data?trim] /> 
1281				</#if> 
1282			</#list> 
1283			<#if emailList?has_content> 
1284				<#list emailList as email> 
1285					"${email?json_string}"<#if email_has_next>,</#if> 
1286				</#list> 
1287			</#if> 
1288
1289	</#if> 
1290	<#if Informacion.Horario?? && Informacion.Horario.data?has_content> 
1291		<#assign cleanHorario = htmlUtil.extractText(Informacion.Horario.data)?trim /> 
1292		<#if cleanHorario?has_content> 
1293			,"openingHoursSpecification": { 
1294				"@type": "OpeningHoursSpecification", 
1295				"description": "${cleanHorario?json_string}" 
1296
1297		</#if> 
1298	</#if> 
1299
1300</script> 
1301<script type="text/javascript"> 
1302	(function() { 
1303		'use strict'; 
1304		setTimeout(function() { 
1305			var links = document.querySelectorAll('.internal-tab-link'); 
1306			links.forEach(function(link) { 
1307				link.addEventListener('click', function(e) { 
1308					e.preventDefault(); 
1309					 
1310					var tabHeadingId = this.getAttribute('data-tab-heading'); 
1311					var tabContentId = this.getAttribute('data-tab-content'); 
1312					var tabControl = document.getElementById(tabHeadingId); 
1313					var tabContent = document.getElementById(tabContentId); 
1314					 
1315					if (!tabControl || !tabContent) return; 
1316					 
1317					var isExpanded = tabControl.getAttribute('aria-expanded') === 'true'; 
1318					if (!isExpanded) { 
1319						tabControl.click(); 
1320						setTimeout(function() { 
1321							scrollToElement(tabControl); 
1322						}, 350); 
1323					} else { 
1324						scrollToElement(tabControl); 
1325
1326				}); 
1327			}); 
1328		}, 500); 
1329	   
1330		function scrollToElement(element) { 
1331			var elementPosition = element.getBoundingClientRect().top; 
1332			var offsetPosition = elementPosition + window.pageYOffset - 140; 
1333			window.scrollTo({ 
1334				top: offsetPosition, 
1335				behavior: 'smooth' 
1336			}); 
1337			setTimeout(function() { 
1338				element.focus(); 
1339			}, 400); 
1340
1341	})(); 
1342</script>