cdp-edge 1.18.0 → 2.0.1
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/README.md +308 -308
- package/bin/cdp-edge.js +61 -61
- package/dist/commands/analyze.js +52 -52
- package/dist/commands/infra.js +54 -54
- package/dist/commands/install.js +186 -0
- package/dist/commands/server.js +174 -174
- package/dist/commands/setup.js +18 -1
- package/dist/commands/validate.js +84 -84
- package/dist/index.js +12 -12
- package/extracted-skill/tracking-events-generator/advanced-matching.js +364 -364
- package/extracted-skill/tracking-events-generator/agents/browser-tracking.md +172 -72
- package/extracted-skill/tracking-events-generator/agents/google-agent.md +118 -0
- package/extracted-skill/tracking-events-generator/agents/intelligence-agent.md +86 -0
- package/extracted-skill/tracking-events-generator/agents/intelligence-scheduling.md +8 -641
- package/extracted-skill/tracking-events-generator/agents/memory-agent.md +98 -0
- package/extracted-skill/tracking-events-generator/agents/webhook-agent.md +42 -0
- package/extracted-skill/tracking-events-generator/anti-blocking.js +285 -285
- package/extracted-skill/tracking-events-generator/cdpTrack.js +641 -641
- package/extracted-skill/tracking-events-generator/engagement-scoring.js +226 -226
- package/extracted-skill/tracking-events-generator/evals/evals.json +235 -235
- package/extracted-skill/tracking-events-generator/integration-test.js +497 -497
- package/extracted-skill/tracking-events-generator/micro-events.js +992 -992
- package/extracted-skill/tracking-events-generator/models/pinterest/conversions-api-template.js +144 -144
- package/extracted-skill/tracking-events-generator/models/pinterest/event-mappings.json +48 -48
- package/extracted-skill/tracking-events-generator/models/pinterest/tag-template.js +28 -28
- package/extracted-skill/tracking-events-generator/models/reddit/conversions-api-template.js +205 -205
- package/extracted-skill/tracking-events-generator/models/reddit/event-mappings.json +56 -56
- package/extracted-skill/tracking-events-generator/models/reddit/pixel-template.js +19 -19
- package/extracted-skill/tracking-events-generator/models/scenarios/behavior-engine.js +425 -425
- package/package.json +76 -76
- package/server-edge-tracker/schema.sql +265 -265
- package/server-edge-tracker/worker.js +4160 -4160
- package/server-edge-tracker/wrangler.toml +103 -103
- package/templates/pinterest/conversions-api-template.js +144 -144
- package/templates/pinterest/event-mappings.json +48 -48
- package/templates/pinterest/tag-template.js +28 -28
- package/templates/reddit/conversions-api-template.js +205 -205
- package/templates/reddit/event-mappings.json +56 -56
- package/templates/reddit/pixel-template.js +19 -19
- package/templates/scenarios/behavior-engine.js +425 -425
|
@@ -1,226 +1,226 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ENGAGEMENT SCORING - CDP Edge (Quantum Tier)
|
|
3
|
-
*
|
|
4
|
-
* Cálculo preliminar de engajamento no browser.
|
|
5
|
-
* O cálculo final é feito no servidor para máxima precisão.
|
|
6
|
-
* @version 1.0.0
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
// ── Configurações ──────────────────────────────────────────────────────
|
|
10
|
-
const ENGAGEMENT_CONFIG = {
|
|
11
|
-
timeWeights: {
|
|
12
|
-
'curioso': 1.0, // < 10s: score base 1.0
|
|
13
|
-
'interessado': 2.5, // 10-60s: score base 2.5
|
|
14
|
-
'comprador': 4.0 // > 60s: score base 4.0
|
|
15
|
-
},
|
|
16
|
-
scrollWeights: {
|
|
17
|
-
'baixo': 1.0, // < 25%: score base 1.0
|
|
18
|
-
'medio': 2.0, // 25-75%: score base 2.0
|
|
19
|
-
'alto': 3.0 // > 75%: score base 3.0
|
|
20
|
-
},
|
|
21
|
-
clickWeights: {
|
|
22
|
-
'generico': 1.0, // clique sem categoria
|
|
23
|
-
'cta': 2.5, // clique em CTA
|
|
24
|
-
'button': 2.0 // clique em botão
|
|
25
|
-
'link': 1.5 // clique em link
|
|
26
|
-
'input': 0.5, // clique em input
|
|
27
|
-
},
|
|
28
|
-
videoWeights: {
|
|
29
|
-
'play': 1.5, // vídeo iniciou
|
|
30
|
-
'progress25': 2.0, // 25% assistido
|
|
31
|
-
'progress50': 3.0, // 50% assistido
|
|
32
|
-
'progress75': 4.0, // 75% assistido
|
|
33
|
-
'complete': 5.0 // vídeo completo
|
|
34
|
-
},
|
|
35
|
-
hoverWeights: {
|
|
36
|
-
'curto': 1.0, // < 3s: hover curto
|
|
37
|
-
'medio': 2.0, // 3-10s: hover médio
|
|
38
|
-
'longo': 3.0 // > 10s: hover longo
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// ── Estado Global ──────────────────────────────────────────────────────
|
|
43
|
-
const engagementState = {
|
|
44
|
-
timeOnPage: 0,
|
|
45
|
-
scrollDepth: 0,
|
|
46
|
-
clicksCount: 0,
|
|
47
|
-
videoEngagement: 0,
|
|
48
|
-
ctaHoverTime: 0,
|
|
49
|
-
lastActivityTime: Date.now()
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// ── Calculadoras ──────────────────────────────────────────────────────────────
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Calcular score de tempo na página
|
|
56
|
-
* @param {number} timeOnPage - Tempo em segundos desde o carregamento
|
|
57
|
-
* @returns {object} Score e nível de intenção
|
|
58
|
-
*/
|
|
59
|
-
function calculateTimeScore(timeOnPage) {
|
|
60
|
-
let level = 'curioso';
|
|
61
|
-
let score = ENGAGEMENT_CONFIG.timeWeights.curioso;
|
|
62
|
-
|
|
63
|
-
if (timeOnPage >= 10 && timeOnPage < 60) {
|
|
64
|
-
level = 'interessado';
|
|
65
|
-
score = ENGAGEMENT_CONFIG.timeWeights.interessado;
|
|
66
|
-
} else if (timeOnPage >= 60) {
|
|
67
|
-
level = 'comprador';
|
|
68
|
-
score = ENGAGEMENT_CONFIG.timeWeights.comprador;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return { score, level };
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Calcular score de scroll
|
|
76
|
-
* @param {number} scrollDepth - Porcentagem de scroll (0-100)
|
|
77
|
-
* @returns {object} Score e nível
|
|
78
|
-
*/
|
|
79
|
-
function calculateScrollScore(scrollDepth) {
|
|
80
|
-
let level = 'baixo';
|
|
81
|
-
let score = ENGAGEMENT_CONFIG.scrollWeights.baixo;
|
|
82
|
-
|
|
83
|
-
if (scrollDepth >= 25 && scrollDepth < 75) {
|
|
84
|
-
level = 'medio';
|
|
85
|
-
score = ENGAGEMENT_CONFIG.scrollWeights.medio;
|
|
86
|
-
} else if (scrollDepth >= 75) {
|
|
87
|
-
level = 'alto';
|
|
88
|
-
score = ENGAGEMENT_CONFIG.scrollWeights.alto;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return { score, level };
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Calcular score de cliques
|
|
96
|
-
* @param {number} clicksCount - Número de cliques
|
|
97
|
-
* @param {string} clickCategory - Categoria do clique
|
|
98
|
-
* @returns {number} Score de clique
|
|
99
|
-
*/
|
|
100
|
-
function calculateClickScore(clicksCount, clickCategory) {
|
|
101
|
-
const baseScore = ENGAGEMENT_CONFIG.clickWeights.generico;
|
|
102
|
-
const categoryBonus = ENGAGEMENT_CONFIG.clickWeights[clickCategory] || 1.0;
|
|
103
|
-
|
|
104
|
-
// Penalidade para cliques excessivos (após 50 cliques)
|
|
105
|
-
const clickPenalty = Math.max(0, 1 - (clicksCount / 50));
|
|
106
|
-
|
|
107
|
-
return baseScore + categoryBonus;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Calcular score de vídeo
|
|
112
|
-
* @param {string} videoEvent - Tipo de evento de vídeo
|
|
113
|
-
* @returns {number} Score de vídeo
|
|
114
|
-
*/
|
|
115
|
-
function calculateVideoScore(videoEvent) {
|
|
116
|
-
return ENGAGEMENT_CONFIG.videoWeights[videoEvent] || 0;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Calcular score de hover no CTA
|
|
121
|
-
* @param {number} hoverTime - Tempo em segundos de hover
|
|
122
|
-
* @returns {number} Score de hover
|
|
123
|
-
*/
|
|
124
|
-
function calculateHoverScore(hoverTime) {
|
|
125
|
-
let level = 'curto';
|
|
126
|
-
let score = ENGAGEMENT_CONFIG.hoverWeights.curto;
|
|
127
|
-
|
|
128
|
-
if (hoverTime >= 3 && hoverTime < 10) {
|
|
129
|
-
level = 'medio';
|
|
130
|
-
score = ENGAGEMENT_CONFIG.hoverWeights.medio;
|
|
131
|
-
} else if (hoverTime >= 10) {
|
|
132
|
-
level = 'longo';
|
|
133
|
-
score = ENGAGEMENT_CONFIG.hoverWeights.longo;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return { score, level };
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// ── Função Principal de Cálculo ──────────────────────────────────────────────
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Calcular score de engajamento total (browser-side preliminar)
|
|
143
|
-
* @returns {object} Score, nível, componentes
|
|
144
|
-
*/
|
|
145
|
-
function calculateEngagementScore() {
|
|
146
|
-
// 1. Score de tempo
|
|
147
|
-
const { score: timeScore, level: timeLevel } = calculateTimeScore(engagementState.timeOnPage);
|
|
148
|
-
|
|
149
|
-
// 2. Score de scroll
|
|
150
|
-
const { score: scrollScore } = calculateScrollScore(engagementState.scrollDepth);
|
|
151
|
-
|
|
152
|
-
// 3. Score de cliques (com base na média)
|
|
153
|
-
const clickScore = engagementState.clicksCount > 0
|
|
154
|
-
? calculateClickScore(engagementState.clicksCount, 'generico')
|
|
155
|
-
: 0;
|
|
156
|
-
|
|
157
|
-
// 4. Score de vídeo
|
|
158
|
-
const videoScore = engagementState.videoEngagement;
|
|
159
|
-
|
|
160
|
-
// 5. Score de hover no CTA
|
|
161
|
-
const hoverScore = engagementState.ctaHoverTime > 0
|
|
162
|
-
? calculateHoverScore(engagementState.ctaHoverTime / 1000)
|
|
163
|
-
: 0;
|
|
164
|
-
|
|
165
|
-
// 6. Cálculo ponderado
|
|
166
|
-
const totalScore = (
|
|
167
|
-
(timeScore * 0.3) + // 30% peso para tempo
|
|
168
|
-
(scrollScore * 0.2) + // 20% peso para scroll
|
|
169
|
-
(clickScore * 0.15) + // 15% peso para cliques
|
|
170
|
-
(videoScore * 0.25) + // 25% peso para vídeo
|
|
171
|
-
(hoverScore * 0.1) // 10% peso para hover
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
// 7. Nível final de intenção
|
|
175
|
-
let intentionLevel = timeLevel;
|
|
176
|
-
if (totalScore < 1.5) {
|
|
177
|
-
intentionLevel = 'curioso';
|
|
178
|
-
} else if (totalScore < 2.5) {
|
|
179
|
-
intentionLevel = 'interessado';
|
|
180
|
-
} else {
|
|
181
|
-
intentionLevel = 'comprador';
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return {
|
|
185
|
-
totalScore: Math.min(totalScore, 5.0),
|
|
186
|
-
timeScore,
|
|
187
|
-
scrollScore,
|
|
188
|
-
clickScore,
|
|
189
|
-
videoScore,
|
|
190
|
-
hoverScore,
|
|
191
|
-
intentionLevel,
|
|
192
|
-
components: {
|
|
193
|
-
timeOnPage: engagementState.timeOnPage,
|
|
194
|
-
scrollDepth: engagementState.scrollDepth,
|
|
195
|
-
clicksCount: engagementState.clicksCount,
|
|
196
|
-
videoEngagement: engagementState.videoEngagement,
|
|
197
|
-
ctaHoverTime: engagementState.ctaHoverTime
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// ── Atualizador de Estado ──────────────────────────────────────────────────────
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Atualizar estado de engajamento
|
|
206
|
-
* @param {string} component - Componente a atualizar
|
|
207
|
-
* @param {any} value - Novo valor
|
|
208
|
-
*/
|
|
209
|
-
function updateEngagementState(component, value) {
|
|
210
|
-
engagementState[component] = value;
|
|
211
|
-
engagementState.lastActivityTime = Date.now();
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// ── Exportações ─────────────────────────────────────────────────────────────────────
|
|
215
|
-
|
|
216
|
-
export {
|
|
217
|
-
calculateTimeScore,
|
|
218
|
-
calculateScrollScore,
|
|
219
|
-
calculateClickScore,
|
|
220
|
-
calculateVideoScore,
|
|
221
|
-
calculateHoverScore,
|
|
222
|
-
calculateEngagementScore,
|
|
223
|
-
updateEngagementState,
|
|
224
|
-
engagementState,
|
|
225
|
-
ENGAGEMENT_CONFIG
|
|
226
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* ENGAGEMENT SCORING - CDP Edge (Quantum Tier)
|
|
3
|
+
*
|
|
4
|
+
* Cálculo preliminar de engajamento no browser.
|
|
5
|
+
* O cálculo final é feito no servidor para máxima precisão.
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// ── Configurações ──────────────────────────────────────────────────────
|
|
10
|
+
const ENGAGEMENT_CONFIG = {
|
|
11
|
+
timeWeights: {
|
|
12
|
+
'curioso': 1.0, // < 10s: score base 1.0
|
|
13
|
+
'interessado': 2.5, // 10-60s: score base 2.5
|
|
14
|
+
'comprador': 4.0 // > 60s: score base 4.0
|
|
15
|
+
},
|
|
16
|
+
scrollWeights: {
|
|
17
|
+
'baixo': 1.0, // < 25%: score base 1.0
|
|
18
|
+
'medio': 2.0, // 25-75%: score base 2.0
|
|
19
|
+
'alto': 3.0 // > 75%: score base 3.0
|
|
20
|
+
},
|
|
21
|
+
clickWeights: {
|
|
22
|
+
'generico': 1.0, // clique sem categoria
|
|
23
|
+
'cta': 2.5, // clique em CTA
|
|
24
|
+
'button': 2.0 // clique em botão
|
|
25
|
+
'link': 1.5 // clique em link
|
|
26
|
+
'input': 0.5, // clique em input
|
|
27
|
+
},
|
|
28
|
+
videoWeights: {
|
|
29
|
+
'play': 1.5, // vídeo iniciou
|
|
30
|
+
'progress25': 2.0, // 25% assistido
|
|
31
|
+
'progress50': 3.0, // 50% assistido
|
|
32
|
+
'progress75': 4.0, // 75% assistido
|
|
33
|
+
'complete': 5.0 // vídeo completo
|
|
34
|
+
},
|
|
35
|
+
hoverWeights: {
|
|
36
|
+
'curto': 1.0, // < 3s: hover curto
|
|
37
|
+
'medio': 2.0, // 3-10s: hover médio
|
|
38
|
+
'longo': 3.0 // > 10s: hover longo
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// ── Estado Global ──────────────────────────────────────────────────────
|
|
43
|
+
const engagementState = {
|
|
44
|
+
timeOnPage: 0,
|
|
45
|
+
scrollDepth: 0,
|
|
46
|
+
clicksCount: 0,
|
|
47
|
+
videoEngagement: 0,
|
|
48
|
+
ctaHoverTime: 0,
|
|
49
|
+
lastActivityTime: Date.now()
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// ── Calculadoras ──────────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Calcular score de tempo na página
|
|
56
|
+
* @param {number} timeOnPage - Tempo em segundos desde o carregamento
|
|
57
|
+
* @returns {object} Score e nível de intenção
|
|
58
|
+
*/
|
|
59
|
+
function calculateTimeScore(timeOnPage) {
|
|
60
|
+
let level = 'curioso';
|
|
61
|
+
let score = ENGAGEMENT_CONFIG.timeWeights.curioso;
|
|
62
|
+
|
|
63
|
+
if (timeOnPage >= 10 && timeOnPage < 60) {
|
|
64
|
+
level = 'interessado';
|
|
65
|
+
score = ENGAGEMENT_CONFIG.timeWeights.interessado;
|
|
66
|
+
} else if (timeOnPage >= 60) {
|
|
67
|
+
level = 'comprador';
|
|
68
|
+
score = ENGAGEMENT_CONFIG.timeWeights.comprador;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { score, level };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Calcular score de scroll
|
|
76
|
+
* @param {number} scrollDepth - Porcentagem de scroll (0-100)
|
|
77
|
+
* @returns {object} Score e nível
|
|
78
|
+
*/
|
|
79
|
+
function calculateScrollScore(scrollDepth) {
|
|
80
|
+
let level = 'baixo';
|
|
81
|
+
let score = ENGAGEMENT_CONFIG.scrollWeights.baixo;
|
|
82
|
+
|
|
83
|
+
if (scrollDepth >= 25 && scrollDepth < 75) {
|
|
84
|
+
level = 'medio';
|
|
85
|
+
score = ENGAGEMENT_CONFIG.scrollWeights.medio;
|
|
86
|
+
} else if (scrollDepth >= 75) {
|
|
87
|
+
level = 'alto';
|
|
88
|
+
score = ENGAGEMENT_CONFIG.scrollWeights.alto;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { score, level };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Calcular score de cliques
|
|
96
|
+
* @param {number} clicksCount - Número de cliques
|
|
97
|
+
* @param {string} clickCategory - Categoria do clique
|
|
98
|
+
* @returns {number} Score de clique
|
|
99
|
+
*/
|
|
100
|
+
function calculateClickScore(clicksCount, clickCategory) {
|
|
101
|
+
const baseScore = ENGAGEMENT_CONFIG.clickWeights.generico;
|
|
102
|
+
const categoryBonus = ENGAGEMENT_CONFIG.clickWeights[clickCategory] || 1.0;
|
|
103
|
+
|
|
104
|
+
// Penalidade para cliques excessivos (após 50 cliques)
|
|
105
|
+
const clickPenalty = Math.max(0, 1 - (clicksCount / 50));
|
|
106
|
+
|
|
107
|
+
return baseScore + categoryBonus;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Calcular score de vídeo
|
|
112
|
+
* @param {string} videoEvent - Tipo de evento de vídeo
|
|
113
|
+
* @returns {number} Score de vídeo
|
|
114
|
+
*/
|
|
115
|
+
function calculateVideoScore(videoEvent) {
|
|
116
|
+
return ENGAGEMENT_CONFIG.videoWeights[videoEvent] || 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Calcular score de hover no CTA
|
|
121
|
+
* @param {number} hoverTime - Tempo em segundos de hover
|
|
122
|
+
* @returns {number} Score de hover
|
|
123
|
+
*/
|
|
124
|
+
function calculateHoverScore(hoverTime) {
|
|
125
|
+
let level = 'curto';
|
|
126
|
+
let score = ENGAGEMENT_CONFIG.hoverWeights.curto;
|
|
127
|
+
|
|
128
|
+
if (hoverTime >= 3 && hoverTime < 10) {
|
|
129
|
+
level = 'medio';
|
|
130
|
+
score = ENGAGEMENT_CONFIG.hoverWeights.medio;
|
|
131
|
+
} else if (hoverTime >= 10) {
|
|
132
|
+
level = 'longo';
|
|
133
|
+
score = ENGAGEMENT_CONFIG.hoverWeights.longo;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { score, level };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ── Função Principal de Cálculo ──────────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Calcular score de engajamento total (browser-side preliminar)
|
|
143
|
+
* @returns {object} Score, nível, componentes
|
|
144
|
+
*/
|
|
145
|
+
function calculateEngagementScore() {
|
|
146
|
+
// 1. Score de tempo
|
|
147
|
+
const { score: timeScore, level: timeLevel } = calculateTimeScore(engagementState.timeOnPage);
|
|
148
|
+
|
|
149
|
+
// 2. Score de scroll
|
|
150
|
+
const { score: scrollScore } = calculateScrollScore(engagementState.scrollDepth);
|
|
151
|
+
|
|
152
|
+
// 3. Score de cliques (com base na média)
|
|
153
|
+
const clickScore = engagementState.clicksCount > 0
|
|
154
|
+
? calculateClickScore(engagementState.clicksCount, 'generico')
|
|
155
|
+
: 0;
|
|
156
|
+
|
|
157
|
+
// 4. Score de vídeo
|
|
158
|
+
const videoScore = engagementState.videoEngagement;
|
|
159
|
+
|
|
160
|
+
// 5. Score de hover no CTA
|
|
161
|
+
const hoverScore = engagementState.ctaHoverTime > 0
|
|
162
|
+
? calculateHoverScore(engagementState.ctaHoverTime / 1000)
|
|
163
|
+
: 0;
|
|
164
|
+
|
|
165
|
+
// 6. Cálculo ponderado
|
|
166
|
+
const totalScore = (
|
|
167
|
+
(timeScore * 0.3) + // 30% peso para tempo
|
|
168
|
+
(scrollScore * 0.2) + // 20% peso para scroll
|
|
169
|
+
(clickScore * 0.15) + // 15% peso para cliques
|
|
170
|
+
(videoScore * 0.25) + // 25% peso para vídeo
|
|
171
|
+
(hoverScore * 0.1) // 10% peso para hover
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// 7. Nível final de intenção
|
|
175
|
+
let intentionLevel = timeLevel;
|
|
176
|
+
if (totalScore < 1.5) {
|
|
177
|
+
intentionLevel = 'curioso';
|
|
178
|
+
} else if (totalScore < 2.5) {
|
|
179
|
+
intentionLevel = 'interessado';
|
|
180
|
+
} else {
|
|
181
|
+
intentionLevel = 'comprador';
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
totalScore: Math.min(totalScore, 5.0),
|
|
186
|
+
timeScore,
|
|
187
|
+
scrollScore,
|
|
188
|
+
clickScore,
|
|
189
|
+
videoScore,
|
|
190
|
+
hoverScore,
|
|
191
|
+
intentionLevel,
|
|
192
|
+
components: {
|
|
193
|
+
timeOnPage: engagementState.timeOnPage,
|
|
194
|
+
scrollDepth: engagementState.scrollDepth,
|
|
195
|
+
clicksCount: engagementState.clicksCount,
|
|
196
|
+
videoEngagement: engagementState.videoEngagement,
|
|
197
|
+
ctaHoverTime: engagementState.ctaHoverTime
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ── Atualizador de Estado ──────────────────────────────────────────────────────
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Atualizar estado de engajamento
|
|
206
|
+
* @param {string} component - Componente a atualizar
|
|
207
|
+
* @param {any} value - Novo valor
|
|
208
|
+
*/
|
|
209
|
+
function updateEngagementState(component, value) {
|
|
210
|
+
engagementState[component] = value;
|
|
211
|
+
engagementState.lastActivityTime = Date.now();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ── Exportações ─────────────────────────────────────────────────────────────────────
|
|
215
|
+
|
|
216
|
+
export {
|
|
217
|
+
calculateTimeScore,
|
|
218
|
+
calculateScrollScore,
|
|
219
|
+
calculateClickScore,
|
|
220
|
+
calculateVideoScore,
|
|
221
|
+
calculateHoverScore,
|
|
222
|
+
calculateEngagementScore,
|
|
223
|
+
updateEngagementState,
|
|
224
|
+
engagementState,
|
|
225
|
+
ENGAGEMENT_CONFIG
|
|
226
|
+
};
|