New MangaDex Follows

Manage your follows

// ==UserScript==
// @name         New MangaDex Follows
// @namespace    https://greasyfork.org/scripts/430295-new-mangadex-follows
// @version      1.3.4
// @description  Manage your follows
// @author       Australis
// @match        https://mangadex.org/*
// @icon         https://www.google.com/s2/favicons?domain=mangadex.org
// @grant        none
// @license      MIT
// ==/UserScript==

function LoadSD(){
    if(localStorage.getItem("seriesdex") == null) seriesdex = []
    else seriesdex = JSON.parse(localStorage.getItem("seriesdex"))
    //1.2
    if(localStorage.getItem("forbidden") == null) forbidden = []
    else forbidden = JSON.parse(localStorage.getItem("forbidden"))
    //1.2.7
    if(localStorage.getItem("splitchaps") == null) splitchaps = []
    else splitchaps = JSON.parse(localStorage.getItem("splitchaps"))
}
LoadSD()

//GLOBAL VARIABLES
// var seriesdex,forbidden,whitelist,blacklist,titlepage,frutyloop,repeat,lista,new_r,new_c,new_d,new_o,new_p,follows,trigger,fstatus,funky
var classChapter = "flex chapter" //class of the elements containing the chapters
var classFeed = "chapter-feed__chapters-list" //class containing the chapter cluster
var grouptagclass = "group-tag lift" //1.3 "group-tag line-clamp-1 -my-1"
var loadedp = "flex gap-2 sm:mb-0 mb-2" //status
var feedone = "mb-4"//"mb-2"//mb-4
var MAXNUM = 10000
var MINNUM = -10
var disURL = ""
var unchecked = true
var preevent = null
whitelist = []
blacklist = []
var orphans = []
titlepage = null
var filter,pikapika
handler = false
var chapdata = "chapter-link" //1.3.1 "ml-2 font-bold line-clamp-1 break-all" //1.3
var chapterelement = "flex items-center"
var chaptergrid = "chapter-grid flex-grow"

var newStyle = newInner("style","text/css",".hideme {\ndisplay: none !important;\n} .levy {\nwhite-space: nowrap;\noverflow: hidden;\ntext-overflow: ellipsis;\nmax-width: 30vw;\ndisplay: block;} .centered{\ntext-align: center;} .yellow{\ncolor: yellow !important}") //1.3.1 //1.2
document.querySelector("head").append(newStyle)

filter = LoadCheckers("filter")
pikapika = LoadCheckers("pikapika")

//FUNCTIONS
function LoadCheckers(name){//1.2
    let varr = JSON.parse(localStorage.getItem(name))
    if(varr == undefined || varr == null) {
        console.info(`${name}: ${JSON.stringify(varr)}`)
        varr = true
        SafeSave(name,varr)
    }
    return varr
}

function SafeLoad(name){//1.2
    let temp = []
    if(localStorage.getItem(name)) temp = JSON.parse(localStorage.getItem(name))
    return temp
}

function GetNumero(text){
    let skip = false
    if(text.includes("Ch.") && text.includes(" - ")) text = text.split("Ch. ")[1].split("-")[0] //1.2.4 //text = text.split(" - ")[0] //1.2
    for(let t of text.replaceAll("\n"," ").replaceAll("\t"," ").split(" ")){
        if(t == "Vol.") skip = true
        else if(t.includes(".")){//1.2
            let num = t.split(".")
            if(num.length > 2){
                let resto = ""
                for(let i = 1; i<num.length; i++) resto+=num[i]
                t = num[0]+"."+resto
            }
        }
        if(t!="" && Number.isFinite(t*1)){//1.2
            if(skip){
                skip = false
            }
            else return t*1
        }
    }
    console.warn(`no number found in ${text}`)
    return NaN
}

function createModal(){
    if(!document.getElementById("daModal")){
        console.log("creating modal")
        var modal = newInner("div","modal",'<div class="modal-content"></div>')
        modal.id = "daModal"
        var body = document.querySelector("body")
        body.insertBefore(modal,body.firstElementChild) //1.2
        var daStyle = newInner("style","text/css",'.modal {display: none;position: fixed;z-index: 500;padding-top: 100px;right: 0;top: 0;width: 100%;height: 100%;overflow: auto;background-color: rgb(0,0,0);background-color: rgba(0,0,0,0.4);}.modal-content {background-color: var(--bg-color);margin: auto;padding: 20px;border: 1px solid #888;width: 80%;}.close {color: #aaaaaa;float: right;font-size: 28px;font-weight: bold;}.close:hover,.close:focus {color: #000;text-decoration: none;cursor: pointer;}')
        document.querySelector("head").append(daStyle)
        var daTableStyle = newInner("style","text/css",'table {border-collapse: collapse;border-spacing: 0;width: 100%;border: 1px solid #ddd;}th, td {text-align: left;padding: 16px;}')
        document.querySelector("head").append(daTableStyle)
    }
    else console.info("modal already exists")
}

function FS(array, number){//FindSeries
    return array.findIndex(q => q.id == number)
}

function HideThis(series,group){
    for(let g of group){//1.2
        if(blacklist.findIndex(q => q[0] == series && q[1] == g) >= 0){ //q[1] == group
            console.info("hide this!")
            return true
        }
        if(blacklist.findIndex(q => q[0] == 0 && q[1] == g) >= 0){
            console.info(`group ${g} globally blocked`)
            return true
        }
    }
    return false
}

function OnlyThis(series,group){
    let result = 0
    for(let g of group){//1.2
        if(whitelist.findIndex(q => q[0] == series && q[1] == g) >= 0) { //the series is listed with this group
            console.info("onlythis!")
            return 2
        }
        if(whitelist.findIndex(q => q[0] == series && q[1] != g) >= 0) { //the series is listed but not this group
            console.info("not whitelisted")
            result = 1
        }
    }
    return result
}

function newInner(tag,classN,inner){
    var temp = document.createElement(tag)
    if(classN == "text/css") temp.type = classN
    else temp.className = classN
    temp.innerHTML = inner
    return temp
}

function cloneDOM(tag,nodo){
    var temp = document.createElement(tag)
    console.debug(nodo) //1.3.4
    temp = nodo.cloneNode(true)
    return temp
}

function newDOM(tag,classN,style){
    var temp = document.createElement(tag)
    temp.className = classN
    temp.style.display = style
    return temp
}

function InverseIt(nodo){//ShowItgain
    let hideme = getCN2(nodo,"hideme")[0]
    let showme = getCN2(nodo,"showme")[0]
    if(!!hideme && !!showme){
        console.log("inversing in process")
        hideme.className = nodo.children[2].className.replace("hideme","showme")
        showme.className = nodo.children[3].className.replace("showme","hideme")
    }
}

function getTID(nodo){//1.2 (get title ID)
    let result = null
    if(nodo){//1.3
        // console.debug(nodo) //1.3.1
        if(typeof(nodo)=="string") result = nodo.split("/")[4] //1.3.2
        else if(getTAG(nodo,"a").length && getTAG(nodo,"a")[0].href.includes("/title/")) result = getTAG(nodo,"a")[0].href.split("/")[4] //1.3
        else if(nodo.href) result = nodo.href.split("/")[4] //1.3
        else if(nodo.firstChild.href) result = nodo.href.split("/")[4] //1.3
        else if(nodo.parentElement.href) result = nodo.parentElement.href.split("/")[4] //1.3.1
    }
    if(result && result.includes("?")) result = result.split("?")[0]
    return result
}

function getGID(nodo){//1.2 //getID2
    let result = []
    function Push(x){
        result.push(x)
        if(result.length == 0) result = [x]
    }
    if(document.URL.includes("/title/")){//1.3.2
        for(let a of getTAG(nodo,"a")){
            let b = a.href
            if(b.includes("?")) b = b.split("?")[0]
            if(b.includes("/group/")) Push(getID3(b))
        }
        // if(getCN("cursor-default").length) Push(0)
        if(getCN2(nodo,"group-tag none").length) Push(0) //1.2.7
    }
    if(nodo){ //1.3.2
        for(let g of nodo.getElementsByClassName(grouptagclass)){
            if(getCN2(nodo,"group-tag none").length) Push(0) //1.2.7
            else{
                let b = g.href
                if(b.includes("?")) b = b.split("?")[0]
                if(b.includes("/group/")) Push(getID3(b))
                }
        }
    }
    else return null
    return result
}

function getID3(text){
    return text.split("/")[4]
}

function HasBeenRead(nodo){
    if(getTAG(nodo,"svg")[0].parentElement.innerHTML.includes(" feather-eye ")) return false
    else{
        if(getTAG(nodo,"svg").length == 0){ //1.3
            console.debug(`NULL SVG: ${nodo.outerHTML}`)
            return null
        }
        // console.debug(`READ SVG: ${nodo.outerHTML}`)
        return true
    }
}

function getDec(n,x){ //1.2.7
    let m = n.toString()
    if(m.includes(".")) return m.split(".")[x]*1
    else {
        if(x==1) return 0
        else return n*1
    }
}

function CheckSplit(nodo,daONE){ //1.2.7
    console.info(`CheckSplit for ${daONE.name}`)
    for(let line of getCN2(nodo,classChapter)){
        let inline = line.getElementsByClassName(chapterelement)[0].innerText //1.3 line.getElementsByTagName("a")[0].innerText
        let ch = GetNumero(inline)*1
        console.log(`processing ${ch}`)
        // console.log(`getDec(ch,0):${getDec(ch,0)} | getDec(ch,1):${getDec(ch,1)}`)
        // console.log(`daONE.last < ch: ${daONE.last < ch}\n!!daONE.aval: ${!!daONE.aval}\ngetDec(daONE.aval,0) == getDec(ch,0): ${getDec(daONE.aval,0) == getDec(ch,0)}\ngetDec(ch,1) < daONE.split: ${getDec(ch,1) < daONE.split}`)
        console.log(daONE)
        if(daONE.last < ch && !!daONE.aval && getDec(ch,1) >= 1 && getDec(ch,1) < daONE.split) SPPush([daONE.id,getTID(line),ch])
    }
    SafeSave("splitchaps",splitchaps)
}

function HaySplit(nodo,daONE){ //1.2.7
    console.info(`HaySplit for ${daONE.name}`)
    for(let line of getCN2(nodo,classChapter)){
        if(splitchaps.findIndex(q => q[1] == getTID(line)) >= 0) return true
    }
    return false
}

function DeMark(){//1.2.7
    for(let i=splitchaps.length-1; i>=0; i--){
        let daONE = seriesdex[seriesdex.findIndex(q => q.id == splitchaps[i][0])]
        if(getDec(daONE.aval,1) == daONE.split) splitchaps.splice(i,1)
        else if(getDec(daONE.aval,0) > splitchaps[i][2]) splitchaps.splice(i,1)
    }
    SafeSave("splitchaps",splitchaps)
}

function ResetLast(id,ch){//1.2.7
    let ps = FS(seriesdex,id)
    seriesdex[ps].last = ch.id
    seriesdex[ps].lastl = ch.l
    seriesdex[ps].next = MAXNUM
    seriesdex[ps].nextl = null
    SafeSave("seriesdex",seriesdex)
    console.debug("resetlast")
}

function FollowsFeed(){
    whitelist = SafeLoad("whitelist")
    blacklist = SafeLoad("blacklist")
    let proxydex = seriesdex //1.3.2
    LoadSD()//1.1.3.3
    unreads = 0
    follows = []

    if(document.URL.includes("titles/feed")) {
        var chapfeed = "chapter-feed__container mb-4" //1.3.3 || feedwhole = "mb-12"

        if(getCN(chapfeed).length){//1.3.3 || if(getCN(feedwhole).length) //if page is loaded
            console.log("FollowsFeed")
            //lista = getCN2(getCN(feedwhole)[0],feedone)
            lista = getCN(chapfeed)[0].parentElement.children //1.3.3
            console.log("lista loaded")
            createModal()

            for(let i = seriesdex.length-1; i>=0; i--){//to correct previous bugs
                if(seriesdex[i].id.includes("/") || seriesdex[i].id.includes("?")) {
                    console.log("bug correction! removing this one:")
                    console.log(seriesdex[i])
                    seriesdex.splice(i,1)
                }
                else{
                    if(seriesdex[i].last == null) seriesdex[i].last = MINNUM
                    if(seriesdex[i].nextc == MAXNUM || seriesdex[i].nextc == null || forbidden.includes(seriesdex[i].nextl)) seriesdex[i] = DefaultNext(seriesdex[i])
                    if(!seriesdex[i].mu) seriesdex[i].mu = 0 //1.2
                    if(!Number.isFinite(seriesdex[i].last)){
                        if(Number.isFinite(seriesdex[i].last*1)) seriesdex[i].last*=1
                        else{
                            let digits = ["1","2","3","4","5","6","7","8","9","0","."]
                            let daNumber = ""
                            for(let j of seriesdex[i].last){
                                if(!digits.includes(j)) break
                                else daNumber+=j
                            }
                            if(daNumber.length) seriesdex[i].last = daNumber*1
                            else seriesdex[i].last = MINNUM
                        }
                    }
                    if(seriesdex[i].last == seriesdex[i].nextc) seriesdex[i] = DefaultNext(seriesdex[i])
                    if(seriesdex[i].lastl == undefined) seriesdex[i].lastl = null //1.2.8
                    if(seriesdex[i].nextl == null && seriesdex[i].nextc != MAXNUM) DefaultNext(seriesdex[i]) //1.2.8
                }
            }

            let rep = 0

            function DecideNext(pseries,nextc,nextl,last,link,id_series,l,nextv,lastv,lastl){//lastl added - 1.2.7 //nextv added - 1.2.5 //moved - 1.2
                let daName = l.children[1].title //1.2
                if(forbidden.includes(nextl)){
                    nextl = null
                    nextc = MAXNUM
                    if(nextv) nextv = MAXNUM
                }
                if(daName[0] == " ") daName = daName.slice(1)
                if(pseries >= 0) {
                    if(!!nextv) RevisaNext2(seriesdex[pseries],[nextc,nextl,nextv]) //1.2.5
                    else RevisaNext2(seriesdex[pseries],[nextc,nextl])
                }
                else {
                    if(!!nextv) seriesdex.push({id:id_series, mu:0, name:daName, last:last, lastl:lastl, nextc:nextc, nextl:nextl, time:0, nextv:nextv, lastv:lastv})
                    else seriesdex.push({id:id_series, mu:0, name:daName, last:last, lastl:lastl, nextc:nextc, nextl:nextl, time:0})
                }

                let index = FS(follows,id_series)
                if(index >= 0){
                    if(!!nextv){//1.2.5
                        if((seriesdex[pseries].last < last && nextv == seriesdex[pseries].lastv) || seriesdex[pseries].last == null) {
                            seriesdex[pseries].last = last
                            seriesdex[pseries].lastl = lastl //1.2.8
                            seriesdex[pseries].lastv = lastv
                            seriesdex[pseries].nextv = nextv
                        }
                        if(nextc > last && nextv == seriesdex[pseries].lastv){
                            RevisaNext2(follows[index],[nextc,nextl,nextv])
                            RevisaNext2(seriesdex[pseries],[nextc,nextl,nextv])
                        }
                        else seriesdex[pseries] = DefaultNext(seriesdex[pseries])
                        if(l != follows[index].pointer){//1.2
                            for(let n of getCN2(l,classChapter)){
                                let temp = cloneDOM("div",n)
                                if(!l.className.includes("dummy") && !follows[index].pointer.innerText.includes(n.innerText)) {//1.2.1
                                    getCN2(follows[index].pointer,classChapter)[0].parentElement.append(temp)
                                }
                            }
                            l.style.display = "none"
                        }
                    }
                    else{
                        if(seriesdex[pseries].last < last || seriesdex[pseries].last == null) seriesdex[pseries].last = last
                        if(nextc > last){
                            RevisaNext2(follows[index],[nextc,nextl])
                            RevisaNext2(seriesdex[pseries],[nextc,nextl])
                        }
                        else seriesdex[pseries] = DefaultNext(seriesdex[pseries])
                        if(l != follows[index].pointer){
                            //while(getCN2(l,classChapter)[0] != undefined) getCN2(follows[index].pointer,classChapter)[0].parentElement.append(getCN2(l,classChapter)[0])
                            //1.2
                            for(let n of getCN2(l,classChapter)){
                                let temp = cloneDOM("div",n)
                                if(!l.className.includes("dummy") && !follows[index].pointer.innerText.includes(n.innerText)) {//1.2.1
                                    getCN2(follows[index].pointer,classChapter)[0].parentElement.append(temp)
                                }
                            }
                            l.style.display = "none"
                        }
                    }
                }
                else{
                    if(!!nextv) follows.push({id:id_series, ch:last, url:link, nextc:nextc, nextl:nextl, pointer:l, nextv:nextv, lastv:lastv})
                    else follows.push({id:id_series, ch:last, url:link, nextc:nextc, nextl:nextl, pointer:l})
                }

                if(pseries == -1) pseries = FS(seriesdex,id_series) //should be the last
                let ati = seriesdex[pseries].nextc //1.2
                if(/*ati == 0 || */ati == null || ati == MAXNUM || (ati > nextc && seriesdex[pseries].last < nextc)){//1.2.8
                    seriesdex[pseries].nextc = nextc
                    seriesdex[pseries].nextl = nextl
                }
            }

            function ProcessGroups(batchi,id_series){
                if(filter){
                    var icono,newdiv
                    var gid = getGID(batchi)
                    let OTresult = OnlyThis(id_series,gid)
                    if(OTresult == 2) {
                        console.log("whitelisted!!")
                        return true
                    }
                    if(HideThis(id_series,gid)) {
                        console.log("blacklisted!! hidethis")
                        funky = "BLACKLIST"
                        return false
                    }
                    if(OTresult == 1) {
                        console.log("not in whitelist!!")
                        funky = "WHITELIST"
                        return false
                    }
                    //not part of any list
                    return true
                }
                else return true
            }

            function ChangeToBL(nodo){//moved - 1.2
                if(getCN2(nodo.parentElement,"showme").length) console.log("still blacklisted?")
                else {
                    var parche = newInner("div","ml-2 font-bold line-clamp-1 break-all showme blacklisted",`BLOCKED (${funky})`) //1.3
                    parche.setAttribute("data-v-7c8acb10","") //1.3
                    nodo.parentElement.insertBefore(parche, nodo.nextSibling) //1.3.4 nodo.parentElement.append(parche)
                    nodo.className += " hideme"
                }
            }

            let lastnode
            try{//1.3.1
                if(!getCN("dummy").length) lastnode = cloneDOM("div",lista[lista.length-2]) //1.3.4 length-1
                else lastnode = null
            }
            catch(e){
                setTimeout(FollowsFeed,1000)
                console.debug(e)
                return
            }
            function SkipLL(l){//1.3.4
                if(!l.className.includes("mb-4")){ //1.3.4
                    console.debug("skipping element")
                    if(l.className.includes("mb-6")) primerelem = l
                    if(l.className.includes("mt-6")) ultimoelem = l
                    return true
                }
                else{
                    console.debug("available")
                    return false
                }
            }
            do{//1.1.3.2
                for(let l of lista){//check the list
                // if(false){
                    try{
                        if(SkipLL(l)) continue //1.3.4
                        console.debug(l)
                        var id_series = getTID(l)
                        var batch = getCN2(l,chaptergrid) //1.3 getCN2(l,classChapter)
                        var chap, link, read, nextc, nextl, last, nextv, lastv
                        nextv = false
                        nextc = MAXNUM
                        nextl = null
                        lastv = MINNUM //1.2.5
                        let verylast = MINNUM //1.2.7
                        let pseries = FS(seriesdex,id_series)
                        if(pseries < 0) {
                            last = MINNUM
                            //1.2.6
                            let sdummy = DefaultObj()
                            sdummy.name = l.children[1].title
                            sdummy.id = id_series
                            seriesdex.push(sdummy)
                            pseries = FS(seriesdex,id_series)
                        }
                        else {
                            last = seriesdex[pseries].last
                            if(seriesdex[pseries].name == "") seriesdex[pseries].name = l.children[1].title //1.2
                        }

                        function GetVol(text){//1.1.3.2
                            if(text.includes("Vol. ")){//1.2.7
                                let t = text.split("Vol. ")[1].split(" ")[0]*1
                                if(!Number.isNaN(t)) {
                                    // console.info(`GetVol: ${t}`)
                                    return t*1
                                }
                            }
                            else {
                                // console.info(`GetVol: FALSE`)
                                return false
                            }
                        }

                        if(batch.length){//if there's chapters
                        //if(false){
                            let prevgid = false
                            for(let i=0; i<batch.length; i++){
                                var name = getCN2(batch[i],chapdata)[0].innerText.replace("\n"," ") //1.3 getTAG(batch[i],"a")[0].innerText.replace("\n"," ")
                                // console.info(`name: ${name}`)
                                var current = GetNumero(name)
                                var vol = GetVol(name)
                                var process = true //1.2 //false
                                var timestamp = 0
                                getCN2(batch[i],chapdata)[0].setAttribute("title",name.replaceAll('"','$').replaceAll('<','[').replaceAll('>',']')) //1.3 getTAG(batch[i],"a")[0].setAttribute("title",name.replaceAll('"','$').replaceAll('<','[').replaceAll('>',']'))

                                if(filter) process = ProcessGroups(batch[i],id_series)

                                function SetVolNext(){//1.2.8
                                    nextc = current
                                    nextl = thisLink
                                    nextv = vol //1.2.5
                                }

                                if(process){//should be shown
                                    if(!batch[i].innerHTML.includes("hideme") && HasBeenRead(batch[i]) == false){ //1.3.4
                                        thisLink = getTAG(batch[i],"a")[0].href //1.3.4 batch[i].parentElement.href //1.3 getTAG(batch[i],"a")[0].href.split("chapter/")[1] //1.2.3
                                        //if(!batch[i].parentElement.href.includes("mangadex")) thisLink = batch[i].parentElement.href //1.3 redundant??
                                        if(verylast < current) verylast = current //1.2.7
                                        if(!seriesdex[pseries].lastv && last > current && (name.toLowerCase().includes("extra") || name.toLowerCase().includes("omake") || name.toLowerCase().includes("bonus") || Number.isInteger(current - 0.5) || Number.isInteger(current - 0.9))) {
                                            getTAG(batch[i],"svg")[0].classList.add("amarillo") //1.2
                                        }
                                        if(seriesdex[pseries].lastv && last > current && vol <= seriesdex[pseries].lastv && (name.toLowerCase().includes("extra") || name.toLowerCase().includes("omake") || name.toLowerCase().includes("bonus") || Number.isInteger(current - 0.5) || Number.isInteger(current - 0.9))) {
                                            getTAG(batch[i],"svg")[0].classList.add("amarillo") //1.2.9
                                        }
                                        if(pseries >= 0 && !!seriesdex[pseries].lastv && vol){//1.1.3.2
                                            if(vol == seriesdex[pseries].lastv && last < current && nextc > last && nextc >= current){
                                                SetVolNext()
                                            }
                                            if(vol == seriesdex[pseries].lastv+1){//1.2.8
                                                if(seriesdex[pseries].nextv > vol){
                                                    SetVolNext()
                                                }
                                                else if(seriesdex[pseries].nextv == vol && nextc > current) {
                                                    SetVolNext()
                                                }
                                            }
                                        }
                                        else if(last < current && nextc >= last && nextc > current){
                                            nextc = current
                                            nextl = thisLink//getTAG(batch[i],"a")[0].href.split("chapter/")[1]
                                            if(forbidden.includes(nextl)) CleanFB(batch[i]) //1.2.1 //shouldn't be part of forbidden
                                            prevgid = getGID(batch[i]) //1.1.3.3
                                        }
                                        else if(current == nextc){//1.1.3.3
                                            let gids = getGID(batch[i])
                                            if(prevgid == [0]){//give priority to real groups
                                                nextl = thisLink//getTAG(batch[i],"a")[0].href.split("chapter/")[1]
                                            }
                                            prevgid = gids
                                        }
                                        if(seriesdex[pseries].aval){//1.2.7
                                            if(seriesdex[pseries].aval < verylast) seriesdex[pseries].aval = verylast
                                        }
                                        else seriesdex[pseries].aval = verylast
                                    }
                                    if(HasBeenRead(batch[i]) == true){//1.3
                                        let cid = getTID(batch[i].parentElement) //1.3
                                        if(getTAG(batch[i],"svg")[0].classList.contains("yellow")) {//1.2
                                            getTAG(batch[i],"svg")[0].classList.remove("yellow")
                                        }
                                        if(seriesdex[pseries].lastl == cid && current != last){//1.2.7
                                            ResetLast(id_series,{id:current,l:cid})
                                            setTimeout(FollowsFeed,100) //1.3
                                            return
                                        }
                                        if(last < current) last = current
                                        if(vol && lastv < vol) lastv = vol //1.2.5
                                        let thistmp = (new Date(getTAG(batch[i],"time")[0].dateTime)).getTime()
                                        if(thistmp > timestamp) timestamp = thistmp
                                    }
                                    //if(HasBeenRead(batch[i]) == null) ignore
                                    if(filter) InverseIt(getCN2(batch[i],chapdata)[0].parentElement) //1.3
                                }
                                else{//has to be hidden
                                    console.log("not to process")
                                    console.log(batch[i])
                                    console.log(seriesdex[pseries])
                                    let cid = getTID(batch[i].parentElement) //1.3
                                    if((!seriesdex[pseries].lastv && current > last) || (seriesdex[pseries].lastv && (vol > seriesdex[pseries].lastv || (vol == seriesdex[pseries].lastv && current > last)))){//1.2.1
                                        FBPush(cid)
                                        getTAG(batch[i],"svg")[0].style.color = "red"
                                        if(forbidden.includes(seriesdex[pseries].nextl)) {//1.3.4 //nextl
                                            console.log("resetting due forbidden")
                                            seriesdex[pseries] = DefaultNext(seriesdex[pseries])
                                        }
                                    }
                                    else{
                                        console.log(`${cid} less than last (${current} <= ${last}\n${name})`)
                                        if(vol) console.log(`vol: ${vol}`) //1.2.4
                                        CleanFB(batch[i])
                                        if(getTAG(batch[i],"svg")[0].style.color) getTAG(batch[i],"svg")[0].style.removeProperty("color")
                                    }
                                    let card = getCN2(l,"continue")
                                    if(card.length && card[0].firstChild.href == batch[i].parentElement.href.split("chapter/")[1]){ //1.3 getTAG(batch[i],"a")[0].href.split("chapter/")[1]){
                                        nextc = MAXNUM
                                        nextl = null
                                    }
                                    if(filter) ChangeToBL(getCN2(batch[i],chapdata)[0])//1.3 ChangeToBL(getTAG(batch[i],"a")[0])
                                }

                            }
                        }
                        DecideNext(pseries,nextc,nextl,last,link,id_series,l,nextv,lastv)
                    }
                    catch(e){
                        console.log("error processing lista")
                        console.log(e)
                    }
                }
                DeMark()
            }while(rep++ < 1)
                document.getElementsByClassName("chapter-feed__title")[0].className+=" caca" //1.3.2
                for(let l of lista){//add the continue link if necessary and add filtering button
                // if(false){
                    if(SkipLL(l)) continue //1.3.4
                    let fbtn = newInner("button","nmf-btn","🔧")
                    fbtn.style.float = "right"
                    fbtn.setAttribute("onclick","NMDFilter(event)")
                    let titu = getCN2(l,"chapter-feed__title")[0]
                    let fbtn_container = cloneDOM("a",titu)
                    fbtn_container.innerHTML = ""
                    fbtn_container.removeAttribute("href")
                    fbtn_container.append(fbtn)
                    fbtn_container.style.display = "block"
                    if(filter && !getCN2(l,"nmf-btn").length) {
                        titu.parentElement.insertBefore(fbtn_container,titu)
                        titu.style.width = "95%"
                    }
                    //let elem = getTAG(l,"a")[0]
                    let elem = getCN2(l,chaptergrid)[0] //1.3
                    if(elem){
                        let daONE = seriesdex[FS(seriesdex,getID3(getTAG(l,"a")[0].href))] //1.3
                        let extrainfo = ""
                        let currLink = `/chapter/${daONE.nextl}` //1.2.3
                        if(daONE.nextl && daONE.nextl.includes(".")) currLink = daONE.nextl //1.2.3
                        if(getCN2(l,classFeed).length == 0) l.style.display = "none"
                        else if(daONE.nextc > daONE.last && daONE.nextl){
                            if(daONE.last != MINNUM && (daONE.nextc - daONE.last >= 1.2)) extrainfo = " (WARNING: skipped chapters)"
                            if(daONE.last == MINNUM && daONE.nextc != 1) extrainfo = " (WARNING: no previous info)"
                            if(daONE.last == MINNUM && daONE.nextc <= 1.1) extrainfo = " (Start reading!)"//1.1.3.2
                            if(daONE.last != MINNUM && daONE.split){ //1.2.7
                                CheckSplit(l,daONE)
                                if(HaySplit(l,daONE)) extrainfo = " (WARNING: split chapter incomplete)"
                            }
                            let continuetext = `CONTINUE to Chapter ${daONE.nextc}${extrainfo}`
                            if(daONE.nextv) continuetext = `CONTINUE to Volume ${daONE.nextv} Chapter ${daONE.nextc}${extrainfo}`
                            let newbutton = newInner("div",classFeed,`<button class=\"continue\"><a href=\"${currLink}\" target="_blank" rel="noopener noreferrer">${continuetext}</button>`) //1.3.1
                            if(getCN2(l,"continue").length == 0) getCN2(l,"chapter-feed__chapters")[0].insertBefore(newbutton,getCN2(l,classFeed)[0])
                            else getCN2(l,"continue")[0].parentElement.innerHTML = newbutton.innerHTML
                        }
                        if(((daONE.nextl == null || daONE.nextl == "") || daONE.last >= daONE.nextc) && getCN2(l,"continue")[0] != undefined){
                            getCN2(l,"continue")[0].parentElement.remove()
                        }
                    }
                    let checker = [] //1.3.4
                    for(let ce of getCN2(l,classChapter)){//1.3.4
                        let state = true
                        for(let ch of checker){
                            if(getTAG(ch,"a")[0].href == getTAG(ce,"a")[0].href) state = false
                        }
                        if(state) checker.push(ce)
                        else ce.style.display = "none"
                    }
                }

            //TopWoNerae()//1.2
            console.info("TOP WO NERAE!")
            let amor = []
            for(let o of getCN("amarillo")){
                amor.push(o)
            }
            for(let a of amor){
                a.classList.replace("amarillo","yellow")
            }

            for(let n=follows.length-1; n >= 0; n--){//put unread chapters on top of the list
                if(getCN2(follows[n].pointer,"yellow").length || follows[n].pointer.innerHTML.includes(" feather-eye ")) {
                    lista[0].parentElement.insertBefore(follows[n].pointer,lista[0]) //1.2
                    console.log("unread UP!")
                }
            }
            for(let n=follows.length-1; n >= 0; n--){//put unread series on top of the list
                if(getCN2(follows[n].pointer,"continue").length) {
                    lista[0].parentElement.insertBefore(follows[n].pointer,lista[0]) //1.2
                    console.log("continue UP!")
                }
            }
            for(let n=follows.length-1; n >= 0; n--){//put comikey's unread series on top of the list since they expire quicker
                if(getCN2(follows[n].pointer,"continue").length && follows[n].pointer.innerText.includes("Comikey")) {
                    lista[0].parentElement.insertBefore(follows[n].pointer,lista[0]) //1.2
                    console.log("comikey UP!")
                }
            }
            //end TopWoNerae
            lista[0].parentElement.insertBefore(primerelem,lista[0]) //1.3.4

            if(lastnode && lista[lista.length-1].innerText != lastnode.innerText){//1.2 //to not mess up the pagination for some reason
                let ultimo = cloneDOM("div",lastnode)
                console.log("dummy this time:")
                console.log(ultimo)
                ultimo.style.display = "none"
                ultimo.className+= " dummy"
                lista[0].parentElement.append(ultimo)
                lista[0].parentElement.append(ultimoelem) //1.3.4
            }

            if(!frutyloop) {
                console.log("fruty fruty frutyloooop!")
                frutyloop = true
                // for(let i=1; i<6; i++) setTimeout(KeepChecking,i*2000)
                e2o = lista[0].parentElement
                observer = new MutationObserver(function() {
                    KeepChecking()
                })
                observer.observe(e2o, {subtree: true, attributes: true})
            }
            //1.3.2
            let counter = 0
            for(let i=0; i<proxydex.length;i++){
                if(seriesdex[i].last > proxydex[i].last) counter++
            }
            if(counter <= 1) SafeSave("seriesdex",seriesdex)
            else alert("Possible bug! Reload the page to be sure")
        }
        else setTimeout(FollowsFeed,1000)
    }
    else console.log("FollowsFeed doesn't apply") //1.3.3
}

function KeepChecking(){//1.2
    if(frutyloop){
        if(document.getElementsByClassName("chapter-feed__title").length){ //1.3.2
            let totales = getCN("flex-shrink-0 cursor-pointer").length
            let noleidos = getCN("flex-shrink-0 cursor-pointer feather-eye").length
            if(unreads != totales-noleidos){
                if(noleidos > 0) FollowsFeed()
                unreads = totales-noleidos
            }
        }
        else setTimeout(KeepChecking,2000) //1.3.2
        // setTimeout(KeepChecking,2000)
    }
}

function DefaultObj(){//moved - 1,2.6
    return {id:0,mu:0,name:"",avail:MINNUM,last:MINNUM,lastl:null,nextc:MAXNUM,nextl:null, time:0} //1.2.7
}

function Llenar2(){//1.1.3.2
    function Walala(){
        console.info("walala")
        let items = getCN("manga-card") //1.2.5 getCN("manga-card bg-accent")
        let temp = []
        let pgn = 1 //1.3.4

        function WaitElement(){
            console.info("waiting")
            if(items.length){
                setTimeout(Primero,1000)
                console.info("for primero")
            }
            else{
                setTimeout(WaitElement,5000)
                console.log("another 5 seconds")
            }
        }

        function Primero(){
            console.info("primero")
            try{
                for(let i of items){
                    let manga = DefaultObj()
                    manga.id = getTID(i)
                    manga.name = getTAG(i,"span")[0].innerText//1.2//i.firstChild.innerText
                    if(FS(temp,manga.id) < 0) temp.push(manga)
                }
                ClickSiguiente()
            }
            catch(e){
                console.warn("catch primero")
                console.error(e)
                setTimeout(Primero,500)
            }
        }

        function ClickSiguiente(){
            try{
                let pagination = getCN("flex justify-center flex-wrap gap-2 my-6")[0].children
                //1.2.7
                // let final = pagination[pagination.length-1]
                // final.href = final.href.replace("?page=1","?page=2")
                // if(!final.className.includes("disabled")){
                //     if(final.href.includes("?page=1")) pagination[2].click()
                //     else final.click()
                //     console.info(`click ${final.href}!`)
                //     Segundo()
                // }
                //1.3.4
                let state = true
                console.info(`seeking page ${pgn+1}`)
                for(let p of pagination){
                    console.info(p.href)
                    if(!p.className.includes("px-0") && p.href && p.href.includes((pgn+1).toString())){
                        state = false
                        console.info(`found page ${pgn+1}`)
                        p.click()
                        pgn++
                        Segundo()
                        return
                    }
                }
                if(state){
                    console.info(`no page ${pgn}, proceeding to next tab`) //1.3.4
                    NextTab()
                    pgn = 1 //1.3.4
                    console.log(temp)
                    return temp
                }
                console.info("ClickSiguiente failed?")
            }
            catch(e){
                if(!getCN("flex justify-center flex-wrap gap-2 my-6")[0]){
                    console.warn("no pagination")
                    NextTab()
                    pgn = 1 //1.3.4
                    console.log(temp) //1.2.7
                    return temp
                }
            }
        }

        function Segundo(){
            try{
                items = getCN("manga-card") //1.2.5 getCN("manga-card bg-accent")
                let dummy = DefaultObj()
                dummy.id = getTID(items[0])
                dummy.name = items[0].firstChild.innerText
                //1.2.7
                let pagination = getCN("flex justify-center flex-wrap gap-2 my-6")[0].children
                let final = pagination[pagination.length-1]

                if(final.href.includes("page=2")){ //1.2.7
                    console.info("segundo!!")
                    final.click()
                    setTimeout(Segundo,250)
                }
                else if(FS(temp,dummy.id)>=0) {
                    setTimeout(Segundo,250)
                }
                else Primero()
            }
            catch(e){
                console.warn("catch segundo")
                console.error(e)
                setTimeout(Segundo,5000)
            }
        }

        WaitElement()

        return temp
    }
    var tabs = getCN("select__tab")
    console.log(tabs)
    let firsttab = tabs[0]
    if(!firsttab.className.includes("active")) firsttab.click()
    function FillTitles(){
        try{
            console.info("Filling Titles")

            let oldr = SafeLoad("reading")
            let oldo = SafeLoad("onhold")
            let oldp = SafeLoad("planto")
            let oldd = SafeLoad("dropped")
            let oldc = SafeLoad("completed")

            function Copiar(arrA,argB){
                let indice = FS(arrA, argB.id)
                if(indice >= 0){
                    arrA[indice].last = argB.last
                    arrA[indice].nextc = argB.nextc
                    arrA[indice].nextl = argB.nextl
                    //1.2
                    if(!arrA[indice].mu) arrA[indice].mu = argB.mu
                    arrA[indice].time = argB.time
                }
            }

            for(let s of seriesdex){
                Copiar(new_c, s)
                Copiar(new_o, s)
                Copiar(new_r, s)
                Copiar(new_d, s)
            }

            function UpdateArrays(old,neww){
                for(let a of neww){
                    let indice = FS(old,a.id)
                    if(indice >= 0) {//1.2
                        let name = a.name
                        a = old[indice]
                        if(old[indice].name != name) a.name = name
                    }
                }
                return neww
            }

            new_r = UpdateArrays(oldr,new_r)
            new_p = UpdateArrays(oldp,new_p)
            new_o = UpdateArrays(oldo,new_o)
            new_d = UpdateArrays(oldd,new_d)
            new_c = UpdateArrays(oldc,new_c)

            SafeSave("reading",new_r)
            SafeSave("planto",new_p)
            SafeSave("onhold",new_o)
            SafeSave("dropped",new_d)
            SafeSave("completed",new_c)
            alert("Done!")
        }
        catch(e){
            console.log("error filling titles")
            console.log(e)
        }
    }
    function NextTab(){
        console.log("next tab")
        for(let x=0; x<tabs.length; x++){
            if(tabs[x].className.includes("active")){
                if(x+1 < tabs.length){
                    tabs[x+1].click()
                    setTimeout(Unbelievable,3000)
                }
                else{
                    console.log("End of loading mangas")
                    FillTitles()
                }
            }
        }
    }
    function Unbelievable(){
        console.log("unbelievable")
        try{
            getCN("flex justify-center flex-wrap gap-2 my-6")[0].children[0]//1.3.4 .click()
        }
        catch(e){
            console.warn("no pagination")
        }

        for(let t of tabs){
            if(t.className.includes("active")){//1.3.4 tab-active
                console.info("checking active tab")
                console.info(t.innerText+":")
                if(t.innerText == "Reading") new_r = Walala()
                if(t.innerText == "Plan To Read") new_p = Walala()
                if(t.innerText == "Completed") new_c = Walala()
                if(t.innerText == "On Hold") new_o = Walala()
                if(t.innerText == "Re-reading"){
                    console.info("who gives a shit lol")
                    NextTab()
                }
                if(t.innerText == "Dropped") {
                    new_d = Walala()
                    console.info("END!!")
                }
            }
        }
    }

    Unbelievable()
}

filling = false

function Loop(){
    try{
        if(disURL != document.URL){
            if(!document.URL.includes("https://mangadex.org/titles/follows")){
                console.log("loop")
                setTimeout(main,5000)
                disURL = document.URL
                trigger = false
                filling = false
            }
            else{
                if(!filling){
                    console.log("preparing to fill")
                    setTimeout(main,5000)
                    disURL = document.URL
                    trigger = false
                    filling = true
                }
            }
        }
    }
    catch(e){
        console.warn("error loop")
    }
    setTimeout(Loop,1000)
}

setTimeout(Loop,1000)

function UpdateSD(arrayname,sd){//1.2
    console.log("updating "+arrayname+"with new changes")
    let array = SafeLoad(arrayname)
    let index = FS(array,sd.id)
    if(index >= 0){
        let nextl = array[index].nextl
        let nextc = array[index].nextc
        let last = array[index].last
        let lastl = array[index].lastl //1.2.8
        let mu = array[index].mu
        let time = array[index].time
        array[index].last = sd.last
        array[index].lastl = sd.lastl //1.2.8
        if(nextl && nextc > sd.last && nextc < sd.nextc){
            console.log("there's a new chapter to consider")
            array[index].nextl = nextl
            array[index].nextc = nextc
        }
        if(sd.lastv){
            array[index].lastv = sd.lastv
            if(sd.nextv) array[index].nextv = sd.nextv
            console.log("volume sorting in consideration")
        }
        if(time){
            if(sd.time && time > sd.time){
                console.log("there was a latter update")
                array[index].time = time
            }
            if(!sd.time){
                console.log("there was no previous time")
                array[index].time = time
            }
        }
        if(mu){
            if(!sd.mu){
                console.log("there was no mangaupdate link before")
                array[index].mu = mu
            }
        }
    }
    else console.log("there's nothing to process??")
    SafeSave(arrayname,array)
    console.log(arrayname+" updated with sd:")
    console.log(array[index])
}

function CompareSD(arrayname,sd){//1.2
    console.log("Comparing SD with "+arrayname)
    let array = SafeLoad(arrayname)
    let index = FS(array,sd.id)
    if(index >= 0){
        let nextl = array[index].nextl
        let nextc = array[index].nextc
        let last = array[index].last
        let lastl = array[index].lastl //1.2.8
        let mu = array[index].mu
        let time = array[index].time
        array[index] = sd
        if(nextl && nextc > sd.last && nextc < sd.nextc){
            console.log("there's a new chapter to consider")
            array[index].nextl = nextl
            array[index].nextc = nextc
        }
        if(last > sd.last){
            console.log("a new last")
            array[index].last = last
            array[index].lastl = lastl //1.2.8
        }
        if(time){
            if(sd.time && time > sd.time){
                console.log("there was a latter update")
                array[index].time = time
            }
            if(!sd.time){
                console.log("there was no previous time")
                array[index].time = time
            }
        }
        if(mu){
            // console.log("mu "+arrayname+": "+mu)
            if(!sd.mu){
                console.log("there was no mangaupdate link before")
                array[index].mu = mu
            }
            else if(sd.mu && mu != sd.mu){
                console.log("mangaupdate link is different... updating it!")
                array[index].mu = mu
            }
        }
        else if(sd.mu){
            console.log(`adding mangaupdate link: ${sd.mu}`)
            array[index].mu = sd.mu
        }
        //1.2.7
        if(sd.split) array[index].split = sd.split
        if(sd.aval) array[index].aval = sd.aval
    }
    else console.log("there's nothing to process??")
    SafeSave(arrayname,array)
    console.log(arrayname+" updated with seriesdex:")
    console.log(array[index])
}

function getCN(classname){//1.2
    return document.getElementsByClassName(classname)
}

function getCN2(nodo,classname){//1.2
    return nodo.getElementsByClassName(classname)
}

function getTAG(nodo,tagname){//1.2
    return nodo.getElementsByTagName(tagname)
}

function SafeSave(item,array){//1.2
    localStorage.setItem(item,JSON.stringify(array))
    console.log(`${item} was saved sucessfully`) //1.2.6
}

function getFstatus(fstatus){//1.2
    let arrayname = null
    if(fstatus == "Reading") arrayname = "reading"
    if(fstatus == "Completed") arrayname = "completed"
    if(fstatus == "Dropped") arrayname = "dropped"
    if(fstatus == "On Hold") arrayname = "onhold"
    if(fstatus == "Plan to Read") arrayname = "planto"
    return arrayname
}

function RevisaNext(nodo){//1.2
    if(nodo.last >= nodo.nextc) nodo = DefaultNext(nodo)
}

function RevisaNext2(nodo,xxx){//1.2
    if(xxx.length == 2){
        if(nodo.last >= xxx[0] || nodo.last >= nodo.nextc) nodo = DefaultNext(nodo)
        if(nodo.nextl == xxx[1] && nodo.nextc != xxx[0]){//1.2.4
            console.log("updated link?")
            nodo.nextc = xxx[0]
        }
        if(xxx[0] > nodo.last && xxx[0] <= nodo.nextc){
            nodo.nextc = xxx[0]
            nodo.nextl = xxx[1]
        }
    }
    else{
        if(xxx[2] > nodo.lastv){
            if(!nodo.nextl){//there's no next chapter registered
                nodo.nextv = xxx[2]
                nodo.nextc = xxx[0]
                nodo.nextl = xxx[1]
            }
            if(nodo.last >= nodo.nextc){//change of volume //1.2.8
                nodo.nextv = xxx[2]
                nodo.nextc = xxx[0]
                nodo.nextl = xxx[1]
            }
        }
        if(xxx[2] == nodo.lastv){
            if(nodo.last >= xxx[0] || nodo.last >= nodo.nextc) nodo = DefaultNext(nodo)
            if(xxx[0] > nodo.last && xxx[0] <= nodo.nextc){
                nodo.nextc = xxx[0]
                nodo.nextl = xxx[1]
                nodo.nextv = xxx[2] //redundant?
            }
        }
    }
}

function DefaultNext(p){//1.2
    let q = p //1.2.2
    q.nextc = MAXNUM
    q.nextl = null
    if(q.lastv) q.nextv = MAXNUM
    return q
}

function CleanFB(nodo){
    let id = getTID(nodo)
    let index = forbidden.indexOf(id)
    if(index >= 0) {
        console.log(`deleting ${id} from forbidden`)
        forbidden.splice(index,1)
        console.log("length: "+forbidden.length)
    }
    // else console.log(`${id} not part of forbidden`)
    SafeSave("forbidden",forbidden)
}

function FBPush(x){//1.2
    if(forbidden.length == 0){ //1.2.7
        console.log(`adding ${x} to forbidden`)
        forbidden.push(x)
    }
    else{
        if(!forbidden.includes(x)){
            console.log(`adding ${x} to forbidden`)
            forbidden.push(x)
        }
        else console.log(`${x} already forbidden`)
    }
    SafeSave("forbidden",forbidden)
}

function SPPush(x){//1.2.7
    console.log("SPPush")
    console.log(x)
    if(getDec(x[2],1) >= 1){
        if(splitchaps.length == 0){
            console.log(`adding ${x} to splitchaps`)
            splitchaps.push(x)
        }
        else{
            if(splitchaps.findIndex(q => q[1] == x[1]) < 0){
                console.log(`adding ${x} to splitchaps`)
                splitchaps.push(x)
            }
            else console.log(`${x} already part of splitchaps`)
        }
        console.log(splitchaps)
        DeMark()
    }
}

function RemoveFromSD(mangaid){//moved 1.2.8 //1.1.3.3
    removedsd = false
    let index = FS(seriesdex,mangaid)
    if(index >= 0) {
        console.log("removed from seriesdex:")
        console.log(seriesdex[index])
        seriesdex.splice(index,1)
        SafeSave("seriesdex",seriesdex)
        removedsd = true
    }
}

//WINDOW FUNCTIONS

window.SC = function(){
    filter = document.getElementById("filter").checked
    SafeSave("filter",filter)
    alert("Changes saved successfully")//1.2
}

window.ReadNext = function(){//1.1.3.3
    console.log("ReadNext")
    FollowsFeed()
    var daModal = document.getElementById("daModal")
    if(!daModal) createModal()
    let reading = SafeLoad("reading")
    let daTable = '<table><tr><th>Name</th><th class="text-align: center;">Unread Chapter</th></tr>'
    for(let s of seriesdex){
        if(s.nextl && s.last < s.nextc){
            let name = s.name
            let currLink = `/chapter/${s.nextl}` //1.2.3
            if(s.nextl && s.nextl.includes(".")) currLink = s.nextl //1.2.3
            if(name == ""){
                let index = FS(reading,s.id)
                if(index >= 0) name = reading[index].name
            }
            if(s.nextc > s.last+1.1) name+=" ‼️"
            daTable+=`<tr><td><a href="/title/${s.id}/${name.replace(/\W\S*/g, '').replaceAll(" ","-")}" target="_blank" rel="noopener noreferrer">${name}</a></td><td><a href="${currLink}" target="_blank" rel="noopener noreferrer">CH. ${s.nextc}</a></td></tr>` //1.3.1 //1.2.5
        }
    }
    daTable+="</table>"
    let closebutton = '<span class="close">&times;</span>'
    daModal.firstChild.innerHTML= closebutton+daTable
    var closebtn = getCN("close")[0]
    closebtn.onclick = function() {
        daModal.style.display = "none"
    }
}

window.DisplayOrphans = function(){//1.2
    FollowsFeed()
    var daModal = document.getElementById("daModal")
    if(!daModal) createModal()
    let reading = SafeLoad("reading")
    let daTable = '<table><tr><th>Name</th><th style="text-align: center;">Unread Chapter</th></tr>'
    for(let o of orphans){
        let name = o.name
        let arl,kink
        if(o.nextc != MAXNUM) {
            //if(o.nextc > o.last+1.1) name+=" ‼️"
            arl = 'CH. '+o.nextc
            kink = ` href="/chapter/${o.nextl}"`
            if(o.nextl && o.nextl.includes(".")) kink = ` href="${o.nextl}"` //1.2.3
        }
        else {
            arl = '🚫'
            kink = ''
        }
        daTable+=`<tr><td><a href="/title/${o.id}/${name.replace(/\W/g, '').replaceAll(" ","-")}" target="_blank" rel="noopener noreferrer">${name}</a></td><td style="text-align: center;"><a${kink}>${arl}</a></td></tr>` //1.3.1
    }
    daTable+="</table>"
    let closebutton = '<span class="close">&times;</span><p>The following series aren\'t part of any list, they\'re just marked to be notified, visit their title page to add them to a list (like Reading, for example)</p>'
    daModal.firstChild.innerHTML= closebutton+daTable
    var closebtn = getCN("close")[0]
    closebtn.onclick = function() {
        daModal.style.display = "none"
    }
}

window.NMDF = function(){//1.1.3.3
    let fcheck,ycheck
    function Checkear(a){//1.2
        if(a) return " checked"
        else return ""
    }
    fcheck = Checkear(filter)
    ycheck = Checkear(pikapika)
    var daModal = document.getElementById("daModal")
    if(!daModal) createModal()
    let closebutton = '<span class="close" onclick="Close()">&times;</span>'
    let d1 = `<label><input type="checkbox" id="filter"${fcheck}> Filter by groups</label><details><summary>Description</summary><p>You can filter chapters by adding certain groups to a blacklist (so it\'s hidden) or whitelist (so it only shows that group releases), by clicking at the 🔧 besides the title. This only applies to 1 series at a time.</p></details>`
    let d2 = ''
    let body = `<h2>New MangaDex Follows Script Settings</h2>${d1+d2}<button id="nmdf_save" onclick="SC()" style="background-color: orangered;padding: 0.5rem;margin: 0.5rem;">Save Changes</button><button id="nmdf_exit" onclick="Close()">Exit</button>`
    let series = '<hr><button onclick="ReadNext()" style="padding: 0.5rem;background-color: var(--md-primary);">Check unread chapters</button><button onclick="ShowSD()" style="padding: 0.5rem;background-color: var(--md-secondary);margin: 0.5rem;">Check notification list</button>'

    function FindOrphans(){//1.2
        console.log("searching for orphans")
        let com = SafeLoad("completed")
        let ptr = SafeLoad("planto")
        let dro = SafeLoad("dropped")
        let rea = SafeLoad("reading")
        let onh = SafeLoad("onhold")

        let x = 0
        for(let s of seriesdex){
            let z = 0
            for(let y of [com,ptr,dro,rea,onh]) if(FS(y,s.id)>=0) z++
            if(z==0){
                console.log("an orphan!")
                console.log(s)
                if(FS(orphans,s.id) < 0) orphans.push(s)
                x++
            }
        }
        return x
    }

    if(FindOrphans()) series+='<button onclick="DisplayOrphans()">Orphan series</button>' //1.2
    daModal.firstChild.innerHTML= closebutton+body+series
    daModal.style.display = "block"
    if(unchecked){
        window.onclick = function(event) {
            var daModal = document.getElementById("daModal")
            if (event.target == daModal) {
                daModal.style.display = "none"
            }
        }
        unchecked = false
    }
}

window.Close = function(){
    document.getElementById("daModal").style.display = "none"
}

window.NMDFilter = function(event){
    if(document.URL.includes("/title/")) main()
    var daElement = event.target.parentElement.parentElement
    if(document.URL.includes("/title/")) daElement = document.getElementsByClassName(classChapter)[0].parentElement.parentElement.parentElement.parentElement.parentElement //1.3.2
    preevent = event //1.1.3.3
    var daModal = document.getElementById("daModal")
    let ttext
    let gtext = []
    let glink = []
    let id = getTID(daElement)
    if(document.URL.includes("/title/")) {
        id = getID3(document.URL)
        ttext = getCN("mb-1")[1].innerText //1.3.2
    }
    let daSeries = seriesdex[FS(seriesdex,id)]
    for(let link of getTAG(daElement,"a")){
        if(link.innerText != ""){
            console.debug(link) //1.3.2
            if(link.href.includes("/title/")) ttext = link.innerText.replaceAll("\n","")
            if(link.href.includes("/group/")) {
                if(!gtext.includes(link.innerText.replaceAll("\n",""))){
                    gtext.push(link.innerText.replaceAll("\n",""))
                    glink.push(link.href)
                }
            }
        }
    }
    let gtags = getCN2(daElement,chapterelement)
    for(let g of gtags){
        if(g.innerText.includes("No Group")){
            gtext.push("No Group")
            glink.push("0/0/0/0/0/0")
            break
        }
    }

    if(!daModal) createModal()
    let closebutton = '<span class="close" onclick="Close()">&times;</span>'
    let series = `<p id="${id}">SERIES NAME: ${ttext}</p>`
    if(document.URL.includes("/title/")){//1.2
        fstatus = getCN(loadedp)[0].firstChild.innerText //following status
        series+="<p>Status: "+fstatus.toUpperCase()+"</p>"
        let arrayname = getFstatus(fstatus)
        let temp
        if(arrayname != "planto") temp = SafeLoad(arrayname)
        daSeries = temp[FS(temp,id)]
    }
    if(daSeries.mu) series+=`<a href="https://www.mangaupdates.com/series.html?id=${daSeries.mu}" target="_blank" rel="noopener noreferrer">🔗 MangaUpdates Link 🔗</a>` //1.3.1
    if(daSeries.name == "") seriesdex[FS(seriesdex,id)].name = ttext
    let lastext = daSeries.last
    let lastvol = ""
    if(daSeries.lastv) {
        lastvol = "Vol "+daSeries.lastv
        lastext = " Ch "+daSeries.last //1.2
    }
    let nextext = daSeries.nextc
    if(daSeries.nextv) nextext = `Vol. ${daSeries.nextv} Ch. ${daSeries.nextc}`
    let nextlink = ''
    if(!!daSeries.nextl && !daSeries.nextl.includes(".")) nextlink = ` href="https://mangadex.org/chapter/${daSeries.nextl}"`
    if(daSeries.nextl && daSeries.nextl.includes(".")) nextlink = ` href="${daSeries.nextl}"` //1.2.3
    console.log(lastext)
    if(daSeries.last == MINNUM || daSeries.last == "-10" || JSON.parse(daSeries.last) == null) {
        lastext = "Not registered"
        nextext = "Not registered"
    }
    let last = `<div><span>Last chapter read: ${lastext}</span><button onclick="NewLast(event)">✍️</button></div>`
    let split = `<div><span>Split chapters?: </span><button onclick="SplitThis(event)">🪚</button></div>`
    if(daSeries.split) split = `<div><span>Split parts: ${daSeries.split}</span><button onclick="SplitThis(event)">🪚</button></div>`
    if(daSeries.lastv) last = `<div><span>Last chapter read: ${lastvol}</span><button onclick="NewLastV(event)">✍️ </button><span>${lastext}</span><button onclick="NewLast(event)">✍️</button></div>`
    if(nextext == MAXNUM) nextext = "Up to date"
    let next = `<div><a${nextlink}>Next chapter: ${nextext}</a><button onclick="ReloadFF()">⟳</button></div>`
    let groups = '<p>Groups:</p>'
    let daTable = '<table><tr><th>Name</th><th style="text-align: center;">Whitelisted</th><th style="text-align: center;">Blacklisted</th></tr>'//1.1.3.3
    for(let w=0;w<gtext.length;w++){
        let gid = getID3(glink[w])
        let wcheck = ""
        let bcheck = ""
        if(OnlyThis(id,[gid])==2) {
            wcheck = "checked"
            console.log(gtext[w]+" whitelisted")
        }
        if(HideThis(id,[gid])) {
            bcheck = "checked"
            console.log(gtext[w]+" blacklisted")
        }
        daTable+=`<tr><td><a href="https://mangadex.org/group/${gid}/" target="_blank" rel="noopener noreferrer">${gtext[w]}</a></td><td style="text-align: center;"><input type="checkbox" id="wl${w}" name="wl${w}" ${wcheck}></td><td style="text-align: center;"><input type="checkbox" id="bl${w}" name="bl${w}" ${bcheck}></td></tr>`//1.3.1 //1.1.3.
    }
    daTable+="</table>"
    let savebtn = '<div style="text-align: right;"><button onclick="SaveFilter(event)" style="margin: 0.5rem;">SAVE CHANGES</button></div>'

    daModal.firstChild.innerHTML= closebutton+series+next+last+split+groups+daTable+savebtn
    daModal.style.display = "block"
    if(unchecked){
        window.onclick = function(event) {
            var daModal = document.getElementById("daModal")
            if (event.target == daModal) {
                daModal.style.display = "none"
            }
        }
        unchecked = false
    }
}

window.ResetThis = function(event){//1.2.9
    if(document.URL.includes("/title/")){
        if(confirm(`Are you sure you want you reset this series' stored data?`)){//1.3
            console.log("Resetting")
            let nodo = event.target.parentElement.parentElement
            let id = nodo.children[1].id
            let temp = DefaultObj()
            temp.id = id
            let pseries = FS(seriesdex,id)
            let split = seriesdex[pseries].split //1.3
            seriesdex[pseries] = temp
            if(split) temp.split = split //1.3
            SafeSave("seriesdex",seriesdex)
            let fstatus = getCN(loadedp)[0].firstChild.innerText //following status
            if(fstatus == "Reading"){
                console.log("Resetting READING")
                let temp2 = SafeLoad("reading")
                let ptemp = FS(temp2,id)
                let thisSD = seriesdex[pseries]
                temp2[ptemp].id = thisSD.id
                temp2[ptemp].last = thisSD.last
                temp2[ptemp].mu = thisSD.mu
                temp2[ptemp].name = thisSD.name
                temp2[ptemp].nextc = thisSD.nextc
                temp2[ptemp].nextl = thisSD.nextl
                temp2[ptemp].time = thisSD.time
                if(split) temp2[ptemp].split = thisSD.split //1.3
                console.log(temp2[ptemp])
                SafeSave("reading",temp2)
            }
            else console.log(`Not READING, fstatus: ${fstatus}`)
            ReloadFF()
        }
    }
    else alert("To reset your data for this series go to its title page")

}

window.SaveFilter = function(event){
    let nodo = event.target.parentElement.parentElement
    if(document.URL.includes("/title/")) nodo = document.getElementById("daModal") //1.3.2

    function AddtoArray(array,id,gid){
        if(array.findIndex(q => q[0] == id && q[1] == gid) < 0) array.push([id,gid])
        return array
    }

    function RemoveFromArray(array,id,gid){
        let index = array.findIndex(q => q[0] == id && q[1] == gid)
        if(index >= 0) {
            array.splice(index,1)
            alert("Removed from the list")
        }
        return array
    }
    let count = 0
    let latabla = getTAG(nodo,"table")[0] //1.2
    for(let j of latabla.firstChild.children){
        if(j.cells[2].firstChild.checked) count++
    }
    if(count > 1){
        alert("There can only be one whitelisted group per series. If you want to block more than one group then you should add them to the blacklist")
    }
    else{
        for(let x=1; x<latabla.firstChild.childElementCount; x++){//1.2
            let gid = getGID(latabla.firstChild.children[x].cells[0]) //1.3.2 //1.1.3.3 getTID
            let wl = JSON.parse(latabla.firstChild.children[x].cells[1].firstChild.checked)
            let bl = JSON.parse(latabla.firstChild.children[x].cells[2].firstChild.checked)
            let id = 0 //1.3.2
            if(document.URL.includes("/title/")) id = getTID(document.URL)
            else id = nodo.children[1].id
            if(wl&&bl) alert("It can't be part of both lists")
            else if(wl) {
                whitelist = AddtoArray(whitelist,id,gid)
                alert("Whitelisted")
            }
            else if(bl) {
                blacklist = AddtoArray(blacklist,id,gid)
                alert("Blacklisted")
            }
            if(!wl) whitelist = RemoveFromArray(whitelist,id,gid)
            if(!bl) blacklist = RemoveFromArray(blacklist,id,gid)
        }
        SafeSave("whitelist",whitelist)
        SafeSave("blacklist",blacklist)
        alert("Changes saved successfully!") //1.3.2
    }
}

window.NewLast = function(event){//1.1.3.3
    LoadSD()
    var daElement = event.target.parentElement.parentElement
    // var daElement = event.target
    // while(daElement.tagName != "TR") daElement = daElement.parentElement
    var newvalue = prompt("Enter a new value for last read","1")
    var id = getTAG(daElement,"p")[0].id

    function Proceso(newvalue,i){
        if(i>=0){
            seriesdex[i].last = newvalue*1
            if(seriesdex[i].last >= seriesdex[i].nextc) seriesdex[i] = DefaultNext(seriesdex[i])
            if(document.URL.includes("/title/")){//1.2
                if(getCN(loadedp).length){
                    UpdateSD(getFstatus(getCN(loadedp)[0].firstChild.innerText),seriesdex[i])
                }
            }
            console.log("seriesdex entry:")
            console.log(seriesdex[i])
            SafeSave("seriesdex",seriesdex) //1.1.3.3
            ReloadFF()//1.1.3.3
        }
        else{
            if(document.URL.includes("/title/")){
                if(getCN(loadedp).length){
                    let arrayname = getFstatus(getCN(loadedp)[0].firstChild.innerText)
                    let temp = SafeLoad(arrayname)
                    let j = FS(temp,id)
                    temp[j].last = newvalue*1
                    if(temp[j].nextl && temp[j].nextc <= newvalue*1) temp[j] = DefaultNext(temp[j])
                    SafeSave(arrayname,temp)
                }
            }
            else console.log("error NewLast")
        }
    }

    if(Number.isNaN(newvalue*1)) alert("Enter a number!")
    else if(!newvalue){
        console.log("cancel by user")
    }
    else {
        console.log("New Last!")
        newvalue*=1
        let i = FS(seriesdex,id)
        if(newvalue < seriesdex[i].last){
            if(confirm("The new value is lower than the last one read, are you sure you want to set it to "+newvalue+"?")) Proceso(newvalue,i)
        }
        else{
            Proceso(newvalue,i)
        }
    }
}

window.NewLastV = function(event){//1.2
    LoadSD()
    var daElement = event.target.parentElement.parentElement
    var newvalue = prompt("Enter a new value for last vol","1")
    var id = getTAG(daElement,"p")[0].id
    if(Number.isNaN(newvalue*1)) alert("Enter a number!")
    else if(!newvalue){
        console.log("cancel by user")
    }
    else {
        console.log("New LastV!")
        newvalue*=1
        let i = FS(seriesdex,id)
        if(i >= 0){
            seriesdex[i].lastv = newvalue*1
            if(seriesdex[i].last >= seriesdex[i].nextc) seriesdex[i] = DefaultNext(seriesdex[i])
            if(document.URL.includes("/title/")){//1.2
                if(getCN(loadedp).length){
                    UpdateSD(getFstatus(getCN(loadedp)[0].firstChild.innerText),seriesdex[i])
                }
            }
            console.log("seriesdex entry:")
            console.log(seriesdex[i])
            SafeSave("seriesdex",seriesdex) //1.1.3.3
        }
        else{
            if(document.URL.includes("/title/")){
                if(getCN(loadedp).length){
                    let arrayname = getFstatus(getCN(loadedp)[0].firstChild.innerText)
                    let temp = SafeLoad(arrayname)
                    let j = FS(temp,id)
                    temp[j].lastv = newvalue
                    if(temp[j].nextv && temp[j].nextv < newvalue) temp[j] = DefaultNext(temp[j])
                    SafeSave(arrayname,temp)
                }
            }
            else console.log("error NewLastV")
        }

        ReloadFF()//1.1.3.3
    }
}

window.SplitThis = function(event){//1.2.7
    LoadSD()
    var daElement = event.target.parentElement.parentElement
    var newvalue = prompt("Enter a new value for split parts","2")
    var id = getTAG(daElement,"p")[0].id

    function Proceso(newvalue,i){
        if(i>=0){
            if(newvalue*1 >= 0) seriesdex[i].split = newvalue*1
            if(document.URL.includes("/title/")){
                if(getCN(loadedp).length){
                    UpdateSD(getFstatus(getCN(loadedp)[0].firstChild.innerText),seriesdex[i])
                }
            }
            console.log("seriesdex entry:")
            console.log(seriesdex[i])
            SafeSave("seriesdex",seriesdex)
            ReloadFF()
        }
        else{
            if(document.URL.includes("/title/")){
                if(getCN(loadedp).length){
                    let arrayname = getFstatus(getCN(loadedp)[0].firstChild.innerText)
                    let temp = SafeLoad(arrayname)
                    let j = FS(temp,id)
                    temp[j].split = newvalue*1
                    SafeSave(arrayname,temp)
                }
            }
            else console.error("error SplitThis")
        }
    }

    if(Number.isNaN(newvalue*1)) alert("Enter a number!")
    else if(!newvalue){
        console.log("cancel by user")
    }
    else {
        console.log("Split This!")
        newvalue*=1
        let i = FS(seriesdex,id)
        if(newvalue <= 1){
            if(confirm(`The new value is lower than 2, which would cancel the splitting, are you sure you want to set it to ${newvalue}?`)) Proceso(newvalue,i)
        }
        else{
            Proceso(newvalue,i)
        }
    }
}

window.ReloadFF = function(){
    main()
    //FollowsFeed()
    NMDFilter(preevent)
}

window.ShowSD = function(){//1.1.3.3
    console.log("ShowSD")
    FollowsFeed()
    var daModal = document.getElementById("daModal")
    if(!daModal) createModal()
    let reading = SafeLoad("reading")
    let daTable = '<table><tr><th>Name</th><th style="text-align: center;">Last Read</th><th style="text-align: center;">Next Chapter</th></tr>'
    for(let s of seriesdex){
        let name = s.name
        if(name == ""){
            let index = FS(reading,s.id)
            if(index >= 0) name = reading[index].name
        }
        if(s.nextc != MAXNUM && s.nextc > s.last+1.1) name+=" ‼️"
        let lastone = s.last
        if(lastone < 0 || lastone == null) lastone = '🚫'
        let nextone, nextlink
        if(s.nextl == null || s.nextl == "") {
            nextlink = ''
            nextone = '🚫'
        }
        else {
            nextlink = ` href="/chapter/${s.nextl}"`
            if(s.nextl.includes(".")) nextlink = ` href="${s.nextl}"` //1.2.3
            nextone = 'CH. '+s.nextc
        }
        daTable+=`<tr><td><a href="/title/${s.id}/${name.replace(/\W/g, '').replaceAll(" ","-")}" target="_blank" rel="noopener noreferrer">${name}</a></td><td style="text-align: center;"><span>${lastone} </span><button onclick="NewLast2(event)">✍️</button></td><td style="text-align: center;"><a${nextlink}>${nextone}</a></td></tr>` //1.3.1
    }
    daTable+="</table>"
    let closebutton = '<span class="close">&times;</span>'
    daModal.firstChild.innerHTML= closebutton+daTable
    var closebtn = getCN("close")[0]
    closebtn.onclick = function() {
        daModal.style.display = "none"
    }
}

window.NewLast2 = function(event){//1.1.3.3
    LoadSD()
    var daElement = event.target
    while(daElement.tagName != "TR") daElement = daElement.parentElement //1.2
    var newvalue = prompt("Enter a new value for last read","1")
    var id = getTID(daElement)
    let sid = FS(seriesdex,id) //1.2
    if(Number.isNaN(newvalue*1)) alert("Enter a number!")
    else if(!newvalue){
        console.log("cancel by user")
    }
    else {
        console.log("New Last2!")
        function McCloud(arraynode){//1.2
            arraynode.last = newvalue*1
            if(arraynode.last >= arraynode.nextc) arraynode = DefaultNext(arraynode)
            return arraynode
        }
        seriesdex[sid] = McCloud(seriesdex[sid])

        console.log(seriesdex[sid])
        SafeSave("seriesdex",seriesdex) //1.1.3.3
        FollowsFeed()
        //1.2
        let arrays = ["reading","completed","planto","onhold","dropped"]
        for(let a of arrays){
            let temp = SafeLoad(a)
            let index = FS(temp,seriesdex[sid].id)
            if(index >= 0){
                temp[index] = McCloud(temp[index])
                SafeSave(a,temp)
            }
        }
        ShowSD() //1.2
    }
}

window.NewLast3 = function(event){//1.2
    LoadSD()
    var daElement = event.target
    while(daElement.tagName != "TR") daElement = daElement.parentElement
    var newvalue = prompt("Enter a new value for last read","1")
    var id = getTID(daElement)

    if(Number.isNaN(newvalue*1)) alert("Enter a number!")
    else if(!newvalue){
        console.log("cancel by user")
    }
    else {
        console.log("New Last3!")
        let stat = getTAG(daElement,"td")[2].innerText
        let temp = []
        let sid = FS(seriesdex,id)
        let arrayname = getFstatus(stat) //1.2
        temp = SafeLoad(arrayname)
        let tid = FS(temp,id)

        function UpdateData(array,index){
            array[index].last = newvalue*1
            if(array[index].last >= array[index].nextc) array[index] = DefaultNext(array[index])
        }

        if(sid >= 0) {
            UpdateData(seriesdex,sid)
            console.log("seriesdex entry:")
            console.log(seriesdex[sid])
        }
        UpdateData(temp,tid)
        console.log(arrayname+" entry:")
        console.log(temp[tid])
        SafeSave("seriesdex",seriesdex) //1.1.3.3
        SafeSave(arrayname,temp) //1.2
        main() //1.2
    }
}

window.FS = function(array,number){//for debugging
    FS(array, number)
}

window.FF = function(){//for debugging
    FollowsFeed()
}

//THE MAIN FUNCTION
function main(){
    let logo = "ml-2 md:ml-4 cursor-pointer bg-accent rounded-full flex items-center justify-center" //1.3.4
    console.log("main")
    if(getCN(logo).length && getCN(logo)[0].firstChild.tagName == "IMG"){//is logged
        LoadSD()
        frutyloop = false
        if(document.URL.includes("https://mangadex.org/titles/follows")){
            console.log("Script ready")

            function EsperaBotones(){
                try{
                    let botones = getTAG(getCN("px-6 mb-4 mt-2")[0],"a")
                    }
                catch(e){
                    setTimeout(EsperaBotones,500)
                }
            }

            EsperaBotones()

            document.Fill = function(){
                console.log("Loading series...")
                alert("Please wait until the next alert, this can take several minutes depending of how many series you follow.")
                Llenar2()
            }

            function NewButton(){//moved - 1.2
                try{
                    let newb = document.createElement("button")
                    newb.innerHTML = '<button id="fill-btn" data-v-621772ff="" type="button" class="bg-primary v-btn v-btn--is-elevated v-btn--has-bg theme--dark v-size--default"><span class="v-btn__content"><span data-v-621772ff="" aria-hidden="true" class="v-icon notranslate theme--dark" onclick="Fill()"><a>FILL</a></span></span></button>'
                    if(!document.getElementById("fill-btn")) getCN("controls mb-auto ml-auto")[0].appendChild(newb)

                    let titulo = getCN("flex items-center mb-6 mt-2")[0]
                    let dl = cloneDOM('div',titulo)//document.createElement("div")
                    dl.id="dlbtn"
                    dl.innerHTML='<button class="rounded relative md-btn flex items-center px-3 my-6 justify-center text-white bg-primary hover:bg-primary-darken active:bg-primary-darken2 glow px-4 px-6" onclick="DownloadCSV()" style="margin-left: 0.5rem;margin-right: 1rem;background-color: var(--md-primary);border-width: 0.5rem;border-color: var(--md-primary);">Download CSV</button><button class="rounded relative md-btn flex items-center px-3 my-6 justify-center text-white bg-primary hover:bg-primary-darken active:bg-primary-darken2 glow px-4 px-6" onclick="DownloadJSON()" style="margin-left: 0.5rem;margin-right: 1rem;background-color: var(--md-primary);border-width: 0.5rem;border-color: var(--md-primary);">Download JSON</button>'
                    if(!!!document.getElementById("dlbtn") && !!dl) titulo.insertAdjacentElement('afterend',dl)
                }
                catch(e){
                    setTimeout(NewButton,500)
                }
            }
            if(!document.getElementById("dlbtn")) NewButton()
        }

        if(document.URL.includes("mangadex.org/titles/feed")){
            console.log("checking feed")
            function ScriptForm(){//moved - 1.2
                if(document.URL.includes("https://mangadex.org/titles/feed") && !document.getElementById("script_btn")){
                    console.log("executing ScriptForm")
                    var options_loc = "flex items-center mb-6" //1.2.8
                    if(getCN(options_loc).length){
                        var newButton = newInner("div","",'<button id="script_btn" onclick="NMDF()" style="right: 2rem;position: absolute;">📜 SCRIPT SETTINGS</button>')
                        getCN(options_loc)[0].append(newButton.children[0])
                        console.log("form added")
                    }
                    else setTimeout(ScriptForm,500)
                }
            }
            follows = []
            ScriptForm()

            if(getCN(feedone).length) FollowsFeed()
            else {//1.3.3
                console.log("waiting for FollowsFeed")
                setTimeout(main,2000)
            }
        }

        if(document.URL.includes("mangadex.org/title/")){
            console.log("Checking a series")
            var fstatus
            whitelist = SafeLoad("whitelist")
            blacklist = SafeLoad("blacklist")
            var chgrid = "chapter-grid"
            var id_series = getID3(document.URL)//moved 1.2.8 //1.2 //document.URL.split("/")[4]
            function UpdatingSeriesData(){
                var toConsider = ["Reading","Completed","On Hold","Dropped","Added To Library"]
                let timestamp = 0 //1.2
                let mu = 0 //1.2
                fstatus = getCN(loadedp)[0].firstChild.innerText //following status
                if(getCN(loadedp).length && getCN(chgrid).length){//if page is loaded
                    console.log("loaded")
                    var toProcess = false
                    let daIndex = FS(seriesdex,id_series)
                    var daLast = MINNUM
                    if(daIndex >= 0) daLast = seriesdex[daIndex].last
                    var daLastV = null
                    var daNext,daNLink,lastl //1.2.7
                    DefNext()
                    var nextvol = MAXNUM
                    var tags = getCN("tag bg-accent")
                    var volChange = getCN("col-span-4")
                    var sus = false
                    let prevvol = null
                    console.log("fstatus: "+fstatus)
                    if(fstatus == ""){
                        setTimeout(UpdatingSeriesData,500)
                        return
                    }
                    for(let x of getTAG(getCN("readmore")[0],"a")){//1.2
                        if(x.href.includes("mangaupdates")) mu = x.href.split("=")[1]*1
                    }

                    function GetChapter(dc,dv){//1.2
                        let current
                        if(dc.innerText.includes("BLOCKED (")) return 0 //1.3.4
                        if(dc.innerText.toLowerCase().includes("oneshot")) current = 0 //1.1.3.3
                        else if(dc.innerText.includes("Ch.")) current = GetNumero(dc.innerText)
                        else {
                            let turkey = dc.parentElement
                            while(!turkey.innerText.includes("Chapter ") && turkey != dv) turkey = turkey.parentElement
                            if(turkey.innerText.includes("Volume ")) current = 0
                            else current = GetNumero(turkey.innerText)
                        }
                        return current
                    }

                    function DefNext(){//1.2
                        daNext = MAXNUM
                        daNLink = null
                    }

                    function getVol(txt){//moved 1.2.5
                        let temp = txt.replaceAll("\n"," ").replaceAll("\t"," ")
                        for(let t of temp.split(" ")){
                            if(Number.isFinite(t*1)) return t*1
                        }
                        return 0
                    }

                    if(!sus){
                        for(let v of document.getElementsByClassName("grid grid-cols-12 volume-head mb-2")){
                            if(v.innerText.includes("No Volume")){
                                console.log("volume sorting doesn't apply!")
                                break
                            }
                            if((v.innerText.includes("Ch. 1 -") || v.innerText.includes("Ch. 0 -")) && getVol(v.innerText) > 1){
                                console.log("SUS!")
                                sus = true
                                break
                            }
                        }
                    }

                    function Apoo(){
                        if(toConsider.includes(fstatus)){//(fstatus == "Reading"){
                            console.log("reading series:")
                            console.log(seriesdex[daIndex])
                            toProcess = true
                            let continuar = true //1.2

                            function DefaultProcess(dv,dc,current,currvol){//1.2
                                let cid = getTID(dc)
                                if(forbidden.includes(cid)){//if chapter is marked as forbidden
                                    console.log("forbidden chapter "+cid)
                                    if((!HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==2) && OnlyThis(id_series,getGID(dc))!=1 && HasBeenRead(dc) == false){//1.2.5
                                        CleanFB(dc)
                                    }
                                    else if(GetChapter(dc,dv) > seriesdex[daIndex].last) getTAG(dc,"svg")[0].style.color = "red"
                                    else{
                                        if(getTAG(dc,"svg")[0].style.color) getTAG(dc,"svg")[0].style.removeProperty("color")
                                        CleanFB(dc)
                                    }
                                    if(seriesdex[daIndex].nextl == cid) {
                                        seriesdex[daIndex] = DefaultNext(seriesdex[daIndex]) //if it's stored as next one, ignore it
                                    }
                                }
                                else if(HasBeenRead(dc) == false){//1.3
                                    if((!HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==2) && OnlyThis(id_series,getGID(dc))!=1 && HasBeenRead(dc) == false && daNext >= current && daNext > daLast && current > daLast){
                                        daNext = current
                                        console.log("daNext: "+daNext)
                                        daNLink = cid//getTID(dc)
                                        console.log("daNLink: "+daNLink)
                                    }
                                    else if((HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==1) && HasBeenRead(dc) == false){// && daNext > current && daNext > daLast){//not consider if it's blacklisted
                                        if(daNext >= current && daNext > daLast && current > daLast){//1.2
                                            FBPush(cid)
                                        }
                                        if(current <= daLast){ //check for a forbidden chapter that can be ignored
                                            console.log(`ignore ${cid} for forbidden`)
                                            CleanFB(dc)
                                        }
                                        if(daIndex >= 0 && cid == seriesdex[daIndex].nextl){//ignores a next chapter if it's blacklisted
                                            console.log("reseting daNext")
                                            DefNext()
                                        }
                                    }
                                }
                                else if(!(HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==1) && HasBeenRead(dc) == true){//1.3
                                    if(cid == seriesdex[daIndex].lastl) {
                                        if(current != last){
                                            ResetLast(id_series,{id:current,l:cid})
                                        }
                                        let thistmp = (new Date(getTAG(dc,"time")[0].dateTime)).getTime()
                                        if(thistmp > timestamp) timestamp = thistmp
                                        if(daNext <= daLast) {
                                            DefNext()
                                        }
                                        console.log("found a last one: "+daLast)
                                    }
                                    if(daLast < current){
                                        daLast = current
                                        let thistmp = (new Date(getTAG(dc,"time")[0].dateTime)).getTime()
                                        if(thistmp > timestamp) timestamp = thistmp
                                        if(daNext <= daLast) {
                                            DefNext()
                                        }
                                        console.log("found a last one: "+daLast)
                                    }
                                }
                                else CleanFB(dc)
                            }

                            function VolProcess(dv,dc,current,currvol){//1.2
                                function ASSign(){
                                    daNext = current
                                    console.log("daNext: vol "+currvol+" chap "+daNext)
                                    daNLink = getTID(dc)
                                    console.log("daNLink: "+daNLink)
                                }

                                function FoundLast(){
                                    daLast = current
                                    lastl = getTID(dc) //1.2.7
                                    let thistmp = (new Date(getTAG(dc,"time")[0].dateTime)).getTime()
                                    if(thistmp > timestamp) timestamp = thistmp
                                    if(daNext <= daLast) DefNext()
                                    console.log("found a last one: "+daLast)
                                }

                                if(HasBeenRead(dc) == true){
                                    console.log("sus checking vol "+GetNumero(dv.parentElement.innerText)+" ch "+current)
                                    if(currvol > daLastV){
                                        daLastV = currvol
                                        FoundLast()
                                    }
                                    else if(currvol == daLastV){
                                        if(daLast < current) FoundLast()
                                    }
                                    //currvol < daLastV are irrelevant
                                }
                                else{//unread chapters
                                    let cid = getTID(dc)
                                    if((!HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==2) && OnlyThis(id_series,getGID(dc))!=1){//to consider
                                        if(daLastV == currvol && daNext >= current && daNext > daLast) ASSign()
                                        else if(daLastV < currvol && nextvol >= daLastV){
                                            if(nextvol > currvol) {
                                                nextvol = currvol
                                                ASSign()
                                            }
                                            else if(nextvol == currvol) ASSign()
                                        }
                                    }
                                    else if((HideThis(id_series,getGID(dc)) || OnlyThis(id_series,getGID(dc))==1)){// && daNext > current && daNext > daLast){//not consider if it's blacklisted
                                        if(daNext >= current && daNext > daLast){//1.2
                                            FBPush(cid)
                                            if(daIndex >= 0 && cid == seriesdex[daIndex].nextl){//ignores a next chapter if it's blacklisted
                                                console.log("reseting daNext")
                                                DefNext()
                                            }
                                        }
                                        if(current < daLast) {
                                            console.log(`${cid} can be ignored (sus)`)
                                            CleanFB(dc)
                                            dc.style.removeProperty("color")
                                        }
                                    }
                                }
                            }

                            function Splitter(){//1.2.7
                                let markit = true
                                if(daIndex >= 0) for(let dv of getCN("rounded flex flex-col gap-2")){
                                    for(let dc of getCN2(dv,chgrid)){
                                        let current = GetChapter(dc,dv)
                                        let currvol = getVol(dv.parentElement.innerText)
                                        if(seriesdex[daIndex].split == getDec(current,1)){
                                            markit = false
                                            DeMark()
                                        }
                                        if(markit && HasBeenRead(dc) == false) SPPush([seriesdex[daIndex].id,getTID(dc),current])
                                        else if(!markit) DeMark()
                                    }
                                }
                            }

                            if(daIndex >= 0) for(let dv of getCN("rounded flex flex-col gap-2")){
                                for(let dc of getCN2(dv,chgrid)){
                                    let current = GetChapter(dc,dv)
                                    let currvol = getVol(dv.parentElement.innerText) //1.2.5
                                    if(sus) VolProcess(dv,dc,current,currvol)
                                    else DefaultProcess(dv,dc,current,currvol) //1.2
                                }
                            }
                            return true
                        }
                        return false
                    }
                    function UpdateStorage(obj,item){//1.1.3.3
                        let temp = SafeLoad(item) //1.2
                        let index = FS(temp,obj.id)
                        if(index >= 0){//1.2
                            console.log("it's part of "+item)
                            console.log(obj)
                            if(obj.nextl && !document.body.innerHTML.includes(obj.nextl)){//1.2.7
                                console.log(`next chapter (${obj.nextc}) unavailable`)
                                obj.nextc = MAXNUM
                                obj.nextl = null
                            }
                            if(obj.name == "MangaDex") obj.name = temp[index].name
                            if(obj.last >= temp[index].last){
                                console.log("new last is equal or greater than last registered")
                                console.log("old: "+temp[index].last)
                                console.log("new: "+obj.last)
                                if(obj.lastv == temp[index].lastv) {
                                    temp[index] = obj
                                    console.log("same volume, new chapter")
                                }
                                if(obj.lastv && temp[index].lastv && obj.lastv >= temp[index].lastv) {
                                    temp[index] = obj
                                    console.log("new volume")
                                }
                                if(!obj.lastv && temp[index].lastv){
                                    temp[index] = obj
                                    console.log("was stored as volume but it shouldn't")
                                }
                                if(!temp[index].lastv){
                                    temp[index] = obj
                                    if(obj.lastv) console.log("now consider with volume sorting")
                                    else console.log("no volume sorting")
                                }
                            }
                            else{
                                console.log("new last is lower than last registered, checking for volume sorting")
                                if(temp[index].lastv && obj.lastv && temp[index].lastv <= obj.lastv) {
                                    temp[index] = obj
                                    console.log("new volume")
                                }
                                if(!temp[index].nextv && obj.nextv) {
                                    temp[index] = obj
                                    console.log("new chapter")
                                }
                                if(temp[index].nextv && obj.nextv && temp[index].nextv < obj.nextv) {
                                    temp[index] = obj
                                    console.log("new unread chapter on new volume")
                                }
                                if(obj.nextl && temp[index].last < obj.nextc){
                                    temp[index].nextc = obj.nextc
                                    temp[index].nextl = obj.nextl
                                    console.log("new unread chapter but earlier last read")
                                }
                                if(!obj.nextl){
                                    temp[index].nextc = obj.nextc
                                    temp[index].nextl = obj.nextl
                                    console.log("no next unread chapter")
                                }
                                if(obj.mu && !temp[index].mu){
                                    temp[index].mu = obj.mu
                                    console.log("added mangaupdates link")
                                }
                                if(!temp[index].time && obj.time){
                                    temp[index].time = obj.time
                                    console.log("added update time")
                                }
                            }
                            RevisaNext(temp[index])
                        }
                        else{//if(index == -1)
                            temp.push(obj)
                            console.log("added to "+item+"!")
                        }
                        SafeSave(item,temp)
                        console.log("stored changes in "+item+"!")
                        console.log(temp[index])
                        console.log("index: "+index)
                        // return temp[index] //1.2
                    }
                    var removedsd = false

                    function Registrar(){ //1.1.3.3
                        let manga
                        let marked = false
                        if(sus) manga = {id:id_series, mu:mu, name:document.title.replace(" - MangaDex",""), last:daLast, lastl:lastl, lastv: daLastV, nextv:nextvol, nextc:daNext, nextl:daNLink, time:timestamp} //1.2.7
                        else manga = {id:id_series, mu:mu, name:document.title.replace(" - MangaDex",""), last:daLast, lastl:lastl, nextc:daNext, nextl:daNLink, time:timestamp} //1.2.7
                        //1.2.7
                        if(daIndex >= 0 && seriesdex[daIndex].split) manga.split = seriesdex[daIndex].split
                        if(daIndex >= 0 && seriesdex[daIndex].aval) manga.aval = seriesdex[daIndex].aval

                        let campana = (getTAG(getCN("sm:ml-2")[0],"svg")[0].firstChild.getAttribute("d") == "M18 8A6 6 0 1 0 6 8c0 7-3 9-3 9h9m6.63-4A17.888 17.888 0 0 1 18 8m-4.27 13a2 2 0 0 1-3.46 0M17 18l2 2 4-4") //1.2.6
                        let blink = getFstatus(fstatus)
                        UpdateStorage(manga,blink)
                        if(daIndex >= 0) {
                            // LoadSD()
                            CompareSD(blink,seriesdex[daIndex]) //1.2
                        }
                        if(campana) {
                            UpdateStorage(manga,"seriesdex")
                        }
                        else marked = true
                        if(marked) RemoveFromSD(manga.id)

                        //Delete duplicates //1.2
                        console.log("Checking for duplicates")
                        for(let c of ["Completed","Plan to Read","On Hold","Dropped","Reading"]){
                            if(c != fstatus){
                                let namevar = getFstatus(c)
                                if(namevar){
                                    console.log("Checking "+namevar)
                                    let temp = SafeLoad(namevar) //1.2
                                    let index = FS(temp,id_series)
                                    if(index >= 0){
                                        console.log("Duplicated in "+namevar)
                                        console.log(temp[index])
                                        temp.splice(index,1)
                                        SafeSave(namevar,temp)
                                        console.log("Deleted from "+namevar)
                                    }
                                }
                            }
                        }
                        console.log("reference:")
                        console.log(manga)

                        console.log("the one registered in "+fstatus+":")
                        let final = SafeLoad(blink)
                        let k = FS(final,id_series)
                        console.log(final[k])
                        return true
                    }
                    function LoadWBS(){
                        let ww = getCN("flex gap-x-2")[0]
                        let newbtn = cloneDOM("div",ww)
                        newbtn.id="FilterG"
                        newbtn.innerHTML = '<button data-v-cae07f5c="" data-v-4e000227="" class="rounded relative md-btn flex items-center" style="min-height: 48px; min-width: 220px;" onclick="NMDFilter(event)"><!----> <span data-v-cae07f5c="" class="flex items-center justify-center font-medium select-none" style="pointer-events: none;"><!---->🔧 WHITE/BLACKLIST GROUPS HERE 🔧</span></button>'
                        if(!document.getElementById("FilterG")) {//1.3.2
                            let xx = document.getElementsByClassName("nav-bar-search")[0]
                            xx.parentElement.insertBefore(newbtn,xx)
                        }
                        createModal()
                    }
                    if(Apoo() && daIndex >= 0){
                        LoadWBS()
                        if(seriesdex[daIndex].name != document.title.replace(" - MangaDex","") && document.title != "MangaDex") seriesdex[daIndex].name = document.title.replace(" - MangaDex","")
                        console.log("previous last: "+seriesdex[daIndex].last)
                        console.log("updating values")
                        if(Registrar() && !removedsd) console.log("new last: "+seriesdex[daIndex].last)
                    }
                    else if(daIndex >= 0){//fixes bug that adds everything
                        if(!toConsider.includes(fstatus)) seriesdex.splice(daIndex,1)//1.1.3.2
                        console.debug("fixing old bug")
                        SafeSave("seriesdex",seriesdex)//1.1.3.3
                    }
                    else if(daIndex == -1 && toProcess){//not registered
                        if(fstatus == "Reading") console.log("new series!")//1.1.3.3
                        Registrar()
                        LoadWBS()
                    }
                    if(FS(seriesdex,id_series) >= 0) {
                        LoadWBS()
                        console.log("seriesdex entry:")
                        console.log(seriesdex[FS(seriesdex,id_series)])
                    }
                }
                else if(getCN("text-center").length && getCN("text-center")[0].innerText == "No Chapters"){
                    console.log("no chapters!")
                    let daIndex = FS(seriesdex,getID3(document.URL))
                    for(let x of getTAG(getCN("readmore")[0],"a")){//1.2
                        if(x.href.includes("mangaupdates")) {
                            mu = x.href.split("=")[1]*1
                            console.log("mu: "+mu)
                        }
                    }

                    function LoadWBS(){//1.2
                        let ww = getCN("track")[0].parentElement.parentElement //1.3.2 getCN("text-center")[0].parentElement
                        let newbtn = cloneDOM("div",ww)
                        newbtn.id="FilterG"
                        newbtn.innerHTML = '<button data-v-cae07f5c="" data-v-4e000227="" class="rounded relative md-btn flex items-center" style="min-height: 48px; min-width: 220px;" onclick="NMDFilter(event)"><!----> <span data-v-cae07f5c="" class="flex items-center justify-center font-medium select-none" style="pointer-events: none;"><!---->🔧 WHITE/BLACKLIST GROUPS HERE 🔧</span></button>'
                        if(!document.getElementById("FilterG")) {//1.3.2
                            let xx = document.getElementsByClassName("nav-bar-search")[0]
                            xx.parentElement.insertBefore(newbtn,xx)
                        }
                        createModal()
                    }

                    function Empty(){//1.2
                        console.log("Empty()")
                        let temp = {id: getID3(document.URL),mu:mu,name: document.title.replace(" - MangaDex",""),last: MINNUM,nextc: MAXNUM,nextl: null, time:timestamp}
                        function UpdateEmpty(arrayname,obj){
                            console.log("mu ue "+arrayname+": "+mu)
                            console.log("reference data:")
                            console.log(obj)
                            let dummy = SafeLoad(arrayname)
                            let index = FS(dummy,obj.id)
                            dummy[index].mu = mu
                            obj.mu = mu
                            if(!obj.time && dummy[index].time) obj.time = dummy[index].time
                            if(index >= 0) {
                                console.log(arrayname+" data:")
                                console.log(dummy[index])
                                if(dummy[index].last < 0 && dummy[index].nextl == null) dummy[index] = obj
                                //else it has previous data
                            }
                            else dummy.push(obj)
                            SafeSave(arrayname,dummy)
                            console.log("new data ("+arrayname+"):")
                            console.log(dummy[index])
                        }
                        if(fstatus == "Reading") {
                            UpdateEmpty("reading",temp)
                            UpdateEmpty("seriesdex",temp)
                            if(daIndex >= 0) CompareSD("reading",seriesdex[daIndex])
                        }
                        else if(fstatus == "On Hold") {
                            UpdateEmpty("onhold",temp)
                            if(daIndex >= 0) CompareSD("onhold",seriesdex[daIndex])
                        }
                        else if(fstatus == "Dropped") {
                            UpdateEmpty("dropped",temp)
                            if(daIndex >= 0) CompareSD("dropped",seriesdex[daIndex])
                        }
                    }

                    if(getCN("w-full").length){
                        for(let f of getCN("w-full")){
                            if(fstatus == "Completed" && f.innerText.includes("Final Chapter")){
                                let completed = SafeLoad("completed")
                                let temp = {id: getID3(document.URL),mu:mu,name: document.title.replace(" - MangaDex",""),last: GetNumero(f.innerText), time:timestamp}
                                let index = FS(completed,temp.id)
                                if(index >= 0) completed[index] = temp
                                else completed.push(temp)
                                SafeSave("completed",completed)
                                console.log("new data (completed):")
                                console.log(temp)
                                if(FS(seriesdex,temp.id) >= 0){
                                    seriesdex.splice(FS(seriesdex,temp.id),1)
                                    console.log("removed from seriesdex!")
                                    SafeSave("seriesdex",seriesdex)
                                }
                            }
                        }
                        Empty() //1.2
                    }
                    else if(toConsider.includes(fstatus)){//1.1.3.3
                        Empty() //1.2
                    }
                    LoadWBS() //1.2
                }
                else setTimeout(UpdatingSeriesData,500)
            }
            try{
                UpdatingSeriesData()
            }
            catch(e){
                console.log("catch UpdatingSeriesData")
                if(document.getElementsByClassName("flex flex-col items-center").length && document.getElementsByClassName("flex flex-col items-center")[0].innerText == "404: Title not found") RemoveFromSD(id_series)
                else setTimeout(UpdatingSeriesData,1000)
            }
        }

        if(document.URL.includes("https://mangadex.org/chapter/")){//1.2
            try{
                if(!titlepage) titlepage = getTAG(getCN("menu flex-col")[0],"a")[0].href
                let current = GetNumero(getCN("placeholder-text")[1].innerText)
                let sid = getID3(titlepage)
                let chid = getID3(document.URL)
                let pseries = FS(seriesdex,sid)
                if(forbidden.includes(chid)){
                    console.log("FORBIDDEN!!")
                    window.location.href = titlepage
                }
                if(pseries >= 0 && current){//1.2.2
                    if(current > seriesdex[pseries].last){
                        console.log(`${getCN("ml-4")[1].innerText}'s previous last: ${seriesdex[pseries].last}`)
                        seriesdex[pseries].last = current
                        console.log(`${getCN("ml-4")[1].innerText}'s new last: ${seriesdex[pseries].last}`)
                        seriesdex[pseries] = DefaultNext(seriesdex[pseries])
                        console.log(seriesdex[pseries])
                        SafeSave("seriesdex",seriesdex)
                    }
                }
            }
            catch(e){//1.2.2
                console.log("External link?")
                for(let sd of seriesdex){
                    if(document.URL.includes(sd.nextl)){
                        let pseries = FS(seriesdex,sd.id)
                        sd.last = sd.nextc
                        sd = DefaultNext(sd)
                        console.log(`${document.title.split(" - ")[1]}'s new last: ${seriesdex[pseries].last}`)
                        SafeSave("seriesdex",seriesdex)
                        break
                    }
                }
            }

            // let nextlink = null
            // let menuclass = "menu flex flex-col gap-2 bg-background p-4"//"menu flex flex-col gap-2 bg-background p-4 open pinned"
            // if(getCN(menuclass)[0].children[4].children[2].href) nextlink = getCN(menuclass)[0].children[4].children[2].href
            // if(nextlink && forbidden.includes(getTID(nextlink))){//it's a blacklisted chapter
            //     if(getCN("md--pages")[0].firstChild.childElementCount == document.URL.split("/")[5]*1){//last page
            //         alert("Next chapter is blacklisted. Don't click it if you don't want to read it. Ctrl+M to go to title page.")
            //     }
            // }

        }

        if(document.URL.includes("https://mangadex.org/user/me")){//1.2
            function DisplayTabla(){
                if(getCN("select__tab-active")[0].innerText == "Info"){
                    let com = SafeLoad("completed")
                    let ptr = SafeLoad("planto")
                    let dro = SafeLoad("dropped")
                    let rea = SafeLoad("reading")
                    let onh = SafeLoad("onhold")
                    let daTable = '<tr><th>Name</th><th class="centered">MU Link</th><th class="centered">Status</th><th class="centered">Last Read</th><th class="centered">Next</th><th class="centered">Last Update</th></tr>'
                    function LlenarTabla(array,stat){
                        for(let a of array){
                            let mulink = ''
                            let mubody = '🚫'
                            if(a.mu){
                                mulink = ` href="https://www.mangaupdates.com/series.html?id=${a.mu}"`
                                mubody = '🔗'
                            }
                            let stamp = '⚠️'
                            if(a.time) stamp = (new Date(a.time)).toLocaleDateString()
                            let lastone = '🚫'
                            if(JSON.parse(a.last) != null && a.last > MINNUM) {
                                if(!a.lastv) lastone = a.last
                                else lastone = "v"+a.lastv+"c"+a.last
                            }
                            let nextone = '🚫'
                            let nextlink = ''
                            if(a.nextl){
                                nextone = a.nextc
                                if(a.nextv) nextone = "v"+a.nextv+"c"+a.nextc
                                nextlink = ` href="/chapter/${a.nextl}"`
                                if(a.nextl.includes(".")) nextlink = ` href="${a.nextl}"` //1.2.3
                            }
                            let bell = '🔕'
                            if(FS(seriesdex,a.id) >= 0) bell = '🔔 '
                            daTable+=`<tr><td><a class="levy" href="/title/${a.id}" title="${a.name.replaceAll('"','$').replaceAll("<",'\<').replaceAll(">",'\>')}">${bell+a.name}</a></td><td class="centered"><a${mulink}>${mubody}</a></td><td class="centered">${stat}</td><td class="centered"><div style="display: flex;justify-content: center;"><span>${lastone} </span><button onclick="NewLast3(event)">✍️</button></div></td><td class="centered"><a${nextlink}>${nextone}</a></td><td class="centered">${stamp}</td></tr>`
                        }
                    }
                    LlenarTabla(rea,"Reading")
                    LlenarTabla(onh,"On Hold")
                    LlenarTabla(dro,"Dropped")
                    LlenarTabla(ptr,"Plan to Read")
                    LlenarTabla(com,"Completed")
                    let divTabla = newInner("table","table",daTable)
                    divTabla.id = "divTabla"
                    divTabla.style.display = "grid"
                    if(!document.getElementById("divTabla")){
                        let target = null
                        if(getCN("px-6 page-container").length) target = getCN("px-6 page-container")[0].parentElement.parentElement
                        if(target) target.append(divTabla)
                        else setTimeout(target.append(divTabla),500)
                    }
                    else document.getElementById("divTabla").innerHTML = daTable
                }
            }
            DisplayTabla()
        }

        if(document.URL.includes("https://mangadex.org/group/")){
            blacklist = SafeLoad("blacklist")
            let gid = getID3(document.URL)
            let boton = getCN("rounded md-btn px-4")[0]
            let newboton = cloneDOM("button",boton)
            if(blacklist.findIndex(q => q[0] == 0 && q[1] == gid) < 0) {
                newboton.innerText = "Blacklist this"
                newboton.setAttribute("onclick","BLThis()")
            }
            else {
                newboton.innerText = "Remove from blacklist"
                newboton.setAttribute("onclick","unBLThis()")
            }
            boton.parentElement.append(newboton)
        }
    }
    else setTimeout(main,5000)
}

window.BLThis = function(){//1.2.2
    let gid = getID3(document.URL)
    blacklist = SafeLoad("blacklist")
    if(blacklist.findIndex(q => q[0] == 0 && q[1] == gid) < 0) blacklist.push([0,gid])
    SafeSave("blacklist",blacklist)
    alert(`${document.title.split(" - ")[0]} marked as globally blacklisted`)
    let boton = getCN("rounded md-btn px-4")[1]
    boton.innerText = "Remove from blacklist"
    boton.setAttribute("onclick","unBLThis()")
}

window.unBLThis = function(){//1.2.2
    let gid = getID3(document.URL)
    blacklist = SafeLoad("blacklist")
    let index = blacklist.findIndex(q => q[0] == 0 && q[1] == gid)
    if(index >= 0) blacklist.splice(index,1)
    SafeSave("blacklist",blacklist)
    alert(`${document.title.split(" - ")[0]} removed from globally blacklisted`)
    let boton = getCN("rounded md-btn px-4")[1]
    boton.innerText = "Blacklist this"
    boton.setAttribute("onclick","BLThis()")
}

document.addEventListener('keydown', function(event) {
    if(document.URL.includes("/chapter/") && event.ctrlKey && (event.key === 'm' || event.key === 'M')){
        window.location.href = titlepage
        // localStorage.setItem("reader.hidePagebar",0) //1.2.3
    }
});

//EXPORT FUNCTIONS
function exportToJsonFile(jsonData) {
    let dataStr = JSON.stringify(jsonData);
    let dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);

    let exportFileDefaultName = 'seriesdex.json';

    let linkElement = document.createElement('a');
    linkElement.setAttribute('href', dataUri);
    linkElement.setAttribute('download', exportFileDefaultName);
    linkElement.click();
}

function parseJSONToCSVStr(jsonData) {
    if(jsonData.length == 0) {
        return '';
    }

    let keys = Object.keys(jsonData[0]);

    let columnDelimiter = '\t';
    let lineDelimiter = '\n';

    let csvColumnHeader = keys.join(columnDelimiter);
    let csvStr = csvColumnHeader + lineDelimiter;

    jsonData.forEach(item => {
        keys.forEach((key, index) => {
            if( (index > 0) && (index < keys.length) ) {
                csvStr += columnDelimiter;
            }
            csvStr += item[key];
        });
        csvStr += lineDelimiter;
    });

    return encodeURIComponent(csvStr);;
}

function exportToCsvFile(jsonData) {
    let csvStr = parseJSONToCSVStr(jsonData);
    let dataUri = 'data:text/csv;charset=utf-8,'+ csvStr;

    let exportFileDefaultName = 'MangaDexFollowFeed.csv';

    let linkElement = document.createElement('a');
    linkElement.setAttribute('href', dataUri);
    linkElement.setAttribute('download', exportFileDefaultName);
    linkElement.click();
}

function PrepareData(lala){
    var temp = []
    let reading = SafeLoad("reading")
    let planto = SafeLoad("planto")
    let onhold = SafeLoad("onhold")
    let dropped = SafeLoad("dropped")
    let completed = SafeLoad("completed")

    function Processing(arrayy,naame){
        for(let a of arrayy){
            let last,daTime
            if(lala){
                //if(a.last*1 < 0 || JSON.parse(a.last) == null) last = "unregistered"
                if(a.last*1 < 0 || a.last == null) last = "unregistered"
                else last = a.last
                if(a.time) daTime = new Date(a.time).toLocaleString()
                else daTime = "unregistered"
            }
            else {
                last = a.last
                daTime = a.time
            }
            temp.push({id:a.id,mu:a.mu,name:a.name,state:naame,last:last, time:(new Date(a.time).toLocaleString())})
            if(temp.length == 0) temp = [{id:a.id,mu:a.mu,name:a.name,state:naame,last:last, time:(new Date(a.time).toLocaleString())}]
        }
    }

    if(reading.length+planto.length+onhold.length+dropped.length+completed.length){
        Processing(reading,"Reading")
        Processing(onhold,"On Hold")
        Processing(planto,"Plan to Read")
        Processing(dropped,"Dropped")
        Processing(completed,"Completed")
        return temp
    }
    else{
        alert("There's no data. Please press the FILL button to collect the data")
        return null
    }
}

window.DownloadCSV = function(){
    exportToCsvFile(PrepareData(true))
}

window.DownloadJSON = function(){
    exportToJsonFile(PrepareData(false))
}

// document.onscroll = function(){
//     var w = document.documentElement.clientHeight;
//     var over = document.documentElement.scrollTopMax;
//     if(document.documentElement.scrollTop < over) trigger = true
//     if(w < over && document.documentElement.scrollTop == over) {
//         if(trigger && !filling) setTimeout(main,500)
//         trigger = false
//     }
// }