PageSourceSearch

https://www.ohlalafrenchcourse.com/fr/assets/js/attribution.js

js ohlalafrenchcourse.com collected 2026-10-10 01:43:37 UTC 6,009 bytes, 204 lines download raw bytes

1(function () {
2  const STORAGE_KEY = 'ohlala_attribution';
3  const TTL_MS = 90 * 24 * 60 * 60 * 1000;
4  const QUERY_KEYS = [
5    'utm_source',
6    'utm_medium',
7    'utm_campaign',
8    'utm_content',
9    'utm_term',
10    'fbclid',
11    'gclid',
12    'ci',
13    't1',
14    't2',
15    'ai',
16    'psource',
17    'source'
18  ];
19
20  function compact(object) {
21    return Object.keys(object).reduce((memo, key) => {
22      const value = object[key];
23      if (value !== null && value !== undefined && value !== '') {
24        memo[key] = value;
25      }
26      return memo;
27    }, {});
28  }
29
30  function readCookie(name) {
31    const value = `; ${document.cookie}`;
32    const parts = value.split(`; ${name}=`);
33    if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
34    return null;
35  }
36
37  function cookieDomainAttribute() {
38    const hostname = window.location.hostname;
39    if (!hostname || hostname === 'localhost' || /^\d+\.\d+\.\d+\.\d+$/.test(hostname)) return '';
40
41    const parts = hostname.split('.');
42    if (parts.length < 2) return '';
43
44    return `; domain=.${parts.slice(-2).join('.')}`;
45  }
46
47  function writeCookie(name, value) {
48    const expires = new Date(Date.now() + TTL_MS).toUTCString();
49    document.cookie = `${name}=${encodeURIComponent(value)}; path=/; expires=${expires}; SameSite=Lax${cookieDomainAttribute()}`;
50  }
51
52  function queryValues(params) {
53    return QUERY_KEYS.reduce((memo, key) => {
54      const value = params.get(key);
55      if (value) memo[key] = value;
56      return memo;
57    }, {});
58  }
59
60  function readStore() {
61    try {
62      const stored = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
63      if (!stored.expires_at || stored.expires_at < Date.now()) return {};
64      return stored;
65    } catch (_error) {
66      return {};
67    }
68  }
69
70  function writeStore(store) {
71    localStorage.setItem(STORAGE_KEY, JSON.stringify({
72      ...store,
73      expires_at: Date.now() + TTL_MS
74    }));
75  }
76
77  function ensureFbc(params) {
78    const fbc = readCookie('_fbc');
79    if (fbc) return fbc;
80
81    const fbclid = params.get('fbclid');
82    if (!fbclid) return null;
83
84    const generatedFbc = `fb.1.${Date.now()}.${fbclid}`;
85    writeCookie('_fbc', generatedFbc);
86    return generatedFbc;
87  }
88
89  function gaClientId() {
90    const ga = readCookie('_ga');
91    if (!ga) return null;
92
93    const parts = ga.split('.');
94    return parts.length >= 4 ? parts.slice(-2).join('.') : ga;
95  }
96
97  function currentTouch(params) {
98    const query = queryValues(params);
99
100    return compact({
101      ...query,
102      psource: query.psource || query.source,
103      landing_page: window.location.href,
104      page_location: window.location.href,
105      referrer: document.referrer,
106      captured_at: new Date().toISOString()
107    });
108  }
109
110  function capture() {
111    const params = new URLSearchParams(window.location.search);
112    const stored = readStore();
113    const touch = currentTouch(params);
114    const fbc = ensureFbc(params);
115    const fbp = readCookie('_fbp');
116
117    const nextStore = {
118      first_touch: stored.first_touch || touch,
119      last_touch: touch
120    };
121    writeStore(nextStore);
122
123    const affiliateId = params.get('ai') || touch.ai || nextStore.first_touch.ai;
124    if (affiliateId) localStorage.setItem('affiliate_id', affiliateId);
125    if (fbc) window.FBC = fbc;
126    if (fbp) window.FBP = fbp;
127
128    return nextStore;
129  }
130
131  function getPayload() {
132    const params = new URLSearchParams(window.location.search);
133    const stored = readStore();
134    const firstTouch = stored.first_touch || {};
135    const lastTouch = stored.last_touch || currentTouch(params);
136    const fbc = readCookie('_fbc') || window.FBC;
137    const fbp = readCookie('_fbp') || window.FBP;
138
139    return compact({
140      utm_source: lastTouch.utm_source || firstTouch.utm_source,
141      utm_medium: lastTouch.utm_medium || firstTouch.utm_medium,
142      utm_campaign: lastTouch.utm_campaign || firstTouch.utm_campaign,
143      utm_content: lastTouch.utm_content || firstTouch.utm_content,
144      utm_term: lastTouch.utm_term || firstTouch.utm_term,
145      fbclid: lastTouch.fbclid || firstTouch.fbclid,
146      gclid: lastTouch.gclid || firstTouch.gclid,
147      fbc: fbc,
148      fbp: fbp,
149      landing_page: firstTouch.landing_page || lastTouch.landing_page,
150      page_location: window.location.href,
151      referrer: firstTouch.referrer || lastTouch.referrer || document.referrer,
152      first_touch: firstTouch,
153      last_touch: lastTouch,
154      psource: lastTouch.psource || firstTouch.psource,
155      affiliate: compact({
156        ai: lastTouch.ai || firstTouch.ai || localStorage.getItem('affiliate_id'),
157        ci: lastTouch.ci || firstTouch.ci,
158        t1: lastTouch.t1 || firstTouch.t1,
159        t2: lastTouch.t2 || firstTouch.t2
160      }),
161      client_id: gaClientId()
162    });
163  }
164
165  function appendToUrl(url) {
166    const payload = getPayload();
167
168    ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term', 'fbclid', 'gclid', 'fbc', 'fbp', 'psource', 'client_id'].forEach((key) => {
169      if (payload[key]) url.searchParams.set(key, payload[key]);
170    });
171
172    if (payload.affiliate) {
173      if (payload.affiliate.ai) url.searchParams.set('ai', payload.affiliate.ai);
174      if (payload.affiliate.ci) url.searchParams.set('ci', payload.affiliate.ci);
175      if (payload.affiliate.t1) url.searchParams.set('t1', payload.affiliate.t1);
176      if (payload.affiliate.t2) url.searchParams.set('t2', payload.affiliate.t2);
177    }
178
179    return url;
180  }
181
182  function mergeIntoPayload(data) {
183    return {
184      ...data,
185      attribution: getPayload()
186    };
187  }
188
189  capture();
190
191  window.OhlalaAttribution = {
192    appendToUrl: appendToUrl,
193    getAffiliateId: function () {
194      return getPayload().affiliate && getPayload().affiliate.ai;
195    },
196    getPayload: getPayload,
197    getParams: getPayload,
198    mergeIntoPayload: mergeIntoPayload
199  };
200
201  window.getAffiliateIdFromStorage = window.getAffiliateIdFromStorage || function () {
202    return localStorage.getItem('affiliate_id');
203  };
204})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.