Initial commit: site monorepo with API, web, and infra.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
(function (global) {
|
||||
"use strict";
|
||||
|
||||
const MAX_MS = 5000;
|
||||
const MIN_MS = 2400;
|
||||
const DEFAULT_MS = 4000;
|
||||
|
||||
const SOURCE_LABELS = {
|
||||
agrostar: "Поставка AgroStar",
|
||||
sandbox: "Песочница рациона",
|
||||
formulate: "Автоготовка",
|
||||
lab: "Лаборатория",
|
||||
};
|
||||
|
||||
let overlay = null;
|
||||
let hideTimer = null;
|
||||
|
||||
function ensureOverlay() {
|
||||
if (overlay) return overlay;
|
||||
overlay = document.createElement("div");
|
||||
overlay.id = "labHeisenbergPrime";
|
||||
overlay.className = "lab-heisenberg-prime-overlay";
|
||||
overlay.hidden = true;
|
||||
overlay.innerHTML =
|
||||
'<div class="lab-heisenberg-prime__vignette" aria-hidden="true"></div>' +
|
||||
'<div class="lab-heisenberg-prime__eyes" aria-hidden="true">' +
|
||||
'<span class="lab-heisenberg-prime__eye lab-heisenberg-prime__eye--left"></span>' +
|
||||
'<span class="lab-heisenberg-prime__eye lab-heisenberg-prime__eye--right"></span>' +
|
||||
"</div>" +
|
||||
'<div class="lab-heisenberg-prime__glow" aria-hidden="true"></div>' +
|
||||
'<div class="lab-heisenberg-prime__scanlines" aria-hidden="true"></div>' +
|
||||
'<div class="lab-heisenberg-prime__banner" role="alert" aria-live="assertive">' +
|
||||
'<div class="lab-heisenberg-prime__title">В нашем деле - или ты, или тебя.</div>' +
|
||||
"</div>";
|
||||
document.body.appendChild(overlay);
|
||||
return overlay;
|
||||
}
|
||||
|
||||
function sourceLabel(source) {
|
||||
const key = String(source || "lab").toLowerCase();
|
||||
return SOURCE_LABELS[key] || SOURCE_LABELS.lab;
|
||||
}
|
||||
|
||||
function dismiss() {
|
||||
if (hideTimer) {
|
||||
clearTimeout(hideTimer);
|
||||
hideTimer = null;
|
||||
}
|
||||
document.body.classList.remove("lab-heisenberg-prime-active");
|
||||
if (overlay) overlay.hidden = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} reason — почему сработал prime (показываем пользователю)
|
||||
* @param {{ source?: string, durationMs?: number }} [options]
|
||||
*/
|
||||
function trigger(reason, options) {
|
||||
if (!document.body.classList.contains("lab-sandbox-page")) return;
|
||||
|
||||
const opts = options || {};
|
||||
const text = String(reason || "Что-то пошло не по плану").trim();
|
||||
const duration = Math.min(MAX_MS, Math.max(MIN_MS, Number(opts.durationMs) || DEFAULT_MS));
|
||||
|
||||
global.WespZootechNotify?.dismissAll?.();
|
||||
|
||||
dismiss();
|
||||
|
||||
const el = ensureOverlay();
|
||||
const reasonEl = el.querySelector(".lab-heisenberg-prime__reason");
|
||||
const sourceEl = el.querySelector(".lab-heisenberg-prime__source");
|
||||
if (reasonEl) reasonEl.textContent = text;
|
||||
|
||||
el.hidden = false;
|
||||
requestAnimationFrame(() => {
|
||||
document.body.classList.add("lab-heisenberg-prime-active");
|
||||
});
|
||||
|
||||
hideTimer = setTimeout(dismiss, duration);
|
||||
}
|
||||
|
||||
/** Ошибка на /lab: только prime (без toast/alert — они ломают сцену). */
|
||||
function error(reason, source) {
|
||||
trigger(reason, { source: source || "lab" });
|
||||
}
|
||||
|
||||
global.WespLabHeisenbergPrime = {
|
||||
trigger,
|
||||
dismiss,
|
||||
error,
|
||||
MAX_MS,
|
||||
SOURCE_LABELS,
|
||||
};
|
||||
})(window);
|
||||
Reference in New Issue
Block a user