{"id":2990,"date":"2025-12-05T11:44:08","date_gmt":"2025-12-05T16:44:08","guid":{"rendered":"https:\/\/biblioteca.utc.edu.ec\/?page_id=2990"},"modified":"2025-12-05T14:26:28","modified_gmt":"2025-12-05T19:26:28","slug":"web-scraper","status":"publish","type":"page","link":"https:\/\/biblioteca.utc.edu.ec\/?page_id=2990","title":{"rendered":"Web Scraper"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"es\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Scraper Web Premium<\/title>\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Outfit:wght@300;400;600;700&#038;display=swap\" rel=\"stylesheet\">\n    <style>\n        :root {\n            --primary: #2563eb;\n            \/* Professional Blue *\/\n            --primary-hover: #1d4ed8;\n            --bg-color: #f8fafc;\n            \/* Light Slate Background *\/\n            --surface: #ffffff;\n            \/* White Surface *\/\n            --text-primary: #0f172a;\n            \/* Dark Slate Text *\/\n            --text-secondary: #64748b;\n            \/* Muted Text *\/\n            --border-color: #e2e8f0;\n            \/* Light Border *\/\n            --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);\n        }\n\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n            font-family: 'Outfit', sans-serif;\n        }\n\n        body {\n            min-height: 100vh;\n            background-color: var(--bg-color);\n            color: var(--text-primary);\n            display: flex;\n            justify-content: center;\n            padding: 40px 20px;\n            line-height: 1.5;\n        }\n\n        \/* Removed background blobs for a cleaner, sober look as requested *\/\n        .background-blobs {\n            display: none;\n        }\n\n        \/* Main Container *\/\n        .glass-container {\n            width: 100%;\n            max-width: 900px;\n            background: var(--surface);\n            border: 1px solid var(--border-color);\n            border-radius: 16px;\n            padding: 40px;\n            box-shadow: var(--shadow);\n            margin-top: 20px;\n        }\n\n        header {\n            text-align: center;\n            margin-bottom: 40px;\n            border-bottom: 1px solid var(--border-color);\n            padding-bottom: 20px;\n        }\n\n        h1 {\n            font-size: 2.5rem;\n            font-weight: 700;\n            margin-bottom: 8px;\n            color: var(--text-primary);\n            letter-spacing: -0.5px;\n        }\n\n        .highlight {\n            color: var(--primary);\n            background: none;\n            -webkit-text-fill-color: initial;\n        }\n\n        header p {\n            color: var(--text-secondary);\n            font-size: 1.1rem;\n        }\n\n        \/* Search Section *\/\n        .search-section {\n            margin-bottom: 30px;\n        }\n\n        .input-group {\n            display: flex;\n            gap: 10px;\n            background: var(--surface);\n            padding: 6px;\n            border-radius: 12px;\n            border: 1px solid var(--border-color);\n            box-shadow: var(--shadow);\n            transition: all 0.2s;\n        }\n\n        .input-group:focus-within {\n            border-color: var(--primary);\n            box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n        }\n\n        input {\n            flex: 1;\n            background: transparent;\n            border: none;\n            padding: 12px 20px;\n            color: var(--text-primary);\n            font-size: 1rem;\n            outline: none;\n        }\n\n        input::placeholder {\n            color: #94a3b8;\n        }\n\n        button#searchBtn {\n            background: var(--primary);\n            border: none;\n            padding: 10px 24px;\n            border-radius: 8px;\n            color: white;\n            font-weight: 600;\n            cursor: pointer;\n            transition: background 0.2s;\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        button#searchBtn:hover {\n            background: var(--primary-hover);\n        }\n\n        \/* Sources Management *\/\n        .sources-control {\n            margin-top: 15px;\n        }\n\n        .text-btn {\n            background: none;\n            border: none;\n            color: var(--text-secondary);\n            cursor: pointer;\n            font-size: 0.9rem;\n            padding: 5px 0;\n            font-weight: 500;\n        }\n\n        .text-btn:hover {\n            color: var(--primary);\n        }\n\n        .sources-panel {\n            background: #f1f5f9;\n            padding: 20px;\n            border-radius: 12px;\n            margin-top: 10px;\n            border: 1px solid var(--border-color);\n        }\n\n        .add-source-group {\n            display: flex;\n            gap: 10px;\n            margin-bottom: 15px;\n        }\n\n        #newSourceInput {\n            background: var(--surface);\n            border: 1px solid var(--border-color);\n            border-radius: 8px;\n            padding: 8px 12px;\n        }\n\n        .sm-btn {\n            background: var(--primary);\n            border: none;\n            color: white;\n            width: 36px;\n            height: 36px;\n            border-radius: 8px;\n            cursor: pointer;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-size: 1.2rem;\n        }\n\n        .sources-list {\n            list-style: none;\n            max-height: 200px;\n            overflow-y: auto;\n        }\n\n        .sources-list li {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            padding: 10px;\n            background: var(--surface);\n            margin-bottom: 6px;\n            border-radius: 8px;\n            font-size: 0.9rem;\n            border: 1px solid var(--border-color);\n            color: var(--text-primary);\n        }\n\n        .remove-source-btn {\n            background: none;\n            border: none;\n            color: #cbd5e1;\n            cursor: pointer;\n            font-size: 1.2rem;\n            transition: color 0.2s;\n        }\n\n        .remove-source-btn:hover {\n            color: #ef4444;\n        }\n\n        \/* Results Grid *\/\n        .results-grid {\n            display: grid;\n            grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n            gap: 24px;\n            margin-top: 30px;\n        }\n\n        .article-card {\n            background: var(--surface);\n            border: 1px solid var(--border-color);\n            border-radius: 12px;\n            padding: 24px;\n            transition: all 0.2s;\n            cursor: pointer;\n            display: flex;\n            flex-direction: column;\n            box-shadow: var(--shadow);\n        }\n\n        .article-card:hover {\n            transform: translateY(-4px);\n            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);\n            border-color: var(--primary);\n        }\n\n        .article-source {\n            font-size: 0.75rem;\n            color: var(--text-secondary);\n            text-transform: uppercase;\n            font-weight: 700;\n            margin-bottom: 12px;\n            letter-spacing: 0.5px;\n        }\n\n        .article-card h3 {\n            font-size: 1.15rem;\n            font-weight: 600;\n            margin-bottom: 12px;\n            color: var(--text-primary);\n            line-height: 1.4;\n        }\n\n        .article-snippet {\n            font-size: 0.95rem;\n            color: var(--text-secondary);\n            line-height: 1.6;\n            flex: 1;\n            display: -webkit-box;\n            -webkit-line-clamp: 3;\n            -webkit-box-orient: vertical;\n            overflow: hidden;\n        }\n\n        .read-more {\n            margin-top: 20px;\n            font-size: 0.9rem;\n            color: var(--primary);\n            font-weight: 600;\n        }\n\n        \/* Reading View *\/\n        #readingView {\n            background: var(--surface);\n            animation: fadeIn 0.3s;\n        }\n\n        #resultTitle {\n            font-size: 2rem;\n            color: var(--text-primary);\n            margin-bottom: 24px;\n            line-height: 1.3;\n        }\n\n        .content-area {\n            color: var(--text-primary);\n            line-height: 1.8;\n            font-size: 1.1rem;\n        }\n\n        .content-area p {\n            margin-bottom: 1.5em;\n        }\n\n        \/* Loading *\/\n        .hidden {\n            display: none !important;\n        }\n\n        #loading {\n            text-align: center;\n            padding: 40px;\n            color: var(--text-secondary);\n        }\n\n        .spinner {\n            width: 40px;\n            height: 40px;\n            border: 4px solid #e2e8f0;\n            border-left-color: var(--primary);\n            border-radius: 50%;\n            margin: 0 auto 15px;\n            animation: spin 1s linear infinite;\n        }\n\n        @keyframes spin {\n            to {\n                transform: rotate(360deg);\n            }\n        }\n\n        @keyframes fadeIn {\n            from {\n                opacity: 0;\n            }\n\n            to {\n                opacity: 1;\n            }\n        }\n\n        \/* Responsive *\/\n        @media (max-width: 600px) {\n            body {\n                padding: 10px;\n            }\n\n            .glass-container {\n                padding: 20px;\n            }\n\n            h1 {\n                font-size: 2rem;\n            }\n\n            .input-group {\n                flex-direction: column;\n                padding: 10px;\n            }\n\n            button#searchBtn {\n                width: 100%;\n                justify-content: center;\n            }\n        }\n    <\/style>\n<\/head>\n\n<body>\n    <div class=\"background-blobs\">\n        <div class=\"blob blob-1\"><\/div>\n        <div class=\"blob blob-2\"><\/div>\n        <div class=\"blob blob-3\"><\/div>\n    <\/div>\n\n    <main class=\"glass-container\">\n        <header>\n            <h1>Web Scraper <span class=\"highlight\">Pro<\/span><\/h1>\n            <p>Extrae contenido de blogs al instante. Puedes Gestionar tus propias fuentes y encontrar desde un mismo lugar la noticia que quieras&#8230;<\/p>\n        <\/header>\n\n        <!-- Search Section -->\n        <div class=\"search-section\">\n            <div class=\"input-group\">\n                <input type=\"text\" id=\"searchInput\" placeholder=\"Buscar noticias (ej. cambio clim\u00e1tico)...\">\n                <button id=\"searchBtn\">\n                    <span class=\"btn-text\">Buscar<\/span>\n                    <span class=\"btn-icon\">\ud83d\udd0d<\/span>\n                <\/button>\n            <\/div>\n\n            <div class=\"sources-control\">\n                <button id=\"toggleSourcesBtn\" class=\"text-btn\">Gestionar Fuentes \u25be<\/button>\n                <div id=\"sourcesPanel\" class=\"sources-panel hidden\">\n                    <div class=\"add-source-group\">\n                        <input type=\"url\" id=\"newSourceInput\" placeholder=\"https:\/\/mi-blog.blogspot.com\">\n                        <button id=\"addSourceBtn\" class=\"sm-btn\">+<\/button>\n                    <\/div>\n                    <ul id=\"sourcesList\" class=\"sources-list\">\n                        <!-- Sources will be injected here -->\n                    <\/ul>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Search Results (New) -->\n        <div id=\"searchResults\" class=\"results-grid hidden\">\n            <!-- Article Cards will go here -->\n        <\/div>\n\n        <!-- Reading View (Hidden by default, overlays or replaces results) -->\n        <div id=\"readingView\" class=\"hidden\">\n            <button id=\"backToResultsBtn\" class=\"text-btn\">\u2190 Volver a los resultados<\/button>\n\n            <div id=\"loading\" class=\"hidden\">\n                <div class=\"spinner\"><\/div>\n                <p>Analizando sitio web&#8230;<\/p>\n            <\/div>\n\n            <div id=\"resultContainer\" class=\"hidden\">\n                <div class=\"result-header\">\n                    <span class=\"badge\">Resultado<\/span>\n                    <button id=\"copyBtn\" class=\"icon-btn\" title=\"Copiar texto\">\ud83d\udccb<\/button>\n                <\/div>\n                <h2 id=\"resultTitle\"><\/h2>\n                <div id=\"resultContent\" class=\"content-area\"><\/div>\n            <\/div>\n        <\/div> <!-- End readingView -->\n    <\/main>\n\n    <script>\n        document.addEventListener('DOMContentLoaded', () => {\n            \/\/ --- Elements ---\n            const searchInput = document.getElementById('searchInput');\n            const searchBtn = document.getElementById('searchBtn');\n\n            \/\/ Sources UI\n            const toggleSourcesBtn = document.getElementById('toggleSourcesBtn');\n            const sourcesPanel = document.getElementById('sourcesPanel');\n            const newSourceInput = document.getElementById('newSourceInput');\n            const addSourceBtn = document.getElementById('addSourceBtn');\n            const sourcesList = document.getElementById('sourcesList');\n\n            \/\/ Results UI\n            const searchResults = document.getElementById('searchResults');\n            const readingView = document.getElementById('readingView');\n            const backToResultsBtn = document.getElementById('backToResultsBtn');\n\n            \/\/ Reading View Elements\n            const resultContainer = document.getElementById('resultContainer');\n            const resultTitle = document.getElementById('resultTitle');\n            const resultContent = document.getElementById('resultContent');\n            const loading = document.getElementById('loading');\n            const copyBtn = document.getElementById('copyBtn');\n\n            \/\/ --- State ---\n            const defaultSources = [\n                'https:\/\/boletinscielomx.blogspot.com',\n                'https:\/\/www.infobae.com',\n                'https:\/\/www.lapatilla.com',\n                'https:\/\/www.huffingtonpost.es',\n                'https:\/\/www.bbc.com\/mundo',\n                'https:\/\/elpais.com',\n                'https:\/\/elmundotoday.com',\n                'https:\/\/elpitazo.net',\n                'https:\/\/rebelion.org'\n            ];\n\n            let sources = JSON.parse(localStorage.getItem('news_sources'));\n\n            \/\/ If no sources in storage, or if we want to ensure these defaults exist\n            if (!sources || sources.length === 0) {\n                sources = defaultSources;\n                localStorage.setItem('news_sources', JSON.stringify(sources));\n            }\n\n            \/\/ --- Initialization ---\n            renderSources();\n\n            \/\/ --- Event Listeners ---\n            searchBtn.addEventListener('click', handleSearch);\n            searchInput.addEventListener('keypress', (e) => {\n                if (e.key === 'Enter') handleSearch();\n            });\n\n            toggleSourcesBtn.addEventListener('click', () => {\n                sourcesPanel.classList.toggle('hidden');\n            });\n\n            addSourceBtn.addEventListener('click', addSource);\n\n            backToResultsBtn.addEventListener('click', () => {\n                readingView.classList.add('hidden');\n                searchResults.classList.remove('hidden');\n            });\n\n            copyBtn.addEventListener('click', copyToClipboard);\n\n            \/\/ --- Source Management ---\n            function addSource() {\n                const url = newSourceInput.value.trim();\n                if (url && !sources.includes(url)) {\n                    sources.push(url);\n                    saveSources();\n                    renderSources();\n                    newSourceInput.value = '';\n                }\n            }\n\n            function removeSource(url) {\n                sources = sources.filter(s => s !== url);\n                saveSources();\n                renderSources();\n            }\n\n            function saveSources() {\n                localStorage.setItem('news_sources', JSON.stringify(sources));\n            }\n\n            function renderSources() {\n                sourcesList.innerHTML = sources.map(url => `\n            <li>\n                <span style=\"overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\">${url}<\/span>\n                <button class=\"remove-source-btn\" onclick=\"document.dispatchEvent(new CustomEvent('remove-source', {detail: '${url}'}))\">\u00d7<\/button>\n            <\/li>\n        `).join('');\n            }\n\n            \/\/ Event delegation for remove buttons\n            document.addEventListener('remove-source', (e) => {\n                removeSource(e.detail);\n            });\n\n            \/\/ --- Search Logic ---\n            async function handleSearch() {\n                const query = searchInput.value.trim();\n                if (!query) return;\n\n                \/\/ UI State: Loading\n                searchBtn.disabled = true;\n                searchResults.innerHTML = '<div class=\"spinner\"><\/div><p style=\"text-align:center; color:var(--text-secondary);\">Buscando en todas las fuentes...<\/p>';\n                searchResults.classList.remove('hidden');\n                readingView.classList.add('hidden');\n\n                try {\n                    const allResults = await Promise.all(sources.map(source => searchInSource(source, query)));\n                    const flatResults = allResults.flat();\n                    renderResults(flatResults);\n                } catch (error) {\n                    console.error(error);\n                    searchResults.innerHTML = '<p class=\"error\">Error al buscar.<\/p>';\n                } finally {\n                    searchBtn.disabled = false;\n                }\n            }\n\n            async function searchInSource(baseUrl, query) {\n                try {\n                    if (!baseUrl.startsWith('http')) baseUrl = 'https:\/\/' + baseUrl;\n\n                    const searchUrl = `${baseUrl.replace(\/\\\/$\/, '')}\/search?q=${encodeURIComponent(query)}`;\n                    const proxyUrl = `https:\/\/corsproxy.io\/?${encodeURIComponent(searchUrl)}`;\n                    const response = await fetch(proxyUrl);\n                    const html = await response.text();\n\n                    const parser = new DOMParser();\n                    const doc = parser.parseFromString(html, 'text\/html');\n\n                    const articles = [];\n                    const items = doc.querySelectorAll('.post, article, .entry, .post-outer, .news-item, .story, .bbc-1f5r4p');\n\n                    items.forEach(item => {\n                        const titleEl = item.querySelector('.post-title a, .entry-title a, h2 a, h3 a, .story__title a, .promo-text a');\n                        const link = titleEl ? titleEl.href : null;\n                        const title = titleEl ? titleEl.innerText.trim() : 'Sin t\u00edtulo';\n\n                        const snippetEl = item.querySelector('.post-body, .entry-content, .post-snippet, p');\n                        let snippet = snippetEl ? snippetEl.innerText.substring(0, 150) + '...' : '';\n\n                        if (link && title && title.length > 5) {\n                            let absoluteLink = link;\n                            const hrefAttr = titleEl.getAttribute('href');\n                            if (hrefAttr && !hrefAttr.startsWith('http')) {\n                                const urlObj = new URL(baseUrl);\n                                if (hrefAttr.startsWith('\/')) {\n                                    absoluteLink = `${urlObj.origin}${hrefAttr}`;\n                                } else {\n                                    absoluteLink = `${urlObj.origin}\/${hrefAttr}`;\n                                }\n                            }\n\n                            articles.push({\n                                title,\n                                link: absoluteLink,\n                                snippet,\n                                source: new URL(baseUrl).hostname\n                            });\n                        }\n                    });\n\n                    return articles;\n\n                } catch (e) {\n                    console.warn(`Skipping ${baseUrl}:`, e);\n                    return [];\n                }\n            }\n\n            function renderResults(articles) {\n                if (articles.length === 0) {\n                    searchResults.innerHTML = '<p style=\"text-align:center; color:var(--text-secondary); grid-column: 1\/-1;\">No se encontraron resultados. Intenta con otros t\u00e9rminos.<\/p>';\n                    return;\n                }\n\n                searchResults.innerHTML = articles.map(article => `\n            <div class=\"article-card\" data-link=\"${article.link}\">\n                <div class=\"article-source\">${article.source}<\/div>\n                <h3>${article.title}<\/h3>\n                <p class=\"article-snippet\">${article.snippet}<\/p>\n                <div class=\"read-more\">Leer art\u00edculo \u2192<\/div>\n            <\/div>\n        `).join('');\n\n                document.querySelectorAll('.article-card').forEach(card => {\n                    card.addEventListener('click', () => {\n                        const link = card.dataset.link;\n                        fetchAndDisplayArticle(link);\n                    });\n                });\n            }\n\n            \/\/ --- Article Scraping ---\n            async function fetchAndDisplayArticle(url) {\n                searchResults.classList.add('hidden');\n                readingView.classList.remove('hidden');\n                loading.classList.remove('hidden');\n                resultContainer.classList.add('hidden');\n\n                try {\n                    const proxyUrl = `https:\/\/corsproxy.io\/?${encodeURIComponent(url)}`;\n                    const response = await fetch(proxyUrl);\n                    if (!response.ok) throw new Error('Error network');\n                    const html = await response.text();\n\n                    const parser = new DOMParser();\n                    const doc = parser.parseFromString(html, 'text\/html');\n\n                    const title = doc.querySelector('.post-title, h1.entry-title, h3.post-title, h1')?.innerText.trim() || 'Noticia';\n                    let content = '';\n\n                    const contentElement = doc.querySelector('.post-body, .entry-content, article, .article-body, .story-body, .mw-parser-output');\n\n                    if (contentElement) {\n                        const scripts = contentElement.querySelectorAll('script, style, iframe, .advertisement');\n                        scripts.forEach(s => s.remove());\n                        content = contentElement.innerHTML;\n                    } else {\n                        content = 'No se pudo extraer el contenido principal autom\u00e1ticamente.';\n                    }\n\n                    resultTitle.textContent = title;\n                    resultContent.innerHTML = content;\n                    resultContainer.classList.remove('hidden');\n\n                } catch (error) {\n                    alert('Error al cargar la noticia: ' + error.message);\n                    readingView.classList.add('hidden');\n                    searchResults.classList.remove('hidden');\n                } finally {\n                    loading.classList.add('hidden');\n                }\n            }\n\n            function copyToClipboard() {\n                const text = `${resultTitle.innerText}\\n\\n${resultContent.innerText}`;\n                navigator.clipboard.writeText(text).then(() => {\n                    const originalIcon = copyBtn.innerText;\n                    copyBtn.innerText = '\u2705';\n                    setTimeout(() => copyBtn.innerText = originalIcon, 2000);\n                });\n            }\n        });\n    <\/script>\n<\/body>\n\n<\/html>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Scraper Web Premium Web Scraper Pro Extrae contenido de blogs al instante. Puedes Gestionar tus propias fuentes y encontrar desde [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_eb_attr":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-2990","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/biblioteca.utc.edu.ec\/index.php?rest_route=\/wp\/v2\/pages\/2990","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/biblioteca.utc.edu.ec\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/biblioteca.utc.edu.ec\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/biblioteca.utc.edu.ec\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/biblioteca.utc.edu.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2990"}],"version-history":[{"count":23,"href":"https:\/\/biblioteca.utc.edu.ec\/index.php?rest_route=\/wp\/v2\/pages\/2990\/revisions"}],"predecessor-version":[{"id":3013,"href":"https:\/\/biblioteca.utc.edu.ec\/index.php?rest_route=\/wp\/v2\/pages\/2990\/revisions\/3013"}],"wp:attachment":[{"href":"https:\/\/biblioteca.utc.edu.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2990"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}