您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
The more questions you answer the smarter it will get. Features: spelling-assistance & auto - complete, definitions and examples, actively learning bot.
- // ==UserScript==
- // @name Vocabulary.com Answer Bot
- // @namespace http://tampermonkey.net/
- // @version 3.01
- // @description The more questions you answer the smarter it will get. Features: spelling-assistance & auto - complete, definitions and examples, actively learning bot.
- // @author longkidkoolstar
- // @match https://www.vocabulary.com/*
- // @icon https://cdn1.iconfinder.com/data/icons/network-and-comminications-flat-square-rounded-sha/120/content__blog__media__articles__news__management__edit-512.png
- // @license MIT
- // @grant none
- // ==/UserScript==
- let url = window.location.href,list=url.split("/")[4],words_defs,lists,learned=[],incorrect=[],inProgress=false;
- if(localStorage.getItem("lists")!==null){lists = JSON.parse(localStorage.getItem("lists"))}
- else{lists = []}if(localStorage.getItem("words&defs")!==null){words_defs = JSON.parse(localStorage.getItem("words&defs"))}
- else{words_defs = []}if(localStorage.getItem("learned")!==null){learned = JSON.parse(localStorage.getItem("learned"))}
- if(localStorage.getItem("wrong")!==null){incorrect = JSON.parse(localStorage.getItem("wrong"))}
- let dictionary = "https://api.dictionaryapi.dev/api/v2/entries/en/";
- //console.log(list,lists,partsOfList(list,"words"),partsOfList(list,"defs"))
- if(!url.includes("/practice")){
- setInterval(function(){
- if(document.getElementsByClassName("activity practice")[0]!==undefined){
- let practice = document.getElementsByClassName("activity practice")[0];
- if(!lists.includes(list)){
- practice.addEventListener("click",function(){
- let enteries = document.getElementsByClassName("entry");
- for(let i=0;i<enteries.length;i++){
- let word = enteries[i].children[0].innerText.trim();
- let def = enteries[i].children[1].innerText.trim();
- words_defs.push({"word":word,"def":def,"list":list});
- if(enteries.length-1==i){
- localStorage.setItem("words&defs",JSON.stringify(words_defs));
- lists.push(list);
- localStorage.setItem("lists",JSON.stringify(lists));
- }
- }
- })
- }
- if(list.trim().length>0){
- practice.click();
- }
- }
- },1000)
- }
- else if(url.includes("/practice")){
- setTimeout(function(){
- if(!lists.includes(list)){
- location.href=url.split("/practice")[0];
- }
- else{
- bot()
- }
- },250)
- }
- if(url.includes("/play/")){
- bot();
- }
- function bot(){
- let bot = setInterval(function(){
- if(document.getElementsByClassName("challenge-history")[0].children[1].children!==undefined&&inProgress!==true){
- let arr = document.getElementsByClassName("challenge-history")[0].children[1].children;
- let currQuest = getQuest(arr);
- if(currQuest!==false){
- let questIndx = Number(currQuest.innerText-1)
- let questBox = document.getElementsByClassName("question")[questIndx];
- let quest_Type = questType(questBox);
- let nxt = document.getElementsByClassName("next")[0];
- if(quest_Type!==false){
- inProgress = true;
- if(quest_Type=="spell"){
- answerSpelling(questBox,questIndx);
- }
- if(quest_Type=="choice1"){
- answerMultChoice(questBox);
- }
- if(quest_Type=="choice2"){
- answerMultChoice(questBox,2);
- }
- }
- else{
- console.log("Question type doesn't exist 🤨");
- inProgress=false;
- }
- nxt.addEventListener("click",function(){
- inProgress=false;
- //console.log("inProgress = false!")
- })
- }
- }
- },500)
- }
- setInterval(()=>{
- makeRoom();
- if(document.getElementsByClassName("next active")[0]!==undefined){
- document.getElementsByClassName("next active")[0].click();
- }
- },250)
- function makeRoom(){
- if(document.getElementsByClassName("vcom-challenge resizable large started")[0]!==undefined){
- document.getElementsByClassName("vcom-challenge resizable large started")[0].style.minHeight="2500px";
- }
- }
- function questType(quest){
- let type=false;
- let children = quest.children;
- for(let i=0;i<children.length;i++){
- if(children[i].className=="spelltheword"){
- type = "spell"
- }
- if(children[i].className=="choices"){
- if(children[1].childElementCount>0){
- type= "choice1";
- }
- else if(children[1].childElementCount==0){
- type="choice2";
- }
- }
- }
- console.log(type)
- return type;
- }
- function getQuest(arr){
- let result=false;
- for(let i=0;i<arr.length;i++){
- if(arr[i].classList[0]=="enabled"&&arr[i].classList[1]=="selected"&&arr[i].classList.value=="enabled selected"){
- result = arr[i];
- }
- }
- return result;
- }
- function partsOfList(listId,part){
- let words = [];
- let defs = [];
- let examples = [];
- for(let i=0;i<words_defs.length;i++){
- if(words_defs[i].list==listId){
- if(!words.includes(words_defs[i].word)){
- words.push(words_defs[i].word)
- }
- defs.push(words_defs[i].def);
- if(!examples.includes(words_defs[i].example)){
- examples.push(words_defs[i].example)
- }
- }
- if(words_defs.length-1==i){
- if(part=="words"){
- return words;
- }
- if(part=="defs"){
- return defs;
- }
- if(part=="examples"){
- return examples;
- }
- }
- }
- }
- function getChoices(arr){
- let temp=[];
- for(let i=0;i<arr.length;i++){
- temp.push(arr[i].innerText);
- }
- return temp;
- }
- function learn(word,choice,def){
- let present=false;
- for(let i=0;i<learned.length;i++){
- if(learned[i].word==word&&learned[i].choice==choice){
- present=true;
- console.log(`${word} is known 💡`)
- }
- }
- if(!present){
- learned.push({"word":word,"choice":choice});
- if(choice.split(" ").length==1){
- learned.push({"word":choice,"choice":def});
- }
- localStorage.setItem("learned",JSON.stringify(learned))
- console.log(`Learned ${word} 🧠`)
- }
- inProgress=false;
- }
- function getDef(word){
- let def = false;
- let words = partsOfList(list,"words");
- let defs = partsOfList(list,"defs");
- for(let i=0;i<words.length;i++){
- if(words[i].includes(word)||word.includes(words[i])){
- def = defs[i];
- }
- }
- return def;
- }
- function defineChoices(word,arr){
- for(let i=0;i<arr.length;i++){
- if(arr[i].innerText.split(" ").length==1){
- let def = getDef(arr[i].innerText);
- if(def!==false){
- arr[i].innerText += `: ${getDef(arr[i].innerText)} - (answer?)`;
- arr[i].style.color = "orange";
- arr[i].innerText+=" 🧠"
- clean(word,arr)
- }
- }
- }
- }
- function answerMultChoice(questBox,clause){
- let word,choiceBox,choices;
- if(clause==2){
- let chil = questBox.children[2].children;
- if(chil.length>1){
- for(let i=0;i<chil.length;i++){
- if(chil[i].tagName=="STRONG"){
- word = chil[i].innerText
- }
- }
- }
- else{
- word = questBox.children[2].children[0].innerText;
- }
- }
- else if(clause==undefined){
- word = questBox.children[1].children[0].children[0].innerText;
- }
- choiceBox = questBox.children[3].children;
- choices = getChoices(choiceBox);
- defineChoices(word,choiceBox)
- let instruct = questBox.children[2];
- let words = partsOfList(list,"words");
- let defs = partsOfList(list,"defs");
- let def=false;
- deepSearch(word,questBox);
- //deepDef(word,choices,choiceBox);
- def = getDef(word);
- defAllChoices(choices,choiceBox,def)
- maybe(choices,choiceBox)
- if(def!==false){
- let answr = false;
- for(let i=0;i<choices.length;i++){
- if(choices[i].includes(def)||def.includes(choices[i])){
- answr = i;
- }
- }
- if(answr!==false){
- choiceBox[answr].style.color="springgreen";
- choiceBox[answr].innerText+=" 🧠"
- clean(word,choiceBox)
- }
- else{
- answr=false;
- if(learned.length>0){
- for(let i=0;i<learned.length;i++){
- for(let j=0;j<choiceBox.length;j++){
- if(learned[i].word.includes(word)||choiceBox[j].innerText.includes(learned[i].choice)||learned[i].choice.includes(choiceBox[j].innerText)||word.includes(learned[i].word)){
- answr = learned[i].choice;
- }
- }
- }
- }
- if(answr!==false){
- for(let i=0;i<choices.length;i++){
- if(choices[i].includes(answr)||answr.includes(choices[i])){
- choiceBox[i].style.color="springgreen";
- choiceBox[i].innerText+=" 🧠"
- clean(word,choiceBox)
- }
- }
- }
- else{
- //console.log("No answer found - normal way");
- }
- }
- }
- for(let i=0;i<choiceBox.length;i++){
- choiceBox[i].addEventListener("click",function(){
- setTimeout(function(){
- grabChoice(word,choiceBox,def);
- },250)
- })
- }
- }
- function grabChoice(word,choices,def){
- let correct = false;
- for(let i=0;i<choices.length;i++){
- if(choices[i].className=="correct"){
- learn(word,choices[i].innerText,def);
- correct = true;
- }
- if(correct){
- if(choices[i].className!=="correct"){
- wrong(word,choices[i].innerText)
- }
- }
- else{
- if(choices[i].className=="incorrect"){
- wrong(word,choices[i].innerText);
- }
- }
- }
- }
- function clean(word,choices){
- for(let j=0;j<choices.length;j++){
- for(let i=0;i<incorrect.length;i++){
- if(incorrect[i].word==word&&incorrect[i].choice==choices[j].innerText){
- choices[j].style.color="red";
- }
- }
- }
- }
- function wrong(word,choice){
- let present=false;
- for(let i=0;i<incorrect.length;i++){
- if(incorrect[i].word==word&&incorrect[i].choice==choice){
- present=true;
- console.log(`${word}'s choice is known as incorrect ❌`);
- }
- }
- if(!present){
- incorrect.push({"word":word,"choice":choice});
- localStorage.setItem("wrong",JSON.stringify(incorrect))
- console.log(`Learned ${word}'s incorrect choice 🧠`)
- }
- inProgress=false;
- }
- async function deepSearch(word,questBox){
- try{
- let api=`https://vocabulary.now.sh/words/${word}`;
- let api2=`https://vocabulary.now.sh/word/${word}`;
- let result=await fetch(api).then(data => data.json()).then(data => data.data[0]);
- let example=await fetch(api2).then(data => data.json()).then(data => data.data);
- let def = await result.description;
- let choiceBox = questBox.children[3].children;
- let choices = getChoices(questBox.children[3].children);
- let instruct = questBox.children[2];
- let content = questBox.children[1];
- let answr=false;
- for(let i=0;i<choices.length;i++){
- if(choices[i].includes(example)||choices[i].includes(def)||def.includes(choices[i])||example.includes(choices[i])){
- answr=i;
- }
- }
- if(answr!==false){
- choiceBox[answr].style.color="springgreen";
- choiceBox[answr].innerText+=" 🧠"
- }
- else{
- //console.log("DeepSearch failed. Will add correct answer to dataSet when answered. 🤔");
- }
- if(getDef(word)!==false){
- let set = false;
- let rep = false;
- if(content.children.length>0){
- rep = content;
- }
- if(instruct.children.length>0){
- rep = instruct;
- }
- if(rep!==false){
- if(!set){
- set = true;
- rep.style.overflowY="auto";
- rep.style.height="fit-content";
- rep.innerHTML+=`<hr><div style="margin-top:50px;"><b style="color:black;">${word}</b> means: ${getDef(word)} 🧠 <br><br> <span style="font-size:18px; margin-bottom:10px;"><b style="color:black;">Example:</b> ${example}</span></div><br>`;
- questBox.style.marginTop="-45px";
- }
- }
- }
- for(let i=0;i<choices.length;i++){
- if(similarity(choices[i],def)||similarity(choices[i],example)/*||similar(def,choices[i])||similar(example,choices[i])*/){
- choiceBox[i].style.color="springgreen";
- choiceBox[i].innerText+=" 🧠"
- }
- }
- }
- catch(e){
- return false;
- }
- }
- function maybe(choices,choiceBox){
- for(let i=0;i<choices.length;i++){
- for(let j=0;j<learned.length;j++){
- if(choices[i].toLowerCase().includes(learned[j].word.toLowerCase())||learned[j].word.toLowerCase().includes(choices[i].toLowerCase())){
- if(!choiceBox[i].innerText.includes(" - maybe this...")){
- choiceBox[i].innerText+=" - maybe this...";
- choiceBox[i].style.color="orange";
- }
- }
- }
- }
- }
- function cleanUp(choices){
- for(let i=0;i<choices.length;i++){
- choices[i].style.color="#36588e";
- }
- }
- function answerSpelling(questBox,indx){
- let inp = questBox.children[1].children[1].children[1];
- let submit = questBox.children[1].children[2].children[0];
- let surrender = questBox.children[1].children[2].children[1];
- let status = document.getElementsByClassName("status")[indx];
- let speak = questBox.children[1].children[1].children[0];
- let label = questBox.children[1].children[0];
- let words = partsOfList(list,"words");
- speak.click();
- function auto(matches){
- inp.value=matches[0];
- inp.blur();
- setTimeout(function(){
- submit.click();
- inProgress = false;
- },350)
- }
- inp.addEventListener("keyup",function(evt){
- if(inp.value.trim().length>0){
- label.innerText = "Spell the word:";
- let input = inp.value;
- let matches=[];
- for(let i=0;i<words.length;i++){
- if(words[i].toLowerCase().includes(input.toLowerCase())||input.toLowerCase().includes(words[i].toLowerCase())){
- matches.push(words[i]);
- }
- }
- if(matches.length>0){
- label.innerText = "Matches 😉:"
- let newLabel = document.createElement("div");
- label.append(newLabel);
- let max = 5;
- if(matches.length<5){
- max = matches.length;
- }
- for(let i=0;i<max;i++){
- newLabel.style="width:100%;height:fit-content;display:flex;align-items:center;justify-content:center;flex-direction:row;overflow:hidden;"
- newLabel.innerHTML+=` <p style="cursor:pointer;margin:5px;" class = "spellGuess">${matches[i]}</p>`;
- let guesses = document.getElementsByClassName("spellGuess");
- for(let i=0;i<guesses.length;i++){
- guesses[i].addEventListener("click",()=>{
- inp.value = guesses[i].innerText;
- setTimeout(()=>{
- submit.click();
- inProgress = false;
- },350)
- })
- }
- }
- if(matches.length==1){
- let auto_do = true;
- if(status.children.length>0){
- if(status.children[0].innerText.includes("again")){
- auto_do = false;
- }
- }
- if(auto_do){
- auto(matches);
- }
- }
- }
- else{
- label.innerText = "No matches 😟";
- }
- }
- else{
- label.innerText = "Spell the word:";
- }
- })
- inp.addEventListener("keydown",function(evt){
- if(evt.keyCode==13){
- if(inp.value.trim().length>0){
- inProgress=false;
- }
- }
- })
- submit.addEventListener("click",function(){
- inProgress=false;
- })
- }
- function similarity(s1, s2) {
- var longer = s1;
- var shorter = s2;
- if (s1.length < s2.length) {
- longer = s2;
- shorter = s1;
- }
- var longerLength = longer.length;
- if (longerLength == 0) {
- return 1.0;
- }
- if((longerLength - editDistance(longer, shorter)) / parseFloat(longerLength)>0.5){
- return true;
- }
- }
- function editDistance(s1, s2) {
- s1 = s1.toLowerCase();
- s2 = s2.toLowerCase();
- var costs = new Array();
- for (var i = 0; i <= s1.length; i++) {
- var lastValue = i;
- for (var j = 0; j <= s2.length; j++) {
- if (i == 0)
- costs[j] = j;
- else {
- if (j > 0) {
- var newValue = costs[j - 1];
- if (s1.charAt(i - 1) != s2.charAt(j - 1))
- newValue = Math.min(Math.min(newValue, lastValue),
- costs[j]) + 1;
- costs[j - 1] = lastValue;
- lastValue = newValue;
- }
- }
- }
- if (i > 0)
- costs[s2.length] = lastValue;
- }
- return costs[s2.length];
- }
- function similar(phrase,choice){
- let simScore1 = 0;
- let simScore2 = 0;
- phrase = cleanPunc(phrase).split(" ");
- choice = cleanPunc(choice).split(" ");
- for(let i=0;i<phrase.length;i++){
- for(let j=0;j<choice.length;j++){
- if(phrase[i].includes(choice[j])||choice[j].includes(phrase[i])){
- return true;
- }
- }
- }
- return false;
- }
- function cleanPunc(string){
- return string.replace(/[^A-Za-z0-9\s]/g,"").replace(/\s{2,}/g, " ");
- }
- /*
- async function deepDef(word,choices,choiceBox){
- try{
- let api = dictionary+word;
- let dets = await fetch(api).then(data => data.json()).then(data=>data[0].meanings[0].definitions[0]);
- let synms = dets.synonyms;
- let antms = dets.antonyms;
- let def = dets.definition;
- for(let i=0;i<choices.length;i++){
- for(let j=0;j<synms.length;j++){
- if(choices[i].includes(synms[j])||synms[j].includes(choices[i])){
- choiceBox[i].style.color="springgreen";
- choiceBox[i].innerText+=" 🧠"
- }
- }
- }
- }
- catch(error){
- console.log("Can't find synonyms for this one. Not a big problem, I have other ways of dealing with this 😊")
- }
- }
- */
- async function defAllChoices(choices,choiceBox,def){
- for(let i=0;i<choices.length;i++){
- if(choices[i].split(" ").length==1){
- let api = dictionary+choices[i];
- let defs = await fetch(api).then(data => data.json()).then(data=>data[0].meanings[0].definitions);
- let temp=[];
- for(let j=0;j<defs.length;j++){
- if(defs[j]!==undefined){
- temp.push(defs[j].definition);
- }
- }
- for(let x=0;x<temp.length;x++){
- choiceBox[i].innerText+=` - ${temp[x]}`;
- }
- }
- }
- }