PageSourceSearch

http://aquagroup.ru/admin-mockup-v1/assets/app.js

js aquagroup.ru collected 2026-10-04 13:27:41 UTC 9,529 bytes, 198 lines download raw bytes

1/* Aquario ONE admin // общий motion-слой для макетов */
2(function () {
3  'use strict';
4  var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
5
6  /* --- Reveal со стаггером по мере прокрутки --- */
7  function initReveal() {
8    var els = [].slice.call(document.querySelectorAll('.reveal'));
9    if (reduce || !('IntersectionObserver' in window)) {
10      els.forEach(function (e) { e.classList.add('in'); });
11      return;
12    }
13    var io = new IntersectionObserver(function (entries) {
14      entries.forEach(function (en) {
15        if (!en.isIntersecting) return;
16        var el = en.target;
17        var d = parseInt(el.getAttribute('data-delay') || '0', 10);
18        setTimeout(function () { el.classList.add('in'); }, d);
19        io.unobserve(el);
20      });
21    }, { threshold: 0.08, rootMargin: '0px 0px -40px 0px' });
22    els.forEach(function (e) { io.observe(e); });
23  }
24
25  /* --- Ripple на кнопках --- */
26  function initRipple() {
27    document.addEventListener('pointerdown', function (e) {
28      var btn = e.target.closest('.btn');
29      if (!btn || reduce) return;
30      var r = btn.getBoundingClientRect();
31      var size = Math.max(r.width, r.height);
32      var s = document.createElement('span');
33      s.className = 'ripple';
34      s.style.width = s.style.height = size + 'px';
35      s.style.left = (e.clientX - r.left - size / 2) + 'px';
36      s.style.top = (e.clientY - r.top - size / 2) + 'px';
37      btn.appendChild(s);
38      setTimeout(function () { s.remove(); }, 600);
39    });
40  }
41
42  /* --- Count-up для чисел [data-count] --- */
43  function initCounters() {
44    var els = [].slice.call(document.querySelectorAll('[data-count]'));
45    function run(el) {
46      var target = parseFloat(el.getAttribute('data-count'));
47      var dec = parseInt(el.getAttribute('data-dec') || '0', 10);
48      var suf = el.getAttribute('data-suffix') || '';
49      if (reduce) { el.textContent = fmt(target, dec) + suf; return; }
50      var dur = 1100, start = null;
51      function step(ts) {
52        if (!start) start = ts;
53        var p = Math.min((ts - start) / dur, 1);
54        var e = 1 - Math.pow(1 - p, 3);
55        el.textContent = fmt(target * e, dec) + suf;
56        if (p < 1) requestAnimationFrame(step);
57      }
58      requestAnimationFrame(step);
59    }
60    function fmt(n, dec) {
61      return n.toLocaleString('ru-RU', { minimumFractionDigits: dec, maximumFractionDigits: dec });
62    }
63    if (!('IntersectionObserver' in window)) { els.forEach(run); return; }
64    var io = new IntersectionObserver(function (en) {
65      en.forEach(function (x) { if (x.isIntersecting) { run(x.target); io.unobserve(x.target); } });
66    }, { threshold: 0.5 });
67    els.forEach(function (e) { io.observe(e); });
68  }
69
70  /* --- Простые тогглы (switch, tab, segmented, chip-select) --- */
71  function initToggles() {
72    document.addEventListener('click', function (e) {
73      var sw = e.target.closest('.switch');
74      if (sw) { sw.classList.toggle('on'); }
75
76      var seg = e.target.closest('.segmented button, .tabs .tab');
77      if (seg) {
78        var group = seg.closest('.segmented, .tabs');
79        group.querySelectorAll('.active').forEach(function (a) { a.classList.remove('active'); });
80        seg.classList.add('active');
81      }
82    });
83  }
84
85  /* --- Рисование SVG-кривых (stroke-dashoffset) при появлении --- */
86  function initDrawPaths() {
87    var paths = [].slice.call(document.querySelectorAll('.draw'));
88    paths.forEach(function (p) {
89      try {
90        var len = p.getTotalLength();
91        p.style.strokeDasharray = len;
92        p.style.strokeDashoffset = reduce ? 0 : len;
93      } catch (err) {}
94    });
95    if (reduce || !('IntersectionObserver' in window)) {
96      paths.forEach(function (p) { p.style.strokeDashoffset = 0; });
97      return;
98    }
99    var io = new IntersectionObserver(function (en) {
100      en.forEach(function (x) {
101        if (!x.isIntersecting) return;
102        var p = x.target;
103        p.style.transition = 'stroke-dashoffset 1.6s var(--ease-out)';
104        p.style.strokeDashoffset = 0;
105        io.unobserve(p);
106      });
107    }, { threshold: 0.3 });
108    paths.forEach(function (p) { io.observe(p); });
109  }
110
111  /* --- Иконки (line, 24px, currentColor) --- */
112  var ICON = {
113    dashboard: '<path d="M3 13h8V3H3v10Zm0 8h8v-6H3v6Zm10 0h8V11h-8v10Zm0-18v6h8V3h-8Z"/>',
114    equipment: '<path d="M12 2v4m0 12v4M4.9 4.9l2.8 2.8m8.6 8.6 2.8 2.8M2 12h4m12 0h4M4.9 19.1l2.8-2.8m8.6-8.6 2.8-2.8"/><circle cx="12" cy="12" r="3.4"/>',
115    files: '<path d="M4 5a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5Z"/>',
116    tags: '<path d="M3 7v5.6a2 2 0 0 0 .6 1.4l7.4 7.4a2 2 0 0 0 2.8 0l5.6-5.6a2 2 0 0 0 0-2.8L12 5.6A2 2 0 0 0 10.6 5H5a2 2 0 0 0-2 2Z"/><circle cx="7.5" cy="9.5" r="1.4"/>
116',
117    fields: '<rect x="3" y="4" width="18" height="4" rx="1.2"/><rect x="3" y="10" width="18" height="4" rx="1.2"/><rect x="3" y="16" width="11" height="4" rx="1.2"/>',
118    partners: '<circle cx="9" cy="8" r="3.2"/><path d="M3 20c0-3.3 2.7-5.5 6-5.5M16 11l2 2 4-4"/>',
119    orders: '<path d="M8 6h12M8 12h12M8 18h12M3.5 6h.01M3.5 12h.01M3.5 18h.01"/>',
120    chart: '<path d="M4 19V5m0 14h16M8 15l3-4 3 2.5L20 8"/>',
121    cube: '<path d="m12 2 8 4.5v9L12 20l-8-4.5v-9L12 2Zm0 0v18m8-13.5L12 11 4 6.5"/>',
122    search: '<circle cx="11" cy="11" r="7"/><path d="m20 20-3.2-3.2"/>',
123    chevron: '<path d="m9 6 6 6-6 6"/>',
124    settings: '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.6 1.6 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.6 1.6 0 0 0-2.7 1.1V21a2 2 0 1 1-4 0v-.1A1.6 1.6 0 0 0 7 19.4l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1A1.6 1.6 0 0 0 3 12a2 2 0 1 1 0-4 1.6 1.6 0 0 0 1.1-2.7l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1A1.6 1.6 0 0 0 9 3.6V3a2 2 0 1 1 4 0v.1A1.6 1.6 0 0 0 17 4.6l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1A1.6 1.6 0 0 0 21 9a2 2 0 1 1 0 4 1.6 1.6 0 0 0-1.6 2Z"/>',
125    bell: '<path d="M6 9a6 6 0 1 1 12 0c0 5 2 6 2 6H4s2-1 2-6Zm3.5 9a2.5 2.5 0 0 0 5 0"/>'
126  };
127  window.AQ_ICON = ICON;
128  function svg(name, cls) {
129    return '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" ' +
130      'stroke-linecap="round" stroke-linejoin="round"' + (cls ? ' class="' + cls + '"' : '') + '>' +
131      (ICON[name] || '') + '</svg>';
132  }
133  window.AQ_SVG = svg;
134
135  var NAV = [
136    { group: 'Каталог', items: [
137      { id: 'dashboard', label: 'Дашборд', icon: 'dashboard', href: '01-dashboard.html' },
138      { id: 'equipment', label: 'Оборудование', icon: 'equipment', href: '02-equipment.html', badge: '248' },
139      { id: 'files', label: 'Файлы', icon: 'files', href: '03-files.html', badge: '1.2k' }
140    ]},
141    { group: 'Таксономия', items: [
142      { id: 'tags', label: 'Теги объектов', icon: 'tags', href: '04-taxonomy.html' },
143      { id: 'fields', label: 'Поля объектов', icon: 'fields', href: '04-taxonomy.html' }
144    ]},
145    { group: 'Сеть', items: [
146      { id: 'partners', label: 'Партнёры', icon: 'partners', href: '#', badge: '64' },
147      { id: 'orders', label: 'Порядок', icon: 'orders', href: '#' }
148    ]},
149    { group: 'Система', items: [
150      { id: 'ds', label: 'Дизайн-система', icon: 'cube', href: 'design-system.html' }
151    ]}
152  ];
153
154  /* --- Сборка фона + сайдбара (единый хром на всех страницах) --- */
155  function buildChrome() {
156    var page = document.body.getAttribute('data-page');
157    if (!document.querySelector('.bg-ambient')) {
158      var bg = document.createElement('div');
159      bg.className = 'bg-ambient';
160      bg.innerHTML = '<div class="blob b1"></div><div class="blob b2"></div><div class="blob b3"></div>' +
161        '<div class="grid"></div><div class="vignette"></div>';
162      var bw = document.body.getAttribute('data-bgword');
163      if (bw) {
164        var lines = bw.split('|').map(function (w) { return '<div>' + w + '</div>'; }).join('');
165        bg.innerHTML += '<div class="word">' + lines + '</div>';
166      }
167      document.body.insertBefore(bg, document.body.firstChild);
168    }
169    var mount = document.querySelector('[data-sidebar]');
170    if (!mount) return;
171    var nav = NAV.map(function (g) {
172      return '<div class="nav__label">' + g.group + '</div>' + g.items.map(function (it) {
173        return '<a class="nav__item' + (it.id === page ? ' active' : '') + '" href="' + it.href + '">' +
174          svg(it.icon) + '<span>' + it.label + '</span>' +
175          (it.badge ? '<span class="badge badge--brand">' + it.badge + '</span>' : '') + '</a>';
176      }).join('');
177    }).join('');
178    mount.innerHTML =
179      '<div class="sidebar__brand">' +
180        '<div class="mark"><img src="assets/logo-icon.svg" alt="Aquario"></div>' +
181        '<div><div class="name">Aquario<span> ONE</span></div>' +
182        '<div class="sub">admin</div></div>' +
183      '</div>' +
184      '<nav class="nav">' + nav + '</nav>' +
185      '<div class="sidebar__foot"><div class="userchip">' +
186        '<div class="avatar">МК</div>' +
187        '<div class="meta"><b>Максим К.</b><br><small>Администратор</small></div>' +
188        '<span style="margin-left:auto;color:var(--text-3)">' + svg('settings') + '</span>' +
189      '</div></div>';
190  }
191
192  function boot() {
193    buildChrome();
194    initReveal(); initRipple(); initCounters(); initToggles(); initDrawPaths();
195  }
196  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot);
197  else boot();
198})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.