зеркало из
https://github.com/M82-project/M82-SiteWeb.git
synced 2025-10-29 13:06:05 +02:00
Коммит
6d08c55e51
@ -7,7 +7,7 @@ tags: [LMI,désinformation,guide,plugin]
|
|||||||
|
|
||||||
## La V1 du Détecteur de Manipulation Cognitive 🧠 Plugin DIMA est disponible
|
## La V1 du Détecteur de Manipulation Cognitive 🧠 Plugin DIMA est disponible
|
||||||
|
|
||||||
[Téléchargez et installez le plugin Chrome ici :](https://github.com/M82-project/DIMA/tree/main/plugin/plugin_chrome/fichiers%20%C3%A0%20t%C3%A9l%C3%A9charger)
|
[Téléchargez et installez le plugin Chrome ici :](/files/Plugin-dima-V1)
|
||||||
|
|
||||||
L'index [DIMA](https://m82-project.org/ressources/framework_dima_presentation/) est un outil de détection automatique des techniques cognitives dans les contenus web. Basé sur [la matrice DIMA](https://github.com/M82-project/DIMA) développée par le M82 project, il analyse en temps réel les pages que vous visitez pour identifier les tentatives de manipulation de l'information.
|
L'index [DIMA](https://m82-project.org/ressources/framework_dima_presentation/) est un outil de détection automatique des techniques cognitives dans les contenus web. Basé sur [la matrice DIMA](https://github.com/M82-project/DIMA) développée par le M82 project, il analyse en temps réel les pages que vous visitez pour identifier les tentatives de manipulation de l'information.
|
||||||
|
|
||||||
|
|||||||
283
static/files/Plugin-dima-V1/Data/keywords.js
Обычный файл
283
static/files/Plugin-dima-V1/Data/keywords.js
Обычный файл
@ -0,0 +1,283 @@
|
|||||||
|
// DIMA Enhanced Keywords Database
|
||||||
|
// Enhanced keyword patterns for manipulation technique detection
|
||||||
|
|
||||||
|
// ===== DÉTECTION DE TYPES DE PAGES AMÉLIORÉE =====
|
||||||
|
const PAGE_TYPE_PATTERNS = {
|
||||||
|
news: {
|
||||||
|
domains: ['bfmtv.com', 'lefigaro.fr', 'lemonde.fr', 'liberation.fr', 'franceinfo.fr', 'rfi.fr', 'euronews.com', 'cnn.com', 'bbc.com', 'reuters.com', 'france24.com'],
|
||||||
|
urls: ['news', 'article', 'actualit', 'info', 'breaking', 'flash'],
|
||||||
|
selectors: ['.article', '.news-article', '[class*="news"]', '[class*="article"]'],
|
||||||
|
meta: ['article:section', 'article:tag'],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0500': 1.5, // Clickbait très grave en news
|
||||||
|
'TE0132': 1.4, // Biais négativité suspect
|
||||||
|
'TE0221': 1.6, // Stéréotypes inacceptables
|
||||||
|
'TE0501': 1.3 // FOMO suspect en news
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
blog: {
|
||||||
|
domains: ['medium.com', 'substack.com', 'wordpress.com', 'blogspot.com', 'ghost.io'],
|
||||||
|
urls: ['blog', 'post', 'article'],
|
||||||
|
selectors: ['.post', '.blog-post', '[class*="blog"]', '.entry'],
|
||||||
|
meta: ['article:author'],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0212': 0.8, // Anecdotes plus normales
|
||||||
|
'TE0314': 0.9, // Suggestions plus acceptables
|
||||||
|
'TE0261': 0.7, // Biais rétrospectif courant
|
||||||
|
'TE0321': 1.1 // Biais confirmation suspect
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
social: {
|
||||||
|
domains: ['facebook.com', 'twitter.com', 'instagram.com', 'linkedin.com', 'tiktok.com', 'youtube.com', 'reddit.com', 'discord.com', 'telegram.org'],
|
||||||
|
urls: ['social', 'post', 'status', 'tweet', 'story'],
|
||||||
|
selectors: ['.post', '.tweet', '.story', '[data-testid*="tweet"]', '[role="article"]'],
|
||||||
|
meta: ['twitter:card', 'og:type'],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0132': 0.9, // Négativité plus courante
|
||||||
|
'TE0131': 0.8, // Bizarrerie normale
|
||||||
|
'TE0501': 1.3, // FOMO plus manipulatoire
|
||||||
|
'TE0221': 1.7, // Stéréotypes très graves
|
||||||
|
'TE0251': 1.2 // Faux consensus suspect
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
commerce: {
|
||||||
|
domains: ['amazon.com', 'aliexpress.com', 'cdiscount.com', 'fnac.com', 'darty.com', 'leclerc.com', 'carrefour.fr', 'shopify.com'],
|
||||||
|
urls: ['shop', 'buy', 'product', 'store', 'cart', 'checkout', 'commerce', 'vente'],
|
||||||
|
selectors: ['.product', '.shop', '.store', '[class*="price"]', '.add-to-cart'],
|
||||||
|
meta: ['product:price', 'product:availability'],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0501': 0.8, // FOMO plus normale en commerce
|
||||||
|
'TE0141': 0.7, // Effet Restorff marketing normal
|
||||||
|
'TE0143': 0.6, // Comparaisons normales
|
||||||
|
'TE0422': 1.2, // Fausse autorité problématique
|
||||||
|
'TE0411': 1.1 // Excès confiance suspect
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
educational: {
|
||||||
|
domains: ['wikipedia.org', 'edu', 'ac.uk', 'universalis.fr', 'larousse.fr', 'coursera.com', 'edx.org', 'khanacademy.org'],
|
||||||
|
urls: ['learn', 'course', 'education', 'wiki', 'tutorial', 'lesson', 'formation'],
|
||||||
|
selectors: ['.course', '.lesson', '.wiki-content', '.educational'],
|
||||||
|
meta: ['article:section'],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0221': 1.8, // Stéréotypes très graves en éducation
|
||||||
|
'TE0422': 0.8, // Autorité plus normale
|
||||||
|
'TE0212': 0.7, // Exemples pédagogiques normaux
|
||||||
|
'TE0241': 0.8 // Simplifications parfois nécessaires
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
health: {
|
||||||
|
domains: ['ameli.fr', 'who.int', 'doctissimo.fr', 'vidal.fr', 'pasteur.fr', 'has-sante.fr', 'webmd.com', 'mayoclinic.org'],
|
||||||
|
urls: ['health', 'medical', 'sante', 'medecin', 'doctor', 'hospital', 'clinic'],
|
||||||
|
selectors: ['.health-content', '.medical', '[class*="health"]'],
|
||||||
|
meta: ['article:section'],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0422': 0.7, // Autorité médicale légitime
|
||||||
|
'TE0212': 1.4, // Preuves anecdotiques dangereuses
|
||||||
|
'TE0221': 1.9, // Stéréotypes très graves
|
||||||
|
'TE0500': 1.6, // Clickbait santé très dangereux
|
||||||
|
'TE0501': 1.5 // FOMO santé dangereux
|
||||||
|
}
|
||||||
|
},
|
||||||
|
political: {
|
||||||
|
domains: ['gouvernement.fr', 'elysee.fr', 'assemblee-nationale.fr', 'senat.fr', 'service-public.fr'],
|
||||||
|
urls: ['politique', 'political', 'election', 'vote', 'government','gouv', 'gov', 'ministre'],
|
||||||
|
selectors: ['.political', '.government', '[class*="politic"]'],
|
||||||
|
meta: ['article:section'],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0221': 2.0, // Stéréotypes très graves en politique
|
||||||
|
'TE0132': 1.3, // Biais négativité suspect
|
||||||
|
'TE0251': 1.5, // Faux consensus très suspect
|
||||||
|
'TE0321': 1.4, // Biais confirmation dangereux
|
||||||
|
'TE0422': 1.2 // Fausse autorité problématique
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
financial: {
|
||||||
|
domains: ['banque-france.fr', 'amf-france.org', 'boursorama.com', 'lesechos.fr', 'bloomberg.com', 'reuters.com'],
|
||||||
|
urls: ['finance', 'investment', 'bourse', 'crypto', 'trading', 'bank', 'credit'],
|
||||||
|
selectors: ['.financial', '.investment', '[class*="finance"]', '.trading'],
|
||||||
|
meta: ['article:section'],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0501': 1.6, // FOMO financier très dangereux
|
||||||
|
'TE0422': 1.3, // Fausse autorité financière grave
|
||||||
|
'TE0411': 1.4, // Excès confiance dangereux
|
||||||
|
'TE0500': 1.5, // Clickbait financier dangereux
|
||||||
|
'TE0212': 1.3 // Preuves anecdotiques suspectes
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
gaming: {
|
||||||
|
domains: ['steam.com', 'epicgames.com', 'twitch.tv', 'gamepass.com', 'ign.com', 'gamespot.com'],
|
||||||
|
urls: ['game', 'gaming', 'jeux', 'play', 'stream'],
|
||||||
|
selectors: ['.game', '.gaming', '[class*="game"]', '.player'],
|
||||||
|
meta: ['og:type'],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0501': 0.9, // FOMO plus normal en gaming
|
||||||
|
'TE0141': 0.8, // Unicité marketing normale
|
||||||
|
'TE0131': 0.7, // Bizarrerie plus normale
|
||||||
|
'TE0421': 1.2 // Coûts irrécupérables suspect (microtransactions)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dating: {
|
||||||
|
domains: ['tinder.com', 'meetic.fr', 'adopteunmec.com', 'badoo.com', 'bumble.com'],
|
||||||
|
urls: ['dating', 'rencontre', 'love', 'flirt'],
|
||||||
|
selectors: ['.profile', '.dating', '[class*="match"]', '.member'],
|
||||||
|
meta: ['og:type'],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0501': 1.4, // FOMO émotionnel suspect
|
||||||
|
'TE0221': 1.8, // Stéréotypes graves
|
||||||
|
'TE0131': 1.1, // Bizarrerie suspecte
|
||||||
|
'TE0251': 1.3, // Faux consensus suspect
|
||||||
|
'TE0422': 1.2 // Fausse autorité suspecte
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
conspiracy: {
|
||||||
|
domains: ['4chan.org', 'infowars.com', 'breitbart.com'],
|
||||||
|
urls: ['conspiracy', 'complot', 'truth', 'expose', 'reveal', 'secret'],
|
||||||
|
selectors: ['.conspiracy', '.truth', '[class*="expose"]'],
|
||||||
|
meta: [],
|
||||||
|
weight_adjustments: {
|
||||||
|
'TE0221': 2.5, // Stéréotypes extrêmement graves
|
||||||
|
'TE0132': 1.8, // Biais négativité très suspect
|
||||||
|
'TE0500': 1.9, // Clickbait très dangereux
|
||||||
|
'TE0212': 1.7, // Preuves anecdotiques très suspectes
|
||||||
|
'TE0251': 1.8, // Faux consensus très dangereux
|
||||||
|
'TE0321': 1.6 // Biais confirmation très dangereux
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ===== BASE DE DONNÉES DES MOTS-CLÉS AMÉLIORÉS =====
|
||||||
|
const DIMA_ENHANCED_KEYWORDS = {
|
||||||
|
"TE0111": {
|
||||||
|
core: ["exemple", "cas", "témoignage", "example", "case", "testimony"],
|
||||||
|
variants: {
|
||||||
|
formal: ["illustration", "démonstration", "spécimen"],
|
||||||
|
informal: ["histoire", "vécu", "expérience"],
|
||||||
|
intensity: {
|
||||||
|
weak: ["petit exemple", "simple cas"],
|
||||||
|
strong: ["exemple frappant", "cas édifiant", "témoignage bouleversant"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
patterns: [
|
||||||
|
/(?:par\s+exemple|for\s+example|comme\s+dans\s+le\s+cas)/i,
|
||||||
|
/(?:prenons\s+l'exemple|take\s+the\s+example)/i
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"TE0500": {
|
||||||
|
core: ["secret", "choquant", "incroyable", "shocking", "amazing"],
|
||||||
|
variants: {
|
||||||
|
clickbait_formulas: [
|
||||||
|
"vous ne croirez pas", "ce qui arrive ensuite", "you won't believe",
|
||||||
|
"what happens next", "les experts détestent", "un truc simple",
|
||||||
|
"cette astuce", "révélation choc", "doctors hate this"
|
||||||
|
],
|
||||||
|
emotional_hooks: [
|
||||||
|
"ça va vous surprendre", "préparez-vous", "attention",
|
||||||
|
"exclusif", "urgent", "will shock you", "prepare yourself"
|
||||||
|
],
|
||||||
|
curiosity_gaps: [
|
||||||
|
"la raison va vous étonner", "voici pourquoi", "découvrez comment",
|
||||||
|
"la vérité sur", "the reason will amaze you", "here's why"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
patterns: [
|
||||||
|
/\d+\s+(?:choses|façons|méthodes|secrets|things|ways|methods)\s+(?:que|pour|de|to|that)/i,
|
||||||
|
/(?:voici|découvrez|here's|discover)\s+(?:comment|pourquoi|ce que|how|why|what)/i,
|
||||||
|
/(?:cette|cette|this)\s+\w+\s+va\s+vous\s+(?:\w+|will)/i,
|
||||||
|
/(?:shocking|amazing|incredible)\s+(?:secret|truth|fact)/i
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"TE0132": {
|
||||||
|
core: ["catastrophe", "panique", "chaos", "disaster", "danger", "menace", "threat", "risque", "risk", "grave", "serious", "crise", "crisis"],
|
||||||
|
variants: {
|
||||||
|
intensity: {
|
||||||
|
weak: ["problème", "difficulté", "souci", "issue", "concern"],
|
||||||
|
strong: ["catastrophe majeure", "crise grave", "danger mortel", "major catastrophe", "deadly danger"]
|
||||||
|
},
|
||||||
|
temporal: ["imminent", "proche", "bientôt", "soon", "approaching"]
|
||||||
|
},
|
||||||
|
patterns: [
|
||||||
|
/(?:alerte|alert|warning|attention)\s+(?:rouge|red|maximum)/i,
|
||||||
|
/(?:situation|crisis|problem)\s+(?:critique|critical|dramatique|dramatic)/i
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"TE0501": {
|
||||||
|
core: ["ne ratez pas", "don't miss", "dernière chance", "last chance", "limité", "limited", "exclusif", "exclusive"],
|
||||||
|
variants: {
|
||||||
|
urgency: ["dépêchez-vous", "hurry up", "vite", "quickly", "maintenant ou jamais", "now or never"],
|
||||||
|
scarcity: ["stock limité", "places limitées", "limited stock", "limited seats", "offre limitée"]
|
||||||
|
},
|
||||||
|
patterns: [
|
||||||
|
/(?:seulement|only)\s+\d+\s+(?:jours?|heures?|minutes?|days?|hours?|minutes?)/i,
|
||||||
|
/(?:expire|ends?)\s+(?:bientôt|soon|today|demain|tomorrow)/i
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// ===== PATTERNS CONTEXTUELS ÉTENDUS =====
|
||||||
|
const CONTEXT_PATTERNS = {
|
||||||
|
urgency: {
|
||||||
|
patterns: [
|
||||||
|
/(?:urgent|rapidement|vite|immédiatement|maintenant|now|quickly|immediately)/i,
|
||||||
|
/(?:dernière\s+chance|temps\s+limité|offre\s+limitée|last\s+chance|limited\s+time)/i,
|
||||||
|
/(?:dépêchez-vous|ne\s+ratez\s+pas|hurry|don't\s+miss)/i,
|
||||||
|
/(?:avant\s+qu'il\s+soit\s+trop\s+tard|before\s+it's\s+too\s+late)/i
|
||||||
|
],
|
||||||
|
boost: 1.3,
|
||||||
|
techniques: ['TE0501', 'TE0500']
|
||||||
|
},
|
||||||
|
authority: {
|
||||||
|
patterns: [
|
||||||
|
/(?:selon\s+(?:les\s+)?(?:experts?|spécialistes?|docteurs?|doctors?|experts?))/i,
|
||||||
|
/(?:étude\s+(?:révèle|montre|démontre|shows?|reveals?))/i,
|
||||||
|
/(?:recherche\s+(?:scientifique|universitaire|scientific|university))/i,
|
||||||
|
/(?:professeur|université|institut|laboratory)/i
|
||||||
|
],
|
||||||
|
boost: 1.4,
|
||||||
|
techniques: ['TE0422', 'TE0212']
|
||||||
|
},
|
||||||
|
social_proof: {
|
||||||
|
patterns: [
|
||||||
|
/(?:\d+(?:\.\d+)?[km]?\s+personnes?\s+(?:utilisent|font|pensent|people\s+(?:use|do|think)))/i,
|
||||||
|
/(?:tout\s+le\s+monde|la\s+plupart\s+des\s+gens|everyone|most\s+people)/i,
|
||||||
|
/(?:viral|tendance|populaire|trending|popular)/i,
|
||||||
|
/(?:millions\s+de|thousands\s+of|des\s+milliers)/i
|
||||||
|
],
|
||||||
|
boost: 1.2,
|
||||||
|
techniques: ['TE0251', 'TE0221']
|
||||||
|
},
|
||||||
|
fear: {
|
||||||
|
patterns: [
|
||||||
|
/(?:attention|danger|risque|warning|risk|threat)/i,
|
||||||
|
/(?:peur|fear|afraid|effrayant|scary)/i,
|
||||||
|
/(?:catastrophe|disaster|tragédie|tragedy)/i
|
||||||
|
],
|
||||||
|
boost: 1.4,
|
||||||
|
techniques: ['TE0132', 'TE0500']
|
||||||
|
},
|
||||||
|
conspiracy: {
|
||||||
|
patterns: [
|
||||||
|
/(?:ils\s+(?:ne\s+veulent\s+pas|cachent)|they\s+(?:don't\s+want|hide))/i,
|
||||||
|
/(?:vérité\s+cachée|hidden\s+truth|secret\s+agenda)/i,
|
||||||
|
/(?:complot|conspiracy|manipulation\s+des\s+masses)/i,
|
||||||
|
/(?:révélation|expose|dévoile|reveals?)/i
|
||||||
|
],
|
||||||
|
boost: 1.6,
|
||||||
|
techniques: ['TE0500', 'TE0221', 'TE0132']
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Make keywords and patterns available globally for Chrome extension
|
||||||
|
window.DIMA_ENHANCED_KEYWORDS = DIMA_ENHANCED_KEYWORDS;
|
||||||
|
window.CONTEXT_PATTERNS = CONTEXT_PATTERNS;
|
||||||
922
static/files/Plugin-dima-V1/Data/techniques.js
Обычный файл
922
static/files/Plugin-dima-V1/Data/techniques.js
Обычный файл
@ -0,0 +1,922 @@
|
|||||||
|
// DIMA Techniques Database
|
||||||
|
// Complete database of manipulation techniques and tactics
|
||||||
|
|
||||||
|
const DIMA_TECHNIQUES = [
|
||||||
|
// PHASE DETECTER - TACTIQUES
|
||||||
|
{
|
||||||
|
index: "TA0011",
|
||||||
|
nom: "Information préexistante",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Exploitation d'informations déjà connues ou familières",
|
||||||
|
mots_cles: [
|
||||||
|
"déjà",
|
||||||
|
"connu",
|
||||||
|
"already",
|
||||||
|
"known",
|
||||||
|
"familier",
|
||||||
|
"familiar",
|
||||||
|
"habituel",
|
||||||
|
"usual",
|
||||||
|
"précédemment",
|
||||||
|
"previously",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0012",
|
||||||
|
nom: "Information à exposition répétée",
|
||||||
|
phase: "Detect",
|
||||||
|
description:
|
||||||
|
"Répétition d'informations pour créer une familiarité artificielle",
|
||||||
|
mots_cles: [
|
||||||
|
"encore",
|
||||||
|
"again",
|
||||||
|
"répéter",
|
||||||
|
"repeat",
|
||||||
|
"redire",
|
||||||
|
"retell",
|
||||||
|
"rappel",
|
||||||
|
"reminder",
|
||||||
|
"à nouveau",
|
||||||
|
"once again",
|
||||||
|
],
|
||||||
|
weight: 1.2,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0013",
|
||||||
|
nom: "Information clivante",
|
||||||
|
phase: "Detect",
|
||||||
|
description:
|
||||||
|
"Utilisation d'informations polarisantes pour attirer l'attention",
|
||||||
|
mots_cles: [
|
||||||
|
"polémique",
|
||||||
|
"controversial",
|
||||||
|
"scandaleux",
|
||||||
|
"outrageous",
|
||||||
|
"choquant",
|
||||||
|
"shocking",
|
||||||
|
"divise",
|
||||||
|
"divides",
|
||||||
|
"clivant",
|
||||||
|
],
|
||||||
|
weight: 1.4,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0014",
|
||||||
|
nom: "Écart à la norme",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Mise en avant d'éléments sortant de l'ordinaire",
|
||||||
|
mots_cles: [
|
||||||
|
"inhabituel",
|
||||||
|
"unusual",
|
||||||
|
"anormal",
|
||||||
|
"abnormal",
|
||||||
|
"exception",
|
||||||
|
"extraordinary",
|
||||||
|
"hors norme",
|
||||||
|
"atypique",
|
||||||
|
],
|
||||||
|
weight: 1.3,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0015",
|
||||||
|
nom: "Détail signifiant",
|
||||||
|
phase: "Detect",
|
||||||
|
description:
|
||||||
|
"Focus sur des détails pour donner une impression de précision",
|
||||||
|
mots_cles: [
|
||||||
|
"précisément",
|
||||||
|
"exactly",
|
||||||
|
"détail",
|
||||||
|
"detail",
|
||||||
|
"spécifiquement",
|
||||||
|
"specifically",
|
||||||
|
"en particulier",
|
||||||
|
"particularly",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
|
||||||
|
// PHASE DETECTER - TECHNIQUES
|
||||||
|
{
|
||||||
|
index: "TE0111",
|
||||||
|
nom: "Heuristique de disponibilité",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Surreprésentation d'exemples facilement mémorisables",
|
||||||
|
mots_cles: [
|
||||||
|
"récent",
|
||||||
|
"disponible",
|
||||||
|
"recently",
|
||||||
|
"exemple",
|
||||||
|
"example",
|
||||||
|
"cas",
|
||||||
|
"case",
|
||||||
|
"témoignage",
|
||||||
|
"testimony",
|
||||||
|
],
|
||||||
|
weight: 1.0,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0011",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0112",
|
||||||
|
nom: "Effet de simple exposition",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Répétition pour créer une familiarité artificielle",
|
||||||
|
mots_cles: [
|
||||||
|
"encore",
|
||||||
|
"again",
|
||||||
|
"toujours",
|
||||||
|
"always",
|
||||||
|
"répétition",
|
||||||
|
"repetition",
|
||||||
|
"familier",
|
||||||
|
"familiar",
|
||||||
|
],
|
||||||
|
weight: 1.2,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0011",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0121",
|
||||||
|
nom: "Illusion de la fréquence",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Impression exagérée de fréquence d'un phénomène",
|
||||||
|
mots_cles: [
|
||||||
|
"partout",
|
||||||
|
"everywhere",
|
||||||
|
"de plus en plus",
|
||||||
|
"more and more",
|
||||||
|
"fréquent",
|
||||||
|
"frequent",
|
||||||
|
"épidémie",
|
||||||
|
"epidemic",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0012",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0122",
|
||||||
|
nom: "Effet de contexte",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Utilisation du contexte pour influencer la perception",
|
||||||
|
mots_cles: [
|
||||||
|
"similaire",
|
||||||
|
"same as",
|
||||||
|
"cela rappelle",
|
||||||
|
"déjà vu",
|
||||||
|
"par ailleurs",
|
||||||
|
"contexte",
|
||||||
|
],
|
||||||
|
weight: 0.9,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0012",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0131",
|
||||||
|
nom: "Effet de bizarrerie",
|
||||||
|
phase: "Detect",
|
||||||
|
description:
|
||||||
|
"Mise en avant d'éléments inhabituels pour attirer l'attention",
|
||||||
|
mots_cles: [
|
||||||
|
"étrange",
|
||||||
|
"strange",
|
||||||
|
"bizarre",
|
||||||
|
"weird",
|
||||||
|
"incroyable",
|
||||||
|
"incredible",
|
||||||
|
"choquant",
|
||||||
|
"shocking",
|
||||||
|
"inhabituel",
|
||||||
|
"unusual",
|
||||||
|
],
|
||||||
|
weight: 1.3,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0013",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0132",
|
||||||
|
nom: "Biais de négativité",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Accent mis sur les aspects négatifs pour capter l'attention",
|
||||||
|
mots_cles: [
|
||||||
|
"catastrophe",
|
||||||
|
"chaos",
|
||||||
|
"disaster",
|
||||||
|
"danger",
|
||||||
|
"menace",
|
||||||
|
"threat",
|
||||||
|
"risque",
|
||||||
|
"risk",
|
||||||
|
"grave",
|
||||||
|
"serious",
|
||||||
|
"crise",
|
||||||
|
"crisis",
|
||||||
|
],
|
||||||
|
weight: 1.4,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0013",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0141",
|
||||||
|
nom: "Effet von Restorff",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Mise en avant de l'unicité pour marquer les esprits",
|
||||||
|
mots_cles: [
|
||||||
|
"unique",
|
||||||
|
"seul",
|
||||||
|
"only",
|
||||||
|
"exclusif",
|
||||||
|
"exclusive",
|
||||||
|
"spécial",
|
||||||
|
"special",
|
||||||
|
"exceptionnel",
|
||||||
|
"exceptional",
|
||||||
|
"rare",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0014",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0142",
|
||||||
|
nom: "Biais d'ancrage",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Première information comme point de référence",
|
||||||
|
mots_cles: [
|
||||||
|
"première fois",
|
||||||
|
"first time",
|
||||||
|
"jamais vu",
|
||||||
|
"never seen",
|
||||||
|
"inédit",
|
||||||
|
"unprecedented",
|
||||||
|
"révélation",
|
||||||
|
"revelation",
|
||||||
|
],
|
||||||
|
weight: 1.2,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0015",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0143",
|
||||||
|
nom: "Effet de contraste",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Comparaisons pour influencer la perception relative",
|
||||||
|
mots_cles: [
|
||||||
|
"par rapport à",
|
||||||
|
"compare with",
|
||||||
|
"différence",
|
||||||
|
"difference",
|
||||||
|
"comparaison",
|
||||||
|
"delta",
|
||||||
|
"distinction",
|
||||||
|
],
|
||||||
|
weight: 0.8,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0015",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0500",
|
||||||
|
nom: "Clickbait",
|
||||||
|
phase: "Detect",
|
||||||
|
description: "Titres accrocheurs pour générer des clics",
|
||||||
|
mots_cles: [
|
||||||
|
"vous ne croirez pas",
|
||||||
|
"you won't believe",
|
||||||
|
"ce qui arrive ensuite",
|
||||||
|
"what happens next",
|
||||||
|
"secret",
|
||||||
|
"shocking",
|
||||||
|
"mind-blowing",
|
||||||
|
"amazing",
|
||||||
|
],
|
||||||
|
weight: 1.5,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0013",
|
||||||
|
},
|
||||||
|
|
||||||
|
// PHASE INFORMER - TACTIQUES
|
||||||
|
{
|
||||||
|
index: "TA0021",
|
||||||
|
nom: "Création d'un motif",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Construction artificielle de patterns ou de tendances",
|
||||||
|
mots_cles: [
|
||||||
|
"motif",
|
||||||
|
"pattern",
|
||||||
|
"tendance",
|
||||||
|
"trend",
|
||||||
|
"récurrent",
|
||||||
|
"recurrent",
|
||||||
|
"régulier",
|
||||||
|
"regular",
|
||||||
|
"systématique",
|
||||||
|
],
|
||||||
|
weight: 1.3,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0022",
|
||||||
|
nom: "Généralisation et renforcement de stéréotypes",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Utilisation et amplification de clichés pour simplifier",
|
||||||
|
mots_cles: [
|
||||||
|
"stéréotype",
|
||||||
|
"stereotype",
|
||||||
|
"cliché",
|
||||||
|
"caricature",
|
||||||
|
"généralement",
|
||||||
|
"generally",
|
||||||
|
"typique",
|
||||||
|
"typical",
|
||||||
|
],
|
||||||
|
weight: 1.6,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0023",
|
||||||
|
nom: "Supériorité familière",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Valorisation de ce qui est connu et familier",
|
||||||
|
mots_cles: [
|
||||||
|
"mieux",
|
||||||
|
"better",
|
||||||
|
"supérieur",
|
||||||
|
"superior",
|
||||||
|
"préférable",
|
||||||
|
"preferable",
|
||||||
|
"notre",
|
||||||
|
"our",
|
||||||
|
"familier",
|
||||||
|
"familiar",
|
||||||
|
],
|
||||||
|
weight: 1.2,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0024",
|
||||||
|
nom: "Simplification",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Réduction excessive de la complexité",
|
||||||
|
mots_cles: [
|
||||||
|
"simple",
|
||||||
|
"simple",
|
||||||
|
"facile",
|
||||||
|
"easy",
|
||||||
|
"évident",
|
||||||
|
"obvious",
|
||||||
|
"clair",
|
||||||
|
"clear",
|
||||||
|
"suffit",
|
||||||
|
"enough",
|
||||||
|
],
|
||||||
|
weight: 1.3,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0025",
|
||||||
|
nom: "Auto-référence",
|
||||||
|
phase: "Informer",
|
||||||
|
description:
|
||||||
|
"Utilisation de références internes pour créer une cohérence artificielle",
|
||||||
|
mots_cles: [
|
||||||
|
"comme nous",
|
||||||
|
"like us",
|
||||||
|
"notre",
|
||||||
|
"our",
|
||||||
|
"nous-mêmes",
|
||||||
|
"ourselves",
|
||||||
|
"chez nous",
|
||||||
|
"among us",
|
||||||
|
],
|
||||||
|
weight: 1.2,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0026",
|
||||||
|
nom: "Projection temporelle",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Manipulation de la perception du temps",
|
||||||
|
mots_cles: [
|
||||||
|
"bientôt",
|
||||||
|
"soon",
|
||||||
|
"déjà",
|
||||||
|
"already",
|
||||||
|
"encore",
|
||||||
|
"still",
|
||||||
|
"toujours",
|
||||||
|
"always",
|
||||||
|
"jamais",
|
||||||
|
"never",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
|
||||||
|
// PHASE INFORMER - TECHNIQUES
|
||||||
|
{
|
||||||
|
index: "TE0211",
|
||||||
|
nom: "Corrélation illusoire",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Présentation de corrélations trompeuses",
|
||||||
|
mots_cles: [
|
||||||
|
"corrélation",
|
||||||
|
"similaire",
|
||||||
|
"pareil",
|
||||||
|
"comparaison",
|
||||||
|
"lien",
|
||||||
|
"relation",
|
||||||
|
],
|
||||||
|
weight: 1.3,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0021",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0212",
|
||||||
|
nom: "Biais de la preuve anecdotique",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Généralisation basée sur des cas particuliers",
|
||||||
|
mots_cles: [
|
||||||
|
"cette histoire démontre",
|
||||||
|
"anecdote",
|
||||||
|
"exemple",
|
||||||
|
"illustration",
|
||||||
|
"selon une étude",
|
||||||
|
"un témoignage",
|
||||||
|
"un témoin",
|
||||||
|
],
|
||||||
|
weight: 1.4,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0021",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0213",
|
||||||
|
nom: "Illusion des séries",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Perception de motifs dans des données aléatoires",
|
||||||
|
mots_cles: [
|
||||||
|
"coïncidences",
|
||||||
|
"motif",
|
||||||
|
"données démontrent",
|
||||||
|
"statistiques",
|
||||||
|
"tendance",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0021",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0221",
|
||||||
|
nom: "Stéréotypes",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Généralisation excessive de groupes",
|
||||||
|
mots_cles: [
|
||||||
|
"stéréotype",
|
||||||
|
"les étrangers",
|
||||||
|
"les immigrants",
|
||||||
|
"all the",
|
||||||
|
"toujours",
|
||||||
|
"always",
|
||||||
|
"jamais",
|
||||||
|
"never",
|
||||||
|
"en général",
|
||||||
|
"in general",
|
||||||
|
"les français",
|
||||||
|
"americans",
|
||||||
|
],
|
||||||
|
weight: 1.6,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0022",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0231",
|
||||||
|
nom: "Biais d'homogénéité",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Perception que tous les membres d'un groupe sont similaires",
|
||||||
|
mots_cles: [
|
||||||
|
"tous les",
|
||||||
|
"Homogène",
|
||||||
|
"tous pareil",
|
||||||
|
"toutes choses égales par ailleurs",
|
||||||
|
],
|
||||||
|
weight: 1.2,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0022",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0232",
|
||||||
|
nom: "Biais de la route connue",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Préférence pour les solutions familières",
|
||||||
|
mots_cles: [
|
||||||
|
"comme avant",
|
||||||
|
"habitude",
|
||||||
|
"habituel",
|
||||||
|
"conserver",
|
||||||
|
"rassurant",
|
||||||
|
],
|
||||||
|
weight: 0.9,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0023",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0241",
|
||||||
|
nom: "Simplification excessive",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Réduction de problèmes complexes à des solutions simples",
|
||||||
|
mots_cles: [
|
||||||
|
"simple",
|
||||||
|
"évident",
|
||||||
|
"obvious",
|
||||||
|
"clair",
|
||||||
|
"clear",
|
||||||
|
"facile",
|
||||||
|
"easy",
|
||||||
|
"suffit de",
|
||||||
|
"just need to",
|
||||||
|
"solution",
|
||||||
|
],
|
||||||
|
weight: 1.3,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0024",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0251",
|
||||||
|
nom: "Faux consensus",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Illusion d'un accord général inexistant",
|
||||||
|
mots_cles: [
|
||||||
|
"tout le monde",
|
||||||
|
"consensus",
|
||||||
|
"convergence",
|
||||||
|
"everyone",
|
||||||
|
"la plupart",
|
||||||
|
"most people",
|
||||||
|
"nous pensons",
|
||||||
|
"we think",
|
||||||
|
"accord",
|
||||||
|
],
|
||||||
|
weight: 1.4,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0025",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0261",
|
||||||
|
nom: "Biais rétrospectif",
|
||||||
|
phase: "Informer",
|
||||||
|
description: "Illusion d'avoir prévu un événement après coup",
|
||||||
|
mots_cles: [
|
||||||
|
"j'avais dit",
|
||||||
|
"nous étions prévenus",
|
||||||
|
"on le savait",
|
||||||
|
"i told you",
|
||||||
|
"prévisible",
|
||||||
|
"predictable",
|
||||||
|
"on aurait dû",
|
||||||
|
"should have",
|
||||||
|
"signes",
|
||||||
|
"signs",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0026",
|
||||||
|
},
|
||||||
|
|
||||||
|
// PHASE MEMORISER - TACTIQUES
|
||||||
|
{
|
||||||
|
index: "TA0031",
|
||||||
|
nom: "Renforcement indirect",
|
||||||
|
phase: "Mémoriser",
|
||||||
|
description:
|
||||||
|
"Consolidation subtile d'informations par répétition indirecte",
|
||||||
|
mots_cles: [
|
||||||
|
"renforce",
|
||||||
|
"reinforces",
|
||||||
|
"confirme",
|
||||||
|
"confirms",
|
||||||
|
"soutient",
|
||||||
|
"supports",
|
||||||
|
"appuie",
|
||||||
|
"backs",
|
||||||
|
],
|
||||||
|
weight: 1.2,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0032",
|
||||||
|
nom: "Renforcement pré-existant",
|
||||||
|
phase: "Mémoriser",
|
||||||
|
description: "Activation de croyances déjà établies",
|
||||||
|
mots_cles: [
|
||||||
|
"comme prévu",
|
||||||
|
"as expected",
|
||||||
|
"j'avais raison",
|
||||||
|
"I was right",
|
||||||
|
"évident",
|
||||||
|
"obvious",
|
||||||
|
"logique",
|
||||||
|
"logical",
|
||||||
|
],
|
||||||
|
weight: 1.3,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0033",
|
||||||
|
nom: "Exposition de contenus",
|
||||||
|
phase: "Mémoriser",
|
||||||
|
description: "Présentation répétée de contenus pour ancrage mémoriel",
|
||||||
|
mots_cles: [
|
||||||
|
"exposition",
|
||||||
|
"exposure",
|
||||||
|
"présentation",
|
||||||
|
"presentation",
|
||||||
|
"affichage",
|
||||||
|
"display",
|
||||||
|
"montrer",
|
||||||
|
"show",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
|
||||||
|
// PHASE MEMORISER - TECHNIQUES
|
||||||
|
{
|
||||||
|
index: "TE0312",
|
||||||
|
nom: "Biais de la confusion des sources",
|
||||||
|
phase: "Mémoriser",
|
||||||
|
description: "Difficulté à distinguer les sources d'information",
|
||||||
|
mots_cles: [
|
||||||
|
"des sources affirment",
|
||||||
|
"sources confirment",
|
||||||
|
"rien ne démontre",
|
||||||
|
"hasard ?",
|
||||||
|
"les faits",
|
||||||
|
],
|
||||||
|
weight: 1.2,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0031",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0313",
|
||||||
|
nom: "Effet d'espacement",
|
||||||
|
phase: "Mémoriser",
|
||||||
|
description: "Répétition espacée pour renforcer la mémorisation",
|
||||||
|
mots_cles: [
|
||||||
|
"comme déjà",
|
||||||
|
"dans un article précédent",
|
||||||
|
"rappelons",
|
||||||
|
"comme nous l'avons vu",
|
||||||
|
],
|
||||||
|
weight: 1.0,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0033",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0314",
|
||||||
|
nom: "Effet de suggestion",
|
||||||
|
phase: "Mémoriser",
|
||||||
|
description: "Implantation d'idées par suggestion indirecte",
|
||||||
|
mots_cles: [
|
||||||
|
"et si",
|
||||||
|
"cela évoque",
|
||||||
|
"évoquer",
|
||||||
|
"image",
|
||||||
|
"imaginez",
|
||||||
|
"supposons",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0031",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0321",
|
||||||
|
nom: "Biais de confirmation",
|
||||||
|
phase: "Mémoriser",
|
||||||
|
description: "Recherche d'informations confirmant les croyances existantes",
|
||||||
|
mots_cles: [
|
||||||
|
"confirme",
|
||||||
|
"cela démontre",
|
||||||
|
"démontrer",
|
||||||
|
"confirms",
|
||||||
|
"prouve",
|
||||||
|
"proves",
|
||||||
|
"comme prévu",
|
||||||
|
"as expected",
|
||||||
|
"j'avais raison",
|
||||||
|
"i was right",
|
||||||
|
"évident",
|
||||||
|
"obvious",
|
||||||
|
],
|
||||||
|
weight: 1.5,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0032",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0331",
|
||||||
|
nom: "Effet de récence",
|
||||||
|
phase: "Mémoriser",
|
||||||
|
description: "Surpondération des informations récentes",
|
||||||
|
mots_cles: [
|
||||||
|
"récent",
|
||||||
|
"recent",
|
||||||
|
"nouveauté",
|
||||||
|
"dernier",
|
||||||
|
"last",
|
||||||
|
"nouveau",
|
||||||
|
"new",
|
||||||
|
"frais",
|
||||||
|
"fresh",
|
||||||
|
"actuel",
|
||||||
|
"current",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0033",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0333",
|
||||||
|
nom: "Effet de primauté",
|
||||||
|
phase: "Mémoriser",
|
||||||
|
description: "Surpondération des premières informations reçues",
|
||||||
|
mots_cles: [
|
||||||
|
"premier",
|
||||||
|
"first",
|
||||||
|
"initial",
|
||||||
|
"début",
|
||||||
|
"beginning",
|
||||||
|
"origine",
|
||||||
|
"origin",
|
||||||
|
"primordial",
|
||||||
|
],
|
||||||
|
weight: 1.0,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0033",
|
||||||
|
},
|
||||||
|
|
||||||
|
// PHASE AGIR - TACTIQUES
|
||||||
|
{
|
||||||
|
index: "TA0041",
|
||||||
|
nom: "Valorisation individuelle",
|
||||||
|
phase: "Act",
|
||||||
|
description: "Mise en avant des bénéfices personnels pour motiver l'action",
|
||||||
|
mots_cles: [
|
||||||
|
"vous bénéficiez",
|
||||||
|
"you benefit",
|
||||||
|
"votre avantage",
|
||||||
|
"your advantage",
|
||||||
|
"pour vous",
|
||||||
|
"for you",
|
||||||
|
"personnel",
|
||||||
|
"personal",
|
||||||
|
],
|
||||||
|
weight: 1.3,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0042",
|
||||||
|
nom: "Renforcement escalatoire",
|
||||||
|
phase: "Act",
|
||||||
|
description: "Augmentation progressive de l'engagement demandé",
|
||||||
|
mots_cles: [
|
||||||
|
"progressivement",
|
||||||
|
"progressively",
|
||||||
|
"étape par étape",
|
||||||
|
"step by step",
|
||||||
|
"graduellement",
|
||||||
|
"gradually",
|
||||||
|
"petit à petit",
|
||||||
|
],
|
||||||
|
weight: 1.4,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TA0043",
|
||||||
|
nom: "Ozaekomi waza (contrôle par immobilisation)",
|
||||||
|
phase: "Act",
|
||||||
|
description: "Blocage des alternatives pour forcer une décision",
|
||||||
|
mots_cles: [
|
||||||
|
"seule option",
|
||||||
|
"only option",
|
||||||
|
"pas le choix",
|
||||||
|
"no choice",
|
||||||
|
"obligé",
|
||||||
|
"forced",
|
||||||
|
"contrainte",
|
||||||
|
"constraint",
|
||||||
|
],
|
||||||
|
weight: 1.5,
|
||||||
|
type: "tactic",
|
||||||
|
},
|
||||||
|
|
||||||
|
// PHASE AGIR - TECHNIQUES
|
||||||
|
{
|
||||||
|
index: "TE0411",
|
||||||
|
nom: "Excès de confiance",
|
||||||
|
phase: "Act",
|
||||||
|
description: "Surestimation de ses propres capacités ou connaissances",
|
||||||
|
mots_cles: [
|
||||||
|
"confiant",
|
||||||
|
"confident",
|
||||||
|
"sûr",
|
||||||
|
"sure",
|
||||||
|
"certain",
|
||||||
|
"capable",
|
||||||
|
"expert",
|
||||||
|
"maîtrise",
|
||||||
|
"mastery",
|
||||||
|
],
|
||||||
|
weight: 1.2,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0041",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0421",
|
||||||
|
nom: "Coûts irrécupérables",
|
||||||
|
phase: "Act",
|
||||||
|
description: "Persistance dans une voie du fait d'investissements passés",
|
||||||
|
mots_cles: [
|
||||||
|
"continuer",
|
||||||
|
"continue",
|
||||||
|
"persister",
|
||||||
|
"persist",
|
||||||
|
"investir plus",
|
||||||
|
"invest more",
|
||||||
|
"ne pas abandonner",
|
||||||
|
"don't give up",
|
||||||
|
],
|
||||||
|
weight: 1.1,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0042",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0422",
|
||||||
|
nom: "Biais d'autorité",
|
||||||
|
phase: "Act",
|
||||||
|
description: "Influence excessive des figures d'autorité",
|
||||||
|
mots_cles: [
|
||||||
|
"autorité",
|
||||||
|
"authority",
|
||||||
|
"expert",
|
||||||
|
"spécialiste",
|
||||||
|
"specialist",
|
||||||
|
"professeur",
|
||||||
|
"professor",
|
||||||
|
"docteur",
|
||||||
|
"doctor",
|
||||||
|
"officiel",
|
||||||
|
],
|
||||||
|
weight: 1.3,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0041",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0432",
|
||||||
|
nom: "Biais du statu quo",
|
||||||
|
phase: "Act",
|
||||||
|
description: "Préférence pour maintenir l'état actuel",
|
||||||
|
mots_cles: [
|
||||||
|
"rester",
|
||||||
|
"stay",
|
||||||
|
"maintenir",
|
||||||
|
"maintain",
|
||||||
|
"ne pas changer",
|
||||||
|
"don't change",
|
||||||
|
"status quo",
|
||||||
|
"comme ça",
|
||||||
|
"as is",
|
||||||
|
],
|
||||||
|
weight: 1.0,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0043",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: "TE0501",
|
||||||
|
nom: "FOMO",
|
||||||
|
phase: "Act",
|
||||||
|
description: "Peur de rater une opportunité",
|
||||||
|
mots_cles: [
|
||||||
|
"ne ratez pas",
|
||||||
|
"don't miss",
|
||||||
|
"dernière chance",
|
||||||
|
"last chance",
|
||||||
|
"limité",
|
||||||
|
"limited",
|
||||||
|
"exclusif",
|
||||||
|
"exclusive",
|
||||||
|
"hurry",
|
||||||
|
"urgent",
|
||||||
|
],
|
||||||
|
weight: 1.4,
|
||||||
|
type: "technique",
|
||||||
|
tactic: "TA0041",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// Make DIMA_TECHNIQUES available globally for Chrome extension
|
||||||
|
window.DIMA_TECHNIQUES = DIMA_TECHNIQUES;
|
||||||
Двоичные данные
static/files/Plugin-dima-V1/M82-logo-128.png
Обычный файл
Двоичные данные
static/files/Plugin-dima-V1/M82-logo-128.png
Обычный файл
Двоичный файл не отображается.
|
После Ширина: | Высота: | Размер: 332 KiB |
Двоичные данные
static/files/Plugin-dima-V1/M82-logo-16.png
Обычный файл
Двоичные данные
static/files/Plugin-dima-V1/M82-logo-16.png
Обычный файл
Двоичный файл не отображается.
|
После Ширина: | Высота: | Размер: 332 KiB |
Двоичные данные
static/files/Plugin-dima-V1/M82-logo-48.png
Обычный файл
Двоичные данные
static/files/Plugin-dima-V1/M82-logo-48.png
Обычный файл
Двоичный файл не отображается.
|
После Ширина: | Высота: | Размер: 332 KiB |
146
static/files/Plugin-dima-V1/content.js
Обычный файл
146
static/files/Plugin-dima-V1/content.js
Обычный файл
@ -0,0 +1,146 @@
|
|||||||
|
// Plugin DIMA - content.js - Version finale consolidée
|
||||||
|
// Détection de manipulation cognitive - M82 Project
|
||||||
|
// Version: 3.0 Refactored with ContentExtractor
|
||||||
|
// Note: All dependencies are loaded via manifest.json in correct order
|
||||||
|
|
||||||
|
// ===== CLASSE PRINCIPALE DIMA =====
|
||||||
|
class DIMAAnalyzer {
|
||||||
|
constructor() {
|
||||||
|
this.analysisResults = null;
|
||||||
|
this.cache = new Map();
|
||||||
|
this.settings = {
|
||||||
|
maxContentLength: 5000,
|
||||||
|
minKeywordLength: 3,
|
||||||
|
analysisDelay: 2000,
|
||||||
|
debugMode: false,
|
||||||
|
enhancedKeywords: true,
|
||||||
|
}; // Initialize ContentExtractor with settings
|
||||||
|
this.contentExtractor = new window.ContentExtractor(this.settings);
|
||||||
|
this.pageType = this.contentExtractor.detectPageType();
|
||||||
|
|
||||||
|
// Initialize TechniqueAnalyzer with dependencies
|
||||||
|
this.techniqueAnalyzer = new window.TechniqueAnalyzer(
|
||||||
|
this.settings,
|
||||||
|
window.DIMA_ENHANCED_KEYWORDS,
|
||||||
|
window.CONTEXT_PATTERNS,
|
||||||
|
window.DIMA_TECHNIQUES,
|
||||||
|
this.pageType
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initialize UIManager
|
||||||
|
this.uiManager = new window.UIManager(this.settings);
|
||||||
|
this.uiManager.setPageType(this.pageType);
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.log("Initialisation DIMA avec mots-clés améliorés...");
|
||||||
|
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
this.delayedInit();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.delayedInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delayedInit() {
|
||||||
|
setTimeout(() => {
|
||||||
|
try {
|
||||||
|
this.analyzeCurrentPage();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("DIMA: Erreur lors de l'analyse:", error);
|
||||||
|
}
|
||||||
|
}, this.settings.analysisDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
log(message, data = null) {
|
||||||
|
if (this.settings.debugMode) {
|
||||||
|
console.log(`DIMA: ${message}`, data || "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeCurrentPage() {
|
||||||
|
try {
|
||||||
|
this.log("Analyse de la page...");
|
||||||
|
|
||||||
|
const cacheKey = window.location.href + document.title;
|
||||||
|
if (this.cache.has(cacheKey)) {
|
||||||
|
this.analysisResults = this.cache.get(cacheKey);
|
||||||
|
this.uiManager.createButton(this.analysisResults);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = this.contentExtractor.extractTitle();
|
||||||
|
const content = this.contentExtractor.extractContent();
|
||||||
|
|
||||||
|
this.log("Titre extrait:", title);
|
||||||
|
this.log("Contenu extrait:", `${content.length} caractères`);
|
||||||
|
|
||||||
|
this.analysisResults = this.techniqueAnalyzer.performAnalysis(
|
||||||
|
title,
|
||||||
|
content
|
||||||
|
);
|
||||||
|
this.cache.set(cacheKey, this.analysisResults);
|
||||||
|
|
||||||
|
this.log("Analyse terminée, score:", this.analysisResults.globalScore);
|
||||||
|
this.uiManager.createButton(this.analysisResults);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("DIMA: Erreur dans analyzeCurrentPage:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== INITIALISATION ET STYLES =====
|
||||||
|
|
||||||
|
// CSS pour les animations
|
||||||
|
const style = document.createElement("style");
|
||||||
|
style.textContent = `
|
||||||
|
@keyframes dimaFadeIn {
|
||||||
|
from { opacity: 0; transform: scale(0.9); }
|
||||||
|
to { opacity: 1; transform: scale(1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#dima-btn {
|
||||||
|
animation: dimaFadeIn 0.5s ease-out;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
|
||||||
|
// Initialisation sécurisée avec gestion d'erreurs améliorée
|
||||||
|
console.log("DIMA: Script chargé - Version complète avec mots-clés améliorés");
|
||||||
|
|
||||||
|
// Vérifier que toutes les dépendances sont chargées
|
||||||
|
function checkDependencies() {
|
||||||
|
return (
|
||||||
|
window.DIMA_TECHNIQUES &&
|
||||||
|
window.DIMA_ENHANCED_KEYWORDS &&
|
||||||
|
window.CONTEXT_PATTERNS &&
|
||||||
|
window.ContentExtractor &&
|
||||||
|
window.TechniqueAnalyzer &&
|
||||||
|
window.UIManager
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialiser avec retry si nécessaire
|
||||||
|
function initializeDIMA() {
|
||||||
|
if (!checkDependencies()) {
|
||||||
|
console.log("DIMA: Attente du chargement des dépendances...");
|
||||||
|
setTimeout(initializeDIMA, 100);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const analyzer = new DIMAAnalyzer();
|
||||||
|
console.log(
|
||||||
|
`DIMA: Analyseur initialisé pour page de type: ${analyzer.pageType}`
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("DIMA: Erreur d'initialisation critique:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Démarrer l'initialisation
|
||||||
|
initializeDIMA();
|
||||||
34
static/files/Plugin-dima-V1/manifest.json
Обычный файл
34
static/files/Plugin-dima-V1/manifest.json
Обычный файл
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"manifest_version": 3,
|
||||||
|
"name": "Analyseur DIMA - M82 Project",
|
||||||
|
"version": "1.1",
|
||||||
|
"description": "Plugin d'analyse de manipulation cognitive selon la matrice DIMA par M82 Project",
|
||||||
|
"permissions": ["activeTab", "storage"],
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": ["<all_urls>"],
|
||||||
|
"js": [
|
||||||
|
"data/techniques.js",
|
||||||
|
"data/keywords.js",
|
||||||
|
"modules/contentExtractor.js",
|
||||||
|
"modules/techniqueAnalyzer.js",
|
||||||
|
"modules/uiManager.js",
|
||||||
|
"content.js"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"action": {
|
||||||
|
"default_title": "Analyse DIMA - M82 Project"
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"16": "M82-logo-16.png",
|
||||||
|
"48": "M82-logo-48.png",
|
||||||
|
"128": "M82-logo-128.png"
|
||||||
|
},
|
||||||
|
"web_accessible_resources": [
|
||||||
|
{
|
||||||
|
"resources": ["M82-logo-16.png"],
|
||||||
|
"matches": ["<all_urls>"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
184
static/files/Plugin-dima-V1/modules/contentExtractor.js
Обычный файл
184
static/files/Plugin-dima-V1/modules/contentExtractor.js
Обычный файл
@ -0,0 +1,184 @@
|
|||||||
|
// Content Extractor Module
|
||||||
|
// Responsible for extracting and cleaning content from web pages
|
||||||
|
|
||||||
|
class ContentExtractor {
|
||||||
|
constructor(settings) {
|
||||||
|
this.settings = settings || {
|
||||||
|
maxContentLength: 5000,
|
||||||
|
minKeywordLength: 3,
|
||||||
|
debugMode: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
log(message, data = null) {
|
||||||
|
if (this.settings.debugMode) {
|
||||||
|
console.log(`ContentExtractor: ${message}`, data || "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extractTitle() {
|
||||||
|
const titleSources = [
|
||||||
|
() => document.title,
|
||||||
|
() => document.querySelector('meta[property="og:title"]')?.content,
|
||||||
|
() => document.querySelector('meta[name="twitter:title"]')?.content,
|
||||||
|
() => document.querySelector("h1")?.textContent?.trim(),
|
||||||
|
() =>
|
||||||
|
document
|
||||||
|
.querySelector('.title, .headline, [class*="title"]')
|
||||||
|
?.textContent?.trim(),
|
||||||
|
];
|
||||||
|
|
||||||
|
return titleSources
|
||||||
|
.map((fn) => fn())
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(" ")
|
||||||
|
.substring(0, 500)
|
||||||
|
.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
extractContent() {
|
||||||
|
this.log("Début extraction de contenu...");
|
||||||
|
|
||||||
|
const extractedTexts = new Set();
|
||||||
|
let content = "";
|
||||||
|
|
||||||
|
// Sélecteurs prioritaires pour le contenu principal
|
||||||
|
const contentSelectors = [
|
||||||
|
"article",
|
||||||
|
'[role="main"]',
|
||||||
|
"main",
|
||||||
|
".article-content, .post-content, .entry-content",
|
||||||
|
".content, .story-body, .article-body",
|
||||||
|
"#article-body, .post-body, .text-content",
|
||||||
|
];
|
||||||
|
|
||||||
|
// Extraction du contenu principal
|
||||||
|
for (const selector of contentSelectors) {
|
||||||
|
const elements = document.querySelectorAll(selector);
|
||||||
|
if (elements.length > 0) {
|
||||||
|
this.log(`Contenu trouvé avec: ${selector}`);
|
||||||
|
content += this.extractTextFromElements(elements, extractedTexts);
|
||||||
|
if (content.length > 1000) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback si contenu insuffisant
|
||||||
|
if (content.length < 300) {
|
||||||
|
this.log("Contenu insuffisant, utilisation de fallbacks...");
|
||||||
|
const fallbackSelectors = [
|
||||||
|
"p, h1, h2, h3, h4, h5, h6",
|
||||||
|
".text, .description, .summary",
|
||||||
|
'[class*="content"], [class*="text"]',
|
||||||
|
"blockquote, figcaption",
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const selector of fallbackSelectors) {
|
||||||
|
const elements = document.querySelectorAll(selector);
|
||||||
|
content += this.extractTextFromElements(elements, extractedTexts, 30);
|
||||||
|
if (content.length > 1500) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dernier recours
|
||||||
|
if (content.length < 200) {
|
||||||
|
this.log("Dernier recours - texte visible");
|
||||||
|
const bodyText = this.cleanText(document.body.innerText);
|
||||||
|
content = bodyText.substring(0, this.settings.maxContentLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalContent = content
|
||||||
|
.substring(0, this.settings.maxContentLength)
|
||||||
|
.trim();
|
||||||
|
this.log(`Extraction terminée: ${finalContent.length} caractères`);
|
||||||
|
|
||||||
|
return finalContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
extractTextFromElements(elements, extractedTexts, maxElements = 100) {
|
||||||
|
let text = "";
|
||||||
|
const elementsArray = Array.from(elements).slice(0, maxElements);
|
||||||
|
|
||||||
|
for (const element of elementsArray) {
|
||||||
|
if (this.shouldSkipElement(element)) continue;
|
||||||
|
|
||||||
|
const elementText = this.cleanText(
|
||||||
|
element.textContent || element.innerText
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
elementText &&
|
||||||
|
elementText.length > 15 &&
|
||||||
|
!extractedTexts.has(elementText)
|
||||||
|
) {
|
||||||
|
extractedTexts.add(elementText);
|
||||||
|
text += elementText + " ";
|
||||||
|
|
||||||
|
if (text.length > this.settings.maxContentLength) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldSkipElement(element) {
|
||||||
|
const skipClasses = [
|
||||||
|
"nav",
|
||||||
|
"menu",
|
||||||
|
"footer",
|
||||||
|
"header",
|
||||||
|
"sidebar",
|
||||||
|
"ad",
|
||||||
|
"advertisement",
|
||||||
|
"social",
|
||||||
|
"share",
|
||||||
|
];
|
||||||
|
const skipIds = ["nav", "menu", "footer", "header", "sidebar", "comments"];
|
||||||
|
|
||||||
|
const className = element.className?.toLowerCase() || "";
|
||||||
|
const id = element.id?.toLowerCase() || "";
|
||||||
|
|
||||||
|
return (
|
||||||
|
skipClasses.some((skip) => className.includes(skip)) ||
|
||||||
|
skipIds.some((skip) => id.includes(skip)) ||
|
||||||
|
element.getAttribute("aria-hidden") === "true" ||
|
||||||
|
getComputedStyle(element).display === "none"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanText(text) {
|
||||||
|
if (!text) return "";
|
||||||
|
|
||||||
|
return text
|
||||||
|
.replace(/\s+/g, " ")
|
||||||
|
.replace(/[\r\n\t]/g, " ")
|
||||||
|
.replace(/[^\w\s\.,!?;:()\-'"%àâäéèêëïîôöùûüÿç]/gi, "")
|
||||||
|
.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
detectPageType() {
|
||||||
|
const url = window.location.href.toLowerCase();
|
||||||
|
if (
|
||||||
|
url.includes("news") ||
|
||||||
|
url.includes("article") ||
|
||||||
|
url.includes("actualit")
|
||||||
|
)
|
||||||
|
return "news";
|
||||||
|
if (url.includes("blog")) return "blog";
|
||||||
|
if (
|
||||||
|
url.includes("facebook") ||
|
||||||
|
url.includes("twitter") ||
|
||||||
|
url.includes("instagram")
|
||||||
|
)
|
||||||
|
return "social";
|
||||||
|
if (
|
||||||
|
url.includes("shop") ||
|
||||||
|
url.includes("buy") ||
|
||||||
|
url.includes("product") ||
|
||||||
|
url.includes("commerce")
|
||||||
|
)
|
||||||
|
return "commerce";
|
||||||
|
return "general";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make ContentExtractor available globally for Chrome extension
|
||||||
|
window.ContentExtractor = ContentExtractor;
|
||||||
473
static/files/Plugin-dima-V1/modules/techniqueAnalyzer.js
Обычный файл
473
static/files/Plugin-dima-V1/modules/techniqueAnalyzer.js
Обычный файл
@ -0,0 +1,473 @@
|
|||||||
|
// Technique Analyzer Module
|
||||||
|
// Responsible for analyzing manipulation techniques in text
|
||||||
|
|
||||||
|
class TechniqueAnalyzer {
|
||||||
|
constructor(
|
||||||
|
settings,
|
||||||
|
enhancedKeywords,
|
||||||
|
contextPatterns,
|
||||||
|
techniques,
|
||||||
|
pageType = "general"
|
||||||
|
) {
|
||||||
|
this.settings = settings || {
|
||||||
|
enhancedKeywords: true,
|
||||||
|
minKeywordLength: 3,
|
||||||
|
debugMode: false,
|
||||||
|
};
|
||||||
|
this.enhancedKeywords = enhancedKeywords;
|
||||||
|
this.contextPatterns = contextPatterns;
|
||||||
|
this.techniques = techniques;
|
||||||
|
this.pageType = pageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(message, data = null) {
|
||||||
|
if (this.settings.debugMode) {
|
||||||
|
console.log(`TechniqueAnalyzer: ${message}`, data || "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
performAnalysis(title, content) {
|
||||||
|
const fullText = (title + " " + content).toLowerCase();
|
||||||
|
const detected = [];
|
||||||
|
let totalScore = 0;
|
||||||
|
const phaseScores = {};
|
||||||
|
|
||||||
|
this.log("Analyse du texte...", fullText.substring(0, 200));
|
||||||
|
|
||||||
|
// Analyser SEULEMENT les techniques (TE), pas les tactiques (TA)
|
||||||
|
const techniques = this.techniques.filter(
|
||||||
|
(item) => item.type === "technique"
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const technique of techniques) {
|
||||||
|
const analysis = this.analyzeTechnique(technique, fullText);
|
||||||
|
|
||||||
|
if (analysis.score > 0) {
|
||||||
|
detected.push(analysis);
|
||||||
|
totalScore += analysis.weightedScore;
|
||||||
|
|
||||||
|
// Calcul par phase
|
||||||
|
if (!phaseScores[technique.phase]) {
|
||||||
|
phaseScores[technique.phase] = 0;
|
||||||
|
}
|
||||||
|
phaseScores[technique.phase] += analysis.weightedScore;
|
||||||
|
|
||||||
|
this.log(`Technique détectée: ${technique.index} (${analysis.score})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Score global avec normalisation améliorée
|
||||||
|
const globalScore = Math.min(Math.round(totalScore * 3), 100);
|
||||||
|
|
||||||
|
return {
|
||||||
|
globalScore,
|
||||||
|
detectedTechniques: detected.sort(
|
||||||
|
(a, b) => b.weightedScore - a.weightedScore
|
||||||
|
),
|
||||||
|
phaseScores,
|
||||||
|
riskLevel: this.calculateRiskLevel(globalScore),
|
||||||
|
riskColor: this.getColor(globalScore),
|
||||||
|
url: window.location.href,
|
||||||
|
title: title.substring(0, 200),
|
||||||
|
contentLength: content.length,
|
||||||
|
analyzedText: fullText.length,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeTechnique(technique, fullText) {
|
||||||
|
// Utiliser le système amélioré si disponible et activé
|
||||||
|
if (
|
||||||
|
this.settings.enhancedKeywords &&
|
||||||
|
this.enhancedKeywords[technique.index]
|
||||||
|
) {
|
||||||
|
return this.analyzeEnhancedTechnique(technique, fullText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback vers l'ancienne méthode
|
||||||
|
return this.analyzeBasicTechnique(technique, fullText);
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeEnhancedTechnique(technique, fullText) {
|
||||||
|
const enhancedData = this.enhancedKeywords[technique.index];
|
||||||
|
const results = {
|
||||||
|
matches: [],
|
||||||
|
score: 0,
|
||||||
|
contextBoosts: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
// 1. Analyse des mots-clés de base
|
||||||
|
if (enhancedData.core) {
|
||||||
|
const coreMatches = this.findKeywordMatches(
|
||||||
|
fullText,
|
||||||
|
enhancedData.core,
|
||||||
|
1.0
|
||||||
|
);
|
||||||
|
results.matches.push(...coreMatches);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Analyse des variantes
|
||||||
|
if (enhancedData.variants) {
|
||||||
|
for (const [category, variants] of Object.entries(
|
||||||
|
enhancedData.variants
|
||||||
|
)) {
|
||||||
|
if (Array.isArray(variants)) {
|
||||||
|
const weight = this.getVariantWeight(category);
|
||||||
|
const variantMatches = this.findKeywordMatches(
|
||||||
|
fullText,
|
||||||
|
variants,
|
||||||
|
weight
|
||||||
|
);
|
||||||
|
results.matches.push(
|
||||||
|
...variantMatches.map((m) => ({ ...m, category }))
|
||||||
|
);
|
||||||
|
} else if (typeof variants === "object") {
|
||||||
|
// Variantes avec sous-catégories (ex: intensity.strong)
|
||||||
|
for (const [subcat, subvariants] of Object.entries(variants)) {
|
||||||
|
const weight = this.getIntensityWeight(subcat);
|
||||||
|
const subMatches = this.findKeywordMatches(
|
||||||
|
fullText,
|
||||||
|
subvariants,
|
||||||
|
weight
|
||||||
|
);
|
||||||
|
results.matches.push(
|
||||||
|
...subMatches.map((m) => ({
|
||||||
|
...m,
|
||||||
|
category: `${category}.${subcat}`,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Analyse des patterns regex
|
||||||
|
if (enhancedData.patterns) {
|
||||||
|
for (const pattern of enhancedData.patterns) {
|
||||||
|
const patternMatches = this.findPatternMatches(fullText, pattern);
|
||||||
|
results.matches.push(...patternMatches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Analyse contextuelle
|
||||||
|
const contextBoosts = this.analyzeContext(fullText, technique.index);
|
||||||
|
results.contextBoosts = contextBoosts;
|
||||||
|
|
||||||
|
// 5. Calcul du score
|
||||||
|
results.score = results.matches.reduce(
|
||||||
|
(sum, match) => sum + match.weight,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
// 6. Application des boosts contextuels
|
||||||
|
let finalScore = results.score;
|
||||||
|
for (const boost of contextBoosts) {
|
||||||
|
finalScore *= boost.boost;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. Pondération contextuelle et dynamique
|
||||||
|
let contextualWeight = this.calculateContextualWeight(
|
||||||
|
technique,
|
||||||
|
this.pageType
|
||||||
|
);
|
||||||
|
let dynamicWeight = this.calculateDynamicWeight(technique, finalScore);
|
||||||
|
|
||||||
|
const totalWeight =
|
||||||
|
(technique.weight || 1.0) * contextualWeight * dynamicWeight;
|
||||||
|
const weightedScore = finalScore * totalWeight;
|
||||||
|
|
||||||
|
const confidence = Math.min(
|
||||||
|
Math.round(results.score * 15 + results.matches.length * 10),
|
||||||
|
100
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
index: technique.index,
|
||||||
|
nom: technique.nom,
|
||||||
|
phase: technique.phase,
|
||||||
|
description: technique.description || "",
|
||||||
|
score: Math.round(finalScore),
|
||||||
|
weightedScore,
|
||||||
|
finalWeight: totalWeight,
|
||||||
|
contextualWeight,
|
||||||
|
dynamicWeight,
|
||||||
|
confidence,
|
||||||
|
matchedKeywords: this.formatEnhancedMatches(results.matches),
|
||||||
|
enhancedAnalysis: {
|
||||||
|
coreMatches: results.matches.filter((m) => m.type === "core").length,
|
||||||
|
variantMatches: results.matches.filter((m) => m.type === "variant")
|
||||||
|
.length,
|
||||||
|
patternMatches: results.matches.filter((m) => m.type === "pattern")
|
||||||
|
.length,
|
||||||
|
contextBoosts: results.contextBoosts,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeBasicTechnique(technique, fullText) {
|
||||||
|
let score = 0;
|
||||||
|
const matchedKeywords = [];
|
||||||
|
|
||||||
|
for (const keyword of technique.mots_cles) {
|
||||||
|
if (keyword.length < this.settings.minKeywordLength) continue;
|
||||||
|
|
||||||
|
const keywordLower = keyword.toLowerCase();
|
||||||
|
const matches = this.findKeywordMatches(fullText, [keywordLower], 1.0);
|
||||||
|
|
||||||
|
if (matches.length > 0) {
|
||||||
|
score += matches.length;
|
||||||
|
matchedKeywords.push({
|
||||||
|
keyword,
|
||||||
|
count: matches.length,
|
||||||
|
type: "basic",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pondération contextuelle et dynamique
|
||||||
|
let contextualWeight = this.calculateContextualWeight(
|
||||||
|
technique,
|
||||||
|
this.pageType
|
||||||
|
);
|
||||||
|
let dynamicWeight = this.calculateDynamicWeight(technique, score);
|
||||||
|
|
||||||
|
const finalWeight =
|
||||||
|
(technique.weight || 1.0) * contextualWeight * dynamicWeight;
|
||||||
|
const weightedScore = score * finalWeight;
|
||||||
|
|
||||||
|
const confidence = Math.min(
|
||||||
|
Math.round(score * 15 + weightedScore * 5),
|
||||||
|
100
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
index: technique.index,
|
||||||
|
nom: technique.nom,
|
||||||
|
phase: technique.phase,
|
||||||
|
description: technique.description || "",
|
||||||
|
score,
|
||||||
|
weightedScore,
|
||||||
|
finalWeight,
|
||||||
|
contextualWeight,
|
||||||
|
dynamicWeight,
|
||||||
|
confidence,
|
||||||
|
matchedKeywords,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
findKeywordMatches(text, keywords, weight = 1.0) {
|
||||||
|
const matches = [];
|
||||||
|
|
||||||
|
for (const keyword of keywords) {
|
||||||
|
const keywordLower = keyword.toLowerCase();
|
||||||
|
let regex;
|
||||||
|
|
||||||
|
if (keywordLower.includes(" ")) {
|
||||||
|
// Expression avec espaces
|
||||||
|
regex = new RegExp(this.escapeRegex(keywordLower), "gi");
|
||||||
|
} else {
|
||||||
|
// Mot simple avec frontières
|
||||||
|
regex = new RegExp(
|
||||||
|
"\\b" + this.escapeRegex(keywordLower) + "\\b",
|
||||||
|
"gi"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let match;
|
||||||
|
while ((match = regex.exec(text)) !== null) {
|
||||||
|
matches.push({
|
||||||
|
type: "core",
|
||||||
|
keyword: keyword,
|
||||||
|
position: match.index,
|
||||||
|
weight: weight,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
findPatternMatches(text, pattern) {
|
||||||
|
const matches = [];
|
||||||
|
let match;
|
||||||
|
|
||||||
|
// Réinitialiser le regex pour éviter les problèmes de state
|
||||||
|
pattern.lastIndex = 0;
|
||||||
|
|
||||||
|
while ((match = pattern.exec(text)) !== null) {
|
||||||
|
matches.push({
|
||||||
|
type: "pattern",
|
||||||
|
keyword: match[0],
|
||||||
|
position: match.index,
|
||||||
|
weight: 1.5, // Les patterns ont un poids plus élevé
|
||||||
|
});
|
||||||
|
|
||||||
|
// Éviter les boucles infinies
|
||||||
|
if (!pattern.global) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeContext(text, techniqueId) {
|
||||||
|
const boosts = [];
|
||||||
|
|
||||||
|
for (const [contextType, contextData] of Object.entries(
|
||||||
|
this.contextPatterns
|
||||||
|
)) {
|
||||||
|
if (contextData.techniques.includes(techniqueId)) {
|
||||||
|
for (const pattern of contextData.patterns) {
|
||||||
|
if (pattern.test(text)) {
|
||||||
|
boosts.push({
|
||||||
|
type: contextType,
|
||||||
|
boost: contextData.boost,
|
||||||
|
pattern: pattern.source,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return boosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
getVariantWeight(category) {
|
||||||
|
const weights = {
|
||||||
|
formal: 0.9,
|
||||||
|
informal: 1.1,
|
||||||
|
clickbait_formulas: 1.6,
|
||||||
|
emotional_hooks: 1.4,
|
||||||
|
curiosity_gaps: 1.5,
|
||||||
|
urgency: 1.3,
|
||||||
|
scarcity: 1.4,
|
||||||
|
temporal: 1.2,
|
||||||
|
};
|
||||||
|
return weights[category] || 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
getIntensityWeight(intensity) {
|
||||||
|
const weights = {
|
||||||
|
weak: 0.7,
|
||||||
|
strong: 1.5,
|
||||||
|
};
|
||||||
|
return weights[intensity] || 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
formatEnhancedMatches(matches) {
|
||||||
|
const grouped = {};
|
||||||
|
|
||||||
|
for (const match of matches) {
|
||||||
|
const key = match.keyword;
|
||||||
|
if (!grouped[key]) {
|
||||||
|
grouped[key] = {
|
||||||
|
keyword: key,
|
||||||
|
count: 0,
|
||||||
|
type: match.type,
|
||||||
|
category: match.category,
|
||||||
|
totalWeight: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
grouped[key].count++;
|
||||||
|
grouped[key].totalWeight += match.weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.values(grouped);
|
||||||
|
}
|
||||||
|
|
||||||
|
escapeRegex(string) {
|
||||||
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateRiskLevel(score) {
|
||||||
|
if (score < 15) return "Faible";
|
||||||
|
if (score < 30) return "Modéré";
|
||||||
|
if (score < 50) return "Élevé";
|
||||||
|
if (score < 75) return "Très Élevé";
|
||||||
|
return "Critique";
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateContextualWeight(technique, pageType) {
|
||||||
|
let contextualWeight = 1.0;
|
||||||
|
|
||||||
|
switch (pageType) {
|
||||||
|
case "news":
|
||||||
|
if (technique.index === "TE0500") contextualWeight = 1.4;
|
||||||
|
if (technique.index === "TE0132") contextualWeight = 1.3;
|
||||||
|
if (technique.index === "TE0221") contextualWeight = 1.5;
|
||||||
|
if (technique.index === "TE0212") contextualWeight = 1.3;
|
||||||
|
if (technique.index === "TE0261") contextualWeight = 0.8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "social":
|
||||||
|
if (technique.index === "TE0132") contextualWeight = 0.9;
|
||||||
|
if (technique.index === "TE0131") contextualWeight = 0.8;
|
||||||
|
if (technique.index === "TE0501") contextualWeight = 1.3;
|
||||||
|
if (technique.index === "TE0221") contextualWeight = 1.6;
|
||||||
|
if (technique.index === "TE0251") contextualWeight = 1.2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "commerce":
|
||||||
|
if (technique.index === "TE0501") contextualWeight = 0.9;
|
||||||
|
if (technique.index === "TE0141") contextualWeight = 0.8;
|
||||||
|
if (technique.index === "TE0143") contextualWeight = 0.7;
|
||||||
|
if (technique.index === "TE0422") contextualWeight = 1.2;
|
||||||
|
if (technique.index === "TE0411") contextualWeight = 1.1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "blog":
|
||||||
|
if (technique.index === "TE0212") contextualWeight = 0.8;
|
||||||
|
if (technique.index === "TE0314") contextualWeight = 0.9;
|
||||||
|
if (technique.index === "TE0261") contextualWeight = 0.7;
|
||||||
|
if (technique.index === "TE0321") contextualWeight = 1.1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log(
|
||||||
|
`Poids contextuel pour ${technique.index} sur ${pageType}: ${contextualWeight}`
|
||||||
|
);
|
||||||
|
return contextualWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateDynamicWeight(technique, occurrences) {
|
||||||
|
let dynamicWeight = 1.0;
|
||||||
|
|
||||||
|
// Plus une technique apparaît, plus elle devient suspecte
|
||||||
|
if (occurrences >= 10) {
|
||||||
|
dynamicWeight = 1.4;
|
||||||
|
} else if (occurrences >= 7) {
|
||||||
|
dynamicWeight = 1.3;
|
||||||
|
} else if (occurrences >= 5) {
|
||||||
|
dynamicWeight = 1.2;
|
||||||
|
} else if (occurrences >= 3) {
|
||||||
|
dynamicWeight = 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cas spéciaux : certaines techniques sont plus graves même avec peu d'occurrences
|
||||||
|
const criticalTechniques = ["TE0221", "TE0500", "TE0132", "TE0501"];
|
||||||
|
if (criticalTechniques.includes(technique.index) && occurrences >= 2) {
|
||||||
|
dynamicWeight *= 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Réduire le poids si technique très fréquente mais bénigne
|
||||||
|
const benignTechniques = ["TE0143", "TE0232", "TE0333"];
|
||||||
|
if (benignTechniques.includes(technique.index) && occurrences >= 5) {
|
||||||
|
dynamicWeight *= 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log(
|
||||||
|
`Poids dynamique pour ${technique.index} (${occurrences} occ.): ${dynamicWeight}`
|
||||||
|
);
|
||||||
|
return dynamicWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
getColor(score) {
|
||||||
|
if (score < 15) return "#27ae60"; // Vert
|
||||||
|
if (score < 30) return "#f39c12"; // Orange clair
|
||||||
|
if (score < 50) return "#e67e22"; // Orange
|
||||||
|
if (score < 75) return "#d35400"; // Rouge-orange
|
||||||
|
return "#c0392b"; // Rouge foncé
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make TechniqueAnalyzer available globally for Chrome extension
|
||||||
|
window.TechniqueAnalyzer = TechniqueAnalyzer;
|
||||||
290
static/files/Plugin-dima-V1/modules/uiManager.js
Обычный файл
290
static/files/Plugin-dima-V1/modules/uiManager.js
Обычный файл
@ -0,0 +1,290 @@
|
|||||||
|
// UI Manager Module
|
||||||
|
// Responsible for creating and managing the user interface elements
|
||||||
|
|
||||||
|
class UIManager {
|
||||||
|
constructor(settings) {
|
||||||
|
this.settings = settings || {
|
||||||
|
debugMode: false,
|
||||||
|
};
|
||||||
|
this.buttonCreated = false;
|
||||||
|
this.analysisResults = null;
|
||||||
|
this.pageType = 'general';
|
||||||
|
}
|
||||||
|
|
||||||
|
log(message, data = null) {
|
||||||
|
if (this.settings.debugMode) {
|
||||||
|
console.log(`UIManager: ${message}`, data || "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setPageType(pageType) {
|
||||||
|
this.pageType = pageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
createButton(analysisResults = null) {
|
||||||
|
if (analysisResults) {
|
||||||
|
this.analysisResults = analysisResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.analysisResults) {
|
||||||
|
console.error('DIMA: Aucun résultat d\'analyse disponible pour créer le bouton');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// Supprimer bouton existant
|
||||||
|
document.getElementById('dima-btn')?.remove();
|
||||||
|
|
||||||
|
if (this.buttonCreated) return;
|
||||||
|
|
||||||
|
const button = document.createElement('div');
|
||||||
|
button.id = 'dima-btn';
|
||||||
|
|
||||||
|
button.innerHTML = `
|
||||||
|
<div style="display: flex; align-items: center; gap: 8px;">
|
||||||
|
🧠
|
||||||
|
<span style="font-weight: bold;">${this.analysisResults.globalScore}</span>
|
||||||
|
<span style="font-size: 0.8em; opacity: 0.9;">${this.analysisResults.riskLevel}</span>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
button.style.cssText = `
|
||||||
|
position: fixed !important;
|
||||||
|
top: 20px !important;
|
||||||
|
right: 20px !important;
|
||||||
|
z-index: 999999 !important;
|
||||||
|
background: linear-gradient(135deg, ${this.analysisResults.riskColor}, ${this.adjustColor(this.analysisResults.riskColor, -20)}) !important;
|
||||||
|
color: white !important;
|
||||||
|
padding: 12px 16px !important;
|
||||||
|
border-radius: 25px !important;
|
||||||
|
cursor: pointer !important;
|
||||||
|
font-family: 'Segoe UI', Arial, sans-serif !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
box-shadow: 0 4px 15px rgba(0,0,0,0.2), 0 2px 5px rgba(0,0,0,0.1) !important;
|
||||||
|
border: 2px solid rgba(255,255,255,0.2) !important;
|
||||||
|
user-select: none !important;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
||||||
|
backdrop-filter: blur(10px) !important;
|
||||||
|
`;
|
||||||
|
|
||||||
|
button.title = this.generateTooltip();
|
||||||
|
|
||||||
|
// Événements
|
||||||
|
button.addEventListener('click', () => this.showModal());
|
||||||
|
button.addEventListener('mouseenter', () => {
|
||||||
|
button.style.transform = 'scale(1.05) translateY(-2px)';
|
||||||
|
button.style.boxShadow = '0 6px 20px rgba(0,0,0,0.3), 0 4px 8px rgba(0,0,0,0.2)';
|
||||||
|
});
|
||||||
|
button.addEventListener('mouseleave', () => {
|
||||||
|
button.style.transform = 'scale(1) translateY(0)';
|
||||||
|
button.style.boxShadow = '0 4px 15px rgba(0,0,0,0.2), 0 2px 5px rgba(0,0,0,0.1)';
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body?.appendChild(button);
|
||||||
|
this.buttonCreated = true;
|
||||||
|
this.log('Bouton créé avec succès');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('DIMA: Erreur création bouton:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustColor(color, amount) {
|
||||||
|
const num = parseInt(color.replace("#", ""), 16);
|
||||||
|
const amt = Math.round(2.55 * amount);
|
||||||
|
const R = (num >> 16) + amt;
|
||||||
|
const G = (num >> 8 & 0x00FF) + amt;
|
||||||
|
const B = (num & 0x0000FF) + amt;
|
||||||
|
return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +
|
||||||
|
(G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +
|
||||||
|
(B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
generateTooltip() {
|
||||||
|
const techniques = this.analysisResults.detectedTechniques.slice(0, 3);
|
||||||
|
return `DIMA Score: ${this.analysisResults.globalScore} (${this.analysisResults.riskLevel})
|
||||||
|
${this.analysisResults.detectedTechniques.length} techniques détectées
|
||||||
|
${techniques.map(t => `• ${t.nom}`).join('\n')}
|
||||||
|
Contenu: ${this.analysisResults.contentLength} caractères`;
|
||||||
|
}
|
||||||
|
|
||||||
|
showModal() {
|
||||||
|
try {
|
||||||
|
this.log('Affichage du modal');
|
||||||
|
|
||||||
|
document.getElementById('dima-modal')?.remove();
|
||||||
|
|
||||||
|
const modal = document.createElement('div');
|
||||||
|
modal.id = 'dima-modal';
|
||||||
|
|
||||||
|
modal.style.cssText = `
|
||||||
|
position: fixed !important;
|
||||||
|
top: 0 !important;
|
||||||
|
left: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
background: rgba(0,0,0,0.75) !important;
|
||||||
|
backdrop-filter: blur(5px) !important;
|
||||||
|
z-index: 9999999 !important;
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
font-family: 'Segoe UI', Arial, sans-serif !important;
|
||||||
|
animation: fadeIn 0.3s ease-out !important;
|
||||||
|
`;
|
||||||
|
// Récupérer l'URL du logo
|
||||||
|
const logoUrl = chrome.runtime.getURL('M82-logo-16.png');
|
||||||
|
|
||||||
|
modal.innerHTML = `
|
||||||
|
<div style="background: white; padding: 30px; border-radius: 20px; max-width: 900px; max-height: 90vh; overflow-y: auto; margin: 20px; box-shadow: 0 25px 50px rgba(0,0,0,0.3); animation: slideIn 0.3s ease-out;">
|
||||||
|
|
||||||
|
<!-- En-tête -->
|
||||||
|
<div style="text-align: center; margin-bottom: 25px; padding-bottom: 20px; border-bottom: 2px solid #f0f0f0;">
|
||||||
|
<div style="display: flex; align-items: center; justify-content: center; gap: 12px; margin-bottom: 10px;">
|
||||||
|
<img src="${logoUrl}"
|
||||||
|
style="width: 24px; height: 24px;"
|
||||||
|
alt="M82 Project"
|
||||||
|
onerror="this.style.display='none'">
|
||||||
|
<h2 style="color: #2c3e50; margin: 0; font-size: 1.8em;">Analyse DIMA</h2>
|
||||||
|
</div>
|
||||||
|
<p style="color: #7f8c8d; margin: 0; font-size: 0.95em;">
|
||||||
|
Détection de techniques de manipulation cognitive par
|
||||||
|
<a href="https://m82-project.org/" target="_blank"
|
||||||
|
style="color: #3498db; text-decoration: none; font-weight: 500;">M82 Project</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Métriques principales -->
|
||||||
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 15px; margin-bottom: 25px;">
|
||||||
|
<div style="background: linear-gradient(135deg, ${this.analysisResults.riskColor}, ${this.adjustColor(this.analysisResults.riskColor, -15)}); color: white; padding: 20px; border-radius: 12px; text-align: center; box-shadow: 0 4px 15px rgba(0,0,0,0.1);">
|
||||||
|
<div style="font-size: 2.2em; font-weight: bold; margin-bottom: 5px;">${this.analysisResults.globalScore}</div>
|
||||||
|
<div style="font-size: 0.9em; opacity: 0.9;">Score Global</div>
|
||||||
|
</div>
|
||||||
|
<div style="background: #f8f9fa; padding: 20px; border-radius: 12px; text-align: center; border: 1px solid #e9ecef;">
|
||||||
|
<div style="font-size: 2.2em; font-weight: bold; color: #3498db; margin-bottom: 5px;">${this.analysisResults.detectedTechniques.length}</div>
|
||||||
|
<div style="color: #7f8c8d; font-size: 0.9em;">Techniques</div>
|
||||||
|
</div>
|
||||||
|
<div style="background: #f8f9fa; padding: 20px; border-radius: 12px; text-align: center; border: 1px solid #e9ecef;">
|
||||||
|
<div style="font-size: 1.4em; font-weight: bold; color: ${this.analysisResults.riskColor}; margin-bottom: 5px;">${this.analysisResults.riskLevel}</div>
|
||||||
|
<div style="color: #7f8c8d; font-size: 0.9em;">Niveau Risque</div>
|
||||||
|
</div>
|
||||||
|
<div style="background: #f8f9fa; padding: 20px; border-radius: 12px; text-align: center; border: 1px solid #e9ecef;">
|
||||||
|
<div style="font-size: 1.6em; font-weight: bold; color: #17a2b8; margin-bottom: 5px;">${this.analysisResults.contentLength}</div>
|
||||||
|
<div style="color: #7f8c8d; font-size: 0.9em;">Caractères</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Informations sur la page -->
|
||||||
|
<div style="background: #f8f9fa; padding: 20px; border-radius: 12px; margin-bottom: 25px; border: 1px solid #e9ecef;">
|
||||||
|
<h4 style="margin: 0 0 10px 0; color: #2c3e50; font-size: 1.1em;">📄 Page analysée</h4>
|
||||||
|
<div style="font-weight: 500; margin-bottom: 8px; line-height: 1.4;">${this.analysisResults.title}</div>
|
||||||
|
<div style="color: #666; font-size: 0.9em; word-break: break-all; margin-bottom: 8px;">${this.analysisResults.url}</div>
|
||||||
|
<div style="color: #888; font-size: 0.85em;">
|
||||||
|
Analysé le ${new Date(this.analysisResults.timestamp).toLocaleString('fr-FR')} •
|
||||||
|
${this.analysisResults.analyzedText} caractères traités • Type: ${this.pageType}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Message si aucune technique -->
|
||||||
|
${this.analysisResults.detectedTechniques.length === 0 ? `
|
||||||
|
<div style="background: linear-gradient(135deg, #d4edda, #c3e6cb); color: #155724; padding: 25px; border-radius: 12px; text-align: center; border: 1px solid #c3e6cb;">
|
||||||
|
<div style="font-size: 2em; margin-bottom: 10px;">✅</div>
|
||||||
|
<div style="font-size: 1.2em; font-weight: bold; margin-bottom: 8px;">Aucune manipulation détectée</div>
|
||||||
|
<div style="font-size: 0.95em; opacity: 0.8;">Le contenu analysé semble exempt de techniques de manipulation cognitive manifestes</div>
|
||||||
|
</div>
|
||||||
|
` : `
|
||||||
|
<div style="background: linear-gradient(135deg, #fff3cd, #ffeaa7); padding: 20px; border-radius: 12px; border: 1px solid #ffeaa7;">
|
||||||
|
<h4 style="margin: 0 0 20px 0; color: #856404; font-size: 1.2em;">⚠️ Techniques de manipulation détectées</h4>
|
||||||
|
<div style="display: grid; gap: 12px;">
|
||||||
|
${this.analysisResults.detectedTechniques.slice(0, 8).map(technique => `
|
||||||
|
<div style="background: white; padding: 16px; border-radius: 10px; border-left: 4px solid #e67e22; box-shadow: 0 2px 8px rgba(0,0,0,0.08);">
|
||||||
|
<div style="display: flex; justify-content: between; align-items: start; margin-bottom: 8px;">
|
||||||
|
<div style="flex: 1;">
|
||||||
|
<div style="font-weight: bold; color: #2c3e50; margin-bottom: 4px; font-size: 1.05em;">
|
||||||
|
${technique.phase === 'Detect' ? '👁️' : technique.phase === 'Informer' ? '📢' : technique.phase === 'Mémoriser' ? '🧠' : '⚡'} ${technique.index}: ${technique.nom}
|
||||||
|
</div>
|
||||||
|
${technique.tactic ? `<div style="font-size: 0.75em; color: #7f8c8d; margin-bottom: 8px;">↳ Tactique: ${technique.tactic}</div>` : ''}
|
||||||
|
${technique.description ? `<div style="color: #666; font-size: 0.9em; margin-bottom: 8px; line-height: 1.4;">${technique.description}</div>` : ''}
|
||||||
|
</div>
|
||||||
|
<span style="background: #27ae60; color: white; padding: 4px 8px; border-radius: 12px; font-size: 0.8em; font-weight: bold; margin-left: 15px;">
|
||||||
|
${technique.confidence}%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display: flex; justify-content: between; align-items: center; margin-bottom: 8px;">
|
||||||
|
<span style="background: #e67e22; color: white; padding: 3px 8px; border-radius: 6px; font-size: 0.8em; font-weight: 500;">
|
||||||
|
${technique.phase}
|
||||||
|
</span>
|
||||||
|
<div style="text-align: right; font-size: 0.75em; color: #7f8c8d;">
|
||||||
|
<div>Score pondéré: ${technique.weightedScore?.toFixed(1) || technique.score}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
${technique.matchedKeywords?.length > 0 ? `
|
||||||
|
<div style="margin-top: 10px;">
|
||||||
|
<div style="font-size: 0.85em; color: #666; margin-bottom: 6px; font-weight: 500;">
|
||||||
|
🔍 Mots-clés détectés:
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; flex-wrap: wrap; gap: 4px;">
|
||||||
|
${technique.matchedKeywords.slice(0, 4).map(keyword =>
|
||||||
|
`<span style="background: #e9ecef; color: #495057; padding: 2px 6px; border-radius: 4px; font-size: 0.75em;">
|
||||||
|
${keyword.keyword} ${(keyword.count > 1) ? `(×${keyword.count})` : ''}
|
||||||
|
</span>`
|
||||||
|
).join('')}
|
||||||
|
${technique.matchedKeywords.length > 4 ?
|
||||||
|
`<span style="color: #999; font-size: 0.75em; padding: 2px 4px;">+${technique.matchedKeywords.length - 4} autres...</span>`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
</div>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`}
|
||||||
|
|
||||||
|
<!-- Actions -->
|
||||||
|
<div style="text-align: center; margin-top: 25px; padding-top: 20px; border-top: 1px solid #e9ecef;">
|
||||||
|
<div style="display: flex; gap: 15px; justify-content: center; flex-wrap: wrap;">
|
||||||
|
<button onclick="document.getElementById('dima-modal').remove()"
|
||||||
|
style="background: #3498db; color: white; border: none; padding: 12px 24px; border-radius: 8px; cursor: pointer; font-size: 16px; font-weight: 500; transition: background 0.3s;">
|
||||||
|
Fermer
|
||||||
|
</button>
|
||||||
|
<button onclick="window.open('https://diod.m82-project.org/', '_blank')"
|
||||||
|
style="background: #95a5a6; color: white; border: none; padding: 12px 24px; border-radius: 8px; cursor: pointer; font-size: 16px; font-weight: 500; transition: background 0.3s;">
|
||||||
|
En savoir plus
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
@keyframes slideIn {
|
||||||
|
from { transform: translateY(30px); opacity: 0; }
|
||||||
|
to { transform: translateY(0); opacity: 1; }
|
||||||
|
}
|
||||||
|
#dima-modal button:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
modal.addEventListener('click', (e) => {
|
||||||
|
if (e.target === modal) modal.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
this.log('Modal affiché');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('DIMA: Erreur modal:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Make UIManager available globally for Chrome extension
|
||||||
|
window.UIManager = UIManager;
|
||||||
Загрузка…
x
Ссылка в новой задаче
Block a user