{"id":47,"date":"2025-12-08T16:31:08","date_gmt":"2025-12-08T16:31:08","guid":{"rendered":"http:\/\/178.62.106.99\/?page_id=47"},"modified":"2026-04-28T23:33:46","modified_gmt":"2026-04-28T23:33:46","slug":"about-us","status":"publish","type":"page","link":"https:\/\/v1.ecrn-owc.eu\/index.php\/about-us\/","title":{"rendered":"About us"},"content":{"rendered":"\n<div class=\"wp-block-group alignfull has-global-padding is-layout-constrained wp-block-group-is-layout-constrained\" style=\"margin-top:0;margin-bottom:0\">\n<div class=\"wp-block-columns alignfull is-layout-flex wp-container-core-columns-is-layout-9c22b1e3 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:55%\">\n<div class=\"wp-block-cover is-light\"><img loading=\"lazy\" decoding=\"async\" width=\"3514\" height=\"1994\" class=\"wp-block-cover__image-background wp-image-118 size-full\" alt=\"\" src=\"https:\/\/v1.ecrn-owc.eu\/wp-content\/uploads\/2025\/12\/frontpage.png\" data-object-fit=\"cover\"\/><span aria-hidden=\"true\" class=\"wp-block-cover__background has-background-dim-0 has-background-dim\" style=\"background-color:#919a9b\"><\/span><div class=\"wp-block-cover__inner-container is-layout-flow wp-block-cover-is-layout-flow\">\n<div style=\"height:var(--wp--preset--spacing--20)\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\" style=\"padding-top:var(--wp--preset--spacing--60);padding-right:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)\">\n<h2 class=\"wp-block-heading has-xx-large-font-size\">European Collaborative Research Network<\/h2>\n\n\n\n<p>On Optical Wireless Communications<\/p>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>ECRN Countries Map<\/title>\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/d3\/7.8.5\/d3.min.js\"><\/script>\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/topojson\/3.0.2\/topojson.min.js\"><\/script>\n    <style>\n        body {\n            margin: 0;\n            padding: 10px;\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n        }\n        \n        .container {\n            background: white;\n            border-radius: 16px;\n            padding: 15px;\n            box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n            max-width: 1200px;\n            margin: 0 auto;\n        }\n        \n        #map {\n            width: 100%;\n            height: 500px;\n            background: #f7fafc;\n            border-radius: 8px;\n            position: relative;\n        }\n        \n        .inset-box {\n            position: absolute;\n            bottom: 10px;\n            left: 10px;\n            width: 120px;\n            height: 100px;\n            background: #ffffff;\n            border: 2px solid #2d3748;\n            border-radius: 8px;\n            overflow: hidden;\n            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);\n        }\n        \n        .inset-title {\n            position: absolute;\n            top: 3px;\n            left: 50%;\n            transform: translateX(-50%);\n            font-size: 9px;\n            font-weight: bold;\n            color: #2d3748;\n            z-index: 10;\n            background: rgba(255, 255, 255, 0.9);\n            padding: 2px 6px;\n            border-radius: 4px;\n        }\n        \n        @media (min-width: 768px) {\n            body { padding: 20px; }\n            .container { padding: 30px; }\n            #map { height: 600px; }\n            .inset-box { bottom: 20px; left: 20px; width: 180px; height: 140px; }\n            .inset-title { font-size: 11px; top: 5px; padding: 2px 8px; }\n        }\n        \n        .country {\n            stroke: #000000;\n            stroke-width: 1;\n            cursor: pointer;\n            transition: all 0.3s;\n        }\n        \n        .country-other { fill: #ffffff; }\n        .country-ecrn { fill: #2d3748; }\n        \n        .country:hover { stroke-width: 2.5; opacity: 0.7; }\n        \n        .legend {\n            margin-top: 15px;\n            padding: 10px;\n            background: #f7fafc;\n            border-radius: 8px;\n            display: flex;\n            gap: 15px;\n            justify-content: center;\n            flex-wrap: wrap;\n            font-size: 13px;\n        }\n        \n        @media (min-width: 768px) {\n            .legend { margin-top: 20px; padding: 15px; gap: 20px; font-size: 14px; }\n        }\n        \n        .legend-item { display: flex; align-items: center; gap: 8px; }\n        \n        .legend-color { width: 20px; height: 20px; border-radius: 4px; border: 1px solid #cbd5e0; }\n        \n        .tooltip {\n            position: fixed;\n            background: #ffffff;\n            color: #2d3748;\n            padding: 12px 15px;\n            border-radius: 8px;\n            font-size: 13px;\n            pointer-events: none;\n            opacity: 0;\n            transition: opacity 0.3s;\n            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n            border: 2px solid #2d3748;\n            min-width: 200px;\n            max-width: 90vw;\n            z-index: 1000;\n        }\n        \n        @media (min-width: 768px) {\n            .tooltip { padding: 15px 20px; font-size: 14px; min-width: 250px; max-width: none; }\n        }\n        \n        .tooltip-country { font-weight: bold; font-size: 16px; margin-bottom: 8px; color: #2d3748; }\n        .tooltip-institution { font-size: 14px; color: #4a5568; line-height: 1.4; }\n        \n        .city-marker {\n            fill: white;\n            stroke: #2d3748;\n            stroke-width: 2;\n            cursor: pointer;\n        }\n        \n        .city-marker:hover { fill: #f7fafc; stroke-width: 3; }\n        \n        @media (max-width: 767px) {\n            .city-marker { r: 8 !important; stroke-width: 2.5; }\n        }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"container\">\n        <div id=\"map\">\n            <div class=\"inset-box\" id=\"inset-map\">\n                <div class=\"inset-title\">Canary Islands<\/div>\n            <\/div>\n        <\/div>\n        \n        <div class=\"legend\">\n            <div class=\"legend-item\">\n                <div class=\"legend-color\" style=\"background: #2d3748;\"><\/div>\n                <span>ECRN Members<\/span>\n            <\/div>\n            <div class=\"legend-item\">\n                <div class=\"legend-color\" style=\"background: #ffffff; border: 2px solid #000;\"><\/div>\n                <span>Other Country<\/span>\n            <\/div>\n        <\/div>\n    <\/div>\n    \n    <div class=\"tooltip\" id=\"tooltip\"><\/div>\n    \n    <script>\n        const ecrnCountries = {\n            'United Kingdom': 'Northumbria University\\nNewcastle upon Tyne, UK',\n            'Czechia': 'Czech Technical University in Prague\\nPrague, Czech Republic',\n            'Czech Republic': 'Czech Technical University in Prague\\nPrague, Czech Republic',\n            'Portugal': 'Telecommunications Institute\\nAveiro, Portugal',\n            'Spain': 'Universidad de Valencia\\nValencia, Spain\\n\\nUniversidad de Las Palmas de Gran Canaria\\nIslas Canarias, Spain',\n            'Italy': 'Universita Roma Tre\\nRome, Italy',\n            'France': 'Centrale Marseille\\nMarseille, France',\n            'Germany': 'Fraunhofer HHI\\nBerlin, Germany',\n            'Greece': 'Harokopio University\\nAthens, Greece',\n            'Ireland': 'Eblana Photonics\\nDublin, Ireland'\n        };\n        \n        const cityLocations = [\n            { name: 'Newcastle upon Tyne', coords: [-1.6178, 54.9783], institution: 'Northumbria University' },\n            { name: 'Aveiro', coords: [-8.6537, 40.6443], institution: 'Telecommunications Institute' },\n            { name: 'Rome', coords: [12.4964, 41.9028], institution: 'Universita Roma Tre' },\n            { name: 'Valencia', coords: [-0.3763, 39.4699], institution: 'Universidad de Valencia' },\n            { name: 'Prague', coords: [14.4378, 50.0755], institution: 'Czech Technical University in Prague' },\n            { name: 'Marseille', coords: [5.3698, 43.2965], institution: 'Centrale Marseille' },\n            { name: 'Berlin', coords: [13.4050, 52.5200], institution: 'Fraunhofer HHI' },\n            { name: 'Athens', coords: [23.7275, 37.9838], institution: 'Harokopio University' },\n            { name: 'Dublin', coords: [-6.2603, 53.3498], institution: 'Eblana Photonics' }\n        ];\n        \n        const canaryLocation = { name: 'Las Palmas', coords: [-15.4363, 28.1248], institution: 'Universidad de Las Palmas de Gran Canaria' };\n        \n        const mapContainer = document.getElementById('map');\n        const width = 1140;\n        const height = 600;\n        \n        const svg = d3.select(\"#map\")\n            .append(\"svg\")\n            .attr(\"width\", width)\n            .attr(\"height\", height);\n        \n        const projection = d3.geoMercator()\n            .center([8, 51])\n            .scale(850)\n            .translate([width \/ 2, height \/ 2]);\n        \n        const path = d3.geoPath().projection(projection);\n        const tooltip = d3.select(\"#tooltip\");\n        \n        d3.json(\"https:\/\/cdn.jsdelivr.net\/npm\/world-atlas@2\/countries-50m.json\")\n            .then(data => {\n                const countries = topojson.feature(data, data.objects.countries);\n                \n                svg.selectAll(\"path\")\n                    .data(countries.features)\n                    .enter()\n                    .append(\"path\")\n                    .attr(\"class\", d => {\n                        const countryName = d.properties.name;\n                        return ecrnCountries[countryName] ? \"country country-ecrn\" : \"country country-other\";\n                    })\n                    .attr(\"d\", path)\n                    .on(\"mouseover\", function(event, d) {\n                        const countryName = d.properties.name;\n                        const institution = ecrnCountries[countryName];\n                        if (institution) {\n                            const formattedInstitution = institution.replace(\/\\n\/g, '<br>');\n                            tooltip\n                                .style(\"opacity\", 1)\n                                .html(`\n                                    <div class=\"tooltip-country\">${countryName}<\/div>\n                                    <div class=\"tooltip-institution\">${formattedInstitution}<\/div>\n                                `)\n                                .style(\"left\", (event.clientX + 15) + \"px\")\n                                .style(\"top\", (event.clientY + 15) + \"px\");\n                        }\n                    })\n                    .on(\"mousemove\", function(event, d) {\n                        const countryName = d.properties.name;\n                        const institution = ecrnCountries[countryName];\n                        if (institution) {\n                            tooltip\n                                .style(\"left\", (event.clientX + 15) + \"px\")\n                                .style(\"top\", (event.clientY + 15) + \"px\");\n                        }\n                    })\n                    .on(\"mouseout\", function() {\n                        tooltip.style(\"opacity\", 0);\n                    });\n                \n                svg.selectAll(\".city-marker\")\n                    .data(cityLocations)\n                    .enter()\n                    .append(\"circle\")\n                    .attr(\"class\", \"city-marker\")\n                    .attr(\"cx\", d => projection(d.coords)[0])\n                    .attr(\"cy\", d => projection(d.coords)[1])\n                    .attr(\"r\", window.innerWidth < 768 ? 8 : 6)\n                    .on(\"mouseover\", function(event, d) {\n                        tooltip\n                            .style(\"opacity\", 1)\n                            .html(`\n                                <div class=\"tooltip-country\">${d.name}<\/div>\n                                <div class=\"tooltip-institution\">${d.institution}<\/div>\n                            `)\n                            .style(\"left\", (event.clientX + 10) + \"px\")\n                            .style(\"top\", (event.clientY + 10) + \"px\");\n                    })\n                    .on(\"mousemove\", function(event) {\n                        tooltip\n                            .style(\"left\", (event.clientX + 10) + \"px\")\n                            .style(\"top\", (event.clientY + 10) + \"px\");\n                    })\n                    .on(\"mouseout\", function() {\n                        tooltip.style(\"opacity\", 0);\n                    })\n                    .on(\"touchstart\", function(event, d) {\n                        event.preventDefault();\n                        tooltip\n                            .style(\"opacity\", 1)\n                            .html(`\n                                <div class=\"tooltip-country\">${d.name}<\/div>\n                                <div class=\"tooltip-institution\">${d.institution}<\/div>\n                            `)\n                            .style(\"left\", (event.touches[0].clientX + 10) + \"px\")\n                            .style(\"top\", (event.touches[0].clientY + 10) + \"px\");\n                        setTimeout(() => tooltip.style(\"opacity\", 0), 3000);\n                    });\n                \n                const insetWidth = window.innerWidth < 768 ? 120 : 180;\n                const insetHeight = window.innerWidth < 768 ? 100 : 140;\n                const insetSvg = d3.select(\"#inset-map\")\n                    .append(\"svg\")\n                    .attr(\"width\", insetWidth)\n                    .attr(\"height\", insetHeight);\n                \n                const insetProjection = d3.geoMercator()\n                    .center([-15.5, 28.5])\n                    .scale(window.innerWidth < 768 ? 1700 : 2500)\n                    .translate([insetWidth \/ 2, insetHeight \/ 2]);\n                \n                const insetPath = d3.geoPath().projection(insetProjection);\n                \n                insetSvg.selectAll(\"path\")\n                    .data(countries.features)\n                    .enter()\n                    .append(\"path\")\n                    .attr(\"class\", d => {\n                        const countryName = d.properties.name;\n                        return countryName === 'Spain' ? \"country country-ecrn\" : \"country country-other\";\n                    })\n                    .attr(\"d\", insetPath);\n                \n                insetSvg.append(\"circle\")\n                    .attr(\"class\", \"city-marker\")\n                    .attr(\"cx\", insetProjection(canaryLocation.coords)[0])\n                    .attr(\"cy\", insetProjection(canaryLocation.coords)[1])\n                    .attr(\"r\", window.innerWidth < 768 ? 4 : 5)\n                    .on(\"mouseover\", function(event) {\n                        tooltip\n                            .style(\"opacity\", 1)\n                            .html(`\n                                <div class=\"tooltip-country\">${canaryLocation.name}<\/div>\n                                <div class=\"tooltip-institution\">${canaryLocation.institution}<\/div>\n                            `)\n                            .style(\"left\", (event.clientX + 10) + \"px\")\n                            .style(\"top\", (event.clientY + 10) + \"px\");\n                    })\n                    .on(\"mousemove\", function(event) {\n                        tooltip\n                            .style(\"left\", (event.clientX + 10) + \"px\")\n                            .style(\"top\", (event.clientY + 10) + \"px\");\n                    })\n                    .on(\"mouseout\", function() {\n                        tooltip.style(\"opacity\", 0);\n                    })\n                    .on(\"touchstart\", function(event) {\n                        event.preventDefault();\n                        tooltip\n                            .style(\"opacity\", 1)\n                            .html(`\n                                <div class=\"tooltip-country\">${canaryLocation.name}<\/div>\n                                <div class=\"tooltip-institution\">${canaryLocation.institution}<\/div>\n                            `)\n                            .style(\"left\", (event.touches[0].clientX + 10) + \"px\")\n                            .style(\"top\", (event.touches[0].clientY + 10) + \"px\");\n                        setTimeout(() => tooltip.style(\"opacity\", 0), 3000);\n                    });\n            })\n            .catch(error => {\n                console.error(\"Error loading map data:\", error);\n                document.getElementById(\"map\").innerHTML = \n                    '<div style=\"display: flex; align-items: center; justify-content: center; height: 100%; color: #e53e3e; font-size: 18px;\">Error loading map data. Please refresh the page.<\/div>';\n            });\n    <\/script>\n<\/body>\n<\/html>\n\n\n\n\n\n<div class=\"wp-block-group alignfull is-style-default has-global-padding is-layout-constrained wp-block-group-is-layout-constrained\" style=\"margin-top:0;margin-bottom:0;padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60)\">\n<div class=\"wp-block-columns alignwide is-layout-flex wp-container-core-columns-is-layout-6ef9061c wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60%\">\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-913d5755 wp-block-group-is-layout-flex\" style=\"padding-bottom:var(--wp--preset--spacing--30)\">\n<h2 class=\"wp-block-heading\">Universities<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1322\" height=\"697\" src=\"https:\/\/v1.ecrn-owc.eu\/wp-content\/uploads\/2026\/01\/logos.png\" alt=\"\" class=\"wp-image-145\"\/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:40%\">\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-container-core-column-is-layout-5dafc681 wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group has-global-padding is-content-justification-left is-layout-constrained wp-container-core-group-is-layout-3540e7cd wp-block-group-is-layout-constrained\">\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"font-style:normal;font-weight:500\">Northumbria University<\/h3>\n\n\n\n<p class=\"has-medium-font-size\"><a href=\"#\">Newcastle upon Tyne, UK<\/a><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-global-padding is-content-justification-left is-layout-constrained wp-container-core-group-is-layout-0b710646 wp-block-group-is-layout-constrained\">\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"font-style:normal;font-weight:500\">Telecommunications Institute<\/h3>\n\n\n\n<p class=\"has-medium-font-size\"><a href=\"#\">Aveiro, Protugal<\/a><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-global-padding is-content-justification-left is-layout-constrained wp-container-core-group-is-layout-0b710646 wp-block-group-is-layout-constrained\">\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"font-style:normal;font-weight:500\">Universita Roma Tre<\/h3>\n\n\n\n<p class=\"has-medium-font-size\"><a href=\"#\">Rome, Italy<\/a><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-global-padding is-content-justification-left is-layout-constrained wp-container-core-group-is-layout-0b710646 wp-block-group-is-layout-constrained\">\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"font-style:normal;font-weight:500\">Universidad del Las Palmas de Gran Canaria<\/h3>\n\n\n\n<p class=\"has-medium-font-size\"><a href=\"#\">Islas Canarias, Spain<\/a><\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-container-core-column-is-layout-5dafc681 wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group has-global-padding is-content-justification-left is-layout-constrained wp-container-core-group-is-layout-3540e7cd wp-block-group-is-layout-constrained\">\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"font-style:normal;font-weight:500\">Czech Technical University in Prague <\/h3>\n\n\n\n<p class=\"has-medium-font-size\">Prague, <a href=\"#\">Czech Republic<\/a><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-global-padding is-content-justification-left is-layout-constrained wp-container-core-group-is-layout-0b710646 wp-block-group-is-layout-constrained\">\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"font-style:normal;font-weight:500\">Universidad de Valencia<\/h3>\n\n\n\n<p class=\"has-medium-font-size\"><a href=\"#\">Valencia, Spain<\/a><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-global-padding is-content-justification-left is-layout-constrained wp-container-core-group-is-layout-0b710646 wp-block-group-is-layout-constrained\">\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"font-style:normal;font-weight:500\">Centrale Marseille<\/h3>\n\n\n\n<p class=\"has-medium-font-size\"><a href=\"#\">Marseille, France<\/a><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-global-padding is-content-justification-left is-layout-constrained wp-container-core-group-is-layout-0b710646 wp-block-group-is-layout-constrained\">\n<h3 class=\"wp-block-heading has-large-font-size\" style=\"font-style:normal;font-weight:500\"><\/h3>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns alignfull is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<!-- ECRN Ray Tracer \u2014 iframe srcdoc version (fully isolated from WordPress theme\/scripts) -->\n<!-- Paste this entire block into a WordPress Custom HTML block -->\n<iframe\n  style=\"width:100%; max-width:1200px; height:640px; border:0; display:block; margin:24px auto; border-radius:8px; box-shadow:0 20px 60px rgba(0,0,0,0.25);\"\n  srcdoc='\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<style>\n  :root {\n    --bg-deep: #05060a;\n    --bg-mid: #0a0d18;\n    --ink: #e8e6dc;\n    --ink-dim: #8a8478;\n    --accent: #f4b942;\n    --line: rgba(232, 230, 220, 0.08);\n  }\n  * { box-sizing: border-box; margin: 0; padding: 0; }\n  html, body {\n    width: 100%; height: 100%;\n    background: var(--bg-deep);\n    color: var(--ink);\n    font-family: \"Iowan Old Style\", \"Palatino\", Georgia, serif;\n    overflow: hidden;\n  }\n  .frame {\n    position: fixed; inset: 0;\n    display: grid;\n    grid-template-rows: auto 1fr auto;\n    background:\n      radial-gradient(ellipse at 20% 30%, rgba(244, 185, 66, 0.06), transparent 50%),\n      radial-gradient(ellipse at 80% 70%, rgba(80, 140, 220, 0.05), transparent 50%),\n      var(--bg-deep);\n  }\n  header {\n    padding: 16px 24px 12px;\n    border-bottom: 1px solid var(--line);\n    display: flex;\n    align-items: baseline;\n    justify-content: space-between;\n    gap: 16px;\n    flex-wrap: wrap;\n  }\n  .title {\n    font-family: \"Didot\", \"Bodoni 72\", \"Playfair Display\", serif;\n    font-size: 24px;\n    font-weight: 400;\n    letter-spacing: 0.02em;\n  }\n  .title em { font-style: italic; color: var(--accent); }\n  .subtitle {\n    font-size: 10px;\n    text-transform: uppercase;\n    letter-spacing: 0.3em;\n    color: var(--ink-dim);\n    margin-top: 4px;\n  }\n  .canvas-wrap { position: relative; overflow: hidden; min-height: 200px; }\n  canvas { width: 100%; height: 100%; display: block; cursor: crosshair; touch-action: none; }\n  .legend {\n    position: absolute; top: 14px; left: 14px;\n    background: rgba(10, 13, 24, 0.75);\n    backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);\n    border: 1px solid var(--line);\n    padding: 10px 12px;\n    font-size: 11px;\n    color: var(--ink-dim);\n    letter-spacing: 0.05em;\n    line-height: 1.7;\n    pointer-events: none;\n    border-radius: 2px;\n  }\n  .legend strong {\n    color: var(--ink);\n    text-transform: uppercase;\n    letter-spacing: 0.3em;\n    font-size: 9px;\n    display: block;\n    margin-bottom: 6px;\n  }\n  .swatch { display: inline-block; width: 16px; height: 2px; margin-right: 6px; vertical-align: middle; }\n  .controls {\n    padding: 14px 24px;\n    border-top: 1px solid var(--line);\n    display: flex;\n    align-items: center;\n    gap: 20px;\n    flex-wrap: wrap;\n    background: rgba(5, 6, 10, 0.6);\n  }\n  .control {\n    display: flex; align-items: center; gap: 8px;\n    font-size: 10px;\n    text-transform: uppercase;\n    letter-spacing: 0.18em;\n    color: var(--ink-dim);\n  }\n  .control input[type=\"range\"] {\n    -webkit-appearance: none; appearance: none;\n    width: 90px; height: 2px;\n    background: var(--line);\n    outline: none; border-radius: 1px;\n  }\n  .control input[type=\"range\"]::-webkit-slider-thumb {\n    -webkit-appearance: none; appearance: none;\n    width: 12px; height: 12px;\n    background: var(--accent);\n    border-radius: 50%; cursor: pointer; border: none;\n  }\n  .control input[type=\"range\"]::-moz-range-thumb {\n    width: 12px; height: 12px;\n    background: var(--accent);\n    border: none; border-radius: 50%; cursor: pointer;\n  }\n  .control .val {\n    color: var(--ink); min-width: 32px;\n    font-family: \"Courier New\", monospace;\n    font-size: 11px;\n  }\n  button {\n    background: transparent;\n    border: 1px solid var(--line);\n    color: var(--ink);\n    padding: 7px 14px;\n    font-family: inherit;\n    font-size: 10px;\n    letter-spacing: 0.25em;\n    text-transform: uppercase;\n    cursor: pointer;\n    transition: all 0.2s;\n    border-radius: 2px;\n  }\n  button:hover { border-color: var(--accent); color: var(--accent); }\n  button.active { background: var(--accent); color: var(--bg-deep); border-color: var(--accent); }\n  .hint {\n    margin-left: auto;\n    color: var(--ink-dim);\n    font-size: 10px;\n    letter-spacing: 0.18em;\n    text-transform: uppercase;\n    font-style: italic;\n  }\n  @media (max-width: 600px) {\n    .title { font-size: 20px; }\n    .controls { gap: 12px; padding: 12px 16px; }\n    .control input[type=\"range\"] { width: 70px; }\n    .hint { display: none; }\n    header { padding: 14px 16px 10px; }\n  }\n<\/style>\n<\/head>\n<body>\n<div class=\"frame\">\n  <header>\n    <div>\n      <div class=\"title\">Ray Tracer \u00b7 <em>ECRN<\/em><\/div>\n      <div class=\"subtitle\">Optical simulation \u2014 lenses, mirrors, refractive glass<\/div>\n    <\/div>\n  <\/header>\n  <div class=\"canvas-wrap\">\n    <canvas id=\"stage\"><\/canvas>\n    <div class=\"legend\">\n      <strong>Elements<\/strong>\n      <span class=\"swatch\" style=\"background:#f4b942\"><\/span>Light source<br>\n      <span class=\"swatch\" style=\"background:rgba(120,180,255,0.6)\"><\/span>Glass \/ Lens<br>\n      <span class=\"swatch\" style=\"background:#c0c0c0\"><\/span>Mirror\n    <\/div>\n  <\/div>\n  <div class=\"controls\">\n    <div class=\"control\">\n      <span>Rays<\/span>\n      <input type=\"range\" id=\"rayCount\" min=\"1\" max=\"60\" value=\"18\">\n      <span class=\"val\" id=\"rayCountVal\">18<\/span>\n    <\/div>\n    <div class=\"control\">\n      <span>Spread<\/span>\n      <input type=\"range\" id=\"spread\" min=\"0\" max=\"180\" value=\"40\">\n      <span class=\"val\" id=\"spreadVal\">40\u00b0<\/span>\n    <\/div>\n    <div class=\"control\">\n      <span>IOR<\/span>\n      <input type=\"range\" id=\"ior\" min=\"100\" max=\"200\" value=\"150\">\n      <span class=\"val\" id=\"iorVal\">1.50<\/span>\n    <\/div>\n    <button id=\"toggleAnimate\" class=\"active\">Animate<\/button>\n    <button id=\"reset\">Reset<\/button>\n    <span class=\"hint\">drag the source \u00b7 scroll to rotate<\/span>\n  <\/div>\n<\/div>\n<script>\n(function(){\n  var canvas = document.getElementById(\"stage\");\n  var ctx = canvas.getContext(\"2d\", { alpha: false });\n  var canvasWrap = canvas.parentElement;\n  var W = 0, H = 0, DPR = window.devicePixelRatio || 1;\n\n  function resize() {\n    var rect = canvasWrap.getBoundingClientRect();\n    W = rect.width; H = rect.height;\n    canvas.width = Math.max(1, Math.floor(W * DPR));\n    canvas.height = Math.max(1, Math.floor(H * DPR));\n    ctx.setTransform(DPR, 0, 0, DPR, 0, 0);\n  }\n\n  var V = {\n    sub: function(a,b){ return {x:a.x-b.x, y:a.y-b.y}; },\n    add: function(a,b){ return {x:a.x+b.x, y:a.y+b.y}; },\n    mul: function(a,s){ return {x:a.x*s, y:a.y*s}; },\n    dot: function(a,b){ return a.x*b.x + a.y*b.y; },\n    norm: function(a){ var L = Math.hypot(a.x,a.y) || 1; return {x:a.x\/L, y:a.y\/L}; }\n  };\n\n  var elements = [];\n  var source = { x: 100, y: 0, angle: 0 };\n\n  function addMirror(a, b) { elements.push({ type:\"mirror\", a:a, b:b }); }\n  function addLens(c, r, ior) { elements.push({ type:\"lens\", c:c, r:r, ior:ior }); }\n  function addGlass(points, ior) { elements.push({ type:\"glass\", points:points, ior:ior }); }\n\n  function buildECRN() {\n    elements = [];\n    var marginLeft = W * 0.18;\n    var marginRight = W * 0.06;\n    var marginVertical = H * 0.12;\n    var availableW = W - marginLeft - marginRight;\n    var availableH = H - marginVertical * 2;\n\n    var letterW_byWidth = availableW \/ 5.35;\n    var letterW_byHeight = 0.7 * availableH;\n    var letterW = Math.max(20, Math.min(letterW_byWidth, letterW_byHeight));\n    var letterH = letterW \/ 0.7;\n    var gap = letterW * 0.45;\n\n    var totalW = letterW * 4 + gap * 3;\n    var startX = marginLeft + (availableW - totalW) \/ 2 + letterW \/ 2;\n    var cy = H \/ 2;\n\n    var positions = [0,1,2,3].map(function(i) {\n      return { x: startX + i * (letterW + gap), y: cy };\n    });\n\n    buildE(positions[0], letterW, letterH);\n    buildC(positions[1], letterW, letterH);\n    buildR(positions[2], letterW, letterH);\n    buildN(positions[3], letterW, letterH);\n  }\n\n  function buildE(p, w, h) {\n    var x = p.x - w\/2, y = p.y - h\/2;\n    addMirror({x:x, y:y}, {x:x, y:y+h});\n    addMirror({x:x, y:y}, {x:x+w*0.85, y:y});\n    addMirror({x:x, y:y+h*0.5}, {x:x+w*0.6, y:y+h*0.5});\n    addMirror({x:x, y:y+h}, {x:x+w*0.85, y:y+h});\n  }\n\n  function buildC(p, w, h) {\n    var cx = p.x, cy = p.y;\n    var rx = w*0.45, ry = h*0.5;\n    var segs = 18;\n    var a0 = Math.PI * 0.78, a1 = -Math.PI * 0.78;\n    var angles = [];\n    for (var i = 0; i <= segs; i++) {\n      var t = i \/ segs;\n      angles.push(a0 + t * ((2*Math.PI - a0) + a1));\n    }\n    for (var j = 0; j < angles.length - 1; j++) {\n      addMirror(\n        { x: cx + Math.cos(angles[j])*rx, y: cy - Math.sin(angles[j])*ry },\n        { x: cx + Math.cos(angles[j+1])*rx, y: cy - Math.sin(angles[j+1])*ry }\n      );\n    }\n  }\n\n  function buildR(p, w, h) {\n    var x = p.x - w\/2, y = p.y - h\/2;\n    addMirror({x:x, y:y}, {x:x, y:y+h});\n    var loopR = h * 0.22;\n    addLens({ x: x + w*0.42, y: y + loopR + 4 }, loopR, 1.5);\n    addMirror({x:x, y:y}, {x:x + w*0.42, y:y});\n    addMirror({x:x, y:y+loopR*2+8}, {x:x + w*0.42, y:y+loopR*2+8});\n    addMirror({x:x + w*0.18, y:y+loopR*2+8}, {x:x + w*0.85, y:y+h});\n  }\n\n  function buildN(p, w, h) {\n    var x = p.x - w\/2, y = p.y - h\/2;\n    addMirror({x:x, y:y}, {x:x, y:y+h});\n    addMirror({x:x+w*0.85, y:y}, {x:x+w*0.85, y:y+h});\n    var a = {x:x+4, y:y+4};\n    var b = {x:x+18, y:y+4};\n    var c = {x:x+w*0.85-4, y:y+h-4};\n    var d = {x:x+w*0.85-18, y:y+h-4};\n    addGlass([a, b, c, d], 1.5);\n  }\n\n  function intersectSegment(o, d, a, b) {\n    var rx = b.x - a.x, ry = b.y - a.y;\n    var denom = d.x * ry - d.y * rx;\n    if (Math.abs(denom) < 1e-9) return null;\n    var t = ((a.x - o.x) * ry - (a.y - o.y) * rx) \/ denom;\n    var u = ((a.x - o.x) * d.y - (a.y - o.y) * d.x) \/ denom;\n    if (t > 1e-4 && u >= 0 && u <= 1) {\n      var point = { x: o.x + d.x*t, y: o.y + d.y*t };\n      var n = V.norm({ x: -ry, y: rx });\n      if (V.dot(n, d) > 0) n = V.mul(n, -1);\n      return { t: t, point: point, normal: n };\n    }\n    return null;\n  }\n\n  function intersectCircle(o, d, c, r, fromInside) {\n    var oc = V.sub(o, c);\n    var b = V.dot(oc, d);\n    var cc = V.dot(oc, oc) - r*r;\n    var disc = b*b - cc;\n    if (disc < 0) return null;\n    var s = Math.sqrt(disc);\n    var t1 = -b - s, t2 = -b + s;\n    var t = -1;\n    if (fromInside) t = t2 > 1e-4 ? t2 : -1;\n    else t = t1 > 1e-4 ? t1 : (t2 > 1e-4 ? t2 : -1);\n    if (t < 0) return null;\n    var point = { x: o.x + d.x*t, y: o.y + d.y*t };\n    var n = V.norm(V.sub(point, c));\n    if (fromInside) n = V.mul(n, -1);\n    return { t: t, point: point, normal: n };\n  }\n\n  function intersectPolygon(o, d, points, fromInside) {\n    var best = null;\n    for (var i = 0; i < points.length; i++) {\n      var hit = intersectSegment(o, d, points[i], points[(i+1) % points.length]);\n      if (hit &#038;&#038; (!best || hit.t < best.t)) best = hit;\n    }\n    if (best &#038;&#038; fromInside) best.normal = V.mul(best.normal, -1);\n    return best;\n  }\n\n  function traceRay(origin, direction) {\n    var segments = [];\n    var o = { x: origin.x, y: origin.y };\n    var d = V.norm(direction);\n    var inside = null;\n    for (var bounce = 0; bounce < 20; bounce++) {\n      var nearest = null, nearestEl = null, nearestExit = false;\n      for (var i = 0; i < elements.length; i++) {\n        var el = elements[i];\n        var hit = null;\n        var isInside = inside === el;\n        if (el.type === \"mirror\") hit = intersectSegment(o, d, el.a, el.b);\n        else if (el.type === \"lens\") hit = intersectCircle(o, d, el.c, el.r, isInside);\n        else if (el.type === \"glass\") hit = intersectPolygon(o, d, el.points, isInside);\n        if (hit &#038;&#038; (!nearest || hit.t < nearest.t)) {\n          nearest = hit; nearestEl = el; nearestExit = isInside;\n        }\n      }\n      if (!nearest) {\n        var farT = 4000;\n        segments.push({ a: o, b: { x: o.x + d.x*farT, y: o.y + d.y*farT } });\n        break;\n      }\n      segments.push({ a: o, b: nearest.point });\n      if (nearestEl.type === \"mirror\") {\n        var nDotD = V.dot(nearest.normal, d);\n        d = V.norm(V.sub(d, V.mul(nearest.normal, 2 * nDotD)));\n        o = V.add(nearest.point, V.mul(d, 0.01));\n      } else {\n        var ior = nearestEl.ior || 1.5;\n        var n1 = nearestExit ? ior : 1.0;\n        var n2 = nearestExit ? 1.0 : ior;\n        var eta = n1 \/ n2;\n        var n = nearest.normal;\n        var cosI = -V.dot(n, d);\n        var sinT2 = eta*eta * (1 - cosI*cosI);\n        if (sinT2 > 1) {\n          d = V.norm(V.add(d, V.mul(n, 2*cosI)));\n          o = V.add(nearest.point, V.mul(d, 0.01));\n        } else {\n          var cosT = Math.sqrt(1 - sinT2);\n          d = V.norm(V.add(V.mul(d, eta), V.mul(n, eta*cosI - cosT)));\n          o = V.add(nearest.point, V.mul(d, 0.01));\n          inside = nearestExit ? null : nearestEl;\n        }\n      }\n    }\n    return segments;\n  }\n\n  var currentIOR = 1.5;\n  var rayCount = 18;\n  var spreadDeg = 40;\n  var animate = true;\n  var t0 = performance.now();\n  var dragging = false;\n\n  function drawElements() {\n    for (var i = 0; i < elements.length; i++) {\n      var el = elements[i];\n      if (el.type === \"mirror\") {\n        var dx = el.b.x - el.a.x, dy = el.b.y - el.a.y;\n        var L = Math.hypot(dx, dy) || 1;\n        var nx = -dy \/ L, ny = dx \/ L;\n        ctx.strokeStyle = \"rgba(192, 192, 192, 0.35)\";\n        ctx.lineWidth = 1;\n        var steps = Math.max(3, Math.floor(L \/ 8));\n        ctx.beginPath();\n        for (var k = 0; k < steps; k++) {\n          var t = k \/ steps;\n          var px = el.a.x + dx * t, py = el.a.y + dy * t;\n          ctx.moveTo(px, py);\n          ctx.lineTo(px + nx * 5, py + ny * 5);\n        }\n        ctx.stroke();\n        ctx.strokeStyle = \"#d8d8d8\";\n        ctx.lineWidth = 2;\n        ctx.shadowColor = \"rgba(255,255,255,0.4)\";\n        ctx.shadowBlur = 4;\n        ctx.beginPath();\n        ctx.moveTo(el.a.x, el.a.y);\n        ctx.lineTo(el.b.x, el.b.y);\n        ctx.stroke();\n        ctx.shadowBlur = 0;\n      } else if (el.type === \"lens\") {\n        var grad = ctx.createRadialGradient(el.c.x - el.r*0.3, el.c.y - el.r*0.3, 0, el.c.x, el.c.y, el.r);\n        grad.addColorStop(0, \"rgba(180, 220, 255, 0.18)\");\n        grad.addColorStop(0.7, \"rgba(120, 180, 255, 0.10)\");\n        grad.addColorStop(1, \"rgba(80, 140, 220, 0.05)\");\n        ctx.fillStyle = grad;\n        ctx.beginPath();\n        ctx.arc(el.c.x, el.c.y, el.r, 0, Math.PI * 2);\n        ctx.fill();\n        ctx.strokeStyle = \"rgba(160, 200, 255, 0.5)\";\n        ctx.lineWidth = 1.2;\n        ctx.stroke();\n        ctx.fillStyle = \"rgba(255,255,255,0.15)\";\n        ctx.beginPath();\n        ctx.arc(el.c.x - el.r*0.4, el.c.y - el.r*0.4, el.r*0.18, 0, Math.PI*2);\n        ctx.fill();\n      } else if (el.type === \"glass\") {\n        ctx.fillStyle = \"rgba(120, 180, 255, 0.13)\";\n        ctx.strokeStyle = \"rgba(160, 200, 255, 0.5)\";\n        ctx.lineWidth = 1.2;\n        ctx.beginPath();\n        ctx.moveTo(el.points[0].x, el.points[0].y);\n        for (var p = 1; p < el.points.length; p++) ctx.lineTo(el.points[p].x, el.points[p].y);\n        ctx.closePath();\n        ctx.fill();\n        ctx.stroke();\n      }\n    }\n  }\n\n  function drawSource() {\n    var g = ctx.createRadialGradient(source.x, source.y, 0, source.x, source.y, 30);\n    g.addColorStop(0, \"rgba(244, 185, 66, 0.9)\");\n    g.addColorStop(0.4, \"rgba(244, 185, 66, 0.3)\");\n    g.addColorStop(1, \"rgba(244, 185, 66, 0)\");\n    ctx.fillStyle = g;\n    ctx.beginPath();\n    ctx.arc(source.x, source.y, 30, 0, Math.PI*2);\n    ctx.fill();\n    ctx.fillStyle = \"#fff5d6\";\n    ctx.beginPath();\n    ctx.arc(source.x, source.y, 5, 0, Math.PI*2);\n    ctx.fill();\n  }\n\n  function drawRays() {\n    for (var i = 0; i < elements.length; i++) {\n      if (elements[i].ior !== undefined) elements[i].ior = currentIOR;\n    }\n    var spread = spreadDeg * Math.PI \/ 180;\n    var baseAngle = source.angle;\n    ctx.lineWidth = 1;\n    ctx.lineCap = \"round\";\n    for (var r = 0; r < rayCount; r++) {\n      var t = rayCount === 1 ? 0.5 : r \/ (rayCount - 1);\n      var angle = baseAngle - spread\/2 + t * spread;\n      var dir = { x: Math.cos(angle), y: Math.sin(angle) };\n      var segs = traceRay(source, dir);\n      var hue = 38 + t * 20;\n      ctx.strokeStyle = \"hsla(\" + hue + \", 90%, 65%, 0.55)\";\n      ctx.shadowColor = \"hsla(\" + hue + \", 90%, 70%, 0.6)\";\n      ctx.shadowBlur = 6;\n      ctx.beginPath();\n      for (var s = 0; s < segs.length; s++) {\n        ctx.moveTo(segs[s].a.x, segs[s].a.y);\n        ctx.lineTo(segs[s].b.x, segs[s].b.y);\n      }\n      ctx.stroke();\n    }\n    ctx.shadowBlur = 0;\n  }\n\n  function frame(now) {\n    if (animate) {\n      var t = (now - t0) * 0.0004;\n      if (!dragging) {\n        \/\/ Figure-8 (lemniscate) trajectory spanning the full width across the ECRN array\n        var centerX = W * 0.50;\n        var centerY = H * 0.50;\n        var radiusX = W * 0.42;\n        var radiusY = H * 0.32;\n        source.x = centerX + Math.sin(t) * radiusX;\n        source.y = centerY + Math.sin(t * 2) * radiusY * 0.5;\n\n        \/\/ Aim the beam toward the center of the ECRN block, with a slight oscillation\n        var aimX = W * 0.50;\n        var aimY = H * 0.50;\n        var dx = aimX - source.x;\n        var dy = aimY - source.y;\n        \/\/ When source is near the center, point it outward instead\n        var distFromCenter = Math.hypot(dx, dy);\n        if (distFromCenter < 50) {\n          source.angle += 0.02;\n        } else {\n          source.angle = Math.atan2(dy, dx) + Math.sin(t * 1.5) * 0.2;\n        }\n      }\n    }\n    var bg = ctx.createLinearGradient(0, 0, W, H);\n    bg.addColorStop(0, \"#06080f\");\n    bg.addColorStop(1, \"#0a0d18\");\n    ctx.fillStyle = bg;\n    ctx.fillRect(0, 0, W, H);\n    ctx.strokeStyle = \"rgba(232, 230, 220, 0.025)\";\n    ctx.lineWidth = 1;\n    ctx.beginPath();\n    for (var x = 0; x < W; x += 40) { ctx.moveTo(x, 0); ctx.lineTo(x, H); }\n    for (var y = 0; y < H; y += 40) { ctx.moveTo(0, y); ctx.lineTo(W, y); }\n    ctx.stroke();\n    drawElements();\n    drawRays();\n    drawSource();\n    requestAnimationFrame(frame);\n  }\n\n  canvas.addEventListener(\"pointerdown\", function(e) {\n    var rect = canvas.getBoundingClientRect();\n    var px = e.clientX - rect.left, py = e.clientY - rect.top;\n    if (Math.hypot(px - source.x, py - source.y) < 30) {\n      dragging = true;\n      animate = false;\n      document.getElementById(\"toggleAnimate\").classList.remove(\"active\");\n      try { canvas.setPointerCapture(e.pointerId); } catch (err) {}\n      e.preventDefault();\n    }\n  });\n  canvas.addEventListener(\"pointermove\", function(e) {\n    if (!dragging) return;\n    var rect = canvas.getBoundingClientRect();\n    source.x = e.clientX - rect.left;\n    source.y = e.clientY - rect.top;\n  });\n  canvas.addEventListener(\"pointerup\", function() { dragging = false; });\n  canvas.addEventListener(\"pointercancel\", function() { dragging = false; });\n  canvas.addEventListener(\"wheel\", function(e) {\n    e.preventDefault();\n    source.angle += e.deltaY * 0.002;\n  }, { passive: false });\n\n  document.getElementById(\"rayCount\").addEventListener(\"input\", function(e) {\n    rayCount = +e.target.value;\n    document.getElementById(\"rayCountVal\").textContent = rayCount;\n  });\n  document.getElementById(\"spread\").addEventListener(\"input\", function(e) {\n    spreadDeg = +e.target.value;\n    document.getElementById(\"spreadVal\").textContent = spreadDeg + \"\u00b0\";\n  });\n  document.getElementById(\"ior\").addEventListener(\"input\", function(e) {\n    currentIOR = (+e.target.value) \/ 100;\n    document.getElementById(\"iorVal\").textContent = currentIOR.toFixed(2);\n  });\n  document.getElementById(\"toggleAnimate\").addEventListener(\"click\", function(e) {\n    animate = !animate;\n    e.currentTarget.classList.toggle(\"active\", animate);\n  });\n  document.getElementById(\"reset\").addEventListener(\"click\", function() {\n    resize();\n    buildECRN();\n    source = { x: W * 0.08, y: H * 0.5, angle: 0 };\n  });\n\n  function init() {\n    resize();\n    buildECRN();\n    source = { x: W * 0.08, y: H * 0.5, angle: 0 };\n  }\n\n  init();\n  window.addEventListener(\"resize\", function() {\n    resize();\n    buildECRN();\n  });\n  setTimeout(init, 100);\n  setTimeout(init, 500);\n\n  requestAnimationFrame(frame);\n})();\n<\/script>\n<\/body>\n<\/html>\n'><\/iframe>\n<\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>European Collaborative Research Network On Optical Wireless Communications ECRN Countries Map Canary Islands ECRN Members Other Country Universities Northumbria University Newcastle upon Tyne, UK Telecommunications Institute Aveiro, Protugal Universita Roma Tre Rome, Italy Universidad del Las Palmas de Gran Canaria Islas Canarias, Spain Czech Technical University in Prague Prague, Czech Republic Universidad de Valencia Valencia, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-47","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/v1.ecrn-owc.eu\/index.php\/wp-json\/wp\/v2\/pages\/47","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/v1.ecrn-owc.eu\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/v1.ecrn-owc.eu\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/v1.ecrn-owc.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/v1.ecrn-owc.eu\/index.php\/wp-json\/wp\/v2\/comments?post=47"}],"version-history":[{"count":53,"href":"https:\/\/v1.ecrn-owc.eu\/index.php\/wp-json\/wp\/v2\/pages\/47\/revisions"}],"predecessor-version":[{"id":588,"href":"https:\/\/v1.ecrn-owc.eu\/index.php\/wp-json\/wp\/v2\/pages\/47\/revisions\/588"}],"wp:attachment":[{"href":"https:\/\/v1.ecrn-owc.eu\/index.php\/wp-json\/wp\/v2\/media?parent=47"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}