1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 | import { boolText, formatDuration } from './session.js?v=20260427c';
export function buildProfile(session) {
const endedAt = session.endedAt || Date.now();
const durationMs = endedAt - session.startedAt;
const accepted = session.behavioral.promptDecisions.filter((decision) => decision.accepted).length;
const segment = buildSegment(session, accepted);
const impressionValue = estimateImpressionValue(session, accepted);
session.profile = {
header: {
sessionId: session.id,
duration: formatDuration(durationMs),
date: new Date(endedAt).toLocaleString(),
},
device: deviceLines(session),
behavioral: behavioralLines(session),
advertising: {
segment,
impressionValue: `$${impressionValue.toFixed(4)} per impression`,
annualValue: `~$${(impressionValue * 80).toFixed(2)}`,
auctionId: `#${String(2000000 + (session.currencies.dataShadow * 791) % 7000000).padStart(7, '0')}`,
},
context: {
dataPoints: countDataPoints(session),
copy: [
`We used ${countDataPoints(session)} data points.`,
'Facebook uses around 52,000.',
'A typical data broker profile contains 1,500+ attributes.',
'Everything collected here lived in this tab.',
'The difference is that we showed you the receipt.',
],
},
callouts: buildCallouts(session, accepted),
};
return session.profile;
}
function deviceLines(session) {
const device = session.device || {};
const geo = session.geo || {};
return {
Browser: device.browser || device.status || 'Unknown',
OS: device.os || 'Unknown',
Screen: device.screen || 'Unknown',
GPU: device.gpu || 'Unknown',
Language: device.language || 'Unknown',
Timezone: device.timezone || 'Unknown',
'Local time': device.localTime || 'Unknown',
Battery: device.battery || 'Unknown',
Connection: device.connection || 'Unknown',
'Dark mode': boolText(device.darkMode),
'Reduced motion': boolText(device.reducedMotion),
Touch: device.touchPoints ? `${device.touchPoints} touch points` : 'No / unknown',
City: geo.city || 'Unknown',
'VPN likely': boolText(geo.vpnLikely),
Incognito: boolText(session.incognito?.detected),
};
}
function behavioralLines(session) {
const consent = session.consentTelemetry;
const promptCopy = session.behavioral.promptDecisions.map((decision) => `${decision.accepted ? 'yes' : 'no'}: ${decision.prompt}`).join(', ') || 'None';
return {
'Cookie consent': `${consent.choice} in ${(consent.decisionMs / 1000).toFixed(1)} seconds`,
'Modal scroll': consent.scrolled ? `${consent.maxScrollDepth}%` : 'Did not scroll',
'Click path': consent.clickPath.map((entry) => entry.label).join(' -> ') || 'None',
'Ad blocker': session.adblock.tested ? boolText(session.adblock.detected) : 'Not tested',
'Do Not Track': session.device.doNotTrack || 'Unknown',
'Prompts': promptCopy,
'Posts / lurks': `${session.behavioral.posts} / ${session.behavioral.lurks}`,
'Doppelgangers': String(session.doppelgangers.length),
'Jumps': String(session.behavioral.jumps),
'Longest idle': `${Math.round(session.behavioral.longestIdleMs / 1000)} seconds`,
'Rage taps': String(session.behavioral.rageTaps),
'Cookies': String(session.currencies.cookies),
'Data Shadow': String(session.currencies.dataShadow),
};
}
function buildSegment(session, accepted) {
const parts = [];
if ((session.device.timezone || '').includes('/')) parts.push('timezone-coded');
if (isLateNight()) parts.push('night owl');
if ((session.device.deviceTier || '').includes('Premium')) parts.push('premium device');
if (accepted >= 3) parts.push('accepts defaults');
if (session.behavioral.purchases.length) parts.push('impulse buyer');
if (session.behavioral.posts > session.behavioral.lurks) parts.push('high engagement');
if (session.device.darkMode) parts.push('dark-mode native');
return parts.length ? titleCase(parts.join(', ')) : 'Low-signal, privacy-conscious, hard to target';
}
function estimateImpressionValue(session, accepted) {
let value = 0.002;
value += accepted * 0.0011;
value += session.behavioral.posts * 0.0004;
value += session.behavioral.purchases.length * 0.0008;
if (session.device.deviceTier?.includes('Premium')) value += 0.0014;
if (session.adblock.detected === false) value += 0.001;
return Math.min(0.018, value);
}
function countDataPoints(session) {
if (!session.consent.analytics) return 6;
const deviceCount = Object.values(session.device || {}).filter((value) => value !== undefined && value !== 'Unknown').length;
const geoCount = session.geo?.status === 'Collected with consent' ? 5 : 0;
const behaviorCount = 9;
return deviceCount + geoCount + behaviorCount;
}
function buildCallouts(session, accepted) {
const callouts = [];
if (session.consentTelemetry.choice === 'Accepted all') {
callouts.push(`You accepted our cookie banner in ${(session.consentTelemetry.decisionMs / 1000).toFixed(1)} seconds. People spend longer choosing a sandwich than deciding who gets their data.`);
}
if (session.adblock.detected === false) {
callouts.push('You played the runner on hard mode without an ad blocker. With one, you would have faced fewer ad obstacles.');
}
if (session.adblock.detected === true) {
callouts.push('Your ad blocker made the marketplace easier. That is not cheating. That is self-defense.');
}
if (session.geo.vpnLikely === true) {
callouts.push('Your location data looked inconsistent. A VPN is a start, but your browser, GPU, screen, timezone, and play style still spoke up.');
}
if (String(session.device.doNotTrack).toLowerCase() === '1') {
callouts.push('You enabled Do Not Track. We treated it as a signal, but most websites treat it as a polite suggestion.');
}
if (isLateNight()) {
callouts.push(`It is ${session.device.localTime || 'late'} where you are. Companies know late-night users make different decisions. You accepted ${accepted} permissions tonight.`);
}
if (session.behavioral.optOutFound) {
callouts.push('You found the opt-out clause. Almost nobody does. In real life, it is buried even deeper.');
}
if (!session.consent.analytics) {
callouts.push('You rejected analytics cookies. We honored that, so most of this receipt is intentionally blank.');
}
return callouts;
}
function isLateNight() {
const hour = new Date().getHours();
return hour < 5 || hour >= 23;
}
function titleCase(value) {
return value.replace(/\b\w/g, (letter) => letter.toUpperCase());
}
|