Duolingo PRO

The fastest Duolingo XP gainer, working as of November 2025.

Size

389.9 KB

Version

3.1BETA.03

Created

Nov 29, 2025

Updated

3 months ago

1// ==UserScript==
2// @name         Duolingo PRO
3// @namespace    https://duolingopro.net
4// @version      3.1BETA.03
5// @description  The fastest Duolingo XP gainer, working as of November 2025.
6// @author       anonymousHackerIV
7// @match        https://*.duolingo.com/*
8// @match        https://*.duolingo.cn/*
9// @icon         https://www.duolingopro.net/static/favicons/duo/128/light/primary.png
10// @grant        GM_log
11// @antifeature  payment
12// @downloadURL https://update.greasyfork.org/scripts/473310/Duolingo%20PRO.user.js
13// @updateURL https://update.greasyfork.org/scripts/473310/Duolingo%20PRO.meta.js
14// ==/UserScript==
15
16let storageLocal;
17let storageSession;
18let versionNumber = "05";
19let storageLocalVersion = "05";
20let storageSessionVersion = "05";
21let versionName = "BETA.03";
22let versionFull = "3.1BETA.03";
23let versionFormal = "3.1 BETA.03";
24let serverURL = "https://www.duolingopro.net";
25let apiURL = "https://api.duolingopro.net";
26let greasyfork = true;
27let alpha = false;
28
29let hidden = false;
30let lastPage;
31let currentPage = 1;
32let windowBlurState = true;
33
34let solvingIntervalId;
35let isAutoMode;
36let findReactMainElementClass = '_3yE3H';
37let reactTraverseUp = 1;
38
39const debug = false;
40const flag01 = false;
41const flag02 = false;
42const flag03 = false;
43
44// USAGE OR MODIFICATION OF THIS SCRIPT IMPLIES YOU AGREE TO THE TERMS AND CONDITIONS PRESENTED IN THE SCRIPT. IF YOU DO NOT AGREE, DO NOT USE OR MODIFY THIS SCRIPT.
45
46(function buildOrMigrateStorageLocal() {
47    let tempRandom16 = Array.from({ length: 16 }, () => 'abcdefghijklmnopqrstuvwxyz0123456789'[Math.floor(Math.random() * 36)]).join('');
48    let tempTimestamp = Date.now();
49
50    const DEFAULTS = {
51        version: versionNumber,
52        terms: "00",
53        random16: tempRandom16,
54        pins: {
55            home: ["DLP_Get_XP_1_ID", "DLP_Get_GEM_1_ID"],
56            legacy: ["DLP_Get_PATH_1_ID", "DLP_Get_PRACTICE_1_ID"]
57        },
58        settings: {
59            autoUpdate: !greasyfork,
60            showSolveButtons: true,
61            showAutoServerButton: alpha,
62            muteLessons: false,
63            anonymousUsageData: alpha,
64            solveSpeed: 0.9
65        },
66        stats: {
67            modern: {
68                xp: 0,
69                gem: 0,
70                streak: 0,
71                super: 0,
72                heart_refill: 0,
73                streak_freeze: 0,
74                double_xp_boost: 0
75            },
76            legacy: {
77                path: {
78                    lessons: 0,
79                    questions: 0
80                },
81                practice: {
82                    lessons: 0,
83                    questions: 0
84                },
85                listen: {
86                    lessons: 0,
87                    questions: 0
88                },
89                lesson: {
90                    lessons: 0,
91                    questions: 0
92                }
93            },
94            tracking_since: tempTimestamp
95        },
96        chats: [],
97        notifications: [{ id: "0000" }],
98        tips: { seeMore1: false },
99        languagePackVersion: "00",
100        onboarding: false,
101        storageVersion: storageLocalVersion
102    };
103
104    function isPlainObject(v) {
105        return Object.prototype.toString.call(v) === "[object Object]";
106    }
107    function safeParse(json) {
108        try {
109            const v = JSON.parse(json);
110            return isPlainObject(v) ? v : null;
111        } catch {
112            return null;
113        }
114    }
115
116    function mergeWithPrune(existing, defaults) {
117        const result = Array.isArray(defaults) ? [] : {};
118        for (const key of Object.keys(defaults)) {
119            const defVal = defaults[key];
120            const hasExisting = existing && Object.prototype.hasOwnProperty.call(existing, key);
121            const exVal = hasExisting ? existing[key] : undefined;
122
123            if (isPlainObject(defVal)) {
124            if (isPlainObject(exVal)) {
125                result[key] = mergeWithPrune(exVal, defVal);
126            } else {
127                result[key] = mergeWithPrune({}, defVal); // take full default subtree
128            }
129            } else if (Array.isArray(defVal)) {
130                result[key] = Array.isArray(exVal) ? exVal : defVal.slice();
131            } else {
132                // primitives / everything else: keep existing if present, else default
133                result[key] = hasExisting ? exVal : defVal;
134            }
135        }
136        // Unknown keys in `existing` are intentionally NOT copied (pruned)
137        return result;
138    }
139
140    const raw = localStorage.getItem("DLP_Local_Storage");
141    const existing = safeParse(raw);
142
143    // Migrate: replace old "DLP_Get_GEMS_1_ID" pin with new "DLP_Get_GEM_1_ID"
144    if (existing && existing.pins && Array.isArray(existing.pins.home)) {
145        const legacyIndex = existing.pins.home.indexOf("DLP_Get_GEMS_1_ID");
146        if (legacyIndex !== -1) {
147            existing.pins.home[legacyIndex] = "DLP_Get_GEM_1_ID";
148        }
149    }
150
151    // Fresh write if missing or unparsable
152    if (!existing) {
153        const fresh = { ...DEFAULTS, storageVersion: storageLocalVersion };
154        localStorage.setItem("DLP_Local_Storage", JSON.stringify(fresh));
155        storageLocal = fresh;
156        return;
157    }
158
159    // Up-to-date -> just use it
160    if (existing.storageVersion === storageLocalVersion) {
161        storageLocal = existing;
162        return;
163    }
164
165    // Migrate: keep existing values where keys match, add missing defaults, drop extras
166    const migrated = mergeWithPrune(existing, DEFAULTS);
167
168    // Ensure we actually bump the version so we don't re-migrate on next load
169    migrated.storageVersion = storageLocalVersion;
170
171    localStorage.setItem("DLP_Local_Storage", JSON.stringify(migrated));
172    storageLocal = migrated;
173})();
174function saveStorageLocal() {
175    localStorage.setItem("DLP_Local_Storage", JSON.stringify(storageLocal));
176}
177
178if (sessionStorage.getItem("DLP_Session_Storage") == null || JSON.parse(sessionStorage.getItem("DLP_Session_Storage")).storageVersion !== storageSessionVersion) {
179    sessionStorage.setItem("DLP_Session_Storage", JSON.stringify({
180        "legacy": {
181            "page": 0,
182            "status": false,
183            "path": {
184                "type": "lesson",
185                "amount": 0
186            },
187            "practice": {
188                "type": "lesson",
189                "amount": 0
190            },
191            "listen": {
192                "type": "lesson",
193                "amount": 0
194            },
195            "lesson": {
196                "section": 1,
197                "unit": 1,
198                "level": 1,
199                "type": "lesson",
200                "amount": 0
201            }
202        },
203        "notifications": [
204            {
205                "id": "0001"
206            }
207        ],
208        "storageVersion": storageSessionVersion
209    }));
210    storageSession = JSON.parse(sessionStorage.getItem("DLP_Session_Storage"));
211} else {
212    storageSession = JSON.parse(sessionStorage.getItem("DLP_Session_Storage"));
213}
214function saveStorageSession() {
215    sessionStorage.setItem("DLP_Session_Storage", JSON.stringify(storageSession));
216}
217
218if (alpha) apiURL = "https://api.duolingopro.net/alpha";
219
220let systemLanguage = document.cookie.split('; ').find(row => row.startsWith('lang=')).split('=')[1];
221let systemText = {
222    en: {
223        1: "Switch to Legacy",
224        2: "Show",
225        3: "Connecting",
226        4: "Donate",
227        5: "Support",
228        6: "Settings",
229        7: "What's New",
230        8: "How much XP would you like to gain?",
231        9: "GET",
232        10: "How many Gems would you like to gain?",
233        12: "Would you like to redeem 3 days of Super Duolingo?",
234        13: "REDEEM",
235        14: "Terms & Conditions",
236        15: "See More",
237        16: "Back",
238        17: "How many lessons would you like to solve on the path?",
239        18: "START",
240        19: "How many practices would you like to solve?",
241        21: "How many listening practices would you like to solve? (Requires Super Duolingo)",
242        23: "Which and how many lessons would you like to repeat?",
243        25: "Please read and accept the Terms & Conditions to use Duolingo PRO 3.1.",
244        26: "These are the Terms & Conditions you agreed to use Duolingo PRO 3.1.",
245        27: "LOADING TERMS & CONDITIONS<br><br>YOU CANNOT USE THIS SOFTWARE UNTIL TERMS & CONDITIONS ARE LOADED",
246        28: "DECLINE",
247        29: "ACCEPT",
248        30: "Without accepting the Terms & Conditions, you cannot use Duolingo PRO 3.1.",
249        31: "BACK",
250        32: "Settings",
251        34: "Automatic Updates",
252        35: "Duolingo PRO 3.1 will automatically update itself when there's a new version available.",
253        37: "SAVE",
254        38: "Feedback",
255        39: "Help us make Duolingo PRO 3.1 better.",
256        40: "Write here as much as you can with as many details as possible.",
257        41: "Feedback Type: ",
258        42: "BUG REPORT",
259        43: "SUGGESTION",
260        44: "Add Attachment: (Optional)",
261        45: "UPLOAD",
262        47: "SEND",
263        48: "What's New",
264        51: "LEARN MORE",
265        52: "Welcome to",
266        53: "The next generation of Duolingo PRO is here, with Instant XP, Magnet UI, all powerful than ever. ",
267        54: "START",
268        100: "SOLVE",
269        101: "SOLVE ALL",
270        102: "PAUSE SOLVE",
271        103: "Hide",
272        104: "Show",
273        105: "Switch to 3.1",
274        106: "Switch to Legacy",
275        107: "STOP",
276        108: "Connected",
277        109: "Error",
278        110: "SEND",
279        111: "SENDING",
280        112: "SENT",
281        113: "LOADING",
282        114: "DONE",
283        115: "FAILED",
284        116: "SAVING AND APPLYING",
285        200: "Under Construction",
286        201: "The Gems function is currently under construction. We plan to make it accessible to everyone soon.",
287        202: "Update Available",
288        203: "You are using an outdated version of Duolingo PRO.<br><br>Please <a href='https://www.duolingopro.net/greasyfork' target='_blank' style='font-family: Duolingo PRO Rounded; color: #007AFF; text-decoration: underline;'>update Duolingo PRO</a> or turn on automatic updates.",
289        204: "Feedback Sent",
290        205: "Your feedback was successfully sent, and our developers will look over it. Keep in mind, we cannot respond back to your feedback.",
291        206: "Error Sending Feedback",
292        207: "Your feedback was not sent. This might be because you are using an outdated or a modified version of Duolingo PRO.",
293        208: "Unknown Error",
294        209: "Please try again later. An unknown error occurred. Number: ",
295        210: "hour",
296        211: "hours",
297        212: "minute",
298        213: "minutes",
299        214: "and",
300        215: "{hours} {hourUnit}",
301        216: "{minutes} {minuteUnit}",
302        217: "{hourPhrase} {conjunction} {minutePhrase}",
303        218: "XP Successfully Received",
304        219: "You received {amount} XP. You can request up to {remainingXP} XP before your limit resets back to {totalLimit} XP in {timeMessage}. To boost your limits, <a href='https://duolingopro.net/donate' target='_blank' style='font-family: Duolingo PRO Rounded; text-decoration: underline; color: #007AFF;'>donate</a>.",
305        220: "Super Duolingo Successfully Redeemed",
306        221: "You redeemed a 3 day Super Duolingo trial. You can request another 3 day Super Duolingo trial in {timeMessage}.",
307        222: "Limit Warning",
308        223: "You can only request up to {limitAmount} XP before your limit resets back to {totalLimitAmount} XP in {timeMessage}. To boost your limits, <a href='https://duolingopro.net/donate' target='_blank' style='font-family: Duolingo PRO Rounded; text-decoration: underline; color: #007AFF;'>donate</a>.",
309        224: "Limit Reached",
310        225: "You reached your XP limit for the next {timeMessage}. To boost your limits, <a href='https://duolingopro.net/donate' target='_blank' style='font-family: Duolingo PRO Rounded; text-decoration: underline; color: #007AFF;'>donate</a>.",
311        227: "You already redeemed a 3 day Super Duolingo trial. You can request another 3 day Super Duolingo trial in {timeMessage}.",
312        229: "REFILL",
313        230: "GEMS testing",
314        231: "Error Connecting",
315        232: "Duolingo PRO was unable to connect to our servers. This may be because our servers are temporarily unavailable or you are using an outdated version. Check for <a href='https://status.duolingopro.net' target='_blank' style='font-family: Duolingo PRO Rounded; text-decoration: underline; color: #007AFF;'>server status</a> or <a href='https://duolingopro.net/greasyfork' target='_blank' style='font-family: Duolingo PRO Rounded; text-decoration: underline; color: #007AFF;'>updates</a>.",
316        233: "Update Duolingo PRO",
317        234: "You are using an outdated version of Duolingo PRO. Please <a href='https://www.duolingopro.net/greasyfork' target='_blank' style='font-family: Duolingo PRO Rounded; color: #007AFF; text-decoration: underline;'>update Duolingo PRO</a>."
318    },
319};
320
321let CSS1;
322let HTML2;
323let CSS2;
324let HTML3;
325let HTML4;
326let HTML5;
327let CSS5;
328let HTML6;
329let CSS6;
330let HTML7;
331let CSS7;
332
333function Two() {
334CSS1 = `
335@font-face {
336    font-family: 'Duolingo PRO Rounded';
337    src: url(${serverURL}/static/fonts/V7R100DB1/Duolingo-PRO-Rounded-Semibold.woff2) format('woff2');
338    font-weight: 600;
339}
340
341:root {
342    --DLP-red-hex: #ff3b30;
343    --DLP-orange-hex: #ff9500;
344    --DLP-yellow-hex: #ffcc00;
345    --DLP-green-hex: #34c759;
346    --DLP-teal-hex: #00c7be;
347    --DLP-cyan-hex: #5ac8fa;
348    --DLP-blue-hex: #007aff;
349    --DLP-indigo-hex: #5856d6;
350    --DLP-purple-hex: #af52de;
351    --DLP-pink-hex: #ff2d55;
352
353    --DLP-red-rgb: rgb(255, 59, 48);
354    --DLP-orange-rgb: rgb(255, 149, 0);
355    --DLP-yellow-rgb: rgb(255, 204, 0);
356    --DLP-green-rgb: rgb(52, 199, 89);
357    --DLP-teal-rgb: rgb(0, 199, 190);
358    --DLP-cyan-rgb: rgb(90, 200, 250);
359    --DLP-blue-rgb: rgb(0, 122, 255);
360    --DLP-indigo-rgb: rgb(88, 86, 214);
361    --DLP-purple-rgb: rgb(175, 82, 222);
362    --DLP-pink-rgb: rgb(255, 45, 85);
363
364    --DLP-red: 255, 59, 48;
365    --DLP-orange: 255, 149, 0;
366    --DLP-yellow: 255, 204, 0;
367    --DLP-green: 52, 199, 89;
368    --DLP-teal: 0, 199, 190;
369    --DLP-cyan: 90, 200, 250;
370    --DLP-blue: 0, 122, 255;
371    --DLP-indigo: 88, 86, 214;
372    --DLP-purple: 175, 82, 222;
373    --DLP-pink: 255, 45, 85;
374}
375@media (prefers-color-scheme: dark) {
376    :root {
377        --DLP-red-hex: #ff453a;
378        --DLP-orange-hex: #ff9f0a;
379        --DLP-yellow-hex: #ffd60a;
380        --DLP-green-hex: #30d158;
381        --DLP-teal-hex: #63e6e2;
382        --DLP-cyan-hex: #64d2ff;
383        --DLP-blue-hex: #0a84ff;
384        --DLP-indigo-hex: #5e5ce6;
385        --DLP-purple-hex: #bf5af2;
386        --DLP-pink-hex: #ff375f;
387
388        --DLP-red-rgb: rgb(255, 69, 58);
389        --DLP-orange-rgb: rgb(255, 159, 10);
390        --DLP-yellow-rgb: rgb(255, 214, 10);
391        --DLP-green-rgb: rgb(48, 209, 88);
392        --DLP-teal-rgb: rgb(99, 230, 226);
393        --DLP-cyan-rgb: rgb(100, 210, 255);
394        --DLP-blue-rgb: rgb(10, 132, 255);
395        --DLP-indigo-rgb: rgb(94, 92, 230);
396        --DLP-purple-rgb: rgb(191, 90, 242);
397        --DLP-pink-rgb: rgb(255, 55, 95);
398
399        --DLP-red: 255, 69, 58;
400        --DLP-orange: 255, 159, 10;
401        --DLP-yellow: 255, 214, 10;
402        --DLP-green: 48, 209, 88;
403        --DLP-teal: 99, 230, 226;
404        --DLP-cyan: 100, 210, 255;
405        --DLP-blue: 10, 132, 255;
406        --DLP-indigo: 94, 92, 230;
407        --DLP-purple: 191, 90, 242;
408        --DLP-pink: 255, 55, 95;
409
410        --DLP-background: var(--color-snow);
411    }
412}
413`;
414
415HTML2 = `
416<canvas style="position: fixed; top: 0; left: 0; bottom: 0; right: 0; width: 100%; height: 100vh; z-index: 211; pointer-events: none;" id="DLP_Confetti_Canvas"></canvas>
417<div class="DLP_Notification_Main"></div>
418<div class="DLP_Main">
419    <div class="DLP_HStack_8" style="align-self: flex-end;">
420        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Switch_Legacy_Button_1_ID" style="outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80); backdrop-filter: blur(16px);">
421            <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--DLP-blue));">􀱏</p>
422            <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: rgb(var(--DLP-blue)); white-space: nowrap;">${systemText[systemLanguage][1]}</p>
423        </div>
424        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Hide_Button_1_ID" style="outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: rgba(var(--DLP-blue), 0.10); flex: none; backdrop-filter: blur(16px);">
425            <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--DLP-blue));">􀋮</p>
426            <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][2]}</p>
427        </div>
428    </div>
429    <div class="DLP_Main_Box">
430        <div class="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_1_ID" style="display: block;">
431            <div class="DLP_VStack_8">
432                <div class="DLP_VStack_8">
433                    <div class="DLP_HStack_8">
434                        <div id="DLP_Main_1_Server_Connection_Button_1_ID" class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" style="outline: 2px solid rgb(var(--color-eel), 0.20); outline-offset: -2px; background: rgb(var(--color-eel), 0.10); transition: opacity 0.8s cubic-bezier(0.16, 1, 0.32, 1), background 0.8s cubic-bezier(0.16, 1, 0.32, 1), outline 0.8s cubic-bezier(0.16, 1, 0.32, 1), filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 0.4s cubic-bezier(0.16, 1, 0.32, 1); padding: 10px 0px 10px 10px;">
435                            <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--color-eel));">􀓞</p>
436                            <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: rgb(var(--color-eel));">${systemText[systemLanguage][3]}</p>
437                        </div>
438                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Main_Donate_Button_1_ID" onclick="window.open('https://duolingopro.net/donate', '_blank');" style="outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; padding: 10px 0px 10px 10px;">
439                            <svg width="17" height="19" viewBox="0 0 17 19" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
440                                <path d="M16.5 5.90755C16.4968 3.60922 14.6997 1.72555 12.5913 1.04588C9.97298 0.201877 6.51973 0.324211 4.01956 1.49921C0.989301 2.92355 0.0373889 6.04355 0.00191597 9.15522C-0.0271986 11.7136 0.229143 18.4517 4.04482 18.4997C6.87998 18.5356 7.30214 14.8967 8.61397 13.1442C9.5473 11.8974 10.749 11.5452 12.2284 11.1806C14.7709 10.5537 16.5037 8.55506 16.5 5.90755Z"/>
441                            </svg>
442                            <p class="DLP_Text_Style_1" style="color: #FFF;">${systemText[systemLanguage][4]}</p>
443                        </div>
444                    </div>
445                    <div class="DLP_HStack_8">
446                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Main_Feedback_1_Button_1_ID" style="outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80); backdrop-filter: blur(16px);">
447                            <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--DLP-blue));">􂄺</p>
448                            <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][5]}</p>
449                        </div>
450                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Main_Settings_1_Button_1_ID" style="outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80); backdrop-filter: blur(16px);">
451                            <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--DLP-blue));">􀍟</p>
452                            <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][6]}</p>
453                        </div>
454                    </div>
455                    <div class="DLP_HStack_8">
456                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Secondary_Earn_Button_1_ID" style="outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; padding: 10px 0px 10px 10px;">
457                            <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀋦</p>
458                            <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">Boost</p>
459                        </div>
460                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Main_YouTube_Button_1_ID" onclick="window.open('https://duolingopro.net/youtube', '_blank');" style="justify-content: center; flex: none; width: 40px; padding: 10px; outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: rgb(var(--DLP-pink));">
461                            <svg width="22" height="16" viewBox="0 0 22 16" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
462                                <path fill-rule="evenodd" clip-rule="evenodd" d="M19.2043 1.0885C20.1084 1.33051 20.8189 2.041 21.0609 2.9451C21.4982 4.58216 21.5 7.99976 21.5 7.99976C21.5 7.99976 21.5 11.4174 21.0609 13.0544C20.8189 13.9585 20.1084 14.669 19.2043 14.911C17.5673 15.3501 11 15.3501 11 15.3501C11 15.3501 4.43274 15.3501 2.79568 14.911C1.89159 14.669 1.1811 13.9585 0.939084 13.0544C0.5 11.4174 0.5 7.99976 0.5 7.99976C0.5 7.99976 0.5 4.58216 0.939084 2.9451C1.1811 2.041 1.89159 1.33051 2.79568 1.0885C4.43274 0.649414 11 0.649414 11 0.649414C11 0.649414 17.5673 0.649414 19.2043 1.0885ZM14.3541 8.00005L8.89834 11.1497V4.85038L14.3541 8.00005Z"/>
463                            </svg>
464                        </div>
465                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Main_Discord_Button_1_ID" onclick="window.open('https://duolingopro.net/discord', '_blank');" style="justify-content: center; flex: none; width: 40px; padding: 10px; outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: rgb(var(--DLP-indigo));">
466                            <svg width="22" height="16" viewBox="0 0 22 16" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
467                                <path d="M18.289 1.34C16.9296 0.714 15.4761 0.259052 13.9565 0C13.7699 0.332095 13.5519 0.77877 13.4016 1.1341C11.7862 0.894993 10.1857 0.894993 8.60001 1.1341C8.44972 0.77877 8.22674 0.332095 8.03844 0C6.51721 0.259052 5.06204 0.715671 3.70267 1.34331C0.960812 5.42136 0.21754 9.39811 0.589177 13.3184C2.40772 14.655 4.17011 15.467 5.90275 15.9984C6.33055 15.4189 6.71209 14.8028 7.04078 14.1536C6.41478 13.9195 5.81521 13.6306 5.24869 13.2952C5.39898 13.1856 5.546 13.071 5.68803 12.9531C9.14342 14.5438 12.8978 14.5438 16.3119 12.9531C16.4556 13.071 16.6026 13.1856 16.7512 13.2952C16.183 13.6322 15.5818 13.9211 14.9558 14.1553C15.2845 14.8028 15.6644 15.4205 16.0939 16C17.8282 15.4687 19.5922 14.6567 21.4107 13.3184C21.8468 8.77378 20.6658 4.83355 18.289 1.34ZM7.51153 10.9075C6.47426 10.9075 5.62361 9.95435 5.62361 8.7937C5.62361 7.63305 6.45609 6.67831 7.51153 6.67831C8.56699 6.67831 9.41761 7.63138 9.39945 8.7937C9.40109 9.95435 8.56699 10.9075 7.51153 10.9075ZM14.4884 10.9075C13.4511 10.9075 12.6005 9.95435 12.6005 8.7937C12.6005 7.63305 13.4329 6.67831 14.4884 6.67831C15.5438 6.67831 16.3945 7.63138 16.3763 8.7937C16.3763 9.95435 15.5438 10.9075 14.4884 10.9075Z"/>
468                            </svg>
469                        </div>
470                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Main_GitHub_Button_1_ID" onclick="window.open('https://duolingopro.net/github', '_blank');" style="justify-content: center; flex: none; width: 40px; padding: 10px; outline: 2px solid rgba(255, 255, 255, 0.20); outline-offset: -2px; background: #333333;">
471                            <svg width="22" height="22" viewBox="0 0 22 22" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
472                                <path fill-rule="evenodd" clip-rule="evenodd" d="M11.0087 0.5C5.19766 0.5 0.5 5.3125 0.5 11.2662C0.5 16.0253 3.50995 20.0538 7.68555 21.4797C8.2076 21.5868 8.39883 21.248 8.39883 20.963C8.39883 20.7134 8.38162 19.8578 8.38162 18.9664C5.45836 19.6082 4.84962 17.683 4.84962 17.683C4.37983 16.4353 3.68375 16.1146 3.68375 16.1146C2.72697 15.4551 3.75345 15.4551 3.75345 15.4551C4.81477 15.5264 5.37167 16.5602 5.37167 16.5602C6.31103 18.1999 7.82472 17.7366 8.43368 17.4514C8.52058 16.7562 8.79914 16.2749 9.09491 16.0076C6.7634 15.758 4.31035 14.8312 4.31035 10.6957C4.31035 9.51928 4.72765 8.55678 5.38888 7.80822C5.28456 7.54091 4.9191 6.43556 5.49342 4.95616C5.49342 4.95616 6.38073 4.67091 8.38141 6.06128C9.23797 5.82561 10.1213 5.70573 11.0087 5.70472C11.896 5.70472 12.8005 5.82963 13.6358 6.06128C15.6367 4.67091 16.524 4.95616 16.524 4.95616C17.0983 6.43556 16.7326 7.54091 16.6283 7.80822C17.3069 8.55678 17.707 9.51928 17.707 10.6957C17.707 14.8312 15.254 15.7401 12.905 16.0076C13.2879 16.3463 13.6183 16.9878 13.6183 18.0039C13.6183 19.4477 13.6011 20.6064 13.6011 20.9627C13.6011 21.248 13.7926 21.5868 14.3144 21.4799C18.49 20.0536 21.5 16.0253 21.5 11.2662C21.5172 5.3125 16.8023 0.5 11.0087 0.5Z"/>
473                            </svg>
474                        </div>
475                    </div>
476                </div>
477                <div class="DLP_HStack_Auto_Top DLP_NoSelect">
478                    <div class="DLP_HStack_4">
479                        <p class="DLP_Text_Style_2">Duolingo</p>
480                        <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">PRO 3.1</p>
481                    </div>
482                    <p class="DLP_Text_Style_1" style="margin-top: 2px; font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
483                </div>
484                <p id="DLP_Main_Warning_1_ID" class="DLP_Text_Style_1" style="transition: 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); text-align: center; opacity: 0.5; display: none;"></p>
485                <div class="DLP_VStack_8" id="DLP_Main_Inputs_1_Divider_1_ID" style="opacity: 0.5; pointer-events: none; transition: 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);">
486                    <div class="DLP_VStack_8" id="DLP_Get_XP_1_ID" style="flex: 1 0 0;">
487                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][8]}</p>
488                        <div class="DLP_HStack_8">
489                            <div class="DLP_Input_Style_1_Active">
490                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">􀆃</p>
491                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
492                            </div>
493                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
494                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][9]}</p>
495                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
496                            </div>
497                        </div>
498                    </div>
499                    <div class="DLP_VStack_8" id="DLP_Get_GEM_1_ID" style="flex: 1 0 0; align-self: stretch;">
500                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][10]}</p>
501                        <div class="DLP_HStack_8">
502                            <div class="DLP_Input_Style_1_Active" style="position: relative; overflow: hidden;">
503                                <svg width="120" height="48" viewBox="0 0 120 48" fill="none" xmlns="http://www.w3.org/2000/svg" style="position: absolute; pointer-events: none; transform: translateX(-150px); animation: slideRight 4s ease-in-out forwards infinite; animation-delay: 2s;">
504                                    <path opacity="0.5" d="M72 0H96L72 48H48L72 0Z" fill="rgb(var(--DLP-blue))"/>
505                                    <path opacity="0.5" d="M24 0H60L36 48H0L24 0Z" fill="rgb(var(--DLP-blue))"/>
506                                    <path opacity="0.5" d="M108 0H120L96 48H84L108 0Z" fill="rgb(var(--DLP-blue))"/>
507                                </svg>
508                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">􀆃</p>
509                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
510                            </div>
511                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
512                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][9]}</p>
513                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
514                            </div>
515                        </div>
516                    </div>
517                    <div class="DLP_VStack_8" id="DLP_Get_SUPER_1_ID" style="display: none;">
518                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][12]}</p>
519                        <div class="DLP_HStack_8">
520                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID" style="flex: 1 0 0;">
521                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][13]}</p>
522                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
523                            </div>
524                        </div>
525                    </div>
526                    <div class="DLP_VStack_8" id="DLP_Get_DOUBLE_XP_BOOST_1_ID" style="display: none;">
527                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">Would you like to redeem an XP Boost?</p>
528                        <div class="DLP_HStack_8">
529                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID" style="flex: 1 0 0;">
530                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][13]}</p>
531                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
532                            </div>
533                        </div>
534                    </div>
535                    <div class="DLP_VStack_8" id="DLP_Get_Streak_Freeze_1_ID" style="display: none;">
536                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">How many Streak Freezes would you like to get?</p>
537                        <div class="DLP_HStack_8">
538                            <div class="DLP_Input_Style_1_Active">
539                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">􀆃</p>
540                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
541                            </div>
542                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
543                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][9]}</p>
544                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
545                            </div>
546                        </div>
547                    </div>
548                    <div class="DLP_VStack_8" id="DLP_Get_Streak_1_ID" style="display: none;">
549                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">How many days would you like to increase your Streak by?</p>
550                        <div class="DLP_HStack_8">
551                            <div class="DLP_Input_Style_1_Active">
552                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">􀆃</p>
553                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
554                            </div>
555                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
556                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][9]}</p>
557                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
558                            </div>
559                        </div>
560                    </div>
561                    <div class="DLP_VStack_8" id="DLP_Get_Heart_Refill_1_ID" style="display: none;">
562                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">Would you like to refill your Hearts to full?</p>
563                        <div class="DLP_HStack_8">
564                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID" style="flex: 1 0 0;">
565                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][229]}</p>
566                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
567                            </div>
568                        </div>
569                    </div>
570                    <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Main_See_More_1_Button_1_ID" style="outline: rgba(var(--DLP-blue), 0.2) solid 2px; outline-offset: -2px; background: linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80); backdrop-filter: blur(16px); transform: translate(0px, 0px) scale(1); align-self: stretch; justify-content: space-between;">
571                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][15]}</p>
572                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">􀯻</p>
573                    </div>
574                </div>
575                <div class="DLP_HStack_Auto" style="padding-top: 4px;">
576                    <div class="DLP_HStack_4 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Main_Terms_1_Button_1_ID" style="align-items: center;">
577                        <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">${systemText[systemLanguage][14]}</p>
578                    </div>
579                    <div class="DLP_HStack_4 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Main_Whats_New_1_Button_1_ID" style="align-items: center;">
580                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][7]}</p>
581                    </div>
582                </div>
583            </div>
584        </div>
585
586
587        <div class="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_2_ID" style="display: none;">
588            <div class="DLP_VStack_8">
589                <div class="DLP_HStack_Auto_Top DLP_NoSelect">
590                    <div class="DLP_HStack_4 DLP_Hover_1" id="DLP_Universal_Back_1_Button_1_ID">
591                        <p class="DLP_Text_Style_2" style="font-size: 20px;">􀯶</p>
592                        <p class="DLP_Text_Style_2">Duolingo</p>
593                        <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">PRO 3.1</p>
594                    </div>
595                    <p class="DLP_Text_Style_1" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
596                </div>
597                <div class="DLP_VStack_8" id="DLP_Main_Inputs_1_Divider_1_ID">
598                    <div class="DLP_HStack_8">
599                        <div class="DLP_VStack_8" id="DLP_Get_XP_2_ID" style="flex: 1 0 0;">
600                            <div class="DLP_HStack_8" style="align-items: center;">
601                                <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
602                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][8]}</p>
603                            </div>
604                            <div class="DLP_HStack_8">
605                                <div class="DLP_Input_Style_1_Active">
606                                    <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">􀆃</p>
607                                    <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
608                                </div>
609                                <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
610                                    <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][9]}</p>
611                                    <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
612                                </div>
613                            </div>
614                        </div>
615                        <div class="DLP_VStack_8" id="DLP_Get_GEM_2_ID" style="flex: 1 0 0; align-self: stretch;">
616                            <div class="DLP_HStack_8" style="align-items: center;">
617                                <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
618                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][10]}</p>
619                            </div>
620                            <div class="DLP_HStack_8">
621                                <div class="DLP_Input_Style_1_Active" style="position: relative; overflow: hidden;">
622                                    <svg width="120" height="48" viewBox="0 0 120 48" fill="none" xmlns="http://www.w3.org/2000/svg" style="position: absolute; pointer-events: none; transform: translateX(-150px); animation: slideRight 4s ease-in-out forwards infinite; animation-delay: 2s;">
623                                        <path opacity="0.5" d="M72 0H96L72 48H48L72 0Z" fill="rgb(var(--DLP-blue))"/>
624                                        <path opacity="0.5" d="M24 0H60L36 48H0L24 0Z" fill="rgb(var(--DLP-blue))"/>
625                                        <path opacity="0.5" d="M108 0H120L96 48H84L108 0Z" fill="rgb(var(--DLP-blue))"/>
626                                    </svg>
627                                    <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">􀆃</p>
628                                    <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
629                                </div>
630                                <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
631                                    <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][9]}</p>
632                                    <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
633                                </div>
634                            </div>
635                        </div>
636                    </div>
637                    <div class="DLP_HStack_8">
638                        <div class="DLP_VStack_8" id="DLP_Get_SUPER_2_ID" style="flex: 1 0 0;">
639                            <div class="DLP_HStack_8" style="align-items: center;">
640                                <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
641                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][12]}</p>
642                            </div>
643                            <div class="DLP_HStack_8">
644                                <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID" style="flex: 1 0 0;">
645                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][13]}</p>
646                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
647                                </div>
648                            </div>
649                        </div>
650                        <div class="DLP_VStack_8" id="DLP_Get_DOUBLE_XP_BOOST_2_ID" style="flex: 1 0 0;">
651                            <div class="DLP_HStack_8" style="align-items: center;">
652                                <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
653                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">Would you like to redeem an XP Boost?</p>
654                            </div>
655                            <div class="DLP_HStack_8">
656                                <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID" style="flex: 1 0 0;">
657                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][13]}</p>
658                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
659                                </div>
660                            </div>
661                        </div>
662                    </div>
663                    <div class="DLP_HStack_8">
664                        <div class="DLP_VStack_8" id="DLP_Get_Streak_Freeze_2_ID" style="flex: 1 0 0;">
665                            <div class="DLP_HStack_8" style="align-items: center;">
666                                <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
667                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">How many Streak Freezes would you like to get?</p>
668                            </div>
669                            <div class="DLP_HStack_8">
670                                <div class="DLP_Input_Style_1_Active">
671                                    <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">􀆃</p>
672                                    <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
673                                </div>
674                                <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
675                                    <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][9]}</p>
676                                    <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
677                                </div>
678                            </div>
679                        </div>
680                        <div class="DLP_VStack_8" id="DLP_Get_Streak_2_ID" style="flex: 1 0 0;">
681                            <div class="DLP_HStack_8" style="align-items: center;">
682                                <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
683                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">How many days would you like to increase your Streak by?</p>
684                            </div>
685                            <div class="DLP_HStack_8">
686                                <div class="DLP_Input_Style_1_Active">
687                                    <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">􀆃</p>
688                                    <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
689                                </div>
690                                <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
691                                    <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][9]}</p>
692                                    <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
693                                </div>
694                            </div>
695                        </div>
696                    </div>
697                    <div class="DLP_HStack_8">
698                        <div class="DLP_VStack_8" id="DLP_Get_Heart_Refill_2_ID" style="flex: 1 0 0;">
699                            <div class="DLP_HStack_8" style="align-items: center;">
700                                <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
701                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">Would you like to refill your Hearts to full?</p>
702                            </div>
703                            <div class="DLP_HStack_8">
704                                <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID" style="flex: 1 0 0;">
705                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][229]}</p>
706                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
707                                </div>
708                            </div>
709                        </div>
710                        <div style="flex: 1 0 0; align-self: stretch; opacity: 0; pointer-events: none;"></div>
711                    </div>
712                </div>
713            </div>
714        </div>
715
716
717        <div class="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_3_ID" style="display: none;">
718            <div class="DLP_VStack_8">
719                <div class="DLP_VStack_8">
720                    <div class="DLP_HStack_8">
721                        <div id="DLP_Secondary_1_Server_Connection_Button_1_ID" class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" style="outline: 2px solid rgb(var(--color-eel), 0.20); outline-offset: -2px; background: rgb(var(--color-eel), 0.10); transition: opacity 0.8s cubic-bezier(0.16, 1, 0.32, 1), background 0.8s cubic-bezier(0.16, 1, 0.32, 1), outline 0.8s cubic-bezier(0.16, 1, 0.32, 1), filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 0.4s cubic-bezier(0.16, 1, 0.32, 1); padding: 10px 0px 10px 10px; opacity: 0.25; pointer-events: none;">
722                            <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--DLP-blue));">􀓞</p>
723                            <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #000; transition: 0.4s;">${systemText[systemLanguage][3]}</p>
724                        </div>
725                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Secondary_Donate_Button_1_ID" onclick="window.open('https://duolingopro.net/donate', '_blank');" style="outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; padding: 10px 0px 10px 10px;">
726                            <svg width="17" height="19" viewBox="0 0 17 19" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
727                                <path d="M16.5 5.90755C16.4968 3.60922 14.6997 1.72555 12.5913 1.04588C9.97298 0.201877 6.51973 0.324211 4.01956 1.49921C0.989301 2.92355 0.0373889 6.04355 0.00191597 9.15522C-0.0271986 11.7136 0.229143 18.4517 4.04482 18.4997C6.87998 18.5356 7.30214 14.8967 8.61397 13.1442C9.5473 11.8974 10.749 11.5452 12.2284 11.1806C14.7709 10.5537 16.5037 8.55506 16.5 5.90755Z"/>
728                            </svg>
729                            <p class="DLP_Text_Style_1" style="color: #FFF;">${systemText[systemLanguage][4]}</p>
730                        </div>
731                    </div>
732                    <div class="DLP_HStack_8">
733                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Secondary_Feedback_1_Button_1_ID" style="outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80); backdrop-filter: blur(16px);">
734                            <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--DLP-blue));">􂄺</p>
735                            <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][5]}</p>
736                        </div>
737                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Secondary_Settings_1_Button_1_ID" style="outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80); backdrop-filter: blur(16px);">
738                            <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--DLP-blue));">􀍟</p>
739                            <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][6]}</p>
740                        </div>
741                    </div>
742                    <div class="DLP_HStack_8">
743                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Main_Earn_Button_1_ID" style="outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; padding: 10px 0px 10px 10px;">
744                            <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀋦</p>
745                            <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">Boost</p>
746                        </div>
747                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Secondary_YouTube_Button_1_ID" onclick="window.open('https://duolingopro.net/youtube', '_blank');" style="justify-content: center; flex: none; width: 40px; padding: 10px; outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: rgb(var(--DLP-pink));">
748                            <svg width="22" height="16" viewBox="0 0 22 16" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
749                                <path fill-rule="evenodd" clip-rule="evenodd" d="M19.2043 1.0885C20.1084 1.33051 20.8189 2.041 21.0609 2.9451C21.4982 4.58216 21.5 7.99976 21.5 7.99976C21.5 7.99976 21.5 11.4174 21.0609 13.0544C20.8189 13.9585 20.1084 14.669 19.2043 14.911C17.5673 15.3501 11 15.3501 11 15.3501C11 15.3501 4.43274 15.3501 2.79568 14.911C1.89159 14.669 1.1811 13.9585 0.939084 13.0544C0.5 11.4174 0.5 7.99976 0.5 7.99976C0.5 7.99976 0.5 4.58216 0.939084 2.9451C1.1811 2.041 1.89159 1.33051 2.79568 1.0885C4.43274 0.649414 11 0.649414 11 0.649414C11 0.649414 17.5673 0.649414 19.2043 1.0885ZM14.3541 8.00005L8.89834 11.1497V4.85038L14.3541 8.00005Z"/>
750                            </svg>
751                        </div>
752                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Secondary_Discord_Button_1_ID" onclick="window.open('https://duolingopro.net/discord', '_blank');" style="justify-content: center; flex: none; width: 40px; padding: 10px; outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: rgb(var(--DLP-indigo));">
753                            <svg width="22" height="16" viewBox="0 0 22 16" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
754                                <path d="M18.289 1.34C16.9296 0.714 15.4761 0.259052 13.9565 0C13.7699 0.332095 13.5519 0.77877 13.4016 1.1341C11.7862 0.894993 10.1857 0.894993 8.60001 1.1341C8.44972 0.77877 8.22674 0.332095 8.03844 0C6.51721 0.259052 5.06204 0.715671 3.70267 1.34331C0.960812 5.42136 0.21754 9.39811 0.589177 13.3184C2.40772 14.655 4.17011 15.467 5.90275 15.9984C6.33055 15.4189 6.71209 14.8028 7.04078 14.1536C6.41478 13.9195 5.81521 13.6306 5.24869 13.2952C5.39898 13.1856 5.546 13.071 5.68803 12.9531C9.14342 14.5438 12.8978 14.5438 16.3119 12.9531C16.4556 13.071 16.6026 13.1856 16.7512 13.2952C16.183 13.6322 15.5818 13.9211 14.9558 14.1553C15.2845 14.8028 15.6644 15.4205 16.0939 16C17.8282 15.4687 19.5922 14.6567 21.4107 13.3184C21.8468 8.77378 20.6658 4.83355 18.289 1.34ZM7.51153 10.9075C6.47426 10.9075 5.62361 9.95435 5.62361 8.7937C5.62361 7.63305 6.45609 6.67831 7.51153 6.67831C8.56699 6.67831 9.41761 7.63138 9.39945 8.7937C9.40109 9.95435 8.56699 10.9075 7.51153 10.9075ZM14.4884 10.9075C13.4511 10.9075 12.6005 9.95435 12.6005 8.7937C12.6005 7.63305 13.4329 6.67831 14.4884 6.67831C15.5438 6.67831 16.3945 7.63138 16.3763 8.7937C16.3763 9.95435 15.5438 10.9075 14.4884 10.9075Z"/>
755                            </svg>
756                        </div>
757                        <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Secondary_GitHub_Button_1_ID" onclick="window.open('https://duolingopro.net/github', '_blank');" style="justify-content: center; flex: none; width: 40px; padding: 10px; outline: 2px solid rgba(255, 255, 255, 0.20); outline-offset: -2px; background: #333333;">
758                            <svg width="22" height="22" viewBox="0 0 22 22" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
759                                <path fill-rule="evenodd" clip-rule="evenodd" d="M11.0087 0.5C5.19766 0.5 0.5 5.3125 0.5 11.2662C0.5 16.0253 3.50995 20.0538 7.68555 21.4797C8.2076 21.5868 8.39883 21.248 8.39883 20.963C8.39883 20.7134 8.38162 19.8578 8.38162 18.9664C5.45836 19.6082 4.84962 17.683 4.84962 17.683C4.37983 16.4353 3.68375 16.1146 3.68375 16.1146C2.72697 15.4551 3.75345 15.4551 3.75345 15.4551C4.81477 15.5264 5.37167 16.5602 5.37167 16.5602C6.31103 18.1999 7.82472 17.7366 8.43368 17.4514C8.52058 16.7562 8.79914 16.2749 9.09491 16.0076C6.7634 15.758 4.31035 14.8312 4.31035 10.6957C4.31035 9.51928 4.72765 8.55678 5.38888 7.80822C5.28456 7.54091 4.9191 6.43556 5.49342 4.95616C5.49342 4.95616 6.38073 4.67091 8.38141 6.06128C9.23797 5.82561 10.1213 5.70573 11.0087 5.70472C11.896 5.70472 12.8005 5.82963 13.6358 6.06128C15.6367 4.67091 16.524 4.95616 16.524 4.95616C17.0983 6.43556 16.7326 7.54091 16.6283 7.80822C17.3069 8.55678 17.707 9.51928 17.707 10.6957C17.707 14.8312 15.254 15.7401 12.905 16.0076C13.2879 16.3463 13.6183 16.9878 13.6183 18.0039C13.6183 19.4477 13.6011 20.6064 13.6011 20.9627C13.6011 21.248 13.7926 21.5868 14.3144 21.4799C18.49 20.0536 21.5 16.0253 21.5 11.2662C21.5172 5.3125 16.8023 0.5 11.0087 0.5Z"/>
760                            </svg>
761                        </div>
762                    </div>
763                </div>
764                <div class="DLP_HStack_Auto_Top DLP_NoSelect">
765                    <div class="DLP_HStack_4">
766                        <p class="DLP_Text_Style_2">Duolingo</p>
767                        <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">PRO LE</p>
768                    </div>
769                    <p class="DLP_Text_Style_1" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
770                </div>
771                <p class="DLP_Text_Style_1" style="display: none; transition: 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); opacity: 0; filter: blur(4px);">You are using an outdated version of Duolingo PRO. <br><br>Please update Duolingo PRO or turn on automatic updates. </p>
772                <p class="DLP_Text_Style_1" style="display: none; transition: 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); opacity: 0; filter: blur(4px);">Duolingo PRO failed to connect. This might be happening because of an issue on our system or your device. <br><br>Try updating Duolingo PRO. If the issue persists afterwards, join our Discord Server to get support. </p>
773                <p class="DLP_Text_Style_1" style="display: none; transition: 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); opacity: 0; filter: blur(4px);">We are currently unable to receive new requests due to high demand. Join our Discord Server to learn more. <br><br>You can help us handle more demand by donating on Patreon while getting exclusive features and higher limits. </p>
774                <div class="DLP_VStack_8" id="DLP_Main_Inputs_2_Divider_1_ID">
775                    <div class="DLP_VStack_8" id="DLP_Get_PATH_1_ID">
776                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][17]}</p>
777                        <div class="DLP_HStack_8">
778                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_2_ID" style="width: 48px; padding: 0;">
779                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀆃</p>
780                            </div>
781                            <div class="DLP_Input_Style_1_Active">
782                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
783                            </div>
784                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
785                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][18]}</p>
786                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
787                            </div>
788                        </div>
789                    </div>
790                    <div class="DLP_VStack_8" id="DLP_Get_PRACTICE_1_ID">
791                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][19]}</p>
792                        <div class="DLP_HStack_8">
793                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_2_ID" style="width: 48px; padding: 0;">
794                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀆃</p>
795                            </div>
796                            <div class="DLP_Input_Style_1_Active">
797                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
798                            </div>
799                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
800                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][18]}</p>
801                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
802                            </div>
803                        </div>
804                    </div>
805                    <div class="DLP_VStack_8" id="DLP_Get_LISTEN_1_ID" style="display: none;">
806                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][21]}</p>
807                        <div class="DLP_HStack_8">
808                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_2_ID" style="width: 48px; padding: 0;">
809                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀆃</p>
810                            </div>
811                            <div class="DLP_Input_Style_1_Active">
812                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
813                            </div>
814                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
815                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][18]}</p>
816                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
817                            </div>
818                        </div>
819                    </div>
820                    <div class="DLP_VStack_8" id="DLP_Get_LESSON_1_ID" style="display: none;">
821                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][23]}</p>
822                        <div class="DLP_HStack_8">
823                            <div class="DLP_Input_Style_1_Active">
824                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">􀆃</p>
825                                <div style="display: flex; align-items: center; gap: 8px; width: 100%; justify-content: flex-end;">
826                                    <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgba(var(--DLP-blue), 0.5);">Unit:</p>
827                                    <input type="text" value="1" placeholder="1" id="DLP_Inset_Input_3_ID" class="DLP_Input_Input_Style_1" style="width: 30px;">
828                                    <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgba(var(--DLP-blue), 0.5);">Lesson:</p>
829                                    <input type="text" value="1" placeholder="1" id="DLP_Inset_Input_4_ID" class="DLP_Input_Input_Style_1" style="width: 30px;">
830                                </div>
831                            </div>
832                        </div>
833                        <div class="DLP_HStack_8">
834                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_2_ID" style="width: 48px; padding: 0;">
835                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀆃</p>
836                            </div>
837                            <div class="DLP_Input_Style_1_Active">
838                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
839                            </div>
840                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
841                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][18]}</p>
842                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
843                            </div>
844                        </div>
845                    </div>
846                    <div class="DLP_Button_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Secondary_See_More_1_Button_1_ID" style="outline: rgba(var(--DLP-blue), 0.2) solid 2px; outline-offset: -2px; background: linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80); backdrop-filter: blur(16px); transform: translate(0px, 0px) scale(1); align-self: stretch; justify-content: space-between;">
847                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][15]}</p>
848                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">􀯻</p>
849                    </div>
850                    <div class="DLP_HStack_Auto" style="padding-top: 4px;">
851                        <div class="DLP_HStack_4 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Secondary_Terms_1_Button_1_ID" style="align-items: center;">
852                            <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">${systemText[systemLanguage][14]}</p>
853                        </div>
854                        <div class="DLP_HStack_4 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Secondary_Whats_New_1_Button_1_ID" style="align-items: center;">
855                            <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][7]}</p>
856                        </div>
857                    </div>
858                </div>
859            </div>
860        </div>
861
862
863        <div class="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_4_ID" style="display: none;">
864            <div class="DLP_VStack_8">
865                <div class="DLP_HStack_Auto_Top DLP_NoSelect">
866                    <div class="DLP_HStack_4 DLP_Hover_1" id="DLP_Universal_Back_1_Button_1_ID">
867                        <p class="DLP_Text_Style_2" style="font-size: 20px;">􀯶</p>
868                        <p class="DLP_Text_Style_2">Duolingo</p>
869                        <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">PRO LE</p>
870                    </div>
871                    <p class="DLP_Text_Style_1" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
872                </div>
873                <div class="DLP_VStack_8" id="DLP_Main_Inputs_1_Divider_1_ID">
874                    <div class="DLP_VStack_8" id="DLP_Get_PATH_2_ID">
875                        <div class="DLP_HStack_8" style="align-items: center;">
876                            <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
877                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][17]}</p>
878                        </div>
879                        <div class="DLP_HStack_8">
880                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_2_ID" style="width: 48px; padding: 0;">
881                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀆃</p>
882                            </div>
883                            <div class="DLP_Input_Style_1_Active">
884                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
885                            </div>
886                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
887                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][18]}</p>
888                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
889                            </div>
890                        </div>
891                    </div>
892                    <div class="DLP_VStack_8" id="DLP_Get_PRACTICE_2_ID">
893                        <div class="DLP_HStack_8" style="align-items: center;">
894                            <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
895                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][19]}</p>
896                        </div>
897                        <div class="DLP_HStack_8">
898                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_2_ID" style="width: 48px; padding: 0;">
899                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀆃</p>
900                            </div>
901                            <div class="DLP_Input_Style_1_Active">
902                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
903                            </div>
904                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
905                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][18]}</p>
906                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
907                            </div>
908                        </div>
909                    </div>
910                    <div class="DLP_VStack_8" id="DLP_Get_LISTEN_2_ID">
911                        <div class="DLP_HStack_8" style="align-items: center;">
912                            <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
913                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][21]}</p>
914                        </div>
915                        <div class="DLP_HStack_8">
916                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_2_ID" style="width: 48px; padding: 0;">
917                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀆃</p>
918                            </div>
919                            <div class="DLP_Input_Style_1_Active">
920                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
921                            </div>
922                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
923                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][18]}</p>
924                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
925                            </div>
926                        </div>
927                    </div>
928                    <div class="DLP_VStack_8" id="DLP_Get_LESSON_2_ID">
929                        <div class="DLP_HStack_8" style="align-items: center;">
930                            <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: rgba(var(--color-eel), 0.50);">􀎦</p>
931                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][23]}</p>
932                        </div>
933                        <div class="DLP_HStack_8">
934                            <div class="DLP_Input_Style_1_Active">
935                                <div style="display: flex; align-items: center; gap: 8px; width: 100%; justify-content: flex-end;">
936                                    <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgba(var(--DLP-blue), 0.5);">Unit:</p>
937                                    <input type="text" value="1" placeholder="1" id="DLP_Inset_Input_3_ID" class="DLP_Input_Input_Style_1" style="width: 30px;">
938                                    <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgba(var(--DLP-blue), 0.5);">Lesson:</p>
939                                    <input type="text" value="1" placeholder="1" id="DLP_Inset_Input_4_ID" class="DLP_Input_Input_Style_1" style="width: 30px;">
940                                </div>
941                            </div>
942                        </div>
943                        <div class="DLP_HStack_8">
944                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_2_ID" style="width: 48px; padding: 0;">
945                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀆃</p>
946                            </div>
947                            <div class="DLP_Input_Style_1_Active">
948                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1">
949                            </div>
950                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_1_ID">
951                                <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][18]}</p>
952                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
953                            </div>
954                        </div>
955                    </div>
956                </div>
957            </div>
958        </div>
959
960
961        <div class="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_5_ID" style="display: none;">
962            <div class="DLP_VStack_8">
963                <div class="DLP_HStack_Auto_Top DLP_NoSelect">
964                    <div class="DLP_HStack_4">
965                        <p class="DLP_Text_Style_2">Duolingo</p>
966                        <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">PRO 3.1</p>
967                    </div>
968                    <p class="DLP_Text_Style_1" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
969                </div>
970                <p class="DLP_Text_Style_1 DLP_NoSelect" id="DLP_Terms_1_Text_1_ID">${systemText[systemLanguage][25]}</p>
971                <p class="DLP_Text_Style_1 DLP_NoSelect" id="DLP_Terms_1_Text_2_ID" style="display: none; align-self: stretch;">${systemText[systemLanguage][26]}</p>
972                <div class="DLP_Scroll_Box_Style_1">
973                    <p id="DLP_Terms_Main_Text_1_ID" class="DLP_Scroll_Box_Text_Style_1">${systemText[systemLanguage][27]}</p>
974                </div>
975                <div class="DLP_HStack_8" id="DLP_Terms_1_Button_1_ID">
976                    <div id="DLP_Terms_Decline_Button_1_ID" class="DLP_Button_Style_2 DLP_Magnetic_Hover_1 DLP_NoSelect" style="outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: rgba(var(--DLP-blue), 0.10);">
977                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">􀆄</p>
978                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][28]}</p>
979                    </div>
980                    <div id="DLP_Terms_Accept_Button_1_ID" class="DLP_Button_Style_2 DLP_Magnetic_Hover_1 DLP_NoSelect" style="outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: rgb(var(--DLP-blue));">
981                        <p class="DLP_Text_Style_1" style="color: #FFF;">ACCEPT</p>
982                        <p class="DLP_Text_Style_1" style="color: #FFF;">􀰫</p>
983                    </div>
984                </div>
985                <div class="DLP_HStack_8" id="DLP_Terms_1_Button_2_ID" style="display: none;">
986                    <div class="DLP_Button_Style_2 DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Terms_Back_Button_1_ID" style="outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: rgba(var(--DLP-blue), 0.10);">
987                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">􀯶</p>
988                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][29]}</p>
989                    </div>
990                </div>
991            </div>
992        </div>
993
994
995        <div class="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_6_ID" style="display: none;">
996            <div class="DLP_VStack_8">
997                <div class="DLP_HStack_Auto_Top DLP_NoSelect">
998                    <div class="DLP_HStack_4">
999                        <p class="DLP_Text_Style_2">Duolingo</p>
1000                        <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">PRO 3.1</p>
1001                    </div>
1002                    <p class="DLP_Text_Style_1" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
1003                </div>
1004                <p class="DLP_Text_Style_1 DLP_NoSelect" style="opacity: 0.5;">${systemText[systemLanguage][30]}</p>
1005                <div class="DLP_HStack_8">
1006                    <div id="DLP_Terms_Declined_Back_Button_1_ID" class="DLP_Button_Style_2 DLP_Magnetic_Hover_1 DLP_NoSelect" style="outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: rgba(var(--DLP-blue), 0.10);">
1007                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">􀯶</p>
1008                        <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">${systemText[systemLanguage][31]}</p>
1009                    </div>
1010                </div>
1011            </div>
1012        </div>
1013
1014
1015        <div class="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_7_ID" style="display: none;">
1016            <div class="DLP_VStack_8">
1017                <div class="DLP_HStack_Auto_Top DLP_NoSelect">
1018                    <div id="DLP_Universal_Back_1_Button_1_ID" class="DLP_HStack_4 DLP_Hover_1">
1019                        <p class="DLP_Text_Style_2" style="font-size: 20px; background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 0% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">􀯶</p>
1020                        <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${systemText[systemLanguage][32]}</p>
1021                    </div>
1022                    <p class="DLP_Text_Style_1" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
1023                </div>
1024                <div style="max-height: 320px; overflow-y: auto;">
1025                    <div class="DLP_VStack_8">
1026                        <div id="DLP_Settings_Show_Solve_Buttons_1_ID" class="DLP_HStack_8" style="justify-content: center; align-items: center;">
1027                            <div class="DLP_VStack_0" style="align-items: flex-start; flex: 1 0 0;">
1028                                <p class="DLP_Text_Style_1">Show Solve Buttons</p>
1029                                <p class="DLP_Text_Style_1" style="opacity: 0.5;">In lessons and practices, see the solve and solve all buttons.</p>
1030                            </div>
1031                            <div id="DLP_Inset_Toggle_1_ID" class="DLP_Toggle_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect">
1032                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀁣</p>
1033                            </div>
1034                        </div>
1035                        <div id="DLP_Settings_Show_AutoServer_Button_1_ID" class="DLP_HStack_8" style="justify-content: center; align-items: center;">
1036                            <div class="DLP_VStack_0" style="align-items: flex-start; flex: 1 0 0;">
1037                                <p class="DLP_Text_Style_1">Show AutoServer Button</p>
1038                                <p class="DLP_Text_Style_1" style="opacity: 0.5;">See the AutoServer by Duolingo PRO button in your Duolingo menubar.</p>
1039                            </div>
1040                            <div id="DLP_Inset_Toggle_1_ID" class="DLP_Toggle_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect">
1041                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀁣</p>
1042                            </div>
1043                        </div>
1044                        <div id="DLP_Settings_Legacy_Solve_Speed_1_ID" class="DLP_HStack_8" style="justify-content: center; align-items: center;">
1045                            <div class="DLP_VStack_0" style="align-items: flex-start; flex: 1 0 0;">
1046                                <p class="DLP_Text_Style_1">Legacy Solve Speed</p>
1047                                <p class="DLP_Text_Style_1" style="opacity: 0.5;">Legacy will solve each question every this amount of seconds. The lower speed you set, the more mistakes Legacy can make.</p>
1048                            </div>
1049                            <div class="DLP_Input_Style_1_Active" style="flex: none; width: 72px;">
1050                                <input type="text" placeholder="0" id="DLP_Inset_Input_1_ID" class="DLP_Input_Input_Style_1" style="text-align: center;">
1051                            </div>
1052                        </div>
1053                        <div id="DLP_Settings_Help_Us_Make_Better_Button_1_ID" class="DLP_HStack_8" style="justify-content: center; align-items: center;${alpha ? ' opacity: 0.5; pointer-events: none;' : ''}">
1054                            <div class="DLP_VStack_0" style="align-items: flex-start; flex: 1 0 0;">
1055                                <p class="DLP_Text_Style_1">Help Us Make Duolingo PRO Better</p>
1056                                <p class="DLP_Text_Style_1" style="opacity: 0.5;">Allow Duolingo PRO to collect anonymous usage data for us to improve the script.</p>
1057                            </div>
1058                            <div id="DLP_Inset_Toggle_1_ID" class="DLP_Toggle_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect">
1059                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀁣</p>
1060                            </div>
1061                        </div>
1062                        <div id="DLP_Settings_Auto_Update_Toggle_1_ID" class="DLP_HStack_8" style="justify-content: center; align-items: center; opacity: 0.5; pointer-events: none; cursor: not-allowed;">
1063                            <div class="DLP_VStack_0" style="align-items: flex-start; flex: 1 0 0;">
1064                                <p class="DLP_Text_Style_1">${systemText[systemLanguage][34]}</p>
1065                                <p class="DLP_Text_Style_1" style="opacity: 0.5;">${systemText[systemLanguage][35]}</p>
1066                            </div>
1067                            <div id="DLP_Inset_Toggle_1_ID" class="DLP_Toggle_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect">
1068                                <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀁣</p>
1069                            </div>
1070                        </div>
1071                        <div id="DLP_Settings_Modern_Stats_Main_Box_1_ID" class="DLP_VStack_6" style="background: rgba(var(--DLP-blue), 0.10); outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; padding: 16px; border-radius: 8px;">
1072                            <div style="display: flex; align-self: stretch; justify-content: space-between; align-items: center;">
1073                                <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">3.1 Stats</p>
1074                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);"></p>
1075                            </div>
1076                            <div style="display: flex; align-self: stretch; justify-content: space-between; align-items: center;">
1077                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">XP Gained:</p>
1078                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);"></p>
1079                            </div>
1080                            <div style="display: flex; align-self: stretch; justify-content: space-between; align-items: center;">
1081                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">Gems Gained:</p>
1082                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);"></p>
1083                            </div>
1084                            <div style="display: flex; align-self: stretch; justify-content: space-between; align-items: center;">
1085                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">Streak Gained:</p>
1086                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);"></p>
1087                            </div>
1088                            <div style="display: flex; align-self: stretch; justify-content: space-between; align-items: center;">
1089                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">Heart Refills Requested:</p>
1090                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);"></p>
1091                            </div>
1092                        </div>
1093                        <div id="DLP_Settings_Legacy_Stats_Main_Box_1_ID" class="DLP_VStack_6" style="background: rgba(var(--DLP-blue), 0.10); outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; padding: 16px; border-radius: 8px;">
1094                            <div style="display: flex; align-self: stretch; justify-content: space-between; align-items: center;">
1095                                <p class="DLP_Text_Style_1" style="color: rgb(var(--DLP-blue));">Legacy Mode Stats</p>
1096                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);"></p>
1097                            </div>
1098                            <div style="display: flex; align-self: stretch; justify-content: space-between; align-items: center;">
1099                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">Lessons Solved:</p>
1100                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);"></p>
1101                            </div>
1102                            <div style="display: flex; align-self: stretch; justify-content: space-between; align-items: center;">
1103                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);">Questions Solved:</p>
1104                                <p class="DLP_Text_Style_1" style="color: rgba(var(--DLP-blue), 0.5);"></p>
1105                            </div>
1106                        </div>
1107                    </div>
1108                </div>
1109                <div class="DLP_HStack_8">
1110                    <div id="DLP_Settings_Save_Button_1_ID" class="DLP_Button_Style_2 DLP_Magnetic_Hover_1 DLP_NoSelect" style="outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: rgb(var(--DLP-blue));">
1111                        <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][37]}</p>
1112                        <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀁣</p>
1113                    </div>
1114                </div>
1115            </div>
1116        </div>
1117
1118
1119        <div clas="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_8_ID" style="display: none;">
1120            <div class="DLP_VStack_8">
1121                <div class="DLP_HStack_Auto_Top DLP_NoSelect">
1122                    <div id="DLP_Universal_Back_1_Button_1_ID" class="DLP_HStack_4 DLP_Hover_1">
1123                        <p class="DLP_Text_Style_2" style="font-size: 20px; background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 0% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">􀯶</p>
1124                        <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${systemText[systemLanguage][38]}</p>
1125                    </div>
1126                    <p class="DLP_Text_Style_1" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
1127                </div>
1128                <div class="DLP_VStack_4" style="padding: 16px; border-radius: 8px; outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: rgba(var(--DLP-blue), 0.10); box-sizing: border-box;">
1129                    <div class="DLP_HStack_4">
1130                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgb(var(--DLP-blue));">􀁝</p>
1131                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch; color: rgb(var(--DLP-blue));">Need Support?</p>
1132                    </div>
1133                    <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch; color: rgba(var(--DLP-blue), 0.5);">Get help from our <a href='https://www.duolingopro.net/faq' target='_blank' style='font-family: Duolingo PRO Rounded; color: rgb(var(--DLP-blue)); text-decoration: underline;'>FAQ page</a>, enhanced with AI, or join our <a href='https://www.duolingopro.net/discord' target='_blank' style='font-family: Duolingo PRO Rounded; color: rgb(var(--DLP-blue)); text-decoration: underline;'>Discord server</a> and talk with the devs.</p>
1134                </div>
1135                <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][39]}</p>
1136                <textarea id="DLP_Feedback_Text_Input_1_ID" class="DLP_Large_Input_Box_Style_1" style="height: 128px; max-height: 256px;" placeholder="${systemText[systemLanguage][40]}"/></textarea>
1137                <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][41]}</p>
1138                <div class="DLP_HStack_8">
1139                    <div id="DLP_Feedback_Type_Bug_Report_Button_1_ID" class="DLP_Button_Style_2 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Feedback_Type_Button_Style_1_OFF" style="transition: background 0.4s, outline 0.4s, filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 0.4s cubic-bezier(0.16, 1, 0.32, 1);">
1140                        <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="transition: 0.4s;">􀌛</p>
1141                        <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="transition: 0.4s;">${systemText[systemLanguage][42]}</p>
1142                    </div>
1143                    <div id="DLP_Feedback_Type_Suggestion_Button_1_ID" class="DLP_Button_Style_2 DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Feedback_Type_Button_Style_2_ON" style="transition: background 0.4s, outline 0.4s, filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 0.4s cubic-bezier(0.16, 1, 0.32, 1);">
1144                        <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="transition: 0.4s;">􁷙</p>
1145                        <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="transition: 0.4s;">${systemText[systemLanguage][43]}</p>
1146                    </div>
1147                </div>
1148                <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch;">${systemText[systemLanguage][44]}</p>
1149                <div class="DLP_HStack_8">
1150                    <div id="DLP_Feedback_Attachment_Upload_Button_1_ID" class="DLP_Button_Style_2 DLP_Magnetic_Hover_1 DLP_NoSelect" style="outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: rgba(var(--DLP-blue), 0.10); transition: background 0.4s, outline 0.4s, filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 0.4s cubic-bezier(0.16, 1, 0.32, 1);">
1151                        <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: rgb(var(--DLP-blue)); transition: 0.4s;">${systemText[systemLanguage][45]}</p>
1152                        <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--DLP-blue));">􀅼</p>
1153                    </div>
1154                </div>
1155                <input type="file" accept="image/png, image/jpg, image/jpeg, video/mp4, image/gif, video/mov, video/webm" id="DLP_Feedback_Attachment_Input_Hidden_1_ID" style="display: none;"/>
1156                <div class="DLP_HStack_8">
1157                    <div id="DLP_Feedback_Send_Button_1_ID" class="DLP_Button_Style_2 DLP_Magnetic_Hover_1 DLP_NoSelect" style="outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: rgb(var(--DLP-blue));">
1158                        <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: #FFF;">${systemText[systemLanguage][47]}</p>
1159                        <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀰫</p>
1160                    </div>
1161                </div>
1162            </div>
1163        </div>
1164
1165
1166        <div class="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_9_ID" style="display: none;">
1167            <div class="DLP_VStack_8">
1168                <div class="DLP_HStack_Auto_Top DLP_NoSelect">
1169                    <div id="DLP_Universal_Back_1_Button_1_ID" class="DLP_HStack_4 DLP_Hover_1">
1170                        <p class="DLP_Text_Style_2" style="font-size: 20px; background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 0% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">􀯶</p>
1171                        <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${systemText[systemLanguage][48]}</p>
1172                    </div>
1173                    <p class="DLP_Text_Style_1" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
1174                </div>
1175                <div class="DLP_VStack_8" id="DLP_Release_Notes_List_1_ID" style="height: 256px; padding: 0 16px;"></div>
1176                <div id="DLP_Release_Notes_Controls" class="DLP_NoSelect" style="display: flex; align-items: center; gap: 8px; margin: 8px;">
1177                    <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--DLP-blue));">􀯶</p>
1178                    <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="color: rgb(var(--DLP-blue));"></p>
1179                    <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_Inset_Icon_2_ID" style="color: rgb(var(--DLP-blue));">􀯻</p>
1180                </div>
1181            </div>
1182        </div>
1183
1184
1185        <div class="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_10_ID" style="display: none;">
1186            <div class="DLP_VStack_8">
1187                <div class="DLP_VStack_8" style="padding: 8px 0;">
1188                    <div class="DLP_VStack_0">
1189                        <p class="DLP_Text_Style_1" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${systemText[systemLanguage][52]}</p>
1190                        <div class="DLP_HStack_4" style="align-self: auto;">
1191                            <p class="DLP_Text_Style_2">Duolingo</p>
1192                            <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">PRO 3.1</p>
1193                        </div>
1194                    </div>
1195                    <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch; text-align: center;">${systemText[systemLanguage][53]}</p>
1196                </div>
1197                <div class="DLP_HStack_8">
1198                    <div id="DLP_Onboarding_Start_Button_1_ID" class="DLP_Button_Style_2 DLP_Magnetic_Hover_1 DLP_NoSelect" style="outline: 2px solid rgba(0, 0, 0, 0.20); outline-offset: -2px; background: rgb(var(--DLP-blue));">
1199                        <p class="DLP_Text_Style_1" style="color: #FFF;">${systemText[systemLanguage][54]}</p>
1200                        <p class="DLP_Text_Style_1" style="color: #FFF;">􀰫</p>
1201                    </div>
1202                </div>
1203            </div>
1204        </div>
1205
1206
1207        <div class="DLP_Main_Box_Divider" id="DLP_Main_Box_Divider_11_ID" style="display: none;">
1208            <div class="DLP_VStack_8">
1209                <div class="DLP_HStack_Auto_Top DLP_NoSelect">
1210                    <div id="DLP_Universal_Back_1_Button_1_ID" class="DLP_HStack_4 DLP_Hover_1">
1211                        <p class="DLP_Text_Style_2" style="font-size: 20px; background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 0% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">􀯶</p>
1212                        <p class="DLP_Text_Style_2" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">Support</p>
1213                    </div>
1214                    <p class="DLP_Text_Style_1" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
1215                </div>
1216
1217                <div class="DLP_VStack_8" style="height: 500px;">
1218                    <div id="DLP_Inset_Card_1" style="display: flex; padding: 16px; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 4px; align-self: stretch; border-radius: 8px; outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: rgba(var(--DLP-blue), 0.10); overflow: hidden; transition: all 0.4s cubic-bezier(0.16, 1, 0.32, 1);">
1219                        <div class="DLP_HStack_6">
1220                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgb(var(--DLP-blue));">􀅵</p>
1221                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgb(var(--DLP-blue)); flex: 1 0 0;">Response Times</p>
1222                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgb(var(--DLP-blue));">􀯻</p>
1223                        </div>
1224                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch; color: rgba(var(--DLP-blue), 0.5); display: none; opacity: 0; filter: blur(4px); height: 0px; transition: 0.4s cubic-bezier(0.16, 1, 0.32, 1);">It may take a few hours for a developer to respond to you. You will be notified in Duolingo PRO when there's a reply.</p>
1225                    </div>
1226
1227                    <div class="DLP_Chat_Box_1_ID_1" style="display: flex; flex-direction: column; align-items: center; gap: 8px; flex: 1 0 0; align-self: stretch; overflow-y: auto; display: none;">
1228
1229                    </div>
1230
1231                    <div class="DLP_VStack_8" id="DLP_Inset_Group_3" style="padding: 0px 32px; flex: 1 0 0;">
1232                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="background: url(https://www.duolingopro.net/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-size: 24px;">􀘲</p>
1233                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch; text-align: center;">Send a message to start talking with a support member.</p>
1234                    </div>
1235
1236                    <div class="DLP_VStack_8" id="DLP_Inset_Group_2" style="display: none;">
1237                        <div id="DLP_Inset_Card_2" style="display: flex; padding: 16px; flex-direction: column; justify-content: flex-start; align-items: flex-start; gap: 4px; align-self: stretch; border-radius: 8px; outline: 2px solid rgba(var(--DLP-blue), 0.20); outline-offset: -2px; background: rgba(var(--DLP-blue), 0.10); overflow: hidden; transition: all 0.4s cubic-bezier(0.16, 1, 0.32, 1);">
1238                            <div class="DLP_HStack_6">
1239                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgb(var(--DLP-blue));">􀿌</p>
1240                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgb(var(--DLP-blue)); flex: 1 0 0;">This chat was closed.</p>
1241                            </div>
1242                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="align-self: stretch; color: rgba(var(--DLP-blue), 0.5);">We hope to have solved your issue. If not, you can start a new chat.</p>
1243                        </div>
1244
1245                        <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_3_ID" style="width: 100%;">
1246                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: #FFF;">Start a New Chat</p>
1247                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: #FFF;">􀅼</p>
1248                        </div>
1249                    </div>
1250
1251                    <div class="DLP_VStack_8" id="DLP_Inset_Group_1">
1252                        <div id="DLP_Attachment_Preview_Parent" class="DLP_Row DLP_Left DLP_Gap_8" style="width: 100%; overflow-y: scroll; display: none;">
1253                            <div class="DLP_Attachment_Box_Drop_1 DLP_Fill_Col" style="height: 96px; display: none;">
1254                                <div class="DLP_Row DLP_Gap_6" style="opacity: 0.5;">
1255                                    <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgb(var(--DLP-blue));">􀉂</p>
1256                                    <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgb(var(--DLP-blue));">Drop here to attach</p>
1257                                </div>
1258                            </div>
1259                        </div>
1260
1261                        <div class="DLP_HStack_8" style="align-items: flex-end;">
1262                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Hide_Scrollbar" id="DLP_Inset_Button_1_ID" style="width: 48px; background: rgba(var(--DLP-blue), 0.10); outline-offset: -2px; outline: 2px solid rgba(var(--DLP-blue), 0.20);">
1263                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: rgb(var(--DLP-blue));">􀉢</p>
1264                                <input type="file" id="DLP_Attachment_Input_1" accept="image/*, video/*" multiple style="display: none;">
1265                            </div>
1266                            <div class="DLP_Input_Style_1_Active" style="padding: 0;">
1267                                <textarea type="text" placeholder="Type here..." id="DLP_Inset_Input_1_ID" class="DLP_Input_Style_1 DLP_Hide_Scrollbar" style="padding: 16px; box-sizing: content-box; overflow: scroll;"></textarea>
1268                            </div>
1269                            <div class="DLP_Input_Button_Style_1_Active DLP_Magnetic_Hover_1 DLP_NoSelect" id="DLP_Inset_Button_2_ID" style="width: 48px;">
1270                                <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: #FFF;">􀰫</p>
1271                            </div>
1272                        </div>
1273                    </div>
1274                </div>
1275
1276            </div>
1277        </div>
1278
1279    </div>
1280</div>
1281`;
1282CSS2 = `
1283.DLP_NoSelect {
1284    -webkit-touch-callout: none;
1285    -webkit-user-select: none;
1286    -khtml-user-select: none;
1287    -moz-user-select: none;
1288    -ms-user-select: none;
1289    user-select: none;
1290}
1291.DLP_Text_Style_1 {
1292    font-family: "Duolingo PRO Rounded";
1293    font-size: 16px;
1294    font-style: normal;
1295    font-weight: 500;
1296    line-height: normal;
1297
1298    color: rgb(var(--color-wolf), 0.8);
1299
1300    margin: 0;
1301    -webkit-font-smoothing: antialiased;
1302}
1303.DLP_Text_Style_2 {
1304    font-family: "Duolingo PRO Rounded";
1305    font-size: 24px;
1306    font-style: normal;
1307    font-weight: 500;
1308    line-height: normal;
1309
1310    margin: 0;
1311    -webkit-font-smoothing: antialiased;
1312}
1313.DLP_Magnetic_Hover_1 {
1314    transition: filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 0.4s cubic-bezier(0.16, 1, 0.32, 1);
1315    cursor: pointer;
1316}
1317.DLP_Magnetic_Hover_1:hover {
1318    filter: brightness(0.9);
1319    transform: scale(1.05);
1320}
1321.DLP_Magnetic_Hover_1:active {
1322    filter: brightness(0.9);
1323    transform: scale(0.9);
1324}
1325
1326.DLP_Hover_1 {
1327    transition: filter 0.4s cubic-bezier(0.16, 1, 0.32, 1);
1328    cursor: pointer;
1329}
1330.DLP_Hover_1:hover {
1331    filter: brightness(0.9);
1332}
1333.DLP_Hover_1:active {
1334    filter: brightness(0.9);
1335}
1336
1337
1338
1339.DLP_Row {
1340    display: flex;
1341    flex-direction: row;
1342}
1343.DLP_Col {
1344    display: flex;
1345    flex-direction: column;
1346}
1347
1348.DLP_Auto {
1349    justify-content: space-between;
1350}
1351.DLP_Hug {
1352    justify-content: center;
1353}
1354.DLP_Fill_Row {
1355    align-self: stretch;
1356}
1357.DLP_Fill_Col {
1358    flex: 1 0 0;
1359}
1360
1361.DLP_Left {
1362    justify-content: flex-start;
1363}
1364.DLP_Right {
1365    justify-content: flex-end;
1366}
1367
1368.DLP_Top {
1369    align-items: flex-start;
1370}
1371.DLP_Center {
1372    align-items: center;
1373}
1374.DLP_Bottom {
1375    align-items: flex-end;
1376}
1377
1378.DLP_Gap_0 {
1379    gap: 0px;
1380}
1381.DLP_Gap_2 {
1382    gap: 2px;
1383}
1384.DLP_Gap_4 {
1385    gap: 4px;
1386}
1387.DLP_Gap_6 {
1388    gap: 6px;
1389}
1390.DLP_Gap_8 {
1391    gap: 8px;
1392}
1393.DLP_Gap_12 {
1394    gap: 12px;
1395}
1396.DLP_Gap_16 {
1397    gap: 16px;
1398}
1399.DLP_Gap_24 {
1400    gap: 24px;
1401}
1402.DLP_Gap_32 {
1403    gap: 32px;
1404}
1405
1406
1407
1408.DLP_Main {
1409    display: inline-flex;
1410    flex-direction: column;
1411    justify-content: flex-end;
1412    align-items: flex-end;
1413    gap: 8px;
1414
1415    position: fixed;
1416    right: 16px;
1417    bottom: 16px;
1418    z-index: 2;
1419}
1420@media (max-width: 699px) {
1421    .DLP_Main {
1422        display: inline-flex;
1423        flex-direction: column;
1424        justify-content: flex-end;
1425        align-items: flex-end;
1426        gap: 8px;
1427
1428        position: fixed;
1429        right: 16px;
1430        bottom: 16px;
1431        z-index: 2;
1432        margin-bottom: 80px;
1433    }
1434}
1435.DLP_Main_Box {
1436    display: flex;
1437    width: 312px;
1438    padding: 16px;
1439    box-sizing: border-box;
1440    flex-direction: column;
1441    justify-content: center;
1442    align-items: center;
1443    gap: 8px;
1444    overflow: hidden;
1445
1446    border-radius: 20px;
1447    outline: 2px solid rgb(var(--color-eel), 0.10);
1448    outline-offset: -2px;
1449    background: rgb(var(--color-snow), 0.90);
1450    backdrop-filter: blur(16px);
1451}
1452.DLP_Main_Box_Divider {
1453    display: flex;
1454    box-sizing: border-box;
1455    flex-direction: column;
1456    justify-content: center;
1457    align-items: center;
1458    gap: 8px;
1459
1460    width: 100%;
1461}
1462svg {
1463    flex-shrink: 0;
1464}
1465.DLP_HStack_Auto {
1466    display: flex;
1467    align-items: center;
1468    justify-content: space-between;
1469    align-self: stretch;
1470}
1471.DLP_HStack_Auto_Top {
1472    display: flex;
1473    align-items: flex-start;
1474    justify-content: space-between;
1475    align-self: stretch;
1476}
1477.DLP_HStack_0 {
1478    display: flex;
1479    align-items: center;
1480    gap: 0;
1481    align-self: stretch;
1482}
1483.DLP_HStack_4 {
1484    display: flex;
1485    align-items: center;
1486    gap: 4px;
1487    align-self: stretch;
1488}
1489.DLP_HStack_6 {
1490    display: flex;
1491    align-items: center;
1492    gap: 6px;
1493    align-self: stretch;
1494}
1495.DLP_HStack_8 {
1496    display: flex;
1497    align-items: center;
1498    gap: 8px;
1499    align-self: stretch;
1500}
1501.DLP_VStack_0 {
1502    display: flex;
1503    flex-direction: column;
1504    justify-content: center;
1505    align-items: center;
1506    gap: 0;
1507    align-self: stretch;
1508}
1509.DLP_VStack_4 {
1510    display: flex;
1511    flex-direction: column;
1512    justify-content: center;
1513    align-items: center;
1514    gap: 4px;
1515    align-self: stretch;
1516}
1517.DLP_VStack_6 {
1518    display: flex;
1519    flex-direction: column;
1520    justify-content: center;
1521    align-items: center;
1522    gap: 6px;
1523    align-self: stretch;
1524}
1525.DLP_VStack_8 {
1526    display: flex;
1527    flex-direction: column;
1528    justify-content: center;
1529    align-items: center;
1530    gap: 8px;
1531    align-self: stretch;
1532}
1533.DLP_VStack_12 {
1534    display: flex;
1535    flex-direction: column;
1536    justify-content: center;
1537    align-items: center;
1538    gap: 12px;
1539    align-self: stretch;
1540}
1541.DLP_Hide_Scrollbar {
1542    scrollbar-width: none;
1543    -ms-overflow-style: none;
1544}
1545.DLP_Hide_Scrollbar::-webkit-scrollbar {
1546    display: none;
1547}
1548.DLP_Button_Style_1 {
1549    display: flex;
1550    height: 40px;
1551    padding: 10px 12px 10px 10px;
1552    box-sizing: border-box;
1553    align-items: center;
1554    gap: 6px;
1555    flex: 1 0 0;
1556
1557    border-radius: 8px;
1558}
1559.DLP_Input_Style_1 {
1560    border: none;
1561    outline: none;
1562    background: none;
1563
1564    font-family: "Duolingo PRO Rounded";
1565    font-size: 16px;
1566    font-style: normal;
1567    font-weight: 500;
1568    line-height: normal;
1569    color: rgb(var(--DLP-blue));
1570
1571    width: 100%;
1572
1573    width: 100%; /* Full width */
1574    height: auto; /* Let the height be controlled dynamically */
1575    min-height: 1.2em; /* Set minimum height for one line */
1576    max-height: calc(1.2em * 5); /* Limit to 5 lines */
1577    line-height: 1.2em; /* Adjust the line height */
1578    overflow-y: hidden; /* Hide vertical scrollbar */
1579    resize: none; /* Prevent manual resizing */
1580    padding: 0; /* Remove padding to eliminate extra space */
1581    margin: 0; /* Remove margin to eliminate extra space */
1582    box-sizing: border-box; /* Include padding in height calculation */
1583
1584}
1585.DLP_Input_Style_1::placeholder {
1586    color: rgba(var(--DLP-blue), 0.50);
1587}
1588.DLP_Input_Input_Style_1 {
1589    border: none;
1590    outline: none;
1591    background: none;
1592    text-align: right;
1593
1594    font-family: "Duolingo PRO Rounded";
1595    font-size: 16px;
1596    font-style: normal;
1597    font-weight: 500;
1598    line-height: normal;
1599    color: rgb(var(--DLP-blue));
1600
1601    width: 100%;
1602}
1603.DLP_Input_Input_Style_1::placeholder {
1604    color: rgba(var(--DLP-blue), 0.50);
1605}
1606.DLP_Input_Style_1_Active {
1607    display: flex;
1608    height: 48px;
1609    padding: 16px;
1610    box-sizing: border-box;
1611    align-items: center;
1612    flex: 1 0 0;
1613    gap: 6px;
1614
1615    border-radius: 8px;
1616    outline: 2px solid rgba(var(--DLP-blue), 0.20);
1617    outline-offset: -2px;
1618    background: rgba(var(--DLP-blue), 0.10);
1619}
1620.DLP_Input_Button_Style_1_Active {
1621    display: flex;
1622    height: 48px;
1623    padding: 12px 12px 12px 14px;
1624    box-sizing: border-box;
1625    justify-content: center;
1626    align-items: center;
1627    gap: 6px;
1628
1629    border-radius: 8px;
1630    outline: 2px solid rgba(0, 0, 0, 0.20);
1631    outline-offset: -2px;
1632    background: rgb(var(--DLP-blue));
1633}
1634@keyframes DLP_Rotate_360_Animation_1 {
1635    from {
1636        transform: rotate(0deg);
1637    }
1638    to {
1639        transform: rotate(360deg);
1640    }
1641}
1642@keyframes DLP_Pulse_Opacity_Animation_1 {
1643    0% {
1644        opacity: 1;
1645    }
1646    16.66666666% {
1647        opacity: 0.75;
1648    }
1649    33.33333333% {
1650        opacity: 1;
1651    }
1652    100% {
1653        opacity: 1;
1654    }
1655}
1656@keyframes DLP_Pulse_Opacity_Animation_2 {
1657    0% {
1658        opacity: 0.75;
1659    }
1660    50% {
1661        opacity: 0.5;
1662    }
1663    100% {
1664        opacity: 0.75;
1665    }
1666}
1667.DLP_Scroll_Box_Style_1 {
1668    display: flex;
1669    height: 200px;
1670    padding: 14px 16px;
1671    box-sizing: border-box;
1672    justify-content: center;
1673    align-items: flex-start;
1674    gap: 8px;
1675    align-self: stretch;
1676
1677    border-radius: 8px;
1678    outline: 2px solid rgb(var(--color-eel), 0.10);
1679    outline-offset: -2px;
1680    background: rgb(var(--color-snow), 0.90);
1681
1682    position: relative;
1683}
1684.DLP_Scroll_Box_Text_Style_1 {
1685    font-family: "Duolingo PRO Rounded";
1686    font-size: 16px;
1687    font-style: normal;
1688    font-weight: 500;
1689    line-height: normal;
1690    color: rgb(var(--color-wolf));
1691    margin: 0;
1692
1693    overflow-y: scroll;
1694    overflow-x: hidden;
1695    position: absolute;
1696    top: 0;
1697    bottom: 0;
1698    right: 16px;
1699    left: 16px;
1700    padding-top: 16px;
1701    padding-bottom: 16px;
1702}
1703.DLP_Scroll_Box_Text_Style_1::-webkit-scrollbar {
1704    transform: translateX(16px);
1705}
1706.DLP_Button_Style_2 {
1707    display: flex;
1708    height: 48px;
1709    box-sizing: border-box;
1710    justify-content: center;
1711    align-items: center;
1712    gap: 6px;
1713    flex: 1 0 0;
1714
1715    border-radius: 8px;
1716}
1717.DLP_Toggle_Style_1 {
1718    display: flex;
1719    width: 48px;
1720    height: 48px;
1721    padding: 16px;
1722    box-sizing: border-box;
1723    justify-content: center;
1724    align-items: center;
1725    gap: 6px;
1726
1727    border-radius: 8px;
1728    transition: background 0.8s cubic-bezier(0.16, 1, 0.32, 1), filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 0.4s cubic-bezier(0.16, 1, 0.32, 1);
1729}
1730.DLP_Toggle_Style_1_ON {
1731    outline: 2px solid rgba(0, 0, 0, 0.20);
1732    outline-offset: -2px;
1733    background: rgb(var(--DLP-green));
1734}
1735.DLP_Toggle_Style_1_OFF {
1736    outline: 2px solid rgba(0, 0, 0, 0.20);
1737    outline-offset: -2px;
1738    background: rgb(var(--DLP-pink));
1739}
1740.DLP_Large_Input_Box_Style_1 {
1741    display: flex;
1742    padding: 16px;
1743    box-sizing: border-box;
1744    justify-content: center;
1745    align-items: flex-start;
1746    align-self: stretch;
1747
1748    border-radius: 8px;
1749    border: none;
1750    outline: 2px solid rgb(var(--color-eel), 0.10);
1751    outline-offset: -2px;
1752    background: rgb(var(--color-snow), 0.90);
1753
1754    color: rgb(var(--color-eel), 0.50);
1755    font-size: 16px;
1756    font-weight: 500;
1757    font-family: Duolingo PRO Rounded, 'din-round' !important;
1758
1759    resize: vertical;
1760    transition: .2s;
1761}
1762.DLP_Large_Input_Box_Style_1::placeholder {
1763    font-weight: 500;
1764    color: rgb(var(--color-eel), 0.25);
1765}
1766.DLP_Large_Input_Box_Style_1:focus {
1767    outline: 2px solid rgb(var(--DLP-blue));
1768}
1769.DLP_Feedback_Type_Button_Style_1_ON {
1770    outline: 2px solid rgba(0, 0, 0, 0.20);
1771    outline-offset: -2px;
1772    background: rgb(var(--DLP-pink));
1773}
1774.DLP_Feedback_Type_Button_Style_1_ON .DLP_Text_Style_1 {
1775    color: #FFF;
1776}
1777.DLP_Feedback_Type_Button_Style_1_OFF {
1778    outline: 2px solid rgba(255, 45, 85, 0.20);
1779    outline-offset: -2px;
1780    background: rgba(255, 45, 85, 0.10);
1781}
1782.DLP_Feedback_Type_Button_Style_1_OFF .DLP_Text_Style_1 {
1783    color: rgb(var(--DLP-pink));
1784}
1785.DLP_Feedback_Type_Button_Style_2_ON {
1786    outline: 2px solid rgba(0, 0, 0, 0.20);
1787    outline-offset: -2px;
1788    background: rgb(var(--DLP-green));
1789}
1790.DLP_Feedback_Type_Button_Style_2_ON .DLP_Text_Style_1 {
1791    color: #FFF;
1792}
1793.DLP_Feedback_Type_Button_Style_2_OFF {
1794    outline: 2px solid rgba(52, 199, 89, 0.20);
1795    outline-offset: -2px;
1796    background: rgba(52, 199, 89, 0.10);
1797}
1798.DLP_Feedback_Type_Button_Style_2_OFF .DLP_Text_Style_1 {
1799    color: rgb(var(--DLP-green));
1800}
1801
1802.DLP_Notification_Main {
1803    display: flex;
1804    justify-content: center;
1805    align-items: center;
1806
1807    transition: 0.8s cubic-bezier(0.16, 1, 0.32, 1);
1808    width: 300px;
1809    position: fixed;
1810    left: calc(50% - (300px / 2));
1811    z-index: 210;
1812    bottom: 16px;
1813    border-radius: 16px;
1814}
1815.DLP_Notification_Box {
1816    display: flex;
1817    width: 300px;
1818    padding: 16px;
1819    box-sizing: border-box;
1820    flex-direction: column;
1821    justify-content: flex-start;
1822    align-items: center;
1823    gap: 4px;
1824
1825    border-radius: 16px;
1826    outline: 2px solid rgb(var(--color-eel), 0.10);
1827    outline-offset: -2px;
1828    background: rgb(var(--color-snow), 0.90);
1829    backdrop-filter: blur(16px);
1830
1831    transition: 0.8s cubic-bezier(0.16, 1, 0.32, 1);
1832    filter: blur(16px);
1833    opacity: 0;
1834}
1835._2V6ug._1ursp._7jW2t._2hkLC._1wiIJ {
1836    width: 36px !important;
1837    height: 38px !important;
1838}
1839._2V6ug._1ursp._7jW2t._2hkLC._1wiIJ::before {
1840    border-radius: 20px !important;
1841}
1842.DLP_Tooltip {
1843    position: fixed;
1844    display: inline-flex;
1845    height: 40px;
1846    padding: 10px 14px;
1847    box-sizing: border-box;
1848    margin: 0;
1849    align-items: center;
1850    gap: 6px;
1851    flex-shrink: 0;
1852
1853    border-radius: 24px;
1854    outline: 2px solid rgb(var(--color-eel), 0.10);
1855    outline-offset: -2px;
1856    background: rgb(var(--color-snow), 0.90);
1857    backdrop-filter: blur(4px);
1858    filter: blur(8px);
1859
1860    font-family: Duolingo PRO Rounded;
1861    z-index: 10;
1862    opacity: 0;
1863    transition: opacity 0.5s ease-in-out, filter 0.5s ease-in-out;
1864    white-space: nowrap;
1865    pointer-events: none;
1866}
1867.DLP_Tooltip.DLP_Tooltip_Visible {
1868    opacity: 1;
1869    filter: blur(0px);
1870}
1871.DLP_Attachment_Box_1 {
1872    width: 96px;
1873    height: 96px;
1874    aspect-ratio: 1/1;
1875    object-fit: cover;
1876    overflow: hidden;
1877    position: relative;
1878
1879    border-radius: 8px;
1880    outline: 2px solid rgba(var(--color-black-white), 0.20);
1881    outline-offset: -2px;
1882    background: rgba(var(--color-black-text), 0.20); /* Gotta change */
1883}
1884.DLP_Attachment_Box_1_Content {
1885    width: 100%;
1886    height: 100%;
1887    aspect-ratio: 1/1;
1888    object-fit: cover;
1889}
1890.DLP_Attachment_Box_1_Hover {
1891    display: flex;
1892    width: 100%;
1893    height: 100%;
1894    position: absolute;
1895    top: 0;
1896    left: 0;
1897    right: 0;
1898    bottom: 0;
1899
1900    flex-direction: column;
1901    justify-content: center;
1902    align-items: center;
1903    flex-shrink: 0;
1904
1905    background: rgba(var(--color-snow), 0.50);
1906    backdrop-filter: blur(8px);
1907    outline: inherit;
1908    outline-offset: inherit;
1909    border-radius: inherit;
1910}
1911.DLP_Attachment_Box_Large_View_1 {
1912    display: flex;
1913    position: fixed;
1914    inset: 0;
1915    width: 100%;
1916    height: 100vh;
1917    justify-content: center;
1918    align-items: center;
1919    flex-shrink: 0;
1920
1921    background: rgba(var(--color-snow), 0.00);
1922    backdrop-filter: blur(0px);
1923    z-index: 211;
1924    transition: 0.4s cubic-bezier(0.16, 1, 0.32, 1);
1925}
1926.DLP_Attachment_Box_Drop_1 {
1927    display: flex;
1928    height: 48px;
1929    padding: 16px;
1930    justify-content: center;
1931    align-items: center;
1932    gap: 6px;
1933
1934    border-radius: 8px;
1935    /* outline: 2px dashed rgba(var(--DLP-blue), 0.20); */
1936    outline: 2px solid rgba(var(--DLP-blue), 0.20);
1937    outline-offset: -2px;
1938    background: linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.90);
1939}
1940
1941@keyframes slideRight {
1942    0% {
1943        transform: translateX(-150px);
1944    }
1945    20% {
1946        transform: translateX(200px);
1947    }
1948    100% {
1949        transform: translateX(200px);
1950    }
1951}
1952
1953`;
1954
1955HTML3 = `
1956<div class="DLP_Notification_Box" style="position: fixed;">
1957    <div class="DLP_HStack_4" style="align-items: center;">
1958        <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID DLP_NoSelect"></p>
1959        <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID" style="flex: 1 0 0;"></p>
1960        <p class="DLP_Text_Style_1 DLP_Inset_Icon_2_ID DLP_Magnetic_Hover_1 DLP_NoSelect" style="align-self: stretch;">􀆄</p>
1961    </div>
1962    <p class="DLP_Text_Style_1 DLP_Inset_Text_2_ID" style="opacity: 0.5; align-self: stretch; overflow-wrap: break-word;"></p>
1963</div>
1964`;
1965
1966HTML4 = `
1967.solving-btn {
1968    position: relative;
1969    min-width: 150px;
1970    font-size: 17px;
1971    border: none;
1972    border-bottom: 4px solid #2b70c9;
1973    border-radius: 16px;
1974    padding: 13px 16px;
1975    transition: filter .0s;
1976    font-weight: 700;
1977    letter-spacing: .8px;
1978    background: #1cb0f6;
1979    color: rgb(var(--color-snow));
1980    cursor: pointer;
1981}
1982.solve-btn {
1983    position: relative;
1984    min-width: 100px;
1985    font-size: 17px;
1986    border: none;
1987    border-bottom: 4px solid #ff9600;
1988    border-radius: 16px;
1989    padding: 13px 16px;
1990    transition: filter .0s;
1991    font-weight: 700;
1992    letter-spacing: .8px;
1993    background: #ffc800;
1994    color: rgb(var(--color-snow));
1995    cursor: pointer;
1996}
1997.auto-solver-btn:hover {
1998    filter: brightness(1.1);
1999}
2000.auto-solver-btn:active {
2001    border-bottom: 0px;
2002    margin-bottom: 4px;
2003    top: 4px;
2004}
2005`;
2006
2007HTML5 = `
2008<div class="DLP_AutoServer_Mother_Box" style="display: none; opacity: 0; filter: blur(8px);">
2009    <div class="DLP_AutoServer_Box DLP_Hide_Scrollbar">
2010        <div class="DLP_AutoServer_Menu_Bar">
2011            <div style="display: flex; justify-content: center; align-items: center; gap: 6px; opacity: 0.5;">
2012                <p id="DLP_AutoServer_Close_Button_1_ID" class="DLP_AutoServer_Text_Style_1 DLP_Magnetic_Hover_1" style="color: rgb(var(--color-black-text));">􀆄</p>
2013            </div>
2014            <div class="DLP_NoSelect" style="display: flex; justify-content: center; align-items: center; gap: 6px; opacity: 0.5;">
2015                <p class="DLP_AutoServer_Text_Style_1 DLP_Inset_Text_1_ID" style="color: rgb(var(--color-black-text));">Unavailable</p>
2016                <p class="DLP_AutoServer_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--color-black-text));">􀌔</p>
2017            </div>
2018        </div>
2019        <div class="DLP_AutoServer_Scroll_Box">
2020
2021            <div style="display: flex; justify-content: space-between; align-items: center; align-self: stretch;">
2022                <div style="display: flex; align-items: flex-end; gap: 4px;">
2023                    <p class="DLP_AutoServer_Text_Style_2 DLP_NoSelect">AutoServer</p>
2024                    <div class="DLP_HStack_4" style="align-items: center; padding-top: 6px;">
2025                        <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="opacity: 0.5;">by Duolingo</p>
2026                        <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="background: url(${serverURL}/static/images/flow/primary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">PRO</p>
2027                    </div>
2028                </div>
2029                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="font-size: 14px; background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${versionName}</p>
2030            </div>
2031
2032            <div class="DLP_AutoServer_Default_Box" style="background: linear-gradient(rgba(var(--color-snow), 0.8), rgba(var(--color-snow), 0.8)), url(${serverURL}/static/images/flow/primary/512/light.png); background-position: center; background-size: cover; background-repeat: no-repeat;">
2033                <div style="display: flex; display: none; flex-direction: column; align-items: flex-start; gap: 6px; align-self: stretch; width: 100%;">
2034                    <div class="DLP_HStack_Auto">
2035                        <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect">Settings</p>
2036                        <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect">􀍟</p>
2037                    </div>
2038                    <div class="DLP_HStack_Auto">
2039                        <div class="DLP_HStack_4" style="align-items: center;">
2040                            <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect">􀆪</p>
2041                            <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect">Timezone</p>
2042                        </div>
2043                        <p class="DLP_AutoServer_Text_Style_1">America/NewYork - 11:45 PM</p>
2044                    </div>
2045                </div>
2046                <div style="display: flex; flex-direction: column; align-items: flex-start; gap: 6px; align-self: stretch; width: 100%;">
2047                    <div class="DLP_HStack_Auto" style="align-items: center; width: 100%;">
2048                        <p class="DLP_AutoServer_Text_Style_1">Under Construction</p>
2049                        <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect">􀇿</p>
2050                    </div>
2051                    <p class="DLP_AutoServer_Text_Style_1" style="opacity: 0.5;">AutoServer is currently under construction and unavailable. We appreciate your patience and will provide updates as progress continues.</p>
2052                </div>
2053            </div>
2054
2055            <div class="DLP_AutoServer_Default_Box" style="height: 256px; background: linear-gradient(rgba(var(--color-snow), 0), rgba(var(--color-snow), 0)), url(${serverURL}/static/images/flow/primary/512/light.png); background-position: center; background-size: cover; background-repeat: no-repeat;">
2056                <div style="display: flex; width: 168px; flex-direction: column; justify-content: space-between; align-items: flex-start; align-self: stretch;">
2057                    <div class="DLP_VStack_6">
2058                        <div class="DLP_HStack_Auto">
2059                            <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">􀙭</p>
2060                            <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">Streak Protector</p>
2061                        </div>
2062                        <div class="DLP_HStack_Auto">
2063                            <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0;">BETA</p>
2064                            <div class="DLP_HStack_4 DLP_Magnetic_Hover_1">
2065                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">Active</p>
2066                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: #FFF;">􀃳</p>
2067                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: #FFF; display: none;">􀂒</p>
2068                            </div>
2069                        </div>
2070                    </div>
2071                    <div class="DLP_VStack_12">
2072                        <div class="DLP_VStack_6">
2073                            <div class="DLP_HStack_Auto">
2074                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">Protecting:</p>
2075                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0;">BETA</p>
2076                            </div>
2077                            <div class="DLP_HStack_Auto">
2078                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Magnetic_Hover_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀃟</p>
2079                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">2 Days</p>
2080                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Magnetic_Hover_1 DLP_Inset_Icon_2_ID" style="color: #FFF;">􀑎</p>
2081                            </div>
2082                        </div>
2083                        <div class="DLP_VStack_6">
2084                            <div class="DLP_HStack_Auto">
2085                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">Protecting Time:</p>
2086                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0;">BETA</p>
2087                            </div>
2088                            <div class="DLP_HStack_Auto">
2089                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Magnetic_Hover_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀄃</p>
2090                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">Morning</p>
2091                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Magnetic_Hover_1 DLP_Inset_Icon_2_ID" style="color: #FFF;">􀯿</p>
2092                            </div>
2093                        </div>
2094                    </div>
2095                </div>
2096                <div style="display: flex; flex-direction: column; align-items: flex-start; gap: 6px; flex: 1 0 0; align-self: stretch;">
2097                    <div class="DLP_VStack_6" style="height: 100%; justify-content: flex-start;">
2098                        <div class="DLP_HStack_Auto">
2099                            <div class="DLP_HStack_4">
2100                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">􀅵</p>
2101                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">Info</p>
2102                            </div>
2103                            <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">This function is in BETA</p>
2104                        </div>
2105                        <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">Streak Protector extends your streak by completing a lesson in our servers.</p>
2106                        <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">You can only protect your streak for up to 7 days. Donate to protect longer.</p>
2107                        <div style="display: flex; justify-content: flex-end; align-items: flex-end; gap: 6px; flex: 1 0 0; align-self: stretch;">
2108                            <p class="DLP_AutoServer_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">Learn More</p>
2109                        </div>
2110                    </div>
2111                </div>
2112            </div>
2113
2114            <div class="DLP_AutoServer_Default_Box" style="height: 256px; background: linear-gradient(rgba(var(--color-snow), 0), rgba(var(--color-snow), 0)), url(${serverURL}/static/images/flow/secondary/512/light.png); background-position: center; background-size: cover; background-repeat: no-repeat;">
2115                <div style="display: flex; width: 168px; flex-direction: column; justify-content: space-between; align-items: flex-start; align-self: stretch;">
2116                    <div class="DLP_VStack_6">
2117                        <div class="DLP_HStack_Auto">
2118                            <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">􀙨</p>
2119                            <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">League Protector</p>
2120                        </div>
2121                        <div class="DLP_HStack_Auto">
2122                            <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0;">BETA</p>
2123                            <div class="DLP_HStack_4 DLP_Magnetic_Hover_1">
2124                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">Active</p>
2125                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: #FFF;">􀃳</p>
2126                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Inset_Icon_1_ID" style="color: #FFF; display: none;">􀂒</p>
2127                            </div>
2128                        </div>
2129                    </div>
2130                    <div class="DLP_VStack_12">
2131                        <div class="DLP_VStack_6">
2132                            <div class="DLP_HStack_Auto">
2133                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">Protecting:</p>
2134                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0;">BETA</p>
2135                            </div>
2136                            <div class="DLP_HStack_Auto">
2137                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Magnetic_Hover_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀃟</p>
2138                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">5 Days</p>
2139                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Magnetic_Hover_1 DLP_Inset_Icon_2_ID" style="color: #FFF;">􀑎</p>
2140                            </div>
2141                        </div>
2142                        <div class="DLP_VStack_6">
2143                            <div class="DLP_HStack_Auto">
2144                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">Protecting Mode:</p>
2145                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0;">BETA</p>
2146                            </div>
2147                            <div class="DLP_HStack_Auto">
2148                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Magnetic_Hover_1 DLP_Inset_Icon_1_ID" style="color: #FFF;">􀄃</p>
2149                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">Chill</p>
2150                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect DLP_Magnetic_Hover_1 DLP_Inset_Icon_2_ID" style="color: #FFF;">􀯿</p>
2151                            </div>
2152                        </div>
2153                    </div>
2154                </div>
2155                <div style="display: flex; flex-direction: column; align-items: flex-start; gap: 6px; flex: 1 0 0; align-self: stretch;">
2156                    <div class="DLP_VStack_6" style="height: 100%; justify-content: flex-start;">
2157                        <div class="DLP_HStack_Auto">
2158                            <div class="DLP_HStack_4">
2159                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">􀅵</p>
2160                                <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF;">Info</p>
2161                            </div>
2162                            <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">This function is in BETA</p>
2163                        </div>
2164                        <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">League Protector protects your league position by completing lessons in our servers.</p>
2165                        <p class="DLP_AutoServer_Text_Style_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">You only have access to Chill and Standard Mode with up to 7 days of protection. Donate to get access to Aggressive Mode and longer protection.</p>
2166                        <div style="display: flex; justify-content: flex-end; align-items: flex-end; gap: 6px; flex: 1 0 0; align-self: stretch;">
2167                            <p class="DLP_AutoServer_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect" style="color: #FFF; opacity: 0.5;">Learn More</p>
2168                        </div>
2169                    </div>
2170                </div>
2171            </div>
2172
2173        </div>
2174    </div>
2175</div>
2176`;
2177CSS5 = `
2178.DLP_AutoServer_Text_Style_1 {
2179    font-family: "Duolingo PRO Rounded";
2180    font-size: 16px;
2181    font-style: normal;
2182    font-weight: 500;
2183    line-height: normal;
2184
2185    margin: 0;
2186    -webkit-font-smoothing: antialiased;
2187}
2188.DLP_AutoServer_Text_Style_2 {
2189    font-family: "Duolingo PRO Rounded";
2190    font-size: 24px;
2191    font-style: normal;
2192    font-weight: 500;
2193    line-height: normal;
2194
2195    margin: 0;
2196    -webkit-font-smoothing: antialiased;
2197}
2198.DLP_AutoServer_Mother_Box {
2199    position: fixed;
2200    top: 0;
2201    bottom: 0;
2202    right: 0;
2203    left: 0;
2204    display: flex;
2205    width: 100%;
2206    height: 100vh;
2207    justify-content: center;
2208    align-items: center;
2209    flex-shrink: 0;
2210    z-index: 210;
2211    transition: filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), opacity 0.4s cubic-bezier(0.16, 1, 0.32, 1);
2212
2213    background: rgba(var(--color-snow), 0.50);
2214    backdrop-filter: blur(16px);
2215}
2216
2217.DLP_AutoServer_Box {
2218    display: flex;
2219    width: 512px;
2220    height: 512px;
2221    flex-direction: column;
2222    align-items: center;
2223    flex-shrink: 0;
2224    overflow-y: scroll;
2225    overflow-x: hidden;
2226    scrollbar-width: none;
2227    -ms-overflow-style: none;
2228
2229    border-radius: 20px;
2230    border: 2px solid rgba(var(--color-eel), 0.10);
2231    background: rgba(var(--color-snow), 0.90);
2232    backdrop-filter: blur(16px);
2233    box-sizing: border-box;
2234}
2235
2236.DLP_AutoServer_Menu_Bar {
2237    display: flex;
2238    width: 100%;
2239    height: 64px;
2240    padding: 16px;
2241    justify-content: space-between;
2242    align-items: center;
2243
2244    position: sticky;
2245    top: 0;
2246    right: 0;
2247    left: 0;
2248
2249    background: rgba(var(--color-snow), 0.80);
2250    backdrop-filter: blur(8px);
2251    z-index: 2;
2252}
2253
2254.DLP_AutoServer_Scroll_Box {
2255    display: flex;
2256    padding: 0 16px 16px 16px;
2257    flex-direction: column;
2258    justify-content: center;
2259    align-items: center;
2260    gap: 8px;
2261    align-self: stretch;
2262}
2263
2264.DLP_AutoServer_Default_Box {
2265    display: flex;
2266    padding: 16px;
2267    justify-content: center;
2268    align-items: center;
2269    gap: 16px;
2270    align-self: stretch;
2271
2272    border-radius: 8px;
2273    outline: 2px solid rgba(0, 0, 0, 0.10);
2274    outline-offset: -2px;
2275}
2276`;
2277
2278HTML6 = `
2279<div class="DPAutoServerButtonMainMenu">
2280    <svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
2281        <g clip-path="url(#clip0_952_270)">
2282            <rect width="30" height="30" rx="15" fill="rgb(var(--DLP-blue))"/>
2283            <path d="M19.9424 20.5947H10.4404C7.96582 20.5947 6.04492 18.7764 6.04492 16.582C6.04492 14.8115 7.02246 13.3623 8.61523 13.0342C8.73145 11.0859 10.5361 9.77344 12.3545 10.1904C13.2773 8.88477 14.7061 8.02344 16.4766 8.02344C19.4502 8.02344 21.7334 10.2998 21.7402 13.458C23.1279 14.0322 23.9551 15.3926 23.9551 16.876C23.9551 18.9404 22.1777 20.5947 19.9424 20.5947ZM10.6318 16.1445C10.2285 16.6504 10.6934 17.1904 11.2539 16.9102L13.4688 15.7549L16.1006 17.2109C16.2578 17.2998 16.4082 17.3477 16.5586 17.3477C16.7705 17.3477 16.9688 17.2383 17.1465 17.0195L19.3818 14.1963C19.7646 13.7109 19.3203 13.1641 18.7598 13.4443L16.5312 14.5928L13.9062 13.1436C13.7422 13.0547 13.5986 13.0068 13.4414 13.0068C13.2363 13.0068 13.0381 13.1094 12.8535 13.335L10.6318 16.1445Z" fill="white"/>
2284        </g>
2285        <defs>
2286            <clipPath id="clip0_952_270">
2287                <rect width="30" height="30" rx="15" fill="#FFF"/>
2288            </clipPath>
2289        </defs>
2290    </svg>
2291    <p class="DPAutoServerElementsMenu DLP_NoSelect" style="flex: 1 0 0; color: rgb(var(--DLP-blue)); font-size: 16px; font-style: normal; font-weight: 700; line-height: normal; margin: 0px;">AUTOSERVER</p>
2292    <svg class="DPAutoServerElementsMenu" style="opacity: 0;" width="9" height="16" viewBox="0 0 9 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2293        <path d="M8.57031 7.85938C8.57031 8.24219 8.4375 8.5625 8.10938 8.875L2.20312 14.6641C1.96875 14.8984 1.67969 15.0156 1.33594 15.0156C0.648438 15.0156 0.0859375 14.4609 0.0859375 13.7734C0.0859375 13.4219 0.226562 13.1094 0.484375 12.8516L5.63281 7.85156L0.484375 2.85938C0.226562 2.60938 0.0859375 2.28906 0.0859375 1.94531C0.0859375 1.26562 0.648438 0.703125 1.33594 0.703125C1.67969 0.703125 1.96875 0.820312 2.20312 1.05469L8.10938 6.84375C8.42969 7.14844 8.57031 7.46875 8.57031 7.85938Z" fill="rgb(var(--DLP-blue))"/>
2294    </svg>
2295</div>
2296`;
2297CSS6 = `
2298.DPAutoServerButtonMainMenu {
2299	display: flex;
2300	box-sizing: border-box;
2301	justify-content: center;
2302	align-items: center;
2303	gap: 16px;
2304	flex-shrink: 0;
2305
2306	border-radius: 12px;
2307
2308	cursor: pointer;
2309}
2310.DPAutoServerButtonMainMenu:hover {
2311	background: rgba(var(--DLP-blue), 0.10);
2312}
2313.DPAutoServerButtonMainMenu:active {
2314	filter: brightness(.9);
2315
2316}
2317
2318.DPAutoServerButtonMainMenu:hover .DPAutoServerElementsMenu {
2319	opacity: 1 !important;
2320}
2321
2322.DPAutoServerButtonMainMenuMedium {
2323	width: 56px;
2324	height: 52px;
2325	padding: 8px;
2326}
2327
2328.DPAutoServerButtonMainMenuLarge {
2329	width: 222px;
2330	height: 52px;
2331	padding: 16px 17px;
2332}
2333`;
2334HTML7 = `
2335<div id="DLP_The_Bar_Thing_Box" class="DuolingoProCounterBoxOneClass" style="display: inline-flex; justify-content: center; flex-direction: row-reverse; align-items: center; gap: 4px;">
2336    <div class="vCIrKKxykXwXyUza DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Button_1_ID">
2337        <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--color-eel)); display: none;">􀯠</p>
2338        <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID"></p>
2339    </div>
2340    <div class="vCIrKKxykXwXyUza DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Button_2_ID">
2341        <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--color-eel));">􀊣</p>
2342        <p class="DLP_Text_Style_1 DLP_Inset_Text_1_ID">Mute</p>
2343    </div>
2344    <div class="vCIrKKxykXwXyUza DLP_Magnetic_Hover_1 DLP_NoSelect DLP_Inset_Button_3_ID" style="width: 40px; padding: 0;">
2345        <p class="DLP_Text_Style_1 DLP_Inset_Icon_1_ID" style="color: rgb(var(--color-eel)); transition: all 0.8s cubic-bezier(0.16, 1, 0.32, 1);">􀯸</p>
2346    </div>
2347</div>
2348`;
2349CSS7 = `
2350.vCIrKKxykXwXyUza {
2351    outline: 2px solid rgb(var(--color-swan));
2352    outline-offset: -2px;
2353    height: 40px;
2354    width: auto;
2355    padding: 0 16px;
2356    gap: 6px;
2357    display: inline-flex;
2358    justify-content: center;
2359    align-items: center;
2360    flex-wrap: nowrap;
2361    flex-shrink: 0;
2362
2363    border-radius: 32px;
2364    background: rgb(var(--color-snow), 0.84);
2365    backdrop-filter: blur(16px);
2366    overflow: hidden;
2367
2368    transition: all 0.4s cubic-bezier(0.16, 1, 0.32, 1);
2369    cursor: pointer;
2370}
2371.vCIrKKxykXwXyUza p {
2372    white-space: nowrap;
2373}
2374.vCIrKKxykXwXyUza svg {
2375    flex-shrink: 0;
2376}
2377`;
2378}
2379
2380function One() {
2381    Two();
2382
2383    document.head.appendChild(Object.assign(document.createElement('style'), { type: 'text/css', textContent: CSS1 }));
2384    document.body.insertAdjacentHTML('beforeend', HTML2);
2385    document.head.appendChild(Object.assign(document.createElement('style'), { type: 'text/css', textContent: CSS2 }));
2386
2387    document.body.insertAdjacentHTML('beforeend', HTML5);
2388    document.head.appendChild(Object.assign(document.createElement('style'), { type: 'text/css', textContent: CSS5 }));
2389
2390    let DPAutoServerButtonMainMenuElement = null;
2391    let DPAutoServerButtonMainMenuStyle = null;
2392
2393    function DPAutoServerButtonMainMenuFunction() {
2394        try {
2395            if (storageLocal.settings.showAutoServerButton && alpha) {
2396                let targetElement = document.querySelector('._2uLXp');
2397                if (!targetElement || document.querySelector('.DPAutoServerButtonMainMenu')) return;
2398
2399                DPAutoServerButtonMainMenuStyle = document.createElement('style');
2400                DPAutoServerButtonMainMenuStyle.type = 'text/css';
2401                DPAutoServerButtonMainMenuStyle.innerHTML = CSS6;
2402                document.head.appendChild(DPAutoServerButtonMainMenuStyle);
2403
2404                let targetDivLast = document.querySelector('[data-test="profile-tab"]');
2405
2406                if (targetElement && targetDivLast) {
2407                    targetElement.lastChild.insertAdjacentHTML('beforebegin', HTML6);
2408
2409                    let otherTargetDiv = document.querySelector('.DPAutoServerButtonMainMenu');
2410                    otherTargetDiv.addEventListener('click', () => {
2411                        manageAutoServerWindowVisibility(true);
2412                    });
2413
2414                    let lastWidth = targetElement.offsetWidth;
2415                    const resizeObserver = new ResizeObserver(entries => {
2416                        for (let entry of entries) {
2417                            if (entry.target.offsetWidth !== lastWidth) {
2418                                otherTargetDiv.remove();
2419                                DPAutoServerButtonMainMenuFunction();
2420                                lastWidth = entry.target.offsetWidth;
2421                            }
2422                        }
2423                    });
2424                    resizeObserver.observe(targetElement);
2425
2426                    if (targetElement.offsetWidth < 100) {
2427                        otherTargetDiv.classList.add('DPAutoServerButtonMainMenuMedium');
2428                        document.querySelectorAll('.DPAutoServerElementsMenu').forEach(function(element) {
2429                            element.remove();
2430                        });
2431                    } else {
2432                        otherTargetDiv.classList.add('DPAutoServerButtonMainMenuLarge');
2433                    }
2434                }
2435            }
2436        } catch(error) {}
2437    }
2438    setInterval(DPAutoServerButtonMainMenuFunction, 500);
2439
2440    document.querySelector('.DLP_AutoServer_Mother_Box').querySelector('#DLP_AutoServer_Close_Button_1_ID').addEventListener('click', () => {
2441        manageAutoServerWindowVisibility(false);
2442    });
2443    document.querySelector('.DLP_AutoServer_Mother_Box').addEventListener('click', (event) => {
2444        if (event.target === event.currentTarget) {
2445            manageAutoServerWindowVisibility(false);
2446        }
2447    });
2448    function manageAutoServerWindowVisibility(state) {
2449        if (state) {
2450            document.querySelector('.DLP_AutoServer_Mother_Box').style.display = "";
2451            document.querySelector('.DLP_AutoServer_Mother_Box').offsetHeight;
2452            document.querySelector('.DLP_AutoServer_Mother_Box').style.opacity = "1";
2453            document.querySelector('.DLP_AutoServer_Mother_Box').style.filter = "blur(0px)";
2454        } else {
2455            document.querySelector('.DLP_AutoServer_Mother_Box').style.opacity = "0";
2456            document.querySelector('.DLP_AutoServer_Mother_Box').style.filter = "blur(8px)";
2457            setTimeout(() => {
2458                document.querySelector('.DLP_AutoServer_Mother_Box').style.display = "none";
2459            }, 400);
2460        }
2461    }
2462
2463    let counterPaused = false;
2464    function DuolingoProCounterOneFunction() {
2465        function handleMuteTab(value) {
2466            if (isBusySwitchingPages) return;
2467            isBusySwitchingPages = true;
2468            muteTab(value);
2469            let button = document.querySelector('#DLP_Inset_Button_2_ID');
2470            if (value) {
2471                setButtonState(button, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: 'Muted', icon: '􀊣'}, {text: '', icon: ' '}, () => {
2472                    setTimeout(() => {
2473                        isBusySwitchingPages = false;
2474                    }, 400);
2475                });
2476            } else {
2477                setButtonState(button, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: 'Mute', icon: '􀊧'}, {text: '', icon: ' '}, () => {
2478                    setTimeout(() => {
2479                        isBusySwitchingPages = false;
2480                    }, 400);
2481                });
2482            }
2483        }
2484
2485        if ((window.location.pathname.includes('/lesson') || window.location.pathname.includes('/practice')) && storageSession.legacy.status) {
2486            let theBarThing = document.querySelector('#DLP_The_Bar_Thing_Box');
2487            if (!theBarThing) {
2488                document.head.appendChild(Object.assign(document.createElement('style'), { type: 'text/css', textContent: CSS7 }));
2489                //const targetElement1 = document.querySelector('.I-Avc._1zcW8');
2490                const targetElement1 = document.querySelector('._1zcW8');
2491                const targetElement2 = document.querySelector('.mAxZF');
2492                if (targetElement1) {
2493                    targetElement1.insertAdjacentHTML('beforeend', HTML7);
2494                    theBarThing = document.querySelector('#DLP_The_Bar_Thing_Box');
2495                    targetElement1.style.display = "flex";
2496                    document.querySelector('[role="progressbar"]').style.width = "100%";
2497                } else if (targetElement2) {
2498                    targetElement2.insertAdjacentHTML('beforeend', HTML7);
2499                    theBarThing = document.querySelector('#DLP_The_Bar_Thing_Box');
2500                    theBarThing.style.marginLeft = '24px';
2501                    document.querySelector('._15ch1').style.pointerEvents = 'all';
2502                }
2503                else if (debug) console.log('Element with class ._1zcW8 or .mAxZF not found');
2504
2505                let muteButton = theBarThing.querySelector('.DLP_Inset_Button_2_ID');
2506                let expandButton = theBarThing.querySelector('.DLP_Inset_Button_3_ID');
2507                let expandButtonIcon = expandButton.querySelector('.DLP_Inset_Icon_1_ID');
2508                let theBarThingExtended = false;
2509                function theBarThingExtend(button, visibility, noAnimation) {
2510                    if (visibility) {
2511                        button.style.display = "";
2512                        button.style.width = "";
2513                        button.style.padding = "";
2514                        button.style.transition = '';
2515                        let remember0010 = button.offsetWidth;
2516                        button.style.width = "0px";
2517                        requestAnimationFrame(() => {
2518                            button.style.width = remember0010 + "px";
2519                            button.style.padding = "";
2520                            button.style.filter = "blur(0px)";
2521                            button.style.opacity = "1";
2522                            button.style.margin = "";
2523                        });
2524                    } else {
2525                        button.style.transition = '';
2526                        button.style.width = button.offsetWidth + "px";
2527                        requestAnimationFrame(() => {
2528                            button.style.width = "4px";
2529                            button.style.padding = "0";
2530                            button.style.filter = "blur(8px)";
2531                            button.style.margin = "0 -4px";
2532                            button.style.opacity = "0";
2533                        });
2534                        if (!noAnimation) {
2535                            setTimeout(function() {
2536                                button.style.display = "none";
2537                            }, 400);
2538                        } else {
2539                            button.style.display = "none";
2540                        }
2541                    }
2542                }
2543                theBarThingExtend(muteButton, false, true);
2544                expandButton.addEventListener('click', () => {
2545                    if (theBarThingExtended) {
2546                        expandButtonIcon.style.transform = "rotate(0deg)";
2547                        theBarThingExtended = false;
2548                        theBarThingExtend(muteButton, false);
2549                    } else {
2550                        expandButtonIcon.style.transform = "rotate(180deg)";
2551                        theBarThingExtended = true;
2552                        theBarThingExtend(muteButton, true);
2553                    }
2554                });
2555
2556                let counterButton = theBarThing.querySelector('.DLP_Inset_Button_1_ID');
2557                counterButton.addEventListener('click', () => {
2558                    if (isBusySwitchingPages) return;
2559                    isBusySwitchingPages = true;
2560                    if (theBarThing.querySelector('#DLP_Inset_Button_1_ID').querySelector('#DLP_Inset_Text_1_ID').innerHTML === 'Click Again to Stop Legacy') {
2561                        setButtonState(counterButton, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: 'Stopping', icon: undefined}, {text: '', icon: ''}, () => {
2562                            storageSession.legacy.status = false;
2563                            saveStorageSession();
2564                            setTimeout(() => {
2565                                isBusySwitchingPages = false;
2566                                window.location.href = "https://duolingo.com";
2567                            }, 400);
2568                        });
2569                    } else {
2570                        counterPaused = true;
2571                        setButtonState(counterButton, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: 'Click Again to Stop', icon: undefined}, {text: '', icon: ''}, () => {
2572                            setTimeout(() => {
2573                                isBusySwitchingPages = false;
2574                                setTimeout(() => {
2575                                    if (storageSession.legacy.status) counterPaused = false;
2576                                }, 4000);
2577                            }, 400);
2578                        });
2579                    }
2580                });
2581
2582                if (storageLocal.settings.muteLessons) {
2583                    handleMuteTab(true);
2584                }
2585
2586                document.querySelector('#DLP_Inset_Button_2_ID').addEventListener('click', () => {
2587                    storageLocal.settings.muteLessons = !storageLocal.settings.muteLessons;
2588                    saveStorageLocal();
2589                    handleMuteTab(storageLocal.settings.muteLessons);
2590                });
2591            }
2592
2593            function updateCounter() {
2594                let button = theBarThing.querySelector('.DLP_Inset_Button_1_ID');
2595                let text = button.querySelector('.DLP_Inset_Text_1_ID');
2596
2597                if (storageSession.legacy[storageSession.legacy.status].type === 'infinity' && text.textContent !== 'Infinity') {
2598                    isBusySwitchingPages = true;
2599                    setButtonState(button, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: 'Infinity', icon: '􀯠'}, {text: '', icon: ''}, () => {
2600                        setTimeout(() => {
2601                            isBusySwitchingPages = false;
2602                        }, 400);
2603                    });
2604                } else if (storageSession.legacy[storageSession.legacy.status].type === 'xp' && text.textContent !== String(storageSession.legacy[storageSession.legacy.status].amount + ' XP Left')) {
2605                    isBusySwitchingPages = true;
2606                    setButtonState(button, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: String(storageSession.legacy[storageSession.legacy.status].amount + ' XP Left'), icon: ''}, {text: '', icon: ''}, () => {
2607                        setTimeout(() => {
2608                            isBusySwitchingPages = false;
2609                        }, 400);
2610                    });
2611                } else if (window.location.pathname === '/practice') {
2612                    if (storageSession.legacy[storageSession.legacy.status].amount === 1 && text.textContent !== 'Last Practice') {
2613                        isBusySwitchingPages = true;
2614                        setButtonState(button, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: 'Last Practice', icon: ''}, {text: '', icon: ''}, () => {
2615                            setTimeout(() => {
2616                                isBusySwitchingPages = false;
2617                            }, 400);
2618                        });
2619                    } else if (storageSession.legacy[storageSession.legacy.status].amount === 0 && text.textContent !== 'Finishing Up') {
2620                        isBusySwitchingPages = true;
2621                        setButtonState(button, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: 'Finishing Up', icon: ''}, {text: '', icon: ''}, () => {
2622                            setTimeout(() => {
2623                                isBusySwitchingPages = false;
2624                            }, 400);
2625                        });
2626                    } else if (storageSession.legacy[storageSession.legacy.status].amount > 1 && text.textContent !== String(storageSession.legacy[storageSession.legacy.status].amount + ' Practices Left')) {
2627                        isBusySwitchingPages = true;
2628                        setButtonState(button, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: String(storageSession.legacy[storageSession.legacy.status].amount + ' Practices Left'), icon: ''}, {text: '', icon: ''}, () => {
2629                            setTimeout(() => {
2630                                isBusySwitchingPages = false;
2631                            }, 400);
2632                        });
2633                    }
2634                } else if (storageSession.legacy[storageSession.legacy.status].type === 'lesson') {
2635                    if (storageSession.legacy[storageSession.legacy.status].amount === 1 && text.textContent !== 'Last Lesson') {
2636                        isBusySwitchingPages = true;
2637                        setButtonState(button, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: 'Last Lesson', icon: ''}, {text: '', icon: ''}, () => {
2638                            setTimeout(() => {
2639                                isBusySwitchingPages = false;
2640                            }, 400);
2641                        });
2642                    } else if (storageSession.legacy[storageSession.legacy.status].amount === 0 && text.textContent !== 'Finishing Up') {
2643                        isBusySwitchingPages = true;
2644                        setButtonState(button, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: 'Finishing Up', icon: ''}, {text: '', icon: ''}, () => {
2645                            setTimeout(() => {
2646                                isBusySwitchingPages = false;
2647                            }, 400);
2648                        });
2649                    } else if (storageSession.legacy[storageSession.legacy.status].amount > 1 && text.textContent !== String(storageSession.legacy[storageSession.legacy.status].amount + ' Lessons Left')) {
2650                        isBusySwitchingPages = true;
2651                        setButtonState(button, {button: 'rgb(var(--color-snow), 0.84)', outline: 'rgb(var(--color-swan))', text: 'rgb(var(--color-black-text))', icon: 'rgb(var(--color-black-text))'}, {text: String(storageSession.legacy[storageSession.legacy.status].amount + ' Lessons Left'), icon: ''}, {text: '', icon: ''}, () => {
2652                            setTimeout(() => {
2653                                isBusySwitchingPages = false;
2654                            }, 400);
2655                        });
2656                    }
2657                }
2658            }
2659
2660            if (!counterPaused) updateCounter();
2661        }
2662    }
2663    setInterval(DuolingoProCounterOneFunction, 500);
2664
2665
2666    window.onfocus = () => {
2667        windowBlurState = true;
2668    };
2669    window.onblur = () => {
2670        windowBlurState = false;
2671    };
2672
2673    function addButtons() {
2674        if (!storageLocal.settings.showSolveButtons) return;
2675        if (window.location.pathname === '/learn' && document.querySelector('a[data-test="global-practice"]')) return;
2676        if (document.querySelector("#solveAllButton")) return;
2677
2678        document.querySelector('[data-test="quit-button"]')?.addEventListener('click', function() {
2679            solving("stop");
2680            //storageSession.legacy.status = false;
2681            //saveStorageSession();
2682        });
2683
2684        function createButton(id, text, styleClass, eventHandlers) {
2685            const button = document.createElement('button');
2686            button.id = id;
2687            button.innerText = text;
2688            button.className = styleClass;
2689            Object.keys(eventHandlers).forEach(event => {
2690                button.addEventListener(event, eventHandlers[event]);
2691            });
2692            return button;
2693        }
2694
2695        const nextButton = document.querySelector('[data-test="player-next"]');
2696        const storiesContinueButton = document.querySelector('[data-test="stories-player-continue"]');
2697        const storiesDoneButton = document.querySelector('[data-test="stories-player-done"]');
2698        const target = nextButton || storiesContinueButton || storiesDoneButton;
2699
2700        if (document.querySelector('[data-test="story-start"]') && storageSession.legacy.status) {
2701            document.querySelector('[data-test="story-start"]').click();
2702        }
2703        if (!target) {
2704            const startButton = document.querySelector('[data-test="start-button"]');
2705            if (!startButton) {
2706                return;
2707            }
2708            const solveAllButton = createButton("solveAllButton", "COMPLETE SKILL", "solve-all-btn", {
2709                'click': () => {
2710                    solving(true);
2711                    setInterval(() => {
2712                        const startButton = document.querySelector('[data-test="start-button"]');
2713                        if (startButton && startButton.innerText.startsWith("START")) {
2714                            startButton.click();
2715                        }
2716                    }, 1000);
2717                    startButton.click();
2718                }
2719            });
2720            startButton.parentNode.appendChild(solveAllButton);
2721        } else {
2722            if (document.querySelector('.MYehf') !== null) {
2723                document.querySelector('.MYehf').style.display = "flex";
2724                document.querySelector('.MYehf').style.gap = "20px";
2725            } else if (document.querySelector(".FmlUF") !== null) { // Story
2726                findReactMainElementClass = '_3TJzR';
2727                reactTraverseUp = 0;
2728                document.querySelector('._3TJzR').style.display = "flex";
2729                document.querySelector('._3TJzR').style.gap = "20px";
2730            }
2731
2732            const buttonsCSS = document.createElement('style');
2733            buttonsCSS.innerHTML = HTML4;
2734            document.head.appendChild(buttonsCSS);
2735
2736            const solveCopy = createButton('solveAllButton', systemText[systemLanguage][101], 'auto-solver-btn solving-btn', { click: solving });
2737            const pauseCopy = createButton('', systemText[systemLanguage][100], 'auto-solver-btn solve-btn', { click: solve });
2738
2739            target.parentElement.appendChild(pauseCopy);
2740            target.parentElement.appendChild(solveCopy);
2741
2742            if (storageSession.legacy.status) {
2743                solving("start");
2744            }
2745        }
2746    }
2747    setInterval(addButtons, 500);
2748
2749
2750
2751    let notificationCount = 0;
2752    let currentNotification = [];
2753    let notificationsHovered = false;
2754
2755    const notificationMain = document.querySelector('.DLP_Notification_Main');
2756    notificationMain.addEventListener('mouseenter', () => {
2757        notificationsHovered = true;
2758    });
2759    notificationMain.addEventListener('mouseleave', () => {
2760        notificationsHovered = false;
2761    });
2762
2763    function showNotification(icon, head, body, time = 0) {
2764        notificationCount++;
2765        let notificationID = notificationCount;
2766        currentNotification.push(notificationID);
2767
2768        let element = new DOMParser().parseFromString(HTML3, 'text/html').body.firstChild;
2769        element.id = 'DLP_Notification_Box_' + notificationID + '_ID';
2770        notificationMain.appendChild(element);
2771        initializeMagneticHover(element.querySelector('.DLP_Inset_Icon_2_ID'));
2772
2773        let iconElement = element.querySelector('.DLP_Inset_Icon_1_ID');
2774        if (icon === "") {
2775            iconElement.style.display = 'none';
2776            playHaptic();
2777        } else if (icon === "checkmark") {
2778            iconElement.style.color = "rgb(var(--DLP-green))";
2779            iconElement.textContent = "􀁣";
2780            playHaptic("success");
2781        } else if (icon === "warning") {
2782            iconElement.style.color = "rgb(var(--DLP-orange))";
2783            iconElement.textContent = "􀁟";
2784            playHaptic("warning");
2785        } else if (icon === "error") {
2786            iconElement.style.color = "rgb(var(--DLP-pink))";
2787            iconElement.textContent = "􀇿";
2788            playHaptic("error");
2789        } else {
2790            iconElement.style.color = icon.color;
2791            iconElement.textContent = icon.icon;
2792            playHaptic();
2793        }
2794
2795        element.querySelector('.DLP_Inset_Text_1_ID').innerHTML = head;
2796        if (body && body !== "") {
2797            element.querySelector('.DLP_Inset_Text_2_ID').innerHTML = body;
2798        } else {
2799            element.querySelector('.DLP_Inset_Text_2_ID').style.display = "none";
2800        }
2801
2802        let notification = document.querySelector(
2803            '#DLP_Notification_Box_' + notificationID + '_ID'
2804        );
2805        let notificationHeight = notification.offsetHeight;
2806        notification.style.bottom = '-' + notificationHeight + 'px';
2807
2808        setTimeout(() => {
2809            requestAnimationFrame(() => {
2810                notification.style.bottom = "16px";
2811                notification.style.filter = "blur(0px)";
2812                notification.style.opacity = "1";
2813            });
2814        }, 50);
2815
2816        let isBusyDisappearing = false;
2817
2818        let timerData = null;
2819        if (time !== 0) {
2820            timerData = {
2821                remaining: time * 1000,
2822                lastTimestamp: Date.now(),
2823                timeoutHandle: null,
2824                paused: false,
2825            };
2826            timerData.timeoutHandle = setTimeout(internalDisappear, timerData.remaining);
2827        }
2828
2829        let repeatInterval = setInterval(() => {
2830            if (document.body.offsetWidth <= 963) {
2831                requestAnimationFrame(() => {
2832                    notificationMain.style.width = "300px";
2833                    notificationMain.style.position = "fixed";
2834                    notificationMain.style.left = "16px";
2835                });
2836            } else {
2837                requestAnimationFrame(() => {
2838                    notificationMain.style.width = "";
2839                    notificationMain.style.position = "";
2840                    notificationMain.style.left = "";
2841                });
2842            }
2843
2844            if (isBusyDisappearing) return;
2845
2846            if (timerData) {
2847                if (notificationsHovered && !timerData.paused) {
2848                    clearTimeout(timerData.timeoutHandle);
2849                    let elapsed = Date.now() - timerData.lastTimestamp;
2850                    timerData.remaining -= elapsed;
2851                    timerData.paused = true;
2852                }
2853                if (!notificationsHovered && timerData.paused) {
2854                    timerData.paused = false;
2855                    timerData.lastTimestamp = Date.now();
2856                    timerData.timeoutHandle = setTimeout(internalDisappear, timerData.remaining);
2857                }
2858            }
2859
2860            if (notificationsHovered) {
2861                let allIDs = currentNotification.slice();
2862                let bottoms = {};
2863                let currentBottom = 16;
2864                for (let i = allIDs.length - 1; i >= 0; i--) {
2865                    let notifEl = document.querySelector(
2866                        '#DLP_Notification_Box_' + allIDs[i] + '_ID'
2867                    );
2868                    if (!notifEl) continue;
2869                    notifEl.style.width = "";
2870                    notifEl.style.height = "";
2871                    notifEl.style.transform = "";
2872                    bottoms[allIDs[i]] = currentBottom;
2873                    currentBottom += notifEl.offsetHeight + 8;
2874                }
2875                notification.style.bottom = bottoms[notificationID] + "px";
2876
2877                let totalHeight = 0;
2878                for (let i = 0; i < allIDs.length; i++) {
2879                    let notifEl = document.querySelector(
2880                        '#DLP_Notification_Box_' + allIDs[i] + '_ID'
2881                    );
2882                    if (notifEl) {
2883                        totalHeight += notifEl.offsetHeight;
2884                    }
2885                }
2886                if (allIDs.length > 1) {
2887                    totalHeight += (allIDs.length - 1) * 8;
2888                }
2889                notificationMain.style.height = totalHeight + "px";
2890            } else {
2891                notificationMain.style.height = '';
2892                notification.style.bottom = "16px";
2893                if (currentNotification[currentNotification.length - 1] !== notificationID) {
2894                    notification.style.height = notificationHeight + 'px';
2895                    requestAnimationFrame(() => {
2896                        let latestNotif = document.querySelector(
2897                            '#DLP_Notification_Box_' +
2898                            String(currentNotification[currentNotification.length - 1]) +
2899                            '_ID'
2900                        );
2901                        if (latestNotif) {
2902                            notification.style.height = latestNotif.offsetHeight + 'px';
2903                        }
2904                        notification.style.width = "284px";
2905                        notification.style.transform = "translateY(-8px)";
2906                    });
2907                } else {
2908                    requestAnimationFrame(() => {
2909                        notification.style.height = notificationHeight + "px";
2910                        notification.style.width = "";
2911                        notification.style.transform = "";
2912                    });
2913                }
2914            }
2915        }, 20);
2916
2917        function internalDisappear() {
2918            if (timerData && timerData.timeoutHandle) {
2919                clearTimeout(timerData.timeoutHandle);
2920            }
2921            if (isBusyDisappearing) return;
2922            isBusyDisappearing = true;
2923            currentNotification.splice(currentNotification.indexOf(notificationID), 1);
2924
2925            requestAnimationFrame(() => {
2926                notification.style.bottom = "-" + notificationHeight + "px";
2927                notification.style.filter = "blur(16px)";
2928                notification.style.opacity = "0";
2929            });
2930            clearInterval(repeatInterval);
2931            setTimeout(() => {
2932                notification.remove();
2933                if (currentNotification.length === 0) {
2934                    notificationMain.style.height = '';
2935                }
2936            }, 800);
2937        }
2938
2939        function disappear() {
2940            internalDisappear();
2941        }
2942
2943        notification.querySelector('.DLP_Inset_Icon_2_ID').addEventListener("click", disappear);
2944
2945        return {
2946            close: disappear
2947        };
2948    }
2949
2950
2951    let isBusySwitchingPages = false;
2952    let pages = {
2953        "DLP_Onboarding_Start_Button_1_ID": [5],
2954        "DLP_Switch_Legacy_Button_1_ID": [3],
2955
2956        "DLP_Universal_Back_1_Button_1_ID": [1],
2957
2958        "DLP_Main_Settings_1_Button_1_ID": [7],
2959        //"DLP_Main_Feedback_1_Button_1_ID": [8],
2960
2961        "DLP_Main_Feedback_1_Button_1_ID": [11],
2962
2963        "DLP_Main_Whats_New_1_Button_1_ID": [9],
2964        "DLP_Main_See_More_1_Button_1_ID": [2],
2965        "DLP_Main_Terms_1_Button_1_ID": [5],
2966
2967        "DLP_Secondary_Settings_1_Button_1_ID": [7],
2968        "DLP_Secondary_Feedback_1_Button_1_ID": [8],
2969        "DLP_Secondary_Whats_New_1_Button_1_ID": [9],
2970        "DLP_Secondary_See_More_1_Button_1_ID": [4],
2971        "DLP_Secondary_Terms_1_Button_1_ID": [5],
2972
2973        "DLP_Terms_Back_Button_1_ID": [1],
2974        "DLP_Terms_Accept_Button_1_ID": [1],
2975        "DLP_Terms_Decline_Button_1_ID": [6],
2976        "DLP_Terms_Declined_Back_Button_1_ID": [5]
2977    };
2978    function goToPage(to, buttonID) {
2979        if (isBusySwitchingPages) return;
2980        isBusySwitchingPages = true;
2981
2982        let mainBox = document.querySelector(`.DLP_Main_Box`);
2983        let toNumber = to;
2984        let fromPage = document.querySelector(`#DLP_Main_Box_Divider_${currentPage}_ID`);
2985        let toPage = document.querySelector(`#DLP_Main_Box_Divider_${toNumber}_ID`);
2986
2987        let mainBoxNewToBeWidth = mainBox.offsetWidth;
2988
2989        if (buttonID === 'DLP_Main_Terms_1_Button_1_ID' || buttonID === 'DLP_Secondary_Terms_1_Button_1_ID') {
2990            document.querySelector(`#DLP_Terms_1_Text_1_ID`).style.display = 'none';
2991            document.querySelector(`#DLP_Terms_1_Button_1_ID`).style.display = 'none';
2992            document.querySelector(`#DLP_Terms_1_Text_2_ID`).style.display = 'block';
2993            document.querySelector(`#DLP_Terms_1_Button_2_ID`).style.display = 'block';
2994        } else if (buttonID === 'DLP_Terms_Back_Button_1_ID') {
2995            toNumber = lastPage;
2996            toPage = document.querySelector(`#DLP_Main_Box_Divider_${toNumber}_ID`);
2997            setTimeout(() => {
2998                document.querySelector(`#DLP_Terms_1_Text_1_ID`).style.display = 'block';
2999                document.querySelector(`#DLP_Terms_1_Button_1_ID`).style.display = 'block';
3000                document.querySelector(`#DLP_Terms_1_Text_2_ID`).style.display = 'none';
3001                document.querySelector(`#DLP_Terms_1_Button_2_ID`).style.display = 'none';
3002            }, 400);
3003        } else if (buttonID === 'DLP_Universal_Back_1_Button_1_ID' || to === -1) {
3004            toNumber = lastPage;
3005            toPage = document.querySelector(`#DLP_Main_Box_Divider_${toNumber}_ID`);
3006        } else if (buttonID === 'DLP_Switch_Legacy_Button_1_ID') {
3007            let button = document.querySelector('#DLP_Switch_Legacy_Button_1_ID');
3008            console.log(storageSession.legacy.page);
3009            if (storageSession.legacy.page !== 0) {
3010                toNumber = 1;
3011                toPage = document.querySelector(`#DLP_Main_Box_Divider_${toNumber}_ID`);
3012                setButtonState(button, {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][106], icon: '􀱏'}, {text: '', icon: ''});
3013                storageSession.legacy.page = 0;
3014                saveStorageSession();
3015            } else {
3016                toNumber = 3;
3017                toPage = document.querySelector(`#DLP_Main_Box_Divider_${toNumber}_ID`);
3018                setButtonState(button, {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][105], icon: '􀂑'}, {text: '', icon: ''});
3019                storageSession.legacy.page = 1;
3020                saveStorageSession();
3021            }
3022        } else if (buttonID === 'DLP_Terms_Accept_Button_1_ID') {
3023            storageLocal.terms = newTermID;
3024            saveStorageLocal();
3025            connectToServer();
3026        } else if (buttonID === 'DLP_Onboarding_Start_Button_1_ID') {
3027            storageLocal.onboarding = true;
3028            saveStorageLocal();
3029            goToPage(1);
3030        } else if (buttonID === 'DLP_Main_Feedback_1_Button_1_ID') {
3031            setTimeout(() => {
3032                const chatBox = document.querySelector('#DLP_Main_Box_Divider_11_ID')?.querySelector('.DLP_Chat_Box_1_ID_1');
3033                chatBox.scrollTop = chatBox.scrollHeight;
3034            }, 420);
3035        } else if (toNumber === 7) {
3036            const trackingSinceDateString = new Date(storageLocal.stats.tracking_since).toLocaleDateString(systemLanguage, { month: 'short', day: 'numeric', year: 'numeric' });
3037
3038            let modernStatsBox = document.querySelector('#DLP_Main_Box_Divider_7_ID').querySelector('#DLP_Settings_Modern_Stats_Main_Box_1_ID');
3039            modernStatsBox.children[0].lastElementChild.innerHTML = "since " + trackingSinceDateString;
3040            modernStatsBox.children[1].lastElementChild.innerHTML = storageLocal.stats.modern.xp;
3041            modernStatsBox.children[2].lastElementChild.innerHTML = storageLocal.stats.modern.gem;
3042            modernStatsBox.children[3].lastElementChild.innerHTML = storageLocal.stats.modern.streak;
3043            modernStatsBox.children[4].lastElementChild.innerHTML = storageLocal.stats.modern.heart_refill;
3044
3045            let legacyStatsBox = document.querySelector('#DLP_Main_Box_Divider_7_ID').querySelector('#DLP_Settings_Legacy_Stats_Main_Box_1_ID');
3046            legacyStatsBox.children[0].lastElementChild.innerHTML = "since " + trackingSinceDateString;
3047            legacyStatsBox.children[1].lastElementChild.innerHTML = (storageLocal.stats.legacy.listen.lessons + storageLocal.stats.legacy.path.lessons + storageLocal.stats.legacy.practice.lessons + storageLocal.stats.legacy.lesson.lessons);
3048            legacyStatsBox.children[2].lastElementChild.innerHTML = (storageLocal.stats.legacy.listen.questions + storageLocal.stats.legacy.path.questions + storageLocal.stats.legacy.practice.questions + storageLocal.stats.legacy.lesson.questions);
3049        }
3050
3051        if (toNumber === 11) {
3052            if (newReplyButtonActive) {
3053                newReplyButtonActive = false;
3054                updateConnetionButtonStyles(document.getElementById("DLP_Main_Feedback_1_Button_1_ID"), {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][5], icon: '􂄺'}, {text: '', icon: ''});
3055            }
3056        }
3057
3058        if (toNumber === 2) mainBoxNewToBeWidth = "600";
3059        else if (toNumber === 5) mainBoxNewToBeWidth = "400";
3060        else if (toNumber === 7) mainBoxNewToBeWidth = "400";
3061        else if (toNumber === 8) mainBoxNewToBeWidth = "400";
3062        else if (toNumber === 9) mainBoxNewToBeWidth = "400";
3063        else if (toNumber === 11) mainBoxNewToBeWidth = "400";
3064        else mainBoxNewToBeWidth = "312";
3065
3066        if ([1, 2, 3, 4].includes(toNumber)) legacyButtonVisibility(true);
3067        else legacyButtonVisibility(false);
3068
3069        if (toNumber === 3) {
3070            storageSession.legacy.page = 1;
3071            saveStorageSession();
3072        } else if (toNumber === 4) {
3073            storageSession.legacy.page = 2;
3074            saveStorageSession();
3075        }
3076
3077        let mainBoxOldWidth = mainBox.offsetWidth;
3078        let mainBoxOldHeight = mainBox.offsetHeight;
3079        let fromBoxOldWidth = fromPage.offsetWidth;
3080        let fromBoxOldHeight = fromPage.offsetHeight;
3081        console.log(fromBoxOldWidth, fromBoxOldHeight);
3082        mainBox.style.transition = "";
3083        fromPage.style.display = "none";
3084        toPage.style.display = "block";
3085        mainBox.offsetHeight;
3086        mainBox.style.width = `${mainBoxNewToBeWidth}px`;
3087        let mainBoxNewWidth = mainBoxNewToBeWidth;
3088        let mainBoxNewHeight = mainBox.offsetHeight;
3089        let toBoxOldWidth = toPage.offsetWidth;
3090        let toBoxOldHeight = toPage.offsetHeight;
3091        console.log(toBoxOldWidth, toBoxOldHeight);
3092        fromPage.style.display = "block";
3093        toPage.style.display = "none";
3094        mainBox.style.width = `${mainBoxOldWidth}px`;
3095        mainBox.style.height = `${mainBoxOldHeight}px`;
3096        mainBox.offsetHeight;
3097
3098        if (flag02) mainBox.style.transition = "0.8s linear(0.00, -0.130, 0.164, 0.450, 0.687, 0.861, 0.973, 1.04, 1.06, 1.07, 1.06, 1.04, 1.03, 1.02, 1.01, 1.00, 0.999, 0.997, 0.997, 0.997, 0.998, 0.998, 0.999, 0.999, 1.00)";
3099        else mainBox.style.transition = "0.8s cubic-bezier(0.16, 1, 0.32, 1)";
3100
3101        mainBox.offsetHeight;
3102        mainBox.style.width = `${mainBoxNewToBeWidth}px`;
3103        mainBox.style.height = `${mainBoxNewHeight}px`;
3104
3105        fromPage.style.transform = `scaleX(1) scaleY(1)`;
3106        fromPage.style.width = `${fromBoxOldWidth}px`;
3107        fromPage.style.height = `${fromBoxOldHeight}px`;
3108
3109        if (flag02) fromPage.style.transition = "opacity 0.4s cubic-bezier(0.16, 1, 0.32, 1), filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 1.5s linear(0.00, -0.130, 0.164, 0.450, 0.687, 0.861, 0.973, 1.04, 1.06, 1.07, 1.06, 1.04, 1.03, 1.02, 1.01, 1.00, 0.999, 0.997, 0.997, 0.997, 0.998, 0.998, 0.999, 0.999, 1.00)";
3110        else fromPage.style.transition = "opacity 0.4s cubic-bezier(0.16, 1, 0.32, 1), filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 0.8s cubic-bezier(0.16, 1, 0.32, 1)";
3111
3112        fromPage.offsetHeight;
3113        fromPage.style.opacity = "0";
3114        fromPage.style.filter = "blur(4px)";
3115        fromPage.style.transform = `scaleX(${toBoxOldWidth / fromBoxOldWidth}) scaleY(${toBoxOldHeight / fromBoxOldHeight})`;
3116
3117        toPage.style.width = `${toBoxOldWidth}px`;
3118        toPage.style.height = `${toBoxOldHeight}px`;
3119        toPage.style.opacity = "0";
3120        toPage.style.filter = "blur(4px)";
3121        toPage.style.transform = `scaleX(${fromBoxOldWidth / toBoxOldWidth}) scaleY(${fromBoxOldHeight / toBoxOldHeight})`;
3122
3123        if (flag02) toPage.style.transition = "opacity 0.4s cubic-bezier(0.16, 1, 0.32, 1), filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 1.5s linear(0.00, -0.130, 0.164, 0.450, 0.687, 0.861, 0.973, 1.04, 1.06, 1.07, 1.06, 1.04, 1.03, 1.02, 1.01, 1.00, 0.999, 0.997, 0.997, 0.997, 0.998, 0.998, 0.999, 0.999, 1.00)";
3124        else toPage.style.transition = "opacity 0.4s cubic-bezier(0.16, 1, 0.32, 1), filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 0.8s cubic-bezier(0.16, 1, 0.32, 1)";
3125
3126        toPage.offsetHeight;
3127        toPage.style.transform = `scaleX(1) scaleY(1)`;
3128
3129        setTimeout(() => {
3130            fromPage.style.display = "none";
3131
3132            fromPage.style.width = ``;
3133            fromPage.style.height = ``;
3134            fromPage.style.transform = ``;
3135
3136            toPage.style.display = "block";
3137            toPage.offsetHeight;
3138            toPage.style.opacity = "1";
3139            toPage.style.filter = "blur(0px)";
3140            setTimeout(() => {
3141                toPage.style.opacity = "";
3142                toPage.style.filter = "";
3143                toPage.style.transition = "";
3144
3145                fromPage.style.transition = "";
3146                toPage.style.opacity = "";
3147                toPage.style.filter = "";
3148
3149                mainBox.style.height = "";
3150
3151                toPage.style.width = ``;
3152                toPage.style.height = ``;
3153                toPage.style.transform = ``;
3154
3155                lastPage = currentPage;
3156                currentPage = toNumber;
3157                isBusySwitchingPages = false;
3158            }, 400);
3159        }, 400);
3160    }
3161    Object.keys(pages).forEach(function (key) {
3162        document.querySelectorAll(`#${key}`).forEach(element => {
3163            element.addEventListener("click", function () {
3164                if (isBusySwitchingPages || isGetButtonsBusy) return;
3165                goToPage(pages[key][0], key);
3166            });
3167        });
3168    });
3169    document.getElementById('DLP_Hide_Button_1_ID').addEventListener("click", function () {
3170        if (isBusySwitchingPages) return;
3171        hidden = !hidden;
3172        hide(hidden);
3173    });
3174    function hide(value) {
3175        if (isBusySwitchingPages) return;
3176        isBusySwitchingPages = true;
3177        let button = document.querySelector(`#DLP_Hide_Button_1_ID`);
3178        let main = document.querySelector(`.DLP_Main`);
3179        let mainBox = document.querySelector(`.DLP_Main_Box`);
3180
3181        let mainBoxHeight = mainBox.offsetHeight;
3182
3183        main.style.transition = "0.8s cubic-bezier(0.16, 1, 0.32, 1)";
3184        mainBox.style.transition = "0.8s cubic-bezier(0.16, 1, 0.32, 1)";
3185        if (value) {
3186            setButtonState(button, {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][104], icon: '􀋮'}, {text: '', icon: ''});
3187            main.style.bottom = `-${mainBoxHeight - 8}px`;
3188            legacyButtonVisibility(false);
3189            mainBox.style.filter = "blur(8px)";
3190            mainBox.style.opacity = "0";
3191        } else {
3192            setButtonState(button, {button: 'rgb(var(--DLP-blue)', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF'}, {text: systemText[systemLanguage][103], icon: '􀋰'}, {text: '', icon: ''});
3193            main.style.bottom = "16px";
3194            if (currentPage === 1 || currentPage === 3) legacyButtonVisibility(true);
3195            mainBox.style.filter = "";
3196            mainBox.style.opacity = "";
3197        }
3198        setTimeout(() => {
3199            main.style.transition = "";
3200            mainBox.style.transition = "";
3201            isBusySwitchingPages = false;
3202        }, 800);
3203    }
3204    document.querySelector(`.DLP_Main`).style.bottom = `-${document.querySelector(`.DLP_Main_Box`).offsetHeight - 8}px`;
3205    document.querySelector(`.DLP_Main_Box`).style.opacity = "0";
3206    document.querySelector(`.DLP_Main_Box`).style.filter = "blur(8px)";
3207    document.querySelector(`#DLP_Switch_Legacy_Button_1_ID`).style.filter = "blur(8px)";
3208    document.querySelector(`#DLP_Switch_Legacy_Button_1_ID`).style.opacity = "0";
3209    document.querySelector(`#DLP_Switch_Legacy_Button_1_ID`).style.display = "none";
3210    hide(false, false);
3211    function legacyButtonVisibility(value) {
3212        let legacyButton = document.querySelector(`#DLP_Switch_Legacy_Button_1_ID`);
3213        legacyButton.style.transition = 'width 0.8s cubic-bezier(0.77,0,0.18,1), opacity 0.8s cubic-bezier(0.16, 1, 0.32, 1), filter 0.8s cubic-bezier(0.16, 1, 0.32, 1), transform 0.4s cubic-bezier(0.16, 1, 0.32, 1)';
3214        if (value) {
3215            legacyButton.style.display = "";
3216            legacyButton.offsetWidth;
3217            legacyButton.style.filter = "";
3218            legacyButton.style.opacity = "";
3219        } else {
3220            legacyButton.style.filter = "blur(8px)";
3221            legacyButton.style.opacity = "0";
3222            setTimeout(() => {
3223                legacyButton.style.display = "none";
3224            }, 800);
3225        }
3226    }
3227    function handleVisibility() {
3228        if (document.querySelector('.MYehf') !== null || window.location.pathname.includes('/lesson') || window.location.pathname === '/practice') {
3229            document.querySelector('.DLP_Main').style.display = 'none';
3230        } else {
3231            document.querySelector('.DLP_Main').style.display = '';
3232        }
3233    }
3234    setInterval(handleVisibility, 200);
3235
3236    let isGetButtonsBusy = false;
3237    function setButtonState(button, color, content, animation, callback) {
3238        try {
3239            let textElement = button.querySelector('.DLP_Inset_Text_1_ID');
3240            let iconElement = button.querySelector('.DLP_Inset_Icon_1_ID');
3241
3242            let previousText = textElement.textContent;
3243            let previousIcon = undefined;
3244            if (iconElement.style.display !== 'none') {
3245                previousIcon = {
3246                    icon: iconElement.textContent,
3247                    color: iconElement.style.color
3248                };
3249            }
3250            textElement.textContent = content.text;
3251            if (content.icon !== '') {
3252                if (content.icon !== undefined) iconElement.textContent = content.icon;
3253            } else {
3254                iconElement.style.display = 'none';
3255            }
3256            let buttonNewWidth = button.offsetWidth;
3257            textElement.textContent = previousText;
3258            if (previousIcon !== undefined) {
3259                iconElement.textContent = previousIcon.icon;
3260                iconElement.style.color = previousIcon.color;
3261                iconElement.style.display = '';
3262            }
3263
3264            button.style.transition = 'width 0.8s cubic-bezier(0.77,0,0.18,1), background 0.8s cubic-bezier(0.16, 1, 0.32, 1), outline 0.8s cubic-bezier(0.16, 1, 0.32, 1), filter 0.4s cubic-bezier(0.16, 1, 0.32, 1), transform 0.4s cubic-bezier(0.16, 1, 0.32, 1)';
3265            button.style.width = `${button.offsetWidth}px`;
3266
3267            requestAnimationFrame(() => {
3268                textElement.style.transition = '0.4s';
3269                if (previousIcon !== undefined) iconElement.style.transition = '0.4s';
3270
3271                textElement.style.filter = 'blur(4px)';
3272                if (previousIcon !== undefined) iconElement.style.filter = 'blur(4px)';
3273                textElement.style.opacity = '0';
3274                if (previousIcon !== undefined) iconElement.style.opacity = '0';
3275                button.style.width = `${buttonNewWidth}px`;
3276
3277                button.style.background = color.button;
3278                button.style.outline = `solid 2px ${color.outline}`;
3279            });
3280
3281            setTimeout(() => {
3282                textElement.style.animation = '';
3283                if (content.icon !== '') iconElement.style.animation = '';
3284
3285                textElement.style.transition = '0s';
3286                if (content.icon !== '') iconElement.style.transition = '0s';
3287                textElement.style.color = color.text;
3288                if (content.icon !== '') iconElement.style.color = color.icon;
3289                void textElement.offsetWidth;
3290                textElement.style.transition = '0.4s';
3291                if (content.icon !== '') iconElement.style.transition = '0.4s';
3292
3293                textElement.textContent = content.text;
3294                if (content.icon !== '') {
3295                    if (content.icon !== undefined) iconElement.textContent = content.icon;
3296                } else {
3297                    iconElement.style.display = 'none';
3298                }
3299
3300                requestAnimationFrame(() => {
3301                    textElement.style.filter = 'blur(0px)';
3302                    if (content.icon !== '') iconElement.style.filter = 'blur(0px)';
3303                    textElement.style.opacity = '1';
3304                    if (content.icon !== '') iconElement.style.opacity = '1';
3305                });
3306
3307                setTimeout(() => {
3308                    textElement.style.animation = animation.text;
3309                    if (content.icon !== '') iconElement.style.animation = animation.icon;
3310
3311                    button.style.width = '';
3312                }, 400);
3313
3314                if (callback) callback();
3315            }, 400);
3316        } catch (e) {
3317            console.log('setButton error', e);
3318        }
3319    }
3320
3321    const tooltipObserver = new MutationObserver((mutationsList) => {
3322        mutationsList.forEach(mutation => {
3323            if (mutation.type === 'attributes' && mutation.attributeName === 'data-dlp-tooltip') {
3324                tooltipCreate(mutation.target);
3325                console.log('Attribute changed: registered');
3326            } else if (mutation.type === 'childList') {
3327                mutation.addedNodes.forEach(node => {
3328                    if (node.nodeType === Node.ELEMENT_NODE && node.hasAttribute('data-dlp-tooltip')) {
3329                        tooltipCreate(node);
3330                        console.log('New element with attribute: registered');
3331                    }
3332                });
3333            }
3334        });
3335    });
3336
3337    tooltipObserver.observe(document.body, {
3338        childList: true,
3339        subtree: true,
3340        attributes: true,
3341        attributeFilter: ['data-dlp-tooltip']
3342    });
3343
3344    const tooltipData = new WeakMap(); // Store tooltip data associated with elements
3345
3346    function tooltipCreate(element) {
3347        if (!flag01) return;
3348        // Check if there's an existing tooltip for this element and hide it
3349        if (tooltipData.has(element)) {
3350            hideTooltip(element);
3351        }
3352
3353        let timeoutId = null;
3354        let currentTooltip = null; // Use a local variable here
3355
3356        const showTooltipForElement = (event) => { // Pass event to showTooltipForElement
3357            timeoutId = setTimeout(() => {
3358                currentTooltip = showTooltip(element, event); // Pass event to showTooltip
3359                tooltipData.set(element, { tooltip: currentTooltip, timeoutId: timeoutId }); // Store data
3360            }, 1000);
3361        };
3362
3363        const hideTooltipForElement = () => {
3364            clearTimeout(timeoutId);
3365            hideTooltip(element);
3366        };
3367
3368        const positionTooltipForElement = (event) => { // Pass event to positionTooltipForElement
3369            if(!currentTooltip) return; // Use the local currentTooltip
3370            positionTooltip(currentTooltip, event); // Pass tooltip and event to positionTooltip
3371        };
3372
3373        element.addEventListener('mouseenter', showTooltipForElement);
3374        element.addEventListener('mouseleave', hideTooltipForElement);
3375        element.addEventListener('mousemove', positionTooltipForElement);
3376
3377        // Store the listeners so we can remove them later if needed (though not explicitly required by the prompt, good practice)
3378        tooltipData.set(element, {
3379            timeoutId: null,
3380            tooltip: null,
3381            listeners: {
3382                mouseenter: showTooltipForElement,
3383                mouseleave: hideTooltipForElement,
3384                mousemove: positionTooltipForElement
3385            }
3386        });
3387
3388        console.log('Tooltip listeners attached to element');
3389
3390        // Immediately show tooltip if mouse is already over and attribute is just added/changed
3391        if (element.matches(':hover')) {
3392            // Simulate mousemove event to position tooltip correctly on initial hover if attribute is added dynamically
3393            const mockEvent = new MouseEvent('mousemove', {
3394                clientX: element.getBoundingClientRect().left, // Or any reasonable default cursor position
3395                clientY: element.getBoundingClientRect().top
3396            });
3397            showTooltipForElement(mockEvent);
3398        }
3399    };
3400
3401    function showTooltip(element, event) { // Accept event in showTooltip
3402        const tooltipText = element.dataset.dlpTooltip;
3403        let tooltip = document.createElement('div'); // Create a new tooltip each time
3404        tooltip.classList.add('DLP_Tooltip');
3405        document.body.appendChild(tooltip);
3406
3407        tooltip.textContent = tooltipText;
3408        tooltip.offsetHeight; // Trigger reflow for transition
3409        tooltip.classList.add('DLP_Tooltip_Visible');
3410
3411        positionTooltip(tooltip, event); // Pass tooltip and event to positionTooltip
3412        console.log('created tooltip');
3413        return tooltip; // Return the created tooltip
3414    }
3415
3416    function positionTooltip(tooltip, event){ // Accept tooltip and event in positionTooltip
3417        if (!tooltip || !event) return; // Exit if tooltip or event is null
3418
3419        const tooltipRect = tooltip.getBoundingClientRect();
3420        const viewportWidth = window.innerWidth;
3421        const viewportHeight = window.innerHeight;
3422
3423        const cursorX = event.clientX;
3424        const cursorY = event.clientY;
3425
3426        const tooltipWidth = tooltipRect.width;
3427        const tooltipHeight = tooltipRect.height;
3428
3429        const offsetX = 10; // Horizontal offset from cursor
3430        const offsetY = 10; // Vertical offset from cursor
3431
3432        let preferredPosition = 'bottom-right'; // Default position
3433        let tooltipLeft, tooltipTop, tooltipBottom, tooltipRight;
3434
3435        // Check bottom-right position
3436        tooltipLeft = cursorX + offsetX;
3437        tooltipTop = cursorY + offsetY;
3438        if (tooltipLeft + tooltipWidth <= viewportWidth && tooltipTop + tooltipHeight <= viewportHeight) {
3439            preferredPosition = 'bottom-right';
3440        } else if (cursorX - offsetX - tooltipWidth >= 0 && tooltipTop + tooltipHeight <= viewportHeight) { // Check bottom-left
3441            tooltipLeft = cursorX - offsetX - tooltipWidth;
3442            tooltipTop = cursorY + offsetY;
3443            preferredPosition = 'bottom-left';
3444        } else if (tooltipLeft + tooltipWidth <= viewportWidth && cursorY - offsetY - tooltipHeight >= 0) { // Check top-right
3445            tooltipLeft = cursorX + offsetX;
3446            tooltipTop = cursorY - offsetY - tooltipHeight;
3447            preferredPosition = 'top-right';
3448        } else if (cursorX - offsetX - tooltipWidth >= 0 && cursorY - offsetY - tooltipHeight >= 0) { // Check top-left
3449            tooltipLeft = cursorX - offsetX - tooltipWidth;
3450            tooltipTop = cursorY - offsetY - tooltipHeight;
3451            preferredPosition = 'top-left';
3452        } else { // Fallback to bottom-right if none fit (might go off-screen)
3453            tooltipLeft = cursorX + offsetX;
3454            tooltipTop = cursorY + offsetY;
3455            preferredPosition = 'bottom-right';
3456        }
3457
3458        tooltip.style.left = tooltipLeft + 'px';
3459        tooltip.style.top = tooltipTop + 'px';
3460        tooltip.style.bottom = 'auto'; // Ensure bottom is not overriding top
3461        tooltip.style.right = 'auto'; // Ensure right is not overriding left
3462    }
3463
3464    function hideTooltip(element) {
3465        if (!tooltipData.has(element)) return; // Exit if no tooltip data for this element
3466
3467        const data = tooltipData.get(element);
3468        const tooltip = data.tooltip;
3469        if (tooltip) {
3470            tooltip.classList.remove('DLP_Tooltip_Visible');
3471            setTimeout(() => {
3472                if (tooltip && tooltip.parentNode) {
3473                    tooltip.parentNode.removeChild(tooltip);
3474                }
3475                tooltipData.delete(element); // Clear tooltip data when hidden
3476                console.log('tooltip removed');
3477            }, 500);
3478        } else {
3479            tooltipData.delete(element); // Clear data even if no tooltip element (to avoid memory leak)
3480        }
3481    }
3482
3483
3484
3485
3486    const DLP_Get_PATH_1_ID = document.getElementById("DLP_Get_PATH_1_ID");
3487    const DLP_Get_PATH_2_ID = document.getElementById("DLP_Get_PATH_2_ID");
3488    const DLP_Get_PRACTICE_1_ID = document.getElementById("DLP_Get_PRACTICE_1_ID");
3489    const DLP_Get_PRACTICE_2_ID = document.getElementById("DLP_Get_PRACTICE_2_ID");
3490    const DLP_Get_LISTEN_1_ID = document.getElementById("DLP_Get_LISTEN_1_ID");
3491    const DLP_Get_LISTEN_2_ID = document.getElementById("DLP_Get_LISTEN_2_ID");
3492    const DLP_Get_LESSON_1_ID = document.getElementById("DLP_Get_LESSON_1_ID");
3493    const DLP_Get_LESSON_2_ID = document.getElementById("DLP_Get_LESSON_2_ID");
3494
3495    function inputCheck2() {
3496        const ids = {
3497            "DLP_Get_PATH_1_ID": ["path"],
3498            "DLP_Get_PATH_2_ID": ["path"],
3499            "DLP_Get_PRACTICE_1_ID": ["practice"],
3500            "DLP_Get_PRACTICE_2_ID": ["practice"],
3501            "DLP_Get_LISTEN_1_ID": ["listen"],
3502            "DLP_Get_LISTEN_2_ID": ["listen"],
3503            "DLP_Get_LESSON_1_ID": ["lesson"],
3504            "DLP_Get_LESSON_2_ID": ["lesson"]
3505        };
3506
3507        Object.keys(ids).forEach(id => {
3508            const element = document.getElementById(id);
3509            if (!element) return;
3510            const input = element.querySelector('#DLP_Inset_Input_1_ID');
3511            const button = element.querySelector('#DLP_Inset_Button_1_ID');
3512            if (!input || !button) return;
3513            function updateButtonState() {
3514                const isEmpty = input.value.length === 0;
3515                button.style.opacity = isEmpty ? '0.5' : '';
3516                button.style.pointerEvents = isEmpty ? 'none' : '';
3517            };
3518            const category = ids[id][0];
3519            input.addEventListener("input", function () {
3520                this.value = this.value.replace(/[^0-9]/g, "");
3521                if (this.value.length === 1 && this.value[0] === '0') this.value = this.value.slice(1);
3522                if (this.value.length > 6) this.value = this.value.slice(0, 6);
3523                updateButtonState();
3524                //if (!storageSession.legacy[category]) storageSession.legacy[category] = [];
3525                storageSession.legacy[category].amount = Number(this.value);
3526                saveStorageSession();
3527            });
3528            if (['DLP_Get_LESSON_1_ID', 'DLP_Get_LESSON_2_ID'].includes(id)) {
3529                const input3 = element.querySelector('#DLP_Inset_Input_3_ID');
3530                const input4 = element.querySelector('#DLP_Inset_Input_4_ID');
3531
3532                input3.addEventListener("input", function () {
3533                    this.value = this.value.replace(/[^0-9]/g, "");
3534                    if (this.value.length === 1 && this.value[0] === '0') this.value = this.value.slice(1);
3535                    if (this.value.length > 2) this.value = this.value.slice(0, 2);
3536                    //if (!storageSession.legacy[category]) storageSession.legacy[category] = [];
3537                    storageSession.legacy[category].unit = Number(this.value);
3538                    saveStorageSession();
3539                });
3540                input3.addEventListener("blur", function () {
3541                    if (this.value.trim() === "") {
3542                        this.value = "1";
3543                        storageSession.legacy[category].unit = 1;
3544                        saveStorageSession();
3545                    }
3546                });
3547
3548                input4.addEventListener("input", function () {
3549                    this.value = this.value.replace(/[^0-9]/g, "");
3550                    if (this.value.length === 1 && this.value[0] === '0') this.value = this.value.slice(1);
3551                    if (this.value.length > 2) this.value = this.value.slice(0, 2);
3552                    //if (!storageSession.legacy[category]) storageSession.legacy[category] = [];
3553                    storageSession.legacy[category].level = Number(this.value);
3554                    saveStorageSession();
3555                });
3556                input4.addEventListener("blur", function () {
3557                    if (this.value.trim() === "") {
3558                        this.value = "1";
3559                        storageSession.legacy[category].level = 1;
3560                        saveStorageSession();
3561                    }
3562                });
3563            }
3564            if (storageSession.legacy[category].amount !== 0) input.value = storageSession.legacy[category].amount; updateButtonState();
3565        });
3566
3567        Object.keys(ids).forEach(id => {
3568            const element = document.getElementById(id);
3569            if (!element) return;
3570            const input = element.querySelector('#DLP_Inset_Input_1_ID');
3571            const button = element.querySelector('#DLP_Inset_Button_1_ID');
3572            if (!input || !button) return;
3573            function updateButtonState() {
3574                const isEmpty = input.value.length === 0;
3575                button.style.opacity = isEmpty ? '0.5' : '';
3576                button.style.pointerEvents = isEmpty ? 'none' : '';
3577            };
3578            const category = ids[id][0];
3579            input.addEventListener("input", function () {
3580                this.value = this.value.replace(/[^0-9]/g, "");
3581                if (this.value.length === 1 && this.value[0] === '0') this.value = this.value.slice(1);
3582                if (this.value.length > 6) this.value = this.value.slice(0, 6);
3583                updateButtonState();
3584                if (!storageSession.legacy[category]) storageSession.legacy[category] = [];
3585                storageSession.legacy[category].amount = Number(this.value);
3586                saveStorageSession();
3587            });
3588            if (storageSession.legacy[category].amount !== 0) input.value = storageSession.legacy[category].amount; updateButtonState();
3589        });
3590
3591        function updatePinnedItems() {
3592            const pinnedIds = storageLocal.pins.legacy || [];
3593            for (const id in ids) {
3594                if (id.endsWith("1_ID")) {
3595                    const element = document.getElementById(id);
3596                    if (element) {
3597                        if (pinnedIds.includes(id)) {
3598                            element.style.display = 'flex';
3599                        } else {
3600                            element.style.display = 'none';
3601                        }
3602                    }
3603                }
3604            }
3605        };
3606        updatePinnedItems();
3607
3608        Object.keys(ids).forEach(id => {
3609            if (id.endsWith("2_ID")) {
3610                const pinIcon = document.querySelector(`#${id} > .DLP_HStack_8 > .DLP_Inset_Icon_1_ID`);
3611                const modifiedId = id.replace("2_ID", "1_ID");
3612
3613                function updatePinViews() {
3614                    if (storageLocal.pins.legacy.includes(modifiedId)) {
3615                        pinIcon.textContent = "􀎧";
3616                        pinIcon.style.color = "rgb(var(--DLP-blue))";
3617                    } else {
3618                        pinIcon.textContent = "􀎦";
3619                        pinIcon.style.color = "rgba(var(--color-eel), 0.50)";
3620                    }
3621                }
3622                updatePinViews();
3623
3624                function updatePins(isAdding) {
3625                    const index = storageLocal.pins.legacy.indexOf(modifiedId);
3626                    if (isAdding && index === -1) {
3627                        if (storageLocal.pins.legacy.length > Math.floor(((window.innerHeight) / 200) - 1)) {
3628                            showNotification("warning", "Pin Limit Reached", "You've pinned too many functions. Please unpin one to continue.", 15);
3629                        } else {
3630                            storageLocal.pins.legacy.push(modifiedId);
3631                        }
3632                    } else if (!isAdding && index !== -1) {
3633                        storageLocal.pins.legacy.splice(index, 1);
3634                    } else {
3635                        console.log("Something unexpected happened: djr9234.");
3636                    }
3637                    updatePinViews();
3638                    saveStorageLocal();
3639                    updatePinnedItems();
3640                }
3641
3642                pinIcon.addEventListener('click', () => {
3643                    updatePins(!storageLocal.pins.legacy.includes(modifiedId));
3644                });
3645            }
3646        });
3647    }
3648
3649    inputCheck2();
3650
3651    function setupButton1Events(baseId, page, type) {
3652        const button1 = document.querySelector(`#${baseId}_ID`).querySelector('#DLP_Inset_Button_1_ID');
3653        const input1 = document.querySelector(`#${baseId}_ID`).querySelector('#DLP_Inset_Input_1_ID');
3654
3655        function clickHandler() {
3656            if (isGetButtonsBusy) return;
3657            isGetButtonsBusy = true;
3658
3659            const buttonElement = document.querySelector(`#${baseId}_ID`).querySelector('#DLP_Inset_Button_1_ID');
3660
3661            if (!storageSession.legacy.status && storageSession.legacy[type].amount > 0) {
3662                setButtonState(buttonElement, {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][107], icon: '􀊆'}, {text: '', icon: ''});
3663                storageSession.legacy.page = page;
3664                storageSession.legacy.status = type;
3665                saveStorageSession();
3666            } else if (storageSession.legacy.status === type) {
3667                setButtonState(buttonElement, {button: 'rgb(var(--DLP-blue))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF'}, {text: systemText[systemLanguage][18], icon: '􀰫'}, {text: '', icon: ''});
3668                storageSession.legacy.status = false;
3669                saveStorageSession();
3670            }
3671            setTimeout(() => {
3672                isGetButtonsBusy = false;
3673            }, 800);
3674        };
3675
3676        button1.addEventListener('click', clickHandler);
3677
3678        input1.onkeyup = function (event) {
3679            if (event.keyCode === 13) {
3680                if (isGetButtonsBusy) return;
3681                isGetButtonsBusy = true;
3682
3683                const buttonElement = document.querySelector(`#${baseId}_ID`).querySelector('#DLP_Inset_Button_1_ID');
3684
3685                if (!storageSession.legacy.status && storageSession.legacy[type].amount > 0) {
3686                    setButtonState(buttonElement, {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][107], icon: '􀊆'}, {text: '', icon: ''});
3687                    storageSession.legacy.page = page;
3688                    storageSession.legacy.status = type;
3689                    saveStorageSession();
3690                }
3691                setTimeout(() => {
3692                    isGetButtonsBusy = false;
3693                }, 800);
3694            }
3695        };
3696    }
3697
3698    function setupButton2Events(baseId, type) {
3699        const button2 = document.querySelector(`#${baseId}_ID`).querySelector('#DLP_Inset_Button_2_ID');
3700
3701        function clickHandler() {
3702            const icon = button2.querySelector('.DLP_Inset_Icon_1_ID');
3703            const input = button2.parentElement.querySelector('#DLP_Inset_Input_1_ID');
3704            const button1 = button2.parentElement.querySelector('#DLP_Inset_Button_1_ID');
3705
3706            function animateElement(element, visibility, duration = 400) {
3707                if (visibility) {
3708                    element.style.display = 'block';
3709                    element.style.filter = 'blur(4px)';
3710                    element.style.opacity = '0';
3711                    element.style.transition = '0.4s';
3712
3713                    requestAnimationFrame(() => {
3714                        element.style.filter = 'blur(0px)';
3715                        element.style.opacity = '1';
3716                    });
3717
3718                    setTimeout(() => {
3719                        element.style.filter = '';
3720                        element.style.opacity = '';
3721
3722                        element.style.transition = '';
3723                    }, duration);
3724                } else {
3725                    element.style.display = 'block';
3726                    element.style.filter = 'blur(0px)';
3727                    element.style.opacity = '1';
3728                    element.style.transition = '0.4s';
3729
3730                    requestAnimationFrame(() => {
3731                        element.style.filter = 'blur(4px)';
3732                        element.style.opacity = '0';
3733                    });
3734
3735                    setTimeout(() => {
3736                        element.style.display = 'none';
3737                        element.style.filter = '';
3738                        element.style.opacity = '';
3739                        element.style.transition = '';
3740                    }, duration);
3741                }
3742            }
3743
3744            function syncGetButtonState(mode) {
3745                if (!button1) return;
3746                if (mode === 'infinity') {
3747                    button1.style.opacity = '';
3748                    button1.style.pointerEvents = '';
3749                } else {
3750                    const isEmpty = input && input.value.length === 0;
3751                    button1.style.opacity = isEmpty ? '0.5' : '';
3752                    button1.style.pointerEvents = isEmpty ? 'none' : '';
3753                }
3754            }
3755
3756            if (storageSession.legacy[type].type === 'lesson') {
3757                let inputTo;
3758                button2.setAttribute("data-dlp-tooltip", "Lesson Mode");
3759
3760                if (input.style.display === 'none') inputTo = 'show';
3761
3762                syncGetButtonState('lesson');
3763
3764                animateElement(icon, false);
3765                setTimeout(() => {
3766                    icon.textContent = '􀆃';
3767                    animateElement(icon, true);
3768                }, 400);
3769                if (inputTo === 'show') setTimeout(() => animateElement(input, true), 400);
3770
3771            } else if (storageSession.legacy[type].type === 'xp') {
3772                let inputTo;
3773                button2.setAttribute("data-dlp-tooltip", "XP Mode");
3774
3775                if (input.style.display === 'none') inputTo = 'show';
3776
3777                syncGetButtonState('xp');
3778
3779                animateElement(icon, false);
3780                setTimeout(() => {
3781                    icon.textContent = 'XP';
3782                    animateElement(icon, true);
3783                }, 400);
3784                if (inputTo === 'show') setTimeout(() => animateElement(input, true), 400);
3785
3786            } else if (storageSession.legacy[type].type === 'infinity') {
3787                let inputTo;
3788                button2.setAttribute("data-dlp-tooltip", "Infinity Mode");
3789
3790                if (input.style.display !== 'none') inputTo = 'hide';
3791
3792                syncGetButtonState('infinity');
3793
3794                animateElement(icon, false);
3795                setTimeout(() => {
3796                    icon.textContent = '􀯠';
3797                    animateElement(icon, true);
3798                }, 400);
3799                if (inputTo === 'hide') animateElement(input, false);
3800
3801            }
3802        };
3803        clickHandler();
3804
3805        button2.addEventListener('click', () => {
3806            if (isGetButtonsBusy) return;
3807            isGetButtonsBusy = true;
3808            if (storageSession.legacy[type].type === 'lesson') {
3809                storageSession.legacy[type].type = 'xp';
3810                saveStorageSession();
3811            } else if (storageSession.legacy[type].type === 'xp') {
3812                storageSession.legacy[type].type = 'infinity';
3813                saveStorageSession();
3814            } else if (storageSession.legacy[type].type === 'infinity') {
3815                storageSession.legacy[type].type = 'lesson';
3816                saveStorageSession();
3817            }
3818            clickHandler();
3819            setTimeout(() => {
3820                isGetButtonsBusy = false;
3821            }, 800);
3822        });
3823    }
3824
3825    for (const type of ['PATH', 'PRACTICE', 'LISTEN', 'LESSON']) {
3826        for (let i = 1; i <= 2; i++) {
3827            const baseId = `DLP_Get_${type}_${i}`;
3828            setupButton1Events(baseId, i, type.toLowerCase());
3829            setupButton2Events(baseId, type.toLowerCase());
3830        }
3831    }
3832
3833    if (storageSession.legacy.status === 'path' && storageSession.legacy.path.amount > 0) {
3834        if (storageSession.legacy.page === 1) {
3835            setButtonState(DLP_Get_PATH_1_ID.querySelector('#DLP_Inset_Button_1_ID'), {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][107], icon: '􀊆'}, {text: '', icon: ''});
3836        } else if (storageSession.legacy.page === 2) {
3837            setButtonState(DLP_Get_PATH_2_ID.querySelector('#DLP_Inset_Button_1_ID'), {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][107], icon: '􀊆'}, {text: '', icon: ''});
3838        }
3839    } else if (storageSession.legacy.status === 'practice' && storageSession.legacy.practice.amount > 0) {
3840        if (storageSession.legacy.page === 1) {
3841            setButtonState(DLP_Get_PRACTICE_1_ID.querySelector('#DLP_Inset_Button_1_ID'), {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][107], icon: '􀊆'}, {text: '', icon: ''});
3842        } else if (storageSession.legacy.page === 2) {
3843            setButtonState(DLP_Get_PRACTICE_2_ID.querySelector('#DLP_Inset_Button_1_ID'), {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][107], icon: '􀊆'}, {text: '', icon: ''});
3844        }
3845    } else if (storageSession.legacy.status === 'listen' && storageSession.legacy.listen.amount > 0) {
3846        if (storageSession.legacy.page === 1) {
3847            setButtonState(DLP_Get_LISTEN_1_ID.querySelector('#DLP_Inset_Button_1_ID'), {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][107], icon: '􀊆'}, {text: '', icon: ''});
3848        } else if (storageSession.legacy.page === 2) {
3849            setButtonState(DLP_Get_LISTEN_2_ID.querySelector('#DLP_Inset_Button_1_ID'), {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][107], icon: '􀊆'}, {text: '', icon: ''});
3850        }
3851    } else if (storageSession.legacy.status === 'lesson' && storageSession.legacy.lesson.amount > 0) {
3852        if (storageSession.legacy.page === 1) {
3853            setButtonState(DLP_Get_LESSON_1_ID.querySelector('#DLP_Inset_Button_1_ID'), {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][107], icon: '􀊆'}, {text: '', icon: ''});
3854        } else if (storageSession.legacy.page === 2) {
3855            setButtonState(DLP_Get_LESSON_2_ID.querySelector('#DLP_Inset_Button_1_ID'), {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][107], icon: '􀊆'}, {text: '', icon: ''});
3856        }
3857    }
3858
3859    let pageSwitching = false;
3860    function process1() {
3861        if (window.location.href.includes('/lesson') || window.location.href.includes('/practice') || window.location.href.includes('/practice-hub/listening-practice')) return;
3862        if (storageSession.legacy.status && storageSession.legacy[storageSession.legacy.status].amount > 0) {
3863            if (pageSwitching) return;
3864            pageSwitching = true;
3865            setTimeout(() => {
3866                checkChest();
3867            }, 2000);
3868        } else {
3869            pageSwitching = false;
3870        }
3871    }
3872    setInterval(process1, 500);
3873    function process2() {
3874        if (storageSession.legacy.status && storageSession.legacy[storageSession.legacy.status].amount > 0) {
3875            if (storageSession.legacy.status === 'path') {
3876                window.location.href = "https://duolingo.com/lesson";
3877            } else if (storageSession.legacy.status === 'practice') {
3878                window.location.href = "https://duolingo.com/practice";
3879            } else if (storageSession.legacy.status === 'listen') {
3880                window.location.href = "https://duolingo.com/practice-hub/listening-practice";
3881            } else if (storageSession.legacy.status === 'lesson') {
3882                //storageSession.legacy[storageSession.legacy.status].section
3883                window.location.href = `https://duolingo.com/lesson/unit/${storageSession.legacy[storageSession.legacy.status].unit}/level/${storageSession.legacy[storageSession.legacy.status].level}`;
3884            }
3885        } else {
3886            pageSwitching = false;
3887        }
3888    }
3889    let checkChestCount = 0;
3890    function checkChest() {
3891        try {
3892            if (document.readyState === 'complete') {
3893                const imageUrl = 'https://d35aaqx5ub95lt.cloudfront.net/images/path/09f977a3e299d1418fde0fd053de0beb.svg';
3894                const images = document.querySelectorAll('.TI9Is');
3895                if (!images.length) {
3896                    setTimeout(function () {
3897                        process2();
3898                    }, 2000);
3899                } else {
3900                    let imagesProcessed = 0;
3901                    let chestFound = false;
3902                    images.forEach(image => {
3903                        if (image.src === imageUrl) {
3904                            image.click();
3905                            chestFound = true;
3906                            setTimeout(function () {
3907                                process2();
3908                            }, 2000);
3909                        }
3910                        imagesProcessed++;
3911                        if (imagesProcessed >= images.length && !chestFound) {
3912                            process2();
3913                        }
3914                    });
3915                }
3916            } else {
3917                setTimeout(function () {
3918                    checkChestCount++;
3919                    checkChest();
3920                }, 100);
3921            }
3922        } catch (error) {
3923            setTimeout(function () {
3924                process2();
3925            }, 2000);
3926        }
3927    };
3928
3929    if (storageSession.legacy.page === 1) {
3930        document.querySelector(`#DLP_Main_Box_Divider_${currentPage}_ID`).style.display = 'none';
3931        document.querySelector(`#DLP_Main_Box_Divider_3_ID`).style.display = 'block';
3932        currentPage = 3;
3933        let button = document.querySelector('#DLP_Switch_Legacy_Button_1_ID');
3934        setButtonState(button, {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][105], icon: '􀂑'}, {text: '', icon: ''});
3935    } else if (storageSession.legacy.page === 2) {
3936        document.querySelector(`#DLP_Main_Box_Divider_${currentPage}_ID`).style.display = 'none';
3937        document.querySelector(`#DLP_Main_Box_Divider_4_ID`).style.display = 'block';
3938        lastPage = 3;
3939        currentPage = 4;
3940        let button = document.querySelector('#DLP_Switch_Legacy_Button_1_ID');
3941        setButtonState(button, {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][105], icon: '􀂑'}, {text: '', icon: ''});
3942    }
3943
3944
3945
3946
3947
3948
3949
3950    if (storageLocal.pins.home.includes("DLP_Get_XP_1_ID")) {
3951        document.querySelector("#DLP_Get_Heart_Refill_2_ID > .DLP_HStack_8 > #DLP_Inset_Icon_1_ID");
3952    }
3953
3954    function inputCheck1() {
3955        const ids = {
3956            "DLP_Get_XP_1_ID": ["xp"],
3957            "DLP_Get_XP_2_ID": ["xp"],
3958            "DLP_Get_GEM_1_ID": ["gem"],
3959            "DLP_Get_GEM_2_ID": ["gem"],
3960            "DLP_Get_SUPER_1_ID": ["super"],
3961            "DLP_Get_SUPER_2_ID": ["super"],
3962            "DLP_Get_DOUBLE_XP_BOOST_1_ID": ["double_xp_boost"],
3963            "DLP_Get_DOUBLE_XP_BOOST_2_ID": ["double_xp_boost"],
3964            "DLP_Get_Streak_Freeze_1_ID": ["streak_freeze"],
3965            "DLP_Get_Streak_Freeze_2_ID": ["streak_freeze"],
3966            "DLP_Get_Heart_Refill_1_ID": ["heart_refill"],
3967            "DLP_Get_Heart_Refill_2_ID": ["heart_refill"],
3968            "DLP_Get_Streak_1_ID": ["streak"],
3969            "DLP_Get_Streak_2_ID": ["streak"]
3970        };
3971
3972        Object.keys(ids).forEach(id => {
3973            const element = document.getElementById(id);
3974            if (!element) return;
3975            const input = element.querySelector('#DLP_Inset_Input_1_ID');
3976            const button = element.querySelector('#DLP_Inset_Button_1_ID');
3977            if (!input || !button) return;
3978            function updateButtonState() {
3979                const isEmpty = input.value.length === 0;
3980                button.style.opacity = isEmpty ? '0.5' : '';
3981                button.style.pointerEvents = isEmpty ? 'none' : '';
3982            };
3983            const category = ids[id][0];
3984            input.addEventListener("input", function () {
3985                this.value = this.value.replace(/[^0-9]/g, "");
3986                if (this.value.length === 1 && this.value[0] === '0') this.value = this.value.slice(1);
3987                if (this.value.length > 9) this.value = this.value.slice(0, 9);
3988                updateButtonState();
3989            });
3990            if (!input.value) updateButtonState();
3991        });
3992
3993        function updatePinnedItems() {
3994            const pinnedIds = storageLocal.pins.home || [];
3995            for (const id in ids) {
3996                if (id.endsWith("1_ID")) {
3997                    const element = document.getElementById(id);
3998                    if (element) {
3999                        if (pinnedIds.includes(id)) {
4000                            element.style.display = 'flex';
4001                        } else {
4002                            element.style.display = 'none';
4003                        }
4004                    }
4005                }
4006            }
4007        };
4008        updatePinnedItems();
4009
4010        Object.keys(ids).forEach(id => {
4011            if (id.endsWith("2_ID")) {
4012                const pinIcon = document.querySelector(`#${id} > .DLP_HStack_8 > .DLP_Inset_Icon_1_ID`);
4013                const modifiedId = id.replace("2_ID", "1_ID");
4014
4015                function updatePinViews() {
4016                    if (storageLocal.pins.home.includes(modifiedId)) {
4017                        pinIcon.textContent = "􀎧";
4018                        pinIcon.style.color = "rgb(var(--DLP-blue))";
4019                    } else {
4020                        pinIcon.textContent = "􀎦";
4021                        pinIcon.style.color = "rgba(var(--color-eel), 0.50)";
4022                    }
4023                }
4024                updatePinViews();
4025
4026                function updatePins(isAdding) {
4027                    const index = storageLocal.pins.home.indexOf(modifiedId);
4028                    if (isAdding && index === -1) {
4029                        if (storageLocal.pins.home.length > Math.floor(((window.innerHeight) / 200) - 1)) {
4030                            showNotification("warning", "Pin Limit Reached", "You've pinned too many functions. Please unpin one to continue.", 15);
4031                        } else {
4032                            storageLocal.pins.home.push(modifiedId);
4033                        }
4034                    } else if (!isAdding && index !== -1) {
4035                        storageLocal.pins.home.splice(index, 1);
4036                    } else {
4037                        console.log("Something unexpected happened: djr9234.");
4038                    }
4039                    updatePinViews();
4040                    saveStorageLocal();
4041                    updatePinnedItems();
4042                }
4043
4044                pinIcon.addEventListener('click', () => {
4045                    updatePins(!storageLocal.pins.home.includes(modifiedId));
4046                });
4047            }
4048        });
4049    }
4050    inputCheck1();
4051
4052
4053    function initializeMagneticHover(element) {
4054        let mouseDown = false;
4055        let originalZIndex = null;
4056        element.addEventListener('pointermove', (e) => {
4057            const rect = element.getBoundingClientRect();
4058            const x = e.clientX - rect.left - rect.width / 2;
4059            const y = e.clientY - rect.top - rect.height / 2;
4060            if (mouseDown) {
4061                element.style.transform = `translate(${x * 0.1}px, ${y * 0.1}px) scale(0.9)`;
4062            } else {
4063                element.style.transform = `translate(${x * 0.1}px, ${y * 0.1}px) scale(1.1)`;
4064            }
4065            if (!originalZIndex) {
4066                if (element.style.zIndex) originalZIndex = parseInt(element.style.zIndex);
4067                else originalZIndex = 0;
4068            }
4069            element.style.zIndex = originalZIndex + 1;
4070        });
4071        element.addEventListener('pointerleave', () => {
4072            element.style.transform = 'translate(0, 0) scale(1)';
4073            element.style.zIndex = originalZIndex;
4074            mouseDown = false;
4075        });
4076        element.addEventListener('pointerdown', (e) => {
4077            mouseDown = true;
4078            const rect = element.getBoundingClientRect();
4079            const x = e.clientX - rect.left - rect.width / 2;
4080            const y = e.clientY - rect.top - rect.height / 2;
4081            if (mouseDown) {
4082                element.style.transform = `translate(${x * 0.1}px, ${y * 0.1}px) scale(0.9)`;
4083            } else {
4084                element.style.transform = `translate(${x * 0.1}px, ${y * 0.1}px) scale(1.1)`;
4085            }
4086        });
4087        element.addEventListener('pointerup', (e) => {
4088            mouseDown = false;
4089            const rect = element.getBoundingClientRect();
4090            const x = e.clientX - rect.left - rect.width / 2;
4091            const y = e.clientY - rect.top - rect.height / 2;
4092
4093            const isPointerWithinElement = e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom;
4094            if (isPointerWithinElement) {
4095                playHaptic();
4096            }
4097
4098            if (mouseDown) {
4099                element.style.transform = `translate(${x * 0.1}px, ${y * 0.1}px) scale(0.9)`;
4100            } else {
4101                element.style.transform = `translate(${x * 0.1}px, ${y * 0.1}px) scale(1.1)`;
4102            }
4103        });
4104    }
4105    document.querySelectorAll('.DLP_Magnetic_Hover_1').forEach(element => {
4106        initializeMagneticHover(element);
4107    });
4108
4109    function initializeDefaultHover(element) {
4110        element.addEventListener('pointerup', (e) => {
4111            const rect = element.getBoundingClientRect();
4112            const isPointerWithinElement = e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom;
4113            if (isPointerWithinElement) {
4114                playHaptic();
4115            }
4116        });
4117    }
4118    document.querySelectorAll('.DLP_Hover_1').forEach(element => {
4119        initializeDefaultHover(element);
4120    });
4121
4122
4123    let DLP_Server_Connection_Button = document.getElementById("DLP_Main_1_Server_Connection_Button_1_ID");
4124    let DLP_Server_Connection_Button_2 = document.getElementById("DLP_Secondary_1_Server_Connection_Button_1_ID");
4125    DLP_Server_Connection_Button.addEventListener('click', () => {
4126        if (DLP_Server_Connection_Button.getAttribute("data-dlp-connection-status") === "outdated") {
4127            window.open("https://duolingopro.net/update/userscript", "_blank");
4128        } else if (DLP_Server_Connection_Button.getAttribute("data-dlp-connection-status") === "error") {
4129            window.open("https://status.duolingopro.net", "_blank");
4130        }
4131    });
4132    function updateConnetionButtonStyles(button, color, content, animation) {
4133        let iconToChange = button.querySelector(".DLP_Inset_Icon_1_ID");
4134        let textToChange = button.querySelector(".DLP_Inset_Text_1_ID");
4135        textToChange.style.animation = '';
4136        iconToChange.style.animation = '';
4137        void button.offsetWidth;
4138        requestAnimationFrame(() => {
4139            textToChange.style.filter = 'blur(4px)';
4140            textToChange.style.opacity = '0';
4141            iconToChange.style.filter = 'blur(4px)';
4142            iconToChange.style.opacity = '0';
4143            button.style.background = color.button;
4144            button.style.outline = `2px solid ${color.outline}`;
4145        });
4146        setTimeout(() => {
4147            textToChange.style.animation = 'none';
4148            iconToChange.style.animation = 'none';
4149            requestAnimationFrame(() => {
4150                textToChange.style.transition = '0s';
4151                iconToChange.style.transition = '0s';
4152                textToChange.textContent = content.text;
4153                iconToChange.textContent = content.icon;
4154                textToChange.style.color = color.text;
4155                iconToChange.style.color = color.icon;
4156                void button.offsetWidth;
4157                textToChange.style.transition = '0.4s';
4158                iconToChange.style.transition = '0.4s';
4159                void button.offsetWidth;
4160                textToChange.style.filter = 'blur(0px)';
4161                iconToChange.style.filter = 'blur(0px)';
4162                textToChange.style.opacity = '1';
4163                iconToChange.style.opacity = '1';
4164                setTimeout(() => {
4165                    textToChange.style.animation = animation.text;
4166                    iconToChange.style.animation = animation.icon;
4167                }, 400);
4168            });
4169        }, 400);
4170    }
4171    let serverConnectedBefore = 'no';
4172    let serverConnectedBeforeNotification;
4173    let newTermID;
4174    let chatMemory = [];
4175    let chatTempSendList = [];
4176    const pendingTempMessages = new Map();
4177    let chatMemoryFingerprints = [];
4178    let chatMessageLookup = new Map();
4179
4180    function normalizeMessageValue(value) {
4181        if (Array.isArray(value)) {
4182            return value.map(normalizeMessageValue);
4183        }
4184        if (value && typeof value === 'object') {
4185            const sortedKeys = Object.keys(value).sort();
4186            const normalizedObject = {};
4187            sortedKeys.forEach(key => {
4188                normalizedObject[key] = normalizeMessageValue(value[key]);
4189            });
4190            return normalizedObject;
4191        }
4192        if (value === undefined || Number.isNaN(value)) {
4193            return null;
4194        }
4195        return value;
4196    }
4197
4198    function computeMessageFingerprint(message) {
4199        const relevantData = {
4200            accent: message?.accent ?? '',
4201            author: message?.author ?? '',
4202            deleted: message?.deleted ?? false,
4203            edited: message?.edited ?? false,
4204            files: Array.isArray(message?.files) ? message.files.slice() : [],
4205            message_id: message?.message_id ?? null,
4206            message: message?.message ?? '',
4207            profile_picture: message?.profile_picture ?? '',
4208            role: message?.role ?? '',
4209            send_time: message?.send_time ?? null,
4210            status: message?.status ?? '',
4211            reply_to: message?.reply_to ?? null
4212        };
4213
4214        try {
4215            return JSON.stringify(normalizeMessageValue(relevantData));
4216        } catch (error) {
4217            console.error('Failed to compute message fingerprint', error);
4218            return JSON.stringify({
4219                message_id: message?.message_id ?? null,
4220                send_time: message?.send_time ?? null
4221            });
4222        }
4223    }
4224
4225    function resolveMessageKey(msg) {
4226        if (!msg || typeof msg !== 'object') return null;
4227        if (msg?.message_id !== undefined && msg?.message_id !== null) {
4228            return String(msg.message_id);
4229        }
4230        if (msg?.send_time !== undefined && msg?.send_time !== null) {
4231            return String(msg.send_time);
4232        }
4233        return null;
4234    }
4235
4236    function areArraysEqual(arrayA = [], arrayB = []) {
4237        if (arrayA.length !== arrayB.length) return false;
4238        for (let i = 0; i < arrayA.length; i++) {
4239            if (arrayA[i] !== arrayB[i]) return false;
4240        }
4241        return true;
4242    }
4243    let newReplyButtonActive = false;
4244    let userBioData = false;
4245    let kqjzvmbt = false;
4246    function connectToServer() {
4247        let mainInputsDiv1 = document.getElementById('DLP_Main_Inputs_1_Divider_1_ID');
4248
4249        const chatKeyValue = storageLocal?.chatKey?.[0] ?? false;
4250
4251        //fetch(apiURL + '/server', {
4252        fetch('https://api.duolingopro.net/server', {
4253            method: 'POST',
4254            headers: {
4255                'Content-Type': 'application/json'
4256            },
4257            body: JSON.stringify({
4258                version: versionFormal,
4259                key: storageLocal.random16,
4260                ...(chatKeyValue && { chat_key: chatKeyValue })
4261            })
4262        })
4263            .then(response => response.json())
4264            .then(data => {
4265                if (data.global || data.versions) {
4266                    console.log(data.chats);
4267
4268                    if (!userBioData && !fetchingUserBioData) {
4269                        fetchUserBioData();
4270                    }
4271
4272                    if (chatKeyValue) {
4273                        if (!data.chats) {
4274                            if (kqjzvmbt) {
4275                                storageLocal.chatKey.shift();
4276                                saveStorageLocal();
4277                            }
4278                            kqjzvmbt = true;
4279                        } else {
4280                            buildChat(data);
4281                        }
4282                    }
4283
4284                    function buildChat(data) {
4285                        const chatParent = document.querySelector('#DLP_Main_Box_Divider_11_ID').lastElementChild;
4286                        const chatBox = chatParent?.querySelector('.DLP_Chat_Box_1_ID_1');
4287                        if (!chatBox) return;
4288
4289                        if (typeof data === 'undefined' || typeof data.chats === 'undefined' || !Array.isArray(data.chats.messages)) return;
4290                        if (chatParent?.querySelector('#DLP_Inset_Group_3')?.style.display !== 'none') chatParent.querySelector('#DLP_Inset_Group_3').style.display = 'none';
4291                        if (chatBox?.style.display === 'none') chatBox.style.display = 'flex';
4292                        
4293                        if (data.chats.solved) {
4294                            chatParent.querySelector('#DLP_Inset_Group_1').style.display = 'none';
4295                            chatParent.querySelector('#DLP_Inset_Group_2').style.display = '';
4296                        }
4297
4298                        const incomingMessages = data.chats.messages.filter(msg => !msg?.deleted && msg?.status !== 'deleted');
4299                        const nextFingerprints = incomingMessages.map(computeMessageFingerprint);
4300                        const hasChanges = nextFingerprints.length !== chatMemoryFingerprints.length || nextFingerprints.some((fingerprint, index) => fingerprint !== chatMemoryFingerprints[index]);
4301
4302                        if (hasChanges) {
4303                            const previousLength = chatMemory.length;
4304                            const wasAtBottom = Math.abs(chatBox.scrollHeight - (chatBox.scrollTop + chatBox.clientHeight)) < 5;
4305                            const scrollOffsetFromBottom = chatBox.scrollHeight - chatBox.scrollTop;
4306
4307                            chatBox.innerHTML = '';
4308                            const combinedMessages = [];
4309                            let sequenceCounter = 0;
4310                            const resolveTimestamp = (msg) => {
4311                                const rawTimestamp = msg?.send_time;
4312                                if (rawTimestamp === undefined || rawTimestamp === null) {
4313                                    return Number.MAX_SAFE_INTEGER;
4314                                }
4315                                const numericTimestamp = Number(rawTimestamp);
4316                                if (!Number.isFinite(numericTimestamp)) {
4317                                    return Number.MAX_SAFE_INTEGER;
4318                                }
4319                                return numericTimestamp < 1e12 ? numericTimestamp * 1000 : numericTimestamp;
4320                            };
4321
4322                            incomingMessages.forEach(message => {
4323                                combinedMessages.push({
4324                                    message,
4325                                    tempId: false,
4326                                    sequence: sequenceCounter++
4327                                });
4328                            });
4329                            pendingTempMessages.forEach((tempMessage, tempId) => {
4330                                combinedMessages.push({
4331                                    message: tempMessage,
4332                                    tempId,
4333                                    sequence: sequenceCounter++
4334                                });
4335                            });
4336
4337                            combinedMessages.sort((a, b) => {
4338                                const timeA = resolveTimestamp(a.message);
4339                                const timeB = resolveTimestamp(b.message);
4340                                if (timeA === timeB) {
4341                                    return a.sequence - b.sequence;
4342                                }
4343                                return timeA - timeB;
4344                            });
4345
4346                            chatMessageLookup.clear();
4347                            incomingMessages.forEach(msg => {
4348                                const key = resolveMessageKey(msg);
4349                                if (key) {
4350                                    chatMessageLookup.set(key, msg);
4351                                }
4352                                if (msg?.send_time !== undefined && msg?.send_time !== null) {
4353                                    const sendKey = String(msg.send_time);
4354                                    if (sendKey && sendKey !== key) {
4355                                        chatMessageLookup.set(sendKey, msg);
4356                                    }
4357                                }
4358                            });
4359
4360                            combinedMessages.forEach(({ message, tempId }) => {
4361                                createMessage(message, false, tempId || false);
4362                            });
4363
4364                            const hasNewMessages = incomingMessages.length > previousLength;
4365                            if (hasNewMessages || wasAtBottom) {
4366                                chatBox.scrollTop = chatBox.scrollHeight;
4367                            } else {
4368                                const newScrollTop = chatBox.scrollHeight - scrollOffsetFromBottom;
4369                                chatBox.scrollTop = newScrollTop < 0 ? 0 : newScrollTop;
4370                            }
4371                        }
4372
4373                        chatMemory = incomingMessages.map(message => ({ ...message }));
4374                        chatMemoryFingerprints = nextFingerprints;
4375
4376                        const knownMessageIds = (storageLocal.chats ?? []).map(id => (id === null || id === undefined) ? id : String(id));
4377
4378                        if (currentPage === 11) {
4379                            const newMessageIds = chatMemory.map(resolveMessageKey);
4380                            if (!areArraysEqual(knownMessageIds, newMessageIds)) {
4381                                storageLocal.chats = newMessageIds;
4382                                saveStorageLocal();
4383                            }
4384                        } else {
4385                            incomingMessages.forEach(msg => {
4386                                const messageKey = resolveMessageKey(msg);
4387                                const sendTimeKey = (msg?.send_time !== undefined && msg?.send_time !== null) ? String(msg.send_time) : null;
4388                                const alreadyKnown = (messageKey && knownMessageIds.includes(messageKey)) || (sendTimeKey && knownMessageIds.includes(sendTimeKey));
4389                                if (!alreadyKnown && !newReplyButtonActive) {
4390                                    newReplyButtonActive = true;
4391                                    updateConnetionButtonStyles(document.getElementById("DLP_Main_Feedback_1_Button_1_ID"), {button: 'rgb(var(--DLP-blue))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF'}, {text: 'New Reply', icon: '􀝗'}, {text: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite', icon: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite'});
4392                                    showNotification({icon: "􂄺", color: "rgb(var(--DLP-blue))"}, "Support Team Response", "You have a new message from our support team.", 30);
4393                                }
4394                            });
4395                        }
4396                    }
4397
4398
4399                    const globalData = data.global;
4400                    const versionData = data.versions[versionFull];
4401                    const warnings = versionData.warnings || [];
4402
4403                    const termsText = Object.entries(globalData.terms)[0][1];
4404                    newTermID = Object.entries(globalData.terms)[0][0];
4405
4406                    //console.log('Global Warning:', globalData.warning);
4407                    //console.log('Notifications:', globalData.notifications);
4408
4409                    document.querySelector(`#DLP_Terms_Main_Text_1_ID`).innerHTML = termsText;
4410
4411                    if (versionData.status === 'latest') {
4412                        if (storageLocal.terms === newTermID) {
4413                            if (serverConnectedBefore !== 'yes') {
4414                                updateReleaseNotes(warnings);
4415                                mainInputsDiv1.style.opacity = '1';
4416                                mainInputsDiv1.style.pointerEvents = 'auto';
4417                                updateConnetionButtonStyles(DLP_Server_Connection_Button, {button: 'rgb(var(--DLP-green))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF'}, {text: systemText[systemLanguage][108], icon: '􀤆'}, {text: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite', icon: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite'});
4418                                updateConnetionButtonStyles(DLP_Server_Connection_Button_2, {button: 'rgb(var(--DLP-green))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF'}, {text: systemText[systemLanguage][108], icon: '􀤆'}, {text: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite', icon: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite'});
4419                                DLP_Server_Connection_Button.setAttribute("data-dlp-connection-status", "connected");
4420                                DLP_Server_Connection_Button_2.setAttribute("data-dlp-connection-status", "connected");
4421                                if (serverConnectedBefore === 'error' || serverConnectedBeforeNotification) {
4422                                    serverConnectedBeforeNotification.close();
4423                                    serverConnectedBeforeNotification = false;
4424                                }
4425                                serverConnectedBefore = 'yes';
4426                            }
4427                        } else {
4428                            if (storageLocal.onboarding) {
4429                                if (currentPage !== 5 && currentPage !== 6) goToPage(5);
4430                                document.querySelector(`#DLP_Main_Box_Divider_5_ID`).querySelector(`#DLP_Terms_1_Text_1_ID`).innerHTML = "We have updated our Terms & Conditions. Please read them carefully and accept to continue using Duolingo PRO 3.1.";
4431                            } else {
4432                                if (currentPage !== 10) goToPage(10);
4433                            }
4434                        }
4435                    } else if (serverConnectedBefore !== 'outdated') {
4436                        updateConnetionButtonStyles(DLP_Server_Connection_Button, {button: 'rgb(var(--DLP-orange))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF'}, {text: 'Outdated', icon: '􀁟'}, {text: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite', icon: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite'});
4437                        updateConnetionButtonStyles(DLP_Server_Connection_Button_2, {button: 'rgb(var(--DLP-orange))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF'}, {text: 'Outdated', icon: '􀁟'}, {text: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite', icon: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite'});
4438                        DLP_Server_Connection_Button.setAttribute("data-dlp-connection-status", "outdated");
4439                        DLP_Server_Connection_Button_2.setAttribute("data-dlp-connection-status", "outdated");
4440                        if (serverConnectedBefore === 'no') {
4441                            mainInputsDiv1.style.opacity = '0.5';
4442                            mainInputsDiv1.style.pointerEvents = 'none';
4443                            showNotification("warning", systemText[systemLanguage][233], systemText[systemLanguage][234], 0);
4444                        } else if (serverConnectedBefore === 'error' || serverConnectedBeforeNotification) {
4445                            serverConnectedBeforeNotification.close();
4446                            serverConnectedBeforeNotification = false;
4447                        }
4448                        serverConnectedBefore = 'outdated';
4449                    }
4450
4451                    //if (storageLocal.languagePackVersion !== versionData.languagePackVersion) {
4452                    //    fetch(serverURL + "/static/3.0/resources/language_pack.json")
4453                    //        .then(response => response.json())
4454                    //        .then(data => {
4455                    //            if (data[versionFull]) {
4456                    //                storageLocal.languagePack = data[versionFull];
4457                    //                console.log(data[versionFull]);
4458                    //                storageLocal.languagePackVersion = versionData.languagePackVersion;
4459                    //                saveStorageLocal();
4460                    //            }
4461                    //        })
4462                    //        .catch(error => console.error('Error fetching systemText:', error));
4463                    //}
4464                } else {
4465                    console.error(`Version ${versionFull} not found in the data`);
4466                }
4467            })
4468            .catch(error => {
4469                console.error('Error fetching data:', error);
4470                if (serverConnectedBefore !== 'error') {
4471                    mainInputsDiv1.style.opacity = '0.5';
4472                    mainInputsDiv1.style.pointerEvents = 'none';
4473                    updateConnetionButtonStyles(DLP_Server_Connection_Button, {button: 'rgb(var(--DLP-pink))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF'}, {text: systemText[systemLanguage][109], icon: '􀇿'}, {text: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite', icon: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite'});
4474                    updateConnetionButtonStyles(DLP_Server_Connection_Button_2, {button: 'rgb(var(--DLP-pink))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF'}, {text: systemText[systemLanguage][109], icon: '􀇿'}, {text: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite', icon: 'DLP_Pulse_Opacity_Animation_1 6s ease-in-out infinite'});
4475                    DLP_Server_Connection_Button.setAttribute("data-dlp-connection-status", "error");
4476                    DLP_Server_Connection_Button_2.setAttribute("data-dlp-connection-status", "error");
4477                    serverConnectedBeforeNotification = showNotification("error", systemText[systemLanguage][231], systemText[systemLanguage][232], 0);
4478                    serverConnectedBefore = 'error';
4479                }
4480            });
4481    }
4482    connectToServer();
4483    setTimeout(() => {
4484        connectToServer();
4485    }, 1000);
4486    setInterval(() => {
4487        //if (windowBlurState) connectToServer();
4488        if (document.visibilityState === "visible" || isAutoMode) connectToServer();
4489    }, 4000);
4490
4491    let fetchingUserBioData = false;
4492    async function fetchUserBioData() {
4493        fetchingUserBioData = true;
4494        console.log('FETHCING FOR YOU YOUR HONOR');
4495        const userResponse = await fetch('https://www.duolingo.com/2017-06-30/users/' + JSON.parse(atob(document.cookie.split(';').find(cookie => cookie.includes('jwt_token')).split('=')[1].split('.')[1])).sub + '?fields=name,username,picture');
4496        if (!userResponse.ok) {
4497            fetchingUserBioData = false;
4498            return;
4499        }
4500        const userData = await userResponse.json();
4501        console.log(userData);
4502        userBioData = {
4503            username: (userData.name && userData.name.trim().length > 0) ? userData.name : userData.username,
4504            profile_picture: "https:" + userData.picture + "/xlarge"
4505        };
4506        fetchingUserBioData = false;
4507    }
4508
4509    function createMessage(message, isBefore=false, isTemp=false) {
4510        function formatTimeAgo(timestamp) {
4511            // If the timestamp is in seconds (10 digits), convert to ms
4512            if (timestamp < 1e12) {
4513                timestamp = timestamp * 1000;
4514            }
4515            const now = Date.now();
4516            const diff = now - timestamp; // Difference in milliseconds
4517
4518            const seconds = Math.floor(diff / 1000);
4519            const minutes = Math.floor(seconds / 60);
4520            const hours = Math.floor(minutes / 60);
4521            const days = Math.floor(hours / 24);
4522            const weeks = Math.floor(days / 7);
4523            const months = Math.floor(days / 30);
4524            const years = Math.floor(days / 365);
4525
4526            if (seconds < 60) {
4527                return "now";
4528            } else if (minutes < 60) {
4529                return `${minutes}m ago`;
4530            } else if (hours < 24) {
4531                return `${hours}h ago`;
4532            } else if (days < 7) {
4533                return `${days}d ago`;
4534            } else if (weeks < 4) {
4535                return `${weeks}w ago`;
4536            } else if (months < 12) {
4537                return `${months}m ago`;
4538            } else {
4539                return `${years}y ago`;
4540            }
4541        }
4542        function toMilliseconds(ts) {
4543            return ts < 1e12 ? ts * 1000 : ts;
4544        }
4545        function updateTimeAgo(element, timestamp) {
4546            function update() {
4547                if (!document.contains(element)) {
4548                    clearInterval(intervalId);
4549                    return;
4550                }
4551                const newText = formatTimeAgo(timestamp);
4552                if (element.textContent !== newText) {
4553                    element.textContent = newText;
4554                }
4555            }
4556
4557            update();
4558            const intervalId = setInterval(update, 1000);
4559        }
4560
4561        const chatBox = document.querySelector('#DLP_Main_Box_Divider_11_ID')?.querySelector('.DLP_Chat_Box_1_ID_1');
4562
4563        const messageKey = (() => {
4564            if (message?.message_id !== undefined && message?.message_id !== null) {
4565                return String(message.message_id);
4566            }
4567            if (message?.send_time !== undefined && message?.send_time !== null) {
4568                return String(message.send_time);
4569            }
4570            if (isTemp) {
4571                return `temp-${isTemp}`;
4572            }
4573            return '';
4574        })();
4575
4576        let lastChatChild = chatBox.lastElementChild;
4577        if (isBefore) lastChatChild = isBefore.previousElementSibling;
4578
4579        const tempState = isTemp ? pendingTempMessages.get(isTemp) : null;
4580        const failedTemp = Boolean(tempState?.sendFailed);
4581
4582        function getReplyKey(message) {
4583            const rawReplyTo = message?.reply_to;
4584            if (typeof rawReplyTo === 'number' && Number.isFinite(rawReplyTo)) {
4585                return String(rawReplyTo);
4586            }
4587            if (typeof rawReplyTo === 'string') {
4588                const trimmed = rawReplyTo.trim();
4589                if (/^\d+$/.test(trimmed)) {
4590                    return trimmed;
4591                }
4592            }
4593            if (typeof rawReplyTo === 'bigint') {
4594                return rawReplyTo.toString();
4595            }
4596            return null;
4597        }
4598
4599        function hasNumericReply(message) {
4600            return Boolean(getReplyKey(message));
4601        }
4602
4603        function createReplyPreview(message) {
4604            const replyKey = getReplyKey(message);
4605            if (!replyKey) {
4606                return null;
4607            }
4608
4609            function deriveTargetFromDom(key) {
4610                if (!chatBox) return null;
4611
4612                const messageNodes = chatBox.querySelectorAll('[data-message-id]');
4613                let matchedNode = null;
4614                for (const node of messageNodes) {
4615                    if (node.getAttribute('data-message-id') === key) {
4616                        matchedNode = node;
4617                        break;
4618                    }
4619                }
4620
4621                if (!matchedNode) {
4622                    const groupCandidate = chatBox.querySelector(`[data-group-id="${key}"]`);
4623                    if (groupCandidate) {
4624                        matchedNode = groupCandidate.querySelector('[data-message-id]');
4625                    }
4626                }
4627
4628                if (!matchedNode) return null;
4629
4630                const result = {
4631                    message_id: key,
4632                    message: (matchedNode.textContent || '').trim()
4633                };
4634
4635                const sendAttr = matchedNode.getAttribute('data-message-sent');
4636                if (sendAttr && sendAttr !== '') {
4637                    const numericSend = Number(sendAttr);
4638                    result.send_time = Number.isFinite(numericSend) ? numericSend : sendAttr;
4639                }
4640
4641                const groupNode = matchedNode.closest('[data-group-id]');
4642                if (groupNode) {
4643                    if (!result.message) {
4644                        const fallbackNode = groupNode.querySelector('[data-message-id]');
4645                        if (fallbackNode && fallbackNode !== matchedNode) {
4646                            const fallbackText = (fallbackNode.textContent || '').trim();
4647                            if (fallbackText) {
4648                                result.message = fallbackText;
4649                            }
4650                        }
4651                    }
4652
4653                    const authorNameAttr = groupNode.getAttribute('data-author-name');
4654                    if (authorNameAttr) {
4655                        result.author = authorNameAttr;
4656                    }
4657
4658                    const headerNode = groupNode.querySelector('[data-chat-header="true"]');
4659                    if (headerNode) {
4660                        const authorElement = headerNode.querySelector('.DLP_HStack_6 p.DLP_Text_Style_1');
4661                        if (authorElement) {
4662                            const authorText = authorElement.textContent || '';
4663                            if (authorText.trim()) {
4664                                result.author = authorText.trim();
4665                            }
4666                            let accentColor = authorElement.style?.color?.trim();
4667                            if ((!accentColor || accentColor === '') && typeof window !== 'undefined' && document.contains(authorElement)) {
4668                                try {
4669                                    accentColor = window.getComputedStyle(authorElement).color;
4670                                } catch (error) {
4671                                    console.error('Failed to compute accent color for reply preview', error);
4672                                }
4673                            }
4674                            if (accentColor) {
4675                                result.accent = accentColor;
4676                            }
4677                        }
4678
4679                        const avatarElement = headerNode.querySelector('div[style*="background"]');
4680                        if (avatarElement) {
4681                            const styleAttr = avatarElement.getAttribute('style') || '';
4682                            const urlMatch = styleAttr.match(/url\((['"]?)(.*?)\1\)/);
4683                            if (urlMatch && urlMatch[2]) {
4684                                result.profile_picture = urlMatch[2];
4685                            }
4686                        }
4687                    }
4688                }
4689
4690                if ((!result.message || result.message === '') && matchedNode.classList?.contains('DLP_Hide_Scrollbar')) {
4691                    result.message = 'Attachment';
4692                }
4693
4694                return result;
4695            }
4696
4697            let targetMessage = chatMessageLookup.get(replyKey);
4698            if (!targetMessage && chatMemory.length) {
4699                targetMessage = chatMemory.find(existing => resolveMessageKey(existing) === replyKey);
4700            }
4701
4702            function isMeaningful(value, type) {
4703                if (value === undefined || value === null) return false;
4704                const trimmed = String(value).trim();
4705                if (!trimmed) return false;
4706                if (type === 'author' && trimmed === 'The User Who Was Replied') return false;
4707                if (type === 'message' && trimmed === 'Reply content') return false;
4708                return true;
4709            }
4710
4711            const domMessage = deriveTargetFromDom(replyKey);
4712            if (domMessage) {
4713                const merged = targetMessage ? { ...targetMessage } : {};
4714
4715                if (isMeaningful(domMessage.author, 'author')) {
4716                    merged.author = domMessage.author;
4717                }
4718                if (isMeaningful(domMessage.profile_picture)) {
4719                    merged.profile_picture = domMessage.profile_picture;
4720                }
4721                if (isMeaningful(domMessage.accent)) {
4722                    merged.accent = domMessage.accent;
4723                }
4724
4725                if (isMeaningful(domMessage.message, 'message')) {
4726                    if (!isMeaningful(merged.message, 'message') || domMessage.message !== 'Attachment') {
4727                        merged.message = domMessage.message;
4728                    }
4729                } else if (!isMeaningful(merged.message, 'message') && domMessage.message) {
4730                    merged.message = domMessage.message;
4731                }
4732
4733                if (domMessage.send_time !== undefined && domMessage.send_time !== null && (merged.send_time === undefined || merged.send_time === null || merged.send_time === '')) {
4734                    merged.send_time = domMessage.send_time;
4735                }
4736                if (!isMeaningful(merged.message_id)) {
4737                    merged.message_id = replyKey;
4738                }
4739
4740                targetMessage = merged;
4741                chatMessageLookup.set(replyKey, targetMessage);
4742                const derivedSendKey = targetMessage?.send_time;
4743                if (derivedSendKey !== undefined && derivedSendKey !== null) {
4744                    const sendKey = String(derivedSendKey);
4745                    if (sendKey && sendKey !== replyKey) {
4746                        chatMessageLookup.set(sendKey, targetMessage);
4747                    }
4748                }
4749            }
4750
4751            const previewWrapper = document.createElement('div');
4752            const targetKey = resolveMessageKey(targetMessage) ?? replyKey;
4753            const targetSendTime = targetMessage?.send_time ?? '';
4754            const previewAccent = targetMessage?.accent && targetMessage.accent !== '' ? targetMessage.accent : (message?.accent || 'rgb(var(--DLP-blue))');
4755            const previewAuthor = targetMessage?.author ?? message?.author ?? 'Unknown user';
4756            const previewAvatar = targetMessage?.profile_picture ?? message?.profile_picture ?? '';
4757            const avatarBackground = previewAvatar ? `background: url(${previewAvatar}) 50% center / cover no-repeat white;` : 'background: rgba(var(--color-snow), 1);';
4758            const previewMessage = (targetMessage?.message && targetMessage.message.trim() !== '') ? targetMessage.message : 'Original message unavailable';
4759
4760            previewWrapper.innerHTML = `
4761                <div class="DLP_HStack_8" data-reply-preview="true" style="padding-left: 24px; position: relative;">
4762                    <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" style="position: absolute; left: 9px; top: 9px; z-index: -1;">
4763                        <path d="M17 1H11C5.47715 1 1 5.47715 1 11V17" stroke="rgb(var(--color-eel), 0.20)" stroke-width="2" stroke-linecap="round"/>
4764                    </svg>
4765                    <div class="DLP_HStack_6">
4766                        <div style="width: 20px; height: 20px; border-radius: 16px; outline: rgba(0, 0, 0, 0.2) solid 2px; outline-offset: -2px; ${avatarBackground}"></div>
4767                        <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: ${previewAccent}; white-space: pre;">${previewAuthor}</p>
4768                    </div>
4769                    <p class="DLP_Text_Style_1" data-message-id="${targetKey}" data-message-sent="${targetSendTime}" style="align-self: stretch; white-space: nowrap; overflow-wrap: anywhere; word-break: break-word; text-overflow: ellipsis; -webkit-line-clamp: 1; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical;">${previewMessage}</p>
4770                </div>
4771            `;
4772
4773            return previewWrapper.firstElementChild;
4774        }
4775
4776        function ensureReplyPreview(container, message) {
4777            if (!container) return;
4778            const replyKey = getReplyKey(message);
4779            const existingPreview = container.querySelector('[data-reply-preview="true"]');
4780
4781            if (!replyKey) {
4782                if (existingPreview) existingPreview.remove();
4783                return;
4784            }
4785
4786            const headerElement = container.querySelector('[data-chat-header="true"]');
4787            if (!headerElement) {
4788                if (existingPreview) existingPreview.remove();
4789                return;
4790            }
4791
4792            if (existingPreview) {
4793                existingPreview.remove();
4794            }
4795
4796            const previewElement = createReplyPreview(message);
4797            if (previewElement) {
4798                container.insertBefore(previewElement, headerElement);
4799            }
4800        }
4801
4802        function createStartersMessage(message) {
4803            const temp = document.createElement('div');
4804            temp.innerHTML = `
4805                <div class="DLP_VStack_4" data-group-id="${messageKey}" data-group-sent="${message.send_time ?? ''}" data-author-name="${message.author}">
4806                    <div data-chat-header="true" style="display: flex; justify-content: space-between; align-items: center; align-self: stretch;">
4807                        <div class="DLP_HStack_6">
4808                            <div style="width: 20px; height: 20px; border-radius: 16px; outline: rgba(0, 0, 0, 0.2) solid 2px; outline-offset: -2px; background: url(${message.profile_picture}) 50% center / cover no-repeat white;"></div>
4809                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: ${message.accent};">${message.author}</p>
4810                        </div>
4811                        <div class="DLP_HStack_6">
4812                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: ${message.accent};">${message.role}</p>
4813                            <p class="DLP_Text_Style_1 DLP_NoSelect" style="color: ${message.accent}; font-size: 4px;">􀀁</p>
4814                            <p class="DLP_Text_Style_1 DLP_NoSelect" data-time-element="true" style="color: ${message.accent};">${formatTimeAgo(message.send_time)}</p>
4815                        </div>
4816                    </div>
4817                </div>
4818            `;
4819            const newElement = temp.firstElementChild;
4820            chatBox.appendChild(newElement);
4821            lastChatChild = newElement;
4822
4823            ensureReplyPreview(lastChatChild, message);
4824
4825            const timeElement = lastChatChild.querySelector('[data-time-element="true"]');
4826            if (timeElement) {
4827                updateTimeAgo(timeElement, message.send_time);
4828            }
4829
4830            createContinuationMessage(message, true);
4831        }
4832
4833        function createContinuationMessage(message, skipGroupChecks = false) {
4834            const firstMessageTimestampAttr = lastChatChild.getAttribute('data-group-sent') ?? lastChatChild.getAttribute('data-group-timestamp');
4835            const firstMessageTimestamp = firstMessageTimestampAttr ? parseInt(firstMessageTimestampAttr) : 0;
4836            const replyKey = getReplyKey(message);
4837
4838            if (!skipGroupChecks) {
4839                if (replyKey) {
4840                    createStartersMessage(message);
4841                    return;
4842                }
4843                if (toMilliseconds(message.send_time) - toMilliseconds(firstMessageTimestamp) > 900000) { // 15 minutes, 900,000 milliseconds
4844                    createStartersMessage(message);
4845                    return;
4846                }
4847            }
4848
4849            if (replyKey) {
4850                ensureReplyPreview(lastChatChild, message);
4851            }
4852
4853            if (message.message !== "") {
4854                const continuationStyles = [
4855                    'align-self: stretch',
4856                    'white-space: pre-line',
4857                    'overflow-wrap: anywhere',
4858                    'word-break: break-word'
4859                ];
4860                if (isTemp && !failedTemp) {
4861                    continuationStyles.push('animation: DLP_Pulse_Opacity_Animation_2 2s ease-in-out infinite');
4862                }
4863                if (failedTemp) {
4864                    continuationStyles.push('color: rgba(var(--DLP-pink))');
4865                }
4866                const continuationStyleAttr = continuationStyles.join('; ') + ';';
4867                const temp = document.createElement('div');
4868                temp.innerHTML = `
4869                    <p class="DLP_Text_Style_1" data-message-id="${messageKey}" data-message-sent="${message.send_time ?? ''}"${isTemp ? ` data-is-temp="${isTemp}"` : ''} style="${continuationStyleAttr}">${message.message}</p>
4870                `;
4871                const newElement = temp.firstElementChild;
4872                lastChatChild.appendChild(newElement);
4873            }
4874            createAttachmentMessage(message);
4875        }
4876
4877        function expandAttachment(lastAttachment) {
4878            let expanded = false;
4879
4880            function getElementPosition(element) {
4881                if (!element || !(element instanceof Element)) {
4882                    return false;
4883                }
4884                const rect = element.getBoundingClientRect();
4885                return {
4886                    top: rect.top,
4887                    right: rect.right,
4888                    bottom: rect.bottom,
4889                    left: rect.left,
4890                    width: rect.width,
4891                    height: rect.height
4892                };
4893            }
4894
4895            async function getElementDimensions(element) {
4896                return new Promise((resolve, reject) => {
4897                    if (!(element instanceof HTMLImageElement) && !(element instanceof HTMLVideoElement)) {
4898                    return reject(new Error('Element must be an image or video'));
4899                    }
4900
4901                    if (element instanceof HTMLImageElement) {
4902                    if (element.complete) {
4903                        return resolve({ width: element.naturalWidth, height: element.naturalHeight });
4904                    }
4905                    element.addEventListener('load', () => {
4906                        resolve({ width: element.naturalWidth, height: element.naturalHeight });
4907                    }, { once: true });
4908                    element.addEventListener('error', () => {
4909                        reject(new Error('Failed to load image'));
4910                    }, { once: true });
4911                    } else if (element instanceof HTMLVideoElement) {
4912                    if (element.readyState >= 1) {
4913                        return resolve({ width: element.videoWidth, height: element.videoHeight });
4914                    }
4915                    element.addEventListener('loadedmetadata', () => {
4916                        resolve({ width: element.videoWidth, height: element.videoHeight });
4917                    }, { once: true });
4918                    element.addEventListener('error', () => {
4919                        reject(new Error('Failed to load video'));
4920                    }, { once: true });
4921                    }
4922                });
4923            }
4924
4925            function getMaxDimensions(element) {
4926                const computedStyle = window.getComputedStyle(element);
4927                const maxWidth = computedStyle.maxWidth;
4928                const maxHeight = computedStyle.maxHeight;
4929
4930                const result = { width: null, height: null };
4931
4932                function parseCalcOrPixel(value, dimension) {
4933                    // If value is in pixels, return it
4934                    if (value.endsWith('px')) {
4935                    return parseFloat(value);
4936                    }
4937
4938                    // Handle calc(100% - Npx)
4939                    if (value.includes('calc')) {
4940                    const match = value.match(/calc\(100% - (\d+\.?\d*?)px\)/);
4941                    if (match) {
4942                        const subtractedPx = parseFloat(match[1]);
4943                        const parent = element.parentElement;
4944                        if (dimension === 'width') {
4945                        return parent ? parent.getBoundingClientRect().width - subtractedPx : window.innerWidth - subtractedPx;
4946                        } else if (dimension === 'height') {
4947                        return parent ? parent.getBoundingClientRect().height - subtractedPx : window.innerHeight - subtractedPx;
4948                        }
4949                    }
4950                    }
4951
4952                    return false; // Fallback
4953                }
4954
4955                // Calculate max-width and max-height in pixels
4956                result.width = parseCalcOrPixel(maxWidth, 'width');
4957                result.height = parseCalcOrPixel(maxHeight, 'height');
4958
4959                return result;
4960            }
4961
4962            async function fitToWindow() {
4963                const max = getMaxDimensions(lastAttachment);
4964                const lastAttachmentContent = lastAttachment.querySelector('.DLP_Attachment_Box_1_Content');
4965                const orig = await getElementDimensions(lastAttachmentContent);
4966                const scale = Math.min(max.width / orig.width, max.height / orig.height);
4967
4968                const w = Math.floor(orig.width * scale);
4969                const h = Math.floor(orig.height * scale);
4970                lastAttachment.style.width = `${w}px`;
4971                lastAttachment.style.height = `${h}px`;
4972            }
4973
4974            lastAttachment.addEventListener('mouseenter', () => {
4975                if (expanded) return;
4976                lastAttachment.querySelector('.DLP_Attachment_Box_1_Hover').style.display = '';
4977            });
4978            lastAttachment.addEventListener('mouseleave', () => {
4979                if (expanded) return;
4980                lastAttachment.querySelector('.DLP_Attachment_Box_1_Hover').style.display = 'none';
4981            });
4982            lastAttachment.querySelector('.DLP_Attachment_Box_1_Hover p').addEventListener('click', async () => {
4983                expanded = true;
4984                lastAttachment.querySelector('.DLP_Attachment_Box_1_Hover').style.display = 'none';
4985
4986                let pos = getElementPosition(lastAttachment);
4987                const tempHover = document.createElement('div');
4988                tempHover.style.width = pos.width + 'px';
4989                tempHover.style.height = pos.height + 'px';
4990                tempHover.style.opacity = '0';
4991
4992                // append tempHover right before lastAttachment
4993                lastAttachment.parentNode.insertBefore(tempHover, lastAttachment);
4994
4995                const largeViewMotherBox = document.createElement('div');
4996                largeViewMotherBox.className = 'DLP_Attachment_Box_Large_View_1';
4997                document.body.appendChild(largeViewMotherBox);
4998
4999                let closeBtn = `
5000                    <div style="display: flex; padding: 2px; justify-content: center; align-items: center; gap: 6px; opacity: 0.5; position: absolute; bottom: 24px; pointer-events: none;">
5001                        <p class="DLP_Text_Style_1 DLP_NoSelect">􀆄</p>
5002                        <p class="DLP_Text_Style_1 DLP_NoSelect">Close</p>
5003                    </div>
5004                `;
5005                largeViewMotherBox.insertAdjacentHTML('beforeend', closeBtn);
5006
5007                function getTransformToMatchPosition(element) {
5008                    const parentRect = largeViewMotherBox.getBoundingClientRect();
5009                    const centerX = parentRect.width / 2;
5010                    const centerY = parentRect.height / 2;
5011                    const elementRect = element.getBoundingClientRect();
5012                    const elementCenterX = elementRect.width / 2;
5013                    const elementCenterY = elementRect.height / 2;
5014                    const shiftX = pos.left + elementCenterX - centerX;
5015                    const shiftY = pos.top + elementCenterY - centerY;
5016                    return { translateX: shiftX, translateY: shiftY };
5017                }
5018
5019                largeViewMotherBox.appendChild(lastAttachment);
5020
5021                translate = getTransformToMatchPosition(lastAttachment);
5022
5023                lastAttachment.style.transform = `translate(${translate.translateX}px, ${translate.translateY}px)`;
5024                void lastAttachment.offsetHeight;
5025
5026                lastAttachment.style.transition = '0.4s cubic-bezier(0.16, 1, 0.32, 1)';
5027
5028                void lastAttachment.offsetHeight;
5029
5030                lastAttachment.style.transform = 'translate(0px, 0px)';
5031
5032                largeViewMotherBox.style.background = 'rgba(var(--color-snow), 0.50)';
5033                largeViewMotherBox.style.backdropFilter = 'blur(16px)';
5034
5035                lastAttachment.style.aspectRatio = 'unset';
5036
5037                let lastAttachmentContent = lastAttachment.querySelector('.DLP_Attachment_Box_1_Content');
5038
5039                lastAttachmentContent.style.aspectRatio = 'unset';
5040                lastAttachmentContent.style.maxWidth = '100%';
5041                lastAttachmentContent.style.maxHeight = '100%';
5042                lastAttachmentContent.style.width = 'auto';
5043                lastAttachmentContent.style.height = 'auto';
5044
5045                lastAttachment.style.maxWidth = 'calc(100% - 32px)';
5046                lastAttachment.style.maxHeight = 'calc(100% - 142px)';
5047
5048                lastAttachment.style.display = 'inline-flex';
5049
5050                lastAttachment.style.width = 'auto';
5051                lastAttachment.style.height = 'auto';
5052
5053                void lastAttachment.offsetHeight;
5054
5055                const maxDimensions = getMaxDimensions(lastAttachment);
5056                const elementDimensions = await getElementDimensions(lastAttachmentContent);
5057
5058                // compute uniform scale to fit within maxDimensions
5059                const scale = Math.min(maxDimensions.width / elementDimensions.width, maxDimensions.height / elementDimensions.height);
5060
5061                // calculate final pixel dimensions
5062                let newWidth = Math.floor(elementDimensions.width * scale);
5063                let newHeight = Math.floor(elementDimensions.height * scale);
5064
5065                //let newWidth = lastAttachmentContent.offsetWidth;
5066                //let newHeight = lastAttachmentContent.offsetHeight;
5067
5068                lastAttachment.style.width = '';
5069                lastAttachment.style.height = '';
5070
5071                void lastAttachment.offsetHeight;
5072
5073                lastAttachment.style.width = newWidth + 'px';
5074                lastAttachment.style.height = newHeight + 'px';
5075
5076                lastAttachmentContent.style.width = '100%';
5077                lastAttachmentContent.style.height = '100%';
5078
5079                if (lastAttachmentContent.tagName.toLowerCase() === 'video') {
5080                    lastAttachmentContent.controls = true;
5081                    lastAttachmentContent.autoplay = false;
5082                    lastAttachmentContent.muted = false;
5083                    lastAttachmentContent.currentTime = 0;
5084                    lastAttachmentContent.play();
5085                }
5086
5087                window.addEventListener('resize', fitToWindow);
5088
5089                largeViewMotherBox.addEventListener('click', (event) => {
5090                    if (largeViewMotherBox === event.target && lastAttachment !== event.target) {
5091                        window.removeEventListener('resize', fitToWindow);
5092
5093                        if (lastAttachmentContent.tagName.toLowerCase() === 'video') {
5094                            lastAttachmentContent.controls = false;
5095                            lastAttachmentContent.autoplay = true;
5096                            lastAttachmentContent.muted = true;
5097                            lastAttachmentContent.play();
5098                        }
5099
5100                        lastAttachment.style.transform = `translate(${translate.translateX}px, ${translate.translateY}px)`;
5101                        lastAttachment.style.width = pos.width + 'px';
5102                        lastAttachment.style.height = pos.height + 'px';
5103
5104                        largeViewMotherBox.style.background = 'rgba(var(--color-snow), 0.00)';
5105                        largeViewMotherBox.style.backdropFilter = 'blur(0px)';
5106
5107                        setTimeout(() => {
5108                            tempHover.parentNode.insertBefore(lastAttachment, tempHover);
5109                            lastAttachment.style.transform = '';
5110                            tempHover.remove();
5111                            largeViewMotherBox.remove();
5112
5113                            lastAttachment.style.aspectRatio = '';
5114                            lastAttachment.querySelector('.DLP_Attachment_Box_1_Content').style.aspectRatio = '';
5115                            lastAttachment.querySelector('.DLP_Attachment_Box_1_Content').style.maxWidth = '';
5116                            lastAttachment.querySelector('.DLP_Attachment_Box_1_Content').style.maxHeight = '';
5117                            lastAttachment.querySelector('.DLP_Attachment_Box_1_Content').style.width = '';
5118                            lastAttachment.querySelector('.DLP_Attachment_Box_1_Content').style.height = '';
5119
5120                            lastAttachment.style.maxWidth = '';
5121                            lastAttachment.style.maxHeight = '';
5122
5123                            lastAttachment.style.display = '';
5124
5125                            lastAttachment.style.transition = '';
5126                            void lastAttachment.offsetHeight;
5127
5128                            expanded = false;
5129                        }, 400);
5130                    }
5131                });
5132            });
5133        }
5134
5135        async function createAttachmentMessage(message) {
5136            async function contentType(url) {
5137                const imageExts = ['jpg','jpeg','png','gif','webp','bmp','svg'];
5138                const videoExts = ['mp4','webm','ogg','mov','m4v'];
5139
5140                let ft = '';
5141                try {
5142                    const u = new URL(url);
5143                    ft = (u.searchParams.get('filetype') || '').toLowerCase();
5144                } catch (e) {
5145                    const qs = url.split('?')[1] || '';
5146                    const match = qs.match(/(?:^|&)filetype=([^&]+)/i);
5147                    ft = match ? decodeURIComponent(match[1]).toLowerCase() : '';
5148                }
5149                if (imageExts.includes(ft)) return 'image';
5150                if (videoExts.includes(ft)) return 'video';
5151
5152                // 3) give up
5153                return 'other';
5154            }
5155
5156            if (message.files.length > 0) {
5157                const temp2 = document.createElement('div');
5158                temp2.innerHTML = `
5159                    <div data-message-id="${messageKey}" data-message-sent="${message.send_time ?? ''}"${isTemp ? ` data-is-temp="${isTemp}"` : ''} class="DLP_Hide_Scrollbar" style="display: flex; align-items: center; gap: 8px; align-self: stretch; width: 100%; overflow-y: scroll; opacity: 1; filter: blur(0px); margin-top: 0px; transition: 0.4s cubic-bezier(0.16, 1, 0.32, 1);${failedTemp ? ' color: rgba(var(--DLP-pink));' : ''}"></div>
5160                `;
5161                const newElement2 = temp2.firstElementChild;
5162                lastChatChild.appendChild(newElement2);
5163                let attachmentParent = lastChatChild.lastElementChild;
5164                for (let i = 0; i < message.files.length; i++) {
5165                    const file = message.files[i];
5166                    const temp = document.createElement('div');
5167                    let extensionType = await contentType(file);
5168                    if (extensionType === 'image') {
5169                        temp.innerHTML = `
5170                            <div class="DLP_Attachment_Box_1" data-preview-src="${file}">
5171                                <img class="DLP_Attachment_Box_1_Content" src="${file}">
5172                                <div class="DLP_Attachment_Box_1_Hover" style="display: none;">
5173                                    <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect">􂅆</p>
5174                                </div>
5175                            </div>
5176                        `;
5177                    } else if (extensionType === 'video') {
5178                        temp.innerHTML = `
5179                            <div class="DLP_Attachment_Box_1" data-preview-src="${file}">
5180                                <video class="DLP_Attachment_Box_1_Content" src="${file}" muted autoplay loop></video>
5181                                <div class="DLP_Attachment_Box_1_Hover" style="display: none;">
5182                                    <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect">􂅆</p>
5183                                </div>
5184                            </div>
5185                        `;
5186                    } else {
5187                        temp.innerHTML = `
5188                            <div class="DLP_Attachment_Box_1" data-preview-src="${file}">
5189                                <div style="display: flex; width: 100%; height: 100%; padding-top: 6px; flex-direction: column; justify-content: center; align-items: center; gap: 6px; flex-shrink: 0;">
5190                                    <p class="DLP_Text_Style_1 DLP_NoSelect" style="font-size: 24px;">􀈸</p>
5191                                    <p class="DLP_Text_Style_1 DLP_NoSelect">File</p>
5192                                </div>
5193                                <div class="DLP_Attachment_Box_1_Hover" style="display: none;">
5194                                    <p class="DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect">􀄉</p>
5195                                </div>
5196                            </div>
5197                        `;
5198                    }
5199                    const newElement = temp.firstElementChild;
5200                    attachmentParent.appendChild(newElement);
5201
5202                    expandAttachment(newElement);
5203                }
5204            }
5205        }
5206
5207        const sameAuthor = lastChatChild !== null && message.author === lastChatChild.getAttribute('data-author-name');
5208        const messageHasReply = hasNumericReply(message);
5209
5210        if (sameAuthor && !messageHasReply) {
5211            createContinuationMessage(message);
5212        } else {
5213            createStartersMessage(message);
5214        }
5215    }
5216
5217    async function intelligentLeaderboardBasedWarningLimit() {
5218        const defaultBoardId = "7d9f5dd1-8423-491a-91f2-2532052038ce";
5219        const tournamentBoardId = "4b668ba6-288d-4b78-81a3-7b213175ae2c";
5220        const baseUrl = "https://duolingo-leaderboards-prod.duolingo.com/leaderboards/";
5221
5222        function getDuolingoUserIdFromJwt(token) {
5223            try {
5224                const p = token.split('.')[1];
5225                const decoded = decodeURIComponent(atob(p.replace(/-/g, '+').replace(/_/g, '/').padEnd(p.length + (4 - p.length % 4) % 4, '=')).split('').map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)).join(''));
5226                return JSON.parse(decoded).sub;
5227            } catch (e) {
5228                console.error("Failed to decode JWT:", e);
5229                return null;
5230            }
5231        }
5232
5233        function processLeaderboardData(data, userId) {
5234            if (!data || !data.active || !data.active.cohort || !data.active.cohort.rankings) {
5235                console.log("Chosen leaderboard data is invalid or inactive.");
5236                return null;
5237            }
5238
5239            const rankings = data.active.cohort.rankings;
5240            const topN = 5;
5241            const topScores = [...rankings].sort((a, b) => b.score - a.score).slice(0, topN).map(user => user.score);
5242
5243            const userRanking = rankings.find(u => u.user_id === userId);
5244            const userScore = userRanking ? userRanking.score : 0;
5245            const avgTopScore = topScores.length ? Math.round(topScores.reduce((sum, val) => sum + val, 0) / topScores.length) : 0;
5246
5247            const intelligentAmount = Math.max(0, avgTopScore - userScore);
5248
5249            console.log(`Using leaderboard: ${data.active.contest.contest_id}`);
5250            console.log(`Average top ${topN} score:`, avgTopScore);
5251            console.log(`Your score:`, userScore);
5252            console.log(`Calculated intelligent warning limit:`, intelligentAmount);
5253
5254            return intelligentAmount;
5255        }
5256
5257        const jwtToken = document.cookie.split('; ').find(cookie => cookie.startsWith('jwt_token='))?.split('=')[1];
5258        if (!jwtToken) {
5259            console.error("JWT token not found. Cannot proceed.");
5260            return null;
5261        }
5262
5263        const userID = getDuolingoUserIdFromJwt(jwtToken);
5264        if (!userID) {
5265            console.error("Could not extract User ID from JWT.");
5266            return null;
5267        }
5268
5269        const spedTimestamp = Date.now();
5270        const fetchOptions = {
5271            method: 'GET',
5272            headers: {
5273                'Content-Type': 'application/json',
5274                'Authorization': `Bearer ${jwtToken}`,
5275            },
5276        };
5277
5278        try {
5279            const [tournamentResult, defaultResult] = await Promise.allSettled([
5280                fetch(`${baseUrl}${tournamentBoardId}/users/${userID}?_=${spedTimestamp}`, fetchOptions).then(res => res.json()),
5281                fetch(`${baseUrl}${defaultBoardId}/users/${userID}?_=${spedTimestamp}`, fetchOptions).then(res => res.json()),
5282            ]);
5283
5284            let selectedData = null;
5285
5286            if (tournamentResult.status === 'fulfilled' && tournamentResult.value.active) {
5287                console.log("Tournament leaderboard is active. Using it for calculation.");
5288                selectedData = tournamentResult.value;
5289            } else if (defaultResult.status === 'fulfilled' && defaultResult.value.active) {
5290                console.log("Default leaderboard is active. Using it for calculation.");
5291                selectedData = defaultResult.value;
5292            } else {
5293                console.log("No active leaderboards found (neither tournament nor default).");
5294                if (tournamentResult.status === 'rejected') console.error("Tournament fetch failed:", tournamentResult.reason);
5295                if (defaultResult.status === 'rejected') console.error("Default fetch failed:", defaultResult.reason);
5296                return null;
5297            }
5298
5299            const intelligentAmount = processLeaderboardData(selectedData, userID);
5300            // return intelligentAmount ?? null;
5301            return 20;
5302        } catch (error) {
5303            console.error("An unexpected error occurred during the fetch process:", error);
5304            return null;
5305        }
5306    }
5307
5308    function updateReleaseNotes(warnings) {
5309        const releaseNotesContainer = document.getElementById('DLP_Release_Notes_List_1_ID');
5310        const controlsContainer = document.getElementById('DLP_Release_Notes_Controls');
5311        const warningCounterDisplay = controlsContainer.querySelector('.DLP_Inset_Text_1_ID');
5312        const prevButton = controlsContainer.querySelector('.DLP_Inset_Icon_1_ID');
5313        const nextButton = controlsContainer.querySelector('.DLP_Inset_Icon_2_ID');
5314
5315        releaseNotesContainer.innerHTML = '';
5316
5317        let currentWarningIndex = 0;
5318        const totalWarnings = warnings.length;
5319
5320        function updateCounterDisplay(current, total, displayElement) {
5321            displayElement.textContent = `${current}/${total}`;
5322        }
5323
5324        function updateButtonOpacity(current, total, prevButton, nextButton) {
5325            if (current === 0) {
5326                prevButton.style.opacity = '0.5';
5327                prevButton.style.pointerEvents = 'none';
5328            } else {
5329                prevButton.style.opacity = '1';
5330                prevButton.style.pointerEvents = 'auto';
5331            }
5332
5333            if (current === total - 1) {
5334                nextButton.style.opacity = '0.5';
5335                nextButton.style.pointerEvents = 'none';
5336            } else {
5337                nextButton.style.opacity = '1';
5338                nextButton.style.pointerEvents = 'auto';
5339            }
5340        }
5341
5342        warnings.forEach((warning, index) => {
5343            if (warning.head && warning.body && warning.icon) {
5344                const warningHTML = `
5345                <div id="warning-${index}" style="display: ${index === 0 ? 'flex' : 'none'}; flex-direction: column; justify-content: center; align-items: center; gap: 8px; align-self: stretch; transition: filter 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);">
5346                    <div style="display: flex; flex-direction: column; align-items: center; gap: 4px;">
5347                        ${warning.icon}
5348                        <p class="DLP_Text_Style_2">${warning.head}</p>
5349                        <p class="DLP_Text_Style_1" style="background: url(${serverURL}/static/images/flow/secondary/512/light.png) lightgray 50% / cover no-repeat; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;">${warning.tag}</p>
5350                    </div>
5351                    <p class="DLP_Text_Style_1" style="text-align: center;">${warning.body}</p>
5352                </div>
5353                `;
5354                releaseNotesContainer.insertAdjacentHTML('beforeend', warningHTML);
5355            }
5356        });
5357
5358        updateCounterDisplay(currentWarningIndex + 1, totalWarnings, warningCounterDisplay);
5359        updateButtonOpacity(currentWarningIndex, totalWarnings, prevButton, nextButton);
5360
5361        prevButton.addEventListener('click', () => {
5362            if (isBusySwitchingPages) return;
5363            isBusySwitchingPages = true;
5364            if (currentWarningIndex > 0) {
5365                const oldWarning = document.getElementById(`warning-${currentWarningIndex}`);
5366                const newWarning = document.getElementById(`warning-${currentWarningIndex - 1}`);
5367
5368                oldWarning.style.filter = 'blur(16px)';
5369                oldWarning.style.opacity = '0';
5370                newWarning.style.filter = 'blur(16px)';
5371                newWarning.style.opacity = '0';
5372
5373                setTimeout(() => {
5374                    oldWarning.style.display = 'none';
5375                    newWarning.style.display = 'flex';
5376                    newWarning.offsetHeight;
5377                    newWarning.style.filter = 'blur(0px)';
5378                    newWarning.style.opacity = '1';
5379                    currentWarningIndex--;
5380                    updateCounterDisplay(currentWarningIndex + 1, totalWarnings, warningCounterDisplay);
5381                    updateButtonOpacity(currentWarningIndex, totalWarnings, prevButton, nextButton);
5382                    setTimeout(() => {
5383                        isBusySwitchingPages = false;
5384                    }, 400);
5385                }, 400);
5386            }
5387        });
5388
5389        nextButton.addEventListener('click', () => {
5390            if (isBusySwitchingPages) return;
5391            isBusySwitchingPages = true;
5392            if (currentWarningIndex < totalWarnings - 1) {
5393                const oldWarning = document.getElementById(`warning-${currentWarningIndex}`);
5394                const newWarning = document.getElementById(`warning-${currentWarningIndex + 1}`);
5395                oldWarning.style.filter = 'blur(16px)';
5396                oldWarning.style.opacity = '0';
5397                newWarning.style.filter = 'blur(16px)';
5398                newWarning.style.opacity = '0';
5399
5400                setTimeout(() => {
5401                    oldWarning.style.display = 'none';
5402                    newWarning.style.display = 'flex';
5403                    newWarning.offsetHeight;
5404                    newWarning.style.filter = 'blur(0px)';
5405                    newWarning.style.opacity = '1';
5406                    currentWarningIndex++;
5407                    updateCounterDisplay(currentWarningIndex + 1, totalWarnings, warningCounterDisplay);
5408                    updateButtonOpacity(currentWarningIndex, totalWarnings, prevButton, nextButton);
5409                    setTimeout(() => {
5410                        isBusySwitchingPages = false;
5411                    }, 400);
5412                }, 400);
5413            }
5414        });
5415    }
5416
5417    let DLP_Feedback_Text_Input_1_ID = document.getElementById("DLP_Feedback_Text_Input_1_ID");
5418    let DLP_Feedback_Type_Bug_Report_Button_1_ID = document.getElementById("DLP_Feedback_Type_Bug_Report_Button_1_ID");
5419    let DLP_Feedback_Type_Suggestion_Button_1_ID = document.getElementById("DLP_Feedback_Type_Suggestion_Button_1_ID");
5420    let DLP_Feedback_Attachment_Upload_Button_1_ID = document.getElementById("DLP_Feedback_Attachment_Upload_Button_1_ID");
5421    let DLP_Feedback_Attachment_Input_Hidden_1_ID = document.getElementById("DLP_Feedback_Attachment_Input_Hidden_1_ID");
5422    let DLP_Feedback_Send_Button_1_ID = document.getElementById("DLP_Feedback_Send_Button_1_ID");
5423
5424    let sendFeedbackStatus = '';
5425    DLP_Feedback_Send_Button_1_ID.addEventListener('click', () => {
5426        if (sendFeedbackStatus !== '') return;
5427        let FeedbackText = DLP_Feedback_Text_Input_1_ID.value;
5428        sendFeedbackServer(feedbackType, FeedbackText);
5429
5430        setButtonState(DLP_Feedback_Send_Button_1_ID, {button: 'linear-gradient(0deg, rgba(var(--DLP-blue), 0.10) 0%, rgba(var(--DLP-blue), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))'}, {text: systemText[systemLanguage][111], icon: '􀓞'}, {text: '', icon: 'DLP_Rotate_360_Animation_1 4s ease-in-out infinite'}, () => {
5431            function f() {
5432                if (sendFeedbackStatus === 'sent') {
5433                    setButtonState(DLP_Feedback_Send_Button_1_ID, {button: 'linear-gradient(0deg, rgba(var(--DLP-green), 0.10) 0%, rgba(var(--DLP-green), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-green), 0.20)', text: 'rgb(var(--DLP-green))', icon: 'rgb(var(--DLP-green))'}, {text: systemText[systemLanguage][112], icon: '􀁣'}, {text: '', icon: ' '}, () => {
5434                        confetti();
5435                    });
5436                } else if (sendFeedbackStatus === 'error') {
5437                    setButtonState(DLP_Feedback_Send_Button_1_ID, {button: 'linear-gradient(0deg, rgba(var(--DLP-pink), 0.10) 0%, rgba(var(--DLP-pink), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-pink), 0.20)', text: 'rgb(var(--DLP-pink))', icon: 'rgb(var(--DLP-pink))'}, {text: systemText[systemLanguage][115], icon: '􀇿'}, {text: '', icon: ' '}, () => {
5438                    });
5439                } else if (sendFeedbackStatus === 'sending') {
5440                    setTimeout(() => { f(); }, 800);
5441                }
5442            }
5443            f();
5444        });
5445    });
5446
5447    let feedbackType = 'Suggestion';
5448    DLP_Feedback_Type_Bug_Report_Button_1_ID.addEventListener('click', () => {
5449        feedbackType = 'Bug Report';
5450        DLP_Feedback_Type_Bug_Report_Button_1_ID.classList.add('DLP_Feedback_Type_Button_Style_1_ON');
5451        DLP_Feedback_Type_Bug_Report_Button_1_ID.classList.remove('DLP_Feedback_Type_Button_Style_1_OFF');
5452        DLP_Feedback_Type_Suggestion_Button_1_ID.classList.add('DLP_Feedback_Type_Button_Style_2_OFF');
5453        DLP_Feedback_Type_Suggestion_Button_1_ID.classList.remove('DLP_Feedback_Type_Button_Style_2_ON');
5454    });
5455    DLP_Feedback_Type_Suggestion_Button_1_ID.addEventListener('click', () => {
5456        feedbackType = 'Suggestion';
5457        DLP_Feedback_Type_Bug_Report_Button_1_ID.classList.add('DLP_Feedback_Type_Button_Style_1_OFF');
5458        DLP_Feedback_Type_Bug_Report_Button_1_ID.classList.remove('DLP_Feedback_Type_Button_Style_1_ON');
5459        DLP_Feedback_Type_Suggestion_Button_1_ID.classList.add('DLP_Feedback_Type_Button_Style_2_ON');
5460        DLP_Feedback_Type_Suggestion_Button_1_ID.classList.remove('DLP_Feedback_Type_Button_Style_2_OFF');
5461    });
5462    let currentFileName = '';
5463    setInterval(() => {
5464        if (DLP_Feedback_Attachment_Input_Hidden_1_ID.files.length > 0) {
5465            let fileName = DLP_Feedback_Attachment_Input_Hidden_1_ID.files[0].name;
5466            if (currentFileName === fileName) return;
5467            currentFileName = fileName;
5468            DLP_Feedback_Attachment_Upload_Button_1_ID.querySelector('.DLP_Inset_Text_1_ID').style.filter = 'blur(4px)';
5469            DLP_Feedback_Attachment_Upload_Button_1_ID.querySelector('.DLP_Inset_Text_1_ID').style.opacity = '0';
5470            DLP_Feedback_Attachment_Upload_Button_1_ID.querySelector('.DLP_Inset_Icon_1_ID').style.filter = 'blur(4px)';
5471            DLP_Feedback_Attachment_Upload_Button_1_ID.querySelector('.DLP_Inset_Icon_1_ID').style.opacity = '0';
5472            DLP_Feedback_Attachment_Upload_Button_1_ID.style.background = 'rgb(var(--DLP-blue))';
5473            DLP_Feedback_Attachment_Upload_Button_1_ID.style.outline = '2px solid rgba(0, 0, 0, 0.20)';
5474            setTimeout(() => {
5475                DLP_Feedback_Attachment_Upload_Button_1_ID.querySelector('.DLP_Inset_Icon_1_ID').style.display = 'none';
5476                DLP_Feedback_Attachment_Upload_Button_1_ID.querySelector('.DLP_Inset_Text_1_ID').textContent = fileName;
5477                DLP_Feedback_Attachment_Upload_Button_1_ID.querySelector('.DLP_Inset_Text_1_ID').style.color = '#FFF';
5478                DLP_Feedback_Attachment_Upload_Button_1_ID.querySelector('.DLP_Inset_Text_1_ID').style.filter = '';
5479                DLP_Feedback_Attachment_Upload_Button_1_ID.querySelector('.DLP_Inset_Text_1_ID').style.opacity = '';
5480            }, 400);
5481        }
5482    }, 1000);
5483    DLP_Feedback_Attachment_Upload_Button_1_ID.addEventListener('click', () => {
5484        DLP_Feedback_Attachment_Input_Hidden_1_ID.click();
5485    });
5486
5487    DLP_Feedback_Send_Button_1_ID.style.pointerEvents = 'none';
5488    DLP_Feedback_Send_Button_1_ID.style.opacity = '0.5';
5489    DLP_Feedback_Text_Input_1_ID.addEventListener("input", function () {
5490        if (DLP_Feedback_Text_Input_1_ID.value.replace(/\s/g, "").length <= 16) {
5491            DLP_Feedback_Send_Button_1_ID.style.pointerEvents = 'none';
5492            DLP_Feedback_Send_Button_1_ID.style.opacity = '0.5';
5493        } else {
5494            DLP_Feedback_Send_Button_1_ID.style.pointerEvents = '';
5495            DLP_Feedback_Send_Button_1_ID.style.opacity = '';
5496        }
5497    });
5498    async function sendFeedbackServer(head, body) {
5499        try {
5500            sendFeedbackStatus = 'sending';
5501
5502            let payload = {
5503                head: head,
5504                body: body,
5505                version: versionFormal
5506            };
5507
5508            if (DLP_Feedback_Attachment_Input_Hidden_1_ID.files.length > 0) {
5509                const file = DLP_Feedback_Attachment_Input_Hidden_1_ID.files[0];
5510                const base64File = await new Promise((resolve) => {
5511                    const reader = new FileReader();
5512                    reader.onloadend = () => {
5513                        resolve(reader.result);
5514                    };
5515                    reader.readAsDataURL(file);
5516                });
5517                payload.file = base64File;
5518            }
5519
5520            const response = await fetch(apiURL + "/feedback", {
5521                method: 'POST',
5522                headers: {
5523                    'Content-Type': 'application/json',
5524                    'Authorization': `Bearer ${document.cookie.split(';').find(cookie => cookie.includes('jwt_token')).split('=')[1]}`
5525                },
5526                body: JSON.stringify(payload)
5527            });
5528
5529            const responseData = await response.json();
5530
5531            if (responseData.status) sendFeedbackStatus = 'sent';
5532            else sendFeedbackStatus = 'error';
5533
5534            showNotification(responseData.notification.icon, responseData.notification.head, responseData.notification.body, responseData.notification.duration);
5535        } catch (error) {
5536            console.error('Error:', error);
5537            sendFeedbackStatus = 'error';
5538            showNotification("error", systemText[systemLanguage][206], systemText[systemLanguage][207], 30);
5539        }
5540    }
5541
5542
5543    async function handleClick(button, id, amount) {
5544        const ANIM_MS = 820;
5545        let status = 'loading';
5546
5547        const loadingStart = Date.now();
5548        setButtonState(
5549            button,
5550            { button: 'rgba(var(--DLP-blue), 0.10)', outline: 'rgba(var(--DLP-blue), 0.20)', text: 'rgb(var(--DLP-blue))', icon: 'rgb(var(--DLP-blue))' },
5551            { text: systemText[systemLanguage][113], icon: '􀓞' },
5552            { text: '', icon: 'DLP_Rotate_360_Animation_1 4s ease-in-out infinite' }
5553        );
5554        let nextAnimationEndsAt = loadingStart + ANIM_MS;
5555
5556        setTimeout(() => { f(); }, Math.max(0, nextAnimationEndsAt - Date.now()));
5557
5558        try {
5559            if (flag03) {
5560                const intelligentAmount = await intelligentLeaderboardBasedWarningLimit();
5561                console.log(`Intelligent amount: ${intelligentAmount}`);
5562
5563                const overrideXp = button.dataset.overrideXp === 'true';
5564                if (id === 'xp' && amount > intelligentAmount && !overrideXp) {
5565                    button.dataset.overrideXp = 'true';
5566
5567                    showNotification(
5568                        'warning',
5569                        'That is a lot of XP...',
5570                        `You're about to gain more XP than recommended. Click CONFIRM to continue.`,
5571                        10
5572                    );
5573
5574                    const elapsed = Date.now() - loadingStart;
5575                    const delay = Math.max(0, ANIM_MS - elapsed);
5576                    setTimeout(() => {
5577                        setButtonState(
5578                            button,
5579                            { button: 'rgb(var(--DLP-blue))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF' },
5580                            { text: 'CONFIRM', icon: '􀰫' },
5581                            { text: '', icon: '' }
5582                        );
5583                        nextAnimationEndsAt = Date.now() + ANIM_MS;
5584                    }, delay);
5585
5586                    // Keep status 'loading' so the poller waits until the user confirms or cancels
5587                    return;
5588                }
5589
5590                // Reset the override flag when actually proceeding
5591                button.dataset.overrideXp = 'false';
5592            }
5593
5594            const response = await fetch(apiURL + '/request', {
5595                method: 'POST',
5596                headers: {
5597                    'Content-Type': 'application/json',
5598                    'Authorization': `Bearer ${document.cookie.split(';').find(cookie => cookie.includes('jwt_token')).split('=')[1]}`
5599                },
5600                body: JSON.stringify({ type: id, amount, version: versionFull })
5601            });
5602
5603            if (!response.ok) throw new Error('Request failed with status ' + response.status);
5604
5605            const reader = response.body.getReader();
5606            const decoder = new TextDecoder();
5607            let done = false;
5608            let buffer = '';
5609
5610            while (!done) {
5611                const { value, done: doneReading } = await reader.read();
5612                done = doneReading;
5613                buffer += decoder.decode(value, { stream: true });
5614
5615                let openBraces = 0;
5616                let start = 0;
5617
5618                for (let i = 0; i < buffer.length; i++) {
5619                    const ch = buffer[i];
5620
5621                    if (ch === '{') {
5622                        openBraces++;
5623                    } else if (ch === '}') {
5624                        openBraces--;
5625
5626                        if (openBraces === 0) {
5627                            const jsonStr = buffer.substring(start, i + 1).trim();
5628
5629                            try {
5630                                const data = JSON.parse(jsonStr);
5631
5632                                if (data.status === 'completed') {
5633                                    status = 'done';
5634                                    done = true;
5635                                    showNotification(data.notification.icon, data.notification.head, data.notification.body, data.notification.duration);
5636
5637                                    if (storageLocal.stats.tracking_since === 0) storageLocal.stats.tracking_since = Date.now();
5638                                    storageLocal.stats.modern[id] += amount;
5639                                    saveStorageLocal();
5640
5641                                    const input = button.parentElement.querySelector('#DLP_Inset_Input_1_ID');
5642                                    if (input) {
5643                                        input.value = '';
5644                                        setTimeout(() => input.dispatchEvent(new Event('input')), 2400);
5645                                    }
5646                                } else if (data.status == 'failed') {
5647                                    status = 'error';
5648                                    done = true;
5649                                    showNotification(data.notification.icon, data.notification.head, data.notification.body, data.notification.duration);
5650                                    console.log(data);
5651                                } else if (data.status === 'rejected') {
5652                                    status = 'rejected';
5653                                    done = true;
5654                                    showNotification(data.notification.icon, data.notification.head, data.notification.body, data.notification.duration);
5655
5656                                    const input = button.parentElement.querySelector('#DLP_Inset_Input_1_ID');
5657                                    if (data.max_amount && input) {
5658                                        input.value = data.max_amount;
5659                                        setTimeout(() => input.dispatchEvent(new Event('input')), 2400);
5660                                    }
5661                                } else {
5662                                    console.log(`Percentage: ${data.percentage}%`);
5663                                    button.querySelector('.DLP_Inset_Text_1_ID').innerHTML = data.percentage + '%';
5664                                }
5665
5666                                // Trim processed chunk and reset counters
5667                                buffer = buffer.substring(i + 1);
5668                                i = -1;
5669                                start = 0;
5670                                openBraces = 0;
5671                            } catch (e) {
5672                                // ignore and continue streaming
5673                            }
5674                        }
5675                    } else if (openBraces === 0 && buffer[i].trim() !== '') {
5676                        start = i;
5677                    }
5678                }
5679            }
5680        } catch (error) {
5681            console.error('Error during request:', error);
5682            status = 'error';
5683        }
5684
5685        function f() {
5686            const now = Date.now();
5687
5688            // If an animation is still running, wait precisely until it ends
5689            if (now < nextAnimationEndsAt) {
5690                setTimeout(() => { f(); }, nextAnimationEndsAt - now);
5691                return;
5692            }
5693
5694            if (status === 'done') {
5695                setButtonState(
5696                    button,
5697                    { button: 'rgba(var(--DLP-green), 0.10)', outline: 'rgba(var(--DLP-green), 0.20)', text: 'rgb(var(--DLP-green))', icon: 'rgb(var(--DLP-green))' },
5698                    { text: systemText[systemLanguage][114], icon: '􀁣' },
5699                    { text: '', icon: '' }
5700                );
5701                nextAnimationEndsAt = Date.now() + ANIM_MS;
5702
5703                confetti();
5704                setTimeout(() => {
5705                    let buttonContentText = systemText[systemLanguage][9];
5706                    if (id === 'super' || id === 'double_xp_boost') buttonContentText = systemText[systemLanguage][13];
5707                    else if (id === 'heart_refill') buttonContentText = systemText[systemLanguage][229];
5708                    setButtonState(
5709                        button,
5710                        { button: 'rgb(var(--DLP-blue))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF' },
5711                        { text: buttonContentText, icon: '􀰫' },
5712                        { text: '', icon: '' }
5713                    );
5714                    nextAnimationEndsAt = Date.now() + ANIM_MS;
5715
5716                    setTimeout(() => { isGetButtonsBusy = false; }, ANIM_MS);
5717                }, (ANIM_MS * 2));
5718
5719            } else if (status === 'error') {
5720                setButtonState(
5721                    button,
5722                    { button: 'rgb(var(--DLP-pink))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF' },
5723                    { text: systemText[systemLanguage][115], icon: '􀇿' },
5724                    { text: '', icon: '' }
5725                );
5726                nextAnimationEndsAt = Date.now() + ANIM_MS;
5727
5728                setTimeout(() => {
5729                    setButtonState(
5730                        button,
5731                        { button: 'rgb(var(--DLP-blue))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF' },
5732                        { text: systemText[systemLanguage][9], icon: '􀰫' },
5733                        { text: '', icon: '' }
5734                    );
5735                    nextAnimationEndsAt = Date.now() + ANIM_MS;
5736
5737                    setTimeout(() => { isGetButtonsBusy = false; }, ANIM_MS);
5738                }, (ANIM_MS * 2));
5739
5740            } else if (status === 'rejected') {
5741                setButtonState(
5742                    button,
5743                    { button: 'rgb(var(--DLP-blue))', outline: 'rgba(0, 0, 0, 0.20)', text: '#FFF', icon: '#FFF' },
5744                    { text: systemText[systemLanguage][9], icon: '􀰫' },
5745                    { text: '', icon: '' }
5746                );
5747                nextAnimationEndsAt = Date.now() + ANIM_MS;
5748
5749                setTimeout(() => { isGetButtonsBusy = false; }, ANIM_MS);
5750
5751            } else {
5752                // Still waiting for async work or user confirmation; check again after any new animation
5753                setTimeout(() => { f(); }, ANIM_MS);
5754            }
5755        }
5756    }
5757
5758    const getButtonsList1 = [
5759        { base: 'DLP_Get_XP', type: 'xp', input: true },
5760        { base: 'DLP_Get_GEM', type: 'gem', input: true },
5761        { base: 'DLP_Get_Streak', type: 'streak', input: true },
5762        { base: 'DLP_Get_SUPER', type: 'super' },
5763        { base: 'DLP_Get_DOUBLE_XP_BOOST', type: 'double_xp_boost' },
5764        { base: 'DLP_Get_Streak_Freeze', type: 'streak_freeze', input: true },
5765        { base: 'DLP_Get_Heart_Refill', type: 'heart_refill' }
5766    ];
5767    function setupGetButtons(base, type, hasInput) {
5768        [1, 2].forEach(n => {
5769            const parent = document.getElementById(`${base}_${n}_ID`);
5770            if (!parent) return;
5771
5772            const button = parent.querySelector('#DLP_Inset_Button_1_ID');
5773            const handler = () => {
5774                if (isGetButtonsBusy && !(type === 'xp' && button.dataset.overrideXp === 'true')) return;
5775                isGetButtonsBusy = true;
5776                handleClick(button, type, hasInput ? Number(parent.querySelector('#DLP_Inset_Input_1_ID').value) : 1);
5777            };
5778
5779            button.addEventListener('click', handler);
5780
5781            if (hasInput) {
5782                const input = parent.querySelector('#DLP_Inset_Input_1_ID');
5783                input.onkeyup = e => e.keyCode === 13 && handler();
5784            }
5785        });
5786    };
5787    getButtonsList1.forEach(({ base, type, input }) => setupGetButtons(base, type, input));
5788
5789
5790    let DLP_Settings_Save_Button_1_ID = document.getElementById("DLP_Settings_Save_Button_1_ID");
5791    DLP_Settings_Save_Button_1_ID.addEventListener('click', () => {
5792        if (isBusySwitchingPages) return;
5793        isBusySwitchingPages = true;
5794        storageLocal.settings.autoUpdate = DLP_Settings_Var.autoUpdate;
5795        storageLocal.settings.showAutoServerButton = DLP_Settings_Var.showAutoServerButton;
5796        storageLocal.settings.showSolveButtons = DLP_Settings_Var.showSolveButtons;
5797        storageLocal.settings.anonymousUsageData = DLP_Settings_Var.anonymousUsageData;
5798        storageLocal.settings.solveSpeed = Number(settingsLegacySolveSpeedInputSanitizeValue(DLP_Settings_Legacy_Solve_Speed_1_ID.querySelector('#DLP_Inset_Input_1_ID').value, true));
5799        saveStorageLocal();
5800        setButtonState(DLP_Settings_Save_Button_1_ID, {button: 'linear-gradient(0deg, rgba(var(--DLP-green), 0.10) 0%, rgba(var(--DLP-green), 0.10) 100%), rgba(var(--color-snow), 0.80)', outline: 'rgba(var(--DLP-green), 0.20)', text: 'rgb(var(--DLP-green))', icon: 'rgb(var(--DLP-green))'}, {text: systemText[systemLanguage][116], icon: ''}, {text: '', icon: ' '}, () => {
5801            //confetti();
5802            setTimeout(() => {
5803                //goToPage(-1);
5804                location.reload();
5805            }, 1600);
5806            //setTimeout(() => {
5807            //    setButtonState(DLP_Settings_Save_Button_1_ID, systemText[systemLanguage][37], DLP_Settings_Save_Button_1_ID.querySelector('#DLP_Inset_Icon_1_ID'), DLP_Settings_Save_Button_1_ID.querySelector('#DLP_Inset_Icon_3_ID'), 'rgb(var(--DLP-blue))', '2px solid rgba(0, 0, 0, 0.20)', '#FFF', 400);
5808            //    isBusySwitchingPages = false;
5809            //}, 2400);
5810        });
5811    });
5812
5813    let DLP_Settings_Var = {
5814        autoUpdate: storageLocal.settings.autoUpdate,
5815        showAutoServerButton: storageLocal.settings.showAutoServerButton,
5816        showSolveButtons: storageLocal.settings.showSolveButtons,
5817        solveSpeed: storageLocal.settings.solveSpeed,
5818        anonymousUsageData: storageLocal.settings.anonymousUsageData
5819    };
5820    let DLP_Settings_Toggle_Busy = false;
5821    let DLP_Settings_Show_Solve_Buttons_1_ID = document.getElementById("DLP_Settings_Show_Solve_Buttons_1_ID");
5822    let DLP_Settings_Show_AutoServer_Button_1_ID = document.getElementById("DLP_Settings_Show_AutoServer_Button_1_ID");
5823    let DLP_Settings_Legacy_Solve_Speed_1_ID = document.getElementById("DLP_Settings_Legacy_Solve_Speed_1_ID");
5824    let DLP_Settings_Help_Us_Make_Better_Button_1_ID = document.getElementById("DLP_Settings_Help_Us_Make_Better_Button_1_ID");
5825    let DLP_Settings_Auto_Update_Toggle_1_ID = document.getElementById("DLP_Settings_Auto_Update_Toggle_1_ID");
5826
5827    handleToggleClick(DLP_Settings_Show_Solve_Buttons_1_ID.querySelector('#DLP_Inset_Toggle_1_ID'), DLP_Settings_Var.showSolveButtons);
5828    if (alpha) handleToggleClick(DLP_Settings_Show_AutoServer_Button_1_ID.querySelector('#DLP_Inset_Toggle_1_ID'), DLP_Settings_Var.showAutoServerButton);
5829    else DLP_Settings_Show_AutoServer_Button_1_ID.remove();
5830    handleToggleClick(DLP_Settings_Auto_Update_Toggle_1_ID.querySelector('#DLP_Inset_Toggle_1_ID'), DLP_Settings_Var.autoUpdate);
5831    handleToggleClick(DLP_Settings_Help_Us_Make_Better_Button_1_ID.querySelector('#DLP_Inset_Toggle_1_ID'), DLP_Settings_Var.anonymousUsageData);
5832    DLP_Settings_Legacy_Solve_Speed_1_ID.querySelector('#DLP_Inset_Input_1_ID').value = DLP_Settings_Var.solveSpeed;
5833
5834    DLP_Settings_Legacy_Solve_Speed_1_ID.querySelector('#DLP_Inset_Input_1_ID').addEventListener("input", function () {
5835        this.value = settingsLegacySolveSpeedInputSanitizeValue(this.value, false);
5836    });
5837    DLP_Settings_Legacy_Solve_Speed_1_ID.querySelector('#DLP_Inset_Input_1_ID').addEventListener("blur", function () {
5838        this.value = settingsLegacySolveSpeedInputSanitizeValue(this.value, true);
5839        DLP_Settings_Var.solveSpeed = Number(this.value);
5840    });
5841
5842    function settingsLegacySolveSpeedInputSanitizeValue(value, completeSanitization) {
5843        value = value.replace(/[^0-9.,]/g, '');
5844        let match = value.match(/[.,]/g);
5845        if (match && match.length > 1) {
5846            value = value.slice(0, value.lastIndexOf(match[match.length - 1]));
5847        }
5848        let decimalIndex = value.indexOf('.');
5849        if (decimalIndex !== -1) {
5850            value = value.slice(0, decimalIndex + 3);
5851        }
5852        let digitCount = value.replace(/[^0-9]/g, '').length;
5853        if (digitCount > 3) {
5854            value = value.replace(/(\d{3})\d+/, '$1');
5855        }
5856        if (/^0\d/.test(value) && !value.startsWith("0.")) {
5857            value = value.replace(/^0+/, '0');
5858        }
5859
5860        if (!completeSanitization) return value;
5861
5862        value = value.replace(',', '.');
5863        value = parseFloat(value);
5864        if (!isNaN(value)) {
5865            if (value < 0.6) value = 0.6;
5866        } else {
5867            value = 0.8;
5868        }
5869        return value;
5870    }
5871
5872
5873    function handleToggleClick(button, state) {
5874        try {
5875            let iconToChange = button.querySelector(".DLP_Inset_Icon_1_ID");
5876            iconToChange.style.transition = '0.4s';
5877
5878            void button.offsetWidth;
5879            iconToChange.style.filter = 'blur(4px)';
5880            iconToChange.style.opacity = '0';
5881
5882            if (state) {
5883                button.classList.add('DLP_Toggle_Style_1_ON');
5884                button.classList.remove('DLP_Toggle_Style_1_OFF');
5885            } else {
5886                button.classList.add('DLP_Toggle_Style_1_OFF');
5887                button.classList.remove('DLP_Toggle_Style_1_ON');
5888            }
5889
5890            setTimeout(() => {
5891                iconToChange.textContent = state ? '􀁣' : '􀁡';
5892
5893                void button.offsetWidth;
5894                iconToChange.style.filter = 'blur(0px)';
5895                iconToChange.style.opacity = '1';
5896            }, 400);
5897        } catch (e) {
5898            console.error(e);
5899        }
5900    }
5901    DLP_Settings_Auto_Update_Toggle_1_ID.querySelector('#DLP_Inset_Toggle_1_ID').addEventListener('click', () => {
5902        if (DLP_Settings_Toggle_Busy) return;
5903        if (!greasyfork) {
5904            DLP_Settings_Var.autoUpdate = !DLP_Settings_Var.autoUpdate;
5905            DLP_Settings_Toggle_Busy = true;
5906            handleToggleClick(DLP_Settings_Auto_Update_Toggle_1_ID.querySelector('#DLP_Inset_Toggle_1_ID'), DLP_Settings_Var.autoUpdate);
5907            setTimeout(() => {
5908                DLP_Settings_Toggle_Busy = false;
5909            }, 800);
5910        }
5911    });
5912    DLP_Settings_Show_Solve_Buttons_1_ID.querySelector('#DLP_Inset_Toggle_1_ID').addEventListener('click', () => {
5913        if (DLP_Settings_Toggle_Busy) return;
5914        DLP_Settings_Var.showSolveButtons = !DLP_Settings_Var.showSolveButtons;
5915        DLP_Settings_Toggle_Busy = true;
5916        handleToggleClick(DLP_Settings_Show_Solve_Buttons_1_ID.querySelector('#DLP_Inset_Toggle_1_ID'), DLP_Settings_Var.showSolveButtons);
5917        setTimeout(() => {
5918            DLP_Settings_Toggle_Busy = false;
5919        }, 800);
5920    });
5921    DLP_Settings_Show_AutoServer_Button_1_ID.querySelector('#DLP_Inset_Toggle_1_ID').addEventListener('click', () => {
5922        if (DLP_Settings_Toggle_Busy) return;
5923        DLP_Settings_Var.showAutoServerButton = !DLP_Settings_Var.showAutoServerButton;
5924        DLP_Settings_Toggle_Busy = true;
5925        handleToggleClick(DLP_Settings_Show_AutoServer_Button_1_ID.querySelector('#DLP_Inset_Toggle_1_ID'), DLP_Settings_Var.showAutoServerButton);
5926        setTimeout(() => {
5927            DLP_Settings_Toggle_Busy = false;
5928        }, 800);
5929    });
5930    DLP_Settings_Help_Us_Make_Better_Button_1_ID.querySelector('#DLP_Inset_Toggle_1_ID').addEventListener('click', () => {
5931        if (DLP_Settings_Toggle_Busy) return;
5932        if (alpha) return;
5933        DLP_Settings_Var.anonymousUsageData = !DLP_Settings_Var.anonymousUsageData;
5934        DLP_Settings_Toggle_Busy = true;
5935        handleToggleClick(DLP_Settings_Help_Us_Make_Better_Button_1_ID.querySelector('#DLP_Inset_Toggle_1_ID'), DLP_Settings_Var.anonymousUsageData);
5936        setTimeout(() => {
5937            DLP_Settings_Toggle_Busy = false;
5938        }, 800);
5939    });
5940
5941
5942    function confetti() {
5943        let canvas = document.getElementById("DLP_Confetti_Canvas");
5944        if (!canvas.confettiInitialized) {
5945            let ctx = canvas.getContext("2d");
5946            canvas.width = window.innerWidth;
5947            canvas.height = window.innerHeight;
5948            let cx = ctx.canvas.width / 2;
5949            let cy = ctx.canvas.height / 2;
5950
5951            canvas.ctx = ctx;
5952            canvas.cx = cx;
5953            canvas.cy = cy;
5954            canvas.confetti = [];
5955            canvas.animationId = null;
5956            canvas.confettiInitialized = true;
5957
5958            let resizeCanvas = () => {
5959                canvas.width = window.innerWidth;
5960                canvas.height = window.innerHeight;
5961                canvas.cx = canvas.ctx.canvas.width / 2;
5962                canvas.cy = canvas.ctx.canvas.height / 2;
5963            };
5964
5965            const resizeObserver = new ResizeObserver(() => {
5966                resizeCanvas();
5967            });
5968            resizeObserver.observe(canvas);
5969
5970            let render = () => {
5971                canvas.ctx.clearRect(0, 0, canvas.width, canvas.height);
5972                canvas.confetti.forEach((confetto, index) => {
5973                    let width = confetto.dimensions.x * confetto.scale.x;
5974                    let height = confetto.dimensions.y * confetto.scale.y;
5975                    canvas.ctx.translate(confetto.position.x, confetto.position.y);
5976                    canvas.ctx.rotate(confetto.rotation);
5977
5978                    confetto.velocity.x -= confetto.velocity.x * drag;
5979                    confetto.velocity.y = Math.min(
5980                        confetto.velocity.y + gravity,
5981                        terminalVelocity,
5982                    );
5983                    confetto.velocity.x +=
5984                        Math.random() > 0.5 ? Math.random() : -Math.random();
5985
5986                    confetto.position.x += confetto.velocity.x;
5987                    confetto.position.y += confetto.velocity.y;
5988
5989                    if (confetto.position.y >= canvas.height) canvas.confetti.splice(index, 1);
5990
5991                    if (confetto.position.x > canvas.width) confetto.position.x = 0;
5992                    if (confetto.position.x < 0) confetto.position.x = canvas.width;
5993
5994                    canvas.ctx.fillStyle = confetto.color.front;
5995                    canvas.ctx.fillRect(-width / 2, -height / 2, width, height);
5996                    canvas.ctx.setTransform(1, 0, 0, 1, 0, 0);
5997                });
5998                canvas.animationId = window.requestAnimationFrame(render);
5999            };
6000            render();
6001        }
6002
6003        const gravity = 0.5;
6004        const terminalVelocity = 10;
6005        const drag = 0.01;
6006        const colors = [
6007            { front: "#FF2D55", back: "#FF2D55" },
6008            { front: "#FF9500", back: "#FF9500" },
6009            { front: "#FFCC00", back: "#FFCC00" },
6010            { front: "#34C759", back: "#34C759" },
6011            { front: "#5AC8FA", back: "#5AC8FA" },
6012            { front: "#007AFF", back: "#007AFF" },
6013            { front: "#5856D6", back: "#5856D6" },
6014            { front: "#AF52DE", back: "#AF52DE" },
6015        ];
6016
6017        const confettiSizeRange = {
6018            min: 5,
6019            max: 15
6020        };
6021
6022        let randomRange = (min, max) => Math.random() * (max - min) + min;
6023
6024        const confettiCount = 400;
6025        for (let i = 0; i < confettiCount; i++) {
6026            canvas.confetti.push({
6027                color: colors[Math.floor(randomRange(0, colors.length))],
6028                dimensions: {
6029                    x: randomRange(confettiSizeRange.min, confettiSizeRange.max),
6030                    y: randomRange(confettiSizeRange.min, confettiSizeRange.max),
6031                },
6032                position: {
6033                    x: randomRange(0, canvas.width),
6034                    y: canvas.height - 1,
6035                },
6036                rotation: randomRange(0, 2 * Math.PI),
6037                scale: {
6038                    x: 1,
6039                    y: 1,
6040                },
6041                velocity: {
6042                    x: randomRange(-25, 25),
6043                    y: randomRange(0, -50),
6044                },
6045            });
6046        }
6047    }
6048
6049    function playHaptic(type) {
6050        function isIPhone() {
6051            return (/iPhone/.test(navigator.userAgent) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1));
6052        }
6053        function isAndroid() {
6054            return /Android/.test(navigator.userAgent) && 'vibrate' in navigator;
6055        }
6056
6057        // iOS haptic trick
6058        function iosHaptic() {
6059            try {
6060                const label = document.createElement("label");
6061                label.ariaHidden = "true";
6062                label.style.display = "none";
6063                const input = document.createElement("input");
6064                input.type = "checkbox";
6065                input.setAttribute("switch", "");
6066                label.appendChild(input);
6067                document.head.appendChild(label);
6068                label.click();
6069                document.head.removeChild(label);
6070            } catch {
6071                console.log("iOS haptic error");
6072            }
6073        }
6074
6075        // Android/Browser Vibration API
6076        function androidHaptic(pattern) {
6077            try {
6078                if (navigator.vibrate) {
6079                    navigator.vibrate(pattern);
6080                }
6081            } catch {
6082                console.log("Android haptic error");
6083            }
6084        }
6085
6086        if (isIPhone()) {
6087            if (type === "success") {
6088                iosHaptic();
6089                setTimeout(iosHaptic, 80);
6090            } else if (type === "warning" || type === "error") {
6091                iosHaptic();
6092                setTimeout(iosHaptic, 100);
6093                setTimeout(iosHaptic, 200);
6094                setTimeout(iosHaptic, 280);
6095            } else {
6096                iosHaptic();
6097            }
6098        } else if (isAndroid()) {
6099            if (type === "success") {
6100                androidHaptic([30, 40, 30]);
6101            } else if (type === "fail" || type === "error") {
6102                androidHaptic([30, 40, 30, 40, 30]);
6103            } else {
6104                androidHaptic(30);
6105            }
6106        } else if (navigator.vibrate) {
6107            // fallback for other platforms supporting Vibration API
6108            if (type === "success") {
6109                navigator.vibrate([30, 40, 30]);
6110            } else if (type === "fail" || type === "error") {
6111                navigator.vibrate([30, 40, 30, 40, 30]);
6112            } else {
6113                navigator.vibrate(30);
6114            }
6115        }
6116        // else: no-op
6117    }
6118
6119
6120
6121    async function generateEarnKey() {
6122        const endpoint = `https://api.duolingopro.net/earn/connect/generate`;
6123
6124        try {
6125            const response = await fetch(endpoint, {
6126                method: 'GET',
6127                headers: {
6128                    'Content-Type': 'application/json',
6129                    'Authorization': `Bearer ${document.cookie.split(';').find(cookie => cookie.includes('jwt_token')).split('=')[1]}`
6130                },
6131            });
6132
6133            if (response.ok) {
6134                const data = await response.json();
6135                if (data.earn_key) {
6136                    console.log('Earn Key:', data.earn_key);
6137                    return data.earn_key;
6138                } else {
6139                    throw new Error('Earn key not found in the response.');
6140                }
6141            } else if (response.status === 401) {
6142                throw new Error('Unauthorized: Invalid or missing authentication token.');
6143            } else if (response.status === 429) {
6144                throw new Error('Rate limit exceeded: Please try again later.');
6145            } else if (response.status === 500) {
6146                const errorData = await response.json();
6147                throw new Error(`Server Error: ${errorData.detail || 'An unexpected error occurred.'}`);
6148            } else {
6149                const errorData = await response.json();
6150                throw new Error(`Error ${response.status}: ${errorData.detail || 'An unexpected error occurred.'}`);
6151            }
6152        } catch (error) {
6153            console.error('Error generating earn key:', error.message);
6154            throw error;
6155        }
6156    }
6157
6158    let earnButtonAssignedLink = false;
6159    document.querySelectorAll("#DLP_Main_Earn_Button_1_ID, #DLP_Secondary_Earn_Button_1_ID").forEach(button => {
6160        button.addEventListener('click', () => {
6161            button.style.opacity = '0.5';
6162            button.style.pointerEvents = 'none';
6163
6164            generateEarnKey()
6165                .then(earnKey => {
6166                console.log('Successfully retrieved earn key:', earnKey);
6167                button.setAttribute("onclick", `window.open('${serverURL}/earn/connect/link/${earnKey}', '_blank');`);
6168                if (!earnButtonAssignedLink) {
6169                    earnButtonAssignedLink = true;
6170                    window.open(serverURL + "/earn/connect/link/" + earnKey, "_blank");
6171                }
6172            })
6173                .catch(error => {
6174                console.error('Failed to retrieve earn key:', error.message);
6175            })
6176                .finally(() => {
6177                button.style.opacity = '';
6178                button.style.pointerEvents = '';
6179            });
6180        });
6181    });
6182
6183
6184
6185
6186    let currentChatId = 1;
6187    let allTexts = {}; // { [chatId]: text }
6188    let allAttachments = {}; // { [chatId]: [ {id, file}, … ] }
6189
6190    function setupSupportPage() {
6191        const container = document.getElementById("DLP_Main_Box_Divider_11_ID");
6192        const chatBox = container.querySelector('.DLP_Chat_Box_1_ID_1');
6193        const attachmentVisualButton = container.querySelector('#DLP_Inset_Button_1_ID');
6194        const sendButton = container.querySelector("#DLP_Inset_Button_2_ID");
6195        const attachmentInput = container.querySelector("#DLP_Attachment_Input_1");
6196        const messageInput = container.querySelector("#DLP_Inset_Input_1_ID");
6197        const activeContainer = container.querySelector('.DLP_Input_Style_1_Active');
6198        let messageSendInProgress = false;
6199
6200        function resetMessageInputState() {
6201            messageInput.value = '';
6202            messageInput.style.height = '1.2em';
6203            if (activeContainer) activeContainer.style.height = '48px';
6204            messageInput.scrollTop = 0;
6205            checkSendButton();
6206        }
6207
6208        function setupCard() {
6209            let card = document.getElementById("DLP_Main_Box_Divider_11_ID").querySelector("#DLP_Inset_Card_1");
6210            let cardExpanded = false;
6211            let cardAnimating = false;
6212
6213            let descriptionText = card.querySelectorAll(':scope > .DLP_Text_Style_1');
6214
6215            card.addEventListener('click', () => {
6216                if (cardAnimating) return;
6217                cardAnimating = true;
6218                if (!cardExpanded) {
6219                    let cardHeight = card.offsetHeight;
6220                    let textHeight = false;
6221                    if (descriptionText.length > 0) {
6222                        textHeight = Array.from(descriptionText).map(() => "0");
6223                        descriptionText.forEach(element => {
6224                            element.style.display = 'block';
6225                            element.style.height = 'auto';
6226                        });
6227                    }
6228                    void card.offsetHeight;
6229                    let newCardHeight = card.offsetHeight;
6230                    let newTextHeight = false;
6231                    if (descriptionText.length > 0) {
6232                        newTextHeight = Array.from(descriptionText).map(element => element.offsetHeight);
6233                    }
6234                    if (descriptionText.length > 0) {
6235                        descriptionText.forEach(element => {
6236                            element.style.height = '0px';
6237                        });
6238                    }
6239                    card.style.height = `${cardHeight}px`;
6240                    void card.offsetHeight;
6241                    if (descriptionText.length > 0) {
6242                        descriptionText.forEach(element => {
6243                            element.style.filter = 'blur(0px)';
6244                            element.style.opacity = '1';
6245                        });
6246                    }
6247                    card.style.height = `${newCardHeight}px`;
6248                    if (descriptionText.length > 0) {
6249                        descriptionText.forEach(element => {
6250                            element.style.height = `${newTextHeight[Array.from(descriptionText).indexOf(element)]}px`;
6251                        });
6252                    }
6253                    card.querySelector('.DLP_HStack_6').style.opacity = '0.5';
6254                    card.querySelector('.DLP_HStack_6').lastElementChild.style.transition = 'all 0.4s cubic-bezier(0.16, 1, 0.32, 1)';
6255                    card.querySelector('.DLP_HStack_6').lastElementChild.style.transform = 'rotate(90deg)';
6256                    setTimeout(() => {
6257                        card.style.height = 'auto';
6258                        if (descriptionText.length > 0) {
6259                            descriptionText.forEach(element => {
6260                                element.style.height = 'auto';
6261                            });
6262                        }
6263                        cardExpanded = true;
6264                        cardAnimating = false;
6265                    }, 400);
6266                } else {
6267                    let cardHeight = card.offsetHeight;
6268                    let textHeight = false;
6269                    if (descriptionText.length > 0) {
6270                        textHeight = Array.from(descriptionText).map(element => element.offsetHeight);
6271                        descriptionText.forEach(element => {
6272                            element.style.display = 'none';
6273                        });
6274                    }
6275                    void card.offsetHeight;
6276                    let newCardHeight = card.offsetHeight;
6277                    let newTextHeight = false;
6278                    if (descriptionText.length > 0) {
6279                        newTextHeight = Array.from(descriptionText).map(() => "0");
6280                        descriptionText.forEach(element => {
6281                            element.style.display = 'block';
6282                            element.style.height = `${textHeight[Array.from(descriptionText).indexOf(element)]}px`;
6283                        });
6284                    }
6285                    card.style.height = `${cardHeight}px`;
6286                    void card.offsetHeight;
6287
6288                    if (descriptionText.length > 0) {
6289                        descriptionText.forEach(element => {
6290                            element.style.filter = 'blur(4px)';
6291                            element.style.opacity = '0';
6292                        });
6293                    }
6294                    card.style.height = `${newCardHeight}px`;
6295                    if (descriptionText.length > 0) {
6296                        descriptionText.forEach(element => {
6297                            element.style.height = '0px';
6298                        });
6299                    }
6300                    card.querySelector('.DLP_HStack_6').style.opacity = '1';
6301                    card.querySelector('.DLP_HStack_6').lastElementChild.style.transition = 'all 0.4s cubic-bezier(0.16, 1, 0.32, 1)';
6302                    card.querySelector('.DLP_HStack_6').lastElementChild.style.transform = 'rotate(0deg)';
6303                    setTimeout(() => {
6304                        card.style.height = 'auto';
6305                        if (descriptionText.length > 0) {
6306                            descriptionText.forEach(element => {
6307                                element.style.display = 'none';
6308                            });
6309                        }
6310                        cardExpanded = false;
6311                        cardAnimating = false;
6312                    }, 400);
6313                }
6314            });
6315        }
6316        setupCard();
6317
6318        function markTempMessageFailed(tempId) {
6319            const tempState = pendingTempMessages.get(tempId);
6320            if (tempState) {
6321                tempState.sendFailed = true;
6322            }
6323            const tempElements = chatBox.querySelectorAll(`[data-is-temp="${tempId}"]`);
6324            tempElements.forEach(element => {
6325                element.style.animation = '';
6326                element.style.color = 'rgba(var(--DLP-pink))';
6327            });
6328        }
6329
6330        function setupSendButton() {
6331            sendButton.addEventListener('click', async () => {
6332                if (messageSendInProgress) return;
6333                if (!storageLocal.chatKey || storageLocal.chatKey.length === 0) {
6334                    if (container?.querySelector('#DLP_Inset_Group_3')?.style.display !== 'none') container.querySelector('#DLP_Inset_Group_3').style.display = 'none';
6335                    if (chatBox?.style.display === 'none') chatBox.style.display = 'flex';
6336
6337                    try {
6338                        let response = await fetch(apiURL + "/chats/create", {
6339                            method: "GET",
6340                            headers: {
6341                                "Authorization": `Bearer ${document.cookie.split(';').find(cookie => cookie.includes('jwt_token')).split('=')[1]}`
6342                            }
6343                        });
6344
6345                        let data = await response.json();
6346                        console.log("Server Response:", data);
6347                        storageLocal.chatKey = [data.chat_key];
6348                        saveStorageLocal();
6349                    } catch (error) {
6350                        console.error("Fetch error:", error);
6351                    }
6352                }
6353
6354                let formData = new FormData();
6355                formData.append("message", messageInput.value);
6356
6357                let fileUrls = [];
6358                for (const attachment of allAttachments[currentChatId] ?? []) {
6359                    const file = attachment.file;
6360                    console.log("attaching", file);
6361                    formData.append("files", file);
6362                    const url = URL.createObjectURL(file);
6363                    console.log("url", url);
6364                    fileUrls.push(url);
6365                }
6366
6367                let chatTempSendNumber = chatTempSendList.length ? chatTempSendList[chatTempSendList.length - 1] + 1 : 1;
6368                const tempMessageId = `temp-${chatTempSendNumber}`;
6369                let tempData = {
6370                    "accent": '#007AFF',
6371                    "author": userBioData.username,
6372                    "edited": false,
6373                    "files": fileUrls,
6374                    "message": messageInput.value,
6375                    "profile_picture": userBioData.profile_picture,
6376                    "role": "You",
6377                    "send_time": Number(Date.now()),
6378                    "message_id": tempMessageId
6379                };
6380                createMessage(tempData, false, chatTempSendNumber);
6381                pendingTempMessages.set(chatTempSendNumber, {
6382                    ...tempData,
6383                    files: [...tempData.files]
6384                });
6385
6386                chatTempSendList.push(chatTempSendNumber);
6387
6388                chatBox.scrollTop = chatBox.scrollHeight;
6389                allAttachments[currentChatId] = [];
6390                renderAttachmentsPreview();
6391                messageSendInProgress = true;
6392                checkSendButton();
6393                resetMessageInputState();
6394
6395                try {
6396                    let response = await fetch(apiURL + "/chats/send_message", {
6397                        method: "POST",
6398                        headers: alpha
6399                        ? {
6400                            'Authorization': `Bearer ${document.cookie.split(';').find(cookie => cookie.includes('jwt_token')).split('=')[1]}`,
6401                            'X-Chat-Key': `${storageLocal.chatKey[0]}`
6402                        }
6403                        : {
6404                            'X-Chat-Key': `${storageLocal.chatKey[0]}`
6405                        },
6406                        body: formData
6407                    });
6408
6409                    let responseData = await response.json();
6410                    console.log("Server Response:", responseData);
6411
6412                    const isNewMessageFormat = response.ok && responseData && typeof responseData === 'object' && Object.prototype.hasOwnProperty.call(responseData, 'message_id');
6413                    if (isNewMessageFormat) {
6414                        const wasAtBottom = Math.abs(chatBox.scrollHeight - (chatBox.scrollTop + chatBox.clientHeight)) < 5;
6415                        chatBox.querySelectorAll(`[data-is-temp="${chatTempSendNumber}"]`).forEach(element => {
6416                            element.remove();
6417                        });
6418                        createMessage(responseData);
6419                        const tempIndex = chatTempSendList.indexOf(chatTempSendNumber);
6420                        if (tempIndex !== -1) {
6421                            chatTempSendList.splice(tempIndex, 1);
6422                        }
6423                        pendingTempMessages.delete(chatTempSendNumber);
6424                        if (wasAtBottom) {
6425                            chatBox.scrollTop = chatBox.scrollHeight;
6426                        }
6427                    } else {
6428                        if (responseData?.status === false && responseData?.notification) {
6429                            showNotification(responseData.notification.icon, responseData.notification.head, responseData.notification.body, responseData.notification.duration);
6430                        } else {
6431                            showNotification("error", "Send Failed", "We could not verify that your message was delivered. Please try again.", 8);
6432                        }
6433                        markTempMessageFailed(chatTempSendNumber);
6434                    }
6435
6436                } catch (error) {
6437                    console.error("Fetch error:", error);
6438                    markTempMessageFailed(chatTempSendNumber);
6439                } finally {
6440                    messageSendInProgress = false;
6441                    checkSendButton();
6442                }
6443            });
6444        }
6445        setupSendButton();
6446
6447        function setupTextInput() {
6448            const sendButton = container.querySelector("#DLP_Inset_Button_2_ID");
6449            resetMessageInputState();
6450
6451            messageInput.addEventListener('input', function () {
6452                messageInput.style.height = '1.2em';
6453
6454                const lineHeight = parseInt(getComputedStyle(messageInput).lineHeight);
6455                const maxRows = 5;
6456                const maxHeight = lineHeight * maxRows;
6457
6458                const newHeight = Math.min((messageInput.scrollHeight - 32), maxHeight);
6459
6460                messageInput.style.height = newHeight + 'px';
6461
6462                if (newHeight < 20) {
6463                    activeContainer.style.height = '48px';
6464                } else {
6465                    activeContainer.style.height = (newHeight + 32) + 'px';
6466                }
6467
6468                checkSendButton();
6469            });
6470
6471            messageInput.addEventListener('keydown', function (event) {
6472                if (event.key === 'Enter' && !event.shiftKey) {
6473                    event.preventDefault();
6474                    if (sendButton.style.pointerEvents !== 'none') {
6475                        sendButton.click();
6476                    }
6477                }
6478            });
6479        }
6480        setupTextInput();
6481
6482        let nextAttachmentId = 0;
6483        let attachmentDropBoxExpanded = false;
6484
6485        const MAX_ATTACHMENT_FILE_SIZE = 50 * 1024 * 1024; // 50 MB
6486        const MAX_ATTACHMENT_FILE_COUNT = 3;
6487
6488        function setupAttachmentsInput() {
6489            const attachmentBox = container.querySelector('#DLP_Attachment_Preview_Parent');
6490            const attachmentBoxDrop = attachmentBox.querySelector('.DLP_Attachment_Box_Drop_1');
6491
6492            attachmentBoxDrop.addEventListener('dragenter', event => {
6493                event.preventDefault();
6494                //attachmentBoxDrop.style.outline = '2px solid rgba(var(--DLP-blue), 0.20)';
6495                attachmentBoxDrop.firstElementChild.style.opacity = '1';
6496            });
6497
6498            attachmentBoxDrop.addEventListener('dragleave', event => {
6499                event.preventDefault();
6500                if (attachmentBoxDrop.contains(event.relatedTarget)) return;
6501                //attachmentBoxDrop.style.outline = '2px dashed rgba(var(--DLP-blue), 0.20)';
6502                attachmentBoxDrop.firstElementChild.style.opacity = '0.5';
6503            });
6504
6505            window.addEventListener('dragover', (event) => {
6506                event.preventDefault();
6507                if (attachmentInput.disabled) return;
6508                if (event.dataTransfer && event.dataTransfer.types.includes('Files')) {
6509                    if (attachmentBox.style.display === 'none') {
6510                        attachmentBox.style.display = '';
6511                    }
6512                    [...attachmentBox.children].forEach(child => {
6513                        if (child !== attachmentBoxDrop) {
6514                            child.style.display = 'none';
6515                        }
6516                    });
6517                    attachmentBoxDrop.style.display = '';
6518                }
6519            });
6520
6521            window.addEventListener('dragleave', (event) => {
6522                if (event.clientX <= 0 || event.clientY <= 0 || event.clientX >= window.innerWidth || event.clientY >= window.innerHeight) {
6523                    if (attachmentBox.children.length === 1 && attachmentBox.children[0] === attachmentBoxDrop) {
6524                        attachmentBox.style.display = 'none';
6525                    }
6526                    [...attachmentBox.children].forEach(child => {
6527                        if (child !== attachmentBoxDrop) {
6528                            child.style.display = '';
6529                        }
6530                    });
6531                    attachmentBoxDrop.style.display = 'none';
6532                    //attachmentBoxDrop.style.outline = '2px dashed a(var(--DLP-blue), 0.20)';
6533                    attachmentBoxDrop.firstElementChild.style.opacity = '0.5';
6534                }
6535            });
6536
6537            window.addEventListener('drop', (event) => {
6538                event.preventDefault();
6539                [...attachmentBox.children].forEach(child => {
6540                    if (child !== attachmentBoxDrop) {
6541                        child.style.display = '';
6542                    }
6543                });
6544                attachmentBoxDrop.style.display = 'none';
6545                //attachmentBoxDrop.style.outline = '2px dashed rgba(var(--DLP-blue), 0.20)';
6546                attachmentBoxDrop.firstElementChild.style.opacity = '0.5';
6547            });
6548
6549            attachmentBoxDrop.addEventListener('drop', (event) => {
6550                event.preventDefault();
6551                attachmentBoxDrop.style.display = 'none';
6552
6553                const selectedFiles = Array.from(event.dataTransfer.files);
6554                triggerInputAttachments(selectedFiles);
6555            });
6556
6557            attachmentVisualButton.addEventListener('click', () => attachmentInput.click());
6558
6559            attachmentInput.addEventListener('change', (event) => {
6560                const selectedFiles = Array.from(event.target.files);
6561                triggerInputAttachments(selectedFiles);
6562            });
6563        }
6564        setupAttachmentsInput();
6565
6566        function triggerInputAttachments(selectedFiles) {
6567            if (!allAttachments[currentChatId]) {
6568                allAttachments[currentChatId] = [];
6569            }
6570            const validFiles = [];
6571
6572            selectedFiles.forEach(file => {
6573                if (file.size > MAX_ATTACHMENT_FILE_SIZE) {
6574                    showNotification("warning", "File Too Large", `${file.name} is over 10 MB, please choose a smaller file.`, 10);
6575                } else {
6576                    validFiles.push(file);
6577                }
6578            });
6579
6580            const remainingSlots = MAX_ATTACHMENT_FILE_COUNT - allAttachments[currentChatId]?.length;
6581            if (validFiles.length > remainingSlots) {
6582                showNotification("warning", "Too Many Files", `You can only attach up to ${MAX_ATTACHMENT_FILE_COUNT} files at once.`, 10);
6583                validFiles.length = remainingSlots;
6584            }
6585
6586            validFiles.forEach(file => {
6587                allAttachments[currentChatId]?.push({ id: String(nextAttachmentId++), file }); // wrap each in an {id, file} and append
6588            });
6589
6590            updateAttachmentsInput();
6591            renderAttachmentsPreview();
6592            checkSendButton();
6593            attachmentInput.value = '';
6594        }
6595
6596        function updateAttachmentsInput() {
6597            const dt = new DataTransfer();
6598            allAttachments[currentChatId]?.forEach(a => dt.items.add(a.file));
6599            attachmentInput.files = dt.files;
6600        }
6601
6602        function removeAttachmentById(id) {
6603            allAttachments[currentChatId] = allAttachments[currentChatId]?.filter(a => a.id !== id);
6604            updateAttachmentsInput();
6605            renderAttachmentsPreview();
6606            checkSendButton();
6607        }
6608
6609        function renderAttachmentsPreview() {
6610            const attachmentBox = container.querySelector('#DLP_Attachment_Preview_Parent');
6611            const attachmentBoxDrop = attachmentBox.querySelector('.DLP_Attachment_Box_Drop_1');
6612
6613            const currentIds = new Set(allAttachments[currentChatId]?.map(a => a.id));
6614
6615            // 1) remove deleted attachments from the DOM
6616            Array.from(attachmentBox.children).forEach(child => {
6617                const childId = child.getAttribute('data-id');
6618                if (!currentIds.has(childId) && child !== attachmentBoxDrop) {
6619                    attachmentBox.removeChild(child);
6620                }
6621            });
6622
6623            // 2) add new attachments to the DOM
6624            allAttachments[currentChatId]?.forEach(({ id, file }) => {
6625                if (attachmentBox.querySelector(`[data-id="${id}"]`)) return;
6626
6627                const url = URL.createObjectURL(file);
6628                const box = document.createElement('div');
6629                box.className = 'DLP_Attachment_Box_1';
6630                box.setAttribute('data-id', id);
6631                box.style.position = 'relative';
6632
6633                let media;
6634                if (file.type.startsWith('image/')) {
6635                    media = document.createElement('img');
6636                    media.src = url;
6637                    media.className = 'DLP_Attachment_Box_1_Content';
6638                } else if (file.type.startsWith('video/')) {
6639                    media = document.createElement('video');
6640                    media.src = url;
6641                    media.autoplay = true;
6642                    media.muted = true;
6643                    media.loop = true;
6644                    media.className = 'DLP_Attachment_Box_1_Content';
6645                } else {
6646                    media = document.createElement('div');
6647                    media.style.display = 'flex';
6648                    media.style.width = '100%';
6649                    media.style.height = '100%';
6650                    media.style.paddingTop = '6px';
6651                    media.style.flexDirection = 'column';
6652                    media.style.justifyContent = 'center';
6653                    media.style.alignItems = 'center';
6654                    media.style.gap = '6px';
6655                    media.style.flexShrink = '0';
6656
6657                    mediaChild1 = document.createElement('p');
6658                    mediaChild1.className = 'DLP_Text_Style_1 DLP_NoSelect';
6659                    mediaChild1.style.fontSize = '24px';
6660                    mediaChild1.textContent = '􀈸';
6661                    media.appendChild(mediaChild1);
6662
6663                    mediaChild2 = document.createElement('p');
6664                    mediaChild2.className = 'DLP_Text_Style_1 DLP_NoSelect';
6665                    mediaChild2.style.opacity = '0.5';
6666                    mediaChild2.textContent = 'File';
6667                    //mediaChild2.textContent = file.name;
6668                    media.appendChild(mediaChild2);
6669                }
6670
6671                // Create and append delete button
6672                const hover = document.createElement('div');
6673                hover.className = 'DLP_Attachment_Box_1_Hover';
6674                hover.style.display = 'none';
6675                box.addEventListener('mouseenter', () => {
6676                    hover.style.display = '';
6677                });
6678                box.addEventListener('mouseleave', () => {
6679                    hover.style.display = 'none';
6680                });
6681                const btn = document.createElement('p');
6682                btn.className = 'DLP_Text_Style_1 DLP_Magnetic_Hover_1 DLP_NoSelect';
6683                if ((file.type.startsWith('image/') || file.type.startsWith('video/'))) btn.textContent = '􀻀';
6684                else btn.textContent = '􀈸';
6685                btn.addEventListener('click', () => removeAttachmentById(id));
6686                hover.appendChild(btn);
6687
6688                box.appendChild(media);
6689                box.appendChild(hover);
6690                attachmentBox.appendChild(box);
6691
6692                if (false) {
6693                    if (file.type.startsWith('image/')) {
6694                        media.addEventListener('load', () => updateContrast(box));
6695                        if (media.complete) updateContrast(box);
6696                    } else if (file.type.startsWith('video/')) {
6697                        media.addEventListener('loadeddata', () => {
6698                            const iv = setInterval(() => {
6699                                if (!document.contains(media)) {
6700                                    clearInterval(iv);
6701                                } else {
6702                                    updateContrast(box);
6703                                }
6704                            }, 250);
6705                            updateContrast(box);
6706                        });
6707                    } else {
6708                        updateContrast(box);
6709                    }
6710                }
6711            });
6712
6713            // Show or hide the attachmentBox and adjust padding/navigation
6714            if ((allAttachments[currentChatId]?.length ?? 0) === 0 && attachmentDropBoxExpanded) {
6715                attachmentBox.style.display = 'none';
6716                attachmentDropBoxExpanded = false;
6717                chatBox.scrollTop = chatBox.scrollHeight;
6718                //const nav = document.querySelector('#DLP_Main_Navigation_Box_5_ID .DLP_Col.DLP_Fill_Col.DLP_Fill_Row.DLP_Gap_8');
6719                //nav.style.paddingBottom = `${parseFloat(getComputedStyle(nav).paddingBottom) - 104}px`;
6720            } else if (allAttachments[currentChatId]?.length > 0 && !attachmentDropBoxExpanded) {
6721                attachmentBox.style.display = '';
6722                attachmentDropBoxExpanded = true;
6723                chatBox.scrollTop = chatBox.scrollHeight;
6724                //const nav = document.querySelector('#DLP_Main_Navigation_Box_5_ID .DLP_Col.DLP_Fill_Col.DLP_Fill_Row.DLP_Gap_8');
6725                //nav.style.paddingBottom = `${parseFloat(getComputedStyle(nav).paddingBottom) + 104}px`;
6726                //void container.offsetHeight;
6727                //document.querySelector('#DLP_Main_Navigation_Box_5_ID').scrollTop += 104;
6728            }
6729
6730            // Disable input if there are too many files
6731            if (allAttachments[currentChatId]?.length >= MAX_ATTACHMENT_FILE_COUNT) {
6732                attachmentInput.disabled = true;
6733                attachmentVisualButton.style.opacity = '0.5';
6734                attachmentVisualButton.style.pointerEvents = 'none';
6735            } else {
6736                attachmentInput.disabled = false;
6737                attachmentVisualButton.style.opacity = '';
6738                attachmentVisualButton.style.pointerEvents = '';
6739            }
6740
6741        }
6742
6743        function setupCreateNewChatButton() {
6744            let theButton = container.querySelector('#DLP_Inset_Group_2').querySelector('#DLP_Inset_Button_3_ID');
6745            theButton.addEventListener('click', async () => {
6746                theButton.style.opacity = "0.5";
6747                theButton.style.pointerEvents = "none";
6748                try {
6749                    let response = await fetch(apiURL + "/chats/create", {
6750                        method: "GET",
6751                        headers: {
6752                            "Authorization": `Bearer ${document.cookie.split(';').find(cookie => cookie.includes('jwt_token')).split('=')[1]}`
6753                        }
6754                    });
6755
6756                    let data = await response.json();
6757                    console.log("Server Response:", data);
6758                    storageLocal.chatKey = [data.chat_key];
6759                    saveStorageLocal();
6760
6761                    chatBox.innerHTML = '';
6762
6763                    container.querySelector('#DLP_Inset_Group_1').style.display = "";
6764                    container.querySelector('#DLP_Inset_Group_2').style.display = "none";
6765
6766                    theButton.style.opacity = "";
6767                    theButton.style.pointerEvents = "";
6768                } catch (error) {
6769                    console.error("Fetch error:", error);
6770                    theButton.style.opacity = "";
6771                    theButton.style.pointerEvents = "";
6772                }
6773            });
6774        }
6775        setupCreateNewChatButton();
6776
6777        function checkSendButton() {
6778            if (messageSendInProgress) {
6779                sendButton.style.opacity = "0.5";
6780                sendButton.style.pointerEvents = "none";
6781                return;
6782            }
6783            if (messageInput.value.trim() !== "" || (allAttachments[currentChatId]?.length ?? 0) > 0) {
6784                sendButton.style.opacity = "";
6785                sendButton.style.pointerEvents = "";
6786            } else {
6787                sendButton.style.opacity = "0.5";
6788                sendButton.style.pointerEvents = "none";
6789            }
6790        }
6791        checkSendButton();
6792    }
6793    setupSupportPage();
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804    const originalPlay = HTMLAudioElement.prototype.play;
6805    function muteTab(value) {
6806        HTMLAudioElement.prototype.play = function () {
6807            if (value) {
6808                this.muted = true;
6809            } else {
6810                this.muted = false;
6811            }
6812            return originalPlay.apply(this, arguments);
6813        };
6814    }
6815
6816    document.addEventListener('keydown', function(event) {
6817        if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
6818            if (event.shiftKey) {
6819                solving();
6820            } else {
6821                solve();
6822            }
6823        }
6824    });
6825
6826    let currentQuestionId = null;
6827    let hasLoggedForCurrent = false;
6828
6829    async function logOnce(flag, sol, dom) {
6830        // flag: 1 = solved, 2 = wrong, 3 = stuck
6831        if (!hasLoggedForCurrent) {
6832            if (alpha) {
6833                console.log(flag);
6834                //console.log(sol);
6835                //console.log(dom);
6836                console.log(sol.challengeGeneratorIdentifier.generatorId);
6837            }
6838            hasLoggedForCurrent = true;
6839
6840            if (storageLocal.settings.anonymousUsageData) {
6841                if (flag === 2) showNotification("error", "Legacy Solved Incorrectly", "Legacy has detected that it solved a question incorrectly. A report has been made under ID: " + sol.challengeGeneratorIdentifier.generatorId, 10);
6842                else if (flag === 3) showNotification("error", "Legacy is Stuck", "Legacy has detected that it is stuck on a question. A report has been made under ID: " + sol.challengeGeneratorIdentifier.generatorId, 10);
6843
6844                const payload = {
6845                    version: versionFormal,
6846                    random: storageLocal.random16,
6847                    flag: flag,
6848                    sol: sol,
6849                    dom: dom.outerHTML
6850                };
6851
6852                console.log(sol);
6853
6854                const response = await fetch("https://api.duolingopro.net/analytics/legacy", {
6855                    method: 'POST',
6856                    headers: {
6857                        'Content-Type': 'application/json'
6858                    },
6859                    body: JSON.stringify(payload)
6860                });
6861            } else {
6862                if (flag === 2) showNotification("error", "Legacy Solved Incorrectly", "Legacy has detected that it solved a question incorrectly. Turn on share anonymous usage data in settings to help us fix this bug.", 10);
6863                else if (flag === 3) showNotification("error", "Legacy is Stuck", "Legacy has detected that it is stuck on a question. Turn on share anonymous usage data in settings to help us fix this bug.", 10);
6864            }
6865        }
6866    }
6867
6868    function updateSolveButtonText(text) {
6869        document.getElementById("solveAllButton").innerText = text;
6870    }
6871
6872    function solving(value) {
6873        if (value === "start") isAutoMode = true;
6874        else if (value === "stop") isAutoMode = false;
6875        else isAutoMode = !isAutoMode;
6876        updateSolveButtonText(isAutoMode ? systemText[systemLanguage][102] : systemText[systemLanguage][101]);
6877        solvingIntervalId = isAutoMode ? (function() {
6878            let initialUrl = window.location.href;
6879            return setInterval(function() {
6880                if (window.location.href !== initialUrl) {
6881                    isAutoMode = false;
6882                    clearInterval(solvingIntervalId);
6883                    updateSolveButtonText(isAutoMode ? systemText[systemLanguage][102] : systemText[systemLanguage][101]);
6884                    return;
6885                } else {
6886                    solve();
6887                }
6888            }, storageLocal.settings.solveSpeed * 1000);
6889        })() : clearInterval(solvingIntervalId);
6890    }
6891
6892    let hcwNIIOdaQqCZRDL = false;
6893    function solve() {
6894        const practiceAgain = document.querySelector('[data-test="player-practice-again"]');
6895        const sessionCompleteSlide = document.querySelector('[data-test="session-complete-slide"]');
6896
6897        const selectorsForSkip = [
6898            '[data-test="practice-hub-ad-no-thanks-button"]',
6899            '.vpDIE',
6900            '[data-test="plus-no-thanks"]',
6901            '._1N-oo._36Vd3._16r-S._1ZBYz._23KDq._1S2uf.HakPM',
6902            '._8AMBh._2vfJy._3Qy5R._28UWu._3h0lA._1S2uf._1E9sc',
6903            '._1Qh5D._36g4N._2YF0P._28UWu._3h0lA._1S2uf._1E9sc',
6904            '[data-test="story-start"]',
6905            '._3bBpU._1x5JY._1M9iF._36g4N._2YF0P.T7I0c._2EnxW.MYehf',
6906            '._2V6ug._1ursp._7jW2t._28UWu._3h0lA._1S2uf._1E9sc', // No Thanks Legendary Button
6907            '._1rcV8._1VYyp._1ursp._7jW2t._1gKir', // Language Score
6908            '._2V6ug._1ursp._7jW2t._3zgLG' // Create Profile Later
6909        ];
6910        selectorsForSkip.forEach(selector => {
6911            const element = document.querySelector(selector);
6912            if (element) element.click();
6913        });
6914
6915
6916        const status = storageSession.legacy.status;
6917        const type = status ? storageSession.legacy[status]?.type : null;
6918        let amount;
6919
6920        if (sessionCompleteSlide !== null && isAutoMode && storageSession.legacy.status) {
6921            if (!hcwNIIOdaQqCZRDL) {
6922                hcwNIIOdaQqCZRDL = true;
6923                if (type === 'lesson') {
6924                    storageSession.legacy[status].amount -= 1;
6925                    saveStorageSession();
6926                    (((storageLocal.stats ??= {}).legacy ??= {})[status] ??= { lessons: 0 }).lessons++;
6927                    saveStorageLocal();
6928                    amount = status ? storageSession.legacy[status]?.amount : null;
6929                    if (amount > 0) {
6930                        if (practiceAgain !== null) {
6931                            practiceAgain.click();
6932                            return;
6933                        } else {
6934                            location.reload();
6935                        }
6936                    } else {
6937                        storageSession.legacy[status].amount = 0;
6938                        storageSession.legacy.status = false;
6939                        saveStorageSession();
6940                        window.location.href = "https://duolingo.com";
6941                        return;
6942                    }
6943                } else if (type === 'xp') {
6944                    storageSession.legacy[status].amount -= findSubReact(document.getElementsByClassName("_1XNQX")[0]).xpGoalSessionProgress.totalXpThisSession;
6945                    saveStorageSession();
6946                    (((storageLocal.stats ??= {}).legacy ??= {})[status] ??= { lessons: 0 }).lessons++;
6947                    saveStorageLocal();
6948                    amount = status ? storageSession.legacy[status]?.amount : null;
6949                    if (amount > 0) {
6950                        if (practiceAgain !== null) {
6951                            practiceAgain.click();
6952                            return;
6953                        } else {
6954                            location.reload();
6955                        }
6956                    } else {
6957                        storageSession.legacy[status].amount = 0;
6958                        storageSession.legacy.status = false;
6959                        saveStorageSession();
6960                        window.location.href = "https://duolingo.com";
6961                        return;
6962                    }
6963                } else if (type === 'infinity') {
6964                    (((storageLocal.stats ??= {}).legacy ??= {})[status] ??= { lessons: 0 }).lessons++;
6965                    saveStorageLocal();
6966                    if (practiceAgain !== null) {
6967                        practiceAgain.click();
6968                        return;
6969                    } else {
6970                        location.reload();
6971                    }
6972                }
6973            }
6974        }
6975
6976        try {
6977            window.sol = findReact(document.getElementsByClassName(findReactMainElementClass)[0]).props.currentChallenge;
6978        } catch (error) {
6979            console.log(error);
6980            //let next = document.querySelector('[data-test="player-next"]');
6981            //if (next) {
6982            //    next.click();
6983            //}
6984            //return;
6985        }
6986        //if (!window.sol) {
6987        //    return;
6988        //}
6989
6990        let challengeType;
6991        if (window.sol) {
6992            challengeType = determineChallengeType();
6993        } else {
6994            challengeType = 'error';
6995            nextClickFunc();
6996        }
6997
6998        let questionKey;
6999        if (window.sol && window.sol.id) {
7000            questionKey = window.sol.id;
7001        } else if (window.sol) {
7002            // Fallback if no 'id' property: use type + prompt
7003            questionKey = JSON.stringify({
7004                type: window.sol.type,
7005                prompt: window.sol.prompt || ''
7006            });
7007        } else {
7008            questionKey = null;
7009        }
7010
7011        if (questionKey !== currentQuestionId) {
7012            currentQuestionId = questionKey;
7013            hasLoggedForCurrent = false;
7014        }
7015
7016        if (challengeType === 'error') {
7017            nextClickFunc();
7018        } else if (challengeType) {
7019            if (debug) document.getElementById("solveAllButton").innerText = challengeType;
7020            handleChallenge(challengeType);
7021            nextClickFunc();
7022        } else {
7023            nextClickFunc();
7024        }
7025    }
7026
7027
7028
7029    function nextClickFunc() {
7030        setTimeout(function () {
7031            try {
7032                let nextButtonNormal = document.querySelector('[data-test="player-next"]');
7033                let storiesContinueButton = document.querySelector('[data-test="stories-player-continue"]');
7034                let storiesDoneButton = document.querySelector('[data-test="stories-player-done"]');
7035
7036                let nextButtonAriaValueNormal = nextButtonNormal ? nextButtonNormal.getAttribute('aria-disabled') : null;
7037                let nextButtonAriaValueStoriesContinue = storiesContinueButton ? storiesContinueButton.disabled : null;
7038
7039                let nextButton = nextButtonNormal || storiesContinueButton || storiesDoneButton;
7040                let nextButtonAriaValue = nextButtonAriaValueNormal || nextButtonAriaValueStoriesContinue || storiesDoneButton;
7041
7042                if (nextButton) {
7043                    if (nextButtonAriaValue === 'true' || nextButtonAriaValue === true) {
7044                        requestAnimationFrame(() => {
7045                            if (document.querySelectorAll('._35QY2._3jIlr.f2zGP._18W4a.xtPuL').length > 0) {
7046                            } else {
7047                                if (nextButtonAriaValue === 'true') {
7048                                    //console.log('The next button is disabled.');
7049                                    logOnce(3, window.sol, document.querySelector('.RMEuZ._1GVfY'));
7050                                }
7051                            }
7052                        });
7053                    } else if (nextButtonAriaValue === 'false' || nextButtonAriaValue === false) {
7054                        nextButton.click();
7055                        requestAnimationFrame(() => {
7056                            if (document.querySelector('[data-test="player-next"]').classList.contains('_2oGJR')) { // _1rcV8 _1VYyp _1ursp _7jW2t _3DbUj _2VWgj _3S8jJ
7057                                logOnce(1, window.sol, document.querySelector('.RMEuZ._1GVfY'));
7058                                const status = storageSession.legacy.status;
7059                                (((storageLocal.stats ??= {}).legacy ??= {})[status] ??= { questions: 0 }).questions++;
7060                                saveStorageLocal();
7061                                //mainSolveStatistics('question', 1);
7062                                if (isAutoMode) {
7063                                    setTimeout(function () {
7064                                        nextButton.click();
7065                                    }, 100);
7066                                }
7067                            } else if (document.querySelector('[data-test="player-next"]').classList.contains('_3S8jJ')) {
7068                                logOnce(2, window.sol, document.querySelector('.RMEuZ._1GVfY'));
7069                                //if (solveSpeed < 0.6) {
7070                                //    solveSpeed = 0.6;
7071                                //    localStorage.setItem('duopro.autoSolveDelay', solveSpeed);
7072                                //}
7073                            } else {
7074                                console.log('The element does not have the class ._9C_ii or .NAidc or the element is not found.');
7075                            }
7076                        });
7077                    } else {
7078                        console.log('The aria-disabled attribute is not set or has an unexpected value.');
7079                        //notificationCall("what", "Idk");
7080                        nextButton.click();
7081                    }
7082                } else {
7083                    console.log('Element with data-test="player-next" or data-test="stories-player-continue" not found.');
7084                }
7085            } catch (error) { }
7086        }, 100);
7087    }
7088
7089
7090    function LhEqEHHc() {
7091        const randomImageValue = Math.random().toString(36).substring(2, 15);
7092        //questionErrorLogs(findReact(document.getElementsByClassName(findReactMainElementClass)[0]).props.currentChallenge, document.body.innerHTML, randomImageValue);
7093        //const challengeAssistElement = document.querySelector('[data-test="challenge challenge-assist"]');
7094        const challengeAssistElement = document.querySelector('._3x0ok');
7095        if (challengeAssistElement) {
7096        } else {
7097            console.log('Element not found');
7098        }
7099    }
7100    function determineChallengeType() {
7101        try {
7102            //console.log(window.sol);
7103            if (document.getElementsByClassName("FmlUF").length > 0) {
7104                // Story
7105                if (window.sol.type === "arrange") {
7106                    return "Story Arrange"
7107                } else if (window.sol.type === "multiple-choice" || window.sol.type === "select-phrases") {
7108                    return "Story Multiple Choice"
7109                } else if (window.sol.type === "point-to-phrase") {
7110                    return "Story Point to Phrase"
7111                } else if (window.sol.type === "match") {
7112                    return "Story Pairs"
7113                }
7114            } else {
7115                // Lesson
7116                if (document.querySelectorAll('[data-test*="challenge-speak"]').length > 0) {
7117                    hcwNIIOdaQqCZRDL = false;
7118                    return 'Challenge Speak';
7119                } else if (window.sol.type === 'tapCompleteTable') {
7120                    return 'Tap Complete Table';
7121                } else if (window.sol.type === 'typeCloze') {
7122                    return 'Type Cloze';
7123                } else if (window.sol.type === 'typeClozeTable') {
7124                    return 'Type Cloze Table';
7125                } else if (window.sol.type === 'tapClozeTable') {
7126                    return 'Tap Cloze Table';
7127                } else if (window.sol.type === 'typeCompleteTable') {
7128                    return 'Type Complete Table';
7129                } else if (window.sol.type === 'patternTapComplete') {
7130                    return 'Pattern Tap Complete';
7131                } else if (document.querySelectorAll('[data-test*="challenge-name"]').length > 0 && document.querySelectorAll('[data-test="challenge-choice"]').length > 0) {
7132                    hcwNIIOdaQqCZRDL = false;
7133                    return 'Challenge Name';
7134                } else if (window.sol.type === 'listenMatch') {
7135                    hcwNIIOdaQqCZRDL = false;
7136                    return 'Listen Match';
7137                } else if (document.querySelectorAll('[data-test="challenge challenge-listenSpeak"]').length > 0) {
7138                    hcwNIIOdaQqCZRDL = false;
7139                    return 'Listen Speak';
7140                } else if (document.querySelectorAll('[data-test="challenge-choice"]').length > 0) {
7141                    hcwNIIOdaQqCZRDL = false;
7142                    if (document.querySelectorAll('[data-test="challenge-text-input"]').length > 0) {
7143                        return 'Challenge Choice with Text Input';
7144                    } else {
7145                        return 'Challenge Choice'
7146                    }
7147                } else if (document.querySelectorAll('[data-test$="challenge-tap-token"]').length > 0) {
7148                    hcwNIIOdaQqCZRDL = false;
7149                    if (window.sol.pairs !== undefined) {
7150                        return 'Pairs';
7151                    } else if (window.sol.correctTokens !== undefined) {
7152                        return 'Tokens Run';
7153                    } else if (window.sol.correctIndices !== undefined) {
7154                        return 'Indices Run';
7155                    }
7156                } else if (document.querySelectorAll('[data-test="challenge-tap-token-text"]').length > 0) {
7157                    hcwNIIOdaQqCZRDL = false;
7158                    return 'Fill in the Gap';
7159                } else if (document.querySelectorAll('[data-test="challenge-text-input"]').length > 0) {
7160                    hcwNIIOdaQqCZRDL = false;
7161                    return 'Challenge Text Input';
7162                } else if (document.querySelectorAll('[data-test*="challenge-partialReverseTranslate"]').length > 0) {
7163                    hcwNIIOdaQqCZRDL = false;
7164                    return 'Partial Reverse';
7165                } else if (document.querySelectorAll('textarea[data-test="challenge-translate-input"]').length > 0) {
7166                    hcwNIIOdaQqCZRDL = false;
7167                    return 'Challenge Translate Input';
7168                } else if (document.querySelectorAll('[data-test="session-complete-slide"]').length > 0) {
7169                    return 'Session Complete';
7170                } else if (document.querySelectorAll('[data-test="daily-quest-progress-slide"]').length > 0) {
7171                    return 'Daily Quest Progress';
7172                } else if (document.querySelectorAll('[data-test="streak-slide"]').length > 0) {
7173                    return 'Streak';
7174                } else if (document.querySelectorAll('[data-test="leaderboard-slide"]').length > 0) { // needs maintainance
7175                    return 'Leaderboard';
7176                } else {
7177                    return false;
7178                }
7179            }
7180        } catch (error) {
7181            console.log(error);
7182            return 'error';
7183        }
7184    }
7185
7186    function handleChallenge(challengeType) {
7187        // Implement logic to handle different challenge types
7188        // This function should encapsulate the logic for each challenge type
7189        if (challengeType === 'Challenge Speak' || challengeType === 'Listen Match' || challengeType === 'Listen Speak') {
7190            const buttonSkip = document.querySelector('button[data-test="player-skip"]');
7191            buttonSkip?.click();
7192        } else if (challengeType === 'Challenge Choice' || challengeType === 'Challenge Choice with Text Input') {
7193            // Text input
7194            if (challengeType === 'Challenge Choice with Text Input') {
7195                let elm = document.querySelectorAll('[data-test="challenge-text-input"]')[0];
7196                let nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
7197                nativeInputValueSetter.call(elm, window.sol.correctSolutions ? window.sol.correctSolutions[0].split(/(?<=^\S+)\s/)[1] : (window.sol.displayTokens ? window.sol.displayTokens.find(t => t.isBlank).text : window.sol.prompt));
7198                let inputEvent = new Event('input', {
7199                    bubbles: true
7200                });
7201
7202                elm.dispatchEvent(inputEvent);
7203            } else if (challengeType === 'Challenge Choice') {
7204                document.querySelectorAll("[data-test='challenge-choice']")[window.sol.correctIndex].click();
7205            }
7206
7207        } else if (challengeType === 'Pairs') {
7208            let nl = document.querySelectorAll('[data-test*="challenge-tap-token"]:not(span)');
7209            if (document.querySelectorAll('[data-test="challenge-tap-token-text"]').length === nl.length) {
7210                window.sol.pairs?.forEach((pair) => {
7211                    for (let i = 0; i < nl.length; i++) {
7212                        const nlInnerText = nl[i].querySelector('[data-test="challenge-tap-token-text"]').innerText.toLowerCase().trim();
7213
7214                        try {
7215                            if (
7216                                (
7217                                    nlInnerText === pair.transliteration.toLowerCase().trim() ||
7218                                    nlInnerText === pair.character.toLowerCase().trim()
7219                                )
7220                                && !nl[i].disabled
7221                            ) {
7222                                nl[i].click()
7223                            }
7224                        } catch (TypeError) {
7225                            if (
7226                                (
7227                                    nlInnerText === pair.learningToken.toLowerCase().trim() ||
7228                                    nlInnerText === pair.fromToken.toLowerCase().trim()
7229                                )
7230                                && !nl[i].disabled
7231                            ) {
7232                                nl[i].click()
7233                            }
7234                        }
7235                    }
7236                })
7237            }
7238
7239        } else if (challengeType === 'Story Pairs') {
7240            const nl = document.querySelectorAll('[data-test*="challenge-tap-token"]:not(span)');
7241            const textElements = document.querySelectorAll('[data-test="challenge-tap-token-text"]');
7242
7243            const textToElementMap = new Map();
7244            for (let i = 0; i < nl.length; i++) {
7245                const text = textElements[i].innerText.toLowerCase().trim();
7246                textToElementMap.set(text, nl[i]);
7247            }
7248
7249            for (const key in window.sol.dictionary) {
7250                if (window.sol.dictionary.hasOwnProperty(key)) {
7251                    const value = window.sol.dictionary[key];
7252                    const keyPart = key.split(":")[1].toLowerCase().trim();
7253                    const normalizedValue = value.toLowerCase().trim();
7254
7255                    const element1 = textToElementMap.get(keyPart);
7256                    const element2 = textToElementMap.get(normalizedValue);
7257
7258                    if (element1 && !element1.disabled) element1.click();
7259                    if (element2 && !element2.disabled) element2.click();
7260                }
7261            }
7262
7263        } else if (challengeType === 'Tap Complete Table') {
7264            solveTapCompleteTable();
7265
7266        } else if (challengeType === 'Tokens Run') {
7267            correctTokensRun();
7268
7269        } else if (challengeType === 'Indices Run') {
7270            correctIndicesRun();
7271
7272        } else if (challengeType === 'Fill in the Gap') {
7273            correctIndicesRun();
7274
7275        } else if (challengeType === 'Challenge Text Input') {
7276            let elm = document.querySelectorAll('[data-test="challenge-text-input"]')[0];
7277            let nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
7278            nativeInputValueSetter.call(elm, window.sol.correctSolutions ? window.sol.correctSolutions[0] : (window.sol.displayTokens ? window.sol.displayTokens.find(t => t.isBlank).text : window.sol.prompt));
7279            let inputEvent = new Event('input', {
7280                bubbles: true
7281            });
7282
7283            elm.dispatchEvent(inputEvent);
7284
7285        } else if (challengeType === 'Partial Reverse') {
7286            let elm = document.querySelector('[data-test*="challenge-partialReverseTranslate"]')?.querySelector("span[contenteditable]");
7287            let nativeInputNodeTextSetter = Object.getOwnPropertyDescriptor(Node.prototype, "textContent").set
7288            nativeInputNodeTextSetter.call(elm, window.sol?.displayTokens?.filter(t => t.isBlank)?.map(t => t.text)?.join()?.replaceAll(',', ''));
7289            let inputEvent = new Event('input', {
7290                bubbles: true
7291            });
7292
7293            elm.dispatchEvent(inputEvent);
7294
7295        } else if (challengeType === 'Challenge Translate Input') {
7296            const elm = document.querySelector('textarea[data-test="challenge-translate-input"]');
7297            const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set;
7298            nativeInputValueSetter.call(elm, window.sol.correctSolutions ? window.sol.correctSolutions[0] : window.sol.prompt);
7299
7300            let inputEvent = new Event('input', {
7301                bubbles: true
7302            });
7303
7304            elm.dispatchEvent(inputEvent);
7305        } else if (challengeType === 'Challenge Name') {
7306
7307            let articles = findReact(document.getElementsByClassName(findReactMainElementClass)[0]).props.currentChallenge.articles;
7308            let correctSolutions = findReact(document.getElementsByClassName(findReactMainElementClass)[0]).props.currentChallenge.correctSolutions[0];
7309
7310            let matchingArticle = articles.find(article => correctSolutions.startsWith(article));
7311            let matchingIndex = matchingArticle !== undefined ? articles.indexOf(matchingArticle) : null;
7312            let remainingValue = correctSolutions.substring(matchingArticle.length);
7313
7314            let selectedElement = document.querySelector(`[data-test="challenge-choice"]:nth-child(${matchingIndex + 1})`);
7315            if (selectedElement) {
7316                selectedElement.click();
7317            }
7318
7319            let elm = document.querySelector('[data-test="challenge-text-input"]');
7320            let nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
7321            nativeInputValueSetter.call(elm, remainingValue);
7322            let inputEvent = new Event('input', {
7323                bubbles: true
7324            });
7325
7326            elm.dispatchEvent(inputEvent);
7327        } else if (challengeType === 'Type Cloze') {
7328            const input = document.querySelector('input[type="text"].b4jqk');
7329            if (!input) return;
7330
7331            let targetToken = window.sol.displayTokens.find(t => t.damageStart !== undefined);
7332            let correctWord = targetToken?.text || "";
7333
7334            let correctEnding = "";
7335            if (typeof targetToken?.damageStart === "number") {
7336                correctEnding = correctWord.slice(targetToken.damageStart);
7337            }
7338
7339            const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
7340            nativeInputValueSetter.call(input, correctEnding);
7341
7342            input.dispatchEvent(new Event("input", { bubbles: true }));
7343            input.dispatchEvent(new Event("change", { bubbles: true }));
7344        } else if (challengeType === 'Type Cloze Table') {
7345            const tableRows = document.querySelectorAll('tbody tr');
7346
7347            window.sol.displayTableTokens.slice(1).forEach((rowTokens, i) => {
7348                const answerCell = rowTokens[1]?.find(t => typeof t.damageStart === "number");
7349
7350                if (answerCell && tableRows[i]) {
7351                    const input = tableRows[i].querySelector('input[type="text"].b4jqk');
7352                    if (!input) return;
7353
7354                    const correctWord = answerCell.text;
7355                    const correctEnding = correctWord.slice(answerCell.damageStart);
7356
7357                    const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
7358                    nativeInputValueSetter.call(input, correctEnding);
7359
7360                    input.dispatchEvent(new Event("input", { bubbles: true }));
7361                    input.dispatchEvent(new Event("change", { bubbles: true }));
7362                }
7363            });
7364        } else if (challengeType === 'Tap Cloze Table') {
7365            const tableRows = document.querySelectorAll('tbody tr');
7366
7367            window.sol.displayTableTokens.slice(1).forEach((rowTokens, i) => {
7368                const answerCell = rowTokens[1]?.find(t => typeof t.damageStart === "number");
7369                if (!answerCell || !tableRows[i]) return;
7370
7371                const wordBank = document.querySelector('[data-test="word-bank"], .eSgkc');
7372                const wordButtons = wordBank ? Array.from(wordBank.querySelectorAll('button[data-test*="challenge-tap-token"]:not([aria-disabled="true"])')) : [];
7373
7374                const correctWord = answerCell.text;
7375                const correctEnding = correctWord.slice(answerCell.damageStart);
7376
7377                let endingMatched = "";
7378                let used = new Set();
7379                for (let btn of wordButtons) {
7380                    if (!correctEnding.startsWith(endingMatched + btn.innerText)) continue;
7381                    btn.click();
7382                    endingMatched += btn.innerText;
7383                    used.add(btn);
7384                    if (endingMatched === correctEnding) break;
7385                }
7386            });
7387        } else if (challengeType === 'Type Complete Table') {
7388            const tableRows = document.querySelectorAll('tbody tr');
7389
7390            window.sol.displayTableTokens.slice(1).forEach((rowTokens, i) => {
7391                const answerCell = rowTokens[1]?.find(t => t.isBlank);
7392                if (!answerCell || !tableRows[i]) return;
7393
7394                const input = tableRows[i].querySelector('input[type="text"].b4jqk');
7395                if (!input) return;
7396
7397                const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
7398                nativeInputValueSetter.call(input, answerCell.text);
7399
7400                input.dispatchEvent(new Event("input", { bubbles: true }));
7401                input.dispatchEvent(new Event("change", { bubbles: true }));
7402            });
7403        } else if (challengeType === 'Pattern Tap Complete') {
7404            const wordBank = document.querySelector('[data-test="word-bank"], .eSgkc');
7405            if (!wordBank) return;
7406
7407            const choices = window.sol.choices;
7408            const correctIndex = window.sol.correctIndex ?? 0;
7409            const correctText = choices[correctIndex];
7410
7411            const buttons = Array.from(wordBank.querySelectorAll('button[data-test*="challenge-tap-token"]:not([aria-disabled="true"])'));
7412            const targetButton = buttons.find(btn => btn.innerText.trim() === correctText);
7413
7414            if (targetButton) {
7415                targetButton.click();
7416            }
7417        } else if (challengeType === 'Session Complete') {
7418        } else if (challengeType === 'Story Arrange') {
7419            let choices = document.querySelectorAll('[data-test*="challenge-tap-token"]:not(span)');
7420            for (let i = 0; i < window.sol.phraseOrder.length; i++) {
7421                choices[window.sol.phraseOrder[i]].click();
7422            }
7423        } else if (challengeType === 'Story Multiple Choice') {
7424            let choices = document.querySelectorAll('[data-test="stories-choice"]');
7425            choices[window.sol.correctAnswerIndex].click();
7426        } else if (challengeType === 'Story Point to Phrase') {
7427            let choices = document.querySelectorAll('[data-test="challenge-tap-token-text"]');
7428            var correctIndex = -1;
7429            for (let i = 0; i < window.sol.parts.length; i++) {
7430                if (window.sol.parts[i].selectable === true) {
7431                    correctIndex += 1;
7432                    if (window.sol.correctAnswerIndex === i) {
7433                        choices[correctIndex].parentElement.click();
7434                    }
7435                }
7436            }
7437        }
7438    }
7439
7440    function correctTokensRun() {
7441        const all_tokens = document.querySelectorAll('[data-test$="challenge-tap-token"]');
7442        const correct_tokens = window.sol.correctTokens;
7443        const clicked_tokens = [];
7444
7445        correct_tokens.forEach(correct_token => {
7446            const matching_elements = Array.from(all_tokens).filter(element => element.textContent.trim() === correct_token.trim());
7447            if (matching_elements.length > 0) {
7448                const match_index = clicked_tokens.filter(token => token.textContent.trim() === correct_token.trim()).length;
7449                if (match_index < matching_elements.length) {
7450                    matching_elements[match_index].click();
7451                    clicked_tokens.push(matching_elements[match_index]);
7452                } else {
7453                    clicked_tokens.push(matching_elements[0]);
7454                }
7455            }
7456        });
7457    }
7458
7459
7460    function correctIndicesRun() {
7461        if (window.sol.correctIndices) {
7462            window.sol.correctIndices?.forEach(index => {
7463                document.querySelectorAll('div[data-test="word-bank"] [data-test*="challenge-tap-token"]:not(span)')[index].click();
7464            });
7465        }
7466    }
7467
7468    function solveTapCompleteTable() {
7469        const solutionRows = window.sol.displayTableTokens.slice(1);
7470
7471        const tableRowElements = document.querySelectorAll('tbody tr');
7472
7473        const wordBank = document.querySelector('div[data-test="word-bank"]');
7474        const wordBankButtons = wordBank ? wordBank.querySelectorAll('button[data-test*="-challenge-tap-token"]') : [];
7475
7476        const usedWordBankIndexes = new Set();
7477
7478        solutionRows.forEach((solutionRow, rowIndex) => {
7479            const answerCellData = solutionRow[1];
7480
7481            const correctToken = answerCellData.find(token => token.isBlank);
7482
7483            if (correctToken) {
7484                const correctAnswerText = correctToken.text;
7485                const currentRowElement = tableRowElements[rowIndex];
7486
7487                let buttons = currentRowElement.querySelectorAll('button[data-test*="-challenge-tap-token"]');
7488                let clicked = false;
7489
7490                if (buttons.length > 0) {
7491                    for (let button of buttons) {
7492                        const buttonTextElm = button.querySelector('[data-test="challenge-tap-token-text"]');
7493                        if (buttonTextElm && buttonTextElm.innerText.trim() === correctAnswerText && !button.disabled) {
7494                            button.click();
7495                            clicked = true;
7496                            break;
7497                        }
7498                    }
7499                }
7500
7501                if (!clicked && wordBankButtons.length > 0) {
7502                    for (let i = 0; i < wordBankButtons.length; i++) {
7503                        if (usedWordBankIndexes.has(i)) continue;
7504
7505                        const button = wordBankButtons[i];
7506                        const buttonTextElm = button.querySelector('[data-test="challenge-tap-token-text"]');
7507                        if (buttonTextElm && buttonTextElm.innerText.trim() === correctAnswerText && !button.disabled) {
7508                            button.click();
7509                            usedWordBankIndexes.add(i);
7510                            break;
7511                        }
7512                    }
7513                }
7514            }
7515        });
7516    }
7517
7518    function findSubReact(dom, traverseUp = reactTraverseUp) {
7519        const key = Object.keys(dom).find(key => key.startsWith("__reactProps"));
7520        return dom?.[key]?.children?.props?.slide;
7521    }
7522
7523    function findReact(dom, traverseUp = reactTraverseUp) {
7524        const key = Object.keys(dom).find(key => {
7525            return key.startsWith("__reactFiber$") // react 17+
7526                || key.startsWith("__reactInternalInstance$"); // react <17
7527        });
7528        const domFiber = dom[key];
7529        if (domFiber == null) return null;
7530        // react <16
7531        if (domFiber._currentElement) {
7532            let compFiber = domFiber._currentElement._owner;
7533            for (let i = 0; i < traverseUp; i++) {
7534                compFiber = compFiber._currentElement._owner;
7535            }
7536            return compFiber._instance;
7537        }
7538        // react 16+
7539        const GetCompFiber = fiber => {
7540            //return fiber._debugOwner; // this also works, but is __DEV__ only
7541            let parentFiber = fiber.return;
7542            while (typeof parentFiber.type == "string") {
7543                parentFiber = parentFiber.return;
7544            }
7545            return parentFiber;
7546        };
7547        let compFiber = GetCompFiber(domFiber);
7548        for (let i = 0; i < traverseUp; i++) {
7549            compFiber = GetCompFiber(compFiber);
7550        }
7551        return compFiber.stateNode;
7552    }
7553
7554    window.findReact = findReact;
7555    window.findSubReact = findSubReact;
7556    window.ss = solving;
7557}
7558
7559try {
7560    if (false) {
7561        if (storageLocal.languagePackVersion !== "00") {
7562            if (!storageLocal.languagePack.hasOwnProperty(systemLanguage)) systemLanguage = "en";
7563            systemText = storageLocal.languagePack;
7564            One();
7565        } else {
7566            systemLanguage = "en";
7567            One();
7568        }
7569    } else {
7570        systemLanguage = "en";
7571        One();
7572    }
7573} catch (error) {
7574    console.log(error);
7575    One();
7576}
7577
Duolingo PRO | Robomonkey