1import { api } from "./api.js"; 2import { insertarBuscadorInput } from "./interface.js"; 3 4let siteMap = new Map(); 5 6document.addEventListener("DOMContentLoaded", async () => { 7 insertarBuscadorInput(); 8 // 1) Procesar subsitios de primer nivel 9 const todosSubsitios = await api.obtenerSubsitios(); 10 const subsitiosPrimerNivelEspecificos = 11 await api.obtenerSubsitiosPrimerNivelEspecificos(todosSubsitios); 12 for (const subsitio of subsitiosPrimerNivelEspecificos) { 13 const paginas = await api.obtenerPaginasSubsitio(subsitio.Url); 14 const listas = await api.obtenerListas(subsitio.Url); 15 16 const listasFiltradas = []; 17 listas.forEach((lista) => { 18 api.LISTAS_ESPECIFICAS.forEach(async (listaEspecifica) => { 19 if (lista.Title === listaEspecifica.nombre) { 20 const itemsRaw = await api.obtenerElementosLista( 21 subsitio.Url, 22 listaEspecifica.nombre, 23 listaEspecifica.campos 24 ); 25 const items = itemsRaw.map((item) => ({ 26 Title: 27 item.FileLeafRef?.replace(/\.[^/.]+$/, "").replace( 28 /[-_]/g, 29 " " 30 ) ?? item.Title, 31 Url: 32 item.FileRef || 33 item.Pagina || 34 item["Trámite Online"]?.split(",")[0].trim(), 35 Description: 36 item.Description || item.Descripcion || item["Descripción"], 37 })); 38 listasFiltradas.push({ nombre: listaEspecifica.nombre, items }); 39 } 40 }); 41 }); 42 siteMap.set(subsitio.Url, { 43 title: subsitio.Title, 44 url: subsitio.Url, 45 pages: paginas, 46 listas: listasFiltradas, 47 }); 48 } 49 50 // 2) Procesar subsitios de segundo nivel 51 for (const subsitio of todosSubsitios) { 52 if ( 53 subsitio.Url.split("/").filter(Boolean).length === 2 && 54 !siteMap.has(subsitio.Url) 55 ) { 56 const paginaPrincipal = await api.obtenerPaginaPrincipalSubsitio( 57 subsitio.Url 58 ); 59 if (paginaPrincipal) { 60 siteMap.set(subsitio.Url, { 61 title: subsitio.Title, 62 url: subsitio.Url, 63 mainPage: paginaPrincipal, 64 }); 65 } 66 } 67 } 68 69 // 3) Procesar la raÃz "/" 70 const raiz = "/"; 71 const paginasRaiz = await api.obtenerPaginasSubsitio(raiz); 72 const listasRaiz = await api.obtenerListas(raiz); 73 74 const listasFiltradasRaiz = []; 75 listasRaiz.forEach((lista) => { 76 api.LISTAS_ESPECIFICAS.forEach(async (listaEspecifica) => { 77 if (lista.Title === listaEspecifica.nombre) { 78 const itemsRaw = await api.obtenerElementosLista( 79 raiz, 80 listaEspecifica.nombre, 81 listaEspecifica.campos 82 ); 83 const items = itemsRaw.map((item) => ({ 84 Title: 85 item.FileLeafRef?.replace(/\.[^/.]+$/, "").replace(/[-_]/g, " ") ?? 86 item.Title, 87 Url: 88 item.FileRef || 89 item.Pagina || 90 item["Trámite Online"]?.split(",")[0].trim(), 91 Description: 92 item.Description || item.Descripcion || item["Descripción"], 93 })); 94 listasFiltradasRaiz.push({ nombre: listaEspecifica.nombre, items }); 95 } 96 }); 97 }); 98 99 siteMap.set(raiz, { 100 title: "Home", 101 url: raiz, 102 pages: paginasRaiz, 103 listas: listasFiltradasRaiz, 104 }); 105}); 106 107export function buscarCoincidenciasDesdeSiteMap(texto) { 108 const textoNormalizado = normalizarTexto(texto); 109 const resultados = []; 110 const seen = new Set(); // dedupe real por Title+Url 111 112 for (const sitio of siteMap?.values?.() || []) { 113 if (sitio?.pages?.length) { 114 for (const pagina of sitio.pages) { 115 const titulo = normalizarTexto(pagina.Title || ""); 116 const descripcion = normalizarTexto(pagina.Description || ""); 117 if ( 118 titulo.includes(textoNormalizado) || 119 descripcion.includes(textoNormalizado) || 120 (sitio.title || "").toLowerCase().includes(textoNormalizado) 121 ) { 122 const item = { 123 Title: pagina.Title, 124 Url: pagina.FileRef || pagina.Url, 125 Comments: pagina.Description || "", 126 Location: sitio.title, 127 };
128 const key = `${item.Title}::${item.Url}`; 129 if (!seen.has(key)) { 130 seen.add(key); 131 resultados.push(item); 132 } 133 } 134 } 135 } 136 137 if (sitio?.listas?.length) { 138 for (const lista of sitio.listas) { 139 for (const item of lista.items) { 140 const titulo = normalizarTexto(item.Title || ""); 141 const descripcion = normalizarTexto( 142 item.Description || item.Descripcion || item["Descripción"] || "" 143 ); 144 if ( 145 titulo.includes(textoNormalizado) || 146 descripcion.includes(textoNormalizado) 147 ) { 148 const node = { 149 Title: item.Title, 150 Url: item.Url, 151 Comments: 152 item.Description || 153 item.Descripcion || 154 item["Descripción"] || 155 "", 156 Location: lista.nombre, 157 }; 158 const key = `${node.Title}::${node.Url}`; 159 if (!seen.has(key)) { 160 seen.add(key); 161 resultados.push(node); 162 } 163 } 164 } 165 } 166 } 167 } 168 return resultados; 169} 170 171function normalizarTexto(texto) { 172 return texto 173 .toLowerCase() 174 .normalize("NFD") 175 .replace(/[\u0300-\u036f]/g, "") 176 .replace(/[^\w\sñ]/gi, "") 177 .replace(/\s+/g, " "); 178}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.