{"id":16844,"date":"2026-02-25T16:52:18","date_gmt":"2026-02-25T16:52:18","guid":{"rendered":"https:\/\/www.cejj-justice.tn\/mes-abonnements\/"},"modified":"2026-03-11T22:08:34","modified_gmt":"2026-03-11T22:08:34","slug":"mes-abonnements","status":"publish","type":"page","link":"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/","title":{"rendered":"Mes Abonnements"},"content":{"rendered":"\n    <div class=\"sub-wrap\" dir=\"ltr\" data-lang=\"fr\">\n      <div class=\"sub-tabs\">\n        <button class=\"sub-tab active\" onclick=\"switchTab('new', 0)\">\n          <svg class=\"icon-svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"16\"\/><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"\/><\/svg>\n          Nouvel abonnement        <\/button>\n        <button class=\"sub-tab\" onclick=\"switchTab('list', 1)\">\n          <svg class=\"icon-svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"\/><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"\/><line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"\/><line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"\/><line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"\/><line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"\/><\/svg>\n          Mes abonnements                  <\/button>\n      <\/div>\n\n      <!-- \u2500\u2500 NEW SUBSCRIPTION \u2500\u2500 -->\n      <div class=\"sub-panel\" id=\"tab-new\">\n        <div class=\"sub-form\">\n          <div class=\"sub-field\">\n            <label>Choisir les cat\u00e9gories <span class=\"sub-hint\">(1 \u00e0 4, ou Tout)<\/span><\/label>\n            <div class=\"dropdown-check-list\" id=\"cat-dropdown\">\n              <span class=\"anchor\" onclick=\"toggleDropdown()\">\n                <span id=\"anchor-text\">S\u00e9lectionner des cat\u00e9gories<\/span>\n                <svg class=\"icon-svg anchor-icon\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"6 9 12 15 18 9\"\/><\/svg>\n              <\/span>\n              <div class=\"items\" id=\"cat-items\" style=\"display:none;\">\n                <label class=\"check-item check-all-item\">\n                  <input type=\"checkbox\" id=\"check-all\" onchange=\"toggleAll(this)\">\n                  <strong>Toutes les cat\u00e9gories<\/strong>\n                <\/label>\n                <div class=\"items-divider\"><\/div>\n                                <label class=\"check-item\">\n                  <input type=\"checkbox\" class=\"cat-check\" value=\"22\"\n                         data-name=\"Uncategorized\" onchange=\"updateSummary()\">\n                  Uncategorized                <\/label>\n                                <label class=\"check-item\">\n                  <input type=\"checkbox\" class=\"cat-check\" value=\"27\"\n                         data-name=\"Ouvrages\" onchange=\"updateSummary()\">\n                  Ouvrages                <\/label>\n                                <label class=\"check-item\">\n                  <input type=\"checkbox\" class=\"cat-check\" value=\"28\"\n                         data-name=\"Revue de Jurisprudence et de la l\u00e9gislation\" onchange=\"updateSummary()\">\n                  Revue de Jurisprudence et de la l\u00e9gislation                <\/label>\n                                <label class=\"check-item\">\n                  <input type=\"checkbox\" class=\"cat-check\" value=\"343\"\n                         data-name=\"\u0646\u0634\u0631\u064a\u0629 \u0645\u062d\u0643\u0645\u0629 \u0627\u0644\u062a\u0639\u0642\u064a\u0628\" onchange=\"updateSummary()\">\n                  \u0646\u0634\u0631\u064a\u0629 \u0645\u062d\u0643\u0645\u0629 \u0627\u0644\u062a\u0639\u0642\u064a\u0628                <\/label>\n                              <\/div>\n            <\/div>\n          <\/div>\n                    <div class=\"sub-field\">\n            <label for=\"sub-years\">Ann\u00e9e d'abonnement<\/label>\n            <select id=\"sub-years\" onchange=\"updateSummary()\">\n                            <option value=\"2025\">2025<\/option>\n                            <option value=\"2026\">2026<\/option>\n                            <option value=\"2027\">2027<\/option>\n                          <\/select>\n          <\/div>\n          <div class=\"sub-summary-wrap\">\n            <div class=\"sub-placeholder\" id=\"sub-placeholder\">\n              <svg class=\"icon-svg\" width=\"36\" height=\"36\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" opacity=\".35\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"\/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\"\/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"\/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\"\/><\/svg>\n              <p>Choisissez des cat\u00e9gories et une ann\u00e9e pour voir le r\u00e9capitulatif<\/p>\n            <\/div>\n            <div class=\"sub-summary\" id=\"sub-summary\" style=\"display:none;\">\n              <h3>R\u00e9capitulatif<\/h3>\n              <div class=\"sum-row\"><span class=\"sum-label\">Cat\u00e9gories<\/span><span class=\"sum-val\" id=\"sum-cats\">\u2014<\/span><\/div>\n              <div class=\"sum-row\"><span class=\"sum-label\">Ann\u00e9e<\/span><span class=\"sum-val\" id=\"sum-years\">\u2014<\/span><\/div>\n              <div class=\"sum-row sum-total-row\"><span class=\"sum-label\">Total<\/span><span class=\"sum-val sum-price\" id=\"sum-price\">\u2014<\/span><\/div>\n            <\/div>\n          <\/div>\n          <p class=\"sub-error\" id=\"sub-error\" style=\"display:none;\"><\/p>\n          <button class=\"button sub-btn\" id=\"sub-btn\" onclick=\"addToCart()\">\n            <span class=\"btn-text\">Ajouter au panier<\/span>\n            <span class=\"btn-loader\" style=\"display:none;\">\n              <svg class=\"icon-svg spinner\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><path d=\"M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83\"\/><\/svg>\n              Ajout en cours\u2026            <\/span>\n          <\/button>\n        <\/div>\n      <\/div>\n\n      <!-- \u2500\u2500 MY SUBSCRIPTIONS \u2500\u2500 -->\n      <div class=\"sub-panel\" id=\"tab-list\" style=\"display:none;\">\n                <div class=\"sub-empty\">\n          <svg class=\"icon-svg\" width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"><path d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2\"\/><rect x=\"9\" y=\"3\" width=\"6\" height=\"4\" rx=\"1\"\/><line x1=\"9\" y1=\"12\" x2=\"15\" y2=\"12\"\/><line x1=\"9\" y1=\"16\" x2=\"12\" y2=\"16\"\/><\/svg>\n          <h3>Aucun abonnement pour l'instant<\/h3>\n          <p>Vos abonnements actifs appara\u00eetront ici une fois votre achat finalis\u00e9.<\/p>\n          <button class=\"button sub-btn-outline\" onclick=\"switchTab('new', 0)\">Commencer un abonnement<\/button>\n        <\/div>\n              <\/div>\n\n      <!-- \u2500\u2500 CONTENT SECTION \u2500\u2500 -->\n      <div id=\"sub-content-section\" style=\"display:none;\">\n        <div class=\"sub-content-header\">\n          <div class=\"sub-content-title\">\n            <svg class=\"icon-svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M4 19.5A2.5 2.5 0 016.5 17H20\"\/><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z\"\/><\/svg>\n            <span id=\"sub-content-label\">Livres de l'abonnement<\/span>\n          <\/div>\n          <button class=\"sub-close-btn\" onclick=\"closeContent()\">\n            <svg class=\"icon-svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"\/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"\/><\/svg>\n            Fermer          <\/button>\n        <\/div>\n        <div id=\"sub-content-loading\" style=\"display:none;\">\n          <div class=\"sub-books-loading\">\n            <svg class=\"icon-svg spinner\" width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#1a5fb4\" stroke-width=\"2\"><path d=\"M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83\"\/><\/svg>\n            <p>Chargement de vos livres\u2026<\/p>\n          <\/div>\n        <\/div>\n        <div id=\"sub-content-main\" style=\"display:none;\">\n          <div class=\"sub-books-layout\">\n            <aside class=\"sub-filter-sidebar\">\n              <h4 class=\"filter-title\">Filtrer par cat\u00e9gorie<\/h4>\n              <ul class=\"filter-list\" id=\"filter-list\"><\/ul>\n            <\/aside>\n            <div class=\"sub-books-area\">\n              <div class=\"sub-books-count\" id=\"sub-books-count\"><\/div>\n              <div class=\"sub-books-grid\" id=\"sub-books-grid\"><\/div>\n              <div class=\"sub-books-empty\" id=\"sub-books-empty\" style=\"display:none;\">\n                <svg class=\"icon-svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\"><path d=\"M4 19.5A2.5 2.5 0 016.5 17H20\"\/><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z\"\/><\/svg>\n                <p>Aucun livre dans cette cat\u00e9gorie.<\/p>\n              <\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div><!-- \/.sub-wrap -->\n\n    <!-- \u2550\u2550 PDF READER \u2550\u2550 -->\n    <div id=\"sub-pdf-modal\" dir=\"ltr\" style=\"display:none;\">\n      <div class=\"pdf-modal-header\">\n        <div class=\"pdf-modal-title\">\n          <svg class=\"icon-svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M4 19.5A2.5 2.5 0 016.5 17H20\"\/><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z\"\/><\/svg>\n          <span id=\"pdf-title-text\">\u2014<\/span>\n        <\/div>\n        <div class=\"pdf-modal-actions\">\n          <span class=\"pdf-page-info\" id=\"pdf-page-info\" style=\"display:none;\">\n            Page <span id=\"pdf-current-page\">1<\/span> \/ <span id=\"pdf-total-pages\">\u2014<\/span>\n          <\/span>\n          <div class=\"pdf-print-btn-wrap\" id=\"pdf-print-btn-wrap\" style=\"display:none;\">\n            <button class=\"pdf-action-btn\" id=\"pdf-print-btn\" onclick=\"subOpenPrintDialog()\">\n              <svg class=\"icon-svg\" id=\"pdf-print-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"6 9 6 2 18 2 18 9\"\/><path d=\"M6 18H4a2 2 0 01-2-2v-5a2 2 0 012-2h16a2 2 0 012 2v5a2 2 0 01-2 2h-2\"\/><rect x=\"6\" y=\"14\" width=\"12\" height=\"8\"\/><\/svg>\n              <div class=\"pdf-print-btn-spinner\" id=\"pdf-print-btn-spinner\" style=\"display:none;\"><\/div>\n              <span id=\"pdf-print-btn-label\">Imprimer<\/span>\n            <\/button>\n            <div class=\"pdf-print-quota-tip\" id=\"pdf-print-quota-tip\"><\/div>\n          <\/div>\n          <button class=\"pdf-action-btn pdf-close\" onclick=\"closePdfModal()\">\n            <svg class=\"icon-svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"\/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"\/><\/svg>\n            Fermer le lecteur          <\/button>\n        <\/div>\n      <\/div>\n      <div class=\"pdf-modal-body\">\n        <div class=\"pdf-loading-overlay\" id=\"pdf-loading-overlay\">\n          <div class=\"pdf-load-spinner\"><\/div>\n          <p id=\"pdf-loading-msg\">Ouverture du livre\u2026<\/p>\n        <\/div>\n        <div class=\"pdf-error-box\" id=\"pdf-error-box\">\n          <svg class=\"icon-svg\" width=\"44\" height=\"44\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#e57373\" stroke-width=\"1.5\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"\/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"\/><\/svg>\n          <h3>Impossible d'ouvrir ce livre<\/h3>\n          <p id=\"pdf-error-msg\">Le fichier n'a pas pu \u00eatre charg\u00e9.<\/p>\n          <div class=\"pdf-error-actions\">\n            <button class=\"pdf-error-btn\" onclick=\"closePdfModal()\">\n              <svg class=\"icon-svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"\/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"\/><\/svg>\n              Fermer            <\/button>\n          <\/div>\n        <\/div>\n        <div class=\"pdf-bookmarks-sidebar\" id=\"pdf-bookmarks-sidebar\" style=\"display:none;\">\n          <div class=\"pdf-bookmarks-title\">\n            <svg class=\"icon-svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M19 21l-7-5-7 5V5a2 2 0 012-2h10a2 2 0 012 2z\"\/><\/svg>\n            Sommaire          <\/div>\n          <ul class=\"pdf-bookmarks-list\" id=\"pdf-bookmarks-list\"><\/ul>\n        <\/div>\n        <div class=\"pdf-canvas-area\" id=\"pdf-canvas-area\" style=\"display:none;\">\n          <div class=\"pdf-nav-bar\">\n            <span class=\"pdf-nav-label\">Page <span id=\"pdf-nav-current\">1<\/span> \/ <span id=\"pdf-nav-total\">\u2014<\/span><\/span>\n            <div class=\"pdf-zoom-controls\">\n              <button class=\"pdf-nav-btn\" id=\"pdf-zoom-out-btn\" onclick=\"subZoom(-0.1)\">\n                <svg class=\"icon-svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><circle cx=\"11\" cy=\"11\" r=\"8\"\/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"\/><line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\"\/><\/svg>\n              <\/button>\n              <span id=\"pdf-zoom-label\" class=\"pdf-zoom-label\">50%<\/span>\n              <button class=\"pdf-nav-btn\" id=\"pdf-zoom-in-btn\" onclick=\"subZoom(0.1)\">\n                <svg class=\"icon-svg\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><circle cx=\"11\" cy=\"11\" r=\"8\"\/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"\/><line x1=\"11\" y1=\"8\" x2=\"11\" y2=\"14\"\/><line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\"\/><\/svg>\n              <\/button>\n            <\/div>\n            <div class=\"pdf-goto-wrap\">\n              <span class=\"pdf-nav-label\">Aller \u00e0<\/span>\n              <input type=\"number\" id=\"pdf-page-input\" min=\"1\" value=\"1\" class=\"pdf-page-jump-input\"\n                     onkeydown=\"if(event.key==='Enter') subScrollToPage(parseInt(this.value))\">\n              <button class=\"pdf-nav-btn\" onclick=\"subScrollToPage(parseInt(document.getElementById('pdf-page-input').value))\">\n                <svg class=\"icon-svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"9 18 15 12 9 6\"\/><\/svg>\n              <\/button>\n            <\/div>\n          <\/div>\n          <div class=\"pdf-scroll-viewport\" id=\"pdf-scroll-viewport\"><\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- \u2550\u2550 PRINT DIALOG \u2550\u2550 -->\n    <div id=\"pdf-print-dialog\" dir=\"ltr\" style=\"display:none;\">\n      <div class=\"pdf-print-dialog-box\">\n        <div class=\"pdf-print-dialog-header\">\n          <svg class=\"icon-svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"6 9 6 2 18 2 18 9\"\/><path d=\"M6 18H4a2 2 0 01-2-2v-5a2 2 0 012-2h16a2 2 0 012 2v5a2 2 0 01-2 2h-2\"\/><rect x=\"6\" y=\"14\" width=\"12\" height=\"8\"\/><\/svg>\n          Imprimer les pages        <\/div>\n        <div class=\"pdf-print-quota-bar\" id=\"pdf-print-quota-bar\"><\/div>\n        <p class=\"pdf-print-dialog-info\">Cliquez sur les miniatures pour les s\u00e9lectionner. <strong id=\"pdf-print-left-label\">\u2014<\/strong> pages restantes dans votre quota d'impression pour ce livre.<\/p>\n        <div class=\"pdf-print-thumbs\" id=\"pdf-print-thumbs\"><\/div>\n        <div class=\"pdf-print-dialog-footer\">\n          <span id=\"pdf-print-count\" class=\"pdf-print-count\">0 s\u00e9lectionn\u00e9(s)<\/span>\n          <div style=\"display:flex;gap:8px;\">\n            <button class=\"pdf-error-btn\" onclick=\"subClosePrintDialog()\">Annuler<\/button>\n            <button class=\"pdf-print-confirm-btn\" id=\"pdf-print-confirm\" onclick=\"subExecutePrint()\" disabled>\n              <svg class=\"icon-svg\" id=\"pdf-confirm-icon\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><polyline points=\"6 9 6 2 18 2 18 9\"\/><path d=\"M6 18H4a2 2 0 01-2-2v-5a2 2 0 012-2h16a2 2 0 012 2v5a2 2 0 01-2 2h-2\"\/><rect x=\"6\" y=\"14\" width=\"12\" height=\"8\"\/><\/svg>\n              <div class=\"pdf-print-btn-spinner\" id=\"pdf-confirm-spinner\" style=\"display:none;\"><\/div>\n              <span id=\"pdf-confirm-label\">Imprimer la s\u00e9lection<\/span>\n            <\/button>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <style>\n      .sub-wrap svg,.sub-wrap svg * { width:auto!important;height:auto!important; }\n      #sub-pdf-modal svg,#sub-pdf-modal svg * { width:auto!important;height:auto!important; }\n      #pdf-print-dialog svg,#pdf-print-dialog svg * { width:auto!important;height:auto!important; }\n      .sub-wrap .icon-svg,#sub-pdf-modal .icon-svg,#pdf-print-dialog .icon-svg { flex-shrink:0; }\n\n      [dir=\"rtl\"] .sub-tabs           { flex-direction:row-reverse; }\n      [dir=\"rtl\"] .sum-row            { flex-direction:row-reverse; }\n      [dir=\"rtl\"] .sub-content-header { flex-direction:row-reverse; }\n      [dir=\"rtl\"] .sub-books-layout   { flex-direction:row-reverse; }\n      [dir=\"rtl\"] .sub-filter-sidebar { border-right:none; border-left:1px solid #eee; }\n      [dir=\"rtl\"] .filter-list li a   { border-left:none; border-right:3px solid transparent; }\n      [dir=\"rtl\"] .filter-list li a.active { border-left-color:transparent; border-right-color:#1a5fb4; }\n      [dir=\"rtl\"] .sub-table          { direction:rtl; }\n      [dir=\"rtl\"] .sub-table th,[dir=\"rtl\"] .sub-table td { text-align:right; }\n      [dir=\"rtl\"] .pdf-bookmarks-list li a { border-left:none; border-right:3px solid transparent; }\n      [dir=\"rtl\"] .pdf-bookmarks-list li a.active { border-right-color:#1a5fb4; border-left-color:transparent; }\n\n      .sub-wrap { max-width:900px; font-family:inherit; }\n      .sub-tabs { display:flex; gap:4px; border-bottom:2px solid #e8e8e8; }\n      .sub-tab  { display:inline-flex; align-items:center; justify-content:center; gap:7px; padding:11px 20px; background:none; border:none; font-size:.93em; font-weight:600; color:#888; cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-2px; border-radius:4px 4px 0 0; transition:color .2s,border-color .2s; flex:1; }\n      .sub-tab:hover { color:#1a5fb4; }\n      .sub-tab.active { color:#1a5fb4; border-bottom-color:#1a5fb4; background:#f0f6ff; }\n      .sub-badge { background:#1a5fb4; color:#fff; font-size:.72em; font-weight:700; padding:1px 6px; border-radius:10px; line-height:1.5; }\n      .sub-panel { padding:28px; border:1px solid #e8e8e8; border-top:none; border-radius:0 0 8px 8px; background:#fff; }\n      .sub-field { margin-bottom:20px; }\n      .sub-field > label { display:block; font-weight:600; margin-bottom:7px; font-size:.95em; }\n      .sub-hint { font-weight:400; color:#999; font-size:.88em; }\n      .dropdown-check-list { position:relative; }\n      .dropdown-check-list .anchor { display:flex; align-items:center; justify-content:space-between; padding:9px 13px; border:1.5px solid #d0d0d0; border-radius:6px; cursor:pointer; background:#fff; font-size:.94em; color:#333; transition:border-color .2s; user-select:none; }\n      .dropdown-check-list .anchor:hover { border-color:#1a5fb4; }\n      .anchor-icon { flex-shrink:0; transition:transform .2s; }\n      .dropdown-open .anchor-icon { transform:rotate(180deg); }\n      .dropdown-check-list .items { position:absolute; z-index:999; background:#fff; border:1.5px solid #d0d0d0; border-radius:6px; width:100%; max-height:230px; overflow-y:auto; padding:6px 0; box-shadow:0 6px 20px rgba(0,0,0,.09); margin-top:4px; }\n      .check-item { display:flex; align-items:center; gap:10px; padding:8px 14px; cursor:pointer; font-size:.93em; transition:background .15s; }\n      .check-item:hover { background:#f0f6ff; }\n      .check-item input[type=\"checkbox\"] { accent-color:#1a5fb4; width:15px; height:15px; cursor:pointer; flex-shrink:0; }\n      .check-all-item { background:#fafafa; }\n      .items-divider { height:1px; background:#eee; margin:4px 0; }\n      select#sub-years { width:100%; padding:9px 13px; border:1.5px solid #d0d0d0; border-radius:6px; font-size:.94em; background:#fff; cursor:pointer; transition:border-color .2s; }\n      select#sub-years:focus { outline:none; border-color:#1a5fb4; }\n      .sub-summary-wrap { min-height:130px; margin:4px 0 20px; }\n      .sub-placeholder { min-height:130px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; border:1.5px dashed #ddd; border-radius:8px; color:#aaa; text-align:center; padding:18px; }\n      .sub-placeholder p { margin:0; font-size:.88em; line-height:1.6; }\n      .sub-summary { background:#f0f6ff; padding:16px 18px; border-radius:8px; border:1px solid #c5daf5; }\n      .sub-summary h3 { margin:0 0 12px; font-size:.95em; color:#1a5fb4; text-transform:uppercase; letter-spacing:.05em; }\n      .sum-row { display:flex; justify-content:space-between; align-items:baseline; padding:5px 0; font-size:.93em; }\n      .sum-row + .sum-row { border-top:1px solid #dceeff; }\n      .sum-label { color:#666; }\n      .sum-val { font-weight:600; color:#222; text-align:right; max-width:60%; }\n      .sum-total-row { margin-top:6px; padding-top:10px!important; border-top:2px solid #b8d4f5!important; }\n      .sum-price { font-size:1.15em; color:#1a5fb4; direction:ltr; unicode-bidi:plaintext; }\n      .sub-error { color:#c0392b; font-size:.88em; background:#fdf0ef; border:1px solid #f5c6c2; border-radius:5px; padding:8px 12px; margin-bottom:14px; }\n      .sub-btn { display:inline-flex; align-items:center; justify-content:center; gap:8px; background:#1a5fb4; color:#fff!important; padding:12px 30px; font-size:.97em; font-weight:600; border:none; cursor:pointer; border-radius:6px; width:100%; transition:background .2s,opacity .2s; }\n      .sub-btn:hover:not(:disabled) { background:#164a8a; }\n      .sub-btn:disabled { opacity:.65; cursor:not-allowed; }\n      .sub-btn-outline { display:inline-flex; align-items:center; justify-content:center; background:none; color:#1a5fb4!important; padding:10px 24px; font-size:.93em; font-weight:600; border:2px solid #1a5fb4; border-radius:6px; cursor:pointer; margin-top:14px; transition:background .2s,color .2s; }\n      .sub-btn-outline:hover { background:#1a5fb4; color:#fff!important; }\n      @keyframes sub-spin { to { transform:rotate(360deg); } }\n      .sub-wrap .spinner { animation:sub-spin .7s linear infinite; }\n      .sub-table-wrap { overflow-x:auto; }\n      .sub-table { width:100%; border-collapse:collapse; font-size:.9em; }\n      .sub-table th { background:#f0f6ff; color:#1a5fb4; font-weight:700; padding:10px 13px; text-align:left; font-size:.85em; text-transform:uppercase; letter-spacing:.04em; border-bottom:2px solid #c5daf5; }\n      .sub-table td { padding:11px 13px; border-bottom:1px solid #eee; color:#333; vertical-align:middle; }\n      .sub-table tr:last-child td { border-bottom:none; }\n      .sub-table tr:hover td { background:#f5f8ff; }\n      .sub-table tr.sub-row-active td { background:#eef4ff; }\n      .sub-table a { color:#1a5fb4; font-weight:600; text-decoration:none; }\n      .sub-table a:hover { text-decoration:underline; }\n      .sub-cats-cell { max-width:200px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }\n      .sub-status { display:inline-block; padding:3px 9px; border-radius:20px; font-size:.82em; font-weight:600; text-transform:capitalize; }\n      .sub-status-completed { background:#e3eeff; color:#1a5fb4; }\n      .sub-status-processing { background:#fff3cd; color:#856404; }\n      .sub-status-cancelled  { background:#fde8e8; color:#c0392b; }\n      .sub-view-btn { display:inline-flex; align-items:center; gap:6px; padding:6px 13px; border:1.5px solid #1a5fb4; border-radius:5px; background:#fff; color:#1a5fb4; font-size:.84em; font-weight:600; cursor:pointer; white-space:nowrap; transition:background .18s,color .18s; }\n      .sub-view-btn:hover,.sub-view-btn.active { background:#1a5fb4; color:#fff; }\n      .sub-empty { display:flex; flex-direction:column; align-items:center; justify-content:center; padding:40px 20px; text-align:center; color:#aaa; }\n      .sub-empty h3 { color:#555; margin:14px 0 6px; font-size:1.05em; }\n      .sub-empty p  { margin:0; font-size:.9em; line-height:1.6; }\n      #sub-content-section { margin-top:20px; border:1.5px solid #c5daf5; border-radius:8px; background:#fff; overflow:hidden; }\n      .sub-content-header { display:flex; align-items:center; justify-content:space-between; padding:14px 20px; background:#f0f6ff; border-bottom:1px solid #c5daf5; }\n      .sub-content-title { display:flex; align-items:center; gap:8px; font-weight:700; font-size:.97em; color:#1a5fb4; }\n      .sub-close-btn { display:inline-flex; align-items:center; gap:5px; background:none; border:1.5px solid #ccc; border-radius:5px; padding:5px 12px; font-size:.84em; color:#666; cursor:pointer; transition:border-color .18s,color .18s; }\n      .sub-close-btn:hover { border-color:#c0392b; color:#c0392b; }\n      .sub-books-loading { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:12px; padding:50px 20px; color:#1a5fb4; font-size:.93em; }\n      .sub-books-loading p { margin:0; }\n      .sub-books-layout { display:flex; min-height:300px; width:100%; }\n      .sub-filter-sidebar { width:190px; flex-shrink:0; border-right:1px solid #eee; padding:20px 0; }\n      .filter-title { font-size:.8em; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:#999; padding:0 18px 10px; margin:0; }\n      .filter-list { list-style:none; margin:0; padding:0; }\n      .filter-list li a { display:block; padding:8px 18px; font-size:.9em; color:#444; text-decoration:none; border-left:3px solid transparent; cursor:pointer; transition:background .15s,color .15s; }\n      .filter-list li a:hover { background:#f0f6ff; color:#1a5fb4; }\n      .filter-list li a.active { background:#e8f0ff; color:#1a5fb4; font-weight:700; border-left-color:#1a5fb4; }\n      .filter-count { display:inline-block; margin-left:5px; font-size:.78em; color:#aaa; font-weight:400; }\n      .sub-books-area { flex:1; padding:20px; min-width:0; overflow:hidden; }\n      .sub-books-count { font-size:.84em; color:#999; margin-bottom:14px; }\n      .sub-books-grid { display:grid; grid-template-columns:repeat(4,1fr); gap:18px; }\n      .sub-book-card { border:1px solid #eee; border-radius:8px; overflow:hidden; background:#fff; display:flex; flex-direction:column; transition:box-shadow .18s,transform .18s; }\n      .sub-book-card:hover { box-shadow:0 6px 20px rgba(0,0,0,.1); transform:translateY(-2px); }\n      .sub-book-img-wrap { position:relative; aspect-ratio:3\/4; overflow:hidden; background:#f5f5f5; }\n      .sub-book-img { width:100%; height:100%; object-fit:cover; display:block; }\n      .sub-book-info { padding:10px 10px 12px; display:flex; flex-direction:column; flex:1; gap:6px; }\n      .sub-book-title { font-size:.85em; font-weight:600; color:#222; line-height:1.35; margin:0; }\n      .sub-book-cat { font-size:.75em; color:#999; margin:0; flex:1; }\n      .sub-read-btn { display:inline-flex; align-items:center; justify-content:center; gap:6px; margin-top:6px; padding:7px 0; width:100%; background:#1a5fb4; color:#fff; font-size:.82em; font-weight:600; border:none; border-radius:5px; cursor:pointer; transition:background .18s; }\n      .sub-read-btn:hover { background:#164a8a; color:#fff; }\n      .sub-read-btn-disabled { display:inline-flex; align-items:center; justify-content:center; gap:6px; margin-top:6px; padding:7px 0; width:100%; background:#eee; color:#aaa; font-size:.82em; font-weight:600; border:none; border-radius:5px; cursor:not-allowed; }\n      .sub-tooltip-wrap { position:relative; display:block; margin-top:6px; }\n      .sub-tooltip-wrap .sub-read-btn-disabled { margin-top:0; width:100%; }\n      .sub-tooltip-wrap:hover .sub-tooltip { opacity:1; transform:translateX(-50%) translateY(0); pointer-events:auto; }\n      .sub-tooltip { position:absolute; bottom:calc(100% + 8px); left:50%; transform:translateX(-50%) translateY(4px); width:220px; background:#222; color:#f0f0f0; font-size:.78em; line-height:1.5; padding:9px 12px; border-radius:6px; text-align:center; opacity:0; pointer-events:none; transition:opacity .2s,transform .2s; z-index:999; box-shadow:0 4px 16px rgba(0,0,0,.25); white-space:pre-line; }\n      .sub-tooltip::after { content:''; position:absolute; top:100%; left:50%; transform:translateX(-50%); border:6px solid transparent; border-top-color:#222; }\n      .sub-books-empty { display:flex; flex-direction:column; align-items:center; gap:10px; padding:40px 20px; color:#bbb; text-align:center; }\n      .sub-books-empty p { margin:0; font-size:.9em; }\n\n      #sub-pdf-modal { position:fixed; inset:0; z-index:999999; background:#1a1a1a; display:flex; flex-direction:column; }\n      .pdf-modal-header { display:flex; align-items:center; justify-content:space-between; padding:10px 16px; background:#111; border-bottom:1px solid #333; flex-shrink:0; gap:12px; }\n      .pdf-modal-title { display:flex; align-items:center; gap:10px; color:#e8e8e8; font-weight:700; font-size:.97em; flex:1; min-width:0; }\n      .pdf-modal-title span { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }\n      .pdf-modal-actions { display:flex; align-items:center; gap:8px; flex-shrink:0; }\n      .pdf-page-info { color:#888; font-size:.82em; padding:0 6px; white-space:nowrap; }\n      .pdf-action-btn { display:inline-flex; align-items:center; gap:6px; padding:7px 14px; border-radius:5px; font-size:.84em; font-weight:600; cursor:pointer; transition:background .18s,color .18s; border:1.5px solid #444; background:#222; color:#ccc; }\n      .pdf-action-btn:hover:not(:disabled) { background:#333; color:#fff; border-color:#666; }\n      .pdf-action-btn:disabled { opacity:.5; cursor:not-allowed; }\n      .pdf-close { border-color:#c0392b; color:#e57373; }\n      .pdf-close:hover { background:#c0392b; color:#fff; border-color:#c0392b; }\n      .pdf-modal-body { flex:1; display:flex; overflow:hidden; position:relative; }\n      .pdf-loading-overlay { position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px; background:#1e1e1e; color:#ccc; font-size:.93em; z-index:20; }\n      .pdf-load-spinner { width:36px; height:36px; border:3px solid #444; border-top-color:#1a5fb4; border-radius:50%; animation:sub-spin .8s linear infinite; }\n      .pdf-loading-overlay p { margin:0; opacity:.8; }\n      .pdf-error-box { position:absolute; inset:0; display:none; flex-direction:column; align-items:center; justify-content:center; gap:16px; background:#1e1e1e; color:#ccc; text-align:center; padding:30px; z-index:20; }\n      .pdf-error-box h3 { margin:0; font-size:1em; color:#e57373; }\n      .pdf-error-box p  { margin:0; font-size:.87em; line-height:1.6; opacity:.75; max-width:360px; }\n      .pdf-error-actions { display:flex; gap:10px; flex-wrap:wrap; justify-content:center; }\n      .pdf-error-btn { display:inline-flex; align-items:center; gap:6px; padding:8px 16px; border-radius:5px; font-size:.84em; font-weight:600; cursor:pointer; border:1.5px solid #555; background:#2a2a2a; color:#ccc; transition:background .18s,border-color .18s; }\n      .pdf-error-btn:hover { background:#333; border-color:#777; color:#fff; }\n      .pdf-bookmarks-sidebar { width:220px; flex-shrink:0; background:#1a1a1a; border-right:1px solid #333; display:flex; flex-direction:column; overflow:hidden; }\n      .pdf-bookmarks-title { display:flex; align-items:center; gap:7px; padding:12px 14px; font-size:.8em; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:#777; border-bottom:1px solid #2a2a2a; flex-shrink:0; }\n      .pdf-bookmarks-list { list-style:none; margin:0; padding:6px 0; overflow-y:auto; flex:1; }\n      .pdf-bookmarks-list li a { display:block; padding:7px 14px; font-size:.84em; color:#aaa; text-decoration:none; border-left:3px solid transparent; cursor:pointer; transition:background .15s,color .15s; line-height:1.4; }\n      .pdf-bookmarks-list li a:hover { background:#222; color:#fff; }\n      .pdf-bookmarks-list li a.active { background:#1e2a3e; color:#6db3f2; border-left-color:#1a5fb4; }\n      .pdf-bookmarks-list li ul { list-style:none; padding:0; margin:0; }\n      .pdf-canvas-area { flex:1; display:flex; flex-direction:column; overflow:hidden; }\n      .pdf-nav-bar { display:flex; align-items:center; gap:12px; padding:8px 14px; background:#161616; border-bottom:1px solid #2a2a2a; flex-shrink:0; flex-wrap:wrap; }\n      .pdf-nav-btn { display:inline-flex; align-items:center; justify-content:center; padding:5px 8px; background:#222; border:1.5px solid #444; border-radius:5px; color:#ccc; cursor:pointer; transition:background .15s,color .15s; }\n      .pdf-nav-btn:hover:not(:disabled) { background:#333; color:#fff; }\n      .pdf-nav-btn:disabled { opacity:.35; cursor:not-allowed; }\n      .pdf-nav-label { color:#aaa; font-size:.85em; display:flex; align-items:center; gap:5px; white-space:nowrap; }\n      .pdf-goto-wrap { display:flex; align-items:center; gap:5px; }\n      .pdf-page-jump-input { width:46px; padding:3px 6px; background:#222; border:1.5px solid #444; border-radius:4px; color:#eee; font-size:.9em; text-align:center; -moz-appearance:textfield; }\n      .pdf-page-jump-input::-webkit-outer-spin-button,.pdf-page-jump-input::-webkit-inner-spin-button { -webkit-appearance:none; }\n      .pdf-zoom-controls { display:flex; align-items:center; gap:6px; }\n      .pdf-zoom-label { color:#777; font-size:.82em; min-width:38px; text-align:center; }\n      .pdf-scroll-viewport { flex:1; overflow-y:auto; overflow-x:auto; background:#2a2a2a; padding:20px; display:flex; flex-direction:column; align-items:center; gap:16px; -webkit-user-select:none; user-select:none; }\n      .pdf-page-wrapper { position:relative; flex-shrink:0; box-shadow:0 4px 24px rgba(0,0,0,.5); }\n      .pdf-page-wrapper canvas { display:block; }\n      .pdf-page-label { position:absolute; bottom:8px; right:10px; background:rgba(0,0,0,.55); color:#ccc; font-size:.72em; padding:2px 7px; border-radius:10px; pointer-events:none; }\n      .pdf-print-btn-wrap { position:relative; display:inline-flex; }\n      .pdf-print-quota-tip { display:none; position:absolute; top:calc(100% + 8px); right:0; background:#222; color:#f0f0f0; font-size:.78em; line-height:1.5; padding:8px 12px; border-radius:6px; white-space:nowrap; box-shadow:0 4px 16px rgba(0,0,0,.4); z-index:10; border:1px solid #444; }\n      .pdf-print-quota-tip::before { content:''; position:absolute; bottom:100%; right:18px; border:6px solid transparent; border-bottom-color:#444; }\n      .pdf-print-btn-wrap:hover .pdf-print-quota-tip { display:block; }\n      .pdf-print-btn-spinner { width:14px; height:14px; border:2px solid #555; border-top-color:#ccc; border-radius:50%; animation:sub-spin .7s linear infinite; flex-shrink:0; }\n      #pdf-print-dialog { position:fixed; inset:0; z-index:9999999; background:rgba(0,0,0,.75); display:flex; align-items:center; justify-content:center; }\n      .pdf-print-dialog-box { background:#1e1e1e; border:1px solid #333; border-radius:10px; width:min(92vw,700px); max-height:85vh; display:flex; flex-direction:column; overflow:hidden; box-shadow:0 20px 60px rgba(0,0,0,.6); }\n      .pdf-print-dialog-header { display:flex; align-items:center; gap:10px; padding:16px 20px; border-bottom:1px solid #333; font-size:1em; font-weight:700; color:#e8e8e8; flex-shrink:0; }\n      .pdf-print-quota-bar { padding:10px 20px 0; flex-shrink:0; }\n      .pdf-print-quota-track { height:6px; background:#333; border-radius:3px; overflow:hidden; }\n      .pdf-print-quota-fill { height:100%; background:#1a5fb4; border-radius:3px; transition:width .3s; }\n      .pdf-print-quota-fill.warn   { background:#e67e22; }\n      .pdf-print-quota-fill.danger { background:#c0392b; }\n      .pdf-print-dialog-info { padding:8px 20px; font-size:.87em; color:#aaa; margin:0; flex-shrink:0; }\n      .pdf-print-dialog-info strong { color:#e8e8e8; }\n      .pdf-print-thumbs { flex:1; overflow-y:auto; padding:16px 20px; display:grid; grid-template-columns:repeat(3,1fr); gap:16px; }\n      .pdf-print-thumb { position:relative; cursor:pointer; border-radius:6px; overflow:hidden; border:2px solid transparent; transition:border-color .15s,transform .15s; background:#fff; width:100%; height:220px; }\n      .pdf-print-thumb:hover { border-color:#555; transform:scale(1.02); }\n      .pdf-print-thumb.selected { border-color:#1a5fb4; }\n      .pdf-print-thumb.quota-disabled { opacity:.4; cursor:not-allowed; }\n      .pdf-print-thumb.quota-disabled:hover { transform:none; border-color:transparent; }\n      .pdf-print-thumb canvas { display:block; width:100%; height:100%; object-fit:contain; }\n      .pdf-print-thumb-label { position:absolute; bottom:0; left:0; right:0; text-align:center; font-size:.78em; padding:5px; background:rgba(0,0,0,.65); color:#fff; font-weight:600; }\n      .pdf-print-thumb .pdf-thumb-check { display:none; position:absolute; top:6px; right:6px; width:22px; height:22px; background:#1a5fb4; border-radius:50%; align-items:center; justify-content:center; box-shadow:0 2px 6px rgba(0,0,0,.4); z-index:5; }\n      .pdf-print-thumb.selected .pdf-thumb-check { display:flex; }\n      .pdf-print-thumb .pdf-thumb-check::after { content:''; width:5px; height:9px; border:2px solid #fff; border-top:none; border-left:none; transform:rotate(45deg) translate(-1px,-1px); display:block; }\n      .pdf-print-dialog-footer { display:flex; align-items:center; justify-content:space-between; padding:14px 20px; border-top:1px solid #333; flex-shrink:0; }\n      .pdf-print-count { font-size:.85em; color:#888; }\n      .pdf-print-confirm-btn { display:inline-flex; align-items:center; gap:6px; padding:8px 18px; background:#1a5fb4; color:#fff; border:none; border-radius:5px; font-size:.88em; font-weight:600; cursor:pointer; transition:background .18s; }\n      .pdf-print-confirm-btn:hover:not(:disabled) { background:#164a8a; }\n      .pdf-print-confirm-btn:disabled { opacity:.4; cursor:not-allowed; }\n\n      @media (max-width:700px) {\n        .pdf-bookmarks-sidebar { display:none!important; }\n        .sub-filter-sidebar { width:120px; }\n        .sub-books-grid { grid-template-columns:repeat(2,1fr); }\n        .pdf-modal-title span { display:none; }\n        .pdf-print-thumbs { grid-template-columns:repeat(2,1fr); }\n      }\n    <\/style>\n\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.min.js\"><\/script>\n    <script>\n      pdfjsLib.GlobalWorkerOptions.workerSrc = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.worker.min.js';\n\n      const PRICE_PER        = 15; \/\/ fallback only\n      const CAT_PRICES       = {\"22\":15,\"27\":15,\"28\":15,\"343\":21}; \/\/ {term_id: price}\n      const ALL_CATS_PRICE   = 0;          \/\/ flat \"all\" price, 0 = sum\n      const PRODUCT_ID       = 16821;\n      const MAX_CATS         = 4;\n     const TOTAL_CATS       = 4; \/\/ only visible categories\n      const AJAX_URL         = 'https:\/\/www.cejj-justice.tn\/wp-admin\/admin-ajax.php';\n      const SUB_NONCE        = '2b9af13538';\n      const PRINT_PAGE_LIMIT = 10;\n      const PDF_SCALE_MIN    = 0.3;\n      const PDF_SCALE_MAX    = 3.0;\n      const LANG             = 'fr';\n\n      const T = {\n        allCategories    : \"Toutes les cat\\u00e9gories\",\n        selectCats       : \"S\\u00e9lectionner des cat\\u00e9gories\",\n        yearSuffix1      : \"an\",\n        yearSuffixN      : \"ans\",\n        errSelectCat     : \"Veuillez s\\u00e9lectionner au moins une cat\\u00e9gorie.\",\n        errMaxCats       : \"Vous pouvez s\\u00e9lectionner jusqu'\\u00e0 4 cat\\u00e9gories (ou choisir Tout).\",\n        errAddCart       : \"Erreur lors de l'ajout. Veuillez r\\u00e9essayer.\",\n        errNetwork       : \"Erreur r\\u00e9seau. Veuillez r\\u00e9essayer.\",\n        addingToCart     : \"Ajout en cours\\u2026\",\n        booksOrder       : \"Livres \\u2014 Commande #\",\n        all              : \"Tout\",\n        bookFound1       : \"1 livre trouv\\u00e9\",\n        booksFoundN      : \"livres trouv\\u00e9s\",\n        read             : \"Lire\",\n        noFile           : \"Aucun fichier\",\n        archiveTooltip   : \"Ce livre est disponible en archive compress\\u00e9e (.zip\\\/.rar).\\\\nLa lecture en ligne n'est pas prise en charge.\\\\nVeuillez contacter le support pour demander une version PDF.\",\n        couldNotLoad     : \"Impossible de charger le contenu de l'abonnement.\",\n        openingBook      : \"Ouverture du livre\\u2026\",\n        loadingFromCache : \"Chargement depuis le cache\\u2026\",\n        renderingPage    : \"Rendu de la page\",\n        of               : \"sur\",\n        page             : \"Page\",\n        print            : \"Imprimer\",\n        opening          : \"Ouverture\\u2026\",\n        quotaTipLeftAr   : \"\",\n        quotaTipLeftFr   : \"Il reste %d pages \\u00e0 imprimer sur %d\",\n        quotaTipUsed     : \"Vous avez utilis\\u00e9 toutes les\",\n        quotaTipUsed2    : \"pages d'impression pour ce livre.\",\n        pagesRemaining   : \"pages restantes dans votre quota d'impression pour ce livre.\",\n        selected         : \"s\\u00e9lectionn\\u00e9(s)\",\n        printSelected    : \"Imprimer la s\\u00e9lection\",\n        preparing        : \"Pr\\u00e9paration\\u2026\",\n        printQuotaErr    : \"Erreur de quota d'impression : \",\n        quotaVerifyErr   : \"Impossible de v\\u00e9rifier le quota d'impression. Veuillez r\\u00e9essayer.\",\n        renderErr        : \"Impossible de pr\\u00e9parer les pages pour l'impression.\",\n        cancel           : \"Annuler\",\n      };\n\n      let currentOrderId = null, allBooks = [], allCategories = [];\n      let pdfDoc = null, pdfScale = 0.5;\n      const pdfCache = new Map();\n      let pdfPageObserver = null, pdfVisiblePage = 1;\n      let printSelected = new Set(), currentProductId = null, printQuotaLeft = PRINT_PAGE_LIMIT;\n      const quotaCache = new Map();\n\n      \/\/ \u2500\u2500 Tabs \u2500\u2500\n      function switchTab(id, idx) {\n        document.querySelectorAll('.sub-panel').forEach(p => p.style.display = 'none');\n        document.querySelectorAll('.sub-tab').forEach(t => t.classList.remove('active'));\n        document.getElementById('tab-' + id).style.display = 'block';\n        document.querySelectorAll('.sub-tab')[idx].classList.add('active');\n        closeContent();\n      }\n\n      \/\/ \u2500\u2500 Dropdown \u2500\u2500\n      function toggleDropdown() {\n        const items = document.getElementById('cat-items');\n        const dd    = document.getElementById('cat-dropdown');\n        const open  = items.style.display !== 'none';\n        items.style.display = open ? 'none' : 'block';\n        dd.classList.toggle('dropdown-open', !open);\n      }\n      document.addEventListener('click', function(e) {\n        const dd = document.getElementById('cat-dropdown');\n        if (dd && !dd.contains(e.target)) { document.getElementById('cat-items').style.display = 'none'; dd.classList.remove('dropdown-open'); }\n      });\n      function toggleAll(cb) {\n        document.querySelectorAll('.cat-check').forEach(c => { c.checked = cb.checked; });\n        updateSummary();\n      }\n\n      \/\/ [CHANGED] calcTotal: price is flat per year, no multiplier\n      function calcTotal(checked, allCb) {\n        if (allCb.checked && ALL_CATS_PRICE > 0) return ALL_CATS_PRICE;\n        return checked.reduce((sum, c) => sum + (CAT_PRICES[c.value] || PRICE_PER), 0);\n      }\n\n      \/\/ \u2500\u2500 Summary \u2500\u2500\n      function updateSummary() {\n        const checked = [...document.querySelectorAll('.cat-check:checked')];\n        const allCb   = document.getElementById('check-all');\n        \/\/ [CHANGED] selYear is a calendar year string e.g. \"2026\"\n        const selYear = document.getElementById('sub-years').value;\n        const errEl   = document.getElementById('sub-error');\n        if (!allCb.checked && checked.length > MAX_CATS) {\n          if (event && event.target && event.target.classList.contains('cat-check')) event.target.checked = false;\n          errEl.textContent = T.errMaxCats; errEl.style.display = 'block'; updateSummary(); return;\n        } else { errEl.style.display = 'none'; }\n        allCb.checked = (checked.length === TOTAL_CATS);\n        const anchorText = document.getElementById('anchor-text');\n        if (checked.length === 0)   anchorText.textContent = T.selectCats;\n        else if (allCb.checked)     anchorText.textContent = T.allCategories;\n        else                        anchorText.textContent = checked.map(c => c.dataset.name).join(', ');\n        if (checked.length === 0) {\n          document.getElementById('sub-summary').style.display     = 'none';\n          document.getElementById('sub-placeholder').style.display = 'flex'; return;\n        }\n        \/\/ [CHANGED] flat price, no multiplier\n        const total    = calcTotal(checked, allCb);\n        const catNames = allCb.checked ? T.allCategories : checked.map(c => c.dataset.name).join(', ');\n        document.getElementById('sum-cats').textContent  = catNames;\n        \/\/ [CHANGED] Show the year directly, not \"N year(s)\"\n        document.getElementById('sum-years').textContent = selYear;\n        const priceEl = document.getElementById('sum-price');\n        priceEl.textContent      = total.toFixed(2) + '\\u00A0TND';\n        priceEl.style.direction  = 'ltr';\n        priceEl.style.unicodeBidi= 'plaintext';\n        document.getElementById('sub-summary').style.display     = 'block';\n        document.getElementById('sub-placeholder').style.display = 'none';\n      }\n\n      \/\/ \u2500\u2500 Add to cart \u2500\u2500\n      function addToCart() {\n        const checked = [...document.querySelectorAll('.cat-check:checked')];\n        const allCb   = document.getElementById('check-all');\n        \/\/ [CHANGED] selYear is a calendar year (e.g. \"2026\"), not a duration count\n        const selYear = document.getElementById('sub-years').value;\n        const errEl   = document.getElementById('sub-error');\n        const btn     = document.getElementById('sub-btn');\n        if (checked.length === 0) { errEl.textContent = T.errSelectCat; errEl.style.display = 'block'; return; }\n        btn.disabled = true;\n        btn.querySelector('.btn-text').style.display   = 'none';\n        btn.querySelector('.btn-loader').style.display = 'flex';\n        const catIds   = checked.map(c => c.value).join(',');\n        const catNames = allCb.checked ? 'All' : checked.map(c => c.dataset.name).join('|');\n        const total    = calcTotal(checked, allCb).toFixed(2); \/\/ [CHANGED] no multiplier\n        fetch(AJAX_URL, {\n          method: 'POST', headers: { 'Content-Type': 'application\/x-www-form-urlencoded' },\n          body: new URLSearchParams({ action: 'add_subscription_to_cart', product_id: PRODUCT_ID, cat_ids: catIds, cat_names: catNames, sub_year: selYear, price: total, nonce: SUB_NONCE }) \/\/ [CHANGED] sub_year\n        }).then(r => r.json()).then(data => {\n          if (data.success) { window.location.href = data.data.cart_url; }\n          else {\n            btn.disabled = false;\n            btn.querySelector('.btn-text').style.display   = 'inline';\n            btn.querySelector('.btn-loader').style.display = 'none';\n            errEl.textContent = T.errAddCart; errEl.style.display = 'block';\n          }\n        }).catch(() => {\n          btn.disabled = false;\n          btn.querySelector('.btn-text').style.display   = 'inline';\n          btn.querySelector('.btn-loader').style.display = 'none';\n          errEl.textContent = T.errNetwork; errEl.style.display = 'block';\n        });\n      }\n\n      \/\/ \u2500\u2500 View subscription \u2500\u2500\n      function viewSubscription(orderId, btnEl) {\n        document.querySelectorAll('.sub-view-btn').forEach(b => b.classList.remove('active'));\n        document.querySelectorAll('.sub-table tbody tr').forEach(r => r.classList.remove('sub-row-active'));\n        if (currentOrderId === orderId && document.getElementById('sub-content-section').style.display !== 'none') { closeContent(); return; }\n        btnEl.classList.add('active');\n        const row = document.getElementById('sub-row-' + orderId);\n        if (row) row.classList.add('sub-row-active');\n        currentOrderId = orderId;\n        document.getElementById('sub-content-label').textContent = T.booksOrder + orderId;\n        const section = document.getElementById('sub-content-section');\n        section.style.display = 'block';\n        document.getElementById('sub-content-loading').style.display = 'block';\n        document.getElementById('sub-content-main').style.display   = 'none';\n        setTimeout(() => section.scrollIntoView({ behavior: 'smooth', block: 'start' }), 100);\n        fetch(AJAX_URL, { method: 'POST', headers: { 'Content-Type': 'application\/x-www-form-urlencoded' }, body: new URLSearchParams({ action: 'sub_get_books', order_id: orderId, nonce: SUB_NONCE }) })\n        .then(r => r.json()).then(data => {\n          document.getElementById('sub-content-loading').style.display = 'none';\n          if (data.success) {\n            allBooks = data.data.books; allCategories = data.data.categories;\n            \/\/ [CHANGED] Show subscription year in section header\n            const subYear = data.data.sub_year || '';\n            document.getElementById('sub-content-label').textContent = T.booksOrder + orderId + (subYear ? ' \u2014 ' + subYear : '');\n            renderFilterSidebar(); renderBooks('all');\n            document.getElementById('sub-content-main').style.display = 'flex';\n          } else { section.style.display = 'none'; alert(T.couldNotLoad); }\n        }).catch(() => {\n          document.getElementById('sub-content-loading').style.display = 'none';\n          document.getElementById('sub-content-section').style.display = 'none';\n        });\n      }\n\n      function closeContent() {\n        document.getElementById('sub-content-section').style.display = 'none';\n        document.querySelectorAll('.sub-view-btn').forEach(b => b.classList.remove('active'));\n        document.querySelectorAll('.sub-table tbody tr').forEach(r => r.classList.remove('sub-row-active'));\n        currentOrderId = null;\n      }\n\n      function renderFilterSidebar() {\n        const list = document.getElementById('filter-list');\n        list.innerHTML = `<li><a class=\"active\" onclick=\"filterBooks('all',this)\">${T.all} <span class=\"filter-count\">(${allBooks.length})<\/span><\/a><\/li>`;\n        allCategories.forEach(cat => {\n          const count = allBooks.filter(b => b.cats.split(', ').includes(cat.name)).length;\n          list.innerHTML += `<li><a onclick=\"filterBooks(${cat.id},this)\">${cat.name} <span class=\"filter-count\">(${count})<\/span><\/a><\/li>`;\n        });\n      }\n      function filterBooks(catId, linkEl) {\n        document.querySelectorAll('.filter-list a').forEach(a => a.classList.remove('active'));\n        linkEl.classList.add('active'); renderBooks(catId);\n      }\n\n      function renderBooks(catId) {\n        const grid    = document.getElementById('sub-books-grid');\n        const countEl = document.getElementById('sub-books-count');\n        const emptyEl = document.getElementById('sub-books-empty');\n        const filtered = catId === 'all' ? allBooks : allBooks.filter(b => {\n          const cat = allCategories.find(c => c.id == catId);\n          return cat && b.cats.split(', ').includes(cat.name);\n        });\n        grid.innerHTML = '';\n        if (filtered.length === 0) { emptyEl.style.display = 'flex'; countEl.textContent = ''; return; }\n        emptyEl.style.display = 'none';\n        countEl.textContent = filtered.length === 1 ? '1 ' + T.bookFound1 : filtered.length + ' ' + T.booksFoundN;\n        filtered.forEach(book => {\n          let actionBtn = '';\n          if (book.file_type === 'pdf') {\n            const bmJson = JSON.stringify(book.bookmarks || []).replace(\/\"\/g, '&quot;');\n            actionBtn = `<button class=\"sub-read-btn\" data-bm=\"${bmJson}\" onclick=\"openPdf('${book.pdf_proxy_url.replace(\/'\/g,\"\\\\'\")}','${book.title.replace(\/'\/g,\"\\\\'\")}',${book.id},JSON.parse(this.dataset.bm))\">\n              <svg class=\"icon-svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"><path d=\"M4 19.5A2.5 2.5 0 016.5 17H20\"\/><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z\"\/><\/svg>${T.read}<\/button>`;\n          } else if (book.file_type === 'archive') {\n            actionBtn = `<div class=\"sub-tooltip-wrap\"><span class=\"sub-read-btn-disabled\">\n              <svg class=\"icon-svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M4 19.5A2.5 2.5 0 016.5 17H20\"\/><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z\"\/><\/svg>${T.read}\n              <svg class=\"icon-svg\" width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" style=\"margin-left:2px;opacity:.6\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"\/><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"\/><\/svg>\n              <\/span><div class=\"sub-tooltip\">${T.archiveTooltip}<\/div><\/div>`;\n          } else {\n            actionBtn = `<span class=\"sub-read-btn-disabled\">\n              <svg class=\"icon-svg\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><line x1=\"4.93\" y1=\"4.93\" x2=\"19.07\" y2=\"19.07\"\/><\/svg>${T.noFile}<\/span>`;\n          }\n          grid.innerHTML += `<div class=\"sub-book-card\">\n            <div class=\"sub-book-img-wrap\"><img decoding=\"async\" class=\"sub-book-img\" src=\"${book.image}\" alt=\"${book.title}\" loading=\"lazy\"><\/div>\n            <div class=\"sub-book-info\"><p class=\"sub-book-title\">${book.title}<\/p><p class=\"sub-book-cat\">${book.cats}<\/p>${actionBtn}<\/div>\n          <\/div>`;\n        });\n      }\n\n      \/\/ \u2550\u2550 PDF READER \u2550\u2550\n      function subResetPrintBtn() {\n        const btn = document.getElementById('pdf-print-btn'); if (!btn) return;\n        document.getElementById('pdf-print-icon').style.display        = 'flex';\n        document.getElementById('pdf-print-btn-spinner').style.display = 'none';\n        document.getElementById('pdf-print-btn-label').textContent     = T.print;\n        subUpdatePrintButton();\n      }\n      function subResetConfirmBtn() {\n        const btn = document.getElementById('pdf-print-confirm'); if (!btn) return;\n        document.getElementById('pdf-confirm-icon').style.display    = 'flex';\n        document.getElementById('pdf-confirm-spinner').style.display = 'none';\n        document.getElementById('pdf-confirm-label').textContent     = T.printSelected;\n        btn.disabled = printSelected.size === 0;\n      }\n\n      function openPdf(proxyUrl, title, productId, adminBookmarks) {\n        pdfDoc = null; pdfScale = 0.5; pdfVisiblePage = 1;\n        printSelected.clear(); currentProductId = productId;\n        document.getElementById('pdf-title-text').textContent          = title;\n        document.getElementById('pdf-loading-overlay').style.display   = 'flex';\n        document.getElementById('pdf-error-box').style.display         = 'none';\n        document.getElementById('pdf-canvas-area').style.display       = 'none';\n        document.getElementById('pdf-bookmarks-sidebar').style.display = 'none';\n        document.getElementById('pdf-page-info').style.display         = 'none';\n        document.getElementById('pdf-print-btn-wrap').style.display    = 'none';\n        document.getElementById('pdf-loading-msg').textContent         = T.openingBook;\n        document.getElementById('sub-pdf-modal').style.display         = 'flex';\n        document.getElementById('pdf-scroll-viewport').innerHTML       = '';\n        document.getElementById('pdf-bookmarks-list').innerHTML        = '';\n        document.getElementById('pdf-page-input').value                = 1;\n        subUpdateZoomButtons();\n        document.body.style.overflow = 'hidden';\n\n        const quotaPromise = new Promise(resolve => {\n          if (quotaCache.has(productId)) { printQuotaLeft = quotaCache.get(productId); resolve(); }\n          else {\n            fetch(AJAX_URL, { method:'POST', headers:{'Content-Type':'application\/x-www-form-urlencoded'},\n              body: new URLSearchParams({ action:'sub_get_print_quota', product_id:productId, nonce:SUB_NONCE })\n            }).then(r => r.json()).then(q => {\n              printQuotaLeft = q.success ? q.data.left : PRINT_PAGE_LIMIT;\n              quotaCache.set(productId, printQuotaLeft); resolve();\n            }).catch(() => { printQuotaLeft = PRINT_PAGE_LIMIT; resolve(); });\n          }\n        });\n\n        const loadSource = pdfCache.has(proxyUrl) ? { data: pdfCache.get(proxyUrl).slice(0) } : { url: proxyUrl, withCredentials: true };\n        if (pdfCache.has(proxyUrl)) document.getElementById('pdf-loading-msg').textContent = T.loadingFromCache;\n\n        pdfjsLib.getDocument(loadSource).promise.then(doc => {\n          pdfDoc = doc; const total = doc.numPages;\n          if (!pdfCache.has(proxyUrl)) doc.getData().then(d => pdfCache.set(proxyUrl, d.slice(0)));\n          document.getElementById('pdf-nav-total').textContent    = total;\n          document.getElementById('pdf-total-pages').textContent  = total;\n          document.getElementById('pdf-current-page').textContent = '1';\n          document.getElementById('pdf-page-input').max           = total;\n          document.getElementById('pdf-page-info').style.display  = 'inline-flex';\n          return Promise.all([\n            doc.getOutline().then(outline => {\n              if (adminBookmarks && adminBookmarks.length) {\n                renderAdminBookmarks(adminBookmarks);\n                document.getElementById('pdf-bookmarks-sidebar').style.display = 'flex';\n              } else if (outline && outline.length) {\n                renderBookmarks(outline, doc);\n                document.getElementById('pdf-bookmarks-sidebar').style.display = 'flex';\n              }\n              return subRenderAllPages(doc);\n            }),\n            quotaPromise\n          ]);\n        }).then(() => {\n          document.getElementById('pdf-loading-overlay').style.display = 'none';\n          document.getElementById('pdf-canvas-area').style.display     = 'flex';\n          subSetupScrollObserver(); subUpdatePrintButton();\n          document.getElementById('pdf-print-btn-wrap').style.display  = 'inline-flex';\n        }).catch(err => { showPdfError(T.openingBook + ' (' + (err.message || err) + ')'); });\n      }\n\n      async function subRenderAllPages(doc) {\n        const viewport = document.getElementById('pdf-scroll-viewport');\n        const total    = doc.numPages;\n        const loadMsg  = document.getElementById('pdf-loading-msg');\n        for (let i = 1; i <= total; i++) {\n          loadMsg.textContent = T.renderingPage + ' ' + i + ' ' + T.of + ' ' + total + '\u2026';\n          const page    = await doc.getPage(i);\n          const vp0     = page.getViewport({ scale:1 });\n          const fitW    = (viewport.clientWidth || window.innerWidth) - 40;\n          const vp      = page.getViewport({ scale:(fitW \/ vp0.width) * pdfScale });\n          const wrapper = document.createElement('div');\n          wrapper.className = 'pdf-page-wrapper'; wrapper.dataset.page = i;\n          const canvas = document.createElement('canvas');\n          canvas.width = vp.width; canvas.height = vp.height;\n          canvas.addEventListener('contextmenu', e => e.preventDefault());\n          await page.render({ canvasContext: canvas.getContext('2d'), viewport: vp }).promise;\n          const label = document.createElement('div');\n          label.className = 'pdf-page-label'; label.textContent = i;\n          wrapper.appendChild(canvas); wrapper.appendChild(label); viewport.appendChild(wrapper);\n        }\n      }\n\n      async function subReRenderAllPages() {\n        if (!pdfDoc) return;\n        const viewport = document.getElementById('pdf-scroll-viewport');\n        const wrappers = viewport.querySelectorAll('.pdf-page-wrapper');\n        const fitW     = (viewport.clientWidth || window.innerWidth) - 40;\n        for (let i = 0; i < wrappers.length; i++) {\n          const page   = await pdfDoc.getPage(i + 1);\n          const vp0    = page.getViewport({ scale:1 });\n          const vp     = page.getViewport({ scale:(fitW \/ vp0.width) * pdfScale });\n          const canvas = wrappers[i].querySelector('canvas');\n          canvas.width = vp.width; canvas.height = vp.height;\n          await page.render({ canvasContext: canvas.getContext('2d'), viewport: vp }).promise;\n        }\n      }\n\n      function subSetupScrollObserver() {\n        if (pdfPageObserver) pdfPageObserver.disconnect();\n        const viewport = document.getElementById('pdf-scroll-viewport');\n        pdfPageObserver = new IntersectionObserver(entries => {\n          let best = null, bestRatio = 0;\n          entries.forEach(e => { if (e.isIntersecting && e.intersectionRatio > bestRatio) { bestRatio = e.intersectionRatio; best = e.target; } });\n          if (best) {\n            const p = parseInt(best.dataset.page); pdfVisiblePage = p;\n            document.getElementById('pdf-nav-current').textContent  = p;\n            document.getElementById('pdf-current-page').textContent = p;\n            updateActiveBookmark(p);\n          }\n        }, { root: viewport, threshold: [0.1, 0.5, 0.9] });\n        viewport.querySelectorAll('.pdf-page-wrapper').forEach(w => pdfPageObserver.observe(w));\n      }\n\n      function subScrollToPage(pageNum) {\n        if (!pdfDoc) return;\n        const n = Math.max(1, Math.min(pageNum, pdfDoc.numPages));\n        const w = document.querySelector(`.pdf-page-wrapper[data-page=\"${n}\"]`);\n        if (w) w.scrollIntoView({ behavior:'smooth', block:'start' });\n      }\n\n      function subZoom(delta) {\n        const next = Math.round(Math.max(PDF_SCALE_MIN, Math.min(PDF_SCALE_MAX, pdfScale + delta)) * 10) \/ 10;\n        if (next === pdfScale) return;\n        pdfScale = next; subUpdateZoomButtons(); subReRenderAllPages();\n      }\n      function subUpdateZoomButtons() {\n        document.getElementById('pdf-zoom-out-btn').disabled = pdfScale <= PDF_SCALE_MIN;\n        document.getElementById('pdf-zoom-in-btn').disabled  = pdfScale >= PDF_SCALE_MAX;\n        document.getElementById('pdf-zoom-label').textContent = Math.round(pdfScale * 100) + '%';\n      }\n\n      function subUpdatePrintButton() {\n        const btn = document.getElementById('pdf-print-btn');\n        const tip = document.getElementById('pdf-print-quota-tip');\n        if (!btn) return;\n        if (printQuotaLeft <= 0) {\n          btn.disabled = true;\n          tip.textContent = T.quotaTipUsed + ' ' + PRINT_PAGE_LIMIT + ' ' + T.quotaTipUsed2;\n        } else {\n          btn.disabled = false;\n          const tpl = LANG === 'ar' ? T.quotaTipLeftAr : T.quotaTipLeftFr;\n          tip.textContent = tpl.replace('%d', printQuotaLeft).replace('%d', PRINT_PAGE_LIMIT);\n        }\n      }\n\n      function renderBookmarks(outline, doc, container, depth) {\n        container = container || document.getElementById('pdf-bookmarks-list'); depth = depth || 0;\n        outline.forEach(item => {\n          const li = document.createElement('li'); const a = document.createElement('a');\n          a.textContent = item.title; a.style.paddingLeft = (14 + depth * 14) + 'px';\n          a.onclick = async e => {\n            e.preventDefault();\n            if (item.dest) { try { let d = item.dest; if (typeof d === 'string') d = await doc.getDestination(d); if (d) { const pi = await doc.getPageIndex(d[0]); subScrollToPage(pi + 1); } } catch(e) {} }\n          };\n          li.appendChild(a);\n          if (item.items && item.items.length) { const ul = document.createElement('ul'); li.appendChild(ul); renderBookmarks(item.items, doc, ul, depth + 1); }\n          container.appendChild(li);\n        });\n      }\n\n      function renderAdminBookmarks(bookmarks) {\n        const list = document.getElementById('pdf-bookmarks-list'); list.innerHTML = '';\n        bookmarks.forEach(bm => {\n          const li = document.createElement('li'); const a = document.createElement('a');\n          a.textContent = bm.title; a.dataset.page = bm.page;\n          a.style.paddingLeft = (14 + (bm.indent || 0) * 14) + 'px';\n          a.onclick = e => { e.preventDefault(); subScrollToPage(bm.page); };\n          li.appendChild(a); list.appendChild(li);\n        });\n      }\n\n      function updateActiveBookmark(pageNum) {\n        document.querySelectorAll('.pdf-bookmarks-list a').forEach(a => a.classList.toggle('active', parseInt(a.dataset.page) === pageNum));\n      }\n\n      \/\/ \u2500\u2500 Print dialog \u2500\u2500\n      function subOpenPrintDialog() {\n        if (!pdfDoc || printQuotaLeft <= 0) return;\n        printSelected.clear();\n        const printBtn = document.getElementById('pdf-print-btn');\n        printBtn.disabled = true;\n        document.getElementById('pdf-print-icon').style.display        = 'none';\n        document.getElementById('pdf-print-btn-spinner').style.display = 'flex';\n        document.getElementById('pdf-print-btn-label').textContent     = T.opening;\n        subRenderQuotaBar(printQuotaLeft);\n        document.getElementById('pdf-print-left-label').textContent = printQuotaLeft;\n        document.getElementById('pdf-print-thumbs').innerHTML = '';\n        const total = pdfDoc.numPages, THUMB_H = 220, promises = [];\n        for (let i = 1; i <= total; i++) {\n          promises.push(pdfDoc.getPage(i).then(page => {\n            const vp0 = page.getViewport({ scale:1 });\n            const vp  = page.getViewport({ scale:(THUMB_H \/ vp0.height) * (window.devicePixelRatio || 1) });\n            const canvas = document.createElement('canvas'); canvas.width = vp.width; canvas.height = vp.height;\n            const ctx = canvas.getContext('2d'); ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, canvas.width, canvas.height);\n            return page.render({ canvasContext: ctx, viewport: vp }).promise.then(() => ({ pageNum: i, canvas }));\n          }));\n        }\n        Promise.all(promises).then(pages => {\n          pages.sort((a,b) => a.pageNum - b.pageNum).forEach(({ pageNum, canvas }) => {\n            const thumb = document.createElement('div'); thumb.className = 'pdf-print-thumb'; thumb.dataset.page = pageNum;\n            const check = document.createElement('div'); check.className = 'pdf-thumb-check';\n            const label = document.createElement('div'); label.className = 'pdf-print-thumb-label'; label.textContent = T.page + ' ' + pageNum;\n            thumb.appendChild(canvas); thumb.appendChild(check); thumb.appendChild(label);\n            thumb.onclick = () => subTogglePrintPage(pageNum, thumb);\n            document.getElementById('pdf-print-thumbs').appendChild(thumb);\n          });\n          subUpdatePrintCount(); subResetPrintBtn();\n        });\n        document.getElementById('pdf-print-dialog').style.display = 'flex';\n      }\n\n      function subRenderQuotaBar(left) {\n        const pct = ((PRINT_PAGE_LIMIT - left) \/ PRINT_PAGE_LIMIT) * 100;\n        const cls = pct >= 90 ? 'danger' : pct >= 60 ? 'warn' : '';\n        document.getElementById('pdf-print-quota-bar').innerHTML = `<div class=\"pdf-print-quota-track\"><div class=\"pdf-print-quota-fill ${cls}\" style=\"width:${pct}%\"><\/div><\/div>`;\n      }\n\n      function subTogglePrintPage(pageNum, thumbEl) {\n        if (thumbEl.classList.contains('quota-disabled') && !thumbEl.classList.contains('selected')) return;\n        if (printSelected.has(pageNum)) { printSelected.delete(pageNum); thumbEl.classList.remove('selected'); }\n        else {\n          if (printSelected.size >= printQuotaLeft) { const el = document.getElementById('pdf-print-count'); el.style.color = '#e57373'; setTimeout(() => el.style.color = '', 800); return; }\n          printSelected.add(pageNum); thumbEl.classList.add('selected');\n        }\n        subUpdatePrintCount();\n        const atLimit = printSelected.size >= printQuotaLeft;\n        document.querySelectorAll('.pdf-print-thumb').forEach(t => { if (!t.classList.contains('selected')) t.classList.toggle('quota-disabled', atLimit); });\n      }\n\n      function subUpdatePrintCount() {\n        const n = printSelected.size;\n        document.getElementById('pdf-print-count').textContent = n + ' ' + T.selected;\n        document.getElementById('pdf-print-confirm').disabled  = n === 0;\n      }\n\n      function subClosePrintDialog() {\n        document.getElementById('pdf-print-dialog').style.display = 'none'; subResetConfirmBtn();\n      }\n\n      function subExecutePrint() {\n        if (!pdfDoc || printSelected.size === 0) return;\n        const pages = Array.from(printSelected).sort((a,b) => a - b);\n        const confirmBtn = document.getElementById('pdf-print-confirm'); confirmBtn.disabled = true;\n        document.getElementById('pdf-confirm-icon').style.display    = 'none';\n        document.getElementById('pdf-confirm-spinner').style.display = 'flex';\n        document.getElementById('pdf-confirm-label').textContent     = T.preparing;\n        Promise.all(pages.map(i => pdfDoc.getPage(i).then(page => {\n          const vp = page.getViewport({ scale:2.0 }); const canvas = document.createElement('canvas');\n          canvas.width = vp.width; canvas.height = vp.height;\n          const ctx = canvas.getContext('2d'); ctx.fillStyle = '#fff'; ctx.fillRect(0,0,canvas.width,canvas.height);\n          return page.render({ canvasContext: ctx, viewport: vp }).promise.then(() => canvas.toDataURL('image\/jpeg', 0.92));\n        }))).then(dataUrls => {\n          fetch(AJAX_URL, { method:'POST', headers:{'Content-Type':'application\/x-www-form-urlencoded'},\n            body: new URLSearchParams({ action:'sub_consume_print_quota', product_id:currentProductId, pages:pages.length, nonce:SUB_NONCE })\n          }).then(r => r.json()).then(data => {\n            if (!data.success) { subResetConfirmBtn(); alert(T.printQuotaErr + (data.data || '')); return; }\n            printQuotaLeft = data.data.left; quotaCache.set(currentProductId, printQuotaLeft);\n            subUpdatePrintButton(); subClosePrintDialog();\n            const win = window.open('', '_blank');\n            win.document.write(`<!DOCTYPE html><html><head><title>Print<\/title><style>*{margin:0;padding:0;box-sizing:border-box;}body{background:#fff;}img{width:100%;display:block;page-break-after:always;}img:last-child{page-break-after:avoid;}<\/style><\/head><body>`);\n            dataUrls.forEach(d => win.document.write(`<img decoding=\"async\" src=\"${d}\">`));\n            win.document.write('<\/body><\/html>'); win.document.close();\n            win.onload = () => { win.focus(); win.print(); win.close(); };\n          }).catch(() => { subResetConfirmBtn(); alert(T.quotaVerifyErr); });\n        }).catch(() => { subResetConfirmBtn(); alert(T.renderErr); });\n      }\n\n      function showPdfError(message) {\n        document.getElementById('pdf-loading-overlay').style.display = 'none';\n        document.getElementById('pdf-canvas-area').style.display     = 'none';\n        document.getElementById('pdf-error-msg').textContent         = message;\n        document.getElementById('pdf-error-box').style.display       = 'flex';\n      }\n\n      function closePdfModal() {\n        if (pdfPageObserver) { pdfPageObserver.disconnect(); pdfPageObserver = null; }\n        document.getElementById('sub-pdf-modal').style.display          = 'none';\n        document.getElementById('pdf-loading-overlay').style.display    = 'flex';\n        document.getElementById('pdf-error-box').style.display          = 'none';\n        document.getElementById('pdf-canvas-area').style.display        = 'none';\n        document.getElementById('pdf-bookmarks-sidebar').style.display  = 'none';\n        document.getElementById('pdf-scroll-viewport').innerHTML        = '';\n        document.getElementById('pdf-bookmarks-list').innerHTML         = '';\n        document.getElementById('pdf-page-info').style.display          = 'none';\n        document.getElementById('pdf-print-btn-wrap').style.display     = 'none';\n        document.getElementById('pdf-print-dialog').style.display       = 'none';\n        pdfDoc = null; printSelected.clear(); document.body.style.overflow = '';\n      }\n\n           document.getElementById('sub-pdf-modal').addEventListener('contextmenu', e => e.preventDefault());\n\n      document.addEventListener('keydown', function(e) {\n        const modal = document.getElementById('sub-pdf-modal');\n        if (!modal || modal.style.display === 'none') return;\n\n        if (e.key === 'Escape') {\n          closePdfModal();\n          return;\n        }\n\n        \/\/ \u2190\u2190\u2190 NEW: BLOCK Ctrl+P \/ Cmd+P \u2192 open OUR quota print modal instead\n        if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'p') {\n          e.preventDefault();           \/\/ stop browser print dialog\n          subOpenPrintDialog();         \/\/ open our custom print dialog with quota + thumbnails\n          return;\n        }\n      });\n    <\/script>\n    \n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":67,"featured_media":16786,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"class_list":["post-16844","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Mes Abonnements - CENTRE D&#039;ETUDES JURIDIQUES ET JUDICIAIRES<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Mes Abonnements - CENTRE D&#039;ETUDES JURIDIQUES ET JUDICIAIRES\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/\" \/>\n<meta property=\"og:site_name\" content=\"CENTRE D&#039;ETUDES JURIDIQUES ET JUDICIAIRES\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-11T22:08:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.cejj-justice.tn\/wp-content\/uploads\/2026\/02\/library.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"1200\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/\",\"url\":\"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/\",\"name\":\"Mes Abonnements - CENTRE D&#039;ETUDES JURIDIQUES ET JUDICIAIRES\",\"isPartOf\":{\"@id\":\"https:\/\/www.cejj-justice.tn\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.cejj-justice.tn\/wp-content\/uploads\/2026\/02\/library.jpg\",\"datePublished\":\"2026-02-25T16:52:18+00:00\",\"dateModified\":\"2026-03-11T22:08:34+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/#primaryimage\",\"url\":\"https:\/\/www.cejj-justice.tn\/wp-content\/uploads\/2026\/02\/library.jpg\",\"contentUrl\":\"https:\/\/www.cejj-justice.tn\/wp-content\/uploads\/2026\/02\/library.jpg\",\"width\":1800,\"height\":1200},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.cejj-justice.tn\/fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Mes Abonnements\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.cejj-justice.tn\/#website\",\"url\":\"https:\/\/www.cejj-justice.tn\/\",\"name\":\"CENTRE D&#039;ETUDES JURIDIQUES ET JUDICIAIRES\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.cejj-justice.tn\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Mes Abonnements - CENTRE D&#039;ETUDES JURIDIQUES ET JUDICIAIRES","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/","og_locale":"fr_FR","og_type":"article","og_title":"Mes Abonnements - CENTRE D&#039;ETUDES JURIDIQUES ET JUDICIAIRES","og_url":"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/","og_site_name":"CENTRE D&#039;ETUDES JURIDIQUES ET JUDICIAIRES","article_modified_time":"2026-03-11T22:08:34+00:00","og_image":[{"width":1800,"height":1200,"url":"https:\/\/www.cejj-justice.tn\/wp-content\/uploads\/2026\/02\/library.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/","url":"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/","name":"Mes Abonnements - CENTRE D&#039;ETUDES JURIDIQUES ET JUDICIAIRES","isPartOf":{"@id":"https:\/\/www.cejj-justice.tn\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/#primaryimage"},"image":{"@id":"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/#primaryimage"},"thumbnailUrl":"https:\/\/www.cejj-justice.tn\/wp-content\/uploads\/2026\/02\/library.jpg","datePublished":"2026-02-25T16:52:18+00:00","dateModified":"2026-03-11T22:08:34+00:00","breadcrumb":{"@id":"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/"]}]},{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/#primaryimage","url":"https:\/\/www.cejj-justice.tn\/wp-content\/uploads\/2026\/02\/library.jpg","contentUrl":"https:\/\/www.cejj-justice.tn\/wp-content\/uploads\/2026\/02\/library.jpg","width":1800,"height":1200},{"@type":"BreadcrumbList","@id":"https:\/\/www.cejj-justice.tn\/fr\/mes-abonnements\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.cejj-justice.tn\/fr\/"},{"@type":"ListItem","position":2,"name":"Mes Abonnements"}]},{"@type":"WebSite","@id":"https:\/\/www.cejj-justice.tn\/#website","url":"https:\/\/www.cejj-justice.tn\/","name":"CENTRE D&#039;ETUDES JURIDIQUES ET JUDICIAIRES","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.cejj-justice.tn\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"}]}},"_links":{"self":[{"href":"https:\/\/www.cejj-justice.tn\/fr\/wp-json\/wp\/v2\/pages\/16844","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cejj-justice.tn\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.cejj-justice.tn\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.cejj-justice.tn\/fr\/wp-json\/wp\/v2\/users\/67"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cejj-justice.tn\/fr\/wp-json\/wp\/v2\/comments?post=16844"}],"version-history":[{"count":1,"href":"https:\/\/www.cejj-justice.tn\/fr\/wp-json\/wp\/v2\/pages\/16844\/revisions"}],"predecessor-version":[{"id":16845,"href":"https:\/\/www.cejj-justice.tn\/fr\/wp-json\/wp\/v2\/pages\/16844\/revisions\/16845"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cejj-justice.tn\/fr\/wp-json\/wp\/v2\/media\/16786"}],"wp:attachment":[{"href":"https:\/\/www.cejj-justice.tn\/fr\/wp-json\/wp\/v2\/media?parent=16844"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}