{"id":610,"date":"2026-02-24T08:05:03","date_gmt":"2026-02-24T08:05:03","guid":{"rendered":"https:\/\/danielepatente.it\/?page_id=610"},"modified":"2026-02-24T23:47:46","modified_gmt":"2026-02-24T23:47:46","slug":"rentri-prova","status":"publish","type":"page","link":"https:\/\/danielepatente.it\/index.php\/rentri-prova\/","title":{"rendered":"RENTRI PROVA"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"610\" class=\"elementor elementor-610\">\n\t\t\t\t<div class=\"elementor-element elementor-element-464317c e-flex e-con-boxed e-con e-parent\" data-id=\"464317c\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-bf9090a elementor-widget elementor-widget-html\" data-id=\"bf9090a\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<!DOCTYPE html>\r\n<html lang=\"it\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>RENTRI Manager \u2014 ECOF Italia<\/title>\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300&family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,300&display=swap\" rel=\"stylesheet\">\r\n<style>\r\n:root {\r\n  --bg:       #ffffff;\r\n  --bg2:      #f7f8f6;\r\n  --bg3:      #f0f2ee;\r\n  --surface:  #f4f5f2;\r\n  --surface2: #eceee9;\r\n  --border:   #dde0d8;\r\n  --border2:  #c8ccc2;\r\n  --green:    #2d6a4f;\r\n  --green2:   #1b4332;\r\n  --green-dim:#e8f5ee;\r\n  --teal:     #2a7c6f;\r\n  --amber:    #b5620a;\r\n  --red:      #c0392b;\r\n  --blue:     #1a5c9e;\r\n  --text:     #1a1f18;\r\n  --text2:    #4a5244;\r\n  --text3:    #8a9485;\r\n  --mono:     'DM Mono', monospace;\r\n  --sans:     'DM Sans', sans-serif;\r\n}\r\n\r\n*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\r\nhtml { scroll-behavior: smooth; }\r\nbody { font-family: var(--sans); background: rgba(247,248,246,.97); color: var(--text); min-height: 100vh; overflow-x: hidden; }\r\n\r\n#page-search { min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; padding: 2rem; }\r\n#page-search::after { content: ''; position: fixed; inset: 0; background-image: radial-gradient(circle, var(--border) 1px, transparent 1px); background-size: 28px 28px; pointer-events: none; opacity: .45; z-index: 0; }\r\n.logo-area { text-align: center; margin-bottom: 3.5rem; animation: fadeUp .7s ease both; }\r\n.logo-sub { font-size: .75rem; color: var(--text3); margin-top: .3rem; letter-spacing: .08em; font-family: var(--mono); }\r\n.search-wrap { width: 100%; max-width: 560px; position: relative; animation: fadeUp .7s .1s ease both; }\r\n.search-input { width: 100%; padding: 1rem 3.5rem 1rem 1.25rem; background: var(--bg); border: 1.5px solid var(--border2); border-radius: 12px; color: var(--text); font-family: var(--sans); font-size: 1rem; outline: none; transition: border-color .2s, box-shadow .2s; box-shadow: 0 2px 12px rgba(0,0,0,.06); }\r\n.search-input::placeholder { color: var(--text3); }\r\n.search-input:focus { border-color: var(--green); box-shadow: 0 0 0 3px rgba(45,106,79,.1), 0 4px 20px rgba(0,0,0,.08); }\r\n.search-icon { position: absolute; right: 1rem; top: 50%; transform: translateY(-50%); color: var(--text3); font-size: 1.1rem; pointer-events: none; }\r\n.search-results { position: absolute; top: calc(100% + .5rem); left: 0; right: 0; background: var(--bg); border: 1.5px solid var(--border2); border-radius: 10px; overflow: hidden; z-index: 100; box-shadow: 0 8px 40px rgba(0,0,0,.14); display: none; }\r\n.search-results.open { display: block; }\r\n.result-item { padding: .75rem 1.1rem; cursor: pointer; transition: background .15s; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: .75rem; }\r\n.result-item:last-child { border-bottom: none; }\r\n.result-item:hover { background: var(--surface2); }\r\n.result-icon { width: 32px; height: 32px; border-radius: 8px; background: var(--green-dim); display: flex; align-items: center; justify-content: center; font-size: .8rem; flex-shrink: 0; color: var(--green); }\r\n.result-name { font-size: .88rem; font-weight: 500; }\r\n.result-meta { font-size: .72rem; color: var(--text3); font-family: var(--mono); margin-top: .1rem; }\r\n.search-hint { text-align: center; margin-top: 1.5rem; font-size: .75rem; color: var(--text3); font-family: var(--mono); animation: fadeUp .7s .2s ease both; }\r\n.search-hint span { color: var(--text2); }\r\n.admin-link { position: fixed; bottom: 1.5rem; right: 1.5rem; font-size: .7rem; font-family: var(--mono); color: var(--text3); cursor: pointer; padding: .4rem .7rem; border: 1px solid var(--border); border-radius: 6px; transition: all .2s; text-decoration: none; background: var(--bg); z-index: 10; }\r\n.admin-link:hover { color: var(--green); border-color: var(--green); }\r\n\r\n#page-operatore { display: none; min-height: 100vh; }\r\n.op-topbar { position: sticky; top: 0; z-index: 50; background: rgba(255,255,255,.95); backdrop-filter: blur(12px); border-bottom: 1px solid var(--border); padding: .75rem 2rem; display: flex; align-items: center; gap: 1rem; }\r\n.back-btn { display: flex; align-items: center; gap: .4rem; font-size: .78rem; font-family: var(--mono); color: var(--text3); cursor: pointer; padding: .3rem .6rem; border: 1px solid var(--border); border-radius: 6px; background: none; transition: all .15s; white-space: nowrap; }\r\n.back-btn:hover { color: var(--green); border-color: var(--green); }\r\n.op-topbar-name { font-weight: 600; font-size: .9rem; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\r\n.op-topbar-cf { font-family: var(--mono); font-size: .72rem; color: var(--text3); white-space: nowrap; }\r\n.op-hero { padding: 2.5rem 2rem 2rem; border-bottom: 1px solid var(--border); background: linear-gradient(180deg, var(--bg2) 0%, var(--bg) 100%); border-top: 3px solid var(--green); }\r\n.op-hero-inner { max-width: 1100px; margin: 0 auto; }\r\n.op-badge { display: inline-flex; align-items: center; gap: .4rem; font-family: var(--mono); font-size: .65rem; color: var(--green); background: var(--green-dim); border: 1px solid rgba(45,106,79,.25); border-radius: 20px; padding: .2rem .6rem; margin-bottom: .8rem; letter-spacing: .05em; }\r\n.op-nome { font-size: 1.6rem; font-weight: 600; line-height: 1.2; margin-bottom: .6rem; }\r\n.op-meta-row { display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; font-size: .78rem; color: var(--text2); font-family: var(--mono); }\r\n.op-meta-item { display: flex; align-items: center; gap: .3rem; }\r\n.op-meta-label { color: var(--text3); }\r\n.op-meta-val { color: var(--text); }\r\n\r\n.kpi-strip { max-width: 1100px; margin: 0 auto; padding: 1.5rem 2rem; display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1rem; }\r\n.kpi-card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 1rem 1.2rem; transition: border-color .2s; }\r\n.kpi-card:hover { border-color: var(--border2); }\r\n.kpi-label { font-size: .65rem; font-family: var(--mono); color: var(--text3); text-transform: uppercase; letter-spacing: .08em; margin-bottom: .4rem; }\r\n.kpi-val { font-size: 1.5rem; font-weight: 600; font-family: var(--mono); line-height: 1; }\r\n.kpi-val.green { color: var(--green); }\r\n.kpi-val.teal  { color: var(--teal); }\r\n.kpi-val.amber { color: var(--amber); }\r\n.kpi-val.blue  { color: var(--blue); }\r\n.kpi-sub { font-size: .68rem; color: var(--text3); margin-top: .3rem; }\r\n\r\n.op-content { max-width: 1100px; margin: 0 auto; padding: 0 2rem 4rem; display: grid; grid-template-columns: 280px 1fr; gap: 1.5rem; align-items: start; }\r\n.ul-sidebar { position: sticky; top: 60px; }\r\n.section-title { font-family: var(--mono); font-size: .65rem; text-transform: uppercase; letter-spacing: .1em; color: var(--text3); margin-bottom: .75rem; padding-bottom: .4rem; border-bottom: 1px solid var(--border); }\r\n.ul-card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: .85rem 1rem; margin-bottom: .6rem; cursor: pointer; transition: all .15s; position: relative; }\r\n.ul-card:hover { border-color: var(--border2); background: var(--surface2); }\r\n.ul-card.active { border-color: var(--green); background: var(--surface2); box-shadow: 0 0 0 1px var(--green); }\r\n.ul-card-name { font-size: .82rem; font-weight: 500; margin-bottom: .25rem; }\r\n.ul-card-addr { font-size: .7rem; color: var(--text3); line-height: 1.4; }\r\n.ul-cat-dot { position: absolute; top: .85rem; right: .85rem; width: 8px; height: 8px; border-radius: 50%; }\r\n.op-main {}\r\n\r\n.tabs { display: flex; gap: .25rem; margin-bottom: 1.25rem; border-bottom: 1px solid var(--border); padding-bottom: 0; }\r\n.tab-btn { background: none; border: none; color: var(--text3); font-family: var(--mono); font-size: .72rem; letter-spacing: .05em; text-transform: uppercase; padding: .5rem .9rem; cursor: pointer; position: relative; transition: color .15s; }\r\n.tab-btn::after { content: ''; position: absolute; bottom: -1px; left: 0; right: 0; height: 2px; background: var(--green); transform: scaleX(0); transition: transform .2s; border-radius: 2px 2px 0 0; }\r\n.tab-btn:hover { color: var(--text2); }\r\n.tab-btn.active { color: var(--green); }\r\n.tab-btn.active::after { transform: scaleX(1); }\r\n\r\n.reg-toolbar { display: flex; gap: .6rem; margin-bottom: 1rem; flex-wrap: wrap; }\r\n.reg-search { flex: 1; min-width: 180px; padding: .45rem .75rem; background: var(--surface); border: 1px solid var(--border); border-radius: 7px; color: var(--text); font-family: var(--sans); font-size: .8rem; outline: none; }\r\n.reg-search:focus { border-color: var(--green); }\r\n.reg-search::placeholder { color: var(--text3); }\r\n.btn { padding: .45rem .9rem; border-radius: 7px; font-size: .78rem; font-family: var(--mono); cursor: pointer; border: 1px solid var(--border); transition: all .15s; display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap; }\r\n.btn-green { background: var(--green); color: #fff; border-color: var(--green); font-weight: 600; }\r\n.btn-green:hover { background: var(--green2); }\r\n.btn-outline { background: none; color: var(--text2); }\r\n.btn-outline:hover { border-color: var(--border2); color: var(--text); }\r\n.btn-ghost { background: none; border-color: transparent; color: var(--text3); }\r\n.btn-ghost:hover { color: var(--text); }\r\n\r\n.table-wrap { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }\r\ntable { width: 100%; border-collapse: collapse; font-size: .78rem; }\r\nthead { background: var(--bg2); }\r\nth { padding: .6rem .85rem; text-align: left; font-family: var(--mono); font-size: .62rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text3); border-bottom: 1px solid var(--border); white-space: nowrap; }\r\ntd { padding: .6rem .85rem; border-bottom: 1px solid var(--border); vertical-align: middle; }\r\ntr:last-child td { border-bottom: none; }\r\ntbody tr { transition: background .1s; }\r\ntbody tr:hover { background: var(--surface); }\r\n\r\n.badge { display: inline-flex; align-items: center; font-family: var(--mono); font-size: .6rem; font-weight: 500; padding: .15rem .4rem; border-radius: 4px; letter-spacing: .04em; }\r\n.badge-P  { background: rgba(192,57,43,.08); color: var(--red); border: 1px solid rgba(192,57,43,.18); }\r\n.badge-NP { background: rgba(26,92,158,.07); color: var(--blue); border: 1px solid rgba(26,92,158,.18); }\r\n.badge-R  { background: rgba(45,106,79,.08); color: var(--green); border: 1px solid rgba(45,106,79,.18); }\r\n.badge-D  { background: rgba(181,98,10,.07); color: var(--amber); border: 1px solid rgba(181,98,10,.18); }\r\n.mono-cell { font-family: var(--mono); }\r\n.action-btn { background: none; border: none; color: var(--text3); cursor: pointer; padding: .2rem .35rem; border-radius: 4px; font-size: .8rem; transition: all .1s; }\r\n.action-btn:hover { color: var(--text); background: var(--surface2); }\r\n.action-btn.del:hover { color: var(--red); }\r\n\r\n.empty { text-align: center; padding: 3rem 1rem; color: var(--text3); font-size: .82rem; }\r\n.empty-icon { font-size: 2rem; margin-bottom: .75rem; opacity: .4; }\r\n\r\n.chart-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem; }\r\n.chart-card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 1.2rem; }\r\n.chart-title { font-family: var(--mono); font-size: .65rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text3); margin-bottom: 1rem; }\r\ncanvas { max-width: 100%; }\r\n\r\n#page-admin { display: none; min-height: 100vh; }\r\n.admin-layout { display: grid; grid-template-columns: 240px 1fr; min-height: 100vh; }\r\n.admin-sidebar { background: var(--bg); border-right: 1px solid var(--border); padding: 1.5rem 1rem; position: sticky; top: 0; height: 100vh; overflow-y: auto; }\r\n.admin-logo { font-family: var(--mono); font-size: .7rem; color: var(--text3); letter-spacing: .12em; text-transform: uppercase; margin-bottom: 2rem; padding-bottom: .75rem; border-bottom: 1px solid var(--border); }\r\n.admin-logo strong { color: var(--green); display: block; font-size: .85rem; margin-bottom: .2rem; }\r\n.admin-nav-item { display: flex; align-items: center; gap: .6rem; padding: .55rem .75rem; border-radius: 7px; font-size: .8rem; color: var(--text2); cursor: pointer; margin-bottom: .15rem; transition: all .15s; }\r\n.admin-nav-item:hover { background: var(--surface); color: var(--text); }\r\n.admin-nav-item.active { background: var(--surface); color: var(--green); }\r\n.admin-nav-icon { font-size: .9rem; opacity: .7; }\r\n.admin-main { padding: 2rem; overflow-y: auto; }\r\n.admin-section { display: none; }\r\n.admin-section.active { display: block; }\r\n.page-title { font-size: 1.2rem; font-weight: 600; margin-bottom: .3rem; }\r\n.page-sub { font-size: .78rem; color: var(--text3); margin-bottom: 1.5rem; }\r\n\r\n.upload-zone { border: 2px dashed var(--border2); border-radius: 12px; padding: 2.5rem; text-align: center; cursor: pointer; transition: all .2s; background: var(--surface); margin-bottom: 1rem; }\r\n.upload-zone:hover, .upload-zone.over { border-color: var(--green); background: rgba(74,222,128,.04); }\r\n.upload-zone-icon { font-size: 2rem; margin-bottom: .75rem; opacity: .5; }\r\n.upload-zone-title { font-size: .88rem; font-weight: 500; margin-bottom: .3rem; }\r\n.upload-zone-sub { font-size: .72rem; color: var(--text3); }\r\n\r\n.op-list-item { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 1rem 1.2rem; margin-bottom: .75rem; display: flex; align-items: center; gap: 1rem; }\r\n.op-list-name { font-weight: 500; flex: 1; }\r\n.op-list-meta { font-size: .72rem; color: var(--text3); font-family: var(--mono); }\r\n\r\n.overlay { display: none; position: fixed; inset: 0; background: rgba(26,31,24,.45); backdrop-filter: blur(4px); z-index: 1000; align-items: center; justify-content: center; }\r\n.overlay.open { display: flex; }\r\n.modal { background: var(--bg); border: 1px solid var(--border2); border-radius: 14px; padding: 1.75rem; width: 100%; max-width: 480px; max-height: 90vh; overflow-y: auto; box-shadow: 0 30px 80px rgba(0,0,0,.6); animation: modalIn .2s ease; }\r\n.modal-wide { max-width: 720px; }\r\n.modal-title { font-family: var(--mono); font-size: .8rem; text-transform: uppercase; letter-spacing: .1em; color: var(--green); margin-bottom: 1.25rem; padding-bottom: .75rem; border-bottom: 1px solid var(--border); }\r\n.modal-actions { display: flex; gap: .5rem; justify-content: flex-end; margin-top: 1.25rem; padding-top: .75rem; border-top: 1px solid var(--border); }\r\n\r\n.field { margin-bottom: .9rem; }\r\n.field label { display: block; font-size: .65rem; font-family: var(--mono); text-transform: uppercase; letter-spacing: .08em; color: var(--text3); margin-bottom: .35rem; }\r\n.field input, .field select { width: 100%; padding: .5rem .75rem; background: var(--surface); border: 1px solid var(--border); border-radius: 7px; color: var(--text); font-family: var(--sans); font-size: .85rem; outline: none; transition: border-color .15s; }\r\n.field input:focus, .field select:focus { border-color: var(--green); }\r\n.field select option { background: var(--surface); }\r\n.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; }\r\n\r\n.pwd-screen { position: fixed; inset: 0; background: var(--bg); display: flex; align-items: center; justify-content: center; z-index: 2000; }\r\n.pwd-box { background: var(--bg); border: 1.5px solid var(--border2); box-shadow: 0 4px 24px rgba(0,0,0,.12); border-radius: 14px; padding: 2rem; width: 320px; text-align: center; }\r\n.pwd-title { font-size: 1rem; font-weight: 600; margin-bottom: .3rem; }\r\n.pwd-sub { font-size: .75rem; color: var(--text3); margin-bottom: 1.25rem; }\r\n.pwd-input { width: 100%; padding: .6rem .85rem; background: var(--bg); border: 1px solid var(--border2); border-radius: 8px; color: var(--text); font-family: var(--mono); font-size: .9rem; outline: none; text-align: center; letter-spacing: .2em; margin-bottom: .75rem; }\r\n.pwd-input:focus { border-color: var(--green); }\r\n.pwd-err { font-size: .72rem; color: var(--red); margin-top: .4rem; }\r\n\r\n#toast { position: fixed; bottom: 2rem; left: 50%; transform: translateX(-50%); background: var(--bg); border: 1.5px solid var(--border2); border-radius: 8px; padding: .6rem 1.2rem; font-size: .8rem; font-family: var(--mono); box-shadow: 0 8px 30px rgba(0,0,0,.4); z-index: 9999; opacity: 0; pointer-events: none; transition: opacity .2s; white-space: nowrap; }\r\n#toast.show { opacity: 1; }\r\n#toast.ok  { border-color: var(--green); color: var(--green); }\r\n#toast.err { border-color: var(--red);   color: var(--red); }\r\n\r\n@keyframes fadeUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }\r\n@keyframes modalIn { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: scale(1); } }\r\n\r\n::-webkit-scrollbar { width: 5px; }\r\n::-webkit-scrollbar-track { background: var(--bg2); }\r\n::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 3px; }\r\n::-webkit-scrollbar-thumb:hover { background: var(--text3); }\r\n\r\n@media (max-width: 768px) {\r\n  .op-content { grid-template-columns: 1fr; }\r\n  .ul-sidebar { position: static; }\r\n  .admin-layout { grid-template-columns: 1fr; }\r\n  .admin-sidebar { height: auto; position: static; }\r\n  .chart-grid { grid-template-columns: 1fr; }\r\n}\r\n<\/style>\r\n<\/head>\r\n<body>\r\n\r\n<div id=\"toast\"><\/div>\r\n\r\n<div id=\"page-search\">\r\n  <div class=\"logo-area\">\r\n    <img decoding=\"async\" src=\"data:image\/png;base64,[[BASE64_LOGO_DAL_FILE_ORIGINALE]]\" alt=\"RENTRI\" style=\"height:72px;width:auto;margin-bottom:.75rem;display:block;margin-left:auto;margin-right:auto;\">\r\n    <div class=\"logo-sub\">ECOF ITALIA S.R.L. \u2014 Gestione Registri<\/div>\r\n    <div class=\"search-hint\" style=\"margin-top:.6rem;\">\r\n      <span id=\"search-count\">\u2014<\/span> operatori registrati \u00b7 premi <span>\u21b5<\/span> per aprire\r\n    <\/div>\r\n  <\/div>\r\n  <div class=\"search-wrap\">\r\n    <input type=\"text\" class=\"search-input\" id=\"search-input\"\r\n      placeholder=\"Cerca per nome, codice fiscale o P.IVA...\"\r\n      oninput=\"onSearch(this.value)\"\r\n      onkeydown=\"onSearchKey(event)\"\r\n      autocomplete=\"off\">\r\n    <div class=\"search-icon\">\u2315<\/div>\r\n    <div class=\"search-results\" id=\"search-results\"><\/div>\r\n  <\/div>\r\n  <a class=\"admin-link\" onclick=\"openAdmin()\">\u2699 Admin<\/a>\r\n<\/div>\r\n\r\n<div id=\"page-operatore\">\r\n  <div class=\"op-topbar\">\r\n    <button class=\"back-btn\" onclick=\"goSearch()\">\u2190 Ricerca<\/button>\r\n    <img decoding=\"async\" src=\"data:image\/png;base64,[[BASE64_LOGO_DAL_FILE_ORIGINALE]]\" alt=\"RENTRI\" style=\"height:28px;width:auto;mix-blend-mode:multiply;flex-shrink:0;\">\r\n    <div class=\"op-topbar-name\" id=\"top-nome\">\u2014<\/div>\r\n    <div class=\"op-topbar-cf\" id=\"top-cf\">\u2014<\/div>\r\n  <\/div>\r\n  <div class=\"op-hero\">\r\n    <div class=\"op-hero-inner\">\r\n      <div class=\"op-badge\">\u2713 Iscritto RENTRI<\/div>\r\n      <div class=\"op-nome\" id=\"op-nome\">\u2014<\/div>\r\n      <div class=\"op-meta-row\" id=\"op-meta-row\"><\/div>\r\n    <\/div>\r\n  <\/div>\r\n  <div class=\"kpi-strip\" id=\"kpi-strip\"><\/div>\r\n  <div class=\"op-content\">\r\n    <div class=\"ul-sidebar\">\r\n      <div class=\"section-title\">Unit\u00e0 Locali<\/div>\r\n      <div id=\"ul-list\"><\/div>\r\n    <\/div>\r\n    <div class=\"op-main\">\r\n      <div class=\"tabs\">\r\n        <button class=\"tab-btn active\" onclick=\"switchTab('registro',this)\">Registro<\/button>\r\n        <button class=\"tab-btn\" onclick=\"switchTab('statistiche',this)\">Statistiche<\/button>\r\n      <\/div>\r\n      <div id=\"tab-registro\">\r\n        <div class=\"reg-toolbar\">\r\n          <input type=\"text\" class=\"reg-search\" id=\"reg-search\"\r\n            placeholder=\"Filtra per EER, FIR, impianto...\"\r\n            oninput=\"renderRegistro()\">\r\n          <button class=\"btn btn-outline\" onclick=\"openImportModal()\">\u2b06 Importa<\/button>\r\n          <button class=\"btn btn-outline\" onclick=\"openAddMovimento()\">+ Movimento<\/button>\r\n          <button class=\"btn btn-outline\" onclick=\"esportaCSV()\">\u2193 CSV<\/button>\r\n        <\/div>\r\n        <div class=\"table-wrap\">\r\n          <table>\r\n            <thead>\r\n              <tr>\r\n                <th>Data<\/th><th>EER<\/th><th>Descrizione<\/th><th>Pericolosit\u00e0<\/th>\r\n                <th>R\/D<\/th><th style=\"text-align:right\">kg<\/th><th>FIR<\/th><th>Impianto<\/th><th><\/th>\r\n              <\/tr>\r\n            <\/thead>\r\n            <tbody id=\"registro-tbody\"><\/tbody>\r\n          <\/table>\r\n        <\/div>\r\n        <div id=\"registro-empty\" class=\"empty\" style=\"display:none\">\r\n          <div class=\"empty-icon\">\ud83d\udccb<\/div>\r\n          Nessuna movimentazione registrata.<br>Importa un PDF Prometeo o aggiungi manualmente.\r\n        <\/div>\r\n        <div id=\"reg-count\" style=\"font-size:.7rem;color:var(--text3);font-family:var(--mono);margin-top:.6rem;text-align:right;\"><\/div>\r\n      <\/div>\r\n      <div id=\"tab-statistiche\" style=\"display:none\">\r\n        <div class=\"chart-grid\">\r\n          <div class=\"chart-card\">\r\n            <div class=\"chart-title\">Movimentazioni mensili (kg)<\/div>\r\n            <canvas id=\"chart-mensile\" height=\"200\"><\/canvas>\r\n          <\/div>\r\n          <div class=\"chart-card\">\r\n            <div class=\"chart-title\">Top CER per peso<\/div>\r\n            <canvas id=\"chart-cer\" height=\"200\"><\/canvas>\r\n          <\/div>\r\n        <\/div>\r\n        <div class=\"chart-card\" style=\"margin-bottom:1rem\">\r\n          <div class=\"chart-title\">Operazioni R vs D<\/div>\r\n          <canvas id=\"chart-rd\" height=\"120\"><\/canvas>\r\n        <\/div>\r\n        <div id=\"stat-fir-table\"><\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div id=\"page-admin\">\r\n  <div class=\"admin-layout\">\r\n    <div class=\"admin-sidebar\">\r\n      <div class=\"admin-logo\"><strong>Admin Panel<\/strong>RENTRI Manager<\/div>\r\n      <div class=\"admin-nav-item active\" onclick=\"adminNav('carica',this)\"><span class=\"admin-nav-icon\">\ud83d\udcc4<\/span> Carica PDF<\/div>\r\n      <div class=\"admin-nav-item\" onclick=\"adminNav('operatori',this)\"><span class=\"admin-nav-icon\">\ud83c\udfe2<\/span> Operatori<\/div>\r\n      <div class=\"admin-nav-item\" onclick=\"adminNav('backup',this)\"><span class=\"admin-nav-icon\">\ud83d\udcbe<\/span> Backup<\/div>\r\n      <div style=\"margin-top:auto;padding-top:2rem;\">\r\n        <div class=\"admin-nav-item\" onclick=\"goSearch()\"><span class=\"admin-nav-icon\">\u2190<\/span> Torna all'app<\/div>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"admin-main\">\r\n      <div id=\"admin-carica\" class=\"admin-section active\">\r\n        <div class=\"page-title\">Carica documenti<\/div>\r\n        <div class=\"page-sub\">Carica ricevute di iscrizione RENTRI o file movimentazioni Prometeo<\/div>\r\n        <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:1.5rem\">\r\n          <div>\r\n            <div class=\"section-title\" style=\"margin-bottom:.75rem\">Ricevute iscrizione RENTRI<\/div>\r\n            <div class=\"upload-zone\" id=\"dz-ricevuta\"\r\n              onclick=\"document.getElementById('f-ricevuta').click()\"\r\n              ondragover=\"dzOver(event,'dz-ricevuta')\"\r\n              ondragleave=\"dzOut('dz-ricevuta')\"\r\n              ondrop=\"dzDrop(event,'ricevuta')\">\r\n              <div class=\"upload-zone-icon\">\ud83d\udccb<\/div>\r\n              <div class=\"upload-zone-title\">Ricevuta iscrizione operatore<\/div>\r\n              <div class=\"upload-zone-sub\">PDF dall'Albo Nazionale Gestori Ambientali<\/div>\r\n            <\/div>\r\n            <input type=\"file\" id=\"f-ricevuta\" accept=\".pdf\" multiple style=\"display:none\" onchange=\"handleRicevute(this.files)\">\r\n            <div id=\"ricevuta-log\"><\/div>\r\n          <\/div>\r\n          <div>\r\n            <div class=\"section-title\" style=\"margin-bottom:.75rem\">Movimentazioni Prometeo<\/div>\r\n            <div class=\"upload-zone\" id=\"dz-prometeo\"\r\n              ondragover=\"dzOver(event,'dz-prometeo')\"\r\n              ondragleave=\"dzOut('dz-prometeo')\"\r\n              ondrop=\"dzDrop(event,'prometeo')\">\r\n              <div class=\"upload-zone-icon\">\ud83d\udcca<\/div>\r\n              <div class=\"upload-zone-title\">Stampa Elenco Formulari<\/div>\r\n              <div class=\"upload-zone-sub\">PDF Prometeo raggruppato per C.E.R. \u2014 seleziona prima l'operatore<\/div>\r\n            <\/div>\r\n            <div style=\"margin-top:.75rem;display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;\">\r\n              <select id=\"prometeo-op-sel\" style=\"flex:1;padding:.45rem .75rem;background:var(--surface);border:1px solid var(--border);border-radius:7px;color:var(--text);font-size:.8rem;outline:none;\">\r\n                <option value=\"\">\u2014 Seleziona operatore \u2014<\/option>\r\n              <\/select>\r\n              <select id=\"prometeo-ul-sel\" style=\"flex:1;padding:.45rem .75rem;background:var(--surface);border:1px solid var(--border);border-radius:7px;color:var(--text);font-size:.8rem;outline:none;\">\r\n                <option value=\"\">\u2014 Seleziona UL \u2014<\/option>\r\n              <\/select>\r\n            <\/div>\r\n            <label style=\"display:flex;flex-direction:column;gap:.3rem;margin-top:.75rem;\">\r\n              <span style=\"font-size:.62rem;font-family:var(--mono);text-transform:uppercase;letter-spacing:.07em;color:var(--text3);\">File PDF<\/span>\r\n              <input type=\"file\" id=\"f-prometeo\" accept=\".pdf\"\r\n                style=\"font-size:.8rem;padding:.4rem;background:var(--surface);border:1px solid var(--border);border-radius:6px;color:var(--text);cursor:pointer;\"\r\n                onchange=\"handlePrometeo(this.files[0])\">\r\n            <\/label>\r\n            <div id=\"prometeo-log\"><\/div>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n      <div id=\"admin-operatori\" class=\"admin-section\">\r\n        <div class=\"page-title\">Operatori registrati<\/div>\r\n        <div class=\"page-sub\">Gestisci gli operatori nel sistema<\/div>\r\n        <div style=\"margin-bottom:1rem;display:flex;gap:.5rem;\">\r\n          <button class=\"btn btn-green\" onclick=\"openAddOperatore()\">+ Nuovo operatore<\/button>\r\n        <\/div>\r\n        <div id=\"admin-op-list\"><\/div>\r\n      <\/div>\r\n      <div id=\"admin-backup\" class=\"admin-section\">\r\n        <div class=\"page-title\">Backup & Ripristino<\/div>\r\n        <div class=\"page-sub\">Esporta o importa tutti i dati<\/div>\r\n        <div style=\"display:flex;gap:1rem;flex-wrap:wrap;margin-top:1rem;\">\r\n          <button class=\"btn btn-green\" onclick=\"esportaBackup()\">\u2193 Esporta backup JSON<\/button>\r\n          <label class=\"btn btn-outline\" style=\"cursor:pointer;\">\r\n            \u2191 Importa backup\r\n            <input type=\"file\" accept=\".json\" style=\"display:none\" onchange=\"importaBackup(this)\">\r\n          <\/label>\r\n        <\/div>\r\n        <div style=\"margin-top:1.5rem;padding:1rem;background:var(--surface);border-radius:8px;font-size:.75rem;color:var(--text3);font-family:var(--mono);\">\r\n          <div id=\"backup-info\"><\/div>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div id=\"pwd-screen\" class=\"pwd-screen\" style=\"display:none\">\r\n  <div class=\"pwd-box\">\r\n    <div class=\"pwd-title\">\ud83d\udd12 Accesso Admin<\/div>\r\n    <div class=\"pwd-sub\">Inserisci la password per accedere al pannello<\/div>\r\n    <input type=\"password\" class=\"pwd-input\" id=\"pwd-input\" placeholder=\"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\" onkeydown=\"if(event.key==='Enter')checkPwd()\">\r\n    <button class=\"btn btn-green\" style=\"width:100%\" onclick=\"checkPwd()\">Accedi<\/button>\r\n    <div class=\"pwd-err\" id=\"pwd-err\"><\/div>\r\n    <button class=\"btn btn-ghost\" style=\"margin-top:.5rem;width:100%;font-size:.72rem;\" onclick=\"closePwd()\">Annulla<\/button>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div class=\"overlay\" id=\"m-import\">\r\n  <div class=\"modal modal-wide\">\r\n    <div class=\"modal-title\">\/\/ Importa movimentazioni<\/div>\r\n    <div style=\"display:flex;gap:.5rem;margin-bottom:1rem;\">\r\n      <button class=\"tab-btn active\" id=\"imp-tab-pdf\" onclick=\"switchImpTab('pdf',this)\">PDF Prometeo<\/button>\r\n      <button class=\"tab-btn\" id=\"imp-tab-csv\" onclick=\"switchImpTab('csv',this)\">CSV<\/button>\r\n    <\/div>\r\n    <div id=\"imp-tab-pdf-content\">\r\n      <label style=\"display:flex;flex-direction:column;gap:.3rem;\">\r\n        <span style=\"font-size:.62rem;font-family:var(--mono);text-transform:uppercase;letter-spacing:.07em;color:var(--text3);\">File PDF Prometeo<\/span>\r\n        <input type=\"file\" id=\"f-imp-pdf\" accept=\".pdf\"\r\n          style=\"font-size:.8rem;padding:.4rem;background:var(--surface);border:1px solid var(--border);border-radius:6px;color:var(--text);cursor:pointer;\"\r\n          onchange=\"handleImpPDF(this.files[0])\">\r\n      <\/label>\r\n      <div id=\"imp-pdf-preview\" style=\"margin-top:.75rem;\"><\/div>\r\n    <\/div>\r\n    <div id=\"imp-tab-csv-content\" style=\"display:none\">\r\n      <label style=\"display:flex;flex-direction:column;gap:.3rem;\">\r\n        <span style=\"font-size:.62rem;font-family:var(--mono);text-transform:uppercase;letter-spacing:.07em;color:var(--text3);\">File CSV<\/span>\r\n        <input type=\"file\" id=\"f-imp-csv\" accept=\".csv\"\r\n          style=\"font-size:.8rem;padding:.4rem;background:var(--surface);border:1px solid var(--border);border-radius:6px;color:var(--text);cursor:pointer;\"\r\n          onchange=\"handleImpCSV(this.files[0])\">\r\n      <\/label>\r\n      <div id=\"imp-csv-preview\" style=\"margin-top:.75rem;\"><\/div>\r\n    <\/div>\r\n    <div class=\"modal-actions\">\r\n      <button class=\"btn btn-green\" id=\"imp-confirm-btn\" style=\"display:none\" onclick=\"confirmImport()\">\u2713 Importa<\/button>\r\n      <button class=\"btn btn-outline\" onclick=\"closeModal('m-import')\">Chiudi<\/button>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div class=\"overlay\" id=\"m-movimento\">\r\n  <div class=\"modal\">\r\n    <div class=\"modal-title\">\/\/ Nuova movimentazione<\/div>\r\n    <div class=\"field-row\">\r\n      <div class=\"field\"><label>Data<\/label><input type=\"date\" id=\"mov-data\"><\/div>\r\n      <div class=\"field\"><label>EER *<\/label><input type=\"text\" id=\"mov-eer\" placeholder=\"es. 150110*\"><\/div>\r\n    <\/div>\r\n    <div class=\"field\"><label>Descrizione<\/label><input type=\"text\" id=\"mov-desc\" placeholder=\"Descrizione rifiuto\"><\/div>\r\n    <div class=\"field-row\">\r\n      <div class=\"field\"><label>Quantit\u00e0 kg *<\/label><input type=\"number\" id=\"mov-qty\" placeholder=\"0.00\" step=\"0.01\"><\/div>\r\n      <div class=\"field\"><label>Tipo<\/label>\r\n        <select id=\"mov-tipo\"><option value=\"NP\">NP \u2014 Non pericoloso<\/option><option value=\"P\">P \u2014 Pericoloso<\/option><\/select>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"field-row\">\r\n      <div class=\"field\"><label>Operazione<\/label>\r\n        <select id=\"mov-op\"><option value=\"S\">S \u2014 Scarico<\/option><option value=\"C\">C \u2014 Carico<\/option><\/select>\r\n      <\/div>\r\n      <div class=\"field\"><label>Cod. R\/D<\/label><input type=\"text\" id=\"mov-rd\" placeholder=\"es. R13\"><\/div>\r\n    <\/div>\r\n    <div class=\"field-row\">\r\n      <div class=\"field\"><label>Trasportatore<\/label><input type=\"text\" id=\"mov-tras\" placeholder=\"Ragione sociale\"><\/div>\r\n      <div class=\"field\"><label>Impianto destinatario<\/label><input type=\"text\" id=\"mov-imp\" placeholder=\"Ragione sociale\"><\/div>\r\n    <\/div>\r\n    <div class=\"field\"><label>N\u00b0 FIR<\/label><input type=\"text\" id=\"mov-fir\" placeholder=\"es. GKRLX 007742 TY\"><\/div>\r\n    <div class=\"modal-actions\">\r\n      <button class=\"btn btn-green\" onclick=\"salvaMovimento()\">\u2713 Salva<\/button>\r\n      <button class=\"btn btn-outline\" onclick=\"closeModal('m-movimento')\">Annulla<\/button>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div class=\"overlay\" id=\"m-operatore\">\r\n  <div class=\"modal\">\r\n    <div class=\"modal-title\">\/\/ Operatore<\/div>\r\n    <div class=\"field\"><label>Denominazione *<\/label><input type=\"text\" id=\"aop-nome\"><\/div>\r\n    <div class=\"field-row\">\r\n      <div class=\"field\"><label>Codice fiscale<\/label><input type=\"text\" id=\"aop-cf\"><\/div>\r\n      <div class=\"field\"><label>P.IVA<\/label><input type=\"text\" id=\"aop-piva\"><\/div>\r\n    <\/div>\r\n    <div class=\"field-row\">\r\n      <div class=\"field\"><label>N\u00b0 dipendenti<\/label><input type=\"text\" id=\"aop-dip\"><\/div>\r\n      <div class=\"field\"><label>Rappresentante<\/label><input type=\"text\" id=\"aop-rapp\"><\/div>\r\n    <\/div>\r\n    <div class=\"field\"><label>Sede legale<\/label><input type=\"text\" id=\"aop-sede\"><\/div>\r\n    <div class=\"field-row\">\r\n      <div class=\"field\"><label>N\u00b0 pratica<\/label><input type=\"text\" id=\"aop-pratica\"><\/div>\r\n      <div class=\"field\"><label>Data iscrizione<\/label><input type=\"date\" id=\"aop-data\"><\/div>\r\n    <\/div>\r\n    <div id=\"aop-id\" style=\"display:none\"><\/div>\r\n    <div class=\"modal-actions\">\r\n      <button class=\"btn btn-green\" onclick=\"salvaOperatore()\">\u2713 Salva<\/button>\r\n      <button class=\"btn btn-outline\" onclick=\"closeModal('m-operatore')\">Annulla<\/button>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/Chart.js\/4.4.0\/chart.umd.min.js\"><\/script>\r\n<script>\r\n'use strict';\r\nconst LS_KEY = 'rentri_v9';\r\nconst ADMIN_PWD = 'ecof2025';\r\nconst S = { operatori: [], ul: [], entries: [] };\r\n\r\nfunction loadState() {\r\n  try {\r\n    const d = JSON.parse(localStorage.getItem(LS_KEY) || '{}');\r\n    S.operatori = d.operatori || [];\r\n    S.ul        = d.ul        || [];\r\n    S.entries   = d.entries   || [];\r\n  } catch(e) { console.error(e); }\r\n}\r\nfunction saveState() { localStorage.setItem(LS_KEY, JSON.stringify(S)); }\r\n\r\nfunction caricaDatiIniziali() {\r\n  const opPreset = [\r\n    { id:1001, nome:'ARTHREX ITALIA S.R.L.', piva:'', cf:'09301330966', dip:'70', rapp:'MINOGGIO FILIPPO', sede:'VIALE CERTOSA 233, MILANO (20151) MI', pratica:'01-250212-00099256', dataIsc:'2025-02-12' },\r\n    { id:1002, nome:\"ANICA SERVIZI - SOCIETA' A RESPONSABILITA' LIMITATA\", piva:'', cf:'05007041006', dip:'21', rapp:'LOPEZ MAURIZIO', sede:'VIALE REGINA MARGHERITA 286, ROMA (00161) RM', pratica:'01-250211-00089083', dataIsc:'2025-02-11' }\r\n  ];\r\n  const ulPreset = [\r\n    { id:1101, operatoreId:1001, nome:'Unit\u00e0 locale RM\/1', indirizzo:'VIA GIACOMO PERONI 400\/402, ROMA (RM)', attivita:'PRODUZIONE DI RIFIUTI', categoria:'R' },\r\n    { id:1102, operatoreId:1001, nome:'Sede legale', indirizzo:'VIALE CERTOSA 233, MILANO (MI)', attivita:'PRODUZIONE DI RIFIUTI', categoria:'R' },\r\n    { id:1201, operatoreId:1002, nome:'Sede legale', indirizzo:'VIALE REGINA MARGHERITA 286, ROMA (RM)', attivita:'PRODUZIONE DI RIFIUTI', categoria:'R' }\r\n  ];\r\n  const entriesPreset = [\r\n    { id:2000, ulId:1101, date:'2025-08-29', eer:'150110*', desc:'imballaggi contenenti residui di sostanze pericolose o contaminati da tali sostanze', fir:'GKRLX 007742 TY', impianto:'SIECO SRL', trasportatore:'ECOF ITALIA SRL', rd:'D15', qty:1.0, type:'P', op:'S', tx:'no' },\r\n    { id:2001, ulId:1101, date:'2025-03-14', eer:'160213*', desc:'apparecchiature fuori uso, contenenti componenti pericolosi diversi da quelli di cui alle voci 16 02 09 e 16 02 12', fir:'GKRLX 001545 HJ', impianto:'ECO ERIDANIA SPA', trasportatore:'ECOF ITALIA SRL', rd:'R13', qty:5.0, type:'P', op:'S', tx:'no' },\r\n    { id:2002, ulId:1101, date:'2025-03-21', eer:'160213*', desc:'apparecchiature fuori uso, contenenti componenti pericolosi diversi da quelli di cui alle voci 16 02 09 e 16 02 12', fir:'GKRLX 001964 ZX', impianto:'SIECO SRL', trasportatore:'ECOF ITALIA SRL', rd:'R13', qty:3.0, type:'P', op:'S', tx:'no' },\r\n    { id:2003, ulId:1101, date:'2025-03-03', eer:'160214', desc:'apparecchiature fuori uso, diverse da quelle di cui alle voci da 16 02 09 a 16 02 13', fir:'GKRLX 000965 CC', impianto:'SIECO SRL', trasportatore:'ECOF ITALIA SRL', rd:'R13', qty:28.0, type:'NP', op:'S', tx:'no' },\r\n    { id:2004, ulId:1101, date:'2025-04-11', eer:'160214', desc:'apparecchiature fuori uso, diverse da quelle di cui alle voci da 16 02 09 a 16 02 13', fir:'GKRLX 002814 LK', impianto:'ECO ERIDANIA SPA', trasportatore:'ECOF ITALIA SRL', rd:'R13', qty:8.0, type:'NP', op:'S', tx:'no' },\r\n    { id:2005, ulId:1101, date:'2025-03-07', eer:'180103*', desc:'rifiuti che devono essere raccolti e smaltiti applicando precauzioni particolari per evitare infezioni', fir:'GKRLX 001228 YV', impianto:'ECO ERIDANIA SPA', trasportatore:'ECOF ITALIA SRL', rd:'D15', qty:8.0, type:'P', op:'S', tx:'no' },\r\n    { id:2006, ulId:1101, date:'2025-10-06', eer:'180103*', desc:'rifiuti che devono essere raccolti e smaltiti applicando precauzioni particolari per evitare infezioni', fir:'GKRLX 008996 GG', impianto:'SIECO SRL', trasportatore:'ECOF ITALIA SRL', rd:'R13', qty:6.0, type:'P', op:'S', tx:'no' },\r\n    { id:2007, ulId:1101, date:'2025-03-10', eer:'180104', desc:'rifiuti che non devono essere raccolti e smaltiti applicando precauzioni particolari per evitare infezioni', fir:'GKRLX 001286 JJ', impianto:'ECO ERIDANIA SPA', trasportatore:'ECOF ITALIA SRL', rd:'D15', qty:11.0, type:'NP', op:'S', tx:'no' },\r\n    { id:2008, ulId:1101, date:'2025-10-06', eer:'180104', desc:'rifiuti che non devono essere raccolti e smaltiti applicando precauzioni particolari per evitare infezioni', fir:'GKRLX 008984 QG', impianto:'SIECO SRL', trasportatore:'ECOF ITALIA SRL', rd:'R13', qty:4.0, type:'NP', op:'S', tx:'no' },\r\n    { id:2009, ulId:1101, date:'2025-10-06', eer:'190905', desc:'resine a scambio ionico saturate o esaurite', fir:'GKRLX 008997 WS', impianto:'SIECO SRL', trasportatore:'ECOF ITALIA SRL', rd:'R13', qty:14.0, type:'NP', op:'S', tx:'no' }\r\n  ];\r\n  opPreset.forEach(op => { if (!S.operatori.find(o => o.id === op.id)) S.operatori.push(op); });\r\n  ulPreset.forEach(ul => { if (!S.ul.find(u => u.id === ul.id)) S.ul.push(ul); });\r\n  entriesPreset.forEach(e => { if (!S.entries.find(x => x.id === e.id)) S.entries.push(e); });\r\n  saveState();\r\n}\r\n\r\nlet activePage = 'search', activeOpId = null, activeUlId = null, _impMovs = null;\r\n\r\nfunction showPage(id) {\r\n  document.getElementById('page-search').style.display    = id === 'page-search'    ? 'flex'  : 'none';\r\n  document.getElementById('page-operatore').style.display = id === 'page-operatore' ? 'block' : 'none';\r\n  document.getElementById('page-admin').style.display     = id === 'page-admin'     ? 'block' : 'none';\r\n  activePage = id;\r\n}\r\nfunction goSearch() {\r\n  showPage('page-search');\r\n  document.getElementById('search-input').value = '';\r\n  document.getElementById('search-results').classList.remove('open');\r\n  updateSearchCount();\r\n}\r\n\r\nfunction updateSearchCount() { document.getElementById('search-count').textContent = S.operatori.length; }\r\n\r\nfunction onSearch(q) {\r\n  const box = document.getElementById('search-results');\r\n  q = q.trim().toLowerCase();\r\n  if (!q) { box.classList.remove('open'); return; }\r\n  const matches = S.operatori.filter(op =>\r\n    op.nome.toLowerCase().includes(q) ||\r\n    (op.cf   && op.cf.toLowerCase().includes(q)) ||\r\n    (op.piva && op.piva.toLowerCase().includes(q))\r\n  ).slice(0, 8);\r\n  if (!matches.length) {\r\n    box.innerHTML = '<div class=\"result-item\"><div class=\"result-icon\">?<\/div><div><div class=\"result-name\">Nessun risultato<\/div><\/div><\/div>';\r\n    box.classList.add('open'); return;\r\n  }\r\n  box.innerHTML = matches.map(op => `\r\n    <div class=\"result-item\" onmousedown=\"event.preventDefault(); apriOperatore(${op.id})\">\r\n      <div class=\"result-icon\">\ud83c\udfe2<\/div>\r\n      <div>\r\n        <div class=\"result-name\">${op.nome}<\/div>\r\n        <div class=\"result-meta\">${[op.cf ? 'CF '+op.cf : '', op.piva ? 'P.IVA '+op.piva : ''].filter(Boolean).join(' \u00b7 ')}<\/div>\r\n      <\/div>\r\n    <\/div>`).join('');\r\n  box.classList.add('open');\r\n}\r\nfunction onSearchKey(e) {\r\n  if (e.key === 'Enter') { const first = document.querySelector('.result-item'); if (first) first.click(); }\r\n  if (e.key === 'Escape') document.getElementById('search-results').classList.remove('open');\r\n}\r\ndocument.addEventListener('click', e => { if (!e.target.closest('.search-wrap')) document.getElementById('search-results').classList.remove('open'); });\r\n\r\nfunction apriOperatore(opId) {\r\n  const op = S.operatori.find(o => o.id === opId);\r\n  if (!op) return;\r\n  activeOpId = opId;\r\n  document.getElementById('search-results').classList.remove('open');\r\n  document.getElementById('top-nome').textContent = op.nome;\r\n  document.getElementById('top-cf').textContent = op.cf ? 'CF '+op.cf : '';\r\n  document.getElementById('op-nome').textContent = op.nome;\r\n  document.getElementById('op-meta-row').innerHTML = [\r\n    op.cf      ? `<div class=\"op-meta-item\"><span class=\"op-meta-label\">CF<\/span><span class=\"op-meta-val\">${op.cf}<\/span><\/div>` : '',\r\n    op.piva    ? `<div class=\"op-meta-item\"><span class=\"op-meta-label\">P.IVA<\/span><span class=\"op-meta-val\">${op.piva}<\/span><\/div>` : '',\r\n    op.dip     ? `<div class=\"op-meta-item\"><span class=\"op-meta-label\">Dipendenti<\/span><span class=\"op-meta-val\">${op.dip}<\/span><\/div>` : '',\r\n    op.rapp    ? `<div class=\"op-meta-item\"><span class=\"op-meta-label\">Legale rapp.<\/span><span class=\"op-meta-val\">${op.rapp}<\/span><\/div>` : '',\r\n    op.sede    ? `<div class=\"op-meta-item\"><span class=\"op-meta-label\">Sede<\/span><span class=\"op-meta-val\">${op.sede}<\/span><\/div>` : '',\r\n    op.pratica ? `<div class=\"op-meta-item\"><span class=\"op-meta-label\">Pratica<\/span><span class=\"op-meta-val\">${op.pratica}<\/span><\/div>` : '',\r\n    op.dataIsc ? `<div class=\"op-meta-item\"><span class=\"op-meta-label\">Iscrizione<\/span><span class=\"op-meta-val\">${op.dataIsc}<\/span><\/div>` : '',\r\n  ].filter(Boolean).join('');\r\n  const uls = S.ul.filter(u => u.operatoreId === opId);\r\n  activeUlId = uls.length ? uls[0].id : null;\r\n  const catColor = { R:'var(--amber)', T:'var(--teal)', RT:'var(--green)' };\r\n  document.getElementById('ul-list').innerHTML = uls.map(ul => `\r\n    <div class=\"ul-card${ul.id === activeUlId ? ' active' : ''}\" onclick=\"selectUL(${ul.id})\" id=\"ul-card-${ul.id}\">\r\n      <div class=\"ul-card-name\">${ul.nome}<\/div>\r\n      <div class=\"ul-card-addr\">${ul.indirizzo}<\/div>\r\n      <div class=\"ul-cat-dot\" style=\"background:${catColor[ul.categoria]||'var(--text3)'}\"><\/div>\r\n    <\/div>`).join('') || '<div style=\"font-size:.75rem;color:var(--text3);\">Nessuna UL registrata<\/div>';\r\n  renderKPI(opId, activeUlId);\r\n  renderRegistro();\r\n  showPage('page-operatore');\r\n  window.scrollTo(0, 0);\r\n}\r\n\r\nfunction selectUL(ulId) {\r\n  activeUlId = ulId;\r\n  document.querySelectorAll('.ul-card').forEach(c => c.classList.remove('active'));\r\n  const card = document.getElementById('ul-card-'+ulId);\r\n  if (card) card.classList.add('active');\r\n  renderKPI(activeOpId, ulId);\r\n  renderRegistro();\r\n}\r\n\r\nfunction renderKPI(opId, ulId) {\r\n  const uls = ulId ? [ulId] : S.ul.filter(u => u.operatoreId === opId).map(u => u.id);\r\n  const movs = S.entries.filter(e => uls.includes(e.ulId));\r\n  const totKg    = movs.reduce((s,e) => s + (e.qty||0), 0);\r\n  const totMovs  = movs.length;\r\n  const pericolose = movs.filter(e => e.type === 'P').length;\r\n  const cerSet   = new Set(movs.map(e => e.eer)).size;\r\n  document.getElementById('kpi-strip').innerHTML = `\r\n    <div class=\"kpi-card\"><div class=\"kpi-label\">Movimentazioni<\/div><div class=\"kpi-val green\">${totMovs}<\/div><div class=\"kpi-sub\">registrate<\/div><\/div>\r\n    <div class=\"kpi-card\"><div class=\"kpi-label\">Chilogrammi totali<\/div><div class=\"kpi-val teal\">${totKg.toLocaleString('it-IT')}<\/div><div class=\"kpi-sub\">kg movimentati<\/div><\/div>\r\n    <div class=\"kpi-card\"><div class=\"kpi-label\">Pericolose<\/div><div class=\"kpi-val amber\">${pericolose}<\/div><div class=\"kpi-sub\">su ${totMovs} totali<\/div><\/div>\r\n    <div class=\"kpi-card\"><div class=\"kpi-label\">Codici EER<\/div><div class=\"kpi-val blue\">${cerSet}<\/div><div class=\"kpi-sub\">distinti<\/div><\/div>`;\r\n}\r\n\r\nfunction renderRegistro() {\r\n  if (!activeUlId) {\r\n    document.getElementById('registro-tbody').innerHTML = '';\r\n    document.getElementById('registro-empty').style.display = '';\r\n    document.getElementById('reg-count').textContent = '';\r\n    return;\r\n  }\r\n  const q = (document.getElementById('reg-search').value || '').toLowerCase();\r\n  let movs = S.entries.filter(e => e.ulId === activeUlId);\r\n  if (q) movs = movs.filter(e =>\r\n    (e.eer||'').toLowerCase().includes(q) ||\r\n    (e.desc||'').toLowerCase().includes(q) ||\r\n    (e.fir||'').toLowerCase().includes(q) ||\r\n    (e.impianto||'').toLowerCase().includes(q) ||\r\n    (e.trasportatore||'').toLowerCase().includes(q)\r\n  );\r\n  movs.sort((a,b) => (b.date||'').localeCompare(a.date||''));\r\n  const tbody = document.getElementById('registro-tbody');\r\n  const empty = document.getElementById('registro-empty');\r\n  if (!movs.length) { tbody.innerHTML = ''; empty.style.display = ''; document.getElementById('reg-count').textContent = ''; return; }\r\n  empty.style.display = 'none';\r\n  tbody.innerHTML = movs.map(e => `\r\n    <tr>\r\n      <td class=\"mono-cell\" style=\"white-space:nowrap\">${e.date||''}<\/td>\r\n      <td class=\"mono-cell\" style=\"color:var(--green);font-weight:500\">${e.eer||''}<\/td>\r\n      <td style=\"max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap\" title=\"${e.desc||''}\">${e.desc||''}<\/td>\r\n      <td><span class=\"badge badge-${e.type||'NP'}\">${e.type==='P' ? '\u26a0 Pericoloso' : 'Non pericoloso'}<\/span><\/td>\r\n      <td><span class=\"badge ${(e.rd||'').startsWith('R')?'badge-R':'badge-D'}\">${e.rd||'\u2014'}<\/span><\/td>\r\n      <td class=\"mono-cell\" style=\"text-align:right\">${(e.qty||0).toLocaleString('it-IT')}<\/td>\r\n      <td class=\"mono-cell\" style=\"font-size:.7rem;color:var(--text3)\">${e.fir||'\u2014'}<\/td>\r\n      <td style=\"font-size:.72rem;color:var(--text2);max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap\">${e.impianto||'\u2014'}<\/td>\r\n      <td>\r\n        <button class=\"action-btn\" onclick=\"openEditMovimento(${e.id})\">\u270f<\/button>\r\n        <button class=\"action-btn del\" onclick=\"eliminaMovimento(${e.id})\">\u2715<\/button>\r\n      <\/td>\r\n    <\/tr>`).join('');\r\n  document.getElementById('reg-count').textContent = `${movs.length} record`;\r\n}\r\n\r\nlet charts = {};\r\nfunction renderStatistiche() {\r\n  if (!activeUlId) return;\r\n  const movs = S.entries.filter(e => e.ulId === activeUlId);\r\n  if (!movs.length) return;\r\n\r\n  const mensile = {};\r\n  movs.forEach(e => { const m = (e.date||'').substring(0,7); if (m) mensile[m] = (mensile[m]||0) + (e.qty||0); });\r\n  const mLabels = Object.keys(mensile).sort();\r\n  const mVals   = mLabels.map(k => mensile[k]);\r\n  if (charts.mensile) charts.mensile.destroy();\r\n  charts.mensile = new Chart(document.getElementById('chart-mensile'), {\r\n    type: 'bar', data: { labels: mLabels, datasets: [{ data: mVals, backgroundColor: 'rgba(74,222,128,.5)', borderColor: '#4ade80', borderWidth: 1 }] },\r\n    options: { plugins: { legend: { display: false } }, scales: { x: { ticks: { color: '#5a7a7e', font: { family: 'DM Mono', size: 10 } }, grid: { color: '#263033' } }, y: { ticks: { color: '#5a7a7e', font: { family: 'DM Mono', size: 10 } }, grid: { color: '#263033' } } } }\r\n  });\r\n\r\n  const cerMap = {};\r\n  movs.forEach(e => { cerMap[e.eer||'?'] = (cerMap[e.eer||'?']||0) + (e.qty||0); });\r\n  const cerSorted = Object.entries(cerMap).sort((a,b) => b[1]-a[1]).slice(0,6);\r\n  if (charts.cer) charts.cer.destroy();\r\n  charts.cer = new Chart(document.getElementById('chart-cer'), {\r\n    type: 'doughnut', data: { labels: cerSorted.map(c=>c[0]), datasets: [{ data: cerSorted.map(c=>c[1]), backgroundColor: ['#4ade80','#2dd4bf','#60a5fa','#fbbf24','#f87171','#a78bfa'], borderColor: '#1a2325', borderWidth: 2 }] },\r\n    options: { plugins: { legend: { labels: { color: '#9eb5b8', font: { family: 'DM Mono', size: 10 }, padding: 8 } } } }\r\n  });\r\n\r\n  const rKg = movs.filter(e => (e.rd||'').startsWith('R')).reduce((s,e) => s+(e.qty||0), 0);\r\n  const dKg = movs.filter(e => (e.rd||'').startsWith('D')).reduce((s,e) => s+(e.qty||0), 0);\r\n  if (charts.rd) charts.rd.destroy();\r\n  charts.rd = new Chart(document.getElementById('chart-rd'), {\r\n    type: 'bar', data: { labels: ['Recupero (R)', 'Smaltimento (D)'], datasets: [{ data: [rKg, dKg], backgroundColor: ['rgba(74,222,128,.5)','rgba(251,191,36,.5)'], borderColor: ['#4ade80','#fbbf24'], borderWidth: 1 }] },\r\n    options: { indexAxis: 'y', plugins: { legend: { display: false } }, scales: { x: { ticks: { color: '#5a7a7e', font: { family: 'DM Mono', size: 10 } }, grid: { color: '#263033' } }, y: { ticks: { color: '#9eb5b8', font: { family: 'DM Mono', size: 10 } }, grid: { display: false } } } }\r\n  });\r\n\r\n  const sorted = [...movs].sort((a,b) => (b.date||'').localeCompare(a.date||''));\r\n  const P = 'padding:.4rem .6rem;border-bottom:1px solid var(--border)';\r\n  const firRows = sorted.map(e => `\r\n    <tr>\r\n      <td class=\"mono-cell\" style=\"${P};white-space:nowrap;color:var(--text2)\">${e.date||'\u2014'}<\/td>\r\n      <td class=\"mono-cell\" style=\"${P};font-size:.7rem;color:var(--text3)\">${e.fir||'\u2014'}<\/td>\r\n      <td class=\"mono-cell\" style=\"${P};color:var(--green);font-weight:500\">${e.eer||'\u2014'}<\/td>\r\n      <td style=\"${P};color:var(--text2);font-size:.8rem\">${e.trasportatore||'\u2014'}<\/td>\r\n      <td style=\"${P};color:var(--text3);font-size:.75rem;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap\" title=\"${e.impianto||''}\">${e.impianto||'\u2014'}<\/td>\r\n      <td style=\"${P}\"><span class=\"badge ${(e.rd||'').startsWith('R')?'badge-R':'badge-D'}\">${e.rd||'\u2014'}<\/span><\/td>\r\n      <td class=\"mono-cell\" style=\"${P};text-align:right;color:var(--text2)\">${(e.qty||0).toLocaleString('it-IT')}<\/td>\r\n    <\/tr>`).join('');\r\n  document.getElementById('stat-fir-table').innerHTML = `\r\n    <div class=\"chart-card\" style=\"margin-top:1rem\">\r\n      <div class=\"chart-title\">Formulari (FIR) \u2014 dettaglio trasportatori<\/div>\r\n      <div style=\"overflow-x:auto\">\r\n        <table style=\"width:100%;border-collapse:collapse;font-size:.78rem\">\r\n          <thead>\r\n            <tr style=\"border-bottom:1px solid var(--border)\">\r\n              <th style=\"text-align:left;padding:.4rem .6rem;color:var(--text3);font-weight:500;font-family:var(--mono)\">Data<\/th>\r\n              <th style=\"text-align:left;padding:.4rem .6rem;color:var(--text3);font-weight:500;font-family:var(--mono)\">FIR<\/th>\r\n              <th style=\"text-align:left;padding:.4rem .6rem;color:var(--text3);font-weight:500;font-family:var(--mono)\">EER<\/th>\r\n              <th style=\"text-align:left;padding:.4rem .6rem;color:var(--text3);font-weight:500\">Trasportatore<\/th>\r\n              <th style=\"text-align:left;padding:.4rem .6rem;color:var(--text3);font-weight:500\">Impianto<\/th>\r\n              <th style=\"text-align:left;padding:.4rem .6rem;color:var(--text3);font-weight:500\">R\/D<\/th>\r\n              <th style=\"text-align:right;padding:.4rem .6rem;color:var(--text3);font-weight:500;font-family:var(--mono)\">kg<\/th>\r\n            <\/tr>\r\n          <\/thead>\r\n          <tbody>${firRows}<\/tbody>\r\n        <\/table>\r\n      <\/div>\r\n    <\/div>`;\r\n}\r\n\r\nfunction switchTab(name, btn) {\r\n  document.querySelectorAll('.op-main .tab-btn').forEach(b => b.classList.remove('active'));\r\n  btn.classList.add('active');\r\n  document.getElementById('tab-registro').style.display    = name === 'registro' ? '' : 'none';\r\n  document.getElementById('tab-statistiche').style.display = name === 'statistiche' ? '' : 'none';\r\n  if (name === 'statistiche') renderStatistiche();\r\n}\r\nfunction switchImpTab(name, btn) {\r\n  document.querySelectorAll('#m-import .tab-btn').forEach(b => b.classList.remove('active'));\r\n  btn.classList.add('active');\r\n  document.getElementById('imp-tab-pdf-content').style.display = name==='pdf' ? '' : 'none';\r\n  document.getElementById('imp-tab-csv-content').style.display = name==='csv' ? '' : 'none';\r\n  document.getElementById('imp-confirm-btn').style.display = 'none';\r\n  _impMovs = null;\r\n}\r\n\r\nlet editMovId = null;\r\nfunction openAddMovimento() {\r\n  editMovId = null;\r\n  ['mov-data','mov-eer','mov-desc','mov-qty','mov-rd','mov-tras','mov-imp','mov-fir'].forEach(id => { const el = document.getElementById(id); if (el) el.value = ''; });\r\n  document.getElementById('mov-tipo').value = 'NP';\r\n  document.getElementById('mov-op').value   = 'S';\r\n  openModal('m-movimento');\r\n}\r\nfunction openEditMovimento(id) {\r\n  const e = S.entries.find(x => x.id === id);\r\n  if (!e) return;\r\n  editMovId = id;\r\n  document.getElementById('mov-data').value  = e.date || '';\r\n  document.getElementById('mov-eer').value   = e.eer  || '';\r\n  document.getElementById('mov-desc').value  = e.desc || '';\r\n  document.getElementById('mov-qty').value   = e.qty  || '';\r\n  document.getElementById('mov-tipo').value  = e.type || 'NP';\r\n  document.getElementById('mov-op').value    = e.op   || 'S';\r\n  document.getElementById('mov-rd').value    = e.rd   || '';\r\n  document.getElementById('mov-tras').value  = e.trasportatore || '';\r\n  document.getElementById('mov-imp').value   = e.impianto || '';\r\n  document.getElementById('mov-fir').value   = e.fir  || '';\r\n  openModal('m-movimento');\r\n}\r\nfunction salvaMovimento() {\r\n  const data = {\r\n    ulId: activeUlId, date: document.getElementById('mov-data').value,\r\n    eer:  document.getElementById('mov-eer').value.trim(), desc: document.getElementById('mov-desc').value.trim(),\r\n    qty:  parseFloat(document.getElementById('mov-qty').value) || 0,\r\n    type: document.getElementById('mov-tipo').value, op: document.getElementById('mov-op').value,\r\n    rd:   document.getElementById('mov-rd').value.trim(),\r\n    trasportatore: document.getElementById('mov-tras').value.trim(),\r\n    impianto: document.getElementById('mov-imp').value.trim(),\r\n    fir:  document.getElementById('mov-fir').value.trim(), tx: 'no',\r\n  };\r\n  if (!data.eer || !data.qty) { showToast('EER e quantit\u00e0 obbligatori', true); return; }\r\n  if (editMovId) {\r\n    const idx = S.entries.findIndex(e => e.id === editMovId);\r\n    if (idx >= 0) S.entries[idx] = { ...S.entries[idx], ...data };\r\n  } else { data.id = Date.now() + Math.floor(Math.random()*10000); S.entries.push(data); }\r\n  saveState(); renderRegistro(); renderKPI(activeOpId, activeUlId);\r\n  closeModal('m-movimento'); showToast('\u2713 Movimento salvato');\r\n}\r\nfunction eliminaMovimento(id) {\r\n  if (!confirm('Eliminare questa movimentazione?')) return;\r\n  S.entries = S.entries.filter(e => e.id !== id);\r\n  saveState(); renderRegistro(); renderKPI(activeOpId, activeUlId); showToast('\u2713 Eliminato');\r\n}\r\n\r\nconst CMAPS = [\r\n  {3:' ',10:\"'\",11:'(',12:')',13:'*',15:',',17:'.',18:'\/',19:'0',20:'1',21:'2',22:'3',23:'4',24:'5',25:'6',27:'8',28:'9',29:':',36:'A',38:'C',39:'D',40:'E',41:'F',44:'I',47:'L',48:'M',49:'N',50:'O',51:'P',52:'Q',53:'R',54:'S',55:'T',56:'U',68:'a',69:'b',70:'c',71:'d',72:'e',73:'f',74:'g',75:'h',76:'i',78:'k',79:'l',80:'m',81:'n',82:'o',83:'p',84:'q',85:'r',86:'s',87:'t',88:'u',89:'v',93:'z',106:'\\u00e0',113:'\\u00e8'},\r\n  {3:' ',10:\"'\",11:'(',12:')',13:'*',15:',',17:'.',18:'\/',19:'0',20:'1',21:'2',22:'3',23:'4',24:'5',25:'6',26:'7',27:'8',28:'9',29:':',36:'A',37:'B',38:'C',39:'D',40:'E',41:'F',42:'G',43:'H',44:'I',45:'J',46:'K',47:'L',48:'M',49:'N',50:'O',51:'P',52:'Q',53:'R',54:'S',55:'T',56:'U',57:'V',58:'W',59:'X',60:'Y',61:'Z',68:'a',69:'b',70:'c',71:'d',72:'e',73:'f',74:'g',75:'h',76:'i',79:'l',80:'m',81:'n',82:'o',83:'p',84:'q',85:'r',86:'s',87:'t',88:'u',89:'v',91:'x',93:'z'},\r\n  {3:' ',16:'-',17:'.',19:'0',20:'1',21:'2',22:'3',23:'4',36:'A',38:'C',40:'E',42:'G',43:'H',44:'I',47:'L',48:'M',49:'N',50:'O',51:'P',53:'R',54:'S',55:'T',57:'V',59:'X',68:'a',80:'m',82:'o'}\r\n];\r\nfunction cidDecode(hex, cmap) {\r\n  let r = '';\r\n  for (let i = 0; i < hex.length - 1; i += 4) r += cmap[parseInt(hex.substr(i,4),16)] || '';\r\n  return r;\r\n}\r\nasync function pdfDecompress(binStr) {\r\n  if (typeof DecompressionStream === 'undefined') return null;\r\n  const bytes = new Uint8Array(binStr.length);\r\n  for (let i = 0; i < binStr.length; i++) bytes[i] = binStr.charCodeAt(i) & 0xFF;\r\n  const payload = bytes.slice(2);\r\n  const ds = new DecompressionStream('deflate-raw');\r\n  const w = ds.writable.getWriter(); const r = ds.readable.getReader();\r\n  w.write(payload); w.close();\r\n  const chunks = [];\r\n  while (true) { const {done, value} = await r.read(); if (done) break; chunks.push(value); }\r\n  const len = chunks.reduce((a,c) => a+c.length, 0);\r\n  const out = new Uint8Array(len); let off = 0;\r\n  chunks.forEach(c => { out.set(c,off); off += c.length; });\r\n  let s = '';\r\n  for (let i = 0; i < out.length; i++) s += String.fromCharCode(out[i]);\r\n  return s;\r\n}\r\nasync function parsaPDFPrometeo(arrayBuffer) {\r\n  const raw = new Uint8Array(arrayBuffer);\r\n  let bin = '';\r\n  for (let i = 0; i < raw.length; i += 65536) bin += String.fromCharCode.apply(null, raw.subarray(i, Math.min(i+65536, raw.length)));\r\n  const streamRe = \/stream\\r?\\n([\\s\\S]*?)\\r?\\nendstream\/g;\r\n  const rawStreams = []; let m;\r\n  while ((m = streamRe.exec(bin)) !== null) rawStreams.push(m[1]);\r\n  const contentStreams = [];\r\n  for (const s of rawStreams) {\r\n    if (s.indexOf('beginbfchar') >= 0) continue;\r\n    const b0 = s.charCodeAt(0) & 0xFF;\r\n    if (b0 === 0x78) { try { const dec = await pdfDecompress(s); if (dec && (dec.indexOf('Tf') >= 0 || dec.indexOf('TJ') >= 0)) contentStreams.push(dec); } catch(e) {} }\r\n  }\r\n  if (!contentStreams.length) return [];\r\n  const tokens = [];\r\n  const fontMap = {F1:1, F2:0, F3:2}; let cf = 1;\r\n  const opRe = \/\\\/(F\\d+)\\s+[\\d.]+\\s+Tf|<([0-9A-Fa-f]+)>\\s*Tj|\\[([^\\]]+)\\]\\s*TJ\/g;\r\n  for (const cs of contentStreams) {\r\n    let om;\r\n    while ((om = opRe.exec(cs)) !== null) {\r\n      if (om[1]) { cf = fontMap[om[1]] !== undefined ? fontMap[om[1]] : 1; }\r\n      else if (om[2]) { const t = cidDecode(om[2], CMAPS[cf]); if (t.trim()) tokens.push(t); }\r\n      else if (om[3]) { const hexes = om[3].match(\/<([0-9A-Fa-f]+)>\/g) || []; const t = hexes.map(h => cidDecode(h.slice(1,-1), CMAPS[cf])).join(''); if (t.trim()) tokens.push(t); }\r\n    }\r\n  }\r\n  const movs = []; let currentCer = '', currentDesc = ''; let i = 0;\r\n  while (i < tokens.length) {\r\n    const t = tokens[i].trim();\r\n    if (t === 'C.E.R.:') {\r\n      i++;\r\n      if (i < tokens.length) {\r\n        const cm = tokens[i].trim().match(\/^(\\d{6}\\*?)(.*)\/);\r\n        if (cm) { currentCer = cm[1]; currentDesc = cm[2].trim().substring(0,100); if (!currentDesc && i+1 < tokens.length && !\/^(N\\.|C\\.E\\.R\\.|STAMPA|Registro|CER\\s|\\d)\/.test(tokens[i+1])) currentDesc = tokens[++i].trim().substring(0,100); }\r\n      }\r\n      i++; continue;\r\n    }\r\n    if (\/^(?:G?K?)?RL\\s+\\d+\\s*$\/.test(t) && currentCer) {\r\n      const firNum = t.trim(); i++;\r\n      let firSuffix = '';\r\n      if (i < tokens.length && \/^[A-Z]{1,2}$\/.test(tokens[i].trim())) firSuffix = tokens[i++].trim();\r\n      const numM = firNum.match(\/\\d+\/);\r\n      const fir  = 'GKRLX ' + (numM ? numM[0] : firNum) + (firSuffix ? ' '+firSuffix : '');\r\n      let data = '';\r\n      if (i < tokens.length && \/^\\d{1,2}\\\/\\d{2}\\\/\\d{2,4}$\/.test(tokens[i].trim())) data = tokens[i++].trim();\r\n      if (!data) continue;\r\n      if (i < tokens.length && \/Solido\/i.test(tokens[i])) i++;\r\n      if (i < tokens.length && \/S\\.R\\.L\\.|ARTR|ARTHR\/i.test(tokens[i])) i++;\r\n      let dest = '', tras = '', rd = '', qty = 0;\r\n      if (i < tokens.length && !\/^[RD]\\d+$\/.test(tokens[i].trim())) dest = tokens[i++].trim();\r\n      if (i < tokens.length && !\/^[RD]\\d+$\/.test(tokens[i].trim())) tras = tokens[i++].trim();\r\n      if (i < tokens.length && \/^[RD]\\d+$\/.test(tokens[i].trim()))  rd   = tokens[i++].trim();\r\n      if (i < tokens.length) { const qm = tokens[i].trim().match(\/^(\\d+[,\\.]\\d+)\/); if (qm) { qty = parseFloat(qm[1].replace(',','.')); i++; } }\r\n      if (!rd || !qty) continue;\r\n      const dp = data.split('\/'); const aa = dp[2].length===2 ? '20'+dp[2] : dp[2];\r\n      movs.push({ id: Date.now() + Math.floor(Math.random()*100000), ulId: activeUlId, date: aa+'-'+dp[1].padStart(2,'0')+'-'+dp[0].padStart(2,'0'), eer: currentCer, desc: currentDesc, fir, impianto: dest, trasportatore: tras, rd, qty, type: currentCer.endsWith('*') ? 'P' : 'NP', op: 'S', tx: 'no' });\r\n      continue;\r\n    }\r\n    i++;\r\n  }\r\n  return movs;\r\n}\r\n\r\nasync function parsaPDFRicevuta(arrayBuffer) {\r\n  const raw = new Uint8Array(arrayBuffer);\r\n  let bin = '';\r\n  for (let i = 0; i < raw.length; i += 65536) bin += String.fromCharCode.apply(null, raw.subarray(i, Math.min(i+65536, raw.length)));\r\n  const streamRe = \/stream\\r?\\n([\\s\\S]*?)\\r?\\nendstream\/g;\r\n  const rawStreams = []; let m;\r\n  while ((m = streamRe.exec(bin)) !== null) rawStreams.push(m[1]);\r\n  let text = '';\r\n  for (const s of rawStreams) {\r\n    const b0 = s.charCodeAt(0) & 0xFF; let content = s;\r\n    if (b0 === 0x78) { try { const dec = await pdfDecompress(s); if (dec) content = dec; } catch(e) {} }\r\n    const tjBlocks = content.match(\/\\[([^\\]]+)\\]\\s*TJ\/g) || [];\r\n    tjBlocks.forEach(block => {\r\n      const parts = block.match(\/\\(([^)\\\\]*(?:\\\\.[^)\\\\]*)*)\\)\/g) || [];\r\n      parts.forEach(p => { const c = p.slice(1,-1).replace(\/\\\\n\/g,' ').replace(\/\\\\r\/g,' ').replace(\/\\\\\\\\\/g,'\\\\'); text += c; });\r\n      text += ' ';\r\n    });\r\n  }\r\n  return text.replace(\/\\s+\/g,' ').trim();\r\n}\r\nfunction parsaRicevuta(txt) {\r\n  const t = txt.replace(\/\\s+\/g,' ');\r\n  const g = (re) => { const m = t.match(re); return m ? m[1].trim() : ''; };\r\n  const nome   = g(\/Denominazione\\s*:\\s*([A-Z0-9\\s'.,&\\-()]+?)(?:\\s+Indirizzo|Codice fiscale|Numero dipendenti|$)\/i) || g(\/Denominazione\\s*[:\\s]+(.+?)(?:Indirizzo|Codice|Numero|\\n)\/i);\r\n  const cf     = g(\/Codice fiscale\\s*:\\s*([0-9A-Z]{11,16})\/i);\r\n  const dip    = g(\/Numero dipendenti\\s*:\\s*(\\d+)\/i);\r\n  const rapp   = g(\/Operatore rappresentato da\\s*:\\s*(.+?)\\s*\\(\/i);\r\n  const pratica= g(\/Identificativo pratica\\s*:\\s*([0-9\\-]+)\/i);\r\n  const dataIsc= g(\/Data creazione\\s*:\\s*(\\d{2}\\\/\\d{2}\\\/\\d{4})\/i);\r\n  const uls = [];\r\n  const ulRe = \/Unit[\u00e0a]\\s+locale\\s*:\\s*(.+?)\\s+Indirizzo\\s*:\\s*(.+?)\\s+Attivit[\u00e0a]\\s*:\\s*(.+?)(?=Unit[\u00e0a]\\s+locale|$)\/gi;\r\n  let um;\r\n  while ((um = ulRe.exec(t)) !== null) uls.push({ nome: um[1].trim(), indirizzo: um[2].trim(), attivita: um[3].trim() });\r\n  const sede = g(\/Indirizzo sede legale\\s*:\\s*(.+?)(?=Operatore|$)\/i);\r\n  return { nome, cf, dip, rapp, pratica, dataIsc, sede, uls };\r\n}\r\n\r\nasync function handleRicevute(files) {\r\n  const log = document.getElementById('ricevuta-log');\r\n  log.innerHTML = '<div style=\"font-size:.75rem;color:var(--text3);margin-top:.5rem;\">Elaborazione in corso...<\/div>';\r\n  let ok = 0, err = 0;\r\n  for (const file of files) {\r\n    try {\r\n      const ab = await file.arrayBuffer(); const txt = await parsaPDFRicevuta(ab); const dati = parsaRicevuta(txt);\r\n      if (!dati.nome) { err++; log.innerHTML += `<div style=\"font-size:.72rem;color:var(--red);margin-top:.3rem;\">\u2715 ${file.name}: nome non trovato<\/div>`; continue; }\r\n      let op = S.operatori.find(o => o.cf && o.cf === dati.cf);\r\n      if (!op) {\r\n        op = { id: Date.now() + Math.floor(Math.random()*10000), nome: dati.nome, cf: dati.cf, piva: '', dip: dati.dip, rapp: dati.rapp, sede: dati.sede, pratica: dati.pratica, dataIsc: dati.dataIsc ? dati.dataIsc.split('\/').reverse().join('-') : '' };\r\n        S.operatori.push(op);\r\n      }\r\n      dati.uls.forEach(ul => { const exists = S.ul.find(u => u.operatoreId === op.id && u.indirizzo === ul.indirizzo); if (!exists) S.ul.push({ id: Date.now() + Math.floor(Math.random()*10000), operatoreId: op.id, nome: ul.nome, indirizzo: ul.indirizzo, attivita: ul.attivita, categoria: 'R' }); });\r\n      saveState(); updateSearchCount(); renderAdminOpList(); ok++;\r\n      log.innerHTML += `<div style=\"font-size:.72rem;color:var(--green);margin-top:.3rem;\">\u2713 ${dati.nome} (${dati.uls.length} UL)<\/div>`;\r\n    } catch(e) { err++; log.innerHTML += `<div style=\"font-size:.72rem;color:var(--red);margin-top:.3rem;\">\u2715 ${file.name}: ${e.message}<\/div>`; }\r\n  }\r\n  showToast(ok ? `\u2713 ${ok} operatore\/i caricati` : 'Nessun operatore trovato', !ok);\r\n}\r\n\r\nasync function handlePrometeo(file) {\r\n  if (!file) return;\r\n  const opId = parseInt(document.getElementById('prometeo-op-sel').value);\r\n  const ulId = parseInt(document.getElementById('prometeo-ul-sel').value);\r\n  const log  = document.getElementById('prometeo-log');\r\n  if (!opId || !ulId) { log.innerHTML = '<div style=\"font-size:.72rem;color:var(--amber);margin-top:.5rem;\">\u26a0 Seleziona operatore e unit\u00e0 locale<\/div>'; return; }\r\n  log.innerHTML = '<div style=\"font-size:.72rem;color:var(--text3);margin-top:.5rem;\">Lettura PDF...<\/div>';\r\n  try {\r\n    const ab = await file.arrayBuffer();\r\n    const prevUlId = activeUlId; activeUlId = ulId;\r\n    const movs = await parsaPDFPrometeo(ab); activeUlId = prevUlId;\r\n    if (!movs.length) { log.innerHTML = '<div style=\"font-size:.72rem;color:var(--red);margin-top:.5rem;\">Nessuna movimentazione trovata<\/div>'; return; }\r\n    movs.forEach(mv => { mv.ulId = ulId; S.entries.push(mv); });\r\n    saveState(); log.innerHTML = `<div style=\"font-size:.72rem;color:var(--green);margin-top:.5rem;\">\u2713 Importate ${movs.length} movimentazioni<\/div>`; showToast(`\u2713 ${movs.length} movimentazioni importate`);\r\n  } catch(e) { log.innerHTML = `<div style=\"font-size:.72rem;color:var(--red);margin-top:.5rem;\">Errore: ${e.message}<\/div>`; }\r\n}\r\n\r\nasync function handleImpPDF(file) {\r\n  if (!file || !activeUlId) return;\r\n  document.getElementById('imp-pdf-preview').innerHTML = '<div style=\"font-size:.75rem;color:var(--text3);\">Lettura...<\/div>';\r\n  try {\r\n    const ab = await file.arrayBuffer(); const movs = await parsaPDFPrometeo(ab); _impMovs = movs;\r\n    if (!movs.length) { document.getElementById('imp-pdf-preview').innerHTML = '<div style=\"font-size:.75rem;color:var(--red);\">Nessuna movimentazione trovata<\/div>'; return; }\r\n    document.getElementById('imp-pdf-preview').innerHTML = `\r\n      <div style=\"font-size:.75rem;color:var(--green);margin-bottom:.5rem;\">\u2713 Trovate ${movs.length} movimentazioni<\/div>\r\n      <div style=\"max-height:180px;overflow-y:auto;border:1px solid var(--border);border-radius:7px;\">\r\n        <table style=\"width:100%;font-size:.7rem;border-collapse:collapse;\">\r\n          <thead style=\"background:var(--surface)\"><tr>\r\n            <th style=\"padding:.3rem .6rem;text-align:left;color:var(--text3)\">Data<\/th>\r\n            <th style=\"padding:.3rem .6rem;text-align:left;color:var(--text3)\">EER<\/th>\r\n            <th style=\"padding:.3rem .6rem;text-align:left;color:var(--text3)\">R\/D<\/th>\r\n            <th style=\"padding:.3rem .6rem;text-align:right;color:var(--text3)\">kg<\/th>\r\n          <\/tr><\/thead>\r\n          <tbody>${movs.map(mv => `<tr>\r\n            <td style=\"padding:.25rem .6rem;border-top:1px solid var(--border)\">${mv.date}<\/td>\r\n            <td style=\"padding:.25rem .6rem;border-top:1px solid var(--border);color:var(--green);font-family:var(--mono)\">${mv.eer}<\/td>\r\n            <td style=\"padding:.25rem .6rem;border-top:1px solid var(--border)\">${mv.rd}<\/td>\r\n            <td style=\"padding:.25rem .6rem;border-top:1px solid var(--border);text-align:right;font-family:var(--mono)\">${mv.qty}<\/td>\r\n          <\/tr>`).join('')}<\/tbody>\r\n        <\/table>\r\n      <\/div>`;\r\n    document.getElementById('imp-confirm-btn').style.display = '';\r\n  } catch(e) { document.getElementById('imp-pdf-preview').innerHTML = `<div style=\"font-size:.75rem;color:var(--red);\">Errore: ${e.message}<\/div>`; }\r\n}\r\n\r\nfunction handleImpCSV(file) {\r\n  if (!file) return;\r\n  const reader = new FileReader();\r\n  reader.onload = (ev) => {\r\n    const lines = ev.target.result.split('\\n').filter(l => l.trim());\r\n    if (lines.length < 2) return;\r\n    const sep  = lines[0].includes(';') ? ';' : ',';\r\n    const hdrs = lines[0].split(sep).map(h => h.trim().toLowerCase());\r\n    const movs = [];\r\n    for (let i = 1; i < lines.length; i++) {\r\n      const cols = lines[i].split(sep);\r\n      const get  = (k) => (cols[hdrs.indexOf(k)]||'').trim();\r\n      const qty  = parseFloat((get('qty')||get('quantita')||get('kg')||'0').replace(',','.'));\r\n      if (!qty) continue;\r\n      movs.push({ id: Date.now() + i, ulId: activeUlId, date: get('data')||get('date'), eer: get('eer')||get('cer'), desc: get('descrizione')||get('desc'), qty, type: (get('tipo')||'NP').toUpperCase(), op: (get('operazione')||'S').toUpperCase(), rd: get('rd')||get('r\/d'), trasportatore: get('trasportatore'), impianto: get('impianto'), fir: get('fir'), tx: 'no' });\r\n    }\r\n    _impMovs = movs;\r\n    document.getElementById('imp-csv-preview').innerHTML = `<div style=\"font-size:.75rem;color:var(--green);margin-top:.5rem;\">\u2713 Trovate ${movs.length} righe<\/div>`;\r\n    document.getElementById('imp-confirm-btn').style.display = movs.length ? '' : 'none';\r\n  };\r\n  reader.readAsText(file);\r\n}\r\n\r\nfunction confirmImport() {\r\n  if (!_impMovs || !_impMovs.length) return;\r\n  _impMovs.forEach(mv => { mv.ulId = activeUlId; S.entries.push(mv); });\r\n  saveState(); renderRegistro(); renderKPI(activeOpId, activeUlId);\r\n  closeModal('m-import'); showToast(`\u2713 Importate ${_impMovs.length} movimentazioni`); _impMovs = null;\r\n}\r\nfunction openImportModal() {\r\n  document.getElementById('imp-pdf-preview').innerHTML = '';\r\n  document.getElementById('imp-csv-preview').innerHTML = '';\r\n  document.getElementById('imp-confirm-btn').style.display = 'none';\r\n  _impMovs = null; openModal('m-import');\r\n}\r\n\r\nlet editOpId = null;\r\nfunction openAddOperatore() {\r\n  editOpId = null;\r\n  ['aop-nome','aop-cf','aop-piva','aop-dip','aop-rapp','aop-sede','aop-pratica','aop-data'].forEach(id => { document.getElementById(id).value = ''; });\r\n  openModal('m-operatore');\r\n}\r\nfunction openEditOperatore(id) {\r\n  const op = S.operatori.find(o => o.id === id);\r\n  if (!op) return;\r\n  editOpId = id;\r\n  document.getElementById('aop-nome').value    = op.nome    || '';\r\n  document.getElementById('aop-cf').value      = op.cf      || '';\r\n  document.getElementById('aop-piva').value    = op.piva    || '';\r\n  document.getElementById('aop-dip').value     = op.dip     || '';\r\n  document.getElementById('aop-rapp').value    = op.rapp    || '';\r\n  document.getElementById('aop-sede').value    = op.sede    || '';\r\n  document.getElementById('aop-pratica').value = op.pratica || '';\r\n  document.getElementById('aop-data').value    = op.dataIsc || '';\r\n  openModal('m-operatore');\r\n}\r\nfunction salvaOperatore() {\r\n  const nome = document.getElementById('aop-nome').value.trim();\r\n  if (!nome) { showToast('Nome obbligatorio', true); return; }\r\n  const data = { nome, cf: document.getElementById('aop-cf').value.trim(), piva: document.getElementById('aop-piva').value.trim(), dip: document.getElementById('aop-dip').value.trim(), rapp: document.getElementById('aop-rapp').value.trim(), sede: document.getElementById('aop-sede').value.trim(), pratica: document.getElementById('aop-pratica').value.trim(), dataIsc: document.getElementById('aop-data').value };\r\n  if (editOpId) { const idx = S.operatori.findIndex(o => o.id === editOpId); if (idx >= 0) S.operatori[idx] = { ...S.operatori[idx], ...data }; }\r\n  else { data.id = Date.now() + Math.floor(Math.random()*10000); S.operatori.push(data); }\r\n  saveState(); updateSearchCount(); renderAdminOpList(); closeModal('m-operatore'); showToast('\u2713 Operatore salvato');\r\n}\r\nfunction eliminaOperatore(id) {\r\n  const op = S.operatori.find(o => o.id === id);\r\n  if (!confirm(`Eliminare \"${op?.nome}\" e tutte le sue unit\u00e0 locali e movimentazioni?`)) return;\r\n  const ulIds = S.ul.filter(u => u.operatoreId === id).map(u => u.id);\r\n  S.entries = S.entries.filter(e => !ulIds.includes(e.ulId));\r\n  S.ul = S.ul.filter(u => u.operatoreId !== id);\r\n  S.operatori = S.operatori.filter(o => o.id !== id);\r\n  saveState(); updateSearchCount(); renderAdminOpList(); showToast('\u2713 Operatore eliminato');\r\n}\r\nfunction renderAdminOpList() {\r\n  const list = document.getElementById('admin-op-list');\r\n  if (!list) return;\r\n  if (!S.operatori.length) { list.innerHTML = '<div class=\"empty\"><div class=\"empty-icon\">\ud83c\udfe2<\/div>Nessun operatore. Carica una ricevuta PDF o aggiungi manualmente.<\/div>'; return; }\r\n  list.innerHTML = S.operatori.map(op => {\r\n    const uls = S.ul.filter(u => u.operatoreId === op.id);\r\n    const movs = S.entries.filter(e => uls.map(u=>u.id).includes(e.ulId));\r\n    return `<div class=\"op-list-item\"><div><div class=\"op-list-name\">${op.nome}<\/div><div class=\"op-list-meta\">${op.cf ? 'CF '+op.cf : ''} \u00b7 ${uls.length} UL \u00b7 ${movs.length} movimentazioni<\/div><\/div><button class=\"btn btn-outline\" onclick=\"openEditOperatore(${op.id})\">\u270f Modifica<\/button><button class=\"btn btn-outline\" style=\"color:var(--red);border-color:var(--red)\" onclick=\"eliminaOperatore(${op.id})\">\u2715<\/button><\/div>`;\r\n  }).join('');\r\n}\r\n\r\nfunction refreshPrometeoSelectors() {\r\n  const opSel = document.getElementById('prometeo-op-sel');\r\n  const ulSel = document.getElementById('prometeo-ul-sel');\r\n  if (!opSel) return;\r\n  opSel.innerHTML = '<option value=\"\">\u2014 Seleziona operatore \u2014<\/option>' + S.operatori.map(op => `<option value=\"${op.id}\">${op.nome}<\/option>`).join('');\r\n  ulSel.innerHTML = '<option value=\"\">\u2014 Seleziona UL \u2014<\/option>';\r\n  opSel.onchange = () => { const id = parseInt(opSel.value); ulSel.innerHTML = '<option value=\"\">\u2014 Seleziona UL \u2014<\/option>' + S.ul.filter(u => u.operatoreId === id).map(u => `<option value=\"${u.id}\">${u.nome}<\/option>`).join(''); };\r\n}\r\n\r\nfunction esportaBackup() {\r\n  const json = JSON.stringify({ operatori: S.operatori, ul: S.ul, entries: S.entries }, null, 2);\r\n  const blob = new Blob([json], { type: 'application\/json' });\r\n  const a = document.createElement('a'); a.href = URL.createObjectURL(blob);\r\n  a.download = `rentri_backup_${new Date().toISOString().slice(0,10)}.json`; a.click(); showToast('\u2713 Backup esportato');\r\n}\r\nfunction importaBackup(input) {\r\n  const file = input.files[0]; if (!file) return;\r\n  const reader = new FileReader();\r\n  reader.onload = (ev) => {\r\n    try {\r\n      const d = JSON.parse(ev.target.result);\r\n      if (!confirm(`Importare ${d.operatori?.length||0} operatori, ${d.ul?.length||0} UL, ${d.entries?.length||0} movimentazioni? I dati attuali verranno sovrascritti.`)) return;\r\n      S.operatori = d.operatori || []; S.ul = d.ul || []; S.entries = d.entries || [];\r\n      saveState(); updateSearchCount(); renderAdminOpList(); updateBackupInfo(); showToast('\u2713 Backup importato');\r\n    } catch(e) { showToast('Errore nel file JSON', true); }\r\n  };\r\n  reader.readAsText(file);\r\n}\r\nfunction updateBackupInfo() {\r\n  const el = document.getElementById('backup-info'); if (!el) return;\r\n  el.innerHTML = `Operatori: ${S.operatori.length} &nbsp;\u00b7&nbsp; Unit\u00e0 Locali: ${S.ul.length} &nbsp;\u00b7&nbsp; Movimentazioni: ${S.entries.length}<br>Ultimo salvataggio: ${new Date().toLocaleString('it-IT')}`;\r\n}\r\n\r\nfunction openAdmin() { document.getElementById('pwd-screen').style.display = 'flex'; document.getElementById('pwd-input').value = ''; document.getElementById('pwd-err').textContent = ''; setTimeout(() => document.getElementById('pwd-input').focus(), 100); }\r\nfunction checkPwd() {\r\n  const pwd = document.getElementById('pwd-input').value;\r\n  if (pwd === ADMIN_PWD) { document.getElementById('pwd-screen').style.display = 'none'; showPage('page-admin'); renderAdminOpList(); refreshPrometeoSelectors(); updateBackupInfo(); }\r\n  else { document.getElementById('pwd-err').textContent = 'Password errata'; document.getElementById('pwd-input').value = ''; }\r\n}\r\nfunction closePwd() { document.getElementById('pwd-screen').style.display = 'none'; }\r\nfunction adminNav(section, el) {\r\n  document.querySelectorAll('.admin-nav-item').forEach(n => n.classList.remove('active')); el.classList.add('active');\r\n  document.querySelectorAll('.admin-section').forEach(s => s.classList.remove('active'));\r\n  document.getElementById('admin-'+section).classList.add('active');\r\n  if (section === 'operatori') renderAdminOpList();\r\n  if (section === 'backup')    updateBackupInfo();\r\n}\r\n\r\nfunction esportaCSV() {\r\n  if (!activeUlId) return;\r\n  const ul = S.ul.find(u => u.id === activeUlId); const op = S.operatori.find(o => o.id === activeOpId);\r\n  const movs = S.entries.filter(e => e.ulId === activeUlId);\r\n  let csv = `Operatore: ${op?.nome||''} | CF: ${op?.cf||''}\\nUnit\u00e0 Locale: ${ul?.nome||''} \u2014 ${ul?.indirizzo||''}\\n\\n`;\r\n  csv += 'Data;EER;Descrizione;Tipo;Operazione;R\/D;Kg;FIR;Trasportatore;Impianto\\n';\r\n  movs.forEach(e => { csv += [e.date,e.eer,`\"${e.desc||''}\"`,e.type,e.op,e.rd,e.qty,e.fir,`\"${e.trasportatore||''}\"`,`\"${e.impianto||''}\"`].join(';') + '\\n'; });\r\n  const blob = new Blob(['\\uFEFF'+csv], { type: 'text\/csv;charset=utf-8' });\r\n  const a = document.createElement('a'); a.href = URL.createObjectURL(blob);\r\n  a.download = `${ul?.nome||'registro'}_${new Date().getFullYear()}.csv`; a.click(); showToast('\u2713 CSV esportato');\r\n}\r\n\r\nfunction dzOver(e, id) { e.preventDefault(); document.getElementById(id)?.classList.add('over'); }\r\nfunction dzOut(id)     { document.getElementById(id)?.classList.remove('over'); }\r\nfunction dzDrop(e, tipo) {\r\n  e.preventDefault(); dzOut('dz-'+tipo);\r\n  const file = e.dataTransfer.files[0]; if (!file) return;\r\n  if (tipo === 'ricevuta') handleRicevute([file]);\r\n  if (tipo === 'prometeo') handlePrometeo(file);\r\n}\r\n\r\nfunction openModal(id)  { document.getElementById(id).classList.add('open'); }\r\nfunction closeModal(id) { document.getElementById(id).classList.remove('open'); }\r\ndocument.querySelectorAll('.overlay').forEach(ov => ov.addEventListener('click', e => { if (e.target === ov) closeModal(ov.id); }));\r\n\r\nlet toastTimer;\r\nfunction showToast(msg, isErr = false) {\r\n  const el = document.getElementById('toast');\r\n  el.textContent = msg; el.className = 'show ' + (isErr ? 'err' : 'ok');\r\n  clearTimeout(toastTimer); toastTimer = setTimeout(() => { el.className = ''; }, 3000);\r\n}\r\n\r\nloadState();\r\ncaricaDatiIniziali();\r\nupdateSearchCount();\r\nshowPage('page-search');\r\n<\/script>\r\n<\/body>\r\n<\/html>\r\n\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>RENTRI Manager \u2014 ECOF Italia ECOF ITALIA S.R.L. \u2014 Gestione Registri \u2014 operatori registrati \u00b7 premi \u21b5 per aprire \u2315 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-610","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/danielepatente.it\/index.php\/wp-json\/wp\/v2\/pages\/610","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/danielepatente.it\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/danielepatente.it\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/danielepatente.it\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/danielepatente.it\/index.php\/wp-json\/wp\/v2\/comments?post=610"}],"version-history":[{"count":51,"href":"https:\/\/danielepatente.it\/index.php\/wp-json\/wp\/v2\/pages\/610\/revisions"}],"predecessor-version":[{"id":664,"href":"https:\/\/danielepatente.it\/index.php\/wp-json\/wp\/v2\/pages\/610\/revisions\/664"}],"wp:attachment":[{"href":"https:\/\/danielepatente.it\/index.php\/wp-json\/wp\/v2\/media?parent=610"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}