// ==UserScript== // @name Auto-Duolingo // @version 1.0.9 // @author DevX // @namespace http://tampermonkey.net/ // @description [LITE] Auto solve lessons, auto farm XP, hack Streaks, Gems and more! Hacking Duolingo is so easy! // @description:vi [LITE] Tự động giải bài học, tự động farm XP, hack chuỗi Streaks, Gems và nhiều hơn thế! Hack Duolingo thật dễ dàng! // @description:fr [LITE] Résolvez automatiquement les leçons, gagnez de l'XP, piratez les séries, les gemmes et plus encore ! Pirater Duolingo est si facile ! // @description:es [LITE] Resuelve automáticamente las lecciones, farmea XP, hackea rachas, gemas y más. ¡Hackear Duolingo es muy fácil! // @description:de [LITE] Lektionen automatisch lösen, XP farmen, Serien, Edelsteine und mehr hacken! Duolingo zu hacken ist so einfach! // @description:it [LITE] Risolvi automaticamente le lezioni, accumula XP, hacka serie, gemme e altro ancora! Hackerare Duolingo è così facile! // @description:ja [LITE] レッスンを自動で解き、XPを稼ぎ、連続日数やジェムなどをハック!Duolingoをハッキングするのはとても簡単です! // @description:ko [LITE] 자동으로 레슨을 풀고, XP를 모으며, 연속 학습, 보석 등을 해킹! Duolingo 해킹은 아주 쉽습니다! // @description:ru [LITE] Автоматическое решение уроков, фарминг XP, взлом серий, драгоценностей и многого другого! Взломать Duolingo так легко! // @description:zh-CN [LITE] 自动完成课程,自动刷XP,破解连续天数、宝石等!黑掉Duolingo就是这么简单! // @match https://*.duolingo.com/* // @match https://*.duolingo.cn/* // @grant none // @license MIT // @icon https://autoduo.site/assets/imgs/favicon.ico // @downloadURL none // ==/UserScript== (() => { const AUTODUOLINGO_STORAGE = "autoDuolingoStorage"; const { isSafeMode, isShowUI, isAnimationOff, exp, time, version, isNewNotify, rmNotiVer, rmNotiContent } = getSession(); const { notifyVersion } = getLocal(AUTODUOLINGO_STORAGE); const autoDuoLite = { initSignature: function () { this.signatureElm = document.createElement("div"); Object.assign(this.signatureElm, { className: "signature-listening", innerHTML: `
Chat with DevX
Telegram Community
Youtube Channel
Facebook Community
Greasy Fork
`, }); }, initContactModal: function () { const admList = [ { name: 'THUẬN THIÊN', role: 'Supporter', avatar: 'thuanthien.jpg', bio: 'If you have difficulties upgrading versions, obtaining activation keys, or have any questions while using AutoDuo, please contact me for assistance!', contact: { fb: 'https://www.facebook.com/share/1B8gdn7DFu/', tele: 'https://t.me/Thien22092008', } }, { name: 'DEVX', role: 'Developer', avatar: 'devx.jpg', bio: 'If you need to purchase long-term activation keys or upgrade key levels, please contact me!', contact: { fb: 'https://www.facebook.com/autoduofamily/', tele: 'https://t.me/imdevx', } }, ] this.contactModal = document.createElement('div') Object.assign(this.contactModal, { className: 'contact-modal', innerHTML: ` ` }) const closeModalBtn = this.contactModal.querySelector('.close-contact-modal') closeModalBtn.addEventListener('click', () => { this.contactModal.remove() }) }, initPopup: function () { this.updateGuidePopup = document.createElement("div"); Object.assign(this.updateGuidePopup, { className: "update-guide-popup", innerHTML: `This is a lite version of AutoDuo with the main feature of automatically farming listening exercises (requires Super Duolingo). To use auto, follow the steps below:
Step 1: Go to the Super workout page (with the dumbbell icon).
Step 2: Press the "Start Farm XP" button to start the automatic farming process!.
Note: Super Duolingo is required to use this version. If you want to auto or use all the other useful features without Super, click Upgrade version and follow the instructions!
SUPPORT'
this.contactBtn.addEventListener('click', () => {
document.body.appendChild(this.contactModal)
})
this.footerContainer.append(this.autoduoPowered, this.contactBtn)
this.autoContainer = document.createElement("div");
this.autoContainer.className = "auto-container-listening";
this.autoContainer.append(
this.statistic,
this.functionWrapper,
this.settingBtn,
this.autoBtn,
this.updateBtn
);
this.overlayContainer = document.createElement("div");
this.overlayContainer.className = "overlay-listening";
this.controlContainer = document.createElement("div");
this.controlContainer.className = "control-container-listening";
this.controlContainer.append(this.autoContainer, this.contactWrapper, this.footerContainer);
this.bubbleContainer = document.createElement("div");
this.bubbleContainer.className = "bubble-container-listening";
this.bubbleContainer.append(this.marketerBubble, this.superBubble, this.notifyBubble);
document.body.append(this.controlContainer, this.bubbleContainer);
},
fetchNoti: async function () {
try {
const res = await (
await fetch("https://api.autoduo.site/super/data/notify/?c7f54a73e6340a16176=91bf0d18b83")
)?.json();
if (res?.code === 200) {
const { notifyVersion: rmVersion, notifyContent: rmContent } = res.data[0];
setDataSession({
isNewNotify: (this.isNewNotify = +rmVersion > this.notifyVersion),
rmNotiVer: (this.rmNotiVer = +rmVersion),
rmNotiContent: (this.rmNotiContent = rmContent.replaceAll("\\n", "\n")),
});
this.setNoti();
}
} catch (e) {}
},
setNoti: function () {
if (!this.rmNotiVer) {
return;
}
if (this.isNewNotify) {
this.notifyBubble.classList.add("new");
}
this.notifyBubble.addEventListener("click", () => {
if (this.isNewNotify) {
this.notifyBubble.classList.remove("new");
setDataSession("isNewNotify", (this.isNewNotify = false));
setDataLocal("notifyVersion", this.rmNotiVer);
}
window.alert(this.rmNotiContent);
});
},
handleShowHideUI: function (isSave = false) {
if (this.isShowUI) {
this.showHideBtn.classList.remove("hide");
document.body.append(this.controlContainer, this.signatureElm, this.bubbleContainer);
} else {
this.showHideBtn.classList.add("hide");
this.controlContainer.remove();
this.signatureElm.remove();
this.bubbleContainer.remove();
}
if (isSave) {
setDataSession("isShowUI", this.isShowUI);
this.controlContainer.classList.contains("autoduo-animate") ||
this.controlContainer.classList.add("autoduo-animate");
}
},
handleAnimationOff: function (isSave = false) {
this.isAnimationOff
? document.head.appendChild(this.animationStyle)
: document.head.removeChild(this.animationStyle);
isSave && setDataSession("isAnimationOff", this.isAnimationOff);
},
handleSafeModeOn: function () {
this.safeModeWrapper.setAutoduoSwitch(this.setSafeMode(true));
},
handleSafeModeOff: function () {
this.safeModeWrapper.setAutoduoSwitch(this.setSafeMode(false));
},
start: function () {
if (this.isAuto || this.isAutoRunning) {
return;
}
document.body.appendChild(this.overlayContainer);
this.isAuto = true;
this.autoBtn.classList.add("running");
this.autoBtn.innerText = "STOP FARM XP";
setDataSession("isBasicAuto", this.isAuto);
this.startTm = Date.now();
this.handleLocation();
},
stop: function () {
if (!this.isAuto || this.isLegendMode) {
return;
}
document.body.removeChild(this.overlayContainer);
this.isAuto = false;
this.autoBtn.classList.remove("running");
this.autoBtn.innerText = "START FARM XP";
setDataSession("isBasicAuto", this.isAuto);
},
handleLocation: function () {
if (!this.isAuto) {
return;
}
const currentPath = window.location.pathname;
switch (currentPath) {
case this.practiceHubPath:
this.goPracticeHubChallenge();
break;
case this.listeningPacticePath:
this.handlePracticeHubChallenge();
break;
default:
this.autoduoError(
"[Inappropriate location]: Only enable auto when on the practice page (with the dumbbell icon) of Duolingo Super!" +
"\n- Enabling auto on Duolingo Super's practice page will automatically farm listening exercises (20 XP)." +
"\n- Upgrade to the full version of Auto-Duolingo to use auto farming and many other useful features without needing Super Duolingo!"
, true);
break;
}
},
goPracticeHubChallenge: function () {
if (this.isAuto === false) {
return;
}
const challengeBtn = $(
'img[src="https://d35aaqx5ub95lt.cloudfront.net/images/practiceHub/2ebe830fd55a7f2754d371bcd79faf32.svg"]'
);
if (!challengeBtn) {
setTimeout(this.goPracticeHubChallenge.bind(this), 1000);
return;
}
challengeBtn.click();
setTimeout(this.handlePracticeHubChallenge.bind(this), 1000);
},
handlePracticeHubChallenge: function () {
if (window.location.pathname === this.practiceHubPath) {
this.goPracticeHubChallenge();
return;
}
// Flag:BETA
const challengeWrapper = $(".wqSzE");
if (challengeWrapper) {
this.getDataStateNode(challengeWrapper);
this.next();
return;
}
const nextActiveBtn = $('[data-test="player-next"][aria-disabled="false"]');
if (nextActiveBtn) {
this.next();
return;
}
setTimeout(this.handlePracticeHubChallenge.bind(this), 1000);
},
handleChallenge: async function () {
if (this.isSafeMode) {
await this.sleep(1000);
}
if (!this.isAuto || this.isAutoRunning) {
return;
}
const challengeTypeElm = $('[data-test*="challenge challenge"]');
if (!challengeTypeElm) {
return this.autoduoError("Undefined challenge!!");
}
const challengeType = challengeTypeElm.dataset.test?.split(' ')[1]
this.setAutoRunning(true);
switch (challengeType) {
case "challenge-listenTap":
this.handleChallengeTranslate();
break;
case "challenge-gapFill":
case "challenge-listenIsolation":
case "challenge-assist":
case "challenge-selectTranscription":
case "challenge-characterIntro":
case "challenge-characterSelect":
case "challenge-selectPronunciation":
case "challenge-dialogue":
case "challenge-readComprehension":
case "challenge-listenComprehension":
case "challenge-select":
case "challenge-form":
case "challenge-definition":
case "challenge-sameDifferent":
this.handleChallengeChoice();
break;
default:
this.autoduoError(
"This exercise is not currently supported in this version. Try updating to the full version of Auto-Duolingo and try again!"
);
break;
}
},
handleChallengeTranslate: function () {
if (this.isAuto === false) {
return;
}
let data = this.getData("correctTokens");
if (this.isAuto === false) {
return;
}
if (!data?.length) {
data = this.getData(["challengeResponseTrackingProperties", "best_solution"])?.split(" ");
}
if (!data) {
return this.autoduoError("Lesson data not found.");
}
const textArea = $('textarea[data-test="challenge-translate-input"]:not([disabled])');
if (textArea) {
const toggleKeyboard = $('[data-test="player-toggle-keyboard"]');
if (toggleKeyboard) {
toggleKeyboard.click();
return setTimeout(this.handleChallengeTranslate.bind(this), 500);
}
const inputEvent = new Event("input", {
bubbles: true,
});
let answer = "";
const inputCaseHandler = () => {
setTimeout(() => {
if (data.length === 0) {
this.setAutoRunning(false);
this.next(true);
return;
}
answer += " " + data.shift();
this.nativeTextareaValueSetter.call(textArea, answer);
textArea.dispatchEvent(inputEvent);
inputCaseHandler();
}, this.rmSafeDlTm());
};
inputCaseHandler();
return;
}
// Flag:BETA
let options = arr($$('button[data-test*="challenge-tap-token"]'));
if (options.length === 0) {
return setTimeout(this.handleChallengeTranslate.bind(this), 500);
}
const getIndexOfOption = (targetData) => {
const index = options.findIndex((option) => option.textContent === targetData);
return index;
};
const selectCaseHandler = () => {
setTimeout(() => {
if (data.length === 0) {
this.setAutoRunning(false);
this.next(true);
return;
}
const firstValue = data.shift();
const index = getIndexOfOption(firstValue);
if (index === -1) {
return this.autoduoLessonError("No suitable option found.");
}
options[index].click();
options.splice(index, 1);
selectCaseHandler();
}, this.rmSafeDlTm());
};
selectCaseHandler();
},
handleChallengeChoice: function () {
if (!this.isAuto) {
return;
}
const optionElm = $$('[data-test="challenge-choice"]');
const correctIndex = this.getData("correctIndex");
if (correctIndex === null) {
return this.autoduoError("Lesson data not found.");
}
setTimeout(() => {
optionElm[correctIndex].click();
setTimeout(() => {
this.setAutoRunning(false);
this.next();
}, this.rmSafeDlTm());
}, this.rmSafeDlTm());
},
next: function () {
if (!this.isAuto) {
return;
}
// Flag:BETA
const expWrapper = $('[class="_1XNQX"]');
if (expWrapper) {
const exp = this.getExp(expWrapper);
if (exp !== undefined) {
this.exp += exp;
this.expElm.innerText = this.exp;
const timeNow = Date.now();
const finishTime = timeNow - this.startTm;
this.totalTime += finishTime;
this.startTm = timeNow;
this.renderTime();
setDataSession({
exp: this.exp,
time: this.totalTime,
});
const currentPath = window.location.pathname;
if (currentPath === this.listeningPacticePath) {
if ((this.totalReloadTime += finishTime) >= this.reloadTm) {
window.location.reload();
return;
}
}
}
}
const nextBtn = $('[data-test="player-next"]');
if (!nextBtn) {
setTimeout(this.handleLocation.bind(this), this.goChallengeTm);
return;
}
const isDisabled = nextBtn.getAttribute("aria-disabled") === "true";
const isFullProgress = !!$('[aria-valuenow="1"]');
if (isDisabled && !isFullProgress) {
boom(this.handleChallenge.bind(this));
return;
}
!isDisabled && nextBtn.click();
boom(this.next.bind(this));
},
findReactProps: function (wrapperElm) {
this.reactProps = Object.keys(wrapperElm).find((key) => key.startsWith("__reactProps"));
if (!this.reactProps) {
return this.autoduoError("ERROR");
}
},
getDataStateNode: function (wrapperElm) {
this.reactProps === null && this.findReactProps(wrapperElm);
const childrenData = wrapperElm?.[this.reactProps]?.children;
if (Array.isArray(childrenData)) {
this.dataStateNode = childrenData?.[0]?._owner?.stateNode;
} else {
this.dataStateNode = childrenData?._owner?.stateNode;
}
},
getData: function (subGenealogy) {
const currentChallenge = this.dataStateNode?.props?.currentChallenge;
if (!currentChallenge) {
return this.autoduoError("There was an error while loading challenge data!");
}
if (Array.isArray(subGenealogy)) {
const result = subGenealogy.reduce((acc, currentKey) => {
if (acc === null) {
return null;
}
const currentValue = acc[currentKey];
return currentValue || null;
}, currentChallenge);
if (result === null) {
return this.autoduoError("There was an error while getting the data!");
}
return Array.isArray(result) ? [...result] : result;
} else {
const result = currentChallenge[subGenealogy];
return Array.isArray(result) ? [...result] : result;
}
},
getExp: function (expWrapper) {
const keys = Object.keys(expWrapper);
const key = keys.find((key) => key.startsWith("__reactProps"));
const exp = expWrapper?.[key]?.children?.props?.slide?.xpGoalSessionProgress?.totalXpThisSession;
return exp;
},
renderTime: function () {
const timeString = timeFormat(this.totalTime);
this.dateElm.innerText = timeString;
},
setAutoRunning: function (isRunning) {
this.isAutoRunning = isRunning;
},
setSafeMode: function (isSafeMode) {
this.isSafeMode = isSafeMode;
setDataSession("isSafeMode", isSafeMode);
return isSafeMode;
},
rmSafeDlTm: function () {
if (!this.isSafeMode) {
return 0;
}
return Math.floor(Math.random() * 900 + 300);
},
sleep: async function (time) {
await new Promise((resolve) => setTimeout(resolve, time));
},
autoduoError: function (message = '', native = false) {
this.isAutoRunning && this.setAutoRunning(false);
this.isAuto && this.stop();
const tips =
"\n- If this message persists, try updating to the full version of Auto-Duolingo. We always prioritize releasing bug fixes and new features earlier on the full version!";
native ? alert(message + tips) : alert("ERROR: " + message + tips);
},
autoduoLessonError: function (errorText) {
// Flag:BETA
const settingIcon = $("._2VEsk");
if (settingIcon) {
settingIcon.click();
return setTimeout(() => {
this.autoduoError(
`${errorText}. If you are currently displaying the pronunciation guide, please turn it off first, then reload the page, and finally turn on auto again!`
);
}, 800);
}
return this.autoduoError(errorText);
},
autoduoCreateSwitch: function (descriptionText = "", wrapperElm, id, isChecked, handleSwitch) {
const infoElm = document.createElement("i");
Object.assign(infoElm, {
className: "switch-info-listening",
title: "Detail",
onclick: () => {
alert(descriptionText);
},
});
const checkboxElm = document.createElement("input");
Object.assign(checkboxElm, {
type: "checkbox",
hidden: true,
checked: isChecked,
});
const setSwitch = (isEnable) => {
checkboxElm.checked = isEnable;
};
const labelElm = document.createElement("label");
labelElm.addEventListener("click", () => {
id > 3 ? notAvailable() : handleSwitch(setSwitch);
});
const switchContainer = document.createElement("div");
switchContainer.className = "switch-container-listening";
switchContainer.append(infoElm, checkboxElm, labelElm);
wrapperElm.classList.add("switch-wrapper-listening");
if (id > 3) {
wrapperElm.classList.add("unavailable");
}
wrapperElm.append(switchContainer);
wrapperElm.setAutoduoSwitch = setSwitch;
},
autoduoCheckUpdate: async function () {
let rmVersion =
version || (await (await fetch("https://api.autoduo.site/lite/version/"))?.json())?.version;
if (this.version !== rmVersion) {
$("#greasyfork").classList.add("has-update");
$("#greasyfork .popup").innerText = "A new updated version is available!";
}
if (!version) {
setDataSession("version", rmVersion);
}
},
initStyle: function () {
this.animationStyle = document.createElement("style");
this.animationStyle.innerHTML = `
img, svg, canvas {
visibility: hidden !important;
}
:is(
.control-container-listening,
.contact-modal
) :is(img, svg, canvas) {
visibility: initial !important;
}
div
:not(.autoduo-animate)
:not(.setting-overlay-listening)
:not(.contact-modal)
:not(.contact-modal *)
{
transition: none !important;
animation-duration: 0s !important;
}
.fSJFz {
display: none !important;
}
`;
const listenStyle = document.createElement("style");
listenStyle.innerHTML = `
@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap');
:root{
--autoduo-bg: 255,255,255;
--autoduo-color: 75,75,75;
--autoduo-h-color: 0,159,235;
--autoduo-sky-color: 0,160,190;
--gradient-bg: linear-gradient(0deg, #FFDEE9 0%, #B5FFFC 100%);
--modal-shadow: rgba(var(--autoduo-color), 0.3) 0px 0px 28px 0px, rgba(var(--autoduo-color), 0.3) 0px 2px 6px 2px;
}
:root[data-duo-theme="dark"]{
--autoduo-bg: 19,31,36;
--autoduo-color: 241,247,251;
--autoduo-h-color: 241,247,251;
--autoduo-black-color: 255,255,255;
--gradient-bg: linear-gradient(135deg, #3b3b3b 0%, #000000 100%);
}
.control-container-listening{
position: fixed;
z-index: 9999999;
left: 20px;
bottom: 75px;
padding: 12px 10px;
border: 2px dotted #00b3c1;
border-radius: 20px;
box-shadow: rgba(14, 30, 37, 0.12) 0px 2px 4px 0px, rgba(14, 30, 37, 0.32) 0px 2px 16px 0px;
background-color: rgba(var(--autoduo-bg), 0.4);
backdrop-filter: blur(4px);
}
.autoduo-animate{
animation: autoduo-control-eff .15s;
}
.autoduo-animate::after{
animation: autoduo-control-border-eff .35s .12s backwards;
}
@keyframes autoduo-control-eff {
from {
transform: scale(.8);
opacity: .5;
}
to {
transform: scale(1);
opacity: 1;
}
}
@keyframes autoduo-control-border-eff {
from {
transform: scale(1);
opacity: 1;
}
to {
transform: scale(1.15);
opacity: 0;
}
}
.control-container-listening::after{
content: '';
position: absolute;
z-index: -1;
inset: 0;
border-radius: inherit;
background-color: transparent;
box-shadow: rgb(104 149 199 / 50%) 0px 0px 0px 5px;
opacity: 0;
}
.footer-container {
position: absolute;
top: calc(100% + 8px);
left: 4px;
right: 8px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
}
.contact-btn {
display: flex;
align-items: center;
padding-top: 4px;
border: 2px solid #1CB0F6;
border-radius: 50px;
background-color: #DDF4FF;
color: #0085c4;
cursor: pointer;
transition: 300ms;
}
.contact-btn:hover {
filter: brightness(0.8);
}
.autoduo-powered a {
display: inline-block;
color: #1cb0f6;
font-weight: 700;
transition: all 0.25s;
}
.autoduo-powered a:hover {
color: #d555ff;
text-decoration: underline;
transform: scale(1.1);
}
.auto-container-listening{
width: 250px !important;
}
.setting-overlay-listening {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
padding: inherit;
padding-bottom: 20px;
border-radius: inherit;
backdrop-filter: inherit;
background-color: rgba(var(--autoduo-bg), 0.8);
animation: setting-overlay-eff 0.4s;
}
@keyframes setting-overlay-eff {
from {
opacity: 0;
transform: perspective(450px) rotateY(-90deg);
}
to {
opacity: 1;
transform: perspective(450px) rotateY(0deg);
}
}
.setting-overlay-listening h3 {
padding: 8px 0 12px 0;
text-align: center;
text-transform: uppercase;
}
.setting-function-listening{
flex-grow: 1;
}
.setting-function-listening .switch-wrapper-listening {
margin-bottom: 11px;
font-weight: bold;
color: #ff4e00;
}
.close-setting-btn-listening {
width: 80%;
margin: 0 auto;
}
.autoduo-btn {
display: flex;
justify-content: center;
align-items: center;
position: relative;
height: 46px;
margin-bottom: 4px;
background-color: transparent;
color: rgb(var(--autoduo-bg));
border: none;
border-radius: 16px;
text-transform: uppercase;
letter-spacing: 1px;
font-weight: bold;
font-size: 15px;
cursor: pointer;
user-select: none;
}
.autoduo-btn::before {
content: '';
position: absolute;
inset: 0;
z-index: -1;
background-color: #1cb0f6;
color: rgb(25, 132, 183);
border-radius: inherit;
box-shadow: 0 4px 0;
}
.autoduo-btn:hover {
filter: brightness(1.1);
}
.autoduo-btn:active {
transform: translateY(4px);
}
.autoduo-btn:active::before {
box-shadow: none;
}
.btn-green::before {
background-color: #58CC02;
color: rgb(81, 151, 4);
}
.btn-red::before {
background-color: #FF4B4B;
color: rgb(234,43,43);
}
button.setting-btn-listening {
width: 100% !important;
margin-top: 10px;
}
button.setting-btn-listening::before {
background-image: url(https://autoduo.site/assets/clients/setting.svg);
background-repeat: no-repeat;
background-size: 22px;
background-position: 18px;
}
button.auto-farm-btn-listening{
width: 100% !important;
margin-top: 8px;
}
button.auto-farm-btn-listening::before {
background-image: url(https://autoduo.site/assets/clients/xp.svg);
background-repeat: no-repeat;
background-size: 32px;
background-position: 12px;
}
button.auto-farm-btn-listening.running::before {
background-color: #FF4B4B;
color: rgb(234,43,43);
}
.statistic-listening {
color: rgb(var(--autoduo-color));
font-size: 18px;
font-weight: bold;
}
.statistic-listening p{
margin-bottom: 8px;
}
.statistic-listening > p::before{
display: inline-block;
min-width: 60px;
}
.statistic-wrapper-listening{
display: flex;
justify-content: space-between;
margin: 16px 0;
}
.time-listening, .total-exp-listening{
display: flex;
align-items: center;
margin-bottom: 0 !important;
}
.time-listening::before,
.total-exp-listening::before{
content: '';
width: 21px;
height: 21px;
margin-right: 4px;
background-image: url('https://autoduo.site/assets/clients/clock.svg');
background-size: cover;
}
.total-exp-listening::before{
width: 16px;
height: 21px;
background-image: url('https://autoduo.site/assets/clients/exp.svg');
}
.total-exp-listening::after{
content: 'XP';
margin-left: 4px;
}
.guide-btn-listening{
width: 100%;
margin-top: 8px;
}
.guide-btn-listening::before{
background-image: url('https://autoduo.site/assets/clients/twinkle.ndx');
background-size: 85px auto;
}
.notify-bubble-listening::before {
background-image: url('https://autoduo.site/assets/clients/notify-icon-lite.png');
}
.super-bubble-listening::before {
background-image: url('https://autoduo.site/assets/clients/superfree-icon.png');
}
.full-bubble-listening::before {
background-image: url('https://autoduo.site/assets/clients/upgrade.png'), url('https://autoduo.site/assets/clients/marketer.webp');
background-size: 26px, 250% !important;
background-position: center;
background-repeat: no-repeat;
}
.bubble-container-listening {
position: fixed;
z-index: 99999;
right: 8px;
bottom: 69px;
display: flex;
flex-direction: column;
}
.bubble-item-listening + .bubble-item-listening {
margin-top: 16px;
}
.bubble-item-listening {
position: relative;
width: 48px;
height: 48px;
border-radius: 50%;
border: 1px solid #ccc;
background-color: #ffffff40;
backdrop-filter: blur(4px);
box-shadow: rgba(0, 0, 0, 0.25) 0px 0.0625em 0.0625em, rgba(0, 0, 0, 0.25) 0px 0.125em 0.5em, rgba(255, 255, 255, 0.1) 0px 0px 0px 1px inset;
cursor: pointer;
}
.bubble-item-listening:hover {
filter: brightness(0.9);
}
.bubble-item-listening::before,
.bubble-item-listening::after {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
pointer-events: none;
}
.bubble-item-listening::before {
background-size: cover;
}
.bubble-item-listening::after {
display: none;
border: 1px solid #009febdb;
box-shadow: 2px 2px 5px #ccc, -2px -2px 5px #ccc;
animation: notify-border-eff 2s infinite;
}
.bubble-item-listening.new {
animation: notify-eff 2s infinite;
}
.bubble-item-listening.new::before {
animation: notify-bell-eff 2s infinite;
}
.bubble-item-listening.new::after {
display: block;
}
@keyframes notify-border-eff {
70% {
transform: scale(1.6);
opacity: 0.1;
}
100% {
transform: scale(1.6);
opacity: 0;
}
}
@keyframes notify-eff {
0%, 75%, 100% {
transform: scale(1);
}
10% {
transform: scale(1.1);
}
}
@keyframes notify-bell-eff {
5%, 15% {
transform: rotate(25deg);
}
10%, 20% {
transform: rotate(-25deg);
}
25%, 100% {
transform: rotate(0deg);
}
}
.signature-listening{
position: fixed;
z-index: 99999999;
top: 4px;
left: 50%;
transform: translateX(-50%);
color: rgb(var(--autoduo-h-color));
background-color: rgba(255, 255, 255, .5);
font-style: italic;
font-size: 15px;
font-weight: 700;
padding: 2px 8px;
border-radius: 8px;
width: max-content;
display: flex;
align-items: center;
}
.signature-listening::before{
content: '';
width: 50px;
height: 50px;
background-image: url(https://autoduo.site/assets/clients/autoduosuperThumb.ndx);
background-size: cover;
margin: -4px 0;
margin-right: 4px;
}
.autoduo-lite-version{
display: flex;
justify-content: center;
margin-top: 2px;
position: relative;
font-size: 13px;
font-style: normal;
text-align: center;
}
.autoduo-upgrade {
margin-left: 6px;
margin-top: -4px;
width: 22px;
height: 22px;
border: none;
background-color: transparent;
background: url('https://autoduo.site/assets/clients/upgrade.png');
background-size: cover;
transition: transform 0.3s;
}
.autoduo-upgrade:hover {
transform: scale(1.2);
cursor: pointer;
}
.key-type-listening {
text-align: center;
}
.show-hide-listening{
position: fixed;
right: 8px;
top: 50%;
transform: translateY(-50%);
z-index: 99999999;
padding: 0;
width: 50px;
height: 50px;
border-radius: 50%;
color: rgb(var(--autoduo-h-color));
background-color: #00DBDE;
background-image: linear-gradient(90deg, #00DBDE 0%, #FC00FF 100%);
border: 2px solid currentColor;
display: flex;
justify-content: center;
align-items: center;
font-size: 32px;
padding-top: 2px;
cursor: pointer;
}
.show-hide-listening.vip::before{
content: '';
position: absolute;
inset: 0;
background-image: url('https://autoduo.site/assets/clients/vipCircle.ndx');
background-size: cover;
transform: scale(1.2);
}
.show-hide-listening::after{
content: var(--data-version);
position: absolute;
left: 50%;
bottom: 0;
transform: translate(-50%, 130%);
font-size: 15px;
font-weight: bold;
}
.show-hide-listening.older::after{
text-decoration: line-through;
}
.show-hide-listening i {
position: relative;
flex-shrink: 0;
width: 35px;
height: 35px;
background-image: url('https://autoduo.site/assets/clients/eye.svg');
background-size: cover;
}
.show-hide-listening.hide i::after{
content: '';
position: absolute;
top: 50%;
left: 0;
width: 110%;
height: 5px;
transform: rotate(45deg) translateX(-3px);
background-color: #c0efff;
border-radius: 7px;
}
.overlay-listening{
position: fixed;
inset: 0;
z-index: 9999
}
.switch-wrapper-listening{
display: flex;
align-items: center;
margin-bottom: 8px;
}
.switch-wrapper-listening::before{
content: var(--data-name);
}
.switch-wrapper-listening.disable{
opacity: .4;
pointer-events: none !important;
user-select: none !important;
-ms-user-select: none !important;
-moz-user-select: none !important;
-webkit-user-select: none !important;
}
.switch-wrapper-listening.unavailable{
color: #808080;
}
.switch-wrapper-listening.unavailable label{
opacity: .6;
}
.switch-container-listening{
flex-grow: 1;
display: flex;
justify-content: space-between;
align-items: center;
}
.switch-info-listening{
width: 18px;
height: 18px;
margin-left: 4px;
margin-right: 8px;
border-radius: 50%;
background-image: url('https://autoduo.site/assets/clients/infomation-icon.ndx');
background-size: cover;
cursor: pointer;
}
.switch-info-listening:hover{
filter: brightness(0.8);
}
.switch-wrapper-listening label{
position: relative;
width: 46px;
height: 24px;
background-color: #bbb;
box-shadow: rgb(104 149 199 / 50%) 0px 0px 0px 3px;
border-radius: 20px;
transition: .2s;
}
.switch-wrapper-listening label::after{
content: '';
position: absolute;
left: 2px;
top: 2px;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: white;
transition: .2s;
}
.switch-wrapper-listening input:checked + label{
background-color: #1FC2FF;
}
.switch-wrapper-listening input:checked + label::after {
left: 24px;
}
.function-wrapper-listening{
font-weight: bold;
font-size: 18px;
color: #ff4e00;
}
.contact-wrapper-listening{
display: flex;
justify-content: center;
flex-wrap: wrap;
margin: 10px 0 -4px 0;
}
.contact-item-listening{
position: relative;
width: 34px;
height: 34px;
margin: 2px 4px;
border-radius: 50%;
background-image: var(--data-img);
background-size: cover;
transition: .12s;
color: rgb(var(--autoduo-color));
}
.contact-item-listening:hover{
box-shadow: rgb(104 149 199 / 50%) 0px 0px 0px 3px;
transform: scale(1.11);
}
.contact-item-listening:hover .popup {
display: block;
}
.contact-item-listening .popup {
display: none;
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
margin-bottom: 12px;
padding: 2px 6px;
width: max-content;
font-size: 12px;
font-weight: bold;
border: 1px solid #ccc;
border-radius: 6px;
background-color: rgb(var(--autoduo-bg));
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 2px 6px 2px;
animation: contact-popup-eff 0.2s;
}
@keyframes contact-popup-eff {
from {
opacity: 0;
bottom: 50%;
}
to {
opacity: 1;
bottom: 100%;
}
}
@keyframes contact-popup-update-eff {
0%, 100% {
transform: translateY(3px)
}
50% {
transform: translateY(-3px)
}
}
@keyframes spin-eff {
0% {
transform: scale(var(--scale)) rotate(0deg);
}
100% {
transform: scale(var(--scale)) rotate(360deg);
}
}
.contact-item-listening .popup::before{
content: '';
position: absolute;
top: calc(100% - 2px);
left: 50%;
transform: translateX(-50%);
border: 10px solid transparent;
border-top-color: rgb(var(--autoduo-bg));
}
.contact-item-listening.has-update {
transform: scale(1.11) !important;
box-shadow: rgb(117 117 117 / 50%) 0px 0px 0px 3px;
}
.contact-item-listening.has-update::before {
content: '';
--scale: 1.05;
position: absolute;
inset: 0;
border-radius: 50%;
border: 2px solid white;
border-top-color: transparent;
border-bottom-color: transparent;
animation: spin-eff 1.1s linear infinite;
}
.contact-item-listening.has-update .popup{
display: block !important;
transform: unset;
right: -70%;
left: unset;
animation: contact-popup-update-eff 1.2s infinite;
}
.contact-item-listening.has-update .popup::before {
left: 75%;
transform: unset;
}
.control-container-listening.vip .contact-item-listening:hover{
box-shadow: rgb(199 138 217 / 50%) 0px 0px 0px 3px;
}
.update-guide-popup {
position: fixed;
inset: 0;
z-index: 99999999;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.4);
backdrop-filter: blur(4px);
box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px;
animation: popup-overlay-eff 0.25s;
}
.guide-popup-main * {
font-family: "Nunito", sans-serif;
}
.guide-popup-main {
display: flex;
flex-direction: column;
width: 480px;
margin: 4px;
background-color: #009ee9;
border: 2px solid #fff;
border-radius: 20px;
overflow: hidden;
animation: popup-main-eff 0.25s;
}
.guide-popup-title {
text-align: center;
padding: 14px 8px 10px 8px;
margin: 0;
color: white;
font-size: 22px;
}
.guide-popup-content {
flex-grow: 1;
padding: 20px 16px;
text-align: justify;
background-color: rgb(var(--autoduo-bg));
border-top-left-radius: 18px;
border-top-right-radius: 18px;
font-size: 15px;
}
.guide-popup-text {
line-height: 1.3;
color: rgb(var(--autoduo-color));
margin-bottom: 8px;
}
.guide-popup-btn {
display: flex;
justify-content: space-between;
margin-top: 26px;
}
.guide-popup-btn .autoduo-btn {
z-index: 1;
width: calc(40% - 4px);
}
.guide-popup-btn .autoduo-btn:last-child {
width: calc(60% - 4px);
}
.guide-popup-btn .autoduo-btn:last-child::before {
background-image: url(https://autoduo.site/assets/clients/video-icon.png);
background-size: 30px;
background-position: 16px center;
background-repeat: no-repeat;
}
.guide-popup-btn .autoduo-btn span {
margin-bottom: -4px;
}
.contact-modal * {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: "Nunito", sans-serif;
}
.contact-modal {
position: fixed;
z-index: 999999999999999999;
inset: 0;
display: flex;
padding: 4px;
background-color: rgba(0, 0, 0, 0.2);
animation: fade-in 0.2s linear;
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.contact-modal .contact-modal-inner {
position: relative;
width: 100%;
height: fit-content;
inset: initial;
animation: autoduo-control-eff 0.3s;
display: flex;
flex-direction: column;
max-width: 500px;
max-height: 100%;
margin: auto;
padding: 12px;
overflow: hidden;
border: 1px dashed rgb(var(--autoduo-h-color));
background-image: var(--gradient-bg);
box-shadow: var(--modal-shadow);
border-radius: 12px;
font-size: 16px;
line-height: 16px;
color: rgb(var(--autoduo-black-color))
}
.contact-modal h3 {
text-align: center;
}
.contact-modal h3 span {
font-size: 24px;
font-weight: 800;
line-height: 28px;
background-image: linear-gradient(90deg, red, orange, #00d800, #00bbff, #ff02c0, violet);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
.contact-modal-inner > * {
flex-shrink: 0;
}
.contact-modal header {
padding-bottom: 10px;
}
.contact-modal footer {
padding-top: 28px;
}
.contact-modal-inner .body {
flex-grow: 1;
flex-shrink: 1 !important;
overflow: overlay;
}
.contact-modal-inner .adm-item {
padding: 20px 0;
text-align: center;
font-size: 14px;
}
.contact-modal-inner .adm-item + .adm-item {
border-top: 1px dashed rgb(var(--autoduo-color));
}
.contact-modal-inner .adm-bio {
position: relative;
padding: 8px;
max-width: 420px;
margin: 0 auto;
margin-bottom: 16px;
border: 1px solid rgb(var(--autoduo-color));
border-radius: 20px;
text-align: left;
font-style: italic;
}
.contact-modal-inner .adm-bio::after {
content: '';
position: absolute;
top: 100%;
left: calc(50% - 39px);
border: 8px solid rgb(var(--autoduo-color));
border-left: 14px solid transparent;
border-bottom: 4px solid transparent;
border-bottom-right-radius: 4px;
transform: skewX(10deg);
}
.contact-modal-inner .adm-avatar {
width: 65px;
height: 65px;
margin: 6px 0 12px 0;
border-radius: 50%;
border: 3px solid rgb(var(--autoduo-sky-color));
object-fit: cover;
}
.adm-role {
margin-top: 6px;
font-style: italic;
}
.adm-contact {
margin-top: 12px;
gap: 6px;
}
.adm-contact .contact-item-listening {
width: 30px;
height: 30px;
}
.close-contact-modal {
z-index: 1;
min-width: 120px;
margin: 0 auto;
}
@keyframes popup-overlay-eff {
from {
opacity: 0;
}
to{
opacity: 1;
}
}
@keyframes popup-main-eff {
from {
transform: scale(0.5);
}
to{
transform: scale(1);
}
}
@media (max-height: 550px) {
.control-container-listening {
bottom: 4px;
}
}
@media (max-width: 320px) {
.guide-popup-btn .autoduo-btn {
width: 100% !important;
margin-top: 4px;
}
.guide-popup-btn {
flex-direction: column-reverse;
}
}
`;
document.head.appendChild(listenStyle);
const tm = +notAvailable("MjAw");
window.boom = (cb) => {
if (Number.isNaN(tm)) return;
setTimeout(cb, tm);
};
},
setup: function () {
this.initStyle();
this.initSignature();
this.initContact();
this.initContactModal();
this.initPopup();
this.initBtn();
this.initBubbles();
this.initStatistics();
this.initFunctions();
this.initSetting();
this.initContainer();
!isShowUI && this.handleShowHideUI();
isAnimationOff && this.handleAnimationOff();
this.renderTime();
getDataSession("isBasicAuto") && this.start();
this.autoduoCheckUpdate();
this.rmNotiVer ? this.setNoti() : this.fetchNoti();
},
version: "1.0.9",
isAuto: false,
isAutoRunning: false,
isSafeMode: !!isSafeMode,
isAnimationOff: !!isAnimationOff,
goChallengeTm: 500,
reloadTm: 1800000,
startTm: null,
isShowUI: isShowUI === undefined || isShowUI,
exp: exp || 0,
totalTime: time || 0,
practiceHubPath: "/practice-hub",
listeningPacticePath: "/practice-hub/listening-practice",
lessonWrapper: "._3js2_",
reactProps: null,
dataStateNode: null,
nativeTextareaValueSetter: Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set,
isDarkMode: document.documentElement.getAttribute("data-duo-theme") === "dark",
notifyVersion: +notifyVersion || 0,
isNewNotify: isNewNotify,
rmNotiVer: rmNotiVer,
rmNotiContent: rmNotiContent,
};
function timeFormat(ms) {
const h = String(parseInt(ms / 1000 / 60 / 60));
const m = String(parseInt((ms / 1000 / 60) % 60));
return `${h.padStart(2, "0")}h:${m.padStart(2, "0")}m`;
}
function notAvailable(str) {
try {
return str
? atob(str)
: window.alert(
"The current functionality is not available! To use this feature, please update to the full version of Auto-Duolingo!"
);
} catch (e) {
autoDuoLite.start = () => {};
}
}
const $ = document.querySelector.bind(document);
const $$ = document.querySelectorAll.bind(document);
const arr = (nodeList) => {
return Array.from(nodeList);
};
function getSession() {
const dataStorage = sessionStorage.getItem(AUTODUOLINGO_STORAGE) || "{}";
return JSON.parse(dataStorage);
}
function setDataSession(key, value) {
const dataStorage = getSession();
if (key instanceof Object) {
Object.assign(dataStorage, key);
} else {
dataStorage[key] = value;
}
sessionStorage.setItem(AUTODUOLINGO_STORAGE, JSON.stringify(dataStorage));
}
function getDataSession(key) {
const dataStorage = getSession();
return dataStorage[key];
}
function getLocal(STORAGE_KEY) {
const dataStorage = localStorage.getItem(STORAGE_KEY) || "{}";
try {
return JSON.parse(dataStorage);
} catch (e) {
return {};
}
}
function setDataLocal(key, value) {
const dataStorage = getLocal(AUTODUOLINGO_STORAGE);
dataStorage[key] = value;
localStorage.setItem(AUTODUOLINGO_STORAGE, JSON.stringify(dataStorage));
}
autoDuoLite.setup();
})();