<?xml version="1.0" encoding="windows-1251"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="https://skaditest5.rusff.me/export.php?type=rss" rel="self" type="application/rss+xml" />
		<title>test skadi</title>
		<link>https://skaditest5.rusff.me/</link>
		<description>test skadi</description>
		<language>ru-ru</language>
		<lastBuildDate>Tue, 23 Jun 2026 15:51:12 +0300</lastBuildDate>
		<generator>MyBB/mybb.ru</generator>
		<item>
			<title>банк банк банк</title>
			<link>https://skaditest5.rusff.me/viewtopic.php?pid=21#p21</link>
			<description>&lt;p&gt;&amp;lt;label style=&amp;quot;display:flex; align-items:center; gap:4px;&amp;quot;&amp;gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;lt;input type=&amp;quot;checkbox&amp;quot; class=&amp;quot;proof-discount&amp;quot;&amp;gt;&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; скидка 50%&lt;br /&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;lt;/label&amp;gt;&lt;/p&gt;&lt;div class=&quot;code-box&quot;&gt;&lt;strong class=&quot;legend&quot;&gt;Код:&lt;/strong&gt;&lt;div class=&quot;blockcode&quot;&gt;&lt;div class=&quot;scrollbox&quot; style=&quot;height: 35em&quot;&gt;&lt;pre&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;// YJ &amp;amp; qwen
// YJ &amp;amp; qwen (modded)
(function() {
    var currentUrl = window.location.href;
    if (currentUrl.indexOf(&#039;/viewtopic.php?id=9&#039;) === -1) {
        return;
    }

document.addEventListener(&#039;DOMContentLoaded&#039;, () =&amp;gt; {
    const bankState = [];
    const replyBtn = document.getElementById(&#039;bank-reply&#039;);
    const replyArea = document.getElementById(&#039;main-reply&#039;);
    const reportOutput = document.getElementById(&#039;bank-report-output&#039;);

    // Рендер отчёта
    function renderReport() {
        if (!bankState.length) {
            reportOutput.innerHTML = &#039;&amp;lt;em style=&amp;quot;color:#888&amp;quot;&amp;gt;Пока ничего не выбрано. Кликни на операции выше.&amp;lt;/em&amp;gt;&#039;;
            reportOutput.classList.add(&#039;show&#039;);
            return;
        }

        let lines = [];
        let total = 0;
        let calcParts = [];

        bankState.forEach((op, idx) =&amp;gt; {
            const sign = op.type === &#039;get&#039; ? &#039;+&#039; : &#039;-&#039;;
            const proofPart = op.type === &#039;get&#039; ? ` (${op.proof})` : &#039;&#039;;

            lines.push(
                `&amp;lt;div class=&amp;quot;report-line&amp;quot; data-idx=&amp;quot;${idx}&amp;quot;&amp;gt;` +
                `${sign}${op.name}: ${op.cost}$${proofPart}` +
                ` &amp;lt;span class=&amp;quot;report-remove&amp;quot; title=&amp;quot;Убрать&amp;quot;&amp;gt;X&amp;lt;/span&amp;gt;` +
                `&amp;lt;/div&amp;gt;`
            );

            if (op.type === &#039;get&#039;) {
                total += op.cost;
                calcParts.push(`+ ${op.cost}`);
            } else {
                total -= op.cost;
                calcParts.push(`- ${op.cost}`);
            }
        });

        let calcLine = calcParts.join(&#039; &#039;).trim();
        if (calcLine.startsWith(&#039;+ &#039;)) calcLine = calcLine.slice(2);

        lines.push(`&amp;lt;div class=&amp;quot;report-total&amp;quot;&amp;gt;подсчет: ${calcLine} = ${total}$&amp;lt;/div&amp;gt;`);

        reportOutput.innerHTML = lines.join(&#039;\n&#039;);
        reportOutput.classList.add(&#039;show&#039;);

        // Удаление по крестику
        reportOutput.querySelectorAll(&#039;.report-remove&#039;).forEach(btn =&amp;gt; {
            btn.addEventListener(&#039;click&#039;, (e) =&amp;gt; {
                e.stopPropagation();
                const idx = parseInt(btn.closest(&#039;.report-line&#039;).dataset.idx);
                bankState.splice(idx, 1);
                renderReport();
            });
        });

        // Удаление по клику на строку
        reportOutput.querySelectorAll(&#039;.report-line&#039;).forEach(line =&amp;gt; {
            line.addEventListener(&#039;click&#039;, (e) =&amp;gt; {
                if (e.target.classList.contains(&#039;report-remove&#039;)) return;
                const idx = parseInt(line.dataset.idx);
                bankState.splice(idx, 1);
                renderReport();
            });
        });
    }

    // Клик по операциям
    document.querySelectorAll(&#039;.op-item&#039;).forEach(el =&amp;gt; {
        el.addEventListener(&#039;click&#039;, function() {
            const type = this.dataset.type;
            const name = this.dataset.name;
            const cost = parseFloat(this.dataset.cost);

            // ДОХОД &amp;#8594; показываем textarea
if (type === &#039;get&#039;) {
    const existing = this.querySelector(&#039;.proof-wrap&#039;);

    // &amp;#128073; если уже открыт — закрываем
    if (existing) {
        existing.remove();
        return;
    }

    const wrap = document.createElement(&#039;div&#039;);
    wrap.className = &#039;proof-wrap&#039;;
    wrap.style.marginTop = &#039;5px&#039;;

    wrap.innerHTML = `
        &amp;lt;textarea class=&amp;quot;proof-input&amp;quot; placeholder=&amp;quot;Ссылки...&amp;quot; rows=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;
        
        &amp;lt;div style=&amp;quot;margin-top:5px; display:flex; gap:10px; align-items:center;&amp;quot;&amp;gt;
            &amp;lt;label&amp;gt;кол-во: 
                &amp;lt;input type=&amp;quot;number&amp;quot; class=&amp;quot;proof-count&amp;quot; value=&amp;quot;1&amp;quot; min=&amp;quot;1&amp;quot; style=&amp;quot;width:50px;&amp;quot;&amp;gt;
            &amp;lt;/label&amp;gt;

            &amp;lt;label style=&amp;quot;display:flex; align-items:center; gap:4px;&amp;quot;&amp;gt;
                &amp;lt;input type=&amp;quot;checkbox&amp;quot; class=&amp;quot;proof-mult&amp;quot;&amp;gt;
                x2
            &amp;lt;/label&amp;gt;
        &amp;lt;/div&amp;gt;
    `;

    this.appendChild(wrap);

    const textarea = wrap.querySelector(&#039;.proof-input&#039;);
    const countInput = wrap.querySelector(&#039;.proof-count&#039;);
    const multCheckbox = wrap.querySelector(&#039;.proof-mult&#039;);
    const discountCheckbox = wrap.querySelector(&#039;.proof-discount&#039;);

    textarea.focus();

    const save = () =&amp;gt; {
        const proof = textarea.value.trim() || &#039;нет ссылки&#039;;
        let count = parseInt(countInput.value) || 1;

        let finalCost = cost * count;

        if (multCheckbox.checked) finalCost *= 2;
        if (discountCheckbox.checked) finalCost *= 0.5;

        bankState.push({
            id: Date.now() + Math.random(),
            type,
            name: `${name} x${count}`,
            cost: finalCost,
            proof
        });

        wrap.remove();
        renderReport();
    };
                };


            // РАСХОД &amp;#8594; сразу добавляется
            bankState.push({
                id: Date.now() + Math.random(),
                type,
                name,
                cost,
                proof: &#039;&#039;
            });

            this.classList.add(&#039;added&#039;);
            setTimeout(() =&amp;gt; this.classList.remove(&#039;added&#039;), 250);

            renderReport();
        });
    });

    // Кнопка &amp;quot;В форму ответа&amp;quot;
    replyBtn?.addEventListener(&#039;click&#039;, () =&amp;gt; {
        if (!bankState.length) return alert(&#039;ничего не выбрано.&#039;);

        let text = [];
        let total = 0;

        bankState.forEach(op =&amp;gt; {
            const sign = op.type === &#039;get&#039; ? &#039;+&#039; : &#039;-&#039;;
            const proofPart = op.type === &#039;get&#039; ? ` (${op.proof})` : &#039;&#039;;
            text.push(`${sign}${op.name}: ${op.cost}$${proofPart}`);
            total += op.type === &#039;get&#039; ? op.cost : -op.cost;
        });

        let calcParts = bankState.map(op =&amp;gt; {
            const s = op.type === &#039;get&#039; ? &#039;+&#039; : &#039;-&#039;;
            return `${s} ${op.cost}`;
        });

        let calcLine = calcParts.join(&#039; &#039;).replace(/^\+ /, &#039;&#039;);
        text.push(`подсчет: ${calcLine} = ${total}$`);

        const finalText = text.join(&#039;\n&#039;);

        if (replyArea) {
            replyArea.value = replyArea.value.trim()
                ? replyArea.value + &#039;\n\n&#039; + finalText
                : finalText;

            replyArea.focus();
            replyArea.style.outline = &#039;2px solid #4caf50&#039;;
            setTimeout(() =&amp;gt; replyArea.style.outline = &#039;&#039;, 800);
        } else {
            navigator.clipboard?.writeText(finalText).then(() =&amp;gt; {
                alert(&#039;Форма не найдена, но отчёт скопирован в буфер!&#039;);
            });
        }
    });

    renderReport();
});
})();

&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</description>
			<author>mybb@mybb.ru (skadi)</author>
			<pubDate>Tue, 23 Jun 2026 15:51:12 +0300</pubDate>
			<guid>https://skaditest5.rusff.me/viewtopic.php?pid=21#p21</guid>
		</item>
		<item>
			<title>биржа</title>
			<link>https://skaditest5.rusff.me/viewtopic.php?pid=19#p19</link>
			<description>&lt;div class=&quot;code-box&quot;&gt;&lt;strong class=&quot;legend&quot;&gt;Код:&lt;/strong&gt;&lt;div class=&quot;blockcode&quot;&gt;&lt;div class=&quot;scrollbox&quot; style=&quot;height: 35em&quot;&gt;&lt;pre&gt;window.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function () {

  const FORUM_ID = 2;
  const CACHE_KEY = `jobs_cache_${FORUM_ID}`;
  const CACHE_TTL = 1000 * 60 * 60;

  const root = document.querySelector(&amp;quot;#jobs-root&amp;quot;);

  console.log(&amp;quot;JOBS START&amp;quot;);
  console.log(&amp;quot;ROOT:&amp;quot;, root);

  if (!root) return;

  // ======================
  // &amp;#129532; CLEAN (кодировка костыль)
  // ======================
  function clean(str) {
    return (str || &amp;quot;&amp;quot;)
      .replace(/\uFFFD/g, &amp;quot;&amp;quot;)
      .replace(/&amp;#65533;+/g, &amp;quot;&amp;quot;)
      .replace(/\s+/g, &amp;quot; &amp;quot;)
      .trim();
  }

  // ======================
  // CATEGORY NORMALIZER
  // ======================
 function normalizeCategory(text) {
  const t = clean(text).toLowerCase();

  if (t.includes(&amp;quot;обще&amp;quot;)) return &amp;quot;общественная сфера&amp;quot;;
  if (t.includes(&amp;quot;образ&amp;quot;)) return &amp;quot;образовательная сфера&amp;quot;;
  if (t.includes(&amp;quot;коммер&amp;quot;) || t.includes(&amp;quot;услуг&amp;quot;) || t.includes(&amp;quot;магаз&amp;quot;)) {
    return &amp;quot;коммерческая сфера&amp;quot;;
  }
  if (t.includes(&amp;quot;твор&amp;quot;)) return &amp;quot;творческая сфера&amp;quot;;

  return &amp;quot;другое&amp;quot;;
}

  // ======================
  // CACHE
  // ======================
  try {
    const cached = localStorage.getItem(CACHE_KEY);

    if (cached) {
      const parsed = JSON.parse(cached);

      if (Date.now() - parsed.time &amp;lt; CACHE_TTL) {
        console.log(&amp;quot;CACHE HIT&amp;quot;);
        render(parsed.data);
        return;
      }
    }
  } catch(e) {
    console.warn(&amp;quot;CACHE ERROR&amp;quot;, e);
  }

  load();

  // ======================
  // SAFE GET
  // ======================
  function get(root, cls) {
    const el = root?.querySelector(`.${cls}`);
    return clean(el?.textContent || el?.innerText || &amp;quot;&amp;quot;);
  }

  // ======================
  // LOAD
  // ======================
  function load() {

    console.log(&amp;quot;LOADING TOPICS...&amp;quot;);

    fetch(`/api.php?method=topic.get&amp;amp;forum_id=${FORUM_ID}`)
      .then(r =&amp;gt; r.json())
      .then(d =&amp;gt; {

        const topics = d.response || [];
        console.log(&amp;quot;TOPICS:&amp;quot;, topics.length);

        return Promise.all(
          topics.map(t =&amp;gt;
            fetch(`/viewtopic.php?id=${t.id}`)
              .then(r =&amp;gt; r.text())
          )
        );
      })
      .then(pages =&amp;gt; {

        const jobs = {};

        pages.forEach((html, i) =&amp;gt; {

          console.log(&amp;quot;PAGE&amp;quot;, i, &amp;quot;HAS m-ank:&amp;quot;, html.includes(&amp;quot;m-ank&amp;quot;));

          const temp = document.createElement(&amp;quot;div&amp;quot;);
          temp.innerHTML = html;

          const firstPost = temp.querySelector(&amp;quot;.post&amp;quot;);
          const userId = firstPost?.dataset?.userId || &amp;quot;0&amp;quot;;

          const ank = temp.querySelector(&amp;quot;.m-ank&amp;quot;);


          console.log(&amp;quot;ANK FOUND:&amp;quot;, !!ank);

console.log(&amp;quot;RAW JOBCAT:&amp;quot;, ank.querySelector(&amp;quot;.m-job&amp;quot;)?.innerHTML);

          if (!ank) return;

          const jobCat = clean(ank.querySelector(&amp;quot;.m-job&amp;quot;)?.textContent);
          const jobPlace = clean(ank.querySelector(&amp;quot;.m-job-pl&amp;quot;)?.textContent);
          const jobTitle = clean(ank.querySelector(&amp;quot;.m-job-t&amp;quot;)?.textContent);
          const name = get(ank, &amp;quot;m-name&amp;quot;);

          console.log(&amp;quot;JOB DATA:&amp;quot;, {
            jobCat,
            jobPlace,
            jobTitle,
            name
          });

          // &amp;#10071; если вообще пусто — НЕ убиваем страницу
          if (!jobCat &amp;amp;&amp;amp; !jobPlace &amp;amp;&amp;amp; !jobTitle) return;

          const cat = normalizeCategory(jobCat || &amp;quot;&amp;quot;);
          const place = jobPlace || &amp;quot;без места работы&amp;quot;;
          const title = jobTitle &amp;amp;&amp;amp; jobTitle.length
            ? jobTitle
            : &amp;quot;без должности&amp;quot;;

          if (!jobs[cat]) jobs[cat] = {};
          if (!jobs[cat][place]) jobs[cat][place] = {};
          if (!jobs[cat][place][title]) jobs[cat][place][title] = [];

          jobs[cat][place][title].push({
            name,
            id: userId
          });

        });

        console.log(&amp;quot;FINAL JOBS:&amp;quot;, jobs);

        localStorage.setItem(CACHE_KEY, JSON.stringify({
          time: Date.now(),
          data: jobs
        }));

        render(jobs);
      })
      .catch(err =&amp;gt; console.error(&amp;quot;API ERROR&amp;quot;, err));
  }

  // ======================
  // RENDER
  // ======================
  function render(jobs) {

    console.log(&amp;quot;RENDER START&amp;quot;);

    const categories = [
      &amp;quot;общественная сфера&amp;quot;,
      &amp;quot;образовательная сфера&amp;quot;,
      &amp;quot;коммерческая сфера&amp;quot;,
      &amp;quot;творческая сфера&amp;quot;,
      &amp;quot;другое&amp;quot;
    ];

    function renderPane(cat) {

      const places = jobs[cat] || {};

      return Object.entries(places).map(([place, roles]) =&amp;gt; {

        return `
          &amp;lt;mjb&amp;gt;
            &amp;lt;h10&amp;gt;${clean(place)}&amp;lt;/h10&amp;gt;

            ${Object.entries(roles).map(([role, people]) =&amp;gt; `
              &amp;lt;b1&amp;gt;
                ${clean(role)}:
                ${people.map(p =&amp;gt;
                  `&amp;lt;a href=&amp;quot;/profile.php?id=${p.id}&amp;quot;&amp;gt;${clean(p.name)}&amp;lt;/a&amp;gt;`
                ).join(&amp;quot;, &amp;quot;)}
              &amp;lt;/b1&amp;gt;
            `).join(&amp;quot;&amp;quot;)}

          &amp;lt;/mjb&amp;gt;
        `;
      }).join(&amp;quot;&amp;quot;);
    }

    const panes = root.querySelectorAll(&amp;quot;.pane&amp;quot;);

    console.log(&amp;quot;PANES FOUND:&amp;quot;, panes.length);

    panes.forEach((pane, i) =&amp;gt; {
      const cat = categories[i];
      console.log(&amp;quot;RENDER PANE:&amp;quot;, cat);
      pane.innerHTML = renderPane(cat);
    });
  }

});&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</description>
			<author>mybb@mybb.ru (skadi)</author>
			<pubDate>Tue, 23 Jun 2026 13:36:34 +0300</pubDate>
			<guid>https://skaditest5.rusff.me/viewtopic.php?pid=19#p19</guid>
		</item>
		<item>
			<title>Тестовое сообщение</title>
			<link>https://skaditest5.rusff.me/viewtopic.php?pid=16#p16</link>
			<description>&lt;div class=&quot;code-box&quot;&gt;&lt;strong class=&quot;legend&quot;&gt;Код:&lt;/strong&gt;&lt;div class=&quot;blockcode&quot;&gt;&lt;div class=&quot;scrollbox&quot; style=&quot;height: 35em&quot;&gt;&lt;pre&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
window.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function () {

  const FORUM_ID = 2;
  const CACHE_KEY = `characters_cache_${FORUM_ID}`;
  const CACHE_TTL = 1000 * 60 * 60;

  const facesRoot = document.getElementById(&amp;quot;faces-root&amp;quot;);
  const namesRoot = document.getElementById(&amp;quot;names-root&amp;quot;);

  if (!facesRoot &amp;amp;&amp;amp; !namesRoot) return;

  console.log(&amp;quot;SCRIPT STARTED&amp;quot;);

  // ======================
  // CACHE
  // ======================
  try {
    const cached = localStorage.getItem(CACHE_KEY);

    if (cached) {
      const parsed = JSON.parse(cached);

      if (Date.now() - parsed.time &amp;lt; CACHE_TTL) {
        renderAll(parsed.data);
      } else {
        load();
      }
    } else {
      load();
    }
  } catch (e) {
    console.warn(&amp;quot;CACHE ERROR&amp;quot;, e);
    load();
  }

  // ======================
  // HELPERS
  // ======================
  function getField(root, cls) {
    return (root?.querySelector(`.${cls}`)?.innerText || &amp;quot;&amp;quot;).trim();
  }

  // ======================
  // LOAD DATA
  // ======================
  function load() {

    console.log(&amp;quot;LOADING...&amp;quot;);

    fetch(`/api.php?method=topic.get&amp;amp;forum_id=${FORUM_ID}`)
      .then(r =&amp;gt; r.json())
      .then(d =&amp;gt; {

        const topics = d.response || [];

        return Promise.all(
          topics.map(t =&amp;gt;
            fetch(`/viewtopic.php?id=${t.id}`)
              .then(r =&amp;gt; r.text())
              .then(html =&amp;gt; {

                const temp = document.createElement(&amp;quot;div&amp;quot;);
                temp.innerHTML = html;

                const firstPost = temp.querySelector(&amp;quot;.post&amp;quot;);
                const userId = firstPost?.dataset?.userId;

                const ank = temp.querySelector(&amp;quot;.m-ank&amp;quot;);

                const name = getField(ank, &amp;quot;m-name&amp;quot;);
                const face = getField(ank, &amp;quot;m-face&amp;quot;);

                // &amp;#128165; ВАЖНО: берём ВСЁ как текст (обход битой кодировки)
                const genderRaw = (ank?.innerText || &amp;quot;&amp;quot;).toLowerCase();

                return {
                  id: userId,
                  name,
                  face,
                  genderRaw
                };

              })
          )
        );
      })
      .then(characters =&amp;gt; {

        characters = characters.filter(c =&amp;gt; c.face || c.name);

        // ======================
        // ДУБЛИ ВНЕШНОСТЕЙ
        // ======================
        const faceCount = {};

        characters.forEach(c =&amp;gt; {
          const key = (c.face || &amp;quot;&amp;quot;).toLowerCase().trim();
          faceCount[key] = (faceCount[key] || 0) + 1;
        });

        characters.forEach(c =&amp;gt; {
          const key = (c.face || &amp;quot;&amp;quot;).toLowerCase().trim();
          c.isDuplicate = faceCount[key] &amp;gt; 1;
        });

        // ======================
        // ПОЛ (СТАБИЛЬНО ЧЕРЕЗ TEXT)
        // ======================
        const males = [];
        const females = [];

        const maleWords = [&amp;quot;м&amp;quot;, &amp;quot;муж&amp;quot;, &amp;quot;male&amp;quot;, &amp;quot;man&amp;quot;];
        const femaleWords = [&amp;quot;ж&amp;quot;, &amp;quot;жен&amp;quot;, &amp;quot;female&amp;quot;, &amp;quot;woman&amp;quot;];

        characters.forEach(c =&amp;gt; {

          const g = c.genderRaw;

          if (femaleWords.some(w =&amp;gt; g.includes(w))) {
            females.push(c);
          } else if (maleWords.some(w =&amp;gt; g.includes(w))) {
            males.push(c);
          } else {
            females.push(c); // дефолт
          }

        });

        // ======================
        // ИМЕНА / ФАМИЛИИ
        // ======================
        const firstNames = [];
        const lastNames = [];

        characters.forEach(c =&amp;gt; {

          const parts = (c.name || &amp;quot;&amp;quot;).split(/\s+/);

          const first = (parts[0] || &amp;quot;&amp;quot;).toLowerCase();
          const last = (parts.slice(1).join(&amp;quot; &amp;quot;) || &amp;quot;&amp;quot;).toLowerCase();

          if (first) {
            firstNames.push({ key: first, label: c.name, id: c.id });
          }

          if (last) {
            lastNames.push({ key: last, label: c.name, id: c.id });
          }

        });

        const data = { males, females, firstNames, lastNames };

        localStorage.setItem(CACHE_KEY, JSON.stringify({
          time: Date.now(),
          data
        }));

        renderAll(data);
      })
      .catch(err =&amp;gt; {
        console.error(&amp;quot;API ERROR&amp;quot;, err);
      });
  }

  // ======================
  // GROUPING
  // ======================
  function groupByLetters(list, keyName) {

    const groups = {
      &amp;quot;a-b-c-d&amp;quot;: [],
      &amp;quot;e-f-g-h&amp;quot;: [],
      &amp;quot;i-j-k-l&amp;quot;: [],
      &amp;quot;m-n-o-p&amp;quot;: [],
      &amp;quot;q-r-s-t&amp;quot;: [],
      &amp;quot;u-v-w-x-y-z&amp;quot;: []
    };

    list.forEach(c =&amp;gt; {

      const first = (c[keyName] || &amp;quot;&amp;quot;)
        .trim()
        .charAt(0)
        .toLowerCase();

      if (&amp;quot;abcd&amp;quot;.includes(first)) groups[&amp;quot;a-b-c-d&amp;quot;].push(c);
      else if (&amp;quot;efgh&amp;quot;.includes(first)) groups[&amp;quot;e-f-g-h&amp;quot;].push(c);
      else if (&amp;quot;ijkl&amp;quot;.includes(first)) groups[&amp;quot;i-j-k-l&amp;quot;].push(c);
      else if (&amp;quot;mnop&amp;quot;.includes(first)) groups[&amp;quot;m-n-o-p&amp;quot;].push(c);
      else if (&amp;quot;qrst&amp;quot;.includes(first)) groups[&amp;quot;q-r-s-t&amp;quot;].push(c);
      else groups[&amp;quot;u-v-w-x-y-z&amp;quot;].push(c);
    });

    return groups;
  }

  // ======================
  // RENDER FACES
  // ======================
  function renderFaces(root, males, females) {

    function column(title, list) {

      const sorted = list.slice().sort((a, b) =&amp;gt;
        (a.face || &amp;quot;&amp;quot;).localeCompare(b.face || &amp;quot;&amp;quot;)
      );

      const groups = groupByLetters(sorted, &amp;quot;face&amp;quot;);

      return `
        &amp;lt;div class=&amp;quot;faces-column&amp;quot;&amp;gt;
          &amp;lt;h2&amp;gt;${title}&amp;lt;/h2&amp;gt;

          ${Object.entries(groups).map(([g, items]) =&amp;gt; {
            if (!items.length) return &amp;quot;&amp;quot;;

            return `
              &amp;lt;div class=&amp;quot;face-group&amp;quot;&amp;gt;
                &amp;lt;div class=&amp;quot;face-letter&amp;quot;&amp;gt;${g}&amp;lt;/div&amp;gt;

                ${items.map(c =&amp;gt; `
                  &amp;lt;div class=&amp;quot;face-item&amp;quot;&amp;gt;
                    &amp;lt;a href=&amp;quot;/profile.php?id=${c.id}&amp;quot;&amp;gt;
                      ${c.face}${c.isDuplicate ? &amp;quot; &amp;#9733;&amp;quot; : &amp;quot;&amp;quot;} — ${c.name}
                    &amp;lt;/a&amp;gt;
                  &amp;lt;/div&amp;gt;
                `).join(&amp;quot;&amp;quot;)}

              &amp;lt;/div&amp;gt;
            `;
          }).join(&amp;quot;&amp;quot;)}

        &amp;lt;/div&amp;gt;
      `;
    }

    root.innerHTML = `
      &amp;lt;div style=&amp;quot;display:flex; justify-content:flex-end; margin-bottom:10px;&amp;quot;&amp;gt;
        &amp;lt;button id=&amp;quot;refresh-all&amp;quot;&amp;gt;Обновить&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div class=&amp;quot;faces-wrapper&amp;quot;&amp;gt;
        &amp;lt;div class=&amp;quot;faces-columns&amp;quot;&amp;gt;
          ${column(&amp;quot;Мужские внешности&amp;quot;, males)}
          ${column(&amp;quot;Женские внешности&amp;quot;, females)}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    `;
  }

  // ======================
  // RENDER NAMES
  // ======================
  function renderNames(root, firstNames, lastNames) {

    function column(title, list) {

      const sorted = list.slice().sort((a, b) =&amp;gt;
        a.key.localeCompare(b.key)
      );

      const groups = groupByLetters(sorted, &amp;quot;key&amp;quot;);

      return `
        &amp;lt;div class=&amp;quot;faces-column&amp;quot;&amp;gt;
          &amp;lt;h2&amp;gt;${title}&amp;lt;/h2&amp;gt;

          ${Object.entries(groups).map(([g, items]) =&amp;gt; {
            if (!items.length) return &amp;quot;&amp;quot;;

            return `
              &amp;lt;div class=&amp;quot;face-group&amp;quot;&amp;gt;
                &amp;lt;div class=&amp;quot;face-letter&amp;quot;&amp;gt;${g}&amp;lt;/div&amp;gt;

                ${items.map(c =&amp;gt; `
                  &amp;lt;div class=&amp;quot;face-item&amp;quot;&amp;gt;
                    &amp;lt;a href=&amp;quot;/profile.php?id=${c.id}&amp;quot;&amp;gt;
                      ${c.key} — ${c.label}
                    &amp;lt;/a&amp;gt;
                  &amp;lt;/div&amp;gt;
                `).join(&amp;quot;&amp;quot;)}

              &amp;lt;/div&amp;gt;
            `;
          }).join(&amp;quot;&amp;quot;)}

        &amp;lt;/div&amp;gt;
      `;
    }

    root.innerHTML = `
      &amp;lt;div class=&amp;quot;faces-wrapper&amp;quot;&amp;gt;
        &amp;lt;div class=&amp;quot;faces-columns&amp;quot;&amp;gt;
          ${column(&amp;quot;Имена&amp;quot;, firstNames)}
          ${column(&amp;quot;Фамилии&amp;quot;, lastNames)}
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    `;
  }

  // ======================
  // RENDER ALL
  // ======================
  function renderAll(data) {

    if (facesRoot) {
      renderFaces(facesRoot, data.males, data.females);
    }

    if (namesRoot) {
      renderNames(namesRoot, data.firstNames, data.lastNames);
    }

    const btn = document.getElementById(&amp;quot;refresh-all&amp;quot;);
    if (btn) {
      btn.onclick = () =&amp;gt; {
        localStorage.removeItem(CACHE_KEY);
        load();
      };
    }
  }

});
&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</description>
			<author>mybb@mybb.ru (skadi)</author>
			<pubDate>Mon, 22 Jun 2026 20:36:53 +0300</pubDate>
			<guid>https://skaditest5.rusff.me/viewtopic.php?pid=16#p16</guid>
		</item>
		<item>
			<title>внешности</title>
			<link>https://skaditest5.rusff.me/viewtopic.php?pid=14#p14</link>
			<description>&lt;p&gt;[html]&amp;lt;div id=&amp;quot;names-root&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;[/html]&lt;/p&gt;</description>
			<author>mybb@mybb.ru (skadi)</author>
			<pubDate>Mon, 22 Jun 2026 19:36:33 +0300</pubDate>
			<guid>https://skaditest5.rusff.me/viewtopic.php?pid=14#p14</guid>
		</item>
		<item>
			<title>имена</title>
			<link>https://skaditest5.rusff.me/viewtopic.php?pid=13#p13</link>
			<description>&lt;p&gt;[html]&amp;lt;div id=&amp;quot;names-root&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;[/html]&lt;/p&gt;</description>
			<author>mybb@mybb.ru (skadi)</author>
			<pubDate>Sun, 21 Jun 2026 21:51:32 +0300</pubDate>
			<guid>https://skaditest5.rusff.me/viewtopic.php?pid=13#p13</guid>
		</item>
		<item>
			<title>анкета проверочная три</title>
			<link>https://skaditest5.rusff.me/viewtopic.php?pid=6#p6</link>
			<description>&lt;div class=&quot;m-ank&quot; id=&quot;block-1&quot;&gt;&lt;div class=&quot;m-name&quot; id=&quot;block-11&quot;&gt;&lt;p&gt;Chris Nott&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-name-r&quot; id=&quot;block-2&quot;&gt;&lt;p&gt;Крис Нотт&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-face&quot; id=&quot;block-3&quot;&gt;&lt;p&gt;Tom Hardy&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-gender&quot; id=&quot;block-4&quot;&gt;&lt;p&gt;м&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-age&quot; id=&quot;block-5&quot;&gt;&lt;p&gt;40/10.10.1986&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-home&quot; id=&quot;block-6&quot;&gt;&lt;p&gt;район саутгейт&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-work&quot; id=&quot;block-7&quot;&gt;&lt;div class=&quot;m-job&quot; id=&quot;block-12&quot;&gt;&lt;p&gt;общественная сфера&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-job-pl&quot; id=&quot;block-8&quot;&gt;&lt;p&gt;old cranky cemetery&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-job-t&quot; id=&quot;block-9&quot;&gt;&lt;p&gt;владелец&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;m-about&quot; id=&quot;block-10&quot;&gt;&lt;p&gt;i should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change me&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</description>
			<author>mybb@mybb.ru (skadi)</author>
			<pubDate>Tue, 16 Jun 2026 21:09:49 +0300</pubDate>
			<guid>https://skaditest5.rusff.me/viewtopic.php?pid=6#p6</guid>
		</item>
		<item>
			<title>анкета проверочная два</title>
			<link>https://skaditest5.rusff.me/viewtopic.php?pid=4#p4</link>
			<description>&lt;div class=&quot;m-ank&quot; id=&quot;block-13&quot;&gt;&lt;div class=&quot;m-name&quot; id=&quot;block-23&quot;&gt;&lt;p&gt;Lane Mine&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-name-r&quot; id=&quot;block-14&quot;&gt;&lt;p&gt;Лейн Майн&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-face&quot; id=&quot;block-15&quot;&gt;&lt;p&gt;Jenna Coleman&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-gender&quot; id=&quot;block-16&quot;&gt;&lt;p&gt;ж&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-age&quot; id=&quot;block-17&quot;&gt;&lt;p&gt;43/10.10.1986&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-home&quot; id=&quot;block-18&quot;&gt;&lt;p&gt;район саутгейт&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-work&quot; id=&quot;block-19&quot;&gt;&lt;div class=&quot;m-job&quot; id=&quot;block-24&quot;&gt;&lt;p&gt;коммерческая сфера&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-job-pl&quot; id=&quot;block-20&quot;&gt;&lt;p&gt;The Esoteric Store&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-job-t&quot; id=&quot;block-21&quot;&gt;&lt;p&gt;владелец&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;m-about&quot; id=&quot;block-22&quot;&gt;&lt;p&gt;i should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change me&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</description>
			<author>mybb@mybb.ru (skadi)</author>
			<pubDate>Tue, 16 Jun 2026 20:30:43 +0300</pubDate>
			<guid>https://skaditest5.rusff.me/viewtopic.php?pid=4#p4</guid>
		</item>
		<item>
			<title>анкета проверочная раз</title>
			<link>https://skaditest5.rusff.me/viewtopic.php?pid=2#p2</link>
			<description>&lt;div class=&quot;m-ank&quot; id=&quot;block-25&quot;&gt;&lt;div class=&quot;m-name&quot; id=&quot;block-35&quot;&gt;&lt;p&gt;Jane Dow&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-name-r&quot; id=&quot;block-26&quot;&gt;&lt;p&gt;Джейн Доу&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-face&quot; id=&quot;block-27&quot;&gt;&lt;p&gt;Jenna Coleman&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-gender&quot; id=&quot;block-28&quot;&gt;&lt;p&gt;ж&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-age&quot; id=&quot;block-29&quot;&gt;&lt;p&gt;40/10.10.1986&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-home&quot; id=&quot;block-30&quot;&gt;&lt;p&gt;район саутгейт&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-work&quot; id=&quot;block-31&quot;&gt;&lt;div class=&quot;m-job&quot; id=&quot;block-36&quot;&gt;&lt;p&gt;коммерческая сфера&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-job-pl&quot; id=&quot;block-32&quot;&gt;&lt;p&gt;The Esoteric Store&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;m-job-t&quot; id=&quot;block-33&quot;&gt;&lt;p&gt;сотрудница&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;m-about&quot; id=&quot;block-34&quot;&gt;&lt;p&gt;i should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change mei should be motherfucking crazy,nothing in this world could change me&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</description>
			<author>mybb@mybb.ru (skadi)</author>
			<pubDate>Tue, 16 Jun 2026 18:58:32 +0300</pubDate>
			<guid>https://skaditest5.rusff.me/viewtopic.php?pid=2#p2</guid>
		</item>
	</channel>
</rss>
