PageSourceSearch

https://images.nvidia.com/aem-dam/Solutions/ot-js/ot-custom.js

js nvidia.com collected 2026-09-24 08:23:57 UTC 47,041 bytes, 873 lines download raw bytes

1
2const NvCookies = {
3    get(name) {
4        const cookies = document.cookie.split('; ');
5        for (let i = 0; i < cookies.length; i++) {
6            const [key, value] = cookies[i].split('=');
7            if (key === name) {
8                return decodeURIComponent(value);
9            }
10        }
11        return undefined; // Return undefined if the cookie doesn't exist
12    },
13
14    set(name, value, options = {}) {
15        let cookieString = `${name}=${encodeURIComponent(value)}`;
16        if (options.expires) {
17            if (typeof options.expires === 'number') {
18                const date = new Date();
19                date.setTime(date.getTime() + options.expires * 24 * 60 * 60 * 1000);
20                options.expires = date.toUTCString();
21            }
22            cookieString += `; expires=${options.expires}`;
23        }
24        if (options.path) {
25            cookieString += `; path=${options.path}`;
26        }
27        if (options.domain) {
28            cookieString += `; domain=${options.domain}`;
29        }
30        if (options.secure) {
31            cookieString += '; secure';
32        }
33        document.cookie = cookieString;
34    }
35};
36
37
38/* below Event listener checks the loaded in iframe hide the banner */
39window.addEventListener('bannerLoaded', function otcustomcallback() {
40    const banner = document.getElementById('onetrust-consent-sdk');
41    if (window.location !== window.parent.location) {   
42        if (banner) {
43            banner.style.display = 'none';
44        }
45    }
46    /* if user agent contains any AI bot identifier, close the banner WEB0-73354 */
47    if (isAIBotUserAgent()) {
48        if (banner) {
49            banner.style.display = 'none';
50        }
51    }
52
53
54    const translations = {
55        "en": { "done": "Done" },
56        "en-us": { "done": "Done" },
57        "zh-cn": { "done": "完成" },
58        "zh-hans": { "done": "完成" },
59        "zh-hant": { "done": "完成" },
60        "zh-tw": { "done": "完成" },
61        "ja-jp": { "done": "完了する" },
62        "ja": { "done": "完了する" },
63        "ko-kr": { "done": "완료" },
64        "en-in": { "done": "Done" },
65        "en-au": { "done": "Done" },
66        "en-sg": { "done": "Done" },
67        "id-id": { "done": "Selesai" },
68        "th-th": { "done": "เสร็จสิ้น" },
69        "vi-vn": { "done": "done" },
70        "en-ph": { "done": "Done" },
71        "en-my": { "done": "Done" },
72        "en-gb": { "done": "Done" },
73        "cs-cz": { "done": "Hotovo" },
74        "da-dk": { "done": "Udført" },
75        "de-de": { "done": "Fertig" },
76        "es-es": { "done": "Hecho" },
77        "fi-fi": { "done": "Valmis" },
78        "fr-fr": { "done": "Terminé" },
79        "it-it": { "done": "Fine" },
80        "nb-no": { "done": "Ferdig" },
81        "nl-nl": { "done": "Gereed" },
82        "pl-pl": { "done": "Gotowe" },
83        "ro-ro": { "done": "Gata" },
84        "ru-ru": { "done": "Готово" },
85        "sv-se": { "done": "Klart" },
86        "tr-tr": { "done": "Bitti" },
87        "fr-be": { "done": "Terminé" },
88        "de-at": { "done": "Fertig" },
89        "en-eu": { "done": "Done" },
90        "en-me": { "done": "Done" },
91        "es-la": { "done": "Listo" },
92        "pt-br": { "done": "Concluído" }
93    }
94
95    const setNvDone = function () {
96        var acceptbtn = document.getElementById('onetrust-accept-btn-handler');
97        var rejectbtn = document.getElementById('onetrust-reject-all-handler');
98        var btngroup = document.getElementById('onetrust-button-group');
99        var isdoneBtn = document.getElementById('nv-done-btn-handler');
100        var cookiebanner = document.getElementById('onetrust-consent-sdk');
101
102        if (acceptbtn) {
103            acceptbtn.style.display = 'none';
104        }
105        if (rejectbtn) {
106            rejectbtn.style.display = 'none';
107        }
108
109        if (!isdoneBtn) {
110            const lang = document.documentElement.lang.toLowerCase() || 'en';
111            const doneButton = document.createElement('button');
112            doneButton.id = 'nv-done-btn-handler';
113            doneButton.textContent = translations[lang]?.done || translations['en'].done || 'Done';
114            if (btngroup) {
115                document.getElementById('onetrust-button-group').appendChild(doneButton);
116            }
117        }
118        const doneBtnevnt = document.getElementById('nv-done-btn-handler');
119        doneBtnevnt.addEventListener('click', function () {
120            if(cookiebanner) {
121                OneTrust.RejectAll();
122            }
123        });
124
125    };
126
127    /* if gpc enabled then setting the Done button with translations */
128    function isGPCEnabled() {
129        return navigator.globalPrivacyControl === true;
130    }
131
132    if (isGPCEnabled() && !(OneTrust.IsAlertBoxClosed())) {
133        setNvDone();
134    }
135
136    // Function to parse query parameters from URL
137    function getQueryParam(param) {
138        const queryString = window.location.search;
139        const urlParams = new URLSearchParams(queryString);
140        return urlParams.get(param);
141    }
142
143    var manageCookiesLink = document.getElementById("manage-nvcookies-link");
144    if (manageCookiesLink) {
145        manageCookiesLink.addEventListener('click', function () {
146            OneTrust.ToggleInfoDisplay();
147        });
148    }
149
150    var showprefPanel = getQueryParam('manage-cookies');
151    if (showprefPanel === 'true') {
152        setTimeout(function () {
153            OneTrust.ToggleInfoDisplay();
154        }, 1000);
155    }
156
157    /* **************** */
158    function isValidLoginDataAvailable(key) {
159        try {
160            const value = localStorage.getItem(key);
161            if (value) {
162                const item = JSON.parse(value);
163                if (item.expiration) {
164                    const expirationDate = new Date(item.expiration);
165                    const currentDate = new Date();
166                    if (expirationDate > currentDate) {
167                        return item;
168                    } else {
169                        console.log('LocalStorage item has expired.');
170                        localStorage.removeItem(key);
171                        return null;
172                    }
173                } else {
174                    console.log('LocalStorage item does not have an expiration date.');
175                    return item; // Or false, depending on your requirement
176                }
177            } else {
178                return null;
179            }
180        } catch (e) {
181            console.error('Error parsing localStorage item:', e);
182            return null;
183        }
184    }
185
186
187    /* ************ */
188    function preferenceGetRequest(url, headers) {
189        return fetch(url, {
190            method: 'GET',
191            headers: headers,
192            credentials: 'omit'
193        })
194        .then(response => {
195            if (!response.ok) {
196                throw new Error(`HTTP error! status: ${response.status}`);
197            }
198            return response.json();
199        })
200        .catch(error => {
201            console.error('Error in preferenceGetRequest:', error);
202            throw error;
203        });
204    }
205
206    /* ************ */
207
208    function postPreferenceRequest(url, headers, data) {
209        return fetch(url, {
210            method: 'PUT',
211            headers: {
212                ...headers,
213                'Content-Type': 'application/json'
214            },
215            body: JSON.stringify(data),
216            credentials: 'omit',
217            mode: 'cors'
218        })
219        .then(response => {
220            if (!response.ok) {
221                throw new Error(`HTTP error! status: ${response.status}`);
222            }
223            return response.json();
224        })
225        .catch(error => {
226            console.error('Error in postPreferenceRequest:', error);
227            throw error;
228        });
229    }
230
231    function deleteDateProps(obj) {
232        if (obj) {
233            ['createAt', 'updatedAt', 'subscribedAt'].forEach(prop => {
234                if (prop in obj) {
235                    delete obj[prop];
236                }
237            });
238        }
239    }
240    /* ************ */
241    // Helper function to get user email from login data
242    function getUserEmail(loginData) {
243        try {
244            if (loginData && loginData.id_token) {
245                // Decode JWT token to get email
246                const tokenParts = loginData.id_token.split('.');
247                if (tokenParts.length === 3) {
248                    const payload = JSON.parse(atob(tokenParts[1]));
249                    return payload.email || payload.sub || null;
250                }
251            }
252        } catch (e) {
253            console.error('Error extracting email from token:', e);
254        }
255        return null;
256    }
257    
258    // Helper function to check if user has completed action
259    function hasUserCompletedAction(cookieName, currentUserEmail) {
260        const cookieValue = NvCookies.get(cookieName);
261        if (!cookieValue) {
262            return false;
263        }
264        
265        try {
266            const data = JSON.parse(cookieValue);
267            // Check if the stored email matches current user
268            return data.email === currentUserEmail && data.completed === true;
269        } catch (e) {
270            // If parsing fails, treat as old format (just 'true')
271            // Return false to trigger the action again with new format
272            console.log(`Cookie ${cookieName} in old format, will update`);
273            return false;
274        }
275    }
276    
277    // Helper function to set user completed action
278    function setUserCompletedAction(cookieName, userEmail, options = {}) {
279        const data = {
280            email: userEmail,
281            completed: true,
282            timestamp: new Date().toISOString()
283        };
284        NvCookies.set(cookieName, JSON.stringify(data), options);
285    }
286    
287    function checkAndUpdateData() {
288        const isOneTrustClosed = OneTrust.IsAlertBoxClosed();
289
290        if (!isOneTrustClosed) {
291            const validLoginData = isValidLoginDataAvailable('acctFederationData');
292            const gpcEnabled = isGPCEnabled();
293            
294            if (validLoginData && gpcEnabled) {
295                const currentUserEmail = getUserEmail(validLoginData);
296                
297                if (!currentUserEmail) {
298                    console.log('Could not extract user email from login data');
299                    return;
300                }
301                
302                console.log(`Checking preferences for user: ${currentUserEmail}`);
303                
304                // Check if current user has already updated preferences
305                const isPrefUpdated = hasUserCompletedAction('isPrefUpdated', currentUserEmail);
306                
307                if (!isPrefUpdated) {
308                const url = 'https://api-prod.nvidia.com/services/preferences-service/api/v1/users/me/preferences';
309                let headers = {
310                    'idtoken': validLoginData.id_token,
311                    'access-token': validLoginData.access_token,
312                    'X-Client': 'gpc'
313                }
314                preferenceGetRequest(url, headers)
315                    .then(function (data) {
316                        console.log("Preference Data", data);
317
318                        if (data.gpcOverride === null || data.gpcOverride === false) {
319                            if (OneTrust.GetDomainData().ConsentModel.Name === 'opt-out') {
320                                var prefLoginGpc = document.getElementById('nv-pref-login-gpc-text');
321                                var prefLoginGpcOpted = document.getElementById('nv-pref-login-gpc-text-opted');
322                                var gpcText = document.getElementById('nv-gpc-text');
323
324                                if (!data.interestBasedAds) {
325                                    data.interestBasedAds = { 'subscribed': false };
326                                }
327
328                                if (!data.targetedAdsOptIn) {
329                                    data.targetedAdsOptIn = { 'subscribed': false };
330                                }
331
332                                if (data.interestBasedAds.subscribed === true || data.targetedAdsOptIn.subscribed === true) {
333                                    if (gpcText) gpcText.style.display = 'none';
334                                    if (prefLoginGpcOpted) prefLoginGpcOpted.style.display = 'block';
335                                } else {
336                                    if (gpcText) gpcText.style.display = 'none';
337                                    if (prefLoginGpc) prefLoginGpc.style.display = 'block';
338                                }
339                            }
340
341                            data.gpcOverride = true;
342                            data.interestBasedAds.subscribed = false;
343                            data.targetedAdsOptIn.subscribed = false;
344                            let areasOfInterests = data.areasOfInterest.map(area => area.machineName);
345                            data.areasOfInterest = areasOfInterests;
346                            ['developer', 'enterprise', 'startups', 'gaming'].forEach(key => {
347                                deleteDateProps(data[key]);
348                            });
349                            console.log('Updated Data', data);
350                            postPreferenceRequest(url, headers, data)
351                                .then(function (res) {
352                                    // Store preference updated with user email
353                                    setUserCompletedAction('isPrefUpdated', currentUserEmail, { 
354                                        expires: 365,
355                                        path: '/',
356                                        domain: window.location.hostname.includes('.nvidia.com') ? '.nvidia.com' : undefined
357                                    });
358                                    console.log(`Preference updated successfully for user: ${currentUserEmail}`, res);
359                                })
360                                .catch(function (error) {
361                                    console.error("error", error);
362                                });
363                        }
364
365                    })
366                    .catch(function (error) {
367                        console.error("error", error);
368                    });
369            
370                // Call do-not-share API with hCaptcha verification (pass user email)
371                loadHCaptchaAndExecute(currentUserEmail);
372                }
373            }
374        }
375
376    }
377    
378    // Function to dynamically load hCaptcha script and setup container
379    function loadHCaptchaAndExecute(userEmail) {
380        // Check if hCaptcha script already exists
381        const existingScript = document.querySelector('script[src*="hcaptcha.com"]');
382        
383        if (!existingScript) {
384            // Create and append hCaptcha script to head
385            const hcaptchaScript = document.createElement('script');
386            hcaptchaScript.src = 'https://js.hcaptcha.com/1/api.js';
387            hcaptchaScript.async = true;
388            hcaptchaScript.defer = true;
389            
390            // Add onload event to know when script is ready
391            hcaptchaScript.onload = function() {
392                console.log('hCaptcha script loaded successfully');
393                setupContainerAndExecute(userEmail);
394            };
395            
396            hcaptchaScript.onerror = function() {
397                console.error('Failed to load hCaptcha script');
398            };
399            
400            document.head.appendChild(hcaptchaScript);
401            console.log('hCaptcha script added to head');
402        } else {
403            console.log('hCaptcha script already exists');
404            // If script exists, check if hcaptcha is available
405            if (typeof hcaptcha !== 'undefined') {
406                setupContainerAndExecute(userEmail);
407            } else {
408                // Wait for hcaptcha to be available
409                waitForHCaptcha(function() {
410                    setupContainerAndExecute(userEmail);
411                });
412            }
413        }
414    }
415    
416    // Function to setup container and execute hCaptcha
417    function setupContainerAndExecute(userEmail) {
418        // Check if container already exists
419        let hcaptchaContainer = document.getElementById('hcaptcha-container');
420        
421        if (!hcaptchaContainer) {
422            // Create and append hCaptcha container to body
423            hcaptchaContainer = document.createElement('div');
424            hcaptchaContainer.id = 'hcaptcha-container';
425            hcaptchaContainer.style.display = 'none';
426            document.body.appendChild(hcaptchaContainer);
427            console.log('hCaptcha container added to body');
428        } else {
429            console.log('hCaptcha container already exists');
430        }
431        
432        // Wait for hcaptcha to be fully available, then execute
433        waitForHCaptcha(function() {
434            executeWithHCaptcha(userEmail);
435        });
436    }
437    
438    // Function to wait for hCaptcha to be available
439    function waitForHCaptcha(callback) {
440        let attempts = 0;
441        const maxAttempts = 50; // 5 seconds max wait time
442        
443        const checkHCaptcha = setInterval(function() {
444            attempts++;
445            
446            if (typeof hcaptcha !== 'undefined') {
447                clearInterval(checkHCaptcha);
448                console.log('hCaptcha is ready');
449                callback();
450            } else if (attempts >= maxAttempts) {
451                clearInterval(checkHCaptcha);
452                console.error('hCaptcha failed to load after 5 seconds');
453            }
454        }, 100); // Check every 100ms
455    }
456    
457    // Function to execute hCaptcha and call do-not-share API
458    function executeWithHCaptcha(userEmail) {
459        const hCaptchaSiteKey = '77d885a8-5f36-43b2-96cc-76d21266da74';
460        
461        // Check if hcaptcha is loaded
462        if (typeof hcaptcha === 'undefined') {
463            console.error('hCaptcha library not loaded');
464            return;
465        }
466        
467        // Render invisible hCaptcha
468        const widgetId = hcaptcha.render('hcaptcha-container', {
469            sitekey: hCaptchaSiteKey,
470            size: 'invisible',
471            callback: function(token) {
472                // This callback is triggered when hCaptcha is solved
473                console.log('hCaptcha token received');
474                callDoNotShareAPI(token, hCaptchaSiteKey, userEmail);
475            },
476            'error-callback': function(error) {
477                console.error('hCaptcha error:', error);
478            },
479            'expired-callback': function() {
480                console.warn('hCaptcha token expired');
481            }
482        });
483        
484        // Execute the invisible hCaptcha
485        hcaptcha.execute(widgetId);
486    }
487    
488    // Function to call do-not-share API with hCaptcha token
489    function callDoNotShareAPI(hCaptchaToken, hCaptchaSiteKey, userEmail) {
490        const validLoginData = isValidLoginDataAvailable('acctFederationData');
491        
492        if (!validLoginData) {
493            console.error('No valid login data available');
494            return;
495        }
496        
497        const doNotShareUrl = 'https://api-prod.nvidia.com/services/voltron/v1/user/do-not-share';
498        const doNotShareHeaders = {
499            'Content-Type': 'application/json'
500        };
501        const doNotShareData = {
502            'hCaptchaResponse': hCaptchaToken,
503            'idtoken': validLoginData.id_token,
504            'source': hCaptchaSiteKey
505        };
506        
507        postDoNotShareRequest(doNotShareUrl, doNotShareHeaders, doNotShareData)
508            .then(function (res) {
509                console.log(`Do-not-share preference updated successfully for user: ${userEmail}`, res);
510                // Show success modal with user email
511                showDoNotShareSuccessModal(userEmail);
512                OneTrust.RejectAll();
513            })
514            .catch(function (error) {
515                console.error('Error updating do-not-share preference', error);
516            });
517    }
518    
519    // Add new function to handle do-not-share API call
520    function postDoNotShareRequest(url, headers, data) {
521        return fetch(url, {
522            method: 'POST',
523            headers: {
524                ...headers,
525                'Content-Type': 'application/json'
526            },
527            body: JSON.stringify(data),
528            credentials: 'omit',
529            mode: 'cors'
530        })
531        .then(response => {
532            if (!response.ok) {
533                throw new Error(`HTTP error! status: ${response.status}`);
534            }
535            // Hide banner on success
536            const banner = document.getElementById('onetrust-consent-sdk');
537            if (banner) {
538                banner.style.display = 'none';
539            }
540            return response.json();
541        })
542        .catch(error => {
543            console.error('Error in postDoNotShareRequest:', error);
544            throw error;
545        });
546    }
547
548    // Function to create and show success modal
549    function showDoNotShareSuccessModal(userEmail) {
550        // Check if current user has already seen the modal
551        const hasSeenModal = hasUserCompletedAction('doNotShareModalShown', userEmail);
552        if (hasSeenModal) {
553            console.log(`User ${userEmail} has already seen the do-not-share success modal`);
554            return;
555        }
556
557        // Get current language from HTML lang attribute
558        const currentLang = document.documentElement.lang || 'en-us';
559        
560        // Translations for modal content
561        const translations = {
562            'cs-cz': {
563                title: 'Success!',
564                message: 'Nyní jste odhlášeni z „prodeje“ a „sdílení“ osobních údajů (získaných jinak než prostřednictvím souborů cookie) pro účely zájmově orientované reklamy. Chcete-li vyjádřit výslovný nesouhlas s „prodejem“ a „sdílením“ osobních údajů pro účely zájmově orientované reklamy prostřednictvím souborů cookie a dalších sledovacích technologií, aktualizujte <a href="https://www.nvidia.com/cs-cz/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Nastavení souborů cookie</a>.'
565            },
566            'da-dk': {
567                title: 'Success!',
568                message: 'Du har nu fravalgt "salg" og "deling" af ikke-cookiebaserede personlige oplysninger til interessebaserede reklameformål. For at fravælge "salg" og "deling" af personlige oplysninger til interessebaserede reklameformål via cookies og andre sporingsteknologier, skal du opdatere din <a href="https://www.nvidia.com/da-dk/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookieindstillinger</a>.'
569            },
570            'de-de': {
571                title: 'Success!',
572                message: 'Ihre personenbezogenen Daten, die nicht mit Cookies erfasst werden, sind nun vom „Verkauf“ und der „Weitergabe“ für interessenbezogene Werbezwecke ausgeschlossen. Um den „Verkauf“ und die „Weitergabe“ personenbezogener Daten für interessenbezogene Werbezwecke durch Cookies und andere Tracking-Technologien abzulehnen, aktualisieren Sie bitte Ihre <a href="https://www.nvidia.com/de-de/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie-Einstellungen</a>.'
573            },
574            'en-gb': {
575                title: 'Success!',
576                message: 'You are now opted out of non-cookie personal data "sales" and "sharing" for interest-based advertising purposes. To opt out of personal data "sales" and "sharing" for interest-based advertising purposes through cookies and other tracking technologies, please update your <a href="https://www.nvidia.com/en-gb/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a>.'
577            },
578            'en-in': {
579                title: 'Success!',
580                message: 'You are now opted out of non-cookie personal data "sales" and "sharing" for interest-based advertising purposes. To opt out of personal data "sales" and "sharing" for interest-based advertising purposes through cookies and other tracking technologies, please update your <a href="https://www.nvidia.com/en-in/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a>.'
581            },
582            'en-au': {
583                title: 'Success!',
584                message: 'You are now opted out of non-cookie personal data "sales" and "sharing" for interest-based advertising purposes. To opt out of personal data "sales" and "sharing" for interest-based advertising purposes through cookies and other tracking technologies, please update your <a href="https://www.nvidia.com/en-au/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a>.'
585            },
586            'en-sg': {
587                title: 'Success!',
588                message: 'You are now opted out of non-cookie personal data "sales" and "sharing" for interest-based advertising purposes. To opt out of personal data "sales" and "sharing" for interest-based advertising purposes through cookies and other tracking technologies, please update your <a href="https://www.nvidia.com/en-sg/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a>.'
589            },
590            'en-eu': {
591                title: 'Success!',
592                message: 'You are now opted out of non-cookie personal data "sales" and "sharing" for interest-based advertising purposes. To opt out of personal data "sales" and "sharing" for interest-based advertising purposes through cookies and other tracking technologies, please update your <a href="https://www.nvidia.com/en-eu/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a>.'
593            },
594            'en-us': {
595                title: 'Success!',
596                message: 'You are now opted out of non-cookie personal data "sales" and "sharing" for interest-based advertising purposes. To opt out of personal data "sales" and "sharing" for interest-based advertising purposes through cookies and other tracking technologies, please update your <a href="https://www.nvidia.com/en-us
596/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a>.'
597            },
598            'es-es': {
599                title: 'Success!',
600                message: 'Ahora mismo está de baja en el “uso compartido” y “venta” de datos personales distintos de cookies para fines de publicidad basada en intereses. Para darse de baja en el “uso compartido” y “venta” de datos personales para fines de publicidad basada en intereses a través de cookies y otras tecnologías de seguimiento, actualice su <a href="https://www.nvidia.com/es-es/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Configuración de cookies</a>.'
601            },
602            'fi-fi': {
603                title: 'Success!',
604                message: 'Olet nyt kieltäytynyt henkilötietojen "myynnistä" ja "jakamisesta" kiinnostuksen kohteisiin perustuvassa mainonnassa, jossa ei käytetä evästeitä. Jos haluat kieltäytyä henkilötietojen "myynnistä" ja "jakamisesta" kiinnostuksen kohteisiin liittyvässä mainonnassa evästeiden ja muiden seurantatekniikoiden avulla, päivitä <a href="https://www.nvidia.com/fi-fi/about-nvidia/cookie-policy/#choices" target="_blank" style="color: #76b900; text-decoration: none; font-weight: 500;">Evästeasetukset</a>.'
605            },
606            'fr-fr': {
607                title: 'Success!',
608                message: 'La vente et le partage des données personnelles non liées aux cookies à des fins de publicité ciblée par centres d\'intérêt ont été désactivés pour votre compte. Pour désactiver la vente et le partage des données personnelles à des fins de publicité ciblée par centres d\'intérêt par le biais de cookies et d’autres technologies de suivi, veuillez mettre à jour votre <a href="https://www.nvidia.com/fr-fr/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Paramètres des cookies</a>.'
609            },
610            'id-id': {
611                title: 'Success!',
612                message: 'Anda sekarang tidak ikut serta dalam “penjualan” dan “pembagian” data pribadi non-cookie untuk tujuan periklanan berbasis minat. Untuk tidak ikut serta dalam “penjualan” dan “pembagian” data pribadi untuk tujuan periklanan berbasis minat melalui cookie dan teknologi pelacakan lainnya, perbarui <a href="https://www.nvidia.com/id-id/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a> Anda.'
613            },
614            'it-it': {
615                title: 'Success!',
616                message: 'Hai revocato il consenso alla "vendita" e alla "condivisione" di dati personali non cookie per scopi pubblicitari basati sugli interessi. Per revocare il consenso alla “vendita” e alla “condivisione” dei dati personali per scopi pubblicitari basati sugli interessi tramite cookie e altre tecnologie di tracciamento, aggiorna <a href="https://www.nvidia.com/it-it/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Impostazioni dei cookie</a>.'
617            },
618            'ja-jp': {
619                title: 'Success!',
620                message: 'あなたはこれで、興味に基づいた広告目的の個人データ (クッキーを除く) の「販売」および「共有」からオプトアウトしたことになります。 クッキーやその他の追跡技術による興味に基づく広告目的の個人データの「販売」および「共有」をオプトアウトするには、<a href="https://www.nvidia.com/ja-jp/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie の設定</a> を更新してください。'
621            },
622            'ko-kr': {
623                title: 'Success!',
624                message: '관심사 기반 광고 목적으로 비 쿠키 개인 데이터를 "판매" 및 "공유"하는 것이 거부되었습니다. 쿠키 및 기타 추적 기술을 통한 관심사 기반 광고 목적으로 개인 데이터를 "판매" 및 "공유"하는 것을 거부하려면 <a href="https://www.nvidia.com/ko-kr/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">개인정보 선호 센터</a>을 업데이트하십시오.'
625            },
626            'nb-no': {
627                title: 'Success!',
628                message: 'Du har nå valgt bort «salg» og «deling» av personopplysninger for interessebaserte annonser. Hvis du vil velge bort «salg» og «deling» av personopplysninger for interessebaserte annonser gjennom informasjonskapsler og andre sporingsteknologier, må du oppdatere <a href="https://www.nvidia.com/nb-no/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Innstillinger for informasjonskapsler</a>.'
629            },
630            'nl-nl': {
631                title: 'Success!',
632                message: 'Je bent nu afgemeld voor de \'verkoop\' en het \'delen\' van persoonlijke gegevens zonder cookies voor op interesses gebaseerde reclamedoeleinden. Om je af te melden voor de \'verkoop\' en het \'delen\' van persoonlijke gegevens voor op interesses gebaseerde advertentiedoeleinden via co
632okies en andere trackingtechnologieën, moet je je <a href="https://www.nvidia.com/nl-nl/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie-instellingen</a> bijwerken.'
633            },
634            'pl-pl': {
635                title: 'Success!',
636                message: 'Zrezygnowano z wykorzystania plików cookie do „sprzedaży” i „udostępniania” danych osobowych w celach reklamowych opartych na zainteresowaniach. Aby zrezygnować z wykorzystywania plików cookie i innych technologii monitorowania do „sprzedaży” i „udostępniania” danych osobowych w celach reklamowych opartych na zainteresowaniach, należy zaktualizować <a href="https://www.nvidia.com/pl-pl/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Ustawienia plików cookie</a>.'
637            },
638            'pt-pt': {
639                title: 'Success!',
640                message: 'Agora, desativou a “venda” e a “partilha” de dados pessoais não relacionados com cookies para fins de publicidade baseada em interesses. Para desativar a “venda” e a “partilha” de dados pessoais para fins de publicidade baseada em interesses através de cookies e outras tecnologias de monitorização, atualize o seu <a href="https://www.nvidia.com/pt-pt/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a>.'
641            },
642            'ro-ro': {
643                title: 'Success!',
644                message: 'Acum ai renunțat la „vânzarea” și „partajarea” datelor cu caracter personal în scopuri de publicitate bazată pe interese care nu se livrează prin intermediul cookie-urilor. Pentru renunța la „vânzarea” și „partajarea” datelor cu caracter personal în scopuri de publicitate bazată pe interese prin intermediul cookie-urilor și al altor tehnologii de monitorizare, actualizează <a href="https://www.nvidia.com/ro-ro/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Setări cookie-uri</a>.'
645            },
646            'sv-se': {
647                title: 'Success!',
648                message: 'Du har nu valt bort "försäljning" och "delning" av personuppgifter som inte är cookies för intressebaserade annonseringsändamål. För att välja bort "försäljning" och "delning" av personuppgifter för intressebaserade annonseringsändamål via cookies och annan spårningsteknik, uppdatera din <a href="https://www.nvidia.com/sv-se/about-nvidia/cookie-policy/#choices" id="openCookieSettings" target="_blank" style="color: #76b900; text-decoration: none; font-weight: 500;">Inställningar för cookies</a>.'
649            },
650            'th-th': {
651                title: 'Success!',
652                message: 'คุณได้ยก้เลิกการขายและการแบ่งปันข้อมูลส่วนบุคคลที่ไม่ใช่คุกกี้สําหรับวัตถุประสงค์การโฆษณาตามความสนใจแล้ว หากต้องการยกเลิกการขายและการแบ่งปันข้อมูลส่วนบุคคลเพื่อวัตถุประสงค์การโฆษณาตามความสนใจผ่านคุกกี้และเทคโนโลยีการติดตามอื่น ๆ โปรดอัปเดต <a href="https://www.nvidia.com/th-th/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a> ของคุณ'
653            },
654            'tr-tr': {
655                title: 'Success!',
656                message: 'Artık ilgi alanlarına dayalı reklamcılık amaçları için çerez dışı kişisel veri "satışını" ve "paylaşımını" devre dışı bıraktınız. Çerezler ve diğer izleme teknolojileri aracılığıyla ilgi alanlarına dayalı reklamcılık amaçları için kişisel veri "satışını" ve "paylaşımını" devre dışı bırakmak için lütfen <a href="https://www.nvidia.com/tr-tr/about-nvidia/cookie-policy/#choices" id="openCookieSettings" target="_blank" style="color: #76b900; text-decoration: none; font-weight: 500;">Çerez Ayarları</a> güncelleyin.'
657            },
658            'uk-ua': {
659                title: 'Success!',
660                message: 'Тепер ви відмовляєтеся від персональних даних щодо «продажу» та «поширення», не пов\'язаних з файлами cookie, з метою реклами Ð
660½Ð° основі вподобань. Щоб відмовитися від персональних даних щодо «продажу» та «поширення» з метою реклами на основі вподобань за допомогою файлів cookie та інших технологій відстеження, оновіть свої налаштування <a href="https://www.nvidia.com/uk-ua/about-nvidia/cookie-policy/#choices" id="openCookieSettings" target="_blank" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a>.'
661            },
662            'vi-vn': {
663                title: 'Success!',
664                message: 'Hiện bạn đã từ chối "bán" và "chia sẻ" dữ liệu cá nhân không phải cookie cho mục đích quảng cáo dựa trên sở thích. Để từ chối "bán" và "chia sẻ" dữ liệu cá nhân cho mục đích quảng cáo dựa trên sở thích thông qua cookie và các công nghệ theo dõi khác, vui lòng cập nhật <a href="https://www.nvidia.com/vi-vn/about-nvidia/cookie-policy/#choices" id="openCookieSettings" target="_blank" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a> của bạn.'
665            },
666            'zh-tw': {
667                title: 'Success!',
668                message: '你現在已停止透過 Cookie「銷售」和「共享」個人資料來用於興趣導向廣告。 如要停止透過 Cookie 和其他追蹤技術「銷售」和「共享」個人資料來用於興趣導向廣告,請更新你的 <a href="https://www.nvidia.com/zh-tw/about-nvidia/cookie-policy/#choices" id="openCookieSettings" target="_blank" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie 設定</a>。'
669            },
670            'es-la': {
671                title: 'Success!',
672                message: 'You are now opted out of non-cookie personal data "sales" and "sharing" for interest-based advertising purposes. To opt out of personal data "sales" and "sharing" for interest-based advertising purposes through cookies and other tracking technologies, please update your <a href="https://www.nvidia.com/es-la/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a>.'
673            },
674            'pt-br': {
675                title: 'Success!',
676                message: 'You are now opted out of non-cookie personal data "sales" and "sharing" for interest-based advertising purposes. To opt out of personal data "sales" and "sharing" for interest-based advertising purposes through cookies and other tracking technologies, please update your <a href="https://www.nvidia.com/pt-br/about-nvidia/cookie-policy/#choices" target="_blank" id="openCookieSettings" style="color: #76b900; text-decoration: none; font-weight: 500;">Cookie Settings</a>.'
677            }
678        };
679        
680        // Get translation for current language, fallback to en-us if not found
681        const t = translations[currentLang] || translations['en-us'];
682        
683        console.log(`Do-not-share modal using language: ${currentLang}`);
684
685        // Create modal HTML
686        const modalHTML = `
687            <div id="doNotShareModal" style="
688                display: flex;
689                position: fixed;
690                z-index: 10000;
691                left: 0;
692                top: 0;
693                width: 100%;
694                height: 100%;
695                background-color: rgba(0,0,0,0.5);
696                justify-content: center;
697                align-items: center;
698                ">
699                <div style="
700                    background-color: #ffffff;
701                    padding: 32px;
702                    border-radius: 8px;
703                    max-width: 500px;
704                    width: 90%;
705                    position: relative;
706                    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
707                ">
708                    <button 
709                        id="closeDoNotShareModal" 
710                        style="
711                        position: absolute; 
712                        top: 16px; 
713                        right: 16px;
714                        background: transparent;
715                        border: none;
716                        font-size: 28px;
717                        cursor: pointer;">
718                            <span class="fa-light fa-xmark"></span>
719                    </button>
720                    <p style="
721                        margin: 0;
722                        font-size: 28px;
723                        font-weight: 600;
724                        color: #000;
725                    ">${t.title}</p>
726                    <p style="
727                        margin: 0 0 16px 0;
728                        font-size: 15px;
729                        line-height: 1.6;
730                        color: #333;
731                    ">
732                        ${t.message}
733                    </p>
734                </div>
735            </div>
736        `;
737
738        // Insert modal into body
739        document.body.insertAdjacentHTML('beforeend', modalHTML);
740
741        // Get modal element
742        const modal = document.getElementById('doNotShareModal');
743        const closeBtn = document.getElementById('closeDoNotShareModal');
744        const cookieSettingsLink = document.getElementById('openCookieSettings');
745
746        // Close modal function
747        function closeModal() {
748            if (modal) {
749                modal.style.display = 'none';
750                modal.remove();
751            }
752            // Store modal shown with user email (expires in 1 year)
753            setUserCompletedAction('doNotShareModalShown', userEmail, { 
754                expires: 365, 
755                path: '/',
756                domain: window.location.hostname.includes('.nvidia.com') ? '.nvidia.com' : undefined
757            });
758            console.log(`Modal shown recorded for user: ${userEmail}`);
759            OneTrust.RejectAll();
760        }
761
762        // Close button event
763        if (closeBtn) {
764            closeBtn.addEventListener('click', closeModal);
765        }
766
767        // Close when clicking outside modal
768        modal.addEventListener('click', function(e) {
769            if (e.target === modal) {
770                closeModal();
771            }
772        });
773
774        // Cookie Settings link event
775        //if (cookieSettingsLink) {
776        //    cookieSettingsLink.addEventListener('click', function(e) {
777        //        e.preventDefault();
778        //        closeModal();
779        //    });
780        //}
781
782        // Close on ESC key
783        document.addEventListener('keydown', function(e) {
784            if (e.key === 'Escape' && modal) {
785                closeModal();
786            }
787        });
788    }
789
790    checkAndUpdateData();
791
792}, false);
793
794
795/**
796 * Event listener to log the consent applied event for 
797 * checking the page refresh after consent applied
798 */
799window.addEventListener("OTConsentApplied", event => { 
800    console.log("The user has updated their consent."); 
801    console.log(`New consent states: ${OnetrustActiveGroups}`); 
802});
803
804/**
805 * Function to identify if user agent contains any AI bot identifiers
806 * @returns {boolean} True if user agent contains AI bot identifier, false otherwise
807 */
808function isAIBotUserAgent() {
809    const userAgent = navigator.userAgent;
810
811    const aiBotIdentifiers = [
812      "GPTBot/1.0",
813      "GPTBot/1.1",
814      "GPTBot/1.2",
815      "OAI-SearchBot/1.0",
816      "ChatGPT-User/1.0",
817      "ChatGPT-User/2.0",
818      "ClaudeBot",
819      "ClaudeBot/1.0",
820      "claude-web",
821      "claude-web/1.0",
822      "Claude-SearchBot",
823      "Claude/1.0",
824      "Claude-User",
825      "Anthropic-ai",
826      "PerplexityBot",
827      "Perplexity",
828      "Perplexity-User",
829      "ChatGLM-Spider/1.0",
830      "Cohere-ai/1.0",
831      "Phindbot.1.0",
832      "PoeBot",
833      "Tongyibot/1.0",
834      "Yanbaobot/1.0",
835      "DeepseekBot/1.0",
836      "Deepseek/1.0",
837      "DeepSeek Chat",
838      "MetaAIbot",
839      "Meta-externalagent",
840      "Meta-ExternalFetcher",
841      "Meta-llama",
842      "Gemini-Deep-Research",
843      "Gemini-User",
844      "Deepseek-desktop",
845      "GoogleAgent-Mariner",
846      "NovaAct",
847      "ChatGPT Agent",
848      "Bedrock-bot",
849      "Devin",
850      "AI2bot",
851      "Applebot-extended",
852      "BytespiderBot",
853      "CCBot",
854      "Cotoyogi",
855      "DuckAssistBot",
856      "Google-extended",
857      "Iaskspider",
858      "iaskbot",
859      "ICC-Crawler",
860      "LinerBot",
861      "MistralAI-User",
862      "PanguBot",
863      "cohere-ai/1.0",
864      "anthropic-ai/1.0",
865      "Bytespider/1.0",
866      "TongyiBot/1.0",
867      "YanbaoBot/1.0"
868    ];
869    
870    return aiBotIdentifiers.some(identifier => 
871        userAgent.includes(identifier)
872    );
873}

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.