<?xml version="1.0" encoding="windows-1251"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="https://mistakeno.rusff.me/export.php?type=rss" rel="self" type="application/rss+xml" />
		<title>Mistake Not</title>
		<link>https://mistakeno.rusff.me/</link>
		<description>Mistake Not</description>
		<language>ru-ru</language>
		<lastBuildDate>Sun, 26 Jul 2026 08:57:32 +0300</lastBuildDate>
		<generator>MyBB/mybb.ru</generator>
		<item>
			<title>Новая тема</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=261#p261</link>
			<description>&lt;p&gt;ап&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Mistake Not)</author>
			<pubDate>Sun, 26 Jul 2026 08:57:32 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=261#p261</guid>
		</item>
		<item>
			<title>Закрепленная тема</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=260#p260</link>
			<description>&lt;div class=&quot;quote-box spoiler-box&quot;&gt;&lt;div onclick=&quot;$(this).toggleClass(&#039;visible&#039;); $(this).next().toggleClass(&#039;visible&#039;);&quot;&gt;cg&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;d ddd&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;</description>
			<author>mybb@mybb.ru (Mistake Not)</author>
			<pubDate>Mon, 20 Jul 2026 12:52:00 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=260#p260</guid>
		</item>
		<item>
			<title>Проверочная тема</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=252#p252</link>
			<description>&lt;p&gt;@Mistake Not вот так вот&lt;/p&gt;</description>
			<author>mybb@mybb.ru (test)</author>
			<pubDate>Tue, 30 Jun 2026 09:34:05 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=252#p252</guid>
		</item>
		<item>
			<title>Очень важная тема для проверки некоторых идей</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=247#p247</link>
			<description>&lt;p&gt;so it is anothr post&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Mistake Not)</author>
			<pubDate>Mon, 29 Jun 2026 15:37:23 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=247#p247</guid>
		</item>
		<item>
			<title>эпизод</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=225#p225</link>
			<description>&lt;p&gt;@смайлоносец&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Mistake Not)</author>
			<pubDate>Thu, 18 Jun 2026 14:11:20 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=225#p225</guid>
		</item>
		<item>
			<title>Закрытая тема</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=210#p210</link>
			<description>&lt;p&gt;@смайлоносец&amp;#160; приветики&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Mistake Not)</author>
			<pubDate>Thu, 18 Jun 2026 05:14:54 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=210#p210</guid>
		</item>
		<item>
			<title>Тема для опроса</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=207#p207</link>
			<description>&lt;p&gt;&lt;strong&gt;Mistake Not&lt;/strong&gt;, не грусти, похрусти&lt;/p&gt;</description>
			<author>mybb@mybb.ru (смайлоносец)</author>
			<pubDate>Thu, 18 Jun 2026 05:04:49 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=207#p207</guid>
		</item>
		<item>
			<title>Стандартная тема</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=143#p143</link>
			<description>&lt;p&gt;синий водяной пистолет &lt;img class=&quot;postimg&quot; loading=&quot;lazy&quot; src=&quot;https://forumstatic.ru/files/001c/56/64/21977.webp?v=1&quot; alt=&quot;https://forumstatic.ru/files/001c/56/64/21977.webp?v=1&quot; /&gt; из темы &lt;a href=&quot;https://mistakeno.rusff.me/viewtopic.php?id=3#p141&quot;&gt;Стандартная тема&lt;/a&gt;&lt;/p&gt;</description>
			<author>mybb@mybb.ru (test)</author>
			<pubDate>Sun, 07 Jun 2026 06:44:32 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=143#p143</guid>
		</item>
		<item>
			<title>script</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=105#p105</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;!-- SPRING by @vatueil --&amp;gt;
&amp;lt;script&amp;gt;
/*
 * christmas ornaments
 * version: v1.1.0
 * copyright (c) 2026 @vatueil for executecross.ru
 * need &amp;lt;div id=&amp;quot;springOrnaments&amp;quot;&amp;gt;&amp;lt;/div&amp;gt; in html bottom
 */


class UniqueSelector {
  static getElementSelector(element) {
    if (element._uniqueSelectorCache) {
      return element._uniqueSelectorCache;
    }
    
    if (element.id) {
      const selector = `#${CSS.escape(element.id)}`;
      element._uniqueSelectorCache = selector;
      return selector;
    }
    
    if (element.tagName === &#039;BODY&#039;) {
      element._uniqueSelectorCache = &#039;body&#039;;
      return &#039;body&#039;;
    }
    
    let selector = element.tagName.toLowerCase();
    
    if (element.className &amp;amp;&amp;amp; typeof element.className === &#039;string&#039;) {
      const className = element.className.trim();
      if (className) {
        const classList = className.split(/\s+/).filter(cls =&amp;gt; 
          cls &amp;amp;&amp;amp; cls !== &#039;highlight&#039; &amp;amp;&amp;amp; cls !== &#039;decoratable&#039; &amp;amp;&amp;amp; cls !== &#039;ornaments-container&#039;
        );
        if (classList.length &amp;gt; 0) {
          selector += &#039;.&#039; + classList.map(c =&amp;gt; CSS.escape(c)).join(&#039;.&#039;);
        }
      }
    }
    
    const parent = element.parentNode;
    if (parent &amp;amp;&amp;amp; parent.children &amp;amp;&amp;amp; parent.children.length &amp;gt; 1) {
      let index = 1;
      for (let i = 0; i &amp;lt; parent.children.length; i++) {
        if (parent.children[i] === element) {
          selector += `:nth-child(${index})`;
          break;
        }
        index++;
      }
    }
    
    element._uniqueSelectorCache = selector;
    return selector;
  }

  static getUniqueSelector(element) {
    let selector = this.getElementSelector(element);
    let elements;
    
    try {
      elements = document.querySelectorAll(selector);
    } catch (e) {
      return selector;
    }
    
    if (elements.length === 1) {
      return selector;
    }

    let bestSelector = selector;
    let bestCount = elements.length;

    const queryCache = new Map();
    const queryElements = (sel) =&amp;gt; {
      if (queryCache.has(sel)) {
        return queryCache.get(sel);
      }
      try {
        const result = document.querySelectorAll(sel);
        queryCache.set(sel, result);
        return result;
      } catch {
        return [];
      }
    };

    let parent = element.parentElement;
    while (parent) {
      if (parent.id) {
        const parentSelector = `#${CSS.escape(parent.id)} ${selector}`;
        elements = queryElements(parentSelector);
        if (elements.length === 1) {
          UniqueSelector.clearCache(parent);
          return parentSelector;
        }
        if (elements.length &amp;lt; bestCount) {
          bestSelector = parentSelector;
          bestCount = elements.length;
        }
      }
      parent = parent.parentElement;
    }

    const usedParentClasses = new Set();
    parent = element.parentElement;
    
    while (parent &amp;amp;&amp;amp; parent.tagName !== &#039;BODY&#039;) {
      const classList = Array.from(parent.classList).filter(c =&amp;gt; 
        !usedParentClasses.has(c) &amp;amp;&amp;amp; 
        c !== &#039;highlight&#039; &amp;amp;&amp;amp; 
        c !== &#039;decoratable&#039; &amp;amp;&amp;amp; 
        c !== &#039;ornaments-container&#039;
      );
      
      for (const cls of classList) {
        const parentSelector = `.${CSS.escape(cls)} ${selector}`;
        elements = queryElements(parentSelector);
        if (elements.length === 1) {
          UniqueSelector.clearCache(parent);
          return parentSelector;
        }
        if (elements.length &amp;lt; bestCount) {
          bestSelector = parentSelector;
          bestCount = elements.length;
        }
        usedParentClasses.add(cls);
      }
      parent = parent.parentElement;
    }

    parent = element.parentElement;
    let selectors = [selector];
    
    while (parent &amp;amp;&amp;amp; parent.tagName !== &#039;BODY&#039;) {
      const parentSelector = this.getElementSelector(parent);
      const newSelectors = [];
      
      for (const sel of selectors) {
        const newSelector = `${parentSelector} ${sel}`;
        newSelectors.push(newSelector);
        elements = queryElements(newSelector);
        if (elements.length === 1) {
          UniqueSelector.clearCache(parent);
          return newSelector;
        }
        if (elements.length &amp;lt; bestCount) {
          bestSelector = newSelector;
          bestCount = elements.length;
        }
      }
      
      selectors = newSelectors;
      parent = parent.parentElement;
    }

    return bestSelector;
  }

  static clearCache(element) {
    delete element._uniqueSelectorCache;
  }
}

class ForumDecorator {
  constructor(config) {
    this.config = {
      decoratableSelectors: [&#039;.pa-author, .pa-posts, .pa-fld3, .pa-fld2&#039;, &#039;#profile-name, #pa-fld3 strong, #pa-fld2 strong, #pa-posts a&#039;, &#039;#pun-navlinks li:not(#navlogout)&#039;, &#039;.crumbs a&#039;, &#039;.pa-fld1 .lz-name&#039;, &#039;#post-form h2 span&#039;, &#039;.permalink, .postlink a&#039;, &#039;.tclcon h3 a, .tcl h3 a, .pf &amp;gt; a, .lastpost-link, .avatar-image&#039;, &#039;.button&#039;, &#039;#pun-status .container&#039;, &amp;quot;.statscon span&amp;quot;, &amp;quot;h1 span&amp;quot;, &amp;quot;.announce-btn, #pun-announcement .character-wrapper&amp;quot;],
      maxOrnaments: 2025,
      ornamentCategories: [
        {
          name: &#039;Цветы&#039;,
          images: [
            &amp;quot;https://forumstatic.ru/files/001b/f1/8a/42536.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001b/f1/8a/32614.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001b/f1/8a/63068.png?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001b/f1/8a/39327.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/45666.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/14658.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/96576.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/66356.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/88283.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/36804.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/56082.webp?v=1&amp;quot;,
          ]
        },
        {
          name: &#039;Зелень&#039;,
          images: [
            &amp;quot;https://forumstatic.ru/files/001b/f1/8a/30630.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/25010.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/66763.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/54117.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/46868.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/14096.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/67503.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/92313.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/34272.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/72885.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/55623.webp?v=1&amp;quot;

          ]
        },
        {
          name: &#039;Бабочки&#039;,
          images: [
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/86329.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/76207.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/63953.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001b/f1/8a/15694.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/28830.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/89872.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/22835.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/68567.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/91548.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/53938.webp?v=1&amp;quot;,
            &amp;quot;https://forumstatic.ru/files/001c/7f/71/79345.webp?v=1&amp;quot;,
          ]
        }
      ],
      storageKey: &#039;forum_decor_spring&#039;,
      ...config
    };
    
    this.ornaments = [];
    this.draggingFromCollection = null;
    this.isPanelCollapsed = this.loadPanelState();
    this.currentTab = 0;
    
    this.decoratableElements = null;
    this.decoratableCacheTime = 0;
    this.cacheTTL = 1000;
    
    this.save = this.debounce(this.save.bind(this), 500);
    
    this.preloadedImages = new Set();
    
    this.init();
  }
  
  init() {
    this.createContainer();
    this.markDecoratableElements();
    this.createCollectionPanel();
    this.preloadImages();
    this.loadSavedDecorations();
    this.setupGlobalEvents();
  }
  
  createContainer() {
    this.container = document.getElementById(&#039;springOrnaments&#039;) || 
      document.body.appendChild(document.createElement(&#039;div&#039;));
    this.container.id = &#039;springOrnaments&#039;;
  }
  
  markDecoratableElements() {
    const fragment = document.createDocumentFragment();
    
    this.config.decoratableSelectors.forEach(selector =&amp;gt; {
      try {
        const elements = document.querySelectorAll(selector);
        elements.forEach(el =&amp;gt; {
          el.classList.add(&#039;decoratable&#039;);
          if (!el.querySelector(&#039;.ornaments-container&#039;)) {
            const container = document.createElement(&#039;div&#039;);
            container.className = &#039;ornaments-container spring&#039;;
            el.appendChild(container);
          }
        });
      } catch (e) {
        console.warn(&#039;Неверный селектор:&#039;, selector, e);
      }
    });
  }
  
  getDecoratableElements() {
    const now = Date.now();
    if (!this.decoratableElements || (now - this.decoratableCacheTime) &amp;gt; this.cacheTTL) {
      this.decoratableElements = [];
      this.config.decoratableSelectors.forEach(selector =&amp;gt; {
        try {
          const elements = document.querySelectorAll(selector);
          this.decoratableElements.push(...elements);
        } catch (e) {
          console.warn(&#039;Ошибка в селекторе:&#039;, selector);
        }
      });
      this.decoratableCacheTime = now;
    }
    return this.decoratableElements;
  }
  
  debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
      const later = () =&amp;gt; {
        clearTimeout(timeout);
        func(...args);
      };
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
    };
  }
  
  preloadImages() {
    const allImages = this.getAllImages();
    allImages.forEach(src =&amp;gt; {
      if (!this.preloadedImages.has(src)) {
        const img = new Image();
        img.src = src;
        this.preloadedImages.add(src);
      }
    });
  }
  
  createCollectionPanel() {
    this.panel = document.createElement(&#039;div&#039;);
    this.panel.className = `ornament-collection ${this.isPanelCollapsed ? &#039;collapsed&#039; : &#039;&#039;}`;
    
    const tabsHTML = this.config.ornamentCategories.map((cat, index) =&amp;gt; 
      `&amp;lt;div class=&amp;quot;collection-tab ${index === 0 ? &#039;active&#039; : &#039;&#039;}&amp;quot; data-tab=&amp;quot;${index}&amp;quot;&amp;gt;${cat.name}&amp;lt;/div&amp;gt;`
    ).join(&#039;&#039;);
    
    this.panel.innerHTML = `
      &amp;lt;div class=&amp;quot;collection-toggle&amp;quot;&amp;gt;
        &amp;lt;i class=&amp;quot;fi fi-ss-flower-tulip&amp;quot;&amp;gt;&amp;lt;/i&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;collection-tabs&amp;quot;&amp;gt;${tabsHTML}&amp;lt;/div&amp;gt;
      ${this.config.ornamentCategories.map((_, index) =&amp;gt; 
        `&amp;lt;div class=&amp;quot;collection-items ${index === 0 ? &#039;&#039; : &#039;hidden&#039;}&amp;quot; data-tab-content=&amp;quot;${index}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;`
      ).join(&#039;&#039;)}
      &amp;lt;div class=&amp;quot;collection-footer&amp;quot;&amp;gt;
        &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Shift + Click&amp;lt;/strong&amp;gt; чтобы убрать украшение&amp;lt;/p&amp;gt;
        &amp;lt;button class=&amp;quot;button btn-sm&amp;quot; onclick=&amp;quot;window.decor.resetAll()&amp;quot;&amp;gt;
          Сбросить все
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    `;
    
    document.body.appendChild(this.panel);
    
    this.panel.addEventListener(&#039;click&#039;, (e) =&amp;gt; {
      const tab = e.target.closest(&#039;.collection-tab&#039;);
      if (tab) {
        const tabIndex = parseInt(tab.dataset.tab);
        this.switchTab(tabIndex);
      }
    });
    
    requestAnimationFrame(() =&amp;gt; {
      this.updatePanel();
    });

    this.panel.querySelector(&#039;.collection-toggle&#039;).addEventListener(&#039;click&#039;, () =&amp;gt; {
      this.panel.classList.toggle(&#039;collapsed&#039;);
      this.isPanelCollapsed = this.panel.classList.contains(&#039;collapsed&#039;);
      this.savePanelState();
    });
  }

  loadPanelState() {
    return localStorage.getItem(`${this.config.storageKey}_panelState`) === &#039;false&#039; || localStorage.getItem(`${this.config.storageKey}_panelState`) === null ? false : true;
  }

  savePanelState() {
    try {
      localStorage.setItem(
        `${this.config.storageKey}_panelState`, 
        JSON.stringify(this.isPanelCollapsed)
      );
    } catch (e) {
      console.warn(&#039;Не удалось сохранить состояние панели:&#039;, e);
    }
  }  
  
  switchTab(tabIndex) {
    if (this.currentTab === tabIndex) return;
    
    this.currentTab = tabIndex;
    
    this.panel.querySelectorAll(&#039;.collection-tab&#039;).forEach(tab =&amp;gt; {
      tab.classList.toggle(&#039;active&#039;, parseInt(tab.dataset.tab) === tabIndex);
    });
    
    this.panel.querySelectorAll(&#039;.collection-items&#039;).forEach(content =&amp;gt; {
      content.classList.toggle(&#039;hidden&#039;, parseInt(content.dataset.tabContent) !== tabIndex);
    });
    
    requestAnimationFrame(() =&amp;gt; {
      this.updateCurrentTab();
    });
  }
  
  updatePanel() {
    requestAnimationFrame(() =&amp;gt; {
      this.updateCurrentTab();
    });
  }
  
  updateCurrentTab() {
    const currentCategory = this.config.ornamentCategories[this.currentTab];
    const itemsContainer = this.panel.querySelector(`.collection-items[data-tab-content=&amp;quot;${this.currentTab}&amp;quot;]`);
    if (!itemsContainer) return;
    
    const fragment = document.createDocumentFragment();
    
    currentCategory.images.forEach((src, i) =&amp;gt; {
      const globalIndex = this.getGlobalIndex(this.currentTab, i);
      const count = this.ornaments.filter(o =&amp;gt; o.typeIndex === globalIndex).length;
      const isAvailable = count &amp;lt; 3;
      
      const btn = document.createElement(&#039;div&#039;);
      btn.className = &#039;collection-ornament spring&#039;;
      btn.dataset.category = this.currentTab;
      btn.dataset.index = i;
      btn.draggable = isAvailable;
      
      if (!isAvailable) {
        btn.style.opacity = &#039;0.4&#039;;
        btn.style.cursor = &#039;not-allowed&#039;;
      } else {
        btn.addEventListener(&#039;dragstart&#039;, (e) =&amp;gt; this.startDragFromCollection(e, src, globalIndex));
        btn.addEventListener(&#039;dragend&#039;, () =&amp;gt; this.endDragFromCollection());
      }
      
      this.createOrnamentElement(btn, src);
      fragment.appendChild(btn);
    });
    
    itemsContainer.innerHTML = &#039;&#039;;
    itemsContainer.appendChild(fragment);
  }
  
  getGlobalIndex(categoryIndex, itemIndex) {
    let globalIndex = 0;
    for (let i = 0; i &amp;lt; categoryIndex; i++) {
      globalIndex += this.config.ornamentCategories[i].images.length;
    }
    return globalIndex + itemIndex;
  }
  
  getCategoryInfo(globalIndex) {
    let accumulated = 0;
    for (let i = 0; i &amp;lt; this.config.ornamentCategories.length; i++) {
      const category = this.config.ornamentCategories[i];
      if (globalIndex &amp;lt; accumulated + category.images.length) {
        return {
          categoryIndex: i,
          categoryName: category.name,
          image: category.images[globalIndex - accumulated],
          localIndex: globalIndex - accumulated
        };
      }
      accumulated += category.images.length;
    }
    return null;
  }
  
  getAllImages() {
    return this.config.ornamentCategories.reduce((all, cat) =&amp;gt; 
      all.concat(cat.images), []);
  }
  
  createOrnamentElement(container, src) {
    const img = document.createElement(&#039;img&#039;);
    img.src = src;
    img.loading = &#039;lazy&#039;;
    img.style.width = &#039;100%&#039;;
    img.style.height = &#039;100%&#039;;
    img.style.objectFit = &#039;contain&#039;;
    img.draggable = false;
    
    container.appendChild(img);
    return img;
  }
  
  startDragFromCollection(e, src, typeIndex) {
    if (this.ornaments.length &amp;gt;= this.config.maxOrnaments) {
      $.jGrowl(&#039;&amp;lt;i class=&amp;quot;fi fi-ss-flower-daffodil&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Лимит украшений достигнут&#039;);
      e.preventDefault();
      return;
    }
    
    this.draggingFromCollection = { src, typeIndex };
    e.dataTransfer.setData(&#039;text/plain&#039;, &#039;from_collection&#039;);
    e.dataTransfer.effectAllowed = &#039;copy&#039;;
    
    if (!this.dragGhost) {
      this.dragGhost = document.createElement(&#039;div&#039;);
      this.dragGhost.className = &#039;forum-ornament spring&#039;;
      this.dragGhost.style.position = &#039;fixed&#039;;
      this.dragGhost.style.left = &#039;-100px&#039;;
      this.dragGhost.style.pointerEvents = &#039;none&#039;;
      this.dragGhost.style.zIndex = &#039;99&#039;;
      document.body.appendChild(this.dragGhost);
    }
    
    this.dragGhost.innerHTML = &#039;&#039;;
    this.createOrnamentElement(this.dragGhost, src);
    e.dataTransfer.setDragImage(this.dragGhost, 20, 20);
    
    const elements = this.getDecoratableElements();
    for (const el of elements) {
      el.classList.add(&#039;highlight&#039;);
    }
  }
  
  endDragFromCollection() {
    this.draggingFromCollection = null;
    
    const elements = this.getDecoratableElements();
    for (const el of elements) {
      el.classList.remove(&#039;highlight&#039;);
    }
  }
  
  createOrnament(src, typeIndex, x, y) {
    if (this.ornaments.length &amp;gt;= this.config.maxOrnaments) {
      $.jGrowl(&#039;&amp;lt;i class=&amp;quot;fi fi-ss-flower-daffodil&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Лимит украшений!&#039;);
      return null;
    }
    
    const id = `o_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
    const o = document.createElement(&#039;div&#039;);
    o.className = &#039;forum-ornament spring&#039;;
    o.dataset.id = id;
    o.dataset.typeIndex = typeIndex;
    
    this.createOrnamentElement(o, src);
    o.style.left = `${x}px`;
    o.style.top = `${y}px`;
    o.draggable = true;
    
    o.addEventListener(&#039;dragstart&#039;, (e) =&amp;gt; this.dragStart(e, o));
    o.addEventListener(&#039;dragend&#039;, (e) =&amp;gt; this.dragEnd(e, o));
    
    this.container.appendChild(o);
    
    const data = {
      element: o, 
      typeIndex, 
      attachedTo: null, 
      pos: null, 
      selector: null,
      id
    };
    
    this.ornaments.push(data);
    
    requestAnimationFrame(() =&amp;gt; {
      this.updatePanel();
    });
    
    return data;
  }
  
  handleDrop(e) {
    e.preventDefault();
    e.stopPropagation();
    
    if (!this.draggingFromCollection) return;
    
    const { src, typeIndex } = this.draggingFromCollection;
    const target = document.elementFromPoint(e.clientX, e.clientY);
    const decorEl = this.findDecoratable(target, e.clientX, e.clientY);
    
    if (decorEl) {
      decorEl.classList.remove(&#039;highlight&#039;);
      const selector = UniqueSelector.getUniqueSelector(decorEl);
      
      if (!selector || selector === &#039;&#039;) {
        $.jGrowl(&#039;Ошибка сохранения позиции&#039;);
        this.endDragFromCollection();
        return;
      }
      
      try {
        const elements = document.querySelectorAll(selector);
        if (elements.length === 0 || (elements.length &amp;gt; 1 &amp;amp;&amp;amp; !Array.from(elements).includes(decorEl))) {
          $.jGrowl(&#039;Ошибка уникальности селектора&#039;);
          this.endDragFromCollection();
          return;
        }
        
        this.attachNewOrnament(src, typeIndex, decorEl, selector, e.clientX, e.clientY);
      } catch(err) {
        $.jGrowl(&#039;Неизвестная ошибка&#039;);
        this.endDragFromCollection();
        return;
      }
    } else {
      const x = Math.max(10, Math.min(e.clientX - 20, window.innerWidth - 50));
      const y = Math.max(10, Math.min(e.clientY - 20, window.innerHeight - 50));
      this.createOrnament(src, typeIndex, x, y);
      $.jGrowl(`&amp;lt;i class=&amp;quot;fi fi-ss-flower&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Украшение добавлено`);
    }
    
    this.endDragFromCollection();
  }
  
  attachNewOrnament(src, typeIndex, el, selector, x, y) {
    const data = this.createOrnament(src, typeIndex, -100, -100);
    if (!data) return;
    
    this.attachOrnament(data.element, el, selector, x, y);
  }
  
  findDecoratable(el, clientX, clientY) {
    const decoratable = el.closest(&#039;.decoratable&#039;);
    if (!decoratable) return null;
    
    const rect = decoratable.getBoundingClientRect();
    const ballCenterX = clientX;
    const ballCenterY = clientY;
    
    const isBelow = ballCenterY &amp;gt;= rect.top - 37 &amp;amp;&amp;amp; ballCenterY &amp;lt;= rect.bottom + 20;
    const isHorizontallyAligned = ballCenterX &amp;gt;= rect.left &amp;amp;&amp;amp; ballCenterX &amp;lt;= rect.right;
    
    return isBelow &amp;amp;&amp;amp; isHorizontallyAligned ? decoratable : null;
  }
  
  dragStart(e, o) {
    o.classList.add(&#039;dragging&#039;);
    e.dataTransfer.setData(&#039;text&#039;, o.dataset.id);
    
    const elements = this.getDecoratableElements();
    for (const el of elements) {
      el.classList.add(&#039;highlight&#039;);
    }
  }
  
  dragEnd(e, o) {
    o.classList.remove(&#039;dragging&#039;);
    
    const elements = this.getDecoratableElements();
    for (const el of elements) {
      el.classList.remove(&#039;highlight&#039;);
    }
    
    const target = document.elementFromPoint(e.clientX, e.clientY);
    const decorEl = this.findDecoratable(target, e.clientX, e.clientY);
    
    if (decorEl) {
      const selector = UniqueSelector.getUniqueSelector(decorEl);
      if (selector &amp;amp;&amp;amp; selector !== &#039;&#039;) {
        this.attachOrnament(o, decorEl, selector, e.clientX, e.clientY);
      } else {
        this.freeOrnament(o, e.clientX, e.clientY);
      }
    } else {
      this.freeOrnament(o, e.clientX, e.clientY);
    }
  }
  
  freeOrnament(o, clientX, clientY) {
    o.style.left = `${Math.max(10, Math.min(clientX - 20, window.innerWidth - 50))}px`;
    o.style.top = `${Math.max(10, Math.min(clientY - 20, window.innerHeight - 50))}px`;
    o.classList.remove(&#039;attached&#039;);
    
    if (o.parentElement !== this.container) {
      this.container.appendChild(o);
    }
    
    const data = this.ornaments.find(d =&amp;gt; d.element === o);
    if (data) {
      data.attachedTo = null;
      data.selector = null;
      data.pos = null;
      this.save();
    }
  }
  
  attachOrnament(o, el, selector, clientX, clientY) {
    let container = el.querySelector(&#039;.ornaments-container&#039;);
    if (!container) {
      container = document.createElement(&#039;div&#039;);
      container.className = &#039;ornaments-container spring&#039;;
      el.appendChild(container);
    }
    
    if (o.parentElement) {
      o.parentElement.removeChild(o);
    }
    
    const rect = el.getBoundingClientRect();
    const relativeX = Math.max(0, Math.min(clientX - rect.left - 20, rect.width - 40));
    const fixedTop = &#039;0&#039;;
    const fixedBottom = &#039;calc(100% - 0.15em - 24px)&#039;;
    
    o.style.position = &#039;absolute&#039;;
    o.style.left = `${relativeX}px`;
    o.style.top = fixedTop;
    o.style.transformOrigin = &#039;bottom center&#039;;
    o.classList.add(&#039;attached&#039;);
    
    container.appendChild(o);
    
    const data = this.ornaments.find(d =&amp;gt; d.element === o);
    if (data) {
      data.attachedTo = selector;
      data.selector = selector;
      data.pos = {
        top: fixedTop,
        left: relativeX,
        width: rect.width,
        page: window.location.pathname + window.location.search
      };
    }
    
    this.save();
    $.jGrowl(&#039;&amp;lt;i class=&amp;quot;fi fi-ss-flower&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Украсили!&#039;);
  }
  
  resolveElementSelector(selector) {
    if (!selector || selector === &#039;&#039;) return null;
    
    try {
      const elements = document.querySelectorAll(selector);
      
      if (elements.length === 0) {
        const parts = selector.split(&#039; &#039;);
        for (let i = 1; i &amp;lt; parts.length; i++) {
          const partial = parts.slice(-i).join(&#039; &#039;);
          const partialElements = document.querySelectorAll(partial);
          if (partialElements.length === 1) return partialElements[0];
        }
        return null;
      }
      
      return elements[0];
    } catch (e) {
      console.warn(&#039;Ошибка разрешения селектора:&#039;, selector, e);
      return null;
    }
  }
  
  removeOrnament(o) {
    const index = this.ornaments.findIndex(d =&amp;gt; d.element === o);
    if (index &amp;gt; -1) {
      this.ornaments.splice(index, 1);
      o.remove();
      
      requestAnimationFrame(() =&amp;gt; {
        this.updatePanel();
        this.save();
      });
    }
  }
  
  loadSavedDecorations() {
    try {
      const currentPage = window.location.pathname + window.location.search;
      const savedData = localStorage.getItem(`${this.config.storageKey}_${currentPage}`);
      
      if (!savedData) return;
      
      const data = JSON.parse(savedData);
      if (!data.ornaments || !Array.isArray(data.ornaments)) return;
      
      const allImages = this.getAllImages();
      const validOrnaments = [];
      const fragment = document.createDocumentFragment();
      const freeOrnaments = [];
      
      data.ornaments.forEach(item =&amp;gt; {
        if (item.typeIndex === undefined || !allImages[item.typeIndex]) {
          return;
        }
        
        const src = allImages[item.typeIndex];
        const o = document.createElement(&#039;div&#039;);
        o.className = &#039;forum-ornament spring&#039;;
        this.createOrnamentElement(o, src);
        o.draggable = true;
        
        o.addEventListener(&#039;dragstart&#039;, (e) =&amp;gt; this.dragStart(e, o));
        o.addEventListener(&#039;dragend&#039;, (e) =&amp;gt; this.dragEnd(e, o));
        
        const ornamentData = {
          element: o,
          typeIndex: item.typeIndex,
          attachedTo: item.attachedTo,
          selector: item.selector || item.attachedTo,
          pos: item.pos
        };
        
        validOrnaments.push(ornamentData);
        
        if (item.attachedTo) {
          const targetEl = this.resolveElementSelector(item.attachedTo);
          if (targetEl) {
            let container = targetEl.querySelector(&#039;.ornaments-container&#039;);
            if (!container) {
              container = document.createElement(&#039;div&#039;);
              container.className = &#039;ornaments-container spring&#039;;
              targetEl.appendChild(container);
            }
            
            container.appendChild(o);
            o.style.position = &#039;absolute&#039;;
            o.style.left = `${item.pos?.left || 0}px`;
            o.style.top = item.pos?.top || &#039;0&#039;;
            o.classList.add(&#039;attached&#039;);
          } else {
            freeOrnaments.push({ o, item });
          }
        } else {
          freeOrnaments.push({ o, item });
        }
      });
      
      freeOrnaments.forEach(({ o, item }) =&amp;gt; {
        if (item.pos &amp;amp;&amp;amp; item.pos.x &amp;amp;&amp;amp; item.pos.y) {
          o.style.left = `${item.pos.x}px`;
          o.style.top = `${item.pos.y}px`;
        } else {
          o.style.left = `${50 + Math.random() * (window.innerWidth - 150)}px`;
          o.style.top = `${50 + Math.random() * (window.innerHeight - 150)}px`;
        }
        fragment.appendChild(o);
      });
      
      this.container.appendChild(fragment);
      this.ornaments = validOrnaments;
      
      requestAnimationFrame(() =&amp;gt; {
        this.updatePanel();
      });
      
      console.log(&#039;Загружено украшений:&#039;, this.ornaments.length);
    } catch(e) {
      console.warn(&#039;Ошибка загрузки украшений:&#039;, e);
    }
  }
  
  save() {
    try {
      const currentPage = window.location.pathname + window.location.search;
      const validOrnaments = this.ornaments.filter(o =&amp;gt; {
        if (o.attachedTo) {
          try {
            return document.querySelector(o.attachedTo) !== null;
          } catch {
            return false;
          }
        }
        return true;
      });
      
      const pageData = {
        ornaments: validOrnaments.map(o =&amp;gt; ({
          typeIndex: o.typeIndex,
          attachedTo: o.attachedTo,
          selector: o.selector,
          pos: o.pos
        })),
        timestamp: Date.now(),
        version: &#039;1.0&#039;
      };
      
      const currentData = JSON.stringify(pageData);
      const savedData = localStorage.getItem(`${this.config.storageKey}_${currentPage}`);
      
      if (savedData !== currentData) {
        localStorage.setItem(`${this.config.storageKey}_${currentPage}`, currentData);
      }
    } catch(e) {
      console.warn(&#039;Ошибка сохранения:&#039;, e);
    }
  }
  
  setupGlobalEvents() {
    document.addEventListener(&#039;dragover&#039;, (e) =&amp;gt; {
      e.preventDefault();
      e.dataTransfer.dropEffect = &#039;copy&#039;;
    }, { passive: false });
    
    document.addEventListener(&#039;drop&#039;, (e) =&amp;gt; this.handleDrop(e), { passive: false });
    
    document.addEventListener(&#039;click&#039;, (e) =&amp;gt; {
      if (e.shiftKey &amp;amp;&amp;amp; e.target.closest(&#039;.forum-ornament&#039;)) {
        const ornament = e.target.closest(&#039;.forum-ornament&#039;);
        this.removeOrnament(ornament);
        $.jGrowl(&#039;&amp;lt;i class=&amp;quot;fi fi-ss-trash-xmark&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Украшение удалено&#039;);
        e.stopPropagation();
      }
    });
    
    const observer = new MutationObserver(() =&amp;gt; {
      this.decoratableElements = null;
      this.decoratableCacheTime = 0;
    });
    
    observer.observe(document.body, {
      childList: true,
      subtree: true,
      attributes: true,
      attributeFilter: [&#039;class&#039;, &#039;id&#039;]
    });
  }
  
  resetAll() {
    if (confirm(&#039;Убрать все украшения?&#039;)) {
      this.ornaments.forEach(o =&amp;gt; o.element.remove());
      this.ornaments = [];
      
      const currentPage = window.location.pathname + window.location.search;
      localStorage.removeItem(`${this.config.storageKey}_${currentPage}`);
      
      requestAnimationFrame(() =&amp;gt; {
        this.updatePanel();
        $.jGrowl(&#039;&amp;lt;i class=&amp;quot;fi fi-ss-flower&amp;quot;&amp;gt;&amp;lt;/i&amp;gt; Все украшения убраны&#039;);
      });
    }
  }
  
  destroy() {
    if (this.dragGhost) {
      this.dragGhost.remove();
    }
  }
}

if (window.matchMedia(&amp;quot;(min-device-width: 768px)&amp;quot;).matches) {
  document.addEventListener(&#039;DOMContentLoaded&#039;, () =&amp;gt; {
    window.decor = new ForumDecorator();
  });
}
&amp;lt;/script&amp;gt;
&amp;lt;!-- SPRING end --&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</description>
			<author>mybb@mybb.ru (Mistake Not)</author>
			<pubDate>Sat, 28 Mar 2026 14:17:07 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=105#p105</guid>
		</item>
		<item>
			<title>черновик</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=94#p94</link>
			<description>&lt;p&gt;@смайлоносец&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Mistake Not)</author>
			<pubDate>Mon, 23 Feb 2026 22:45:55 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=94#p94</guid>
		</item>
		<item>
			<title>Falling Outside the Normal Moral Constraints</title>
			<link>https://mistakeno.rusff.me/viewtopic.php?pid=68#p68</link>
			<description>&lt;p&gt;&lt;img class=&quot;custom_tag custom_tag_eventimg&quot; src=&quot;https://upforme.ru/uploads/001b/f1/8a/207/150708.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;</description>
			<author>mybb@mybb.ru (Mistake Not)</author>
			<pubDate>Thu, 05 Jun 2025 05:25:41 +0300</pubDate>
			<guid>https://mistakeno.rusff.me/viewtopic.php?pid=68#p68</guid>
		</item>
	</channel>
</rss>
