 
{"id":14230,"date":"2026-09-01T19:29:53","date_gmt":"2026-09-01T19:29:53","guid":{"rendered":"https:\/\/steentijdvondsten.nl\/post\/?page_id=14230"},"modified":"2026-09-24T01:13:49","modified_gmt":"2026-09-24T01:13:49","slug":"archeotheek","status":"publish","type":"page","link":"https:\/\/steentijdvondsten.nl\/post\/index.php\/archeotheek\/","title":{"rendered":"Bibliotheek"},"content":{"rendered":"\n<div class=\"template-frame\">\n  <div class=\"afbeelding-kader\">\n    <div class=\"tekst-kader\">\n\n      <h1><\/h1>\n\n      <h2 id=\"tijdschriften\">\n        <a href=\"#\" class=\"nummer-icoon nummer-1\">1<\/a>\n      <\/h2>\n\n    <\/div>\n  <\/div>\n<\/div>\n\n<style>\n\/* Template container *\/\n.template-frame {\n  width: 100%;\n  max-width: 1200px;\n  margin: 0 auto;\n}\n\n\/* Afbeelding container *\/\n.afbeelding-kader {\n  width: 100%;\n  aspect-ratio: 1200\/200;\n  background-image: url('https:\/\/steentijdvondsten.nl\/post\/wp-content\/uploads\/2026\/04\/cropped-sierlijn.png');\n  background-size: contain;\n  background-repeat: no-repeat;\n  background-position: center;\n\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\n\/* Tekstkader *\/\n.tekst-kader {\n  display: inline-block;\n  background-color: white;\n  padding: 2mm 5mm;\n  text-align: center;\n  box-sizing: border-box;\n}\n\n\/* Nummer-rondje *\/\n.nummer-icoon {\n  width: 32px;\n  height: 32px;\n  margin: 0;\n  border-radius: 50%;\n\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n\n  box-sizing: border-box;\n\n  font-family: Arial, Helvetica, sans-serif;\n  font-size: 18px;\n  font-weight: bold;\n  line-height: 1;\n\n  text-decoration: none;\n}\n\n\/* Zwart rondje met witte 1 *\/\n.nummer-icoon.nummer-1 {\n  background: #000 !important;\n  color: #fff !important;\n}\n\n\/* Hover *\/\n.nummer-icoon:hover {\n  transform: scale(1.08);\n}\n\n\/* H2 standaardmarges verwijderen *\/\n#tijdschriften {\n  margin: 0;\n  padding: 0;\n  line-height: 1;\n}\n<\/style>\n\n\n\n    <div\n        id=\"stt-library\"\n        class=\"stt-library\"\n    >\n\n\n        <style>\n\n            .stt-library {\n\n                --stt-bg: #f5f1e8;\n                --stt-card: #ffffff;\n                --stt-text: #29251f;\n                --stt-muted: #746d63;\n                --stt-border: #ded6c8;\n                --stt-accent: #a26b25;\n\n                max-width: 1200px;\n\n                margin: 40px auto;\n\n                padding: 20px;\n\n                color: var(--stt-text);\n\n                font-family: inherit;\n            }\n\n\n            .stt-library * {\n                box-sizing: border-box;\n            }\n\n            \/* Alle teksten binnen de bibliotheek links uitlijnen.\n             * Door de .stt-library-scope blijft de rest van de website ongemoeid.\n             *\/\n            .stt-library,\n            .stt-library h1,\n            .stt-library h2,\n            .stt-library h3,\n            .stt-library h4,\n            .stt-library h5,\n            .stt-library h6,\n            .stt-library p,\n            .stt-library span,\n            .stt-library div,\n            .stt-library a,\n            .stt-library button,\n            .stt-library input,\n            .stt-library select,\n            .stt-library option {\n                text-align: left !important;\n            }\n\n\n            .stt-header {\n                margin-bottom: 25px;\n            }\n\n\n            .stt-header h2 {\n\n                margin: 0 0 8px;\n\n                font-size: 32px;\n\n                line-height: 1.15;\n            }\n\n\n            .stt-header p {\n\n                margin: 0;\n\n                color: var(--stt-muted);\n            }\n\n\n            .stt-controls {\n\n                display: grid;\n\n                grid-template-columns:\n                    1fr 220px;\n\n                gap: 12px;\n\n                margin-bottom: 20px;\n            }\n\n\n            .stt-controls input,\n            .stt-controls select {\n\n                width: 100%;\n\n                padding: 12px 14px;\n\n                border:\n                    1px solid\n                    var(--stt-border);\n\n                border-radius: 8px;\n\n                background: #fff;\n\n                font-size: 15px;\n            }\n\n\n            .stt-count {\n\n                margin:\n                    10px 0 20px;\n\n                color:\n                    var(--stt-muted);\n\n                font-size: 14px;\n            }\n\n\n            .stt-grid {\n\n                display: grid;\n\n                grid-template-columns:\n                    repeat(\n                        4,\n                        minmax(0, 1fr)\n                    );\n\n                gap: 20px;\n            }\n\n\n            .stt-card {\n\n                position: relative;\n\n                border:\n                    1px solid\n                    var(--stt-border);\n\n                border-radius: 12px;\n\n                overflow: hidden;\n\n                background:\n                    var(--stt-card);\n\n                cursor: pointer;\n\n                transition:\n                    transform .18s ease,\n                    box-shadow .18s ease;\n            }\n\n\n            .stt-card:hover {\n\n                transform:\n                    translateY(-3px);\n\n                box-shadow:\n                    0 8px 25px\n                    rgba(0,0,0,.10);\n            }\n\n\n            .stt-card-cover {\n\n                min-height: 180px;\n\n                padding: 22px;\n\n                display: flex;\n\n                flex-direction: column;\n\n                justify-content:\n                    space-between;\n            }\n\n\n            .stt-cover-amber {\n                background: #d5a45c;\n            }\n\n\n            .stt-cover-stone {\n                background: #aaa59a;\n            }\n\n\n            .stt-cover-yellow {\n                background: #dfc95f;\n            }\n\n\n            .stt-cover-neutral {\n                background: #d9d5cc;\n            }\n\n\n            .stt-card-number {\n\n                font-size: 13px;\n\n                font-weight: 700;\n\n                opacity: .75;\n            }\n\n\n            .stt-card-title {\n\n                font-size: 22px;\n\n                font-weight: 800;\n\n                line-height: 1.12;\n\n                max-width: 90%;\n            }\n\n\n            .stt-card-body {\n\n                padding: 16px;\n            }\n\n\n            .stt-card-body h3 {\n\n                margin:\n                    0 0 7px;\n\n                font-size: 18px;\n            }\n\n\n            .stt-card-meta {\n\n                display: flex;\n\n                flex-wrap: wrap;\n\n                gap: 6px;\n\n                font-size: 13px;\n\n                color:\n                    var(--stt-muted);\n            }\n\n\n            .stt-card-meta span {\n\n                padding:\n                    4px 7px;\n\n                border-radius: 5px;\n\n                background:\n                    #f4f1eb;\n            }\n\n\n            \/* =====================================\n             * PDF LEZER\n             * ===================================== *\/\n\n            .stt-reader {\n\n                display: none;\n\n                margin-bottom: 30px;\n\n                border:\n                    1px solid\n                    var(--stt-border);\n\n                border-radius: 12px;\n\n                overflow: hidden;\n\n                background: #292621;\n            }\n\n\n            .stt-reader-toolbar {\n\n                display: flex;\n\n                align-items: center;\n\n                justify-content:\n                    space-between;\n\n                gap: 10px;\n\n                padding: 12px 15px;\n\n                background: #302c27;\n\n                color: #fff;\n            }\n\n\n            .stt-reader-title {\n\n                font-weight: 700;\n\n                overflow: hidden;\n\n                text-overflow: ellipsis;\n\n                white-space: nowrap;\n            }\n\n\n            .stt-reader-actions {\n\n                display: flex;\n\n                align-items: center;\n\n                gap: 7px;\n\n                flex-shrink: 0;\n            }\n\n\n            .stt-reader-actions button,\n            .stt-reader-actions a {\n\n                display: inline-block;\n\n                border: 0;\n\n                border-radius: 6px;\n\n                padding:\n                    8px 11px;\n\n                background: #fff;\n\n                color: #29251f;\n\n                text-decoration: none;\n\n                cursor: pointer;\n\n                font-size: 13px;\n            }\n\n\n            .stt-reader-navigation {\n\n                display: flex;\n\n                justify-content:\n                    center;\n\n                align-items: center;\n\n                gap: 12px;\n\n                padding:\n                    10px;\n\n                background: #211f1c;\n\n                color: #fff;\n            }\n\n\n            .stt-reader-navigation button {\n\n                border: 0;\n\n                border-radius: 6px;\n\n                padding:\n                    8px 14px;\n\n                background: #fff;\n\n                color: #29251f;\n\n                cursor: pointer;\n\n                font-size: 13px;\n            }\n\n\n            .stt-reader-navigation button:disabled {\n\n                opacity: .4;\n\n                cursor: default;\n            }\n\n\n            .stt-page-info {\n\n                min-width: 100px;\n\n                text-align: center;\n\n                font-size: 13px;\n            }\n\n\n            .stt-reader-pages {\n\n                min-height: 600px;\n\n                display: flex;\n\n                align-items:\n                    flex-start;\n\n                justify-content:\n                    center;\n\n                overflow: auto;\n\n                padding: 20px;\n\n                background: #4a4640;\n            }\n\n\n            .stt-reader-pages canvas {\n\n                display: block;\n\n                max-width: 100%;\n\n                height: auto;\n\n                background: #fff;\n\n                box-shadow:\n                    0 3px 15px\n                    rgba(0,0,0,.25);\n            }\n\n\n            .stt-reader-status {\n\n                width: 100%;\n\n                padding: 50px 20px;\n\n                color: #fff;\n\n                text-align: center;\n\n                line-height: 1.5;\n            }\n\n\n            .stt-reader-loading {\n\n                display: inline-block;\n\n                width: 28px;\n\n                height: 28px;\n\n                border:\n                    3px solid\n                    rgba(255,255,255,.3);\n\n                border-top-color:\n                    #fff;\n\n                border-radius: 50%;\n\n                animation:\n                    stt-spin .8s\n                    linear infinite;\n\n                margin-bottom: 12px;\n            }\n\n\n            @keyframes stt-spin {\n\n                to {\n                    transform: rotate(360deg);\n                }\n\n            }\n\n\n            .stt-pagination {\n\n                display: flex;\n\n                flex-wrap: wrap;\n\n                justify-content:\n                    center;\n\n                gap: 8px;\n\n                margin-top: 25px;\n            }\n\n\n            .stt-pagination button {\n\n                border:\n                    1px solid\n                    var(--stt-border);\n\n                background: #fff;\n\n                padding:\n                    8px 12px;\n\n                border-radius: 7px;\n\n                cursor: pointer;\n            }\n\n\n            .stt-pagination button.active {\n\n                background:\n                    var(--stt-accent);\n\n                color: #fff;\n\n                border-color:\n                    var(--stt-accent);\n            }\n\n\n            .stt-empty {\n\n                grid-column:\n                    1 \/ -1;\n\n                padding: 35px;\n\n                text-align: center;\n\n                background: #fff;\n\n                border:\n                    1px solid\n                    var(--stt-border);\n\n                border-radius: 12px;\n\n                color:\n                    var(--stt-muted);\n            }\n\n\n            @media (max-width: 1000px) {\n\n                .stt-grid {\n\n                    grid-template-columns:\n                        repeat(\n                            3,\n                            minmax(0, 1fr)\n                        );\n                }\n\n            }\n\n\n            @media (max-width: 750px) {\n\n                .stt-grid {\n\n                    grid-template-columns:\n                        repeat(\n                            2,\n                            minmax(0, 1fr)\n                        );\n                }\n\n\n                .stt-controls {\n\n                    grid-template-columns:\n                        1fr;\n                }\n\n\n                .stt-reader-pages {\n\n                    min-height: 450px;\n\n                    padding: 10px;\n                }\n\n\n                .stt-reader-toolbar {\n\n                    align-items:\n                        flex-start;\n\n                    flex-direction:\n                        column;\n                }\n\n            }\n\n\n            @media (max-width: 480px) {\n\n                .stt-library {\n\n                    padding: 12px;\n                }\n\n\n                .stt-grid {\n\n                    grid-template-columns:\n                        1fr;\n                }\n\n\n                .stt-card-cover {\n\n                    min-height: 150px;\n                }\n\n\n                .stt-header h2 {\n\n                    font-size: 26px;\n                }\n\n\n                .stt-reader-actions {\n\n                    width: 100%;\n                }\n\n\n                .stt-reader-actions button,\n                .stt-reader-actions a {\n\n                    flex: 1;\n\n                    text-align: center;\n                }\n\n            }\n\n        <\/style>\n\n\n        <!-- =====================================\n             HEADER\n             ===================================== -->\n\n        <div class=\"stt-header\">\n\n            <h2>\n               Archeologische documentatie en publicaties\n            <\/h2>\n\n            <p>\n                Bekijk de beschikbare tijdschriften en lees de PDF online.\n            <\/p>\n\n        <\/div>\n\n\n        <!-- =====================================\n             FILTERS\n             ===================================== -->\n\n        <div class=\"stt-controls\">\n\n            <input\n                type=\"search\"\n                id=\"stt-search\"\n                placeholder=\"Zoek op titel, editie of jaar...\"\n                autocomplete=\"off\"\n            >\n\n\n            <select id=\"stt-category\">\n\n                <option value=\"\">\n                    Alle categorie\u00ebn\n                <\/option>\n\n\n                \n                    <option\n                        value=\"Brochures\"\n                    >\n                        Brochures                    <\/option>\n\n                \n                    <option\n                        value=\"Wetenschappelijke publicaties\"\n                    >\n                        Wetenschappelijke publicaties                    <\/option>\n\n                \n                    <option\n                        value=\"APAN\/Extern\"\n                    >\n                        APAN\/Extern                    <\/option>\n\n                \n                    <option\n                        value=\"Archaeologische berichten\"\n                    >\n                        Archaeologische berichten                    <\/option>\n\n                \n            <\/select>\n\n        <\/div>\n\n\n        <!-- =====================================\n             PDF READER\n             ===================================== -->\n\n        <div\n            id=\"stt-reader\"\n            class=\"stt-reader\"\n        >\n\n\n            <div class=\"stt-reader-toolbar\">\n\n                <div\n                    id=\"stt-reader-title\"\n                    class=\"stt-reader-title\"\n                >\n                    PDF-lezer\n                <\/div>\n\n\n                <div class=\"stt-reader-actions\">\n\n                    <button\n                        type=\"button\"\n                        id=\"stt-close-reader\"\n                    >\n                        Sluiten\n                    <\/button>\n\n\n                    <a\n                        id=\"stt-direct-pdf\"\n                        href=\"#\"\n                        target=\"_blank\"\n                        rel=\"noopener\"\n                    >\n                        PDF openen\n                    <\/a>\n\n                <\/div>\n\n            <\/div>\n\n\n            <div\n                class=\"stt-reader-navigation\"\n            >\n\n                <button\n                    type=\"button\"\n                    id=\"stt-prev-page\"\n                    disabled\n                >\n                    \u2190 Vorige\n                <\/button>\n\n\n                <div\n                    id=\"stt-page-info\"\n                    class=\"stt-page-info\"\n                >\n                    Pagina 0 \/ 0\n                <\/div>\n\n\n                <button\n                    type=\"button\"\n                    id=\"stt-next-page\"\n                    disabled\n                >\n                    Volgende \u2192\n                <\/button>\n\n            <\/div>\n\n\n            <div\n                id=\"stt-reader-pages\"\n                class=\"stt-reader-pages\"\n            >\n\n                <div\n                    id=\"stt-reader-status\"\n                    class=\"stt-reader-status\"\n                >\n                    Klik op een tijdschrift om de PDF te openen.\n                <\/div>\n\n            <\/div>\n\n        <\/div>\n\n\n        <!-- =====================================\n             COUNT\n             ===================================== -->\n\n        <div\n            id=\"stt-count\"\n            class=\"stt-count\"\n        >\n        <\/div>\n\n\n        <!-- =====================================\n             GRID\n             ===================================== -->\n\n        <div\n            id=\"stt-grid\"\n            class=\"stt-grid\"\n        >\n        <\/div>\n\n\n        <!-- =====================================\n             PAGINATION\n             ===================================== -->\n\n        <div\n            id=\"stt-pagination\"\n            class=\"stt-pagination\"\n        >\n        <\/div>\n\n    <\/div>\n\n\n    <!-- =========================================\n         PDF.JS\n         ========================================= -->\n\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.min.js\"><\/script>\n\n\n    <script>\n\n    document.addEventListener(\n        'DOMContentLoaded',\n        function() {\n\n\n        \/* =========================================\n         * DATA\n         * ========================================= *\/\n\n        const initialMagazines =\n            [{\"id\":29,\"title\":\"Archeologische berichten 1\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1977,\"pages\":37,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=29\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/Archaeologische-berichten-1.pdf\",\"cover_color\":\"amber\",\"sort_order\":1},{\"id\":31,\"title\":\"Archeologische berichten 2\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1978,\"pages\":36,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=31\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/Archaeologische-berichten-2_compressed.pdf\",\"cover_color\":\"stone\",\"sort_order\":2},{\"id\":32,\"title\":\"Archeologische berichten 3\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1978,\"pages\":62,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=32\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/Archaeologische-berichten-3_compressed-gecomprimeerd-gecomprimeerd.pdf\",\"cover_color\":\"yellow\",\"sort_order\":3},{\"id\":33,\"title\":\"Archeologische berichten 4\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1978,\"pages\":77,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=33\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/Archaeologische-berichten-4-gecomprimeerd-compressed.pdf\",\"cover_color\":\"neutral\",\"sort_order\":4},{\"id\":34,\"title\":\"Archeologische berichten 5\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1979,\"pages\":94,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=34\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-5.pdf\",\"cover_color\":\"yellow\",\"sort_order\":5},{\"id\":35,\"title\":\"Archeologische berichten 6\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1979,\"pages\":142,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=35\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-6.pdf\",\"cover_color\":\"stone\",\"sort_order\":6},{\"id\":36,\"title\":\"Archeologische berichten 7\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1980,\"pages\":153,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=36\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-7.pdf\",\"cover_color\":\"amber\",\"sort_order\":7},{\"id\":37,\"title\":\"Archeologische berichten 8\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1980,\"pages\":153,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=37\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-8.pdf\",\"cover_color\":\"neutral\",\"sort_order\":8},{\"id\":47,\"title\":\"Archeologische berichten 9\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1980,\"pages\":141,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=47\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-9.pdf\",\"cover_color\":\"yellow\",\"sort_order\":9},{\"id\":39,\"title\":\"Archeologische berichten 10\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1981,\"pages\":137,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=39\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-10.pdf\",\"cover_color\":\"amber\",\"sort_order\":10},{\"id\":49,\"title\":\"Archeologische berichten 11&12\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1982,\"pages\":216,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=49\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-1112.pdf\",\"cover_color\":\"neutral\",\"sort_order\":11},{\"id\":41,\"title\":\"Archeologische berichten 13\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1982,\"pages\":209,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=41\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-13.pdf\",\"cover_color\":\"amber\",\"sort_order\":12},{\"id\":42,\"title\":\"Archeologische berichten 14\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1983,\"pages\":188,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=42\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-14.pdf\",\"cover_color\":\"stone\",\"sort_order\":13},{\"id\":48,\"title\":\"Archeologische berichten 15\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1984,\"pages\":192,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=48\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-15.pdf\",\"cover_color\":\"yellow\",\"sort_order\":15},{\"id\":44,\"title\":\"Archeologische berichten 16\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1985,\"pages\":201,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=44\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-16.pdf\",\"cover_color\":\"neutral\",\"sort_order\":16},{\"id\":45,\"title\":\"Archeologische berichten 17\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1986,\"pages\":185,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=45\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-17.pdf\",\"cover_color\":\"stone\",\"sort_order\":16},{\"id\":46,\"title\":\"Archeologische berichten 18\",\"edition\":\"\",\"category\":\"Archaeologische berichten\",\"publication_year\":1987,\"pages\":191,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=46\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/Archaeologische-berichten-18.pdf\",\"cover_color\":\"amber\",\"sort_order\":17},{\"id\":52,\"title\":\"APAN\\\/Extern 1\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":1992,\"pages\":32,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=52\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-1.pdf\",\"cover_color\":\"neutral\",\"sort_order\":19},{\"id\":53,\"title\":\"APAN\\\/Extern 2\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":1993,\"pages\":78,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=53\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-2.pdf\",\"cover_color\":\"yellow\",\"sort_order\":20},{\"id\":54,\"title\":\"APAN\\\/Extern 3\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":1993,\"pages\":93,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=54\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-3.pdf\",\"cover_color\":\"neutral\",\"sort_order\":21},{\"id\":55,\"title\":\"APAN\\\/Extern 4\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":1994,\"pages\":100,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=55\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-4.pdf\",\"cover_color\":\"neutral\",\"sort_order\":22},{\"id\":56,\"title\":\"APAN\\\/Extern 5\",\"edition\":\"1995 en 1996\",\"category\":\"APAN\\\/Extern\",\"publication_year\":1995,\"pages\":98,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=56\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-5.pdf\",\"cover_color\":\"stone\",\"sort_order\":23},{\"id\":57,\"title\":\"APAN\\\/Extern 6\",\"edition\":\"1996 en 1997\",\"category\":\"APAN\\\/Extern\",\"publication_year\":1996,\"pages\":84,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=57\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-6.pdf\",\"cover_color\":\"neutral\",\"sort_order\":24},{\"id\":58,\"title\":\"APAN\\\/Extern 7\",\"edition\":\"1997 en 1998\",\"category\":\"APAN\\\/Extern\",\"publication_year\":1997,\"pages\":92,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=58\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-7.pdf\",\"cover_color\":\"yellow\",\"sort_order\":25},{\"id\":59,\"title\":\"APAN\\\/Extern 8\",\"edition\":\"1999 en 2000\",\"category\":\"APAN\\\/Extern\",\"publication_year\":1999,\"pages\":96,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=59\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-8.pdf\",\"cover_color\":\"neutral\",\"sort_order\":26},{\"id\":60,\"title\":\"APAN\\\/Extern 9\",\"edition\":\"2000 en 2001\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2000,\"pages\":105,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=60\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-9.pdf\",\"cover_color\":\"stone\",\"sort_order\":27},{\"id\":61,\"title\":\"APAN\\\/Extern 10\",\"edition\":\"2002 en 2003\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2002,\"pages\":90,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=61\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-10.pdf\",\"cover_color\":\"neutral\",\"sort_order\":28},{\"id\":62,\"title\":\"APAN\\\/Extern 11\",\"edition\":\"2004 en 2005\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2004,\"pages\":44,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=62\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-11.pdf\",\"cover_color\":\"amber\",\"sort_order\":29},{\"id\":63,\"title\":\"APAN\\\/Extern 12\",\"edition\":\"2005 en 2006\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2005,\"pages\":95,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=63\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-12.pdf\",\"cover_color\":\"yellow\",\"sort_order\":30},{\"id\":64,\"title\":\"APAN\\\/Extern 13\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2009,\"pages\":84,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=64\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-13.pdf\",\"cover_color\":\"stone\",\"sort_order\":31},{\"id\":65,\"title\":\"APAN\\\/Extern 14\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2010,\"pages\":140,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=65\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-14.pdf\",\"cover_color\":\"neutral\",\"sort_order\":32},{\"id\":66,\"title\":\"APAN\\\/Extern 15\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2014,\"pages\":134,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=66\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-15.pdf\",\"cover_color\":\"yellow\",\"sort_order\":33},{\"id\":67,\"title\":\"APAN\\\/Extern 16\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2017,\"pages\":82,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=67\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-16.pdf\",\"cover_color\":\"amber\",\"sort_order\":34},{\"id\":68,\"title\":\"APAN\\\/Extern 17\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2018,\"pages\":102,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=68\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-17.pdf\",\"cover_color\":\"stone\",\"sort_order\":35},{\"id\":69,\"title\":\"APAN\\\/Extern 18\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2019,\"pages\":124,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=69\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-18.pdf\",\"cover_color\":\"amber\",\"sort_order\":36},{\"id\":70,\"title\":\"APAN\\\/Extern 19\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2021,\"pages\":107,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=70\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/apan-19.pdf\",\"cover_color\":\"yellow\",\"sort_order\":37},{\"id\":51,\"title\":\"APAN\\\/Extern 20\",\"edition\":\"\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2025,\"pages\":222,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=51\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/ApanExtern20digitaal.pdf\",\"cover_color\":\"neutral\",\"sort_order\":38},{\"id\":71,\"title\":\"the Paleolithic how and why\",\"edition\":\"1\",\"category\":\"APAN\\\/Extern\",\"publication_year\":2019,\"pages\":145,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=71\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/the-Paleolithic-how-and-why.pdf\",\"cover_color\":\"stone\",\"sort_order\":39},{\"id\":72,\"title\":\"Flint paper\",\"edition\":\"\",\"category\":\"Brochures\",\"publication_year\":1988,\"pages\":32,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=72\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/flint-paper-digital-1.pdf\",\"cover_color\":\"stone\",\"sort_order\":40},{\"id\":73,\"title\":\"Gampelen Janet 3 Eine mesolithische Sied\",\"edition\":\"\",\"category\":\"Wetenschappelijke publicaties\",\"publication_year\":1991,\"pages\":152,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=73\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/Gampelen_Janet_3_Eine_mesolithische_Sied.pdf\",\"cover_color\":\"neutral\",\"sort_order\":41},{\"id\":74,\"title\":\"Flint Patina as an Aspect of \\u201cFlaked Stone Taphonomy\\u201d: A Case Study from the Loess Terrain of the Netherlands and Belgium\",\"edition\":\"1\",\"category\":\"Wetenschappelijke publicaties\",\"publication_year\":2026,\"pages\":23,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=74\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/2012-PP-FlintTaphonomy.pdf\",\"cover_color\":\"yellow\",\"sort_order\":42},{\"id\":75,\"title\":\"De Neanderthaler- vindplaats Esbeek- Diessen, gemeente Hilvarenbeek\",\"edition\":\"\",\"category\":\"Wetenschappelijke publicaties\",\"publication_year\":2022,\"pages\":292,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=75\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/RAM290_Esbeek-Diessen.pdf\",\"cover_color\":\"amber\",\"sort_order\":43},{\"id\":76,\"title\":\"Onderzoek naar de stratigrafie van de l\\u00f6sssequentie en de daarin aangetroffen artefacten op De Kaap bij St. Geertruid\",\"edition\":\"\",\"category\":\"Wetenschappelijke publicaties\",\"publication_year\":2017,\"pages\":88,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=76\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/rce-ram-236-de_kaap_bij_st_geertruid.pdf\",\"cover_color\":\"neutral\",\"sort_order\":44},{\"id\":77,\"title\":\"Archeologie Totaal 1\",\"edition\":\"1\",\"category\":\"Wetenschappelijke publicaties\",\"publication_year\":1989,\"pages\":108,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=77\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/Archeologie_01_Totaal.pdf\",\"cover_color\":\"stone\",\"sort_order\":45},{\"id\":78,\"title\":\"J ' cusse de zaak Vermaning\",\"edition\":\"1\",\"category\":\"Brochures\",\"publication_year\":1999,\"pages\":274,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=78\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/jaccuse-1.pdf\",\"cover_color\":\"neutral\",\"sort_order\":46},{\"id\":79,\"title\":\"\\u2018Oh, So You Want to Be an Academic?\\u2019\",\"edition\":\"Het document bevat de volledige vertaling van het artikel \\u2018Oh, So You Want to Be an Academic?\\u2019 van Seth Chagi, met behoud van de oorspronkelijke hoofdstukindeling, humor en kritische toon.\",\"category\":\"Wetenschappelijke publicaties\",\"publication_year\":2026,\"pages\":8,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=79\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/Vertaling_O_dus_je_wilt_wetenschapper_worden.docx.pdf\",\"cover_color\":\"neutral\",\"sort_order\":47},{\"id\":80,\"title\":\"A bifacial paradise\\u2014The site of Ochtmissen, Germany, and its lithic assemblage in the context of the last glacial (early MIS 4) in the north- central European Lowland\",\"edition\":\"1\",\"category\":\"Wetenschappelijke publicaties\",\"publication_year\":2026,\"pages\":17,\"pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/?stt_pdf_proxy=80\",\"direct_pdf_url\":\"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/Boreas-2026-Di-Maida-A-bifacial-paradise-The-site-of-Ochtmissen-Germany-and-its-lithic-assemblage-in-the-context-of.pdf\",\"cover_color\":\"stone\",\"sort_order\":48}];\n\n\n        const ajaxUrl =\n            \"https:\\\/\\\/steentijdvondsten.nl\\\/post\\\/wp-admin\\\/admin-ajax.php\";\n\n\n        let magazines =\n            Array.isArray(\n                initialMagazines\n            )\n                ? initialMagazines\n                : [];\n\n\n        let filteredMagazines =\n            magazines.slice();\n\n\n        let currentPage =\n            1;\n\n\n        const perPage =\n            20;\n\n\n        \/* =========================================\n         * PDF STATE\n         * ========================================= *\/\n\n        let currentPdf =\n            null;\n\n\n        let currentMagazine =\n            null;\n\n\n        let currentPageNumber =\n            0;\n\n\n        let totalPages =\n            0;\n\n\n        let loadingTask =\n            null;\n\n\n        let renderTask =\n            null;\n\n\n        let readerToken =\n            0;\n\n\n        \/* =========================================\n         * ELEMENTEN\n         * ========================================= *\/\n\n        const grid =\n            document.getElementById(\n                'stt-grid'\n            );\n\n\n        const pagination =\n            document.getElementById(\n                'stt-pagination'\n            );\n\n\n        const count =\n            document.getElementById(\n                'stt-count'\n            );\n\n\n        const search =\n            document.getElementById(\n                'stt-search'\n            );\n\n\n        const category =\n            document.getElementById(\n                'stt-category'\n            );\n\n\n        const reader =\n            document.getElementById(\n                'stt-reader'\n            );\n\n\n        const readerTitle =\n            document.getElementById(\n                'stt-reader-title'\n            );\n\n\n        const readerPages =\n            document.getElementById(\n                'stt-reader-pages'\n            );\n\n\n        const readerStatus =\n            document.getElementById(\n                'stt-reader-status'\n            );\n\n\n        const directPdf =\n            document.getElementById(\n                'stt-direct-pdf'\n            );\n\n\n        const closeReader =\n            document.getElementById(\n                'stt-close-reader'\n            );\n\n\n        const prevPage =\n            document.getElementById(\n                'stt-prev-page'\n            );\n\n\n        const nextPage =\n            document.getElementById(\n                'stt-next-page'\n            );\n\n\n        const pageInfo =\n            document.getElementById(\n                'stt-page-info'\n            );\n\n\n        \/* =========================================\n         * PDF.JS\n         * ========================================= *\/\n\n        if (\n            typeof pdfjsLib !==\n            'undefined'\n        ) {\n\n            pdfjsLib\n                .GlobalWorkerOptions\n                .workerSrc =\n                'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.worker.min.js';\n\n        }\n\n\n        \/* =========================================\n         * FILTERS\n         * ========================================= *\/\n\n        function applyFilters() {\n\n            const searchTerm =\n                search.value\n                    .trim()\n                    .toLowerCase();\n\n\n            const categoryValue =\n                category.value;\n\n\n            filteredMagazines =\n                magazines.filter(\n                    function(magazine) {\n\n                        const searchable =\n                            (\n                                magazine.title +\n                                ' ' +\n                                magazine.edition +\n                                ' ' +\n                                magazine.category +\n                                ' ' +\n                                magazine.publication_year\n                            ).toLowerCase();\n\n\n                        const matchesSearch =\n                            !searchTerm ||\n                            searchable.includes(\n                                searchTerm\n                            );\n\n\n                        const matchesCategory =\n                            !categoryValue ||\n                            magazine.category ===\n                                categoryValue;\n\n\n                        return (\n                            matchesSearch &&\n                            matchesCategory\n                        );\n\n                    }\n                );\n\n\n            currentPage =\n                1;\n\n\n            renderCards();\n\n        }\n\n\n        \/* =========================================\n         * KAARTEN\n         * ========================================= *\/\n\n        function renderCards() {\n\n            grid.innerHTML =\n                '';\n\n\n            const total =\n                filteredMagazines.length;\n\n\n            count.textContent =\n                total +\n                (\n                    total === 1\n                        ? ' tijdschrift'\n                        : ' tijdschriften'\n                );\n\n\n            if (!total) {\n\n                grid.innerHTML =\n                    '<div class=\"stt-empty\">' +\n                    'Geen tijdschriften gevonden.' +\n                    '<\/div>';\n\n\n                pagination.innerHTML =\n                    '';\n\n\n                return;\n            }\n\n\n            const start =\n                (\n                    currentPage - 1\n                ) *\n                perPage;\n\n\n            const end =\n                start +\n                perPage;\n\n\n            const visible =\n                filteredMagazines.slice(\n                    start,\n                    end\n                );\n\n\n            visible.forEach(\n                function(magazine) {\n\n\n                const card =\n                    document.createElement(\n                        'article'\n                    );\n\n\n                card.className =\n                    'stt-card';\n\n\n                let coverColor =\n                    magazine.cover_color ||\n                    'stone';\n\n\n                if (\n                    ![\n                        'amber',\n                        'stone',\n                        'yellow',\n                        'neutral'\n                    ].includes(\n                        coverColor\n                    )\n                ) {\n\n                    coverColor =\n                        'stone';\n                }\n\n\n                const edition =\n                    magazine.edition\n                        ? escapeHtml(\n                            magazine.edition\n                        )\n                        : '';\n\n\n                const categoryText =\n                    magazine.category\n                        ? escapeHtml(\n                            magazine.category\n                        )\n                        : '';\n\n\n                const year =\n                    magazine.publication_year\n                        ? escapeHtml(\n                            String(\n                                magazine.publication_year\n                            )\n                        )\n                        : '';\n\n\n                const pages =\n                    magazine.pages\n                        ? magazine.pages +\n                          ' pagina\\'s'\n                        : '';\n\n\n                card.innerHTML =\n\n                    '<div class=\"stt-card-cover stt-cover-' +\n                    coverColor +\n                    '\">' +\n\n                        '<div class=\"stt-card-number\">' +\n\n                            (\n                                magazine.publication_year\n                                    ? escapeHtml(\n                                        String(\n                                            magazine.publication_year\n                                        )\n                                    )\n                                    : 'TIJDSCHRIFT'\n                            ) +\n\n                        '<\/div>' +\n\n\n                        '<div class=\"stt-card-title\">' +\n\n                            escapeHtml(\n                                magazine.title\n                            ) +\n\n                        '<\/div>' +\n\n                    '<\/div>' +\n\n\n                    '<div class=\"stt-card-body\">' +\n\n                        '<h3>' +\n\n                            escapeHtml(\n                                magazine.title\n                            ) +\n\n                        '<\/h3>' +\n\n\n                        '<div class=\"stt-card-meta\">' +\n\n                            (\n                                edition\n                                    ? '<span>' +\n                                      edition +\n                                      '<\/span>'\n                                    : ''\n                            ) +\n\n\n                            (\n                                categoryText\n                                    ? '<span>' +\n                                      categoryText +\n                                      '<\/span>'\n                                    : ''\n                            ) +\n\n\n                            (\n                                year\n                                    ? '<span>' +\n                                      year +\n                                      '<\/span>'\n                                    : ''\n                            ) +\n\n\n                            (\n                                pages\n                                    ? '<span>' +\n                                      pages +\n                                      '<\/span>'\n                                    : ''\n                            ) +\n\n\n                        '<\/div>' +\n\n                    '<\/div>';\n\n\n                card.addEventListener(\n                    'click',\n                    function() {\n\n                        openMagazine(\n                            magazine\n                        );\n\n                    }\n                );\n\n\n                grid.appendChild(\n                    card\n                );\n\n            });\n\n\n            renderPagination();\n\n        }\n\n\n        \/* =========================================\n         * PAGINATION\n         * ========================================= *\/\n\n        function renderPagination() {\n\n            pagination.innerHTML =\n                '';\n\n\n            const totalPages =\n                Math.ceil(\n                    filteredMagazines.length \/\n                    perPage\n                );\n\n\n            if (\n                totalPages <= 1\n            ) {\n\n                return;\n            }\n\n\n            for (\n                let page = 1;\n                page <= totalPages;\n                page++\n            ) {\n\n\n                const button =\n                    document.createElement(\n                        'button'\n                    );\n\n\n                button.type =\n                    'button';\n\n\n                button.textContent =\n                    page;\n\n\n                if (\n                    page ===\n                    currentPage\n                ) {\n\n                    button.classList.add(\n                        'active'\n                    );\n                }\n\n\n                button.addEventListener(\n                    'click',\n                    function() {\n\n                        currentPage =\n                            page;\n\n\n                        renderCards();\n\n\n                        const library =\n                            document.getElementById(\n                                'stt-library'\n                            );\n\n\n                        if (library) {\n\n                            window.scrollTo({\n\n                                top:\n                                    library.offsetTop -\n                                    30,\n\n                                behavior:\n                                    'smooth'\n\n                            });\n\n                        }\n\n                    }\n                );\n\n\n                pagination.appendChild(\n                    button\n                );\n\n            }\n\n        }\n\n\n        \/* =========================================\n         * PDF LEZER - ALLES OPRUIMEN\n         * ========================================= *\/\n\n        async function cleanupPdf() {\n\n            \/*\n             * Ongeldig token.\n             * Eventuele oude async acties mogen\n             * niets meer aan de interface doen.\n             *\/\n            readerToken++;\n\n\n            \/*\n             * Lopende pagina-rendering annuleren.\n             *\/\n            if (renderTask) {\n\n                try {\n\n                    renderTask.cancel();\n\n                } catch (e) {}\n\n                renderTask =\n                    null;\n            }\n\n\n            \/*\n             * Lopende PDF-loading annuleren.\n             *\/\n            if (loadingTask) {\n\n                try {\n\n                    await loadingTask.destroy();\n\n                } catch (e) {}\n\n                loadingTask =\n                    null;\n            }\n\n\n            \/*\n             * PDF-document zelf vernietigen.\n             *\/\n            if (currentPdf) {\n\n                try {\n\n                    await currentPdf.destroy();\n\n                } catch (e) {}\n\n                currentPdf =\n                    null;\n            }\n\n\n            \/*\n             * Canvas volledig verwijderen.\n             *\/\n            readerPages.innerHTML =\n                '';\n\n\n            currentPageNumber =\n                0;\n\n\n            totalPages =\n                0;\n\n\n            pageInfo.textContent =\n                'Pagina 0 \/ 0';\n\n\n            prevPage.disabled =\n                true;\n\n\n            nextPage.disabled =\n                true;\n\n        }\n\n\n        \/* =========================================\n         * PDF OPENEN\n         * ========================================= *\/\n\n        async function openMagazine(\n            magazine\n        ) {\n\n            if (\n                !magazine ||\n                !magazine.pdf_url\n            ) {\n\n                return;\n            }\n\n\n            \/*\n             * Eerst alles van het vorige\n             * tijdschrift opruimen.\n             *\/\n            await cleanupPdf();\n\n\n            const myToken =\n                readerToken;\n\n\n            currentMagazine =\n                magazine;\n\n\n            reader.style.display =\n                'block';\n\n\n            readerTitle.textContent =\n                magazine.title;\n\n\n            directPdf.href =\n                magazine.direct_pdf_url ||\n                magazine.pdf_url;\n\n\n            showReaderLoading(\n                'PDF wordt geladen...'\n            );\n\n\n            reader.scrollIntoView({\n                behavior: 'smooth',\n                block: 'start'\n            });\n\n\n            if (\n                typeof pdfjsLib ===\n                'undefined'\n            ) {\n\n                showReaderError(\n                    'De PDF-lezer kon niet worden geladen.'\n                );\n\n                return;\n            }\n\n\n            try {\n\n                \/*\n                 * Nieuwe loading task.\n                 *\/\n                loadingTask =\n                    pdfjsLib.getDocument({\n\n                        url:\n                            magazine.pdf_url,\n\n                        withCredentials:\n                            false,\n\n                        \/*\n                         * We gebruiken bewust geen\n                         * range\/stream rendering.\n                         * Dit voorkomt veel browserproblemen\n                         * bij sommige externe PDF's.\n                         *\/\n                        disableRange:\n                            true,\n\n                        disableStream:\n                            true,\n\n                        disableAutoFetch:\n                            false\n\n                    });\n\n\n                const pdf =\n                    await loadingTask.promise;\n\n\n                \/*\n                 * Controleer of de gebruiker ondertussen\n                 * alweer een ander tijdschrift heeft gekozen.\n                 *\/\n                if (\n                    myToken !==\n                    readerToken\n                ) {\n\n                    try {\n                        await pdf.destroy();\n                    } catch (e) {}\n\n                    return;\n                }\n\n\n                currentPdf =\n                    pdf;\n\n\n                loadingTask =\n                    null;\n\n\n                totalPages =\n                    pdf.numPages;\n\n\n                currentPageNumber =\n                    1;\n\n\n                updatePageNavigation();\n\n\n                await renderCurrentPage(\n                    myToken\n                );\n\n\n            } catch (error) {\n\n                console.error(\n                    'STT PDF error:',\n                    error\n                );\n\n\n                if (\n                    myToken !==\n                    readerToken\n                ) {\n\n                    return;\n                }\n\n\n                showReaderError(\n                    'De PDF kon niet worden geladen. ' +\n                    'Gebruik eventueel de knop \"PDF openen\".'\n                );\n\n            }\n\n        }\n\n\n        \/* =========================================\n         * \u00c9\u00c9N PAGINA RENDEREN\n         * ========================================= *\/\n\n        async function renderCurrentPage(\n            myToken\n        ) {\n\n            if (\n                !currentPdf ||\n                !currentPageNumber\n            ) {\n\n                return;\n            }\n\n\n            if (\n                myToken !==\n                readerToken\n            ) {\n\n                return;\n            }\n\n\n            \/*\n             * Oude render annuleren.\n             *\/\n            if (renderTask) {\n\n                try {\n\n                    renderTask.cancel();\n\n                } catch (e) {}\n\n                renderTask =\n                    null;\n            }\n\n\n            readerPages.innerHTML =\n                '<div class=\"stt-reader-status\">' +\n                    '<div class=\"stt-reader-loading\"><\/div>' +\n                    '<br>' +\n                    'Pagina wordt geladen...' +\n                '<\/div>';\n\n\n            try {\n\n                const page =\n                    await currentPdf.getPage(\n                        currentPageNumber\n                    );\n\n\n                if (\n                    myToken !==\n                    readerToken\n                ) {\n\n                    return;\n                }\n\n\n                \/*\n                 * Schaal automatisch naar de breedte\n                 * van de reader.\n                 *\/\n                const containerWidth =\n                    Math.max(\n                        readerPages.clientWidth -\n                        40,\n                        300\n                    );\n\n\n                const baseViewport =\n                    page.getViewport({\n                        scale: 1\n                    });\n\n\n                let scale =\n                    containerWidth \/\n                    baseViewport.width;\n\n\n                \/*\n                 * Niet extreem klein.\n                 *\/\n                scale =\n                    Math.max(\n                        scale,\n                        0.7\n                    );\n\n\n                \/*\n                 * Niet extreem groot.\n                 *\/\n                scale =\n                    Math.min(\n                        scale,\n                        1.8\n                    );\n\n\n                const viewport =\n                    page.getViewport({\n                        scale: scale\n                    });\n\n\n                const canvas =\n                    document.createElement(\n                        'canvas'\n                    );\n\n\n                const context =\n                    canvas.getContext(\n                        '2d',\n                        {\n                            alpha: false\n                        }\n                    );\n\n\n                canvas.width =\n                    Math.floor(\n                        viewport.width\n                    );\n\n\n                canvas.height =\n                    Math.floor(\n                        viewport.height\n                    );\n\n\n                canvas.style.width =\n                    Math.floor(\n                        viewport.width\n                    ) + 'px';\n\n\n                canvas.style.height =\n                    Math.floor(\n                        viewport.height\n                    ) + 'px';\n\n\n                readerPages.innerHTML =\n                    '';\n\n\n                readerPages.appendChild(\n                    canvas\n                );\n\n\n                \/*\n                 * Alleen deze ene pagina wordt\n                 * gerenderd.\n                 *\/\n                renderTask =\n                    page.render({\n\n                        canvasContext:\n                            context,\n\n                        viewport:\n                            viewport\n\n                    });\n\n\n                await renderTask.promise;\n\n\n                renderTask =\n                    null;\n\n\n                if (\n                    myToken !==\n                    readerToken\n                ) {\n\n                    return;\n                }\n\n\n                updatePageNavigation();\n\n\n            } catch (error) {\n\n                renderTask =\n                    null;\n\n\n                \/*\n                 * Een annulering is normaal wanneer\n                 * iemand snel naar een andere pagina\n                 * gaat.\n                 *\/\n                if (\n                    error &&\n                    error.name ===\n                    'RenderingCancelledException'\n                ) {\n\n                    return;\n                }\n\n\n                if (\n                    myToken !==\n                    readerToken\n                ) {\n\n                    return;\n                }\n\n\n                console.error(\n                    'STT page render error:',\n                    error\n                );\n\n\n                showReaderError(\n                    'Deze pagina kon niet worden weergegeven.'\n                );\n\n            }\n\n        }\n\n\n        \/* =========================================\n         * PAGINA NAVIGATIE\n         * ========================================= *\/\n\n        function updatePageNavigation() {\n\n            pageInfo.textContent =\n                'Pagina ' +\n                currentPageNumber +\n                ' \/ ' +\n                totalPages;\n\n\n            prevPage.disabled =\n                currentPageNumber <= 1;\n\n\n            nextPage.disabled =\n                currentPageNumber >=\n                totalPages;\n\n        }\n\n\n        async function goToPage(\n            pageNumber\n        ) {\n\n            if (\n                !currentPdf ||\n                !totalPages\n            ) {\n\n                return;\n            }\n\n\n            if (\n                pageNumber < 1 ||\n                pageNumber > totalPages\n            ) {\n\n                return;\n            }\n\n\n            currentPageNumber =\n                pageNumber;\n\n\n            updatePageNavigation();\n\n\n            const myToken =\n                readerToken;\n\n\n            await renderCurrentPage(\n                myToken\n            );\n\n        }\n\n\n        prevPage.addEventListener(\n            'click',\n            function() {\n\n                if (\n                    currentPageNumber >\n                    1\n                ) {\n\n                    goToPage(\n                        currentPageNumber - 1\n                    );\n\n                }\n\n            }\n        );\n\n\n        nextPage.addEventListener(\n            'click',\n            function() {\n\n                if (\n                    currentPageNumber <\n                    totalPages\n                ) {\n\n                    goToPage(\n                        currentPageNumber + 1\n                    );\n\n                }\n\n            }\n        );\n\n\n        \/* =========================================\n         * READER SLUITEN\n         * ========================================= *\/\n\n        closeReader.addEventListener(\n            'click',\n            async function() {\n\n                await cleanupPdf();\n\n\n                currentMagazine =\n                    null;\n\n\n                reader.style.display =\n                    'none';\n\n\n                readerPages.innerHTML =\n                    '<div class=\"stt-reader-status\">' +\n                    'Klik op een tijdschrift om de PDF te openen.' +\n                    '<\/div>';\n\n            }\n        );\n\n\n        \/* =========================================\n         * LOADING\n         * ========================================= *\/\n\n        function showReaderLoading(\n            message\n        ) {\n\n            readerPages.innerHTML =\n                '<div class=\"stt-reader-status\">' +\n\n                    '<div class=\"stt-reader-loading\"><\/div>' +\n\n                    '<br>' +\n\n                    escapeHtml(\n                        message\n                    ) +\n\n                '<\/div>';\n\n        }\n\n\n        function showReaderError(\n            message\n        ) {\n\n            readerPages.innerHTML =\n                '<div class=\"stt-reader-status\">' +\n                    escapeHtml(\n                        message\n                    ) +\n                '<\/div>';\n\n        }\n\n\n        \/* =========================================\n         * ACTUELE DATA OPHALEN\n         * ========================================= *\/\n\n        async function refreshMagazines() {\n\n            try {\n\n                const formData =\n                    new FormData();\n\n\n                formData.append(\n                    'action',\n                    'stt_get_magazines'\n                );\n\n\n                \/*\n                 * Cache-busting.\n                 *\/\n                formData.append(\n                    '_stt_refresh',\n                    String(\n                        Date.now()\n                    )\n                );\n\n\n                const response =\n                    await fetch(\n                        ajaxUrl,\n                        {\n                            method:\n                                'POST',\n\n                            body:\n                                formData,\n\n                            credentials:\n                                'same-origin',\n\n                            cache:\n                                'no-store'\n                        }\n                    );\n\n\n                if (\n                    !response.ok\n                ) {\n\n                    throw new Error(\n                        'HTTP ' +\n                        response.status\n                    );\n                }\n\n\n                const json =\n                    await response.json();\n\n\n                if (\n                    !json.success ||\n                    !json.data ||\n                    !Array.isArray(\n                        json.data.items\n                    )\n                ) {\n\n                    throw new Error(\n                        'Ongeldige serverrespons.'\n                    );\n                }\n\n\n                \/*\n                 * Actuele databasegegevens.\n                 *\/\n                magazines =\n                    json.data.items;\n\n\n                applyFilters();\n\n\n            } catch (error) {\n\n                console.error(\n                    'STT refresh error:',\n                    error\n                );\n\n\n                \/*\n                 * Fallback naar de data die\n                 * al in de pagina zat.\n                 *\/\n                applyFilters();\n\n            }\n\n        }\n\n\n        \/* =========================================\n         * HTML ESCAPE\n         * ========================================= *\/\n\n        function escapeHtml(\n            value\n        ) {\n\n            return String(value)\n                .replace(\n                    \/&\/g,\n                    '&amp;'\n                )\n                .replace(\n                    \/<\/g,\n                    '&lt;'\n                )\n                .replace(\n                    \/>\/g,\n                    '&gt;'\n                )\n                .replace(\n                    \/\"\/g,\n                    '&quot;'\n                )\n                .replace(\n                    \/'\/g,\n                    '&#039;'\n                );\n\n        }\n\n\n        \/* =========================================\n         * EVENTS\n         * ========================================= *\/\n\n        search.addEventListener(\n            'input',\n            applyFilters\n        );\n\n\n        category.addEventListener(\n            'change',\n            applyFilters\n        );\n\n\n        \/*\n         * Bij het sluiten\/verwijderen van de pagina\n         * proberen we de PDF netjes op te ruimen.\n         *\/\n        window.addEventListener(\n            'pagehide',\n            function() {\n\n                if (currentPdf) {\n\n                    try {\n                        currentPdf.destroy();\n                    } catch (e) {}\n\n                }\n\n            }\n        );\n\n\n        \/*\n         * Bij browser resize de huidige pagina\n         * opnieuw tekenen.\n         *\/\n        let resizeTimer =\n            null;\n\n\n        window.addEventListener(\n            'resize',\n            function() {\n\n                clearTimeout(\n                    resizeTimer\n                );\n\n\n                resizeTimer =\n                    setTimeout(\n                        function() {\n\n                            if (\n                                currentPdf &&\n                                currentPageNumber\n                            ) {\n\n                                const myToken =\n                                    readerToken;\n\n                                renderCurrentPage(\n                                    myToken\n                                );\n\n                            }\n\n                        },\n                        250\n                    );\n\n            }\n        );\n\n\n        \/* =========================================\n         * INIT\n         * ========================================= *\/\n\n        \/*\n         * Eerst kaarten tonen.\n         *\n         * BELANGRIJK:\n         * Er wordt GEEN PDF automatisch geopend.\n         *\/\n        applyFilters();\n\n\n        \/*\n         * Daarna actuele database ophalen.\n         *\/\n        refreshMagazines();\n\n\n    });\n\n    <\/script>\n\n    \n","protected":false},"excerpt":{"rendered":"<p>1<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"templates\/template-full-width-blank.php","meta":{"footnotes":""},"class_list":["post-14230","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/steentijdvondsten.nl\/post\/index.php\/wp-json\/wp\/v2\/pages\/14230","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/steentijdvondsten.nl\/post\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/steentijdvondsten.nl\/post\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/steentijdvondsten.nl\/post\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/steentijdvondsten.nl\/post\/index.php\/wp-json\/wp\/v2\/comments?post=14230"}],"version-history":[{"count":22,"href":"https:\/\/steentijdvondsten.nl\/post\/index.php\/wp-json\/wp\/v2\/pages\/14230\/revisions"}],"predecessor-version":[{"id":15529,"href":"https:\/\/steentijdvondsten.nl\/post\/index.php\/wp-json\/wp\/v2\/pages\/14230\/revisions\/15529"}],"wp:attachment":[{"href":"https:\/\/steentijdvondsten.nl\/post\/index.php\/wp-json\/wp\/v2\/media?parent=14230"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}