<rss version="2.0">
  <channel>
    <title>Сервіси міської ради</title>
    <link>https://test2.vmr.gov.ua/servisy-miskoi-rady</link>
    <description><![CDATA[]]></description>
    <item>
      <title>Пошук нормативних актів міської ради</title>
      <link>https://test2.vmr.gov.ua/poshuk-normatyvnykh-aktiv</link>
      <description><![CDATA[<div id="vmr-legalacts-widget" class="vmr-la">
  <div class="vmr-la__header">
    <div>
      <div class="vmr-la__title">Документи Вінницької міської ради</div>
      <div class="vmr-la__subtitle">Пошук здійснюється серед нормативно-правових актів, оприлюднених з 2019 року</div>
    </div>
    <div class="vmr-la__badge" id="vmr-la-status">Ініціалізація…</div>
  </div>

  <div class="vmr-la__panel">
    <div class="vmr-la__tabs" role="tablist" aria-label="Типи документів">
      <button class="vmr-la__tab is-active" data-scope="all" role="tab" aria-selected="true">Усі</button>
      <button class="vmr-la__tab" data-scope="mr" role="tab" aria-selected="false">Рішення міської ради</button>
      <button class="vmr-la__tab" data-scope="vk" role="tab" aria-selected="false">Рішення виконавчого комітету</button>
      <button class="vmr-la__tab" data-scope="mayor" role="tab" aria-selected="false">Розпорядження міського голови</button>
    </div>

    <div class="vmr-la__filters">
      <div class="vmr-la__field">
        <label class="vmr-la__label" for="vmr-la-q">Назва / ключові слова</label>
        <input id="vmr-la-q" class="vmr-la__input" type="text" placeholder="Напр.: бюджет, земельні, комісія…" />
      </div>

      <div class="vmr-la__field">
        <label class="vmr-la__label" for="vmr-la-number">Номер</label>
        <input id="vmr-la-number" class="vmr-la__input" type="text" placeholder="Напр.: 123, 9/Р" />
      </div>

      <div class="vmr-la__field">
        <label class="vmr-la__label" for="vmr-la-type">Вид / тип</label>
        <select id="vmr-la-type" class="vmr-la__select">
          <option value="">Усі</option>
        </select>
      </div>

      <div class="vmr-la__field">
        <label class="vmr-la__label" for="vmr-la-date-from">Дата з</label>
        <input id="vmr-la-date-from" class="vmr-la__input" type="date" />
      </div>

      <div class="vmr-la__field">
        <label class="vmr-la__label" for="vmr-la-date-to">Дата по</label>
        <input id="vmr-la-date-to" class="vmr-la__input" type="date" />
      </div>

      <div class="vmr-la__actions">
        <button class="vmr-la__btn vmr-la__btn--primary" id="vmr-la-search">Пошук</button>
        <button class="vmr-la__btn" id="vmr-la-reset" title="Скинути фільтри">Скинути</button>
      </div>
    </div>
  </div>

  <div class="vmr-la__meta">
    <div id="vmr-la-count">—</div>
    <div class="vmr-la__right">
      <label class="vmr-la__label vmr-la__label--inline" for="vmr-la-page-size">На сторінці</label>
      <select id="vmr-la-page-size" class="vmr-la__select vmr-la__select--sm">
        <option value="10">10</option>
        <option value="25" selected>25</option>
        <option value="50">50</option>
      </select>
    </div>
  </div>

  <div class="vmr-la__tablewrap" role="region" aria-label="Результати пошуку">
    <table class="vmr-la__table">
      <thead>
        <tr>
          <th style="width: 150px;">Дата</th>
          <th style="width: 140px;">Номер</th>
          <th>Назва</th>
          <th style="width: 260px;">Вид/тип</th>
          <th style="width: 140px;">Посилання</th>
        </tr>
      </thead>
      <tbody id="vmr-la-tbody">
        <tr><td colspan="5" class="vmr-la__empty">Завантаження…</td></tr>
      </tbody>
    </table>
  </div>

<div class="vmr-la__pager">
  <button class="vmr-la__btn vmr-la__btn--sm" id="vmr-la-prev" disabled>Назад</button>
  <div class="vmr-la__pages" id="vmr-la-pages" aria-label="Нумерація сторінок"></div>
  <div class="vmr-la__pagerinfo" id="vmr-la-pageinfo">—</div>
  <button class="vmr-la__btn vmr-la__btn--sm" id="vmr-la-next" disabled>Далі</button>
</div>

  <div class="vmr-la__details">
    <div class="vmr-la__detailsbody">
      <div>
        <strong>Джерело даних:</strong>
        <a class="vmr-la__link" href="https://opendata.gov.ua" target="_blank" rel="noopener noreferrer">opendata.gov.ua</a>
      </div>
      <div>
        <strong>API/DataStore:</strong>
        <a
          id="vmr-la-src-acts"
          class="vmr-la__mono vmr-la__link"
          href="https://opendata.gov.ua/api/3/action/datastore_search?resource_id=50b2439b-6811-4323-83f1-13274174ede1&limit=1"
          target="_blank"
          rel="noopener noreferrer"
        >
          resource_id: 50b2439b-6811-4323-83f1-13274174ede1
        </a>
      </div>
    </div>
  </div>
</div>

<style>
  .vmr-la{
    width:100%;
    max-width:1800px;
    margin:0 auto;
    box-sizing:border-box;

    --vmr-primary:#0B4DA2;
    --vmr-primary-2:#083B7D;
    --vmr-bg:#F6F8FB;
    --vmr-card:#FFFFFF;
    --vmr-text:#0F172A;
    --vmr-muted:#64748B;
    --vmr-border:#E2E8F0;
    --vmr-shadow:0 10px 30px rgba(2,6,23,.08);
    --vmr-radius:14px;
    --vmr-font: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;

    font-family:var(--vmr-font);
    color:var(--vmr-text);
    background:linear-gradient(180deg, rgba(11,77,162,.06), rgba(246,248,251,1) 160px);
    border:1px solid var(--vmr-border);
    border-radius:var(--vmr-radius);
    padding:16px;
    box-shadow:var(--vmr-shadow);
  }

  .vmr-la__header{ display:flex; gap:12px; justify-content:space-between; align-items:center; padding:8px 6px 14px; border-bottom:1px solid var(--vmr-border); margin-bottom:14px; }
  .vmr-la__title{ font-size:20px; font-weight:750; letter-spacing:.2px; }
  .vmr-la__subtitle{ margin-top:4px; font-size:13px; color:var(--vmr-muted); }
  .vmr-la__badge{ font-size:12px; color:var(--vmr-primary-2); background:rgba(11,77,162,.08); border:1px solid rgba(11,77,162,.18); padding:7px 10px; border-radius:999px; white-space:nowrap; }

  .vmr-la__panel{ background:var(--vmr-card); border:1px solid var(--vmr-border); border-radius:var(--vmr-radius); padding:12px; }
  .vmr-la__tabs{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:12px; }
  .vmr-la__tab{ cursor:pointer; border:1px solid var(--vmr-border); background:#fff; color:var(--vmr-text); border-radius:999px; padding:8px 12px; font-size:13px; transition:all .15s ease; }
  .vmr-la__tab:hover{ border-color:rgba(11,77,162,.45); }
  .vmr-la__tab.is-active{ background:rgba(11,77,162,.10); border-color:rgba(11,77,162,.35); color:var(--vmr-primary-2); font-weight:650; }

  .vmr-la__filters{ display:grid; grid-template-columns: 1.6fr 0.8fr 0.8fr 0.6fr 0.6fr auto; gap:10px; align-items:end; }
  @media (max-width:1100px){ .vmr-la__filters{ grid-template-columns:1fr 1fr; } .vmr-la__actions{ justify-content:flex-start; } }
  .vmr-la__field{ display:flex; flex-direction:column; gap:6px; }
  .vmr-la__label{ font-size:12px; color:var(--vmr-muted); }
  .vmr-la__label--inline{ margin-right:8px; }
  .vmr-la__input,.vmr-la__select{ border:1px solid var(--vmr-border); border-radius:12px; padding:10px; font-size:14px; outline:none; background:#fff; transition:border-color .15s ease, box-shadow .15s ease; }
  .vmr-la__select{ padding:10px 8px; }
  .vmr-la__select--sm{ padding:7px 8px; border-radius:10px; font-size:13px; }
  .vmr-la__input:focus,.vmr-la__select:focus{ border-color:rgba(11,77,162,.55); box-shadow:0 0 0 4px rgba(11,77,162,.12); }

  .vmr-la__actions{ display:flex; gap:8px; justify-content:flex-end; }
  .vmr-la__btn{ cursor:pointer; border:1px solid var(--vmr-border); background:#fff; border-radius:12px; padding:10px 12px; font-size:14px; transition:all .15s ease; }
  .vmr-la__btn:hover{ border-color:rgba(11,77,162,.45); }
  .vmr-la__btn:disabled{ opacity:.55; cursor:not-allowed; }
  .vmr-la__btn--primary{ background:var(--vmr-primary); border-color:var(--vmr-primary); color:#fff; font-weight:650; }
  .vmr-la__btn--primary:hover{ background:var(--vmr-primary-2); border-color:var(--vmr-primary-2); }
  .vmr-la__btn--sm{ padding:8px 10px; border-radius:10px; font-size:13px; }

  .vmr-la__meta{ display:flex; justify-content:space-between; align-items:center; margin:12px 2px 10px; color:var(--vmr-muted); font-size:13px; }
  .vmr-la__right{ display:flex; align-items:center; gap:8px; }

  .vmr-la__tablewrap{ overflow:auto; background:var(--vmr-card); border:1px solid var(--vmr-border); border-radius:var(--vmr-radius); }
  .vmr-la__table{ width:100%; border-collapse:separate; border-spacing:0; min-width:920px; table-layout:fixed; }
  .vmr-la__table thead th{ position:sticky; top:0; background:var(--vmr-bg); color:#334155; font-size:12px; letter-spacing:.3px; text-transform:uppercase; padding:12px; border-bottom:1px solid var(--vmr-border); z-index:2; }
  .vmr-la__table tbody td{ padding:12px; border-bottom:1px solid var(--vmr-border); vertical-align:top; font-size:14px; overflow:hidden; text-overflow:ellipsis; }
  .vmr-la__table tbody tr:hover td{ background:rgba(11,77,162,.04); }
  .vmr-la__empty{ text-align:center; padding:20px 12px !important; color:var(--vmr-muted); }
  .vmr-la__link{ color:var(--vmr-primary); text-decoration:none; font-weight:650; }
  .vmr-la__link:hover{ text-decoration:underline; }
  .vmr-la__muted{ color:var(--vmr-muted); font-size:12px; margin-top:4px; }
  .vmr-la__nowrap{ white-space:nowrap; }
  .vmr-la__mono{ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size:12px; }

  .vmr-la__pager{ display:flex; justify-content:center; align-items:center; gap:10px; padding:12px 0 2px; }
  .vmr-la__pagerinfo{ color:var(--vmr-muted); font-size:13px; min-width:180px; text-align:center; }

  .vmr-la__details{ margin-top:12px; border:1px solid var(--vmr-border); border-radius:var(--vmr-radius); background:#fff; padding:10px 12px; }
  .vmr-la__detailsbody{ margin-top:10px; display:flex; flex-direction:column; gap:8px; color:#334155; font-size:13px; }

  @media (max-width:720px){
    .vmr-la__table{ min-width:0; }
    .vmr-la__table thead{ display:none; }
    .vmr-la__table, .vmr-la__table tbody, .vmr-la__table tr, .vmr-la__table td{ display:block; width:100%; }

    .vmr-la__table tbody tr{
      padding:10px;
      margin:10px 8px;
      background:#fff;
      border:1px solid var(--vmr-border);
      border-radius:16px;
      box-shadow:0 6px 18px rgba(2,6,23,.06);
    }
    .vmr-la__table tbody td{ border-bottom:none; padding:8px; overflow:visible; text-overflow:clip; }

    .vmr-la__table tbody td::before{
      display:block;
      font-size:11px;
      letter-spacing:.3px;
      text-transform:uppercase;
      color:var(--vmr-muted);
      margin-bottom:4px;
    }
    .vmr-la__table tbody td:nth-child(1)::before{ content:"Дата"; }
    .vmr-la__table tbody td:nth-child(2)::before{ content:"Номер"; }
    .vmr-la__table tbody td:nth-child(3)::before{ content:"Назва"; }
    .vmr-la__table tbody td:nth-child(4)::before{ content:"Вид/тип"; }
    .vmr-la__table tbody td:nth-child(5)::before{ content:"Посилання"; }

    .vmr-la__table tbody td:nth-child(1),
    .vmr-la__table tbody td:nth-child(2){ display:inline-block; width:auto; vertical-align:top; }
    .vmr-la__table tbody td:nth-child(1){ padding-right:10px; }
    .vmr-la__nowrap{ white-space:normal; }

    .vmr-la__filters{ grid-template-columns:1fr; }
    .vmr-la__actions{ justify-content:stretch; }
    .vmr-la__actions .vmr-la__btn{ width:100%; }

    .vmr-la__meta{ flex-direction:column; align-items:flex-start; gap:8px; }
  }
    
 .vmr-la__pages{
  display:flex;
  gap:6px;
  flex-wrap:wrap;
  align-items:center;
  justify-content:center;
}
.vmr-la__pbtn{
  padding:6px 10px;
  border:1px solid var(--vmr-border);
  background:var(--vmr-card);
  border-radius:10px;
  cursor:pointer;
}
.vmr-la__pbtn.is-active{
  border-color: var(--vmr-primary);
  font-weight:700;
}
.vmr-la__dots{
  padding:0 6px;
  color: var(--vmr-muted);
}
 
</style>


<script>
(function(){
  const ACTS_RESOURCE_ID = "50b2439b-6811-4323-83f1-13274174ede1";
  const CKAN_SQL_URL = "https://opendata.gov.ua/api/3/action/datastore_search_sql";

  const els = {
    status: document.getElementById("vmr-la-status"),
    tabs: Array.from(document.querySelectorAll("#vmr-legalacts-widget .vmr-la__tab")),
    q: document.getElementById("vmr-la-q"),
    num: document.getElementById("vmr-la-number"),
    type: document.getElementById("vmr-la-type"),
    dateFrom: document.getElementById("vmr-la-date-from"),
    dateTo: document.getElementById("vmr-la-date-to"),
    btnSearch: document.getElementById("vmr-la-search"),
    btnReset: document.getElementById("vmr-la-reset"),
    tbody: document.getElementById("vmr-la-tbody"),
    count: document.getElementById("vmr-la-count"),
    prev: document.getElementById("vmr-la-prev"),
    next: document.getElementById("vmr-la-next"),
    pages: document.getElementById("vmr-la-pages"),
    pageInfo: document.getElementById("vmr-la-pageinfo"),
    pageSize: document.getElementById("vmr-la-page-size")
  };

  let scope = "all";
	let page = getPageFromUrl();
  let pageSize = parseInt(els.pageSize.value, 10) || 25;

  let pageRecords = [];
  let totalFound = 0;
  let lastRequestKey = "";
  let isLoading = false;

  function setStatus(text){ if (els.status) els.status.textContent = text; }

  function escapeHtml(s){
    return String(s ?? "")
      .replaceAll("&", "&amp;")
      .replaceAll("<", "&lt;")
      .replaceAll(">", "&gt;")
      .replaceAll('"', "&quot;")
      .replaceAll("'", "&#039;");
  }
  function escapeHtmlAttr(s){ return escapeHtml(s); }
  function normStr(s){ return (s || "").toString().trim().toLowerCase(); }
  function cleanNull(v){
    if (v === null || v === undefined) return "";
    if (typeof v === "string"){
      const t = v.trim();
      if (t.toLowerCase() === "null") return "";
      return t;
    }
    return v;
  }
  function toISODate(d){
    const s0 = String(cleanNull(d) || "").trim();
    if (!s0) return "";
    if (/^\d{4}-\d{2}-\d{2}T/.test(s0)) return s0.slice(0,10);
    if (/^\d{4}-\d{2}-\d{2}$/.test(s0)) return s0;
    if (/^\d{4}-\d{2}-\d{2}\s+/.test(s0)) return s0.slice(0,10);
    if (/^\d{4}\/\d{2}\/\d{2}$/.test(s0)) return s0.replaceAll("/", "-");
    if (/^\d{2}\.\d{2}\.\d{4}/.test(s0)){
      const [datePart] = s0.split(/\s+/);
      const [dd,mm,yy] = datePart.split(".");
      return `${yy}-${mm}-${dd}`;
    }
    return s0;
  }
  function formatDateUA(iso){
    const s = (iso || "").trim();
    if (!/^\d{4}-\d{2}-\d{2}$/.test(s)) return s || "—";
    const [y,m,d] = s.split("-");
    return `${d}.${m}.${y}`;
  }
  function sqlEscape(s){ return String(s || "").replaceAll("'", "''"); }

  // ===== JSONP =====
  function jsonp(url, params, timeoutMs){
    const cbName = "__vmr_jsonp_cb_" + Math.random().toString(36).slice(2);
    const timeout = timeoutMs ?? 30000;

    return new Promise((resolve, reject) => {
      const script = document.createElement("script");
      const cleanUp = () => {
        if (script && script.parentNode) script.parentNode.removeChild(script);
        try { delete window[cbName]; } catch(e){ window[cbName] = undefined; }
      };
      const timer = setTimeout(() => {
        cleanUp();
        reject(new Error("JSONP timeout"));
      }, timeout);

      window[cbName] = (data) => {
        clearTimeout(timer);
        cleanUp();
        resolve(data);
      };

      const qs = new URLSearchParams();
      Object.entries(params || {}).forEach(([k,v]) => {
        if (v === undefined || v === null) return;
        qs.append(k, String(v));
      });
      qs.append("callback", cbName);

      script.async = true;
      script.src = url + (url.includes("?") ? "&" : "?") + qs.toString();
      script.onerror = () => {
        clearTimeout(timer);
        cleanUp();
        reject(new Error("JSONP load error"));
      };

      document.head.appendChild(script);
    });
  }

  async function ckanSql(sql){
    const resp = await jsonp(CKAN_SQL_URL, { sql }, 30000);
    if (!resp || resp.success !== true) throw new Error("CKAN SQL error");
    return resp.result;
  }

  // ===== Type options =====
  const TYPE_OPTIONS = [
    { value: "", label: "Усі" },
    { value: "Рішення міської ради", label: "Рішення міської ради" },
    { value: "Рішення виконавчого комітету", label: "Рішення виконавчого комітету" },
    { value: "Розпорядження міського голови (Р)", label: "Розпорядження міського голови (Р)" },
    { value: "Розпорядження міського голови (О)", label: "Розпорядження міського голови (О)" }
  ];
  function buildTypeOptions(){
    if (!els.type) return;
    els.type.innerHTML = TYPE_OPTIONS
      .map(o => `<option value="${escapeHtmlAttr(o.value)}">${escapeHtml(o.label)}</option>`)
      .join("");
    els.type.value = "";
  }

  // ===== SQL builder (UPDATED) =====
 function buildSqlQuery({ q, num, type, fromIso, toIso, scope, limit, offset }){
  let where = `WHERE 1=1`;

  // вкладки
  if (scope === "mr") {
    where += ` AND lower("type") LIKE '%рішення міської ради%'`;
  } else if (scope === "vk") {
    where += ` AND lower("type") LIKE '%рішення виконавчого комітету%'`;
  } else if (scope === "mayor") {
    where += ` AND (lower("type") LIKE '%розпорядження міського голови (р)%'
                 OR lower("type") LIKE '%розпорядження міського голови (о)%'
                 OR lower("type") LIKE '%розпорядження міського голови%')`;
  }

  // type тільки на "Усі"
  if (scope === "all" && type) {
    const t = sqlEscape(type.toLowerCase());
    where += ` AND lower("type") = '${t}'`;
  }

  // ===== НОМЕР (фільтр) =====
  const numTrim = String(num || "").trim();
  const numTrimEsc = sqlEscape(numTrim);

  // нормалізація для SQL-порівнянь
  const numNorm = numTrim.replace(/\s+/g, "").toUpperCase();
  const numNormEsc = sqlEscape(numNorm);

  if (numTrim) {
    // фільтрація
    where += ` AND coalesce("number",'') ILIKE '%${numTrimEsc}%'`;
  }

  // ===== НАЗВА/ключові слова: тільки title + numeric-boundary =====
  const qTrim = String(q || "").trim();
  if (qTrim) {
    const qq = sqlEscape(qTrim);

    if (/^\d+$/.test(qTrim)) {
      where += ` AND coalesce("title",'') ~ '(^|[^0-9])${qq}([^0-9]|$)'`;
    } else {
      where += ` AND coalesce("title",'') ILIKE '%${qq}%'`;
    }
  }

  // дати
  if (fromIso) {
    const f = sqlEscape(fromIso);
    where += ` AND "acceptedDate" >= '${f}'`;
  }
  if (toIso) {
    const t = sqlEscape(toIso);
    where += ` AND "acceptedDate" < ('${t}'::date + interval '1 day')`;
  }

  // ===== ORDER BY з 3 групами =====
  // normalize_db_number = upper(regexp_replace(coalesce(number,''), '\s+', '', 'g'))
  // 0) exact: normalize_db_number = normalize_input
  // 1) для числового вводу: ^123[-/](Р|О)  (у верхньому регістрі)
  // 2) решта

const hasFrom = Boolean(fromIso);
const dateDir = hasFrom ? "ASC" : "DESC";

let orderBy = `"acceptedDate" ${dateDir}, "_id" ${dateDir}`;

if (numTrim) {
  const dbNorm = `upper(regexp_replace(coalesce("number",''), '\\s+', '', 'g'))`;

  // “пріоритет суфіксів” (123-Р/123/Р/123-О/123/О)
  if (/^\d+$/.test(numNorm)) {
    orderBy = `
      CASE
        WHEN ${dbNorm} = '${numNormEsc}' THEN 0
        WHEN ${dbNorm} ~ '^${numNormEsc}[-/](Р|О)$' THEN 1
        ELSE 2
      END,
      "acceptedDate" ${dateDir},
      "_id" ${dateDir}
    `.trim();
  } else {
    orderBy = `
      CASE
        WHEN ${dbNorm} = '${numNormEsc}' THEN 0
        ELSE 1
      END,
      "acceptedDate" ${dateDir},
      "_id" ${dateDir}
    `.trim();
  }
}


  const select = `
    SELECT "_id", "type", "title", "acceptedDate", "number", "issuedDate", "url"
    FROM "${ACTS_RESOURCE_ID}"
    ${where}
    ORDER BY ${orderBy}
    LIMIT ${Number(limit)} OFFSET ${Number(offset)}
  `.trim();

  const count = `
    SELECT count(*) AS total
    FROM "${ACTS_RESOURCE_ID}"
    ${where}
  `.trim();

  return { select, count };
}

  async function fetchPageFromApi({ q, num, type, fromIso, toIso, scope, page, pageSize }){
    const offset = (page - 1) * pageSize;
    const { select, count } = buildSqlQuery({
      q, num, type, fromIso, toIso, scope,
      limit: pageSize,
      offset
    });

    const [cnt, sel] = await Promise.all([ckanSql(count), ckanSql(select)]);
    const total = Number(cnt.records?.[0]?.total || 0);
    const records = sel.records || [];
    return { total, records };
  }

  function normalizeRecords(items){
    return (items || []).map(x => ({
      type: cleanNull(x.type),
      title: cleanNull(x.title),
      date: toISODate(x.acceptedDate),
      issuedDate: toISODate(x.issuedDate),
      number: cleanNull(x.number),
      url: cleanNull(x.url)
    }));
  }

  function buildPageList(current, total){
  const out = [];
  const windowSize = 2;
  const left = Math.max(2, current - windowSize);
  const right = Math.min(total - 1, current + windowSize);

  out.push(1);
  if (left > 2) out.push("…");
  for (let i = left; i <= right; i++) out.push(i);
  if (right < total - 1) out.push("…");
  if (total > 1) out.push(total);

  return out.filter((x, idx, arr) => idx === 0 || x !== arr[idx - 1]);
}

function renderPages(totalPages){
  if (!els.pages) return;

  const items = totalPages <= 7
    ? Array.from({length: totalPages}, (_, i) => i + 1)
    : buildPageList(page, totalPages);

  els.pages.innerHTML = items.map(x => {
    if (x === "…") return `<span class="vmr-la__dots">…</span>`;
    const isActive = x === page;
    return `
      <button
        type="button"
        class="vmr-la__pbtn ${isActive ? "is-active" : ""}"
        data-page="${x}"
        ${isActive ? 'aria-current="page"' : ""}
        ${isLoading ? "disabled" : ""}
      >${x}</button>
    `.trim();
  }).join("");
}

  
function render(){
  const total = totalFound;
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
  page = Math.min(page, totalPages);

  if (els.prev) els.prev.disabled = (page <= 1) || isLoading;
  if (els.next) els.next.disabled = (page >= totalPages) || isLoading;
  if (els.pageInfo) els.pageInfo.textContent = total ? `Сторінка ${page} з ${totalPages}` : "—";

  if (!total){
    if (els.count) els.count.textContent = "Нічого не знайдено";
    if (els.tbody) els.tbody.innerHTML = `<tr><td colspan="5" class="vmr-la__empty">Немає результатів за заданими критеріями.</td></tr>`;
    if (els.pages) els.pages.innerHTML = "";

    return;
  }

  // номери сторінок лише коли є результати
  renderPages(totalPages);

  const startIdx = (page - 1) * pageSize;
  const endIdx = Math.min(startIdx + pageRecords.length, total);
  if (els.count) els.count.textContent = `Знайдено: ${total}. Показано ${startIdx + 1}–${endIdx}.`;

  if (!els.tbody) return;

  els.tbody.innerHTML = pageRecords.map(item => {
    const dateCell =
      `${escapeHtml(formatDateUA(item.date))}` +
      (item.issuedDate ? `<div class="vmr-la__muted">Оприлюдн.: ${escapeHtml(formatDateUA(item.issuedDate))}</div>` : "");

    const numCell = escapeHtml(item.number || "—");

    const link = (item.url || "").trim();
    const linkCell = link
      ? `<a class="vmr-la__link" href="${escapeHtmlAttr(link)}" target="_blank" rel="noopener noreferrer">Відкрити</a>`
      : `<span class="vmr-la__muted">—</span>`;

    return `
      <tr>
        <td class="vmr-la__nowrap">${dateCell}</td>
        <td class="vmr-la__nowrap">${numCell}</td>
        <td>${escapeHtml(item.title || "—")}</td>
        <td>${escapeHtml(item.type || "—")}</td>
        <td class="vmr-la__nowrap">${linkCell}</td>
      </tr>
    `;
  }).join("");
}


  function getRequestKey(){
    return JSON.stringify({
      scope,
      q: normStr(els.q?.value),
      num: String(els.num?.value || "").trim(),   // важливо: exact зберігаємо як введено
      type: els.type?.value || "",
      from: (els.dateFrom?.value || "").trim(),
      to: (els.dateTo?.value || "").trim(),
      page,
      pageSize: parseInt(els.pageSize?.value, 10) || 25
    });
  }

function getPageFromUrl(){
  const p = parseInt(new URLSearchParams(window.location.search).get("page") || "1", 10);
  return Number.isFinite(p) && p > 0 ? p : 1;
}

function setPageToUrl(p){
  const url = new URL(window.location.href);

  if (Number(p) <= 1) {
    url.searchParams.delete("page");
  } else {
    url.searchParams.set("page", String(p));
  }
  if (url.toString() === window.location.href) return;
  window.history.replaceState({}, "", url.toString());
}


  async function runSearch(){
    const q = String(els.q?.value || "").trim();
    const num = String(els.num?.value || "").trim();
    const type = (els.type?.value || "");
    const fromIso = (els.dateFrom?.value || "").trim();
    const toIso = (els.dateTo?.value || "").trim();
    pageSize = parseInt(els.pageSize?.value, 10) || 25;

    const requestKey = getRequestKey();
    lastRequestKey = requestKey;

    isLoading = true;
    if (els.prev) els.prev.disabled = true;
    if (els.next) els.next.disabled = true;
    setStatus("Пошук по API…");
    if (els.tbody) els.tbody.innerHTML = `<tr><td colspan="5" class="vmr-la__empty">Завантаження…</td></tr>`;

    try{
      const res = await fetchPageFromApi({
        q, num, type,
        fromIso, toIso,
        scope, page, pageSize
      });

      if (requestKey !== lastRequestKey) return;

      totalFound = res.total;
      pageRecords = normalizeRecords(res.records);
      render();
      setStatus(`Доступно: ${totalFound}`);
    } catch(e){
      console.error(e);
      if (requestKey !== lastRequestKey) return;
      totalFound = 0;
      pageRecords = [];
      if (els.count) els.count.textContent = "Не вдалося отримати дані";
      if (els.pageInfo) els.pageInfo.textContent = "—";
      if (els.tbody) els.tbody.innerHTML = `<tr><td colspan="5" class="vmr-la__empty">Не вдалося виконати пошук через API.</td></tr>`;
      setStatus("Помилка (API)");
    } finally {
      if (requestKey === lastRequestKey){
        isLoading = false;
        render();
      }
    }
  }

  function setTypeForScope(nextScope){
    if (!els.type) return;

    if (nextScope === "all"){
      els.type.disabled = false;
      if (els.type.options[0]) els.type.options[0].textContent = "Усі";
      els.type.value = ""; // IMPORTANT: завжди скидаємо на "Усі"
      return;
    }

    els.type.disabled = true;

    if (nextScope === "mr"){
      els.type.value = "Рішення міської ради";
      return;
    }
    if (nextScope === "vk"){
      els.type.value = "Рішення виконавчого комітету";
      return;
    }
    if (nextScope === "mayor"){
      if (els.type.options[0]) els.type.options[0].textContent = "Розпорядження міського голови";
      els.type.value = "";
      return;
    }
  }

  function setScope(nextScope){
    scope = nextScope;

    els.tabs.forEach(btn => {
      const active = btn.dataset.scope === scope;
      btn.classList.toggle("is-active", active);
      btn.setAttribute("aria-selected", active ? "true" : "false");
    });

setTypeForScope(scope);
page = 1;
setPageToUrl(page); 
runSearch();
  }

  // Events
  els.tabs.forEach(btn => btn.addEventListener("click", () => setScope(btn.dataset.scope)));

 if (els.btnSearch) els.btnSearch.addEventListener("click", () => {
  page = 1;
  setPageToUrl(page);
  runSearch();
});


  if (els.btnReset) els.btnReset.addEventListener("click", () => {
    if (els.q) els.q.value = "";
    if (els.num) els.num.value = "";
    if (els.dateFrom) els.dateFrom.value = "";
    if (els.dateTo) els.dateTo.value = "";
    if (els.pageSize) els.pageSize.value = "25";
    page = 1;
    setScope("all");
  });

 if (els.prev){
  els.prev.addEventListener("click", () => {
    if (page <= 1) return;
    page -= 1;
    setPageToUrl(page);  
    runSearch();
  });
}

if (els.next){
  els.next.addEventListener("click", () => {
    page += 1;
    setPageToUrl(page);  
    runSearch();
  });
}

if (els.pages){
  els.pages.addEventListener("click", (e) => {
    const btn = e.target.closest("[data-page]");
    if (!btn) return;

    const p = parseInt(btn.dataset.page, 10);
    if (!Number.isFinite(p) || p <= 0 || p === page) return;

    page = p;
    setPageToUrl(page);
    runSearch();
  });
}

 if (els.pageSize) els.pageSize.addEventListener("change", () => {
  page = 1;
  setPageToUrl(page);
  runSearch();
});


// Enter to search
[els.q, els.num, els.dateFrom, els.dateTo].forEach(inp => {
  if (!inp) return;
  inp.addEventListener("keydown", (e) => {
    if (e.key === "Enter"){
      e.preventDefault();
      page = 1;
      setPageToUrl(page);
      runSearch();
    }
  });
});

  // Init
  buildTypeOptions();
  setStatus("Готово");
  setScope("all");
})();
</script>


]]></description>
      <pubDate>Thu, 29 Jan 2026 14:32:12 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/poshuk-normatyvnykh-aktiv</guid>
    </item>
    <item>
      <title>тестова сторінка моніторингу</title>
      <link>https://test2.vmr.gov.ua/test-3</link>
      <description><![CDATA[<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Моніторинг якості повітря Вінниці</title>

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
  	<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    
    
  <style>
        :root {
            --uaqi-a: #4ade80; /* Зелений - Дуже добра якість */
            --uaqi-b: #a3e635; /* Світло-зелений - Добра якість */
            --uaqi-c: #fde047; /* Жовтий - Помірна якість */
            --uaqi-d: #f97316; /* Оранжевий - Незадовільна для чутливих */
            --uaqi-e: #ef4444; /* Червоний - Шкідлива якість */
            --uaqi-f: #8b5cf6; /* Фіолетовий - Дуже шкідлива якість */
            --primary: #3b82f6;
            --secondary: #64748b;
            --light: #f8fafc;
            --dark: #1e293b;
            --text-high: #1e293b;
            --text-medium: #475569;
            --text-low: #94a3b8;
        }
   
      a {
  		text-decoration: none; /* прибирає підкреслення */
  		color: inherit;        /* успадковує колір від батьківського елемента */
		}
      
/* прибираємо фон з усього хедера */
.dashboard-header {
  background: transparent;
  padding: 1rem 0;
  color: white; /* колір тексту можна лишити, якщо потрібен */
}

/* внутрішній "банер" рівно по ширині .container */
.header-banner {
  background: linear-gradient(135deg, #89fabe 0%, #3b82f6 65%);
  border-radius: 16px;
  box-shadow: 0 4px 20px rgba(0,0,0,.15);
  padding: 1rem;
  color: #fff;
}

        
        .card {
            border: none;
            border-radius: 16px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
            transition: all 0.3s ease;
            margin-bottom: 1.5rem;
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: none;
            border: 1px solid rgba(0, 0, 0, 0.05);
        }
        
        .card:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
        }
        
        .station-card {
            cursor: pointer;
            background: white;
            transition: all 0.3s ease;
            height: 100%;
        }
        
        .station-card:hover {
            border-color: var(--primary);
            transform: translateY(-3px);
        }
        
        .uaqi-indicator {
            width: 24px;
            height: 24px;
            border-radius: 50%;
            display: inline-block;
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
        }
        
        .map-container {
            height: 500px;
            border-radius: 16px;
            overflow: hidden;
            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
            border: 1px solid rgba(0, 0, 0, 0.1);
        }
        
        #map {
            height: 100%;
            width: 100%;
            border-radius: 16px;
        }
        
        .stat-card {
            text-align: center;
            padding: 1.5rem;
            background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
        }
        
        .stat-value {
            font-size: 1.8rem;
            font-weight: 700;
            margin: 0.5rem 0;
            color: var(--primary);
        }
        
        .stat-label {
            color: var(--text-low);
            font-size: 0.85rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }
        
        .loading {
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 400px;
            background: rgba(255, 255, 255, 0.8);
            border-radius: 16px;
        }
        
        .spinner {
            width: 3rem;
            height: 3rem;
        }
        
        .modal-content {
            border-radius: 20px;
            border: none;
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
        }
        
        .sensor-item {
            padding: 0.75rem;
            border-radius: 12px;
            margin-bottom: 0.75rem;
            background: #f8fafc;
            border-left: 3px solid #e2e8f0;
        }
        
        .leaflet-popup-content {
            margin: 10px;
            min-width: 250px;
        }
        
        .popup-title {
            font-weight: 700;
            margin-bottom: 8px;
            color: var(--dark);
            font-size: 1.1rem;
        }
        
        .popup-uaqi {
            display: inline-block;
            padding: 4px 10px;
            border-radius: 15px;
            font-weight: 600;
            font-size: 0.85rem;
            color: white;
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
        }
        
        .advice-card {
            background: linear-gradient(135deg, #dbeafe 0%, #d1fae5 100%);
            border: none;
            position: relative;
            overflow: hidden;
        }
        
        .advice-card::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 3px;
            background: linear-gradient(90deg, var(--primary) 0%, var(--uaqi-b) 100%);
        }
        
        .error-message {
            background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
            border: 1px solid #fecaca;
            border-radius: 16px;
            padding: 2rem;
            margin: 1rem 0;
            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
            border-left: 4px solid var(--uaqi-e);
        }
        
        .retry-btn {
            background: linear-gradient(135deg, var(--primary) 0%, #2563eb 100%);
            border: none;
            padding: 0.75rem 1.5rem;
            border-radius: 12px;
            color: white;
            cursor: pointer;
            transition: all 0.3s;
            font-weight: 600;
            box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
        }
        
        .retry-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 16px rgba(59, 130, 246, 0.4);
        }
        
        .section-title {
            font-weight: 700;
            color: var(--dark);
            margin-bottom: 1.5rem;
            position: relative;
            padding-bottom: 0.5rem;
        }
        
        .section-title::after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 0;
            width: 50px;
            height: 3px;
            background: linear-gradient(90deg, var(--primary) 0%, var(--uaqi-b) 100%);
            border-radius: 2px;
        }
        
        .refresh-indicator {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            background: rgba(255, 255, 255, 0.2);
            padding: 0.5rem 1rem;
            border-radius: 20px;
            font-size: 0.85rem;
        }
        
        .uaqi-level-a { background: linear-gradient(135deg, var(--uaqi-a) 0%, #22c55e 100%); }
        .uaqi-level-b { background: linear-gradient(135deg, var(--uaqi-b) 0%, #84cc16 100%); }
        .uaqi-level-c { background: linear-gradient(135deg, var(--uaqi-c) 0%, #eab308 100%); }
        .uaqi-level-d { background: linear-gradient(135deg, var(--uaqi-d) 0%, #ea580c 100%); }
        .uaqi-level-e { background: linear-gradient(135deg, var(--uaqi-e) 0%, #dc2626 100%); }
        .uaqi-level-f { background: linear-gradient(135deg, var(--uaqi-f) 0%, #7c3aed 100%); }
    
    	/* Світло-сірий бейдж (для попапу) */
.uaqi-level-stale {
  background: linear-gradient(135deg, #D1D5DB 0%, #9CA3AF 100%);
  color: #111827;
}

/* Легша тінь лише для застарілих маркерів */
.leaflet-marker-icon.stale {
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}

        
        .leaflet-marker-icon {
            background: white;
            border: 2px solid;
            border-radius: 50%;
            width: 20px;
            height: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
        }
        
        .modal-header {
            border-bottom: 1px solid rgba(0, 0, 0, 0.1);
            padding: 1.5rem;
        }
        
        .modal-body {
            padding: 1.5rem;
        }
        
        .btn-close {
            background: transparent !important;
            border: none !important;
            opacity: 0.7;
        }
        
        .btn-close:hover {
            opacity: 1;
        }
        
        .air-quality-text {
            color: var(--text-high);
            font-weight: 600;
        }
        
        /* кращий контраст для дрібного тексту часу оновлення */
        .update-time,
        .station-update-time,
        #update-time {
            color: #475569;            /* = var(--text-medium), має кращий контраст */
            font-size: 0.875rem;       /* трохи більший розмір допомагає доступності */
            font-weight: 500;          /* робить читабельнішим */
        }

        /* про всяк випадок: перекрити можливу прозорість */
        #update-time { opacity: 1 !important; }

        /* Доступність - забезпечення контрасту */
        .text-high-contrast {
            color: var(--text-high);
        }
        
        .text-medium-contrast {
            color: var(--text-medium);
        }
        
        .text-low-contrast {
            color: var(--text-low);
        }
        
        .uaqi-category {
            padding: 1rem;
            border-radius: 12px;
            margin-bottom: 1rem;
            background: #f8fafc;
            border-left: 4px solid;
        }
        
        .category-a { border-left-color: var(--uaqi-a); }
        .category-b { border-left-color: var(--uaqi-b); }
        .category-c { border-left-color: var(--uaqi-c); }
        .category-d { border-left-color: var(--uaqi-d); }
        .category-e { border-left-color: var(--uaqi-e); }
        .category-f { border-left-color: var(--uaqi-f); }
        
        /* Адаптивний дизайн для header */
        .header-content {
            display: flex;
            flex-direction: column;
            gap: 1rem;
            max-width: var(--bs-container-lg);
            margin: 0 auto;
            padding: 0 1rem;
            flex-wrap: wrap;  
        }
        
        .header-left h1 {
            font-size: 1.5rem;
            margin-bottom: 0;
            text-align: center;
        }
        
        .header-right {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 0.5rem;
        }
        
        .uaqi-info-container {
            display: flex;
            align-items: center;
            gap: 0.75rem;
        }
        
        .uaqi-text-container {
            display: flex;
            flex-direction: column;
            text-align: right;
        }
        
        .uaqi-label-main {
            font-size: 0.9rem;
            opacity: 0.9;
            line-height: 1.2;
        }
        
		.uaqi-label-sub { 
          font-size: 0.9rem; 
          opacity: 0.9; 
          line-height: 1.2; 
      }

        
        .uaqi-value-container {
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }
        
        .uaqi-value {
            font-size: 1.6rem;
            font-weight: bold;
        }
        
        .update-info-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 0.25rem;
        }
        
        .update-info {
            font-size: 0.85rem;
            opacity: 0.9;
            text-align: center;
        }
        
        .refresh-info {
            display: flex;
            align-items: center;
            gap: 0.5rem;
            font-size: 0.8rem;
            opacity: 0.8;
        }
        
        /* Для планшетів і більших екранів */
        @media (min-width: 768px) {
            .header-content {
                flex-direction: row;
                justify-content: space-between;
                align-items: center;
            }
            
            .header-left h1 {
                text-align: left;
                font-size: 1.8rem;
            }
            
            .header-right {
                align-items: flex-end;
            }
            
            .uaqi-info-container {
                gap: 1rem;
            }
            
            .uaqi-text-container {
                text-align: right;
            }
            
            .update-info-container {
                align-items: flex-end;
            }
            
            .update-info {
                text-align: right;
            }
            
            .refresh-info {
                justify-content: flex-end;
            }
        }
      
      
      /* підсвітка правих плиток якості повітря за порогами */
.tile-a { border-left: 4px solid var(--uaqi-a); }
.tile-b { border-left: 4px solid var(--uaqi-b); }
.tile-c { border-left: 4px solid var(--uaqi-c); }
.tile-d { border-left: 4px solid var(--uaqi-d); }
.tile-e { border-left: 4px solid var(--uaqi-e); }
      
/* метео-плитки (без порогів) */
.sensor-item.meteo { border-left: 4px solid #60a5fa; }

      
    </style>
</head>


<body>
    <!-- Header -->
<header class="dashboard-header">
  <div class="container">
    <div class="header-banner">
      <div class="header-content">
        <div class="header-left">
          <h1>Інтерактивний дашборд стану атмосферного повітря</h1>
        </div>
        <div class="header-right">
          <div class="uaqi-info-container">
            <div class="uaqi-text-container">
              <span class="uaqi-label-main">Загальний</span>
              <span class="uaqi-label-sub">UAQI</span>
            </div>
            <div class="uaqi-value-container">
              <div id="overall-uaqi" class="uaqi-value">--</div>
              <div id="overall-uaqi-indicator" class="uaqi-indicator uaqi-level-a"></div>
            </div>
          </div>
          <div class="update-info-container">
            <div id="update-time" class="update-info"></div>
            <div class="refresh-info">
              <i class="fas fa-sync-alt"></i>
              <span>Оновлення кожні 5 хв</span>
            </div>
          </div>
        </div>
      </div> <!-- /.header-content -->
    </div>   <!-- /.header-banner -->
  </div>     <!-- /.container -->
</header>


    <!-- Main Content -->
    <main class="container py-5">
        <!-- Stats Overview -->
<div class="row mb-5">
  <div class="col-12">
    <h2 class="section-title">Загальна статистика</h2>
  </div>

  <div class="col-md-3">
    <div class="card stat-card h-100">
      <div class="stat-label">Температура</div>
      <div id="avg-temp" class="stat-value">--</div>
    </div>
  </div>

  <div class="col-md-3">
    <div class="card stat-card h-100">
      <div class="stat-label">Вологість</div>
      <div id="avg-humidity" class="stat-value">--</div>
    </div>
  </div>

  <div class="col-md-3">
    <div class="card stat-card h-100">
      <div class="stat-label">Атмосферний тиск</div>
      <div id="avg-pressure" class="stat-value">--</div>
    </div>
  </div>

  <div class="col-md-3">
    <div class="card stat-card h-100">
      <div class="stat-label">Радіаційний фон</div>
      <div id="avg-radiation" class="stat-value">--</div>
    </div>
  </div>
</div>


        <!-- Error Message -->
        <div id="error-container" class="d-none">
            <div class="error-message">
                <div class="d-flex align-items-center mb-3">
                    <i class="fas fa-exclamation-triangle fa-2x me-3"></i>
                    <div>
                        <h4 class="mb-1">⚠️ Помилка завантаження даних</h4>
                        <p class="mb-0">Не вдалося отримати дані з API. Можливо, сервер тимчасово недоступний.</p>
                    </div>
                </div>
                <button class="retry-btn" onclick="fetchAllStations()">
                    <i class="fas fa-redo me-2"></i>Спробувати знову
                </button>
            </div>
        </div>

        <!-- Map and Stations -->
        <div class="row mb-5">
            <div class="col-12">
                <h2 class="section-title">Карта станцій моніторингу</h2>
                <div class="map-container">
                    <div id="map"></div>
                </div>
            </div>
        </div>

        <!-- Stations Grid -->
        <div class="row">
            <div class="col-12">
                <h2 class="section-title">Станції моніторингу</h2>
                <div id="stations-container" class="row station-grid">
                    <div class="col-12 text-center py-5">
                        <div class="loading">
                            <div class="text-center">
                                <div class="spinner-border text-primary mb-3" role="status">
                                    <span class="visually-hidden">Завантаження...</span>
                                </div>
                                <p class="text-muted">Отримання даних зі станцій...</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

    
<!-- UAQI: що це і як розраховується -->
<div class="row mt-5">
  <div class="col-12">
    <div class="card uaqi-info-card">
      <div class="card-body">
        <h3 class="card-title mb-2 text-high-contrast">Що таке UAQI?</h3>
        <p class="mb-3 text-medium-contrast">
          <strong>UAQI (Ukrainian Air Quality Index)</strong> — національний індекс якості повітря, який показує,
          наскільки чистим або забрудненим є повітря у певний момент часу. Його розраховують автоматичні станції
          моніторингу на основі концентрацій шкідливих речовин у повітрі. Для кожного з них визначається частковий
          індекс, а <strong>UAQI приймає найвище (найгірше) значення</strong>, що відображає компонент із найбільшим
          впливом на здоров’я. Методика узгоджена з рекомендаціями <strong>ВООЗ</strong> і враховує кліматичні умови України.
        </p>
      </div>
    </div>
  </div>
</div>
      
      
<!-- Пояснення показників (ЗАВЖДИ ВИДНО, компактні плитки, єдина підсвітка) -->
<div class="row mt-4">
  <div class="col-12">
    <div class="card uaqi-info-card">
      <div class="card-body">
        <h3 class="card-title mb-3 text-high-contrast">Що вимірюють показники</h3>

        <div class="row g-2">
          <div class="col-12 col-md-6 col-lg-4">
            <div class="uaqi-chip">
              <div class="fw-semibold">PM₁ — ультрадрібний пил (≤ 1&nbsp;мкм)</div>
              <div class="small text-medium-contrast">Утворюються при згоранні палива, димі, вихлопах і роботі котелень.
					Потрапляють глибоко в легені та можуть переходити в кров, переносячи токсини. Найвищі рівні — узимку та за безвітряної погоди.</div>
            </div>
          </div>

          <div class="col-12 col-md-6 col-lg-4">
            <div class="uaqi-chip">
              <div class="fw-semibold">PM₂.₅ — дуже дрібний пил (≤ 2,5&nbsp;мкм)</div>
              <div class="small text-medium-contrast">Утворюється з диму, вихлопів транспорту, спалювання листя та твердого палива.
					Осідає в дихальних шляхах і легенях, подразнює слизові. Підвищується взимку, у туманну й безвітряну погоду.</div>
            </div>
          </div>

          <div class="col-12 col-md-6 col-lg-4">
            <div class="uaqi-chip">
              <div class="fw-semibold">PM₁₀ — більші частинки пилу (≤ 10&nbsp;мкм)</div>
              <div class="small text-medium-contrast">Утворюється через дорожній, ґрунтовий або будівельний пил. Підвищення значень спостерігається під час безвітря, туманів і 				опалювального сезону.</div>
            </div>
          </div>

          <div class="col-12 col-md-6 col-lg-4">
            <div class="uaqi-chip">
              <div class="fw-semibold">NO₂ — діоксид азоту</div>
              <div class="small text-medium-contrast">Основне джерело — автотранспорт і спалювання газу. Підвищується поблизу жвавих магістралей, у холодну пору року, коли 						збільшується використання опалення.</div>
            </div>
          </div>

          <div class="col-12 col-md-6 col-lg-4">
            <div class="uaqi-chip">
              <div class="fw-semibold">SO₂ — діоксид сірки</div>
              <div class="small text-medium-contrast">Потрапляє у повітря при спалюванні вугілля, мазуту, нафтопродуктів. Високі рівні можуть бути поблизу котелень або 							промислових підприємств.</div>
            </div>
          </div>

          <div class="col-12 col-md-6 col-lg-4">
            <div class="uaqi-chip">
              <div class="fw-semibold">CO — чадний газ</div>
              <div class="small text-medium-contrast">З’являється при неповному згоранні палива: робота двигунів, печей, генераторів.</div>
            </div>
          </div>

          <div class="col-12 col-md-6 col-lg-4">
            <div class="uaqi-chip">
              <div class="fw-semibold">CO₂ — вуглекислий газ</div>
              <div class="small text-medium-contrast">Природний компонент атмосфери, але локальне підвищення може свідчити про погану вентиляцію або значну кількість транспорту.						</div>
            </div>
          </div>

          <div class="col-12 col-md-6 col-lg-4">
            <div class="uaqi-chip">
              <div class="fw-semibold">NH₃ — аміак</div>
              <div class="small text-medium-contrast">Характерний для сільськогосподарських регіонів, тваринницьких комплексів, добрив і каналізаційних викидів.</div>
            </div>
          </div>

          <div class="col-12 col-md-6 col-lg-4">
            <div class="uaqi-chip">
              <div class="fw-semibold">O₃ — озон</div>
              <div class="small text-medium-contrast">Утворюється в сонячну погоду внаслідок реакцій вихлопних газів із ультрафіолетом.</div>
            </div>
          </div>

      </div>
    </div>
  </div>
</div>

     
        <!-- Advice Section -->
        <div class="row mt-5">
            <div class="col-12">    
                <div class="card advice-card">
                    <div class="card-body">
                        <h3 class="card-title mb-4">Опис категорій якості повітря UAQI</h3>
                        <div id="uaqi-explanation">
                            <div class="uaqi-category category-a">
                                <div class="d-flex align-items-center">
                                    <div class="uaqi-indicator uaqi-level-a me-3" style="width: 20px; height: 20px;"></div>
                                    <div>
                                        <div class="fw-bold">Категорія A - Дуже добра якість</div>
                                        <div class="small text-muted">Безпечне повітря для всіх</div>
                                    </div>
                                </div>
                            </div>
                            <div class="uaqi-category category-b">
                                <div class="d-flex align-items-center">
                                    <div class="uaqi-indicator uaqi-level-b me-3" style="width: 20px; height: 20px;"></div>
                                    <div>
                                        <div class="fw-bold">Категорія B - Добра якість</div>
                                        <div class="small text-muted">Незначний вплив, без обмежень</div>
                                    </div>
                                </div>
                            </div>
                            <div class="uaqi-category category-c">
                                <div class="d-flex align-items-center">
                                    <div class="uaqi-indicator uaqi-level-c me-3" style="width: 20px; height: 20px;"></div>
                                    <div>
                                        <div class="fw-bold">Категорія C - Помірна якість</div>
                                        <div class="small text-muted">Може впливати на чутливі групи (діти, літні, хворі)</div>
                                    </div>
                                </div>
                            </div>
                            <div class="uaqi-category category-d">
                                <div class="d-flex align-items-center">
                                    <div class="uaqi-indicator uaqi-level-d me-3" style="width: 20px; height: 20px;"></div>
                                    <div>
                                        <div class="fw-bold">Категорія D - Незадовільна для чутливих</div>
                                        <div class="small text-muted">Ризик для чутливих груп, можуть з'являтися симптоми</div>
                                    </div>
                                </div>
                            </div>
                            <div class="uaqi-category category-e">
                                <div class="d-flex align-items-center">
                                    <div class="uaqi-indicator uaqi-level-e me-3" style="width: 20px; height: 20px;"></div>
                                    <div>
                                        <div class="fw-bold">Категорія E - Шкідлива якість</div>
                                        <div class="small text-muted">Небезпечно для здорових людей, особливо для чутливих</div>
                                    </div>
                                </div>
                            </div>
                            <div class="uaqi-category category-f">
                                <div class="d-flex align-items-center">
                                    <div class="uaqi-indicator uaqi-level-f me-3" style="width: 20px; height: 20px;"></div>
                                    <div>
                                        <div class="fw-bold">Категорія F - Дуже шкідлива якість</div>
                                        <div class="small text-muted">Значна небезпека для всіх</div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
      </div>
    </main>
  
  
  
  

    <!-- Station Detail Modal -->
<!-- Station Detail Modal -->
<div class="modal fade" id="stationModal" tabindex="-1" aria-labelledby="stationModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-xl">
    <div class="modal-content">
      <div class="modal-header">
        <h3 class="modal-title" id="station-modal-title">Деталі станції</h3>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>

      <div class="modal-body">
        <div class="row g-4 align-items-start">
          <!-- ЛІВОРУЧ: UAQI + Метео -->
          <div class="col-md-6 order-md-1">
            <!-- UAQI -->
            <div class="card mb-4">
              <div class="card-body text-center">
                <h4 class="card-title mb-3">
                  <i class="fas fa-gauge-high me-2"></i>Якість повітря (UAQI)
                </h4>
                <div class="my-3">
                  <div id="modal-uaqi-indicator" class="uaqi-indicator mx-auto mb-3 uaqi-level-a" style="width:40px;height:40px;"></div>
                  <h3 id="modal-uaqi-label" class="mb-1">--</h3>
                  <p id="modal-uaqi-description" class="text-muted mb-0">--</p>
                </div>
              </div>
            </div>

            <!-- Метеопоказники -->
            <div class="card">
              <div class="card-body">
                <h4 class="card-title mb-3">
                  <i class="fas fa-temperature-high me-2"></i>Метеопоказники
                </h4>
                <div id="station-meteo"></div>
              </div>
            </div>
          </div>

          <!-- ПРАВОРУЧ: Показники якості з порогами -->
          <div class="col-md-6 order-md-2">
            <div class="card">
              <div class="card-body">
                <h4 class="card-title mb-3">
                  <i class="fas fa-leaf me-2"></i>Показники якості
                </h4>
                <div id="station-air"></div>
              </div>
            </div>
          </div>
        </div>

        <div class="text-center mt-4 update-time">
          <small>Останнє оновлення: <span id="modal-update-time"></span></small>
        </div>
      </div>

<div class="modal-footer border-0 justify-content-center">
  <button type="button" class="btn btn-secondary" id="close-modal-btn" data-bs-dismiss="modal">
    <i class="fas fa-times me-2"></i>Закрити
  </button>
</div>

    </div>
  </div>
</div>


    <!-- Footer -->
    <footer class="bg-white border-top py-4 mt-5">
        <div class="container">
            <div class="text-center text-muted">
                <p class="fs-5 mb-1">Сервіс працює в тестовому режимі</p>
                <p class="fs-5 mb-0">Дані надано екологічною мережею 
  			<a href="https://eco-city.org.ua/" target="_blank" rel="noopener noreferrer" class="text-muted fw-semibold">EcoCity</a>
				</p>
            </div>
        </div>
    </footer>

    <!-- Scripts -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
    <script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
    <script>
        // Глобальні змінні
        let stations = [];
        let map;
        let markers = {};
        let currentModal = null;
      
      // --- "застарілі дані" ---
const STALE_THRESHOLD_HOURS = 24;

function isStale(updatedAt) {
  if (!updatedAt) return true;
  const t = Date.parse(updatedAt);
  if (Number.isNaN(t)) return true;
  return (Date.now() - t) > STALE_THRESHOLD_HOURS * 3600 * 1000;
}



        // Ініціалізація карти
        function initMap() {
            map = L.map('map').setView([49.2333, 28.4667], 13);
            
            L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
    attribution: '&copy; OpenStreetMap & CartoDB'
}).addTo(map);
        }

        // Отримання даних з API через проксі
        async function fetchStationData(id) {
            try {
                // Використовуємо другий проксі сервіс
                const proxyUrl = 'https://api.codetabs.com/v1/proxy?quest=';
                const targetUrl = `https://reborn.eco-city.org.ua/api/v1/station?id=${id}`;
                
                const response = await fetch(proxyUrl + encodeURIComponent(targetUrl), {
                    method: 'GET',
                    headers: {
                        'Accept': 'application/json'
                    }
                });
                
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                
                const data = await response.json();
                return data;
            } catch (error) {
                console.error(`Error fetching data for station ${id}:`, error);
                return null;
            }
        }

        // Отримання всіх станцій
        async function fetchAllStations() {
            // Приховуємо повідомлення про помилку
            document.getElementById('error-container').classList.add('d-none');
            
            // Показуємо завантаження
            document.getElementById('stations-container').innerHTML = `
                <div class="col-12 text-center py-5">
                    <div class="loading">
                        <div class="text-center">
                            <div class="spinner-border text-primary mb-3" role="status">
                                <span class="visually-hidden">Завантаження...</span>
                            </div>
                            <p class="text-muted">Отримання даних зі станцій...</p>
                        </div>
                    </div>
                </div>
            `;
            
            try {
                const stationIds = [1918, 1315, 1909, 790, 774, 1769, 1919, 1612, 767, 1872, 1876];
                const promises = stationIds.map(id => fetchStationData(id));
                const results = await Promise.allSettled(promises);
                
                // Фільтруємо успішні результати
                stations = results
                    .filter(result => result.status === 'fulfilled' && result.value !== null)
                    .map(result => result.value);
                
                renderStations();
                updateStats();
                updateMap();
            } catch (error) {
                console.error('Error fetching stations:', error);
                document.getElementById('error-container').classList.remove('d-none');
                document.getElementById('stations-container').innerHTML = `
                    <div class="col-12 text-center py-5">
                        <div class="alert alert-warning">
                            <div class="d-flex align-items-center mb-3">
                                <i class="fas fa-exclamation-triangle fa-2x me-3"></i>
                                <div>
                                    <h4 class="mb-1">⚠️ Не вдалося завантажити дані</h4>
                                    <p class="mb-0">Спробуйте оновити сторінку пізніше</p>
                                </div>
                            </div>
                            <button class="retry-btn" onclick="fetchAllStations()">
                                <i class="fas fa-redo me-2"></i>Оновити дані
                            </button>
                        </div>
                    </div>
                `;
            }
        }

        // Отримання кольору UAQI
        function getUAQIColor(category) {
            const colors = {
                'A': 'var(--uaqi-a)',
                'B': 'var(--uaqi-b)',
                'C': 'var(--uaqi-c)',
                'D': 'var(--uaqi-d)',
                'E': 'var(--uaqi-e)',
                'F': 'var(--uaqi-f)'
            };
            return colors[category] || 'var(--uaqi-a)';
        }

        // Отримання мітки UAQI
        function getUAQILabel(category) {
            const labels = {
                'A': 'Дуже добра якість',
                'B': 'Добра якість',
                'C': 'Помірна якість',
                'D': 'Незадовільна для чутливих',
                'E': 'Шкідлива якість',
                'F': 'Дуже шкідлива якість'
            };
            return labels[category] || 'Невідомо';
        }

        // Отримання опису категорії
        function getCategoryDescription(category) {
            const descriptions = {
                'A': 'Безпечне повітря для всіх',
                'B': 'Незначний вплив, без обмежень',
                'C': 'Може впливати на чутливі групи (діти, літні, хворі)',
                'D': 'Ризик для чутливих груп, можуть з’являтися симптоми',
                'E': 'Небезпечно для здорових людей, особливо для чутливих',
                'F': 'Значна небезпека для всіх'
            };
            return descriptions[category] || 'Немає інформації';
        }

        // Форматування значення сенсора
        function formatSensorValue(value, unit) {
            if (unit === '°C') return `${value.toFixed(1)}°C`;
            if (unit === '%') return `${value.toFixed(0)}%`;
            if (unit === 'mm') return `${value.toFixed(0)} мм.рт.ст.`;
            if (unit === 'µR/h') return `${value.toFixed(1)} мкР/год`;
            return `${value.toFixed(2)} ${unit}`;
        }

        // Визначення головної категорії за значенням UAQI
function getMainCategoryFromUAQI(uaqi) {
  const categories = ['A', 'B', 'C', 'D', 'E', 'F'];
  const main = Number(uaqi?.main);
  if (!isFinite(main) || main < 1 || main > 6) return 'A';
  return categories[main - 1];
}


        // Рендер карток станцій
function renderStations() {
  const container = document.getElementById('stations-container');

  if (stations.length === 0) {
    container.innerHTML = `<div class="col-12 text-center py-5">
      <div class="alert alert-info">
        <i class="fas fa-info-circle me-2"></i> Дані недоступні
      </div>
    </div>`;
    return;
  }

  let html = '';
  stations.forEach(station => {
    const pm25 = station.current_values.find(v => v.type === 'PM2.5');
    const pm10 = station.current_values.find(v => v.type === 'PM10');
    const temperature = station.current_values.find(v => v.type === 'Temperature');
    const humidity = station.current_values.find(v => v.type === 'Humidity');

    let sensorBlocks = '';

    if (pm25 || pm10) {
      if (pm25) {
        sensorBlocks += `
          <div class="col-6">
            <div class="bg-light rounded p-2 text-center">
              <div class="small text-muted">PM2.5</div>
              <div class="fw-bold">${pm25.value.toFixed(1)}</div>
              <div class="small text-muted">мкг/м³</div>
            </div>
          </div>`;
      }
      if (pm10) {
        sensorBlocks += `
          <div class="col-6">
            <div class="bg-light rounded p-2 text-center">
              <div class="small text-muted">PM10</div>
              <div class="fw-bold">${pm10.value.toFixed(1)}</div>
              <div class="small text-muted">мкг/м³</div>
            </div>
          </div>`;
      }
    } else {
      const fallback = station.current_values
        .filter(v => !['Temperature', 'Humidity'].includes(v.type))
        .slice(0, 2);

      fallback.forEach(sensor => {
        sensorBlocks += `
          <div class="col-6">
            <div class="bg-light rounded p-2 text-center">
              <div class="small text-muted">${sensor.local_type || sensor.type}</div>
              <div class="fw-bold">${sensor.value.toFixed(1)}</div>
              <div class="small text-muted">${sensor.local_unit || sensor.unit}</div>
            </div>
          </div>`;
      });
    }

    const mainCategory = getMainCategoryFromUAQI(station.uaqi);
    const stale = isStale(station.last_online); // нове: перевіряємо чи застаріла

    // колір індикатора
    const indicatorClass = stale
      ? 'uaqi-level-stale'
      : `uaqi-level-${mainCategory.toLowerCase()}`;

    // текст UAQI або "Дані застарілі"
    const airQualityText = stale
      ? 'Дані застарілі'
      : getUAQILabel(mainCategory);

    html += `
      <div class="col-lg-4 col-md-6 col-12">
        <div class="card station-card h-100" onclick="showStationDetails(${station.id})">
          <div class="card-body">
            <div class="d-flex justify-content-between align-items-start mb-3">
              <h5 class="card-title mb-0">${station.name}</h5>
              <div class="uaqi-indicator ${indicatorClass}"></div>
            </div>
            <p class="text-muted small mb-3">
              <i class="fas fa-map-marker-alt me-1"></i> ${station.address}
            </p>
            <div class="row mb-3 g-2">
              ${sensorBlocks}
            </div>
            <div class="d-flex justify-content-between align-items-center">
              <div>
                ${temperature ? `<div class="fw-bold">${temperature.value.toFixed(1)}°C</div>` : ''}
                ${humidity ? `<div class="small text-muted">${humidity.value.toFixed(0)}%</div>` : ''}
              </div>
              <div class="text-end">
                <div class="small text-muted">Якість повітря</div>
                <div class="air-quality-text">${airQualityText}</div>
              </div>
            </div>
          </div>
          <div class="card-footer bg-transparent border-0">
            <small class="update-time">
              <i class="fas fa-clock me-1"></i>
              Оновлено:
              ${new Date(station.last_online).toLocaleDateString('uk-UA', {
                day: '2-digit', month: '2-digit', year: 'numeric'
              })},
              ${new Date(station.last_online).toLocaleTimeString('uk-UA', {
                hour: '2-digit', minute: '2-digit'
              })}
            </small>
          </div>
        </div>
      </div>`;
  });

  container.innerHTML = html;
}


        // Оновлення статистики
        function updateStats() {
  // беремо тільки свіжі станції
  const freshStations = stations.filter(s => !isStale(s.last_online));

  // якщо всі станції застарілі — покажемо дефіси і сірий індикатор у хедері
  if (freshStations.length === 0) {
    document.getElementById('avg-temp').textContent = '--';
    document.getElementById('avg-humidity').textContent = '--';
    document.getElementById('avg-pressure').textContent = '--';
    document.getElementById('avg-radiation').textContent = '--';

    // Загальний UAQI: позначимо як застаріло
    const overallValEl = document.getElementById('overall-uaqi');
    const overallIndEl = document.getElementById('overall-uaqi-indicator');
    if (overallValEl) overallValEl.textContent = '—';
    if (overallIndEl) overallIndEl.className = 'uaqi-indicator uaqi-level-stale';

    // Час оновлення дашборду (поточний)
    const now = new Date();
    document.getElementById('update-time').textContent =
      `${now.toLocaleDateString('uk-UA')} ${now.toLocaleTimeString('uk-UA', { hour: '2-digit', minute: '2-digit' })}`;
    return;
  }

  // Середня температура
  const tempValues = freshStations
    .map(s => s.current_values.find(v => v.type === 'Temperature'))
    .filter(Boolean)
    .map(v => Number(v.value))
    .filter(Number.isFinite);

  document.getElementById('avg-temp').textContent =
    tempValues.length ? (tempValues.reduce((a,b)=>a+b,0) / tempValues.length).toFixed(1) + ' °C' : '--';

  // Середня вологість
  const humidityValues = freshStations
    .map(s => s.current_values.find(v => v.type === 'Humidity'))
    .filter(Boolean)
    .map(v => Number(v.value))
    .filter(Number.isFinite);

  document.getElementById('avg-humidity').textContent =
    humidityValues.length ? Math.round(humidityValues.reduce((a,b)=>a+b,0) / humidityValues.length) + ' %' : '--';

  // Середній тиск (переводимо в мм рт. ст.)
  const pressureSensors = freshStations
    .map(s => s.current_values.find(v =>
      v?.type?.toLowerCase?.().includes('pressure') ||
      v?.local_type?.toLowerCase?.().includes('тиск')
    ))
    .filter(Boolean);

  if (pressureSensors.length) {
    const mmHgValues = pressureSensors.map(v => {
      const unit = String(v.local_unit || v.unit || '').toLowerCase().trim();
      const val = Number(v.value);
      if (!isFinite(val)) return null;
      if (unit.includes('hpa') || unit.includes('гпа')) return val * 0.75006;
      if (unit === 'pa') return (val / 100) * 0.75006;
      if (unit.includes('мм')) return val;
      if (unit.includes('kpa') || unit.includes('кпа')) return (val * 10) * 0.75006;
      return val; // якщо невідомо — вважаємо вже мм рт. ст.
    }).filter(v => v !== null);

    document.getElementById('avg-pressure').textContent =
      mmHgValues.length ? Math.round(mmHgValues.reduce((a,b)=>a+b,0) / mmHgValues.length) + ' мм рт.ст.' : '--';
  } else {
    document.getElementById('avg-pressure').textContent = '--';
  }

  // Середній радіаційний фон
  const radValues = freshStations
    .map(s => s.current_values.find(v => v.type === 'Radiation'))
    .filter(Boolean)
    .map(v => Number(v.value))
    .filter(Number.isFinite);

  document.getElementById('avg-radiation').textContent =
    radValues.length ? (radValues.reduce((a,b)=>a+b,0) / radValues.length).toFixed(1) + ' мкР/год' : '--';

  // Загальний UAQI (середня категорія серед свіжих)
  const uaqiNums = freshStations
    .map(s => Number(s.uaqi?.main))
    .filter(n => Number.isFinite(n) && n >= 1 && n <= 6);

  const overallValEl = document.getElementById('overall-uaqi');
  const overallIndEl = document.getElementById('overall-uaqi-indicator');

  if (uaqiNums.length) {
    const avgUAQI = Math.round(uaqiNums.reduce((a,b)=>a+b,0) / uaqiNums.length);
    const categories = ['A', 'B', 'C', 'D', 'E', 'F'];
    const mainCategory = categories[avgUAQI - 1] || 'A';
    if (overallValEl) overallValEl.textContent = mainCategory;
    if (overallIndEl) overallIndEl.className = `uaqi-indicator uaqi-level-${mainCategory.toLowerCase()}`;
  } else {
    // якщо свіжі є, але без UAQI — покажемо дефіс і нейтральний індикатор
    if (overallValEl) overallValEl.textContent = '—';
    if (overallIndEl) overallIndEl.className = 'uaqi-indicator uaqi-level-stale';
  }

  // Час оновлення дашборду (поточний)
  const now = new Date();
  document.getElementById('update-time').textContent =
    `${now.toLocaleDateString('uk-UA')} ${now.toLocaleTimeString('uk-UA', { hour: '2-digit', minute: '2-digit' })}`;
}

        // Оновлення карти
// допоміжна функція: додає ARIA/клавіатуру, коли елемент маркера вже в DOM
function attachMarkerA11y(marker, station, mainCategory) {
  const el = marker.getElement();
  if (!el) return; // ще не відрендерився — нічого не робимо

  const accessibleLabel =
    `Станція ${station.name}. Якість повітря: ${getUAQILabel(mainCategory)}. Натисніть, щоб відкрити деталі.`;

  el.setAttribute('role', 'button');
  el.setAttribute('tabindex', '0');
  el.setAttribute('aria-label', accessibleLabel);
  el.setAttribute('title', accessibleLabel);

  // щоб не дублювати слухачі при повторному рендері
  el.onkeydown = null;
  el.onkeydown = (e) => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      showStationDetails(station.id);
    }
  };
}

function updateMap() {
  // прибираємо старі маркери
  Object.values(markers).forEach(marker => map.removeLayer(marker));
  markers = {};

  stations.forEach(station => {
    const mainCategory = getMainCategoryFromUAQI(station.uaqi);
    const stale = isStale(station.last_online);


    // іконка з aria-hidden всередині
const markerIcon = L.divIcon({
  className: 'leaflet-marker-icon',
  html: `<div aria-hidden="true" style="
    background: ${stale ? '#BDBDBD' : getUAQIColor(mainCategory)};
    width: 16px; height: 16px; border-radius: 50%;
    border: ${stale ? '0,5px solid #000000' : 'none'};
    box-shadow: 0 2px 6px rgba(0,0,0,0.25);
  "></div>`,
  iconSize: [20, 20],
  iconAnchor: [10, 10]
});





    const marker = L.marker([station.latitude, station.longitude], { icon: markerIcon })
      .addTo(map)
.bindPopup(`
  <div>
    <div class="popup-title">${station.name}</div>
    <div class="mb-2 text-muted small">${station.address || ''}</div>
    <div class="mb-3">
      <span class="popup-uaqi ${stale ? 'uaqi-level-stale' : `uaqi-level-${mainCategory.toLowerCase()}`}">
        ${stale ? 'Дані застарілі' : `UAQI: ${mainCategory} - ${getUAQILabel(mainCategory)}`}
      </span>
    </div>
    <div class="small text-muted mb-2">
      <i class="fas fa-clock me-1"></i>
      Оновлено:
      ${new Date(station.last_online).toLocaleDateString('uk-UA', {
        day: '2-digit', month: '2-digit', year: 'numeric'
      })},
      ${new Date(station.last_online).toLocaleTimeString('uk-UA', {
        hour: '2-digit', minute: '2-digit'
      })}
    </div>
    <button class="btn btn-sm btn-primary w-100"
            onclick="showStationDetails(${station.id})"
            aria-label="Деталі станції ${station.name}">
      <i class="fas fa-info-circle me-1"></i>Деталі
    </button>
  </div>
`);



    // Коли маркер додано в DOM — додаємо ARIA/клавіатуру
    marker.on('add', () => attachMarkerA11y(marker, station, mainCategory));

    // fallback на випадок, якщо подія проскочила до навішування слухача
    setTimeout(() => attachMarkerA11y(marker, station, mainCategory), 0);

    markers[station.id] = marker;
  });
}


        // Показ деталей станції
// --- Пороги в ЄДИНИХ ОДИНИЦЯХ (bandUnits) ---
// PM1/PM2.5/PM10, NO2, O3, SO2, NH3 — у µg/m³
// CO — у mg/m³ (так зручніше для нормативів)
// CO2 — у ppm
// Radiation — у µSv/h
const SENSOR_BANDS = {
  pm1:       { bands: [10, 20, 30, 50],          unit: 'µg/m³' },  // індикативно, суворіше за PM2.5
  pm25:      { bands: [15, 25, 35, 50],          unit: 'µg/m³' },
  pm10:      { bands: [45, 75, 100, 150],        unit: 'µg/m³' },
  no2:       { bands: [100, 150, 200, 300],      unit: 'µg/m³' },
  o3:        { bands: [100, 120, 160, 200],      unit: 'µg/m³' },
  so2:       { bands: [50, 75, 125, 200],        unit: 'µg/m³' },
  nh3:       { bands: [50, 100, 200, 400],       unit: 'µg/m³' },   // аміак
  co:        { bands: [4, 7, 10, 15],            unit: 'mg/m³' },   // чадний газ
  co2:       { bands: [1000, 1400, 2000, 3000],  unit: 'ppm' },     // вуглекислий газ
  radiation: { bands: [0.3, 0.5, 1.0, 2.0],      unit: 'µSv/h' },    // радіац. фон
  hcho:      { bands: [30, 60, 100, 200],        unit: 'µg/m³' }    // формальдегід
};

// Мапінг назв сенсорів API -> ключі порогів
function normKey(type, localType='') {
  const s = `${(type||'').toLowerCase()} ${(localType||'').toLowerCase()}`;

  if (s.includes('pm1')) return 'pm1';
  if (s.includes('pm2.5') || s.includes('pm2_5') || s.includes('pm25') || s.includes('мікропил pm2.5')) return 'pm25';
  if (s.includes('pm10') || s.includes('мікропил pm10')) return 'pm10';

  if (s.includes('no2') || s.includes('діоксид азоту')) return 'no2';
  if (s.includes('o3')  || s.includes('озон')) return 'o3';
  if (s.includes('so2') || s.includes('діоксид сірки')) return 'so2';
  if (s === 'co' || s.includes('чадний газ')) return 'co';
  if (s.includes('nh3') || s.includes('аміак') || s.includes('амiак')) return 'nh3';
  if (s.includes('co2') || s.includes('вуглекислий газ')) return 'co2';
  if (s.includes('radiation') || s.includes('радіа') || s.includes('радіац')) return 'radiation';
  if (s.includes('hcho') || s.includes('формаль') || s.includes('formaldehyde')) return 'hcho';

  return null; // інші не підсвічуємо порогами
}

// --- конвертація ---
function normUnit(u='') {
  const s = String(u).trim()
    .replaceAll(' ', '')
    .replace('мкг/м³', 'µg/m³')
    .replace('мкР/год', 'µR/h')
    .replace('мкР/г', 'µR/h')
    .replace('мкР/ч', 'µR/h')
    .replace('мкЗв/год', 'µSv/h')
    .replace('мкЗв/г', 'µSv/h')
    .replace('ppm', 'ppm')
    .replace('мг/м³', 'mg/m³')
    .replace('°C', '°C')
    .replace('%', '%');
  return s;
}

function toBandUnits(value, fromUnit, key) {
  const def = SENSOR_BANDS[key];
  if (!def) return Number(value);
  const target = def.unit;
  const from = normUnit(fromUnit);

  let v = Number(value);
  if (!isFinite(v)) return NaN;

  if (from === target) return v;

  // Радіація: µR/h → µSv/h
  if (from === 'µR/h' && target === 'µSv/h') return v * 0.00877;
  if (from === 'µSv/h' && target === 'µR/h') return v / 0.00877;

  // Маса-обʼєм: µg/m³ ↔ mg/m³
  if (from === 'µg/m³' && target === 'mg/m³') return v / 1000;
  if (from === 'mg/m³' && target === 'µg/m³') return v * 1000;
  
  return v;
}


// Категорія A..E за bands
function bandCategory(v, bands) {
  const x = Number(v);
  if (!isFinite(x)) return null;   // <- додано
  if (x < bands[0]) return 'A';
  if (x < bands[1]) return 'B';
  if (x < bands[2]) return 'C';
  if (x < bands[3]) return 'D';
  return 'E';
}

function tileClassByCategory(cat) {
  return cat ? `tile-${cat.toLowerCase()}` : '';
}

// Визначаємо, чи це метео-сенсор (без підсвітки порогами)
function isMeteo(type, localType='') {
  const s = `${(type||'').toLowerCase()} ${(localType||'').toLowerCase()}`;
  return (
    s.includes('temperature') || s.includes('температ') ||
    s.includes('humidity')    || s.includes('волог')   ||
    s.includes('pressure')    || s.includes('тиск')    ||
    s.includes('wind')        || s.includes('вітер')   || s.includes('швидк') ||
    s.includes('rain')        || s.includes('опад')    || s.includes('дощ')
  );
}

// Красиве відображення метео
function prettyMeteoValue(sensor) {
  const unit = sensor?.local_unit || sensor?.unit || '';
  const v = Number(sensor?.value);
  const t = `${sensor?.type || ''} ${sensor?.local_type || ''}`.toLowerCase();

  if (!isFinite(v)) return `-- ${unit}`;

  // температура
  if (unit === '°C' || t.includes('temperature') || t.includes('температ')) {
    return `${v.toFixed(1)}°C`;
  }
  // вологість
  if (unit === '%' || t.includes('humidity') || t.includes('волог')) {
    return `${v.toFixed(0)}%`;
  }
  // тиск
  if (t.includes('pressure') || t.includes('тиск')) {
    return `${v.toFixed(0)} мм.рт.ст.`;
  }

  return `${v.toFixed(1)} ${unit}`;
}

      
      
      
function showStationDetails(stationId) {
  const station = stations.find(s => s.id === stationId);
  if (!station) return;

            
            // Заголовок
  document.getElementById('station-modal-title').textContent = station.name;
            
            // UAQI
            // UAQI (із перевіркою застарілості)
const mainCategory = getMainCategoryFromUAQI(station.uaqi);
const stale = isStale(station.last_online);

const ind  = document.getElementById('modal-uaqi-indicator');
const lbl  = document.getElementById('modal-uaqi-label');
const desc = document.getElementById('modal-uaqi-description');

if (stale) {
  // сірий маркер + текст "Дані застарілі"
  ind.className = 'uaqi-indicator mx-auto mb-3 uaqi-level-stale';
  lbl.textContent = 'Дані застарілі';
  desc.textContent = '';
} else {
  ind.className = `uaqi-indicator mx-auto mb-3 uaqi-level-${mainCategory.toLowerCase()}`;
  lbl.textContent = getUAQILabel(mainCategory);
  desc.textContent = getCategoryDescription(mainCategory);
}

            
            // Показники станції
// Показники станції (ліворуч — метео, праворуч — якість)
let meteoHtml = '';
let airHtml   = '';

station.current_values.forEach(sensor => {
  if (isMeteo(sensor.type, sensor.local_type)) {
    // МЕТЕО (без порогів)
    meteoHtml += `
      <div class="sensor-item meteo">
        <div class="d-flex justify-content-between align-items-center">
          <div class="fw-bold">${sensor.local_type || sensor.type}</div>
          <div class="fw-bold">${prettyMeteoValue(sensor)}</div>
        </div>
      </div>`;
  } else {
    // ЯКІСТЬ ПОВІТРЯ (з порогами + конвертація одиниць)
const key = normKey(sensor.type, sensor.local_type);
const def = key ? SENSOR_BANDS[key] : null;

// конвертуємо значення сенсора у цільові одиниці порогів (def.unit)
const fromUnit = sensor.local_unit || sensor.unit || '';
const vInBandUnits = def ? toBandUnits(sensor.value, fromUnit, key) : NaN;

// категорія за масивом порогів
const cat = def ? bandCategory(vInBandUnits, def.bands) : null;
const cls = tileClassByCategory(cat);


    airHtml += `
      <div class="sensor-item ${cls}">
        <div class="d-flex justify-content-between align-items-center">
          <div class="fw-bold">${sensor.local_type || sensor.type}</div>
          <div class="text-end">
            <div class="fw-bold">${formatSensorValue(sensor.value, sensor.local_unit || sensor.unit || '')}</div>
            ${cat ? `<div class="small text-muted">Рівень: ${tileLevelText(cat)}</div>` : ''}
          </div>
        </div>
      </div>`;
  }
});
  
  function tileLevelText(cat) {
  const m = {
    'A': 'Добра якість',
    'B': 'Прийнятна',
    'C': 'Помірна / незначне перевищення',
    'D': 'Незадовільна',
    'E': 'Шкідлива якість'
  };
  return m[cat] || 'Невідомо';
}


document.getElementById('station-meteo').innerHTML = meteoHtml || `<div class="text-muted">Немає метеоданих</div>`;
document.getElementById('station-air').innerHTML   = airHtml   || `<div class="text-muted">Немає даних якості</div>`;

            
            // Час оновлення
           document.getElementById('modal-update-time').textContent = 
    new Date(station.last_online).toLocaleString('uk-UA');
            
            // Показ модального вікна
  const modalElement = document.getElementById('stationModal');
  currentModal = new bootstrap.Modal(modalElement);
  currentModal.show();
}

// Функція для закриття модального вікна
function closeStationModal() {
    if (currentModal) {
        currentModal.hide();
    }
}

        // Ініціалізація
        document.addEventListener('DOMContentLoaded', function() {
            initMap();
            fetchAllStations();
            
            // Оновлення даних кожні 5 хвилин
            setInterval(fetchAllStations, 300000);
            
            // Додаємо обробник події для кнопки "Закрити"
            document.getElementById('close-modal-btn').addEventListener('click', closeStationModal);
        });
    </script>
  
  
  

 
]]></description>
      <pubDate>Mon, 18 May 2026 11:10:00 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/test-3</guid>
    </item>
    <item>
      <title>ТЕСТ</title>
      <link>https://test2.vmr.gov.ua/test-2</link>
      <description><![CDATA[<p> <img src="/media/001_Порядок Кредіти/photo_5408984952939942965_w.jpg"></p><p><br> <img src="/media/001_Порядок Кредіти/photo_5408984952939942966_w.jpg"><br></p><p><br></p>]]></description>
      <pubDate>Fri, 17 Apr 2026 08:30:38 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/test-2</guid>
    </item>
    <item>
      <title>Подяки громаді</title>
      <link>https://test2.vmr.gov.ua/podiaky-test</link>
      <description><![CDATA[<style>
  .gallery-container {
    max-width: 1600px; /* обмежує ширину галереї */
    margin: 0 auto;
    padding: 20px 0;
  }

  .gallery {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 15px;
    justify-items: center;
    align-items: center;
  }

  .gallery img {
    width: 100%;
    max-width: 300px;
    height: auto;
    cursor: pointer;
    border-radius: 4px;
    box-shadow: 0 2px 6px rgba(0,0,0,0.2);
    transition: transform 0.2s;
  }

  .gallery img:hover {
    transform: scale(1.05);
  }

  .lightbox {
    display: none;
    position: fixed;
    z-index: 1000;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: rgba(0,0,0,0.85);
    justify-content: center;
    align-items: center;
  }

  .lightbox img {
    max-width: 90%;
    max-height: 90%;
    border-radius: 6px;
  }

  .lightbox .nav {
    position: absolute;
    top: 50%;
    font-size: 2rem;
    color: white;
    background: rgba(0,0,0,0.3);
    padding: 10px;
    cursor: pointer;
    user-select: none;
    border-radius: 4px;
    transform: translateY(-50%);
  }

  .lightbox .prev { left: 20px; }
  .lightbox .next { right: 20px; }

  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0,0,0,0);
    border: 0;
  }
</style>

<div class="gallery-container">
  <div class="gallery">


    <img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0011.jpg" alt="Подяка">    
    <img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0001.jpg" alt="Подяка" class="custom" style="grid-column: span 2; max-width: 600px;">
	<img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0002.jpg" alt="Подяка" class="custom" style="grid-column: span 2; max-width: 600px;">

    <img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0007.jpg" alt="Подяка" class="custom" style="grid-column: span 2; max-width: 600px;">     
    <img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0010.jpg" alt="Подяка">
    <img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0006.jpg" alt="Подяка" class="custom" style="grid-column: span 2; max-width: 600px;">
 
    <img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0009.jpg" alt="Подяка">
    <img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0005.jpg" alt="Подяка" class="custom" style="grid-column: span 2; max-width: 600px;">
 	<img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0004.jpg" alt="Подяка" class="custom" style="grid-column: span 2; max-width: 600px;">
   
    <img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0008.jpg" alt="Подяка" class="custom" style="grid-column: span 2; max-width: 600px;">    
	<img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0012.jpg" alt="Подяка">
    <img src="https://test2.vmr.gov.ua/media/%D0%A1%D0%B5%D1%80%D0%B2%D1%96%D1%81%D0%B8/podyaky-gromadi/IMG_0003.jpg" alt="Подяка" class="custom" style="grid-column: span 2; max-width: 600px;">  

    
    
  </div>
</div>

<div class="lightbox" id="lightbox">
  <span class="nav prev">&#10094;</span>
  <img id="lightbox-img" src="" alt="">
  <span class="nav next">&#10095;</span>
</div>

<script>
  const images = document.querySelectorAll('.gallery img');
  const lightbox = document.getElementById('lightbox');
  const lightboxImg = document.getElementById('lightbox-img');
  const prev = lightbox.querySelector('.prev');
  const next = lightbox.querySelector('.next');
  let currentIndex = 0;

  images.forEach((img, index) => {
    img.addEventListener('click', () => openLightbox(index));
  });

  function openLightbox(index) {
    currentIndex = index;
    updateLightbox();
    lightbox.style.display = 'flex';
  }

  function closeLightbox() {
    lightbox.style.display = 'none';
  }

  function updateLightbox() {
    lightboxImg.src = images[currentIndex].src;
    lightboxImg.alt = images[currentIndex].alt;
  }

  function changeSlide(direction) {
    currentIndex = (currentIndex + direction + images.length) % images.length;
    updateLightbox();
  }

  prev.addEventListener('click', (e) => {
    e.stopPropagation();
    changeSlide(-1);
  });

  next.addEventListener('click', (e) => {
    e.stopPropagation();
    changeSlide(1);
  });

  lightbox.addEventListener('click', (e) => {
    if (e.target === lightbox) closeLightbox();
  });

  document.addEventListener('keydown', (e) => {
    if (lightbox.style.display === 'flex') {
      if (e.key === 'ArrowRight') changeSlide(1);
      if (e.key === 'ArrowLeft') changeSlide(-1);
      if (e.key === 'Escape') closeLightbox();
    }
  });
</script>
]]></description>
      <pubDate>Wed, 17 Sep 2025 06:21:18 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/podiaky-test</guid>
    </item>
    <item>
      <title>Подяки Вінницькій громаді</title>
      <link>https://test2.vmr.gov.ua/podyaky-gromadi</link>
      <description><![CDATA[<!DOCTYPE html>
<html lang="uk">
<head>
       <style>
        body 
        .gallery {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
            gap: 20px;
            padding: 0;
            justify-items: center;
        }
        
        .gallery-item {
            position: relative;
            overflow: hidden;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
            background: white;
            transition: transform 0.3s ease;
            cursor: pointer;
            width: 210px;
            height: 297px;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .gallery-item:hover {
            transform: translateY(-5px);
        }
        
        .gallery-item img {
            max-width: 100%;
            max-height: 100%;
            width: auto;
            height: auto;
            object-fit: contain;
            transition: transform 0.3s ease;
        }
        
        .gallery-item:hover img {
            transform: scale(1.05);
        }
        
        .modal {
            display: none;
            position: fixed;
            z-index: 1000;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0,0,0,0.9);
            animation: fadeIn 0.3s;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        
        .modal-content {
            display: block;
            max-width: 90%;
            max-height: 90%;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            animation: zoomIn 0.3s;
            width: auto;
            height: auto;
            object-fit: contain;
        }
        
        @keyframes zoomIn {
            from { transform: translate(-50%, -50%) scale(0.8); opacity: 0; }
            to { transform: translate(-50%, -50%) scale(1); opacity: 1; }
        }
        
        .close {
            position: absolute;
            top: 20px;
            right: 35px;
            color: #fff;
            font-size: 40px;
            font-weight: bold;
            cursor: pointer;
            z-index: 1001;
            transition: color 0.3s;
        }
        
        .close:hover {
            color: #ccc;
        }
        
        .caption {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            color: white;
            font-size: 16px;
            text-align: center;
            width: 80%;
        }
        
        @media (max-width: 768px) {
            .gallery {
                grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
                gap: 15px;
            }
            
            .gallery-item {
                width: 140px;
                height: 198px;
            }
            
            .close {
                font-size: 30px;
                top: 15px;
                right: 20px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Грамоти та подяки</h1>
        <div class="gallery">
            <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/1.jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/1.jpg" alt="Грамота 1">
            </div>
            <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/12312321123%20(4).jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/12312321123%20(4).jpg" alt="Грамота 2">
            </div>
            <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/12312321123%20(2).jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/12312321123%20(2).jpg" alt="Грамота 3">
            </div>
            <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%96%20%D0%B2%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D1%83%20%D1%80%D0%BE%D0%B1%D1%96%D1%82%20%D0%B2%D0%B5%D1%82%D0%B5%D1%80%D0%B0%D0%BD%D1%96%D0%B2%20(2).JPG')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%96%20%D0%B2%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D1%83%20%D1%80%D0%BE%D0%B1%D1%96%D1%82%20%D0%B2%D0%B5%D1%82%D0%B5%D1%80%D0%B0%D0%BD%D1%96%D0%B2%20(2).JPG" alt="Грамота 4">
            </div>
            <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%96%20%D0%B2%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D1%83%20%D1%80%D0%BE%D0%B1%D1%96%D1%82%20%D0%B2%D0%B5%D1%82%D0%B5%D1%80%D0%B0%D0%BD%D1%96%D0%B2%20(8).JPG')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%96%20%D0%B2%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D1%83%20%D1%80%D0%BE%D0%B1%D1%96%D1%82%20%D0%B2%D0%B5%D1%82%D0%B5%D1%80%D0%B0%D0%BD%D1%96%D0%B2%20(8).JPG" alt="Грамота 5">
            </div>
            <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%96%20%D0%B2%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D1%83%20%D1%80%D0%BE%D0%B1%D1%96%D1%82%20%D0%B2%D0%B5%D1%82%D0%B5%D1%80%D0%B0%D0%BD%D1%96%D0%B2%20(4).JPG')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%96%20%D0%B2%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D1%83%20%D1%80%D0%BE%D0%B1%D1%96%D1%82%20%D0%B2%D0%B5%D1%82%D0%B5%D1%80%D0%B0%D0%BD%D1%96%D0%B2%20(4).JPG" alt="Грамота 6">
            </div>
            <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%96%20%D0%B2%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D1%83%20%D1%80%D0%BE%D0%B1%D1%96%D1%82%20%D0%B2%D0%B5%D1%82%D0%B5%D1%80%D0%B0%D0%BD%D1%96%D0%B2%20(3).JPG')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%96%20%D0%B2%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D1%83%20%D1%80%D0%BE%D0%B1%D1%96%D1%82%20%D0%B2%D0%B5%D1%82%D0%B5%D1%80%D0%B0%D0%BD%D1%96%D0%B2%20(3).JPG" alt="Грамота 7">
            </div>
		
		<div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%8C%D0%BA%D0%B8%D0%B9%20%D1%82%D0%BE%D1%80%D1%82.jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%8C%D0%BA%D0%B8%D0%B9%20%D1%82%D0%BE%D1%80%D1%82.jpg" alt="Грамота 7">
            </div>
		
		<div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%96%20%D0%B2%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D1%83%20%D1%80%D0%BE%D0%B1%D1%96%D1%82%20%D0%B2%D0%B5%D1%82%D0%B5%D1%80%D0%B0%D0%BD%D1%96%D0%B2%20(8).JPG')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%96%D0%BD%D0%BD%D0%B8%D1%86%D1%96%20%D0%B2%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D0%BB%D0%B8%20%D0%B2%D0%B8%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D1%83%20%D1%80%D0%BE%D0%B1%D1%96%D1%82%20%D0%B2%D0%B5%D1%82%D0%B5%D1%80%D0%B0%D0%BD%D1%96%D0%B2%20(8).JPG" alt="Грамота 7">
            </div>

<div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%95%D0%BA%D1%81%D0%BA%D1%83%D1%80%D1%81%D1%96%D1%97%20%D0%BF%D1%96%D0%B4%D0%B7%D0%B5%D0%BC%D0%B5%D0%BB%D0%BB%D1%8F%D0%BC%D0%B8%20%D0%BA%D0%BE%D1%81%D1%82%D0%B5%D0%BB%D1%83%20%D0%B7%20%D1%80%D0%BE%D0%B7%D0%BF%D0%BE%D0%B2%D1%96%D0%B4%D0%B4%D1%8E%20%D0%BF%D1%80%D0%BE%20%D1%81%D0%B2%D1%8F%D1%82%D0%BE%D0%B3%D0%BE%20%D0%AF%D0%BA%D0%BE%D0%B2%D0%B0.JPG')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%95%D0%BA%D1%81%D0%BA%D1%83%D1%80%D1%81%D1%96%D1%97%20%D0%BF%D1%96%D0%B4%D0%B7%D0%B5%D0%BC%D0%B5%D0%BB%D0%BB%D1%8F%D0%BC%D0%B8%20%D0%BA%D0%BE%D1%81%D1%82%D0%B5%D0%BB%D1%83%20%D0%B7%20%D1%80%D0%BE%D0%B7%D0%BF%D0%BE%D0%B2%D1%96%D0%B4%D0%B4%D1%8E%20%D0%BF%D1%80%D0%BE%20%D1%81%D0%B2%D1%8F%D1%82%D0%BE%D0%B3%D0%BE%20%D0%AF%D0%BA%D0%BE%D0%B2%D0%B0.JPG" alt="Грамота 7">
            </div>

<div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%94%D0%BC%D0%B8%D1%82%D1%80%D0%BE%20%D0%9C%D0%B8%D1%80%D0%B0.JPG')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%94%D0%BC%D0%B8%D1%82%D1%80%D0%BE%20%D0%9C%D0%B8%D1%80%D0%B0.JPG" alt="Грамота 7">
            </div>

<div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%80%D1%83%D1%87%D0%B5%D0%BD%D0%BD%D1%8F%20%D0%B2%D1%96%D0%B4%D0%B7%D0%BD%D0%B0%D0%BA%D0%B8%20%D0%B7%D0%B0%20%D0%B2%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8F%20%D0%BD%D0%B0%D1%86%D1%96%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%20%D1%80%D0%B5%D0%BA%D0%BE%D1%80%D0%B4%D1%83.jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%92%D1%80%D1%83%D1%87%D0%B5%D0%BD%D0%BD%D1%8F%20%D0%B2%D1%96%D0%B4%D0%B7%D0%BD%D0%B0%D0%BA%D0%B8%20%D0%B7%D0%B0%20%D0%B2%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8F%20%D0%BD%D0%B0%D1%86%D1%96%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE%20%D1%80%D0%B5%D0%BA%D0%BE%D1%80%D0%B4%D1%83.jpg" alt="Грамота 7">
            </div>

 <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(10).jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(10).jpg" alt="Грамота 1">
            </div>
          
 <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(11).jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(11).jpg" alt="Грамота 1">
            </div>
          
 <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(13).jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(13).jpg" alt="Грамота 1">
            </div>
          
 <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(15).jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(15).jpg" alt="Грамота 1">
            </div>
          
 <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(16).jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(16).jpg" alt="Грамота 1">
            </div>
          
 <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(20).jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(20).jpg" alt="Грамота 1">
            </div>
          
 <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/-5318822130420403765_121.jpg')">
                <img src="https://www.vmr.gov.ua/media/-5318822130420403765_121.jpg" alt="Грамота 1">
            </div>          
          
 <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/-5373187564460165997_121.jpg')">
                <img src="https://www.vmr.gov.ua/media/-5373187564460165997_121.jpg" alt="Грамота 1">
            </div>          
 
<div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/-5373187564460165998_121.jpg')">
                <img src="https://www.vmr.gov.ua/media/-5373187564460165998_121.jpg" alt="Грамота 1">
            </div>     
          
 <div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/-5373187564460165999_121.jpg')">
                <img src="https://www.vmr.gov.ua/media/-5373187564460165999_121.jpg" alt="Грамота 1">
            </div>
 
<div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(20).jpg')">
                <img src="https://www.vmr.gov.ua/media/%D0%A2%D0%A3%D0%A0%D0%98%D0%97%D0%9C/%D0%9A%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B0%20(20).jpg" alt="Грамота 1">
            </div>          
          
<div class="gallery-item" onclick="openModal('https://www.vmr.gov.ua/media/-5436113924882812300_121.jpeg')">
                <img src="https://www.vmr.gov.ua/media/-5436113924882812300_121.jpeg" alt="Грамота 1">
            </div>           


        </div>
    </div>

    <div id="myModal" class="modal" onclick="closeModal()">
        <span class="close">&times;</span>
        <img class="modal-content" id="modalImg">
        <div id="caption" class="caption"></div>
    </div>

    <script>
        function openModal(imageSrc) {
            const modal = document.getElementById("myModal");
            const modalImg = document.getElementById("modalImg");
            const captionText = document.getElementById("caption");
            
            modal.style.display = "block";
            modalImg.src = imageSrc;
            captionText.innerHTML = "Натисніть ESC або клікніть поза зображенням для закриття";
        }

        function closeModal() {
            document.getElementById("myModal").style.display = "none";
        }

        document.addEventListener('keydown', function(event) {
            if (event.key === 'Escape') {
                closeModal();
            }
        });

        window.onclick = function(event) {
            const modal = document.getElementById("myModal");
            if (event.target === modal) {
                closeModal();
            }
        }
    </script>
</body>
</html>]]></description>
      <pubDate>Mon, 15 Sep 2025 10:13:15 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/podyaky-gromadi</guid>
    </item>
    <item>
      <title>Підтримка книговидання про Вінницю</title>
      <link>https://test2.vmr.gov.ua/pidtrymka-knyhovydannia-pro-vinnytsiu</link>
      <description><![CDATA[]]></description>
      <pubDate>Fri, 04 Apr 2025 13:52:34 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/pidtrymka-knyhovydannia-pro-vinnytsiu</guid>
    </item>
    <item>
      <title>Важлива інформація</title>
      <link>https://test2.vmr.gov.ua/vazhlyva-informatsiia-2025</link>
      <description><![CDATA[]]></description>
      <pubDate>Mon, 14 Apr 2025 12:29:06 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/vazhlyva-informatsiia-2025</guid>
    </item>
    <item>
      <title>Гуманітарна допомога</title>
      <link>https://test2.vmr.gov.ua/humanitarna-dopomoha</link>
      <description><![CDATA[]]></description>
      <pubDate>Wed, 25 Dec 2024 09:10:57 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/humanitarna-dopomoha</guid>
    </item>
    <item>
      <title>Цифровий простір міста</title>
      <link>https://test2.vmr.gov.ua/tsyfrovyi-prostir-mista</link>
      <description><![CDATA[]]></description>
      <pubDate>Fri, 23 Aug 2024 11:37:34 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/tsyfrovyi-prostir-mista</guid>
    </item>
    <item>
      <title>Важлива інформація 2024</title>
      <link>https://test2.vmr.gov.ua/vazhlyva-informatsiia-2024</link>
      <description><![CDATA[]]></description>
      <pubDate>Thu, 16 Jan 2025 08:47:07 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/vazhlyva-informatsiia-2024</guid>
    </item>
    <item>
      <title>Очищення влади</title>
      <link>https://test2.vmr.gov.ua/ochyshchennia-vlady</link>
      <description><![CDATA[]]></description>
      <pubDate>Thu, 16 Jan 2025 07:23:01 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/ochyshchennia-vlady</guid>
    </item>
    <item>
      <title> ​Інтегрований розвиток міста</title>
      <link>https://test2.vmr.gov.ua/intehrovanyi-rozvytok-mista</link>
      <description><![CDATA[]]></description>
      <pubDate>Wed, 25 Oct 2023 08:13:25 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/intehrovanyi-rozvytok-mista</guid>
    </item>
    <item>
      <title>Інформація Податкової служби</title>
      <link>https://test2.vmr.gov.ua/informatsiia-podatkovoi-sluzhby</link>
      <description><![CDATA[]]></description>
      <pubDate>Wed, 27 Sep 2023 08:49:22 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/informatsiia-podatkovoi-sluzhby</guid>
    </item>
    <item>
      <title>Конкурс проєктів ІГС</title>
      <link>https://test2.vmr.gov.ua/konkurs-proiektiv-ihs</link>
      <description><![CDATA[]]></description>
      <pubDate>Wed, 25 Oct 2023 12:36:03 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/konkurs-proiektiv-ihs</guid>
    </item>
    <item>
      <title>Цифрова освіта</title>
      <link>https://test2.vmr.gov.ua/tsyfrova-osvita</link>
      <description><![CDATA[]]></description>
      <pubDate>Fri, 04 Apr 2025 08:39:57 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/tsyfrova-osvita</guid>
    </item>
    <item>
      <title>Безбар'єрність та доступність </title>
      <link>https://test2.vmr.gov.ua/dostupnist</link>
      <description><![CDATA[<div class="container mb-5">
  <div class="row">
    <div class="col-lg-8 col-md-10 col-12">
      <h2 style="font-family: VinnytsiaSansReg; font-size: 2.27rem; font-weight: 500; color: #212529; margin-top: 0; margin-bottom: 1rem;">
  Калькулятор розрахунку пандуса
</h2>

      <form id="rampForm" class="text-black">
        <div class="mb-3">
          <label for="heightInput" class="form-label fw-semibold text-black" style="font-size: 1.05rem;">
            Введіть висоту підйому (в см):
          </label>
          <input type="number" id="heightInput" min="1" required class="form-control" placeholder="Наприклад, 90">
        </div>
        <button type="submit" class="btn btn-primary w-100 fw-semibold" style="background-color: #e6f0f9; color: #000000; border: none;">Розрахувати</button>
      </form>

      <div id="result" class="mt-4 alert alert-light border-start border-4 border-primary d-none" style="color: #000; font-size: 1.05rem;"></div>
    </div>
  </div>
</div>

<script>
  document.getElementById('rampForm').addEventListener('submit', function (e) {
    e.preventDefault();
    const heightCm = parseFloat(document.getElementById('heightInput').value);
    if (isNaN(heightCm) || heightCm <= 0) {
      alert('Будь ласка, введіть коректну висоту в сантиметрах.');
      return;
    }

    const rampLength8 = (heightCm * 100) / 8;
    const rampLength5 = (heightCm * 100) / 5;

    const angle8deg = Math.atan(0.08) * (180 / Math.PI);
    const angle5deg = Math.atan(0.05) * (180 / Math.PI);

    const resultDiv = document.getElementById('result');
    resultDiv.innerHTML = `
      <strong>Результати розрахунку:</strong>
      <ul class="mt-2 mb-0 ps-3">
        <li>Довжина пандуса зі схилом 8%: <strong>${rampLength8.toFixed(1)} см</strong> (8%)</li>
        <li>Довжина пандуса зі схилом 5%: <strong>${rampLength5.toFixed(1)} см</strong> (5%)</li>
        <li>Кут нахилу при схилі 8%: <strong>${angle8deg.toFixed(1)}°</strong></li>
        <li>Кут нахилу при схилі 5%: <strong>${angle5deg.toFixed(1)}°</strong></li>
      </ul>
    `;
    resultDiv.classList.remove("d-none");
  });
</script>
]]></description>
      <pubDate>Thu, 05 Jun 2025 12:24:06 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/dostupnist</guid>
    </item>
    <item>
      <title>Консультативно-дорадчі органи</title>
      <link>https://test2.vmr.gov.ua/konsultatyvno-doradchi-orhany</link>
      <description><![CDATA[]]></description>
      <pubDate>Fri, 01 Nov 2024 12:24:45 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/konsultatyvno-doradchi-orhany</guid>
    </item>
    <item>
      <title>Підтримка бізнесу</title>
      <link>https://test2.vmr.gov.ua/pidtrymka-biznesu</link>
      <description><![CDATA[]]></description>
      <pubDate>Tue, 15 Apr 2025 06:11:49 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/pidtrymka-biznesu</guid>
    </item>
    <item>
      <title>ДСНС інформує</title>
      <link>https://test2.vmr.gov.ua/dsns-informuie</link>
      <description><![CDATA[]]></description>
      <pubDate>Mon, 14 Apr 2025 12:40:12 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/dsns-informuie</guid>
    </item>
    <item>
      <title>Збори громадян за місцем проживання</title>
      <link>https://test2.vmr.gov.ua/zbory-gromadian-0</link>
      <description><![CDATA[]]></description>
      <pubDate>Fri, 03 Jan 2025 09:36:10 GMT</pubDate>
      <guid isPermaLink="true">https://test2.vmr.gov.ua/zbory-gromadian-0</guid>
    </item>
  </channel>
</rss>