# 🧠 Эвалюаторы

## 📌 Введение

**Эвалюаторы** — это кастомные JavaScript-функции, которые позволяют гибко управлять персонализацией на основе данных со страницы. С их помощью вы можете реализовать любую бизнес-логику, которая зависит от контекста, пользовательских данных, структуры DOM или даже внешних API.

Эвалюаторы используются:
- для таргетинга в сценариях;
- для динамических фильтров в рекомендациях;
- для вычисления условий показа контента.

---

## 🛠 Где создаются эвалюаторы

Все эвалюаторы настраиваются в интерфейсе платформы:  
**Assets → Evaluators**

### ➕ Как создать эвалюатор

1. Перейдите в раздел **Assets**.
2. Выберите вкладку **Evaluators**.
3. Нажмите **Создать эвалюатор**.
4. Заполните поля:
   - **Название** — удобное для поиска имя.
   - **Описание** — зачем используется этот эвалюатор.
   - **Тип возвращаемого значения** — строка, число, булево и т.д.
   - **Код** — JavaScript-функция с возвращаемым значением.
5. Нажмите **Сохранить**.

Эвалюаторы автоматически становятся доступны в сценариях и стратегиях, где требуется вычисление на лету.

---

## ⚙️ Принцип работы

- Эвалюатор запускается на клиенте при загрузке страницы и старте сценария.
- Возвращает значение, которое используется в условиях (таргетинг, фильтры, шаблоны).
- Имеет ограничение по времени выполнения — **4 секунды**.
- Поддерживает `Promise` — если эвалюатор асинхронный.

---

## 🧪 Примеры

### 🛒 Получить количество товаров в корзине
```js
SL.waitForElement("sup", (elements) => {
  return parseInt(elements[0].textContent);
}, 1, 10, 100);
```

### ✅ Определить, есть ли кнопка на странице
```js
SL.waitForElement("#composite-order-btn-smalcart", () => {
  return Boolean(document.getElementById("composite-order-btn-smalcart"));
}, 1, 10, 100);
```

### 💾 Получить значение из `localStorage`
```js
(function() {
  return localStorage.getItem("gender");
})();
```

### 🎟 Промокоды по дате
```js
(function() {
  const day = new Date().getDate();
  const promocodes = {
    1: 'WINTER10',
    2: 'FRESH5',
    3: 'SALE20',
    // ...
  };
  return promocodes[day];
})();
```

### 🌍 Регион пользователя из Page Context
```js
(function(){
  return SL.pageContext.lng;
})();
```

---

## 🚧 Edge cases

- Если элемент ещё не загрузился — используйте `SL.waitForElement`.
- Если возвращается `undefined` или `null` — система подставит `false`.
- Эвалюатор должен быть предсказуемым: избегайте сильной зависимости от внешних источников.
- Не используйте тяжёлые API-запросы без нужды — это замедляет запуск сценария.

---

## 💡 FAQ

```
Q: Что произойдет, если эвалюатор не вернет значение за 4 секунды?
A: Платформа подставит значение `false`.

Q: Можно ли использовать несколько эвалюаторов в одном сценарии?
A: Да, в рамках одного сценария можно использовать любое количество эвалюаторов.

Q: Как отладить эвалюатор?
A: Используйте `console.log` в коде и проверяйте результат в браузерной консоли.

Q: Можно ли обращаться к внешним данным?
A: Да, но помните про таймаут — внешний `fetch` должен укладываться в 4 секунды или использовать `Promise`.

Q: Эвалюатор асинхронный — что делать?
A: Оберните код в `Promise`, платформа дождется результат.
```

---

## 🧩 Применение

Эвалюаторы можно использовать в:
- **Таргетинге** — показать контент только если `gender = female`.
- **Фильтрах в стратегиях** — исключить товары определённой категории в зависимости от контекста.
- **Атрибуции** — привязать события к условиям на странице.

---

## 🧷 Примеры задач

| Задача                                 | Решение                                            |
|----------------------------------------|----------------------------------------------------|
| Показать баннер только в корзине       | Проверка URL или DOM-элементов корзины             |
| Подставить текущий регион              | `SL.pageContext.lng`                               |
| Исключить текущий товар из рекомендации| Взять SKU со страницы и передать в фильтр стратегии|
| Показать промокод в определённый день | Возврат значения по `Date().getDay()`              |

---

Если нужен шаблон или готовый фрагмент под вашу задачу — напишите в поддержку, и мы поможем.
