// ==UserScript== // @name Duolingo Pro BETA // @namespace Violentmonkey Scripts // @match https://*.duolingo.com/* // @grant GM_log // @version 2.0B1 // @author anonymoushackerIV // @description Duolingo Auto-Solver Tool - WORKING AUGUST 2023 // @license MIT // @downloadURL none // ==/UserScript== //localStorage.getItem("someVarKey"); let solvingIntervalId; let isAutoMode = false; isAutoMode = Boolean(sessionStorage.getItem('isAutoMode')); const debug = false; let numberOfTimes = 0; numberOfTimes = Number(sessionStorage.getItem('numberOfTimes')); let isStartButtonPressed = false; isStartButtonPressed = Boolean(sessionStorage.getItem('isStartButtonPressed')); let onboardingDone; if (Boolean(localStorage.getItem("onboardingDone")) === false) { console.log('onboardingDone False'); } else if (Boolean(localStorage.getItem("onboardingDone")) === true) { console.log('onboardingDone True'); } else { console.log('onboardingDone Set to false'); onboardingDone = false; Boolean(localStorage.setItem("onboardingDone", onboardingDone)); } //...all your existing c const onBoardingHTML = `

Welcome to

v2.0 BETA 1

Duolingo

I

Pro

Solve, a better Skip button

Stuck somewhere and want to see the answer? Press Solve to only solve that question.

Solve All, skip the whole hustle

A steak saver and a leaderboard champion. Solve All let’s you finish the whole lesson without the hard work.

AutoSolver Box, full automation (BETA)

AutoSolver Box enables you to set a certain amount of lessons you want completed, then mutes your tab, both sounds and visuals until it’s done.

More coming soon

Many bug fixes, support for more languages and lessons are coming, as well as a dedicated app that will put your steak and leaderboard position at safe hold, without you needing to sign in everyday.

CONTINUE

`; function injectOnBoardingHTML() { // Creating a container for the overlay if (Boolean(localStorage.getItem("onboardingDone")) === false) { const containerOnBoarding = document.createElement('div'); containerOnBoarding.innerHTML = onBoardingHTML; document.body.appendChild(containerOnBoarding); } else { console.log('idk check'); } } //setTimeout(injectOnBoardingHTML, 1000); injectOnBoardingHTML(); function onBoardingButton() { if (Boolean(localStorage.getItem("onboardingDone")) === false) { const onBoardingContinueButton = document.querySelector('.BoxOneTwoButtonOne'); console.log('continue pressed'); onBoardingContinueButton.addEventListener('click', () => { console.log('continue registered'); onboardingDone = true; localStorage.setItem("onboardingDone", onboardingDone); window.location.reload(); }); } else { console.log('idk check again'); } } onBoardingButton(); if (window.location.href.includes('duolingo.com/learn')) { // HTML content const htmlContent = `

Stories are not supported yet

Chests can’t open automatically

AutoSolver

v2.0 BETA 1

How many lessons would you like to AutoSolve?

0
`; // CSS content const cssContent = ` .boxFirst { display: inline-flex; flex-direction: column; align-items: flex-end; gap: 16px; position: fixed; /* Fix the position to the bottom-right corner */ bottom: 24px; right: 24px; z-index:2; } .ContactButton { position: relative; min-width: 50px; width: height; font-size: 17px; border: none; border: 2px solid rgb(var(--color-swan)); border-bottom: 4px solid rgb(var(--color-swan)); border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: rgb(var(--color-snow)); color: rgb(var(--color-eel)); text-align: center; cursor: pointer; height: 50px; } .ContactButton:hover { position: relative; min-width: 50px; font-size: 17px; border: none; border: 2px solid rgb(var(--color-swan)); border-bottom: 4px solid rgb(var(--color-swan)); border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: rgb(var(--color-snow)); color: rgb(var(--color-eel)); text-align: center; cursor: pointer; height: 50px; filter: brightness(0.9); } .ContactButton:active { position: relative; min-width: 50px; font-size: 17px; border: none; border: 2px solid rgb(var(--color-swan)); border-bottom: 2px solid rgb(var(--color-swan)); border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: rgb(var(--color-snow)); color: rgb(var(--color-eel)); text-align: center; cursor: pointer; height: 48px; filter: brightness(0.9); } .boxOne { padding: 16px; background-color: rgb(var(--color-snow)); border-radius: 16px; width: 300px; border: 2px solid rgb(var(--color-swan)); } .BoxOutside { height: 100%; width: 100%; margin-right: 20px; } .BetaTagAlert { display: flex; justify-content: space-between; align-items: center; align-self: stretch; padding-bottom: 10px; } .BETATagSpaceText { color: rgb(var(--color-eel)); font-size: 25px; font-style: normal; font-weight: 700; line-height: 100%; /* 50px */ margin-top: 0px; margin-bottom: 0px; } .BETATag { display: flex; padding: 10px; flex-direction: column; justify-content: center; align-items: center; border-radius: 12.5px; background: #FF4B4B; } .BETATagText {color: #FFF; font-style: normal; font-weight: 700; line-height: normal; margin-top: 0px; margin-bottom: 0px; } .BoxInsideAlert { display: inline-flex; align-items: center; gap: 5px; height: 18px; padding-bottom: 16px; } .AutoBoxAlertIcon { width: 20px; height: 18px; } .AutoBoxAlertText { color: #FF4B4B; font-weight: 700; height: 18px; margin-top: 16px; } .AutoBoxAlertTwo { display: inline-flex; align-items: center; gap: 5px; height: 18px; padding-bottom: 24px; padding-top: 16px; } .AutoBoxAlertTwoIcon { width: 20px; height: 20px; } .AutoBoxAlertTwoText { color: #FFC800; font-weight: 700; height: 18px; margin-top: 16px; } .AutoBoxExplanation { color: rgb(var(--color-eel)); margin-top: -0px; } .AutoBoxExplanation { color: rgb(var(--color-eel)); margin-top: -0px; height: 30px; font-weight: 700; } .BoxInside { height: 100%; width: 100%; display: flex; margin-right: 20px; } .button-down { position: relative; min-width: 50px; width: height; font-size: 17px; border: none; border-bottom: 4px solid #168DC5; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); text-align: center; cursor: pointer; } .button-down:hover { position: relative; min-width: 50px; width: height; font-size: 17px; border: none; border-bottom: 4px solid #168DC5; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); text-align: center; cursor: pointer; filter: brightness(1.1); } .button-down:active { position: relative; min-width: 50px; width: height; font-size: 17px; border: none; border-bottom: 0px solid #168DC5; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); text-align: center; cursor: pointer; margin-top: 4px; filter: brightness(1.1); } .ticker { position: relative; min-width: 100px; width: 100%; font-size: 17px; border: none; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: rgb(var(--color-swan)); color: rgb(var(--color-eel)); margin-left: 10px; text-align: center; } .button-up { position: relative; min-width: 50px; width: height; font-size: 17px; border: none; border-bottom: 4px solid #168DC5; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); margin-left: 10px; text-align: center; cursor: pointer; } .button-up:hover { position: relative; min-width: 50px; width: height; font-size: 17px; border: none; border-bottom: 4px solid #168DC5; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); margin-left: 10px; text-align: center; cursor: pointer; filter: brightness(1.1); } .button-up:active { position: relative; min-width: 50px; width: height; font-size: 17px; border: none; border-bottom: 0px solid #168DC5; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); margin-left: 10px; text-align: center; cursor: pointer; margin-top: 4px; filter: brightness(1.1); } .StartToolWithValue { position: relative; min-width: 150px; width: calc(100% - 0px); font-size: 17px; border: none; border-bottom: 4px solid #168DC5; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); margin-top: 10px; text-align: center; cursor: pointer; } .StartToolWithValue:hover { position: relative; min-width: 150px; width: calc(100% - 0px); font-size: 17px; border: none; border-bottom: 4px solid #168DC5; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); margin-top: 10px; text-align: center; cursor: pointer; filter: brightness(1.1); } .StartToolWithValue:active { position: relative; min-width: 150px; width: calc(100% - 0px); font-size: 17px; border: none; border-bottom: 0px solid #168DC5; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); text-align: center; cursor: pointer; margin-top: 14px; filter: brightness(1.1); } `; // Function to inject HTML and CSS into the document let injectedContainer = null; let injectedStyleElement = null; function injectContent() { // Check if the current URL matches the target URL if (window.location.href === 'https://preview.duolingo.com/learn' || window.location.href === 'https://duolingo.com/learn') { //console.log('tageturlmatches') // Inject the content if it's not already injected if (!injectedContainer) { // Creating a container for the overlay injectedContainer = document.createElement('div'); injectedContainer.innerHTML = htmlContent; document.body.appendChild(injectedContainer); // Creating a style tag for CSS injectedStyleElement = document.createElement('style'); injectedStyleElement.type = 'text/css'; injectedStyleElement.innerHTML = cssContent; document.head.appendChild(injectedStyleElement); } } else { //console.log('tageturlnotmatches') // Remove the content if it was previously injected if (injectedContainer) { document.body.removeChild(injectedContainer); document.head.removeChild(injectedStyleElement); injectedContainer = null; injectedStyleElement = null; } } } // Check the URL and inject/remove content every 1 second setInterval(injectContent, 1000); // Function to initialize JavaScript functionality function initialize() { const ticker = document.querySelector('.ticker'); const buttonUp = document.querySelector('.button-up'); const buttonDown = document.querySelector('.button-down'); const solveFastButton = document.querySelector('.StartToolWithValue'); solveFastButton.addEventListener('click', () => { sessionStorage.setItem('isAutoMode', true); sessionStorage.setItem('numberOfTimes', numberOfTimes); isStartButtonPressed = true; sessionStorage.setItem('isStartButtonPressed', true); isAutoMode = true; }); buttonUp.addEventListener('click', () => { numberOfTimes++; ticker.textContent = numberOfTimes; sessionStorage.setItem('numberOfTimes', numberOfTimes); }); buttonDown.addEventListener('click', () => { numberOfTimes--; if (numberOfTimes < 0) { numberOfTimes = 0; } ticker.textContent = numberOfTimes; sessionStorage.setItem('numberOfTimes', numberOfTimes); }); console.log(isAutoMode) } // Calling the functions to inject content and initialize functionality injectContent(); initialize(); } const muteButtonHTML = `
`; const muteButtonCSS = ` .TopBoxPart { display: inline-flex; gap: 16px; flex-direction: column; position: fixed; align-items: flex-end; top: 100px; right: 16px; z-index: 2; } .SettingsButtonOne { min-width: 50px; width: height; font-size: 17px; border: none; border: 2px solid rgb(var(--color-swan)); border-bottom: 4px solid rgb(var(--color-swan)); border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: rgb(var(--color-snow)); color: rgb(var(--color-eel)); text-align: center; cursor: pointer; height: 50px; } .SettingsButtonOne:hover { position: relative; min-width: 50px; width: height; font-size: 17px; border: none; border: 2px solid rgb(var(--color-swan)); border-bottom: 4px solid rgb(var(--color-swan)); border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: rgb(var(--color-snow)); color: rgb(var(--color-eel)); text-align: center; cursor: pointer; height: 50px; filter: brightness(0.9); } .SettingsButtonOne:active { position: relative; min-width: 50px; font-size: 17px; border: none; border: 2px solid rgb(var(--color-swan)); border-bottom: 2px solid rgb(var(--color-swan)); border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: rgb(var(--color-snow)); color: rgb(var(--color-eel)); text-align: center; cursor: pointer; height: 48px; margin-top: 2px; filter: brightness(0.9); } .MuteAllDuolingoSounds { min-width: 50px; width: height; font-size: 17px; border: none; border: 2px solid rgb(var(--color-swan)); border-bottom: 4px solid rgb(var(--color-swan)); border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: rgb(var(--color-snow)); color: rgb(var(--color-eel)); text-align: center; cursor: pointer; height: 50px; } .MuteAllDuolingoSounds:hover { position: relative; min-width: 50px; width: height; font-size: 17px; border: none; border: 2px solid rgb(var(--color-swan)); border-bottom: 4px solid rgb(var(--color-swan)); border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: rgb(var(--color-snow)); color: rgb(var(--color-eel)); text-align: center; cursor: pointer; height: 50px; filter: brightness(0.9); } .MuteAllDuolingoSounds:active { position: relative; min-width: 50px; font-size: 17px; border: none; border: 2px solid rgb(var(--color-swan)); border-bottom: 2px solid rgb(var(--color-swan)); border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: rgb(var(--color-snow)); color: rgb(var(--color-eel)); text-align: center; cursor: pointer; height: 48px; margin-top: 2px; filter: brightness(0.9); } `; function injectMuteButton() { const injectedMuteButtonContainer = document.createElement('div'); injectedMuteButtonContainer.innerHTML = muteButtonHTML; document.body.appendChild(injectedMuteButtonContainer); // Creating a style tag for CSS const injectedMuteButtonStyle = document.createElement('style'); injectedMuteButtonStyle.type = 'text/css'; injectedMuteButtonStyle.innerHTML = muteButtonCSS; document.head.appendChild(injectedMuteButtonStyle); console.log('injected mute button'); } injectMuteButton(); window.document.querySelector('.MuteAllDuolingoSounds').onclick = function() { function muteAudioElements(doc) { var audioElements = doc.getElementsByTagName('audio'); for (var i = 0; i < audioElements.length; i++) { audioElements[i].muted = !audioElements[i].muted; } } // Mute audio elements in the main document. muteAudioElements(window.document); // Mute audio elements inside iframes. var iframes = window.document.getElementsByTagName('iframe'); for (var i = 0; i < iframes.length; i++) { try { muteAudioElements(iframes[i].contentDocument); } catch (e) { console.error('Unable to access iframe content:', e); } } // Update the button text. this.textContent = this.textContent === 'UNDER CONSTRUCTION' ? 'MUTE SOUND' : 'UNDER CONSTRUCTION'; }; function checkDomainAndCallSolving() { console.log('checking domain'); // Get the current URL. const currentUrl = window.location.href; // Check if the domain of the current URL includes "duolingo.com/lesson" or "duolingo.com/unit". const domain = currentUrl; const isDuolingoLessonOrUnit = domain.includes("duolingo.com/lesson") || domain.includes("duolingo.com/unit") || domain.includes("duolingo.com/practice"); console.log(isDuolingoLessonOrUnit); // If the domain is a Duolingo lesson or unit, and the let value is true, call the solving function. if(Boolean(isDuolingoLessonOrUnit) && Boolean(isAutoMode)) { console.log('checked domain true'); setTimeout(solving, 6000); } else { console.log('shouldnt happen ' + domain); } } // Add the checkDomainAndCallSolving function to the window.onload event listener. window.onload = setTimeout(checkDomainAndCallSolving, 2000); function checkAutoMode() { if(isAutoMode === true) { console.log('smth'); console.log(numberOfTimes); } else { console.log('wdf'); } } setInterval(checkAutoMode, 1000); //testing function checkUrl() { const currentUrl = window.location.href; const mainUrls = [ 'http://duolingo.com', 'https://duolingo.com', 'duolingo.com', 'duolingo.com/learn', 'http://duolingo.com/learn', 'https://duolingo.com/learn', 'http://preview.duolingo.com', 'https://preview.duolingo.com', 'preview.duolingo.com', 'preview.duolingo.com/learn', 'http://preview.duolingo.com/learn', 'https://preview.duolingo.com/learn', ]; const currentOrigin = window.location.origin; try { if(mainUrls.includes(currentUrl) && isAutoMode && numberOfTimes > 0 && isStartButtonPressed === true) { window.location.href = currentOrigin + '/lesson'; numberOfTimes = numberOfTimes - 1; sessionStorage.setItem('numberOfTimes', numberOfTimes); console.log('hey1'); } if(isStartButtonPressed === true && numberOfTimes === 0) { isStartButtonPressed = false; sessionStorage.setItem('isStartButtonPressed', false); } } catch (error) { console.log('error number 7'); } console.log(currentUrl); console.log('isAutoMode ' + isAutoMode) } setInterval(checkUrl, 1000); //testing function addButtons() { if (window.location.pathname === '/learn') { let button = document.querySelector('a[data-test="global-practice"]'); if (button) { return; //button.click(); } } const solveAllButton = document.getElementById("solveAllButton"); if (solveAllButton !== null) { //solving(); return; } const original = document.querySelectorAll('[data-test="player-next"]')[0]; if (original === undefined) { const startButton = document.querySelector('[data-test="start-button"]'); console.log(`Wrapper line: ${startButton}`); if (startButton === null) { return; } const wrapper = startButton.parentNode; const solveAllButton = document.createElement('a'); solveAllButton.className = startButton.className; solveAllButton.id = "solveAllButton"; solveAllButton.innerText = "COMPLETE SKILL"; solveAllButton.removeAttribute('href'); solveAllButton.addEventListener('click', () => { solving(); setInterval(() => { const startButton = document.querySelector('[data-test="start-button"]'); if (startButton && startButton.innerText.startsWith("START")) { startButton.click(); } }, 3000); startButton.click(); }); wrapper.appendChild(solveAllButton); } else { const wrapper = document.getElementsByClassName('_10vOG')[0]; wrapper.style.display = "flex"; const solveCopy = document.createElement('button'); // const presssolveCopy1 = () => { solveCopy.style.borderBottom = '0px'; solveCopy.style.marginBottom = '4px'; solveCopy.style.top = '4px'; }; // Function to revert the border-bottom when the button is released const releasesolveCopy1 = () => { solveCopy.style.borderBottom = '4px solid #2b70c9'; solveCopy.style.marginBottom = '0px'; solveCopy.style.top = '0px'; }; // Add event listeners for mousedown, mouseup, and mouseleave solveCopy.addEventListener('mousedown', presssolveCopy1); solveCopy.addEventListener('mouseup', releasesolveCopy1); solveCopy.addEventListener('mouseleave', releasesolveCopy1); // const pauseCopy = document.createElement('button'); // const presspauseCopy2 = () => { pauseCopy.style.borderBottom = '0px'; pauseCopy.style.marginBottom = '4px'; pauseCopy.style.top = '4px'; }; // Function to revert the border-bottom when the button is released const releasepauseCopy2 = () => { pauseCopy.style.borderBottom = '4px solid #ff9600'; pauseCopy.style.marginBottom = '0px'; pauseCopy.style.top = '0px'; }; // Add event listeners for mousedown, mouseup, and mouseleave pauseCopy.addEventListener('mousedown', presspauseCopy2); pauseCopy.addEventListener('mouseup', releasepauseCopy2); pauseCopy.addEventListener('mouseleave', releasepauseCopy2); // solveCopy.id = 'solveAllButton'; solveCopy.innerHTML = solvingIntervalId ? 'PAUSE SOLVE' : 'SOLVE ALL'; solveCopy.disabled = false; pauseCopy.innerHTML = 'SOLVE'; const defaultButtonStyle = ` position: relative; min-width: 150px; font-size: 17px; border: none; border-bottom: 4px solid #2b70c9; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); margin-left: 20px; cursor: pointer; `; const solveCopyStyle = ` position: relative; min-width: 150px; font-size: 17px; border: none; border-bottom: 4px solid #2b70c9; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #1cb0f6; color: rgb(var(--color-snow)); margin-left: 20px; cursor: pointer; `; const pauseCopyStyle = ` position: relative; min-width: 100px; font-size: 17px; border: none; border-bottom: 4px solid #ff9600; border-radius: 16px; padding: 13px 16px; transform: translateZ(0); transition: filter .0s; font-weight: 700; letter-spacing: .8px; background: #ffc800; color: rgb(var(--color-snow)); margin-left: 20px; cursor: pointer; `; solveCopy.style.cssText = solveCopyStyle; pauseCopy.style.cssText = pauseCopyStyle; [solveCopy, pauseCopy].forEach(button => { button.addEventListener("mousemove", () => { button.style.filter = "brightness(1.1)"; }); }); [solveCopy, pauseCopy].forEach(button => { button.addEventListener("mouseleave", () => { button.style.filter = "none"; }); }); original.parentElement.appendChild(pauseCopy); original.parentElement.appendChild(solveCopy); solveCopy.addEventListener('click', solving); pauseCopy.addEventListener('click', solve); //solving(); } } setInterval(addButtons, 1000); function solving() { if (solvingIntervalId) { clearInterval(solvingIntervalId); solvingIntervalId = undefined; document.getElementById("solveAllButton").innerText = "SOLVE ALL"; isAutoMode = false; } else { document.getElementById("solveAllButton").innerText = "PAUSE SOLVE"; isAutoMode = true; solvingIntervalId = setInterval(solve, 500); } } function solve() { const selAgain = document.querySelectorAll('[data-test="player-practice-again"]'); const practiceAgain = document.querySelector('[data-test="player-practice-again"]'); if (selAgain.length === 1 && isAutoMode) { // Make sure it's the `practice again` button //if (selAgain[0].innerHTML.toLowerCase() === 'practice again') { // Click the `practice again` button selAgain[0].click(); // Terminate return; //} } if (practiceAgain !== null && isAutoMode) { practiceAgain.click(); return; } try { window.sol = findReact(document.getElementsByClassName('_3FiYg')[0]).props.currentChallenge; } catch { let next = document.querySelector('[data-test="player-next"]'); if (next) { next.click(); } return; } if (!window.sol) { return; } let nextButton = document.querySelector('[data-test="player-next"]'); if (!nextButton) { return; } if (document.querySelectorAll('[data-test*="challenge-speak"]').length > 0) { if (debug) document.getElementById("solveAllButton").innerText = 'Challenge Speak'; const buttonSkip = document.querySelector('button[data-test="player-skip"]'); if (buttonSkip) { buttonSkip.click(); } } else if (window.sol.type === 'listenMatch') { if (debug) document.getElementById("solveAllButton").innerText = 'Listen Match'; console.log('hello'); const nl = document.querySelectorAll('[data-test$="challenge-tap-token"]'); window.sol.pairs?.forEach((pair) => { for (let i = 0; i < nl.length; i++) { let nlInnerText; if (nl[i].querySelectorAll('[data-test="challenge-tap-token-text"]').length > 1) { nlInnerText = nl[i].querySelector('[data-test="challenge-tap-token-text"]').innerText.toLowerCase().trim(); } else { //nlInnerText = findSubReact(nl[i]).textContent.toLowerCase().trim(); nlInnerText = nl[i].getAttribute('data-test').split('-')[0].toLowerCase().trim(); console.log(nlInnerText); } if ( ( nlInnerText === pair.learningWord.toLowerCase().trim() || nlInnerText === pair.translation.toLowerCase().trim() ) && !nl[i].disabled ) { nl[i].click(); } } }); } else if (document.querySelectorAll('[data-test="challenge-choice"]').length > 0) { // choice challenge if (debug) document.getElementById("solveAllButton").innerText = 'Challenge Choice'; if (window.sol.correctTokens !== undefined) { correctTokensRun(); nextButton.click() } else if (window.sol.correctIndex !== undefined) { document.querySelectorAll('[data-test="challenge-choice"]')[window.sol.correctIndex].click(); nextButton.click(); } } else if (document.querySelectorAll('[data-test$="challenge-tap-token"]').length > 0) { // match correct pairs challenge if (window.sol.pairs !== undefined) { if (debug) document.getElementById("solveAllButton").innerText = 'Pairs'; let nl = document.querySelectorAll('[data-test$="challenge-tap-token"]'); if (document.querySelectorAll('[data-test="challenge-tap-token-text"]').length === nl.length) { window.sol.pairs?.forEach((pair) => { for (let i = 0; i < nl.length; i++) { const nlInnerText = nl[i].querySelector('[data-test="challenge-tap-token-text"]').innerText.toLowerCase().trim(); try { if ( ( nlInnerText === pair.transliteration.toLowerCase().trim() || nlInnerText === pair.character.toLowerCase().trim() ) && !nl[i].disabled ) { nl[i].click() } } catch (TypeError) { if ( ( nlInnerText === pair.learningToken.toLowerCase().trim() || nlInnerText === pair.fromToken.toLowerCase().trim() ) && !nl[i].disabled ) { nl[i].click() } } } }) } } else if (window.sol.correctTokens !== undefined) { if (debug) document.getElementById("solveAllButton").innerText = 'Token Run'; correctTokensRun(); nextButton.click() } else if (window.sol.correctIndices !== undefined) { if (debug) document.getElementById("solveAllButton").innerText = 'Indices Run'; correctIndicesRun(); } } else if (document.querySelectorAll('[data-test="challenge-tap-token-text"]').length > 0) { if (debug) document.getElementById("solveAllButton").innerText = 'Challenge Tap Token Text'; // fill the gap challenge correctIndicesRun(); } else if (document.querySelectorAll('[data-test="challenge-text-input"]').length > 0) { if (debug) document.getElementById("solveAllButton").innerText = 'Challenge Text Input'; let elm = document.querySelectorAll('[data-test="challenge-text-input"]')[0]; let nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set; nativeInputValueSetter.call(elm, window.sol.correctSolutions ? window.sol.correctSolutions[0] : (window.sol.displayTokens ? window.sol.displayTokens.find(t => t.isBlank).text : window.sol.prompt)); let inputEvent = new Event('input', { bubbles: true }); elm.dispatchEvent(inputEvent); } else if (document.querySelectorAll('[data-test*="challenge-partialReverseTranslate"]').length > 0) { if (debug) document.getElementById("solveAllButton").innerText = 'Partial Reverse'; let elm = document.querySelector('[data-test*="challenge-partialReverseTranslate"]')?.querySelector("span[contenteditable]"); let nativeInputNodeTextSetter = Object.getOwnPropertyDescriptor(Node.prototype, "textContent").set nativeInputNodeTextSetter.call(elm, '"' + window.sol?.displayTokens?.filter(t => t.isBlank)?.map(t => t.text)?.join()?.replaceAll(',', '') + '"'); let inputEvent = new Event('input', { bubbles: true }); elm.dispatchEvent(inputEvent); } else if (document.querySelectorAll('textarea[data-test="challenge-translate-input"]').length > 0) { if (debug) document.getElementById("solveAllButton").innerText = 'Challenge Translate Input'; const elm = document.querySelector('textarea[data-test="challenge-translate-input"]'); const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set; nativeInputValueSetter.call(elm, window.sol.correctSolutions ? window.sol.correctSolutions[0] : window.sol.prompt); let inputEvent = new Event('input', { bubbles: true }); elm.dispatchEvent(inputEvent); } nextButton.click() } function correctTokensRun() { const all_tokens = document.querySelectorAll('[data-test$="challenge-tap-token"]'); const correct_tokens = window.sol.correctTokens; const clicked_tokens = []; correct_tokens.forEach(correct_token => { const matching_elements = Array.from(all_tokens).filter(element => element.textContent.trim() === correct_token.trim()); if (matching_elements.length > 0) { const match_index = clicked_tokens.filter(token => token.textContent.trim() === correct_token.trim()).length; if (match_index < matching_elements.length) { matching_elements[match_index].click(); clicked_tokens.push(matching_elements[match_index]); } else { clicked_tokens.push(matching_elements[0]); } } }); } function correctIndicesRun() { if (window.sol.correctIndices) { window.sol.correctIndices?.forEach(index => { document.querySelectorAll('div[data-test="word-bank"] [data-test="challenge-tap-token-text"]')[index].click(); }); // nextButton.click(); } } function findSubReact(dom, traverseUp = 0) { const key = Object.keys(dom).find(key => key.startsWith("__reactProps$")); return dom.parentElement[key].children.props; } function findReact(dom, traverseUp = 0) { let reactProps = Object.keys(dom.parentElement).find((key) => key.startsWith("__reactProps$")); while (traverseUp-- > 0 && dom.parentElement) { dom = dom.parentElement; reactProps = Object.keys(dom.parentElement).find((key) => key.startsWith("__reactProps$")); } if(dom?.parentElement?.[reactProps]?.children[0] == null){ return dom?.parentElement?.[reactProps]?.children[1]?._owner?.stateNode; } else{ return dom?.parentElement?.[reactProps]?.children[0]?._owner?.stateNode; } //return dom?.parentElement?.[reactProps]?.children[0]?._owner?.stateNode; } window.findReact = findReact; window.ss = solving;