get paid to paste

q v2021.03-03.js

/*
 * q v2021.03-03.js - 
 * Original file (offline) 'q 2018.3-6.js' - http://anonsw.github.io/8chjs/
 * Changed - Default fading posts to OFF.
 * Fixed - Update Q's tripcode on line 23 to match data on line 416 and line 419 to correct deprecated values.
 * Q's Trip-code: Q !!Hs1Jq13jV6 
  */

// Settings
var qflair = ''; // Examples: REAL, →
var qcolor = '#ffc';
var youcolor = '#fcc';
var scrollcolor = 'rgba(153, 153, 153, 0.6)';
var scrollbackcolor = '#333';
var scrolltime = 400; // ms
var updateDelay = 200; // ms
var sidenavWidth = 30; // px

var floodEnabled = false;
var floodThreshold = 15; // min # posts before beginning fade
var floodVanish = 30; // max # posts before completed fade/hide
var floodBehavior = 'fade'; // hide, fade
var fadenametripregex = /^(Anon(ymous)?-*|Q -!!Hs1Jq13jV6)$/i;
var fadenametripfloodvalue = -1; // Effective post count for fading; or -1 for auto of floodThreshold+post count

var rateHistoryLen = 50; // Data points on chart
var rateAvgLen = 10; // Number of data points to average for instantaneous rate

/* House keeping variables */
var qposts = [];
var allqposts = [];
var currq = -1;
var youposts = [];
var curryou = -1;
var qnavposts = [];
var younavposts = [];
var ctx;
var	borderSz;
var	scrollWd;
var minheight;
var ratehistory = [];

/* Case insensitive contains selector for finding yous. SO #8746882 */
jQuery.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) {
    return function (elem) {
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});

/* On scroll stop. SO #9144560 */
(function ($) {
    var on = $.fn.on, timer;
    $.fn.on = function () {
        var args = Array.apply(null, arguments);
        var last = args[args.length - 1];

        if (isNaN(last) || (last === 1 && args.pop())) return on.apply(this, args);

        var delay = args.pop();
        var fn = args.pop();

        args.push(function () {
            var self = this, params = arguments;
            clearTimeout(timer);
            timer = setTimeout(function () {
                fn.apply(self, params);
            }, delay);
        });

        return on.apply(this, args);
    };
}(this.jQuery || this.Zepto));

/* Scroll to element */
function myScrollTo(el) {
    $('html, body').animate({
        scrollTop: $(el).offset().top - $('div.boardlist').height()
    }, scrolltime);
}

/* Highlight you references */
function highlightYouRefs() {
    $('div.body:icontains("(You)")').each(function() {
        $(this).parents('div.post').first().css('background-color',youcolor);
    });
    return $.Deferred().resolve();
}

/* Remove invalid (you)'s */
function removeInvalidYous() {
    $('div.body:icontains("(You)")').each(function() {
        $(this).find(':not(small)').contents().filter(function() { return this.nodeType == 3 }).each(function() {
            this.textContent = this.textContent.replace(/\(+ *You *\)+/ig, "you");
        });
    });
    return $.Deferred().resolve();
}

/* Highlight Q posts */
function highlightQ() {
    $(allqposts).each(function(idx,val) {
		var div = $(val).parents('div.post').first();
        if($(div).css('background-color') !== qcolor) {
			if(qflair !== "") {
	            $(val).prepend(qflair + " ");
			}
            $(div).css('background-color', qcolor);
        }
    });
    return $.Deferred().resolve();
}

/* Scroll to next Q */
function nextq() {
    if(qposts.length > 0) {
        if(currq < qposts.length-1) {
            currq++;
        }
        myScrollTo($(qposts).get(currq));
    }
}

/* Scroll to last Q */
function lastq() {
    if(qposts.length > 0) {
        currq = qposts.length - 1;
        myScrollTo($(qposts).get(currq));
    }
}

/* Scroll to previous Q */
function prevq() {
    if(qposts.length > 0) {
        if(currq > 0) {
            currq--;
        }
        myScrollTo($(qposts).get(currq));
    }
}

/* Scroll to first Q */
function firstq() {
    if(qposts.length > 0) {
        currq = 0;
        myScrollTo($(qposts).get(currq));
    }
}

/* Scroll to next (You) */
function nextyou() {
    if(youposts.length > 0) {
        if(curryou < youposts.length-1) {
            curryou++;
        }
        myScrollTo($(youposts).get(curryou));
    }
}

/* Scroll to last (You) */
function lastyou() {
    if(youposts.length > 0) {
        curryou = youposts.length - 1;
        myScrollTo($(youposts).get(curryou));
    }
}

/* Scroll to previous (You) */
function prevyou() {
    if(youposts.length > 0) {
        if(curryou > 0) {
            curryou--;
        }
        myScrollTo($(youposts).get(curryou));
    }
}

/* Scroll to first (You) */
function firstyou() {
    if(youposts.length > 0) {
        curryou = 0;
        myScrollTo($(youposts).get(curryou));
    }
}

/* Inserts Q navigation links */
function qnav() {
    $('div.boardlist').append('<span>[ <a href="javascript:firstq();"><i class="fa fa-step-backward"></i></a> <a href="javascript:prevq();"><i class="fa fa-backward"></i></a> <span style="filter:brightness(70%);">Q</span> <span class="qcount">(?:?)</span> <a href="javascript:nextq();"><i class="fa fa-forward"></i></a> <a href="javascript:lastq();"><i class="fa fa-step-forward"></i></a> ]</span>');
}

/* Inserts (You) navigation links */
function younav() {
    $('div.boardlist').append('<span>[ <a href="javascript:firstyou();"><i class="fa fa-step-backward"></i></a> <a href="javascript:prevyou();"><i class="fa fa-backward"></i></a> <span style="filter:brightness(70%);">(You)</span> <span class="youcount">(?:?)</span> </span><a href="javascript:nextyou();"><i class="fa fa-forward"></i></a> <a href="javascript:lastyou();"><i class="fa fa-step-forward"></i></a> ]</span>');
}

/* Inserts feature toggle links */
function togglenav() {
    $('div.boardlist').append('<span>[ <a href="javascript:toggleFlood();">Turn Post Fading <span class="toggleFloodState">On</span></a> ]</span>')
}

function postratenav() {
	var height = $('div.boardlist').height() - 1;
    $('div.boardlist').append('<span>[ Post Rate: <span class="postRate">0</span> posts/min <canvas class="postRateChart"></canvas>]</span>')
	$('.postRate').css('color', $('div.boardlist a').css('color'));
	var charts = $('.postRateChart');
	$(charts).each(function() {
		$(this).css('width', '100px');
		$(this).css('height', height);
		$(this).css('vertical-align', 'middle');
		//$(this).css('border', '1px solid');
		//$(this).css('border-color', $('div.boardlist').css('color'));
		var gctx = $(this).get(0).getContext('2d');
		gctx.canvas.height = 20;
		gctx.canvas.width = 100;
	});
}

/* Inserts side navigation */
function sidenav() {
    $('body').append('<canvas id="sidenav"></canvas>');
    var nav = $('#sidenav');
    $(nav).css('position', 'fixed');
    $(nav).css('top', $('div.boardlist').height());
    $(nav).css('right', 0);
    $(nav).css('width', sidenavWidth);
    $(nav).css('height', $(window).height() - $('div.boardlist').height());
    $(nav).css('background-color', scrollbackcolor);
    $('body').css('margin-right', sidenavWidth);
    ctx = $('#sidenav').get(0).getContext('2d');
	//ctx.canvas.height = $(document).height() - $('div.boardlist').height();
	ctx.canvas.height = 2048;
	ctx.canvas.width = sidenavWidth;
	borderSz = 1;
	scrollWd = ctx.canvas.width / 2;
}

/* Update navigation counts */
function updateNavCounts() {
    var fontSize = -1;
    var lineHeight;

    if(currq > qposts.length) { currq = qposts.length; }
    if(curryou > youposts.length) { curryou = youposts.length; }

    for(i=0; i<qposts.length; i++) {
        var el = $(qposts).get(i);
        if(fontSize == -1) {
            fontSize = $(el).css('font-size');
            lineHeight = Math.floor(parseInt(fontSize.replace('px', '')) * 1.5);
        }
        if(($(el).offset().top + $(el).height() - 2.25*lineHeight) > $(window).scrollTop()) {
            currq = i;
            break;
        }
    }

    for(i=0; i<youposts.length; i++) {
        var el = $(youposts).get(i);
        if(fontSize == -1) {
            fontSize = $(el).css('font-size');
            lineHeight = Math.floor(parseInt(fontSize.replace('px', '')) * 1.5);
        }
        if(($(el).offset().top + $(el).height() - 2.25*lineHeight) > $(window).scrollTop()) {
            curryou = i;
            break;
        }
    }

    // TODO: check for duplicates and remove from counts
    $('.qcount').text("(" + (currq+1) + ":" + qposts.length + ")");
    $('.youcount').text("(" + (curryou+1) + ":" + youposts.length + ")");
}

/* Update navigation graphics */
function updateNavGraphics() {
    var sidenav = $('#sidenav');
    if(sidenav.length) {
		$(sidenav).css('height', $(window).height() - $('div.boardlist').height());
		minheight = ctx.canvas.height / ($(window).height() - $('div.boardlist').height()); // 1px
		ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

        // Draw nav q posts
        qnavposts = [];
        ctx.fillStyle = qcolor;
        for (i = 0; i < qposts.length; i++) {
            // TODO: check if we have already added post, don't draw it again
            var el = $(qposts).get(i);
            var height = $(el).height() / $(document).height() * ctx.canvas.height;
            if(height < minheight) height = minheight;
            qnavposts[i] = {
				x : borderSz,
				y : $(el).offset().top / $(document).height() * ctx.canvas.height,
				width : ctx.canvas.width - borderSz*2,
				height : height
			};
            ctx.fillRect(qnavposts[i].x, qnavposts[i].y, qnavposts[i].width, qnavposts[i].height);
        }

        // Draw nav you posts
        younavposts = [];
        ctx.fillStyle = youcolor;
        for (i = 0; i < youposts.length; i++) {
            // TODO: check if we have already added post, don't add it again
            var el = $(youposts).get(i);
            var height = $(el).height() / $(document).height() * ctx.canvas.height;
            if(height < minheight) height = minheight;
            younavposts[i] = {
				x : borderSz,
				y : $(el).offset().top / $(document).height() * ctx.canvas.height,
				width : ctx.canvas.width - borderSz*2,
				height : height
			};
            ctx.fillRect(younavposts[i].x, younavposts[i].y, younavposts[i].width, younavposts[i].height);
        }

        // Update nav window
        ctx.fillStyle = scrollcolor;
        ctx.fillRect(
			scrollWd / 2,
			$(window).scrollTop() / $(document).height() * ctx.canvas.height,
			scrollWd,
			$(window).height() / $(document).height() * ctx.canvas.height
		);

		// Add red marker at bottom of >750 posts
		if($('#thread_stats_posts').text() > 750) {
			var barHeight = (4 * 2048) / ($(window).height() - $('div.boardlist').height());
			ctx.fillStyle = '#f66';
			ctx.fillRect(
				0,
				ctx.canvas.height - barHeight,
				ctx.canvas.width,
				barHeight
			);
		}
    }
}

function updateNavPostRate() {
	var posts = $('div.post').not('.post-hover');
	var startPost = posts.length - (rateHistoryLen + rateAvgLen) + 1;
	if(startPost < 1) startPost = 1;
	var start = $($($(posts).get(0)).find('.intro time').get(0)).attr('unixtime'); //$('div.post:first .intro time').attr('unixtime');
	ratehistory = [];
	timehistory = [];
	for(var i=startPost; i<posts.length; i++) {
	    // TODO: check if we have already added post, don't add it again
		var step = $($($(posts).get(i)).find('.intro time').get(0)).attr('unixtime'); //$($('div.post .intro time').get(i)).attr('unixtime');
		timehistory[timehistory.length] = step;
		if(timehistory.length - rateAvgLen - 1 >= 0) {
			var avgend = timehistory[timehistory.length - 1];
			var avgstart = timehistory[timehistory.length - rateAvgLen - 1];
			ratehistory[ratehistory.length] = rateAvgLen / ((avgend - avgstart) / 60);
		} else {
			ratehistory[ratehistory.length] = 0;
		}
	}
    //console.log(ratehistory);

//	$('.postRate').text(ratehistory[ratehistory.length-1].toFixed(1));
	if (ratehistory.length) {
		$('.postRate').text(ratehistory[ratehistory.length-1].toFixed(1));
		}	
	if(ratehistory.length > rateAvgLen) {
		var maxRate = Math.max.apply(null, ratehistory);
		var minRate = Math.min.apply(null, ratehistory);
		//console.log("Max: " + maxRate);
		//console.log("Min: " + minRate);
		if(minRate > (maxRate - 0.5)) {
			minRate = maxRate - 0.5;
			maxRate = maxRate + 0.5;
		}
		if(minRate < 0) {
			minRate = 0;
		}
		var maxTime = timehistory[timehistory.length-1];
		var minTime = timehistory[rateAvgLen];
		$('.postRateChart').each(function() {
			var gctx = $(this).get(0).getContext('2d');
			gctx.clearRect(0, 0, gctx.canvas.width, gctx.canvas.height);
			gctx.strokeStyle = $('div.boardlist a').css('color');
			gctx.beginPath();
			var x = 0;
			var y = gctx.canvas.height - (ratehistory[rateAvgLen] - minRate)/(maxRate - minRate) * gctx.canvas.height;
			gctx.moveTo(x, y);
			for(var i=rateAvgLen+1; i<ratehistory.length; i++) {
				x = (timehistory[i] - minTime)/(maxTime - minTime) * gctx.canvas.width;
				y = gctx.canvas.height - (ratehistory[i] - minRate)/(maxRate - minRate) * gctx.canvas.height;
				gctx.lineTo(x, y);
			}
			gctx.stroke();
			gctx.closePath();
		});
	}
}

/* Update navigation */
function updateNav() {
	updateNavCounts();
	updateNavGraphics();
	updateNavPostRate();
}

// Update nav when scrolling stops
$(window).on('scroll', function(e) {
	updateNavCounts();
	updateNavGraphics();
}, updateDelay);

// Update nav when resize stops
$(window).on('resize', function(e) {
	updateNav();
}, updateDelay);

/* Set which posts are Q posts */
function setQPosts() {
    qposts = $.map($('div.post span.trip:contains("!!Hs1Jq13jV6"):visible').not('.post-hover'), function(el) {
		return $(el).parents('div.post').first();
	});
    allqposts = $('span.trip:contains("!!Hs1Jq13jV6")');
    return $.Deferred().resolve();
}

/* Set which posts are you posts */
function setYouPosts() {
    youposts = $.map($('div.post span.own_post,div.body:icontains("(You)")').not('.post-hover'), function(el) {
        return $(el).parents('div.post').first();
    });
    return $.Deferred().resolve();
}

function setFloodPosts() {
    if(floodEnabled) {
        var stats = {};
        var firstId = null;
        $('span.poster_id').each(function () {
            var id = $(this).text();
            if (!(id in stats)) {
                stats[id] = {count: 0, namefag: false, floodcount: 0};
            }
            stats[id].count++;
			if(!stats[id].namefag) {
	            var name = $(this).parents('div').first().find('span.name').text();
	            var trip = $(this).parents('div').first().find('span.trip').text();
				stats[id].namefag = !fadenametripregex.test(name+'-'+trip);
			}
			if(stats[id].namefag) {
				if(fadenametripfloodvalue < 0) {
					stats[id].floodcount = floodThreshold + stats[id].count;
				} else {
					stats[id].floodcount = fadenametripfloodvalue;
				}
			} else {
				stats[id].floodcount = stats[id].count;
			}
            if (firstId == null) {
                firstId = id;
            }
        });
		$.each(stats, function (key, value) {
            if (key !== firstId) {
                if (value.floodcount > floodThreshold || value.namefag) {
                    if (floodBehavior === 'fade') {
                        var intensity = value.floodcount;
                        if (intensity > floodVanish) {
                            intensity = floodVanish;
                        }
                        intensity = ((floodVanish - floodThreshold) - (intensity - floodThreshold)) / (floodVanish - floodThreshold);
                        if (intensity < 0.1) {
                            intensity = 0.1;
                        }
                        $('span.poster_id:contains("' + key + '")').each(function () {
                            $(this).parents('div.post').first().css('opacity', intensity);
                            $(this).parents('div.post').first().hover(function () {
                                $(this).animate({opacity: 1.0}, updateDelay);
                            }, function () {
                                $(this).animate({opacity: intensity}, updateDelay);
                            });
                        });
                    } else if (floodBehavior === 'hide') {
                        if (value.count >= floodVanish) {
                            $('span.poster_id:contains("' + key + '")').each(function () {
                                $(this).parents('div.post').first().hide();
                            });
                        }
                    }
                }
            }
        });
    }
	return $.Deferred().resolve();
}

function toggleFlood() {
    if(floodEnabled) {
        floodEnabled = false;
        $('.toggleFloodState').text('On');
        if(floodBehavior === 'fade') {
            $('span.poster_id').each(function () {
                $(this).parents('div.post').first().css('opacity', 1);
                $(this).parents('div.post').first().off('mouseenter mouseleave');
            });
        } else if(floodBehavior === 'hide') {
            $(this).parents('div.post').first().show();
        }
    } else {
        floodEnabled = true;
        $('.toggleFloodState').text('Off');
        runq()
    }
}

/* Helper to run snippets in the right order */
function runq() {
    setQPosts()
        .done(highlightQ)
        .done(removeInvalidYous)
        .done(highlightYouRefs)
        .done(setYouPosts)
		.done(setFloodPosts)
        .done(updateNav);
}

/* Attach snippets to ready/change events */
$(document).ready(function() {
    qnav();
    younav();
    togglenav();
    postratenav();
    sidenav();
    runq();

    // Select the node that will be observed for mutations
    var targetNode = $('div.thread')[0];

    // Options for the observer (which mutations to observe)
    var config = { childList: true };

    // Callback function to execute when mutations are observed
    var callback = function(mutationsList) {
        for(var mutation of mutationsList) {
            if (mutation.type == 'childList') {
                runq();
                break;
            }
        }
    };

    // Create an observer instance linked to the callback function
    var observer = new MutationObserver(callback);

    // Start observing the target node for configured mutations
    observer.observe(targetNode, config);
});

Pasted: Mar 3, 2021, 4:59:05 pm
Views: 27