# KeyRota : rotations avancées (KRC), documentation

Source: https://keyrota.app/documentation/fr/advanced (Mis à jour le 18/10/2026). JSON Schema: https://keyrota.app/documentation/keyrota-rotation.schema.json. Index pour les agents IA: https://keyrota.app/documentation/llms.txt.

---

<!-- https://keyrota.app/documentation/fr/advanced -->

## Rotations avancées (KRC)

> [!TIP] Nous recommandons de créer les rotations avec un agent IA
> C’est beaucoup plus rapide et plus pratique que de configurer une rotation à la main. Plus l’agent IA est avancé, plus la rotation correspond à vos exigences dès le premier essai. Nous recommandons les derniers modèles d’Anthropic et d’OpenAI avec le niveau de raisonnement « Extra (xhigh) ». Marche à suivre : [Créer avec un agent IA](https://keyrota.app/documentation/fr/ai).

Une rotation avancée est votre propre liste de règles : quelle technique presser, et quand. En combat, KeyRota vérifie les règles et presse le premier bouton qui convient. Le format et le moteur de ces rotations s’appellent **KRC** (KeyRota Customization).

### De base ou avancée

| | Blizzard (de base) | Avancée (KRC) |
|---|---|---|
| Qui choisit le bouton | Le jeu : la recommandation de Blizzard | Vos règles |
| Configuration | Aucune | Emplacements, auras et règles : dans l’éditeur ou depuis un fichier |
| Spécialisations | Toutes les spécialisations de dégâts (DPS au corps à corps et à distance) et de tank | Celle pour laquelle la rotation est écrite |
| Burst et mode de cibles | Non utilisés | Les boutons Burst et Cibles ; les règles décident de leur signification |
| Quand la choisir | Pour démarrer vite avec n’importe quel personnage | Vous avez besoin d’une priorité précise : DoT, mise en réserve de ressources, temps de recharge dans une fenêtre de burst, votre propre logique multicible |

Dans le bloc Rotation de l’application, le profil Blizzard apparaît en premier, et vos rotations en dessous, sous « Vos rotations ». Vous pouvez en changer à tout moment tant que la rotation est arrêtée.

### Composition d’une rotation

| Élément | Description | Nombre |
|---|---|---|
| **Emplacements** | Les boutons de la rotation. L’emplacement N de la rotation correspond à l’emplacement N du profil Better Assistant. | jusqu’à 12 |
| **Auras** | Vos améliorations et vos affaiblissements sur la cible, par ID de sort. L’aura N de la rotation correspond à l’aura N de la liste Better Assistant. | jusqu’à 12 |
| **Ressources** | La vie du joueur et celle de la cible, ainsi que les ressources de la spécialisation : énergie, points de combo, rage, mana, etc. Toutes les valeurs sont des pourcentages. | selon la spécialisation |
| **Combat** | Le nombre d’ennemis à proximité et la distance de la cible. | 2 |
| **Options** | Les boutons du panneau de réglages rapides : mode de cibles (deux valeurs dans les règles : `aoe` et `st`), Burst, Soins / défense, Au sol, Déplacement. | 6 |
| **Règles** | Quel emplacement presser et dans quelles conditions. L’ordre des règles définit la priorité. | illimité |

Une règle se compose de groupes de conditions. Une règle est remplie quand **au moins un** de ses groupes est rempli (OU), et un groupe est rempli quand **toutes** ses conditions sont remplies (ET). Une règle sans groupe est toujours remplie.

*Texte KRC:*

```text
use Envenom when  # Envenimer
	Combo_Points >= 70 and Envenom_Buff.down  # 5+ points de combo, pas d’amélioration
	or
	Combo_Points >= 70 and Energy >= 70  # 5+ points de combo, beaucoup d’énergie
```

*JSON:*

```json
{
  "use": "Envenom",
  "name": "Envenimer",
  "when": [
    {"all": ["Combo_Points >= 70", "Envenom_Buff.down"], "comment": "5+ points de combo, pas d’amélioration"},
    {"all": ["Combo_Points >= 70", "Energy >= 70"], "comment": "5+ points de combo, beaucoup d’énergie"}
  ]
}
```


Elle se lit ainsi : « Presser Envenimer s’il y a 5 points de combo ou plus et aucune amélioration Envenimer, **ou** s’il y a 5 points de combo ou plus et au moins 70 % d’énergie ». La raison pour laquelle 5 points de combo s’écrivent `70` est expliquée dans [Ressources](https://keyrota.app/documentation/fr/conditions#resources).

### Comment KeyRota choisit un bouton

1. Les règles sont vérifiées **de haut en bas**, dans l’ordre de la liste.
2. Pour chaque règle, ses groupes sont vérifiés. Si aucun n’est rempli, KeyRota passe à la règle suivante.
3. Si la règle est remplie mais que son sort **ne peut pas être utilisé** à ce moment-là (temps de recharge, ressource insuffisante, cible trop éloignée, pas de cible, sort non appris), KeyRota passe aussi à la règle suivante. Inutile d’ajouter une condition sur la disponibilité de l’emplacement lui-même.
4. La première règle remplie dont le sort peut être utilisé est **choisie**. Le temps de recharge global (GCD) ne change pas ce choix : une règle qui attend la fin du GCD reste choisie, et les règles situées en dessous ne la devancent pas.
5. Si aucune règle ne convient : si « Ignorer l’icône principale » est activé, KeyRota attend ; sinon, elle presse la recommandation du jeu.

L’attente est normale. Une rotation qui met de l’énergie en réserve, par exemple, ne presse souvent rien pendant une demi-seconde ou une seconde, le temps d’avoir assez d’énergie pour une règle placée plus haut.

### Une valeur inconnue n’autorise jamais une règle

Il arrive que KeyRota ne connaisse pas une valeur : une aura n’est pas lue (son ID ne figure pas dans le profil Better Assistant), il n’y a pas de cible (la vie et la distance de la cible sont inconnues), les ennemis n’ont pas été comptés. Une condition qui lit une valeur inconnue est **fausse** : `X.up` comme `X.down`, `TargetHP >= 50` comme `TargetHP < 50`. Une valeur inconnue peut seulement interdire une règle, jamais l’autoriser : mieux vaut sauter un appui que presser la mauvaise touche.

> [!TIP]
> Si une règle ne se déclenche jamais, vérifiez d’abord que chaque aura qu’elle lit figure dans le profil Better Assistant avec le bon ID. Plus d’informations dans [FAQ et dépannage](https://keyrota.app/documentation/fr/faq#never-fires).

### Quand un bouton est pressé

- **Un sort normal** (soumis au GCD) est pressé dans la fenêtre de file d’attente des sorts, tout à la fin du GCD : le jeu le lance dès que le GCD se termine.
- **Les indicateurs d’emplacement** modifient ce comportement : « Manuel uniquement (M) », « Canalisation (C) », « Hors GCD (O) », « Fenêtre de file d’attente (Q) ». Le rôle de chacun et leurs combinaisons sont décrits dans [Indicateurs d’emplacement](https://keyrota.app/documentation/fr/rotation-json#flags).
- **Canalisations.** Pendant une canalisation, KeyRota ne presse rien pour ne pas l’interrompre. Pendant une **incantation**, KeyRota attend qu’il ne reste plus que la fenêtre de file d’attente.
- **Vos propres appuis.** Quand vous pressez vous-même la touche d’une technique, KeyRota s’efface et n’entre pas en concurrence avec vous.

### Démarrage rapide

Si KeyRota n’est pas encore installée, commencez par les [premiers pas](https://keyrota.app/documentation/fr/start).

1. Dans KeyRota, ouvrez Rotation — Nouveau — Dans l’éditeur…
2. Sur la page Général, choisissez la spécialisation et donnez un nom à la rotation.
3. Sur la page Emplacements, ajoutez les boutons et leurs ID de sort ; sur la page Auras, les améliorations et les affaiblissements que liront les règles.
4. Sur la page Règles, ajoutez les règles par ordre de priorité.
5. Sur la page Général, cliquez sur « Créer depuis la rotation », puis sur « Copier ». Dans le jeu : `/ba` — onglet Profile — collez la chaîne — Apply.
6. Placez les sorts des emplacements sur vos barres d’action et assignez-leur des touches (une macro avec `#showtooltip` fonctionne aussi).
7. Cliquez sur Enregistrer, choisissez le profil dans la liste et démarrez la rotation avec F1 (sur macOS, ⌃⇧Space).

Chaque bouton, avec un exemple complet, est décrit dans [Éditeur de rotation](https://keyrota.app/documentation/fr/editor).

### Dans cette section

- [Éditeur de rotation](https://keyrota.app/documentation/fr/editor) — chaque page et chaque bouton de la fenêtre, et une rotation construite pas à pas.
- [JSON de rotation](https://keyrota.app/documentation/fr/rotation-json) — chaque champ du format, les indicateurs d’emplacement, les noms, les limites, les erreurs et le texte KRC.
- [Conditions](https://keyrota.app/documentation/fr/conditions) — chaque type de condition, les opérateurs, les pourcentages et les valeurs inconnues.
- [Exemples de modèles](https://keyrota.app/documentation/fr/patterns) — DoT, mise en réserve, générateur et dépense, AoE, Burst, défense et d’autres modèles.
- [Créer avec un agent IA](https://keyrota.app/documentation/fr/ai) — un modèle de prompt, l’analyse des logs et la vérification du résultat.
- [FAQ et dépannage](https://keyrota.app/documentation/fr/faq) — pourquoi une règle ne se déclenche pas, presse trop tôt ou trop tard, coupe une canalisation.

---

<!-- https://keyrota.app/documentation/fr/editor -->

## Éditeur de rotation

L’éditeur de rotation est la fenêtre de KeyRota dans laquelle vous assemblez une rotation avancée sans rien taper : des emplacements avec leurs indicateurs, des auras, des règles, avec le texte KRC et le JSON juste à côté. La documentation est la même pour Windows et macOS ; les captures d’écran ont été réalisées sous Windows. Elles montrent la rotation de raid Assassinat des [exemples](https://keyrota.app/documentation/fr/patterns#example-files).

### Ouvrir l’éditeur

- **Votre rotation.** Sélectionnez le profil dans le bloc Rotation de la fenêtre principale, puis cliquez sur Configurer.
- **Une nouvelle rotation.** Nouveau — Dans l’éditeur… La spécialisation est reprise du jeu ou du profil actuel. La rotation devient un profil lors de son premier enregistrement.
- **Depuis un fichier ou le presse-papiers.** Nouveau — Depuis un fichier… accepte le texte KRC (`.txt`), le JSON de rotation et un fichier de profil KeyRota ; Nouveau — Depuis le presse-papiers accepte les mêmes contenus depuis le presse-papiers. Ouvrez ensuite le nouveau profil dans l’éditeur avec Configurer.

![Une nouvelle rotation dans l’éditeur : la page Général, sans emplacements ni règles pour l’instant](https://keyrota.app/documentation/img/fr/editor-new.png)

Pour un **profil Blizzard**, l’éditeur n’affiche que le nom et le délai de frappe : c’est le jeu qui choisit le bouton principal. « Créer votre rotation » crée un nouveau profil avec une rotation avancée ; le profil Blizzard reste dans la liste.

![Un profil Blizzard dans l’éditeur : le nom du profil, le délai de frappe et « Créer votre rotation »](https://keyrota.app/documentation/img/fr/editor-blizzard.png)

#### La fenêtre

- **À gauche**, les pages : Général, Emplacements, Auras, Règles (avec le nombre de règles), Texte et JSON. Au-dessus, « Rotation personnalisée » et la spécialisation choisie.
- **À droite**, la page sélectionnée.
- **En bas**, la barre d’état : si la rotation est valide (« Rotation valide : 15 règles, 11 emplacements, 10 auras »), s’il y a des modifications non enregistrées et, en cas d’erreur, où elle se trouve, avec un bouton Afficher. À droite, Fermer et Enregistrer.

Rien n’est appliqué avant Enregistrer (sous Windows, également Ctrl+S).

### Général

![La page Général : profil, spécialisation, nom de la rotation, Ignorer l’icône principale, délai de frappe](https://keyrota.app/documentation/img/fr/editor-general.png)

| Contrôle | Rôle |
|---|---|
| **Nom du profil** | Le nom du profil dans la liste des rotations de la fenêtre principale. |
| **Spécialisation** | Définit les ressources de la rotation (énergie, points de combo, rage…) ainsi que la classe et la spécialisation du profil Better Assistant. La changer remplace les ressources, sauf si les règles lisent les ressources de l’ancienne spécialisation (la vie ne compte pas). |
| **Nom de la rotation** | La première ligne du texte KRC (`rotation "…"`), affichée dans le journal de KeyRota. Sans guillemets doubles. C’est un bon endroit pour la version : « Assassinat v1.3 ». |
| **Ignorer l’icône principale** | Activé : KeyRota presse uniquement selon les règles ; si aucune règle ne correspond, elle attend. Désactivé : elle presse alors la recommandation du jeu. Généralement activé pour vos propres rotations : l’attente (par exemple pour mettre de l’énergie en réserve) est normale. |
| **Délai de frappe** | Une pause avant chaque appui, comme chez un humain : Aucun, Fixe (un intervalle de 0 à 1000 ms) ou Aléatoire (une plage de 0 à 1000 ms). « Aussi pour les interruptions et la défense » applique la même pause à ces appuis. |

![La page Général plus bas : le bloc Better Assistant, le rayon du compteur d’ennemis, Ennemis en combat uniquement et la description](https://keyrota.app/documentation/img/fr/editor-general-ba.png)

| Contrôle | Rôle |
|---|---|
| **Profil : …** | Un résumé de la chaîne du profil Better Assistant : spécialisation, nombre de sorts et d’auras. |
| **Créer depuis la rotation** | Crée la chaîne du profil Better Assistant à partir des ID de sort des emplacements, du réglage « Better Assistant l’affiche » de chaque emplacement, des auras dans l’ordre, de la spécialisation, du rayon et de l’option « Ennemis en combat uniquement ». Si un profil de la même spécialisation est déjà collé, ses autres réglages sont conservés. |
| **Depuis le presse-papiers** | Colle une chaîne de profil toute prête. Sa spécialisation doit correspondre à celle de la rotation. |
| **Copier** | Copie la chaîne pour la coller dans le jeu. |
| **Rayon du compteur d’ennemis, mètres** | De 1 à 100, 8 par défaut. Utilisé par la condition « Ennemis à proximité » (`enemies`). |
| **Ennemis en combat uniquement** | Activé par défaut : les ennemis qui ne sont pas encore en combat ne sont pas comptés. |
| **Description** | Des notes sur la rotation : les lignes commençant par `#` dans le texte KRC. Elles n’influent pas sur le fonctionnement de la rotation. |

Des avertissements apparaissent sous les boutons : quels emplacements utilisés dans les règles n’ont pas d’ID de sort (ils ne figureront pas dans le profil Better Assistant) et ce qui, dans un profil déjà collé, ne correspond pas à la rotation.

> [!IMPORTANT]
> Dans le profil Better Assistant, les auras se suivent sans trou à partir de la première. Si l’aura 3 n’a pas d’ID alors que l’aura 4 en a un, le profil ne peut pas être créé : « L’aura 3 n’a pas de numéro de sort ». Renseignez l’ID ou renumérotez les auras.

#### Le profil Better Assistant dans le jeu

L’emplacement N de la rotation correspond à l’emplacement N dans Better Assistant, et l’aura N à l’aura N de sa liste. La chaîne de profil y place vos emplacements et vos auras dans le bon ordre.

1. Sur la page Général, cliquez sur « Créer depuis la rotation », puis sur « Copier ».
2. Dans le jeu, tapez `/ba`, ouvrez l’onglet **Profile**, collez la chaîne, cliquez sur **Apply** et confirmez.
3. Après toute modification des emplacements ou des auras (ID, ordre, Avec une cible / En combat), recréez le profil et collez-le de nouveau.

### Emplacements

![La page Emplacements : les 12 places à gauche, à droite l’emplacement 10 Disparition sélectionné, avec l’ID 1856](https://keyrota.app/documentation/img/fr/editor-slots.png)

À gauche se trouvent les 12 places : numéro, nom, ID de sort, indicateurs (« hors GCD, en file d’attente ») et « non utilisé » quand l’emplacement ne figure dans aucune règle. Une place libre affiche « Vide » ; sélectionnez-la pour faire apparaître le bouton « Ajouter l’emplacement ».

| Contrôle | Rôle |
|---|---|
| **Nom** | Le nom du sort dans le jeu. Affiché dans la liste des règles et dans le journal. |
| **ID du sort** | Le numéro dans le lien Wowhead : dans `wowhead.com/fr/spell=1856/disparition`, c’est `1856`. Better Assistant s’en sert pour placer le sort dans cet emplacement. |
| **Better Assistant l’affiche** | Avec une cible ou En combat. L’emplacement n’est prêt que lorsque Better Assistant l’affiche. En combat convient aux soins et aux techniques défensives qui doivent fonctionner sans cible. |
| **Comment presser** | Quatre interrupteurs d’indicateurs, voir le tableau ci-dessous. |
| **Nom dans le texte** | Le nom de l’emplacement dans les règles et dans le texte KRC : lettres, chiffres et `_`, sans espaces. |
| **Commentaire** | Un commentaire en fin de ligne de déclaration dans le texte. |
| **Règles qui l’utilisent** | Les règles qui pressent ou lisent l’emplacement. « Retirer l’emplacement » n’est disponible que si l’emplacement n’est pas utilisé. |

Pour que KeyRota presse un emplacement, son sort doit se trouver sur une barre d’action dans le jeu, avec une touche assignée : KeyRota prend la touche sur vos barres. Une macro avec `#showtooltip Nom` fonctionne aussi. Un emplacement sans touche n’est jamais pressé.

#### Comment presser : les indicateurs

![Les interrupteurs Comment presser de l’emplacement Disparition : Hors GCD (O) et Fenêtre de file d’attente (Q) sont activés](https://keyrota.app/documentation/img/fr/editor-slot-flags.png)

| Interrupteur | Rôle | Quand l’utiliser |
|---|---|---|
| aucun indicateur | L’emplacement est pressé comme un sort normal : à la fin du temps de recharge global, dans la fenêtre de file d’attente. | Presque tous les sorts soumis au GCD. |
| **Manuel uniquement (M)** | KeyRota ne presse jamais cet emplacement d’elle-même et ignore ses règles. Si vous appuyez vous-même sur sa touche, la rotation se met en pause. | Les techniques que vous voulez presser uniquement vous-même. |
| **Canalisation (C)** | Pendant la canalisation de ce sort, KeyRota ne presse rien et ne l’interrompt pas. | Les sorts canalisés, comme Série meurtrière. |
| **Hors GCD (O)** | N’attend pas le temps de recharge global : pressé immédiatement, même en plein GCD. | Les sorts hors GCD, comme Osselets relancés. |
| **Fenêtre de file d’attente (Q)** | Uniquement avec Hors GCD : pressé tout à la fin du GCD, dans la fenêtre de file d’attente des sorts. | Les macros dont la deuxième ligne est soumise au GCD (Poussée d'adrénaline + Série meurtrière) et les boutons qui ont besoin du résultat du coup précédent (Disparition après Plaie des rois). |

Toutes les combinaisons d’indicateurs et leur JSON sont décrites dans [Indicateurs d’emplacement](https://keyrota.app/documentation/fr/rotation-json#flags).

### Auras

![La page Auras : aura 1 « Garrot sur la cible [703] », ID 703, nom dans le texte Garrote_DoT, utilisée dans les règles 3, 4, 5, 7, 8, 10](https://keyrota.app/documentation/img/fr/editor-auras.png)

Les auras sont vos améliorations et vos affaiblissements sur la cible, que lisent les règles. L’aura N de la rotation correspond à l’aura N de la liste Better Assistant.

| Contrôle | Rôle |
|---|---|
| **Nom** | Le nom de l’aura ; affiché dans les règles. Pratique avec l’ID entre crochets : « Garrot sur la cible [703] ». |
| **ID du sort** | Le numéro de l’aura sur Wowhead. Better Assistant la cherche parmi vos améliorations et vos affaiblissements sur la cible. |
| **Nom dans le texte**, **Commentaire** | Comme pour les emplacements. |
| **Règles qui l’utilisent** | Les règles qui lisent l’aura. « Retirer l’aura » ne fonctionne que pour une aura non utilisée. |

> [!NOTE]
> L’ID d’une aura peut différer de celui du sort qui l’applique. Le sort Disparition a l’ID `1856`, l’amélioration qu’il donne `11327` ; Camouflage a l’ID `1784`, Camouflage avec le talent Subterfuge `115191`. Vérifiez sur Wowhead l’ID de l’amélioration ou de l’affaiblissement lui-même.

Seules **vos** auras sont visibles : les améliorations que vous vous appliquez et les affaiblissements que vous appliquez à la cible. Les améliorations venant d’autres joueurs et les affaiblissements que d’autres joueurs appliquent à la cible sont invisibles pour les règles.

### Règles

![La page Règles : 15 règles à gauche, à droite la règle 4 Marque létale avec son groupe de conditions](https://keyrota.app/documentation/img/fr/editor-rules.png)

Les règles sont vérifiées de haut en bas : KeyRota presse la première qui est remplie et dont le sort peut être lancé ; si ce n’est pas possible (temps de recharge, ressource, portée), elle vérifie la suivante.

**La barre d’outils au-dessus de la liste :**

| Bouton | Rôle |
|---|---|
| **+** | Une nouvelle règle sous la règle sélectionnée. Elle presse le premier emplacement et n’a pas encore de conditions. |
| **Dupliquer** | Une copie de la règle, placée juste en dessous. |
| **Corbeille** | Supprime la règle. |
| **Monter**, **Descendre** | Déplace la règle vers le haut (vérifiée plus tôt) ou vers le bas (vérifiée plus tard). |

Chaque règle de la liste affiche son numéro (la priorité), l’emplacement, le nom et le nombre de groupes ; une règle contenant une erreur porte une marque rouge.

**La règle sélectionnée :**

| Contrôle | Rôle |
|---|---|
| **Presser** | L’emplacement à presser quand la règle est remplie. |
| **Nom** | Affiché dans le journal quand la règle se déclenche. |
| **Description** | Des notes au-dessus de la règle dans le texte KRC. |
| **Quand presser** | Les groupes de conditions : la règle est remplie quand au moins un groupe est rempli (OU) ; un groupe, quand toutes ses conditions sont remplies (ET). |

![Les groupes de conditions de la règle Rupture : groupe 1 et groupe 2 séparés par OU](https://keyrota.app/documentation/img/fr/editor-rule-groups.png)

Chaque groupe comporte « Groupe N », un champ « Commentaire du groupe » et les boutons Dupliquer le groupe et Supprimer le groupe. Une ligne de condition comprend **ce qu’il faut vérifier**, la **propriété**, la **comparaison** et le **nombre** ; la croix supprime la condition. « + Condition » ajoute une condition au groupe, « + Groupe (OU) » ajoute un nouveau groupe. Un groupe contient jusqu’à 16 conditions et une règle jusqu’à 16 groupes : une fois la limite atteinte, les boutons sont désactivés. Une règle sans groupe affiche « Sans conditions : la règle se déclenche dès que le sort peut être lancé ».

| Ce qu’il faut vérifier | Propriétés | Dans le texte KRC |
|---|---|---|
| **Auras** (chaque aura de la rotation) | active, absente, « restant, % », cumuls | `Garrote_DoT.up`, `.down`, `.duration <= 30`, `.stacks >= 3` |
| **Emplacements** (chaque emplacement) | prêt, en recharge, « recharge, % », charges, illuminé, non illuminé | `Kingsbane.ready`, `.oncd`, `.cd <= 3`, `.charges >= 2`, `.glow`, `.noglow` |
| **Ressources** | vie du joueur et de la cible, ressources de la spécialisation, en % | `PlayerHP <= 40`, `Energy >= 70` |
| **Combat** : Ennemis à proximité | un nombre | `enemies >= 3` |
| **Combat** : Distance de la cible | mètres | `target.distance <= 8` |
| **Panneau de réglages rapides** | activé, désactivé | `aoe == 1`, `st == 1`, `cd == 1`, `defensives == 1`, `ground_spells == 1`, `movement == 1` |

Comparaisons : `<`, `≤`, `=`, `≥`, `>` ; le nombre va de 0 à 100. Une nouvelle condition commence par « active » pour la première aura ; quand vous changez ce qu’il faut vérifier, la propriété et le nombre reprennent leurs valeurs par défaut (`≥ 50` pour une ressource, `≥ 2` pour les ennemis, `≤ 8` pour la distance). Toutes les conditions en détail : [Conditions](https://keyrota.app/documentation/fr/conditions).

### Erreurs et barre d’état

![Une erreur dans la règle 9 : le groupe 1 sans conditions est encadré en rouge ; la barre d’état indique « Règle 9, groupe 1 : le groupe n’a aucune condition » avec Afficher](https://keyrota.app/documentation/img/fr/editor-problem.png)

- **Vert** : « Rotation valide : … », aucune erreur, la rotation peut être enregistrée.
- **Rouge** : le message indique l’endroit, par exemple « Règle 9, groupe 1 : le groupe n’a aucune condition ». Afficher ouvre cet endroit. La règle est marquée dans la liste, le groupe est encadré en rouge.
- Une rotation contenant une erreur n’est pas enregistrée : « Impossible d’enregistrer une rotation contenant une erreur : corrigez ce qui est signalé en bas ».
- Pendant que la rotation est en cours, l’enregistrement est impossible : « Arrêtez la rotation pour enregistrer ».

### Texte et JSON

![La page Texte et JSON en mode texte KRC : le début du texte de la rotation avec la description et les déclarations buff1 à buff7](https://keyrota.app/documentation/img/fr/editor-text.png)

![La page Texte et JSON en mode JSON : le début du JSON de la rotation avec format, version, title, specID, ignoreMainIcon, enemies et notes](https://keyrota.app/documentation/img/fr/editor-json.png)

| Contrôle | Rôle |
|---|---|
| **Texte KRC / JSON** | Change d’affichage. |
| **Copier** | Copie tout le texte ou tout le JSON. |
| **Coller** | Remplace la rotation par le contenu du presse-papiers : texte KRC, JSON de rotation ou profil KeyRota. |
| **Ouvrir…** | Charge une rotation depuis un fichier `.txt` ou `.json`. |
| **Enregistrer…** | Enregistre l’affichage actuel dans un fichier : le texte en `.txt`, le JSON en `.json`. |

Une modification dans le champ s’applique immédiatement si elle ne contient pas d’erreur ; sinon, l’erreur s’affiche sous le champ et les autres pages conservent la dernière version valide.

**Ce que conserve le texte et ce que seul le JSON conserve.** Le texte KRC ne contient ni les ID de sort, ni les indicateurs d’emplacement, ni Avec une cible / En combat, ni la spécialisation, ni Ignorer l’icône principale, ni les réglages du compteur d’ennemis. Quand vous modifiez le texte, ces données restent attachées aux emplacements et aux auras de mêmes numéros. Le JSON conserve tout. Quand vous collez ou ouvrez une nouvelle version de la rotation, les emplacements et les auras de mêmes numéros conservent leurs ID, leur visibilité et leurs indicateurs si la nouvelle version n’en contient pas.

### Enregistrer et fermer

- Enregistrer (sous Windows, également Ctrl+S) écrit la rotation dans le profil ; le bouton affiche brièvement Enregistré. Une nouvelle rotation devient un profil et est sélectionnée dans la liste.
- Si vous fermez la fenêtre avec des modifications non enregistrées, la question « Enregistrer les modifications ? » s’affiche : Enregistrer, Ne pas enregistrer ou Annuler. Il en va de même à la fermeture de KeyRota.
- Exporter, dans la fenêtre principale, enregistre le profil avec sa rotation au format JSON ; Importer accepte aussi bien un profil KeyRota qu’un JSON de rotation seul.

### Exemple : une rotation à partir de zéro

Construisons une petite rotation Assassinat : deux DoT (Garrot et Rupture), un générateur (Estropier), une dépense (Envenimer), une défense (Fiole cramoisie à 40 % de vie ou moins) et un temps de recharge sur le bouton Burst (Marque létale).

**1. Nouveau profil.** Rotation — Nouveau — Dans l’éditeur…

**2. Général.** Nom du profil : « Assassinat : exemple ». Spécialisation : Assassinat (les ressources deviennent `PlayerHP`, `TargetHP`, `Energy`, `Combo_Points`). Nom de la rotation : « Assassinat : exemple v1 ». Ignorer l’icône principale : activé.

**3. Emplacements.** Pour chaque ligne du tableau : sélectionnez la place à gauche, cliquez sur « Ajouter l’emplacement », renseignez Nom, ID du sort et Nom dans le texte ; pour Fiole cramoisie, choisissez En combat. Aucun indicateur n’est nécessaire.

| Emplacement | Nom | ID | Nom dans le texte | Better Assistant l’affiche |
|---|---|---|---|---|
| 1 | Garrot | 703 | `Garrote` | Avec une cible |
| 2 | Rupture | 1943 | `Rupture` | Avec une cible |
| 3 | Envenimer | 32645 | `Envenom` | Avec une cible |
| 4 | Estropier | 1329 | `Mutilate` | Avec une cible |
| 5 | Marque létale | 360194 | `Deathmark` | Avec une cible |
| 6 | Fiole cramoisie | 185311 | `Crimson_Vial` | En combat |

**4. Auras.** Même chose sur la page Auras :

| Aura | Nom | ID | Nom dans le texte |
|---|---|---|---|
| 1 | Garrot sur la cible [703] | 703 | `Garrote_DoT` |
| 2 | Rupture sur la cible [1943] | 1943 | `Rupture_DoT` |
| 3 | Envenimer [32645] | 32645 | `Envenom_Buff` |
| 4 | Marque létale sur la cible [360194] | 360194 | `Deathmark_DoT` |

**5. Règles.** Sur la page Règles, cliquez sur « + », choisissez l’emplacement dans Presser et saisissez le Nom. « + Groupe (OU) » ajoute un groupe avec une condition par défaut : changez ce qu’il faut vérifier, la propriété, la comparaison et le nombre. « + Condition » ajoute la condition suivante dans le même groupe. Les règles, dans cet ordre :

| N° | Presser | Groupes (OU), conditions d’un groupe (ET) |
|---|---|---|
| 1 | Fiole cramoisie | Soins / défense activé, Vie du joueur ≤ 40 |
| 2 | Marque létale | Burst activé, Garrot sur la cible : active, Rupture sur la cible : active, Envenimer : active |
| 3 | Garrot | (1) Garrot sur la cible : absente ; (2) Garrot sur la cible : active, restant ≤ 30 % |
| 4 | Rupture | (1) Points de combo ≥ 70, Rupture sur la cible : absente ; (2) Points de combo ≥ 70, Rupture sur la cible : active, restant ≤ 30 % |
| 5 | Envenimer | (1) Points de combo ≥ 70, Envenimer : absente ; (2) Points de combo ≥ 70, Envenimer : active, restant ≤ 20 % ; (3) Points de combo ≥ 70, Énergie ≥ 70 ; (4) Points de combo ≥ 70, Marque létale sur la cible : active |
| 6 | Estropier | Points de combo < 70 |

Pourquoi :
- **La défense d’abord** : à faible vie, Fiole cramoisie compte plus que les dégâts. Elle ne se déclenche que si Soins / défense est activé dans le panneau de réglages rapides.
- **Marque létale sur Burst** : `cd == 1` est le bouton Burst (F3 sous Windows, ⌃⇧B sous macOS), pas le temps de recharge du sort. Désactivez Burst, et Marque létale attend.
- **Des DoT avec la fenêtre de pandémie** : une aura absente a 0 restant, donc le renouvellement demande deux groupes : « pas de DoT » et « DoT actif avec 30 % restant ou moins ».
- **5 points de combo = 70** : sur 7 points de combo, 5 représentent 71 % ; le seuil `70` fonctionne quel que soit l’arrondi. Le tableau se trouve dans [Ressources](https://keyrota.app/documentation/fr/conditions#resources).
- **Estropier en dernier**, et seulement en dessous de 5 points de combo, pour ne pas gaspiller d’énergie pendant qu’Envenimer attend ses conditions.

**6. Vérifier.** La barre d’état doit indiquer « Rotation valide : 6 règles, 6 emplacements, 4 auras ». Ouvrez Texte et JSON pour voir la même chose que ci-dessous.

**7. Le profil Better Assistant.** Général — « Créer depuis la rotation » — « Copier » ; dans le jeu, `/ba` — Profile — coller — Apply.

**8. Touches.** Placez les six sorts sur vos barres d’action et assignez-leur des touches.

**9. Lancer.** Enregistrez, fermez la fenêtre, choisissez le profil « Assassinat : exemple » et démarrez la rotation (F1 sous Windows, ⌃⇧Space sous macOS). Dans le panneau de réglages rapides, activez Soins / défense si vous voulez utiliser Fiole cramoisie ; le bouton Burst active et désactive Marque létale.

*Texte KRC:*

```text
rotation "Assassinat : exemple v1"

# Exemple de la documentation KeyRota : deux saignements, un générateur, une dépense avec mise en réserve d’énergie,
# une défense à faible vie et Marque létale sur le bouton Burst.
# Points de combo en pourcentage de 7 : 5 points = 71 %, seuil 70 = 5+.

buff1	Garrote_DoT = "Garrot sur la cible [703]"
buff2	Rupture_DoT = "Rupture sur la cible [1943]"
buff3	Envenom_Buff = "Envenimer [32645]"
buff4	Deathmark_DoT = "Marque létale sur la cible [360194]"
slot1	Garrote = "Garrot"
slot2	Rupture = "Rupture"
slot3	Envenom = "Envenimer"
slot4	Mutilate = "Estropier"
slot5	Deathmark = "Marque létale"
slot6	Crimson_Vial = "Fiole cramoisie"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

# --- Défense : seulement avec « Soins / défense » activé ---
use Crimson_Vial when  # Fiole cramoisie
	defensives == 1 and PlayerHP <= 40  # vie à 40 % ou moins

# --- Temps de recharge : seulement avec Burst activé ---
use Deathmark when  # Marque létale
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up and Envenom_Buff.up  # Burst activé, saignements et Envenimer actifs

# --- Saignements ---
use Garrote when  # Garrot
	Garrote_DoT.down  # pas de saignement
	or
	Garrote_DoT.up and Garrote_DoT.duration <= 30  # fenêtre de pandémie : 30 % ou moins restants

use Rupture when  # Rupture
	Combo_Points >= 70 and Rupture_DoT.down  # 5+ points de combo, pas de saignement
	or
	Combo_Points >= 70 and Rupture_DoT.up and Rupture_DoT.duration <= 30  # 5+ points de combo, fenêtre de pandémie

# --- Dépense : 5+ points de combo, en réservant l’énergie ---
use Envenom when  # Envenimer
	Combo_Points >= 70 and Envenom_Buff.down  # pas d’amélioration
	or
	Combo_Points >= 70 and Envenom_Buff.up and Envenom_Buff.duration <= 20  # l’amélioration se termine
	or
	Combo_Points >= 70 and Energy >= 70  # ne pas plafonner l’énergie
	or
	Combo_Points >= 70 and Deathmark_DoT.up  # Marque létale sur la cible

# --- Générateur : moins de 5 points de combo ---
use Mutilate when  # Estropier
	Combo_Points < 70  # moins de 5 points de combo
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Assassinat : exemple v1",
  "specID": 259,
  "ignoreMainIcon": true,
  "enemies": {"range": 8, "combatOnly": true},
  "notes": [
    "Exemple de la documentation KeyRota : deux saignements, un générateur, une dépense avec mise en réserve d’énergie,",
    "une défense à faible vie et Marque létale sur le bouton Burst.",
    "Points de combo en pourcentage de 7 : 5 points = 71 %, seuil 70 = 5+."
  ],
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 1, "alias": "Garrote_DoT", "label": "Garrot sur la cible [703]", "spell": 703},
    {"n": 2, "alias": "Rupture_DoT", "label": "Rupture sur la cible [1943]", "spell": 1943},
    {"n": 3, "alias": "Envenom_Buff", "label": "Envenimer [32645]", "spell": 32645},
    {"n": 4, "alias": "Deathmark_DoT", "label": "Marque létale sur la cible [360194]", "spell": 360194}
  ],
  "slots": [
    {"n": 1, "alias": "Garrote", "label": "Garrot", "spell": 703, "show": "target"},
    {"n": 2, "alias": "Rupture", "label": "Rupture", "spell": 1943, "show": "target"},
    {"n": 3, "alias": "Envenom", "label": "Envenimer", "spell": 32645, "show": "target"},
    {"n": 4, "alias": "Mutilate", "label": "Estropier", "spell": 1329, "show": "target"},
    {"n": 5, "alias": "Deathmark", "label": "Marque létale", "spell": 360194, "show": "target"},
    {"n": 6, "alias": "Crimson_Vial", "label": "Fiole cramoisie", "spell": 185311, "show": "combat"}
  ],
  "rules": [
    {
      "use": "Crimson_Vial",
      "name": "Fiole cramoisie",
      "note": ["--- Défense : seulement avec « Soins / défense » activé ---"],
      "when": [{"all": ["defensives == 1", "PlayerHP <= 40"], "comment": "vie à 40 % ou moins"}]
    },
    {
      "use": "Deathmark",
      "name": "Marque létale",
      "note": ["--- Temps de recharge : seulement avec Burst activé ---"],
      "when": [
        {
          "all": ["cd == 1", "Garrote_DoT.up", "Rupture_DoT.up", "Envenom_Buff.up"],
          "comment": "Burst activé, saignements et Envenimer actifs"
        }
      ]
    },
    {
      "use": "Garrote",
      "name": "Garrot",
      "note": ["--- Saignements ---"],
      "when": [
        {"all": ["Garrote_DoT.down"], "comment": "pas de saignement"},
        {
          "all": ["Garrote_DoT.up", "Garrote_DoT.duration <= 30"],
          "comment": "fenêtre de pandémie : 30 % ou moins restants"
        }
      ]
    },
    {
      "use": "Rupture",
      "name": "Rupture",
      "when": [
        {
          "all": ["Combo_Points >= 70", "Rupture_DoT.down"],
          "comment": "5+ points de combo, pas de saignement"
        },
        {
          "all": ["Combo_Points >= 70", "Rupture_DoT.up", "Rupture_DoT.duration <= 30"],
          "comment": "5+ points de combo, fenêtre de pandémie"
        }
      ]
    },
    {
      "use": "Envenom",
      "name": "Envenimer",
      "note": ["--- Dépense : 5+ points de combo, en réservant l’énergie ---"],
      "when": [
        {"all": ["Combo_Points >= 70", "Envenom_Buff.down"], "comment": "pas d’amélioration"},
        {
          "all": ["Combo_Points >= 70", "Envenom_Buff.up", "Envenom_Buff.duration <= 20"],
          "comment": "l’amélioration se termine"
        },
        {"all": ["Combo_Points >= 70", "Energy >= 70"], "comment": "ne pas plafonner l’énergie"},
        {"all": ["Combo_Points >= 70", "Deathmark_DoT.up"], "comment": "Marque létale sur la cible"}
      ]
    },
    {
      "use": "Mutilate",
      "name": "Estropier",
      "note": ["--- Générateur : moins de 5 points de combo ---"],
      "when": [{"all": ["Combo_Points < 70"], "comment": "moins de 5 points de combo"}]
    }
  ]
}
```


Télécharger cet exemple : [JSON](https://keyrota.app/documentation/examples/starter-assassination.fr.json), [texte KRC](https://keyrota.app/documentation/examples/starter-assassination.fr.txt). Ouvrez-le avec Ouvrir… sur la page Texte et JSON, ou avec Nouveau — Depuis un fichier…

---

<!-- https://keyrota.app/documentation/fr/rotation-json -->

## JSON de rotation

Le JSON est la description complète d’une rotation avancée : tout ce que contient le texte KRC, plus les ID de sort, les indicateurs d’emplacement et les réglages du profil. L’éditeur l’affiche sur la page Texte et JSON, et KeyRota l’accepte sous forme de fichier (Nouveau — Depuis un fichier…, Importer). Le format s’appelle `keyrota-rotation`, version 1. Un [JSON Schema](#schema) permet de le vérifier.

### Fichier d’exemple

La plus courte rotation utile : Rupture à 5 points de combo ou plus quand elle n’est pas sur la cible, sinon Estropier.

*minimal.json:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Assassinat : minimum",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [{"n": 1, "alias": "Rupture_DoT", "label": "Rupture sur la cible [1943]", "spell": 1943}],
  "slots": [
    {"n": 2, "alias": "Rupture", "label": "Rupture", "spell": 1943},
    {"n": 4, "alias": "Mutilate", "label": "Estropier", "spell": 1329}
  ],
  "rules": [
    {
      "use": "Rupture",
      "name": "Rupture",
      "when": [
        {
          "all": ["Combo_Points >= 70", "Rupture_DoT.down"],
          "comment": "5+ points de combo, pas de saignement"
        }
      ]
    },
    {"use": "Mutilate", "name": "Estropier"}
  ]
}
```


Tout ce que le fichier omet prend sa valeur par défaut : les emplacements s’affichent Avec une cible et n’ont aucun indicateur, le compteur d’ennemis porte à 8 mètres et ne compte que les ennemis en combat. Une règle sans `when` est toujours remplie.

### Champs de premier niveau

| Champ | Type | Obligatoire | Par défaut | Description |
|---|---|---|---|---|
| `format` | chaîne | oui | — | Toujours `"keyrota-rotation"`. |
| `version` | entier | oui | — | Toujours `1`. Une version plus récente est refusée : « mettez-la à jour ». |
| `title` | chaîne | non | `""` | Nom de la rotation : la première ligne du texte, le nom dans le journal. Sans guillemets doubles. |
| `specID` | entier de 0 à 100000 | non | `0` | Spécialisation WoW, `0` = toutes. Nécessaire pour le profil Better Assistant. |
| `ignoreMainIcon` | true / false | non | `true` | Activé : presser uniquement selon les règles. Désactivé : quand aucune règle ne correspond, presser la recommandation du jeu. |
| `enemies` | objet | non | `{"range": 8, "combatOnly": true}` | Le compteur d’ennemis pour la condition `enemies`. |
| `notes` | chaîne ou liste de chaînes | non | `[]` | Description : lignes `#` en haut du texte. |
| `resources` | liste de chaînes et de `null` | non | `[]` | Noms de `resource1…N`, dans l’ordre. |
| `auras` | liste | non | `[]` | Auras `buff1…12`. |
| `slots` | liste | non | `[]` | Emplacements `slot1…12`. |
| `rules` | liste | non | `[]` | Règles par ordre de priorité. |
| `footer` | chaîne ou liste de chaînes | non | `[]` | Commentaires après la dernière règle. |

Tout autre champ est une erreur, « champ en trop » : les fautes de frappe ne passent pas inaperçues. N’ajoutez donc pas `"$schema"` au fichier ; associez le schéma dans votre éditeur ou votre validateur.

Presque partout, `null` peut remplacer une valeur ; il a le même effet que l’absence du champ.

### format et version

`"format": "keyrota-rotation"` et `"version": 1` sont obligatoires. Si `version` est supérieur à 1, KeyRota refuse le fichier : « la version 2 est plus récente que ce que comprend cette KeyRota : mettez-la à jour ». Sans `version` : « version 1 requise ».

### title

Une chaîne sans guillemets doubles `"`. Les sauts de ligne deviennent des espaces. Dans le texte KRC, c’est `rotation "…"`. C’est un bon endroit pour la version : `"Assassinat v1.3"`.

### specID

L’ID de spécialisation du jeu. Il détermine les ressources de la rotation (lors de sa création dans l’éditeur) ainsi que la classe et la spécialisation du profil Better Assistant. `0` signifie n’importe quelle spécialisation : la rotation fonctionne, mais le profil Better Assistant ne peut pas être créé (« Choisissez une spécialisation : le profil Better Assistant en a besoin »).

| Classe | Spécialisation | specID | Ressources de la spécialisation (`resource3`…) |
|---|---|---|---|
| Guerrier | Armes | 71 | `Rage` |
| Guerrier | Fureur | 72 | `Rage` |
| Guerrier | Protection | 73 | `Rage` |
| Paladin | Sacré | 65 | `Mana`, `Holy_Power` |
| Paladin | Protection | 66 | `Mana`, `Holy_Power` |
| Paladin | Vindicte | 70 | `Mana`, `Holy_Power` |
| Chasseur | Maîtrise des bêtes | 253 | `Focus` |
| Chasseur | Précision | 254 | `Focus` |
| Chasseur | Survie | 255 | `Focus` |
| Voleur | Assassinat | 259 | `Energy`, `Combo_Points` |
| Voleur | Hors-la-loi | 260 | `Energy`, `Combo_Points` |
| Voleur | Finesse | 261 | `Energy`, `Combo_Points` |
| Prêtre | Discipline | 256 | `Mana`, `Insanity` |
| Prêtre | Sacré | 257 | `Mana`, `Insanity` |
| Prêtre | Ombre | 258 | `Mana`, `Insanity` |
| Chevalier de la mort | Sang | 250 | `Runes`, `Runic_Power` |
| Chevalier de la mort | Givre | 251 | `Runes`, `Runic_Power` |
| Chevalier de la mort | Impie | 252 | `Runes`, `Runic_Power` |
| Chaman | Élémentaire | 262 | `Mana`, `Maelstrom` |
| Chaman | Amélioration | 263 | `Mana`, `Maelstrom` |
| Chaman | Restauration | 264 | `Mana`, `Maelstrom` |
| Mage | Arcanes | 62 | `Mana`, `Arcane_Charges` |
| Mage | Feu | 63 | `Mana`, `Arcane_Charges` |
| Mage | Givre | 64 | `Mana`, `Arcane_Charges` |
| Démoniste | Affliction | 265 | `Mana`, `Soul_Shards` |
| Démoniste | Démonologie | 266 | `Mana`, `Soul_Shards` |
| Démoniste | Destruction | 267 | `Mana`, `Soul_Shards` |
| Moine | Maître brasseur | 268 | `Energy`, `Stagger` |
| Moine | Tisse-brume | 270 | `Mana` |
| Moine | Marche-vent | 269 | `Energy`, `Chi` |
| Druide | Équilibre | 102 | `Mana`, `Astral_Power` |
| Druide | Farouche | 103 | `Energy`, `Combo_Points` |
| Druide | Gardien | 104 | `Rage` |
| Druide | Restauration | 105 | `Mana`, `Astral_Power` |
| Chasseur de démons | Dévastation | 577 | `Fury` |
| Chasseur de démons | Vengeance | 581 | `Fury` |
| Chasseur de démons | Dévoration | 1480 | `Fury` |
| Évocateur | Dévastation | 1467 | `Mana`, `Essence` |
| Évocateur | Préservation | 1468 | `Mana`, `Essence` |
| Évocateur | Augmentation | 1473 | `Mana`, `Essence` |

### ignoreMainIcon

`true` (par défaut) : KeyRota presse uniquement selon les règles ; quand aucune ne correspond, elle attend. `false` : elle presse alors la recommandation du jeu, comme le profil Blizzard. La recommandation est le dernier recours après toutes les règles ; elle ne devance jamais une règle.

### enemies

```json
"enemies": {"range": 8, "combatOnly": true}
```


| Champ | Type | Par défaut | Description |
|---|---|---|---|
| `range` | entier de 1 à 100 | `8` | Le rayon du compteur d’ennemis, en mètres. |
| `combatOnly` | true / false | `true` | Ne compter que les ennemis déjà en combat. |

La condition `enemies` lit ce compteur (voir [Ennemis à proximité](https://keyrota.app/documentation/fr/conditions#enemies)). Dans l’éditeur, ce sont « Rayon du compteur d’ennemis, mètres » et « Ennemis en combat uniquement » sur la page Général. Ces valeurs sont aussi reportées dans le profil Better Assistant.

### notes et footer

La description de la rotation (`notes`) et les commentaires après la dernière règle (`footer`). Une liste de chaînes, ou une seule chaîne avec `\n`. Une chaîne vide `""` correspond à une ligne vide dans le texte. Les lignes vides aux extrémités sont supprimées.

```json
"notes": ["D’après un guide et les meilleurs logs, patch 12.1", "", "v1.1 : Envenimer plus tôt sur 4+ cibles"]
```


Dans le texte KRC, ce sont des lignes `# …` placées avant les déclarations. Elles n’influent pas sur le fonctionnement de la rotation.

### resources

Les noms des ressources, dans l’ordre : le premier élément est `resource1`, le deuxième `resource2`, et ainsi de suite. **C’est le numéro qui détermine la ressource** ; le nom sert seulement à l’écrire dans les conditions :

- `resource1` est la vie du joueur, `resource2` la vie de la cible ;
- à partir de `resource3`, ce sont les ressources de la spécialisation, dans l’ordre du [tableau des specID](#spec-id) : pour un voleur, `resource3` est l’énergie et `resource4` les points de combo.

```json
"resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"]
```


Utilisez les noms standard du tableau : l’éditeur les affiche en clair (« Vie du joueur », « Énergie »), et les autres joueurs comme les agents IA comprennent tout de suite les conditions. `null` saute un numéro : `["PlayerHP", null, "Energy"]` ne déclare que `resource1` et `resource3`. Une ressource non déclarée ne peut pas être lue : « resource2 non déclaré ».

Toutes les ressources sont des **pourcentages** du maximum, de 0 à 100. Pour convertir points de combo, énergie et runes en pourcentages, voir [Ressources](https://keyrota.app/documentation/fr/conditions#resources) dans Conditions.

### auras

Les auras sont vos améliorations et vos affaiblissements sur la cible. L’aura `n` de la rotation correspond à l’aura `n` de la liste Better Assistant.

| Champ | Type | Obligatoire | Par défaut | Description |
|---|---|---|---|---|
| `n` | entier de 1 à 12 | oui | — | Numéro de l’aura (`buffN`). Chaque numéro une seule fois. |
| `alias` | chaîne | non | tiré de `label` | Le nom dans les conditions. Voir [Noms](#aliases). |
| `label` | chaîne | non | `""` | Nom affiché. Sans guillemets doubles `"`. Pratique avec l’ID entre crochets : `"Garrot sur la cible [703]"`. |
| `spell` | entier de 0 à 100000000 | non | `0` | L’ID de l’aura sur Wowhead. `0` = non défini : l’aura ne figurera pas dans le profil Better Assistant et restera inconnue. |
| `note` | chaîne | non | `""` | Un commentaire en fin de ligne de déclaration. |

```json
"auras": [
  {"n": 1, "alias": "Garrote_DoT", "label": "Garrot sur la cible [703]", "spell": 703},
  {"n": 2, "alias": "Rupture_DoT", "label": "Rupture sur la cible [1943]", "spell": 1943}
]
```


L’ordre dans la liste n’a pas d’importance, seul `n` compte. Les numéros peuvent comporter des trous, mais pour le profil Better Assistant, les auras qui ont un ID doivent se suivre à partir de la première.

### slots

Les emplacements sont les boutons de la rotation. L’emplacement `n` de la rotation correspond à l’emplacement `n` dans Better Assistant.

| Champ | Type | Obligatoire | Par défaut | Description |
|---|---|---|---|---|
| `n` | entier de 1 à 12 | oui | — | Numéro de l’emplacement (`slotN`). |
| `alias` | chaîne | non | tiré de `label` | Le nom dans les règles et les conditions. |
| `label` | chaîne | non | `""` | Le nom du sort. Sans guillemets doubles `"`. |
| `spell` | entier de 0 à 100000000 | non | `0` | L’ID du sort sur Wowhead. Better Assistant s’en sert pour placer le sort dans l’emplacement. |
| `note` | chaîne | non | `""` | Un commentaire en fin de ligne de déclaration. |
| `show` | `"target"` / `"combat"` | non | `"target"` | Quand Better Assistant affiche l’emplacement. |
| `manual` | true / false | non | `false` | Indicateur **M**. |
| `channel` | true / false | non | `false` | Indicateur **C**. |
| `offGcd` | true / false | non | `false` | Indicateur **O**. |
| `queue` | true / false | non | `false` | Indicateur **Q**, uniquement avec `offGcd`. |

#### show

- `"target"` : l’emplacement est affiché quand vous avez une cible. C’est le cas de presque toutes les attaques.
- `"combat"` : l’emplacement est affiché en combat, même sans cible. Pour les soins et les techniques défensives : Fiole cramoisie doit fonctionner même sans cible.

Un emplacement n’est prêt que lorsque Better Assistant l’affiche. Un emplacement `"target"` sans cible n’est pas prêt, et ses règles sont ignorées.

### Indicateurs d’emplacement

Les indicateurs précisent **comment** presser un emplacement une fois sa règle choisie. Dans l’éditeur, ce sont les interrupteurs Comment presser.

| Indicateurs | En JSON | Quand l’emplacement est pressé | Exemple |
|---|---|---|---|
| aucun | tous à `false` | Dans la fenêtre de file d’attente, à la fin du GCD : le sort part dès la fin du GCD. | Estropier, Envenimer |
| **M** | `"manual": true` | Jamais. Les règles de l’emplacement sont ignorées. Si vous appuyez vous-même sur sa touche, la rotation se met en pause. | Une technique que vous pressez vous-même |
| **C** | `"channel": true` | Comme un sort normal ; pendant la canalisation, rien n’est pressé. Après l’appui, l’emplacement n’est plus pressé tant que la canalisation n’a pas commencé. | Série meurtrière (51690) |
| **O** | `"offGcd": true` | Immédiatement, même en plein GCD. | Osselets relancés (381989) |
| **O + Q** | `"offGcd": true, "queue": true` | Hors GCD, mais seulement dans la fenêtre de file d’attente à la fin du GCD. | La macro Poussée d'adrénaline + Série meurtrière (13750) ; Disparition (1856) après Plaie des rois |
| **C + O** | `"channel": true, "offGcd": true` | Une canalisation qui démarre hors GCD : immédiatement, puis plus rien jusqu’à la fin de la canalisation. | Rare |
| **C + O + Q** | les trois | Pareil, dans la fenêtre de file d’attente. | Rare |
| **Q** sans O | `"queue": true` | Erreur : « queue uniquement avec offGcd ». | — |
| **M** + autres | `"manual": true, …` | M l’emporte : l’emplacement n’est pas pressé, les autres indicateurs n’ont pas d’effet. | — |

Pourquoi **O + Q** et pas seulement **O** : un bouton avec O seul est pressé immédiatement, en plein GCD, avant que le coup précédent n’ait abouti. Avec O seul, Disparition après Plaie des rois serait pressée avant l’arrivée des points de combo de Plaie des rois, et la règle de Disparition (`Combo_Points < 65`) vérifierait l’ancienne valeur. Avec Q, le bouton attend la fin du GCD.

Priorité stricte : une règle hors GCD placée plus bas dans la liste **ne devance pas** une règle plus haute qui attend le GCD.

```json
"slots": [
  {"n": 1, "alias": "Adrenaline_Rush", "label": "Poussée d'adrénaline (macro avec Série meurtrière)", "spell": 13750, "offGcd": true, "queue": true},
  {"n": 4, "alias": "Keep_It_Rolling", "label": "Osselets relancés", "spell": 381989, "offGcd": true},
  {"n": 8, "alias": "Killing_Spree", "label": "Série meurtrière", "spell": 51690, "channel": true},
  {"n": 11, "alias": "Crimson_Vial", "label": "Fiole cramoisie", "spell": 185311, "show": "combat"}
]
```


### rules

Les règles par ordre de priorité : la première de la liste est vérifiée en premier.

| Champ | Type | Obligatoire | Par défaut | Description |
|---|---|---|---|---|
| `use` | chaîne | oui | — | L’emplacement à presser : son `alias` ou `slotN`. |
| `name` | chaîne | non | `""` | Le nom de l’action, affiché dans le journal. Dans le texte, c’est le commentaire de la ligne `use`. |
| `note` | chaîne ou liste de chaînes | non | `[]` | Des notes au-dessus de la règle (lignes `#` avant `use`). |
| `when` | liste de groupes | non | `[]` | Groupes OU. Vide ou absent : une règle sans conditions, pressée dès que le sort peut être utilisé. |

#### when : groupes et conditions

| Champ | Type | Obligatoire | Description |
|---|---|---|---|
| `all` | liste de chaînes non vide | oui | Les conditions du groupe, toutes doivent être remplies (ET). |
| `comment` | chaîne | non | Le commentaire du groupe (dans le texte, à la fin de sa ligne). |

```json
{
  "use": "Garrote",
  "name": "Garrot",
  "note": ["Renouveler dans la fenêtre de pandémie"],
  "when": [
    {"all": ["Garrote_DoT.down"], "comment": "pas de DoT"},
    {"all": ["Garrote_DoT.up", "Garrote_DoT.duration <= 30"], "comment": "30 % restant ou moins"}
  ]
}
```


Un même emplacement peut figurer dans plusieurs règles : par exemple, Garrot depuis le Camouflage en haut de la liste et l’entretien normal de Garrot plus bas.

#### Les conditions en JSON

Chaque condition est une chaîne en syntaxe KRC : `Garrote_DoT.down`, `Rupture_DoT.duration <= 25`, `Kingsbane.cd <= 3`, `Combo_Points >= 70`, `enemies >= 2`, `target.distance <= 8`, `cd == 1`. La liste complète se trouve dans [Conditions](https://keyrota.app/documentation/fr/conditions).

- Faites référence par nom (`Garrote_DoT`) ou par numéro : `buff1`, `slot3`, `resource4`.
- ` and ` à l’intérieur d’une chaîne la divise en deux conditions : `"Combo_Points >= 70 and Energy >= 70"` compte pour deux conditions, et les deux entrent dans la limite de 16.
- Pas de `#` ni de saut de ligne dans une chaîne.
- C’est le moteur de KeyRota lui-même qui lit les conditions : le JSON et le texte ont donc toujours le même sens.

### Noms

Un nom (`alias`) est la façon dont on désigne les auras, les emplacements et les ressources dans les conditions et dans `use`.

- Le premier caractère est une lettre (de n’importe quel alphabet) ou `_` ; ensuite viennent des lettres, des chiffres `0–9` et `_`. Les lettres accentuées et le cyrillique sont acceptés ; les espaces, les traits d’union et les points ne le sont pas : `Fan_of_Knives`, et non `Fan-of-Knives`.
- Un nom est unique parmi l’ensemble des auras, des emplacements et des ressources.
- Noms réservés : `use`, `when`, `and`, `or`, `rotation`, `gcd`, `enemies`, `target`, `aoe`, `st`, `cd`, `defensives`, `ground_spells`, `movement`, ainsi que les noms du type `buffN`, `slotN`, `resourceN`.
- Les mots-clés s’écrivent uniquement en minuscules : `use`, `or`, `.up`. `Use`, `OR` et `.UP` sont des erreurs.

**Un nom tiré du libellé.** Sans `alias`, KeyRota en crée un à partir de `label` : les crochets et leur contenu sont supprimés, les lettres et les chiffres sont conservés, tout le reste devient `_`. Par exemple, `"Garrot sur la cible [703]"` devient `Garrot_sur_la_cible`. Un nom vide ou inutilisable devient `Aura_N` ou `Slot_N` ; un nom déjà pris reçoit `_2`, `_3`. Si une règle fait référence à un `buffN` ou un `slotN` absent des listes, ils sont déclarés automatiquement sous les noms `Aura_N` et `Slot_N`.

### Champs obligatoires et valeurs par défaut

| Où | Obligatoire | Valeurs par défaut |
|---|---|---|
| Fichier | `format`, `version` | `title` `""`, `specID` `0`, `ignoreMainIcon` `true`, `enemies` `{"range": 8, "combatOnly": true}`, listes vides |
| Aura | `n` | `alias` tiré de `label`, `label` `""`, `spell` `0` |
| Emplacement | `n` | `show` `"target"`, tous les indicateurs à `false`, `spell` `0` |
| Règle | `use` | `name` `""`, `note` `[]`, `when` `[]` (sans conditions) |
| Groupe | `all` (non vide) | `comment` `""` |

### Limites

| Élément | Limite |
|---|---|
| Auras | 12 (`n` de 1 à 12) |
| Emplacements | 12 (`n` de 1 à 12) |
| Groupes OU dans une règle | 16 |
| Conditions ET dans un groupe | 16 |
| Règles | illimité |
| Nombre dans une condition | entier de 0 à 100 |
| `enemies.range` | de 1 à 100 |
| `spell` | de 0 à 100000000 |
| `specID` | de 0 à 100000 |
| Ressources | jusqu’à 99 |

Exactement 16 groupes de 16 conditions, c’est accepté ; 17, c’est une erreur.

### Erreurs

Une rotation contenant une erreur ne se charge pas du tout : il n’y a pas d’exécution partielle. Une erreur indique toujours l’endroit. En JSON, c’est un chemin : `rules[3].when[1]: nom inconnu Foo` (en comptant à partir de zéro). Dans l’éditeur : « Règle 4, groupe 2 : nom inconnu Foo » (en comptant à partir de un). Dans le texte KRC : un numéro de ligne.

**Structure du JSON :**

| Message | Cause |
|---|---|
| `champ en trop « offgcd »` | Un champ mal orthographié ou inconnu (la casse compte : `offGcd`). |
| `champ manquant « format »` | Un champ obligatoire est absent. |
| `format: « keyrota-rotation » attendu` | Une autre valeur de `format`. |
| `version: version 1 requise` | Pas de `version`, ou une valeur inférieure à 1. |
| `slots[0]: numéro n manquant (1–12)` | Un emplacement ou une aura sans `n`. |
| `slots[2].n: nombre hors de 1..12` | `n` hors de la plage. |
| `slots[3]: le numéro 4 est déjà pris` | Deux emplacements (ou deux auras) avec le même `n`. |
| `slots[1].show: « target » ou « combat » attendu` | Une autre valeur de `show`. |
| `slots[0]: queue uniquement avec offGcd` | `queue: true` sans `offGcd: true`. |
| `rules[2].use: pas d’emplacement « Garotte »` | `use` fait référence à un emplacement qui n’existe pas. |
| `rules[0].when[1].all: liste de conditions non vide requise` | Un groupe vide ou sans `all`. |
| `rules[0].when[0].all[2]: condition vide ou contenant # ou un saut de ligne` | Une chaîne de condition vide, ou contenant `#`. |
| `….spell: entier attendu` | Mauvais type : une chaîne au lieu d’un nombre, `true` au lieu d’un nombre, etc. |

**Conditions et déclarations** (les mêmes que dans le texte KRC) :

| Code | Exemple de message | Cause |
|---|---|---|
| `unknown_ref` | `nom inconnu Foo` | Aucune aura, aucun emplacement ni aucune ressource ne porte ce nom. |
| `unknown_ref` | `resource5 non déclaré` | La ressource n’est pas déclarée dans `resources`. |
| `wrong_kind` | `Garrote est de type slot, attendu : buff` | Une propriété d’aura sur un emplacement (`Garrote.up`), ou l’inverse. |
| `bad_condition` | `impossible d’analyser la condition "Energy => 50"` | Une faute de frappe dans la condition ou l’opérateur. |
| `bad_condition` | `"Garrote.distance <= 8" : distance n’existe que pour target` | Seule la cible a une distance. |
| `value_range` | `valeur 120 hors de 0..100` | Un nombre supérieur à 100. Il n’existe ni nombres négatifs ni nombres décimaux. |
| `toggle_value` | `"cd >= 1" : une option n’accepte que == 0 ou == 1` | Une option se compare uniquement avec `==` et 0 ou 1. |
| `bad_alias` | `nom non valide Fan-of-Knives` | Des caractères non autorisés dans un nom. |
| `reserved_alias` | `le nom cd est réservé` | Un nom réservé. |
| `duplicate_alias` | `le nom Garrote est déjà déclaré` | Deux auras, emplacements ou ressources avec le même nom. |
| `index_range` | `buff13: numéro hors de 1..12` | Une référence à un numéro supérieur à 12. |
| `too_many_groups` | `plus de 16 groupes OR` | Plus de 16 groupes dans une règle. |
| `too_many_conditions` | `17 conditions dans le groupe (16 maximum)` | Plus de 16 conditions dans un groupe. |

L’éditeur signale aussi « le groupe n’a aucune condition » (un groupe vide), « aucun emplacement choisi » et « guillemets interdits dans le nom ».

### Texte KRC

Le texte KRC est la même rotation sous forme de lignes. La page Texte et JSON l’affiche, et vous pouvez le conserver dans un fichier `.txt`. Le texte et le JSON se convertissent l’un en l’autre sans perte de sens.

*Texte KRC:*

```text
rotation "Assassinat : minimum"

buff1	Rupture_DoT = "Rupture sur la cible [1943]"
slot2	Rupture = "Rupture"
slot4	Mutilate = "Estropier"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Rupture when  # Rupture
	Combo_Points >= 70 and Rupture_DoT.down  # 5+ points de combo, pas de saignement

use Mutilate when  # Estropier
```


#### Lignes

- `#` en dehors des guillemets doubles commence un commentaire jusqu’à la fin de la ligne. À l’intérieur d’un `"libellé"`, `#` est un caractère ordinaire.
- Les lignes vides et les lignes ne contenant qu’un commentaire sont ignorées : c’est ainsi qu’on écrit les descriptions et les séparateurs.
- Toute autre ligne est une déclaration, `use`, `or` ou une ligne de conditions. Sinon, c’est une erreur `stray_line` : « ligne hors règle : "…" (commencez le texte libre par #) ».
- Entre les éléments, n’importe quels espaces et tabulations. La forme canonique utilise une tabulation après `buffN`/`slotN` et en début des lignes de conditions.

#### Déclarations

Uniquement avant le premier `use` :

```text
rotation "Nom"                                       # facultatif, au plus une fois
buff1	Garrote_DoT = "Garrot sur la cible [703]"   # aura 1
slot1	Garrote = "Garrot"                          # emplacement 1
resource1	PlayerHP                               # ressource 1
```


`buffN` et `slotN` vont de 1 à 12, `resourceN` de 1 à 99. Le libellé entre guillemets peut être vide : `slot5	Filler = ""`. Une déclaration placée après le premier `use` est une erreur `late_declaration`.

#### Règles

```text
use Rupture when  # Rupture
	Combo_Points >= 70 and Rupture_DoT.down  # pas de DoT
	or
	Combo_Points >= 70 and Rupture_DoT.up and Rupture_DoT.duration <= 30  # pandémie
```


- `use Emplacement when` ouvre une règle ; un commentaire sur cette ligne donne le nom de l’action.
- Chaque ligne de conditions forme un groupe (conditions reliées par `and`). Les groupes sont séparés par une ligne contenant le seul mot `or`.
- Une règle sans ligne de conditions n’a pas de conditions.
- Deux lignes de conditions consécutives sans `or` provoquent une erreur `split_group` ; `or` au début, à la fin ou deux fois de suite provoque `empty_group`.

#### Texte et JSON : correspondance

| Dans le texte | En JSON |
|---|---|
| `rotation "…"` | `title` |
| Lignes `# …` avant le premier `use` | `notes` |
| Un commentaire en fin de ligne `buffN` / `slotN` | Le `note` de l’aura / de l’emplacement |
| Lignes `# …` juste avant `use` (et entre les groupes de la règle) | Le `note` de la règle |
| Un commentaire sur la ligne `use` | Le `name` de la règle |
| Un commentaire en fin de ligne de conditions | Le `comment` du groupe |
| Lignes `# …` après la dernière règle | `footer` |
| — (absent du texte) | `specID`, `ignoreMainIcon`, `enemies`, `spell`, `show`, indicateurs |

Les lignes vides aux extrémités des blocs de commentaires sont supprimées ; à l’intérieur, elles sont conservées sous forme de `""`.

### Importation et stockage

- KeyRota conserve la rotation à l’intérieur du profil. Exporter, dans la fenêtre principale, enregistre le profil KeyRota (JSON) avec sa rotation ; Importer accepte un profil KeyRota et un JSON de rotation seul.
- Nouveau — Depuis un fichier… accepte un `.txt` avec du texte KRC, un JSON de rotation et un profil KeyRota ; Nouveau — Depuis le presse-papiers accepte les mêmes contenus depuis le presse-papiers.
- Dans l’éditeur : Texte et JSON — Coller ou Ouvrir… remplacent la rotation ; les emplacements et les auras de mêmes numéros conservent leurs ID, Avec une cible / En combat et leurs indicateurs si la nouvelle version n’en contient pas.
- Une rotation en texte (sans JSON) reprend les ID et la visibilité des emplacements du profil Better Assistant déjà enregistré dans le profil KeyRota, et les ID des auras également à partir des marques `[703]` de leurs libellés.

### Le profil Better Assistant à partir du JSON

« Créer depuis la rotation », dans l’éditeur, produit la chaîne du profil Better Assistant à partir du JSON de la rotation :

- **12 emplacements** : l’emplacement N est `slots[n = N].spell`, affiché selon `show`. Un emplacement sans ID reste vide.
- **Auras** dans l’ordre, à partir de la première : `auras[n = 1].spell`, `auras[n = 2].spell`… Une aura sans ID au milieu est une erreur.
- **Classe et spécialisation** tirées de `specID`.
- **Compteur d’ennemis** tiré de `enemies.range` et `enemies.combatOnly`.
- Si le profil KeyRota contient déjà un profil Better Assistant de la même spécialisation, ses autres réglages ainsi que les emplacements et les auras correspondants sont conservés.

Dans le jeu : `/ba` — Profile — coller — Apply.

### JSON Schema

Le schéma du format : [keyrota-rotation.schema.json](https://keyrota.app/documentation/keyrota-rotation.schema.json) (draft 2020-12). Il vérifie les champs, les types, les plages, `queue` sans `offGcd` et la forme des chaînes de conditions. Il ne vérifie pas l’unicité de `n` et des noms, l’existence des noms utilisés dans les conditions, ni la limite de 16 après le découpage des chaînes au niveau de ` and ` : KeyRota s’en charge au chargement.

Pour vérifier un fichier :

```text
npx ajv-cli validate --spec=draft2020 -s keyrota-rotation.schema.json -d ma-rotation.json
```


N’ajoutez pas de champ `"$schema"` dans un fichier de rotation : KeyRota le considère comme un champ en trop.

---

<!-- https://keyrota.app/documentation/fr/conditions -->

## Conditions

Une condition est une vérification unique : « Garrot est sur la cible », « l’énergie est d’au moins 70 % », « Burst est activé ». Les conditions forment des groupes (ET), les groupes forment une règle (OU). Dans l’éditeur, vous choisissez une condition dans des listes ; dans le texte KRC et le JSON, elle s’écrit sous forme de chaîne, et c’est ce que montrent les exemples.

### Syntaxe

| Type | Forme | Exemple |
|---|---|---|
| Aura : présente / absente | `Aura.up`, `Aura.down` | `Garrote_DoT.down` |
| Aura : temps restant, cumuls | `Aura.duration op N`, `Aura.stacks op N` | `Rupture_DoT.duration <= 30` |
| Emplacement : prêt / pas prêt | `Slot.ready`, `Slot.oncd` | `Kingsbane.ready` |
| Emplacement : temps de recharge, charges | `Slot.cd op N`, `Slot.charges op N` | `Deathmark.cd <= 3` |
| Emplacement : surbrillance | `Slot.glow`, `Slot.noglow` | `Ambush.glow` |
| Ressource | `Resource op N` | `Combo_Points >= 70` |
| Ennemis à proximité | `enemies op N` | `enemies >= 3` |
| Distance de la cible | `target.distance op N` | `target.distance <= 8` |
| Option | `aoe`, `st`, `cd`, `defensives`, `ground_spells`, `movement` `== 0` ou `== 1` | `cd == 1` |

**Opérateurs :** `<`, `<=`, `==`, `=` (identique à `==`), `>=`, `>`. Il n’existe pas d’opérateur « différent de ».

**Le nombre** `N` est un entier de 0 à 100. Pas de nombres négatifs ni décimaux, et rien au-delà de 100 : `valeur 120 hors de 0..100`.

**Les espaces** autour de l’opérateur sont facultatifs : `Energy>=70` et `Energy >= 70` sont équivalents. Pas d’espace à l’intérieur d’un nom ni entre un nom et sa propriété : `Garrote_DoT.up`, et non `Garrote_DoT .up`.

**Les références** se font par nom (`Garrote_DoT`) ou par numéro : `buff1`, `slot3`, `resource4`. Les mots-clés s’écrivent en minuscules.

### Auras

Une aura est votre amélioration ou votre affaiblissement sur la cible, déclaré dans la liste des auras avec son ID. Les améliorations et les affaiblissements des autres joueurs ne sont pas visibles.

#### .up et .down

`Envenom_Buff.up` : l’aura est présente. `Envenom_Buff.down` : elle est absente. Si l’aura est inconnue (non lue), les deux sont fausses.

```text
use Garrote when  # Garrot : l’appliquer quand il manque
	Garrote_DoT.down
```


#### .duration : temps restant en pourcentage

`Rupture_DoT.duration <= 30` : il ne reste pas plus de 30 % de la durée **totale** de l’aura. La durée totale est celle obtenue lors de cette application : Rupture à 5 points de combo dure 24 s, à 7 points elle dure 32 s, donc 30 % correspondent à 7,2 s et 9,6 s.

> [!IMPORTANT]
> Une aura absente a **0** restant. `Rupture_DoT.duration <= 30` est donc aussi remplie quand Rupture n’est pas du tout là. Pour ne renouveler qu’une aura active, écrivez `Rupture_DoT.up and Rupture_DoT.duration <= 30`, et traitez le cas « l’aura manque » dans un groupe distinct avec `Rupture_DoT.down`.

Dans WoW, la fenêtre de pandémie représente 30 % de la durée : un renouvellement dans cette fenêtre ne fait rien perdre. D’où le seuil habituel `<= 30`.

*Texte KRC:*

```text
use Rupture when  # Rupture
	Combo_Points >= 70 and Rupture_DoT.down  # pas de DoT
	or
	Combo_Points >= 70 and Rupture_DoT.up and Rupture_DoT.duration <= 30  # pandémie
```

*JSON:*

```json
{
  "use": "Rupture",
  "name": "Rupture",
  "when": [
    {"all": ["Combo_Points >= 70", "Rupture_DoT.down"], "comment": "pas de DoT"},
    {"all": ["Combo_Points >= 70", "Rupture_DoT.up", "Rupture_DoT.duration <= 30"], "comment": "pandémie"}
  ]
}
```


Des secondes au pourcentage : `pourcentage = secondes / durée totale × 100`. Garrot dure 18 s : « il reste 14 s » s’écrit `<= 78`, « il reste 5,4 s » s’écrit `<= 30`.

**Une aura sans durée** (Camouflage et autres) indique toujours **1** restant. Pour ces auras, utilisez uniquement `.up` et `.down`.

#### .stacks : nombre de cumuls

`Opportunity.stacks >= 6` : l’aura a 6 cumuls ou plus. Une aura absente a 0 cumul.

> [!NOTE]
> Le décompte des cumuls commence à deux : une aura avec un seul cumul indique **0**, comme une aura sans compteur. Pour vérifier qu’une aura est présente, utilisez `.up` ; réservez `.stacks` aux seuils de 2 et plus.

```text
use Pistol_Shot when  # Coup de pistolet à 6 cumuls d’Occasion
	Opportunity.stacks >= 6 and Combo_Points < 80
```


### Emplacements

Les conditions d’emplacement lisent l’état d’**un autre** bouton : « presser Envenimer seulement tant que Marque létale n’est pas encore prête », etc. L’emplacement de la règle elle-même est vérifié automatiquement : si son sort ne peut pas être utilisé, KeyRota passe simplement à la règle suivante.

#### .ready et .oncd

`Kingsbane.ready` : le sort de l’emplacement peut être utilisé, sans tenir compte du temps de recharge global. Il faut pour cela que toutes ces conditions soient réunies :

- le sort est appris (le talent est pris) ;
- la ressource est suffisante ;
- la cible est à portée, si une cible est nécessaire ;
- le temps de recharge restant est inférieur à 0,2 s, ou une charge est disponible ;
- Better Assistant affiche l’emplacement (Avec une cible : vous avez une cible ; En combat : vous êtes en combat).

`Kingsbane.oncd` : l’emplacement n’est **pas prêt**, pour l’une quelconque de ces raisons, pas seulement à cause du temps de recharge. Si l’état est inconnu, les deux sont fausses.

```text
use Preparation when  # Préparation quand Poussée d'adrénaline, Entre les deux yeux et Série meurtrière sont en recharge
	Adrenaline_Rush.oncd and Between_the_Eyes.oncd and Killing_Spree.oncd
```


#### .cd : temps de recharge restant en pourcentage

`Deathmark.cd <= 3` : il ne reste pas plus de 3 % du temps de recharge total. `0` signifie prêt, `100` vient d’être utilisé. Le temps de recharge global n’est pas inclus. Pour un sort à charges, `.cd` est la recharge de la charge **suivante** : le sort peut donc être prêt avec `cd > 0`.

| Temps de recharge | 1 % = | Exemple |
|---|---|---|
| 30 s | 0,3 s | `X.cd <= 10` : ≤ 3 s restantes |
| 1 min | 0,6 s | `Kingsbane.cd <= 3` : ≤ 1,8 s restante |
| 2 min | 1,2 s | `Deathmark.cd <= 3` : ≤ 3,6 s restantes ; `Deathmark.cd >= 44` : encore ≥ 52 s |
| 3 min | 1,8 s | `X.cd >= 50` : encore ≥ 90 s |

Usage typique : « garder pour un temps de recharge majeur » : ne pas utiliser Plaie des rois si Marque létale revient bientôt, l’utiliser si Marque létale est encore loin.

```text
use Kingsbane when  # Plaie des rois
	cd == 1 and Deathmark_DoT.up  # sous Marque létale
	or
	cd == 1 and Deathmark.cd >= 44  # Marque létale dans plus de 52 s
```


#### .charges

`Barbed_Shot.charges >= 2` : le sort a 2 charges ou plus. Les sorts sans charges en ont 0. Un modèle typique évite que les charges plafonnent :

```text
use Barbed_Shot when  # Tir acéré
	Barbed_Shot.charges >= 2  # les deux charges : ne pas gaspiller la recharge
	or
	Barbed_Shot.charges == 1 and Barbed_Shot.cd <= 20  # la deuxième revient bientôt
```


#### .glow et .noglow : le bouton s’illumine

`Ambush.glow` : le jeu met en surbrillance le bouton de ce sort (la même surbrillance que vous voyez sur votre barre d’action lors d’un proc). `Ambush.noglow` : il n’est pas en surbrillance. N’utilisez `.glow` que si le bouton de ce sort s’illumine réellement dans le jeu ; en cas de doute, vérifiez plutôt l’amélioration du proc : `Blindside.up`.

### Ressources

`Energy >= 70` : au moins 70 % de l’énergie maximale. **Toutes les ressources sont des pourcentages** de 0 à 100 : vie, énergie, mana, rage, runes, points de combo.

| Ressource | Numéro | Exemple |
|---|---|---|
| Vie du joueur | `resource1` (`PlayerHP`) | `PlayerHP <= 40` : vie à 40 % ou moins |
| Vie de la cible | `resource2` (`TargetHP`) | `TargetHP >= 50` : la cible n’est pas encore à la moitié de sa vie. Inconnue sans cible |
| Ressources de la spécialisation | à partir de `resource3` | `Energy >= 70`, `Combo_Points >= 70`, `Rage >= 40` |

**Conversion en pourcentage :** `pourcentage = valeur / maximum × 100`. Avec 250 d’énergie maximum, 175 d’énergie représentent 70 %. L’énergie maximale et les autres ressources varient selon les talents : les seuils en pourcentage se transposent donc mieux d’un personnage à l’autre que les valeurs brutes.

**Points de combo.** Avec un maximum de 7 points de combo, un point vaut environ 14,3 %. La valeur est arrondie à l’entier, et selon l’arrondi, 2 points se lisent 28 ou 29, 3 points 42 ou 43, 6 points 85 ou 86. Placez donc le seuil **à mi-chemin entre deux paliers** : il est alors correct quel que soit l’arrondi.

| Points de combo | % | « au moins N » | « au plus N » |
|---|---|---|---|
| 0 | 0 | — | `< 7` |
| 1 | 14 | `>= 7` | `< 20` |
| 2 | 28–29 | `>= 20` | `< 35` |
| 3 | 42–43 | `>= 35` | `< 50` |
| 4 | 57 | `>= 50` | `< 65` |
| 5 | 71 | `>= 65` (`>= 70`) | `< 80` |
| 6 | 85–86 | `>= 80` | `< 95` |
| 7 | 100 | `>= 95` | — |

Pour un autre maximum, « au moins N » s’écrit `(N − 0,5) / maximum × 100`. Avec 5 points de combo au maximum, « au moins 4 » donne `>= 70` et « au moins 5 » donne `>= 90`.

### Ennemis à proximité

`enemies >= 3` : 3 ennemis ou plus dans le rayon du compteur. Le rayon et « Ennemis en combat uniquement » se règlent sur la page Général (`enemies.range` et `enemies.combatOnly` en JSON). Si le nombre est inconnu, la condition est fausse.

- Pour que les ennemis soient comptés, les barres de vie des ennemis (nameplates) doivent être affichées dans le jeu (touche V par défaut), sans masquer les ennemis mineurs.
- Choisissez le rayon en fonction de vos techniques : Éventail de couteaux touche à 8 mètres, donc 8 est le rayon juste pour « Éventail de couteaux ou Estropier ».
- Pour une cible unique, `enemies <= 1` est plus sûr que `enemies == 1` : la règle continue de fonctionner si l’ennemi n’est pas compté.

### Distance de la cible

`target.distance <= 8` : la cible se trouve à 8 mètres ou moins. Sans cible, la distance est inconnue et la condition est fausse. La distance est approximative : la condition n’est remplie que si la distance respecte le seuil de façon certaine ; dans les cas limites, elle est fausse.

```text
use Pistol_Shot when  # la cible est hors de portée de mêlée mais à 20 mètres ou moins
	target.distance >= 10 and target.distance <= 20
```


### Options du panneau

Les options sont les boutons du panneau de réglages rapides affiché au-dessus du jeu, avec leurs raccourcis. C’est la rotation qui décide de leur signification.

| Condition | Bouton du panneau | Touche : Windows, macOS | Signification habituelle |
|---|---|---|---|
| `aoe == 1` | Cibles : Plusieurs | F2, ⌃⇧T, en cycle | Forcer le mode multicible |
| `st == 1` | Cibles : Une | F2, ⌃⇧T, en cycle | Forcer une cible unique |
| `aoe == 0 and st == 0` | Cibles : Auto | F2, ⌃⇧T, en cycle | Les règles décident, généralement d’après `enemies` |
| `cd == 1` | Burst | F3, ⌃⇧B | Temps de recharge majeurs : utiliser maintenant ou garder |
| `defensives == 1` | Soins / défense | — | Soins et techniques défensives |
| `ground_spells == 1` | Au sol | — | Sorts ciblés au sol |
| `movement == 1` | Déplacement | — | Actions en déplacement |

- Comparez uniquement avec `== 0` ou `== 1`.
- **`cd == 1` est le bouton Burst, pas le temps de recharge d’un sort.** Le temps de recharge d’un emplacement s’écrit `Slot.cd`.
- `aoe` et `st` ne valent jamais 1 en même temps. La touche du mode de cibles passe en cycle par Auto, Une, Plusieurs.
- Par défaut, Burst est activé, le mode de cibles est Auto et les autres boutons sont désactivés. KeyRota mémorise leur état.
- Un bouton du panneau n’est actif que si la rotation lit cette option ; avec le profil Blizzard, ils sont tous grisés.
- Les options ne sont jamais inconnues.

### Évaluation des conditions

| Condition | Valeur présente | Aura absente | Inconnue |
|---|---|---|---|
| `X.up` | vraie | fausse | **fausse** |
| `X.down` | fausse | vraie | **fausse** |
| `X.duration op N`, `X.stacks op N` | comparée | comparée avec **0** | **fausse** |
| `X.ready` / `X.oncd` | selon la disponibilité | — | **fausse** (les deux) |
| `X.glow` / `X.noglow` | selon la surbrillance | — | **fausse** (les deux) |
| `X.cd`, `X.charges`, une ressource, `enemies`, `target.distance` | comparée | — | **fausse** |
| une option | comparée | — | jamais |

Un groupe est vrai quand toutes ses conditions sont vraies. Une règle est remplie quand au moins un groupe est vrai, ou quand elle n’a aucun groupe.

### « Non », parenthèses et OU dans un groupe

KRC n’a ni `not`, ni `!=`, ni parenthèses. Tout s’exprime avec des groupes :

- **« Non »** s’écrit avec la condition opposée : le contraire de `.up` est `.down`, celui de `.ready` est `.oncd`, celui de `.glow` est `.noglow` ; pour les nombres, l’opérateur inverse : le contraire de `>= 70` est `< 70`.
- **(A ou B) et C** s’écrit avec deux groupes : `A and C`, `B and C`.
- **A et non (B et C)** s’écrit avec deux groupes : `A and non-B`, `A and non-C`.
- **La même condition dans chaque groupe** (comme la protection d’une canalisation) se répète dans chaque groupe.

```text
use Fan_of_Knives when  # Éventail de couteaux : (mode Plusieurs OU Auto et 2+ ennemis) ET moins de 5 points de combo
	aoe == 1 and Combo_Points < 70
	or
	st == 0 and enemies >= 2 and Combo_Points < 70
```


### Aide-mémoire

| Condition | Signification |
|---|---|
| `X.up` / `X.down` | aura présente / absente |
| `X.duration <= 30` | ≤ 30 % restant (une aura absente a 0) |
| `X.up and X.duration <= 30` | active et à renouveler |
| `X.stacks >= 2` | 2 cumuls ou plus (1 cumul se lit 0) |
| `X.ready` / `X.oncd` | emplacement prêt / pas prêt, quelle qu’en soit la raison |
| `X.cd <= 3` | ≤ 3 % du temps de recharge restant |
| `X.charges >= 2` | 2 charges ou plus |
| `X.glow` / `X.noglow` | bouton en surbrillance / non |
| `PlayerHP <= 40` | votre vie ≤ 40 % |
| `TargetHP >= 50` | la cible à ≥ 50 % (fausse sans cible) |
| `Combo_Points >= 70` | 5 points de combo ou plus sur 7 |
| `Energy >= 70` | énergie ≥ 70 % |
| `enemies >= 3` | 3 ennemis ou plus dans le rayon |
| `target.distance <= 8` | la cible à 8 mètres ou moins (fausse sans cible) |
| `aoe == 1` / `st == 1` | mode Plusieurs / Une |
| `aoe == 0 and st == 0` | mode Auto |
| `cd == 1` | Burst activé |
| `defensives == 1` | Soins / défense activé |
| `ground_spells == 1` | Au sol activé |
| `movement == 1` | Déplacement activé |

---

<!-- https://keyrota.app/documentation/fr/patterns -->

## Exemples de modèles

Chaque modèle est une petite rotation complète : le texte KRC à gauche, le même JSON à droite. Collez-le dans l’éditeur (Texte et JSON — Coller) pour voir à quoi il ressemble sur les pages Emplacements et Règles. Les ID de sort sont réels, tirés de Wowhead. À la fin : des [rotations complètes](#example-files).

### Un DoT renouvelé dans la fenêtre de pandémie

Appliquez un DoT quand il manque et renouvelez-le quand il reste 30 % ou moins : un renouvellement dans cette fenêtre ne fait rien perdre. Une aura absente a 0 restant : le renouvellement fait donc l’objet d’un groupe distinct avec `.up`.

*Texte KRC:*

```text
rotation "Modèle : DoT avec la fenêtre de pandémie"

buff1	Garrote_DoT = "Garrot sur la cible [703]"
slot1	Garrote = "Garrot"
slot4	Mutilate = "Estropier"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Garrote when  # Garrot
	Garrote_DoT.down  # pas de DoT
	or
	Garrote_DoT.up and Garrote_DoT.duration <= 30  # pandémie

use Mutilate when  # Estropier
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : DoT avec la fenêtre de pandémie",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 1, "alias": "Garrote_DoT", "label": "Garrot sur la cible [703]", "spell": 703}
  ],
  "slots": [
    {"n": 1, "alias": "Garrote", "label": "Garrot", "spell": 703},
    {"n": 4, "alias": "Mutilate", "label": "Estropier", "spell": 1329}
  ],
  "rules": [
    {"use": "Garrote", "name": "Garrot", "when": [
      {"all": ["Garrote_DoT.down"], "comment": "pas de DoT"},
      {"all": ["Garrote_DoT.up", "Garrote_DoT.duration <= 30"], "comment": "pandémie"}
    ]},
    {"use": "Mutilate", "name": "Estropier"}
  ]
}
```


- Pour éviter de poser un nouveau DoT sur une cible sur le point de mourir quand il y a 3 cibles ou plus, ajoutez `TargetHP >= 50` au groupe « pas de DoT », ainsi qu’un groupe distinct `Garrote_DoT.down and enemies <= 2` pour une ou deux cibles.
- Un DoT long à durée variable (Rupture : 4 s + 4 s par point de combo) fonctionne de la même façon : les pourcentages se rapportent à la durée de cette application.

### Générateur et dépense selon les points de combo

Dépensez à partir de 5 points de combo sur 7, générez en dessous. Les seuils sont placés à mi-chemin entre deux paliers, voir le [tableau des points de combo](https://keyrota.app/documentation/fr/conditions#resources).

*Texte KRC:*

```text
rotation "Modèle : générateur et dépense"

slot3	Envenom = "Envenimer"
slot4	Mutilate = "Estropier"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Envenom when  # Envenimer
	Combo_Points >= 70  # 5+ points de combo

use Mutilate when  # Estropier
	Combo_Points < 70  # moins de 5 points de combo
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : générateur et dépense",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "slots": [
    {"n": 3, "alias": "Envenom", "label": "Envenimer", "spell": 32645},
    {"n": 4, "alias": "Mutilate", "label": "Estropier", "spell": 1329}
  ],
  "rules": [
    {"use": "Envenom", "name": "Envenimer", "when": [
      {"all": ["Combo_Points >= 70"], "comment": "5+ points de combo"}
    ]},
    {"use": "Mutilate", "name": "Estropier", "when": [
      {"all": ["Combo_Points < 70"], "comment": "moins de 5 points de combo"}
    ]}
  ]
}
```


Un générateur avec `Combo_Points < 70` ne fait pas déborder les points de combo : à partir de 5, il se tait même si la dépense n’est pas encore prête (pas assez d’énergie), et KeyRota attend.

### Mise en réserve de ressources

Ne pas dépenser tout de suite, maintenir l’amélioration et mettre de l’énergie en réserve : Envenimer quand son amélioration se termine, sous Marque létale, ou quand l’énergie est élevée. Le reste du temps, aucune règle ne convient à partir de 5 points de combo, et KeyRota attend davantage d’énergie : c’est la mise en réserve.

*Texte KRC:*

```text
rotation "Modèle : mise en réserve d’énergie"

buff3	Envenom_Buff = "Envenimer [32645]"
buff4	Deathmark_DoT = "Marque létale sur la cible [360194]"
slot3	Envenom = "Envenimer"
slot4	Mutilate = "Estropier"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Envenom when  # Envenimer
	Combo_Points >= 70 and Envenom_Buff.down  # pas d’amélioration
	or
	Combo_Points >= 70 and Envenom_Buff.duration <= 20  # l’amélioration se termine
	or
	Combo_Points >= 70 and Deathmark_DoT.up  # sous Marque létale
	or
	Combo_Points >= 70 and Energy >= 70  # ne pas plafonner l’énergie

use Mutilate when  # Estropier
	Combo_Points < 70
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : mise en réserve d’énergie",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 3, "alias": "Envenom_Buff", "label": "Envenimer [32645]", "spell": 32645},
    {"n": 4, "alias": "Deathmark_DoT", "label": "Marque létale sur la cible [360194]", "spell": 360194}
  ],
  "slots": [
    {"n": 3, "alias": "Envenom", "label": "Envenimer", "spell": 32645},
    {"n": 4, "alias": "Mutilate", "label": "Estropier", "spell": 1329}
  ],
  "rules": [
    {"use": "Envenom", "name": "Envenimer", "when": [
      {"all": ["Combo_Points >= 70", "Envenom_Buff.down"], "comment": "pas d’amélioration"},
      {"all": ["Combo_Points >= 70", "Envenom_Buff.duration <= 20"], "comment": "l’amélioration se termine"},
      {"all": ["Combo_Points >= 70", "Deathmark_DoT.up"], "comment": "sous Marque létale"},
      {"all": ["Combo_Points >= 70", "Energy >= 70"], "comment": "ne pas plafonner l’énergie"}
    ]},
    {"use": "Mutilate", "name": "Estropier", "when": [
      {"all": ["Combo_Points < 70"]}
    ]}
  ]
}
```


- Le seuil `Energy >= 70` empêche l’énergie de plafonner.
- Le groupe `Envenom_Buff.duration <= 20` se déclenche aussi sans l’amélioration (0 restant) ; le groupe `.down` est là pour la clarté.
- Pour ajuster la mise en réserve, ne modifiez que le seuil d’énergie : plus bas, la dépense est plus précoce ; plus haut, la réserve dure plus longtemps.

### Cible unique et plusieurs cibles

Le joueur choisit le mode de cibles avec la touche du mode de cibles (elle passe en cycle par Auto, Une, Plusieurs) ; en mode Auto, les règles décident d’après le nombre d’ennemis. Chaque règle AoE reçoit deux groupes, « mode Plusieurs » et « Auto avec 2 ennemis ou plus » ; la règle de cible unique reçoit « mode Une » et « Auto avec un ennemi au plus ».

*Texte KRC:*

```text
rotation "Modèle : une ou plusieurs cibles"

slot3	Envenom = "Envenimer"
slot4	Mutilate = "Estropier"
slot6	Fan_of_Knives = "Éventail de couteaux"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Envenom when  # Envenimer
	Combo_Points >= 70

use Fan_of_Knives when  # Éventail de couteaux : 2+ cibles
	aoe == 1 and Combo_Points < 70  # mode Plusieurs
	or
	st == 0 and enemies >= 2 and Combo_Points < 70  # mode Auto, 2+ ennemis

use Mutilate when  # Estropier : cible unique
	st == 1 and Combo_Points < 70  # mode Une
	or
	aoe == 0 and enemies <= 1 and Combo_Points < 70  # mode Auto, un ennemi
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : une ou plusieurs cibles",
  "specID": 259,
  "enemies": {"range": 8, "combatOnly": true},
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "slots": [
    {"n": 3, "alias": "Envenom", "label": "Envenimer", "spell": 32645},
    {"n": 4, "alias": "Mutilate", "label": "Estropier", "spell": 1329},
    {"n": 6, "alias": "Fan_of_Knives", "label": "Éventail de couteaux", "spell": 51723}
  ],
  "rules": [
    {"use": "Envenom", "name": "Envenimer", "when": [
      {"all": ["Combo_Points >= 70"]}
    ]},
    {"use": "Fan_of_Knives", "name": "Éventail de couteaux : 2+ cibles", "when": [
      {"all": ["aoe == 1", "Combo_Points < 70"], "comment": "mode Plusieurs"},
      {"all": ["st == 0", "enemies >= 2", "Combo_Points < 70"], "comment": "mode Auto, 2+ ennemis"}
    ]},
    {"use": "Mutilate", "name": "Estropier : cible unique", "when": [
      {"all": ["st == 1", "Combo_Points < 70"], "comment": "mode Une"},
      {"all": ["aoe == 0", "enemies <= 1", "Combo_Points < 70"], "comment": "mode Auto, un ennemi"}
    ]}
  ]
}
```


- `st == 0 and enemies >= 2` signifie « pas en mode Une » : en mode Plusieurs, la règle se déclenche de toute façon par son premier groupe.
- `enemies <= 1` est plus sûr que `enemies == 1` : sur une cible unique, l’ennemi peut ne pas être compté.
- Prenez le rayon du compteur (`enemies.range`) d’après votre technique AoE : Éventail de couteaux touche à 8 mètres.

### Temps de recharge sur Burst et « seulement sous le temps de recharge »

`cd == 1` est le bouton Burst. Un temps de recharge majeur n’est pressé que tant que Burst est activé, et vous le gardez en réserve en désactivant Burst, par exemple avant une phase où le boss est insensible. Ce qui renforce la fenêtre du temps de recharge n’est pressé que pendant celle-ci : ici, Disparition seulement tant que Marque létale est sur la cible, et Plaie des rois sous Marque létale ou quand Marque létale est encore loin.

*Texte KRC:*

```text
rotation "Modèle : Burst"

buff1	Garrote_DoT = "Garrot sur la cible [703]"
buff2	Rupture_DoT = "Rupture sur la cible [1943]"
buff4	Deathmark_DoT = "Marque létale sur la cible [360194]"
buff10	Vanish_Buff = "Disparition [11327]"
slot1	Garrote = "Garrot"
slot4	Mutilate = "Estropier"
slot8	Deathmark = "Marque létale"
slot9	Kingsbane = "Plaie des rois"
slot10	Vanish = "Disparition"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Garrote when  # Garrot depuis le Camouflage
	Vanish_Buff.up

use Deathmark when  # Marque létale
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up  # Burst activé, DoT actifs

use Kingsbane when  # Plaie des rois
	cd == 1 and Deathmark_DoT.up and Combo_Points < 50  # sous Marque létale, 0-3 points de combo
	or
	cd == 1 and Deathmark.cd >= 44 and Combo_Points < 50  # Marque létale dans plus de 52 s

use Vanish when  # Disparition
	Deathmark_DoT.up and Combo_Points < 65  # sous Marque létale, 0-4 points de combo

use Mutilate when  # Estropier
	Combo_Points < 70
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : Burst",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 1, "alias": "Garrote_DoT", "label": "Garrot sur la cible [703]", "spell": 703},
    {"n": 2, "alias": "Rupture_DoT", "label": "Rupture sur la cible [1943]", "spell": 1943},
    {"n": 4, "alias": "Deathmark_DoT", "label": "Marque létale sur la cible [360194]", "spell": 360194},
    {"n": 10, "alias": "Vanish_Buff", "label": "Disparition [11327]", "spell": 11327}
  ],
  "slots": [
    {"n": 1, "alias": "Garrote", "label": "Garrot", "spell": 703},
    {"n": 4, "alias": "Mutilate", "label": "Estropier", "spell": 1329},
    {"n": 8, "alias": "Deathmark", "label": "Marque létale", "spell": 360194},
    {"n": 9, "alias": "Kingsbane", "label": "Plaie des rois", "spell": 385627},
    {"n": 10, "alias": "Vanish", "label": "Disparition", "spell": 1856, "offGcd": true, "queue": true}
  ],
  "rules": [
    {"use": "Garrote", "name": "Garrot depuis le Camouflage", "when": [
      {"all": ["Vanish_Buff.up"]}
    ]},
    {"use": "Deathmark", "name": "Marque létale", "when": [
      {"all": ["cd == 1", "Garrote_DoT.up", "Rupture_DoT.up"], "comment": "Burst activé, DoT actifs"}
    ]},
    {"use": "Kingsbane", "name": "Plaie des rois", "when": [
      {"all": ["cd == 1", "Deathmark_DoT.up", "Combo_Points < 50"], "comment": "sous Marque létale, 0-3 points de combo"},
      {"all": ["cd == 1", "Deathmark.cd >= 44", "Combo_Points < 50"], "comment": "Marque létale dans plus de 52 s"}
    ]},
    {"use": "Vanish", "name": "Disparition", "when": [
      {"all": ["Deathmark_DoT.up", "Combo_Points < 65"], "comment": "sous Marque létale, 0-4 points de combo"}
    ]},
    {"use": "Mutilate", "name": "Estropier", "when": [
      {"all": ["Combo_Points < 70"]}
    ]}
  ]
}
```


- Disparition est hors GCD, mais a aussi Fenêtre de file d’attente (**O + Q**) : sinon elle serait pressée en plein GCD juste après Plaie des rois, avant l’arrivée des points de combo de Plaie des rois, et vérifierait l’ancien nombre.
- Désactivez Burst, et Marque létale comme Plaie des rois attendent ; Disparition attend Marque létale.
- Plaie des rois à 0–3 points de combo : 5 points de plus arrivent après elle, et aucun n’est perdu.

### Protection d’une canalisation

Le jeu termine certaines canalisations un peu avant le dernier coup, et l’appui suivant la coupe. La protection repose sur l’aura de la canalisation elle-même : tant qu’il en reste plus de 8 %, aucune règle n’est remplie. La condition figure dans **chaque** groupe de chaque règle. L’indicateur **C** sur l’emplacement de la canalisation l’empêche d’être pressé deux fois au démarrage.

*Texte KRC:*

```text
rotation "Modèle : protection d’une canalisation"

buff10	Killing_Spree_Buff = "Série meurtrière, canalisation [51690]"
slot8	Killing_Spree = "Série meurtrière"
slot9	Dispatch = "Couperet"
slot11	Sinister_Strike = "Attaque pernicieuse"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Killing_Spree when  # Série meurtrière
	Combo_Points >= 80 and Killing_Spree_Buff.duration <= 8

use Dispatch when  # Couperet
	Combo_Points >= 80 and Killing_Spree_Buff.duration <= 8

use Sinister_Strike when  # Attaque pernicieuse
	Combo_Points < 80 and Killing_Spree_Buff.duration <= 8
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : protection d’une canalisation",
  "specID": 260,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 10, "alias": "Killing_Spree_Buff", "label": "Série meurtrière, canalisation [51690]", "spell": 51690}
  ],
  "slots": [
    {"n": 8, "alias": "Killing_Spree", "label": "Série meurtrière", "spell": 51690, "channel": true},
    {"n": 9, "alias": "Dispatch", "label": "Couperet", "spell": 2098},
    {"n": 11, "alias": "Sinister_Strike", "label": "Attaque pernicieuse", "spell": 193315}
  ],
  "rules": [
    {"use": "Killing_Spree", "name": "Série meurtrière", "when": [
      {"all": ["Combo_Points >= 80", "Killing_Spree_Buff.duration <= 8"]}
    ]},
    {"use": "Dispatch", "name": "Couperet", "when": [
      {"all": ["Combo_Points >= 80", "Killing_Spree_Buff.duration <= 8"]}
    ]},
    {"use": "Sinister_Strike", "name": "Attaque pernicieuse", "when": [
      {"all": ["Combo_Points < 80", "Killing_Spree_Buff.duration <= 8"]}
    ]}
  ]
}
```


- Pourquoi `<= 8` et pas `.down` : sans canalisation, l’aura a 0 restant et la condition est remplie ; pendant la canalisation, elle n’attend que les 8 % finaux, et non des fractions de seconde supplémentaires après la fin.
- Si l’aura n’est pas lue, la condition est fausse dans toutes les règles et KeyRota ne presse rien : mieux vaut sauter un appui que couper la canalisation. L’aura de la canalisation doit donc figurer dans le profil Better Assistant.

### Une macro hors GCD dans la fenêtre de file d’attente

Il existe deux sortes de « hors GCD » :
- **O** : le bouton est pressé immédiatement, même en plein GCD. C’est ainsi qu’Osselets relancés (qui prolonge Jet d’osselets) ne fait perdre aucun temps.
- **O + Q** : le bouton est hors GCD, mais sa macro ou son résultat dépend du GCD. La macro Poussée d'adrénaline avec Série meurtrière en deuxième ligne (Série meurtrière est soumise au GCD) est pressée dans la fenêtre de file d’attente, à la fin du GCD, et Série meurtrière part juste après Poussée d'adrénaline.

*La macro dans le jeu (emplacement 1):*

```text
#showtooltip Poussée d'adrénaline
/cast Poussée d'adrénaline
/cast Série meurtrière
```


*Texte KRC:*

```text
rotation "Modèle : hors GCD"

buff2	Triple_Threat = "Jet d’osselets, niveau 3 [1214935]"
buff3	Jackpot = "Jet d’osselets, niveau 4 [1214937]"
buff6	Adrenaline_Rush_Buff = "Poussée d'adrénaline [13750]"
slot1	Adrenaline_Rush = "Poussée d'adrénaline + Série meurtrière (macro)"
slot4	Keep_It_Rolling = "Osselets relancés"
slot11	Sinister_Strike = "Attaque pernicieuse"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Adrenaline_Rush when  # Poussée d'adrénaline (+ Série meurtrière par la macro)
	Adrenaline_Rush_Buff.down and Combo_Points >= 7 and Combo_Points < 80  # 1-5 points de combo : à 0, la Série meurtrière de la macro ne part pas

use Keep_It_Rolling when  # Osselets relancés
	Triple_Threat.up
	or
	Jackpot.up

use Sinister_Strike when  # Attaque pernicieuse
	Combo_Points < 80
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : hors GCD",
  "specID": 260,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 2, "alias": "Triple_Threat", "label": "Jet d’osselets, niveau 3 [1214935]", "spell": 1214935},
    {"n": 3, "alias": "Jackpot", "label": "Jet d’osselets, niveau 4 [1214937]", "spell": 1214937},
    {"n": 6, "alias": "Adrenaline_Rush_Buff", "label": "Poussée d'adrénaline [13750]", "spell": 13750}
  ],
  "slots": [
    {"n": 1, "alias": "Adrenaline_Rush", "label": "Poussée d'adrénaline + Série meurtrière (macro)", "spell": 13750, "offGcd": true, "queue": true},
    {"n": 4, "alias": "Keep_It_Rolling", "label": "Osselets relancés", "spell": 381989, "offGcd": true},
    {"n": 11, "alias": "Sinister_Strike", "label": "Attaque pernicieuse", "spell": 193315}
  ],
  "rules": [
    {"use": "Adrenaline_Rush", "name": "Poussée d'adrénaline (+ Série meurtrière par la macro)", "when": [
      {"all": ["Adrenaline_Rush_Buff.down", "Combo_Points >= 7", "Combo_Points < 80"], "comment": "1-5 points de combo : à 0, la Série meurtrière de la macro ne part pas"}
    ]},
    {"use": "Keep_It_Rolling", "name": "Osselets relancés", "when": [
      {"all": ["Triple_Threat.up"]},
      {"all": ["Jackpot.up"]}
    ]},
    {"use": "Sinister_Strike", "name": "Attaque pernicieuse", "when": [
      {"all": ["Combo_Points < 80"]}
    ]}
  ]
}
```


L’ID d’un emplacement de macro est celui du sort principal de la macro (Poussée d'adrénaline, 13750) : Better Assistant s’en sert pour placer le sort de la macro dans l’emplacement, et KeyRota prend la touche du bouton de la macro sur votre barre.

### Une défense selon la vie

Un soin ou une technique défensive en dessous d’un seuil de vie, uniquement quand Soins / défense est activé dans le panneau. L’emplacement est affiché **en combat** (En combat, `"show": "combat"`) pour fonctionner sans cible. La règle vient en premier : à faible vie, elle compte plus que les dégâts.

*Texte KRC:*

```text
rotation "Modèle : une défense selon la vie"

slot4	Mutilate = "Estropier"
slot11	Crimson_Vial = "Fiole cramoisie"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Crimson_Vial when  # Fiole cramoisie
	defensives == 1 and PlayerHP <= 40  # vie à 40 % ou moins

use Mutilate when  # Estropier
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : une défense selon la vie",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "slots": [
    {"n": 4, "alias": "Mutilate", "label": "Estropier", "spell": 1329},
    {"n": 11, "alias": "Crimson_Vial", "label": "Fiole cramoisie", "spell": 185311, "show": "combat"}
  ],
  "rules": [
    {"use": "Crimson_Vial", "name": "Fiole cramoisie", "when": [
      {"all": ["defensives == 1", "PlayerHP <= 40"], "comment": "vie à 40 % ou moins"}
    ]},
    {"use": "Mutilate", "name": "Estropier"}
  ]
}
```


Soins / défense est désactivé par défaut : activez-le dans le panneau de réglages rapides si vous voulez des défenses automatiques.

### Procs : par amélioration ou par surbrillance

Vérifiez un proc par son amélioration : dans la rotation de raid Assassinat, l’amélioration Angle mort (`Blindside.up`) autorise la règle d’Embuscade. Si le jeu met le bouton en surbrillance lors d’un proc, une règle peut lire la surbrillance (`Ambush.glow`), mais seulement si vous voyez réellement cette surbrillance sur votre barre.

*Texte KRC:*

```text
rotation "Modèle : un proc"

buff7	Blindside = "Angle mort [121153]"
slot4	Mutilate = "Estropier"
slot5	Ambush = "Embuscade"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Ambush when  # Embuscade (Angle mort)
	Blindside.up and Combo_Points < 70

use Mutilate when  # Estropier
	Combo_Points < 70
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : un proc",
  "specID": 259,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 7, "alias": "Blindside", "label": "Angle mort [121153]", "spell": 121153}
  ],
  "slots": [
    {"n": 4, "alias": "Mutilate", "label": "Estropier", "spell": 1329},
    {"n": 5, "alias": "Ambush", "label": "Embuscade", "spell": 8676}
  ],
  "rules": [
    {"use": "Ambush", "name": "Embuscade (Angle mort)", "when": [
      {"all": ["Blindside.up", "Combo_Points < 70"]}
    ]},
    {"use": "Mutilate", "name": "Estropier", "when": [
      {"all": ["Combo_Points < 70"]}
    ]}
  ]
}
```


### Charges

Un sort à charges est pressé à deux charges ou quand la deuxième est presque revenue, pour que sa recharge ne soit jamais à l’arrêt. Exemple : Tir acéré du chasseur (2 charges).

*Texte KRC:*

```text
rotation "Modèle : charges"

slot1	Barbed_Shot = "Tir acéré"
slot2	Kill_Command = "Ordre de tuer"
resource1	PlayerHP
resource2	TargetHP
resource3	Focus

use Barbed_Shot when  # Tir acéré
	Barbed_Shot.charges >= 2  # les deux charges
	or
	Barbed_Shot.charges == 1 and Barbed_Shot.cd <= 20  # la deuxième revient bientôt

use Kill_Command when  # Ordre de tuer
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : charges",
  "specID": 253,
  "resources": ["PlayerHP", "TargetHP", "Focus"],
  "slots": [
    {"n": 1, "alias": "Barbed_Shot", "label": "Tir acéré", "spell": 217200},
    {"n": 2, "alias": "Kill_Command", "label": "Ordre de tuer", "spell": 34026}
  ],
  "rules": [
    {"use": "Barbed_Shot", "name": "Tir acéré", "when": [
      {"all": ["Barbed_Shot.charges >= 2"], "comment": "les deux charges"},
      {"all": ["Barbed_Shot.charges == 1", "Barbed_Shot.cd <= 20"], "comment": "la deuxième revient bientôt"}
    ]},
    {"use": "Kill_Command", "name": "Ordre de tuer"}
  ]
}
```


Pour un sort à charges, `.cd` est la recharge de la charge suivante : `Barbed_Shot.cd <= 20` signifie qu’il reste au plus 20 % de sa recharge.

### Distance de la cible

Quand la cible est hors de portée de mêlée mais à portée d’une technique à distance, pressez celle-ci au lieu de rester inactif. Sans cible, la distance est inconnue et la règle se tait.

*Texte KRC:*

```text
rotation "Modèle : distance"

slot10	Pistol_Shot = "Coup de pistolet"
slot11	Sinister_Strike = "Attaque pernicieuse"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Pistol_Shot when  # Coup de pistolet : la cible est loin
	target.distance >= 10 and target.distance <= 20 and Combo_Points < 80

use Sinister_Strike when  # Attaque pernicieuse
	Combo_Points < 80
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : distance",
  "specID": 260,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "slots": [
    {"n": 10, "alias": "Pistol_Shot", "label": "Coup de pistolet", "spell": 185763},
    {"n": 11, "alias": "Sinister_Strike", "label": "Attaque pernicieuse", "spell": 193315}
  ],
  "rules": [
    {"use": "Pistol_Shot", "name": "Coup de pistolet : la cible est loin", "when": [
      {"all": ["target.distance >= 10", "target.distance <= 20", "Combo_Points < 80"]}
    ]},
    {"use": "Sinister_Strike", "name": "Attaque pernicieuse", "when": [
      {"all": ["Combo_Points < 80"]}
    ]}
  ]
}
```


Une règle de mêlée n’a pas besoin de vérifier la distance : si la cible est trop loin, le sort ne peut pas être utilisé, et KeyRota passe d’elle-même à la règle suivante.

### Déplacement

Le bouton Déplacement du panneau est votre signal à la rotation : « je vais devoir courir ». C’est la rotation qui décide quoi faire, par exemple passer à une technique à distance.

*Texte KRC:*

```text
rotation "Modèle : déplacement"

slot10	Pistol_Shot = "Coup de pistolet"
slot11	Sinister_Strike = "Attaque pernicieuse"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

use Pistol_Shot when  # Coup de pistolet en déplacement
	movement == 1 and Combo_Points < 80

use Sinister_Strike when  # Attaque pernicieuse
	movement == 0 and Combo_Points < 80
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : déplacement",
  "specID": 260,
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "slots": [
    {"n": 10, "alias": "Pistol_Shot", "label": "Coup de pistolet", "spell": 185763},
    {"n": 11, "alias": "Sinister_Strike", "label": "Attaque pernicieuse", "spell": 193315}
  ],
  "rules": [
    {"use": "Pistol_Shot", "name": "Coup de pistolet en déplacement", "when": [
      {"all": ["movement == 1", "Combo_Points < 80"]}
    ]},
    {"use": "Sinister_Strike", "name": "Attaque pernicieuse", "when": [
      {"all": ["movement == 0", "Combo_Points < 80"]}
    ]}
  ]
}
```


### Sorts ciblés au sol

Le bouton Au sol autorise les sorts qui se placent au sol. KeyRota ne fait que presser une touche ; c’est donc la macro qui définit l’endroit : `[@player]` à vos pieds, `[@cursor]` sous le curseur.

*La macro dans le jeu:*

```text
#showtooltip Mort et décomposition
/cast [@player] Mort et décomposition
```


*Texte KRC:*

```text
rotation "Modèle : sorts au sol"

slot1	Death_and_Decay = "Mort et décomposition (macro @player)"
resource1	PlayerHP
resource2	TargetHP
resource3	Runes
resource4	Runic_Power

use Death_and_Decay when  # Mort et décomposition
	ground_spells == 1 and enemies >= 2  # Au sol activé, 2+ ennemis
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Modèle : sorts au sol",
  "specID": 250,
  "resources": ["PlayerHP", "TargetHP", "Runes", "Runic_Power"],
  "slots": [
    {"n": 1, "alias": "Death_and_Decay", "label": "Mort et décomposition (macro @player)", "spell": 43265}
  ],
  "rules": [
    {"use": "Death_and_Decay", "name": "Mort et décomposition", "when": [
      {"all": ["ground_spells == 1", "enemies >= 2"], "comment": "Au sol activé, 2+ ennemis"}
    ]}
  ]
}
```


### La rotation de départ complète

La rotation de l’[exemple de l’éditeur](https://keyrota.app/documentation/fr/editor#walkthrough) : deux DoT, un générateur, une dépense avec mise en réserve, une défense et Marque létale sur Burst.

*Texte KRC:*

```text
rotation "Assassinat : exemple v1"

# Exemple de la documentation KeyRota : deux saignements, un générateur, une dépense avec mise en réserve d’énergie,
# une défense à faible vie et Marque létale sur le bouton Burst.
# Points de combo en pourcentage de 7 : 5 points = 71 %, seuil 70 = 5+.

buff1	Garrote_DoT = "Garrot sur la cible [703]"
buff2	Rupture_DoT = "Rupture sur la cible [1943]"
buff3	Envenom_Buff = "Envenimer [32645]"
buff4	Deathmark_DoT = "Marque létale sur la cible [360194]"
slot1	Garrote = "Garrot"
slot2	Rupture = "Rupture"
slot3	Envenom = "Envenimer"
slot4	Mutilate = "Estropier"
slot5	Deathmark = "Marque létale"
slot6	Crimson_Vial = "Fiole cramoisie"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

# --- Défense : seulement avec « Soins / défense » activé ---
use Crimson_Vial when  # Fiole cramoisie
	defensives == 1 and PlayerHP <= 40  # vie à 40 % ou moins

# --- Temps de recharge : seulement avec Burst activé ---
use Deathmark when  # Marque létale
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up and Envenom_Buff.up  # Burst activé, saignements et Envenimer actifs

# --- Saignements ---
use Garrote when  # Garrot
	Garrote_DoT.down  # pas de saignement
	or
	Garrote_DoT.up and Garrote_DoT.duration <= 30  # fenêtre de pandémie : 30 % ou moins restants

use Rupture when  # Rupture
	Combo_Points >= 70 and Rupture_DoT.down  # 5+ points de combo, pas de saignement
	or
	Combo_Points >= 70 and Rupture_DoT.up and Rupture_DoT.duration <= 30  # 5+ points de combo, fenêtre de pandémie

# --- Dépense : 5+ points de combo, en réservant l’énergie ---
use Envenom when  # Envenimer
	Combo_Points >= 70 and Envenom_Buff.down  # pas d’amélioration
	or
	Combo_Points >= 70 and Envenom_Buff.up and Envenom_Buff.duration <= 20  # l’amélioration se termine
	or
	Combo_Points >= 70 and Energy >= 70  # ne pas plafonner l’énergie
	or
	Combo_Points >= 70 and Deathmark_DoT.up  # Marque létale sur la cible

# --- Générateur : moins de 5 points de combo ---
use Mutilate when  # Estropier
	Combo_Points < 70  # moins de 5 points de combo
```

*JSON:*

```json
{
  "format": "keyrota-rotation",
  "version": 1,
  "title": "Assassinat : exemple v1",
  "specID": 259,
  "ignoreMainIcon": true,
  "enemies": {"range": 8, "combatOnly": true},
  "notes": [
    "Exemple de la documentation KeyRota : deux saignements, un générateur, une dépense avec mise en réserve d’énergie,",
    "une défense à faible vie et Marque létale sur le bouton Burst.",
    "Points de combo en pourcentage de 7 : 5 points = 71 %, seuil 70 = 5+."
  ],
  "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"],
  "auras": [
    {"n": 1, "alias": "Garrote_DoT", "label": "Garrot sur la cible [703]", "spell": 703},
    {"n": 2, "alias": "Rupture_DoT", "label": "Rupture sur la cible [1943]", "spell": 1943},
    {"n": 3, "alias": "Envenom_Buff", "label": "Envenimer [32645]", "spell": 32645},
    {"n": 4, "alias": "Deathmark_DoT", "label": "Marque létale sur la cible [360194]", "spell": 360194}
  ],
  "slots": [
    {"n": 1, "alias": "Garrote", "label": "Garrot", "spell": 703, "show": "target"},
    {"n": 2, "alias": "Rupture", "label": "Rupture", "spell": 1943, "show": "target"},
    {"n": 3, "alias": "Envenom", "label": "Envenimer", "spell": 32645, "show": "target"},
    {"n": 4, "alias": "Mutilate", "label": "Estropier", "spell": 1329, "show": "target"},
    {"n": 5, "alias": "Deathmark", "label": "Marque létale", "spell": 360194, "show": "target"},
    {"n": 6, "alias": "Crimson_Vial", "label": "Fiole cramoisie", "spell": 185311, "show": "combat"}
  ],
  "rules": [
    {
      "use": "Crimson_Vial",
      "name": "Fiole cramoisie",
      "note": ["--- Défense : seulement avec « Soins / défense » activé ---"],
      "when": [{"all": ["defensives == 1", "PlayerHP <= 40"], "comment": "vie à 40 % ou moins"}]
    },
    {
      "use": "Deathmark",
      "name": "Marque létale",
      "note": ["--- Temps de recharge : seulement avec Burst activé ---"],
      "when": [
        {
          "all": ["cd == 1", "Garrote_DoT.up", "Rupture_DoT.up", "Envenom_Buff.up"],
          "comment": "Burst activé, saignements et Envenimer actifs"
        }
      ]
    },
    {
      "use": "Garrote",
      "name": "Garrot",
      "note": ["--- Saignements ---"],
      "when": [
        {"all": ["Garrote_DoT.down"], "comment": "pas de saignement"},
        {
          "all": ["Garrote_DoT.up", "Garrote_DoT.duration <= 30"],
          "comment": "fenêtre de pandémie : 30 % ou moins restants"
        }
      ]
    },
    {
      "use": "Rupture",
      "name": "Rupture",
      "when": [
        {
          "all": ["Combo_Points >= 70", "Rupture_DoT.down"],
          "comment": "5+ points de combo, pas de saignement"
        },
        {
          "all": ["Combo_Points >= 70", "Rupture_DoT.up", "Rupture_DoT.duration <= 30"],
          "comment": "5+ points de combo, fenêtre de pandémie"
        }
      ]
    },
    {
      "use": "Envenom",
      "name": "Envenimer",
      "note": ["--- Dépense : 5+ points de combo, en réservant l’énergie ---"],
      "when": [
        {"all": ["Combo_Points >= 70", "Envenom_Buff.down"], "comment": "pas d’amélioration"},
        {
          "all": ["Combo_Points >= 70", "Envenom_Buff.up", "Envenom_Buff.duration <= 20"],
          "comment": "l’amélioration se termine"
        },
        {"all": ["Combo_Points >= 70", "Energy >= 70"], "comment": "ne pas plafonner l’énergie"},
        {"all": ["Combo_Points >= 70", "Deathmark_DoT.up"], "comment": "Marque létale sur la cible"}
      ]
    },
    {
      "use": "Mutilate",
      "name": "Estropier",
      "note": ["--- Générateur : moins de 5 points de combo ---"],
      "when": [{"all": ["Combo_Points < 70"], "comment": "moins de 5 points de combo"}]
    }
  ]
}
```


### Une rotation de raid complète

Une vraie rotation de raid Assassinat (Fatebound) : 15 règles, Burst, Disparition sous Marque létale, copie des DoT avec Tempête cramoisie, AoE et cible unique, mise en réserve d’énergie.

**Texte KRC : Assassinat, raid**
*Texte KRC:*

```text
rotation "Assassinat, raid v2.8 : bouton Burst, Method 12.1, SimulationCraft, meilleurs logs"

# Assassinat, raid. Base : le guide Method (patch 12.1), la liste d’actions de SimulationCraft et les meilleurs joueurs de Warcraft Logs.
# Ignorer l’icône principale : activé. Marque létale et Plaie des rois seulement avec Burst activé ; Disparition seulement tant que Marque létale est sur la cible.
# Points de combo en pourcentage de 7 : 3 = 43 %, 4 = 57 %, 5 = 71 %, 6 = 86 %, 7 = 100 %.

# v2.4 : Plaie des rois seulement à 0–3 points de combo (Frappes implacables en donnent ensuite 5), Disparition à 0–4 (Garrot depuis le Camouflage en donne 3).
# v2.5 : Tempête cramoisie seulement quand un seul des deux saignements est frais ; avant, elle partait plusieurs fois de suite.
# v2.6 : si Burst est activé et que Marque létale est prête ou déjà sur la cible, Garrot et Rupture vont sur une cible quelle que soit sa vie.
# v2.7 et v2.8 : nouvelle cible sans saignements, Burst activé, Marque létale prête, 2+ ennemis à proximité : Tempête cramoisie copie d’abord les saignements (avec n’importe quels points de combo), puis Marque létale.

buff1	Garrote_DoT = "Garrot sur la cible [703]"
buff2	Rupture_DoT = "Rupture sur la cible [1943]"
buff3	Envenom_Buff = "Envenimer [32645]"
buff4	Deathmark_DoT = "Marque létale sur la cible [360194]"
buff5	Improved_Garrote = "Garrot amélioré [392401]"
buff6	Darkest_Night = "Nuit noire [457280]"
buff7	Blindside = "Angle mort [121153]"
buff8	Stealth_Buff = "Camouflage [1784]"
buff9	Stealth_Sub = "Camouflage (Subterfuge) [115191]"
buff10	Vanish_Buff = "Disparition [11327]"
slot1	Garrote = "Garrot"
slot2	Rupture = "Rupture"
slot3	Envenom = "Envenimer"
slot4	Mutilate = "Estropier"
slot5	Ambush = "Embuscade"
slot6	Fan_of_Knives = "Éventail de couteaux"
slot7	Crimson_Tempest = "Tempête cramoisie"
slot8	Deathmark = "Marque létale"
slot9	Kingsbane = "Plaie des rois"
slot10	Vanish = "Disparition"
slot11	Crimson_Vial = "Fiole cramoisie"
resource1	PlayerHP
resource2	TargetHP
resource3	Energy
resource4	Combo_Points

# --- Défense : seulement avec « Soins / défense » activé ---
use Crimson_Vial when  # Fiole cramoisie
	defensives == 1 and PlayerHP <= 40  # vie à 40 % ou moins

# === Camouflage ===
use Garrote when  # Garrot depuis le Camouflage
	Stealth_Buff.up  # camouflé
	or
	Stealth_Sub.up  # camouflé (Subterfuge)
	or
	Vanish_Buff.up  # juste après Disparition

use Garrote when  # Garrot : fenêtre de Garrot amélioré
	Improved_Garrote.up and Garrote_DoT.down  # fenêtre ouverte, pas de Garrot sur la cible
	or
	Improved_Garrote.up and Garrote_DoT.duration <= 78  # SimulationCraft : renouveler quand il reste 14 s sur 18

# === Temps de recharge (bouton Burst) ===
use Deathmark when  # Marque létale
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up and Kingsbane.cd <= 3 and Envenom_Buff.duration >= 35 and Stealth_Buff.down and Stealth_Sub.down  # Burst activé, saignements actifs, Plaie des rois prête, Envenimer encore 2 s ou plus

use Kingsbane when  # Plaie des rois
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up and Envenom_Buff.up and Deathmark_DoT.up and Combo_Points < 50 and Stealth_Buff.down and Stealth_Sub.down  # Burst activé, Marque létale sur la cible, 0–3 points de combo
	or
	cd == 1 and Garrote_DoT.up and Rupture_DoT.up and Envenom_Buff.up and Deathmark.cd >= 44 and Combo_Points < 50 and Stealth_Buff.down and Stealth_Sub.down  # Burst activé, Marque létale dans plus de 52 s, 0–3 points de combo

use Vanish when  # Disparition
	Deathmark_DoT.up and Improved_Garrote.down and Combo_Points < 65 and Stealth_Buff.down and Stealth_Sub.down  # Marque létale sur la cible, 0–4 points de combo (Garrot depuis le Camouflage en donne 3)

# === Saignements ===
use Crimson_Tempest when  # Tempête cramoisie : copier les saignements sur une nouvelle cible pour Marque létale
	cd == 1 and Deathmark.cd <= 3 and Garrote_DoT.down and Rupture_DoT.down and Envenom_Buff.up and enemies >= 2  # points de combo indifférents

# Pas de nouveau saignement sur des adds presque morts (comme « la cible vit encore 12 s ou plus » de SimulationCraft) : sur 1–2 cibles et en mode « Une », toujours ;
# sur 3+ cibles, seulement si la cible a 50 %+ de vie, ou si Burst est activé et Marque létale prête, ou si Marque létale est déjà sur la cible.
use Garrote when  # Garrot : entretien
	Garrote_DoT.down and Combo_Points < 95 and enemies <= 2
	or
	Garrote_DoT.down and Combo_Points < 95 and st == 1
	or
	Garrote_DoT.down and Combo_Points < 95 and TargetHP >= 50  # 3+ cibles : seulement une cible qui va durer
	or
	Garrote_DoT.down and Combo_Points < 95 and cd == 1 and Deathmark.cd <= 3  # Burst activé et Marque létale prête : la vie n’importe pas
	or
	Garrote_DoT.down and Combo_Points < 95 and Deathmark_DoT.up  # Marque létale sur la cible (saignements copiés)
	or
	Garrote_DoT.up and Garrote_DoT.duration <= 30 and Combo_Points < 95  # fenêtre de pandémie (déjà actif)

use Rupture when  # Rupture
	Combo_Points >= 70 and Rupture_DoT.down and enemies <= 2
	or
	Combo_Points >= 70 and Rupture_DoT.down and st == 1
	or
	Combo_Points >= 70 and Rupture_DoT.down and TargetHP >= 50  # 3+ cibles : seulement une cible qui va durer
	or
	Combo_Points >= 70 and Rupture_DoT.down and cd == 1 and Deathmark.cd <= 3  # Burst activé et Marque létale prête
	or
	Combo_Points >= 70 and Rupture_DoT.down and Deathmark_DoT.up  # Marque létale sur la cible
	or
	Combo_Points >= 70 and Rupture_DoT.up and Rupture_DoT.duration <= 25 and Darkest_Night.down  # renouvellement ; ne pas y dépenser les 7 points de combo de Nuit noire

# === Générateurs : jusqu’à 5 points de combo, jusqu’à 7 avec Nuit noire ===

# Tempête cramoisie une fois juste après une Rupture fraîche (sur 4+ cibles aussi après un Garrot frais), sinon Éventail de couteaux.
# Un seul des deux doit être frais (94 %+) : juste après Tempête cramoisie, les deux le sont, la suivante attend donc.
use Crimson_Tempest when  # Tempête cramoisie : répandre les saignements juste après une Rupture fraîche ou un Garrot frais
	aoe == 1 and Darkest_Night.down and Combo_Points < 70 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94
	or
	aoe == 1 and Darkest_Night.down and Combo_Points < 70 and Garrote_DoT.up and Rupture_DoT.up and Garrote_DoT.duration >= 94 and Rupture_DoT.duration < 94
	or
	aoe == 1 and Darkest_Night.up and Combo_Points < 95 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94
	or
	aoe == 1 and Darkest_Night.up and Combo_Points < 95 and Garrote_DoT.up and Rupture_DoT.up and Garrote_DoT.duration >= 94 and Rupture_DoT.duration < 94
	or
	st == 0 and enemies >= 4 and Darkest_Night.down and Combo_Points < 70 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94
	or
	st == 0 and enemies >= 4 and Darkest_Night.down and Combo_Points < 70 and Garrote_DoT.up and Rupture_DoT.up and Garrote_DoT.duration >= 94 and Rupture_DoT.duration < 94
	or
	st == 0 and enemies >= 4 and Darkest_Night.up and Combo_Points < 95 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94
	or
	st == 0 and enemies >= 4 and Darkest_Night.up and Combo_Points < 95 and Garrote_DoT.up and Rupture_DoT.up and Garrote_DoT.duration >= 94 and Rupture_DoT.duration < 94
	or
	st == 0 and enemies >= 2 and enemies <= 3 and Darkest_Night.down and Combo_Points < 70 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94  # 2–3 cibles : seulement après une Rupture fraîche
	or
	st == 0 and enemies >= 2 and enemies <= 3 and Darkest_Night.up and Combo_Points < 95 and Garrote_DoT.up and Rupture_DoT.up and Rupture_DoT.duration >= 94 and Garrote_DoT.duration < 94  # 2–3 cibles : seulement après une Rupture fraîche

use Fan_of_Knives when  # Éventail de couteaux : cible unique, Nuit noire, il manque un point de combo
	st == 1 and Darkest_Night.up and Combo_Points >= 80 and Combo_Points < 95
	or
	aoe == 0 and enemies <= 1 and Darkest_Night.up and Combo_Points >= 80 and Combo_Points < 95

use Fan_of_Knives when  # Éventail de couteaux : 2+ cibles
	aoe == 1 and Darkest_Night.down and Combo_Points < 70
	or
	aoe == 1 and Darkest_Night.up and Combo_Points < 95
	or
	st == 0 and enemies >= 2 and Darkest_Night.down and Combo_Points < 70
	or
	st == 0 and enemies >= 2 and Darkest_Night.up and Combo_Points < 95

use Ambush when  # Embuscade (Angle mort)
	Blindside.up and st == 1 and Darkest_Night.down and Combo_Points < 70
	or
	Blindside.up and st == 1 and Darkest_Night.up and Combo_Points < 95
	or
	Blindside.up and aoe == 0 and enemies <= 1 and Darkest_Night.down and Combo_Points < 70
	or
	Blindside.up and aoe == 0 and enemies <= 1 and Darkest_Night.up and Combo_Points < 95

use Mutilate when  # Estropier
	st == 1 and Darkest_Night.down and Combo_Points < 70
	or
	st == 1 and Darkest_Night.up and Combo_Points < 95
	or
	aoe == 0 and enemies <= 1 and Darkest_Night.down and Combo_Points < 70
	or
	aoe == 0 and enemies <= 1 and Darkest_Night.up and Combo_Points < 95

# === Dépense : 5+ points de combo (7 avec Nuit noire) ===
# SimulationCraft : ne pas l’utiliser tout de suite mais garder Envenimer actif : dans la dernière seconde de l’amélioration, tant que Marque létale est sur la cible, avant que l’énergie ne plafonne, plus tôt sur 4+ cibles.
use Envenom when  # Envenimer
	Darkest_Night.down and Combo_Points >= 70 and Envenom_Buff.down
	or
	Darkest_Night.down and Combo_Points >= 70 and Envenom_Buff.duration <= 20  # il reste environ 1 s
	or
	Darkest_Night.down and Combo_Points >= 70 and Deathmark_DoT.up
	or
	Darkest_Night.down and Combo_Points >= 70 and Energy >= 70  # ne pas plafonner l’énergie
	or
	Darkest_Night.down and Combo_Points >= 70 and Energy >= 30 and enemies >= 4
	or
	Darkest_Night.up and Combo_Points >= 95 and Envenom_Buff.down
	or
	Darkest_Night.up and Combo_Points >= 95 and Envenom_Buff.duration <= 20
	or
	Darkest_Night.up and Combo_Points >= 95 and Deathmark_DoT.up
	or
	Darkest_Night.up and Combo_Points >= 95 and Energy >= 70
	or
	Darkest_Night.up and Combo_Points >= 95 and Energy >= 30 and enemies >= 4
```


Son JSON se trouve dans les fichiers ci-dessous. La deuxième rotation est Hors-la-loi (Trickster), avec la macro Poussée d'adrénaline (**O + Q**), Osselets relancés (**O**), Série meurtrière (**C**) et la protection de canalisation dans chaque règle.

### Fichiers d’exemple

| Exemple | Fichiers |
|---|---|
| La rotation Assassinat de départ de l’exemple de l’éditeur | [JSON](https://keyrota.app/documentation/examples/starter-assassination.fr.json), [texte KRC](https://keyrota.app/documentation/examples/starter-assassination.fr.txt) |
| Assassinat, raid : 15 règles | [JSON](https://keyrota.app/documentation/examples/assassination-raid.fr.json), [texte KRC](https://keyrota.app/documentation/examples/assassination-raid.fr.txt) |
| Hors-la-loi, raid et Mythique+ : 13 règles, indicateurs O, OQ, C | [JSON](https://keyrota.app/documentation/examples/outlaw-raid.fr.json), [texte KRC](https://keyrota.app/documentation/examples/outlaw-raid.fr.txt) |
| La plus courte rotation utile | [JSON](https://keyrota.app/documentation/examples/minimal.fr.json), [texte KRC](https://keyrota.app/documentation/examples/minimal.fr.txt) |
| Un exemple de syntaxe : toutes les conditions et tous les indicateurs (sans ID, pas pour le combat) | [JSON](https://keyrota.app/documentation/examples/syntax-every-condition.fr.json), [texte KRC](https://keyrota.app/documentation/examples/syntax-every-condition.fr.txt) |

Chaque exemple existe dans toutes les langues du site : les libellés, les règles et les commentaires sont traduits, tandis que les conditions, les ID de sort et les indicateurs restent identiques. La langue figure dans le nom du fichier : `.en`, `.ru`, `.de`, `.fr`, `.es`, `.it`, `.pt`, `.ko`, `.zh`, `.zh-TW`.

Pour ouvrir un fichier : Nouveau — Depuis un fichier… dans la fenêtre principale, ou Ouvrir… sur la page Texte et JSON de l’éditeur.

---

<!-- https://keyrota.app/documentation/fr/ai -->

## Créer une rotation avec un agent IA

> [!TIP] Un lien vers cette page suffit
> Vous pouvez simplement donner à votre agent IA le lien vers cette page : il comprendra tout par lui-même et vous demandera les informations manquantes s’il en a besoin.

Un agent IA ayant accès au web et aux fichiers peut créer une rotation KRC pour vous : étudier les logs des meilleurs joueurs de votre spécialisation, les guides et la liste d’actions de SimulationCraft, les comparer avec vos talents et vos logs, puis vous remettre un JSON prêt à l’emploi. Voici ce qu’il faut lui fournir, un prompt tout prêt et la façon de vérifier le résultat.

### Ce dont vous avez besoin

**Un agent** capable d’ouvrir des sites web (Warcraft Logs, Raider.IO, Wowhead, GitHub) et de lire des fichiers. Sans accès au web, fournissez-lui la documentation et des extraits de logs sous forme de fichiers.

**La documentation pour l’agent** (les liens figurent déjà dans le prompt) :

| Lien | Contenu |
|---|---|
| [llms.txt](https://keyrota.app/documentation/llms.txt) | L’index de la documentation pour les agents IA : toutes les langues, tous les fichiers et tous les exemples |
| [krc-guide.en.md](https://keyrota.app/documentation/krc-guide.fr.md) | Toute la documentation dans un seul fichier Markdown |
| [keyrota-rotation.schema.json](https://keyrota.app/documentation/keyrota-rotation.schema.json) | Le JSON Schema pour vérifier la réponse |
| [Assassinat, raid](https://keyrota.app/documentation/examples/assassination-raid.fr.json), [Hors-la-loi, raid et Mythique+](https://keyrota.app/documentation/examples/outlaw-raid.fr.json) | De vraies rotations de raid comme modèles |

**Vos données** (les espaces réservés du prompt) :

| Espace réservé | Ce qu’il faut indiquer | Exemple |
|---|---|---|
| `{CLASS}` | Classe | Voleur |
| `{SPEC}` | Spécialisation | Assassinat |
| `{HERO_TALENTS}` | Talents de héros | Fatebound |
| `{TALENT_STRING}` | La chaîne d’exportation des talents du jeu (fenêtre des talents, Partager) | `CMQAAAAA…` |
| `{CONTENT}` | Raid ou Mythique+ | raid |
| `{RAID_OR_DUNGEONS}` | Le raid ou une liste de donjons | The Venomous Abyss |
| `{DIFFICULTY}` | Difficulté ou niveau de clé | héroïque |
| `{BOSSES}` | Les boss visés par la rotation | tous |
| `{ITEM_LEVEL}` | Niveau d’objet | 328 |
| `{MY_LOGS}` | Un lien vers votre personnage ou votre rapport sur Warcraft Logs | `https://www.warcraftlogs.com/character/eu/<realm>/<name>` |
| `{COMBAT_LOG_FILE}` | Le fichier de journal de combat que vous joignez | `WoWCombatLog-101726_214449.txt` |
| `{PREFERENCES}` | Vos souhaits | « temps de recharge uniquement sur le bouton Burst, pas de défenses » |

### Le prompt

L’agent collecte lui-même les données, les compare avec les vôtres et explique chaque règle. Remplissez les accolades et joignez un journal de combat si vous en avez un.

*Prompt:*

```text
Tu es un expert de World of Warcraft et un auteur de rotations KeyRota. Crée-moi une rotation avancée KeyRota : un JSON au format keyrota-rotation, version 1.

MON PERSONNAGE
- Classe et spécialisation : {CLASS}, {SPEC}. Talents de héros : {HERO_TALENTS}.
- Chaîne de talents du jeu : {TALENT_STRING}
- Contenu : {CONTENT} : {RAID_OR_DUNGEONS}. Difficulté ou niveaux de clé : {DIFFICULTY}. Boss : {BOSSES}.
- Niveau d’objet : {ITEM_LEVEL}.
- Mes Warcraft Logs : {MY_LOGS}
- Journal de combat (joint) : {COMBAT_LOG_FILE}
- Préférences : {PREFERENCES}

ÉTAPE 1. APPRENDRE LE FORMAT KEYROTA
- https://keyrota.app/documentation/llms.txt et https://keyrota.app/documentation/krc-guide.en.md : les emplacements (jusqu’à 12), les auras (jusqu’à 12, uniquement mes améliorations et mes affaiblissements sur la cible), les ressources en pourcentage, toutes les conditions, les indicateurs d’emplacement, les options du panneau aoe, st, cd, defensives, ground_spells, movement, les règles vérifiées de haut en bas, les groupes OU de conditions ET, les limites de 16 groupes de 16 conditions, une valeur inconnue rend une condition fausse.
- JSON Schema : https://keyrota.app/documentation/keyrota-rotation.schema.json
- Modèles : https://keyrota.app/documentation/examples/assassination-raid.en.json et https://keyrota.app/documentation/examples/outlaw-raid.en.json

ÉTAPE 2. COLLECTER LES DONNÉES
1. Warcraft Logs : classements de dégâts {CLASS} {SPEC} pour chaque boss ({CONTENT}, {DIFFICULTY}) ; pour Mythique+, pour chaque donjon et niveau de clé. Prends les 5 à 10 meilleurs logs avec les talents de héros {HERO_TALENTS}.
2. Compare leurs talents avec ma chaîne. Note les différences qui changent la priorité et dis-moi si je dois les prendre.
3. Dans les meilleurs logs, relève : l’ouverture et l’ordre des incantations ; le temps de présence des améliorations et des affaiblissements importants ; les ressources au moment des incantations (points de combo ou équivalent aux coups de grâce, énergie ou équivalent avant une dépense, ressource perdue par plafonnement) ; quand et avec quoi les temps de recharge majeurs sont utilisés, et comment ils sont calés sur les phases ; quand et à quel niveau de vie les défenses sont utilisées ; à partir de combien de cibles ils passent en AoE ; les incantations par minute et le temps sans incantation.
4. Pour Mythique+ : Raider.IO (la méta, les meilleures clés, les talents par donjon).
5. Les guides (Wowhead, Method, le Discord de la classe) et la liste d’actions (APL) de SimulationCraft pour {SPEC} sur la branche de l’extension en cours : utilise-la comme priorité de base et confronte-la aux logs.
6. Mes logs et mon journal de combat : en quoi mes temps de présence, mes ressources au moment des dépenses, mes temps de recharge et mon rythme diffèrent de ceux des meilleurs joueurs.

ÉTAPE 3. ÉCRIRE LA ROTATION
- "format": "keyrota-rotation", "version": 1, le specID de ma spécialisation, les ressources du tableau des spécialisations de la documentation (resource1 PlayerHP, resource2 TargetHP, puis les ressources de la spécialisation), "ignoreMainIcon": true.
- Emplacements : de vrais ID de sort Wowhead (le champ spell). "show": "combat" pour les soins et les défenses. Indicateurs : offGcd pour les sorts hors GCD ; offGcd et queue pour les macros dont la deuxième ligne est soumise au GCD et pour les boutons qui ont besoin du résultat du coup précédent ; channel pour les canalisations ; manual pour ce que je presse moi-même. Pour un emplacement de macro, écris le texte de la macro (#showtooltip et /cast).
- Auras : les ID des améliorations et des affaiblissements eux-mêmes, pas ceux des sorts qui les appliquent. Uniquement mes auras.
- Règles par ordre de priorité. Les défenses en premier et seulement avec defensives == 1. Les temps de recharge majeurs seulement avec cd == 1 (le bouton Burst, pas un temps de recharge de sort) ; ce qui renforce la fenêtre du temps de recharge seulement pendant celle-ci. Cible unique et AoE : un groupe aoe == 1 et un groupe st == 0 and enemies >= N pour l’AoE ; un groupe st == 1 et un groupe aoe == 0 and enemies <= 1 pour la cible unique. DoT : un groupe X.down et un groupe X.up and X.duration <= 30. Ressources en pourcentage, seuils à mi-chemin entre deux paliers (points de combo sur 7 : « au moins 5 » s’écrit Combo_Points >= 70, « au plus 3 » s’écrit Combo_Points < 50). Si le bouton suivant coupe une canalisation, ajoute X.duration <= 8 pour l’aura de la canalisation à chaque groupe de chaque règle.
- KRC n’a ni not, ni !=, ni parenthèses : utilise les paires up/down, ready/oncd, glow/noglow, les opérateurs inverses et plusieurs groupes.
- Écris les libellés (label), les noms des règles et les commentaires en français, et les noms utilisés dans les conditions (alias) en caractères latins.
- Donne un nom à chaque règle et un court commentaire à chaque groupe : quoi et pourquoi.
- À la fin, vérifie : le JSON est conforme au schéma ; chaque nom utilisé dans les conditions est déclaré ; pas plus de 16 conditions par groupe ni de 16 groupes par règle ; les ID existent sur Wowhead pour le patch actuel.

RÉPONSE
1. Le JSON complet de la rotation dans un seul bloc.
2. Les textes des macros pour les emplacements de macro.
3. Un tableau : règle, ce qu’elle fait, d’où elle vient (quel log, quel guide ou quelle ligne de l’APL).
4. Ce qu’il faut activer dans le jeu : les boutons du panneau de réglages rapides, le rayon du compteur d’ennemis, ce qu’il faut placer sur les barres d’action.
5. Un plan de test : un mannequin d’entraînement, puis un journal de combat comparé aux meilleurs logs ; quels chiffres comparer.
```


### Un prompt rempli

Le même prompt en entier, rempli pour Assassinat en raid héroïque :

*Prompt : Assassinat, raid héroïque:*

```text
Tu es un expert de World of Warcraft et un auteur de rotations KeyRota. Crée-moi une rotation avancée KeyRota : un JSON au format keyrota-rotation, version 1.

MON PERSONNAGE
- Classe et spécialisation : Voleur, Assassinat. Talents de héros : Fatebound.
- Chaîne de talents du jeu : CMQAAAAAAAAAAAAAAAAAAAAAAYmlZmFDGAAAAAYWGsNDAAAAAILzMzMzMjxyMzMbzsMzMPgZMzYMMzYMAGYBmxoxsBYbAbGAMzMGD
- Contenu : raid : The Venomous Abyss. Difficulté : héroïque. Boss : tous ; accorde une attention particulière à Ula'tek (fenêtres de dégâts sur le Cœur).
- Niveau d’objet : 328.
- Mes Warcraft Logs : https://www.warcraftlogs.com/character/eu/<realm>/<name>
- Journal de combat (joint) : WoWCombatLog-101726_214449.txt, 5 minutes sur un mannequin d’entraînement, cible unique.
- Préférences : Marque létale et Plaie des rois uniquement sur le bouton Burst ; Disparition uniquement sous Marque létale ; Fiole cramoisie à 40 % de vie ou moins ; mise en réserve d’énergie comme dans SimulationCraft.

ÉTAPE 1. APPRENDRE LE FORMAT KEYROTA
- https://keyrota.app/documentation/llms.txt et https://keyrota.app/documentation/krc-guide.en.md : les emplacements (jusqu’à 12), les auras (jusqu’à 12, uniquement mes améliorations et mes affaiblissements sur la cible), les ressources en pourcentage, toutes les conditions, les indicateurs d’emplacement, les options du panneau aoe, st, cd, defensives, ground_spells, movement, les règles vérifiées de haut en bas, les groupes OU de conditions ET, les limites de 16 groupes de 16 conditions, une valeur inconnue rend une condition fausse.
- JSON Schema : https://keyrota.app/documentation/keyrota-rotation.schema.json
- Modèles : https://keyrota.app/documentation/examples/assassination-raid.en.json et https://keyrota.app/documentation/examples/outlaw-raid.en.json

ÉTAPE 2. COLLECTER LES DONNÉES
1. Warcraft Logs : classements de dégâts Voleur Assassinat pour chaque boss (raid The Venomous Abyss, difficulté héroïque). Prends les 5 à 10 meilleurs logs avec les talents de héros Fatebound.
2. Compare leurs talents avec ma chaîne. Note les différences qui changent la priorité et dis-moi si je dois les prendre.
3. Dans les meilleurs logs, relève : l’ouverture et l’ordre des incantations ; le temps de présence de Garrot, de Rupture et de l’amélioration Envenimer ; les points de combo à Envenimer, Rupture, Plaie des rois et Disparition, l’énergie avant Envenimer, l’énergie et les points de combo perdus par plafonnement ; quand et avec quoi Marque létale et Plaie des rois sont utilisées, et comment elles sont calées sur les phases (en particulier sur le Cœur d’Ula'tek) ; quand et à quel niveau de vie Fiole cramoisie et les autres défenses sont utilisées ; à partir de combien de cibles ils passent à Éventail de couteaux et à Tempête cramoisie ; les incantations par minute et le temps sans incantation.
4. Les guides (Wowhead, Method, le Discord des voleurs) et la liste d’actions (APL) de SimulationCraft pour Assassinat sur la branche de l’extension en cours : utilise-la comme priorité de base et confronte-la aux logs.
5. Mes logs et mon journal de combat : en quoi mes temps de présence, mes points de combo au moment des dépenses, mes temps de recharge et mon rythme diffèrent de ceux des meilleurs joueurs.

ÉTAPE 3. ÉCRIRE LA ROTATION
- "format": "keyrota-rotation", "version": 1, "specID": 259, "resources": ["PlayerHP", "TargetHP", "Energy", "Combo_Points"], "ignoreMainIcon": true.
- Emplacements : de vrais ID de sort Wowhead (le champ spell). "show": "combat" pour Fiole cramoisie. Indicateurs : offGcd pour les sorts hors GCD ; offGcd et queue pour Disparition (elle a besoin des points de combo du coup précédent) ; channel pour les canalisations, s’il y en a ; manual pour ce que je presse moi-même. Pour un emplacement de macro, écris le texte de la macro (#showtooltip et /cast).
- Auras : les ID des améliorations et des affaiblissements eux-mêmes, pas ceux des sorts qui les appliquent (par exemple, l’amélioration de Disparition n’a pas le même ID que le sort). Uniquement mes auras.
- Règles par ordre de priorité. Fiole cramoisie en premier, et seulement avec defensives == 1 et une vie à 40 % ou moins. Marque létale et Plaie des rois seulement avec cd == 1 (le bouton Burst, pas un temps de recharge de sort) ; Disparition seulement tant que Marque létale est sur la cible. Cible unique et AoE : un groupe aoe == 1 et un groupe st == 0 and enemies >= 2 pour Éventail de couteaux ; un groupe st == 1 et un groupe aoe == 0 and enemies <= 1 pour Estropier. Garrot et Rupture : un groupe X.down et un groupe X.up and X.duration <= 30. Points de combo sur 7 en pourcentage, seuils à mi-chemin entre deux paliers : « au moins 5 » s’écrit Combo_Points >= 70, « au plus 3 » s’écrit Combo_Points < 50. Mise en réserve d’énergie : Envenimer à 5 points de combo ou plus quand l’amélioration se termine, sous Marque létale ou à Energy >= 70.
- KRC n’a ni not, ni !=, ni parenthèses : utilise les paires up/down, ready/oncd, glow/noglow, les opérateurs inverses et plusieurs groupes.
- Écris les libellés (label), les noms des règles et les commentaires en français, et les noms utilisés dans les conditions (alias) en caractères latins.
- Donne un nom à chaque règle et un court commentaire à chaque groupe : quoi et pourquoi.
- À la fin, vérifie : le JSON est conforme au schéma ; chaque nom utilisé dans les conditions est déclaré ; pas plus de 16 conditions par groupe ni de 16 groupes par règle ; les ID existent sur Wowhead pour le patch actuel.

RÉPONSE
1. Le JSON complet de la rotation dans un seul bloc.
2. Les textes des macros pour les emplacements de macro.
3. Un tableau : règle, ce qu’elle fait, d’où elle vient (quel log, quel guide ou quelle ligne de l’APL).
4. Ce qu’il faut activer dans le jeu : les boutons du panneau de réglages rapides, le rayon du compteur d’ennemis, ce qu’il faut placer sur les barres d’action.
5. Un plan de test : un mannequin d’entraînement, puis un journal de combat comparé aux meilleurs logs ; quels chiffres comparer.
```


### Analyser les logs

Des indications pour l’agent et pour vous : où trouver les données et quoi comparer.

**Warcraft Logs**
- Classements : `https://www.warcraftlogs.com/zone/rankings/<zone id>?boss=<boss id>&class=<Class>&spec=<Spec>&difficulty=<3|4|5>&metric=dps` (3 normal, 4 héroïque, 5 mythique). Les classements Mythique+ sont séparés par niveau de clé.
- Dans le rapport d’un joueur : les onglets « Casts » (ordre et moment des incantations), « Buffs » et « Debuffs » (temps de présence), « Resources » (ressources et plafonnement), « Damage Done » (par technique et par cible), « Deaths ».
- Les talents d’un log : le résumé du joueur contient la chaîne d’exportation des talents ; ouvrez-la dans le calculateur de talents de Wowhead.
- Comparez le comportement, pas les DPS : temps de présence des DoT et des améliorations, ressources au moment des dépenses, incantations par minute, temps sans incantation, moment d’utilisation des temps de recharge majeurs par rapport aux phases du combat.

**Raider.IO** (Mythique+)
- Les meilleures clés d’un donjon : `https://raider.io/api/v1/mythic-plus/runs?season=<season>&region=world&dungeon=<slug>&page=0` ; saisons et donjons : `https://raider.io/api/v1/mythic-plus/static-data?expansion_id=<id>`.
- La méta change d’une semaine à l’autre : prenez des données récentes, pas d’anciennes conclusions.

**SimulationCraft**
- La liste d’actions (APL) d’une spécialisation se trouve dans le dépôt `simulationcraft/simc` sur GitHub, sur la branche de l’extension en cours, dans le dossier `ActionPriorityLists`.
- Comment convertir une APL en KRC :

| APL de SimulationCraft | KRC |
|---|---|
| lignes `actions`, de haut en bas | règles, de haut en bas |
| `buff.X.up` | `X.up` |
| `dot.X.remains`, `buff.X.remains` | `X.duration` en pourcentage |
| `cooldown.X.remains` | `X.cd` en pourcentage |
| `combo_points`, `energy` | ressources en pourcentage |
| `active_enemies` | `enemies` |
| `target.time_to_die`, secondes exactes | pas d’équivalent ; le substitut le plus proche, par exemple « la cible vit encore 12 secondes » devient `TargetHP >= 50` sur 3 cibles ou plus |

**Le journal de combat**
- Avec le journal de combat avancé, chaque `SPELL_CAST_SUCCESS` contient les ressources du lanceur (type, valeur actuelle, maximum) ; l’énergie est le type 3.
- `SPELL_AURA_APPLIED`, `SPELL_AURA_REFRESH`, `SPELL_AURA_REMOVED` : temps de présence et renouvellements des auras ; `SPELL_ENERGIZE` : gains de ressources ; `SPELL_CAST_FAILED` : appuis refusés par le jeu.
- À compter : incantations par minute, écarts entre les GCD, temps de présence des DoT, points de combo aux coups de grâce, plafonnement de l’énergie, moment d’utilisation des temps de recharge majeurs.

### Enregistrer un journal de combat

1. Dans les options du jeu, Système — Réseau, cochez « Journal de combat avancé ». Sans lui, le journal ne contient ni ressources ni positions.
2. Avant le pull, tapez `/combatlog` dans le chat : l’enregistrement démarre. Après le combat, tapez de nouveau `/combatlog` : l’enregistrement s’arrête.
3. Le fichier se trouve dans le dossier du jeu : `World of Warcraft\_retail_\Logs\WoWCombatLog-MMDDYY_HHMMSS.txt`. Le jeu l’écrit avec un certain délai : attendez une minute après avoir arrêté l’enregistrement.
4. Le logiciel d’envoi de Warcraft Logs peut vider le fichier après l’envoi : copiez-le d’abord.

Faites les premiers tests sur un mannequin d’entraînement : 2 à 3 minutes sur une cible unique, puis sur un groupe de mannequins pour l’AoE.

### Tester et itérer

1. Chargez la rotation (voir ci-dessous), créez et collez le profil Better Assistant, placez les sorts des emplacements sur vos barres avec des touches.
2. Testez sur un mannequin. Le Journal de la fenêtre principale indique ce qui est pressé. Le fichier journal de KeyRota (le bouton dossier à côté de Journal) consigne, pour chaque GCD, la règle choisie et la raison pour laquelle les règles placées au-dessus ont été ignorées : conditions, pas prêt, inconnu, manuel.
3. Donnez à l’agent le JSON de la rotation, un journal de combat récent et, si nécessaire, le fichier journal de KeyRota. Demandez-lui de comparer avec les meilleurs logs : temps de présence, ressources au moment des dépenses, temps de recharge, temps d’inactivité.
4. Modifiez une seule règle à la fois et indiquez la version dans le nom de la rotation (« v1.3 »). Conservez les anciennes versions : Exporter dans la fenêtre principale, ou Texte et JSON — Enregistrer…
5. Après le raid ou la clé, comparez de nouveau avec Warcraft Logs.

### Charger le résultat

- **Sous forme de fichier :** enregistrez le JSON de la réponse dans un fichier `.json`, puis Rotation — Nouveau — Depuis un fichier…
- **Depuis le presse-papiers :** copiez le JSON, puis Nouveau — Depuis le presse-papiers.
- **Dans une rotation ouverte :** l’éditeur — Texte et JSON — JSON — Coller. Les emplacements de mêmes numéros conservent leurs ID, leurs indicateurs et leur visibilité si le nouveau JSON n’en contient pas.

La barre d’état de l’éditeur doit indiquer « Rotation valide ». En cas d’erreur, elle indique l’endroit : transmettez-le mot pour mot à l’agent. Ensuite, Général — « Créer depuis la rotation » — « Copier », puis dans le jeu `/ba` — Profile — coller — Apply. Créez dans le jeu les macros de la réponse et placez-les sur vos barres.

---

<!-- https://keyrota.app/documentation/fr/faq -->

## FAQ et dépannage

### Une règle ne se déclenche jamais

Vérifiez dans cet ordre :

1. **Une règle placée au-dessus l’emporte toujours.** Les règles sont vérifiées de haut en bas : si une règle placée au-dessus est remplie et que son sort peut être utilisé, la vôtre n’a jamais son tour. Remontez votre règle ou restreignez les conditions de celle du dessus.
2. **Une valeur inconnue.** Une condition portant sur une valeur inconnue est fausse, même `.down`. Une aura est inconnue quand elle ne figure pas dans le profil Better Assistant ou qu’elle a un mauvais ID. Recréez le profil (« Créer depuis la rotation ») et collez-le dans le jeu.
3. **L’ID de l’aura, pas celui du sort.** Une amélioration peut avoir un autre ID que le sort qui l’applique : Disparition a l’ID `1856`, son amélioration `11327`. Et les règles ne voient que vos auras, pas les améliorations venant d’autres joueurs.
4. **L’emplacement n’est pas prêt.** Ressource insuffisante, cible trop éloignée, temps de recharge, talent non pris. Une telle règle est ignorée sans erreur.
5. **Better Assistant n’affiche pas l’emplacement.** Un emplacement Avec une cible n’est pas prêt sans cible. Utilisez En combat pour les soins et les techniques défensives.
6. **Pas de touche.** Le sort de l’emplacement doit se trouver sur une barre d’action avec une touche assignée (ou une macro avec `#showtooltip`).
7. **Une option est désactivée.** Soins / défense est désactivé par défaut, Burst a peut-être été désactivé avec la touche Burst (F3 sous Windows, ⌃⇧B sous macOS), le mode de cibles est peut-être resté sur Une ou Plusieurs.
8. **Les pourcentages.** 5 points de combo s’écrivent `70`, pas `5`. Voir [Ressources](https://keyrota.app/documentation/fr/conditions#resources).
9. **Les cumuls.** Un seul cumul se lit 0 : `X.stacks >= 1` ne distingue pas un cumul d’une aura absente ; utilisez `.up`.
10. **Une aura sans durée.** Camouflage et les auras similaires indiquent toujours 1 restant : `.duration` ne fonctionne pas pour elles.

Le fichier journal de KeyRota indique quelle règle a été choisie et pourquoi celles du dessus ont été ignorées : bouton dossier à côté de Journal dans la fenêtre principale.

### KeyRota presse trop tôt ou trop tard

| Ce que vous constatez | Cause | Que faire |
|---|---|---|
| Un sort hors GCD attend la fin du GCD | Pas d’indicateur O | Activez Hors GCD (O). |
| Un bouton hors GCD est pressé avant l’arrivée du résultat du coup précédent | L’indicateur O presse immédiatement, en plein GCD | Ajoutez Fenêtre de file d’attente (Q) : O + Q. |
| Une macro dont la deuxième ligne est soumise au GCD ne s’exécute pas entièrement | La macro a été pressée en plein GCD | O + Q : la macro est pressée à la fin du GCD. |
| Une règle hors GCD placée plus bas ne devance pas une règle plus haute | C’est voulu : priorité stricte | Remontez la règle. |
| Après une dépense, la rotation « reste immobile » | Mise en réserve de ressources : aucune règle n’est remplie | C’est normal ; pour dépenser plus tôt, abaissez le seuil d’énergie. |
| La rotation ne presse rien pendant que vous pressez vos propres boutons | KeyRota s’efface quand vous pressez vos techniques | C’est normal. |

### Une canalisation est coupée

- Activez Canalisation (C) pour l’emplacement : pendant la canalisation, KeyRota ne presse rien et ne presse pas l’emplacement deux fois au démarrage.
- Le jeu termine certaines canalisations un peu avant le dernier coup, et un appui juste après la fin de la canalisation la coupe. Ajoutez l’aura de la canalisation aux auras de la rotation, et la condition `Channel_aura.duration <= 8` à **chaque groupe de chaque règle**. Exemple : [Protection d’une canalisation](https://keyrota.app/documentation/fr/patterns#channel).

### La rotation ne passe pas en AoE

1. Le mode de cibles est-il sur Auto (F2 sous Windows, ⌃⇧T sous macOS, en cycle Auto, Une, Plusieurs) ? En mode Une, les règles avec `st == 0` se taisent.
2. Les barres de vie des ennemis (nameplates) sont-elles affichées dans le jeu (V), sans masquer les ennemis mineurs ?
3. Le rayon du compteur sur la page Général est-il au moins égal à la portée de votre technique AoE ?
4. Ennemis en combat uniquement : les ennemis qui ne sont pas encore en combat ne sont pas comptés. Avec des groupes qui arrivent un par un, le compte peut être plus bas.
5. Le seuil de la règle : `enemies >= 2` ou `>= 3` ?
6. Après avoir changé le rayon, recréez le profil Better Assistant et collez-le de nouveau.

### Burst ne se déclenche pas, ou pas au bon moment

- `cd == 1` est **le bouton Burst** (F3 sous Windows, ⌃⇧B sous macOS, le bouton Burst du panneau), pas le temps de recharge d’un sort. Le temps de recharge d’un sort s’écrit `Slot.cd`.
- Burst est activé par défaut. Désactivez-le avant un moment où le temps de recharge ne doit pas être utilisé (insensibilité, changement de phase), puis réactivez-le le moment venu.
- Si un temps de recharge majeur dépend d’auras (DoT sur la cible), il les attend. Vérifiez dans le journal de KeyRota quelle condition de la règle n’est pas remplie.
- Pour ce qui doit partir seulement sous le temps de recharge, vérifiez l’aura du temps de recharge (`Deathmark_DoT.up`), pas le bouton Burst.

### Comment calculer les pourcentages

- **Ressources et vie :** `valeur / maximum × 100`. 175 d’énergie sur 250 donnent `70`.
- **Points de combo sur 7 :** placez le seuil à mi-chemin entre deux paliers : « au moins 5 » s’écrit `>= 70`, « au plus 3 » s’écrit `< 50`. [Le tableau](https://keyrota.app/documentation/fr/conditions#resources).
- **Temps restant d’une aura :** un pourcentage de la durée de cette application. 30 % correspondent à la fenêtre de pandémie.
- **Temps de recharge :** un pourcentage du temps de recharge total, sans le GCD. Pour un temps de recharge de 2 minutes, 1 % vaut 1,2 s.

### « Impossible d’enregistrer une rotation contenant une erreur »

L’éditeur n’enregistre pas une rotation contenant une erreur : KeyRota n’exécute jamais une rotation partiellement. La barre d’état indique l’endroit, par exemple « Règle 9, groupe 1 : le groupe n’a aucune condition ». Cliquez sur Afficher pour ouvrir la règle. Causes fréquentes :

| Message | Que faire |
|---|---|
| le groupe n’a aucune condition | Ajoutez une condition ou supprimez le groupe vide. |
| aucun emplacement choisi | Choisissez un emplacement dans Presser. |
| l’indicateur Q s’utilise uniquement avec O | Activez Hors GCD (O) ou désactivez Q. |
| nom inconnu … | Un nom utilisé dans une condition ne correspond à aucune aura, aucun emplacement ni aucune ressource : vérifiez Nom dans le texte. |
| … est de type slot, attendu : buff | Une propriété d’aura (`.up`, `.duration`) sur un emplacement, ou une propriété d’emplacement (`.ready`, `.cd`) sur une aura. |
| guillemets interdits dans le nom | Retirez `"` du nom de la rotation, de l’emplacement ou de l’aura. |

Tous les messages sont décrits dans [Erreurs](https://keyrota.app/documentation/fr/rotation-json#errors).

### Quelle différence entre `.oncd` et `.cd > 0` ?

`X.oncd` : l’emplacement n’est pas prêt, pour **quelque raison que ce soit** : temps de recharge, ressource manquante, cible trop éloignée, emplacement non affiché. `X.cd > 0` : un temps de recharge est en cours. Pour un sort à charges, `.cd > 0` est possible alors que l’emplacement est prêt : une charge est disponible, la suivante se recharge.

### Comment écrire « non » et des parenthèses ?

KRC n’a ni `not`, ni `!=`, ni parenthèses. « Non » s’écrit avec la condition opposée (`up`/`down`, `ready`/`oncd`, `glow`/`noglow`) ou avec l’opérateur inverse (au lieu de « non `>= 70` », écrivez `< 70`). « (A ou B) et C » s’écrit avec deux groupes : `A and C`, `B and C`. Plus d’informations : [« Non », parenthèses et OU](https://keyrota.app/documentation/fr/conditions#logic).

### Plus de 12 emplacements ou auras ?

Non : une rotation compte jusqu’à 12 emplacements et jusqu’à 12 auras, comme le profil Better Assistant. Les macros permettent de gagner de la place (un bouton, plusieurs sorts), et un même emplacement peut figurer dans plusieurs règles. Le nombre de règles est illimité.

### Une rotation avec un talent que vous n’avez pas

Si un talent n’est pas pris, le sort n’est pas appris, l’emplacement n’est pas prêt, et ses règles sont simplement ignorées. Une même rotation peut fonctionner avec différentes configurations de talents : les règles des sorts manquants se taisent.

### Transférer ou partager une rotation

- Exporter, dans la fenêtre principale, enregistre le profil avec sa rotation ; Importer le charge sur un autre ordinateur.
- Dans l’éditeur, Texte et JSON — Enregistrer… enregistre la rotation au format `.json` ou `.txt` ; pour l’ouvrir, Nouveau — Depuis un fichier…
- Le profil Better Assistant se recrée à partir des emplacements et des auras de la rotation : inutile de le transmettre séparément.

### Pourquoi KeyRota ne presse parfois rien

Si « Ignorer l’icône principale » est activé et qu’aucune règle ne convient, KeyRota attend. Dans les rotations qui mettent de l’énergie en réserve, c’est normal : à partir de 5 points de combo, la dépense attend sa condition et le générateur se tait. Si l’attente vous paraît anormale, vérifiez dans le journal de KeyRota quelles règles ont été ignorées et pourquoi.
