[{"command":"add_css","data":[{"rel":"stylesheet","media":"all","href":"\/modules\/contrib\/paragraphs\/css\/paragraphs.unpublished.css?tlth02"},{"rel":"stylesheet","media":"all","href":"\/themes\/custom\/bootstrap_barrio\/css\/components\/node.css?tlth02"}]},{"command":"insert","method":"replaceWith","selector":"#indicator-content-ajax","data":"\n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027container\u0027 --\u003E\n\u003C!-- \ud83d\udca1 BEGIN CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/form\/container.html.twig\u0027 --\u003E\n\u003Cdiv id=\u0022indicator-content-ajax\u0022 class=\u0022daba-bank-full-main  mb-lg-0\u0022\u003E\n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027container\u0027 --\u003E\n\u003C!-- \ud83d\udca1 BEGIN CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/form\/container.html.twig\u0027 --\u003E\n\u003Cdiv class=\u0022data-bank-indicator-title text-uppercase fs-5 fw-bold pb-2 mb-lg-0\u0022\u003E\u003Cp\u003EComparaci\u00f3n con la poblaci\u00f3n sin discapacidad\u003C\/p\u003E\n\u003C\/div\u003E\n\n\u003C!-- END CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/form\/container.html.twig\u0027 --\u003E\n\n\n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027container\u0027 --\u003E\n\u003C!-- \ud83d\udca1 BEGIN CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/form\/container.html.twig\u0027 --\u003E\n\u003Cdiv class=\u0022o-field-value mb-lg-0\u0022\u003E\n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027node\u0027 --\u003E\n\u003C!-- FILE NAME SUGGESTIONS:\n   \u25aa\ufe0f node--943--teaser.html.twig\n   \u25aa\ufe0f node--943.html.twig\n   \u25aa\ufe0f node--data-sample--teaser.html.twig\n   \u2705 node--data-sample.html.twig\n   \u25aa\ufe0f node--teaser.html.twig\n   \u25aa\ufe0f node.html.twig\n--\u003E\n\u003C!-- \ud83d\udca1 BEGIN CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/content\/node--data-sample.html.twig\u0027 --\u003E\n\n\n\u003Carticle class=\u0022node node--type-data-sample node--view-mode-teaser clearfix\u0022\u003E\n    \u003Cdiv class=\u0022node__content clearfix m-0\u0022\u003E\n        \n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027container\u0027 --\u003E\n\u003C!-- \ud83d\udca1 BEGIN CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/form\/container.html.twig\u0027 --\u003E\n\u003Cdiv class=\u0022field field--name-field-title field--type-string field--label-hidden field__item teaser-title text-primary pb-3 mb-lg-0\u0022\u003E\u003Ca href=\u0022\/data\/tasa-de-paro-de-la-poblacion-en-funcion-de-la-discapacidad-2024\u0022\u003ETasa de paro de la poblaci\u00f3n en funci\u00f3n de la discapacidad. 2024\u003C\/a\u003E\u003C\/div\u003E\n\n\u003C!-- END CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/form\/container.html.twig\u0027 --\u003E\n\n\n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027field\u0027 --\u003E\n\u003C!-- FILE NAME SUGGESTIONS:\n   \u25aa\ufe0f field--node--field-source-data--data-sample.html.twig\n   \u25aa\ufe0f field--node--field-source-data.html.twig\n   \u25aa\ufe0f field--node--data-sample.html.twig\n   \u25aa\ufe0f field--field-source-data.html.twig\n   \u25aa\ufe0f field--entity-reference-revisions.html.twig\n   \u2705 field.html.twig\n--\u003E\n\u003C!-- BEGIN OUTPUT from \u0027themes\/contrib\/noahs_builder_theme\/templates\/field\/field.html.twig\u0027 --\u003E\n\n            \u003Cdiv class=\u0022field field-field-source-data field-type-entity-reference-revisions field-label-hidden field-item\u0022\u003E\n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027paragraph\u0027 --\u003E\n\u003C!-- FILE NAME SUGGESTIONS:\n   \u25aa\ufe0f paragraph--1904.html.twig\n   \u25aa\ufe0f paragraph--html--default.html.twig\n   \u25aa\ufe0f paragraph--html.html.twig\n   \u2705 paragraph--default.html.twig\n   \u25aa\ufe0f paragraph.html.twig\n--\u003E\n\u003C!-- \ud83d\udca1 BEGIN CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/paragraph\/paragraph--default.html.twig\u0027 --\u003E\n\n  \u003Cdiv class=\u0022paragraph paragraph--type--html paragraph--view-mode--default\u0022\u003E\n      \u003Cdiv class=\u0022container-fluid p-0\u0022\u003E\n          \n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027field\u0027 --\u003E\n\u003C!-- FILE NAME SUGGESTIONS:\n   \u25aa\ufe0f field--paragraph--field-description--html.html.twig\n   \u25aa\ufe0f field--paragraph--field-description.html.twig\n   \u25aa\ufe0f field--paragraph--html.html.twig\n   \u25aa\ufe0f field--field-description.html.twig\n   \u25aa\ufe0f field--text-long.html.twig\n   \u2705 field.html.twig\n--\u003E\n\u003C!-- BEGIN OUTPUT from \u0027themes\/contrib\/noahs_builder_theme\/templates\/field\/field.html.twig\u0027 --\u003E\n\n            \u003Cdiv class=\u0022field field-field-description field-type-text-long field-label-hidden field-item\u0022\u003E\u003C!doctype html\u003E\n\u003Chtml lang=\u0022es\u0022\u003E\u003Chead\u003E\u003Cmeta charset=\u0022utf-8\u0022\u003E\u003Cmeta name=\u0022viewport\u0022 content=\u0022width=device-width,initial-scale=1\u0022\u003E\n\u003Ctitle\u003E1.05 Comparativa | ODISMET\u003C\/title\u003E\n\u003Cstyle\u003E\n:root{--red:#d22630;--yellow:#ffd100;--ink:#202124;--muted:#667085;--bg:#f4f6f8;--card:#fff;--line:#e2e6ea;--green:#198754;--blue:#0077c8;--orange:#e87500}\n*{box-sizing:border-box}body{margin:0;font-family:Arial,Helvetica,sans-serif;background:var(--bg);color:var(--ink)}\nheader{background:#fff;border-bottom:5px solid var(--yellow);padding:22px clamp(18px,4vw,55px)}.head{max-width:1280px;margin:auto;display:flex;align-items:center;justify-content:space-between;gap:18px}.brand{display:flex;align-items:center;gap:15px}.mark{width:50px;height:50px;border-radius:50%;background:var(--red);position:relative}.mark:after{content:\u0022\u0022;position:absolute;inset:13px;border:7px solid var(--yellow);border-radius:50%}h1{margin:0;font-size:clamp(24px,3vw,36px)}.eyebrow{font-size:12px;color:var(--red);font-weight:800;letter-spacing:.08em;text-transform:uppercase;margin-bottom:4px}\nmain{max-width:1280px;margin:auto;padding:26px}.admin-toggle{display:none;border:1px solid var(--line);background:#fff;color:var(--muted);border-radius:9px;padding:9px 12px;font-weight:700;cursor:pointer}.admin{display:none;background:#fff;border:1px solid var(--line);border-radius:14px;padding:18px;margin-bottom:18px}.admin.open{display:block}.drop{border:2px dashed #aeb6c2;border-radius:12px;padding:20px;text-align:center;cursor:pointer}.drop.over{border-color:var(--red);background:#fff8f8}.btn{border:0;border-radius:9px;padding:10px 15px;font-weight:700;cursor:pointer;background:var(--red);color:#fff}.btn.secondary{background:#fff;color:var(--ink);border:1px solid var(--line)}input[type=file]{display:none}.status{font-size:12px;color:var(--muted);margin-top:9px}.error{color:#b42318;font-weight:700}\n\/* KPIs: columnas m\u00e1s estrechas, alineadas a la izquierda en vez de ocupar todo el ancho *\/\n\/* KPIs: la fila ocupa todo el ancho de la caja (igual que el gr\u00e1fico de abajo), pero cada\n   tarjeta tiene un ancho m\u00e1ximo para no verse tan ancha. Funciona igual con 3, 4 o m\u00e1s tarjetas. *\/\n.kpis{display:flex;flex-wrap:wrap;justify-content:space-between;gap:16px}\n.kpi{flex:1 1 160px;min-width:150px;max-width:230px}\n.kpi{min-height:150px;border-radius:16px;padding:18px 20px;color:#fff;position:relative;overflow:hidden;box-shadow:0 8px 24px #10182813}.kpi:after{content:\u0022\u0022;position:absolute;width:110px;height:110px;border:24px solid #ffffff18;border-radius:50%;right:-30px;top:-35px}.kpi.rate{background:linear-gradient(135deg,#df5961,#c93640)}.kpi.gap{background:linear-gradient(135deg,#4a9bd1,#2378b1)}.kpi.evolution{background:linear-gradient(135deg,#55a77d,#2f8860)}.kpi.evolution.bad{background:linear-gradient(135deg,#efaa58,#d77a24)}.klabel{font-size:12.5px;font-weight:800;text-transform:uppercase;letter-spacing:.05em}.kvalue{font-size:clamp(26px,3vw,38px);font-weight:900;margin:12px 0 5px;position:relative;z-index:1;white-space:nowrap}.unit{font-size:.40em;font-weight:800;vertical-align:.15em;margin-left:.12em}.knote{font-size:11.5px;opacity:.93}.trend{font-size:.78em;margin-right:7px}\n.cards{display:grid;grid-template-columns:1.35fr .9fr;gap:16px;margin-top:16px}.card{background:#fff;border:1px solid var(--line);border-radius:16px;padding:21px;box-shadow:0 3px 15px #1018280a}.card h2{font-size:19px;margin:0 0 5px}.hint{font-size:12px;color:var(--muted);margin-bottom:12px}\n\/* Gr\u00e1fico: m\u00e1s alto y ocupando todo el ancho\/alto de su caja (el SVG se redibuja a medida) *\/\n.chart{height:460px;display:flex}.chart svg{width:100%;height:100%;display:block;overflow:visible}.axis{fill:#667085;font-size:14px}.gridline{stroke:#e6e9ed}\n.conclusion{font-size:17px;line-height:1.65;padding-top:8px}.conclusion strong{color:var(--red)}.source{font-size:11px;color:var(--muted);border-top:1px solid var(--line);padding-top:14px;margin-top:20px}.actions{display:flex;justify-content:flex-end;margin-top:16px}.mailbtn{background:var(--ink)}\n.modal{position:fixed;inset:0;background:#10182899;display:none;align-items:center;justify-content:center;padding:18px;z-index:99}.modal.open{display:flex}.modalbox{background:#fff;width:min(760px,100%);max-height:92vh;overflow:auto;border-radius:16px;padding:22px}.modalhead{display:flex;justify-content:space-between;gap:12px}.close{border:0;border-radius:50%;font-size:20px;width:36px;height:36px;cursor:pointer}.field{margin:12px 0}.field label{display:block;font-size:12px;font-weight:700;color:var(--muted);margin-bottom:6px}.field input,.field textarea{width:100%;border:1px solid var(--line);border-radius:10px;padding:11px;font:inherit}.field textarea{min-height:280px;resize:vertical}.notice{font-size:12px;background:#fff8db;border-left:4px solid var(--yellow);padding:10px}.modalactions{display:flex;justify-content:flex-end;gap:10px}.data-state{display:flex;align-items:center;gap:8px;color:var(--muted);font-size:12px;margin:0 0 14px;flex-wrap:wrap}.refresh-btn{border:1px solid #d0d5dd;background:#fff;color:#667085;border-radius:18px;padding:4px 9px;font-size:11px;font-weight:700;cursor:pointer}.refresh-btn:hover{background:#f2f4f7}.refresh-btn:disabled{opacity:.55;cursor:wait}.data-state .dot{width:9px;height:9px;border-radius:50%;background:#98a2b3}.data-state.ok .dot{background:#198754}.data-state.warn .dot{background:#e87500}.footer{text-align:center;color:var(--muted);font-size:11px;padding:18px}\n@media(max-width:850px){.kpi{flex:1 1 100%;max-width:100%}.cards{grid-template-columns:1fr}.chart{height:340px}}\n@media(max-width:520px){main{padding:14px}.head{align-items:flex-start}.kpi{min-height:130px}.admin-toggle{font-size:0}.admin-toggle:after{content:\u0022Actualizar\u0022;font-size:12px}}\n\u003C\/style\u003E\u003C\/head\u003E\u003Cbody\u003E\n\u003Cheader\u003E\u003Cdiv class=\u0022head\u0022\u003E\u003Cdiv class=\u0022brand\u0022\u003E\u003Cdiv class=\u0022mark\u0022 aria-hidden=\u0022true\u0022\u003E\u003C\/div\u003E\u003Cdiv\u003E\u003Cdiv class=\u0022eyebrow\u0022\u003EODISMET\u003C\/div\u003E\u003Ch1 id=\u0022title\u0022\u003E1.05 Comparativa\u003C\/h1\u003E\u003C\/div\u003E\u003C\/div\u003E\u003Cbutton id=\u0022adminToggle\u0022 class=\u0022admin-toggle\u0022 type=\u0022button\u0022 aria-expanded=\u0022false\u0022\u003E\u2699 Actualizar datos\u003C\/button\u003E\u003C\/div\u003E\u003C\/header\u003E\n\u003Cmain\u003E\n\u003Csection id=\u0022admin\u0022 class=\u0022admin\u0022 aria-label=\u0022Zona privada de actualizaci\u00f3n\u0022\u003E\u003Cstrong\u003EActualizaci\u00f3n local del indicador\u003C\/strong\u003E\u003Cp class=\u0022hint\u0022\u003EEsta zona solo aparece en modo administrador y requiere una clave. La actualizaci\u00f3n afecta \u00fanicamente a esta sesi\u00f3n del navegador.\u003C\/p\u003E\u003Cdiv id=\u0022drop\u0022 class=\u0022drop\u0022 tabindex=\u00220\u0022 role=\u0022button\u0022\u003E\u003Cb\u003EArrastra aqu\u00ed el Excel de actualizaci\u00f3n\u003C\/b\u003E\u003Cbr\u003E\u003Cspan class=\u0022hint\u0022\u003Eo\u003C\/span\u003E\u003Cbr\u003E\u003Cbutton id=\u0022pick\u0022 class=\u0022btn\u0022 type=\u0022button\u0022\u003ESeleccionar Excel\u003C\/button\u003E\u003Cinput id=\u0022file\u0022 type=\u0022file\u0022 accept=\u0022.xlsx,application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet\u0022\u003E\u003C\/div\u003E\u003Cdiv id=\u0022status\u0022 class=\u0022status\u0022\u003EDatos iniciales: 1_05_comparativa.xlsx\u003C\/div\u003E\u003C\/section\u003E\n\u003Cdiv id=\u0022dataState\u0022 class=\u0022data-state\u0022\u003E\u003Cspan class=\u0022dot\u0022\u003E\u003C\/span\u003E\u003Cspan id=\u0022dataText\u0022\u003ECargando datos desde el repositorio\u2026\u003C\/span\u003E\u003Cbutton id=\u0022refreshBtn\u0022 class=\u0022refresh-btn\u0022 type=\u0022button\u0022 aria-label=\u0022Actualizar datos desde el repositorio\u0022\u003E\u21bb Actualizar\u003C\/button\u003E\u003C\/div\u003E\n\u003Csection class=\u0022kpis\u0022\u003E\n\u003Carticle class=\u0022kpi rate\u0022\u003E\u003Cdiv class=\u0022klabel\u0022\u003ETasa de paro\u003C\/div\u003E\u003Cdiv id=\u0022kRate\u0022 class=\u0022kvalue\u0022\u003E18,5 %\u003C\/div\u003E\u003Cdiv class=\u0022knote\u0022\u003EPersonas con discapacidad\u003C\/div\u003E\u003C\/article\u003E\n\u003Carticle class=\u0022kpi gap\u0022\u003E\u003Cdiv class=\u0022klabel\u0022\u003EDiferencia entre poblaciones\u003C\/div\u003E\u003Cdiv id=\u0022kGap\u0022 class=\u0022kvalue\u0022\u003E+7,3 \u003Cspan class=\u0022unit\u0022\u003Epuntos\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv class=\u0022knote\u0022\u003ETasa personas con discapacidad menos tasa personas sin discapacidad\u003C\/div\u003E\u003C\/article\u003E\n\u003Carticle id=\u0022evoCard\u0022 class=\u0022kpi evolution\u0022\u003E\u003Cdiv class=\u0022klabel\u0022\u003EEvoluci\u00f3n de la tasa de paro\u003C\/div\u003E\u003Cdiv id=\u0022kEvo\u0022 class=\u0022kvalue\u0022\u003E\u003Cspan class=\u0022trend\u0022\u003E\u25bc\u003C\/span\u003E-1,2 \u003Cspan class=\u0022unit\u0022\u003Epuntos\u003C\/span\u003E\u003C\/div\u003E\u003Cdiv class=\u0022knote\u0022\u003ERespecto al a\u00f1o anterior\u003C\/div\u003E\u003C\/article\u003E\n\u003C\/section\u003E\n\u003Csection class=\u0022cards\u0022\u003E\u003Carticle class=\u0022card\u0022\u003E\u003Ch2\u003EComparativa entre poblaciones\u003C\/h2\u003E\u003Cdiv class=\u0022hint\u0022\u003ETasa de paro, en porcentaje\u003C\/div\u003E\u003Cdiv id=\u0022bar\u0022 class=\u0022chart\u0022\u003E\u003C\/div\u003E\u003C\/article\u003E\u003Carticle class=\u0022card\u0022\u003E\u003Ch2\u003EConclusiones\u003C\/h2\u003E\u003Cdiv id=\u0022conclusion\u0022 class=\u0022conclusion\u0022\u003E\u003C\/div\u003E\u003Cdiv class=\u0022source\u0022 id=\u0022sourceNote\u0022\u003EFuente: repositorio de datos ODISMET. Unidad: porcentaje y puntos porcentuales.\u003C\/div\u003E\u003C\/article\u003E\u003C\/section\u003E\n\u003Cdiv class=\u0022actions\u0022\u003E\u003Cbutton id=\u0022btnMail\u0022 class=\u0022btn mailbtn\u0022 type=\u0022button\u0022\u003E\u2709 Generar borrador\u003C\/button\u003E\u003C\/div\u003E\n\u003C\/main\u003E\u003Cdiv class=\u0022footer\u0022\u003EODISMET \u00b7 Observatorio sobre discapacidad y mercado de trabajo en Espa\u00f1a\u003C\/div\u003E\n\u003Cdiv id=\u0022mailModal\u0022 class=\u0022modal\u0022 role=\u0022dialog\u0022 aria-modal=\u0022true\u0022\u003E\u003Cdiv class=\u0022modalbox\u0022\u003E\u003Cdiv class=\u0022modalhead\u0022\u003E\u003Cdiv\u003E\u003Ch2\u003ERevisar borrador\u003C\/h2\u003E\u003Cp class=\u0022hint\u0022\u003EComprueba y edita el contenido antes de abrirlo en tu cliente de correo.\u003C\/p\u003E\u003C\/div\u003E\u003Cbutton id=\u0022closeMail\u0022 class=\u0022close\u0022 type=\u0022button\u0022\u003E\u00d7\u003C\/button\u003E\u003C\/div\u003E\u003Cdiv class=\u0022notice\u0022\u003E\u003Cb\u003ENo se enviar\u00e1 autom\u00e1ticamente.\u003C\/b\u003E Se abrir\u00e1 un mensaje nuevo para revisi\u00f3n y env\u00edo manual.\u003C\/div\u003E\u003Cdiv class=\u0022field\u0022\u003E\u003Clabel\u003EDestinatario, opcional\u003C\/label\u003E\u003Cinput id=\u0022mailTo\u0022 type=\u0022email\u0022\u003E\u003C\/div\u003E\u003Cdiv class=\u0022field\u0022\u003E\u003Clabel\u003EAsunto\u003C\/label\u003E\u003Cinput id=\u0022mailSubject\u0022\u003E\u003C\/div\u003E\u003Cdiv class=\u0022field\u0022\u003E\u003Clabel\u003EContenido\u003C\/label\u003E\u003Ctextarea id=\u0022mailBody\u0022\u003E\u003C\/textarea\u003E\u003C\/div\u003E\u003Cdiv class=\u0022modalactions\u0022\u003E\u003Cbutton id=\u0022cancelMail\u0022 class=\u0022btn secondary\u0022\u003ECancelar\u003C\/button\u003E\u003Cbutton id=\u0022openMail\u0022 class=\u0022btn\u0022\u003EAbrir borrador en correo\u003C\/button\u003E\u003C\/div\u003E\u003C\/div\u003E\u003C\/div\u003E\n\u003Cscript\u003E\n\u0027use strict\u0027;\nconst $=id=\u003Edocument.getElementById(id), esc=s=\u003EString(s??\u0027\u0027).replace(\/[\u0026\u003C\u003E\u0022\u0027]\/g,c=\u003E({\u0027\u0026\u0027:\u0027\u0026amp;\u0027,\u0027\u003C\u0027:\u0027\u0026lt;\u0027,\u0027\u003E\u0027:\u0027\u0026gt;\u0027,\u0027\u0022\u0027:\u0027\u0026quot;\u0027,\u0022\u0027\u0022:\u0027\u0026#39;\u0027}[c]));\nlet D={file:\u00271_05_comparativa.xlsx\u0027,rows:[{Grupo:\u0027Personas con discapacidad\u0027,Valor:18.5,\u0027A\u00f1o anterior\u0027:19.7},{Grupo:\u0027Personas sin discapacidad\u0027,Valor:11.2,\u0027A\u00f1o anterior\u0027:\u0027\u0027},{Grupo:\u0027Total\u0027,Valor:11.4,\u0027A\u00f1o anterior\u0027:\u0027\u0027}]};\n\n\/\/ URL raw del Excel en el repositorio de datos (sustituye a Google Apps Script)\nconst XLSX_URL=\u0027https:\/\/raw.githubusercontent.com\/LuisenQ\/Odismet_datos\/main\/1_05_comparativa.xlsx\u0027;\n\nconst num=v=\u003E{if(typeof v===\u0027number\u0027)return isFinite(v)?v:null;if(v==null||v===\u0027\u0027)return null;let s=String(v).trim().replace(\/\\s|%\/g,\u0027\u0027);if(\/^[-+]?\\d{1,3}(\\.\\d{3})*,\\d+$\/.test(s))s=s.replace(\/\\.\/g,\u0027\u0027).replace(\u0027,\u0027,\u0027.\u0027);else if(\/^[-+]?\\d+,\\d+$\/.test(s))s=s.replace(\u0027,\u0027,\u0027.\u0027);let n=Number(s);return isFinite(n)?n:null};\nconst fmt=(n,d=1)=\u003Enew Intl.NumberFormat(\u0027es-ES\u0027,{minimumFractionDigits:d,maximumFractionDigits:d}).format(n);\nfunction findRow(term){return D.rows.find(r=\u003EString(r.Grupo??\u0027\u0027).toLowerCase().includes(term))}\nlet lastChartData=null;\nfunction render(){let pd=findRow(\u0027con discapacidad\u0027),ps=findRow(\u0027sin discapacidad\u0027),a=pd\u0026\u0026num(pd.Valor),b=ps\u0026\u0026num(ps.Valor),prev=pd\u0026\u0026num(pd[\u0027A\u00f1o anterior\u0027]);if(a===null||a===undefined||b===null||b===undefined){$(\u0027conclusion\u0027).innerHTML=\u0027\u003Cspan class=\u0022error\u0022\u003EEl Excel debe incluir las filas \u201cPersonas con discapacidad\u201d y \u201cPersonas sin discapacidad\u201d, y la columna Valor.\u003C\/span\u003E\u0027;return}let gap=a-b,evo=prev===null?null:a-prev;$(\u0027kRate\u0027).textContent=fmt(a)+\u0027 %\u0027;$(\u0027kGap\u0027).innerHTML=(gap\u003E=0?\u0027+\u0027:\u0027\u0027)+fmt(gap)+\u0027 \u003Cspan class=\u0022unit\u0022\u003Epuntos\u003C\/span\u003E\u0027;if(evo===null){$(\u0027kEvo\u0027).textContent=\u0027Sin dato\u0027;$(\u0027evoCard\u0027).classList.remove(\u0027bad\u0027)}else{$(\u0027kEvo\u0027).innerHTML=`\u003Cspan class=\u0022trend\u0022\u003E${evo\u003E0?\u0027\u25b2\u0027:evo\u003C0?\u0027\u25bc\u0027:\u0027\u25cf\u0027}\u003C\/span\u003E${evo\u003E0?\u0027+\u0027:\u0027\u0027}${fmt(evo)} \u003Cspan class=\u0022unit\u0022\u003Epuntos\u003C\/span\u003E`;$(\u0027evoCard\u0027).classList.toggle(\u0027bad\u0027,evo\u003E0)}let total=findRow(\u0027total\u0027),tv=total\u0026\u0026num(total.Valor),chartData=[[pd.Grupo,a],[ps.Grupo,b]];if(tv!==null\u0026\u0026tv!==undefined)chartData.push([total.Grupo,tv]);lastChartData=chartData;drawBar(chartData);let comp=gap\u003E=0?`superando en \u003Cstrong\u003E${fmt(Math.abs(gap))} puntos\u003C\/strong\u003E la registrada entre las personas sin discapacidad`:`situ\u00e1ndose \u003Cstrong\u003E${fmt(Math.abs(gap))} puntos por debajo\u003C\/strong\u003E de la registrada entre las personas sin discapacidad`;let evotxt=evo===null?\u0027No se dispone del valor del a\u00f1o anterior para calcular la evoluci\u00f3n.\u0027:evo\u003C0?`La tasa se ha reducido \u003Cstrong\u003E${fmt(Math.abs(evo))} puntos\u003C\/strong\u003E respecto al a\u00f1o anterior.`:evo\u003E0?`La tasa ha aumentado \u003Cstrong\u003E${fmt(evo)} puntos\u003C\/strong\u003E respecto al a\u00f1o anterior.`:\u0027La tasa se mantiene sin variaci\u00f3n respecto al a\u00f1o anterior.\u0027;$(\u0027conclusion\u0027).innerHTML=`\u003Cp\u003ELa tasa de paro de las personas con discapacidad alcanza el \u003Cstrong\u003E${fmt(a)} %\u003C\/strong\u003E, ${comp}. ${evotxt}\u003C\/p\u003E`}\n\n\/\/ Gr\u00e1fico de barras: ahora se dimensiona seg\u00fan el tama\u00f1o real de su caja (la llena por completo)\n\/\/ en vez de un tama\u00f1o fijo, y usa una fuente algo mayor para las etiquetas.\nfunction drawBar(data){\n  const box=$(\u0027bar\u0027);\n  const W=Math.max(box.clientWidth,320), H=Math.max(box.clientHeight,240);\n  const L=Math.min(270,Math.max(200,W*0.32)), R=40, T=30, B=46, iw=W-L-R, ih=H-T-B;\n  const max=Math.max(...data.map(x=\u003Ex[1]),1)*1.18;\n  const gap=ih\/data.length, bh=Math.min(gap*0.62,90);\n  let svg=`\u003Csvg viewBox=\u00220 0 ${W} ${H}\u0022 role=\u0022img\u0022 aria-label=\u0022Comparativa de tasas de paro\u0022\u003E`;\n  for(let i=0;i\u003C=4;i++){let x=L+iw*i\/4;svg+=`\u003Cline class=\u0022gridline\u0022 x1=\u0022${x}\u0022 y1=\u0022${T}\u0022 x2=\u0022${x}\u0022 y2=\u0022${H-B}\u0022\/\u003E\u003Ctext class=\u0022axis\u0022 x=\u0022${x}\u0022 y=\u0022${H-16}\u0022 text-anchor=\u0022middle\u0022\u003E${fmt(max*i\/4)} %\u003C\/text\u003E`}\n  data.forEach(([k,v],i)=\u003E{\n    let y=T+(gap-bh)\/2+i*gap,w=v\/max*iw,c=[\u0027#d22630\u0027,\u0027#ffd100\u0027,\u0027#7b8794\u0027][i]||\u0027#7b8794\u0027;\n    svg+=`\u003Ctext class=\u0022axis\u0022 x=\u0022${L-12}\u0022 y=\u0022${y+bh\/2+5}\u0022 text-anchor=\u0022end\u0022 font-size=\u002215\u0022\u003E${esc(k)}\u003C\/text\u003E\u003Crect x=\u0022${L}\u0022 y=\u0022${y}\u0022 width=\u0022${w}\u0022 height=\u0022${bh}\u0022 rx=\u00229\u0022 fill=\u0022${c}\u0022\u003E\u003Ctitle\u003E${esc(k)}: ${fmt(v)} %\u003C\/title\u003E\u003C\/rect\u003E\u003Ctext x=\u0022${L+w+10}\u0022 y=\u0022${y+bh\/2+7}\u0022 font-size=\u002221\u0022 font-weight=\u0022800\u0022\u003E${fmt(v)} %\u003C\/text\u003E`;\n  });\n  $(\u0027bar\u0027).innerHTML=svg+\u0027\u003C\/svg\u003E\u0027;\n}\n\/\/ Redibuja el gr\u00e1fico si cambia el tama\u00f1o de su caja (responsive real, sin recargar datos)\nnew ResizeObserver(()=\u003E{if(lastChartData)drawBar(lastChartData)}).observe($(\u0027bar\u0027));\n\nfunction titleFromFile(name){return name.replace(\/\\.[^.]+$\/,\u0027\u0027).replace(\/_\/g,\u0027.\u0027).replace(\/-\/g,\u0027 \u0027).replace(\/\\.+\/g,\u0027.\u0027).replace(\/(^|\\s)0+(\\d)\/g,\u0027$1$2\u0027).replace(\/^(\\d+)\\.(\\d+)\\s*\/,(_,a,b)=\u003E`${a}.${b.padStart(2,\u00270\u0027)} `).trim().replace(\/\\b\\w\/g,c=\u003Ec.toUpperCase())}\nconst ADMIN_HASH=\u0027b1bd8de945eb8b0bd244e374f8fa43479effe029effcd16767e59935187ae7e0\u0027;\nasync function sha256(t){let b=await crypto.subtle.digest(\u0027SHA-256\u0027,new TextEncoder().encode(t));return [...new Uint8Array(b)].map(x=\u003Ex.toString(16).padStart(2,\u00270\u0027)).join(\u0027\u0027)}\nconst adminMode=new URLSearchParams(location.search).get(\u0027admin\u0027)===\u00271\u0027;\nif(adminMode)$(\u0027adminToggle\u0027).style.display=\u0027block\u0027;\n$(\u0027adminToggle\u0027).onclick=async()=\u003E{if(!$(\u0027admin\u0027).classList.contains(\u0027open\u0027)){let pin=prompt(\u0027Introduce la clave de actualizaci\u00f3n\u0027);if(pin===null)return;if(await sha256(pin)!==ADMIN_HASH){alert(\u0027Clave incorrecta\u0027);return}}let o=$(\u0027admin\u0027).classList.toggle(\u0027open\u0027);$(\u0027adminToggle\u0027).setAttribute(\u0027aria-expanded\u0027,o)};$(\u0027pick\u0027).onclick=e=\u003E{e.stopPropagation();$(\u0027file\u0027).click()};$(\u0027drop\u0027).onclick=e=\u003E{if(e.target.id!==\u0027pick\u0027)$(\u0027file\u0027).click()};[\u0027dragenter\u0027,\u0027dragover\u0027].forEach(n=\u003E$(\u0027drop\u0027).addEventListener(n,e=\u003E{e.preventDefault();$(\u0027drop\u0027).classList.add(\u0027over\u0027)}));[\u0027dragleave\u0027,\u0027drop\u0027].forEach(n=\u003E$(\u0027drop\u0027).addEventListener(n,e=\u003E{e.preventDefault();$(\u0027drop\u0027).classList.remove(\u0027over\u0027)}));$(\u0027drop\u0027).addEventListener(\u0027drop\u0027,e=\u003Eload(e.dataTransfer.files[0]));$(\u0027file\u0027).onchange=e=\u003Eload(e.target.files[0]);\n\n\/\/ Carga los datos publicados directamente desde el .xlsx del repositorio (sin API intermedia)\nasync function loadPublishedData(){\n  const state=$(\u0027dataState\u0027);\n  const text=$(\u0027dataText\u0027);\n  const button=$(\u0027refreshBtn\u0027);\n  button.disabled=true;\n  state.className=\u0027data-state\u0027;\n  text.textContent=\u0027Actualizando datos desde el repositorio\u2026\u0027;\n  try{\n    const resp=await fetch(XLSX_URL+\u0027?v=\u0027+Date.now(),{cache:\u0027no-store\u0027});\n    if(!resp.ok) throw new Error(\u0027HTTP \u0027+resp.status);\n    const ab=await resp.arrayBuffer();\n    const zip=await unzip(ab);\n    const rows=await parseXlsx(zip);\n    if(!rows.length) throw new Error(\u0027El Excel no contiene filas legibles\u0027);\n    D={file:\u0027GitHub: 1_05_comparativa.xlsx\u0027,rows};\n    render();\n    state.className=\u0027data-state ok\u0027;\n    text.textContent=\u0027Datos actualizados desde el repositorio\u0027;\n  }catch(error){\n    console.error(\u0027Error cargando XLSX_URL:\u0027,XLSX_URL,error);\n    render();\n    state.className=\u0027data-state warn\u0027;\n    text.textContent=\u0027No se pudieron actualizar los datos. Se muestran los datos de respaldo incluidos en el HTML.\u0027;\n  }finally{\n    button.disabled=false;\n  }\n}\n$(\u0027refreshBtn\u0027).onclick=loadPublishedData;\nasync function load(file){if(!file||!\/\\.xlsx$\/i.test(file.name))return status(\u0027Selecciona un archivo .xlsx v\u00e1lido.\u0027,true);try{status(\u0027Procesando localmente\u2026\u0027);let z=await unzip(await file.arrayBuffer()),rows=await parseXlsx(z);D={file:file.name,rows};$(\u0027title\u0027).textContent=titleFromFile(file.name);render();$(\u0027dataState\u0027).className=\u0027data-state ok\u0027;$(\u0027dataText\u0027).textContent=\u0027Datos cargados manualmente desde \u0027+file.name;status(`${file.name} actualizado localmente`)}catch(e){status(\u0027No se pudo leer el Excel: \u0027+e.message,true)}}function status(t,e=false){$(\u0027status\u0027).innerHTML=e?`\u003Cspan class=\u0022error\u0022\u003E${esc(t)}\u003C\/span\u003E`:esc(t)}\nasync function unzip(ab){let b=new Uint8Array(ab),dv=new DataView(ab),e=-1;for(let i=b.length-22;i\u003E=Math.max(0,b.length-65557);i--)if(dv.getUint32(i,true)===0x06054b50){e=i;break}if(e\u003C0)throw Error(\u0027ZIP no v\u00e1lido\u0027);let count=dv.getUint16(e+10,true),off=dv.getUint32(e+16,true),out={};for(let n=0;n\u003Ccount;n++){let method=dv.getUint16(off+10,true),cs=dv.getUint32(off+20,true),nl=dv.getUint16(off+28,true),xl=dv.getUint16(off+30,true),cl=dv.getUint16(off+32,true),lo=dv.getUint32(off+42,true),name=new TextDecoder().decode(b.slice(off+46,off+46+nl)),lnl=dv.getUint16(lo+26,true),lxl=dv.getUint16(lo+28,true),data=b.slice(lo+30+lnl+lxl,lo+30+lnl+lxl+cs);if(!name.endsWith(\u0027\/\u0027)){if(method===0)out[name]=data;else if(method===8){let ds=new DecompressionStream(\u0027deflate-raw\u0027),resp=new Response(new Blob([data]).stream().pipeThrough(ds));out[name]=new Uint8Array(await resp.arrayBuffer())}}off+=46+nl+xl+cl}return out}const xml=u=\u003Enew DOMParser().parseFromString(new TextDecoder().decode(u),\u0027application\/xml\u0027);async function parseXlsx(z){let ss=[];if(z[\u0027xl\/sharedStrings.xml\u0027])xml(z[\u0027xl\/sharedStrings.xml\u0027]).querySelectorAll(\u0027si\u0027).forEach(x=\u003Ess.push([...x.querySelectorAll(\u0027t\u0027)].map(t=\u003Et.textContent).join(\u0027\u0027)));let wb=xml(z[\u0027xl\/workbook.xml\u0027]),rel=xml(z[\u0027xl\/_rels\/workbook.xml.rels\u0027]),rm={};rel.querySelectorAll(\u0027Relationship\u0027).forEach(x=\u003Erm[x.getAttribute(\u0027Id\u0027)]=x.getAttribute(\u0027Target\u0027));let sh=wb.querySelector(\u0027sheet\u0027),rid=sh.getAttribute(\u0027r:id\u0027)||sh.getAttributeNS(\u0027http:\/\/schemas.openxmlformats.org\/officeDocument\/2006\/relationships\u0027,\u0027id\u0027),path=\u0027xl\/\u0027+rm[rid].replace(\/^\\.\\\/\/,\u0027\u0027).replace(\/^\\.\\.\\\/\/,\u0027\u0027),doc=xml(z[path]),mat=[];doc.querySelectorAll(\u0027sheetData row\u0027).forEach(row=\u003E{let a=[];row.querySelectorAll(\u0027c\u0027).forEach(c=\u003E{let letters=(c.getAttribute(\u0027r\u0027).match(\/[A-Z]+\/)||[\u0027A\u0027])[0],col=[...letters].reduce((x,ch)=\u003Ex*26+ch.charCodeAt(0)-64,0)-1,t=c.getAttribute(\u0027t\u0027),v=c.querySelector(\u0027v\u0027)?.textContent??\u0027\u0027,val=t===\u0027s\u0027?ss[+v]:(t===\u0027inlineStr\u0027?[...c.querySelectorAll(\u0027t\u0027)].map(x=\u003Ex.textContent).join(\u0027\u0027):(v!==\u0027\u0027\u0026\u0026isFinite(Number(v))?Number(v):v));a[col]=val});mat.push(a)});let h=mat.shift().map((x,i)=\u003EString(x||`Columna ${i+1}`).trim());return mat.filter(a=\u003Ea.some(v=\u003Ev!==undefined\u0026\u0026v!==\u0027\u0027)).map(a=\u003EObject.fromEntries(h.map((x,i)=\u003E[x,a[i]??\u0027\u0027])))}\nfunction draft(){let date=new Intl.DateTimeFormat(\u0027es-ES\u0027,{dateStyle:\u0027long\u0027}).format(new Date());$(\u0027mailSubject\u0027).value=`${$(\u0027title\u0027).textContent} \u00b7 Indicador ODISMET`;$(\u0027mailBody\u0027).value=`${$(\u0027title\u0027).textContent}\\n\\nFecha: ${date}\\n\\n${$(\u0027conclusion\u0027).innerText}\\n\\nIndicadores\\n\u2022 Tasa de paro: ${$(\u0027kRate\u0027).textContent}\\n\u2022 Diferencia entre poblaciones: ${$(\u0027kGap\u0027).textContent}\\n\u2022 Evoluci\u00f3n: ${$(\u0027kEvo\u0027).innerText}\\n\\nBorrador generado localmente. Revisar antes de enviar.`;$(\u0027mailModal\u0027).classList.add(\u0027open\u0027)}$(\u0027btnMail\u0027).onclick=draft;const close=()=\u003E$(\u0027mailModal\u0027).classList.remove(\u0027open\u0027);$(\u0027closeMail\u0027).onclick=close;$(\u0027cancelMail\u0027).onclick=close;$(\u0027mailModal\u0027).onclick=e=\u003E{if(e.target===$(\u0027mailModal\u0027))close()};$(\u0027openMail\u0027).onclick=()=\u003Elocation.href=`mailto:${encodeURIComponent($(\u0027mailTo\u0027).value.trim())}?subject=${encodeURIComponent($(\u0027mailSubject\u0027).value)}\u0026body=${encodeURIComponent($(\u0027mailBody\u0027).value)}`;\nloadPublishedData();\n\u003C\/script\u003E\u003C\/body\u003E\u003C\/html\u003E\u003C\/div\u003E\n      \n\u003C!-- END OUTPUT from \u0027themes\/contrib\/noahs_builder_theme\/templates\/field\/field.html.twig\u0027 --\u003E\n\n\n          \u003C\/div\u003E\n  \u003C\/div\u003E\n\n\u003C!-- END CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/paragraph\/paragraph--default.html.twig\u0027 --\u003E\n\n\u003C\/div\u003E\n      \n\u003C!-- END OUTPUT from \u0027themes\/contrib\/noahs_builder_theme\/templates\/field\/field.html.twig\u0027 --\u003E\n\n\n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027field\u0027 --\u003E\n\u003C!-- FILE NAME SUGGESTIONS:\n   \u25aa\ufe0f field--node--field-footnote--data-sample.html.twig\n   \u25aa\ufe0f field--node--field-footnote.html.twig\n   \u25aa\ufe0f field--node--data-sample.html.twig\n   \u25aa\ufe0f field--field-footnote.html.twig\n   \u25aa\ufe0f field--text-long.html.twig\n   \u2705 field.html.twig\n--\u003E\n\u003C!-- BEGIN OUTPUT from \u0027themes\/contrib\/noahs_builder_theme\/templates\/field\/field.html.twig\u0027 --\u003E\n\n            \u003Cdiv class=\u0022field field-field-footnote field-type-text-long field-label-hidden field-item\u0022\u003E\u003Cp\u003E\u003Cspan style=\u0022color:#c0392b;\u0022\u003E\u003Cstrong\u003EExplicaci\u00f3n del gr\u00e1fico:\u003C\/strong\u003E\u003C\/span\u003E\u003C\/p\u003E\u003Cp\u003EEste gr\u00e1fico de barras muestra la tasa de paro de la poblaci\u00f3n en funci\u00f3n de la discapacidad, correspondiente al a\u00f1o 2024. Estos son los valores que contiene el gr\u00e1fico. Personas con discapacidad 18,5; personas sin discapacidad 11,2; y total de poblaci\u00f3n 11,4.\u003C\/p\u003E\u003C\/div\u003E\n      \n\u003C!-- END OUTPUT from \u0027themes\/contrib\/noahs_builder_theme\/templates\/field\/field.html.twig\u0027 --\u003E\n\n\n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027pseudo_field\u0027 --\u003E\n\u003C!-- \ud83d\udca1 BEGIN CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/field\/pseudo-field.html.twig\u0027 --\u003E\n\n\u003Cdiv class=\u0022field field-pseudo-social-sharing pt-3\u0022\u003E\n  \u003Cdiv class=\u0022pt-3 border-top border-primary\u0022\u003E\n\n\u003C!-- THEME DEBUG --\u003E\n\u003C!-- THEME HOOK: \u0027item_list\u0027 --\u003E\n\u003C!-- BEGIN OUTPUT from \u0027core\/modules\/system\/templates\/item-list.html.twig\u0027 --\u003E\n\u003Ch3\u003ECompartir:\u003C\/h3\u003E\u003Cul class=\u0022share-container__items d-flex gap-3 flex-column flex-sm-row\u0022\u003E\u003Cli class=\u0022share-container__item border-0 rounded-0 p-0 col-12 col-sm-auto share-container__item-facebook\u0022\u003E\u003Ca href=\u0022https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A\/\/odismet.org\/data\/tasa-de-paro-de-la-poblacion-en-funcion-de-la-discapacidad-2024\u0022 class=\u0022text-white share-link px-3 py-2 lh-sm\u0022 target=\u0022_blank\u0022\u003EFacebook\u003C\/a\u003E\u003C\/li\u003E\u003Cli class=\u0022share-container__item border-0 rounded-0 p-0 col-12 col-sm-auto share-container__item-twitter\u0022\u003E\u003Ca href=\u0022https:\/\/twitter.com\/intent\/tweet?text=Tasa%20de%20paro%20de%20la%20poblaci%C3%B3n%20en%20funci%C3%B3n%20de%20la%20discapacidad.%202024\u0026amp;url=https%3A\/\/odismet.org\/data\/tasa-de-paro-de-la-poblacion-en-funcion-de-la-discapacidad-2024\u0022 class=\u0022text-white share-link px-3 py-2 lh-sm\u0022 target=\u0022_blank\u0022\u003ETwitter\u003C\/a\u003E\u003C\/li\u003E\u003Cli class=\u0022share-container__item border-0 rounded-0 p-0 col-12 col-sm-auto share-container__item-linkedin\u0022\u003E\u003Ca href=\u0022https:\/\/www.linkedin.com\/shareArticle?mini=true\u0026amp;url=https%3A\/\/odismet.org\/data\/tasa-de-paro-de-la-poblacion-en-funcion-de-la-discapacidad-2024\u0026amp;title=Tasa%20de%20paro%20de%20la%20poblaci%C3%B3n%20en%20funci%C3%B3n%20de%20la%20discapacidad.%202024\u0022 class=\u0022text-white share-link px-3 py-2 lh-sm\u0022 target=\u0022_blank\u0022\u003ELinkedin\u003C\/a\u003E\u003C\/li\u003E\u003C\/ul\u003E\n\u003C!-- END OUTPUT from \u0027core\/modules\/system\/templates\/item-list.html.twig\u0027 --\u003E\n\n\n\u003C\/div\u003E\n\n\u003C!-- END CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/field\/pseudo-field.html.twig\u0027 --\u003E\n\n\n    \u003C\/div\u003E\n\u003C\/article\u003E\n\n\n\u003C!-- END CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/content\/node--data-sample.html.twig\u0027 --\u003E\n\n\u003C\/div\u003E\n\n\u003C!-- END CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/form\/container.html.twig\u0027 --\u003E\n\n\u003C\/div\u003E\n\n\u003C!-- END CUSTOM TEMPLATE OUTPUT from \u0027themes\/custom\/sub_noahs_theme\/templates\/form\/container.html.twig\u0027 --\u003E\n\n","settings":null,"effect":"fade","speed":"slow"}]