{"id":821,"date":"2019-02-01T18:46:50","date_gmt":"2019-02-01T18:46:50","guid":{"rendered":"https:\/\/www.ipleiria.pt\/?page_id=821"},"modified":"2021-08-06T11:51:14","modified_gmt":"2021-08-06T10:51:14","slug":"short-cycle-tesp","status":"publish","type":"page","link":"https:\/\/www.ipleiria.pt\/en\/study\/courses\/short-cycle-tesp\/","title":{"rendered":"Short Cycle Programmes (TeSP)"},"content":{"rendered":"\n<div class=\"wp-container-3 wp-block-columns\">\n<div class=\"wp-container-1 wp-block-column\" style=\"flex-basis:60%\">\n<p class=\"is-style-theme-subtitle\">polit\u00e9cnico de leiria<\/p>\n\n\n\n<p class=\"is-style-theme-title\">Short Cycle Programmes (TeSP)<\/p>\n\n\n\n<p><a href=\"https:\/\/www.dges.gov.pt\/en\/pagina\/curso-tecnico-superior-profissional-ctesp?plid=1529\" target=\"_blank\" rel=\"noreferrer noopener\">Professional Higher Tecnhical Courses<\/a> are short cycle programmes with 120 ECTS. They last two years and do not confer an academic degree. The successful conclusion leads to the award of the diploma of professional technician.<\/p>\n\n\n\n<p>These short cycle programmes (also known by the Portuguese acronym &#8216;TeSP&#8217; include: &nbsp;<\/p>\n\n\n\n<ul><li>general and scientific curricular units;<\/li><li>practical curricular units;<\/li><li>work-related training, which lasts up to one academic year. &nbsp;<\/li><\/ul>\n\n\n\n<p>By completing a TeSP, you&#8217;ll get a qualification equivalent to level 5 of the <a rel=\"noreferrer noopener\" href=\"https:\/\/www.dges.gov.pt\/pt\/quadro_qualificacoes?plid=371\" target=\"_blank\">National Qualification Framework<\/a>.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div>\n\n\n\n<div class=\"wp-container-2 wp-block-column\" style=\"flex-basis:40%\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"925\" height=\"1024\" src=\"https:\/\/www.ipleiria.pt\/wp-content\/uploads\/2021\/04\/tesp.jpg\" alt=\"\" class=\"wp-image-26257\" srcset=\"https:\/\/www.ipleiria.pt\/en\/wp-content\/uploads\/sites\/25\/2021\/04\/tesp.jpg 925w, https:\/\/www.ipleiria.pt\/en\/wp-content\/uploads\/sites\/25\/2021\/04\/tesp-271x300.jpg 271w, https:\/\/www.ipleiria.pt\/en\/wp-content\/uploads\/sites\/25\/2021\/04\/tesp-768x850.jpg 768w\" sizes=\"(max-width: 925px) 100vw, 925px\" \/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator is-style-wide\"\/>\n\n\n    <section aria-describedby=\"courses-section-title\">\n        <h2 id=\"courses-section-title\" class=\"sr-only\">Programs Search<\/h2>\n        <form id=\"courses-search\" name=\"courses-search\" class=\"courses-as-grid\" data-api-url=\"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\" aria-controls=\"courses-list\">\n            <div class=\"container\">\n                <div class=\"row\">\n                    \n                        <select name=\"course_type\" class=\"custom-select custom-select-sm course-taxonomy-filter disabled-filter d-none\" data-api-url=\"${apiUrl}\/${taxonomy}?type=course\" data-include=\"tesp,licenciatura,mestrado,pos-graduacoes,doutoramento\" data-selected=\"tesp\" style=\"-webkit-appearance: none;-moz-appearance: none;\">\n                            <option value=\"\" class=\"font-weight-bold taxonomy-label\">Type: <\/option>\n                        <\/select>\n                        \n                    \n                    <div class=\"col-sm pl-2 pr-2 pl-sm-0\">\n                        <select name=\"course_domain\" class=\"custom-select custom-select-sm course-taxonomy-filter disabled-filter\" data-api-url=\"${apiUrl}\/${taxonomy}?type=course\" data-include=\"artes-e-design,ciencias-empresariais-e-juridicas,educacao-e-ciencias-sociais,engenharia-e-tecnologia,saude-desporto,turismo\"  style=\"-webkit-appearance: none;-moz-appearance: none;\">\n                            <option value=\"\" class=\"font-weight-bold taxonomy-label\">Scientific Field: <\/option>\n                        <\/select>\n                    <\/div>\n                    \n                                        <div class=\"col-sm pl-2 pr-2\">\n                        <label for=\"course_school\" class=\"sr-only\">School: <\/label>\n                        <select id=\"course_school\" name=\"course_school\" class=\"bg-transparent custom-select custom-select-sm course-taxonomy-filter disabled-filter\" data-api-url=\"${apiUrl}\/${taxonomy}?type=course\" data-include=\"esad,esecs,ess,estg,estm\"  style=\"-webkit-appearance: none;-moz-appearance: none; appearance: none;\">\n                            <option value=\"\" class=\"font-weight-bold taxonomy-label\">School: <\/option>\n                        <\/select>\n                    <\/div>\n                    \n                    <div class=\"col-sm pl-2 pr-2\">\n                        <label for=\"course_city\" class=\"sr-only\">City: <\/label>\n                        <select id=\"course_city\" name=\"course_city\" class=\"bg-transparent custom-select custom-select-sm course-taxonomy-filter disabled-filter\" data-api-url=\"${apiUrl}\/${taxonomy}?type=course\" style=\"-webkit-appearance: none;-moz-appearance: none; appearance: none;\">\n                            <option value=\"\" class=\"font-weight-bold taxonomy-label\">City: <\/option>\n                        <\/select>\n                    <\/div>\n                    \n                    <div class=\"col-sm pl-2 pr-2\">\n                        <select name=\"course_schedule\" class=\"custom-select custom-select-sm course-taxonomy-filter disabled-filter\" data-api-url=\"${apiUrl}\/${taxonomy}?type=course\" data-include=\"b-learning,diurno,ensino-a-distancia,pos-laboral\" style=\"-webkit-appearance: none;-moz-appearance: none;\">\n                            <option value=\"\" class=\"font-weight-bold taxonomy-label\">Schedule: <\/option>\n                        <\/select>\n                    <\/div>\n                    <div class=\"col-sm pl-2 pr-2\">\n                        <select name=\"enrolment_state\" class=\"custom-select custom-select-sm course-taxonomy-filter disabled-filter\" data-api-url=\"${apiUrl}\/${taxonomy}?type=course\" data-include=\"abertas,fechadas\" style=\"-webkit-appearance: none;-moz-appearance: none;\">\n                            <option value=\"\" class=\"font-weight-bold taxonomy-label\">Application Status: <\/option>\n                        <\/select>\n                    <\/div>\n                    <div class=\"col-sm pl-2 pr-2\">\n                        <select name=\"course_language\" class=\"custom-select custom-select-sm course-taxonomy-filter disabled-filter\" data-api-url=\"${apiUrl}\/${taxonomy}?type=course\" data-include=\"portugues,ingles\" style=\"-webkit-appearance: none;-moz-appearance: none;\">\n                            <option value=\"\" class=\"font-weight-bold taxonomy-label\">Language: <\/option>\n                        <\/select>\n                    <\/div>\n                    <div class=\"col-sm pl-2 pr-2 pr-sm-0 d-flex flex-sm-grow-0 justify-content-center mt-2 mt-sm-0\">\n                        <div class=\"btn-group courses-layout-btn-group\" role=\"radiogroup\" aria-label=\"Layout\">\n                            <button type=\"button\" role=\"radio\" aria-checked=\"true\" id=\"courses-as-grid\" class=\"courses-layout-btn btn btn-light btn-sm active\">\n                                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" height=\"100%\" width=\"100%\" viewBox=\"0 -256 1800 1800\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M0-56h519.593v400H0zm640.407 0H1160v400H640.407zM1280-56h519.593v400H1280zM0 464h519.593v400H0zm640.407 0H1160v400H640.407zM1280 464h519.593v400H1280zM0 984h519.593v400H0zm640.407 0H1160v400H640.407zM1280 984h519.593v400H1280z\"\/><\/svg>\n                                <span class=\"sr-only\">Grid<\/span><\/button>\n                            <button type=\"button\" role=\"radio\" aria-checked=\"false\" id=\"courses-as-list\" class=\"courses-layout-btn btn btn-light btn-sm\">\n                                <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" height=\"100%\" width=\"100%\" viewBox=\"0 -256 1800 1800\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M0 984h1800v400H0zm0-520h1800v400H0zM0-56h1800v400H0z\"\/><\/svg>\n                                <span class=\"sr-only\">Lista<\/span><\/button>\n                            <input type=\"hidden\" name=\"courses-layout\" id=\"courses-layout\" value=\"courses-as-grid\">\n                        <\/div>\n                    <\/div>\n                <\/div>\n                \n                <div class=\"row\">\n                    <input type=\"text\" class=\"courses-search-input form-control form-control-xs mt-2 mb-2 course-search-filter disabled-filter\" name=\"search\" value=\"\" placeholder=\"Search...\" data-api-url=\"${apiUrl}\/course\" >\n                <\/div>\n                \n                <input style=\"display: none;\" type=\"submit\" value=\"Submit Search\">\n            <\/div>\n            \n            <div id=\"courses-container\">\n                <h3 id=\"courses-list-title\" class=\"courses-list-title\">Programmes<span class=\"sr-only\">: <\/span><\/h3>\n                <div id=\"courses-list\" class=\"\" aria-live=\"polite\" >\n                    <div class=\"container\">Loading&#8230;<\/div>\n                <\/div>\n                <div>\n                    <div class=\"wp-block-button is-style-theme-button-solid mt-4 mt-lg-0 text-center\">\n                        <button id=\"loading-button\" class=\"hide-if-no-js wp-block-button__link\"><span class=\"loading-label\">Show More<\/span>\u00a0<\/button>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/form>\n    <\/section>\n    <script>\n        (function(isSupported){\n        'use strict';\n        \n        document.head.insertAdjacentHTML(\"beforeend\", `\n            <style>\n                #courses-search .course-search-filter,\n                #courses-search .course-taxonomy-filter{\n                    transition: opacity 0.5s;\n                }\n                #courses-search .disabled-filter{\n                    visibility: hidden;\n                    opacity: 0;\n                }\n                #courses-search .enabled-filter{\n                    visibility: visible;\n                    opacity: 1;\n                }\n                \n                \n                #courses-search .courses-layout-btn-group{\n                    padding-top: calc(0.25rem - 1px);\n                }\n                #courses-search .courses-layout-btn svg{\n                    fill: #030303;\n                    height: calc(1.5em - 0.25rem);\n                    width: auto;\n                    pointer-events: none;\n                }\n                #courses-search .btn-light:not(:disabled):not(.disabled):active, \n                #courses-search .show>.btn-light.dropdown-toggle {\n                    color: #FFFFFF;\n                    background-color: #030303;\n                    border-color: #000000;\n                }\n                \n                #courses-search .btn-light:not(:disabled):not(.disabled):active svg{\n                    fill: #FFFFFF\n                }\n                \n                #courses-search .courses-list-title{\n                    background-color: #f2f2f2;\n                    color: #666666;\n                    vertical-align: middle;\n                    padding: .75rem;\n                    font-size: 1rem;\n                    margin: 40px 0 30px;\n                }#courses-list{\n                    min-height: 60px;\n                }\n                .loading{\n                    position: relative;\n                }\n                                .loading:after {\n                    content: '';\n                    display: inline-block;\n                    width: 1.5rem;\n                    height: 1.5rem;\n                    vertical-align: text-bottom;\n                    border: .25em solid currentColor;\n                    border-right-color: transparent;\n                    border-radius: 50%;\n                    animation: spinner-border .75s linear infinite;\n                    position: absolute;\n                    z-index: 3;\n                    left: calc(50% - 0.75rem);\n                    top: 0.75rem;\n                }.courses-as-list #courses-list ul{\n                    list-style: none;\n                    padding: 0;\n                }\n                .courses-as-list #courses-list ul li {\n                    display: flex;\n                    flex-direction: column;\n                }\n                .courses-as-list #courses-list a {\n                    line-height: 1.7rem;\n                    padding: 15px 0.75rem;\n                    margin: 0;\n                    border-bottom: 1px solid #f2f4f7;\n                }\n                .courses-as-list #courses-list a,\n                .courses-as-list #courses-list a:link,\n                .courses-as-list #courses-list a:visited{\n                    color: #262626;\n                    text-decoration: none;\n                }\n                .courses-as-list #courses-list a:hover,\n                .courses-as-list #courses-list a:focus,\n                .courses-as-list #courses-list a:active,\n                .courses-as-list #courses-list a:hover .meta,\n                .courses-as-list #courses-list a:focus .meta,\n                .courses-as-list #courses-list a:active .meta{\n                    color: #8F6600;\n                }\n                .courses-as-list #courses-list a:hover:before,\n                .courses-as-list #courses-list a:focus:before,\n                .courses-as-list #courses-list a:active:before{\n                    border-color: #545454;\n                }\n                .courses-as-list #courses-list a:before {\n                    display: block;\n                    width: 15px;\n                    height: 15px;\n                    border-color: #545454;\n                    border-right: 1px solid;\n                    border-top: 1px solid;\n                    transform: rotate(45deg);\n                    margin: 20px;\n                    content: ' ';\n                    float: right;\n                }\n                \n                .courses-as-list #courses-list a .title{\n                    display: block;\n                    font-weight: 600;\n                    font-size: 1.1rem;\n                }\n                .courses-as-list #courses-list a .meta{\n                    display: flex;\n                    color: #8c8c8c;\n                }\n                .courses-as-list #courses-list a .meta .taxonomy{\n                    font-size: 0.9rem;\n                    line-height: 1rem;\n                }\n                .courses-as-list #courses-list a .meta .taxonomy-label{\n                    font-weight: 600;\n                    padding-right: 5px;\n                }\n                .courses-as-list #courses-list a .meta .taxonomies-separator {\n                    padding: 0 0.2rem 0 0.4rem;\n                }\n                .courses-as-list #courses-list a .meta .taxonomy:not([style*=\"display:none\"]):last-child:after,\n                .courses-as-list #courses-list a .course-thumbnail-wrapper{\n                    display: none;\n                }\n                .courses-as-list #courses-list a .meta .taxonomy-type,\n                .courses-as-list #courses-list a .meta .taxonomy-area,\n                .courses-as-list #courses-list a .meta .taxonomy-clanguage{\n                    display: none;\n                }\n                .courses-as-list #courses-list a .meta .taxonomy-school{\n                    order: 1;\n                }\n                .courses-as-list #courses-list a .meta .taxonomy-period{\n                    order: 2;\n                }\n                .courses-as-list #courses-list a .meta .taxonomy-state{\n                    order: 3;\n                }\n                #courses-search.courses-as-list .courses-list-title{\n                    margin-bottom: 0;\n                }.courses-as-grid #courses-list ul{\n                    display: flex;\n                    flex-wrap: wrap;\n                    margin-right: -15px;\n                    margin-left: -15px;\n                }\n                .courses-as-grid #courses-list ul li{\n                    position: relative;\n                    width: 100%;\n                    padding-right: 15px;\n                    padding-left: 15px;\n                }\n                .courses-as-grid #courses-list a{\n                    display: block;\n                    width: 100%;\n                    padding-top: 30%;\n                    margin-bottom: 30px;\n                    position: relative;\n                    background-color: #1c1c1c;\n                    color: #fffffe;\n                    font-size: 1.5rem;\n                    text-transform: uppercase;\n                    font-weight: 700;\n                    text-decoration: none;\n                }\n                .courses-as-grid #courses-list a:hover,\n                .courses-as-grid #courses-list a:focus,\n                .courses-as-grid #courses-list a:active{\n                    background-color: #edaa03;\n                }\n                .courses-as-grid #courses-list a>.title{\n                    display: flex;\n                    flex-direction: column;\n                    position: absolute;\n                    top: 0;\n                    right: 0;\n                    left: 0;\n                    bottom: 0;\n                    width: 100%;\n                    height: 100%;\n                    align-items: center;\n                    justify-content: center;\n                    text-align: center;\n                    overflow: hidden;\n                    text-overflow: ellipsis;\n                    word-break: break-word;\n                    padding: 15px;\n                    z-index: 2;\n                    line-height: 1.3rem;\n                    text-transform: none;\n                    font-size: 1.2rem;\n                }\n                .courses-as-grid #courses-list a>.meta{\n                    display: none;\n                }\n                .courses-as-grid #courses-list a .course-thumbnail-wrapper{\n                    display: flex;\n                    position: absolute;\n                    top: 0;\n                    right: 0;\n                    left: 0;\n                    bottom: 0;\n                    width: 100%;\n                    height: 100%;\n                    align-items: center;\n                    justify-content: center;\n                    text-align: center;\n                    overflow: hidden;\n                    text-overflow: ellipsis;\n                    word-break: break-word;\n                }\n                .courses-as-grid #courses-list a .course-thumbnail,\n                .courses-as-grid #courses-list a .course-thumbnail-wrapper:after{\n                    display: block;\n                    width: 100%;\n                    height: auto;\n                    max-width: none;\n                    position: absolute;\n                }\n                .courses-as-grid #courses-list a .course-thumbnail-wrapper:after{\n                    content: \" \";\n                    z-index: 1;\n                    background-color: #1c1c1c;\n                    opacity: .5;\n                    left: 0;\n                    right: 0;\n                    top: 0;\n                    bottom: 0;\n                }\n                .courses-as-grid #courses-list a:hover .course-thumbnail-wrapper:after,\n                .courses-as-grid #courses-list a:focus .course-thumbnail-wrapper:after,\n                .courses-as-grid #courses-list a:active .course-thumbnail-wrapper:after{\n                    \/*opacity: 0;*\/\n                    background-color: #edaa03;\n                }\n                @media (min-width: 576px){\n                    .courses-as-grid #courses-list ul li{\n                        flex: 0 0 50%;\n                        max-width: 50%;\n                    }\n                    \n                    .courses-as-grid #courses-list a{\n                        padding-top: 100%;\n                    }\n                    .courses-as-grid #courses-list a .course-thumbnail{\n                        display: block;\n                        height: 100%;\n                        width: auto;\n                    }\n                }\n                @media (min-width: 768px){\n                    .courses-as-grid #courses-list ul li{\n                        flex: 0 0 33.33333%;\n                        max-width: 33.33333%;\n                    }\n                }\n                @media (min-width: 992px){\n                    .courses-as-grid #courses-list ul li{\n                        flex: 0 0 25%;\n                        max-width: 25%;\n                    }\n                }\n            <\/style>\n        `);\n        \n        const taxonomiesInfo = {};\n        \n        const getForm = () => {\n            return document.querySelector('form#courses-search');\n        };\n        \n        const getContainer = ()=>{\n            const form = getForm();\n            return !!form?form.querySelector('#courses-list'):null;\n        };\n        \n        const getLoading = () => {\n            const form = getForm();\n            return !!form?form.querySelector('#loading-button'):null;\n        };\n        \n        const enableLoading = (loading=false) => {\n            const loadingButton = getLoading();\n            if(loadingButton){\n                const loadingLabel = loadingButton.querySelector('.loading-label');\n                if(!!loadingLabel){\n                    loadingLabel.style.display = loading?'none':'initial';\n                }\n                if(loading){\n                    loadingButton.classList.add(\"loading\");\n                    loadingButton.style.display = 'inline-block';\n                }else{\n                    if(ofPages()<=currentPage()){\n                        loadingButton.style.display = 'none';\n                    }\n                    loadingButton.classList.remove(\"loading\");\n                }\n                loadingButton.setAttribute(\"aria-busy\", loading);\n                loadingButton.dataset.loading = loading;\n            }\n        };\n        \n        const isLoading = () => {\n            const loadingButton = getLoading();\n            return !!loadingButton && loadingButton.dataset.loading===true;\n        };\n        \n        const currentPage = () => {\n            const loadingButton = getLoading();\n            return !!loadingButton && !!loadingButton.dataset.page ? parseInt(loadingButton.dataset.page) : 0 ;\n        };\n        \n        const ofPages = () => {\n            const loadingButton = getLoading();\n            return !!loadingButton && !!loadingButton.dataset.totalPages ? loadingButton.dataset.totalPages : 0 ;\n        };\n        \n        const doGetApiRequest = (url, page=1, allPages=false) => {\n            let totalPages = 0;\n            \n            const loadingButton = getLoading();\n            if(loadingButton && !allPages){\n                loadingButton.dataset.page = page;\n            }\n            \n            return fetch( url, {\n                \/\/credentials: 'omit',\n                mode: 'cors'\n            })\n            .then( response => {\n                if (response.status === 200) {\n                    const contentType = response.headers.get('content-type');\n                    totalPages = response.headers.get('X-WP-TotalPages');\n                    if(loadingButton && !allPages){\n                        loadingButton.dataset.totalPages = totalPages;\n                    }\n                    if (!contentType || !contentType.includes('application\/json')) {\n                        throw new TypeError(\"Invalid JSON response\");\n                    }\n                    return response.json();\n                }\n            })\n            .then( response => {\n                if (page>1 || totalPages<=1) {\n                    return response;\n                }else if(allPages){\n                    let pageUrl = new URL(url);\n                    let params = new URLSearchParams(url.search);\n                    const requests = Array.from({length:(totalPages-1)},(v,k)=>k+1+1).map(page=>{\n                        params.set('page', page);\n                        pageUrl.search = params.toString();\n                        return doGetApiRequest(pageUrl.toString(), page, allPages);\n                    });\n                    return Promise.all(requests)\n                        .then(responses => {\n                            return response.concat(responses.flat());\n                        });\n                }\n                return response;\n            })\n            .catch(err => {\n                \/\/console.error('Error: ', err);\n                const container = document.getElementById('courses-list');\n                if(!!container){\n                    container.innerHTML = `Error`;\n                }\n                enableLoading(false);\n                return err;\n            });\n        };\n        \n        \n        const syncState = () => {\n            const form = getForm();\n            history.replaceState({ 'courseSearch': Object.fromEntries(new FormData(form)) }, '');\n        };\n        \n        const doSearch = (page=1) => {\n            const form = getForm();\n            const input = form.querySelector('.courses-search-input');\n            const container = getContainer();\n            const url = new URL(input.dataset.apiUrl.replace(\/\\${apiUrl}\/,form.dataset.apiUrl));\n            const taxonomies = Object.keys(taxonomiesInfo);\n            const urlSearchParameters = new URLSearchParams({\n                '_fields': 'title,content,date,link,_links,_embedded.wp:featuredmedia,'+taxonomies.join(\",\"),\n                '_embed':'wp:term,wp:featuredmedia','context': 'view',\n                'per_page': 12,\n                'page': page,\n                'orderby': 'title',\n                'order': 'asc',\n            });\n            \n            enableLoading(true);\n            syncState();\n            \n            const formData = new FormData(form);\n            for (let [key, value] of formData.entries()) { \n                if(!!value && value.length>0){\n                    urlSearchParameters.append(key, value);\n                }\n            }\n            url.search = urlSearchParameters.toString();\n            \n            if(page<=1){\n                container.innerHTML = '<ul class=\"courses-list-items-container no-bullets\" aria-role=\"group\" aria-describedby=\"courses-list-title\"><\/ul>';\n            }\n            \n            return doGetApiRequest(url, page).then(posts => {\n                if(!posts || typeof posts[Symbol.iterator] !== 'function'){\n                    if(page<=1){\n                        container.innerHTML = '';\n                    }\n                    return posts;\n                }\n                if(posts.length<=0){\n                    container.innerHTML = 'No data to show.';\n                }else{\n                    const itemsContainer = container.querySelector('.courses-list-items-container');\n                    if(!!itemsContainer){\n                        let output = '';\n                        for ( let post of posts ) {\n                            let meta = `<dl title=\"More info:\" class=\"meta\">`;\n                            meta += taxonomies.map(taxonomy=>{\n                                let info =  (Array.isArray(post[taxonomy]) && taxonomiesInfo[taxonomy])?post[taxonomy].map(id=>{\n                                    return (taxonomiesInfo[taxonomy][id] && taxonomiesInfo[taxonomy][id].name && taxonomiesInfo[taxonomy][id].name.length>0)?taxonomiesInfo[taxonomy][id].name:false;\n                                }).join('<span class=\"taxonomy-separator\">, <\/span>'):false;\n                                \n                                return (info && taxonomiesInfo[taxonomy].label && taxonomiesInfo[taxonomy].label.length>0) ? (`\n                                    <dt class=\"taxonomy taxonomy-label taxonomy-${taxonomy}\">${taxonomiesInfo[taxonomy].label}<\/dt> \n                                    <dd class=\"taxonomy taxonomy-value\">${info}<span class=\"taxonomies-separator\">.\u00a0<\/span><\/dd>`):'';\n                            }).join('');\n                            meta += '<\/dl>';\n                            \n                            let featuredMedia = '';\n                            const featuredMediaInfo = (post._embedded && Array.isArray(post._embedded[\"wp:featuredmedia\"]) && post._embedded[\"wp:featuredmedia\"].length>0)?post._embedded[\"wp:featuredmedia\"].shift():null;\n                            if(featuredMediaInfo && featuredMediaInfo.source_url){\n                                const srcSet = [];\n                                const sizes = '';\n                                if(featuredMediaInfo.media_details && typeof featuredMediaInfo.media_details.sizes === 'object' && featuredMediaInfo.media_details.sizes !== null){\n                                    for (let [key, size] of Object.entries(featuredMediaInfo.media_details.sizes)) {\n                                        if(size.source_url && size.width){\n                                            srcSet.push(`${size.source_url} ${size.width}w`);\n                                        }\n                                    }\n                                    if(srcSet.length>0){\n                                        featuredMedia += ` srcset=\"${srcSet.join(', ')}\"`;\n                                    }\n                                }\n                                if(featuredMediaInfo.media_details.width){\n                                    featuredMedia +=` sizes=\"(max-width: ${featuredMediaInfo.media_details.width}px) 100vw, ${featuredMediaInfo.media_details.width}px\"`;\n                                }\n                                featuredMedia = `<span class=\"course-thumbnail-wrapper\"><img class=\"course-thumbnail\" loading=\"lazy\" alt=\"\" src=\"${featuredMediaInfo.source_url}\" ${featuredMedia}><\/span>`;\n                            } \n                            \n                            output += `\n                                <li>\n                                    <a href=\"${post.link}\">\n                                        ${featuredMedia}\n                                        <span class=\"title\">${post.title.rendered}<span class=\"sr-only\">.\u00a0<\/span><\/span>\n                                        ${meta}\n                                    <\/a>\n                                <\/li>\n                            `;\n                        }\n                        itemsContainer.innerHTML += output;\n                    }\n                }\n                enableLoading(false);\n                return posts;\n            });\n        };\n        \n        document.addEventListener('DOMContentLoaded', () => {\n            const form = getForm();\n            if(!isSupported || form===undefined || form.dataset.apiUrl===undefined){\n                return;\n            }\n            \n            enableLoading(true);\n            \n            if (form.querySelector('.courses-layout-btn')) {\n                form.querySelectorAll('.courses-layout-btn').forEach((button) => {\n                    button.addEventListener(\"click\", function(event) {\n                        const input = form.querySelector('#courses-layout');\n                        if(event.target.tagName === \"BUTTON\" && !form.classList.contains(event.target.id)){\n                            form.classList.remove(event.target.id===\"courses-as-grid\"?\"courses-as-list\":\"courses-as-grid\");\n                            form.classList.add(event.target.id);\n                            if(input){\n                                input.value = event.target.id;\n                            }\n                            form.querySelectorAll('.courses-layout-btn.active').forEach((button) => {\n                                button.classList.remove('active');\n                                button.setAttribute('aria-checked', 'false');\n                            });\n                            button.classList.add('active');\n                            button.setAttribute('aria-checked', 'true');\n                        }\n                        syncState();\n                    });\n                });\n            }\n            \n            const loadingButton = getLoading();\n            if(loadingButton){\n                loadingButton.addEventListener(\"click\", function(event) {\n                    if(!isLoading() && (ofPages()>0 && ofPages()>currentPage())){\n                        doSearch(currentPage()+1).then(posts => {});\n                    }\n                    event.preventDefault();\n                });\n            }\n            \n            const container = document.getElementById('courses-list');\n            const taxonomiesRequests = Array.from(form.querySelectorAll(\".course-taxonomy-filter\")).map(taxonomy => {\n            \n                if(! \"apiUrl\" in taxonomy.dataset || ! \"taxonomy\" in taxonomy.dataset){\n                    return;\n                }\n                const taxonomySlug = taxonomy.getAttribute(\"name\");\n                const taxonomyLabel = taxonomy.querySelector(\".taxonomy-label\");\n                const taxonomySelected = taxonomy.dataset.selected||'';\n                const taxonomyInclude = taxonomy.dataset.include?taxonomy.dataset.include.split(','):[];\n                taxonomiesInfo[taxonomySlug] = {};\n                \n                let url = new URL(taxonomy.dataset.apiUrl.replace(\/\\${apiUrl}\/, form.dataset.apiUrl).replace(\/\\${taxonomy}\/, taxonomySlug));\n                url.search = new URLSearchParams({\n                    '_fields': 'id,slug,name,taxonomy,link,description,count',\n                    'context': 'view'\n                }).toString();\n                \n                return doGetApiRequest(url).then(terms => {\n                    if(typeof terms[Symbol.iterator] !== 'function'){\n                        return;\n                    }\n                    if(taxonomyLabel && taxonomyLabel.text){\n                        taxonomiesInfo[taxonomySlug]['label'] = taxonomyLabel.text;\n                    }\n                    for ( let term of terms ) {\n                        if(taxonomyInclude.length>0 && !taxonomyInclude.includes(term.slug)){\n                            continue;\n                        }\n                        \n                        taxonomiesInfo[taxonomySlug][term.id] = term;\n                        \n                        let option = document.createElement(\"option\");\n                        option.text = term.name;\n                        option.value = term.id;\n                        option.id = `select-${taxonomySlug}-${term.slug}`;\n                        if(term.slug===taxonomySelected){\n                            option.selected = true;\n                            option.setAttribute('selected', 'selected');\n                        }\n                        taxonomy.appendChild(option);\n                    }\n                    \n                    taxonomy.addEventListener('change', ()=>doSearch());\n                    taxonomy.classList.replace(\"disabled-filter\", \"enabled-filter\");\n                });\n            });\n            \n            Promise.all(taxonomiesRequests).then(()=>{\n                form.addEventListener('submit',  event => {\n                    doSearch();\n                    \n                    event.preventDefault();\n                });\n                \n                \n                const input = form.querySelector('.courses-search-input');\n                input.timeout = null;\n                input.addEventListener('keyup', function (e) {\n                    clearTimeout(input.timeout);\n                \n                    input.timeout = setTimeout(()=>{\n                        doSearch();\n                    }, 350);\n                });\n                input.addEventListener('blur', function (e) {\n                    clearTimeout(input.timeout);\n                });\n                input.classList.replace(\"disabled-filter\", \"enabled-filter\");if(history.state && history.state.courseSearch){\n                    let formItem, formItemKey;\n                    for ( formItemKey in history.state.courseSearch ) {\n                        if(history.state.courseSearch[formItemKey] && history.state.courseSearch[formItemKey].length>0 && (formItem = form.querySelector(`[name=\"${formItemKey}\"]:not([data-selected])`) )){\n                            formItem.value = history.state.courseSearch[formItemKey];\n                        }\n                    }\n                    const input = form.querySelector('#courses-layout');\n                    if(input && input.value.length>0 && !form.classList.contains(input.value)){\n                        form.classList.remove(input.value===\"courses-as-grid\"?\"courses-as-list\":\"courses-as-grid\");\n                        form.classList.add(input.value);\n                        form.querySelectorAll('.courses-layout-btn').forEach((button) => {\n                            if(button.id == input.value){\n                                button.classList.add('active');\n                                button.setAttribute('aria-checked', 'true');\n                            }else{\n                                button.classList.remove('active');\n                                button.setAttribute('aria-checked', 'false');\n                            }\n                        });\n                    }\n                }\n                doSearch().then(posts => {const loadingButton = getLoading();\n                    if(loadingButton){\n                        (new IntersectionObserver((targets)=>{\n                            targets.forEach((target) => {\n                                if (target.isIntersecting && target.intersectionRatio >= 0.75 && !isLoading() && (ofPages()>0 && ofPages()>currentPage())) {\n                                    target.target.dispatchEvent(new MouseEvent('click', {\n                                        view: window,\n                                        bubbles: true,\n                                        cancelable: true\n                                    }));\n                                }\n                            });\n                        }, {\n                          root: null,\n                          rootMargin: '0px',\n                          threshold: 1.0\n                        })).observe(loadingButton);\n                    }\n                });\n            });\n        });\n    })(\n           \"fetch\" in window \n        && \"URL\" in window \n        && \"URLSearchParams\" in window \n        && \"FormData\" in window\n        && \"Promise\" in window\n        && \"history\" in window\n        && \"querySelector\" in document\n        && \"querySelectorAll\" in document\n        && \"includes\" in Array()\n        && \"from\" in Array\n        && (function(){\n            try{\n                Function(\"() => {};\"); \n                Function(\"class Feature {};\");\n                return true;\n            }catch(exception){\n                return false;\n            }\n        })()\n    );\n        <\/script>\n    <noscript>\n        JavaScript is not supported.\n        <a href=\"&#x2F;en&#x2F;wp-json&#x2F;wp&#x2F;v2&#x2F;pages&#x2F;821&#x3F;nojs&#x3D;true\">\n             Please visit an alternate version.\n        <\/a>\n    <\/noscript>\n","protected":false},"excerpt":{"rendered":"polit\u00e9cnico de leiria Short Cycle Programmes (TeSP) Professional Higher Tecnhical Courses are short cycle programmes with 120 ECTS. They last two years and do not confer an academic degree. The successful conclusion leads to the award of the diploma of professional technician. These short cycle programmes (also known by the Portuguese acronym &#8216;TeSP&#8217; include: &nbsp; [&hellip;]","protected":false},"author":1,"featured_media":26673,"parent":817,"menu_order":10,"comment_status":"closed","ping_status":"closed","template":"","meta":{"multilingual_post_translation":"{\"pt-PT\":{\"url\":\"https:\/\/www.ipleiria.pt\/estudar\/cursos\/tesp\/\",\"postID\":null,\"postTitle\":\"\",\"siteID\":1,\"customURL\":true,\"languageInfo\":{\"multilingual_site_api_url\":\"https:\/\/www.ipleiria.pt\/wp-json\/\",\"name\":\"Portugu\u00eas\",\"locale\":\"pt_PT\"}}}","custompostfields_page-thumbnail":"","custompostfields_banners":"","custompostfields_meta-description":""},"_links":{"self":[{"href":"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\/pages\/821"}],"collection":[{"href":"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\/comments?post=821"}],"version-history":[{"count":19,"href":"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\/pages\/821\/revisions"}],"predecessor-version":[{"id":34988,"href":"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\/pages\/821\/revisions\/34988"}],"up":[{"embeddable":true,"href":"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\/pages\/817"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\/media\/26673"}],"wp:attachment":[{"href":"https:\/\/www.ipleiria.pt\/en\/wp-json\/wp\/v2\/media?parent=821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}