{"id":5206,"date":"2014-08-06T08:40:48","date_gmt":"2014-08-06T08:40:48","guid":{"rendered":"https:\/\/demo.wpzoom.com\/inspiro\/?page_id=5206"},"modified":"2026-03-17T16:47:13","modified_gmt":"2026-03-17T16:47:13","slug":"portfolio","status":"publish","type":"page","link":"https:\/\/egmbimgroup.com\/index.php\/portfolio\/","title":{"rendered":"Portfolio"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"5206\" class=\"elementor elementor-5206\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8ffb502 e-flex e-con-boxed e-con e-parent\" data-id=\"8ffb502\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-0fd031b e-con-full e-flex e-con e-child\" data-id=\"0fd031b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6622f2b elementor-widget elementor-widget-counter\" data-id=\"6622f2b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"counter.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-counter\">\n\t\t\t<div class=\"elementor-counter-title\">OBRAS<\/div>\t\t\t<div class=\"elementor-counter-number-wrapper\">\n\t\t\t\t<span class=\"elementor-counter-number-prefix\"><\/span>\n\t\t\t\t<span class=\"elementor-counter-number\" data-duration=\"2000\" data-to-value=\"32\" data-from-value=\"0\" data-delimiter=\",\">0<\/span>\n\t\t\t\t<span class=\"elementor-counter-number-suffix\"><\/span>\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-a66e33f e-con-full e-flex e-con e-child\" data-id=\"a66e33f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-16b1b67 elementor-widget elementor-widget-counter\" data-id=\"16b1b67\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"counter.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-counter\">\n\t\t\t<div class=\"elementor-counter-title\">PROYECTOS<\/div>\t\t\t<div class=\"elementor-counter-number-wrapper\">\n\t\t\t\t<span class=\"elementor-counter-number-prefix\"><\/span>\n\t\t\t\t<span class=\"elementor-counter-number\" data-duration=\"2000\" data-to-value=\"51\" data-from-value=\"0\" data-delimiter=\",\">0<\/span>\n\t\t\t\t<span class=\"elementor-counter-number-suffix\"><\/span>\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8b50edd e-con-full e-flex e-con e-child\" data-id=\"8b50edd\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-610ade0 elementor-widget elementor-widget-counter\" data-id=\"610ade0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"counter.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-counter\">\n\t\t\t<div class=\"elementor-counter-title\">PAISES<\/div>\t\t\t<div class=\"elementor-counter-number-wrapper\">\n\t\t\t\t<span class=\"elementor-counter-number-prefix\"><\/span>\n\t\t\t\t<span class=\"elementor-counter-number\" data-duration=\"2000\" data-to-value=\"4\" data-from-value=\"0\" data-delimiter=\",\">0<\/span>\n\t\t\t\t<span class=\"elementor-counter-number-suffix\"><\/span>\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-960c267 e-flex e-con-boxed e-con e-parent\" data-id=\"960c267\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e5953ba elementor-widget elementor-widget-shortcode\" data-id=\"e5953ba\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">  <div id=\"uy_map_832a58b9-cf44-4c04-bed1-33af6da9dab6\" style=\"width:100%; height:650px; border-radius:12px; overflow:hidden;\"><\/div>\n\n  <script>\n  (function() {\n    const mapId = \"uy_map_832a58b9-cf44-4c04-bed1-33af6da9dab6\";\n    const csvBaseUrl = \"https:\\\/\\\/egmbimgroup.com\\\/wp-content\\\/uploads\\\/sucursales.csv\";\n    const initialZoom = 7;\n\n    function parseCSV(text) {\n      const rows = [];\n      let row = [];\n      let cur = '';\n      let inQuotes = false;\n\n      for (let i = 0; i < text.length; i++) {\n        const ch = text[i];\n        const next = text[i+1];\n\n        if (ch === '\"' && inQuotes && next === '\"') { cur += '\"'; i++; continue; }\n        if (ch === '\"') { inQuotes = !inQuotes; continue; }\n\n        if (ch === ',' && !inQuotes) { row.push(cur); cur = ''; continue; }\n\n        if ((ch === '\\n' || ch === '\\r') && !inQuotes) {\n          if (ch === '\\r' && next === '\\n') i++;\n          row.push(cur); cur = '';\n          if (row.some(v => String(v).trim() !== '')) rows.push(row);\n          row = [];\n          continue;\n        }\n\n        cur += ch;\n      }\n\n      row.push(cur);\n      if (row.some(v => String(v).trim() !== '')) rows.push(row);\n      return rows;\n    }\n\n    function escapeHtml(s) {\n      return String(s).replace(\/[&<>\"']\/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#039;'}[m]));\n    }\n    function escapeAttr(s) { return String(s).replace(\/\"\/g, '%22').trim(); }\n\n    function whenLeafletReady(cb) {\n      if (typeof window.L !== 'undefined' && window.L && typeof window.L.map === 'function') return cb();\n      let tries = 0;\n      const t = setInterval(() => {\n        tries++;\n        if (typeof window.L !== 'undefined' && window.L && typeof window.L.map === 'function') {\n          clearInterval(t);\n          cb();\n        } else if (tries > 80) { \/\/ ~4s\n          clearInterval(t);\n          console.error('Leaflet no carg\u00f3 (L undefined).');\n        }\n      }, 50);\n    }\n\n    function init() {\n      const map = L.map(mapId).setView([-32.5228, -55.7658], initialZoom);\n\n      L.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png', {\n        maxZoom: 19,\n        attribution: '\u00a9 OpenStreetMap'\n      }).addTo(map);\n\n      const markersLayer = L.layerGroup().addTo(map);\n\n      async function loadMarkers() {\n        const csvUrl = csvBaseUrl + (csvBaseUrl.includes('?') ? '&' : '?') + 'v=' + Date.now();\n\n        try {\n          const res = await fetch(csvUrl, { cache: 'no-store' });\n          if (!res.ok) throw new Error('HTTP ' + res.status);\n          const text = await res.text();\n\n          const rows = parseCSV(text);\n          if (!rows.length) throw new Error('CSV vac\u00edo');\n\n          const header = rows[0].map(h => h.trim().toLowerCase());\n          const idx = {\n            lat: header.indexOf('lat'),\n            lon: header.indexOf('lon'),\n            nombre: header.indexOf('nombre'),\n            direccion: header.indexOf('direccion'),\n            datos: header.indexOf('datos'),\n            link: header.indexOf('link')\n          };\n\n          if (idx.lat === -1 || idx.lon === -1 || idx.nombre === -1) {\n            throw new Error('Columnas requeridas: lat, lon, nombre (opcionales: direccion, datos, link)');\n          }\n\n          markersLayer.clearLayers();\n\n          let bounds = null;\n          let count = 0;\n\n          for (let i = 1; i < rows.length; i++) {\n            const r = rows[i];\n\n            const lat = parseFloat((r[idx.lat] || '').trim());\n            const lon = parseFloat((r[idx.lon] || '').trim());\n            const nombre = (r[idx.nombre] || '').trim();\n            const direccion = idx.direccion !== -1 ? (r[idx.direccion] || '').trim() : '';\n            const datos = idx.datos !== -1 ? (r[idx.datos] || '').trim() : '';\n            const link = idx.link !== -1 ? (r[idx.link] || '').trim() : '';\n\n            if (!nombre || Number.isNaN(lat) || Number.isNaN(lon)) continue;\n\n            const tooltip = [nombre, direccion].filter(Boolean).join(' \u2014 ');\n\n            const popupParts = [];\n            popupParts.push('<div style=\"font-size:14px; line-height:1.35;\">');\n            popupParts.push('<div style=\"font-weight:700; margin-bottom:4px;\">' + escapeHtml(nombre) + '<\/div>');\n            if (direccion) popupParts.push('<div><strong>Detalle:<\/strong> ' + escapeHtml(direccion) + '<\/div>');\n            if (datos) popupParts.push('<div><strong>Datos:<\/strong> ' + escapeHtml(datos) + '<\/div>');\n            if (link) popupParts.push('<div style=\"margin-top:8px;\"><a href=\"' + escapeAttr(link) + '\" target=\"_blank\" rel=\"noopener\">M\u00e1s Informaci\u00f3n<\/a><\/div>');\n            popupParts.push('<\/div>');\n\n            const marker = L.marker([lat, lon]).bindPopup(popupParts.join(''));\n            if (tooltip) marker.bindTooltip(tooltip, { direction: 'top' });\n            marker.addTo(markersLayer);\n\n            const ll = L.latLng(lat, lon);\n            bounds = bounds ? bounds.extend(ll) : L.latLngBounds(ll, ll);\n            count++;\n          }\n\n          \/\/ Auto-zoom a los puntos (si hay al menos 1)\n          if (count === 1 && bounds) {\n            map.setView(bounds.getCenter(), Math.min(14, Math.max(10, initialZoom)));\n          } else if (count > 1 && bounds) {\n            map.fitBounds(bounds.pad(0.12), { animate: true });\n          }\n\n        } catch (e) {\n          console.error(e);\n        }\n      }\n\n      loadMarkers();\n    }\n\n    document.addEventListener('DOMContentLoaded', function () {\n      whenLeafletReady(init);\n    });\n  })();\n  <\/script>\n  <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>OBRAS 0 PROYECTOS 0 PAISES 0<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"page-templates\/full-width-builder-bb.php","meta":{"_themeisle_gutenberg_block_has_review":false,"inspiro_hide_title":true,"footnotes":""},"class_list":["post-5206","page","type-page","status-publish","hentry"],"featured_media_urls":[],"_links":{"self":[{"href":"https:\/\/egmbimgroup.com\/index.php\/wp-json\/wp\/v2\/pages\/5206","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/egmbimgroup.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/egmbimgroup.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/egmbimgroup.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/egmbimgroup.com\/index.php\/wp-json\/wp\/v2\/comments?post=5206"}],"version-history":[{"count":13,"href":"https:\/\/egmbimgroup.com\/index.php\/wp-json\/wp\/v2\/pages\/5206\/revisions"}],"predecessor-version":[{"id":7538,"href":"https:\/\/egmbimgroup.com\/index.php\/wp-json\/wp\/v2\/pages\/5206\/revisions\/7538"}],"wp:attachment":[{"href":"https:\/\/egmbimgroup.com\/index.php\/wp-json\/wp\/v2\/media?parent=5206"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}