Fiction.Live Merged

An attempt to improve fiction.live through the addition of various features.

As of 2021-02-04. See the latest version.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Fiction.Live Merged
// @namespace    http://tampermonkey.net/
// @version      32.1
// @description  An attempt to improve fiction.live through the addition of various features.
// @author       You
// @match        https://fiction.live/*
// @grant        none
// @run-at       document-idle
// @noframes
// ==/UserScript==

(function() {
    'use strict';
    function insertCSS(){
        var css=`
    #liveBox{
      display:block;
      height:100%;
      width:auto;
      float:right;
      padding-left:1%;
      padding-right:1%;
      border-left:solid;
      border-Right:solid;
      border-color:#323448;
      box-sizing:border-box;
      font-weight:bold;
      color:white;
      text-shadow:-1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
    }
    .blacklist{
      height:auto;
      width:0px;
    }
    .blacklistEntry{
      font-size:20px;
      float:left;
      min-width:50%;
      color:white;
      display:inline-block;
      border:thin solid silver;
      padding:5px;
    }
    .blacklistRemove{
      color:white;
      font-size:20px;
      display:inline-block;
      border:3px solid red;
      background-color:red;
      float:right;
      padding-left:5px;
      padding-right:5px;
    }
    .blacklistRemove:hover{
      color:white;
    }
    #settingsBox{
      margin-bottom:5px;
    }
    .settingsInput{
      color:white;
      max-width:40%;
      height:30px;
      margin:0 !important;
    }
    #settingsBlacklist{
      padding:5px;
    }
    #confDisp{
      height:100%;
      position:fixed;
      top:0;
      bottom:0;
      left:0;
      right:0;
      z-index:9999;
      display:none;
      overflow-y:auto;
      pointer-events:auto;
    }
    #confBox{
      height:auto;
      min-height:60%;
      width:auto;
      min-width:60%;
      position:relative;
      top:10px;
      margin:10%;
      padding:1%;
      display:flex;
      flex-flow:column;
      background:#2a2c3b;
      boxs-hadow:0 0 10px #000000;
      pointer-evnts:auto;
    }
    .functionalLink{
      padding:0.5em;
    }
    .settingsToggle{
      min-width:25%;
      font-size:20px;
      color:white;
      border:thin solid silver;
      padding:5px;
      max-width:25%;
      float:left;
    }
    .settingsTab{
      padding:5px;
      display:none;
    }
    .settingsSelect{
      max-height:80px;
      padding-top:5px;
    }
    .settingsSelectDiv{
      display:inline-block;
      backgroundColor:#4b4f6b;
      box-sizing=border-box;
      height:2em;
    }
    .settingsSelectBTN{
      width:100% !important;
      height:100%;
      font-size:20px;
      color:white;
      text-decoration:none;
      background-color:#373952;
      box-sizing:border-box;
      border:1px #21222b solid;
    }
    .toggleCheck {
		-webkit-appearance: none;
		background-color: #fafafa;
		border: 1px solid #cacece;
		box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), inset 0px -15px 10px -12px rgba(0, 0, 0, 0.05);
		padding: 9px;
		border-radius: 3px;
		display: inline-block;
		position: relative;
		height:100% !important;
		max-height:100% !important;
		margin-top:0 !important;
		margin-bottom:0 !important;
		margin-left:5px !important;
		margin-right:0 !important;
	}
	.toggleCheck:active,
	.toggleCheck:checked:active {
		box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), inset 0px 1px 3px rgba(0, 0, 0, 0.1);
	}
	.toggleCheck:checked {
		background-color: #e9ecee;
		border: 1px solid #adb8c0;
		box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), inset 0px -15px 10px -12px rgba(0, 0, 0, 0.05), inset 15px 10px -12px rgba(255, 255, 255, 0.1);
		color: black;
	}
	.toggleCheck:checked:after {
		content: '\\2714';
		font-size: 20px;
		position: absolute;
		left: 2px;
		color: black;
	}
	.toggleCheck:after {
		content: '\\2716';
		font-size: 20px;
		position: absolute;
		top: -5px;
		left: 1px;
		color: black;
	}
	.functionalContainer {
		position: relative;
		width: 100%;
		padding-bottom: 100%;
	}
	.functionalVideo {
		position: absolute;
		width: 100%;
		height: 100%;
	}
    `
    var style = document.createElement('style');

        if (style.styleSheet) {
            style.styleSheet.cssText = css;
        } else {
            style.appendChild(document.createTextNode(css));
        }
        document.getElementsByTagName('head')[0].appendChild(style);}
    insertCSS()

    var rolled=false;
    var lastURL = window.location.href;
    try{
        var alertBlacklist = JSON.parse(localStorage.getItem('alertBlacklist'));
        alertBlacklist = [...new Set(alertBlacklist)];
    }
    catch(error){
    };
    var settings = JSON.parse(localStorage.getItem('FL_Settings'));
    var defaultSettings = {
        'imageResize':true,
        'questRemove':true,
        'questAuthorRemove':true,
        'removeTaggedAuthor':false,
        'anonToggle':false,
        'removeUsernames':false,
        'autoRoller':false,
        'removeTopicForm':true,
        'removeBlankTopics':true,
        'authorHighlight':true,
        'authorBlacklist':[],
        'chatBlacklist':false,
        'chatBlacklisted':[],
        'tagBlacklist':[],
        'alertBlacklist':[],
        'highlightColor':'#393c59',
        'highlightLight':'#fc8c03',
        'highlightLightToggle':false,
        'liveRestore':true,
        'liveLight':false,
        'functionalLinks':false,
        'functionalVideos':false
    };

    //Updates settings when there is a change between versions.
    if (!settings){
        console.log('Settings set to defaults.');
        settings = defaultSettings
    }
    else if (Object.keys(settings).length !== Object.keys(defaultSettings).length){
        console.log('Settings differ in length.');
        Object.keys(defaultSettings).forEach(
            function(key){
                if (!(key in settings)){
                    settings[key] = defaultSettings[key];
                    console.log('Added '+key+' to the current settings.');
                };
            }
        );
        if (Object.keys(settings).length > Object.keys(defaultSettings).length){
            Object.keys(settings).forEach(
                function(key){
                    if (!(key in defaultSettings)){
                        console.log(`Removed invalid variable and value from settings, ${key}:${settings[key]}.`);
                        delete settings[key]
                    };
                }
            );
        }
    };

    //For handling merge and deletion of alertBlacklist storage item.
    if (typeof alertBlacklist != ('undefined' || 'null')){
        if (settings.alertBlacklist.length == 0 && alertBlacklist.length > 0){
            console.log('set and remove alert bl');
            settings.alertBlacklist = alertBlacklist;
            try{
                localStorage.removeItem('alertBlacklist');
            }catch(error){console.log(error);};
        }
        else if(settings.alertBlacklist.length == 0 && alertBlacklist.length == 0){
            try{
                localStorage.removeItem('alertBlacklist');
            }catch(error){console.log(error);};
        }
    };

    localStorage.setItem('FL_Settings', JSON.stringify(settings));

    function sortQuestTags(){
        //ignore this
        var list = document.querySelector('span.tags');
        var l2 = [...list.children];
        var l3 = l2.filter(
            function(value, index, arr){
                if (value.className !== 'tag more ng-scope'){
                    return value
                };
            }
        );
        l3.sort((a,b)=>a.innerText>b.innerText?1:-1).forEach(node=>list.appendChild(node));
    };

    function blacklistRemove(item){
        if (settings.alertBlacklist.includes(item)){
            let position = settings.alertBlacklist.indexOf(item);
            settings.alertBlacklist.splice(position, 1);
            localStorage.setItem('FL_Settings', JSON.stringify(settings));
        };
    };

    function repeatChecker(){
        try{
            let thisPage = window.location.href;
            if (thisPage !== lastURL){
                try{
                    questCheck.observerQst.disconnect();
                }catch(error){
                }
                try{
                    questCheck.observerTopic.disconnect();
                }catch(error){
                }
                pageCheck();
                lastURL = window.location.href;
            };
        }catch(error){
            console.log('Error with repeatChecker',error);
        };
    };
    setInterval(repeatChecker,500);

    function chatSend(info){
        let body = info[1]
        try{
            //var encodedBody = encodeURI(body);
            fetch("https://fiction.live/api/anonkun/dice", {
                "credentials": "include",
                "headers": {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0",
                    "Accept": "*/*",
                    "Accept-Language": "en-GB,en;q=0.5",
                    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                    "X-Requested-With": "XMLHttpRequest"
                },
                "referrer": window.location.href,
                "body": body,
                "method": "POST",
                "mode": "cors"
            }
                 );
        }catch(error){
            console.log('Error with chatSend',error);
        }
        try{
            let chapterID = info[0][0]
            let dataID = info[0][1]
            let roll = info[0][2]
            var cookies = document.cookie;
            cookies=cookies.split("; ")
            for (let i = 0; i < cookies.length; i++){
                var cookie = cookies[i].split("=")
                if (/.*distinct_id.*/.test(cookie)){
                    var cookieName = cookie[0].replace(/_posthog/,'')
                    cookieName = cookieName.replace('ph_','')
                }
            }
            fetch("https://fiction.live/api/node", {
                "credentials": "include",
                "headers": {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0",
                    "Accept": "*/*",
                    "Accept-Language": "en-GB,en;q=0.5",
                    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                    "X-Requested-With": "XMLHttpRequest"
                },
                "referrer": `https://fiction.live/stories/${body}`,
                "body": encodeURI(`r[]=${chapterID}&r[]=${dataID}&nt=chat&b=%2Froll+`)+encodeURIComponent(`${roll}`)+encodeURI(`&ra[hide]=true&ra[_id]=${dataID}&ra[b]=chapter+${dataID}&token=${cookieName}`),
                "method": "POST",
                "mode": "cors"
            });
        }catch(error){
            console.log('Error with RollSend',error);}
    }

    function autoRoll(change){
        if (settings.autoRoller != true){
            return;
        };
        try{
            var rollRegex = /[0-9]+d[0-9]+(?<!1d1)(\+[0-9]+)?( ?)(([ie]+)?([ut][0-9]+)?)+/
            if (rollRegex.test(change.innerText)){
                var roll = change.innerText.match(rollRegex)[0];
                var qewq = document.querySelector('div#storyPosts').firstChild.lastChild;
                if (qewq.firstChild.firstChild.classList.contains('rolled'||'closed')){return}
                else if(qewq.firstChild.firstChild.classList.contains('inner') && !(qewq.firstChild.firstChild.classList.contains('closed'))){
                    var dataID = qewq.getAttribute('data-id');
                    var chapterID = document.querySelector('article.threads').getAttribute('threads');
                    chapterID = chapterID.replace(/\/.*/,'');
                    var rollSend = `/roll ${roll}`;
                    var template = `sid=${chapterID}&dice=${encodeURIComponent(rollSend)}`;
                    if (rolled == false){
                        chatSend([[chapterID,dataID,roll],template]);
                        rolled = true;
                        qewq.firstChild.firstChild.classList.add('rolled');
                        setTimeout(function (){rolled = false},5000);
                    }
                }
            }
        }catch(error){}
    }

    function authorCheck(quest){
        let author = quest.querySelector('div.authorPane');
        if (author == null){
            try{
                author = quest.parentNode.parentNode.querySelector('span.name').innerText
                quest = quest.parentNode.parentNode.parentNode
            }catch(error){
                console.log('authorCheck Null',error)
            };
        }
        else{
            author = author.innerText;
        }
        if (settings.authorBlacklist.includes(author)){
            try{
                while (true){
                    if(quest.parentNode == null){
                        break
                    }
                    if (quest.parentNode.classList.contains('ng-scope') && quest.parentNode.tagName == 'LI'){
                        quest.parentNode.remove()
                        break
                    }
                    else{
                        quest = quest.parentNode
                    }
                }
                return
            }catch(error){console.log('authorCheck remove',error)};
            return;
        };
    };

    function tagCheck(quest){
        let tags = quest.querySelector('div.tags');
        if (tags == null){
            let tag = quest.parentNode.parentNode.querySelector('div.displayedTag');
            if (tag){
                if (settings.tagBlacklist.includes(tag.innerText)){
                    try{
                        while (true){
                            if(quest.parentNode == null){
                                break
                            }
                            if (quest.parentNode.classList.contains('ng-scope') && quest.parentNode.tagName == 'LI'){
                                quest.parentNode.remove()
                                break
                            }
                            else{
                                quest = quest.parentNode
                            }
                        }
                        return
                    }catch(error){
                        console.log('tagCheck remove',error)
                    };
                };
                return

            }
            else{return}
        };
        tags = tags.children;
        for (let i = 0; i < tags.length; i++){
            let tag = tags[i]
            if (settings.tagBlacklist.includes(tag.innerText)){
                try{
                    quest.parentNode.parentNode.remove();
                }catch(error){
                    console.log('tagCheck remove',error)
                };
                return;
            };
        };
    };

    function removeBlacklisted(){
        let quests = document.querySelectorAll('div.storyListItem');
        for (let i = 0; i < quests.length; i++){
            if (settings.questRemove == true){
                tagCheck(quests[i].children[0]);
            }
            if (settings.questAuthorRemove == true){
                authorCheck(quests[i].children[0]);
            }
        };
    };

    function liveRestore() {
        if (document.querySelector('div#liveBox')) {
            return
        };
        var navBar = document.querySelector('[id="mainMenuReplacement"][class="navbar navbar-default navbar-fixed-top"]');
        var liveTimer = document.querySelectorAll('[class="next-live ng-scope"]');
        var myLive = document.createElement('div');
        myLive.setAttribute('id', 'liveBox');
        if (settings.liveLight == true){
            myLive.style.color = 'black';
            myLive.style.textShadow = '-1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff';
        } else{
            myLive.style.color = 'white';
            myLive.style.textShadow = '-1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000';
        }

        while (liveTimer[0].childNodes.length > 0) {
            myLive.appendChild(liveTimer[0].childNodes[0]);
        }
        navBar.appendChild(myLive);
        liveTimer[0].style.display = 'none';
    };

    function waitForTimer() {
        if (settings.liveRestore == false){return};
        var options = {
            childList: true,
            subtree: true
        };
        var observerTimer = new MutationObserver(awaitTimer);
        function awaitTimer(mutations) {
            for (let mutation of mutations) {
                try {
                    var canvas = document.querySelector('header[class="next-live ng-scope"]');
                } catch (error) {}
                if (canvas && (canvas !== undefined && canvas.length != 0)) {
                    observerTimer.disconnect(); // stop observing
                    liveRestore()
                    return;
                };
            };
        };
        observerTimer.observe(document, options);
        setTimeout(function(){
            try{
                observerTimer.disconnect();
            }catch(error){}
        },1000);
    };

    function questCheck(){
        if ((settings.questRemove && settings.questAuthorRemove) !== true){
            return;
        }
        try{
            var options = {
                childList: true,
                subtree: true
            };
            function qstMod(mutations) {
                for (let mutation of mutations) {
                    try{
                        let quest = mutation.addedNodes[0];
                        if (quest){
                            try{
                                if (quest.parentNode.classList.contains('storyListItem')){
                                    if (settings.questRemove == true){
                                        tagCheck(quest);
                                    }
                                    if (settings.questAuthorRemove == true){
                                        authorCheck(quest);
                                    }

                                }else if (quest.parentNode.parentNode.parentNode.parentNode.classList.contains('storyListItem') && /.*fiction.live\/$/.test(URL)){
                                    if (settings.questRemove == true){
                                        if (quest){
                                            tagCheck(quest);
                                        }
                                    }
                                    try{
                                        if (settings.questAuthorRemove == true){
                                            if (quest){
                                                authorCheck(quest);
                                            }
                                        }
                                    }catch(error){console.log(error)}

                                }
                            }catch(error){
                                //console.log('If this appears more than twice, make an issue.')
                                if (error instanceof TypeError){}
                                else{
                                    console.log(error)}
                            }

                        }
                        //observerMessage.disconnect();
                    }catch(error){
                        console.log('New quest Error',error);
                    }

                };
            };
            let observerQst = new MutationObserver(qstMod);
            observerQst.observe(document, options);
            questCheck.observerQst = observerQst;
            removeBlacklisted();
        }
        catch(error){console.log('questCheck',error)};


    };

    function pageCheck() {
        try{
            let URL = window.location.href;
            if ((/.*(fiction.live\/stories\/).*/.test(URL))) {
                //console.log('quest');
                chatThings();
                waitForTimer();
                //questThings();
            } else if (/.*(fiction.live\/stories\?).*/.test(URL)) {
                //console.log('main/search page');
                //mainThings();
                questCheck();
            } else if (/.*(fiction.live\/live\?).*/.test(URL)) {
                //console.log('live page');
                //LiveThings();
                questCheck();
            } else if (/.*(fiction.live\/social).*/.test(URL)){
                //console.log('thread page');
                removeBlankTopics();
            } else if (/.*fiction.live\/$/.test(URL)){
                questCheck();
            } else if (/.*fiction.live\/user\/.*\/stories$/.test(URL)){
                if (settings.removeTaggedAuthor == true){
                    questCheck();
                }
            } else {
                console.log('Page currently has no specific functions.');
            }
        }catch(error){
            console.log('Error with pageCheck',error)
        }


    };

    function removeBlankTopics(){
        if (settings.removeBlankTopics !== true){
            return;
        }
        try{
            var options = {
                childList: true,
                subtree: true
            };
            function topicWatch(mutations) {
                for (let mutation of mutations) {
                    try{
                        let topic = mutation.addedNodes[0];
                        if (topic){
                            try{
                                if (typeof(topic.classList)=='undefined'){}
                                else if (topic.classList.contains('threadList')){
                                    //observerTopic.disconnect();
                                    let topicItem = topic.querySelectorAll('li.threadListItem')
                                    for (let i = 0; i < topicItem.length; i++){
                                        if (topicItem[i].querySelector('div.row.title.header').innerText.length == 0){
                                            topicItem[i].remove();
                                        };
                                    };
                                };

                                //if (!(topic.querySelector('div.row.title.header').innerText)){console.log('empty',topic)}
                            }catch(error){
                                console.log(error)
                            }

                        }
                    }catch(error){
                        console.log('New quest Error',error);
                    }

                };
            };
            let observerTopic = new MutationObserver(topicWatch);
            observerTopic.observe(document, options);
            questCheck.observerTopic = observerTopic;
        }catch(error){
            console.log('topicCheck',error)
        };
    };

    function chatBlacklist(message){
        function delMSG(name){
            if (name == message.temp1.querySelector('div.user').querySelector('span').innerText){
                //message.remove();
                message.style.display = 'none';
                return;
            };
        }
        if (settings.chatBlacklist != true && settings.chatBlacklisted.length == 0){
            return;
        }
        else{
            settings.chatBlacklisted.forEach(name=>delMSG(name));
        };
    };

    function chatThings() {
        waitForChat();

        function functionalLinks(message){
            if (settings.functionalLinks != true){
                return;
            }
            try{
                var regex = new RegExp(/(https?:\/\/(www\.)?)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)*/);
                //var regex = new RegExp(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)*/);
                var text = message.querySelector('div.fieldBody').innerText;
                if (regex.test(text)){
                    var matches = text.match(regex);
                    //console.log(matches)
                    for (var i = 0;i<matches.length;i++){
                        if (typeof matches[i]=='undefined' || matches[i].startsWith('/')|| matches[i].length < 5 || /.+\..+/.test(matches[i])==false){}
                        else{
                            try{console.log('matches[i]',matches[i])
                                var elm;
                                if (/https?:\/\//.test(matches[i])==false){matches[i]='https://'.concat(matches[i])}
                                if(/.*(jpg|jpeg|png|gif|webm|webp)/.test(matches[i])){
                                    elm=document.createElement('img');
                                    elm.src = matches[i];
                                }
                                else if(settings.functionalVideos == true){
                                    if(/.*v=(\w+).*/.test(matches[i])){
                                        elm=document.createElement('iframe');
                                        elm.setAttribute('frameborder', '0')
                                        elm.setAttribute('allowFullScreen', '')
                                        elm.allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture';
                                        elm.src = `https://www.youtube.com/embed/${(matches[i].match(/v=(\w+)/)[1])}`;
                                        elm.setAttribute('class','functionalVideo');

                                        let functionalContainer=document.createElement('div');
                                        functionalContainer.setAttribute('class','functionalContainer');
                                        functionalContainer.appendChild(elm);

                                        message.querySelector('.chatMsg').parentNode.appendChild(functionalContainer);
                                        return;
                                    }
                                    else if(/be\/(\w+)/.test(matches[i])){
                                        elm=document.createElement('iframe');
                                        elm.setAttribute('frameborder', '0')
                                        elm.setAttribute('allowFullScreen', '')
                                        elm.allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture';
                                        elm.src = `https://www.youtube.com/embed/${(matches[i].match(/be\/(\w+)/)[1])}`;
                                        elm.setAttribute('class','functionalVideo');

                                        let functionalContainer=document.createElement('div');
                                        functionalContainer.setAttribute('class','functionalContainer');
                                        functionalContainer.appendChild(elm);

                                        message.querySelector('.chatMsg').parentNode.appendChild(functionalContainer);
                                        return;
                                    }
                                }
                                else{
                                    elm=document.createElement('a');
                                    elm.innerHTML='Link';
                                    elm.href = matches[i];
                                }

                                elm.setAttribute('class','functionalLink');
                                elm.rel="noopener noreferrer";
                                elm.target="_blank";
                                message.querySelector('.chatMsg').parentNode.appendChild(elm);
                               }catch(error){}
                        }
                    };
                };
            }catch(error){}
        };

        function removeUsernames(message){
            //return;
            //console.log('this shouldnt be seen')
            if (settings.removeUsernames == true && message.querySelector('span.name')){
                message.querySelector('span.name').style.display = 'none';
                let authorList = document.querySelectorAll('span.author.ng-scope');
                let authors=[]
                authorList.forEach(element=>authors.push(element.querySelector('span.name').innerText))

                try {
                    console.log(authors)
                    console.log(message.querySelector('span.name'))
                    if (authors.includes(message.querySelector('span.name').innerText)) {
                        message.querySelector('span.name').style.display = 'initial';
                        return;
                    }
                    else {
                        console.log('ac')
                        setTimeout(function(){
                            try{
                                message.querySelector('img.avatar').remove()
                            }catch(error){
                            };
                            try{
                                message.querySelector('span.name').innerText='anon'
                                message.querySelector('span.name').style.display = 'initial';
                            }catch(error){
                                console.log('Error forcing anon',error);
                            };
                            setTimeout(function(){
                                if (message.querySelector('span.name').innerText!='anon'){
                                    message.querySelector('span.name').innerText='anon'
                                }
                            },100);
                        },100);


                    }
                } catch (error) {
                    console.log('Author highlighter failed',error);
                };
            }
            else return

        };

        function authorHighlight(message){
            if (settings.authorHighlight == true && message.querySelector('span.name')){
                var currentColor = settings.highlightColor;
                if (settings.highlightLightToggle == true){
                    currentColor = settings.highlightLight;
                }
                let authorList = document.querySelectorAll('span.author.ng-scope');
                let authors=[]
                authorList.forEach(element=>authors.push(element.querySelector('span.name').innerText))
                try {
                    if (authors.includes(message.querySelector('span.name').innerText)) {
                        if (settings.highlightColor){
                            try{
                                message.style.backgroundColor = currentColor;
                            }catch(error){
                                console.log('Failed using custom color',error);
                                message.style.backgroundColor = '#393c59';
                                settings.highlightColor = '#393c59';
                            }
                        }
                        else{
                            message.style.backgroundColor = '#393c59';
                        };
                    };
                } catch (error) {
                    console.log('Author highlighter failed',error);
                };
            }
            else return

        };

        function imageResize(message){
            if (settings.imageResize == true){
                let msgImage = message.querySelector('div.message').querySelector('img');
                if (msgImage !== null && msgImage !== undefined) {
                    let image = message.querySelector('div.message').querySelector('img');
                    image.src = image.src.replace(/(h[0-9]+\-w[0-9]+)/, 'h5600-w5600');
                    let page = image.src;
                    image.setAttribute('onclick', "window.open('" + page + "', '_blank');")
                    try {
                        image.onerror = (function () {
                            setTimeout(this.src = this.src, 100)
                        })
                    } catch (error) {
                        'img error add fail'
                    };
                };}
            else return
        };

        function whenNewMessage(chat) {
            var options = {
                childList: true
            };
            function messageMod(mutations) {
                for (let mutation of mutations) {
                    try{
                        var message = mutation.addedNodes[0];
                        chatBlacklist(message);
                        removeUsernames(message);
                        authorHighlight(message);
                        imageResize(message);
                        autoRoll(message);
                        functionalLinks(message);
                        //observerMessage.disconnect();
                    }catch(error){
                        console.log('New Message Error',error);
                    }

                };
            };
            let observerMessage = new MutationObserver(messageMod);
            observerMessage.observe(chat, options);
        };

        function withOldMessage(chat) {
            let messages = chat.childNodes;
            try {
                messages.forEach(messageMod);
            } catch (error) {
                console.log('tried running msgmod',error)
            };

            function messageMod(message) {
                try {
                    imageResize(message);
                    authorHighlight(message);
                    functionalLinks(message);
                } catch (error) {
                    console.log('messageMod', error);
                };
            };
        };

        function waitForChat() {
            //waits for chat to exist
            var options = {
                childList: true,
                subtree: true
            };
            var observerChat = new MutationObserver(awaitChat);
            observerChat.observe(document, options)

            function awaitChat(mutations) {
                for (let mutation of mutations) {
                    try {
                        var chat = document.querySelector('article.chatLog').querySelector('div.jadeRepeat');
                    } catch (TypeError) {};
                    if (chat && (chat !== (undefined || null) && chat.length != 0)) {
                        observerChat.disconnect();
                        if (/.*(fiction.live\/stories\/).*/.test(window.location.href)) {
                            whenNewMessage(chat);
                            withOldMessage(chat);
                        };
                        break;
                    };
                };
            };
        };
    };

    function deleteTopicCreate(){
        try{
            if (settings.removeTopicForm == true){
                let formItem = document.querySelector('div.formItem');
                if (formItem){
                    formItem.parentNode.remove();
                };
            };
        }catch(error){
            console.log('Error with removing topic form',error);
        };

    };

    function blacklistAdd(){
        let title = this.parentNode.querySelector('[set-text="item.value.value"]').textContent.replace(' went live', '');
        let author = this.parentNode.querySelector('span.user').innerText;
        let entry = title+'___'+author;
        settings.alertBlacklist.push(entry);
        localStorage.setItem('FL_Settings', JSON.stringify(settings));
        let dismiss = this.parentNode.querySelector('a.dismiss');
        simClick(dismiss);
        document.querySelector('div#settingsBlacklist').appendChild(elementBlacklisted(entry));
    };

    function alertBlacklistButton(alert){
        function createBlacklistButton(){
            var blacklistButton = document.createElement('a');
            blacklistButton.setAttribute('class', 'blacklist');
            blacklistButton.innerText = '∅';
            blacklistButton.onclick = blacklistAdd;
            return blacklistButton
        }
        alert.childNodes[0].after(createBlacklistButton());
    };

    function blacklistCheck(alert){
        try{
            var title = alert.querySelector('[set-text="item.value.value"]').textContent.replace(' went live', '');
            var author = alert.querySelector('span.user').innerText;
            var dismiss = alert.querySelector('a.dismiss');
            if (settings.alertBlacklist.includes(title+'___'+author)){
                simClick(dismiss);
            }
            else{
                alertBlacklistButton(alert);
            };}
        catch(error){
            console.log('blacklist checker error',error)
        };
    };

    function simClick(elem) {
        var evt = new MouseEvent('click', {
            bubbles: true,
            cancelable: true,
            view: window
        });
        var canceled = !elem.dispatchEvent(evt);
    };

    function monitorAlerts() {
        try {
            let alertContainer = document.getElementsByClassName('feedType')[0];
            alertContainer.querySelectorAll('li').forEach(alert => blacklistCheck(alert))
            var observer = new MutationObserver(function (mutations, me) {
                try {
                    for (let mutation of mutations) {
                        if (mutation.addedNodes[0] !== undefined) {
                            if (mutation.addedNodes[0].className == ('feedItem ng-scope ng-animate')) {
                                blacklistCheck(mutation.addedNodes[0]);
                            };
                        };

                    };
                } catch (error) {
                    console.log('Alert monitor error',error)
                };
            });
            observer.observe(alertContainer, {
                childList: true
            });
        } catch (error) {
            console.log('watcher ded',error)
        };
    };

    function awaitMainMenu(){
        try{
            var options = {
                childList: true,
                subtree: true
            };

            let observerMenu = new MutationObserver(awaitMenu);
            observerMenu.observe(document, options);
            function awaitMenu(mutations){
                for (let mutation of mutations) {
                    try {
                        var mainMenu = document.querySelector('nav#mainMenu');
                    } catch (error) {};
                    if (mainMenu){
                        observerMenu.disconnect();
                        settingsContainer();
                        deleteTopicCreate();
                    };
                };
            };
        }catch (error){console.log('Error awaiting main menu',error)};

    };

    function elementBlacklisted(element){
        var settingsBlacklisted = document.createElement('div');
        settingsBlacklisted.setAttribute('class','blacklistEntry')
        settingsBlacklisted.innerText = element
        settingsBlacklisted.innerText = settingsBlacklisted.innerText.replace('___','     Author: ')


        var settingsBlacklistRemove = document.createElement('a');
        settingsBlacklistRemove.setAttribute('class','blacklistRemove')
        settingsBlacklistRemove.innerText = 'Remove'
        settingsBlacklistRemove.onclick = function(){
            blacklistRemove(element);
            this.parentNode.remove();
        }

        settingsBlacklisted.appendChild(settingsBlacklistRemove)
        return settingsBlacklisted
    };

    function settingsContainer(){
        function settingsDisplay(){
            try{
                if (!document.querySelector('#confDisp')){
                    function configDisplay(){
                        var confDisp = document.createElement('div');
                        confDisp.setAttribute('id', 'confDisp');
                        return confDisp
                    };
                    function configBox(){
                        var confBox = document.createElement('div');
                        confBox.setAttribute('id', 'confBox');
                        return confBox
                    };

                    //Toggles features here

                    function settingsImageResize(){
                        var settingsImageResize = document.createElement('div');
                        settingsImageResize.setAttribute('class', 'settingsToggle');
                        settingsImageResize.innerText = 'Resize images in chat.';

                        var settingsImageResizeCheckbox = document.createElement('input');
                        settingsImageResizeCheckbox.setAttribute("type", "checkbox");
                        settingsImageResizeCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.imageResize == true){
                            settingsImageResizeCheckbox.checked = true;
                        };
                        settingsImageResizeCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.imageResize = true;
                            } else {
                                settings.imageResize = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsImageResize.appendChild(settingsImageResizeCheckbox);
                        return settingsImageResize
                    };

                    function settingsRemoveBlankTopics(){
                        var settingsRemoveBlankTopics = document.createElement('div');
                        settingsRemoveBlankTopics.setAttribute('class', 'settingsToggle');
                        settingsRemoveBlankTopics.innerText = 'Remove blank topics.';

                        var settingsRemoveBlankTopicsCheckbox = document.createElement('input');
                        settingsRemoveBlankTopicsCheckbox.setAttribute("type", "checkbox");
                        settingsRemoveBlankTopicsCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.removeBlankTopics == true){
                            settingsRemoveBlankTopicsCheckbox.checked = true;
                        };

                        settingsRemoveBlankTopicsCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.removeBlankTopics = true;
                            } else {
                                settings.removeBlankTopics = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsRemoveBlankTopics.appendChild(settingsRemoveBlankTopicsCheckbox);
                        return settingsRemoveBlankTopics
                    };

                    function settingsFormRemove(){
                        var settingsFormRemove = document.createElement('div');
                        settingsFormRemove.setAttribute('class', 'settingsToggle');
                        settingsFormRemove.innerText = 'Remove topic submission form.';
                        var settingsFormRemoveCheckbox = document.createElement('input');
                        settingsFormRemoveCheckbox.setAttribute("type", "checkbox");
                        settingsFormRemoveCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.removeTopicForm == true){
                            settingsFormRemoveCheckbox.checked = true;
                        };
                        settingsFormRemoveCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.removeTopicForm = true;
                            } else {
                                settings.removeTopicForm = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsFormRemove.appendChild(settingsFormRemoveCheckbox);
                        return settingsFormRemove
                    };

                    function settingsChatBlacklist(){
                        var settingsChatBlacklist = document.createElement('div');
                        settingsChatBlacklist.setAttribute('class', 'settingsToggle');
                        settingsChatBlacklist.innerText = 'Hide blacklisted users in chat.';

                        var settingsChatBlacklistCheckbox = document.createElement('input');
                        settingsChatBlacklistCheckbox.setAttribute("type", "checkbox");
                        settingsChatBlacklistCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.chatBlacklist == true){
                            settingsChatBlacklistCheckbox.checked = true;
                        };
                        settingsChatBlacklistCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.chatBlacklist = true;
                            } else {
                                settings.chatBlacklist = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsChatBlacklist.appendChild(settingsChatBlacklistCheckbox);
                        return settingsChatBlacklist
                    };

                    function settingsUserBlacklist() {
                        var settingsTab = document.createElement('div');
                        settingsTab.setAttribute('class','settingsTab');
                        settingsTab.setAttribute('name','Chat');
                        function chatBlacklistRemove(item) {
                            if (settings.chatBlacklisted.includes(item)) {
                                let position = settings.chatBlacklisted.indexOf(item);
                                settings.chatBlacklisted.splice(position, 1);
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            };
                        };

                        function chatBlacklisted(element) {
                            try {
                                var chatBlacklisted = document.createElement('div');
                                chatBlacklisted.setAttribute('class', 'blacklistEntry');
                                chatBlacklisted.innerText = element;

                                var settingsUserRemove = document.createElement('a');
                                settingsUserRemove.setAttribute('class', 'blacklistRemove');
                                settingsUserRemove.innerText = 'Remove';
                                settingsUserRemove.onclick = function () {
                                    try {
                                        chatBlacklistRemove(element);
                                        this.parentNode.remove();
                                    } catch (error) {
                                        console.log('Error removing user', error)
                                    }
                                };
                                chatBlacklisted.appendChild(settingsUserRemove);
                                return chatBlacklisted;
                            } catch (error) {
                                console.log('', error)
                            }
                        };

                        function userAddBlacklist() {
                            var settingsUserBox = document.createElement('div');
                            settingsUserBox.setAttribute('id', 'settingsBox');

                            var settingsUserInput = document.createElement('input');
                            settingsUserInput.setAttribute("type", "text");
                            settingsUserInput.setAttribute("class", "settingsInput");
                            settingsUserInput.setAttribute("placeholder", "Input username here.");

                            var settingsUserAdd = document.createElement('input');
                            settingsUserAdd.setAttribute("type", "button");
                            settingsUserAdd.style.height = '30px';
                            settingsUserAdd.value = 'Add User';
                            settingsUserAdd.onclick = function () {
                                settings.chatBlacklisted.push(this.parentNode.childNodes[0].value);
                                this.parentNode.parentNode.appendChild(chatBlacklisted(this.parentNode.childNodes[0].value));
                                this.parentNode.childNodes[0].value = "";
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                                removeBlacklisted();
                            };

                            settingsUserBox.appendChild(settingsUserInput);
                            settingsUserBox.appendChild(settingsUserAdd);

                            return settingsUserBox
                        };

                        var settingsUserBlacklist = document.createElement('div');
                        settingsUserBlacklist.setAttribute('id', 'settingsBlacklist');
                        settingsUserBlacklist.style.padding = '5px';
                        settings.chatBlacklisted.forEach(element => settingsUserBlacklist.appendChild(chatBlacklisted(element)));

                        var settingsUserBlacklistText = document.createElement('div');
                        settingsUserBlacklistText.innerText = 'Chat User Blacklist';
                        settingsUserBlacklistText.style.minWidth = '100%';
                        settingsUserBlacklistText.style.fontSize = '20px';
                        settingsUserBlacklistText.style.color = 'white';
                        settingsUserBlacklist.prepend(userAddBlacklist());
                        settingsUserBlacklist.prepend(settingsUserBlacklistText);

                        settingsTab.appendChild(settingsUserBlacklist)
                        return settingsTab;
                    };

                    function settingsAuthorBlacklist(){
                        var settingsAuthorBlacklist = document.createElement('div');
                        settingsAuthorBlacklist.setAttribute('class','settingsToggle')
                        settingsAuthorBlacklist.innerText = 'Hide quests with blacklisted authors.';

                        var settingsAuthorBlacklistCheckbox = document.createElement('input');
                        settingsAuthorBlacklistCheckbox.setAttribute("type", "checkbox");
                        settingsAuthorBlacklistCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.questAuthorRemove == true){
                            settingsAuthorBlacklistCheckbox.checked = true;
                        };
                        settingsAuthorBlacklistCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.questAuthorRemove = true;
                            } else {
                                settings.questAuthorRemove = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsAuthorBlacklist.appendChild(settingsAuthorBlacklistCheckbox);
                        return settingsAuthorBlacklist
                    };

                    function settingsAuthorsBlacklist() {
                        var settingsTab = document.createElement('div');
                        settingsTab.setAttribute('class','settingsTab');
                        settingsTab.setAttribute('name','Author');
                        function authorBlacklistRemove(item) {
                            if (settings.authorBlacklist.includes(item)) {
                                let position = settings.authorBlacklist.indexOf(item);
                                settings.authorBlacklist.splice(position, 1);
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            };
                        };
                        function authorBlacklisted(element) {
                            try {
                                var authorBlacklisted = document.createElement('div');
                                authorBlacklisted.setAttribute('class','blacklistEntry')
                                authorBlacklisted.innerText = element;

                                var settingsAuthorRemove = document.createElement('a');
                                settingsAuthorRemove.setAttribute('class', 'blacklistRemove');
                                settingsAuthorRemove.innerText = 'Remove';
                                settingsAuthorRemove.onclick = function () {
                                    try {
                                        authorBlacklistRemove(element);
                                        this.parentNode.remove();
                                    } catch (error) {
                                        console.log('Error removing author', error)
                                    }
                                };
                                authorBlacklisted.appendChild(settingsAuthorRemove);
                                return authorBlacklisted;
                            } catch (error) {
                                console.log('', error)
                            }
                        };

                        function authorAddBlacklist() {
                            var settingsAuthorBox = document.createElement('div');
                            settingsAuthorBox.setAttribute('id', 'settingsBox');
                            settingsAuthorBox.style.marginBottom = '5px';

                            var settingsAuthorsInput = document.createElement('input');
                            settingsAuthorsInput.setAttribute("type", "text");
                            settingsAuthorsInput.setAttribute("class", "settingsInput");
                            settingsAuthorsInput.setAttribute("placeholder", "Input author here.");

                            var settingsAuthorsAdd = document.createElement('input');
                            settingsAuthorsAdd.setAttribute("type", "button");
                            settingsAuthorsAdd.style.height = '30px';
                            settingsAuthorsAdd.value = 'Add Author';
                            settingsAuthorsAdd.onclick = function () {
                                settings.authorBlacklist.push(this.parentNode.childNodes[0].value);
                                this.parentNode.parentNode.appendChild(authorBlacklisted(this.parentNode.childNodes[0].value));
                                this.parentNode.childNodes[0].value = "";
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                                removeBlacklisted();
                            };

                            settingsAuthorBox.appendChild(settingsAuthorsInput);
                            settingsAuthorBox.appendChild(settingsAuthorsAdd);

                            return settingsAuthorBox
                        };

                        var settingsAuthorsBlacklist = document.createElement('div');
                        settingsAuthorsBlacklist.setAttribute('id', 'settingsBlacklist');
                        settings.authorBlacklist.forEach(element => settingsAuthorsBlacklist.appendChild(authorBlacklisted(element)));

                        var settingsAuthorsBlacklistText = document.createElement('div');
                        settingsAuthorsBlacklistText.innerText = 'Authors Blacklist';
                        settingsAuthorsBlacklistText.style.minWidth = '100%';
                        settingsAuthorsBlacklistText.style.fontSize = '20px';
                        settingsAuthorsBlacklistText.style.color = 'white';
                        settingsAuthorsBlacklist.prepend(authorAddBlacklist());
                        settingsAuthorsBlacklist.prepend(settingsAuthorsBlacklistText);


                        settingsTab.appendChild(settingsAuthorsBlacklist)
                        return settingsTab;
                    };

                    function settingsTagBlacklist(){
                        var settingsTagBlacklist = document.createElement('div');
                        settingsTagBlacklist.setAttribute("class", "settingsToggle");
                        settingsTagBlacklist.innerText = 'Hide quests with blacklisted tags.';

                        var settingsTagBlacklistCheckbox = document.createElement('input');
                        settingsTagBlacklistCheckbox.setAttribute("type", "checkbox");
                        settingsTagBlacklistCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.questRemove == true){
                            settingsTagBlacklistCheckbox.checked = true;
                        };
                        settingsTagBlacklistCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.questRemove = true;
                            } else {
                                settings.questRemove = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsTagBlacklist.appendChild(settingsTagBlacklistCheckbox);
                        return settingsTagBlacklist
                    };

                    function settingsTagsBlacklist(){
                        var settingsTab = document.createElement('div');
                        settingsTab.setAttribute('class','settingsTab');
                        settingsTab.setAttribute('name','Tags');
                        function tagBlacklistRemove(item){
                            if (settings.tagBlacklist.includes(item)){
                                let position = settings.tagBlacklist.indexOf(item);
                                settings.tagBlacklist.splice(position, 1);
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                            };
                        };
                        function tagBlacklisted(element){
                            try{
                                var tagBlacklisted = document.createElement('div');
                                tagBlacklisted.setAttribute('class','blacklistEntry');
                                tagBlacklisted.innerText = element;

                                var settingsTagRemove = document.createElement('a');
                                settingsTagRemove.setAttribute('class','blacklistRemove');
                                settingsTagRemove.innerText = 'Remove';
                                settingsTagRemove.onclick = function(){
                                    try{
                                        tagBlacklistRemove(element);
                                        this.parentNode.remove();
                                    }catch(error){
                                        console.log('Error removing tag',error)}
                                };
                                tagBlacklisted.appendChild(settingsTagRemove);
                                return tagBlacklisted;
                            }catch(error){console.log('',error)}
                        };

                        function tagAddBlacklist(){
                            var settingsTagBox = document.createElement('div');
                            settingsTagBox.setAttribute('id', 'settingsBox');

                            var settingsTagsInput = document.createElement('input');
                            settingsTagsInput.setAttribute("type", "text");
                            settingsTagsInput.setAttribute("class", "settingsInput");
                            settingsTagsInput.setAttribute("placeholder", "Input tag here.");

                            var settingsTagsAdd = document.createElement('input');
                            settingsTagsAdd.setAttribute("type", "button");
                            settingsTagsAdd.style.height = '30px';
                            settingsTagsAdd.value = 'Add Tag';
                            settingsTagsAdd.onclick = function (){
                                settings.tagBlacklist.push(this.parentNode.childNodes[0].value);
                                this.parentNode.parentNode.appendChild(tagBlacklisted(this.parentNode.childNodes[0].value));
                                this.parentNode.childNodes[0].value = "";
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settings = JSON.parse(localStorage.getItem('FL_Settings'));
                                removeBlacklisted();
                            };

                            settingsTagBox.appendChild(settingsTagsInput);
                            settingsTagBox.appendChild(settingsTagsAdd);

                            return settingsTagBox
                        };

                        var settingsTagsBlacklist = document.createElement('div');
                        settingsTagsBlacklist.setAttribute('id', 'settingsBlacklist');
                        settings.tagBlacklist.forEach(element => settingsTagsBlacklist.appendChild(tagBlacklisted(element)));

                        var settingsTagsBlacklistText = document.createElement('div');
                        settingsTagsBlacklistText.innerText = 'Tags Blacklist';
                        settingsTagsBlacklistText.style.minWidth = '100%';
                        settingsTagsBlacklistText.style.fontSize = '20px';
                        settingsTagsBlacklistText.style.color = 'white';
                        settingsTagsBlacklist.prepend(tagAddBlacklist());
                        settingsTagsBlacklist.prepend(settingsTagsBlacklistText);

                        settingsTab.appendChild(settingsTagsBlacklist)
                        return settingsTab;
                    };
                    //Toggles for features start here

                    function settingsNamefagToggle(){

                        var settingsNamefagToggle = document.createElement('div');
                        settingsNamefagToggle.innerText = 'Make everyone Anon.';
                        settingsNamefagToggle.style.minWidth = '25%';
                        settingsNamefagToggle.style.fontSize = '20px';
                        settingsNamefagToggle.style.color = 'white';
                        settingsNamefagToggle.style.border = 'thin solid silver';
                        settingsNamefagToggle.style.padding = '5px';
                        settingsNamefagToggle.style.maxWidth = '25%';
                        settingsNamefagToggle.style.float = 'left';

                        var settingsNamefagToggleCheckbox = document.createElement('input');
                        settingsNamefagToggleCheckbox.setAttribute("type", "checkbox");
                        settingsNamefagToggleCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.removeUsernames == true){
                            settingsNamefagToggleCheckbox.checked = true;
                        };
                        settingsNamefagToggle.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.removeUsernames = true;
                            } else {
                                settings.removeUsernames = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsNamefagToggle.appendChild(settingsNamefagToggleCheckbox);
                        return settingsNamefagToggle
                    };

                    function settingsRollerToggle(){

                        var settingsRollerToggle = document.createElement('div');
                        settingsRollerToggle.innerText = 'Toggle Auto Roller.';
                        settingsRollerToggle.style.minWidth = '25%';
                        settingsRollerToggle.style.fontSize = '20px';
                        settingsRollerToggle.style.color = 'white';
                        settingsRollerToggle.style.border = 'thin solid silver';
                        settingsRollerToggle.style.padding = '5px';
                        settingsRollerToggle.style.maxWidth = '25%';
                        settingsRollerToggle.style.float = 'left';

                        var settingsRollerToggleCheckbox = document.createElement('input');
                        settingsRollerToggleCheckbox.setAttribute("type", "checkbox");
                        settingsRollerToggleCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.autoRoller == true){
                            settingsRollerToggleCheckbox.checked = true;
                        };
                        settingsRollerToggle.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.autoRoller = true;
                            } else {
                                settings.autoRoller = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsRollerToggle.appendChild(settingsRollerToggleCheckbox);
                        return settingsRollerToggle
                    };



                    function settingsAnonToggle(){

                        function toggleAnonStatus(){
                            var x=1
                            try{
                                try{
                                    var username = localStorage.getItem('username');
                                    var refURL = "https://fiction.live/user/"+username;
                                    var profile = window.ty.currentUser.profile;
                                    profile.asAnon = settings.anonToggle;
                                }catch(error){
                                    console.log('Toggle Anon Prep',error);x=2;
                                };
                                if (x=1){
                                    fetch("https://fiction.live/api/user", {
                                        "credentials": "include",
                                        "headers": {
                                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0",
                                            "Accept": "application/json, text/javascript, */*; q=0.01",
                                            "Accept-Language": "en-GB,en;q=0.5",
                                            "Content-Type": "application/json",
                                            "X-Requested-With": "XMLHttpRequest"
                                        },
                                        "referrer": refURL,
                                        "body": JSON.stringify(profile),
                                        "method": "PUT",
                                        "mode": "cors"
                                    });};
                            }catch(error){
                                console.log('Toggle Anon Set',error);
                            };
                        };

                        var settingsAnonToggle = document.createElement('div');
                        settingsAnonToggle.innerText = 'Toggle Anon status.';
                        settingsAnonToggle.style.minWidth = '25%';
                        settingsAnonToggle.style.fontSize = '20px';
                        settingsAnonToggle.style.color = 'white';
                        settingsAnonToggle.style.border = 'thin solid silver';
                        settingsAnonToggle.style.padding = '5px';
                        settingsAnonToggle.style.maxWidth = '25%';
                        settingsAnonToggle.style.float = 'left';

                        var settingsAnonToggleCheckbox = document.createElement('input');
                        settingsAnonToggleCheckbox.setAttribute("type", "checkbox");
                        settingsAnonToggleCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.anonToggle == true){
                            settingsAnonToggleCheckbox.checked = true;
                        };
                        settingsAnonToggleCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.anonToggle = true;
                                toggleAnonStatus();
                            } else {
                                settings.anonToggle = false;
                                toggleAnonStatus();
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsAnonToggle.appendChild(settingsAnonToggleCheckbox);
                        return settingsAnonToggle
                    };




                    function settingsLiveRestore(){
                        var settingsLiveRestore = document.createElement('div');
                        settingsLiveRestore.innerText = 'Restore live timer to nav bar.';
                        settingsLiveRestore.style.minWidth = '25%';
                        settingsLiveRestore.style.fontSize = '20px';
                        settingsLiveRestore.style.color = 'white';
                        settingsLiveRestore.style.border = 'thin solid silver';
                        settingsLiveRestore.style.padding = '5px';
                        settingsLiveRestore.style.maxWidth = '25%';
                        settingsLiveRestore.style.float = 'left';

                        var settingsLiveRestoreCheckbox = document.createElement('input');
                        settingsLiveRestoreCheckbox.setAttribute("type", "checkbox");
                        settingsLiveRestoreCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.liveRestore == true){
                            settingsLiveRestoreCheckbox.checked = true;
                        };
                        settingsLiveRestoreCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.liveRestore = true;
                            } else {
                                settings.liveRestore = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsLiveRestore.appendChild(settingsLiveRestoreCheckbox);
                        return settingsLiveRestore
                    };


                    function settingsLiveLight(){
                        var settingsLiveLight = document.createElement('div');
                        settingsLiveLight.innerText = 'Light mode live timer.';
                        settingsLiveLight.style.minWidth = '25%';
                        settingsLiveLight.style.fontSize = '20px';
                        settingsLiveLight.style.color = 'white';
                        settingsLiveLight.style.border = 'thin solid silver';
                        settingsLiveLight.style.padding = '5px';
                        settingsLiveLight.style.maxWidth = '25%';
                        settingsLiveLight.style.float = 'left';
                        var settingsLiveLightCheckbox = document.createElement('input');
                        settingsLiveLightCheckbox.setAttribute("type", "checkbox");
                        settingsLiveLightCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.liveLight == true){
                            settingsLiveLightCheckbox.checked = true;
                        };
                        settingsLiveLightCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.liveLight = true;
                            } else {
                                settings.liveLight = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsLiveLight.appendChild(settingsLiveLightCheckbox);
                        return settingsLiveLight
                    };

                    function settingsAuthorHighlight(){
                        var settingsAuthorHighlight = document.createElement('div');
                        settingsAuthorHighlight.innerText = 'Highlight author(s) in chat.';
                        settingsAuthorHighlight.style.minWidth = '25%';
                        settingsAuthorHighlight.style.fontSize = '20px';
                        settingsAuthorHighlight.style.color = 'white';
                        settingsAuthorHighlight.style.border = 'thin solid silver';
                        settingsAuthorHighlight.style.padding = '5px';
                        settingsAuthorHighlight.style.maxWidth = '25%';
                        settingsAuthorHighlight.style.float = 'left';

                        var settingsAuthorHighlightCheckbox = document.createElement('input');
                        settingsAuthorHighlightCheckbox.setAttribute("type", "checkbox");
                        settingsAuthorHighlightCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.authorHighlight == true){
                            settingsAuthorHighlightCheckbox.checked = true;
                        };
                        settingsAuthorHighlightCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.authorHighlight = true;
                            } else {
                                settings.authorHighlight = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsAuthorHighlight.appendChild(settingsAuthorHighlightCheckbox);
                        return settingsAuthorHighlight
                    };

                    function settingsLightHighlight(){
                        var settingsLightHighlight = document.createElement('div');
                        settingsLightHighlight.innerText = 'Light mode highlighting.';
                        settingsLightHighlight.style.minWidth = '25%';
                        settingsLightHighlight.style.fontSize = '20px';
                        settingsLightHighlight.style.color = 'white';
                        settingsLightHighlight.style.border = 'thin solid silver';
                        settingsLightHighlight.style.padding = '5px';
                        settingsLightHighlight.style.maxWidth = '25%';
                        settingsLightHighlight.style.float = 'left';

                        var settingsLightHighlightCheckbox = document.createElement('input');
                        settingsLightHighlightCheckbox.setAttribute("type", "checkbox");
                        settingsLightHighlightCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.highlightLightToggle == true){
                            settingsLightHighlightCheckbox.checked = true;
                        };
                        settingsLightHighlightCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.highlightLightToggle = true;
                            } else {
                                settings.highlightLightToggle = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsLightHighlight.appendChild(settingsLightHighlightCheckbox);
                        return settingsLightHighlight
                    };

                    function settingsTaggedAuthor(){
                        var settingsTaggedAuthor = document.createElement('div');
                        settingsTaggedAuthor.innerText = 'Hide tagged on author pages.';
                        settingsTaggedAuthor.style.minWidth = '25%';
                        settingsTaggedAuthor.style.fontSize = '20px';
                        settingsTaggedAuthor.style.color = 'white';
                        settingsTaggedAuthor.style.border = 'thin solid silver';
                        settingsTaggedAuthor.style.padding = '5px';
                        settingsTaggedAuthor.style.maxWidth = '25%';
                        settingsTaggedAuthor.style.float = 'left';

                        var settingsTaggedAuthorCheckbox = document.createElement('input');
                        settingsTaggedAuthorCheckbox.setAttribute("type", "checkbox");
                        settingsTaggedAuthorCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.removeTaggedAuthor == true){
                            settingsTaggedAuthorCheckbox.checked = true;
                        };
                        settingsTaggedAuthorCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.removeTaggedAuthor = true;
                            } else {
                                settings.removeTaggedAuthor = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsTaggedAuthor.appendChild(settingsTaggedAuthorCheckbox);
                        return settingsTaggedAuthor
                    };

                    function settingsFunctionalLinks(){
                        var settingsFunctionalLinks = document.createElement('div');
                        settingsFunctionalLinks.innerText = 'Make text links functional.';
                        settingsFunctionalLinks.style.minWidth = '25%';
                        settingsFunctionalLinks.style.fontSize = '20px';
                        settingsFunctionalLinks.style.color = 'white';
                        settingsFunctionalLinks.style.border = 'thin solid silver';
                        settingsFunctionalLinks.style.padding = '5px';
                        settingsFunctionalLinks.style.maxWidth = '25%';
                        settingsFunctionalLinks.style.float = 'left';

                        var settingsFunctionalLinksCheckbox = document.createElement('input');
                        settingsFunctionalLinksCheckbox.setAttribute("type", "checkbox");
                        settingsFunctionalLinksCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.functionalLinks == true){
                            settingsFunctionalLinksCheckbox.checked = true;
                        };
                        settingsFunctionalLinksCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.functionalLinks = true;
                            } else {
                                settings.functionalLinks = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsFunctionalLinks.appendChild(settingsFunctionalLinksCheckbox);
                        return settingsFunctionalLinks
                    };
                    function settingsFunctionalVideos(){
                        var settingsFunctionalVideos = document.createElement('div');
                        settingsFunctionalVideos.innerText = 'Make video links functional.';
                        settingsFunctionalVideos.style.minWidth = '25%';
                        settingsFunctionalVideos.style.fontSize = '20px';
                        settingsFunctionalVideos.style.color = 'white';
                        settingsFunctionalVideos.style.border = 'thin solid silver';
                        settingsFunctionalVideos.style.padding = '5px';
                        settingsFunctionalVideos.style.maxWidth = '25%';
                        settingsFunctionalVideos.style.float = 'left';

                        var settingsFunctionalVideosCheckbox = document.createElement('input');
                        settingsFunctionalVideosCheckbox.setAttribute("type", "checkbox");
                        settingsFunctionalVideosCheckbox.setAttribute("class", "toggleCheck");
                        if (settings.functionalVideos == true){
                            settingsFunctionalVideosCheckbox.checked = true;
                        };
                        settingsFunctionalVideosCheckbox.addEventListener('change', (event) => {
                            if (event.target.checked) {
                                settings.functionalVideos = true;
                            } else {
                                settings.functionalVideos = false;
                            };
                            localStorage.setItem('FL_Settings', JSON.stringify(settings));
                            settings = JSON.parse(localStorage.getItem('FL_Settings'));
                        });
                        settingsFunctionalVideos.appendChild(settingsFunctionalVideosCheckbox);
                        return settingsFunctionalVideos
                    };


                    function settingsActual(){

                        var settingsActual = document.createElement('div');
                        settingsActual.setAttribute('class','settingsTab');
                        settingsActual.setAttribute('name','General');
                        settingsActual.style.display = 'initial';

                        var settingsActualText = document.createElement('div');
                        settingsActualText.innerText = 'General Script Settings';
                        settingsActualText.style.minWidth = '100%';
                        settingsActualText.style.fontSize = '20px';
                        settingsActualText.style.color = 'white';

                        //Settings Checkboxes
                        settingsActual.appendChild(settingsAnonToggle());
                        settingsActual.appendChild(settingsRollerToggle());
                        settingsActual.appendChild(settingsNamefagToggle());
                        settingsActual.appendChild(settingsImageResize());
                        settingsActual.appendChild(settingsFunctionalLinks());
                        settingsActual.appendChild(settingsFunctionalVideos());
                        settingsActual.appendChild(settingsLiveRestore());
                        settingsActual.appendChild(settingsLiveLight());
                        settingsActual.appendChild(settingsAuthorHighlight());
                        settingsActual.appendChild(settingsLightHighlight());
                        settingsActual.appendChild(settingsRemoveBlankTopics());
                        settingsActual.appendChild(settingsFormRemove());
                        settingsActual.appendChild(settingsTagBlacklist());
                        settingsActual.appendChild(settingsTaggedAuthor());
                        settingsActual.appendChild(settingsChatBlacklist());
                        settingsActual.appendChild(settingsAuthorBlacklist());
                        settingsActual.prepend(settingsActualText);

                        return settingsActual
                    }

                    var settingsTop = document.createElement('div');
                    settingsTop.innerText = 'Script Config';
                    settingsTop.style.fontSize = '30px';
                    settingsTop.style.color = 'white';

                    try{
                        var settingsSelect = document.createElement('div');
                        settingsSelect.setAttribute("class", "settingsSelect");
                        var settingsTabs=['General','Tags','Chat','Alerts','Author'];
                        let tabC=0;
                        function createTab(tab){
                            let settingsSelectBTN = document.createElement('input');
                            settingsSelectBTN.setAttribute("type", "button");
                            settingsSelectBTN.setAttribute("class", "settingsSelectBTN");
                            settingsSelectBTN.value=String(tab);
                            if (tabC==0){
                                settingsSelectBTN.style.backgroundColor='#4b4f6b';
                                settingsSelectBTN.disabled = true;
                                tabC=1;
                                var settingTab = document.querySelector(`.settingsTab[name="${String(tab)}"]`)

                                }
                            settingsSelectBTN.onclick=function(){
                                let len=document.querySelectorAll('input.settingsSelectBTN');
                                for (let i = 0; i < len.length; i++){
                                    if (len[i].disabled == true){
                                        len[i].disabled = false;
                                        len[i].style.backgroundColor='#373952';
                                    }
                                };
                                this.disabled = true;
                                this.style.backgroundColor='#4b4f6b';
                                try{
                                    var settingTab = document.querySelector(`.settingsTab[name="${String(tab)}"]`)
                                    if (settingTab){
                                        var tabs=document.querySelectorAll(`div.settingsTab`)
                                        for (let i = 0; i < tabs.length; i++){
                                            tabs[i].style.display='none';
                                        };
                                        settingTab.style.display = 'initial'
                                    }
                                }catch(error){
                                    console.log(error);
                                };
                            };

                            let settingsSelectDiv = document.createElement('div');
                            settingsSelectDiv.setAttribute('class','settingsSelectDiv');
                            settingsSelectDiv.style.width=String(100/settingsTabs.length)+'%';
                            settingsSelectDiv.appendChild(settingsSelectBTN);
                            settingsSelect.appendChild(settingsSelectDiv);
                        }
                        settingsTabs.forEach(tab => createTab(tab));
                    }catch(error){
                        console.log(error);
                    }

                    function settingsBlacklist(){
                        var settingsTab = document.createElement('div');
                        settingsTab.setAttribute('class','settingsTab');
                        settingsTab.setAttribute('name','Alerts');
                        var settingsAlertBox = document.createElement('div');
                        settingsAlertBox.setAttribute('id', 'settingsAlertBox');
                        settingsAlertBox.style.marginBottom = '5px';

                        var settingsAlertAdd = document.createElement('input');
                        settingsAlertAdd.setAttribute("type", "button");
                        settingsAlertAdd.style.height = '30px';
                        settingsAlertAdd.value = 'Blacklist Current Quest';
                        settingsAlertAdd.onclick = function (){
                            try{
                                let author = document.querySelector('span.author span.name').innerText;
                                let title = document.querySelector('header.page-title').innerText;
                                let entry = title + '___' + author;
                                settings.alertBlacklist.push(entry);
                                localStorage.setItem('FL_Settings', JSON.stringify(settings));
                                settingsBlacklist.appendChild(elementBlacklisted(entry));

                            }catch(error){
                                console.log('Something went wrong when trying to blacklist this quest. You did try it on a quest, RIGHT?',error);
                            }
                        };

                        var settingsBlacklist = document.createElement('div');
                        settingsBlacklist.setAttribute('id', 'settingsBlacklist');
                        settings.alertBlacklist.forEach(element => settingsBlacklist.appendChild(elementBlacklisted(element)));

                        var settingsBlacklistText = document.createElement('div');
                        settingsBlacklistText.innerText = 'Alert Blacklist';
                        settingsBlacklistText.style.marginBottom = '5px';
                        settingsBlacklistText.style.minWidth = '100%';
                        settingsBlacklistText.style.fontSize = '20px';
                        settingsBlacklistText.style.color = 'white';

                        settingsAlertBox.prepend(settingsAlertAdd);
                        settingsBlacklist.prepend(settingsAlertBox);
                        settingsBlacklist.prepend(settingsBlacklistText);
                        settingsTab.appendChild(settingsBlacklist)
                        return settingsTab;
                    };

                    var settingsExit = document.createElement('a');
                    settingsExit.setAttribute('class', 'blacklistRemove');
                    settingsExit.innerText = 'Exit'
                    settingsExit.onclick = function(){document.querySelector('#confDisp').style.display = 'none'};

                    function reportIssuesHere(){
                        var reportIssuesHere = document.createElement('div');
                        reportIssuesHere.innerText = 'Report any issues you encounter to me through either of the links below.';
                        reportIssuesHere.style.fontSize = '20px';
                        reportIssuesHere.style.color = 'white';
                        reportIssuesHere.style.padding = '5px';

                        var reportIssuesHereA = document.createElement('a');
                        reportIssuesHereA.innerText = 'Akun Forum';
                        reportIssuesHereA.href = 'https://fiction.live/social/threads/snFwRdTqfhBoQxutt';
                        reportIssuesHereA.rel="noopener noreferrer"
                        reportIssuesHereA.target="_blank"
                        reportIssuesHere.appendChild(document.createElement('br'));
                        reportIssuesHere.appendChild(reportIssuesHereA);
                        var reportIssuesHereB = document.createElement('a');
                        reportIssuesHereB.innerText = 'Greasyfork Page';
                        reportIssuesHereB.href = 'https://greasyfork.org/en/scripts/418607-fiction-live-merged';
                        reportIssuesHereB.rel="noopener noreferrer"
                        reportIssuesHereB.target="_blank"
                        reportIssuesHere.appendChild(document.createElement('br'));
                        reportIssuesHere.appendChild(reportIssuesHereB);

                        return reportIssuesHere;
                    };


                    settingsTop.appendChild(settingsExit)
                    var confDisp = configDisplay();
                    var confBox = configBox();
                    confBox.appendChild(settingsTop);
                    confBox.appendChild(settingsSelect);
                    confBox.appendChild(settingsActual());
                    confBox.appendChild(settingsTagsBlacklist());
                    confBox.appendChild(settingsUserBlacklist());
                    confBox.appendChild(settingsAuthorsBlacklist());
                    confBox.appendChild(settingsBlacklist());
                    confBox.appendChild(reportIssuesHere());
                    confDisp.appendChild(confBox);
                    document.querySelector('body').prepend(confDisp);
                }
            }catch (error){
                console.log('Settings Display Error',error);
            };
        };

        function settingsOpen(){
            var myLive = document.createElement('li');
            myLive.setAttribute('id', 'confScript');
            myLive.style.textShadow = '-1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000';
            myLive.style.fontWeight = 'bold';

            var configOpen = document.createElement('a');
            configOpen.innerText = 'Config';
            configOpen.onclick = function(){document.querySelector('#confDisp').style.display = 'block'};
            myLive.appendChild(configOpen);
            return myLive
        };

        function settingsInsert(){
            try{
                let mainMenu = document.querySelector('nav#mainMenu');
                settingsDisplay()
                if (!(mainMenu.querySelector('#confScript'))){
                    mainMenu.childNodes[2].appendChild(settingsOpen());
                }
            }catch (error){console.log('Errors inserting Settings',error)};
        };

        settingsInsert()
    };


    pageCheck();
    monitorAlerts();
    awaitMainMenu();
})();