@lynxflow/seo-engine 1.8.1 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,118 +1,4 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- function __accessProp(key) {
6
- return this[key];
7
- }
8
- var __toCommonJS = (from) => {
9
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
10
- if (entry)
11
- return entry;
12
- entry = __defProp({}, "__esModule", { value: true });
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (var key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(entry, key))
16
- __defProp(entry, key, {
17
- get: __accessProp.bind(from, key),
18
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
- });
20
- }
21
- __moduleCache.set(from, entry);
22
- return entry;
23
- };
24
- var __moduleCache;
25
- var __returnValue = (v) => v;
26
- function __exportSetter(name, newValue) {
27
- this[name] = __returnValue.bind(null, newValue);
28
- }
29
- var __export = (target, all) => {
30
- for (var name in all)
31
- __defProp(target, name, {
32
- get: all[name],
33
- enumerable: true,
34
- configurable: true,
35
- set: __exportSetter.bind(all, name)
36
- });
37
- };
38
-
39
- // src/index.ts
40
- var exports_src = {};
41
- __export(exports_src, {
42
- validateSeoSlug: () => validateSeoSlug,
43
- resolveFeatureIcon: () => resolveFeatureIcon,
44
- resolveBuiltInLocations: () => resolveBuiltInLocations,
45
- resolveBrandIcon: () => resolveBrandIcon,
46
- renderUiIconSvg: () => renderUiIconSvg,
47
- renderBrandIconSvg: () => renderBrandIconSvg,
48
- getSeoAgentPrompt: () => getSeoAgentPrompt,
49
- default: () => src_default,
50
- createLynxSeoEngine: () => createLynxSeoEngine,
51
- cleanSeoSlug: () => cleanSeoSlug,
52
- YoastParityEngine: () => YoastParityEngine,
53
- VideoYouTubeAnalyzer: () => VideoYouTubeAnalyzer,
54
- UrlyticsEngine: () => UrlyticsEngine,
55
- UI_ICONS: () => UI_ICONS,
56
- TokenQuotaManager: () => TokenQuotaManager,
57
- TechnicalRulesAuditor: () => TechnicalRulesAuditor,
58
- TeamRbacEngine: () => TeamRbacEngine,
59
- SocialVideoSeoAnalyticsEngine: () => SocialVideoSeoAnalyticsEngine,
60
- SocialTrendSeoGenerator: () => SocialTrendSeoGenerator,
61
- SocialGrowthSuite: () => SocialGrowthSuite,
62
- SocialAdsSocialSeoEngine: () => SocialAdsSocialSeoEngine,
63
- SiteAuditor: () => SiteAuditor,
64
- SerpRankHistoryEngine: () => SerpRankHistoryEngine,
65
- SerpClient: () => SerpClient,
66
- SeoOpportunitiesDecayDetector: () => SeoOpportunitiesDecayDetector,
67
- SchemaGraphBuilder: () => SchemaGraphBuilder,
68
- SUPPORTED_CANONICAL_LOCALES: () => SUPPORTED_CANONICAL_LOCALES,
69
- SCHEMA_LOCAL_BUSINESS_MAP: () => SCHEMA_LOCAL_BUSINESS_MAP,
70
- RssSyndicationFeedGenerator: () => RssSyndicationFeedGenerator,
71
- RealReviewsSyncEngine: () => RealReviewsSyncEngine,
72
- RankMathParityEngine: () => RankMathParityEngine,
73
- PseoMatrixEngine: () => PseoMatrixEngine,
74
- PSEO_AGENT_SYSTEM_PROMPT: () => PSEO_AGENT_SYSTEM_PROMPT,
75
- OgImageGenerator: () => OgImageGenerator,
76
- NGramDensityAnalyzer: () => NGramDensityAnalyzer,
77
- McpSeoServerHub: () => McpSeoServerHub,
78
- MasterMarketingEngine: () => MasterMarketingEngine,
79
- MULTILINGUAL_STOP_WORDS: () => MULTILINGUAL_STOP_WORDS,
80
- MULTILINGUAL_DISCLAIMERS: () => MULTILINGUAL_DISCLAIMERS,
81
- MULTILINGUAL_BANNED_DISPARAGING_WORDS: () => MULTILINGUAL_BANNED_DISPARAGING_WORDS,
82
- LynxSeoEngine: () => LynxSeoEngine,
83
- LynxSeo: () => LynxSeo,
84
- LynxAnalyticsClient: () => LynxAnalyticsClient,
85
- LlmContentCleaner: () => LlmContentCleaner,
86
- LegalDisclaimerEngine: () => LegalDisclaimerEngine,
87
- LagoTokenMeter: () => LagoTokenMeter,
88
- KnowledgeGraphLinker: () => KnowledgeGraphLinker,
89
- KeywordPermutatorEngine: () => KeywordPermutatorEngine,
90
- IsrCacheManager: () => IsrCacheManager,
91
- InstantMatrixSearchEngine: () => InstantMatrixSearchEngine,
92
- IndexNowClient: () => IndexNowClient,
93
- I18nDetector: () => I18nDetector,
94
- HyperswitchGateway: () => HyperswitchGateway,
95
- GoogleBusinessProfileEngine: () => GoogleBusinessProfileEngine,
96
- GeoMeshLinkingEngine: () => GeoMeshLinkingEngine,
97
- FreePublicToolsEngine: () => FreePublicToolsEngine,
98
- ExtendedSchemaGraphBuilder: () => ExtendedSchemaGraphBuilder,
99
- EmbeddableSeoWidgetGenerator: () => EmbeddableSeoWidgetGenerator,
100
- DeepCrawlerAuditor: () => DeepCrawlerAuditor,
101
- CrosslinkScorerEngine: () => CrosslinkScorerEngine,
102
- CroCopywritingEngine: () => CroCopywritingEngine,
103
- CopywritingFrameworksMaster: () => CopywritingFrameworksMaster,
104
- BrandDnaCalendarEngine: () => BrandDnaCalendarEngine,
105
- BacklinksClient: () => BacklinksClient,
106
- BUILT_IN_LOCATIONS_DATABASE: () => BUILT_IN_LOCATIONS_DATABASE,
107
- BRAND_ICONS: () => BRAND_ICONS,
108
- ApiKeyGuardian: () => ApiKeyGuardian,
109
- AiCopilotClient: () => AiCopilotClient,
110
- AiBotsLogAnalyzer: () => AiBotsLogAnalyzer,
111
- AdIntelligenceCroEngine: () => AdIntelligenceCroEngine
112
- });
113
- module.exports = __toCommonJS(exports_src);
114
-
115
- // src/token-quota-manager.ts
1
+ // packages/lynx-seo-engine/src/token-quota-manager.ts
116
2
  class TokenQuotaManager {
117
3
  tier;
118
4
  monthlyCreditBudget;
@@ -160,7 +46,7 @@ class TokenQuotaManager {
160
46
  }
161
47
  }
162
48
 
163
- // src/auth-key.ts
49
+ // packages/lynx-seo-engine/src/auth-key.ts
164
50
  class ApiKeyGuardian {
165
51
  static domainRegistry = new Map;
166
52
  static uniquePageRegistry = new Map;
@@ -334,7 +220,7 @@ class ApiKeyGuardian {
334
220
  }
335
221
  }
336
222
 
337
- // src/i18n-dictionary.ts
223
+ // packages/lynx-seo-engine/src/i18n-dictionary.ts
338
224
  var DICTIONARIES = {
339
225
  fr: {
340
226
  geoTitle: (s, city, country, b) => `${s} à ${city} (${country}) — ${b}`,
@@ -690,7 +576,7 @@ function isSupportedLanguage(lang) {
690
576
  return Boolean(DICTIONARIES[code]);
691
577
  }
692
578
 
693
- // src/indexnow-client.ts
579
+ // packages/lynx-seo-engine/src/indexnow-client.ts
694
580
  var SUCCESS_STATUSES = new Set([200, 202]);
695
581
  var MAX_URLS_PER_REQUEST = 1e4;
696
582
  var REQUEST_TIMEOUT_MS = 15000;
@@ -746,7 +632,7 @@ class IndexNowClient {
746
632
  }
747
633
  }
748
634
 
749
- // src/analytics-client.ts
635
+ // packages/lynx-seo-engine/src/analytics-client.ts
750
636
  class LynxAnalyticsClient {
751
637
  apiKey;
752
638
  endpoint;
@@ -975,7 +861,7 @@ class LynxAnalyticsClient {
975
861
  }
976
862
  }
977
863
 
978
- // src/serp-client.ts
864
+ // packages/lynx-seo-engine/src/serp-client.ts
979
865
  class SerpClient {
980
866
  apiKey;
981
867
  endpoint;
@@ -1028,7 +914,7 @@ class SerpClient {
1028
914
  }
1029
915
  }
1030
916
 
1031
- // src/backlinks-client.ts
917
+ // packages/lynx-seo-engine/src/backlinks-client.ts
1032
918
  class BacklinksClient {
1033
919
  apiKey;
1034
920
  endpoint;
@@ -1084,7 +970,7 @@ class BacklinksClient {
1084
970
  }
1085
971
  }
1086
972
 
1087
- // src/ai-copilot-client.ts
973
+ // packages/lynx-seo-engine/src/ai-copilot-client.ts
1088
974
  class AiCopilotClient {
1089
975
  apiKey;
1090
976
  endpoint;
@@ -1148,7 +1034,7 @@ Optimiser votre stratégie avec ${params.targetKeywords.join(", ")}.
1148
1034
  }
1149
1035
  }
1150
1036
 
1151
- // src/lago-token-meter.ts
1037
+ // packages/lynx-seo-engine/src/lago-token-meter.ts
1152
1038
  class LagoTokenMeter {
1153
1039
  lagoApiUrl;
1154
1040
  apiKey;
@@ -1229,7 +1115,7 @@ class HyperswitchGateway {
1229
1115
  }
1230
1116
  }
1231
1117
 
1232
- // src/site-auditor.ts
1118
+ // packages/lynx-seo-engine/src/site-auditor.ts
1233
1119
  class SiteAuditor {
1234
1120
  static inspectMeta(params) {
1235
1121
  const checks = [];
@@ -1275,7 +1161,7 @@ class SiteAuditor {
1275
1161
  }
1276
1162
  }
1277
1163
 
1278
- // src/schema-builder.ts
1164
+ // packages/lynx-seo-engine/src/schema-builder.ts
1279
1165
  class SchemaGraphBuilder {
1280
1166
  static buildGraph(opts) {
1281
1167
  const productNode = {
@@ -1370,7 +1256,7 @@ class SchemaGraphBuilder {
1370
1256
  }
1371
1257
  }
1372
1258
 
1373
- // src/site-crawler.ts
1259
+ // packages/lynx-seo-engine/src/site-crawler.ts
1374
1260
  class DeepCrawlerAuditor {
1375
1261
  static DEFAULT_USER_AGENT = "LynxFlowSeoBot/1.2 (+https://lynxintel.io/bot; technical audit)";
1376
1262
  static inspectHtmlSnapshot(url, html, statusCode = 200, responseTimeMs = 45) {
@@ -1659,7 +1545,7 @@ class DeepCrawlerAuditor {
1659
1545
  }
1660
1546
  }
1661
1547
 
1662
- // src/cro-copywriting-engine.ts
1548
+ // packages/lynx-seo-engine/src/cro-copywriting-engine.ts
1663
1549
  class CroCopywritingEngine {
1664
1550
  static generatePasCopy(solutionName, targetNiche) {
1665
1551
  return {
@@ -1721,7 +1607,7 @@ class CroCopywritingEngine {
1721
1607
  }
1722
1608
  }
1723
1609
 
1724
- // src/llm-content-cleaner.ts
1610
+ // packages/lynx-seo-engine/src/llm-content-cleaner.ts
1725
1611
  class LlmContentCleaner {
1726
1612
  static cleanForLlm(content) {
1727
1613
  return this.htmlToCleanMarkdown(content);
@@ -1749,7 +1635,7 @@ $1
1749
1635
  }
1750
1636
  }
1751
1637
 
1752
- // src/engine.ts
1638
+ // packages/lynx-seo-engine/src/engine.ts
1753
1639
  class LynxSeoEngine {
1754
1640
  config;
1755
1641
  servicesMap;
@@ -2347,7 +2233,7 @@ ${servicesList}
2347
2233
  `;
2348
2234
  }
2349
2235
  }
2350
- // src/slug-engine.ts
2236
+ // packages/lynx-seo-engine/src/slug-engine.ts
2351
2237
  var MULTILINGUAL_STOP_WORDS = {
2352
2238
  en: new Set([
2353
2239
  "the",
@@ -2738,7 +2624,7 @@ function validateSeoSlug(slug) {
2738
2624
  errors
2739
2625
  };
2740
2626
  }
2741
- // src/legal-disclaimers.ts
2627
+ // packages/lynx-seo-engine/src/legal-disclaimers.ts
2742
2628
  var MULTILINGUAL_DISCLAIMERS = {
2743
2629
  en: {
2744
2630
  comparison: {
@@ -3034,7 +2920,7 @@ class LegalDisclaimerEngine {
3034
2920
  };
3035
2921
  }
3036
2922
  }
3037
- // src/extended-schemas.ts
2923
+ // packages/lynx-seo-engine/src/extended-schemas.ts
3038
2924
  var SCHEMA_LOCAL_BUSINESS_MAP = {
3039
2925
  plumber: "Plumber",
3040
2926
  plumbing: "Plumber",
@@ -3198,10 +3084,13 @@ class ExtendedSchemaGraphBuilder {
3198
3084
  };
3199
3085
  }
3200
3086
  static buildAggregateRating(opts) {
3087
+ if (!opts.ratingValue || !opts.reviewCount || opts.reviewCount <= 0) {
3088
+ return null;
3089
+ }
3201
3090
  return {
3202
3091
  "@type": "AggregateRating",
3203
- ratingValue: opts.ratingValue ?? 4.9,
3204
- reviewCount: opts.reviewCount ?? 1280,
3092
+ ratingValue: opts.ratingValue,
3093
+ reviewCount: opts.reviewCount,
3205
3094
  bestRating: opts.bestRating ?? 5,
3206
3095
  worstRating: opts.worstRating ?? 1,
3207
3096
  itemReviewed: {
@@ -3255,7 +3144,7 @@ class ExtendedSchemaGraphBuilder {
3255
3144
  }
3256
3145
  }
3257
3146
 
3258
- // src/built-in-locations.ts
3147
+ // packages/lynx-seo-engine/src/built-in-locations.ts
3259
3148
  var BUILT_IN_LOCATIONS_DATABASE = {
3260
3149
  fr: [
3261
3150
  { slug: "paris", name: "Paris", region: "Île-de-France", country: "France", population: 2161000, currency: "EUR", currencySymbol: "€", latitude: 48.8566, longitude: 2.3522, neighborSlugs: ["boulogne-billancourt", "saint-denis", "montreuil"] },
@@ -3399,7 +3288,7 @@ function resolveBuiltInLocations(territories) {
3399
3288
  return results.length > 0 ? results : [...BUILT_IN_LOCATIONS_DATABASE.fr];
3400
3289
  }
3401
3290
 
3402
- // src/og-image-generator.ts
3291
+ // packages/lynx-seo-engine/src/og-image-generator.ts
3403
3292
  class OgImageGenerator {
3404
3293
  static generateOgImageUrl(domain, pageMeta, brandName) {
3405
3294
  const cleanDomain = domain.replace(/\/+$/, "");
@@ -3419,8 +3308,8 @@ class OgImageGenerator {
3419
3308
  const badge = opts.badgeText || "OFFICIAL";
3420
3309
  const title = opts.title.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
3421
3310
  const loc = opts.locationName ? `\uD83D\uDCCD ${opts.locationName}` : "⚡ Instant Cloud Setup";
3422
- const rating = opts.ratingValue ?? 4.9;
3423
- const reviews = opts.reviewCount ?? 1280;
3311
+ const rating = opts.ratingValue;
3312
+ const reviews = opts.reviewCount;
3424
3313
  const accent = opts.brandColor || "#6366F1";
3425
3314
  return `<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
3426
3315
  <defs>
@@ -3463,12 +3352,12 @@ class OgImageGenerator {
3463
3352
  ${title.length > 38 ? `<tspan x="80" dy="68">${title.slice(38, 80)}</tspan>` : ""}
3464
3353
  </text>
3465
3354
 
3466
- <!-- Trust Stars & Social Proof -->
3467
- <g transform="translate(80, 470)">
3355
+ <!-- Trust Stars & Social Proof (Only if real verified reviews exist) -->
3356
+ ${rating && reviews ? `<g transform="translate(80, 470)">
3468
3357
  <text x="0" y="32" fill="#FBBF24" font-size="24">★★★★★</text>
3469
3358
  <text x="140" y="30" fill="#F8FAFC" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="20" font-weight="800">${rating} / 5</text>
3470
3359
  <text x="210" y="30" fill="#64748B" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="16" font-weight="500">(${reviews.toLocaleString()} verified reviews)</text>
3471
- </g>
3360
+ </g>` : ""}
3472
3361
 
3473
3362
  <!-- Footer Brand -->
3474
3363
  <g transform="translate(80, 540)">
@@ -3480,7 +3369,7 @@ class OgImageGenerator {
3480
3369
  }
3481
3370
  }
3482
3371
 
3483
- // src/matrix-engine.ts
3372
+ // packages/lynx-seo-engine/src/matrix-engine.ts
3484
3373
  class PseoMatrixEngine {
3485
3374
  legalEngine;
3486
3375
  constructor(legalOptions) {
@@ -4099,7 +3988,7 @@ ${urls}
4099
3988
  };
4100
3989
  }
4101
3990
  }
4102
- // src/i18n-detector.ts
3991
+ // packages/lynx-seo-engine/src/i18n-detector.ts
4103
3992
  var SUPPORTED_CANONICAL_LOCALES = [
4104
3993
  "en",
4105
3994
  "fr",
@@ -4176,7 +4065,7 @@ class I18nDetector {
4176
4065
  };
4177
4066
  }
4178
4067
  }
4179
- // src/brand-icons.ts
4068
+ // packages/lynx-seo-engine/src/brand-icons.ts
4180
4069
  var BRAND_ICONS = {
4181
4070
  facebook: {
4182
4071
  name: "Facebook",
@@ -4292,7 +4181,7 @@ function renderBrandIconSvg(input, className = "w-5 h-5 inline-block") {
4292
4181
  return "";
4293
4182
  return `<svg class="${className}" viewBox="${icon.viewBox}" fill="currentColor" aria-hidden="true"><path d="${icon.svgPath}"/></svg>`;
4294
4183
  }
4295
- // src/ui-icons.ts
4184
+ // packages/lynx-seo-engine/src/ui-icons.ts
4296
4185
  var UI_ICONS = {
4297
4186
  zap: {
4298
4187
  name: "Zap / Lightning",
@@ -4405,7 +4294,7 @@ function resolveFeatureIcon(featureText) {
4405
4294
  }
4406
4295
  return "zap";
4407
4296
  }
4408
- // src/free-public-tools.ts
4297
+ // packages/lynx-seo-engine/src/free-public-tools.ts
4409
4298
  class FreePublicToolsEngine {
4410
4299
  static simulateSerpSnippet(input) {
4411
4300
  const title = (input.title || "").trim();
@@ -4539,7 +4428,7 @@ class FreePublicToolsEngine {
4539
4428
  });
4540
4429
  }
4541
4430
  }
4542
- // src/urlytics-engine.ts
4431
+ // packages/lynx-seo-engine/src/urlytics-engine.ts
4543
4432
  class UrlyticsEngine {
4544
4433
  static parseUrl(rawUrl) {
4545
4434
  if (!rawUrl || typeof rawUrl !== "string") {
@@ -4601,7 +4490,7 @@ class UrlyticsEngine {
4601
4490
  return urls.map((u) => this.parseUrl(u));
4602
4491
  }
4603
4492
  }
4604
- // src/keyword-permutator.ts
4493
+ // packages/lynx-seo-engine/src/keyword-permutator.ts
4605
4494
  class KeywordPermutatorEngine {
4606
4495
  static generateKeywordMatrix(options) {
4607
4496
  const { products, words = [], locations = [], maxCombinations = 5000 } = options;
@@ -4677,7 +4566,7 @@ class KeywordPermutatorEngine {
4677
4566
  return results;
4678
4567
  }
4679
4568
  }
4680
- // src/llm-prompt.ts
4569
+ // packages/lynx-seo-engine/src/llm-prompt.ts
4681
4570
  var PSEO_AGENT_SYSTEM_PROMPT = `
4682
4571
  You are the Programmatic SEO Implementation Specialist powered by @lynxflow/seo-engine.
4683
4572
  Your role is to configure, resolve, and maintain programmatic SEO pages, XML sitemaps, Schema.org JSON-LD graphs, and compliance rules.
@@ -4991,7 +4880,7 @@ ${PSEO_AGENT_SYSTEM_PROMPT}
4991
4880
  - Domain: ${customContext.domain || "https://example.com"}
4992
4881
  `.trim();
4993
4882
  }
4994
- // src/geo-mesh-linking.ts
4883
+ // packages/lynx-seo-engine/src/geo-mesh-linking.ts
4995
4884
  class GeoMeshLinkingEngine {
4996
4885
  static computeDistanceKm(coord1, coord2) {
4997
4886
  const R = 6371;
@@ -5023,7 +4912,7 @@ class GeoMeshLinkingEngine {
5023
4912
  return sameRegion.slice(0, maxNeighbors).map((c) => ({ city: c }));
5024
4913
  }
5025
4914
  }
5026
- // src/brand-dna-calendar.ts
4915
+ // packages/lynx-seo-engine/src/brand-dna-calendar.ts
5027
4916
  class BrandDnaCalendarEngine {
5028
4917
  static generate4WeekCalendar(dna, services, topCities = ["Paris", "Lyon", "Marseille", "Bordeaux"]) {
5029
4918
  const calendar = [];
@@ -5103,7 +4992,7 @@ class BrandDnaCalendarEngine {
5103
4992
  return calendar;
5104
4993
  }
5105
4994
  }
5106
- // src/technical-rules-auditor.ts
4995
+ // packages/lynx-seo-engine/src/technical-rules-auditor.ts
5107
4996
  class TechnicalRulesAuditor {
5108
4997
  static auditPage(page) {
5109
4998
  const issues = [];
@@ -5221,7 +5110,7 @@ class TechnicalRulesAuditor {
5221
5110
  return issues;
5222
5111
  }
5223
5112
  }
5224
- // src/ai-bots-log-analyzer.ts
5113
+ // packages/lynx-seo-engine/src/ai-bots-log-analyzer.ts
5225
5114
  class AiBotsLogAnalyzer {
5226
5115
  static classifyUserAgent(ua) {
5227
5116
  const lowerUa = ua.toLowerCase();
@@ -5292,7 +5181,7 @@ class AiBotsLogAnalyzer {
5292
5181
  return result;
5293
5182
  }
5294
5183
  }
5295
- // src/serp-history-alerts.ts
5184
+ // packages/lynx-seo-engine/src/serp-history-alerts.ts
5296
5185
  class SerpRankHistoryEngine {
5297
5186
  static analyzeRankShift(previousSnapshot, currentSnapshot) {
5298
5187
  const prev = previousSnapshot.position;
@@ -5333,7 +5222,7 @@ class SerpRankHistoryEngine {
5333
5222
  return null;
5334
5223
  }
5335
5224
  }
5336
- // src/seo-opportunities-decay.ts
5225
+ // packages/lynx-seo-engine/src/seo-opportunities-decay.ts
5337
5226
  class SeoOpportunitiesDecayDetector {
5338
5227
  static getExpectedCtr(position) {
5339
5228
  if (position <= 1)
@@ -5422,7 +5311,7 @@ class SeoOpportunitiesDecayDetector {
5422
5311
  return cannibalized;
5423
5312
  }
5424
5313
  }
5425
- // src/knowledge-graph-linker.ts
5314
+ // packages/lynx-seo-engine/src/knowledge-graph-linker.ts
5426
5315
  class KnowledgeGraphLinker {
5427
5316
  static buildSearchUrl(query, apiKey, limit = 5, languages = ["fr", "en"]) {
5428
5317
  const params = new URLSearchParams({
@@ -5470,7 +5359,7 @@ class KnowledgeGraphLinker {
5470
5359
  return Array.from(new Set(links));
5471
5360
  }
5472
5361
  }
5473
- // src/mcp-seo-server.ts
5362
+ // packages/lynx-seo-engine/src/mcp-seo-server.ts
5474
5363
  class McpSeoServerHub {
5475
5364
  static getRegisteredTools() {
5476
5365
  return [
@@ -5559,7 +5448,7 @@ class McpSeoServerHub {
5559
5448
  }
5560
5449
  }
5561
5450
  }
5562
- // src/master-marketing-engine.ts
5451
+ // packages/lynx-seo-engine/src/master-marketing-engine.ts
5563
5452
  class MasterMarketingEngine {
5564
5453
  static generateDirectoryListings(domain = "lynxintel.io", brandName = "LynxSEO") {
5565
5454
  return [
@@ -5784,7 +5673,7 @@ class MasterMarketingEngine {
5784
5673
  };
5785
5674
  }
5786
5675
  }
5787
- // src/social-video-seo.ts
5676
+ // packages/lynx-seo-engine/src/social-video-seo.ts
5788
5677
  class SocialVideoSeoAnalyticsEngine {
5789
5678
  static buildVideoObjectSchema(opts) {
5790
5679
  const schema = {
@@ -5832,7 +5721,7 @@ class SocialVideoSeoAnalyticsEngine {
5832
5721
  };
5833
5722
  }
5834
5723
  }
5835
- // src/social-trend-seo.ts
5724
+ // packages/lynx-seo-engine/src/social-trend-seo.ts
5836
5725
  class SocialTrendSeoGenerator {
5837
5726
  static generateActionFromTrend(trend, serviceSlug = "crm-pipeline", serviceName = "CRM Pipeline Commercial") {
5838
5727
  const cleanTopic = trend.topicName.toLowerCase().replace(/[^a-z0-9]+/g, "-");
@@ -5892,7 +5781,7 @@ class SocialTrendSeoGenerator {
5892
5781
  ];
5893
5782
  }
5894
5783
  }
5895
- // src/crosslink-scorer.ts
5784
+ // packages/lynx-seo-engine/src/crosslink-scorer.ts
5896
5785
  class CrosslinkScorerEngine {
5897
5786
  static computeCrosslinkScore(source, candidate) {
5898
5787
  if (source.slug === candidate.slug)
@@ -5943,7 +5832,7 @@ class CrosslinkScorerEngine {
5943
5832
  return suggestions.sort((a, b) => b.score - a.score).slice(0, maxLinks);
5944
5833
  }
5945
5834
  }
5946
- // src/instant-matrix-search.ts
5835
+ // packages/lynx-seo-engine/src/instant-matrix-search.ts
5947
5836
  class InstantMatrixSearchEngine {
5948
5837
  static search(query, pages, limit = 10) {
5949
5838
  const cleanQuery = query.trim().toLowerCase();
@@ -5965,7 +5854,7 @@ class InstantMatrixSearchEngine {
5965
5854
  }).filter((item) => item.score > 0).sort((a, b) => b.score - a.score).slice(0, limit).map((item) => item.page);
5966
5855
  }
5967
5856
  }
5968
- // src/rss-syndication-feed.ts
5857
+ // packages/lynx-seo-engine/src/rss-syndication-feed.ts
5969
5858
  class RssSyndicationFeedGenerator {
5970
5859
  static generateRss2(opts) {
5971
5860
  const itemsXml = opts.items.map((item) => `
@@ -5994,7 +5883,7 @@ ${itemsXml}
5994
5883
  </rss>`.trim();
5995
5884
  }
5996
5885
  }
5997
- // src/embeddable-seo-widget.ts
5886
+ // packages/lynx-seo-engine/src/embeddable-seo-widget.ts
5998
5887
  class EmbeddableSeoWidgetGenerator {
5999
5888
  static generateWidgetJs(apiBaseUrl) {
6000
5889
  return `
@@ -6042,7 +5931,7 @@ class EmbeddableSeoWidgetGenerator {
6042
5931
  `.trim();
6043
5932
  }
6044
5933
  }
6045
- // src/ngram-density-analyzer.ts
5934
+ // packages/lynx-seo-engine/src/ngram-density-analyzer.ts
6046
5935
  class NGramDensityAnalyzer {
6047
5936
  static stopwords = new Set([
6048
5937
  "le",
@@ -6151,7 +6040,7 @@ class NGramDensityAnalyzer {
6151
6040
  })).sort((a, b) => b.count - a.count);
6152
6041
  }
6153
6042
  }
6154
- // src/isr-cache-manager.ts
6043
+ // packages/lynx-seo-engine/src/isr-cache-manager.ts
6155
6044
  class IsrCacheManager {
6156
6045
  static cache = new Map;
6157
6046
  static defaultTtlMs = 24 * 3600 * 1000;
@@ -6189,7 +6078,7 @@ class IsrCacheManager {
6189
6078
  return this.cache.size;
6190
6079
  }
6191
6080
  }
6192
- // src/copy-frameworks-master.ts
6081
+ // packages/lynx-seo-engine/src/copy-frameworks-master.ts
6193
6082
  class CopywritingFrameworksMaster {
6194
6083
  static generateHeadlines(opts) {
6195
6084
  return {
@@ -6223,7 +6112,7 @@ class CopywritingFrameworksMaster {
6223
6112
  ];
6224
6113
  }
6225
6114
  }
6226
- // src/social-ads-seo.ts
6115
+ // packages/lynx-seo-engine/src/social-ads-seo.ts
6227
6116
  class SocialAdsSocialSeoEngine {
6228
6117
  static auditLinkedInTrendsForSeo(industry = "avocats", serviceSlug = "crm-pipeline", serviceName = "CRM Pipeline") {
6229
6118
  return [
@@ -6359,7 +6248,7 @@ ${template.targetHashtags.join(" ")}
6359
6248
  ];
6360
6249
  }
6361
6250
  }
6362
- // src/ad-intelligence-cro.ts
6251
+ // packages/lynx-seo-engine/src/ad-intelligence-cro.ts
6363
6252
  class AdIntelligenceCroEngine {
6364
6253
  static inspectCompetitorAds(competitorDomain, serviceName = "CRM Pipeline") {
6365
6254
  const brand = competitorDomain.replace(/^https?:\/\//, "").split(".")[0];
@@ -6443,7 +6332,7 @@ Avec ${opts.serviceName}, tout est automatisé en tâche de fond pour vous appor
6443
6332
  ];
6444
6333
  }
6445
6334
  }
6446
- // src/rank-math-parity.ts
6335
+ // packages/lynx-seo-engine/src/rank-math-parity.ts
6447
6336
  class RankMathParityEngine {
6448
6337
  static calculateOnPageScore(opts) {
6449
6338
  const kw = opts.focusKeyword.trim().toLowerCase();
@@ -6597,7 +6486,7 @@ class RankMathParityEngine {
6597
6486
  `);
6598
6487
  }
6599
6488
  }
6600
- // src/yoast-parity.ts
6489
+ // packages/lynx-seo-engine/src/yoast-parity.ts
6601
6490
  class YoastParityEngine {
6602
6491
  static frenchTransitionWords = [
6603
6492
  "en effet",
@@ -6712,7 +6601,7 @@ class YoastParityEngine {
6712
6601
  };
6713
6602
  }
6714
6603
  }
6715
- // src/social-growth-suite.ts
6604
+ // packages/lynx-seo-engine/src/social-growth-suite.ts
6716
6605
  class SocialGrowthSuite {
6717
6606
  static generateCarouselDeck(opts) {
6718
6607
  return {
@@ -6918,7 +6807,7 @@ Voici le guide complet en 6 slides pour automatiser votre acquisition en 2026 \u
6918
6807
  ];
6919
6808
  }
6920
6809
  }
6921
- // src/team-rbac.ts
6810
+ // packages/lynx-seo-engine/src/team-rbac.ts
6922
6811
  var ROLE_PERMISSIONS = {
6923
6812
  owner: [
6924
6813
  "project:delete",
@@ -6955,7 +6844,7 @@ class TeamRbacEngine {
6955
6844
  return permissions.includes(action);
6956
6845
  }
6957
6846
  }
6958
- // src/real-reviews-sync.ts
6847
+ // packages/lynx-seo-engine/src/real-reviews-sync.ts
6959
6848
  class RealReviewsSyncEngine {
6960
6849
  static async fetchGooglePlacesReviews(opts) {
6961
6850
  try {
@@ -7078,7 +6967,7 @@ class RealReviewsSyncEngine {
7078
6967
  `;
7079
6968
  }
7080
6969
  }
7081
- // src/google-business-profile.ts
6970
+ // packages/lynx-seo-engine/src/google-business-profile.ts
7082
6971
  class GoogleBusinessProfileEngine {
7083
6972
  static generateLocalBusinessSchema(config) {
7084
6973
  const schema = {
@@ -7292,7 +7181,7 @@ class GoogleBusinessProfileEngine {
7292
7181
  };
7293
7182
  }
7294
7183
  }
7295
- // src/video-youtube-analyzer.ts
7184
+ // packages/lynx-seo-engine/src/video-youtube-analyzer.ts
7296
7185
  class VideoYouTubeAnalyzer {
7297
7186
  static extractVideoId(urlOrIframe) {
7298
7187
  const regExp = /(?:youtube(?:-nocookie)?\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})/;
@@ -7346,7 +7235,614 @@ class VideoYouTubeAnalyzer {
7346
7235
  `.trim();
7347
7236
  }
7348
7237
  }
7349
- // src/index.ts
7238
+ // packages/lynx-seo-engine/src/power-words-psychology.ts
7239
+ var MULTILINGUAL_POWER_WORDS = {
7240
+ fr: {
7241
+ authority: [
7242
+ "officiel",
7243
+ "guide",
7244
+ "expert",
7245
+ "complet",
7246
+ "certifié",
7247
+ "ultime",
7248
+ "meilleur",
7249
+ "meilleurs",
7250
+ "comparatif",
7251
+ "maîtriser",
7252
+ "spécialiste",
7253
+ "leader",
7254
+ "professionnel",
7255
+ "authentique",
7256
+ "infaillible",
7257
+ "reconnu",
7258
+ "démontré",
7259
+ "avis"
7260
+ ],
7261
+ urgency: [
7262
+ "rapide",
7263
+ "instantané",
7264
+ "maintenant",
7265
+ "immédiat",
7266
+ "express",
7267
+ "2026",
7268
+ "dernière minute",
7269
+ "urgent",
7270
+ "dépêchez-vous",
7271
+ "en 5 min",
7272
+ "en 10 min",
7273
+ "aujourd'hui",
7274
+ "débloquer",
7275
+ "vite"
7276
+ ],
7277
+ value: [
7278
+ "gratuit",
7279
+ "économique",
7280
+ "rentable",
7281
+ "offert",
7282
+ "sans engagement",
7283
+ "garanti",
7284
+ "facile",
7285
+ "clé en main",
7286
+ "rentabilité",
7287
+ "gain",
7288
+ "économisez",
7289
+ "inclus",
7290
+ "accessible",
7291
+ "inédit",
7292
+ "remise",
7293
+ "promo"
7294
+ ],
7295
+ curiosity: [
7296
+ "exclusif",
7297
+ "secret",
7298
+ "astuces",
7299
+ "révélé",
7300
+ "inédit",
7301
+ "top",
7302
+ "méthode",
7303
+ "pourquoi",
7304
+ "comment",
7305
+ "découvrir",
7306
+ "choc",
7307
+ "incontournable",
7308
+ "mystère",
7309
+ "incroyable",
7310
+ "vérité"
7311
+ ],
7312
+ sentimentPositive: [
7313
+ "parfait",
7314
+ "incroyable",
7315
+ "magnifique",
7316
+ "puissant",
7317
+ "réussi",
7318
+ "génial",
7319
+ "exceptionnel",
7320
+ "facile",
7321
+ "meilleur",
7322
+ "succès",
7323
+ "brillant",
7324
+ "splendide",
7325
+ "radieux",
7326
+ "magique",
7327
+ "sublime"
7328
+ ],
7329
+ sentimentNegative: [
7330
+ "erreur",
7331
+ "piège",
7332
+ "danger",
7333
+ "éviter",
7334
+ "pire",
7335
+ "arnaque",
7336
+ "catastrophe",
7337
+ "risqué",
7338
+ "menace",
7339
+ "perte",
7340
+ "alerte"
7341
+ ]
7342
+ },
7343
+ en: {
7344
+ authority: [
7345
+ "ultimate",
7346
+ "complete",
7347
+ "definitive",
7348
+ "guide",
7349
+ "expert",
7350
+ "official",
7351
+ "proven",
7352
+ "master",
7353
+ "certified",
7354
+ "best",
7355
+ "top",
7356
+ "authority",
7357
+ "case study",
7358
+ "benchmark",
7359
+ "professional",
7360
+ "review",
7361
+ "formula"
7362
+ ],
7363
+ urgency: [
7364
+ "instant",
7365
+ "fast",
7366
+ "quick",
7367
+ "now",
7368
+ "today",
7369
+ "2026",
7370
+ "deadline",
7371
+ "last chance",
7372
+ "step-by-step",
7373
+ "in 5 minutes",
7374
+ "immediate",
7375
+ "urgent",
7376
+ "unlock",
7377
+ "rapid"
7378
+ ],
7379
+ value: [
7380
+ "free",
7381
+ "affordable",
7382
+ "save",
7383
+ "guaranteed",
7384
+ "easy",
7385
+ "bonus",
7386
+ "discount",
7387
+ "effortless",
7388
+ "lifetime",
7389
+ "roi",
7390
+ "value",
7391
+ "exclusive deal",
7392
+ "profitable"
7393
+ ],
7394
+ curiosity: [
7395
+ "secret",
7396
+ "revealed",
7397
+ "insider",
7398
+ "hacks",
7399
+ "why",
7400
+ "how to",
7401
+ "untold",
7402
+ "surprising",
7403
+ "shocking",
7404
+ "hidden",
7405
+ "must-know",
7406
+ "unbelievable",
7407
+ "myth"
7408
+ ],
7409
+ sentimentPositive: [
7410
+ "amazing",
7411
+ "brilliant",
7412
+ "powerful",
7413
+ "epic",
7414
+ "perfect",
7415
+ "stunning",
7416
+ "thriving",
7417
+ "seamless",
7418
+ "exceptional",
7419
+ "masterpiece",
7420
+ "unbeatable"
7421
+ ],
7422
+ sentimentNegative: [
7423
+ "mistake",
7424
+ "warning",
7425
+ "fail",
7426
+ "avoid",
7427
+ "risk",
7428
+ "trap",
7429
+ "worst",
7430
+ "scam",
7431
+ "danger",
7432
+ "flaw"
7433
+ ]
7434
+ },
7435
+ es: {
7436
+ authority: [
7437
+ "definitiva",
7438
+ "completa",
7439
+ "guía",
7440
+ "experto",
7441
+ "oficial",
7442
+ "certificado",
7443
+ "mejor",
7444
+ "mejores",
7445
+ "comparativa",
7446
+ "profesional",
7447
+ "comprobado",
7448
+ "líder",
7449
+ "análisis"
7450
+ ],
7451
+ urgency: [
7452
+ "rápido",
7453
+ "ahora",
7454
+ "urgente",
7455
+ "hoy",
7456
+ "2026",
7457
+ "en 5 minutos",
7458
+ "inmediato",
7459
+ "última oportunidad",
7460
+ "fácil"
7461
+ ],
7462
+ value: [
7463
+ "gratis",
7464
+ "económico",
7465
+ "ahorra",
7466
+ "garantizado",
7467
+ "rentable",
7468
+ "oferta",
7469
+ "descuento",
7470
+ "exclusivo"
7471
+ ],
7472
+ curiosity: [
7473
+ "secreto",
7474
+ "revelado",
7475
+ "trucos",
7476
+ "por qué",
7477
+ "cómo",
7478
+ "impactante",
7479
+ "increíble",
7480
+ "descubre",
7481
+ "método"
7482
+ ],
7483
+ sentimentPositive: [
7484
+ "excelente",
7485
+ "increíble",
7486
+ "perfecto",
7487
+ "potente",
7488
+ "maravilloso",
7489
+ "éxito",
7490
+ "fantástico"
7491
+ ],
7492
+ sentimentNegative: [
7493
+ "error",
7494
+ "peligro",
7495
+ "evita",
7496
+ "peor",
7497
+ "estafa",
7498
+ "trampa",
7499
+ "fracaso",
7500
+ "riesgo"
7501
+ ]
7502
+ },
7503
+ de: {
7504
+ authority: [
7505
+ "ultimativ",
7506
+ "vollständig",
7507
+ "leitfaden",
7508
+ "experte",
7509
+ "offiziell",
7510
+ "zertifiziert",
7511
+ "beste",
7512
+ "bester",
7513
+ "vergleich",
7514
+ "profi"
7515
+ ],
7516
+ urgency: [
7517
+ "schnell",
7518
+ "jetzt",
7519
+ "sofort",
7520
+ "2026",
7521
+ "in 5 minuten",
7522
+ "heute",
7523
+ "dringend",
7524
+ "einfach"
7525
+ ],
7526
+ value: [
7527
+ "kostenlos",
7528
+ "gratis",
7529
+ "sparen",
7530
+ "garantiert",
7531
+ "rabatt",
7532
+ "günstig",
7533
+ "angebot",
7534
+ "profitabel"
7535
+ ],
7536
+ curiosity: [
7537
+ "geheimnis",
7538
+ "enthüllt",
7539
+ "tricks",
7540
+ "tipps",
7541
+ "warum",
7542
+ "wie man",
7543
+ "unglaublich",
7544
+ "entdecken"
7545
+ ],
7546
+ sentimentPositive: [
7547
+ "hervorragend",
7548
+ "perfekt",
7549
+ "genial",
7550
+ "erfolg",
7551
+ "fantastisch",
7552
+ "wunderbar",
7553
+ "stark"
7554
+ ],
7555
+ sentimentNegative: [
7556
+ "fehler",
7557
+ "gefahr",
7558
+ "vermeiden",
7559
+ "schlimmste",
7560
+ "betrug",
7561
+ "risiko",
7562
+ "warnung"
7563
+ ]
7564
+ },
7565
+ it: {
7566
+ authority: [
7567
+ "guida",
7568
+ "completa",
7569
+ "esperto",
7570
+ "ufficiale",
7571
+ "certificato",
7572
+ "migliore",
7573
+ "migliori",
7574
+ "confronto",
7575
+ "definitiva",
7576
+ "professionale"
7577
+ ],
7578
+ urgency: [
7579
+ "veloce",
7580
+ "ora",
7581
+ "subito",
7582
+ "immediato",
7583
+ "2026",
7584
+ "in 5 minuti",
7585
+ "oggi",
7586
+ "urgente"
7587
+ ],
7588
+ value: [
7589
+ "gratis",
7590
+ "gratuito",
7591
+ "risparmia",
7592
+ "garantito",
7593
+ "sconto",
7594
+ "facile",
7595
+ "offerta",
7596
+ "conveniente"
7597
+ ],
7598
+ curiosity: [
7599
+ "segreto",
7600
+ "svelato",
7601
+ "trucchi",
7602
+ "perché",
7603
+ "come fare",
7604
+ "incredibile",
7605
+ "scopri",
7606
+ "metodo"
7607
+ ],
7608
+ sentimentPositive: [
7609
+ "perfetto",
7610
+ "incredibile",
7611
+ "fantastico",
7612
+ "successo",
7613
+ "eccezionale",
7614
+ "meraviglioso"
7615
+ ],
7616
+ sentimentNegative: [
7617
+ "errore",
7618
+ "pericolo",
7619
+ "evitare",
7620
+ "peggiore",
7621
+ "truffa",
7622
+ "rischio",
7623
+ "trappola"
7624
+ ]
7625
+ },
7626
+ nl: {
7627
+ authority: ["ultiem", "gids", "expert", "officieel", "beste", "vergelijk", "compleet", "bewezen"],
7628
+ urgency: ["snel", "nu", "direct", "vandaag", "2026", "meteen", "eenvoudig"],
7629
+ value: ["gratis", "bespaar", "gegarandeerd", "korting", "goedkoop", "voordeel"],
7630
+ curiosity: ["geheim", "onthuld", "tips", "waarom", "hoe", "ontdek"],
7631
+ sentimentPositive: ["geweldig", "perfect", "uitstekend", "succes", "fantastisch"],
7632
+ sentimentNegative: ["fout", "gevaar", "vermijd", "slechtste", "oplichting", "risico"]
7633
+ },
7634
+ pt: {
7635
+ authority: ["guia", "completo", "definitivo", "especialista", "oficial", "melhor", "melhores", "comparativo"],
7636
+ urgency: ["rápido", "agora", "imediato", "hoje", "2026", "em 5 minutos", "urgente"],
7637
+ value: ["grátis", "gratuito", "economize", "garantido", "desconto", "fácil", "oferta"],
7638
+ curiosity: ["segredo", "revelado", "dicas", "por que", "como fazer", "incrível", "descubra"],
7639
+ sentimentPositive: ["perfeito", "incrível", "fantástico", "sucesso", "excelente"],
7640
+ sentimentNegative: ["erro", "perigo", "evite", "pior", "golpe", "risco", "cilada"]
7641
+ },
7642
+ ar: {
7643
+ authority: ["دليل", "شامل", "رسمي", "خبير", "أفضل", "مقارنة", "معتمد", "نهائي"],
7644
+ urgency: ["سريع", "الآن", "فوري", "اليوم", "2026", "في دقائق", "عاجل"],
7645
+ value: ["مجانا", "وفر", "مضمون", "خصم", "سهل", "عرض", "مميز"],
7646
+ curiosity: ["سر", "كشف", "أسرار", "لماذا", "كيف", "مذهل", "اكتشف"],
7647
+ sentimentPositive: ["رائع", "ممتاز", "ناجح", "مبهر", "مثالي"],
7648
+ sentimentNegative: ["خطأ", "تحذير", "تجنب", "فخ", "احتيال", "خطر"]
7649
+ },
7650
+ ru: {
7651
+ authority: ["руководство", "полный", "эксперт", "официальный", "лучший", "лучшие", "сравнение", "проверенный"],
7652
+ urgency: ["быстро", "сейчас", "срочно", "сегодня", "2026", "за 5 минут", "немедленно"],
7653
+ value: ["бесплатно", "скидка", "гарантия", "выгодно", "легко", "акция"],
7654
+ curiosity: ["секрет", "раскрыт", "лайфхаки", "почему", "как", "невероятный", "узнайте"],
7655
+ sentimentPositive: ["отлично", "идеально", "успех", "потрясающий", "великолепный"],
7656
+ sentimentNegative: ["ошибка", "опасность", "избегать", "худший", "обман", "риск"]
7657
+ },
7658
+ zh: {
7659
+ authority: ["终极", "完整", "指南", "专家", "官方", "最佳", "对比", "评测", "权威"],
7660
+ urgency: ["快速", "立即", "今天", "2026", "5分钟", "马上", "紧急"],
7661
+ value: ["免费", "省钱", "保证", "优惠", "简单", "折扣", "高性价比"],
7662
+ curiosity: ["秘密", "揭秘", "技巧", "为什么", "如何", "必看", "探索"],
7663
+ sentimentPositive: ["完美", "惊人", "卓越", "成功", "极佳", "出色"],
7664
+ sentimentNegative: ["错误", "陷阱", "避免", "危险", "骗局", "风险"]
7665
+ },
7666
+ ja: {
7667
+ authority: ["完全ガイド", "究極", "公式", "専門家", "おすすめ", "徹底比較", "決定版", "プロ"],
7668
+ urgency: ["今すぐ", "速報", "最短", "2026年", "今日", "5分で", "簡単"],
7669
+ value: ["無料", "お得", "割引", "保証", "コスパ", "特典", "プレゼント"],
7670
+ curiosity: ["秘密", "裏ワザ", "暴露", "なぜ", "方法", "必見", "真実"],
7671
+ sentimentPositive: ["最高", "完璧", "圧倒的", "成功", "絶賛", "素晴らしい"],
7672
+ sentimentNegative: ["失敗", "注意", "危険", "避けるべき", "詐欺", "罠"]
7673
+ },
7674
+ hi: {
7675
+ authority: ["गाइड", "सम्पूर्ण", "विशेषज्ञ", "आधिकारिक", "सर्वश्रेष्ठ", "तुलना", "सटीक"],
7676
+ urgency: ["तुरंत", "अभी", "आज", "2026", "5 मिनट में", "जल्दी"],
7677
+ value: ["मुफ्त", "बचत", "गारंटी", "छूट", "आसान", "ऑफर"],
7678
+ curiosity: ["रहस्य", "खुलासा", "टिप्स", "क्यों", "कैसे", "अनोखा"],
7679
+ sentimentPositive: ["उत्कृष्ट", "शानदार", "सफल", "अद्भुत", "बेहतरीन"],
7680
+ sentimentNegative: ["गलती", "खतरा", "सावधान", "धोखा", "नुकसान"]
7681
+ }
7682
+ };
7683
+
7684
+ class PowerWordsPsychologyEngine {
7685
+ static registerLanguageWords(langCode, words) {
7686
+ const code = langCode.toLowerCase().trim();
7687
+ if (!MULTILINGUAL_POWER_WORDS[code]) {
7688
+ MULTILINGUAL_POWER_WORDS[code] = {
7689
+ authority: [],
7690
+ urgency: [],
7691
+ value: [],
7692
+ curiosity: [],
7693
+ sentimentPositive: [],
7694
+ sentimentNegative: []
7695
+ };
7696
+ }
7697
+ if (words.authority)
7698
+ MULTILINGUAL_POWER_WORDS[code].authority.push(...words.authority);
7699
+ if (words.urgency)
7700
+ MULTILINGUAL_POWER_WORDS[code].urgency.push(...words.urgency);
7701
+ if (words.value)
7702
+ MULTILINGUAL_POWER_WORDS[code].value.push(...words.value);
7703
+ if (words.curiosity)
7704
+ MULTILINGUAL_POWER_WORDS[code].curiosity.push(...words.curiosity);
7705
+ if (words.sentimentPositive)
7706
+ MULTILINGUAL_POWER_WORDS[code].sentimentPositive.push(...words.sentimentPositive);
7707
+ if (words.sentimentNegative)
7708
+ MULTILINGUAL_POWER_WORDS[code].sentimentNegative.push(...words.sentimentNegative);
7709
+ }
7710
+ static getSupportedLanguages() {
7711
+ return Object.keys(MULTILINGUAL_POWER_WORDS);
7712
+ }
7713
+ static analyzeTitle(title, lang = "fr") {
7714
+ const raw = (title || "").toLowerCase().trim();
7715
+ const langKey = lang.toLowerCase().trim();
7716
+ const primaryBank = MULTILINGUAL_POWER_WORDS[langKey] || MULTILINGUAL_POWER_WORDS["en"] || MULTILINGUAL_POWER_WORDS["fr"];
7717
+ const allBanks = [primaryBank];
7718
+ if (langKey !== "en" && MULTILINGUAL_POWER_WORDS["en"])
7719
+ allBanks.push(MULTILINGUAL_POWER_WORDS["en"]);
7720
+ const detectedWords = [];
7721
+ let authorityMatch = false;
7722
+ let urgencyMatch = false;
7723
+ let valueMatch = false;
7724
+ let curiosityMatch = false;
7725
+ let positiveCount = 0;
7726
+ let negativeCount = 0;
7727
+ for (const bank of allBanks) {
7728
+ for (const word of bank.authority) {
7729
+ if (raw.includes(word.toLowerCase())) {
7730
+ authorityMatch = true;
7731
+ if (!detectedWords.includes(word))
7732
+ detectedWords.push(word);
7733
+ }
7734
+ }
7735
+ for (const word of bank.urgency) {
7736
+ if (raw.includes(word.toLowerCase())) {
7737
+ urgencyMatch = true;
7738
+ if (!detectedWords.includes(word))
7739
+ detectedWords.push(word);
7740
+ }
7741
+ }
7742
+ for (const word of bank.value) {
7743
+ if (raw.includes(word.toLowerCase())) {
7744
+ valueMatch = true;
7745
+ if (!detectedWords.includes(word))
7746
+ detectedWords.push(word);
7747
+ }
7748
+ }
7749
+ for (const word of bank.curiosity) {
7750
+ if (raw.includes(word.toLowerCase())) {
7751
+ curiosityMatch = true;
7752
+ if (!detectedWords.includes(word))
7753
+ detectedWords.push(word);
7754
+ }
7755
+ }
7756
+ for (const word of bank.sentimentPositive) {
7757
+ if (raw.includes(word.toLowerCase())) {
7758
+ positiveCount++;
7759
+ if (!detectedWords.includes(word))
7760
+ detectedWords.push(word);
7761
+ }
7762
+ }
7763
+ for (const word of bank.sentimentNegative) {
7764
+ if (raw.includes(word.toLowerCase())) {
7765
+ negativeCount++;
7766
+ if (!detectedWords.includes(word))
7767
+ detectedWords.push(word);
7768
+ }
7769
+ }
7770
+ }
7771
+ const hasNumber = /\b\d+\b/.test(raw);
7772
+ const hasYear = /\b(202[4-9]|203[0-9])\b/.test(raw);
7773
+ const hasCurrencyOrDiscount = /[\$€£¥₹%]|د\.إ|﷼|\b(promo|soldes|discount|deal|off)\b/i.test(raw);
7774
+ const hasBracketsOrParentheses = /[\[\]\(\)\{\}【】《》「」]/.test(raw);
7775
+ let score = 30;
7776
+ if (detectedWords.length >= 1)
7777
+ score += 20;
7778
+ if (detectedWords.length >= 2)
7779
+ score += 10;
7780
+ if (detectedWords.length >= 3)
7781
+ score += 10;
7782
+ if (hasNumber)
7783
+ score += 15;
7784
+ if (hasYear)
7785
+ score += 10;
7786
+ if (hasCurrencyOrDiscount)
7787
+ score += 5;
7788
+ if (hasBracketsOrParentheses)
7789
+ score += 5;
7790
+ if (score > 100)
7791
+ score = 100;
7792
+ let sentiment = "neutre";
7793
+ if (positiveCount > negativeCount)
7794
+ sentiment = "positif";
7795
+ else if (negativeCount > positiveCount)
7796
+ sentiment = "negatif";
7797
+ const recommendations = [];
7798
+ if (detectedWords.length === 0) {
7799
+ recommendations.push("Ajoutez au moins 1 mot d'impact émotionnel ou d'autorité (ex: 'Guide', 'Ultime', 'Meilleur').");
7800
+ }
7801
+ if (!hasNumber) {
7802
+ recommendations.push("Intégrez un chiffre (ex: 'Les 7 Meilleurs...') pour augmenter le taux de clic de +36%.");
7803
+ }
7804
+ if (!hasYear) {
7805
+ recommendations.push("Indiquez l'année courante (2026) pour signaler la fraîcheur du contenu aux internautes.");
7806
+ }
7807
+ if (!hasBracketsOrParentheses) {
7808
+ recommendations.push("Utilisez des crochets ou parenthèses [Guide 2026] pour structurer visuellement l'extrait.");
7809
+ }
7810
+ const cleanSubject = title.replace(/\(.*?\)|\[.*?\]/g, "").trim();
7811
+ const suggestedTitles = [
7812
+ `Les 7 Meilleurs ${cleanSubject} [Guide Ultime 2026]`,
7813
+ `Comment Maîtriser ${cleanSubject} en 5 Étapes (Méthode 2026)`,
7814
+ `${cleanSubject} : Avis, Comparatif et Pièges à Éviter (2026)`
7815
+ ];
7816
+ return {
7817
+ score,
7818
+ powerWordsDetected: detectedWords,
7819
+ sentiment,
7820
+ hasNumber,
7821
+ hasYear,
7822
+ hasCuriosityTrigger: curiosityMatch,
7823
+ hasUrgencyTrigger: urgencyMatch,
7824
+ hasAuthorityTrigger: authorityMatch,
7825
+ hasCurrencyOrDiscount,
7826
+ hasBracketsOrParentheses,
7827
+ recommendations,
7828
+ suggestedTitles
7829
+ };
7830
+ }
7831
+ static enrichProgrammaticTitle(baseTitle, lang = "fr") {
7832
+ const analysis = this.analyzeTitle(baseTitle, lang);
7833
+ if (analysis.score >= 80)
7834
+ return baseTitle;
7835
+ let enriched = baseTitle.trim();
7836
+ if (!analysis.hasNumber && !enriched.startsWith("Top ") && !enriched.startsWith("Les ")) {
7837
+ enriched = `Les Meilleurs ${enriched}`;
7838
+ }
7839
+ if (!analysis.hasYear) {
7840
+ enriched = `${enriched} (Guide 2026)`;
7841
+ }
7842
+ return enriched;
7843
+ }
7844
+ }
7845
+ // packages/lynx-seo-engine/src/index.ts
7350
7846
  function createLynxSeoEngine(config) {
7351
7847
  return new LynxSeoEngine(config);
7352
7848
  }
@@ -7391,3 +7887,77 @@ var LynxSeo = {
7391
7887
  realReviews: RealReviewsSyncEngine
7392
7888
  };
7393
7889
  var src_default = LynxSeo;
7890
+ export {
7891
+ validateSeoSlug,
7892
+ resolveFeatureIcon,
7893
+ resolveBuiltInLocations,
7894
+ resolveBrandIcon,
7895
+ renderUiIconSvg,
7896
+ renderBrandIconSvg,
7897
+ getSeoAgentPrompt,
7898
+ src_default as default,
7899
+ createLynxSeoEngine,
7900
+ cleanSeoSlug,
7901
+ YoastParityEngine,
7902
+ VideoYouTubeAnalyzer,
7903
+ UrlyticsEngine,
7904
+ UI_ICONS,
7905
+ TokenQuotaManager,
7906
+ TechnicalRulesAuditor,
7907
+ TeamRbacEngine,
7908
+ SocialVideoSeoAnalyticsEngine,
7909
+ SocialTrendSeoGenerator,
7910
+ SocialGrowthSuite,
7911
+ SocialAdsSocialSeoEngine,
7912
+ SiteAuditor,
7913
+ SerpRankHistoryEngine,
7914
+ SerpClient,
7915
+ SeoOpportunitiesDecayDetector,
7916
+ SchemaGraphBuilder,
7917
+ SUPPORTED_CANONICAL_LOCALES,
7918
+ SCHEMA_LOCAL_BUSINESS_MAP,
7919
+ RssSyndicationFeedGenerator,
7920
+ RealReviewsSyncEngine,
7921
+ RankMathParityEngine,
7922
+ PseoMatrixEngine,
7923
+ PowerWordsPsychologyEngine,
7924
+ PSEO_AGENT_SYSTEM_PROMPT,
7925
+ OgImageGenerator,
7926
+ NGramDensityAnalyzer,
7927
+ McpSeoServerHub,
7928
+ MasterMarketingEngine,
7929
+ MULTILINGUAL_STOP_WORDS,
7930
+ MULTILINGUAL_POWER_WORDS,
7931
+ MULTILINGUAL_DISCLAIMERS,
7932
+ MULTILINGUAL_BANNED_DISPARAGING_WORDS,
7933
+ LynxSeoEngine,
7934
+ LynxSeo,
7935
+ LynxAnalyticsClient,
7936
+ LlmContentCleaner,
7937
+ LegalDisclaimerEngine,
7938
+ LagoTokenMeter,
7939
+ KnowledgeGraphLinker,
7940
+ KeywordPermutatorEngine,
7941
+ IsrCacheManager,
7942
+ InstantMatrixSearchEngine,
7943
+ IndexNowClient,
7944
+ I18nDetector,
7945
+ HyperswitchGateway,
7946
+ GoogleBusinessProfileEngine,
7947
+ GeoMeshLinkingEngine,
7948
+ FreePublicToolsEngine,
7949
+ ExtendedSchemaGraphBuilder,
7950
+ EmbeddableSeoWidgetGenerator,
7951
+ DeepCrawlerAuditor,
7952
+ CrosslinkScorerEngine,
7953
+ CroCopywritingEngine,
7954
+ CopywritingFrameworksMaster,
7955
+ BrandDnaCalendarEngine,
7956
+ BacklinksClient,
7957
+ BUILT_IN_LOCATIONS_DATABASE,
7958
+ BRAND_ICONS,
7959
+ ApiKeyGuardian,
7960
+ AiCopilotClient,
7961
+ AiBotsLogAnalyzer,
7962
+ AdIntelligenceCroEngine
7963
+ };