{"id":18,"date":"2026-04-01T14:46:02","date_gmt":"2026-04-01T07:46:02","guid":{"rendered":"https:\/\/www.chiangmaiconvention.com\/?page_id=18"},"modified":"2026-10-05T09:33:32","modified_gmt":"2026-10-05T02:33:32","slug":"event","status":"publish","type":"page","link":"https:\/\/www.chiangmaiconvention.com\/en\/event\/","title":{"rendered":"Event"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"18\" class=\"elementor elementor-18\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8b42ba9 e-flex e-con-boxed e-con e-parent\" data-id=\"8b42ba9\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-73b161e elementor-widget elementor-widget-html\" data-id=\"73b161e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<style>\r\n\/* =========================================================\r\n   CMEC EVENTS\r\n========================================================= *\/\r\n\r\n#cmec-events-app{\r\n    width:100%;\r\n    max-width:1440px;\r\n    margin:0 auto;\r\n    padding:10px 20px 70px;\r\n    font-family:\"Noto Sans Thai\", Arial, sans-serif;\r\n    color:#111;\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   MODERN MONTH FILTER\r\n========================================================= *\/\r\n\r\n.cmec-filter-wrap{\r\n    display:flex;\r\n    justify-content:flex-end;\r\n    align-items:center;\r\n    gap:14px;\r\n    margin-bottom:32px;\r\n}\r\n\r\n.cmec-filter-label{\r\n    font-size:16px;\r\n    font-weight:500;\r\n    color:#172342;\r\n    white-space:nowrap;\r\n}\r\n\r\n.cmec-select{\r\n    position:relative;\r\n    width:250px;\r\n}\r\n\r\n.cmec-select-button{\r\n    width:100%;\r\n    height:52px;\r\n\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:space-between;\r\n\r\n    padding:0 16px 0 18px;\r\n\r\n    border:1px solid #e7dcc0;\r\n    border-radius:12px;\r\n\r\n    background:#fff;\r\n    color:#172342;\r\n\r\n    font-family:inherit;\r\n    font-size:16px;\r\n    font-weight:400;\r\n\r\n    cursor:pointer;\r\n\r\n    box-shadow:\r\n        0 5px 18px rgba(23,35,66,.06);\r\n\r\n    transition:\r\n        border-color .2s ease,\r\n        box-shadow .2s ease,\r\n        transform .2s ease;\r\n}\r\n\r\n.cmec-select-button:hover{\r\n    border-color:#c99a29;\r\n\r\n    box-shadow:\r\n        0 7px 20px rgba(23,35,66,.09);\r\n}\r\n\r\n.cmec-select.open .cmec-select-button{\r\n    border-color:#c99a29;\r\n\r\n    box-shadow:\r\n        0 0 0 3px rgba(201,154,41,.11),\r\n        0 10px 25px rgba(23,35,66,.08);\r\n}\r\n\r\n.cmec-select-arrow{\r\n    width:18px;\r\n    height:18px;\r\n    flex:0 0 18px;\r\n\r\n    transition:transform .25s ease;\r\n}\r\n\r\n.cmec-select.open .cmec-select-arrow{\r\n    transform:rotate(180deg);\r\n}\r\n\r\n.cmec-select-menu{\r\n    position:absolute;\r\n\r\n    top:calc(100% + 8px);\r\n    left:0;\r\n    right:0;\r\n\r\n    z-index:9999;\r\n\r\n    padding:7px;\r\n\r\n    background:#fff;\r\n\r\n    border:1px solid #eee3c5;\r\n    border-radius:14px;\r\n\r\n    box-shadow:\r\n        0 16px 45px rgba(18,31,60,.15);\r\n\r\n    opacity:0;\r\n    visibility:hidden;\r\n\r\n    transform:translateY(-5px);\r\n\r\n    transition:\r\n        opacity .18s ease,\r\n        visibility .18s ease,\r\n        transform .18s ease;\r\n}\r\n\r\n.cmec-select.open .cmec-select-menu{\r\n    opacity:1;\r\n    visibility:visible;\r\n    transform:translateY(0);\r\n}\r\n\r\n.cmec-select-option{\r\n    display:flex;\r\n    align-items:center;\r\n\r\n    width:100%;\r\n    min-height:43px;\r\n\r\n    padding:8px 12px;\r\n\r\n    border:0;\r\n    border-radius:9px;\r\n\r\n    background:transparent;\r\n    color:#172342;\r\n\r\n    font-family:inherit;\r\n    font-size:15px;\r\n\r\n    text-align:left;\r\n\r\n    cursor:pointer;\r\n\r\n    transition:\r\n        background .15s ease,\r\n        color .15s ease,\r\n        padding-left .15s ease;\r\n}\r\n\r\n.cmec-select-option:hover{\r\n    background:#f8f3e7;\r\n    color:#ae7d12;\r\n    padding-left:15px;\r\n}\r\n\r\n.cmec-select-option.active{\r\n    background:#172342;\r\n    color:#fff;\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   EVENT GRID\r\n========================================================= *\/\r\n\r\n.cmec-event-grid{\r\n    display:grid;\r\n    grid-template-columns:repeat(3,minmax(0,1fr));\r\n    column-gap:58px;\r\n    row-gap:48px;\r\n    width:100%;\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   EVENT CARD\r\n========================================================= *\/\r\n\r\n.cmec-event-card{\r\n    width:100%;\r\n    min-width:0;\r\n    margin:0;\r\n    padding:0;\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   IMAGE\r\n========================================================= *\/\r\n\r\n.cmec-event-thumb{\r\n    position:relative;\r\n\r\n    width:100%;\r\n    aspect-ratio:1 \/ 1;\r\n\r\n    margin:0;\r\n    padding:0;\r\n\r\n    overflow:hidden;\r\n\r\n    border-radius:22px;\r\n\r\n    background:#f3f3f3;\r\n}\r\n\r\n.cmec-event-thumb a{\r\n    display:block;\r\n    width:100%;\r\n    height:100%;\r\n}\r\n\r\n.cmec-event-thumb img{\r\n    display:block;\r\n\r\n    width:100%;\r\n    height:100%;\r\n\r\n    object-fit:cover;\r\n\r\n    transition:transform .35s ease;\r\n}\r\n\r\n.cmec-event-card:hover .cmec-event-thumb img{\r\n    transform:scale(1.025);\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   EVENT DATE\r\n========================================================= *\/\r\n\r\n.cmec-event-date{\r\n    display:flex;\r\n    align-items:center;\r\n    gap:10px;\r\n\r\n    margin-top:18px;\r\n    margin-bottom:9px;\r\n\r\n    color:#bd8b16;\r\n\r\n    font-size:18px;\r\n    font-weight:400;\r\n    line-height:1.4;\r\n}\r\n\r\n.cmec-event-date span{\r\n    display:block;\r\n    margin:0;\r\n    padding:0;\r\n}\r\n\r\n.cmec-calendar-icon{\r\n    display:block;\r\n\r\n    width:25px;\r\n    height:25px;\r\n\r\n    flex:0 0 25px;\r\n\r\n    fill:#d1a13a;\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   TITLE\r\n========================================================= *\/\r\n\r\n.cmec-event-title{\r\n    margin:0 !important;\r\n    padding:0 !important;\r\n\r\n    color:#000;\r\n\r\n    font-size:20px;\r\n    font-weight:400;\r\n    line-height:1.45;\r\n}\r\n\r\n.cmec-event-title a{\r\n    display:block;\r\n\r\n    margin:0;\r\n    padding:0;\r\n\r\n    color:#000;\r\n\r\n    text-decoration:none;\r\n\r\n    transition:color .2s ease;\r\n}\r\n\r\n.cmec-event-title a:hover{\r\n    color:#bd8b16;\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   LOADING \/ EMPTY \/ ERROR\r\n========================================================= *\/\r\n\r\n.cmec-loading,\r\n.cmec-empty,\r\n.cmec-error{\r\n    width:100%;\r\n\r\n    padding:60px 20px;\r\n\r\n    text-align:center;\r\n\r\n    color:#777;\r\n\r\n    font-size:16px;\r\n}\r\n\r\n.cmec-empty,\r\n.cmec-error{\r\n    grid-column:1 \/ -1;\r\n}\r\n\r\n.cmec-error{\r\n    color:#a33;\r\n}\r\n\r\n.cmec-loader{\r\n    width:36px;\r\n    height:36px;\r\n\r\n    margin:0 auto 14px;\r\n\r\n    border:3px solid #eee;\r\n    border-top-color:#c99a29;\r\n\r\n    border-radius:50%;\r\n\r\n    animation:cmec-spin .8s linear infinite;\r\n}\r\n\r\n@keyframes cmec-spin{\r\n    to{\r\n        transform:rotate(360deg);\r\n    }\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   TABLET\r\n========================================================= *\/\r\n\r\n@media(max-width:1024px){\r\n\r\n    #cmec-events-app{\r\n        padding-left:18px;\r\n        padding-right:18px;\r\n    }\r\n\r\n    .cmec-event-grid{\r\n        grid-template-columns:repeat(2,minmax(0,1fr));\r\n        column-gap:35px;\r\n        row-gap:42px;\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   MOBILE\r\n========================================================= *\/\r\n\r\n@media(max-width:767px){\r\n\r\n    #cmec-events-app{\r\n        padding:10px 15px 50px;\r\n    }\r\n\r\n    .cmec-filter-wrap{\r\n        display:block;\r\n        margin-bottom:24px;\r\n    }\r\n\r\n    .cmec-filter-label{\r\n        display:block;\r\n        margin-bottom:8px;\r\n        font-size:15px;\r\n    }\r\n\r\n    .cmec-select{\r\n        width:100%;\r\n    }\r\n\r\n    .cmec-select-button{\r\n        height:50px;\r\n        font-size:15px;\r\n    }\r\n\r\n    .cmec-event-grid{\r\n        grid-template-columns:1fr;\r\n        row-gap:36px;\r\n    }\r\n\r\n    .cmec-event-thumb{\r\n        border-radius:15px;\r\n    }\r\n\r\n    .cmec-event-date{\r\n        gap:8px;\r\n        margin-top:14px;\r\n        margin-bottom:7px;\r\n        font-size:16px;\r\n    }\r\n\r\n    .cmec-calendar-icon{\r\n        width:22px;\r\n        height:22px;\r\n        flex-basis:22px;\r\n    }\r\n\r\n    .cmec-event-title{\r\n        font-size:18px;\r\n        line-height:1.45;\r\n    }\r\n\r\n}\r\n<\/style>\r\n\r\n\r\n<div id=\"cmec-events-app\">\r\n\r\n    <div class=\"cmec-filter-wrap\">\r\n\r\n        <div class=\"cmec-filter-label\">\r\n            Choose Event Month\r\n        <\/div>\r\n\r\n        <div class=\"cmec-select\" id=\"cmecCustomSelect\">\r\n\r\n            <button\r\n                type=\"button\"\r\n                class=\"cmec-select-button\"\r\n                id=\"cmecSelectButton\">\r\n\r\n                <span id=\"cmecSelectedText\">\r\n                    \u0e01\u0e33\u0e25\u0e31\u0e07\u0e42\u0e2b\u0e25\u0e14...\r\n                <\/span>\r\n\r\n                <svg\r\n                    class=\"cmec-select-arrow\"\r\n                    viewbox=\"0 0 24 24\"\r\n                    fill=\"none\"\r\n                    stroke=\"currentColor\"\r\n                    stroke-width=\"2\">\r\n\r\n                    <path d=\"M6 9l6 6 6-6\"><\/path>\r\n\r\n                <\/svg>\r\n\r\n            <\/button>\r\n\r\n            <div\r\n                class=\"cmec-select-menu\"\r\n                id=\"cmecSelectMenu\">\r\n            <\/div>\r\n\r\n        <\/div>\r\n\r\n    <\/div>\r\n\r\n\r\n    <div id=\"cmec-loading\" class=\"cmec-loading\">\r\n\r\n        <div class=\"cmec-loader\"><\/div>\r\n\r\n        \u0e01\u0e33\u0e25\u0e31\u0e07\u0e42\u0e2b\u0e25\u0e14\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21...\r\n\r\n    <\/div>\r\n\r\n\r\n    <div\r\n        id=\"cmec-event-grid\"\r\n        class=\"cmec-event-grid\"\r\n        style=\"display:none;\">\r\n    <\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<script>\r\n(function(){\r\n\r\n\r\n\/* =========================================================\r\n   SETTINGS\r\n========================================================= *\/\r\n\r\nconst SITE_URL =\r\n    window.location.origin;\r\n\r\n\r\nconst CATEGORY_SLUG =\r\n    'events';\r\n\r\n\r\nconst EVENT_DATE_FIELD =\r\n    'event_date';\r\n\r\n\r\nconst EVENT_START_DATE_FIELD =\r\n    'event_start_date';\r\n\r\n\r\nconst PER_PAGE =\r\n    100;\r\n\r\n\r\n\/* =========================================================\r\n   ELEMENTS\r\n========================================================= *\/\r\n\r\nconst grid =\r\n    document.getElementById(\r\n        'cmec-event-grid'\r\n    );\r\n\r\nconst loading =\r\n    document.getElementById(\r\n        'cmec-loading'\r\n    );\r\n\r\nconst customSelect =\r\n    document.getElementById(\r\n        'cmecCustomSelect'\r\n    );\r\n\r\nconst selectButton =\r\n    document.getElementById(\r\n        'cmecSelectButton'\r\n    );\r\n\r\nconst selectedText =\r\n    document.getElementById(\r\n        'cmecSelectedText'\r\n    );\r\n\r\nconst selectMenu =\r\n    document.getElementById(\r\n        'cmecSelectMenu'\r\n    );\r\n\r\n\r\nlet allPosts = [];\r\n\r\n\r\n\/* =========================================================\r\n   THAI MONTHS\r\n========================================================= *\/\r\n\r\nconst thaiMonths = [\r\n\r\n    '\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21',\r\n    '\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c',\r\n    '\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21',\r\n    '\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19',\r\n    '\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21',\r\n    '\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19',\r\n    '\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21',\r\n    '\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21',\r\n    '\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19',\r\n    '\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21',\r\n    '\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19',\r\n    '\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21'\r\n\r\n];\r\n\r\n\r\n\/* =========================================================\r\n   CUSTOM SELECT OPEN \/ CLOSE\r\n========================================================= *\/\r\n\r\nselectButton.addEventListener(\r\n    'click',\r\n    function(e){\r\n\r\n        e.stopPropagation();\r\n\r\n        customSelect.classList.toggle(\r\n            'open'\r\n        );\r\n\r\n    }\r\n);\r\n\r\n\r\ndocument.addEventListener(\r\n    'click',\r\n    function(){\r\n\r\n        customSelect.classList.remove(\r\n            'open'\r\n        );\r\n\r\n    }\r\n);\r\n\r\n\r\nselectMenu.addEventListener(\r\n    'click',\r\n    function(e){\r\n\r\n        e.stopPropagation();\r\n\r\n    }\r\n);\r\n\r\n\r\n\/* =========================================================\r\n   GET CATEGORY ID\r\n========================================================= *\/\r\n\r\nasync function getCategoryId(){\r\n\r\n    const url =\r\n        `${SITE_URL}\/wp-json\/wp\/v2\/categories` +\r\n        `?slug=${encodeURIComponent(CATEGORY_SLUG)}`;\r\n\r\n\r\n    const response =\r\n        await fetch(\r\n            url,\r\n            {\r\n                credentials:'same-origin'\r\n            }\r\n        );\r\n\r\n\r\n    if(!response.ok){\r\n\r\n        throw new Error(\r\n            '\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e2d\u0e48\u0e32\u0e19\u0e2b\u0e21\u0e27\u0e14\u0e2b\u0e21\u0e39\u0e48 Events \u0e44\u0e14\u0e49'\r\n        );\r\n\r\n    }\r\n\r\n\r\n    const categories =\r\n        await response.json();\r\n\r\n\r\n    if(!categories.length){\r\n\r\n        throw new Error(\r\n            '\u0e44\u0e21\u0e48\u0e1e\u0e1a Category: ' +\r\n            CATEGORY_SLUG\r\n        );\r\n\r\n    }\r\n\r\n\r\n    return categories[0].id;\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   GET EVENT DATE TEXT\r\n========================================================= *\/\r\n\r\nfunction getEventDateText(post){\r\n\r\n    if(\r\n        post.event_date !== undefined &&\r\n        post.event_date !== null &&\r\n        String(post.event_date).trim() !== ''\r\n    ){\r\n\r\n        return String(\r\n            post.event_date\r\n        ).trim();\r\n\r\n    }\r\n\r\n\r\n    if(\r\n        post.acf &&\r\n        post.acf[EVENT_DATE_FIELD] !== undefined &&\r\n        post.acf[EVENT_DATE_FIELD] !== null &&\r\n        String(\r\n            post.acf[EVENT_DATE_FIELD]\r\n        ).trim() !== ''\r\n    ){\r\n\r\n        return String(\r\n            post.acf[EVENT_DATE_FIELD]\r\n        ).trim();\r\n\r\n    }\r\n\r\n\r\n    if(\r\n        post.meta &&\r\n        post.meta[EVENT_DATE_FIELD] !== undefined &&\r\n        post.meta[EVENT_DATE_FIELD] !== null &&\r\n        String(\r\n            post.meta[EVENT_DATE_FIELD]\r\n        ).trim() !== ''\r\n    ){\r\n\r\n        return String(\r\n            post.meta[EVENT_DATE_FIELD]\r\n        ).trim();\r\n\r\n    }\r\n\r\n\r\n    return '';\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   EVENT START DATE VALUE\r\n========================================================= *\/\r\n\r\nfunction getEventStartDateValue(post){\r\n\r\n    if(\r\n        post.event_start_date !== undefined &&\r\n        post.event_start_date !== null &&\r\n        String(post.event_start_date).trim() !== ''\r\n    ){\r\n\r\n        return String(\r\n            post.event_start_date\r\n        ).trim();\r\n\r\n    }\r\n\r\n\r\n    if(\r\n        post.acf &&\r\n        post.acf[EVENT_START_DATE_FIELD] !== undefined &&\r\n        post.acf[EVENT_START_DATE_FIELD] !== null &&\r\n        String(\r\n            post.acf[EVENT_START_DATE_FIELD]\r\n        ).trim() !== ''\r\n    ){\r\n\r\n        return String(\r\n            post.acf[EVENT_START_DATE_FIELD]\r\n        ).trim();\r\n\r\n    }\r\n\r\n\r\n    if(\r\n        post.meta &&\r\n        post.meta[EVENT_START_DATE_FIELD] !== undefined &&\r\n        post.meta[EVENT_START_DATE_FIELD] !== null &&\r\n        String(\r\n            post.meta[EVENT_START_DATE_FIELD]\r\n        ).trim() !== ''\r\n    ){\r\n\r\n        return String(\r\n            post.meta[EVENT_START_DATE_FIELD]\r\n        ).trim();\r\n\r\n    }\r\n\r\n\r\n    return '';\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   PARSE EVENT START DATE\r\n   \u0e23\u0e2d\u0e07\u0e23\u0e31\u0e1a \u0e04.\u0e28. \u0e41\u0e25\u0e30 \u0e1e.\u0e28.\r\n========================================================= *\/\r\n\r\nfunction parseEventStartDate(value){\r\n\r\n    const raw =\r\n        String(\r\n            value || ''\r\n        ).trim();\r\n\r\n\r\n    if(!raw){\r\n\r\n        return null;\r\n\r\n    }\r\n\r\n\r\n    let match;\r\n\r\n\r\n    \/* -----------------------------------------------------\r\n       Ymd\r\n\r\n       \u0e04.\u0e28. \u0e40\u0e0a\u0e48\u0e19 20260924\r\n       \u0e1e.\u0e28. \u0e40\u0e0a\u0e48\u0e19 25690924\r\n    ----------------------------------------------------- *\/\r\n\r\n    match =\r\n        raw.match(\r\n            \/^(\\d{4})(\\d{2})(\\d{2})$\/\r\n        );\r\n\r\n    if(match){\r\n\r\n        let year =\r\n            Number(match[1]);\r\n\r\n\r\n        \/*\r\n         * \u0e16\u0e49\u0e32\u0e1b\u0e35\u0e21\u0e32\u0e01\u0e01\u0e27\u0e48\u0e32 2400\r\n         * \u0e43\u0e2b\u0e49\u0e16\u0e37\u0e2d\u0e27\u0e48\u0e32\u0e40\u0e1b\u0e47\u0e19 \u0e1e.\u0e28.\r\n         *\/\r\n        if(year > 2400){\r\n\r\n            year -= 543;\r\n\r\n        }\r\n\r\n\r\n        const date =\r\n            new Date(\r\n                year,\r\n                Number(match[2]) - 1,\r\n                Number(match[3])\r\n            );\r\n\r\n\r\n        \/*\r\n         * \u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e27\u0e31\u0e19\u0e17\u0e35\u0e48\u0e2d\u0e35\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07\r\n         * \u0e1b\u0e49\u0e2d\u0e07\u0e01\u0e31\u0e19\u0e27\u0e31\u0e19\u0e17\u0e35\u0e48\u0e1c\u0e34\u0e14 \u0e40\u0e0a\u0e48\u0e19 20261340\r\n         *\/\r\n        if(\r\n            date.getFullYear() !== year ||\r\n            date.getMonth() !== Number(match[2]) - 1 ||\r\n            date.getDate() !== Number(match[3])\r\n        ){\r\n\r\n            return null;\r\n\r\n        }\r\n\r\n\r\n        return date;\r\n\r\n    }\r\n\r\n\r\n    \/* -----------------------------------------------------\r\n       Y-m-d\r\n\r\n       \u0e04.\u0e28. \u0e40\u0e0a\u0e48\u0e19 2026-09-24\r\n       \u0e1e.\u0e28. \u0e40\u0e0a\u0e48\u0e19 2569-09-24\r\n    ----------------------------------------------------- *\/\r\n\r\n    match =\r\n        raw.match(\r\n            \/^(\\d{4})-(\\d{1,2})-(\\d{1,2})$\/\r\n        );\r\n\r\n    if(match){\r\n\r\n        let year =\r\n            Number(match[1]);\r\n\r\n\r\n        if(year > 2400){\r\n\r\n            year -= 543;\r\n\r\n        }\r\n\r\n\r\n        const month =\r\n            Number(match[2]) - 1;\r\n\r\n\r\n        const day =\r\n            Number(match[3]);\r\n\r\n\r\n        const date =\r\n            new Date(\r\n                year,\r\n                month,\r\n                day\r\n            );\r\n\r\n\r\n        if(\r\n            date.getFullYear() !== year ||\r\n            date.getMonth() !== month ||\r\n            date.getDate() !== day\r\n        ){\r\n\r\n            return null;\r\n\r\n        }\r\n\r\n\r\n        return date;\r\n\r\n    }\r\n\r\n\r\n    \/* -----------------------------------------------------\r\n       d\/m\/Y \u0e2b\u0e23\u0e37\u0e2d d-m-Y\r\n\r\n       \u0e04.\u0e28. \u0e40\u0e0a\u0e48\u0e19 24\/09\/2026\r\n       \u0e1e.\u0e28. \u0e40\u0e0a\u0e48\u0e19 24\/09\/2569\r\n    ----------------------------------------------------- *\/\r\n\r\n    match =\r\n        raw.match(\r\n            \/^(\\d{1,2})[\\\/-](\\d{1,2})[\\\/-](\\d{4})$\/\r\n        );\r\n\r\n    if(match){\r\n\r\n        const day =\r\n            Number(match[1]);\r\n\r\n\r\n        const month =\r\n            Number(match[2]) - 1;\r\n\r\n\r\n        let year =\r\n            Number(match[3]);\r\n\r\n\r\n        if(year > 2400){\r\n\r\n            year -= 543;\r\n\r\n        }\r\n\r\n\r\n        const date =\r\n            new Date(\r\n                year,\r\n                month,\r\n                day\r\n            );\r\n\r\n\r\n        if(\r\n            date.getFullYear() !== year ||\r\n            date.getMonth() !== month ||\r\n            date.getDate() !== day\r\n        ){\r\n\r\n            return null;\r\n\r\n        }\r\n\r\n\r\n        return date;\r\n\r\n    }\r\n\r\n\r\n    \/* -----------------------------------------------------\r\n       Fallback\r\n    ----------------------------------------------------- *\/\r\n\r\n    const fallback =\r\n        new Date(raw);\r\n\r\n\r\n    if(\r\n        !isNaN(\r\n            fallback.getTime()\r\n        )\r\n    ){\r\n\r\n        let year =\r\n            fallback.getFullYear();\r\n\r\n\r\n        \/*\r\n         * Browser \u0e2d\u0e48\u0e32\u0e19\u0e1b\u0e35 \u0e1e.\u0e28.\r\n         *\/\r\n        if(year > 2400){\r\n\r\n            year -= 543;\r\n\r\n\r\n            return new Date(\r\n                year,\r\n                fallback.getMonth(),\r\n                fallback.getDate()\r\n            );\r\n\r\n        }\r\n\r\n\r\n        return fallback;\r\n\r\n    }\r\n\r\n\r\n    return null;\r\n\r\n}\r\n\r\n\r\nfunction getEventStartDate(post){\r\n\r\n    return parseEventStartDate(\r\n        getEventStartDateValue(post)\r\n    );\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   EVENT MONTH KEY\r\n========================================================= *\/\r\n\r\nfunction getEventMonthKey(post){\r\n\r\n    const date =\r\n        getEventStartDate(post);\r\n\r\n\r\n    if(!date){\r\n\r\n        return '';\r\n\r\n    }\r\n\r\n\r\n    const year =\r\n        date.getFullYear();\r\n\r\n\r\n    const month =\r\n        String(\r\n            date.getMonth() + 1\r\n        ).padStart(\r\n            2,\r\n            '0'\r\n        );\r\n\r\n\r\n    return (\r\n        year +\r\n        '-' +\r\n        month\r\n    );\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   CURRENT MONTH KEY\r\n========================================================= *\/\r\n\r\nfunction getCurrentMonthKey(){\r\n\r\n    \/*\r\n     * \u0e43\u0e0a\u0e49\u0e40\u0e27\u0e25\u0e32\u0e17\u0e49\u0e2d\u0e07\u0e16\u0e34\u0e48\u0e19\u0e02\u0e2d\u0e07 Browser\r\n     *\/\r\n    const now =\r\n        new Date();\r\n\r\n\r\n    const year =\r\n        now.getFullYear();\r\n\r\n\r\n    const month =\r\n        String(\r\n            now.getMonth() + 1\r\n        ).padStart(\r\n            2,\r\n            '0'\r\n        );\r\n\r\n\r\n    return (\r\n        year +\r\n        '-' +\r\n        month\r\n    );\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   FEATURED IMAGE\r\n========================================================= *\/\r\n\r\nfunction getFeaturedImage(post){\r\n\r\n    try{\r\n\r\n        if(\r\n            post._cmec_featured_image_url\r\n        ){\r\n\r\n            return post._cmec_featured_image_url;\r\n\r\n        }\r\n\r\n\r\n        const media =\r\n            post._embedded?.[\r\n                'wp:featuredmedia'\r\n            ]?.[0];\r\n\r\n\r\n        const embeddedImage =\r\n\r\n            media?.media_details\r\n                ?.sizes\r\n                ?.large\r\n                ?.source_url\r\n\r\n            ||\r\n\r\n            media?.media_details\r\n                ?.sizes\r\n                ?.medium_large\r\n                ?.source_url\r\n\r\n            ||\r\n\r\n            media?.media_details\r\n                ?.sizes\r\n                ?.full\r\n                ?.source_url\r\n\r\n            ||\r\n\r\n            media?.source_url\r\n\r\n            ||\r\n\r\n            '';\r\n\r\n\r\n        if(embeddedImage){\r\n\r\n            return embeddedImage;\r\n\r\n        }\r\n\r\n\r\n        if(\r\n            post.jetpack_featured_media_url\r\n        ){\r\n\r\n            return post.jetpack_featured_media_url;\r\n\r\n        }\r\n\r\n\r\n        const ogImage =\r\n            post.yoast_head_json\r\n                ?.og_image?.[0]?.url;\r\n\r\n\r\n        if(ogImage){\r\n\r\n            return ogImage;\r\n\r\n        }\r\n\r\n\r\n        return '';\r\n\r\n    }\r\n    catch(error){\r\n\r\n        return '';\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   FEATURED IMAGE FALLBACK\r\n========================================================= *\/\r\n\r\nfunction getFirstImageFromHTML(html){\r\n\r\n    if(!html){\r\n\r\n        return '';\r\n\r\n    }\r\n\r\n\r\n    try{\r\n\r\n        const doc =\r\n            new DOMParser().parseFromString(\r\n                html,\r\n                'text\/html'\r\n            );\r\n\r\n\r\n        const img =\r\n            doc.querySelector(\r\n                'img[src]'\r\n            );\r\n\r\n\r\n        return img\r\n            ? img.getAttribute('src') || ''\r\n            : '';\r\n\r\n    }\r\n    catch(error){\r\n\r\n        return '';\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\nasync function fetchImageFromPostPage(post){\r\n\r\n    if(!post?.link){\r\n\r\n        return '';\r\n\r\n    }\r\n\r\n\r\n    try{\r\n\r\n        const separator =\r\n            post.link.includes('?')\r\n                ? '&'\r\n                : '?';\r\n\r\n\r\n        const response =\r\n            await fetch(\r\n                post.link +\r\n                separator +\r\n                '_cmec_img=' +\r\n                Date.now(),\r\n                {\r\n                    credentials:'same-origin',\r\n                    cache:'no-store'\r\n                }\r\n            );\r\n\r\n\r\n        if(!response.ok){\r\n\r\n            return '';\r\n\r\n        }\r\n\r\n\r\n        const html =\r\n            await response.text();\r\n\r\n\r\n        const doc =\r\n            new DOMParser().parseFromString(\r\n                html,\r\n                'text\/html'\r\n            );\r\n\r\n\r\n        const selectors = [\r\n\r\n            'meta[property=\"og:image\"]',\r\n            'meta[property=\"og:image:secure_url\"]',\r\n            'meta[name=\"twitter:image\"]',\r\n            'meta[name=\"twitter:image:src\"]',\r\n            'link[rel=\"image_src\"]'\r\n\r\n        ];\r\n\r\n\r\n        for(\r\n            const selector\r\n            of selectors\r\n        ){\r\n\r\n            const element =\r\n                doc.querySelector(\r\n                    selector\r\n                );\r\n\r\n\r\n            if(element){\r\n\r\n                const url =\r\n                    element.getAttribute(\r\n                        'content'\r\n                    )\r\n                    ||\r\n                    element.getAttribute(\r\n                        'href'\r\n                    )\r\n                    ||\r\n                    '';\r\n\r\n\r\n                if(url){\r\n\r\n                    return url;\r\n\r\n                }\r\n\r\n            }\r\n\r\n        }\r\n\r\n\r\n        const mainImage =\r\n            doc.querySelector(\r\n                'article img[src], main img[src], .entry-content img[src], .elementor img[src]'\r\n            );\r\n\r\n\r\n        return mainImage\r\n            ? mainImage.getAttribute('src') || ''\r\n            : '';\r\n\r\n    }\r\n    catch(error){\r\n\r\n        console.warn(\r\n            'CMEC Post Page Image Error:',\r\n            error\r\n        );\r\n\r\n\r\n        return '';\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\nasync function fetchFeaturedImageFallback(post){\r\n\r\n    const mediaId =\r\n        parseInt(\r\n            post.featured_media || 0,\r\n            10\r\n        );\r\n\r\n\r\n    if(mediaId){\r\n\r\n        try{\r\n\r\n            const url =\r\n                `${SITE_URL}\/wp-json\/wp\/v2\/media\/${mediaId}` +\r\n                `?_=${Date.now()}`;\r\n\r\n\r\n            const response =\r\n                await fetch(\r\n                    url,\r\n                    {\r\n                        credentials:'same-origin',\r\n                        cache:'no-store'\r\n                    }\r\n                );\r\n\r\n\r\n            if(response.ok){\r\n\r\n                const media =\r\n                    await response.json();\r\n\r\n\r\n                const mediaImage = (\r\n\r\n                    media.media_details\r\n                        ?.sizes\r\n                        ?.large\r\n                        ?.source_url\r\n\r\n                    ||\r\n\r\n                    media.media_details\r\n                        ?.sizes\r\n                        ?.medium_large\r\n                        ?.source_url\r\n\r\n                    ||\r\n\r\n                    media.media_details\r\n                        ?.sizes\r\n                        ?.full\r\n                        ?.source_url\r\n\r\n                    ||\r\n\r\n                    media.source_url\r\n\r\n                    ||\r\n\r\n                    ''\r\n\r\n                );\r\n\r\n\r\n                if(mediaImage){\r\n\r\n                    return mediaImage;\r\n\r\n                }\r\n\r\n            }\r\n\r\n        }\r\n        catch(error){\r\n\r\n            console.warn(\r\n                'CMEC Media REST Image Error:',\r\n                error\r\n            );\r\n\r\n        }\r\n\r\n    }\r\n\r\n\r\n    const contentImage =\r\n        getFirstImageFromHTML(\r\n            post.content?.rendered || ''\r\n        );\r\n\r\n\r\n    if(contentImage){\r\n\r\n        return contentImage;\r\n\r\n    }\r\n\r\n\r\n    return await fetchImageFromPostPage(\r\n        post\r\n    );\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   DECODE \/ ESCAPE\r\n========================================================= *\/\r\n\r\nfunction decodeHTML(html){\r\n\r\n    const textarea =\r\n        document.createElement(\r\n            'textarea'\r\n        );\r\n\r\n    textarea.innerHTML =\r\n        html;\r\n\r\n    return textarea.value;\r\n\r\n}\r\n\r\n\r\nfunction escapeHTML(text){\r\n\r\n    return String(text)\r\n\r\n        .replace(\r\n            \/&\/g,\r\n            '&amp;'\r\n        )\r\n\r\n        .replace(\r\n            \/<\/g,\r\n            '&lt;'\r\n        )\r\n\r\n        .replace(\r\n            \/>\/g,\r\n            '&gt;'\r\n        )\r\n\r\n        .replace(\r\n            \/\"\/g,\r\n            '&quot;'\r\n        )\r\n\r\n        .replace(\r\n            \/'\/g,\r\n            '&#039;'\r\n        );\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   FETCH EVENTS\r\n========================================================= *\/\r\n\r\nasync function fetchAllPosts(\r\n    categoryId\r\n){\r\n\r\n    let page =\r\n        1;\r\n\r\n    let totalPages =\r\n        1;\r\n\r\n    let result =\r\n        [];\r\n\r\n\r\n    do{\r\n\r\n        const url =\r\n\r\n            `${SITE_URL}\/wp-json\/wp\/v2\/posts`\r\n\r\n            +\r\n\r\n            `?categories=${categoryId}`\r\n\r\n            +\r\n\r\n            `&status=publish`\r\n\r\n            +\r\n\r\n            `&per_page=${PER_PAGE}`\r\n\r\n            +\r\n\r\n            `&page=${page}`\r\n\r\n            +\r\n\r\n            `&_embed=wp:featuredmedia`\r\n\r\n            +\r\n\r\n            `&orderby=date`\r\n\r\n            +\r\n\r\n            `&order=desc`\r\n\r\n            +\r\n\r\n            `&_=${Date.now()}`;\r\n\r\n\r\n        const response =\r\n            await fetch(\r\n                url,\r\n                {\r\n                    credentials:\r\n                        'same-origin',\r\n\r\n                    cache:\r\n                        'no-store'\r\n                }\r\n            );\r\n\r\n\r\n        if(!response.ok){\r\n\r\n            throw new Error(\r\n                'REST API Error ' +\r\n                response.status\r\n            );\r\n\r\n        }\r\n\r\n\r\n        const posts =\r\n            await response.json();\r\n\r\n\r\n        const hydratedPosts =\r\n            await Promise.all(\r\n\r\n                posts.map(\r\n\r\n                    async post => {\r\n\r\n                        if(\r\n                            !getFeaturedImage(post)\r\n                        ){\r\n\r\n                            post._cmec_featured_image_url =\r\n                                await fetchFeaturedImageFallback(\r\n                                    post\r\n                                );\r\n\r\n                        }\r\n\r\n\r\n                        return post;\r\n\r\n                    }\r\n\r\n                )\r\n\r\n            );\r\n\r\n\r\n        result =\r\n            result.concat(\r\n                hydratedPosts\r\n            );\r\n\r\n\r\n        totalPages =\r\n            parseInt(\r\n\r\n                response.headers.get(\r\n                    'X-WP-TotalPages'\r\n                )\r\n\r\n                ||\r\n\r\n                '1'\r\n\r\n            );\r\n\r\n\r\n        page++;\r\n\r\n\r\n    }\r\n    while(\r\n        page <= totalPages\r\n    );\r\n\r\n\r\n    return result;\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   CREATE CUSTOM MONTH OPTION\r\n========================================================= *\/\r\n\r\nfunction createMonthOption(\r\n    value,\r\n    label,\r\n    active = false\r\n){\r\n\r\n    const option =\r\n        document.createElement(\r\n            'button'\r\n        );\r\n\r\n\r\n    option.type =\r\n        'button';\r\n\r\n\r\n    option.className =\r\n        'cmec-select-option';\r\n\r\n\r\n    option.dataset.value =\r\n        value;\r\n\r\n\r\n    option.textContent =\r\n        label;\r\n\r\n\r\n    if(active){\r\n\r\n        option.classList.add(\r\n            'active'\r\n        );\r\n\r\n    }\r\n\r\n\r\n    option.addEventListener(\r\n        'click',\r\n        function(){\r\n\r\n\r\n            selectedText.textContent =\r\n                label;\r\n\r\n\r\n            selectMenu\r\n                .querySelectorAll(\r\n                    '.cmec-select-option'\r\n                )\r\n                .forEach(\r\n                    item => {\r\n\r\n                        item.classList.remove(\r\n                            'active'\r\n                        );\r\n\r\n                    }\r\n                );\r\n\r\n\r\n            this.classList.add(\r\n                'active'\r\n            );\r\n\r\n\r\n            customSelect.classList.remove(\r\n                'open'\r\n            );\r\n\r\n\r\n            renderPosts(\r\n                value\r\n            );\r\n\r\n        }\r\n    );\r\n\r\n\r\n    selectMenu.appendChild(\r\n        option\r\n    );\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   BUILD MONTH FILTER\r\n========================================================= *\/\r\n\r\nfunction buildMonthFilter(posts){\r\n\r\n    const months =\r\n        new Map();\r\n\r\n\r\n    posts.forEach(\r\n        post => {\r\n\r\n\r\n            const date =\r\n                getEventStartDate(\r\n                    post\r\n                );\r\n\r\n\r\n            \/*\r\n             * \u0e16\u0e49\u0e32\u0e44\u0e21\u0e48\u0e21\u0e35 event_start_date\r\n             * \u0e08\u0e30\u0e44\u0e21\u0e48\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e40\u0e14\u0e37\u0e2d\u0e19\u0e43\u0e19 Dropdown\r\n             *\/\r\n            if(\r\n                !date ||\r\n                isNaN(\r\n                    date.getTime()\r\n                )\r\n            ){\r\n\r\n                return;\r\n\r\n            }\r\n\r\n\r\n            const key =\r\n                getEventMonthKey(\r\n                    post\r\n                );\r\n\r\n\r\n            const label =\r\n\r\n                thaiMonths[\r\n                    date.getMonth()\r\n                ]\r\n\r\n                +\r\n\r\n                ' '\r\n\r\n                +\r\n\r\n                (\r\n                    date.getFullYear()\r\n                    +\r\n                    543\r\n                );\r\n\r\n\r\n            if(\r\n                !months.has(\r\n                    key\r\n                )\r\n            ){\r\n\r\n                months.set(\r\n\r\n                    key,\r\n\r\n                    {\r\n\r\n                        key:key,\r\n\r\n                        label:label,\r\n\r\n                        timestamp:\r\n                            new Date(\r\n\r\n                                date.getFullYear(),\r\n\r\n                                date.getMonth(),\r\n\r\n                                1\r\n\r\n                            ).getTime()\r\n\r\n                    }\r\n\r\n                );\r\n\r\n            }\r\n\r\n        }\r\n    );\r\n\r\n\r\n    const sortedMonths =\r\n\r\n        Array.from(\r\n            months.values()\r\n        )\r\n\r\n        .sort(\r\n            (a,b) =>\r\n                b.timestamp\r\n                -\r\n                a.timestamp\r\n        );\r\n\r\n\r\n    selectMenu.innerHTML =\r\n        '';\r\n\r\n\r\n    const currentMonthKey =\r\n        getCurrentMonthKey();\r\n\r\n\r\n    \/*\r\n     * \u0e17\u0e38\u0e01\u0e40\u0e14\u0e37\u0e2d\u0e19\r\n     *\/\r\n    createMonthOption(\r\n        'all',\r\n        '\u0e07\u0e32\u0e19\u0e2d\u0e34\u0e40\u0e27\u0e19\u0e15\u0e4c\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14',\r\n        false\r\n    );\r\n\r\n\r\n    \/*\r\n     * \u0e40\u0e14\u0e37\u0e2d\u0e19\u0e15\u0e48\u0e32\u0e07 \u0e46\r\n     *\/\r\n    sortedMonths.forEach(\r\n        item => {\r\n\r\n            createMonthOption(\r\n                item.key,\r\n                item.label,\r\n                item.key === currentMonthKey\r\n            );\r\n\r\n        }\r\n    );\r\n\r\n\r\n    \/*\r\n     * \u0e2b\u0e32\u0e40\u0e14\u0e37\u0e2d\u0e19\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\r\n     *\/\r\n    const currentMonth =\r\n        sortedMonths.find(\r\n            item =>\r\n                item.key ===\r\n                currentMonthKey\r\n        );\r\n\r\n\r\n    \/*\r\n     * \u0e16\u0e49\u0e32\u0e21\u0e35 Event \u0e43\u0e19\u0e40\u0e14\u0e37\u0e2d\u0e19\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\r\n     * \u0e43\u0e2b\u0e49 Default \u0e40\u0e1b\u0e47\u0e19\u0e40\u0e14\u0e37\u0e2d\u0e19\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\r\n     *\r\n     * \u0e16\u0e49\u0e32\u0e44\u0e21\u0e48\u0e21\u0e35 Event \u0e43\u0e19\u0e40\u0e14\u0e37\u0e2d\u0e19\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\r\n     * \u0e43\u0e2b\u0e49 Default \u0e40\u0e1b\u0e47\u0e19 \"\u0e17\u0e38\u0e01\u0e40\u0e14\u0e37\u0e2d\u0e19\"\r\n     *\/\r\n    if(currentMonth){\r\n\r\n        selectedText.textContent =\r\n            currentMonth.label;\r\n\r\n    }\r\n    else{\r\n\r\n        selectedText.textContent =\r\n            '\u0e17\u0e38\u0e01\u0e40\u0e14\u0e37\u0e2d\u0e19';\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   CALENDAR ICON\r\n========================================================= *\/\r\n\r\nfunction calendarIcon(){\r\n\r\n    return `\r\n        <svg\r\n            class=\"cmec-calendar-icon\"\r\n            viewBox=\"0 0 24 24\"\r\n            aria-hidden=\"true\">\r\n\r\n            <path d=\"\r\n            M19 4h-1V2h-2v2H8V2H6v2H5\r\n            c-1.1 0-2 .9-2 2v14\r\n            c0 1.1.9 2 2 2h14\r\n            c1.1 0 2-.9 2-2V6\r\n            c0-1.1-.9-2-2-2zm0 16H5V9h14v11z\r\n            M7 11h5v5H7z\">\r\n            <\/path>\r\n\r\n        <\/svg>\r\n    `;\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   CREATE EVENT CARD\r\n========================================================= *\/\r\n\r\nfunction createCard(post){\r\n\r\n    const image =\r\n        getFeaturedImage(\r\n            post\r\n        );\r\n\r\n\r\n    const title =\r\n        decodeHTML(\r\n\r\n            post.title\r\n                ?.rendered\r\n\r\n            ||\r\n\r\n            ''\r\n\r\n        );\r\n\r\n\r\n    const eventDateText =\r\n        getEventDateText(\r\n            post\r\n        );\r\n\r\n\r\n    const month =\r\n        getEventMonthKey(\r\n            post\r\n        );\r\n\r\n\r\n    let imageHTML =\r\n        '';\r\n\r\n\r\n    if(image){\r\n\r\n        imageHTML = `\r\n\r\n            <img decoding=\"async\"\r\n                src=\"${escapeHTML(image)}\"\r\n                alt=\"${escapeHTML(title)}\"\r\n                loading=\"lazy\"\r\n            >\r\n\r\n        `;\r\n\r\n    }\r\n    else{\r\n\r\n        imageHTML = `\r\n\r\n            <div style=\"\r\n                width:100%;\r\n                height:100%;\r\n                display:flex;\r\n                align-items:center;\r\n                justify-content:center;\r\n                background:#f3f3f3;\r\n                color:#aaa;\r\n                font-size:14px;\r\n            \">\r\n\r\n                \u0e44\u0e21\u0e48\u0e21\u0e35\u0e23\u0e39\u0e1b\u0e20\u0e32\u0e1e\r\n\r\n            <\/div>\r\n\r\n        `;\r\n\r\n    }\r\n\r\n\r\n    let dateHTML =\r\n        '';\r\n\r\n\r\n    if(eventDateText){\r\n\r\n        dateHTML = `\r\n\r\n            <div class=\"cmec-event-date\">\r\n\r\n                ${calendarIcon()}\r\n\r\n                <span>\r\n                    ${escapeHTML(\r\n                        eventDateText\r\n                    )}\r\n                <\/span>\r\n\r\n            <\/div>\r\n\r\n        `;\r\n\r\n    }\r\n\r\n\r\n    return `\r\n\r\n        <article\r\n            class=\"cmec-event-card\"\r\n            data-month=\"${month}\"\r\n        >\r\n\r\n            <div class=\"cmec-event-thumb\">\r\n\r\n                <a\r\n                    href=\"${escapeHTML(post.link)}\"\r\n                    aria-label=\"${escapeHTML(title)}\"\r\n                >\r\n\r\n                    ${imageHTML}\r\n\r\n                <\/a>\r\n\r\n            <\/div>\r\n\r\n\r\n            ${dateHTML}\r\n\r\n\r\n            <h3 class=\"cmec-event-title\">\r\n\r\n                <a href=\"${escapeHTML(post.link)}\">\r\n\r\n                    ${escapeHTML(title)}\r\n\r\n                <\/a>\r\n\r\n            <\/h3>\r\n\r\n        <\/article>\r\n\r\n    `;\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   RENDER POSTS\r\n========================================================= *\/\r\n\r\nfunction renderPosts(\r\n    month = 'all'\r\n){\r\n\r\n    let posts =\r\n        allPosts;\r\n\r\n\r\n    \/*\r\n     * \u0e01\u0e23\u0e2d\u0e07\u0e15\u0e32\u0e21\u0e40\u0e14\u0e37\u0e2d\u0e19\r\n     *\/\r\n    if(\r\n        month !== 'all'\r\n    ){\r\n\r\n        posts =\r\n            allPosts.filter(\r\n\r\n                post =>\r\n\r\n                    getEventMonthKey(\r\n                        post\r\n                    )\r\n\r\n                    ===\r\n\r\n                    month\r\n\r\n            );\r\n\r\n    }\r\n\r\n\r\n    \/*\r\n     * \u0e40\u0e23\u0e35\u0e22\u0e07 Event\r\n     *\r\n     * \u0e07\u0e32\u0e19\u0e2d\u0e35\u0e40\u0e27\u0e19\u0e15\u0e4c\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14:\r\n     * \u0e25\u0e48\u0e32\u0e2a\u0e38\u0e14 \u2192 \u0e40\u0e01\u0e48\u0e32\u0e2a\u0e38\u0e14\r\n     *\r\n     * \u0e40\u0e25\u0e37\u0e2d\u0e01\u0e40\u0e14\u0e37\u0e2d\u0e19:\r\n     * \u0e27\u0e31\u0e19\u0e15\u0e49\u0e19\u0e40\u0e14\u0e37\u0e2d\u0e19 \u2192 \u0e27\u0e31\u0e19\u0e17\u0e49\u0e32\u0e22\u0e40\u0e14\u0e37\u0e2d\u0e19\r\n     *\/\r\n    posts =\r\n        [...posts].sort(\r\n\r\n            (a,b) => {\r\n\r\n                const dateA =\r\n                    getEventStartDate(a);\r\n\r\n                const dateB =\r\n                    getEventStartDate(b);\r\n\r\n\r\n                \/*\r\n                 * \u0e16\u0e49\u0e32\u0e44\u0e21\u0e48\u0e21\u0e35\u0e27\u0e31\u0e19\u0e17\u0e35\u0e48\r\n                 * \u0e43\u0e2b\u0e49\u0e44\u0e1b\u0e2d\u0e22\u0e39\u0e48\u0e17\u0e49\u0e32\u0e22\u0e2a\u0e38\u0e14\r\n                 *\/\r\n                if(\r\n                    !dateA &&\r\n                    !dateB\r\n                ){\r\n\r\n                    return 0;\r\n\r\n                }\r\n\r\n\r\n                if(!dateA){\r\n\r\n                    return 1;\r\n\r\n                }\r\n\r\n\r\n                if(!dateB){\r\n\r\n                    return -1;\r\n\r\n                }\r\n\r\n\r\n                \/*\r\n                 * \u0e07\u0e32\u0e19\u0e2d\u0e35\u0e40\u0e27\u0e19\u0e15\u0e4c\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\r\n                 * \u0e25\u0e48\u0e32\u0e2a\u0e38\u0e14 \u2192 \u0e40\u0e01\u0e48\u0e32\u0e2a\u0e38\u0e14\r\n                 *\/\r\n                if(\r\n                    month === 'all'\r\n                ){\r\n\r\n                    return (\r\n                        dateB.getTime()\r\n                        -\r\n                        dateA.getTime()\r\n                    );\r\n\r\n                }\r\n\r\n\r\n                \/*\r\n                 * \u0e40\u0e25\u0e37\u0e2d\u0e01\u0e40\u0e14\u0e37\u0e2d\u0e19\r\n                 * \u0e15\u0e49\u0e19\u0e40\u0e14\u0e37\u0e2d\u0e19 \u2192 \u0e17\u0e49\u0e32\u0e22\u0e40\u0e14\u0e37\u0e2d\u0e19\r\n                 *\/\r\n                return (\r\n                    dateA.getTime()\r\n                    -\r\n                    dateB.getTime()\r\n                );\r\n\r\n            }\r\n\r\n        );\r\n\r\n\r\n    \/*\r\n     * \u0e44\u0e21\u0e48\u0e1e\u0e1a Event\r\n     *\/\r\n    if(\r\n        !posts.length\r\n    ){\r\n\r\n        grid.innerHTML = `\r\n\r\n            <div class=\"cmec-empty\">\r\n\r\n                \u0e44\u0e21\u0e48\u0e1e\u0e1a\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e43\u0e19\u0e40\u0e14\u0e37\u0e2d\u0e19\u0e17\u0e35\u0e48\u0e40\u0e25\u0e37\u0e2d\u0e01\r\n\r\n            <\/div>\r\n\r\n        `;\r\n\r\n        return;\r\n\r\n    }\r\n\r\n\r\n    \/*\r\n     * \u0e41\u0e2a\u0e14\u0e07 Event\r\n     *\/\r\n    grid.innerHTML =\r\n\r\n        posts\r\n\r\n        .map(\r\n            createCard\r\n        )\r\n\r\n        .join('');\r\n\r\n}\r\n\r\n\/* =========================================================\r\n   INIT\r\n========================================================= *\/\r\n\r\nasync function init(){\r\n\r\n    try{\r\n\r\n\r\n        const categoryId =\r\n            await getCategoryId();\r\n\r\n\r\n        allPosts =\r\n            await fetchAllPosts(\r\n                categoryId\r\n            );\r\n\r\n\r\n        loading.style.display =\r\n            'none';\r\n\r\n\r\n        grid.style.display =\r\n            'grid';\r\n\r\n\r\n        if(\r\n            !allPosts.length\r\n        ){\r\n\r\n            grid.innerHTML = `\r\n\r\n                <div class=\"cmec-empty\">\r\n\r\n                    \u0e44\u0e21\u0e48\u0e1e\u0e1a\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\r\n\r\n                <\/div>\r\n\r\n            `;\r\n\r\n            selectedText.textContent =\r\n                '\u0e17\u0e38\u0e01\u0e40\u0e14\u0e37\u0e2d\u0e19';\r\n\r\n            return;\r\n\r\n        }\r\n\r\n\r\n        buildMonthFilter(\r\n            allPosts\r\n        );\r\n\r\n\r\n        \/*\r\n         * Default = \u0e40\u0e14\u0e37\u0e2d\u0e19\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\r\n         * \u0e16\u0e49\u0e32\u0e21\u0e35 Event \u0e43\u0e19\u0e40\u0e14\u0e37\u0e2d\u0e19\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\r\n         *\r\n         * \u0e16\u0e49\u0e32\u0e44\u0e21\u0e48\u0e21\u0e35 Event \u0e43\u0e19\u0e40\u0e14\u0e37\u0e2d\u0e19\u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\r\n         * = \u0e17\u0e38\u0e01\u0e40\u0e14\u0e37\u0e2d\u0e19\r\n         *\/\r\n        const currentMonthKey =\r\n            getCurrentMonthKey();\r\n\r\n\r\n        const hasCurrentMonthEvents =\r\n            allPosts.some(\r\n\r\n                post =>\r\n                    getEventMonthKey(post)\r\n                    ===\r\n                    currentMonthKey\r\n\r\n            );\r\n\r\n\r\n        if(hasCurrentMonthEvents){\r\n\r\n            renderPosts(\r\n                currentMonthKey\r\n            );\r\n\r\n        }\r\n        else{\r\n\r\n            renderPosts(\r\n                'all'\r\n            );\r\n\r\n        }\r\n\r\n\r\n    }\r\n    catch(error){\r\n\r\n\r\n        console.error(\r\n            'CMEC Events Error:',\r\n            error\r\n        );\r\n\r\n\r\n        loading.style.display =\r\n            'none';\r\n\r\n\r\n        grid.style.display =\r\n            'block';\r\n\r\n\r\n        selectedText.textContent =\r\n            '\u0e17\u0e38\u0e01\u0e40\u0e14\u0e37\u0e2d\u0e19';\r\n\r\n\r\n        grid.innerHTML = `\r\n\r\n            <div class=\"cmec-error\">\r\n\r\n                \u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e42\u0e2b\u0e25\u0e14\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e44\u0e14\u0e49\r\n\r\n                <br><br>\r\n\r\n                ${escapeHTML(\r\n                    error.message\r\n                )}\r\n\r\n            <\/div>\r\n\r\n        `;\r\n\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   RUN\r\n========================================================= *\/\r\n\r\ninit();\r\n\r\n\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>\u0e40\u0e25\u0e37\u0e2d\u0e01\u0e40\u0e14\u0e37\u0e2d\u0e19\u0e02\u0e2d\u0e07\u0e07\u0e32\u0e19\u0e2d\u0e34\u0e40\u0e27\u0e19\u0e15\u0e4c \u0e01\u0e33\u0e25\u0e31\u0e07\u0e42\u0e2b\u0e25\u0e14&#8230; \u0e01\u0e33\u0e25\u0e31\u0e07\u0e42\u0e2b\u0e25\u0e14\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21&#8230;<\/p>","protected":false},"author":1,"featured_media":1112,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-18","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.chiangmaiconvention.com\/en\/wp-json\/wp\/v2\/pages\/18","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.chiangmaiconvention.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.chiangmaiconvention.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.chiangmaiconvention.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.chiangmaiconvention.com\/en\/wp-json\/wp\/v2\/comments?post=18"}],"version-history":[{"count":55,"href":"https:\/\/www.chiangmaiconvention.com\/en\/wp-json\/wp\/v2\/pages\/18\/revisions"}],"predecessor-version":[{"id":1426,"href":"https:\/\/www.chiangmaiconvention.com\/en\/wp-json\/wp\/v2\/pages\/18\/revisions\/1426"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.chiangmaiconvention.com\/en\/wp-json\/wp\/v2\/media\/1112"}],"wp:attachment":[{"href":"https:\/\/www.chiangmaiconvention.com\/en\/wp-json\/wp\/v2\/media?parent=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}